From 6f4e7a65034ad77ec622baade9d312042306c445 Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Fri, 13 May 2022 13:44:31 -0700 Subject: [PATCH] CONVERSION STEP - explicitify --- src/cancellationToken/cancellationToken.ts | 2 +- src/compiler/binder.ts | 2385 +- src/compiler/builder.ts | 813 +- src/compiler/builderPublic.ts | 67 +- src/compiler/builderState.ts | 185 +- src/compiler/builderStatePublic.ts | 4 +- src/compiler/checker.ts | 27722 ++++++++-------- src/compiler/commandLineParser.ts | 1828 +- src/compiler/core.ts | 490 +- src/compiler/corePublic.ts | 43 +- src/compiler/debug.ts | 481 +- src/compiler/emitter.ts | 3527 +- src/compiler/factory/baseNodeFactory.ts | 40 +- src/compiler/factory/emitHelpers.ts | 378 +- src/compiler/factory/emitNode.ts | 99 +- src/compiler/factory/nodeConverters.ts | 132 +- src/compiler/factory/nodeFactory.ts | 4064 +-- src/compiler/factory/nodeTests.ts | 868 +- src/compiler/factory/parenthesizerRules.ts | 369 +- src/compiler/factory/utilities.ts | 852 +- src/compiler/factory/utilitiesPublic.ts | 4 +- src/compiler/moduleNameResolver.ts | 1204 +- src/compiler/moduleSpecifiers.ts | 608 +- src/compiler/parser.ts | 5344 ++- src/compiler/path.ts | 178 +- src/compiler/perfLogger.ts | 40 +- src/compiler/performance.ts | 24 +- src/compiler/performanceCore.ts | 11 +- src/compiler/program.ts | 2611 +- src/compiler/resolutionCache.ts | 449 +- src/compiler/scanner.ts | 1510 +- src/compiler/semver.ts | 141 +- src/compiler/sourcemap.ts | 219 +- src/compiler/symbolWalker.ts | 107 +- src/compiler/sys.ts | 510 +- src/compiler/tracing.ts | 126 +- src/compiler/transformer.ts | 369 +- src/compiler/transformers/classFields.ts | 1407 +- src/compiler/transformers/declarations.ts | 1382 +- .../transformers/declarations/diagnostics.ts | 484 +- src/compiler/transformers/destructuring.ts | 302 +- src/compiler/transformers/es2015.ts | 2709 +- src/compiler/transformers/es2016.ts | 95 +- src/compiler/transformers/es2017.ts | 614 +- src/compiler/transformers/es2018.ts | 1094 +- src/compiler/transformers/es2019.ts | 29 +- src/compiler/transformers/es2020.ts | 201 +- src/compiler/transformers/es2021.ts | 83 +- src/compiler/transformers/es5.ts | 56 +- src/compiler/transformers/esnext.ts | 15 +- src/compiler/transformers/generators.ts | 1180 +- src/compiler/transformers/jsx.ts | 338 +- .../transformers/module/esnextAnd2015.ts | 208 +- src/compiler/transformers/module/module.ts | 1280 +- src/compiler/transformers/module/node.ts | 41 +- src/compiler/transformers/module/system.ts | 1071 +- src/compiler/transformers/taggedTemplate.ts | 56 +- src/compiler/transformers/ts.ts | 2000 +- src/compiler/transformers/utilities.ts | 289 +- src/compiler/tsbuild.ts | 21 +- src/compiler/tsbuildPublic.ts | 1346 +- src/compiler/types.ts | 2389 +- src/compiler/utilities.ts | 5077 ++- src/compiler/utilitiesPublic.ts | 1480 +- src/compiler/visitorPublic.ts | 1496 +- src/compiler/watch.ts | 628 +- src/compiler/watchPublic.ts | 485 +- src/compiler/watchUtilities.ts | 314 +- src/debug/dbg.ts | 124 +- src/deprecatedCompat/deprecations.ts | 971 +- src/executeCommandLine/executeCommandLine.ts | 590 +- src/harness/client.ts | 592 +- src/harness/collectionsImpl.ts | 42 +- src/harness/compilerImpl.ts | 43 +- src/harness/documentsUtil.ts | 5 +- src/harness/evaluatorImpl.ts | 55 +- src/harness/fakesHosts.ts | 32 +- src/harness/findUpDir.ts | 12 +- src/harness/fourslashImpl.ts | 436 +- src/harness/fourslashInterfaceImpl.ts | 135 +- src/harness/harnessGlobals.ts | 7 +- src/harness/harnessIO.ts | 169 +- src/harness/harnessLanguageService.ts | 28 +- src/harness/harnessUtils.ts | 24 +- src/harness/runnerbase.ts | 10 +- src/harness/sourceMapRecorder.ts | 20 +- src/harness/typeWriter.ts | 24 +- src/harness/util.ts | 19 +- src/harness/vfsUtil.ts | 346 +- src/harness/virtualFileSystemWithWatch.ts | 424 +- src/harness/vpathUtil.ts | 56 +- src/jsTyping/jsTyping.ts | 131 +- src/jsTyping/shared.ts | 10 +- src/jsTyping/types.ts | 46 +- src/loggedIO/loggedIO.ts | 83 +- src/server/editorServices.ts | 1742 +- src/server/moduleSpecifierCache.ts | 34 +- src/server/packageJsonCache.ts | 47 +- src/server/project.ts | 975 +- src/server/protocol.ts | 107 +- src/server/scriptInfo.ts | 204 +- src/server/scriptVersionCache.ts | 67 +- src/server/session.ts | 1566 +- src/server/types.ts | 17 +- src/server/typingsCache.ts | 60 +- src/server/utilities.ts | 31 +- src/server/utilitiesPublic.ts | 28 +- src/services/breakpoints.ts | 552 +- src/services/callHierarchy.ts | 455 +- src/services/classifier.ts | 778 +- src/services/classifier2020.ts | 172 +- src/services/codeFixProvider.ts | 70 +- ...dConvertToUnknownForNonOverlappingTypes.ts | 28 +- .../codefixes/addEmptyExportDeclaration.ts | 18 +- src/services/codefixes/addMissingAsync.ts | 63 +- src/services/codefixes/addMissingAwait.ts | 185 +- src/services/codefixes/addMissingConst.ts | 84 +- .../codefixes/addMissingDeclareProperty.ts | 24 +- .../addMissingInvocationForDecorator.ts | 20 +- .../codefixes/addNameToNamelessParameter.ts | 35 +- .../codefixes/addOptionalPropertyUndefined.ts | 75 +- .../codefixes/annotateWithTypeFromJSDoc.ts | 169 +- src/services/codefixes/convertConstToLet.ts | 33 +- .../codefixes/convertFunctionToEs6Class.ts | 187 +- .../convertLiteralTypeToMappedType.ts | 35 +- .../codefixes/convertToAsyncFunction.ts | 437 +- src/services/codefixes/convertToEsModule.ts | 419 +- .../codefixes/convertToMappedObjectType.ts | 70 +- .../codefixes/convertToTypeOnlyExport.ts | 58 +- .../codefixes/convertToTypeOnlyImport.ts | 28 +- ...correctQualifiedNameToIndexedAccessType.ts | 31 +- .../codefixes/disableJsDiagnostics.ts | 43 +- src/services/codefixes/fixAddMissingMember.ts | 535 +- .../codefixes/fixAddMissingNewOperator.ts | 23 +- .../fixAddModuleReferTypeMissingTypeof.ts | 26 +- src/services/codefixes/fixAddVoidToPromise.ts | 51 +- .../codefixes/fixAwaitInSyncFunction.ts | 69 +- src/services/codefixes/fixCannotFindModule.ts | 37 +- ...sDoesntImplementInheritedAbstractMember.ts | 37 +- .../fixClassIncorrectlyImplementsInterface.ts | 68 +- .../fixClassSuperMustPrecedeThisAccess.ts | 50 +- .../fixConstructorForDerivedNeedSuperCall.ts | 21 +- .../fixEnableExperimentalDecorators.ts | 14 +- src/services/codefixes/fixEnableJsxFlag.ts | 17 +- src/services/codefixes/fixExpectedComma.ts | 44 +- .../fixExtendsInterfaceBecomesImplements.ts | 36 +- .../fixForgottenThisPropertyAccess.ts | 33 +- src/services/codefixes/fixImplicitThis.ts | 42 +- .../codefixes/fixIncorrectNamedTupleSyntax.ts | 34 +- .../codefixes/fixInvalidImportSyntax.ts | 84 +- .../codefixes/fixInvalidJsxCharacters.ts | 22 +- src/services/codefixes/fixJSDocTypes.ts | 75 +- .../codefixes/fixMissingCallParentheses.ts | 31 +- .../codefixes/fixModuleAndTargetOptions.ts | 43 +- .../fixNoPropertyAccessFromIndexSignature.ts | 31 +- src/services/codefixes/fixOverrideModifier.ts | 177 +- .../codefixes/fixPropertyAssignment.ts | 19 +- .../codefixes/fixPropertyOverrideAccessor.ts | 39 +- .../codefixes/fixReturnTypeInAsyncFunction.ts | 35 +- src/services/codefixes/fixSpelling.ts | 136 +- .../codefixes/fixStrictClassInitialization.ts | 142 +- .../codefixes/fixUnmatchedParameter.ts | 80 +- src/services/codefixes/fixUnreachableCode.ts | 48 +- .../fixUnreferenceableDecoratorMetadata.ts | 46 +- src/services/codefixes/fixUnusedIdentifier.ts | 262 +- src/services/codefixes/fixUnusedLabel.ts | 20 +- src/services/codefixes/generateAccessors.ts | 244 +- src/services/codefixes/helpers.ts | 434 +- src/services/codefixes/importFixes.ts | 1031 +- src/services/codefixes/inferFromUsage.ts | 702 +- .../removeAccidentalCallParentheses.ts | 10 +- .../codefixes/removeUnnecessaryAwait.ts | 28 +- src/services/codefixes/requireInTs.ts | 54 +- src/services/codefixes/returnValueCorrect.ts | 196 +- src/services/codefixes/splitTypeOnlyImport.ts | 34 +- src/services/codefixes/useBigintLiteral.ts | 16 +- src/services/codefixes/useDefaultImport.ts | 37 +- src/services/codefixes/wrapJsxInFragment.ts | 51 +- src/services/completions.ts | 2795 +- src/services/documentHighlights.ts | 374 +- src/services/documentRegistry.ts | 170 +- src/services/exportAsModule.ts | 4 +- src/services/exportInfoMap.ts | 276 +- src/services/findAllReferences.ts | 1443 +- src/services/formatting/formatting.ts | 608 +- src/services/formatting/formattingContext.ts | 33 +- src/services/formatting/formattingScanner.ts | 132 +- src/services/formatting/rule.ts | 10 +- src/services/formatting/rules.ts | 890 +- src/services/formatting/rulesMap.ts | 50 +- src/services/formatting/smartIndenter.ts | 435 +- src/services/getEditsForFileRename.ts | 166 +- src/services/globalThisShim.ts | 3 +- src/services/goToDefinition.ts | 304 +- src/services/importTracker.ts | 384 +- src/services/inlayHints.ts | 149 +- src/services/jsDoc.ts | 313 +- src/services/navigateTo.ts | 76 +- src/services/navigationBar.ts | 595 +- src/services/organizeImports.ts | 286 +- src/services/outliningElementsCollector.ts | 264 +- src/services/patternMatcher.ts | 125 +- src/services/preProcess.ts | 209 +- src/services/refactorProvider.ts | 13 +- .../addOrRemoveBracesToArrowFunction.ts | 72 +- ...onvertArrowFunctionOrFunctionExpression.ts | 158 +- src/services/refactors/convertExport.ts | 211 +- src/services/refactors/convertImport.ts | 171 +- .../convertOverloadListToSingleSignature.ts | 163 +- .../convertParamsToDestructuredObject.ts | 450 +- .../convertStringOrTemplateLiteral.ts | 147 +- .../convertToOptionalChainExpression.ts | 177 +- src/services/refactors/extractSymbol.ts | 1177 +- src/services/refactors/extractType.ts | 201 +- .../generateGetAccessorAndSetAccessor.ts | 35 +- src/services/refactors/helpers.ts | 6 +- .../refactors/inferFunctionReturnType.ts | 70 +- src/services/refactors/moveToNewFile.ts | 703 +- src/services/rename.ts | 92 +- src/services/services.ts | 1583 +- src/services/shims.ts | 544 +- src/services/signatureHelp.ts | 402 +- src/services/smartSelection.ts | 169 +- src/services/sourcemaps.ts | 104 +- src/services/stringCompletions.ts | 581 +- src/services/suggestionDiagnostics.ts | 179 +- src/services/symbolDisplay.ts | 617 +- src/services/textChanges.ts | 801 +- src/services/transform.ts | 12 +- src/services/transpile.ts | 79 +- src/services/types.ts | 405 +- src/services/utilities.ts | 2362 +- src/shims/collectionShims.ts | 85 +- src/testRunner/compilerRunner.ts | 87 +- src/testRunner/externalCompileRunner.ts | 49 +- src/testRunner/fourslashRunner.ts | 9 +- src/testRunner/parallel/host.ts | 125 +- src/testRunner/parallel/shared.ts | 12 +- src/testRunner/parallel/worker.ts | 54 +- src/testRunner/projectsRunner.ts | 14 +- src/testRunner/runner.ts | 98 +- src/testRunner/rwcRunner.ts | 13 +- src/testRunner/test262Runner.ts | 33 +- src/testRunner/unittests/asserts.ts | 8 +- src/testRunner/unittests/base64.ts | 2 +- src/testRunner/unittests/builder.ts | 60 +- src/testRunner/unittests/comments.ts | 8 +- src/testRunner/unittests/compilerCore.ts | 50 +- .../unittests/config/commandLineParsing.ts | 383 +- .../config/configurationExtension.ts | 90 +- .../config/convertCompilerOptionsFromJson.ts | 345 +- .../config/convertTypeAcquisitionFromJson.ts | 142 +- .../unittests/config/initializeTSConfig.ts | 4 +- src/testRunner/unittests/config/matchFiles.ts | 292 +- .../unittests/config/projectReferences.ts | 56 +- src/testRunner/unittests/config/showConfig.ts | 30 +- .../unittests/config/tsconfigParsing.ts | 174 +- .../config/tsconfigParsingWatchOptions.ts | 87 +- src/testRunner/unittests/convertToBase64.ts | 4 +- src/testRunner/unittests/createMapShim.ts | 62 +- src/testRunner/unittests/createSetShim.ts | 62 +- src/testRunner/unittests/customTransforms.ts | 110 +- src/testRunner/unittests/debugDeprecation.ts | 30 +- src/testRunner/unittests/factory.ts | 94 +- src/testRunner/unittests/incrementalParser.ts | 223 +- src/testRunner/unittests/jsDocParsing.ts | 155 +- .../unittests/jsonParserRecovery.ts | 6 +- src/testRunner/unittests/moduleResolution.ts | 563 +- src/testRunner/unittests/parsePseudoBigInt.ts | 34 +- src/testRunner/unittests/paths.ts | 20 +- src/testRunner/unittests/printer.ts | 256 +- src/testRunner/unittests/programApi.ts | 73 +- src/testRunner/unittests/publicApi.ts | 21 +- .../unittests/reuseProgramStructure.ts | 316 +- src/testRunner/unittests/semver.ts | 108 +- .../cancellableLanguageServiceOperations.ts | 25 +- .../unittests/services/colorization.ts | 333 +- .../services/convertToAsyncFunction.ts | 296 +- .../unittests/services/extract/constants.ts | 74 +- .../unittests/services/extract/functions.ts | 104 +- .../unittests/services/extract/helpers.ts | 97 +- .../unittests/services/extract/ranges.ts | 139 +- .../services/extract/symbolWalker.ts | 6 +- .../unittests/services/hostNewLineSupport.ts | 41 +- .../unittests/services/languageService.ts | 144 +- .../unittests/services/organizeImports.ts | 580 +- .../unittests/services/preProcessFile.ts | 123 +- .../unittests/services/textChanges.ts | 237 +- .../unittests/services/transpile.ts | 120 +- src/testRunner/unittests/transform.ts | 429 +- .../unittests/tsbuild/amdModulesWithOut.ts | 64 +- src/testRunner/unittests/tsbuild/clean.ts | 4 +- .../unittests/tsbuild/configFileErrors.ts | 21 +- .../unittests/tsbuild/configFileExtends.ts | 6 +- .../tsbuild/containerOnlyReferenced.ts | 6 +- .../unittests/tsbuild/declarationEmit.ts | 12 +- src/testRunner/unittests/tsbuild/demo.ts | 25 +- .../unittests/tsbuild/emitDeclarationOnly.ts | 16 +- .../unittests/tsbuild/emptyFiles.ts | 6 +- .../unittests/tsbuild/exitCodeOnBogusFile.ts | 4 +- .../unittests/tsbuild/graphOrdering.ts | 27 +- src/testRunner/unittests/tsbuild/helpers.ts | 280 +- .../inferredTypeFromTransitiveModule.ts | 18 +- .../tsbuild/javascriptProjectEmit.ts | 20 +- .../unittests/tsbuild/lateBoundSymbol.ts | 8 +- .../unittests/tsbuild/moduleResolution.ts | 150 +- .../unittests/tsbuild/moduleSpecifiers.ts | 12 +- .../unittests/tsbuild/noEmitOnError.ts | 28 +- src/testRunner/unittests/tsbuild/outFile.ts | 219 +- .../unittests/tsbuild/outputPaths.ts | 34 +- src/testRunner/unittests/tsbuild/publicApi.ts | 63 +- .../tsbuild/referencesWithRootDirInParent.ts | 12 +- .../unittests/tsbuild/resolveJsonModule.ts | 30 +- src/testRunner/unittests/tsbuild/sample.ts | 173 +- .../unittests/tsbuild/transitiveReferences.ts | 8 +- .../tsbuildWatch/configFileErrors.ts | 27 +- src/testRunner/unittests/tsbuildWatch/demo.ts | 39 +- .../tsbuildWatch/moduleResolution.ts | 31 +- .../unittests/tsbuildWatch/noEmit.ts | 27 +- .../unittests/tsbuildWatch/noEmitOnError.ts | 25 +- .../unittests/tsbuildWatch/programUpdates.ts | 303 +- .../unittests/tsbuildWatch/publicApi.ts | 62 +- .../unittests/tsbuildWatch/reexport.ts | 19 +- .../tsbuildWatch/watchEnvironment.ts | 30 +- src/testRunner/unittests/tsc/composite.ts | 16 +- .../unittests/tsc/declarationEmit.ts | 97 +- src/testRunner/unittests/tsc/helpers.ts | 102 +- src/testRunner/unittests/tsc/incremental.ts | 156 +- src/testRunner/unittests/tsc/listFilesOnly.ts | 8 +- .../unittests/tsc/projectReferences.ts | 8 +- src/testRunner/unittests/tsc/redirect.ts | 4 +- .../unittests/tsc/runWithoutArgs.ts | 12 +- .../unittests/tscWatch/consoleClearing.ts | 28 +- src/testRunner/unittests/tscWatch/emit.ts | 172 +- .../unittests/tscWatch/emitAndErrorUpdates.ts | 184 +- .../forceConsistentCasingInFileNames.ts | 141 +- src/testRunner/unittests/tscWatch/helpers.ts | 202 +- .../unittests/tscWatch/incremental.ts | 132 +- .../unittests/tscWatch/nodeNextWatch.ts | 22 +- .../unittests/tscWatch/programUpdates.ts | 812 +- .../tscWatch/projectsWithReferences.ts | 282 +- .../unittests/tscWatch/resolutionCache.ts | 188 +- .../sourceOfProjectReferenceRedirect.ts | 59 +- src/testRunner/unittests/tscWatch/watchApi.ts | 278 +- .../unittests/tscWatch/watchEnvironment.ts | 283 +- .../tsserver/applyChangesToOpenFiles.ts | 82 +- .../unittests/tsserver/autoImportProvider.ts | 100 +- .../unittests/tsserver/auxiliaryProject.ts | 20 +- .../tsserver/cachingFileSystemInformation.ts | 268 +- .../unittests/tsserver/cancellationToken.ts | 76 +- .../unittests/tsserver/compileOnSave.ts | 486 +- .../unittests/tsserver/completions.ts | 114 +- .../tsserver/completionsIncomplete.ts | 120 +- .../unittests/tsserver/configFileSearch.ts | 106 +- .../unittests/tsserver/configuredProjects.ts | 780 +- .../unittests/tsserver/declarationFileMaps.ts | 412 +- .../unittests/tsserver/documentRegistry.ts | 30 +- .../unittests/tsserver/duplicatePackages.ts | 27 +- .../unittests/tsserver/dynamicFiles.ts | 174 +- .../tsserver/events/largeFileReferenced.ts | 46 +- .../events/projectLanguageServiceState.ts | 32 +- .../tsserver/events/projectLoading.ts | 94 +- .../events/projectUpdatedInBackground.ts | 149 +- .../unittests/tsserver/exportMapCache.ts | 62 +- .../unittests/tsserver/externalProjects.ts | 401 +- .../forceConsistentCasingInFileNames.ts | 95 +- .../unittests/tsserver/formatSettings.ts | 12 +- .../tsserver/getApplicableRefactors.ts | 11 +- .../tsserver/getEditsForFileRename.ts | 68 +- .../unittests/tsserver/getExportReferences.ts | 78 +- .../unittests/tsserver/getFileReferences.ts | 33 +- src/testRunner/unittests/tsserver/helpers.ts | 307 +- .../unittests/tsserver/importHelpers.ts | 6 +- .../unittests/tsserver/inferredProjects.ts | 277 +- .../unittests/tsserver/inlayHints.ts | 46 +- src/testRunner/unittests/tsserver/jsdocTag.ts | 100 +- .../unittests/tsserver/languageService.ts | 12 +- .../tsserver/maxNodeModuleJsDepth.ts | 16 +- .../unittests/tsserver/metadataInResponse.ts | 53 +- .../tsserver/moduleSpecifierCache.ts | 50 +- src/testRunner/unittests/tsserver/navTo.ts | 83 +- .../unittests/tsserver/occurences.ts | 27 +- src/testRunner/unittests/tsserver/openFile.ts | 82 +- .../unittests/tsserver/packageJsonInfo.ts | 44 +- .../tsserver/partialSemanticServer.ts | 180 +- src/testRunner/unittests/tsserver/plugins.ts | 40 +- .../unittests/tsserver/projectErrors.ts | 467 +- .../tsserver/projectReferenceCompileOnSave.ts | 1571 +- .../tsserver/projectReferenceErrors.ts | 31 +- .../unittests/tsserver/projectReferences.ts | 693 +- .../tsserver/projectReferencesSourcemap.ts | 2953 +- src/testRunner/unittests/tsserver/projects.ts | 744 +- .../tsserver/projectsWithReferences.ts | 556 +- .../unittests/tsserver/refactors.ts | 37 +- src/testRunner/unittests/tsserver/reload.ts | 56 +- .../unittests/tsserver/reloadProjects.ts | 74 +- src/testRunner/unittests/tsserver/rename.ts | 146 +- .../unittests/tsserver/resolutionCache.ts | 436 +- src/testRunner/unittests/tsserver/session.ts | 371 +- .../unittests/tsserver/skipLibCheck.ts | 133 +- .../unittests/tsserver/smartSelection.ts | 63 +- src/testRunner/unittests/tsserver/symLinks.ts | 80 +- .../unittests/tsserver/symlinkCache.ts | 29 +- .../unittests/tsserver/syntacticServer.ts | 150 +- .../unittests/tsserver/syntaxOperations.ts | 54 +- .../unittests/tsserver/telemetry.ts | 70 +- .../unittests/tsserver/textStorage.ts | 38 +- .../unittests/tsserver/typeAquisition.ts | 12 +- .../tsserver/typeOnlyImportChains.ts | 31 +- .../tsserver/typeReferenceDirectives.ts | 38 +- .../unittests/tsserver/typingsInstaller.ts | 779 +- .../unittests/tsserver/versionCache.ts | 30 +- .../unittests/tsserver/watchEnvironment.ts | 644 +- .../unittests/tsserver/webServer.ts | 67 +- src/tsserver/nodeServer.ts | 316 +- src/tsserver/server.ts | 64 +- src/tsserver/webServer.ts | 74 +- src/typingsInstaller/nodeTypingsInstaller.ts | 87 +- src/typingsInstallerCore/typingsInstaller.ts | 160 +- src/watchGuard/watchGuard.ts | 4 +- src/webServer/webServer.ts | 119 +- 421 files changed, 70658 insertions(+), 84305 deletions(-) diff --git a/src/cancellationToken/cancellationToken.ts b/src/cancellationToken/cancellationToken.ts index aaa19750b8710..195de1f64aca3 100644 --- a/src/cancellationToken/cancellationToken.ts +++ b/src/cancellationToken/cancellationToken.ts @@ -62,7 +62,7 @@ function createCancellationToken(args: string[]): ServerCancellationToken { } else { return { - isCancellationRequested: () => pipeExists(cancellationPipeName!), // TODO: GH#18217 + isCancellationRequested: () => pipeExists(cancellationPipeName!), setRequest: (_requestId: number): void => void 0, resetRequest: (_requestId: number): void => void 0 }; diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 66a9f6393dc75..aac499d008c28 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -9,23 +9,23 @@ namespace ts { interface ActiveLabel { next: ActiveLabel | undefined; - name: __String; - breakTarget: FlowLabel; - continueTarget: FlowLabel | undefined; + name: ts.__String; + breakTarget: ts.FlowLabel; + continueTarget: ts.FlowLabel | undefined; referenced: boolean; } - export function getModuleInstanceState(node: ModuleDeclaration, visited?: ESMap): ModuleInstanceState { + export function getModuleInstanceState(node: ts.ModuleDeclaration, visited?: ts.ESMap): ModuleInstanceState { if (node.body && !node.body.parent) { // getModuleInstanceStateForAliasTarget needs to walk up the parent chain, so parent pointers must be set on this tree already - setParent(node.body, node); - setParentRecursive(node.body, /*incremental*/ false); + ts.setParent(node.body, node); + ts.setParentRecursive(node.body, /*incremental*/ false); } return node.body ? getModuleInstanceStateCached(node.body, visited) : ModuleInstanceState.Instantiated; } - function getModuleInstanceStateCached(node: Node, visited = new Map()) { - const nodeId = getNodeId(node); + function getModuleInstanceStateCached(node: ts.Node, visited = new ts.Map()) { + const nodeId = ts.getNodeId(node); if (visited.has(nodeId)) { return visited.get(nodeId) || ModuleInstanceState.NonInstantiated; } @@ -35,30 +35,30 @@ namespace ts { return result; } - function getModuleInstanceStateWorker(node: Node, visited: ESMap): ModuleInstanceState { + function getModuleInstanceStateWorker(node: ts.Node, visited: ts.ESMap): ModuleInstanceState { // A module is uninstantiated if it contains only switch (node.kind) { // 1. interface declarations, type alias declarations - case SyntaxKind.InterfaceDeclaration: - case SyntaxKind.TypeAliasDeclaration: + case ts.SyntaxKind.InterfaceDeclaration: + case ts.SyntaxKind.TypeAliasDeclaration: return ModuleInstanceState.NonInstantiated; // 2. const enum declarations - case SyntaxKind.EnumDeclaration: - if (isEnumConst(node as EnumDeclaration)) { + case ts.SyntaxKind.EnumDeclaration: + if (ts.isEnumConst(node as ts.EnumDeclaration)) { return ModuleInstanceState.ConstEnumOnly; } break; // 3. non-exported import declarations - case SyntaxKind.ImportDeclaration: - case SyntaxKind.ImportEqualsDeclaration: - if (!(hasSyntacticModifier(node, ModifierFlags.Export))) { + case ts.SyntaxKind.ImportDeclaration: + case ts.SyntaxKind.ImportEqualsDeclaration: + if (!(ts.hasSyntacticModifier(node, ts.ModifierFlags.Export))) { return ModuleInstanceState.NonInstantiated; } break; // 4. Export alias declarations pointing at only uninstantiated modules or things uninstantiated modules contain - case SyntaxKind.ExportDeclaration: - const exportDeclaration = node as ExportDeclaration; - if (!exportDeclaration.moduleSpecifier && exportDeclaration.exportClause && exportDeclaration.exportClause.kind === SyntaxKind.NamedExports) { + case ts.SyntaxKind.ExportDeclaration: + const exportDeclaration = node as ts.ExportDeclaration; + if (!exportDeclaration.moduleSpecifier && exportDeclaration.exportClause && exportDeclaration.exportClause.kind === ts.SyntaxKind.NamedExports) { let state = ModuleInstanceState.NonInstantiated; for (const specifier of exportDeclaration.exportClause.elements) { const specifierState = getModuleInstanceStateForAliasTarget(specifier, visited); @@ -73,9 +73,9 @@ namespace ts { } break; // 5. other uninstantiated module declarations. - case SyntaxKind.ModuleBlock: { + case ts.SyntaxKind.ModuleBlock: { let state = ModuleInstanceState.NonInstantiated; - forEachChild(node, n => { + ts.forEachChild(node, n => { const childState = getModuleInstanceStateCached(n, visited); switch (childState) { case ModuleInstanceState.NonInstantiated: @@ -90,35 +90,35 @@ namespace ts { state = ModuleInstanceState.Instantiated; return true; default: - Debug.assertNever(childState); + ts.Debug.assertNever(childState); } }); return state; } - case SyntaxKind.ModuleDeclaration: - return getModuleInstanceState(node as ModuleDeclaration, visited); - case SyntaxKind.Identifier: + case ts.SyntaxKind.ModuleDeclaration: + return getModuleInstanceState(node as ts.ModuleDeclaration, visited); + case ts.SyntaxKind.Identifier: // Only jsdoc typedef definition can exist in jsdoc namespace, and it should // be considered the same as type alias - if ((node as Identifier).isInJSDocNamespace) { + if ((node as ts.Identifier).isInJSDocNamespace) { return ModuleInstanceState.NonInstantiated; } } return ModuleInstanceState.Instantiated; } - function getModuleInstanceStateForAliasTarget(specifier: ExportSpecifier, visited: ESMap) { + function getModuleInstanceStateForAliasTarget(specifier: ts.ExportSpecifier, visited: ts.ESMap) { const name = specifier.propertyName || specifier.name; - let p: Node | undefined = specifier.parent; + let p: ts.Node | undefined = specifier.parent; while (p) { - if (isBlock(p) || isModuleBlock(p) || isSourceFile(p)) { + if (ts.isBlock(p) || ts.isModuleBlock(p) || ts.isSourceFile(p)) { const statements = p.statements; let found: ModuleInstanceState | undefined; for (const statement of statements) { - if (nodeHasName(statement, name)) { + if (ts.nodeHasName(statement, name)) { if (!statement.parent) { - setParent(statement, p); - setParentRecursive(statement, /*incremental*/ false); + ts.setParent(statement, p); + ts.setParentRecursive(statement, /*incremental*/ false); } const state = getModuleInstanceStateCached(statement, visited); if (found === undefined || state > found) { @@ -163,51 +163,50 @@ namespace ts { IsFunctionExpression = 1 << 4, HasLocals = 1 << 5, IsInterface = 1 << 6, - IsObjectLiteralOrClassExpressionMethodOrAccessor = 1 << 7, + IsObjectLiteralOrClassExpressionMethodOrAccessor = 1 << 7 } - function initFlowNode(node: T) { - Debug.attachFlowNodeDebugInfo(node); + function initFlowNode(node: T) { + ts.Debug.attachFlowNodeDebugInfo(node); return node; } const binder = createBinder(); - export function bindSourceFile(file: SourceFile, options: CompilerOptions) { - performance.mark("beforeBind"); - perfLogger.logStartBindFile("" + file.fileName); + export function bindSourceFile(file: ts.SourceFile, options: ts.CompilerOptions) { + ts.performance.mark("beforeBind"); + ts.perfLogger.logStartBindFile("" + file.fileName); binder(file, options); - perfLogger.logStopBindFile(); - performance.mark("afterBind"); - performance.measure("Bind", "beforeBind", "afterBind"); + ts.perfLogger.logStopBindFile(); + ts.performance.mark("afterBind"); + ts.performance.measure("Bind", "beforeBind", "afterBind"); } - - function createBinder(): (file: SourceFile, options: CompilerOptions) => void { - let file: SourceFile; - let options: CompilerOptions; - let languageVersion: ScriptTarget; - let parent: Node; - let container: Node; - let thisParentContainer: Node; // Container one level up - let blockScopeContainer: Node; - let lastContainer: Node; - let delayedTypeAliases: (JSDocTypedefTag | JSDocCallbackTag | JSDocEnumTag)[]; + function createBinder(): (file: ts.SourceFile, options: ts.CompilerOptions) => void { + let file: ts.SourceFile; + let options: ts.CompilerOptions; + let languageVersion: ts.ScriptTarget; + let parent: ts.Node; + let container: ts.Node; + let thisParentContainer: ts.Node; // Container one level up + let blockScopeContainer: ts.Node; + let lastContainer: ts.Node; + let delayedTypeAliases: (ts.JSDocTypedefTag | ts.JSDocCallbackTag | ts.JSDocEnumTag)[]; let seenThisKeyword: boolean; // state used by control flow analysis - let currentFlow: FlowNode; - let currentBreakTarget: FlowLabel | undefined; - let currentContinueTarget: FlowLabel | undefined; - let currentReturnTarget: FlowLabel | undefined; - let currentTrueTarget: FlowLabel | undefined; - let currentFalseTarget: FlowLabel | undefined; - let currentExceptionTarget: FlowLabel | undefined; - let preSwitchCaseFlow: FlowNode | undefined; + let currentFlow: ts.FlowNode; + let currentBreakTarget: ts.FlowLabel | undefined; + let currentContinueTarget: ts.FlowLabel | undefined; + let currentReturnTarget: ts.FlowLabel | undefined; + let currentTrueTarget: ts.FlowLabel | undefined; + let currentFalseTarget: ts.FlowLabel | undefined; + let currentExceptionTarget: ts.FlowLabel | undefined; + let preSwitchCaseFlow: ts.FlowNode | undefined; let activeLabelList: ActiveLabel | undefined; let hasExplicitReturn: boolean; // state used for emit helpers - let emitFlags: NodeFlags; + let emitFlags: ts.NodeFlags; // If this file is an external module, then it is automatically in strict-mode according to // ES6. If it is not an external module, then we'll determine if it is in strict mode or @@ -220,11 +219,10 @@ namespace ts { let symbolCount = 0; - let Symbol: new (flags: SymbolFlags, name: __String) => Symbol; - let classifiableNames: Set<__String>; - - const unreachableFlow: FlowNode = { flags: FlowFlags.Unreachable }; - const reportedUnreachableFlow: FlowNode = { flags: FlowFlags.Unreachable }; + let Symbol: new (flags: ts.SymbolFlags, name: ts.__String) => ts.Symbol; + let classifiableNames: ts.Set; + const unreachableFlow: ts.FlowNode = { flags: ts.FlowFlags.Unreachable }; + const reportedUnreachableFlow: ts.FlowNode = { flags: ts.FlowFlags.Unreachable }; const bindBinaryExpressionFlow = createBindBinaryExpressionFlow(); /** @@ -232,28 +230,28 @@ namespace ts { * If so, the node _must_ be in the current file (as that's the only way anything could have traversed to it to yield it as the error node) * This version of `createDiagnosticForNode` uses the binder's context to account for this, and always yields correct diagnostics even in these situations. */ - function createDiagnosticForNode(node: Node, message: DiagnosticMessage, arg0?: string | number, arg1?: string | number, arg2?: string | number): DiagnosticWithLocation { - return createDiagnosticForNodeInSourceFile(getSourceFileOfNode(node) || file, node, message, arg0, arg1, arg2); + function createDiagnosticForNode(node: ts.Node, message: ts.DiagnosticMessage, arg0?: string | number, arg1?: string | number, arg2?: string | number): ts.DiagnosticWithLocation { + return ts.createDiagnosticForNodeInSourceFile(ts.getSourceFileOfNode(node) || file, node, message, arg0, arg1, arg2); } - function bindSourceFile(f: SourceFile, opts: CompilerOptions) { + function bindSourceFile(f: ts.SourceFile, opts: ts.CompilerOptions) { file = f; options = opts; - languageVersion = getEmitScriptTarget(options); + languageVersion = ts.getEmitScriptTarget(options); inStrictMode = bindInStrictMode(file, opts); - classifiableNames = new Set(); + classifiableNames = new ts.Set(); symbolCount = 0; - Symbol = objectAllocator.getSymbolConstructor(); + Symbol = ts.objectAllocator.getSymbolConstructor(); // Attach debugging information if necessary - Debug.attachFlowNodeDebugInfo(unreachableFlow); - Debug.attachFlowNodeDebugInfo(reportedUnreachableFlow); + ts.Debug.attachFlowNodeDebugInfo(unreachableFlow); + ts.Debug.attachFlowNodeDebugInfo(reportedUnreachableFlow); if (!file.locals) { - tracing?.push(tracing.Phase.Bind, "bindSourceFile", { path: file.path }, /*separateBeginAndEnd*/ true); + ts.tracing?.push(ts.tracing.Phase.Bind, "bindSourceFile", { path: file.path }, /*separateBeginAndEnd*/ true); bind(file); - tracing?.pop(); + ts.tracing?.pop(); file.symbolCount = symbolCount; file.classifiableNames = classifiableNames; delayedBindJSDocTypedefTag(); @@ -279,13 +277,13 @@ namespace ts { activeLabelList = undefined; hasExplicitReturn = false; inAssignmentPattern = false; - emitFlags = NodeFlags.None; + emitFlags = ts.NodeFlags.None; } return bindSourceFile; - function bindInStrictMode(file: SourceFile, opts: CompilerOptions): boolean { - if (getStrictOptionValue(opts, "alwaysStrict") && !file.isDeclarationFile) { + function bindInStrictMode(file: ts.SourceFile, opts: ts.CompilerOptions): boolean { + if (ts.getStrictOptionValue(opts, "alwaysStrict") && !file.isDeclarationFile) { // bind in strict mode source files with alwaysStrict option return true; } @@ -294,112 +292,111 @@ namespace ts { } } - function createSymbol(flags: SymbolFlags, name: __String): Symbol { + function createSymbol(flags: ts.SymbolFlags, name: ts.__String): ts.Symbol { symbolCount++; return new Symbol(flags, name); } - function addDeclarationToSymbol(symbol: Symbol, node: Declaration, symbolFlags: SymbolFlags) { + function addDeclarationToSymbol(symbol: ts.Symbol, node: ts.Declaration, symbolFlags: ts.SymbolFlags) { symbol.flags |= symbolFlags; node.symbol = symbol; - symbol.declarations = appendIfUnique(symbol.declarations, node); - - if (symbolFlags & (SymbolFlags.Class | SymbolFlags.Enum | SymbolFlags.Module | SymbolFlags.Variable) && !symbol.exports) { - symbol.exports = createSymbolTable(); + symbol.declarations = ts.appendIfUnique(symbol.declarations, node); + if (symbolFlags & (ts.SymbolFlags.Class | ts.SymbolFlags.Enum | ts.SymbolFlags.Module | ts.SymbolFlags.Variable) && !symbol.exports) { + symbol.exports = ts.createSymbolTable(); } - if (symbolFlags & (SymbolFlags.Class | SymbolFlags.Interface | SymbolFlags.TypeLiteral | SymbolFlags.ObjectLiteral) && !symbol.members) { - symbol.members = createSymbolTable(); + if (symbolFlags & (ts.SymbolFlags.Class | ts.SymbolFlags.Interface | ts.SymbolFlags.TypeLiteral | ts.SymbolFlags.ObjectLiteral) && !symbol.members) { + symbol.members = ts.createSymbolTable(); } // On merge of const enum module with class or function, reset const enum only flag (namespaces will already recalculate) - if (symbol.constEnumOnlyModule && (symbol.flags & (SymbolFlags.Function | SymbolFlags.Class | SymbolFlags.RegularEnum))) { + if (symbol.constEnumOnlyModule && (symbol.flags & (ts.SymbolFlags.Function | ts.SymbolFlags.Class | ts.SymbolFlags.RegularEnum))) { symbol.constEnumOnlyModule = false; } - if (symbolFlags & SymbolFlags.Value) { - setValueDeclaration(symbol, node); + if (symbolFlags & ts.SymbolFlags.Value) { + ts.setValueDeclaration(symbol, node); } } // Should not be called on a declaration with a computed property name, // unless it is a well known Symbol. - function getDeclarationName(node: Declaration): __String | undefined { - if (node.kind === SyntaxKind.ExportAssignment) { - return (node as ExportAssignment).isExportEquals ? InternalSymbolName.ExportEquals : InternalSymbolName.Default; + function getDeclarationName(node: ts.Declaration): ts.__String | undefined { + if (node.kind === ts.SyntaxKind.ExportAssignment) { + return (node as ts.ExportAssignment).isExportEquals ? ts.InternalSymbolName.ExportEquals : ts.InternalSymbolName.Default; } - const name = getNameOfDeclaration(node); + const name = ts.getNameOfDeclaration(node); if (name) { - if (isAmbientModule(node)) { - const moduleName = getTextOfIdentifierOrLiteral(name as Identifier | StringLiteral); - return (isGlobalScopeAugmentation(node as ModuleDeclaration) ? "__global" : `"${moduleName}"`) as __String; + if (ts.isAmbientModule(node)) { + const moduleName = ts.getTextOfIdentifierOrLiteral(name as ts.Identifier | ts.StringLiteral); + return (ts.isGlobalScopeAugmentation(node as ts.ModuleDeclaration) ? "__global" : `"${moduleName}"`) as ts.__String; } - if (name.kind === SyntaxKind.ComputedPropertyName) { + if (name.kind === ts.SyntaxKind.ComputedPropertyName) { const nameExpression = name.expression; // treat computed property names where expression is string/numeric literal as just string/numeric literal - if (isStringOrNumericLiteralLike(nameExpression)) { - return escapeLeadingUnderscores(nameExpression.text); + if (ts.isStringOrNumericLiteralLike(nameExpression)) { + return ts.escapeLeadingUnderscores(nameExpression.text); } - if (isSignedNumericLiteral(nameExpression)) { - return tokenToString(nameExpression.operator) + nameExpression.operand.text as __String; + if (ts.isSignedNumericLiteral(nameExpression)) { + return ts.tokenToString(nameExpression.operator) + nameExpression.operand.text as ts.__String; } else { - Debug.fail("Only computed properties with literal names have declaration names"); + ts.Debug.fail("Only computed properties with literal names have declaration names"); } } - if (isPrivateIdentifier(name)) { + if (ts.isPrivateIdentifier(name)) { // containingClass exists because private names only allowed inside classes - const containingClass = getContainingClass(node); + const containingClass = ts.getContainingClass(node); if (!containingClass) { // we can get here in cases where there is already a parse error. return undefined; } const containingClassSymbol = containingClass.symbol; - return getSymbolNameForPrivateIdentifier(containingClassSymbol, name.escapedText); + return ts.getSymbolNameForPrivateIdentifier(containingClassSymbol, name.escapedText); } - return isPropertyNameLiteral(name) ? getEscapedTextOfIdentifierOrLiteral(name) : undefined; + return ts.isPropertyNameLiteral(name) ? ts.getEscapedTextOfIdentifierOrLiteral(name) : undefined; } switch (node.kind) { - case SyntaxKind.Constructor: - return InternalSymbolName.Constructor; - case SyntaxKind.FunctionType: - case SyntaxKind.CallSignature: - case SyntaxKind.JSDocSignature: - return InternalSymbolName.Call; - case SyntaxKind.ConstructorType: - case SyntaxKind.ConstructSignature: - return InternalSymbolName.New; - case SyntaxKind.IndexSignature: - return InternalSymbolName.Index; - case SyntaxKind.ExportDeclaration: - return InternalSymbolName.ExportStar; - case SyntaxKind.SourceFile: + case ts.SyntaxKind.Constructor: + return ts.InternalSymbolName.Constructor; + case ts.SyntaxKind.FunctionType: + case ts.SyntaxKind.CallSignature: + case ts.SyntaxKind.JSDocSignature: + return ts.InternalSymbolName.Call; + case ts.SyntaxKind.ConstructorType: + case ts.SyntaxKind.ConstructSignature: + return ts.InternalSymbolName.New; + case ts.SyntaxKind.IndexSignature: + return ts.InternalSymbolName.Index; + case ts.SyntaxKind.ExportDeclaration: + return ts.InternalSymbolName.ExportStar; + case ts.SyntaxKind.SourceFile: // json file should behave as // module.exports = ... - return InternalSymbolName.ExportEquals; - case SyntaxKind.BinaryExpression: - if (getAssignmentDeclarationKind(node as BinaryExpression) === AssignmentDeclarationKind.ModuleExports) { + return ts.InternalSymbolName.ExportEquals; + case ts.SyntaxKind.BinaryExpression: + if (ts.getAssignmentDeclarationKind(node as ts.BinaryExpression) === ts.AssignmentDeclarationKind.ModuleExports) { // module.exports = ... - return InternalSymbolName.ExportEquals; + return ts.InternalSymbolName.ExportEquals; } - Debug.fail("Unknown binary declaration kind"); + ts.Debug.fail("Unknown binary declaration kind"); break; - case SyntaxKind.JSDocFunctionType: - return (isJSDocConstructSignature(node) ? InternalSymbolName.New : InternalSymbolName.Call); - case SyntaxKind.Parameter: + case ts.SyntaxKind.JSDocFunctionType: + return (ts.isJSDocConstructSignature(node) ? ts.InternalSymbolName.New : ts.InternalSymbolName.Call); + case ts.SyntaxKind.Parameter: // Parameters with names are handled at the top of this function. Parameters // without names can only come from JSDocFunctionTypes. - Debug.assert(node.parent.kind === SyntaxKind.JSDocFunctionType, "Impossible parameter parent kind", () => `parent is: ${(ts as any).SyntaxKind ? (ts as any).SyntaxKind[node.parent.kind] : node.parent.kind}, expected JSDocFunctionType`); - const functionType = node.parent as JSDocFunctionType; - const index = functionType.parameters.indexOf(node as ParameterDeclaration); - return "arg" + index as __String; + ts.Debug.assert(node.parent.kind === ts.SyntaxKind.JSDocFunctionType, "Impossible parameter parent kind", () => `parent is: ${(ts as any).SyntaxKind ? (ts as any).SyntaxKind[node.parent.kind] : node.parent.kind}, expected JSDocFunctionType`); + const functionType = node.parent as ts.JSDocFunctionType; + const index = functionType.parameters.indexOf(node as ts.ParameterDeclaration); + return "arg" + index as ts.__String; } } - function getDisplayName(node: Declaration): string { - return isNamedDeclaration(node) ? declarationNameToString(node.name) : unescapeLeadingUnderscores(Debug.checkDefined(getDeclarationName(node))); + function getDisplayName(node: ts.Declaration): string { + return ts.isNamedDeclaration(node) ? ts.declarationNameToString(node.name) : ts.unescapeLeadingUnderscores(ts.Debug.checkDefined(getDeclarationName(node))); } /** @@ -410,19 +407,18 @@ namespace ts { * @param includes - The SymbolFlags that node has in addition to its declaration type (eg: export, ambient, etc.) * @param excludes - The flags which node cannot be declared alongside in a symbol table. Used to report forbidden declarations. */ - function declareSymbol(symbolTable: SymbolTable, parent: Symbol | undefined, node: Declaration, includes: SymbolFlags, excludes: SymbolFlags, isReplaceableByMethod?: boolean, isComputedName?: boolean): Symbol { - Debug.assert(isComputedName || !hasDynamicName(node)); - - const isDefaultExport = hasSyntacticModifier(node, ModifierFlags.Default) || isExportSpecifier(node) && node.name.escapedText === "default"; + function declareSymbol(symbolTable: ts.SymbolTable, parent: ts.Symbol | undefined, node: ts.Declaration, includes: ts.SymbolFlags, excludes: ts.SymbolFlags, isReplaceableByMethod?: boolean, isComputedName?: boolean): ts.Symbol { + ts.Debug.assert(isComputedName || !ts.hasDynamicName(node)); + const isDefaultExport = ts.hasSyntacticModifier(node, ts.ModifierFlags.Default) || ts.isExportSpecifier(node) && node.name.escapedText === "default"; // The exported symbol for an export default function/class node is always named "default" - const name = isComputedName ? InternalSymbolName.Computed - : isDefaultExport && parent ? InternalSymbolName.Default + const name = isComputedName ? ts.InternalSymbolName.Computed + : isDefaultExport && parent ? ts.InternalSymbolName.Default : getDeclarationName(node); - let symbol: Symbol | undefined; + let symbol: ts.Symbol | undefined; if (name === undefined) { - symbol = createSymbol(SymbolFlags.None, InternalSymbolName.Missing); + symbol = createSymbol(ts.SymbolFlags.None, ts.InternalSymbolName.Missing); } else { // Check and see if the symbol table already has a symbol with this name. If not, @@ -450,13 +446,14 @@ namespace ts { // just add this node into the declarations list of the symbol. symbol = symbolTable.get(name); - if (includes & SymbolFlags.Classifiable) { + if (includes & ts.SymbolFlags.Classifiable) { classifiableNames.add(name); } if (!symbol) { - symbolTable.set(name, symbol = createSymbol(SymbolFlags.None, name)); - if (isReplaceableByMethod) symbol.isReplaceableByMethod = true; + symbolTable.set(name, symbol = createSymbol(ts.SymbolFlags.None, name)); + if (isReplaceableByMethod) + symbol.isReplaceableByMethod = true; } else if (isReplaceableByMethod && !symbol.isReplaceableByMethod) { // A symbol already exists, so don't add this as a declaration. @@ -466,32 +463,32 @@ namespace ts { if (symbol.isReplaceableByMethod) { // Javascript constructor-declared symbols can be discarded in favor of // prototype symbols like methods. - symbolTable.set(name, symbol = createSymbol(SymbolFlags.None, name)); + symbolTable.set(name, symbol = createSymbol(ts.SymbolFlags.None, name)); } - else if (!(includes & SymbolFlags.Variable && symbol.flags & SymbolFlags.Assignment)) { + else if (!(includes & ts.SymbolFlags.Variable && symbol.flags & ts.SymbolFlags.Assignment)) { // Assignment declarations are allowed to merge with variables, no matter what other flags they have. - if (isNamedDeclaration(node)) { - setParent(node.name, node); + if (ts.isNamedDeclaration(node)) { + ts.setParent(node.name, node); } // Report errors every position with duplicate declaration // Report errors on previous encountered declarations - let message = symbol.flags & SymbolFlags.BlockScopedVariable - ? Diagnostics.Cannot_redeclare_block_scoped_variable_0 - : Diagnostics.Duplicate_identifier_0; + let message = symbol.flags & ts.SymbolFlags.BlockScopedVariable + ? ts.Diagnostics.Cannot_redeclare_block_scoped_variable_0 + : ts.Diagnostics.Duplicate_identifier_0; let messageNeedsName = true; - if (symbol.flags & SymbolFlags.Enum || includes & SymbolFlags.Enum) { - message = Diagnostics.Enum_declarations_can_only_merge_with_namespace_or_other_enum_declarations; + if (symbol.flags & ts.SymbolFlags.Enum || includes & ts.SymbolFlags.Enum) { + message = ts.Diagnostics.Enum_declarations_can_only_merge_with_namespace_or_other_enum_declarations; messageNeedsName = false; } let multipleDefaultExports = false; - if (length(symbol.declarations)) { + if (ts.length(symbol.declarations)) { // If the current node is a default export of some sort, then check if // there are any other default exports that we need to error on. // We'll know whether we have other default exports depending on if `symbol` already has a declaration list set. if (isDefaultExport) { - message = Diagnostics.A_module_cannot_have_multiple_default_exports; + message = ts.Diagnostics.A_module_cannot_have_multiple_default_exports; messageNeedsName = false; multipleDefaultExports = true; } @@ -501,43 +498,40 @@ namespace ts { // 1. multiple export default of class declaration or function declaration by checking NodeFlags.Default // 2. multiple export default of export assignment. This one doesn't have NodeFlags.Default on (as export default doesn't considered as modifiers) if (symbol.declarations && symbol.declarations.length && - (node.kind === SyntaxKind.ExportAssignment && !(node as ExportAssignment).isExportEquals)) { - message = Diagnostics.A_module_cannot_have_multiple_default_exports; + (node.kind === ts.SyntaxKind.ExportAssignment && !(node as ts.ExportAssignment).isExportEquals)) { + message = ts.Diagnostics.A_module_cannot_have_multiple_default_exports; messageNeedsName = false; multipleDefaultExports = true; } } } - const relatedInformation: DiagnosticRelatedInformation[] = []; - if (isTypeAliasDeclaration(node) && nodeIsMissing(node.type) && hasSyntacticModifier(node, ModifierFlags.Export) && symbol.flags & (SymbolFlags.Alias | SymbolFlags.Type | SymbolFlags.Namespace)) { + const relatedInformation: ts.DiagnosticRelatedInformation[] = []; + if (ts.isTypeAliasDeclaration(node) && ts.nodeIsMissing(node.type) && ts.hasSyntacticModifier(node, ts.ModifierFlags.Export) && symbol.flags & (ts.SymbolFlags.Alias | ts.SymbolFlags.Type | ts.SymbolFlags.Namespace)) { // export type T; - may have meant export type { T }? - relatedInformation.push(createDiagnosticForNode(node, Diagnostics.Did_you_mean_0, `export type { ${unescapeLeadingUnderscores(node.name.escapedText)} }`)); + relatedInformation.push(createDiagnosticForNode(node, ts.Diagnostics.Did_you_mean_0, `export type { ${ts.unescapeLeadingUnderscores(node.name.escapedText)} }`)); } - const declarationName = getNameOfDeclaration(node) || node; - forEach(symbol.declarations, (declaration, index) => { - const decl = getNameOfDeclaration(declaration) || declaration; + const declarationName = ts.getNameOfDeclaration(node) || node; + ts.forEach(symbol.declarations, (declaration, index) => { + const decl = ts.getNameOfDeclaration(declaration) || declaration; const diag = createDiagnosticForNode(decl, message, messageNeedsName ? getDisplayName(declaration) : undefined); - file.bindDiagnostics.push( - multipleDefaultExports ? addRelatedInfo(diag, createDiagnosticForNode(declarationName, index === 0 ? Diagnostics.Another_export_default_is_here : Diagnostics.and_here)) : diag - ); + file.bindDiagnostics.push(multipleDefaultExports ? ts.addRelatedInfo(diag, createDiagnosticForNode(declarationName, index === 0 ? ts.Diagnostics.Another_export_default_is_here : ts.Diagnostics.and_here)) : diag); if (multipleDefaultExports) { - relatedInformation.push(createDiagnosticForNode(decl, Diagnostics.The_first_export_default_is_here)); + relatedInformation.push(createDiagnosticForNode(decl, ts.Diagnostics.The_first_export_default_is_here)); } }); const diag = createDiagnosticForNode(declarationName, message, messageNeedsName ? getDisplayName(node) : undefined); - file.bindDiagnostics.push(addRelatedInfo(diag, ...relatedInformation)); - - symbol = createSymbol(SymbolFlags.None, name); + file.bindDiagnostics.push(ts.addRelatedInfo(diag, ...relatedInformation)); + symbol = createSymbol(ts.SymbolFlags.None, name); } } } addDeclarationToSymbol(symbol, node, includes); if (symbol.parent) { - Debug.assert(symbol.parent === parent, "Existing symbol parent should match new one"); + ts.Debug.assert(symbol.parent === parent, "Existing symbol parent should match new one"); } else { symbol.parent = parent; @@ -546,10 +540,10 @@ namespace ts { return symbol; } - function declareModuleMember(node: Declaration, symbolFlags: SymbolFlags, symbolExcludes: SymbolFlags): Symbol { - const hasExportModifier = !!(getCombinedModifierFlags(node) & ModifierFlags.Export) || jsdocTreatAsExported(node); - if (symbolFlags & SymbolFlags.Alias) { - if (node.kind === SyntaxKind.ExportSpecifier || (node.kind === SyntaxKind.ImportEqualsDeclaration && hasExportModifier)) { + function declareModuleMember(node: ts.Declaration, symbolFlags: ts.SymbolFlags, symbolExcludes: ts.SymbolFlags): ts.Symbol { + const hasExportModifier = !!(ts.getCombinedModifierFlags(node) & ts.ModifierFlags.Export) || jsdocTreatAsExported(node); + if (symbolFlags & ts.SymbolFlags.Alias) { + if (node.kind === ts.SyntaxKind.ExportSpecifier || (node.kind === ts.SyntaxKind.ImportEqualsDeclaration && hasExportModifier)) { return declareSymbol(container.symbol.exports!, container.symbol, node, symbolFlags, symbolExcludes); } else { @@ -572,12 +566,13 @@ namespace ts { // during global merging in the checker. Why? The only case when ambient module is permitted inside another module is module augmentation // and this case is specially handled. Module augmentations should only be merged with original module definition // and should never be merged directly with other augmentation, and the latter case would be possible if automatic merge is allowed. - if (isJSDocTypeAlias(node)) Debug.assert(isInJSFile(node)); // We shouldn't add symbols for JSDoc nodes if not in a JS file. - if (!isAmbientModule(node) && (hasExportModifier || container.flags & NodeFlags.ExportContext)) { - if (!container.locals || (hasSyntacticModifier(node, ModifierFlags.Default) && !getDeclarationName(node))) { + if (ts.isJSDocTypeAlias(node)) + ts.Debug.assert(ts.isInJSFile(node)); // We shouldn't add symbols for JSDoc nodes if not in a JS file. + if (!ts.isAmbientModule(node) && (hasExportModifier || container.flags & ts.NodeFlags.ExportContext)) { + if (!container.locals || (ts.hasSyntacticModifier(node, ts.ModifierFlags.Default) && !getDeclarationName(node))) { return declareSymbol(container.symbol.exports!, container.symbol, node, symbolFlags, symbolExcludes); // No local symbol for an unnamed default! } - const exportKind = symbolFlags & SymbolFlags.Value ? SymbolFlags.ExportValue : 0; + const exportKind = symbolFlags & ts.SymbolFlags.Value ? ts.SymbolFlags.ExportValue : 0; const local = declareSymbol(container.locals, /*parent*/ undefined, node, exportKind, symbolExcludes); local.exportSymbol = declareSymbol(container.symbol.exports!, container.symbol, node, symbolFlags, symbolExcludes); node.localSymbol = local; @@ -589,19 +584,24 @@ namespace ts { } } - function jsdocTreatAsExported(node: Node) { - if (node.parent && isModuleDeclaration(node)) { + function jsdocTreatAsExported(node: ts.Node) { + if (node.parent && ts.isModuleDeclaration(node)) { node = node.parent; } - if (!isJSDocTypeAlias(node)) return false; + if (!ts.isJSDocTypeAlias(node)) + return false; // jsdoc typedef handling is a bit of a doozy, but to summarize, treat the typedef as exported if: // 1. It has an explicit name (since by default typedefs are always directly exported, either at the top level or in a container), or - if (!isJSDocEnumTag(node) && !!node.fullName) return true; + if (!ts.isJSDocEnumTag(node) && !!node.fullName) + return true; // 2. The thing a nameless typedef pulls its name from is implicitly a direct export (either by assignment or actual export flag). - const declName = getNameOfDeclaration(node); - if (!declName) return false; - if (isPropertyAccessEntityNameExpression(declName.parent) && isTopLevelNamespaceAssignment(declName.parent)) return true; - if (isDeclaration(declName.parent) && getCombinedModifierFlags(declName.parent) & ModifierFlags.Export) return true; + const declName = ts.getNameOfDeclaration(node); + if (!declName) + return false; + if (ts.isPropertyAccessEntityNameExpression(declName.parent) && isTopLevelNamespaceAssignment(declName.parent)) + return true; + if (ts.isDeclaration(declName.parent) && ts.getCombinedModifierFlags(declName.parent) & ts.ModifierFlags.Export) + return true; // This could potentially be simplified by having `delayedBindJSDocTypedefTag` pass in an override for `hasExportModifier`, since it should // already have calculated and branched on most of this. return false; @@ -610,7 +610,7 @@ namespace ts { // All container nodes are kept on a linked list in declaration order. This list is used by // the getLocalNameOfContainer function in the type checker to validate that the local name // used for a container is unique. - function bindContainer(node: Mutable, containerFlags: ContainerFlags) { + function bindContainer(node: ts.Mutable, containerFlags: ContainerFlags) { // Before we recurse into a node's children, we first save the existing parent, container // and block-container. Then after we pop out of processing the children, we restore // these saved values. @@ -636,12 +636,12 @@ namespace ts { // for it. We must clear this so we don't accidentally move any stale data forward from // a previous compilation. if (containerFlags & ContainerFlags.IsContainer) { - if (node.kind !== SyntaxKind.ArrowFunction) { + if (node.kind !== ts.SyntaxKind.ArrowFunction) { thisParentContainer = container; } container = blockScopeContainer = node; if (containerFlags & ContainerFlags.HasLocals) { - container.locals = createSymbolTable(); + container.locals = ts.createSymbolTable(); } addToContainerChain(container); } @@ -657,23 +657,22 @@ namespace ts { const saveExceptionTarget = currentExceptionTarget; const saveActiveLabelList = activeLabelList; const saveHasExplicitReturn = hasExplicitReturn; - const isImmediatelyInvoked = - (containerFlags & ContainerFlags.IsFunctionExpression && - !hasSyntacticModifier(node, ModifierFlags.Async) && - !(node as FunctionLikeDeclaration).asteriskToken && - !!getImmediatelyInvokedFunctionExpression(node)) || - node.kind === SyntaxKind.ClassStaticBlockDeclaration; + const isImmediatelyInvoked = (containerFlags & ContainerFlags.IsFunctionExpression && + !ts.hasSyntacticModifier(node, ts.ModifierFlags.Async) && + !(node as ts.FunctionLikeDeclaration).asteriskToken && + !!ts.getImmediatelyInvokedFunctionExpression(node)) || + node.kind === ts.SyntaxKind.ClassStaticBlockDeclaration; // A non-async, non-generator IIFE is considered part of the containing control flow. Return statements behave // similarly to break statements that exit to a label just past the statement body. if (!isImmediatelyInvoked) { - currentFlow = initFlowNode({ flags: FlowFlags.Start }); + currentFlow = initFlowNode({ flags: ts.FlowFlags.Start }); if (containerFlags & (ContainerFlags.IsFunctionExpression | ContainerFlags.IsObjectLiteralOrClassExpressionMethodOrAccessor)) { - currentFlow.node = node as FunctionExpression | ArrowFunction | MethodDeclaration | GetAccessorDeclaration | SetAccessorDeclaration; + currentFlow.node = node as ts.FunctionExpression | ts.ArrowFunction | ts.MethodDeclaration | ts.GetAccessorDeclaration | ts.SetAccessorDeclaration; } } // We create a return control flow graph for IIFEs and constructors. For constructors // we use the return control flow graph in strict property initialization checks. - currentReturnTarget = isImmediatelyInvoked || node.kind === SyntaxKind.Constructor || (isInJSFile(node) && (node.kind === SyntaxKind.FunctionDeclaration || node.kind === SyntaxKind.FunctionExpression)) ? createBranchLabel() : undefined; + currentReturnTarget = isImmediatelyInvoked || node.kind === ts.SyntaxKind.Constructor || (ts.isInJSFile(node) && (node.kind === ts.SyntaxKind.FunctionDeclaration || node.kind === ts.SyntaxKind.FunctionExpression)) ? createBranchLabel() : undefined; currentExceptionTarget = undefined; currentBreakTarget = undefined; currentContinueTarget = undefined; @@ -681,22 +680,23 @@ namespace ts { hasExplicitReturn = false; bindChildren(node); // Reset all reachability check related flags on node (for incremental scenarios) - node.flags &= ~NodeFlags.ReachabilityAndEmitFlags; - if (!(currentFlow.flags & FlowFlags.Unreachable) && containerFlags & ContainerFlags.IsFunctionLike && nodeIsPresent((node as FunctionLikeDeclaration | ClassStaticBlockDeclaration).body)) { - node.flags |= NodeFlags.HasImplicitReturn; - if (hasExplicitReturn) node.flags |= NodeFlags.HasExplicitReturn; - (node as FunctionLikeDeclaration | ClassStaticBlockDeclaration).endFlowNode = currentFlow; - } - if (node.kind === SyntaxKind.SourceFile) { + node.flags &= ~ts.NodeFlags.ReachabilityAndEmitFlags; + if (!(currentFlow.flags & ts.FlowFlags.Unreachable) && containerFlags & ContainerFlags.IsFunctionLike && ts.nodeIsPresent((node as ts.FunctionLikeDeclaration | ts.ClassStaticBlockDeclaration).body)) { + node.flags |= ts.NodeFlags.HasImplicitReturn; + if (hasExplicitReturn) + node.flags |= ts.NodeFlags.HasExplicitReturn; + (node as ts.FunctionLikeDeclaration | ts.ClassStaticBlockDeclaration).endFlowNode = currentFlow; + } + if (node.kind === ts.SyntaxKind.SourceFile) { node.flags |= emitFlags; - (node as SourceFile).endFlowNode = currentFlow; + (node as ts.SourceFile).endFlowNode = currentFlow; } if (currentReturnTarget) { addAntecedent(currentReturnTarget, currentFlow); currentFlow = finishFlowLabel(currentReturnTarget); - if (node.kind === SyntaxKind.Constructor || node.kind === SyntaxKind.ClassStaticBlockDeclaration || (isInJSFile(node) && (node.kind === SyntaxKind.FunctionDeclaration || node.kind === SyntaxKind.FunctionExpression))) { - (node as FunctionLikeDeclaration | ClassStaticBlockDeclaration).returnFlowNode = currentFlow; + if (node.kind === ts.SyntaxKind.Constructor || node.kind === ts.SyntaxKind.ClassStaticBlockDeclaration || (ts.isInJSFile(node) && (node.kind === ts.SyntaxKind.FunctionDeclaration || node.kind === ts.SyntaxKind.FunctionExpression))) { + (node as ts.FunctionLikeDeclaration | ts.ClassStaticBlockDeclaration).returnFlowNode = currentFlow; } } if (!isImmediatelyInvoked) { @@ -712,7 +712,7 @@ namespace ts { else if (containerFlags & ContainerFlags.IsInterface) { seenThisKeyword = false; bindChildren(node); - node.flags = seenThisKeyword ? node.flags | NodeFlags.ContainsThis : node.flags & ~NodeFlags.ContainsThis; + node.flags = seenThisKeyword ? node.flags | ts.NodeFlags.ContainsThis : node.flags & ~ts.NodeFlags.ContainsThis; } else { bindChildren(node); @@ -723,24 +723,24 @@ namespace ts { blockScopeContainer = savedBlockScopeContainer; } - function bindEachFunctionsFirst(nodes: NodeArray | undefined): void { - bindEach(nodes, n => n.kind === SyntaxKind.FunctionDeclaration ? bind(n) : undefined); - bindEach(nodes, n => n.kind !== SyntaxKind.FunctionDeclaration ? bind(n) : undefined); + function bindEachFunctionsFirst(nodes: ts.NodeArray | undefined): void { + bindEach(nodes, n => n.kind === ts.SyntaxKind.FunctionDeclaration ? bind(n) : undefined); + bindEach(nodes, n => n.kind !== ts.SyntaxKind.FunctionDeclaration ? bind(n) : undefined); } - function bindEach(nodes: NodeArray | undefined, bindFunction: (node: Node) => void = bind): void { + function bindEach(nodes: ts.NodeArray | undefined, bindFunction: (node: ts.Node) => void = bind): void { if (nodes === undefined) { return; } - forEach(nodes, bindFunction); + ts.forEach(nodes, bindFunction); } - function bindEachChild(node: Node) { - forEachChild(node, bind, bindEach); + function bindEachChild(node: ts.Node) { + ts.forEachChild(node, bind, bindEach); } - function bindChildren(node: Node): void { + function bindChildren(node: ts.Node): void { const saveInAssignmentPattern = inAssignmentPattern; // Most nodes aren't valid in an assignment pattern, so we clear the value here // and set it before we descend into nodes that could actually be part of an assignment pattern. @@ -751,109 +751,109 @@ namespace ts { inAssignmentPattern = saveInAssignmentPattern; return; } - if (node.kind >= SyntaxKind.FirstStatement && node.kind <= SyntaxKind.LastStatement && !options.allowUnreachableCode) { + if (node.kind >= ts.SyntaxKind.FirstStatement && node.kind <= ts.SyntaxKind.LastStatement && !options.allowUnreachableCode) { node.flowNode = currentFlow; } switch (node.kind) { - case SyntaxKind.WhileStatement: - bindWhileStatement(node as WhileStatement); + case ts.SyntaxKind.WhileStatement: + bindWhileStatement(node as ts.WhileStatement); break; - case SyntaxKind.DoStatement: - bindDoStatement(node as DoStatement); + case ts.SyntaxKind.DoStatement: + bindDoStatement(node as ts.DoStatement); break; - case SyntaxKind.ForStatement: - bindForStatement(node as ForStatement); + case ts.SyntaxKind.ForStatement: + bindForStatement(node as ts.ForStatement); break; - case SyntaxKind.ForInStatement: - case SyntaxKind.ForOfStatement: - bindForInOrForOfStatement(node as ForInOrOfStatement); + case ts.SyntaxKind.ForInStatement: + case ts.SyntaxKind.ForOfStatement: + bindForInOrForOfStatement(node as ts.ForInOrOfStatement); break; - case SyntaxKind.IfStatement: - bindIfStatement(node as IfStatement); + case ts.SyntaxKind.IfStatement: + bindIfStatement(node as ts.IfStatement); break; - case SyntaxKind.ReturnStatement: - case SyntaxKind.ThrowStatement: - bindReturnOrThrow(node as ReturnStatement | ThrowStatement); + case ts.SyntaxKind.ReturnStatement: + case ts.SyntaxKind.ThrowStatement: + bindReturnOrThrow(node as ts.ReturnStatement | ts.ThrowStatement); break; - case SyntaxKind.BreakStatement: - case SyntaxKind.ContinueStatement: - bindBreakOrContinueStatement(node as BreakOrContinueStatement); + case ts.SyntaxKind.BreakStatement: + case ts.SyntaxKind.ContinueStatement: + bindBreakOrContinueStatement(node as ts.BreakOrContinueStatement); break; - case SyntaxKind.TryStatement: - bindTryStatement(node as TryStatement); + case ts.SyntaxKind.TryStatement: + bindTryStatement(node as ts.TryStatement); break; - case SyntaxKind.SwitchStatement: - bindSwitchStatement(node as SwitchStatement); + case ts.SyntaxKind.SwitchStatement: + bindSwitchStatement(node as ts.SwitchStatement); break; - case SyntaxKind.CaseBlock: - bindCaseBlock(node as CaseBlock); + case ts.SyntaxKind.CaseBlock: + bindCaseBlock(node as ts.CaseBlock); break; - case SyntaxKind.CaseClause: - bindCaseClause(node as CaseClause); + case ts.SyntaxKind.CaseClause: + bindCaseClause(node as ts.CaseClause); break; - case SyntaxKind.ExpressionStatement: - bindExpressionStatement(node as ExpressionStatement); + case ts.SyntaxKind.ExpressionStatement: + bindExpressionStatement(node as ts.ExpressionStatement); break; - case SyntaxKind.LabeledStatement: - bindLabeledStatement(node as LabeledStatement); + case ts.SyntaxKind.LabeledStatement: + bindLabeledStatement(node as ts.LabeledStatement); break; - case SyntaxKind.PrefixUnaryExpression: - bindPrefixUnaryExpressionFlow(node as PrefixUnaryExpression); + case ts.SyntaxKind.PrefixUnaryExpression: + bindPrefixUnaryExpressionFlow(node as ts.PrefixUnaryExpression); break; - case SyntaxKind.PostfixUnaryExpression: - bindPostfixUnaryExpressionFlow(node as PostfixUnaryExpression); + case ts.SyntaxKind.PostfixUnaryExpression: + bindPostfixUnaryExpressionFlow(node as ts.PostfixUnaryExpression); break; - case SyntaxKind.BinaryExpression: - if (isDestructuringAssignment(node)) { + case ts.SyntaxKind.BinaryExpression: + if (ts.isDestructuringAssignment(node)) { // Carry over whether we are in an assignment pattern to // binary expressions that could actually be an initializer inAssignmentPattern = saveInAssignmentPattern; bindDestructuringAssignmentFlow(node); return; } - bindBinaryExpressionFlow(node as BinaryExpression); + bindBinaryExpressionFlow(node as ts.BinaryExpression); break; - case SyntaxKind.DeleteExpression: - bindDeleteExpressionFlow(node as DeleteExpression); + case ts.SyntaxKind.DeleteExpression: + bindDeleteExpressionFlow(node as ts.DeleteExpression); break; - case SyntaxKind.ConditionalExpression: - bindConditionalExpressionFlow(node as ConditionalExpression); + case ts.SyntaxKind.ConditionalExpression: + bindConditionalExpressionFlow(node as ts.ConditionalExpression); break; - case SyntaxKind.VariableDeclaration: - bindVariableDeclarationFlow(node as VariableDeclaration); + case ts.SyntaxKind.VariableDeclaration: + bindVariableDeclarationFlow(node as ts.VariableDeclaration); break; - case SyntaxKind.PropertyAccessExpression: - case SyntaxKind.ElementAccessExpression: - bindAccessExpressionFlow(node as AccessExpression); + case ts.SyntaxKind.PropertyAccessExpression: + case ts.SyntaxKind.ElementAccessExpression: + bindAccessExpressionFlow(node as ts.AccessExpression); break; - case SyntaxKind.CallExpression: - bindCallExpressionFlow(node as CallExpression); + case ts.SyntaxKind.CallExpression: + bindCallExpressionFlow(node as ts.CallExpression); break; - case SyntaxKind.NonNullExpression: - bindNonNullExpressionFlow(node as NonNullExpression); + case ts.SyntaxKind.NonNullExpression: + bindNonNullExpressionFlow(node as ts.NonNullExpression); break; - case SyntaxKind.JSDocTypedefTag: - case SyntaxKind.JSDocCallbackTag: - case SyntaxKind.JSDocEnumTag: - bindJSDocTypeAlias(node as JSDocTypedefTag | JSDocCallbackTag | JSDocEnumTag); + case ts.SyntaxKind.JSDocTypedefTag: + case ts.SyntaxKind.JSDocCallbackTag: + case ts.SyntaxKind.JSDocEnumTag: + bindJSDocTypeAlias(node as ts.JSDocTypedefTag | ts.JSDocCallbackTag | ts.JSDocEnumTag); break; // In source files and blocks, bind functions first to match hoisting that occurs at runtime - case SyntaxKind.SourceFile: { - bindEachFunctionsFirst((node as SourceFile).statements); - bind((node as SourceFile).endOfFileToken); + case ts.SyntaxKind.SourceFile: { + bindEachFunctionsFirst((node as ts.SourceFile).statements); + bind((node as ts.SourceFile).endOfFileToken); break; } - case SyntaxKind.Block: - case SyntaxKind.ModuleBlock: - bindEachFunctionsFirst((node as Block).statements); + case ts.SyntaxKind.Block: + case ts.SyntaxKind.ModuleBlock: + bindEachFunctionsFirst((node as ts.Block).statements); break; - case SyntaxKind.BindingElement: - bindBindingElementFlow(node as BindingElement); + case ts.SyntaxKind.BindingElement: + bindBindingElementFlow(node as ts.BindingElement); break; - case SyntaxKind.ObjectLiteralExpression: - case SyntaxKind.ArrayLiteralExpression: - case SyntaxKind.PropertyAssignment: - case SyntaxKind.SpreadElement: + case ts.SyntaxKind.ObjectLiteralExpression: + case ts.SyntaxKind.ArrayLiteralExpression: + case ts.SyntaxKind.PropertyAssignment: + case ts.SyntaxKind.SpreadElement: // Carry over whether we are in an assignment pattern of Object and Array literals // as well as their children that are valid assignment targets. inAssignmentPattern = saveInAssignmentPattern; @@ -866,42 +866,42 @@ namespace ts { inAssignmentPattern = saveInAssignmentPattern; } - function isNarrowingExpression(expr: Expression): boolean { + function isNarrowingExpression(expr: ts.Expression): boolean { switch (expr.kind) { - case SyntaxKind.Identifier: - case SyntaxKind.PrivateIdentifier: - case SyntaxKind.ThisKeyword: - case SyntaxKind.PropertyAccessExpression: - case SyntaxKind.ElementAccessExpression: + case ts.SyntaxKind.Identifier: + case ts.SyntaxKind.PrivateIdentifier: + case ts.SyntaxKind.ThisKeyword: + case ts.SyntaxKind.PropertyAccessExpression: + case ts.SyntaxKind.ElementAccessExpression: return containsNarrowableReference(expr); - case SyntaxKind.CallExpression: - return hasNarrowableArgument(expr as CallExpression); - case SyntaxKind.ParenthesizedExpression: - case SyntaxKind.NonNullExpression: - return isNarrowingExpression((expr as ParenthesizedExpression | NonNullExpression).expression); - case SyntaxKind.BinaryExpression: - return isNarrowingBinaryExpression(expr as BinaryExpression); - case SyntaxKind.PrefixUnaryExpression: - return (expr as PrefixUnaryExpression).operator === SyntaxKind.ExclamationToken && isNarrowingExpression((expr as PrefixUnaryExpression).operand); - case SyntaxKind.TypeOfExpression: - return isNarrowingExpression((expr as TypeOfExpression).expression); + case ts.SyntaxKind.CallExpression: + return hasNarrowableArgument(expr as ts.CallExpression); + case ts.SyntaxKind.ParenthesizedExpression: + case ts.SyntaxKind.NonNullExpression: + return isNarrowingExpression((expr as ts.ParenthesizedExpression | ts.NonNullExpression).expression); + case ts.SyntaxKind.BinaryExpression: + return isNarrowingBinaryExpression(expr as ts.BinaryExpression); + case ts.SyntaxKind.PrefixUnaryExpression: + return (expr as ts.PrefixUnaryExpression).operator === ts.SyntaxKind.ExclamationToken && isNarrowingExpression((expr as ts.PrefixUnaryExpression).operand); + case ts.SyntaxKind.TypeOfExpression: + return isNarrowingExpression((expr as ts.TypeOfExpression).expression); } return false; } - function isNarrowableReference(expr: Expression): boolean { - return isDottedName(expr) - || (isPropertyAccessExpression(expr) || isNonNullExpression(expr) || isParenthesizedExpression(expr)) && isNarrowableReference(expr.expression) - || isBinaryExpression(expr) && expr.operatorToken.kind === SyntaxKind.CommaToken && isNarrowableReference(expr.right) - || isElementAccessExpression(expr) && (isStringOrNumericLiteralLike(expr.argumentExpression) || isEntityNameExpression(expr.argumentExpression)) && isNarrowableReference(expr.expression) - || isAssignmentExpression(expr) && isNarrowableReference(expr.left); + function isNarrowableReference(expr: ts.Expression): boolean { + return ts.isDottedName(expr) + || (ts.isPropertyAccessExpression(expr) || ts.isNonNullExpression(expr) || ts.isParenthesizedExpression(expr)) && isNarrowableReference(expr.expression) + || ts.isBinaryExpression(expr) && expr.operatorToken.kind === ts.SyntaxKind.CommaToken && isNarrowableReference(expr.right) + || ts.isElementAccessExpression(expr) && (ts.isStringOrNumericLiteralLike(expr.argumentExpression) || ts.isEntityNameExpression(expr.argumentExpression)) && isNarrowableReference(expr.expression) + || ts.isAssignmentExpression(expr) && isNarrowableReference(expr.left); } - function containsNarrowableReference(expr: Expression): boolean { - return isNarrowableReference(expr) || isOptionalChain(expr) && containsNarrowableReference(expr.expression); + function containsNarrowableReference(expr: ts.Expression): boolean { + return isNarrowableReference(expr) || ts.isOptionalChain(expr) && containsNarrowableReference(expr.expression); } - function hasNarrowableArgument(expr: CallExpression) { + function hasNarrowableArgument(expr: ts.CallExpression) { if (expr.arguments) { for (const argument of expr.arguments) { if (containsNarrowableReference(argument)) { @@ -909,89 +909,89 @@ namespace ts { } } } - if (expr.expression.kind === SyntaxKind.PropertyAccessExpression && - containsNarrowableReference((expr.expression as PropertyAccessExpression).expression)) { + if (expr.expression.kind === ts.SyntaxKind.PropertyAccessExpression && + containsNarrowableReference((expr.expression as ts.PropertyAccessExpression).expression)) { return true; } return false; } - function isNarrowingTypeofOperands(expr1: Expression, expr2: Expression) { - return isTypeOfExpression(expr1) && isNarrowableOperand(expr1.expression) && isStringLiteralLike(expr2); + function isNarrowingTypeofOperands(expr1: ts.Expression, expr2: ts.Expression) { + return ts.isTypeOfExpression(expr1) && isNarrowableOperand(expr1.expression) && ts.isStringLiteralLike(expr2); } - function isNarrowingBinaryExpression(expr: BinaryExpression) { + function isNarrowingBinaryExpression(expr: ts.BinaryExpression) { switch (expr.operatorToken.kind) { - case SyntaxKind.EqualsToken: - case SyntaxKind.BarBarEqualsToken: - case SyntaxKind.AmpersandAmpersandEqualsToken: - case SyntaxKind.QuestionQuestionEqualsToken: + case ts.SyntaxKind.EqualsToken: + case ts.SyntaxKind.BarBarEqualsToken: + case ts.SyntaxKind.AmpersandAmpersandEqualsToken: + case ts.SyntaxKind.QuestionQuestionEqualsToken: return containsNarrowableReference(expr.left); - case SyntaxKind.EqualsEqualsToken: - case SyntaxKind.ExclamationEqualsToken: - case SyntaxKind.EqualsEqualsEqualsToken: - case SyntaxKind.ExclamationEqualsEqualsToken: + case ts.SyntaxKind.EqualsEqualsToken: + case ts.SyntaxKind.ExclamationEqualsToken: + case ts.SyntaxKind.EqualsEqualsEqualsToken: + case ts.SyntaxKind.ExclamationEqualsEqualsToken: return isNarrowableOperand(expr.left) || isNarrowableOperand(expr.right) || isNarrowingTypeofOperands(expr.right, expr.left) || isNarrowingTypeofOperands(expr.left, expr.right); - case SyntaxKind.InstanceOfKeyword: + case ts.SyntaxKind.InstanceOfKeyword: return isNarrowableOperand(expr.left); - case SyntaxKind.InKeyword: + case ts.SyntaxKind.InKeyword: return isNarrowingExpression(expr.right); - case SyntaxKind.CommaToken: + case ts.SyntaxKind.CommaToken: return isNarrowingExpression(expr.right); } return false; } - function isNarrowableOperand(expr: Expression): boolean { + function isNarrowableOperand(expr: ts.Expression): boolean { switch (expr.kind) { - case SyntaxKind.ParenthesizedExpression: - return isNarrowableOperand((expr as ParenthesizedExpression).expression); - case SyntaxKind.BinaryExpression: - switch ((expr as BinaryExpression).operatorToken.kind) { - case SyntaxKind.EqualsToken: - return isNarrowableOperand((expr as BinaryExpression).left); - case SyntaxKind.CommaToken: - return isNarrowableOperand((expr as BinaryExpression).right); + case ts.SyntaxKind.ParenthesizedExpression: + return isNarrowableOperand((expr as ts.ParenthesizedExpression).expression); + case ts.SyntaxKind.BinaryExpression: + switch ((expr as ts.BinaryExpression).operatorToken.kind) { + case ts.SyntaxKind.EqualsToken: + return isNarrowableOperand((expr as ts.BinaryExpression).left); + case ts.SyntaxKind.CommaToken: + return isNarrowableOperand((expr as ts.BinaryExpression).right); } } return containsNarrowableReference(expr); } - function createBranchLabel(): FlowLabel { - return initFlowNode({ flags: FlowFlags.BranchLabel, antecedents: undefined }); + function createBranchLabel(): ts.FlowLabel { + return initFlowNode({ flags: ts.FlowFlags.BranchLabel, antecedents: undefined }); } - function createLoopLabel(): FlowLabel { - return initFlowNode({ flags: FlowFlags.LoopLabel, antecedents: undefined }); + function createLoopLabel(): ts.FlowLabel { + return initFlowNode({ flags: ts.FlowFlags.LoopLabel, antecedents: undefined }); } - function createReduceLabel(target: FlowLabel, antecedents: FlowNode[], antecedent: FlowNode): FlowReduceLabel { - return initFlowNode({ flags: FlowFlags.ReduceLabel, target, antecedents, antecedent }); + function createReduceLabel(target: ts.FlowLabel, antecedents: ts.FlowNode[], antecedent: ts.FlowNode): ts.FlowReduceLabel { + return initFlowNode({ flags: ts.FlowFlags.ReduceLabel, target, antecedents, antecedent }); } - function setFlowNodeReferenced(flow: FlowNode) { + function setFlowNodeReferenced(flow: ts.FlowNode) { // On first reference we set the Referenced flag, thereafter we set the Shared flag - flow.flags |= flow.flags & FlowFlags.Referenced ? FlowFlags.Shared : FlowFlags.Referenced; + flow.flags |= flow.flags & ts.FlowFlags.Referenced ? ts.FlowFlags.Shared : ts.FlowFlags.Referenced; } - function addAntecedent(label: FlowLabel, antecedent: FlowNode): void { - if (!(antecedent.flags & FlowFlags.Unreachable) && !contains(label.antecedents, antecedent)) { + function addAntecedent(label: ts.FlowLabel, antecedent: ts.FlowNode): void { + if (!(antecedent.flags & ts.FlowFlags.Unreachable) && !ts.contains(label.antecedents, antecedent)) { (label.antecedents || (label.antecedents = [])).push(antecedent); setFlowNodeReferenced(antecedent); } } - function createFlowCondition(flags: FlowFlags, antecedent: FlowNode, expression: Expression | undefined): FlowNode { - if (antecedent.flags & FlowFlags.Unreachable) { + function createFlowCondition(flags: ts.FlowFlags, antecedent: ts.FlowNode, expression: ts.Expression | undefined): ts.FlowNode { + if (antecedent.flags & ts.FlowFlags.Unreachable) { return antecedent; } if (!expression) { - return flags & FlowFlags.TrueCondition ? antecedent : unreachableFlow; + return flags & ts.FlowFlags.TrueCondition ? antecedent : unreachableFlow; } - if ((expression.kind === SyntaxKind.TrueKeyword && flags & FlowFlags.FalseCondition || - expression.kind === SyntaxKind.FalseKeyword && flags & FlowFlags.TrueCondition) && - !isExpressionOfOptionalChainRoot(expression) && !isNullishCoalesce(expression.parent)) { + if ((expression.kind === ts.SyntaxKind.TrueKeyword && flags & ts.FlowFlags.FalseCondition || + expression.kind === ts.SyntaxKind.FalseKeyword && flags & ts.FlowFlags.TrueCondition) && + !ts.isExpressionOfOptionalChainRoot(expression) && !ts.isNullishCoalesce(expression.parent)) { return unreachableFlow; } if (!isNarrowingExpression(expression)) { @@ -1001,12 +1001,12 @@ namespace ts { return initFlowNode({ flags, antecedent, node: expression }); } - function createFlowSwitchClause(antecedent: FlowNode, switchStatement: SwitchStatement, clauseStart: number, clauseEnd: number): FlowNode { + function createFlowSwitchClause(antecedent: ts.FlowNode, switchStatement: ts.SwitchStatement, clauseStart: number, clauseEnd: number): ts.FlowNode { setFlowNodeReferenced(antecedent); - return initFlowNode({ flags: FlowFlags.SwitchClause, antecedent, switchStatement, clauseStart, clauseEnd }); + return initFlowNode({ flags: ts.FlowFlags.SwitchClause, antecedent, switchStatement, clauseStart, clauseEnd }); } - function createFlowMutation(flags: FlowFlags, antecedent: FlowNode, node: Expression | VariableDeclaration | ArrayBindingElement): FlowNode { + function createFlowMutation(flags: ts.FlowFlags, antecedent: ts.FlowNode, node: ts.Expression | ts.VariableDeclaration | ts.ArrayBindingElement): ts.FlowNode { setFlowNodeReferenced(antecedent); const result = initFlowNode({ flags, antecedent, node }); if (currentExceptionTarget) { @@ -1015,12 +1015,12 @@ namespace ts { return result; } - function createFlowCall(antecedent: FlowNode, node: CallExpression): FlowNode { + function createFlowCall(antecedent: ts.FlowNode, node: ts.CallExpression): ts.FlowNode { setFlowNodeReferenced(antecedent); - return initFlowNode({ flags: FlowFlags.Call, antecedent, node }); + return initFlowNode({ flags: ts.FlowFlags.Call, antecedent, node }); } - function finishFlowLabel(flow: FlowLabel): FlowNode { + function finishFlowLabel(flow: ts.FlowLabel): ts.FlowNode { const antecedents = flow.antecedents; if (!antecedents) { return unreachableFlow; @@ -1031,53 +1031,52 @@ namespace ts { return flow; } - function isStatementCondition(node: Node) { + function isStatementCondition(node: ts.Node) { const parent = node.parent; switch (parent.kind) { - case SyntaxKind.IfStatement: - case SyntaxKind.WhileStatement: - case SyntaxKind.DoStatement: - return (parent as IfStatement | WhileStatement | DoStatement).expression === node; - case SyntaxKind.ForStatement: - case SyntaxKind.ConditionalExpression: - return (parent as ForStatement | ConditionalExpression).condition === node; + case ts.SyntaxKind.IfStatement: + case ts.SyntaxKind.WhileStatement: + case ts.SyntaxKind.DoStatement: + return (parent as ts.IfStatement | ts.WhileStatement | ts.DoStatement).expression === node; + case ts.SyntaxKind.ForStatement: + case ts.SyntaxKind.ConditionalExpression: + return (parent as ts.ForStatement | ts.ConditionalExpression).condition === node; } return false; } - function isLogicalExpression(node: Node) { + function isLogicalExpression(node: ts.Node) { while (true) { - if (node.kind === SyntaxKind.ParenthesizedExpression) { - node = (node as ParenthesizedExpression).expression; + if (node.kind === ts.SyntaxKind.ParenthesizedExpression) { + node = (node as ts.ParenthesizedExpression).expression; } - else if (node.kind === SyntaxKind.PrefixUnaryExpression && (node as PrefixUnaryExpression).operator === SyntaxKind.ExclamationToken) { - node = (node as PrefixUnaryExpression).operand; + else if (node.kind === ts.SyntaxKind.PrefixUnaryExpression && (node as ts.PrefixUnaryExpression).operator === ts.SyntaxKind.ExclamationToken) { + node = (node as ts.PrefixUnaryExpression).operand; } else { - return node.kind === SyntaxKind.BinaryExpression && ( - (node as BinaryExpression).operatorToken.kind === SyntaxKind.AmpersandAmpersandToken || - (node as BinaryExpression).operatorToken.kind === SyntaxKind.BarBarToken || - (node as BinaryExpression).operatorToken.kind === SyntaxKind.QuestionQuestionToken); + return node.kind === ts.SyntaxKind.BinaryExpression && ((node as ts.BinaryExpression).operatorToken.kind === ts.SyntaxKind.AmpersandAmpersandToken || + (node as ts.BinaryExpression).operatorToken.kind === ts.SyntaxKind.BarBarToken || + (node as ts.BinaryExpression).operatorToken.kind === ts.SyntaxKind.QuestionQuestionToken); } } } - function isLogicalAssignmentExpression(node: Node) { - node = skipParentheses(node); - return isBinaryExpression(node) && isLogicalOrCoalescingAssignmentOperator(node.operatorToken.kind); + function isLogicalAssignmentExpression(node: ts.Node) { + node = ts.skipParentheses(node); + return ts.isBinaryExpression(node) && ts.isLogicalOrCoalescingAssignmentOperator(node.operatorToken.kind); } - function isTopLevelLogicalExpression(node: Node): boolean { - while (isParenthesizedExpression(node.parent) || - isPrefixUnaryExpression(node.parent) && node.parent.operator === SyntaxKind.ExclamationToken) { + function isTopLevelLogicalExpression(node: ts.Node): boolean { + while (ts.isParenthesizedExpression(node.parent) || + ts.isPrefixUnaryExpression(node.parent) && node.parent.operator === ts.SyntaxKind.ExclamationToken) { node = node.parent; } return !isStatementCondition(node) && !isLogicalExpression(node.parent) && - !(isOptionalChain(node.parent) && node.parent.expression === node); + !(ts.isOptionalChain(node.parent) && node.parent.expression === node); } - function doWithConditionalBranches(action: (value: T) => void, value: T, trueTarget: FlowLabel, falseTarget: FlowLabel) { + function doWithConditionalBranches(action: (value: T) => void, value: T, trueTarget: ts.FlowLabel, falseTarget: ts.FlowLabel) { const savedTrueTarget = currentTrueTarget; const savedFalseTarget = currentFalseTarget; currentTrueTarget = trueTarget; @@ -1087,15 +1086,15 @@ namespace ts { currentFalseTarget = savedFalseTarget; } - function bindCondition(node: Expression | undefined, trueTarget: FlowLabel, falseTarget: FlowLabel) { + function bindCondition(node: ts.Expression | undefined, trueTarget: ts.FlowLabel, falseTarget: ts.FlowLabel) { doWithConditionalBranches(bind, node, trueTarget, falseTarget); - if (!node || !isLogicalAssignmentExpression(node) && !isLogicalExpression(node) && !(isOptionalChain(node) && isOutermostOptionalChain(node))) { - addAntecedent(trueTarget, createFlowCondition(FlowFlags.TrueCondition, currentFlow, node)); - addAntecedent(falseTarget, createFlowCondition(FlowFlags.FalseCondition, currentFlow, node)); + if (!node || !isLogicalAssignmentExpression(node) && !isLogicalExpression(node) && !(ts.isOptionalChain(node) && ts.isOutermostOptionalChain(node))) { + addAntecedent(trueTarget, createFlowCondition(ts.FlowFlags.TrueCondition, currentFlow, node)); + addAntecedent(falseTarget, createFlowCondition(ts.FlowFlags.FalseCondition, currentFlow, node)); } } - function bindIterativeStatement(node: Statement, breakTarget: FlowLabel, continueTarget: FlowLabel): void { + function bindIterativeStatement(node: ts.Statement, breakTarget: ts.FlowLabel, continueTarget: ts.FlowLabel): void { const saveBreakTarget = currentBreakTarget; const saveContinueTarget = currentContinueTarget; currentBreakTarget = breakTarget; @@ -1105,9 +1104,9 @@ namespace ts { currentContinueTarget = saveContinueTarget; } - function setContinueTarget(node: Node, target: FlowLabel) { + function setContinueTarget(node: ts.Node, target: ts.FlowLabel) { let label = activeLabelList; - while (label && node.parent.kind === SyntaxKind.LabeledStatement) { + while (label && node.parent.kind === ts.SyntaxKind.LabeledStatement) { label.continueTarget = target; label = label.next; node = node.parent; @@ -1115,7 +1114,7 @@ namespace ts { return target; } - function bindWhileStatement(node: WhileStatement): void { + function bindWhileStatement(node: ts.WhileStatement): void { const preWhileLabel = setContinueTarget(node, createLoopLabel()); const preBodyLabel = createBranchLabel(); const postWhileLabel = createBranchLabel(); @@ -1128,7 +1127,7 @@ namespace ts { currentFlow = finishFlowLabel(postWhileLabel); } - function bindDoStatement(node: DoStatement): void { + function bindDoStatement(node: ts.DoStatement): void { const preDoLabel = createLoopLabel(); const preConditionLabel = setContinueTarget(node, createBranchLabel()); const postDoLabel = createBranchLabel(); @@ -1141,7 +1140,7 @@ namespace ts { currentFlow = finishFlowLabel(postDoLabel); } - function bindForStatement(node: ForStatement): void { + function bindForStatement(node: ts.ForStatement): void { const preLoopLabel = setContinueTarget(node, createLoopLabel()); const preBodyLabel = createBranchLabel(); const postLoopLabel = createBranchLabel(); @@ -1156,18 +1155,18 @@ namespace ts { currentFlow = finishFlowLabel(postLoopLabel); } - function bindForInOrForOfStatement(node: ForInOrOfStatement): void { + function bindForInOrForOfStatement(node: ts.ForInOrOfStatement): void { const preLoopLabel = setContinueTarget(node, createLoopLabel()); const postLoopLabel = createBranchLabel(); bind(node.expression); addAntecedent(preLoopLabel, currentFlow); currentFlow = preLoopLabel; - if (node.kind === SyntaxKind.ForOfStatement) { + if (node.kind === ts.SyntaxKind.ForOfStatement) { bind(node.awaitModifier); } addAntecedent(postLoopLabel, currentFlow); bind(node.initializer); - if (node.initializer.kind !== SyntaxKind.VariableDeclarationList) { + if (node.initializer.kind !== ts.SyntaxKind.VariableDeclarationList) { bindAssignmentTargetFlow(node.initializer); } bindIterativeStatement(node.statement, postLoopLabel, preLoopLabel); @@ -1175,7 +1174,7 @@ namespace ts { currentFlow = finishFlowLabel(postLoopLabel); } - function bindIfStatement(node: IfStatement): void { + function bindIfStatement(node: ts.IfStatement): void { const thenLabel = createBranchLabel(); const elseLabel = createBranchLabel(); const postIfLabel = createBranchLabel(); @@ -1189,9 +1188,9 @@ namespace ts { currentFlow = finishFlowLabel(postIfLabel); } - function bindReturnOrThrow(node: ReturnStatement | ThrowStatement): void { + function bindReturnOrThrow(node: ts.ReturnStatement | ts.ThrowStatement): void { bind(node.expression); - if (node.kind === SyntaxKind.ReturnStatement) { + if (node.kind === ts.SyntaxKind.ReturnStatement) { hasExplicitReturn = true; if (currentReturnTarget) { addAntecedent(currentReturnTarget, currentFlow); @@ -1200,7 +1199,7 @@ namespace ts { currentFlow = unreachableFlow; } - function findActiveLabel(name: __String) { + function findActiveLabel(name: ts.__String) { for (let label = activeLabelList; label; label = label.next) { if (label.name === name) { return label; @@ -1209,15 +1208,15 @@ namespace ts { return undefined; } - function bindBreakOrContinueFlow(node: BreakOrContinueStatement, breakTarget: FlowLabel | undefined, continueTarget: FlowLabel | undefined) { - const flowLabel = node.kind === SyntaxKind.BreakStatement ? breakTarget : continueTarget; + function bindBreakOrContinueFlow(node: ts.BreakOrContinueStatement, breakTarget: ts.FlowLabel | undefined, continueTarget: ts.FlowLabel | undefined) { + const flowLabel = node.kind === ts.SyntaxKind.BreakStatement ? breakTarget : continueTarget; if (flowLabel) { addAntecedent(flowLabel, currentFlow); currentFlow = unreachableFlow; } } - function bindBreakOrContinueStatement(node: BreakOrContinueStatement): void { + function bindBreakOrContinueStatement(node: ts.BreakOrContinueStatement): void { bind(node.label); if (node.label) { const activeLabel = findActiveLabel(node.label.escapedText); @@ -1231,7 +1230,7 @@ namespace ts { } } - function bindTryStatement(node: TryStatement): void { + function bindTryStatement(node: ts.TryStatement): void { // We conservatively assume that *any* code in the try block can cause an exception, but we only need // to track code that causes mutations (because only mutations widen the possible control flow type of // a variable). The exceptionLabel is the target label for control flows that result from exceptions. @@ -1280,10 +1279,10 @@ namespace ts { // set of antecedents for the pre-finally label. As control flow analysis passes by a ReduceLabel // node, the pre-finally label is temporarily switched to the reduced antecedent set. const finallyLabel = createBranchLabel(); - finallyLabel.antecedents = concatenate(concatenate(normalExitLabel.antecedents, exceptionLabel.antecedents), returnLabel.antecedents); + finallyLabel.antecedents = ts.concatenate(ts.concatenate(normalExitLabel.antecedents, exceptionLabel.antecedents), returnLabel.antecedents); currentFlow = finallyLabel; bind(node.finallyBlock); - if (currentFlow.flags & FlowFlags.Unreachable) { + if (currentFlow.flags & ts.FlowFlags.Unreachable) { // If the end of the finally block is unreachable, the end of the entire try statement is unreachable. currentFlow = unreachableFlow; } @@ -1309,7 +1308,7 @@ namespace ts { } } - function bindSwitchStatement(node: SwitchStatement): void { + function bindSwitchStatement(node: ts.SwitchStatement): void { const postSwitchLabel = createBranchLabel(); bind(node.expression); const saveBreakTarget = currentBreakTarget; @@ -1318,7 +1317,7 @@ namespace ts { preSwitchCaseFlow = currentFlow; bind(node.caseBlock); addAntecedent(postSwitchLabel, currentFlow); - const hasDefault = forEach(node.caseBlock.clauses, c => c.kind === SyntaxKind.DefaultClause); + const hasDefault = ts.forEach(node.caseBlock.clauses, c => c.kind === ts.SyntaxKind.DefaultClause); // We mark a switch statement as possibly exhaustive if it has no default clause and if all // case clauses have unreachable end points (e.g. they all return). Note, we no longer need // this property in control flow analysis, it's there only for backwards compatibility. @@ -1331,7 +1330,7 @@ namespace ts { currentFlow = finishFlowLabel(postSwitchLabel); } - function bindCaseBlock(node: CaseBlock): void { + function bindCaseBlock(node: ts.CaseBlock): void { const clauses = node.clauses; const isNarrowingSwitch = isNarrowingExpression(node.parent.expression); let fallthroughFlow = unreachableFlow; @@ -1348,13 +1347,13 @@ namespace ts { const clause = clauses[i]; bind(clause); fallthroughFlow = currentFlow; - if (!(currentFlow.flags & FlowFlags.Unreachable) && i !== clauses.length - 1 && options.noFallthroughCasesInSwitch) { + if (!(currentFlow.flags & ts.FlowFlags.Unreachable) && i !== clauses.length - 1 && options.noFallthroughCasesInSwitch) { clause.fallthroughFlowNode = currentFlow; } } } - function bindCaseClause(node: CaseClause): void { + function bindCaseClause(node: ts.CaseClause): void { const saveCurrentFlow = currentFlow; currentFlow = preSwitchCaseFlow!; bind(node.expression); @@ -1362,23 +1361,23 @@ namespace ts { bindEach(node.statements); } - function bindExpressionStatement(node: ExpressionStatement): void { + function bindExpressionStatement(node: ts.ExpressionStatement): void { bind(node.expression); maybeBindExpressionFlowIfCall(node.expression); } - function maybeBindExpressionFlowIfCall(node: Expression) { + function maybeBindExpressionFlowIfCall(node: ts.Expression) { // A top level or comma expression call expression with a dotted function name and at least one argument // is potentially an assertion and is therefore included in the control flow. - if (node.kind === SyntaxKind.CallExpression) { - const call = node as CallExpression; - if (call.expression.kind !== SyntaxKind.SuperKeyword && isDottedName(call.expression)) { + if (node.kind === ts.SyntaxKind.CallExpression) { + const call = node as ts.CallExpression; + if (call.expression.kind !== ts.SyntaxKind.SuperKeyword && ts.isDottedName(call.expression)) { currentFlow = createFlowCall(currentFlow, call); } } } - function bindLabeledStatement(node: LabeledStatement): void { + function bindLabeledStatement(node: ts.LabeledStatement): void { const postStatementLabel = createBranchLabel(); activeLabelList = { next: activeLabelList, @@ -1390,54 +1389,54 @@ namespace ts { bind(node.label); bind(node.statement); if (!activeLabelList.referenced && !options.allowUnusedLabels) { - errorOrSuggestionOnNode(unusedLabelIsError(options), node.label, Diagnostics.Unused_label); + errorOrSuggestionOnNode(ts.unusedLabelIsError(options), node.label, ts.Diagnostics.Unused_label); } activeLabelList = activeLabelList.next; addAntecedent(postStatementLabel, currentFlow); currentFlow = finishFlowLabel(postStatementLabel); } - function bindDestructuringTargetFlow(node: Expression) { - if (node.kind === SyntaxKind.BinaryExpression && (node as BinaryExpression).operatorToken.kind === SyntaxKind.EqualsToken) { - bindAssignmentTargetFlow((node as BinaryExpression).left); + function bindDestructuringTargetFlow(node: ts.Expression) { + if (node.kind === ts.SyntaxKind.BinaryExpression && (node as ts.BinaryExpression).operatorToken.kind === ts.SyntaxKind.EqualsToken) { + bindAssignmentTargetFlow((node as ts.BinaryExpression).left); } else { bindAssignmentTargetFlow(node); } } - function bindAssignmentTargetFlow(node: Expression) { + function bindAssignmentTargetFlow(node: ts.Expression) { if (isNarrowableReference(node)) { - currentFlow = createFlowMutation(FlowFlags.Assignment, currentFlow, node); + currentFlow = createFlowMutation(ts.FlowFlags.Assignment, currentFlow, node); } - else if (node.kind === SyntaxKind.ArrayLiteralExpression) { - for (const e of (node as ArrayLiteralExpression).elements) { - if (e.kind === SyntaxKind.SpreadElement) { - bindAssignmentTargetFlow((e as SpreadElement).expression); + else if (node.kind === ts.SyntaxKind.ArrayLiteralExpression) { + for (const e of (node as ts.ArrayLiteralExpression).elements) { + if (e.kind === ts.SyntaxKind.SpreadElement) { + bindAssignmentTargetFlow((e as ts.SpreadElement).expression); } else { bindDestructuringTargetFlow(e); } } } - else if (node.kind === SyntaxKind.ObjectLiteralExpression) { - for (const p of (node as ObjectLiteralExpression).properties) { - if (p.kind === SyntaxKind.PropertyAssignment) { + else if (node.kind === ts.SyntaxKind.ObjectLiteralExpression) { + for (const p of (node as ts.ObjectLiteralExpression).properties) { + if (p.kind === ts.SyntaxKind.PropertyAssignment) { bindDestructuringTargetFlow(p.initializer); } - else if (p.kind === SyntaxKind.ShorthandPropertyAssignment) { + else if (p.kind === ts.SyntaxKind.ShorthandPropertyAssignment) { bindAssignmentTargetFlow(p.name); } - else if (p.kind === SyntaxKind.SpreadAssignment) { + else if (p.kind === ts.SyntaxKind.SpreadAssignment) { bindAssignmentTargetFlow(p.expression); } } } } - function bindLogicalLikeExpression(node: BinaryExpression, trueTarget: FlowLabel, falseTarget: FlowLabel) { + function bindLogicalLikeExpression(node: ts.BinaryExpression, trueTarget: ts.FlowLabel, falseTarget: ts.FlowLabel) { const preRightLabel = createBranchLabel(); - if (node.operatorToken.kind === SyntaxKind.AmpersandAmpersandToken || node.operatorToken.kind === SyntaxKind.AmpersandAmpersandEqualsToken) { + if (node.operatorToken.kind === ts.SyntaxKind.AmpersandAmpersandToken || node.operatorToken.kind === ts.SyntaxKind.AmpersandAmpersandEqualsToken) { bindCondition(node.left, preRightLabel, falseTarget); } else { @@ -1446,20 +1445,20 @@ namespace ts { currentFlow = finishFlowLabel(preRightLabel); bind(node.operatorToken); - if (isLogicalOrCoalescingAssignmentOperator(node.operatorToken.kind)) { + if (ts.isLogicalOrCoalescingAssignmentOperator(node.operatorToken.kind)) { doWithConditionalBranches(bind, node.right, trueTarget, falseTarget); bindAssignmentTargetFlow(node.left); - addAntecedent(trueTarget, createFlowCondition(FlowFlags.TrueCondition, currentFlow, node)); - addAntecedent(falseTarget, createFlowCondition(FlowFlags.FalseCondition, currentFlow, node)); + addAntecedent(trueTarget, createFlowCondition(ts.FlowFlags.TrueCondition, currentFlow, node)); + addAntecedent(falseTarget, createFlowCondition(ts.FlowFlags.FalseCondition, currentFlow, node)); } else { bindCondition(node.right, trueTarget, falseTarget); } } - function bindPrefixUnaryExpressionFlow(node: PrefixUnaryExpression) { - if (node.operator === SyntaxKind.ExclamationToken) { + function bindPrefixUnaryExpressionFlow(node: ts.PrefixUnaryExpression) { + if (node.operator === ts.SyntaxKind.ExclamationToken) { const saveTrueTarget = currentTrueTarget; currentTrueTarget = currentFalseTarget; currentFalseTarget = saveTrueTarget; @@ -1469,20 +1468,20 @@ namespace ts { } else { bindEachChild(node); - if (node.operator === SyntaxKind.PlusPlusToken || node.operator === SyntaxKind.MinusMinusToken) { + if (node.operator === ts.SyntaxKind.PlusPlusToken || node.operator === ts.SyntaxKind.MinusMinusToken) { bindAssignmentTargetFlow(node.operand); } } } - function bindPostfixUnaryExpressionFlow(node: PostfixUnaryExpression) { + function bindPostfixUnaryExpressionFlow(node: ts.PostfixUnaryExpression) { bindEachChild(node); - if (node.operator === SyntaxKind.PlusPlusToken || node.operator === SyntaxKind.MinusMinusToken) { + if (node.operator === ts.SyntaxKind.PlusPlusToken || node.operator === ts.SyntaxKind.MinusMinusToken) { bindAssignmentTargetFlow(node.operand); } } - function bindDestructuringAssignmentFlow(node: DestructuringAssignment) { + function bindDestructuringAssignmentFlow(node: ts.DestructuringAssignment) { if (inAssignmentPattern) { inAssignmentPattern = false; bind(node.operatorToken); @@ -1505,17 +1504,16 @@ namespace ts { stackIndex: number; skip: boolean; inStrictModeStack: (boolean | undefined)[]; - parentStack: (Node | undefined)[]; + parentStack: (ts.Node | undefined)[]; } - return createBinaryExpressionTrampoline(onEnter, onLeft, onOperator, onRight, onExit, /*foldState*/ undefined); - - function onEnter(node: BinaryExpression, state: WorkArea | undefined) { + return ts.createBinaryExpressionTrampoline(onEnter, onLeft, onOperator, onRight, onExit, /*foldState*/ undefined); + function onEnter(node: ts.BinaryExpression, state: WorkArea | undefined) { if (state) { state.stackIndex++; // Emulate the work that `bind` does before reaching `bindChildren`. A normal call to // `bindBinaryExpressionFlow` will already have done this work. - setParent(node, parent); + ts.setParent(node, parent); const saveInStrictMode = inStrictMode; bindWorker(node); const saveParent = parent; @@ -1536,10 +1534,10 @@ namespace ts { // we'll need to handle the `bindLogicalExpression` scenarios in this state machine, too // For now, though, since the common cases are chained `+`, leaving it recursive is fine const operator = node.operatorToken.kind; - if (operator === SyntaxKind.AmpersandAmpersandToken || - operator === SyntaxKind.BarBarToken || - operator === SyntaxKind.QuestionQuestionToken || - isLogicalOrCoalescingAssignmentOperator(operator)) { + if (operator === ts.SyntaxKind.AmpersandAmpersandToken || + operator === ts.SyntaxKind.BarBarToken || + operator === ts.SyntaxKind.QuestionQuestionToken || + ts.isLogicalOrCoalescingAssignmentOperator(operator)) { if (isTopLevelLogicalExpression(node)) { const postExpressionLabel = createBranchLabel(); bindLogicalLikeExpression(node, postExpressionLabel, postExpressionLabel); @@ -1553,41 +1551,41 @@ namespace ts { return state; } - function onLeft(left: Expression, state: WorkArea, node: BinaryExpression) { + function onLeft(left: ts.Expression, state: WorkArea, node: ts.BinaryExpression) { if (!state.skip) { const maybeBound = maybeBind(left); - if (node.operatorToken.kind === SyntaxKind.CommaToken) { + if (node.operatorToken.kind === ts.SyntaxKind.CommaToken) { maybeBindExpressionFlowIfCall(left); } return maybeBound; } } - function onOperator(operatorToken: BinaryOperatorToken, state: WorkArea, _node: BinaryExpression) { + function onOperator(operatorToken: ts.BinaryOperatorToken, state: WorkArea, _node: ts.BinaryExpression) { if (!state.skip) { bind(operatorToken); } } - function onRight(right: Expression, state: WorkArea, node: BinaryExpression) { + function onRight(right: ts.Expression, state: WorkArea, node: ts.BinaryExpression) { if (!state.skip) { const maybeBound = maybeBind(right); - if (node.operatorToken.kind === SyntaxKind.CommaToken) { + if (node.operatorToken.kind === ts.SyntaxKind.CommaToken) { maybeBindExpressionFlowIfCall(right); } return maybeBound; } } - function onExit(node: BinaryExpression, state: WorkArea) { + function onExit(node: ts.BinaryExpression, state: WorkArea) { if (!state.skip) { const operator = node.operatorToken.kind; - if (isAssignmentOperator(operator) && !isAssignmentTarget(node)) { + if (ts.isAssignmentOperator(operator) && !ts.isAssignmentTarget(node)) { bindAssignmentTargetFlow(node.left); - if (operator === SyntaxKind.EqualsToken && node.left.kind === SyntaxKind.ElementAccessExpression) { - const elementAccess = node.left as ElementAccessExpression; + if (operator === ts.SyntaxKind.EqualsToken && node.left.kind === ts.SyntaxKind.ElementAccessExpression) { + const elementAccess = node.left as ts.ElementAccessExpression; if (isNarrowableOperand(elementAccess.expression)) { - currentFlow = createFlowMutation(FlowFlags.ArrayMutation, currentFlow, node); + currentFlow = createFlowMutation(ts.FlowFlags.ArrayMutation, currentFlow, node); } } } @@ -1604,22 +1602,22 @@ namespace ts { state.stackIndex--; } - function maybeBind(node: Node) { - if (node && isBinaryExpression(node) && !isDestructuringAssignment(node)) { + function maybeBind(node: ts.Node) { + if (node && ts.isBinaryExpression(node) && !ts.isDestructuringAssignment(node)) { return node; } bind(node); } } - function bindDeleteExpressionFlow(node: DeleteExpression) { + function bindDeleteExpressionFlow(node: ts.DeleteExpression) { bindEachChild(node); - if (node.expression.kind === SyntaxKind.PropertyAccessExpression) { + if (node.expression.kind === ts.SyntaxKind.PropertyAccessExpression) { bindAssignmentTargetFlow(node.expression); } } - function bindConditionalExpressionFlow(node: ConditionalExpression) { + function bindConditionalExpressionFlow(node: ts.ConditionalExpression) { const trueLabel = createBranchLabel(); const falseLabel = createBranchLabel(); const postExpressionLabel = createBranchLabel(); @@ -1635,27 +1633,27 @@ namespace ts { currentFlow = finishFlowLabel(postExpressionLabel); } - function bindInitializedVariableFlow(node: VariableDeclaration | ArrayBindingElement) { - const name = !isOmittedExpression(node) ? node.name : undefined; - if (isBindingPattern(name)) { + function bindInitializedVariableFlow(node: ts.VariableDeclaration | ts.ArrayBindingElement) { + const name = !ts.isOmittedExpression(node) ? node.name : undefined; + if (ts.isBindingPattern(name)) { for (const child of name.elements) { bindInitializedVariableFlow(child); } } else { - currentFlow = createFlowMutation(FlowFlags.Assignment, currentFlow, node); + currentFlow = createFlowMutation(ts.FlowFlags.Assignment, currentFlow, node); } } - function bindVariableDeclarationFlow(node: VariableDeclaration) { + function bindVariableDeclarationFlow(node: ts.VariableDeclaration) { bindEachChild(node); - if (node.initializer || isForInOrOfStatement(node.parent.parent)) { + if (node.initializer || ts.isForInOrOfStatement(node.parent.parent)) { bindInitializedVariableFlow(node); } } - function bindBindingElementFlow(node: BindingElement) { - if (isBindingPattern(node.name)) { + function bindBindingElementFlow(node: ts.BindingElement) { + if (ts.isBindingPattern(node.name)) { // When evaluating a binding pattern, the initializer is evaluated before the binding pattern, per: // - https://tc39.es/ecma262/#sec-destructuring-binding-patterns-runtime-semantics-iteratorbindinginitialization // - `BindingElement: BindingPattern Initializer?` @@ -1673,45 +1671,45 @@ namespace ts { } } - function bindJSDocTypeAlias(node: JSDocTypedefTag | JSDocCallbackTag | JSDocEnumTag) { + function bindJSDocTypeAlias(node: ts.JSDocTypedefTag | ts.JSDocCallbackTag | ts.JSDocEnumTag) { bind(node.tagName); - if (node.kind !== SyntaxKind.JSDocEnumTag && node.fullName) { + if (node.kind !== ts.SyntaxKind.JSDocEnumTag && node.fullName) { // don't bind the type name yet; that's delayed until delayedBindJSDocTypedefTag - setParent(node.fullName, node); - setParentRecursive(node.fullName, /*incremental*/ false); + ts.setParent(node.fullName, node); + ts.setParentRecursive(node.fullName, /*incremental*/ false); } if (typeof node.comment !== "string") { bindEach(node.comment); } } - function bindJSDocClassTag(node: JSDocClassTag) { + function bindJSDocClassTag(node: ts.JSDocClassTag) { bindEachChild(node); - const host = getHostSignatureFromJSDoc(node); - if (host && host.kind !== SyntaxKind.MethodDeclaration) { - addDeclarationToSymbol(host.symbol, host, SymbolFlags.Class); + const host = ts.getHostSignatureFromJSDoc(node); + if (host && host.kind !== ts.SyntaxKind.MethodDeclaration) { + addDeclarationToSymbol(host.symbol, host, ts.SymbolFlags.Class); } } - function bindOptionalExpression(node: Expression, trueTarget: FlowLabel, falseTarget: FlowLabel) { + function bindOptionalExpression(node: ts.Expression, trueTarget: ts.FlowLabel, falseTarget: ts.FlowLabel) { doWithConditionalBranches(bind, node, trueTarget, falseTarget); - if (!isOptionalChain(node) || isOutermostOptionalChain(node)) { - addAntecedent(trueTarget, createFlowCondition(FlowFlags.TrueCondition, currentFlow, node)); - addAntecedent(falseTarget, createFlowCondition(FlowFlags.FalseCondition, currentFlow, node)); + if (!ts.isOptionalChain(node) || ts.isOutermostOptionalChain(node)) { + addAntecedent(trueTarget, createFlowCondition(ts.FlowFlags.TrueCondition, currentFlow, node)); + addAntecedent(falseTarget, createFlowCondition(ts.FlowFlags.FalseCondition, currentFlow, node)); } } - function bindOptionalChainRest(node: OptionalChain) { + function bindOptionalChainRest(node: ts.OptionalChain) { switch (node.kind) { - case SyntaxKind.PropertyAccessExpression: + case ts.SyntaxKind.PropertyAccessExpression: bind(node.questionDotToken); bind(node.name); break; - case SyntaxKind.ElementAccessExpression: + case ts.SyntaxKind.ElementAccessExpression: bind(node.questionDotToken); bind(node.argumentExpression); break; - case SyntaxKind.CallExpression: + case ts.SyntaxKind.CallExpression: bind(node.questionDotToken); bindEach(node.typeArguments); bindEach(node.arguments); @@ -1719,7 +1717,7 @@ namespace ts { } } - function bindOptionalChain(node: OptionalChain, trueTarget: FlowLabel, falseTarget: FlowLabel) { + function bindOptionalChain(node: ts.OptionalChain, trueTarget: ts.FlowLabel, falseTarget: ts.FlowLabel) { // For an optional chain, we emulate the behavior of a logical expression: // // a?.b -> a && a.b @@ -1731,19 +1729,19 @@ namespace ts { // and build it's CFA graph as if it were the first condition (`a && ...`). Then we bind the rest // of the node as part of the "true" branch, and continue to do so as we ascend back up to the outermost // chain node. We then treat the entire node as the right side of the expression. - const preChainLabel = isOptionalChainRoot(node) ? createBranchLabel() : undefined; + const preChainLabel = ts.isOptionalChainRoot(node) ? createBranchLabel() : undefined; bindOptionalExpression(node.expression, preChainLabel || trueTarget, falseTarget); if (preChainLabel) { currentFlow = finishFlowLabel(preChainLabel); } doWithConditionalBranches(bindOptionalChainRest, node, trueTarget, falseTarget); - if (isOutermostOptionalChain(node)) { - addAntecedent(trueTarget, createFlowCondition(FlowFlags.TrueCondition, currentFlow, node)); - addAntecedent(falseTarget, createFlowCondition(FlowFlags.FalseCondition, currentFlow, node)); + if (ts.isOutermostOptionalChain(node)) { + addAntecedent(trueTarget, createFlowCondition(ts.FlowFlags.TrueCondition, currentFlow, node)); + addAntecedent(falseTarget, createFlowCondition(ts.FlowFlags.FalseCondition, currentFlow, node)); } } - function bindOptionalChainFlow(node: OptionalChain) { + function bindOptionalChainFlow(node: ts.OptionalChain) { if (isTopLevelLogicalExpression(node)) { const postExpressionLabel = createBranchLabel(); bindOptionalChain(node, postExpressionLabel, postExpressionLabel); @@ -1754,8 +1752,8 @@ namespace ts { } } - function bindNonNullExpressionFlow(node: NonNullExpression | NonNullChain) { - if (isOptionalChain(node)) { + function bindNonNullExpressionFlow(node: ts.NonNullExpression | ts.NonNullChain) { + if (ts.isOptionalChain(node)) { bindOptionalChainFlow(node); } else { @@ -1763,8 +1761,8 @@ namespace ts { } } - function bindAccessExpressionFlow(node: AccessExpression | PropertyAccessChain | ElementAccessChain) { - if (isOptionalChain(node)) { + function bindAccessExpressionFlow(node: ts.AccessExpression | ts.PropertyAccessChain | ts.ElementAccessChain) { + if (ts.isOptionalChain(node)) { bindOptionalChainFlow(node); } else { @@ -1772,94 +1770,93 @@ namespace ts { } } - function bindCallExpressionFlow(node: CallExpression | CallChain) { - if (isOptionalChain(node)) { + function bindCallExpressionFlow(node: ts.CallExpression | ts.CallChain) { + if (ts.isOptionalChain(node)) { bindOptionalChainFlow(node); } else { // If the target of the call expression is a function expression or arrow function we have // an immediately invoked function expression (IIFE). Initialize the flowNode property to // the current control flow (which includes evaluation of the IIFE arguments). - const expr = skipParentheses(node.expression); - if (expr.kind === SyntaxKind.FunctionExpression || expr.kind === SyntaxKind.ArrowFunction) { + const expr = ts.skipParentheses(node.expression); + if (expr.kind === ts.SyntaxKind.FunctionExpression || expr.kind === ts.SyntaxKind.ArrowFunction) { bindEach(node.typeArguments); bindEach(node.arguments); bind(node.expression); } else { bindEachChild(node); - if (node.expression.kind === SyntaxKind.SuperKeyword) { + if (node.expression.kind === ts.SyntaxKind.SuperKeyword) { currentFlow = createFlowCall(currentFlow, node); } } } - if (node.expression.kind === SyntaxKind.PropertyAccessExpression) { - const propertyAccess = node.expression as PropertyAccessExpression; - if (isIdentifier(propertyAccess.name) && isNarrowableOperand(propertyAccess.expression) && isPushOrUnshiftIdentifier(propertyAccess.name)) { - currentFlow = createFlowMutation(FlowFlags.ArrayMutation, currentFlow, node); + if (node.expression.kind === ts.SyntaxKind.PropertyAccessExpression) { + const propertyAccess = node.expression as ts.PropertyAccessExpression; + if (ts.isIdentifier(propertyAccess.name) && isNarrowableOperand(propertyAccess.expression) && ts.isPushOrUnshiftIdentifier(propertyAccess.name)) { + currentFlow = createFlowMutation(ts.FlowFlags.ArrayMutation, currentFlow, node); } } } - function getContainerFlags(node: Node): ContainerFlags { + function getContainerFlags(node: ts.Node): ContainerFlags { switch (node.kind) { - case SyntaxKind.ClassExpression: - case SyntaxKind.ClassDeclaration: - case SyntaxKind.EnumDeclaration: - case SyntaxKind.ObjectLiteralExpression: - case SyntaxKind.TypeLiteral: - case SyntaxKind.JSDocTypeLiteral: - case SyntaxKind.JsxAttributes: + case ts.SyntaxKind.ClassExpression: + case ts.SyntaxKind.ClassDeclaration: + case ts.SyntaxKind.EnumDeclaration: + case ts.SyntaxKind.ObjectLiteralExpression: + case ts.SyntaxKind.TypeLiteral: + case ts.SyntaxKind.JSDocTypeLiteral: + case ts.SyntaxKind.JsxAttributes: return ContainerFlags.IsContainer; - case SyntaxKind.InterfaceDeclaration: + case ts.SyntaxKind.InterfaceDeclaration: return ContainerFlags.IsContainer | ContainerFlags.IsInterface; - case SyntaxKind.ModuleDeclaration: - case SyntaxKind.TypeAliasDeclaration: - case SyntaxKind.MappedType: - case SyntaxKind.IndexSignature: + case ts.SyntaxKind.ModuleDeclaration: + case ts.SyntaxKind.TypeAliasDeclaration: + case ts.SyntaxKind.MappedType: + case ts.SyntaxKind.IndexSignature: return ContainerFlags.IsContainer | ContainerFlags.HasLocals; - case SyntaxKind.SourceFile: + case ts.SyntaxKind.SourceFile: return ContainerFlags.IsContainer | ContainerFlags.IsControlFlowContainer | ContainerFlags.HasLocals; - case SyntaxKind.GetAccessor: - case SyntaxKind.SetAccessor: - case SyntaxKind.MethodDeclaration: - if (isObjectLiteralOrClassExpressionMethodOrAccessor(node)) { + case ts.SyntaxKind.GetAccessor: + case ts.SyntaxKind.SetAccessor: + case ts.SyntaxKind.MethodDeclaration: + if (ts.isObjectLiteralOrClassExpressionMethodOrAccessor(node)) { return ContainerFlags.IsContainer | ContainerFlags.IsControlFlowContainer | ContainerFlags.HasLocals | ContainerFlags.IsFunctionLike | ContainerFlags.IsObjectLiteralOrClassExpressionMethodOrAccessor; } // falls through - case SyntaxKind.Constructor: - case SyntaxKind.FunctionDeclaration: - case SyntaxKind.MethodSignature: - case SyntaxKind.CallSignature: - case SyntaxKind.JSDocSignature: - case SyntaxKind.JSDocFunctionType: - case SyntaxKind.FunctionType: - case SyntaxKind.ConstructSignature: - case SyntaxKind.ConstructorType: - case SyntaxKind.ClassStaticBlockDeclaration: + case ts.SyntaxKind.Constructor: + case ts.SyntaxKind.FunctionDeclaration: + case ts.SyntaxKind.MethodSignature: + case ts.SyntaxKind.CallSignature: + case ts.SyntaxKind.JSDocSignature: + case ts.SyntaxKind.JSDocFunctionType: + case ts.SyntaxKind.FunctionType: + case ts.SyntaxKind.ConstructSignature: + case ts.SyntaxKind.ConstructorType: + case ts.SyntaxKind.ClassStaticBlockDeclaration: return ContainerFlags.IsContainer | ContainerFlags.IsControlFlowContainer | ContainerFlags.HasLocals | ContainerFlags.IsFunctionLike; - case SyntaxKind.FunctionExpression: - case SyntaxKind.ArrowFunction: + case ts.SyntaxKind.FunctionExpression: + case ts.SyntaxKind.ArrowFunction: return ContainerFlags.IsContainer | ContainerFlags.IsControlFlowContainer | ContainerFlags.HasLocals | ContainerFlags.IsFunctionLike | ContainerFlags.IsFunctionExpression; - case SyntaxKind.ModuleBlock: + case ts.SyntaxKind.ModuleBlock: return ContainerFlags.IsControlFlowContainer; - case SyntaxKind.PropertyDeclaration: - return (node as PropertyDeclaration).initializer ? ContainerFlags.IsControlFlowContainer : 0; - - case SyntaxKind.CatchClause: - case SyntaxKind.ForStatement: - case SyntaxKind.ForInStatement: - case SyntaxKind.ForOfStatement: - case SyntaxKind.CaseBlock: + case ts.SyntaxKind.PropertyDeclaration: + return (node as ts.PropertyDeclaration).initializer ? ContainerFlags.IsControlFlowContainer : 0; + case ts.SyntaxKind.CatchClause: + case ts.SyntaxKind.ForStatement: + case ts.SyntaxKind.ForInStatement: + case ts.SyntaxKind.ForOfStatement: + case ts.SyntaxKind.CaseBlock: return ContainerFlags.IsBlockScopedContainer; - case SyntaxKind.Block: + case ts.SyntaxKind.Block: // do not treat blocks directly inside a function as a block-scoped-container. // Locals that reside in this block should go to the function locals. Otherwise 'x' // would not appear to be a redeclaration of a block scoped local in the following @@ -1876,13 +1873,13 @@ namespace ts { // By not creating a new block-scoped-container here, we ensure that both 'var x' // and 'let x' go into the Function-container's locals, and we do get a collision // conflict. - return isFunctionLike(node.parent) || isClassStaticBlockDeclaration(node.parent) ? ContainerFlags.None : ContainerFlags.IsBlockScopedContainer; + return ts.isFunctionLike(node.parent) || ts.isClassStaticBlockDeclaration(node.parent) ? ContainerFlags.None : ContainerFlags.IsBlockScopedContainer; } return ContainerFlags.None; } - function addToContainerChain(next: Node) { + function addToContainerChain(next: ts.Node) { if (lastContainer) { lastContainer.nextContainer = next; } @@ -1890,30 +1887,30 @@ namespace ts { lastContainer = next; } - function declareSymbolAndAddToSymbolTable(node: Declaration, symbolFlags: SymbolFlags, symbolExcludes: SymbolFlags): Symbol | undefined { + function declareSymbolAndAddToSymbolTable(node: ts.Declaration, symbolFlags: ts.SymbolFlags, symbolExcludes: ts.SymbolFlags): ts.Symbol | undefined { switch (container.kind) { // Modules, source files, and classes need specialized handling for how their // members are declared (for example, a member of a class will go into a specific // symbol table depending on if it is static or not). We defer to specialized // handlers to take care of declaring these child members. - case SyntaxKind.ModuleDeclaration: + case ts.SyntaxKind.ModuleDeclaration: return declareModuleMember(node, symbolFlags, symbolExcludes); - case SyntaxKind.SourceFile: + case ts.SyntaxKind.SourceFile: return declareSourceFileMember(node, symbolFlags, symbolExcludes); - case SyntaxKind.ClassExpression: - case SyntaxKind.ClassDeclaration: + case ts.SyntaxKind.ClassExpression: + case ts.SyntaxKind.ClassDeclaration: return declareClassMember(node, symbolFlags, symbolExcludes); - case SyntaxKind.EnumDeclaration: + case ts.SyntaxKind.EnumDeclaration: return declareSymbol(container.symbol.exports!, container.symbol, node, symbolFlags, symbolExcludes); - case SyntaxKind.TypeLiteral: - case SyntaxKind.JSDocTypeLiteral: - case SyntaxKind.ObjectLiteralExpression: - case SyntaxKind.InterfaceDeclaration: - case SyntaxKind.JsxAttributes: + case ts.SyntaxKind.TypeLiteral: + case ts.SyntaxKind.JSDocTypeLiteral: + case ts.SyntaxKind.ObjectLiteralExpression: + case ts.SyntaxKind.InterfaceDeclaration: + case ts.SyntaxKind.JsxAttributes: // Interface/Object-types always have their children added to the 'members' of // their container. They are only accessible through an instance of their // container, and are never in scope otherwise (even inside the body of the @@ -1921,26 +1918,26 @@ namespace ts { // which are in scope without qualification (similar to 'locals'). return declareSymbol(container.symbol.members!, container.symbol, node, symbolFlags, symbolExcludes); - case SyntaxKind.FunctionType: - case SyntaxKind.ConstructorType: - case SyntaxKind.CallSignature: - case SyntaxKind.ConstructSignature: - case SyntaxKind.JSDocSignature: - case SyntaxKind.IndexSignature: - case SyntaxKind.MethodDeclaration: - case SyntaxKind.MethodSignature: - case SyntaxKind.Constructor: - case SyntaxKind.GetAccessor: - case SyntaxKind.SetAccessor: - case SyntaxKind.FunctionDeclaration: - case SyntaxKind.FunctionExpression: - case SyntaxKind.ArrowFunction: - case SyntaxKind.JSDocFunctionType: - case SyntaxKind.JSDocTypedefTag: - case SyntaxKind.JSDocCallbackTag: - case SyntaxKind.ClassStaticBlockDeclaration: - case SyntaxKind.TypeAliasDeclaration: - case SyntaxKind.MappedType: + case ts.SyntaxKind.FunctionType: + case ts.SyntaxKind.ConstructorType: + case ts.SyntaxKind.CallSignature: + case ts.SyntaxKind.ConstructSignature: + case ts.SyntaxKind.JSDocSignature: + case ts.SyntaxKind.IndexSignature: + case ts.SyntaxKind.MethodDeclaration: + case ts.SyntaxKind.MethodSignature: + case ts.SyntaxKind.Constructor: + case ts.SyntaxKind.GetAccessor: + case ts.SyntaxKind.SetAccessor: + case ts.SyntaxKind.FunctionDeclaration: + case ts.SyntaxKind.FunctionExpression: + case ts.SyntaxKind.ArrowFunction: + case ts.SyntaxKind.JSDocFunctionType: + case ts.SyntaxKind.JSDocTypedefTag: + case ts.SyntaxKind.JSDocCallbackTag: + case ts.SyntaxKind.ClassStaticBlockDeclaration: + case ts.SyntaxKind.TypeAliasDeclaration: + case ts.SyntaxKind.MappedType: // All the children of these container types are never visible through another // symbol (i.e. through another symbol's 'exports' or 'members'). Instead, // they're only accessed 'lexically' (i.e. from code that exists underneath @@ -1951,55 +1948,55 @@ namespace ts { } } - function declareClassMember(node: Declaration, symbolFlags: SymbolFlags, symbolExcludes: SymbolFlags) { - return isStatic(node) + function declareClassMember(node: ts.Declaration, symbolFlags: ts.SymbolFlags, symbolExcludes: ts.SymbolFlags) { + return ts.isStatic(node) ? declareSymbol(container.symbol.exports!, container.symbol, node, symbolFlags, symbolExcludes) : declareSymbol(container.symbol.members!, container.symbol, node, symbolFlags, symbolExcludes); } - function declareSourceFileMember(node: Declaration, symbolFlags: SymbolFlags, symbolExcludes: SymbolFlags) { - return isExternalModule(file) + function declareSourceFileMember(node: ts.Declaration, symbolFlags: ts.SymbolFlags, symbolExcludes: ts.SymbolFlags) { + return ts.isExternalModule(file) ? declareModuleMember(node, symbolFlags, symbolExcludes) : declareSymbol(file.locals!, /*parent*/ undefined, node, symbolFlags, symbolExcludes); } - function hasExportDeclarations(node: ModuleDeclaration | SourceFile): boolean { - const body = isSourceFile(node) ? node : tryCast(node.body, isModuleBlock); - return !!body && body.statements.some(s => isExportDeclaration(s) || isExportAssignment(s)); + function hasExportDeclarations(node: ts.ModuleDeclaration | ts.SourceFile): boolean { + const body = ts.isSourceFile(node) ? node : ts.tryCast(node.body, ts.isModuleBlock); + return !!body && body.statements.some(s => ts.isExportDeclaration(s) || ts.isExportAssignment(s)); } - function setExportContextFlag(node: Mutable) { + function setExportContextFlag(node: ts.Mutable) { // A declaration source file or ambient module declaration that contains no export declarations (but possibly regular // declarations with export modifiers) is an export context in which declarations are implicitly exported. - if (node.flags & NodeFlags.Ambient && !hasExportDeclarations(node)) { - node.flags |= NodeFlags.ExportContext; + if (node.flags & ts.NodeFlags.Ambient && !hasExportDeclarations(node)) { + node.flags |= ts.NodeFlags.ExportContext; } else { - node.flags &= ~NodeFlags.ExportContext; + node.flags &= ~ts.NodeFlags.ExportContext; } } - function bindModuleDeclaration(node: ModuleDeclaration) { + function bindModuleDeclaration(node: ts.ModuleDeclaration) { setExportContextFlag(node); - if (isAmbientModule(node)) { - if (hasSyntacticModifier(node, ModifierFlags.Export)) { - errorOnFirstToken(node, Diagnostics.export_modifier_cannot_be_applied_to_ambient_modules_and_module_augmentations_since_they_are_always_visible); + if (ts.isAmbientModule(node)) { + if (ts.hasSyntacticModifier(node, ts.ModifierFlags.Export)) { + errorOnFirstToken(node, ts.Diagnostics.export_modifier_cannot_be_applied_to_ambient_modules_and_module_augmentations_since_they_are_always_visible); } - if (isModuleAugmentationExternal(node)) { + if (ts.isModuleAugmentationExternal(node)) { declareModuleSymbol(node); } else { - let pattern: string | Pattern | undefined; - if (node.name.kind === SyntaxKind.StringLiteral) { + let pattern: string | ts.Pattern | undefined; + if (node.name.kind === ts.SyntaxKind.StringLiteral) { const { text } = node.name; - pattern = tryParsePattern(text); + pattern = ts.tryParsePattern(text); if (pattern === undefined) { - errorOnFirstToken(node.name, Diagnostics.Pattern_0_can_have_at_most_one_Asterisk_character, text); + errorOnFirstToken(node.name, ts.Diagnostics.Pattern_0_can_have_at_most_one_Asterisk_character, text); } } - const symbol = declareSymbolAndAddToSymbolTable(node, SymbolFlags.ValueModule, SymbolFlags.ValueModuleExcludes)!; - file.patternAmbientModules = append(file.patternAmbientModules, pattern && !isString(pattern) ? { pattern, symbol } : undefined); + const symbol = declareSymbolAndAddToSymbolTable(node, ts.SymbolFlags.ValueModule, ts.SymbolFlags.ValueModuleExcludes)!; + file.patternAmbientModules = ts.append(file.patternAmbientModules, pattern && !ts.isString(pattern) ? { pattern, symbol } : undefined); } } else { @@ -2007,7 +2004,7 @@ namespace ts { if (state !== ModuleInstanceState.NonInstantiated) { const { symbol } = node; // if module was already merged with some function, class or non-const enum, treat it as non-const-enum-only - symbol.constEnumOnlyModule = (!(symbol.flags & (SymbolFlags.Function | SymbolFlags.Class | SymbolFlags.RegularEnum))) + symbol.constEnumOnlyModule = (!(symbol.flags & (ts.SymbolFlags.Function | ts.SymbolFlags.Class | ts.SymbolFlags.RegularEnum))) // Current must be `const enum` only && state === ModuleInstanceState.ConstEnumOnly // Can't have been set to 'false' in a previous merged symbol. ('undefined' OK) @@ -2016,42 +2013,39 @@ namespace ts { } } - function declareModuleSymbol(node: ModuleDeclaration): ModuleInstanceState { + function declareModuleSymbol(node: ts.ModuleDeclaration): ModuleInstanceState { const state = getModuleInstanceState(node); const instantiated = state !== ModuleInstanceState.NonInstantiated; - declareSymbolAndAddToSymbolTable(node, - instantiated ? SymbolFlags.ValueModule : SymbolFlags.NamespaceModule, - instantiated ? SymbolFlags.ValueModuleExcludes : SymbolFlags.NamespaceModuleExcludes); + declareSymbolAndAddToSymbolTable(node, instantiated ? ts.SymbolFlags.ValueModule : ts.SymbolFlags.NamespaceModule, instantiated ? ts.SymbolFlags.ValueModuleExcludes : ts.SymbolFlags.NamespaceModuleExcludes); return state; } - function bindFunctionOrConstructorType(node: SignatureDeclaration | JSDocSignature): void { + function bindFunctionOrConstructorType(node: ts.SignatureDeclaration | ts.JSDocSignature): void { // For a given function symbol "<...>(...) => T" we want to generate a symbol identical // to the one we would get for: { <...>(...): T } // // We do that by making an anonymous type literal symbol, and then setting the function // symbol as its sole member. To the rest of the system, this symbol will be indistinguishable // from an actual type literal symbol you would have gotten had you used the long form. - const symbol = createSymbol(SymbolFlags.Signature, getDeclarationName(node)!); // TODO: GH#18217 - addDeclarationToSymbol(symbol, node, SymbolFlags.Signature); - - const typeLiteralSymbol = createSymbol(SymbolFlags.TypeLiteral, InternalSymbolName.Type); - addDeclarationToSymbol(typeLiteralSymbol, node, SymbolFlags.TypeLiteral); - typeLiteralSymbol.members = createSymbolTable(); + const symbol = createSymbol(ts.SymbolFlags.Signature, getDeclarationName(node)!); // TODO: GH#18217 + addDeclarationToSymbol(symbol, node, ts.SymbolFlags.Signature); + const typeLiteralSymbol = createSymbol(ts.SymbolFlags.TypeLiteral, ts.InternalSymbolName.Type); + addDeclarationToSymbol(typeLiteralSymbol, node, ts.SymbolFlags.TypeLiteral); + typeLiteralSymbol.members = ts.createSymbolTable(); typeLiteralSymbol.members.set(symbol.escapedName, symbol); } - function bindObjectLiteralExpression(node: ObjectLiteralExpression) { + function bindObjectLiteralExpression(node: ts.ObjectLiteralExpression) { const enum ElementKind { Property = 1, Accessor = 2 } - if (inStrictMode && !isAssignmentTarget(node)) { - const seen = new Map<__String, ElementKind>(); + if (inStrictMode && !ts.isAssignmentTarget(node)) { + const seen = new ts.Map(); for (const prop of node.properties) { - if (prop.kind === SyntaxKind.SpreadAssignment || prop.name.kind !== SyntaxKind.Identifier) { + if (prop.kind === ts.SyntaxKind.SpreadAssignment || prop.name.kind !== ts.SyntaxKind.Identifier) { continue; } @@ -2065,7 +2059,7 @@ namespace ts { // c.IsAccessorDescriptor(previous) is true and IsDataDescriptor(propId.descriptor) is true. // d.IsAccessorDescriptor(previous) is true and IsAccessorDescriptor(propId.descriptor) is true // and either both previous and propId.descriptor have[[Get]] fields or both previous and propId.descriptor have[[Set]] fields - const currentKind = prop.kind === SyntaxKind.PropertyAssignment || prop.kind === SyntaxKind.ShorthandPropertyAssignment || prop.kind === SyntaxKind.MethodDeclaration + const currentKind = prop.kind === ts.SyntaxKind.PropertyAssignment || prop.kind === ts.SyntaxKind.ShorthandPropertyAssignment || prop.kind === ts.SyntaxKind.MethodDeclaration ? ElementKind.Property : ElementKind.Accessor; @@ -2077,40 +2071,40 @@ namespace ts { } } - return bindAnonymousDeclaration(node, SymbolFlags.ObjectLiteral, InternalSymbolName.Object); + return bindAnonymousDeclaration(node, ts.SymbolFlags.ObjectLiteral, ts.InternalSymbolName.Object); } - function bindJsxAttributes(node: JsxAttributes) { - return bindAnonymousDeclaration(node, SymbolFlags.ObjectLiteral, InternalSymbolName.JSXAttributes); + function bindJsxAttributes(node: ts.JsxAttributes) { + return bindAnonymousDeclaration(node, ts.SymbolFlags.ObjectLiteral, ts.InternalSymbolName.JSXAttributes); } - function bindJsxAttribute(node: JsxAttribute, symbolFlags: SymbolFlags, symbolExcludes: SymbolFlags) { + function bindJsxAttribute(node: ts.JsxAttribute, symbolFlags: ts.SymbolFlags, symbolExcludes: ts.SymbolFlags) { return declareSymbolAndAddToSymbolTable(node, symbolFlags, symbolExcludes); } - function bindAnonymousDeclaration(node: Declaration, symbolFlags: SymbolFlags, name: __String) { + function bindAnonymousDeclaration(node: ts.Declaration, symbolFlags: ts.SymbolFlags, name: ts.__String) { const symbol = createSymbol(symbolFlags, name); - if (symbolFlags & (SymbolFlags.EnumMember | SymbolFlags.ClassMember)) { + if (symbolFlags & (ts.SymbolFlags.EnumMember | ts.SymbolFlags.ClassMember)) { symbol.parent = container.symbol; } addDeclarationToSymbol(symbol, node, symbolFlags); return symbol; } - function bindBlockScopedDeclaration(node: Declaration, symbolFlags: SymbolFlags, symbolExcludes: SymbolFlags) { + function bindBlockScopedDeclaration(node: ts.Declaration, symbolFlags: ts.SymbolFlags, symbolExcludes: ts.SymbolFlags) { switch (blockScopeContainer.kind) { - case SyntaxKind.ModuleDeclaration: + case ts.SyntaxKind.ModuleDeclaration: declareModuleMember(node, symbolFlags, symbolExcludes); break; - case SyntaxKind.SourceFile: - if (isExternalOrCommonJsModule(container as SourceFile)) { + case ts.SyntaxKind.SourceFile: + if (ts.isExternalOrCommonJsModule(container as ts.SourceFile)) { declareModuleMember(node, symbolFlags, symbolExcludes); break; } // falls through default: if (!blockScopeContainer.locals) { - blockScopeContainer.locals = createSymbolTable(); + blockScopeContainer.locals = ts.createSymbolTable(); addToContainerChain(blockScopeContainer); } declareSymbol(blockScopeContainer.locals, /*parent*/ undefined, node, symbolFlags, symbolExcludes); @@ -2128,52 +2122,51 @@ namespace ts { const saveCurrentFlow = currentFlow; for (const typeAlias of delayedTypeAliases) { const host = typeAlias.parent.parent; - container = findAncestor(host.parent, n => !!(getContainerFlags(n) & ContainerFlags.IsContainer)) || file; - blockScopeContainer = getEnclosingBlockScopeContainer(host) || file; - currentFlow = initFlowNode({ flags: FlowFlags.Start }); + container = ts.findAncestor(host.parent, n => !!(getContainerFlags(n) & ContainerFlags.IsContainer)) || file; + blockScopeContainer = ts.getEnclosingBlockScopeContainer(host) || file; + currentFlow = initFlowNode({ flags: ts.FlowFlags.Start }); parent = typeAlias; bind(typeAlias.typeExpression); - const declName = getNameOfDeclaration(typeAlias); - if ((isJSDocEnumTag(typeAlias) || !typeAlias.fullName) && declName && isPropertyAccessEntityNameExpression(declName.parent)) { + const declName = ts.getNameOfDeclaration(typeAlias); + if ((ts.isJSDocEnumTag(typeAlias) || !typeAlias.fullName) && declName && ts.isPropertyAccessEntityNameExpression(declName.parent)) { // typedef anchored to an A.B.C assignment - we need to bind into B's namespace under name C const isTopLevel = isTopLevelNamespaceAssignment(declName.parent); if (isTopLevel) { - bindPotentiallyMissingNamespaces(file.symbol, declName.parent, isTopLevel, - !!findAncestor(declName, d => isPropertyAccessExpression(d) && d.name.escapedText === "prototype"), /*containerIsClass*/ false); + bindPotentiallyMissingNamespaces(file.symbol, declName.parent, isTopLevel, !!ts.findAncestor(declName, d => ts.isPropertyAccessExpression(d) && d.name.escapedText === "prototype"), /*containerIsClass*/ false); const oldContainer = container; - switch (getAssignmentDeclarationPropertyAccessKind(declName.parent)) { - case AssignmentDeclarationKind.ExportsProperty: - case AssignmentDeclarationKind.ModuleExports: - if (!isExternalOrCommonJsModule(file)) { + switch (ts.getAssignmentDeclarationPropertyAccessKind(declName.parent)) { + case ts.AssignmentDeclarationKind.ExportsProperty: + case ts.AssignmentDeclarationKind.ModuleExports: + if (!ts.isExternalOrCommonJsModule(file)) { container = undefined!; } else { container = file; } break; - case AssignmentDeclarationKind.ThisProperty: + case ts.AssignmentDeclarationKind.ThisProperty: container = declName.parent.expression; break; - case AssignmentDeclarationKind.PrototypeProperty: - container = (declName.parent.expression as PropertyAccessExpression).name; + case ts.AssignmentDeclarationKind.PrototypeProperty: + container = (declName.parent.expression as ts.PropertyAccessExpression).name; break; - case AssignmentDeclarationKind.Property: + case ts.AssignmentDeclarationKind.Property: container = isExportsOrModuleExportsOrAlias(file, declName.parent.expression) ? file - : isPropertyAccessExpression(declName.parent.expression) ? declName.parent.expression.name + : ts.isPropertyAccessExpression(declName.parent.expression) ? declName.parent.expression.name : declName.parent.expression; break; - case AssignmentDeclarationKind.None: - return Debug.fail("Shouldn't have detected typedef or enum on non-assignment declaration"); + case ts.AssignmentDeclarationKind.None: + return ts.Debug.fail("Shouldn't have detected typedef or enum on non-assignment declaration"); } if (container) { - declareModuleMember(typeAlias, SymbolFlags.TypeAlias, SymbolFlags.TypeAliasExcludes); + declareModuleMember(typeAlias, ts.SymbolFlags.TypeAlias, ts.SymbolFlags.TypeAliasExcludes); } container = oldContainer; } } - else if (isJSDocEnumTag(typeAlias) || !typeAlias.fullName || typeAlias.fullName.kind === SyntaxKind.Identifier) { + else if (ts.isJSDocEnumTag(typeAlias) || !typeAlias.fullName || typeAlias.fullName.kind === ts.SyntaxKind.Identifier) { parent = typeAlias.parent; - bindBlockScopedDeclaration(typeAlias, SymbolFlags.TypeAlias, SymbolFlags.TypeAliasExcludes); + bindBlockScopedDeclaration(typeAlias, ts.SymbolFlags.TypeAlias, ts.SymbolFlags.TypeAliasExcludes); } else { bind(typeAlias.fullName); @@ -2189,75 +2182,67 @@ namespace ts { // The binder visits every node in the syntax tree so it is a convenient place to perform a single localized // check for reserved words used as identifiers in strict mode code, as well as `yield` or `await` in // [Yield] or [Await] contexts, respectively. - function checkContextualIdentifier(node: Identifier) { + function checkContextualIdentifier(node: ts.Identifier) { // Report error only if there are no parse errors in file if (!file.parseDiagnostics.length && - !(node.flags & NodeFlags.Ambient) && - !(node.flags & NodeFlags.JSDoc) && - !isIdentifierName(node)) { + !(node.flags & ts.NodeFlags.Ambient) && + !(node.flags & ts.NodeFlags.JSDoc) && + !ts.isIdentifierName(node)) { // strict mode identifiers if (inStrictMode && - node.originalKeywordKind! >= SyntaxKind.FirstFutureReservedWord && - node.originalKeywordKind! <= SyntaxKind.LastFutureReservedWord) { - file.bindDiagnostics.push(createDiagnosticForNode(node, - getStrictModeIdentifierMessage(node), declarationNameToString(node))); + node.originalKeywordKind! >= ts.SyntaxKind.FirstFutureReservedWord && + node.originalKeywordKind! <= ts.SyntaxKind.LastFutureReservedWord) { + file.bindDiagnostics.push(createDiagnosticForNode(node, getStrictModeIdentifierMessage(node), ts.declarationNameToString(node))); } - else if (node.originalKeywordKind === SyntaxKind.AwaitKeyword) { - if (isExternalModule(file) && isInTopLevelContext(node)) { - file.bindDiagnostics.push(createDiagnosticForNode(node, - Diagnostics.Identifier_expected_0_is_a_reserved_word_at_the_top_level_of_a_module, - declarationNameToString(node))); + else if (node.originalKeywordKind === ts.SyntaxKind.AwaitKeyword) { + if (ts.isExternalModule(file) && ts.isInTopLevelContext(node)) { + file.bindDiagnostics.push(createDiagnosticForNode(node, ts.Diagnostics.Identifier_expected_0_is_a_reserved_word_at_the_top_level_of_a_module, ts.declarationNameToString(node))); } - else if (node.flags & NodeFlags.AwaitContext) { - file.bindDiagnostics.push(createDiagnosticForNode(node, - Diagnostics.Identifier_expected_0_is_a_reserved_word_that_cannot_be_used_here, - declarationNameToString(node))); + else if (node.flags & ts.NodeFlags.AwaitContext) { + file.bindDiagnostics.push(createDiagnosticForNode(node, ts.Diagnostics.Identifier_expected_0_is_a_reserved_word_that_cannot_be_used_here, ts.declarationNameToString(node))); } } - else if (node.originalKeywordKind === SyntaxKind.YieldKeyword && node.flags & NodeFlags.YieldContext) { - file.bindDiagnostics.push(createDiagnosticForNode(node, - Diagnostics.Identifier_expected_0_is_a_reserved_word_that_cannot_be_used_here, - declarationNameToString(node))); + else if (node.originalKeywordKind === ts.SyntaxKind.YieldKeyword && node.flags & ts.NodeFlags.YieldContext) { + file.bindDiagnostics.push(createDiagnosticForNode(node, ts.Diagnostics.Identifier_expected_0_is_a_reserved_word_that_cannot_be_used_here, ts.declarationNameToString(node))); } } } - function getStrictModeIdentifierMessage(node: Node) { + function getStrictModeIdentifierMessage(node: ts.Node) { // Provide specialized messages to help the user understand why we think they're in // strict mode. - if (getContainingClass(node)) { - return Diagnostics.Identifier_expected_0_is_a_reserved_word_in_strict_mode_Class_definitions_are_automatically_in_strict_mode; + if (ts.getContainingClass(node)) { + return ts.Diagnostics.Identifier_expected_0_is_a_reserved_word_in_strict_mode_Class_definitions_are_automatically_in_strict_mode; } if (file.externalModuleIndicator) { - return Diagnostics.Identifier_expected_0_is_a_reserved_word_in_strict_mode_Modules_are_automatically_in_strict_mode; + return ts.Diagnostics.Identifier_expected_0_is_a_reserved_word_in_strict_mode_Modules_are_automatically_in_strict_mode; } - return Diagnostics.Identifier_expected_0_is_a_reserved_word_in_strict_mode; + return ts.Diagnostics.Identifier_expected_0_is_a_reserved_word_in_strict_mode; } // The binder visits every node, so this is a good place to check for // the reserved private name (there is only one) - function checkPrivateIdentifier(node: PrivateIdentifier) { + function checkPrivateIdentifier(node: ts.PrivateIdentifier) { if (node.escapedText === "#constructor") { // Report error only if there are no parse errors in file if (!file.parseDiagnostics.length) { - file.bindDiagnostics.push(createDiagnosticForNode(node, - Diagnostics.constructor_is_a_reserved_word, declarationNameToString(node))); + file.bindDiagnostics.push(createDiagnosticForNode(node, ts.Diagnostics.constructor_is_a_reserved_word, ts.declarationNameToString(node))); } } } - function checkStrictModeBinaryExpression(node: BinaryExpression) { - if (inStrictMode && isLeftHandSideExpression(node.left) && isAssignmentOperator(node.operatorToken.kind)) { + function checkStrictModeBinaryExpression(node: ts.BinaryExpression) { + if (inStrictMode && ts.isLeftHandSideExpression(node.left) && ts.isAssignmentOperator(node.operatorToken.kind)) { // ECMA 262 (Annex C) The identifier eval or arguments may not appear as the LeftHandSideExpression of an // Assignment operator(11.13) or of a PostfixExpression(11.3) - checkStrictModeEvalOrArguments(node, node.left as Identifier); + checkStrictModeEvalOrArguments(node, node.left as ts.Identifier); } } - function checkStrictModeCatchClause(node: CatchClause) { + function checkStrictModeCatchClause(node: ts.CatchClause) { // It is a SyntaxError if a TryStatement with a Catch occurs within strict code and the Identifier of the // Catch production is eval or arguments if (inStrictMode && node.variableDeclaration) { @@ -2265,153 +2250,152 @@ namespace ts { } } - function checkStrictModeDeleteExpression(node: DeleteExpression) { + function checkStrictModeDeleteExpression(node: ts.DeleteExpression) { // Grammar checking - if (inStrictMode && node.expression.kind === SyntaxKind.Identifier) { + if (inStrictMode && node.expression.kind === ts.SyntaxKind.Identifier) { // When a delete operator occurs within strict mode code, a SyntaxError is thrown if its // UnaryExpression is a direct reference to a variable, function argument, or function name - const span = getErrorSpanForNode(file, node.expression); - file.bindDiagnostics.push(createFileDiagnostic(file, span.start, span.length, Diagnostics.delete_cannot_be_called_on_an_identifier_in_strict_mode)); + const span = ts.getErrorSpanForNode(file, node.expression); + file.bindDiagnostics.push(ts.createFileDiagnostic(file, span.start, span.length, ts.Diagnostics.delete_cannot_be_called_on_an_identifier_in_strict_mode)); } } - function isEvalOrArgumentsIdentifier(node: Node): boolean { - return isIdentifier(node) && (node.escapedText === "eval" || node.escapedText === "arguments"); + function isEvalOrArgumentsIdentifier(node: ts.Node): boolean { + return ts.isIdentifier(node) && (node.escapedText === "eval" || node.escapedText === "arguments"); } - function checkStrictModeEvalOrArguments(contextNode: Node, name: Node | undefined) { - if (name && name.kind === SyntaxKind.Identifier) { - const identifier = name as Identifier; + function checkStrictModeEvalOrArguments(contextNode: ts.Node, name: ts.Node | undefined) { + if (name && name.kind === ts.SyntaxKind.Identifier) { + const identifier = name as ts.Identifier; if (isEvalOrArgumentsIdentifier(identifier)) { // We check first if the name is inside class declaration or class expression; if so give explicit message // otherwise report generic error message. - const span = getErrorSpanForNode(file, name); - file.bindDiagnostics.push(createFileDiagnostic(file, span.start, span.length, - getStrictModeEvalOrArgumentsMessage(contextNode), idText(identifier))); + const span = ts.getErrorSpanForNode(file, name); + file.bindDiagnostics.push(ts.createFileDiagnostic(file, span.start, span.length, getStrictModeEvalOrArgumentsMessage(contextNode), ts.idText(identifier))); } } } - function getStrictModeEvalOrArgumentsMessage(node: Node) { + function getStrictModeEvalOrArgumentsMessage(node: ts.Node) { // Provide specialized messages to help the user understand why we think they're in // strict mode. - if (getContainingClass(node)) { - return Diagnostics.Code_contained_in_a_class_is_evaluated_in_JavaScript_s_strict_mode_which_does_not_allow_this_use_of_0_For_more_information_see_https_Colon_Slash_Slashdeveloper_mozilla_org_Slashen_US_Slashdocs_SlashWeb_SlashJavaScript_SlashReference_SlashStrict_mode; + if (ts.getContainingClass(node)) { + return ts.Diagnostics.Code_contained_in_a_class_is_evaluated_in_JavaScript_s_strict_mode_which_does_not_allow_this_use_of_0_For_more_information_see_https_Colon_Slash_Slashdeveloper_mozilla_org_Slashen_US_Slashdocs_SlashWeb_SlashJavaScript_SlashReference_SlashStrict_mode; } if (file.externalModuleIndicator) { - return Diagnostics.Invalid_use_of_0_Modules_are_automatically_in_strict_mode; + return ts.Diagnostics.Invalid_use_of_0_Modules_are_automatically_in_strict_mode; } - return Diagnostics.Invalid_use_of_0_in_strict_mode; + return ts.Diagnostics.Invalid_use_of_0_in_strict_mode; } - function checkStrictModeFunctionName(node: FunctionLikeDeclaration) { + function checkStrictModeFunctionName(node: ts.FunctionLikeDeclaration) { if (inStrictMode) { // It is a SyntaxError if the identifier eval or arguments appears within a FormalParameterList of a strict mode FunctionDeclaration or FunctionExpression (13.1)) checkStrictModeEvalOrArguments(node, node.name); } } - function getStrictModeBlockScopeFunctionDeclarationMessage(node: Node) { + function getStrictModeBlockScopeFunctionDeclarationMessage(node: ts.Node) { // Provide specialized messages to help the user understand why we think they're in // strict mode. - if (getContainingClass(node)) { - return Diagnostics.Function_declarations_are_not_allowed_inside_blocks_in_strict_mode_when_targeting_ES3_or_ES5_Class_definitions_are_automatically_in_strict_mode; + if (ts.getContainingClass(node)) { + return ts.Diagnostics.Function_declarations_are_not_allowed_inside_blocks_in_strict_mode_when_targeting_ES3_or_ES5_Class_definitions_are_automatically_in_strict_mode; } if (file.externalModuleIndicator) { - return Diagnostics.Function_declarations_are_not_allowed_inside_blocks_in_strict_mode_when_targeting_ES3_or_ES5_Modules_are_automatically_in_strict_mode; + return ts.Diagnostics.Function_declarations_are_not_allowed_inside_blocks_in_strict_mode_when_targeting_ES3_or_ES5_Modules_are_automatically_in_strict_mode; } - return Diagnostics.Function_declarations_are_not_allowed_inside_blocks_in_strict_mode_when_targeting_ES3_or_ES5; + return ts.Diagnostics.Function_declarations_are_not_allowed_inside_blocks_in_strict_mode_when_targeting_ES3_or_ES5; } - function checkStrictModeFunctionDeclaration(node: FunctionDeclaration) { - if (languageVersion < ScriptTarget.ES2015) { + function checkStrictModeFunctionDeclaration(node: ts.FunctionDeclaration) { + if (languageVersion < ts.ScriptTarget.ES2015) { // Report error if function is not top level function declaration - if (blockScopeContainer.kind !== SyntaxKind.SourceFile && - blockScopeContainer.kind !== SyntaxKind.ModuleDeclaration && - !isFunctionLikeOrClassStaticBlockDeclaration(blockScopeContainer)) { + if (blockScopeContainer.kind !== ts.SyntaxKind.SourceFile && + blockScopeContainer.kind !== ts.SyntaxKind.ModuleDeclaration && + !ts.isFunctionLikeOrClassStaticBlockDeclaration(blockScopeContainer)) { // We check first if the name is inside class declaration or class expression; if so give explicit message // otherwise report generic error message. - const errorSpan = getErrorSpanForNode(file, node); - file.bindDiagnostics.push(createFileDiagnostic(file, errorSpan.start, errorSpan.length, - getStrictModeBlockScopeFunctionDeclarationMessage(node))); + const errorSpan = ts.getErrorSpanForNode(file, node); + file.bindDiagnostics.push(ts.createFileDiagnostic(file, errorSpan.start, errorSpan.length, getStrictModeBlockScopeFunctionDeclarationMessage(node))); } } } - function checkStrictModeNumericLiteral(node: NumericLiteral) { - if (languageVersion < ScriptTarget.ES5 && inStrictMode && node.numericLiteralFlags & TokenFlags.Octal) { - file.bindDiagnostics.push(createDiagnosticForNode(node, Diagnostics.Octal_literals_are_not_allowed_in_strict_mode)); + function checkStrictModeNumericLiteral(node: ts.NumericLiteral) { + if (languageVersion < ts.ScriptTarget.ES5 && inStrictMode && node.numericLiteralFlags & ts.TokenFlags.Octal) { + file.bindDiagnostics.push(createDiagnosticForNode(node, ts.Diagnostics.Octal_literals_are_not_allowed_in_strict_mode)); } } - function checkStrictModePostfixUnaryExpression(node: PostfixUnaryExpression) { + function checkStrictModePostfixUnaryExpression(node: ts.PostfixUnaryExpression) { // Grammar checking // The identifier eval or arguments may not appear as the LeftHandSideExpression of an // Assignment operator(11.13) or of a PostfixExpression(11.3) or as the UnaryExpression // operated upon by a Prefix Increment(11.4.4) or a Prefix Decrement(11.4.5) operator. if (inStrictMode) { - checkStrictModeEvalOrArguments(node, node.operand as Identifier); + checkStrictModeEvalOrArguments(node, node.operand as ts.Identifier); } } - function checkStrictModePrefixUnaryExpression(node: PrefixUnaryExpression) { + function checkStrictModePrefixUnaryExpression(node: ts.PrefixUnaryExpression) { // Grammar checking if (inStrictMode) { - if (node.operator === SyntaxKind.PlusPlusToken || node.operator === SyntaxKind.MinusMinusToken) { - checkStrictModeEvalOrArguments(node, node.operand as Identifier); + if (node.operator === ts.SyntaxKind.PlusPlusToken || node.operator === ts.SyntaxKind.MinusMinusToken) { + checkStrictModeEvalOrArguments(node, node.operand as ts.Identifier); } } } - function checkStrictModeWithStatement(node: WithStatement) { + function checkStrictModeWithStatement(node: ts.WithStatement) { // Grammar checking for withStatement if (inStrictMode) { - errorOnFirstToken(node, Diagnostics.with_statements_are_not_allowed_in_strict_mode); + errorOnFirstToken(node, ts.Diagnostics.with_statements_are_not_allowed_in_strict_mode); } } - function checkStrictModeLabeledStatement(node: LabeledStatement) { + function checkStrictModeLabeledStatement(node: ts.LabeledStatement) { // Grammar checking for labeledStatement - if (inStrictMode && getEmitScriptTarget(options) >= ScriptTarget.ES2015) { - if (isDeclarationStatement(node.statement) || isVariableStatement(node.statement)) { - errorOnFirstToken(node.label, Diagnostics.A_label_is_not_allowed_here); + if (inStrictMode && ts.getEmitScriptTarget(options) >= ts.ScriptTarget.ES2015) { + if (ts.isDeclarationStatement(node.statement) || ts.isVariableStatement(node.statement)) { + errorOnFirstToken(node.label, ts.Diagnostics.A_label_is_not_allowed_here); } } } - function errorOnFirstToken(node: Node, message: DiagnosticMessage, arg0?: any, arg1?: any, arg2?: any) { - const span = getSpanOfTokenAtPosition(file, node.pos); - file.bindDiagnostics.push(createFileDiagnostic(file, span.start, span.length, message, arg0, arg1, arg2)); + function errorOnFirstToken(node: ts.Node, message: ts.DiagnosticMessage, arg0?: any, arg1?: any, arg2?: any) { + const span = ts.getSpanOfTokenAtPosition(file, node.pos); + file.bindDiagnostics.push(ts.createFileDiagnostic(file, span.start, span.length, message, arg0, arg1, arg2)); } - function errorOrSuggestionOnNode(isError: boolean, node: Node, message: DiagnosticMessage): void { + function errorOrSuggestionOnNode(isError: boolean, node: ts.Node, message: ts.DiagnosticMessage): void { errorOrSuggestionOnRange(isError, node, node, message); } - function errorOrSuggestionOnRange(isError: boolean, startNode: Node, endNode: Node, message: DiagnosticMessage): void { - addErrorOrSuggestionDiagnostic(isError, { pos: getTokenPosOfNode(startNode, file), end: endNode.end }, message); + function errorOrSuggestionOnRange(isError: boolean, startNode: ts.Node, endNode: ts.Node, message: ts.DiagnosticMessage): void { + addErrorOrSuggestionDiagnostic(isError, { pos: ts.getTokenPosOfNode(startNode, file), end: endNode.end }, message); } - function addErrorOrSuggestionDiagnostic(isError: boolean, range: TextRange, message: DiagnosticMessage): void { - const diag = createFileDiagnostic(file, range.pos, range.end - range.pos, message); + function addErrorOrSuggestionDiagnostic(isError: boolean, range: ts.TextRange, message: ts.DiagnosticMessage): void { + const diag = ts.createFileDiagnostic(file, range.pos, range.end - range.pos, message); if (isError) { file.bindDiagnostics.push(diag); } else { - file.bindSuggestionDiagnostics = append(file.bindSuggestionDiagnostics, { ...diag, category: DiagnosticCategory.Suggestion }); + file.bindSuggestionDiagnostics = ts.append(file.bindSuggestionDiagnostics, { ...diag, category: ts.DiagnosticCategory.Suggestion }); } } - function bind(node: Node | undefined): void { + function bind(node: ts.Node | undefined): void { if (!node) { return; } - setParent(node, parent); - if (tracing) (node as TracingNode).tracingPath = file.path; + ts.setParent(node, parent); + if (ts.tracing) + (node as ts.TracingNode).tracingPath = file.path; const saveInStrictMode = inStrictMode; // Even though in the AST the jsdoc @typedef node belongs to the current node, @@ -2440,7 +2424,7 @@ namespace ts { // the current 'container' node when it changes. This helps us know which symbol table // a local should go into for example. Since terminal nodes are known not to have // children, as an optimization we don't process those. - if (node.kind > SyntaxKind.LastToken) { + if (node.kind > ts.SyntaxKind.LastToken) { const saveParent = parent; parent = node; const containerFlags = getContainerFlags(node); @@ -2454,37 +2438,38 @@ namespace ts { } else { const saveParent = parent; - if (node.kind === SyntaxKind.EndOfFileToken) parent = node; + if (node.kind === ts.SyntaxKind.EndOfFileToken) + parent = node; bindJSDoc(node); parent = saveParent; } inStrictMode = saveInStrictMode; } - function bindJSDoc(node: Node) { - if (hasJSDocNodes(node)) { - if (isInJSFile(node)) { + function bindJSDoc(node: ts.Node) { + if (ts.hasJSDocNodes(node)) { + if (ts.isInJSFile(node)) { for (const j of node.jsDoc!) { bind(j); } } else { for (const j of node.jsDoc!) { - setParent(j, node); - setParentRecursive(j, /*incremental*/ false); + ts.setParent(j, node); + ts.setParentRecursive(j, /*incremental*/ false); } } } } - function updateStrictModeStatementList(statements: NodeArray) { + function updateStrictModeStatementList(statements: ts.NodeArray) { if (!inStrictMode) { for (const statement of statements) { - if (!isPrologueDirective(statement)) { + if (!ts.isPrologueDirective(statement)) { return; } - if (isUseStrictPrologueDirective(statement as ExpressionStatement)) { + if (isUseStrictPrologueDirective(statement as ts.ExpressionStatement)) { inStrictMode = true; return; } @@ -2493,347 +2478,340 @@ namespace ts { } /// Should be called only on prologue directives (isPrologueDirective(node) should be true) - function isUseStrictPrologueDirective(node: ExpressionStatement): boolean { - const nodeText = getSourceTextOfNodeFromSourceFile(file, node.expression); + function isUseStrictPrologueDirective(node: ts.ExpressionStatement): boolean { + const nodeText = ts.getSourceTextOfNodeFromSourceFile(file, node.expression); // Note: the node text must be exactly "use strict" or 'use strict'. It is not ok for the // string to contain unicode escapes (as per ES5). return nodeText === '"use strict"' || nodeText === "'use strict'"; } - function bindWorker(node: Node) { + function bindWorker(node: ts.Node) { switch (node.kind) { /* Strict mode checks */ - case SyntaxKind.Identifier: + case ts.SyntaxKind.Identifier: // for typedef type names with namespaces, bind the new jsdoc type symbol here // because it requires all containing namespaces to be in effect, namely the // current "blockScopeContainer" needs to be set to its immediate namespace parent. - if ((node as Identifier).isInJSDocNamespace) { + if ((node as ts.Identifier).isInJSDocNamespace) { let parentNode = node.parent; - while (parentNode && !isJSDocTypeAlias(parentNode)) { + while (parentNode && !ts.isJSDocTypeAlias(parentNode)) { parentNode = parentNode.parent; } - bindBlockScopedDeclaration(parentNode as Declaration, SymbolFlags.TypeAlias, SymbolFlags.TypeAliasExcludes); + bindBlockScopedDeclaration(parentNode as ts.Declaration, ts.SymbolFlags.TypeAlias, ts.SymbolFlags.TypeAliasExcludes); break; } // falls through - case SyntaxKind.ThisKeyword: - if (currentFlow && (isExpression(node) || parent.kind === SyntaxKind.ShorthandPropertyAssignment)) { + case ts.SyntaxKind.ThisKeyword: + if (currentFlow && (ts.isExpression(node) || parent.kind === ts.SyntaxKind.ShorthandPropertyAssignment)) { node.flowNode = currentFlow; } - return checkContextualIdentifier(node as Identifier); - case SyntaxKind.QualifiedName: - if (currentFlow && isPartOfTypeQuery(node)) { + return checkContextualIdentifier(node as ts.Identifier); + case ts.SyntaxKind.QualifiedName: + if (currentFlow && ts.isPartOfTypeQuery(node)) { node.flowNode = currentFlow; } break; - case SyntaxKind.MetaProperty: - case SyntaxKind.SuperKeyword: + case ts.SyntaxKind.MetaProperty: + case ts.SyntaxKind.SuperKeyword: node.flowNode = currentFlow; break; - case SyntaxKind.PrivateIdentifier: - return checkPrivateIdentifier(node as PrivateIdentifier); - case SyntaxKind.PropertyAccessExpression: - case SyntaxKind.ElementAccessExpression: - const expr = node as PropertyAccessExpression | ElementAccessExpression; + case ts.SyntaxKind.PrivateIdentifier: + return checkPrivateIdentifier(node as ts.PrivateIdentifier); + case ts.SyntaxKind.PropertyAccessExpression: + case ts.SyntaxKind.ElementAccessExpression: + const expr = node as ts.PropertyAccessExpression | ts.ElementAccessExpression; if (currentFlow && isNarrowableReference(expr)) { expr.flowNode = currentFlow; } - if (isSpecialPropertyDeclaration(expr)) { + if (ts.isSpecialPropertyDeclaration(expr)) { bindSpecialPropertyDeclaration(expr); } - if (isInJSFile(expr) && + if (ts.isInJSFile(expr) && file.commonJsModuleIndicator && - isModuleExportsAccessExpression(expr) && - !lookupSymbolForName(blockScopeContainer, "module" as __String)) { - declareSymbol(file.locals!, /*parent*/ undefined, expr.expression, - SymbolFlags.FunctionScopedVariable | SymbolFlags.ModuleExports, SymbolFlags.FunctionScopedVariableExcludes); + ts.isModuleExportsAccessExpression(expr) && + !lookupSymbolForName(blockScopeContainer, "module" as ts.__String)) { + declareSymbol(file.locals!, /*parent*/ undefined, expr.expression, ts.SymbolFlags.FunctionScopedVariable | ts.SymbolFlags.ModuleExports, ts.SymbolFlags.FunctionScopedVariableExcludes); } break; - case SyntaxKind.BinaryExpression: - const specialKind = getAssignmentDeclarationKind(node as BinaryExpression); + case ts.SyntaxKind.BinaryExpression: + const specialKind = ts.getAssignmentDeclarationKind(node as ts.BinaryExpression); switch (specialKind) { - case AssignmentDeclarationKind.ExportsProperty: - bindExportsPropertyAssignment(node as BindableStaticPropertyAssignmentExpression); + case ts.AssignmentDeclarationKind.ExportsProperty: + bindExportsPropertyAssignment(node as ts.BindableStaticPropertyAssignmentExpression); break; - case AssignmentDeclarationKind.ModuleExports: - bindModuleExportsAssignment(node as BindablePropertyAssignmentExpression); + case ts.AssignmentDeclarationKind.ModuleExports: + bindModuleExportsAssignment(node as ts.BindablePropertyAssignmentExpression); break; - case AssignmentDeclarationKind.PrototypeProperty: - bindPrototypePropertyAssignment((node as BindableStaticPropertyAssignmentExpression).left, node); + case ts.AssignmentDeclarationKind.PrototypeProperty: + bindPrototypePropertyAssignment((node as ts.BindableStaticPropertyAssignmentExpression).left, node); break; - case AssignmentDeclarationKind.Prototype: - bindPrototypeAssignment(node as BindableStaticPropertyAssignmentExpression); + case ts.AssignmentDeclarationKind.Prototype: + bindPrototypeAssignment(node as ts.BindableStaticPropertyAssignmentExpression); break; - case AssignmentDeclarationKind.ThisProperty: - bindThisPropertyAssignment(node as BindablePropertyAssignmentExpression); + case ts.AssignmentDeclarationKind.ThisProperty: + bindThisPropertyAssignment(node as ts.BindablePropertyAssignmentExpression); break; - case AssignmentDeclarationKind.Property: - const expression = ((node as BinaryExpression).left as AccessExpression).expression; - if (isInJSFile(node) && isIdentifier(expression)) { + case ts.AssignmentDeclarationKind.Property: + const expression = ((node as ts.BinaryExpression).left as ts.AccessExpression).expression; + if (ts.isInJSFile(node) && ts.isIdentifier(expression)) { const symbol = lookupSymbolForName(blockScopeContainer, expression.escapedText); - if (isThisInitializedDeclaration(symbol?.valueDeclaration)) { - bindThisPropertyAssignment(node as BindablePropertyAssignmentExpression); + if (ts.isThisInitializedDeclaration(symbol?.valueDeclaration)) { + bindThisPropertyAssignment(node as ts.BindablePropertyAssignmentExpression); break; } } - bindSpecialPropertyAssignment(node as BindablePropertyAssignmentExpression); + bindSpecialPropertyAssignment(node as ts.BindablePropertyAssignmentExpression); break; - case AssignmentDeclarationKind.None: + case ts.AssignmentDeclarationKind.None: // Nothing to do break; default: - Debug.fail("Unknown binary expression special property assignment kind"); - } - return checkStrictModeBinaryExpression(node as BinaryExpression); - case SyntaxKind.CatchClause: - return checkStrictModeCatchClause(node as CatchClause); - case SyntaxKind.DeleteExpression: - return checkStrictModeDeleteExpression(node as DeleteExpression); - case SyntaxKind.NumericLiteral: - return checkStrictModeNumericLiteral(node as NumericLiteral); - case SyntaxKind.PostfixUnaryExpression: - return checkStrictModePostfixUnaryExpression(node as PostfixUnaryExpression); - case SyntaxKind.PrefixUnaryExpression: - return checkStrictModePrefixUnaryExpression(node as PrefixUnaryExpression); - case SyntaxKind.WithStatement: - return checkStrictModeWithStatement(node as WithStatement); - case SyntaxKind.LabeledStatement: - return checkStrictModeLabeledStatement(node as LabeledStatement); - case SyntaxKind.ThisType: + ts.Debug.fail("Unknown binary expression special property assignment kind"); + } + return checkStrictModeBinaryExpression(node as ts.BinaryExpression); + case ts.SyntaxKind.CatchClause: + return checkStrictModeCatchClause(node as ts.CatchClause); + case ts.SyntaxKind.DeleteExpression: + return checkStrictModeDeleteExpression(node as ts.DeleteExpression); + case ts.SyntaxKind.NumericLiteral: + return checkStrictModeNumericLiteral(node as ts.NumericLiteral); + case ts.SyntaxKind.PostfixUnaryExpression: + return checkStrictModePostfixUnaryExpression(node as ts.PostfixUnaryExpression); + case ts.SyntaxKind.PrefixUnaryExpression: + return checkStrictModePrefixUnaryExpression(node as ts.PrefixUnaryExpression); + case ts.SyntaxKind.WithStatement: + return checkStrictModeWithStatement(node as ts.WithStatement); + case ts.SyntaxKind.LabeledStatement: + return checkStrictModeLabeledStatement(node as ts.LabeledStatement); + case ts.SyntaxKind.ThisType: seenThisKeyword = true; return; - case SyntaxKind.TypePredicate: + case ts.SyntaxKind.TypePredicate: break; // Binding the children will handle everything - case SyntaxKind.TypeParameter: - return bindTypeParameter(node as TypeParameterDeclaration); - case SyntaxKind.Parameter: - return bindParameter(node as ParameterDeclaration); - case SyntaxKind.VariableDeclaration: - return bindVariableDeclarationOrBindingElement(node as VariableDeclaration); - case SyntaxKind.BindingElement: + case ts.SyntaxKind.TypeParameter: + return bindTypeParameter(node as ts.TypeParameterDeclaration); + case ts.SyntaxKind.Parameter: + return bindParameter(node as ts.ParameterDeclaration); + case ts.SyntaxKind.VariableDeclaration: + return bindVariableDeclarationOrBindingElement(node as ts.VariableDeclaration); + case ts.SyntaxKind.BindingElement: node.flowNode = currentFlow; - return bindVariableDeclarationOrBindingElement(node as BindingElement); - case SyntaxKind.PropertyDeclaration: - case SyntaxKind.PropertySignature: - return bindPropertyWorker(node as PropertyDeclaration | PropertySignature); - case SyntaxKind.PropertyAssignment: - case SyntaxKind.ShorthandPropertyAssignment: - return bindPropertyOrMethodOrAccessor(node as Declaration, SymbolFlags.Property, SymbolFlags.PropertyExcludes); - case SyntaxKind.EnumMember: - return bindPropertyOrMethodOrAccessor(node as Declaration, SymbolFlags.EnumMember, SymbolFlags.EnumMemberExcludes); - - case SyntaxKind.CallSignature: - case SyntaxKind.ConstructSignature: - case SyntaxKind.IndexSignature: - return declareSymbolAndAddToSymbolTable(node as Declaration, SymbolFlags.Signature, SymbolFlags.None); - case SyntaxKind.MethodDeclaration: - case SyntaxKind.MethodSignature: + return bindVariableDeclarationOrBindingElement(node as ts.BindingElement); + case ts.SyntaxKind.PropertyDeclaration: + case ts.SyntaxKind.PropertySignature: + return bindPropertyWorker(node as ts.PropertyDeclaration | ts.PropertySignature); + case ts.SyntaxKind.PropertyAssignment: + case ts.SyntaxKind.ShorthandPropertyAssignment: + return bindPropertyOrMethodOrAccessor(node as ts.Declaration, ts.SymbolFlags.Property, ts.SymbolFlags.PropertyExcludes); + case ts.SyntaxKind.EnumMember: + return bindPropertyOrMethodOrAccessor(node as ts.Declaration, ts.SymbolFlags.EnumMember, ts.SymbolFlags.EnumMemberExcludes); + case ts.SyntaxKind.CallSignature: + case ts.SyntaxKind.ConstructSignature: + case ts.SyntaxKind.IndexSignature: + return declareSymbolAndAddToSymbolTable(node as ts.Declaration, ts.SymbolFlags.Signature, ts.SymbolFlags.None); + case ts.SyntaxKind.MethodDeclaration: + case ts.SyntaxKind.MethodSignature: // If this is an ObjectLiteralExpression method, then it sits in the same space // as other properties in the object literal. So we use SymbolFlags.PropertyExcludes // so that it will conflict with any other object literal members with the same // name. - return bindPropertyOrMethodOrAccessor(node as Declaration, SymbolFlags.Method | ((node as MethodDeclaration).questionToken ? SymbolFlags.Optional : SymbolFlags.None), - isObjectLiteralMethod(node) ? SymbolFlags.PropertyExcludes : SymbolFlags.MethodExcludes); - case SyntaxKind.FunctionDeclaration: - return bindFunctionDeclaration(node as FunctionDeclaration); - case SyntaxKind.Constructor: - return declareSymbolAndAddToSymbolTable(node as Declaration, SymbolFlags.Constructor, /*symbolExcludes:*/ SymbolFlags.None); - case SyntaxKind.GetAccessor: - return bindPropertyOrMethodOrAccessor(node as Declaration, SymbolFlags.GetAccessor, SymbolFlags.GetAccessorExcludes); - case SyntaxKind.SetAccessor: - return bindPropertyOrMethodOrAccessor(node as Declaration, SymbolFlags.SetAccessor, SymbolFlags.SetAccessorExcludes); - case SyntaxKind.FunctionType: - case SyntaxKind.JSDocFunctionType: - case SyntaxKind.JSDocSignature: - case SyntaxKind.ConstructorType: - return bindFunctionOrConstructorType(node as SignatureDeclaration | JSDocSignature); - case SyntaxKind.TypeLiteral: - case SyntaxKind.JSDocTypeLiteral: - case SyntaxKind.MappedType: - return bindAnonymousTypeWorker(node as TypeLiteralNode | MappedTypeNode | JSDocTypeLiteral); - case SyntaxKind.JSDocClassTag: - return bindJSDocClassTag(node as JSDocClassTag); - case SyntaxKind.ObjectLiteralExpression: - return bindObjectLiteralExpression(node as ObjectLiteralExpression); - case SyntaxKind.FunctionExpression: - case SyntaxKind.ArrowFunction: - return bindFunctionExpression(node as FunctionExpression); - - case SyntaxKind.CallExpression: - const assignmentKind = getAssignmentDeclarationKind(node as CallExpression); + return bindPropertyOrMethodOrAccessor(node as ts.Declaration, ts.SymbolFlags.Method | ((node as ts.MethodDeclaration).questionToken ? ts.SymbolFlags.Optional : ts.SymbolFlags.None), ts.isObjectLiteralMethod(node) ? ts.SymbolFlags.PropertyExcludes : ts.SymbolFlags.MethodExcludes); + case ts.SyntaxKind.FunctionDeclaration: + return bindFunctionDeclaration(node as ts.FunctionDeclaration); + case ts.SyntaxKind.Constructor: + return declareSymbolAndAddToSymbolTable(node as ts.Declaration, ts.SymbolFlags.Constructor, /*symbolExcludes:*/ ts.SymbolFlags.None); + case ts.SyntaxKind.GetAccessor: + return bindPropertyOrMethodOrAccessor(node as ts.Declaration, ts.SymbolFlags.GetAccessor, ts.SymbolFlags.GetAccessorExcludes); + case ts.SyntaxKind.SetAccessor: + return bindPropertyOrMethodOrAccessor(node as ts.Declaration, ts.SymbolFlags.SetAccessor, ts.SymbolFlags.SetAccessorExcludes); + case ts.SyntaxKind.FunctionType: + case ts.SyntaxKind.JSDocFunctionType: + case ts.SyntaxKind.JSDocSignature: + case ts.SyntaxKind.ConstructorType: + return bindFunctionOrConstructorType(node as ts.SignatureDeclaration | ts.JSDocSignature); + case ts.SyntaxKind.TypeLiteral: + case ts.SyntaxKind.JSDocTypeLiteral: + case ts.SyntaxKind.MappedType: + return bindAnonymousTypeWorker(node as ts.TypeLiteralNode | ts.MappedTypeNode | ts.JSDocTypeLiteral); + case ts.SyntaxKind.JSDocClassTag: + return bindJSDocClassTag(node as ts.JSDocClassTag); + case ts.SyntaxKind.ObjectLiteralExpression: + return bindObjectLiteralExpression(node as ts.ObjectLiteralExpression); + case ts.SyntaxKind.FunctionExpression: + case ts.SyntaxKind.ArrowFunction: + return bindFunctionExpression(node as ts.FunctionExpression); + case ts.SyntaxKind.CallExpression: + const assignmentKind = ts.getAssignmentDeclarationKind(node as ts.CallExpression); switch (assignmentKind) { - case AssignmentDeclarationKind.ObjectDefinePropertyValue: - return bindObjectDefinePropertyAssignment(node as BindableObjectDefinePropertyCall); - case AssignmentDeclarationKind.ObjectDefinePropertyExports: - return bindObjectDefinePropertyExport(node as BindableObjectDefinePropertyCall); - case AssignmentDeclarationKind.ObjectDefinePrototypeProperty: - return bindObjectDefinePrototypeProperty(node as BindableObjectDefinePropertyCall); - case AssignmentDeclarationKind.None: + case ts.AssignmentDeclarationKind.ObjectDefinePropertyValue: + return bindObjectDefinePropertyAssignment(node as ts.BindableObjectDefinePropertyCall); + case ts.AssignmentDeclarationKind.ObjectDefinePropertyExports: + return bindObjectDefinePropertyExport(node as ts.BindableObjectDefinePropertyCall); + case ts.AssignmentDeclarationKind.ObjectDefinePrototypeProperty: + return bindObjectDefinePrototypeProperty(node as ts.BindableObjectDefinePropertyCall); + case ts.AssignmentDeclarationKind.None: break; // Nothing to do default: - return Debug.fail("Unknown call expression assignment declaration kind"); + return ts.Debug.fail("Unknown call expression assignment declaration kind"); } - if (isInJSFile(node)) { - bindCallExpression(node as CallExpression); + if (ts.isInJSFile(node)) { + bindCallExpression(node as ts.CallExpression); } break; // Members of classes, interfaces, and modules - case SyntaxKind.ClassExpression: - case SyntaxKind.ClassDeclaration: + case ts.SyntaxKind.ClassExpression: + case ts.SyntaxKind.ClassDeclaration: // All classes are automatically in strict mode in ES6. inStrictMode = true; - return bindClassLikeDeclaration(node as ClassLikeDeclaration); - case SyntaxKind.InterfaceDeclaration: - return bindBlockScopedDeclaration(node as Declaration, SymbolFlags.Interface, SymbolFlags.InterfaceExcludes); - case SyntaxKind.TypeAliasDeclaration: - return bindBlockScopedDeclaration(node as Declaration, SymbolFlags.TypeAlias, SymbolFlags.TypeAliasExcludes); - case SyntaxKind.EnumDeclaration: - return bindEnumDeclaration(node as EnumDeclaration); - case SyntaxKind.ModuleDeclaration: - return bindModuleDeclaration(node as ModuleDeclaration); + return bindClassLikeDeclaration(node as ts.ClassLikeDeclaration); + case ts.SyntaxKind.InterfaceDeclaration: + return bindBlockScopedDeclaration(node as ts.Declaration, ts.SymbolFlags.Interface, ts.SymbolFlags.InterfaceExcludes); + case ts.SyntaxKind.TypeAliasDeclaration: + return bindBlockScopedDeclaration(node as ts.Declaration, ts.SymbolFlags.TypeAlias, ts.SymbolFlags.TypeAliasExcludes); + case ts.SyntaxKind.EnumDeclaration: + return bindEnumDeclaration(node as ts.EnumDeclaration); + case ts.SyntaxKind.ModuleDeclaration: + return bindModuleDeclaration(node as ts.ModuleDeclaration); // Jsx-attributes - case SyntaxKind.JsxAttributes: - return bindJsxAttributes(node as JsxAttributes); - case SyntaxKind.JsxAttribute: - return bindJsxAttribute(node as JsxAttribute, SymbolFlags.Property, SymbolFlags.PropertyExcludes); + case ts.SyntaxKind.JsxAttributes: + return bindJsxAttributes(node as ts.JsxAttributes); + case ts.SyntaxKind.JsxAttribute: + return bindJsxAttribute(node as ts.JsxAttribute, ts.SymbolFlags.Property, ts.SymbolFlags.PropertyExcludes); // Imports and exports - case SyntaxKind.ImportEqualsDeclaration: - case SyntaxKind.NamespaceImport: - case SyntaxKind.ImportSpecifier: - case SyntaxKind.ExportSpecifier: - return declareSymbolAndAddToSymbolTable(node as Declaration, SymbolFlags.Alias, SymbolFlags.AliasExcludes); - case SyntaxKind.NamespaceExportDeclaration: - return bindNamespaceExportDeclaration(node as NamespaceExportDeclaration); - case SyntaxKind.ImportClause: - return bindImportClause(node as ImportClause); - case SyntaxKind.ExportDeclaration: - return bindExportDeclaration(node as ExportDeclaration); - case SyntaxKind.ExportAssignment: - return bindExportAssignment(node as ExportAssignment); - case SyntaxKind.SourceFile: - updateStrictModeStatementList((node as SourceFile).statements); + case ts.SyntaxKind.ImportEqualsDeclaration: + case ts.SyntaxKind.NamespaceImport: + case ts.SyntaxKind.ImportSpecifier: + case ts.SyntaxKind.ExportSpecifier: + return declareSymbolAndAddToSymbolTable(node as ts.Declaration, ts.SymbolFlags.Alias, ts.SymbolFlags.AliasExcludes); + case ts.SyntaxKind.NamespaceExportDeclaration: + return bindNamespaceExportDeclaration(node as ts.NamespaceExportDeclaration); + case ts.SyntaxKind.ImportClause: + return bindImportClause(node as ts.ImportClause); + case ts.SyntaxKind.ExportDeclaration: + return bindExportDeclaration(node as ts.ExportDeclaration); + case ts.SyntaxKind.ExportAssignment: + return bindExportAssignment(node as ts.ExportAssignment); + case ts.SyntaxKind.SourceFile: + updateStrictModeStatementList((node as ts.SourceFile).statements); return bindSourceFileIfExternalModule(); - case SyntaxKind.Block: - if (!isFunctionLikeOrClassStaticBlockDeclaration(node.parent)) { + case ts.SyntaxKind.Block: + if (!ts.isFunctionLikeOrClassStaticBlockDeclaration(node.parent)) { return; } // falls through - case SyntaxKind.ModuleBlock: - return updateStrictModeStatementList((node as Block | ModuleBlock).statements); - - case SyntaxKind.JSDocParameterTag: - if (node.parent.kind === SyntaxKind.JSDocSignature) { - return bindParameter(node as JSDocParameterTag); + case ts.SyntaxKind.ModuleBlock: + return updateStrictModeStatementList((node as ts.Block | ts.ModuleBlock).statements); + case ts.SyntaxKind.JSDocParameterTag: + if (node.parent.kind === ts.SyntaxKind.JSDocSignature) { + return bindParameter(node as ts.JSDocParameterTag); } - if (node.parent.kind !== SyntaxKind.JSDocTypeLiteral) { + if (node.parent.kind !== ts.SyntaxKind.JSDocTypeLiteral) { break; } // falls through - case SyntaxKind.JSDocPropertyTag: - const propTag = node as JSDocPropertyLikeTag; - const flags = propTag.isBracketed || propTag.typeExpression && propTag.typeExpression.type.kind === SyntaxKind.JSDocOptionalType ? - SymbolFlags.Property | SymbolFlags.Optional : - SymbolFlags.Property; - return declareSymbolAndAddToSymbolTable(propTag, flags, SymbolFlags.PropertyExcludes); - case SyntaxKind.JSDocTypedefTag: - case SyntaxKind.JSDocCallbackTag: - case SyntaxKind.JSDocEnumTag: - return (delayedTypeAliases || (delayedTypeAliases = [])).push(node as JSDocTypedefTag | JSDocCallbackTag | JSDocEnumTag); + case ts.SyntaxKind.JSDocPropertyTag: + const propTag = node as ts.JSDocPropertyLikeTag; + const flags = propTag.isBracketed || propTag.typeExpression && propTag.typeExpression.type.kind === ts.SyntaxKind.JSDocOptionalType ? + ts.SymbolFlags.Property | ts.SymbolFlags.Optional : + ts.SymbolFlags.Property; + return declareSymbolAndAddToSymbolTable(propTag, flags, ts.SymbolFlags.PropertyExcludes); + case ts.SyntaxKind.JSDocTypedefTag: + case ts.SyntaxKind.JSDocCallbackTag: + case ts.SyntaxKind.JSDocEnumTag: + return (delayedTypeAliases || (delayedTypeAliases = [])).push(node as ts.JSDocTypedefTag | ts.JSDocCallbackTag | ts.JSDocEnumTag); } } - - function bindPropertyWorker(node: PropertyDeclaration | PropertySignature) { - return bindPropertyOrMethodOrAccessor(node, SymbolFlags.Property | (node.questionToken ? SymbolFlags.Optional : SymbolFlags.None), SymbolFlags.PropertyExcludes); + function bindPropertyWorker(node: ts.PropertyDeclaration | ts.PropertySignature) { + return bindPropertyOrMethodOrAccessor(node, ts.SymbolFlags.Property | (node.questionToken ? ts.SymbolFlags.Optional : ts.SymbolFlags.None), ts.SymbolFlags.PropertyExcludes); } - - function bindAnonymousTypeWorker(node: TypeLiteralNode | MappedTypeNode | JSDocTypeLiteral) { - return bindAnonymousDeclaration(node as Declaration, SymbolFlags.TypeLiteral, InternalSymbolName.Type); + function bindAnonymousTypeWorker(node: ts.TypeLiteralNode | ts.MappedTypeNode | ts.JSDocTypeLiteral) { + return bindAnonymousDeclaration(node as ts.Declaration, ts.SymbolFlags.TypeLiteral, ts.InternalSymbolName.Type); } function bindSourceFileIfExternalModule() { setExportContextFlag(file); - if (isExternalModule(file)) { + if (ts.isExternalModule(file)) { bindSourceFileAsExternalModule(); } - else if (isJsonSourceFile(file)) { + else if (ts.isJsonSourceFile(file)) { bindSourceFileAsExternalModule(); // Create symbol equivalent for the module.exports = {} const originalSymbol = file.symbol; - declareSymbol(file.symbol.exports!, file.symbol, file, SymbolFlags.Property, SymbolFlags.All); + declareSymbol(file.symbol.exports!, file.symbol, file, ts.SymbolFlags.Property, ts.SymbolFlags.All); file.symbol = originalSymbol; } } function bindSourceFileAsExternalModule() { - bindAnonymousDeclaration(file, SymbolFlags.ValueModule, `"${removeFileExtension(file.fileName)}"` as __String); + bindAnonymousDeclaration(file, ts.SymbolFlags.ValueModule, `"${ts.removeFileExtension(file.fileName)}"` as ts.__String); } - function bindExportAssignment(node: ExportAssignment) { + function bindExportAssignment(node: ts.ExportAssignment) { if (!container.symbol || !container.symbol.exports) { // Incorrect export assignment in some sort of block construct - bindAnonymousDeclaration(node, SymbolFlags.Value, getDeclarationName(node)!); + bindAnonymousDeclaration(node, ts.SymbolFlags.Value, getDeclarationName(node)!); } else { - const flags = exportAssignmentIsAlias(node) + const flags = ts.exportAssignmentIsAlias(node) // An export default clause with an EntityNameExpression or a class expression exports all meanings of that identifier or expression; - ? SymbolFlags.Alias + ? ts.SymbolFlags.Alias // An export default clause with any other expression exports a value - : SymbolFlags.Property; + : ts.SymbolFlags.Property; // If there is an `export default x;` alias declaration, can't `export default` anything else. // (In contrast, you can still have `export default function f() {}` and `export default interface I {}`.) - const symbol = declareSymbol(container.symbol.exports, container.symbol, node, flags, SymbolFlags.All); + const symbol = declareSymbol(container.symbol.exports, container.symbol, node, flags, ts.SymbolFlags.All); if (node.isExportEquals) { // Will be an error later, since the module already has other exports. Just make sure this has a valueDeclaration set. - setValueDeclaration(symbol, node); + ts.setValueDeclaration(symbol, node); } } } - function bindNamespaceExportDeclaration(node: NamespaceExportDeclaration) { + function bindNamespaceExportDeclaration(node: ts.NamespaceExportDeclaration) { if (node.modifiers && node.modifiers.length) { - file.bindDiagnostics.push(createDiagnosticForNode(node, Diagnostics.Modifiers_cannot_appear_here)); + file.bindDiagnostics.push(createDiagnosticForNode(node, ts.Diagnostics.Modifiers_cannot_appear_here)); } - const diag = !isSourceFile(node.parent) ? Diagnostics.Global_module_exports_may_only_appear_at_top_level - : !isExternalModule(node.parent) ? Diagnostics.Global_module_exports_may_only_appear_in_module_files - : !node.parent.isDeclarationFile ? Diagnostics.Global_module_exports_may_only_appear_in_declaration_files + const diag = !ts.isSourceFile(node.parent) ? ts.Diagnostics.Global_module_exports_may_only_appear_at_top_level + : !ts.isExternalModule(node.parent) ? ts.Diagnostics.Global_module_exports_may_only_appear_in_module_files + : !node.parent.isDeclarationFile ? ts.Diagnostics.Global_module_exports_may_only_appear_in_declaration_files : undefined; if (diag) { file.bindDiagnostics.push(createDiagnosticForNode(node, diag)); } else { - file.symbol.globalExports = file.symbol.globalExports || createSymbolTable(); - declareSymbol(file.symbol.globalExports, file.symbol, node, SymbolFlags.Alias, SymbolFlags.AliasExcludes); + file.symbol.globalExports = file.symbol.globalExports || ts.createSymbolTable(); + declareSymbol(file.symbol.globalExports, file.symbol, node, ts.SymbolFlags.Alias, ts.SymbolFlags.AliasExcludes); } } - function bindExportDeclaration(node: ExportDeclaration) { + function bindExportDeclaration(node: ts.ExportDeclaration) { if (!container.symbol || !container.symbol.exports) { // Export * in some sort of block construct - bindAnonymousDeclaration(node, SymbolFlags.ExportStar, getDeclarationName(node)!); + bindAnonymousDeclaration(node, ts.SymbolFlags.ExportStar, getDeclarationName(node)!); } else if (!node.exportClause) { // All export * declarations are collected in an __export symbol - declareSymbol(container.symbol.exports, container.symbol, node, SymbolFlags.ExportStar, SymbolFlags.None); + declareSymbol(container.symbol.exports, container.symbol, node, ts.SymbolFlags.ExportStar, ts.SymbolFlags.None); } - else if (isNamespaceExport(node.exportClause)) { + else if (ts.isNamespaceExport(node.exportClause)) { // declareSymbol walks up parents to find name text, parent _must_ be set // but won't be set by the normal binder walk until `bindChildren` later on. - setParent(node.exportClause, node); - declareSymbol(container.symbol.exports, container.symbol, node.exportClause, SymbolFlags.Alias, SymbolFlags.AliasExcludes); + ts.setParent(node.exportClause, node); + declareSymbol(container.symbol.exports, container.symbol, node.exportClause, ts.SymbolFlags.Alias, ts.SymbolFlags.AliasExcludes); } } - function bindImportClause(node: ImportClause) { + function bindImportClause(node: ts.ImportClause) { if (node.name) { - declareSymbolAndAddToSymbolTable(node, SymbolFlags.Alias, SymbolFlags.AliasExcludes); + declareSymbolAndAddToSymbolTable(node, ts.SymbolFlags.Alias, ts.SymbolFlags.AliasExcludes); } } - function setCommonJsModuleIndicator(node: Node) { + function setCommonJsModuleIndicator(node: ts.Node) { if (file.externalModuleIndicator) { return false; } @@ -2844,23 +2822,23 @@ namespace ts { return true; } - function bindObjectDefinePropertyExport(node: BindableObjectDefinePropertyCall) { + function bindObjectDefinePropertyExport(node: ts.BindableObjectDefinePropertyCall) { if (!setCommonJsModuleIndicator(node)) { return; } const symbol = forEachIdentifierInEntityName(node.arguments[0], /*parent*/ undefined, (id, symbol) => { if (symbol) { - addDeclarationToSymbol(symbol, id, SymbolFlags.Module | SymbolFlags.Assignment); + addDeclarationToSymbol(symbol, id, ts.SymbolFlags.Module | ts.SymbolFlags.Assignment); } return symbol; }); if (symbol) { - const flags = SymbolFlags.Property | SymbolFlags.ExportValue; - declareSymbol(symbol.exports!, symbol, node, flags, SymbolFlags.None); + const flags = ts.SymbolFlags.Property | ts.SymbolFlags.ExportValue; + declareSymbol(symbol.exports!, symbol, node, flags, ts.SymbolFlags.None); } } - function bindExportsPropertyAssignment(node: BindableStaticPropertyAssignmentExpression) { + function bindExportsPropertyAssignment(node: ts.BindableStaticPropertyAssignmentExpression) { // When we create a property via 'exports.foo = bar', the 'exports.foo' property access // expression is the declaration if (!setCommonJsModuleIndicator(node)) { @@ -2868,19 +2846,19 @@ namespace ts { } const symbol = forEachIdentifierInEntityName(node.left.expression, /*parent*/ undefined, (id, symbol) => { if (symbol) { - addDeclarationToSymbol(symbol, id, SymbolFlags.Module | SymbolFlags.Assignment); + addDeclarationToSymbol(symbol, id, ts.SymbolFlags.Module | ts.SymbolFlags.Assignment); } return symbol; }); if (symbol) { - const isAlias = isAliasableExpression(node.right) && (isExportsIdentifier(node.left.expression) || isModuleExportsAccessExpression(node.left.expression)); - const flags = isAlias ? SymbolFlags.Alias : SymbolFlags.Property | SymbolFlags.ExportValue; - setParent(node.left, node); - declareSymbol(symbol.exports!, symbol, node.left, flags, SymbolFlags.None); + const isAlias = ts.isAliasableExpression(node.right) && (ts.isExportsIdentifier(node.left.expression) || ts.isModuleExportsAccessExpression(node.left.expression)); + const flags = isAlias ? ts.SymbolFlags.Alias : ts.SymbolFlags.Property | ts.SymbolFlags.ExportValue; + ts.setParent(node.left, node); + declareSymbol(symbol.exports!, symbol, node.left, flags, ts.SymbolFlags.None); } } - function bindModuleExportsAssignment(node: BindablePropertyAssignmentExpression) { + function bindModuleExportsAssignment(node: ts.BindablePropertyAssignmentExpression) { // A common practice in node modules is to set 'export = module.exports = {}', this ensures that 'exports' // is still pointing to 'module.exports'. // We do not want to consider this as 'export=' since a module can have only one of these. @@ -2888,115 +2866,113 @@ namespace ts { if (!setCommonJsModuleIndicator(node)) { return; } - const assignedExpression = getRightMostAssignedExpression(node.right); - if (isEmptyObjectLiteral(assignedExpression) || container === file && isExportsOrModuleExportsOrAlias(file, assignedExpression)) { + const assignedExpression = ts.getRightMostAssignedExpression(node.right); + if (ts.isEmptyObjectLiteral(assignedExpression) || container === file && isExportsOrModuleExportsOrAlias(file, assignedExpression)) { return; } - if (isObjectLiteralExpression(assignedExpression) && every(assignedExpression.properties, isShorthandPropertyAssignment)) { - forEach(assignedExpression.properties, bindExportAssignedObjectMemberAlias); + if (ts.isObjectLiteralExpression(assignedExpression) && ts.every(assignedExpression.properties, ts.isShorthandPropertyAssignment)) { + ts.forEach(assignedExpression.properties, bindExportAssignedObjectMemberAlias); return; } // 'module.exports = expr' assignment - const flags = exportAssignmentIsAlias(node) - ? SymbolFlags.Alias // An export= with an EntityNameExpression or a ClassExpression exports all meanings of that identifier or class - : SymbolFlags.Property | SymbolFlags.ExportValue | SymbolFlags.ValueModule; - const symbol = declareSymbol(file.symbol.exports!, file.symbol, node, flags | SymbolFlags.Assignment, SymbolFlags.None); - setValueDeclaration(symbol, node); + const flags = ts.exportAssignmentIsAlias(node) + ? ts.SymbolFlags.Alias // An export= with an EntityNameExpression or a ClassExpression exports all meanings of that identifier or class + : ts.SymbolFlags.Property | ts.SymbolFlags.ExportValue | ts.SymbolFlags.ValueModule; + const symbol = declareSymbol(file.symbol.exports!, file.symbol, node, flags | ts.SymbolFlags.Assignment, ts.SymbolFlags.None); + ts.setValueDeclaration(symbol, node); } - - function bindExportAssignedObjectMemberAlias(node: ShorthandPropertyAssignment) { - declareSymbol(file.symbol.exports!, file.symbol, node, SymbolFlags.Alias | SymbolFlags.Assignment, SymbolFlags.None); + function bindExportAssignedObjectMemberAlias(node: ts.ShorthandPropertyAssignment) { + declareSymbol(file.symbol.exports!, file.symbol, node, ts.SymbolFlags.Alias | ts.SymbolFlags.Assignment, ts.SymbolFlags.None); } - - function bindThisPropertyAssignment(node: BindablePropertyAssignmentExpression | PropertyAccessExpression | LiteralLikeElementAccessExpression) { - Debug.assert(isInJSFile(node)); + function bindThisPropertyAssignment(node: ts.BindablePropertyAssignmentExpression | ts.PropertyAccessExpression | ts.LiteralLikeElementAccessExpression) { + ts.Debug.assert(ts.isInJSFile(node)); // private identifiers *must* be declared (even in JS files) - const hasPrivateIdentifier = (isBinaryExpression(node) && isPropertyAccessExpression(node.left) && isPrivateIdentifier(node.left.name)) - || (isPropertyAccessExpression(node) && isPrivateIdentifier(node.name)); + const hasPrivateIdentifier = (ts.isBinaryExpression(node) && ts.isPropertyAccessExpression(node.left) && ts.isPrivateIdentifier(node.left.name)) + || (ts.isPropertyAccessExpression(node) && ts.isPrivateIdentifier(node.name)); if (hasPrivateIdentifier) { return; } - const thisContainer = getThisContainer(node, /*includeArrowFunctions*/ false); + const thisContainer = ts.getThisContainer(node, /*includeArrowFunctions*/ false); switch (thisContainer.kind) { - case SyntaxKind.FunctionDeclaration: - case SyntaxKind.FunctionExpression: - let constructorSymbol: Symbol | undefined = thisContainer.symbol; + case ts.SyntaxKind.FunctionDeclaration: + case ts.SyntaxKind.FunctionExpression: + let constructorSymbol: ts.Symbol | undefined = thisContainer.symbol; // For `f.prototype.m = function() { this.x = 0; }`, `this.x = 0` should modify `f`'s members, not the function expression. - if (isBinaryExpression(thisContainer.parent) && thisContainer.parent.operatorToken.kind === SyntaxKind.EqualsToken) { + if (ts.isBinaryExpression(thisContainer.parent) && thisContainer.parent.operatorToken.kind === ts.SyntaxKind.EqualsToken) { const l = thisContainer.parent.left; - if (isBindableStaticAccessExpression(l) && isPrototypeAccess(l.expression)) { + if (ts.isBindableStaticAccessExpression(l) && ts.isPrototypeAccess(l.expression)) { constructorSymbol = lookupSymbolForPropertyAccess(l.expression.expression, thisParentContainer); } } if (constructorSymbol && constructorSymbol.valueDeclaration) { // Declare a 'member' if the container is an ES5 class or ES6 constructor - constructorSymbol.members = constructorSymbol.members || createSymbolTable(); + constructorSymbol.members = constructorSymbol.members || ts.createSymbolTable(); // It's acceptable for multiple 'this' assignments of the same identifier to occur - if (hasDynamicName(node)) { + if (ts.hasDynamicName(node)) { bindDynamicallyNamedThisPropertyAssignment(node, constructorSymbol, constructorSymbol.members); } else { - declareSymbol(constructorSymbol.members, constructorSymbol, node, SymbolFlags.Property | SymbolFlags.Assignment, SymbolFlags.PropertyExcludes & ~SymbolFlags.Property); + declareSymbol(constructorSymbol.members, constructorSymbol, node, ts.SymbolFlags.Property | ts.SymbolFlags.Assignment, ts.SymbolFlags.PropertyExcludes & ~ts.SymbolFlags.Property); } - addDeclarationToSymbol(constructorSymbol, constructorSymbol.valueDeclaration, SymbolFlags.Class); + addDeclarationToSymbol(constructorSymbol, constructorSymbol.valueDeclaration, ts.SymbolFlags.Class); } break; - case SyntaxKind.Constructor: - case SyntaxKind.PropertyDeclaration: - case SyntaxKind.MethodDeclaration: - case SyntaxKind.GetAccessor: - case SyntaxKind.SetAccessor: - case SyntaxKind.ClassStaticBlockDeclaration: + case ts.SyntaxKind.Constructor: + case ts.SyntaxKind.PropertyDeclaration: + case ts.SyntaxKind.MethodDeclaration: + case ts.SyntaxKind.GetAccessor: + case ts.SyntaxKind.SetAccessor: + case ts.SyntaxKind.ClassStaticBlockDeclaration: // this.foo assignment in a JavaScript class // Bind this property to the containing class const containingClass = thisContainer.parent; - const symbolTable = isStatic(thisContainer) ? containingClass.symbol.exports! : containingClass.symbol.members!; - if (hasDynamicName(node)) { + const symbolTable = ts.isStatic(thisContainer) ? containingClass.symbol.exports! : containingClass.symbol.members!; + if (ts.hasDynamicName(node)) { bindDynamicallyNamedThisPropertyAssignment(node, containingClass.symbol, symbolTable); } else { - declareSymbol(symbolTable, containingClass.symbol, node, SymbolFlags.Property | SymbolFlags.Assignment, SymbolFlags.None, /*isReplaceableByMethod*/ true); + declareSymbol(symbolTable, containingClass.symbol, node, ts.SymbolFlags.Property | ts.SymbolFlags.Assignment, ts.SymbolFlags.None, /*isReplaceableByMethod*/ true); } break; - case SyntaxKind.SourceFile: + case ts.SyntaxKind.SourceFile: // this.property = assignment in a source file -- declare symbol in exports for a module, in locals for a script - if (hasDynamicName(node)) { + if (ts.hasDynamicName(node)) { break; } - else if ((thisContainer as SourceFile).commonJsModuleIndicator) { - declareSymbol(thisContainer.symbol.exports!, thisContainer.symbol, node, SymbolFlags.Property | SymbolFlags.ExportValue, SymbolFlags.None); + else if ((thisContainer as ts.SourceFile).commonJsModuleIndicator) { + declareSymbol(thisContainer.symbol.exports!, thisContainer.symbol, node, ts.SymbolFlags.Property | ts.SymbolFlags.ExportValue, ts.SymbolFlags.None); } else { - declareSymbolAndAddToSymbolTable(node, SymbolFlags.FunctionScopedVariable, SymbolFlags.FunctionScopedVariableExcludes); + declareSymbolAndAddToSymbolTable(node, ts.SymbolFlags.FunctionScopedVariable, ts.SymbolFlags.FunctionScopedVariableExcludes); } break; default: - Debug.failBadSyntaxKind(thisContainer); + ts.Debug.failBadSyntaxKind(thisContainer); } } - function bindDynamicallyNamedThisPropertyAssignment(node: BinaryExpression | DynamicNamedDeclaration, symbol: Symbol, symbolTable: SymbolTable) { - declareSymbol(symbolTable, symbol, node, SymbolFlags.Property, SymbolFlags.None, /*isReplaceableByMethod*/ true, /*isComputedName*/ true); + function bindDynamicallyNamedThisPropertyAssignment(node: ts.BinaryExpression | ts.DynamicNamedDeclaration, symbol: ts.Symbol, symbolTable: ts.SymbolTable) { + declareSymbol(symbolTable, symbol, node, ts.SymbolFlags.Property, ts.SymbolFlags.None, /*isReplaceableByMethod*/ true, /*isComputedName*/ true); addLateBoundAssignmentDeclarationToSymbol(node, symbol); } - function addLateBoundAssignmentDeclarationToSymbol(node: BinaryExpression | DynamicNamedDeclaration, symbol: Symbol | undefined) { + function addLateBoundAssignmentDeclarationToSymbol(node: ts.BinaryExpression | ts.DynamicNamedDeclaration, symbol: ts.Symbol | undefined) { if (symbol) { - (symbol.assignmentDeclarationMembers || (symbol.assignmentDeclarationMembers = new Map())).set(getNodeId(node), node); + (symbol.assignmentDeclarationMembers || (symbol.assignmentDeclarationMembers = new ts.Map())).set(ts.getNodeId(node), node); } } - function bindSpecialPropertyDeclaration(node: PropertyAccessExpression | LiteralLikeElementAccessExpression) { - if (node.expression.kind === SyntaxKind.ThisKeyword) { + function bindSpecialPropertyDeclaration(node: ts.PropertyAccessExpression | ts.LiteralLikeElementAccessExpression) { + if (node.expression.kind === ts.SyntaxKind.ThisKeyword) { bindThisPropertyAssignment(node); } - else if (isBindableStaticAccessExpression(node) && node.parent.parent.kind === SyntaxKind.SourceFile) { - if (isPrototypeAccess(node.expression)) { + else if (ts.isBindableStaticAccessExpression(node) && node.parent.parent.kind === ts.SyntaxKind.SourceFile) { + if (ts.isPrototypeAccess(node.expression)) { bindPrototypePropertyAssignment(node, node.parent); } else { @@ -3006,17 +2982,17 @@ namespace ts { } /** For `x.prototype = { p, ... }`, declare members p,... if `x` is function/class/{}, or not declared. */ - function bindPrototypeAssignment(node: BindableStaticPropertyAssignmentExpression) { - setParent(node.left, node); - setParent(node.right, node); + function bindPrototypeAssignment(node: ts.BindableStaticPropertyAssignmentExpression) { + ts.setParent(node.left, node); + ts.setParent(node.right, node); bindPropertyAssignment(node.left.expression, node.left, /*isPrototypeProperty*/ false, /*containerIsClass*/ true); } - function bindObjectDefinePrototypeProperty(node: BindableObjectDefinePropertyCall) { - const namespaceSymbol = lookupSymbolForPropertyAccess((node.arguments[0] as PropertyAccessExpression).expression as EntityNameExpression); + function bindObjectDefinePrototypeProperty(node: ts.BindableObjectDefinePropertyCall) { + const namespaceSymbol = lookupSymbolForPropertyAccess((node.arguments[0] as ts.PropertyAccessExpression).expression as ts.EntityNameExpression); if (namespaceSymbol && namespaceSymbol.valueDeclaration) { // Ensure the namespace symbol becomes class-like - addDeclarationToSymbol(namespaceSymbol, namespaceSymbol.valueDeclaration, SymbolFlags.Class); + addDeclarationToSymbol(namespaceSymbol, namespaceSymbol.valueDeclaration, ts.SymbolFlags.Class); } bindPotentiallyNewExpandoMemberToNamespace(node, namespaceSymbol, /*isPrototypeProperty*/ true); } @@ -3025,53 +3001,53 @@ namespace ts { * For `x.prototype.y = z`, declare a member `y` on `x` if `x` is a function or class, or not declared. * Note that jsdoc preceding an ExpressionStatement like `x.prototype.y;` is also treated as a declaration. */ - function bindPrototypePropertyAssignment(lhs: BindableStaticAccessExpression, parent: Node) { + function bindPrototypePropertyAssignment(lhs: ts.BindableStaticAccessExpression, parent: ts.Node) { // Look up the function in the local scope, since prototype assignments should // follow the function declaration - const classPrototype = lhs.expression as BindableStaticAccessExpression; + const classPrototype = lhs.expression as ts.BindableStaticAccessExpression; const constructorFunction = classPrototype.expression; // Fix up parent pointers since we're going to use these nodes before we bind into them - setParent(constructorFunction, classPrototype); - setParent(classPrototype, lhs); - setParent(lhs, parent); + ts.setParent(constructorFunction, classPrototype); + ts.setParent(classPrototype, lhs); + ts.setParent(lhs, parent); bindPropertyAssignment(constructorFunction, lhs, /*isPrototypeProperty*/ true, /*containerIsClass*/ true); } - function bindObjectDefinePropertyAssignment(node: BindableObjectDefinePropertyCall) { + function bindObjectDefinePropertyAssignment(node: ts.BindableObjectDefinePropertyCall) { let namespaceSymbol = lookupSymbolForPropertyAccess(node.arguments[0]); - const isToplevel = node.parent.parent.kind === SyntaxKind.SourceFile; + const isToplevel = node.parent.parent.kind === ts.SyntaxKind.SourceFile; namespaceSymbol = bindPotentiallyMissingNamespaces(namespaceSymbol, node.arguments[0], isToplevel, /*isPrototypeProperty*/ false, /*containerIsClass*/ false); bindPotentiallyNewExpandoMemberToNamespace(node, namespaceSymbol, /*isPrototypeProperty*/ false); } - function bindSpecialPropertyAssignment(node: BindablePropertyAssignmentExpression) { + function bindSpecialPropertyAssignment(node: ts.BindablePropertyAssignmentExpression) { // Class declarations in Typescript do not allow property declarations const parentSymbol = lookupSymbolForPropertyAccess(node.left.expression, container) || lookupSymbolForPropertyAccess(node.left.expression, blockScopeContainer) ; - if (!isInJSFile(node) && !isFunctionSymbol(parentSymbol)) { + if (!ts.isInJSFile(node) && !ts.isFunctionSymbol(parentSymbol)) { return; } - const rootExpr = getLeftmostAccessExpression(node.left); - if (isIdentifier(rootExpr) && lookupSymbolForName(container, rootExpr.escapedText)!?.flags & SymbolFlags.Alias) { + const rootExpr = ts.getLeftmostAccessExpression(node.left); + if (ts.isIdentifier(rootExpr) && lookupSymbolForName(container, rootExpr.escapedText)!?.flags & ts.SymbolFlags.Alias) { return; } // Fix up parent pointers since we're going to use these nodes before we bind into them - setParent(node.left, node); - setParent(node.right, node); - if (isIdentifier(node.left.expression) && container === file && isExportsOrModuleExportsOrAlias(file, node.left.expression)) { + ts.setParent(node.left, node); + ts.setParent(node.right, node); + if (ts.isIdentifier(node.left.expression) && container === file && isExportsOrModuleExportsOrAlias(file, node.left.expression)) { // This can be an alias for the 'exports' or 'module.exports' names, e.g. // var util = module.exports; // util.property = function ... - bindExportsPropertyAssignment(node as BindableStaticPropertyAssignmentExpression); + bindExportsPropertyAssignment(node as ts.BindableStaticPropertyAssignmentExpression); } - else if (hasDynamicName(node)) { - bindAnonymousDeclaration(node, SymbolFlags.Property | SymbolFlags.Assignment, InternalSymbolName.Computed); + else if (ts.hasDynamicName(node)) { + bindAnonymousDeclaration(node, ts.SymbolFlags.Property | ts.SymbolFlags.Assignment, ts.InternalSymbolName.Computed); const sym = bindPotentiallyMissingNamespaces(parentSymbol, node.left.expression, isTopLevelNamespaceAssignment(node.left), /*isPrototype*/ false, /*containerIsClass*/ false); addLateBoundAssignmentDeclarationToSymbol(node, sym); } else { - bindStaticPropertyAssignment(cast(node.left, isBindableStaticNameExpression)); + bindStaticPropertyAssignment(ts.cast(node.left, ts.isBindableStaticNameExpression)); } } @@ -3079,20 +3055,20 @@ namespace ts { * For nodes like `x.y = z`, declare a member 'y' on 'x' if x is a function (or IIFE) or class or {}, or not declared. * Also works for expression statements preceded by JSDoc, like / ** @type number * / x.y; */ - function bindStaticPropertyAssignment(node: BindableStaticNameExpression) { - Debug.assert(!isIdentifier(node)); - setParent(node.expression, node); + function bindStaticPropertyAssignment(node: ts.BindableStaticNameExpression) { + ts.Debug.assert(!ts.isIdentifier(node)); + ts.setParent(node.expression, node); bindPropertyAssignment(node.expression, node, /*isPrototypeProperty*/ false, /*containerIsClass*/ false); } - function bindPotentiallyMissingNamespaces(namespaceSymbol: Symbol | undefined, entityName: BindableStaticNameExpression, isToplevel: boolean, isPrototypeProperty: boolean, containerIsClass: boolean) { - if (namespaceSymbol?.flags! & SymbolFlags.Alias) { + function bindPotentiallyMissingNamespaces(namespaceSymbol: ts.Symbol | undefined, entityName: ts.BindableStaticNameExpression, isToplevel: boolean, isPrototypeProperty: boolean, containerIsClass: boolean) { + if (namespaceSymbol?.flags! & ts.SymbolFlags.Alias) { return namespaceSymbol; } if (isToplevel && !isPrototypeProperty) { // make symbols or add declarations for intermediate containers - const flags = SymbolFlags.Module | SymbolFlags.Assignment; - const excludeFlags = SymbolFlags.ValueModuleExcludes & ~SymbolFlags.Assignment; + const flags = ts.SymbolFlags.Module | ts.SymbolFlags.Assignment; + const excludeFlags = ts.SymbolFlags.ValueModuleExcludes & ~ts.SymbolFlags.Assignment; namespaceSymbol = forEachIdentifierInEntityName(entityName, namespaceSymbol, (id, symbol, parent) => { if (symbol) { addDeclarationToSymbol(symbol, id, flags); @@ -3100,69 +3076,68 @@ namespace ts { } else { const table = parent ? parent.exports! : - file.jsGlobalAugmentations || (file.jsGlobalAugmentations = createSymbolTable()); + file.jsGlobalAugmentations || (file.jsGlobalAugmentations = ts.createSymbolTable()); return declareSymbol(table, parent, id, flags, excludeFlags); } }); } if (containerIsClass && namespaceSymbol && namespaceSymbol.valueDeclaration) { - addDeclarationToSymbol(namespaceSymbol, namespaceSymbol.valueDeclaration, SymbolFlags.Class); + addDeclarationToSymbol(namespaceSymbol, namespaceSymbol.valueDeclaration, ts.SymbolFlags.Class); } return namespaceSymbol; } - function bindPotentiallyNewExpandoMemberToNamespace(declaration: BindableStaticAccessExpression | CallExpression, namespaceSymbol: Symbol | undefined, isPrototypeProperty: boolean) { + function bindPotentiallyNewExpandoMemberToNamespace(declaration: ts.BindableStaticAccessExpression | ts.CallExpression, namespaceSymbol: ts.Symbol | undefined, isPrototypeProperty: boolean) { if (!namespaceSymbol || !isExpandoSymbol(namespaceSymbol)) { return; } // Set up the members collection if it doesn't exist already const symbolTable = isPrototypeProperty ? - (namespaceSymbol.members || (namespaceSymbol.members = createSymbolTable())) : - (namespaceSymbol.exports || (namespaceSymbol.exports = createSymbolTable())); - - let includes = SymbolFlags.None; - let excludes = SymbolFlags.None; + (namespaceSymbol.members || (namespaceSymbol.members = ts.createSymbolTable())) : + (namespaceSymbol.exports || (namespaceSymbol.exports = ts.createSymbolTable())); + let includes = ts.SymbolFlags.None; + let excludes = ts.SymbolFlags.None; // Method-like - if (isFunctionLikeDeclaration(getAssignedExpandoInitializer(declaration)!)) { - includes = SymbolFlags.Method; - excludes = SymbolFlags.MethodExcludes; + if (ts.isFunctionLikeDeclaration(ts.getAssignedExpandoInitializer(declaration)!)) { + includes = ts.SymbolFlags.Method; + excludes = ts.SymbolFlags.MethodExcludes; } // Maybe accessor-like - else if (isCallExpression(declaration) && isBindableObjectDefinePropertyCall(declaration)) { - if (some(declaration.arguments[2].properties, p => { - const id = getNameOfDeclaration(p); - return !!id && isIdentifier(id) && idText(id) === "set"; + else if (ts.isCallExpression(declaration) && ts.isBindableObjectDefinePropertyCall(declaration)) { + if (ts.some(declaration.arguments[2].properties, p => { + const id = ts.getNameOfDeclaration(p); + return !!id && ts.isIdentifier(id) && ts.idText(id) === "set"; })) { // We mix in `SymbolFLags.Property` so in the checker `getTypeOfVariableParameterOrProperty` is used for this // symbol, instead of `getTypeOfAccessor` (which will assert as there is no real accessor declaration) - includes |= SymbolFlags.SetAccessor | SymbolFlags.Property; - excludes |= SymbolFlags.SetAccessorExcludes; + includes |= ts.SymbolFlags.SetAccessor | ts.SymbolFlags.Property; + excludes |= ts.SymbolFlags.SetAccessorExcludes; } - if (some(declaration.arguments[2].properties, p => { - const id = getNameOfDeclaration(p); - return !!id && isIdentifier(id) && idText(id) === "get"; + if (ts.some(declaration.arguments[2].properties, p => { + const id = ts.getNameOfDeclaration(p); + return !!id && ts.isIdentifier(id) && ts.idText(id) === "get"; })) { - includes |= SymbolFlags.GetAccessor | SymbolFlags.Property; - excludes |= SymbolFlags.GetAccessorExcludes; + includes |= ts.SymbolFlags.GetAccessor | ts.SymbolFlags.Property; + excludes |= ts.SymbolFlags.GetAccessorExcludes; } } - if (includes === SymbolFlags.None) { - includes = SymbolFlags.Property; - excludes = SymbolFlags.PropertyExcludes; + if (includes === ts.SymbolFlags.None) { + includes = ts.SymbolFlags.Property; + excludes = ts.SymbolFlags.PropertyExcludes; } - declareSymbol(symbolTable, namespaceSymbol, declaration, includes | SymbolFlags.Assignment, excludes & ~SymbolFlags.Assignment); + declareSymbol(symbolTable, namespaceSymbol, declaration, includes | ts.SymbolFlags.Assignment, excludes & ~ts.SymbolFlags.Assignment); } - function isTopLevelNamespaceAssignment(propertyAccess: BindableAccessExpression) { - return isBinaryExpression(propertyAccess.parent) - ? getParentOfBinaryExpression(propertyAccess.parent).parent.kind === SyntaxKind.SourceFile - : propertyAccess.parent.parent.kind === SyntaxKind.SourceFile; + function isTopLevelNamespaceAssignment(propertyAccess: ts.BindableAccessExpression) { + return ts.isBinaryExpression(propertyAccess.parent) + ? getParentOfBinaryExpression(propertyAccess.parent).parent.kind === ts.SyntaxKind.SourceFile + : propertyAccess.parent.parent.kind === ts.SyntaxKind.SourceFile; } - function bindPropertyAssignment(name: BindableStaticNameExpression, propertyAccess: BindableStaticAccessExpression, isPrototypeProperty: boolean, containerIsClass: boolean) { + function bindPropertyAssignment(name: ts.BindableStaticNameExpression, propertyAccess: ts.BindableStaticAccessExpression, isPrototypeProperty: boolean, containerIsClass: boolean) { let namespaceSymbol = lookupSymbolForPropertyAccess(name, container) || lookupSymbolForPropertyAccess(name, blockScopeContainer); const isToplevel = isTopLevelNamespaceAssignment(propertyAccess); namespaceSymbol = bindPotentiallyMissingNamespaces(namespaceSymbol, propertyAccess.expression, isToplevel, isPrototypeProperty, containerIsClass); @@ -3179,77 +3154,77 @@ namespace ts { * - with empty object literals * - with non-empty object literals if assigned to the prototype property */ - function isExpandoSymbol(symbol: Symbol): boolean { - if (symbol.flags & (SymbolFlags.Function | SymbolFlags.Class | SymbolFlags.NamespaceModule)) { + function isExpandoSymbol(symbol: ts.Symbol): boolean { + if (symbol.flags & (ts.SymbolFlags.Function | ts.SymbolFlags.Class | ts.SymbolFlags.NamespaceModule)) { return true; } const node = symbol.valueDeclaration; - if (node && isCallExpression(node)) { - return !!getAssignedExpandoInitializer(node); + if (node && ts.isCallExpression(node)) { + return !!ts.getAssignedExpandoInitializer(node); } let init = !node ? undefined : - isVariableDeclaration(node) ? node.initializer : - isBinaryExpression(node) ? node.right : - isPropertyAccessExpression(node) && isBinaryExpression(node.parent) ? node.parent.right : + ts.isVariableDeclaration(node) ? node.initializer : + ts.isBinaryExpression(node) ? node.right : + ts.isPropertyAccessExpression(node) && ts.isBinaryExpression(node.parent) ? node.parent.right : undefined; - init = init && getRightMostAssignedExpression(init); + init = init && ts.getRightMostAssignedExpression(init); if (init) { - const isPrototypeAssignment = isPrototypeAccess(isVariableDeclaration(node!) ? node.name : isBinaryExpression(node!) ? node.left : node!); - return !!getExpandoInitializer(isBinaryExpression(init) && (init.operatorToken.kind === SyntaxKind.BarBarToken || init.operatorToken.kind === SyntaxKind.QuestionQuestionToken) ? init.right : init, isPrototypeAssignment); + const isPrototypeAssignment = ts.isPrototypeAccess(ts.isVariableDeclaration(node!) ? node.name : ts.isBinaryExpression(node!) ? node.left : node!); + return !!ts.getExpandoInitializer(ts.isBinaryExpression(init) && (init.operatorToken.kind === ts.SyntaxKind.BarBarToken || init.operatorToken.kind === ts.SyntaxKind.QuestionQuestionToken) ? init.right : init, isPrototypeAssignment); } return false; } - function getParentOfBinaryExpression(expr: Node) { - while (isBinaryExpression(expr.parent)) { + function getParentOfBinaryExpression(expr: ts.Node) { + while (ts.isBinaryExpression(expr.parent)) { expr = expr.parent; } return expr.parent; } - function lookupSymbolForPropertyAccess(node: BindableStaticNameExpression, lookupContainer: Node = container): Symbol | undefined { - if (isIdentifier(node)) { + function lookupSymbolForPropertyAccess(node: ts.BindableStaticNameExpression, lookupContainer: ts.Node = container): ts.Symbol | undefined { + if (ts.isIdentifier(node)) { return lookupSymbolForName(lookupContainer, node.escapedText); } else { const symbol = lookupSymbolForPropertyAccess(node.expression); - return symbol && symbol.exports && symbol.exports.get(getElementOrPropertyAccessName(node)); + return symbol && symbol.exports && symbol.exports.get(ts.getElementOrPropertyAccessName(node)); } } - function forEachIdentifierInEntityName(e: BindableStaticNameExpression, parent: Symbol | undefined, action: (e: Declaration, symbol: Symbol | undefined, parent: Symbol | undefined) => Symbol | undefined): Symbol | undefined { + function forEachIdentifierInEntityName(e: ts.BindableStaticNameExpression, parent: ts.Symbol | undefined, action: (e: ts.Declaration, symbol: ts.Symbol | undefined, parent: ts.Symbol | undefined) => ts.Symbol | undefined): ts.Symbol | undefined { if (isExportsOrModuleExportsOrAlias(file, e)) { return file.symbol; } - else if (isIdentifier(e)) { + else if (ts.isIdentifier(e)) { return action(e, lookupSymbolForPropertyAccess(e), parent); } else { const s = forEachIdentifierInEntityName(e.expression, parent, action); - const name = getNameOrArgument(e); + const name = ts.getNameOrArgument(e); // unreachable - if (isPrivateIdentifier(name)) { - Debug.fail("unexpected PrivateIdentifier"); + if (ts.isPrivateIdentifier(name)) { + ts.Debug.fail("unexpected PrivateIdentifier"); } - return action(name, s && s.exports && s.exports.get(getElementOrPropertyAccessName(e)), s); + return action(name, s && s.exports && s.exports.get(ts.getElementOrPropertyAccessName(e)), s); } } - function bindCallExpression(node: CallExpression) { + function bindCallExpression(node: ts.CallExpression) { // We're only inspecting call expressions to detect CommonJS modules, so we can skip // this check if we've already seen the module indicator - if (!file.commonJsModuleIndicator && isRequireCall(node, /*checkArgumentIsStringLiteralLike*/ false)) { + if (!file.commonJsModuleIndicator && ts.isRequireCall(node, /*checkArgumentIsStringLiteralLike*/ false)) { setCommonJsModuleIndicator(node); } } - function bindClassLikeDeclaration(node: ClassLikeDeclaration) { - if (node.kind === SyntaxKind.ClassDeclaration) { - bindBlockScopedDeclaration(node, SymbolFlags.Class, SymbolFlags.ClassExcludes); + function bindClassLikeDeclaration(node: ts.ClassLikeDeclaration) { + if (node.kind === ts.SyntaxKind.ClassDeclaration) { + bindBlockScopedDeclaration(node, ts.SymbolFlags.Class, ts.SymbolFlags.ClassExcludes); } else { - const bindingName = node.name ? node.name.escapedText : InternalSymbolName.Class; - bindAnonymousDeclaration(node, SymbolFlags.Class, bindingName); + const bindingName = node.name ? node.name.escapedText : ts.InternalSymbolName.Class; + bindAnonymousDeclaration(node, ts.SymbolFlags.Class, bindingName); // Add name of class expression into the map for semantic classifier if (node.name) { classifiableNames.add(node.name.escapedText); @@ -3267,37 +3242,37 @@ namespace ts { // Note: we check for this here because this class may be merging into a module. The // module might have an exported variable called 'prototype'. We can't allow that as // that would clash with the built-in 'prototype' for the class. - const prototypeSymbol = createSymbol(SymbolFlags.Property | SymbolFlags.Prototype, "prototype" as __String); + const prototypeSymbol = createSymbol(ts.SymbolFlags.Property | ts.SymbolFlags.Prototype, "prototype" as ts.__String); const symbolExport = symbol.exports!.get(prototypeSymbol.escapedName); if (symbolExport) { if (node.name) { - setParent(node.name, node); + ts.setParent(node.name, node); } - file.bindDiagnostics.push(createDiagnosticForNode(symbolExport.declarations![0], Diagnostics.Duplicate_identifier_0, symbolName(prototypeSymbol))); + file.bindDiagnostics.push(createDiagnosticForNode(symbolExport.declarations![0], ts.Diagnostics.Duplicate_identifier_0, ts.symbolName(prototypeSymbol))); } symbol.exports!.set(prototypeSymbol.escapedName, prototypeSymbol); prototypeSymbol.parent = symbol; } - function bindEnumDeclaration(node: EnumDeclaration) { - return isEnumConst(node) - ? bindBlockScopedDeclaration(node, SymbolFlags.ConstEnum, SymbolFlags.ConstEnumExcludes) - : bindBlockScopedDeclaration(node, SymbolFlags.RegularEnum, SymbolFlags.RegularEnumExcludes); + function bindEnumDeclaration(node: ts.EnumDeclaration) { + return ts.isEnumConst(node) + ? bindBlockScopedDeclaration(node, ts.SymbolFlags.ConstEnum, ts.SymbolFlags.ConstEnumExcludes) + : bindBlockScopedDeclaration(node, ts.SymbolFlags.RegularEnum, ts.SymbolFlags.RegularEnumExcludes); } - function bindVariableDeclarationOrBindingElement(node: VariableDeclaration | BindingElement) { + function bindVariableDeclarationOrBindingElement(node: ts.VariableDeclaration | ts.BindingElement) { if (inStrictMode) { checkStrictModeEvalOrArguments(node, node.name); } - if (!isBindingPattern(node.name)) { - if (isInJSFile(node) && isVariableDeclarationInitializedToBareOrAccessedRequire(node) && !getJSDocTypeTag(node) && !(getCombinedModifierFlags(node) & ModifierFlags.Export)) { - declareSymbolAndAddToSymbolTable(node as Declaration, SymbolFlags.Alias, SymbolFlags.AliasExcludes); + if (!ts.isBindingPattern(node.name)) { + if (ts.isInJSFile(node) && ts.isVariableDeclarationInitializedToBareOrAccessedRequire(node) && !ts.getJSDocTypeTag(node) && !(ts.getCombinedModifierFlags(node) & ts.ModifierFlags.Export)) { + declareSymbolAndAddToSymbolTable(node as ts.Declaration, ts.SymbolFlags.Alias, ts.SymbolFlags.AliasExcludes); } - else if (isBlockOrCatchScoped(node)) { - bindBlockScopedDeclaration(node, SymbolFlags.BlockScopedVariable, SymbolFlags.BlockScopedVariableExcludes); + else if (ts.isBlockOrCatchScoped(node)) { + bindBlockScopedDeclaration(node, ts.SymbolFlags.BlockScopedVariable, ts.SymbolFlags.BlockScopedVariableExcludes); } - else if (isParameterDeclaration(node)) { + else if (ts.isParameterDeclaration(node)) { // It is safe to walk up parent chain to find whether the node is a destructuring parameter declaration // because its parent chain has already been set up, since parents are set before descending into children. // @@ -3307,138 +3282,138 @@ namespace ts { // function foo([a,a]) {} // Duplicate Identifier error // function bar(a,a) {} // Duplicate Identifier error, parameter declaration in this case is handled in bindParameter // // which correctly set excluded symbols - declareSymbolAndAddToSymbolTable(node, SymbolFlags.FunctionScopedVariable, SymbolFlags.ParameterExcludes); + declareSymbolAndAddToSymbolTable(node, ts.SymbolFlags.FunctionScopedVariable, ts.SymbolFlags.ParameterExcludes); } else { - declareSymbolAndAddToSymbolTable(node, SymbolFlags.FunctionScopedVariable, SymbolFlags.FunctionScopedVariableExcludes); + declareSymbolAndAddToSymbolTable(node, ts.SymbolFlags.FunctionScopedVariable, ts.SymbolFlags.FunctionScopedVariableExcludes); } } } - function bindParameter(node: ParameterDeclaration | JSDocParameterTag) { - if (node.kind === SyntaxKind.JSDocParameterTag && container.kind !== SyntaxKind.JSDocSignature) { + function bindParameter(node: ts.ParameterDeclaration | ts.JSDocParameterTag) { + if (node.kind === ts.SyntaxKind.JSDocParameterTag && container.kind !== ts.SyntaxKind.JSDocSignature) { return; } - if (inStrictMode && !(node.flags & NodeFlags.Ambient)) { + if (inStrictMode && !(node.flags & ts.NodeFlags.Ambient)) { // It is a SyntaxError if the identifier eval or arguments appears within a FormalParameterList of a // strict mode FunctionLikeDeclaration or FunctionExpression(13.1) checkStrictModeEvalOrArguments(node, node.name); } - if (isBindingPattern(node.name)) { - bindAnonymousDeclaration(node, SymbolFlags.FunctionScopedVariable, "__" + (node as ParameterDeclaration).parent.parameters.indexOf(node as ParameterDeclaration) as __String); + if (ts.isBindingPattern(node.name)) { + bindAnonymousDeclaration(node, ts.SymbolFlags.FunctionScopedVariable, "__" + (node as ts.ParameterDeclaration).parent.parameters.indexOf(node as ts.ParameterDeclaration) as ts.__String); } else { - declareSymbolAndAddToSymbolTable(node, SymbolFlags.FunctionScopedVariable, SymbolFlags.ParameterExcludes); + declareSymbolAndAddToSymbolTable(node, ts.SymbolFlags.FunctionScopedVariable, ts.SymbolFlags.ParameterExcludes); } // If this is a property-parameter, then also declare the property symbol into the // containing class. - if (isParameterPropertyDeclaration(node, node.parent)) { + if (ts.isParameterPropertyDeclaration(node, node.parent)) { const classDeclaration = node.parent.parent; - declareSymbol(classDeclaration.symbol.members!, classDeclaration.symbol, node, SymbolFlags.Property | (node.questionToken ? SymbolFlags.Optional : SymbolFlags.None), SymbolFlags.PropertyExcludes); + declareSymbol(classDeclaration.symbol.members!, classDeclaration.symbol, node, ts.SymbolFlags.Property | (node.questionToken ? ts.SymbolFlags.Optional : ts.SymbolFlags.None), ts.SymbolFlags.PropertyExcludes); } } - function bindFunctionDeclaration(node: FunctionDeclaration) { - if (!file.isDeclarationFile && !(node.flags & NodeFlags.Ambient)) { - if (isAsyncFunction(node)) { - emitFlags |= NodeFlags.HasAsyncFunctions; + function bindFunctionDeclaration(node: ts.FunctionDeclaration) { + if (!file.isDeclarationFile && !(node.flags & ts.NodeFlags.Ambient)) { + if (ts.isAsyncFunction(node)) { + emitFlags |= ts.NodeFlags.HasAsyncFunctions; } } checkStrictModeFunctionName(node); if (inStrictMode) { checkStrictModeFunctionDeclaration(node); - bindBlockScopedDeclaration(node, SymbolFlags.Function, SymbolFlags.FunctionExcludes); + bindBlockScopedDeclaration(node, ts.SymbolFlags.Function, ts.SymbolFlags.FunctionExcludes); } else { - declareSymbolAndAddToSymbolTable(node, SymbolFlags.Function, SymbolFlags.FunctionExcludes); + declareSymbolAndAddToSymbolTable(node, ts.SymbolFlags.Function, ts.SymbolFlags.FunctionExcludes); } } - function bindFunctionExpression(node: FunctionExpression) { - if (!file.isDeclarationFile && !(node.flags & NodeFlags.Ambient)) { - if (isAsyncFunction(node)) { - emitFlags |= NodeFlags.HasAsyncFunctions; + function bindFunctionExpression(node: ts.FunctionExpression) { + if (!file.isDeclarationFile && !(node.flags & ts.NodeFlags.Ambient)) { + if (ts.isAsyncFunction(node)) { + emitFlags |= ts.NodeFlags.HasAsyncFunctions; } } if (currentFlow) { node.flowNode = currentFlow; } checkStrictModeFunctionName(node); - const bindingName = node.name ? node.name.escapedText : InternalSymbolName.Function; - return bindAnonymousDeclaration(node, SymbolFlags.Function, bindingName); + const bindingName = node.name ? node.name.escapedText : ts.InternalSymbolName.Function; + return bindAnonymousDeclaration(node, ts.SymbolFlags.Function, bindingName); } - function bindPropertyOrMethodOrAccessor(node: Declaration, symbolFlags: SymbolFlags, symbolExcludes: SymbolFlags) { - if (!file.isDeclarationFile && !(node.flags & NodeFlags.Ambient) && isAsyncFunction(node)) { - emitFlags |= NodeFlags.HasAsyncFunctions; + function bindPropertyOrMethodOrAccessor(node: ts.Declaration, symbolFlags: ts.SymbolFlags, symbolExcludes: ts.SymbolFlags) { + if (!file.isDeclarationFile && !(node.flags & ts.NodeFlags.Ambient) && ts.isAsyncFunction(node)) { + emitFlags |= ts.NodeFlags.HasAsyncFunctions; } - if (currentFlow && isObjectLiteralOrClassExpressionMethodOrAccessor(node)) { + if (currentFlow && ts.isObjectLiteralOrClassExpressionMethodOrAccessor(node)) { node.flowNode = currentFlow; } - return hasDynamicName(node) - ? bindAnonymousDeclaration(node, symbolFlags, InternalSymbolName.Computed) + return ts.hasDynamicName(node) + ? bindAnonymousDeclaration(node, symbolFlags, ts.InternalSymbolName.Computed) : declareSymbolAndAddToSymbolTable(node, symbolFlags, symbolExcludes); } - function getInferTypeContainer(node: Node): ConditionalTypeNode | undefined { - const extendsType = findAncestor(node, n => n.parent && isConditionalTypeNode(n.parent) && n.parent.extendsType === n); - return extendsType && extendsType.parent as ConditionalTypeNode; + function getInferTypeContainer(node: ts.Node): ts.ConditionalTypeNode | undefined { + const extendsType = ts.findAncestor(node, n => n.parent && ts.isConditionalTypeNode(n.parent) && n.parent.extendsType === n); + return extendsType && extendsType.parent as ts.ConditionalTypeNode; } - function bindTypeParameter(node: TypeParameterDeclaration) { - if (isJSDocTemplateTag(node.parent)) { - const container = getEffectiveContainerForJSDocTemplateTag(node.parent); + function bindTypeParameter(node: ts.TypeParameterDeclaration) { + if (ts.isJSDocTemplateTag(node.parent)) { + const container = ts.getEffectiveContainerForJSDocTemplateTag(node.parent); if (container) { if (!container.locals) { - container.locals = createSymbolTable(); + container.locals = ts.createSymbolTable(); } - declareSymbol(container.locals, /*parent*/ undefined, node, SymbolFlags.TypeParameter, SymbolFlags.TypeParameterExcludes); + declareSymbol(container.locals, /*parent*/ undefined, node, ts.SymbolFlags.TypeParameter, ts.SymbolFlags.TypeParameterExcludes); } else { - declareSymbolAndAddToSymbolTable(node, SymbolFlags.TypeParameter, SymbolFlags.TypeParameterExcludes); + declareSymbolAndAddToSymbolTable(node, ts.SymbolFlags.TypeParameter, ts.SymbolFlags.TypeParameterExcludes); } } - else if (node.parent.kind === SyntaxKind.InferType) { + else if (node.parent.kind === ts.SyntaxKind.InferType) { const container = getInferTypeContainer(node.parent); if (container) { if (!container.locals) { - container.locals = createSymbolTable(); + container.locals = ts.createSymbolTable(); } - declareSymbol(container.locals, /*parent*/ undefined, node, SymbolFlags.TypeParameter, SymbolFlags.TypeParameterExcludes); + declareSymbol(container.locals, /*parent*/ undefined, node, ts.SymbolFlags.TypeParameter, ts.SymbolFlags.TypeParameterExcludes); } else { - bindAnonymousDeclaration(node, SymbolFlags.TypeParameter, getDeclarationName(node)!); // TODO: GH#18217 + bindAnonymousDeclaration(node, ts.SymbolFlags.TypeParameter, getDeclarationName(node)!); // TODO: GH#18217 } } else { - declareSymbolAndAddToSymbolTable(node, SymbolFlags.TypeParameter, SymbolFlags.TypeParameterExcludes); + declareSymbolAndAddToSymbolTable(node, ts.SymbolFlags.TypeParameter, ts.SymbolFlags.TypeParameterExcludes); } } // reachability checks - function shouldReportErrorOnModuleDeclaration(node: ModuleDeclaration): boolean { + function shouldReportErrorOnModuleDeclaration(node: ts.ModuleDeclaration): boolean { const instanceState = getModuleInstanceState(node); - return instanceState === ModuleInstanceState.Instantiated || (instanceState === ModuleInstanceState.ConstEnumOnly && shouldPreserveConstEnums(options)); + return instanceState === ModuleInstanceState.Instantiated || (instanceState === ModuleInstanceState.ConstEnumOnly && ts.shouldPreserveConstEnums(options)); } - function checkUnreachable(node: Node): boolean { - if (!(currentFlow.flags & FlowFlags.Unreachable)) { + function checkUnreachable(node: ts.Node): boolean { + if (!(currentFlow.flags & ts.FlowFlags.Unreachable)) { return false; } if (currentFlow === unreachableFlow) { const reportError = // report error on all statements except empty ones - (isStatementButNotDeclaration(node) && node.kind !== SyntaxKind.EmptyStatement) || + (ts.isStatementButNotDeclaration(node) && node.kind !== ts.SyntaxKind.EmptyStatement) || // report error on class declarations - node.kind === SyntaxKind.ClassDeclaration || + node.kind === ts.SyntaxKind.ClassDeclaration || // report error on instantiated modules or const-enums only modules if preserveConstEnums is set - (node.kind === SyntaxKind.ModuleDeclaration && shouldReportErrorOnModuleDeclaration(node as ModuleDeclaration)); + (node.kind === ts.SyntaxKind.ModuleDeclaration && shouldReportErrorOnModuleDeclaration(node as ts.ModuleDeclaration)); if (reportError) { currentFlow = reportedUnreachableFlow; @@ -3453,16 +3428,12 @@ namespace ts { // - node is not block scoped variable statement and at least one variable declaration has initializer // Rationale: we don't want to report errors on non-initialized var's since they are hoisted // On the other side we do want to report errors on non-initialized 'lets' because of TDZ - const isError = - unreachableCodeIsError(options) && - !(node.flags & NodeFlags.Ambient) && - ( - !isVariableStatement(node) || - !!(getCombinedNodeFlags(node.declarationList) & NodeFlags.BlockScoped) || - node.declarationList.declarations.some(d => !!d.initializer) - ); - - eachUnreachableRange(node, (start, end) => errorOrSuggestionOnRange(isError, start, end, Diagnostics.Unreachable_code_detected)); + const isError = ts.unreachableCodeIsError(options) && + !(node.flags & ts.NodeFlags.Ambient) && + (!ts.isVariableStatement(node) || + !!(ts.getCombinedNodeFlags(node.declarationList) & ts.NodeFlags.BlockScoped) || + node.declarationList.declarations.some(d => !!d.initializer)); + eachUnreachableRange(node, (start, end) => errorOrSuggestionOnRange(isError, start, end, ts.Diagnostics.Unreachable_code_detected)); } } } @@ -3470,53 +3441,53 @@ namespace ts { } } - function eachUnreachableRange(node: Node, cb: (start: Node, last: Node) => void): void { - if (isStatement(node) && isExecutableStatement(node) && isBlock(node.parent)) { + function eachUnreachableRange(node: ts.Node, cb: (start: ts.Node, last: ts.Node) => void): void { + if (ts.isStatement(node) && isExecutableStatement(node) && ts.isBlock(node.parent)) { const { statements } = node.parent; - const slice = sliceAfter(statements, node); - getRangesWhere(slice, isExecutableStatement, (start, afterEnd) => cb(slice[start], slice[afterEnd - 1])); + const slice = ts.sliceAfter(statements, node); + ts.getRangesWhere(slice, isExecutableStatement, (start, afterEnd) => cb(slice[start], slice[afterEnd - 1])); } else { cb(node, node); } } // As opposed to a pure declaration like an `interface` - function isExecutableStatement(s: Statement): boolean { + function isExecutableStatement(s: ts.Statement): boolean { // Don't remove statements that can validly be used before they appear. - return !isFunctionDeclaration(s) && !isPurelyTypeDeclaration(s) && !isEnumDeclaration(s) && + return !ts.isFunctionDeclaration(s) && !isPurelyTypeDeclaration(s) && !ts.isEnumDeclaration(s) && // `var x;` may declare a variable used above - !(isVariableStatement(s) && !(getCombinedNodeFlags(s) & (NodeFlags.Let | NodeFlags.Const)) && s.declarationList.declarations.some(d => !d.initializer)); + !(ts.isVariableStatement(s) && !(ts.getCombinedNodeFlags(s) & (ts.NodeFlags.Let | ts.NodeFlags.Const)) && s.declarationList.declarations.some(d => !d.initializer)); } - function isPurelyTypeDeclaration(s: Statement): boolean { + function isPurelyTypeDeclaration(s: ts.Statement): boolean { switch (s.kind) { - case SyntaxKind.InterfaceDeclaration: - case SyntaxKind.TypeAliasDeclaration: + case ts.SyntaxKind.InterfaceDeclaration: + case ts.SyntaxKind.TypeAliasDeclaration: return true; - case SyntaxKind.ModuleDeclaration: - return getModuleInstanceState(s as ModuleDeclaration) !== ModuleInstanceState.Instantiated; - case SyntaxKind.EnumDeclaration: - return hasSyntacticModifier(s, ModifierFlags.Const); + case ts.SyntaxKind.ModuleDeclaration: + return getModuleInstanceState(s as ts.ModuleDeclaration) !== ModuleInstanceState.Instantiated; + case ts.SyntaxKind.EnumDeclaration: + return ts.hasSyntacticModifier(s, ts.ModifierFlags.Const); default: return false; } } - export function isExportsOrModuleExportsOrAlias(sourceFile: SourceFile, node: Expression): boolean { + export function isExportsOrModuleExportsOrAlias(sourceFile: ts.SourceFile, node: ts.Expression): boolean { let i = 0; const q = [node]; while (q.length && i < 100) { i++; node = q.shift()!; - if (isExportsIdentifier(node) || isModuleExportsAccessExpression(node)) { + if (ts.isExportsIdentifier(node) || ts.isModuleExportsAccessExpression(node)) { return true; } - else if (isIdentifier(node)) { + else if (ts.isIdentifier(node)) { const symbol = lookupSymbolForName(sourceFile, node.escapedText); - if (!!symbol && !!symbol.valueDeclaration && isVariableDeclaration(symbol.valueDeclaration) && !!symbol.valueDeclaration.initializer) { + if (!!symbol && !!symbol.valueDeclaration && ts.isVariableDeclaration(symbol.valueDeclaration) && !!symbol.valueDeclaration.initializer) { const init = symbol.valueDeclaration.initializer; q.push(init); - if (isAssignmentExpression(init, /*excludeCompoundAssignment*/ true)) { + if (ts.isAssignmentExpression(init, /*excludeCompoundAssignment*/ true)) { q.push(init.left); q.push(init.right); } @@ -3526,12 +3497,12 @@ namespace ts { return false; } - function lookupSymbolForName(container: Node, name: __String): Symbol | undefined { + function lookupSymbolForName(container: ts.Node, name: ts.__String): ts.Symbol | undefined { const local = container.locals && container.locals.get(name); if (local) { return local.exportSymbol || local; } - if (isSourceFile(container) && container.jsGlobalAugmentations && container.jsGlobalAugmentations.has(name)) { + if (ts.isSourceFile(container) && container.jsGlobalAugmentations && container.jsGlobalAugmentations.has(name)) { return container.jsGlobalAugmentations.get(name); } return container.symbol && container.symbol.exports && container.symbol.exports.get(name); diff --git a/src/compiler/builder.ts b/src/compiler/builder.ts index 0485f10cbf071..7626ad2638982 100644 --- a/src/compiler/builder.ts +++ b/src/compiler/builder.ts @@ -3,14 +3,14 @@ namespace ts { export interface ReusableDiagnostic extends ReusableDiagnosticRelatedInformation { /** May store more in future. For now, this will simply be `true` to indicate when a diagnostic is an unused-identifier diagnostic. */ reportsUnnecessary?: {}; - reportDeprecated?: {} + reportDeprecated?: {}; source?: string; relatedInformation?: ReusableDiagnosticRelatedInformation[]; - skippedOn?: keyof CompilerOptions; + skippedOn?: keyof ts.CompilerOptions; } export interface ReusableDiagnosticRelatedInformation { - category: DiagnosticCategory; + category: ts.DiagnosticCategory; code: number; file: string | undefined; start: number | undefined; @@ -18,54 +18,53 @@ namespace ts { messageText: string | ReusableDiagnosticMessageChain; } - export type ReusableDiagnosticMessageChain = DiagnosticMessageChain; - - export interface ReusableBuilderProgramState extends ReusableBuilderState { + export type ReusableDiagnosticMessageChain = ts.DiagnosticMessageChain; + export interface ReusableBuilderProgramState extends ts.ReusableBuilderState { /** * Cache of bind and check diagnostics for files with their Path being the key */ - semanticDiagnosticsPerFile?: ReadonlyESMap | undefined; + semanticDiagnosticsPerFile?: ts.ReadonlyESMap | undefined; /** * The map has key by source file's path that has been changed */ - changedFilesSet?: ReadonlySet; + changedFilesSet?: ts.ReadonlySet; /** * Set of affected files being iterated */ - affectedFiles?: readonly SourceFile[] | undefined; + affectedFiles?: readonly ts.SourceFile[] | undefined; /** * Current changed file for iterating over affected files */ - currentChangedFilePath?: Path | undefined; + currentChangedFilePath?: ts.Path | undefined; /** * Map of file signatures, with key being file path, calculated while getting current changed file's affected files * These will be committed whenever the iteration through affected files of current changed file is complete */ - currentAffectedFilesSignatures?: ReadonlyESMap | undefined; + currentAffectedFilesSignatures?: ts.ReadonlyESMap | undefined; /** * Newly computed visible to outside referencedSet */ - currentAffectedFilesExportedModulesMap?: BuilderState.ReadonlyManyToManyPathMap | undefined; + currentAffectedFilesExportedModulesMap?: ts.BuilderState.ReadonlyManyToManyPathMap | undefined; /** * True if the semantic diagnostics were copied from the old state */ - semanticDiagnosticsFromOldState?: Set; + semanticDiagnosticsFromOldState?: ts.Set; /** * program corresponding to this state */ - program?: Program | undefined; + program?: ts.Program | undefined; /** * compilerOptions for the program */ - compilerOptions: CompilerOptions; + compilerOptions: ts.CompilerOptions; /** * Files pending to be emitted */ - affectedFilesPendingEmit?: readonly Path[] | undefined; + affectedFilesPendingEmit?: readonly ts.Path[] | undefined; /** * Files pending to be emitted kind. */ - affectedFilesPendingEmitKind?: ReadonlyESMap | undefined; + affectedFilesPendingEmitKind?: ts.ReadonlyESMap | undefined; /** * Current index to retrieve pending affected file */ @@ -85,19 +84,19 @@ namespace ts { * State to store the changed files, affected files and cache semantic diagnostics */ // TODO: GH#18217 Properties of this interface are frequently asserted to be defined. - export interface BuilderProgramState extends BuilderState { + export interface BuilderProgramState extends ts.BuilderState { /** * Cache of bind and check diagnostics for files with their Path being the key */ - semanticDiagnosticsPerFile: ESMap | undefined; + semanticDiagnosticsPerFile: ts.ESMap | undefined; /** * The map has key by source file's path that has been changed */ - changedFilesSet: Set; + changedFilesSet: ts.Set; /** * Set of affected files being iterated */ - affectedFiles: readonly SourceFile[] | undefined; + affectedFiles: readonly ts.SourceFile[] | undefined; /** * Current index to retrieve affected file from */ @@ -105,22 +104,22 @@ namespace ts { /** * Current changed file for iterating over affected files */ - currentChangedFilePath: Path | undefined; + currentChangedFilePath: ts.Path | undefined; /** * Map of file signatures, with key being file path, calculated while getting current changed file's affected files * These will be committed whenever the iteration through affected files of current changed file is complete */ - currentAffectedFilesSignatures: ESMap | undefined; + currentAffectedFilesSignatures: ts.ESMap | undefined; /** * Newly computed visible to outside referencedSet * We need to store the updates separately in case the in-progress build is cancelled * and we need to roll back. */ - currentAffectedFilesExportedModulesMap: BuilderState.ManyToManyPathMap | undefined; + currentAffectedFilesExportedModulesMap: ts.BuilderState.ManyToManyPathMap | undefined; /** * Already seen affected files */ - seenAffectedFiles: Set | undefined; + seenAffectedFiles: ts.Set | undefined; /** * whether this program has cleaned semantic diagnostics cache for lib files */ @@ -128,23 +127,23 @@ namespace ts { /** * True if the semantic diagnostics were copied from the old state */ - semanticDiagnosticsFromOldState?: Set; + semanticDiagnosticsFromOldState?: ts.Set; /** * program corresponding to this state */ - program: Program | undefined; + program: ts.Program | undefined; /** * compilerOptions for the program */ - compilerOptions: CompilerOptions; + compilerOptions: ts.CompilerOptions; /** * Files pending to be emitted */ - affectedFilesPendingEmit: Path[] | undefined; + affectedFilesPendingEmit: ts.Path[] | undefined; /** * Files pending to be emitted kind. */ - affectedFilesPendingEmitKind: ESMap | undefined; + affectedFilesPendingEmitKind: ts.ESMap | undefined; /** * Current index to retrieve pending affected file */ @@ -156,56 +155,55 @@ namespace ts { /** * Already seen emitted files */ - seenEmittedFiles: ESMap | undefined; + seenEmittedFiles: ts.ESMap | undefined; /** * true if program has been emitted */ programEmitComplete?: true; /** Stores list of files that change signature during emit - test only */ - filesChangingSignature?: Set; + filesChangingSignature?: ts.Set; } - function hasSameKeys(map1: ReadonlyCollection | undefined, map2: ReadonlyCollection | undefined): boolean { + function hasSameKeys(map1: ts.ReadonlyCollection | undefined, map2: ts.ReadonlyCollection | undefined): boolean { // Has same size and every key is present in both maps - return map1 === map2 || map1 !== undefined && map2 !== undefined && map1.size === map2.size && !forEachKey(map1, key => !map2.has(key)); + return map1 === map2 || map1 !== undefined && map2 !== undefined && map1.size === map2.size && !ts.forEachKey(map1, key => !map2.has(key)); } /** * Create the state so that we can iterate on changedFiles/affected files */ - function createBuilderProgramState(newProgram: Program, getCanonicalFileName: GetCanonicalFileName, oldState: Readonly | undefined, disableUseFileVersionAsSignature: boolean | undefined): BuilderProgramState { - const state = BuilderState.create(newProgram, getCanonicalFileName, oldState, disableUseFileVersionAsSignature) as BuilderProgramState; + function createBuilderProgramState(newProgram: ts.Program, getCanonicalFileName: ts.GetCanonicalFileName, oldState: Readonly | undefined, disableUseFileVersionAsSignature: boolean | undefined): BuilderProgramState { + const state = ts.BuilderState.create(newProgram, getCanonicalFileName, oldState, disableUseFileVersionAsSignature) as BuilderProgramState; state.program = newProgram; const compilerOptions = newProgram.getCompilerOptions(); state.compilerOptions = compilerOptions; // With --out or --outFile, any change affects all semantic diagnostics so no need to cache them - if (!outFile(compilerOptions)) { - state.semanticDiagnosticsPerFile = new Map(); + if (!ts.outFile(compilerOptions)) { + state.semanticDiagnosticsPerFile = new ts.Map(); } - state.changedFilesSet = new Set(); - - const useOldState = BuilderState.canReuseOldState(state.referencedMap, oldState); + state.changedFilesSet = new ts.Set(); + const useOldState = ts.BuilderState.canReuseOldState(state.referencedMap, oldState); const oldCompilerOptions = useOldState ? oldState!.compilerOptions : undefined; const canCopySemanticDiagnostics = useOldState && oldState!.semanticDiagnosticsPerFile && !!state.semanticDiagnosticsPerFile && - !compilerOptionsAffectSemanticDiagnostics(compilerOptions, oldCompilerOptions!); + !ts.compilerOptionsAffectSemanticDiagnostics(compilerOptions, oldCompilerOptions!); if (useOldState) { // Verify the sanity of old state if (!oldState!.currentChangedFilePath) { const affectedSignatures = oldState!.currentAffectedFilesSignatures; - Debug.assert(!oldState!.affectedFiles && (!affectedSignatures || !affectedSignatures.size), "Cannot reuse if only few affected files of currentChangedFile were iterated"); + ts.Debug.assert(!oldState!.affectedFiles && (!affectedSignatures || !affectedSignatures.size), "Cannot reuse if only few affected files of currentChangedFile were iterated"); } const changedFilesSet = oldState!.changedFilesSet; if (canCopySemanticDiagnostics) { - Debug.assert(!changedFilesSet || !forEachKey(changedFilesSet, path => oldState!.semanticDiagnosticsPerFile!.has(path)), "Semantic diagnostics shouldnt be available for changed files"); + ts.Debug.assert(!changedFilesSet || !ts.forEachKey(changedFilesSet, path => oldState!.semanticDiagnosticsPerFile!.has(path)), "Semantic diagnostics shouldnt be available for changed files"); } // Copy old state's changed files set changedFilesSet?.forEach(value => state.changedFilesSet.add(value)); - if (!outFile(compilerOptions) && oldState!.affectedFilesPendingEmit) { + if (!ts.outFile(compilerOptions) && oldState!.affectedFilesPendingEmit) { state.affectedFilesPendingEmit = oldState!.affectedFilesPendingEmit.slice(); - state.affectedFilesPendingEmitKind = oldState!.affectedFilesPendingEmitKind && new Map(oldState!.affectedFilesPendingEmitKind); + state.affectedFilesPendingEmitKind = oldState!.affectedFilesPendingEmitKind && new ts.Map(oldState!.affectedFilesPendingEmitKind); state.affectedFilesPendingEmitIndex = oldState!.affectedFilesPendingEmitIndex; - state.seenAffectedFiles = new Set(); + state.seenAffectedFiles = new ts.Set(); } } @@ -215,8 +213,8 @@ namespace ts { const copyDeclarationFileDiagnostics = canCopySemanticDiagnostics && !compilerOptions.skipLibCheck === !oldCompilerOptions!.skipLibCheck; const copyLibFileDiagnostics = copyDeclarationFileDiagnostics && !compilerOptions.skipDefaultLibCheck === !oldCompilerOptions!.skipDefaultLibCheck; state.fileInfos.forEach((info, sourceFilePath) => { - let oldInfo: Readonly | undefined; - let newReferences: ReadonlySet | undefined; + let oldInfo: Readonly | undefined; + let newReferences: ts.ReadonlySet | undefined; // if not using old state, every file is changed if (!useOldState || @@ -227,22 +225,24 @@ namespace ts { // Referenced files changed !hasSameKeys(newReferences = referencedMap && referencedMap.getValues(sourceFilePath), oldReferencedMap && oldReferencedMap.getValues(sourceFilePath)) || // Referenced file was deleted in the new program - newReferences && forEachKey(newReferences, path => !state.fileInfos.has(path) && oldState!.fileInfos.has(path))) { + newReferences && ts.forEachKey(newReferences, path => !state.fileInfos.has(path) && oldState!.fileInfos.has(path))) { // Register file as changed file and do not copy semantic diagnostics, since all changed files need to be re-evaluated state.changedFilesSet.add(sourceFilePath); } else if (canCopySemanticDiagnostics) { const sourceFile = newProgram.getSourceFileByPath(sourceFilePath)!; - if (sourceFile.isDeclarationFile && !copyDeclarationFileDiagnostics) return; - if (sourceFile.hasNoDefaultLib && !copyLibFileDiagnostics) return; + if (sourceFile.isDeclarationFile && !copyDeclarationFileDiagnostics) + return; + if (sourceFile.hasNoDefaultLib && !copyLibFileDiagnostics) + return; // Unchanged file copy diagnostics const diagnostics = oldState!.semanticDiagnosticsPerFile!.get(sourceFilePath); if (diagnostics) { - state.semanticDiagnosticsPerFile!.set(sourceFilePath, oldState!.hasReusableDiagnostic ? convertToDiagnostics(diagnostics as readonly ReusableDiagnostic[], newProgram, getCanonicalFileName) : diagnostics as readonly Diagnostic[]); + state.semanticDiagnosticsPerFile!.set(sourceFilePath, oldState!.hasReusableDiagnostic ? convertToDiagnostics(diagnostics as readonly ReusableDiagnostic[], newProgram, getCanonicalFileName) : diagnostics as readonly ts.Diagnostic[]); if (!state.semanticDiagnosticsFromOldState) { - state.semanticDiagnosticsFromOldState = new Set(); + state.semanticDiagnosticsFromOldState = new ts.Set(); } state.semanticDiagnosticsFromOldState.add(sourceFilePath); } @@ -250,19 +250,19 @@ namespace ts { }); // If the global file is removed, add all files as changed - if (useOldState && forEachEntry(oldState!.fileInfos, (info, sourceFilePath) => info.affectsGlobalScope && !state.fileInfos.has(sourceFilePath))) { - BuilderState.getAllFilesExcludingDefaultLibraryFile(state, newProgram, /*firstSourceFile*/ undefined) + if (useOldState && ts.forEachEntry(oldState!.fileInfos, (info, sourceFilePath) => info.affectsGlobalScope && !state.fileInfos.has(sourceFilePath))) { + ts.BuilderState.getAllFilesExcludingDefaultLibraryFile(state, newProgram, /*firstSourceFile*/ undefined) .forEach(file => state.changedFilesSet.add(file.resolvedPath)); } - else if (oldCompilerOptions && !outFile(compilerOptions) && compilerOptionsAffectEmit(compilerOptions, oldCompilerOptions)) { + else if (oldCompilerOptions && !ts.outFile(compilerOptions) && ts.compilerOptionsAffectEmit(compilerOptions, oldCompilerOptions)) { // Add all files to affectedFilesPendingEmit since emit changed newProgram.getSourceFiles().forEach(f => addToAffectedFilesPendingEmit(state, f.resolvedPath, BuilderFileEmit.Full)); - Debug.assert(!state.seenAffectedFiles || !state.seenAffectedFiles.size); - state.seenAffectedFiles = state.seenAffectedFiles || new Set(); + ts.Debug.assert(!state.seenAffectedFiles || !state.seenAffectedFiles.size); + state.seenAffectedFiles = state.seenAffectedFiles || new ts.Set(); } if (useOldState) { // Any time the interpretation of a source file changes, mark it as changed - forEachEntry(oldState!.fileInfos, (info, sourceFilePath) => { + ts.forEachEntry(oldState!.fileInfos, (info, sourceFilePath) => { if (state.fileInfos.has(sourceFilePath) && state.fileInfos.get(sourceFilePath)!.impliedFormat !== info.impliedFormat) { state.changedFilesSet.add(sourceFilePath); } @@ -273,11 +273,12 @@ namespace ts { return state; } - function convertToDiagnostics(diagnostics: readonly ReusableDiagnostic[], newProgram: Program, getCanonicalFileName: GetCanonicalFileName): readonly Diagnostic[] { - if (!diagnostics.length) return emptyArray; - const buildInfoDirectory = getDirectoryPath(getNormalizedAbsolutePath(getTsBuildInfoEmitOutputFilePath(newProgram.getCompilerOptions())!, newProgram.getCurrentDirectory())); + function convertToDiagnostics(diagnostics: readonly ReusableDiagnostic[], newProgram: ts.Program, getCanonicalFileName: ts.GetCanonicalFileName): readonly ts.Diagnostic[] { + if (!diagnostics.length) + return ts.emptyArray; + const buildInfoDirectory = ts.getDirectoryPath(ts.getNormalizedAbsolutePath(ts.getTsBuildInfoEmitOutputFilePath(newProgram.getCompilerOptions())!, newProgram.getCurrentDirectory())); return diagnostics.map(diagnostic => { - const result: Diagnostic = convertToDiagnosticRelatedInformation(diagnostic, newProgram, toPath); + const result: ts.Diagnostic = convertToDiagnosticRelatedInformation(diagnostic, newProgram, toPath); result.reportsUnnecessary = diagnostic.reportsUnnecessary; result.reportsDeprecated = diagnostic.reportDeprecated; result.source = diagnostic.source; @@ -296,7 +297,7 @@ namespace ts { } } - function convertToDiagnosticRelatedInformation(diagnostic: ReusableDiagnosticRelatedInformation, newProgram: Program, toPath: (path: string) => Path): DiagnosticRelatedInformation { + function convertToDiagnosticRelatedInformation(diagnostic: ReusableDiagnosticRelatedInformation, newProgram: ts.Program, toPath: (path: string) => ts.Path): ts.DiagnosticRelatedInformation { const { file } = diagnostic; return { ...diagnostic, @@ -308,7 +309,7 @@ namespace ts { * Releases program and other related not needed properties */ function releaseCache(state: BuilderProgramState) { - BuilderState.releaseCache(state); + ts.BuilderState.releaseCache(state); state.program = undefined; } @@ -316,23 +317,23 @@ namespace ts { * Creates a clone of the state */ function cloneBuilderProgramState(state: Readonly): BuilderProgramState { - const newState = BuilderState.clone(state) as BuilderProgramState; - newState.semanticDiagnosticsPerFile = state.semanticDiagnosticsPerFile && new Map(state.semanticDiagnosticsPerFile); - newState.changedFilesSet = new Set(state.changedFilesSet); + const newState = ts.BuilderState.clone(state) as BuilderProgramState; + newState.semanticDiagnosticsPerFile = state.semanticDiagnosticsPerFile && new ts.Map(state.semanticDiagnosticsPerFile); + newState.changedFilesSet = new ts.Set(state.changedFilesSet); newState.affectedFiles = state.affectedFiles; newState.affectedFilesIndex = state.affectedFilesIndex; newState.currentChangedFilePath = state.currentChangedFilePath; - newState.currentAffectedFilesSignatures = state.currentAffectedFilesSignatures && new Map(state.currentAffectedFilesSignatures); + newState.currentAffectedFilesSignatures = state.currentAffectedFilesSignatures && new ts.Map(state.currentAffectedFilesSignatures); newState.currentAffectedFilesExportedModulesMap = state.currentAffectedFilesExportedModulesMap?.clone(); - newState.seenAffectedFiles = state.seenAffectedFiles && new Set(state.seenAffectedFiles); + newState.seenAffectedFiles = state.seenAffectedFiles && new ts.Set(state.seenAffectedFiles); newState.cleanedDiagnosticsOfLibFiles = state.cleanedDiagnosticsOfLibFiles; - newState.semanticDiagnosticsFromOldState = state.semanticDiagnosticsFromOldState && new Set(state.semanticDiagnosticsFromOldState); + newState.semanticDiagnosticsFromOldState = state.semanticDiagnosticsFromOldState && new ts.Set(state.semanticDiagnosticsFromOldState); newState.program = state.program; newState.compilerOptions = state.compilerOptions; newState.affectedFilesPendingEmit = state.affectedFilesPendingEmit && state.affectedFilesPendingEmit.slice(); - newState.affectedFilesPendingEmitKind = state.affectedFilesPendingEmitKind && new Map(state.affectedFilesPendingEmitKind); + newState.affectedFilesPendingEmitKind = state.affectedFilesPendingEmitKind && new ts.Map(state.affectedFilesPendingEmitKind); newState.affectedFilesPendingEmitIndex = state.affectedFilesPendingEmitIndex; - newState.seenEmittedFiles = state.seenEmittedFiles && new Map(state.seenEmittedFiles); + newState.seenEmittedFiles = state.seenEmittedFiles && new ts.Map(state.seenEmittedFiles); newState.programEmitComplete = state.programEmitComplete; return newState; } @@ -340,8 +341,8 @@ namespace ts { /** * Verifies that source file is ok to be used in calls that arent handled by next */ - function assertSourceFileOkWithoutNextAffectedCall(state: BuilderProgramState, sourceFile: SourceFile | undefined) { - Debug.assert(!sourceFile || !state.affectedFiles || state.affectedFiles[state.affectedFilesIndex! - 1] !== sourceFile || !state.semanticDiagnosticsPerFile!.has(sourceFile.resolvedPath)); + function assertSourceFileOkWithoutNextAffectedCall(state: BuilderProgramState, sourceFile: ts.SourceFile | undefined) { + ts.Debug.assert(!sourceFile || !state.affectedFiles || state.affectedFiles[state.affectedFilesIndex! - 1] !== sourceFile || !state.semanticDiagnosticsPerFile!.has(sourceFile.resolvedPath)); } /** @@ -350,7 +351,7 @@ namespace ts { * This is to allow the callers to be able to actually remove affected file only when the operation is complete * eg. if during diagnostics check cancellation token ends up cancelling the request, the affected file should be retained */ - function getNextAffectedFile(state: BuilderProgramState, cancellationToken: CancellationToken | undefined, computeHash: BuilderState.ComputeHash, host: BuilderProgramHost): SourceFile | Program | undefined { + function getNextAffectedFile(state: BuilderProgramState, cancellationToken: ts.CancellationToken | undefined, computeHash: ts.BuilderState.ComputeHash, host: ts.BuilderProgramHost): ts.SourceFile | ts.Program | undefined { while (true) { const { affectedFiles } = state; if (affectedFiles) { @@ -371,9 +372,9 @@ namespace ts { state.changedFilesSet.delete(state.currentChangedFilePath!); state.currentChangedFilePath = undefined; // Commit the changes in file signature - BuilderState.updateSignaturesFromCache(state, state.currentAffectedFilesSignatures!); + ts.BuilderState.updateSignaturesFromCache(state, state.currentAffectedFilesSignatures!); state.currentAffectedFilesSignatures!.clear(); - BuilderState.updateExportedFilesMapFromCache(state, state.currentAffectedFilesExportedModulesMap); + ts.BuilderState.updateExportedFilesMapFromCache(state, state.currentAffectedFilesExportedModulesMap); state.currentAffectedFilesExportedModulesMap?.clear(); state.affectedFiles = undefined; } @@ -387,22 +388,24 @@ namespace ts { // With --out or --outFile all outputs go into single file // so operations are performed directly on program, return program - const program = Debug.checkDefined(state.program); + const program = ts.Debug.checkDefined(state.program); const compilerOptions = program.getCompilerOptions(); - if (outFile(compilerOptions)) { - Debug.assert(!state.semanticDiagnosticsPerFile); + if (ts.outFile(compilerOptions)) { + ts.Debug.assert(!state.semanticDiagnosticsPerFile); return program; } // Get next batch of affected files - if (!state.currentAffectedFilesSignatures) state.currentAffectedFilesSignatures = new Map(); + if (!state.currentAffectedFilesSignatures) + state.currentAffectedFilesSignatures = new ts.Map(); if (state.exportedModulesMap) { - state.currentAffectedFilesExportedModulesMap ||= BuilderState.createManyToManyPathMap(); + state.currentAffectedFilesExportedModulesMap ||= ts.BuilderState.createManyToManyPathMap(); } - state.affectedFiles = BuilderState.getFilesAffectedBy(state, program, nextKey.value, cancellationToken, computeHash, state.currentAffectedFilesSignatures, state.currentAffectedFilesExportedModulesMap); + state.affectedFiles = ts.BuilderState.getFilesAffectedBy(state, program, nextKey.value, cancellationToken, computeHash, state.currentAffectedFilesSignatures, state.currentAffectedFilesExportedModulesMap); state.currentChangedFilePath = nextKey.value; state.affectedFilesIndex = 0; - if (!state.seenAffectedFiles) state.seenAffectedFiles = new Set(); + if (!state.seenAffectedFiles) + state.seenAffectedFiles = new ts.Set(); } } @@ -418,12 +421,12 @@ namespace ts { function getNextAffectedFilePendingEmit(state: BuilderProgramState) { const { affectedFilesPendingEmit } = state; if (affectedFilesPendingEmit) { - const seenEmittedFiles = (state.seenEmittedFiles || (state.seenEmittedFiles = new Map())); + const seenEmittedFiles = (state.seenEmittedFiles || (state.seenEmittedFiles = new ts.Map())); for (let i = state.affectedFilesPendingEmitIndex!; i < affectedFilesPendingEmit.length; i++) { - const affectedFile = Debug.checkDefined(state.program).getSourceFileByPath(affectedFilesPendingEmit[i]); + const affectedFile = ts.Debug.checkDefined(state.program).getSourceFileByPath(affectedFilesPendingEmit[i]); if (affectedFile) { const seenKind = seenEmittedFiles.get(affectedFile.resolvedPath); - const emitKind = Debug.checkDefined(Debug.checkDefined(state.affectedFilesPendingEmitKind).get(affectedFile.resolvedPath)); + const emitKind = ts.Debug.checkDefined(ts.Debug.checkDefined(state.affectedFilesPendingEmitKind).get(affectedFile.resolvedPath)); if (seenKind === undefined || seenKind < emitKind) { // emit this file state.affectedFilesPendingEmitIndex = i; @@ -439,13 +442,11 @@ namespace ts { function removeDiagnosticsOfLibraryFiles(state: BuilderProgramState) { if (!state.cleanedDiagnosticsOfLibFiles) { state.cleanedDiagnosticsOfLibFiles = true; - const program = Debug.checkDefined(state.program); + const program = ts.Debug.checkDefined(state.program); const options = program.getCompilerOptions(); - forEach(program.getSourceFiles(), f => - program.isSourceFileDefaultLibrary(f) && - !skipTypeChecking(f, options, program) && - removeSemanticDiagnosticsOf(state, f.resolvedPath) - ); + ts.forEach(program.getSourceFiles(), f => program.isSourceFileDefaultLibrary(f) && + !ts.skipTypeChecking(f, options, program) && + removeSemanticDiagnosticsOf(state, f.resolvedPath)); } } @@ -453,13 +454,7 @@ namespace ts { * Handles semantic diagnostics and dts emit for affectedFile and files, that are referencing modules that export entities from affected file * This is because even though js emit doesnt change, dts emit / type used can change resulting in need for dts emit and js change */ - function handleDtsMayChangeOfAffectedFile( - state: BuilderProgramState, - affectedFile: SourceFile, - cancellationToken: CancellationToken | undefined, - computeHash: BuilderState.ComputeHash, - host: BuilderProgramHost, - ) { + function handleDtsMayChangeOfAffectedFile(state: BuilderProgramState, affectedFile: ts.SourceFile, cancellationToken: ts.CancellationToken | undefined, computeHash: ts.BuilderState.ComputeHash, host: ts.BuilderProgramHost) { removeSemanticDiagnosticsOf(state, affectedFile.resolvedPath); // If affected files is everything except default library, then nothing more to do @@ -468,19 +463,12 @@ namespace ts { // When a change affects the global scope, all files are considered to be affected without updating their signature // That means when affected file is handled, its signature can be out of date // To avoid this, ensure that we update the signature for any affected file in this scenario. - BuilderState.updateShapeSignature( - state, - Debug.checkDefined(state.program), - affectedFile, - Debug.checkDefined(state.currentAffectedFilesSignatures), - cancellationToken, - computeHash, - state.currentAffectedFilesExportedModulesMap - ); + ts.BuilderState.updateShapeSignature(state, ts.Debug.checkDefined(state.program), affectedFile, ts.Debug.checkDefined(state.currentAffectedFilesSignatures), cancellationToken, computeHash, state.currentAffectedFilesExportedModulesMap); return; } - Debug.assert(state.hasCalledUpdateShapeSignature.has(affectedFile.resolvedPath) || state.currentAffectedFilesSignatures?.has(affectedFile.resolvedPath), `Signature not updated for affected file: ${affectedFile.fileName}`); - if (state.compilerOptions.assumeChangesOnlyAffectDirectDependencies) return; + ts.Debug.assert(state.hasCalledUpdateShapeSignature.has(affectedFile.resolvedPath) || state.currentAffectedFilesSignatures?.has(affectedFile.resolvedPath), `Signature not updated for affected file: ${affectedFile.fileName}`); + if (state.compilerOptions.assumeChangesOnlyAffectDirectDependencies) + return; handleDtsMayChangeOfReferencingExportOfAffectedFile(state, affectedFile, cancellationToken, computeHash, host); } @@ -488,17 +476,11 @@ namespace ts { * Handle the dts may change, so they need to be added to pending emit if dts emit is enabled, * Also we need to make sure signature is updated for these files */ - function handleDtsMayChangeOf( - state: BuilderProgramState, - path: Path, - cancellationToken: CancellationToken | undefined, - computeHash: BuilderState.ComputeHash, - host: BuilderProgramHost - ): void { + function handleDtsMayChangeOf(state: BuilderProgramState, path: ts.Path, cancellationToken: ts.CancellationToken | undefined, computeHash: ts.BuilderState.ComputeHash, host: ts.BuilderProgramHost): void { removeSemanticDiagnosticsOf(state, path); if (!state.changedFilesSet.has(path)) { - const program = Debug.checkDefined(state.program); + const program = ts.Debug.checkDefined(state.program); const sourceFile = program.getSourceFileByPath(path); if (sourceFile) { // Even though the js emit doesnt change and we are already handling dts emit and semantic diagnostics @@ -506,18 +488,9 @@ namespace ts { // This ensures that we dont later during incremental builds considering wrong signature. // Eg where this also is needed to ensure that .tsbuildinfo generated by incremental build should be same as if it was first fresh build // But we avoid expensive full shape computation, as using file version as shape is enough for correctness. - BuilderState.updateShapeSignature( - state, - program, - sourceFile, - Debug.checkDefined(state.currentAffectedFilesSignatures), - cancellationToken, - computeHash, - state.currentAffectedFilesExportedModulesMap, - !host.disableUseFileVersionAsSignature - ); + ts.BuilderState.updateShapeSignature(state, program, sourceFile, ts.Debug.checkDefined(state.currentAffectedFilesSignatures), cancellationToken, computeHash, state.currentAffectedFilesExportedModulesMap, !host.disableUseFileVersionAsSignature); // If not dts emit, nothing more to do - if (getEmitDeclarations(state.compilerOptions)) { + if (ts.getEmitDeclarations(state.compilerOptions)) { addToAffectedFilesPendingEmit(state, path, BuilderFileEmit.DtsOnly); } } @@ -528,7 +501,7 @@ namespace ts { * Removes semantic diagnostics for path and * returns true if there are no more semantic diagnostics from the old state */ - function removeSemanticDiagnosticsOf(state: BuilderProgramState, path: Path) { + function removeSemanticDiagnosticsOf(state: BuilderProgramState, path: ts.Path) { if (!state.semanticDiagnosticsFromOldState) { return true; } @@ -537,50 +510,34 @@ namespace ts { return !state.semanticDiagnosticsFromOldState.size; } - function isChangedSignature(state: BuilderProgramState, path: Path) { - const newSignature = Debug.checkDefined(state.currentAffectedFilesSignatures).get(path); - const oldSignature = Debug.checkDefined(state.fileInfos.get(path)).signature; + function isChangedSignature(state: BuilderProgramState, path: ts.Path) { + const newSignature = ts.Debug.checkDefined(state.currentAffectedFilesSignatures).get(path); + const oldSignature = ts.Debug.checkDefined(state.fileInfos.get(path)).signature; return newSignature !== oldSignature; } - function forEachKeyOfExportedModulesMap( - state: BuilderProgramState, - filePath: Path, - fn: (exportedFromPath: Path) => T | undefined, - ): T | undefined { + function forEachKeyOfExportedModulesMap(state: BuilderProgramState, filePath: ts.Path, fn: (exportedFromPath: ts.Path) => T | undefined): T | undefined { // Go through exported modules from cache first let keys = state.currentAffectedFilesExportedModulesMap!.getKeys(filePath); - const result = keys && forEachKey(keys, fn); - if (result) return result; + const result = keys && ts.forEachKey(keys, fn); + if (result) + return result; // If exported from path is not from cache and exported modules has path, all files referencing file exported from are affected keys = state.exportedModulesMap!.getKeys(filePath); - return keys && forEachKey(keys, exportedFromPath => + return keys && ts.forEachKey(keys, exportedFromPath => // If the cache had an updated value, skip !state.currentAffectedFilesExportedModulesMap!.hasKey(exportedFromPath) && !state.currentAffectedFilesExportedModulesMap!.deletedKeys()?.has(exportedFromPath) ? fn(exportedFromPath) : - undefined - ); + undefined); } - - function handleDtsMayChangeOfGlobalScope( - state: BuilderProgramState, - filePath: Path, - cancellationToken: CancellationToken | undefined, - computeHash: BuilderState.ComputeHash, - host: BuilderProgramHost, - ): boolean { - if (!state.fileInfos.get(filePath)?.affectsGlobalScope) return false; + function handleDtsMayChangeOfGlobalScope(state: BuilderProgramState, filePath: ts.Path, cancellationToken: ts.CancellationToken | undefined, computeHash: ts.BuilderState.ComputeHash, host: ts.BuilderProgramHost): boolean { + if (!state.fileInfos.get(filePath)?.affectsGlobalScope) + return false; // Every file needs to be handled - BuilderState.getAllFilesExcludingDefaultLibraryFile(state, state.program!, /*firstSourceFile*/ undefined) - .forEach(file => handleDtsMayChangeOf( - state, - file.resolvedPath, - cancellationToken, - computeHash, - host, - )); + ts.BuilderState.getAllFilesExcludingDefaultLibraryFile(state, state.program!, /*firstSourceFile*/ undefined) + .forEach(file => handleDtsMayChangeOf(state, file.resolvedPath, cancellationToken, computeHash, host)); removeDiagnosticsOfLibraryFiles(state); return true; } @@ -588,55 +545,44 @@ namespace ts { /** * Iterate on referencing modules that export entities from affected file and delete diagnostics and add pending emit */ - function handleDtsMayChangeOfReferencingExportOfAffectedFile( - state: BuilderProgramState, - affectedFile: SourceFile, - cancellationToken: CancellationToken | undefined, - computeHash: BuilderState.ComputeHash, - host: BuilderProgramHost - ) { + function handleDtsMayChangeOfReferencingExportOfAffectedFile(state: BuilderProgramState, affectedFile: ts.SourceFile, cancellationToken: ts.CancellationToken | undefined, computeHash: ts.BuilderState.ComputeHash, host: ts.BuilderProgramHost) { // If there was change in signature (dts output) for the changed file, // then only we need to handle pending file emit - if (!state.exportedModulesMap || !state.changedFilesSet.has(affectedFile.resolvedPath)) return; - if (!isChangedSignature(state, affectedFile.resolvedPath)) return; + if (!state.exportedModulesMap || !state.changedFilesSet.has(affectedFile.resolvedPath)) + return; + if (!isChangedSignature(state, affectedFile.resolvedPath)) + return; // Since isolated modules dont change js files, files affected by change in signature is itself // But we need to cleanup semantic diagnostics and queue dts emit for affected files if (state.compilerOptions.isolatedModules) { - const seenFileNamesMap = new Map(); + const seenFileNamesMap = new ts.Map(); seenFileNamesMap.set(affectedFile.resolvedPath, true); - const queue = BuilderState.getReferencedByPaths(state, affectedFile.resolvedPath); + const queue = ts.BuilderState.getReferencedByPaths(state, affectedFile.resolvedPath); while (queue.length > 0) { const currentPath = queue.pop()!; if (!seenFileNamesMap.has(currentPath)) { seenFileNamesMap.set(currentPath, true); - if (handleDtsMayChangeOfGlobalScope(state, currentPath, cancellationToken, computeHash, host)) return; + if (handleDtsMayChangeOfGlobalScope(state, currentPath, cancellationToken, computeHash, host)) + return; handleDtsMayChangeOf(state, currentPath, cancellationToken, computeHash, host); if (isChangedSignature(state, currentPath)) { - const currentSourceFile = Debug.checkDefined(state.program).getSourceFileByPath(currentPath)!; - queue.push(...BuilderState.getReferencedByPaths(state, currentSourceFile.resolvedPath)); + const currentSourceFile = ts.Debug.checkDefined(state.program).getSourceFileByPath(currentPath)!; + queue.push(...ts.BuilderState.getReferencedByPaths(state, currentSourceFile.resolvedPath)); } } } } - Debug.assert(!!state.currentAffectedFilesExportedModulesMap); - const seenFileAndExportsOfFile = new Set(); + ts.Debug.assert(!!state.currentAffectedFilesExportedModulesMap); + const seenFileAndExportsOfFile = new ts.Set(); // Go through exported modules from cache first // If exported modules has path, all files referencing file exported from are affected forEachKeyOfExportedModulesMap(state, affectedFile.resolvedPath, exportedFromPath => { - if (handleDtsMayChangeOfGlobalScope(state, exportedFromPath, cancellationToken, computeHash, host)) return true; + if (handleDtsMayChangeOfGlobalScope(state, exportedFromPath, cancellationToken, computeHash, host)) + return true; const references = state.referencedMap!.getKeys(exportedFromPath); - return references && forEachKey(references, filePath => - handleDtsMayChangeOfFileAndExportsOfFile( - state, - filePath, - seenFileAndExportsOfFile, - cancellationToken, - computeHash, - host, - ) - ); + return references && ts.forEachKey(references, filePath => handleDtsMayChangeOfFileAndExportsOfFile(state, filePath, seenFileAndExportsOfFile, cancellationToken, computeHash, host)); }); } @@ -644,43 +590,21 @@ namespace ts { * handle dts and semantic diagnostics on file and iterate on anything that exports this file * return true when all work is done and we can exit handling dts emit and semantic diagnostics */ - function handleDtsMayChangeOfFileAndExportsOfFile( - state: BuilderProgramState, - filePath: Path, - seenFileAndExportsOfFile: Set, - cancellationToken: CancellationToken | undefined, - computeHash: BuilderState.ComputeHash, - host: BuilderProgramHost, - ): boolean | undefined { - if (!tryAddToSet(seenFileAndExportsOfFile, filePath)) return undefined; - - if (handleDtsMayChangeOfGlobalScope(state, filePath, cancellationToken, computeHash, host)) return true; + function handleDtsMayChangeOfFileAndExportsOfFile(state: BuilderProgramState, filePath: ts.Path, seenFileAndExportsOfFile: ts.Set, cancellationToken: ts.CancellationToken | undefined, computeHash: ts.BuilderState.ComputeHash, host: ts.BuilderProgramHost): boolean | undefined { + if (!ts.tryAddToSet(seenFileAndExportsOfFile, filePath)) + return undefined; + if (handleDtsMayChangeOfGlobalScope(state, filePath, cancellationToken, computeHash, host)) + return true; handleDtsMayChangeOf(state, filePath, cancellationToken, computeHash, host); - Debug.assert(!!state.currentAffectedFilesExportedModulesMap); + ts.Debug.assert(!!state.currentAffectedFilesExportedModulesMap); // If exported modules has path, all files referencing file exported from are affected - forEachKeyOfExportedModulesMap(state, filePath, exportedFromPath => - handleDtsMayChangeOfFileAndExportsOfFile( - state, - exportedFromPath, - seenFileAndExportsOfFile, - cancellationToken, - computeHash, - host, - ) - ); + forEachKeyOfExportedModulesMap(state, filePath, exportedFromPath => handleDtsMayChangeOfFileAndExportsOfFile(state, exportedFromPath, seenFileAndExportsOfFile, cancellationToken, computeHash, host)); // Remove diagnostics of files that import this file (without going to exports of referencing files) - state.referencedMap!.getKeys(filePath)?.forEach(referencingFilePath => - !seenFileAndExportsOfFile.has(referencingFilePath) && // Not already removed diagnostic file + state.referencedMap!.getKeys(filePath)?.forEach(referencingFilePath => !seenFileAndExportsOfFile.has(referencingFilePath) && // Not already removed diagnostic file handleDtsMayChangeOf( // Dont add to seen since this is not yet done with the export removal - state, - referencingFilePath, - cancellationToken, - computeHash, - host, - ) - ); + state, referencingFilePath, cancellationToken, computeHash, host)); return undefined; } @@ -688,13 +612,7 @@ namespace ts { * This is called after completing operation on the next affected file. * The operations here are postponed to ensure that cancellation during the iteration is handled correctly */ - function doneWithAffectedFile( - state: BuilderProgramState, - affected: SourceFile | Program, - emitKind?: BuilderFileEmit, - isPendingEmit?: boolean, - isBuildInfoEmit?: boolean - ) { + function doneWithAffectedFile(state: BuilderProgramState, affected: ts.SourceFile | ts.Program, emitKind?: BuilderFileEmit, isPendingEmit?: boolean, isBuildInfoEmit?: boolean) { if (isBuildInfoEmit) { state.buildInfoEmitPending = false; } @@ -703,9 +621,9 @@ namespace ts { state.programEmitComplete = true; } else { - state.seenAffectedFiles!.add((affected as SourceFile).resolvedPath); + state.seenAffectedFiles!.add((affected as ts.SourceFile).resolvedPath); if (emitKind !== undefined) { - (state.seenEmittedFiles || (state.seenEmittedFiles = new Map())).set((affected as SourceFile).resolvedPath, emitKind); + (state.seenEmittedFiles || (state.seenEmittedFiles = new ts.Map())).set((affected as ts.SourceFile).resolvedPath, emitKind); } if (isPendingEmit) { state.affectedFilesPendingEmitIndex!++; @@ -720,7 +638,7 @@ namespace ts { /** * Returns the result with affected file */ - function toAffectedFileResult(state: BuilderProgramState, result: T, affected: SourceFile | Program): AffectedFileResult { + function toAffectedFileResult(state: BuilderProgramState, result: T, affected: ts.SourceFile | ts.Program): ts.AffectedFileResult { doneWithAffectedFile(state, affected); return { result, affected }; } @@ -728,14 +646,7 @@ namespace ts { /** * Returns the result with affected file */ - function toAffectedFileEmitResult( - state: BuilderProgramState, - result: EmitResult, - affected: SourceFile | Program, - emitKind: BuilderFileEmit, - isPendingEmit?: boolean, - isBuildInfoEmit?: boolean - ): AffectedFileResult { + function toAffectedFileEmitResult(state: BuilderProgramState, result: ts.EmitResult, affected: ts.SourceFile | ts.Program, emitKind: BuilderFileEmit, isPendingEmit?: boolean, isBuildInfoEmit?: boolean): ts.AffectedFileResult { doneWithAffectedFile(state, affected, emitKind, isPendingEmit, isBuildInfoEmit); return { result, affected }; } @@ -744,41 +655,51 @@ namespace ts { * Gets semantic diagnostics for the file which are * bindAndCheckDiagnostics (from cache) and program diagnostics */ - function getSemanticDiagnosticsOfFile(state: BuilderProgramState, sourceFile: SourceFile, cancellationToken?: CancellationToken): readonly Diagnostic[] { - return concatenate( - getBinderAndCheckerDiagnosticsOfFile(state, sourceFile, cancellationToken), - Debug.checkDefined(state.program).getProgramDiagnostics(sourceFile) - ); + function getSemanticDiagnosticsOfFile(state: BuilderProgramState, sourceFile: ts.SourceFile, cancellationToken?: ts.CancellationToken): readonly ts.Diagnostic[] { + return ts.concatenate(getBinderAndCheckerDiagnosticsOfFile(state, sourceFile, cancellationToken), ts.Debug.checkDefined(state.program).getProgramDiagnostics(sourceFile)); } /** * Gets the binder and checker diagnostics either from cache if present, or otherwise from program and caches it * Note that it is assumed that when asked about binder and checker diagnostics, the file has been taken out of affected files/changed file set */ - function getBinderAndCheckerDiagnosticsOfFile(state: BuilderProgramState, sourceFile: SourceFile, cancellationToken?: CancellationToken): readonly Diagnostic[] { + function getBinderAndCheckerDiagnosticsOfFile(state: BuilderProgramState, sourceFile: ts.SourceFile, cancellationToken?: ts.CancellationToken): readonly ts.Diagnostic[] { const path = sourceFile.resolvedPath; if (state.semanticDiagnosticsPerFile) { const cachedDiagnostics = state.semanticDiagnosticsPerFile.get(path); // Report the bind and check diagnostics from the cache if we already have those diagnostics present if (cachedDiagnostics) { - return filterSemanticDiagnostics(cachedDiagnostics, state.compilerOptions); + return ts.filterSemanticDiagnostics(cachedDiagnostics, state.compilerOptions); } } // Diagnostics werent cached, get them from program, and cache the result - const diagnostics = Debug.checkDefined(state.program).getBindAndCheckDiagnostics(sourceFile, cancellationToken); + const diagnostics = ts.Debug.checkDefined(state.program).getBindAndCheckDiagnostics(sourceFile, cancellationToken); if (state.semanticDiagnosticsPerFile) { state.semanticDiagnosticsPerFile.set(path, diagnostics); } - return filterSemanticDiagnostics(diagnostics, state.compilerOptions); + return ts.filterSemanticDiagnostics(diagnostics, state.compilerOptions); } - export type ProgramBuildInfoFileId = number & { __programBuildInfoFileIdBrand: any }; - export type ProgramBuildInfoFileIdListId = number & { __programBuildInfoFileIdListIdBrand: any }; - export type ProgramBuildInfoDiagnostic = ProgramBuildInfoFileId | [fileId: ProgramBuildInfoFileId, diagnostics: readonly ReusableDiagnostic[]]; - export type ProgramBuilderInfoFilePendingEmit = [fileId: ProgramBuildInfoFileId, emitKind: BuilderFileEmit]; - export type ProgramBuildInfoReferencedMap = [fileId: ProgramBuildInfoFileId, fileIdListId: ProgramBuildInfoFileIdListId][]; - export type ProgramBuildInfoBuilderStateFileInfo = Omit & { + export type ProgramBuildInfoFileId = number & { + __programBuildInfoFileIdBrand: any; + }; + export type ProgramBuildInfoFileIdListId = number & { + __programBuildInfoFileIdListIdBrand: any; + }; + export type ProgramBuildInfoDiagnostic = ProgramBuildInfoFileId | [ + fileId: ProgramBuildInfoFileId, + diagnostics: readonly ReusableDiagnostic[] + ]; + export type ProgramBuilderInfoFilePendingEmit = [ + fileId: ProgramBuildInfoFileId, + emitKind: BuilderFileEmit + ]; + export type ProgramBuildInfoReferencedMap = [ + fileId: ProgramBuildInfoFileId, + fileIdListId: ProgramBuildInfoFileIdListId + ][]; + export type ProgramBuildInfoBuilderStateFileInfo = Omit & { /** * Signature is * - undefined if FileInfo.version === FileInfo.signature @@ -794,7 +715,7 @@ namespace ts { export interface ProgramBuildInfo { fileNames: readonly string[]; fileInfos: readonly ProgramBuildInfoFileInfo[]; - options: CompilerOptions | undefined; + options: ts.CompilerOptions | undefined; fileIdsList?: readonly (readonly ProgramBuildInfoFileId[])[]; referencedMap?: ProgramBuildInfoReferencedMap; exportedModulesMap?: ProgramBuildInfoReferencedMap; @@ -805,18 +726,19 @@ namespace ts { /** * Gets the program information to be emitted in buildInfo so that we can use it to create new program */ - function getProgramBuildInfo(state: Readonly, getCanonicalFileName: GetCanonicalFileName): ProgramBuildInfo | undefined { - if (outFile(state.compilerOptions)) return undefined; - const currentDirectory = Debug.checkDefined(state.program).getCurrentDirectory(); - const buildInfoDirectory = getDirectoryPath(getNormalizedAbsolutePath(getTsBuildInfoEmitOutputFilePath(state.compilerOptions)!, currentDirectory)); + function getProgramBuildInfo(state: Readonly, getCanonicalFileName: ts.GetCanonicalFileName): ProgramBuildInfo | undefined { + if (ts.outFile(state.compilerOptions)) + return undefined; + const currentDirectory = ts.Debug.checkDefined(state.program).getCurrentDirectory(); + const buildInfoDirectory = ts.getDirectoryPath(ts.getNormalizedAbsolutePath(ts.getTsBuildInfoEmitOutputFilePath(state.compilerOptions)!, currentDirectory)); const fileNames: string[] = []; - const fileNameToFileId = new Map(); + const fileNameToFileId = new ts.Map(); let fileIdsList: (readonly ProgramBuildInfoFileId[])[] | undefined; - let fileNamesToFileIdListId: ESMap | undefined; - const fileInfos = arrayFrom(state.fileInfos.entries(), ([key, value]): ProgramBuildInfoFileInfo => { + let fileNamesToFileIdListId: ts.ESMap | undefined; + const fileInfos = ts.arrayFrom(state.fileInfos.entries(), ([key, value]): ProgramBuildInfoFileInfo => { // Ensure fileId const fileId = toFileId(key); - Debug.assert(fileNames[fileId - 1] === relativeToBuildInfo(key)); + ts.Debug.assert(fileNames[fileId - 1] === relativeToBuildInfo(key)); const signature = state.currentAffectedFilesSignatures && state.currentAffectedFilesSignatures.get(key); const actualSignature = signature ?? value.signature; return value.version === actualSignature ? @@ -837,7 +759,7 @@ namespace ts { let referencedMap: ProgramBuildInfoReferencedMap | undefined; if (state.referencedMap) { - referencedMap = arrayFrom(state.referencedMap.keys()).sort(compareStringsCaseSensitive).map(key => [ + referencedMap = ts.arrayFrom(state.referencedMap.keys()).sort(ts.compareStringsCaseSensitive).map(key => [ toFileId(key), toFileIdListId(state.referencedMap!.getValues(key)!) ]); @@ -845,7 +767,7 @@ namespace ts { let exportedModulesMap: ProgramBuildInfoReferencedMap | undefined; if (state.exportedModulesMap) { - exportedModulesMap = mapDefined(arrayFrom(state.exportedModulesMap.keys()).sort(compareStringsCaseSensitive), key => { + exportedModulesMap = ts.mapDefined(ts.arrayFrom(state.exportedModulesMap.keys()).sort(ts.compareStringsCaseSensitive), key => { if (state.currentAffectedFilesExportedModulesMap) { if (state.currentAffectedFilesExportedModulesMap.deletedKeys()?.has(key)) { return undefined; @@ -864,26 +786,24 @@ namespace ts { let semanticDiagnosticsPerFile: ProgramBuildInfoDiagnostic[] | undefined; if (state.semanticDiagnosticsPerFile) { - for (const key of arrayFrom(state.semanticDiagnosticsPerFile.keys()).sort(compareStringsCaseSensitive)) { + for (const key of ts.arrayFrom(state.semanticDiagnosticsPerFile.keys()).sort(ts.compareStringsCaseSensitive)) { const value = state.semanticDiagnosticsPerFile.get(key)!; - (semanticDiagnosticsPerFile ||= []).push( - value.length ? + (semanticDiagnosticsPerFile ||= []).push(value.length ? [ toFileId(key), state.hasReusableDiagnostic ? value as readonly ReusableDiagnostic[] : - convertToReusableDiagnostics(value as readonly Diagnostic[], relativeToBuildInfo) + convertToReusableDiagnostics(value as readonly ts.Diagnostic[], relativeToBuildInfo) ] : - toFileId(key) - ); + toFileId(key)); } } let affectedFilesPendingEmit: ProgramBuilderInfoFilePendingEmit[] | undefined; if (state.affectedFilesPendingEmit) { - const seenFiles = new Set(); - for (const path of state.affectedFilesPendingEmit.slice(state.affectedFilesPendingEmitIndex).sort(compareStringsCaseSensitive)) { - if (tryAddToSet(seenFiles, path)) { + const seenFiles = new ts.Set(); + for (const path of state.affectedFilesPendingEmit.slice(state.affectedFilesPendingEmitIndex).sort(ts.compareStringsCaseSensitive)) { + if (ts.tryAddToSet(seenFiles, path)) { (affectedFilesPendingEmit ||= []).push([toFileId(path), state.affectedFilesPendingEmitKind!.get(path)!]); } } @@ -901,14 +821,14 @@ namespace ts { }; function relativeToBuildInfoEnsuringAbsolutePath(path: string) { - return relativeToBuildInfo(getNormalizedAbsolutePath(path, currentDirectory)); + return relativeToBuildInfo(ts.getNormalizedAbsolutePath(path, currentDirectory)); } function relativeToBuildInfo(path: string) { - return ensurePathIsNonModuleName(getRelativePathFromDirectory(buildInfoDirectory, path, getCanonicalFileName)); + return ts.ensurePathIsNonModuleName(ts.getRelativePathFromDirectory(buildInfoDirectory, path, getCanonicalFileName)); } - function toFileId(path: Path): ProgramBuildInfoFileId { + function toFileId(path: ts.Path): ProgramBuildInfoFileId { let fileId = fileNameToFileId.get(path); if (fileId === undefined) { fileNames.push(relativeToBuildInfo(path)); @@ -917,23 +837,22 @@ namespace ts { return fileId; } - function toFileIdListId(set: ReadonlySet): ProgramBuildInfoFileIdListId { - const fileIds = arrayFrom(set.keys(), toFileId).sort(compareValues); + function toFileIdListId(set: ts.ReadonlySet): ProgramBuildInfoFileIdListId { + const fileIds = ts.arrayFrom(set.keys(), toFileId).sort(ts.compareValues); const key = fileIds.join(); let fileIdListId = fileNamesToFileIdListId?.get(key); if (fileIdListId === undefined) { (fileIdsList ||= []).push(fileIds); - (fileNamesToFileIdListId ||= new Map()).set(key, fileIdListId = fileIdsList.length as ProgramBuildInfoFileIdListId); + (fileNamesToFileIdListId ||= new ts.Map()).set(key, fileIdListId = fileIdsList.length as ProgramBuildInfoFileIdListId); } return fileIdListId; } } - function convertToProgramBuildInfoCompilerOptions(options: CompilerOptions, relativeToBuildInfo: (path: string) => string) { - let result: CompilerOptions | undefined; - const { optionsNameMap } = getOptionsNameMap(); - - for (const name of getOwnKeys(options).sort(compareStringsCaseSensitive)) { + function convertToProgramBuildInfoCompilerOptions(options: ts.CompilerOptions, relativeToBuildInfo: (path: string) => string) { + let result: ts.CompilerOptions | undefined; + const { optionsNameMap } = ts.getOptionsNameMap(); + for (const name of ts.getOwnKeys(options).sort(ts.compareStringsCaseSensitive)) { const optionKey = name.toLowerCase(); const optionInfo = optionsNameMap.get(optionKey); if (optionInfo?.affectsEmit || optionInfo?.affectsSemanticDiagnostics || @@ -942,17 +861,13 @@ namespace ts { optionKey === "strict" || // We need to store these to determine whether `lib` files need to be rechecked. optionKey === "skiplibcheck" || optionKey === "skipdefaultlibcheck") { - (result ||= {})[name] = convertToReusableCompilerOptionValue( - optionInfo, - options[name] as CompilerOptionsValue, - relativeToBuildInfo - ); + (result ||= {})[name] = convertToReusableCompilerOptionValue(optionInfo, options[name] as ts.CompilerOptionsValue, relativeToBuildInfo); } } return result; } - function convertToReusableCompilerOptionValue(option: CommandLineOption | undefined, value: CompilerOptionsValue, relativeToBuildInfo: (path: string) => string) { + function convertToReusableCompilerOptionValue(option: ts.CommandLineOption | undefined, value: ts.CompilerOptionsValue, relativeToBuildInfo: (path: string) => string) { if (option) { if (option.type === "list") { const values = value as readonly (string | number)[]; @@ -967,8 +882,8 @@ namespace ts { return value; } - function convertToReusableDiagnostics(diagnostics: readonly Diagnostic[], relativeToBuildInfo: (path: string) => string): readonly ReusableDiagnostic[] { - Debug.assert(!!diagnostics.length); + function convertToReusableDiagnostics(diagnostics: readonly ts.Diagnostic[], relativeToBuildInfo: (path: string) => string): readonly ReusableDiagnostic[] { + ts.Debug.assert(!!diagnostics.length); return diagnostics.map(diagnostic => { const result: ReusableDiagnostic = convertToReusableDiagnosticRelatedInformation(diagnostic, relativeToBuildInfo); result.reportsUnnecessary = diagnostic.reportsUnnecessary; @@ -985,7 +900,7 @@ namespace ts { }); } - function convertToReusableDiagnosticRelatedInformation(diagnostic: DiagnosticRelatedInformation, relativeToBuildInfo: (path: string) => string): ReusableDiagnosticRelatedInformation { + function convertToReusableDiagnosticRelatedInformation(diagnostic: ts.DiagnosticRelatedInformation, relativeToBuildInfo: (path: string) => string): ReusableDiagnosticRelatedInformation { const { file } = diagnostic; return { ...diagnostic, @@ -999,46 +914,45 @@ namespace ts { } export interface BuilderCreationParameters { - newProgram: Program; - host: BuilderProgramHost; - oldProgram: BuilderProgram | undefined; - configFileParsingDiagnostics: readonly Diagnostic[]; + newProgram: ts.Program; + host: ts.BuilderProgramHost; + oldProgram: ts.BuilderProgram | undefined; + configFileParsingDiagnostics: readonly ts.Diagnostic[]; } - - export function getBuilderCreationParameters(newProgramOrRootNames: Program | readonly string[] | undefined, hostOrOptions: BuilderProgramHost | CompilerOptions | undefined, oldProgramOrHost?: BuilderProgram | CompilerHost, configFileParsingDiagnosticsOrOldProgram?: readonly Diagnostic[] | BuilderProgram, configFileParsingDiagnostics?: readonly Diagnostic[], projectReferences?: readonly ProjectReference[]): BuilderCreationParameters { - let host: BuilderProgramHost; - let newProgram: Program; - let oldProgram: BuilderProgram; + export function getBuilderCreationParameters(newProgramOrRootNames: ts.Program | readonly string[] | undefined, hostOrOptions: ts.BuilderProgramHost | ts.CompilerOptions | undefined, oldProgramOrHost?: ts.BuilderProgram | ts.CompilerHost, configFileParsingDiagnosticsOrOldProgram?: readonly ts.Diagnostic[] | ts.BuilderProgram, configFileParsingDiagnostics?: readonly ts.Diagnostic[], projectReferences?: readonly ts.ProjectReference[]): BuilderCreationParameters { + let host: ts.BuilderProgramHost; + let newProgram: ts.Program; + let oldProgram: ts.BuilderProgram; if (newProgramOrRootNames === undefined) { - Debug.assert(hostOrOptions === undefined); - host = oldProgramOrHost as CompilerHost; - oldProgram = configFileParsingDiagnosticsOrOldProgram as BuilderProgram; - Debug.assert(!!oldProgram); + ts.Debug.assert(hostOrOptions === undefined); + host = oldProgramOrHost as ts.CompilerHost; + oldProgram = configFileParsingDiagnosticsOrOldProgram as ts.BuilderProgram; + ts.Debug.assert(!!oldProgram); newProgram = oldProgram.getProgram(); } - else if (isArray(newProgramOrRootNames)) { - oldProgram = configFileParsingDiagnosticsOrOldProgram as BuilderProgram; - newProgram = createProgram({ + else if (ts.isArray(newProgramOrRootNames)) { + oldProgram = configFileParsingDiagnosticsOrOldProgram as ts.BuilderProgram; + newProgram = ts.createProgram({ rootNames: newProgramOrRootNames, - options: hostOrOptions as CompilerOptions, - host: oldProgramOrHost as CompilerHost, + options: hostOrOptions as ts.CompilerOptions, + host: oldProgramOrHost as ts.CompilerHost, oldProgram: oldProgram && oldProgram.getProgramOrUndefined(), configFileParsingDiagnostics, projectReferences }); - host = oldProgramOrHost as CompilerHost; + host = oldProgramOrHost as ts.CompilerHost; } else { newProgram = newProgramOrRootNames; - host = hostOrOptions as BuilderProgramHost; - oldProgram = oldProgramOrHost as BuilderProgram; - configFileParsingDiagnostics = configFileParsingDiagnosticsOrOldProgram as readonly Diagnostic[]; + host = hostOrOptions as ts.BuilderProgramHost; + oldProgram = oldProgramOrHost as ts.BuilderProgram; + configFileParsingDiagnostics = configFileParsingDiagnosticsOrOldProgram as readonly ts.Diagnostic[]; } - return { host, newProgram, oldProgram, configFileParsingDiagnostics: configFileParsingDiagnostics || emptyArray }; + return { host, newProgram, oldProgram, configFileParsingDiagnostics: configFileParsingDiagnostics || ts.emptyArray }; } - export function createBuilderProgram(kind: BuilderProgramKind.SemanticDiagnosticsBuilderProgram, builderCreationParameters: BuilderCreationParameters): SemanticDiagnosticsBuilderProgram; - export function createBuilderProgram(kind: BuilderProgramKind.EmitAndSemanticDiagnosticsBuilderProgram, builderCreationParameters: BuilderCreationParameters): EmitAndSemanticDiagnosticsBuilderProgram; + export function createBuilderProgram(kind: BuilderProgramKind.SemanticDiagnosticsBuilderProgram, builderCreationParameters: BuilderCreationParameters): ts.SemanticDiagnosticsBuilderProgram; + export function createBuilderProgram(kind: BuilderProgramKind.EmitAndSemanticDiagnosticsBuilderProgram, builderCreationParameters: BuilderCreationParameters): ts.EmitAndSemanticDiagnosticsBuilderProgram; export function createBuilderProgram(kind: BuilderProgramKind, { newProgram, host, oldProgram, configFileParsingDiagnostics }: BuilderCreationParameters) { // Return same program if underlying program doesnt change let oldState = oldProgram && oldProgram.getState(); @@ -1051,11 +965,11 @@ namespace ts { /** * Create the canonical file name for identity */ - const getCanonicalFileName = createGetCanonicalFileName(host.useCaseSensitiveFileNames()); + const getCanonicalFileName = ts.createGetCanonicalFileName(host.useCaseSensitiveFileNames()); /** * Computing hash to for signature verification */ - const computeHash = maybeBind(host, host.createHash); + const computeHash = ts.maybeBind(host, host.createHash); let state = createBuilderProgramState(newProgram, getCanonicalFileName, oldState, host.disableUseFileVersionAsSignature); let backupState: BuilderProgramState | undefined; newProgram.getProgramBuildInfo = () => getProgramBuildInfo(state, getCanonicalFileName); @@ -1069,14 +983,14 @@ namespace ts { const builderProgram = createRedirectedBuilderProgram(getState, configFileParsingDiagnostics); builderProgram.getState = getState; builderProgram.backupState = () => { - Debug.assert(backupState === undefined); + ts.Debug.assert(backupState === undefined); backupState = cloneBuilderProgramState(state); }; builderProgram.restoreState = () => { - state = Debug.checkDefined(backupState); + state = ts.Debug.checkDefined(backupState); backupState = undefined; }; - builderProgram.getAllDependencies = sourceFile => BuilderState.getAllDependencies(state, Debug.checkDefined(state.program), sourceFile); + builderProgram.getAllDependencies = sourceFile => ts.BuilderState.getAllDependencies(state, ts.Debug.checkDefined(state.program), sourceFile); builderProgram.getSemanticDiagnostics = getSemanticDiagnostics; builderProgram.emit = emit; builderProgram.releaseProgram = () => { @@ -1085,26 +999,26 @@ namespace ts { }; if (kind === BuilderProgramKind.SemanticDiagnosticsBuilderProgram) { - (builderProgram as SemanticDiagnosticsBuilderProgram).getSemanticDiagnosticsOfNextAffectedFile = getSemanticDiagnosticsOfNextAffectedFile; + (builderProgram as ts.SemanticDiagnosticsBuilderProgram).getSemanticDiagnosticsOfNextAffectedFile = getSemanticDiagnosticsOfNextAffectedFile; } else if (kind === BuilderProgramKind.EmitAndSemanticDiagnosticsBuilderProgram) { - (builderProgram as EmitAndSemanticDiagnosticsBuilderProgram).getSemanticDiagnosticsOfNextAffectedFile = getSemanticDiagnosticsOfNextAffectedFile; - (builderProgram as EmitAndSemanticDiagnosticsBuilderProgram).emitNextAffectedFile = emitNextAffectedFile; + (builderProgram as ts.EmitAndSemanticDiagnosticsBuilderProgram).getSemanticDiagnosticsOfNextAffectedFile = getSemanticDiagnosticsOfNextAffectedFile; + (builderProgram as ts.EmitAndSemanticDiagnosticsBuilderProgram).emitNextAffectedFile = emitNextAffectedFile; builderProgram.emitBuildInfo = emitBuildInfo; } else { - notImplemented(); + ts.notImplemented(); } return builderProgram; - function emitBuildInfo(writeFile?: WriteFileCallback, cancellationToken?: CancellationToken): EmitResult { + function emitBuildInfo(writeFile?: ts.WriteFileCallback, cancellationToken?: ts.CancellationToken): ts.EmitResult { if (state.buildInfoEmitPending) { - const result = Debug.checkDefined(state.program).emitBuildInfo(writeFile || maybeBind(host, host.writeFile), cancellationToken); + const result = ts.Debug.checkDefined(state.program).emitBuildInfo(writeFile || ts.maybeBind(host, host.writeFile), cancellationToken); state.buildInfoEmitPending = false; return result; } - return emitSkippedWithNoDiagnostics; + return ts.emitSkippedWithNoDiagnostics; } /** @@ -1112,84 +1026,76 @@ namespace ts { * The first of writeFile if provided, writeFile of BuilderProgramHost if provided, writeFile of compiler host * in that order would be used to write the files */ - function emitNextAffectedFile(writeFile?: WriteFileCallback, cancellationToken?: CancellationToken, emitOnlyDtsFiles?: boolean, customTransformers?: CustomTransformers): AffectedFileResult { + function emitNextAffectedFile(writeFile?: ts.WriteFileCallback, cancellationToken?: ts.CancellationToken, emitOnlyDtsFiles?: boolean, customTransformers?: ts.CustomTransformers): ts.AffectedFileResult { let affected = getNextAffectedFile(state, cancellationToken, computeHash, host); let emitKind = BuilderFileEmit.Full; let isPendingEmitFile = false; if (!affected) { - if (!outFile(state.compilerOptions)) { + if (!ts.outFile(state.compilerOptions)) { const pendingAffectedFile = getNextAffectedFilePendingEmit(state); if (!pendingAffectedFile) { if (!state.buildInfoEmitPending) { return undefined; } - const affected = Debug.checkDefined(state.program); - return toAffectedFileEmitResult( - state, + const affected = ts.Debug.checkDefined(state.program); + return toAffectedFileEmitResult(state, // When whole program is affected, do emit only once (eg when --out or --outFile is specified) // Otherwise just affected file - affected.emitBuildInfo(writeFile || maybeBind(host, host.writeFile), cancellationToken), - affected, + affected.emitBuildInfo(writeFile || ts.maybeBind(host, host.writeFile), cancellationToken), affected, /*emitKind*/ BuilderFileEmit.Full, /*isPendingEmitFile*/ false, - /*isBuildInfoEmit*/ true - ); + /*isBuildInfoEmit*/ true); } ({ affectedFile: affected, emitKind } = pendingAffectedFile); isPendingEmitFile = true; } else { - const program = Debug.checkDefined(state.program); - if (state.programEmitComplete) return undefined; + const program = ts.Debug.checkDefined(state.program); + if (state.programEmitComplete) + return undefined; affected = program; } } - return toAffectedFileEmitResult( - state, + return toAffectedFileEmitResult(state, // When whole program is affected, do emit only once (eg when --out or --outFile is specified) // Otherwise just affected file - Debug.checkDefined(state.program).emit( - affected === state.program ? undefined : affected as SourceFile, - affected !== state.program && getEmitDeclarations(state.compilerOptions) && !customTransformers ? + ts.Debug.checkDefined(state.program).emit(affected === state.program ? undefined : affected as ts.SourceFile, affected !== state.program && ts.getEmitDeclarations(state.compilerOptions) && !customTransformers ? getWriteFileUpdatingSignatureCallback(writeFile) : - writeFile || maybeBind(host, host.writeFile), - cancellationToken, - emitOnlyDtsFiles || emitKind === BuilderFileEmit.DtsOnly, - customTransformers - ), - affected, - emitKind, - isPendingEmitFile, - ); + writeFile || ts.maybeBind(host, host.writeFile), cancellationToken, emitOnlyDtsFiles || emitKind === BuilderFileEmit.DtsOnly, customTransformers), affected, emitKind, isPendingEmitFile); } - - function getWriteFileUpdatingSignatureCallback(writeFile: WriteFileCallback | undefined): WriteFileCallback { + function getWriteFileUpdatingSignatureCallback(writeFile: ts.WriteFileCallback | undefined): ts.WriteFileCallback { return (fileName, text, writeByteOrderMark, onError, sourceFiles, data) => { - if (isDeclarationFileName(fileName)) { - Debug.assert(sourceFiles?.length === 1); + if (ts.isDeclarationFileName(fileName)) { + ts.Debug.assert(sourceFiles?.length === 1); const file = sourceFiles[0]; const info = state.fileInfos.get(file.resolvedPath)!; const signature = state.currentAffectedFilesSignatures?.get(file.resolvedPath) || info.signature; if (signature === file.version) { - const newSignature = (computeHash || generateDjb2Hash)(data?.sourceMapUrlPos !== undefined ? text.substring(0, data.sourceMapUrlPos) : text); + const newSignature = (computeHash || ts.generateDjb2Hash)(data?.sourceMapUrlPos !== undefined ? text.substring(0, data.sourceMapUrlPos) : text); if (newSignature !== file.version) { // Update it - if (host.storeFilesChangingSignatureDuringEmit) (state.filesChangingSignature ||= new Set()).add(file.resolvedPath); - if (state.exportedModulesMap) BuilderState.updateExportedModules(file, file.exportedModulesFromDeclarationEmit, state.currentAffectedFilesExportedModulesMap ||= BuilderState.createManyToManyPathMap()); + if (host.storeFilesChangingSignatureDuringEmit) + (state.filesChangingSignature ||= new ts.Set()).add(file.resolvedPath); + if (state.exportedModulesMap) + ts.BuilderState.updateExportedModules(file, file.exportedModulesFromDeclarationEmit, state.currentAffectedFilesExportedModulesMap ||= ts.BuilderState.createManyToManyPathMap()); if (state.affectedFiles && state.affectedFilesIndex! < state.affectedFiles.length) { state.currentAffectedFilesSignatures!.set(file.resolvedPath, newSignature); } else { info.signature = newSignature; - if (state.exportedModulesMap) BuilderState.updateExportedFilesMapFromCache(state, state.currentAffectedFilesExportedModulesMap); + if (state.exportedModulesMap) + ts.BuilderState.updateExportedFilesMapFromCache(state, state.currentAffectedFilesExportedModulesMap); } } } } - if (writeFile) writeFile(fileName, text, writeByteOrderMark, onError, sourceFiles, data); - else if (host.writeFile) host.writeFile(fileName, text, writeByteOrderMark, onError, sourceFiles, data); - else state.program!.writeFile(fileName, text, writeByteOrderMark, onError, sourceFiles, data); + if (writeFile) + writeFile(fileName, text, writeByteOrderMark, onError, sourceFiles, data); + else if (host.writeFile) + host.writeFile(fileName, text, writeByteOrderMark, onError, sourceFiles, data); + else + state.program!.writeFile(fileName, text, writeByteOrderMark, onError, sourceFiles, data); }; } @@ -1204,65 +1110,59 @@ namespace ts { * The first of writeFile if provided, writeFile of BuilderProgramHost if provided, writeFile of compiler host * in that order would be used to write the files */ - function emit(targetSourceFile?: SourceFile, writeFile?: WriteFileCallback, cancellationToken?: CancellationToken, emitOnlyDtsFiles?: boolean, customTransformers?: CustomTransformers): EmitResult { + function emit(targetSourceFile?: ts.SourceFile, writeFile?: ts.WriteFileCallback, cancellationToken?: ts.CancellationToken, emitOnlyDtsFiles?: boolean, customTransformers?: ts.CustomTransformers): ts.EmitResult { if (kind === BuilderProgramKind.EmitAndSemanticDiagnosticsBuilderProgram) { assertSourceFileOkWithoutNextAffectedCall(state, targetSourceFile); } - const result = handleNoEmitOptions(builderProgram, targetSourceFile, writeFile, cancellationToken); - if (result) return result; + const result = ts.handleNoEmitOptions(builderProgram, targetSourceFile, writeFile, cancellationToken); + if (result) + return result; // Emit only affected files if using builder for emit if (!targetSourceFile) { if (kind === BuilderProgramKind.EmitAndSemanticDiagnosticsBuilderProgram) { // Emit and report any errors we ran into. - let sourceMaps: SourceMapEmitResult[] = []; + let sourceMaps: ts.SourceMapEmitResult[] = []; let emitSkipped = false; - let diagnostics: Diagnostic[] | undefined; + let diagnostics: ts.Diagnostic[] | undefined; let emittedFiles: string[] = []; - let affectedEmitResult: AffectedFileResult; + let affectedEmitResult: ts.AffectedFileResult; while (affectedEmitResult = emitNextAffectedFile(writeFile, cancellationToken, emitOnlyDtsFiles, customTransformers)) { emitSkipped = emitSkipped || affectedEmitResult.result.emitSkipped; - diagnostics = addRange(diagnostics, affectedEmitResult.result.diagnostics); - emittedFiles = addRange(emittedFiles, affectedEmitResult.result.emittedFiles); - sourceMaps = addRange(sourceMaps, affectedEmitResult.result.sourceMaps); + diagnostics = ts.addRange(diagnostics, affectedEmitResult.result.diagnostics); + emittedFiles = ts.addRange(emittedFiles, affectedEmitResult.result.emittedFiles); + sourceMaps = ts.addRange(sourceMaps, affectedEmitResult.result.sourceMaps); } return { emitSkipped, - diagnostics: diagnostics || emptyArray, + diagnostics: diagnostics || ts.emptyArray, emittedFiles, sourceMaps }; } // In non Emit builder, clear affected files pending emit else if (state.affectedFilesPendingEmitKind?.size) { - Debug.assert(kind === BuilderProgramKind.SemanticDiagnosticsBuilderProgram); + ts.Debug.assert(kind === BuilderProgramKind.SemanticDiagnosticsBuilderProgram); // State can clear affected files pending emit if if (!emitOnlyDtsFiles // If we are doing complete emit, affected files pending emit can be cleared // If every file pending emit is pending on only dts emit - || every(state.affectedFilesPendingEmit, (path, index) => - index < state.affectedFilesPendingEmitIndex! || + || ts.every(state.affectedFilesPendingEmit, (path, index) => index < state.affectedFilesPendingEmitIndex! || state.affectedFilesPendingEmitKind!.get(path) === BuilderFileEmit.DtsOnly)) { clearAffectedFilesPendingEmit(state); } } } - return Debug.checkDefined(state.program).emit( - targetSourceFile, - !outFile(state.compilerOptions) && getEmitDeclarations(state.compilerOptions) && !customTransformers ? + return ts.Debug.checkDefined(state.program).emit(targetSourceFile, !ts.outFile(state.compilerOptions) && ts.getEmitDeclarations(state.compilerOptions) && !customTransformers ? getWriteFileUpdatingSignatureCallback(writeFile) : - writeFile || maybeBind(host, host.writeFile), - cancellationToken, - emitOnlyDtsFiles, - customTransformers - ); + writeFile || ts.maybeBind(host, host.writeFile), cancellationToken, emitOnlyDtsFiles, customTransformers); } /** * Return the semantic diagnostics for the next affected file or undefined if iteration is complete * If provided ignoreSourceFile would be called before getting the diagnostics and would ignore the sourceFile if the returned value was true */ - function getSemanticDiagnosticsOfNextAffectedFile(cancellationToken?: CancellationToken, ignoreSourceFile?: (sourceFile: SourceFile) => boolean): AffectedFileResult { + function getSemanticDiagnosticsOfNextAffectedFile(cancellationToken?: ts.CancellationToken, ignoreSourceFile?: (sourceFile: ts.SourceFile) => boolean): ts.AffectedFileResult { while (true) { const affected = getNextAffectedFile(state, cancellationToken, computeHash, host); if (!affected) { @@ -1271,31 +1171,23 @@ namespace ts { } else if (affected === state.program) { // When whole program is affected, get all semantic diagnostics (eg when --out or --outFile is specified) - return toAffectedFileResult( - state, - state.program.getSemanticDiagnostics(/*targetSourceFile*/ undefined, cancellationToken), - affected - ); + return toAffectedFileResult(state, state.program.getSemanticDiagnostics(/*targetSourceFile*/ undefined, cancellationToken), affected); } // Add file to affected file pending emit to handle for later emit time // Apart for emit builder do this for tsbuildinfo, do this for non emit builder when noEmit is set as tsbuildinfo is written and reused between emitters if (kind === BuilderProgramKind.EmitAndSemanticDiagnosticsBuilderProgram || state.compilerOptions.noEmit || state.compilerOptions.noEmitOnError) { - addToAffectedFilesPendingEmit(state, (affected as SourceFile).resolvedPath, BuilderFileEmit.Full); + addToAffectedFilesPendingEmit(state, (affected as ts.SourceFile).resolvedPath, BuilderFileEmit.Full); } // Get diagnostics for the affected file if its not ignored - if (ignoreSourceFile && ignoreSourceFile(affected as SourceFile)) { + if (ignoreSourceFile && ignoreSourceFile(affected as ts.SourceFile)) { // Get next affected file doneWithAffectedFile(state, affected); continue; } - return toAffectedFileResult( - state, - getSemanticDiagnosticsOfFile(state, affected as SourceFile, cancellationToken), - affected - ); + return toAffectedFileResult(state, getSemanticDiagnosticsOfFile(state, affected as ts.SourceFile, cancellationToken), affected); } } @@ -1307,13 +1199,13 @@ namespace ts { * In case of SemanticDiagnosticsBuilderProgram if the source file is not provided, * it will iterate through all the affected files, to ensure that cache stays valid and yet provide a way to get all semantic diagnostics */ - function getSemanticDiagnostics(sourceFile?: SourceFile, cancellationToken?: CancellationToken): readonly Diagnostic[] { + function getSemanticDiagnostics(sourceFile?: ts.SourceFile, cancellationToken?: ts.CancellationToken): readonly ts.Diagnostic[] { assertSourceFileOkWithoutNextAffectedCall(state, sourceFile); - const compilerOptions = Debug.checkDefined(state.program).getCompilerOptions(); - if (outFile(compilerOptions)) { - Debug.assert(!state.semanticDiagnosticsPerFile); + const compilerOptions = ts.Debug.checkDefined(state.program).getCompilerOptions(); + if (ts.outFile(compilerOptions)) { + ts.Debug.assert(!state.semanticDiagnosticsPerFile); // We dont need to cache the diagnostics just return them from program - return Debug.checkDefined(state.program).getSemanticDiagnostics(sourceFile, cancellationToken); + return ts.Debug.checkDefined(state.program).getSemanticDiagnostics(sourceFile, cancellationToken); } if (sourceFile) { @@ -1326,17 +1218,19 @@ namespace ts { while (getSemanticDiagnosticsOfNextAffectedFile(cancellationToken)) { } - let diagnostics: Diagnostic[] | undefined; - for (const sourceFile of Debug.checkDefined(state.program).getSourceFiles()) { - diagnostics = addRange(diagnostics, getSemanticDiagnosticsOfFile(state, sourceFile, cancellationToken)); + let diagnostics: ts.Diagnostic[] | undefined; + for (const sourceFile of ts.Debug.checkDefined(state.program).getSourceFiles()) { + diagnostics = ts.addRange(diagnostics, getSemanticDiagnosticsOfFile(state, sourceFile, cancellationToken)); } - return diagnostics || emptyArray; + return diagnostics || ts.emptyArray; } } - function addToAffectedFilesPendingEmit(state: BuilderProgramState, affectedFilePendingEmit: Path, kind: BuilderFileEmit) { - if (!state.affectedFilesPendingEmit) state.affectedFilesPendingEmit = []; - if (!state.affectedFilesPendingEmitKind) state.affectedFilesPendingEmitKind = new Map(); + function addToAffectedFilesPendingEmit(state: BuilderProgramState, affectedFilePendingEmit: ts.Path, kind: BuilderFileEmit) { + if (!state.affectedFilesPendingEmit) + state.affectedFilesPendingEmit = []; + if (!state.affectedFilesPendingEmitKind) + state.affectedFilesPendingEmitKind = new ts.Map(); const existingKind = state.affectedFilesPendingEmitKind.get(affectedFilePendingEmit); state.affectedFilesPendingEmit.push(affectedFilePendingEmit); @@ -1351,56 +1245,56 @@ namespace ts { } } - export function toBuilderStateFileInfo(fileInfo: ProgramBuildInfoFileInfo): BuilderState.FileInfo { - return isString(fileInfo) ? + export function toBuilderStateFileInfo(fileInfo: ProgramBuildInfoFileInfo): ts.BuilderState.FileInfo { + return ts.isString(fileInfo) ? { version: fileInfo, signature: fileInfo, affectsGlobalScope: undefined, impliedFormat: undefined } : - isString(fileInfo.signature) ? - fileInfo as BuilderState.FileInfo : + ts.isString(fileInfo.signature) ? + fileInfo as ts.BuilderState.FileInfo : { version: fileInfo.version, signature: fileInfo.signature === false ? undefined : fileInfo.version, affectsGlobalScope: fileInfo.affectsGlobalScope, impliedFormat: fileInfo.impliedFormat }; } - export function createBuildProgramUsingProgramBuildInfo(program: ProgramBuildInfo, buildInfoPath: string, host: ReadBuildProgramHost): EmitAndSemanticDiagnosticsBuilderProgram { - const buildInfoDirectory = getDirectoryPath(getNormalizedAbsolutePath(buildInfoPath, host.getCurrentDirectory())); - const getCanonicalFileName = createGetCanonicalFileName(host.useCaseSensitiveFileNames()); + export function createBuildProgramUsingProgramBuildInfo(program: ProgramBuildInfo, buildInfoPath: string, host: ts.ReadBuildProgramHost): ts.EmitAndSemanticDiagnosticsBuilderProgram { + const buildInfoDirectory = ts.getDirectoryPath(ts.getNormalizedAbsolutePath(buildInfoPath, host.getCurrentDirectory())); + const getCanonicalFileName = ts.createGetCanonicalFileName(host.useCaseSensitiveFileNames()); const filePaths = program.fileNames.map(toPath); - const filePathsSetList = program.fileIdsList?.map(fileIds => new Set(fileIds.map(toFilePath))); - const fileInfos = new Map(); + const filePathsSetList = program.fileIdsList?.map(fileIds => new ts.Set(fileIds.map(toFilePath))); + const fileInfos = new ts.Map(); program.fileInfos.forEach((fileInfo, index) => fileInfos.set(toFilePath(index + 1 as ProgramBuildInfoFileId), toBuilderStateFileInfo(fileInfo))); const state: ReusableBuilderProgramState = { fileInfos, - compilerOptions: program.options ? convertToOptionsWithAbsolutePaths(program.options, toAbsolutePath) : {}, + compilerOptions: program.options ? ts.convertToOptionsWithAbsolutePaths(program.options, toAbsolutePath) : {}, referencedMap: toManyToManyPathMap(program.referencedMap), exportedModulesMap: toManyToManyPathMap(program.exportedModulesMap), - semanticDiagnosticsPerFile: program.semanticDiagnosticsPerFile && arrayToMap(program.semanticDiagnosticsPerFile, value => toFilePath(isNumber(value) ? value : value[0]), value => isNumber(value) ? emptyArray : value[1]), + semanticDiagnosticsPerFile: program.semanticDiagnosticsPerFile && ts.arrayToMap(program.semanticDiagnosticsPerFile, value => toFilePath(ts.isNumber(value) ? value : value[0]), value => ts.isNumber(value) ? ts.emptyArray : value[1]), hasReusableDiagnostic: true, - affectedFilesPendingEmit: map(program.affectedFilesPendingEmit, value => toFilePath(value[0])), - affectedFilesPendingEmitKind: program.affectedFilesPendingEmit && arrayToMap(program.affectedFilesPendingEmit, value => toFilePath(value[0]), value => value[1]), + affectedFilesPendingEmit: ts.map(program.affectedFilesPendingEmit, value => toFilePath(value[0])), + affectedFilesPendingEmitKind: program.affectedFilesPendingEmit && ts.arrayToMap(program.affectedFilesPendingEmit, value => toFilePath(value[0]), value => value[1]), affectedFilesPendingEmitIndex: program.affectedFilesPendingEmit && 0, }; return { getState: () => state, - backupState: noop, - restoreState: noop, - getProgram: notImplemented, - getProgramOrUndefined: returnUndefined, - releaseProgram: noop, + backupState: ts.noop, + restoreState: ts.noop, + getProgram: ts.notImplemented, + getProgramOrUndefined: ts.returnUndefined, + releaseProgram: ts.noop, getCompilerOptions: () => state.compilerOptions, - getSourceFile: notImplemented, - getSourceFiles: notImplemented, - getOptionsDiagnostics: notImplemented, - getGlobalDiagnostics: notImplemented, - getConfigFileParsingDiagnostics: notImplemented, - getSyntacticDiagnostics: notImplemented, - getDeclarationDiagnostics: notImplemented, - getSemanticDiagnostics: notImplemented, - emit: notImplemented, - getAllDependencies: notImplemented, - getCurrentDirectory: notImplemented, - emitNextAffectedFile: notImplemented, - getSemanticDiagnosticsOfNextAffectedFile: notImplemented, - emitBuildInfo: notImplemented, - close: noop, + getSourceFile: ts.notImplemented, + getSourceFiles: ts.notImplemented, + getOptionsDiagnostics: ts.notImplemented, + getGlobalDiagnostics: ts.notImplemented, + getConfigFileParsingDiagnostics: ts.notImplemented, + getSyntacticDiagnostics: ts.notImplemented, + getDeclarationDiagnostics: ts.notImplemented, + getSemanticDiagnostics: ts.notImplemented, + emit: ts.notImplemented, + getAllDependencies: ts.notImplemented, + getCurrentDirectory: ts.notImplemented, + emitNextAffectedFile: ts.notImplemented, + getSemanticDiagnosticsOfNextAffectedFile: ts.notImplemented, + emitBuildInfo: ts.notImplemented, + close: ts.noop, }; function toPath(path: string) { @@ -1408,7 +1302,7 @@ namespace ts { } function toAbsolutePath(path: string) { - return getNormalizedAbsolutePath(path, buildInfoDirectory); + return ts.getNormalizedAbsolutePath(path, buildInfoDirectory); } function toFilePath(fileId: ProgramBuildInfoFileId) { @@ -1419,24 +1313,25 @@ namespace ts { return filePathsSetList![fileIdsListId - 1]; } - function toManyToManyPathMap(referenceMap: ProgramBuildInfoReferencedMap | undefined): BuilderState.ManyToManyPathMap | undefined { + function toManyToManyPathMap(referenceMap: ProgramBuildInfoReferencedMap | undefined): ts.BuilderState.ManyToManyPathMap | undefined { if (!referenceMap) { return undefined; } - const map = BuilderState.createManyToManyPathMap(); - referenceMap.forEach(([fileId, fileIdListId]) => - map.set(toFilePath(fileId), toFilePathsSet(fileIdListId)) - ); + const map = ts.BuilderState.createManyToManyPathMap(); + referenceMap.forEach(([fileId, fileIdListId]) => map.set(toFilePath(fileId), toFilePathsSet(fileIdListId))); return map; } } - export function createRedirectedBuilderProgram(getState: () => { program: Program | undefined; compilerOptions: CompilerOptions; }, configFileParsingDiagnostics: readonly Diagnostic[]): BuilderProgram { + export function createRedirectedBuilderProgram(getState: () => { + program: ts.Program | undefined; + compilerOptions: ts.CompilerOptions; + }, configFileParsingDiagnostics: readonly ts.Diagnostic[]): ts.BuilderProgram { return { - getState: notImplemented, - backupState: noop, - restoreState: noop, + getState: ts.notImplemented, + backupState: ts.noop, + restoreState: ts.noop, getProgram, getProgramOrUndefined: () => getState().program, releaseProgram: () => getState().program = undefined, @@ -1451,13 +1346,13 @@ namespace ts { getSemanticDiagnostics: (sourceFile, cancellationToken) => getProgram().getSemanticDiagnostics(sourceFile, cancellationToken), emit: (sourceFile, writeFile, cancellationToken, emitOnlyDts, customTransformers) => getProgram().emit(sourceFile, writeFile, cancellationToken, emitOnlyDts, customTransformers), emitBuildInfo: (writeFile, cancellationToken) => getProgram().emitBuildInfo(writeFile, cancellationToken), - getAllDependencies: notImplemented, + getAllDependencies: ts.notImplemented, getCurrentDirectory: () => getProgram().getCurrentDirectory(), - close: noop, + close: ts.noop, }; function getProgram() { - return Debug.checkDefined(getState().program); + return ts.Debug.checkDefined(getState().program); } } } diff --git a/src/compiler/builderPublic.ts b/src/compiler/builderPublic.ts index a3527a83f9fa2..e80ae6e6f973b 100644 --- a/src/compiler/builderPublic.ts +++ b/src/compiler/builderPublic.ts @@ -1,5 +1,8 @@ namespace ts { - export type AffectedFileResult = { result: T; affected: SourceFile | Program; } | undefined; + export type AffectedFileResult = { + result: T; + affected: ts.SourceFile | ts.Program; + } | undefined; export interface BuilderProgramHost { /** @@ -14,7 +17,7 @@ namespace ts { * When emit or emitNextAffectedFile are called without writeFile, * this callback if present would be used to write files */ - writeFile?: WriteFileCallback; + writeFile?: ts.WriteFileCallback; /** * disable using source file version as signature for testing */ @@ -32,7 +35,7 @@ namespace ts { */ export interface BuilderProgram { /*@internal*/ - getState(): ReusableBuilderProgramState; + getState(): ts.ReusableBuilderProgramState; /*@internal*/ backupState(): void; /*@internal*/ @@ -40,12 +43,12 @@ namespace ts { /** * Returns current program */ - getProgram(): Program; + getProgram(): ts.Program; /** * Returns current program that could be undefined if the program was released */ /*@internal*/ - getProgramOrUndefined(): Program | undefined; + getProgramOrUndefined(): ts.Program | undefined; /** * Releases reference to the program, making all the other operations that need program to fail. */ @@ -54,39 +57,39 @@ namespace ts { /** * Get compiler options of the program */ - getCompilerOptions(): CompilerOptions; + getCompilerOptions(): ts.CompilerOptions; /** * Get the source file in the program with file name */ - getSourceFile(fileName: string): SourceFile | undefined; + getSourceFile(fileName: string): ts.SourceFile | undefined; /** * Get a list of files in the program */ - getSourceFiles(): readonly SourceFile[]; + getSourceFiles(): readonly ts.SourceFile[]; /** * Get the diagnostics for compiler options */ - getOptionsDiagnostics(cancellationToken?: CancellationToken): readonly Diagnostic[]; + getOptionsDiagnostics(cancellationToken?: ts.CancellationToken): readonly ts.Diagnostic[]; /** * Get the diagnostics that dont belong to any file */ - getGlobalDiagnostics(cancellationToken?: CancellationToken): readonly Diagnostic[]; + getGlobalDiagnostics(cancellationToken?: ts.CancellationToken): readonly ts.Diagnostic[]; /** * Get the diagnostics from config file parsing */ - getConfigFileParsingDiagnostics(): readonly Diagnostic[]; + getConfigFileParsingDiagnostics(): readonly ts.Diagnostic[]; /** * Get the syntax diagnostics, for all source files if source file is not supplied */ - getSyntacticDiagnostics(sourceFile?: SourceFile, cancellationToken?: CancellationToken): readonly Diagnostic[]; + getSyntacticDiagnostics(sourceFile?: ts.SourceFile, cancellationToken?: ts.CancellationToken): readonly ts.Diagnostic[]; /** * Get the declaration diagnostics, for all source files if source file is not supplied */ - getDeclarationDiagnostics(sourceFile?: SourceFile, cancellationToken?: CancellationToken): readonly DiagnosticWithLocation[]; + getDeclarationDiagnostics(sourceFile?: ts.SourceFile, cancellationToken?: ts.CancellationToken): readonly ts.DiagnosticWithLocation[]; /** * Get all the dependencies of the file */ - getAllDependencies(sourceFile: SourceFile): readonly string[]; + getAllDependencies(sourceFile: ts.SourceFile): readonly string[]; /** * Gets the semantic diagnostics from the program corresponding to this state of file (if provided) or whole program @@ -96,7 +99,7 @@ namespace ts { * In case of SemanticDiagnosticsBuilderProgram if the source file is not provided, * it will iterate through all the affected files, to ensure that cache stays valid and yet provide a way to get all semantic diagnostics */ - getSemanticDiagnostics(sourceFile?: SourceFile, cancellationToken?: CancellationToken): readonly Diagnostic[]; + getSemanticDiagnostics(sourceFile?: ts.SourceFile, cancellationToken?: ts.CancellationToken): readonly ts.Diagnostic[]; /** * Emits the JavaScript and declaration files. * When targetSource file is specified, emits the files corresponding to that source file, @@ -108,9 +111,9 @@ namespace ts { * The first of writeFile if provided, writeFile of BuilderProgramHost if provided, writeFile of compiler host * in that order would be used to write the files */ - emit(targetSourceFile?: SourceFile, writeFile?: WriteFileCallback, cancellationToken?: CancellationToken, emitOnlyDtsFiles?: boolean, customTransformers?: CustomTransformers): EmitResult; + emit(targetSourceFile?: ts.SourceFile, writeFile?: ts.WriteFileCallback, cancellationToken?: ts.CancellationToken, emitOnlyDtsFiles?: boolean, customTransformers?: ts.CustomTransformers): ts.EmitResult; /*@internal*/ - emitBuildInfo(writeFile?: WriteFileCallback, cancellationToken?: CancellationToken): EmitResult; + emitBuildInfo(writeFile?: ts.WriteFileCallback, cancellationToken?: ts.CancellationToken): ts.EmitResult; /** * Get the current directory of the program */ @@ -127,7 +130,7 @@ namespace ts { * Gets the semantic diagnostics from the program for the next affected file and caches it * Returns undefined if the iteration is complete */ - getSemanticDiagnosticsOfNextAffectedFile(cancellationToken?: CancellationToken, ignoreSourceFile?: (sourceFile: SourceFile) => boolean): AffectedFileResult; + getSemanticDiagnosticsOfNextAffectedFile(cancellationToken?: ts.CancellationToken, ignoreSourceFile?: (sourceFile: ts.SourceFile) => boolean): AffectedFileResult; } /** @@ -140,35 +143,35 @@ namespace ts { * The first of writeFile if provided, writeFile of BuilderProgramHost if provided, writeFile of compiler host * in that order would be used to write the files */ - emitNextAffectedFile(writeFile?: WriteFileCallback, cancellationToken?: CancellationToken, emitOnlyDtsFiles?: boolean, customTransformers?: CustomTransformers): AffectedFileResult; + emitNextAffectedFile(writeFile?: ts.WriteFileCallback, cancellationToken?: ts.CancellationToken, emitOnlyDtsFiles?: boolean, customTransformers?: ts.CustomTransformers): AffectedFileResult; } /** * Create the builder to manage semantic diagnostics and cache them */ - export function createSemanticDiagnosticsBuilderProgram(newProgram: Program, host: BuilderProgramHost, oldProgram?: SemanticDiagnosticsBuilderProgram, configFileParsingDiagnostics?: readonly Diagnostic[]): SemanticDiagnosticsBuilderProgram; - export function createSemanticDiagnosticsBuilderProgram(rootNames: readonly string[] | undefined, options: CompilerOptions | undefined, host?: CompilerHost, oldProgram?: SemanticDiagnosticsBuilderProgram, configFileParsingDiagnostics?: readonly Diagnostic[], projectReferences?: readonly ProjectReference[]): SemanticDiagnosticsBuilderProgram; - export function createSemanticDiagnosticsBuilderProgram(newProgramOrRootNames: Program | readonly string[] | undefined, hostOrOptions: BuilderProgramHost | CompilerOptions | undefined, oldProgramOrHost?: CompilerHost | SemanticDiagnosticsBuilderProgram, configFileParsingDiagnosticsOrOldProgram?: readonly Diagnostic[] | SemanticDiagnosticsBuilderProgram, configFileParsingDiagnostics?: readonly Diagnostic[], projectReferences?: readonly ProjectReference[]) { - return createBuilderProgram(BuilderProgramKind.SemanticDiagnosticsBuilderProgram, getBuilderCreationParameters(newProgramOrRootNames, hostOrOptions, oldProgramOrHost, configFileParsingDiagnosticsOrOldProgram, configFileParsingDiagnostics, projectReferences)); + export function createSemanticDiagnosticsBuilderProgram(newProgram: ts.Program, host: BuilderProgramHost, oldProgram?: SemanticDiagnosticsBuilderProgram, configFileParsingDiagnostics?: readonly ts.Diagnostic[]): SemanticDiagnosticsBuilderProgram; + export function createSemanticDiagnosticsBuilderProgram(rootNames: readonly string[] | undefined, options: ts.CompilerOptions | undefined, host?: ts.CompilerHost, oldProgram?: SemanticDiagnosticsBuilderProgram, configFileParsingDiagnostics?: readonly ts.Diagnostic[], projectReferences?: readonly ts.ProjectReference[]): SemanticDiagnosticsBuilderProgram; + export function createSemanticDiagnosticsBuilderProgram(newProgramOrRootNames: ts.Program | readonly string[] | undefined, hostOrOptions: BuilderProgramHost | ts.CompilerOptions | undefined, oldProgramOrHost?: ts.CompilerHost | SemanticDiagnosticsBuilderProgram, configFileParsingDiagnosticsOrOldProgram?: readonly ts.Diagnostic[] | SemanticDiagnosticsBuilderProgram, configFileParsingDiagnostics?: readonly ts.Diagnostic[], projectReferences?: readonly ts.ProjectReference[]) { + return ts.createBuilderProgram(ts.BuilderProgramKind.SemanticDiagnosticsBuilderProgram, ts.getBuilderCreationParameters(newProgramOrRootNames, hostOrOptions, oldProgramOrHost, configFileParsingDiagnosticsOrOldProgram, configFileParsingDiagnostics, projectReferences)); } /** * Create the builder that can handle the changes in program and iterate through changed files * to emit the those files and manage semantic diagnostics cache as well */ - export function createEmitAndSemanticDiagnosticsBuilderProgram(newProgram: Program, host: BuilderProgramHost, oldProgram?: EmitAndSemanticDiagnosticsBuilderProgram, configFileParsingDiagnostics?: readonly Diagnostic[]): EmitAndSemanticDiagnosticsBuilderProgram; - export function createEmitAndSemanticDiagnosticsBuilderProgram(rootNames: readonly string[] | undefined, options: CompilerOptions | undefined, host?: CompilerHost, oldProgram?: EmitAndSemanticDiagnosticsBuilderProgram, configFileParsingDiagnostics?: readonly Diagnostic[], projectReferences?: readonly ProjectReference[]): EmitAndSemanticDiagnosticsBuilderProgram; - export function createEmitAndSemanticDiagnosticsBuilderProgram(newProgramOrRootNames: Program | readonly string[] | undefined, hostOrOptions: BuilderProgramHost | CompilerOptions | undefined, oldProgramOrHost?: CompilerHost | EmitAndSemanticDiagnosticsBuilderProgram, configFileParsingDiagnosticsOrOldProgram?: readonly Diagnostic[] | EmitAndSemanticDiagnosticsBuilderProgram, configFileParsingDiagnostics?: readonly Diagnostic[], projectReferences?: readonly ProjectReference[]) { - return createBuilderProgram(BuilderProgramKind.EmitAndSemanticDiagnosticsBuilderProgram, getBuilderCreationParameters(newProgramOrRootNames, hostOrOptions, oldProgramOrHost, configFileParsingDiagnosticsOrOldProgram, configFileParsingDiagnostics, projectReferences)); + export function createEmitAndSemanticDiagnosticsBuilderProgram(newProgram: ts.Program, host: BuilderProgramHost, oldProgram?: EmitAndSemanticDiagnosticsBuilderProgram, configFileParsingDiagnostics?: readonly ts.Diagnostic[]): EmitAndSemanticDiagnosticsBuilderProgram; + export function createEmitAndSemanticDiagnosticsBuilderProgram(rootNames: readonly string[] | undefined, options: ts.CompilerOptions | undefined, host?: ts.CompilerHost, oldProgram?: EmitAndSemanticDiagnosticsBuilderProgram, configFileParsingDiagnostics?: readonly ts.Diagnostic[], projectReferences?: readonly ts.ProjectReference[]): EmitAndSemanticDiagnosticsBuilderProgram; + export function createEmitAndSemanticDiagnosticsBuilderProgram(newProgramOrRootNames: ts.Program | readonly string[] | undefined, hostOrOptions: BuilderProgramHost | ts.CompilerOptions | undefined, oldProgramOrHost?: ts.CompilerHost | EmitAndSemanticDiagnosticsBuilderProgram, configFileParsingDiagnosticsOrOldProgram?: readonly ts.Diagnostic[] | EmitAndSemanticDiagnosticsBuilderProgram, configFileParsingDiagnostics?: readonly ts.Diagnostic[], projectReferences?: readonly ts.ProjectReference[]) { + return ts.createBuilderProgram(ts.BuilderProgramKind.EmitAndSemanticDiagnosticsBuilderProgram, ts.getBuilderCreationParameters(newProgramOrRootNames, hostOrOptions, oldProgramOrHost, configFileParsingDiagnosticsOrOldProgram, configFileParsingDiagnostics, projectReferences)); } /** * Creates a builder thats just abstraction over program and can be used with watch */ - export function createAbstractBuilder(newProgram: Program, host: BuilderProgramHost, oldProgram?: BuilderProgram, configFileParsingDiagnostics?: readonly Diagnostic[]): BuilderProgram; - export function createAbstractBuilder(rootNames: readonly string[] | undefined, options: CompilerOptions | undefined, host?: CompilerHost, oldProgram?: BuilderProgram, configFileParsingDiagnostics?: readonly Diagnostic[], projectReferences?: readonly ProjectReference[]): BuilderProgram; - export function createAbstractBuilder(newProgramOrRootNames: Program | readonly string[] | undefined, hostOrOptions: BuilderProgramHost | CompilerOptions | undefined, oldProgramOrHost?: CompilerHost | BuilderProgram, configFileParsingDiagnosticsOrOldProgram?: readonly Diagnostic[] | BuilderProgram, configFileParsingDiagnostics?: readonly Diagnostic[], projectReferences?: readonly ProjectReference[]): BuilderProgram { - const { newProgram, configFileParsingDiagnostics: newConfigFileParsingDiagnostics } = getBuilderCreationParameters(newProgramOrRootNames, hostOrOptions, oldProgramOrHost, configFileParsingDiagnosticsOrOldProgram, configFileParsingDiagnostics, projectReferences); - return createRedirectedBuilderProgram(() => ({ program: newProgram, compilerOptions: newProgram.getCompilerOptions() }), newConfigFileParsingDiagnostics); + export function createAbstractBuilder(newProgram: ts.Program, host: BuilderProgramHost, oldProgram?: BuilderProgram, configFileParsingDiagnostics?: readonly ts.Diagnostic[]): BuilderProgram; + export function createAbstractBuilder(rootNames: readonly string[] | undefined, options: ts.CompilerOptions | undefined, host?: ts.CompilerHost, oldProgram?: BuilderProgram, configFileParsingDiagnostics?: readonly ts.Diagnostic[], projectReferences?: readonly ts.ProjectReference[]): BuilderProgram; + export function createAbstractBuilder(newProgramOrRootNames: ts.Program | readonly string[] | undefined, hostOrOptions: BuilderProgramHost | ts.CompilerOptions | undefined, oldProgramOrHost?: ts.CompilerHost | BuilderProgram, configFileParsingDiagnosticsOrOldProgram?: readonly ts.Diagnostic[] | BuilderProgram, configFileParsingDiagnostics?: readonly ts.Diagnostic[], projectReferences?: readonly ts.ProjectReference[]): BuilderProgram { + const { newProgram, configFileParsingDiagnostics: newConfigFileParsingDiagnostics } = ts.getBuilderCreationParameters(newProgramOrRootNames, hostOrOptions, oldProgramOrHost, configFileParsingDiagnosticsOrOldProgram, configFileParsingDiagnostics, projectReferences); + return ts.createRedirectedBuilderProgram(() => ({ program: newProgram, compilerOptions: newProgram.getCompilerOptions() }), newConfigFileParsingDiagnostics); } } diff --git a/src/compiler/builderState.ts b/src/compiler/builderState.ts index f501eda66a1d1..1348aa6a809da 100644 --- a/src/compiler/builderState.ts +++ b/src/compiler/builderState.ts @@ -1,8 +1,7 @@ /*@internal*/ namespace ts { - export function getFileEmitOutput(program: Program, sourceFile: SourceFile, emitOnlyDtsFiles: boolean, - cancellationToken?: CancellationToken, customTransformers?: CustomTransformers, forceDtsEmit?: boolean): EmitOutput { - const outputFiles: OutputFile[] = []; + export function getFileEmitOutput(program: ts.Program, sourceFile: ts.SourceFile, emitOnlyDtsFiles: boolean, cancellationToken?: ts.CancellationToken, customTransformers?: ts.CustomTransformers, forceDtsEmit?: boolean): ts.EmitOutput { + const outputFiles: ts.OutputFile[] = []; const { emitSkipped, diagnostics, exportedModulesFromDeclarationEmit } = program.emit(sourceFile, writeFile, cancellationToken, emitOnlyDtsFiles, customTransformers, forceDtsEmit); return { outputFiles, emitSkipped, diagnostics, exportedModulesFromDeclarationEmit }; @@ -15,7 +14,7 @@ namespace ts { /** * Information of the file eg. its version, signature etc */ - fileInfos: ReadonlyESMap; + fileInfos: ts.ReadonlyESMap; /** * Contains the map of ReferencedSet=Referenced files of the file if module emit is enabled * Otherwise undefined @@ -33,7 +32,7 @@ namespace ts { /** * Information of the file eg. its version, signature etc */ - fileInfos: ESMap; + fileInfos: ts.ESMap; /** * Contains the map of ReferencedSet=Referenced files of the file if module emit is enabled * Otherwise undefined @@ -58,11 +57,11 @@ namespace ts { * That means hence forth these files are assumed to have * no change in their signature for this version of the program */ - hasCalledUpdateShapeSignature: Set; + hasCalledUpdateShapeSignature: ts.Set; /** * Cache of all files excluding default library file for the current program */ - allFilesExcludingDefaultLibraryFile?: readonly SourceFile[]; + allFilesExcludingDefaultLibraryFile?: readonly ts.SourceFile[]; /** * Cache of all the file names */ @@ -82,30 +81,30 @@ namespace ts { export interface ReadonlyManyToManyPathMap { clone(): ManyToManyPathMap; - forEach(action: (v: ReadonlySet, k: Path) => void): void; - getKeys(v: Path): ReadonlySet | undefined; - getValues(k: Path): ReadonlySet | undefined; - hasKey(k: Path): boolean; - keys(): Iterator; + forEach(action: (v: ts.ReadonlySet, k: ts.Path) => void): void; + getKeys(v: ts.Path): ts.ReadonlySet | undefined; + getValues(k: ts.Path): ts.ReadonlySet | undefined; + hasKey(k: ts.Path): boolean; + keys(): ts.Iterator; /** * The set of arguments to {@link deleteKeys} which have not subsequently * been arguments to {@link set}. Note that a key does not have to have * ever been in the map to appear in this set. */ - deletedKeys(): ReadonlySet | undefined; + deletedKeys(): ts.ReadonlySet | undefined; } export interface ManyToManyPathMap extends ReadonlyManyToManyPathMap { - deleteKey(k: Path): boolean; - set(k: Path, v: ReadonlySet): void; + deleteKey(k: ts.Path): boolean; + set(k: ts.Path, v: ts.ReadonlySet): void; clear(): void; } export function createManyToManyPathMap(): ManyToManyPathMap { - function create(forward: ESMap>, reverse: ESMap>, deleted: Set | undefined): ManyToManyPathMap { + function create(forward: ts.ESMap>, reverse: ts.ESMap>, deleted: ts.Set | undefined): ManyToManyPathMap { const map: ManyToManyPathMap = { - clone: () => create(new Map(forward), new Map(reverse), deleted && new Set(deleted)), + clone: () => create(new ts.Map(forward), new ts.Map(reverse), deleted && new ts.Set(deleted)), forEach: fn => forward.forEach(fn), getKeys: v => reverse.get(v), getValues: k => forward.get(k), @@ -114,7 +113,7 @@ namespace ts { deletedKeys: () => deleted, deleteKey: k => { - (deleted ||= new Set()).add(k); + (deleted ||= new ts.Set()).add(k); const set = forward.get(k); if (!set) { @@ -155,19 +154,19 @@ namespace ts { return map; } - return create(new Map>(), new Map>(), /*deleted*/ undefined); + return create(new ts.Map>(), new ts.Map>(), /*deleted*/ undefined); } - function addToMultimap(map: ESMap>, k: K, v: V): void { + function addToMultimap(map: ts.ESMap>, k: K, v: V): void { let set = map.get(k); if (!set) { - set = new Set(); + set = new ts.Set(); map.set(k, set); } set.add(v); } - function deleteFromMultimap(map: ESMap>, k: K, v: V): boolean { + function deleteFromMultimap(map: ts.ESMap>, k: K, v: V): boolean { const set = map.get(k); if (set?.delete(v)) { @@ -185,14 +184,14 @@ namespace ts { */ export type ComputeHash = ((data: string) => string) | undefined; - function getReferencedFilesFromImportedModuleSymbol(symbol: Symbol): Path[] { - return mapDefined(symbol.declarations, declaration => getSourceFileOfNode(declaration)?.resolvedPath); + function getReferencedFilesFromImportedModuleSymbol(symbol: ts.Symbol): ts.Path[] { + return ts.mapDefined(symbol.declarations, declaration => ts.getSourceFileOfNode(declaration)?.resolvedPath); } /** * Get the module source file and all augmenting files from the import name node from file */ - function getReferencedFilesFromImportLiteral(checker: TypeChecker, importName: StringLiteralLike): Path[] | undefined { + function getReferencedFilesFromImportLiteral(checker: ts.TypeChecker, importName: ts.StringLiteralLike): ts.Path[] | undefined { const symbol = checker.getSymbolAtLocation(importName); return symbol && getReferencedFilesFromImportedModuleSymbol(symbol); } @@ -200,28 +199,28 @@ namespace ts { /** * Gets the path to reference file from file name, it could be resolvedPath if present otherwise path */ - function getReferencedFileFromFileName(program: Program, fileName: string, sourceFileDirectory: Path, getCanonicalFileName: GetCanonicalFileName): Path { - return toPath(program.getProjectReferenceRedirect(fileName) || fileName, sourceFileDirectory, getCanonicalFileName); + function getReferencedFileFromFileName(program: ts.Program, fileName: string, sourceFileDirectory: ts.Path, getCanonicalFileName: ts.GetCanonicalFileName): ts.Path { + return ts.toPath(program.getProjectReferenceRedirect(fileName) || fileName, sourceFileDirectory, getCanonicalFileName); } /** * Gets the referenced files for a file from the program with values for the keys as referenced file's path to be true */ - function getReferencedFiles(program: Program, sourceFile: SourceFile, getCanonicalFileName: GetCanonicalFileName): Set | undefined { - let referencedFiles: Set | undefined; + function getReferencedFiles(program: ts.Program, sourceFile: ts.SourceFile, getCanonicalFileName: ts.GetCanonicalFileName): ts.Set | undefined { + let referencedFiles: ts.Set | undefined; // We need to use a set here since the code can contain the same import twice, // but that will only be one dependency. // To avoid invernal conversion, the key of the referencedFiles map must be of type Path if (sourceFile.imports && sourceFile.imports.length > 0) { - const checker: TypeChecker = program.getTypeChecker(); + const checker: ts.TypeChecker = program.getTypeChecker(); for (const importName of sourceFile.imports) { const declarationSourceFilePaths = getReferencedFilesFromImportLiteral(checker, importName); declarationSourceFilePaths?.forEach(addReferencedFile); } } - const sourceFileDirectory = getDirectoryPath(sourceFile.resolvedPath); + const sourceFileDirectory = ts.getDirectoryPath(sourceFile.resolvedPath); // Handle triple slash references if (sourceFile.referencedFiles && sourceFile.referencedFiles.length > 0) { for (const referencedFile of sourceFile.referencedFiles) { @@ -247,9 +246,11 @@ namespace ts { if (sourceFile.moduleAugmentations.length) { const checker = program.getTypeChecker(); for (const moduleName of sourceFile.moduleAugmentations) { - if (!isStringLiteral(moduleName)) continue; + if (!ts.isStringLiteral(moduleName)) + continue; const symbol = checker.getSymbolAtLocation(moduleName); - if (!symbol) continue; + if (!symbol) + continue; // Add any file other than our own as reference addReferenceFromAmbientModule(symbol); @@ -265,13 +266,13 @@ namespace ts { return referencedFiles; - function addReferenceFromAmbientModule(symbol: Symbol) { + function addReferenceFromAmbientModule(symbol: ts.Symbol) { if (!symbol.declarations) { return; } // Add any file other than our own as reference for (const declaration of symbol.declarations) { - const declarationSourceFile = getSourceFileOfNode(declaration); + const declarationSourceFile = ts.getSourceFileOfNode(declaration); if (declarationSourceFile && declarationSourceFile !== sourceFile) { addReferencedFile(declarationSourceFile.resolvedPath); @@ -279,8 +280,8 @@ namespace ts { } } - function addReferencedFile(referencedPath: Path) { - (referencedFiles || (referencedFiles = new Set())).add(referencedPath); + function addReferencedFile(referencedPath: ts.Path) { + (referencedFiles || (referencedFiles = new ts.Set())).add(referencedPath); } } @@ -294,11 +295,11 @@ namespace ts { /** * Creates the state of file references and signature for the new program from oldState if it is safe */ - export function create(newProgram: Program, getCanonicalFileName: GetCanonicalFileName, oldState?: Readonly, disableUseFileVersionAsSignature?: boolean): BuilderState { - const fileInfos = new Map(); - const referencedMap = newProgram.getCompilerOptions().module !== ModuleKind.None ? createManyToManyPathMap() : undefined; + export function create(newProgram: ts.Program, getCanonicalFileName: ts.GetCanonicalFileName, oldState?: Readonly, disableUseFileVersionAsSignature?: boolean): BuilderState { + const fileInfos = new ts.Map(); + const referencedMap = newProgram.getCompilerOptions().module !== ts.ModuleKind.None ? createManyToManyPathMap() : undefined; const exportedModulesMap = referencedMap ? createManyToManyPathMap() : undefined; - const hasCalledUpdateShapeSignature = new Set(); + const hasCalledUpdateShapeSignature = new ts.Set(); const useOldState = canReuseOldState(referencedMap, oldState); // Ensure source files have parent pointers set @@ -306,7 +307,7 @@ namespace ts { // Create the reference map, and set the file infos for (const sourceFile of newProgram.getSourceFiles()) { - const version = Debug.checkDefined(sourceFile.version, "Program intended to be used with Builder should have source files with versions set"); + const version = ts.Debug.checkDefined(sourceFile.version, "Program intended to be used with Builder should have source files with versions set"); const oldInfo = useOldState ? oldState!.fileInfos.get(sourceFile.resolvedPath) : undefined; if (referencedMap) { const newReferences = getReferencedFiles(newProgram, sourceFile, getCanonicalFileName); @@ -347,10 +348,10 @@ namespace ts { export function clone(state: Readonly): BuilderState { // Dont need to backup allFiles info since its cache anyway return { - fileInfos: new Map(state.fileInfos), + fileInfos: new ts.Map(state.fileInfos), referencedMap: state.referencedMap?.clone(), exportedModulesMap: state.exportedModulesMap?.clone(), - hasCalledUpdateShapeSignature: new Set(state.hasCalledUpdateShapeSignature), + hasCalledUpdateShapeSignature: new ts.Set(state.hasCalledUpdateShapeSignature), useFileVersionAsSignature: state.useFileVersionAsSignature, }; } @@ -358,15 +359,15 @@ namespace ts { /** * Gets the files affected by the path from the program */ - export function getFilesAffectedBy(state: BuilderState, programOfThisState: Program, path: Path, cancellationToken: CancellationToken | undefined, computeHash: ComputeHash, cacheToUpdateSignature?: ESMap, exportedModulesMapCache?: ManyToManyPathMap): readonly SourceFile[] { + export function getFilesAffectedBy(state: BuilderState, programOfThisState: ts.Program, path: ts.Path, cancellationToken: ts.CancellationToken | undefined, computeHash: ComputeHash, cacheToUpdateSignature?: ts.ESMap, exportedModulesMapCache?: ManyToManyPathMap): readonly ts.SourceFile[] { // Since the operation could be cancelled, the signatures are always stored in the cache // They will be committed once it is safe to use them // eg when calling this api from tsserver, if there is no cancellation of the operation // In the other cases the affected files signatures are committed only after the iteration through the result is complete - const signatureCache = cacheToUpdateSignature || new Map(); + const signatureCache = cacheToUpdateSignature || new ts.Map(); const sourceFile = programOfThisState.getSourceFileByPath(path); if (!sourceFile) { - return emptyArray; + return ts.emptyArray; } if (!updateShapeSignature(state, programOfThisState, sourceFile, signatureCache, cancellationToken, computeHash, exportedModulesMapCache)) { @@ -385,11 +386,11 @@ namespace ts { * Updates the signatures from the cache into state's fileinfo signatures * This should be called whenever it is safe to commit the state of the builder */ - export function updateSignaturesFromCache(state: BuilderState, signatureCache: ESMap) { + export function updateSignaturesFromCache(state: BuilderState, signatureCache: ts.ESMap) { signatureCache.forEach((signature, path) => updateSignatureOfFile(state, signature, path)); } - export function updateSignatureOfFile(state: BuilderState, signature: string | undefined, path: Path) { + export function updateSignatureOfFile(state: BuilderState, signature: string | undefined, path: ts.Path) { state.fileInfos.get(path)!.signature = signature; state.hasCalledUpdateShapeSignature.add(path); } @@ -397,9 +398,9 @@ namespace ts { /** * Returns if the shape of the signature has changed since last emit */ - export function updateShapeSignature(state: Readonly, programOfThisState: Program, sourceFile: SourceFile, cacheToUpdateSignature: ESMap, cancellationToken: CancellationToken | undefined, computeHash: ComputeHash, exportedModulesMapCache?: ManyToManyPathMap, useFileVersionAsSignature: boolean = state.useFileVersionAsSignature) { - Debug.assert(!!sourceFile); - Debug.assert(!exportedModulesMapCache || !!state.exportedModulesMap, "Compute visible to outside map only if visibleToOutsideReferencedMap present in the state"); + export function updateShapeSignature(state: Readonly, programOfThisState: ts.Program, sourceFile: ts.SourceFile, cacheToUpdateSignature: ts.ESMap, cancellationToken: ts.CancellationToken | undefined, computeHash: ComputeHash, exportedModulesMapCache?: ManyToManyPathMap, useFileVersionAsSignature: boolean = state.useFileVersionAsSignature) { + ts.Debug.assert(!!sourceFile); + ts.Debug.assert(!exportedModulesMapCache || !!state.exportedModulesMap, "Compute visible to outside map only if visibleToOutsideReferencedMap present in the state"); // If we have cached the result for this file, that means hence forth we should assume file shape is uptodate if (state.hasCalledUpdateShapeSignature.has(sourceFile.resolvedPath) || cacheToUpdateSignature.has(sourceFile.resolvedPath)) { @@ -407,23 +408,20 @@ namespace ts { } const info = state.fileInfos.get(sourceFile.resolvedPath); - if (!info) return Debug.fail(); + if (!info) + return ts.Debug.fail(); const prevSignature = info.signature; let latestSignature: string | undefined; if (!sourceFile.isDeclarationFile && !useFileVersionAsSignature) { - const emitOutput = getFileEmitOutput( - programOfThisState, - sourceFile, - /*emitOnlyDtsFiles*/ true, - cancellationToken, + const emitOutput = getFileEmitOutput(programOfThisState, sourceFile, + /*emitOnlyDtsFiles*/ true, cancellationToken, /*customTransformers*/ undefined, - /*forceDtsEmit*/ true - ); - const firstDts = firstOrUndefined(emitOutput.outputFiles); + /*forceDtsEmit*/ true); + const firstDts = ts.firstOrUndefined(emitOutput.outputFiles); if (firstDts) { - Debug.assert(isDeclarationFileName(firstDts.name), "File extension for signature expected to be dts", () => `Found: ${getAnyExtensionFromPath(firstDts.name)} for ${firstDts.name}:: All output files: ${JSON.stringify(emitOutput.outputFiles.map(f => f.name))}`); - latestSignature = (computeHash || generateDjb2Hash)(firstDts.text); + ts.Debug.assert(ts.isDeclarationFileName(firstDts.name), "File extension for signature expected to be dts", () => `Found: ${ts.getAnyExtensionFromPath(firstDts.name)} for ${firstDts.name}:: All output files: ${JSON.stringify(emitOutput.outputFiles.map(f => f.name))}`); + latestSignature = (computeHash || ts.generateDjb2Hash)(firstDts.text); if (exportedModulesMapCache && latestSignature !== prevSignature) { updateExportedModules(sourceFile, emitOutput.exportedModulesFromDeclarationEmit, exportedModulesMapCache); } @@ -450,13 +448,13 @@ namespace ts { /** * Coverts the declaration emit result into exported modules map */ - export function updateExportedModules(sourceFile: SourceFile, exportedModulesFromDeclarationEmit: ExportedModulesFromDeclarationEmit | undefined, exportedModulesMapCache: ManyToManyPathMap) { + export function updateExportedModules(sourceFile: ts.SourceFile, exportedModulesFromDeclarationEmit: ts.ExportedModulesFromDeclarationEmit | undefined, exportedModulesMapCache: ManyToManyPathMap) { if (!exportedModulesFromDeclarationEmit) { exportedModulesMapCache.deleteKey(sourceFile.resolvedPath); return; } - let exportedModules: Set | undefined; + let exportedModules: ts.Set | undefined; exportedModulesFromDeclarationEmit.forEach(symbol => addExportedModule(getReferencedFilesFromImportedModuleSymbol(symbol))); if (exportedModules) { exportedModulesMapCache.set(sourceFile.resolvedPath, exportedModules); @@ -465,10 +463,10 @@ namespace ts { exportedModulesMapCache.deleteKey(sourceFile.resolvedPath); } - function addExportedModule(exportedModulePaths: Path[] | undefined) { + function addExportedModule(exportedModulePaths: ts.Path[] | undefined) { if (exportedModulePaths?.length) { if (!exportedModules) { - exportedModules = new Set(); + exportedModules = new ts.Set(); } exportedModulePaths.forEach(path => exportedModules!.add(path)); } @@ -481,7 +479,7 @@ namespace ts { */ export function updateExportedFilesMapFromCache(state: BuilderState, exportedModulesMapCache: ManyToManyPathMap | undefined) { if (exportedModulesMapCache) { - Debug.assert(!!state.exportedModulesMap); + ts.Debug.assert(!!state.exportedModulesMap); exportedModulesMapCache.deletedKeys()?.forEach(path => state.exportedModulesMap!.deleteKey(path)); exportedModulesMapCache.forEach((exportedModules, path) => state.exportedModulesMap!.set(path, exportedModules)); } @@ -490,10 +488,10 @@ namespace ts { /** * Get all the dependencies of the sourceFile */ - export function getAllDependencies(state: BuilderState, programOfThisState: Program, sourceFile: SourceFile): readonly string[] { + export function getAllDependencies(state: BuilderState, programOfThisState: ts.Program, sourceFile: ts.SourceFile): readonly string[] { const compilerOptions = programOfThisState.getCompilerOptions(); // With --out or --outFile all outputs go into single file, all files depend on each other - if (outFile(compilerOptions)) { + if (ts.outFile(compilerOptions)) { return getAllFileNames(state, programOfThisState); } @@ -503,7 +501,7 @@ namespace ts { } // Get the references, traversing deep from the referenceMap - const seenMap = new Set(); + const seenMap = new ts.Set(); const queue = [sourceFile.resolvedPath]; while (queue.length) { const path = queue.pop()!; @@ -519,16 +517,16 @@ namespace ts { } } - return arrayFrom(mapDefinedIterator(seenMap.keys(), path => programOfThisState.getSourceFileByPath(path)?.fileName ?? path)); + return ts.arrayFrom(ts.mapDefinedIterator(seenMap.keys(), path => programOfThisState.getSourceFileByPath(path)?.fileName ?? path)); } /** * Gets the names of all files from the program */ - function getAllFileNames(state: BuilderState, programOfThisState: Program): readonly string[] { + function getAllFileNames(state: BuilderState, programOfThisState: ts.Program): readonly string[] { if (!state.allFileNames) { const sourceFiles = programOfThisState.getSourceFiles(); - state.allFileNames = sourceFiles === emptyArray ? emptyArray : sourceFiles.map(file => file.fileName); + state.allFileNames = sourceFiles === ts.emptyArray ? ts.emptyArray : sourceFiles.map(file => file.fileName); } return state.allFileNames; } @@ -536,9 +534,9 @@ namespace ts { /** * Gets the files referenced by the the file path */ - export function getReferencedByPaths(state: Readonly, referencedFilePath: Path) { + export function getReferencedByPaths(state: Readonly, referencedFilePath: ts.Path) { const keys = state.referencedMap!.getKeys(referencedFilePath); - return keys ? arrayFrom(keys.keys()) : []; + return keys ? ts.arrayFrom(keys.keys()) : []; } /** @@ -547,9 +545,9 @@ namespace ts { * there are no point to rebuild all script files if these special files have changed. However, if any statement * in the file is not ambient external module, we treat it as a regular script file. */ - function containsOnlyAmbientModules(sourceFile: SourceFile) { + function containsOnlyAmbientModules(sourceFile: ts.SourceFile) { for (const statement of sourceFile.statements) { - if (!isModuleWithStringLiteralName(statement)) { + if (!ts.isModuleWithStringLiteralName(statement)) { return false; } } @@ -560,38 +558,39 @@ namespace ts { * Return true if file contains anything that augments to global scope we need to build them as if * they are global files as well as module */ - function containsGlobalScopeAugmentation(sourceFile: SourceFile) { - return some(sourceFile.moduleAugmentations, augmentation => isGlobalScopeAugmentation(augmentation.parent as ModuleDeclaration)); + function containsGlobalScopeAugmentation(sourceFile: ts.SourceFile) { + return ts.some(sourceFile.moduleAugmentations, augmentation => ts.isGlobalScopeAugmentation(augmentation.parent as ts.ModuleDeclaration)); } /** * Return true if the file will invalidate all files because it affectes global scope */ - function isFileAffectingGlobalScope(sourceFile: SourceFile) { + function isFileAffectingGlobalScope(sourceFile: ts.SourceFile) { return containsGlobalScopeAugmentation(sourceFile) || - !isExternalOrCommonJsModule(sourceFile) && !isJsonSourceFile(sourceFile) && !containsOnlyAmbientModules(sourceFile); + !ts.isExternalOrCommonJsModule(sourceFile) && !ts.isJsonSourceFile(sourceFile) && !containsOnlyAmbientModules(sourceFile); } /** * Gets all files of the program excluding the default library file */ - export function getAllFilesExcludingDefaultLibraryFile(state: BuilderState, programOfThisState: Program, firstSourceFile: SourceFile | undefined): readonly SourceFile[] { + export function getAllFilesExcludingDefaultLibraryFile(state: BuilderState, programOfThisState: ts.Program, firstSourceFile: ts.SourceFile | undefined): readonly ts.SourceFile[] { // Use cached result if (state.allFilesExcludingDefaultLibraryFile) { return state.allFilesExcludingDefaultLibraryFile; } - let result: SourceFile[] | undefined; - if (firstSourceFile) addSourceFile(firstSourceFile); + let result: ts.SourceFile[] | undefined; + if (firstSourceFile) + addSourceFile(firstSourceFile); for (const sourceFile of programOfThisState.getSourceFiles()) { if (sourceFile !== firstSourceFile) { addSourceFile(sourceFile); } } - state.allFilesExcludingDefaultLibraryFile = result || emptyArray; + state.allFilesExcludingDefaultLibraryFile = result || ts.emptyArray; return state.allFilesExcludingDefaultLibraryFile; - function addSourceFile(sourceFile: SourceFile) { + function addSourceFile(sourceFile: ts.SourceFile) { if (!programOfThisState.isSourceFileDefaultLibrary(sourceFile)) { (result || (result = [])).push(sourceFile); } @@ -601,11 +600,11 @@ namespace ts { /** * When program emits non modular code, gets the files affected by the sourceFile whose shape has changed */ - function getFilesAffectedByUpdatedShapeWhenNonModuleEmit(state: BuilderState, programOfThisState: Program, sourceFileWithUpdatedShape: SourceFile) { + function getFilesAffectedByUpdatedShapeWhenNonModuleEmit(state: BuilderState, programOfThisState: ts.Program, sourceFileWithUpdatedShape: ts.SourceFile) { const compilerOptions = programOfThisState.getCompilerOptions(); // If `--out` or `--outFile` is specified, any new emit will result in re-emitting the entire project, // so returning the file itself is good enough. - if (compilerOptions && outFile(compilerOptions)) { + if (compilerOptions && ts.outFile(compilerOptions)) { return [sourceFileWithUpdatedShape]; } return getAllFilesExcludingDefaultLibraryFile(state, programOfThisState, sourceFileWithUpdatedShape); @@ -614,20 +613,20 @@ namespace ts { /** * When program emits modular code, gets the files affected by the sourceFile whose shape has changed */ - function getFilesAffectedByUpdatedShapeWhenModuleEmit(state: BuilderState, programOfThisState: Program, sourceFileWithUpdatedShape: SourceFile, cacheToUpdateSignature: ESMap, cancellationToken: CancellationToken | undefined, computeHash: ComputeHash, exportedModulesMapCache: ManyToManyPathMap | undefined) { + function getFilesAffectedByUpdatedShapeWhenModuleEmit(state: BuilderState, programOfThisState: ts.Program, sourceFileWithUpdatedShape: ts.SourceFile, cacheToUpdateSignature: ts.ESMap, cancellationToken: ts.CancellationToken | undefined, computeHash: ComputeHash, exportedModulesMapCache: ManyToManyPathMap | undefined) { if (isFileAffectingGlobalScope(sourceFileWithUpdatedShape)) { return getAllFilesExcludingDefaultLibraryFile(state, programOfThisState, sourceFileWithUpdatedShape); } const compilerOptions = programOfThisState.getCompilerOptions(); - if (compilerOptions && (compilerOptions.isolatedModules || outFile(compilerOptions))) { + if (compilerOptions && (compilerOptions.isolatedModules || ts.outFile(compilerOptions))) { return [sourceFileWithUpdatedShape]; } // Now we need to if each file in the referencedBy list has a shape change as well. // Because if so, its own referencedBy files need to be saved as well to make the // emitting result consistent with files on disk. - const seenFileNamesMap = new Map(); + const seenFileNamesMap = new ts.Map(); // Start with the paths this file was referenced by seenFileNamesMap.set(sourceFileWithUpdatedShape.resolvedPath, sourceFileWithUpdatedShape); @@ -644,7 +643,7 @@ namespace ts { } // Return array of values that needs emit - return arrayFrom(mapDefinedIterator(seenFileNamesMap.values(), value => value)); + return ts.arrayFrom(ts.mapDefinedIterator(seenFileNamesMap.values(), value => value)); } } } diff --git a/src/compiler/builderStatePublic.ts b/src/compiler/builderStatePublic.ts index ce542b0825b80..2b447d3264530 100644 --- a/src/compiler/builderStatePublic.ts +++ b/src/compiler/builderStatePublic.ts @@ -2,8 +2,8 @@ namespace ts { export interface EmitOutput { outputFiles: OutputFile[]; emitSkipped: boolean; - /* @internal */ diagnostics: readonly Diagnostic[]; - /* @internal */ exportedModulesFromDeclarationEmit?: ExportedModulesFromDeclarationEmit; + /* @internal */ diagnostics: readonly ts.Diagnostic[]; + /* @internal */ exportedModulesFromDeclarationEmit?: ts.ExportedModulesFromDeclarationEmit; } export interface OutputFile { diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index ef86d21a4df67..d16a95b20c400 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -1,7 +1,7 @@ /* @internal */ namespace ts { const ambientModuleSymbolRegex = /^".+"$/; - const anon = "(anonymous)" as __String & string; + const anon = "(anonymous)" as ts.__String & string; let nextSymbolId = 1; let nextNodeId = 1; @@ -30,63 +30,63 @@ namespace ts { AsyncYieldStar = AllowsSyncIterablesFlag | AllowsAsyncIterablesFlag | YieldStarFlag, GeneratorReturnType = AllowsSyncIterablesFlag, - AsyncGeneratorReturnType = AllowsAsyncIterablesFlag, + AsyncGeneratorReturnType = AllowsAsyncIterablesFlag } const enum IterationTypeKind { Yield, Return, - Next, + Next } interface IterationTypesResolver { iterableCacheKey: "iterationTypesOfAsyncIterable" | "iterationTypesOfIterable"; iteratorCacheKey: "iterationTypesOfAsyncIterator" | "iterationTypesOfIterator"; iteratorSymbolName: "asyncIterator" | "iterator"; - getGlobalIteratorType: (reportErrors: boolean) => GenericType; - getGlobalIterableType: (reportErrors: boolean) => GenericType; - getGlobalIterableIteratorType: (reportErrors: boolean) => GenericType; - getGlobalGeneratorType: (reportErrors: boolean) => GenericType; - resolveIterationType: (type: Type, errorNode: Node | undefined) => Type | undefined; - mustHaveANextMethodDiagnostic: DiagnosticMessage; - mustBeAMethodDiagnostic: DiagnosticMessage; - mustHaveAValueDiagnostic: DiagnosticMessage; + getGlobalIteratorType: (reportErrors: boolean) => ts.GenericType; + getGlobalIterableType: (reportErrors: boolean) => ts.GenericType; + getGlobalIterableIteratorType: (reportErrors: boolean) => ts.GenericType; + getGlobalGeneratorType: (reportErrors: boolean) => ts.GenericType; + resolveIterationType: (type: ts.Type, errorNode: ts.Node | undefined) => ts.Type | undefined; + mustHaveANextMethodDiagnostic: ts.DiagnosticMessage; + mustBeAMethodDiagnostic: ts.DiagnosticMessage; + mustHaveAValueDiagnostic: ts.DiagnosticMessage; } const enum WideningKind { Normal, FunctionReturn, GeneratorNext, - GeneratorYield, + GeneratorYield } const enum TypeFacts { None = 0, - TypeofEQString = 1 << 0, // typeof x === "string" - TypeofEQNumber = 1 << 1, // typeof x === "number" - TypeofEQBigInt = 1 << 2, // typeof x === "bigint" - TypeofEQBoolean = 1 << 3, // typeof x === "boolean" - TypeofEQSymbol = 1 << 4, // typeof x === "symbol" - TypeofEQObject = 1 << 5, // typeof x === "object" - TypeofEQFunction = 1 << 6, // typeof x === "function" - TypeofEQHostObject = 1 << 7, // typeof x === "xxx" - TypeofNEString = 1 << 8, // typeof x !== "string" - TypeofNENumber = 1 << 9, // typeof x !== "number" - TypeofNEBigInt = 1 << 10, // typeof x !== "bigint" - TypeofNEBoolean = 1 << 11, // typeof x !== "boolean" - TypeofNESymbol = 1 << 12, // typeof x !== "symbol" - TypeofNEObject = 1 << 13, // typeof x !== "object" - TypeofNEFunction = 1 << 14, // typeof x !== "function" - TypeofNEHostObject = 1 << 15, // typeof x !== "xxx" - EQUndefined = 1 << 16, // x === undefined - EQNull = 1 << 17, // x === null - EQUndefinedOrNull = 1 << 18, // x === undefined / x === null - NEUndefined = 1 << 19, // x !== undefined - NENull = 1 << 20, // x !== null - NEUndefinedOrNull = 1 << 21, // x != undefined / x != null - Truthy = 1 << 22, // x - Falsy = 1 << 23, // !x + TypeofEQString = 1 << 0, + TypeofEQNumber = 1 << 1, + TypeofEQBigInt = 1 << 2, + TypeofEQBoolean = 1 << 3, + TypeofEQSymbol = 1 << 4, + TypeofEQObject = 1 << 5, + TypeofEQFunction = 1 << 6, + TypeofEQHostObject = 1 << 7, + TypeofNEString = 1 << 8, + TypeofNENumber = 1 << 9, + TypeofNEBigInt = 1 << 10, + TypeofNEBoolean = 1 << 11, + TypeofNESymbol = 1 << 12, + TypeofNEObject = 1 << 13, + TypeofNEFunction = 1 << 14, + TypeofNEHostObject = 1 << 15, + EQUndefined = 1 << 16, + EQNull = 1 << 17, + EQUndefinedOrNull = 1 << 18, + NEUndefined = 1 << 19, + NENull = 1 << 20, + NEUndefinedOrNull = 1 << 21, + Truthy = 1 << 22, + Falsy = 1 << 23, All = (1 << 24) - 1, // The following members encode facts about particular kinds of types for use in the getTypeFacts function. // The presence of a particular fact means that the given test is true for some (and possibly all) values @@ -136,10 +136,10 @@ namespace ts { EmptyObjectFacts = All, // Masks OrFactsMask = TypeofEQFunction | TypeofNEObject, - AndFactsMask = All & ~OrFactsMask, + AndFactsMask = All & ~OrFactsMask } - const typeofEQFacts: ReadonlyESMap = new Map(getEntries({ + const typeofEQFacts: ts.ReadonlyESMap = new ts.Map(ts.getEntries({ string: TypeFacts.TypeofEQString, number: TypeFacts.TypeofEQNumber, bigint: TypeFacts.TypeofEQBigInt, @@ -150,7 +150,7 @@ namespace ts { function: TypeFacts.TypeofEQFunction })); - const typeofNEFacts: ReadonlyESMap = new Map(getEntries({ + const typeofNEFacts: ts.ReadonlyESMap = new ts.Map(ts.getEntries({ string: TypeFacts.TypeofNEString, number: TypeFacts.TypeofNENumber, bigint: TypeFacts.TypeofNEBigInt, @@ -161,7 +161,7 @@ namespace ts { function: TypeFacts.TypeofNEFunction })); - type TypeSystemEntity = Node | Symbol | Type | Signature; + type TypeSystemEntity = ts.Node | ts.Symbol | ts.Type | ts.Signature; const enum TypeSystemPropertyName { Type, @@ -172,20 +172,18 @@ namespace ts { EnumTagType, ResolvedTypeArguments, ResolvedBaseTypes, - WriteType, + WriteType } const enum CheckMode { - Normal = 0, // Normal type checking - Contextual = 1 << 0, // Explicitly assigned contextual type, therefore not cacheable - Inferential = 1 << 1, // Inferential typing - SkipContextSensitive = 1 << 2, // Skip context sensitive function expressions - SkipGenericFunctions = 1 << 3, // Skip single signature generic functions - IsForSignatureHelp = 1 << 4, // Call resolution for purposes of signature help - IsForStringLiteralArgumentCompletions = 1 << 5, // Do not infer from the argument currently being typed - RestBindingElement = 1 << 6, // Checking a type that is going to be used to determine the type of a rest binding element - // e.g. in `const { a, ...rest } = foo`, when checking the type of `foo` to determine the type of `rest`, - // we need to preserve generic types instead of substituting them for constraints + Normal = 0, + Contextual = 1 << 0, + Inferential = 1 << 1, + SkipContextSensitive = 1 << 2, + SkipGenericFunctions = 1 << 3, + IsForSignatureHelp = 1 << 4, + IsForStringLiteralArgumentCompletions = 1 << 5, + RestBindingElement = 1 << 6 } const enum SignatureCheckMode { @@ -193,7 +191,7 @@ namespace ts { StrictCallback = 1 << 1, IgnoreReturnTypes = 1 << 2, StrictArity = 1 << 3, - Callback = BivariantCallback | StrictCallback, + Callback = BivariantCallback | StrictCallback } const enum IntersectionState { @@ -201,28 +199,28 @@ namespace ts { Source = 1 << 0, Target = 1 << 1, PropertyCheck = 1 << 2, - InPropertyCheck = 1 << 3, + InPropertyCheck = 1 << 3 } const enum RecursionFlags { None = 0, Source = 1 << 0, Target = 1 << 1, - Both = Source | Target, + Both = Source | Target } const enum MappedTypeModifiers { IncludeReadonly = 1 << 0, ExcludeReadonly = 1 << 1, IncludeOptional = 1 << 2, - ExcludeOptional = 1 << 3, + ExcludeOptional = 1 << 3 } const enum ExpandingFlags { None = 0, Source = 1, Target = 1 << 1, - Both = Source | Target, + Both = Source | Target } const enum MembersOrExportsResolutionKind { @@ -232,13 +230,12 @@ namespace ts { const enum UnusedKind { Local, - Parameter, + Parameter } /** @param containingNode Node to check for parse error */ - type AddUnusedDiagnostic = (containingNode: Node, type: UnusedKind, diagnostic: DiagnosticWithLocation) => void; - - const isNotOverloadAndNotAccessor = and(isNotOverload, isNotAccessor); + type AddUnusedDiagnostic = (containingNode: ts.Node, type: UnusedKind, diagnostic: ts.DiagnosticWithLocation) => void; + const isNotOverloadAndNotAccessor = ts.and(isNotOverload, isNotAccessor); const enum DeclarationMeaning { GetAccessor = 1, @@ -247,20 +244,20 @@ namespace ts { Method = 8, PrivateStatic = 16, GetOrSetAccessor = GetAccessor | SetAccessor, - PropertyAssignmentOrMethod = PropertyAssignment | Method, + PropertyAssignmentOrMethod = PropertyAssignment | Method } const enum DeclarationSpaces { None = 0, ExportValue = 1 << 0, ExportType = 1 << 1, - ExportNamespace = 1 << 2, + ExportNamespace = 1 << 2 } const enum MinArgumentCountFlags { None = 0, StrongArityForUntypedJS = 1 << 0, - VoidIsNonOptional = 1 << 1, + VoidIsNonOptional = 1 << 1 } const enum IntrinsicTypeKind { @@ -270,21 +267,21 @@ namespace ts { Uncapitalize } - const intrinsicTypeKinds: ReadonlyESMap = new Map(getEntries({ + const intrinsicTypeKinds: ts.ReadonlyESMap = new ts.Map(ts.getEntries({ Uppercase: IntrinsicTypeKind.Uppercase, Lowercase: IntrinsicTypeKind.Lowercase, Capitalize: IntrinsicTypeKind.Capitalize, Uncapitalize: IntrinsicTypeKind.Uncapitalize })); - function SymbolLinks(this: SymbolLinks) { + function SymbolLinks(this: ts.SymbolLinks) { } - function NodeLinks(this: NodeLinks) { + function NodeLinks(this: ts.NodeLinks) { this.flags = 0; } - export function getNodeId(node: Node): number { + export function getNodeId(node: ts.Node): number { if (!node.id) { node.id = nextNodeId; nextNodeId++; @@ -292,7 +289,7 @@ namespace ts { return node.id; } - export function getSymbolId(symbol: Symbol): SymbolId { + export function getSymbolId(symbol: ts.Symbol): ts.SymbolId { if (!symbol.id) { symbol.id = nextSymbolId; nextSymbolId++; @@ -301,24 +298,26 @@ namespace ts { return symbol.id; } - export function isInstantiatedModule(node: ModuleDeclaration, preserveConstEnums: boolean) { - const moduleState = getModuleInstanceState(node); - return moduleState === ModuleInstanceState.Instantiated || - (preserveConstEnums && moduleState === ModuleInstanceState.ConstEnumOnly); + export function isInstantiatedModule(node: ts.ModuleDeclaration, preserveConstEnums: boolean) { + const moduleState = ts.getModuleInstanceState(node); + return moduleState === ts.ModuleInstanceState.Instantiated || + (preserveConstEnums && moduleState === ts.ModuleInstanceState.ConstEnumOnly); } - export function createTypeChecker(host: TypeCheckerHost): TypeChecker { - const getPackagesMap = memoize(() => { + export function createTypeChecker(host: ts.TypeCheckerHost): ts.TypeChecker { + const getPackagesMap = ts.memoize(() => { // A package name maps to true when we detect it has .d.ts files. // This is useful as an approximation of whether a package bundles its own types. // Note: we only look at files already found by module resolution, // so there may be files we did not consider. - const map = new Map(); + const map = new ts.Map(); host.getSourceFiles().forEach(sf => { - if (!sf.resolvedModules) return; + if (!sf.resolvedModules) + return; sf.resolvedModules.forEach(r => { - if (r && r.packageId) map.set(r.packageId.name, r.extension === Extension.Dts || !!map.get(r.packageId.name)); + if (r && r.packageId) + map.set(r.packageId.name, r.extension === ts.Extension.Dts || !!map.get(r.packageId.name)); }); }); return map; @@ -339,13 +338,12 @@ namespace ts { // Currently we only support setting the cancellation token when getting diagnostics. This // is because diagnostics can be quite expensive, and we want to allow hosts to bail out if // they no longer need the information (for example, if the user started editing again). - let cancellationToken: CancellationToken | undefined; - let requestedExternalEmitHelpers: ExternalEmitHelpers; - let externalHelpersModule: Symbol; - - const Symbol = objectAllocator.getSymbolConstructor(); - const Type = objectAllocator.getTypeConstructor(); - const Signature = objectAllocator.getSignatureConstructor(); + let cancellationToken: ts.CancellationToken | undefined; + let requestedExternalEmitHelpers: ts.ExternalEmitHelpers; + let externalHelpersModule: ts.Symbol; + const Symbol = ts.objectAllocator.getSymbolConstructor(); + const Type = ts.objectAllocator.getTypeConstructor(); + const Signature = ts.objectAllocator.getSignatureConstructor(); let typeCount = 0; let symbolCount = 0; @@ -354,43 +352,42 @@ namespace ts { let instantiationCount = 0; let instantiationDepth = 0; let inlineLevel = 0; - let currentNode: Node | undefined; - let varianceTypeParameter: TypeParameter | undefined; - - const emptySymbols = createSymbolTable(); - const arrayVariances = [VarianceFlags.Covariant]; + let currentNode: ts.Node | undefined; + let varianceTypeParameter: ts.TypeParameter | undefined; + const emptySymbols = ts.createSymbolTable(); + const arrayVariances = [ts.VarianceFlags.Covariant]; const compilerOptions = host.getCompilerOptions(); - const languageVersion = getEmitScriptTarget(compilerOptions); - const moduleKind = getEmitModuleKind(compilerOptions); - const useDefineForClassFields = getUseDefineForClassFields(compilerOptions); - const allowSyntheticDefaultImports = getAllowSyntheticDefaultImports(compilerOptions); - const strictNullChecks = getStrictOptionValue(compilerOptions, "strictNullChecks"); - const strictFunctionTypes = getStrictOptionValue(compilerOptions, "strictFunctionTypes"); - const strictBindCallApply = getStrictOptionValue(compilerOptions, "strictBindCallApply"); - const strictPropertyInitialization = getStrictOptionValue(compilerOptions, "strictPropertyInitialization"); - const noImplicitAny = getStrictOptionValue(compilerOptions, "noImplicitAny"); - const noImplicitThis = getStrictOptionValue(compilerOptions, "noImplicitThis"); - const useUnknownInCatchVariables = getStrictOptionValue(compilerOptions, "useUnknownInCatchVariables"); + const languageVersion = ts.getEmitScriptTarget(compilerOptions); + const moduleKind = ts.getEmitModuleKind(compilerOptions); + const useDefineForClassFields = ts.getUseDefineForClassFields(compilerOptions); + const allowSyntheticDefaultImports = ts.getAllowSyntheticDefaultImports(compilerOptions); + const strictNullChecks = ts.getStrictOptionValue(compilerOptions, "strictNullChecks"); + const strictFunctionTypes = ts.getStrictOptionValue(compilerOptions, "strictFunctionTypes"); + const strictBindCallApply = ts.getStrictOptionValue(compilerOptions, "strictBindCallApply"); + const strictPropertyInitialization = ts.getStrictOptionValue(compilerOptions, "strictPropertyInitialization"); + const noImplicitAny = ts.getStrictOptionValue(compilerOptions, "noImplicitAny"); + const noImplicitThis = ts.getStrictOptionValue(compilerOptions, "noImplicitThis"); + const useUnknownInCatchVariables = ts.getStrictOptionValue(compilerOptions, "useUnknownInCatchVariables"); const keyofStringsOnly = !!compilerOptions.keyofStringsOnly; - const freshObjectLiteralFlag = compilerOptions.suppressExcessPropertyErrors ? 0 : ObjectFlags.FreshLiteral; + const freshObjectLiteralFlag = compilerOptions.suppressExcessPropertyErrors ? 0 : ts.ObjectFlags.FreshLiteral; const exactOptionalPropertyTypes = compilerOptions.exactOptionalPropertyTypes; const checkBinaryExpression = createCheckBinaryExpression(); const emitResolver = createResolver(); const nodeBuilder = createNodeBuilder(); - const globals = createSymbolTable(); - const undefinedSymbol = createSymbol(SymbolFlags.Property, "undefined" as __String); + const globals = ts.createSymbolTable(); + const undefinedSymbol = createSymbol(ts.SymbolFlags.Property, "undefined" as ts.__String); undefinedSymbol.declarations = []; - const globalThisSymbol = createSymbol(SymbolFlags.Module, "globalThis" as __String, CheckFlags.Readonly); + const globalThisSymbol = createSymbol(ts.SymbolFlags.Module, "globalThis" as ts.__String, ts.CheckFlags.Readonly); globalThisSymbol.exports = globals; globalThisSymbol.declarations = []; globals.set(globalThisSymbol.escapedName, globalThisSymbol); - const argumentsSymbol = createSymbol(SymbolFlags.Property, "arguments" as __String); - const requireSymbol = createSymbol(SymbolFlags.Property, "require" as __String); + const argumentsSymbol = createSymbol(ts.SymbolFlags.Property, "arguments" as ts.__String); + const requireSymbol = createSymbol(ts.SymbolFlags.Property, "require" as ts.__String); /** This will be set during calls to `getResolvedSignature` where services determines an apparent number of arguments greater than what is actually provided. */ let apparentArgumentCount: number | undefined; @@ -400,10 +397,10 @@ namespace ts { // for most of these, we perform the guard only on `checker` to avoid any possible // extra cost of calling `getParseTreeNode` when calling these functions from inside the // checker. - const checker: TypeChecker = { - getNodeCount: () => sum(host.getSourceFiles(), "nodeCount"), - getIdentifierCount: () => sum(host.getSourceFiles(), "identifierCount"), - getSymbolCount: () => sum(host.getSourceFiles(), "symbolCount") + symbolCount, + const checker: ts.TypeChecker = { + getNodeCount: () => ts.sum(host.getSourceFiles(), "nodeCount"), + getIdentifierCount: () => ts.sum(host.getSourceFiles(), "identifierCount"), + getSymbolCount: () => ts.sum(host.getSourceFiles(), "symbolCount") + symbolCount, getTypeCount: () => typeCount, getInstantiationCount: () => totalInstantiationCount, getRelationCacheSizes: () => ({ @@ -421,38 +418,39 @@ namespace ts { getRecursionIdentity, getUnmatchedProperties, getTypeOfSymbolAtLocation: (symbol, locationIn) => { - const location = getParseTreeNode(locationIn); + const location = ts.getParseTreeNode(locationIn); return location ? getTypeOfSymbolAtLocation(symbol, location) : errorType; }, getTypeOfSymbol, getSymbolsOfParameterPropertyDeclaration: (parameterIn, parameterName) => { - const parameter = getParseTreeNode(parameterIn, isParameter); - if (parameter === undefined) return Debug.fail("Cannot get symbols of a synthetic parameter that cannot be resolved to a parse-tree node."); - return getSymbolsOfParameterPropertyDeclaration(parameter, escapeLeadingUnderscores(parameterName)); + const parameter = ts.getParseTreeNode(parameterIn, ts.isParameter); + if (parameter === undefined) + return ts.Debug.fail("Cannot get symbols of a synthetic parameter that cannot be resolved to a parse-tree node."); + return getSymbolsOfParameterPropertyDeclaration(parameter, ts.escapeLeadingUnderscores(parameterName)); }, getDeclaredTypeOfSymbol, getPropertiesOfType, - getPropertyOfType: (type, name) => getPropertyOfType(type, escapeLeadingUnderscores(name)), - getPrivateIdentifierPropertyOfType: (leftType: Type, name: string, location: Node) => { - const node = getParseTreeNode(location); + getPropertyOfType: (type, name) => getPropertyOfType(type, ts.escapeLeadingUnderscores(name)), + getPrivateIdentifierPropertyOfType: (leftType: ts.Type, name: string, location: ts.Node) => { + const node = ts.getParseTreeNode(location); if (!node) { return undefined; } - const propName = escapeLeadingUnderscores(name); + const propName = ts.escapeLeadingUnderscores(name); const lexicallyScopedIdentifier = lookupSymbolForPrivateIdentifierDeclaration(propName, node); return lexicallyScopedIdentifier ? getPrivateIdentifierPropertyOfType(leftType, lexicallyScopedIdentifier) : undefined; }, - getTypeOfPropertyOfType: (type, name) => getTypeOfPropertyOfType(type, escapeLeadingUnderscores(name)), - getIndexInfoOfType: (type, kind) => getIndexInfoOfType(type, kind === IndexKind.String ? stringType : numberType), + getTypeOfPropertyOfType: (type, name) => getTypeOfPropertyOfType(type, ts.escapeLeadingUnderscores(name)), + getIndexInfoOfType: (type, kind) => getIndexInfoOfType(type, kind === ts.IndexKind.String ? stringType : numberType), getIndexInfosOfType, getSignaturesOfType, - getIndexTypeOfType: (type, kind) => getIndexTypeOfType(type, kind === IndexKind.String ? stringType : numberType), + getIndexTypeOfType: (type, kind) => getIndexTypeOfType(type, kind === ts.IndexKind.String ? stringType : numberType), getIndexType: type => getIndexType(type), getBaseTypes, getBaseTypeOfLiteralType, getWidenedType, getTypeFromTypeNode: nodeIn => { - const node = getParseTreeNode(nodeIn, isTypeNode); + const node = ts.getParseTreeNode(nodeIn, ts.isTypeNode); return node ? getTypeFromTypeNode(node) : errorType; }, getParameterType: getTypeAtPosition, @@ -474,120 +472,117 @@ namespace ts { symbolToParameterDeclaration: nodeBuilder.symbolToParameterDeclaration, typeParameterToDeclaration: nodeBuilder.typeParameterToDeclaration, getSymbolsInScope: (locationIn, meaning) => { - const location = getParseTreeNode(locationIn); + const location = ts.getParseTreeNode(locationIn); return location ? getSymbolsInScope(location, meaning) : []; }, getSymbolAtLocation: nodeIn => { - const node = getParseTreeNode(nodeIn); + const node = ts.getParseTreeNode(nodeIn); // set ignoreErrors: true because any lookups invoked by the API shouldn't cause any new errors return node ? getSymbolAtLocation(node, /*ignoreErrors*/ true) : undefined; }, getIndexInfosAtLocation: nodeIn => { - const node = getParseTreeNode(nodeIn); + const node = ts.getParseTreeNode(nodeIn); return node ? getIndexInfosAtLocation(node) : undefined; }, getShorthandAssignmentValueSymbol: nodeIn => { - const node = getParseTreeNode(nodeIn); + const node = ts.getParseTreeNode(nodeIn); return node ? getShorthandAssignmentValueSymbol(node) : undefined; }, getExportSpecifierLocalTargetSymbol: nodeIn => { - const node = getParseTreeNode(nodeIn, isExportSpecifier); + const node = ts.getParseTreeNode(nodeIn, ts.isExportSpecifier); return node ? getExportSpecifierLocalTargetSymbol(node) : undefined; }, getExportSymbolOfSymbol(symbol) { return getMergedSymbol(symbol.exportSymbol || symbol); }, getTypeAtLocation: nodeIn => { - const node = getParseTreeNode(nodeIn); + const node = ts.getParseTreeNode(nodeIn); return node ? getTypeOfNode(node) : errorType; }, getTypeOfAssignmentPattern: nodeIn => { - const node = getParseTreeNode(nodeIn, isAssignmentPattern); + const node = ts.getParseTreeNode(nodeIn, ts.isAssignmentPattern); return node && getTypeOfAssignmentPattern(node) || errorType; }, getPropertySymbolOfDestructuringAssignment: locationIn => { - const location = getParseTreeNode(locationIn, isIdentifier); + const location = ts.getParseTreeNode(locationIn, ts.isIdentifier); return location ? getPropertySymbolOfDestructuringAssignment(location) : undefined; }, signatureToString: (signature, enclosingDeclaration, flags, kind) => { - return signatureToString(signature, getParseTreeNode(enclosingDeclaration), flags, kind); + return signatureToString(signature, ts.getParseTreeNode(enclosingDeclaration), flags, kind); }, typeToString: (type, enclosingDeclaration, flags) => { - return typeToString(type, getParseTreeNode(enclosingDeclaration), flags); + return typeToString(type, ts.getParseTreeNode(enclosingDeclaration), flags); }, symbolToString: (symbol, enclosingDeclaration, meaning, flags) => { - return symbolToString(symbol, getParseTreeNode(enclosingDeclaration), meaning, flags); + return symbolToString(symbol, ts.getParseTreeNode(enclosingDeclaration), meaning, flags); }, typePredicateToString: (predicate, enclosingDeclaration, flags) => { - return typePredicateToString(predicate, getParseTreeNode(enclosingDeclaration), flags); + return typePredicateToString(predicate, ts.getParseTreeNode(enclosingDeclaration), flags); }, writeSignature: (signature, enclosingDeclaration, flags, kind, writer) => { - return signatureToString(signature, getParseTreeNode(enclosingDeclaration), flags, kind, writer); + return signatureToString(signature, ts.getParseTreeNode(enclosingDeclaration), flags, kind, writer); }, writeType: (type, enclosingDeclaration, flags, writer) => { - return typeToString(type, getParseTreeNode(enclosingDeclaration), flags, writer); + return typeToString(type, ts.getParseTreeNode(enclosingDeclaration), flags, writer); }, writeSymbol: (symbol, enclosingDeclaration, meaning, flags, writer) => { - return symbolToString(symbol, getParseTreeNode(enclosingDeclaration), meaning, flags, writer); + return symbolToString(symbol, ts.getParseTreeNode(enclosingDeclaration), meaning, flags, writer); }, writeTypePredicate: (predicate, enclosingDeclaration, flags, writer) => { - return typePredicateToString(predicate, getParseTreeNode(enclosingDeclaration), flags, writer); + return typePredicateToString(predicate, ts.getParseTreeNode(enclosingDeclaration), flags, writer); }, getAugmentedPropertiesOfType, getRootSymbols, getSymbolOfExpando, - getContextualType: (nodeIn: Expression, contextFlags?: ContextFlags) => { - const node = getParseTreeNode(nodeIn, isExpression); + getContextualType: (nodeIn: ts.Expression, contextFlags?: ts.ContextFlags) => { + const node = ts.getParseTreeNode(nodeIn, ts.isExpression); if (!node) { return undefined; } - if (contextFlags! & ContextFlags.Completions) { + if (contextFlags! & ts.ContextFlags.Completions) { return runWithInferenceBlockedFromSourceNode(node, () => getContextualType(node, contextFlags)); } return getContextualType(node, contextFlags); }, getContextualTypeForObjectLiteralElement: nodeIn => { - const node = getParseTreeNode(nodeIn, isObjectLiteralElementLike); + const node = ts.getParseTreeNode(nodeIn, ts.isObjectLiteralElementLike); return node ? getContextualTypeForObjectLiteralElement(node) : undefined; }, getContextualTypeForArgumentAtIndex: (nodeIn, argIndex) => { - const node = getParseTreeNode(nodeIn, isCallLikeExpression); + const node = ts.getParseTreeNode(nodeIn, ts.isCallLikeExpression); return node && getContextualTypeForArgumentAtIndex(node, argIndex); }, getContextualTypeForJsxAttribute: (nodeIn) => { - const node = getParseTreeNode(nodeIn, isJsxAttributeLike); + const node = ts.getParseTreeNode(nodeIn, ts.isJsxAttributeLike); return node && getContextualTypeForJsxAttribute(node); }, isContextSensitive, getTypeOfPropertyOfContextualType, getFullyQualifiedName, - getResolvedSignature: (node, candidatesOutArray, argumentCount) => - getResolvedSignatureWorker(node, candidatesOutArray, argumentCount, CheckMode.Normal), - getResolvedSignatureForStringLiteralCompletions: (call, editingArgument, candidatesOutArray) => - getResolvedSignatureWorker(call, candidatesOutArray, /*argumentCount*/ undefined, CheckMode.IsForStringLiteralArgumentCompletions, editingArgument), - getResolvedSignatureForSignatureHelp: (node, candidatesOutArray, argumentCount) => - getResolvedSignatureWorker(node, candidatesOutArray, argumentCount, CheckMode.IsForSignatureHelp), + getResolvedSignature: (node, candidatesOutArray, argumentCount) => getResolvedSignatureWorker(node, candidatesOutArray, argumentCount, CheckMode.Normal), + getResolvedSignatureForStringLiteralCompletions: (call, editingArgument, candidatesOutArray) => getResolvedSignatureWorker(call, candidatesOutArray, /*argumentCount*/ undefined, CheckMode.IsForStringLiteralArgumentCompletions, editingArgument), + getResolvedSignatureForSignatureHelp: (node, candidatesOutArray, argumentCount) => getResolvedSignatureWorker(node, candidatesOutArray, argumentCount, CheckMode.IsForSignatureHelp), getExpandedParameters, hasEffectiveRestParameter, containsArgumentsReference, getConstantValue: nodeIn => { - const node = getParseTreeNode(nodeIn, canHaveConstantValue); + const node = ts.getParseTreeNode(nodeIn, canHaveConstantValue); return node ? getConstantValue(node) : undefined; }, isValidPropertyAccess: (nodeIn, propertyName) => { - const node = getParseTreeNode(nodeIn, isPropertyAccessOrQualifiedNameOrImportTypeNode); - return !!node && isValidPropertyAccess(node, escapeLeadingUnderscores(propertyName)); + const node = ts.getParseTreeNode(nodeIn, ts.isPropertyAccessOrQualifiedNameOrImportTypeNode); + return !!node && isValidPropertyAccess(node, ts.escapeLeadingUnderscores(propertyName)); }, isValidPropertyAccessForCompletions: (nodeIn, type, property) => { - const node = getParseTreeNode(nodeIn, isPropertyAccessExpression); + const node = ts.getParseTreeNode(nodeIn, ts.isPropertyAccessExpression); return !!node && isValidPropertyAccessForCompletions(node, type, property); }, getSignatureFromDeclaration: declarationIn => { - const declaration = getParseTreeNode(declarationIn, isFunctionLike); + const declaration = ts.getParseTreeNode(declarationIn, ts.isFunctionLike); return declaration ? getSignatureFromDeclaration(declaration) : undefined; }, isImplementationOfOverload: nodeIn => { - const node = getParseTreeNode(nodeIn, isFunctionLike); + const node = ts.getParseTreeNode(nodeIn, ts.isFunctionLike); return node ? isImplementationOfOverload(node) : undefined; }, getImmediateAliasedSymbol, @@ -596,26 +591,15 @@ namespace ts { getExportsOfModule: getExportsOfModuleAsArray, getExportsAndPropertiesOfModule, forEachExportAndPropertyOfModule, - getSymbolWalker: createGetSymbolWalker( - getRestTypeOfSignature, - getTypePredicateOfSignature, - getReturnTypeOfSignature, - getBaseTypes, - resolveStructuredTypeMembers, - getTypeOfSymbol, - getResolvedSymbol, - getConstraintOfTypeParameter, - getFirstIdentifier, - getTypeArguments, - ), + getSymbolWalker: ts.createGetSymbolWalker(getRestTypeOfSignature, getTypePredicateOfSignature, getReturnTypeOfSignature, getBaseTypes, resolveStructuredTypeMembers, getTypeOfSymbol, getResolvedSymbol, getConstraintOfTypeParameter, ts.getFirstIdentifier, getTypeArguments), getAmbientModules, getJsxIntrinsicTagNamesAt, isOptionalParameter: nodeIn => { - const node = getParseTreeNode(nodeIn, isParameter); + const node = ts.getParseTreeNode(nodeIn, ts.isParameter); return node ? isOptionalParameter(node) : false; }, - tryGetMemberInModuleExports: (name, symbol) => tryGetMemberInModuleExports(escapeLeadingUnderscores(name), symbol), - tryGetMemberInModuleExportsAndProperties: (name, symbol) => tryGetMemberInModuleExportsAndProperties(escapeLeadingUnderscores(name), symbol), + tryGetMemberInModuleExports: (name, symbol) => tryGetMemberInModuleExports(ts.escapeLeadingUnderscores(name), symbol), + tryGetMemberInModuleExportsAndProperties: (name, symbol) => tryGetMemberInModuleExportsAndProperties(ts.escapeLeadingUnderscores(name), symbol), tryFindAmbientModule: moduleName => tryFindAmbientModule(moduleName, /*withAugmentations*/ true), tryFindAmbientModuleWithoutAugmentations: moduleName => { // we deliberately exclude augmentations @@ -656,43 +640,43 @@ namespace ts { getSuggestedSymbolForNonexistentProperty, getSuggestionForNonexistentProperty, getSuggestedSymbolForNonexistentJSXAttribute, - getSuggestedSymbolForNonexistentSymbol: (location, name, meaning) => getSuggestedSymbolForNonexistentSymbol(location, escapeLeadingUnderscores(name), meaning), - getSuggestionForNonexistentSymbol: (location, name, meaning) => getSuggestionForNonexistentSymbol(location, escapeLeadingUnderscores(name), meaning), + getSuggestedSymbolForNonexistentSymbol: (location, name, meaning) => getSuggestedSymbolForNonexistentSymbol(location, ts.escapeLeadingUnderscores(name), meaning), + getSuggestionForNonexistentSymbol: (location, name, meaning) => getSuggestionForNonexistentSymbol(location, ts.escapeLeadingUnderscores(name), meaning), getSuggestedSymbolForNonexistentModule, getSuggestionForNonexistentExport, getSuggestedSymbolForNonexistentClassMember, getBaseConstraintOfType, - getDefaultFromTypeParameter: type => type && type.flags & TypeFlags.TypeParameter ? getDefaultFromTypeParameter(type as TypeParameter) : undefined, + getDefaultFromTypeParameter: type => type && type.flags & ts.TypeFlags.TypeParameter ? getDefaultFromTypeParameter(type as ts.TypeParameter) : undefined, resolveName(name, location, meaning, excludeGlobals) { - return resolveName(location, escapeLeadingUnderscores(name), meaning, /*nameNotFoundMessage*/ undefined, /*nameArg*/ undefined, /*isUse*/ false, excludeGlobals); + return resolveName(location, ts.escapeLeadingUnderscores(name), meaning, /*nameNotFoundMessage*/ undefined, /*nameArg*/ undefined, /*isUse*/ false, excludeGlobals); }, - getJsxNamespace: n => unescapeLeadingUnderscores(getJsxNamespace(n)), + getJsxNamespace: n => ts.unescapeLeadingUnderscores(getJsxNamespace(n)), getJsxFragmentFactory: n => { const jsxFragmentFactory = getJsxFragmentFactoryEntity(n); - return jsxFragmentFactory && unescapeLeadingUnderscores(getFirstIdentifier(jsxFragmentFactory).escapedText); + return jsxFragmentFactory && ts.unescapeLeadingUnderscores(ts.getFirstIdentifier(jsxFragmentFactory).escapedText); }, getAccessibleSymbolChain, getTypePredicateOfSignature, resolveExternalModuleName: moduleSpecifierIn => { - const moduleSpecifier = getParseTreeNode(moduleSpecifierIn, isExpression); + const moduleSpecifier = ts.getParseTreeNode(moduleSpecifierIn, ts.isExpression); return moduleSpecifier && resolveExternalModuleName(moduleSpecifier, moduleSpecifier, /*ignoreErrors*/ true); }, resolveExternalModuleSymbol, tryGetThisTypeAt: (nodeIn, includeGlobalThis) => { - const node = getParseTreeNode(nodeIn); + const node = ts.getParseTreeNode(nodeIn); return node && tryGetThisTypeAt(node, includeGlobalThis); }, getTypeArgumentConstraint: nodeIn => { - const node = getParseTreeNode(nodeIn, isTypeNode); + const node = ts.getParseTreeNode(nodeIn, ts.isTypeNode); return node && getTypeArgumentConstraint(node); }, getSuggestionDiagnostics: (fileIn, ct) => { - const file = getParseTreeNode(fileIn, isSourceFile) || Debug.fail("Could not determine parsed source file."); - if (skipTypeChecking(file, compilerOptions, host)) { - return emptyArray; + const file = ts.getParseTreeNode(fileIn, ts.isSourceFile) || ts.Debug.fail("Could not determine parsed source file."); + if (ts.skipTypeChecking(file, compilerOptions, host)) { + return ts.emptyArray; } - let diagnostics: DiagnosticWithLocation[] | undefined; + let diagnostics: ts.DiagnosticWithLocation[] | undefined; try { // Record the cancellation token so it can be checked later on during checkSourceElement. // Do this in a finally block so we can ensure that it gets reset back to nothing after @@ -701,16 +685,15 @@ namespace ts { // Ensure file is type checked, with _eager_ diagnostic production, so identifiers are registered as potentially unused checkSourceFileWithEagerDiagnostics(file); - Debug.assert(!!(getNodeLinks(file).flags & NodeCheckFlags.TypeChecked)); - - diagnostics = addRange(diagnostics, suggestionDiagnostics.getDiagnostics(file.fileName)); + ts.Debug.assert(!!(getNodeLinks(file).flags & ts.NodeCheckFlags.TypeChecked)); + diagnostics = ts.addRange(diagnostics, suggestionDiagnostics.getDiagnostics(file.fileName)); checkUnusedIdentifiers(getPotentiallyUnusedIdentifiers(file), (containingNode, kind, diag) => { - if (!containsParseError(containingNode) && !unusedIsError(kind, !!(containingNode.flags & NodeFlags.Ambient))) { - (diagnostics || (diagnostics = [])).push({ ...diag, category: DiagnosticCategory.Suggestion }); + if (!ts.containsParseError(containingNode) && !unusedIsError(kind, !!(containingNode.flags & ts.NodeFlags.Ambient))) { + (diagnostics || (diagnostics = [])).push({ ...diag, category: ts.DiagnosticCategory.Suggestion }); } }); - return diagnostics || emptyArray; + return diagnostics || ts.emptyArray; } finally { cancellationToken = undefined; @@ -734,8 +717,8 @@ namespace ts { getMemberOverrideModifierStatus, }; - function runWithInferenceBlockedFromSourceNode(node: Node | undefined, fn: () => T): T { - const containingCall = findAncestor(node, isCallLikeExpression); + function runWithInferenceBlockedFromSourceNode(node: ts.Node | undefined, fn: () => T): T { + const containingCall = ts.findAncestor(node, ts.isCallLikeExpression); const containingCallResolvedSignature = containingCall && getNodeLinks(containingCall).resolvedSignature; if (containingCall) { let toMarkSkip = node!; @@ -757,60 +740,57 @@ namespace ts { return result; } - function getResolvedSignatureWorker(nodeIn: CallLikeExpression, candidatesOutArray: Signature[] | undefined, argumentCount: number | undefined, checkMode: CheckMode, editingArgument?: Node): Signature | undefined { - const node = getParseTreeNode(nodeIn, isCallLikeExpression); + function getResolvedSignatureWorker(nodeIn: ts.CallLikeExpression, candidatesOutArray: ts.Signature[] | undefined, argumentCount: number | undefined, checkMode: CheckMode, editingArgument?: ts.Node): ts.Signature | undefined { + const node = ts.getParseTreeNode(nodeIn, ts.isCallLikeExpression); apparentArgumentCount = argumentCount; - const res = - !node ? undefined : + const res = !node ? undefined : editingArgument ? runWithInferenceBlockedFromSourceNode(editingArgument, () => getResolvedSignature(node, candidatesOutArray, checkMode)) : getResolvedSignature(node, candidatesOutArray, checkMode); apparentArgumentCount = undefined; return res; } - const tupleTypes = new Map(); - const unionTypes = new Map(); - const intersectionTypes = new Map(); - const stringLiteralTypes = new Map(); - const numberLiteralTypes = new Map(); - const bigIntLiteralTypes = new Map(); - const enumLiteralTypes = new Map(); - const indexedAccessTypes = new Map(); - const templateLiteralTypes = new Map(); - const stringMappingTypes = new Map(); - const substitutionTypes = new Map(); - const subtypeReductionCache = new Map(); - const evolvingArrayTypes: EvolvingArrayType[] = []; - const undefinedProperties: SymbolTable = new Map(); - const markerTypes = new Set(); - - const unknownSymbol = createSymbol(SymbolFlags.Property, "unknown" as __String); - const resolvingSymbol = createSymbol(0, InternalSymbolName.Resolving); - const unresolvedSymbols = new Map(); - const errorTypes = new Map(); - - const anyType = createIntrinsicType(TypeFlags.Any, "any"); - const autoType = createIntrinsicType(TypeFlags.Any, "any"); - const wildcardType = createIntrinsicType(TypeFlags.Any, "any"); - const errorType = createIntrinsicType(TypeFlags.Any, "error"); - const unresolvedType = createIntrinsicType(TypeFlags.Any, "unresolved"); - const nonInferrableAnyType = createIntrinsicType(TypeFlags.Any, "any", ObjectFlags.ContainsWideningType); - const intrinsicMarkerType = createIntrinsicType(TypeFlags.Any, "intrinsic"); - const unknownType = createIntrinsicType(TypeFlags.Unknown, "unknown"); - const nonNullUnknownType = createIntrinsicType(TypeFlags.Unknown, "unknown"); - const undefinedType = createIntrinsicType(TypeFlags.Undefined, "undefined"); - const undefinedWideningType = strictNullChecks ? undefinedType : createIntrinsicType(TypeFlags.Undefined, "undefined", ObjectFlags.ContainsWideningType); - const optionalType = createIntrinsicType(TypeFlags.Undefined, "undefined"); - const missingType = exactOptionalPropertyTypes ? createIntrinsicType(TypeFlags.Undefined, "undefined") : undefinedType; - const nullType = createIntrinsicType(TypeFlags.Null, "null"); - const nullWideningType = strictNullChecks ? nullType : createIntrinsicType(TypeFlags.Null, "null", ObjectFlags.ContainsWideningType); - const stringType = createIntrinsicType(TypeFlags.String, "string"); - const numberType = createIntrinsicType(TypeFlags.Number, "number"); - const bigintType = createIntrinsicType(TypeFlags.BigInt, "bigint"); - const falseType = createIntrinsicType(TypeFlags.BooleanLiteral, "false") as FreshableIntrinsicType; - const regularFalseType = createIntrinsicType(TypeFlags.BooleanLiteral, "false") as FreshableIntrinsicType; - const trueType = createIntrinsicType(TypeFlags.BooleanLiteral, "true") as FreshableIntrinsicType; - const regularTrueType = createIntrinsicType(TypeFlags.BooleanLiteral, "true") as FreshableIntrinsicType; + const tupleTypes = new ts.Map(); + const unionTypes = new ts.Map(); + const intersectionTypes = new ts.Map(); + const stringLiteralTypes = new ts.Map(); + const numberLiteralTypes = new ts.Map(); + const bigIntLiteralTypes = new ts.Map(); + const enumLiteralTypes = new ts.Map(); + const indexedAccessTypes = new ts.Map(); + const templateLiteralTypes = new ts.Map(); + const stringMappingTypes = new ts.Map(); + const substitutionTypes = new ts.Map(); + const subtypeReductionCache = new ts.Map(); + const evolvingArrayTypes: ts.EvolvingArrayType[] = []; + const undefinedProperties: ts.SymbolTable = new ts.Map(); + const markerTypes = new ts.Set(); + const unknownSymbol = createSymbol(ts.SymbolFlags.Property, "unknown" as ts.__String); + const resolvingSymbol = createSymbol(0, ts.InternalSymbolName.Resolving); + const unresolvedSymbols = new ts.Map(); + const errorTypes = new ts.Map(); + const anyType = createIntrinsicType(ts.TypeFlags.Any, "any"); + const autoType = createIntrinsicType(ts.TypeFlags.Any, "any"); + const wildcardType = createIntrinsicType(ts.TypeFlags.Any, "any"); + const errorType = createIntrinsicType(ts.TypeFlags.Any, "error"); + const unresolvedType = createIntrinsicType(ts.TypeFlags.Any, "unresolved"); + const nonInferrableAnyType = createIntrinsicType(ts.TypeFlags.Any, "any", ts.ObjectFlags.ContainsWideningType); + const intrinsicMarkerType = createIntrinsicType(ts.TypeFlags.Any, "intrinsic"); + const unknownType = createIntrinsicType(ts.TypeFlags.Unknown, "unknown"); + const nonNullUnknownType = createIntrinsicType(ts.TypeFlags.Unknown, "unknown"); + const undefinedType = createIntrinsicType(ts.TypeFlags.Undefined, "undefined"); + const undefinedWideningType = strictNullChecks ? undefinedType : createIntrinsicType(ts.TypeFlags.Undefined, "undefined", ts.ObjectFlags.ContainsWideningType); + const optionalType = createIntrinsicType(ts.TypeFlags.Undefined, "undefined"); + const missingType = exactOptionalPropertyTypes ? createIntrinsicType(ts.TypeFlags.Undefined, "undefined") : undefinedType; + const nullType = createIntrinsicType(ts.TypeFlags.Null, "null"); + const nullWideningType = strictNullChecks ? nullType : createIntrinsicType(ts.TypeFlags.Null, "null", ts.ObjectFlags.ContainsWideningType); + const stringType = createIntrinsicType(ts.TypeFlags.String, "string"); + const numberType = createIntrinsicType(ts.TypeFlags.Number, "number"); + const bigintType = createIntrinsicType(ts.TypeFlags.BigInt, "bigint"); + const falseType = createIntrinsicType(ts.TypeFlags.BooleanLiteral, "false") as ts.FreshableIntrinsicType; + const regularFalseType = createIntrinsicType(ts.TypeFlags.BooleanLiteral, "false") as ts.FreshableIntrinsicType; + const trueType = createIntrinsicType(ts.TypeFlags.BooleanLiteral, "true") as ts.FreshableIntrinsicType; + const regularTrueType = createIntrinsicType(ts.TypeFlags.BooleanLiteral, "true") as ts.FreshableIntrinsicType; trueType.regularType = regularTrueType; trueType.freshType = trueType; regularTrueType.regularType = regularTrueType; @@ -820,65 +800,59 @@ namespace ts { regularFalseType.regularType = regularFalseType; regularFalseType.freshType = falseType; const booleanType = getUnionType([regularFalseType, regularTrueType]); - const esSymbolType = createIntrinsicType(TypeFlags.ESSymbol, "symbol"); - const voidType = createIntrinsicType(TypeFlags.Void, "void"); - const neverType = createIntrinsicType(TypeFlags.Never, "never"); - const silentNeverType = createIntrinsicType(TypeFlags.Never, "never"); - const nonInferrableType = createIntrinsicType(TypeFlags.Never, "never", ObjectFlags.NonInferrableType); - const implicitNeverType = createIntrinsicType(TypeFlags.Never, "never"); - const unreachableNeverType = createIntrinsicType(TypeFlags.Never, "never"); - const nonPrimitiveType = createIntrinsicType(TypeFlags.NonPrimitive, "object"); + const esSymbolType = createIntrinsicType(ts.TypeFlags.ESSymbol, "symbol"); + const voidType = createIntrinsicType(ts.TypeFlags.Void, "void"); + const neverType = createIntrinsicType(ts.TypeFlags.Never, "never"); + const silentNeverType = createIntrinsicType(ts.TypeFlags.Never, "never"); + const nonInferrableType = createIntrinsicType(ts.TypeFlags.Never, "never", ts.ObjectFlags.NonInferrableType); + const implicitNeverType = createIntrinsicType(ts.TypeFlags.Never, "never"); + const unreachableNeverType = createIntrinsicType(ts.TypeFlags.Never, "never"); + const nonPrimitiveType = createIntrinsicType(ts.TypeFlags.NonPrimitive, "object"); const stringOrNumberType = getUnionType([stringType, numberType]); const stringNumberSymbolType = getUnionType([stringType, numberType, esSymbolType]); const keyofConstraintType = keyofStringsOnly ? stringType : stringNumberSymbolType; const numberOrBigIntType = getUnionType([numberType, bigintType]); - const templateConstraintType = getUnionType([stringType, numberType, booleanType, bigintType, nullType, undefinedType]) as UnionType; + const templateConstraintType = getUnionType([stringType, numberType, booleanType, bigintType, nullType, undefinedType]) as ts.UnionType; const numericStringType = getTemplateLiteralType(["", ""], [numberType]); // The `${number}` type - const restrictiveMapper: TypeMapper = makeFunctionTypeMapper(t => t.flags & TypeFlags.TypeParameter ? getRestrictiveTypeParameter(t as TypeParameter) : t); - const permissiveMapper: TypeMapper = makeFunctionTypeMapper(t => t.flags & TypeFlags.TypeParameter ? wildcardType : t); - const uniqueLiteralType = createIntrinsicType(TypeFlags.Never, "never"); // `uniqueLiteralType` is a special `never` flagged by union reduction to behave as a literal - const uniqueLiteralMapper: TypeMapper = makeFunctionTypeMapper(t => t.flags & TypeFlags.TypeParameter ? uniqueLiteralType : t); // replace all type parameters with the unique literal type (disregarding constraints) - - const emptyObjectType = createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, emptyArray); - const emptyJsxObjectType = createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, emptyArray); - emptyJsxObjectType.objectFlags |= ObjectFlags.JsxAttributes; - - const emptyTypeLiteralSymbol = createSymbol(SymbolFlags.TypeLiteral, InternalSymbolName.Type); - emptyTypeLiteralSymbol.members = createSymbolTable(); - const emptyTypeLiteralType = createAnonymousType(emptyTypeLiteralSymbol, emptySymbols, emptyArray, emptyArray, emptyArray); - - const emptyGenericType = createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, emptyArray) as ObjectType as GenericType; - emptyGenericType.instantiations = new Map(); - - const anyFunctionType = createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, emptyArray); + const restrictiveMapper: ts.TypeMapper = makeFunctionTypeMapper(t => t.flags & ts.TypeFlags.TypeParameter ? getRestrictiveTypeParameter(t as ts.TypeParameter) : t); + const permissiveMapper: ts.TypeMapper = makeFunctionTypeMapper(t => t.flags & ts.TypeFlags.TypeParameter ? wildcardType : t); + const uniqueLiteralType = createIntrinsicType(ts.TypeFlags.Never, "never"); // `uniqueLiteralType` is a special `never` flagged by union reduction to behave as a literal + const uniqueLiteralMapper: ts.TypeMapper = makeFunctionTypeMapper(t => t.flags & ts.TypeFlags.TypeParameter ? uniqueLiteralType : t); // replace all type parameters with the unique literal type (disregarding constraints) + const emptyObjectType = createAnonymousType(undefined, emptySymbols, ts.emptyArray, ts.emptyArray, ts.emptyArray); + const emptyJsxObjectType = createAnonymousType(undefined, emptySymbols, ts.emptyArray, ts.emptyArray, ts.emptyArray); + emptyJsxObjectType.objectFlags |= ts.ObjectFlags.JsxAttributes; + const emptyTypeLiteralSymbol = createSymbol(ts.SymbolFlags.TypeLiteral, ts.InternalSymbolName.Type); + emptyTypeLiteralSymbol.members = ts.createSymbolTable(); + const emptyTypeLiteralType = createAnonymousType(emptyTypeLiteralSymbol, emptySymbols, ts.emptyArray, ts.emptyArray, ts.emptyArray); + const emptyGenericType = createAnonymousType(undefined, emptySymbols, ts.emptyArray, ts.emptyArray, ts.emptyArray) as ts.ObjectType as ts.GenericType; + emptyGenericType.instantiations = new ts.Map(); + const anyFunctionType = createAnonymousType(undefined, emptySymbols, ts.emptyArray, ts.emptyArray, ts.emptyArray); // The anyFunctionType contains the anyFunctionType by definition. The flag is further propagated // in getPropagatingFlagsOfTypes, and it is checked in inferFromTypes. - anyFunctionType.objectFlags |= ObjectFlags.NonInferrableType; - - const noConstraintType = createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, emptyArray); - const circularConstraintType = createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, emptyArray); - const resolvingDefaultType = createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, emptyArray); + anyFunctionType.objectFlags |= ts.ObjectFlags.NonInferrableType; + const noConstraintType = createAnonymousType(undefined, emptySymbols, ts.emptyArray, ts.emptyArray, ts.emptyArray); + const circularConstraintType = createAnonymousType(undefined, emptySymbols, ts.emptyArray, ts.emptyArray, ts.emptyArray); + const resolvingDefaultType = createAnonymousType(undefined, emptySymbols, ts.emptyArray, ts.emptyArray, ts.emptyArray); const markerSuperType = createTypeParameter(); const markerSubType = createTypeParameter(); markerSubType.constraint = markerSuperType; const markerOtherType = createTypeParameter(); - const noTypePredicate = createTypePredicate(TypePredicateKind.Identifier, "<>", 0, anyType); - - const anySignature = createSignature(undefined, undefined, undefined, emptyArray, anyType, /*resolvedTypePredicate*/ undefined, 0, SignatureFlags.None); - const unknownSignature = createSignature(undefined, undefined, undefined, emptyArray, errorType, /*resolvedTypePredicate*/ undefined, 0, SignatureFlags.None); - const resolvingSignature = createSignature(undefined, undefined, undefined, emptyArray, anyType, /*resolvedTypePredicate*/ undefined, 0, SignatureFlags.None); - const silentNeverSignature = createSignature(undefined, undefined, undefined, emptyArray, silentNeverType, /*resolvedTypePredicate*/ undefined, 0, SignatureFlags.None); + const noTypePredicate = createTypePredicate(ts.TypePredicateKind.Identifier, "<>", 0, anyType); + const anySignature = createSignature(undefined, undefined, undefined, ts.emptyArray, anyType, /*resolvedTypePredicate*/ undefined, 0, ts.SignatureFlags.None); + const unknownSignature = createSignature(undefined, undefined, undefined, ts.emptyArray, errorType, /*resolvedTypePredicate*/ undefined, 0, ts.SignatureFlags.None); + const resolvingSignature = createSignature(undefined, undefined, undefined, ts.emptyArray, anyType, /*resolvedTypePredicate*/ undefined, 0, ts.SignatureFlags.None); + const silentNeverSignature = createSignature(undefined, undefined, undefined, ts.emptyArray, silentNeverType, /*resolvedTypePredicate*/ undefined, 0, ts.SignatureFlags.None); const enumNumberIndexInfo = createIndexInfo(numberType, stringType, /*isReadonly*/ true); - const iterationTypesCache = new Map(); // cache for common IterationTypes instances - const noIterationTypes: IterationTypes = { - get yieldType(): Type { return Debug.fail("Not supported"); }, - get returnType(): Type { return Debug.fail("Not supported"); }, - get nextType(): Type { return Debug.fail("Not supported"); }, + const iterationTypesCache = new ts.Map(); // cache for common IterationTypes instances + const noIterationTypes: ts.IterationTypes = { + get yieldType(): ts.Type { return ts.Debug.fail("Not supported"); }, + get returnType(): ts.Type { return ts.Debug.fail("Not supported"); }, + get nextType(): ts.Type { return ts.Debug.fail("Not supported"); }, }; const anyIterationTypes = createIterationTypes(anyType, anyType, anyType); @@ -894,9 +868,9 @@ namespace ts { getGlobalIterableIteratorType: getGlobalAsyncIterableIteratorType, getGlobalGeneratorType: getGlobalAsyncGeneratorType, resolveIterationType: getAwaitedType, - mustHaveANextMethodDiagnostic: Diagnostics.An_async_iterator_must_have_a_next_method, - mustBeAMethodDiagnostic: Diagnostics.The_0_property_of_an_async_iterator_must_be_a_method, - mustHaveAValueDiagnostic: Diagnostics.The_type_returned_by_the_0_method_of_an_async_iterator_must_be_a_promise_for_a_type_with_a_value_property, + mustHaveANextMethodDiagnostic: ts.Diagnostics.An_async_iterator_must_have_a_next_method, + mustBeAMethodDiagnostic: ts.Diagnostics.The_0_property_of_an_async_iterator_must_be_a_method, + mustHaveAValueDiagnostic: ts.Diagnostics.The_type_returned_by_the_0_method_of_an_async_iterator_must_be_a_promise_for_a_type_with_a_value_property, }; const syncIterationTypesResolver: IterationTypesResolver = { @@ -908,91 +882,89 @@ namespace ts { getGlobalIterableIteratorType, getGlobalGeneratorType, resolveIterationType: (type, _errorNode) => type, - mustHaveANextMethodDiagnostic: Diagnostics.An_iterator_must_have_a_next_method, - mustBeAMethodDiagnostic: Diagnostics.The_0_property_of_an_iterator_must_be_a_method, - mustHaveAValueDiagnostic: Diagnostics.The_type_returned_by_the_0_method_of_an_iterator_must_have_a_value_property, + mustHaveANextMethodDiagnostic: ts.Diagnostics.An_iterator_must_have_a_next_method, + mustBeAMethodDiagnostic: ts.Diagnostics.The_0_property_of_an_iterator_must_be_a_method, + mustHaveAValueDiagnostic: ts.Diagnostics.The_type_returned_by_the_0_method_of_an_iterator_must_have_a_value_property, }; interface DuplicateInfoForSymbol { - readonly firstFileLocations: Declaration[]; - readonly secondFileLocations: Declaration[]; + readonly firstFileLocations: ts.Declaration[]; + readonly secondFileLocations: ts.Declaration[]; readonly isBlockScoped: boolean; } interface DuplicateInfoForFiles { - readonly firstFile: SourceFile; - readonly secondFile: SourceFile; + readonly firstFile: ts.SourceFile; + readonly secondFile: ts.SourceFile; /** Key is symbol name. */ - readonly conflictingSymbols: ESMap; + readonly conflictingSymbols: ts.ESMap; } /** Key is "/path/to/a.ts|/path/to/b.ts". */ - let amalgamatedDuplicates: ESMap | undefined; - const reverseMappedCache = new Map(); + let amalgamatedDuplicates: ts.ESMap | undefined; + const reverseMappedCache = new ts.Map(); let inInferTypeForHomomorphicMappedType = false; - let ambientModulesCache: Symbol[] | undefined; + let ambientModulesCache: ts.Symbol[] | undefined; /** * List of every ambient module with a "*" wildcard. * Unlike other ambient modules, these can't be stored in `globals` because symbol tables only deal with exact matches. * This is only used if there is no exact match. */ - let patternAmbientModules: PatternAmbientModule[]; - let patternAmbientModuleAugmentations: ESMap | undefined; - - let globalObjectType: ObjectType; - let globalFunctionType: ObjectType; - let globalCallableFunctionType: ObjectType; - let globalNewableFunctionType: ObjectType; - let globalArrayType: GenericType; - let globalReadonlyArrayType: GenericType; - let globalStringType: ObjectType; - let globalNumberType: ObjectType; - let globalBooleanType: ObjectType; - let globalRegExpType: ObjectType; - let globalThisType: GenericType; - let anyArrayType: Type; - let autoArrayType: Type; - let anyReadonlyArrayType: Type; - let deferredGlobalNonNullableTypeAlias: Symbol; + let patternAmbientModules: ts.PatternAmbientModule[]; + let patternAmbientModuleAugmentations: ts.ESMap | undefined; + let globalObjectType: ts.ObjectType; + let globalFunctionType: ts.ObjectType; + let globalCallableFunctionType: ts.ObjectType; + let globalNewableFunctionType: ts.ObjectType; + let globalArrayType: ts.GenericType; + let globalReadonlyArrayType: ts.GenericType; + let globalStringType: ts.ObjectType; + let globalNumberType: ts.ObjectType; + let globalBooleanType: ts.ObjectType; + let globalRegExpType: ts.ObjectType; + let globalThisType: ts.GenericType; + let anyArrayType: ts.Type; + let autoArrayType: ts.Type; + let anyReadonlyArrayType: ts.Type; + let deferredGlobalNonNullableTypeAlias: ts.Symbol; // The library files are only loaded when the feature is used. // This allows users to just specify library files they want to used through --lib // and they will not get an error from not having unrelated library files - let deferredGlobalESSymbolConstructorSymbol: Symbol | undefined; - let deferredGlobalESSymbolConstructorTypeSymbol: Symbol | undefined; - let deferredGlobalESSymbolType: ObjectType | undefined; - let deferredGlobalTypedPropertyDescriptorType: GenericType; - let deferredGlobalPromiseType: GenericType | undefined; - let deferredGlobalPromiseLikeType: GenericType | undefined; - let deferredGlobalPromiseConstructorSymbol: Symbol | undefined; - let deferredGlobalPromiseConstructorLikeType: ObjectType | undefined; - let deferredGlobalIterableType: GenericType | undefined; - let deferredGlobalIteratorType: GenericType | undefined; - let deferredGlobalIterableIteratorType: GenericType | undefined; - let deferredGlobalGeneratorType: GenericType | undefined; - let deferredGlobalIteratorYieldResultType: GenericType | undefined; - let deferredGlobalIteratorReturnResultType: GenericType | undefined; - let deferredGlobalAsyncIterableType: GenericType | undefined; - let deferredGlobalAsyncIteratorType: GenericType | undefined; - let deferredGlobalAsyncIterableIteratorType: GenericType | undefined; - let deferredGlobalAsyncGeneratorType: GenericType | undefined; - let deferredGlobalTemplateStringsArrayType: ObjectType | undefined; - let deferredGlobalImportMetaType: ObjectType; - let deferredGlobalImportMetaExpressionType: ObjectType; - let deferredGlobalImportCallOptionsType: ObjectType | undefined; - let deferredGlobalExtractSymbol: Symbol | undefined; - let deferredGlobalOmitSymbol: Symbol | undefined; - let deferredGlobalAwaitedSymbol: Symbol | undefined; - let deferredGlobalBigIntType: ObjectType | undefined; - - const allPotentiallyUnusedIdentifiers = new Map(); // key is file name + let deferredGlobalESSymbolConstructorSymbol: ts.Symbol | undefined; + let deferredGlobalESSymbolConstructorTypeSymbol: ts.Symbol | undefined; + let deferredGlobalESSymbolType: ts.ObjectType | undefined; + let deferredGlobalTypedPropertyDescriptorType: ts.GenericType; + let deferredGlobalPromiseType: ts.GenericType | undefined; + let deferredGlobalPromiseLikeType: ts.GenericType | undefined; + let deferredGlobalPromiseConstructorSymbol: ts.Symbol | undefined; + let deferredGlobalPromiseConstructorLikeType: ts.ObjectType | undefined; + let deferredGlobalIterableType: ts.GenericType | undefined; + let deferredGlobalIteratorType: ts.GenericType | undefined; + let deferredGlobalIterableIteratorType: ts.GenericType | undefined; + let deferredGlobalGeneratorType: ts.GenericType | undefined; + let deferredGlobalIteratorYieldResultType: ts.GenericType | undefined; + let deferredGlobalIteratorReturnResultType: ts.GenericType | undefined; + let deferredGlobalAsyncIterableType: ts.GenericType | undefined; + let deferredGlobalAsyncIteratorType: ts.GenericType | undefined; + let deferredGlobalAsyncIterableIteratorType: ts.GenericType | undefined; + let deferredGlobalAsyncGeneratorType: ts.GenericType | undefined; + let deferredGlobalTemplateStringsArrayType: ts.ObjectType | undefined; + let deferredGlobalImportMetaType: ts.ObjectType; + let deferredGlobalImportMetaExpressionType: ts.ObjectType; + let deferredGlobalImportCallOptionsType: ts.ObjectType | undefined; + let deferredGlobalExtractSymbol: ts.Symbol | undefined; + let deferredGlobalOmitSymbol: ts.Symbol | undefined; + let deferredGlobalAwaitedSymbol: ts.Symbol | undefined; + let deferredGlobalBigIntType: ts.ObjectType | undefined; + const allPotentiallyUnusedIdentifiers = new ts.Map(); // key is file name let flowLoopStart = 0; let flowLoopCount = 0; let sharedFlowCount = 0; let flowAnalysisDisabled = false; let flowInvocationCount = 0; - let lastFlowNode: FlowNode | undefined; + let lastFlowNode: ts.FlowNode | undefined; let lastFlowNodeReachable: boolean; - let flowTypeCache: Type[] | undefined; + let flowTypeCache: ts.Type[] | undefined; const emptyStringType = getStringLiteralType(""); const zeroType = getNumberLiteralType(0); @@ -1004,27 +976,26 @@ namespace ts { let suggestionCount = 0; const maximumSuggestionCount = 10; - const mergedSymbols: Symbol[] = []; - const symbolLinks: SymbolLinks[] = []; - const nodeLinks: NodeLinks[] = []; - const flowLoopCaches: ESMap[] = []; - const flowLoopNodes: FlowNode[] = []; + const mergedSymbols: ts.Symbol[] = []; + const symbolLinks: ts.SymbolLinks[] = []; + const nodeLinks: ts.NodeLinks[] = []; + const flowLoopCaches: ts.ESMap[] = []; + const flowLoopNodes: ts.FlowNode[] = []; const flowLoopKeys: string[] = []; - const flowLoopTypes: Type[][] = []; - const sharedFlowNodes: FlowNode[] = []; - const sharedFlowTypes: FlowType[] = []; + const flowLoopTypes: ts.Type[][] = []; + const sharedFlowNodes: ts.FlowNode[] = []; + const sharedFlowTypes: ts.FlowType[] = []; const flowNodeReachable: (boolean | undefined)[] = []; const flowNodePostSuper: (boolean | undefined)[] = []; - const potentialThisCollisions: Node[] = []; - const potentialNewTargetCollisions: Node[] = []; - const potentialWeakMapSetCollisions: Node[] = []; - const potentialReflectCollisions: Node[] = []; + const potentialThisCollisions: ts.Node[] = []; + const potentialNewTargetCollisions: ts.Node[] = []; + const potentialWeakMapSetCollisions: ts.Node[] = []; + const potentialReflectCollisions: ts.Node[] = []; const awaitedTypeStack: number[] = []; - const diagnostics = createDiagnosticCollection(); - const suggestionDiagnostics = createDiagnosticCollection(); - - const typeofTypesByName: ReadonlyESMap = new Map(getEntries({ + const diagnostics = ts.createDiagnosticCollection(); + const suggestionDiagnostics = ts.createDiagnosticCollection(); + const typeofTypesByName: ts.ReadonlyESMap = new ts.Map(ts.getEntries({ string: stringType, number: numberType, bigint: bigintType, @@ -1034,32 +1005,34 @@ namespace ts { })); const typeofType = createTypeofType(); - let _jsxNamespace: __String; - let _jsxFactoryEntity: EntityName | undefined; + let _jsxNamespace: ts.__String; + let _jsxFactoryEntity: ts.EntityName | undefined; let outofbandVarianceMarkerHandler: ((onlyUnreliable: boolean) => void) | undefined; - const subtypeRelation = new Map(); - const strictSubtypeRelation = new Map(); - const assignableRelation = new Map(); - const comparableRelation = new Map(); - const identityRelation = new Map(); - const enumRelation = new Map(); - - const builtinGlobals = createSymbolTable(); + const subtypeRelation = new ts.Map(); + const strictSubtypeRelation = new ts.Map(); + const assignableRelation = new ts.Map(); + const comparableRelation = new ts.Map(); + const identityRelation = new ts.Map(); + const enumRelation = new ts.Map(); + const builtinGlobals = ts.createSymbolTable(); builtinGlobals.set(undefinedSymbol.escapedName, undefinedSymbol); // Extensions suggested for path imports when module resolution is node16 or higher. // The first element of each tuple is the extension a file has. // The second element of each tuple is the extension that should be used in a path import. // e.g. if we want to import file `foo.mts`, we should write `import {} from "./foo.mjs". - const suggestedExtensions: [string, string][] = [ + const suggestedExtensions: [ + string, + string + ][] = [ [".mts", ".mjs"], [".ts", ".js"], [".cts", ".cjs"], [".mjs", ".mjs"], [".js", ".js"], [".cjs", ".cjs"], - [".tsx", compilerOptions.jsx === JsxEmit.Preserve ? ".jsx" : ".js"], + [".tsx", compilerOptions.jsx === ts.JsxEmit.Preserve ? ".jsx" : ".js"], [".jsx", ".jsx"], [".json", ".json"], ]; @@ -1068,27 +1041,27 @@ namespace ts { return checker; - function getJsxNamespace(location: Node | undefined): __String { + function getJsxNamespace(location: ts.Node | undefined): ts.__String { if (location) { - const file = getSourceFileOfNode(location); + const file = ts.getSourceFileOfNode(location); if (file) { - if (isJsxOpeningFragment(location)) { + if (ts.isJsxOpeningFragment(location)) { if (file.localJsxFragmentNamespace) { return file.localJsxFragmentNamespace; } const jsxFragmentPragma = file.pragmas.get("jsxfrag"); if (jsxFragmentPragma) { - const chosenPragma = isArray(jsxFragmentPragma) ? jsxFragmentPragma[0] : jsxFragmentPragma; - file.localJsxFragmentFactory = parseIsolatedEntityName(chosenPragma.arguments.factory, languageVersion); - visitNode(file.localJsxFragmentFactory, markAsSynthetic); + const chosenPragma = ts.isArray(jsxFragmentPragma) ? jsxFragmentPragma[0] : jsxFragmentPragma; + file.localJsxFragmentFactory = ts.parseIsolatedEntityName(chosenPragma.arguments.factory, languageVersion); + ts.visitNode(file.localJsxFragmentFactory, markAsSynthetic); if (file.localJsxFragmentFactory) { - return file.localJsxFragmentNamespace = getFirstIdentifier(file.localJsxFragmentFactory).escapedText; + return file.localJsxFragmentNamespace = ts.getFirstIdentifier(file.localJsxFragmentFactory).escapedText; } } const entity = getJsxFragmentFactoryEntity(location); if (entity) { file.localJsxFragmentFactory = entity; - return file.localJsxFragmentNamespace = getFirstIdentifier(entity).escapedText; + return file.localJsxFragmentNamespace = ts.getFirstIdentifier(entity).escapedText; } } else { @@ -1100,55 +1073,55 @@ namespace ts { } } if (!_jsxNamespace) { - _jsxNamespace = "React" as __String; + _jsxNamespace = "React" as ts.__String; if (compilerOptions.jsxFactory) { - _jsxFactoryEntity = parseIsolatedEntityName(compilerOptions.jsxFactory, languageVersion); - visitNode(_jsxFactoryEntity, markAsSynthetic); + _jsxFactoryEntity = ts.parseIsolatedEntityName(compilerOptions.jsxFactory, languageVersion); + ts.visitNode(_jsxFactoryEntity, markAsSynthetic); if (_jsxFactoryEntity) { - _jsxNamespace = getFirstIdentifier(_jsxFactoryEntity).escapedText; + _jsxNamespace = ts.getFirstIdentifier(_jsxFactoryEntity).escapedText; } } else if (compilerOptions.reactNamespace) { - _jsxNamespace = escapeLeadingUnderscores(compilerOptions.reactNamespace); + _jsxNamespace = ts.escapeLeadingUnderscores(compilerOptions.reactNamespace); } } if (!_jsxFactoryEntity) { - _jsxFactoryEntity = factory.createQualifiedName(factory.createIdentifier(unescapeLeadingUnderscores(_jsxNamespace)), "createElement"); + _jsxFactoryEntity = ts.factory.createQualifiedName(ts.factory.createIdentifier(ts.unescapeLeadingUnderscores(_jsxNamespace)), "createElement"); } return _jsxNamespace; } - function getLocalJsxNamespace(file: SourceFile): __String | undefined { + function getLocalJsxNamespace(file: ts.SourceFile): ts.__String | undefined { if (file.localJsxNamespace) { return file.localJsxNamespace; } const jsxPragma = file.pragmas.get("jsx"); if (jsxPragma) { - const chosenPragma = isArray(jsxPragma) ? jsxPragma[0] : jsxPragma; - file.localJsxFactory = parseIsolatedEntityName(chosenPragma.arguments.factory, languageVersion); - visitNode(file.localJsxFactory, markAsSynthetic); + const chosenPragma = ts.isArray(jsxPragma) ? jsxPragma[0] : jsxPragma; + file.localJsxFactory = ts.parseIsolatedEntityName(chosenPragma.arguments.factory, languageVersion); + ts.visitNode(file.localJsxFactory, markAsSynthetic); if (file.localJsxFactory) { - return file.localJsxNamespace = getFirstIdentifier(file.localJsxFactory).escapedText; + return file.localJsxNamespace = ts.getFirstIdentifier(file.localJsxFactory).escapedText; } } } - function markAsSynthetic(node: Node): VisitResult { - setTextRangePosEnd(node, -1, -1); - return visitEachChild(node, markAsSynthetic, nullTransformationContext); + function markAsSynthetic(node: ts.Node): ts.VisitResult { + ts.setTextRangePosEnd(node, -1, -1); + return ts.visitEachChild(node, markAsSynthetic, ts.nullTransformationContext); } - function getEmitResolver(sourceFile: SourceFile, cancellationToken: CancellationToken) { + function getEmitResolver(sourceFile: ts.SourceFile, cancellationToken: ts.CancellationToken) { // Ensure we have all the type information in place for this file so that all the // emitter questions of this resolver will return the right information. getDiagnostics(sourceFile, cancellationToken); return emitResolver; } - function lookupOrIssueError(location: Node | undefined, message: DiagnosticMessage, arg0?: string | number, arg1?: string | number, arg2?: string | number, arg3?: string | number): Diagnostic { + function lookupOrIssueError(location: ts.Node | undefined, message: ts.DiagnosticMessage, arg0?: string | number, arg1?: string | number, arg2?: string | number, arg3?: string | number): ts.Diagnostic { const diagnostic = location - ? createDiagnosticForNode(location, message, arg0, arg1, arg2, arg3) - : createCompilerDiagnostic(message, arg0, arg1, arg2, arg3); + ? ts.createDiagnosticForNode(location, message, arg0, arg1, arg2, arg3) + : ts.createCompilerDiagnostic(message, arg0, arg1, arg2, arg3); const existing = diagnostics.lookup(diagnostic); if (existing) { return existing; @@ -1159,117 +1132,126 @@ namespace ts { } } - function errorSkippedOn(key: keyof CompilerOptions, location: Node | undefined, message: DiagnosticMessage, arg0?: string | number, arg1?: string | number, arg2?: string | number, arg3?: string | number): Diagnostic { + function errorSkippedOn(key: keyof ts.CompilerOptions, location: ts.Node | undefined, message: ts.DiagnosticMessage, arg0?: string | number, arg1?: string | number, arg2?: string | number, arg3?: string | number): ts.Diagnostic { const diagnostic = error(location, message, arg0, arg1, arg2, arg3); diagnostic.skippedOn = key; return diagnostic; } - function createError(location: Node | undefined, message: DiagnosticMessage, arg0?: string | number, arg1?: string | number, arg2?: string | number, arg3?: string | number): Diagnostic { + function createError(location: ts.Node | undefined, message: ts.DiagnosticMessage, arg0?: string | number, arg1?: string | number, arg2?: string | number, arg3?: string | number): ts.Diagnostic { return location - ? createDiagnosticForNode(location, message, arg0, arg1, arg2, arg3) - : createCompilerDiagnostic(message, arg0, arg1, arg2, arg3); + ? ts.createDiagnosticForNode(location, message, arg0, arg1, arg2, arg3) + : ts.createCompilerDiagnostic(message, arg0, arg1, arg2, arg3); } - function error(location: Node | undefined, message: DiagnosticMessage, arg0?: string | number, arg1?: string | number, arg2?: string | number, arg3?: string | number): Diagnostic { + function error(location: ts.Node | undefined, message: ts.DiagnosticMessage, arg0?: string | number, arg1?: string | number, arg2?: string | number, arg3?: string | number): ts.Diagnostic { const diagnostic = createError(location, message, arg0, arg1, arg2, arg3); diagnostics.add(diagnostic); return diagnostic; } - function addErrorOrSuggestion(isError: boolean, diagnostic: Diagnostic) { + function addErrorOrSuggestion(isError: boolean, diagnostic: ts.Diagnostic) { if (isError) { diagnostics.add(diagnostic); } else { - suggestionDiagnostics.add({ ...diagnostic, category: DiagnosticCategory.Suggestion }); + suggestionDiagnostics.add({ ...diagnostic, category: ts.DiagnosticCategory.Suggestion }); } } - function errorOrSuggestion(isError: boolean, location: Node, message: DiagnosticMessage | DiagnosticMessageChain, arg0?: string | number, arg1?: string | number, arg2?: string | number, arg3?: string | number): void { + function errorOrSuggestion(isError: boolean, location: ts.Node, message: ts.DiagnosticMessage | ts.DiagnosticMessageChain, arg0?: string | number, arg1?: string | number, arg2?: string | number, arg3?: string | number): void { // Pseudo-synthesized input node if (location.pos < 0 || location.end < 0) { if (!isError) { return; // Drop suggestions (we have no span to suggest on) } // Issue errors globally - const file = getSourceFileOfNode(location); - addErrorOrSuggestion(isError, "message" in message ? createFileDiagnostic(file, 0, 0, message, arg0, arg1, arg2, arg3) : createDiagnosticForFileFromMessageChain(file, message)); // eslint-disable-line no-in-operator + const file = ts.getSourceFileOfNode(location); + addErrorOrSuggestion(isError, "message" in message ? ts.createFileDiagnostic(file, 0, 0, message, arg0, arg1, arg2, arg3) : ts.createDiagnosticForFileFromMessageChain(file, message)); // eslint-disable-line no-in-operator return; } - addErrorOrSuggestion(isError, "message" in message ? createDiagnosticForNode(location, message, arg0, arg1, arg2, arg3) : createDiagnosticForNodeFromMessageChain(location, message)); // eslint-disable-line no-in-operator + addErrorOrSuggestion(isError, "message" in message ? ts.createDiagnosticForNode(location, message, arg0, arg1, arg2, arg3) : ts.createDiagnosticForNodeFromMessageChain(location, message)); // eslint-disable-line no-in-operator } - function errorAndMaybeSuggestAwait( - location: Node, - maybeMissingAwait: boolean, - message: DiagnosticMessage, - arg0?: string | number | undefined, arg1?: string | number | undefined, arg2?: string | number | undefined, arg3?: string | number | undefined): Diagnostic { + function errorAndMaybeSuggestAwait(location: ts.Node, maybeMissingAwait: boolean, message: ts.DiagnosticMessage, arg0?: string | number | undefined, arg1?: string | number | undefined, arg2?: string | number | undefined, arg3?: string | number | undefined): ts.Diagnostic { const diagnostic = error(location, message, arg0, arg1, arg2, arg3); if (maybeMissingAwait) { - const related = createDiagnosticForNode(location, Diagnostics.Did_you_forget_to_use_await); - addRelatedInfo(diagnostic, related); + const related = ts.createDiagnosticForNode(location, ts.Diagnostics.Did_you_forget_to_use_await); + ts.addRelatedInfo(diagnostic, related); } return diagnostic; } - function addDeprecatedSuggestionWorker(declarations: Node | Node[], diagnostic: DiagnosticWithLocation) { - const deprecatedTag = Array.isArray(declarations) ? forEach(declarations, getJSDocDeprecatedTag) : getJSDocDeprecatedTag(declarations); + function addDeprecatedSuggestionWorker(declarations: ts.Node | ts.Node[], diagnostic: ts.DiagnosticWithLocation) { + const deprecatedTag = Array.isArray(declarations) ? ts.forEach(declarations, ts.getJSDocDeprecatedTag) : ts.getJSDocDeprecatedTag(declarations); if (deprecatedTag) { - addRelatedInfo( - diagnostic, - createDiagnosticForNode(deprecatedTag, Diagnostics.The_declaration_was_marked_as_deprecated_here) - ); + ts.addRelatedInfo(diagnostic, ts.createDiagnosticForNode(deprecatedTag, ts.Diagnostics.The_declaration_was_marked_as_deprecated_here)); } // We call `addRelatedInfo()` before adding the diagnostic to prevent duplicates. suggestionDiagnostics.add(diagnostic); return diagnostic; } - function isDeprecatedSymbol(symbol: Symbol) { - return !!(getDeclarationNodeFlagsFromSymbol(symbol) & NodeFlags.Deprecated); + function isDeprecatedSymbol(symbol: ts.Symbol) { + return !!(getDeclarationNodeFlagsFromSymbol(symbol) & ts.NodeFlags.Deprecated); } - function addDeprecatedSuggestion(location: Node, declarations: Node[], deprecatedEntity: string) { - const diagnostic = createDiagnosticForNode(location, Diagnostics._0_is_deprecated, deprecatedEntity); + function addDeprecatedSuggestion(location: ts.Node, declarations: ts.Node[], deprecatedEntity: string) { + const diagnostic = ts.createDiagnosticForNode(location, ts.Diagnostics._0_is_deprecated, deprecatedEntity); return addDeprecatedSuggestionWorker(declarations, diagnostic); } - function addDeprecatedSuggestionWithSignature(location: Node, declaration: Node, deprecatedEntity: string | undefined, signatureString: string) { + function addDeprecatedSuggestionWithSignature(location: ts.Node, declaration: ts.Node, deprecatedEntity: string | undefined, signatureString: string) { const diagnostic = deprecatedEntity - ? createDiagnosticForNode(location, Diagnostics.The_signature_0_of_1_is_deprecated, signatureString, deprecatedEntity) - : createDiagnosticForNode(location, Diagnostics._0_is_deprecated, signatureString); + ? ts.createDiagnosticForNode(location, ts.Diagnostics.The_signature_0_of_1_is_deprecated, signatureString, deprecatedEntity) + : ts.createDiagnosticForNode(location, ts.Diagnostics._0_is_deprecated, signatureString); return addDeprecatedSuggestionWorker(declaration, diagnostic); } - function createSymbol(flags: SymbolFlags, name: __String, checkFlags?: CheckFlags) { + function createSymbol(flags: ts.SymbolFlags, name: ts.__String, checkFlags?: ts.CheckFlags) { symbolCount++; - const symbol = (new Symbol(flags | SymbolFlags.Transient, name) as TransientSymbol); + const symbol = (new Symbol(flags | ts.SymbolFlags.Transient, name) as ts.TransientSymbol); symbol.checkFlags = checkFlags || 0; return symbol; } - function getExcludedSymbolFlags(flags: SymbolFlags): SymbolFlags { - let result: SymbolFlags = 0; - if (flags & SymbolFlags.BlockScopedVariable) result |= SymbolFlags.BlockScopedVariableExcludes; - if (flags & SymbolFlags.FunctionScopedVariable) result |= SymbolFlags.FunctionScopedVariableExcludes; - if (flags & SymbolFlags.Property) result |= SymbolFlags.PropertyExcludes; - if (flags & SymbolFlags.EnumMember) result |= SymbolFlags.EnumMemberExcludes; - if (flags & SymbolFlags.Function) result |= SymbolFlags.FunctionExcludes; - if (flags & SymbolFlags.Class) result |= SymbolFlags.ClassExcludes; - if (flags & SymbolFlags.Interface) result |= SymbolFlags.InterfaceExcludes; - if (flags & SymbolFlags.RegularEnum) result |= SymbolFlags.RegularEnumExcludes; - if (flags & SymbolFlags.ConstEnum) result |= SymbolFlags.ConstEnumExcludes; - if (flags & SymbolFlags.ValueModule) result |= SymbolFlags.ValueModuleExcludes; - if (flags & SymbolFlags.Method) result |= SymbolFlags.MethodExcludes; - if (flags & SymbolFlags.GetAccessor) result |= SymbolFlags.GetAccessorExcludes; - if (flags & SymbolFlags.SetAccessor) result |= SymbolFlags.SetAccessorExcludes; - if (flags & SymbolFlags.TypeParameter) result |= SymbolFlags.TypeParameterExcludes; - if (flags & SymbolFlags.TypeAlias) result |= SymbolFlags.TypeAliasExcludes; - if (flags & SymbolFlags.Alias) result |= SymbolFlags.AliasExcludes; + function getExcludedSymbolFlags(flags: ts.SymbolFlags): ts.SymbolFlags { + let result: ts.SymbolFlags = 0; + if (flags & ts.SymbolFlags.BlockScopedVariable) + result |= ts.SymbolFlags.BlockScopedVariableExcludes; + if (flags & ts.SymbolFlags.FunctionScopedVariable) + result |= ts.SymbolFlags.FunctionScopedVariableExcludes; + if (flags & ts.SymbolFlags.Property) + result |= ts.SymbolFlags.PropertyExcludes; + if (flags & ts.SymbolFlags.EnumMember) + result |= ts.SymbolFlags.EnumMemberExcludes; + if (flags & ts.SymbolFlags.Function) + result |= ts.SymbolFlags.FunctionExcludes; + if (flags & ts.SymbolFlags.Class) + result |= ts.SymbolFlags.ClassExcludes; + if (flags & ts.SymbolFlags.Interface) + result |= ts.SymbolFlags.InterfaceExcludes; + if (flags & ts.SymbolFlags.RegularEnum) + result |= ts.SymbolFlags.RegularEnumExcludes; + if (flags & ts.SymbolFlags.ConstEnum) + result |= ts.SymbolFlags.ConstEnumExcludes; + if (flags & ts.SymbolFlags.ValueModule) + result |= ts.SymbolFlags.ValueModuleExcludes; + if (flags & ts.SymbolFlags.Method) + result |= ts.SymbolFlags.MethodExcludes; + if (flags & ts.SymbolFlags.GetAccessor) + result |= ts.SymbolFlags.GetAccessorExcludes; + if (flags & ts.SymbolFlags.SetAccessor) + result |= ts.SymbolFlags.SetAccessorExcludes; + if (flags & ts.SymbolFlags.TypeParameter) + result |= ts.SymbolFlags.TypeParameterExcludes; + if (flags & ts.SymbolFlags.TypeAlias) + result |= ts.SymbolFlags.TypeAliasExcludes; + if (flags & ts.SymbolFlags.Alias) + result |= ts.SymbolFlags.AliasExcludes; return result; } - function recordMergedSymbol(target: Symbol, source: Symbol) { + function recordMergedSymbol(target: ts.Symbol, source: ts.Symbol) { if (!source.mergeId) { source.mergeId = nextMergeId; nextMergeId++; @@ -1277,14 +1259,18 @@ namespace ts { mergedSymbols[source.mergeId] = target; } - function cloneSymbol(symbol: Symbol): Symbol { + function cloneSymbol(symbol: ts.Symbol): ts.Symbol { const result = createSymbol(symbol.flags, symbol.escapedName); result.declarations = symbol.declarations ? symbol.declarations.slice() : []; result.parent = symbol.parent; - if (symbol.valueDeclaration) result.valueDeclaration = symbol.valueDeclaration; - if (symbol.constEnumOnlyModule) result.constEnumOnlyModule = true; - if (symbol.members) result.members = new Map(symbol.members); - if (symbol.exports) result.exports = new Map(symbol.exports); + if (symbol.valueDeclaration) + result.valueDeclaration = symbol.valueDeclaration; + if (symbol.constEnumOnlyModule) + result.constEnumOnlyModule = true; + if (symbol.members) + result.members = new ts.Map(symbol.members); + if (symbol.exports) + result.exports = new ts.Map(symbol.exports); recordMergedSymbol(result, symbol); return result; } @@ -1293,15 +1279,15 @@ namespace ts { * Note: if target is transient, then it is mutable, and mergeSymbol with both mutate and return it. * If target is not transient, mergeSymbol will produce a transient clone, mutate that and return it. */ - function mergeSymbol(target: Symbol, source: Symbol, unidirectional = false): Symbol { + function mergeSymbol(target: ts.Symbol, source: ts.Symbol, unidirectional = false): ts.Symbol { if (!(target.flags & getExcludedSymbolFlags(source.flags)) || - (source.flags | target.flags) & SymbolFlags.Assignment) { + (source.flags | target.flags) & ts.SymbolFlags.Assignment) { if (source === target) { // This can happen when an export assigned namespace exports something also erroneously exported at the top level // See `declarationFileNoCrashOnExtraExportModifier` for an example return target; } - if (!(target.flags & SymbolFlags.Transient)) { + if (!(target.flags & ts.SymbolFlags.Transient)) { const resolvedTarget = resolveSymbol(target); if (resolvedTarget === unknownSymbol) { return source; @@ -1309,132 +1295,136 @@ namespace ts { target = cloneSymbol(resolvedTarget); } // Javascript static-property-assignment declarations always merge, even though they are also values - if (source.flags & SymbolFlags.ValueModule && target.flags & SymbolFlags.ValueModule && target.constEnumOnlyModule && !source.constEnumOnlyModule) { + if (source.flags & ts.SymbolFlags.ValueModule && target.flags & ts.SymbolFlags.ValueModule && target.constEnumOnlyModule && !source.constEnumOnlyModule) { // reset flag when merging instantiated module into value module that has only const enums target.constEnumOnlyModule = false; } target.flags |= source.flags; if (source.valueDeclaration) { - setValueDeclaration(target, source.valueDeclaration); + ts.setValueDeclaration(target, source.valueDeclaration); } - addRange(target.declarations, source.declarations); + ts.addRange(target.declarations, source.declarations); if (source.members) { - if (!target.members) target.members = createSymbolTable(); + if (!target.members) + target.members = ts.createSymbolTable(); mergeSymbolTable(target.members, source.members, unidirectional); } if (source.exports) { - if (!target.exports) target.exports = createSymbolTable(); + if (!target.exports) + target.exports = ts.createSymbolTable(); mergeSymbolTable(target.exports, source.exports, unidirectional); } if (!unidirectional) { recordMergedSymbol(target, source); } } - else if (target.flags & SymbolFlags.NamespaceModule) { + else if (target.flags & ts.SymbolFlags.NamespaceModule) { // Do not report an error when merging `var globalThis` with the built-in `globalThis`, // as we will already report a "Declaration name conflicts..." error, and this error // won't make much sense. if (target !== globalThisSymbol) { - error( - source.declarations && getNameOfDeclaration(source.declarations[0]), - Diagnostics.Cannot_augment_module_0_with_value_exports_because_it_resolves_to_a_non_module_entity, - symbolToString(target)); + error(source.declarations && ts.getNameOfDeclaration(source.declarations[0]), ts.Diagnostics.Cannot_augment_module_0_with_value_exports_because_it_resolves_to_a_non_module_entity, symbolToString(target)); } } else { // error - const isEitherEnum = !!(target.flags & SymbolFlags.Enum || source.flags & SymbolFlags.Enum); - const isEitherBlockScoped = !!(target.flags & SymbolFlags.BlockScopedVariable || source.flags & SymbolFlags.BlockScopedVariable); - const message = isEitherEnum ? Diagnostics.Enum_declarations_can_only_merge_with_namespace_or_other_enum_declarations - : isEitherBlockScoped ? Diagnostics.Cannot_redeclare_block_scoped_variable_0 - : Diagnostics.Duplicate_identifier_0; - const sourceSymbolFile = source.declarations && getSourceFileOfNode(source.declarations[0]); - const targetSymbolFile = target.declarations && getSourceFileOfNode(target.declarations[0]); - - const isSourcePlainJs = isPlainJsFile(sourceSymbolFile, compilerOptions.checkJs); - const isTargetPlainJs = isPlainJsFile(targetSymbolFile, compilerOptions.checkJs); + const isEitherEnum = !!(target.flags & ts.SymbolFlags.Enum || source.flags & ts.SymbolFlags.Enum); + const isEitherBlockScoped = !!(target.flags & ts.SymbolFlags.BlockScopedVariable || source.flags & ts.SymbolFlags.BlockScopedVariable); + const message = isEitherEnum ? ts.Diagnostics.Enum_declarations_can_only_merge_with_namespace_or_other_enum_declarations + : isEitherBlockScoped ? ts.Diagnostics.Cannot_redeclare_block_scoped_variable_0 + : ts.Diagnostics.Duplicate_identifier_0; + const sourceSymbolFile = source.declarations && ts.getSourceFileOfNode(source.declarations[0]); + const targetSymbolFile = target.declarations && ts.getSourceFileOfNode(target.declarations[0]); + const isSourcePlainJs = ts.isPlainJsFile(sourceSymbolFile, compilerOptions.checkJs); + const isTargetPlainJs = ts.isPlainJsFile(targetSymbolFile, compilerOptions.checkJs); const symbolName = symbolToString(source); // Collect top-level duplicate identifier errors into one mapping, so we can then merge their diagnostics if there are a bunch if (sourceSymbolFile && targetSymbolFile && amalgamatedDuplicates && !isEitherEnum && sourceSymbolFile !== targetSymbolFile) { - const firstFile = comparePaths(sourceSymbolFile.path, targetSymbolFile.path) === Comparison.LessThan ? sourceSymbolFile : targetSymbolFile; + const firstFile = ts.comparePaths(sourceSymbolFile.path, targetSymbolFile.path) === ts.Comparison.LessThan ? sourceSymbolFile : targetSymbolFile; const secondFile = firstFile === sourceSymbolFile ? targetSymbolFile : sourceSymbolFile; - const filesDuplicates = getOrUpdate(amalgamatedDuplicates, `${firstFile.path}|${secondFile.path}`, () => - ({ firstFile, secondFile, conflictingSymbols: new Map() } as DuplicateInfoForFiles)); - const conflictingSymbolInfo = getOrUpdate(filesDuplicates.conflictingSymbols, symbolName, () => - ({ isBlockScoped: isEitherBlockScoped, firstFileLocations: [], secondFileLocations: [] } as DuplicateInfoForSymbol)); - if (!isSourcePlainJs) addDuplicateLocations(conflictingSymbolInfo.firstFileLocations, source); - if (!isTargetPlainJs) addDuplicateLocations(conflictingSymbolInfo.secondFileLocations, target); + const filesDuplicates = ts.getOrUpdate(amalgamatedDuplicates, `${firstFile.path}|${secondFile.path}`, () => ({ firstFile, secondFile, conflictingSymbols: new ts.Map() } as DuplicateInfoForFiles)); + const conflictingSymbolInfo = ts.getOrUpdate(filesDuplicates.conflictingSymbols, symbolName, () => ({ isBlockScoped: isEitherBlockScoped, firstFileLocations: [], secondFileLocations: [] } as DuplicateInfoForSymbol)); + if (!isSourcePlainJs) + addDuplicateLocations(conflictingSymbolInfo.firstFileLocations, source); + if (!isTargetPlainJs) + addDuplicateLocations(conflictingSymbolInfo.secondFileLocations, target); } else { - if (!isSourcePlainJs) addDuplicateDeclarationErrorsForSymbols(source, message, symbolName, target); - if (!isTargetPlainJs) addDuplicateDeclarationErrorsForSymbols(target, message, symbolName, source); + if (!isSourcePlainJs) + addDuplicateDeclarationErrorsForSymbols(source, message, symbolName, target); + if (!isTargetPlainJs) + addDuplicateDeclarationErrorsForSymbols(target, message, symbolName, source); } } return target; - function addDuplicateLocations(locs: Declaration[], symbol: Symbol): void { + function addDuplicateLocations(locs: ts.Declaration[], symbol: ts.Symbol): void { if (symbol.declarations) { for (const decl of symbol.declarations) { - pushIfUnique(locs, decl); + ts.pushIfUnique(locs, decl); } } } } - function addDuplicateDeclarationErrorsForSymbols(target: Symbol, message: DiagnosticMessage, symbolName: string, source: Symbol) { - forEach(target.declarations, node => { + function addDuplicateDeclarationErrorsForSymbols(target: ts.Symbol, message: ts.DiagnosticMessage, symbolName: string, source: ts.Symbol) { + ts.forEach(target.declarations, node => { addDuplicateDeclarationError(node, message, symbolName, source.declarations); }); } - function addDuplicateDeclarationError(node: Declaration, message: DiagnosticMessage, symbolName: string, relatedNodes: readonly Declaration[] | undefined) { - const errorNode = (getExpandoInitializer(node, /*isPrototypeAssignment*/ false) ? getNameOfExpando(node) : getNameOfDeclaration(node)) || node; + function addDuplicateDeclarationError(node: ts.Declaration, message: ts.DiagnosticMessage, symbolName: string, relatedNodes: readonly ts.Declaration[] | undefined) { + const errorNode = (ts.getExpandoInitializer(node, /*isPrototypeAssignment*/ false) ? ts.getNameOfExpando(node) : ts.getNameOfDeclaration(node)) || node; const err = lookupOrIssueError(errorNode, message, symbolName); - for (const relatedNode of relatedNodes || emptyArray) { - const adjustedNode = (getExpandoInitializer(relatedNode, /*isPrototypeAssignment*/ false) ? getNameOfExpando(relatedNode) : getNameOfDeclaration(relatedNode)) || relatedNode; - if (adjustedNode === errorNode) continue; + for (const relatedNode of relatedNodes || ts.emptyArray) { + const adjustedNode = (ts.getExpandoInitializer(relatedNode, /*isPrototypeAssignment*/ false) ? ts.getNameOfExpando(relatedNode) : ts.getNameOfDeclaration(relatedNode)) || relatedNode; + if (adjustedNode === errorNode) + continue; err.relatedInformation = err.relatedInformation || []; - const leadingMessage = createDiagnosticForNode(adjustedNode, Diagnostics._0_was_also_declared_here, symbolName); - const followOnMessage = createDiagnosticForNode(adjustedNode, Diagnostics.and_here); - if (length(err.relatedInformation) >= 5 || some(err.relatedInformation, r => compareDiagnostics(r, followOnMessage) === Comparison.EqualTo || compareDiagnostics(r, leadingMessage) === Comparison.EqualTo)) continue; - addRelatedInfo(err, !length(err.relatedInformation) ? leadingMessage : followOnMessage); + const leadingMessage = ts.createDiagnosticForNode(adjustedNode, ts.Diagnostics._0_was_also_declared_here, symbolName); + const followOnMessage = ts.createDiagnosticForNode(adjustedNode, ts.Diagnostics.and_here); + if (ts.length(err.relatedInformation) >= 5 || ts.some(err.relatedInformation, r => ts.compareDiagnostics(r, followOnMessage) === ts.Comparison.EqualTo || ts.compareDiagnostics(r, leadingMessage) === ts.Comparison.EqualTo)) + continue; + ts.addRelatedInfo(err, !ts.length(err.relatedInformation) ? leadingMessage : followOnMessage); } } - function combineSymbolTables(first: SymbolTable | undefined, second: SymbolTable | undefined): SymbolTable | undefined { - if (!first?.size) return second; - if (!second?.size) return first; - const combined = createSymbolTable(); + function combineSymbolTables(first: ts.SymbolTable | undefined, second: ts.SymbolTable | undefined): ts.SymbolTable | undefined { + if (!first?.size) + return second; + if (!second?.size) + return first; + const combined = ts.createSymbolTable(); mergeSymbolTable(combined, first); mergeSymbolTable(combined, second); return combined; } - function mergeSymbolTable(target: SymbolTable, source: SymbolTable, unidirectional = false) { + function mergeSymbolTable(target: ts.SymbolTable, source: ts.SymbolTable, unidirectional = false) { source.forEach((sourceSymbol, id) => { const targetSymbol = target.get(id); target.set(id, targetSymbol ? mergeSymbol(targetSymbol, sourceSymbol, unidirectional) : sourceSymbol); }); } - function mergeModuleAugmentation(moduleName: StringLiteral | Identifier): void { - const moduleAugmentation = moduleName.parent as ModuleDeclaration; + function mergeModuleAugmentation(moduleName: ts.StringLiteral | ts.Identifier): void { + const moduleAugmentation = moduleName.parent as ts.ModuleDeclaration; if (moduleAugmentation.symbol.declarations?.[0] !== moduleAugmentation) { // this is a combined symbol for multiple augmentations within the same file. // its symbol already has accumulated information for all declarations // so we need to add it just once - do the work only for first declaration - Debug.assert(moduleAugmentation.symbol.declarations!.length > 1); + ts.Debug.assert(moduleAugmentation.symbol.declarations!.length > 1); return; } - if (isGlobalScopeAugmentation(moduleAugmentation)) { + if (ts.isGlobalScopeAugmentation(moduleAugmentation)) { mergeSymbolTable(globals, moduleAugmentation.symbol.exports!); } else { // find a module that about to be augmented // do not validate names of augmentations that are defined in ambient context - const moduleNotFoundError = !(moduleName.parent.parent.flags & NodeFlags.Ambient) - ? Diagnostics.Invalid_module_name_in_augmentation_module_0_cannot_be_found + const moduleNotFoundError = !(moduleName.parent.parent.flags & ts.NodeFlags.Ambient) + ? ts.Diagnostics.Invalid_module_name_in_augmentation_module_0_cannot_be_found : undefined; let mainModule = resolveExternalModuleNameWorker(moduleName, moduleName, moduleNotFoundError, /*isForAugmentation*/ true); if (!mainModule) { @@ -1442,25 +1432,25 @@ namespace ts { } // obtain item referenced by 'export=' mainModule = resolveExternalModuleSymbol(mainModule); - if (mainModule.flags & SymbolFlags.Namespace) { + if (mainModule.flags & ts.SymbolFlags.Namespace) { // If we're merging an augmentation to a pattern ambient module, we want to // perform the merge unidirectionally from the augmentation ('a.foo') to // the pattern ('*.foo'), so that 'getMergedSymbol()' on a.foo gives you // all the exports both from the pattern and from the augmentation, but // 'getMergedSymbol()' on *.foo only gives you exports from *.foo. - if (some(patternAmbientModules, module => mainModule === module.symbol)) { + if (ts.some(patternAmbientModules, module => mainModule === module.symbol)) { const merged = mergeSymbol(moduleAugmentation.symbol, mainModule, /*unidirectional*/ true); if (!patternAmbientModuleAugmentations) { - patternAmbientModuleAugmentations = new Map(); + patternAmbientModuleAugmentations = new ts.Map(); } // moduleName will be a StringLiteral since this is not `declare global`. - patternAmbientModuleAugmentations.set((moduleName as StringLiteral).text, merged); + patternAmbientModuleAugmentations.set((moduleName as ts.StringLiteral).text, merged); } else { - if (mainModule.exports?.get(InternalSymbolName.ExportStar) && moduleAugmentation.symbol.exports?.size) { + if (mainModule.exports?.get(ts.InternalSymbolName.ExportStar) && moduleAugmentation.symbol.exports?.size) { // We may need to merge the module augmentation's exports into the target symbols of the resolved exports const resolvedExports = getResolvedMembersOrExportsOfSymbol(mainModule, MembersOrExportsResolutionKind.resolvedExports); - for (const [key, value] of arrayFrom(moduleAugmentation.symbol.exports.entries())) { + for (const [key, value] of ts.arrayFrom(moduleAugmentation.symbol.exports.entries())) { if (resolvedExports.has(key) && !mainModule.exports.has(key)) { mergeSymbol(resolvedExports.get(key)!, value); } @@ -1471,52 +1461,53 @@ namespace ts { } else { // moduleName will be a StringLiteral since this is not `declare global`. - error(moduleName, Diagnostics.Cannot_augment_module_0_because_it_resolves_to_a_non_module_entity, (moduleName as StringLiteral).text); + error(moduleName, ts.Diagnostics.Cannot_augment_module_0_because_it_resolves_to_a_non_module_entity, (moduleName as ts.StringLiteral).text); } } } - function addToSymbolTable(target: SymbolTable, source: SymbolTable, message: DiagnosticMessage) { + function addToSymbolTable(target: ts.SymbolTable, source: ts.SymbolTable, message: ts.DiagnosticMessage) { source.forEach((sourceSymbol, id) => { const targetSymbol = target.get(id); if (targetSymbol) { // Error on redeclarations - forEach(targetSymbol.declarations, addDeclarationDiagnostic(unescapeLeadingUnderscores(id), message)); + ts.forEach(targetSymbol.declarations, addDeclarationDiagnostic(ts.unescapeLeadingUnderscores(id), message)); } else { target.set(id, sourceSymbol); } }); - function addDeclarationDiagnostic(id: string, message: DiagnosticMessage) { - return (declaration: Declaration) => diagnostics.add(createDiagnosticForNode(declaration, message, id)); + function addDeclarationDiagnostic(id: string, message: ts.DiagnosticMessage) { + return (declaration: ts.Declaration) => diagnostics.add(ts.createDiagnosticForNode(declaration, message, id)); } } - function getSymbolLinks(symbol: Symbol): SymbolLinks { - if (symbol.flags & SymbolFlags.Transient) return symbol as TransientSymbol; + function getSymbolLinks(symbol: ts.Symbol): ts.SymbolLinks { + if (symbol.flags & ts.SymbolFlags.Transient) + return symbol as ts.TransientSymbol; const id = getSymbolId(symbol); return symbolLinks[id] || (symbolLinks[id] = new (SymbolLinks as any)()); } - function getNodeLinks(node: Node): NodeLinks { + function getNodeLinks(node: ts.Node): ts.NodeLinks { const nodeId = getNodeId(node); return nodeLinks[nodeId] || (nodeLinks[nodeId] = new (NodeLinks as any)()); } - function isGlobalSourceFile(node: Node) { - return node.kind === SyntaxKind.SourceFile && !isExternalOrCommonJsModule(node as SourceFile); + function isGlobalSourceFile(node: ts.Node) { + return node.kind === ts.SyntaxKind.SourceFile && !ts.isExternalOrCommonJsModule(node as ts.SourceFile); } - function getSymbol(symbols: SymbolTable, name: __String, meaning: SymbolFlags): Symbol | undefined { + function getSymbol(symbols: ts.SymbolTable, name: ts.__String, meaning: ts.SymbolFlags): ts.Symbol | undefined { if (meaning) { const symbol = getMergedSymbol(symbols.get(name)); if (symbol) { - Debug.assert((getCheckFlags(symbol) & CheckFlags.Instantiated) === 0, "Should never get an instantiated symbol here."); + ts.Debug.assert((ts.getCheckFlags(symbol) & ts.CheckFlags.Instantiated) === 0, "Should never get an instantiated symbol here."); if (symbol.flags & meaning) { return symbol; } - if (symbol.flags & SymbolFlags.Alias) { + if (symbol.flags & ts.SymbolFlags.Alias) { const target = resolveAlias(symbol); // Unknown symbol means an error occurred in alias resolution, treat it as positive answer to avoid cascading errors if (target === unknownSymbol || target.flags & meaning) { @@ -1534,29 +1525,32 @@ namespace ts { * @param parameterName a name of the parameter to get the symbols for. * @return a tuple of two symbols */ - function getSymbolsOfParameterPropertyDeclaration(parameter: ParameterDeclaration, parameterName: __String): [Symbol, Symbol] { + function getSymbolsOfParameterPropertyDeclaration(parameter: ts.ParameterDeclaration, parameterName: ts.__String): [ + ts.Symbol, + ts.Symbol + ] { const constructorDeclaration = parameter.parent; const classDeclaration = parameter.parent.parent; - const parameterSymbol = getSymbol(constructorDeclaration.locals!, parameterName, SymbolFlags.Value); - const propertySymbol = getSymbol(getMembersOfSymbol(classDeclaration.symbol), parameterName, SymbolFlags.Value); + const parameterSymbol = getSymbol(constructorDeclaration.locals!, parameterName, ts.SymbolFlags.Value); + const propertySymbol = getSymbol(getMembersOfSymbol(classDeclaration.symbol), parameterName, ts.SymbolFlags.Value); if (parameterSymbol && propertySymbol) { return [parameterSymbol, propertySymbol]; } - return Debug.fail("There should exist two symbols, one as property declaration and one as parameter declaration"); + return ts.Debug.fail("There should exist two symbols, one as property declaration and one as parameter declaration"); } - function isBlockScopedNameDeclaredBeforeUse(declaration: Declaration, usage: Node): boolean { - const declarationFile = getSourceFileOfNode(declaration); - const useFile = getSourceFileOfNode(usage); - const declContainer = getEnclosingBlockScopeContainer(declaration); + function isBlockScopedNameDeclaredBeforeUse(declaration: ts.Declaration, usage: ts.Node): boolean { + const declarationFile = ts.getSourceFileOfNode(declaration); + const useFile = ts.getSourceFileOfNode(usage); + const declContainer = ts.getEnclosingBlockScopeContainer(declaration); if (declarationFile !== useFile) { if ((moduleKind && (declarationFile.externalModuleIndicator || useFile.externalModuleIndicator)) || - (!outFile(compilerOptions)) || + (!ts.outFile(compilerOptions)) || isInTypeQuery(usage) || - declaration.flags & NodeFlags.Ambient) { + declaration.flags & ts.NodeFlags.Ambient) { // nodes are in different files and order cannot be determined return true; } @@ -1569,34 +1563,34 @@ namespace ts { return sourceFiles.indexOf(declarationFile) <= sourceFiles.indexOf(useFile); } - if (declaration.pos <= usage.pos && !(isPropertyDeclaration(declaration) && isThisProperty(usage.parent) && !declaration.initializer && !declaration.exclamationToken)) { + if (declaration.pos <= usage.pos && !(ts.isPropertyDeclaration(declaration) && ts.isThisProperty(usage.parent) && !declaration.initializer && !declaration.exclamationToken)) { // declaration is before usage - if (declaration.kind === SyntaxKind.BindingElement) { + if (declaration.kind === ts.SyntaxKind.BindingElement) { // still might be illegal if declaration and usage are both binding elements (eg var [a = b, b = b] = [1, 2]) - const errorBindingElement = getAncestor(usage, SyntaxKind.BindingElement) as BindingElement; + const errorBindingElement = ts.getAncestor(usage, ts.SyntaxKind.BindingElement) as ts.BindingElement; if (errorBindingElement) { - return findAncestor(errorBindingElement, isBindingElement) !== findAncestor(declaration, isBindingElement) || + return ts.findAncestor(errorBindingElement, ts.isBindingElement) !== ts.findAncestor(declaration, ts.isBindingElement) || declaration.pos < errorBindingElement.pos; } // or it might be illegal if usage happens before parent variable is declared (eg var [a] = a) - return isBlockScopedNameDeclaredBeforeUse(getAncestor(declaration, SyntaxKind.VariableDeclaration) as Declaration, usage); + return isBlockScopedNameDeclaredBeforeUse(ts.getAncestor(declaration, ts.SyntaxKind.VariableDeclaration) as ts.Declaration, usage); } - else if (declaration.kind === SyntaxKind.VariableDeclaration) { + else if (declaration.kind === ts.SyntaxKind.VariableDeclaration) { // still might be illegal if usage is in the initializer of the variable declaration (eg var a = a) - return !isImmediatelyUsedInInitializerOfBlockScopedVariable(declaration as VariableDeclaration, usage); + return !isImmediatelyUsedInInitializerOfBlockScopedVariable(declaration as ts.VariableDeclaration, usage); } - else if (isClassDeclaration(declaration)) { + else if (ts.isClassDeclaration(declaration)) { // still might be illegal if the usage is within a computed property name in the class (eg class A { static p = "a"; [A.p]() {} }) - return !findAncestor(usage, n => isComputedPropertyName(n) && n.parent.parent === declaration); + return !ts.findAncestor(usage, n => ts.isComputedPropertyName(n) && n.parent.parent === declaration); } - else if (isPropertyDeclaration(declaration)) { + else if (ts.isPropertyDeclaration(declaration)) { // still might be illegal if a self-referencing property initializer (eg private x = this.x) return !isPropertyImmediatelyReferencedWithinDeclaration(declaration, usage, /*stopAtAnyPropertyDeclaration*/ false); } - else if (isParameterPropertyDeclaration(declaration, declaration.parent)) { + else if (ts.isParameterPropertyDeclaration(declaration, declaration.parent)) { // foo = this.bar is illegal in esnext+useDefineForClassFields when bar is a parameter property - return !(getEmitScriptTarget(compilerOptions) === ScriptTarget.ESNext && useDefineForClassFields - && getContainingClass(declaration) === getContainingClass(usage) + return !(ts.getEmitScriptTarget(compilerOptions) === ts.ScriptTarget.ESNext && useDefineForClassFields + && ts.getContainingClass(declaration) === ts.getContainingClass(usage) && isUsedInFunctionOrInstanceProperty(usage, declaration)); } return true; @@ -1613,22 +1607,22 @@ namespace ts { // or if usage is in a type context: // 1. inside a type query (typeof in type position) // 2. inside a jsdoc comment - if (usage.parent.kind === SyntaxKind.ExportSpecifier || (usage.parent.kind === SyntaxKind.ExportAssignment && (usage.parent as ExportAssignment).isExportEquals)) { + if (usage.parent.kind === ts.SyntaxKind.ExportSpecifier || (usage.parent.kind === ts.SyntaxKind.ExportAssignment && (usage.parent as ts.ExportAssignment).isExportEquals)) { // export specifiers do not use the variable, they only make it available for use return true; } // When resolving symbols for exports, the `usage` location passed in can be the export site directly - if (usage.kind === SyntaxKind.ExportAssignment && (usage as ExportAssignment).isExportEquals) { + if (usage.kind === ts.SyntaxKind.ExportAssignment && (usage as ts.ExportAssignment).isExportEquals) { return true; } - if (!!(usage.flags & NodeFlags.JSDoc) || isInTypeQuery(usage) || usageInTypeDeclaration()) { + if (!!(usage.flags & ts.NodeFlags.JSDoc) || isInTypeQuery(usage) || usageInTypeDeclaration()) { return true; } if (isUsedInFunctionOrInstanceProperty(usage, declaration)) { - if (getEmitScriptTarget(compilerOptions) === ScriptTarget.ESNext && useDefineForClassFields - && getContainingClass(declaration) - && (isPropertyDeclaration(declaration) || isParameterPropertyDeclaration(declaration, declaration.parent))) { + if (ts.getEmitScriptTarget(compilerOptions) === ts.ScriptTarget.ESNext && useDefineForClassFields + && ts.getContainingClass(declaration) + && (ts.isPropertyDeclaration(declaration) || ts.isParameterPropertyDeclaration(declaration, declaration.parent))) { return !isPropertyImmediatelyReferencedWithinDeclaration(declaration, usage, /*stopAtAnyPropertyDeclaration*/ true); } else { @@ -1638,14 +1632,14 @@ namespace ts { return false; function usageInTypeDeclaration() { - return !!findAncestor(usage, node => isInterfaceDeclaration(node) || isTypeAliasDeclaration(node)); + return !!ts.findAncestor(usage, node => ts.isInterfaceDeclaration(node) || ts.isTypeAliasDeclaration(node)); } - function isImmediatelyUsedInInitializerOfBlockScopedVariable(declaration: VariableDeclaration, usage: Node): boolean { + function isImmediatelyUsedInInitializerOfBlockScopedVariable(declaration: ts.VariableDeclaration, usage: ts.Node): boolean { switch (declaration.parent.parent.kind) { - case SyntaxKind.VariableStatement: - case SyntaxKind.ForStatement: - case SyntaxKind.ForOfStatement: + case ts.SyntaxKind.VariableStatement: + case ts.SyntaxKind.ForStatement: + case ts.SyntaxKind.ForOfStatement: // variable statement/for/for-of statement case, // use site should not be inside variable declaration (initializer of declaration or binding element) if (isSameScopeDescendentOf(usage, declaration, declContainer)) { @@ -1656,34 +1650,34 @@ namespace ts { // ForIn/ForOf case - use site should not be used in expression part const grandparent = declaration.parent.parent; - return isForInOrOfStatement(grandparent) && isSameScopeDescendentOf(usage, grandparent.expression, declContainer); + return ts.isForInOrOfStatement(grandparent) && isSameScopeDescendentOf(usage, grandparent.expression, declContainer); } - function isUsedInFunctionOrInstanceProperty(usage: Node, declaration: Node): boolean { - return !!findAncestor(usage, current => { + function isUsedInFunctionOrInstanceProperty(usage: ts.Node, declaration: ts.Node): boolean { + return !!ts.findAncestor(usage, current => { if (current === declContainer) { return "quit"; } - if (isFunctionLike(current)) { + if (ts.isFunctionLike(current)) { return true; } - if (isClassStaticBlockDeclaration(current)) { + if (ts.isClassStaticBlockDeclaration(current)) { return declaration.pos < usage.pos; } - const propertyDeclaration = tryCast(current.parent, isPropertyDeclaration); + const propertyDeclaration = ts.tryCast(current.parent, ts.isPropertyDeclaration); if (propertyDeclaration) { const initializerOfProperty = propertyDeclaration.initializer === current; if (initializerOfProperty) { - if (isStatic(current.parent)) { - if (declaration.kind === SyntaxKind.MethodDeclaration) { + if (ts.isStatic(current.parent)) { + if (declaration.kind === ts.SyntaxKind.MethodDeclaration) { return true; } - if (isPropertyDeclaration(declaration) && getContainingClass(usage) === getContainingClass(declaration)) { + if (ts.isPropertyDeclaration(declaration) && ts.getContainingClass(usage) === ts.getContainingClass(declaration)) { const propName = declaration.name; - if (isIdentifier(propName) || isPrivateIdentifier(propName)) { + if (ts.isIdentifier(propName) || ts.isPrivateIdentifier(propName)) { const type = getTypeOfSymbol(getSymbolOfNode(declaration)); - const staticBlocks = filter(declaration.parent.members, isClassStaticBlockDeclaration); + const staticBlocks = ts.filter(declaration.parent.members, ts.isClassStaticBlockDeclaration); if (isPropertyInitializedInStaticBlocks(propName, type, staticBlocks, declaration.parent.pos, current.pos)) { return true; } @@ -1691,8 +1685,8 @@ namespace ts { } } else { - const isDeclarationInstanceProperty = declaration.kind === SyntaxKind.PropertyDeclaration && !isStatic(declaration); - if (!isDeclarationInstanceProperty || getContainingClass(usage) !== getContainingClass(declaration)) { + const isDeclarationInstanceProperty = declaration.kind === ts.SyntaxKind.PropertyDeclaration && !ts.isStatic(declaration); + if (!isDeclarationInstanceProperty || ts.getContainingClass(usage) !== ts.getContainingClass(declaration)) { return true; } } @@ -1703,7 +1697,7 @@ namespace ts { } /** stopAtAnyPropertyDeclaration is used for detecting ES-standard class field use-before-def errors */ - function isPropertyImmediatelyReferencedWithinDeclaration(declaration: PropertyDeclaration | ParameterPropertyDeclaration, usage: Node, stopAtAnyPropertyDeclaration: boolean) { + function isPropertyImmediatelyReferencedWithinDeclaration(declaration: ts.PropertyDeclaration | ts.ParameterPropertyDeclaration, usage: ts.Node, stopAtAnyPropertyDeclaration: boolean) { // always legal if usage is after declaration if (usage.end > declaration.end) { return false; @@ -1711,25 +1705,25 @@ namespace ts { // still might be legal if usage is deferred (e.g. x: any = () => this.x) // otherwise illegal if immediately referenced within the declaration (e.g. x: any = this.x) - const ancestorChangingReferenceScope = findAncestor(usage, (node: Node) => { + const ancestorChangingReferenceScope = ts.findAncestor(usage, (node: ts.Node) => { if (node === declaration) { return "quit"; } switch (node.kind) { - case SyntaxKind.ArrowFunction: + case ts.SyntaxKind.ArrowFunction: return true; - case SyntaxKind.PropertyDeclaration: + case ts.SyntaxKind.PropertyDeclaration: // even when stopping at any property declaration, they need to come from the same class return stopAtAnyPropertyDeclaration && - (isPropertyDeclaration(declaration) && node.parent === declaration.parent - || isParameterPropertyDeclaration(declaration, declaration.parent) && node.parent === declaration.parent.parent) + (ts.isPropertyDeclaration(declaration) && node.parent === declaration.parent + || ts.isParameterPropertyDeclaration(declaration, declaration.parent) && node.parent === declaration.parent.parent) ? "quit": true; - case SyntaxKind.Block: + case ts.SyntaxKind.Block: switch (node.parent.kind) { - case SyntaxKind.GetAccessor: - case SyntaxKind.MethodDeclaration: - case SyntaxKind.SetAccessor: + case ts.SyntaxKind.GetAccessor: + case ts.SyntaxKind.MethodDeclaration: + case ts.SyntaxKind.SetAccessor: return true; default: return false; @@ -1743,10 +1737,10 @@ namespace ts { } } - function useOuterVariableScopeInParameter(result: Symbol, location: Node, lastLocation: Node) { - const target = getEmitScriptTarget(compilerOptions); - const functionLocation = location as FunctionLikeDeclaration; - if (isParameter(lastLocation) + function useOuterVariableScopeInParameter(result: ts.Symbol, location: ts.Node, lastLocation: ts.Node) { + const target = ts.getEmitScriptTarget(compilerOptions); + const functionLocation = location as ts.FunctionLikeDeclaration; + if (ts.isParameter(lastLocation) && functionLocation.body && result.valueDeclaration && result.valueDeclaration.pos >= functionLocation.body.pos @@ -1756,57 +1750,58 @@ namespace ts { // - optional chaining pre-es2020 // - nullish coalesce pre-es2020 // - spread assignment in binding pattern pre-es2017 - if (target >= ScriptTarget.ES2015) { + if (target >= ts.ScriptTarget.ES2015) { const links = getNodeLinks(functionLocation); if (links.declarationRequiresScopeChange === undefined) { - links.declarationRequiresScopeChange = forEach(functionLocation.parameters, requiresScopeChange) || false; + links.declarationRequiresScopeChange = ts.forEach(functionLocation.parameters, requiresScopeChange) || false; } return !links.declarationRequiresScopeChange; } } return false; - function requiresScopeChange(node: ParameterDeclaration): boolean { + function requiresScopeChange(node: ts.ParameterDeclaration): boolean { return requiresScopeChangeWorker(node.name) || !!node.initializer && requiresScopeChangeWorker(node.initializer); } - function requiresScopeChangeWorker(node: Node): boolean { + function requiresScopeChangeWorker(node: ts.Node): boolean { switch (node.kind) { - case SyntaxKind.ArrowFunction: - case SyntaxKind.FunctionExpression: - case SyntaxKind.FunctionDeclaration: - case SyntaxKind.Constructor: + case ts.SyntaxKind.ArrowFunction: + case ts.SyntaxKind.FunctionExpression: + case ts.SyntaxKind.FunctionDeclaration: + case ts.SyntaxKind.Constructor: // do not descend into these return false; - case SyntaxKind.MethodDeclaration: - case SyntaxKind.GetAccessor: - case SyntaxKind.SetAccessor: - case SyntaxKind.PropertyAssignment: - return requiresScopeChangeWorker((node as MethodDeclaration | AccessorDeclaration | PropertyAssignment).name); - case SyntaxKind.PropertyDeclaration: + case ts.SyntaxKind.MethodDeclaration: + case ts.SyntaxKind.GetAccessor: + case ts.SyntaxKind.SetAccessor: + case ts.SyntaxKind.PropertyAssignment: + return requiresScopeChangeWorker((node as ts.MethodDeclaration | ts.AccessorDeclaration | ts.PropertyAssignment).name); + case ts.SyntaxKind.PropertyDeclaration: // static properties in classes introduce temporary variables - if (hasStaticModifier(node)) { - return target < ScriptTarget.ESNext || !useDefineForClassFields; + if (ts.hasStaticModifier(node)) { + return target < ts.ScriptTarget.ESNext || !useDefineForClassFields; } - return requiresScopeChangeWorker((node as PropertyDeclaration).name); + return requiresScopeChangeWorker((node as ts.PropertyDeclaration).name); default: // null coalesce and optional chain pre-es2020 produce temporary variables - if (isNullishCoalesce(node) || isOptionalChain(node)) { - return target < ScriptTarget.ES2020; + if (ts.isNullishCoalesce(node) || ts.isOptionalChain(node)) { + return target < ts.ScriptTarget.ES2020; } - if (isBindingElement(node) && node.dotDotDotToken && isObjectBindingPattern(node.parent)) { - return target < ScriptTarget.ES2017; + if (ts.isBindingElement(node) && node.dotDotDotToken && ts.isObjectBindingPattern(node.parent)) { + return target < ts.ScriptTarget.ES2017; } - if (isTypeNode(node)) return false; - return forEachChild(node, requiresScopeChangeWorker) || false; + if (ts.isTypeNode(node)) + return false; + return ts.forEachChild(node, requiresScopeChangeWorker) || false; } } } - function isConstAssertion(location: Node) { - return (isAssertionExpression(location) && isConstTypeReference(location.type)) - || (isJSDocTypeTag(location) && isConstTypeReference(location.typeExpression)); + function isConstAssertion(location: ts.Node) { + return (ts.isAssertionExpression(location) && ts.isConstTypeReference(location.type)) + || (ts.isJSDocTypeTag(location) && ts.isConstTypeReference(location.typeExpression)); } /** @@ -1816,37 +1811,20 @@ namespace ts { * * @param isUse If true, this will count towards --noUnusedLocals / --noUnusedParameters. */ - function resolveName( - location: Node | undefined, - name: __String, - meaning: SymbolFlags, - nameNotFoundMessage: DiagnosticMessage | undefined, - nameArg: __String | Identifier | undefined, - isUse: boolean, - excludeGlobals = false, - getSpellingSuggstions = true): Symbol | undefined { + function resolveName(location: ts.Node | undefined, name: ts.__String, meaning: ts.SymbolFlags, nameNotFoundMessage: ts.DiagnosticMessage | undefined, nameArg: ts.__String | ts.Identifier | undefined, isUse: boolean, excludeGlobals = false, getSpellingSuggstions = true): ts.Symbol | undefined { return resolveNameHelper(location, name, meaning, nameNotFoundMessage, nameArg, isUse, excludeGlobals, getSpellingSuggstions, getSymbol); } - function resolveNameHelper( - location: Node | undefined, - name: __String, - meaning: SymbolFlags, - nameNotFoundMessage: DiagnosticMessage | undefined, - nameArg: __String | Identifier | undefined, - isUse: boolean, - excludeGlobals: boolean, - getSpellingSuggestions: boolean, - lookup: typeof getSymbol): Symbol | undefined { + function resolveNameHelper(location: ts.Node | undefined, name: ts.__String, meaning: ts.SymbolFlags, nameNotFoundMessage: ts.DiagnosticMessage | undefined, nameArg: ts.__String | ts.Identifier | undefined, isUse: boolean, excludeGlobals: boolean, getSpellingSuggestions: boolean, lookup: typeof getSymbol): ts.Symbol | undefined { const originalLocation = location; // needed for did-you-mean error reporting, which gathers candidates starting from the original location - let result: Symbol | undefined; - let lastLocation: Node | undefined; - let lastSelfReferenceLocation: Node | undefined; - let propertyWithInvalidInitializer: Node | undefined; - let associatedDeclarationForContainingInitializerOrBindingName: ParameterDeclaration | BindingElement | undefined; + let result: ts.Symbol | undefined; + let lastLocation: ts.Node | undefined; + let lastSelfReferenceLocation: ts.Node | undefined; + let propertyWithInvalidInitializer: ts.Node | undefined; + let associatedDeclarationForContainingInitializerOrBindingName: ts.ParameterDeclaration | ts.BindingElement | undefined; let withinDeferredContext = false; const errorLocation = location; - let grandparent: Node; + let grandparent: ts.Node; let isInExternalModule = false; loop: while (location) { @@ -1859,47 +1837,45 @@ namespace ts { if (location.locals && !isGlobalSourceFile(location)) { if (result = lookup(location.locals, name, meaning)) { let useResult = true; - if (isFunctionLike(location) && lastLocation && lastLocation !== (location as FunctionLikeDeclaration).body) { + if (ts.isFunctionLike(location) && lastLocation && lastLocation !== (location as ts.FunctionLikeDeclaration).body) { // symbol lookup restrictions for function-like declarations // - Type parameters of a function are in scope in the entire function declaration, including the parameter // list and return type. However, local types are only in scope in the function body. // - parameters are only in the scope of function body // This restriction does not apply to JSDoc comment types because they are parented // at a higher level than type parameters would normally be - if (meaning & result.flags & SymbolFlags.Type && lastLocation.kind !== SyntaxKind.JSDoc) { - useResult = result.flags & SymbolFlags.TypeParameter + if (meaning & result.flags & ts.SymbolFlags.Type && lastLocation.kind !== ts.SyntaxKind.JSDoc) { + useResult = result.flags & ts.SymbolFlags.TypeParameter // type parameters are visible in parameter list, return type and type parameter list - ? lastLocation === (location as FunctionLikeDeclaration).type || - lastLocation.kind === SyntaxKind.Parameter || - lastLocation.kind === SyntaxKind.JSDocParameterTag || - lastLocation.kind === SyntaxKind.JSDocReturnTag || - lastLocation.kind === SyntaxKind.TypeParameter + ? lastLocation === (location as ts.FunctionLikeDeclaration).type || + lastLocation.kind === ts.SyntaxKind.Parameter || + lastLocation.kind === ts.SyntaxKind.JSDocParameterTag || + lastLocation.kind === ts.SyntaxKind.JSDocReturnTag || + lastLocation.kind === ts.SyntaxKind.TypeParameter // local types not visible outside the function body : false; } - if (meaning & result.flags & SymbolFlags.Variable) { + if (meaning & result.flags & ts.SymbolFlags.Variable) { // expression inside parameter will lookup as normal variable scope when targeting es2015+ if (useOuterVariableScopeInParameter(result, location, lastLocation)) { useResult = false; } - else if (result.flags & SymbolFlags.FunctionScopedVariable) { + else if (result.flags & ts.SymbolFlags.FunctionScopedVariable) { // parameters are visible only inside function body, parameter list and return type // technically for parameter list case here we might mix parameters and variables declared in function, // however it is detected separately when checking initializers of parameters // to make sure that they reference no variables declared after them. useResult = - lastLocation.kind === SyntaxKind.Parameter || - ( - lastLocation === (location as FunctionLikeDeclaration).type && - !!findAncestor(result.valueDeclaration, isParameter) - ); + lastLocation.kind === ts.SyntaxKind.Parameter || + (lastLocation === (location as ts.FunctionLikeDeclaration).type && + !!ts.findAncestor(result.valueDeclaration, ts.isParameter)); } } } - else if (location.kind === SyntaxKind.ConditionalType) { + else if (location.kind === ts.SyntaxKind.ConditionalType) { // A type parameter declared using 'infer T' in a conditional type is visible only in // the true branch of the conditional type. - useResult = lastLocation === (location as ConditionalTypeNode).trueType; + useResult = lastLocation === (location as ts.ConditionalTypeNode).trueType; } if (useResult) { @@ -1912,18 +1888,19 @@ namespace ts { } withinDeferredContext = withinDeferredContext || getIsDeferredContext(location, lastLocation); switch (location.kind) { - case SyntaxKind.SourceFile: - if (!isExternalOrCommonJsModule(location as SourceFile)) break; + case ts.SyntaxKind.SourceFile: + if (!ts.isExternalOrCommonJsModule(location as ts.SourceFile)) + break; isInExternalModule = true; // falls through - case SyntaxKind.ModuleDeclaration: - const moduleExports = getSymbolOfNode(location as SourceFile | ModuleDeclaration)?.exports || emptySymbols; - if (location.kind === SyntaxKind.SourceFile || (isModuleDeclaration(location) && location.flags & NodeFlags.Ambient && !isGlobalScopeAugmentation(location))) { + case ts.SyntaxKind.ModuleDeclaration: + const moduleExports = getSymbolOfNode(location as ts.SourceFile | ts.ModuleDeclaration)?.exports || emptySymbols; + if (location.kind === ts.SyntaxKind.SourceFile || (ts.isModuleDeclaration(location) && location.flags & ts.NodeFlags.Ambient && !ts.isGlobalScopeAugmentation(location))) { // It's an external module. First see if the module has an export default and if the local // name of that export default matches. - if (result = moduleExports.get(InternalSymbolName.Default)) { - const localSymbol = getLocalSymbolForExportDefault(result); + if (result = moduleExports.get(ts.InternalSymbolName.Default)) { + const localSymbol = ts.getLocalSymbolForExportDefault(result); if (localSymbol && (result.flags & meaning) && localSymbol.escapedName === name) { break loop; } @@ -1943,15 +1920,15 @@ namespace ts { // which is not the desired behavior. const moduleExport = moduleExports.get(name); if (moduleExport && - moduleExport.flags === SymbolFlags.Alias && - (getDeclarationOfKind(moduleExport, SyntaxKind.ExportSpecifier) || getDeclarationOfKind(moduleExport, SyntaxKind.NamespaceExport))) { + moduleExport.flags === ts.SymbolFlags.Alias && + (ts.getDeclarationOfKind(moduleExport, ts.SyntaxKind.ExportSpecifier) || ts.getDeclarationOfKind(moduleExport, ts.SyntaxKind.NamespaceExport))) { break; } } // ES6 exports are also visible locally (except for 'default'), but commonjs exports are not (except typedefs) - if (name !== InternalSymbolName.Default && (result = lookup(moduleExports, name, meaning & SymbolFlags.ModuleMember))) { - if (isSourceFile(location) && location.commonJsModuleIndicator && !result.declarations?.some(isJSDocTypeAlias)) { + if (name !== ts.InternalSymbolName.Default && (result = lookup(moduleExports, name, meaning & ts.SymbolFlags.ModuleMember))) { + if (ts.isSourceFile(location) && location.commonJsModuleIndicator && !result.declarations?.some(ts.isJSDocTypeAlias)) { result = undefined; } else { @@ -1959,64 +1936,64 @@ namespace ts { } } break; - case SyntaxKind.EnumDeclaration: - if (result = lookup(getSymbolOfNode(location)?.exports || emptySymbols, name, meaning & SymbolFlags.EnumMember)) { + case ts.SyntaxKind.EnumDeclaration: + if (result = lookup(getSymbolOfNode(location)?.exports || emptySymbols, name, meaning & ts.SymbolFlags.EnumMember)) { break loop; } break; - case SyntaxKind.PropertyDeclaration: + case ts.SyntaxKind.PropertyDeclaration: // TypeScript 1.0 spec (April 2014): 8.4.1 // Initializer expressions for instance member variables are evaluated in the scope // of the class constructor body but are not permitted to reference parameters or // local variables of the constructor. This effectively means that entities from outer scopes // by the same name as a constructor parameter or local variable are inaccessible // in initializer expressions for instance member variables. - if (!isStatic(location)) { - const ctor = findConstructorDeclaration(location.parent as ClassLikeDeclaration); + if (!ts.isStatic(location)) { + const ctor = findConstructorDeclaration(location.parent as ts.ClassLikeDeclaration); if (ctor && ctor.locals) { - if (lookup(ctor.locals, name, meaning & SymbolFlags.Value)) { + if (lookup(ctor.locals, name, meaning & ts.SymbolFlags.Value)) { // Remember the property node, it will be used later to report appropriate error propertyWithInvalidInitializer = location; } } } break; - case SyntaxKind.ClassDeclaration: - case SyntaxKind.ClassExpression: - case SyntaxKind.InterfaceDeclaration: + case ts.SyntaxKind.ClassDeclaration: + case ts.SyntaxKind.ClassExpression: + case ts.SyntaxKind.InterfaceDeclaration: // The below is used to lookup type parameters within a class or interface, as they are added to the class/interface locals // These can never be latebound, so the symbol's raw members are sufficient. `getMembersOfNode` cannot be used, as it would // trigger resolving late-bound names, which we may already be in the process of doing while we're here! - if (result = lookup(getSymbolOfNode(location as ClassLikeDeclaration | InterfaceDeclaration).members || emptySymbols, name, meaning & SymbolFlags.Type)) { + if (result = lookup(getSymbolOfNode(location as ts.ClassLikeDeclaration | ts.InterfaceDeclaration).members || emptySymbols, name, meaning & ts.SymbolFlags.Type)) { if (!isTypeParameterSymbolDeclaredInContainer(result, location)) { // ignore type parameters not declared in this container result = undefined; break; } - if (lastLocation && isStatic(lastLocation)) { + if (lastLocation && ts.isStatic(lastLocation)) { // TypeScript 1.0 spec (April 2014): 3.4.1 // The scope of a type parameter extends over the entire declaration with which the type // parameter list is associated, with the exception of static member declarations in classes. - error(errorLocation, Diagnostics.Static_members_cannot_reference_class_type_parameters); + error(errorLocation, ts.Diagnostics.Static_members_cannot_reference_class_type_parameters); return undefined; } break loop; } - if (location.kind === SyntaxKind.ClassExpression && meaning & SymbolFlags.Class) { - const className = (location as ClassExpression).name; + if (location.kind === ts.SyntaxKind.ClassExpression && meaning & ts.SymbolFlags.Class) { + const className = (location as ts.ClassExpression).name; if (className && name === className.escapedText) { result = location.symbol; break loop; } } break; - case SyntaxKind.ExpressionWithTypeArguments: + case ts.SyntaxKind.ExpressionWithTypeArguments: // The type parameters of a class are not in scope in the base class expression. - if (lastLocation === (location as ExpressionWithTypeArguments).expression && (location.parent as HeritageClause).token === SyntaxKind.ExtendsKeyword) { + if (lastLocation === (location as ts.ExpressionWithTypeArguments).expression && (location.parent as ts.HeritageClause).token === ts.SyntaxKind.ExtendsKeyword) { const container = location.parent.parent; - if (isClassLike(container) && (result = lookup(getSymbolOfNode(container).members!, name, meaning & SymbolFlags.Type))) { + if (ts.isClassLike(container) && (result = lookup(getSymbolOfNode(container).members!, name, meaning & ts.SymbolFlags.Type))) { if (nameNotFoundMessage) { - error(errorLocation, Diagnostics.Base_class_expressions_cannot_reference_class_type_parameters); + error(errorLocation, ts.Diagnostics.Base_class_expressions_cannot_reference_class_type_parameters); } return undefined; } @@ -2030,48 +2007,48 @@ namespace ts { // [foo()]() { } // <-- Reference to T from class's own computed property // } // - case SyntaxKind.ComputedPropertyName: + case ts.SyntaxKind.ComputedPropertyName: grandparent = location.parent.parent; - if (isClassLike(grandparent) || grandparent.kind === SyntaxKind.InterfaceDeclaration) { + if (ts.isClassLike(grandparent) || grandparent.kind === ts.SyntaxKind.InterfaceDeclaration) { // A reference to this grandparent's type parameters would be an error - if (result = lookup(getSymbolOfNode(grandparent as ClassLikeDeclaration | InterfaceDeclaration).members!, name, meaning & SymbolFlags.Type)) { - error(errorLocation, Diagnostics.A_computed_property_name_cannot_reference_a_type_parameter_from_its_containing_type); + if (result = lookup(getSymbolOfNode(grandparent as ts.ClassLikeDeclaration | ts.InterfaceDeclaration).members!, name, meaning & ts.SymbolFlags.Type)) { + error(errorLocation, ts.Diagnostics.A_computed_property_name_cannot_reference_a_type_parameter_from_its_containing_type); return undefined; } } break; - case SyntaxKind.ArrowFunction: + case ts.SyntaxKind.ArrowFunction: // when targeting ES6 or higher there is no 'arguments' in an arrow function // for lower compile targets the resolved symbol is used to emit an error - if (getEmitScriptTarget(compilerOptions) >= ScriptTarget.ES2015) { + if (ts.getEmitScriptTarget(compilerOptions) >= ts.ScriptTarget.ES2015) { break; } // falls through - case SyntaxKind.MethodDeclaration: - case SyntaxKind.Constructor: - case SyntaxKind.GetAccessor: - case SyntaxKind.SetAccessor: - case SyntaxKind.FunctionDeclaration: - if (meaning & SymbolFlags.Variable && name === "arguments") { + case ts.SyntaxKind.MethodDeclaration: + case ts.SyntaxKind.Constructor: + case ts.SyntaxKind.GetAccessor: + case ts.SyntaxKind.SetAccessor: + case ts.SyntaxKind.FunctionDeclaration: + if (meaning & ts.SymbolFlags.Variable && name === "arguments") { result = argumentsSymbol; break loop; } break; - case SyntaxKind.FunctionExpression: - if (meaning & SymbolFlags.Variable && name === "arguments") { + case ts.SyntaxKind.FunctionExpression: + if (meaning & ts.SymbolFlags.Variable && name === "arguments") { result = argumentsSymbol; break loop; } - if (meaning & SymbolFlags.Function) { - const functionName = (location as FunctionExpression).name; + if (meaning & ts.SymbolFlags.Function) { + const functionName = (location as ts.FunctionExpression).name; if (functionName && name === functionName.escapedText) { result = location.symbol; break loop; } } break; - case SyntaxKind.Decorator: + case ts.SyntaxKind.Decorator: // Decorators are resolved at the class declaration. Resolving at the parameter // or member would result in looking up locals in the method. // @@ -2080,7 +2057,7 @@ namespace ts { // method(@y x, y) {} // <-- decorator y should be resolved at the class declaration, not the parameter. // } // - if (location.parent && location.parent.kind === SyntaxKind.Parameter) { + if (location.parent && location.parent.kind === ts.SyntaxKind.Parameter) { location = location.parent; } // @@ -2096,42 +2073,40 @@ namespace ts { // declare function y(x: T): any; // @param(1 as T) // <-- T should resolve to the type alias outside of class C // class C {} - if (location.parent && (isClassElement(location.parent) || location.parent.kind === SyntaxKind.ClassDeclaration)) { + if (location.parent && (ts.isClassElement(location.parent) || location.parent.kind === ts.SyntaxKind.ClassDeclaration)) { location = location.parent; } break; - case SyntaxKind.JSDocTypedefTag: - case SyntaxKind.JSDocCallbackTag: - case SyntaxKind.JSDocEnumTag: + case ts.SyntaxKind.JSDocTypedefTag: + case ts.SyntaxKind.JSDocCallbackTag: + case ts.SyntaxKind.JSDocEnumTag: // js type aliases do not resolve names from their host, so skip past it - const root = getJSDocRoot(location); + const root = ts.getJSDocRoot(location); if (root) { location = root.parent; } break; - case SyntaxKind.Parameter: - if (lastLocation && ( - lastLocation === (location as ParameterDeclaration).initializer || - lastLocation === (location as ParameterDeclaration).name && isBindingPattern(lastLocation))) { + case ts.SyntaxKind.Parameter: + if (lastLocation && (lastLocation === (location as ts.ParameterDeclaration).initializer || + lastLocation === (location as ts.ParameterDeclaration).name && ts.isBindingPattern(lastLocation))) { if (!associatedDeclarationForContainingInitializerOrBindingName) { - associatedDeclarationForContainingInitializerOrBindingName = location as ParameterDeclaration; + associatedDeclarationForContainingInitializerOrBindingName = location as ts.ParameterDeclaration; } } break; - case SyntaxKind.BindingElement: - if (lastLocation && ( - lastLocation === (location as BindingElement).initializer || - lastLocation === (location as BindingElement).name && isBindingPattern(lastLocation))) { - if (isParameterDeclaration(location as BindingElement) && !associatedDeclarationForContainingInitializerOrBindingName) { - associatedDeclarationForContainingInitializerOrBindingName = location as BindingElement; + case ts.SyntaxKind.BindingElement: + if (lastLocation && (lastLocation === (location as ts.BindingElement).initializer || + lastLocation === (location as ts.BindingElement).name && ts.isBindingPattern(lastLocation))) { + if (ts.isParameterDeclaration(location as ts.BindingElement) && !associatedDeclarationForContainingInitializerOrBindingName) { + associatedDeclarationForContainingInitializerOrBindingName = location as ts.BindingElement; } } break; - case SyntaxKind.InferType: - if (meaning & SymbolFlags.TypeParameter) { - const parameterName = (location as InferTypeNode).typeParameter.name; + case ts.SyntaxKind.InferType: + if (meaning & ts.SymbolFlags.TypeParameter) { + const parameterName = (location as ts.InferTypeNode).typeParameter.name; if (parameterName && name === parameterName.escapedText) { - result = (location as InferTypeNode).typeParameter.symbol; + result = (location as ts.InferTypeNode).typeParameter.symbol; break loop; } } @@ -2141,8 +2116,8 @@ namespace ts { lastSelfReferenceLocation = location; } lastLocation = location; - location = isJSDocTemplateTag(location) ? getEffectiveContainerForJSDocTemplateTag(location) || location.parent : - isJSDocParameterTag(location) || isJSDocReturnTag(location) ? getHostSignatureFromJSDoc(location) || location.parent : + location = ts.isJSDocTemplateTag(location) ? ts.getEffectiveContainerForJSDocTemplateTag(location) || location.parent : + ts.isJSDocParameterTag(location) || ts.isJSDocReturnTag(location) ? ts.getHostSignatureFromJSDoc(location) || location.parent : location.parent; } @@ -2155,8 +2130,8 @@ namespace ts { if (!result) { if (lastLocation) { - Debug.assert(lastLocation.kind === SyntaxKind.SourceFile); - if ((lastLocation as SourceFile).commonJsModuleIndicator && name === "exports" && meaning & lastLocation.symbol.flags) { + ts.Debug.assert(lastLocation.kind === ts.SyntaxKind.SourceFile); + if ((lastLocation as ts.SourceFile).commonJsModuleIndicator && name === "exports" && meaning & lastLocation.symbol.flags) { return lastLocation.symbol; } } @@ -2166,8 +2141,8 @@ namespace ts { } } if (!result) { - if (originalLocation && isInJSFile(originalLocation) && originalLocation.parent) { - if (isRequireCall(originalLocation.parent, /*checkArgumentIsStringLiteralLike*/ false)) { + if (originalLocation && ts.isInJSFile(originalLocation) && originalLocation.parent) { + if (ts.isRequireCall(originalLocation.parent, /*checkArgumentIsStringLiteralLike*/ false)) { return requireSymbol; } } @@ -2183,26 +2158,23 @@ namespace ts { !checkAndReportErrorForUsingTypeAsValue(errorLocation, name, meaning) && !checkAndReportErrorForUsingNamespaceModuleAsValue(errorLocation, name, meaning) && !checkAndReportErrorForUsingValueAsType(errorLocation, name, meaning)) { - let suggestion: Symbol | undefined; + let suggestion: ts.Symbol | undefined; if (getSpellingSuggestions && suggestionCount < maximumSuggestionCount) { suggestion = getSuggestedSymbolForNonexistentSymbol(originalLocation, name, meaning); - const isGlobalScopeAugmentationDeclaration = suggestion?.valueDeclaration && isAmbientModule(suggestion.valueDeclaration) && isGlobalScopeAugmentation(suggestion.valueDeclaration); + const isGlobalScopeAugmentationDeclaration = suggestion?.valueDeclaration && ts.isAmbientModule(suggestion.valueDeclaration) && ts.isGlobalScopeAugmentation(suggestion.valueDeclaration); if (isGlobalScopeAugmentationDeclaration) { suggestion = undefined; } if (suggestion) { const suggestionName = symbolToString(suggestion); const isUncheckedJS = isUncheckedJSSuggestion(originalLocation, suggestion, /*excludeClasses*/ false); - const message = meaning === SymbolFlags.Namespace || nameArg && typeof nameArg !== "string" && nodeIsSynthesized(nameArg) ? Diagnostics.Cannot_find_namespace_0_Did_you_mean_1 - : isUncheckedJS ? Diagnostics.Could_not_find_name_0_Did_you_mean_1 - : Diagnostics.Cannot_find_name_0_Did_you_mean_1; + const message = meaning === ts.SymbolFlags.Namespace || nameArg && typeof nameArg !== "string" && ts.nodeIsSynthesized(nameArg) ? ts.Diagnostics.Cannot_find_namespace_0_Did_you_mean_1 + : isUncheckedJS ? ts.Diagnostics.Could_not_find_name_0_Did_you_mean_1 + : ts.Diagnostics.Cannot_find_name_0_Did_you_mean_1; const diagnostic = createError(errorLocation, message, diagnosticName(nameArg!), suggestionName); addErrorOrSuggestion(!isUncheckedJS, diagnostic); if (suggestion.valueDeclaration) { - addRelatedInfo( - diagnostic, - createDiagnosticForNode(suggestion.valueDeclaration, Diagnostics._0_is_declared_here, suggestionName) - ); + ts.addRelatedInfo(diagnostic, ts.createDiagnosticForNode(suggestion.valueDeclaration, ts.Diagnostics._0_is_declared_here, suggestionName)); } } } @@ -2224,13 +2196,12 @@ namespace ts { return undefined; } - if (propertyWithInvalidInitializer && !(getEmitScriptTarget(compilerOptions) === ScriptTarget.ESNext && useDefineForClassFields)) { + if (propertyWithInvalidInitializer && !(ts.getEmitScriptTarget(compilerOptions) === ts.ScriptTarget.ESNext && useDefineForClassFields)) { // We have a match, but the reference occurred within a property initializer and the identifier also binds // to a local variable in the constructor where the code will be emitted. Note that this is actually allowed // with ESNext+useDefineForClassFields because the scope semantics are different. - const propertyName = (propertyWithInvalidInitializer as PropertyDeclaration).name; - error(errorLocation, Diagnostics.Initializer_of_instance_member_variable_0_cannot_reference_identifier_1_declared_in_the_constructor, - declarationNameToString(propertyName), diagnosticName(nameArg!)); + const propertyName = (propertyWithInvalidInitializer as ts.PropertyDeclaration).name; + error(errorLocation, ts.Diagnostics.Initializer_of_instance_member_variable_0_cannot_reference_identifier_1_declared_in_the_constructor, ts.declarationNameToString(propertyName), diagnosticName(nameArg!)); return undefined; } @@ -2249,46 +2220,43 @@ namespace ts { // try to resolve name in /*1*/ which is used in variable position, // we want to check for block-scoped if (errorLocation && - (meaning & SymbolFlags.BlockScopedVariable || - ((meaning & SymbolFlags.Class || meaning & SymbolFlags.Enum) && (meaning & SymbolFlags.Value) === SymbolFlags.Value))) { + (meaning & ts.SymbolFlags.BlockScopedVariable || + ((meaning & ts.SymbolFlags.Class || meaning & ts.SymbolFlags.Enum) && (meaning & ts.SymbolFlags.Value) === ts.SymbolFlags.Value))) { const exportOrLocalSymbol = getExportSymbolOfValueSymbolIfExported(result!); - if (exportOrLocalSymbol.flags & SymbolFlags.BlockScopedVariable || exportOrLocalSymbol.flags & SymbolFlags.Class || exportOrLocalSymbol.flags & SymbolFlags.Enum) { + if (exportOrLocalSymbol.flags & ts.SymbolFlags.BlockScopedVariable || exportOrLocalSymbol.flags & ts.SymbolFlags.Class || exportOrLocalSymbol.flags & ts.SymbolFlags.Enum) { checkResolvedBlockScopedVariable(exportOrLocalSymbol, errorLocation); } } // If we're in an external module, we can't reference value symbols created from UMD export declarations - if (result && isInExternalModule && (meaning & SymbolFlags.Value) === SymbolFlags.Value && !(originalLocation!.flags & NodeFlags.JSDoc)) { + if (result && isInExternalModule && (meaning & ts.SymbolFlags.Value) === ts.SymbolFlags.Value && !(originalLocation!.flags & ts.NodeFlags.JSDoc)) { const merged = getMergedSymbol(result); - if (length(merged.declarations) && every(merged.declarations, d => isNamespaceExportDeclaration(d) || isSourceFile(d) && !!d.symbol.globalExports)) { - errorOrSuggestion(!compilerOptions.allowUmdGlobalAccess, errorLocation!, Diagnostics._0_refers_to_a_UMD_global_but_the_current_file_is_a_module_Consider_adding_an_import_instead, unescapeLeadingUnderscores(name)); + if (ts.length(merged.declarations) && ts.every(merged.declarations, d => ts.isNamespaceExportDeclaration(d) || ts.isSourceFile(d) && !!d.symbol.globalExports)) { + errorOrSuggestion(!compilerOptions.allowUmdGlobalAccess, errorLocation!, ts.Diagnostics._0_refers_to_a_UMD_global_but_the_current_file_is_a_module_Consider_adding_an_import_instead, ts.unescapeLeadingUnderscores(name)); } } // If we're in a parameter initializer or binding name, we can't reference the values of the parameter whose initializer we're within or parameters to the right - if (result && associatedDeclarationForContainingInitializerOrBindingName && !withinDeferredContext && (meaning & SymbolFlags.Value) === SymbolFlags.Value) { + if (result && associatedDeclarationForContainingInitializerOrBindingName && !withinDeferredContext && (meaning & ts.SymbolFlags.Value) === ts.SymbolFlags.Value) { const candidate = getMergedSymbol(getLateBoundSymbol(result)); - const root = (getRootDeclaration(associatedDeclarationForContainingInitializerOrBindingName) as ParameterDeclaration); + const root = (ts.getRootDeclaration(associatedDeclarationForContainingInitializerOrBindingName) as ts.ParameterDeclaration); // A parameter initializer or binding pattern initializer within a parameter cannot refer to itself if (candidate === getSymbolOfNode(associatedDeclarationForContainingInitializerOrBindingName)) { - error(errorLocation, Diagnostics.Parameter_0_cannot_reference_itself, declarationNameToString(associatedDeclarationForContainingInitializerOrBindingName.name)); + error(errorLocation, ts.Diagnostics.Parameter_0_cannot_reference_itself, ts.declarationNameToString(associatedDeclarationForContainingInitializerOrBindingName.name)); } // And it cannot refer to any declarations which come after it else if (candidate.valueDeclaration && candidate.valueDeclaration.pos > associatedDeclarationForContainingInitializerOrBindingName.pos && root.parent.locals && lookup(root.parent.locals, candidate.escapedName, meaning) === candidate) { - error(errorLocation, Diagnostics.Parameter_0_cannot_reference_identifier_1_declared_after_it, declarationNameToString(associatedDeclarationForContainingInitializerOrBindingName.name), declarationNameToString(errorLocation as Identifier)); + error(errorLocation, ts.Diagnostics.Parameter_0_cannot_reference_identifier_1_declared_after_it, ts.declarationNameToString(associatedDeclarationForContainingInitializerOrBindingName.name), ts.declarationNameToString(errorLocation as ts.Identifier)); } } - if (result && errorLocation && meaning & SymbolFlags.Value && result.flags & SymbolFlags.Alias && !(result.flags & SymbolFlags.Value) && !isValidTypeOnlyAliasUseSite(errorLocation)) { + if (result && errorLocation && meaning & ts.SymbolFlags.Value && result.flags & ts.SymbolFlags.Alias && !(result.flags & ts.SymbolFlags.Value) && !ts.isValidTypeOnlyAliasUseSite(errorLocation)) { const typeOnlyDeclaration = getTypeOnlyAliasDeclaration(result); if (typeOnlyDeclaration) { - const message = typeOnlyDeclaration.kind === SyntaxKind.ExportSpecifier - ? Diagnostics._0_cannot_be_used_as_a_value_because_it_was_exported_using_export_type - : Diagnostics._0_cannot_be_used_as_a_value_because_it_was_imported_using_import_type; - const unescapedName = unescapeLeadingUnderscores(name); - addTypeOnlyDeclarationRelatedInfo( - error(errorLocation, message, unescapedName), - typeOnlyDeclaration, - unescapedName); + const message = typeOnlyDeclaration.kind === ts.SyntaxKind.ExportSpecifier + ? ts.Diagnostics._0_cannot_be_used_as_a_value_because_it_was_exported_using_export_type + : ts.Diagnostics._0_cannot_be_used_as_a_value_because_it_was_imported_using_import_type; + const unescapedName = ts.unescapeLeadingUnderscores(name); + addTypeOnlyDeclarationRelatedInfo(error(errorLocation, message, unescapedName), typeOnlyDeclaration, unescapedName); } } }); @@ -2296,59 +2264,53 @@ namespace ts { return result; } - function addTypeOnlyDeclarationRelatedInfo(diagnostic: Diagnostic, typeOnlyDeclaration: TypeOnlyCompatibleAliasDeclaration | undefined, unescapedName: string) { - if (!typeOnlyDeclaration) return diagnostic; - return addRelatedInfo( - diagnostic, - createDiagnosticForNode( - typeOnlyDeclaration, - typeOnlyDeclaration.kind === SyntaxKind.ExportSpecifier ? Diagnostics._0_was_exported_here : Diagnostics._0_was_imported_here, - unescapedName)); + function addTypeOnlyDeclarationRelatedInfo(diagnostic: ts.Diagnostic, typeOnlyDeclaration: ts.TypeOnlyCompatibleAliasDeclaration | undefined, unescapedName: string) { + if (!typeOnlyDeclaration) + return diagnostic; + return ts.addRelatedInfo(diagnostic, ts.createDiagnosticForNode(typeOnlyDeclaration, typeOnlyDeclaration.kind === ts.SyntaxKind.ExportSpecifier ? ts.Diagnostics._0_was_exported_here : ts.Diagnostics._0_was_imported_here, unescapedName)); } - function getIsDeferredContext(location: Node, lastLocation: Node | undefined): boolean { - if (location.kind !== SyntaxKind.ArrowFunction && location.kind !== SyntaxKind.FunctionExpression) { + function getIsDeferredContext(location: ts.Node, lastLocation: ts.Node | undefined): boolean { + if (location.kind !== ts.SyntaxKind.ArrowFunction && location.kind !== ts.SyntaxKind.FunctionExpression) { // initializers in instance property declaration of class like entities are executed in constructor and thus deferred - return isTypeQueryNode(location) || (( - isFunctionLikeDeclaration(location) || - (location.kind === SyntaxKind.PropertyDeclaration && !isStatic(location)) - ) && (!lastLocation || lastLocation !== (location as SignatureDeclaration | PropertyDeclaration).name)); // A name is evaluated within the enclosing scope - so it shouldn't count as deferred + return ts.isTypeQueryNode(location) || ((ts.isFunctionLikeDeclaration(location) || + (location.kind === ts.SyntaxKind.PropertyDeclaration && !ts.isStatic(location))) && (!lastLocation || lastLocation !== (location as ts.SignatureDeclaration | ts.PropertyDeclaration).name)); // A name is evaluated within the enclosing scope - so it shouldn't count as deferred } - if (lastLocation && lastLocation === (location as FunctionExpression | ArrowFunction).name) { + if (lastLocation && lastLocation === (location as ts.FunctionExpression | ts.ArrowFunction).name) { return false; } // generator functions and async functions are not inlined in control flow when immediately invoked - if ((location as FunctionExpression | ArrowFunction).asteriskToken || hasSyntacticModifier(location, ModifierFlags.Async)) { + if ((location as ts.FunctionExpression | ts.ArrowFunction).asteriskToken || ts.hasSyntacticModifier(location, ts.ModifierFlags.Async)) { return true; } - return !getImmediatelyInvokedFunctionExpression(location); + return !ts.getImmediatelyInvokedFunctionExpression(location); } - function isSelfReferenceLocation(node: Node): boolean { + function isSelfReferenceLocation(node: ts.Node): boolean { switch (node.kind) { - case SyntaxKind.FunctionDeclaration: - case SyntaxKind.ClassDeclaration: - case SyntaxKind.InterfaceDeclaration: - case SyntaxKind.EnumDeclaration: - case SyntaxKind.TypeAliasDeclaration: - case SyntaxKind.ModuleDeclaration: // For `namespace N { N; }` + case ts.SyntaxKind.FunctionDeclaration: + case ts.SyntaxKind.ClassDeclaration: + case ts.SyntaxKind.InterfaceDeclaration: + case ts.SyntaxKind.EnumDeclaration: + case ts.SyntaxKind.TypeAliasDeclaration: + case ts.SyntaxKind.ModuleDeclaration: // For `namespace N { N; }` return true; default: return false; } } - function diagnosticName(nameArg: __String | Identifier | PrivateIdentifier) { - return isString(nameArg) ? unescapeLeadingUnderscores(nameArg as __String) : declarationNameToString(nameArg as Identifier); + function diagnosticName(nameArg: ts.__String | ts.Identifier | ts.PrivateIdentifier) { + return ts.isString(nameArg) ? ts.unescapeLeadingUnderscores(nameArg as ts.__String) : ts.declarationNameToString(nameArg as ts.Identifier); } - function isTypeParameterSymbolDeclaredInContainer(symbol: Symbol, container: Node) { + function isTypeParameterSymbolDeclaredInContainer(symbol: ts.Symbol, container: ts.Node) { if (symbol.declarations) { for (const decl of symbol.declarations) { - if (decl.kind === SyntaxKind.TypeParameter) { - const parent = isJSDocTemplateTag(decl.parent) ? getJSDocHost(decl.parent) : decl.parent; + if (decl.kind === ts.SyntaxKind.TypeParameter) { + const parent = ts.isJSDocTemplateTag(decl.parent) ? ts.getJSDocHost(decl.parent) : decl.parent; if (parent === container) { - return !(isJSDocTemplateTag(decl.parent) && find((decl.parent.parent as JSDoc).tags!, isJSDocTypeAlias)); // TODO: GH#18217 + return !(ts.isJSDocTemplateTag(decl.parent) && ts.find((decl.parent.parent as ts.JSDoc).tags!, ts.isJSDocTypeAlias)); // TODO: GH#18217 } } } @@ -2357,15 +2319,15 @@ namespace ts { return false; } - function checkAndReportErrorForMissingPrefix(errorLocation: Node, name: __String, nameArg: __String | Identifier): boolean { - if (!isIdentifier(errorLocation) || errorLocation.escapedText !== name || isTypeReferenceIdentifier(errorLocation) || isInTypeQuery(errorLocation)) { + function checkAndReportErrorForMissingPrefix(errorLocation: ts.Node, name: ts.__String, nameArg: ts.__String | ts.Identifier): boolean { + if (!ts.isIdentifier(errorLocation) || errorLocation.escapedText !== name || isTypeReferenceIdentifier(errorLocation) || isInTypeQuery(errorLocation)) { return false; } - const container = getThisContainer(errorLocation, /*includeArrowFunctions*/ false); + const container = ts.getThisContainer(errorLocation, /*includeArrowFunctions*/ false); let location = container; while (location) { - if (isClassLike(location.parent)) { + if (ts.isClassLike(location.parent)) { const classSymbol = getSymbolOfNode(location.parent); if (!classSymbol) { break; @@ -2374,16 +2336,16 @@ namespace ts { // Check to see if a static member exists. const constructorType = getTypeOfSymbol(classSymbol); if (getPropertyOfType(constructorType, name)) { - error(errorLocation, Diagnostics.Cannot_find_name_0_Did_you_mean_the_static_member_1_0, diagnosticName(nameArg), symbolToString(classSymbol)); + error(errorLocation, ts.Diagnostics.Cannot_find_name_0_Did_you_mean_the_static_member_1_0, diagnosticName(nameArg), symbolToString(classSymbol)); return true; } // No static member is present. // Check if we're in an instance method and look for a relevant instance member. - if (location === container && !isStatic(location)) { - const instanceType = (getDeclaredTypeOfSymbol(classSymbol) as InterfaceType).thisType!; // TODO: GH#18217 + if (location === container && !ts.isStatic(location)) { + const instanceType = (getDeclaredTypeOfSymbol(classSymbol) as ts.InterfaceType).thisType!; // TODO: GH#18217 if (getPropertyOfType(instanceType, name)) { - error(errorLocation, Diagnostics.Cannot_find_name_0_Did_you_mean_the_instance_member_this_0, diagnosticName(nameArg)); + error(errorLocation, ts.Diagnostics.Cannot_find_name_0_Did_you_mean_the_instance_member_this_0, diagnosticName(nameArg)); return true; } } @@ -2395,10 +2357,10 @@ namespace ts { } - function checkAndReportErrorForExtendingInterface(errorLocation: Node): boolean { + function checkAndReportErrorForExtendingInterface(errorLocation: ts.Node): boolean { const expression = getEntityNameForExtendingInterface(errorLocation); - if (expression && resolveEntityName(expression, SymbolFlags.Interface, /*ignoreErrors*/ true)) { - error(errorLocation, Diagnostics.Cannot_extend_an_interface_0_Did_you_mean_implements, getTextOfNode(expression)); + if (expression && resolveEntityName(expression, ts.SymbolFlags.Interface, /*ignoreErrors*/ true)) { + error(errorLocation, ts.Diagnostics.Cannot_extend_an_interface_0_Did_you_mean_implements, ts.getTextOfNode(expression)); return true; } return false; @@ -2407,14 +2369,14 @@ namespace ts { * Climbs up parents to an ExpressionWithTypeArguments, and returns its expression, * but returns undefined if that expression is not an EntityNameExpression. */ - function getEntityNameForExtendingInterface(node: Node): EntityNameExpression | undefined { + function getEntityNameForExtendingInterface(node: ts.Node): ts.EntityNameExpression | undefined { switch (node.kind) { - case SyntaxKind.Identifier: - case SyntaxKind.PropertyAccessExpression: + case ts.SyntaxKind.Identifier: + case ts.SyntaxKind.PropertyAccessExpression: return node.parent ? getEntityNameForExtendingInterface(node.parent) : undefined; - case SyntaxKind.ExpressionWithTypeArguments: - if (isEntityNameExpression((node as ExpressionWithTypeArguments).expression)) { - return (node as ExpressionWithTypeArguments).expression as EntityNameExpression; + case ts.SyntaxKind.ExpressionWithTypeArguments: + if (ts.isEntityNameExpression((node as ts.ExpressionWithTypeArguments).expression)) { + return (node as ts.ExpressionWithTypeArguments).expression as ts.EntityNameExpression; } // falls through default: @@ -2422,27 +2384,22 @@ namespace ts { } } - function checkAndReportErrorForUsingTypeAsNamespace(errorLocation: Node, name: __String, meaning: SymbolFlags): boolean { - const namespaceMeaning = SymbolFlags.Namespace | (isInJSFile(errorLocation) ? SymbolFlags.Value : 0); + function checkAndReportErrorForUsingTypeAsNamespace(errorLocation: ts.Node, name: ts.__String, meaning: ts.SymbolFlags): boolean { + const namespaceMeaning = ts.SymbolFlags.Namespace | (ts.isInJSFile(errorLocation) ? ts.SymbolFlags.Value : 0); if (meaning === namespaceMeaning) { - const symbol = resolveSymbol(resolveName(errorLocation, name, SymbolFlags.Type & ~namespaceMeaning, /*nameNotFoundMessage*/undefined, /*nameArg*/ undefined, /*isUse*/ false)); + const symbol = resolveSymbol(resolveName(errorLocation, name, ts.SymbolFlags.Type & ~namespaceMeaning, /*nameNotFoundMessage*/ undefined, /*nameArg*/ undefined, /*isUse*/ false)); const parent = errorLocation.parent; if (symbol) { - if (isQualifiedName(parent)) { - Debug.assert(parent.left === errorLocation, "Should only be resolving left side of qualified name as a namespace"); + if (ts.isQualifiedName(parent)) { + ts.Debug.assert(parent.left === errorLocation, "Should only be resolving left side of qualified name as a namespace"); const propName = parent.right.escapedText; const propType = getPropertyOfType(getDeclaredTypeOfSymbol(symbol), propName); if (propType) { - error( - parent, - Diagnostics.Cannot_access_0_1_because_0_is_a_type_but_not_a_namespace_Did_you_mean_to_retrieve_the_type_of_the_property_1_in_0_with_0_1, - unescapeLeadingUnderscores(name), - unescapeLeadingUnderscores(propName), - ); + error(parent, ts.Diagnostics.Cannot_access_0_1_because_0_is_a_type_but_not_a_namespace_Did_you_mean_to_retrieve_the_type_of_the_property_1_in_0_with_0_1, ts.unescapeLeadingUnderscores(name), ts.unescapeLeadingUnderscores(propName)); return true; } } - error(errorLocation, Diagnostics._0_only_refers_to_a_type_but_is_being_used_as_a_namespace_here, unescapeLeadingUnderscores(name)); + error(errorLocation, ts.Diagnostics._0_only_refers_to_a_type_but_is_being_used_as_a_namespace_here, ts.unescapeLeadingUnderscores(name)); return true; } } @@ -2450,46 +2407,46 @@ namespace ts { return false; } - function checkAndReportErrorForUsingValueAsType(errorLocation: Node, name: __String, meaning: SymbolFlags): boolean { - if (meaning & (SymbolFlags.Type & ~SymbolFlags.Namespace)) { - const symbol = resolveSymbol(resolveName(errorLocation, name, ~SymbolFlags.Type & SymbolFlags.Value, /*nameNotFoundMessage*/undefined, /*nameArg*/ undefined, /*isUse*/ false)); - if (symbol && !(symbol.flags & SymbolFlags.Namespace)) { - error(errorLocation, Diagnostics._0_refers_to_a_value_but_is_being_used_as_a_type_here_Did_you_mean_typeof_0, unescapeLeadingUnderscores(name)); + function checkAndReportErrorForUsingValueAsType(errorLocation: ts.Node, name: ts.__String, meaning: ts.SymbolFlags): boolean { + if (meaning & (ts.SymbolFlags.Type & ~ts.SymbolFlags.Namespace)) { + const symbol = resolveSymbol(resolveName(errorLocation, name, ~ts.SymbolFlags.Type & ts.SymbolFlags.Value, /*nameNotFoundMessage*/ undefined, /*nameArg*/ undefined, /*isUse*/ false)); + if (symbol && !(symbol.flags & ts.SymbolFlags.Namespace)) { + error(errorLocation, ts.Diagnostics._0_refers_to_a_value_but_is_being_used_as_a_type_here_Did_you_mean_typeof_0, ts.unescapeLeadingUnderscores(name)); return true; } } return false; } - function isPrimitiveTypeName(name: __String) { + function isPrimitiveTypeName(name: ts.__String) { return name === "any" || name === "string" || name === "number" || name === "boolean" || name === "never" || name === "unknown"; } - function checkAndReportErrorForExportingPrimitiveType(errorLocation: Node, name: __String): boolean { - if (isPrimitiveTypeName(name) && errorLocation.parent.kind === SyntaxKind.ExportSpecifier) { - error(errorLocation, Diagnostics.Cannot_export_0_Only_local_declarations_can_be_exported_from_a_module, name as string); + function checkAndReportErrorForExportingPrimitiveType(errorLocation: ts.Node, name: ts.__String): boolean { + if (isPrimitiveTypeName(name) && errorLocation.parent.kind === ts.SyntaxKind.ExportSpecifier) { + error(errorLocation, ts.Diagnostics.Cannot_export_0_Only_local_declarations_can_be_exported_from_a_module, name as string); return true; } return false; } - function checkAndReportErrorForUsingTypeAsValue(errorLocation: Node, name: __String, meaning: SymbolFlags): boolean { - if (meaning & (SymbolFlags.Value & ~SymbolFlags.NamespaceModule)) { + function checkAndReportErrorForUsingTypeAsValue(errorLocation: ts.Node, name: ts.__String, meaning: ts.SymbolFlags): boolean { + if (meaning & (ts.SymbolFlags.Value & ~ts.SymbolFlags.NamespaceModule)) { if (isPrimitiveTypeName(name)) { - error(errorLocation, Diagnostics._0_only_refers_to_a_type_but_is_being_used_as_a_value_here, unescapeLeadingUnderscores(name)); + error(errorLocation, ts.Diagnostics._0_only_refers_to_a_type_but_is_being_used_as_a_value_here, ts.unescapeLeadingUnderscores(name)); return true; } - const symbol = resolveSymbol(resolveName(errorLocation, name, SymbolFlags.Type & ~SymbolFlags.Value, /*nameNotFoundMessage*/undefined, /*nameArg*/ undefined, /*isUse*/ false)); - if (symbol && !(symbol.flags & SymbolFlags.NamespaceModule)) { - const rawName = unescapeLeadingUnderscores(name); + const symbol = resolveSymbol(resolveName(errorLocation, name, ts.SymbolFlags.Type & ~ts.SymbolFlags.Value, /*nameNotFoundMessage*/ undefined, /*nameArg*/ undefined, /*isUse*/ false)); + if (symbol && !(symbol.flags & ts.SymbolFlags.NamespaceModule)) { + const rawName = ts.unescapeLeadingUnderscores(name); if (isES2015OrLaterConstructorName(name)) { - error(errorLocation, Diagnostics._0_only_refers_to_a_type_but_is_being_used_as_a_value_here_Do_you_need_to_change_your_target_library_Try_changing_the_lib_compiler_option_to_es2015_or_later, rawName); + error(errorLocation, ts.Diagnostics._0_only_refers_to_a_type_but_is_being_used_as_a_value_here_Do_you_need_to_change_your_target_library_Try_changing_the_lib_compiler_option_to_es2015_or_later, rawName); } else if (maybeMappedType(errorLocation, symbol)) { - error(errorLocation, Diagnostics._0_only_refers_to_a_type_but_is_being_used_as_a_value_here_Did_you_mean_to_use_1_in_0, rawName, rawName === "K" ? "P" : "K"); + error(errorLocation, ts.Diagnostics._0_only_refers_to_a_type_but_is_being_used_as_a_value_here_Did_you_mean_to_use_1_in_0, rawName, rawName === "K" ? "P" : "K"); } else { - error(errorLocation, Diagnostics._0_only_refers_to_a_type_but_is_being_used_as_a_value_here, rawName); + error(errorLocation, ts.Diagnostics._0_only_refers_to_a_type_but_is_being_used_as_a_value_here, rawName); } return true; } @@ -2497,17 +2454,16 @@ namespace ts { return false; } - function maybeMappedType(node: Node, symbol: Symbol) { - const container = findAncestor(node.parent, n => - isComputedPropertyName(n) || isPropertySignature(n) ? false : isTypeLiteralNode(n) || "quit") as TypeLiteralNode | undefined; + function maybeMappedType(node: ts.Node, symbol: ts.Symbol) { + const container = ts.findAncestor(node.parent, n => ts.isComputedPropertyName(n) || ts.isPropertySignature(n) ? false : ts.isTypeLiteralNode(n) || "quit") as ts.TypeLiteralNode | undefined; if (container && container.members.length === 1) { const type = getDeclaredTypeOfSymbol(symbol); - return !!(type.flags & TypeFlags.Union) && allTypesAssignableToKind(type, TypeFlags.StringOrNumberLiteral, /*strict*/ true); + return !!(type.flags & ts.TypeFlags.Union) && allTypesAssignableToKind(type, ts.TypeFlags.StringOrNumberLiteral, /*strict*/ true); } return false; } - function isES2015OrLaterConstructorName(n: __String) { + function isES2015OrLaterConstructorName(n: ts.__String) { switch (n) { case "Promise": case "Symbol": @@ -2520,62 +2476,55 @@ namespace ts { return false; } - function checkAndReportErrorForUsingNamespaceModuleAsValue(errorLocation: Node, name: __String, meaning: SymbolFlags): boolean { - if (meaning & (SymbolFlags.Value & ~SymbolFlags.NamespaceModule & ~SymbolFlags.Type)) { - const symbol = resolveSymbol(resolveName(errorLocation, name, SymbolFlags.NamespaceModule & ~SymbolFlags.Value, /*nameNotFoundMessage*/undefined, /*nameArg*/ undefined, /*isUse*/ false)); + function checkAndReportErrorForUsingNamespaceModuleAsValue(errorLocation: ts.Node, name: ts.__String, meaning: ts.SymbolFlags): boolean { + if (meaning & (ts.SymbolFlags.Value & ~ts.SymbolFlags.NamespaceModule & ~ts.SymbolFlags.Type)) { + const symbol = resolveSymbol(resolveName(errorLocation, name, ts.SymbolFlags.NamespaceModule & ~ts.SymbolFlags.Value, /*nameNotFoundMessage*/ undefined, /*nameArg*/ undefined, /*isUse*/ false)); if (symbol) { - error( - errorLocation, - Diagnostics.Cannot_use_namespace_0_as_a_value, - unescapeLeadingUnderscores(name)); + error(errorLocation, ts.Diagnostics.Cannot_use_namespace_0_as_a_value, ts.unescapeLeadingUnderscores(name)); return true; } } - else if (meaning & (SymbolFlags.Type & ~SymbolFlags.NamespaceModule & ~SymbolFlags.Value)) { - const symbol = resolveSymbol(resolveName(errorLocation, name, (SymbolFlags.ValueModule | SymbolFlags.NamespaceModule) & ~SymbolFlags.Type, /*nameNotFoundMessage*/undefined, /*nameArg*/ undefined, /*isUse*/ false)); + else if (meaning & (ts.SymbolFlags.Type & ~ts.SymbolFlags.NamespaceModule & ~ts.SymbolFlags.Value)) { + const symbol = resolveSymbol(resolveName(errorLocation, name, (ts.SymbolFlags.ValueModule | ts.SymbolFlags.NamespaceModule) & ~ts.SymbolFlags.Type, /*nameNotFoundMessage*/ undefined, /*nameArg*/ undefined, /*isUse*/ false)); if (symbol) { - error(errorLocation, Diagnostics.Cannot_use_namespace_0_as_a_type, unescapeLeadingUnderscores(name)); + error(errorLocation, ts.Diagnostics.Cannot_use_namespace_0_as_a_type, ts.unescapeLeadingUnderscores(name)); return true; } } return false; } - function checkResolvedBlockScopedVariable(result: Symbol, errorLocation: Node): void { - Debug.assert(!!(result.flags & SymbolFlags.BlockScopedVariable || result.flags & SymbolFlags.Class || result.flags & SymbolFlags.Enum)); - if (result.flags & (SymbolFlags.Function | SymbolFlags.FunctionScopedVariable | SymbolFlags.Assignment) && result.flags & SymbolFlags.Class) { + function checkResolvedBlockScopedVariable(result: ts.Symbol, errorLocation: ts.Node): void { + ts.Debug.assert(!!(result.flags & ts.SymbolFlags.BlockScopedVariable || result.flags & ts.SymbolFlags.Class || result.flags & ts.SymbolFlags.Enum)); + if (result.flags & (ts.SymbolFlags.Function | ts.SymbolFlags.FunctionScopedVariable | ts.SymbolFlags.Assignment) && result.flags & ts.SymbolFlags.Class) { // constructor functions aren't block scoped return; } // Block-scoped variables cannot be used before their definition - const declaration = result.declarations?.find( - d => isBlockOrCatchScoped(d) || isClassLike(d) || (d.kind === SyntaxKind.EnumDeclaration)); - - if (declaration === undefined) return Debug.fail("checkResolvedBlockScopedVariable could not find block-scoped declaration"); - - if (!(declaration.flags & NodeFlags.Ambient) && !isBlockScopedNameDeclaredBeforeUse(declaration, errorLocation)) { + const declaration = result.declarations?.find(d => ts.isBlockOrCatchScoped(d) || ts.isClassLike(d) || (d.kind === ts.SyntaxKind.EnumDeclaration)); + if (declaration === undefined) + return ts.Debug.fail("checkResolvedBlockScopedVariable could not find block-scoped declaration"); + if (!(declaration.flags & ts.NodeFlags.Ambient) && !isBlockScopedNameDeclaredBeforeUse(declaration, errorLocation)) { let diagnosticMessage; - const declarationName = declarationNameToString(getNameOfDeclaration(declaration)); - if (result.flags & SymbolFlags.BlockScopedVariable) { - diagnosticMessage = error(errorLocation, Diagnostics.Block_scoped_variable_0_used_before_its_declaration, declarationName); + const declarationName = ts.declarationNameToString(ts.getNameOfDeclaration(declaration)); + if (result.flags & ts.SymbolFlags.BlockScopedVariable) { + diagnosticMessage = error(errorLocation, ts.Diagnostics.Block_scoped_variable_0_used_before_its_declaration, declarationName); } - else if (result.flags & SymbolFlags.Class) { - diagnosticMessage = error(errorLocation, Diagnostics.Class_0_used_before_its_declaration, declarationName); + else if (result.flags & ts.SymbolFlags.Class) { + diagnosticMessage = error(errorLocation, ts.Diagnostics.Class_0_used_before_its_declaration, declarationName); } - else if (result.flags & SymbolFlags.RegularEnum) { - diagnosticMessage = error(errorLocation, Diagnostics.Enum_0_used_before_its_declaration, declarationName); + else if (result.flags & ts.SymbolFlags.RegularEnum) { + diagnosticMessage = error(errorLocation, ts.Diagnostics.Enum_0_used_before_its_declaration, declarationName); } else { - Debug.assert(!!(result.flags & SymbolFlags.ConstEnum)); - if (shouldPreserveConstEnums(compilerOptions)) { - diagnosticMessage = error(errorLocation, Diagnostics.Enum_0_used_before_its_declaration, declarationName); + ts.Debug.assert(!!(result.flags & ts.SymbolFlags.ConstEnum)); + if (ts.shouldPreserveConstEnums(compilerOptions)) { + diagnosticMessage = error(errorLocation, ts.Diagnostics.Enum_0_used_before_its_declaration, declarationName); } } if (diagnosticMessage) { - addRelatedInfo(diagnosticMessage, - createDiagnosticForNode(declaration, Diagnostics._0_is_declared_here, declarationName) - ); + ts.addRelatedInfo(diagnosticMessage, ts.createDiagnosticForNode(declaration, ts.Diagnostics._0_is_declared_here, declarationName)); } } } @@ -2585,28 +2534,28 @@ namespace ts { * If current node is an IIFE, continue walking up. * Return false if 'stopAt' node is reached or isFunctionLike(current) === true. */ - function isSameScopeDescendentOf(initial: Node, parent: Node | undefined, stopAt: Node): boolean { - return !!parent && !!findAncestor(initial, n => n === parent - || (n === stopAt || isFunctionLike(n) && !getImmediatelyInvokedFunctionExpression(n) ? "quit" : false)); + function isSameScopeDescendentOf(initial: ts.Node, parent: ts.Node | undefined, stopAt: ts.Node): boolean { + return !!parent && !!ts.findAncestor(initial, n => n === parent + || (n === stopAt || ts.isFunctionLike(n) && !ts.getImmediatelyInvokedFunctionExpression(n) ? "quit" : false)); } - function getAnyImportSyntax(node: Node): AnyImportSyntax | undefined { + function getAnyImportSyntax(node: ts.Node): ts.AnyImportSyntax | undefined { switch (node.kind) { - case SyntaxKind.ImportEqualsDeclaration: - return node as ImportEqualsDeclaration; - case SyntaxKind.ImportClause: - return (node as ImportClause).parent; - case SyntaxKind.NamespaceImport: - return (node as NamespaceImport).parent.parent; - case SyntaxKind.ImportSpecifier: - return (node as ImportSpecifier).parent.parent.parent; + case ts.SyntaxKind.ImportEqualsDeclaration: + return node as ts.ImportEqualsDeclaration; + case ts.SyntaxKind.ImportClause: + return (node as ts.ImportClause).parent; + case ts.SyntaxKind.NamespaceImport: + return (node as ts.NamespaceImport).parent.parent; + case ts.SyntaxKind.ImportSpecifier: + return (node as ts.ImportSpecifier).parent.parent.parent; default: return undefined; } } - function getDeclarationOfAliasSymbol(symbol: Symbol): Declaration | undefined { - return symbol.declarations && findLast(symbol.declarations, isAliasSymbolDeclaration); + function getDeclarationOfAliasSymbol(symbol: ts.Symbol): ts.Declaration | undefined { + return symbol.declarations && ts.findLast(symbol.declarations, isAliasSymbolDeclaration); } /** @@ -2624,42 +2573,40 @@ namespace ts { * {name: } * const { x } = require ... */ - function isAliasSymbolDeclaration(node: Node): boolean { - return node.kind === SyntaxKind.ImportEqualsDeclaration - || node.kind === SyntaxKind.NamespaceExportDeclaration - || node.kind === SyntaxKind.ImportClause && !!(node as ImportClause).name - || node.kind === SyntaxKind.NamespaceImport - || node.kind === SyntaxKind.NamespaceExport - || node.kind === SyntaxKind.ImportSpecifier - || node.kind === SyntaxKind.ExportSpecifier - || node.kind === SyntaxKind.ExportAssignment && exportAssignmentIsAlias(node as ExportAssignment) - || isBinaryExpression(node) && getAssignmentDeclarationKind(node) === AssignmentDeclarationKind.ModuleExports && exportAssignmentIsAlias(node) - || isAccessExpression(node) - && isBinaryExpression(node.parent) + function isAliasSymbolDeclaration(node: ts.Node): boolean { + return node.kind === ts.SyntaxKind.ImportEqualsDeclaration + || node.kind === ts.SyntaxKind.NamespaceExportDeclaration + || node.kind === ts.SyntaxKind.ImportClause && !!(node as ts.ImportClause).name + || node.kind === ts.SyntaxKind.NamespaceImport + || node.kind === ts.SyntaxKind.NamespaceExport + || node.kind === ts.SyntaxKind.ImportSpecifier + || node.kind === ts.SyntaxKind.ExportSpecifier + || node.kind === ts.SyntaxKind.ExportAssignment && ts.exportAssignmentIsAlias(node as ts.ExportAssignment) + || ts.isBinaryExpression(node) && ts.getAssignmentDeclarationKind(node) === ts.AssignmentDeclarationKind.ModuleExports && ts.exportAssignmentIsAlias(node) + || ts.isAccessExpression(node) + && ts.isBinaryExpression(node.parent) && node.parent.left === node - && node.parent.operatorToken.kind === SyntaxKind.EqualsToken + && node.parent.operatorToken.kind === ts.SyntaxKind.EqualsToken && isAliasableOrJsExpression(node.parent.right) - || node.kind === SyntaxKind.ShorthandPropertyAssignment - || node.kind === SyntaxKind.PropertyAssignment && isAliasableOrJsExpression((node as PropertyAssignment).initializer) - || isVariableDeclarationInitializedToBareOrAccessedRequire(node); + || node.kind === ts.SyntaxKind.ShorthandPropertyAssignment + || node.kind === ts.SyntaxKind.PropertyAssignment && isAliasableOrJsExpression((node as ts.PropertyAssignment).initializer) + || ts.isVariableDeclarationInitializedToBareOrAccessedRequire(node); } - function isAliasableOrJsExpression(e: Expression) { - return isAliasableExpression(e) || isFunctionExpression(e) && isJSConstructor(e); + function isAliasableOrJsExpression(e: ts.Expression) { + return ts.isAliasableExpression(e) || ts.isFunctionExpression(e) && isJSConstructor(e); } - function getTargetOfImportEqualsDeclaration(node: ImportEqualsDeclaration | VariableDeclaration, dontResolveAlias: boolean): Symbol | undefined { + function getTargetOfImportEqualsDeclaration(node: ts.ImportEqualsDeclaration | ts.VariableDeclaration, dontResolveAlias: boolean): ts.Symbol | undefined { const commonJSPropertyAccess = getCommonJSPropertyAccess(node); if (commonJSPropertyAccess) { - const name = (getLeftmostAccessExpression(commonJSPropertyAccess.expression) as CallExpression).arguments[0] as StringLiteral; - return isIdentifier(commonJSPropertyAccess.name) + const name = (ts.getLeftmostAccessExpression(commonJSPropertyAccess.expression) as ts.CallExpression).arguments[0] as ts.StringLiteral; + return ts.isIdentifier(commonJSPropertyAccess.name) ? resolveSymbol(getPropertyOfType(resolveExternalModuleTypeByLiteral(name), commonJSPropertyAccess.name.escapedText)) : undefined; } - if (isVariableDeclaration(node) || node.moduleReference.kind === SyntaxKind.ExternalModuleReference) { - const immediate = resolveExternalModuleName( - node, - getExternalModuleRequireArgument(node) || getExternalModuleImportEqualsDeclarationExpression(node)); + if (ts.isVariableDeclaration(node) || node.moduleReference.kind === ts.SyntaxKind.ExternalModuleReference) { + const immediate = resolveExternalModuleName(node, ts.getExternalModuleRequireArgument(node) || ts.getExternalModuleImportEqualsDeclarationExpression(node)); const resolved = resolveExternalModuleSymbol(immediate); markSymbolOfAliasDeclarationIfTypeOnly(node, immediate, resolved, /*overwriteEmpty*/ false); return resolved; @@ -2669,52 +2616,51 @@ namespace ts { return resolved; } - function checkAndReportErrorForResolvingImportAliasToTypeOnlySymbol(node: ImportEqualsDeclaration, resolved: Symbol | undefined) { + function checkAndReportErrorForResolvingImportAliasToTypeOnlySymbol(node: ts.ImportEqualsDeclaration, resolved: ts.Symbol | undefined) { if (markSymbolOfAliasDeclarationIfTypeOnly(node, /*immediateTarget*/ undefined, resolved, /*overwriteEmpty*/ false) && !node.isTypeOnly) { const typeOnlyDeclaration = getTypeOnlyAliasDeclaration(getSymbolOfNode(node))!; - const isExport = typeOnlyDeclaration.kind === SyntaxKind.ExportSpecifier; + const isExport = typeOnlyDeclaration.kind === ts.SyntaxKind.ExportSpecifier; const message = isExport - ? Diagnostics.An_import_alias_cannot_reference_a_declaration_that_was_exported_using_export_type - : Diagnostics.An_import_alias_cannot_reference_a_declaration_that_was_imported_using_import_type; + ? ts.Diagnostics.An_import_alias_cannot_reference_a_declaration_that_was_exported_using_export_type + : ts.Diagnostics.An_import_alias_cannot_reference_a_declaration_that_was_imported_using_import_type; const relatedMessage = isExport - ? Diagnostics._0_was_exported_here - : Diagnostics._0_was_imported_here; - - const name = unescapeLeadingUnderscores(typeOnlyDeclaration.name.escapedText); - addRelatedInfo(error(node.moduleReference, message), createDiagnosticForNode(typeOnlyDeclaration, relatedMessage, name)); + ? ts.Diagnostics._0_was_exported_here + : ts.Diagnostics._0_was_imported_here; + const name = ts.unescapeLeadingUnderscores(typeOnlyDeclaration.name.escapedText); + ts.addRelatedInfo(error(node.moduleReference, message), ts.createDiagnosticForNode(typeOnlyDeclaration, relatedMessage, name)); } } - function resolveExportByName(moduleSymbol: Symbol, name: __String, sourceNode: TypeOnlyCompatibleAliasDeclaration | undefined, dontResolveAlias: boolean) { - const exportValue = moduleSymbol.exports!.get(InternalSymbolName.ExportEquals); + function resolveExportByName(moduleSymbol: ts.Symbol, name: ts.__String, sourceNode: ts.TypeOnlyCompatibleAliasDeclaration | undefined, dontResolveAlias: boolean) { + const exportValue = moduleSymbol.exports!.get(ts.InternalSymbolName.ExportEquals); const exportSymbol = exportValue ? getPropertyOfType(getTypeOfSymbol(exportValue), name) : moduleSymbol.exports!.get(name); const resolved = resolveSymbol(exportSymbol, dontResolveAlias); markSymbolOfAliasDeclarationIfTypeOnly(sourceNode, exportSymbol, resolved, /*overwriteEmpty*/ false); return resolved; } - function isSyntacticDefault(node: Node) { - return ((isExportAssignment(node) && !node.isExportEquals) || hasSyntacticModifier(node, ModifierFlags.Default) || isExportSpecifier(node)); + function isSyntacticDefault(node: ts.Node) { + return ((ts.isExportAssignment(node) && !node.isExportEquals) || ts.hasSyntacticModifier(node, ts.ModifierFlags.Default) || ts.isExportSpecifier(node)); } - function getUsageModeForExpression(usage: Expression) { - return isStringLiteralLike(usage) ? getModeForUsageLocation(getSourceFileOfNode(usage), usage) : undefined; + function getUsageModeForExpression(usage: ts.Expression) { + return ts.isStringLiteralLike(usage) ? ts.getModeForUsageLocation(ts.getSourceFileOfNode(usage), usage) : undefined; } - function isESMFormatImportImportingCommonjsFormatFile(usageMode: SourceFile["impliedNodeFormat"], targetMode: SourceFile["impliedNodeFormat"]) { - return usageMode === ModuleKind.ESNext && targetMode === ModuleKind.CommonJS; + function isESMFormatImportImportingCommonjsFormatFile(usageMode: ts.SourceFile["impliedNodeFormat"], targetMode: ts.SourceFile["impliedNodeFormat"]) { + return usageMode === ts.ModuleKind.ESNext && targetMode === ts.ModuleKind.CommonJS; } - function isOnlyImportedAsDefault(usage: Expression) { + function isOnlyImportedAsDefault(usage: ts.Expression) { const usageMode = getUsageModeForExpression(usage); - return usageMode === ModuleKind.ESNext && endsWith((usage as StringLiteralLike).text, Extension.Json); + return usageMode === ts.ModuleKind.ESNext && ts.endsWith((usage as ts.StringLiteralLike).text, ts.Extension.Json); } - function canHaveSyntheticDefault(file: SourceFile | undefined, moduleSymbol: Symbol, dontResolveAlias: boolean, usage: Expression) { + function canHaveSyntheticDefault(file: ts.SourceFile | undefined, moduleSymbol: ts.Symbol, dontResolveAlias: boolean, usage: ts.Expression) { const usageMode = file && getUsageModeForExpression(usage); if (file && usageMode !== undefined) { const result = isESMFormatImportImportingCommonjsFormatFile(usageMode, file.impliedNodeFormat); - if (usageMode === ModuleKind.ESNext || result) { + if (usageMode === ts.ModuleKind.ESNext || result) { return result; } // fallthrough on cjs usages so we imply defaults for interop'd imports, too @@ -2725,13 +2671,13 @@ namespace ts { // Declaration files (and ambient modules) if (!file || file.isDeclarationFile) { // Definitely cannot have a synthetic default if they have a syntactic default member specified - const defaultExportSymbol = resolveExportByName(moduleSymbol, InternalSymbolName.Default, /*sourceNode*/ undefined, /*dontResolveAlias*/ true); // Dont resolve alias because we want the immediately exported symbol's declaration - if (defaultExportSymbol && some(defaultExportSymbol.declarations, isSyntacticDefault)) { + const defaultExportSymbol = resolveExportByName(moduleSymbol, ts.InternalSymbolName.Default, /*sourceNode*/ undefined, /*dontResolveAlias*/ true); // Dont resolve alias because we want the immediately exported symbol's declaration + if (defaultExportSymbol && ts.some(defaultExportSymbol.declarations, isSyntacticDefault)) { return false; } // It _might_ still be incorrect to assume there is no __esModule marker on the import at runtime, even if there is no `default` member // So we check a bit more, - if (resolveExportByName(moduleSymbol, escapeLeadingUnderscores("__esModule"), /*sourceNode*/ undefined, dontResolveAlias)) { + if (resolveExportByName(moduleSymbol, ts.escapeLeadingUnderscores("__esModule"), /*sourceNode*/ undefined, dontResolveAlias)) { // If there is an `__esModule` specified in the declaration (meaning someone explicitly added it or wrote it in their code), // it definitely is a module and does not have a synthetic default return false; @@ -2742,40 +2688,36 @@ namespace ts { return true; } // TypeScript files never have a synthetic default (as they are always emitted with an __esModule marker) _unless_ they contain an export= statement - if (!isSourceFileJS(file)) { + if (!ts.isSourceFileJS(file)) { return hasExportAssignmentSymbol(moduleSymbol); } // JS files have a synthetic default if they do not contain ES2015+ module syntax (export = is not valid in js) _and_ do not have an __esModule marker - return !file.externalModuleIndicator && !resolveExportByName(moduleSymbol, escapeLeadingUnderscores("__esModule"), /*sourceNode*/ undefined, dontResolveAlias); + return !file.externalModuleIndicator && !resolveExportByName(moduleSymbol, ts.escapeLeadingUnderscores("__esModule"), /*sourceNode*/ undefined, dontResolveAlias); } - function getTargetOfImportClause(node: ImportClause, dontResolveAlias: boolean): Symbol | undefined { + function getTargetOfImportClause(node: ts.ImportClause, dontResolveAlias: boolean): ts.Symbol | undefined { const moduleSymbol = resolveExternalModuleName(node, node.parent.moduleSpecifier); if (moduleSymbol) { - let exportDefaultSymbol: Symbol | undefined; - if (isShorthandAmbientModuleSymbol(moduleSymbol)) { + let exportDefaultSymbol: ts.Symbol | undefined; + if (ts.isShorthandAmbientModuleSymbol(moduleSymbol)) { exportDefaultSymbol = moduleSymbol; } else { - exportDefaultSymbol = resolveExportByName(moduleSymbol, InternalSymbolName.Default, node, dontResolveAlias); + exportDefaultSymbol = resolveExportByName(moduleSymbol, ts.InternalSymbolName.Default, node, dontResolveAlias); } - const file = moduleSymbol.declarations?.find(isSourceFile); + const file = moduleSymbol.declarations?.find(ts.isSourceFile); const hasDefaultOnly = isOnlyImportedAsDefault(node.parent.moduleSpecifier); const hasSyntheticDefault = canHaveSyntheticDefault(file, moduleSymbol, dontResolveAlias, node.parent.moduleSpecifier); if (!exportDefaultSymbol && !hasSyntheticDefault && !hasDefaultOnly) { if (hasExportAssignmentSymbol(moduleSymbol)) { - const compilerOptionName = moduleKind >= ModuleKind.ES2015 ? "allowSyntheticDefaultImports" : "esModuleInterop"; - const exportEqualsSymbol = moduleSymbol.exports!.get(InternalSymbolName.ExportEquals); + const compilerOptionName = moduleKind >= ts.ModuleKind.ES2015 ? "allowSyntheticDefaultImports" : "esModuleInterop"; + const exportEqualsSymbol = moduleSymbol.exports!.get(ts.InternalSymbolName.ExportEquals); const exportAssignment = exportEqualsSymbol!.valueDeclaration; - const err = error(node.name, Diagnostics.Module_0_can_only_be_default_imported_using_the_1_flag, symbolToString(moduleSymbol), compilerOptionName); + const err = error(node.name, ts.Diagnostics.Module_0_can_only_be_default_imported_using_the_1_flag, symbolToString(moduleSymbol), compilerOptionName); if (exportAssignment) { - addRelatedInfo(err, createDiagnosticForNode( - exportAssignment, - Diagnostics.This_module_is_declared_with_using_export_and_can_only_be_used_with_a_default_import_when_using_the_0_flag, - compilerOptionName - )); + ts.addRelatedInfo(err, ts.createDiagnosticForNode(exportAssignment, ts.Diagnostics.This_module_is_declared_with_using_export_and_can_only_be_used_with_a_default_import_when_using_the_0_flag, compilerOptionName)); } } else { @@ -2793,31 +2735,24 @@ namespace ts { } } - function reportNonDefaultExport(moduleSymbol: Symbol, node: ImportClause) { + function reportNonDefaultExport(moduleSymbol: ts.Symbol, node: ts.ImportClause) { if (moduleSymbol.exports?.has(node.symbol.escapedName)) { - error( - node.name, - Diagnostics.Module_0_has_no_default_export_Did_you_mean_to_use_import_1_from_0_instead, - symbolToString(moduleSymbol), - symbolToString(node.symbol), - ); + error(node.name, ts.Diagnostics.Module_0_has_no_default_export_Did_you_mean_to_use_import_1_from_0_instead, symbolToString(moduleSymbol), symbolToString(node.symbol)); } else { - const diagnostic = error(node.name, Diagnostics.Module_0_has_no_default_export, symbolToString(moduleSymbol)); - const exportStar = moduleSymbol.exports?.get(InternalSymbolName.ExportStar); + const diagnostic = error(node.name, ts.Diagnostics.Module_0_has_no_default_export, symbolToString(moduleSymbol)); + const exportStar = moduleSymbol.exports?.get(ts.InternalSymbolName.ExportStar); if (exportStar) { - const defaultExport = exportStar.declarations?.find(decl => !!( - isExportDeclaration(decl) && decl.moduleSpecifier && - resolveExternalModuleName(decl, decl.moduleSpecifier)?.exports?.has(InternalSymbolName.Default) - )); + const defaultExport = exportStar.declarations?.find(decl => !!(ts.isExportDeclaration(decl) && decl.moduleSpecifier && + resolveExternalModuleName(decl, decl.moduleSpecifier)?.exports?.has(ts.InternalSymbolName.Default))); if (defaultExport) { - addRelatedInfo(diagnostic, createDiagnosticForNode(defaultExport, Diagnostics.export_Asterisk_does_not_re_export_a_default)); + ts.addRelatedInfo(diagnostic, ts.createDiagnosticForNode(defaultExport, ts.Diagnostics.export_Asterisk_does_not_re_export_a_default)); } } } } - function getTargetOfNamespaceImport(node: NamespaceImport, dontResolveAlias: boolean): Symbol | undefined { + function getTargetOfNamespaceImport(node: ts.NamespaceImport, dontResolveAlias: boolean): ts.Symbol | undefined { const moduleSpecifier = node.parent.parent.moduleSpecifier; const immediate = resolveExternalModuleName(node, moduleSpecifier); const resolved = resolveESModuleSymbol(immediate, moduleSpecifier, dontResolveAlias, /*suppressUsageError*/ false); @@ -2825,7 +2760,7 @@ namespace ts { return resolved; } - function getTargetOfNamespaceExport(node: NamespaceExport, dontResolveAlias: boolean): Symbol | undefined { + function getTargetOfNamespaceExport(node: ts.NamespaceExport, dontResolveAlias: boolean): ts.Symbol | undefined { const moduleSpecifier = node.parent.moduleSpecifier; const immediate = moduleSpecifier && resolveExternalModuleName(node, moduleSpecifier); const resolved = moduleSpecifier && resolveESModuleSymbol(immediate, moduleSpecifier, dontResolveAlias, /*suppressUsageError*/ false); @@ -2851,24 +2786,27 @@ namespace ts { // // An 'import { Point } from "graphics"' needs to create a symbol that combines the value side 'Point' // property with the type/namespace side interface 'Point'. - function combineValueAndTypeSymbols(valueSymbol: Symbol, typeSymbol: Symbol): Symbol { + function combineValueAndTypeSymbols(valueSymbol: ts.Symbol, typeSymbol: ts.Symbol): ts.Symbol { if (valueSymbol === unknownSymbol && typeSymbol === unknownSymbol) { return unknownSymbol; } - if (valueSymbol.flags & (SymbolFlags.Type | SymbolFlags.Namespace)) { + if (valueSymbol.flags & (ts.SymbolFlags.Type | ts.SymbolFlags.Namespace)) { return valueSymbol; } const result = createSymbol(valueSymbol.flags | typeSymbol.flags, valueSymbol.escapedName); - result.declarations = deduplicate(concatenate(valueSymbol.declarations, typeSymbol.declarations), equateValues); + result.declarations = ts.deduplicate(ts.concatenate(valueSymbol.declarations, typeSymbol.declarations), ts.equateValues); result.parent = valueSymbol.parent || typeSymbol.parent; - if (valueSymbol.valueDeclaration) result.valueDeclaration = valueSymbol.valueDeclaration; - if (typeSymbol.members) result.members = new Map(typeSymbol.members); - if (valueSymbol.exports) result.exports = new Map(valueSymbol.exports); + if (valueSymbol.valueDeclaration) + result.valueDeclaration = valueSymbol.valueDeclaration; + if (typeSymbol.members) + result.members = new ts.Map(typeSymbol.members); + if (valueSymbol.exports) + result.exports = new ts.Map(valueSymbol.exports); return result; } - function getExportOfModule(symbol: Symbol, name: Identifier, specifier: Declaration, dontResolveAlias: boolean): Symbol | undefined { - if (symbol.flags & SymbolFlags.Module) { + function getExportOfModule(symbol: ts.Symbol, name: ts.Identifier, specifier: ts.Declaration, dontResolveAlias: boolean): ts.Symbol | undefined { + if (symbol.flags & ts.SymbolFlags.Module) { const exportSymbol = getExportsOfSymbol(symbol).get(name.escapedText); const resolved = resolveSymbol(exportSymbol, dontResolveAlias); markSymbolOfAliasDeclarationIfTypeOnly(specifier, exportSymbol, resolved, /*overwriteEmpty*/ false); @@ -2876,33 +2814,33 @@ namespace ts { } } - function getPropertyOfVariable(symbol: Symbol, name: __String): Symbol | undefined { - if (symbol.flags & SymbolFlags.Variable) { - const typeAnnotation = (symbol.valueDeclaration as VariableDeclaration).type; + function getPropertyOfVariable(symbol: ts.Symbol, name: ts.__String): ts.Symbol | undefined { + if (symbol.flags & ts.SymbolFlags.Variable) { + const typeAnnotation = (symbol.valueDeclaration as ts.VariableDeclaration).type; if (typeAnnotation) { return resolveSymbol(getPropertyOfType(getTypeFromTypeNode(typeAnnotation), name)); } } } - function getExternalModuleMember(node: ImportDeclaration | ExportDeclaration | VariableDeclaration, specifier: ImportOrExportSpecifier | BindingElement | PropertyAccessExpression, dontResolveAlias = false): Symbol | undefined { - const moduleSpecifier = getExternalModuleRequireArgument(node) || (node as ImportDeclaration | ExportDeclaration).moduleSpecifier!; + function getExternalModuleMember(node: ts.ImportDeclaration | ts.ExportDeclaration | ts.VariableDeclaration, specifier: ts.ImportOrExportSpecifier | ts.BindingElement | ts.PropertyAccessExpression, dontResolveAlias = false): ts.Symbol | undefined { + const moduleSpecifier = ts.getExternalModuleRequireArgument(node) || (node as ts.ImportDeclaration | ts.ExportDeclaration).moduleSpecifier!; const moduleSymbol = resolveExternalModuleName(node, moduleSpecifier)!; // TODO: GH#18217 - const name = !isPropertyAccessExpression(specifier) && specifier.propertyName || specifier.name; - if (!isIdentifier(name)) { + const name = !ts.isPropertyAccessExpression(specifier) && specifier.propertyName || specifier.name; + if (!ts.isIdentifier(name)) { return undefined; } - const suppressInteropError = name.escapedText === InternalSymbolName.Default && !!(compilerOptions.allowSyntheticDefaultImports || getESModuleInterop(compilerOptions)); + const suppressInteropError = name.escapedText === ts.InternalSymbolName.Default && !!(compilerOptions.allowSyntheticDefaultImports || ts.getESModuleInterop(compilerOptions)); const targetSymbol = resolveESModuleSymbol(moduleSymbol, moduleSpecifier, /*dontResolveAlias*/ false, suppressInteropError); if (targetSymbol) { if (name.escapedText) { - if (isShorthandAmbientModuleSymbol(moduleSymbol)) { + if (ts.isShorthandAmbientModuleSymbol(moduleSymbol)) { return moduleSymbol; } - let symbolFromVariable: Symbol | undefined; + let symbolFromVariable: ts.Symbol | undefined; // First check if module was specified with "export=". If so, get the member from the resolved type - if (moduleSymbol && moduleSymbol.exports && moduleSymbol.exports.get(InternalSymbolName.ExportEquals)) { + if (moduleSymbol && moduleSymbol.exports && moduleSymbol.exports.get(ts.InternalSymbolName.ExportEquals)) { symbolFromVariable = getPropertyOfType(getTypeOfSymbol(targetSymbol), name.escapedText, /*skipObjectFunctionPropertyAugment*/ true); } else { @@ -2912,8 +2850,8 @@ namespace ts { symbolFromVariable = resolveSymbol(symbolFromVariable, dontResolveAlias); let symbolFromModule = getExportOfModule(targetSymbol, name, specifier, dontResolveAlias); - if (symbolFromModule === undefined && name.escapedText === InternalSymbolName.Default) { - const file = moduleSymbol.declarations?.find(isSourceFile); + if (symbolFromModule === undefined && name.escapedText === ts.InternalSymbolName.Default) { + const file = moduleSymbol.declarations?.find(ts.isSourceFile); if (isOnlyImportedAsDefault(moduleSpecifier) || canHaveSyntheticDefault(file, moduleSymbol, dontResolveAlias, moduleSpecifier)) { symbolFromModule = resolveExternalModuleSymbol(moduleSymbol, dontResolveAlias) || resolveSymbol(moduleSymbol, dontResolveAlias); } @@ -2924,25 +2862,18 @@ namespace ts { symbolFromModule || symbolFromVariable; if (!symbol) { const moduleName = getFullyQualifiedName(moduleSymbol, node); - const declarationName = declarationNameToString(name); + const declarationName = ts.declarationNameToString(name); const suggestion = getSuggestedSymbolForNonexistentModule(name, targetSymbol); if (suggestion !== undefined) { const suggestionName = symbolToString(suggestion); - const diagnostic = error(name, Diagnostics._0_has_no_exported_member_named_1_Did_you_mean_2, moduleName, declarationName, suggestionName); + const diagnostic = error(name, ts.Diagnostics._0_has_no_exported_member_named_1_Did_you_mean_2, moduleName, declarationName, suggestionName); if (suggestion.valueDeclaration) { - addRelatedInfo(diagnostic, - createDiagnosticForNode(suggestion.valueDeclaration, Diagnostics._0_is_declared_here, suggestionName) - ); + ts.addRelatedInfo(diagnostic, ts.createDiagnosticForNode(suggestion.valueDeclaration, ts.Diagnostics._0_is_declared_here, suggestionName)); } } else { - if (moduleSymbol.exports?.has(InternalSymbolName.Default)) { - error( - name, - Diagnostics.Module_0_has_no_exported_member_1_Did_you_mean_to_use_import_1_from_0_instead, - moduleName, - declarationName - ); + if (moduleSymbol.exports?.has(ts.InternalSymbolName.Default)) { + error(name, ts.Diagnostics.Module_0_has_no_exported_member_1_Did_you_mean_to_use_import_1_from_0_instead, moduleName, declarationName); } else { reportNonExportedMember(node, name, declarationName, moduleSymbol, moduleName); @@ -2954,76 +2885,74 @@ namespace ts { } } - function reportNonExportedMember(node: ImportDeclaration | ExportDeclaration | VariableDeclaration, name: Identifier, declarationName: string, moduleSymbol: Symbol, moduleName: string): void { + function reportNonExportedMember(node: ts.ImportDeclaration | ts.ExportDeclaration | ts.VariableDeclaration, name: ts.Identifier, declarationName: string, moduleSymbol: ts.Symbol, moduleName: string): void { const localSymbol = moduleSymbol.valueDeclaration?.locals?.get(name.escapedText); const exports = moduleSymbol.exports; if (localSymbol) { - const exportedEqualsSymbol = exports?.get(InternalSymbolName.ExportEquals); + const exportedEqualsSymbol = exports?.get(ts.InternalSymbolName.ExportEquals); if (exportedEqualsSymbol) { getSymbolIfSameReference(exportedEqualsSymbol, localSymbol) ? reportInvalidImportEqualsExportMember(node, name, declarationName, moduleName) : - error(name, Diagnostics.Module_0_has_no_exported_member_1, moduleName, declarationName); + error(name, ts.Diagnostics.Module_0_has_no_exported_member_1, moduleName, declarationName); } else { - const exportedSymbol = exports ? find(symbolsToArray(exports), symbol => !!getSymbolIfSameReference(symbol, localSymbol)) : undefined; - const diagnostic = exportedSymbol ? error(name, Diagnostics.Module_0_declares_1_locally_but_it_is_exported_as_2, moduleName, declarationName, symbolToString(exportedSymbol)) : - error(name, Diagnostics.Module_0_declares_1_locally_but_it_is_not_exported, moduleName, declarationName); + const exportedSymbol = exports ? ts.find(symbolsToArray(exports), symbol => !!getSymbolIfSameReference(symbol, localSymbol)) : undefined; + const diagnostic = exportedSymbol ? error(name, ts.Diagnostics.Module_0_declares_1_locally_but_it_is_exported_as_2, moduleName, declarationName, symbolToString(exportedSymbol)) : + error(name, ts.Diagnostics.Module_0_declares_1_locally_but_it_is_not_exported, moduleName, declarationName); if (localSymbol.declarations) { - addRelatedInfo(diagnostic, - ...map(localSymbol.declarations, (decl, index) => - createDiagnosticForNode(decl, index === 0 ? Diagnostics._0_is_declared_here : Diagnostics.and_here, declarationName))); + ts.addRelatedInfo(diagnostic, ...ts.map(localSymbol.declarations, (decl, index) => ts.createDiagnosticForNode(decl, index === 0 ? ts.Diagnostics._0_is_declared_here : ts.Diagnostics.and_here, declarationName))); } } } else { - error(name, Diagnostics.Module_0_has_no_exported_member_1, moduleName, declarationName); + error(name, ts.Diagnostics.Module_0_has_no_exported_member_1, moduleName, declarationName); } } - function reportInvalidImportEqualsExportMember(node: ImportDeclaration | ExportDeclaration | VariableDeclaration, name: Identifier, declarationName: string, moduleName: string) { - if (moduleKind >= ModuleKind.ES2015) { - const message = getESModuleInterop(compilerOptions) ? Diagnostics._0_can_only_be_imported_by_using_a_default_import : - Diagnostics._0_can_only_be_imported_by_turning_on_the_esModuleInterop_flag_and_using_a_default_import; + function reportInvalidImportEqualsExportMember(node: ts.ImportDeclaration | ts.ExportDeclaration | ts.VariableDeclaration, name: ts.Identifier, declarationName: string, moduleName: string) { + if (moduleKind >= ts.ModuleKind.ES2015) { + const message = ts.getESModuleInterop(compilerOptions) ? ts.Diagnostics._0_can_only_be_imported_by_using_a_default_import : + ts.Diagnostics._0_can_only_be_imported_by_turning_on_the_esModuleInterop_flag_and_using_a_default_import; error(name, message, declarationName); } else { - if (isInJSFile(node)) { - const message = getESModuleInterop(compilerOptions) ? Diagnostics._0_can_only_be_imported_by_using_a_require_call_or_by_using_a_default_import : - Diagnostics._0_can_only_be_imported_by_using_a_require_call_or_by_turning_on_the_esModuleInterop_flag_and_using_a_default_import; + if (ts.isInJSFile(node)) { + const message = ts.getESModuleInterop(compilerOptions) ? ts.Diagnostics._0_can_only_be_imported_by_using_a_require_call_or_by_using_a_default_import : + ts.Diagnostics._0_can_only_be_imported_by_using_a_require_call_or_by_turning_on_the_esModuleInterop_flag_and_using_a_default_import; error(name, message, declarationName); } else { - const message = getESModuleInterop(compilerOptions) ? Diagnostics._0_can_only_be_imported_by_using_import_1_require_2_or_a_default_import : - Diagnostics._0_can_only_be_imported_by_using_import_1_require_2_or_by_turning_on_the_esModuleInterop_flag_and_using_a_default_import; + const message = ts.getESModuleInterop(compilerOptions) ? ts.Diagnostics._0_can_only_be_imported_by_using_import_1_require_2_or_a_default_import : + ts.Diagnostics._0_can_only_be_imported_by_using_import_1_require_2_or_by_turning_on_the_esModuleInterop_flag_and_using_a_default_import; error(name, message, declarationName, declarationName, moduleName); } } } - function getTargetOfImportSpecifier(node: ImportSpecifier | BindingElement, dontResolveAlias: boolean): Symbol | undefined { - const root = isBindingElement(node) ? getRootDeclaration(node) as VariableDeclaration : node.parent.parent.parent; + function getTargetOfImportSpecifier(node: ts.ImportSpecifier | ts.BindingElement, dontResolveAlias: boolean): ts.Symbol | undefined { + const root = ts.isBindingElement(node) ? ts.getRootDeclaration(node) as ts.VariableDeclaration : node.parent.parent.parent; const commonJSPropertyAccess = getCommonJSPropertyAccess(root); const resolved = getExternalModuleMember(root, commonJSPropertyAccess || node, dontResolveAlias); const name = node.propertyName || node.name; - if (commonJSPropertyAccess && resolved && isIdentifier(name)) { + if (commonJSPropertyAccess && resolved && ts.isIdentifier(name)) { return resolveSymbol(getPropertyOfType(getTypeOfSymbol(resolved), name.escapedText), dontResolveAlias); } markSymbolOfAliasDeclarationIfTypeOnly(node, /*immediateTarget*/ undefined, resolved, /*overwriteEmpty*/ false); return resolved; } - function getCommonJSPropertyAccess(node: Node) { - if (isVariableDeclaration(node) && node.initializer && isPropertyAccessExpression(node.initializer)) { + function getCommonJSPropertyAccess(node: ts.Node) { + if (ts.isVariableDeclaration(node) && node.initializer && ts.isPropertyAccessExpression(node.initializer)) { return node.initializer; } } - function getTargetOfNamespaceExportDeclaration(node: NamespaceExportDeclaration, dontResolveAlias: boolean): Symbol { + function getTargetOfNamespaceExportDeclaration(node: ts.NamespaceExportDeclaration, dontResolveAlias: boolean): ts.Symbol { const resolved = resolveExternalModuleSymbol(node.parent.symbol, dontResolveAlias); markSymbolOfAliasDeclarationIfTypeOnly(node, /*immediateTarget*/ undefined, resolved, /*overwriteEmpty*/ false); return resolved; } - function getTargetOfExportSpecifier(node: ExportSpecifier, meaning: SymbolFlags, dontResolveAlias?: boolean) { + function getTargetOfExportSpecifier(node: ts.ExportSpecifier, meaning: ts.SymbolFlags, dontResolveAlias?: boolean) { const resolved = node.parent.parent.moduleSpecifier ? getExternalModuleMember(node.parent.parent, node, dontResolveAlias) : resolveEntityName(node.propertyName || node.name, meaning, /*ignoreErrors*/ false, dontResolveAlias); @@ -3031,21 +2960,21 @@ namespace ts { return resolved; } - function getTargetOfExportAssignment(node: ExportAssignment | BinaryExpression, dontResolveAlias: boolean): Symbol | undefined { - const expression = isExportAssignment(node) ? node.expression : node.right; + function getTargetOfExportAssignment(node: ts.ExportAssignment | ts.BinaryExpression, dontResolveAlias: boolean): ts.Symbol | undefined { + const expression = ts.isExportAssignment(node) ? node.expression : node.right; const resolved = getTargetOfAliasLikeExpression(expression, dontResolveAlias); markSymbolOfAliasDeclarationIfTypeOnly(node, /*immediateTarget*/ undefined, resolved, /*overwriteEmpty*/ false); return resolved; } - function getTargetOfAliasLikeExpression(expression: Expression, dontResolveAlias: boolean) { - if (isClassExpression(expression)) { + function getTargetOfAliasLikeExpression(expression: ts.Expression, dontResolveAlias: boolean) { + if (ts.isClassExpression(expression)) { return checkExpressionCached(expression).symbol; } - if (!isEntityName(expression) && !isEntityNameExpression(expression)) { + if (!ts.isEntityName(expression) && !ts.isEntityNameExpression(expression)) { return undefined; } - const aliasLike = resolveEntityName(expression, SymbolFlags.Value | SymbolFlags.Type | SymbolFlags.Namespace, /*ignoreErrors*/ true, dontResolveAlias); + const aliasLike = resolveEntityName(expression, ts.SymbolFlags.Value | ts.SymbolFlags.Type | ts.SymbolFlags.Namespace, /*ignoreErrors*/ true, dontResolveAlias); if (aliasLike) { return aliasLike; } @@ -3053,49 +2982,49 @@ namespace ts { return getNodeLinks(expression).resolvedSymbol; } - function getTargetOfPropertyAssignment(node: PropertyAssignment, dontRecursivelyResolve: boolean): Symbol | undefined { + function getTargetOfPropertyAssignment(node: ts.PropertyAssignment, dontRecursivelyResolve: boolean): ts.Symbol | undefined { const expression = node.initializer; return getTargetOfAliasLikeExpression(expression, dontRecursivelyResolve); } - function getTargetOfAccessExpression(node: AccessExpression, dontRecursivelyResolve: boolean): Symbol | undefined { - if (!(isBinaryExpression(node.parent) && node.parent.left === node && node.parent.operatorToken.kind === SyntaxKind.EqualsToken)) { + function getTargetOfAccessExpression(node: ts.AccessExpression, dontRecursivelyResolve: boolean): ts.Symbol | undefined { + if (!(ts.isBinaryExpression(node.parent) && node.parent.left === node && node.parent.operatorToken.kind === ts.SyntaxKind.EqualsToken)) { return undefined; } return getTargetOfAliasLikeExpression(node.parent.right, dontRecursivelyResolve); } - function getTargetOfAliasDeclaration(node: Declaration, dontRecursivelyResolve = false): Symbol | undefined { + function getTargetOfAliasDeclaration(node: ts.Declaration, dontRecursivelyResolve = false): ts.Symbol | undefined { switch (node.kind) { - case SyntaxKind.ImportEqualsDeclaration: - case SyntaxKind.VariableDeclaration: - return getTargetOfImportEqualsDeclaration(node as ImportEqualsDeclaration | VariableDeclaration, dontRecursivelyResolve); - case SyntaxKind.ImportClause: - return getTargetOfImportClause(node as ImportClause, dontRecursivelyResolve); - case SyntaxKind.NamespaceImport: - return getTargetOfNamespaceImport(node as NamespaceImport, dontRecursivelyResolve); - case SyntaxKind.NamespaceExport: - return getTargetOfNamespaceExport(node as NamespaceExport, dontRecursivelyResolve); - case SyntaxKind.ImportSpecifier: - case SyntaxKind.BindingElement: - return getTargetOfImportSpecifier(node as ImportSpecifier | BindingElement, dontRecursivelyResolve); - case SyntaxKind.ExportSpecifier: - return getTargetOfExportSpecifier(node as ExportSpecifier, SymbolFlags.Value | SymbolFlags.Type | SymbolFlags.Namespace, dontRecursivelyResolve); - case SyntaxKind.ExportAssignment: - case SyntaxKind.BinaryExpression: - return getTargetOfExportAssignment((node as ExportAssignment | BinaryExpression), dontRecursivelyResolve); - case SyntaxKind.NamespaceExportDeclaration: - return getTargetOfNamespaceExportDeclaration(node as NamespaceExportDeclaration, dontRecursivelyResolve); - case SyntaxKind.ShorthandPropertyAssignment: - return resolveEntityName((node as ShorthandPropertyAssignment).name, SymbolFlags.Value | SymbolFlags.Type | SymbolFlags.Namespace, /*ignoreErrors*/ true, dontRecursivelyResolve); - case SyntaxKind.PropertyAssignment: - return getTargetOfPropertyAssignment(node as PropertyAssignment, dontRecursivelyResolve); - case SyntaxKind.ElementAccessExpression: - case SyntaxKind.PropertyAccessExpression: - return getTargetOfAccessExpression(node as AccessExpression, dontRecursivelyResolve); + case ts.SyntaxKind.ImportEqualsDeclaration: + case ts.SyntaxKind.VariableDeclaration: + return getTargetOfImportEqualsDeclaration(node as ts.ImportEqualsDeclaration | ts.VariableDeclaration, dontRecursivelyResolve); + case ts.SyntaxKind.ImportClause: + return getTargetOfImportClause(node as ts.ImportClause, dontRecursivelyResolve); + case ts.SyntaxKind.NamespaceImport: + return getTargetOfNamespaceImport(node as ts.NamespaceImport, dontRecursivelyResolve); + case ts.SyntaxKind.NamespaceExport: + return getTargetOfNamespaceExport(node as ts.NamespaceExport, dontRecursivelyResolve); + case ts.SyntaxKind.ImportSpecifier: + case ts.SyntaxKind.BindingElement: + return getTargetOfImportSpecifier(node as ts.ImportSpecifier | ts.BindingElement, dontRecursivelyResolve); + case ts.SyntaxKind.ExportSpecifier: + return getTargetOfExportSpecifier(node as ts.ExportSpecifier, ts.SymbolFlags.Value | ts.SymbolFlags.Type | ts.SymbolFlags.Namespace, dontRecursivelyResolve); + case ts.SyntaxKind.ExportAssignment: + case ts.SyntaxKind.BinaryExpression: + return getTargetOfExportAssignment((node as ts.ExportAssignment | ts.BinaryExpression), dontRecursivelyResolve); + case ts.SyntaxKind.NamespaceExportDeclaration: + return getTargetOfNamespaceExportDeclaration(node as ts.NamespaceExportDeclaration, dontRecursivelyResolve); + case ts.SyntaxKind.ShorthandPropertyAssignment: + return resolveEntityName((node as ts.ShorthandPropertyAssignment).name, ts.SymbolFlags.Value | ts.SymbolFlags.Type | ts.SymbolFlags.Namespace, /*ignoreErrors*/ true, dontRecursivelyResolve); + case ts.SyntaxKind.PropertyAssignment: + return getTargetOfPropertyAssignment(node as ts.PropertyAssignment, dontRecursivelyResolve); + case ts.SyntaxKind.ElementAccessExpression: + case ts.SyntaxKind.PropertyAccessExpression: + return getTargetOfAccessExpression(node as ts.AccessExpression, dontRecursivelyResolve); default: - return Debug.fail(); + return ts.Debug.fail(); } } @@ -3103,30 +3032,32 @@ namespace ts { * Indicates that a symbol is an alias that does not merge with a local declaration. * OR Is a JSContainer which may merge an alias with a local declaration */ - function isNonLocalAlias(symbol: Symbol | undefined, excludes = SymbolFlags.Value | SymbolFlags.Type | SymbolFlags.Namespace): symbol is Symbol { - if (!symbol) return false; - return (symbol.flags & (SymbolFlags.Alias | excludes)) === SymbolFlags.Alias || !!(symbol.flags & SymbolFlags.Alias && symbol.flags & SymbolFlags.Assignment); + function isNonLocalAlias(symbol: ts.Symbol | undefined, excludes = ts.SymbolFlags.Value | ts.SymbolFlags.Type | ts.SymbolFlags.Namespace): symbol is ts.Symbol { + if (!symbol) + return false; + return (symbol.flags & (ts.SymbolFlags.Alias | excludes)) === ts.SymbolFlags.Alias || !!(symbol.flags & ts.SymbolFlags.Alias && symbol.flags & ts.SymbolFlags.Assignment); } - function resolveSymbol(symbol: Symbol, dontResolveAlias?: boolean): Symbol; - function resolveSymbol(symbol: Symbol | undefined, dontResolveAlias?: boolean): Symbol | undefined; - function resolveSymbol(symbol: Symbol | undefined, dontResolveAlias?: boolean): Symbol | undefined { + function resolveSymbol(symbol: ts.Symbol, dontResolveAlias?: boolean): ts.Symbol; + function resolveSymbol(symbol: ts.Symbol | undefined, dontResolveAlias?: boolean): ts.Symbol | undefined; + function resolveSymbol(symbol: ts.Symbol | undefined, dontResolveAlias?: boolean): ts.Symbol | undefined { return !dontResolveAlias && isNonLocalAlias(symbol) ? resolveAlias(symbol) : symbol; } - function resolveAlias(symbol: Symbol): Symbol { - Debug.assert((symbol.flags & SymbolFlags.Alias) !== 0, "Should only get Alias here."); + function resolveAlias(symbol: ts.Symbol): ts.Symbol { + ts.Debug.assert((symbol.flags & ts.SymbolFlags.Alias) !== 0, "Should only get Alias here."); const links = getSymbolLinks(symbol); if (!links.aliasTarget) { links.aliasTarget = resolvingSymbol; const node = getDeclarationOfAliasSymbol(symbol); - if (!node) return Debug.fail(); + if (!node) + return ts.Debug.fail(); const target = getTargetOfAliasDeclaration(node); if (links.aliasTarget === resolvingSymbol) { links.aliasTarget = target || unknownSymbol; } else { - error(node, Diagnostics.Circular_definition_of_import_alias_0, symbolToString(symbol)); + error(node, ts.Diagnostics.Circular_definition_of_import_alias_0, symbolToString(symbol)); } } else if (links.aliasTarget === resolvingSymbol) { @@ -3135,7 +3066,7 @@ namespace ts { return links.aliasTarget; } - function tryResolveAlias(symbol: Symbol): Symbol | undefined { + function tryResolveAlias(symbol: ts.Symbol): ts.Symbol | undefined { const links = getSymbolLinks(symbol); if (links.aliasTarget !== resolvingSymbol) { return resolveAlias(symbol); @@ -3164,18 +3095,14 @@ namespace ts { * import declaration will initially be marked as not resolving to a type-only symbol. But, namespace `b` * must still be checked for a type-only marker, overwriting the previous negative result if found. */ - function markSymbolOfAliasDeclarationIfTypeOnly( - aliasDeclaration: Declaration | undefined, - immediateTarget: Symbol | undefined, - finalTarget: Symbol | undefined, - overwriteEmpty: boolean, - ): boolean { - if (!aliasDeclaration || isPropertyAccessExpression(aliasDeclaration)) return false; + function markSymbolOfAliasDeclarationIfTypeOnly(aliasDeclaration: ts.Declaration | undefined, immediateTarget: ts.Symbol | undefined, finalTarget: ts.Symbol | undefined, overwriteEmpty: boolean): boolean { + if (!aliasDeclaration || ts.isPropertyAccessExpression(aliasDeclaration)) + return false; // If the declaration itself is type-only, mark it and return. // No need to check what it resolves to. const sourceSymbol = getSymbolOfNode(aliasDeclaration); - if (isTypeOnlyImportOrExportDeclaration(aliasDeclaration)) { + if (ts.isTypeOnlyImportOrExportDeclaration(aliasDeclaration)) { const links = getSymbolLinks(sourceSymbol); links.typeOnlyDeclaration = aliasDeclaration; return true; @@ -3186,30 +3113,30 @@ namespace ts { || markSymbolOfAliasDeclarationIfTypeOnlyWorker(links, finalTarget, overwriteEmpty); } - function markSymbolOfAliasDeclarationIfTypeOnlyWorker(aliasDeclarationLinks: SymbolLinks, target: Symbol | undefined, overwriteEmpty: boolean): boolean { + function markSymbolOfAliasDeclarationIfTypeOnlyWorker(aliasDeclarationLinks: ts.SymbolLinks, target: ts.Symbol | undefined, overwriteEmpty: boolean): boolean { if (target && (aliasDeclarationLinks.typeOnlyDeclaration === undefined || overwriteEmpty && aliasDeclarationLinks.typeOnlyDeclaration === false)) { - const exportSymbol = target.exports?.get(InternalSymbolName.ExportEquals) ?? target; - const typeOnly = exportSymbol.declarations && find(exportSymbol.declarations, isTypeOnlyImportOrExportDeclaration); + const exportSymbol = target.exports?.get(ts.InternalSymbolName.ExportEquals) ?? target; + const typeOnly = exportSymbol.declarations && ts.find(exportSymbol.declarations, ts.isTypeOnlyImportOrExportDeclaration); aliasDeclarationLinks.typeOnlyDeclaration = typeOnly ?? getSymbolLinks(exportSymbol).typeOnlyDeclaration ?? false; } return !!aliasDeclarationLinks.typeOnlyDeclaration; } /** Indicates that a symbol directly or indirectly resolves to a type-only import or export. */ - function getTypeOnlyAliasDeclaration(symbol: Symbol): TypeOnlyAliasDeclaration | undefined { - if (!(symbol.flags & SymbolFlags.Alias)) { + function getTypeOnlyAliasDeclaration(symbol: ts.Symbol): ts.TypeOnlyAliasDeclaration | undefined { + if (!(symbol.flags & ts.SymbolFlags.Alias)) { return undefined; } const links = getSymbolLinks(symbol); return links.typeOnlyDeclaration || undefined; } - function markExportAsReferenced(node: ImportEqualsDeclaration | ExportSpecifier) { + function markExportAsReferenced(node: ts.ImportEqualsDeclaration | ts.ExportSpecifier) { const symbol = getSymbolOfNode(node); const target = resolveAlias(symbol); if (target) { const markAlias = target === unknownSymbol || - ((target.flags & SymbolFlags.Value) && !isConstEnumOrConstEnumOnlyModule(target) && !getTypeOnlyAliasDeclaration(symbol)); + ((target.flags & ts.SymbolFlags.Value) && !isConstEnumOrConstEnumOnlyModule(target) && !getTypeOnlyAliasDeclaration(symbol)); if (markAlias) { markAliasSymbolAsReferenced(symbol); @@ -3220,20 +3147,21 @@ namespace ts { // When an alias symbol is referenced, we need to mark the entity it references as referenced and in turn repeat that until // we reach a non-alias or an exported entity (which is always considered referenced). We do this by checking the target of // the alias as an expression (which recursively takes us back here if the target references another alias). - function markAliasSymbolAsReferenced(symbol: Symbol) { + function markAliasSymbolAsReferenced(symbol: ts.Symbol) { const links = getSymbolLinks(symbol); if (!links.referenced) { links.referenced = true; const node = getDeclarationOfAliasSymbol(symbol); - if (!node) return Debug.fail(); + if (!node) + return ts.Debug.fail(); // We defer checking of the reference of an `import =` until the import itself is referenced, // This way a chain of imports can be elided if ultimately the final input is only used in a type // position. - if (isInternalModuleImportEqualsDeclaration(node)) { + if (ts.isInternalModuleImportEqualsDeclaration(node)) { const target = resolveSymbol(symbol); - if (target === unknownSymbol || target.flags & SymbolFlags.Value) { + if (target === unknownSymbol || target.flags & ts.SymbolFlags.Value) { // import foo = - checkExpressionCached(node.moduleReference as Expression); + checkExpressionCached(node.moduleReference as ts.Expression); } } } @@ -3241,7 +3169,7 @@ namespace ts { // Aliases that resolve to const enums are not marked as referenced because they are not emitted, // but their usage in value positions must be tracked to determine if the import can be type-only. - function markConstEnumAliasAsReferenced(symbol: Symbol) { + function markConstEnumAliasAsReferenced(symbol: ts.Symbol) { const links = getSymbolLinks(symbol); if (!links.constEnumReferenced) { links.constEnumReferenced = true; @@ -3249,46 +3177,46 @@ namespace ts { } // This function is only for imports with entity names - function getSymbolOfPartOfRightHandSideOfImportEquals(entityName: EntityName, dontResolveAlias?: boolean): Symbol | undefined { + function getSymbolOfPartOfRightHandSideOfImportEquals(entityName: ts.EntityName, dontResolveAlias?: boolean): ts.Symbol | undefined { // There are three things we might try to look for. In the following examples, // the search term is enclosed in |...|: // // import a = |b|; // Namespace // import a = |b.c|; // Value, type, namespace // import a = |b.c|.d; // Namespace - if (entityName.kind === SyntaxKind.Identifier && isRightSideOfQualifiedNameOrPropertyAccess(entityName)) { - entityName = entityName.parent as QualifiedName; + if (entityName.kind === ts.SyntaxKind.Identifier && ts.isRightSideOfQualifiedNameOrPropertyAccess(entityName)) { + entityName = entityName.parent as ts.QualifiedName; } // Check for case 1 and 3 in the above example - if (entityName.kind === SyntaxKind.Identifier || entityName.parent.kind === SyntaxKind.QualifiedName) { - return resolveEntityName(entityName, SymbolFlags.Namespace, /*ignoreErrors*/ false, dontResolveAlias); + if (entityName.kind === ts.SyntaxKind.Identifier || entityName.parent.kind === ts.SyntaxKind.QualifiedName) { + return resolveEntityName(entityName, ts.SymbolFlags.Namespace, /*ignoreErrors*/ false, dontResolveAlias); } else { // Case 2 in above example // entityName.kind could be a QualifiedName or a Missing identifier - Debug.assert(entityName.parent.kind === SyntaxKind.ImportEqualsDeclaration); - return resolveEntityName(entityName, SymbolFlags.Value | SymbolFlags.Type | SymbolFlags.Namespace, /*ignoreErrors*/ false, dontResolveAlias); + ts.Debug.assert(entityName.parent.kind === ts.SyntaxKind.ImportEqualsDeclaration); + return resolveEntityName(entityName, ts.SymbolFlags.Value | ts.SymbolFlags.Type | ts.SymbolFlags.Namespace, /*ignoreErrors*/ false, dontResolveAlias); } } - function getFullyQualifiedName(symbol: Symbol, containingLocation?: Node): string { - return symbol.parent ? getFullyQualifiedName(symbol.parent, containingLocation) + "." + symbolToString(symbol) : symbolToString(symbol, containingLocation, /*meaning*/ undefined, SymbolFormatFlags.DoNotIncludeSymbolChain | SymbolFormatFlags.AllowAnyNodeKind); + function getFullyQualifiedName(symbol: ts.Symbol, containingLocation?: ts.Node): string { + return symbol.parent ? getFullyQualifiedName(symbol.parent, containingLocation) + "." + symbolToString(symbol) : symbolToString(symbol, containingLocation, /*meaning*/ undefined, ts.SymbolFormatFlags.DoNotIncludeSymbolChain | ts.SymbolFormatFlags.AllowAnyNodeKind); } - function getContainingQualifiedNameNode(node: QualifiedName) { - while (isQualifiedName(node.parent)) { + function getContainingQualifiedNameNode(node: ts.QualifiedName) { + while (ts.isQualifiedName(node.parent)) { node = node.parent; } return node; } - function tryGetQualifiedNameAsValue(node: QualifiedName) { - let left: Identifier | QualifiedName = getFirstIdentifier(node); - let symbol = resolveName(left, left.escapedText, SymbolFlags.Value, undefined, left, /*isUse*/ true); + function tryGetQualifiedNameAsValue(node: ts.QualifiedName) { + let left: ts.Identifier | ts.QualifiedName = ts.getFirstIdentifier(node); + let symbol = resolveName(left, left.escapedText, ts.SymbolFlags.Value, undefined, left, /*isUse*/ true); if (!symbol) { return undefined; } - while (isQualifiedName(left.parent)) { + while (ts.isQualifiedName(left.parent)) { const type = getTypeOfSymbol(symbol); symbol = getPropertyOfType(type, left.parent.right.escapedText); if (!symbol) { @@ -3302,39 +3230,37 @@ namespace ts { /** * Resolves a qualified name and any involved aliases. */ - function resolveEntityName(name: EntityNameOrEntityNameExpression, meaning: SymbolFlags, ignoreErrors?: boolean, dontResolveAlias?: boolean, location?: Node): Symbol | undefined { - if (nodeIsMissing(name)) { + function resolveEntityName(name: ts.EntityNameOrEntityNameExpression, meaning: ts.SymbolFlags, ignoreErrors?: boolean, dontResolveAlias?: boolean, location?: ts.Node): ts.Symbol | undefined { + if (ts.nodeIsMissing(name)) { return undefined; } - const namespaceMeaning = SymbolFlags.Namespace | (isInJSFile(name) ? meaning & SymbolFlags.Value : 0); - let symbol: Symbol | undefined; - if (name.kind === SyntaxKind.Identifier) { - const message = meaning === namespaceMeaning || nodeIsSynthesized(name) ? Diagnostics.Cannot_find_namespace_0 : getCannotFindNameDiagnosticForName(getFirstIdentifier(name)); - const symbolFromJSPrototype = isInJSFile(name) && !nodeIsSynthesized(name) ? resolveEntityNameFromAssignmentDeclaration(name, meaning) : undefined; + const namespaceMeaning = ts.SymbolFlags.Namespace | (ts.isInJSFile(name) ? meaning & ts.SymbolFlags.Value : 0); + let symbol: ts.Symbol | undefined; + if (name.kind === ts.SyntaxKind.Identifier) { + const message = meaning === namespaceMeaning || ts.nodeIsSynthesized(name) ? ts.Diagnostics.Cannot_find_namespace_0 : getCannotFindNameDiagnosticForName(ts.getFirstIdentifier(name)); + const symbolFromJSPrototype = ts.isInJSFile(name) && !ts.nodeIsSynthesized(name) ? resolveEntityNameFromAssignmentDeclaration(name, meaning) : undefined; symbol = getMergedSymbol(resolveName(location || name, name.escapedText, meaning, ignoreErrors || symbolFromJSPrototype ? undefined : message, name, /*isUse*/ true, false)); if (!symbol) { return getMergedSymbol(symbolFromJSPrototype); } } - else if (name.kind === SyntaxKind.QualifiedName || name.kind === SyntaxKind.PropertyAccessExpression) { - const left = name.kind === SyntaxKind.QualifiedName ? name.left : name.expression; - const right = name.kind === SyntaxKind.QualifiedName ? name.right : name.name; + else if (name.kind === ts.SyntaxKind.QualifiedName || name.kind === ts.SyntaxKind.PropertyAccessExpression) { + const left = name.kind === ts.SyntaxKind.QualifiedName ? name.left : name.expression; + const right = name.kind === ts.SyntaxKind.QualifiedName ? name.right : name.name; let namespace = resolveEntityName(left, namespaceMeaning, ignoreErrors, /*dontResolveAlias*/ false, location); - if (!namespace || nodeIsMissing(right)) { + if (!namespace || ts.nodeIsMissing(right)) { return undefined; } else if (namespace === unknownSymbol) { return namespace; } - if ( - namespace.valueDeclaration && - isInJSFile(namespace.valueDeclaration) && - isVariableDeclaration(namespace.valueDeclaration) && + if (namespace.valueDeclaration && + ts.isInJSFile(namespace.valueDeclaration) && + ts.isVariableDeclaration(namespace.valueDeclaration) && namespace.valueDeclaration.initializer && - isCommonJsRequire(namespace.valueDeclaration.initializer) - ) { - const moduleName = (namespace.valueDeclaration.initializer as CallExpression).arguments[0] as StringLiteral; + isCommonJsRequire(namespace.valueDeclaration.initializer)) { + const moduleName = (namespace.valueDeclaration.initializer as ts.CallExpression).arguments[0] as ts.StringLiteral; const moduleSym = resolveExternalModuleName(moduleName, moduleName); if (moduleSym) { const resolvedModuleSymbol = resolveExternalModuleSymbol(moduleSym); @@ -3347,52 +3273,43 @@ namespace ts { if (!symbol) { if (!ignoreErrors) { const namespaceName = getFullyQualifiedName(namespace); - const declarationName = declarationNameToString(right); + const declarationName = ts.declarationNameToString(right); const suggestionForNonexistentModule = getSuggestedSymbolForNonexistentModule(right, namespace); if (suggestionForNonexistentModule) { - error(right, Diagnostics._0_has_no_exported_member_named_1_Did_you_mean_2, namespaceName, declarationName, symbolToString(suggestionForNonexistentModule)); + error(right, ts.Diagnostics._0_has_no_exported_member_named_1_Did_you_mean_2, namespaceName, declarationName, symbolToString(suggestionForNonexistentModule)); return undefined; } - const containingQualifiedName = isQualifiedName(name) && getContainingQualifiedNameNode(name); + const containingQualifiedName = ts.isQualifiedName(name) && getContainingQualifiedNameNode(name); const canSuggestTypeof = globalObjectType // <-- can't pull on types if global types aren't initialized yet - && (meaning & SymbolFlags.Type) + && (meaning & ts.SymbolFlags.Type) && containingQualifiedName - && !isTypeOfExpression(containingQualifiedName.parent) + && !ts.isTypeOfExpression(containingQualifiedName.parent) && tryGetQualifiedNameAsValue(containingQualifiedName); if (canSuggestTypeof) { - error( - containingQualifiedName, - Diagnostics._0_refers_to_a_value_but_is_being_used_as_a_type_here_Did_you_mean_typeof_0, - entityNameToString(containingQualifiedName) - ); + error(containingQualifiedName, ts.Diagnostics._0_refers_to_a_value_but_is_being_used_as_a_type_here_Did_you_mean_typeof_0, ts.entityNameToString(containingQualifiedName)); return undefined; } - if (meaning & SymbolFlags.Namespace && isQualifiedName(name.parent)) { - const exportedTypeSymbol = getMergedSymbol(getSymbol(getExportsOfSymbol(namespace), right.escapedText, SymbolFlags.Type)); + if (meaning & ts.SymbolFlags.Namespace && ts.isQualifiedName(name.parent)) { + const exportedTypeSymbol = getMergedSymbol(getSymbol(getExportsOfSymbol(namespace), right.escapedText, ts.SymbolFlags.Type)); if (exportedTypeSymbol) { - error( - name.parent.right, - Diagnostics.Cannot_access_0_1_because_0_is_a_type_but_not_a_namespace_Did_you_mean_to_retrieve_the_type_of_the_property_1_in_0_with_0_1, - symbolToString(exportedTypeSymbol), - unescapeLeadingUnderscores(name.parent.right.escapedText) - ); + error(name.parent.right, ts.Diagnostics.Cannot_access_0_1_because_0_is_a_type_but_not_a_namespace_Did_you_mean_to_retrieve_the_type_of_the_property_1_in_0_with_0_1, symbolToString(exportedTypeSymbol), ts.unescapeLeadingUnderscores(name.parent.right.escapedText)); return undefined; } } - error(right, Diagnostics.Namespace_0_has_no_exported_member_1, namespaceName, declarationName); + error(right, ts.Diagnostics.Namespace_0_has_no_exported_member_1, namespaceName, declarationName); } return undefined; } } else { - throw Debug.assertNever(name, "Unknown entity name kind."); + throw ts.Debug.assertNever(name, "Unknown entity name kind."); } - Debug.assert((getCheckFlags(symbol) & CheckFlags.Instantiated) === 0, "Should never get an instantiated symbol here."); - if (!nodeIsSynthesized(name) && isEntityName(name) && (symbol.flags & SymbolFlags.Alias || name.parent.kind === SyntaxKind.ExportAssignment)) { - markSymbolOfAliasDeclarationIfTypeOnly(getAliasDeclarationFromName(name), symbol, /*finalTarget*/ undefined, /*overwriteEmpty*/ true); + ts.Debug.assert((ts.getCheckFlags(symbol) & ts.CheckFlags.Instantiated) === 0, "Should never get an instantiated symbol here."); + if (!ts.nodeIsSynthesized(name) && ts.isEntityName(name) && (symbol.flags & ts.SymbolFlags.Alias || name.parent.kind === ts.SyntaxKind.ExportAssignment)) { + markSymbolOfAliasDeclarationIfTypeOnly(ts.getAliasDeclarationFromName(name), symbol, /*finalTarget*/ undefined, /*overwriteEmpty*/ true); } return (symbol.flags & meaning) || dontResolveAlias ? symbol : resolveAlias(symbol); } @@ -3403,7 +3320,7 @@ namespace ts { * name resolution won't work either. * 2. For property assignments like `{ x: function f () { } }`, try to resolve names in the scope of `f` too. */ - function resolveEntityNameFromAssignmentDeclaration(name: Identifier, meaning: SymbolFlags) { + function resolveEntityNameFromAssignmentDeclaration(name: ts.Identifier, meaning: ts.SymbolFlags) { if (isJSDocTypeReference(name.parent)) { const secondaryLocation = getAssignmentDeclarationLocation(name.parent); if (secondaryLocation) { @@ -3412,49 +3329,49 @@ namespace ts { } } - function getAssignmentDeclarationLocation(node: TypeReferenceNode): Node | undefined { - const typeAlias = findAncestor(node, node => !(isJSDocNode(node) || node.flags & NodeFlags.JSDoc) ? "quit" : isJSDocTypeAlias(node)); + function getAssignmentDeclarationLocation(node: ts.TypeReferenceNode): ts.Node | undefined { + const typeAlias = ts.findAncestor(node, node => !(ts.isJSDocNode(node) || node.flags & ts.NodeFlags.JSDoc) ? "quit" : ts.isJSDocTypeAlias(node)); if (typeAlias) { return; } - const host = getJSDocHost(node); - if (host && isExpressionStatement(host) && isPrototypePropertyAssignment(host.expression)) { + const host = ts.getJSDocHost(node); + if (host && ts.isExpressionStatement(host) && ts.isPrototypePropertyAssignment(host.expression)) { // /** @param {K} p */ X.prototype.m = function () { } <-- look for K on X's declaration const symbol = getSymbolOfNode(host.expression.left); if (symbol) { return getDeclarationOfJSPrototypeContainer(symbol); } } - if (host && isFunctionExpression(host) && isPrototypePropertyAssignment(host.parent) && isExpressionStatement(host.parent.parent)) { + if (host && ts.isFunctionExpression(host) && ts.isPrototypePropertyAssignment(host.parent) && ts.isExpressionStatement(host.parent.parent)) { // X.prototype.m = /** @param {K} p */ function () { } <-- look for K on X's declaration const symbol = getSymbolOfNode(host.parent.left); if (symbol) { return getDeclarationOfJSPrototypeContainer(symbol); } } - if (host && (isObjectLiteralMethod(host) || isPropertyAssignment(host)) && - isBinaryExpression(host.parent.parent) && - getAssignmentDeclarationKind(host.parent.parent) === AssignmentDeclarationKind.Prototype) { + if (host && (ts.isObjectLiteralMethod(host) || ts.isPropertyAssignment(host)) && + ts.isBinaryExpression(host.parent.parent) && + ts.getAssignmentDeclarationKind(host.parent.parent) === ts.AssignmentDeclarationKind.Prototype) { // X.prototype = { /** @param {K} p */m() { } } <-- look for K on X's declaration const symbol = getSymbolOfNode(host.parent.parent.left); if (symbol) { return getDeclarationOfJSPrototypeContainer(symbol); } } - const sig = getEffectiveJSDocHost(node); - if (sig && isFunctionLike(sig)) { + const sig = ts.getEffectiveJSDocHost(node); + if (sig && ts.isFunctionLike(sig)) { const symbol = getSymbolOfNode(sig); return symbol && symbol.valueDeclaration; } } - function getDeclarationOfJSPrototypeContainer(symbol: Symbol) { + function getDeclarationOfJSPrototypeContainer(symbol: ts.Symbol) { const decl = symbol.parent!.valueDeclaration; if (!decl) { return undefined; } - const initializer = isAssignmentDeclaration(decl) ? getAssignedExpandoInitializer(decl) : - hasOnlyExpressionInitializer(decl) ? getDeclaredExpandoInitializer(decl) : + const initializer = ts.isAssignmentDeclaration(decl) ? ts.getAssignedExpandoInitializer(decl) : + ts.hasOnlyExpressionInitializer(decl) ? ts.getDeclaredExpandoInitializer(decl) : undefined; return initializer || decl; } @@ -3465,12 +3382,12 @@ namespace ts { * Normally, declarations have an associated symbol, but when a declaration has an expando * initializer, the expando's symbol is the one that has all the members merged into it. */ - function getExpandoSymbol(symbol: Symbol): Symbol | undefined { + function getExpandoSymbol(symbol: ts.Symbol): ts.Symbol | undefined { const decl = symbol.valueDeclaration; - if (!decl || !isInJSFile(decl) || symbol.flags & SymbolFlags.TypeAlias || getExpandoInitializer(decl, /*isPrototypeAssignment*/ false)) { + if (!decl || !ts.isInJSFile(decl) || symbol.flags & ts.SymbolFlags.TypeAlias || ts.getExpandoInitializer(decl, /*isPrototypeAssignment*/ false)) { return undefined; } - const init = isVariableDeclaration(decl) ? getDeclaredExpandoInitializer(decl) : getAssignedExpandoInitializer(decl); + const init = ts.isVariableDeclaration(decl) ? ts.getDeclaredExpandoInitializer(decl) : ts.getAssignedExpandoInitializer(decl); if (init) { const initSymbol = getSymbolOfNode(init); if (initSymbol) { @@ -3479,24 +3396,24 @@ namespace ts { } } - function resolveExternalModuleName(location: Node, moduleReferenceExpression: Expression, ignoreErrors?: boolean): Symbol | undefined { - const isClassic = getEmitModuleResolutionKind(compilerOptions) === ModuleResolutionKind.Classic; + function resolveExternalModuleName(location: ts.Node, moduleReferenceExpression: ts.Expression, ignoreErrors?: boolean): ts.Symbol | undefined { + const isClassic = ts.getEmitModuleResolutionKind(compilerOptions) === ts.ModuleResolutionKind.Classic; const errorMessage = isClassic? - Diagnostics.Cannot_find_module_0_Did_you_mean_to_set_the_moduleResolution_option_to_node_or_to_add_aliases_to_the_paths_option - : Diagnostics.Cannot_find_module_0_or_its_corresponding_type_declarations; + ts.Diagnostics.Cannot_find_module_0_Did_you_mean_to_set_the_moduleResolution_option_to_node_or_to_add_aliases_to_the_paths_option + : ts.Diagnostics.Cannot_find_module_0_or_its_corresponding_type_declarations; return resolveExternalModuleNameWorker(location, moduleReferenceExpression, ignoreErrors ? undefined : errorMessage); } - function resolveExternalModuleNameWorker(location: Node, moduleReferenceExpression: Expression, moduleNotFoundError: DiagnosticMessage | undefined, isForAugmentation = false): Symbol | undefined { - return isStringLiteralLike(moduleReferenceExpression) + function resolveExternalModuleNameWorker(location: ts.Node, moduleReferenceExpression: ts.Expression, moduleNotFoundError: ts.DiagnosticMessage | undefined, isForAugmentation = false): ts.Symbol | undefined { + return ts.isStringLiteralLike(moduleReferenceExpression) ? resolveExternalModule(location, moduleReferenceExpression.text, moduleNotFoundError, moduleReferenceExpression, isForAugmentation) : undefined; } - function resolveExternalModule(location: Node, moduleReference: string, moduleNotFoundError: DiagnosticMessage | undefined, errorNode: Node, isForAugmentation = false): Symbol | undefined { - if (startsWith(moduleReference, "@types/")) { - const diag = Diagnostics.Cannot_import_type_declaration_files_Consider_importing_0_instead_of_1; - const withoutAtTypePrefix = removePrefix(moduleReference, "@types/"); + function resolveExternalModule(location: ts.Node, moduleReference: string, moduleNotFoundError: ts.DiagnosticMessage | undefined, errorNode: ts.Node, isForAugmentation = false): ts.Symbol | undefined { + if (ts.startsWith(moduleReference, "@types/")) { + const diag = ts.Diagnostics.Cannot_import_type_declaration_files_Consider_importing_0_instead_of_1; + const withoutAtTypePrefix = ts.removePrefix(moduleReference, "@types/"); error(errorNode, diag, withoutAtTypePrefix, moduleReference); } @@ -3504,20 +3421,20 @@ namespace ts { if (ambientModule) { return ambientModule; } - const currentSourceFile = getSourceFileOfNode(location); - const contextSpecifier = isStringLiteralLike(location) + const currentSourceFile = ts.getSourceFileOfNode(location); + const contextSpecifier = ts.isStringLiteralLike(location) ? location - : findAncestor(location, isImportCall)?.arguments[0] || - findAncestor(location, isImportDeclaration)?.moduleSpecifier || - findAncestor(location, isExternalModuleImportEqualsDeclaration)?.moduleReference.expression || - findAncestor(location, isExportDeclaration)?.moduleSpecifier || - (isModuleDeclaration(location) ? location : location.parent && isModuleDeclaration(location.parent) && location.parent.name === location ? location.parent : undefined)?.name || - (isLiteralImportTypeNode(location) ? location : undefined)?.argument.literal; - const mode = contextSpecifier && isStringLiteralLike(contextSpecifier) ? getModeForUsageLocation(currentSourceFile, contextSpecifier) : currentSourceFile.impliedNodeFormat; - const resolvedModule = getResolvedModule(currentSourceFile, moduleReference, mode); - const resolutionDiagnostic = resolvedModule && getResolutionDiagnostic(compilerOptions, resolvedModule); + : ts.findAncestor(location, ts.isImportCall)?.arguments[0] || + ts.findAncestor(location, ts.isImportDeclaration)?.moduleSpecifier || + ts.findAncestor(location, ts.isExternalModuleImportEqualsDeclaration)?.moduleReference.expression || + ts.findAncestor(location, ts.isExportDeclaration)?.moduleSpecifier || + (ts.isModuleDeclaration(location) ? location : location.parent && ts.isModuleDeclaration(location.parent) && location.parent.name === location ? location.parent : undefined)?.name || + (ts.isLiteralImportTypeNode(location) ? location : undefined)?.argument.literal; + const mode = contextSpecifier && ts.isStringLiteralLike(contextSpecifier) ? ts.getModeForUsageLocation(currentSourceFile, contextSpecifier) : currentSourceFile.impliedNodeFormat; + const resolvedModule = ts.getResolvedModule(currentSourceFile, moduleReference, mode); + const resolutionDiagnostic = resolvedModule && ts.getResolutionDiagnostic(compilerOptions, resolvedModule); const sourceFile = resolvedModule - && (!resolutionDiagnostic || resolutionDiagnostic === Diagnostics.Module_0_was_resolved_to_1_but_jsx_is_not_set) + && (!resolutionDiagnostic || resolutionDiagnostic === ts.Diagnostics.Module_0_was_resolved_to_1_but_jsx_is_not_set) && host.getSourceFile(resolvedModule.resolvedFileName); if (sourceFile) { // If there's a resolutionDiagnostic we need to report it even if a sourceFile is found. @@ -3525,17 +3442,17 @@ namespace ts { error(errorNode, resolutionDiagnostic, moduleReference, resolvedModule.resolvedFileName); } if (sourceFile.symbol) { - if (resolvedModule.isExternalLibraryImport && !resolutionExtensionIsTSOrJson(resolvedModule.extension)) { + if (resolvedModule.isExternalLibraryImport && !ts.resolutionExtensionIsTSOrJson(resolvedModule.extension)) { errorOnImplicitAnyModule(/*isError*/ false, errorNode, resolvedModule, moduleReference); } - if (getEmitModuleResolutionKind(compilerOptions) === ModuleResolutionKind.Node16 || getEmitModuleResolutionKind(compilerOptions) === ModuleResolutionKind.NodeNext) { - const isSyncImport = (currentSourceFile.impliedNodeFormat === ModuleKind.CommonJS && !findAncestor(location, isImportCall)) || !!findAncestor(location, isImportEqualsDeclaration); - const overrideClauseHost = findAncestor(location, l => isImportTypeNode(l) || isExportDeclaration(l) || isImportDeclaration(l)) as ImportTypeNode | ImportDeclaration | ExportDeclaration | undefined; - const overrideClause = overrideClauseHost && isImportTypeNode(overrideClauseHost) ? overrideClauseHost.assertions?.assertClause : overrideClauseHost?.assertClause; + if (ts.getEmitModuleResolutionKind(compilerOptions) === ts.ModuleResolutionKind.Node16 || ts.getEmitModuleResolutionKind(compilerOptions) === ts.ModuleResolutionKind.NodeNext) { + const isSyncImport = (currentSourceFile.impliedNodeFormat === ts.ModuleKind.CommonJS && !ts.findAncestor(location, ts.isImportCall)) || !!ts.findAncestor(location, ts.isImportEqualsDeclaration); + const overrideClauseHost = ts.findAncestor(location, l => ts.isImportTypeNode(l) || ts.isExportDeclaration(l) || ts.isImportDeclaration(l)) as ts.ImportTypeNode | ts.ImportDeclaration | ts.ExportDeclaration | undefined; + const overrideClause = overrideClauseHost && ts.isImportTypeNode(overrideClauseHost) ? overrideClauseHost.assertions?.assertClause : overrideClauseHost?.assertClause; // An override clause will take effect for type-only imports and import types, and allows importing the types across formats, regardless of // normal mode restrictions - if (isSyncImport && sourceFile.impliedNodeFormat === ModuleKind.ESNext && !getResolutionModeOverrideForClause(overrideClause)) { - error(errorNode, Diagnostics.Module_0_cannot_be_imported_using_this_construct_The_specifier_only_resolves_to_an_ES_module_which_cannot_be_imported_synchronously_Use_dynamic_import_instead, moduleReference); + if (isSyncImport && sourceFile.impliedNodeFormat === ts.ModuleKind.ESNext && !ts.getResolutionModeOverrideForClause(overrideClause)) { + error(errorNode, ts.Diagnostics.Module_0_cannot_be_imported_using_this_construct_The_specifier_only_resolves_to_an_ES_module_which_cannot_be_imported_synchronously_Use_dynamic_import_instead, moduleReference); } } // merged symbol is module declaration symbol combined with all augmentations @@ -3543,13 +3460,13 @@ namespace ts { } if (moduleNotFoundError) { // report errors only if it was requested - error(errorNode, Diagnostics.File_0_is_not_a_module, sourceFile.fileName); + error(errorNode, ts.Diagnostics.File_0_is_not_a_module, sourceFile.fileName); } return undefined; } if (patternAmbientModules) { - const pattern = findBestPatternMatch(patternAmbientModules, _ => _.pattern, moduleReference); + const pattern = ts.findBestPatternMatch(patternAmbientModules, _ => _.pattern, moduleReference); if (pattern) { // If the module reference matched a pattern ambient module ('*.foo') but there's also a // module augmentation by the specific name requested ('a.foo'), we store the merged symbol @@ -3564,9 +3481,9 @@ namespace ts { } // May be an untyped module. If so, ignore resolutionDiagnostic. - if (resolvedModule && !resolutionExtensionIsTSOrJson(resolvedModule.extension) && resolutionDiagnostic === undefined || resolutionDiagnostic === Diagnostics.Could_not_find_a_declaration_file_for_module_0_1_implicitly_has_an_any_type) { + if (resolvedModule && !ts.resolutionExtensionIsTSOrJson(resolvedModule.extension) && resolutionDiagnostic === undefined || resolutionDiagnostic === ts.Diagnostics.Could_not_find_a_declaration_file_for_module_0_1_implicitly_has_an_any_type) { if (isForAugmentation) { - const diag = Diagnostics.Invalid_module_name_in_augmentation_Module_0_resolves_to_an_untyped_module_at_1_which_cannot_be_augmented; + const diag = ts.Diagnostics.Invalid_module_name_in_augmentation_Module_0_resolves_to_an_untyped_module_at_1_which_cannot_be_augmented; error(errorNode, diag, moduleReference, resolvedModule!.resolvedFileName); } else { @@ -3581,7 +3498,7 @@ namespace ts { if (resolvedModule) { const redirect = host.getProjectReferenceRedirect(resolvedModule.resolvedFileName); if (redirect) { - error(errorNode, Diagnostics.Output_file_0_has_not_been_built_from_source_file_1, redirect, resolvedModule.resolvedFileName); + error(errorNode, ts.Diagnostics.Output_file_0_has_not_been_built_from_source_file_1, redirect, resolvedModule.resolvedFileName); return undefined; } } @@ -3590,40 +3507,38 @@ namespace ts { error(errorNode, resolutionDiagnostic, moduleReference, resolvedModule.resolvedFileName); } else { - const tsExtension = tryExtractTSExtension(moduleReference); - const isExtensionlessRelativePathImport = pathIsRelative(moduleReference) && !hasExtension(moduleReference); - const moduleResolutionKind = getEmitModuleResolutionKind(compilerOptions); - const resolutionIsNode16OrNext = moduleResolutionKind === ModuleResolutionKind.Node16 || - moduleResolutionKind === ModuleResolutionKind.NodeNext; + const tsExtension = ts.tryExtractTSExtension(moduleReference); + const isExtensionlessRelativePathImport = ts.pathIsRelative(moduleReference) && !ts.hasExtension(moduleReference); + const moduleResolutionKind = ts.getEmitModuleResolutionKind(compilerOptions); + const resolutionIsNode16OrNext = moduleResolutionKind === ts.ModuleResolutionKind.Node16 || + moduleResolutionKind === ts.ModuleResolutionKind.NodeNext; if (tsExtension) { - const diag = Diagnostics.An_import_path_cannot_end_with_a_0_extension_Consider_importing_1_instead; - const importSourceWithoutExtension = removeExtension(moduleReference, tsExtension); + const diag = ts.Diagnostics.An_import_path_cannot_end_with_a_0_extension_Consider_importing_1_instead; + const importSourceWithoutExtension = ts.removeExtension(moduleReference, tsExtension); let replacedImportSource = importSourceWithoutExtension; /** * Direct users to import source with .js extension if outputting an ES module. * @see https://github.com/microsoft/TypeScript/issues/42151 */ - if (moduleKind >= ModuleKind.ES2015) { - replacedImportSource += tsExtension === Extension.Mts ? ".mjs" : tsExtension === Extension.Cts ? ".cjs" : ".js"; + if (moduleKind >= ts.ModuleKind.ES2015) { + replacedImportSource += tsExtension === ts.Extension.Mts ? ".mjs" : tsExtension === ts.Extension.Cts ? ".cjs" : ".js"; } error(errorNode, diag, tsExtension, replacedImportSource); } else if (!compilerOptions.resolveJsonModule && - fileExtensionIs(moduleReference, Extension.Json) && - getEmitModuleResolutionKind(compilerOptions) !== ModuleResolutionKind.Classic && - hasJsonModuleEmitEnabled(compilerOptions)) { - error(errorNode, Diagnostics.Cannot_find_module_0_Consider_using_resolveJsonModule_to_import_module_with_json_extension, moduleReference); + ts.fileExtensionIs(moduleReference, ts.Extension.Json) && + ts.getEmitModuleResolutionKind(compilerOptions) !== ts.ModuleResolutionKind.Classic && + ts.hasJsonModuleEmitEnabled(compilerOptions)) { + error(errorNode, ts.Diagnostics.Cannot_find_module_0_Consider_using_resolveJsonModule_to_import_module_with_json_extension, moduleReference); } - else if (mode === ModuleKind.ESNext && resolutionIsNode16OrNext && isExtensionlessRelativePathImport) { - const absoluteRef = getNormalizedAbsolutePath(moduleReference, getDirectoryPath(currentSourceFile.path)); + else if (mode === ts.ModuleKind.ESNext && resolutionIsNode16OrNext && isExtensionlessRelativePathImport) { + const absoluteRef = ts.getNormalizedAbsolutePath(moduleReference, ts.getDirectoryPath(currentSourceFile.path)); const suggestedExt = suggestedExtensions.find(([actualExt, _importExt]) => host.fileExists(absoluteRef + actualExt))?.[1]; if (suggestedExt) { - error(errorNode, - Diagnostics.Relative_import_paths_need_explicit_file_extensions_in_EcmaScript_imports_when_moduleResolution_is_node16_or_nodenext_Did_you_mean_0, - moduleReference + suggestedExt); + error(errorNode, ts.Diagnostics.Relative_import_paths_need_explicit_file_extensions_in_EcmaScript_imports_when_moduleResolution_is_node16_or_nodenext_Did_you_mean_0, moduleReference + suggestedExt); } else { - error(errorNode, Diagnostics.Relative_import_paths_need_explicit_file_extensions_in_EcmaScript_imports_when_moduleResolution_is_node16_or_nodenext_Consider_adding_an_extension_to_the_import_path); + error(errorNode, ts.Diagnostics.Relative_import_paths_need_explicit_file_extensions_in_EcmaScript_imports_when_moduleResolution_is_node16_or_nodenext_Consider_adding_an_extension_to_the_import_path); } } else { @@ -3634,64 +3549,53 @@ namespace ts { return undefined; } - function errorOnImplicitAnyModule(isError: boolean, errorNode: Node, { packageId, resolvedFileName }: ResolvedModuleFull, moduleReference: string): void { - const errorInfo = !isExternalModuleNameRelative(moduleReference) && packageId + function errorOnImplicitAnyModule(isError: boolean, errorNode: ts.Node, { packageId, resolvedFileName }: ts.ResolvedModuleFull, moduleReference: string): void { + const errorInfo = !ts.isExternalModuleNameRelative(moduleReference) && packageId ? typesPackageExists(packageId.name) - ? chainDiagnosticMessages( - /*details*/ undefined, - Diagnostics.If_the_0_package_actually_exposes_this_module_consider_sending_a_pull_request_to_amend_https_Colon_Slash_Slashgithub_com_SlashDefinitelyTyped_SlashDefinitelyTyped_Slashtree_Slashmaster_Slashtypes_Slash_1, - packageId.name, mangleScopedPackageName(packageId.name)) + ? ts.chainDiagnosticMessages( + /*details*/ undefined, ts.Diagnostics.If_the_0_package_actually_exposes_this_module_consider_sending_a_pull_request_to_amend_https_Colon_Slash_Slashgithub_com_SlashDefinitelyTyped_SlashDefinitelyTyped_Slashtree_Slashmaster_Slashtypes_Slash_1, packageId.name, ts.mangleScopedPackageName(packageId.name)) : packageBundlesTypes(packageId.name) - ? chainDiagnosticMessages( - /*details*/ undefined, - Diagnostics.If_the_0_package_actually_exposes_this_module_try_adding_a_new_declaration_d_ts_file_containing_declare_module_1, - packageId.name, - moduleReference) - : chainDiagnosticMessages( - /*details*/ undefined, - Diagnostics.Try_npm_i_save_dev_types_Slash_1_if_it_exists_or_add_a_new_declaration_d_ts_file_containing_declare_module_0, - moduleReference, - mangleScopedPackageName(packageId.name)) + ? ts.chainDiagnosticMessages( + /*details*/ undefined, ts.Diagnostics.If_the_0_package_actually_exposes_this_module_try_adding_a_new_declaration_d_ts_file_containing_declare_module_1, packageId.name, moduleReference) + : ts.chainDiagnosticMessages( + /*details*/ undefined, ts.Diagnostics.Try_npm_i_save_dev_types_Slash_1_if_it_exists_or_add_a_new_declaration_d_ts_file_containing_declare_module_0, moduleReference, ts.mangleScopedPackageName(packageId.name)) : undefined; - errorOrSuggestion(isError, errorNode, chainDiagnosticMessages( - errorInfo, - Diagnostics.Could_not_find_a_declaration_file_for_module_0_1_implicitly_has_an_any_type, - moduleReference, - resolvedFileName)); + errorOrSuggestion(isError, errorNode, ts.chainDiagnosticMessages(errorInfo, ts.Diagnostics.Could_not_find_a_declaration_file_for_module_0_1_implicitly_has_an_any_type, moduleReference, resolvedFileName)); } function typesPackageExists(packageName: string): boolean { - return getPackagesMap().has(getTypesPackageName(packageName)); + return getPackagesMap().has(ts.getTypesPackageName(packageName)); } function packageBundlesTypes(packageName: string): boolean { return !!getPackagesMap().get(packageName); } - function resolveExternalModuleSymbol(moduleSymbol: Symbol, dontResolveAlias?: boolean): Symbol; - function resolveExternalModuleSymbol(moduleSymbol: Symbol | undefined, dontResolveAlias?: boolean): Symbol | undefined; - function resolveExternalModuleSymbol(moduleSymbol: Symbol, dontResolveAlias?: boolean): Symbol | undefined { + function resolveExternalModuleSymbol(moduleSymbol: ts.Symbol, dontResolveAlias?: boolean): ts.Symbol; + function resolveExternalModuleSymbol(moduleSymbol: ts.Symbol | undefined, dontResolveAlias?: boolean): ts.Symbol | undefined; + function resolveExternalModuleSymbol(moduleSymbol: ts.Symbol, dontResolveAlias?: boolean): ts.Symbol | undefined { if (moduleSymbol?.exports) { - const exportEquals = resolveSymbol(moduleSymbol.exports.get(InternalSymbolName.ExportEquals), dontResolveAlias); + const exportEquals = resolveSymbol(moduleSymbol.exports.get(ts.InternalSymbolName.ExportEquals), dontResolveAlias); const exported = getCommonJsExportEquals(getMergedSymbol(exportEquals), getMergedSymbol(moduleSymbol)); return getMergedSymbol(exported) || moduleSymbol; } return undefined; } - function getCommonJsExportEquals(exported: Symbol | undefined, moduleSymbol: Symbol): Symbol | undefined { - if (!exported || exported === unknownSymbol || exported === moduleSymbol || moduleSymbol.exports!.size === 1 || exported.flags & SymbolFlags.Alias) { + function getCommonJsExportEquals(exported: ts.Symbol | undefined, moduleSymbol: ts.Symbol): ts.Symbol | undefined { + if (!exported || exported === unknownSymbol || exported === moduleSymbol || moduleSymbol.exports!.size === 1 || exported.flags & ts.SymbolFlags.Alias) { return exported; } const links = getSymbolLinks(exported); if (links.cjsExportMerged) { return links.cjsExportMerged; } - const merged = exported.flags & SymbolFlags.Transient ? exported : cloneSymbol(exported); - merged.flags = merged.flags | SymbolFlags.ValueModule; + const merged = exported.flags & ts.SymbolFlags.Transient ? exported : cloneSymbol(exported); + merged.flags = merged.flags | ts.SymbolFlags.ValueModule; if (merged.exports === undefined) { - merged.exports = createSymbolTable(); + merged.exports = ts.createSymbolTable(); } moduleSymbol.exports!.forEach((s, name) => { - if (name === InternalSymbolName.ExportEquals) return; + if (name === ts.InternalSymbolName.ExportEquals) + return; merged.exports!.set(name, merged.exports!.has(name) ? mergeSymbol(merged.exports!.get(name)!, s) : s); }); getSymbolLinks(merged).cjsExportMerged = merged; @@ -3701,44 +3605,40 @@ namespace ts { // An external module with an 'export =' declaration may be referenced as an ES6 module provided the 'export =' // references a symbol that is at least declared as a module or a variable. The target of the 'export =' may // combine other declarations with the module or variable (e.g. a class/module, function/module, interface/variable). - function resolveESModuleSymbol(moduleSymbol: Symbol | undefined, referencingLocation: Node, dontResolveAlias: boolean, suppressInteropError: boolean): Symbol | undefined { + function resolveESModuleSymbol(moduleSymbol: ts.Symbol | undefined, referencingLocation: ts.Node, dontResolveAlias: boolean, suppressInteropError: boolean): ts.Symbol | undefined { const symbol = resolveExternalModuleSymbol(moduleSymbol, dontResolveAlias); if (!dontResolveAlias && symbol) { - if (!suppressInteropError && !(symbol.flags & (SymbolFlags.Module | SymbolFlags.Variable)) && !getDeclarationOfKind(symbol, SyntaxKind.SourceFile)) { - const compilerOptionName = moduleKind >= ModuleKind.ES2015 + if (!suppressInteropError && !(symbol.flags & (ts.SymbolFlags.Module | ts.SymbolFlags.Variable)) && !ts.getDeclarationOfKind(symbol, ts.SyntaxKind.SourceFile)) { + const compilerOptionName = moduleKind >= ts.ModuleKind.ES2015 ? "allowSyntheticDefaultImports" : "esModuleInterop"; - error(referencingLocation, Diagnostics.This_module_can_only_be_referenced_with_ECMAScript_imports_Slashexports_by_turning_on_the_0_flag_and_referencing_its_default_export, compilerOptionName); + error(referencingLocation, ts.Diagnostics.This_module_can_only_be_referenced_with_ECMAScript_imports_Slashexports_by_turning_on_the_0_flag_and_referencing_its_default_export, compilerOptionName); return symbol; } const referenceParent = referencingLocation.parent; - if ( - (isImportDeclaration(referenceParent) && getNamespaceDeclarationNode(referenceParent)) || - isImportCall(referenceParent) - ) { - const reference = isImportCall(referenceParent) ? referenceParent.arguments[0] : referenceParent.moduleSpecifier; + if ((ts.isImportDeclaration(referenceParent) && ts.getNamespaceDeclarationNode(referenceParent)) || + ts.isImportCall(referenceParent)) { + const reference = ts.isImportCall(referenceParent) ? referenceParent.arguments[0] : referenceParent.moduleSpecifier; const type = getTypeOfSymbol(symbol); const defaultOnlyType = getTypeWithSyntheticDefaultOnly(type, symbol, moduleSymbol!, reference); if (defaultOnlyType) { return cloneTypeAsModuleType(symbol, defaultOnlyType, referenceParent); } - const targetFile = moduleSymbol?.declarations?.find(isSourceFile); + const targetFile = moduleSymbol?.declarations?.find(ts.isSourceFile); const isEsmCjsRef = targetFile && isESMFormatImportImportingCommonjsFormatFile(getUsageModeForExpression(reference), targetFile.impliedNodeFormat); - if (getESModuleInterop(compilerOptions) || isEsmCjsRef) { - let sigs = getSignaturesOfStructuredType(type, SignatureKind.Call); + if (ts.getESModuleInterop(compilerOptions) || isEsmCjsRef) { + let sigs = getSignaturesOfStructuredType(type, ts.SignatureKind.Call); if (!sigs || !sigs.length) { - sigs = getSignaturesOfStructuredType(type, SignatureKind.Construct); + sigs = getSignaturesOfStructuredType(type, ts.SignatureKind.Construct); } - if ( - (sigs && sigs.length) || - getPropertyOfType(type, InternalSymbolName.Default, /*skipObjectFunctionPropertyAugment*/ true) || - isEsmCjsRef - ) { + if ((sigs && sigs.length) || + getPropertyOfType(type, ts.InternalSymbolName.Default, /*skipObjectFunctionPropertyAugment*/ true) || + isEsmCjsRef) { const moduleType = getTypeWithSyntheticDefaultImportType(type, symbol, moduleSymbol!, reference); return cloneTypeAsModuleType(symbol, moduleType, referenceParent); } @@ -3751,42 +3651,46 @@ namespace ts { /** * Create a new symbol which has the module's type less the call and construct signatures */ - function cloneTypeAsModuleType(symbol: Symbol, moduleType: Type, referenceParent: ImportDeclaration | ImportCall) { + function cloneTypeAsModuleType(symbol: ts.Symbol, moduleType: ts.Type, referenceParent: ts.ImportDeclaration | ts.ImportCall) { const result = createSymbol(symbol.flags, symbol.escapedName); result.declarations = symbol.declarations ? symbol.declarations.slice() : []; result.parent = symbol.parent; result.target = symbol; result.originatingImport = referenceParent; - if (symbol.valueDeclaration) result.valueDeclaration = symbol.valueDeclaration; - if (symbol.constEnumOnlyModule) result.constEnumOnlyModule = true; - if (symbol.members) result.members = new Map(symbol.members); - if (symbol.exports) result.exports = new Map(symbol.exports); - const resolvedModuleType = resolveStructuredTypeMembers(moduleType as StructuredType); // Should already be resolved from the signature checks above - result.type = createAnonymousType(result, resolvedModuleType.members, emptyArray, emptyArray, resolvedModuleType.indexInfos); + if (symbol.valueDeclaration) + result.valueDeclaration = symbol.valueDeclaration; + if (symbol.constEnumOnlyModule) + result.constEnumOnlyModule = true; + if (symbol.members) + result.members = new ts.Map(symbol.members); + if (symbol.exports) + result.exports = new ts.Map(symbol.exports); + const resolvedModuleType = resolveStructuredTypeMembers(moduleType as ts.StructuredType); // Should already be resolved from the signature checks above + result.type = createAnonymousType(result, resolvedModuleType.members, ts.emptyArray, ts.emptyArray, resolvedModuleType.indexInfos); return result; } - function hasExportAssignmentSymbol(moduleSymbol: Symbol): boolean { - return moduleSymbol.exports!.get(InternalSymbolName.ExportEquals) !== undefined; + function hasExportAssignmentSymbol(moduleSymbol: ts.Symbol): boolean { + return moduleSymbol.exports!.get(ts.InternalSymbolName.ExportEquals) !== undefined; } - function getExportsOfModuleAsArray(moduleSymbol: Symbol): Symbol[] { + function getExportsOfModuleAsArray(moduleSymbol: ts.Symbol): ts.Symbol[] { return symbolsToArray(getExportsOfModule(moduleSymbol)); } - function getExportsAndPropertiesOfModule(moduleSymbol: Symbol): Symbol[] { + function getExportsAndPropertiesOfModule(moduleSymbol: ts.Symbol): ts.Symbol[] { const exports = getExportsOfModuleAsArray(moduleSymbol); const exportEquals = resolveExternalModuleSymbol(moduleSymbol); if (exportEquals !== moduleSymbol) { const type = getTypeOfSymbol(exportEquals); if (shouldTreatPropertiesOfExternalModuleAsExports(type)) { - addRange(exports, getPropertiesOfType(type)); + ts.addRange(exports, getPropertiesOfType(type)); } } return exports; } - function forEachExportAndPropertyOfModule(moduleSymbol: Symbol, cb: (symbol: Symbol, key: __String) => void): void { + function forEachExportAndPropertyOfModule(moduleSymbol: ts.Symbol, cb: (symbol: ts.Symbol, key: ts.__String) => void): void { const exports = getExportsOfModule(moduleSymbol); exports.forEach((symbol, key) => { if (!isReservedMemberName(key)) { @@ -3804,14 +3708,14 @@ namespace ts { } } - function tryGetMemberInModuleExports(memberName: __String, moduleSymbol: Symbol): Symbol | undefined { + function tryGetMemberInModuleExports(memberName: ts.__String, moduleSymbol: ts.Symbol): ts.Symbol | undefined { const symbolTable = getExportsOfModule(moduleSymbol); if (symbolTable) { return symbolTable.get(memberName); } } - function tryGetMemberInModuleExportsAndProperties(memberName: __String, moduleSymbol: Symbol): Symbol | undefined { + function tryGetMemberInModuleExportsAndProperties(memberName: ts.__String, moduleSymbol: ts.Symbol): ts.Symbol | undefined { const symbol = tryGetMemberInModuleExports(memberName, moduleSymbol); if (symbol) { return symbol; @@ -3826,47 +3730,49 @@ namespace ts { return shouldTreatPropertiesOfExternalModuleAsExports(type) ? getPropertyOfType(type, memberName) : undefined; } - function shouldTreatPropertiesOfExternalModuleAsExports(resolvedExternalModuleType: Type) { - return !(resolvedExternalModuleType.flags & TypeFlags.Primitive || - getObjectFlags(resolvedExternalModuleType) & ObjectFlags.Class || + function shouldTreatPropertiesOfExternalModuleAsExports(resolvedExternalModuleType: ts.Type) { + return !(resolvedExternalModuleType.flags & ts.TypeFlags.Primitive || + ts.getObjectFlags(resolvedExternalModuleType) & ts.ObjectFlags.Class || // `isArrayOrTupleLikeType` is too expensive to use in this auto-imports hot path isArrayType(resolvedExternalModuleType) || isTupleType(resolvedExternalModuleType)); } - function getExportsOfSymbol(symbol: Symbol): SymbolTable { - return symbol.flags & SymbolFlags.LateBindingContainer ? getResolvedMembersOrExportsOfSymbol(symbol, MembersOrExportsResolutionKind.resolvedExports) : - symbol.flags & SymbolFlags.Module ? getExportsOfModule(symbol) : + function getExportsOfSymbol(symbol: ts.Symbol): ts.SymbolTable { + return symbol.flags & ts.SymbolFlags.LateBindingContainer ? getResolvedMembersOrExportsOfSymbol(symbol, MembersOrExportsResolutionKind.resolvedExports) : + symbol.flags & ts.SymbolFlags.Module ? getExportsOfModule(symbol) : symbol.exports || emptySymbols; } - function getExportsOfModule(moduleSymbol: Symbol): SymbolTable { + function getExportsOfModule(moduleSymbol: ts.Symbol): ts.SymbolTable { const links = getSymbolLinks(moduleSymbol); return links.resolvedExports || (links.resolvedExports = getExportsOfModuleWorker(moduleSymbol)); } interface ExportCollisionTracker { specifierText: string; - exportsWithDuplicate: ExportDeclaration[]; + exportsWithDuplicate: ts.ExportDeclaration[]; } - type ExportCollisionTrackerTable = UnderscoreEscapedMap; + type ExportCollisionTrackerTable = ts.UnderscoreEscapedMap; /** * Extends one symbol table with another while collecting information on name collisions for error message generation into the `lookupTable` argument * Not passing `lookupTable` and `exportNode` disables this collection, and just extends the tables */ - function extendExportSymbols(target: SymbolTable, source: SymbolTable | undefined, lookupTable?: ExportCollisionTrackerTable, exportNode?: ExportDeclaration) { - if (!source) return; + function extendExportSymbols(target: ts.SymbolTable, source: ts.SymbolTable | undefined, lookupTable?: ExportCollisionTrackerTable, exportNode?: ts.ExportDeclaration) { + if (!source) + return; source.forEach((sourceSymbol, id) => { - if (id === InternalSymbolName.Default) return; + if (id === ts.InternalSymbolName.Default) + return; const targetSymbol = target.get(id); if (!targetSymbol) { target.set(id, sourceSymbol); if (lookupTable && exportNode) { lookupTable.set(id, { - specifierText: getTextOfNode(exportNode.moduleSpecifier!) + specifierText: ts.getTextOfNode(exportNode.moduleSpecifier!) } as ExportCollisionTracker); } } @@ -3882,8 +3788,8 @@ namespace ts { }); } - function getExportsOfModuleWorker(moduleSymbol: Symbol): SymbolTable { - const visitedSymbols: Symbol[] = []; + function getExportsOfModuleWorker(moduleSymbol: ts.Symbol): ts.SymbolTable { + const visitedSymbols: ts.Symbol[] = []; // A module defined by an 'export=' consists of one export that needs to be resolved moduleSymbol = resolveExternalModuleSymbol(moduleSymbol); @@ -3892,26 +3798,21 @@ namespace ts { // The ES6 spec permits export * declarations in a module to circularly reference the module itself. For example, // module 'a' can 'export * from "b"' and 'b' can 'export * from "a"' without error. - function visit(symbol: Symbol | undefined): SymbolTable | undefined { - if (!(symbol && symbol.exports && pushIfUnique(visitedSymbols, symbol))) { + function visit(symbol: ts.Symbol | undefined): ts.SymbolTable | undefined { + if (!(symbol && symbol.exports && ts.pushIfUnique(visitedSymbols, symbol))) { return; } - const symbols = new Map(symbol.exports); + const symbols = new ts.Map(symbol.exports); // All export * declarations are collected in an __export symbol by the binder - const exportStars = symbol.exports.get(InternalSymbolName.ExportStar); + const exportStars = symbol.exports.get(ts.InternalSymbolName.ExportStar); if (exportStars) { - const nestedSymbols = createSymbolTable(); - const lookupTable: ExportCollisionTrackerTable = new Map(); + const nestedSymbols = ts.createSymbolTable(); + const lookupTable: ExportCollisionTrackerTable = new ts.Map(); if (exportStars.declarations) { for (const node of exportStars.declarations) { - const resolvedModule = resolveExternalModuleName(node, (node as ExportDeclaration).moduleSpecifier!); + const resolvedModule = resolveExternalModuleName(node, (node as ts.ExportDeclaration).moduleSpecifier!); const exportedSymbols = visit(resolvedModule); - extendExportSymbols( - nestedSymbols, - exportedSymbols, - lookupTable, - node as ExportDeclaration - ); + extendExportSymbols(nestedSymbols, exportedSymbols, lookupTable, node as ts.ExportDeclaration); } } lookupTable.forEach(({ exportsWithDuplicate }, id) => { @@ -3920,12 +3821,7 @@ namespace ts { return; } for (const node of exportsWithDuplicate) { - diagnostics.add(createDiagnosticForNode( - node, - Diagnostics.Module_0_has_already_exported_a_member_named_1_Consider_explicitly_re_exporting_to_resolve_the_ambiguity, - lookupTable.get(id)!.specifierText, - unescapeLeadingUnderscores(id) - )); + diagnostics.add(ts.createDiagnosticForNode(node, ts.Diagnostics.Module_0_has_already_exported_a_member_named_1_Consider_explicitly_re_exporting_to_resolve_the_ambiguity, lookupTable.get(id)!.specifierText, ts.unescapeLeadingUnderscores(id))); } }); extendExportSymbols(symbols, nestedSymbols); @@ -3934,43 +3830,46 @@ namespace ts { } } - function getMergedSymbol(symbol: Symbol): Symbol; - function getMergedSymbol(symbol: Symbol | undefined): Symbol | undefined; - function getMergedSymbol(symbol: Symbol | undefined): Symbol | undefined { - let merged: Symbol; + function getMergedSymbol(symbol: ts.Symbol): ts.Symbol; + function getMergedSymbol(symbol: ts.Symbol | undefined): ts.Symbol | undefined; + function getMergedSymbol(symbol: ts.Symbol | undefined): ts.Symbol | undefined { + let merged: ts.Symbol; return symbol && symbol.mergeId && (merged = mergedSymbols[symbol.mergeId]) ? merged : symbol; } - function getSymbolOfNode(node: Declaration): Symbol; - function getSymbolOfNode(node: Node): Symbol | undefined; - function getSymbolOfNode(node: Node): Symbol | undefined { + function getSymbolOfNode(node: ts.Declaration): ts.Symbol; + function getSymbolOfNode(node: ts.Node): ts.Symbol | undefined; + function getSymbolOfNode(node: ts.Node): ts.Symbol | undefined { return getMergedSymbol(node.symbol && getLateBoundSymbol(node.symbol)); } - function getParentOfSymbol(symbol: Symbol): Symbol | undefined { + function getParentOfSymbol(symbol: ts.Symbol): ts.Symbol | undefined { return getMergedSymbol(symbol.parent && getLateBoundSymbol(symbol.parent)); } - function getAlternativeContainingModules(symbol: Symbol, enclosingDeclaration: Node): Symbol[] { - const containingFile = getSourceFileOfNode(enclosingDeclaration); + function getAlternativeContainingModules(symbol: ts.Symbol, enclosingDeclaration: ts.Node): ts.Symbol[] { + const containingFile = ts.getSourceFileOfNode(enclosingDeclaration); const id = getNodeId(containingFile); const links = getSymbolLinks(symbol); - let results: Symbol[] | undefined; + let results: ts.Symbol[] | undefined; if (links.extendedContainersByFile && (results = links.extendedContainersByFile.get(id))) { return results; } if (containingFile && containingFile.imports) { // Try to make an import using an import already in the enclosing file, if possible for (const importRef of containingFile.imports) { - if (nodeIsSynthesized(importRef)) continue; // Synthetic names can't be resolved by `resolveExternalModuleName` - they'll cause a debug assert if they error + if (ts.nodeIsSynthesized(importRef)) + continue; // Synthetic names can't be resolved by `resolveExternalModuleName` - they'll cause a debug assert if they error const resolvedModule = resolveExternalModuleName(enclosingDeclaration, importRef, /*ignoreErrors*/ true); - if (!resolvedModule) continue; + if (!resolvedModule) + continue; const ref = getAliasForSymbolInContainer(resolvedModule, symbol); - if (!ref) continue; - results = append(results, resolvedModule); + if (!ref) + continue; + results = ts.append(results, resolvedModule); } - if (length(results)) { - (links.extendedContainersByFile || (links.extendedContainersByFile = new Map())).set(id, results!); + if (ts.length(results)) { + (links.extendedContainersByFile || (links.extendedContainersByFile = new ts.Map())).set(id, results!); return results!; } } @@ -3980,106 +3879,105 @@ namespace ts { // No results from files already being imported by this file - expand search (expensive, but not location-specific, so cached) const otherFiles = host.getSourceFiles(); for (const file of otherFiles) { - if (!isExternalModule(file)) continue; + if (!ts.isExternalModule(file)) + continue; const sym = getSymbolOfNode(file); const ref = getAliasForSymbolInContainer(sym, symbol); - if (!ref) continue; - results = append(results, sym); + if (!ref) + continue; + results = ts.append(results, sym); } - return links.extendedContainers = results || emptyArray; + return links.extendedContainers = results || ts.emptyArray; } /** * Attempts to find the symbol corresponding to the container a symbol is in - usually this * is just its' `.parent`, but for locals, this value is `undefined` */ - function getContainersOfSymbol(symbol: Symbol, enclosingDeclaration: Node | undefined, meaning: SymbolFlags): Symbol[] | undefined { + function getContainersOfSymbol(symbol: ts.Symbol, enclosingDeclaration: ts.Node | undefined, meaning: ts.SymbolFlags): ts.Symbol[] | undefined { const container = getParentOfSymbol(symbol); // Type parameters end up in the `members` lists but are not externally visible - if (container && !(symbol.flags & SymbolFlags.TypeParameter)) { - const additionalContainers = mapDefined(container.declarations, fileSymbolIfFileSymbolExportEqualsContainer); + if (container && !(symbol.flags & ts.SymbolFlags.TypeParameter)) { + const additionalContainers = ts.mapDefined(container.declarations, fileSymbolIfFileSymbolExportEqualsContainer); const reexportContainers = enclosingDeclaration && getAlternativeContainingModules(symbol, enclosingDeclaration); const objectLiteralContainer = getVariableDeclarationOfObjectLiteral(container, meaning); - if ( - enclosingDeclaration && + if (enclosingDeclaration && container.flags & getQualifiedLeftMeaning(meaning) && - getAccessibleSymbolChain(container, enclosingDeclaration, SymbolFlags.Namespace, /*externalOnly*/ false) - ) { - return append(concatenate(concatenate([container], additionalContainers), reexportContainers), objectLiteralContainer); // This order expresses a preference for the real container if it is in scope + getAccessibleSymbolChain(container, enclosingDeclaration, ts.SymbolFlags.Namespace, /*externalOnly*/ false)) { + return ts.append(ts.concatenate(ts.concatenate([container], additionalContainers), reexportContainers), objectLiteralContainer); // This order expresses a preference for the real container if it is in scope } // we potentially have a symbol which is a member of the instance side of something - look for a variable in scope with the container's type // which may be acting like a namespace (eg, `Symbol` acts like a namespace when looking up `Symbol.toStringTag`) const firstVariableMatch = !(container.flags & getQualifiedLeftMeaning(meaning)) - && container.flags & SymbolFlags.Type - && getDeclaredTypeOfSymbol(container).flags & TypeFlags.Object - && meaning === SymbolFlags.Value + && container.flags & ts.SymbolFlags.Type + && getDeclaredTypeOfSymbol(container).flags & ts.TypeFlags.Object + && meaning === ts.SymbolFlags.Value ? forEachSymbolTableInScope(enclosingDeclaration, t => { - return forEachEntry(t, s => { + return ts.forEachEntry(t, s => { if (s.flags & getQualifiedLeftMeaning(meaning) && getTypeOfSymbol(s) === getDeclaredTypeOfSymbol(container)) { return s; } }); }) : undefined; let res = firstVariableMatch ? [firstVariableMatch, ...additionalContainers, container] : [...additionalContainers, container]; - res = append(res, objectLiteralContainer); - res = addRange(res, reexportContainers); + res = ts.append(res, objectLiteralContainer); + res = ts.addRange(res, reexportContainers); return res; } - const candidates = mapDefined(symbol.declarations, d => { - if (!isAmbientModule(d) && d.parent){ + const candidates = ts.mapDefined(symbol.declarations, d => { + if (!ts.isAmbientModule(d) && d.parent) { // direct children of a module if (hasNonGlobalAugmentationExternalModuleSymbol(d.parent)) { return getSymbolOfNode(d.parent); } // export ='d member of an ambient module - if (isModuleBlock(d.parent) && d.parent.parent && resolveExternalModuleSymbol(getSymbolOfNode(d.parent.parent)) === symbol) { + if (ts.isModuleBlock(d.parent) && d.parent.parent && resolveExternalModuleSymbol(getSymbolOfNode(d.parent.parent)) === symbol) { return getSymbolOfNode(d.parent.parent); } } - if (isClassExpression(d) && isBinaryExpression(d.parent) && d.parent.operatorToken.kind === SyntaxKind.EqualsToken && isAccessExpression(d.parent.left) && isEntityNameExpression(d.parent.left.expression)) { - if (isModuleExportsAccessExpression(d.parent.left) || isExportsIdentifier(d.parent.left.expression)) { - return getSymbolOfNode(getSourceFileOfNode(d)); + if (ts.isClassExpression(d) && ts.isBinaryExpression(d.parent) && d.parent.operatorToken.kind === ts.SyntaxKind.EqualsToken && ts.isAccessExpression(d.parent.left) && ts.isEntityNameExpression(d.parent.left.expression)) { + if (ts.isModuleExportsAccessExpression(d.parent.left) || ts.isExportsIdentifier(d.parent.left.expression)) { + return getSymbolOfNode(ts.getSourceFileOfNode(d)); } checkExpressionCached(d.parent.left.expression); return getNodeLinks(d.parent.left.expression).resolvedSymbol; } }); - if (!length(candidates)) { + if (!ts.length(candidates)) { return undefined; } - return mapDefined(candidates, candidate => getAliasForSymbolInContainer(candidate, symbol) ? candidate : undefined); - - function fileSymbolIfFileSymbolExportEqualsContainer(d: Declaration) { + return ts.mapDefined(candidates, candidate => getAliasForSymbolInContainer(candidate, symbol) ? candidate : undefined); + function fileSymbolIfFileSymbolExportEqualsContainer(d: ts.Declaration) { return container && getFileSymbolIfFileSymbolExportEqualsContainer(d, container); } } - function getVariableDeclarationOfObjectLiteral(symbol: Symbol, meaning: SymbolFlags) { + function getVariableDeclarationOfObjectLiteral(symbol: ts.Symbol, meaning: ts.SymbolFlags) { // If we're trying to reference some object literal in, eg `var a = { x: 1 }`, the symbol for the literal, `__object`, is distinct // from the symbol of the declaration it is being assigned to. Since we can use the declaration to refer to the literal, however, // we'd like to make that connection here - potentially causing us to paint the declaration's visibility, and therefore the literal. - const firstDecl: Node | false = !!length(symbol.declarations) && first(symbol.declarations!); - if (meaning & SymbolFlags.Value && firstDecl && firstDecl.parent && isVariableDeclaration(firstDecl.parent)) { - if (isObjectLiteralExpression(firstDecl) && firstDecl === firstDecl.parent.initializer || isTypeLiteralNode(firstDecl) && firstDecl === firstDecl.parent.type) { + const firstDecl: ts.Node | false = !!ts.length(symbol.declarations) && ts.first(symbol.declarations!); + if (meaning & ts.SymbolFlags.Value && firstDecl && firstDecl.parent && ts.isVariableDeclaration(firstDecl.parent)) { + if (ts.isObjectLiteralExpression(firstDecl) && firstDecl === firstDecl.parent.initializer || ts.isTypeLiteralNode(firstDecl) && firstDecl === firstDecl.parent.type) { return getSymbolOfNode(firstDecl.parent); } } } - function getFileSymbolIfFileSymbolExportEqualsContainer(d: Declaration, container: Symbol) { + function getFileSymbolIfFileSymbolExportEqualsContainer(d: ts.Declaration, container: ts.Symbol) { const fileSymbol = getExternalModuleContainer(d); - const exported = fileSymbol && fileSymbol.exports && fileSymbol.exports.get(InternalSymbolName.ExportEquals); + const exported = fileSymbol && fileSymbol.exports && fileSymbol.exports.get(ts.InternalSymbolName.ExportEquals); return exported && getSymbolIfSameReference(exported, container) ? fileSymbol : undefined; } - function getAliasForSymbolInContainer(container: Symbol, symbol: Symbol) { + function getAliasForSymbolInContainer(container: ts.Symbol, symbol: ts.Symbol) { if (container === getParentOfSymbol(symbol)) { // fast path, `symbol` is either already the alias or isn't aliased return symbol; } // Check if container is a thing with an `export=` which points directly at `symbol`, and if so, return // the container itself as the alias for the symbol - const exportEquals = container.exports && container.exports.get(InternalSymbolName.ExportEquals); + const exportEquals = container.exports && container.exports.get(ts.InternalSymbolName.ExportEquals); if (exportEquals && getSymbolIfSameReference(exportEquals, symbol)) { return container; } @@ -4088,7 +3986,7 @@ namespace ts { if (quick && getSymbolIfSameReference(quick, symbol)) { return quick; } - return forEachEntry(exports, exported => { + return ts.forEachEntry(exports, exported => { if (getSymbolIfSameReference(exported, symbol)) { return exported; } @@ -4098,54 +3996,53 @@ namespace ts { /** * Checks if two symbols, through aliasing and/or merging, refer to the same thing */ - function getSymbolIfSameReference(s1: Symbol, s2: Symbol) { + function getSymbolIfSameReference(s1: ts.Symbol, s2: ts.Symbol) { if (getMergedSymbol(resolveSymbol(getMergedSymbol(s1))) === getMergedSymbol(resolveSymbol(getMergedSymbol(s2)))) { return s1; } } - function getExportSymbolOfValueSymbolIfExported(symbol: Symbol): Symbol; - function getExportSymbolOfValueSymbolIfExported(symbol: Symbol | undefined): Symbol | undefined; - function getExportSymbolOfValueSymbolIfExported(symbol: Symbol | undefined): Symbol | undefined { - return getMergedSymbol(symbol && (symbol.flags & SymbolFlags.ExportValue) !== 0 && symbol.exportSymbol || symbol); + function getExportSymbolOfValueSymbolIfExported(symbol: ts.Symbol): ts.Symbol; + function getExportSymbolOfValueSymbolIfExported(symbol: ts.Symbol | undefined): ts.Symbol | undefined; + function getExportSymbolOfValueSymbolIfExported(symbol: ts.Symbol | undefined): ts.Symbol | undefined { + return getMergedSymbol(symbol && (symbol.flags & ts.SymbolFlags.ExportValue) !== 0 && symbol.exportSymbol || symbol); } - function symbolIsValue(symbol: Symbol, includeTypeOnlyMembers?: boolean): boolean { - return !!( - symbol.flags & SymbolFlags.Value || - symbol.flags & SymbolFlags.Alias && resolveAlias(symbol).flags & SymbolFlags.Value && (includeTypeOnlyMembers || !getTypeOnlyAliasDeclaration(symbol))); + function symbolIsValue(symbol: ts.Symbol, includeTypeOnlyMembers?: boolean): boolean { + return !!(symbol.flags & ts.SymbolFlags.Value || + symbol.flags & ts.SymbolFlags.Alias && resolveAlias(symbol).flags & ts.SymbolFlags.Value && (includeTypeOnlyMembers || !getTypeOnlyAliasDeclaration(symbol))); } - function findConstructorDeclaration(node: ClassLikeDeclaration): ConstructorDeclaration | undefined { + function findConstructorDeclaration(node: ts.ClassLikeDeclaration): ts.ConstructorDeclaration | undefined { const members = node.members; for (const member of members) { - if (member.kind === SyntaxKind.Constructor && nodeIsPresent((member as ConstructorDeclaration).body)) { - return member as ConstructorDeclaration; + if (member.kind === ts.SyntaxKind.Constructor && ts.nodeIsPresent((member as ts.ConstructorDeclaration).body)) { + return member as ts.ConstructorDeclaration; } } } - function createType(flags: TypeFlags): Type { + function createType(flags: ts.TypeFlags): ts.Type { const result = new Type(checker, flags); typeCount++; result.id = typeCount; - tracing?.recordType(result); + ts.tracing?.recordType(result); return result; } - function createOriginType(flags: TypeFlags): Type { + function createOriginType(flags: ts.TypeFlags): ts.Type { return new Type(checker, flags); } - function createIntrinsicType(kind: TypeFlags, intrinsicName: string, objectFlags: ObjectFlags = 0): IntrinsicType { - const type = createType(kind) as IntrinsicType; + function createIntrinsicType(kind: ts.TypeFlags, intrinsicName: string, objectFlags: ts.ObjectFlags = 0): ts.IntrinsicType { + const type = createType(kind) as ts.IntrinsicType; type.intrinsicName = intrinsicName; type.objectFlags = objectFlags; return type; } - function createObjectType(objectFlags: ObjectFlags, symbol?: Symbol): ObjectType { - const type = createType(TypeFlags.Object) as ObjectType; + function createObjectType(objectFlags: ts.ObjectFlags, symbol?: ts.Symbol): ts.ObjectType { + const type = createType(ts.TypeFlags.Object) as ts.ObjectType; type.objectFlags = objectFlags; type.symbol = symbol!; type.members = undefined; @@ -4157,12 +4054,13 @@ namespace ts { } function createTypeofType() { - return getUnionType(arrayFrom(typeofEQFacts.keys(), getStringLiteralType)); + return getUnionType(ts.arrayFrom(typeofEQFacts.keys(), getStringLiteralType)); } - function createTypeParameter(symbol?: Symbol) { - const type = createType(TypeFlags.TypeParameter) as TypeParameter; - if (symbol) type.symbol = symbol; + function createTypeParameter(symbol?: ts.Symbol) { + const type = createType(ts.TypeFlags.TypeParameter) as ts.TypeParameter; + if (symbol) + type.symbol = symbol; return type; } @@ -4170,68 +4068,65 @@ namespace ts { // @, or #. A third underscore indicates an escaped form of an identifier that started // with at least two underscores. The @ character indicates that the name is denoted by a well known ES // Symbol instance and the # character indicates that the name is a PrivateIdentifier. - function isReservedMemberName(name: __String) { - return (name as string).charCodeAt(0) === CharacterCodes._ && - (name as string).charCodeAt(1) === CharacterCodes._ && - (name as string).charCodeAt(2) !== CharacterCodes._ && - (name as string).charCodeAt(2) !== CharacterCodes.at && - (name as string).charCodeAt(2) !== CharacterCodes.hash; - } - - function getNamedMembers(members: SymbolTable): Symbol[] { - let result: Symbol[] | undefined; + function isReservedMemberName(name: ts.__String) { + return (name as string).charCodeAt(0) === ts.CharacterCodes._ && + (name as string).charCodeAt(1) === ts.CharacterCodes._ && + (name as string).charCodeAt(2) !== ts.CharacterCodes._ && + (name as string).charCodeAt(2) !== ts.CharacterCodes.at && + (name as string).charCodeAt(2) !== ts.CharacterCodes.hash; + } + function getNamedMembers(members: ts.SymbolTable): ts.Symbol[] { + let result: ts.Symbol[] | undefined; members.forEach((symbol, id) => { if (isNamedMember(symbol, id)) { (result || (result = [])).push(symbol); } }); - return result || emptyArray; + return result || ts.emptyArray; } - function isNamedMember(member: Symbol, escapedName: __String) { + function isNamedMember(member: ts.Symbol, escapedName: ts.__String) { return !isReservedMemberName(escapedName) && symbolIsValue(member); } - function getNamedOrIndexSignatureMembers(members: SymbolTable): Symbol[] { + function getNamedOrIndexSignatureMembers(members: ts.SymbolTable): ts.Symbol[] { const result = getNamedMembers(members); const index = getIndexSymbolFromSymbolTable(members); - return index ? concatenate(result, [index]) : result; + return index ? ts.concatenate(result, [index]) : result; } - function setStructuredTypeMembers(type: StructuredType, members: SymbolTable, callSignatures: readonly Signature[], constructSignatures: readonly Signature[], indexInfos: readonly IndexInfo[]): ResolvedType { - const resolved = type as ResolvedType; + function setStructuredTypeMembers(type: ts.StructuredType, members: ts.SymbolTable, callSignatures: readonly ts.Signature[], constructSignatures: readonly ts.Signature[], indexInfos: readonly ts.IndexInfo[]): ts.ResolvedType { + const resolved = type as ts.ResolvedType; resolved.members = members; - resolved.properties = emptyArray; + resolved.properties = ts.emptyArray; resolved.callSignatures = callSignatures; resolved.constructSignatures = constructSignatures; resolved.indexInfos = indexInfos; // This can loop back to getPropertyOfType() which would crash if `callSignatures` & `constructSignatures` are not initialized. - if (members !== emptySymbols) resolved.properties = getNamedMembers(members); + if (members !== emptySymbols) + resolved.properties = getNamedMembers(members); return resolved; } - function createAnonymousType(symbol: Symbol | undefined, members: SymbolTable, callSignatures: readonly Signature[], constructSignatures: readonly Signature[], indexInfos: readonly IndexInfo[]): ResolvedType { - return setStructuredTypeMembers(createObjectType(ObjectFlags.Anonymous, symbol), - members, callSignatures, constructSignatures, indexInfos); + function createAnonymousType(symbol: ts.Symbol | undefined, members: ts.SymbolTable, callSignatures: readonly ts.Signature[], constructSignatures: readonly ts.Signature[], indexInfos: readonly ts.IndexInfo[]): ts.ResolvedType { + return setStructuredTypeMembers(createObjectType(ts.ObjectFlags.Anonymous, symbol), members, callSignatures, constructSignatures, indexInfos); } - function getResolvedTypeWithoutAbstractConstructSignatures(type: ResolvedType) { - if (type.constructSignatures.length === 0) return type; - if (type.objectTypeWithoutAbstractConstructSignatures) return type.objectTypeWithoutAbstractConstructSignatures; - const constructSignatures = filter(type.constructSignatures, signature => !(signature.flags & SignatureFlags.Abstract)); - if (type.constructSignatures === constructSignatures) return type; - const typeCopy = createAnonymousType( - type.symbol, - type.members, - type.callSignatures, - some(constructSignatures) ? constructSignatures : emptyArray, - type.indexInfos); + function getResolvedTypeWithoutAbstractConstructSignatures(type: ts.ResolvedType) { + if (type.constructSignatures.length === 0) + return type; + if (type.objectTypeWithoutAbstractConstructSignatures) + return type.objectTypeWithoutAbstractConstructSignatures; + const constructSignatures = ts.filter(type.constructSignatures, signature => !(signature.flags & ts.SignatureFlags.Abstract)); + if (type.constructSignatures === constructSignatures) + return type; + const typeCopy = createAnonymousType(type.symbol, type.members, type.callSignatures, ts.some(constructSignatures) ? constructSignatures : ts.emptyArray, type.indexInfos); type.objectTypeWithoutAbstractConstructSignatures = typeCopy; typeCopy.objectTypeWithoutAbstractConstructSignatures = typeCopy; return typeCopy; } - function forEachSymbolTableInScope(enclosingDeclaration: Node | undefined, callback: (symbolTable: SymbolTable, ignoreQualification?: boolean, isLocalNameLookup?: boolean, scopeNode?: Node) => T): T { + function forEachSymbolTableInScope(enclosingDeclaration: ts.Node | undefined, callback: (symbolTable: ts.SymbolTable, ignoreQualification?: boolean, isLocalNameLookup?: boolean, scopeNode?: ts.Node) => T): T { let result: T; for (let location = enclosingDeclaration; location; location = location.parent) { // Locals of a source file are not in scope (because they get merged into the global symbol table) @@ -4241,13 +4136,13 @@ namespace ts { } } switch (location.kind) { - case SyntaxKind.SourceFile: - if (!isExternalOrCommonJsModule(location as SourceFile)) { + case ts.SyntaxKind.SourceFile: + if (!ts.isExternalOrCommonJsModule(location as ts.SourceFile)) { break; } // falls through - case SyntaxKind.ModuleDeclaration: - const sym = getSymbolOfNode(location as ModuleDeclaration); + case ts.SyntaxKind.ModuleDeclaration: + const sym = getSymbolOfNode(location as ts.ModuleDeclaration); // `sym` may not have exports if this module declaration is backed by the symbol for a `const` that's being rewritten // into a namespace - in such cases, it's best to just let the namespace appear empty (the const members couldn't have referred // to one another anyway) @@ -4255,9 +4150,9 @@ namespace ts { return result; } break; - case SyntaxKind.ClassDeclaration: - case SyntaxKind.ClassExpression: - case SyntaxKind.InterfaceDeclaration: + case ts.SyntaxKind.ClassDeclaration: + case ts.SyntaxKind.ClassExpression: + case ts.SyntaxKind.InterfaceDeclaration: // Type parameters are bound into `members` lists so they can merge across declarations // This is troublesome, since in all other respects, they behave like locals :cries: // TODO: the below is shared with similar code in `resolveName` - in fact, rephrasing all this symbol @@ -4265,11 +4160,11 @@ namespace ts { // The below is used to lookup type parameters within a class or interface, as they are added to the class/interface locals // These can never be latebound, so the symbol's raw members are sufficient. `getMembersOfNode` cannot be used, as it would // trigger resolving late-bound names, which we may already be in the process of doing while we're here! - let table: UnderscoreEscapedMap | undefined; + let table: ts.UnderscoreEscapedMap | undefined; // TODO: Should this filtered table be cached in some way? - (getSymbolOfNode(location as ClassLikeDeclaration | InterfaceDeclaration).members || emptySymbols).forEach((memberSymbol, key) => { - if (memberSymbol.flags & (SymbolFlags.Type & ~SymbolFlags.Assignment)) { - (table || (table = createSymbolTable())).set(key, memberSymbol); + (getSymbolOfNode(location as ts.ClassLikeDeclaration | ts.InterfaceDeclaration).members || emptySymbols).forEach((memberSymbol, key) => { + if (memberSymbol.flags & (ts.SymbolFlags.Type & ~ts.SymbolFlags.Assignment)) { + (table || (table = ts.createSymbolTable())).set(key, memberSymbol); } }); if (table && (result = callback(table, /*ignoreQualification*/ undefined, /*isLocalNameLookup*/ false, location))) { @@ -4282,17 +4177,17 @@ namespace ts { return callback(globals, /*ignoreQualification*/ undefined, /*isLocalNameLookup*/ true); } - function getQualifiedLeftMeaning(rightMeaning: SymbolFlags) { + function getQualifiedLeftMeaning(rightMeaning: ts.SymbolFlags) { // If we are looking in value space, the parent meaning is value, other wise it is namespace - return rightMeaning === SymbolFlags.Value ? SymbolFlags.Value : SymbolFlags.Namespace; + return rightMeaning === ts.SymbolFlags.Value ? ts.SymbolFlags.Value : ts.SymbolFlags.Namespace; } - function getAccessibleSymbolChain(symbol: Symbol | undefined, enclosingDeclaration: Node | undefined, meaning: SymbolFlags, useOnlyExternalAliasing: boolean, visitedSymbolTablesMap: ESMap = new Map()): Symbol[] | undefined { + function getAccessibleSymbolChain(symbol: ts.Symbol | undefined, enclosingDeclaration: ts.Node | undefined, meaning: ts.SymbolFlags, useOnlyExternalAliasing: boolean, visitedSymbolTablesMap: ts.ESMap = new ts.Map()): ts.Symbol[] | undefined { if (!(symbol && !isPropertyOrMethodDeclarationSymbol(symbol))) { return undefined; } const links = getSymbolLinks(symbol); - const cache = (links.accessibleChainCache ||= new Map()); + const cache = (links.accessibleChainCache ||= new ts.Map()); // Go from enclosingDeclaration to the first scope we check, so the cache is keyed off the scope and thus shared more const firstRelevantLocation = forEachSymbolTableInScope(enclosingDeclaration, (_, __, ___, node) => node); const key = `${useOnlyExternalAliasing ? 0 : 1}|${firstRelevantLocation && getNodeId(firstRelevantLocation)}|${meaning}`; @@ -4312,8 +4207,8 @@ namespace ts { /** * @param {ignoreQualification} boolean Set when a symbol is being looked for through the exports of another symbol (meaning we have a route to qualify it already) */ - function getAccessibleSymbolChainFromSymbolTable(symbols: SymbolTable, ignoreQualification?: boolean, isLocalNameLookup?: boolean): Symbol[] | undefined { - if (!pushIfUnique(visitedSymbolTables!, symbols)) { + function getAccessibleSymbolChainFromSymbolTable(symbols: ts.SymbolTable, ignoreQualification?: boolean, isLocalNameLookup?: boolean): ts.Symbol[] | undefined { + if (!ts.pushIfUnique(visitedSymbolTables!, symbols)) { return undefined; } @@ -4322,42 +4217,41 @@ namespace ts { return result; } - function canQualifySymbol(symbolFromSymbolTable: Symbol, meaning: SymbolFlags) { + function canQualifySymbol(symbolFromSymbolTable: ts.Symbol, meaning: ts.SymbolFlags) { // If the symbol is equivalent and doesn't need further qualification, this symbol is accessible return !needsQualification(symbolFromSymbolTable, enclosingDeclaration, meaning) || // If symbol needs qualification, make sure that parent is accessible, if it is then this symbol is accessible too !!getAccessibleSymbolChain(symbolFromSymbolTable.parent, enclosingDeclaration, getQualifiedLeftMeaning(meaning), useOnlyExternalAliasing, visitedSymbolTablesMap); } - function isAccessible(symbolFromSymbolTable: Symbol, resolvedAliasSymbol?: Symbol, ignoreQualification?: boolean) { + function isAccessible(symbolFromSymbolTable: ts.Symbol, resolvedAliasSymbol?: ts.Symbol, ignoreQualification?: boolean) { return (symbol === (resolvedAliasSymbol || symbolFromSymbolTable) || getMergedSymbol(symbol) === getMergedSymbol(resolvedAliasSymbol || symbolFromSymbolTable)) && // if the symbolFromSymbolTable is not external module (it could be if it was determined as ambient external module and would be in globals table) // and if symbolFromSymbolTable or alias resolution matches the symbol, // check the symbol can be qualified, it is only then this symbol is accessible - !some(symbolFromSymbolTable.declarations, hasNonGlobalAugmentationExternalModuleSymbol) && + !ts.some(symbolFromSymbolTable.declarations, hasNonGlobalAugmentationExternalModuleSymbol) && (ignoreQualification || canQualifySymbol(getMergedSymbol(symbolFromSymbolTable), meaning)); } - function trySymbolTable(symbols: SymbolTable, ignoreQualification: boolean | undefined, isLocalNameLookup: boolean | undefined): Symbol[] | undefined { + function trySymbolTable(symbols: ts.SymbolTable, ignoreQualification: boolean | undefined, isLocalNameLookup: boolean | undefined): ts.Symbol[] | undefined { // If symbol is directly available by its name in the symbol table if (isAccessible(symbols.get(symbol!.escapedName)!, /*resolvedAliasSymbol*/ undefined, ignoreQualification)) { return [symbol!]; } // Check if symbol is any of the aliases in scope - const result = forEachEntry(symbols, symbolFromSymbolTable => { - if (symbolFromSymbolTable.flags & SymbolFlags.Alias - && symbolFromSymbolTable.escapedName !== InternalSymbolName.ExportEquals - && symbolFromSymbolTable.escapedName !== InternalSymbolName.Default - && !(isUMDExportSymbol(symbolFromSymbolTable) && enclosingDeclaration && isExternalModule(getSourceFileOfNode(enclosingDeclaration))) + const result = ts.forEachEntry(symbols, symbolFromSymbolTable => { + if (symbolFromSymbolTable.flags & ts.SymbolFlags.Alias + && symbolFromSymbolTable.escapedName !== ts.InternalSymbolName.ExportEquals + && symbolFromSymbolTable.escapedName !== ts.InternalSymbolName.Default + && !(ts.isUMDExportSymbol(symbolFromSymbolTable) && enclosingDeclaration && ts.isExternalModule(ts.getSourceFileOfNode(enclosingDeclaration))) // If `!useOnlyExternalAliasing`, we can use any type of alias to get the name - && (!useOnlyExternalAliasing || some(symbolFromSymbolTable.declarations, isExternalModuleImportEqualsDeclaration)) + && (!useOnlyExternalAliasing || ts.some(symbolFromSymbolTable.declarations, ts.isExternalModuleImportEqualsDeclaration)) // If we're looking up a local name to reference directly, omit namespace reexports, otherwise when we're trawling through an export list to make a dotted name, we can keep it - && (isLocalNameLookup ? !some(symbolFromSymbolTable.declarations, isNamespaceReexportDeclaration) : true) + && (isLocalNameLookup ? !ts.some(symbolFromSymbolTable.declarations, ts.isNamespaceReexportDeclaration) : true) // While exports are generally considered to be in scope, export-specifier declared symbols are _not_ // See similar comment in `resolveName` for details - && (ignoreQualification || !getDeclarationOfKind(symbolFromSymbolTable, SyntaxKind.ExportSpecifier)) - ) { + && (ignoreQualification || !ts.getDeclarationOfKind(symbolFromSymbolTable, ts.SyntaxKind.ExportSpecifier))) { const resolvedImportedSymbol = resolveAlias(symbolFromSymbolTable); const candidate = getCandidateListForSymbol(symbolFromSymbolTable, resolvedImportedSymbol, ignoreQualification); @@ -4376,7 +4270,7 @@ namespace ts { return result || (symbols === globals ? getCandidateListForSymbol(globalThisSymbol, globalThisSymbol, ignoreQualification) : undefined); } - function getCandidateListForSymbol(symbolFromSymbolTable: Symbol, resolvedImportedSymbol: Symbol, ignoreQualification: boolean | undefined) { + function getCandidateListForSymbol(symbolFromSymbolTable: ts.Symbol, resolvedImportedSymbol: ts.Symbol, ignoreQualification: boolean | undefined) { if (isAccessible(symbolFromSymbolTable, resolvedImportedSymbol, ignoreQualification)) { return [symbolFromSymbolTable]; } @@ -4391,7 +4285,7 @@ namespace ts { } } - function needsQualification(symbol: Symbol, enclosingDeclaration: Node | undefined, meaning: SymbolFlags) { + function needsQualification(symbol: ts.Symbol, enclosingDeclaration: ts.Node | undefined, meaning: ts.SymbolFlags) { let qualify = false; forEachSymbolTableInScope(enclosingDeclaration, symbolTable => { // If symbol of this name is not available in the symbol table we are ok @@ -4407,7 +4301,7 @@ namespace ts { } // Qualify if the symbol from symbol table has same meaning as expected - symbolFromSymbolTable = (symbolFromSymbolTable.flags & SymbolFlags.Alias && !getDeclarationOfKind(symbolFromSymbolTable, SyntaxKind.ExportSpecifier)) ? resolveAlias(symbolFromSymbolTable) : symbolFromSymbolTable; + symbolFromSymbolTable = (symbolFromSymbolTable.flags & ts.SymbolFlags.Alias && !ts.getDeclarationOfKind(symbolFromSymbolTable, ts.SyntaxKind.ExportSpecifier)) ? resolveAlias(symbolFromSymbolTable) : symbolFromSymbolTable; if (symbolFromSymbolTable.flags & meaning) { qualify = true; return true; @@ -4420,14 +4314,14 @@ namespace ts { return qualify; } - function isPropertyOrMethodDeclarationSymbol(symbol: Symbol) { + function isPropertyOrMethodDeclarationSymbol(symbol: ts.Symbol) { if (symbol.declarations && symbol.declarations.length) { for (const declaration of symbol.declarations) { switch (declaration.kind) { - case SyntaxKind.PropertyDeclaration: - case SyntaxKind.MethodDeclaration: - case SyntaxKind.GetAccessor: - case SyntaxKind.SetAccessor: + case ts.SyntaxKind.PropertyDeclaration: + case ts.SyntaxKind.MethodDeclaration: + case ts.SyntaxKind.GetAccessor: + case ts.SyntaxKind.SetAccessor: continue; default: return false; @@ -4438,25 +4332,25 @@ namespace ts { return false; } - function isTypeSymbolAccessible(typeSymbol: Symbol, enclosingDeclaration: Node | undefined): boolean { - const access = isSymbolAccessibleWorker(typeSymbol, enclosingDeclaration, SymbolFlags.Type, /*shouldComputeAliasesToMakeVisible*/ false, /*allowModules*/ true); - return access.accessibility === SymbolAccessibility.Accessible; + function isTypeSymbolAccessible(typeSymbol: ts.Symbol, enclosingDeclaration: ts.Node | undefined): boolean { + const access = isSymbolAccessibleWorker(typeSymbol, enclosingDeclaration, ts.SymbolFlags.Type, /*shouldComputeAliasesToMakeVisible*/ false, /*allowModules*/ true); + return access.accessibility === ts.SymbolAccessibility.Accessible; } - function isValueSymbolAccessible(typeSymbol: Symbol, enclosingDeclaration: Node | undefined): boolean { - const access = isSymbolAccessibleWorker(typeSymbol, enclosingDeclaration, SymbolFlags.Value, /*shouldComputeAliasesToMakeVisible*/ false, /*allowModules*/ true); - return access.accessibility === SymbolAccessibility.Accessible; + function isValueSymbolAccessible(typeSymbol: ts.Symbol, enclosingDeclaration: ts.Node | undefined): boolean { + const access = isSymbolAccessibleWorker(typeSymbol, enclosingDeclaration, ts.SymbolFlags.Value, /*shouldComputeAliasesToMakeVisible*/ false, /*allowModules*/ true); + return access.accessibility === ts.SymbolAccessibility.Accessible; } - function isSymbolAccessibleByFlags(typeSymbol: Symbol, enclosingDeclaration: Node | undefined, flags: SymbolFlags): boolean { + function isSymbolAccessibleByFlags(typeSymbol: ts.Symbol, enclosingDeclaration: ts.Node | undefined, flags: ts.SymbolFlags): boolean { const access = isSymbolAccessibleWorker(typeSymbol, enclosingDeclaration, flags, /*shouldComputeAliasesToMakeVisible*/ false, /*allowModules*/ false); - return access.accessibility === SymbolAccessibility.Accessible; + return access.accessibility === ts.SymbolAccessibility.Accessible; } - function isAnySymbolAccessible(symbols: Symbol[] | undefined, enclosingDeclaration: Node | undefined, initialSymbol: Symbol, meaning: SymbolFlags, shouldComputeAliasesToMakeVisible: boolean, allowModules: boolean): SymbolAccessibilityResult | undefined { - if (!length(symbols)) return; - - let hadAccessibleChain: Symbol | undefined; + function isAnySymbolAccessible(symbols: ts.Symbol[] | undefined, enclosingDeclaration: ts.Node | undefined, initialSymbol: ts.Symbol, meaning: ts.SymbolFlags, shouldComputeAliasesToMakeVisible: boolean, allowModules: boolean): ts.SymbolAccessibilityResult | undefined { + if (!ts.length(symbols)) + return; + let hadAccessibleChain: ts.Symbol | undefined; let earlyModuleBail = false; for (const symbol of symbols!) { // Symbol is accessible if it by itself is accessible @@ -4469,7 +4363,7 @@ namespace ts { } } if (allowModules) { - if (some(symbol.declarations, hasNonGlobalAugmentationExternalModuleSymbol)) { + if (ts.some(symbol.declarations, hasNonGlobalAugmentationExternalModuleSymbol)) { if (shouldComputeAliasesToMakeVisible) { earlyModuleBail = true; // Generally speaking, we want to use the aliases that already exist to refer to a module, if present @@ -4480,7 +4374,7 @@ namespace ts { } // Any meaning of a module symbol is always accessible via an `import` type return { - accessibility: SymbolAccessibility.Accessible + accessibility: ts.SymbolAccessibility.Accessible }; } } @@ -4507,15 +4401,15 @@ namespace ts { if (earlyModuleBail) { return { - accessibility: SymbolAccessibility.Accessible + accessibility: ts.SymbolAccessibility.Accessible }; } if (hadAccessibleChain) { return { - accessibility: SymbolAccessibility.NotAccessible, + accessibility: ts.SymbolAccessibility.NotAccessible, errorSymbolName: symbolToString(initialSymbol, enclosingDeclaration, meaning), - errorModuleName: hadAccessibleChain !== initialSymbol ? symbolToString(hadAccessibleChain, enclosingDeclaration, SymbolFlags.Namespace) : undefined, + errorModuleName: hadAccessibleChain !== initialSymbol ? symbolToString(hadAccessibleChain, enclosingDeclaration, ts.SymbolFlags.Namespace) : undefined, }; } } @@ -4528,11 +4422,11 @@ namespace ts { * @param meaning a SymbolFlags to check if such meaning of the symbol is accessible * @param shouldComputeAliasToMakeVisible a boolean value to indicate whether to return aliases to be mark visible in case the symbol is accessible */ - function isSymbolAccessible(symbol: Symbol | undefined, enclosingDeclaration: Node | undefined, meaning: SymbolFlags, shouldComputeAliasesToMakeVisible: boolean): SymbolAccessibilityResult { + function isSymbolAccessible(symbol: ts.Symbol | undefined, enclosingDeclaration: ts.Node | undefined, meaning: ts.SymbolFlags, shouldComputeAliasesToMakeVisible: boolean): ts.SymbolAccessibilityResult { return isSymbolAccessibleWorker(symbol, enclosingDeclaration, meaning, shouldComputeAliasesToMakeVisible, /*allowModules*/ true); } - function isSymbolAccessibleWorker(symbol: Symbol | undefined, enclosingDeclaration: Node | undefined, meaning: SymbolFlags, shouldComputeAliasesToMakeVisible: boolean, allowModules: boolean): SymbolAccessibilityResult { + function isSymbolAccessibleWorker(symbol: ts.Symbol | undefined, enclosingDeclaration: ts.Node | undefined, meaning: ts.SymbolFlags, shouldComputeAliasesToMakeVisible: boolean, allowModules: boolean): ts.SymbolAccessibilityResult { if (symbol && enclosingDeclaration) { const result = isAnySymbolAccessible([symbol], enclosingDeclaration, symbol, meaning, shouldComputeAliasesToMakeVisible, allowModules); if (result) { @@ -4541,75 +4435,74 @@ namespace ts { // This could be a symbol that is not exported in the external module // or it could be a symbol from different external module that is not aliased and hence cannot be named - const symbolExternalModule = forEach(symbol.declarations, getExternalModuleContainer); + const symbolExternalModule = ts.forEach(symbol.declarations, getExternalModuleContainer); if (symbolExternalModule) { const enclosingExternalModule = getExternalModuleContainer(enclosingDeclaration); if (symbolExternalModule !== enclosingExternalModule) { // name from different external module that is not visible return { - accessibility: SymbolAccessibility.CannotBeNamed, + accessibility: ts.SymbolAccessibility.CannotBeNamed, errorSymbolName: symbolToString(symbol, enclosingDeclaration, meaning), errorModuleName: symbolToString(symbolExternalModule), - errorNode: isInJSFile(enclosingDeclaration) ? enclosingDeclaration : undefined, + errorNode: ts.isInJSFile(enclosingDeclaration) ? enclosingDeclaration : undefined, }; } } // Just a local name that is not accessible return { - accessibility: SymbolAccessibility.NotAccessible, + accessibility: ts.SymbolAccessibility.NotAccessible, errorSymbolName: symbolToString(symbol, enclosingDeclaration, meaning), }; } - return { accessibility: SymbolAccessibility.Accessible }; + return { accessibility: ts.SymbolAccessibility.Accessible }; } - function getExternalModuleContainer(declaration: Node) { - const node = findAncestor(declaration, hasExternalModuleSymbol); + function getExternalModuleContainer(declaration: ts.Node) { + const node = ts.findAncestor(declaration, hasExternalModuleSymbol); return node && getSymbolOfNode(node); } - function hasExternalModuleSymbol(declaration: Node) { - return isAmbientModule(declaration) || (declaration.kind === SyntaxKind.SourceFile && isExternalOrCommonJsModule(declaration as SourceFile)); + function hasExternalModuleSymbol(declaration: ts.Node) { + return ts.isAmbientModule(declaration) || (declaration.kind === ts.SyntaxKind.SourceFile && ts.isExternalOrCommonJsModule(declaration as ts.SourceFile)); } - function hasNonGlobalAugmentationExternalModuleSymbol(declaration: Node) { - return isModuleWithStringLiteralName(declaration) || (declaration.kind === SyntaxKind.SourceFile && isExternalOrCommonJsModule(declaration as SourceFile)); + function hasNonGlobalAugmentationExternalModuleSymbol(declaration: ts.Node) { + return ts.isModuleWithStringLiteralName(declaration) || (declaration.kind === ts.SyntaxKind.SourceFile && ts.isExternalOrCommonJsModule(declaration as ts.SourceFile)); } - function hasVisibleDeclarations(symbol: Symbol, shouldComputeAliasToMakeVisible: boolean): SymbolVisibilityResult | undefined { - let aliasesToMakeVisible: LateVisibilityPaintedStatement[] | undefined; - if (!every(filter(symbol.declarations, d => d.kind !== SyntaxKind.Identifier), getIsDeclarationVisible)) { + function hasVisibleDeclarations(symbol: ts.Symbol, shouldComputeAliasToMakeVisible: boolean): ts.SymbolVisibilityResult | undefined { + let aliasesToMakeVisible: ts.LateVisibilityPaintedStatement[] | undefined; + if (!ts.every(ts.filter(symbol.declarations, d => d.kind !== ts.SyntaxKind.Identifier), getIsDeclarationVisible)) { return undefined; } - return { accessibility: SymbolAccessibility.Accessible, aliasesToMakeVisible }; - - function getIsDeclarationVisible(declaration: Declaration) { + return { accessibility: ts.SymbolAccessibility.Accessible, aliasesToMakeVisible }; + function getIsDeclarationVisible(declaration: ts.Declaration) { if (!isDeclarationVisible(declaration)) { // Mark the unexported alias as visible if its parent is visible // because these kind of aliases can be used to name types in declaration file const anyImportSyntax = getAnyImportSyntax(declaration); if (anyImportSyntax && - !hasSyntacticModifier(anyImportSyntax, ModifierFlags.Export) && // import clause without export + !ts.hasSyntacticModifier(anyImportSyntax, ts.ModifierFlags.Export) && // import clause without export isDeclarationVisible(anyImportSyntax.parent)) { return addVisibleAlias(declaration, anyImportSyntax); } - else if (isVariableDeclaration(declaration) && isVariableStatement(declaration.parent.parent) && - !hasSyntacticModifier(declaration.parent.parent, ModifierFlags.Export) && // unexported variable statement + else if (ts.isVariableDeclaration(declaration) && ts.isVariableStatement(declaration.parent.parent) && + !ts.hasSyntacticModifier(declaration.parent.parent, ts.ModifierFlags.Export) && // unexported variable statement isDeclarationVisible(declaration.parent.parent.parent)) { return addVisibleAlias(declaration, declaration.parent.parent); } - else if (isLateVisibilityPaintedStatement(declaration) // unexported top-level statement - && !hasSyntacticModifier(declaration, ModifierFlags.Export) + else if (ts.isLateVisibilityPaintedStatement(declaration) // unexported top-level statement + && !ts.hasSyntacticModifier(declaration, ts.ModifierFlags.Export) && isDeclarationVisible(declaration.parent)) { return addVisibleAlias(declaration, declaration); } - else if (symbol.flags & SymbolFlags.Alias && isBindingElement(declaration) && isInJSFile(declaration) && declaration.parent?.parent // exported import-like top-level JS require statement - && isVariableDeclaration(declaration.parent.parent) - && declaration.parent.parent.parent?.parent && isVariableStatement(declaration.parent.parent.parent.parent) - && !hasSyntacticModifier(declaration.parent.parent.parent.parent, ModifierFlags.Export) + else if (symbol.flags & ts.SymbolFlags.Alias && ts.isBindingElement(declaration) && ts.isInJSFile(declaration) && declaration.parent?.parent // exported import-like top-level JS require statement + && ts.isVariableDeclaration(declaration.parent.parent) + && declaration.parent.parent.parent?.parent && ts.isVariableStatement(declaration.parent.parent.parent.parent) + && !ts.hasSyntacticModifier(declaration.parent.parent.parent.parent, ts.ModifierFlags.Export) && declaration.parent.parent.parent.parent.parent // check if the thing containing the variable statement is visible (ie, the file) && isDeclarationVisible(declaration.parent.parent.parent.parent.parent)) { return addVisibleAlias(declaration, declaration.parent.parent.parent.parent); @@ -4622,118 +4515,120 @@ namespace ts { return true; } - function addVisibleAlias(declaration: Declaration, aliasingStatement: LateVisibilityPaintedStatement) { + function addVisibleAlias(declaration: ts.Declaration, aliasingStatement: ts.LateVisibilityPaintedStatement) { // In function "buildTypeDisplay" where we decide whether to write type-alias or serialize types, // we want to just check if type- alias is accessible or not but we don't care about emitting those alias at that time // since we will do the emitting later in trackSymbol. if (shouldComputeAliasToMakeVisible) { getNodeLinks(declaration).isVisible = true; - aliasesToMakeVisible = appendIfUnique(aliasesToMakeVisible, aliasingStatement); + aliasesToMakeVisible = ts.appendIfUnique(aliasesToMakeVisible, aliasingStatement); } return true; } } - function isEntityNameVisible(entityName: EntityNameOrEntityNameExpression, enclosingDeclaration: Node): SymbolVisibilityResult { + function isEntityNameVisible(entityName: ts.EntityNameOrEntityNameExpression, enclosingDeclaration: ts.Node): ts.SymbolVisibilityResult { // get symbol of the first identifier of the entityName - let meaning: SymbolFlags; - if (entityName.parent.kind === SyntaxKind.TypeQuery || - entityName.parent.kind === SyntaxKind.ExpressionWithTypeArguments && !isPartOfTypeNode(entityName.parent) || - entityName.parent.kind === SyntaxKind.ComputedPropertyName) { + let meaning: ts.SymbolFlags; + if (entityName.parent.kind === ts.SyntaxKind.TypeQuery || + entityName.parent.kind === ts.SyntaxKind.ExpressionWithTypeArguments && !ts.isPartOfTypeNode(entityName.parent) || + entityName.parent.kind === ts.SyntaxKind.ComputedPropertyName) { // Typeof value - meaning = SymbolFlags.Value | SymbolFlags.ExportValue; + meaning = ts.SymbolFlags.Value | ts.SymbolFlags.ExportValue; } - else if (entityName.kind === SyntaxKind.QualifiedName || entityName.kind === SyntaxKind.PropertyAccessExpression || - entityName.parent.kind === SyntaxKind.ImportEqualsDeclaration) { + else if (entityName.kind === ts.SyntaxKind.QualifiedName || entityName.kind === ts.SyntaxKind.PropertyAccessExpression || + entityName.parent.kind === ts.SyntaxKind.ImportEqualsDeclaration) { // Left identifier from type reference or TypeAlias // Entity name of the import declaration - meaning = SymbolFlags.Namespace; + meaning = ts.SymbolFlags.Namespace; } else { // Type Reference or TypeAlias entity = Identifier - meaning = SymbolFlags.Type; + meaning = ts.SymbolFlags.Type; } - const firstIdentifier = getFirstIdentifier(entityName); + const firstIdentifier = ts.getFirstIdentifier(entityName); const symbol = resolveName(enclosingDeclaration, firstIdentifier.escapedText, meaning, /*nodeNotFoundErrorMessage*/ undefined, /*nameArg*/ undefined, /*isUse*/ false); - if (symbol && symbol.flags & SymbolFlags.TypeParameter && meaning & SymbolFlags.Type) { - return { accessibility: SymbolAccessibility.Accessible }; + if (symbol && symbol.flags & ts.SymbolFlags.TypeParameter && meaning & ts.SymbolFlags.Type) { + return { accessibility: ts.SymbolAccessibility.Accessible }; } // Verify if the symbol is accessible return (symbol && hasVisibleDeclarations(symbol, /*shouldComputeAliasToMakeVisible*/ true)) || { - accessibility: SymbolAccessibility.NotAccessible, - errorSymbolName: getTextOfNode(firstIdentifier), + accessibility: ts.SymbolAccessibility.NotAccessible, + errorSymbolName: ts.getTextOfNode(firstIdentifier), errorNode: firstIdentifier }; } - function symbolToString(symbol: Symbol, enclosingDeclaration?: Node, meaning?: SymbolFlags, flags: SymbolFormatFlags = SymbolFormatFlags.AllowAnyNodeKind, writer?: EmitTextWriter): string { - let nodeFlags = NodeBuilderFlags.IgnoreErrors; - if (flags & SymbolFormatFlags.UseOnlyExternalAliasing) { - nodeFlags |= NodeBuilderFlags.UseOnlyExternalAliasing; + function symbolToString(symbol: ts.Symbol, enclosingDeclaration?: ts.Node, meaning?: ts.SymbolFlags, flags: ts.SymbolFormatFlags = ts.SymbolFormatFlags.AllowAnyNodeKind, writer?: ts.EmitTextWriter): string { + let nodeFlags = ts.NodeBuilderFlags.IgnoreErrors; + if (flags & ts.SymbolFormatFlags.UseOnlyExternalAliasing) { + nodeFlags |= ts.NodeBuilderFlags.UseOnlyExternalAliasing; } - if (flags & SymbolFormatFlags.WriteTypeParametersOrArguments) { - nodeFlags |= NodeBuilderFlags.WriteTypeParametersInQualifiedName; + if (flags & ts.SymbolFormatFlags.WriteTypeParametersOrArguments) { + nodeFlags |= ts.NodeBuilderFlags.WriteTypeParametersInQualifiedName; } - if (flags & SymbolFormatFlags.UseAliasDefinedOutsideCurrentScope) { - nodeFlags |= NodeBuilderFlags.UseAliasDefinedOutsideCurrentScope; + if (flags & ts.SymbolFormatFlags.UseAliasDefinedOutsideCurrentScope) { + nodeFlags |= ts.NodeBuilderFlags.UseAliasDefinedOutsideCurrentScope; } - if (flags & SymbolFormatFlags.DoNotIncludeSymbolChain) { - nodeFlags |= NodeBuilderFlags.DoNotIncludeSymbolChain; + if (flags & ts.SymbolFormatFlags.DoNotIncludeSymbolChain) { + nodeFlags |= ts.NodeBuilderFlags.DoNotIncludeSymbolChain; } - const builder = flags & SymbolFormatFlags.AllowAnyNodeKind ? nodeBuilder.symbolToExpression : nodeBuilder.symbolToEntityName; - return writer ? symbolToStringWorker(writer).getText() : usingSingleLineStringWriter(symbolToStringWorker); - - function symbolToStringWorker(writer: EmitTextWriter) { + const builder = flags & ts.SymbolFormatFlags.AllowAnyNodeKind ? nodeBuilder.symbolToExpression : nodeBuilder.symbolToEntityName; + return writer ? symbolToStringWorker(writer).getText() : ts.usingSingleLineStringWriter(symbolToStringWorker); + function symbolToStringWorker(writer: ts.EmitTextWriter) { const entity = builder(symbol, meaning!, enclosingDeclaration, nodeFlags)!; // TODO: GH#18217 // add neverAsciiEscape for GH#39027 - const printer = enclosingDeclaration?.kind === SyntaxKind.SourceFile ? createPrinter({ removeComments: true, neverAsciiEscape: true }) : createPrinter({ removeComments: true }); - const sourceFile = enclosingDeclaration && getSourceFileOfNode(enclosingDeclaration); - printer.writeNode(EmitHint.Unspecified, entity, /*sourceFile*/ sourceFile, writer); + const printer = enclosingDeclaration?.kind === ts.SyntaxKind.SourceFile ? ts.createPrinter({ removeComments: true, neverAsciiEscape: true }) : ts.createPrinter({ removeComments: true }); + const sourceFile = enclosingDeclaration && ts.getSourceFileOfNode(enclosingDeclaration); + printer.writeNode(ts.EmitHint.Unspecified, entity, /*sourceFile*/ sourceFile, writer); return writer; } } - function signatureToString(signature: Signature, enclosingDeclaration?: Node, flags = TypeFormatFlags.None, kind?: SignatureKind, writer?: EmitTextWriter): string { - return writer ? signatureToStringWorker(writer).getText() : usingSingleLineStringWriter(signatureToStringWorker); - - function signatureToStringWorker(writer: EmitTextWriter) { - let sigOutput: SyntaxKind; - if (flags & TypeFormatFlags.WriteArrowStyleSignature) { - sigOutput = kind === SignatureKind.Construct ? SyntaxKind.ConstructorType : SyntaxKind.FunctionType; + function signatureToString(signature: ts.Signature, enclosingDeclaration?: ts.Node, flags = ts.TypeFormatFlags.None, kind?: ts.SignatureKind, writer?: ts.EmitTextWriter): string { + return writer ? signatureToStringWorker(writer).getText() : ts.usingSingleLineStringWriter(signatureToStringWorker); + function signatureToStringWorker(writer: ts.EmitTextWriter) { + let sigOutput: ts.SyntaxKind; + if (flags & ts.TypeFormatFlags.WriteArrowStyleSignature) { + sigOutput = kind === ts.SignatureKind.Construct ? ts.SyntaxKind.ConstructorType : ts.SyntaxKind.FunctionType; } else { - sigOutput = kind === SignatureKind.Construct ? SyntaxKind.ConstructSignature : SyntaxKind.CallSignature; + sigOutput = kind === ts.SignatureKind.Construct ? ts.SyntaxKind.ConstructSignature : ts.SyntaxKind.CallSignature; } - const sig = nodeBuilder.signatureToSignatureDeclaration(signature, sigOutput, enclosingDeclaration, toNodeBuilderFlags(flags) | NodeBuilderFlags.IgnoreErrors | NodeBuilderFlags.WriteTypeParametersInQualifiedName); - const printer = createPrinter({ removeComments: true, omitTrailingSemicolon: true }); - const sourceFile = enclosingDeclaration && getSourceFileOfNode(enclosingDeclaration); - printer.writeNode(EmitHint.Unspecified, sig!, /*sourceFile*/ sourceFile, getTrailingSemicolonDeferringWriter(writer)); // TODO: GH#18217 + const sig = nodeBuilder.signatureToSignatureDeclaration(signature, sigOutput, enclosingDeclaration, toNodeBuilderFlags(flags) | ts.NodeBuilderFlags.IgnoreErrors | ts.NodeBuilderFlags.WriteTypeParametersInQualifiedName); + const printer = ts.createPrinter({ removeComments: true, omitTrailingSemicolon: true }); + const sourceFile = enclosingDeclaration && ts.getSourceFileOfNode(enclosingDeclaration); + printer.writeNode(ts.EmitHint.Unspecified, sig!, /*sourceFile*/ sourceFile, ts.getTrailingSemicolonDeferringWriter(writer)); // TODO: GH#18217 return writer; } } - function typeToString(type: Type, enclosingDeclaration?: Node, flags: TypeFormatFlags = TypeFormatFlags.AllowUniqueESSymbolType | TypeFormatFlags.UseAliasDefinedOutsideCurrentScope, writer: EmitTextWriter = createTextWriter("")): string { - const noTruncation = compilerOptions.noErrorTruncation || flags & TypeFormatFlags.NoTruncation; - const typeNode = nodeBuilder.typeToTypeNode(type, enclosingDeclaration, toNodeBuilderFlags(flags) | NodeBuilderFlags.IgnoreErrors | (noTruncation ? NodeBuilderFlags.NoTruncation : 0), writer); - if (typeNode === undefined) return Debug.fail("should always get typenode"); + function typeToString(type: ts.Type, enclosingDeclaration?: ts.Node, flags: ts.TypeFormatFlags = ts.TypeFormatFlags.AllowUniqueESSymbolType | ts.TypeFormatFlags.UseAliasDefinedOutsideCurrentScope, writer: ts.EmitTextWriter = ts.createTextWriter("")): string { + const noTruncation = compilerOptions.noErrorTruncation || flags & ts.TypeFormatFlags.NoTruncation; + const typeNode = nodeBuilder.typeToTypeNode(type, enclosingDeclaration, toNodeBuilderFlags(flags) | ts.NodeBuilderFlags.IgnoreErrors | (noTruncation ? ts.NodeBuilderFlags.NoTruncation : 0), writer); + if (typeNode === undefined) + return ts.Debug.fail("should always get typenode"); // The unresolved type gets a synthesized comment on `any` to hint to users that it's not a plain `any`. // Otherwise, we always strip comments out. const options = { removeComments: type !== unresolvedType }; - const printer = createPrinter(options); - const sourceFile = enclosingDeclaration && getSourceFileOfNode(enclosingDeclaration); - printer.writeNode(EmitHint.Unspecified, typeNode, /*sourceFile*/ sourceFile, writer); + const printer = ts.createPrinter(options); + const sourceFile = enclosingDeclaration && ts.getSourceFileOfNode(enclosingDeclaration); + printer.writeNode(ts.EmitHint.Unspecified, typeNode, /*sourceFile*/ sourceFile, writer); const result = writer.getText(); - const maxLength = noTruncation ? noTruncationMaximumTruncationLength * 2 : defaultMaximumTruncationLength * 2; + const maxLength = noTruncation ? ts.noTruncationMaximumTruncationLength * 2 : ts.defaultMaximumTruncationLength * 2; if (maxLength && result && result.length >= maxLength) { return result.substr(0, maxLength - "...".length) + "..."; } return result; } - function getTypeNamesForErrorDisplay(left: Type, right: Type): [string, string] { + function getTypeNamesForErrorDisplay(left: ts.Type, right: ts.Type): [ + string, + string + ] { let leftStr = symbolValueDeclarationIsContextSensitive(left.symbol) ? typeToString(left, left.symbol.valueDeclaration) : typeToString(left); let rightStr = symbolValueDeclarationIsContextSensitive(right.symbol) ? typeToString(right, right.symbol.valueDeclaration) : typeToString(right); if (leftStr === rightStr) { @@ -4743,56 +4638,47 @@ namespace ts { return [leftStr, rightStr]; } - function getTypeNameForErrorDisplay(type: Type) { - return typeToString(type, /*enclosingDeclaration*/ undefined, TypeFormatFlags.UseFullyQualifiedType); + function getTypeNameForErrorDisplay(type: ts.Type) { + return typeToString(type, /*enclosingDeclaration*/ undefined, ts.TypeFormatFlags.UseFullyQualifiedType); } - function symbolValueDeclarationIsContextSensitive(symbol: Symbol): boolean { - return symbol && !!symbol.valueDeclaration && isExpression(symbol.valueDeclaration) && !isContextSensitive(symbol.valueDeclaration); + function symbolValueDeclarationIsContextSensitive(symbol: ts.Symbol): boolean { + return symbol && !!symbol.valueDeclaration && ts.isExpression(symbol.valueDeclaration) && !isContextSensitive(symbol.valueDeclaration); } - function toNodeBuilderFlags(flags = TypeFormatFlags.None): NodeBuilderFlags { - return flags & TypeFormatFlags.NodeBuilderFlagsMask; + function toNodeBuilderFlags(flags = ts.TypeFormatFlags.None): ts.NodeBuilderFlags { + return flags & ts.TypeFormatFlags.NodeBuilderFlagsMask; } - function isClassInstanceSide(type: Type) { - return !!type.symbol && !!(type.symbol.flags & SymbolFlags.Class) && (type === getDeclaredTypeOfClassOrInterface(type.symbol) || (!!(type.flags & TypeFlags.Object) && !!(getObjectFlags(type) & ObjectFlags.IsClassInstanceClone))); + function isClassInstanceSide(type: ts.Type) { + return !!type.symbol && !!(type.symbol.flags & ts.SymbolFlags.Class) && (type === getDeclaredTypeOfClassOrInterface(type.symbol) || (!!(type.flags & ts.TypeFlags.Object) && !!(ts.getObjectFlags(type) & ts.ObjectFlags.IsClassInstanceClone))); } function createNodeBuilder() { return { - typeToTypeNode: (type: Type, enclosingDeclaration?: Node, flags?: NodeBuilderFlags, tracker?: SymbolTracker) => - withContext(enclosingDeclaration, flags, tracker, context => typeToTypeNodeHelper(type, context)), - indexInfoToIndexSignatureDeclaration: (indexInfo: IndexInfo, enclosingDeclaration?: Node, flags?: NodeBuilderFlags, tracker?: SymbolTracker) => - withContext(enclosingDeclaration, flags, tracker, context => indexInfoToIndexSignatureDeclarationHelper(indexInfo, context, /*typeNode*/ undefined)), - signatureToSignatureDeclaration: (signature: Signature, kind: SignatureDeclaration["kind"], enclosingDeclaration?: Node, flags?: NodeBuilderFlags, tracker?: SymbolTracker) => - withContext(enclosingDeclaration, flags, tracker, context => signatureToSignatureDeclarationHelper(signature, kind, context)), - symbolToEntityName: (symbol: Symbol, meaning: SymbolFlags, enclosingDeclaration?: Node, flags?: NodeBuilderFlags, tracker?: SymbolTracker) => - withContext(enclosingDeclaration, flags, tracker, context => symbolToName(symbol, context, meaning, /*expectsIdentifier*/ false)), - symbolToExpression: (symbol: Symbol, meaning: SymbolFlags, enclosingDeclaration?: Node, flags?: NodeBuilderFlags, tracker?: SymbolTracker) => - withContext(enclosingDeclaration, flags, tracker, context => symbolToExpression(symbol, context, meaning)), - symbolToTypeParameterDeclarations: (symbol: Symbol, enclosingDeclaration?: Node, flags?: NodeBuilderFlags, tracker?: SymbolTracker) => - withContext(enclosingDeclaration, flags, tracker, context => typeParametersToTypeParameterDeclarations(symbol, context)), - symbolToParameterDeclaration: (symbol: Symbol, enclosingDeclaration?: Node, flags?: NodeBuilderFlags, tracker?: SymbolTracker) => - withContext(enclosingDeclaration, flags, tracker, context => symbolToParameterDeclaration(symbol, context)), - typeParameterToDeclaration: (parameter: TypeParameter, enclosingDeclaration?: Node, flags?: NodeBuilderFlags, tracker?: SymbolTracker) => - withContext(enclosingDeclaration, flags, tracker, context => typeParameterToDeclaration(parameter, context)), - symbolTableToDeclarationStatements: (symbolTable: SymbolTable, enclosingDeclaration?: Node, flags?: NodeBuilderFlags, tracker?: SymbolTracker, bundled?: boolean) => - withContext(enclosingDeclaration, flags, tracker, context => symbolTableToDeclarationStatements(symbolTable, context, bundled)), + typeToTypeNode: (type: ts.Type, enclosingDeclaration?: ts.Node, flags?: ts.NodeBuilderFlags, tracker?: ts.SymbolTracker) => withContext(enclosingDeclaration, flags, tracker, context => typeToTypeNodeHelper(type, context)), + indexInfoToIndexSignatureDeclaration: (indexInfo: ts.IndexInfo, enclosingDeclaration?: ts.Node, flags?: ts.NodeBuilderFlags, tracker?: ts.SymbolTracker) => withContext(enclosingDeclaration, flags, tracker, context => indexInfoToIndexSignatureDeclarationHelper(indexInfo, context, /*typeNode*/ undefined)), + signatureToSignatureDeclaration: (signature: ts.Signature, kind: ts.SignatureDeclaration["kind"], enclosingDeclaration?: ts.Node, flags?: ts.NodeBuilderFlags, tracker?: ts.SymbolTracker) => withContext(enclosingDeclaration, flags, tracker, context => signatureToSignatureDeclarationHelper(signature, kind, context)), + symbolToEntityName: (symbol: ts.Symbol, meaning: ts.SymbolFlags, enclosingDeclaration?: ts.Node, flags?: ts.NodeBuilderFlags, tracker?: ts.SymbolTracker) => withContext(enclosingDeclaration, flags, tracker, context => symbolToName(symbol, context, meaning, /*expectsIdentifier*/ false)), + symbolToExpression: (symbol: ts.Symbol, meaning: ts.SymbolFlags, enclosingDeclaration?: ts.Node, flags?: ts.NodeBuilderFlags, tracker?: ts.SymbolTracker) => withContext(enclosingDeclaration, flags, tracker, context => symbolToExpression(symbol, context, meaning)), + symbolToTypeParameterDeclarations: (symbol: ts.Symbol, enclosingDeclaration?: ts.Node, flags?: ts.NodeBuilderFlags, tracker?: ts.SymbolTracker) => withContext(enclosingDeclaration, flags, tracker, context => typeParametersToTypeParameterDeclarations(symbol, context)), + symbolToParameterDeclaration: (symbol: ts.Symbol, enclosingDeclaration?: ts.Node, flags?: ts.NodeBuilderFlags, tracker?: ts.SymbolTracker) => withContext(enclosingDeclaration, flags, tracker, context => symbolToParameterDeclaration(symbol, context)), + typeParameterToDeclaration: (parameter: ts.TypeParameter, enclosingDeclaration?: ts.Node, flags?: ts.NodeBuilderFlags, tracker?: ts.SymbolTracker) => withContext(enclosingDeclaration, flags, tracker, context => typeParameterToDeclaration(parameter, context)), + symbolTableToDeclarationStatements: (symbolTable: ts.SymbolTable, enclosingDeclaration?: ts.Node, flags?: ts.NodeBuilderFlags, tracker?: ts.SymbolTracker, bundled?: boolean) => withContext(enclosingDeclaration, flags, tracker, context => symbolTableToDeclarationStatements(symbolTable, context, bundled)), }; - function withContext(enclosingDeclaration: Node | undefined, flags: NodeBuilderFlags | undefined, tracker: SymbolTracker | undefined, cb: (context: NodeBuilderContext) => T): T | undefined { - Debug.assert(enclosingDeclaration === undefined || (enclosingDeclaration.flags & NodeFlags.Synthesized) === 0); + function withContext(enclosingDeclaration: ts.Node | undefined, flags: ts.NodeBuilderFlags | undefined, tracker: ts.SymbolTracker | undefined, cb: (context: NodeBuilderContext) => T): T | undefined { + ts.Debug.assert(enclosingDeclaration === undefined || (enclosingDeclaration.flags & ts.NodeFlags.Synthesized) === 0); const context: NodeBuilderContext = { enclosingDeclaration, - flags: flags || NodeBuilderFlags.None, + flags: flags || ts.NodeBuilderFlags.None, // If no full tracker is provided, fake up a dummy one with a basic limited-functionality moduleResolverHost - tracker: tracker && tracker.trackSymbol ? tracker : { trackSymbol: () => false, moduleResolverHost: flags! & NodeBuilderFlags.DoNotIncludeSymbolChain ? { - getCommonSourceDirectory: !!(host as Program).getCommonSourceDirectory ? () => (host as Program).getCommonSourceDirectory() : () => "", + tracker: tracker && tracker.trackSymbol ? tracker : { trackSymbol: () => false, moduleResolverHost: flags! & ts.NodeBuilderFlags.DoNotIncludeSymbolChain ? { + getCommonSourceDirectory: !!(host as ts.Program).getCommonSourceDirectory ? () => (host as ts.Program).getCommonSourceDirectory() : () => "", getCurrentDirectory: () => host.getCurrentDirectory(), - getSymlinkCache: maybeBind(host, host.getSymlinkCache), + getSymlinkCache: ts.maybeBind(host, host.getSymlinkCache), getPackageJsonInfoCache: () => host.getPackageJsonInfoCache?.(), - useCaseSensitiveFileNames: maybeBind(host, host.useCaseSensitiveFileNames), + useCaseSensitiveFileNames: ts.maybeBind(host, host.useCaseSensitiveFileNames), redirectTargetsMap: host.redirectTargetsMap, getProjectReferenceRedirect: fileName => host.getProjectReferenceRedirect(fileName), isSourceOfProjectReferenceRedirect: fileName => host.isSourceOfProjectReferenceRedirect(fileName), @@ -4809,13 +4695,13 @@ namespace ts { }; context.tracker = wrapSymbolTrackerToReportForContext(context, context.tracker); const resultingNode = cb(context); - if (context.truncating && context.flags & NodeBuilderFlags.NoTruncation) { + if (context.truncating && context.flags & ts.NodeBuilderFlags.NoTruncation) { context.tracker?.reportTruncationError?.(); } return context.encounteredError ? undefined : resultingNode; } - function wrapSymbolTrackerToReportForContext(context: NodeBuilderContext, tracker: SymbolTracker): SymbolTracker { + function wrapSymbolTrackerToReportForContext(context: NodeBuilderContext, tracker: ts.SymbolTracker): ts.SymbolTracker { const oldTrackSymbol = tracker.trackSymbol; return { ...tracker, @@ -4847,143 +4733,141 @@ namespace ts { } function checkTruncationLength(context: NodeBuilderContext): boolean { - if (context.truncating) return context.truncating; - return context.truncating = context.approximateLength > ((context.flags & NodeBuilderFlags.NoTruncation) ? noTruncationMaximumTruncationLength : defaultMaximumTruncationLength); + if (context.truncating) + return context.truncating; + return context.truncating = context.approximateLength > ((context.flags & ts.NodeBuilderFlags.NoTruncation) ? ts.noTruncationMaximumTruncationLength : ts.defaultMaximumTruncationLength); } - function typeToTypeNodeHelper(type: Type, context: NodeBuilderContext): TypeNode { + function typeToTypeNodeHelper(type: ts.Type, context: NodeBuilderContext): ts.TypeNode { if (cancellationToken && cancellationToken.throwIfCancellationRequested) { cancellationToken.throwIfCancellationRequested(); } - const inTypeAlias = context.flags & NodeBuilderFlags.InTypeAlias; - context.flags &= ~NodeBuilderFlags.InTypeAlias; + const inTypeAlias = context.flags & ts.NodeBuilderFlags.InTypeAlias; + context.flags &= ~ts.NodeBuilderFlags.InTypeAlias; if (!type) { - if (!(context.flags & NodeBuilderFlags.AllowEmptyUnionOrIntersection)) { + if (!(context.flags & ts.NodeBuilderFlags.AllowEmptyUnionOrIntersection)) { context.encounteredError = true; return undefined!; // TODO: GH#18217 } context.approximateLength += 3; - return factory.createKeywordTypeNode(SyntaxKind.AnyKeyword); + return ts.factory.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword); } - if (!(context.flags & NodeBuilderFlags.NoTypeReduction)) { + if (!(context.flags & ts.NodeBuilderFlags.NoTypeReduction)) { type = getReducedType(type); } - if (type.flags & TypeFlags.Any) { + if (type.flags & ts.TypeFlags.Any) { if (type.aliasSymbol) { - return factory.createTypeReferenceNode(symbolToEntityNameNode(type.aliasSymbol), mapToTypeNodes(type.aliasTypeArguments, context)); + return ts.factory.createTypeReferenceNode(symbolToEntityNameNode(type.aliasSymbol), mapToTypeNodes(type.aliasTypeArguments, context)); } if (type === unresolvedType) { - return addSyntheticLeadingComment(factory.createKeywordTypeNode(SyntaxKind.AnyKeyword), SyntaxKind.MultiLineCommentTrivia, "unresolved"); + return ts.addSyntheticLeadingComment(ts.factory.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword), ts.SyntaxKind.MultiLineCommentTrivia, "unresolved"); } context.approximateLength += 3; - return factory.createKeywordTypeNode(type === intrinsicMarkerType ? SyntaxKind.IntrinsicKeyword : SyntaxKind.AnyKeyword); + return ts.factory.createKeywordTypeNode(type === intrinsicMarkerType ? ts.SyntaxKind.IntrinsicKeyword : ts.SyntaxKind.AnyKeyword); } - if (type.flags & TypeFlags.Unknown) { - return factory.createKeywordTypeNode(SyntaxKind.UnknownKeyword); + if (type.flags & ts.TypeFlags.Unknown) { + return ts.factory.createKeywordTypeNode(ts.SyntaxKind.UnknownKeyword); } - if (type.flags & TypeFlags.String) { + if (type.flags & ts.TypeFlags.String) { context.approximateLength += 6; - return factory.createKeywordTypeNode(SyntaxKind.StringKeyword); + return ts.factory.createKeywordTypeNode(ts.SyntaxKind.StringKeyword); } - if (type.flags & TypeFlags.Number) { + if (type.flags & ts.TypeFlags.Number) { context.approximateLength += 6; - return factory.createKeywordTypeNode(SyntaxKind.NumberKeyword); + return ts.factory.createKeywordTypeNode(ts.SyntaxKind.NumberKeyword); } - if (type.flags & TypeFlags.BigInt) { + if (type.flags & ts.TypeFlags.BigInt) { context.approximateLength += 6; - return factory.createKeywordTypeNode(SyntaxKind.BigIntKeyword); + return ts.factory.createKeywordTypeNode(ts.SyntaxKind.BigIntKeyword); } - if (type.flags & TypeFlags.Boolean && !type.aliasSymbol) { + if (type.flags & ts.TypeFlags.Boolean && !type.aliasSymbol) { context.approximateLength += 7; - return factory.createKeywordTypeNode(SyntaxKind.BooleanKeyword); + return ts.factory.createKeywordTypeNode(ts.SyntaxKind.BooleanKeyword); } - if (type.flags & TypeFlags.EnumLiteral && !(type.flags & TypeFlags.Union)) { + if (type.flags & ts.TypeFlags.EnumLiteral && !(type.flags & ts.TypeFlags.Union)) { const parentSymbol = getParentOfSymbol(type.symbol)!; - const parentName = symbolToTypeNode(parentSymbol, context, SymbolFlags.Type); + const parentName = symbolToTypeNode(parentSymbol, context, ts.SymbolFlags.Type); if (getDeclaredTypeOfSymbol(parentSymbol) === type) { return parentName; } - const memberName = symbolName(type.symbol); - if (isIdentifierText(memberName, ScriptTarget.ES3)) { - return appendReferenceToType( - parentName as TypeReferenceNode | ImportTypeNode, - factory.createTypeReferenceNode(memberName, /*typeArguments*/ undefined) - ); + const memberName = ts.symbolName(type.symbol); + if (ts.isIdentifierText(memberName, ts.ScriptTarget.ES3)) { + return appendReferenceToType(parentName as ts.TypeReferenceNode | ts.ImportTypeNode, ts.factory.createTypeReferenceNode(memberName, /*typeArguments*/ undefined)); } - if (isImportTypeNode(parentName)) { + if (ts.isImportTypeNode(parentName)) { (parentName as any).isTypeOf = true; // mutably update, node is freshly manufactured anyhow - return factory.createIndexedAccessTypeNode(parentName, factory.createLiteralTypeNode(factory.createStringLiteral(memberName))); + return ts.factory.createIndexedAccessTypeNode(parentName, ts.factory.createLiteralTypeNode(ts.factory.createStringLiteral(memberName))); } - else if (isTypeReferenceNode(parentName)) { - return factory.createIndexedAccessTypeNode(factory.createTypeQueryNode(parentName.typeName), factory.createLiteralTypeNode(factory.createStringLiteral(memberName))); + else if (ts.isTypeReferenceNode(parentName)) { + return ts.factory.createIndexedAccessTypeNode(ts.factory.createTypeQueryNode(parentName.typeName), ts.factory.createLiteralTypeNode(ts.factory.createStringLiteral(memberName))); } else { - return Debug.fail("Unhandled type node kind returned from `symbolToTypeNode`."); + return ts.Debug.fail("Unhandled type node kind returned from `symbolToTypeNode`."); } } - if (type.flags & TypeFlags.EnumLike) { - return symbolToTypeNode(type.symbol, context, SymbolFlags.Type); + if (type.flags & ts.TypeFlags.EnumLike) { + return symbolToTypeNode(type.symbol, context, ts.SymbolFlags.Type); } - if (type.flags & TypeFlags.StringLiteral) { - context.approximateLength += ((type as StringLiteralType).value.length + 2); - return factory.createLiteralTypeNode(setEmitFlags(factory.createStringLiteral((type as StringLiteralType).value, !!(context.flags & NodeBuilderFlags.UseSingleQuotesForStringLiteralType)), EmitFlags.NoAsciiEscaping)); + if (type.flags & ts.TypeFlags.StringLiteral) { + context.approximateLength += ((type as ts.StringLiteralType).value.length + 2); + return ts.factory.createLiteralTypeNode(ts.setEmitFlags(ts.factory.createStringLiteral((type as ts.StringLiteralType).value, !!(context.flags & ts.NodeBuilderFlags.UseSingleQuotesForStringLiteralType)), ts.EmitFlags.NoAsciiEscaping)); } - if (type.flags & TypeFlags.NumberLiteral) { - const value = (type as NumberLiteralType).value; + if (type.flags & ts.TypeFlags.NumberLiteral) { + const value = (type as ts.NumberLiteralType).value; context.approximateLength += ("" + value).length; - return factory.createLiteralTypeNode(value < 0 ? factory.createPrefixUnaryExpression(SyntaxKind.MinusToken, factory.createNumericLiteral(-value)) : factory.createNumericLiteral(value)); + return ts.factory.createLiteralTypeNode(value < 0 ? ts.factory.createPrefixUnaryExpression(ts.SyntaxKind.MinusToken, ts.factory.createNumericLiteral(-value)) : ts.factory.createNumericLiteral(value)); } - if (type.flags & TypeFlags.BigIntLiteral) { - context.approximateLength += (pseudoBigIntToString((type as BigIntLiteralType).value).length) + 1; - return factory.createLiteralTypeNode((factory.createBigIntLiteral((type as BigIntLiteralType).value))); + if (type.flags & ts.TypeFlags.BigIntLiteral) { + context.approximateLength += (ts.pseudoBigIntToString((type as ts.BigIntLiteralType).value).length) + 1; + return ts.factory.createLiteralTypeNode((ts.factory.createBigIntLiteral((type as ts.BigIntLiteralType).value))); } - if (type.flags & TypeFlags.BooleanLiteral) { - context.approximateLength += (type as IntrinsicType).intrinsicName.length; - return factory.createLiteralTypeNode((type as IntrinsicType).intrinsicName === "true" ? factory.createTrue() : factory.createFalse()); + if (type.flags & ts.TypeFlags.BooleanLiteral) { + context.approximateLength += (type as ts.IntrinsicType).intrinsicName.length; + return ts.factory.createLiteralTypeNode((type as ts.IntrinsicType).intrinsicName === "true" ? ts.factory.createTrue() : ts.factory.createFalse()); } - if (type.flags & TypeFlags.UniqueESSymbol) { - if (!(context.flags & NodeBuilderFlags.AllowUniqueESSymbolType)) { + if (type.flags & ts.TypeFlags.UniqueESSymbol) { + if (!(context.flags & ts.NodeBuilderFlags.AllowUniqueESSymbolType)) { if (isValueSymbolAccessible(type.symbol, context.enclosingDeclaration)) { context.approximateLength += 6; - return symbolToTypeNode(type.symbol, context, SymbolFlags.Value); + return symbolToTypeNode(type.symbol, context, ts.SymbolFlags.Value); } if (context.tracker.reportInaccessibleUniqueSymbolError) { context.tracker.reportInaccessibleUniqueSymbolError(); } } context.approximateLength += 13; - return factory.createTypeOperatorNode(SyntaxKind.UniqueKeyword, factory.createKeywordTypeNode(SyntaxKind.SymbolKeyword)); + return ts.factory.createTypeOperatorNode(ts.SyntaxKind.UniqueKeyword, ts.factory.createKeywordTypeNode(ts.SyntaxKind.SymbolKeyword)); } - if (type.flags & TypeFlags.Void) { + if (type.flags & ts.TypeFlags.Void) { context.approximateLength += 4; - return factory.createKeywordTypeNode(SyntaxKind.VoidKeyword); + return ts.factory.createKeywordTypeNode(ts.SyntaxKind.VoidKeyword); } - if (type.flags & TypeFlags.Undefined) { + if (type.flags & ts.TypeFlags.Undefined) { context.approximateLength += 9; - return factory.createKeywordTypeNode(SyntaxKind.UndefinedKeyword); + return ts.factory.createKeywordTypeNode(ts.SyntaxKind.UndefinedKeyword); } - if (type.flags & TypeFlags.Null) { + if (type.flags & ts.TypeFlags.Null) { context.approximateLength += 4; - return factory.createLiteralTypeNode(factory.createNull()); + return ts.factory.createLiteralTypeNode(ts.factory.createNull()); } - if (type.flags & TypeFlags.Never) { + if (type.flags & ts.TypeFlags.Never) { context.approximateLength += 5; - return factory.createKeywordTypeNode(SyntaxKind.NeverKeyword); + return ts.factory.createKeywordTypeNode(ts.SyntaxKind.NeverKeyword); } - if (type.flags & TypeFlags.ESSymbol) { + if (type.flags & ts.TypeFlags.ESSymbol) { context.approximateLength += 6; - return factory.createKeywordTypeNode(SyntaxKind.SymbolKeyword); + return ts.factory.createKeywordTypeNode(ts.SyntaxKind.SymbolKeyword); } - if (type.flags & TypeFlags.NonPrimitive) { + if (type.flags & ts.TypeFlags.NonPrimitive) { context.approximateLength += 6; - return factory.createKeywordTypeNode(SyntaxKind.ObjectKeyword); + return ts.factory.createKeywordTypeNode(ts.SyntaxKind.ObjectKeyword); } - if (isThisTypeParameter(type)) { - if (context.flags & NodeBuilderFlags.InObjectTypeLiteral) { - if (!context.encounteredError && !(context.flags & NodeBuilderFlags.AllowThisInObjectLiteral)) { + if (ts.isThisTypeParameter(type)) { + if (context.flags & ts.NodeBuilderFlags.InObjectTypeLiteral) { + if (!context.encounteredError && !(context.flags & ts.NodeBuilderFlags.AllowThisInObjectLiteral)) { context.encounteredError = true; } if (context.tracker.reportInaccessibleThisError) { @@ -4991,122 +4875,116 @@ namespace ts { } } context.approximateLength += 4; - return factory.createThisTypeNode(); + return ts.factory.createThisTypeNode(); } - if (!inTypeAlias && type.aliasSymbol && (context.flags & NodeBuilderFlags.UseAliasDefinedOutsideCurrentScope || isTypeSymbolAccessible(type.aliasSymbol, context.enclosingDeclaration))) { + if (!inTypeAlias && type.aliasSymbol && (context.flags & ts.NodeBuilderFlags.UseAliasDefinedOutsideCurrentScope || isTypeSymbolAccessible(type.aliasSymbol, context.enclosingDeclaration))) { const typeArgumentNodes = mapToTypeNodes(type.aliasTypeArguments, context); - if (isReservedMemberName(type.aliasSymbol.escapedName) && !(type.aliasSymbol.flags & SymbolFlags.Class)) return factory.createTypeReferenceNode(factory.createIdentifier(""), typeArgumentNodes); - return symbolToTypeNode(type.aliasSymbol, context, SymbolFlags.Type, typeArgumentNodes); - } - - const objectFlags = getObjectFlags(type); - - if (objectFlags & ObjectFlags.Reference) { - Debug.assert(!!(type.flags & TypeFlags.Object)); - return (type as TypeReference).node ? visitAndTransformType(type, typeReferenceToTypeNode) : typeReferenceToTypeNode(type as TypeReference); - } - if (type.flags & TypeFlags.TypeParameter || objectFlags & ObjectFlags.ClassOrInterface) { - if (type.flags & TypeFlags.TypeParameter && contains(context.inferTypeParameters, type)) { - context.approximateLength += (symbolName(type.symbol).length + 6); - let constraintNode: TypeNode | undefined; - const constraint = getConstraintOfTypeParameter(type as TypeParameter); + if (isReservedMemberName(type.aliasSymbol.escapedName) && !(type.aliasSymbol.flags & ts.SymbolFlags.Class)) + return ts.factory.createTypeReferenceNode(ts.factory.createIdentifier(""), typeArgumentNodes); + return symbolToTypeNode(type.aliasSymbol, context, ts.SymbolFlags.Type, typeArgumentNodes); + } + const objectFlags = ts.getObjectFlags(type); + if (objectFlags & ts.ObjectFlags.Reference) { + ts.Debug.assert(!!(type.flags & ts.TypeFlags.Object)); + return (type as ts.TypeReference).node ? visitAndTransformType(type, typeReferenceToTypeNode) : typeReferenceToTypeNode(type as ts.TypeReference); + } + if (type.flags & ts.TypeFlags.TypeParameter || objectFlags & ts.ObjectFlags.ClassOrInterface) { + if (type.flags & ts.TypeFlags.TypeParameter && ts.contains(context.inferTypeParameters, type)) { + context.approximateLength += (ts.symbolName(type.symbol).length + 6); + let constraintNode: ts.TypeNode | undefined; + const constraint = getConstraintOfTypeParameter(type as ts.TypeParameter); if (constraint) { // If the infer type has a constraint that is not the same as the constraint // we would have normally inferred based on context, we emit the constraint // using `infer T extends ?`. We omit inferred constraints from type references // as they may be elided. - const inferredConstraint = getInferredTypeParameterConstraint(type as TypeParameter, /*omitTypeReferences*/ true); + const inferredConstraint = getInferredTypeParameterConstraint(type as ts.TypeParameter, /*omitTypeReferences*/ true); if (!(inferredConstraint && isTypeIdenticalTo(constraint, inferredConstraint))) { context.approximateLength += 9; constraintNode = constraint && typeToTypeNodeHelper(constraint, context); } } - return factory.createInferTypeNode(typeParameterToDeclarationWithConstraint(type as TypeParameter, context, constraintNode)); + return ts.factory.createInferTypeNode(typeParameterToDeclarationWithConstraint(type as ts.TypeParameter, context, constraintNode)); } - if (context.flags & NodeBuilderFlags.GenerateNamesForShadowedTypeParams && - type.flags & TypeFlags.TypeParameter && + if (context.flags & ts.NodeBuilderFlags.GenerateNamesForShadowedTypeParams && + type.flags & ts.TypeFlags.TypeParameter && !isTypeSymbolAccessible(type.symbol, context.enclosingDeclaration)) { const name = typeParameterToName(type, context); - context.approximateLength += idText(name).length; - return factory.createTypeReferenceNode(factory.createIdentifier(idText(name)), /*typeArguments*/ undefined); + context.approximateLength += ts.idText(name).length; + return ts.factory.createTypeReferenceNode(ts.factory.createIdentifier(ts.idText(name)), /*typeArguments*/ undefined); } // Ignore constraint/default when creating a usage (as opposed to declaration) of a type parameter. if (type.symbol) { - return symbolToTypeNode(type.symbol, context, SymbolFlags.Type); + return symbolToTypeNode(type.symbol, context, ts.SymbolFlags.Type); } const name = (type === markerSuperType || type === markerSubType) && varianceTypeParameter && varianceTypeParameter.symbol ? - (type === markerSubType ? "sub-" : "super-") + symbolName(varianceTypeParameter.symbol) : "?"; - return factory.createTypeReferenceNode(factory.createIdentifier(name), /*typeArguments*/ undefined); + (type === markerSubType ? "sub-" : "super-") + ts.symbolName(varianceTypeParameter.symbol) : "?"; + return ts.factory.createTypeReferenceNode(ts.factory.createIdentifier(name), /*typeArguments*/ undefined); } - if (type.flags & TypeFlags.Union && (type as UnionType).origin) { - type = (type as UnionType).origin!; + if (type.flags & ts.TypeFlags.Union && (type as ts.UnionType).origin) { + type = (type as ts.UnionType).origin!; } - if (type.flags & (TypeFlags.Union | TypeFlags.Intersection)) { - const types = type.flags & TypeFlags.Union ? formatUnionTypes((type as UnionType).types) : (type as IntersectionType).types; - if (length(types) === 1) { + if (type.flags & (ts.TypeFlags.Union | ts.TypeFlags.Intersection)) { + const types = type.flags & ts.TypeFlags.Union ? formatUnionTypes((type as ts.UnionType).types) : (type as ts.IntersectionType).types; + if (ts.length(types) === 1) { return typeToTypeNodeHelper(types[0], context); } const typeNodes = mapToTypeNodes(types, context, /*isBareList*/ true); if (typeNodes && typeNodes.length > 0) { - return type.flags & TypeFlags.Union ? factory.createUnionTypeNode(typeNodes) : factory.createIntersectionTypeNode(typeNodes); + return type.flags & ts.TypeFlags.Union ? ts.factory.createUnionTypeNode(typeNodes) : ts.factory.createIntersectionTypeNode(typeNodes); } else { - if (!context.encounteredError && !(context.flags & NodeBuilderFlags.AllowEmptyUnionOrIntersection)) { + if (!context.encounteredError && !(context.flags & ts.NodeBuilderFlags.AllowEmptyUnionOrIntersection)) { context.encounteredError = true; } return undefined!; // TODO: GH#18217 } } - if (objectFlags & (ObjectFlags.Anonymous | ObjectFlags.Mapped)) { - Debug.assert(!!(type.flags & TypeFlags.Object)); + if (objectFlags & (ts.ObjectFlags.Anonymous | ts.ObjectFlags.Mapped)) { + ts.Debug.assert(!!(type.flags & ts.TypeFlags.Object)); // The type is an object literal type. - return createAnonymousTypeNode(type as ObjectType); + return createAnonymousTypeNode(type as ts.ObjectType); } - if (type.flags & TypeFlags.Index) { - const indexedType = (type as IndexType).type; + if (type.flags & ts.TypeFlags.Index) { + const indexedType = (type as ts.IndexType).type; context.approximateLength += 6; const indexTypeNode = typeToTypeNodeHelper(indexedType, context); - return factory.createTypeOperatorNode(SyntaxKind.KeyOfKeyword, indexTypeNode); - } - if (type.flags & TypeFlags.TemplateLiteral) { - const texts = (type as TemplateLiteralType).texts; - const types = (type as TemplateLiteralType).types; - const templateHead = factory.createTemplateHead(texts[0]); - const templateSpans = factory.createNodeArray( - map(types, (t, i) => factory.createTemplateLiteralTypeSpan( - typeToTypeNodeHelper(t, context), - (i < types.length - 1 ? factory.createTemplateMiddle : factory.createTemplateTail)(texts[i + 1])))); + return ts.factory.createTypeOperatorNode(ts.SyntaxKind.KeyOfKeyword, indexTypeNode); + } + if (type.flags & ts.TypeFlags.TemplateLiteral) { + const texts = (type as ts.TemplateLiteralType).texts; + const types = (type as ts.TemplateLiteralType).types; + const templateHead = ts.factory.createTemplateHead(texts[0]); + const templateSpans = ts.factory.createNodeArray(ts.map(types, (t, i) => ts.factory.createTemplateLiteralTypeSpan(typeToTypeNodeHelper(t, context), (i < types.length - 1 ? ts.factory.createTemplateMiddle : ts.factory.createTemplateTail)(texts[i + 1])))); context.approximateLength += 2; - return factory.createTemplateLiteralType(templateHead, templateSpans); + return ts.factory.createTemplateLiteralType(templateHead, templateSpans); } - if (type.flags & TypeFlags.StringMapping) { - const typeNode = typeToTypeNodeHelper((type as StringMappingType).type, context); - return symbolToTypeNode((type as StringMappingType).symbol, context, SymbolFlags.Type, [typeNode]); + if (type.flags & ts.TypeFlags.StringMapping) { + const typeNode = typeToTypeNodeHelper((type as ts.StringMappingType).type, context); + return symbolToTypeNode((type as ts.StringMappingType).symbol, context, ts.SymbolFlags.Type, [typeNode]); } - if (type.flags & TypeFlags.IndexedAccess) { - const objectTypeNode = typeToTypeNodeHelper((type as IndexedAccessType).objectType, context); - const indexTypeNode = typeToTypeNodeHelper((type as IndexedAccessType).indexType, context); + if (type.flags & ts.TypeFlags.IndexedAccess) { + const objectTypeNode = typeToTypeNodeHelper((type as ts.IndexedAccessType).objectType, context); + const indexTypeNode = typeToTypeNodeHelper((type as ts.IndexedAccessType).indexType, context); context.approximateLength += 2; - return factory.createIndexedAccessTypeNode(objectTypeNode, indexTypeNode); + return ts.factory.createIndexedAccessTypeNode(objectTypeNode, indexTypeNode); } - if (type.flags & TypeFlags.Conditional) { - return visitAndTransformType(type, type => conditionalTypeToTypeNode(type as ConditionalType)); + if (type.flags & ts.TypeFlags.Conditional) { + return visitAndTransformType(type, type => conditionalTypeToTypeNode(type as ts.ConditionalType)); } - if (type.flags & TypeFlags.Substitution) { - return typeToTypeNodeHelper((type as SubstitutionType).baseType, context); + if (type.flags & ts.TypeFlags.Substitution) { + return typeToTypeNodeHelper((type as ts.SubstitutionType).baseType, context); } - return Debug.fail("Should be unreachable."); - - - function conditionalTypeToTypeNode(type: ConditionalType) { + return ts.Debug.fail("Should be unreachable."); + function conditionalTypeToTypeNode(type: ts.ConditionalType) { const checkTypeNode = typeToTypeNodeHelper(type.checkType, context); context.approximateLength += 15; - if (context.flags & NodeBuilderFlags.GenerateNamesForShadowedTypeParams && type.root.isDistributive && !(type.checkType.flags & TypeFlags.TypeParameter)) { - const newParam = createTypeParameter(createSymbol(SymbolFlags.TypeParameter, "T" as __String)); + if (context.flags & ts.NodeBuilderFlags.GenerateNamesForShadowedTypeParams && type.root.isDistributive && !(type.checkType.flags & ts.TypeFlags.TypeParameter)) { + const newParam = createTypeParameter(createSymbol(ts.SymbolFlags.TypeParameter, "T" as ts.__String)); const name = typeParameterToName(newParam, context); - const newTypeVariable = factory.createTypeReferenceNode(name); + const newTypeVariable = ts.factory.createTypeReferenceNode(name); context.approximateLength += 37; // 15 each for two added conditionals, 7 for an added infer type const newMapper = prependTypeMapping(type.root.checkType, newParam, type.combinedMapper || type.mapper); const saveInferTypeParameters = context.inferTypeParameters; @@ -5127,17 +5005,7 @@ namespace ts { // On the other hand, // checkType extends infer T extends checkType ? T extends extendsType ? trueType : falseType : never; // may also work with `infer ... extends ...` in, but would produce declarations only compatible with the latest TS. - return factory.createConditionalTypeNode( - checkTypeNode, - factory.createInferTypeNode(factory.createTypeParameterDeclaration(/*modifiers*/ undefined, factory.cloneNode(newTypeVariable.typeName) as Identifier)), - factory.createConditionalTypeNode( - factory.createTypeReferenceNode(factory.cloneNode(name)), - typeToTypeNodeHelper(type.checkType, context), - factory.createConditionalTypeNode(newTypeVariable, extendsTypeNode, trueTypeNode, falseTypeNode), - factory.createKeywordTypeNode(SyntaxKind.NeverKeyword) - ), - factory.createKeywordTypeNode(SyntaxKind.NeverKeyword) - ); + return ts.factory.createConditionalTypeNode(checkTypeNode, ts.factory.createInferTypeNode(ts.factory.createTypeParameterDeclaration(/*modifiers*/ undefined, ts.factory.cloneNode(newTypeVariable.typeName) as ts.Identifier)), ts.factory.createConditionalTypeNode(ts.factory.createTypeReferenceNode(ts.factory.cloneNode(name)), typeToTypeNodeHelper(type.checkType, context), ts.factory.createConditionalTypeNode(newTypeVariable, extendsTypeNode, trueTypeNode, falseTypeNode), ts.factory.createKeywordTypeNode(ts.SyntaxKind.NeverKeyword)), ts.factory.createKeywordTypeNode(ts.SyntaxKind.NeverKeyword)); } const saveInferTypeParameters = context.inferTypeParameters; context.inferTypeParameters = type.root.inferTypeParameters; @@ -5145,13 +5013,13 @@ namespace ts { context.inferTypeParameters = saveInferTypeParameters; const trueTypeNode = typeToTypeNodeOrCircularityElision(getTrueTypeFromConditionalType(type)); const falseTypeNode = typeToTypeNodeOrCircularityElision(getFalseTypeFromConditionalType(type)); - return factory.createConditionalTypeNode(checkTypeNode, extendsTypeNode, trueTypeNode, falseTypeNode); + return ts.factory.createConditionalTypeNode(checkTypeNode, extendsTypeNode, trueTypeNode, falseTypeNode); } - function typeToTypeNodeOrCircularityElision(type: Type) { - if (type.flags & TypeFlags.Union) { + function typeToTypeNodeOrCircularityElision(type: ts.Type) { + if (type.flags & ts.TypeFlags.Union) { if (context.visitedTypes?.has(getTypeId(type))) { - if (!(context.flags & NodeBuilderFlags.AllowAnonymousIdentifier)) { + if (!(context.flags & ts.NodeBuilderFlags.AllowAnonymousIdentifier)) { context.encounteredError = true; context.tracker?.reportCyclicStructureError?.(); } @@ -5162,21 +5030,21 @@ namespace ts { return typeToTypeNodeHelper(type, context); } - function createMappedTypeNodeFromType(type: MappedType) { - Debug.assert(!!(type.flags & TypeFlags.Object)); - const readonlyToken = type.declaration.readonlyToken ? factory.createToken(type.declaration.readonlyToken.kind) as ReadonlyKeyword | PlusToken | MinusToken : undefined; - const questionToken = type.declaration.questionToken ? factory.createToken(type.declaration.questionToken.kind) as QuestionToken | PlusToken | MinusToken : undefined; - let appropriateConstraintTypeNode: TypeNode; - let newTypeVariable: TypeReferenceNode | undefined; + function createMappedTypeNodeFromType(type: ts.MappedType) { + ts.Debug.assert(!!(type.flags & ts.TypeFlags.Object)); + const readonlyToken = type.declaration.readonlyToken ? ts.factory.createToken(type.declaration.readonlyToken.kind) as ts.ReadonlyKeyword | ts.PlusToken | ts.MinusToken : undefined; + const questionToken = type.declaration.questionToken ? ts.factory.createToken(type.declaration.questionToken.kind) as ts.QuestionToken | ts.PlusToken | ts.MinusToken : undefined; + let appropriateConstraintTypeNode: ts.TypeNode; + let newTypeVariable: ts.TypeReferenceNode | undefined; if (isMappedTypeWithKeyofConstraintDeclaration(type)) { // We have a { [P in keyof T]: X } // We do this to ensure we retain the toplevel keyof-ness of the type which may be lost due to keyof distribution during `getConstraintTypeFromMappedType` - if (!(getModifiersTypeFromMappedType(type).flags & TypeFlags.TypeParameter) && context.flags & NodeBuilderFlags.GenerateNamesForShadowedTypeParams) { - const newParam = createTypeParameter(createSymbol(SymbolFlags.TypeParameter, "T" as __String)); + if (!(getModifiersTypeFromMappedType(type).flags & ts.TypeFlags.TypeParameter) && context.flags & ts.NodeBuilderFlags.GenerateNamesForShadowedTypeParams) { + const newParam = createTypeParameter(createSymbol(ts.SymbolFlags.TypeParameter, "T" as ts.__String)); const name = typeParameterToName(newParam, context); - newTypeVariable = factory.createTypeReferenceNode(name); + newTypeVariable = ts.factory.createTypeReferenceNode(name); } - appropriateConstraintTypeNode = factory.createTypeOperatorNode(SyntaxKind.KeyOfKeyword, newTypeVariable || typeToTypeNodeHelper(getModifiersTypeFromMappedType(type), context)); + appropriateConstraintTypeNode = ts.factory.createTypeOperatorNode(ts.SyntaxKind.KeyOfKeyword, newTypeVariable || typeToTypeNodeHelper(getModifiersTypeFromMappedType(type), context)); } else { appropriateConstraintTypeNode = typeToTypeNodeHelper(getConstraintTypeFromMappedType(type), context); @@ -5184,37 +5052,32 @@ namespace ts { const typeParameterNode = typeParameterToDeclarationWithConstraint(getTypeParameterFromMappedType(type), context, appropriateConstraintTypeNode); const nameTypeNode = type.declaration.nameType ? typeToTypeNodeHelper(getNameTypeFromMappedType(type)!, context) : undefined; const templateTypeNode = typeToTypeNodeHelper(removeMissingType(getTemplateTypeFromMappedType(type), !!(getMappedTypeModifiers(type) & MappedTypeModifiers.IncludeOptional)), context); - const mappedTypeNode = factory.createMappedTypeNode(readonlyToken, typeParameterNode, nameTypeNode, questionToken, templateTypeNode, /*members*/ undefined); + const mappedTypeNode = ts.factory.createMappedTypeNode(readonlyToken, typeParameterNode, nameTypeNode, questionToken, templateTypeNode, /*members*/ undefined); context.approximateLength += 10; - const result = setEmitFlags(mappedTypeNode, EmitFlags.SingleLine); - if (isMappedTypeWithKeyofConstraintDeclaration(type) && !(getModifiersTypeFromMappedType(type).flags & TypeFlags.TypeParameter) && context.flags & NodeBuilderFlags.GenerateNamesForShadowedTypeParams) { + const result = ts.setEmitFlags(mappedTypeNode, ts.EmitFlags.SingleLine); + if (isMappedTypeWithKeyofConstraintDeclaration(type) && !(getModifiersTypeFromMappedType(type).flags & ts.TypeFlags.TypeParameter) && context.flags & ts.NodeBuilderFlags.GenerateNamesForShadowedTypeParams) { // homomorphic mapped type with a non-homomorphic naive inlining // wrap it with a conditional like `SomeModifiersType extends infer U ? {..the mapped type...} : never` to ensure the resulting // type stays homomorphic - return factory.createConditionalTypeNode( - typeToTypeNodeHelper(getModifiersTypeFromMappedType(type), context), - factory.createInferTypeNode(factory.createTypeParameterDeclaration(/*modifiers*/ undefined, factory.cloneNode(newTypeVariable!.typeName) as Identifier)), - result, - factory.createKeywordTypeNode(SyntaxKind.NeverKeyword) - ); + return ts.factory.createConditionalTypeNode(typeToTypeNodeHelper(getModifiersTypeFromMappedType(type), context), ts.factory.createInferTypeNode(ts.factory.createTypeParameterDeclaration(/*modifiers*/ undefined, ts.factory.cloneNode(newTypeVariable!.typeName) as ts.Identifier)), result, ts.factory.createKeywordTypeNode(ts.SyntaxKind.NeverKeyword)); } return result; } - function createAnonymousTypeNode(type: ObjectType): TypeNode { + function createAnonymousTypeNode(type: ts.ObjectType): ts.TypeNode { const typeId = type.id; const symbol = type.symbol; if (symbol) { - const isInstanceType = isClassInstanceSide(type) ? SymbolFlags.Type : SymbolFlags.Value; + const isInstanceType = isClassInstanceSide(type) ? ts.SymbolFlags.Type : ts.SymbolFlags.Value; if (isJSConstructor(symbol.valueDeclaration)) { // Instance and static types share the same symbol; only add 'typeof' for the static side. return symbolToTypeNode(symbol, context, isInstanceType); } // Always use 'typeof T' for type of class, enum, and module objects - else if (symbol.flags & SymbolFlags.Class + else if (symbol.flags & ts.SymbolFlags.Class && !getBaseTypeVariableOfClass(symbol) - && !(symbol.valueDeclaration && symbol.valueDeclaration.kind === SyntaxKind.ClassExpression && context.flags & NodeBuilderFlags.WriteClassExpressionAsTypeLiteral) || - symbol.flags & (SymbolFlags.Enum | SymbolFlags.ValueModule) || + && !(symbol.valueDeclaration && symbol.valueDeclaration.kind === ts.SyntaxKind.ClassExpression && context.flags & ts.NodeBuilderFlags.WriteClassExpressionAsTypeLiteral) || + symbol.flags & (ts.SymbolFlags.Enum | ts.SymbolFlags.ValueModule) || shouldWriteTypeOfFunctionSymbol()) { return symbolToTypeNode(symbol, context, isInstanceType); } @@ -5223,7 +5086,7 @@ namespace ts { const typeAlias = getTypeAliasForTypeLiteral(type); if (typeAlias) { // The specified symbol flags need to be reinterpreted as type flags - return symbolToTypeNode(typeAlias, context, SymbolFlags.Type); + return symbolToTypeNode(typeAlias, context, ts.SymbolFlags.Type); } else { return createElidedInformationPlaceholder(context); @@ -5238,40 +5101,39 @@ namespace ts { return createTypeNodeFromObjectType(type); } function shouldWriteTypeOfFunctionSymbol() { - const isStaticMethodSymbol = !!(symbol.flags & SymbolFlags.Method) && // typeof static method - some(symbol.declarations, declaration => isStatic(declaration)); - const isNonLocalFunctionSymbol = !!(symbol.flags & SymbolFlags.Function) && + const isStaticMethodSymbol = !!(symbol.flags & ts.SymbolFlags.Method) && // typeof static method + ts.some(symbol.declarations, declaration => ts.isStatic(declaration)); + const isNonLocalFunctionSymbol = !!(symbol.flags & ts.SymbolFlags.Function) && (symbol.parent || // is exported function symbol - forEach(symbol.declarations, declaration => - declaration.parent.kind === SyntaxKind.SourceFile || declaration.parent.kind === SyntaxKind.ModuleBlock)); + ts.forEach(symbol.declarations, declaration => declaration.parent.kind === ts.SyntaxKind.SourceFile || declaration.parent.kind === ts.SyntaxKind.ModuleBlock)); if (isStaticMethodSymbol || isNonLocalFunctionSymbol) { // typeof is allowed only for static/non local functions - return (!!(context.flags & NodeBuilderFlags.UseTypeOfFunction) || (context.visitedTypes?.has(typeId))) && // it is type of the symbol uses itself recursively - (!(context.flags & NodeBuilderFlags.UseStructuralFallback) || isValueSymbolAccessible(symbol, context.enclosingDeclaration)); // And the build is going to succeed without visibility error or there is no structural fallback allowed + return (!!(context.flags & ts.NodeBuilderFlags.UseTypeOfFunction) || (context.visitedTypes?.has(typeId))) && // it is type of the symbol uses itself recursively + (!(context.flags & ts.NodeBuilderFlags.UseStructuralFallback) || isValueSymbolAccessible(symbol, context.enclosingDeclaration)); // And the build is going to succeed without visibility error or there is no structural fallback allowed } } } - function visitAndTransformType(type: Type, transform: (type: Type) => T) { + function visitAndTransformType(type: ts.Type, transform: (type: ts.Type) => T) { const typeId = type.id; - const isConstructorObject = getObjectFlags(type) & ObjectFlags.Anonymous && type.symbol && type.symbol.flags & SymbolFlags.Class; - const id = getObjectFlags(type) & ObjectFlags.Reference && (type as TypeReference).node ? "N" + getNodeId((type as TypeReference).node!) : - type.flags & TypeFlags.Conditional ? "N" + getNodeId((type as ConditionalType).root.node) : + const isConstructorObject = ts.getObjectFlags(type) & ts.ObjectFlags.Anonymous && type.symbol && type.symbol.flags & ts.SymbolFlags.Class; + const id = ts.getObjectFlags(type) & ts.ObjectFlags.Reference && (type as ts.TypeReference).node ? "N" + getNodeId((type as ts.TypeReference).node!) : + type.flags & ts.TypeFlags.Conditional ? "N" + getNodeId((type as ts.ConditionalType).root.node) : type.symbol ? (isConstructorObject ? "+" : "") + getSymbolId(type.symbol) : undefined; // Since instantiations of the same anonymous type have the same symbol, tracking symbols instead // of types allows us to catch circular references to instantiations of the same anonymous type if (!context.visitedTypes) { - context.visitedTypes = new Set(); + context.visitedTypes = new ts.Set(); } if (id && !context.symbolDepth) { - context.symbolDepth = new Map(); + context.symbolDepth = new ts.Map(); } const links = context.enclosingDeclaration && getNodeLinks(context.enclosingDeclaration); const key = `${getTypeId(type)}|${context.flags}`; if (links) { - links.serializedTypes ||= new Map(); + links.serializedTypes ||= new ts.Map(); } const cachedResult = links?.serializedTypes?.get(key); if (cachedResult) { @@ -5279,7 +5141,7 @@ namespace ts { context.truncating = true; } context.approximateLength += cachedResult.addedLength; - return deepCloneOrReuseNode(cachedResult) as TypeNode as T; + return deepCloneOrReuseNode(cachedResult) as ts.TypeNode as T; } let depth: number | undefined; @@ -5299,7 +5161,10 @@ namespace ts { (result as any).truncating = true; } (result as any).addedLength = addedLength; - links?.serializedTypes?.set(key, result as TypeNode as TypeNode & {truncating?: boolean, addedLength: number}); + links?.serializedTypes?.set(key, result as ts.TypeNode as ts.TypeNode & { + truncating?: boolean; + addedLength: number; + }); } context.visitedTypes.delete(typeId); if (id) { @@ -5307,64 +5172,63 @@ namespace ts { } return result; - function deepCloneOrReuseNode(node: Node): Node { - if (!nodeIsSynthesized(node) && getParseTreeNode(node) === node) { + function deepCloneOrReuseNode(node: ts.Node): ts.Node { + if (!ts.nodeIsSynthesized(node) && ts.getParseTreeNode(node) === node) { return node; } - return setTextRange(factory.cloneNode(visitEachChild(node, deepCloneOrReuseNode, nullTransformationContext, deepCloneOrReuseNodes)), node); + return ts.setTextRange(ts.factory.cloneNode(ts.visitEachChild(node, deepCloneOrReuseNode, ts.nullTransformationContext, deepCloneOrReuseNodes)), node); } - function deepCloneOrReuseNodes(nodes: NodeArray, visitor: Visitor | undefined, test?: (node: Node) => boolean, start?: number, count?: number): NodeArray; - function deepCloneOrReuseNodes(nodes: NodeArray | undefined, visitor: Visitor | undefined, test?: (node: Node) => boolean, start?: number, count?: number): NodeArray | undefined; - function deepCloneOrReuseNodes(nodes: NodeArray | undefined, visitor: Visitor | undefined, test?: (node: Node) => boolean, start?: number, count?: number): NodeArray | undefined { + function deepCloneOrReuseNodes(nodes: ts.NodeArray, visitor: ts.Visitor | undefined, test?: (node: ts.Node) => boolean, start?: number, count?: number): ts.NodeArray; + function deepCloneOrReuseNodes(nodes: ts.NodeArray | undefined, visitor: ts.Visitor | undefined, test?: (node: ts.Node) => boolean, start?: number, count?: number): ts.NodeArray | undefined; + function deepCloneOrReuseNodes(nodes: ts.NodeArray | undefined, visitor: ts.Visitor | undefined, test?: (node: ts.Node) => boolean, start?: number, count?: number): ts.NodeArray | undefined { if (nodes && nodes.length === 0) { // Ensure we explicitly make a copy of an empty array; visitNodes will not do this unless the array has elements, // which can lead to us reusing the same empty NodeArray more than once within the same AST during type noding. - return setTextRange(factory.createNodeArray(/*nodes*/ undefined, nodes.hasTrailingComma), nodes); + return ts.setTextRange(ts.factory.createNodeArray(/*nodes*/ undefined, nodes.hasTrailingComma), nodes); } - return visitNodes(nodes, visitor, test, start, count); + return ts.visitNodes(nodes, visitor, test, start, count); } } - function createTypeNodeFromObjectType(type: ObjectType): TypeNode { - if (isGenericMappedType(type) || (type as MappedType).containsError) { - return createMappedTypeNodeFromType(type as MappedType); + function createTypeNodeFromObjectType(type: ts.ObjectType): ts.TypeNode { + if (isGenericMappedType(type) || (type as ts.MappedType).containsError) { + return createMappedTypeNodeFromType(type as ts.MappedType); } const resolved = resolveStructuredTypeMembers(type); if (!resolved.properties.length && !resolved.indexInfos.length) { if (!resolved.callSignatures.length && !resolved.constructSignatures.length) { context.approximateLength += 2; - return setEmitFlags(factory.createTypeLiteralNode(/*members*/ undefined), EmitFlags.SingleLine); + return ts.setEmitFlags(ts.factory.createTypeLiteralNode(/*members*/ undefined), ts.EmitFlags.SingleLine); } if (resolved.callSignatures.length === 1 && !resolved.constructSignatures.length) { const signature = resolved.callSignatures[0]; - const signatureNode = signatureToSignatureDeclarationHelper(signature, SyntaxKind.FunctionType, context) as FunctionTypeNode; + const signatureNode = signatureToSignatureDeclarationHelper(signature, ts.SyntaxKind.FunctionType, context) as ts.FunctionTypeNode; return signatureNode; } if (resolved.constructSignatures.length === 1 && !resolved.callSignatures.length) { const signature = resolved.constructSignatures[0]; - const signatureNode = signatureToSignatureDeclarationHelper(signature, SyntaxKind.ConstructorType, context) as ConstructorTypeNode; + const signatureNode = signatureToSignatureDeclarationHelper(signature, ts.SyntaxKind.ConstructorType, context) as ts.ConstructorTypeNode; return signatureNode; } } - const abstractSignatures = filter(resolved.constructSignatures, signature => !!(signature.flags & SignatureFlags.Abstract)); - if (some(abstractSignatures)) { - const types = map(abstractSignatures, getOrCreateTypeFromSignature); + const abstractSignatures = ts.filter(resolved.constructSignatures, signature => !!(signature.flags & ts.SignatureFlags.Abstract)); + if (ts.some(abstractSignatures)) { + const types = ts.map(abstractSignatures, getOrCreateTypeFromSignature); // count the number of type elements excluding abstract constructors - const typeElementCount = - resolved.callSignatures.length + + const typeElementCount = resolved.callSignatures.length + (resolved.constructSignatures.length - abstractSignatures.length) + resolved.indexInfos.length + // exclude `prototype` when writing a class expression as a type literal, as per // the logic in `createTypeNodesFromResolvedType`. - (context.flags & NodeBuilderFlags.WriteClassExpressionAsTypeLiteral ? - countWhere(resolved.properties, p => !(p.flags & SymbolFlags.Prototype)) : - length(resolved.properties)); + (context.flags & ts.NodeBuilderFlags.WriteClassExpressionAsTypeLiteral ? + ts.countWhere(resolved.properties, p => !(p.flags & ts.SymbolFlags.Prototype)) : + ts.length(resolved.properties)); // don't include an empty object literal if there were no other static-side // properties to write, i.e. `abstract class C { }` becomes `abstract new () => {}` // and not `(abstract new () => {}) & {}` @@ -5376,75 +5240,69 @@ namespace ts { } const savedFlags = context.flags; - context.flags |= NodeBuilderFlags.InObjectTypeLiteral; + context.flags |= ts.NodeBuilderFlags.InObjectTypeLiteral; const members = createTypeNodesFromResolvedType(resolved); context.flags = savedFlags; - const typeLiteralNode = factory.createTypeLiteralNode(members); + const typeLiteralNode = ts.factory.createTypeLiteralNode(members); context.approximateLength += 2; - setEmitFlags(typeLiteralNode, (context.flags & NodeBuilderFlags.MultilineObjectLiterals) ? 0 : EmitFlags.SingleLine); + ts.setEmitFlags(typeLiteralNode, (context.flags & ts.NodeBuilderFlags.MultilineObjectLiterals) ? 0 : ts.EmitFlags.SingleLine); return typeLiteralNode; } - function typeReferenceToTypeNode(type: TypeReference) { - let typeArguments: readonly Type[] = getTypeArguments(type); + function typeReferenceToTypeNode(type: ts.TypeReference) { + let typeArguments: readonly ts.Type[] = getTypeArguments(type); if (type.target === globalArrayType || type.target === globalReadonlyArrayType) { - if (context.flags & NodeBuilderFlags.WriteArrayAsGenericType) { + if (context.flags & ts.NodeBuilderFlags.WriteArrayAsGenericType) { const typeArgumentNode = typeToTypeNodeHelper(typeArguments[0], context); - return factory.createTypeReferenceNode(type.target === globalArrayType ? "Array" : "ReadonlyArray", [typeArgumentNode]); + return ts.factory.createTypeReferenceNode(type.target === globalArrayType ? "Array" : "ReadonlyArray", [typeArgumentNode]); } const elementType = typeToTypeNodeHelper(typeArguments[0], context); - const arrayType = factory.createArrayTypeNode(elementType); - return type.target === globalArrayType ? arrayType : factory.createTypeOperatorNode(SyntaxKind.ReadonlyKeyword, arrayType); + const arrayType = ts.factory.createArrayTypeNode(elementType); + return type.target === globalArrayType ? arrayType : ts.factory.createTypeOperatorNode(ts.SyntaxKind.ReadonlyKeyword, arrayType); } - else if (type.target.objectFlags & ObjectFlags.Tuple) { - typeArguments = sameMap(typeArguments, (t, i) => removeMissingType(t, !!((type.target as TupleType).elementFlags[i] & ElementFlags.Optional))); + else if (type.target.objectFlags & ts.ObjectFlags.Tuple) { + typeArguments = ts.sameMap(typeArguments, (t, i) => removeMissingType(t, !!((type.target as ts.TupleType).elementFlags[i] & ts.ElementFlags.Optional))); if (typeArguments.length > 0) { const arity = getTypeReferenceArity(type); const tupleConstituentNodes = mapToTypeNodes(typeArguments.slice(0, arity), context); if (tupleConstituentNodes) { - if ((type.target as TupleType).labeledElementDeclarations) { + if ((type.target as ts.TupleType).labeledElementDeclarations) { for (let i = 0; i < tupleConstituentNodes.length; i++) { - const flags = (type.target as TupleType).elementFlags[i]; - tupleConstituentNodes[i] = factory.createNamedTupleMember( - flags & ElementFlags.Variable ? factory.createToken(SyntaxKind.DotDotDotToken) : undefined, - factory.createIdentifier(unescapeLeadingUnderscores(getTupleElementLabel((type.target as TupleType).labeledElementDeclarations![i]))), - flags & ElementFlags.Optional ? factory.createToken(SyntaxKind.QuestionToken) : undefined, - flags & ElementFlags.Rest ? factory.createArrayTypeNode(tupleConstituentNodes[i]) : - tupleConstituentNodes[i] - ); + const flags = (type.target as ts.TupleType).elementFlags[i]; + tupleConstituentNodes[i] = ts.factory.createNamedTupleMember(flags & ts.ElementFlags.Variable ? ts.factory.createToken(ts.SyntaxKind.DotDotDotToken) : undefined, ts.factory.createIdentifier(ts.unescapeLeadingUnderscores(getTupleElementLabel((type.target as ts.TupleType).labeledElementDeclarations![i]))), flags & ts.ElementFlags.Optional ? ts.factory.createToken(ts.SyntaxKind.QuestionToken) : undefined, flags & ts.ElementFlags.Rest ? ts.factory.createArrayTypeNode(tupleConstituentNodes[i]) : + tupleConstituentNodes[i]); } } else { for (let i = 0; i < Math.min(arity, tupleConstituentNodes.length); i++) { - const flags = (type.target as TupleType).elementFlags[i]; + const flags = (type.target as ts.TupleType).elementFlags[i]; tupleConstituentNodes[i] = - flags & ElementFlags.Variable ? factory.createRestTypeNode(flags & ElementFlags.Rest ? factory.createArrayTypeNode(tupleConstituentNodes[i]) : tupleConstituentNodes[i]) : - flags & ElementFlags.Optional ? factory.createOptionalTypeNode(tupleConstituentNodes[i]) : + flags & ts.ElementFlags.Variable ? ts.factory.createRestTypeNode(flags & ts.ElementFlags.Rest ? ts.factory.createArrayTypeNode(tupleConstituentNodes[i]) : tupleConstituentNodes[i]) : + flags & ts.ElementFlags.Optional ? ts.factory.createOptionalTypeNode(tupleConstituentNodes[i]) : tupleConstituentNodes[i]; } } - const tupleTypeNode = setEmitFlags(factory.createTupleTypeNode(tupleConstituentNodes), EmitFlags.SingleLine); - return (type.target as TupleType).readonly ? factory.createTypeOperatorNode(SyntaxKind.ReadonlyKeyword, tupleTypeNode) : tupleTypeNode; + const tupleTypeNode = ts.setEmitFlags(ts.factory.createTupleTypeNode(tupleConstituentNodes), ts.EmitFlags.SingleLine); + return (type.target as ts.TupleType).readonly ? ts.factory.createTypeOperatorNode(ts.SyntaxKind.ReadonlyKeyword, tupleTypeNode) : tupleTypeNode; } } - if (context.encounteredError || (context.flags & NodeBuilderFlags.AllowEmptyTuple)) { - const tupleTypeNode = setEmitFlags(factory.createTupleTypeNode([]), EmitFlags.SingleLine); - return (type.target as TupleType).readonly ? factory.createTypeOperatorNode(SyntaxKind.ReadonlyKeyword, tupleTypeNode) : tupleTypeNode; + if (context.encounteredError || (context.flags & ts.NodeBuilderFlags.AllowEmptyTuple)) { + const tupleTypeNode = ts.setEmitFlags(ts.factory.createTupleTypeNode([]), ts.EmitFlags.SingleLine); + return (type.target as ts.TupleType).readonly ? ts.factory.createTypeOperatorNode(ts.SyntaxKind.ReadonlyKeyword, tupleTypeNode) : tupleTypeNode; } context.encounteredError = true; return undefined!; // TODO: GH#18217 } - else if (context.flags & NodeBuilderFlags.WriteClassExpressionAsTypeLiteral && + else if (context.flags & ts.NodeBuilderFlags.WriteClassExpressionAsTypeLiteral && type.symbol.valueDeclaration && - isClassLike(type.symbol.valueDeclaration) && - !isValueSymbolAccessible(type.symbol, context.enclosingDeclaration) - ) { + ts.isClassLike(type.symbol.valueDeclaration) && + !isValueSymbolAccessible(type.symbol, context.enclosingDeclaration)) { return createAnonymousTypeNode(type); } else { const outerTypeParameters = type.target.outerTypeParameters; let i = 0; - let resultType: TypeReferenceNode | ImportTypeNode | undefined; + let resultType: ts.TypeReferenceNode | ts.ImportTypeNode | undefined; if (outerTypeParameters) { const length = outerTypeParameters.length; while (i < length) { @@ -5456,87 +5314,75 @@ namespace ts { } while (i < length && getParentSymbolOfTypeParameter(outerTypeParameters[i]) === parent); // When type parameters are their own type arguments for the whole group (i.e. we have // the default outer type arguments), we don't show the group. - if (!rangeEquals(outerTypeParameters, typeArguments, start, i)) { + if (!ts.rangeEquals(outerTypeParameters, typeArguments, start, i)) { const typeArgumentSlice = mapToTypeNodes(typeArguments.slice(start, i), context); const flags = context.flags; - context.flags |= NodeBuilderFlags.ForbidIndexedAccessSymbolReferences; - const ref = symbolToTypeNode(parent, context, SymbolFlags.Type, typeArgumentSlice) as TypeReferenceNode | ImportTypeNode; + context.flags |= ts.NodeBuilderFlags.ForbidIndexedAccessSymbolReferences; + const ref = symbolToTypeNode(parent, context, ts.SymbolFlags.Type, typeArgumentSlice) as ts.TypeReferenceNode | ts.ImportTypeNode; context.flags = flags; - resultType = !resultType ? ref : appendReferenceToType(resultType, ref as TypeReferenceNode); + resultType = !resultType ? ref : appendReferenceToType(resultType, ref as ts.TypeReferenceNode); } } } - let typeArgumentNodes: readonly TypeNode[] | undefined; + let typeArgumentNodes: readonly ts.TypeNode[] | undefined; if (typeArguments.length > 0) { - const typeParameterCount = (type.target.typeParameters || emptyArray).length; + const typeParameterCount = (type.target.typeParameters || ts.emptyArray).length; typeArgumentNodes = mapToTypeNodes(typeArguments.slice(i, typeParameterCount), context); } const flags = context.flags; - context.flags |= NodeBuilderFlags.ForbidIndexedAccessSymbolReferences; - const finalRef = symbolToTypeNode(type.symbol, context, SymbolFlags.Type, typeArgumentNodes); + context.flags |= ts.NodeBuilderFlags.ForbidIndexedAccessSymbolReferences; + const finalRef = symbolToTypeNode(type.symbol, context, ts.SymbolFlags.Type, typeArgumentNodes); context.flags = flags; - return !resultType ? finalRef : appendReferenceToType(resultType, finalRef as TypeReferenceNode); + return !resultType ? finalRef : appendReferenceToType(resultType, finalRef as ts.TypeReferenceNode); } } - function appendReferenceToType(root: TypeReferenceNode | ImportTypeNode, ref: TypeReferenceNode): TypeReferenceNode | ImportTypeNode { - if (isImportTypeNode(root)) { + function appendReferenceToType(root: ts.TypeReferenceNode | ts.ImportTypeNode, ref: ts.TypeReferenceNode): ts.TypeReferenceNode | ts.ImportTypeNode { + if (ts.isImportTypeNode(root)) { // first shift type arguments let typeArguments = root.typeArguments; let qualifier = root.qualifier; if (qualifier) { - if (isIdentifier(qualifier)) { - qualifier = factory.updateIdentifier(qualifier, typeArguments); + if (ts.isIdentifier(qualifier)) { + qualifier = ts.factory.updateIdentifier(qualifier, typeArguments); } else { - qualifier = factory.updateQualifiedName(qualifier, - qualifier.left, - factory.updateIdentifier(qualifier.right, typeArguments)); + qualifier = ts.factory.updateQualifiedName(qualifier, qualifier.left, ts.factory.updateIdentifier(qualifier.right, typeArguments)); } } typeArguments = ref.typeArguments; // then move qualifiers const ids = getAccessStack(ref); for (const id of ids) { - qualifier = qualifier ? factory.createQualifiedName(qualifier, id) : id; + qualifier = qualifier ? ts.factory.createQualifiedName(qualifier, id) : id; } - return factory.updateImportTypeNode( - root, - root.argument, - qualifier, - typeArguments, - root.isTypeOf); + return ts.factory.updateImportTypeNode(root, root.argument, qualifier, typeArguments, root.isTypeOf); } else { // first shift type arguments let typeArguments = root.typeArguments; let typeName = root.typeName; - if (isIdentifier(typeName)) { - typeName = factory.updateIdentifier(typeName, typeArguments); + if (ts.isIdentifier(typeName)) { + typeName = ts.factory.updateIdentifier(typeName, typeArguments); } else { - typeName = factory.updateQualifiedName(typeName, - typeName.left, - factory.updateIdentifier(typeName.right, typeArguments)); + typeName = ts.factory.updateQualifiedName(typeName, typeName.left, ts.factory.updateIdentifier(typeName.right, typeArguments)); } typeArguments = ref.typeArguments; // then move qualifiers const ids = getAccessStack(ref); for (const id of ids) { - typeName = factory.createQualifiedName(typeName, id); + typeName = ts.factory.createQualifiedName(typeName, id); } - return factory.updateTypeReferenceNode( - root, - typeName, - typeArguments); + return ts.factory.updateTypeReferenceNode(root, typeName, typeArguments); } } - function getAccessStack(ref: TypeReferenceNode): Identifier[] { + function getAccessStack(ref: ts.TypeReferenceNode): ts.Identifier[] { let state = ref.typeName; const ids = []; - while (!isIdentifier(state)) { + while (!ts.isIdentifier(state)) { ids.unshift(state.right); state = state.left; } @@ -5544,20 +5390,21 @@ namespace ts { return ids; } - function createTypeNodesFromResolvedType(resolvedType: ResolvedType): TypeElement[] | undefined { + function createTypeNodesFromResolvedType(resolvedType: ts.ResolvedType): ts.TypeElement[] | undefined { if (checkTruncationLength(context)) { - return [factory.createPropertySignature(/*modifiers*/ undefined, "...", /*questionToken*/ undefined, /*type*/ undefined)]; + return [ts.factory.createPropertySignature(/*modifiers*/ undefined, "...", /*questionToken*/ undefined, /*type*/ undefined)]; } - const typeElements: TypeElement[] = []; + const typeElements: ts.TypeElement[] = []; for (const signature of resolvedType.callSignatures) { - typeElements.push(signatureToSignatureDeclarationHelper(signature, SyntaxKind.CallSignature, context) as CallSignatureDeclaration); + typeElements.push(signatureToSignatureDeclarationHelper(signature, ts.SyntaxKind.CallSignature, context) as ts.CallSignatureDeclaration); } for (const signature of resolvedType.constructSignatures) { - if (signature.flags & SignatureFlags.Abstract) continue; - typeElements.push(signatureToSignatureDeclarationHelper(signature, SyntaxKind.ConstructSignature, context) as ConstructSignatureDeclaration); + if (signature.flags & ts.SignatureFlags.Abstract) + continue; + typeElements.push(signatureToSignatureDeclarationHelper(signature, ts.SyntaxKind.ConstructSignature, context) as ts.ConstructSignatureDeclaration); } for (const info of resolvedType.indexInfos) { - typeElements.push(indexInfoToIndexSignatureDeclarationHelper(info, context, resolvedType.objectFlags & ObjectFlags.ReverseMapped ? createElidedInformationPlaceholder(context) : undefined)); + typeElements.push(indexInfoToIndexSignatureDeclarationHelper(info, context, resolvedType.objectFlags & ts.ObjectFlags.ReverseMapped ? createElidedInformationPlaceholder(context) : undefined)); } const properties = resolvedType.properties; @@ -5568,16 +5415,16 @@ namespace ts { let i = 0; for (const propertySymbol of properties) { i++; - if (context.flags & NodeBuilderFlags.WriteClassExpressionAsTypeLiteral) { - if (propertySymbol.flags & SymbolFlags.Prototype) { + if (context.flags & ts.NodeBuilderFlags.WriteClassExpressionAsTypeLiteral) { + if (propertySymbol.flags & ts.SymbolFlags.Prototype) { continue; } - if (getDeclarationModifierFlagsFromSymbol(propertySymbol) & (ModifierFlags.Private | ModifierFlags.Protected) && context.tracker.reportPrivateInBaseOfClassExpression) { - context.tracker.reportPrivateInBaseOfClassExpression(unescapeLeadingUnderscores(propertySymbol.escapedName)); + if (ts.getDeclarationModifierFlagsFromSymbol(propertySymbol) & (ts.ModifierFlags.Private | ts.ModifierFlags.Protected) && context.tracker.reportPrivateInBaseOfClassExpression) { + context.tracker.reportPrivateInBaseOfClassExpression(ts.unescapeLeadingUnderscores(propertySymbol.escapedName)); } } if (checkTruncationLength(context) && (i + 2 < properties.length - 1)) { - typeElements.push(factory.createPropertySignature(/*modifiers*/ undefined, `... ${properties.length - i} more ...`, /*questionToken*/ undefined, /*type*/ undefined)); + typeElements.push(ts.factory.createPropertySignature(/*modifiers*/ undefined, `... ${properties.length - i} more ...`, /*questionToken*/ undefined, /*type*/ undefined)); addPropertyToElementList(properties[properties.length - 1], context, typeElements); break; } @@ -5590,42 +5437,38 @@ namespace ts { function createElidedInformationPlaceholder(context: NodeBuilderContext) { context.approximateLength += 3; - if (!(context.flags & NodeBuilderFlags.NoTruncation)) { - return factory.createTypeReferenceNode(factory.createIdentifier("..."), /*typeArguments*/ undefined); + if (!(context.flags & ts.NodeBuilderFlags.NoTruncation)) { + return ts.factory.createTypeReferenceNode(ts.factory.createIdentifier("..."), /*typeArguments*/ undefined); } - return factory.createKeywordTypeNode(SyntaxKind.AnyKeyword); + return ts.factory.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword); } - function shouldUsePlaceholderForProperty(propertySymbol: Symbol, context: NodeBuilderContext) { + function shouldUsePlaceholderForProperty(propertySymbol: ts.Symbol, context: NodeBuilderContext) { // Use placeholders for reverse mapped types we've either already descended into, or which // are nested reverse mappings within a mapping over a non-anonymous type. The later is a restriction mostly just to // reduce the blowup in printback size from doing, eg, a deep reverse mapping over `Window`. // Since anonymous types usually come from expressions, this allows us to preserve the output // for deep mappings which likely come from expressions, while truncating those parts which // come from mappings over library functions. - return !!(getCheckFlags(propertySymbol) & CheckFlags.ReverseMapped) - && ( - contains(context.reverseMappedStack, propertySymbol as ReverseMappedSymbol) - || ( - context.reverseMappedStack?.[0] - && !(getObjectFlags(last(context.reverseMappedStack).propertyType) & ObjectFlags.Anonymous) - ) - ); - } - - function addPropertyToElementList(propertySymbol: Symbol, context: NodeBuilderContext, typeElements: TypeElement[]) { - const propertyIsReverseMapped = !!(getCheckFlags(propertySymbol) & CheckFlags.ReverseMapped); + return !!(ts.getCheckFlags(propertySymbol) & ts.CheckFlags.ReverseMapped) + && (ts.contains(context.reverseMappedStack, propertySymbol as ts.ReverseMappedSymbol) + || (context.reverseMappedStack?.[0] + && !(ts.getObjectFlags(ts.last(context.reverseMappedStack).propertyType) & ts.ObjectFlags.Anonymous))); + } + + function addPropertyToElementList(propertySymbol: ts.Symbol, context: NodeBuilderContext, typeElements: ts.TypeElement[]) { + const propertyIsReverseMapped = !!(ts.getCheckFlags(propertySymbol) & ts.CheckFlags.ReverseMapped); const propertyType = shouldUsePlaceholderForProperty(propertySymbol, context) ? anyType : getNonMissingTypeOfSymbol(propertySymbol); const saveEnclosingDeclaration = context.enclosingDeclaration; context.enclosingDeclaration = undefined; - if (context.tracker.trackSymbol && getCheckFlags(propertySymbol) & CheckFlags.Late && isLateBoundName(propertySymbol.escapedName)) { + if (context.tracker.trackSymbol && ts.getCheckFlags(propertySymbol) & ts.CheckFlags.Late && isLateBoundName(propertySymbol.escapedName)) { if (propertySymbol.declarations) { - const decl = first(propertySymbol.declarations); + const decl = ts.first(propertySymbol.declarations); if (hasLateBindableName(decl)) { - if (isBinaryExpression(decl)) { - const name = getNameOfDeclaration(decl); - if (name && isElementAccessExpression(name) && isPropertyAccessEntityNameExpression(name.argumentExpression)) { + if (ts.isBinaryExpression(decl)) { + const name = ts.getNameOfDeclaration(decl); + if (name && ts.isElementAccessExpression(name) && ts.isPropertyAccessEntityNameExpression(name.argumentExpression)) { trackComputedName(name.argumentExpression, saveEnclosingDeclaration, context); } } @@ -5641,83 +5484,82 @@ namespace ts { context.enclosingDeclaration = propertySymbol.valueDeclaration || propertySymbol.declarations?.[0] || saveEnclosingDeclaration; const propertyName = getPropertyNameNodeForSymbol(propertySymbol, context); context.enclosingDeclaration = saveEnclosingDeclaration; - context.approximateLength += (symbolName(propertySymbol).length + 1); - const optionalToken = propertySymbol.flags & SymbolFlags.Optional ? factory.createToken(SyntaxKind.QuestionToken) : undefined; - if (propertySymbol.flags & (SymbolFlags.Function | SymbolFlags.Method) && !getPropertiesOfObjectType(propertyType).length && !isReadonlySymbol(propertySymbol)) { - const signatures = getSignaturesOfType(filterType(propertyType, t => !(t.flags & TypeFlags.Undefined)), SignatureKind.Call); + context.approximateLength += (ts.symbolName(propertySymbol).length + 1); + const optionalToken = propertySymbol.flags & ts.SymbolFlags.Optional ? ts.factory.createToken(ts.SyntaxKind.QuestionToken) : undefined; + if (propertySymbol.flags & (ts.SymbolFlags.Function | ts.SymbolFlags.Method) && !getPropertiesOfObjectType(propertyType).length && !isReadonlySymbol(propertySymbol)) { + const signatures = getSignaturesOfType(filterType(propertyType, t => !(t.flags & ts.TypeFlags.Undefined)), ts.SignatureKind.Call); for (const signature of signatures) { - const methodDeclaration = signatureToSignatureDeclarationHelper(signature, SyntaxKind.MethodSignature, context, { name: propertyName, questionToken: optionalToken }) as MethodSignature; + const methodDeclaration = signatureToSignatureDeclarationHelper(signature, ts.SyntaxKind.MethodSignature, context, { name: propertyName, questionToken: optionalToken }) as ts.MethodSignature; typeElements.push(preserveCommentsOn(methodDeclaration)); } } else { - let propertyTypeNode: TypeNode; + let propertyTypeNode: ts.TypeNode; if (shouldUsePlaceholderForProperty(propertySymbol, context)) { propertyTypeNode = createElidedInformationPlaceholder(context); } else { if (propertyIsReverseMapped) { context.reverseMappedStack ||= []; - context.reverseMappedStack.push(propertySymbol as ReverseMappedSymbol); + context.reverseMappedStack.push(propertySymbol as ts.ReverseMappedSymbol); } - propertyTypeNode = propertyType ? serializeTypeForDeclaration(context, propertyType, propertySymbol, saveEnclosingDeclaration) : factory.createKeywordTypeNode(SyntaxKind.AnyKeyword); + propertyTypeNode = propertyType ? serializeTypeForDeclaration(context, propertyType, propertySymbol, saveEnclosingDeclaration) : ts.factory.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword); if (propertyIsReverseMapped) { context.reverseMappedStack!.pop(); } } - const modifiers = isReadonlySymbol(propertySymbol) ? [factory.createToken(SyntaxKind.ReadonlyKeyword)] : undefined; + const modifiers = isReadonlySymbol(propertySymbol) ? [ts.factory.createToken(ts.SyntaxKind.ReadonlyKeyword)] : undefined; if (modifiers) { context.approximateLength += 9; } - const propertySignature = factory.createPropertySignature( - modifiers, - propertyName, - optionalToken, - propertyTypeNode); + const propertySignature = ts.factory.createPropertySignature(modifiers, propertyName, optionalToken, propertyTypeNode); typeElements.push(preserveCommentsOn(propertySignature)); } - function preserveCommentsOn(node: T) { - if (some(propertySymbol.declarations, d => d.kind === SyntaxKind.JSDocPropertyTag)) { - const d = propertySymbol.declarations?.find(d => d.kind === SyntaxKind.JSDocPropertyTag)! as JSDocPropertyTag; - const commentText = getTextOfJSDocComment(d.comment); + function preserveCommentsOn(node: T) { + if (ts.some(propertySymbol.declarations, d => d.kind === ts.SyntaxKind.JSDocPropertyTag)) { + const d = propertySymbol.declarations?.find(d => d.kind === ts.SyntaxKind.JSDocPropertyTag)! as ts.JSDocPropertyTag; + const commentText = ts.getTextOfJSDocComment(d.comment); if (commentText) { - setSyntheticLeadingComments(node, [{ kind: SyntaxKind.MultiLineCommentTrivia, text: "*\n * " + commentText.replace(/\n/g, "\n * ") + "\n ", pos: -1, end: -1, hasTrailingNewLine: true }]); + ts.setSyntheticLeadingComments(node, [{ kind: ts.SyntaxKind.MultiLineCommentTrivia, text: "*\n * " + commentText.replace(/\n/g, "\n * ") + "\n ", pos: -1, end: -1, hasTrailingNewLine: true }]); } } else if (propertySymbol.valueDeclaration) { // Copy comments to node for declaration emit - setCommentRange(node, propertySymbol.valueDeclaration); + ts.setCommentRange(node, propertySymbol.valueDeclaration); } return node; } } - function mapToTypeNodes(types: readonly Type[] | undefined, context: NodeBuilderContext, isBareList?: boolean): TypeNode[] | undefined { - if (some(types)) { + function mapToTypeNodes(types: readonly ts.Type[] | undefined, context: NodeBuilderContext, isBareList?: boolean): ts.TypeNode[] | undefined { + if (ts.some(types)) { if (checkTruncationLength(context)) { if (!isBareList) { - return [factory.createTypeReferenceNode("...", /*typeArguments*/ undefined)]; + return [ts.factory.createTypeReferenceNode("...", /*typeArguments*/ undefined)]; } else if (types.length > 2) { return [ typeToTypeNodeHelper(types[0], context), - factory.createTypeReferenceNode(`... ${types.length - 2} more ...`, /*typeArguments*/ undefined), + ts.factory.createTypeReferenceNode(`... ${types.length - 2} more ...`, /*typeArguments*/ undefined), typeToTypeNodeHelper(types[types.length - 1], context) ]; } } - const mayHaveNameCollisions = !(context.flags & NodeBuilderFlags.UseFullyQualifiedType); + const mayHaveNameCollisions = !(context.flags & ts.NodeBuilderFlags.UseFullyQualifiedType); /** Map from type reference identifier text to [type, index in `result` where the type node is] */ - const seenNames = mayHaveNameCollisions ? createUnderscoreEscapedMultiMap<[Type, number]>() : undefined; - const result: TypeNode[] = []; + const seenNames = mayHaveNameCollisions ? ts.createUnderscoreEscapedMultiMap<[ + ts.Type, + number + ]>() : undefined; + const result: ts.TypeNode[] = []; let i = 0; for (const type of types) { i++; if (checkTruncationLength(context) && (i + 2 < types.length - 1)) { - result.push(factory.createTypeReferenceNode(`... ${types.length - i} more ...`, /*typeArguments*/ undefined)); + result.push(ts.factory.createTypeReferenceNode(`... ${types.length - i} more ...`, /*typeArguments*/ undefined)); const typeNode = typeToTypeNodeHelper(types[types.length - 1], context); if (typeNode) { result.push(typeNode); @@ -5728,7 +5570,7 @@ namespace ts { const typeNode = typeToTypeNodeHelper(type, context); if (typeNode) { result.push(typeNode); - if (seenNames && isIdentifierTypeReference(typeNode)) { + if (seenNames && ts.isIdentifierTypeReference(typeNode)) { seenNames.add(typeNode.typeName.escapedText, [type, result.length - 1]); } } @@ -5743,9 +5585,9 @@ namespace ts { // type node for each entry by that name with the // `UseFullyQualifiedType` flag enabled. const saveContextFlags = context.flags; - context.flags |= NodeBuilderFlags.UseFullyQualifiedType; + context.flags |= ts.NodeBuilderFlags.UseFullyQualifiedType; seenNames.forEach(types => { - if (!arrayIsHomogeneous(types, ([a], [b]) => typesAreSameReference(a, b))) { + if (!ts.arrayIsHomogeneous(types, ([a], [b]) => typesAreSameReference(a, b))) { for (const [type, resultIndex] of types) { result[resultIndex] = typeToTypeNodeHelper(type, context); } @@ -5758,53 +5600,49 @@ namespace ts { } } - function typesAreSameReference(a: Type, b: Type): boolean { + function typesAreSameReference(a: ts.Type, b: ts.Type): boolean { return a === b || !!a.symbol && a.symbol === b.symbol || !!a.aliasSymbol && a.aliasSymbol === b.aliasSymbol; } - function indexInfoToIndexSignatureDeclarationHelper(indexInfo: IndexInfo, context: NodeBuilderContext, typeNode: TypeNode | undefined): IndexSignatureDeclaration { - const name = getNameFromIndexInfo(indexInfo) || "x"; + function indexInfoToIndexSignatureDeclarationHelper(indexInfo: ts.IndexInfo, context: NodeBuilderContext, typeNode: ts.TypeNode | undefined): ts.IndexSignatureDeclaration { + const name = ts.getNameFromIndexInfo(indexInfo) || "x"; const indexerTypeNode = typeToTypeNodeHelper(indexInfo.keyType, context); - const indexingParameter = factory.createParameterDeclaration( + const indexingParameter = ts.factory.createParameterDeclaration( /*decorators*/ undefined, /*modifiers*/ undefined, - /*dotDotDotToken*/ undefined, - name, - /*questionToken*/ undefined, - indexerTypeNode, + /*dotDotDotToken*/ undefined, name, + /*questionToken*/ undefined, indexerTypeNode, /*initializer*/ undefined); if (!typeNode) { typeNode = typeToTypeNodeHelper(indexInfo.type || anyType, context); } - if (!indexInfo.type && !(context.flags & NodeBuilderFlags.AllowEmptyIndexInfoType)) { + if (!indexInfo.type && !(context.flags & ts.NodeBuilderFlags.AllowEmptyIndexInfoType)) { context.encounteredError = true; } context.approximateLength += (name.length + 4); - return factory.createIndexSignature( - /*decorators*/ undefined, - indexInfo.isReadonly ? [factory.createToken(SyntaxKind.ReadonlyKeyword)] : undefined, - [indexingParameter], - typeNode); + return ts.factory.createIndexSignature( + /*decorators*/ undefined, indexInfo.isReadonly ? [ts.factory.createToken(ts.SyntaxKind.ReadonlyKeyword)] : undefined, [indexingParameter], typeNode); } interface SignatureToSignatureDeclarationOptions { - modifiers?: readonly Modifier[]; - name?: PropertyName; - questionToken?: QuestionToken; - privateSymbolVisitor?: (s: Symbol) => void; + modifiers?: readonly ts.Modifier[]; + name?: ts.PropertyName; + questionToken?: ts.QuestionToken; + privateSymbolVisitor?: (s: ts.Symbol) => void; bundledImports?: boolean; } - function signatureToSignatureDeclarationHelper(signature: Signature, kind: SignatureDeclaration["kind"], context: NodeBuilderContext, options?: SignatureToSignatureDeclarationOptions): SignatureDeclaration { - const suppressAny = context.flags & NodeBuilderFlags.SuppressAnyReturnType; - if (suppressAny) context.flags &= ~NodeBuilderFlags.SuppressAnyReturnType; // suppress only toplevel `any`s + function signatureToSignatureDeclarationHelper(signature: ts.Signature, kind: ts.SignatureDeclaration["kind"], context: NodeBuilderContext, options?: SignatureToSignatureDeclarationOptions): ts.SignatureDeclaration { + const suppressAny = context.flags & ts.NodeBuilderFlags.SuppressAnyReturnType; + if (suppressAny) + context.flags &= ~ts.NodeBuilderFlags.SuppressAnyReturnType; // suppress only toplevel `any`s context.approximateLength += 3; // Usually a signature contributes a few more characters than this, but 3 is the minimum - let typeParameters: TypeParameterDeclaration[] | undefined; - let typeArguments: TypeNode[] | undefined; - if (context.flags & NodeBuilderFlags.WriteTypeArgumentsOfSignature && signature.target && signature.mapper && signature.target.typeParameters) { + let typeParameters: ts.TypeParameterDeclaration[] | undefined; + let typeArguments: ts.TypeNode[] | undefined; + if (context.flags & ts.NodeBuilderFlags.WriteTypeArgumentsOfSignature && signature.target && signature.mapper && signature.target.typeParameters) { typeArguments = signature.target.typeParameters.map(parameter => typeToTypeNodeHelper(instantiateType(parameter, signature.mapper), context)); } else { @@ -5813,23 +5651,23 @@ namespace ts { const expandedParams = getExpandedParameters(signature, /*skipUnionExpanding*/ true)[0]; // If the expanded parameter list had a variadic in a non-trailing position, don't expand it - const parameters = (some(expandedParams, p => p !== expandedParams[expandedParams.length - 1] && !!(getCheckFlags(p) & CheckFlags.RestParameter)) ? signature.parameters : expandedParams).map(parameter => symbolToParameterDeclaration(parameter, context, kind === SyntaxKind.Constructor, options?.privateSymbolVisitor, options?.bundledImports)); + const parameters = (ts.some(expandedParams, p => p !== expandedParams[expandedParams.length - 1] && !!(ts.getCheckFlags(p) & ts.CheckFlags.RestParameter)) ? signature.parameters : expandedParams).map(parameter => symbolToParameterDeclaration(parameter, context, kind === ts.SyntaxKind.Constructor, options?.privateSymbolVisitor, options?.bundledImports)); const thisParameter = tryGetThisParameterDeclaration(signature, context); if (thisParameter) { parameters.unshift(thisParameter); } - let returnTypeNode: TypeNode | undefined; + let returnTypeNode: ts.TypeNode | undefined; const typePredicate = getTypePredicateOfSignature(signature); if (typePredicate) { - const assertsModifier = typePredicate.kind === TypePredicateKind.AssertsThis || typePredicate.kind === TypePredicateKind.AssertsIdentifier ? - factory.createToken(SyntaxKind.AssertsKeyword) : + const assertsModifier = typePredicate.kind === ts.TypePredicateKind.AssertsThis || typePredicate.kind === ts.TypePredicateKind.AssertsIdentifier ? + ts.factory.createToken(ts.SyntaxKind.AssertsKeyword) : undefined; - const parameterName = typePredicate.kind === TypePredicateKind.Identifier || typePredicate.kind === TypePredicateKind.AssertsIdentifier ? - setEmitFlags(factory.createIdentifier(typePredicate.parameterName), EmitFlags.NoAsciiEscaping) : - factory.createThisTypeNode(); + const parameterName = typePredicate.kind === ts.TypePredicateKind.Identifier || typePredicate.kind === ts.TypePredicateKind.AssertsIdentifier ? + ts.setEmitFlags(ts.factory.createIdentifier(typePredicate.parameterName), ts.EmitFlags.NoAsciiEscaping) : + ts.factory.createThisTypeNode(); const typeNode = typePredicate.type && typeToTypeNodeHelper(typePredicate.type, context); - returnTypeNode = factory.createTypePredicateNode(assertsModifier, parameterName, typeNode); + returnTypeNode = ts.factory.createTypePredicateNode(assertsModifier, parameterName, typeNode); } else { const returnType = getReturnTypeOfSignature(signature); @@ -5837,78 +5675,73 @@ namespace ts { returnTypeNode = serializeReturnTypeForSignature(context, returnType, signature, options?.privateSymbolVisitor, options?.bundledImports); } else if (!suppressAny) { - returnTypeNode = factory.createKeywordTypeNode(SyntaxKind.AnyKeyword); + returnTypeNode = ts.factory.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword); } } let modifiers = options?.modifiers; - if ((kind === SyntaxKind.ConstructorType) && signature.flags & SignatureFlags.Abstract) { - const flags = modifiersToFlags(modifiers); - modifiers = factory.createModifiersFromModifierFlags(flags | ModifierFlags.Abstract); - } - - const node = - kind === SyntaxKind.CallSignature ? factory.createCallSignature(typeParameters, parameters, returnTypeNode) : - kind === SyntaxKind.ConstructSignature ? factory.createConstructSignature(typeParameters, parameters, returnTypeNode) : - kind === SyntaxKind.MethodSignature ? factory.createMethodSignature(modifiers, options?.name ?? factory.createIdentifier(""), options?.questionToken, typeParameters, parameters, returnTypeNode) : - kind === SyntaxKind.MethodDeclaration ? factory.createMethodDeclaration(/*decorators*/ undefined, modifiers, /*asteriskToken*/ undefined, options?.name ?? factory.createIdentifier(""), /*questionToken*/ undefined, typeParameters, parameters, returnTypeNode, /*body*/ undefined) : - kind === SyntaxKind.Constructor ? factory.createConstructorDeclaration(/*decorators*/ undefined, modifiers, parameters, /*body*/ undefined) : - kind === SyntaxKind.GetAccessor ? factory.createGetAccessorDeclaration(/*decorators*/ undefined, modifiers, options?.name ?? factory.createIdentifier(""), parameters, returnTypeNode, /*body*/ undefined) : - kind === SyntaxKind.SetAccessor ? factory.createSetAccessorDeclaration(/*decorators*/ undefined, modifiers, options?.name ?? factory.createIdentifier(""), parameters, /*body*/ undefined) : - kind === SyntaxKind.IndexSignature ? factory.createIndexSignature(/*decorators*/ undefined, modifiers, parameters, returnTypeNode) : - kind === SyntaxKind.JSDocFunctionType ? factory.createJSDocFunctionType(parameters, returnTypeNode) : - kind === SyntaxKind.FunctionType ? factory.createFunctionTypeNode(typeParameters, parameters, returnTypeNode ?? factory.createTypeReferenceNode(factory.createIdentifier(""))) : - kind === SyntaxKind.ConstructorType ? factory.createConstructorTypeNode(modifiers, typeParameters, parameters, returnTypeNode ?? factory.createTypeReferenceNode(factory.createIdentifier(""))) : - kind === SyntaxKind.FunctionDeclaration ? factory.createFunctionDeclaration(/*decorators*/ undefined, modifiers, /*asteriskToken*/ undefined, options?.name ? cast(options.name, isIdentifier) : factory.createIdentifier(""), typeParameters, parameters, returnTypeNode, /*body*/ undefined) : - kind === SyntaxKind.FunctionExpression ? factory.createFunctionExpression(modifiers, /*asteriskToken*/ undefined, options?.name ? cast(options.name, isIdentifier) : factory.createIdentifier(""), typeParameters, parameters, returnTypeNode, factory.createBlock([])) : - kind === SyntaxKind.ArrowFunction ? factory.createArrowFunction(modifiers, typeParameters, parameters, returnTypeNode, /*equalsGreaterThanToken*/ undefined, factory.createBlock([])) : - Debug.assertNever(kind); + if ((kind === ts.SyntaxKind.ConstructorType) && signature.flags & ts.SignatureFlags.Abstract) { + const flags = ts.modifiersToFlags(modifiers); + modifiers = ts.factory.createModifiersFromModifierFlags(flags | ts.ModifierFlags.Abstract); + } + const node = kind === ts.SyntaxKind.CallSignature ? ts.factory.createCallSignature(typeParameters, parameters, returnTypeNode) : + kind === ts.SyntaxKind.ConstructSignature ? ts.factory.createConstructSignature(typeParameters, parameters, returnTypeNode) : + kind === ts.SyntaxKind.MethodSignature ? ts.factory.createMethodSignature(modifiers, options?.name ?? ts.factory.createIdentifier(""), options?.questionToken, typeParameters, parameters, returnTypeNode) : + kind === ts.SyntaxKind.MethodDeclaration ? ts.factory.createMethodDeclaration(/*decorators*/ undefined, modifiers, /*asteriskToken*/ undefined, options?.name ?? ts.factory.createIdentifier(""), /*questionToken*/ undefined, typeParameters, parameters, returnTypeNode, /*body*/ undefined) : + kind === ts.SyntaxKind.Constructor ? ts.factory.createConstructorDeclaration(/*decorators*/ undefined, modifiers, parameters, /*body*/ undefined) : + kind === ts.SyntaxKind.GetAccessor ? ts.factory.createGetAccessorDeclaration(/*decorators*/ undefined, modifiers, options?.name ?? ts.factory.createIdentifier(""), parameters, returnTypeNode, /*body*/ undefined) : + kind === ts.SyntaxKind.SetAccessor ? ts.factory.createSetAccessorDeclaration(/*decorators*/ undefined, modifiers, options?.name ?? ts.factory.createIdentifier(""), parameters, /*body*/ undefined) : + kind === ts.SyntaxKind.IndexSignature ? ts.factory.createIndexSignature(/*decorators*/ undefined, modifiers, parameters, returnTypeNode) : + kind === ts.SyntaxKind.JSDocFunctionType ? ts.factory.createJSDocFunctionType(parameters, returnTypeNode) : + kind === ts.SyntaxKind.FunctionType ? ts.factory.createFunctionTypeNode(typeParameters, parameters, returnTypeNode ?? ts.factory.createTypeReferenceNode(ts.factory.createIdentifier(""))) : + kind === ts.SyntaxKind.ConstructorType ? ts.factory.createConstructorTypeNode(modifiers, typeParameters, parameters, returnTypeNode ?? ts.factory.createTypeReferenceNode(ts.factory.createIdentifier(""))) : + kind === ts.SyntaxKind.FunctionDeclaration ? ts.factory.createFunctionDeclaration(/*decorators*/ undefined, modifiers, /*asteriskToken*/ undefined, options?.name ? ts.cast(options.name, ts.isIdentifier) : ts.factory.createIdentifier(""), typeParameters, parameters, returnTypeNode, /*body*/ undefined) : + kind === ts.SyntaxKind.FunctionExpression ? ts.factory.createFunctionExpression(modifiers, /*asteriskToken*/ undefined, options?.name ? ts.cast(options.name, ts.isIdentifier) : ts.factory.createIdentifier(""), typeParameters, parameters, returnTypeNode, ts.factory.createBlock([])) : + kind === ts.SyntaxKind.ArrowFunction ? ts.factory.createArrowFunction(modifiers, typeParameters, parameters, returnTypeNode, /*equalsGreaterThanToken*/ undefined, ts.factory.createBlock([])) : + ts.Debug.assertNever(kind); if (typeArguments) { - node.typeArguments = factory.createNodeArray(typeArguments); + node.typeArguments = ts.factory.createNodeArray(typeArguments); } return node; } - function tryGetThisParameterDeclaration(signature: Signature, context: NodeBuilderContext) { + function tryGetThisParameterDeclaration(signature: ts.Signature, context: NodeBuilderContext) { if (signature.thisParameter) { return symbolToParameterDeclaration(signature.thisParameter, context); } if (signature.declaration) { - const thisTag = getJSDocThisTag(signature.declaration); + const thisTag = ts.getJSDocThisTag(signature.declaration); if (thisTag && thisTag.typeExpression) { - return factory.createParameterDeclaration( + return ts.factory.createParameterDeclaration( /* decorators */ undefined, /* modifiers */ undefined, - /* dotDotDotToken */ undefined, - "this", - /* questionToken */ undefined, - typeToTypeNodeHelper(getTypeFromTypeNode(thisTag.typeExpression), context) - ); + /* dotDotDotToken */ undefined, "this", + /* questionToken */ undefined, typeToTypeNodeHelper(getTypeFromTypeNode(thisTag.typeExpression), context)); } } } - function typeParameterToDeclarationWithConstraint(type: TypeParameter, context: NodeBuilderContext, constraintNode: TypeNode | undefined): TypeParameterDeclaration { + function typeParameterToDeclarationWithConstraint(type: ts.TypeParameter, context: NodeBuilderContext, constraintNode: ts.TypeNode | undefined): ts.TypeParameterDeclaration { const savedContextFlags = context.flags; - context.flags &= ~NodeBuilderFlags.WriteTypeParametersInQualifiedName; // Avoids potential infinite loop when building for a claimspace with a generic - const modifiers = factory.createModifiersFromModifierFlags(getVarianceModifiers(type)); + context.flags &= ~ts.NodeBuilderFlags.WriteTypeParametersInQualifiedName; // Avoids potential infinite loop when building for a claimspace with a generic + const modifiers = ts.factory.createModifiersFromModifierFlags(getVarianceModifiers(type)); const name = typeParameterToName(type, context); const defaultParameter = getDefaultFromTypeParameter(type); const defaultParameterNode = defaultParameter && typeToTypeNodeHelper(defaultParameter, context); context.flags = savedContextFlags; - return factory.createTypeParameterDeclaration(modifiers, name, constraintNode, defaultParameterNode); + return ts.factory.createTypeParameterDeclaration(modifiers, name, constraintNode, defaultParameterNode); } - function typeParameterToDeclaration(type: TypeParameter, context: NodeBuilderContext, constraint = getConstraintOfTypeParameter(type)): TypeParameterDeclaration { + function typeParameterToDeclaration(type: ts.TypeParameter, context: NodeBuilderContext, constraint = getConstraintOfTypeParameter(type)): ts.TypeParameterDeclaration { const constraintNode = constraint && typeToTypeNodeHelper(constraint, context); return typeParameterToDeclarationWithConstraint(type, context, constraintNode); } - function symbolToParameterDeclaration(parameterSymbol: Symbol, context: NodeBuilderContext, preserveModifierFlags?: boolean, privateSymbolVisitor?: (s: Symbol) => void, bundledImports?: boolean): ParameterDeclaration { - let parameterDeclaration: ParameterDeclaration | JSDocParameterTag | undefined = getDeclarationOfKind(parameterSymbol, SyntaxKind.Parameter); - if (!parameterDeclaration && !isTransientSymbol(parameterSymbol)) { - parameterDeclaration = getDeclarationOfKind(parameterSymbol, SyntaxKind.JSDocParameterTag); + function symbolToParameterDeclaration(parameterSymbol: ts.Symbol, context: NodeBuilderContext, preserveModifierFlags?: boolean, privateSymbolVisitor?: (s: ts.Symbol) => void, bundledImports?: boolean): ts.ParameterDeclaration { + let parameterDeclaration: ts.ParameterDeclaration | ts.JSDocParameterTag | undefined = ts.getDeclarationOfKind(parameterSymbol, ts.SyntaxKind.Parameter); + if (!parameterDeclaration && !ts.isTransientSymbol(parameterSymbol)) { + parameterDeclaration = ts.getDeclarationOfKind(parameterSymbol, ts.SyntaxKind.JSDocParameterTag); } let parameterType = getTypeOfSymbol(parameterSymbol); @@ -5917,73 +5750,65 @@ namespace ts { } const parameterTypeNode = serializeTypeForDeclaration(context, parameterType, parameterSymbol, context.enclosingDeclaration, privateSymbolVisitor, bundledImports); - const modifiers = !(context.flags & NodeBuilderFlags.OmitParameterModifiers) && preserveModifierFlags && parameterDeclaration && parameterDeclaration.modifiers ? parameterDeclaration.modifiers.map(factory.cloneNode) : undefined; - const isRest = parameterDeclaration && isRestParameter(parameterDeclaration) || getCheckFlags(parameterSymbol) & CheckFlags.RestParameter; - const dotDotDotToken = isRest ? factory.createToken(SyntaxKind.DotDotDotToken) : undefined; + const modifiers = !(context.flags & ts.NodeBuilderFlags.OmitParameterModifiers) && preserveModifierFlags && parameterDeclaration && parameterDeclaration.modifiers ? parameterDeclaration.modifiers.map(ts.factory.cloneNode) : undefined; + const isRest = parameterDeclaration && ts.isRestParameter(parameterDeclaration) || ts.getCheckFlags(parameterSymbol) & ts.CheckFlags.RestParameter; + const dotDotDotToken = isRest ? ts.factory.createToken(ts.SyntaxKind.DotDotDotToken) : undefined; const name = parameterDeclaration ? parameterDeclaration.name ? - parameterDeclaration.name.kind === SyntaxKind.Identifier ? setEmitFlags(factory.cloneNode(parameterDeclaration.name), EmitFlags.NoAsciiEscaping) : - parameterDeclaration.name.kind === SyntaxKind.QualifiedName ? setEmitFlags(factory.cloneNode(parameterDeclaration.name.right), EmitFlags.NoAsciiEscaping) : + parameterDeclaration.name.kind === ts.SyntaxKind.Identifier ? ts.setEmitFlags(ts.factory.cloneNode(parameterDeclaration.name), ts.EmitFlags.NoAsciiEscaping) : + parameterDeclaration.name.kind === ts.SyntaxKind.QualifiedName ? ts.setEmitFlags(ts.factory.cloneNode(parameterDeclaration.name.right), ts.EmitFlags.NoAsciiEscaping) : cloneBindingName(parameterDeclaration.name) : - symbolName(parameterSymbol) : - symbolName(parameterSymbol); - const isOptional = parameterDeclaration && isOptionalParameter(parameterDeclaration) || getCheckFlags(parameterSymbol) & CheckFlags.OptionalParameter; - const questionToken = isOptional ? factory.createToken(SyntaxKind.QuestionToken) : undefined; - const parameterNode = factory.createParameterDeclaration( - /*decorators*/ undefined, - modifiers, - dotDotDotToken, - name, - questionToken, - parameterTypeNode, + ts.symbolName(parameterSymbol) : + ts.symbolName(parameterSymbol); + const isOptional = parameterDeclaration && isOptionalParameter(parameterDeclaration) || ts.getCheckFlags(parameterSymbol) & ts.CheckFlags.OptionalParameter; + const questionToken = isOptional ? ts.factory.createToken(ts.SyntaxKind.QuestionToken) : undefined; + const parameterNode = ts.factory.createParameterDeclaration( + /*decorators*/ undefined, modifiers, dotDotDotToken, name, questionToken, parameterTypeNode, /*initializer*/ undefined); - context.approximateLength += symbolName(parameterSymbol).length + 3; + context.approximateLength += ts.symbolName(parameterSymbol).length + 3; return parameterNode; - function cloneBindingName(node: BindingName): BindingName { - return elideInitializerAndSetEmitFlags(node) as BindingName; - function elideInitializerAndSetEmitFlags(node: Node): Node { - if (context.tracker.trackSymbol && isComputedPropertyName(node) && isLateBindableName(node)) { + function cloneBindingName(node: ts.BindingName): ts.BindingName { + return elideInitializerAndSetEmitFlags(node) as ts.BindingName; + function elideInitializerAndSetEmitFlags(node: ts.Node): ts.Node { + if (context.tracker.trackSymbol && ts.isComputedPropertyName(node) && isLateBindableName(node)) { trackComputedName(node.expression, context.enclosingDeclaration, context); } - let visited = visitEachChild(node, elideInitializerAndSetEmitFlags, nullTransformationContext, /*nodesVisitor*/ undefined, elideInitializerAndSetEmitFlags)!; - if (isBindingElement(visited)) { - visited = factory.updateBindingElement( - visited, - visited.dotDotDotToken, - visited.propertyName, - visited.name, + let visited = ts.visitEachChild(node, elideInitializerAndSetEmitFlags, ts.nullTransformationContext, /*nodesVisitor*/ undefined, elideInitializerAndSetEmitFlags)!; + if (ts.isBindingElement(visited)) { + visited = ts.factory.updateBindingElement(visited, visited.dotDotDotToken, visited.propertyName, visited.name, /*initializer*/ undefined); } - if (!nodeIsSynthesized(visited)) { - visited = factory.cloneNode(visited); + if (!ts.nodeIsSynthesized(visited)) { + visited = ts.factory.cloneNode(visited); } - return setEmitFlags(visited, EmitFlags.SingleLine | EmitFlags.NoAsciiEscaping); + return ts.setEmitFlags(visited, ts.EmitFlags.SingleLine | ts.EmitFlags.NoAsciiEscaping); } } } - function trackComputedName(accessExpression: EntityNameOrEntityNameExpression, enclosingDeclaration: Node | undefined, context: NodeBuilderContext) { - if (!context.tracker.trackSymbol) return; + function trackComputedName(accessExpression: ts.EntityNameOrEntityNameExpression, enclosingDeclaration: ts.Node | undefined, context: NodeBuilderContext) { + if (!context.tracker.trackSymbol) + return; // get symbol of the first identifier of the entityName - const firstIdentifier = getFirstIdentifier(accessExpression); - const name = resolveName(firstIdentifier, firstIdentifier.escapedText, SymbolFlags.Value | SymbolFlags.ExportValue, /*nodeNotFoundErrorMessage*/ undefined, /*nameArg*/ undefined, /*isUse*/ true); + const firstIdentifier = ts.getFirstIdentifier(accessExpression); + const name = resolveName(firstIdentifier, firstIdentifier.escapedText, ts.SymbolFlags.Value | ts.SymbolFlags.ExportValue, /*nodeNotFoundErrorMessage*/ undefined, /*nameArg*/ undefined, /*isUse*/ true); if (name) { - context.tracker.trackSymbol(name, enclosingDeclaration, SymbolFlags.Value); + context.tracker.trackSymbol(name, enclosingDeclaration, ts.SymbolFlags.Value); } } - function lookupSymbolChain(symbol: Symbol, context: NodeBuilderContext, meaning: SymbolFlags, yieldModuleSymbol?: boolean) { + function lookupSymbolChain(symbol: ts.Symbol, context: NodeBuilderContext, meaning: ts.SymbolFlags, yieldModuleSymbol?: boolean) { context.tracker.trackSymbol!(symbol, context.enclosingDeclaration, meaning); // TODO: GH#18217 return lookupSymbolChainWorker(symbol, context, meaning, yieldModuleSymbol); } - function lookupSymbolChainWorker(symbol: Symbol, context: NodeBuilderContext, meaning: SymbolFlags, yieldModuleSymbol?: boolean) { + function lookupSymbolChainWorker(symbol: ts.Symbol, context: NodeBuilderContext, meaning: ts.SymbolFlags, yieldModuleSymbol?: boolean) { // Try to get qualified name if the symbol is not a type parameter and there is an enclosing declaration. - let chain: Symbol[]; - const isTypeParameter = symbol.flags & SymbolFlags.TypeParameter; - if (!isTypeParameter && (context.enclosingDeclaration || context.flags & NodeBuilderFlags.UseFullyQualifiedType) && !(context.flags & NodeBuilderFlags.DoNotIncludeSymbolChain)) { - chain = Debug.checkDefined(getSymbolChain(symbol, meaning, /*endOfChain*/ true)); - Debug.assert(chain && chain.length > 0); + let chain: ts.Symbol[]; + const isTypeParameter = symbol.flags & ts.SymbolFlags.TypeParameter; + if (!isTypeParameter && (context.enclosingDeclaration || context.flags & ts.NodeBuilderFlags.UseFullyQualifiedType) && !(context.flags & ts.NodeBuilderFlags.DoNotIncludeSymbolChain)) { + chain = ts.Debug.checkDefined(getSymbolChain(symbol, meaning, /*endOfChain*/ true)); + ts.Debug.assert(chain && chain.length > 0); } else { chain = [symbol]; @@ -5991,17 +5816,16 @@ namespace ts { return chain; /** @param endOfChain Set to false for recursive calls; non-recursive calls should always output something. */ - function getSymbolChain(symbol: Symbol, meaning: SymbolFlags, endOfChain: boolean): Symbol[] | undefined { - let accessibleSymbolChain = getAccessibleSymbolChain(symbol, context.enclosingDeclaration, meaning, !!(context.flags & NodeBuilderFlags.UseOnlyExternalAliasing)); + function getSymbolChain(symbol: ts.Symbol, meaning: ts.SymbolFlags, endOfChain: boolean): ts.Symbol[] | undefined { + let accessibleSymbolChain = getAccessibleSymbolChain(symbol, context.enclosingDeclaration, meaning, !!(context.flags & ts.NodeBuilderFlags.UseOnlyExternalAliasing)); let parentSpecifiers: (string | undefined)[]; if (!accessibleSymbolChain || needsQualification(accessibleSymbolChain[0], context.enclosingDeclaration, accessibleSymbolChain.length === 1 ? meaning : getQualifiedLeftMeaning(meaning))) { // Go up and add our parent. const parents = getContainersOfSymbol(accessibleSymbolChain ? accessibleSymbolChain[0] : symbol, context.enclosingDeclaration, meaning); - if (length(parents)) { - parentSpecifiers = parents!.map(symbol => - some(symbol.declarations, hasNonGlobalAugmentationExternalModuleSymbol) + if (ts.length(parents)) { + parentSpecifiers = parents!.map(symbol => ts.some(symbol.declarations, hasNonGlobalAugmentationExternalModuleSymbol) ? getSpecifierForModuleSymbol(symbol, context) : undefined); const indices = parents!.map((_, i) => i); @@ -6010,8 +5834,8 @@ namespace ts { for (const parent of sortedParents) { const parentChain = getSymbolChain(parent, getQualifiedLeftMeaning(meaning), /*endOfChain*/ false); if (parentChain) { - if (parent.exports && parent.exports.get(InternalSymbolName.ExportEquals) && - getSymbolIfSameReference(parent.exports.get(InternalSymbolName.ExportEquals)!, symbol)) { + if (parent.exports && parent.exports.get(ts.InternalSymbolName.ExportEquals) && + getSymbolIfSameReference(parent.exports.get(ts.InternalSymbolName.ExportEquals)!, symbol)) { // parentChain root _is_ symbol - symbol is a module export=, so it kinda looks like it's own parent // No need to lookup an alias for the symbol in itself accessibleSymbolChain = parentChain; @@ -6031,9 +5855,9 @@ namespace ts { // If this is the last part of outputting the symbol, always output. The cases apply only to parent symbols. endOfChain || // If a parent symbol is an anonymous type, don't write it. - !(symbol.flags & (SymbolFlags.TypeLiteral | SymbolFlags.ObjectLiteral))) { + !(symbol.flags & (ts.SymbolFlags.TypeLiteral | ts.SymbolFlags.ObjectLiteral))) { // If a parent symbol is an external module, don't write it. (We prefer just `x` vs `"foo/bar".x`.) - if (!endOfChain && !yieldModuleSymbol && !!forEach(symbol.declarations, hasNonGlobalAugmentationExternalModuleSymbol)) { + if (!endOfChain && !yieldModuleSymbol && !!ts.forEach(symbol.declarations, hasNonGlobalAugmentationExternalModuleSymbol)) { return; } return [symbol]; @@ -6043,10 +5867,10 @@ namespace ts { const specifierA = parentSpecifiers[a]; const specifierB = parentSpecifiers[b]; if (specifierA && specifierB) { - const isBRelative = pathIsRelative(specifierB); - if (pathIsRelative(specifierA) === isBRelative) { + const isBRelative = ts.pathIsRelative(specifierB); + if (ts.pathIsRelative(specifierA) === isBRelative) { // Both relative or both non-relative, sort by number of parts - return moduleSpecifiers.countPathComponents(specifierA) - moduleSpecifiers.countPathComponents(specifierB); + return ts.moduleSpecifiers.countPathComponents(specifierA) - ts.moduleSpecifiers.countPathComponents(specifierB); } if (isBRelative) { // A is non-relative, B is relative: prefer A @@ -6060,32 +5884,30 @@ namespace ts { } } - function typeParametersToTypeParameterDeclarations(symbol: Symbol, context: NodeBuilderContext) { - let typeParameterNodes: NodeArray | undefined; + function typeParametersToTypeParameterDeclarations(symbol: ts.Symbol, context: NodeBuilderContext) { + let typeParameterNodes: ts.NodeArray | undefined; const targetSymbol = getTargetSymbol(symbol); - if (targetSymbol.flags & (SymbolFlags.Class | SymbolFlags.Interface | SymbolFlags.TypeAlias)) { - typeParameterNodes = factory.createNodeArray(map(getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(symbol), tp => typeParameterToDeclaration(tp, context))); + if (targetSymbol.flags & (ts.SymbolFlags.Class | ts.SymbolFlags.Interface | ts.SymbolFlags.TypeAlias)) { + typeParameterNodes = ts.factory.createNodeArray(ts.map(getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(symbol), tp => typeParameterToDeclaration(tp, context))); } return typeParameterNodes; } - function lookupTypeParameterNodes(chain: Symbol[], index: number, context: NodeBuilderContext) { - Debug.assert(chain && 0 <= index && index < chain.length); + function lookupTypeParameterNodes(chain: ts.Symbol[], index: number, context: NodeBuilderContext) { + ts.Debug.assert(chain && 0 <= index && index < chain.length); const symbol = chain[index]; const symbolId = getSymbolId(symbol); if (context.typeParameterSymbolList?.has(symbolId)) { return undefined; } - (context.typeParameterSymbolList || (context.typeParameterSymbolList = new Set())).add(symbolId); - let typeParameterNodes: readonly TypeNode[] | readonly TypeParameterDeclaration[] | undefined; - if (context.flags & NodeBuilderFlags.WriteTypeParametersInQualifiedName && index < (chain.length - 1)) { + (context.typeParameterSymbolList || (context.typeParameterSymbolList = new ts.Set())).add(symbolId); + let typeParameterNodes: readonly ts.TypeNode[] | readonly ts.TypeParameterDeclaration[] | undefined; + if (context.flags & ts.NodeBuilderFlags.WriteTypeParametersInQualifiedName && index < (chain.length - 1)) { const parentSymbol = symbol; const nextSymbol = chain[index + 1]; - if (getCheckFlags(nextSymbol) & CheckFlags.Instantiated) { - const params = getTypeParametersOfClassOrInterface( - parentSymbol.flags & SymbolFlags.Alias ? resolveAlias(parentSymbol) : parentSymbol - ); - typeParameterNodes = mapToTypeNodes(map(params, t => getMappedType(t, (nextSymbol as TransientSymbol).mapper!)), context); + if (ts.getCheckFlags(nextSymbol) & ts.CheckFlags.Instantiated) { + const params = getTypeParametersOfClassOrInterface(parentSymbol.flags & ts.SymbolFlags.Alias ? resolveAlias(parentSymbol) : parentSymbol); + typeParameterNodes = mapToTypeNodes(ts.map(params, t => getMappedType(t, (nextSymbol as ts.TransientSymbol).mapper!)), context); } else { typeParameterNodes = typeParametersToTypeParameterDeclarations(symbol, context); @@ -6097,19 +5919,19 @@ namespace ts { /** * Given A[B][C][D], finds A[B] */ - function getTopmostIndexedAccessType(top: IndexedAccessTypeNode): IndexedAccessTypeNode { - if (isIndexedAccessTypeNode(top.objectType)) { + function getTopmostIndexedAccessType(top: ts.IndexedAccessTypeNode): ts.IndexedAccessTypeNode { + if (ts.isIndexedAccessTypeNode(top.objectType)) { return getTopmostIndexedAccessType(top.objectType); } return top; } - function getSpecifierForModuleSymbol(symbol: Symbol, context: NodeBuilderContext, overrideImportMode?: SourceFile["impliedNodeFormat"]) { - let file = getDeclarationOfKind(symbol, SyntaxKind.SourceFile); + function getSpecifierForModuleSymbol(symbol: ts.Symbol, context: NodeBuilderContext, overrideImportMode?: ts.SourceFile["impliedNodeFormat"]) { + let file = ts.getDeclarationOfKind(symbol, ts.SyntaxKind.SourceFile); if (!file) { - const equivalentFileSymbol = firstDefined(symbol.declarations, d => getFileSymbolIfFileSymbolExportEqualsContainer(d, symbol)); + const equivalentFileSymbol = ts.firstDefined(symbol.declarations, d => getFileSymbolIfFileSymbolExportEqualsContainer(d, symbol)); if (equivalentFileSymbol) { - file = getDeclarationOfKind(equivalentFileSymbol, SyntaxKind.SourceFile); + file = ts.getDeclarationOfKind(equivalentFileSymbol, ts.SyntaxKind.SourceFile); } } if (file && file.moduleName !== undefined) { @@ -6118,8 +5940,8 @@ namespace ts { } if (!file) { if (context.tracker.trackReferencedAmbientModule) { - const ambientDecls = filter(symbol.declarations, isAmbientModule); - if (length(ambientDecls)) { + const ambientDecls = ts.filter(symbol.declarations, ts.isAmbientModule); + if (ts.length(ambientDecls)) { for (const decl of ambientDecls!) { context.tracker.trackReferencedAmbientModule(decl, symbol); } @@ -6134,82 +5956,70 @@ namespace ts { if (ambientModuleSymbolRegex.test(symbol.escapedName as string)) { return (symbol.escapedName as string).substring(1, (symbol.escapedName as string).length - 1); } - return getSourceFileOfNode(getNonAugmentationDeclaration(symbol)!).fileName; // A resolver may not be provided for baselines and errors - in those cases we use the fileName in full + return ts.getSourceFileOfNode(ts.getNonAugmentationDeclaration(symbol)!).fileName; // A resolver may not be provided for baselines and errors - in those cases we use the fileName in full } - const contextFile = getSourceFileOfNode(getOriginalNode(context.enclosingDeclaration)); + const contextFile = ts.getSourceFileOfNode(ts.getOriginalNode(context.enclosingDeclaration)); const resolutionMode = overrideImportMode || contextFile?.impliedNodeFormat; const cacheKey = getSpecifierCacheKey(contextFile.path, resolutionMode); const links = getSymbolLinks(symbol); let specifier = links.specifierCache && links.specifierCache.get(cacheKey); if (!specifier) { - const isBundle = !!outFile(compilerOptions); + const isBundle = !!ts.outFile(compilerOptions); // For declaration bundles, we need to generate absolute paths relative to the common source dir for imports, // just like how the declaration emitter does for the ambient module declarations - we can easily accomplish this // using the `baseUrl` compiler option (which we would otherwise never use in declaration emit) and a non-relative // specifier preference const { moduleResolverHost } = context.tracker; const specifierCompilerOptions = isBundle ? { ...compilerOptions, baseUrl: moduleResolverHost.getCommonSourceDirectory() } : compilerOptions; - specifier = first(moduleSpecifiers.getModuleSpecifiers( - symbol, - checker, - specifierCompilerOptions, - contextFile, - moduleResolverHost, - { + specifier = ts.first(ts.moduleSpecifiers.getModuleSpecifiers(symbol, checker, specifierCompilerOptions, contextFile, moduleResolverHost, { importModuleSpecifierPreference: isBundle ? "non-relative" : "project-relative", importModuleSpecifierEnding: isBundle ? "minimal" - : resolutionMode === ModuleKind.ESNext ? "js" + : resolutionMode === ts.ModuleKind.ESNext ? "js" : undefined, - }, - { overrideImportMode } - )); - links.specifierCache ??= new Map(); + }, { overrideImportMode })); + links.specifierCache ??= new ts.Map(); links.specifierCache.set(cacheKey, specifier); } return specifier; - function getSpecifierCacheKey(path: string, mode: SourceFile["impliedNodeFormat"] | undefined) { + function getSpecifierCacheKey(path: string, mode: ts.SourceFile["impliedNodeFormat"] | undefined) { return mode === undefined ? path : `${mode}|${path}`; } } - function symbolToEntityNameNode(symbol: Symbol): EntityName { - const identifier = factory.createIdentifier(unescapeLeadingUnderscores(symbol.escapedName)); - return symbol.parent ? factory.createQualifiedName(symbolToEntityNameNode(symbol.parent), identifier) : identifier; + function symbolToEntityNameNode(symbol: ts.Symbol): ts.EntityName { + const identifier = ts.factory.createIdentifier(ts.unescapeLeadingUnderscores(symbol.escapedName)); + return symbol.parent ? ts.factory.createQualifiedName(symbolToEntityNameNode(symbol.parent), identifier) : identifier; } - function symbolToTypeNode(symbol: Symbol, context: NodeBuilderContext, meaning: SymbolFlags, overrideTypeArguments?: readonly TypeNode[]): TypeNode { - const chain = lookupSymbolChain(symbol, context, meaning, !(context.flags & NodeBuilderFlags.UseAliasDefinedOutsideCurrentScope)); // If we're using aliases outside the current scope, dont bother with the module - - const isTypeOf = meaning === SymbolFlags.Value; - if (some(chain[0].declarations, hasNonGlobalAugmentationExternalModuleSymbol)) { + function symbolToTypeNode(symbol: ts.Symbol, context: NodeBuilderContext, meaning: ts.SymbolFlags, overrideTypeArguments?: readonly ts.TypeNode[]): ts.TypeNode { + const chain = lookupSymbolChain(symbol, context, meaning, !(context.flags & ts.NodeBuilderFlags.UseAliasDefinedOutsideCurrentScope)); // If we're using aliases outside the current scope, dont bother with the module + const isTypeOf = meaning === ts.SymbolFlags.Value; + if (ts.some(chain[0].declarations, hasNonGlobalAugmentationExternalModuleSymbol)) { // module is root, must use `ImportTypeNode` const nonRootParts = chain.length > 1 ? createAccessFromSymbolChain(chain, chain.length - 1, 1) : undefined; const typeParameterNodes = overrideTypeArguments || lookupTypeParameterNodes(chain, 0, context); - const contextFile = getSourceFileOfNode(getOriginalNode(context.enclosingDeclaration)); - const targetFile = getSourceFileOfModule(chain[0]); + const contextFile = ts.getSourceFileOfNode(ts.getOriginalNode(context.enclosingDeclaration)); + const targetFile = ts.getSourceFileOfModule(chain[0]); let specifier: string | undefined; - let assertion: ImportTypeAssertionContainer | undefined; - if (getEmitModuleResolutionKind(compilerOptions) === ModuleResolutionKind.Node16 || getEmitModuleResolutionKind(compilerOptions) === ModuleResolutionKind.NodeNext) { + let assertion: ts.ImportTypeAssertionContainer | undefined; + if (ts.getEmitModuleResolutionKind(compilerOptions) === ts.ModuleResolutionKind.Node16 || ts.getEmitModuleResolutionKind(compilerOptions) === ts.ModuleResolutionKind.NodeNext) { // An `import` type directed at an esm format file is only going to resolve in esm mode - set the esm mode assertion - if (targetFile?.impliedNodeFormat === ModuleKind.ESNext && targetFile.impliedNodeFormat !== contextFile?.impliedNodeFormat) { - specifier = getSpecifierForModuleSymbol(chain[0], context, ModuleKind.ESNext); - assertion = factory.createImportTypeAssertionContainer(factory.createAssertClause(factory.createNodeArray([ - factory.createAssertEntry( - factory.createStringLiteral("resolution-mode"), - factory.createStringLiteral("import") - ) + if (targetFile?.impliedNodeFormat === ts.ModuleKind.ESNext && targetFile.impliedNodeFormat !== contextFile?.impliedNodeFormat) { + specifier = getSpecifierForModuleSymbol(chain[0], context, ts.ModuleKind.ESNext); + assertion = ts.factory.createImportTypeAssertionContainer(ts.factory.createAssertClause(ts.factory.createNodeArray([ + ts.factory.createAssertEntry(ts.factory.createStringLiteral("resolution-mode"), ts.factory.createStringLiteral("import")) ]))); } } if (!specifier) { specifier = getSpecifierForModuleSymbol(chain[0], context); } - if (!(context.flags & NodeBuilderFlags.AllowNodeModulesRelativePaths) && getEmitModuleResolutionKind(compilerOptions) !== ModuleResolutionKind.Classic && specifier.indexOf("/node_modules/") >= 0) { + if (!(context.flags & ts.NodeBuilderFlags.AllowNodeModulesRelativePaths) && ts.getEmitModuleResolutionKind(compilerOptions) !== ts.ModuleResolutionKind.Classic && specifier.indexOf("/node_modules/") >= 0) { const oldSpecifier = specifier; - if (getEmitModuleResolutionKind(compilerOptions) === ModuleResolutionKind.Node16 || getEmitModuleResolutionKind(compilerOptions) === ModuleResolutionKind.NodeNext) { + if (ts.getEmitModuleResolutionKind(compilerOptions) === ts.ModuleResolutionKind.Node16 || ts.getEmitModuleResolutionKind(compilerOptions) === ts.ModuleResolutionKind.NodeNext) { // We might be able to write a portable import type using a mode override; try specifier generation again, but with a different mode set - const swappedMode = contextFile?.impliedNodeFormat === ModuleKind.ESNext ? ModuleKind.CommonJS : ModuleKind.ESNext; + const swappedMode = contextFile?.impliedNodeFormat === ts.ModuleKind.ESNext ? ts.ModuleKind.CommonJS : ts.ModuleKind.ESNext; specifier = getSpecifierForModuleSymbol(chain[0], context, swappedMode); if (specifier.indexOf("/node_modules/") >= 0) { @@ -6217,11 +6027,8 @@ namespace ts { specifier = oldSpecifier; } else { - assertion = factory.createImportTypeAssertionContainer(factory.createAssertClause(factory.createNodeArray([ - factory.createAssertEntry( - factory.createStringLiteral("resolution-mode"), - factory.createStringLiteral(swappedMode === ModuleKind.ESNext ? "import" : "require") - ) + assertion = ts.factory.createImportTypeAssertionContainer(ts.factory.createAssertClause(ts.factory.createNodeArray([ + ts.factory.createAssertEntry(ts.factory.createStringLiteral("resolution-mode"), ts.factory.createStringLiteral(swappedMode === ts.ModuleKind.ESNext ? "import" : "require")) ]))); } } @@ -6235,55 +6042,56 @@ namespace ts { } } } - const lit = factory.createLiteralTypeNode(factory.createStringLiteral(specifier)); - if (context.tracker.trackExternalModuleSymbolOfImportTypeNode) context.tracker.trackExternalModuleSymbolOfImportTypeNode(chain[0]); + const lit = ts.factory.createLiteralTypeNode(ts.factory.createStringLiteral(specifier)); + if (context.tracker.trackExternalModuleSymbolOfImportTypeNode) + context.tracker.trackExternalModuleSymbolOfImportTypeNode(chain[0]); context.approximateLength += specifier.length + 10; // specifier + import("") - if (!nonRootParts || isEntityName(nonRootParts)) { + if (!nonRootParts || ts.isEntityName(nonRootParts)) { if (nonRootParts) { - const lastId = isIdentifier(nonRootParts) ? nonRootParts : nonRootParts.right; + const lastId = ts.isIdentifier(nonRootParts) ? nonRootParts : nonRootParts.right; lastId.typeArguments = undefined; } - return factory.createImportTypeNode(lit, assertion, nonRootParts as EntityName, typeParameterNodes as readonly TypeNode[], isTypeOf); + return ts.factory.createImportTypeNode(lit, assertion, nonRootParts as ts.EntityName, typeParameterNodes as readonly ts.TypeNode[], isTypeOf); } else { const splitNode = getTopmostIndexedAccessType(nonRootParts); - const qualifier = (splitNode.objectType as TypeReferenceNode).typeName; - return factory.createIndexedAccessTypeNode(factory.createImportTypeNode(lit, assertion, qualifier, typeParameterNodes as readonly TypeNode[], isTypeOf), splitNode.indexType); + const qualifier = (splitNode.objectType as ts.TypeReferenceNode).typeName; + return ts.factory.createIndexedAccessTypeNode(ts.factory.createImportTypeNode(lit, assertion, qualifier, typeParameterNodes as readonly ts.TypeNode[], isTypeOf), splitNode.indexType); } } const entityName = createAccessFromSymbolChain(chain, chain.length - 1, 0); - if (isIndexedAccessTypeNode(entityName)) { + if (ts.isIndexedAccessTypeNode(entityName)) { return entityName; // Indexed accesses can never be `typeof` } if (isTypeOf) { - return factory.createTypeQueryNode(entityName); + return ts.factory.createTypeQueryNode(entityName); } else { - const lastId = isIdentifier(entityName) ? entityName : entityName.right; + const lastId = ts.isIdentifier(entityName) ? entityName : entityName.right; const lastTypeArgs = lastId.typeArguments; lastId.typeArguments = undefined; - return factory.createTypeReferenceNode(entityName, lastTypeArgs as NodeArray); + return ts.factory.createTypeReferenceNode(entityName, lastTypeArgs as ts.NodeArray); } - function createAccessFromSymbolChain(chain: Symbol[], index: number, stopper: number): EntityName | IndexedAccessTypeNode { + function createAccessFromSymbolChain(chain: ts.Symbol[], index: number, stopper: number): ts.EntityName | ts.IndexedAccessTypeNode { const typeParameterNodes = index === (chain.length - 1) ? overrideTypeArguments : lookupTypeParameterNodes(chain, index, context); const symbol = chain[index]; const parent = chain[index - 1]; let symbolName: string | undefined; if (index === 0) { - context.flags |= NodeBuilderFlags.InInitialEntityName; + context.flags |= ts.NodeBuilderFlags.InInitialEntityName; symbolName = getNameOfSymbolAsWritten(symbol, context); context.approximateLength += (symbolName ? symbolName.length : 0) + 1; - context.flags ^= NodeBuilderFlags.InInitialEntityName; + context.flags ^= ts.NodeBuilderFlags.InInitialEntityName; } else { if (parent && getExportsOfSymbol(parent)) { const exports = getExportsOfSymbol(parent); - forEachEntry(exports, (ex, name) => { - if (getSymbolIfSameReference(ex, symbol) && !isLateBoundName(name) && name !== InternalSymbolName.ExportEquals) { - symbolName = unescapeLeadingUnderscores(name); + ts.forEachEntry(exports, (ex, name) => { + if (getSymbolIfSameReference(ex, symbol) && !isLateBoundName(name) && name !== ts.InternalSymbolName.ExportEquals) { + symbolName = ts.unescapeLeadingUnderscores(name); return true; } }); @@ -6291,11 +6099,11 @@ namespace ts { } if (symbolName === undefined) { - const name = firstDefined(symbol.declarations, getNameOfDeclaration); - if (name && isComputedPropertyName(name) && isEntityName(name.expression)) { + const name = ts.firstDefined(symbol.declarations, ts.getNameOfDeclaration); + if (name && ts.isComputedPropertyName(name) && ts.isEntityName(name.expression)) { const LHS = createAccessFromSymbolChain(chain, index - 1, stopper); - if (isEntityName(LHS)) { - return factory.createIndexedAccessTypeNode(factory.createParenthesizedType(factory.createTypeQueryNode(LHS)), factory.createTypeQueryNode(name.expression)); + if (ts.isEntityName(LHS)) { + return ts.factory.createIndexedAccessTypeNode(ts.factory.createParenthesizedType(ts.factory.createTypeQueryNode(LHS)), ts.factory.createTypeQueryNode(name.expression)); } return LHS; } @@ -6303,37 +6111,37 @@ namespace ts { } context.approximateLength += symbolName.length + 1; - if (!(context.flags & NodeBuilderFlags.ForbidIndexedAccessSymbolReferences) && parent && + if (!(context.flags & ts.NodeBuilderFlags.ForbidIndexedAccessSymbolReferences) && parent && getMembersOfSymbol(parent) && getMembersOfSymbol(parent).get(symbol.escapedName) && getSymbolIfSameReference(getMembersOfSymbol(parent).get(symbol.escapedName)!, symbol)) { // Should use an indexed access const LHS = createAccessFromSymbolChain(chain, index - 1, stopper); - if (isIndexedAccessTypeNode(LHS)) { - return factory.createIndexedAccessTypeNode(LHS, factory.createLiteralTypeNode(factory.createStringLiteral(symbolName))); + if (ts.isIndexedAccessTypeNode(LHS)) { + return ts.factory.createIndexedAccessTypeNode(LHS, ts.factory.createLiteralTypeNode(ts.factory.createStringLiteral(symbolName))); } else { - return factory.createIndexedAccessTypeNode(factory.createTypeReferenceNode(LHS, typeParameterNodes as readonly TypeNode[]), factory.createLiteralTypeNode(factory.createStringLiteral(symbolName))); + return ts.factory.createIndexedAccessTypeNode(ts.factory.createTypeReferenceNode(LHS, typeParameterNodes as readonly ts.TypeNode[]), ts.factory.createLiteralTypeNode(ts.factory.createStringLiteral(symbolName))); } } - const identifier = setEmitFlags(factory.createIdentifier(symbolName, typeParameterNodes), EmitFlags.NoAsciiEscaping); + const identifier = ts.setEmitFlags(ts.factory.createIdentifier(symbolName, typeParameterNodes), ts.EmitFlags.NoAsciiEscaping); identifier.symbol = symbol; if (index > stopper) { const LHS = createAccessFromSymbolChain(chain, index - 1, stopper); - if (!isEntityName(LHS)) { - return Debug.fail("Impossible construct - an export of an indexed access cannot be reachable"); + if (!ts.isEntityName(LHS)) { + return ts.Debug.fail("Impossible construct - an export of an indexed access cannot be reachable"); } - return factory.createQualifiedName(LHS, identifier); + return ts.factory.createQualifiedName(LHS, identifier); } return identifier; } } - function typeParameterShadowsNameInScope(escapedName: __String, context: NodeBuilderContext, type: TypeParameter) { - const result = resolveName(context.enclosingDeclaration, escapedName, SymbolFlags.Type, /*nameNotFoundArg*/ undefined, escapedName, /*isUse*/ false); + function typeParameterShadowsNameInScope(escapedName: ts.__String, context: NodeBuilderContext, type: ts.TypeParameter) { + const result = resolveName(context.enclosingDeclaration, escapedName, ts.SymbolFlags.Type, /*nameNotFoundArg*/ undefined, escapedName, /*isUse*/ false); if (result) { - if (result.flags & SymbolFlags.TypeParameter && result === type.symbol) { + if (result.flags & ts.SymbolFlags.TypeParameter && result === type.symbol) { return false; } return true; @@ -6341,156 +6149,156 @@ namespace ts { return false; } - function typeParameterToName(type: TypeParameter, context: NodeBuilderContext) { - if (context.flags & NodeBuilderFlags.GenerateNamesForShadowedTypeParams && context.typeParameterNames) { + function typeParameterToName(type: ts.TypeParameter, context: NodeBuilderContext) { + if (context.flags & ts.NodeBuilderFlags.GenerateNamesForShadowedTypeParams && context.typeParameterNames) { const cached = context.typeParameterNames.get(getTypeId(type)); if (cached) { return cached; } } - let result = symbolToName(type.symbol, context, SymbolFlags.Type, /*expectsIdentifier*/ true); - if (!(result.kind & SyntaxKind.Identifier)) { - return factory.createIdentifier("(Missing type parameter)"); + let result = symbolToName(type.symbol, context, ts.SymbolFlags.Type, /*expectsIdentifier*/ true); + if (!(result.kind & ts.SyntaxKind.Identifier)) { + return ts.factory.createIdentifier("(Missing type parameter)"); } - if (context.flags & NodeBuilderFlags.GenerateNamesForShadowedTypeParams) { + if (context.flags & ts.NodeBuilderFlags.GenerateNamesForShadowedTypeParams) { const rawtext = result.escapedText as string; let i = context.typeParameterNamesByTextNextNameCount?.get(rawtext) || 0; let text = rawtext; - while (context.typeParameterNamesByText?.has(text) || typeParameterShadowsNameInScope(text as __String, context, type)) { + while (context.typeParameterNamesByText?.has(text) || typeParameterShadowsNameInScope(text as ts.__String, context, type)) { i++; text = `${rawtext}_${i}`; } if (text !== rawtext) { - result = factory.createIdentifier(text, result.typeArguments); + result = ts.factory.createIdentifier(text, result.typeArguments); } // avoiding iterations of the above loop turns out to be worth it when `i` starts to get large, so we cache the max // `i` we've used thus far, to save work later - (context.typeParameterNamesByTextNextNameCount ||= new Map()).set(rawtext, i); - (context.typeParameterNames ||= new Map()).set(getTypeId(type), result); - (context.typeParameterNamesByText ||= new Set()).add(rawtext); + (context.typeParameterNamesByTextNextNameCount ||= new ts.Map()).set(rawtext, i); + (context.typeParameterNames ||= new ts.Map()).set(getTypeId(type), result); + (context.typeParameterNamesByText ||= new ts.Set()).add(rawtext); } return result; } - function symbolToName(symbol: Symbol, context: NodeBuilderContext, meaning: SymbolFlags, expectsIdentifier: true): Identifier; - function symbolToName(symbol: Symbol, context: NodeBuilderContext, meaning: SymbolFlags, expectsIdentifier: false): EntityName; - function symbolToName(symbol: Symbol, context: NodeBuilderContext, meaning: SymbolFlags, expectsIdentifier: boolean): EntityName { + function symbolToName(symbol: ts.Symbol, context: NodeBuilderContext, meaning: ts.SymbolFlags, expectsIdentifier: true): ts.Identifier; + function symbolToName(symbol: ts.Symbol, context: NodeBuilderContext, meaning: ts.SymbolFlags, expectsIdentifier: false): ts.EntityName; + function symbolToName(symbol: ts.Symbol, context: NodeBuilderContext, meaning: ts.SymbolFlags, expectsIdentifier: boolean): ts.EntityName { const chain = lookupSymbolChain(symbol, context, meaning); if (expectsIdentifier && chain.length !== 1 && !context.encounteredError - && !(context.flags & NodeBuilderFlags.AllowQualifiedNameInPlaceOfIdentifier)) { + && !(context.flags & ts.NodeBuilderFlags.AllowQualifiedNameInPlaceOfIdentifier)) { context.encounteredError = true; } return createEntityNameFromSymbolChain(chain, chain.length - 1); - function createEntityNameFromSymbolChain(chain: Symbol[], index: number): EntityName { + function createEntityNameFromSymbolChain(chain: ts.Symbol[], index: number): ts.EntityName { const typeParameterNodes = lookupTypeParameterNodes(chain, index, context); const symbol = chain[index]; if (index === 0) { - context.flags |= NodeBuilderFlags.InInitialEntityName; + context.flags |= ts.NodeBuilderFlags.InInitialEntityName; } const symbolName = getNameOfSymbolAsWritten(symbol, context); if (index === 0) { - context.flags ^= NodeBuilderFlags.InInitialEntityName; + context.flags ^= ts.NodeBuilderFlags.InInitialEntityName; } - const identifier = setEmitFlags(factory.createIdentifier(symbolName, typeParameterNodes), EmitFlags.NoAsciiEscaping); + const identifier = ts.setEmitFlags(ts.factory.createIdentifier(symbolName, typeParameterNodes), ts.EmitFlags.NoAsciiEscaping); identifier.symbol = symbol; - return index > 0 ? factory.createQualifiedName(createEntityNameFromSymbolChain(chain, index - 1), identifier) : identifier; + return index > 0 ? ts.factory.createQualifiedName(createEntityNameFromSymbolChain(chain, index - 1), identifier) : identifier; } } - function symbolToExpression(symbol: Symbol, context: NodeBuilderContext, meaning: SymbolFlags) { + function symbolToExpression(symbol: ts.Symbol, context: NodeBuilderContext, meaning: ts.SymbolFlags) { const chain = lookupSymbolChain(symbol, context, meaning); return createExpressionFromSymbolChain(chain, chain.length - 1); - function createExpressionFromSymbolChain(chain: Symbol[], index: number): Expression { + function createExpressionFromSymbolChain(chain: ts.Symbol[], index: number): ts.Expression { const typeParameterNodes = lookupTypeParameterNodes(chain, index, context); const symbol = chain[index]; if (index === 0) { - context.flags |= NodeBuilderFlags.InInitialEntityName; + context.flags |= ts.NodeBuilderFlags.InInitialEntityName; } let symbolName = getNameOfSymbolAsWritten(symbol, context); if (index === 0) { - context.flags ^= NodeBuilderFlags.InInitialEntityName; + context.flags ^= ts.NodeBuilderFlags.InInitialEntityName; } let firstChar = symbolName.charCodeAt(0); - if (isSingleOrDoubleQuote(firstChar) && some(symbol.declarations, hasNonGlobalAugmentationExternalModuleSymbol)) { - return factory.createStringLiteral(getSpecifierForModuleSymbol(symbol, context)); + if (ts.isSingleOrDoubleQuote(firstChar) && ts.some(symbol.declarations, hasNonGlobalAugmentationExternalModuleSymbol)) { + return ts.factory.createStringLiteral(getSpecifierForModuleSymbol(symbol, context)); } - const canUsePropertyAccess = firstChar === CharacterCodes.hash ? - symbolName.length > 1 && isIdentifierStart(symbolName.charCodeAt(1), languageVersion) : - isIdentifierStart(firstChar, languageVersion); + const canUsePropertyAccess = firstChar === ts.CharacterCodes.hash ? + symbolName.length > 1 && ts.isIdentifierStart(symbolName.charCodeAt(1), languageVersion) : + ts.isIdentifierStart(firstChar, languageVersion); if (index === 0 || canUsePropertyAccess) { - const identifier = setEmitFlags(factory.createIdentifier(symbolName, typeParameterNodes), EmitFlags.NoAsciiEscaping); + const identifier = ts.setEmitFlags(ts.factory.createIdentifier(symbolName, typeParameterNodes), ts.EmitFlags.NoAsciiEscaping); identifier.symbol = symbol; - return index > 0 ? factory.createPropertyAccessExpression(createExpressionFromSymbolChain(chain, index - 1), identifier) : identifier; + return index > 0 ? ts.factory.createPropertyAccessExpression(createExpressionFromSymbolChain(chain, index - 1), identifier) : identifier; } else { - if (firstChar === CharacterCodes.openBracket) { + if (firstChar === ts.CharacterCodes.openBracket) { symbolName = symbolName.substring(1, symbolName.length - 1); firstChar = symbolName.charCodeAt(0); } - let expression: Expression | undefined; - if (isSingleOrDoubleQuote(firstChar) && !(symbol.flags & SymbolFlags.EnumMember)) { - expression = factory.createStringLiteral(stripQuotes(symbolName).replace(/\\./g, s => s.substring(1)), firstChar === CharacterCodes.singleQuote); + let expression: ts.Expression | undefined; + if (ts.isSingleOrDoubleQuote(firstChar) && !(symbol.flags & ts.SymbolFlags.EnumMember)) { + expression = ts.factory.createStringLiteral(ts.stripQuotes(symbolName).replace(/\\./g, s => s.substring(1)), firstChar === ts.CharacterCodes.singleQuote); } else if (("" + +symbolName) === symbolName) { - expression = factory.createNumericLiteral(+symbolName); + expression = ts.factory.createNumericLiteral(+symbolName); } if (!expression) { - expression = setEmitFlags(factory.createIdentifier(symbolName, typeParameterNodes), EmitFlags.NoAsciiEscaping); + expression = ts.setEmitFlags(ts.factory.createIdentifier(symbolName, typeParameterNodes), ts.EmitFlags.NoAsciiEscaping); expression.symbol = symbol; } - return factory.createElementAccessExpression(createExpressionFromSymbolChain(chain, index - 1), expression); + return ts.factory.createElementAccessExpression(createExpressionFromSymbolChain(chain, index - 1), expression); } } } - function isStringNamed(d: Declaration) { - const name = getNameOfDeclaration(d); - return !!name && isStringLiteral(name); + function isStringNamed(d: ts.Declaration) { + const name = ts.getNameOfDeclaration(d); + return !!name && ts.isStringLiteral(name); } - function isSingleQuotedStringNamed(d: Declaration) { - const name = getNameOfDeclaration(d); - return !!(name && isStringLiteral(name) && (name.singleQuote || !nodeIsSynthesized(name) && startsWith(getTextOfNode(name, /*includeTrivia*/ false), "'"))); + function isSingleQuotedStringNamed(d: ts.Declaration) { + const name = ts.getNameOfDeclaration(d); + return !!(name && ts.isStringLiteral(name) && (name.singleQuote || !ts.nodeIsSynthesized(name) && ts.startsWith(ts.getTextOfNode(name, /*includeTrivia*/ false), "'"))); } - function getPropertyNameNodeForSymbol(symbol: Symbol, context: NodeBuilderContext) { - const singleQuote = !!length(symbol.declarations) && every(symbol.declarations, isSingleQuotedStringNamed); + function getPropertyNameNodeForSymbol(symbol: ts.Symbol, context: NodeBuilderContext) { + const singleQuote = !!ts.length(symbol.declarations) && ts.every(symbol.declarations, isSingleQuotedStringNamed); const fromNameType = getPropertyNameNodeForSymbolFromNameType(symbol, context, singleQuote); if (fromNameType) { return fromNameType; } - const rawName = unescapeLeadingUnderscores(symbol.escapedName); - const stringNamed = !!length(symbol.declarations) && every(symbol.declarations, isStringNamed); - return createPropertyNameNodeForIdentifierOrLiteral(rawName, getEmitScriptTarget(compilerOptions), singleQuote, stringNamed); + const rawName = ts.unescapeLeadingUnderscores(symbol.escapedName); + const stringNamed = !!ts.length(symbol.declarations) && ts.every(symbol.declarations, isStringNamed); + return ts.createPropertyNameNodeForIdentifierOrLiteral(rawName, ts.getEmitScriptTarget(compilerOptions), singleQuote, stringNamed); } // See getNameForSymbolFromNameType for a stringy equivalent - function getPropertyNameNodeForSymbolFromNameType(symbol: Symbol, context: NodeBuilderContext, singleQuote?: boolean) { + function getPropertyNameNodeForSymbolFromNameType(symbol: ts.Symbol, context: NodeBuilderContext, singleQuote?: boolean) { const nameType = getSymbolLinks(symbol).nameType; if (nameType) { - if (nameType.flags & TypeFlags.StringOrNumberLiteral) { - const name = "" + (nameType as StringLiteralType | NumberLiteralType).value; - if (!isIdentifierText(name, getEmitScriptTarget(compilerOptions)) && !isNumericLiteralName(name)) { - return factory.createStringLiteral(name, !!singleQuote); + if (nameType.flags & ts.TypeFlags.StringOrNumberLiteral) { + const name = "" + (nameType as ts.StringLiteralType | ts.NumberLiteralType).value; + if (!ts.isIdentifierText(name, ts.getEmitScriptTarget(compilerOptions)) && !ts.isNumericLiteralName(name)) { + return ts.factory.createStringLiteral(name, !!singleQuote); } - if (isNumericLiteralName(name) && startsWith(name, "-")) { - return factory.createComputedPropertyName(factory.createNumericLiteral(+name)); + if (ts.isNumericLiteralName(name) && ts.startsWith(name, "-")) { + return ts.factory.createComputedPropertyName(ts.factory.createNumericLiteral(+name)); } - return createPropertyNameNodeForIdentifierOrLiteral(name, getEmitScriptTarget(compilerOptions)); + return ts.createPropertyNameNodeForIdentifierOrLiteral(name, ts.getEmitScriptTarget(compilerOptions)); } - if (nameType.flags & TypeFlags.UniqueESSymbol) { - return factory.createComputedPropertyName(symbolToExpression((nameType as UniqueESSymbolType).symbol, context, SymbolFlags.Value)); + if (nameType.flags & ts.TypeFlags.UniqueESSymbol) { + return ts.factory.createComputedPropertyName(symbolToExpression((nameType as ts.UniqueESSymbolType).symbol, context, ts.SymbolFlags.Value)); } } } @@ -6510,37 +6318,37 @@ namespace ts { // export const x: (x: T) => T // export const y: (x: T_1) => T_1 if (initial.typeParameterNames) { - initial.typeParameterNames = new Map(initial.typeParameterNames); + initial.typeParameterNames = new ts.Map(initial.typeParameterNames); } if (initial.typeParameterNamesByText) { - initial.typeParameterNamesByText = new Set(initial.typeParameterNamesByText); + initial.typeParameterNamesByText = new ts.Set(initial.typeParameterNamesByText); } if (initial.typeParameterSymbolList) { - initial.typeParameterSymbolList = new Set(initial.typeParameterSymbolList); + initial.typeParameterSymbolList = new ts.Set(initial.typeParameterSymbolList); } initial.tracker = wrapSymbolTrackerToReportForContext(initial, initial.tracker); return initial; } - function getDeclarationWithTypeAnnotation(symbol: Symbol, enclosingDeclaration: Node | undefined) { - return symbol.declarations && find(symbol.declarations, s => !!getEffectiveTypeAnnotationNode(s) && (!enclosingDeclaration || !!findAncestor(s, n => n === enclosingDeclaration))); + function getDeclarationWithTypeAnnotation(symbol: ts.Symbol, enclosingDeclaration: ts.Node | undefined) { + return symbol.declarations && ts.find(symbol.declarations, s => !!ts.getEffectiveTypeAnnotationNode(s) && (!enclosingDeclaration || !!ts.findAncestor(s, n => n === enclosingDeclaration))); } - function existingTypeNodeIsNotReferenceOrIsReferenceWithCompatibleTypeArgumentCount(existing: TypeNode, type: Type) { - return !(getObjectFlags(type) & ObjectFlags.Reference) || !isTypeReferenceNode(existing) || length(existing.typeArguments) >= getMinTypeArgumentCount((type as TypeReference).target.typeParameters); + function existingTypeNodeIsNotReferenceOrIsReferenceWithCompatibleTypeArgumentCount(existing: ts.TypeNode, type: ts.Type) { + return !(ts.getObjectFlags(type) & ts.ObjectFlags.Reference) || !ts.isTypeReferenceNode(existing) || ts.length(existing.typeArguments) >= getMinTypeArgumentCount((type as ts.TypeReference).target.typeParameters); } /** * Unlike `typeToTypeNodeHelper`, this handles setting up the `AllowUniqueESSymbolType` flag * so a `unique symbol` is returned when appropriate for the input symbol, rather than `typeof sym` */ - function serializeTypeForDeclaration(context: NodeBuilderContext, type: Type, symbol: Symbol, enclosingDeclaration: Node | undefined, includePrivateSymbol?: (s: Symbol) => void, bundled?: boolean) { + function serializeTypeForDeclaration(context: NodeBuilderContext, type: ts.Type, symbol: ts.Symbol, enclosingDeclaration: ts.Node | undefined, includePrivateSymbol?: (s: ts.Symbol) => void, bundled?: boolean) { if (!isErrorType(type) && enclosingDeclaration) { const declWithExistingAnnotation = getDeclarationWithTypeAnnotation(symbol, enclosingDeclaration); - if (declWithExistingAnnotation && !isFunctionLikeDeclaration(declWithExistingAnnotation) && !isGetAccessorDeclaration(declWithExistingAnnotation)) { + if (declWithExistingAnnotation && !ts.isFunctionLikeDeclaration(declWithExistingAnnotation) && !ts.isGetAccessorDeclaration(declWithExistingAnnotation)) { // try to reuse the existing annotation - const existing = getEffectiveTypeAnnotationNode(declWithExistingAnnotation)!; + const existing = ts.getEffectiveTypeAnnotationNode(declWithExistingAnnotation)!; if (typeNodeIsEquivalentToType(existing, declWithExistingAnnotation, type) && existingTypeNodeIsNotReferenceOrIsReferenceWithCompatibleTypeArgumentCount(existing, type)) { const result = serializeExistingTypeNode(context, existing, includePrivateSymbol, bundled); if (result) { @@ -6550,32 +6358,32 @@ namespace ts { } } const oldFlags = context.flags; - if (type.flags & TypeFlags.UniqueESSymbol && - type.symbol === symbol && (!context.enclosingDeclaration || some(symbol.declarations, d => getSourceFileOfNode(d) === getSourceFileOfNode(context.enclosingDeclaration!)))) { - context.flags |= NodeBuilderFlags.AllowUniqueESSymbolType; + if (type.flags & ts.TypeFlags.UniqueESSymbol && + type.symbol === symbol && (!context.enclosingDeclaration || ts.some(symbol.declarations, d => ts.getSourceFileOfNode(d) === ts.getSourceFileOfNode(context.enclosingDeclaration!)))) { + context.flags |= ts.NodeBuilderFlags.AllowUniqueESSymbolType; } const result = typeToTypeNodeHelper(type, context); context.flags = oldFlags; return result; } - function typeNodeIsEquivalentToType(typeNode: TypeNode, annotatedDeclaration: Declaration, type: Type) { + function typeNodeIsEquivalentToType(typeNode: ts.TypeNode, annotatedDeclaration: ts.Declaration, type: ts.Type) { const typeFromTypeNode = getTypeFromTypeNode(typeNode); if (typeFromTypeNode === type) { return true; } - if (isParameter(annotatedDeclaration) && annotatedDeclaration.questionToken) { + if (ts.isParameter(annotatedDeclaration) && annotatedDeclaration.questionToken) { return getTypeWithFacts(type, TypeFacts.NEUndefined) === typeFromTypeNode; } return false; } - function serializeReturnTypeForSignature(context: NodeBuilderContext, type: Type, signature: Signature, includePrivateSymbol?: (s: Symbol) => void, bundled?: boolean) { + function serializeReturnTypeForSignature(context: NodeBuilderContext, type: ts.Type, signature: ts.Signature, includePrivateSymbol?: (s: ts.Symbol) => void, bundled?: boolean) { if (!isErrorType(type) && context.enclosingDeclaration) { - const annotation = signature.declaration && getEffectiveReturnTypeNode(signature.declaration); - if (!!findAncestor(annotation, n => n === context.enclosingDeclaration) && annotation) { + const annotation = signature.declaration && ts.getEffectiveReturnTypeNode(signature.declaration); + if (!!ts.findAncestor(annotation, n => n === context.enclosingDeclaration) && annotation) { const annotated = getTypeFromTypeNode(annotation); - const thisInstantiated = annotated.flags & TypeFlags.TypeParameter && (annotated as TypeParameter).isThisType ? instantiateType(annotated, signature.mapper) : annotated; + const thisInstantiated = annotated.flags & ts.TypeFlags.TypeParameter && (annotated as ts.TypeParameter).isThisType ? instantiateType(annotated, signature.mapper) : annotated; if (thisInstantiated === type && existingTypeNodeIsNotReferenceOrIsReferenceWithCompatibleTypeArgumentCount(annotation, type)) { const result = serializeExistingTypeNode(context, annotation, includePrivateSymbol, bundled); if (result) { @@ -6587,157 +6395,119 @@ namespace ts { return typeToTypeNodeHelper(type, context); } - function trackExistingEntityName(node: T, context: NodeBuilderContext, includePrivateSymbol?: (s: Symbol) => void) { + function trackExistingEntityName(node: T, context: NodeBuilderContext, includePrivateSymbol?: (s: ts.Symbol) => void) { let introducesError = false; - const leftmost = getFirstIdentifier(node); - if (isInJSFile(node) && (isExportsIdentifier(leftmost) || isModuleExportsAccessExpression(leftmost.parent) || (isQualifiedName(leftmost.parent) && isModuleIdentifier(leftmost.parent.left) && isExportsIdentifier(leftmost.parent.right)))) { + const leftmost = ts.getFirstIdentifier(node); + if (ts.isInJSFile(node) && (ts.isExportsIdentifier(leftmost) || ts.isModuleExportsAccessExpression(leftmost.parent) || (ts.isQualifiedName(leftmost.parent) && ts.isModuleIdentifier(leftmost.parent.left) && ts.isExportsIdentifier(leftmost.parent.right)))) { introducesError = true; return { introducesError, node }; } - const sym = resolveEntityName(leftmost, SymbolFlags.All, /*ignoreErrors*/ true, /*dontResolveALias*/ true); + const sym = resolveEntityName(leftmost, ts.SymbolFlags.All, /*ignoreErrors*/ true, /*dontResolveALias*/ true); if (sym) { - if (isSymbolAccessible(sym, context.enclosingDeclaration, SymbolFlags.All, /*shouldComputeAliasesToMakeVisible*/ false).accessibility !== SymbolAccessibility.Accessible) { + if (isSymbolAccessible(sym, context.enclosingDeclaration, ts.SymbolFlags.All, /*shouldComputeAliasesToMakeVisible*/ false).accessibility !== ts.SymbolAccessibility.Accessible) { introducesError = true; } else { - context.tracker?.trackSymbol?.(sym, context.enclosingDeclaration, SymbolFlags.All); + context.tracker?.trackSymbol?.(sym, context.enclosingDeclaration, ts.SymbolFlags.All); includePrivateSymbol?.(sym); } - if (isIdentifier(node)) { + if (ts.isIdentifier(node)) { const type = getDeclaredTypeOfSymbol(sym); - const name = sym.flags & SymbolFlags.TypeParameter && !isTypeSymbolAccessible(type.symbol, context.enclosingDeclaration) ? typeParameterToName(type, context) : factory.cloneNode(node); + const name = sym.flags & ts.SymbolFlags.TypeParameter && !isTypeSymbolAccessible(type.symbol, context.enclosingDeclaration) ? typeParameterToName(type, context) : ts.factory.cloneNode(node); name.symbol = sym; // for quickinfo, which uses identifier symbol information - return { introducesError, node: setEmitFlags(setOriginalNode(name, node), EmitFlags.NoAsciiEscaping) }; + return { introducesError, node: ts.setEmitFlags(ts.setOriginalNode(name, node), ts.EmitFlags.NoAsciiEscaping) }; } } return { introducesError, node }; } - function serializeExistingTypeNode(context: NodeBuilderContext, existing: TypeNode, includePrivateSymbol?: (s: Symbol) => void, bundled?: boolean) { + function serializeExistingTypeNode(context: NodeBuilderContext, existing: ts.TypeNode, includePrivateSymbol?: (s: ts.Symbol) => void, bundled?: boolean) { if (cancellationToken && cancellationToken.throwIfCancellationRequested) { cancellationToken.throwIfCancellationRequested(); } let hadError = false; - const file = getSourceFileOfNode(existing); - const transformed = visitNode(existing, visitExistingNodeTreeSymbols); + const file = ts.getSourceFileOfNode(existing); + const transformed = ts.visitNode(existing, visitExistingNodeTreeSymbols); if (hadError) { return undefined; } - return transformed === existing ? setTextRange(factory.cloneNode(existing), existing) : transformed; - - function visitExistingNodeTreeSymbols(node: T): Node { + return transformed === existing ? ts.setTextRange(ts.factory.cloneNode(existing), existing) : transformed; + function visitExistingNodeTreeSymbols(node: T): ts.Node { // We don't _actually_ support jsdoc namepath types, emit `any` instead - if (isJSDocAllType(node) || node.kind === SyntaxKind.JSDocNamepathType) { - return factory.createKeywordTypeNode(SyntaxKind.AnyKeyword); + if (ts.isJSDocAllType(node) || node.kind === ts.SyntaxKind.JSDocNamepathType) { + return ts.factory.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword); } - if (isJSDocUnknownType(node)) { - return factory.createKeywordTypeNode(SyntaxKind.UnknownKeyword); + if (ts.isJSDocUnknownType(node)) { + return ts.factory.createKeywordTypeNode(ts.SyntaxKind.UnknownKeyword); } - if (isJSDocNullableType(node)) { - return factory.createUnionTypeNode([visitNode(node.type, visitExistingNodeTreeSymbols), factory.createLiteralTypeNode(factory.createNull())]); + if (ts.isJSDocNullableType(node)) { + return ts.factory.createUnionTypeNode([ts.visitNode(node.type, visitExistingNodeTreeSymbols), ts.factory.createLiteralTypeNode(ts.factory.createNull())]); } - if (isJSDocOptionalType(node)) { - return factory.createUnionTypeNode([visitNode(node.type, visitExistingNodeTreeSymbols), factory.createKeywordTypeNode(SyntaxKind.UndefinedKeyword)]); + if (ts.isJSDocOptionalType(node)) { + return ts.factory.createUnionTypeNode([ts.visitNode(node.type, visitExistingNodeTreeSymbols), ts.factory.createKeywordTypeNode(ts.SyntaxKind.UndefinedKeyword)]); } - if (isJSDocNonNullableType(node)) { - return visitNode(node.type, visitExistingNodeTreeSymbols); + if (ts.isJSDocNonNullableType(node)) { + return ts.visitNode(node.type, visitExistingNodeTreeSymbols); } - if (isJSDocVariadicType(node)) { - return factory.createArrayTypeNode(visitNode((node as JSDocVariadicType).type, visitExistingNodeTreeSymbols)); + if (ts.isJSDocVariadicType(node)) { + return ts.factory.createArrayTypeNode(ts.visitNode((node as ts.JSDocVariadicType).type, visitExistingNodeTreeSymbols)); } - if (isJSDocTypeLiteral(node)) { - return factory.createTypeLiteralNode(map(node.jsDocPropertyTags, t => { - const name = isIdentifier(t.name) ? t.name : t.name.right; + if (ts.isJSDocTypeLiteral(node)) { + return ts.factory.createTypeLiteralNode(ts.map(node.jsDocPropertyTags, t => { + const name = ts.isIdentifier(t.name) ? t.name : t.name.right; const typeViaParent = getTypeOfPropertyOfType(getTypeFromTypeNode(node), name.escapedText); const overrideTypeNode = typeViaParent && t.typeExpression && getTypeFromTypeNode(t.typeExpression.type) !== typeViaParent ? typeToTypeNodeHelper(typeViaParent, context) : undefined; - return factory.createPropertySignature( - /*modifiers*/ undefined, - name, - t.isBracketed || t.typeExpression && isJSDocOptionalType(t.typeExpression.type) ? factory.createToken(SyntaxKind.QuestionToken) : undefined, - overrideTypeNode || (t.typeExpression && visitNode(t.typeExpression.type, visitExistingNodeTreeSymbols)) || factory.createKeywordTypeNode(SyntaxKind.AnyKeyword) - ); + return ts.factory.createPropertySignature( + /*modifiers*/ undefined, name, t.isBracketed || t.typeExpression && ts.isJSDocOptionalType(t.typeExpression.type) ? ts.factory.createToken(ts.SyntaxKind.QuestionToken) : undefined, overrideTypeNode || (t.typeExpression && ts.visitNode(t.typeExpression.type, visitExistingNodeTreeSymbols)) || ts.factory.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword)); })); } - if (isTypeReferenceNode(node) && isIdentifier(node.typeName) && node.typeName.escapedText === "") { - return setOriginalNode(factory.createKeywordTypeNode(SyntaxKind.AnyKeyword), node); + if (ts.isTypeReferenceNode(node) && ts.isIdentifier(node.typeName) && node.typeName.escapedText === "") { + return ts.setOriginalNode(ts.factory.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword), node); } - if ((isExpressionWithTypeArguments(node) || isTypeReferenceNode(node)) && isJSDocIndexSignature(node)) { - return factory.createTypeLiteralNode([factory.createIndexSignature( + if ((ts.isExpressionWithTypeArguments(node) || ts.isTypeReferenceNode(node)) && ts.isJSDocIndexSignature(node)) { + return ts.factory.createTypeLiteralNode([ts.factory.createIndexSignature( /*decorators*/ undefined, - /*modifiers*/ undefined, - [factory.createParameterDeclaration( + /*modifiers*/ undefined, [ts.factory.createParameterDeclaration( /*decorators*/ undefined, /*modifiers*/ undefined, - /*dotdotdotToken*/ undefined, - "x", - /*questionToken*/ undefined, - visitNode(node.typeArguments![0], visitExistingNodeTreeSymbols) - )], - visitNode(node.typeArguments![1], visitExistingNodeTreeSymbols) - )]); - } - if (isJSDocFunctionType(node)) { - if (isJSDocConstructSignature(node)) { - let newTypeNode: TypeNode | undefined; - return factory.createConstructorTypeNode( - node.modifiers, - visitNodes(node.typeParameters, visitExistingNodeTreeSymbols), - mapDefined(node.parameters, (p, i) => p.name && isIdentifier(p.name) && p.name.escapedText === "new" ? (newTypeNode = p.type, undefined) : factory.createParameterDeclaration( + /*dotdotdotToken*/ undefined, "x", + /*questionToken*/ undefined, ts.visitNode(node.typeArguments![0], visitExistingNodeTreeSymbols))], ts.visitNode(node.typeArguments![1], visitExistingNodeTreeSymbols))]); + } + if (ts.isJSDocFunctionType(node)) { + if (ts.isJSDocConstructSignature(node)) { + let newTypeNode: ts.TypeNode | undefined; + return ts.factory.createConstructorTypeNode(node.modifiers, ts.visitNodes(node.typeParameters, visitExistingNodeTreeSymbols), ts.mapDefined(node.parameters, (p, i) => p.name && ts.isIdentifier(p.name) && p.name.escapedText === "new" ? (newTypeNode = p.type, undefined) : ts.factory.createParameterDeclaration( /*decorators*/ undefined, - /*modifiers*/ undefined, - getEffectiveDotDotDotForParameter(p), - getNameForJSDocFunctionParameter(p, i), - p.questionToken, - visitNode(p.type, visitExistingNodeTreeSymbols), - /*initializer*/ undefined - )), - visitNode(newTypeNode || node.type, visitExistingNodeTreeSymbols) || factory.createKeywordTypeNode(SyntaxKind.AnyKeyword) - ); + /*modifiers*/ undefined, getEffectiveDotDotDotForParameter(p), getNameForJSDocFunctionParameter(p, i), p.questionToken, ts.visitNode(p.type, visitExistingNodeTreeSymbols), + /*initializer*/ undefined)), ts.visitNode(newTypeNode || node.type, visitExistingNodeTreeSymbols) || ts.factory.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword)); } else { - return factory.createFunctionTypeNode( - visitNodes(node.typeParameters, visitExistingNodeTreeSymbols), - map(node.parameters, (p, i) => factory.createParameterDeclaration( + return ts.factory.createFunctionTypeNode(ts.visitNodes(node.typeParameters, visitExistingNodeTreeSymbols), ts.map(node.parameters, (p, i) => ts.factory.createParameterDeclaration( /*decorators*/ undefined, - /*modifiers*/ undefined, - getEffectiveDotDotDotForParameter(p), - getNameForJSDocFunctionParameter(p, i), - p.questionToken, - visitNode(p.type, visitExistingNodeTreeSymbols), - /*initializer*/ undefined - )), - visitNode(node.type, visitExistingNodeTreeSymbols) || factory.createKeywordTypeNode(SyntaxKind.AnyKeyword) - ); + /*modifiers*/ undefined, getEffectiveDotDotDotForParameter(p), getNameForJSDocFunctionParameter(p, i), p.questionToken, ts.visitNode(p.type, visitExistingNodeTreeSymbols), + /*initializer*/ undefined)), ts.visitNode(node.type, visitExistingNodeTreeSymbols) || ts.factory.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword)); } } - if (isTypeReferenceNode(node) && isInJSDoc(node) && (!existingTypeNodeIsNotReferenceOrIsReferenceWithCompatibleTypeArgumentCount(node, getTypeFromTypeNode(node)) || getIntendedTypeFromJSDocTypeReference(node) || unknownSymbol === resolveTypeReferenceName(node, SymbolFlags.Type, /*ignoreErrors*/ true))) { - return setOriginalNode(typeToTypeNodeHelper(getTypeFromTypeNode(node), context), node); + if (ts.isTypeReferenceNode(node) && ts.isInJSDoc(node) && (!existingTypeNodeIsNotReferenceOrIsReferenceWithCompatibleTypeArgumentCount(node, getTypeFromTypeNode(node)) || getIntendedTypeFromJSDocTypeReference(node) || unknownSymbol === resolveTypeReferenceName(node, ts.SymbolFlags.Type, /*ignoreErrors*/ true))) { + return ts.setOriginalNode(typeToTypeNodeHelper(getTypeFromTypeNode(node), context), node); } - if (isLiteralImportTypeNode(node)) { + if (ts.isLiteralImportTypeNode(node)) { const nodeSymbol = getNodeLinks(node).resolvedSymbol; - if (isInJSDoc(node) && + if (ts.isInJSDoc(node) && nodeSymbol && ( // The import type resolved using jsdoc fallback logic - (!node.isTypeOf && !(nodeSymbol.flags & SymbolFlags.Type)) || + (!node.isTypeOf && !(nodeSymbol.flags & ts.SymbolFlags.Type)) || // The import type had type arguments autofilled by js fallback logic - !(length(node.typeArguments) >= getMinTypeArgumentCount(getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(nodeSymbol))) - ) - ) { - return setOriginalNode(typeToTypeNodeHelper(getTypeFromTypeNode(node), context), node); + !(ts.length(node.typeArguments) >= getMinTypeArgumentCount(getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(nodeSymbol))))) { + return ts.setOriginalNode(typeToTypeNodeHelper(getTypeFromTypeNode(node), context), node); } - return factory.updateImportTypeNode( - node, - factory.updateLiteralTypeNode(node.argument, rewriteModuleSpecifier(node, node.argument.literal)), - node.qualifier, - visitNodes(node.typeArguments, visitExistingNodeTreeSymbols, isTypeNode), - node.isTypeOf - ); + return ts.factory.updateImportTypeNode(node, ts.factory.updateLiteralTypeNode(node.argument, rewriteModuleSpecifier(node, node.argument.literal)), node.qualifier, ts.visitNodes(node.typeArguments, visitExistingNodeTreeSymbols, ts.isTypeNode), node.isTypeOf); } - if (isEntityName(node) || isEntityNameExpression(node)) { + if (ts.isEntityName(node) || ts.isEntityNameExpression(node)) { const { introducesError, node: result } = trackExistingEntityName(node, context, includePrivateSymbol); hadError = hadError || introducesError; if (result !== node) { @@ -6745,36 +6515,35 @@ namespace ts { } } - if (file && isTupleTypeNode(node) && (getLineAndCharacterOfPosition(file, node.pos).line === getLineAndCharacterOfPosition(file, node.end).line)) { - setEmitFlags(node, EmitFlags.SingleLine); + if (file && ts.isTupleTypeNode(node) && (ts.getLineAndCharacterOfPosition(file, node.pos).line === ts.getLineAndCharacterOfPosition(file, node.end).line)) { + ts.setEmitFlags(node, ts.EmitFlags.SingleLine); } - return visitEachChild(node, visitExistingNodeTreeSymbols, nullTransformationContext); - - function getEffectiveDotDotDotForParameter(p: ParameterDeclaration) { - return p.dotDotDotToken || (p.type && isJSDocVariadicType(p.type) ? factory.createToken(SyntaxKind.DotDotDotToken) : undefined); + return ts.visitEachChild(node, visitExistingNodeTreeSymbols, ts.nullTransformationContext); + function getEffectiveDotDotDotForParameter(p: ts.ParameterDeclaration) { + return p.dotDotDotToken || (p.type && ts.isJSDocVariadicType(p.type) ? ts.factory.createToken(ts.SyntaxKind.DotDotDotToken) : undefined); } /** Note that `new:T` parameters are not handled, but should be before calling this function. */ - function getNameForJSDocFunctionParameter(p: ParameterDeclaration, index: number) { - return p.name && isIdentifier(p.name) && p.name.escapedText === "this" ? "this" + function getNameForJSDocFunctionParameter(p: ts.ParameterDeclaration, index: number) { + return p.name && ts.isIdentifier(p.name) && p.name.escapedText === "this" ? "this" : getEffectiveDotDotDotForParameter(p) ? `args` : `arg${index}`; } - function rewriteModuleSpecifier(parent: ImportTypeNode, lit: StringLiteral) { + function rewriteModuleSpecifier(parent: ts.ImportTypeNode, lit: ts.StringLiteral) { if (bundled) { if (context.tracker && context.tracker.moduleResolverHost) { const targetFile = getExternalModuleFileFromDeclaration(parent); if (targetFile) { - const getCanonicalFileName = createGetCanonicalFileName(!!host.useCaseSensitiveFileNames); + const getCanonicalFileName = ts.createGetCanonicalFileName(!!host.useCaseSensitiveFileNames); const resolverHost = { getCanonicalFileName, getCurrentDirectory: () => context.tracker.moduleResolverHost!.getCurrentDirectory(), getCommonSourceDirectory: () => context.tracker.moduleResolverHost!.getCommonSourceDirectory() }; - const newName = getResolvedExternalModuleName(resolverHost, targetFile); - return factory.createStringLiteral(newName); + const newName = ts.getResolvedExternalModuleName(resolverHost, targetFile); + return ts.factory.createStringLiteral(newName); } } } @@ -6791,9 +6560,9 @@ namespace ts { } } - function symbolTableToDeclarationStatements(symbolTable: SymbolTable, context: NodeBuilderContext, bundled?: boolean): Statement[] { - const serializePropertySymbolForClass = makeSerializePropertySymbol(factory.createPropertyDeclaration, SyntaxKind.MethodDeclaration, /*useAcessors*/ true); - const serializePropertySymbolForInterfaceWorker = makeSerializePropertySymbol((_decorators, mods, name, question, type) => factory.createPropertySignature(mods, name, question, type), SyntaxKind.MethodSignature, /*useAcessors*/ false); + function symbolTableToDeclarationStatements(symbolTable: ts.SymbolTable, context: NodeBuilderContext, bundled?: boolean): ts.Statement[] { + const serializePropertySymbolForClass = makeSerializePropertySymbol(ts.factory.createPropertyDeclaration, ts.SyntaxKind.MethodDeclaration, /*useAcessors*/ true); + const serializePropertySymbolForInterfaceWorker = makeSerializePropertySymbol((_decorators, mods, name, question, type) => ts.factory.createPropertySignature(mods, name, question, type), ts.SyntaxKind.MethodSignature, /*useAcessors*/ false); // TODO: Use `setOriginalNode` on original declaration names where possible so these declarations see some kind of // declaration mapping @@ -6802,22 +6571,22 @@ namespace ts { // emit codepaths which want to apply more specific contexts (so we can still refer to the root real declaration // we're trying to emit from later on) const enclosingDeclaration = context.enclosingDeclaration!; - let results: Statement[] = []; - const visitedSymbols = new Set(); - const deferredPrivatesStack: ESMap[] = []; + let results: ts.Statement[] = []; + const visitedSymbols = new ts.Set(); + const deferredPrivatesStack: ts.ESMap[] = []; const oldcontext = context; context = { ...oldcontext, - usedSymbolNames: new Set(oldcontext.usedSymbolNames), - remappedSymbolNames: new Map(), + usedSymbolNames: new ts.Set(oldcontext.usedSymbolNames), + remappedSymbolNames: new ts.Map(), tracker: { ...oldcontext.tracker, trackSymbol: (sym, decl, meaning) => { const accessibleResult = isSymbolAccessible(sym, decl, meaning, /*computeAliases*/ false); - if (accessibleResult.accessibility === SymbolAccessibility.Accessible) { + if (accessibleResult.accessibility === ts.SymbolAccessibility.Accessible) { // Lookup the root symbol of the chain of refs we'll use to access it and serialize it const chain = lookupSymbolChainWorker(sym, context, meaning); - if (!(sym.flags & SymbolFlags.Property)) { + if (!(sym.flags & ts.SymbolFlags.Property)) { includePrivateSymbol(chain[0]); } } @@ -6829,109 +6598,93 @@ namespace ts { }, }; context.tracker = wrapSymbolTrackerToReportForContext(context, context.tracker); - forEachEntry(symbolTable, (symbol, name) => { - const baseName = unescapeLeadingUnderscores(name); + ts.forEachEntry(symbolTable, (symbol, name) => { + const baseName = ts.unescapeLeadingUnderscores(name); void getInternalSymbolName(symbol, baseName); // Called to cache values into `usedSymbolNames` and `remappedSymbolNames` }); let addingDeclare = !bundled; - const exportEquals = symbolTable.get(InternalSymbolName.ExportEquals); - if (exportEquals && symbolTable.size > 1 && exportEquals.flags & SymbolFlags.Alias) { - symbolTable = createSymbolTable(); + const exportEquals = symbolTable.get(ts.InternalSymbolName.ExportEquals); + if (exportEquals && symbolTable.size > 1 && exportEquals.flags & ts.SymbolFlags.Alias) { + symbolTable = ts.createSymbolTable(); // Remove extraneous elements from root symbol table (they'll be mixed back in when the target of the `export=` is looked up) - symbolTable.set(InternalSymbolName.ExportEquals, exportEquals); + symbolTable.set(ts.InternalSymbolName.ExportEquals, exportEquals); } visitSymbolTable(symbolTable); return mergeRedundantStatements(results); - function isIdentifierAndNotUndefined(node: Node | undefined): node is Identifier { - return !!node && node.kind === SyntaxKind.Identifier; + function isIdentifierAndNotUndefined(node: ts.Node | undefined): node is ts.Identifier { + return !!node && node.kind === ts.SyntaxKind.Identifier; } - function getNamesOfDeclaration(statement: Statement): Identifier[] { - if (isVariableStatement(statement)) { - return filter(map(statement.declarationList.declarations, getNameOfDeclaration), isIdentifierAndNotUndefined); + function getNamesOfDeclaration(statement: ts.Statement): ts.Identifier[] { + if (ts.isVariableStatement(statement)) { + return ts.filter(ts.map(statement.declarationList.declarations, ts.getNameOfDeclaration), isIdentifierAndNotUndefined); } - return filter([getNameOfDeclaration(statement as DeclarationStatement)], isIdentifierAndNotUndefined); + return ts.filter([ts.getNameOfDeclaration(statement as ts.DeclarationStatement)], isIdentifierAndNotUndefined); } - function flattenExportAssignedNamespace(statements: Statement[]) { - const exportAssignment = find(statements, isExportAssignment); - const nsIndex = findIndex(statements, isModuleDeclaration); - let ns = nsIndex !== -1 ? statements[nsIndex] as ModuleDeclaration : undefined; + function flattenExportAssignedNamespace(statements: ts.Statement[]) { + const exportAssignment = ts.find(statements, ts.isExportAssignment); + const nsIndex = ts.findIndex(statements, ts.isModuleDeclaration); + let ns = nsIndex !== -1 ? statements[nsIndex] as ts.ModuleDeclaration : undefined; if (ns && exportAssignment && exportAssignment.isExportEquals && - isIdentifier(exportAssignment.expression) && isIdentifier(ns.name) && idText(ns.name) === idText(exportAssignment.expression) && - ns.body && isModuleBlock(ns.body)) { + ts.isIdentifier(exportAssignment.expression) && ts.isIdentifier(ns.name) && ts.idText(ns.name) === ts.idText(exportAssignment.expression) && + ns.body && ts.isModuleBlock(ns.body)) { // Pass 0: Correct situations where a module has both an `export = ns` and multiple top-level exports by stripping the export modifiers from // the top-level exports and exporting them in the targeted ns, as can occur when a js file has both typedefs and `module.export` assignments - const excessExports = filter(statements, s => !!(getEffectiveModifierFlags(s) & ModifierFlags.Export)); + const excessExports = ts.filter(statements, s => !!(ts.getEffectiveModifierFlags(s) & ts.ModifierFlags.Export)); const name = ns.name; let body = ns.body; - if (length(excessExports)) { - ns = factory.updateModuleDeclaration( - ns, - ns.decorators, - ns.modifiers, - ns.name, - body = factory.updateModuleBlock( - body, - factory.createNodeArray([...ns.body.statements, factory.createExportDeclaration( + if (ts.length(excessExports)) { + ns = ts.factory.updateModuleDeclaration(ns, ns.decorators, ns.modifiers, ns.name, body = ts.factory.updateModuleBlock(body, ts.factory.createNodeArray([...ns.body.statements, ts.factory.createExportDeclaration( /*decorators*/ undefined, /*modifiers*/ undefined, - /*isTypeOnly*/ false, - factory.createNamedExports(map(flatMap(excessExports, e => getNamesOfDeclaration(e)), id => factory.createExportSpecifier(/*isTypeOnly*/ false, /*alias*/ undefined, id))), - /*moduleSpecifier*/ undefined - )]) - ) - ); + /*isTypeOnly*/ false, ts.factory.createNamedExports(ts.map(ts.flatMap(excessExports, e => getNamesOfDeclaration(e)), id => ts.factory.createExportSpecifier(/*isTypeOnly*/ false, /*alias*/ undefined, id))), + /*moduleSpecifier*/ undefined)]))); statements = [...statements.slice(0, nsIndex), ns, ...statements.slice(nsIndex + 1)]; } // Pass 1: Flatten `export namespace _exports {} export = _exports;` so long as the `export=` only points at a single namespace declaration - if (!find(statements, s => s !== ns && nodeHasName(s, name))) { + if (!ts.find(statements, s => s !== ns && ts.nodeHasName(s, name))) { results = []; // If the namespace contains no export assignments or declarations, and no declarations flagged with `export`, then _everything_ is exported - // to respect this as the top level, we need to add an `export` modifier to everything - const mixinExportFlag = !some(body.statements, s => hasSyntacticModifier(s, ModifierFlags.Export) || isExportAssignment(s) || isExportDeclaration(s)); - forEach(body.statements, s => { - addResult(s, mixinExportFlag ? ModifierFlags.Export : ModifierFlags.None); // Recalculates the ambient (and export, if applicable from above) flag + const mixinExportFlag = !ts.some(body.statements, s => ts.hasSyntacticModifier(s, ts.ModifierFlags.Export) || ts.isExportAssignment(s) || ts.isExportDeclaration(s)); + ts.forEach(body.statements, s => { + addResult(s, mixinExportFlag ? ts.ModifierFlags.Export : ts.ModifierFlags.None); // Recalculates the ambient (and export, if applicable from above) flag }); - statements = [...filter(statements, s => s !== ns && s !== exportAssignment), ...results]; + statements = [...ts.filter(statements, s => s !== ns && s !== exportAssignment), ...results]; } } return statements; } - function mergeExportDeclarations(statements: Statement[]) { + function mergeExportDeclarations(statements: ts.Statement[]) { // Pass 2: Combine all `export {}` declarations - const exports = filter(statements, d => isExportDeclaration(d) && !d.moduleSpecifier && !!d.exportClause && isNamedExports(d.exportClause)) as ExportDeclaration[]; - if (length(exports) > 1) { - const nonExports = filter(statements, d => !isExportDeclaration(d) || !!d.moduleSpecifier || !d.exportClause); - statements = [...nonExports, factory.createExportDeclaration( + const exports = ts.filter(statements, d => ts.isExportDeclaration(d) && !d.moduleSpecifier && !!d.exportClause && ts.isNamedExports(d.exportClause)) as ts.ExportDeclaration[]; + if (ts.length(exports) > 1) { + const nonExports = ts.filter(statements, d => !ts.isExportDeclaration(d) || !!d.moduleSpecifier || !d.exportClause); + statements = [...nonExports, ts.factory.createExportDeclaration( /*decorators*/ undefined, /*modifiers*/ undefined, - /*isTypeOnly*/ false, - factory.createNamedExports(flatMap(exports, e => cast(e.exportClause, isNamedExports).elements)), - /*moduleSpecifier*/ undefined - )]; + /*isTypeOnly*/ false, ts.factory.createNamedExports(ts.flatMap(exports, e => ts.cast(e.exportClause, ts.isNamedExports).elements)), + /*moduleSpecifier*/ undefined)]; } // Pass 2b: Also combine all `export {} from "..."` declarations as needed - const reexports = filter(statements, d => isExportDeclaration(d) && !!d.moduleSpecifier && !!d.exportClause && isNamedExports(d.exportClause)) as ExportDeclaration[]; - if (length(reexports) > 1) { - const groups = group(reexports, decl => isStringLiteral(decl.moduleSpecifier!) ? ">" + decl.moduleSpecifier.text : ">"); + const reexports = ts.filter(statements, d => ts.isExportDeclaration(d) && !!d.moduleSpecifier && !!d.exportClause && ts.isNamedExports(d.exportClause)) as ts.ExportDeclaration[]; + if (ts.length(reexports) > 1) { + const groups = ts.group(reexports, decl => ts.isStringLiteral(decl.moduleSpecifier!) ? ">" + decl.moduleSpecifier.text : ">"); if (groups.length !== reexports.length) { for (const group of groups) { if (group.length > 1) { // remove group members from statements and then merge group members and add back to statements statements = [ - ...filter(statements, s => group.indexOf(s as ExportDeclaration) === -1), - factory.createExportDeclaration( + ...ts.filter(statements, s => group.indexOf(s as ts.ExportDeclaration) === -1), + ts.factory.createExportDeclaration( /*decorators*/ undefined, /*modifiers*/ undefined, - /*isTypeOnly*/ false, - factory.createNamedExports(flatMap(group, e => cast(e.exportClause, isNamedExports).elements)), - group[0].moduleSpecifier - ) + /*isTypeOnly*/ false, ts.factory.createNamedExports(ts.flatMap(group, e => ts.cast(e.exportClause, ts.isNamedExports).elements)), group[0].moduleSpecifier) ]; } } @@ -6940,49 +6693,40 @@ namespace ts { return statements; } - function inlineExportModifiers(statements: Statement[]) { + function inlineExportModifiers(statements: ts.Statement[]) { // Pass 3: Move all `export {}`'s to `export` modifiers where possible - const index = findIndex(statements, d => isExportDeclaration(d) && !d.moduleSpecifier && !d.assertClause && !!d.exportClause && isNamedExports(d.exportClause)); + const index = ts.findIndex(statements, d => ts.isExportDeclaration(d) && !d.moduleSpecifier && !d.assertClause && !!d.exportClause && ts.isNamedExports(d.exportClause)); if (index >= 0) { - const exportDecl = statements[index] as ExportDeclaration & { readonly exportClause: NamedExports }; - const replacements = mapDefined(exportDecl.exportClause.elements, e => { + const exportDecl = statements[index] as ts.ExportDeclaration & { + readonly exportClause: ts.NamedExports; + }; + const replacements = ts.mapDefined(exportDecl.exportClause.elements, e => { if (!e.propertyName) { // export {name} - look thru `statements` for `name`, and if all results can take an `export` modifier, do so and filter it - const indices = indicesOf(statements); - const associatedIndices = filter(indices, i => nodeHasName(statements[i], e.name)); - if (length(associatedIndices) && every(associatedIndices, i => canHaveExportModifier(statements[i]))) { + const indices = ts.indicesOf(statements); + const associatedIndices = ts.filter(indices, i => ts.nodeHasName(statements[i], e.name)); + if (ts.length(associatedIndices) && ts.every(associatedIndices, i => canHaveExportModifier(statements[i]))) { for (const index of associatedIndices) { - statements[index] = addExportModifier(statements[index] as Extract); + statements[index] = addExportModifier(statements[index] as Extract); } return undefined; } } return e; }); - if (!length(replacements)) { + if (!ts.length(replacements)) { // all clauses removed, remove the export declaration - orderedRemoveItemAt(statements, index); + ts.orderedRemoveItemAt(statements, index); } else { // some items filtered, others not - update the export declaration - statements[index] = factory.updateExportDeclaration( - exportDecl, - exportDecl.decorators, - exportDecl.modifiers, - exportDecl.isTypeOnly, - factory.updateNamedExports( - exportDecl.exportClause, - replacements - ), - exportDecl.moduleSpecifier, - exportDecl.assertClause - ); + statements[index] = ts.factory.updateExportDeclaration(exportDecl, exportDecl.decorators, exportDecl.modifiers, exportDecl.isTypeOnly, ts.factory.updateNamedExports(exportDecl.exportClause, replacements), exportDecl.moduleSpecifier, exportDecl.assertClause); } } return statements; } - function mergeRedundantStatements(statements: Statement[]) { + function mergeRedundantStatements(statements: ts.Statement[]) { statements = flattenExportAssignedNamespace(statements); statements = mergeExportDeclarations(statements); statements = inlineExportModifiers(statements); @@ -6990,52 +6734,52 @@ namespace ts { // Not a cleanup, but as a final step: If there is a mix of `export` and non-`export` declarations, but no `export =` or `export {}` add a `export {};` so // declaration privacy is respected. if (enclosingDeclaration && - ((isSourceFile(enclosingDeclaration) && isExternalOrCommonJsModule(enclosingDeclaration)) || isModuleDeclaration(enclosingDeclaration)) && - (!some(statements, isExternalModuleIndicator) || (!hasScopeMarker(statements) && some(statements, needsScopeMarker)))) { - statements.push(createEmptyExports(factory)); + ((ts.isSourceFile(enclosingDeclaration) && ts.isExternalOrCommonJsModule(enclosingDeclaration)) || ts.isModuleDeclaration(enclosingDeclaration)) && + (!ts.some(statements, ts.isExternalModuleIndicator) || (!ts.hasScopeMarker(statements) && ts.some(statements, ts.needsScopeMarker)))) { + statements.push(ts.createEmptyExports(ts.factory)); } return statements; } - function canHaveExportModifier(node: Statement): node is Extract { - return isEnumDeclaration(node) || - isVariableStatement(node) || - isFunctionDeclaration(node) || - isClassDeclaration(node) || - (isModuleDeclaration(node) && !isExternalModuleAugmentation(node) && !isGlobalScopeAugmentation(node)) || - isInterfaceDeclaration(node) || + function canHaveExportModifier(node: ts.Statement): node is Extract { + return ts.isEnumDeclaration(node) || + ts.isVariableStatement(node) || + ts.isFunctionDeclaration(node) || + ts.isClassDeclaration(node) || + (ts.isModuleDeclaration(node) && !ts.isExternalModuleAugmentation(node) && !ts.isGlobalScopeAugmentation(node)) || + ts.isInterfaceDeclaration(node) || isTypeDeclaration(node); } - function addExportModifier(node: Extract) { - const flags = (getEffectiveModifierFlags(node) | ModifierFlags.Export) & ~ModifierFlags.Ambient; - return factory.updateModifiers(node, flags); + function addExportModifier(node: Extract) { + const flags = (ts.getEffectiveModifierFlags(node) | ts.ModifierFlags.Export) & ~ts.ModifierFlags.Ambient; + return ts.factory.updateModifiers(node, flags); } - function removeExportModifier(node: Extract) { - const flags = getEffectiveModifierFlags(node) & ~ModifierFlags.Export; - return factory.updateModifiers(node, flags); + function removeExportModifier(node: Extract) { + const flags = ts.getEffectiveModifierFlags(node) & ~ts.ModifierFlags.Export; + return ts.factory.updateModifiers(node, flags); } - function visitSymbolTable(symbolTable: SymbolTable, suppressNewPrivateContext?: boolean, propertyAsAlias?: boolean) { + function visitSymbolTable(symbolTable: ts.SymbolTable, suppressNewPrivateContext?: boolean, propertyAsAlias?: boolean) { if (!suppressNewPrivateContext) { - deferredPrivatesStack.push(new Map()); + deferredPrivatesStack.push(new ts.Map()); } - symbolTable.forEach((symbol: Symbol) => { + symbolTable.forEach((symbol: ts.Symbol) => { serializeSymbol(symbol, /*isPrivate*/ false, !!propertyAsAlias); }); if (!suppressNewPrivateContext) { // deferredPrivates will be filled up by visiting the symbol table // And will continue to iterate as elements are added while visited `deferredPrivates` // (As that's how a map iterator is defined to work) - deferredPrivatesStack[deferredPrivatesStack.length - 1].forEach((symbol: Symbol) => { + deferredPrivatesStack[deferredPrivatesStack.length - 1].forEach((symbol: ts.Symbol) => { serializeSymbol(symbol, /*isPrivate*/ true, !!propertyAsAlias); }); deferredPrivatesStack.pop(); } } - function serializeSymbol(symbol: Symbol, isPrivate: boolean, propertyAsAlias: boolean) { + function serializeSymbol(symbol: ts.Symbol, isPrivate: boolean, propertyAsAlias: boolean) { // cache visited list based on merged symbol, since we want to use the unmerged top-level symbol, but // still skip reserializing it if we encounter the merged product later on const visitedSym = getMergedSymbol(symbol); @@ -7045,7 +6789,7 @@ namespace ts { visitedSymbols.add(getSymbolId(visitedSym)); // Only actually serialize symbols within the correct enclosing declaration, otherwise do nothing with the out-of-context symbol const skipMembershipCheck = !isPrivate; // We only call this on exported symbols when we know they're in the correct scope - if (skipMembershipCheck || (!!length(symbol.declarations) && some(symbol.declarations, d => !!findAncestor(d, n => n === enclosingDeclaration)))) { + if (skipMembershipCheck || (!!ts.length(symbol.declarations) && ts.some(symbol.declarations, d => !!ts.findAncestor(d, n => n === enclosingDeclaration)))) { const oldContext = context; context = cloneNodeBuilderContext(context); const result = serializeSymbolWorker(symbol, isPrivate, propertyAsAlias); @@ -7067,41 +6811,39 @@ namespace ts { // If it's a property: emit `export default _default` with a `_default` prop // If it's a class/interface/function: emit a class/interface/function with a `default` modifier // These forms can merge, eg (`export default 12; export default interface A {}`) - function serializeSymbolWorker(symbol: Symbol, isPrivate: boolean, propertyAsAlias: boolean) { - const symbolName = unescapeLeadingUnderscores(symbol.escapedName); - const isDefault = symbol.escapedName === InternalSymbolName.Default; - if (isPrivate && !(context.flags & NodeBuilderFlags.AllowAnonymousIdentifier) && isStringANonContextualKeyword(symbolName) && !isDefault) { + function serializeSymbolWorker(symbol: ts.Symbol, isPrivate: boolean, propertyAsAlias: boolean) { + const symbolName = ts.unescapeLeadingUnderscores(symbol.escapedName); + const isDefault = symbol.escapedName === ts.InternalSymbolName.Default; + if (isPrivate && !(context.flags & ts.NodeBuilderFlags.AllowAnonymousIdentifier) && ts.isStringANonContextualKeyword(symbolName) && !isDefault) { // Oh no. We cannot use this symbol's name as it's name... It's likely some jsdoc had an invalid name like `export` or `default` :( context.encounteredError = true; // TODO: Issue error via symbol tracker? return; // If we need to emit a private with a keyword name, we're done for, since something else will try to refer to it by that name } - let needsPostExportDefault = isDefault && !!( - symbol.flags & SymbolFlags.ExportDoesNotSupportDefaultModifier - || (symbol.flags & SymbolFlags.Function && length(getPropertiesOfType(getTypeOfSymbol(symbol)))) - ) && !(symbol.flags & SymbolFlags.Alias); // An alias symbol should preclude needing to make an alias ourselves - let needsExportDeclaration = !needsPostExportDefault && !isPrivate && isStringANonContextualKeyword(symbolName) && !isDefault; + let needsPostExportDefault = isDefault && !!(symbol.flags & ts.SymbolFlags.ExportDoesNotSupportDefaultModifier + || (symbol.flags & ts.SymbolFlags.Function && ts.length(getPropertiesOfType(getTypeOfSymbol(symbol))))) && !(symbol.flags & ts.SymbolFlags.Alias); // An alias symbol should preclude needing to make an alias ourselves + let needsExportDeclaration = !needsPostExportDefault && !isPrivate && ts.isStringANonContextualKeyword(symbolName) && !isDefault; // `serializeVariableOrProperty` will handle adding the export declaration if it is run (since `getInternalSymbolName` will create the name mapping), so we need to ensuer we unset `needsExportDeclaration` if it is if (needsPostExportDefault || needsExportDeclaration) { isPrivate = true; } - const modifierFlags = (!isPrivate ? ModifierFlags.Export : 0) | (isDefault && !needsPostExportDefault ? ModifierFlags.Default : 0); - const isConstMergedWithNS = symbol.flags & SymbolFlags.Module && - symbol.flags & (SymbolFlags.BlockScopedVariable | SymbolFlags.FunctionScopedVariable | SymbolFlags.Property) && - symbol.escapedName !== InternalSymbolName.ExportEquals; + const modifierFlags = (!isPrivate ? ts.ModifierFlags.Export : 0) | (isDefault && !needsPostExportDefault ? ts.ModifierFlags.Default : 0); + const isConstMergedWithNS = symbol.flags & ts.SymbolFlags.Module && + symbol.flags & (ts.SymbolFlags.BlockScopedVariable | ts.SymbolFlags.FunctionScopedVariable | ts.SymbolFlags.Property) && + symbol.escapedName !== ts.InternalSymbolName.ExportEquals; const isConstMergedWithNSPrintableAsSignatureMerge = isConstMergedWithNS && isTypeRepresentableAsFunctionNamespaceMerge(getTypeOfSymbol(symbol), symbol); - if (symbol.flags & (SymbolFlags.Function | SymbolFlags.Method) || isConstMergedWithNSPrintableAsSignatureMerge) { + if (symbol.flags & (ts.SymbolFlags.Function | ts.SymbolFlags.Method) || isConstMergedWithNSPrintableAsSignatureMerge) { serializeAsFunctionNamespaceMerge(getTypeOfSymbol(symbol), symbol, getInternalSymbolName(symbol, symbolName), modifierFlags); } - if (symbol.flags & SymbolFlags.TypeAlias) { + if (symbol.flags & ts.SymbolFlags.TypeAlias) { serializeTypeAlias(symbol, symbolName, modifierFlags); } // Need to skip over export= symbols below - json source files get a single `Property` flagged // symbol of name `export=` which needs to be handled like an alias. It's not great, but it is what it is. - if (symbol.flags & (SymbolFlags.BlockScopedVariable | SymbolFlags.FunctionScopedVariable | SymbolFlags.Property) - && symbol.escapedName !== InternalSymbolName.ExportEquals - && !(symbol.flags & SymbolFlags.Prototype) - && !(symbol.flags & SymbolFlags.Class) + if (symbol.flags & (ts.SymbolFlags.BlockScopedVariable | ts.SymbolFlags.FunctionScopedVariable | ts.SymbolFlags.Property) + && symbol.escapedName !== ts.InternalSymbolName.ExportEquals + && !(symbol.flags & ts.SymbolFlags.Prototype) + && !(symbol.flags & ts.SymbolFlags.Class) && !isConstMergedWithNSPrintableAsSignatureMerge) { if (propertyAsAlias) { const createdExport = serializeMaybeAliasAssignment(symbol); @@ -7113,45 +6855,40 @@ namespace ts { else { const type = getTypeOfSymbol(symbol); const localName = getInternalSymbolName(symbol, symbolName); - if (!(symbol.flags & SymbolFlags.Function) && isTypeRepresentableAsFunctionNamespaceMerge(type, symbol)) { + if (!(symbol.flags & ts.SymbolFlags.Function) && isTypeRepresentableAsFunctionNamespaceMerge(type, symbol)) { // If the type looks like a function declaration + ns could represent it, and it's type is sourced locally, rewrite it into a function declaration + ns serializeAsFunctionNamespaceMerge(type, symbol, localName, modifierFlags); } else { // A Class + Property merge is made for a `module.exports.Member = class {}`, and it doesn't serialize well as either a class _or_ a property symbol - in fact, _it behaves like an alias!_ // `var` is `FunctionScopedVariable`, `const` and `let` are `BlockScopedVariable`, and `module.exports.thing =` is `Property` - const flags = !(symbol.flags & SymbolFlags.BlockScopedVariable) - ? symbol.parent?.valueDeclaration && isSourceFile(symbol.parent?.valueDeclaration) - ? NodeFlags.Const // exports are immutable in es6, which is what we emulate and check; so it's safe to mark all exports as `const` (there's no difference to consumers, but it allows unique symbol type declarations) + const flags = !(symbol.flags & ts.SymbolFlags.BlockScopedVariable) + ? symbol.parent?.valueDeclaration && ts.isSourceFile(symbol.parent?.valueDeclaration) + ? ts.NodeFlags.Const // exports are immutable in es6, which is what we emulate and check; so it's safe to mark all exports as `const` (there's no difference to consumers, but it allows unique symbol type declarations) : undefined : isConstVariable(symbol) - ? NodeFlags.Const - : NodeFlags.Let; - const name = (needsPostExportDefault || !(symbol.flags & SymbolFlags.Property)) ? localName : getUnusedName(localName, symbol); - let textRange: Node | undefined = symbol.declarations && find(symbol.declarations, d => isVariableDeclaration(d)); - if (textRange && isVariableDeclarationList(textRange.parent) && textRange.parent.declarations.length === 1) { + ? ts.NodeFlags.Const + : ts.NodeFlags.Let; + const name = (needsPostExportDefault || !(symbol.flags & ts.SymbolFlags.Property)) ? localName : getUnusedName(localName, symbol); + let textRange: ts.Node | undefined = symbol.declarations && ts.find(symbol.declarations, d => ts.isVariableDeclaration(d)); + if (textRange && ts.isVariableDeclarationList(textRange.parent) && textRange.parent.declarations.length === 1) { textRange = textRange.parent.parent; } - const propertyAccessRequire = symbol.declarations?.find(isPropertyAccessExpression); - if (propertyAccessRequire && isBinaryExpression(propertyAccessRequire.parent) && isIdentifier(propertyAccessRequire.parent.right) - && type.symbol?.valueDeclaration && isSourceFile(type.symbol.valueDeclaration)) { + const propertyAccessRequire = symbol.declarations?.find(ts.isPropertyAccessExpression); + if (propertyAccessRequire && ts.isBinaryExpression(propertyAccessRequire.parent) && ts.isIdentifier(propertyAccessRequire.parent.right) + && type.symbol?.valueDeclaration && ts.isSourceFile(type.symbol.valueDeclaration)) { const alias = localName === propertyAccessRequire.parent.right.escapedText ? undefined : propertyAccessRequire.parent.right; - addResult( - factory.createExportDeclaration( + addResult(ts.factory.createExportDeclaration( /*decorators*/ undefined, /*modifiers*/ undefined, - /*isTypeOnly*/ false, - factory.createNamedExports([factory.createExportSpecifier(/*isTypeOnly*/ false, alias, localName)]) - ), - ModifierFlags.None - ); - context.tracker.trackSymbol!(type.symbol, context.enclosingDeclaration, SymbolFlags.Value); + /*isTypeOnly*/ false, ts.factory.createNamedExports([ts.factory.createExportSpecifier(/*isTypeOnly*/ false, alias, localName)])), ts.ModifierFlags.None); + context.tracker.trackSymbol!(type.symbol, context.enclosingDeclaration, ts.SymbolFlags.Value); } else { - const statement = setTextRange(factory.createVariableStatement(/*modifiers*/ undefined, factory.createVariableDeclarationList([ - factory.createVariableDeclaration(name, /*exclamationToken*/ undefined, serializeTypeForDeclaration(context, type, symbol, enclosingDeclaration, includePrivateSymbol, bundled)) + const statement = ts.setTextRange(ts.factory.createVariableStatement(/*modifiers*/ undefined, ts.factory.createVariableDeclarationList([ + ts.factory.createVariableDeclaration(name, /*exclamationToken*/ undefined, serializeTypeForDeclaration(context, type, symbol, enclosingDeclaration, includePrivateSymbol, bundled)) ], flags)), textRange); - addResult(statement, name !== localName ? modifierFlags & ~ModifierFlags.Export : modifierFlags); + addResult(statement, name !== localName ? modifierFlags & ~ts.ModifierFlags.Export : modifierFlags); if (name !== localName && !isPrivate) { // We rename the variable declaration we generate for Property symbols since they may have a name which // conflicts with a local declaration. For example, given input: @@ -7174,15 +6911,10 @@ namespace ts { // export { g_1 as g }; // ``` // To create an export named `g` that does _not_ shadow the local `g` - addResult( - factory.createExportDeclaration( + addResult(ts.factory.createExportDeclaration( /*decorators*/ undefined, /*modifiers*/ undefined, - /*isTypeOnly*/ false, - factory.createNamedExports([factory.createExportSpecifier(/*isTypeOnly*/ false, name, localName)]) - ), - ModifierFlags.None - ); + /*isTypeOnly*/ false, ts.factory.createNamedExports([ts.factory.createExportSpecifier(/*isTypeOnly*/ false, name, localName)])), ts.ModifierFlags.None); needsExportDeclaration = false; needsPostExportDefault = false; } @@ -7190,14 +6922,14 @@ namespace ts { } } } - if (symbol.flags & SymbolFlags.Enum) { + if (symbol.flags & ts.SymbolFlags.Enum) { serializeEnum(symbol, symbolName, modifierFlags); } - if (symbol.flags & SymbolFlags.Class) { - if (symbol.flags & SymbolFlags.Property + if (symbol.flags & ts.SymbolFlags.Class) { + if (symbol.flags & ts.SymbolFlags.Property && symbol.valueDeclaration - && isBinaryExpression(symbol.valueDeclaration.parent) - && isClassExpression(symbol.valueDeclaration.parent.right)) { + && ts.isBinaryExpression(symbol.valueDeclaration.parent) + && ts.isClassExpression(symbol.valueDeclaration.parent.right)) { // Looks like a `module.exports.Sub = class {}` - if we serialize `symbol` as a class, the result will have no members, // since the classiness is actually from the target of the effective alias the symbol is. yes. A BlockScopedVariable|Class|Property // _really_ acts like an Alias, and none of a BlockScopedVariable, Class, or Property. This is the travesty of JS binding today. @@ -7207,243 +6939,217 @@ namespace ts { serializeAsClass(symbol, getInternalSymbolName(symbol, symbolName), modifierFlags); } } - if ((symbol.flags & (SymbolFlags.ValueModule | SymbolFlags.NamespaceModule) && (!isConstMergedWithNS || isTypeOnlyNamespace(symbol))) || isConstMergedWithNSPrintableAsSignatureMerge) { + if ((symbol.flags & (ts.SymbolFlags.ValueModule | ts.SymbolFlags.NamespaceModule) && (!isConstMergedWithNS || isTypeOnlyNamespace(symbol))) || isConstMergedWithNSPrintableAsSignatureMerge) { serializeModule(symbol, symbolName, modifierFlags); } // The class meaning serialization should handle serializing all interface members - if (symbol.flags & SymbolFlags.Interface && !(symbol.flags & SymbolFlags.Class)) { + if (symbol.flags & ts.SymbolFlags.Interface && !(symbol.flags & ts.SymbolFlags.Class)) { serializeInterface(symbol, symbolName, modifierFlags); } - if (symbol.flags & SymbolFlags.Alias) { + if (symbol.flags & ts.SymbolFlags.Alias) { serializeAsAlias(symbol, getInternalSymbolName(symbol, symbolName), modifierFlags); } - if (symbol.flags & SymbolFlags.Property && symbol.escapedName === InternalSymbolName.ExportEquals) { + if (symbol.flags & ts.SymbolFlags.Property && symbol.escapedName === ts.InternalSymbolName.ExportEquals) { serializeMaybeAliasAssignment(symbol); } - if (symbol.flags & SymbolFlags.ExportStar) { + if (symbol.flags & ts.SymbolFlags.ExportStar) { // synthesize export * from "moduleReference" // Straightforward - only one thing to do - make an export declaration if (symbol.declarations) { for (const node of symbol.declarations) { - const resolvedModule = resolveExternalModuleName(node, (node as ExportDeclaration).moduleSpecifier!); - if (!resolvedModule) continue; - addResult(factory.createExportDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, /*isTypeOnly*/ false, /*exportClause*/ undefined, factory.createStringLiteral(getSpecifierForModuleSymbol(resolvedModule, context))), ModifierFlags.None); + const resolvedModule = resolveExternalModuleName(node, (node as ts.ExportDeclaration).moduleSpecifier!); + if (!resolvedModule) + continue; + addResult(ts.factory.createExportDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, /*isTypeOnly*/ false, /*exportClause*/ undefined, ts.factory.createStringLiteral(getSpecifierForModuleSymbol(resolvedModule, context))), ts.ModifierFlags.None); } } } if (needsPostExportDefault) { - addResult(factory.createExportAssignment(/*decorators*/ undefined, /*modifiers*/ undefined, /*isExportAssignment*/ false, factory.createIdentifier(getInternalSymbolName(symbol, symbolName))), ModifierFlags.None); + addResult(ts.factory.createExportAssignment(/*decorators*/ undefined, /*modifiers*/ undefined, /*isExportAssignment*/ false, ts.factory.createIdentifier(getInternalSymbolName(symbol, symbolName))), ts.ModifierFlags.None); } else if (needsExportDeclaration) { - addResult(factory.createExportDeclaration( + addResult(ts.factory.createExportDeclaration( /*decorators*/ undefined, /*modifiers*/ undefined, - /*isTypeOnly*/ false, - factory.createNamedExports([factory.createExportSpecifier(/*isTypeOnly*/ false, getInternalSymbolName(symbol, symbolName), symbolName)]) - ), ModifierFlags.None); + /*isTypeOnly*/ false, ts.factory.createNamedExports([ts.factory.createExportSpecifier(/*isTypeOnly*/ false, getInternalSymbolName(symbol, symbolName), symbolName)])), ts.ModifierFlags.None); } } - function includePrivateSymbol(symbol: Symbol) { - if (some(symbol.declarations, isParameterDeclaration)) return; - Debug.assertIsDefined(deferredPrivatesStack[deferredPrivatesStack.length - 1]); - getUnusedName(unescapeLeadingUnderscores(symbol.escapedName), symbol); // Call to cache unique name for symbol + function includePrivateSymbol(symbol: ts.Symbol) { + if (ts.some(symbol.declarations, ts.isParameterDeclaration)) + return; + ts.Debug.assertIsDefined(deferredPrivatesStack[deferredPrivatesStack.length - 1]); + getUnusedName(ts.unescapeLeadingUnderscores(symbol.escapedName), symbol); // Call to cache unique name for symbol // Blanket moving (import) aliases into the root private context should work, since imports are not valid within namespaces // (so they must have been in the root to begin with if they were real imports) cjs `require` aliases (an upcoming feature) // will throw a wrench in this, since those may have been nested, but we'll need to synthesize them in the outer scope // anyway, as that's the only place the import they translate to is valid. In such a case, we might need to use a unique name // for the moved import; which hopefully the above `getUnusedName` call should produce. - const isExternalImportAlias = !!(symbol.flags & SymbolFlags.Alias) && !some(symbol.declarations, d => - !!findAncestor(d, isExportDeclaration) || - isNamespaceExport(d) || - (isImportEqualsDeclaration(d) && !isExternalModuleReference(d.moduleReference)) - ); + const isExternalImportAlias = !!(symbol.flags & ts.SymbolFlags.Alias) && !ts.some(symbol.declarations, d => !!ts.findAncestor(d, ts.isExportDeclaration) || + ts.isNamespaceExport(d) || + (ts.isImportEqualsDeclaration(d) && !ts.isExternalModuleReference(d.moduleReference))); deferredPrivatesStack[isExternalImportAlias ? 0 : (deferredPrivatesStack.length - 1)].set(getSymbolId(symbol), symbol); } - function isExportingScope(enclosingDeclaration: Node) { - return ((isSourceFile(enclosingDeclaration) && (isExternalOrCommonJsModule(enclosingDeclaration) || isJsonSourceFile(enclosingDeclaration))) || - (isAmbientModule(enclosingDeclaration) && !isGlobalScopeAugmentation(enclosingDeclaration))); + function isExportingScope(enclosingDeclaration: ts.Node) { + return ((ts.isSourceFile(enclosingDeclaration) && (ts.isExternalOrCommonJsModule(enclosingDeclaration) || ts.isJsonSourceFile(enclosingDeclaration))) || + (ts.isAmbientModule(enclosingDeclaration) && !ts.isGlobalScopeAugmentation(enclosingDeclaration))); } // Prepends a `declare` and/or `export` modifier if the context requires it, and then adds `node` to `result` and returns `node` - function addResult(node: Statement, additionalModifierFlags: ModifierFlags) { - if (canHaveModifiers(node)) { - let newModifierFlags: ModifierFlags = ModifierFlags.None; + function addResult(node: ts.Statement, additionalModifierFlags: ts.ModifierFlags) { + if (ts.canHaveModifiers(node)) { + let newModifierFlags: ts.ModifierFlags = ts.ModifierFlags.None; const enclosingDeclaration = context.enclosingDeclaration && - (isJSDocTypeAlias(context.enclosingDeclaration) ? getSourceFileOfNode(context.enclosingDeclaration) : context.enclosingDeclaration); - if (additionalModifierFlags & ModifierFlags.Export && - enclosingDeclaration && (isExportingScope(enclosingDeclaration) || isModuleDeclaration(enclosingDeclaration)) && - canHaveExportModifier(node) - ) { + (ts.isJSDocTypeAlias(context.enclosingDeclaration) ? ts.getSourceFileOfNode(context.enclosingDeclaration) : context.enclosingDeclaration); + if (additionalModifierFlags & ts.ModifierFlags.Export && + enclosingDeclaration && (isExportingScope(enclosingDeclaration) || ts.isModuleDeclaration(enclosingDeclaration)) && + canHaveExportModifier(node)) { // Classes, namespaces, variables, functions, interfaces, and types should all be `export`ed in a module context if not private - newModifierFlags |= ModifierFlags.Export; + newModifierFlags |= ts.ModifierFlags.Export; } - if (addingDeclare && !(newModifierFlags & ModifierFlags.Export) && - (!enclosingDeclaration || !(enclosingDeclaration.flags & NodeFlags.Ambient)) && - (isEnumDeclaration(node) || isVariableStatement(node) || isFunctionDeclaration(node) || isClassDeclaration(node) || isModuleDeclaration(node))) { + if (addingDeclare && !(newModifierFlags & ts.ModifierFlags.Export) && + (!enclosingDeclaration || !(enclosingDeclaration.flags & ts.NodeFlags.Ambient)) && + (ts.isEnumDeclaration(node) || ts.isVariableStatement(node) || ts.isFunctionDeclaration(node) || ts.isClassDeclaration(node) || ts.isModuleDeclaration(node))) { // Classes, namespaces, variables, enums, and functions all need `declare` modifiers to be valid in a declaration file top-level scope - newModifierFlags |= ModifierFlags.Ambient; + newModifierFlags |= ts.ModifierFlags.Ambient; } - if ((additionalModifierFlags & ModifierFlags.Default) && (isClassDeclaration(node) || isInterfaceDeclaration(node) || isFunctionDeclaration(node))) { - newModifierFlags |= ModifierFlags.Default; + if ((additionalModifierFlags & ts.ModifierFlags.Default) && (ts.isClassDeclaration(node) || ts.isInterfaceDeclaration(node) || ts.isFunctionDeclaration(node))) { + newModifierFlags |= ts.ModifierFlags.Default; } if (newModifierFlags) { - node = factory.updateModifiers(node, newModifierFlags | getEffectiveModifierFlags(node)); + node = ts.factory.updateModifiers(node, newModifierFlags | ts.getEffectiveModifierFlags(node)); } } results.push(node); } - function serializeTypeAlias(symbol: Symbol, symbolName: string, modifierFlags: ModifierFlags) { + function serializeTypeAlias(symbol: ts.Symbol, symbolName: string, modifierFlags: ts.ModifierFlags) { const aliasType = getDeclaredTypeOfTypeAlias(symbol); const typeParams = getSymbolLinks(symbol).typeParameters; - const typeParamDecls = map(typeParams, p => typeParameterToDeclaration(p, context)); - const jsdocAliasDecl = symbol.declarations?.find(isJSDocTypeAlias); - const commentText = getTextOfJSDocComment(jsdocAliasDecl ? jsdocAliasDecl.comment || jsdocAliasDecl.parent.comment : undefined); + const typeParamDecls = ts.map(typeParams, p => typeParameterToDeclaration(p, context)); + const jsdocAliasDecl = symbol.declarations?.find(ts.isJSDocTypeAlias); + const commentText = ts.getTextOfJSDocComment(jsdocAliasDecl ? jsdocAliasDecl.comment || jsdocAliasDecl.parent.comment : undefined); const oldFlags = context.flags; - context.flags |= NodeBuilderFlags.InTypeAlias; + context.flags |= ts.NodeBuilderFlags.InTypeAlias; const oldEnclosingDecl = context.enclosingDeclaration; context.enclosingDeclaration = jsdocAliasDecl; const typeNode = jsdocAliasDecl && jsdocAliasDecl.typeExpression - && isJSDocTypeExpression(jsdocAliasDecl.typeExpression) + && ts.isJSDocTypeExpression(jsdocAliasDecl.typeExpression) && serializeExistingTypeNode(context, jsdocAliasDecl.typeExpression.type, includePrivateSymbol, bundled) || typeToTypeNodeHelper(aliasType, context); - addResult(setSyntheticLeadingComments( - factory.createTypeAliasDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, getInternalSymbolName(symbol, symbolName), typeParamDecls, typeNode), - !commentText ? [] : [{ kind: SyntaxKind.MultiLineCommentTrivia, text: "*\n * " + commentText.replace(/\n/g, "\n * ") + "\n ", pos: -1, end: -1, hasTrailingNewLine: true }] - ), modifierFlags); + addResult(ts.setSyntheticLeadingComments(ts.factory.createTypeAliasDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, getInternalSymbolName(symbol, symbolName), typeParamDecls, typeNode), !commentText ? [] : [{ kind: ts.SyntaxKind.MultiLineCommentTrivia, text: "*\n * " + commentText.replace(/\n/g, "\n * ") + "\n ", pos: -1, end: -1, hasTrailingNewLine: true }]), modifierFlags); context.flags = oldFlags; context.enclosingDeclaration = oldEnclosingDecl; } - function serializeInterface(symbol: Symbol, symbolName: string, modifierFlags: ModifierFlags) { + function serializeInterface(symbol: ts.Symbol, symbolName: string, modifierFlags: ts.ModifierFlags) { const interfaceType = getDeclaredTypeOfClassOrInterface(symbol); const localParams = getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(symbol); - const typeParamDecls = map(localParams, p => typeParameterToDeclaration(p, context)); + const typeParamDecls = ts.map(localParams, p => typeParameterToDeclaration(p, context)); const baseTypes = getBaseTypes(interfaceType); - const baseType = length(baseTypes) ? getIntersectionType(baseTypes) : undefined; - const members = flatMap(getPropertiesOfType(interfaceType), p => serializePropertySymbolForInterface(p, baseType)); - const callSignatures = serializeSignatures(SignatureKind.Call, interfaceType, baseType, SyntaxKind.CallSignature) as CallSignatureDeclaration[]; - const constructSignatures = serializeSignatures(SignatureKind.Construct, interfaceType, baseType, SyntaxKind.ConstructSignature) as ConstructSignatureDeclaration[]; + const baseType = ts.length(baseTypes) ? getIntersectionType(baseTypes) : undefined; + const members = ts.flatMap(getPropertiesOfType(interfaceType), p => serializePropertySymbolForInterface(p, baseType)); + const callSignatures = serializeSignatures(ts.SignatureKind.Call, interfaceType, baseType, ts.SyntaxKind.CallSignature) as ts.CallSignatureDeclaration[]; + const constructSignatures = serializeSignatures(ts.SignatureKind.Construct, interfaceType, baseType, ts.SyntaxKind.ConstructSignature) as ts.ConstructSignatureDeclaration[]; const indexSignatures = serializeIndexSignatures(interfaceType, baseType); - const heritageClauses = !length(baseTypes) ? undefined : [factory.createHeritageClause(SyntaxKind.ExtendsKeyword, mapDefined(baseTypes, b => trySerializeAsTypeReference(b, SymbolFlags.Value)))]; - addResult(factory.createInterfaceDeclaration( + const heritageClauses = !ts.length(baseTypes) ? undefined : [ts.factory.createHeritageClause(ts.SyntaxKind.ExtendsKeyword, ts.mapDefined(baseTypes, b => trySerializeAsTypeReference(b, ts.SymbolFlags.Value)))]; + addResult(ts.factory.createInterfaceDeclaration( /*decorators*/ undefined, - /*modifiers*/ undefined, - getInternalSymbolName(symbol, symbolName), - typeParamDecls, - heritageClauses, - [...indexSignatures, ...constructSignatures, ...callSignatures, ...members] - ), modifierFlags); + /*modifiers*/ undefined, getInternalSymbolName(symbol, symbolName), typeParamDecls, heritageClauses, [...indexSignatures, ...constructSignatures, ...callSignatures, ...members]), modifierFlags); } - function getNamespaceMembersForSerialization(symbol: Symbol) { - return !symbol.exports ? [] : filter(arrayFrom(symbol.exports.values()), isNamespaceMember); + function getNamespaceMembersForSerialization(symbol: ts.Symbol) { + return !symbol.exports ? [] : ts.filter(ts.arrayFrom(symbol.exports.values()), isNamespaceMember); } - function isTypeOnlyNamespace(symbol: Symbol) { - return every(getNamespaceMembersForSerialization(symbol), m => !(resolveSymbol(m).flags & SymbolFlags.Value)); + function isTypeOnlyNamespace(symbol: ts.Symbol) { + return ts.every(getNamespaceMembersForSerialization(symbol), m => !(resolveSymbol(m).flags & ts.SymbolFlags.Value)); } - function serializeModule(symbol: Symbol, symbolName: string, modifierFlags: ModifierFlags) { + function serializeModule(symbol: ts.Symbol, symbolName: string, modifierFlags: ts.ModifierFlags) { const members = getNamespaceMembersForSerialization(symbol); // Split NS members up by declaration - members whose parent symbol is the ns symbol vs those whose is not (but were added in later via merging) - const locationMap = arrayToMultiMap(members, m => m.parent && m.parent === symbol ? "real" : "merged"); - const realMembers = locationMap.get("real") || emptyArray; - const mergedMembers = locationMap.get("merged") || emptyArray; + const locationMap = ts.arrayToMultiMap(members, m => m.parent && m.parent === symbol ? "real" : "merged"); + const realMembers = locationMap.get("real") || ts.emptyArray; + const mergedMembers = locationMap.get("merged") || ts.emptyArray; // TODO: `suppressNewPrivateContext` is questionable -we need to simply be emitting privates in whatever scope they were declared in, rather // than whatever scope we traverse to them in. That's a bit of a complex rewrite, since we're not _actually_ tracking privates at all in advance, // so we don't even have placeholders to fill in. - if (length(realMembers)) { + if (ts.length(realMembers)) { const localName = getInternalSymbolName(symbol, symbolName); - serializeAsNamespaceDeclaration(realMembers, localName, modifierFlags, !!(symbol.flags & (SymbolFlags.Function | SymbolFlags.Assignment))); + serializeAsNamespaceDeclaration(realMembers, localName, modifierFlags, !!(symbol.flags & (ts.SymbolFlags.Function | ts.SymbolFlags.Assignment))); } - if (length(mergedMembers)) { - const containingFile = getSourceFileOfNode(context.enclosingDeclaration); + if (ts.length(mergedMembers)) { + const containingFile = ts.getSourceFileOfNode(context.enclosingDeclaration); const localName = getInternalSymbolName(symbol, symbolName); - const nsBody = factory.createModuleBlock([factory.createExportDeclaration( + const nsBody = ts.factory.createModuleBlock([ts.factory.createExportDeclaration( /*decorators*/ undefined, /*modifiers*/ undefined, - /*isTypeOnly*/ false, - factory.createNamedExports(mapDefined(filter(mergedMembers, n => n.escapedName !== InternalSymbolName.ExportEquals), s => { - const name = unescapeLeadingUnderscores(s.escapedName); + /*isTypeOnly*/ false, ts.factory.createNamedExports(ts.mapDefined(ts.filter(mergedMembers, n => n.escapedName !== ts.InternalSymbolName.ExportEquals), s => { + const name = ts.unescapeLeadingUnderscores(s.escapedName); const localName = getInternalSymbolName(s, name); const aliasDecl = s.declarations && getDeclarationOfAliasSymbol(s); - if (containingFile && (aliasDecl ? containingFile !== getSourceFileOfNode(aliasDecl) : !some(s.declarations, d => getSourceFileOfNode(d) === containingFile))) { + if (containingFile && (aliasDecl ? containingFile !== ts.getSourceFileOfNode(aliasDecl) : !ts.some(s.declarations, d => ts.getSourceFileOfNode(d) === containingFile))) { context.tracker?.reportNonlocalAugmentation?.(containingFile, symbol, s); return undefined; } const target = aliasDecl && getTargetOfAliasDeclaration(aliasDecl, /*dontRecursivelyResolve*/ true); includePrivateSymbol(target || s); - const targetName = target ? getInternalSymbolName(target, unescapeLeadingUnderscores(target.escapedName)) : localName; - return factory.createExportSpecifier(/*isTypeOnly*/ false, name === targetName ? undefined : targetName, name); - })) - )]); - addResult(factory.createModuleDeclaration( + const targetName = target ? getInternalSymbolName(target, ts.unescapeLeadingUnderscores(target.escapedName)) : localName; + return ts.factory.createExportSpecifier(/*isTypeOnly*/ false, name === targetName ? undefined : targetName, name); + })))]); + addResult(ts.factory.createModuleDeclaration( /*decorators*/ undefined, - /*modifiers*/ undefined, - factory.createIdentifier(localName), - nsBody, - NodeFlags.Namespace - ), ModifierFlags.None); + /*modifiers*/ undefined, ts.factory.createIdentifier(localName), nsBody, ts.NodeFlags.Namespace), ts.ModifierFlags.None); } } - function serializeEnum(symbol: Symbol, symbolName: string, modifierFlags: ModifierFlags) { - addResult(factory.createEnumDeclaration( - /*decorators*/ undefined, - factory.createModifiersFromModifierFlags(isConstEnumSymbol(symbol) ? ModifierFlags.Const : 0), - getInternalSymbolName(symbol, symbolName), - map(filter(getPropertiesOfType(getTypeOfSymbol(symbol)), p => !!(p.flags & SymbolFlags.EnumMember)), p => { + function serializeEnum(symbol: ts.Symbol, symbolName: string, modifierFlags: ts.ModifierFlags) { + addResult(ts.factory.createEnumDeclaration( + /*decorators*/ undefined, ts.factory.createModifiersFromModifierFlags(isConstEnumSymbol(symbol) ? ts.ModifierFlags.Const : 0), getInternalSymbolName(symbol, symbolName), ts.map(ts.filter(getPropertiesOfType(getTypeOfSymbol(symbol)), p => !!(p.flags & ts.SymbolFlags.EnumMember)), p => { // TODO: Handle computed names // I hate that to get the initialized value we need to walk back to the declarations here; but there's no // other way to get the possible const value of an enum member that I'm aware of, as the value is cached // _on the declaration_, not on the declaration's symbol... - const initializedValue = p.declarations && p.declarations[0] && isEnumMember(p.declarations[0]) ? getConstantValue(p.declarations[0]) : undefined; - return factory.createEnumMember(unescapeLeadingUnderscores(p.escapedName), initializedValue === undefined ? undefined : - typeof initializedValue === "string" ? factory.createStringLiteral(initializedValue) : - factory.createNumericLiteral(initializedValue)); - }) - ), modifierFlags); - } - - function serializeAsFunctionNamespaceMerge(type: Type, symbol: Symbol, localName: string, modifierFlags: ModifierFlags) { - const signatures = getSignaturesOfType(type, SignatureKind.Call); + const initializedValue = p.declarations && p.declarations[0] && ts.isEnumMember(p.declarations[0]) ? getConstantValue(p.declarations[0]) : undefined; + return ts.factory.createEnumMember(ts.unescapeLeadingUnderscores(p.escapedName), initializedValue === undefined ? undefined : + typeof initializedValue === "string" ? ts.factory.createStringLiteral(initializedValue) : + ts.factory.createNumericLiteral(initializedValue)); + })), modifierFlags); + } + function serializeAsFunctionNamespaceMerge(type: ts.Type, symbol: ts.Symbol, localName: string, modifierFlags: ts.ModifierFlags) { + const signatures = getSignaturesOfType(type, ts.SignatureKind.Call); for (const sig of signatures) { // Each overload becomes a separate function declaration, in order - const decl = signatureToSignatureDeclarationHelper(sig, SyntaxKind.FunctionDeclaration, context, { name: factory.createIdentifier(localName), privateSymbolVisitor: includePrivateSymbol, bundledImports: bundled }) as FunctionDeclaration; - addResult(setTextRange(decl, getSignatureTextRangeLocation(sig)), modifierFlags); + const decl = signatureToSignatureDeclarationHelper(sig, ts.SyntaxKind.FunctionDeclaration, context, { name: ts.factory.createIdentifier(localName), privateSymbolVisitor: includePrivateSymbol, bundledImports: bundled }) as ts.FunctionDeclaration; + addResult(ts.setTextRange(decl, getSignatureTextRangeLocation(sig)), modifierFlags); } // Module symbol emit will take care of module-y members, provided it has exports - if (!(symbol.flags & (SymbolFlags.ValueModule | SymbolFlags.NamespaceModule) && !!symbol.exports && !!symbol.exports.size)) { - const props = filter(getPropertiesOfType(type), isNamespaceMember); + if (!(symbol.flags & (ts.SymbolFlags.ValueModule | ts.SymbolFlags.NamespaceModule) && !!symbol.exports && !!symbol.exports.size)) { + const props = ts.filter(getPropertiesOfType(type), isNamespaceMember); serializeAsNamespaceDeclaration(props, localName, modifierFlags, /*suppressNewPrivateContext*/ true); } } - function getSignatureTextRangeLocation(signature: Signature) { + function getSignatureTextRangeLocation(signature: ts.Signature) { if (signature.declaration && signature.declaration.parent) { - if (isBinaryExpression(signature.declaration.parent) && getAssignmentDeclarationKind(signature.declaration.parent) === AssignmentDeclarationKind.Property) { + if (ts.isBinaryExpression(signature.declaration.parent) && ts.getAssignmentDeclarationKind(signature.declaration.parent) === ts.AssignmentDeclarationKind.Property) { return signature.declaration.parent; } // for expressions assigned to `var`s, use the `var` as the text range - if (isVariableDeclaration(signature.declaration.parent) && signature.declaration.parent.parent) { + if (ts.isVariableDeclaration(signature.declaration.parent) && signature.declaration.parent.parent) { return signature.declaration.parent.parent; } } return signature.declaration; } - function serializeAsNamespaceDeclaration(props: readonly Symbol[], localName: string, modifierFlags: ModifierFlags, suppressNewPrivateContext: boolean) { - if (length(props)) { - const localVsRemoteMap = arrayToMultiMap(props, p => - !length(p.declarations) || some(p.declarations, d => - getSourceFileOfNode(d) === getSourceFileOfNode(context.enclosingDeclaration!) - ) ? "local" : "remote" - ); - const localProps = localVsRemoteMap.get("local") || emptyArray; + function serializeAsNamespaceDeclaration(props: readonly ts.Symbol[], localName: string, modifierFlags: ts.ModifierFlags, suppressNewPrivateContext: boolean) { + if (ts.length(props)) { + const localVsRemoteMap = ts.arrayToMultiMap(props, p => !ts.length(p.declarations) || ts.some(p.declarations, d => ts.getSourceFileOfNode(d) === ts.getSourceFileOfNode(context.enclosingDeclaration!)) ? "local" : "remote"); + const localProps = localVsRemoteMap.get("local") || ts.emptyArray; // handle remote props first - we need to make an `import` declaration that points at the module containing each remote // prop in the outermost scope (TODO: a namespace within a namespace would need to be appropriately handled by this) // Example: @@ -7461,9 +7167,9 @@ namespace ts { // Add a namespace // Create namespace as non-synthetic so it is usable as an enclosing declaration - let fakespace = parseNodeFactory.createModuleDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, factory.createIdentifier(localName), factory.createModuleBlock([]), NodeFlags.Namespace); - setParent(fakespace, enclosingDeclaration as SourceFile | NamespaceDeclaration); - fakespace.locals = createSymbolTable(props); + let fakespace = ts.parseNodeFactory.createModuleDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, ts.factory.createIdentifier(localName), ts.factory.createModuleBlock([]), ts.NodeFlags.Namespace); + ts.setParent(fakespace, enclosingDeclaration as ts.SourceFile | ts.NamespaceDeclaration); + fakespace.locals = ts.createSymbolTable(props); fakespace.symbol = props[0].parent!; const oldResults = results; @@ -7474,41 +7180,34 @@ namespace ts { const oldContext = context; context = subcontext; // TODO: implement handling for the localVsRemoteMap.get("remote") - should be difficult to trigger (see comment above), as only interesting cross-file js merges should make this possible - visitSymbolTable(createSymbolTable(localProps), suppressNewPrivateContext, /*propertyAsAlias*/ true); + visitSymbolTable(ts.createSymbolTable(localProps), suppressNewPrivateContext, /*propertyAsAlias*/ true); context = oldContext; addingDeclare = oldAddingDeclare; const declarations = results; results = oldResults; // replace namespace with synthetic version - const defaultReplaced = map(declarations, d => isExportAssignment(d) && !d.isExportEquals && isIdentifier(d.expression) ? factory.createExportDeclaration( + const defaultReplaced = ts.map(declarations, d => ts.isExportAssignment(d) && !d.isExportEquals && ts.isIdentifier(d.expression) ? ts.factory.createExportDeclaration( /*decorators*/ undefined, /*modifiers*/ undefined, - /*isTypeOnly*/ false, - factory.createNamedExports([factory.createExportSpecifier(/*isTypeOnly*/ false, d.expression, factory.createIdentifier(InternalSymbolName.Default))]) - ) : d); - const exportModifierStripped = every(defaultReplaced, d => hasSyntacticModifier(d, ModifierFlags.Export)) ? map(defaultReplaced, removeExportModifier) : defaultReplaced; - fakespace = factory.updateModuleDeclaration( - fakespace, - fakespace.decorators, - fakespace.modifiers, - fakespace.name, - factory.createModuleBlock(exportModifierStripped)); + /*isTypeOnly*/ false, ts.factory.createNamedExports([ts.factory.createExportSpecifier(/*isTypeOnly*/ false, d.expression, ts.factory.createIdentifier(ts.InternalSymbolName.Default))])) : d); + const exportModifierStripped = ts.every(defaultReplaced, d => ts.hasSyntacticModifier(d, ts.ModifierFlags.Export)) ? ts.map(defaultReplaced, removeExportModifier) : defaultReplaced; + fakespace = ts.factory.updateModuleDeclaration(fakespace, fakespace.decorators, fakespace.modifiers, fakespace.name, ts.factory.createModuleBlock(exportModifierStripped)); addResult(fakespace, modifierFlags); // namespaces can never be default exported } } - function isNamespaceMember(p: Symbol) { - return !!(p.flags & (SymbolFlags.Type | SymbolFlags.Namespace | SymbolFlags.Alias)) || - !(p.flags & SymbolFlags.Prototype || p.escapedName === "prototype" || p.valueDeclaration && isStatic(p.valueDeclaration) && isClassLike(p.valueDeclaration.parent)); + function isNamespaceMember(p: ts.Symbol) { + return !!(p.flags & (ts.SymbolFlags.Type | ts.SymbolFlags.Namespace | ts.SymbolFlags.Alias)) || + !(p.flags & ts.SymbolFlags.Prototype || p.escapedName === "prototype" || p.valueDeclaration && ts.isStatic(p.valueDeclaration) && ts.isClassLike(p.valueDeclaration.parent)); } - function sanitizeJSDocImplements(clauses: readonly ExpressionWithTypeArguments[]): ExpressionWithTypeArguments[] | undefined { - const result = mapDefined(clauses, e => { + function sanitizeJSDocImplements(clauses: readonly ts.ExpressionWithTypeArguments[]): ts.ExpressionWithTypeArguments[] | undefined { + const result = ts.mapDefined(clauses, e => { const oldEnclosing = context.enclosingDeclaration; context.enclosingDeclaration = e; let expr = e.expression; - if (isEntityNameExpression(expr)) { - if (isIdentifier(expr) && idText(expr) === "") { + if (ts.isEntityNameExpression(expr)) { + if (ts.isIdentifier(expr) && ts.idText(expr) === "") { return cleanup(/*result*/ undefined); // Empty heritage clause, should be an error, but prefer emitting no heritage clauses to reemitting the empty one } let introducesError: boolean; @@ -7517,12 +7216,8 @@ namespace ts { return cleanup(/*result*/ undefined); } } - return cleanup(factory.createExpressionWithTypeArguments(expr, - map(e.typeArguments, a => - serializeExistingTypeNode(context, a, includePrivateSymbol, bundled) - || typeToTypeNodeHelper(getTypeFromTypeNode(a), context) - ) - )); + return cleanup(ts.factory.createExpressionWithTypeArguments(expr, ts.map(e.typeArguments, a => serializeExistingTypeNode(context, a, includePrivateSymbol, bundled) + || typeToTypeNodeHelper(getTypeFromTypeNode(a), context)))); function cleanup(result: T): T { context.enclosingDeclaration = oldEnclosing; @@ -7535,274 +7230,227 @@ namespace ts { return undefined; } - function serializeAsClass(symbol: Symbol, localName: string, modifierFlags: ModifierFlags) { - const originalDecl = symbol.declarations?.find(isClassLike); + function serializeAsClass(symbol: ts.Symbol, localName: string, modifierFlags: ts.ModifierFlags) { + const originalDecl = symbol.declarations?.find(ts.isClassLike); const oldEnclosing = context.enclosingDeclaration; context.enclosingDeclaration = originalDecl || oldEnclosing; const localParams = getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(symbol); - const typeParamDecls = map(localParams, p => typeParameterToDeclaration(p, context)); + const typeParamDecls = ts.map(localParams, p => typeParameterToDeclaration(p, context)); const classType = getDeclaredTypeOfClassOrInterface(symbol); const baseTypes = getBaseTypes(classType); - const originalImplements = originalDecl && getEffectiveImplementsTypeNodes(originalDecl); + const originalImplements = originalDecl && ts.getEffectiveImplementsTypeNodes(originalDecl); const implementsExpressions = originalImplements && sanitizeJSDocImplements(originalImplements) - || mapDefined(getImplementsTypes(classType), serializeImplementedType); + || ts.mapDefined(getImplementsTypes(classType), serializeImplementedType); const staticType = getTypeOfSymbol(symbol); - const isClass = !!staticType.symbol?.valueDeclaration && isClassLike(staticType.symbol.valueDeclaration); + const isClass = !!staticType.symbol?.valueDeclaration && ts.isClassLike(staticType.symbol.valueDeclaration); const staticBaseType = isClass - ? getBaseConstructorTypeOfClass(staticType as InterfaceType) + ? getBaseConstructorTypeOfClass(staticType as ts.InterfaceType) : anyType; const heritageClauses = [ - ...!length(baseTypes) ? [] : [factory.createHeritageClause(SyntaxKind.ExtendsKeyword, map(baseTypes, b => serializeBaseType(b, staticBaseType, localName)))], - ...!length(implementsExpressions) ? [] : [factory.createHeritageClause(SyntaxKind.ImplementsKeyword, implementsExpressions)] + ...!ts.length(baseTypes) ? [] : [ts.factory.createHeritageClause(ts.SyntaxKind.ExtendsKeyword, ts.map(baseTypes, b => serializeBaseType(b, staticBaseType, localName)))], + ...!ts.length(implementsExpressions) ? [] : [ts.factory.createHeritageClause(ts.SyntaxKind.ImplementsKeyword, implementsExpressions)] ]; const symbolProps = getNonInterhitedProperties(classType, baseTypes, getPropertiesOfType(classType)); - const publicSymbolProps = filter(symbolProps, s => { + const publicSymbolProps = ts.filter(symbolProps, s => { // `valueDeclaration` could be undefined if inherited from // a union/intersection base type, but inherited properties // don't matter here. const valueDecl = s.valueDeclaration; - return !!valueDecl && !(isNamedDeclaration(valueDecl) && isPrivateIdentifier(valueDecl.name)); + return !!valueDecl && !(ts.isNamedDeclaration(valueDecl) && ts.isPrivateIdentifier(valueDecl.name)); }); - const hasPrivateIdentifier = some(symbolProps, s => { + const hasPrivateIdentifier = ts.some(symbolProps, s => { // `valueDeclaration` could be undefined if inherited from // a union/intersection base type, but inherited properties // don't matter here. const valueDecl = s.valueDeclaration; - return !!valueDecl && isNamedDeclaration(valueDecl) && isPrivateIdentifier(valueDecl.name); + return !!valueDecl && ts.isNamedDeclaration(valueDecl) && ts.isPrivateIdentifier(valueDecl.name); }); // Boil down all private properties into a single one. const privateProperties = hasPrivateIdentifier ? - [factory.createPropertyDeclaration( + [ts.factory.createPropertyDeclaration( /*decorators*/ undefined, - /*modifiers*/ undefined, - factory.createPrivateIdentifier("#private"), + /*modifiers*/ undefined, ts.factory.createPrivateIdentifier("#private"), /*questionOrExclamationToken*/ undefined, /*type*/ undefined, - /*initializer*/ undefined, - )] : - emptyArray; - const publicProperties = flatMap(publicSymbolProps, p => serializePropertySymbolForClass(p, /*isStatic*/ false, baseTypes[0])); + /*initializer*/ undefined)] : ts.emptyArray; + const publicProperties = ts.flatMap(publicSymbolProps, p => serializePropertySymbolForClass(p, /*isStatic*/ false, baseTypes[0])); // Consider static members empty if symbol also has function or module meaning - function namespacey emit will handle statics - const staticMembers = flatMap( - filter(getPropertiesOfType(staticType), p => !(p.flags & SymbolFlags.Prototype) && p.escapedName !== "prototype" && !isNamespaceMember(p)), - p => serializePropertySymbolForClass(p, /*isStatic*/ true, staticBaseType)); + const staticMembers = ts.flatMap(ts.filter(getPropertiesOfType(staticType), p => !(p.flags & ts.SymbolFlags.Prototype) && p.escapedName !== "prototype" && !isNamespaceMember(p)), p => serializePropertySymbolForClass(p, /*isStatic*/ true, staticBaseType)); // When we encounter an `X.prototype.y` assignment in a JS file, we bind `X` as a class regardless as to whether // the value is ever initialized with a class or function-like value. For cases where `X` could never be // created via `new`, we will inject a `private constructor()` declaration to indicate it is not createable. - const isNonConstructableClassLikeInJsFile = - !isClass && + const isNonConstructableClassLikeInJsFile = !isClass && !!symbol.valueDeclaration && - isInJSFile(symbol.valueDeclaration) && - !some(getSignaturesOfType(staticType, SignatureKind.Construct)); + ts.isInJSFile(symbol.valueDeclaration) && + !ts.some(getSignaturesOfType(staticType, ts.SignatureKind.Construct)); const constructors = isNonConstructableClassLikeInJsFile ? - [factory.createConstructorDeclaration(/*decorators*/ undefined, factory.createModifiersFromModifierFlags(ModifierFlags.Private), [], /*body*/ undefined)] : - serializeSignatures(SignatureKind.Construct, staticType, staticBaseType, SyntaxKind.Constructor) as ConstructorDeclaration[]; + [ts.factory.createConstructorDeclaration(/*decorators*/ undefined, ts.factory.createModifiersFromModifierFlags(ts.ModifierFlags.Private), [], /*body*/ undefined)] : + serializeSignatures(ts.SignatureKind.Construct, staticType, staticBaseType, ts.SyntaxKind.Constructor) as ts.ConstructorDeclaration[]; const indexSignatures = serializeIndexSignatures(classType, baseTypes[0]); context.enclosingDeclaration = oldEnclosing; - addResult(setTextRange(factory.createClassDeclaration( + addResult(ts.setTextRange(ts.factory.createClassDeclaration( /*decorators*/ undefined, - /*modifiers*/ undefined, - localName, - typeParamDecls, - heritageClauses, - [...indexSignatures, ...staticMembers, ...constructors, ...publicProperties, ...privateProperties] - ), symbol.declarations && filter(symbol.declarations, d => isClassDeclaration(d) || isClassExpression(d))[0]), modifierFlags); + /*modifiers*/ undefined, localName, typeParamDecls, heritageClauses, [...indexSignatures, ...staticMembers, ...constructors, ...publicProperties, ...privateProperties]), symbol.declarations && ts.filter(symbol.declarations, d => ts.isClassDeclaration(d) || ts.isClassExpression(d))[0]), modifierFlags); } - function getSomeTargetNameFromDeclarations(declarations: Declaration[] | undefined) { - return firstDefined(declarations, d => { - if (isImportSpecifier(d) || isExportSpecifier(d)) { - return idText(d.propertyName || d.name); + function getSomeTargetNameFromDeclarations(declarations: ts.Declaration[] | undefined) { + return ts.firstDefined(declarations, d => { + if (ts.isImportSpecifier(d) || ts.isExportSpecifier(d)) { + return ts.idText(d.propertyName || d.name); } - if (isBinaryExpression(d) || isExportAssignment(d)) { - const expression = isExportAssignment(d) ? d.expression : d.right; - if (isPropertyAccessExpression(expression)) { - return idText(expression.name); + if (ts.isBinaryExpression(d) || ts.isExportAssignment(d)) { + const expression = ts.isExportAssignment(d) ? d.expression : d.right; + if (ts.isPropertyAccessExpression(expression)) { + return ts.idText(expression.name); } } if (isAliasSymbolDeclaration(d)) { // This is... heuristic, at best. But it's probably better than always printing the name of the shorthand ambient module. - const name = getNameOfDeclaration(d); - if (name && isIdentifier(name)) { - return idText(name); + const name = ts.getNameOfDeclaration(d); + if (name && ts.isIdentifier(name)) { + return ts.idText(name); } } return undefined; }); } - function serializeAsAlias(symbol: Symbol, localName: string, modifierFlags: ModifierFlags) { + function serializeAsAlias(symbol: ts.Symbol, localName: string, modifierFlags: ts.ModifierFlags) { // synthesize an alias, eg `export { symbolName as Name }` // need to mark the alias `symbol` points at // as something we need to serialize as a private declaration as well const node = getDeclarationOfAliasSymbol(symbol); - if (!node) return Debug.fail(); + if (!node) + return ts.Debug.fail(); const target = getMergedSymbol(getTargetOfAliasDeclaration(node, /*dontRecursivelyResolve*/ true)); if (!target) { return; } // If `target` refers to a shorthand module symbol, the name we're trying to pull out isn;t recoverable from the target symbol // In such a scenario, we must fall back to looking for an alias declaration on `symbol` and pulling the target name from that - let verbatimTargetName = isShorthandAmbientModuleSymbol(target) && getSomeTargetNameFromDeclarations(symbol.declarations) || unescapeLeadingUnderscores(target.escapedName); - if (verbatimTargetName === InternalSymbolName.ExportEquals && (getESModuleInterop(compilerOptions) || compilerOptions.allowSyntheticDefaultImports)) { + let verbatimTargetName = ts.isShorthandAmbientModuleSymbol(target) && getSomeTargetNameFromDeclarations(symbol.declarations) || ts.unescapeLeadingUnderscores(target.escapedName); + if (verbatimTargetName === ts.InternalSymbolName.ExportEquals && (ts.getESModuleInterop(compilerOptions) || compilerOptions.allowSyntheticDefaultImports)) { // target refers to an `export=` symbol that was hoisted into a synthetic default - rename here to match - verbatimTargetName = InternalSymbolName.Default; + verbatimTargetName = ts.InternalSymbolName.Default; } const targetName = getInternalSymbolName(target, verbatimTargetName); includePrivateSymbol(target); // the target may be within the same scope - attempt to serialize it first switch (node.kind) { - case SyntaxKind.BindingElement: - if (node.parent?.parent?.kind === SyntaxKind.VariableDeclaration) { + case ts.SyntaxKind.BindingElement: + if (node.parent?.parent?.kind === ts.SyntaxKind.VariableDeclaration) { // const { SomeClass } = require('./lib'); const specifier = getSpecifierForModuleSymbol(target.parent || target, context); // './lib' - const { propertyName } = node as BindingElement; - addResult(factory.createImportDeclaration( + const { propertyName } = node as ts.BindingElement; + addResult(ts.factory.createImportDeclaration( /*decorators*/ undefined, - /*modifiers*/ undefined, - factory.createImportClause(/*isTypeOnly*/ false, /*name*/ undefined, factory.createNamedImports([factory.createImportSpecifier( - /*isTypeOnly*/ false, - propertyName && isIdentifier(propertyName) ? factory.createIdentifier(idText(propertyName)) : undefined, - factory.createIdentifier(localName) - )])), - factory.createStringLiteral(specifier), - /*importClause*/ undefined - ), ModifierFlags.None); + /*modifiers*/ undefined, ts.factory.createImportClause(/*isTypeOnly*/ false, /*name*/ undefined, ts.factory.createNamedImports([ts.factory.createImportSpecifier( + /*isTypeOnly*/ false, propertyName && ts.isIdentifier(propertyName) ? ts.factory.createIdentifier(ts.idText(propertyName)) : undefined, ts.factory.createIdentifier(localName))])), ts.factory.createStringLiteral(specifier), + /*importClause*/ undefined), ts.ModifierFlags.None); break; } // We don't know how to serialize this (nested?) binding element - Debug.failBadSyntaxKind(node.parent?.parent || node, "Unhandled binding element grandparent kind in declaration serialization"); + ts.Debug.failBadSyntaxKind(node.parent?.parent || node, "Unhandled binding element grandparent kind in declaration serialization"); break; - case SyntaxKind.ShorthandPropertyAssignment: - if (node.parent?.parent?.kind === SyntaxKind.BinaryExpression) { + case ts.SyntaxKind.ShorthandPropertyAssignment: + if (node.parent?.parent?.kind === ts.SyntaxKind.BinaryExpression) { // module.exports = { SomeClass } - serializeExportSpecifier( - unescapeLeadingUnderscores(symbol.escapedName), - targetName - ); + serializeExportSpecifier(ts.unescapeLeadingUnderscores(symbol.escapedName), targetName); } break; - case SyntaxKind.VariableDeclaration: + case ts.SyntaxKind.VariableDeclaration: // commonjs require: const x = require('y') - if (isPropertyAccessExpression((node as VariableDeclaration).initializer!)) { + if (ts.isPropertyAccessExpression((node as ts.VariableDeclaration).initializer!)) { // const x = require('y').z - const initializer = (node as VariableDeclaration).initializer! as PropertyAccessExpression; // require('y').z - const uniqueName = factory.createUniqueName(localName); // _x + const initializer = (node as ts.VariableDeclaration).initializer! as ts.PropertyAccessExpression; // require('y').z + const uniqueName = ts.factory.createUniqueName(localName); // _x const specifier = getSpecifierForModuleSymbol(target.parent || target, context); // 'y' // import _x = require('y'); - addResult(factory.createImportEqualsDeclaration( + addResult(ts.factory.createImportEqualsDeclaration( /*decorators*/ undefined, /*modifiers*/ undefined, - /*isTypeOnly*/ false, - uniqueName, - factory.createExternalModuleReference(factory.createStringLiteral(specifier)) - ), ModifierFlags.None); + /*isTypeOnly*/ false, uniqueName, ts.factory.createExternalModuleReference(ts.factory.createStringLiteral(specifier))), ts.ModifierFlags.None); // import x = _x.z - addResult(factory.createImportEqualsDeclaration( + addResult(ts.factory.createImportEqualsDeclaration( /*decorators*/ undefined, /*modifiers*/ undefined, - /*isTypeOnly*/ false, - factory.createIdentifier(localName), - factory.createQualifiedName(uniqueName, initializer.name as Identifier), - ), modifierFlags); + /*isTypeOnly*/ false, ts.factory.createIdentifier(localName), ts.factory.createQualifiedName(uniqueName, initializer.name as ts.Identifier)), modifierFlags); break; } // else fall through and treat commonjs require just like import= - case SyntaxKind.ImportEqualsDeclaration: + case ts.SyntaxKind.ImportEqualsDeclaration: // This _specifically_ only exists to handle json declarations - where we make aliases, but since // we emit no declarations for the json document, must not refer to it in the declarations - if (target.escapedName === InternalSymbolName.ExportEquals && some(target.declarations, isJsonSourceFile)) { + if (target.escapedName === ts.InternalSymbolName.ExportEquals && ts.some(target.declarations, ts.isJsonSourceFile)) { serializeMaybeAliasAssignment(symbol); break; } // Could be a local `import localName = ns.member` or // an external `import localName = require("whatever")` - const isLocalImport = !(target.flags & SymbolFlags.ValueModule) && !isVariableDeclaration(node); - addResult(factory.createImportEqualsDeclaration( + const isLocalImport = !(target.flags & ts.SymbolFlags.ValueModule) && !ts.isVariableDeclaration(node); + addResult(ts.factory.createImportEqualsDeclaration( /*decorators*/ undefined, /*modifiers*/ undefined, - /*isTypeOnly*/ false, - factory.createIdentifier(localName), - isLocalImport - ? symbolToName(target, context, SymbolFlags.All, /*expectsIdentifier*/ false) - : factory.createExternalModuleReference(factory.createStringLiteral(getSpecifierForModuleSymbol(target, context))) - ), isLocalImport ? modifierFlags : ModifierFlags.None); + /*isTypeOnly*/ false, ts.factory.createIdentifier(localName), isLocalImport + ? symbolToName(target, context, ts.SymbolFlags.All, /*expectsIdentifier*/ false) + : ts.factory.createExternalModuleReference(ts.factory.createStringLiteral(getSpecifierForModuleSymbol(target, context)))), isLocalImport ? modifierFlags : ts.ModifierFlags.None); break; - case SyntaxKind.NamespaceExportDeclaration: + case ts.SyntaxKind.NamespaceExportDeclaration: // export as namespace foo // TODO: Not part of a file's local or export symbol tables // Is bound into file.symbol.globalExports instead, which we don't currently traverse - addResult(factory.createNamespaceExportDeclaration(idText((node as NamespaceExportDeclaration).name)), ModifierFlags.None); + addResult(ts.factory.createNamespaceExportDeclaration(ts.idText((node as ts.NamespaceExportDeclaration).name)), ts.ModifierFlags.None); break; - case SyntaxKind.ImportClause: - addResult(factory.createImportDeclaration( + case ts.SyntaxKind.ImportClause: + addResult(ts.factory.createImportDeclaration( /*decorators*/ undefined, - /*modifiers*/ undefined, - factory.createImportClause(/*isTypeOnly*/ false, factory.createIdentifier(localName), /*namedBindings*/ undefined), + /*modifiers*/ undefined, ts.factory.createImportClause(/*isTypeOnly*/ false, ts.factory.createIdentifier(localName), /*namedBindings*/ undefined), // We use `target.parent || target` below as `target.parent` is unset when the target is a module which has been export assigned // And then made into a default by the `esModuleInterop` or `allowSyntheticDefaultImports` flag // In such cases, the `target` refers to the module itself already - factory.createStringLiteral(getSpecifierForModuleSymbol(target.parent || target, context)), - /*assertClause*/ undefined - ), ModifierFlags.None); + ts.factory.createStringLiteral(getSpecifierForModuleSymbol(target.parent || target, context)), + /*assertClause*/ undefined), ts.ModifierFlags.None); break; - case SyntaxKind.NamespaceImport: - addResult(factory.createImportDeclaration( + case ts.SyntaxKind.NamespaceImport: + addResult(ts.factory.createImportDeclaration( /*decorators*/ undefined, - /*modifiers*/ undefined, - factory.createImportClause(/*isTypeOnly*/ false, /*importClause*/ undefined, factory.createNamespaceImport(factory.createIdentifier(localName))), - factory.createStringLiteral(getSpecifierForModuleSymbol(target, context)), - /*assertClause*/ undefined - ), ModifierFlags.None); + /*modifiers*/ undefined, ts.factory.createImportClause(/*isTypeOnly*/ false, /*importClause*/ undefined, ts.factory.createNamespaceImport(ts.factory.createIdentifier(localName))), ts.factory.createStringLiteral(getSpecifierForModuleSymbol(target, context)), + /*assertClause*/ undefined), ts.ModifierFlags.None); break; - case SyntaxKind.NamespaceExport: - addResult(factory.createExportDeclaration( + case ts.SyntaxKind.NamespaceExport: + addResult(ts.factory.createExportDeclaration( /*decorators*/ undefined, /*modifiers*/ undefined, - /*isTypeOnly*/ false, - factory.createNamespaceExport(factory.createIdentifier(localName)), - factory.createStringLiteral(getSpecifierForModuleSymbol(target, context)) - ), ModifierFlags.None); + /*isTypeOnly*/ false, ts.factory.createNamespaceExport(ts.factory.createIdentifier(localName)), ts.factory.createStringLiteral(getSpecifierForModuleSymbol(target, context))), ts.ModifierFlags.None); break; - case SyntaxKind.ImportSpecifier: - addResult(factory.createImportDeclaration( + case ts.SyntaxKind.ImportSpecifier: + addResult(ts.factory.createImportDeclaration( /*decorators*/ undefined, - /*modifiers*/ undefined, - factory.createImportClause( - /*isTypeOnly*/ false, - /*importClause*/ undefined, - factory.createNamedImports([ - factory.createImportSpecifier( + /*modifiers*/ undefined, ts.factory.createImportClause( /*isTypeOnly*/ false, - localName !== verbatimTargetName ? factory.createIdentifier(verbatimTargetName) : undefined, - factory.createIdentifier(localName) - ) - ])), - factory.createStringLiteral(getSpecifierForModuleSymbol(target.parent || target, context)), - /*assertClause*/ undefined - ), ModifierFlags.None); + /*importClause*/ undefined, ts.factory.createNamedImports([ + ts.factory.createImportSpecifier( + /*isTypeOnly*/ false, localName !== verbatimTargetName ? ts.factory.createIdentifier(verbatimTargetName) : undefined, ts.factory.createIdentifier(localName)) + ])), ts.factory.createStringLiteral(getSpecifierForModuleSymbol(target.parent || target, context)), + /*assertClause*/ undefined), ts.ModifierFlags.None); break; - case SyntaxKind.ExportSpecifier: + case ts.SyntaxKind.ExportSpecifier: // does not use localName because the symbol name in this case refers to the name in the exports table, // which we must exactly preserve - const specifier = (node.parent.parent as ExportDeclaration).moduleSpecifier; + const specifier = (node.parent.parent as ts.ExportDeclaration).moduleSpecifier; // targetName is only used when the target is local, as otherwise the target is an alias that points at // another file - serializeExportSpecifier( - unescapeLeadingUnderscores(symbol.escapedName), - specifier ? verbatimTargetName : targetName, - specifier && isStringLiteralLike(specifier) ? factory.createStringLiteral(specifier.text) : undefined - ); + serializeExportSpecifier(ts.unescapeLeadingUnderscores(symbol.escapedName), specifier ? verbatimTargetName : targetName, specifier && ts.isStringLiteralLike(specifier) ? ts.factory.createStringLiteral(specifier.text) : undefined); break; - case SyntaxKind.ExportAssignment: + case ts.SyntaxKind.ExportAssignment: serializeMaybeAliasAssignment(symbol); break; - case SyntaxKind.BinaryExpression: - case SyntaxKind.PropertyAccessExpression: - case SyntaxKind.ElementAccessExpression: + case ts.SyntaxKind.BinaryExpression: + case ts.SyntaxKind.PropertyAccessExpression: + case ts.SyntaxKind.ElementAccessExpression: // Could be best encoded as though an export specifier or as though an export assignment // If name is default or export=, do an export assignment // Otherwise do an export specifier - if (symbol.escapedName === InternalSymbolName.Default || symbol.escapedName === InternalSymbolName.ExportEquals) { + if (symbol.escapedName === ts.InternalSymbolName.Default || symbol.escapedName === ts.InternalSymbolName.ExportEquals) { serializeMaybeAliasAssignment(symbol); } else { @@ -7810,30 +7458,27 @@ namespace ts { } break; default: - return Debug.failBadSyntaxKind(node, "Unhandled alias declaration kind in symbol serializer!"); + return ts.Debug.failBadSyntaxKind(node, "Unhandled alias declaration kind in symbol serializer!"); } } - function serializeExportSpecifier(localName: string, targetName: string, specifier?: Expression) { - addResult(factory.createExportDeclaration( + function serializeExportSpecifier(localName: string, targetName: string, specifier?: ts.Expression) { + addResult(ts.factory.createExportDeclaration( /*decorators*/ undefined, /*modifiers*/ undefined, - /*isTypeOnly*/ false, - factory.createNamedExports([factory.createExportSpecifier(/*isTypeOnly*/ false, localName !== targetName ? targetName : undefined, localName)]), - specifier - ), ModifierFlags.None); + /*isTypeOnly*/ false, ts.factory.createNamedExports([ts.factory.createExportSpecifier(/*isTypeOnly*/ false, localName !== targetName ? targetName : undefined, localName)]), specifier), ts.ModifierFlags.None); } /** * Returns `true` if an export assignment or declaration was produced for the symbol */ - function serializeMaybeAliasAssignment(symbol: Symbol): boolean { - if (symbol.flags & SymbolFlags.Prototype) { + function serializeMaybeAliasAssignment(symbol: ts.Symbol): boolean { + if (symbol.flags & ts.SymbolFlags.Prototype) { return false; } - const name = unescapeLeadingUnderscores(symbol.escapedName); - const isExportEquals = name === InternalSymbolName.ExportEquals; - const isDefault = name === InternalSymbolName.Default; + const name = ts.unescapeLeadingUnderscores(symbol.escapedName); + const isExportEquals = name === ts.InternalSymbolName.ExportEquals; + const isDefault = name === ts.InternalSymbolName.Default; const isExportAssignmentCompatibleSymbolName = isExportEquals || isDefault; // synthesize export = ref // ref should refer to either be a locally scoped symbol which we need to emit, or @@ -7842,13 +7487,13 @@ namespace ts { // serialize what the alias points to, preserve the declaration's initializer const target = aliasDecl && getTargetOfAliasDeclaration(aliasDecl, /*dontRecursivelyResolve*/ true); // If the target resolves and resolves to a thing defined in this file, emit as an alias, otherwise emit as a const - if (target && length(target.declarations) && some(target.declarations, d => getSourceFileOfNode(d) === getSourceFileOfNode(enclosingDeclaration))) { + if (target && ts.length(target.declarations) && ts.some(target.declarations, d => ts.getSourceFileOfNode(d) === ts.getSourceFileOfNode(enclosingDeclaration))) { // In case `target` refers to a namespace member, look at the declaration and serialize the leftmost symbol in it // eg, `namespace A { export class B {} }; exports = A.B;` // Technically, this is all that's required in the case where the assignment is an entity name expression - const expr = aliasDecl && ((isExportAssignment(aliasDecl) || isBinaryExpression(aliasDecl)) ? getExportAssignmentExpression(aliasDecl) : getPropertyAssignmentAliasLikeExpression(aliasDecl as ShorthandPropertyAssignment | PropertyAssignment | PropertyAccessExpression)); - const first = expr && isEntityNameExpression(expr) ? getFirstNonModuleExportsIdentifier(expr) : undefined; - const referenced = first && resolveEntityName(first, SymbolFlags.All, /*ignoreErrors*/ true, /*dontResolveAlias*/ true, enclosingDeclaration); + const expr = aliasDecl && ((ts.isExportAssignment(aliasDecl) || ts.isBinaryExpression(aliasDecl)) ? ts.getExportAssignmentExpression(aliasDecl) : ts.getPropertyAssignmentAliasLikeExpression(aliasDecl as ts.ShorthandPropertyAssignment | ts.PropertyAssignment | ts.PropertyAccessExpression)); + const first = expr && ts.isEntityNameExpression(expr) ? getFirstNonModuleExportsIdentifier(expr) : undefined; + const referenced = first && resolveEntityName(first, ts.SymbolFlags.All, /*ignoreErrors*/ true, /*dontResolveAlias*/ true, enclosingDeclaration); if (referenced || target) { includePrivateSymbol(referenced || target); } @@ -7861,31 +7506,25 @@ namespace ts { const oldTrack = context.tracker.trackSymbol; context.tracker.trackSymbol = () => false; if (isExportAssignmentCompatibleSymbolName) { - results.push(factory.createExportAssignment( + results.push(ts.factory.createExportAssignment( /*decorators*/ undefined, - /*modifiers*/ undefined, - isExportEquals, - symbolToExpression(target, context, SymbolFlags.All) - )); + /*modifiers*/ undefined, isExportEquals, symbolToExpression(target, context, ts.SymbolFlags.All))); } else { if (first === expr && first) { // serialize as `export {target as name}` - serializeExportSpecifier(name, idText(first)); + serializeExportSpecifier(name, ts.idText(first)); } - else if (expr && isClassExpression(expr)) { - serializeExportSpecifier(name, getInternalSymbolName(target, symbolName(target))); + else if (expr && ts.isClassExpression(expr)) { + serializeExportSpecifier(name, getInternalSymbolName(target, ts.symbolName(target))); } else { // serialize as `import _Ref = t.arg.et; export { _Ref as name }` const varName = getUnusedName(name, symbol); - addResult(factory.createImportEqualsDeclaration( + addResult(ts.factory.createImportEqualsDeclaration( /*decorators*/ undefined, /*modifiers*/ undefined, - /*isTypeOnly*/ false, - factory.createIdentifier(varName), - symbolToName(target, context, SymbolFlags.All, /*expectsIdentifier*/ false) - ), ModifierFlags.None); + /*isTypeOnly*/ false, ts.factory.createIdentifier(varName), symbolToName(target, context, ts.SymbolFlags.All, /*expectsIdentifier*/ false)), ts.ModifierFlags.None); serializeExportSpecifier(name, varName); } } @@ -7900,26 +7539,22 @@ namespace ts { const typeToSerialize = getWidenedType(getTypeOfSymbol(getMergedSymbol(symbol))); if (isTypeRepresentableAsFunctionNamespaceMerge(typeToSerialize, symbol)) { // If there are no index signatures and `typeToSerialize` is an object type, emit as a namespace instead of a const - serializeAsFunctionNamespaceMerge(typeToSerialize, symbol, varName, isExportAssignmentCompatibleSymbolName ? ModifierFlags.None : ModifierFlags.Export); + serializeAsFunctionNamespaceMerge(typeToSerialize, symbol, varName, isExportAssignmentCompatibleSymbolName ? ts.ModifierFlags.None : ts.ModifierFlags.Export); } else { - const statement = factory.createVariableStatement(/*modifiers*/ undefined, factory.createVariableDeclarationList([ - factory.createVariableDeclaration(varName, /*exclamationToken*/ undefined, serializeTypeForDeclaration(context, typeToSerialize, symbol, enclosingDeclaration, includePrivateSymbol, bundled)) - ], NodeFlags.Const)); + const statement = ts.factory.createVariableStatement(/*modifiers*/ undefined, ts.factory.createVariableDeclarationList([ + ts.factory.createVariableDeclaration(varName, /*exclamationToken*/ undefined, serializeTypeForDeclaration(context, typeToSerialize, symbol, enclosingDeclaration, includePrivateSymbol, bundled)) + ], ts.NodeFlags.Const)); // Inlined JSON types exported with [module.]exports= will already emit an export=, so should use `declare`. // Otherwise, the type itself should be exported. - addResult(statement, - target && target.flags & SymbolFlags.Property && target.escapedName === InternalSymbolName.ExportEquals ? ModifierFlags.Ambient - : name === varName ? ModifierFlags.Export - : ModifierFlags.None); + addResult(statement, target && target.flags & ts.SymbolFlags.Property && target.escapedName === ts.InternalSymbolName.ExportEquals ? ts.ModifierFlags.Ambient + : name === varName ? ts.ModifierFlags.Export + : ts.ModifierFlags.None); } if (isExportAssignmentCompatibleSymbolName) { - results.push(factory.createExportAssignment( + results.push(ts.factory.createExportAssignment( /*decorators*/ undefined, - /*modifiers*/ undefined, - isExportEquals, - factory.createIdentifier(varName) - )); + /*modifiers*/ undefined, isExportEquals, ts.factory.createIdentifier(varName))); return true; } else if (name !== varName) { @@ -7930,161 +7565,113 @@ namespace ts { } } - function isTypeRepresentableAsFunctionNamespaceMerge(typeToSerialize: Type, hostSymbol: Symbol) { + function isTypeRepresentableAsFunctionNamespaceMerge(typeToSerialize: ts.Type, hostSymbol: ts.Symbol) { // Only object types which are not constructable, or indexable, whose members all come from the // context source file, and whose property names are all valid identifiers and not late-bound, _and_ // whose input is not type annotated (if the input symbol has an annotation we can reuse, we should prefer it) - const ctxSrc = getSourceFileOfNode(context.enclosingDeclaration); - return getObjectFlags(typeToSerialize) & (ObjectFlags.Anonymous | ObjectFlags.Mapped) && - !length(getIndexInfosOfType(typeToSerialize)) && + const ctxSrc = ts.getSourceFileOfNode(context.enclosingDeclaration); + return ts.getObjectFlags(typeToSerialize) & (ts.ObjectFlags.Anonymous | ts.ObjectFlags.Mapped) && + !ts.length(getIndexInfosOfType(typeToSerialize)) && !isClassInstanceSide(typeToSerialize) && // While a class instance is potentially representable as a NS, prefer printing a reference to the instance type and serializing the class - !!(length(filter(getPropertiesOfType(typeToSerialize), isNamespaceMember)) || length(getSignaturesOfType(typeToSerialize, SignatureKind.Call))) && - !length(getSignaturesOfType(typeToSerialize, SignatureKind.Construct)) && // TODO: could probably serialize as function + ns + class, now that that's OK + !!(ts.length(ts.filter(getPropertiesOfType(typeToSerialize), isNamespaceMember)) || ts.length(getSignaturesOfType(typeToSerialize, ts.SignatureKind.Call))) && + !ts.length(getSignaturesOfType(typeToSerialize, ts.SignatureKind.Construct)) && // TODO: could probably serialize as function + ns + class, now that that's OK !getDeclarationWithTypeAnnotation(hostSymbol, enclosingDeclaration) && - !(typeToSerialize.symbol && some(typeToSerialize.symbol.declarations, d => getSourceFileOfNode(d) !== ctxSrc)) && - !some(getPropertiesOfType(typeToSerialize), p => isLateBoundName(p.escapedName)) && - !some(getPropertiesOfType(typeToSerialize), p => some(p.declarations, d => getSourceFileOfNode(d) !== ctxSrc)) && - every(getPropertiesOfType(typeToSerialize), p => isIdentifierText(symbolName(p), languageVersion)); - } - - function makeSerializePropertySymbol(createProperty: ( - decorators: readonly Decorator[] | undefined, - modifiers: readonly Modifier[] | undefined, - name: string | PropertyName, - questionOrExclamationToken: QuestionToken | undefined, - type: TypeNode | undefined, - initializer: Expression | undefined - ) => T, methodKind: SignatureDeclaration["kind"], useAccessors: true): (p: Symbol, isStatic: boolean, baseType: Type | undefined) => (T | AccessorDeclaration | (T | AccessorDeclaration)[]); - function makeSerializePropertySymbol(createProperty: ( - decorators: readonly Decorator[] | undefined, - modifiers: readonly Modifier[] | undefined, - name: string | PropertyName, - questionOrExclamationToken: QuestionToken | undefined, - type: TypeNode | undefined, - initializer: Expression | undefined - ) => T, methodKind: SignatureDeclaration["kind"], useAccessors: false): (p: Symbol, isStatic: boolean, baseType: Type | undefined) => (T | T[]); - function makeSerializePropertySymbol(createProperty: ( - decorators: readonly Decorator[] | undefined, - modifiers: readonly Modifier[] | undefined, - name: string | PropertyName, - questionOrExclamationToken: QuestionToken | undefined, - type: TypeNode | undefined, - initializer: Expression | undefined - ) => T, methodKind: SignatureDeclaration["kind"], useAccessors: boolean): (p: Symbol, isStatic: boolean, baseType: Type | undefined) => (T | AccessorDeclaration | (T | AccessorDeclaration)[]) { - return function serializePropertySymbol(p: Symbol, isStatic: boolean, baseType: Type | undefined): (T | AccessorDeclaration | (T | AccessorDeclaration)[]) { - const modifierFlags = getDeclarationModifierFlagsFromSymbol(p); - const isPrivate = !!(modifierFlags & ModifierFlags.Private); - if (isStatic && (p.flags & (SymbolFlags.Type | SymbolFlags.Namespace | SymbolFlags.Alias))) { + !(typeToSerialize.symbol && ts.some(typeToSerialize.symbol.declarations, d => ts.getSourceFileOfNode(d) !== ctxSrc)) && + !ts.some(getPropertiesOfType(typeToSerialize), p => isLateBoundName(p.escapedName)) && + !ts.some(getPropertiesOfType(typeToSerialize), p => ts.some(p.declarations, d => ts.getSourceFileOfNode(d) !== ctxSrc)) && + ts.every(getPropertiesOfType(typeToSerialize), p => ts.isIdentifierText(ts.symbolName(p), languageVersion)); + } + function makeSerializePropertySymbol(createProperty: (decorators: readonly ts.Decorator[] | undefined, modifiers: readonly ts.Modifier[] | undefined, name: string | ts.PropertyName, questionOrExclamationToken: ts.QuestionToken | undefined, type: ts.TypeNode | undefined, initializer: ts.Expression | undefined) => T, methodKind: ts.SignatureDeclaration["kind"], useAccessors: true): (p: ts.Symbol, isStatic: boolean, baseType: ts.Type | undefined) => (T | ts.AccessorDeclaration | (T | ts.AccessorDeclaration)[]); + function makeSerializePropertySymbol(createProperty: (decorators: readonly ts.Decorator[] | undefined, modifiers: readonly ts.Modifier[] | undefined, name: string | ts.PropertyName, questionOrExclamationToken: ts.QuestionToken | undefined, type: ts.TypeNode | undefined, initializer: ts.Expression | undefined) => T, methodKind: ts.SignatureDeclaration["kind"], useAccessors: false): (p: ts.Symbol, isStatic: boolean, baseType: ts.Type | undefined) => (T | T[]); + function makeSerializePropertySymbol(createProperty: (decorators: readonly ts.Decorator[] | undefined, modifiers: readonly ts.Modifier[] | undefined, name: string | ts.PropertyName, questionOrExclamationToken: ts.QuestionToken | undefined, type: ts.TypeNode | undefined, initializer: ts.Expression | undefined) => T, methodKind: ts.SignatureDeclaration["kind"], useAccessors: boolean): (p: ts.Symbol, isStatic: boolean, baseType: ts.Type | undefined) => (T | ts.AccessorDeclaration | (T | ts.AccessorDeclaration)[]) { + return function serializePropertySymbol(p: ts.Symbol, isStatic: boolean, baseType: ts.Type | undefined): (T | ts.AccessorDeclaration | (T | ts.AccessorDeclaration)[]) { + const modifierFlags = ts.getDeclarationModifierFlagsFromSymbol(p); + const isPrivate = !!(modifierFlags & ts.ModifierFlags.Private); + if (isStatic && (p.flags & (ts.SymbolFlags.Type | ts.SymbolFlags.Namespace | ts.SymbolFlags.Alias))) { // Only value-only-meaning symbols can be correctly encoded as class statics, type/namespace/alias meaning symbols // need to be merged namespace members return []; } - if (p.flags & SymbolFlags.Prototype || + if (p.flags & ts.SymbolFlags.Prototype || (baseType && getPropertyOfType(baseType, p.escapedName) && isReadonlySymbol(getPropertyOfType(baseType, p.escapedName)!) === isReadonlySymbol(p) - && (p.flags & SymbolFlags.Optional) === (getPropertyOfType(baseType, p.escapedName)!.flags & SymbolFlags.Optional) + && (p.flags & ts.SymbolFlags.Optional) === (getPropertyOfType(baseType, p.escapedName)!.flags & ts.SymbolFlags.Optional) && isTypeIdenticalTo(getTypeOfSymbol(p), getTypeOfPropertyOfType(baseType, p.escapedName)!))) { return []; } - const flag = (modifierFlags & ~ModifierFlags.Async) | (isStatic ? ModifierFlags.Static : 0); + const flag = (modifierFlags & ~ts.ModifierFlags.Async) | (isStatic ? ts.ModifierFlags.Static : 0); const name = getPropertyNameNodeForSymbol(p, context); - const firstPropertyLikeDecl = p.declarations?.find(or(isPropertyDeclaration, isAccessor, isVariableDeclaration, isPropertySignature, isBinaryExpression, isPropertyAccessExpression)); - if (p.flags & SymbolFlags.Accessor && useAccessors) { - const result: AccessorDeclaration[] = []; - if (p.flags & SymbolFlags.SetAccessor) { - result.push(setTextRange(factory.createSetAccessorDeclaration( - /*decorators*/ undefined, - factory.createModifiersFromModifierFlags(flag), - name, - [factory.createParameterDeclaration( + const firstPropertyLikeDecl = p.declarations?.find(ts.or(ts.isPropertyDeclaration, ts.isAccessor, ts.isVariableDeclaration, ts.isPropertySignature, ts.isBinaryExpression, ts.isPropertyAccessExpression)); + if (p.flags & ts.SymbolFlags.Accessor && useAccessors) { + const result: ts.AccessorDeclaration[] = []; + if (p.flags & ts.SymbolFlags.SetAccessor) { + result.push(ts.setTextRange(ts.factory.createSetAccessorDeclaration( + /*decorators*/ undefined, ts.factory.createModifiersFromModifierFlags(flag), name, [ts.factory.createParameterDeclaration( /*decorators*/ undefined, /*modifiers*/ undefined, - /*dotDotDotToken*/ undefined, - "arg", - /*questionToken*/ undefined, - isPrivate ? undefined : serializeTypeForDeclaration(context, getTypeOfSymbol(p), p, enclosingDeclaration, includePrivateSymbol, bundled) - )], - /*body*/ undefined - ), p.declarations?.find(isSetAccessor) || firstPropertyLikeDecl)); - } - if (p.flags & SymbolFlags.GetAccessor) { - const isPrivate = modifierFlags & ModifierFlags.Private; - result.push(setTextRange(factory.createGetAccessorDeclaration( - /*decorators*/ undefined, - factory.createModifiersFromModifierFlags(flag), - name, - [], - isPrivate ? undefined : serializeTypeForDeclaration(context, getTypeOfSymbol(p), p, enclosingDeclaration, includePrivateSymbol, bundled), - /*body*/ undefined - ), p.declarations?.find(isGetAccessor) || firstPropertyLikeDecl)); + /*dotDotDotToken*/ undefined, "arg", + /*questionToken*/ undefined, isPrivate ? undefined : serializeTypeForDeclaration(context, getTypeOfSymbol(p), p, enclosingDeclaration, includePrivateSymbol, bundled))], + /*body*/ undefined), p.declarations?.find(ts.isSetAccessor) || firstPropertyLikeDecl)); + } + if (p.flags & ts.SymbolFlags.GetAccessor) { + const isPrivate = modifierFlags & ts.ModifierFlags.Private; + result.push(ts.setTextRange(ts.factory.createGetAccessorDeclaration( + /*decorators*/ undefined, ts.factory.createModifiersFromModifierFlags(flag), name, [], isPrivate ? undefined : serializeTypeForDeclaration(context, getTypeOfSymbol(p), p, enclosingDeclaration, includePrivateSymbol, bundled), + /*body*/ undefined), p.declarations?.find(ts.isGetAccessor) || firstPropertyLikeDecl)); } return result; } // This is an else/if as accessors and properties can't merge in TS, but might in JS // If this happens, we assume the accessor takes priority, as it imposes more constraints - else if (p.flags & (SymbolFlags.Property | SymbolFlags.Variable | SymbolFlags.Accessor)) { - return setTextRange(createProperty( - /*decorators*/ undefined, - factory.createModifiersFromModifierFlags((isReadonlySymbol(p) ? ModifierFlags.Readonly : 0) | flag), - name, - p.flags & SymbolFlags.Optional ? factory.createToken(SyntaxKind.QuestionToken) : undefined, - isPrivate ? undefined : serializeTypeForDeclaration(context, getTypeOfSymbol(p), p, enclosingDeclaration, includePrivateSymbol, bundled), + else if (p.flags & (ts.SymbolFlags.Property | ts.SymbolFlags.Variable | ts.SymbolFlags.Accessor)) { + return ts.setTextRange(createProperty( + /*decorators*/ undefined, ts.factory.createModifiersFromModifierFlags((isReadonlySymbol(p) ? ts.ModifierFlags.Readonly : 0) | flag), name, p.flags & ts.SymbolFlags.Optional ? ts.factory.createToken(ts.SyntaxKind.QuestionToken) : undefined, isPrivate ? undefined : serializeTypeForDeclaration(context, getTypeOfSymbol(p), p, enclosingDeclaration, includePrivateSymbol, bundled), // TODO: https://github.com/microsoft/TypeScript/pull/32372#discussion_r328386357 // interface members can't have initializers, however class members _can_ - /*initializer*/ undefined - ), p.declarations?.find(or(isPropertyDeclaration, isVariableDeclaration)) || firstPropertyLikeDecl); + /*initializer*/ undefined), p.declarations?.find(ts.or(ts.isPropertyDeclaration, ts.isVariableDeclaration)) || firstPropertyLikeDecl); } - if (p.flags & (SymbolFlags.Method | SymbolFlags.Function)) { + if (p.flags & (ts.SymbolFlags.Method | ts.SymbolFlags.Function)) { const type = getTypeOfSymbol(p); - const signatures = getSignaturesOfType(type, SignatureKind.Call); - if (flag & ModifierFlags.Private) { - return setTextRange(createProperty( - /*decorators*/ undefined, - factory.createModifiersFromModifierFlags((isReadonlySymbol(p) ? ModifierFlags.Readonly : 0) | flag), - name, - p.flags & SymbolFlags.Optional ? factory.createToken(SyntaxKind.QuestionToken) : undefined, + const signatures = getSignaturesOfType(type, ts.SignatureKind.Call); + if (flag & ts.ModifierFlags.Private) { + return ts.setTextRange(createProperty( + /*decorators*/ undefined, ts.factory.createModifiersFromModifierFlags((isReadonlySymbol(p) ? ts.ModifierFlags.Readonly : 0) | flag), name, p.flags & ts.SymbolFlags.Optional ? ts.factory.createToken(ts.SyntaxKind.QuestionToken) : undefined, /*type*/ undefined, - /*initializer*/ undefined - ), p.declarations?.find(isFunctionLikeDeclaration) || signatures[0] && signatures[0].declaration || p.declarations && p.declarations[0]); + /*initializer*/ undefined), p.declarations?.find(ts.isFunctionLikeDeclaration) || signatures[0] && signatures[0].declaration || p.declarations && p.declarations[0]); } const results = []; for (const sig of signatures) { // Each overload becomes a separate method declaration, in order - const decl = signatureToSignatureDeclarationHelper( - sig, - methodKind, - context, - { + const decl = signatureToSignatureDeclarationHelper(sig, methodKind, context, { name, - questionToken: p.flags & SymbolFlags.Optional ? factory.createToken(SyntaxKind.QuestionToken) : undefined, - modifiers: flag ? factory.createModifiersFromModifierFlags(flag) : undefined - } - ); - const location = sig.declaration && isPrototypePropertyAssignment(sig.declaration.parent) ? sig.declaration.parent : sig.declaration; - results.push(setTextRange(decl, location)); + questionToken: p.flags & ts.SymbolFlags.Optional ? ts.factory.createToken(ts.SyntaxKind.QuestionToken) : undefined, + modifiers: flag ? ts.factory.createModifiersFromModifierFlags(flag) : undefined + }); + const location = sig.declaration && ts.isPrototypePropertyAssignment(sig.declaration.parent) ? sig.declaration.parent : sig.declaration; + results.push(ts.setTextRange(decl, location)); } return results as unknown as T[]; } // The `Constructor`'s symbol isn't in the class's properties lists, obviously, since it's a signature on the static - return Debug.fail(`Unhandled class member kind! ${(p as any).__debugFlags || p.flags}`); + return ts.Debug.fail(`Unhandled class member kind! ${(p as any).__debugFlags || p.flags}`); }; } - function serializePropertySymbolForInterface(p: Symbol, baseType: Type | undefined) { + function serializePropertySymbolForInterface(p: ts.Symbol, baseType: ts.Type | undefined) { return serializePropertySymbolForInterfaceWorker(p, /*isStatic*/ false, baseType); } - function serializeSignatures(kind: SignatureKind, input: Type, baseType: Type | undefined, outputKind: SignatureDeclaration["kind"]) { + function serializeSignatures(kind: ts.SignatureKind, input: ts.Type, baseType: ts.Type | undefined, outputKind: ts.SignatureDeclaration["kind"]) { const signatures = getSignaturesOfType(input, kind); - if (kind === SignatureKind.Construct) { - if (!baseType && every(signatures, s => length(s.parameters) === 0)) { + if (kind === ts.SignatureKind.Construct) { + if (!baseType && ts.every(signatures, s => ts.length(s.parameters) === 0)) { return []; // No base type, every constructor is empty - elide the extraneous `constructor()` } if (baseType) { // If there is a base type, if every signature in the class is identical to a signature in the baseType, elide all the declarations - const baseSigs = getSignaturesOfType(baseType, SignatureKind.Construct); - if (!length(baseSigs) && every(signatures, s => length(s.parameters) === 0)) { + const baseSigs = getSignaturesOfType(baseType, ts.SignatureKind.Construct); + if (!ts.length(baseSigs) && ts.every(signatures, s => ts.length(s.parameters) === 0)) { return []; // Base had no explicit signatures, if all our signatures are also implicit, return an empty list } if (baseSigs.length === signatures.length) { @@ -8100,19 +7687,17 @@ namespace ts { } } } - let privateProtected: ModifierFlags = 0; + let privateProtected: ts.ModifierFlags = 0; for (const s of signatures) { if (s.declaration) { - privateProtected |= getSelectedEffectiveModifierFlags(s.declaration, ModifierFlags.Private | ModifierFlags.Protected); + privateProtected |= ts.getSelectedEffectiveModifierFlags(s.declaration, ts.ModifierFlags.Private | ts.ModifierFlags.Protected); } } if (privateProtected) { - return [setTextRange(factory.createConstructorDeclaration( - /*decorators*/ undefined, - factory.createModifiersFromModifierFlags(privateProtected), + return [ts.setTextRange(ts.factory.createConstructorDeclaration( + /*decorators*/ undefined, ts.factory.createModifiersFromModifierFlags(privateProtected), /*parameters*/ [], - /*body*/ undefined, - ), signatures[0].declaration)]; + /*body*/ undefined), signatures[0].declaration)]; } } @@ -8120,13 +7705,13 @@ namespace ts { for (const sig of signatures) { // Each overload becomes a separate constructor declaration, in order const decl = signatureToSignatureDeclarationHelper(sig, outputKind, context); - results.push(setTextRange(decl, sig.declaration)); + results.push(ts.setTextRange(decl, sig.declaration)); } return results; } - function serializeIndexSignatures(input: Type, baseType: Type | undefined) { - const results: IndexSignatureDeclaration[] = []; + function serializeIndexSignatures(input: ts.Type, baseType: ts.Type | undefined) { + const results: ts.IndexSignatureDeclaration[] = []; for (const info of getIndexInfosOfType(input)) { if (baseType) { const baseInfo = getIndexInfoOfType(baseType, info.keyType); @@ -8141,48 +7726,47 @@ namespace ts { return results; } - function serializeBaseType(t: Type, staticType: Type, rootName: string) { - const ref = trySerializeAsTypeReference(t, SymbolFlags.Value); + function serializeBaseType(t: ts.Type, staticType: ts.Type, rootName: string) { + const ref = trySerializeAsTypeReference(t, ts.SymbolFlags.Value); if (ref) { return ref; } const tempName = getUnusedName(`${rootName}_base`); - const statement = factory.createVariableStatement(/*modifiers*/ undefined, factory.createVariableDeclarationList([ - factory.createVariableDeclaration(tempName, /*exclamationToken*/ undefined, typeToTypeNodeHelper(staticType, context)) - ], NodeFlags.Const)); - addResult(statement, ModifierFlags.None); - return factory.createExpressionWithTypeArguments(factory.createIdentifier(tempName), /*typeArgs*/ undefined); + const statement = ts.factory.createVariableStatement(/*modifiers*/ undefined, ts.factory.createVariableDeclarationList([ + ts.factory.createVariableDeclaration(tempName, /*exclamationToken*/ undefined, typeToTypeNodeHelper(staticType, context)) + ], ts.NodeFlags.Const)); + addResult(statement, ts.ModifierFlags.None); + return ts.factory.createExpressionWithTypeArguments(ts.factory.createIdentifier(tempName), /*typeArgs*/ undefined); } - - function trySerializeAsTypeReference(t: Type, flags: SymbolFlags) { - let typeArgs: TypeNode[] | undefined; - let reference: Expression | undefined; + function trySerializeAsTypeReference(t: ts.Type, flags: ts.SymbolFlags) { + let typeArgs: ts.TypeNode[] | undefined; + let reference: ts.Expression | undefined; // We don't use `isValueSymbolAccessible` below. since that considers alternative containers (like modules) // which we can't write out in a syntactically valid way as an expression - if ((t as TypeReference).target && isSymbolAccessibleByFlags((t as TypeReference).target.symbol, enclosingDeclaration, flags)) { - typeArgs = map(getTypeArguments(t as TypeReference), t => typeToTypeNodeHelper(t, context)); - reference = symbolToExpression((t as TypeReference).target.symbol, context, SymbolFlags.Type); + if ((t as ts.TypeReference).target && isSymbolAccessibleByFlags((t as ts.TypeReference).target.symbol, enclosingDeclaration, flags)) { + typeArgs = ts.map(getTypeArguments(t as ts.TypeReference), t => typeToTypeNodeHelper(t, context)); + reference = symbolToExpression((t as ts.TypeReference).target.symbol, context, ts.SymbolFlags.Type); } else if (t.symbol && isSymbolAccessibleByFlags(t.symbol, enclosingDeclaration, flags)) { - reference = symbolToExpression(t.symbol, context, SymbolFlags.Type); + reference = symbolToExpression(t.symbol, context, ts.SymbolFlags.Type); } if (reference) { - return factory.createExpressionWithTypeArguments(reference, typeArgs); + return ts.factory.createExpressionWithTypeArguments(reference, typeArgs); } } - function serializeImplementedType(t: Type) { - const ref = trySerializeAsTypeReference(t, SymbolFlags.Type); + function serializeImplementedType(t: ts.Type) { + const ref = trySerializeAsTypeReference(t, ts.SymbolFlags.Type); if (ref) { return ref; } if (t.symbol) { - return factory.createExpressionWithTypeArguments(symbolToExpression(t.symbol, context, SymbolFlags.Type), /*typeArgs*/ undefined); + return ts.factory.createExpressionWithTypeArguments(symbolToExpression(t.symbol, context, ts.SymbolFlags.Type), /*typeArgs*/ undefined); } } - function getUnusedName(input: string, symbol?: Symbol): string { + function getUnusedName(input: string, symbol?: ts.Symbol): string { const id = symbol ? getSymbolId(symbol) : undefined; if (id) { if (context.remappedSymbolNames!.has(id)) { @@ -8205,25 +7789,25 @@ namespace ts { return input; } - function getNameCandidateWorker(symbol: Symbol, localName: string) { - if (localName === InternalSymbolName.Default || localName === InternalSymbolName.Class || localName === InternalSymbolName.Function) { + function getNameCandidateWorker(symbol: ts.Symbol, localName: string) { + if (localName === ts.InternalSymbolName.Default || localName === ts.InternalSymbolName.Class || localName === ts.InternalSymbolName.Function) { const flags = context.flags; - context.flags |= NodeBuilderFlags.InInitialEntityName; + context.flags |= ts.NodeBuilderFlags.InInitialEntityName; const nameCandidate = getNameOfSymbolAsWritten(symbol, context); context.flags = flags; - localName = nameCandidate.length > 0 && isSingleOrDoubleQuote(nameCandidate.charCodeAt(0)) ? stripQuotes(nameCandidate) : nameCandidate; + localName = nameCandidate.length > 0 && ts.isSingleOrDoubleQuote(nameCandidate.charCodeAt(0)) ? ts.stripQuotes(nameCandidate) : nameCandidate; } - if (localName === InternalSymbolName.Default) { + if (localName === ts.InternalSymbolName.Default) { localName = "_default"; } - else if (localName === InternalSymbolName.ExportEquals) { + else if (localName === ts.InternalSymbolName.ExportEquals) { localName = "_exports"; } - localName = isIdentifierText(localName, languageVersion) && !isStringANonContextualKeyword(localName) ? localName : "_" + localName.replace(/[^a-zA-Z0-9]/g, "_"); + localName = ts.isIdentifierText(localName, languageVersion) && !ts.isStringANonContextualKeyword(localName) ? localName : "_" + localName.replace(/[^a-zA-Z0-9]/g, "_"); return localName; } - function getInternalSymbolName(symbol: Symbol, localName: string) { + function getInternalSymbolName(symbol: ts.Symbol, localName: string) { const id = getSymbolId(symbol); if (context.remappedSymbolNames!.has(id)) { return context.remappedSymbolNames!.get(id)!; @@ -8236,34 +7820,30 @@ namespace ts { } } - function typePredicateToString(typePredicate: TypePredicate, enclosingDeclaration?: Node, flags: TypeFormatFlags = TypeFormatFlags.UseAliasDefinedOutsideCurrentScope, writer?: EmitTextWriter): string { - return writer ? typePredicateToStringWorker(writer).getText() : usingSingleLineStringWriter(typePredicateToStringWorker); - - function typePredicateToStringWorker(writer: EmitTextWriter) { - const predicate = factory.createTypePredicateNode( - typePredicate.kind === TypePredicateKind.AssertsThis || typePredicate.kind === TypePredicateKind.AssertsIdentifier ? factory.createToken(SyntaxKind.AssertsKeyword) : undefined, - typePredicate.kind === TypePredicateKind.Identifier || typePredicate.kind === TypePredicateKind.AssertsIdentifier ? factory.createIdentifier(typePredicate.parameterName) : factory.createThisTypeNode(), - typePredicate.type && nodeBuilder.typeToTypeNode(typePredicate.type, enclosingDeclaration, toNodeBuilderFlags(flags) | NodeBuilderFlags.IgnoreErrors | NodeBuilderFlags.WriteTypeParametersInQualifiedName)! // TODO: GH#18217 + function typePredicateToString(typePredicate: ts.TypePredicate, enclosingDeclaration?: ts.Node, flags: ts.TypeFormatFlags = ts.TypeFormatFlags.UseAliasDefinedOutsideCurrentScope, writer?: ts.EmitTextWriter): string { + return writer ? typePredicateToStringWorker(writer).getText() : ts.usingSingleLineStringWriter(typePredicateToStringWorker); + function typePredicateToStringWorker(writer: ts.EmitTextWriter) { + const predicate = ts.factory.createTypePredicateNode(typePredicate.kind === ts.TypePredicateKind.AssertsThis || typePredicate.kind === ts.TypePredicateKind.AssertsIdentifier ? ts.factory.createToken(ts.SyntaxKind.AssertsKeyword) : undefined, typePredicate.kind === ts.TypePredicateKind.Identifier || typePredicate.kind === ts.TypePredicateKind.AssertsIdentifier ? ts.factory.createIdentifier(typePredicate.parameterName) : ts.factory.createThisTypeNode(), typePredicate.type && nodeBuilder.typeToTypeNode(typePredicate.type, enclosingDeclaration, toNodeBuilderFlags(flags) | ts.NodeBuilderFlags.IgnoreErrors | ts.NodeBuilderFlags.WriteTypeParametersInQualifiedName)! // TODO: GH#18217 ); - const printer = createPrinter({ removeComments: true }); - const sourceFile = enclosingDeclaration && getSourceFileOfNode(enclosingDeclaration); - printer.writeNode(EmitHint.Unspecified, predicate, /*sourceFile*/ sourceFile, writer); + const printer = ts.createPrinter({ removeComments: true }); + const sourceFile = enclosingDeclaration && ts.getSourceFileOfNode(enclosingDeclaration); + printer.writeNode(ts.EmitHint.Unspecified, predicate, /*sourceFile*/ sourceFile, writer); return writer; } } - function formatUnionTypes(types: readonly Type[]): Type[] { - const result: Type[] = []; - let flags: TypeFlags = 0; + function formatUnionTypes(types: readonly ts.Type[]): ts.Type[] { + const result: ts.Type[] = []; + let flags: ts.TypeFlags = 0; for (let i = 0; i < types.length; i++) { const t = types[i]; flags |= t.flags; - if (!(t.flags & TypeFlags.Nullable)) { - if (t.flags & (TypeFlags.BooleanLiteral | TypeFlags.EnumLiteral)) { - const baseType = t.flags & TypeFlags.BooleanLiteral ? booleanType : getBaseTypeOfEnumLiteralType(t as LiteralType); - if (baseType.flags & TypeFlags.Union) { - const count = (baseType as UnionType).types.length; - if (i + count <= types.length && getRegularTypeOfLiteralType(types[i + count - 1]) === getRegularTypeOfLiteralType((baseType as UnionType).types[count - 1])) { + if (!(t.flags & ts.TypeFlags.Nullable)) { + if (t.flags & (ts.TypeFlags.BooleanLiteral | ts.TypeFlags.EnumLiteral)) { + const baseType = t.flags & ts.TypeFlags.BooleanLiteral ? booleanType : getBaseTypeOfEnumLiteralType(t as ts.LiteralType); + if (baseType.flags & ts.TypeFlags.Union) { + const count = (baseType as ts.UnionType).types.length; + if (i + count <= types.length && getRegularTypeOfLiteralType(types[i + count - 1]) === getRegularTypeOfLiteralType((baseType as ts.UnionType).types[count - 1])) { result.push(baseType); i += count - 1; continue; @@ -8273,78 +7853,78 @@ namespace ts { result.push(t); } } - if (flags & TypeFlags.Null) result.push(nullType); - if (flags & TypeFlags.Undefined) result.push(undefinedType); + if (flags & ts.TypeFlags.Null) + result.push(nullType); + if (flags & ts.TypeFlags.Undefined) + result.push(undefinedType); return result || types; } - function visibilityToString(flags: ModifierFlags): string | undefined { - if (flags === ModifierFlags.Private) { + function visibilityToString(flags: ts.ModifierFlags): string | undefined { + if (flags === ts.ModifierFlags.Private) { return "private"; } - if (flags === ModifierFlags.Protected) { + if (flags === ts.ModifierFlags.Protected) { return "protected"; } return "public"; } - function getTypeAliasForTypeLiteral(type: Type): Symbol | undefined { - if (type.symbol && type.symbol.flags & SymbolFlags.TypeLiteral && type.symbol.declarations) { - const node = walkUpParenthesizedTypes(type.symbol.declarations[0].parent); - if (node.kind === SyntaxKind.TypeAliasDeclaration) { + function getTypeAliasForTypeLiteral(type: ts.Type): ts.Symbol | undefined { + if (type.symbol && type.symbol.flags & ts.SymbolFlags.TypeLiteral && type.symbol.declarations) { + const node = ts.walkUpParenthesizedTypes(type.symbol.declarations[0].parent); + if (node.kind === ts.SyntaxKind.TypeAliasDeclaration) { return getSymbolOfNode(node); } } return undefined; } - function isTopLevelInExternalModuleAugmentation(node: Node): boolean { + function isTopLevelInExternalModuleAugmentation(node: ts.Node): boolean { return node && node.parent && - node.parent.kind === SyntaxKind.ModuleBlock && - isExternalModuleAugmentation(node.parent.parent); + node.parent.kind === ts.SyntaxKind.ModuleBlock && + ts.isExternalModuleAugmentation(node.parent.parent); } interface NodeBuilderContext { - enclosingDeclaration: Node | undefined; - flags: NodeBuilderFlags; - tracker: SymbolTracker; + enclosingDeclaration: ts.Node | undefined; + flags: ts.NodeBuilderFlags; + tracker: ts.SymbolTracker; // State encounteredError: boolean; reportedDiagnostic: boolean; - visitedTypes: Set | undefined; - symbolDepth: ESMap | undefined; - inferTypeParameters: TypeParameter[] | undefined; + visitedTypes: ts.Set | undefined; + symbolDepth: ts.ESMap | undefined; + inferTypeParameters: ts.TypeParameter[] | undefined; approximateLength: number; truncating?: boolean; - typeParameterSymbolList?: Set; - typeParameterNames?: ESMap; - typeParameterNamesByText?: Set; - typeParameterNamesByTextNextNameCount?: ESMap; - usedSymbolNames?: Set; - remappedSymbolNames?: ESMap; - reverseMappedStack?: ReverseMappedSymbol[]; - } - - function isDefaultBindingContext(location: Node) { - return location.kind === SyntaxKind.SourceFile || isAmbientModule(location); - } - - function getNameOfSymbolFromNameType(symbol: Symbol, context?: NodeBuilderContext) { + typeParameterSymbolList?: ts.Set; + typeParameterNames?: ts.ESMap; + typeParameterNamesByText?: ts.Set; + typeParameterNamesByTextNextNameCount?: ts.ESMap; + usedSymbolNames?: ts.Set; + remappedSymbolNames?: ts.ESMap; + reverseMappedStack?: ts.ReverseMappedSymbol[]; + } + function isDefaultBindingContext(location: ts.Node) { + return location.kind === ts.SyntaxKind.SourceFile || ts.isAmbientModule(location); + } + function getNameOfSymbolFromNameType(symbol: ts.Symbol, context?: NodeBuilderContext) { const nameType = getSymbolLinks(symbol).nameType; if (nameType) { - if (nameType.flags & TypeFlags.StringOrNumberLiteral) { - const name = "" + (nameType as StringLiteralType | NumberLiteralType).value; - if (!isIdentifierText(name, getEmitScriptTarget(compilerOptions)) && !isNumericLiteralName(name)) { - return `"${escapeString(name, CharacterCodes.doubleQuote)}"`; + if (nameType.flags & ts.TypeFlags.StringOrNumberLiteral) { + const name = "" + (nameType as ts.StringLiteralType | ts.NumberLiteralType).value; + if (!ts.isIdentifierText(name, ts.getEmitScriptTarget(compilerOptions)) && !ts.isNumericLiteralName(name)) { + return `"${ts.escapeString(name, ts.CharacterCodes.doubleQuote)}"`; } - if (isNumericLiteralName(name) && startsWith(name, "-")) { + if (ts.isNumericLiteralName(name) && ts.startsWith(name, "-")) { return `[${name}]`; } return name; } - if (nameType.flags & TypeFlags.UniqueESSymbol) { - return `[${getNameOfSymbolAsWritten((nameType as UniqueESSymbolType).symbol, context)}]`; + if (nameType.flags & ts.TypeFlags.UniqueESSymbol) { + return `[${getNameOfSymbolAsWritten((nameType as ts.UniqueESSymbolType).symbol, context)}]`; } } } @@ -8356,26 +7936,26 @@ namespace ts { * Unlike `symbolName(symbol)`, this will include quotes if the name is from a string literal. * It will also use a representation of a number as written instead of a decimal form, e.g. `0o11` instead of `9`. */ - function getNameOfSymbolAsWritten(symbol: Symbol, context?: NodeBuilderContext): string { - if (context && symbol.escapedName === InternalSymbolName.Default && !(context.flags & NodeBuilderFlags.UseAliasDefinedOutsideCurrentScope) && + function getNameOfSymbolAsWritten(symbol: ts.Symbol, context?: NodeBuilderContext): string { + if (context && symbol.escapedName === ts.InternalSymbolName.Default && !(context.flags & ts.NodeBuilderFlags.UseAliasDefinedOutsideCurrentScope) && // If it's not the first part of an entity name, it must print as `default` - (!(context.flags & NodeBuilderFlags.InInitialEntityName) || + (!(context.flags & ts.NodeBuilderFlags.InInitialEntityName) || // if the symbol is synthesized, it will only be referenced externally it must print as `default` !symbol.declarations || // if not in the same binding context (source file, module declaration), it must print as `default` - (context.enclosingDeclaration && findAncestor(symbol.declarations[0], isDefaultBindingContext) !== findAncestor(context.enclosingDeclaration, isDefaultBindingContext)))) { + (context.enclosingDeclaration && ts.findAncestor(symbol.declarations[0], isDefaultBindingContext) !== ts.findAncestor(context.enclosingDeclaration, isDefaultBindingContext)))) { return "default"; } if (symbol.declarations && symbol.declarations.length) { - let declaration = firstDefined(symbol.declarations, d => getNameOfDeclaration(d) ? d : undefined); // Try using a declaration with a name, first - const name = declaration && getNameOfDeclaration(declaration); + let declaration = ts.firstDefined(symbol.declarations, d => ts.getNameOfDeclaration(d) ? d : undefined); // Try using a declaration with a name, first + const name = declaration && ts.getNameOfDeclaration(declaration); if (declaration && name) { - if (isCallExpression(declaration) && isBindableObjectDefinePropertyCall(declaration)) { - return symbolName(symbol); + if (ts.isCallExpression(declaration) && ts.isBindableObjectDefinePropertyCall(declaration)) { + return ts.symbolName(symbol); } - if (isComputedPropertyName(name) && !(getCheckFlags(symbol) & CheckFlags.Late)) { + if (ts.isComputedPropertyName(name) && !(ts.getCheckFlags(symbol) & ts.CheckFlags.Late)) { const nameType = getSymbolLinks(symbol).nameType; - if (nameType && nameType.flags & TypeFlags.StringOrNumberLiteral) { + if (nameType && nameType.flags & ts.TypeFlags.StringOrNumberLiteral) { // Computed property name isn't late bound, but has a well-known name type - use name type to generate a symbol name const result = getNameOfSymbolFromNameType(symbol, context); if (result !== undefined) { @@ -8383,29 +7963,29 @@ namespace ts { } } } - return declarationNameToString(name); + return ts.declarationNameToString(name); } if (!declaration) { declaration = symbol.declarations[0]; // Declaration may be nameless, but we'll try anyway } - if (declaration.parent && declaration.parent.kind === SyntaxKind.VariableDeclaration) { - return declarationNameToString((declaration.parent as VariableDeclaration).name); + if (declaration.parent && declaration.parent.kind === ts.SyntaxKind.VariableDeclaration) { + return ts.declarationNameToString((declaration.parent as ts.VariableDeclaration).name); } switch (declaration.kind) { - case SyntaxKind.ClassExpression: - case SyntaxKind.FunctionExpression: - case SyntaxKind.ArrowFunction: - if (context && !context.encounteredError && !(context.flags & NodeBuilderFlags.AllowAnonymousIdentifier)) { + case ts.SyntaxKind.ClassExpression: + case ts.SyntaxKind.FunctionExpression: + case ts.SyntaxKind.ArrowFunction: + if (context && !context.encounteredError && !(context.flags & ts.NodeBuilderFlags.AllowAnonymousIdentifier)) { context.encounteredError = true; } - return declaration.kind === SyntaxKind.ClassExpression ? "(Anonymous class)" : "(Anonymous function)"; + return declaration.kind === ts.SyntaxKind.ClassExpression ? "(Anonymous class)" : "(Anonymous function)"; } } const name = getNameOfSymbolFromNameType(symbol, context); - return name !== undefined ? name : symbolName(symbol); + return name !== undefined ? name : ts.symbolName(symbol); } - function isDeclarationVisible(node: Node): boolean { + function isDeclarationVisible(node: ts.Node): boolean { if (node) { const links = getNodeLinks(node); if (links.isVisible === undefined) { @@ -8418,90 +7998,90 @@ namespace ts { function determineIfDeclarationIsVisible() { switch (node.kind) { - case SyntaxKind.JSDocCallbackTag: - case SyntaxKind.JSDocTypedefTag: - case SyntaxKind.JSDocEnumTag: + case ts.SyntaxKind.JSDocCallbackTag: + case ts.SyntaxKind.JSDocTypedefTag: + case ts.SyntaxKind.JSDocEnumTag: // Top-level jsdoc type aliases are considered exported // First parent is comment node, second is hosting declaration or token; we only care about those tokens or declarations whose parent is a source file - return !!(node.parent && node.parent.parent && node.parent.parent.parent && isSourceFile(node.parent.parent.parent)); - case SyntaxKind.BindingElement: + return !!(node.parent && node.parent.parent && node.parent.parent.parent && ts.isSourceFile(node.parent.parent.parent)); + case ts.SyntaxKind.BindingElement: return isDeclarationVisible(node.parent.parent); - case SyntaxKind.VariableDeclaration: - if (isBindingPattern((node as VariableDeclaration).name) && - !((node as VariableDeclaration).name as BindingPattern).elements.length) { + case ts.SyntaxKind.VariableDeclaration: + if (ts.isBindingPattern((node as ts.VariableDeclaration).name) && + !((node as ts.VariableDeclaration).name as ts.BindingPattern).elements.length) { // If the binding pattern is empty, this variable declaration is not visible return false; } // falls through - case SyntaxKind.ModuleDeclaration: - case SyntaxKind.ClassDeclaration: - case SyntaxKind.InterfaceDeclaration: - case SyntaxKind.TypeAliasDeclaration: - case SyntaxKind.FunctionDeclaration: - case SyntaxKind.EnumDeclaration: - case SyntaxKind.ImportEqualsDeclaration: + case ts.SyntaxKind.ModuleDeclaration: + case ts.SyntaxKind.ClassDeclaration: + case ts.SyntaxKind.InterfaceDeclaration: + case ts.SyntaxKind.TypeAliasDeclaration: + case ts.SyntaxKind.FunctionDeclaration: + case ts.SyntaxKind.EnumDeclaration: + case ts.SyntaxKind.ImportEqualsDeclaration: // external module augmentation is always visible - if (isExternalModuleAugmentation(node)) { + if (ts.isExternalModuleAugmentation(node)) { return true; } const parent = getDeclarationContainer(node); // If the node is not exported or it is not ambient module element (except import declaration) - if (!(getCombinedModifierFlags(node as Declaration) & ModifierFlags.Export) && - !(node.kind !== SyntaxKind.ImportEqualsDeclaration && parent.kind !== SyntaxKind.SourceFile && parent.flags & NodeFlags.Ambient)) { + if (!(ts.getCombinedModifierFlags(node as ts.Declaration) & ts.ModifierFlags.Export) && + !(node.kind !== ts.SyntaxKind.ImportEqualsDeclaration && parent.kind !== ts.SyntaxKind.SourceFile && parent.flags & ts.NodeFlags.Ambient)) { return isGlobalSourceFile(parent); } // Exported members/ambient module elements (exception import declaration) are visible if parent is visible return isDeclarationVisible(parent); - case SyntaxKind.PropertyDeclaration: - case SyntaxKind.PropertySignature: - case SyntaxKind.GetAccessor: - case SyntaxKind.SetAccessor: - case SyntaxKind.MethodDeclaration: - case SyntaxKind.MethodSignature: - if (hasEffectiveModifier(node, ModifierFlags.Private | ModifierFlags.Protected)) { + case ts.SyntaxKind.PropertyDeclaration: + case ts.SyntaxKind.PropertySignature: + case ts.SyntaxKind.GetAccessor: + case ts.SyntaxKind.SetAccessor: + case ts.SyntaxKind.MethodDeclaration: + case ts.SyntaxKind.MethodSignature: + if (ts.hasEffectiveModifier(node, ts.ModifierFlags.Private | ts.ModifierFlags.Protected)) { // Private/protected properties/methods are not visible return false; } // Public properties/methods are visible if its parents are visible, so: // falls through - case SyntaxKind.Constructor: - case SyntaxKind.ConstructSignature: - case SyntaxKind.CallSignature: - case SyntaxKind.IndexSignature: - case SyntaxKind.Parameter: - case SyntaxKind.ModuleBlock: - case SyntaxKind.FunctionType: - case SyntaxKind.ConstructorType: - case SyntaxKind.TypeLiteral: - case SyntaxKind.TypeReference: - case SyntaxKind.ArrayType: - case SyntaxKind.TupleType: - case SyntaxKind.UnionType: - case SyntaxKind.IntersectionType: - case SyntaxKind.ParenthesizedType: - case SyntaxKind.NamedTupleMember: + case ts.SyntaxKind.Constructor: + case ts.SyntaxKind.ConstructSignature: + case ts.SyntaxKind.CallSignature: + case ts.SyntaxKind.IndexSignature: + case ts.SyntaxKind.Parameter: + case ts.SyntaxKind.ModuleBlock: + case ts.SyntaxKind.FunctionType: + case ts.SyntaxKind.ConstructorType: + case ts.SyntaxKind.TypeLiteral: + case ts.SyntaxKind.TypeReference: + case ts.SyntaxKind.ArrayType: + case ts.SyntaxKind.TupleType: + case ts.SyntaxKind.UnionType: + case ts.SyntaxKind.IntersectionType: + case ts.SyntaxKind.ParenthesizedType: + case ts.SyntaxKind.NamedTupleMember: return isDeclarationVisible(node.parent); // Default binding, import specifier and namespace import is visible // only on demand so by default it is not visible - case SyntaxKind.ImportClause: - case SyntaxKind.NamespaceImport: - case SyntaxKind.ImportSpecifier: + case ts.SyntaxKind.ImportClause: + case ts.SyntaxKind.NamespaceImport: + case ts.SyntaxKind.ImportSpecifier: return false; // Type parameters are always visible - case SyntaxKind.TypeParameter: + case ts.SyntaxKind.TypeParameter: // Source file and namespace export are always visible // falls through - case SyntaxKind.SourceFile: - case SyntaxKind.NamespaceExportDeclaration: + case ts.SyntaxKind.SourceFile: + case ts.SyntaxKind.NamespaceExportDeclaration: return true; // Export assignments do not create name bindings outside the module - case SyntaxKind.ExportAssignment: + case ts.SyntaxKind.ExportAssignment: return false; default: @@ -8510,42 +8090,41 @@ namespace ts { } } - function collectLinkedAliases(node: Identifier, setVisibility?: boolean): Node[] | undefined { - let exportSymbol: Symbol | undefined; - if (node.parent && node.parent.kind === SyntaxKind.ExportAssignment) { - exportSymbol = resolveName(node, node.escapedText, SymbolFlags.Value | SymbolFlags.Type | SymbolFlags.Namespace | SymbolFlags.Alias, /*nameNotFoundMessage*/ undefined, node, /*isUse*/ false); + function collectLinkedAliases(node: ts.Identifier, setVisibility?: boolean): ts.Node[] | undefined { + let exportSymbol: ts.Symbol | undefined; + if (node.parent && node.parent.kind === ts.SyntaxKind.ExportAssignment) { + exportSymbol = resolveName(node, node.escapedText, ts.SymbolFlags.Value | ts.SymbolFlags.Type | ts.SymbolFlags.Namespace | ts.SymbolFlags.Alias, /*nameNotFoundMessage*/ undefined, node, /*isUse*/ false); } - else if (node.parent.kind === SyntaxKind.ExportSpecifier) { - exportSymbol = getTargetOfExportSpecifier(node.parent as ExportSpecifier, SymbolFlags.Value | SymbolFlags.Type | SymbolFlags.Namespace | SymbolFlags.Alias); + else if (node.parent.kind === ts.SyntaxKind.ExportSpecifier) { + exportSymbol = getTargetOfExportSpecifier(node.parent as ts.ExportSpecifier, ts.SymbolFlags.Value | ts.SymbolFlags.Type | ts.SymbolFlags.Namespace | ts.SymbolFlags.Alias); } - let result: Node[] | undefined; - let visited: Set | undefined; + let result: ts.Node[] | undefined; + let visited: ts.Set | undefined; if (exportSymbol) { - visited = new Set(); + visited = new ts.Set(); visited.add(getSymbolId(exportSymbol)); buildVisibleNodeList(exportSymbol.declarations); } return result; - function buildVisibleNodeList(declarations: Declaration[] | undefined) { - forEach(declarations, declaration => { + function buildVisibleNodeList(declarations: ts.Declaration[] | undefined) { + ts.forEach(declarations, declaration => { const resultNode = getAnyImportSyntax(declaration) || declaration; if (setVisibility) { getNodeLinks(declaration).isVisible = true; } else { result = result || []; - pushIfUnique(result, resultNode); + ts.pushIfUnique(result, resultNode); } - if (isInternalModuleImportEqualsDeclaration(declaration)) { + if (ts.isInternalModuleImportEqualsDeclaration(declaration)) { // Add the referenced top container visible - const internalModuleReference = declaration.moduleReference as Identifier | QualifiedName; - const firstIdentifier = getFirstIdentifier(internalModuleReference); - const importSymbol = resolveName(declaration, firstIdentifier.escapedText, SymbolFlags.Value | SymbolFlags.Type | SymbolFlags.Namespace, - undefined, undefined, /*isUse*/ false); + const internalModuleReference = declaration.moduleReference as ts.Identifier | ts.QualifiedName; + const firstIdentifier = ts.getFirstIdentifier(internalModuleReference); + const importSymbol = resolveName(declaration, firstIdentifier.escapedText, ts.SymbolFlags.Value | ts.SymbolFlags.Type | ts.SymbolFlags.Namespace, undefined, undefined, /*isUse*/ false); if (importSymbol && visited) { - if (tryAddToSet(visited, getSymbolId(importSymbol))) { + if (ts.tryAddToSet(visited, getSymbolId(importSymbol))) { buildVisibleNodeList(importSymbol.declarations); } } @@ -8596,25 +8175,25 @@ namespace ts { function hasType(target: TypeSystemEntity, propertyName: TypeSystemPropertyName): boolean { switch (propertyName) { case TypeSystemPropertyName.Type: - return !!getSymbolLinks(target as Symbol).type; + return !!getSymbolLinks(target as ts.Symbol).type; case TypeSystemPropertyName.EnumTagType: - return !!(getNodeLinks(target as JSDocEnumTag).resolvedEnumType); + return !!(getNodeLinks(target as ts.JSDocEnumTag).resolvedEnumType); case TypeSystemPropertyName.DeclaredType: - return !!getSymbolLinks(target as Symbol).declaredType; + return !!getSymbolLinks(target as ts.Symbol).declaredType; case TypeSystemPropertyName.ResolvedBaseConstructorType: - return !!(target as InterfaceType).resolvedBaseConstructorType; + return !!(target as ts.InterfaceType).resolvedBaseConstructorType; case TypeSystemPropertyName.ResolvedReturnType: - return !!(target as Signature).resolvedReturnType; + return !!(target as ts.Signature).resolvedReturnType; case TypeSystemPropertyName.ImmediateBaseConstraint: - return !!(target as Type).immediateBaseConstraint; + return !!(target as ts.Type).immediateBaseConstraint; case TypeSystemPropertyName.ResolvedTypeArguments: - return !!(target as TypeReference).resolvedTypeArguments; + return !!(target as ts.TypeReference).resolvedTypeArguments; case TypeSystemPropertyName.ResolvedBaseTypes: - return !!(target as InterfaceType).baseTypesResolved; + return !!(target as ts.InterfaceType).baseTypesResolved; case TypeSystemPropertyName.WriteType: - return !!getSymbolLinks(target as Symbol).writeType; + return !!getSymbolLinks(target as ts.Symbol).writeType; } - return Debug.assertNever(propertyName); + return ts.Debug.assertNever(propertyName); } /** @@ -8627,15 +8206,15 @@ namespace ts { return resolutionResults.pop()!; } - function getDeclarationContainer(node: Node): Node { - return findAncestor(getRootDeclaration(node), node => { + function getDeclarationContainer(node: ts.Node): ts.Node { + return ts.findAncestor(ts.getRootDeclaration(node), node => { switch (node.kind) { - case SyntaxKind.VariableDeclaration: - case SyntaxKind.VariableDeclarationList: - case SyntaxKind.ImportSpecifier: - case SyntaxKind.NamedImports: - case SyntaxKind.NamespaceImport: - case SyntaxKind.ImportClause: + case ts.SyntaxKind.VariableDeclaration: + case ts.SyntaxKind.VariableDeclarationList: + case ts.SyntaxKind.ImportSpecifier: + case ts.SyntaxKind.NamedImports: + case ts.SyntaxKind.NamespaceImport: + case ts.SyntaxKind.ImportClause: return false; default: return true; @@ -8643,38 +8222,38 @@ namespace ts { })!.parent; } - function getTypeOfPrototypeProperty(prototype: Symbol): Type { + function getTypeOfPrototypeProperty(prototype: ts.Symbol): ts.Type { // TypeScript 1.0 spec (April 2014): 8.4 // Every class automatically contains a static property member named 'prototype', // the type of which is an instantiation of the class type with type Any supplied as a type argument for each type parameter. // It is an error to explicitly declare a static property member with the name 'prototype'. - const classType = getDeclaredTypeOfSymbol(getParentOfSymbol(prototype)!) as InterfaceType; - return classType.typeParameters ? createTypeReference(classType as GenericType, map(classType.typeParameters, _ => anyType)) : classType; + const classType = getDeclaredTypeOfSymbol(getParentOfSymbol(prototype)!) as ts.InterfaceType; + return classType.typeParameters ? createTypeReference(classType as ts.GenericType, ts.map(classType.typeParameters, _ => anyType)) : classType; } // Return the type of the given property in the given type, or undefined if no such property exists - function getTypeOfPropertyOfType(type: Type, name: __String): Type | undefined { + function getTypeOfPropertyOfType(type: ts.Type, name: ts.__String): ts.Type | undefined { const prop = getPropertyOfType(type, name); return prop ? getTypeOfSymbol(prop) : undefined; } - function getTypeOfPropertyOrIndexSignature(type: Type, name: __String): Type { + function getTypeOfPropertyOrIndexSignature(type: ts.Type, name: ts.__String): ts.Type { return getTypeOfPropertyOfType(type, name) || getApplicableIndexInfoForName(type, name)?.type || unknownType; } - function isTypeAny(type: Type | undefined) { - return type && (type.flags & TypeFlags.Any) !== 0; + function isTypeAny(type: ts.Type | undefined) { + return type && (type.flags & ts.TypeFlags.Any) !== 0; } - function isErrorType(type: Type) { + function isErrorType(type: ts.Type) { // The only 'any' types that have alias symbols are those manufactured by getTypeFromTypeAliasReference for // a reference to an unresolved symbol. We want those to behave like the errorType. - return type === errorType || !!(type.flags & TypeFlags.Any && type.aliasSymbol); + return type === errorType || !!(type.flags & ts.TypeFlags.Any && type.aliasSymbol); } // Return the type of a binding element parent. We check SymbolLinks first to see if a type has been // assigned by contextual typing. - function getTypeForBindingElementParent(node: BindingElementGrandparent, checkMode: CheckMode) { + function getTypeForBindingElementParent(node: ts.BindingElementGrandparent, checkMode: CheckMode) { if (checkMode !== CheckMode.Normal) { return getTypeForVariableLikeDeclaration(node, /*includeOptionality*/ false, checkMode); } @@ -8682,24 +8261,23 @@ namespace ts { return symbol && getSymbolLinks(symbol).type || getTypeForVariableLikeDeclaration(node, /*includeOptionality*/ false, checkMode); } - function getRestType(source: Type, properties: PropertyName[], symbol: Symbol | undefined): Type { - source = filterType(source, t => !(t.flags & TypeFlags.Nullable)); - if (source.flags & TypeFlags.Never) { + function getRestType(source: ts.Type, properties: ts.PropertyName[], symbol: ts.Symbol | undefined): ts.Type { + source = filterType(source, t => !(t.flags & ts.TypeFlags.Nullable)); + if (source.flags & ts.TypeFlags.Never) { return emptyObjectType; } - if (source.flags & TypeFlags.Union) { + if (source.flags & ts.TypeFlags.Union) { return mapType(source, t => getRestType(t, properties, symbol)); } - let omitKeyType = getUnionType(map(properties, getLiteralTypeFromPropertyName)); - - const spreadableProperties: Symbol[] = []; - const unspreadableToRestKeys: Type[] = []; + let omitKeyType = getUnionType(ts.map(properties, getLiteralTypeFromPropertyName)); + const spreadableProperties: ts.Symbol[] = []; + const unspreadableToRestKeys: ts.Type[] = []; for (const prop of getPropertiesOfType(source)) { - const literalTypeFromProperty = getLiteralTypeFromProperty(prop, TypeFlags.StringOrNumberLiteralOrUnique); + const literalTypeFromProperty = getLiteralTypeFromProperty(prop, ts.TypeFlags.StringOrNumberLiteralOrUnique); if (!isTypeAssignableTo(literalTypeFromProperty, omitKeyType) - && !(getDeclarationModifierFlagsFromSymbol(prop) & (ModifierFlags.Private | ModifierFlags.Protected)) + && !(ts.getDeclarationModifierFlagsFromSymbol(prop) & (ts.ModifierFlags.Private | ts.ModifierFlags.Protected)) && isSpreadableProperty(prop)) { spreadableProperties.push(prop); } @@ -8716,7 +8294,7 @@ namespace ts { omitKeyType = getUnionType([omitKeyType, ...unspreadableToRestKeys]); } - if (omitKeyType.flags & TypeFlags.Never) { + if (omitKeyType.flags & ts.TypeFlags.Never) { return source; } @@ -8726,21 +8304,21 @@ namespace ts { } return getTypeAliasInstantiation(omitTypeAlias, [source, omitKeyType]); } - const members = createSymbolTable(); + const members = ts.createSymbolTable(); for (const prop of spreadableProperties) { members.set(prop.escapedName, getSpreadSymbol(prop, /*readonly*/ false)); } - const result = createAnonymousType(symbol, members, emptyArray, emptyArray, getIndexInfosOfType(source)); - result.objectFlags |= ObjectFlags.ObjectRestType; + const result = createAnonymousType(symbol, members, ts.emptyArray, ts.emptyArray, getIndexInfosOfType(source)); + result.objectFlags |= ts.ObjectFlags.ObjectRestType; return result; } - function isGenericTypeWithUndefinedConstraint(type: Type) { - return !!(type.flags & TypeFlags.Instantiable) && maybeTypeOfKind(getBaseConstraintOfType(type) || unknownType, TypeFlags.Undefined); + function isGenericTypeWithUndefinedConstraint(type: ts.Type) { + return !!(type.flags & ts.TypeFlags.Instantiable) && maybeTypeOfKind(getBaseConstraintOfType(type) || unknownType, ts.TypeFlags.Undefined); } - function getNonUndefinedType(type: Type) { - const typeOrConstraint = someType(type, isGenericTypeWithUndefinedConstraint) ? mapType(type, t => t.flags & TypeFlags.Instantiable ? getBaseConstraintOrType(t) : t) : type; + function getNonUndefinedType(type: ts.Type) { + const typeOrConstraint = someType(type, isGenericTypeWithUndefinedConstraint) ? mapType(type, t => t.flags & ts.TypeFlags.Instantiable ? getBaseConstraintOrType(t) : t) : type; return getTypeWithFacts(typeOrConstraint, TypeFacts.NEUndefined); } @@ -8753,23 +8331,23 @@ namespace ts { // [ x ] = obj; // Expression // We construct a synthetic element access expression corresponding to 'obj.x' such that the control // flow analyzer doesn't have to handle all the different syntactic forms. - function getFlowTypeOfDestructuring(node: BindingElement | PropertyAssignment | ShorthandPropertyAssignment | Expression, declaredType: Type) { + function getFlowTypeOfDestructuring(node: ts.BindingElement | ts.PropertyAssignment | ts.ShorthandPropertyAssignment | ts.Expression, declaredType: ts.Type) { const reference = getSyntheticElementAccess(node); return reference ? getFlowTypeOfReference(reference, declaredType) : declaredType; } - function getSyntheticElementAccess(node: BindingElement | PropertyAssignment | ShorthandPropertyAssignment | Expression): ElementAccessExpression | undefined { + function getSyntheticElementAccess(node: ts.BindingElement | ts.PropertyAssignment | ts.ShorthandPropertyAssignment | ts.Expression): ts.ElementAccessExpression | undefined { const parentAccess = getParentElementAccess(node); if (parentAccess && parentAccess.flowNode) { const propName = getDestructuringPropertyName(node); if (propName) { - const literal = setTextRange(parseNodeFactory.createStringLiteral(propName), node); - const lhsExpr = isLeftHandSideExpression(parentAccess) ? parentAccess : parseNodeFactory.createParenthesizedExpression(parentAccess); - const result = setTextRange(parseNodeFactory.createElementAccessExpression(lhsExpr, literal), node); - setParent(literal, result); - setParent(result, node); + const literal = ts.setTextRange(ts.parseNodeFactory.createStringLiteral(propName), node); + const lhsExpr = ts.isLeftHandSideExpression(parentAccess) ? parentAccess : ts.parseNodeFactory.createParenthesizedExpression(parentAccess); + const result = ts.setTextRange(ts.parseNodeFactory.createElementAccessExpression(lhsExpr, literal), node); + ts.setParent(literal, result); + ts.setParent(result, node); if (lhsExpr !== parentAccess) { - setParent(lhsExpr, result); + ts.setParent(lhsExpr, result); } result.flowNode = parentAccess.flowNode; return result; @@ -8777,52 +8355,51 @@ namespace ts { } } - function getParentElementAccess(node: BindingElement | PropertyAssignment | ShorthandPropertyAssignment | Expression) { + function getParentElementAccess(node: ts.BindingElement | ts.PropertyAssignment | ts.ShorthandPropertyAssignment | ts.Expression) { const ancestor = node.parent.parent; switch (ancestor.kind) { - case SyntaxKind.BindingElement: - case SyntaxKind.PropertyAssignment: - return getSyntheticElementAccess(ancestor as BindingElement | PropertyAssignment); - case SyntaxKind.ArrayLiteralExpression: - return getSyntheticElementAccess(node.parent as Expression); - case SyntaxKind.VariableDeclaration: - return (ancestor as VariableDeclaration).initializer; - case SyntaxKind.BinaryExpression: - return (ancestor as BinaryExpression).right; - } - } - - function getDestructuringPropertyName(node: BindingElement | PropertyAssignment | ShorthandPropertyAssignment | Expression) { + case ts.SyntaxKind.BindingElement: + case ts.SyntaxKind.PropertyAssignment: + return getSyntheticElementAccess(ancestor as ts.BindingElement | ts.PropertyAssignment); + case ts.SyntaxKind.ArrayLiteralExpression: + return getSyntheticElementAccess(node.parent as ts.Expression); + case ts.SyntaxKind.VariableDeclaration: + return (ancestor as ts.VariableDeclaration).initializer; + case ts.SyntaxKind.BinaryExpression: + return (ancestor as ts.BinaryExpression).right; + } + } + function getDestructuringPropertyName(node: ts.BindingElement | ts.PropertyAssignment | ts.ShorthandPropertyAssignment | ts.Expression) { const parent = node.parent; - if (node.kind === SyntaxKind.BindingElement && parent.kind === SyntaxKind.ObjectBindingPattern) { - return getLiteralPropertyNameText((node as BindingElement).propertyName || (node as BindingElement).name as Identifier); + if (node.kind === ts.SyntaxKind.BindingElement && parent.kind === ts.SyntaxKind.ObjectBindingPattern) { + return getLiteralPropertyNameText((node as ts.BindingElement).propertyName || (node as ts.BindingElement).name as ts.Identifier); } - if (node.kind === SyntaxKind.PropertyAssignment || node.kind === SyntaxKind.ShorthandPropertyAssignment) { - return getLiteralPropertyNameText((node as PropertyAssignment | ShorthandPropertyAssignment).name); + if (node.kind === ts.SyntaxKind.PropertyAssignment || node.kind === ts.SyntaxKind.ShorthandPropertyAssignment) { + return getLiteralPropertyNameText((node as ts.PropertyAssignment | ts.ShorthandPropertyAssignment).name); } - return "" + ((parent as BindingPattern | ArrayLiteralExpression).elements as NodeArray).indexOf(node); + return "" + ((parent as ts.BindingPattern | ts.ArrayLiteralExpression).elements as ts.NodeArray).indexOf(node); } - function getLiteralPropertyNameText(name: PropertyName) { + function getLiteralPropertyNameText(name: ts.PropertyName) { const type = getLiteralTypeFromPropertyName(name); - return type.flags & (TypeFlags.StringLiteral | TypeFlags.NumberLiteral) ? "" + (type as StringLiteralType | NumberLiteralType).value : undefined; + return type.flags & (ts.TypeFlags.StringLiteral | ts.TypeFlags.NumberLiteral) ? "" + (type as ts.StringLiteralType | ts.NumberLiteralType).value : undefined; } /** Return the inferred type for a binding element */ - function getTypeForBindingElement(declaration: BindingElement): Type | undefined { + function getTypeForBindingElement(declaration: ts.BindingElement): ts.Type | undefined { const checkMode = declaration.dotDotDotToken ? CheckMode.RestBindingElement : CheckMode.Normal; const parentType = getTypeForBindingElementParent(declaration.parent.parent, checkMode); return parentType && getBindingElementTypeFromParentType(declaration, parentType); } - function getBindingElementTypeFromParentType(declaration: BindingElement, parentType: Type): Type { + function getBindingElementTypeFromParentType(declaration: ts.BindingElement, parentType: ts.Type): ts.Type { // If an any type was inferred for parent, infer that for the binding element if (isTypeAny(parentType)) { return parentType; } const pattern = declaration.parent; // Relax null check on ambient destructuring parameters, since the parameters have no implementation and are just documentation - if (strictNullChecks && declaration.flags & NodeFlags.Ambient && isParameterDeclaration(declaration)) { + if (strictNullChecks && declaration.flags & ts.NodeFlags.Ambient && ts.isParameterDeclaration(declaration)) { parentType = getNonNullableType(parentType); } // Filter `undefined` from the type we check against if the parent has an initializer and that initializer is not possibly `undefined` @@ -8830,27 +8407,27 @@ namespace ts { parentType = getTypeWithFacts(parentType, TypeFacts.NEUndefined); } - let type: Type | undefined; - if (pattern.kind === SyntaxKind.ObjectBindingPattern) { + let type: ts.Type | undefined; + if (pattern.kind === ts.SyntaxKind.ObjectBindingPattern) { if (declaration.dotDotDotToken) { parentType = getReducedType(parentType); - if (parentType.flags & TypeFlags.Unknown || !isValidSpreadType(parentType)) { - error(declaration, Diagnostics.Rest_types_may_only_be_created_from_object_types); + if (parentType.flags & ts.TypeFlags.Unknown || !isValidSpreadType(parentType)) { + error(declaration, ts.Diagnostics.Rest_types_may_only_be_created_from_object_types); return errorType; } - const literalMembers: PropertyName[] = []; + const literalMembers: ts.PropertyName[] = []; for (const element of pattern.elements) { if (!element.dotDotDotToken) { - literalMembers.push(element.propertyName || element.name as Identifier); + literalMembers.push(element.propertyName || element.name as ts.Identifier); } } type = getRestType(parentType, literalMembers, declaration.symbol); } else { // Use explicitly specified property name ({ p: xxx } form), or otherwise the implied name ({ p } form) - const name = declaration.propertyName || declaration.name as Identifier; + const name = declaration.propertyName || declaration.name as ts.Identifier; const indexType = getLiteralTypeFromPropertyName(name); - const declaredType = getIndexedAccessType(parentType, indexType, AccessFlags.ExpressionPosition, name); + const declaredType = getIndexedAccessType(parentType, indexType, ts.AccessFlags.ExpressionPosition, name); type = getFlowTypeOfDestructuring(declaration, declaredType); } } @@ -8865,12 +8442,12 @@ namespace ts { // remaining tuple element types. Otherwise, the rest element has an array type with same // element type as the parent type. type = everyType(parentType, isTupleType) ? - mapType(parentType, t => sliceTupleType(t as TupleTypeReference, index)) : + mapType(parentType, t => sliceTupleType(t as ts.TupleTypeReference, index)) : createArrayType(elementType); } else if (isArrayLikeType(parentType)) { const indexType = getNumberLiteralType(index); - const accessFlags = AccessFlags.ExpressionPosition | (hasDefaultValue(declaration) ? AccessFlags.NoTupleBoundsCheck : 0); + const accessFlags = ts.AccessFlags.ExpressionPosition | (hasDefaultValue(declaration) ? ts.AccessFlags.NoTupleBoundsCheck : 0); const declaredType = getIndexedAccessTypeOrUndefined(parentType, indexType, accessFlags, declaration.name) || errorType; type = getFlowTypeOfDestructuring(declaration, declaredType); } @@ -8881,50 +8458,46 @@ namespace ts { if (!declaration.initializer) { return type; } - if (getEffectiveTypeAnnotationNode(walkUpBindingElementsAndPatterns(declaration))) { + if (ts.getEffectiveTypeAnnotationNode(ts.walkUpBindingElementsAndPatterns(declaration))) { // In strict null checking mode, if a default value of a non-undefined type is specified, remove // undefined from the final type. - return strictNullChecks && !(getFalsyFlags(checkDeclarationInitializer(declaration, CheckMode.Normal)) & TypeFlags.Undefined) ? getNonUndefinedType(type) : type; + return strictNullChecks && !(getFalsyFlags(checkDeclarationInitializer(declaration, CheckMode.Normal)) & ts.TypeFlags.Undefined) ? getNonUndefinedType(type) : type; } - return widenTypeInferredFromInitializer(declaration, getUnionType([getNonUndefinedType(type), checkDeclarationInitializer(declaration, CheckMode.Normal)], UnionReduction.Subtype)); + return widenTypeInferredFromInitializer(declaration, getUnionType([getNonUndefinedType(type), checkDeclarationInitializer(declaration, CheckMode.Normal)], ts.UnionReduction.Subtype)); } - function getTypeForDeclarationFromJSDocComment(declaration: Node) { - const jsdocType = getJSDocType(declaration); + function getTypeForDeclarationFromJSDocComment(declaration: ts.Node) { + const jsdocType = ts.getJSDocType(declaration); if (jsdocType) { return getTypeFromTypeNode(jsdocType); } return undefined; } - function isNullOrUndefined(node: Expression) { - const expr = skipParentheses(node, /*excludeJSDocTypeAssertions*/ true); - return expr.kind === SyntaxKind.NullKeyword || expr.kind === SyntaxKind.Identifier && getResolvedSymbol(expr as Identifier) === undefinedSymbol; + function isNullOrUndefined(node: ts.Expression) { + const expr = ts.skipParentheses(node, /*excludeJSDocTypeAssertions*/ true); + return expr.kind === ts.SyntaxKind.NullKeyword || expr.kind === ts.SyntaxKind.Identifier && getResolvedSymbol(expr as ts.Identifier) === undefinedSymbol; } - function isEmptyArrayLiteral(node: Expression) { - const expr = skipParentheses(node, /*excludeJSDocTypeAssertions*/ true); - return expr.kind === SyntaxKind.ArrayLiteralExpression && (expr as ArrayLiteralExpression).elements.length === 0; + function isEmptyArrayLiteral(node: ts.Expression) { + const expr = ts.skipParentheses(node, /*excludeJSDocTypeAssertions*/ true); + return expr.kind === ts.SyntaxKind.ArrayLiteralExpression && (expr as ts.ArrayLiteralExpression).elements.length === 0; } - function addOptionality(type: Type, isProperty = false, isOptional = true): Type { + function addOptionality(type: ts.Type, isProperty = false, isOptional = true): ts.Type { return strictNullChecks && isOptional ? getOptionalType(type, isProperty) : type; } // Return the inferred type for a variable, parameter, or property declaration - function getTypeForVariableLikeDeclaration( - declaration: ParameterDeclaration | PropertyDeclaration | PropertySignature | VariableDeclaration | BindingElement | JSDocPropertyLikeTag, - includeOptionality: boolean, - checkMode: CheckMode, - ): Type | undefined { + function getTypeForVariableLikeDeclaration(declaration: ts.ParameterDeclaration | ts.PropertyDeclaration | ts.PropertySignature | ts.VariableDeclaration | ts.BindingElement | ts.JSDocPropertyLikeTag, includeOptionality: boolean, checkMode: CheckMode): ts.Type | undefined { // A variable declared in a for..in statement is of type string, or of type keyof T when the // right hand expression is of a type parameter type. - if (isVariableDeclaration(declaration) && declaration.parent.parent.kind === SyntaxKind.ForInStatement) { + if (ts.isVariableDeclaration(declaration) && declaration.parent.parent.kind === ts.SyntaxKind.ForInStatement) { const indexType = getIndexType(getNonNullableTypeIfNeeded(checkExpression(declaration.parent.parent.expression, /*checkMode*/ checkMode))); - return indexType.flags & (TypeFlags.TypeParameter | TypeFlags.Index) ? getExtractStringType(indexType) : stringType; + return indexType.flags & (ts.TypeFlags.TypeParameter | ts.TypeFlags.Index) ? getExtractStringType(indexType) : stringType; } - if (isVariableDeclaration(declaration) && declaration.parent.parent.kind === SyntaxKind.ForOfStatement) { + if (ts.isVariableDeclaration(declaration) && declaration.parent.parent.kind === ts.SyntaxKind.ForOfStatement) { // checkRightHandSideOfForOf will return undefined if the for-of expression type was // missing properties/signatures required to get its iteratedType (like // [Symbol.iterator] or next). This may be because we accessed properties from anyType, @@ -8933,14 +8506,13 @@ namespace ts { return checkRightHandSideOfForOf(forOfStatement) || anyType; } - if (isBindingPattern(declaration.parent)) { - return getTypeForBindingElement(declaration as BindingElement); + if (ts.isBindingPattern(declaration.parent)) { + return getTypeForBindingElement(declaration as ts.BindingElement); } - const isProperty = isPropertyDeclaration(declaration) || isPropertySignature(declaration); - const isOptional = includeOptionality && ( - isProperty && !!declaration.questionToken || - isParameter(declaration) && (!!declaration.questionToken || isJSDocOptionalParameter(declaration)) || + const isProperty = ts.isPropertyDeclaration(declaration) || ts.isPropertySignature(declaration); + const isOptional = includeOptionality && (isProperty && !!declaration.questionToken || + ts.isParameter(declaration) && (!!declaration.questionToken || isJSDocOptionalParameter(declaration)) || isOptionalJSDocPropertyLikeTag(declaration)); // Use type from type annotation if one is present @@ -8949,13 +8521,13 @@ namespace ts { return addOptionality(declaredType, isProperty, isOptional); } - if ((noImplicitAny || isInJSFile(declaration)) && - isVariableDeclaration(declaration) && !isBindingPattern(declaration.name) && - !(getCombinedModifierFlags(declaration) & ModifierFlags.Export) && !(declaration.flags & NodeFlags.Ambient)) { + if ((noImplicitAny || ts.isInJSFile(declaration)) && + ts.isVariableDeclaration(declaration) && !ts.isBindingPattern(declaration.name) && + !(ts.getCombinedModifierFlags(declaration) & ts.ModifierFlags.Export) && !(declaration.flags & ts.NodeFlags.Ambient)) { // If --noImplicitAny is on or the declaration is in a Javascript file, // use control flow tracked 'any' type for non-ambient, non-exported var or let variables with no // initializer or a 'null' or 'undefined' initializer. - if (!(getCombinedNodeFlags(declaration) & NodeFlags.Const) && (!declaration.initializer || isNullOrUndefined(declaration.initializer))) { + if (!(ts.getCombinedNodeFlags(declaration) & ts.NodeFlags.Const) && (!declaration.initializer || isNullOrUndefined(declaration.initializer))) { return autoType; } // Use control flow tracked 'any[]' type for non-ambient, non-exported variables with an empty array @@ -8965,28 +8537,29 @@ namespace ts { } } - if (isParameter(declaration)) { - const func = declaration.parent as FunctionLikeDeclaration; + if (ts.isParameter(declaration)) { + const func = declaration.parent as ts.FunctionLikeDeclaration; // For a parameter of a set accessor, use the type of the get accessor if one is present - if (func.kind === SyntaxKind.SetAccessor && hasBindableName(func)) { - const getter = getDeclarationOfKind(getSymbolOfNode(declaration.parent), SyntaxKind.GetAccessor); + if (func.kind === ts.SyntaxKind.SetAccessor && hasBindableName(func)) { + const getter = ts.getDeclarationOfKind(getSymbolOfNode(declaration.parent), ts.SyntaxKind.GetAccessor); if (getter) { const getterSignature = getSignatureFromDeclaration(getter); - const thisParameter = getAccessorThisParameter(func as AccessorDeclaration); + const thisParameter = getAccessorThisParameter(func as ts.AccessorDeclaration); if (thisParameter && declaration === thisParameter) { // Use the type from the *getter* - Debug.assert(!thisParameter.type); + ts.Debug.assert(!thisParameter.type); return getTypeOfSymbol(getterSignature.thisParameter!); } return getReturnTypeOfSignature(getterSignature); } } - if (isInJSFile(declaration)) { + if (ts.isInJSFile(declaration)) { const type = getParameterTypeOfTypeTag(func, declaration); - if (type) return type; + if (type) + return type; } // Use contextual parameter type if one is available - const type = declaration.symbol.escapedName === InternalSymbolName.This ? getContextualThisParameterType(func) : getContextuallyTypedParameterType(declaration); + const type = declaration.symbol.escapedName === ts.InternalSymbolName.This ? getContextualThisParameterType(func) : getContextuallyTypedParameterType(declaration); if (type) { return addOptionality(type, /*isProperty*/ false, isOptional); } @@ -8994,9 +8567,9 @@ namespace ts { // Use the type of the initializer expression if one is present and the declaration is // not a parameter of a contextually typed function - if (hasOnlyExpressionInitializer(declaration) && !!declaration.initializer) { - if (isInJSFile(declaration) && !isParameter(declaration)) { - const containerObjectType = getJSContainerObjectType(declaration, getSymbolOfNode(declaration), getDeclaredExpandoInitializer(declaration)); + if (ts.hasOnlyExpressionInitializer(declaration) && !!declaration.initializer) { + if (ts.isInJSFile(declaration) && !ts.isParameter(declaration)) { + const containerObjectType = getJSContainerObjectType(declaration, getSymbolOfNode(declaration), ts.getDeclaredExpandoInitializer(declaration)); if (containerObjectType) { return containerObjectType; } @@ -9005,26 +8578,26 @@ namespace ts { return addOptionality(type, isProperty, isOptional); } - if (isPropertyDeclaration(declaration) && (noImplicitAny || isInJSFile(declaration))) { + if (ts.isPropertyDeclaration(declaration) && (noImplicitAny || ts.isInJSFile(declaration))) { // We have a property declaration with no type annotation or initializer, in noImplicitAny mode or a .js file. // Use control flow analysis of this.xxx assignments in the constructor or static block to determine the type of the property. - if (!hasStaticModifier(declaration)) { + if (!ts.hasStaticModifier(declaration)) { const constructor = findConstructorDeclaration(declaration.parent); const type = constructor ? getFlowTypeInConstructor(declaration.symbol, constructor) : - getEffectiveModifierFlags(declaration) & ModifierFlags.Ambient ? getTypeOfPropertyInBaseClass(declaration.symbol) : + ts.getEffectiveModifierFlags(declaration) & ts.ModifierFlags.Ambient ? getTypeOfPropertyInBaseClass(declaration.symbol) : undefined; return type && addOptionality(type, /*isProperty*/ true, isOptional); } else { - const staticBlocks = filter(declaration.parent.members, isClassStaticBlockDeclaration); + const staticBlocks = ts.filter(declaration.parent.members, ts.isClassStaticBlockDeclaration); const type = staticBlocks.length ? getFlowTypeInStaticBlocks(declaration.symbol, staticBlocks) : - getEffectiveModifierFlags(declaration) & ModifierFlags.Ambient ? getTypeOfPropertyInBaseClass(declaration.symbol) : + ts.getEffectiveModifierFlags(declaration) & ts.ModifierFlags.Ambient ? getTypeOfPropertyInBaseClass(declaration.symbol) : undefined; return type && addOptionality(type, /*isProperty*/ true, isOptional); } } - if (isJsxAttribute(declaration)) { + if (ts.isJsxAttribute(declaration)) { // if JSX attribute doesn't have initializer, by default the attribute will have boolean value of true. // I.e is sugar for return trueType; @@ -9032,7 +8605,7 @@ namespace ts { // If the declaration specifies a binding pattern and is not a parameter of a contextually // typed function, use the type implied by the binding pattern - if (isBindingPattern(declaration.name)) { + if (ts.isBindingPattern(declaration.name)) { return getTypeFromBindingPattern(declaration.name, /*includePatternInType*/ false, /*reportErrors*/ true); } @@ -9040,18 +8613,17 @@ namespace ts { return undefined; } - function isConstructorDeclaredProperty(symbol: Symbol) { + function isConstructorDeclaredProperty(symbol: ts.Symbol) { // A property is considered a constructor declared property when all declaration sites are this.xxx assignments, // when no declaration sites have JSDoc type annotations, and when at least one declaration site is in the body of // a class constructor. - if (symbol.valueDeclaration && isBinaryExpression(symbol.valueDeclaration)) { + if (symbol.valueDeclaration && ts.isBinaryExpression(symbol.valueDeclaration)) { const links = getSymbolLinks(symbol); if (links.isConstructorDeclaredProperty === undefined) { links.isConstructorDeclaredProperty = false; - links.isConstructorDeclaredProperty = !!getDeclaringConstructor(symbol) && every(symbol.declarations, declaration => - isBinaryExpression(declaration) && + links.isConstructorDeclaredProperty = !!getDeclaringConstructor(symbol) && ts.every(symbol.declarations, declaration => ts.isBinaryExpression(declaration) && isPossiblyAliasedThisProperty(declaration) && - (declaration.left.kind !== SyntaxKind.ElementAccessExpression || isStringOrNumericLiteralLike((declaration.left as ElementAccessExpression).argumentExpression)) && + (declaration.left.kind !== ts.SyntaxKind.ElementAccessExpression || ts.isStringOrNumericLiteralLike((declaration.left as ts.ElementAccessExpression).argumentExpression)) && !getAnnotatedTypeForAssignmentDeclaration(/*declaredType*/ undefined, declaration, symbol, declaration)); } return links.isConstructorDeclaredProperty; @@ -9059,55 +8631,56 @@ namespace ts { return false; } - function isAutoTypedProperty(symbol: Symbol) { + function isAutoTypedProperty(symbol: ts.Symbol) { // A property is auto-typed when its declaration has no type annotation or initializer and we're in // noImplicitAny mode or a .js file. const declaration = symbol.valueDeclaration; - return declaration && isPropertyDeclaration(declaration) && !getEffectiveTypeAnnotationNode(declaration) && - !declaration.initializer && (noImplicitAny || isInJSFile(declaration)); + return declaration && ts.isPropertyDeclaration(declaration) && !ts.getEffectiveTypeAnnotationNode(declaration) && + !declaration.initializer && (noImplicitAny || ts.isInJSFile(declaration)); } - function getDeclaringConstructor(symbol: Symbol) { + function getDeclaringConstructor(symbol: ts.Symbol) { if (!symbol.declarations) { return; } for (const declaration of symbol.declarations) { - const container = getThisContainer(declaration, /*includeArrowFunctions*/ false); - if (container && (container.kind === SyntaxKind.Constructor || isJSConstructor(container))) { - return container as ConstructorDeclaration; + const container = ts.getThisContainer(declaration, /*includeArrowFunctions*/ false); + if (container && (container.kind === ts.SyntaxKind.Constructor || isJSConstructor(container))) { + return container as ts.ConstructorDeclaration; } - }; } + ; + } /** Create a synthetic property access flow node after the last statement of the file */ - function getFlowTypeFromCommonJSExport(symbol: Symbol) { - const file = getSourceFileOfNode(symbol.declarations![0]); - const accessName = unescapeLeadingUnderscores(symbol.escapedName); - const areAllModuleExports = symbol.declarations!.every(d => isInJSFile(d) && isAccessExpression(d) && isModuleExportsAccessExpression(d.expression)); + function getFlowTypeFromCommonJSExport(symbol: ts.Symbol) { + const file = ts.getSourceFileOfNode(symbol.declarations![0]); + const accessName = ts.unescapeLeadingUnderscores(symbol.escapedName); + const areAllModuleExports = symbol.declarations!.every(d => ts.isInJSFile(d) && ts.isAccessExpression(d) && ts.isModuleExportsAccessExpression(d.expression)); const reference = areAllModuleExports - ? factory.createPropertyAccessExpression(factory.createPropertyAccessExpression(factory.createIdentifier("module"), factory.createIdentifier("exports")), accessName) - : factory.createPropertyAccessExpression(factory.createIdentifier("exports"), accessName); + ? ts.factory.createPropertyAccessExpression(ts.factory.createPropertyAccessExpression(ts.factory.createIdentifier("module"), ts.factory.createIdentifier("exports")), accessName) + : ts.factory.createPropertyAccessExpression(ts.factory.createIdentifier("exports"), accessName); if (areAllModuleExports) { - setParent((reference.expression as PropertyAccessExpression).expression, reference.expression); + ts.setParent((reference.expression as ts.PropertyAccessExpression).expression, reference.expression); } - setParent(reference.expression, reference); - setParent(reference, file); + ts.setParent(reference.expression, reference); + ts.setParent(reference, file); reference.flowNode = file.endFlowNode; return getFlowTypeOfReference(reference, autoType, undefinedType); } - function getFlowTypeInStaticBlocks(symbol: Symbol, staticBlocks: readonly ClassStaticBlockDeclaration[]) { - const accessName = startsWith(symbol.escapedName as string, "__#") - ? factory.createPrivateIdentifier((symbol.escapedName as string).split("@")[1]) - : unescapeLeadingUnderscores(symbol.escapedName); + function getFlowTypeInStaticBlocks(symbol: ts.Symbol, staticBlocks: readonly ts.ClassStaticBlockDeclaration[]) { + const accessName = ts.startsWith(symbol.escapedName as string, "__#") + ? ts.factory.createPrivateIdentifier((symbol.escapedName as string).split("@")[1]) + : ts.unescapeLeadingUnderscores(symbol.escapedName); for (const staticBlock of staticBlocks) { - const reference = factory.createPropertyAccessExpression(factory.createThis(), accessName); - setParent(reference.expression, reference); - setParent(reference, staticBlock); + const reference = ts.factory.createPropertyAccessExpression(ts.factory.createThis(), accessName); + ts.setParent(reference.expression, reference); + ts.setParent(reference, staticBlock); reference.flowNode = staticBlock.returnFlowNode; const flowType = getFlowTypeOfProperty(reference, symbol); if (noImplicitAny && (flowType === autoType || flowType === autoArrayType)) { - error(symbol.valueDeclaration, Diagnostics.Member_0_implicitly_has_an_1_type, symbolToString(symbol), typeToString(flowType)); + error(symbol.valueDeclaration, ts.Diagnostics.Member_0_implicitly_has_an_1_type, symbolToString(symbol), typeToString(flowType)); } // We don't infer a type if assignments are only null or undefined. if (everyType(flowType, isNullableType)) { @@ -9117,35 +8690,35 @@ namespace ts { } } - function getFlowTypeInConstructor(symbol: Symbol, constructor: ConstructorDeclaration) { - const accessName = startsWith(symbol.escapedName as string, "__#") - ? factory.createPrivateIdentifier((symbol.escapedName as string).split("@")[1]) - : unescapeLeadingUnderscores(symbol.escapedName); - const reference = factory.createPropertyAccessExpression(factory.createThis(), accessName); - setParent(reference.expression, reference); - setParent(reference, constructor); + function getFlowTypeInConstructor(symbol: ts.Symbol, constructor: ts.ConstructorDeclaration) { + const accessName = ts.startsWith(symbol.escapedName as string, "__#") + ? ts.factory.createPrivateIdentifier((symbol.escapedName as string).split("@")[1]) + : ts.unescapeLeadingUnderscores(symbol.escapedName); + const reference = ts.factory.createPropertyAccessExpression(ts.factory.createThis(), accessName); + ts.setParent(reference.expression, reference); + ts.setParent(reference, constructor); reference.flowNode = constructor.returnFlowNode; const flowType = getFlowTypeOfProperty(reference, symbol); if (noImplicitAny && (flowType === autoType || flowType === autoArrayType)) { - error(symbol.valueDeclaration, Diagnostics.Member_0_implicitly_has_an_1_type, symbolToString(symbol), typeToString(flowType)); + error(symbol.valueDeclaration, ts.Diagnostics.Member_0_implicitly_has_an_1_type, symbolToString(symbol), typeToString(flowType)); } // We don't infer a type if assignments are only null or undefined. return everyType(flowType, isNullableType) ? undefined : convertAutoToAny(flowType); } - function getFlowTypeOfProperty(reference: Node, prop: Symbol | undefined) { + function getFlowTypeOfProperty(reference: ts.Node, prop: ts.Symbol | undefined) { const initialType = prop?.valueDeclaration - && (!isAutoTypedProperty(prop) || getEffectiveModifierFlags(prop.valueDeclaration) & ModifierFlags.Ambient) + && (!isAutoTypedProperty(prop) || ts.getEffectiveModifierFlags(prop.valueDeclaration) & ts.ModifierFlags.Ambient) && getTypeOfPropertyInBaseClass(prop) || undefinedType; return getFlowTypeOfReference(reference, autoType, initialType); } - function getWidenedTypeForAssignmentDeclaration(symbol: Symbol, resolvedSymbol?: Symbol) { + function getWidenedTypeForAssignmentDeclaration(symbol: ts.Symbol, resolvedSymbol?: ts.Symbol) { // function/class/{} initializers are themselves containers, so they won't merge in the same way as other initializers - const container = getAssignedExpandoInitializer(symbol.valueDeclaration); + const container = ts.getAssignedExpandoInitializer(symbol.valueDeclaration); if (container) { - const tag = getJSDocTypeTag(container); + const tag = ts.getJSDocTypeTag(container); if (tag && tag.typeExpression) { return getTypeFromTypeNode(tag.typeExpression); } @@ -9161,21 +8734,21 @@ namespace ts { type = getFlowTypeInConstructor(symbol, getDeclaringConstructor(symbol)!); } if (!type) { - let types: Type[] | undefined; + let types: ts.Type[] | undefined; if (symbol.declarations) { - let jsdocType: Type | undefined; + let jsdocType: ts.Type | undefined; for (const declaration of symbol.declarations) { - const expression = (isBinaryExpression(declaration) || isCallExpression(declaration)) ? declaration : - isAccessExpression(declaration) ? isBinaryExpression(declaration.parent) ? declaration.parent : declaration : + const expression = (ts.isBinaryExpression(declaration) || ts.isCallExpression(declaration)) ? declaration : + ts.isAccessExpression(declaration) ? ts.isBinaryExpression(declaration.parent) ? declaration.parent : declaration : undefined; if (!expression) { continue; // Non-assignment declaration merged in (eg, an Identifier to mark the thing as a namespace) - skip over it and pull type info from elsewhere } - const kind = isAccessExpression(expression) - ? getAssignmentDeclarationPropertyAccessKind(expression) - : getAssignmentDeclarationKind(expression); - if (kind === AssignmentDeclarationKind.ThisProperty || isBinaryExpression(expression) && isPossiblyAliasedThisProperty(expression, kind)) { + const kind = ts.isAccessExpression(expression) + ? ts.getAssignmentDeclarationPropertyAccessKind(expression) + : ts.getAssignmentDeclarationKind(expression); + if (kind === ts.AssignmentDeclarationKind.ThisProperty || ts.isBinaryExpression(expression) && isPossiblyAliasedThisProperty(expression, kind)) { if (isDeclarationInConstructor(expression)) { definedInConstructor = true; } @@ -9183,17 +8756,17 @@ namespace ts { definedInMethod = true; } } - if (!isCallExpression(expression)) { + if (!ts.isCallExpression(expression)) { jsdocType = getAnnotatedTypeForAssignmentDeclaration(jsdocType, expression, symbol, declaration); } if (!jsdocType) { - (types || (types = [])).push((isBinaryExpression(expression) || isCallExpression(expression)) ? getInitializerTypeFromAssignmentDeclaration(symbol, resolvedSymbol, expression, kind) : neverType); + (types || (types = [])).push((ts.isBinaryExpression(expression) || ts.isCallExpression(expression)) ? getInitializerTypeFromAssignmentDeclaration(symbol, resolvedSymbol, expression, kind) : neverType); } } type = jsdocType; } if (!type) { - if (!length(types)) { + if (!ts.length(types)) { return errorType; // No types from any declarations :( } let constructorTypes = definedInConstructor && symbol.declarations ? getConstructorDefinedThisAssignmentTypes(types!, symbol.declarations) : undefined; @@ -9205,41 +8778,41 @@ namespace ts { definedInConstructor = true; } } - const sourceTypes = some(constructorTypes, t => !!(t.flags & ~TypeFlags.Nullable)) ? constructorTypes : types; // TODO: GH#18217 + const sourceTypes = ts.some(constructorTypes, t => !!(t.flags & ~ts.TypeFlags.Nullable)) ? constructorTypes : types; // TODO: GH#18217 type = getUnionType(sourceTypes!); } } const widened = getWidenedType(addOptionality(type, /*isProperty*/ false, definedInMethod && !definedInConstructor)); - if (symbol.valueDeclaration && filterType(widened, t => !!(t.flags & ~TypeFlags.Nullable)) === neverType) { + if (symbol.valueDeclaration && filterType(widened, t => !!(t.flags & ~ts.TypeFlags.Nullable)) === neverType) { reportImplicitAny(symbol.valueDeclaration, anyType); return anyType; } return widened; } - function getJSContainerObjectType(decl: Node, symbol: Symbol, init: Expression | undefined): Type | undefined { - if (!isInJSFile(decl) || !init || !isObjectLiteralExpression(init) || init.properties.length) { + function getJSContainerObjectType(decl: ts.Node, symbol: ts.Symbol, init: ts.Expression | undefined): ts.Type | undefined { + if (!ts.isInJSFile(decl) || !init || !ts.isObjectLiteralExpression(init) || init.properties.length) { return undefined; } - const exports = createSymbolTable(); - while (isBinaryExpression(decl) || isPropertyAccessExpression(decl)) { + const exports = ts.createSymbolTable(); + while (ts.isBinaryExpression(decl) || ts.isPropertyAccessExpression(decl)) { const s = getSymbolOfNode(decl); if (s?.exports?.size) { mergeSymbolTable(exports, s.exports); } - decl = isBinaryExpression(decl) ? decl.parent : decl.parent.parent; + decl = ts.isBinaryExpression(decl) ? decl.parent : decl.parent.parent; } const s = getSymbolOfNode(decl); if (s?.exports?.size) { mergeSymbolTable(exports, s.exports); } - const type = createAnonymousType(symbol, exports, emptyArray, emptyArray, emptyArray); - type.objectFlags |= ObjectFlags.JSLiteral; + const type = createAnonymousType(symbol, exports, ts.emptyArray, ts.emptyArray, ts.emptyArray); + type.objectFlags |= ts.ObjectFlags.JSLiteral; return type; } - function getAnnotatedTypeForAssignmentDeclaration(declaredType: Type | undefined, expression: Expression, symbol: Symbol, declaration: Declaration) { - const typeNode = getEffectiveTypeAnnotationNode(expression.parent); + function getAnnotatedTypeForAssignmentDeclaration(declaredType: ts.Type | undefined, expression: ts.Expression, symbol: ts.Symbol, declaration: ts.Declaration) { + const typeNode = ts.getEffectiveTypeAnnotationNode(expression.parent); if (typeNode) { const type = getWidenedType(getTypeFromTypeNode(typeNode)); if (!declaredType) { @@ -9250,7 +8823,7 @@ namespace ts { } } if (symbol.parent?.valueDeclaration) { - const typeNode = getEffectiveTypeAnnotationNode(symbol.parent.valueDeclaration); + const typeNode = ts.getEffectiveTypeAnnotationNode(symbol.parent.valueDeclaration); if (typeNode) { const annotationSymbol = getPropertyOfType(getTypeFromTypeNode(typeNode), symbol.escapedName); if (annotationSymbol) { @@ -9263,24 +8836,24 @@ namespace ts { } /** If we don't have an explicit JSDoc type, get the type from the initializer. */ - function getInitializerTypeFromAssignmentDeclaration(symbol: Symbol, resolvedSymbol: Symbol | undefined, expression: BinaryExpression | CallExpression, kind: AssignmentDeclarationKind) { - if (isCallExpression(expression)) { + function getInitializerTypeFromAssignmentDeclaration(symbol: ts.Symbol, resolvedSymbol: ts.Symbol | undefined, expression: ts.BinaryExpression | ts.CallExpression, kind: ts.AssignmentDeclarationKind) { + if (ts.isCallExpression(expression)) { if (resolvedSymbol) { return getTypeOfSymbol(resolvedSymbol); // This shouldn't happen except under some hopefully forbidden merges of export assignments and object define assignments } - const objectLitType = checkExpressionCached((expression as BindableObjectDefinePropertyCall).arguments[2]); - const valueType = getTypeOfPropertyOfType(objectLitType, "value" as __String); + const objectLitType = checkExpressionCached((expression as ts.BindableObjectDefinePropertyCall).arguments[2]); + const valueType = getTypeOfPropertyOfType(objectLitType, "value" as ts.__String); if (valueType) { return valueType; } - const getFunc = getTypeOfPropertyOfType(objectLitType, "get" as __String); + const getFunc = getTypeOfPropertyOfType(objectLitType, "get" as ts.__String); if (getFunc) { const getSig = getSingleCallSignature(getFunc); if (getSig) { return getReturnTypeOfSignature(getSig); } } - const setFunc = getTypeOfPropertyOfType(objectLitType, "set" as __String); + const setFunc = getTypeOfPropertyOfType(objectLitType, "set" as ts.__String); if (setFunc) { const setSig = getSingleCallSignature(setFunc); if (setSig) { @@ -9292,24 +8865,24 @@ namespace ts { if (containsSameNamedThisProperty(expression.left, expression.right)) { return anyType; } - const isDirectExport = kind === AssignmentDeclarationKind.ExportsProperty && (isPropertyAccessExpression(expression.left) || isElementAccessExpression(expression.left)) && (isModuleExportsAccessExpression(expression.left.expression) || (isIdentifier(expression.left.expression) && isExportsIdentifier(expression.left.expression))); + const isDirectExport = kind === ts.AssignmentDeclarationKind.ExportsProperty && (ts.isPropertyAccessExpression(expression.left) || ts.isElementAccessExpression(expression.left)) && (ts.isModuleExportsAccessExpression(expression.left.expression) || (ts.isIdentifier(expression.left.expression) && ts.isExportsIdentifier(expression.left.expression))); const type = resolvedSymbol ? getTypeOfSymbol(resolvedSymbol) : isDirectExport ? getRegularTypeOfLiteralType(checkExpressionCached(expression.right)) : getWidenedLiteralType(checkExpressionCached(expression.right)); - if (type.flags & TypeFlags.Object && - kind === AssignmentDeclarationKind.ModuleExports && - symbol.escapedName === InternalSymbolName.ExportEquals) { - const exportedType = resolveStructuredTypeMembers(type as ObjectType); - const members = createSymbolTable(); - copyEntries(exportedType.members, members); + if (type.flags & ts.TypeFlags.Object && + kind === ts.AssignmentDeclarationKind.ModuleExports && + symbol.escapedName === ts.InternalSymbolName.ExportEquals) { + const exportedType = resolveStructuredTypeMembers(type as ts.ObjectType); + const members = ts.createSymbolTable(); + ts.copyEntries(exportedType.members, members); const initialSize = members.size; if (resolvedSymbol && !resolvedSymbol.exports) { - resolvedSymbol.exports = createSymbolTable(); + resolvedSymbol.exports = ts.createSymbolTable(); } (resolvedSymbol || symbol).exports!.forEach((s, name) => { const exportedMember = members.get(name)!; if (exportedMember && exportedMember !== s) { - if (s.flags & SymbolFlags.Value && exportedMember.flags & SymbolFlags.Value) { + if (s.flags & ts.SymbolFlags.Value && exportedMember.flags & ts.SymbolFlags.Value) { // If the member has an additional value-like declaration, union the types from the two declarations, // but issue an error if they occurred in two different files. The purpose is to support a JS file with // a pattern like: @@ -9320,20 +8893,16 @@ namespace ts { // but we may have a JS file with `module.exports = { a: true }` along with a TypeScript module augmentation // declaring an `export const a: number`. In that case, we issue a duplicate identifier error, because // it's unclear what that's supposed to mean, so it's probably a mistake. - if (s.valueDeclaration && exportedMember.valueDeclaration && getSourceFileOfNode(s.valueDeclaration) !== getSourceFileOfNode(exportedMember.valueDeclaration)) { - const unescapedName = unescapeLeadingUnderscores(s.escapedName); - const exportedMemberName = tryCast(exportedMember.valueDeclaration, isNamedDeclaration)?.name || exportedMember.valueDeclaration; - addRelatedInfo( - error(s.valueDeclaration, Diagnostics.Duplicate_identifier_0, unescapedName), - createDiagnosticForNode(exportedMemberName, Diagnostics._0_was_also_declared_here, unescapedName)); - addRelatedInfo( - error(exportedMemberName, Diagnostics.Duplicate_identifier_0, unescapedName), - createDiagnosticForNode(s.valueDeclaration, Diagnostics._0_was_also_declared_here, unescapedName)); + if (s.valueDeclaration && exportedMember.valueDeclaration && ts.getSourceFileOfNode(s.valueDeclaration) !== ts.getSourceFileOfNode(exportedMember.valueDeclaration)) { + const unescapedName = ts.unescapeLeadingUnderscores(s.escapedName); + const exportedMemberName = ts.tryCast(exportedMember.valueDeclaration, ts.isNamedDeclaration)?.name || exportedMember.valueDeclaration; + ts.addRelatedInfo(error(s.valueDeclaration, ts.Diagnostics.Duplicate_identifier_0, unescapedName), ts.createDiagnosticForNode(exportedMemberName, ts.Diagnostics._0_was_also_declared_here, unescapedName)); + ts.addRelatedInfo(error(exportedMemberName, ts.Diagnostics.Duplicate_identifier_0, unescapedName), ts.createDiagnosticForNode(s.valueDeclaration, ts.Diagnostics._0_was_also_declared_here, unescapedName)); } const union = createSymbol(s.flags | exportedMember.flags, name); union.type = getUnionType([getTypeOfSymbol(s), getTypeOfSymbol(exportedMember)]); union.valueDeclaration = exportedMember.valueDeclaration; - union.declarations = concatenate(exportedMember.declarations, s.declarations); + union.declarations = ts.concatenate(exportedMember.declarations, s.declarations); members.set(name, union); } else { @@ -9344,15 +8913,11 @@ namespace ts { members.set(name, s); } }); - const result = createAnonymousType( - initialSize !== members.size ? undefined : exportedType.symbol, // Only set the type's symbol if it looks to be the same as the original type - members, - exportedType.callSignatures, - exportedType.constructSignatures, - exportedType.indexInfos); - result.objectFlags |= (getObjectFlags(type) & ObjectFlags.JSLiteral); // Propagate JSLiteral flag - if (result.symbol && result.symbol.flags & SymbolFlags.Class && type === getDeclaredTypeOfClassOrInterface(result.symbol)) { - result.objectFlags |= ObjectFlags.IsClassInstanceClone; // Propagate the knowledge that this type is equivalent to the symbol's class instance type + const result = createAnonymousType(initialSize !== members.size ? undefined : exportedType.symbol, // Only set the type's symbol if it looks to be the same as the original type + members, exportedType.callSignatures, exportedType.constructSignatures, exportedType.indexInfos); + result.objectFlags |= (ts.getObjectFlags(type) & ts.ObjectFlags.JSLiteral); // Propagate JSLiteral flag + if (result.symbol && result.symbol.flags & ts.SymbolFlags.Class && type === getDeclaredTypeOfClassOrInterface(result.symbol)) { + result.objectFlags |= ts.ObjectFlags.IsClassInstanceClone; // Propagate the knowledge that this type is equivalent to the symbol's class instance type } return result; } @@ -9363,27 +8928,27 @@ namespace ts { return type; } - function containsSameNamedThisProperty(thisProperty: Expression, expression: Expression) { - return isPropertyAccessExpression(thisProperty) - && thisProperty.expression.kind === SyntaxKind.ThisKeyword - && forEachChildRecursively(expression, n => isMatchingReference(thisProperty, n)); + function containsSameNamedThisProperty(thisProperty: ts.Expression, expression: ts.Expression) { + return ts.isPropertyAccessExpression(thisProperty) + && thisProperty.expression.kind === ts.SyntaxKind.ThisKeyword + && ts.forEachChildRecursively(expression, n => isMatchingReference(thisProperty, n)); } - function isDeclarationInConstructor(expression: Expression) { - const thisContainer = getThisContainer(expression, /*includeArrowFunctions*/ false); + function isDeclarationInConstructor(expression: ts.Expression) { + const thisContainer = ts.getThisContainer(expression, /*includeArrowFunctions*/ false); // Properties defined in a constructor (or base constructor, or javascript constructor function) don't get undefined added. // Function expressions that are assigned to the prototype count as methods. - return thisContainer.kind === SyntaxKind.Constructor || - thisContainer.kind === SyntaxKind.FunctionDeclaration || - (thisContainer.kind === SyntaxKind.FunctionExpression && !isPrototypePropertyAssignment(thisContainer.parent)); + return thisContainer.kind === ts.SyntaxKind.Constructor || + thisContainer.kind === ts.SyntaxKind.FunctionDeclaration || + (thisContainer.kind === ts.SyntaxKind.FunctionExpression && !ts.isPrototypePropertyAssignment(thisContainer.parent)); } - function getConstructorDefinedThisAssignmentTypes(types: Type[], declarations: Declaration[]): Type[] | undefined { - Debug.assert(types.length === declarations.length); + function getConstructorDefinedThisAssignmentTypes(types: ts.Type[], declarations: ts.Declaration[]): ts.Type[] | undefined { + ts.Debug.assert(types.length === declarations.length); return types.filter((_, i) => { const declaration = declarations[i]; - const expression = isBinaryExpression(declaration) ? declaration : - isBinaryExpression(declaration.parent) ? declaration.parent : undefined; + const expression = ts.isBinaryExpression(declaration) ? declaration : + ts.isBinaryExpression(declaration.parent) ? declaration.parent : undefined; return expression && isDeclarationInConstructor(expression); }); } @@ -9391,15 +8956,15 @@ namespace ts { // Return the type implied by a binding pattern element. This is the type of the initializer of the element if // one is present. Otherwise, if the element is itself a binding pattern, it is the type implied by the binding // pattern. Otherwise, it is the type any. - function getTypeFromBindingElement(element: BindingElement, includePatternInType?: boolean, reportErrors?: boolean): Type { + function getTypeFromBindingElement(element: ts.BindingElement, includePatternInType?: boolean, reportErrors?: boolean): ts.Type { if (element.initializer) { // The type implied by a binding pattern is independent of context, so we check the initializer with no // contextual type or, if the element itself is a binding pattern, with the type implied by that binding // pattern. - const contextualType = isBindingPattern(element.name) ? getTypeFromBindingPattern(element.name, /*includePatternInType*/ true, /*reportErrors*/ false) : unknownType; + const contextualType = ts.isBindingPattern(element.name) ? getTypeFromBindingPattern(element.name, /*includePatternInType*/ true, /*reportErrors*/ false) : unknownType; return addOptionality(widenTypeInferredFromInitializer(element, checkDeclarationInitializer(element, CheckMode.Normal, contextualType))); } - if (isBindingPattern(element.name)) { + if (ts.isBindingPattern(element.name)) { return getTypeFromBindingPattern(element.name, includePatternInType, reportErrors); } if (reportErrors && !declarationBelongsToPrivateAmbientMember(element)) { @@ -9413,12 +8978,12 @@ namespace ts { } // Return the type implied by an object binding pattern - function getTypeFromObjectBindingPattern(pattern: ObjectBindingPattern, includePatternInType: boolean, reportErrors: boolean): Type { - const members = createSymbolTable(); - let stringIndexInfo: IndexInfo | undefined; - let objectFlags = ObjectFlags.ObjectLiteral | ObjectFlags.ContainsObjectOrArrayLiteral; - forEach(pattern.elements, e => { - const name = e.propertyName || e.name as Identifier; + function getTypeFromObjectBindingPattern(pattern: ts.ObjectBindingPattern, includePatternInType: boolean, reportErrors: boolean): ts.Type { + const members = ts.createSymbolTable(); + let stringIndexInfo: ts.IndexInfo | undefined; + let objectFlags = ts.ObjectFlags.ObjectLiteral | ts.ObjectFlags.ContainsObjectOrArrayLiteral; + ts.forEach(pattern.elements, e => { + const name = e.propertyName || e.name as ts.Identifier; if (e.dotDotDotToken) { stringIndexInfo = createIndexInfo(stringType, anyType, /*isReadonly*/ false); return; @@ -9427,41 +8992,41 @@ namespace ts { const exprType = getLiteralTypeFromPropertyName(name); if (!isTypeUsableAsPropertyName(exprType)) { // do not include computed properties in the implied type - objectFlags |= ObjectFlags.ObjectLiteralPatternWithComputedProperties; + objectFlags |= ts.ObjectFlags.ObjectLiteralPatternWithComputedProperties; return; } const text = getPropertyNameFromType(exprType); - const flags = SymbolFlags.Property | (e.initializer ? SymbolFlags.Optional : 0); + const flags = ts.SymbolFlags.Property | (e.initializer ? ts.SymbolFlags.Optional : 0); const symbol = createSymbol(flags, text); symbol.type = getTypeFromBindingElement(e, includePatternInType, reportErrors); symbol.bindingElement = e; members.set(symbol.escapedName, symbol); }); - const result = createAnonymousType(undefined, members, emptyArray, emptyArray, stringIndexInfo ? [stringIndexInfo] : emptyArray); + const result = createAnonymousType(undefined, members, ts.emptyArray, ts.emptyArray, stringIndexInfo ? [stringIndexInfo] : ts.emptyArray); result.objectFlags |= objectFlags; if (includePatternInType) { result.pattern = pattern; - result.objectFlags |= ObjectFlags.ContainsObjectOrArrayLiteral; + result.objectFlags |= ts.ObjectFlags.ContainsObjectOrArrayLiteral; } return result; } // Return the type implied by an array binding pattern - function getTypeFromArrayBindingPattern(pattern: BindingPattern, includePatternInType: boolean, reportErrors: boolean): Type { + function getTypeFromArrayBindingPattern(pattern: ts.BindingPattern, includePatternInType: boolean, reportErrors: boolean): ts.Type { const elements = pattern.elements; - const lastElement = lastOrUndefined(elements); - const restElement = lastElement && lastElement.kind === SyntaxKind.BindingElement && lastElement.dotDotDotToken ? lastElement : undefined; + const lastElement = ts.lastOrUndefined(elements); + const restElement = lastElement && lastElement.kind === ts.SyntaxKind.BindingElement && lastElement.dotDotDotToken ? lastElement : undefined; if (elements.length === 0 || elements.length === 1 && restElement) { - return languageVersion >= ScriptTarget.ES2015 ? createIterableType(anyType) : anyArrayType; + return languageVersion >= ts.ScriptTarget.ES2015 ? createIterableType(anyType) : anyArrayType; } - const elementTypes = map(elements, e => isOmittedExpression(e) ? anyType : getTypeFromBindingElement(e, includePatternInType, reportErrors)); - const minLength = findLastIndex(elements, e => !(e === restElement || isOmittedExpression(e) || hasDefaultValue(e)), elements.length - 1) + 1; - const elementFlags = map(elements, (e, i) => e === restElement ? ElementFlags.Rest : i >= minLength ? ElementFlags.Optional : ElementFlags.Required); - let result = createTupleType(elementTypes, elementFlags) as TypeReference; + const elementTypes = ts.map(elements, e => ts.isOmittedExpression(e) ? anyType : getTypeFromBindingElement(e, includePatternInType, reportErrors)); + const minLength = ts.findLastIndex(elements, e => !(e === restElement || ts.isOmittedExpression(e) || hasDefaultValue(e)), elements.length - 1) + 1; + const elementFlags = ts.map(elements, (e, i) => e === restElement ? ts.ElementFlags.Rest : i >= minLength ? ts.ElementFlags.Optional : ts.ElementFlags.Required); + let result = createTupleType(elementTypes, elementFlags) as ts.TypeReference; if (includePatternInType) { result = cloneTypeReference(result); result.pattern = pattern; - result.objectFlags |= ObjectFlags.ContainsObjectOrArrayLiteral; + result.objectFlags |= ts.ObjectFlags.ContainsObjectOrArrayLiteral; } return result; } @@ -9473,8 +9038,8 @@ namespace ts { // used as the contextual type of an initializer associated with the binding pattern. Also, for a destructuring // parameter with no type annotation or initializer, the type implied by the binding pattern becomes the type of // the parameter. - function getTypeFromBindingPattern(pattern: BindingPattern, includePatternInType = false, reportErrors = false): Type { - return pattern.kind === SyntaxKind.ObjectBindingPattern + function getTypeFromBindingPattern(pattern: ts.BindingPattern, includePatternInType = false, reportErrors = false): ts.Type { + return pattern.kind === ts.SyntaxKind.ObjectBindingPattern ? getTypeFromObjectBindingPattern(pattern, includePatternInType, reportErrors) : getTypeFromArrayBindingPattern(pattern, includePatternInType, reportErrors); } @@ -9488,20 +9053,20 @@ namespace ts { // Here, the array literal [1, "one"] is contextually typed by the type [any, string], which is the implied type of the // binding pattern [x, s = ""]. Because the contextual type is a tuple type, the resulting type of [1, "one"] is the // tuple type [number, string]. Thus, the type inferred for 'x' is number and the type inferred for 's' is string. - function getWidenedTypeForVariableLikeDeclaration(declaration: ParameterDeclaration | PropertyDeclaration | PropertySignature | VariableDeclaration | BindingElement | JSDocPropertyLikeTag, reportErrors?: boolean): Type { + function getWidenedTypeForVariableLikeDeclaration(declaration: ts.ParameterDeclaration | ts.PropertyDeclaration | ts.PropertySignature | ts.VariableDeclaration | ts.BindingElement | ts.JSDocPropertyLikeTag, reportErrors?: boolean): ts.Type { return widenTypeForVariableLikeDeclaration(getTypeForVariableLikeDeclaration(declaration, /*includeOptionality*/ true, CheckMode.Normal), declaration, reportErrors); } - function isGlobalSymbolConstructor(node: Node) { + function isGlobalSymbolConstructor(node: ts.Node) { const symbol = getSymbolOfNode(node); const globalSymbol = getGlobalESSymbolConstructorTypeSymbol(/*reportErrors*/ false); return globalSymbol && symbol && symbol === globalSymbol; } - function widenTypeForVariableLikeDeclaration(type: Type | undefined, declaration: any, reportErrors?: boolean) { + function widenTypeForVariableLikeDeclaration(type: ts.Type | undefined, declaration: any, reportErrors?: boolean) { if (type) { // TODO: If back compat with pre-3.0/4.0 libs isn't required, remove the following SymbolConstructor special case transforming `symbol` into `unique symbol` - if (type.flags & TypeFlags.ESSymbol && isGlobalSymbolConstructor(declaration.parent)) { + if (type.flags & ts.TypeFlags.ESSymbol && isGlobalSymbolConstructor(declaration.parent)) { type = getESSymbolLikeTypeForNode(declaration); } if (reportErrors) { @@ -9509,7 +9074,7 @@ namespace ts { } // always widen a 'unique symbol' type if the type was created for a different declaration. - if (type.flags & TypeFlags.UniqueESSymbol && (isBindingElement(declaration) || !declaration.type) && type.symbol !== getSymbolOfNode(declaration)) { + if (type.flags & ts.TypeFlags.UniqueESSymbol && (ts.isBindingElement(declaration) || !declaration.type) && type.symbol !== getSymbolOfNode(declaration)) { type = esSymbolType; } @@ -9517,7 +9082,7 @@ namespace ts { } // Rest parameters default to type any[], other parameters default to type any - type = isParameter(declaration) && declaration.dotDotDotToken ? anyArrayType : anyType; + type = ts.isParameter(declaration) && declaration.dotDotDotToken ? anyArrayType : anyType; // Report implicit any errors unless this is a private property within an ambient declaration if (reportErrors) { @@ -9528,20 +9093,20 @@ namespace ts { return type; } - function declarationBelongsToPrivateAmbientMember(declaration: VariableLikeDeclaration) { - const root = getRootDeclaration(declaration); - const memberDeclaration = root.kind === SyntaxKind.Parameter ? root.parent : root; + function declarationBelongsToPrivateAmbientMember(declaration: ts.VariableLikeDeclaration) { + const root = ts.getRootDeclaration(declaration); + const memberDeclaration = root.kind === ts.SyntaxKind.Parameter ? root.parent : root; return isPrivateWithinAmbient(memberDeclaration); } - function tryGetTypeFromEffectiveTypeNode(node: Node) { - const typeNode = getEffectiveTypeAnnotationNode(node); + function tryGetTypeFromEffectiveTypeNode(node: ts.Node) { + const typeNode = ts.getEffectiveTypeAnnotationNode(node); if (typeNode) { return getTypeFromTypeNode(typeNode); } } - function getTypeOfVariableOrParameterOrProperty(symbol: Symbol): Type { + function getTypeOfVariableOrParameterOrProperty(symbol: ts.Symbol): ts.Type { const links = getSymbolLinks(symbol); if (!links.type) { const type = getTypeOfVariableOrParameterOrPropertyWorker(symbol); @@ -9555,33 +9120,36 @@ namespace ts { return links.type; } - function getTypeOfVariableOrParameterOrPropertyWorker(symbol: Symbol): Type { + function getTypeOfVariableOrParameterOrPropertyWorker(symbol: ts.Symbol): ts.Type { // Handle prototype property - if (symbol.flags & SymbolFlags.Prototype) { + if (symbol.flags & ts.SymbolFlags.Prototype) { return getTypeOfPrototypeProperty(symbol); } // CommonsJS require and module both have type any. if (symbol === requireSymbol) { return anyType; } - if (symbol.flags & SymbolFlags.ModuleExports && symbol.valueDeclaration) { - const fileSymbol = getSymbolOfNode(getSourceFileOfNode(symbol.valueDeclaration)); - const result = createSymbol(fileSymbol.flags, "exports" as __String); + if (symbol.flags & ts.SymbolFlags.ModuleExports && symbol.valueDeclaration) { + const fileSymbol = getSymbolOfNode(ts.getSourceFileOfNode(symbol.valueDeclaration)); + const result = createSymbol(fileSymbol.flags, "exports" as ts.__String); result.declarations = fileSymbol.declarations ? fileSymbol.declarations.slice() : []; result.parent = symbol; result.target = fileSymbol; - if (fileSymbol.valueDeclaration) result.valueDeclaration = fileSymbol.valueDeclaration; - if (fileSymbol.members) result.members = new Map(fileSymbol.members); - if (fileSymbol.exports) result.exports = new Map(fileSymbol.exports); - const members = createSymbolTable(); - members.set("exports" as __String, result); - return createAnonymousType(symbol, members, emptyArray, emptyArray, emptyArray); + if (fileSymbol.valueDeclaration) + result.valueDeclaration = fileSymbol.valueDeclaration; + if (fileSymbol.members) + result.members = new ts.Map(fileSymbol.members); + if (fileSymbol.exports) + result.exports = new ts.Map(fileSymbol.exports); + const members = ts.createSymbolTable(); + members.set("exports" as ts.__String, result); + return createAnonymousType(symbol, members, ts.emptyArray, ts.emptyArray, ts.emptyArray); } // Handle catch clause variables - Debug.assertIsDefined(symbol.valueDeclaration); + ts.Debug.assertIsDefined(symbol.valueDeclaration); const declaration = symbol.valueDeclaration; - if (isCatchClauseVariableDeclarationOrBindingElement(declaration)) { - const typeNode = getEffectiveTypeAnnotationNode(declaration); + if (ts.isCatchClauseVariableDeclarationOrBindingElement(declaration)) { + const typeNode = ts.getEffectiveTypeAnnotationNode(declaration); if (typeNode === undefined) { return useUnknownInCatchVariables ? unknownType : anyType; } @@ -9590,13 +9158,13 @@ namespace ts { return isTypeAny(type) || type === unknownType ? type : errorType; } // Handle export default expressions - if (isSourceFile(declaration) && isJsonSourceFile(declaration)) { + if (ts.isSourceFile(declaration) && ts.isJsonSourceFile(declaration)) { if (!declaration.statements.length) { return emptyObjectType; } return getWidenedType(getWidenedLiteralType(checkExpression(declaration.statements[0].expression))); } - if (isAccessor(declaration)) { + if (ts.isAccessor(declaration)) { // Binding of certain patterns in JS code will occasionally mark symbols as both properties // and accessors. Here we dispatch to accessor resolution if needed. return getTypeOfAccessors(symbol); @@ -9605,74 +9173,73 @@ namespace ts { // Handle variable, parameter or property if (!pushTypeResolution(symbol, TypeSystemPropertyName.Type)) { // Symbol is property of some kind that is merged with something - should use `getTypeOfFuncClassEnumModule` and not `getTypeOfVariableOrParameterOrProperty` - if (symbol.flags & SymbolFlags.ValueModule && !(symbol.flags & SymbolFlags.Assignment)) { + if (symbol.flags & ts.SymbolFlags.ValueModule && !(symbol.flags & ts.SymbolFlags.Assignment)) { return getTypeOfFuncClassEnumModule(symbol); } return reportCircularityError(symbol); } - let type: Type; - if (declaration.kind === SyntaxKind.ExportAssignment) { - type = widenTypeForVariableLikeDeclaration(tryGetTypeFromEffectiveTypeNode(declaration) || checkExpressionCached((declaration as ExportAssignment).expression), declaration); + let type: ts.Type; + if (declaration.kind === ts.SyntaxKind.ExportAssignment) { + type = widenTypeForVariableLikeDeclaration(tryGetTypeFromEffectiveTypeNode(declaration) || checkExpressionCached((declaration as ts.ExportAssignment).expression), declaration); } - else if ( - isBinaryExpression(declaration) || - (isInJSFile(declaration) && - (isCallExpression(declaration) || (isPropertyAccessExpression(declaration) || isBindableStaticElementAccessExpression(declaration)) && isBinaryExpression(declaration.parent)))) { + else if (ts.isBinaryExpression(declaration) || + (ts.isInJSFile(declaration) && + (ts.isCallExpression(declaration) || (ts.isPropertyAccessExpression(declaration) || ts.isBindableStaticElementAccessExpression(declaration)) && ts.isBinaryExpression(declaration.parent)))) { type = getWidenedTypeForAssignmentDeclaration(symbol); } - else if (isPropertyAccessExpression(declaration) - || isElementAccessExpression(declaration) - || isIdentifier(declaration) - || isStringLiteralLike(declaration) - || isNumericLiteral(declaration) - || isClassDeclaration(declaration) - || isFunctionDeclaration(declaration) - || (isMethodDeclaration(declaration) && !isObjectLiteralMethod(declaration)) - || isMethodSignature(declaration) - || isSourceFile(declaration)) { + else if (ts.isPropertyAccessExpression(declaration) + || ts.isElementAccessExpression(declaration) + || ts.isIdentifier(declaration) + || ts.isStringLiteralLike(declaration) + || ts.isNumericLiteral(declaration) + || ts.isClassDeclaration(declaration) + || ts.isFunctionDeclaration(declaration) + || (ts.isMethodDeclaration(declaration) && !ts.isObjectLiteralMethod(declaration)) + || ts.isMethodSignature(declaration) + || ts.isSourceFile(declaration)) { // Symbol is property of some kind that is merged with something - should use `getTypeOfFuncClassEnumModule` and not `getTypeOfVariableOrParameterOrProperty` - if (symbol.flags & (SymbolFlags.Function | SymbolFlags.Method | SymbolFlags.Class | SymbolFlags.Enum | SymbolFlags.ValueModule)) { + if (symbol.flags & (ts.SymbolFlags.Function | ts.SymbolFlags.Method | ts.SymbolFlags.Class | ts.SymbolFlags.Enum | ts.SymbolFlags.ValueModule)) { return getTypeOfFuncClassEnumModule(symbol); } - type = isBinaryExpression(declaration.parent) ? + type = ts.isBinaryExpression(declaration.parent) ? getWidenedTypeForAssignmentDeclaration(symbol) : tryGetTypeFromEffectiveTypeNode(declaration) || anyType; } - else if (isPropertyAssignment(declaration)) { + else if (ts.isPropertyAssignment(declaration)) { type = tryGetTypeFromEffectiveTypeNode(declaration) || checkPropertyAssignment(declaration); } - else if (isJsxAttribute(declaration)) { + else if (ts.isJsxAttribute(declaration)) { type = tryGetTypeFromEffectiveTypeNode(declaration) || checkJsxAttribute(declaration); } - else if (isShorthandPropertyAssignment(declaration)) { + else if (ts.isShorthandPropertyAssignment(declaration)) { type = tryGetTypeFromEffectiveTypeNode(declaration) || checkExpressionForMutableLocation(declaration.name, CheckMode.Normal); } - else if (isObjectLiteralMethod(declaration)) { + else if (ts.isObjectLiteralMethod(declaration)) { type = tryGetTypeFromEffectiveTypeNode(declaration) || checkObjectLiteralMethod(declaration, CheckMode.Normal); } - else if (isParameter(declaration) - || isPropertyDeclaration(declaration) - || isPropertySignature(declaration) - || isVariableDeclaration(declaration) - || isBindingElement(declaration) - || isJSDocPropertyLikeTag(declaration)) { + else if (ts.isParameter(declaration) + || ts.isPropertyDeclaration(declaration) + || ts.isPropertySignature(declaration) + || ts.isVariableDeclaration(declaration) + || ts.isBindingElement(declaration) + || ts.isJSDocPropertyLikeTag(declaration)) { type = getWidenedTypeForVariableLikeDeclaration(declaration, /*includeOptionality*/ true); } // getTypeOfSymbol dispatches some JS merges incorrectly because their symbol flags are not mutually exclusive. // Re-dispatch based on valueDeclaration.kind instead. - else if (isEnumDeclaration(declaration)) { + else if (ts.isEnumDeclaration(declaration)) { type = getTypeOfFuncClassEnumModule(symbol); } - else if (isEnumMember(declaration)) { + else if (ts.isEnumMember(declaration)) { type = getTypeOfEnumMember(symbol); } else { - return Debug.fail("Unhandled declaration kind! " + Debug.formatSyntaxKind(declaration.kind) + " for " + Debug.formatSymbol(symbol)); + return ts.Debug.fail("Unhandled declaration kind! " + ts.Debug.formatSyntaxKind(declaration.kind) + " for " + ts.Debug.formatSymbol(symbol)); } if (!popTypeResolution()) { // Symbol is property of some kind that is merged with something - should use `getTypeOfFuncClassEnumModule` and not `getTypeOfVariableOrParameterOrProperty` - if (symbol.flags & SymbolFlags.ValueModule && !(symbol.flags & SymbolFlags.Assignment)) { + if (symbol.flags & ts.SymbolFlags.ValueModule && !(symbol.flags & ts.SymbolFlags.Assignment)) { return getTypeOfFuncClassEnumModule(symbol); } return reportCircularityError(symbol); @@ -9680,66 +9247,66 @@ namespace ts { return type; } - function getAnnotatedAccessorTypeNode(accessor: AccessorDeclaration | undefined): TypeNode | undefined { + function getAnnotatedAccessorTypeNode(accessor: ts.AccessorDeclaration | undefined): ts.TypeNode | undefined { if (accessor) { - if (accessor.kind === SyntaxKind.GetAccessor) { - const getterTypeAnnotation = getEffectiveReturnTypeNode(accessor); + if (accessor.kind === ts.SyntaxKind.GetAccessor) { + const getterTypeAnnotation = ts.getEffectiveReturnTypeNode(accessor); return getterTypeAnnotation; } else { - const setterTypeAnnotation = getEffectiveSetAccessorTypeAnnotationNode(accessor); + const setterTypeAnnotation = ts.getEffectiveSetAccessorTypeAnnotationNode(accessor); return setterTypeAnnotation; } } return undefined; } - function getAnnotatedAccessorType(accessor: AccessorDeclaration | undefined): Type | undefined { + function getAnnotatedAccessorType(accessor: ts.AccessorDeclaration | undefined): ts.Type | undefined { const node = getAnnotatedAccessorTypeNode(accessor); return node && getTypeFromTypeNode(node); } - function getAnnotatedAccessorThisParameter(accessor: AccessorDeclaration): Symbol | undefined { + function getAnnotatedAccessorThisParameter(accessor: ts.AccessorDeclaration): ts.Symbol | undefined { const parameter = getAccessorThisParameter(accessor); return parameter && parameter.symbol; } - function getThisTypeOfDeclaration(declaration: SignatureDeclaration): Type | undefined { + function getThisTypeOfDeclaration(declaration: ts.SignatureDeclaration): ts.Type | undefined { return getThisTypeOfSignature(getSignatureFromDeclaration(declaration)); } - function getTypeOfAccessors(symbol: Symbol): Type { + function getTypeOfAccessors(symbol: ts.Symbol): ts.Type { const links = getSymbolLinks(symbol); if (!links.type) { if (!pushTypeResolution(symbol, TypeSystemPropertyName.Type)) { return errorType; } - const getter = getDeclarationOfKind(symbol, SyntaxKind.GetAccessor); - const setter = getDeclarationOfKind(symbol, SyntaxKind.SetAccessor); + const getter = ts.getDeclarationOfKind(symbol, ts.SyntaxKind.GetAccessor); + const setter = ts.getDeclarationOfKind(symbol, ts.SyntaxKind.SetAccessor); // We try to resolve a getter type annotation, a setter type annotation, or a getter function // body return type inference, in that order. - let type = getter && isInJSFile(getter) && getTypeForDeclarationFromJSDocComment(getter) || + let type = getter && ts.isInJSFile(getter) && getTypeForDeclarationFromJSDocComment(getter) || getAnnotatedAccessorType(getter) || getAnnotatedAccessorType(setter) || getter && getter.body && getReturnTypeFromBody(getter); if (!type) { if (setter && !isPrivateWithinAmbient(setter)) { - errorOrSuggestion(noImplicitAny, setter, Diagnostics.Property_0_implicitly_has_type_any_because_its_set_accessor_lacks_a_parameter_type_annotation, symbolToString(symbol)); + errorOrSuggestion(noImplicitAny, setter, ts.Diagnostics.Property_0_implicitly_has_type_any_because_its_set_accessor_lacks_a_parameter_type_annotation, symbolToString(symbol)); } else if (getter && !isPrivateWithinAmbient(getter)) { - errorOrSuggestion(noImplicitAny, getter, Diagnostics.Property_0_implicitly_has_type_any_because_its_get_accessor_lacks_a_return_type_annotation, symbolToString(symbol)); + errorOrSuggestion(noImplicitAny, getter, ts.Diagnostics.Property_0_implicitly_has_type_any_because_its_get_accessor_lacks_a_return_type_annotation, symbolToString(symbol)); } type = anyType; } if (!popTypeResolution()) { if (getAnnotatedAccessorTypeNode(getter)) { - error(getter, Diagnostics._0_is_referenced_directly_or_indirectly_in_its_own_type_annotation, symbolToString(symbol)); + error(getter, ts.Diagnostics._0_is_referenced_directly_or_indirectly_in_its_own_type_annotation, symbolToString(symbol)); } else if (getAnnotatedAccessorTypeNode(setter)) { - error(setter, Diagnostics._0_is_referenced_directly_or_indirectly_in_its_own_type_annotation, symbolToString(symbol)); + error(setter, ts.Diagnostics._0_is_referenced_directly_or_indirectly_in_its_own_type_annotation, symbolToString(symbol)); } else if (getter && noImplicitAny) { - error(getter, Diagnostics._0_implicitly_has_return_type_any_because_it_does_not_have_a_return_type_annotation_and_is_referenced_directly_or_indirectly_in_one_of_its_return_expressions, symbolToString(symbol)); + error(getter, ts.Diagnostics._0_implicitly_has_return_type_any_because_it_does_not_have_a_return_type_annotation_and_is_referenced_directly_or_indirectly_in_one_of_its_return_expressions, symbolToString(symbol)); } type = anyType; } @@ -9748,17 +9315,17 @@ namespace ts { return links.type; } - function getWriteTypeOfAccessors(symbol: Symbol): Type { + function getWriteTypeOfAccessors(symbol: ts.Symbol): ts.Type { const links = getSymbolLinks(symbol); if (!links.writeType) { if (!pushTypeResolution(symbol, TypeSystemPropertyName.WriteType)) { return errorType; } - const setter = getDeclarationOfKind(symbol, SyntaxKind.SetAccessor); + const setter = ts.getDeclarationOfKind(symbol, ts.SyntaxKind.SetAccessor); let writeType = getAnnotatedAccessorType(setter); if (!popTypeResolution()) { if (getAnnotatedAccessorTypeNode(setter)) { - error(setter, Diagnostics._0_is_referenced_directly_or_indirectly_in_its_own_type_annotation, symbolToString(symbol)); + error(setter, ts.Diagnostics._0_is_referenced_directly_or_indirectly_in_its_own_type_annotation, symbolToString(symbol)); } writeType = anyType; } @@ -9768,14 +9335,14 @@ namespace ts { return links.writeType; } - function getBaseTypeVariableOfClass(symbol: Symbol) { + function getBaseTypeVariableOfClass(symbol: ts.Symbol) { const baseConstructorType = getBaseConstructorTypeOfClass(getDeclaredTypeOfClassOrInterface(symbol)); - return baseConstructorType.flags & TypeFlags.TypeVariable ? baseConstructorType : - baseConstructorType.flags & TypeFlags.Intersection ? find((baseConstructorType as IntersectionType).types, t => !!(t.flags & TypeFlags.TypeVariable)) : + return baseConstructorType.flags & ts.TypeFlags.TypeVariable ? baseConstructorType : + baseConstructorType.flags & ts.TypeFlags.Intersection ? ts.find((baseConstructorType as ts.IntersectionType).types, t => !!(t.flags & ts.TypeFlags.TypeVariable)) : undefined; } - function getTypeOfFuncClassEnumModule(symbol: Symbol): Type { + function getTypeOfFuncClassEnumModule(symbol: ts.Symbol): ts.Type { let links = getSymbolLinks(symbol); const originalLinks = links; if (!links.type) { @@ -9792,23 +9359,23 @@ namespace ts { return links.type; } - function getTypeOfFuncClassEnumModuleWorker(symbol: Symbol): Type { + function getTypeOfFuncClassEnumModuleWorker(symbol: ts.Symbol): ts.Type { const declaration = symbol.valueDeclaration; - if (symbol.flags & SymbolFlags.Module && isShorthandAmbientModuleSymbol(symbol)) { + if (symbol.flags & ts.SymbolFlags.Module && ts.isShorthandAmbientModuleSymbol(symbol)) { return anyType; } - else if (declaration && (declaration.kind === SyntaxKind.BinaryExpression || - isAccessExpression(declaration) && - declaration.parent.kind === SyntaxKind.BinaryExpression)) { + else if (declaration && (declaration.kind === ts.SyntaxKind.BinaryExpression || + ts.isAccessExpression(declaration) && + declaration.parent.kind === ts.SyntaxKind.BinaryExpression)) { return getWidenedTypeForAssignmentDeclaration(symbol); } - else if (symbol.flags & SymbolFlags.ValueModule && declaration && isSourceFile(declaration) && declaration.commonJsModuleIndicator) { + else if (symbol.flags & ts.SymbolFlags.ValueModule && declaration && ts.isSourceFile(declaration) && declaration.commonJsModuleIndicator) { const resolvedModule = resolveExternalModuleSymbol(symbol); if (resolvedModule !== symbol) { if (!pushTypeResolution(symbol, TypeSystemPropertyName.Type)) { return errorType; } - const exportEquals = getMergedSymbol(symbol.exports!.get(InternalSymbolName.ExportEquals)!); + const exportEquals = getMergedSymbol(symbol.exports!.get(ts.InternalSymbolName.ExportEquals)!); const type = getWidenedTypeForAssignmentDeclaration(exportEquals, exportEquals === resolvedModule ? undefined : resolvedModule); if (!popTypeResolution()) { return reportCircularityError(symbol); @@ -9816,27 +9383,27 @@ namespace ts { return type; } } - const type = createObjectType(ObjectFlags.Anonymous, symbol); - if (symbol.flags & SymbolFlags.Class) { + const type = createObjectType(ts.ObjectFlags.Anonymous, symbol); + if (symbol.flags & ts.SymbolFlags.Class) { const baseTypeVariable = getBaseTypeVariableOfClass(symbol); return baseTypeVariable ? getIntersectionType([type, baseTypeVariable]) : type; } else { - return strictNullChecks && symbol.flags & SymbolFlags.Optional ? getOptionalType(type) : type; + return strictNullChecks && symbol.flags & ts.SymbolFlags.Optional ? getOptionalType(type) : type; } } - function getTypeOfEnumMember(symbol: Symbol): Type { + function getTypeOfEnumMember(symbol: ts.Symbol): ts.Type { const links = getSymbolLinks(symbol); return links.type || (links.type = getDeclaredTypeOfEnumMember(symbol)); } - function getTypeOfAlias(symbol: Symbol): Type { + function getTypeOfAlias(symbol: ts.Symbol): ts.Type { const links = getSymbolLinks(symbol); if (!links.type) { const targetSymbol = resolveAlias(symbol); const exportSymbol = symbol.declarations && getTargetOfAliasDeclaration(getDeclarationOfAliasSymbol(symbol)!, /*dontResolveAlias*/ true); - const declaredType = firstDefined(exportSymbol?.declarations, d => isExportAssignment(d) ? tryGetTypeFromEffectiveTypeNode(d) : undefined); + const declaredType = ts.firstDefined(exportSymbol?.declarations, d => ts.isExportAssignment(d) ? tryGetTypeFromEffectiveTypeNode(d) : undefined); // It only makes sense to get the type of a value symbol. If the result of resolving // the alias is not a value, then it has no type. To get the type associated with a // type symbol, call getDeclaredTypeOfSymbol. @@ -9845,34 +9412,32 @@ namespace ts { links.type = exportSymbol?.declarations && isDuplicatedCommonJSExport(exportSymbol.declarations) && symbol.declarations!.length ? getFlowTypeFromCommonJSExport(exportSymbol) : isDuplicatedCommonJSExport(symbol.declarations) ? autoType : declaredType ? declaredType - : targetSymbol.flags & SymbolFlags.Value ? getTypeOfSymbol(targetSymbol) + : targetSymbol.flags & ts.SymbolFlags.Value ? getTypeOfSymbol(targetSymbol) : errorType; } return links.type; } - function getTypeOfInstantiatedSymbol(symbol: Symbol): Type { + function getTypeOfInstantiatedSymbol(symbol: ts.Symbol): ts.Type { const links = getSymbolLinks(symbol); return links.type || (links.type = instantiateType(getTypeOfSymbol(links.target!), links.mapper)); } - function getWriteTypeOfInstantiatedSymbol(symbol: Symbol): Type { + function getWriteTypeOfInstantiatedSymbol(symbol: ts.Symbol): ts.Type { const links = getSymbolLinks(symbol); return links.writeType || (links.writeType = instantiateType(getWriteTypeOfSymbol(links.target!), links.mapper)); } - function reportCircularityError(symbol: Symbol) { - const declaration = symbol.valueDeclaration as VariableLikeDeclaration; + function reportCircularityError(symbol: ts.Symbol) { + const declaration = symbol.valueDeclaration as ts.VariableLikeDeclaration; // Check if variable has type annotation that circularly references the variable itself - if (getEffectiveTypeAnnotationNode(declaration)) { - error(symbol.valueDeclaration, Diagnostics._0_is_referenced_directly_or_indirectly_in_its_own_type_annotation, - symbolToString(symbol)); + if (ts.getEffectiveTypeAnnotationNode(declaration)) { + error(symbol.valueDeclaration, ts.Diagnostics._0_is_referenced_directly_or_indirectly_in_its_own_type_annotation, symbolToString(symbol)); return errorType; } // Check if variable has initializer that circularly references the variable itself - if (noImplicitAny && (declaration.kind !== SyntaxKind.Parameter || (declaration as HasInitializer).initializer)) { - error(symbol.valueDeclaration, Diagnostics._0_implicitly_has_type_any_because_it_does_not_have_a_type_annotation_and_is_referenced_directly_or_indirectly_in_its_own_initializer, - symbolToString(symbol)); + if (noImplicitAny && (declaration.kind !== ts.SyntaxKind.Parameter || (declaration as ts.HasInitializer).initializer)) { + error(symbol.valueDeclaration, ts.Diagnostics._0_implicitly_has_type_any_because_it_does_not_have_a_type_annotation_and_is_referenced_directly_or_indirectly_in_its_own_initializer, symbolToString(symbol)); } // Circularities could also result from parameters in function expressions that end up // having themselves as contextual types following type argument inference. In those cases @@ -9880,22 +9445,22 @@ namespace ts { return anyType; } - function getTypeOfSymbolWithDeferredType(symbol: Symbol) { + function getTypeOfSymbolWithDeferredType(symbol: ts.Symbol) { const links = getSymbolLinks(symbol); if (!links.type) { - Debug.assertIsDefined(links.deferralParent); - Debug.assertIsDefined(links.deferralConstituents); - links.type = links.deferralParent.flags & TypeFlags.Union ? getUnionType(links.deferralConstituents) : getIntersectionType(links.deferralConstituents); + ts.Debug.assertIsDefined(links.deferralParent); + ts.Debug.assertIsDefined(links.deferralConstituents); + links.type = links.deferralParent.flags & ts.TypeFlags.Union ? getUnionType(links.deferralConstituents) : getIntersectionType(links.deferralConstituents); } return links.type; } - function getWriteTypeOfSymbolWithDeferredType(symbol: Symbol): Type | undefined { + function getWriteTypeOfSymbolWithDeferredType(symbol: ts.Symbol): ts.Type | undefined { const links = getSymbolLinks(symbol); if (!links.writeType && links.deferralWriteConstituents) { - Debug.assertIsDefined(links.deferralParent); - Debug.assertIsDefined(links.deferralConstituents); - links.writeType = links.deferralParent.flags & TypeFlags.Union ? getUnionType(links.deferralWriteConstituents) : getIntersectionType(links.deferralWriteConstituents); + ts.Debug.assertIsDefined(links.deferralParent); + ts.Debug.assertIsDefined(links.deferralConstituents); + links.writeType = links.deferralParent.flags & ts.TypeFlags.Union ? getUnionType(links.deferralWriteConstituents) : getIntersectionType(links.deferralWriteConstituents); } return links.writeType; } @@ -9905,80 +9470,80 @@ namespace ts { * properties deriving from set accessors will either pre-compute or defer the union or * intersection of the writeTypes of their constituents. */ - function getWriteTypeOfSymbol(symbol: Symbol): Type { - const checkFlags = getCheckFlags(symbol); - if (symbol.flags & SymbolFlags.Property) { - return checkFlags & CheckFlags.SyntheticProperty ? - checkFlags & CheckFlags.DeferredType ? + function getWriteTypeOfSymbol(symbol: ts.Symbol): ts.Type { + const checkFlags = ts.getCheckFlags(symbol); + if (symbol.flags & ts.SymbolFlags.Property) { + return checkFlags & ts.CheckFlags.SyntheticProperty ? + checkFlags & ts.CheckFlags.DeferredType ? getWriteTypeOfSymbolWithDeferredType(symbol) || getTypeOfSymbolWithDeferredType(symbol) : - (symbol as TransientSymbol).writeType || (symbol as TransientSymbol).type! : + (symbol as ts.TransientSymbol).writeType || (symbol as ts.TransientSymbol).type! : getTypeOfSymbol(symbol); } - if (symbol.flags & SymbolFlags.Accessor) { - return checkFlags & CheckFlags.Instantiated ? + if (symbol.flags & ts.SymbolFlags.Accessor) { + return checkFlags & ts.CheckFlags.Instantiated ? getWriteTypeOfInstantiatedSymbol(symbol) : getWriteTypeOfAccessors(symbol); } return getTypeOfSymbol(symbol); } - function getTypeOfSymbol(symbol: Symbol): Type { - const checkFlags = getCheckFlags(symbol); - if (checkFlags & CheckFlags.DeferredType) { + function getTypeOfSymbol(symbol: ts.Symbol): ts.Type { + const checkFlags = ts.getCheckFlags(symbol); + if (checkFlags & ts.CheckFlags.DeferredType) { return getTypeOfSymbolWithDeferredType(symbol); } - if (checkFlags & CheckFlags.Instantiated) { + if (checkFlags & ts.CheckFlags.Instantiated) { return getTypeOfInstantiatedSymbol(symbol); } - if (checkFlags & CheckFlags.Mapped) { - return getTypeOfMappedSymbol(symbol as MappedSymbol); + if (checkFlags & ts.CheckFlags.Mapped) { + return getTypeOfMappedSymbol(symbol as ts.MappedSymbol); } - if (checkFlags & CheckFlags.ReverseMapped) { - return getTypeOfReverseMappedSymbol(symbol as ReverseMappedSymbol); + if (checkFlags & ts.CheckFlags.ReverseMapped) { + return getTypeOfReverseMappedSymbol(symbol as ts.ReverseMappedSymbol); } - if (symbol.flags & (SymbolFlags.Variable | SymbolFlags.Property)) { + if (symbol.flags & (ts.SymbolFlags.Variable | ts.SymbolFlags.Property)) { return getTypeOfVariableOrParameterOrProperty(symbol); } - if (symbol.flags & (SymbolFlags.Function | SymbolFlags.Method | SymbolFlags.Class | SymbolFlags.Enum | SymbolFlags.ValueModule)) { + if (symbol.flags & (ts.SymbolFlags.Function | ts.SymbolFlags.Method | ts.SymbolFlags.Class | ts.SymbolFlags.Enum | ts.SymbolFlags.ValueModule)) { return getTypeOfFuncClassEnumModule(symbol); } - if (symbol.flags & SymbolFlags.EnumMember) { + if (symbol.flags & ts.SymbolFlags.EnumMember) { return getTypeOfEnumMember(symbol); } - if (symbol.flags & SymbolFlags.Accessor) { + if (symbol.flags & ts.SymbolFlags.Accessor) { return getTypeOfAccessors(symbol); } - if (symbol.flags & SymbolFlags.Alias) { + if (symbol.flags & ts.SymbolFlags.Alias) { return getTypeOfAlias(symbol); } return errorType; } - function getNonMissingTypeOfSymbol(symbol: Symbol) { - return removeMissingType(getTypeOfSymbol(symbol), !!(symbol.flags & SymbolFlags.Optional)); + function getNonMissingTypeOfSymbol(symbol: ts.Symbol) { + return removeMissingType(getTypeOfSymbol(symbol), !!(symbol.flags & ts.SymbolFlags.Optional)); } - function isReferenceToType(type: Type, target: Type) { + function isReferenceToType(type: ts.Type, target: ts.Type) { return type !== undefined && target !== undefined - && (getObjectFlags(type) & ObjectFlags.Reference) !== 0 - && (type as TypeReference).target === target; + && (ts.getObjectFlags(type) & ts.ObjectFlags.Reference) !== 0 + && (type as ts.TypeReference).target === target; } - function getTargetType(type: Type): Type { - return getObjectFlags(type) & ObjectFlags.Reference ? (type as TypeReference).target : type; + function getTargetType(type: ts.Type): ts.Type { + return ts.getObjectFlags(type) & ts.ObjectFlags.Reference ? (type as ts.TypeReference).target : type; } // TODO: GH#18217 If `checkBase` is undefined, we should not call this because this will always return false. - function hasBaseType(type: Type, checkBase: Type | undefined) { + function hasBaseType(type: ts.Type, checkBase: ts.Type | undefined) { return check(type); - function check(type: Type): boolean { - if (getObjectFlags(type) & (ObjectFlags.ClassOrInterface | ObjectFlags.Reference)) { - const target = getTargetType(type) as InterfaceType; - return target === checkBase || some(getBaseTypes(target), check); + function check(type: ts.Type): boolean { + if (ts.getObjectFlags(type) & (ts.ObjectFlags.ClassOrInterface | ts.ObjectFlags.Reference)) { + const target = getTargetType(type) as ts.InterfaceType; + return target === checkBase || ts.some(getBaseTypes(target), check); } - else if (type.flags & TypeFlags.Intersection) { - return some((type as IntersectionType).types, check); + else if (type.flags & ts.TypeFlags.Intersection) { + return ts.some((type as ts.IntersectionType).types, check); } return false; } @@ -9987,23 +9552,23 @@ namespace ts { // Appends the type parameters given by a list of declarations to a set of type parameters and returns the resulting set. // The function allocates a new array if the input type parameter set is undefined, but otherwise it modifies the set // in-place and returns the same array. - function appendTypeParameters(typeParameters: TypeParameter[] | undefined, declarations: readonly TypeParameterDeclaration[]): TypeParameter[] | undefined { + function appendTypeParameters(typeParameters: ts.TypeParameter[] | undefined, declarations: readonly ts.TypeParameterDeclaration[]): ts.TypeParameter[] | undefined { for (const declaration of declarations) { - typeParameters = appendIfUnique(typeParameters, getDeclaredTypeOfTypeParameter(getSymbolOfNode(declaration))); + typeParameters = ts.appendIfUnique(typeParameters, getDeclaredTypeOfTypeParameter(getSymbolOfNode(declaration))); } return typeParameters; } // Return the outer type parameters of a node or undefined if the node has no outer type parameters. - function getOuterTypeParameters(node: Node, includeThisTypes?: boolean): TypeParameter[] | undefined { + function getOuterTypeParameters(node: ts.Node, includeThisTypes?: boolean): ts.TypeParameter[] | undefined { while (true) { node = node.parent; // TODO: GH#18217 Use SourceFile kind check instead - if (node && isBinaryExpression(node)) { + if (node && ts.isBinaryExpression(node)) { // prototype assignments get the outer type parameters of their constructor function - const assignmentKind = getAssignmentDeclarationKind(node); - if (assignmentKind === AssignmentDeclarationKind.Prototype || assignmentKind === AssignmentDeclarationKind.PrototypeProperty) { + const assignmentKind = ts.getAssignmentDeclarationKind(node); + if (assignmentKind === ts.AssignmentDeclarationKind.Prototype || assignmentKind === ts.AssignmentDeclarationKind.PrototypeProperty) { const symbol = getSymbolOfNode(node.left); - if (symbol && symbol.parent && !findAncestor(symbol.parent.valueDeclaration, d => node === d)) { + if (symbol && symbol.parent && !ts.findAncestor(symbol.parent.valueDeclaration, d => node === d)) { node = symbol.parent.valueDeclaration!; } } @@ -10012,49 +9577,49 @@ namespace ts { return undefined; } switch (node.kind) { - case SyntaxKind.ClassDeclaration: - case SyntaxKind.ClassExpression: - case SyntaxKind.InterfaceDeclaration: - case SyntaxKind.CallSignature: - case SyntaxKind.ConstructSignature: - case SyntaxKind.MethodSignature: - case SyntaxKind.FunctionType: - case SyntaxKind.ConstructorType: - case SyntaxKind.JSDocFunctionType: - case SyntaxKind.FunctionDeclaration: - case SyntaxKind.MethodDeclaration: - case SyntaxKind.FunctionExpression: - case SyntaxKind.ArrowFunction: - case SyntaxKind.TypeAliasDeclaration: - case SyntaxKind.JSDocTemplateTag: - case SyntaxKind.JSDocTypedefTag: - case SyntaxKind.JSDocEnumTag: - case SyntaxKind.JSDocCallbackTag: - case SyntaxKind.MappedType: - case SyntaxKind.ConditionalType: { + case ts.SyntaxKind.ClassDeclaration: + case ts.SyntaxKind.ClassExpression: + case ts.SyntaxKind.InterfaceDeclaration: + case ts.SyntaxKind.CallSignature: + case ts.SyntaxKind.ConstructSignature: + case ts.SyntaxKind.MethodSignature: + case ts.SyntaxKind.FunctionType: + case ts.SyntaxKind.ConstructorType: + case ts.SyntaxKind.JSDocFunctionType: + case ts.SyntaxKind.FunctionDeclaration: + case ts.SyntaxKind.MethodDeclaration: + case ts.SyntaxKind.FunctionExpression: + case ts.SyntaxKind.ArrowFunction: + case ts.SyntaxKind.TypeAliasDeclaration: + case ts.SyntaxKind.JSDocTemplateTag: + case ts.SyntaxKind.JSDocTypedefTag: + case ts.SyntaxKind.JSDocEnumTag: + case ts.SyntaxKind.JSDocCallbackTag: + case ts.SyntaxKind.MappedType: + case ts.SyntaxKind.ConditionalType: { const outerTypeParameters = getOuterTypeParameters(node, includeThisTypes); - if (node.kind === SyntaxKind.MappedType) { - return append(outerTypeParameters, getDeclaredTypeOfTypeParameter(getSymbolOfNode((node as MappedTypeNode).typeParameter))); + if (node.kind === ts.SyntaxKind.MappedType) { + return ts.append(outerTypeParameters, getDeclaredTypeOfTypeParameter(getSymbolOfNode((node as ts.MappedTypeNode).typeParameter))); } - else if (node.kind === SyntaxKind.ConditionalType) { - return concatenate(outerTypeParameters, getInferTypeParameters(node as ConditionalTypeNode)); + else if (node.kind === ts.SyntaxKind.ConditionalType) { + return ts.concatenate(outerTypeParameters, getInferTypeParameters(node as ts.ConditionalTypeNode)); } - const outerAndOwnTypeParameters = appendTypeParameters(outerTypeParameters, getEffectiveTypeParameterDeclarations(node as DeclarationWithTypeParameters)); + const outerAndOwnTypeParameters = appendTypeParameters(outerTypeParameters, ts.getEffectiveTypeParameterDeclarations(node as ts.DeclarationWithTypeParameters)); const thisType = includeThisTypes && - (node.kind === SyntaxKind.ClassDeclaration || node.kind === SyntaxKind.ClassExpression || node.kind === SyntaxKind.InterfaceDeclaration || isJSConstructor(node)) && - getDeclaredTypeOfClassOrInterface(getSymbolOfNode(node as ClassLikeDeclaration | InterfaceDeclaration)).thisType; - return thisType ? append(outerAndOwnTypeParameters, thisType) : outerAndOwnTypeParameters; + (node.kind === ts.SyntaxKind.ClassDeclaration || node.kind === ts.SyntaxKind.ClassExpression || node.kind === ts.SyntaxKind.InterfaceDeclaration || isJSConstructor(node)) && + getDeclaredTypeOfClassOrInterface(getSymbolOfNode(node as ts.ClassLikeDeclaration | ts.InterfaceDeclaration)).thisType; + return thisType ? ts.append(outerAndOwnTypeParameters, thisType) : outerAndOwnTypeParameters; } - case SyntaxKind.JSDocParameterTag: - const paramSymbol = getParameterSymbolFromJSDoc(node as JSDocParameterTag); + case ts.SyntaxKind.JSDocParameterTag: + const paramSymbol = ts.getParameterSymbolFromJSDoc(node as ts.JSDocParameterTag); if (paramSymbol) { node = paramSymbol.valueDeclaration!; } break; - case SyntaxKind.JSDoc: { + case ts.SyntaxKind.JSDoc: { const outerTypeParameters = getOuterTypeParameters(node, includeThisTypes); - return (node as JSDoc).tags - ? appendTypeParameters(outerTypeParameters, flatMap((node as JSDoc).tags, t => isJSDocTemplateTag(t) ? t.typeParameters : undefined)) + return (node as ts.JSDoc).tags + ? appendTypeParameters(outerTypeParameters, ts.flatMap((node as ts.JSDoc).tags, t => ts.isJSDocTemplateTag(t) ? t.typeParameters : undefined)) : outerTypeParameters; } } @@ -10062,27 +9627,27 @@ namespace ts { } // The outer type parameters are those defined by enclosing generic classes, methods, or functions. - function getOuterTypeParametersOfClassOrInterface(symbol: Symbol): TypeParameter[] | undefined { - const declaration = symbol.flags & SymbolFlags.Class ? symbol.valueDeclaration : getDeclarationOfKind(symbol, SyntaxKind.InterfaceDeclaration)!; - Debug.assert(!!declaration, "Class was missing valueDeclaration -OR- non-class had no interface declarations"); + function getOuterTypeParametersOfClassOrInterface(symbol: ts.Symbol): ts.TypeParameter[] | undefined { + const declaration = symbol.flags & ts.SymbolFlags.Class ? symbol.valueDeclaration : ts.getDeclarationOfKind(symbol, ts.SyntaxKind.InterfaceDeclaration)!; + ts.Debug.assert(!!declaration, "Class was missing valueDeclaration -OR- non-class had no interface declarations"); return getOuterTypeParameters(declaration); } // The local type parameters are the combined set of type parameters from all declarations of the class, // interface, or type alias. - function getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(symbol: Symbol): TypeParameter[] | undefined { + function getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(symbol: ts.Symbol): ts.TypeParameter[] | undefined { if (!symbol.declarations) { return; } - let result: TypeParameter[] | undefined; + let result: ts.TypeParameter[] | undefined; for (const node of symbol.declarations) { - if (node.kind === SyntaxKind.InterfaceDeclaration || - node.kind === SyntaxKind.ClassDeclaration || - node.kind === SyntaxKind.ClassExpression || + if (node.kind === ts.SyntaxKind.InterfaceDeclaration || + node.kind === ts.SyntaxKind.ClassDeclaration || + node.kind === ts.SyntaxKind.ClassExpression || isJSConstructor(node) || - isTypeAlias(node)) { - const declaration = node as InterfaceDeclaration | TypeAliasDeclaration | JSDocTypedefTag | JSDocCallbackTag; - result = appendTypeParameters(result, getEffectiveTypeParameterDeclarations(declaration)); + ts.isTypeAlias(node)) { + const declaration = node as ts.InterfaceDeclaration | ts.TypeAliasDeclaration | ts.JSDocTypedefTag | ts.JSDocCallbackTag; + result = appendTypeParameters(result, ts.getEffectiveTypeParameterDeclarations(declaration)); } } return result; @@ -10090,14 +9655,14 @@ namespace ts { // The full set of type parameters for a generic class or interface type consists of its outer type parameters plus // its locally declared type parameters. - function getTypeParametersOfClassOrInterface(symbol: Symbol): TypeParameter[] | undefined { - return concatenate(getOuterTypeParametersOfClassOrInterface(symbol), getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(symbol)); + function getTypeParametersOfClassOrInterface(symbol: ts.Symbol): ts.TypeParameter[] | undefined { + return ts.concatenate(getOuterTypeParametersOfClassOrInterface(symbol), getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(symbol)); } // A type is a mixin constructor if it has a single construct signature taking no type parameters and a single // rest parameter of type any[]. - function isMixinConstructorType(type: Type) { - const signatures = getSignaturesOfType(type, SignatureKind.Construct); + function isMixinConstructorType(type: ts.Type) { + const signatures = getSignaturesOfType(type, ts.SignatureKind.Construct); if (signatures.length === 1) { const s = signatures[0]; if (!s.typeParameters && s.parameters.length === 1 && signatureHasRestParameter(s)) { @@ -10108,33 +9673,32 @@ namespace ts { return false; } - function isConstructorType(type: Type): boolean { - if (getSignaturesOfType(type, SignatureKind.Construct).length > 0) { + function isConstructorType(type: ts.Type): boolean { + if (getSignaturesOfType(type, ts.SignatureKind.Construct).length > 0) { return true; } - if (type.flags & TypeFlags.TypeVariable) { + if (type.flags & ts.TypeFlags.TypeVariable) { const constraint = getBaseConstraintOfType(type); return !!constraint && isMixinConstructorType(constraint); } return false; } - function getBaseTypeNodeOfClass(type: InterfaceType): ExpressionWithTypeArguments | undefined { - const decl = getClassLikeDeclarationOfSymbol(type.symbol); - return decl && getEffectiveBaseTypeNode(decl); + function getBaseTypeNodeOfClass(type: ts.InterfaceType): ts.ExpressionWithTypeArguments | undefined { + const decl = ts.getClassLikeDeclarationOfSymbol(type.symbol); + return decl && ts.getEffectiveBaseTypeNode(decl); } - function getConstructorsForTypeArguments(type: Type, typeArgumentNodes: readonly TypeNode[] | undefined, location: Node): readonly Signature[] { - const typeArgCount = length(typeArgumentNodes); - const isJavascript = isInJSFile(location); - return filter(getSignaturesOfType(type, SignatureKind.Construct), - sig => (isJavascript || typeArgCount >= getMinTypeArgumentCount(sig.typeParameters)) && typeArgCount <= length(sig.typeParameters)); + function getConstructorsForTypeArguments(type: ts.Type, typeArgumentNodes: readonly ts.TypeNode[] | undefined, location: ts.Node): readonly ts.Signature[] { + const typeArgCount = ts.length(typeArgumentNodes); + const isJavascript = ts.isInJSFile(location); + return ts.filter(getSignaturesOfType(type, ts.SignatureKind.Construct), sig => (isJavascript || typeArgCount >= getMinTypeArgumentCount(sig.typeParameters)) && typeArgCount <= ts.length(sig.typeParameters)); } - function getInstantiatedConstructorsForTypeArguments(type: Type, typeArgumentNodes: readonly TypeNode[] | undefined, location: Node): readonly Signature[] { + function getInstantiatedConstructorsForTypeArguments(type: ts.Type, typeArgumentNodes: readonly ts.TypeNode[] | undefined, location: ts.Node): readonly ts.Signature[] { const signatures = getConstructorsForTypeArguments(type, typeArgumentNodes, location); - const typeArguments = map(typeArgumentNodes, getTypeFromTypeNode); - return sameMap(signatures, sig => some(sig.typeParameters) ? getSignatureInstantiation(sig, typeArguments, isInJSFile(location)) : sig); + const typeArguments = ts.map(typeArgumentNodes, getTypeFromTypeNode); + return ts.sameMap(signatures, sig => ts.some(sig.typeParameters) ? getSignatureInstantiation(sig, typeArguments, ts.isInJSFile(location)) : sig); } /** @@ -10145,10 +9709,10 @@ namespace ts { * * anyType if the extends expression has type any, or * * an object type with at least one construct signature. */ - function getBaseConstructorTypeOfClass(type: InterfaceType): Type { + function getBaseConstructorTypeOfClass(type: ts.InterfaceType): ts.Type { if (!type.resolvedBaseConstructorType) { - const decl = getClassLikeDeclarationOfSymbol(type.symbol); - const extended = decl && getEffectiveBaseTypeNode(decl); + const decl = ts.getClassLikeDeclarationOfSymbol(type.symbol); + const extended = decl && ts.getEffectiveBaseTypeNode(decl); const baseTypeNode = getBaseTypeNodeOfClass(type); if (!baseTypeNode) { return type.resolvedBaseConstructorType = undefinedType; @@ -10158,31 +9722,31 @@ namespace ts { } const baseConstructorType = checkExpression(baseTypeNode.expression); if (extended && baseTypeNode !== extended) { - Debug.assert(!extended.typeArguments); // Because this is in a JS file, and baseTypeNode is in an @extends tag + ts.Debug.assert(!extended.typeArguments); // Because this is in a JS file, and baseTypeNode is in an @extends tag checkExpression(extended.expression); } - if (baseConstructorType.flags & (TypeFlags.Object | TypeFlags.Intersection)) { + if (baseConstructorType.flags & (ts.TypeFlags.Object | ts.TypeFlags.Intersection)) { // Resolving the members of a class requires us to resolve the base class of that class. // We force resolution here such that we catch circularities now. - resolveStructuredTypeMembers(baseConstructorType as ObjectType); + resolveStructuredTypeMembers(baseConstructorType as ts.ObjectType); } if (!popTypeResolution()) { - error(type.symbol.valueDeclaration, Diagnostics._0_is_referenced_directly_or_indirectly_in_its_own_base_expression, symbolToString(type.symbol)); + error(type.symbol.valueDeclaration, ts.Diagnostics._0_is_referenced_directly_or_indirectly_in_its_own_base_expression, symbolToString(type.symbol)); return type.resolvedBaseConstructorType = errorType; } - if (!(baseConstructorType.flags & TypeFlags.Any) && baseConstructorType !== nullWideningType && !isConstructorType(baseConstructorType)) { - const err = error(baseTypeNode.expression, Diagnostics.Type_0_is_not_a_constructor_function_type, typeToString(baseConstructorType)); - if (baseConstructorType.flags & TypeFlags.TypeParameter) { + if (!(baseConstructorType.flags & ts.TypeFlags.Any) && baseConstructorType !== nullWideningType && !isConstructorType(baseConstructorType)) { + const err = error(baseTypeNode.expression, ts.Diagnostics.Type_0_is_not_a_constructor_function_type, typeToString(baseConstructorType)); + if (baseConstructorType.flags & ts.TypeFlags.TypeParameter) { const constraint = getConstraintFromTypeParameter(baseConstructorType); - let ctorReturn: Type = unknownType; + let ctorReturn: ts.Type = unknownType; if (constraint) { - const ctorSig = getSignaturesOfType(constraint, SignatureKind.Construct); + const ctorSig = getSignaturesOfType(constraint, ts.SignatureKind.Construct); if (ctorSig[0]) { ctorReturn = getReturnTypeOfSignature(ctorSig[0]); } } if (baseConstructorType.symbol.declarations) { - addRelatedInfo(err, createDiagnosticForNode(baseConstructorType.symbol.declarations[0], Diagnostics.Did_you_mean_for_0_to_be_constrained_to_type_new_args_Colon_any_1, symbolToString(baseConstructorType.symbol), typeToString(ctorReturn))); + ts.addRelatedInfo(err, ts.createDiagnosticForNode(baseConstructorType.symbol.declarations[0], ts.Diagnostics.Did_you_mean_for_0_to_be_constrained_to_type_new_args_Colon_any_1, symbolToString(baseConstructorType.symbol), typeToString(ctorReturn))); } } return type.resolvedBaseConstructorType = errorType; @@ -10192,17 +9756,18 @@ namespace ts { return type.resolvedBaseConstructorType; } - function getImplementsTypes(type: InterfaceType): BaseType[] { - let resolvedImplementsTypes: BaseType[] = emptyArray; + function getImplementsTypes(type: ts.InterfaceType): ts.BaseType[] { + let resolvedImplementsTypes: ts.BaseType[] = ts.emptyArray; if (type.symbol.declarations) { for (const declaration of type.symbol.declarations) { - const implementsTypeNodes = getEffectiveImplementsTypeNodes(declaration as ClassLikeDeclaration); - if (!implementsTypeNodes) continue; + const implementsTypeNodes = ts.getEffectiveImplementsTypeNodes(declaration as ts.ClassLikeDeclaration); + if (!implementsTypeNodes) + continue; for (const node of implementsTypeNodes) { const implementsType = getTypeFromTypeNode(node); if (!isErrorType(implementsType)) { - if (resolvedImplementsTypes === emptyArray) { - resolvedImplementsTypes = [implementsType as ObjectType]; + if (resolvedImplementsTypes === ts.emptyArray) { + resolvedImplementsTypes = [implementsType as ts.ObjectType]; } else { resolvedImplementsTypes.push(implementsType); @@ -10214,30 +9779,30 @@ namespace ts { return resolvedImplementsTypes; } - function reportCircularBaseType(node: Node, type: Type) { - error(node, Diagnostics.Type_0_recursively_references_itself_as_a_base_type, typeToString(type, /*enclosingDeclaration*/ undefined, TypeFormatFlags.WriteArrayAsGenericType)); + function reportCircularBaseType(node: ts.Node, type: ts.Type) { + error(node, ts.Diagnostics.Type_0_recursively_references_itself_as_a_base_type, typeToString(type, /*enclosingDeclaration*/ undefined, ts.TypeFormatFlags.WriteArrayAsGenericType)); } - function getBaseTypes(type: InterfaceType): BaseType[] { + function getBaseTypes(type: ts.InterfaceType): ts.BaseType[] { if (!type.baseTypesResolved) { if (pushTypeResolution(type, TypeSystemPropertyName.ResolvedBaseTypes)) { - if (type.objectFlags & ObjectFlags.Tuple) { - type.resolvedBaseTypes = [getTupleBaseType(type as TupleType)]; + if (type.objectFlags & ts.ObjectFlags.Tuple) { + type.resolvedBaseTypes = [getTupleBaseType(type as ts.TupleType)]; } - else if (type.symbol.flags & (SymbolFlags.Class | SymbolFlags.Interface)) { - if (type.symbol.flags & SymbolFlags.Class) { + else if (type.symbol.flags & (ts.SymbolFlags.Class | ts.SymbolFlags.Interface)) { + if (type.symbol.flags & ts.SymbolFlags.Class) { resolveBaseTypesOfClass(type); } - if (type.symbol.flags & SymbolFlags.Interface) { + if (type.symbol.flags & ts.SymbolFlags.Interface) { resolveBaseTypesOfInterface(type); } } else { - Debug.fail("type must be class or interface"); + ts.Debug.fail("type must be class or interface"); } if (!popTypeResolution() && type.symbol.declarations) { for (const declaration of type.symbol.declarations) { - if (declaration.kind === SyntaxKind.ClassDeclaration || declaration.kind === SyntaxKind.InterfaceDeclaration) { + if (declaration.kind === ts.SyntaxKind.ClassDeclaration || declaration.kind === ts.SyntaxKind.InterfaceDeclaration) { reportCircularBaseType(declaration, type); } } @@ -10248,28 +9813,28 @@ namespace ts { return type.resolvedBaseTypes; } - function getTupleBaseType(type: TupleType) { - const elementTypes = sameMap(type.typeParameters, (t, i) => type.elementFlags[i] & ElementFlags.Variadic ? getIndexedAccessType(t, numberType) : t); - return createArrayType(getUnionType(elementTypes || emptyArray), type.readonly); + function getTupleBaseType(type: ts.TupleType) { + const elementTypes = ts.sameMap(type.typeParameters, (t, i) => type.elementFlags[i] & ts.ElementFlags.Variadic ? getIndexedAccessType(t, numberType) : t); + return createArrayType(getUnionType(elementTypes || ts.emptyArray), type.readonly); } - function resolveBaseTypesOfClass(type: InterfaceType) { - type.resolvedBaseTypes = resolvingEmptyArray; + function resolveBaseTypesOfClass(type: ts.InterfaceType) { + type.resolvedBaseTypes = ts.resolvingEmptyArray; const baseConstructorType = getApparentType(getBaseConstructorTypeOfClass(type)); - if (!(baseConstructorType.flags & (TypeFlags.Object | TypeFlags.Intersection | TypeFlags.Any))) { - return type.resolvedBaseTypes = emptyArray; + if (!(baseConstructorType.flags & (ts.TypeFlags.Object | ts.TypeFlags.Intersection | ts.TypeFlags.Any))) { + return type.resolvedBaseTypes = ts.emptyArray; } const baseTypeNode = getBaseTypeNodeOfClass(type)!; - let baseType: Type; + let baseType: ts.Type; const originalBaseType = baseConstructorType.symbol ? getDeclaredTypeOfSymbol(baseConstructorType.symbol) : undefined; - if (baseConstructorType.symbol && baseConstructorType.symbol.flags & SymbolFlags.Class && + if (baseConstructorType.symbol && baseConstructorType.symbol.flags & ts.SymbolFlags.Class && areAllOuterTypeParametersApplied(originalBaseType!)) { // When base constructor type is a class with no captured type arguments we know that the constructors all have the same type parameters as the // class and all return the instance type of the class. There is no need for further checks and we can apply the // type arguments in the same manner as a type reference to get the same error reporting experience. baseType = getTypeFromClassOrInterfaceReference(baseTypeNode, baseConstructorType.symbol); } - else if (baseConstructorType.flags & TypeFlags.Any) { + else if (baseConstructorType.flags & ts.TypeFlags.Any) { baseType = baseConstructorType; } else { @@ -10278,28 +9843,27 @@ namespace ts { // we check that all instantiated signatures return the same type. const constructors = getInstantiatedConstructorsForTypeArguments(baseConstructorType, baseTypeNode.typeArguments, baseTypeNode); if (!constructors.length) { - error(baseTypeNode.expression, Diagnostics.No_base_constructor_has_the_specified_number_of_type_arguments); - return type.resolvedBaseTypes = emptyArray; + error(baseTypeNode.expression, ts.Diagnostics.No_base_constructor_has_the_specified_number_of_type_arguments); + return type.resolvedBaseTypes = ts.emptyArray; } baseType = getReturnTypeOfSignature(constructors[0]); } if (isErrorType(baseType)) { - return type.resolvedBaseTypes = emptyArray; + return type.resolvedBaseTypes = ts.emptyArray; } const reducedBaseType = getReducedType(baseType); if (!isValidBaseType(reducedBaseType)) { const elaboration = elaborateNeverIntersection(/*errorInfo*/ undefined, baseType); - const diagnostic = chainDiagnosticMessages(elaboration, Diagnostics.Base_constructor_return_type_0_is_not_an_object_type_or_intersection_of_object_types_with_statically_known_members, typeToString(reducedBaseType)); - diagnostics.add(createDiagnosticForNodeFromMessageChain(baseTypeNode.expression, diagnostic)); - return type.resolvedBaseTypes = emptyArray; + const diagnostic = ts.chainDiagnosticMessages(elaboration, ts.Diagnostics.Base_constructor_return_type_0_is_not_an_object_type_or_intersection_of_object_types_with_statically_known_members, typeToString(reducedBaseType)); + diagnostics.add(ts.createDiagnosticForNodeFromMessageChain(baseTypeNode.expression, diagnostic)); + return type.resolvedBaseTypes = ts.emptyArray; } if (type === reducedBaseType || hasBaseType(reducedBaseType, type)) { - error(type.symbol.valueDeclaration, Diagnostics.Type_0_recursively_references_itself_as_a_base_type, - typeToString(type, /*enclosingDeclaration*/ undefined, TypeFormatFlags.WriteArrayAsGenericType)); - return type.resolvedBaseTypes = emptyArray; + error(type.symbol.valueDeclaration, ts.Diagnostics.Type_0_recursively_references_itself_as_a_base_type, typeToString(type, /*enclosingDeclaration*/ undefined, ts.TypeFormatFlags.WriteArrayAsGenericType)); + return type.resolvedBaseTypes = ts.emptyArray; } - if (type.resolvedBaseTypes === resolvingEmptyArray) { + if (type.resolvedBaseTypes === ts.resolvingEmptyArray) { // Circular reference, likely through instantiation of default parameters // (otherwise there'd be an error from hasBaseType) - this is fine, but `.members` should be reset // as `getIndexedAccessType` via `instantiateType` via `getTypeFromClassOrInterfaceReference` forces a @@ -10309,21 +9873,21 @@ namespace ts { return type.resolvedBaseTypes = [reducedBaseType]; } - function areAllOuterTypeParametersApplied(type: Type): boolean { // TODO: GH#18217 Shouldn't this take an InterfaceType? + function areAllOuterTypeParametersApplied(type: ts.Type): boolean { // An unapplied type parameter has its symbol still the same as the matching argument symbol. // Since parameters are applied outer-to-inner, only the last outer parameter needs to be checked. - const outerTypeParameters = (type as InterfaceType).outerTypeParameters; + const outerTypeParameters = (type as ts.InterfaceType).outerTypeParameters; if (outerTypeParameters) { const last = outerTypeParameters.length - 1; - const typeArguments = getTypeArguments(type as TypeReference); + const typeArguments = getTypeArguments(type as ts.TypeReference); return outerTypeParameters[last].symbol !== typeArguments[last].symbol; } return true; } // A valid base type is `any`, an object type or intersection of object types. - function isValidBaseType(type: Type): type is BaseType { - if (type.flags & TypeFlags.TypeParameter) { + function isValidBaseType(type: ts.Type): type is ts.BaseType { + if (type.flags & ts.TypeFlags.TypeParameter) { const constraint = getBaseConstraintOfType(type); if (constraint) { return isValidBaseType(constraint); @@ -10331,22 +9895,22 @@ namespace ts { } // TODO: Given that we allow type parmeters here now, is this `!isGenericMappedType(type)` check really needed? // There's no reason a `T` should be allowed while a `Readonly` should not. - return !!(type.flags & (TypeFlags.Object | TypeFlags.NonPrimitive | TypeFlags.Any) && !isGenericMappedType(type) || - type.flags & TypeFlags.Intersection && every((type as IntersectionType).types, isValidBaseType)); + return !!(type.flags & (ts.TypeFlags.Object | ts.TypeFlags.NonPrimitive | ts.TypeFlags.Any) && !isGenericMappedType(type) || + type.flags & ts.TypeFlags.Intersection && ts.every((type as ts.IntersectionType).types, isValidBaseType)); } - function resolveBaseTypesOfInterface(type: InterfaceType): void { - type.resolvedBaseTypes = type.resolvedBaseTypes || emptyArray; + function resolveBaseTypesOfInterface(type: ts.InterfaceType): void { + type.resolvedBaseTypes = type.resolvedBaseTypes || ts.emptyArray; if (type.symbol.declarations) { for (const declaration of type.symbol.declarations) { - if (declaration.kind === SyntaxKind.InterfaceDeclaration && getInterfaceBaseTypeNodes(declaration as InterfaceDeclaration)) { - for (const node of getInterfaceBaseTypeNodes(declaration as InterfaceDeclaration)!) { + if (declaration.kind === ts.SyntaxKind.InterfaceDeclaration && ts.getInterfaceBaseTypeNodes(declaration as ts.InterfaceDeclaration)) { + for (const node of ts.getInterfaceBaseTypeNodes(declaration as ts.InterfaceDeclaration)!) { const baseType = getReducedType(getTypeFromTypeNode(node)); if (!isErrorType(baseType)) { if (isValidBaseType(baseType)) { if (type !== baseType && !hasBaseType(baseType, type)) { - if (type.resolvedBaseTypes === emptyArray) { - type.resolvedBaseTypes = [baseType as ObjectType]; + if (type.resolvedBaseTypes === ts.emptyArray) { + type.resolvedBaseTypes = [baseType as ts.ObjectType]; } else { type.resolvedBaseTypes.push(baseType); @@ -10357,7 +9921,7 @@ namespace ts { } } else { - error(node, Diagnostics.An_interface_can_only_extend_an_object_type_or_intersection_of_object_types_with_statically_known_members); + error(node, ts.Diagnostics.An_interface_can_only_extend_an_object_type_or_intersection_of_object_types_with_statically_known_members); } } } @@ -10373,21 +9937,21 @@ namespace ts { * to "this" in its body, if all base types are interfaces, * and if none of the base interfaces have a "this" type. */ - function isThislessInterface(symbol: Symbol): boolean { + function isThislessInterface(symbol: ts.Symbol): boolean { if (!symbol.declarations) { return true; } for (const declaration of symbol.declarations) { - if (declaration.kind === SyntaxKind.InterfaceDeclaration) { - if (declaration.flags & NodeFlags.ContainsThis) { + if (declaration.kind === ts.SyntaxKind.InterfaceDeclaration) { + if (declaration.flags & ts.NodeFlags.ContainsThis) { return false; } - const baseTypeNodes = getInterfaceBaseTypeNodes(declaration as InterfaceDeclaration); + const baseTypeNodes = ts.getInterfaceBaseTypeNodes(declaration as ts.InterfaceDeclaration); if (baseTypeNodes) { for (const node of baseTypeNodes) { - if (isEntityNameExpression(node.expression)) { - const baseSymbol = resolveEntityName(node.expression, SymbolFlags.Type, /*ignoreErrors*/ true); - if (!baseSymbol || !(baseSymbol.flags & SymbolFlags.Interface) || getDeclaredTypeOfClassOrInterface(baseSymbol).thisType) { + if (ts.isEntityNameExpression(node.expression)) { + const baseSymbol = resolveEntityName(node.expression, ts.SymbolFlags.Type, /*ignoreErrors*/ true); + if (!baseSymbol || !(baseSymbol.flags & ts.SymbolFlags.Interface) || getDeclaredTypeOfClassOrInterface(baseSymbol).thisType) { return false; } } @@ -10398,18 +9962,18 @@ namespace ts { return true; } - function getDeclaredTypeOfClassOrInterface(symbol: Symbol): InterfaceType { + function getDeclaredTypeOfClassOrInterface(symbol: ts.Symbol): ts.InterfaceType { let links = getSymbolLinks(symbol); const originalLinks = links; if (!links.declaredType) { - const kind = symbol.flags & SymbolFlags.Class ? ObjectFlags.Class : ObjectFlags.Interface; + const kind = symbol.flags & ts.SymbolFlags.Class ? ts.ObjectFlags.Class : ts.ObjectFlags.Interface; const merged = mergeJSSymbols(symbol, symbol.valueDeclaration && getAssignedClassSymbol(symbol.valueDeclaration)); if (merged) { // note:we overwrite links because we just cloned the symbol symbol = links = merged; } - const type = originalLinks.declaredType = links.declaredType = createObjectType(kind, symbol) as InterfaceType; + const type = originalLinks.declaredType = links.declaredType = createObjectType(kind, symbol) as ts.InterfaceType; const outerTypeParameters = getOuterTypeParametersOfClassOrInterface(symbol); const localTypeParameters = getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(symbol); // A class or interface is generic if it has type parameters or a "this" type. We always give classes a "this" type @@ -10417,24 +9981,24 @@ namespace ts { // property types inferred from initializers and method return types inferred from return statements are very hard // to exhaustively analyze). We give interfaces a "this" type if we can't definitely determine that they are free of // "this" references. - if (outerTypeParameters || localTypeParameters || kind === ObjectFlags.Class || !isThislessInterface(symbol)) { - type.objectFlags |= ObjectFlags.Reference; - type.typeParameters = concatenate(outerTypeParameters, localTypeParameters); + if (outerTypeParameters || localTypeParameters || kind === ts.ObjectFlags.Class || !isThislessInterface(symbol)) { + type.objectFlags |= ts.ObjectFlags.Reference; + type.typeParameters = ts.concatenate(outerTypeParameters, localTypeParameters); type.outerTypeParameters = outerTypeParameters; type.localTypeParameters = localTypeParameters; - (type as GenericType).instantiations = new Map(); - (type as GenericType).instantiations.set(getTypeListId(type.typeParameters), type as GenericType); - (type as GenericType).target = type as GenericType; - (type as GenericType).resolvedTypeArguments = type.typeParameters; + (type as ts.GenericType).instantiations = new ts.Map(); + (type as ts.GenericType).instantiations.set(getTypeListId(type.typeParameters), type as ts.GenericType); + (type as ts.GenericType).target = type as ts.GenericType; + (type as ts.GenericType).resolvedTypeArguments = type.typeParameters; type.thisType = createTypeParameter(symbol); type.thisType.isThisType = true; type.thisType.constraint = type; } } - return links.declaredType as InterfaceType; + return links.declaredType as ts.InterfaceType; } - function getDeclaredTypeOfTypeAlias(symbol: Symbol): Type { + function getDeclaredTypeOfTypeAlias(symbol: ts.Symbol): ts.Type { const links = getSymbolLinks(symbol); if (!links.declaredType) { // Note that we use the links object as the target here because the symbol object is used as the unique @@ -10443,8 +10007,8 @@ namespace ts { return errorType; } - const declaration = Debug.checkDefined(symbol.declarations?.find(isTypeAlias), "Type alias symbol with no valid declaration found"); - const typeNode = isJSDocTypeAlias(declaration) ? declaration.typeExpression : declaration.type; + const declaration = ts.Debug.checkDefined(symbol.declarations?.find(ts.isTypeAlias), "Type alias symbol with no valid declaration found"); + const typeNode = ts.isJSDocTypeAlias(declaration) ? declaration.typeExpression : declaration.type; // If typeNode is missing, we will error in checkJSDocTypedefTag. let type = typeNode ? getTypeFromTypeNode(typeNode) : errorType; @@ -10454,17 +10018,17 @@ namespace ts { // Initialize the instantiation cache for generic type aliases. The declared type corresponds to // an instantiation of the type alias with the type parameters supplied as type arguments. links.typeParameters = typeParameters; - links.instantiations = new Map(); + links.instantiations = new ts.Map(); links.instantiations.set(getTypeListId(typeParameters), type); } } else { type = errorType; - if (declaration.kind === SyntaxKind.JSDocEnumTag) { - error(declaration.typeExpression.type, Diagnostics.Type_alias_0_circularly_references_itself, symbolToString(symbol)); + if (declaration.kind === ts.SyntaxKind.JSDocEnumTag) { + error(declaration.typeExpression.type, ts.Diagnostics.Type_alias_0_circularly_references_itself, symbolToString(symbol)); } else { - error(isNamedDeclaration(declaration) ? declaration.name : declaration || declaration, Diagnostics.Type_alias_0_circularly_references_itself, symbolToString(symbol)); + error(ts.isNamedDeclaration(declaration) ? declaration.name : declaration || declaration, ts.Diagnostics.Type_alias_0_circularly_references_itself, symbolToString(symbol)); } } links.declaredType = type; @@ -10472,39 +10036,39 @@ namespace ts { return links.declaredType; } - function isStringConcatExpression(expr: Node): boolean { - if (isStringLiteralLike(expr)) { + function isStringConcatExpression(expr: ts.Node): boolean { + if (ts.isStringLiteralLike(expr)) { return true; } - else if (expr.kind === SyntaxKind.BinaryExpression) { - return isStringConcatExpression((expr as BinaryExpression).left) && isStringConcatExpression((expr as BinaryExpression).right); + else if (expr.kind === ts.SyntaxKind.BinaryExpression) { + return isStringConcatExpression((expr as ts.BinaryExpression).left) && isStringConcatExpression((expr as ts.BinaryExpression).right); } return false; } - function isLiteralEnumMember(member: EnumMember) { + function isLiteralEnumMember(member: ts.EnumMember) { const expr = member.initializer; if (!expr) { - return !(member.flags & NodeFlags.Ambient); + return !(member.flags & ts.NodeFlags.Ambient); } switch (expr.kind) { - case SyntaxKind.StringLiteral: - case SyntaxKind.NumericLiteral: - case SyntaxKind.NoSubstitutionTemplateLiteral: + case ts.SyntaxKind.StringLiteral: + case ts.SyntaxKind.NumericLiteral: + case ts.SyntaxKind.NoSubstitutionTemplateLiteral: return true; - case SyntaxKind.PrefixUnaryExpression: - return (expr as PrefixUnaryExpression).operator === SyntaxKind.MinusToken && - (expr as PrefixUnaryExpression).operand.kind === SyntaxKind.NumericLiteral; - case SyntaxKind.Identifier: - return nodeIsMissing(expr) || !!getSymbolOfNode(member.parent).exports!.get((expr as Identifier).escapedText); - case SyntaxKind.BinaryExpression: + case ts.SyntaxKind.PrefixUnaryExpression: + return (expr as ts.PrefixUnaryExpression).operator === ts.SyntaxKind.MinusToken && + (expr as ts.PrefixUnaryExpression).operand.kind === ts.SyntaxKind.NumericLiteral; + case ts.SyntaxKind.Identifier: + return ts.nodeIsMissing(expr) || !!getSymbolOfNode(member.parent).exports!.get((expr as ts.Identifier).escapedText); + case ts.SyntaxKind.BinaryExpression: return isStringConcatExpression(expr); default: return false; } } - function getEnumKind(symbol: Symbol): EnumKind { + function getEnumKind(symbol: ts.Symbol): ts.EnumKind { const links = getSymbolLinks(symbol); if (links.enumKind !== undefined) { return links.enumKind; @@ -10512,10 +10076,10 @@ namespace ts { let hasNonLiteralMember = false; if (symbol.declarations) { for (const declaration of symbol.declarations) { - if (declaration.kind === SyntaxKind.EnumDeclaration) { - for (const member of (declaration as EnumDeclaration).members) { - if (member.initializer && isStringLiteralLike(member.initializer)) { - return links.enumKind = EnumKind.Literal; + if (declaration.kind === ts.SyntaxKind.EnumDeclaration) { + for (const member of (declaration as ts.EnumDeclaration).members) { + if (member.initializer && ts.isStringLiteralLike(member.initializer)) { + return links.enumKind = ts.EnumKind.Literal; } if (!isLiteralEnumMember(member)) { hasNonLiteralMember = true; @@ -10524,25 +10088,25 @@ namespace ts { } } } - return links.enumKind = hasNonLiteralMember ? EnumKind.Numeric : EnumKind.Literal; + return links.enumKind = hasNonLiteralMember ? ts.EnumKind.Numeric : ts.EnumKind.Literal; } - function getBaseTypeOfEnumLiteralType(type: Type) { - return type.flags & TypeFlags.EnumLiteral && !(type.flags & TypeFlags.Union) ? getDeclaredTypeOfSymbol(getParentOfSymbol(type.symbol)!) : type; + function getBaseTypeOfEnumLiteralType(type: ts.Type) { + return type.flags & ts.TypeFlags.EnumLiteral && !(type.flags & ts.TypeFlags.Union) ? getDeclaredTypeOfSymbol(getParentOfSymbol(type.symbol)!) : type; } - function getDeclaredTypeOfEnum(symbol: Symbol): Type { + function getDeclaredTypeOfEnum(symbol: ts.Symbol): ts.Type { const links = getSymbolLinks(symbol); if (links.declaredType) { return links.declaredType; } - if (getEnumKind(symbol) === EnumKind.Literal) { + if (getEnumKind(symbol) === ts.EnumKind.Literal) { enumCount++; - const memberTypeList: Type[] = []; + const memberTypeList: ts.Type[] = []; if (symbol.declarations) { for (const declaration of symbol.declarations) { - if (declaration.kind === SyntaxKind.EnumDeclaration) { - for (const member of (declaration as EnumDeclaration).members) { + if (declaration.kind === ts.SyntaxKind.EnumDeclaration) { + for (const member of (declaration as ts.EnumDeclaration).members) { const value = getEnumMemberValue(member); const memberType = getFreshTypeOfLiteralType(getEnumLiteralType(value !== undefined ? value : 0, enumCount, getSymbolOfNode(member))); getSymbolLinks(getSymbolOfNode(member)).declaredType = memberType; @@ -10552,20 +10116,20 @@ namespace ts { } } if (memberTypeList.length) { - const enumType = getUnionType(memberTypeList, UnionReduction.Literal, symbol, /*aliasTypeArguments*/ undefined); - if (enumType.flags & TypeFlags.Union) { - enumType.flags |= TypeFlags.EnumLiteral; + const enumType = getUnionType(memberTypeList, ts.UnionReduction.Literal, symbol, /*aliasTypeArguments*/ undefined); + if (enumType.flags & ts.TypeFlags.Union) { + enumType.flags |= ts.TypeFlags.EnumLiteral; enumType.symbol = symbol; } return links.declaredType = enumType; } } - const enumType = createType(TypeFlags.Enum); + const enumType = createType(ts.TypeFlags.Enum); enumType.symbol = symbol; return links.declaredType = enumType; } - function getDeclaredTypeOfEnumMember(symbol: Symbol): Type { + function getDeclaredTypeOfEnumMember(symbol: ts.Symbol): ts.Type { const links = getSymbolLinks(symbol); if (!links.declaredType) { const enumType = getDeclaredTypeOfEnum(getParentOfSymbol(symbol)!); @@ -10576,37 +10140,37 @@ namespace ts { return links.declaredType; } - function getDeclaredTypeOfTypeParameter(symbol: Symbol): TypeParameter { + function getDeclaredTypeOfTypeParameter(symbol: ts.Symbol): ts.TypeParameter { const links = getSymbolLinks(symbol); return links.declaredType || (links.declaredType = createTypeParameter(symbol)); } - function getDeclaredTypeOfAlias(symbol: Symbol): Type { + function getDeclaredTypeOfAlias(symbol: ts.Symbol): ts.Type { const links = getSymbolLinks(symbol); return links.declaredType || (links.declaredType = getDeclaredTypeOfSymbol(resolveAlias(symbol))); } - function getDeclaredTypeOfSymbol(symbol: Symbol): Type { + function getDeclaredTypeOfSymbol(symbol: ts.Symbol): ts.Type { return tryGetDeclaredTypeOfSymbol(symbol) || errorType; } - function tryGetDeclaredTypeOfSymbol(symbol: Symbol): Type | undefined { - if (symbol.flags & (SymbolFlags.Class | SymbolFlags.Interface)) { + function tryGetDeclaredTypeOfSymbol(symbol: ts.Symbol): ts.Type | undefined { + if (symbol.flags & (ts.SymbolFlags.Class | ts.SymbolFlags.Interface)) { return getDeclaredTypeOfClassOrInterface(symbol); } - if (symbol.flags & SymbolFlags.TypeAlias) { + if (symbol.flags & ts.SymbolFlags.TypeAlias) { return getDeclaredTypeOfTypeAlias(symbol); } - if (symbol.flags & SymbolFlags.TypeParameter) { + if (symbol.flags & ts.SymbolFlags.TypeParameter) { return getDeclaredTypeOfTypeParameter(symbol); } - if (symbol.flags & SymbolFlags.Enum) { + if (symbol.flags & ts.SymbolFlags.Enum) { return getDeclaredTypeOfEnum(symbol); } - if (symbol.flags & SymbolFlags.EnumMember) { + if (symbol.flags & ts.SymbolFlags.EnumMember) { return getDeclaredTypeOfEnumMember(symbol); } - if (symbol.flags & SymbolFlags.Alias) { + if (symbol.flags & ts.SymbolFlags.Alias) { return getDeclaredTypeOfAlias(symbol); } return undefined; @@ -10617,32 +10181,32 @@ namespace ts { * literal type, an array with an element type that is free of this references, or a type reference that is * free of this references. */ - function isThislessType(node: TypeNode): boolean { + function isThislessType(node: ts.TypeNode): boolean { switch (node.kind) { - case SyntaxKind.AnyKeyword: - case SyntaxKind.UnknownKeyword: - case SyntaxKind.StringKeyword: - case SyntaxKind.NumberKeyword: - case SyntaxKind.BigIntKeyword: - case SyntaxKind.BooleanKeyword: - case SyntaxKind.SymbolKeyword: - case SyntaxKind.ObjectKeyword: - case SyntaxKind.VoidKeyword: - case SyntaxKind.UndefinedKeyword: - case SyntaxKind.NeverKeyword: - case SyntaxKind.LiteralType: + case ts.SyntaxKind.AnyKeyword: + case ts.SyntaxKind.UnknownKeyword: + case ts.SyntaxKind.StringKeyword: + case ts.SyntaxKind.NumberKeyword: + case ts.SyntaxKind.BigIntKeyword: + case ts.SyntaxKind.BooleanKeyword: + case ts.SyntaxKind.SymbolKeyword: + case ts.SyntaxKind.ObjectKeyword: + case ts.SyntaxKind.VoidKeyword: + case ts.SyntaxKind.UndefinedKeyword: + case ts.SyntaxKind.NeverKeyword: + case ts.SyntaxKind.LiteralType: return true; - case SyntaxKind.ArrayType: - return isThislessType((node as ArrayTypeNode).elementType); - case SyntaxKind.TypeReference: - return !(node as TypeReferenceNode).typeArguments || (node as TypeReferenceNode).typeArguments!.every(isThislessType); + case ts.SyntaxKind.ArrayType: + return isThislessType((node as ts.ArrayTypeNode).elementType); + case ts.SyntaxKind.TypeReference: + return !(node as ts.TypeReferenceNode).typeArguments || (node as ts.TypeReferenceNode).typeArguments!.every(isThislessType); } return false; } /** A type parameter is thisless if its constraint is thisless, or if it has no constraint. */ - function isThislessTypeParameter(node: TypeParameterDeclaration) { - const constraint = getEffectiveConstraintOfTypeParameter(node); + function isThislessTypeParameter(node: ts.TypeParameterDeclaration) { + const constraint = ts.getEffectiveConstraintOfTypeParameter(node); return !constraint || isThislessType(constraint); } @@ -10650,9 +10214,9 @@ namespace ts { * A variable-like declaration is free of this references if it has a type annotation * that is thisless, or if it has no type annotation and no initializer (and is thus of type any). */ - function isThislessVariableLikeDeclaration(node: VariableLikeDeclaration): boolean { - const typeNode = getEffectiveTypeAnnotationNode(node); - return typeNode ? isThislessType(typeNode) : !hasInitializer(node); + function isThislessVariableLikeDeclaration(node: ts.VariableLikeDeclaration): boolean { + const typeNode = ts.getEffectiveTypeAnnotationNode(node); + return typeNode ? isThislessType(typeNode) : !ts.hasInitializer(node); } /** @@ -10660,10 +10224,10 @@ namespace ts { * annotation that is free of this references and if each parameter is thisless and if * each type parameter (if present) is thisless. */ - function isThislessFunctionLikeDeclaration(node: FunctionLikeDeclaration): boolean { - const returnType = getEffectiveReturnTypeNode(node); - const typeParameters = getEffectiveTypeParameterDeclarations(node); - return (node.kind === SyntaxKind.Constructor || (!!returnType && isThislessType(returnType))) && + function isThislessFunctionLikeDeclaration(node: ts.FunctionLikeDeclaration): boolean { + const returnType = ts.getEffectiveReturnTypeNode(node); + const typeParameters = ts.getEffectiveTypeParameterDeclarations(node); + return (node.kind === ts.SyntaxKind.Constructor || (!!returnType && isThislessType(returnType))) && node.parameters.every(isThislessVariableLikeDeclaration) && typeParameters.every(isThislessTypeParameter); } @@ -10675,20 +10239,20 @@ namespace ts { * inferred from their initializers and function members with inferred return types are conservatively * assumed not to be free of "this" references. */ - function isThisless(symbol: Symbol): boolean { + function isThisless(symbol: ts.Symbol): boolean { if (symbol.declarations && symbol.declarations.length === 1) { const declaration = symbol.declarations[0]; if (declaration) { switch (declaration.kind) { - case SyntaxKind.PropertyDeclaration: - case SyntaxKind.PropertySignature: - return isThislessVariableLikeDeclaration(declaration as VariableLikeDeclaration); - case SyntaxKind.MethodDeclaration: - case SyntaxKind.MethodSignature: - case SyntaxKind.Constructor: - case SyntaxKind.GetAccessor: - case SyntaxKind.SetAccessor: - return isThislessFunctionLikeDeclaration(declaration as FunctionLikeDeclaration | AccessorDeclaration); + case ts.SyntaxKind.PropertyDeclaration: + case ts.SyntaxKind.PropertySignature: + return isThislessVariableLikeDeclaration(declaration as ts.VariableLikeDeclaration); + case ts.SyntaxKind.MethodDeclaration: + case ts.SyntaxKind.MethodSignature: + case ts.SyntaxKind.Constructor: + case ts.SyntaxKind.GetAccessor: + case ts.SyntaxKind.SetAccessor: + return isThislessFunctionLikeDeclaration(declaration as ts.FunctionLikeDeclaration | ts.AccessorDeclaration); } } } @@ -10697,15 +10261,15 @@ namespace ts { // The mappingThisOnly flag indicates that the only type parameter being mapped is "this". When the flag is true, // we check symbols to see if we can quickly conclude they are free of "this" references, thus needing no instantiation. - function createInstantiatedSymbolTable(symbols: Symbol[], mapper: TypeMapper, mappingThisOnly: boolean): SymbolTable { - const result = createSymbolTable(); + function createInstantiatedSymbolTable(symbols: ts.Symbol[], mapper: ts.TypeMapper, mappingThisOnly: boolean): ts.SymbolTable { + const result = ts.createSymbolTable(); for (const symbol of symbols) { result.set(symbol.escapedName, mappingThisOnly && isThisless(symbol) ? symbol : instantiateSymbol(symbol, mapper)); } return result; } - function addInheritedMembers(symbols: SymbolTable, baseSymbols: Symbol[]) { + function addInheritedMembers(symbols: ts.SymbolTable, baseSymbols: ts.Symbol[]) { for (const s of baseSymbols) { if (!symbols.has(s.escapedName) && !isStaticPrivateIdentifierProperty(s)) { symbols.set(s.escapedName, s); @@ -10713,32 +10277,31 @@ namespace ts { } } - function isStaticPrivateIdentifierProperty(s: Symbol): boolean { - return !!s.valueDeclaration && isPrivateIdentifierClassElementDeclaration(s.valueDeclaration) && isStatic(s.valueDeclaration); + function isStaticPrivateIdentifierProperty(s: ts.Symbol): boolean { + return !!s.valueDeclaration && ts.isPrivateIdentifierClassElementDeclaration(s.valueDeclaration) && ts.isStatic(s.valueDeclaration); } - function resolveDeclaredMembers(type: InterfaceType): InterfaceTypeWithDeclaredMembers { - if (!(type as InterfaceTypeWithDeclaredMembers).declaredProperties) { + function resolveDeclaredMembers(type: ts.InterfaceType): ts.InterfaceTypeWithDeclaredMembers { + if (!(type as ts.InterfaceTypeWithDeclaredMembers).declaredProperties) { const symbol = type.symbol; const members = getMembersOfSymbol(symbol); - (type as InterfaceTypeWithDeclaredMembers).declaredProperties = getNamedMembers(members); + (type as ts.InterfaceTypeWithDeclaredMembers).declaredProperties = getNamedMembers(members); // Start with signatures at empty array in case of recursive types - (type as InterfaceTypeWithDeclaredMembers).declaredCallSignatures = emptyArray; - (type as InterfaceTypeWithDeclaredMembers).declaredConstructSignatures = emptyArray; - (type as InterfaceTypeWithDeclaredMembers).declaredIndexInfos = emptyArray; - - (type as InterfaceTypeWithDeclaredMembers).declaredCallSignatures = getSignaturesOfSymbol(members.get(InternalSymbolName.Call)); - (type as InterfaceTypeWithDeclaredMembers).declaredConstructSignatures = getSignaturesOfSymbol(members.get(InternalSymbolName.New)); - (type as InterfaceTypeWithDeclaredMembers).declaredIndexInfos = getIndexInfosOfSymbol(symbol); + (type as ts.InterfaceTypeWithDeclaredMembers).declaredCallSignatures = ts.emptyArray; + (type as ts.InterfaceTypeWithDeclaredMembers).declaredConstructSignatures = ts.emptyArray; + (type as ts.InterfaceTypeWithDeclaredMembers).declaredIndexInfos = ts.emptyArray; + (type as ts.InterfaceTypeWithDeclaredMembers).declaredCallSignatures = getSignaturesOfSymbol(members.get(ts.InternalSymbolName.Call)); + (type as ts.InterfaceTypeWithDeclaredMembers).declaredConstructSignatures = getSignaturesOfSymbol(members.get(ts.InternalSymbolName.New)); + (type as ts.InterfaceTypeWithDeclaredMembers).declaredIndexInfos = getIndexInfosOfSymbol(symbol); } - return type as InterfaceTypeWithDeclaredMembers; + return type as ts.InterfaceTypeWithDeclaredMembers; } /** * Indicates whether a type can be used as a property name. */ - function isTypeUsableAsPropertyName(type: Type): type is StringLiteralType | NumberLiteralType | UniqueESSymbolType { - return !!(type.flags & TypeFlags.StringOrNumberLiteralOrUnique); + function isTypeUsableAsPropertyName(type: ts.Type): type is ts.StringLiteralType | ts.NumberLiteralType | ts.UniqueESSymbolType { + return !!(type.flags & ts.TypeFlags.StringOrNumberLiteralOrUnique); } /** @@ -10749,54 +10312,54 @@ namespace ts { * `ElementAccessExpression` consisting only of these same three types of nodes. * - The type of its expression is a string or numeric literal type, or is a `unique symbol` type. */ - function isLateBindableName(node: DeclarationName): node is LateBoundName { - if (!isComputedPropertyName(node) && !isElementAccessExpression(node)) { + function isLateBindableName(node: ts.DeclarationName): node is ts.LateBoundName { + if (!ts.isComputedPropertyName(node) && !ts.isElementAccessExpression(node)) { return false; } - const expr = isComputedPropertyName(node) ? node.expression : node.argumentExpression; - return isEntityNameExpression(expr) - && isTypeUsableAsPropertyName(isComputedPropertyName(node) ? checkComputedPropertyName(node) : checkExpressionCached(expr)); + const expr = ts.isComputedPropertyName(node) ? node.expression : node.argumentExpression; + return ts.isEntityNameExpression(expr) + && isTypeUsableAsPropertyName(ts.isComputedPropertyName(node) ? checkComputedPropertyName(node) : checkExpressionCached(expr)); } - function isLateBoundName(name: __String): boolean { - return (name as string).charCodeAt(0) === CharacterCodes._ && - (name as string).charCodeAt(1) === CharacterCodes._ && - (name as string).charCodeAt(2) === CharacterCodes.at; + function isLateBoundName(name: ts.__String): boolean { + return (name as string).charCodeAt(0) === ts.CharacterCodes._ && + (name as string).charCodeAt(1) === ts.CharacterCodes._ && + (name as string).charCodeAt(2) === ts.CharacterCodes.at; } /** * Indicates whether a declaration has a late-bindable dynamic name. */ - function hasLateBindableName(node: Declaration): node is LateBoundDeclaration | LateBoundBinaryExpressionDeclaration { - const name = getNameOfDeclaration(node); + function hasLateBindableName(node: ts.Declaration): node is ts.LateBoundDeclaration | ts.LateBoundBinaryExpressionDeclaration { + const name = ts.getNameOfDeclaration(node); return !!name && isLateBindableName(name); } /** * Indicates whether a declaration has an early-bound name or a dynamic name that can be late-bound. */ - function hasBindableName(node: Declaration) { - return !hasDynamicName(node) || hasLateBindableName(node); + function hasBindableName(node: ts.Declaration) { + return !ts.hasDynamicName(node) || hasLateBindableName(node); } /** * Indicates whether a declaration name is a dynamic name that cannot be late-bound. */ - function isNonBindableDynamicName(node: DeclarationName) { - return isDynamicName(node) && !isLateBindableName(node); + function isNonBindableDynamicName(node: ts.DeclarationName) { + return ts.isDynamicName(node) && !isLateBindableName(node); } /** * Gets the symbolic name for a member from its type. */ - function getPropertyNameFromType(type: StringLiteralType | NumberLiteralType | UniqueESSymbolType): __String { - if (type.flags & TypeFlags.UniqueESSymbol) { - return (type as UniqueESSymbolType).escapedName; + function getPropertyNameFromType(type: ts.StringLiteralType | ts.NumberLiteralType | ts.UniqueESSymbolType): ts.__String { + if (type.flags & ts.TypeFlags.UniqueESSymbol) { + return (type as ts.UniqueESSymbolType).escapedName; } - if (type.flags & (TypeFlags.StringLiteral | TypeFlags.NumberLiteral)) { - return escapeLeadingUnderscores("" + (type as StringLiteralType | NumberLiteralType).value); + if (type.flags & (ts.TypeFlags.StringLiteral | ts.TypeFlags.NumberLiteral)) { + return ts.escapeLeadingUnderscores("" + (type as ts.StringLiteralType | ts.NumberLiteralType).value); } - return Debug.fail(); + return ts.Debug.fail(); } /** @@ -10804,8 +10367,8 @@ namespace ts { * late-bound members that `addDeclarationToSymbol` in binder.ts performs for early-bound * members. */ - function addDeclarationToLateBoundSymbol(symbol: Symbol, member: LateBoundDeclaration | BinaryExpression, symbolFlags: SymbolFlags) { - Debug.assert(!!(getCheckFlags(symbol) & CheckFlags.Late), "Expected a late-bound symbol."); + function addDeclarationToLateBoundSymbol(symbol: ts.Symbol, member: ts.LateBoundDeclaration | ts.BinaryExpression, symbolFlags: ts.SymbolFlags) { + ts.Debug.assert(!!(ts.getCheckFlags(symbol) & ts.CheckFlags.Late), "Expected a late-bound symbol."); symbol.flags |= symbolFlags; getSymbolLinks(member.symbol).lateSymbol = symbol; if (!symbol.declarations) { @@ -10814,7 +10377,7 @@ namespace ts { else if(!member.symbol.isReplaceableByMethod) { symbol.declarations.push(member); } - if (symbolFlags & SymbolFlags.Value) { + if (symbolFlags & ts.SymbolFlags.Value) { if (!symbol.valueDeclaration || symbol.valueDeclaration.kind !== member.kind) { symbol.valueDeclaration = member; } @@ -10849,22 +10412,23 @@ namespace ts { * @param lateSymbols The late-bound symbols of the parent. * @param decl The member to bind. */ - function lateBindMember(parent: Symbol, earlySymbols: SymbolTable | undefined, lateSymbols: UnderscoreEscapedMap, decl: LateBoundDeclaration | LateBoundBinaryExpressionDeclaration) { - Debug.assert(!!decl.symbol, "The member is expected to have a symbol."); + function lateBindMember(parent: ts.Symbol, earlySymbols: ts.SymbolTable | undefined, lateSymbols: ts.UnderscoreEscapedMap, decl: ts.LateBoundDeclaration | ts.LateBoundBinaryExpressionDeclaration) { + ts.Debug.assert(!!decl.symbol, "The member is expected to have a symbol."); const links = getNodeLinks(decl); if (!links.resolvedSymbol) { // In the event we attempt to resolve the late-bound name of this member recursively, // fall back to the early-bound name of this member. links.resolvedSymbol = decl.symbol; - const declName = isBinaryExpression(decl) ? decl.left : decl.name; - const type = isElementAccessExpression(declName) ? checkExpressionCached(declName.argumentExpression) : checkComputedPropertyName(declName); + const declName = ts.isBinaryExpression(decl) ? decl.left : decl.name; + const type = ts.isElementAccessExpression(declName) ? checkExpressionCached(declName.argumentExpression) : checkComputedPropertyName(declName); if (isTypeUsableAsPropertyName(type)) { const memberName = getPropertyNameFromType(type); const symbolFlags = decl.symbol.flags; // Get or add a late-bound symbol for the member. This allows us to merge late-bound accessor declarations. let lateSymbol = lateSymbols.get(memberName); - if (!lateSymbol) lateSymbols.set(memberName, lateSymbol = createSymbol(SymbolFlags.None, memberName, CheckFlags.Late)); + if (!lateSymbol) + lateSymbols.set(memberName, lateSymbol = createSymbol(ts.SymbolFlags.None, memberName, ts.CheckFlags.Late)); // Report an error if a late-bound member has the same name as an early-bound member, // or if we have another early-bound symbol declaration with the same name and @@ -10873,16 +10437,16 @@ namespace ts { if (lateSymbol.flags & getExcludedSymbolFlags(symbolFlags) || earlySymbol) { // If we have an existing early-bound member, combine its declarations so that we can // report an error at each declaration. - const declarations = earlySymbol ? concatenate(earlySymbol.declarations, lateSymbol.declarations) : lateSymbol.declarations; - const name = !(type.flags & TypeFlags.UniqueESSymbol) && unescapeLeadingUnderscores(memberName) || declarationNameToString(declName); - forEach(declarations, declaration => error(getNameOfDeclaration(declaration) || declaration, Diagnostics.Property_0_was_also_declared_here, name)); - error(declName || decl, Diagnostics.Duplicate_property_0, name); - lateSymbol = createSymbol(SymbolFlags.None, memberName, CheckFlags.Late); + const declarations = earlySymbol ? ts.concatenate(earlySymbol.declarations, lateSymbol.declarations) : lateSymbol.declarations; + const name = !(type.flags & ts.TypeFlags.UniqueESSymbol) && ts.unescapeLeadingUnderscores(memberName) || ts.declarationNameToString(declName); + ts.forEach(declarations, declaration => error(ts.getNameOfDeclaration(declaration) || declaration, ts.Diagnostics.Property_0_was_also_declared_here, name)); + error(declName || decl, ts.Diagnostics.Duplicate_property_0, name); + lateSymbol = createSymbol(ts.SymbolFlags.None, memberName, ts.CheckFlags.Late); } lateSymbol.nameType = type; addDeclarationToLateBoundSymbol(lateSymbol, decl, symbolFlags); if (lateSymbol.parent) { - Debug.assert(lateSymbol.parent === parent, "Existing symbol parent should match new one"); + ts.Debug.assert(lateSymbol.parent === parent, "Existing symbol parent should match new one"); } else { lateSymbol.parent = parent; @@ -10893,12 +10457,12 @@ namespace ts { return links.resolvedSymbol; } - function getResolvedMembersOrExportsOfSymbol(symbol: Symbol, resolutionKind: MembersOrExportsResolutionKind): UnderscoreEscapedMap { + function getResolvedMembersOrExportsOfSymbol(symbol: ts.Symbol, resolutionKind: MembersOrExportsResolutionKind): ts.UnderscoreEscapedMap { const links = getSymbolLinks(symbol); if (!links[resolutionKind]) { const isStatic = resolutionKind === MembersOrExportsResolutionKind.resolvedExports; const earlySymbols = !isStatic ? symbol.members : - symbol.flags & SymbolFlags.Module ? getExportsOfModuleWorker(symbol) : + symbol.flags & ts.SymbolFlags.Module ? getExportsOfModuleWorker(symbol) : symbol.exports; // In the event we recursively resolve the members/exports of the symbol, we @@ -10907,12 +10471,12 @@ namespace ts { links[resolutionKind] = earlySymbols || emptySymbols; // fill in any as-yet-unresolved late-bound members. - const lateSymbols = createSymbolTable() as UnderscoreEscapedMap; - for (const decl of symbol.declarations || emptyArray) { - const members = getMembersOfDeclaration(decl); + const lateSymbols = ts.createSymbolTable() as ts.UnderscoreEscapedMap; + for (const decl of symbol.declarations || ts.emptyArray) { + const members = ts.getMembersOfDeclaration(decl); if (members) { for (const member of members) { - if (isStatic === hasStaticModifier(member) && hasLateBindableName(member)) { + if (isStatic === ts.hasStaticModifier(member) && hasLateBindableName(member)) { lateBindMember(symbol, earlySymbols, lateSymbols, member); } } @@ -10920,13 +10484,13 @@ namespace ts { } const assignments = symbol.assignmentDeclarationMembers; if (assignments) { - const decls = arrayFrom(assignments.values()); + const decls = ts.arrayFrom(assignments.values()); for (const member of decls) { - const assignmentKind = getAssignmentDeclarationKind(member as BinaryExpression | CallExpression); - const isInstanceMember = assignmentKind === AssignmentDeclarationKind.PrototypeProperty - || isBinaryExpression(member) && isPossiblyAliasedThisProperty(member, assignmentKind) - || assignmentKind === AssignmentDeclarationKind.ObjectDefinePrototypeProperty - || assignmentKind === AssignmentDeclarationKind.Prototype; // A straight `Prototype` assignment probably can never have a computed name + const assignmentKind = ts.getAssignmentDeclarationKind(member as ts.BinaryExpression | ts.CallExpression); + const isInstanceMember = assignmentKind === ts.AssignmentDeclarationKind.PrototypeProperty + || ts.isBinaryExpression(member) && isPossiblyAliasedThisProperty(member, assignmentKind) + || assignmentKind === ts.AssignmentDeclarationKind.ObjectDefinePrototypeProperty + || assignmentKind === ts.AssignmentDeclarationKind.Prototype; // A straight `Prototype` assignment probably can never have a computed name if (isStatic === !isInstanceMember && hasLateBindableName(member)) { lateBindMember(symbol, earlySymbols, lateSymbols, member); } @@ -10944,8 +10508,8 @@ namespace ts { * * For a description of late-binding, see `lateBindMember`. */ - function getMembersOfSymbol(symbol: Symbol) { - return symbol.flags & SymbolFlags.LateBindingContainer + function getMembersOfSymbol(symbol: ts.Symbol) { + return symbol.flags & ts.SymbolFlags.LateBindingContainer ? getResolvedMembersOrExportsOfSymbol(symbol, MembersOrExportsResolutionKind.resolvedMembers) : symbol.members || emptySymbols; } @@ -10956,13 +10520,13 @@ namespace ts { * * For a description of late-binding, see `lateBindMember`. */ - function getLateBoundSymbol(symbol: Symbol): Symbol { - if (symbol.flags & SymbolFlags.ClassMember && symbol.escapedName === InternalSymbolName.Computed) { + function getLateBoundSymbol(symbol: ts.Symbol): ts.Symbol { + if (symbol.flags & ts.SymbolFlags.ClassMember && symbol.escapedName === ts.InternalSymbolName.Computed) { const links = getSymbolLinks(symbol); - if (!links.lateSymbol && some(symbol.declarations, hasLateBindableName)) { + if (!links.lateSymbol && ts.some(symbol.declarations, hasLateBindableName)) { // force late binding of members/exports. This will set the late-bound symbol const parent = getMergedSymbol(symbol.parent)!; - if (some(symbol.declarations, hasStaticModifier)) { + if (ts.some(symbol.declarations, ts.hasStaticModifier)) { getExportsOfSymbol(parent); } else { @@ -10974,30 +10538,30 @@ namespace ts { return symbol; } - function getTypeWithThisArgument(type: Type, thisArgument?: Type, needApparentType?: boolean): Type { - if (getObjectFlags(type) & ObjectFlags.Reference) { - const target = (type as TypeReference).target; - const typeArguments = getTypeArguments(type as TypeReference); - if (length(target.typeParameters) === length(typeArguments)) { - const ref = createTypeReference(target, concatenate(typeArguments, [thisArgument || target.thisType!])); + function getTypeWithThisArgument(type: ts.Type, thisArgument?: ts.Type, needApparentType?: boolean): ts.Type { + if (ts.getObjectFlags(type) & ts.ObjectFlags.Reference) { + const target = (type as ts.TypeReference).target; + const typeArguments = getTypeArguments(type as ts.TypeReference); + if (ts.length(target.typeParameters) === ts.length(typeArguments)) { + const ref = createTypeReference(target, ts.concatenate(typeArguments, [thisArgument || target.thisType!])); return needApparentType ? getApparentType(ref) : ref; } } - else if (type.flags & TypeFlags.Intersection) { - const types = sameMap((type as IntersectionType).types, t => getTypeWithThisArgument(t, thisArgument, needApparentType)); - return types !== (type as IntersectionType).types ? getIntersectionType(types) : type; + else if (type.flags & ts.TypeFlags.Intersection) { + const types = ts.sameMap((type as ts.IntersectionType).types, t => getTypeWithThisArgument(t, thisArgument, needApparentType)); + return types !== (type as ts.IntersectionType).types ? getIntersectionType(types) : type; } return needApparentType ? getApparentType(type) : type; } - function resolveObjectTypeMembers(type: ObjectType, source: InterfaceTypeWithDeclaredMembers, typeParameters: readonly TypeParameter[], typeArguments: readonly Type[]) { - let mapper: TypeMapper | undefined; - let members: SymbolTable; - let callSignatures: readonly Signature[]; - let constructSignatures: readonly Signature[]; - let indexInfos: readonly IndexInfo[]; - if (rangeEquals(typeParameters, typeArguments, 0, typeParameters.length)) { - members = source.symbol ? getMembersOfSymbol(source.symbol) : createSymbolTable(source.declaredProperties); + function resolveObjectTypeMembers(type: ts.ObjectType, source: ts.InterfaceTypeWithDeclaredMembers, typeParameters: readonly ts.TypeParameter[], typeArguments: readonly ts.Type[]) { + let mapper: ts.TypeMapper | undefined; + let members: ts.SymbolTable; + let callSignatures: readonly ts.Signature[]; + let constructSignatures: readonly ts.Signature[]; + let indexInfos: readonly ts.IndexInfo[]; + if (ts.rangeEquals(typeParameters, typeArguments, 0, typeParameters.length)) { + members = source.symbol ? getMembersOfSymbol(source.symbol) : ts.createSymbolTable(source.declaredProperties); callSignatures = source.declaredCallSignatures; constructSignatures = source.declaredConstructSignatures; indexInfos = source.declaredIndexInfos; @@ -11012,44 +10576,35 @@ namespace ts { const baseTypes = getBaseTypes(source); if (baseTypes.length) { if (source.symbol && members === getMembersOfSymbol(source.symbol)) { - members = createSymbolTable(source.declaredProperties); + members = ts.createSymbolTable(source.declaredProperties); } setStructuredTypeMembers(type, members, callSignatures, constructSignatures, indexInfos); - const thisArgument = lastOrUndefined(typeArguments); + const thisArgument = ts.lastOrUndefined(typeArguments); for (const baseType of baseTypes) { const instantiatedBaseType = thisArgument ? getTypeWithThisArgument(instantiateType(baseType, mapper), thisArgument) : baseType; addInheritedMembers(members, getPropertiesOfType(instantiatedBaseType)); - callSignatures = concatenate(callSignatures, getSignaturesOfType(instantiatedBaseType, SignatureKind.Call)); - constructSignatures = concatenate(constructSignatures, getSignaturesOfType(instantiatedBaseType, SignatureKind.Construct)); + callSignatures = ts.concatenate(callSignatures, getSignaturesOfType(instantiatedBaseType, ts.SignatureKind.Call)); + constructSignatures = ts.concatenate(constructSignatures, getSignaturesOfType(instantiatedBaseType, ts.SignatureKind.Construct)); const inheritedIndexInfos = instantiatedBaseType !== anyType ? getIndexInfosOfType(instantiatedBaseType) : [createIndexInfo(stringType, anyType, /*isReadonly*/ false)]; - indexInfos = concatenate(indexInfos, filter(inheritedIndexInfos, info => !findIndexInfo(indexInfos, info.keyType))); + indexInfos = ts.concatenate(indexInfos, ts.filter(inheritedIndexInfos, info => !findIndexInfo(indexInfos, info.keyType))); } } setStructuredTypeMembers(type, members, callSignatures, constructSignatures, indexInfos); } - function resolveClassOrInterfaceMembers(type: InterfaceType): void { - resolveObjectTypeMembers(type, resolveDeclaredMembers(type), emptyArray, emptyArray); + function resolveClassOrInterfaceMembers(type: ts.InterfaceType): void { + resolveObjectTypeMembers(type, resolveDeclaredMembers(type), ts.emptyArray, ts.emptyArray); } - function resolveTypeReferenceMembers(type: TypeReference): void { + function resolveTypeReferenceMembers(type: ts.TypeReference): void { const source = resolveDeclaredMembers(type.target); - const typeParameters = concatenate(source.typeParameters!, [source.thisType!]); + const typeParameters = ts.concatenate(source.typeParameters!, [source.thisType!]); const typeArguments = getTypeArguments(type); - const paddedTypeArguments = typeArguments.length === typeParameters.length ? typeArguments : concatenate(typeArguments, [type]); + const paddedTypeArguments = typeArguments.length === typeParameters.length ? typeArguments : ts.concatenate(typeArguments, [type]); resolveObjectTypeMembers(type, source, typeParameters, paddedTypeArguments); } - function createSignature( - declaration: SignatureDeclaration | JSDocSignature | undefined, - typeParameters: readonly TypeParameter[] | undefined, - thisParameter: Symbol | undefined, - parameters: readonly Symbol[], - resolvedReturnType: Type | undefined, - resolvedTypePredicate: TypePredicate | undefined, - minArgumentCount: number, - flags: SignatureFlags - ): Signature { + function createSignature(declaration: ts.SignatureDeclaration | ts.JSDocSignature | undefined, typeParameters: readonly ts.TypeParameter[] | undefined, thisParameter: ts.Symbol | undefined, parameters: readonly ts.Symbol[], resolvedReturnType: ts.Type | undefined, resolvedTypePredicate: ts.TypePredicate | undefined, minArgumentCount: number, flags: ts.SignatureFlags): ts.Signature { const sig = new Signature(checker, flags); sig.declaration = declaration; sig.typeParameters = typeParameters; @@ -11066,9 +10621,9 @@ namespace ts { return sig; } - function cloneSignature(sig: Signature): Signature { + function cloneSignature(sig: ts.Signature): ts.Signature { const result = createSignature(sig.declaration, sig.typeParameters, sig.thisParameter, sig.parameters, /*resolvedReturnType*/ undefined, - /*resolvedTypePredicate*/ undefined, sig.minArgumentCount, sig.flags & SignatureFlags.PropagatingFlags); + /*resolvedTypePredicate*/ undefined, sig.minArgumentCount, sig.flags & ts.SignatureFlags.PropagatingFlags); result.target = sig.target; result.mapper = sig.mapper; result.compositeSignatures = sig.compositeSignatures; @@ -11076,94 +10631,93 @@ namespace ts { return result; } - function createUnionSignature(signature: Signature, unionSignatures: Signature[]) { + function createUnionSignature(signature: ts.Signature, unionSignatures: ts.Signature[]) { const result = cloneSignature(signature); result.compositeSignatures = unionSignatures; - result.compositeKind = TypeFlags.Union; + result.compositeKind = ts.TypeFlags.Union; result.target = undefined; result.mapper = undefined; return result; } - function getOptionalCallSignature(signature: Signature, callChainFlags: SignatureFlags): Signature { - if ((signature.flags & SignatureFlags.CallChainFlags) === callChainFlags) { + function getOptionalCallSignature(signature: ts.Signature, callChainFlags: ts.SignatureFlags): ts.Signature { + if ((signature.flags & ts.SignatureFlags.CallChainFlags) === callChainFlags) { return signature; } if (!signature.optionalCallSignatureCache) { signature.optionalCallSignatureCache = {}; } - const key = callChainFlags === SignatureFlags.IsInnerCallChain ? "inner" : "outer"; + const key = callChainFlags === ts.SignatureFlags.IsInnerCallChain ? "inner" : "outer"; return signature.optionalCallSignatureCache[key] || (signature.optionalCallSignatureCache[key] = createOptionalCallSignature(signature, callChainFlags)); } - function createOptionalCallSignature(signature: Signature, callChainFlags: SignatureFlags) { - Debug.assert(callChainFlags === SignatureFlags.IsInnerCallChain || callChainFlags === SignatureFlags.IsOuterCallChain, - "An optional call signature can either be for an inner call chain or an outer call chain, but not both."); + function createOptionalCallSignature(signature: ts.Signature, callChainFlags: ts.SignatureFlags) { + ts.Debug.assert(callChainFlags === ts.SignatureFlags.IsInnerCallChain || callChainFlags === ts.SignatureFlags.IsOuterCallChain, "An optional call signature can either be for an inner call chain or an outer call chain, but not both."); const result = cloneSignature(signature); result.flags |= callChainFlags; return result; } - function getExpandedParameters(sig: Signature, skipUnionExpanding?: boolean): readonly (readonly Symbol[])[] { + function getExpandedParameters(sig: ts.Signature, skipUnionExpanding?: boolean): readonly (readonly ts.Symbol[])[] { if (signatureHasRestParameter(sig)) { const restIndex = sig.parameters.length - 1; const restType = getTypeOfSymbol(sig.parameters[restIndex]); if (isTupleType(restType)) { return [expandSignatureParametersWithTupleMembers(restType, restIndex)]; } - else if (!skipUnionExpanding && restType.flags & TypeFlags.Union && every((restType as UnionType).types, isTupleType)) { - return map((restType as UnionType).types, t => expandSignatureParametersWithTupleMembers(t as TupleTypeReference, restIndex)); + else if (!skipUnionExpanding && restType.flags & ts.TypeFlags.Union && ts.every((restType as ts.UnionType).types, isTupleType)) { + return ts.map((restType as ts.UnionType).types, t => expandSignatureParametersWithTupleMembers(t as ts.TupleTypeReference, restIndex)); } } return [sig.parameters]; - function expandSignatureParametersWithTupleMembers(restType: TupleTypeReference, restIndex: number) { + function expandSignatureParametersWithTupleMembers(restType: ts.TupleTypeReference, restIndex: number) { const elementTypes = getTypeArguments(restType); const associatedNames = restType.target.labeledElementDeclarations; - const restParams = map(elementTypes, (t, i) => { + const restParams = ts.map(elementTypes, (t, i) => { // Lookup the label from the individual tuple passed in before falling back to the signature `rest` parameter name const tupleLabelName = !!associatedNames && getTupleElementLabel(associatedNames[i]); const name = tupleLabelName || getParameterNameAtPosition(sig, restIndex + i, restType); const flags = restType.target.elementFlags[i]; - const checkFlags = flags & ElementFlags.Variable ? CheckFlags.RestParameter : - flags & ElementFlags.Optional ? CheckFlags.OptionalParameter : 0; - const symbol = createSymbol(SymbolFlags.FunctionScopedVariable, name, checkFlags); - symbol.type = flags & ElementFlags.Rest ? createArrayType(t) : t; + const checkFlags = flags & ts.ElementFlags.Variable ? ts.CheckFlags.RestParameter : + flags & ts.ElementFlags.Optional ? ts.CheckFlags.OptionalParameter : 0; + const symbol = createSymbol(ts.SymbolFlags.FunctionScopedVariable, name, checkFlags); + symbol.type = flags & ts.ElementFlags.Rest ? createArrayType(t) : t; return symbol; }); - return concatenate(sig.parameters.slice(0, restIndex), restParams); + return ts.concatenate(sig.parameters.slice(0, restIndex), restParams); } } - function getDefaultConstructSignatures(classType: InterfaceType): Signature[] { + function getDefaultConstructSignatures(classType: ts.InterfaceType): ts.Signature[] { const baseConstructorType = getBaseConstructorTypeOfClass(classType); - const baseSignatures = getSignaturesOfType(baseConstructorType, SignatureKind.Construct); - const declaration = getClassLikeDeclarationOfSymbol(classType.symbol); - const isAbstract = !!declaration && hasSyntacticModifier(declaration, ModifierFlags.Abstract); + const baseSignatures = getSignaturesOfType(baseConstructorType, ts.SignatureKind.Construct); + const declaration = ts.getClassLikeDeclarationOfSymbol(classType.symbol); + const isAbstract = !!declaration && ts.hasSyntacticModifier(declaration, ts.ModifierFlags.Abstract); if (baseSignatures.length === 0) { - return [createSignature(undefined, classType.localTypeParameters, undefined, emptyArray, classType, /*resolvedTypePredicate*/ undefined, 0, isAbstract ? SignatureFlags.Abstract : SignatureFlags.None)]; + return [createSignature(undefined, classType.localTypeParameters, undefined, ts.emptyArray, classType, /*resolvedTypePredicate*/ undefined, 0, isAbstract ? ts.SignatureFlags.Abstract : ts.SignatureFlags.None)]; } const baseTypeNode = getBaseTypeNodeOfClass(classType)!; - const isJavaScript = isInJSFile(baseTypeNode); + const isJavaScript = ts.isInJSFile(baseTypeNode); const typeArguments = typeArgumentsFromTypeReferenceNode(baseTypeNode); - const typeArgCount = length(typeArguments); - const result: Signature[] = []; + const typeArgCount = ts.length(typeArguments); + const result: ts.Signature[] = []; for (const baseSig of baseSignatures) { const minTypeArgumentCount = getMinTypeArgumentCount(baseSig.typeParameters); - const typeParamCount = length(baseSig.typeParameters); + const typeParamCount = ts.length(baseSig.typeParameters); if (isJavaScript || typeArgCount >= minTypeArgumentCount && typeArgCount <= typeParamCount) { const sig = typeParamCount ? createSignatureInstantiation(baseSig, fillMissingTypeArguments(typeArguments, baseSig.typeParameters, minTypeArgumentCount, isJavaScript)) : cloneSignature(baseSig); sig.typeParameters = classType.localTypeParameters; sig.resolvedReturnType = classType; - sig.flags = isAbstract ? sig.flags | SignatureFlags.Abstract : sig.flags & ~SignatureFlags.Abstract; + sig.flags = isAbstract ? sig.flags | ts.SignatureFlags.Abstract : sig.flags & ~ts.SignatureFlags.Abstract; result.push(sig); } } return result; } - function findMatchingSignature(signatureList: readonly Signature[], signature: Signature, partialMatch: boolean, ignoreThisTypes: boolean, ignoreReturnTypes: boolean): Signature | undefined { + function findMatchingSignature(signatureList: readonly ts.Signature[], signature: ts.Signature, partialMatch: boolean, ignoreThisTypes: boolean, ignoreReturnTypes: boolean): ts.Signature | undefined { for (const s of signatureList) { if (compareSignaturesIdentical(s, signature, partialMatch, ignoreThisTypes, ignoreReturnTypes, partialMatch ? compareTypesSubtypeOf : compareTypesIdentical)) { return s; @@ -11171,7 +10725,7 @@ namespace ts { } } - function findMatchingSignatures(signatureLists: readonly (readonly Signature[])[], signature: Signature, listIndex: number): Signature[] | undefined { + function findMatchingSignatures(signatureLists: readonly (readonly ts.Signature[])[], signature: ts.Signature, listIndex: number): ts.Signature[] | undefined { if (signature.typeParameters) { // We require an exact match for generic signatures, so we only return signatures from the first // signature list and only if they have exact matches in the other signature lists. @@ -11185,7 +10739,7 @@ namespace ts { } return [signature]; } - let result: Signature[] | undefined; + let result: ts.Signature[] | undefined; for (let i = 0; i < signatureLists.length; i++) { // Allow matching non-generic signatures to have excess parameters and different return types. // Prefer matching this types if possible. @@ -11193,7 +10747,7 @@ namespace ts { if (!match) { return undefined; } - result = appendIfUnique(result, match); + result = ts.appendIfUnique(result, match); } return result; } @@ -11202,11 +10756,12 @@ namespace ts { // Generic signatures must match exactly, but non-generic signatures are allowed to have extra optional // parameters and may differ in return types. When signatures differ in return types, the resulting return // type is the union of the constituent return types. - function getUnionSignatures(signatureLists: readonly (readonly Signature[])[]): Signature[] { - let result: Signature[] | undefined; + function getUnionSignatures(signatureLists: readonly (readonly ts.Signature[])[]): ts.Signature[] { + let result: ts.Signature[] | undefined; let indexWithLengthOverOne: number | undefined; for (let i = 0; i < signatureLists.length; i++) { - if (signatureLists[i].length === 0) return emptyArray; + if (signatureLists[i].length === 0) + return ts.emptyArray; if (signatureLists[i].length > 1) { indexWithLengthOverOne = indexWithLengthOverOne === undefined ? i : -1; // -1 is a signal there are multiple overload sets } @@ -11219,9 +10774,9 @@ namespace ts { // Union the result types when more than one signature matches if (unionSignatures.length > 1) { let thisParameter = signature.thisParameter; - const firstThisParameterOfUnionSignatures = forEach(unionSignatures, sig => sig.thisParameter); + const firstThisParameterOfUnionSignatures = ts.forEach(unionSignatures, sig => sig.thisParameter); if (firstThisParameterOfUnionSignatures) { - const thisType = getIntersectionType(mapDefined(unionSignatures, sig => sig.thisParameter && getTypeOfSymbol(sig.thisParameter))); + const thisType = getIntersectionType(ts.mapDefined(unionSignatures, sig => sig.thisParameter && getTypeOfSymbol(sig.thisParameter))); thisParameter = createSymbolWithType(firstThisParameterOfUnionSignatures, thisType); } s = createUnionSignature(signature, unionSignatures); @@ -11232,18 +10787,18 @@ namespace ts { } } } - if (!length(result) && indexWithLengthOverOne !== -1) { + if (!ts.length(result) && indexWithLengthOverOne !== -1) { // No sufficiently similar signature existed to subsume all the other signatures in the union - time to see if we can make a single // signature that handles all over them. We only do this when there are overloads in only one constituent. // (Overloads are conditional in nature and having overloads in multiple constituents would necessitate making a power set of // signatures from the type, whose ordering would be non-obvious) const masterList = signatureLists[indexWithLengthOverOne !== undefined ? indexWithLengthOverOne : 0]; - let results: Signature[] | undefined = masterList.slice(); + let results: ts.Signature[] | undefined = masterList.slice(); for (const signatures of signatureLists) { if (signatures !== masterList) { const signature = signatures[0]; - Debug.assert(!!signature, "getUnionSignatures bails early on empty signature lists and should not have empty lists on second pass"); - results = !!signature.typeParameters && some(results, s => !!s.typeParameters && !compareTypeParametersIdentical(signature.typeParameters, s.typeParameters)) ? undefined : map(results, sig => combineSignaturesOfUnionMembers(sig, signature)); + ts.Debug.assert(!!signature, "getUnionSignatures bails early on empty signature lists and should not have empty lists on second pass"); + results = !!signature.typeParameters && ts.some(results, s => !!s.typeParameters && !compareTypeParametersIdentical(signature.typeParameters, s.typeParameters)) ? undefined : ts.map(results, sig => combineSignaturesOfUnionMembers(sig, signature)); if (!results) { break; } @@ -11251,11 +10806,11 @@ namespace ts { } result = results; } - return result || emptyArray; + return result || ts.emptyArray; } - function compareTypeParametersIdentical(sourceParams: readonly TypeParameter[] | undefined, targetParams: readonly TypeParameter[] | undefined): boolean { - if (length(sourceParams) !== length(targetParams)) { + function compareTypeParametersIdentical(sourceParams: readonly ts.TypeParameter[] | undefined, targetParams: readonly ts.TypeParameter[] | undefined): boolean { + if (ts.length(sourceParams) !== ts.length(targetParams)) { return false; } if (!sourceParams || !targetParams) { @@ -11266,9 +10821,11 @@ namespace ts { for (let i = 0; i < sourceParams.length; i++) { const source = sourceParams[i]; const target = targetParams[i]; - if (source === target) continue; + if (source === target) + continue; // We instantiate the target type parameter constraints into the source types so we can recognize `` as the same as `` - if (!isTypeIdenticalTo(getConstraintFromTypeParameter(source) || unknownType, instantiateType(getConstraintFromTypeParameter(target) || unknownType, mapper))) return false; + if (!isTypeIdenticalTo(getConstraintFromTypeParameter(source) || unknownType, instantiateType(getConstraintFromTypeParameter(target) || unknownType, mapper))) + return false; // We don't compare defaults - we just use the type parameter defaults from the first signature that seems to match. // It might make sense to combine these defaults in the future, but doing so intelligently requires knowing // if the parameter is used covariantly or contravariantly (so we intersect if it's used like a parameter or union if used like a return type) @@ -11278,7 +10835,7 @@ namespace ts { return true; } - function combineUnionThisParam(left: Symbol | undefined, right: Symbol | undefined, mapper: TypeMapper | undefined): Symbol | undefined { + function combineUnionThisParam(left: ts.Symbol | undefined, right: ts.Symbol | undefined, mapper: ts.TypeMapper | undefined): ts.Symbol | undefined { if (!left || !right) { return left || right; } @@ -11289,7 +10846,7 @@ namespace ts { return createSymbolWithType(left, thisType); } - function combineUnionParameters(left: Signature, right: Signature, mapper: TypeMapper | undefined) { + function combineUnionParameters(left: ts.Signature, right: ts.Signature, mapper: ts.TypeMapper | undefined) { const leftCount = getParameterCount(left); const rightCount = getParameterCount(right); const longest = leftCount >= rightCount ? left : right; @@ -11297,7 +10854,7 @@ namespace ts { const longestCount = longest === left ? leftCount : rightCount; const eitherHasEffectiveRest = (hasEffectiveRestParameter(left) || hasEffectiveRestParameter(right)); const needsExtraRestElement = eitherHasEffectiveRest && !hasEffectiveRestParameter(longest); - const params = new Array(longestCount + (needsExtraRestElement ? 1 : 0)); + const params = new Array(longestCount + (needsExtraRestElement ? 1 : 0)); for (let i = 0; i < longestCount; i++) { let longestParamType = tryGetTypeAtPosition(longest, i)!; if (longest === right) { @@ -11317,15 +10874,12 @@ namespace ts { !leftName ? rightName : !rightName ? leftName : undefined; - const paramSymbol = createSymbol( - SymbolFlags.FunctionScopedVariable | (isOptional && !isRestParam ? SymbolFlags.Optional : 0), - paramName || `arg${i}` as __String - ); + const paramSymbol = createSymbol(ts.SymbolFlags.FunctionScopedVariable | (isOptional && !isRestParam ? ts.SymbolFlags.Optional : 0), paramName || `arg${i}` as ts.__String); paramSymbol.type = isRestParam ? createArrayType(unionParamType) : unionParamType; params[i] = paramSymbol; } if (needsExtraRestElement) { - const restParamSymbol = createSymbol(SymbolFlags.FunctionScopedVariable, "args" as __String); + const restParamSymbol = createSymbol(ts.SymbolFlags.FunctionScopedVariable, "args" as ts.__String); restParamSymbol.type = createArrayType(getTypeAtPosition(shorter, longestCount)); if (shorter === right) { restParamSymbol.type = instantiateType(restParamSymbol.type, mapper); @@ -11335,9 +10889,9 @@ namespace ts { return params; } - function combineSignaturesOfUnionMembers(left: Signature, right: Signature): Signature { + function combineSignaturesOfUnionMembers(left: ts.Signature, right: ts.Signature): ts.Signature { const typeParams = left.typeParameters || right.typeParameters; - let paramMapper: TypeMapper | undefined; + let paramMapper: ts.TypeMapper | undefined; if (left.typeParameters && right.typeParameters) { paramMapper = createTypeMapper(right.typeParameters, left.typeParameters); // We just use the type parameter defaults from the first signature @@ -11346,87 +10900,79 @@ namespace ts { const params = combineUnionParameters(left, right, paramMapper); const thisParam = combineUnionThisParam(left.thisParameter, right.thisParameter, paramMapper); const minArgCount = Math.max(left.minArgumentCount, right.minArgumentCount); - const result = createSignature( - declaration, - typeParams, - thisParam, - params, + const result = createSignature(declaration, typeParams, thisParam, params, /*resolvedReturnType*/ undefined, - /*resolvedTypePredicate*/ undefined, - minArgCount, - (left.flags | right.flags) & SignatureFlags.PropagatingFlags - ); - result.compositeKind = TypeFlags.Union; - result.compositeSignatures = concatenate(left.compositeKind !== TypeFlags.Intersection && left.compositeSignatures || [left], [right]); + /*resolvedTypePredicate*/ undefined, minArgCount, (left.flags | right.flags) & ts.SignatureFlags.PropagatingFlags); + result.compositeKind = ts.TypeFlags.Union; + result.compositeSignatures = ts.concatenate(left.compositeKind !== ts.TypeFlags.Intersection && left.compositeSignatures || [left], [right]); if (paramMapper) { - result.mapper = left.compositeKind !== TypeFlags.Intersection && left.mapper && left.compositeSignatures ? combineTypeMappers(left.mapper, paramMapper) : paramMapper; + result.mapper = left.compositeKind !== ts.TypeFlags.Intersection && left.mapper && left.compositeSignatures ? combineTypeMappers(left.mapper, paramMapper) : paramMapper; } return result; } - function getUnionIndexInfos(types: readonly Type[]): IndexInfo[] { + function getUnionIndexInfos(types: readonly ts.Type[]): ts.IndexInfo[] { const sourceInfos = getIndexInfosOfType(types[0]); if (sourceInfos) { const result = []; for (const info of sourceInfos) { const indexType = info.keyType; - if (every(types, t => !!getIndexInfoOfType(t, indexType))) { - result.push(createIndexInfo(indexType, getUnionType(map(types, t => getIndexTypeOfType(t, indexType)!)), - some(types, t => getIndexInfoOfType(t, indexType)!.isReadonly))); + if (ts.every(types, t => !!getIndexInfoOfType(t, indexType))) { + result.push(createIndexInfo(indexType, getUnionType(ts.map(types, t => getIndexTypeOfType(t, indexType)!)), ts.some(types, t => getIndexInfoOfType(t, indexType)!.isReadonly))); } } return result; } - return emptyArray; + return ts.emptyArray; } - function resolveUnionTypeMembers(type: UnionType) { + function resolveUnionTypeMembers(type: ts.UnionType) { // The members and properties collections are empty for union types. To get all properties of a union // type use getPropertiesOfType (only the language service uses this). - const callSignatures = getUnionSignatures(map(type.types, t => t === globalFunctionType ? [unknownSignature] : getSignaturesOfType(t, SignatureKind.Call))); - const constructSignatures = getUnionSignatures(map(type.types, t => getSignaturesOfType(t, SignatureKind.Construct))); + const callSignatures = getUnionSignatures(ts.map(type.types, t => t === globalFunctionType ? [unknownSignature] : getSignaturesOfType(t, ts.SignatureKind.Call))); + const constructSignatures = getUnionSignatures(ts.map(type.types, t => getSignaturesOfType(t, ts.SignatureKind.Construct))); const indexInfos = getUnionIndexInfos(type.types); setStructuredTypeMembers(type, emptySymbols, callSignatures, constructSignatures, indexInfos); } - function intersectTypes(type1: Type, type2: Type): Type; - function intersectTypes(type1: Type | undefined, type2: Type | undefined): Type | undefined; - function intersectTypes(type1: Type | undefined, type2: Type | undefined): Type | undefined { + function intersectTypes(type1: ts.Type, type2: ts.Type): ts.Type; + function intersectTypes(type1: ts.Type | undefined, type2: ts.Type | undefined): ts.Type | undefined; + function intersectTypes(type1: ts.Type | undefined, type2: ts.Type | undefined): ts.Type | undefined { return !type1 ? type2 : !type2 ? type1 : getIntersectionType([type1, type2]); } - function findMixins(types: readonly Type[]): readonly boolean[] { - const constructorTypeCount = countWhere(types, (t) => getSignaturesOfType(t, SignatureKind.Construct).length > 0); - const mixinFlags = map(types, isMixinConstructorType); - if (constructorTypeCount > 0 && constructorTypeCount === countWhere(mixinFlags, (b) => b)) { + function findMixins(types: readonly ts.Type[]): readonly boolean[] { + const constructorTypeCount = ts.countWhere(types, (t) => getSignaturesOfType(t, ts.SignatureKind.Construct).length > 0); + const mixinFlags = ts.map(types, isMixinConstructorType); + if (constructorTypeCount > 0 && constructorTypeCount === ts.countWhere(mixinFlags, (b) => b)) { const firstMixinIndex = mixinFlags.indexOf(/*searchElement*/ true); mixinFlags[firstMixinIndex] = false; } return mixinFlags; } - function includeMixinType(type: Type, types: readonly Type[], mixinFlags: readonly boolean[], index: number): Type { - const mixedTypes: Type[] = []; + function includeMixinType(type: ts.Type, types: readonly ts.Type[], mixinFlags: readonly boolean[], index: number): ts.Type { + const mixedTypes: ts.Type[] = []; for (let i = 0; i < types.length; i++) { if (i === index) { mixedTypes.push(type); } else if (mixinFlags[i]) { - mixedTypes.push(getReturnTypeOfSignature(getSignaturesOfType(types[i], SignatureKind.Construct)[0])); + mixedTypes.push(getReturnTypeOfSignature(getSignaturesOfType(types[i], ts.SignatureKind.Construct)[0])); } } return getIntersectionType(mixedTypes); } - function resolveIntersectionTypeMembers(type: IntersectionType) { + function resolveIntersectionTypeMembers(type: ts.IntersectionType) { // The members and properties collections are empty for intersection types. To get all properties of an // intersection type use getPropertiesOfType (only the language service uses this). - let callSignatures: Signature[] | undefined; - let constructSignatures: Signature[] | undefined; - let indexInfos: IndexInfo[] | undefined; + let callSignatures: ts.Signature[] | undefined; + let constructSignatures: ts.Signature[] | undefined; + let indexInfos: ts.IndexInfo[] | undefined; const types = type.types; const mixinFlags = findMixins(types); - const mixinCount = countWhere(mixinFlags, (b) => b); + const mixinCount = ts.countWhere(mixinFlags, (b) => b); for (let i = 0; i < types.length; i++) { const t = type.types[i]; // When an intersection type contains mixin constructor types, the construct signatures from @@ -11435,9 +10981,9 @@ namespace ts { // '{ new(...args: any[]) => A } & { new(s: string) => B }' has a single construct signature // 'new(s: string) => A & B'. if (!mixinFlags[i]) { - let signatures = getSignaturesOfType(t, SignatureKind.Construct); + let signatures = getSignaturesOfType(t, ts.SignatureKind.Construct); if (signatures.length && mixinCount > 0) { - signatures = map(signatures, s => { + signatures = ts.map(signatures, s => { const clone = cloneSignature(s); clone.resolvedReturnType = includeMixinType(getReturnTypeOfSignature(s), types, mixinFlags, i); return clone; @@ -11445,81 +10991,79 @@ namespace ts { } constructSignatures = appendSignatures(constructSignatures, signatures); } - callSignatures = appendSignatures(callSignatures, getSignaturesOfType(t, SignatureKind.Call)); - indexInfos = reduceLeft(getIndexInfosOfType(t), (infos, newInfo) => appendIndexInfo(infos, newInfo, /*union*/ false), indexInfos); + callSignatures = appendSignatures(callSignatures, getSignaturesOfType(t, ts.SignatureKind.Call)); + indexInfos = ts.reduceLeft(getIndexInfosOfType(t), (infos, newInfo) => appendIndexInfo(infos, newInfo, /*union*/ false), indexInfos); } - setStructuredTypeMembers(type, emptySymbols, callSignatures || emptyArray, constructSignatures || emptyArray, indexInfos || emptyArray); + setStructuredTypeMembers(type, emptySymbols, callSignatures || ts.emptyArray, constructSignatures || ts.emptyArray, indexInfos || ts.emptyArray); } - function appendSignatures(signatures: Signature[] | undefined, newSignatures: readonly Signature[]) { + function appendSignatures(signatures: ts.Signature[] | undefined, newSignatures: readonly ts.Signature[]) { for (const sig of newSignatures) { - if (!signatures || every(signatures, s => !compareSignaturesIdentical(s, sig, /*partialMatch*/ false, /*ignoreThisTypes*/ false, /*ignoreReturnTypes*/ false, compareTypesIdentical))) { - signatures = append(signatures, sig); + if (!signatures || ts.every(signatures, s => !compareSignaturesIdentical(s, sig, /*partialMatch*/ false, /*ignoreThisTypes*/ false, /*ignoreReturnTypes*/ false, compareTypesIdentical))) { + signatures = ts.append(signatures, sig); } } return signatures; } - function appendIndexInfo(indexInfos: IndexInfo[] | undefined, newInfo: IndexInfo, union: boolean) { + function appendIndexInfo(indexInfos: ts.IndexInfo[] | undefined, newInfo: ts.IndexInfo, union: boolean) { if (indexInfos) { for (let i = 0; i < indexInfos.length; i++) { const info = indexInfos[i]; if (info.keyType === newInfo.keyType) { - indexInfos[i] = createIndexInfo(info.keyType, - union ? getUnionType([info.type, newInfo.type]) : getIntersectionType([info.type, newInfo.type]), - union ? info.isReadonly || newInfo.isReadonly : info.isReadonly && newInfo.isReadonly); + indexInfos[i] = createIndexInfo(info.keyType, union ? getUnionType([info.type, newInfo.type]) : getIntersectionType([info.type, newInfo.type]), union ? info.isReadonly || newInfo.isReadonly : info.isReadonly && newInfo.isReadonly); return indexInfos; } } } - return append(indexInfos, newInfo); + return ts.append(indexInfos, newInfo); } /** * Converts an AnonymousType to a ResolvedType. */ - function resolveAnonymousTypeMembers(type: AnonymousType) { + function resolveAnonymousTypeMembers(type: ts.AnonymousType) { if (type.target) { - setStructuredTypeMembers(type, emptySymbols, emptyArray, emptyArray, emptyArray); + setStructuredTypeMembers(type, emptySymbols, ts.emptyArray, ts.emptyArray, ts.emptyArray); const members = createInstantiatedSymbolTable(getPropertiesOfObjectType(type.target), type.mapper!, /*mappingThisOnly*/ false); - const callSignatures = instantiateSignatures(getSignaturesOfType(type.target, SignatureKind.Call), type.mapper!); - const constructSignatures = instantiateSignatures(getSignaturesOfType(type.target, SignatureKind.Construct), type.mapper!); + const callSignatures = instantiateSignatures(getSignaturesOfType(type.target, ts.SignatureKind.Call), type.mapper!); + const constructSignatures = instantiateSignatures(getSignaturesOfType(type.target, ts.SignatureKind.Construct), type.mapper!); const indexInfos = instantiateIndexInfos(getIndexInfosOfType(type.target), type.mapper!); setStructuredTypeMembers(type, members, callSignatures, constructSignatures, indexInfos); return; } const symbol = getMergedSymbol(type.symbol); - if (symbol.flags & SymbolFlags.TypeLiteral) { - setStructuredTypeMembers(type, emptySymbols, emptyArray, emptyArray, emptyArray); + if (symbol.flags & ts.SymbolFlags.TypeLiteral) { + setStructuredTypeMembers(type, emptySymbols, ts.emptyArray, ts.emptyArray, ts.emptyArray); const members = getMembersOfSymbol(symbol); - const callSignatures = getSignaturesOfSymbol(members.get(InternalSymbolName.Call)); - const constructSignatures = getSignaturesOfSymbol(members.get(InternalSymbolName.New)); + const callSignatures = getSignaturesOfSymbol(members.get(ts.InternalSymbolName.Call)); + const constructSignatures = getSignaturesOfSymbol(members.get(ts.InternalSymbolName.New)); const indexInfos = getIndexInfosOfSymbol(symbol); setStructuredTypeMembers(type, members, callSignatures, constructSignatures, indexInfos); return; } // Combinations of function, class, enum and module let members = emptySymbols; - let indexInfos: IndexInfo[] | undefined; + let indexInfos: ts.IndexInfo[] | undefined; if (symbol.exports) { members = getExportsOfSymbol(symbol); if (symbol === globalThisSymbol) { - const varsOnly = new Map() as SymbolTable; + const varsOnly = new ts.Map() as ts.SymbolTable; members.forEach(p => { - if (!(p.flags & SymbolFlags.BlockScoped) && !(p.flags & SymbolFlags.ValueModule && p.declarations?.length && every(p.declarations, isAmbientModule))) { + if (!(p.flags & ts.SymbolFlags.BlockScoped) && !(p.flags & ts.SymbolFlags.ValueModule && p.declarations?.length && ts.every(p.declarations, ts.isAmbientModule))) { varsOnly.set(p.escapedName, p); } }); members = varsOnly; } } - let baseConstructorIndexInfo: IndexInfo | undefined; - setStructuredTypeMembers(type, members, emptyArray, emptyArray, emptyArray); - if (symbol.flags & SymbolFlags.Class) { + let baseConstructorIndexInfo: ts.IndexInfo | undefined; + setStructuredTypeMembers(type, members, ts.emptyArray, ts.emptyArray, ts.emptyArray); + if (symbol.flags & ts.SymbolFlags.Class) { const classType = getDeclaredTypeOfClassOrInterface(symbol); const baseConstructorType = getBaseConstructorTypeOfClass(classType); - if (baseConstructorType.flags & (TypeFlags.Object | TypeFlags.Intersection | TypeFlags.TypeVariable)) { - members = createSymbolTable(getNamedOrIndexSignatureMembers(members)); + if (baseConstructorType.flags & (ts.TypeFlags.Object | ts.TypeFlags.Intersection | ts.TypeFlags.TypeVariable)) { + members = ts.createSymbolTable(getNamedOrIndexSignatureMembers(members)); addInheritedMembers(members, getPropertiesOfType(baseConstructorType)); } else if (baseConstructorType === anyType) { @@ -11533,30 +11077,28 @@ namespace ts { } else { if (baseConstructorIndexInfo) { - indexInfos = append(indexInfos, baseConstructorIndexInfo); + indexInfos = ts.append(indexInfos, baseConstructorIndexInfo); } - if (symbol.flags & SymbolFlags.Enum && (getDeclaredTypeOfSymbol(symbol).flags & TypeFlags.Enum || - some(type.properties, prop => !!(getTypeOfSymbol(prop).flags & TypeFlags.NumberLike)))) { - indexInfos = append(indexInfos, enumNumberIndexInfo); + if (symbol.flags & ts.SymbolFlags.Enum && (getDeclaredTypeOfSymbol(symbol).flags & ts.TypeFlags.Enum || + ts.some(type.properties, prop => !!(getTypeOfSymbol(prop).flags & ts.TypeFlags.NumberLike)))) { + indexInfos = ts.append(indexInfos, enumNumberIndexInfo); } } - setStructuredTypeMembers(type, members, emptyArray, emptyArray, indexInfos || emptyArray); + setStructuredTypeMembers(type, members, ts.emptyArray, ts.emptyArray, indexInfos || ts.emptyArray); // We resolve the members before computing the signatures because a signature may use // typeof with a qualified name expression that circularly references the type we are // in the process of resolving (see issue #6072). The temporarily empty signature list // will never be observed because a qualified name can't reference signatures. - if (symbol.flags & (SymbolFlags.Function | SymbolFlags.Method)) { + if (symbol.flags & (ts.SymbolFlags.Function | ts.SymbolFlags.Method)) { type.callSignatures = getSignaturesOfSymbol(symbol); } // And likewise for construct signatures for classes - if (symbol.flags & SymbolFlags.Class) { + if (symbol.flags & ts.SymbolFlags.Class) { const classType = getDeclaredTypeOfClassOrInterface(symbol); - let constructSignatures = symbol.members ? getSignaturesOfSymbol(symbol.members.get(InternalSymbolName.Constructor)) : emptyArray; - if (symbol.flags & SymbolFlags.Function) { - constructSignatures = addRange(constructSignatures.slice(), mapDefined( - type.callSignatures, - sig => isJSConstructor(sig.declaration) ? - createSignature(sig.declaration, sig.typeParameters, sig.thisParameter, sig.parameters, classType, /*resolvedTypePredicate*/ undefined, sig.minArgumentCount, sig.flags & SignatureFlags.PropagatingFlags) : + let constructSignatures = symbol.members ? getSignaturesOfSymbol(symbol.members.get(ts.InternalSymbolName.Constructor)) : ts.emptyArray; + if (symbol.flags & ts.SymbolFlags.Function) { + constructSignatures = ts.addRange(constructSignatures.slice(), ts.mapDefined(type.callSignatures, sig => isJSConstructor(sig.declaration) ? + createSignature(sig.declaration, sig.typeParameters, sig.thisParameter, sig.parameters, classType, /*resolvedTypePredicate*/ undefined, sig.minArgumentCount, sig.flags & ts.SignatureFlags.PropagatingFlags) : undefined)); } if (!constructSignatures.length) { @@ -11566,37 +11108,40 @@ namespace ts { } } - type ReplaceableIndexedAccessType = IndexedAccessType & { objectType: TypeParameter, indexType: TypeParameter }; - function replaceIndexedAccess(instantiable: Type, type: ReplaceableIndexedAccessType, replacement: Type) { + type ReplaceableIndexedAccessType = ts.IndexedAccessType & { + objectType: ts.TypeParameter; + indexType: ts.TypeParameter; + }; + function replaceIndexedAccess(instantiable: ts.Type, type: ReplaceableIndexedAccessType, replacement: ts.Type) { // map type.indexType to 0 // map type.objectType to `[TReplacement]` // thus making the indexed access `[TReplacement][0]` or `TReplacement` return instantiateType(instantiable, createTypeMapper([type.indexType, type.objectType], [getNumberLiteralType(0), createTupleType([replacement])])); } - function resolveReverseMappedTypeMembers(type: ReverseMappedType) { + function resolveReverseMappedTypeMembers(type: ts.ReverseMappedType) { const indexInfo = getIndexInfoOfType(type.source, stringType); const modifiers = getMappedTypeModifiers(type.mappedType); const readonlyMask = modifiers & MappedTypeModifiers.IncludeReadonly ? false : true; - const optionalMask = modifiers & MappedTypeModifiers.IncludeOptional ? 0 : SymbolFlags.Optional; - const indexInfos = indexInfo ? [createIndexInfo(stringType, inferReverseMappedType(indexInfo.type, type.mappedType, type.constraintType), readonlyMask && indexInfo.isReadonly)] : emptyArray; - const members = createSymbolTable(); + const optionalMask = modifiers & MappedTypeModifiers.IncludeOptional ? 0 : ts.SymbolFlags.Optional; + const indexInfos = indexInfo ? [createIndexInfo(stringType, inferReverseMappedType(indexInfo.type, type.mappedType, type.constraintType), readonlyMask && indexInfo.isReadonly)] : ts.emptyArray; + const members = ts.createSymbolTable(); for (const prop of getPropertiesOfType(type.source)) { - const checkFlags = CheckFlags.ReverseMapped | (readonlyMask && isReadonlySymbol(prop) ? CheckFlags.Readonly : 0); - const inferredProp = createSymbol(SymbolFlags.Property | prop.flags & optionalMask, prop.escapedName, checkFlags) as ReverseMappedSymbol; + const checkFlags = ts.CheckFlags.ReverseMapped | (readonlyMask && isReadonlySymbol(prop) ? ts.CheckFlags.Readonly : 0); + const inferredProp = createSymbol(ts.SymbolFlags.Property | prop.flags & optionalMask, prop.escapedName, checkFlags) as ts.ReverseMappedSymbol; inferredProp.declarations = prop.declarations; inferredProp.nameType = getSymbolLinks(prop).nameType; inferredProp.propertyType = getTypeOfSymbol(prop); - if (type.constraintType.type.flags & TypeFlags.IndexedAccess - && (type.constraintType.type as IndexedAccessType).objectType.flags & TypeFlags.TypeParameter - && (type.constraintType.type as IndexedAccessType).indexType.flags & TypeFlags.TypeParameter) { + if (type.constraintType.type.flags & ts.TypeFlags.IndexedAccess + && (type.constraintType.type as ts.IndexedAccessType).objectType.flags & ts.TypeFlags.TypeParameter + && (type.constraintType.type as ts.IndexedAccessType).indexType.flags & ts.TypeFlags.TypeParameter) { // A reverse mapping of `{[K in keyof T[K_1]]: T[K_1]}` is the same as that of `{[K in keyof T]: T}`, since all we care about is // inferring to the "type parameter" (or indexed access) shared by the constraint and template. So, to reduce the number of // type identities produced, we simplify such indexed access occurences - const newTypeParam = (type.constraintType.type as IndexedAccessType).objectType; + const newTypeParam = (type.constraintType.type as ts.IndexedAccessType).objectType; const newMappedType = replaceIndexedAccess(type.mappedType, type.constraintType.type as ReplaceableIndexedAccessType, newTypeParam); - inferredProp.mappedType = newMappedType as MappedType; - inferredProp.constraintType = getIndexType(newTypeParam) as IndexType; + inferredProp.mappedType = newMappedType as ts.MappedType; + inferredProp.constraintType = getIndexType(newTypeParam) as ts.IndexType; } else { inferredProp.mappedType = type.mappedType; @@ -11604,50 +11149,50 @@ namespace ts { } members.set(prop.escapedName, inferredProp); } - setStructuredTypeMembers(type, members, emptyArray, emptyArray, indexInfos); + setStructuredTypeMembers(type, members, ts.emptyArray, ts.emptyArray, indexInfos); } // Return the lower bound of the key type in a mapped type. Intuitively, the lower // bound includes those keys that are known to always be present, for example because // because of constraints on type parameters (e.g. 'keyof T' for a constrained T). - function getLowerBoundOfKeyType(type: Type): Type { - if (type.flags & TypeFlags.Index) { - const t = getApparentType((type as IndexType).type); + function getLowerBoundOfKeyType(type: ts.Type): ts.Type { + if (type.flags & ts.TypeFlags.Index) { + const t = getApparentType((type as ts.IndexType).type); return isGenericTupleType(t) ? getKnownKeysOfTupleType(t) : getIndexType(t); } - if (type.flags & TypeFlags.Conditional) { - if ((type as ConditionalType).root.isDistributive) { - const checkType = (type as ConditionalType).checkType; + if (type.flags & ts.TypeFlags.Conditional) { + if ((type as ts.ConditionalType).root.isDistributive) { + const checkType = (type as ts.ConditionalType).checkType; const constraint = getLowerBoundOfKeyType(checkType); if (constraint !== checkType) { - return getConditionalTypeInstantiation(type as ConditionalType, prependTypeMapping((type as ConditionalType).root.checkType, constraint, (type as ConditionalType).mapper)); + return getConditionalTypeInstantiation(type as ts.ConditionalType, prependTypeMapping((type as ts.ConditionalType).root.checkType, constraint, (type as ts.ConditionalType).mapper)); } } return type; } - if (type.flags & TypeFlags.Union) { - return mapType(type as UnionType, getLowerBoundOfKeyType); + if (type.flags & ts.TypeFlags.Union) { + return mapType(type as ts.UnionType, getLowerBoundOfKeyType); } - if (type.flags & TypeFlags.Intersection) { - return getIntersectionType(sameMap((type as UnionType).types, getLowerBoundOfKeyType)); + if (type.flags & ts.TypeFlags.Intersection) { + return getIntersectionType(ts.sameMap((type as ts.UnionType).types, getLowerBoundOfKeyType)); } return type; } - function getIsLateCheckFlag(s: Symbol): CheckFlags { - return getCheckFlags(s) & CheckFlags.Late; + function getIsLateCheckFlag(s: ts.Symbol): ts.CheckFlags { + return ts.getCheckFlags(s) & ts.CheckFlags.Late; } - function forEachMappedTypePropertyKeyTypeAndIndexSignatureKeyType(type: Type, include: TypeFlags, stringsOnly: boolean, cb: (keyType: Type) => void) { + function forEachMappedTypePropertyKeyTypeAndIndexSignatureKeyType(type: ts.Type, include: ts.TypeFlags, stringsOnly: boolean, cb: (keyType: ts.Type) => void) { for (const prop of getPropertiesOfType(type)) { cb(getLiteralTypeFromProperty(prop, include)); } - if (type.flags & TypeFlags.Any) { + if (type.flags & ts.TypeFlags.Any) { cb(stringType); } else { for (const info of getIndexInfosOfType(type)) { - if (!stringsOnly || info.keyType.flags & (TypeFlags.String | TypeFlags.TemplateLiteral)) { + if (!stringsOnly || info.keyType.flags & (ts.TypeFlags.String | ts.TypeFlags.TemplateLiteral)) { cb(info.keyType); } } @@ -11655,20 +11200,20 @@ namespace ts { } /** Resolve the members of a mapped type { [P in K]: T } */ - function resolveMappedTypeMembers(type: MappedType) { - const members: SymbolTable = createSymbolTable(); - let indexInfos: IndexInfo[] | undefined; + function resolveMappedTypeMembers(type: ts.MappedType) { + const members: ts.SymbolTable = ts.createSymbolTable(); + let indexInfos: ts.IndexInfo[] | undefined; // Resolve upfront such that recursive references see an empty object type. - setStructuredTypeMembers(type, emptySymbols, emptyArray, emptyArray, emptyArray); + setStructuredTypeMembers(type, emptySymbols, ts.emptyArray, ts.emptyArray, ts.emptyArray); // In { [P in K]: T }, we refer to P as the type parameter type, K as the constraint type, // and T as the template type. const typeParameter = getTypeParameterFromMappedType(type); const constraintType = getConstraintTypeFromMappedType(type); - const nameType = getNameTypeFromMappedType(type.target as MappedType || type); - const templateType = getTemplateTypeFromMappedType(type.target as MappedType || type); + const nameType = getNameTypeFromMappedType(type.target as ts.MappedType || type); + const templateType = getTemplateTypeFromMappedType(type.target as ts.MappedType || type); const modifiersType = getApparentType(getModifiersTypeFromMappedType(type)); // The 'T' in 'keyof T' const templateModifiers = getMappedTypeModifiers(type); - const include = keyofStringsOnly ? TypeFlags.StringLiteral : TypeFlags.StringOrNumberLiteralOrUnique; + const include = keyofStringsOnly ? ts.TypeFlags.StringLiteral : ts.TypeFlags.StringOrNumberLiteralOrUnique; if (isMappedTypeWithKeyofConstraintDeclaration(type)) { // We have a { [P in keyof T]: X } forEachMappedTypePropertyKeyTypeAndIndexSignatureKeyType(modifiersType, include, keyofStringsOnly, addMemberForKeyType); @@ -11676,14 +11221,13 @@ namespace ts { else { forEachType(getLowerBoundOfKeyType(constraintType), addMemberForKeyType); } - setStructuredTypeMembers(type, members, emptyArray, emptyArray, indexInfos || emptyArray); - - function addMemberForKeyType(keyType: Type) { + setStructuredTypeMembers(type, members, ts.emptyArray, ts.emptyArray, indexInfos || ts.emptyArray); + function addMemberForKeyType(keyType: ts.Type) { const propNameType = nameType ? instantiateType(nameType, appendTypeMapping(type.mapper, typeParameter, keyType)) : keyType; forEachType(propNameType, t => addMemberForKeyTypeWorker(keyType, t)); } - function addMemberForKeyTypeWorker(keyType: Type, propNameType: Type) { + function addMemberForKeyTypeWorker(keyType: ts.Type, propNameType: ts.Type) { // If the current iteration type constituent is a string literal type, create a property. // Otherwise, for type string create a string index signature. if (isTypeUsableAsPropertyName(propNameType)) { @@ -11691,7 +11235,7 @@ namespace ts { // String enum members from separate enums with identical values // are distinct types with the same property name. Make the resulting // property symbol's name type be the union of those enum member types. - const existingProp = members.get(propName) as MappedSymbol | undefined; + const existingProp = members.get(propName) as ts.MappedSymbol | undefined; if (existingProp) { existingProp.nameType = getUnionType([existingProp.nameType!, propNameType]); existingProp.keyType = getUnionType([existingProp.keyType, keyType]); @@ -11699,13 +11243,12 @@ namespace ts { else { const modifiersProp = isTypeUsableAsPropertyName(keyType) ? getPropertyOfType(modifiersType, getPropertyNameFromType(keyType)) : undefined; const isOptional = !!(templateModifiers & MappedTypeModifiers.IncludeOptional || - !(templateModifiers & MappedTypeModifiers.ExcludeOptional) && modifiersProp && modifiersProp.flags & SymbolFlags.Optional); + !(templateModifiers & MappedTypeModifiers.ExcludeOptional) && modifiersProp && modifiersProp.flags & ts.SymbolFlags.Optional); const isReadonly = !!(templateModifiers & MappedTypeModifiers.IncludeReadonly || !(templateModifiers & MappedTypeModifiers.ExcludeReadonly) && modifiersProp && isReadonlySymbol(modifiersProp)); - const stripOptional = strictNullChecks && !isOptional && modifiersProp && modifiersProp.flags & SymbolFlags.Optional; - const lateFlag: CheckFlags = modifiersProp ? getIsLateCheckFlag(modifiersProp) : 0; - const prop = createSymbol(SymbolFlags.Property | (isOptional ? SymbolFlags.Optional : 0), propName, - lateFlag | CheckFlags.Mapped | (isReadonly ? CheckFlags.Readonly : 0) | (stripOptional ? CheckFlags.StripOptional : 0)) as MappedSymbol; + const stripOptional = strictNullChecks && !isOptional && modifiersProp && modifiersProp.flags & ts.SymbolFlags.Optional; + const lateFlag: ts.CheckFlags = modifiersProp ? getIsLateCheckFlag(modifiersProp) : 0; + const prop = createSymbol(ts.SymbolFlags.Property | (isOptional ? ts.SymbolFlags.Optional : 0), propName, lateFlag | ts.CheckFlags.Mapped | (isReadonly ? ts.CheckFlags.Readonly : 0) | (stripOptional ? ts.CheckFlags.StripOptional : 0)) as ts.MappedSymbol; prop.mappedType = type; prop.nameType = propNameType; prop.keyType = keyType; @@ -11718,9 +11261,9 @@ namespace ts { members.set(propName, prop); } } - else if (isValidIndexKeyType(propNameType) || propNameType.flags & (TypeFlags.Any | TypeFlags.Enum)) { - const indexKeyType = propNameType.flags & (TypeFlags.Any | TypeFlags.String) ? stringType : - propNameType.flags & (TypeFlags.Number | TypeFlags.Enum) ? numberType : + else if (isValidIndexKeyType(propNameType) || propNameType.flags & (ts.TypeFlags.Any | ts.TypeFlags.Enum)) { + const indexKeyType = propNameType.flags & (ts.TypeFlags.Any | ts.TypeFlags.String) ? stringType : + propNameType.flags & (ts.TypeFlags.Number | ts.TypeFlags.Enum) ? numberType : propNameType; const propType = instantiateType(templateType, appendTypeMapping(type.mapper, typeParameter, keyType)); const indexInfo = createIndexInfo(indexKeyType, propType, !!(templateModifiers & MappedTypeModifiers.IncludeReadonly)); @@ -11729,24 +11272,24 @@ namespace ts { } } - function getTypeOfMappedSymbol(symbol: MappedSymbol) { + function getTypeOfMappedSymbol(symbol: ts.MappedSymbol) { if (!symbol.type) { const mappedType = symbol.mappedType; if (!pushTypeResolution(symbol, TypeSystemPropertyName.Type)) { mappedType.containsError = true; return errorType; } - const templateType = getTemplateTypeFromMappedType(mappedType.target as MappedType || mappedType); + const templateType = getTemplateTypeFromMappedType(mappedType.target as ts.MappedType || mappedType); const mapper = appendTypeMapping(mappedType.mapper, getTypeParameterFromMappedType(mappedType), symbol.keyType); const propType = instantiateType(templateType, mapper); // When creating an optional property in strictNullChecks mode, if 'undefined' isn't assignable to the // type, we include 'undefined' in the type. Similarly, when creating a non-optional property in strictNullChecks // mode, if the underlying property is optional we remove 'undefined' from the type. - let type = strictNullChecks && symbol.flags & SymbolFlags.Optional && !maybeTypeOfKind(propType, TypeFlags.Undefined | TypeFlags.Void) ? getOptionalType(propType, /*isProperty*/ true) : - symbol.checkFlags & CheckFlags.StripOptional ? removeMissingOrUndefinedType(propType) : + let type = strictNullChecks && symbol.flags & ts.SymbolFlags.Optional && !maybeTypeOfKind(propType, ts.TypeFlags.Undefined | ts.TypeFlags.Void) ? getOptionalType(propType, /*isProperty*/ true) : + symbol.checkFlags & ts.CheckFlags.StripOptional ? removeMissingOrUndefinedType(propType) : propType; if (!popTypeResolution()) { - error(currentNode, Diagnostics.Type_of_property_0_circularly_references_itself_in_mapped_type_1, symbolToString(symbol), typeToString(mappedType)); + error(currentNode, ts.Diagnostics.Type_of_property_0_circularly_references_itself_in_mapped_type_1, symbolToString(symbol), typeToString(mappedType)); type = errorType; } symbol.type = type; @@ -11754,128 +11297,128 @@ namespace ts { return symbol.type; } - function getTypeParameterFromMappedType(type: MappedType) { + function getTypeParameterFromMappedType(type: ts.MappedType) { return type.typeParameter || (type.typeParameter = getDeclaredTypeOfTypeParameter(getSymbolOfNode(type.declaration.typeParameter))); } - function getConstraintTypeFromMappedType(type: MappedType) { + function getConstraintTypeFromMappedType(type: ts.MappedType) { return type.constraintType || (type.constraintType = getConstraintOfTypeParameter(getTypeParameterFromMappedType(type)) || errorType); } - function getNameTypeFromMappedType(type: MappedType) { + function getNameTypeFromMappedType(type: ts.MappedType) { return type.declaration.nameType ? type.nameType || (type.nameType = instantiateType(getTypeFromTypeNode(type.declaration.nameType), type.mapper)) : undefined; } - function getTemplateTypeFromMappedType(type: MappedType) { + function getTemplateTypeFromMappedType(type: ts.MappedType) { return type.templateType || (type.templateType = type.declaration.type ? instantiateType(addOptionality(getTypeFromTypeNode(type.declaration.type), /*isProperty*/ true, !!(getMappedTypeModifiers(type) & MappedTypeModifiers.IncludeOptional)), type.mapper) : errorType); } - function getConstraintDeclarationForMappedType(type: MappedType) { - return getEffectiveConstraintOfTypeParameter(type.declaration.typeParameter); + function getConstraintDeclarationForMappedType(type: ts.MappedType) { + return ts.getEffectiveConstraintOfTypeParameter(type.declaration.typeParameter); } - function isMappedTypeWithKeyofConstraintDeclaration(type: MappedType) { + function isMappedTypeWithKeyofConstraintDeclaration(type: ts.MappedType) { const constraintDeclaration = getConstraintDeclarationForMappedType(type)!; // TODO: GH#18217 - return constraintDeclaration.kind === SyntaxKind.TypeOperator && - (constraintDeclaration as TypeOperatorNode).operator === SyntaxKind.KeyOfKeyword; + return constraintDeclaration.kind === ts.SyntaxKind.TypeOperator && + (constraintDeclaration as ts.TypeOperatorNode).operator === ts.SyntaxKind.KeyOfKeyword; } - function getModifiersTypeFromMappedType(type: MappedType) { + function getModifiersTypeFromMappedType(type: ts.MappedType) { if (!type.modifiersType) { if (isMappedTypeWithKeyofConstraintDeclaration(type)) { // If the constraint declaration is a 'keyof T' node, the modifiers type is T. We check // AST nodes here because, when T is a non-generic type, the logic below eagerly resolves // 'keyof T' to a literal union type and we can't recover T from that type. - type.modifiersType = instantiateType(getTypeFromTypeNode((getConstraintDeclarationForMappedType(type) as TypeOperatorNode).type), type.mapper); + type.modifiersType = instantiateType(getTypeFromTypeNode((getConstraintDeclarationForMappedType(type) as ts.TypeOperatorNode).type), type.mapper); } else { // Otherwise, get the declared constraint type, and if the constraint type is a type parameter, // get the constraint of that type parameter. If the resulting type is an indexed type 'keyof T', // the modifiers type is T. Otherwise, the modifiers type is unknown. - const declaredType = getTypeFromMappedTypeNode(type.declaration) as MappedType; + const declaredType = getTypeFromMappedTypeNode(type.declaration) as ts.MappedType; const constraint = getConstraintTypeFromMappedType(declaredType); - const extendedConstraint = constraint && constraint.flags & TypeFlags.TypeParameter ? getConstraintOfTypeParameter(constraint as TypeParameter) : constraint; - type.modifiersType = extendedConstraint && extendedConstraint.flags & TypeFlags.Index ? instantiateType((extendedConstraint as IndexType).type, type.mapper) : unknownType; + const extendedConstraint = constraint && constraint.flags & ts.TypeFlags.TypeParameter ? getConstraintOfTypeParameter(constraint as ts.TypeParameter) : constraint; + type.modifiersType = extendedConstraint && extendedConstraint.flags & ts.TypeFlags.Index ? instantiateType((extendedConstraint as ts.IndexType).type, type.mapper) : unknownType; } } return type.modifiersType; } - function getMappedTypeModifiers(type: MappedType): MappedTypeModifiers { + function getMappedTypeModifiers(type: ts.MappedType): MappedTypeModifiers { const declaration = type.declaration; - return (declaration.readonlyToken ? declaration.readonlyToken.kind === SyntaxKind.MinusToken ? MappedTypeModifiers.ExcludeReadonly : MappedTypeModifiers.IncludeReadonly : 0) | - (declaration.questionToken ? declaration.questionToken.kind === SyntaxKind.MinusToken ? MappedTypeModifiers.ExcludeOptional : MappedTypeModifiers.IncludeOptional : 0); + return (declaration.readonlyToken ? declaration.readonlyToken.kind === ts.SyntaxKind.MinusToken ? MappedTypeModifiers.ExcludeReadonly : MappedTypeModifiers.IncludeReadonly : 0) | + (declaration.questionToken ? declaration.questionToken.kind === ts.SyntaxKind.MinusToken ? MappedTypeModifiers.ExcludeOptional : MappedTypeModifiers.IncludeOptional : 0); } - function getMappedTypeOptionality(type: MappedType): number { + function getMappedTypeOptionality(type: ts.MappedType): number { const modifiers = getMappedTypeModifiers(type); return modifiers & MappedTypeModifiers.ExcludeOptional ? -1 : modifiers & MappedTypeModifiers.IncludeOptional ? 1 : 0; } - function getCombinedMappedTypeOptionality(type: MappedType): number { + function getCombinedMappedTypeOptionality(type: ts.MappedType): number { const optionality = getMappedTypeOptionality(type); const modifiersType = getModifiersTypeFromMappedType(type); return optionality || (isGenericMappedType(modifiersType) ? getMappedTypeOptionality(modifiersType) : 0); } - function isPartialMappedType(type: Type) { - return !!(getObjectFlags(type) & ObjectFlags.Mapped && getMappedTypeModifiers(type as MappedType) & MappedTypeModifiers.IncludeOptional); + function isPartialMappedType(type: ts.Type) { + return !!(ts.getObjectFlags(type) & ts.ObjectFlags.Mapped && getMappedTypeModifiers(type as ts.MappedType) & MappedTypeModifiers.IncludeOptional); } - function isGenericMappedType(type: Type): type is MappedType { - return !!(getObjectFlags(type) & ObjectFlags.Mapped) && isGenericIndexType(getConstraintTypeFromMappedType(type as MappedType)); + function isGenericMappedType(type: ts.Type): type is ts.MappedType { + return !!(ts.getObjectFlags(type) & ts.ObjectFlags.Mapped) && isGenericIndexType(getConstraintTypeFromMappedType(type as ts.MappedType)); } - function resolveStructuredTypeMembers(type: StructuredType): ResolvedType { - if (!(type as ResolvedType).members) { - if (type.flags & TypeFlags.Object) { - if ((type as ObjectType).objectFlags & ObjectFlags.Reference) { - resolveTypeReferenceMembers(type as TypeReference); + function resolveStructuredTypeMembers(type: ts.StructuredType): ts.ResolvedType { + if (!(type as ts.ResolvedType).members) { + if (type.flags & ts.TypeFlags.Object) { + if ((type as ts.ObjectType).objectFlags & ts.ObjectFlags.Reference) { + resolveTypeReferenceMembers(type as ts.TypeReference); } - else if ((type as ObjectType).objectFlags & ObjectFlags.ClassOrInterface) { - resolveClassOrInterfaceMembers(type as InterfaceType); + else if ((type as ts.ObjectType).objectFlags & ts.ObjectFlags.ClassOrInterface) { + resolveClassOrInterfaceMembers(type as ts.InterfaceType); } - else if ((type as ReverseMappedType).objectFlags & ObjectFlags.ReverseMapped) { - resolveReverseMappedTypeMembers(type as ReverseMappedType); + else if ((type as ts.ReverseMappedType).objectFlags & ts.ObjectFlags.ReverseMapped) { + resolveReverseMappedTypeMembers(type as ts.ReverseMappedType); } - else if ((type as ObjectType).objectFlags & ObjectFlags.Anonymous) { - resolveAnonymousTypeMembers(type as AnonymousType); + else if ((type as ts.ObjectType).objectFlags & ts.ObjectFlags.Anonymous) { + resolveAnonymousTypeMembers(type as ts.AnonymousType); } - else if ((type as MappedType).objectFlags & ObjectFlags.Mapped) { - resolveMappedTypeMembers(type as MappedType); + else if ((type as ts.MappedType).objectFlags & ts.ObjectFlags.Mapped) { + resolveMappedTypeMembers(type as ts.MappedType); } } - else if (type.flags & TypeFlags.Union) { - resolveUnionTypeMembers(type as UnionType); + else if (type.flags & ts.TypeFlags.Union) { + resolveUnionTypeMembers(type as ts.UnionType); } - else if (type.flags & TypeFlags.Intersection) { - resolveIntersectionTypeMembers(type as IntersectionType); + else if (type.flags & ts.TypeFlags.Intersection) { + resolveIntersectionTypeMembers(type as ts.IntersectionType); } } - return type as ResolvedType; + return type as ts.ResolvedType; } /** Return properties of an object type or an empty array for other types */ - function getPropertiesOfObjectType(type: Type): Symbol[] { - if (type.flags & TypeFlags.Object) { - return resolveStructuredTypeMembers(type as ObjectType).properties; + function getPropertiesOfObjectType(type: ts.Type): ts.Symbol[] { + if (type.flags & ts.TypeFlags.Object) { + return resolveStructuredTypeMembers(type as ts.ObjectType).properties; } - return emptyArray; + return ts.emptyArray; } /** If the given type is an object type and that type has a property by the given name, * return the symbol for that property. Otherwise return undefined. */ - function getPropertyOfObjectType(type: Type, name: __String): Symbol | undefined { - if (type.flags & TypeFlags.Object) { - const resolved = resolveStructuredTypeMembers(type as ObjectType); + function getPropertyOfObjectType(type: ts.Type, name: ts.__String): ts.Symbol | undefined { + if (type.flags & ts.TypeFlags.Object) { + const resolved = resolveStructuredTypeMembers(type as ts.ObjectType); const symbol = resolved.members.get(name); if (symbol && symbolIsValue(symbol)) { return symbol; @@ -11883,9 +11426,9 @@ namespace ts { } } - function getPropertiesOfUnionOrIntersectionType(type: UnionOrIntersectionType): Symbol[] { + function getPropertiesOfUnionOrIntersectionType(type: ts.UnionOrIntersectionType): ts.Symbol[] { if (!type.resolvedProperties) { - const members = createSymbolTable(); + const members = ts.createSymbolTable(); for (const current of type.types) { for (const prop of getPropertiesOfType(current)) { if (!members.has(prop.escapedName)) { @@ -11897,7 +11440,7 @@ namespace ts { } // The properties of a union type are those that are present in all constituent types, so // we only need to check the properties of the first type without index signature - if (type.flags & TypeFlags.Union && getIndexInfosOfType(current).length === 0) { + if (type.flags & ts.TypeFlags.Union && getIndexInfosOfType(current).length === 0) { break; } } @@ -11906,17 +11449,17 @@ namespace ts { return type.resolvedProperties; } - function getPropertiesOfType(type: Type): Symbol[] { + function getPropertiesOfType(type: ts.Type): ts.Symbol[] { type = getReducedApparentType(type); - return type.flags & TypeFlags.UnionOrIntersection ? - getPropertiesOfUnionOrIntersectionType(type as UnionType) : + return type.flags & ts.TypeFlags.UnionOrIntersection ? + getPropertiesOfUnionOrIntersectionType(type as ts.UnionType) : getPropertiesOfObjectType(type); } - function forEachPropertyOfType(type: Type, action: (symbol: Symbol, escapedName: __String) => void): void { + function forEachPropertyOfType(type: ts.Type, action: (symbol: ts.Symbol, escapedName: ts.__String) => void): void { type = getReducedApparentType(type); - if (type.flags & TypeFlags.StructuredType) { - resolveStructuredTypeMembers(type as StructuredType).members.forEach((symbol, escapedName) => { + if (type.flags & ts.TypeFlags.StructuredType) { + resolveStructuredTypeMembers(type as ts.StructuredType).members.forEach((symbol, escapedName) => { if (isNamedMember(symbol, escapedName)) { action(symbol, escapedName); } @@ -11924,8 +11467,8 @@ namespace ts { } } - function isTypeInvalidDueToUnionDiscriminant(contextualType: Type, obj: ObjectLiteralExpression | JsxAttributes): boolean { - const list = obj.properties as NodeArray; + function isTypeInvalidDueToUnionDiscriminant(contextualType: ts.Type, obj: ts.ObjectLiteralExpression | ts.JsxAttributes): boolean { + const list = obj.properties as ts.NodeArray; return list.some(property => { const nameType = property.name && getLiteralTypeFromPropertyName(property.name); const name = nameType && isTypeUsableAsPropertyName(nameType) ? getPropertyNameFromType(nameType) : undefined; @@ -11934,50 +11477,51 @@ namespace ts { }); } - function getAllPossiblePropertiesOfTypes(types: readonly Type[]): Symbol[] { + function getAllPossiblePropertiesOfTypes(types: readonly ts.Type[]): ts.Symbol[] { const unionType = getUnionType(types); - if (!(unionType.flags & TypeFlags.Union)) { + if (!(unionType.flags & ts.TypeFlags.Union)) { return getAugmentedPropertiesOfType(unionType); } - const props = createSymbolTable(); + const props = ts.createSymbolTable(); for (const memberType of types) { for (const { escapedName } of getAugmentedPropertiesOfType(memberType)) { if (!props.has(escapedName)) { - const prop = createUnionOrIntersectionProperty(unionType as UnionType, escapedName); + const prop = createUnionOrIntersectionProperty(unionType as ts.UnionType, escapedName); // May be undefined if the property is private - if (prop) props.set(escapedName, prop); + if (prop) + props.set(escapedName, prop); } } } - return arrayFrom(props.values()); + return ts.arrayFrom(props.values()); } - function getConstraintOfType(type: InstantiableType | UnionOrIntersectionType): Type | undefined { - return type.flags & TypeFlags.TypeParameter ? getConstraintOfTypeParameter(type as TypeParameter) : - type.flags & TypeFlags.IndexedAccess ? getConstraintOfIndexedAccess(type as IndexedAccessType) : - type.flags & TypeFlags.Conditional ? getConstraintOfConditionalType(type as ConditionalType) : + function getConstraintOfType(type: ts.InstantiableType | ts.UnionOrIntersectionType): ts.Type | undefined { + return type.flags & ts.TypeFlags.TypeParameter ? getConstraintOfTypeParameter(type as ts.TypeParameter) : + type.flags & ts.TypeFlags.IndexedAccess ? getConstraintOfIndexedAccess(type as ts.IndexedAccessType) : + type.flags & ts.TypeFlags.Conditional ? getConstraintOfConditionalType(type as ts.ConditionalType) : getBaseConstraintOfType(type); } - function getConstraintOfTypeParameter(typeParameter: TypeParameter): Type | undefined { + function getConstraintOfTypeParameter(typeParameter: ts.TypeParameter): ts.Type | undefined { return hasNonCircularBaseConstraint(typeParameter) ? getConstraintFromTypeParameter(typeParameter) : undefined; } - function getConstraintOfIndexedAccess(type: IndexedAccessType) { + function getConstraintOfIndexedAccess(type: ts.IndexedAccessType) { return hasNonCircularBaseConstraint(type) ? getConstraintFromIndexedAccess(type) : undefined; } - function getSimplifiedTypeOrConstraint(type: Type) { + function getSimplifiedTypeOrConstraint(type: ts.Type) { const simplified = getSimplifiedType(type, /*writing*/ false); return simplified !== type ? simplified : getConstraintOfType(type); } - function getConstraintFromIndexedAccess(type: IndexedAccessType) { + function getConstraintFromIndexedAccess(type: ts.IndexedAccessType) { if (isMappedTypeGenericIndexedAccess(type)) { // For indexed access types of the form { [P in K]: E }[X], where K is non-generic and X is generic, // we substitute an instantiation of E where P is replaced with X. - return substituteIndexedMappedType(type.objectType as MappedType, type.indexType); + return substituteIndexedMappedType(type.objectType as ts.MappedType, type.indexType); } const indexConstraint = getSimplifiedTypeOrConstraint(type.indexType); if (indexConstraint && indexConstraint !== type.indexType) { @@ -11993,7 +11537,7 @@ namespace ts { return undefined; } - function getDefaultConstraintOfConditionalType(type: ConditionalType) { + function getDefaultConstraintOfConditionalType(type: ts.ConditionalType) { if (!type.resolvedDefaultConstraint) { // An `any` branch of a conditional type would normally be viral - specifically, without special handling here, // a conditional type with a single branch of type `any` would be assignable to anything, since it's constraint would simplify to @@ -12006,7 +11550,7 @@ namespace ts { return type.resolvedDefaultConstraint; } - function getConstraintOfDistributiveConditionalType(type: ConditionalType): Type | undefined { + function getConstraintOfDistributiveConditionalType(type: ts.ConditionalType): ts.Type | undefined { // Check if we have a conditional type of the form 'T extends U ? X : Y', where T is a constrained // type parameter. If so, create an instantiation of the conditional type where T is replaced // with its constraint. We do this because if the constraint is a union type it will be distributed @@ -12023,7 +11567,7 @@ namespace ts { const constraint = simplified === type.checkType ? getConstraintOfType(simplified) : simplified; if (constraint && constraint !== type.checkType) { const instantiated = getConditionalTypeInstantiation(type, prependTypeMapping(type.root.checkType, constraint, type.mapper)); - if (!(instantiated.flags & TypeFlags.Never)) { + if (!(instantiated.flags & ts.TypeFlags.Never)) { return instantiated; } } @@ -12031,33 +11575,33 @@ namespace ts { return undefined; } - function getConstraintFromConditionalType(type: ConditionalType) { + function getConstraintFromConditionalType(type: ts.ConditionalType) { return getConstraintOfDistributiveConditionalType(type) || getDefaultConstraintOfConditionalType(type); } - function getConstraintOfConditionalType(type: ConditionalType) { + function getConstraintOfConditionalType(type: ts.ConditionalType) { return hasNonCircularBaseConstraint(type) ? getConstraintFromConditionalType(type) : undefined; } - function getEffectiveConstraintOfIntersection(types: readonly Type[], targetIsUnion: boolean) { - let constraints: Type[] | undefined; + function getEffectiveConstraintOfIntersection(types: readonly ts.Type[], targetIsUnion: boolean) { + let constraints: ts.Type[] | undefined; let hasDisjointDomainType = false; for (const t of types) { - if (t.flags & TypeFlags.Instantiable) { + if (t.flags & ts.TypeFlags.Instantiable) { // We keep following constraints as long as we have an instantiable type that is known // not to be circular or infinite (hence we stop on index access types). let constraint = getConstraintOfType(t); - while (constraint && constraint.flags & (TypeFlags.TypeParameter | TypeFlags.Index | TypeFlags.Conditional)) { + while (constraint && constraint.flags & (ts.TypeFlags.TypeParameter | ts.TypeFlags.Index | ts.TypeFlags.Conditional)) { constraint = getConstraintOfType(constraint); } if (constraint) { - constraints = append(constraints, constraint); + constraints = ts.append(constraints, constraint); if (targetIsUnion) { - constraints = append(constraints, t); + constraints = ts.append(constraints, t); } } } - else if (t.flags & TypeFlags.DisjointDomains) { + else if (t.flags & ts.TypeFlags.DisjointDomains) { hasDisjointDomainType = true; } } @@ -12068,8 +11612,8 @@ namespace ts { // We add any types belong to one of the disjoint domains because they might cause the final // intersection operation to reduce the union constraints. for (const t of types) { - if (t.flags & TypeFlags.DisjointDomains) { - constraints = append(constraints, t); + if (t.flags & ts.TypeFlags.DisjointDomains) { + constraints = ts.append(constraints, t); } } } @@ -12078,23 +11622,23 @@ namespace ts { return undefined; } - function getBaseConstraintOfType(type: Type): Type | undefined { - if (type.flags & (TypeFlags.InstantiableNonPrimitive | TypeFlags.UnionOrIntersection | TypeFlags.TemplateLiteral | TypeFlags.StringMapping)) { - const constraint = getResolvedBaseConstraint(type as InstantiableType | UnionOrIntersectionType); + function getBaseConstraintOfType(type: ts.Type): ts.Type | undefined { + if (type.flags & (ts.TypeFlags.InstantiableNonPrimitive | ts.TypeFlags.UnionOrIntersection | ts.TypeFlags.TemplateLiteral | ts.TypeFlags.StringMapping)) { + const constraint = getResolvedBaseConstraint(type as ts.InstantiableType | ts.UnionOrIntersectionType); return constraint !== noConstraintType && constraint !== circularConstraintType ? constraint : undefined; } - return type.flags & TypeFlags.Index ? keyofConstraintType : undefined; + return type.flags & ts.TypeFlags.Index ? keyofConstraintType : undefined; } /** * This is similar to `getBaseConstraintOfType` except it returns the input type if there's no base constraint, instead of `undefined` * It also doesn't map indexes to `string`, as where this is used this would be unneeded (and likely undesirable) */ - function getBaseConstraintOrType(type: Type) { + function getBaseConstraintOrType(type: ts.Type) { return getBaseConstraintOfType(type) || type; } - function hasNonCircularBaseConstraint(type: InstantiableType): boolean { + function hasNonCircularBaseConstraint(type: ts.InstantiableType): boolean { return getResolvedBaseConstraint(type) !== circularConstraintType; } @@ -12103,14 +11647,14 @@ namespace ts { * type variable has no constraint, and the circularConstraintType singleton is returned if the constraint * circularly references the type variable. */ - function getResolvedBaseConstraint(type: InstantiableType | UnionOrIntersectionType): Type { + function getResolvedBaseConstraint(type: ts.InstantiableType | ts.UnionOrIntersectionType): ts.Type { if (type.resolvedBaseConstraint) { return type.resolvedBaseConstraint; } const stack: object[] = []; return type.resolvedBaseConstraint = getTypeWithThisArgument(getImmediateBaseConstraint(type), type); - function getImmediateBaseConstraint(t: Type): Type { + function getImmediateBaseConstraint(t: ts.Type): ts.Type { if (!t.immediateBaseConstraint) { if (!pushTypeResolution(t, TypeSystemPropertyName.ImmediateBaseConstraint)) { return circularConstraintType; @@ -12123,18 +11667,18 @@ namespace ts { // yet triggered the deeply nested limiter. We have no test cases that actually get to 50 levels of // nesting, so it is effectively just a safety stop. const identity = getRecursionIdentity(t); - if (stack.length < 10 || stack.length < 50 && !contains(stack, identity)) { + if (stack.length < 10 || stack.length < 50 && !ts.contains(stack, identity)) { stack.push(identity); result = computeBaseConstraint(getSimplifiedType(t, /*writing*/ false)); stack.pop(); } if (!popTypeResolution()) { - if (t.flags & TypeFlags.TypeParameter) { - const errorNode = getConstraintDeclaration(t as TypeParameter); + if (t.flags & ts.TypeFlags.TypeParameter) { + const errorNode = getConstraintDeclaration(t as ts.TypeParameter); if (errorNode) { - const diagnostic = error(errorNode, Diagnostics.Type_parameter_0_has_a_circular_constraint, typeToString(t)); - if (currentNode && !isNodeDescendantOf(errorNode, currentNode) && !isNodeDescendantOf(currentNode, errorNode)) { - addRelatedInfo(diagnostic, createDiagnosticForNode(currentNode, Diagnostics.Circularity_originates_in_type_at_this_location)); + const diagnostic = error(errorNode, ts.Diagnostics.Type_parameter_0_has_a_circular_constraint, typeToString(t)); + if (currentNode && !ts.isNodeDescendantOf(errorNode, currentNode) && !ts.isNodeDescendantOf(currentNode, errorNode)) { + ts.addRelatedInfo(diagnostic, ts.createDiagnosticForNode(currentNode, ts.Diagnostics.Circularity_originates_in_type_at_this_location)); } } } @@ -12145,21 +11689,21 @@ namespace ts { return t.immediateBaseConstraint; } - function getBaseConstraint(t: Type): Type | undefined { + function getBaseConstraint(t: ts.Type): ts.Type | undefined { const c = getImmediateBaseConstraint(t); return c !== noConstraintType && c !== circularConstraintType ? c : undefined; } - function computeBaseConstraint(t: Type): Type | undefined { - if (t.flags & TypeFlags.TypeParameter) { - const constraint = getConstraintFromTypeParameter(t as TypeParameter); - return (t as TypeParameter).isThisType || !constraint ? + function computeBaseConstraint(t: ts.Type): ts.Type | undefined { + if (t.flags & ts.TypeFlags.TypeParameter) { + const constraint = getConstraintFromTypeParameter(t as ts.TypeParameter); + return (t as ts.TypeParameter).isThisType || !constraint ? constraint : getBaseConstraint(constraint); } - if (t.flags & TypeFlags.UnionOrIntersection) { - const types = (t as UnionOrIntersectionType).types; - const baseTypes: Type[] = []; + if (t.flags & ts.TypeFlags.UnionOrIntersection) { + const types = (t as ts.UnionOrIntersectionType).types; + const baseTypes: ts.Type[] = []; let different = false; for (const type of types) { const baseType = getBaseConstraint(type); @@ -12176,49 +11720,49 @@ namespace ts { if (!different) { return t; } - return t.flags & TypeFlags.Union && baseTypes.length === types.length ? getUnionType(baseTypes) : - t.flags & TypeFlags.Intersection && baseTypes.length ? getIntersectionType(baseTypes) : + return t.flags & ts.TypeFlags.Union && baseTypes.length === types.length ? getUnionType(baseTypes) : + t.flags & ts.TypeFlags.Intersection && baseTypes.length ? getIntersectionType(baseTypes) : undefined; } - if (t.flags & TypeFlags.Index) { + if (t.flags & ts.TypeFlags.Index) { return keyofConstraintType; } - if (t.flags & TypeFlags.TemplateLiteral) { - const types = (t as TemplateLiteralType).types; - const constraints = mapDefined(types, getBaseConstraint); - return constraints.length === types.length ? getTemplateLiteralType((t as TemplateLiteralType).texts, constraints) : stringType; + if (t.flags & ts.TypeFlags.TemplateLiteral) { + const types = (t as ts.TemplateLiteralType).types; + const constraints = ts.mapDefined(types, getBaseConstraint); + return constraints.length === types.length ? getTemplateLiteralType((t as ts.TemplateLiteralType).texts, constraints) : stringType; } - if (t.flags & TypeFlags.StringMapping) { - const constraint = getBaseConstraint((t as StringMappingType).type); - return constraint ? getStringMappingType((t as StringMappingType).symbol, constraint) : stringType; + if (t.flags & ts.TypeFlags.StringMapping) { + const constraint = getBaseConstraint((t as ts.StringMappingType).type); + return constraint ? getStringMappingType((t as ts.StringMappingType).symbol, constraint) : stringType; } - if (t.flags & TypeFlags.IndexedAccess) { + if (t.flags & ts.TypeFlags.IndexedAccess) { if (isMappedTypeGenericIndexedAccess(t)) { // For indexed access types of the form { [P in K]: E }[X], where K is non-generic and X is generic, // we substitute an instantiation of E where P is replaced with X. - return getBaseConstraint(substituteIndexedMappedType((t as IndexedAccessType).objectType as MappedType, (t as IndexedAccessType).indexType)); + return getBaseConstraint(substituteIndexedMappedType((t as ts.IndexedAccessType).objectType as ts.MappedType, (t as ts.IndexedAccessType).indexType)); } - const baseObjectType = getBaseConstraint((t as IndexedAccessType).objectType); - const baseIndexType = getBaseConstraint((t as IndexedAccessType).indexType); - const baseIndexedAccess = baseObjectType && baseIndexType && getIndexedAccessTypeOrUndefined(baseObjectType, baseIndexType, (t as IndexedAccessType).accessFlags); + const baseObjectType = getBaseConstraint((t as ts.IndexedAccessType).objectType); + const baseIndexType = getBaseConstraint((t as ts.IndexedAccessType).indexType); + const baseIndexedAccess = baseObjectType && baseIndexType && getIndexedAccessTypeOrUndefined(baseObjectType, baseIndexType, (t as ts.IndexedAccessType).accessFlags); return baseIndexedAccess && getBaseConstraint(baseIndexedAccess); } - if (t.flags & TypeFlags.Conditional) { - const constraint = getConstraintFromConditionalType(t as ConditionalType); + if (t.flags & ts.TypeFlags.Conditional) { + const constraint = getConstraintFromConditionalType(t as ts.ConditionalType); return constraint && getBaseConstraint(constraint); } - if (t.flags & TypeFlags.Substitution) { - return getBaseConstraint((t as SubstitutionType).substitute); + if (t.flags & ts.TypeFlags.Substitution) { + return getBaseConstraint((t as ts.SubstitutionType).substitute); } return t; } } - function getApparentTypeOfIntersectionType(type: IntersectionType) { + function getApparentTypeOfIntersectionType(type: ts.IntersectionType) { return type.resolvedApparentType || (type.resolvedApparentType = getTypeWithThisArgument(type, type, /*apparentType*/ true)); } - function getResolvedTypeParameterDefault(typeParameter: TypeParameter): Type | undefined { + function getResolvedTypeParameterDefault(typeParameter: ts.TypeParameter): ts.Type | undefined { if (!typeParameter.default) { if (typeParameter.target) { const targetDefault = getResolvedTypeParameterDefault(typeParameter.target); @@ -12227,7 +11771,7 @@ namespace ts { else { // To block recursion, set the initial value to the resolvingDefaultType. typeParameter.default = resolvingDefaultType; - const defaultDeclaration = typeParameter.symbol && forEach(typeParameter.symbol.declarations, decl => isTypeParameterDeclaration(decl) && decl.default); + const defaultDeclaration = typeParameter.symbol && ts.forEach(typeParameter.symbol.declarations, decl => ts.isTypeParameterDeclaration(decl) && decl.default); const defaultType = defaultDeclaration ? getTypeFromTypeNode(defaultDeclaration) : noConstraintType; if (typeParameter.default === resolvingDefaultType) { // If we have not been called recursively, set the correct default type. @@ -12249,27 +11793,27 @@ namespace ts { * default type of its target. If the type parameter has no default type or the default is * circular, `undefined` is returned. */ - function getDefaultFromTypeParameter(typeParameter: TypeParameter): Type | undefined { + function getDefaultFromTypeParameter(typeParameter: ts.TypeParameter): ts.Type | undefined { const defaultType = getResolvedTypeParameterDefault(typeParameter); return defaultType !== noConstraintType && defaultType !== circularConstraintType ? defaultType : undefined; } - function hasNonCircularTypeParameterDefault(typeParameter: TypeParameter) { + function hasNonCircularTypeParameterDefault(typeParameter: ts.TypeParameter) { return getResolvedTypeParameterDefault(typeParameter) !== circularConstraintType; } /** * Indicates whether the declaration of a typeParameter has a default type. */ - function hasTypeParameterDefault(typeParameter: TypeParameter): boolean { - return !!(typeParameter.symbol && forEach(typeParameter.symbol.declarations, decl => isTypeParameterDeclaration(decl) && decl.default)); + function hasTypeParameterDefault(typeParameter: ts.TypeParameter): boolean { + return !!(typeParameter.symbol && ts.forEach(typeParameter.symbol.declarations, decl => ts.isTypeParameterDeclaration(decl) && decl.default)); } - function getApparentTypeOfMappedType(type: MappedType) { + function getApparentTypeOfMappedType(type: ts.MappedType) { return type.resolvedApparentType || (type.resolvedApparentType = getResolvedApparentTypeOfMappedType(type)); } - function getResolvedApparentTypeOfMappedType(type: MappedType) { + function getResolvedApparentTypeOfMappedType(type: ts.MappedType) { const typeVariable = getHomomorphicTypeVariable(type); if (typeVariable && !type.declaration.nameType) { const constraint = getConstraintOfTypeParameter(typeVariable); @@ -12280,11 +11824,11 @@ namespace ts { return type; } - function isMappedTypeGenericIndexedAccess(type: Type) { + function isMappedTypeGenericIndexedAccess(type: ts.Type) { let objectType; - return !!(type.flags & TypeFlags.IndexedAccess && getObjectFlags(objectType = (type as IndexedAccessType).objectType) & ObjectFlags.Mapped && - !isGenericMappedType(objectType) && isGenericIndexType((type as IndexedAccessType).indexType) && - !(objectType as MappedType).declaration.questionToken && !(objectType as MappedType).declaration.nameType); + return !!(type.flags & ts.TypeFlags.IndexedAccess && ts.getObjectFlags(objectType = (type as ts.IndexedAccessType).objectType) & ts.ObjectFlags.Mapped && + !isGenericMappedType(objectType) && isGenericIndexType((type as ts.IndexedAccessType).indexType) && + !(objectType as ts.MappedType).declaration.questionToken && !(objectType as ts.MappedType).declaration.nameType); } /** @@ -12292,22 +11836,22 @@ namespace ts { * boolean, and symbol primitive types, return the corresponding object types. Otherwise return the * type itself. */ - function getApparentType(type: Type): Type { - const t = !(type.flags & TypeFlags.Instantiable) ? type : getBaseConstraintOfType(type) || unknownType; - return getObjectFlags(t) & ObjectFlags.Mapped ? getApparentTypeOfMappedType(t as MappedType) : - t.flags & TypeFlags.Intersection ? getApparentTypeOfIntersectionType(t as IntersectionType) : - t.flags & TypeFlags.StringLike ? globalStringType : - t.flags & TypeFlags.NumberLike ? globalNumberType : - t.flags & TypeFlags.BigIntLike ? getGlobalBigIntType(/*reportErrors*/ languageVersion >= ScriptTarget.ES2020) : - t.flags & TypeFlags.BooleanLike ? globalBooleanType : - t.flags & TypeFlags.ESSymbolLike ? getGlobalESSymbolType(/*reportErrors*/ languageVersion >= ScriptTarget.ES2015) : - t.flags & TypeFlags.NonPrimitive ? emptyObjectType : - t.flags & TypeFlags.Index ? keyofConstraintType : - t.flags & TypeFlags.Unknown && !strictNullChecks ? emptyObjectType : + function getApparentType(type: ts.Type): ts.Type { + const t = !(type.flags & ts.TypeFlags.Instantiable) ? type : getBaseConstraintOfType(type) || unknownType; + return ts.getObjectFlags(t) & ts.ObjectFlags.Mapped ? getApparentTypeOfMappedType(t as ts.MappedType) : + t.flags & ts.TypeFlags.Intersection ? getApparentTypeOfIntersectionType(t as ts.IntersectionType) : + t.flags & ts.TypeFlags.StringLike ? globalStringType : + t.flags & ts.TypeFlags.NumberLike ? globalNumberType : + t.flags & ts.TypeFlags.BigIntLike ? getGlobalBigIntType(/*reportErrors*/ languageVersion >= ts.ScriptTarget.ES2020) : + t.flags & ts.TypeFlags.BooleanLike ? globalBooleanType : + t.flags & ts.TypeFlags.ESSymbolLike ? getGlobalESSymbolType(/*reportErrors*/ languageVersion >= ts.ScriptTarget.ES2015) : + t.flags & ts.TypeFlags.NonPrimitive ? emptyObjectType : + t.flags & ts.TypeFlags.Index ? keyofConstraintType : + t.flags & ts.TypeFlags.Unknown && !strictNullChecks ? emptyObjectType : t; } - function getReducedApparentType(type: Type): Type { + function getReducedApparentType(type: ts.Type): ts.Type { // Since getApparentType may return a non-reduced union or intersection type, we need to perform // type reduction both before and after obtaining the apparent type. For example, given a type parameter // 'T extends A | B', the type 'T & X' becomes 'A & X | B & X' after obtaining the apparent type, and @@ -12315,24 +11859,24 @@ namespace ts { return getReducedType(getApparentType(getReducedType(type))); } - function createUnionOrIntersectionProperty(containingType: UnionOrIntersectionType, name: __String, skipObjectFunctionPropertyAugment?: boolean): Symbol | undefined { - let singleProp: Symbol | undefined; - let propSet: ESMap | undefined; - let indexTypes: Type[] | undefined; - const isUnion = containingType.flags & TypeFlags.Union; + function createUnionOrIntersectionProperty(containingType: ts.UnionOrIntersectionType, name: ts.__String, skipObjectFunctionPropertyAugment?: boolean): ts.Symbol | undefined { + let singleProp: ts.Symbol | undefined; + let propSet: ts.ESMap | undefined; + let indexTypes: ts.Type[] | undefined; + const isUnion = containingType.flags & ts.TypeFlags.Union; // Flags we want to propagate to the result if they exist in all source symbols - let optionalFlag = isUnion ? SymbolFlags.None : SymbolFlags.Optional; - let syntheticFlag = CheckFlags.SyntheticMethod; - let checkFlags = isUnion ? 0 : CheckFlags.Readonly; + let optionalFlag = isUnion ? ts.SymbolFlags.None : ts.SymbolFlags.Optional; + let syntheticFlag = ts.CheckFlags.SyntheticMethod; + let checkFlags = isUnion ? 0 : ts.CheckFlags.Readonly; let mergedInstantiations = false; for (const current of containingType.types) { const type = getApparentType(current); - if (!(isErrorType(type) || type.flags & TypeFlags.Never)) { + if (!(isErrorType(type) || type.flags & ts.TypeFlags.Never)) { const prop = getPropertyOfType(type, name, skipObjectFunctionPropertyAugment); - const modifiers = prop ? getDeclarationModifierFlagsFromSymbol(prop) : 0; + const modifiers = prop ? ts.getDeclarationModifierFlagsFromSymbol(prop) : 0; if (prop) { if (isUnion) { - optionalFlag |= (prop.flags & SymbolFlags.Optional); + optionalFlag |= (prop.flags & ts.SymbolFlags.Optional); } else { optionalFlag &= prop.flags; @@ -12345,15 +11889,15 @@ namespace ts { // If the symbols are instances of one another with identical types - consider the symbols // equivalent and just use the first one, which thus allows us to avoid eliding private // members when intersecting a (this-)instantiations of a class with it's raw base or another instance - if (isInstantiation && compareProperties(singleProp, prop, (a, b) => a === b ? Ternary.True : Ternary.False) === Ternary.True) { + if (isInstantiation && compareProperties(singleProp, prop, (a, b) => a === b ? ts.Ternary.True : ts.Ternary.False) === ts.Ternary.True) { // If we merged instantiations of a generic type, we replicate the symbol parent resetting behavior we used // to do when we recorded multiple distinct symbols so that we still get, eg, `Array.length` printed // back and not `Array.length` when we're looking at a `.length` access on a `string[] | number[]` - mergedInstantiations = !!singleProp.parent && !!length(getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(singleProp.parent)); + mergedInstantiations = !!singleProp.parent && !!ts.length(getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(singleProp.parent)); } else { if (!propSet) { - propSet = new Map(); + propSet = new ts.Map(); propSet.set(getSymbolId(singleProp), singleProp); } const id = getSymbolId(prop); @@ -12363,62 +11907,62 @@ namespace ts { } } if (isUnion && isReadonlySymbol(prop)) { - checkFlags |= CheckFlags.Readonly; + checkFlags |= ts.CheckFlags.Readonly; } else if (!isUnion && !isReadonlySymbol(prop)) { - checkFlags &= ~CheckFlags.Readonly; + checkFlags &= ~ts.CheckFlags.Readonly; } - checkFlags |= (!(modifiers & ModifierFlags.NonPublicAccessibilityModifier) ? CheckFlags.ContainsPublic : 0) | - (modifiers & ModifierFlags.Protected ? CheckFlags.ContainsProtected : 0) | - (modifiers & ModifierFlags.Private ? CheckFlags.ContainsPrivate : 0) | - (modifiers & ModifierFlags.Static ? CheckFlags.ContainsStatic : 0); + checkFlags |= (!(modifiers & ts.ModifierFlags.NonPublicAccessibilityModifier) ? ts.CheckFlags.ContainsPublic : 0) | + (modifiers & ts.ModifierFlags.Protected ? ts.CheckFlags.ContainsProtected : 0) | + (modifiers & ts.ModifierFlags.Private ? ts.CheckFlags.ContainsPrivate : 0) | + (modifiers & ts.ModifierFlags.Static ? ts.CheckFlags.ContainsStatic : 0); if (!isPrototypeProperty(prop)) { - syntheticFlag = CheckFlags.SyntheticProperty; + syntheticFlag = ts.CheckFlags.SyntheticProperty; } } else if (isUnion) { const indexInfo = !isLateBoundName(name) && getApplicableIndexInfoForName(type, name); if (indexInfo) { - checkFlags |= CheckFlags.WritePartial | (indexInfo.isReadonly ? CheckFlags.Readonly : 0); - indexTypes = append(indexTypes, isTupleType(type) ? getRestTypeOfTupleType(type) || undefinedType : indexInfo.type); + checkFlags |= ts.CheckFlags.WritePartial | (indexInfo.isReadonly ? ts.CheckFlags.Readonly : 0); + indexTypes = ts.append(indexTypes, isTupleType(type) ? getRestTypeOfTupleType(type) || undefinedType : indexInfo.type); } - else if (isObjectLiteralType(type) && !(getObjectFlags(type) & ObjectFlags.ContainsSpread)) { - checkFlags |= CheckFlags.WritePartial; - indexTypes = append(indexTypes, undefinedType); + else if (isObjectLiteralType(type) && !(ts.getObjectFlags(type) & ts.ObjectFlags.ContainsSpread)) { + checkFlags |= ts.CheckFlags.WritePartial; + indexTypes = ts.append(indexTypes, undefinedType); } else { - checkFlags |= CheckFlags.ReadPartial; + checkFlags |= ts.CheckFlags.ReadPartial; } } } } - if (!singleProp || isUnion && (propSet || checkFlags & CheckFlags.Partial) && checkFlags & (CheckFlags.ContainsPrivate | CheckFlags.ContainsProtected)) { + if (!singleProp || isUnion && (propSet || checkFlags & ts.CheckFlags.Partial) && checkFlags & (ts.CheckFlags.ContainsPrivate | ts.CheckFlags.ContainsProtected)) { // No property was found, or, in a union, a property has a private or protected declaration in one // constituent, but is missing or has a different declaration in another constituent. return undefined; } - if (!propSet && !(checkFlags & CheckFlags.ReadPartial) && !indexTypes) { + if (!propSet && !(checkFlags & ts.CheckFlags.ReadPartial) && !indexTypes) { if (mergedInstantiations) { // No symbol from a union/intersection should have a `.parent` set (since unions/intersections don't act as symbol parents) // Unless that parent is "reconstituted" from the "first value declaration" on the symbol (which is likely different than its instantiated parent!) // They also have a `.containingType` set, which affects some services endpoints behavior, like `getRootSymbol` - const clone = createSymbolWithType(singleProp, (singleProp as TransientSymbol).type); + const clone = createSymbolWithType(singleProp, (singleProp as ts.TransientSymbol).type); clone.parent = singleProp.valueDeclaration?.symbol?.parent; clone.containingType = containingType; - clone.mapper = (singleProp as TransientSymbol).mapper; + clone.mapper = (singleProp as ts.TransientSymbol).mapper; return clone; } else { return singleProp; } } - const props = propSet ? arrayFrom(propSet.values()) : [singleProp]; - let declarations: Declaration[] | undefined; - let firstType: Type | undefined; - let nameType: Type | undefined; - const propTypes: Type[] = []; - let writeTypes: Type[] | undefined; - let firstValueDeclaration: Declaration | undefined; + const props = propSet ? ts.arrayFrom(propSet.values()) : [singleProp]; + let declarations: ts.Declaration[] | undefined; + let firstType: ts.Type | undefined; + let nameType: ts.Type | undefined; + const propTypes: ts.Type[] = []; + let writeTypes: ts.Type[] | undefined; + let firstValueDeclaration: ts.Declaration | undefined; let hasNonUniformValueDeclaration = false; for (const prop of props) { if (!firstValueDeclaration) { @@ -12427,7 +11971,7 @@ namespace ts { else if (prop.valueDeclaration && prop.valueDeclaration !== firstValueDeclaration) { hasNonUniformValueDeclaration = true; } - declarations = addRange(declarations, prop.declarations); + declarations = ts.addRange(declarations, prop.declarations); const type = getTypeOfSymbol(prop); if (!firstType) { firstType = type; @@ -12435,21 +11979,21 @@ namespace ts { } const writeType = getWriteTypeOfSymbol(prop); if (writeTypes || writeType !== type) { - writeTypes = append(!writeTypes ? propTypes.slice() : writeTypes, writeType); + writeTypes = ts.append(!writeTypes ? propTypes.slice() : writeTypes, writeType); } else if (type !== firstType) { - checkFlags |= CheckFlags.HasNonUniformType; + checkFlags |= ts.CheckFlags.HasNonUniformType; } if (isLiteralType(type) || isPatternLiteralType(type) || type === uniqueLiteralType) { - checkFlags |= CheckFlags.HasLiteralType; + checkFlags |= ts.CheckFlags.HasLiteralType; } - if (type.flags & TypeFlags.Never && type !== uniqueLiteralType) { - checkFlags |= CheckFlags.HasNeverType; + if (type.flags & ts.TypeFlags.Never && type !== uniqueLiteralType) { + checkFlags |= ts.CheckFlags.HasNeverType; } propTypes.push(type); } - addRange(propTypes, indexTypes); - const result = createSymbol(SymbolFlags.Property | optionalFlag, name, syntheticFlag | checkFlags); + ts.addRange(propTypes, indexTypes); + const result = createSymbol(ts.SymbolFlags.Property | optionalFlag, name, syntheticFlag | checkFlags); result.containingType = containingType; if (!hasNonUniformValueDeclaration && firstValueDeclaration) { result.valueDeclaration = firstValueDeclaration; @@ -12464,7 +12008,7 @@ namespace ts { result.nameType = nameType; if (propTypes.length > 2) { // When `propTypes` has the potential to explode in size when normalized, defer normalization until absolutely needed - result.checkFlags |= CheckFlags.DeferredType; + result.checkFlags |= ts.CheckFlags.DeferredType; result.deferralParent = containingType; result.deferralConstituents = propTypes; result.deferralWriteConstituents = writeTypes; @@ -12483,25 +12027,25 @@ namespace ts { // constituents, in which case the isPartial flag is set when the containing type is union type. We need // these partial properties when identifying discriminant properties, but otherwise they are filtered out // and do not appear to be present in the union type. - function getUnionOrIntersectionProperty(type: UnionOrIntersectionType, name: __String, skipObjectFunctionPropertyAugment?: boolean): Symbol | undefined { + function getUnionOrIntersectionProperty(type: ts.UnionOrIntersectionType, name: ts.__String, skipObjectFunctionPropertyAugment?: boolean): ts.Symbol | undefined { let property = type.propertyCacheWithoutObjectFunctionPropertyAugment?.get(name) || !skipObjectFunctionPropertyAugment ? type.propertyCache?.get(name) : undefined; if (!property) { property = createUnionOrIntersectionProperty(type, name, skipObjectFunctionPropertyAugment); if (property) { const properties = skipObjectFunctionPropertyAugment ? - type.propertyCacheWithoutObjectFunctionPropertyAugment ||= createSymbolTable() : - type.propertyCache ||= createSymbolTable(); + type.propertyCacheWithoutObjectFunctionPropertyAugment ||= ts.createSymbolTable() : + type.propertyCache ||= ts.createSymbolTable(); properties.set(name, property); } } return property; } - function getPropertyOfUnionOrIntersectionType(type: UnionOrIntersectionType, name: __String, skipObjectFunctionPropertyAugment?: boolean): Symbol | undefined { + function getPropertyOfUnionOrIntersectionType(type: ts.UnionOrIntersectionType, name: ts.__String, skipObjectFunctionPropertyAugment?: boolean): ts.Symbol | undefined { const property = getUnionOrIntersectionProperty(type, name, skipObjectFunctionPropertyAugment); // We need to filter out partial properties in union types - return property && !(getCheckFlags(property) & CheckFlags.ReadPartial) ? property : undefined; + return property && !(ts.getCheckFlags(property) & ts.CheckFlags.ReadPartial) ? property : undefined; } /** @@ -12510,60 +12054,58 @@ namespace ts { * For all other types, it is simply the type itself. Discriminant properties are considered mutually exclusive when * no constituent property has type 'never', but the intersection of the constituent property types is 'never'. */ - function getReducedType(type: Type): Type { - if (type.flags & TypeFlags.Union && (type as UnionType).objectFlags & ObjectFlags.ContainsIntersections) { - return (type as UnionType).resolvedReducedType || ((type as UnionType).resolvedReducedType = getReducedUnionType(type as UnionType)); + function getReducedType(type: ts.Type): ts.Type { + if (type.flags & ts.TypeFlags.Union && (type as ts.UnionType).objectFlags & ts.ObjectFlags.ContainsIntersections) { + return (type as ts.UnionType).resolvedReducedType || ((type as ts.UnionType).resolvedReducedType = getReducedUnionType(type as ts.UnionType)); } - else if (type.flags & TypeFlags.Intersection) { - if (!((type as IntersectionType).objectFlags & ObjectFlags.IsNeverIntersectionComputed)) { - (type as IntersectionType).objectFlags |= ObjectFlags.IsNeverIntersectionComputed | - (some(getPropertiesOfUnionOrIntersectionType(type as IntersectionType), isNeverReducedProperty) ? ObjectFlags.IsNeverIntersection : 0); + else if (type.flags & ts.TypeFlags.Intersection) { + if (!((type as ts.IntersectionType).objectFlags & ts.ObjectFlags.IsNeverIntersectionComputed)) { + (type as ts.IntersectionType).objectFlags |= ts.ObjectFlags.IsNeverIntersectionComputed | + (ts.some(getPropertiesOfUnionOrIntersectionType(type as ts.IntersectionType), isNeverReducedProperty) ? ts.ObjectFlags.IsNeverIntersection : 0); } - return (type as IntersectionType).objectFlags & ObjectFlags.IsNeverIntersection ? neverType : type; + return (type as ts.IntersectionType).objectFlags & ts.ObjectFlags.IsNeverIntersection ? neverType : type; } return type; } - function getReducedUnionType(unionType: UnionType) { - const reducedTypes = sameMap(unionType.types, getReducedType); + function getReducedUnionType(unionType: ts.UnionType) { + const reducedTypes = ts.sameMap(unionType.types, getReducedType); if (reducedTypes === unionType.types) { return unionType; } const reduced = getUnionType(reducedTypes); - if (reduced.flags & TypeFlags.Union) { - (reduced as UnionType).resolvedReducedType = reduced; + if (reduced.flags & ts.TypeFlags.Union) { + (reduced as ts.UnionType).resolvedReducedType = reduced; } return reduced; } - function isNeverReducedProperty(prop: Symbol) { + function isNeverReducedProperty(prop: ts.Symbol) { return isDiscriminantWithNeverType(prop) || isConflictingPrivateProperty(prop); } - function isDiscriminantWithNeverType(prop: Symbol) { + function isDiscriminantWithNeverType(prop: ts.Symbol) { // Return true for a synthetic non-optional property with non-uniform types, where at least one is // a literal type and none is never, that reduces to never. - return !(prop.flags & SymbolFlags.Optional) && - (getCheckFlags(prop) & (CheckFlags.Discriminant | CheckFlags.HasNeverType)) === CheckFlags.Discriminant && - !!(getTypeOfSymbol(prop).flags & TypeFlags.Never); + return !(prop.flags & ts.SymbolFlags.Optional) && + (ts.getCheckFlags(prop) & (ts.CheckFlags.Discriminant | ts.CheckFlags.HasNeverType)) === ts.CheckFlags.Discriminant && + !!(getTypeOfSymbol(prop).flags & ts.TypeFlags.Never); } - function isConflictingPrivateProperty(prop: Symbol) { + function isConflictingPrivateProperty(prop: ts.Symbol) { // Return true for a synthetic property with multiple declarations, at least one of which is private. - return !prop.valueDeclaration && !!(getCheckFlags(prop) & CheckFlags.ContainsPrivate); + return !prop.valueDeclaration && !!(ts.getCheckFlags(prop) & ts.CheckFlags.ContainsPrivate); } - function elaborateNeverIntersection(errorInfo: DiagnosticMessageChain | undefined, type: Type) { - if (type.flags & TypeFlags.Intersection && getObjectFlags(type) & ObjectFlags.IsNeverIntersection) { - const neverProp = find(getPropertiesOfUnionOrIntersectionType(type as IntersectionType), isDiscriminantWithNeverType); + function elaborateNeverIntersection(errorInfo: ts.DiagnosticMessageChain | undefined, type: ts.Type) { + if (type.flags & ts.TypeFlags.Intersection && ts.getObjectFlags(type) & ts.ObjectFlags.IsNeverIntersection) { + const neverProp = ts.find(getPropertiesOfUnionOrIntersectionType(type as ts.IntersectionType), isDiscriminantWithNeverType); if (neverProp) { - return chainDiagnosticMessages(errorInfo, Diagnostics.The_intersection_0_was_reduced_to_never_because_property_1_has_conflicting_types_in_some_constituents, - typeToString(type, /*enclosingDeclaration*/ undefined, TypeFormatFlags.NoTypeReduction), symbolToString(neverProp)); + return ts.chainDiagnosticMessages(errorInfo, ts.Diagnostics.The_intersection_0_was_reduced_to_never_because_property_1_has_conflicting_types_in_some_constituents, typeToString(type, /*enclosingDeclaration*/ undefined, ts.TypeFormatFlags.NoTypeReduction), symbolToString(neverProp)); } - const privateProp = find(getPropertiesOfUnionOrIntersectionType(type as IntersectionType), isConflictingPrivateProperty); + const privateProp = ts.find(getPropertiesOfUnionOrIntersectionType(type as ts.IntersectionType), isConflictingPrivateProperty); if (privateProp) { - return chainDiagnosticMessages(errorInfo, Diagnostics.The_intersection_0_was_reduced_to_never_because_property_1_exists_in_multiple_constituents_and_is_private_in_some, - typeToString(type, /*enclosingDeclaration*/ undefined, TypeFormatFlags.NoTypeReduction), symbolToString(privateProp)); + return ts.chainDiagnosticMessages(errorInfo, ts.Diagnostics.The_intersection_0_was_reduced_to_never_because_property_1_exists_in_multiple_constituents_and_is_private_in_some, typeToString(type, /*enclosingDeclaration*/ undefined, ts.TypeFormatFlags.NoTypeReduction), symbolToString(privateProp)); } } return errorInfo; @@ -12577,15 +12119,16 @@ namespace ts { * @param type a type to look up property from * @param name a name of property to look up in a given type */ - function getPropertyOfType(type: Type, name: __String, skipObjectFunctionPropertyAugment?: boolean, includeTypeOnlyMembers?: boolean): Symbol | undefined { + function getPropertyOfType(type: ts.Type, name: ts.__String, skipObjectFunctionPropertyAugment?: boolean, includeTypeOnlyMembers?: boolean): ts.Symbol | undefined { type = getReducedApparentType(type); - if (type.flags & TypeFlags.Object) { - const resolved = resolveStructuredTypeMembers(type as ObjectType); + if (type.flags & ts.TypeFlags.Object) { + const resolved = resolveStructuredTypeMembers(type as ts.ObjectType); const symbol = resolved.members.get(name); if (symbol && symbolIsValue(symbol, includeTypeOnlyMembers)) { return symbol; } - if (skipObjectFunctionPropertyAugment) return undefined; + if (skipObjectFunctionPropertyAugment) + return undefined; const functionType = resolved === anyFunctionType ? globalFunctionType : resolved.callSignatures.length ? globalCallableFunctionType : resolved.constructSignatures.length ? globalNewableFunctionType : @@ -12598,37 +12141,37 @@ namespace ts { } return getPropertyOfObjectType(globalObjectType, name); } - if (type.flags & TypeFlags.UnionOrIntersection) { - return getPropertyOfUnionOrIntersectionType(type as UnionOrIntersectionType, name, skipObjectFunctionPropertyAugment); + if (type.flags & ts.TypeFlags.UnionOrIntersection) { + return getPropertyOfUnionOrIntersectionType(type as ts.UnionOrIntersectionType, name, skipObjectFunctionPropertyAugment); } return undefined; } - function getSignaturesOfStructuredType(type: Type, kind: SignatureKind): readonly Signature[] { - if (type.flags & TypeFlags.StructuredType) { - const resolved = resolveStructuredTypeMembers(type as ObjectType); - return kind === SignatureKind.Call ? resolved.callSignatures : resolved.constructSignatures; + function getSignaturesOfStructuredType(type: ts.Type, kind: ts.SignatureKind): readonly ts.Signature[] { + if (type.flags & ts.TypeFlags.StructuredType) { + const resolved = resolveStructuredTypeMembers(type as ts.ObjectType); + return kind === ts.SignatureKind.Call ? resolved.callSignatures : resolved.constructSignatures; } - return emptyArray; + return ts.emptyArray; } /** * Return the signatures of the given kind in the given type. Creates synthetic union signatures when necessary and * maps primitive types and type parameters are to their apparent types. */ - function getSignaturesOfType(type: Type, kind: SignatureKind): readonly Signature[] { + function getSignaturesOfType(type: ts.Type, kind: ts.SignatureKind): readonly ts.Signature[] { return getSignaturesOfStructuredType(getReducedApparentType(type), kind); } - function findIndexInfo(indexInfos: readonly IndexInfo[], keyType: Type) { - return find(indexInfos, info => info.keyType === keyType); + function findIndexInfo(indexInfos: readonly ts.IndexInfo[], keyType: ts.Type) { + return ts.find(indexInfos, info => info.keyType === keyType); } - function findApplicableIndexInfo(indexInfos: readonly IndexInfo[], keyType: Type) { + function findApplicableIndexInfo(indexInfos: readonly ts.IndexInfo[], keyType: ts.Type) { // Index signatures for type 'string' are considered only when no other index signatures apply. - let stringIndexInfo: IndexInfo | undefined; - let applicableInfo: IndexInfo | undefined; - let applicableInfos: IndexInfo[] | undefined; + let stringIndexInfo: ts.IndexInfo | undefined; + let applicableInfo: ts.IndexInfo | undefined; + let applicableInfos: ts.IndexInfo[] | undefined; for (const info of indexInfos) { if (info.keyType === stringType) { stringIndexInfo = info; @@ -12645,69 +12188,68 @@ namespace ts { // When more than one index signature is applicable we create a synthetic IndexInfo. Instead of computing // the intersected key type, we just use unknownType for the key type as nothing actually depends on the // keyType property of the returned IndexInfo. - return applicableInfos ? createIndexInfo(unknownType, getIntersectionType(map(applicableInfos, info => info.type)), - reduceLeft(applicableInfos, (isReadonly, info) => isReadonly && info.isReadonly, /*initial*/ true)) : + return applicableInfos ? createIndexInfo(unknownType, getIntersectionType(ts.map(applicableInfos, info => info.type)), ts.reduceLeft(applicableInfos, (isReadonly, info) => isReadonly && info.isReadonly, /*initial*/ true)) : applicableInfo ? applicableInfo : stringIndexInfo && isApplicableIndexType(keyType, stringType) ? stringIndexInfo : undefined; } - function isApplicableIndexType(source: Type, target: Type): boolean { + function isApplicableIndexType(source: ts.Type, target: ts.Type): boolean { // A 'string' index signature applies to types assignable to 'string' or 'number', and a 'number' index // signature applies to types assignable to 'number', `${number}` and numeric string literal types. return isTypeAssignableTo(source, target) || target === stringType && isTypeAssignableTo(source, numberType) || - target === numberType && (source === numericStringType || !!(source.flags & TypeFlags.StringLiteral) && isNumericLiteralName((source as StringLiteralType).value)); + target === numberType && (source === numericStringType || !!(source.flags & ts.TypeFlags.StringLiteral) && ts.isNumericLiteralName((source as ts.StringLiteralType).value)); } - function getIndexInfosOfStructuredType(type: Type): readonly IndexInfo[] { - if (type.flags & TypeFlags.StructuredType) { - const resolved = resolveStructuredTypeMembers(type as ObjectType); + function getIndexInfosOfStructuredType(type: ts.Type): readonly ts.IndexInfo[] { + if (type.flags & ts.TypeFlags.StructuredType) { + const resolved = resolveStructuredTypeMembers(type as ts.ObjectType); return resolved.indexInfos; } - return emptyArray; + return ts.emptyArray; } - function getIndexInfosOfType(type: Type): readonly IndexInfo[] { + function getIndexInfosOfType(type: ts.Type): readonly ts.IndexInfo[] { return getIndexInfosOfStructuredType(getReducedApparentType(type)); } // Return the indexing info of the given kind in the given type. Creates synthetic union index types when necessary and // maps primitive types and type parameters are to their apparent types. - function getIndexInfoOfType(type: Type, keyType: Type): IndexInfo | undefined { + function getIndexInfoOfType(type: ts.Type, keyType: ts.Type): ts.IndexInfo | undefined { return findIndexInfo(getIndexInfosOfType(type), keyType); } // Return the index type of the given kind in the given type. Creates synthetic union index types when necessary and // maps primitive types and type parameters are to their apparent types. - function getIndexTypeOfType(type: Type, keyType: Type): Type | undefined { + function getIndexTypeOfType(type: ts.Type, keyType: ts.Type): ts.Type | undefined { return getIndexInfoOfType(type, keyType)?.type; } - function getApplicableIndexInfos(type: Type, keyType: Type): IndexInfo[] { + function getApplicableIndexInfos(type: ts.Type, keyType: ts.Type): ts.IndexInfo[] { return getIndexInfosOfType(type).filter(info => isApplicableIndexType(keyType, info.keyType)); } - function getApplicableIndexInfo(type: Type, keyType: Type): IndexInfo | undefined { + function getApplicableIndexInfo(type: ts.Type, keyType: ts.Type): ts.IndexInfo | undefined { return findApplicableIndexInfo(getIndexInfosOfType(type), keyType); } - function getApplicableIndexInfoForName(type: Type, name: __String): IndexInfo | undefined { - return getApplicableIndexInfo(type, isLateBoundName(name) ? esSymbolType : getStringLiteralType(unescapeLeadingUnderscores(name))); + function getApplicableIndexInfoForName(type: ts.Type, name: ts.__String): ts.IndexInfo | undefined { + return getApplicableIndexInfo(type, isLateBoundName(name) ? esSymbolType : getStringLiteralType(ts.unescapeLeadingUnderscores(name))); } // Return list of type parameters with duplicates removed (duplicate identifier errors are generated in the actual // type checking functions). - function getTypeParametersFromDeclaration(declaration: DeclarationWithTypeParameters): TypeParameter[] | undefined { - let result: TypeParameter[] | undefined; - for (const node of getEffectiveTypeParameterDeclarations(declaration)) { - result = appendIfUnique(result, getDeclaredTypeOfTypeParameter(node.symbol)); + function getTypeParametersFromDeclaration(declaration: ts.DeclarationWithTypeParameters): ts.TypeParameter[] | undefined { + let result: ts.TypeParameter[] | undefined; + for (const node of ts.getEffectiveTypeParameterDeclarations(declaration)) { + result = ts.appendIfUnique(result, getDeclaredTypeOfTypeParameter(node.symbol)); } return result; } - function symbolsToArray(symbols: SymbolTable): Symbol[] { - const result: Symbol[] = []; + function symbolsToArray(symbols: ts.SymbolTable): ts.Symbol[] { + const result: ts.Symbol[] = []; symbols.forEach((symbol, id) => { if (!isReservedMemberName(id)) { result.push(symbol); @@ -12716,38 +12258,37 @@ namespace ts { return result; } - function isJSDocOptionalParameter(node: ParameterDeclaration) { - return isInJSFile(node) && ( + function isJSDocOptionalParameter(node: ts.ParameterDeclaration) { + return ts.isInJSFile(node) && ( // node.type should only be a JSDocOptionalType when node is a parameter of a JSDocFunctionType - node.type && node.type.kind === SyntaxKind.JSDocOptionalType - || getJSDocParameterTags(node).some(({ isBracketed, typeExpression }) => - isBracketed || !!typeExpression && typeExpression.type.kind === SyntaxKind.JSDocOptionalType)); + node.type && node.type.kind === ts.SyntaxKind.JSDocOptionalType + || ts.getJSDocParameterTags(node).some(({ isBracketed, typeExpression }) => isBracketed || !!typeExpression && typeExpression.type.kind === ts.SyntaxKind.JSDocOptionalType)); } function tryFindAmbientModule(moduleName: string, withAugmentations: boolean) { - if (isExternalModuleNameRelative(moduleName)) { + if (ts.isExternalModuleNameRelative(moduleName)) { return undefined; } - const symbol = getSymbol(globals, '"' + moduleName + '"' as __String, SymbolFlags.ValueModule); + const symbol = getSymbol(globals, '"' + moduleName + '"' as ts.__String, ts.SymbolFlags.ValueModule); // merged symbol is module declaration symbol combined with all augmentations return symbol && withAugmentations ? getMergedSymbol(symbol) : symbol; } - function isOptionalParameter(node: ParameterDeclaration | JSDocParameterTag | JSDocPropertyTag) { - if (hasQuestionToken(node) || isOptionalJSDocPropertyLikeTag(node) || isJSDocOptionalParameter(node)) { + function isOptionalParameter(node: ts.ParameterDeclaration | ts.JSDocParameterTag | ts.JSDocPropertyTag) { + if (ts.hasQuestionToken(node) || isOptionalJSDocPropertyLikeTag(node) || isJSDocOptionalParameter(node)) { return true; } if (node.initializer) { const signature = getSignatureFromDeclaration(node.parent); const parameterIndex = node.parent.parameters.indexOf(node); - Debug.assert(parameterIndex >= 0); + ts.Debug.assert(parameterIndex >= 0); // Only consider syntactic or instantiated parameters as optional, not `void` parameters as this function is used // in grammar checks and checking for `void` too early results in parameter types widening too early // and causes some noImplicitAny errors to be lost. return parameterIndex >= getMinArgumentCount(signature, MinArgumentCountFlags.StrongArityForUntypedJS | MinArgumentCountFlags.VoidIsNonOptional); } - const iife = getImmediatelyInvokedFunctionExpression(node.parent); + const iife = ts.getImmediatelyInvokedFunctionExpression(node.parent); if (iife) { return !node.type && !node.dotDotDotToken && @@ -12757,27 +12298,27 @@ namespace ts { return false; } - function isOptionalPropertyDeclaration(node: Declaration) { - return isPropertyDeclaration(node) && node.questionToken; + function isOptionalPropertyDeclaration(node: ts.Declaration) { + return ts.isPropertyDeclaration(node) && node.questionToken; } - function isOptionalJSDocPropertyLikeTag(node: Node): node is JSDocPropertyLikeTag { - if (!isJSDocPropertyLikeTag(node)) { + function isOptionalJSDocPropertyLikeTag(node: ts.Node): node is ts.JSDocPropertyLikeTag { + if (!ts.isJSDocPropertyLikeTag(node)) { return false; } const { isBracketed, typeExpression } = node; - return isBracketed || !!typeExpression && typeExpression.type.kind === SyntaxKind.JSDocOptionalType; + return isBracketed || !!typeExpression && typeExpression.type.kind === ts.SyntaxKind.JSDocOptionalType; } - function createTypePredicate(kind: TypePredicateKind, parameterName: string | undefined, parameterIndex: number | undefined, type: Type | undefined): TypePredicate { - return { kind, parameterName, parameterIndex, type } as TypePredicate; + function createTypePredicate(kind: ts.TypePredicateKind, parameterName: string | undefined, parameterIndex: number | undefined, type: ts.Type | undefined): ts.TypePredicate { + return { kind, parameterName, parameterIndex, type } as ts.TypePredicate; } /** * Gets the minimum number of type arguments needed to satisfy all non-optional type * parameters. */ - function getMinTypeArgumentCount(typeParameters: readonly TypeParameter[] | undefined): number { + function getMinTypeArgumentCount(typeParameters: readonly ts.TypeParameter[] | undefined): number { let minTypeArgumentCount = 0; if (typeParameters) { for (let i = 0; i < typeParameters.length; i++) { @@ -12797,14 +12338,14 @@ namespace ts { * @param typeParameters The requested type parameters. * @param minTypeArgumentCount The minimum number of required type arguments. */ - function fillMissingTypeArguments(typeArguments: readonly Type[], typeParameters: readonly TypeParameter[] | undefined, minTypeArgumentCount: number, isJavaScriptImplicitAny: boolean): Type[]; - function fillMissingTypeArguments(typeArguments: readonly Type[] | undefined, typeParameters: readonly TypeParameter[] | undefined, minTypeArgumentCount: number, isJavaScriptImplicitAny: boolean): Type[] | undefined; - function fillMissingTypeArguments(typeArguments: readonly Type[] | undefined, typeParameters: readonly TypeParameter[] | undefined, minTypeArgumentCount: number, isJavaScriptImplicitAny: boolean) { - const numTypeParameters = length(typeParameters); + function fillMissingTypeArguments(typeArguments: readonly ts.Type[], typeParameters: readonly ts.TypeParameter[] | undefined, minTypeArgumentCount: number, isJavaScriptImplicitAny: boolean): ts.Type[]; + function fillMissingTypeArguments(typeArguments: readonly ts.Type[] | undefined, typeParameters: readonly ts.TypeParameter[] | undefined, minTypeArgumentCount: number, isJavaScriptImplicitAny: boolean): ts.Type[] | undefined; + function fillMissingTypeArguments(typeArguments: readonly ts.Type[] | undefined, typeParameters: readonly ts.TypeParameter[] | undefined, minTypeArgumentCount: number, isJavaScriptImplicitAny: boolean) { + const numTypeParameters = ts.length(typeParameters); if (!numTypeParameters) { return []; } - const numTypeArguments = length(typeArguments); + const numTypeArguments = ts.length(typeArguments); if (isJavaScriptImplicitAny || (numTypeArguments >= minTypeArgumentCount && numTypeArguments <= numTypeParameters)) { const result = typeArguments ? typeArguments.slice() : []; // Map invalid forward references in default types to the error type @@ -12825,23 +12366,23 @@ namespace ts { return typeArguments && typeArguments.slice(); } - function getSignatureFromDeclaration(declaration: SignatureDeclaration | JSDocSignature): Signature { + function getSignatureFromDeclaration(declaration: ts.SignatureDeclaration | ts.JSDocSignature): ts.Signature { const links = getNodeLinks(declaration); if (!links.resolvedSignature) { - const parameters: Symbol[] = []; - let flags = SignatureFlags.None; + const parameters: ts.Symbol[] = []; + let flags = ts.SignatureFlags.None; let minArgumentCount = 0; - let thisParameter: Symbol | undefined; + let thisParameter: ts.Symbol | undefined; let hasThisParameter = false; - const iife = getImmediatelyInvokedFunctionExpression(declaration); - const isJSConstructSignature = isJSDocConstructSignature(declaration); + const iife = ts.getImmediatelyInvokedFunctionExpression(declaration); + const isJSConstructSignature = ts.isJSDocConstructSignature(declaration); const isUntypedSignatureInJSFile = !iife && - isInJSFile(declaration) && - isValueSignatureDeclaration(declaration) && - !hasJSDocParameterTags(declaration) && - !getJSDocType(declaration); + ts.isInJSFile(declaration) && + ts.isValueSignatureDeclaration(declaration) && + !ts.hasJSDocParameterTags(declaration) && + !ts.getJSDocType(declaration); if (isUntypedSignatureInJSFile) { - flags |= SignatureFlags.IsUntypedSignatureInJSFile; + flags |= ts.SignatureFlags.IsUntypedSignatureInJSFile; } // If this is a JSDoc construct signature, then skip the first parameter in the @@ -12851,13 +12392,13 @@ namespace ts { const param = declaration.parameters[i]; let paramSymbol = param.symbol; - const type = isJSDocParameterTag(param) ? (param.typeExpression && param.typeExpression.type) : param.type; + const type = ts.isJSDocParameterTag(param) ? (param.typeExpression && param.typeExpression.type) : param.type; // Include parameter symbol instead of property symbol in the signature - if (paramSymbol && !!(paramSymbol.flags & SymbolFlags.Property) && !isBindingPattern(param.name)) { - const resolvedSymbol = resolveName(param, paramSymbol.escapedName, SymbolFlags.Value, undefined, undefined, /*isUse*/ false); + if (paramSymbol && !!(paramSymbol.flags & ts.SymbolFlags.Property) && !ts.isBindingPattern(param.name)) { + const resolvedSymbol = resolveName(param, paramSymbol.escapedName, ts.SymbolFlags.Value, undefined, undefined, /*isUse*/ false); paramSymbol = resolvedSymbol!; } - if (i === 0 && paramSymbol.escapedName === InternalSymbolName.This) { + if (i === 0 && paramSymbol.escapedName === ts.InternalSymbolName.This) { hasThisParameter = true; thisParameter = param.symbol; } @@ -12865,13 +12406,13 @@ namespace ts { parameters.push(paramSymbol); } - if (type && type.kind === SyntaxKind.LiteralType) { - flags |= SignatureFlags.HasLiteralTypes; + if (type && type.kind === ts.SyntaxKind.LiteralType) { + flags |= ts.SignatureFlags.HasLiteralTypes; } // Record a new minimum argument count if this is not an optional parameter const isOptionalParameter = isOptionalJSDocPropertyLikeTag(param) || - param.initializer || param.questionToken || isRestParameter(param) || + param.initializer || param.questionToken || ts.isRestParameter(param) || iife && parameters.length > iife.arguments.length && !type || isJSDocOptionalParameter(param); if (!isOptionalParameter) { @@ -12880,30 +12421,29 @@ namespace ts { } // If only one accessor includes a this-type annotation, the other behaves as if it had the same type annotation - if ((declaration.kind === SyntaxKind.GetAccessor || declaration.kind === SyntaxKind.SetAccessor) && + if ((declaration.kind === ts.SyntaxKind.GetAccessor || declaration.kind === ts.SyntaxKind.SetAccessor) && hasBindableName(declaration) && (!hasThisParameter || !thisParameter)) { - const otherKind = declaration.kind === SyntaxKind.GetAccessor ? SyntaxKind.SetAccessor : SyntaxKind.GetAccessor; - const other = getDeclarationOfKind(getSymbolOfNode(declaration), otherKind); + const otherKind = declaration.kind === ts.SyntaxKind.GetAccessor ? ts.SyntaxKind.SetAccessor : ts.SyntaxKind.GetAccessor; + const other = ts.getDeclarationOfKind(getSymbolOfNode(declaration), otherKind); if (other) { thisParameter = getAnnotatedAccessorThisParameter(other); } } - const classType = declaration.kind === SyntaxKind.Constructor ? - getDeclaredTypeOfClassOrInterface(getMergedSymbol((declaration.parent as ClassDeclaration).symbol)) + const classType = declaration.kind === ts.SyntaxKind.Constructor ? + getDeclaredTypeOfClassOrInterface(getMergedSymbol((declaration.parent as ts.ClassDeclaration).symbol)) : undefined; const typeParameters = classType ? classType.localTypeParameters : getTypeParametersFromDeclaration(declaration); - if (hasRestParameter(declaration) || isInJSFile(declaration) && maybeAddJsSyntheticRestParameter(declaration, parameters)) { - flags |= SignatureFlags.HasRestParameter; + if (ts.hasRestParameter(declaration) || ts.isInJSFile(declaration) && maybeAddJsSyntheticRestParameter(declaration, parameters)) { + flags |= ts.SignatureFlags.HasRestParameter; } - if (isConstructorTypeNode(declaration) && hasSyntacticModifier(declaration, ModifierFlags.Abstract) || - isConstructorDeclaration(declaration) && hasSyntacticModifier(declaration.parent, ModifierFlags.Abstract)) { - flags |= SignatureFlags.Abstract; + if (ts.isConstructorTypeNode(declaration) && ts.hasSyntacticModifier(declaration, ts.ModifierFlags.Abstract) || + ts.isConstructorDeclaration(declaration) && ts.hasSyntacticModifier(declaration.parent, ts.ModifierFlags.Abstract)) { + flags |= ts.SignatureFlags.Abstract; } links.resolvedSignature = createSignature(declaration, typeParameters, thisParameter, parameters, - /*resolvedReturnType*/ undefined, /*resolvedTypePredicate*/ undefined, - minArgumentCount, flags); + /*resolvedReturnType*/ undefined, /*resolvedTypePredicate*/ undefined, minArgumentCount, flags); } return links.resolvedSignature; } @@ -12914,16 +12454,14 @@ namespace ts { * OR * 2. It has at least one parameter, and the last parameter has a matching `@param` with a type that starts with `...` */ - function maybeAddJsSyntheticRestParameter(declaration: SignatureDeclaration | JSDocSignature, parameters: Symbol[]): boolean { - if (isJSDocSignature(declaration) || !containsArgumentsReference(declaration)) { + function maybeAddJsSyntheticRestParameter(declaration: ts.SignatureDeclaration | ts.JSDocSignature, parameters: ts.Symbol[]): boolean { + if (ts.isJSDocSignature(declaration) || !containsArgumentsReference(declaration)) { return false; } - const lastParam = lastOrUndefined(declaration.parameters); - const lastParamTags = lastParam ? getJSDocParameterTags(lastParam) : getJSDocTags(declaration).filter(isJSDocParameterTag); - const lastParamVariadicType = firstDefined(lastParamTags, p => - p.typeExpression && isJSDocVariadicType(p.typeExpression.type) ? p.typeExpression.type : undefined); - - const syntheticArgsSymbol = createSymbol(SymbolFlags.Variable, "args" as __String, CheckFlags.RestParameter); + const lastParam = ts.lastOrUndefined(declaration.parameters); + const lastParamTags = lastParam ? ts.getJSDocParameterTags(lastParam) : ts.getJSDocTags(declaration).filter(ts.isJSDocParameterTag); + const lastParamVariadicType = ts.firstDefined(lastParamTags, p => p.typeExpression && ts.isJSDocVariadicType(p.typeExpression.type) ? p.typeExpression.type : undefined); + const syntheticArgsSymbol = createSymbol(ts.SymbolFlags.Variable, "args" as ts.__String, ts.CheckFlags.RestParameter); if (lastParamVariadicType) { // Parameter has effective annotation, lock in type syntheticArgsSymbol.type = createArrayType(getTypeFromTypeNode(lastParamVariadicType.type)); @@ -12932,7 +12470,7 @@ namespace ts { // Parameter has no annotation // By using a `DeferredType` symbol, we allow the type of this rest arg to be overriden by contextual type assignment so long as its type hasn't been // cached by `getTypeOfSymbol` yet. - syntheticArgsSymbol.checkFlags |= CheckFlags.DeferredType; + syntheticArgsSymbol.checkFlags |= ts.CheckFlags.DeferredType; syntheticArgsSymbol.deferralParent = neverType; syntheticArgsSymbol.deferralConstituents = [anyArrayType]; syntheticArgsSymbol.deferralWriteConstituents = [anyArrayType]; @@ -12945,73 +12483,75 @@ namespace ts { return true; } - function getSignatureOfTypeTag(node: SignatureDeclaration | JSDocSignature) { + function getSignatureOfTypeTag(node: ts.SignatureDeclaration | ts.JSDocSignature) { // should be attached to a function declaration or expression - if (!(isInJSFile(node) && isFunctionLikeDeclaration(node))) return undefined; - const typeTag = getJSDocTypeTag(node); + if (!(ts.isInJSFile(node) && ts.isFunctionLikeDeclaration(node))) + return undefined; + const typeTag = ts.getJSDocTypeTag(node); return typeTag?.typeExpression && getSingleCallSignature(getTypeFromTypeNode(typeTag.typeExpression)); } - function getParameterTypeOfTypeTag(func: FunctionLikeDeclaration, parameter: ParameterDeclaration) { + function getParameterTypeOfTypeTag(func: ts.FunctionLikeDeclaration, parameter: ts.ParameterDeclaration) { const signature = getSignatureOfTypeTag(func); - if (!signature) return undefined; + if (!signature) + return undefined; const pos = func.parameters.indexOf(parameter); return parameter.dotDotDotToken ? getRestTypeAtPosition(signature, pos) : getTypeAtPosition(signature, pos); } - function getReturnTypeOfTypeTag(node: SignatureDeclaration | JSDocSignature) { + function getReturnTypeOfTypeTag(node: ts.SignatureDeclaration | ts.JSDocSignature) { const signature = getSignatureOfTypeTag(node); return signature && getReturnTypeOfSignature(signature); } - function containsArgumentsReference(declaration: SignatureDeclaration): boolean { + function containsArgumentsReference(declaration: ts.SignatureDeclaration): boolean { const links = getNodeLinks(declaration); if (links.containsArgumentsReference === undefined) { - if (links.flags & NodeCheckFlags.CaptureArguments) { + if (links.flags & ts.NodeCheckFlags.CaptureArguments) { links.containsArgumentsReference = true; } else { - links.containsArgumentsReference = traverse((declaration as FunctionLikeDeclaration).body!); + links.containsArgumentsReference = traverse((declaration as ts.FunctionLikeDeclaration).body!); } } return links.containsArgumentsReference; - function traverse(node: Node): boolean { - if (!node) return false; + function traverse(node: ts.Node): boolean { + if (!node) + return false; switch (node.kind) { - case SyntaxKind.Identifier: - return (node as Identifier).escapedText === argumentsSymbol.escapedName && getReferencedValueSymbol(node as Identifier) === argumentsSymbol; - - case SyntaxKind.PropertyDeclaration: - case SyntaxKind.MethodDeclaration: - case SyntaxKind.GetAccessor: - case SyntaxKind.SetAccessor: - return (node as NamedDeclaration).name!.kind === SyntaxKind.ComputedPropertyName - && traverse((node as NamedDeclaration).name!); - - case SyntaxKind.PropertyAccessExpression: - case SyntaxKind.ElementAccessExpression: - return traverse((node as PropertyAccessExpression | ElementAccessExpression).expression); - - case SyntaxKind.PropertyAssignment: - return traverse((node as PropertyAssignment).initializer); + case ts.SyntaxKind.Identifier: + return (node as ts.Identifier).escapedText === argumentsSymbol.escapedName && getReferencedValueSymbol(node as ts.Identifier) === argumentsSymbol; + case ts.SyntaxKind.PropertyDeclaration: + case ts.SyntaxKind.MethodDeclaration: + case ts.SyntaxKind.GetAccessor: + case ts.SyntaxKind.SetAccessor: + return (node as ts.NamedDeclaration).name!.kind === ts.SyntaxKind.ComputedPropertyName + && traverse((node as ts.NamedDeclaration).name!); + case ts.SyntaxKind.PropertyAccessExpression: + case ts.SyntaxKind.ElementAccessExpression: + return traverse((node as ts.PropertyAccessExpression | ts.ElementAccessExpression).expression); + case ts.SyntaxKind.PropertyAssignment: + return traverse((node as ts.PropertyAssignment).initializer); default: - return !nodeStartsNewLexicalEnvironment(node) && !isPartOfTypeNode(node) && !!forEachChild(node, traverse); + return !ts.nodeStartsNewLexicalEnvironment(node) && !ts.isPartOfTypeNode(node) && !!ts.forEachChild(node, traverse); } } } - function getSignaturesOfSymbol(symbol: Symbol | undefined): Signature[] { - if (!symbol || !symbol.declarations) return emptyArray; - const result: Signature[] = []; + function getSignaturesOfSymbol(symbol: ts.Symbol | undefined): ts.Signature[] { + if (!symbol || !symbol.declarations) + return ts.emptyArray; + const result: ts.Signature[] = []; for (let i = 0; i < symbol.declarations.length; i++) { const decl = symbol.declarations[i]; - if (!isFunctionLike(decl)) continue; + if (!ts.isFunctionLike(decl)) + continue; // Don't include signature if node is the implementation of an overloaded function. A node is considered // an implementation node if it has a body and the previous node is of the same kind and immediately // precedes the implementation node (i.e. has the same parent and ends where the implementation starts). - if (i > 0 && (decl as FunctionLikeDeclaration).body) { + if (i > 0 && (decl as ts.FunctionLikeDeclaration).body) { const previous = symbol.declarations[i - 1]; if (decl.parent === previous.parent && decl.kind === previous.kind && decl.pos === previous.end) { continue; @@ -13022,7 +12562,7 @@ namespace ts { return result; } - function resolveExternalModuleTypeByLiteral(name: StringLiteral) { + function resolveExternalModuleTypeByLiteral(name: ts.StringLiteral) { const moduleSym = resolveExternalModuleName(name, name); if (moduleSym) { const resolvedModuleSymbol = resolveExternalModuleSymbol(moduleSym); @@ -13034,13 +12574,13 @@ namespace ts { return anyType; } - function getThisTypeOfSignature(signature: Signature): Type | undefined { + function getThisTypeOfSignature(signature: ts.Signature): ts.Type | undefined { if (signature.thisParameter) { return getTypeOfSymbol(signature.thisParameter); } } - function getTypePredicateOfSignature(signature: Signature): TypePredicate | undefined { + function getTypePredicateOfSignature(signature: ts.Signature): ts.TypePredicate | undefined { if (!signature.resolvedTypePredicate) { if (signature.target) { const targetTypePredicate = getTypePredicateOfSignature(signature.target); @@ -13050,65 +12590,64 @@ namespace ts { signature.resolvedTypePredicate = getUnionOrIntersectionTypePredicate(signature.compositeSignatures, signature.compositeKind) || noTypePredicate; } else { - const type = signature.declaration && getEffectiveReturnTypeNode(signature.declaration); - let jsdocPredicate: TypePredicate | undefined; - if (!type && isInJSFile(signature.declaration)) { + const type = signature.declaration && ts.getEffectiveReturnTypeNode(signature.declaration); + let jsdocPredicate: ts.TypePredicate | undefined; + if (!type && ts.isInJSFile(signature.declaration)) { const jsdocSignature = getSignatureOfTypeTag(signature.declaration!); if (jsdocSignature && signature !== jsdocSignature) { jsdocPredicate = getTypePredicateOfSignature(jsdocSignature); } } - signature.resolvedTypePredicate = type && isTypePredicateNode(type) ? + signature.resolvedTypePredicate = type && ts.isTypePredicateNode(type) ? createTypePredicateFromTypePredicateNode(type, signature) : jsdocPredicate || noTypePredicate; } - Debug.assert(!!signature.resolvedTypePredicate); + ts.Debug.assert(!!signature.resolvedTypePredicate); } return signature.resolvedTypePredicate === noTypePredicate ? undefined : signature.resolvedTypePredicate; } - function createTypePredicateFromTypePredicateNode(node: TypePredicateNode, signature: Signature): TypePredicate { + function createTypePredicateFromTypePredicateNode(node: ts.TypePredicateNode, signature: ts.Signature): ts.TypePredicate { const parameterName = node.parameterName; const type = node.type && getTypeFromTypeNode(node.type); - return parameterName.kind === SyntaxKind.ThisType ? - createTypePredicate(node.assertsModifier ? TypePredicateKind.AssertsThis : TypePredicateKind.This, /*parameterName*/ undefined, /*parameterIndex*/ undefined, type) : - createTypePredicate(node.assertsModifier ? TypePredicateKind.AssertsIdentifier : TypePredicateKind.Identifier, parameterName.escapedText as string, - findIndex(signature.parameters, p => p.escapedName === parameterName.escapedText), type); + return parameterName.kind === ts.SyntaxKind.ThisType ? + createTypePredicate(node.assertsModifier ? ts.TypePredicateKind.AssertsThis : ts.TypePredicateKind.This, /*parameterName*/ undefined, /*parameterIndex*/ undefined, type) : + createTypePredicate(node.assertsModifier ? ts.TypePredicateKind.AssertsIdentifier : ts.TypePredicateKind.Identifier, parameterName.escapedText as string, ts.findIndex(signature.parameters, p => p.escapedName === parameterName.escapedText), type); } - function getUnionOrIntersectionType(types: Type[], kind: TypeFlags | undefined, unionReduction?: UnionReduction) { - return kind !== TypeFlags.Intersection ? getUnionType(types, unionReduction) : getIntersectionType(types); + function getUnionOrIntersectionType(types: ts.Type[], kind: ts.TypeFlags | undefined, unionReduction?: ts.UnionReduction) { + return kind !== ts.TypeFlags.Intersection ? getUnionType(types, unionReduction) : getIntersectionType(types); } - function getReturnTypeOfSignature(signature: Signature): Type { + function getReturnTypeOfSignature(signature: ts.Signature): ts.Type { if (!signature.resolvedReturnType) { if (!pushTypeResolution(signature, TypeSystemPropertyName.ResolvedReturnType)) { return errorType; } let type = signature.target ? instantiateType(getReturnTypeOfSignature(signature.target), signature.mapper) : - signature.compositeSignatures ? instantiateType(getUnionOrIntersectionType(map(signature.compositeSignatures, getReturnTypeOfSignature), signature.compositeKind, UnionReduction.Subtype), signature.mapper) : + signature.compositeSignatures ? instantiateType(getUnionOrIntersectionType(ts.map(signature.compositeSignatures, getReturnTypeOfSignature), signature.compositeKind, ts.UnionReduction.Subtype), signature.mapper) : getReturnTypeFromAnnotation(signature.declaration!) || - (nodeIsMissing((signature.declaration as FunctionLikeDeclaration).body) ? anyType : getReturnTypeFromBody(signature.declaration as FunctionLikeDeclaration)); - if (signature.flags & SignatureFlags.IsInnerCallChain) { + (ts.nodeIsMissing((signature.declaration as ts.FunctionLikeDeclaration).body) ? anyType : getReturnTypeFromBody(signature.declaration as ts.FunctionLikeDeclaration)); + if (signature.flags & ts.SignatureFlags.IsInnerCallChain) { type = addOptionalTypeMarker(type); } - else if (signature.flags & SignatureFlags.IsOuterCallChain) { + else if (signature.flags & ts.SignatureFlags.IsOuterCallChain) { type = getOptionalType(type); } if (!popTypeResolution()) { if (signature.declaration) { - const typeNode = getEffectiveReturnTypeNode(signature.declaration); + const typeNode = ts.getEffectiveReturnTypeNode(signature.declaration); if (typeNode) { - error(typeNode, Diagnostics.Return_type_annotation_circularly_references_itself); + error(typeNode, ts.Diagnostics.Return_type_annotation_circularly_references_itself); } else if (noImplicitAny) { - const declaration = signature.declaration as Declaration; - const name = getNameOfDeclaration(declaration); + const declaration = signature.declaration as ts.Declaration; + const name = ts.getNameOfDeclaration(declaration); if (name) { - error(name, Diagnostics._0_implicitly_has_return_type_any_because_it_does_not_have_a_return_type_annotation_and_is_referenced_directly_or_indirectly_in_one_of_its_return_expressions, declarationNameToString(name)); + error(name, ts.Diagnostics._0_implicitly_has_return_type_any_because_it_does_not_have_a_return_type_annotation_and_is_referenced_directly_or_indirectly_in_one_of_its_return_expressions, ts.declarationNameToString(name)); } else { - error(declaration, Diagnostics.Function_implicitly_has_return_type_any_because_it_does_not_have_a_return_type_annotation_and_is_referenced_directly_or_indirectly_in_one_of_its_return_expressions); + error(declaration, ts.Diagnostics.Function_implicitly_has_return_type_any_because_it_does_not_have_a_return_type_annotation_and_is_referenced_directly_or_indirectly_in_one_of_its_return_expressions); } } } @@ -13119,23 +12658,23 @@ namespace ts { return signature.resolvedReturnType; } - function getReturnTypeFromAnnotation(declaration: SignatureDeclaration | JSDocSignature) { - if (declaration.kind === SyntaxKind.Constructor) { - return getDeclaredTypeOfClassOrInterface(getMergedSymbol((declaration.parent as ClassDeclaration).symbol)); + function getReturnTypeFromAnnotation(declaration: ts.SignatureDeclaration | ts.JSDocSignature) { + if (declaration.kind === ts.SyntaxKind.Constructor) { + return getDeclaredTypeOfClassOrInterface(getMergedSymbol((declaration.parent as ts.ClassDeclaration).symbol)); } - if (isJSDocConstructSignature(declaration)) { - return getTypeFromTypeNode((declaration.parameters[0] as ParameterDeclaration).type!); // TODO: GH#18217 + if (ts.isJSDocConstructSignature(declaration)) { + return getTypeFromTypeNode((declaration.parameters[0] as ts.ParameterDeclaration).type!); // TODO: GH#18217 } - const typeNode = getEffectiveReturnTypeNode(declaration); + const typeNode = ts.getEffectiveReturnTypeNode(declaration); if (typeNode) { return getTypeFromTypeNode(typeNode); } - if (declaration.kind === SyntaxKind.GetAccessor && hasBindableName(declaration)) { - const jsDocType = isInJSFile(declaration) && getTypeForDeclarationFromJSDocComment(declaration); + if (declaration.kind === ts.SyntaxKind.GetAccessor && hasBindableName(declaration)) { + const jsDocType = ts.isInJSFile(declaration) && getTypeForDeclarationFromJSDocComment(declaration); if (jsDocType) { return jsDocType; } - const setter = getDeclarationOfKind(getSymbolOfNode(declaration), SyntaxKind.SetAccessor); + const setter = ts.getDeclarationOfKind(getSymbolOfNode(declaration), ts.SyntaxKind.SetAccessor); const setterType = getAnnotatedAccessorType(setter); if (setterType) { return setterType; @@ -13144,15 +12683,15 @@ namespace ts { return getReturnTypeOfTypeTag(declaration); } - function isResolvingReturnTypeOfSignature(signature: Signature) { + function isResolvingReturnTypeOfSignature(signature: ts.Signature) { return !signature.resolvedReturnType && findResolutionCycleStartIndex(signature, TypeSystemPropertyName.ResolvedReturnType) >= 0; } - function getRestTypeOfSignature(signature: Signature): Type { + function getRestTypeOfSignature(signature: ts.Signature): ts.Type { return tryGetRestTypeOfSignature(signature) || anyType; } - function tryGetRestTypeOfSignature(signature: Signature): Type | undefined { + function tryGetRestTypeOfSignature(signature: ts.Signature): ts.Type | undefined { if (signatureHasRestParameter(signature)) { const sigRestType = getTypeOfSymbol(signature.parameters[signature.parameters.length - 1]); const restType = isTupleType(sigRestType) ? getRestTypeOfTupleType(sigRestType) : sigRestType; @@ -13161,7 +12700,7 @@ namespace ts { return undefined; } - function getSignatureInstantiation(signature: Signature, typeArguments: Type[] | undefined, isJavascript: boolean, inferredTypeParameters?: readonly TypeParameter[]): Signature { + function getSignatureInstantiation(signature: ts.Signature, typeArguments: ts.Type[] | undefined, isJavascript: boolean, inferredTypeParameters?: readonly ts.TypeParameter[]): ts.Signature { const instantiatedSignature = getSignatureInstantiationWithoutFillingInTypeArguments(signature, fillMissingTypeArguments(typeArguments, signature.typeParameters, getMinTypeArgumentCount(signature.typeParameters), isJavascript)); if (inferredTypeParameters) { const returnSignature = getSingleCallOrConstructSignature(getReturnTypeOfSignature(instantiatedSignature)); @@ -13176,8 +12715,8 @@ namespace ts { return instantiatedSignature; } - function getSignatureInstantiationWithoutFillingInTypeArguments(signature: Signature, typeArguments: readonly Type[] | undefined): Signature { - const instantiations = signature.instantiations || (signature.instantiations = new Map()); + function getSignatureInstantiationWithoutFillingInTypeArguments(signature: ts.Signature, typeArguments: readonly ts.Type[] | undefined): ts.Signature { + const instantiations = signature.instantiations || (signature.instantiations = new ts.Map()); const id = getTypeListId(typeArguments); let instantiation = instantiations.get(id); if (!instantiation) { @@ -13186,53 +12725,50 @@ namespace ts { return instantiation; } - function createSignatureInstantiation(signature: Signature, typeArguments: readonly Type[] | undefined): Signature { + function createSignatureInstantiation(signature: ts.Signature, typeArguments: readonly ts.Type[] | undefined): ts.Signature { return instantiateSignature(signature, createSignatureTypeMapper(signature, typeArguments), /*eraseTypeParameters*/ true); } - function createSignatureTypeMapper(signature: Signature, typeArguments: readonly Type[] | undefined): TypeMapper { + function createSignatureTypeMapper(signature: ts.Signature, typeArguments: readonly ts.Type[] | undefined): ts.TypeMapper { return createTypeMapper(signature.typeParameters!, typeArguments); } - function getErasedSignature(signature: Signature): Signature { + function getErasedSignature(signature: ts.Signature): ts.Signature { return signature.typeParameters ? signature.erasedSignatureCache || (signature.erasedSignatureCache = createErasedSignature(signature)) : signature; } - function createErasedSignature(signature: Signature) { + function createErasedSignature(signature: ts.Signature) { // Create an instantiation of the signature where all type arguments are the any type. return instantiateSignature(signature, createTypeEraser(signature.typeParameters!), /*eraseTypeParameters*/ true); } - function getCanonicalSignature(signature: Signature): Signature { + function getCanonicalSignature(signature: ts.Signature): ts.Signature { return signature.typeParameters ? signature.canonicalSignatureCache || (signature.canonicalSignatureCache = createCanonicalSignature(signature)) : signature; } - function createCanonicalSignature(signature: Signature) { + function createCanonicalSignature(signature: ts.Signature) { // Create an instantiation of the signature where each unconstrained type parameter is replaced with // its original. When a generic class or interface is instantiated, each generic method in the class or // interface is instantiated with a fresh set of cloned type parameters (which we need to handle scenarios // where different generations of the same type parameter are in scope). This leads to a lot of new type // identities, and potentially a lot of work comparing those identities, so here we create an instantiation // that uses the original type identities for all unconstrained type parameters. - return getSignatureInstantiation( - signature, - map(signature.typeParameters, tp => tp.target && !getConstraintOfTypeParameter(tp.target) ? tp.target : tp), - isInJSFile(signature.declaration)); + return getSignatureInstantiation(signature, ts.map(signature.typeParameters, tp => tp.target && !getConstraintOfTypeParameter(tp.target) ? tp.target : tp), ts.isInJSFile(signature.declaration)); } - function getBaseSignature(signature: Signature) { + function getBaseSignature(signature: ts.Signature) { const typeParameters = signature.typeParameters; if (typeParameters) { if (signature.baseSignatureCache) { return signature.baseSignatureCache; } const typeEraser = createTypeEraser(typeParameters); - const baseConstraintMapper = createTypeMapper(typeParameters, map(typeParameters, tp => getConstraintOfTypeParameter(tp) || unknownType)); - let baseConstraints: readonly Type[] = map(typeParameters, tp => instantiateType(tp, baseConstraintMapper) || unknownType); + const baseConstraintMapper = createTypeMapper(typeParameters, ts.map(typeParameters, tp => getConstraintOfTypeParameter(tp) || unknownType)); + let baseConstraints: readonly ts.Type[] = ts.map(typeParameters, tp => instantiateType(tp, baseConstraintMapper) || unknownType); // Run N type params thru the immediate constraint mapper up to N times // This way any noncircular interdependent type parameters are definitely resolved to their external dependencies for (let i = 0; i < typeParameters.length - 1; i++) { @@ -13245,7 +12781,7 @@ namespace ts { return signature; } - function getOrCreateTypeFromSignature(signature: Signature): ObjectType { + function getOrCreateTypeFromSignature(signature: ts.Signature): ts.ObjectType { // There are two ways to declare a construct signature, one is by declaring a class constructor // using the constructor keyword, and the other is declaring a bare construct signature in an // object type literal or interface (using the new keyword). Each way of declaring a constructor @@ -13254,48 +12790,46 @@ namespace ts { const kind = signature.declaration?.kind; // If declaration is undefined, it is likely to be the signature of the default constructor. - const isConstructor = kind === undefined || kind === SyntaxKind.Constructor || kind === SyntaxKind.ConstructSignature || kind === SyntaxKind.ConstructorType; - - const type = createObjectType(ObjectFlags.Anonymous); + const isConstructor = kind === undefined || kind === ts.SyntaxKind.Constructor || kind === ts.SyntaxKind.ConstructSignature || kind === ts.SyntaxKind.ConstructorType; + const type = createObjectType(ts.ObjectFlags.Anonymous); type.members = emptySymbols; - type.properties = emptyArray; - type.callSignatures = !isConstructor ? [signature] : emptyArray; - type.constructSignatures = isConstructor ? [signature] : emptyArray; - type.indexInfos = emptyArray; + type.properties = ts.emptyArray; + type.callSignatures = !isConstructor ? [signature] : ts.emptyArray; + type.constructSignatures = isConstructor ? [signature] : ts.emptyArray; + type.indexInfos = ts.emptyArray; signature.isolatedSignatureType = type; } return signature.isolatedSignatureType; } - function getIndexSymbol(symbol: Symbol): Symbol | undefined { + function getIndexSymbol(symbol: ts.Symbol): ts.Symbol | undefined { return symbol.members ? getIndexSymbolFromSymbolTable(symbol.members) : undefined; } - function getIndexSymbolFromSymbolTable(symbolTable: SymbolTable): Symbol | undefined { - return symbolTable.get(InternalSymbolName.Index); + function getIndexSymbolFromSymbolTable(symbolTable: ts.SymbolTable): ts.Symbol | undefined { + return symbolTable.get(ts.InternalSymbolName.Index); } - function createIndexInfo(keyType: Type, type: Type, isReadonly: boolean, declaration?: IndexSignatureDeclaration): IndexInfo { + function createIndexInfo(keyType: ts.Type, type: ts.Type, isReadonly: boolean, declaration?: ts.IndexSignatureDeclaration): ts.IndexInfo { return { keyType, type, isReadonly, declaration }; } - function getIndexInfosOfSymbol(symbol: Symbol): IndexInfo[] { + function getIndexInfosOfSymbol(symbol: ts.Symbol): ts.IndexInfo[] { const indexSymbol = getIndexSymbol(symbol); - return indexSymbol ? getIndexInfosOfIndexSymbol(indexSymbol) : emptyArray; + return indexSymbol ? getIndexInfosOfIndexSymbol(indexSymbol) : ts.emptyArray; } - function getIndexInfosOfIndexSymbol(indexSymbol: Symbol): IndexInfo[] { + function getIndexInfosOfIndexSymbol(indexSymbol: ts.Symbol): ts.IndexInfo[] { if (indexSymbol.declarations) { - const indexInfos: IndexInfo[] = []; - for (const declaration of (indexSymbol.declarations as IndexSignatureDeclaration[])) { + const indexInfos: ts.IndexInfo[] = []; + for (const declaration of (indexSymbol.declarations as ts.IndexSignatureDeclaration[])) { if (declaration.parameters.length === 1) { const parameter = declaration.parameters[0]; if (parameter.type) { forEachType(getTypeFromTypeNode(parameter.type), keyType => { if (isValidIndexKeyType(keyType) && !findIndexInfo(indexInfos, keyType)) { - indexInfos.push(createIndexInfo(keyType, declaration.type ? getTypeFromTypeNode(declaration.type) : anyType, - hasEffectiveModifier(declaration, ModifierFlags.Readonly), declaration)); + indexInfos.push(createIndexInfo(keyType, declaration.type ? getTypeFromTypeNode(declaration.type) : anyType, ts.hasEffectiveModifier(declaration, ts.ModifierFlags.Readonly), declaration)); } }); } @@ -13303,33 +12837,33 @@ namespace ts { } return indexInfos; } - return emptyArray; + return ts.emptyArray; } - function isValidIndexKeyType(type: Type): boolean { - return !!(type.flags & (TypeFlags.String | TypeFlags.Number | TypeFlags.ESSymbol)) || isPatternLiteralType(type) || - !!(type.flags & TypeFlags.Intersection) && !isGenericType(type) && some((type as IntersectionType).types, isValidIndexKeyType); + function isValidIndexKeyType(type: ts.Type): boolean { + return !!(type.flags & (ts.TypeFlags.String | ts.TypeFlags.Number | ts.TypeFlags.ESSymbol)) || isPatternLiteralType(type) || + !!(type.flags & ts.TypeFlags.Intersection) && !isGenericType(type) && ts.some((type as ts.IntersectionType).types, isValidIndexKeyType); } - function getConstraintDeclaration(type: TypeParameter): TypeNode | undefined { - return mapDefined(filter(type.symbol && type.symbol.declarations, isTypeParameterDeclaration), getEffectiveConstraintOfTypeParameter)[0]; + function getConstraintDeclaration(type: ts.TypeParameter): ts.TypeNode | undefined { + return ts.mapDefined(ts.filter(type.symbol && type.symbol.declarations, ts.isTypeParameterDeclaration), ts.getEffectiveConstraintOfTypeParameter)[0]; } - function getInferredTypeParameterConstraint(typeParameter: TypeParameter, omitTypeReferences?: boolean) { - let inferences: Type[] | undefined; + function getInferredTypeParameterConstraint(typeParameter: ts.TypeParameter, omitTypeReferences?: boolean) { + let inferences: ts.Type[] | undefined; if (typeParameter.symbol?.declarations) { for (const declaration of typeParameter.symbol.declarations) { - if (declaration.parent.kind === SyntaxKind.InferType) { + if (declaration.parent.kind === ts.SyntaxKind.InferType) { // When an 'infer T' declaration is immediately contained in a type reference node // (such as 'Foo'), T's constraint is inferred from the constraint of the // corresponding type parameter in 'Foo'. When multiple 'infer T' declarations are // present, we form an intersection of the inferred constraint types. - const [childTypeParameter = declaration.parent, grandParent] = walkUpParenthesizedTypesAndGetParentAndChild(declaration.parent.parent); - if (grandParent.kind === SyntaxKind.TypeReference && !omitTypeReferences) { - const typeReference = grandParent as TypeReferenceNode; + const [childTypeParameter = declaration.parent, grandParent] = ts.walkUpParenthesizedTypesAndGetParentAndChild(declaration.parent.parent); + if (grandParent.kind === ts.SyntaxKind.TypeReference && !omitTypeReferences) { + const typeReference = grandParent as ts.TypeReferenceNode; const typeParameters = getTypeParametersForTypeReference(typeReference); if (typeParameters) { - const index = typeReference.typeArguments!.indexOf(childTypeParameter as TypeNode); + const index = typeReference.typeArguments!.indexOf(childTypeParameter as ts.TypeNode); if (index < typeParameters.length) { const declaredConstraint = getConstraintOfTypeParameter(typeParameters[index]); if (declaredConstraint) { @@ -13342,7 +12876,7 @@ namespace ts { const mapper = createTypeMapper(typeParameters, getEffectiveTypeArguments(typeReference, typeParameters)); const constraint = instantiateType(declaredConstraint, mapper); if (constraint !== typeParameter) { - inferences = append(inferences, constraint); + inferences = ts.append(inferences, constraint); } } } @@ -13350,33 +12884,31 @@ namespace ts { } // When an 'infer T' declaration is immediately contained in a rest parameter declaration, a rest type // or a named rest tuple element, we infer an 'unknown[]' constraint. - else if (grandParent.kind === SyntaxKind.Parameter && (grandParent as ParameterDeclaration).dotDotDotToken || - grandParent.kind === SyntaxKind.RestType || - grandParent.kind === SyntaxKind.NamedTupleMember && (grandParent as NamedTupleMember).dotDotDotToken) { - inferences = append(inferences, createArrayType(unknownType)); + else if (grandParent.kind === ts.SyntaxKind.Parameter && (grandParent as ts.ParameterDeclaration).dotDotDotToken || + grandParent.kind === ts.SyntaxKind.RestType || + grandParent.kind === ts.SyntaxKind.NamedTupleMember && (grandParent as ts.NamedTupleMember).dotDotDotToken) { + inferences = ts.append(inferences, createArrayType(unknownType)); } // When an 'infer T' declaration is immediately contained in a string template type, we infer a 'string' // constraint. - else if (grandParent.kind === SyntaxKind.TemplateLiteralTypeSpan) { - inferences = append(inferences, stringType); + else if (grandParent.kind === ts.SyntaxKind.TemplateLiteralTypeSpan) { + inferences = ts.append(inferences, stringType); } // When an 'infer T' declaration is in the constraint position of a mapped type, we infer a 'keyof any' // constraint. - else if (grandParent.kind === SyntaxKind.TypeParameter && grandParent.parent.kind === SyntaxKind.MappedType) { - inferences = append(inferences, keyofConstraintType); + else if (grandParent.kind === ts.SyntaxKind.TypeParameter && grandParent.parent.kind === ts.SyntaxKind.MappedType) { + inferences = ts.append(inferences, keyofConstraintType); } // When an 'infer T' declaration is the template of a mapped type, and that mapped type is the extends // clause of a conditional whose check type is also a mapped type, give it a constraint equal to the template // of the check type's mapped type - else if (grandParent.kind === SyntaxKind.MappedType && (grandParent as MappedTypeNode).type && - skipParentheses((grandParent as MappedTypeNode).type!) === declaration.parent && grandParent.parent.kind === SyntaxKind.ConditionalType && - (grandParent.parent as ConditionalTypeNode).extendsType === grandParent && (grandParent.parent as ConditionalTypeNode).checkType.kind === SyntaxKind.MappedType && - ((grandParent.parent as ConditionalTypeNode).checkType as MappedTypeNode).type) { - const checkMappedType = (grandParent.parent as ConditionalTypeNode).checkType as MappedTypeNode; + else if (grandParent.kind === ts.SyntaxKind.MappedType && (grandParent as ts.MappedTypeNode).type && + ts.skipParentheses((grandParent as ts.MappedTypeNode).type!) === declaration.parent && grandParent.parent.kind === ts.SyntaxKind.ConditionalType && + (grandParent.parent as ts.ConditionalTypeNode).extendsType === grandParent && (grandParent.parent as ts.ConditionalTypeNode).checkType.kind === ts.SyntaxKind.MappedType && + ((grandParent.parent as ts.ConditionalTypeNode).checkType as ts.MappedTypeNode).type) { + const checkMappedType = (grandParent.parent as ts.ConditionalTypeNode).checkType as ts.MappedTypeNode; const nodeType = getTypeFromTypeNode(checkMappedType.type!); - inferences = append(inferences, instantiateType(nodeType, - makeUnaryTypeMapper(getDeclaredTypeOfTypeParameter(getSymbolOfNode(checkMappedType.typeParameter)), checkMappedType.typeParameter.constraint ? getTypeFromTypeNode(checkMappedType.typeParameter.constraint) : keyofConstraintType) - )); + inferences = ts.append(inferences, instantiateType(nodeType, makeUnaryTypeMapper(getDeclaredTypeOfTypeParameter(getSymbolOfNode(checkMappedType.typeParameter)), checkMappedType.typeParameter.constraint ? getTypeFromTypeNode(checkMappedType.typeParameter.constraint) : keyofConstraintType))); } } } @@ -13385,7 +12917,7 @@ namespace ts { } /** This is a worker function. Use getConstraintOfTypeParameter which guards against circular constraints. */ - function getConstraintFromTypeParameter(typeParameter: TypeParameter): Type | undefined { + function getConstraintFromTypeParameter(typeParameter: ts.TypeParameter): ts.Type | undefined { if (!typeParameter.constraint) { if (typeParameter.target) { const targetConstraint = getConstraintOfTypeParameter(typeParameter.target); @@ -13398,10 +12930,10 @@ namespace ts { } else { let type = getTypeFromTypeNode(constraintDeclaration); - if (type.flags & TypeFlags.Any && !isErrorType(type)) { // Allow errorType to propegate to keep downstream errors suppressed + if (type.flags & ts.TypeFlags.Any && !isErrorType(type)) { // Allow errorType to propegate to keep downstream errors suppressed // use keyofConstraintType as the base constraint for mapped type key constraints (unknown isn;t assignable to that, but `any` was), // use unknown otherwise - type = constraintDeclaration.parent.parent.kind === SyntaxKind.MappedType ? keyofConstraintType : unknownType; + type = constraintDeclaration.parent.parent.kind === ts.SyntaxKind.MappedType ? keyofConstraintType : unknownType; } typeParameter.constraint = type; } @@ -13410,13 +12942,13 @@ namespace ts { return typeParameter.constraint === noConstraintType ? undefined : typeParameter.constraint; } - function getParentSymbolOfTypeParameter(typeParameter: TypeParameter): Symbol | undefined { - const tp = getDeclarationOfKind(typeParameter.symbol, SyntaxKind.TypeParameter)!; - const host = isJSDocTemplateTag(tp.parent) ? getEffectiveContainerForJSDocTemplateTag(tp.parent) : tp.parent; + function getParentSymbolOfTypeParameter(typeParameter: ts.TypeParameter): ts.Symbol | undefined { + const tp = ts.getDeclarationOfKind(typeParameter.symbol, ts.SyntaxKind.TypeParameter)!; + const host = ts.isJSDocTemplateTag(tp.parent) ? ts.getEffectiveContainerForJSDocTemplateTag(tp.parent) : tp.parent; return host && getSymbolOfNode(host); } - function getTypeListId(types: readonly Type[] | undefined) { + function getTypeListId(types: readonly ts.Type[] | undefined) { let result = ""; if (types) { const length = types.length; @@ -13440,7 +12972,7 @@ namespace ts { return result; } - function getAliasId(aliasSymbol: Symbol | undefined, aliasTypeArguments: readonly Type[] | undefined) { + function getAliasId(aliasSymbol: ts.Symbol | undefined, aliasTypeArguments: readonly ts.Type[] | undefined) { return aliasSymbol ? `@${getSymbolId(aliasSymbol)}` + (aliasTypeArguments ? `:${getTypeListId(aliasTypeArguments)}` : "") : ""; } @@ -13448,21 +12980,21 @@ namespace ts { // It is only necessary to do so if a constituent type might be the undefined type, the null type, the type // of an object literal or the anyFunctionType. This is because there are operations in the type checker // that care about the presence of such types at arbitrary depth in a containing type. - function getPropagatingFlagsOfTypes(types: readonly Type[], excludeKinds: TypeFlags): ObjectFlags { - let result: ObjectFlags = 0; + function getPropagatingFlagsOfTypes(types: readonly ts.Type[], excludeKinds: ts.TypeFlags): ts.ObjectFlags { + let result: ts.ObjectFlags = 0; for (const type of types) { if (!(type.flags & excludeKinds)) { - result |= getObjectFlags(type); + result |= ts.getObjectFlags(type); } } - return result & ObjectFlags.PropagatingFlags; + return result & ts.ObjectFlags.PropagatingFlags; } - function createTypeReference(target: GenericType, typeArguments: readonly Type[] | undefined): TypeReference { + function createTypeReference(target: ts.GenericType, typeArguments: readonly ts.Type[] | undefined): ts.TypeReference { const id = getTypeListId(typeArguments); let type = target.instantiations.get(id); if (!type) { - type = createObjectType(ObjectFlags.Reference, target.symbol) as TypeReference; + type = createObjectType(ts.ObjectFlags.Reference, target.symbol) as ts.TypeReference; target.instantiations.set(id, type); type.objectFlags |= typeArguments ? getPropagatingFlagsOfTypes(typeArguments, /*excludeKinds*/ 0) : 0; type.target = target; @@ -13471,8 +13003,8 @@ namespace ts { return type; } - function cloneTypeReference(source: TypeReference): TypeReference { - const type = createType(source.flags) as TypeReference; + function cloneTypeReference(source: ts.TypeReference): ts.TypeReference { + const type = createType(source.flags) as ts.TypeReference; type.symbol = source.symbol; type.objectFlags = source.objectFlags; type.target = source.target; @@ -13480,13 +13012,13 @@ namespace ts { return type; } - function createDeferredTypeReference(target: GenericType, node: TypeReferenceNode | ArrayTypeNode | TupleTypeNode, mapper?: TypeMapper, aliasSymbol?: Symbol, aliasTypeArguments?: readonly Type[]): DeferredTypeReference { + function createDeferredTypeReference(target: ts.GenericType, node: ts.TypeReferenceNode | ts.ArrayTypeNode | ts.TupleTypeNode, mapper?: ts.TypeMapper, aliasSymbol?: ts.Symbol, aliasTypeArguments?: readonly ts.Type[]): ts.DeferredTypeReference { if (!aliasSymbol) { aliasSymbol = getAliasSymbolForTypeNode(node); const localAliasTypeArguments = getTypeArgumentsForAliasSymbol(aliasSymbol); aliasTypeArguments = mapper ? instantiateTypes(localAliasTypeArguments, mapper) : localAliasTypeArguments; } - const type = createObjectType(ObjectFlags.Reference, target.symbol) as DeferredTypeReference; + const type = createObjectType(ts.ObjectFlags.Reference, target.symbol) as ts.DeferredTypeReference; type.target = target; type.node = node; type.mapper = mapper; @@ -13495,77 +13027,72 @@ namespace ts { return type; } - function getTypeArguments(type: TypeReference): readonly Type[] { + function getTypeArguments(type: ts.TypeReference): readonly ts.Type[] { if (!type.resolvedTypeArguments) { if (!pushTypeResolution(type, TypeSystemPropertyName.ResolvedTypeArguments)) { - return type.target.localTypeParameters?.map(() => errorType) || emptyArray; + return type.target.localTypeParameters?.map(() => errorType) || ts.emptyArray; } const node = type.node; - const typeArguments = !node ? emptyArray : - node.kind === SyntaxKind.TypeReference ? concatenate(type.target.outerTypeParameters, getEffectiveTypeArguments(node, type.target.localTypeParameters!)) : - node.kind === SyntaxKind.ArrayType ? [getTypeFromTypeNode(node.elementType)] : - map(node.elements, getTypeFromTypeNode); + const typeArguments = !node ? ts.emptyArray : + node.kind === ts.SyntaxKind.TypeReference ? ts.concatenate(type.target.outerTypeParameters, getEffectiveTypeArguments(node, type.target.localTypeParameters!)) : + node.kind === ts.SyntaxKind.ArrayType ? [getTypeFromTypeNode(node.elementType)] : + ts.map(node.elements, getTypeFromTypeNode); if (popTypeResolution()) { type.resolvedTypeArguments = type.mapper ? instantiateTypes(typeArguments, type.mapper) : typeArguments; } else { - type.resolvedTypeArguments = type.target.localTypeParameters?.map(() => errorType) || emptyArray; - error( - type.node || currentNode, - type.target.symbol ? Diagnostics.Type_arguments_for_0_circularly_reference_themselves : Diagnostics.Tuple_type_arguments_circularly_reference_themselves, - type.target.symbol && symbolToString(type.target.symbol) - ); + type.resolvedTypeArguments = type.target.localTypeParameters?.map(() => errorType) || ts.emptyArray; + error(type.node || currentNode, type.target.symbol ? ts.Diagnostics.Type_arguments_for_0_circularly_reference_themselves : ts.Diagnostics.Tuple_type_arguments_circularly_reference_themselves, type.target.symbol && symbolToString(type.target.symbol)); } } return type.resolvedTypeArguments; } - function getTypeReferenceArity(type: TypeReference): number { - return length(type.target.typeParameters); + function getTypeReferenceArity(type: ts.TypeReference): number { + return ts.length(type.target.typeParameters); } /** * Get type from type-reference that reference to class or interface */ - function getTypeFromClassOrInterfaceReference(node: NodeWithTypeArguments, symbol: Symbol): Type { - const type = getDeclaredTypeOfSymbol(getMergedSymbol(symbol)) as InterfaceType; + function getTypeFromClassOrInterfaceReference(node: ts.NodeWithTypeArguments, symbol: ts.Symbol): ts.Type { + const type = getDeclaredTypeOfSymbol(getMergedSymbol(symbol)) as ts.InterfaceType; const typeParameters = type.localTypeParameters; if (typeParameters) { - const numTypeArguments = length(node.typeArguments); + const numTypeArguments = ts.length(node.typeArguments); const minTypeArgumentCount = getMinTypeArgumentCount(typeParameters); - const isJs = isInJSFile(node); + const isJs = ts.isInJSFile(node); const isJsImplicitAny = !noImplicitAny && isJs; if (!isJsImplicitAny && (numTypeArguments < minTypeArgumentCount || numTypeArguments > typeParameters.length)) { - const missingAugmentsTag = isJs && isExpressionWithTypeArguments(node) && !isJSDocAugmentsTag(node.parent); + const missingAugmentsTag = isJs && ts.isExpressionWithTypeArguments(node) && !ts.isJSDocAugmentsTag(node.parent); const diag = minTypeArgumentCount === typeParameters.length ? missingAugmentsTag ? - Diagnostics.Expected_0_type_arguments_provide_these_with_an_extends_tag : - Diagnostics.Generic_type_0_requires_1_type_argument_s : + ts.Diagnostics.Expected_0_type_arguments_provide_these_with_an_extends_tag : + ts.Diagnostics.Generic_type_0_requires_1_type_argument_s : missingAugmentsTag ? - Diagnostics.Expected_0_1_type_arguments_provide_these_with_an_extends_tag : - Diagnostics.Generic_type_0_requires_between_1_and_2_type_arguments; - - const typeStr = typeToString(type, /*enclosingDeclaration*/ undefined, TypeFormatFlags.WriteArrayAsGenericType); + ts.Diagnostics.Expected_0_1_type_arguments_provide_these_with_an_extends_tag : + ts.Diagnostics.Generic_type_0_requires_between_1_and_2_type_arguments; + const typeStr = typeToString(type, /*enclosingDeclaration*/ undefined, ts.TypeFormatFlags.WriteArrayAsGenericType); error(node, diag, typeStr, minTypeArgumentCount, typeParameters.length); if (!isJs) { // TODO: Adopt same permissive behavior in TS as in JS to reduce follow-on editing experience failures (requires editing fillMissingTypeArguments) return errorType; } } - if (node.kind === SyntaxKind.TypeReference && isDeferredTypeReferenceNode(node as TypeReferenceNode, length(node.typeArguments) !== typeParameters.length)) { - return createDeferredTypeReference(type as GenericType, node as TypeReferenceNode, /*mapper*/ undefined); + if (node.kind === ts.SyntaxKind.TypeReference && isDeferredTypeReferenceNode(node as ts.TypeReferenceNode, ts.length(node.typeArguments) !== typeParameters.length)) { + return createDeferredTypeReference(type as ts.GenericType, node as ts.TypeReferenceNode, /*mapper*/ undefined); } // In a type reference, the outer type parameters of the referenced class or interface are automatically // supplied as type arguments and the type reference only specifies arguments for the local type parameters // of the class or interface. - const typeArguments = concatenate(type.outerTypeParameters, fillMissingTypeArguments(typeArgumentsFromTypeReferenceNode(node), typeParameters, minTypeArgumentCount, isJs)); - return createTypeReference(type as GenericType, typeArguments); + const typeArguments = ts.concatenate(type.outerTypeParameters, fillMissingTypeArguments(typeArgumentsFromTypeReferenceNode(node), typeParameters, minTypeArgumentCount, isJs)); + return createTypeReference(type as ts.GenericType, typeArguments); } return checkNoTypeArguments(node, symbol) ? type : errorType; } - function getTypeAliasInstantiation(symbol: Symbol, typeArguments: readonly Type[] | undefined, aliasSymbol?: Symbol, aliasTypeArguments?: readonly Type[]): Type { + function getTypeAliasInstantiation(symbol: ts.Symbol, typeArguments: readonly ts.Type[] | undefined, aliasSymbol?: ts.Symbol, aliasTypeArguments?: readonly ts.Type[]): ts.Type { const type = getDeclaredTypeOfSymbol(symbol); if (type === intrinsicMarkerType && intrinsicTypeKinds.has(symbol.escapedName as string) && typeArguments && typeArguments.length === 1) { return getStringMappingType(symbol, typeArguments[0]); @@ -13575,9 +13102,7 @@ namespace ts { const id = getTypeListId(typeArguments) + getAliasId(aliasSymbol, aliasTypeArguments); let instantiation = links.instantiations!.get(id); if (!instantiation) { - links.instantiations!.set(id, instantiation = instantiateTypeWithAlias(type, - createTypeMapper(typeParameters, fillMissingTypeArguments(typeArguments, typeParameters, getMinTypeArgumentCount(typeParameters), isInJSFile(symbol.valueDeclaration))), - aliasSymbol, aliasTypeArguments)); + links.instantiations!.set(id, instantiation = instantiateTypeWithAlias(type, createTypeMapper(typeParameters, fillMissingTypeArguments(typeArguments, typeParameters, getMinTypeArgumentCount(typeParameters), ts.isInJSFile(symbol.valueDeclaration))), aliasSymbol, aliasTypeArguments)); } return instantiation; } @@ -13587,13 +13112,13 @@ namespace ts { * references to the type parameters of the alias. We replace those with the actual type arguments by instantiating the * declared type. Instantiations are cached using the type identities of the type arguments as the key. */ - function getTypeFromTypeAliasReference(node: NodeWithTypeArguments, symbol: Symbol): Type { - if (getCheckFlags(symbol) & CheckFlags.Unresolved) { + function getTypeFromTypeAliasReference(node: ts.NodeWithTypeArguments, symbol: ts.Symbol): ts.Type { + if (ts.getCheckFlags(symbol) & ts.CheckFlags.Unresolved) { const typeArguments = typeArgumentsFromTypeReferenceNode(node); const id = getAliasId(symbol, typeArguments); let errorType = errorTypes.get(id); if (!errorType) { - errorType = createIntrinsicType(TypeFlags.Any, "error"); + errorType = createIntrinsicType(ts.TypeFlags.Any, "error"); errorType.aliasSymbol = symbol; errorType.aliasTypeArguments = typeArguments; errorTypes.set(id, errorType); @@ -13603,16 +13128,12 @@ namespace ts { const type = getDeclaredTypeOfSymbol(symbol); const typeParameters = getSymbolLinks(symbol).typeParameters; if (typeParameters) { - const numTypeArguments = length(node.typeArguments); + const numTypeArguments = ts.length(node.typeArguments); const minTypeArgumentCount = getMinTypeArgumentCount(typeParameters); if (numTypeArguments < minTypeArgumentCount || numTypeArguments > typeParameters.length) { - error(node, - minTypeArgumentCount === typeParameters.length ? - Diagnostics.Generic_type_0_requires_1_type_argument_s : - Diagnostics.Generic_type_0_requires_between_1_and_2_type_arguments, - symbolToString(symbol), - minTypeArgumentCount, - typeParameters.length); + error(node, minTypeArgumentCount === typeParameters.length ? + ts.Diagnostics.Generic_type_0_requires_1_type_argument_s : + ts.Diagnostics.Generic_type_0_requires_between_1_and_2_type_arguments, symbolToString(symbol), minTypeArgumentCount, typeParameters.length); return errorType; } // We refrain from associating a local type alias with an instantiation of a top-level type alias @@ -13626,20 +13147,20 @@ namespace ts { return checkNoTypeArguments(node, symbol) ? type : errorType; } - function isLocalTypeAlias(symbol: Symbol) { - const declaration = symbol.declarations?.find(isTypeAlias); - return !!(declaration && getContainingFunction(declaration)); + function isLocalTypeAlias(symbol: ts.Symbol) { + const declaration = symbol.declarations?.find(ts.isTypeAlias); + return !!(declaration && ts.getContainingFunction(declaration)); } - function getTypeReferenceName(node: TypeReferenceType): EntityNameOrEntityNameExpression | undefined { + function getTypeReferenceName(node: ts.TypeReferenceType): ts.EntityNameOrEntityNameExpression | undefined { switch (node.kind) { - case SyntaxKind.TypeReference: + case ts.SyntaxKind.TypeReference: return node.typeName; - case SyntaxKind.ExpressionWithTypeArguments: + case ts.SyntaxKind.ExpressionWithTypeArguments: // We only support expressions that are simple qualified names. For other // expressions this produces undefined. const expr = node.expression; - if (isEntityNameExpression(expr)) { + if (ts.isEntityNameExpression(expr)) { return expr; } // fall through; @@ -13648,23 +13169,23 @@ namespace ts { return undefined; } - function getSymbolPath(symbol: Symbol): string { + function getSymbolPath(symbol: ts.Symbol): string { return symbol.parent ? `${getSymbolPath(symbol.parent)}.${symbol.escapedName}` : symbol.escapedName as string; } - function getUnresolvedSymbolForEntityName(name: EntityNameOrEntityNameExpression) { - const identifier = name.kind === SyntaxKind.QualifiedName ? name.right : - name.kind === SyntaxKind.PropertyAccessExpression ? name.name : + function getUnresolvedSymbolForEntityName(name: ts.EntityNameOrEntityNameExpression) { + const identifier = name.kind === ts.SyntaxKind.QualifiedName ? name.right : + name.kind === ts.SyntaxKind.PropertyAccessExpression ? name.name : name; const text = identifier.escapedText; if (text) { - const parentSymbol = name.kind === SyntaxKind.QualifiedName ? getUnresolvedSymbolForEntityName(name.left) : - name.kind === SyntaxKind.PropertyAccessExpression ? getUnresolvedSymbolForEntityName(name.expression) : + const parentSymbol = name.kind === ts.SyntaxKind.QualifiedName ? getUnresolvedSymbolForEntityName(name.left) : + name.kind === ts.SyntaxKind.PropertyAccessExpression ? getUnresolvedSymbolForEntityName(name.expression) : undefined; const path = parentSymbol ? `${getSymbolPath(parentSymbol)}.${text}` : text as string; let result = unresolvedSymbols.get(path); if (!result) { - unresolvedSymbols.set(path, result = createSymbol(SymbolFlags.TypeAlias, text, CheckFlags.Unresolved)); + unresolvedSymbols.set(path, result = createSymbol(ts.SymbolFlags.TypeAlias, text, ts.CheckFlags.Unresolved)); result.parent = parentSymbol; result.declaredType = unresolvedType; } @@ -13673,7 +13194,7 @@ namespace ts { return unknownSymbol; } - function resolveTypeReferenceName(typeReference: TypeReferenceType, meaning: SymbolFlags, ignoreErrors?: boolean) { + function resolveTypeReferenceName(typeReference: ts.TypeReferenceType, meaning: ts.SymbolFlags, ignoreErrors?: boolean) { const name = getTypeReferenceName(typeReference); if (!name) { return unknownSymbol; @@ -13683,15 +13204,15 @@ namespace ts { ignoreErrors ? unknownSymbol : getUnresolvedSymbolForEntityName(name); } - function getTypeReferenceType(node: NodeWithTypeArguments, symbol: Symbol): Type { + function getTypeReferenceType(node: ts.NodeWithTypeArguments, symbol: ts.Symbol): ts.Type { if (symbol === unknownSymbol) { return errorType; } symbol = getExpandoSymbol(symbol) || symbol; - if (symbol.flags & (SymbolFlags.Class | SymbolFlags.Interface)) { + if (symbol.flags & (ts.SymbolFlags.Class | ts.SymbolFlags.Interface)) { return getTypeFromClassOrInterfaceReference(node, symbol); } - if (symbol.flags & SymbolFlags.TypeAlias) { + if (symbol.flags & ts.SymbolFlags.TypeAlias) { return getTypeFromTypeAliasReference(node, symbol); } // Get type from reference to named type that cannot be generic (enum or type parameter) @@ -13699,14 +13220,14 @@ namespace ts { if (res) { return checkNoTypeArguments(node, symbol) ? getRegularTypeOfLiteralType(res) : errorType; } - if (symbol.flags & SymbolFlags.Value && isJSDocTypeReference(node)) { + if (symbol.flags & ts.SymbolFlags.Value && isJSDocTypeReference(node)) { const jsdocType = getTypeFromJSDocValueReference(node, symbol); if (jsdocType) { return jsdocType; } else { // Resolve the type reference as a Type for the purpose of reporting errors. - resolveTypeReferenceName(node, SymbolFlags.Type); + resolveTypeReferenceName(node, ts.SymbolFlags.Type); return getTypeOfSymbol(symbol); } } @@ -13717,13 +13238,13 @@ namespace ts { * A JSdoc TypeReference may be to a value, but resolve it as a type anyway. * Example: import('./b').ConstructorFunction */ - function getTypeFromJSDocValueReference(node: NodeWithTypeArguments, symbol: Symbol): Type | undefined { + function getTypeFromJSDocValueReference(node: ts.NodeWithTypeArguments, symbol: ts.Symbol): ts.Type | undefined { const links = getNodeLinks(node); if (!links.resolvedJSDocType) { const valueType = getTypeOfSymbol(symbol); let typeType = valueType; if (symbol.valueDeclaration) { - const isImportTypeWithQualifier = node.kind === SyntaxKind.ImportType && (node as ImportTypeNode).qualifier; + const isImportTypeWithQualifier = node.kind === ts.SyntaxKind.ImportType && (node as ts.ImportTypeNode).qualifier; // valueType might not have a symbol, eg, {import('./b').STRING_LITERAL} if (valueType.symbol && valueType.symbol !== symbol && isImportTypeWithQualifier) { typeType = getTypeReferenceType(node, valueType.symbol); @@ -13734,8 +13255,8 @@ namespace ts { return links.resolvedJSDocType; } - function getSubstitutionType(baseType: Type, substitute: Type) { - if (substitute.flags & TypeFlags.AnyOrUnknown || substitute === baseType) { + function getSubstitutionType(baseType: ts.Type, substitute: ts.Type) { + if (substitute.flags & ts.TypeFlags.AnyOrUnknown || substitute === baseType) { return baseType; } const id = `${getTypeId(baseType)}>${getTypeId(substitute)}`; @@ -13743,74 +13264,74 @@ namespace ts { if (cached) { return cached; } - const result = createType(TypeFlags.Substitution) as SubstitutionType; + const result = createType(ts.TypeFlags.Substitution) as ts.SubstitutionType; result.baseType = baseType; result.substitute = substitute; substitutionTypes.set(id, result); return result; } - function isUnaryTupleTypeNode(node: TypeNode) { - return node.kind === SyntaxKind.TupleType && (node as TupleTypeNode).elements.length === 1; + function isUnaryTupleTypeNode(node: ts.TypeNode) { + return node.kind === ts.SyntaxKind.TupleType && (node as ts.TupleTypeNode).elements.length === 1; } - function getImpliedConstraint(type: Type, checkNode: TypeNode, extendsNode: TypeNode): Type | undefined { - return isUnaryTupleTypeNode(checkNode) && isUnaryTupleTypeNode(extendsNode) ? getImpliedConstraint(type, (checkNode as TupleTypeNode).elements[0], (extendsNode as TupleTypeNode).elements[0]) : + function getImpliedConstraint(type: ts.Type, checkNode: ts.TypeNode, extendsNode: ts.TypeNode): ts.Type | undefined { + return isUnaryTupleTypeNode(checkNode) && isUnaryTupleTypeNode(extendsNode) ? getImpliedConstraint(type, (checkNode as ts.TupleTypeNode).elements[0], (extendsNode as ts.TupleTypeNode).elements[0]) : getActualTypeVariable(getTypeFromTypeNode(checkNode)) === getActualTypeVariable(type) ? getTypeFromTypeNode(extendsNode) : undefined; } - function getConditionalFlowTypeOfType(type: Type, node: Node) { - let constraints: Type[] | undefined; + function getConditionalFlowTypeOfType(type: ts.Type, node: ts.Node) { + let constraints: ts.Type[] | undefined; let covariant = true; - while (node && !isStatement(node) && node.kind !== SyntaxKind.JSDoc) { + while (node && !ts.isStatement(node) && node.kind !== ts.SyntaxKind.JSDoc) { const parent = node.parent; // only consider variance flipped by parameter locations - `keyof` types would usually be considered variance inverting, but // often get used in indexed accesses where they behave sortof invariantly, but our checking is lax - if (parent.kind === SyntaxKind.Parameter) { + if (parent.kind === ts.SyntaxKind.Parameter) { covariant = !covariant; } // Always substitute on type parameters, regardless of variance, since even // in contravariant positions, they may rely on substituted constraints to be valid - if ((covariant || type.flags & TypeFlags.TypeVariable) && parent.kind === SyntaxKind.ConditionalType && node === (parent as ConditionalTypeNode).trueType) { - const constraint = getImpliedConstraint(type, (parent as ConditionalTypeNode).checkType, (parent as ConditionalTypeNode).extendsType); + if ((covariant || type.flags & ts.TypeFlags.TypeVariable) && parent.kind === ts.SyntaxKind.ConditionalType && node === (parent as ts.ConditionalTypeNode).trueType) { + const constraint = getImpliedConstraint(type, (parent as ts.ConditionalTypeNode).checkType, (parent as ts.ConditionalTypeNode).extendsType); if (constraint) { - constraints = append(constraints, constraint); + constraints = ts.append(constraints, constraint); } } // Given a homomorphic mapped type { [K in keyof T]: XXX }, where T is constrained to an array or tuple type, in the // template type XXX, K has an added constraint of number | `${number}`. - else if (type.flags & TypeFlags.TypeParameter && parent.kind === SyntaxKind.MappedType && node === (parent as MappedTypeNode).type) { - const mappedType = getTypeFromTypeNode(parent as TypeNode) as MappedType; + else if (type.flags & ts.TypeFlags.TypeParameter && parent.kind === ts.SyntaxKind.MappedType && node === (parent as ts.MappedTypeNode).type) { + const mappedType = getTypeFromTypeNode(parent as ts.TypeNode) as ts.MappedType; if (getTypeParameterFromMappedType(mappedType) === getActualTypeVariable(type)) { const typeParameter = getHomomorphicTypeVariable(mappedType); if (typeParameter) { const constraint = getConstraintOfTypeParameter(typeParameter); if (constraint && everyType(constraint, isArrayOrTupleType)) { - constraints = append(constraints, getUnionType([numberType, numericStringType])); + constraints = ts.append(constraints, getUnionType([numberType, numericStringType])); } } } } node = parent; } - return constraints ? getSubstitutionType(type, getIntersectionType(append(constraints, type))) : type; + return constraints ? getSubstitutionType(type, getIntersectionType(ts.append(constraints, type))) : type; } - function isJSDocTypeReference(node: Node): node is TypeReferenceNode { - return !!(node.flags & NodeFlags.JSDoc) && (node.kind === SyntaxKind.TypeReference || node.kind === SyntaxKind.ImportType); + function isJSDocTypeReference(node: ts.Node): node is ts.TypeReferenceNode { + return !!(node.flags & ts.NodeFlags.JSDoc) && (node.kind === ts.SyntaxKind.TypeReference || node.kind === ts.SyntaxKind.ImportType); } - function checkNoTypeArguments(node: NodeWithTypeArguments, symbol?: Symbol) { + function checkNoTypeArguments(node: ts.NodeWithTypeArguments, symbol?: ts.Symbol) { if (node.typeArguments) { - error(node, Diagnostics.Type_0_is_not_generic, symbol ? symbolToString(symbol) : (node as TypeReferenceNode).typeName ? declarationNameToString((node as TypeReferenceNode).typeName) : anon); + error(node, ts.Diagnostics.Type_0_is_not_generic, symbol ? symbolToString(symbol) : (node as ts.TypeReferenceNode).typeName ? ts.declarationNameToString((node as ts.TypeReferenceNode).typeName) : anon); return false; } return true; } - function getIntendedTypeFromJSDocTypeReference(node: TypeReferenceNode): Type | undefined { - if (isIdentifier(node.typeName)) { + function getIntendedTypeFromJSDocTypeReference(node: ts.TypeReferenceNode): ts.Type | undefined { + if (ts.isIdentifier(node.typeName)) { const typeArgs = node.typeArguments; switch (node.typeName.escapedText) { case "String": @@ -13841,11 +13362,11 @@ namespace ts { return (!typeArgs || !typeArgs.length) && !noImplicitAny ? createPromiseType(anyType) : undefined; case "Object": if (typeArgs && typeArgs.length === 2) { - if (isJSDocIndexSignature(node)) { + if (ts.isJSDocIndexSignature(node)) { const indexed = getTypeFromTypeNode(typeArgs[0]); const target = getTypeFromTypeNode(typeArgs[1]); - const indexInfo = indexed === stringType || indexed === numberType ? [createIndexInfo(indexed, target, /*isReadonly*/ false)] : emptyArray; - return createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, indexInfo); + const indexInfo = indexed === stringType || indexed === numberType ? [createIndexInfo(indexed, target, /*isReadonly*/ false)] : ts.emptyArray; + return createAnonymousType(undefined, emptySymbols, ts.emptyArray, ts.emptyArray, indexInfo); } return anyType; } @@ -13855,28 +13376,28 @@ namespace ts { } } - function getTypeFromJSDocNullableTypeNode(node: JSDocNullableType) { + function getTypeFromJSDocNullableTypeNode(node: ts.JSDocNullableType) { const type = getTypeFromTypeNode(node.type); - return strictNullChecks ? getNullableType(type, TypeFlags.Null) : type; + return strictNullChecks ? getNullableType(type, ts.TypeFlags.Null) : type; } - function getTypeFromTypeReference(node: TypeReferenceType): Type { + function getTypeFromTypeReference(node: ts.TypeReferenceType): ts.Type { const links = getNodeLinks(node); if (!links.resolvedType) { // handle LS queries on the `const` in `x as const` by resolving to the type of `x` - if (isConstTypeReference(node) && isAssertionExpression(node.parent)) { + if (ts.isConstTypeReference(node) && ts.isAssertionExpression(node.parent)) { links.resolvedSymbol = unknownSymbol; return links.resolvedType = checkExpressionCached(node.parent.expression); } - let symbol: Symbol | undefined; - let type: Type | undefined; - const meaning = SymbolFlags.Type; + let symbol: ts.Symbol | undefined; + let type: ts.Type | undefined; + const meaning = ts.SymbolFlags.Type; if (isJSDocTypeReference(node)) { type = getIntendedTypeFromJSDocTypeReference(node); if (!type) { symbol = resolveTypeReferenceName(node, meaning, /*ignoreErrors*/ true); if (symbol === unknownSymbol) { - symbol = resolveTypeReferenceName(node, meaning | SymbolFlags.Value); + symbol = resolveTypeReferenceName(node, meaning | ts.SymbolFlags.Value); } else { resolveTypeReferenceName(node, meaning); // Resolve again to mark errors, if any @@ -13896,11 +13417,11 @@ namespace ts { return links.resolvedType; } - function typeArgumentsFromTypeReferenceNode(node: NodeWithTypeArguments): Type[] | undefined { - return map(node.typeArguments, getTypeFromTypeNode); + function typeArgumentsFromTypeReferenceNode(node: ts.NodeWithTypeArguments): ts.Type[] | undefined { + return ts.map(node.typeArguments, getTypeFromTypeNode); } - function getTypeFromTypeQueryNode(node: TypeQueryNode): Type { + function getTypeFromTypeQueryNode(node: ts.TypeQueryNode): ts.Type { const links = getNodeLinks(node); if (!links.resolvedType) { // TypeScript 1.0 spec (April 2014): 3.6.3 @@ -13913,16 +13434,15 @@ namespace ts { return links.resolvedType; } - function getTypeOfGlobalSymbol(symbol: Symbol | undefined, arity: number): ObjectType { - - function getTypeDeclaration(symbol: Symbol): Declaration | undefined { + function getTypeOfGlobalSymbol(symbol: ts.Symbol | undefined, arity: number): ts.ObjectType { + function getTypeDeclaration(symbol: ts.Symbol): ts.Declaration | undefined { const declarations = symbol.declarations; if (declarations) { for (const declaration of declarations) { switch (declaration.kind) { - case SyntaxKind.ClassDeclaration: - case SyntaxKind.InterfaceDeclaration: - case SyntaxKind.EnumDeclaration: + case ts.SyntaxKind.ClassDeclaration: + case ts.SyntaxKind.InterfaceDeclaration: + case ts.SyntaxKind.EnumDeclaration: return declaration; } } @@ -13933,262 +13453,261 @@ namespace ts { return arity ? emptyGenericType : emptyObjectType; } const type = getDeclaredTypeOfSymbol(symbol); - if (!(type.flags & TypeFlags.Object)) { - error(getTypeDeclaration(symbol), Diagnostics.Global_type_0_must_be_a_class_or_interface_type, symbolName(symbol)); + if (!(type.flags & ts.TypeFlags.Object)) { + error(getTypeDeclaration(symbol), ts.Diagnostics.Global_type_0_must_be_a_class_or_interface_type, ts.symbolName(symbol)); return arity ? emptyGenericType : emptyObjectType; } - if (length((type as InterfaceType).typeParameters) !== arity) { - error(getTypeDeclaration(symbol), Diagnostics.Global_type_0_must_have_1_type_parameter_s, symbolName(symbol), arity); + if (ts.length((type as ts.InterfaceType).typeParameters) !== arity) { + error(getTypeDeclaration(symbol), ts.Diagnostics.Global_type_0_must_have_1_type_parameter_s, ts.symbolName(symbol), arity); return arity ? emptyGenericType : emptyObjectType; } - return type as ObjectType; + return type as ts.ObjectType; } - function getGlobalValueSymbol(name: __String, reportErrors: boolean): Symbol | undefined { - return getGlobalSymbol(name, SymbolFlags.Value, reportErrors ? Diagnostics.Cannot_find_global_value_0 : undefined); + function getGlobalValueSymbol(name: ts.__String, reportErrors: boolean): ts.Symbol | undefined { + return getGlobalSymbol(name, ts.SymbolFlags.Value, reportErrors ? ts.Diagnostics.Cannot_find_global_value_0 : undefined); } - function getGlobalTypeSymbol(name: __String, reportErrors: boolean): Symbol | undefined { - return getGlobalSymbol(name, SymbolFlags.Type, reportErrors ? Diagnostics.Cannot_find_global_type_0 : undefined); + function getGlobalTypeSymbol(name: ts.__String, reportErrors: boolean): ts.Symbol | undefined { + return getGlobalSymbol(name, ts.SymbolFlags.Type, reportErrors ? ts.Diagnostics.Cannot_find_global_type_0 : undefined); } - function getGlobalTypeAliasSymbol(name: __String, arity: number, reportErrors: boolean): Symbol | undefined { - const symbol = getGlobalSymbol(name, SymbolFlags.Type, reportErrors ? Diagnostics.Cannot_find_global_type_0 : undefined); + function getGlobalTypeAliasSymbol(name: ts.__String, arity: number, reportErrors: boolean): ts.Symbol | undefined { + const symbol = getGlobalSymbol(name, ts.SymbolFlags.Type, reportErrors ? ts.Diagnostics.Cannot_find_global_type_0 : undefined); if (symbol) { // Resolve the declared type of the symbol. This resolves type parameters for the type // alias so that we can check arity. getDeclaredTypeOfSymbol(symbol); - if (length(getSymbolLinks(symbol).typeParameters) !== arity) { - const decl = symbol.declarations && find(symbol.declarations, isTypeAliasDeclaration); - error(decl, Diagnostics.Global_type_0_must_have_1_type_parameter_s, symbolName(symbol), arity); + if (ts.length(getSymbolLinks(symbol).typeParameters) !== arity) { + const decl = symbol.declarations && ts.find(symbol.declarations, ts.isTypeAliasDeclaration); + error(decl, ts.Diagnostics.Global_type_0_must_have_1_type_parameter_s, ts.symbolName(symbol), arity); return undefined; } } return symbol; } - function getGlobalSymbol(name: __String, meaning: SymbolFlags, diagnostic: DiagnosticMessage | undefined): Symbol | undefined { + function getGlobalSymbol(name: ts.__String, meaning: ts.SymbolFlags, diagnostic: ts.DiagnosticMessage | undefined): ts.Symbol | undefined { // Don't track references for global symbols anyway, so value if `isReference` is arbitrary return resolveName(undefined, name, meaning, diagnostic, name, /*isUse*/ false, /*excludeGlobals*/ false, /*getSpellingSuggestions*/ false); } - function getGlobalType(name: __String, arity: 0, reportErrors: true): ObjectType; - function getGlobalType(name: __String, arity: 0, reportErrors: boolean): ObjectType | undefined; - function getGlobalType(name: __String, arity: number, reportErrors: true): GenericType; - function getGlobalType(name: __String, arity: number, reportErrors: boolean): GenericType | undefined; - function getGlobalType(name: __String, arity: number, reportErrors: boolean): ObjectType | undefined { + function getGlobalType(name: ts.__String, arity: 0, reportErrors: true): ts.ObjectType; + function getGlobalType(name: ts.__String, arity: 0, reportErrors: boolean): ts.ObjectType | undefined; + function getGlobalType(name: ts.__String, arity: number, reportErrors: true): ts.GenericType; + function getGlobalType(name: ts.__String, arity: number, reportErrors: boolean): ts.GenericType | undefined; + function getGlobalType(name: ts.__String, arity: number, reportErrors: boolean): ts.ObjectType | undefined { const symbol = getGlobalTypeSymbol(name, reportErrors); return symbol || reportErrors ? getTypeOfGlobalSymbol(symbol, arity) : undefined; } function getGlobalTypedPropertyDescriptorType() { // We always report an error, so store a result in the event we could not resolve the symbol to prevent reporting it multiple times - return deferredGlobalTypedPropertyDescriptorType ||= getGlobalType("TypedPropertyDescriptor" as __String, /*arity*/ 1, /*reportErrors*/ true) || emptyGenericType; + return deferredGlobalTypedPropertyDescriptorType ||= getGlobalType("TypedPropertyDescriptor" as ts.__String, /*arity*/ 1, /*reportErrors*/ true) || emptyGenericType; } function getGlobalTemplateStringsArrayType() { // We always report an error, so store a result in the event we could not resolve the symbol to prevent reporting it multiple times - return deferredGlobalTemplateStringsArrayType ||= getGlobalType("TemplateStringsArray" as __String, /*arity*/ 0, /*reportErrors*/ true) || emptyObjectType; + return deferredGlobalTemplateStringsArrayType ||= getGlobalType("TemplateStringsArray" as ts.__String, /*arity*/ 0, /*reportErrors*/ true) || emptyObjectType; } function getGlobalImportMetaType() { // We always report an error, so store a result in the event we could not resolve the symbol to prevent reporting it multiple times - return deferredGlobalImportMetaType ||= getGlobalType("ImportMeta" as __String, /*arity*/ 0, /*reportErrors*/ true) || emptyObjectType; + return deferredGlobalImportMetaType ||= getGlobalType("ImportMeta" as ts.__String, /*arity*/ 0, /*reportErrors*/ true) || emptyObjectType; } function getGlobalImportMetaExpressionType() { if (!deferredGlobalImportMetaExpressionType) { // Create a synthetic type `ImportMetaExpression { meta: MetaProperty }` - const symbol = createSymbol(SymbolFlags.None, "ImportMetaExpression" as __String); + const symbol = createSymbol(ts.SymbolFlags.None, "ImportMetaExpression" as ts.__String); const importMetaType = getGlobalImportMetaType(); - const metaPropertySymbol = createSymbol(SymbolFlags.Property, "meta" as __String, CheckFlags.Readonly); + const metaPropertySymbol = createSymbol(ts.SymbolFlags.Property, "meta" as ts.__String, ts.CheckFlags.Readonly); metaPropertySymbol.parent = symbol; metaPropertySymbol.type = importMetaType; - const members = createSymbolTable([metaPropertySymbol]); + const members = ts.createSymbolTable([metaPropertySymbol]); symbol.members = members; - deferredGlobalImportMetaExpressionType = createAnonymousType(symbol, members, emptyArray, emptyArray, emptyArray); + deferredGlobalImportMetaExpressionType = createAnonymousType(symbol, members, ts.emptyArray, ts.emptyArray, ts.emptyArray); } return deferredGlobalImportMetaExpressionType; } function getGlobalImportCallOptionsType(reportErrors: boolean) { - return (deferredGlobalImportCallOptionsType ||= getGlobalType("ImportCallOptions" as __String, /*arity*/ 0, reportErrors)) || emptyObjectType; + return (deferredGlobalImportCallOptionsType ||= getGlobalType("ImportCallOptions" as ts.__String, /*arity*/ 0, reportErrors)) || emptyObjectType; } - function getGlobalESSymbolConstructorSymbol(reportErrors: boolean): Symbol | undefined { - return deferredGlobalESSymbolConstructorSymbol ||= getGlobalValueSymbol("Symbol" as __String, reportErrors); + function getGlobalESSymbolConstructorSymbol(reportErrors: boolean): ts.Symbol | undefined { + return deferredGlobalESSymbolConstructorSymbol ||= getGlobalValueSymbol("Symbol" as ts.__String, reportErrors); } - function getGlobalESSymbolConstructorTypeSymbol(reportErrors: boolean): Symbol | undefined { - return deferredGlobalESSymbolConstructorTypeSymbol ||= getGlobalTypeSymbol("SymbolConstructor" as __String, reportErrors); + function getGlobalESSymbolConstructorTypeSymbol(reportErrors: boolean): ts.Symbol | undefined { + return deferredGlobalESSymbolConstructorTypeSymbol ||= getGlobalTypeSymbol("SymbolConstructor" as ts.__String, reportErrors); } function getGlobalESSymbolType(reportErrors: boolean) { - return (deferredGlobalESSymbolType ||= getGlobalType("Symbol" as __String, /*arity*/ 0, reportErrors)) || emptyObjectType; + return (deferredGlobalESSymbolType ||= getGlobalType("Symbol" as ts.__String, /*arity*/ 0, reportErrors)) || emptyObjectType; } function getGlobalPromiseType(reportErrors: boolean) { - return (deferredGlobalPromiseType ||= getGlobalType("Promise" as __String, /*arity*/ 1, reportErrors)) || emptyGenericType; + return (deferredGlobalPromiseType ||= getGlobalType("Promise" as ts.__String, /*arity*/ 1, reportErrors)) || emptyGenericType; } function getGlobalPromiseLikeType(reportErrors: boolean) { - return (deferredGlobalPromiseLikeType ||= getGlobalType("PromiseLike" as __String, /*arity*/ 1, reportErrors)) || emptyGenericType; + return (deferredGlobalPromiseLikeType ||= getGlobalType("PromiseLike" as ts.__String, /*arity*/ 1, reportErrors)) || emptyGenericType; } - function getGlobalPromiseConstructorSymbol(reportErrors: boolean): Symbol | undefined { - return deferredGlobalPromiseConstructorSymbol ||= getGlobalValueSymbol("Promise" as __String, reportErrors); + function getGlobalPromiseConstructorSymbol(reportErrors: boolean): ts.Symbol | undefined { + return deferredGlobalPromiseConstructorSymbol ||= getGlobalValueSymbol("Promise" as ts.__String, reportErrors); } function getGlobalPromiseConstructorLikeType(reportErrors: boolean) { - return (deferredGlobalPromiseConstructorLikeType ||= getGlobalType("PromiseConstructorLike" as __String, /*arity*/ 0, reportErrors)) || emptyObjectType; + return (deferredGlobalPromiseConstructorLikeType ||= getGlobalType("PromiseConstructorLike" as ts.__String, /*arity*/ 0, reportErrors)) || emptyObjectType; } function getGlobalAsyncIterableType(reportErrors: boolean) { - return (deferredGlobalAsyncIterableType ||= getGlobalType("AsyncIterable" as __String, /*arity*/ 1, reportErrors)) || emptyGenericType; + return (deferredGlobalAsyncIterableType ||= getGlobalType("AsyncIterable" as ts.__String, /*arity*/ 1, reportErrors)) || emptyGenericType; } function getGlobalAsyncIteratorType(reportErrors: boolean) { - return (deferredGlobalAsyncIteratorType ||= getGlobalType("AsyncIterator" as __String, /*arity*/ 3, reportErrors)) || emptyGenericType; + return (deferredGlobalAsyncIteratorType ||= getGlobalType("AsyncIterator" as ts.__String, /*arity*/ 3, reportErrors)) || emptyGenericType; } function getGlobalAsyncIterableIteratorType(reportErrors: boolean) { - return (deferredGlobalAsyncIterableIteratorType ||= getGlobalType("AsyncIterableIterator" as __String, /*arity*/ 1, reportErrors)) || emptyGenericType; + return (deferredGlobalAsyncIterableIteratorType ||= getGlobalType("AsyncIterableIterator" as ts.__String, /*arity*/ 1, reportErrors)) || emptyGenericType; } function getGlobalAsyncGeneratorType(reportErrors: boolean) { - return (deferredGlobalAsyncGeneratorType ||= getGlobalType("AsyncGenerator" as __String, /*arity*/ 3, reportErrors)) || emptyGenericType; + return (deferredGlobalAsyncGeneratorType ||= getGlobalType("AsyncGenerator" as ts.__String, /*arity*/ 3, reportErrors)) || emptyGenericType; } function getGlobalIterableType(reportErrors: boolean) { - return (deferredGlobalIterableType ||= getGlobalType("Iterable" as __String, /*arity*/ 1, reportErrors)) || emptyGenericType; + return (deferredGlobalIterableType ||= getGlobalType("Iterable" as ts.__String, /*arity*/ 1, reportErrors)) || emptyGenericType; } function getGlobalIteratorType(reportErrors: boolean) { - return (deferredGlobalIteratorType ||= getGlobalType("Iterator" as __String, /*arity*/ 3, reportErrors)) || emptyGenericType; + return (deferredGlobalIteratorType ||= getGlobalType("Iterator" as ts.__String, /*arity*/ 3, reportErrors)) || emptyGenericType; } function getGlobalIterableIteratorType(reportErrors: boolean) { - return (deferredGlobalIterableIteratorType ||= getGlobalType("IterableIterator" as __String, /*arity*/ 1, reportErrors)) || emptyGenericType; + return (deferredGlobalIterableIteratorType ||= getGlobalType("IterableIterator" as ts.__String, /*arity*/ 1, reportErrors)) || emptyGenericType; } function getGlobalGeneratorType(reportErrors: boolean) { - return (deferredGlobalGeneratorType ||= getGlobalType("Generator" as __String, /*arity*/ 3, reportErrors)) || emptyGenericType; + return (deferredGlobalGeneratorType ||= getGlobalType("Generator" as ts.__String, /*arity*/ 3, reportErrors)) || emptyGenericType; } function getGlobalIteratorYieldResultType(reportErrors: boolean) { - return (deferredGlobalIteratorYieldResultType ||= getGlobalType("IteratorYieldResult" as __String, /*arity*/ 1, reportErrors)) || emptyGenericType; + return (deferredGlobalIteratorYieldResultType ||= getGlobalType("IteratorYieldResult" as ts.__String, /*arity*/ 1, reportErrors)) || emptyGenericType; } function getGlobalIteratorReturnResultType(reportErrors: boolean) { - return (deferredGlobalIteratorReturnResultType ||= getGlobalType("IteratorReturnResult" as __String, /*arity*/ 1, reportErrors)) || emptyGenericType; + return (deferredGlobalIteratorReturnResultType ||= getGlobalType("IteratorReturnResult" as ts.__String, /*arity*/ 1, reportErrors)) || emptyGenericType; } - function getGlobalTypeOrUndefined(name: __String, arity = 0): ObjectType | undefined { - const symbol = getGlobalSymbol(name, SymbolFlags.Type, /*diagnostic*/ undefined); - return symbol && getTypeOfGlobalSymbol(symbol, arity) as GenericType; + function getGlobalTypeOrUndefined(name: ts.__String, arity = 0): ts.ObjectType | undefined { + const symbol = getGlobalSymbol(name, ts.SymbolFlags.Type, /*diagnostic*/ undefined); + return symbol && getTypeOfGlobalSymbol(symbol, arity) as ts.GenericType; } - function getGlobalExtractSymbol(): Symbol | undefined { + function getGlobalExtractSymbol(): ts.Symbol | undefined { // We always report an error, so cache a result in the event we could not resolve the symbol to prevent reporting it multiple times - deferredGlobalExtractSymbol ||= getGlobalTypeAliasSymbol("Extract" as __String, /*arity*/ 2, /*reportErrors*/ true) || unknownSymbol; + deferredGlobalExtractSymbol ||= getGlobalTypeAliasSymbol("Extract" as ts.__String, /*arity*/ 2, /*reportErrors*/ true) || unknownSymbol; return deferredGlobalExtractSymbol === unknownSymbol ? undefined : deferredGlobalExtractSymbol; } - function getGlobalOmitSymbol(): Symbol | undefined { + function getGlobalOmitSymbol(): ts.Symbol | undefined { // We always report an error, so cache a result in the event we could not resolve the symbol to prevent reporting it multiple times - deferredGlobalOmitSymbol ||= getGlobalTypeAliasSymbol("Omit" as __String, /*arity*/ 2, /*reportErrors*/ true) || unknownSymbol; + deferredGlobalOmitSymbol ||= getGlobalTypeAliasSymbol("Omit" as ts.__String, /*arity*/ 2, /*reportErrors*/ true) || unknownSymbol; return deferredGlobalOmitSymbol === unknownSymbol ? undefined : deferredGlobalOmitSymbol; } - function getGlobalAwaitedSymbol(reportErrors: boolean): Symbol | undefined { + function getGlobalAwaitedSymbol(reportErrors: boolean): ts.Symbol | undefined { // Only cache `unknownSymbol` if we are reporting errors so that we don't report the error more than once. - deferredGlobalAwaitedSymbol ||= getGlobalTypeAliasSymbol("Awaited" as __String, /*arity*/ 1, reportErrors) || (reportErrors ? unknownSymbol : undefined); + deferredGlobalAwaitedSymbol ||= getGlobalTypeAliasSymbol("Awaited" as ts.__String, /*arity*/ 1, reportErrors) || (reportErrors ? unknownSymbol : undefined); return deferredGlobalAwaitedSymbol === unknownSymbol ? undefined : deferredGlobalAwaitedSymbol; } function getGlobalBigIntType(reportErrors: boolean) { - return (deferredGlobalBigIntType ||= getGlobalType("BigInt" as __String, /*arity*/ 0, reportErrors)) || emptyObjectType; + return (deferredGlobalBigIntType ||= getGlobalType("BigInt" as ts.__String, /*arity*/ 0, reportErrors)) || emptyObjectType; } /** * Instantiates a global type that is generic with some element type, and returns that instantiation. */ - function createTypeFromGenericGlobalType(genericGlobalType: GenericType, typeArguments: readonly Type[]): ObjectType { + function createTypeFromGenericGlobalType(genericGlobalType: ts.GenericType, typeArguments: readonly ts.Type[]): ts.ObjectType { return genericGlobalType !== emptyGenericType ? createTypeReference(genericGlobalType, typeArguments) : emptyObjectType; } - function createTypedPropertyDescriptorType(propertyType: Type): Type { + function createTypedPropertyDescriptorType(propertyType: ts.Type): ts.Type { return createTypeFromGenericGlobalType(getGlobalTypedPropertyDescriptorType(), [propertyType]); } - function createIterableType(iteratedType: Type): Type { + function createIterableType(iteratedType: ts.Type): ts.Type { return createTypeFromGenericGlobalType(getGlobalIterableType(/*reportErrors*/ true), [iteratedType]); } - function createArrayType(elementType: Type, readonly?: boolean): ObjectType { + function createArrayType(elementType: ts.Type, readonly?: boolean): ts.ObjectType { return createTypeFromGenericGlobalType(readonly ? globalReadonlyArrayType : globalArrayType, [elementType]); } - function getTupleElementFlags(node: TypeNode) { + function getTupleElementFlags(node: ts.TypeNode) { switch (node.kind) { - case SyntaxKind.OptionalType: - return ElementFlags.Optional; - case SyntaxKind.RestType: - return getRestTypeElementFlags(node as RestTypeNode); - case SyntaxKind.NamedTupleMember: - return (node as NamedTupleMember).questionToken ? ElementFlags.Optional : - (node as NamedTupleMember).dotDotDotToken ? getRestTypeElementFlags(node as NamedTupleMember) : - ElementFlags.Required; + case ts.SyntaxKind.OptionalType: + return ts.ElementFlags.Optional; + case ts.SyntaxKind.RestType: + return getRestTypeElementFlags(node as ts.RestTypeNode); + case ts.SyntaxKind.NamedTupleMember: + return (node as ts.NamedTupleMember).questionToken ? ts.ElementFlags.Optional : + (node as ts.NamedTupleMember).dotDotDotToken ? getRestTypeElementFlags(node as ts.NamedTupleMember) : + ts.ElementFlags.Required; default: - return ElementFlags.Required; + return ts.ElementFlags.Required; } } - function getRestTypeElementFlags(node: RestTypeNode | NamedTupleMember) { - return getArrayElementTypeNode(node.type) ? ElementFlags.Rest : ElementFlags.Variadic; + function getRestTypeElementFlags(node: ts.RestTypeNode | ts.NamedTupleMember) { + return getArrayElementTypeNode(node.type) ? ts.ElementFlags.Rest : ts.ElementFlags.Variadic; } - function getArrayOrTupleTargetType(node: ArrayTypeNode | TupleTypeNode): GenericType { + function getArrayOrTupleTargetType(node: ts.ArrayTypeNode | ts.TupleTypeNode): ts.GenericType { const readonly = isReadonlyTypeOperator(node.parent); const elementType = getArrayElementTypeNode(node); if (elementType) { return readonly ? globalReadonlyArrayType : globalArrayType; } - const elementFlags = map((node as TupleTypeNode).elements, getTupleElementFlags); - const missingName = some((node as TupleTypeNode).elements, e => e.kind !== SyntaxKind.NamedTupleMember); - return getTupleTargetType(elementFlags, readonly, /*associatedNames*/ missingName ? undefined : (node as TupleTypeNode).elements as readonly NamedTupleMember[]); + const elementFlags = ts.map((node as ts.TupleTypeNode).elements, getTupleElementFlags); + const missingName = ts.some((node as ts.TupleTypeNode).elements, e => e.kind !== ts.SyntaxKind.NamedTupleMember); + return getTupleTargetType(elementFlags, readonly, /*associatedNames*/ missingName ? undefined : (node as ts.TupleTypeNode).elements as readonly ts.NamedTupleMember[]); } // Return true if the given type reference node is directly aliased or if it needs to be deferred // because it is possibly contained in a circular chain of eagerly resolved types. - function isDeferredTypeReferenceNode(node: TypeReferenceNode | ArrayTypeNode | TupleTypeNode, hasDefaultTypeArguments?: boolean) { - return !!getAliasSymbolForTypeNode(node) || isResolvedByTypeAlias(node) && ( - node.kind === SyntaxKind.ArrayType ? mayResolveTypeAlias(node.elementType) : - node.kind === SyntaxKind.TupleType ? some(node.elements, mayResolveTypeAlias) : - hasDefaultTypeArguments || some(node.typeArguments, mayResolveTypeAlias)); + function isDeferredTypeReferenceNode(node: ts.TypeReferenceNode | ts.ArrayTypeNode | ts.TupleTypeNode, hasDefaultTypeArguments?: boolean) { + return !!getAliasSymbolForTypeNode(node) || isResolvedByTypeAlias(node) && (node.kind === ts.SyntaxKind.ArrayType ? mayResolveTypeAlias(node.elementType) : + node.kind === ts.SyntaxKind.TupleType ? ts.some(node.elements, mayResolveTypeAlias) : + hasDefaultTypeArguments || ts.some(node.typeArguments, mayResolveTypeAlias)); } // Return true when the given node is transitively contained in type constructs that eagerly // resolve their constituent types. We include SyntaxKind.TypeReference because type arguments // of type aliases are eagerly resolved. - function isResolvedByTypeAlias(node: Node): boolean { + function isResolvedByTypeAlias(node: ts.Node): boolean { const parent = node.parent; switch (parent.kind) { - case SyntaxKind.ParenthesizedType: - case SyntaxKind.NamedTupleMember: - case SyntaxKind.TypeReference: - case SyntaxKind.UnionType: - case SyntaxKind.IntersectionType: - case SyntaxKind.IndexedAccessType: - case SyntaxKind.ConditionalType: - case SyntaxKind.TypeOperator: - case SyntaxKind.ArrayType: - case SyntaxKind.TupleType: + case ts.SyntaxKind.ParenthesizedType: + case ts.SyntaxKind.NamedTupleMember: + case ts.SyntaxKind.TypeReference: + case ts.SyntaxKind.UnionType: + case ts.SyntaxKind.IntersectionType: + case ts.SyntaxKind.IndexedAccessType: + case ts.SyntaxKind.ConditionalType: + case ts.SyntaxKind.TypeOperator: + case ts.SyntaxKind.ArrayType: + case ts.SyntaxKind.TupleType: return isResolvedByTypeAlias(parent); - case SyntaxKind.TypeAliasDeclaration: + case ts.SyntaxKind.TypeAliasDeclaration: return true; } return false; @@ -14196,74 +13715,73 @@ namespace ts { // Return true if resolving the given node (i.e. getTypeFromTypeNode) possibly causes resolution // of a type alias. - function mayResolveTypeAlias(node: Node): boolean { + function mayResolveTypeAlias(node: ts.Node): boolean { switch (node.kind) { - case SyntaxKind.TypeReference: - return isJSDocTypeReference(node) || !!(resolveTypeReferenceName(node as TypeReferenceNode, SymbolFlags.Type).flags & SymbolFlags.TypeAlias); - case SyntaxKind.TypeQuery: + case ts.SyntaxKind.TypeReference: + return isJSDocTypeReference(node) || !!(resolveTypeReferenceName(node as ts.TypeReferenceNode, ts.SymbolFlags.Type).flags & ts.SymbolFlags.TypeAlias); + case ts.SyntaxKind.TypeQuery: return true; - case SyntaxKind.TypeOperator: - return (node as TypeOperatorNode).operator !== SyntaxKind.UniqueKeyword && mayResolveTypeAlias((node as TypeOperatorNode).type); - case SyntaxKind.ParenthesizedType: - case SyntaxKind.OptionalType: - case SyntaxKind.NamedTupleMember: - case SyntaxKind.JSDocOptionalType: - case SyntaxKind.JSDocNullableType: - case SyntaxKind.JSDocNonNullableType: - case SyntaxKind.JSDocTypeExpression: - return mayResolveTypeAlias((node as ParenthesizedTypeNode | OptionalTypeNode | JSDocTypeReferencingNode | NamedTupleMember).type); - case SyntaxKind.RestType: - return (node as RestTypeNode).type.kind !== SyntaxKind.ArrayType || mayResolveTypeAlias(((node as RestTypeNode).type as ArrayTypeNode).elementType); - case SyntaxKind.UnionType: - case SyntaxKind.IntersectionType: - return some((node as UnionOrIntersectionTypeNode).types, mayResolveTypeAlias); - case SyntaxKind.IndexedAccessType: - return mayResolveTypeAlias((node as IndexedAccessTypeNode).objectType) || mayResolveTypeAlias((node as IndexedAccessTypeNode).indexType); - case SyntaxKind.ConditionalType: - return mayResolveTypeAlias((node as ConditionalTypeNode).checkType) || mayResolveTypeAlias((node as ConditionalTypeNode).extendsType) || - mayResolveTypeAlias((node as ConditionalTypeNode).trueType) || mayResolveTypeAlias((node as ConditionalTypeNode).falseType); + case ts.SyntaxKind.TypeOperator: + return (node as ts.TypeOperatorNode).operator !== ts.SyntaxKind.UniqueKeyword && mayResolveTypeAlias((node as ts.TypeOperatorNode).type); + case ts.SyntaxKind.ParenthesizedType: + case ts.SyntaxKind.OptionalType: + case ts.SyntaxKind.NamedTupleMember: + case ts.SyntaxKind.JSDocOptionalType: + case ts.SyntaxKind.JSDocNullableType: + case ts.SyntaxKind.JSDocNonNullableType: + case ts.SyntaxKind.JSDocTypeExpression: + return mayResolveTypeAlias((node as ts.ParenthesizedTypeNode | ts.OptionalTypeNode | ts.JSDocTypeReferencingNode | ts.NamedTupleMember).type); + case ts.SyntaxKind.RestType: + return (node as ts.RestTypeNode).type.kind !== ts.SyntaxKind.ArrayType || mayResolveTypeAlias(((node as ts.RestTypeNode).type as ts.ArrayTypeNode).elementType); + case ts.SyntaxKind.UnionType: + case ts.SyntaxKind.IntersectionType: + return ts.some((node as ts.UnionOrIntersectionTypeNode).types, mayResolveTypeAlias); + case ts.SyntaxKind.IndexedAccessType: + return mayResolveTypeAlias((node as ts.IndexedAccessTypeNode).objectType) || mayResolveTypeAlias((node as ts.IndexedAccessTypeNode).indexType); + case ts.SyntaxKind.ConditionalType: + return mayResolveTypeAlias((node as ts.ConditionalTypeNode).checkType) || mayResolveTypeAlias((node as ts.ConditionalTypeNode).extendsType) || + mayResolveTypeAlias((node as ts.ConditionalTypeNode).trueType) || mayResolveTypeAlias((node as ts.ConditionalTypeNode).falseType); } return false; } - - function getTypeFromArrayOrTupleTypeNode(node: ArrayTypeNode | TupleTypeNode): Type { + function getTypeFromArrayOrTupleTypeNode(node: ts.ArrayTypeNode | ts.TupleTypeNode): ts.Type { const links = getNodeLinks(node); if (!links.resolvedType) { const target = getArrayOrTupleTargetType(node); if (target === emptyGenericType) { links.resolvedType = emptyObjectType; } - else if (!(node.kind === SyntaxKind.TupleType && some(node.elements, e => !!(getTupleElementFlags(e) & ElementFlags.Variadic))) && isDeferredTypeReferenceNode(node)) { - links.resolvedType = node.kind === SyntaxKind.TupleType && node.elements.length === 0 ? target : + else if (!(node.kind === ts.SyntaxKind.TupleType && ts.some(node.elements, e => !!(getTupleElementFlags(e) & ts.ElementFlags.Variadic))) && isDeferredTypeReferenceNode(node)) { + links.resolvedType = node.kind === ts.SyntaxKind.TupleType && node.elements.length === 0 ? target : createDeferredTypeReference(target, node, /*mapper*/ undefined); } else { - const elementTypes = node.kind === SyntaxKind.ArrayType ? [getTypeFromTypeNode(node.elementType)] : map(node.elements, getTypeFromTypeNode); + const elementTypes = node.kind === ts.SyntaxKind.ArrayType ? [getTypeFromTypeNode(node.elementType)] : ts.map(node.elements, getTypeFromTypeNode); links.resolvedType = createNormalizedTypeReference(target, elementTypes); } } return links.resolvedType; } - function isReadonlyTypeOperator(node: Node) { - return isTypeOperatorNode(node) && node.operator === SyntaxKind.ReadonlyKeyword; + function isReadonlyTypeOperator(node: ts.Node) { + return ts.isTypeOperatorNode(node) && node.operator === ts.SyntaxKind.ReadonlyKeyword; } - function createTupleType(elementTypes: readonly Type[], elementFlags?: readonly ElementFlags[], readonly = false, namedMemberDeclarations?: readonly (NamedTupleMember | ParameterDeclaration)[]) { - const tupleTarget = getTupleTargetType(elementFlags || map(elementTypes, _ => ElementFlags.Required), readonly, namedMemberDeclarations); + function createTupleType(elementTypes: readonly ts.Type[], elementFlags?: readonly ts.ElementFlags[], readonly = false, namedMemberDeclarations?: readonly (ts.NamedTupleMember | ts.ParameterDeclaration)[]) { + const tupleTarget = getTupleTargetType(elementFlags || ts.map(elementTypes, _ => ts.ElementFlags.Required), readonly, namedMemberDeclarations); return tupleTarget === emptyGenericType ? emptyObjectType : elementTypes.length ? createNormalizedTypeReference(tupleTarget, elementTypes) : tupleTarget; } - function getTupleTargetType(elementFlags: readonly ElementFlags[], readonly: boolean, namedMemberDeclarations?: readonly (NamedTupleMember | ParameterDeclaration)[]): GenericType { - if (elementFlags.length === 1 && elementFlags[0] & ElementFlags.Rest) { + function getTupleTargetType(elementFlags: readonly ts.ElementFlags[], readonly: boolean, namedMemberDeclarations?: readonly (ts.NamedTupleMember | ts.ParameterDeclaration)[]): ts.GenericType { + if (elementFlags.length === 1 && elementFlags[0] & ts.ElementFlags.Rest) { // [...X[]] is equivalent to just X[] return readonly ? globalReadonlyArrayType : globalArrayType; } - const key = map(elementFlags, f => f & ElementFlags.Required ? "#" : f & ElementFlags.Optional ? "?" : f & ElementFlags.Rest ? "." : "*").join() + + const key = ts.map(elementFlags, f => f & ts.ElementFlags.Required ? "#" : f & ts.ElementFlags.Optional ? "?" : f & ts.ElementFlags.Rest ? "." : "*").join() + (readonly ? "R" : "") + - (namedMemberDeclarations && namedMemberDeclarations.length ? "," + map(namedMemberDeclarations, getNodeId).join(",") : ""); + (namedMemberDeclarations && namedMemberDeclarations.length ? "," + ts.map(namedMemberDeclarations, getNodeId).join(",") : ""); let type = tupleTypes.get(key); if (!type) { tupleTypes.set(key, type = createTupleTargetType(elementFlags, readonly, namedMemberDeclarations)); @@ -14278,21 +13796,20 @@ namespace ts { // // Note that the generic type created by this function has no symbol associated with it. The same // is true for each of the synthesized type parameters. - function createTupleTargetType(elementFlags: readonly ElementFlags[], readonly: boolean, namedMemberDeclarations: readonly (NamedTupleMember | ParameterDeclaration)[] | undefined): TupleType { + function createTupleTargetType(elementFlags: readonly ts.ElementFlags[], readonly: boolean, namedMemberDeclarations: readonly (ts.NamedTupleMember | ts.ParameterDeclaration)[] | undefined): ts.TupleType { const arity = elementFlags.length; - const minLength = countWhere(elementFlags, f => !!(f & (ElementFlags.Required | ElementFlags.Variadic))); - let typeParameters: TypeParameter[] | undefined; - const properties: Symbol[] = []; - let combinedFlags: ElementFlags = 0; + const minLength = ts.countWhere(elementFlags, f => !!(f & (ts.ElementFlags.Required | ts.ElementFlags.Variadic))); + let typeParameters: ts.TypeParameter[] | undefined; + const properties: ts.Symbol[] = []; + let combinedFlags: ts.ElementFlags = 0; if (arity) { typeParameters = new Array(arity); for (let i = 0; i < arity; i++) { const typeParameter = typeParameters[i] = createTypeParameter(); const flags = elementFlags[i]; combinedFlags |= flags; - if (!(combinedFlags & ElementFlags.Variable)) { - const property = createSymbol(SymbolFlags.Property | (flags & ElementFlags.Optional ? SymbolFlags.Optional : 0), - "" + i as __String, readonly ? CheckFlags.Readonly : 0); + if (!(combinedFlags & ts.ElementFlags.Variable)) { + const property = createSymbol(ts.SymbolFlags.Property | (flags & ts.ElementFlags.Optional ? ts.SymbolFlags.Optional : 0), "" + i as ts.__String, readonly ? ts.CheckFlags.Readonly : 0); property.tupleLabelDeclaration = namedMemberDeclarations?.[i]; property.type = typeParameter; properties.push(property); @@ -14300,56 +13817,57 @@ namespace ts { } } const fixedLength = properties.length; - const lengthSymbol = createSymbol(SymbolFlags.Property, "length" as __String, readonly ? CheckFlags.Readonly : 0); - if (combinedFlags & ElementFlags.Variable) { + const lengthSymbol = createSymbol(ts.SymbolFlags.Property, "length" as ts.__String, readonly ? ts.CheckFlags.Readonly : 0); + if (combinedFlags & ts.ElementFlags.Variable) { lengthSymbol.type = numberType; } else { const literalTypes = []; - for (let i = minLength; i <= arity; i++) literalTypes.push(getNumberLiteralType(i)); + for (let i = minLength; i <= arity; i++) + literalTypes.push(getNumberLiteralType(i)); lengthSymbol.type = getUnionType(literalTypes); } properties.push(lengthSymbol); - const type = createObjectType(ObjectFlags.Tuple | ObjectFlags.Reference) as TupleType & InterfaceTypeWithDeclaredMembers; + const type = createObjectType(ts.ObjectFlags.Tuple | ts.ObjectFlags.Reference) as ts.TupleType & ts.InterfaceTypeWithDeclaredMembers; type.typeParameters = typeParameters; type.outerTypeParameters = undefined; type.localTypeParameters = typeParameters; - type.instantiations = new Map(); - type.instantiations.set(getTypeListId(type.typeParameters), type as GenericType); - type.target = type as GenericType; + type.instantiations = new ts.Map(); + type.instantiations.set(getTypeListId(type.typeParameters), type as ts.GenericType); + type.target = type as ts.GenericType; type.resolvedTypeArguments = type.typeParameters; type.thisType = createTypeParameter(); type.thisType.isThisType = true; type.thisType.constraint = type; type.declaredProperties = properties; - type.declaredCallSignatures = emptyArray; - type.declaredConstructSignatures = emptyArray; - type.declaredIndexInfos = emptyArray; + type.declaredCallSignatures = ts.emptyArray; + type.declaredConstructSignatures = ts.emptyArray; + type.declaredIndexInfos = ts.emptyArray; type.elementFlags = elementFlags; type.minLength = minLength; type.fixedLength = fixedLength; - type.hasRestElement = !!(combinedFlags & ElementFlags.Variable); + type.hasRestElement = !!(combinedFlags & ts.ElementFlags.Variable); type.combinedFlags = combinedFlags; type.readonly = readonly; type.labeledElementDeclarations = namedMemberDeclarations; return type; } - function createNormalizedTypeReference(target: GenericType, typeArguments: readonly Type[] | undefined) { - return target.objectFlags & ObjectFlags.Tuple ? createNormalizedTupleType(target as TupleType, typeArguments!) : createTypeReference(target, typeArguments); + function createNormalizedTypeReference(target: ts.GenericType, typeArguments: readonly ts.Type[] | undefined) { + return target.objectFlags & ts.ObjectFlags.Tuple ? createNormalizedTupleType(target as ts.TupleType, typeArguments!) : createTypeReference(target, typeArguments); } - function createNormalizedTupleType(target: TupleType, elementTypes: readonly Type[]): Type { - if (!(target.combinedFlags & ElementFlags.NonRequired)) { + function createNormalizedTupleType(target: ts.TupleType, elementTypes: readonly ts.Type[]): ts.Type { + if (!(target.combinedFlags & ts.ElementFlags.NonRequired)) { // No need to normalize when we only have regular required elements return createTypeReference(target, elementTypes); } - if (target.combinedFlags & ElementFlags.Variadic) { + if (target.combinedFlags & ts.ElementFlags.Variadic) { // Transform [A, ...(X | Y | Z)] into [A, ...X] | [A, ...Y] | [A, ...Z] - const unionIndex = findIndex(elementTypes, (t, i) => !!(target.elementFlags[i] & ElementFlags.Variadic && t.flags & (TypeFlags.Never | TypeFlags.Union))); + const unionIndex = ts.findIndex(elementTypes, (t, i) => !!(target.elementFlags[i] & ts.ElementFlags.Variadic && t.flags & (ts.TypeFlags.Never | ts.TypeFlags.Union))); if (unionIndex >= 0) { - return checkCrossProductUnion(map(elementTypes, (t, i) => target.elementFlags[i] & ElementFlags.Variadic ? t : unknownType)) ? - mapType(elementTypes[unionIndex], t => createNormalizedTupleType(target, replaceElement(elementTypes, unionIndex, t))) : + return checkCrossProductUnion(ts.map(elementTypes, (t, i) => target.elementFlags[i] & ts.ElementFlags.Variadic ? t : unknownType)) ? + mapType(elementTypes[unionIndex], t => createNormalizedTupleType(target, ts.replaceElement(elementTypes, unionIndex, t))) : errorType; } } @@ -14358,34 +13876,34 @@ namespace ts { // (1) Zero or more required elements, followed by zero or more optional elements, followed by zero or one rest element. // (2) Zero or more required elements, followed by a rest element, followed by zero or more required elements. // In either layout, zero or more generic variadic elements may be present at any location. - const expandedTypes: Type[] = []; - const expandedFlags: ElementFlags[] = []; - let expandedDeclarations: (NamedTupleMember | ParameterDeclaration)[] | undefined = []; + const expandedTypes: ts.Type[] = []; + const expandedFlags: ts.ElementFlags[] = []; + let expandedDeclarations: (ts.NamedTupleMember | ts.ParameterDeclaration)[] | undefined = []; let lastRequiredIndex = -1; let firstRestIndex = -1; let lastOptionalOrRestIndex = -1; for (let i = 0; i < elementTypes.length; i++) { const type = elementTypes[i]; const flags = target.elementFlags[i]; - if (flags & ElementFlags.Variadic) { - if (type.flags & TypeFlags.InstantiableNonPrimitive || isGenericMappedType(type)) { + if (flags & ts.ElementFlags.Variadic) { + if (type.flags & ts.TypeFlags.InstantiableNonPrimitive || isGenericMappedType(type)) { // Generic variadic elements stay as they are. - addElement(type, ElementFlags.Variadic, target.labeledElementDeclarations?.[i]); + addElement(type, ts.ElementFlags.Variadic, target.labeledElementDeclarations?.[i]); } else if (isTupleType(type)) { const elements = getTypeArguments(type); - if (elements.length + expandedTypes.length >= 10_000) { - error(currentNode, isPartOfTypeNode(currentNode!) - ? Diagnostics.Type_produces_a_tuple_type_that_is_too_large_to_represent - : Diagnostics.Expression_produces_a_tuple_type_that_is_too_large_to_represent); + if (elements.length + expandedTypes.length >= 10000) { + error(currentNode, ts.isPartOfTypeNode(currentNode!) + ? ts.Diagnostics.Type_produces_a_tuple_type_that_is_too_large_to_represent + : ts.Diagnostics.Expression_produces_a_tuple_type_that_is_too_large_to_represent); return errorType; } // Spread variadic elements with tuple types into the resulting tuple. - forEach(elements, (t, n) => addElement(t, type.target.elementFlags[n], type.target.labeledElementDeclarations?.[n])); + ts.forEach(elements, (t, n) => addElement(t, type.target.elementFlags[n], type.target.labeledElementDeclarations?.[n])); } else { // Treat everything else as an array type and create a rest element. - addElement(isArrayLikeType(type) && getIndexTypeOfType(type, numberType) || errorType, ElementFlags.Rest, target.labeledElementDeclarations?.[i]); + addElement(isArrayLikeType(type) && getIndexTypeOfType(type, numberType) || errorType, ts.ElementFlags.Rest, target.labeledElementDeclarations?.[i]); } } else { @@ -14395,12 +13913,12 @@ namespace ts { } // Turn optional elements preceding the last required element into required elements for (let i = 0; i < lastRequiredIndex; i++) { - if (expandedFlags[i] & ElementFlags.Optional) expandedFlags[i] = ElementFlags.Required; + if (expandedFlags[i] & ts.ElementFlags.Optional) + expandedFlags[i] = ts.ElementFlags.Required; } if (firstRestIndex >= 0 && firstRestIndex < lastOptionalOrRestIndex) { // Turn elements between first rest and last optional/rest into a single rest element - expandedTypes[firstRestIndex] = getUnionType(sameMap(expandedTypes.slice(firstRestIndex, lastOptionalOrRestIndex + 1), - (t, i) => expandedFlags[firstRestIndex + i] & ElementFlags.Variadic ? getIndexedAccessType(t, numberType) : t)); + expandedTypes[firstRestIndex] = getUnionType(ts.sameMap(expandedTypes.slice(firstRestIndex, lastOptionalOrRestIndex + 1), (t, i) => expandedFlags[firstRestIndex + i] & ts.ElementFlags.Variadic ? getIndexedAccessType(t, numberType) : t)); expandedTypes.splice(firstRestIndex + 1, lastOptionalOrRestIndex - firstRestIndex); expandedFlags.splice(firstRestIndex + 1, lastOptionalOrRestIndex - firstRestIndex); expandedDeclarations?.splice(firstRestIndex + 1, lastOptionalOrRestIndex - firstRestIndex); @@ -14410,14 +13928,14 @@ namespace ts { expandedFlags.length ? createTypeReference(tupleTarget, expandedTypes) : tupleTarget; - function addElement(type: Type, flags: ElementFlags, declaration: NamedTupleMember | ParameterDeclaration | undefined) { - if (flags & ElementFlags.Required) { + function addElement(type: ts.Type, flags: ts.ElementFlags, declaration: ts.NamedTupleMember | ts.ParameterDeclaration | undefined) { + if (flags & ts.ElementFlags.Required) { lastRequiredIndex = expandedFlags.length; } - if (flags & ElementFlags.Rest && firstRestIndex < 0) { + if (flags & ts.ElementFlags.Rest && firstRestIndex < 0) { firstRestIndex = expandedFlags.length; } - if (flags & (ElementFlags.Optional | ElementFlags.Rest)) { + if (flags & (ts.ElementFlags.Optional | ts.ElementFlags.Rest)) { lastOptionalOrRestIndex = expandedFlags.length; } expandedTypes.push(type); @@ -14431,44 +13949,43 @@ namespace ts { } } - function sliceTupleType(type: TupleTypeReference, index: number, endSkipCount = 0) { + function sliceTupleType(type: ts.TupleTypeReference, index: number, endSkipCount = 0) { const target = type.target; const endIndex = getTypeReferenceArity(type) - endSkipCount; - return index > target.fixedLength ? getRestArrayTypeOfTupleType(type) || createTupleType(emptyArray) : + return index > target.fixedLength ? getRestArrayTypeOfTupleType(type) || createTupleType(ts.emptyArray) : createTupleType(getTypeArguments(type).slice(index, endIndex), target.elementFlags.slice(index, endIndex), /*readonly*/ false, target.labeledElementDeclarations && target.labeledElementDeclarations.slice(index, endIndex)); } - function getKnownKeysOfTupleType(type: TupleTypeReference) { - return getUnionType(append(arrayOf(type.target.fixedLength, i => getStringLiteralType("" + i)), - getIndexType(type.target.readonly ? globalReadonlyArrayType : globalArrayType))); + function getKnownKeysOfTupleType(type: ts.TupleTypeReference) { + return getUnionType(ts.append(ts.arrayOf(type.target.fixedLength, i => getStringLiteralType("" + i)), getIndexType(type.target.readonly ? globalReadonlyArrayType : globalArrayType))); } // Return count of starting consecutive tuple elements of the given kind(s) - function getStartElementCount(type: TupleType, flags: ElementFlags) { - const index = findIndex(type.elementFlags, f => !(f & flags)); + function getStartElementCount(type: ts.TupleType, flags: ts.ElementFlags) { + const index = ts.findIndex(type.elementFlags, f => !(f & flags)); return index >= 0 ? index : type.elementFlags.length; } // Return count of ending consecutive tuple elements of the given kind(s) - function getEndElementCount(type: TupleType, flags: ElementFlags) { - return type.elementFlags.length - findLastIndex(type.elementFlags, f => !(f & flags)) - 1; + function getEndElementCount(type: ts.TupleType, flags: ts.ElementFlags) { + return type.elementFlags.length - ts.findLastIndex(type.elementFlags, f => !(f & flags)) - 1; } - function getTypeFromOptionalTypeNode(node: OptionalTypeNode): Type { + function getTypeFromOptionalTypeNode(node: ts.OptionalTypeNode): ts.Type { return addOptionality(getTypeFromTypeNode(node.type), /*isProperty*/ true); } - function getTypeId(type: Type): TypeId { + function getTypeId(type: ts.Type): ts.TypeId { return type.id; } - function containsType(types: readonly Type[], type: Type): boolean { - return binarySearch(types, type, getTypeId, compareValues) >= 0; + function containsType(types: readonly ts.Type[], type: ts.Type): boolean { + return ts.binarySearch(types, type, getTypeId, ts.compareValues) >= 0; } - function insertType(types: Type[], type: Type): boolean { - const index = binarySearch(types, type, getTypeId, compareValues); + function insertType(types: ts.Type[], type: ts.Type): boolean { + const index = ts.binarySearch(types, type, getTypeId, ts.compareValues); if (index < 0) { types.splice(~index, 0, type); return true; @@ -14476,22 +13993,25 @@ namespace ts { return false; } - function addTypeToUnion(typeSet: Type[], includes: TypeFlags, type: Type) { + function addTypeToUnion(typeSet: ts.Type[], includes: ts.TypeFlags, type: ts.Type) { const flags = type.flags; - if (flags & TypeFlags.Union) { - return addTypesToUnion(typeSet, includes | (isNamedUnionType(type) ? TypeFlags.Union : 0), (type as UnionType).types); + if (flags & ts.TypeFlags.Union) { + return addTypesToUnion(typeSet, includes | (isNamedUnionType(type) ? ts.TypeFlags.Union : 0), (type as ts.UnionType).types); } // We ignore 'never' types in unions - if (!(flags & TypeFlags.Never)) { - includes |= flags & TypeFlags.IncludesMask; - if (flags & TypeFlags.Instantiable) includes |= TypeFlags.IncludesInstantiable; - if (type === wildcardType) includes |= TypeFlags.IncludesWildcard; - if (!strictNullChecks && flags & TypeFlags.Nullable) { - if (!(getObjectFlags(type) & ObjectFlags.ContainsWideningType)) includes |= TypeFlags.IncludesNonWideningType; + if (!(flags & ts.TypeFlags.Never)) { + includes |= flags & ts.TypeFlags.IncludesMask; + if (flags & ts.TypeFlags.Instantiable) + includes |= ts.TypeFlags.IncludesInstantiable; + if (type === wildcardType) + includes |= ts.TypeFlags.IncludesWildcard; + if (!strictNullChecks && flags & ts.TypeFlags.Nullable) { + if (!(ts.getObjectFlags(type) & ts.ObjectFlags.ContainsWideningType)) + includes |= ts.TypeFlags.IncludesNonWideningType; } else { const len = typeSet.length; - const index = len && type.id > typeSet[len - 1].id ? ~len : binarySearch(typeSet, type, getTypeId, compareValues); + const index = len && type.id > typeSet[len - 1].id ? ~len : ts.binarySearch(typeSet, type, getTypeId, ts.compareValues); if (index < 0) { typeSet.splice(~index, 0, type); } @@ -14502,14 +14022,14 @@ namespace ts { // Add the given types to the given type set. Order is preserved, duplicates are removed, // and nested types of the given kind are flattened into the set. - function addTypesToUnion(typeSet: Type[], includes: TypeFlags, types: readonly Type[]): TypeFlags { + function addTypesToUnion(typeSet: ts.Type[], includes: ts.TypeFlags, types: readonly ts.Type[]): ts.TypeFlags { for (const type of types) { includes = addTypeToUnion(typeSet, includes, type); } return includes; } - function removeSubtypes(types: Type[], hasObjectTypes: boolean): Type[] | undefined { + function removeSubtypes(types: ts.Type[], hasObjectTypes: boolean): ts.Type[] | undefined { // [] and [T] immediately reduce to [] and [T] respectively if (types.length < 2) { return types; @@ -14524,19 +14044,19 @@ namespace ts { // We assume that redundant primitive types have already been removed from the types array and that there // are no any and unknown types in the array. Thus, the only possible supertypes for primitive types are empty // object types, and if none of those are present we can exclude primitive types from the subtype check. - const hasEmptyObject = hasObjectTypes && some(types, t => !!(t.flags & TypeFlags.Object) && !isGenericMappedType(t) && isEmptyResolvedType(resolveStructuredTypeMembers(t as ObjectType))); + const hasEmptyObject = hasObjectTypes && ts.some(types, t => !!(t.flags & ts.TypeFlags.Object) && !isGenericMappedType(t) && isEmptyResolvedType(resolveStructuredTypeMembers(t as ts.ObjectType))); const len = types.length; let i = len; let count = 0; while (i > 0) { i--; const source = types[i]; - if (hasEmptyObject || source.flags & TypeFlags.StructuredOrInstantiable) { + if (hasEmptyObject || source.flags & ts.TypeFlags.StructuredOrInstantiable) { // Find the first property with a unit type, if any. When constituents have a property by the same name // but of a different unit type, we can quickly disqualify them from subtype checks. This helps subtype // reduction of large discriminated union types. - const keyProperty = source.flags & (TypeFlags.Object | TypeFlags.Intersection | TypeFlags.InstantiableNonPrimitive) ? - find(getPropertiesOfType(source), p => isUnitType(getTypeOfSymbol(p))) : + const keyProperty = source.flags & (ts.TypeFlags.Object | ts.TypeFlags.Intersection | ts.TypeFlags.InstantiableNonPrimitive) ? + ts.find(getPropertiesOfType(source), p => isUnitType(getTypeOfSymbol(p))) : undefined; const keyPropertyType = keyProperty && getRegularTypeOfLiteralType(getTypeOfSymbol(keyProperty)); for (const target of types) { @@ -14548,23 +14068,22 @@ namespace ts { // caps union types at 1000 unique object types. const estimatedCount = (count / (len - i)) * len; if (estimatedCount > 1000000) { - tracing?.instant(tracing.Phase.CheckTypes, "removeSubtypes_DepthLimit", { typeIds: types.map(t => t.id) }); - error(currentNode, Diagnostics.Expression_produces_a_union_type_that_is_too_complex_to_represent); + ts.tracing?.instant(ts.tracing.Phase.CheckTypes, "removeSubtypes_DepthLimit", { typeIds: types.map(t => t.id) }); + error(currentNode, ts.Diagnostics.Expression_produces_a_union_type_that_is_too_complex_to_represent); return undefined; } } count++; - if (keyProperty && target.flags & (TypeFlags.Object | TypeFlags.Intersection | TypeFlags.InstantiableNonPrimitive)) { + if (keyProperty && target.flags & (ts.TypeFlags.Object | ts.TypeFlags.Intersection | ts.TypeFlags.InstantiableNonPrimitive)) { const t = getTypeOfPropertyOfType(target, keyProperty.escapedName); if (t && isUnitType(t) && getRegularTypeOfLiteralType(t) !== keyPropertyType) { continue; } } - if (isTypeRelatedTo(source, target, strictSubtypeRelation) && ( - !(getObjectFlags(getTargetType(source)) & ObjectFlags.Class) || - !(getObjectFlags(getTargetType(target)) & ObjectFlags.Class) || + if (isTypeRelatedTo(source, target, strictSubtypeRelation) && (!(ts.getObjectFlags(getTargetType(source)) & ts.ObjectFlags.Class) || + !(ts.getObjectFlags(getTargetType(target)) & ts.ObjectFlags.Class) || isTypeDerivedFrom(source, target))) { - orderedRemoveItemAt(types, i); + ts.orderedRemoveItemAt(types, i); break; } } @@ -14575,59 +14094,58 @@ namespace ts { return types; } - function removeRedundantLiteralTypes(types: Type[], includes: TypeFlags, reduceVoidUndefined: boolean) { + function removeRedundantLiteralTypes(types: ts.Type[], includes: ts.TypeFlags, reduceVoidUndefined: boolean) { let i = types.length; while (i > 0) { i--; const t = types[i]; const flags = t.flags; - const remove = - flags & (TypeFlags.StringLiteral | TypeFlags.TemplateLiteral | TypeFlags.StringMapping) && includes & TypeFlags.String || - flags & TypeFlags.NumberLiteral && includes & TypeFlags.Number || - flags & TypeFlags.BigIntLiteral && includes & TypeFlags.BigInt || - flags & TypeFlags.UniqueESSymbol && includes & TypeFlags.ESSymbol || - reduceVoidUndefined && flags & TypeFlags.Undefined && includes & TypeFlags.Void || - isFreshLiteralType(t) && containsType(types, (t as LiteralType).regularType); + const remove = flags & (ts.TypeFlags.StringLiteral | ts.TypeFlags.TemplateLiteral | ts.TypeFlags.StringMapping) && includes & ts.TypeFlags.String || + flags & ts.TypeFlags.NumberLiteral && includes & ts.TypeFlags.Number || + flags & ts.TypeFlags.BigIntLiteral && includes & ts.TypeFlags.BigInt || + flags & ts.TypeFlags.UniqueESSymbol && includes & ts.TypeFlags.ESSymbol || + reduceVoidUndefined && flags & ts.TypeFlags.Undefined && includes & ts.TypeFlags.Void || + isFreshLiteralType(t) && containsType(types, (t as ts.LiteralType).regularType); if (remove) { - orderedRemoveItemAt(types, i); + ts.orderedRemoveItemAt(types, i); } } } - function removeStringLiteralsMatchedByTemplateLiterals(types: Type[]) { - const templates = filter(types, isPatternLiteralType) as TemplateLiteralType[]; + function removeStringLiteralsMatchedByTemplateLiterals(types: ts.Type[]) { + const templates = ts.filter(types, isPatternLiteralType) as ts.TemplateLiteralType[]; if (templates.length) { let i = types.length; while (i > 0) { i--; const t = types[i]; - if (t.flags & TypeFlags.StringLiteral && some(templates, template => isTypeMatchedByTemplateLiteralType(t, template))) { - orderedRemoveItemAt(types, i); + if (t.flags & ts.TypeFlags.StringLiteral && ts.some(templates, template => isTypeMatchedByTemplateLiteralType(t, template))) { + ts.orderedRemoveItemAt(types, i); } } } } - function isNamedUnionType(type: Type) { - return !!(type.flags & TypeFlags.Union && (type.aliasSymbol || (type as UnionType).origin)); + function isNamedUnionType(type: ts.Type) { + return !!(type.flags & ts.TypeFlags.Union && (type.aliasSymbol || (type as ts.UnionType).origin)); } - function addNamedUnions(namedUnions: Type[], types: readonly Type[]) { + function addNamedUnions(namedUnions: ts.Type[], types: readonly ts.Type[]) { for (const t of types) { - if (t.flags & TypeFlags.Union) { - const origin = (t as UnionType).origin; - if (t.aliasSymbol || origin && !(origin.flags & TypeFlags.Union)) { - pushIfUnique(namedUnions, t); + if (t.flags & ts.TypeFlags.Union) { + const origin = (t as ts.UnionType).origin; + if (t.aliasSymbol || origin && !(origin.flags & ts.TypeFlags.Union)) { + ts.pushIfUnique(namedUnions, t); } - else if (origin && origin.flags & TypeFlags.Union) { - addNamedUnions(namedUnions, (origin as UnionType).types); + else if (origin && origin.flags & ts.TypeFlags.Union) { + addNamedUnions(namedUnions, (origin as ts.UnionType).types); } } } } - function createOriginUnionOrIntersectionType(flags: TypeFlags, types: Type[]) { - const result = createOriginType(flags) as UnionOrIntersectionType; + function createOriginUnionOrIntersectionType(flags: ts.TypeFlags, types: ts.Type[]) { + const result = createOriginType(flags) as ts.UnionOrIntersectionType; result.types = types; return result; } @@ -14639,51 +14157,51 @@ namespace ts { // expression constructs such as array literals and the || and ?: operators). Named types can // circularly reference themselves and therefore cannot be subtype reduced during their declaration. // For example, "type Item = string | (() => Item" is a named type that circularly references itself. - function getUnionType(types: readonly Type[], unionReduction: UnionReduction = UnionReduction.Literal, aliasSymbol?: Symbol, aliasTypeArguments?: readonly Type[], origin?: Type): Type { + function getUnionType(types: readonly ts.Type[], unionReduction: ts.UnionReduction = ts.UnionReduction.Literal, aliasSymbol?: ts.Symbol, aliasTypeArguments?: readonly ts.Type[], origin?: ts.Type): ts.Type { if (types.length === 0) { return neverType; } if (types.length === 1) { return types[0]; } - let typeSet: Type[] | undefined = []; + let typeSet: ts.Type[] | undefined = []; const includes = addTypesToUnion(typeSet, 0, types); - if (unionReduction !== UnionReduction.None) { - if (includes & TypeFlags.AnyOrUnknown) { - return includes & TypeFlags.Any ? - includes & TypeFlags.IncludesWildcard ? wildcardType : anyType : - includes & TypeFlags.Null || containsType(typeSet, unknownType) ? unknownType : nonNullUnknownType; - } - if (exactOptionalPropertyTypes && includes & TypeFlags.Undefined) { - const missingIndex = binarySearch(typeSet, missingType, getTypeId, compareValues); + if (unionReduction !== ts.UnionReduction.None) { + if (includes & ts.TypeFlags.AnyOrUnknown) { + return includes & ts.TypeFlags.Any ? + includes & ts.TypeFlags.IncludesWildcard ? wildcardType : anyType : + includes & ts.TypeFlags.Null || containsType(typeSet, unknownType) ? unknownType : nonNullUnknownType; + } + if (exactOptionalPropertyTypes && includes & ts.TypeFlags.Undefined) { + const missingIndex = ts.binarySearch(typeSet, missingType, getTypeId, ts.compareValues); if (missingIndex >= 0 && containsType(typeSet, undefinedType)) { - orderedRemoveItemAt(typeSet, missingIndex); + ts.orderedRemoveItemAt(typeSet, missingIndex); } } - if (includes & (TypeFlags.Literal | TypeFlags.UniqueESSymbol | TypeFlags.TemplateLiteral | TypeFlags.StringMapping) || includes & TypeFlags.Void && includes & TypeFlags.Undefined) { - removeRedundantLiteralTypes(typeSet, includes, !!(unionReduction & UnionReduction.Subtype)); + if (includes & (ts.TypeFlags.Literal | ts.TypeFlags.UniqueESSymbol | ts.TypeFlags.TemplateLiteral | ts.TypeFlags.StringMapping) || includes & ts.TypeFlags.Void && includes & ts.TypeFlags.Undefined) { + removeRedundantLiteralTypes(typeSet, includes, !!(unionReduction & ts.UnionReduction.Subtype)); } - if (includes & TypeFlags.StringLiteral && includes & TypeFlags.TemplateLiteral) { + if (includes & ts.TypeFlags.StringLiteral && includes & ts.TypeFlags.TemplateLiteral) { removeStringLiteralsMatchedByTemplateLiterals(typeSet); } - if (unionReduction === UnionReduction.Subtype) { - typeSet = removeSubtypes(typeSet, !!(includes & TypeFlags.Object)); + if (unionReduction === ts.UnionReduction.Subtype) { + typeSet = removeSubtypes(typeSet, !!(includes & ts.TypeFlags.Object)); if (!typeSet) { return errorType; } } if (typeSet.length === 0) { - return includes & TypeFlags.Null ? includes & TypeFlags.IncludesNonWideningType ? nullType : nullWideningType : - includes & TypeFlags.Undefined ? includes & TypeFlags.IncludesNonWideningType ? undefinedType : undefinedWideningType : + return includes & ts.TypeFlags.Null ? includes & ts.TypeFlags.IncludesNonWideningType ? nullType : nullWideningType : + includes & ts.TypeFlags.Undefined ? includes & ts.TypeFlags.IncludesNonWideningType ? undefinedType : undefinedWideningType : neverType; } } - if (!origin && includes & TypeFlags.Union) { - const namedUnions: Type[] = []; + if (!origin && includes & ts.TypeFlags.Union) { + const namedUnions: ts.Type[] = []; addNamedUnions(namedUnions, types); - const reducedTypes: Type[] = []; + const reducedTypes: ts.Type[] = []; for (const t of typeSet) { - if (!some(namedUnions, union => containsType((union as UnionType).types, t))) { + if (!ts.some(namedUnions, union => containsType((union as ts.UnionType).types, t))) { reducedTypes.push(t); } } @@ -14692,26 +14210,26 @@ namespace ts { } // We create a denormalized origin type only when the union was created from one or more named unions // (unions with alias symbols or origins) and when there is no overlap between those named unions. - const namedTypesCount = reduceLeft(namedUnions, (sum, union) => sum + (union as UnionType).types.length, 0); + const namedTypesCount = ts.reduceLeft(namedUnions, (sum, union) => sum + (union as ts.UnionType).types.length, 0); if (namedTypesCount + reducedTypes.length === typeSet.length) { for (const t of namedUnions) { insertType(reducedTypes, t); } - origin = createOriginUnionOrIntersectionType(TypeFlags.Union, reducedTypes); + origin = createOriginUnionOrIntersectionType(ts.TypeFlags.Union, reducedTypes); } } - const objectFlags = (includes & TypeFlags.NotPrimitiveUnion ? 0 : ObjectFlags.PrimitiveUnion) | - (includes & TypeFlags.Intersection ? ObjectFlags.ContainsIntersections : 0); + const objectFlags = (includes & ts.TypeFlags.NotPrimitiveUnion ? 0 : ts.ObjectFlags.PrimitiveUnion) | + (includes & ts.TypeFlags.Intersection ? ts.ObjectFlags.ContainsIntersections : 0); return getUnionTypeFromSortedList(typeSet, objectFlags, aliasSymbol, aliasTypeArguments, origin); } - function getUnionOrIntersectionTypePredicate(signatures: readonly Signature[], kind: TypeFlags | undefined): TypePredicate | undefined { - let first: TypePredicate | undefined; - const types: Type[] = []; + function getUnionOrIntersectionTypePredicate(signatures: readonly ts.Signature[], kind: ts.TypeFlags | undefined): ts.TypePredicate | undefined { + let first: ts.TypePredicate | undefined; + const types: ts.Type[] = []; for (const sig of signatures) { const pred = getTypePredicateOfSignature(sig); - if (!pred || pred.kind === TypePredicateKind.AssertsThis || pred.kind === TypePredicateKind.AssertsIdentifier) { - if (kind !== TypeFlags.Intersection) { + if (!pred || pred.kind === ts.TypePredicateKind.AssertsThis || pred.kind === ts.TypePredicateKind.AssertsIdentifier) { + if (kind !== ts.TypeFlags.Intersection) { continue; } else { @@ -14738,12 +14256,12 @@ namespace ts { return createTypePredicate(first.kind, first.parameterName, first.parameterIndex, compositeType); } - function typePredicateKindsMatch(a: TypePredicate, b: TypePredicate): boolean { + function typePredicateKindsMatch(a: ts.TypePredicate, b: ts.TypePredicate): boolean { return a.kind === b.kind && a.parameterIndex === b.parameterIndex; } // This function assumes the constituent type list is sorted and deduplicated. - function getUnionTypeFromSortedList(types: Type[], objectFlags: ObjectFlags, aliasSymbol?: Symbol, aliasTypeArguments?: readonly Type[], origin?: Type): Type { + function getUnionTypeFromSortedList(types: ts.Type[], objectFlags: ts.ObjectFlags, aliasSymbol?: ts.Symbol, aliasTypeArguments?: readonly ts.Type[], origin?: ts.Type): ts.Type { if (types.length === 0) { return neverType; } @@ -14751,92 +14269,91 @@ namespace ts { return types[0]; } const typeKey = !origin ? getTypeListId(types) : - origin.flags & TypeFlags.Union ? `|${getTypeListId((origin as UnionType).types)}` : - origin.flags & TypeFlags.Intersection ? `&${getTypeListId((origin as IntersectionType).types)}` : - `#${(origin as IndexType).type.id}|${getTypeListId(types)}`; // origin type id alone is insufficient, as `keyof x` may resolve to multiple WIP values while `x` is still resolving + origin.flags & ts.TypeFlags.Union ? `|${getTypeListId((origin as ts.UnionType).types)}` : + origin.flags & ts.TypeFlags.Intersection ? `&${getTypeListId((origin as ts.IntersectionType).types)}` : + `#${(origin as ts.IndexType).type.id}|${getTypeListId(types)}`; // origin type id alone is insufficient, as `keyof x` may resolve to multiple WIP values while `x` is still resolving const id = typeKey + getAliasId(aliasSymbol, aliasTypeArguments); let type = unionTypes.get(id); if (!type) { - type = createType(TypeFlags.Union) as UnionType; - type.objectFlags = objectFlags | getPropagatingFlagsOfTypes(types, /*excludeKinds*/ TypeFlags.Nullable); + type = createType(ts.TypeFlags.Union) as ts.UnionType; + type.objectFlags = objectFlags | getPropagatingFlagsOfTypes(types, /*excludeKinds*/ ts.TypeFlags.Nullable); type.types = types; type.origin = origin; type.aliasSymbol = aliasSymbol; type.aliasTypeArguments = aliasTypeArguments; - if (types.length === 2 && types[0].flags & TypeFlags.BooleanLiteral && types[1].flags & TypeFlags.BooleanLiteral) { - type.flags |= TypeFlags.Boolean; - (type as UnionType & IntrinsicType).intrinsicName = "boolean"; + if (types.length === 2 && types[0].flags & ts.TypeFlags.BooleanLiteral && types[1].flags & ts.TypeFlags.BooleanLiteral) { + type.flags |= ts.TypeFlags.Boolean; + (type as ts.UnionType & ts.IntrinsicType).intrinsicName = "boolean"; } unionTypes.set(id, type); } return type; } - function getTypeFromUnionTypeNode(node: UnionTypeNode): Type { + function getTypeFromUnionTypeNode(node: ts.UnionTypeNode): ts.Type { const links = getNodeLinks(node); if (!links.resolvedType) { const aliasSymbol = getAliasSymbolForTypeNode(node); - links.resolvedType = getUnionType(map(node.types, getTypeFromTypeNode), UnionReduction.Literal, - aliasSymbol, getTypeArgumentsForAliasSymbol(aliasSymbol)); + links.resolvedType = getUnionType(ts.map(node.types, getTypeFromTypeNode), ts.UnionReduction.Literal, aliasSymbol, getTypeArgumentsForAliasSymbol(aliasSymbol)); } return links.resolvedType; } - function addTypeToIntersection(typeSet: ESMap, includes: TypeFlags, type: Type) { + function addTypeToIntersection(typeSet: ts.ESMap, includes: ts.TypeFlags, type: ts.Type) { const flags = type.flags; - if (flags & TypeFlags.Intersection) { - return addTypesToIntersection(typeSet, includes, (type as IntersectionType).types); + if (flags & ts.TypeFlags.Intersection) { + return addTypesToIntersection(typeSet, includes, (type as ts.IntersectionType).types); } if (isEmptyAnonymousObjectType(type)) { - if (!(includes & TypeFlags.IncludesEmptyObject)) { - includes |= TypeFlags.IncludesEmptyObject; + if (!(includes & ts.TypeFlags.IncludesEmptyObject)) { + includes |= ts.TypeFlags.IncludesEmptyObject; typeSet.set(type.id.toString(), type); } } else { - if (flags & TypeFlags.AnyOrUnknown) { - if (type === wildcardType) includes |= TypeFlags.IncludesWildcard; + if (flags & ts.TypeFlags.AnyOrUnknown) { + if (type === wildcardType) + includes |= ts.TypeFlags.IncludesWildcard; } - else if (strictNullChecks || !(flags & TypeFlags.Nullable)) { + else if (strictNullChecks || !(flags & ts.TypeFlags.Nullable)) { if (exactOptionalPropertyTypes && type === missingType) { - includes |= TypeFlags.IncludesMissingType; + includes |= ts.TypeFlags.IncludesMissingType; type = undefinedType; } if (!typeSet.has(type.id.toString())) { - if (type.flags & TypeFlags.Unit && includes & TypeFlags.Unit) { + if (type.flags & ts.TypeFlags.Unit && includes & ts.TypeFlags.Unit) { // We have seen two distinct unit types which means we should reduce to an // empty intersection. Adding TypeFlags.NonPrimitive causes that to happen. - includes |= TypeFlags.NonPrimitive; + includes |= ts.TypeFlags.NonPrimitive; } typeSet.set(type.id.toString(), type); } } - includes |= flags & TypeFlags.IncludesMask; + includes |= flags & ts.TypeFlags.IncludesMask; } return includes; } // Add the given types to the given type set. Order is preserved, freshness is removed from literal // types, duplicates are removed, and nested types of the given kind are flattened into the set. - function addTypesToIntersection(typeSet: ESMap, includes: TypeFlags, types: readonly Type[]) { + function addTypesToIntersection(typeSet: ts.ESMap, includes: ts.TypeFlags, types: readonly ts.Type[]) { for (const type of types) { includes = addTypeToIntersection(typeSet, includes, getRegularTypeOfLiteralType(type)); } return includes; } - function removeRedundantPrimitiveTypes(types: Type[], includes: TypeFlags) { + function removeRedundantPrimitiveTypes(types: ts.Type[], includes: ts.TypeFlags) { let i = types.length; while (i > 0) { i--; const t = types[i]; - const remove = - t.flags & TypeFlags.String && includes & (TypeFlags.StringLiteral | TypeFlags.TemplateLiteral | TypeFlags.StringMapping) || - t.flags & TypeFlags.Number && includes & TypeFlags.NumberLiteral || - t.flags & TypeFlags.BigInt && includes & TypeFlags.BigIntLiteral || - t.flags & TypeFlags.ESSymbol && includes & TypeFlags.UniqueESSymbol; + const remove = t.flags & ts.TypeFlags.String && includes & (ts.TypeFlags.StringLiteral | ts.TypeFlags.TemplateLiteral | ts.TypeFlags.StringMapping) || + t.flags & ts.TypeFlags.Number && includes & ts.TypeFlags.NumberLiteral || + t.flags & ts.TypeFlags.BigInt && includes & ts.TypeFlags.BigIntLiteral || + t.flags & ts.TypeFlags.ESSymbol && includes & ts.TypeFlags.UniqueESSymbol; if (remove) { - orderedRemoveItemAt(types, i); + ts.orderedRemoveItemAt(types, i); } } } @@ -14844,13 +14361,13 @@ namespace ts { // Check that the given type has a match in every union. A given type is matched by // an identical type, and a literal type is additionally matched by its corresponding // primitive type. - function eachUnionContains(unionTypes: UnionType[], type: Type) { + function eachUnionContains(unionTypes: ts.UnionType[], type: ts.Type) { for (const u of unionTypes) { if (!containsType(u.types, type)) { - const primitive = type.flags & TypeFlags.StringLiteral ? stringType : - type.flags & TypeFlags.NumberLiteral ? numberType : - type.flags & TypeFlags.BigIntLiteral ? bigintType : - type.flags & TypeFlags.UniqueESSymbol ? esSymbolType : + const primitive = type.flags & ts.TypeFlags.StringLiteral ? stringType : + type.flags & ts.TypeFlags.NumberLiteral ? numberType : + type.flags & ts.TypeFlags.BigIntLiteral ? bigintType : + type.flags & ts.TypeFlags.UniqueESSymbol ? esSymbolType : undefined; if (!primitive || !containsType(u.types, primitive)) { return false; @@ -14863,17 +14380,18 @@ namespace ts { /** * Returns `true` if the intersection of the template literals and string literals is the empty set, eg `get${string}` & "setX", and should reduce to `never` */ - function extractRedundantTemplateLiterals(types: Type[]): boolean { + function extractRedundantTemplateLiterals(types: ts.Type[]): boolean { let i = types.length; - const literals = filter(types, t => !!(t.flags & TypeFlags.StringLiteral)); + const literals = ts.filter(types, t => !!(t.flags & ts.TypeFlags.StringLiteral)); while (i > 0) { i--; const t = types[i]; - if (!(t.flags & TypeFlags.TemplateLiteral)) continue; + if (!(t.flags & ts.TypeFlags.TemplateLiteral)) + continue; for (const t2 of literals) { if (isTypeSubtypeOf(t2, t)) { // eg, ``get${T}` & "getX"` is just `"getX"` - orderedRemoveItemAt(types, i); + ts.orderedRemoveItemAt(types, i); break; } else if (isPatternLiteralType(t)) { @@ -14884,11 +14402,11 @@ namespace ts { return false; } - function eachIsUnionContaining(types: Type[], flag: TypeFlags) { - return every(types, t => !!(t.flags & TypeFlags.Union) && some((t as UnionType).types, tt => !!(tt.flags & flag))); + function eachIsUnionContaining(types: ts.Type[], flag: ts.TypeFlags) { + return ts.every(types, t => !!(t.flags & ts.TypeFlags.Union) && ts.some((t as ts.UnionType).types, tt => !!(tt.flags & flag))); } - function removeFromEach(types: Type[], flag: TypeFlags) { + function removeFromEach(types: ts.Type[], flag: ts.TypeFlags) { for (let i = 0; i < types.length; i++) { types[i] = filterType(types[i], t => !(t.flags & flag)); } @@ -14897,9 +14415,9 @@ namespace ts { // If the given list of types contains more than one union of primitive types, replace the // first with a union containing an intersection of those primitive types, then remove the // other unions and return true. Otherwise, do nothing and return false. - function intersectUnionsOfPrimitiveTypes(types: Type[]) { - let unionTypes: UnionType[] | undefined; - const index = findIndex(types, t => !!(getObjectFlags(t) & ObjectFlags.PrimitiveUnion)); + function intersectUnionsOfPrimitiveTypes(types: ts.Type[]) { + let unionTypes: ts.UnionType[] | undefined; + const index = ts.findIndex(types, t => !!(ts.getObjectFlags(t) & ts.ObjectFlags.PrimitiveUnion)); if (index < 0) { return false; } @@ -14908,9 +14426,9 @@ namespace ts { // the unionTypes array. while (i < types.length) { const t = types[i]; - if (getObjectFlags(t) & ObjectFlags.PrimitiveUnion) { - (unionTypes || (unionTypes = [types[index] as UnionType])).push(t as UnionType); - orderedRemoveItemAt(types, i); + if (ts.getObjectFlags(t) & ts.ObjectFlags.PrimitiveUnion) { + (unionTypes || (unionTypes = [types[index] as ts.UnionType])).push(t as ts.UnionType); + ts.orderedRemoveItemAt(types, i); } else { i++; @@ -14923,8 +14441,8 @@ namespace ts { // We have more than one union of primitive types, now intersect them. For each // type in each union we check if the type is matched in every union and if so // we include it in the result. - const checked: Type[] = []; - const result: Type[] = []; + const checked: ts.Type[] = []; + const result: ts.Type[] = []; for (const u of unionTypes) { for (const t of u.types) { if (insertType(checked, t)) { @@ -14935,13 +14453,13 @@ namespace ts { } } // Finally replace the first union with the result - types[index] = getUnionTypeFromSortedList(result, ObjectFlags.PrimitiveUnion); + types[index] = getUnionTypeFromSortedList(result, ts.ObjectFlags.PrimitiveUnion); return true; } - function createIntersectionType(types: Type[], aliasSymbol?: Symbol, aliasTypeArguments?: readonly Type[]) { - const result = createType(TypeFlags.Intersection) as IntersectionType; - result.objectFlags = getPropagatingFlagsOfTypes(types, /*excludeKinds*/ TypeFlags.Nullable); + function createIntersectionType(types: ts.Type[], aliasSymbol?: ts.Symbol, aliasTypeArguments?: readonly ts.Type[]) { + const result = createType(ts.TypeFlags.Intersection) as ts.IntersectionType; + result.objectFlags = getPropagatingFlagsOfTypes(types, /*excludeKinds*/ ts.TypeFlags.Nullable); result.types = types; result.aliasSymbol = aliasSymbol; result.aliasTypeArguments = aliasTypeArguments; @@ -14958,10 +14476,10 @@ namespace ts { // a type alias of the form "type List = T & { next: List }" cannot be reduced during its declaration. // Also, unlike union types, the order of the constituent types is preserved in order that overload resolution // for intersections of types with signatures can be deterministic. - function getIntersectionType(types: readonly Type[], aliasSymbol?: Symbol, aliasTypeArguments?: readonly Type[]): Type { - const typeMembershipMap: ESMap = new Map(); + function getIntersectionType(types: readonly ts.Type[], aliasSymbol?: ts.Symbol, aliasTypeArguments?: readonly ts.Type[]): ts.Type { + const typeMembershipMap: ts.ESMap = new ts.Map(); const includes = addTypesToIntersection(typeMembershipMap, 0, types); - const typeSet: Type[] = arrayFrom(typeMembershipMap.values()); + const typeSet: ts.Type[] = ts.arrayFrom(typeMembershipMap.values()); // An intersection type is considered empty if it contains // the type never, or // more than one unit type or, @@ -14971,37 +14489,37 @@ namespace ts { // a symbol-like type and a type known to be non-symbol-like, or // a void-like type and a type known to be non-void-like, or // a non-primitive type and a type known to be primitive. - if (includes & TypeFlags.Never) { - return contains(typeSet, silentNeverType) ? silentNeverType : neverType; - } - if (strictNullChecks && includes & TypeFlags.Nullable && includes & (TypeFlags.Object | TypeFlags.NonPrimitive | TypeFlags.IncludesEmptyObject) || - includes & TypeFlags.NonPrimitive && includes & (TypeFlags.DisjointDomains & ~TypeFlags.NonPrimitive) || - includes & TypeFlags.StringLike && includes & (TypeFlags.DisjointDomains & ~TypeFlags.StringLike) || - includes & TypeFlags.NumberLike && includes & (TypeFlags.DisjointDomains & ~TypeFlags.NumberLike) || - includes & TypeFlags.BigIntLike && includes & (TypeFlags.DisjointDomains & ~TypeFlags.BigIntLike) || - includes & TypeFlags.ESSymbolLike && includes & (TypeFlags.DisjointDomains & ~TypeFlags.ESSymbolLike) || - includes & TypeFlags.VoidLike && includes & (TypeFlags.DisjointDomains & ~TypeFlags.VoidLike)) { + if (includes & ts.TypeFlags.Never) { + return ts.contains(typeSet, silentNeverType) ? silentNeverType : neverType; + } + if (strictNullChecks && includes & ts.TypeFlags.Nullable && includes & (ts.TypeFlags.Object | ts.TypeFlags.NonPrimitive | ts.TypeFlags.IncludesEmptyObject) || + includes & ts.TypeFlags.NonPrimitive && includes & (ts.TypeFlags.DisjointDomains & ~ts.TypeFlags.NonPrimitive) || + includes & ts.TypeFlags.StringLike && includes & (ts.TypeFlags.DisjointDomains & ~ts.TypeFlags.StringLike) || + includes & ts.TypeFlags.NumberLike && includes & (ts.TypeFlags.DisjointDomains & ~ts.TypeFlags.NumberLike) || + includes & ts.TypeFlags.BigIntLike && includes & (ts.TypeFlags.DisjointDomains & ~ts.TypeFlags.BigIntLike) || + includes & ts.TypeFlags.ESSymbolLike && includes & (ts.TypeFlags.DisjointDomains & ~ts.TypeFlags.ESSymbolLike) || + includes & ts.TypeFlags.VoidLike && includes & (ts.TypeFlags.DisjointDomains & ~ts.TypeFlags.VoidLike)) { return neverType; } - if (includes & TypeFlags.TemplateLiteral && includes & TypeFlags.StringLiteral && extractRedundantTemplateLiterals(typeSet)) { + if (includes & ts.TypeFlags.TemplateLiteral && includes & ts.TypeFlags.StringLiteral && extractRedundantTemplateLiterals(typeSet)) { return neverType; } - if (includes & TypeFlags.Any) { - return includes & TypeFlags.IncludesWildcard ? wildcardType : anyType; + if (includes & ts.TypeFlags.Any) { + return includes & ts.TypeFlags.IncludesWildcard ? wildcardType : anyType; } - if (!strictNullChecks && includes & TypeFlags.Nullable) { - return includes & TypeFlags.Undefined ? undefinedType : nullType; + if (!strictNullChecks && includes & ts.TypeFlags.Nullable) { + return includes & ts.TypeFlags.Undefined ? undefinedType : nullType; } - if (includes & TypeFlags.String && includes & (TypeFlags.StringLiteral | TypeFlags.TemplateLiteral | TypeFlags.StringMapping) || - includes & TypeFlags.Number && includes & TypeFlags.NumberLiteral || - includes & TypeFlags.BigInt && includes & TypeFlags.BigIntLiteral || - includes & TypeFlags.ESSymbol && includes & TypeFlags.UniqueESSymbol) { + if (includes & ts.TypeFlags.String && includes & (ts.TypeFlags.StringLiteral | ts.TypeFlags.TemplateLiteral | ts.TypeFlags.StringMapping) || + includes & ts.TypeFlags.Number && includes & ts.TypeFlags.NumberLiteral || + includes & ts.TypeFlags.BigInt && includes & ts.TypeFlags.BigIntLiteral || + includes & ts.TypeFlags.ESSymbol && includes & ts.TypeFlags.UniqueESSymbol) { removeRedundantPrimitiveTypes(typeSet, includes); } - if (includes & TypeFlags.IncludesEmptyObject && includes & TypeFlags.Object) { - orderedRemoveItemAt(typeSet, findIndex(typeSet, isEmptyAnonymousObjectType)); + if (includes & ts.TypeFlags.IncludesEmptyObject && includes & ts.TypeFlags.Object) { + ts.orderedRemoveItemAt(typeSet, ts.findIndex(typeSet, isEmptyAnonymousObjectType)); } - if (includes & TypeFlags.IncludesMissingType) { + if (includes & ts.TypeFlags.IncludesMissingType) { typeSet[typeSet.indexOf(undefinedType)] = missingType; } if (typeSet.length === 0) { @@ -15013,21 +14531,21 @@ namespace ts { const id = getTypeListId(typeSet) + getAliasId(aliasSymbol, aliasTypeArguments); let result = intersectionTypes.get(id); if (!result) { - if (includes & TypeFlags.Union) { + if (includes & ts.TypeFlags.Union) { if (intersectUnionsOfPrimitiveTypes(typeSet)) { // When the intersection creates a reduced set (which might mean that *all* union types have // disappeared), we restart the operation to get a new set of combined flags. Once we have // reduced we'll never reduce again, so this occurs at most once. result = getIntersectionType(typeSet, aliasSymbol, aliasTypeArguments); } - else if (eachIsUnionContaining(typeSet, TypeFlags.Undefined)) { - const undefinedOrMissingType = exactOptionalPropertyTypes && some(typeSet, t => containsType((t as UnionType).types, missingType)) ? missingType : undefinedType; - removeFromEach(typeSet, TypeFlags.Undefined); - result = getUnionType([getIntersectionType(typeSet), undefinedOrMissingType], UnionReduction.Literal, aliasSymbol, aliasTypeArguments); + else if (eachIsUnionContaining(typeSet, ts.TypeFlags.Undefined)) { + const undefinedOrMissingType = exactOptionalPropertyTypes && ts.some(typeSet, t => containsType((t as ts.UnionType).types, missingType)) ? missingType : undefinedType; + removeFromEach(typeSet, ts.TypeFlags.Undefined); + result = getUnionType([getIntersectionType(typeSet), undefinedOrMissingType], ts.UnionReduction.Literal, aliasSymbol, aliasTypeArguments); } - else if (eachIsUnionContaining(typeSet, TypeFlags.Null)) { - removeFromEach(typeSet, TypeFlags.Null); - result = getUnionType([getIntersectionType(typeSet), nullType], UnionReduction.Literal, aliasSymbol, aliasTypeArguments); + else if (eachIsUnionContaining(typeSet, ts.TypeFlags.Null)) { + removeFromEach(typeSet, ts.TypeFlags.Null); + result = getUnionType([getIntersectionType(typeSet), nullType], ts.UnionReduction.Literal, aliasSymbol, aliasTypeArguments); } else { // We are attempting to construct a type of the form X & (A | B) & (C | D). Transform this into a type of @@ -15039,8 +14557,8 @@ namespace ts { const constituents = getCrossProductIntersections(typeSet); // We attach a denormalized origin type when at least one constituent of the cross-product union is an // intersection (i.e. when the intersection didn't just reduce one or more unions to smaller unions). - const origin = some(constituents, t => !!(t.flags & TypeFlags.Intersection)) ? createOriginUnionOrIntersectionType(TypeFlags.Intersection, typeSet) : undefined; - result = getUnionType(constituents, UnionReduction.Literal, aliasSymbol, aliasTypeArguments, origin); + const origin = ts.some(constituents, t => !!(t.flags & ts.TypeFlags.Intersection)) ? createOriginUnionOrIntersectionType(ts.TypeFlags.Intersection, typeSet) : undefined; + result = getUnionType(constituents, ts.UnionReduction.Literal, aliasSymbol, aliasTypeArguments, origin); } } else { @@ -15051,64 +14569,64 @@ namespace ts { return result; } - function getCrossProductUnionSize(types: readonly Type[]) { - return reduceLeft(types, (n, t) => t.flags & TypeFlags.Union ? n * (t as UnionType).types.length : t.flags & TypeFlags.Never ? 0 : n, 1); + function getCrossProductUnionSize(types: readonly ts.Type[]) { + return ts.reduceLeft(types, (n, t) => t.flags & ts.TypeFlags.Union ? n * (t as ts.UnionType).types.length : t.flags & ts.TypeFlags.Never ? 0 : n, 1); } - function checkCrossProductUnion(types: readonly Type[]) { + function checkCrossProductUnion(types: readonly ts.Type[]) { const size = getCrossProductUnionSize(types); if (size >= 100000) { - tracing?.instant(tracing.Phase.CheckTypes, "checkCrossProductUnion_DepthLimit", { typeIds: types.map(t => t.id), size }); - error(currentNode, Diagnostics.Expression_produces_a_union_type_that_is_too_complex_to_represent); + ts.tracing?.instant(ts.tracing.Phase.CheckTypes, "checkCrossProductUnion_DepthLimit", { typeIds: types.map(t => t.id), size }); + error(currentNode, ts.Diagnostics.Expression_produces_a_union_type_that_is_too_complex_to_represent); return false; } return true; } - function getCrossProductIntersections(types: readonly Type[]) { + function getCrossProductIntersections(types: readonly ts.Type[]) { const count = getCrossProductUnionSize(types); - const intersections: Type[] = []; + const intersections: ts.Type[] = []; for (let i = 0; i < count; i++) { const constituents = types.slice(); let n = i; for (let j = types.length - 1; j >= 0; j--) { - if (types[j].flags & TypeFlags.Union) { - const sourceTypes = (types[j] as UnionType).types; + if (types[j].flags & ts.TypeFlags.Union) { + const sourceTypes = (types[j] as ts.UnionType).types; const length = sourceTypes.length; constituents[j] = sourceTypes[n % length]; n = Math.floor(n / length); } } const t = getIntersectionType(constituents); - if (!(t.flags & TypeFlags.Never)) intersections.push(t); + if (!(t.flags & ts.TypeFlags.Never)) + intersections.push(t); } return intersections; } - function getTypeFromIntersectionTypeNode(node: IntersectionTypeNode): Type { + function getTypeFromIntersectionTypeNode(node: ts.IntersectionTypeNode): ts.Type { const links = getNodeLinks(node); if (!links.resolvedType) { const aliasSymbol = getAliasSymbolForTypeNode(node); - links.resolvedType = getIntersectionType(map(node.types, getTypeFromTypeNode), - aliasSymbol, getTypeArgumentsForAliasSymbol(aliasSymbol)); + links.resolvedType = getIntersectionType(ts.map(node.types, getTypeFromTypeNode), aliasSymbol, getTypeArgumentsForAliasSymbol(aliasSymbol)); } return links.resolvedType; } - function createIndexType(type: InstantiableType | UnionOrIntersectionType, stringsOnly: boolean) { - const result = createType(TypeFlags.Index) as IndexType; + function createIndexType(type: ts.InstantiableType | ts.UnionOrIntersectionType, stringsOnly: boolean) { + const result = createType(ts.TypeFlags.Index) as ts.IndexType; result.type = type; result.stringsOnly = stringsOnly; return result; } - function createOriginIndexType(type: InstantiableType | UnionOrIntersectionType) { - const result = createOriginType(TypeFlags.Index) as IndexType; + function createOriginIndexType(type: ts.InstantiableType | ts.UnionOrIntersectionType) { + const result = createOriginType(ts.TypeFlags.Index) as ts.IndexType; result.type = type; return result; } - function getIndexTypeForGenericType(type: InstantiableType | UnionOrIntersectionType, stringsOnly: boolean) { + function getIndexTypeForGenericType(type: ts.InstantiableType | ts.UnionOrIntersectionType, stringsOnly: boolean) { return stringsOnly ? type.resolvedStringIndexType || (type.resolvedStringIndexType = createIndexType(type, /*stringsOnly*/ true)) : type.resolvedIndexType || (type.resolvedIndexType = createIndexType(type, /*stringsOnly*/ false)); @@ -15121,15 +14639,15 @@ namespace ts { * reduction in the constraintType) when possible. * @param noIndexSignatures Indicates if _string_ index signatures should be elided. (other index signatures are always reported) */ - function getIndexTypeForMappedType(type: MappedType, stringsOnly: boolean, noIndexSignatures: boolean | undefined) { + function getIndexTypeForMappedType(type: ts.MappedType, stringsOnly: boolean, noIndexSignatures: boolean | undefined) { const typeParameter = getTypeParameterFromMappedType(type); const constraintType = getConstraintTypeFromMappedType(type); - const nameType = getNameTypeFromMappedType(type.target as MappedType || type); + const nameType = getNameTypeFromMappedType(type.target as ts.MappedType || type); if (!nameType && !noIndexSignatures) { // no mapping and no filtering required, just quickly bail to returning the constraint in the common case return constraintType; } - const keyTypes: Type[] = []; + const keyTypes: ts.Type[] = []; if (isMappedTypeWithKeyofConstraintDeclaration(type)) { // We have a { [P in keyof T]: X } @@ -15138,7 +14656,7 @@ namespace ts { // so we only eagerly manifest the keys if the constraint is nongeneric if (!isGenericIndexType(constraintType)) { const modifiersType = getApparentType(getModifiersTypeFromMappedType(type)); // The 'T' in 'keyof T' - forEachMappedTypePropertyKeyTypeAndIndexSignatureKeyType(modifiersType, TypeFlags.StringOrNumberLiteralOrUnique, stringsOnly, addMemberForKeyType); + forEachMappedTypePropertyKeyTypeAndIndexSignatureKeyType(modifiersType, ts.TypeFlags.StringOrNumberLiteralOrUnique, stringsOnly, addMemberForKeyType); } else { // we have a generic index and a homomorphic mapping (but a distributive key remapping) - we need to defer the whole `keyof whatever` for later @@ -15154,13 +14672,13 @@ namespace ts { } // we had to pick apart the constraintType to potentially map/filter it - compare the final resulting list with the original constraintType, // so we can return the union that preserves aliases/origin data if possible - const result = noIndexSignatures ? filterType(getUnionType(keyTypes), t => !(t.flags & (TypeFlags.Any | TypeFlags.String))) : getUnionType(keyTypes); - if (result.flags & TypeFlags.Union && constraintType.flags & TypeFlags.Union && getTypeListId((result as UnionType).types) === getTypeListId((constraintType as UnionType).types)){ + const result = noIndexSignatures ? filterType(getUnionType(keyTypes), t => !(t.flags & (ts.TypeFlags.Any | ts.TypeFlags.String))) : getUnionType(keyTypes); + if (result.flags & ts.TypeFlags.Union && constraintType.flags & ts.TypeFlags.Union && getTypeListId((result as ts.UnionType).types) === getTypeListId((constraintType as ts.UnionType).types)) { return constraintType; } return result; - function addMemberForKeyType(keyType: Type) { + function addMemberForKeyType(keyType: ts.Type) { const propNameType = nameType ? instantiateType(nameType, appendTypeMapping(type.mapper, typeParameter, keyType)) : keyType; // `keyof` currently always returns `string | number` for concrete `string` index signatures - the below ternary keeps that behavior for mapped types // See `getLiteralTypeFromProperties` where there's a similar ternary to cause the same behavior. @@ -15173,35 +14691,35 @@ namespace ts { // want to perform the reduction when the name type of a mapped type is distributive with respect to the type variable // introduced by the 'in' clause of the mapped type. Note that non-generic types are considered to be distributive because // they're the same type regardless of what's being distributed over. - function hasDistributiveNameType(mappedType: MappedType) { + function hasDistributiveNameType(mappedType: ts.MappedType) { const typeVariable = getTypeParameterFromMappedType(mappedType); return isDistributive(getNameTypeFromMappedType(mappedType) || typeVariable); - function isDistributive(type: Type): boolean { - return type.flags & (TypeFlags.AnyOrUnknown | TypeFlags.Primitive | TypeFlags.Never | TypeFlags.TypeParameter | TypeFlags.Object | TypeFlags.NonPrimitive) ? true : - type.flags & TypeFlags.Conditional ? (type as ConditionalType).root.isDistributive && (type as ConditionalType).checkType === typeVariable : - type.flags & (TypeFlags.UnionOrIntersection | TypeFlags.TemplateLiteral) ? every((type as UnionOrIntersectionType | TemplateLiteralType).types, isDistributive) : - type.flags & TypeFlags.IndexedAccess ? isDistributive((type as IndexedAccessType).objectType) && isDistributive((type as IndexedAccessType).indexType) : - type.flags & TypeFlags.Substitution ? isDistributive((type as SubstitutionType).substitute) : - type.flags & TypeFlags.StringMapping ? isDistributive((type as StringMappingType).type) : + function isDistributive(type: ts.Type): boolean { + return type.flags & (ts.TypeFlags.AnyOrUnknown | ts.TypeFlags.Primitive | ts.TypeFlags.Never | ts.TypeFlags.TypeParameter | ts.TypeFlags.Object | ts.TypeFlags.NonPrimitive) ? true : + type.flags & ts.TypeFlags.Conditional ? (type as ts.ConditionalType).root.isDistributive && (type as ts.ConditionalType).checkType === typeVariable : + type.flags & (ts.TypeFlags.UnionOrIntersection | ts.TypeFlags.TemplateLiteral) ? ts.every((type as ts.UnionOrIntersectionType | ts.TemplateLiteralType).types, isDistributive) : + type.flags & ts.TypeFlags.IndexedAccess ? isDistributive((type as ts.IndexedAccessType).objectType) && isDistributive((type as ts.IndexedAccessType).indexType) : + type.flags & ts.TypeFlags.Substitution ? isDistributive((type as ts.SubstitutionType).substitute) : + type.flags & ts.TypeFlags.StringMapping ? isDistributive((type as ts.StringMappingType).type) : false; } } - function getLiteralTypeFromPropertyName(name: PropertyName) { - if (isPrivateIdentifier(name)) { + function getLiteralTypeFromPropertyName(name: ts.PropertyName) { + if (ts.isPrivateIdentifier(name)) { return neverType; } - return isIdentifier(name) ? getStringLiteralType(unescapeLeadingUnderscores(name.escapedText)) : - getRegularTypeOfLiteralType(isComputedPropertyName(name) ? checkComputedPropertyName(name) : checkExpression(name)); + return ts.isIdentifier(name) ? getStringLiteralType(ts.unescapeLeadingUnderscores(name.escapedText)) : + getRegularTypeOfLiteralType(ts.isComputedPropertyName(name) ? checkComputedPropertyName(name) : checkExpression(name)); } - function getLiteralTypeFromProperty(prop: Symbol, include: TypeFlags, includeNonPublic?: boolean) { - if (includeNonPublic || !(getDeclarationModifierFlagsFromSymbol(prop) & ModifierFlags.NonPublicAccessibilityModifier)) { + function getLiteralTypeFromProperty(prop: ts.Symbol, include: ts.TypeFlags, includeNonPublic?: boolean) { + if (includeNonPublic || !(ts.getDeclarationModifierFlagsFromSymbol(prop) & ts.ModifierFlags.NonPublicAccessibilityModifier)) { let type = getSymbolLinks(getLateBoundSymbol(prop)).nameType; if (!type) { - const name = getNameOfDeclaration(prop.valueDeclaration) as PropertyName; - type = prop.escapedName === InternalSymbolName.Default ? getStringLiteralType("default") : - name && getLiteralTypeFromPropertyName(name) || (!isKnownSymbol(prop) ? getStringLiteralType(symbolName(prop)) : undefined); + const name = ts.getNameOfDeclaration(prop.valueDeclaration) as ts.PropertyName; + type = prop.escapedName === ts.InternalSymbolName.Default ? getStringLiteralType("default") : + name && getLiteralTypeFromPropertyName(name) || (!ts.isKnownSymbol(prop) ? getStringLiteralType(ts.symbolName(prop)) : undefined); } if (type && type.flags & include) { return type; @@ -15210,16 +14728,16 @@ namespace ts { return neverType; } - function isKeyTypeIncluded(keyType: Type, include: TypeFlags): boolean { - return !!(keyType.flags & include || keyType.flags & TypeFlags.Intersection && some((keyType as IntersectionType).types, t => isKeyTypeIncluded(t, include))); + function isKeyTypeIncluded(keyType: ts.Type, include: ts.TypeFlags): boolean { + return !!(keyType.flags & include || keyType.flags & ts.TypeFlags.Intersection && ts.some((keyType as ts.IntersectionType).types, t => isKeyTypeIncluded(t, include))); } - function getLiteralTypeFromProperties(type: Type, include: TypeFlags, includeOrigin: boolean) { - const origin = includeOrigin && (getObjectFlags(type) & (ObjectFlags.ClassOrInterface | ObjectFlags.Reference) || type.aliasSymbol) ? createOriginIndexType(type) : undefined; - const propertyTypes = map(getPropertiesOfType(type), prop => getLiteralTypeFromProperty(prop, include)); - const indexKeyTypes = map(getIndexInfosOfType(type), info => info !== enumNumberIndexInfo && isKeyTypeIncluded(info.keyType, include) ? - info.keyType === stringType && include & TypeFlags.Number ? stringOrNumberType : info.keyType : neverType); - return getUnionType(concatenate(propertyTypes, indexKeyTypes), UnionReduction.Literal, + function getLiteralTypeFromProperties(type: ts.Type, include: ts.TypeFlags, includeOrigin: boolean) { + const origin = includeOrigin && (ts.getObjectFlags(type) & (ts.ObjectFlags.ClassOrInterface | ts.ObjectFlags.Reference) || type.aliasSymbol) ? createOriginIndexType(type) : undefined; + const propertyTypes = ts.map(getPropertiesOfType(type), prop => getLiteralTypeFromProperty(prop, include)); + const indexKeyTypes = ts.map(getIndexInfosOfType(type), info => info !== enumNumberIndexInfo && isKeyTypeIncluded(info.keyType, include) ? + info.keyType === stringType && include & ts.TypeFlags.Number ? stringOrNumberType : info.keyType : neverType); + return getUnionType(ts.concatenate(propertyTypes, indexKeyTypes), ts.UnionReduction.Literal, /*aliasSymbol*/ undefined, /*aliasTypeArguments*/ undefined, origin); } @@ -15229,29 +14747,28 @@ namespace ts { * type parameters in the union with a special never type that is treated as a literal in `getReducedType`, we can cause the `getReducedType` logic * to reduce the resulting type if possible (since only intersections with conflicting literal-typed properties are reducible). */ - function isPossiblyReducibleByInstantiation(type: UnionType): boolean { - return some(type.types, t => { + function isPossiblyReducibleByInstantiation(type: ts.UnionType): boolean { + return ts.some(type.types, t => { const uniqueFilled = getUniqueLiteralFilledInstantiation(t); return getReducedType(uniqueFilled) !== uniqueFilled; }); } - function getIndexType(type: Type, stringsOnly = keyofStringsOnly, noIndexSignatures?: boolean): Type { + function getIndexType(type: ts.Type, stringsOnly = keyofStringsOnly, noIndexSignatures?: boolean): ts.Type { type = getReducedType(type); - return type.flags & TypeFlags.Union ? isPossiblyReducibleByInstantiation(type as UnionType) - ? getIndexTypeForGenericType(type as InstantiableType | UnionOrIntersectionType, stringsOnly) - : getIntersectionType(map((type as UnionType).types, t => getIndexType(t, stringsOnly, noIndexSignatures))) : - type.flags & TypeFlags.Intersection ? getUnionType(map((type as IntersectionType).types, t => getIndexType(t, stringsOnly, noIndexSignatures))) : - type.flags & TypeFlags.InstantiableNonPrimitive || isGenericTupleType(type) || isGenericMappedType(type) && !hasDistributiveNameType(type) ? getIndexTypeForGenericType(type as InstantiableType | UnionOrIntersectionType, stringsOnly) : - getObjectFlags(type) & ObjectFlags.Mapped ? getIndexTypeForMappedType(type as MappedType, stringsOnly, noIndexSignatures) : + return type.flags & ts.TypeFlags.Union ? isPossiblyReducibleByInstantiation(type as ts.UnionType) + ? getIndexTypeForGenericType(type as ts.InstantiableType | ts.UnionOrIntersectionType, stringsOnly) + : getIntersectionType(ts.map((type as ts.UnionType).types, t => getIndexType(t, stringsOnly, noIndexSignatures))) : + type.flags & ts.TypeFlags.Intersection ? getUnionType(ts.map((type as ts.IntersectionType).types, t => getIndexType(t, stringsOnly, noIndexSignatures))) : + type.flags & ts.TypeFlags.InstantiableNonPrimitive || isGenericTupleType(type) || isGenericMappedType(type) && !hasDistributiveNameType(type) ? getIndexTypeForGenericType(type as ts.InstantiableType | ts.UnionOrIntersectionType, stringsOnly) : + ts.getObjectFlags(type) & ts.ObjectFlags.Mapped ? getIndexTypeForMappedType(type as ts.MappedType, stringsOnly, noIndexSignatures) : type === wildcardType ? wildcardType : - type.flags & TypeFlags.Unknown ? neverType : - type.flags & (TypeFlags.Any | TypeFlags.Never) ? keyofConstraintType : - getLiteralTypeFromProperties(type, (noIndexSignatures ? TypeFlags.StringLiteral : TypeFlags.StringLike) | (stringsOnly ? 0 : TypeFlags.NumberLike | TypeFlags.ESSymbolLike), - stringsOnly === keyofStringsOnly && !noIndexSignatures); + type.flags & ts.TypeFlags.Unknown ? neverType : + type.flags & (ts.TypeFlags.Any | ts.TypeFlags.Never) ? keyofConstraintType : + getLiteralTypeFromProperties(type, (noIndexSignatures ? ts.TypeFlags.StringLiteral : ts.TypeFlags.StringLike) | (stringsOnly ? 0 : ts.TypeFlags.NumberLike | ts.TypeFlags.ESSymbolLike), stringsOnly === keyofStringsOnly && !noIndexSignatures); } - function getExtractStringType(type: Type) { + function getExtractStringType(type: ts.Type) { if (keyofStringsOnly) { return type; } @@ -15259,54 +14776,52 @@ namespace ts { return extractTypeAlias ? getTypeAliasInstantiation(extractTypeAlias, [type, stringType]) : stringType; } - function getIndexTypeOrString(type: Type): Type { + function getIndexTypeOrString(type: ts.Type): ts.Type { const indexType = getExtractStringType(getIndexType(type)); - return indexType.flags & TypeFlags.Never ? stringType : indexType; + return indexType.flags & ts.TypeFlags.Never ? stringType : indexType; } - function getTypeFromTypeOperatorNode(node: TypeOperatorNode): Type { + function getTypeFromTypeOperatorNode(node: ts.TypeOperatorNode): ts.Type { const links = getNodeLinks(node); if (!links.resolvedType) { switch (node.operator) { - case SyntaxKind.KeyOfKeyword: + case ts.SyntaxKind.KeyOfKeyword: links.resolvedType = getIndexType(getTypeFromTypeNode(node.type)); break; - case SyntaxKind.UniqueKeyword: - links.resolvedType = node.type.kind === SyntaxKind.SymbolKeyword - ? getESSymbolLikeTypeForNode(walkUpParenthesizedTypes(node.parent)) + case ts.SyntaxKind.UniqueKeyword: + links.resolvedType = node.type.kind === ts.SyntaxKind.SymbolKeyword + ? getESSymbolLikeTypeForNode(ts.walkUpParenthesizedTypes(node.parent)) : errorType; break; - case SyntaxKind.ReadonlyKeyword: + case ts.SyntaxKind.ReadonlyKeyword: links.resolvedType = getTypeFromTypeNode(node.type); break; default: - throw Debug.assertNever(node.operator); + throw ts.Debug.assertNever(node.operator); } } return links.resolvedType; } - function getTypeFromTemplateTypeNode(node: TemplateLiteralTypeNode) { + function getTypeFromTemplateTypeNode(node: ts.TemplateLiteralTypeNode) { const links = getNodeLinks(node); if (!links.resolvedType) { - links.resolvedType = getTemplateLiteralType( - [node.head.text, ...map(node.templateSpans, span => span.literal.text)], - map(node.templateSpans, span => getTypeFromTypeNode(span.type))); + links.resolvedType = getTemplateLiteralType([node.head.text, ...ts.map(node.templateSpans, span => span.literal.text)], ts.map(node.templateSpans, span => getTypeFromTypeNode(span.type))); } return links.resolvedType; } - function getTemplateLiteralType(texts: readonly string[], types: readonly Type[]): Type { - const unionIndex = findIndex(types, t => !!(t.flags & (TypeFlags.Never | TypeFlags.Union))); + function getTemplateLiteralType(texts: readonly string[], types: readonly ts.Type[]): ts.Type { + const unionIndex = ts.findIndex(types, t => !!(t.flags & (ts.TypeFlags.Never | ts.TypeFlags.Union))); if (unionIndex >= 0) { return checkCrossProductUnion(types) ? - mapType(types[unionIndex], t => getTemplateLiteralType(texts, replaceElement(types, unionIndex, t))) : + mapType(types[unionIndex], t => getTemplateLiteralType(texts, ts.replaceElement(types, unionIndex, t))) : errorType; } - if (contains(types, wildcardType)) { + if (ts.contains(types, wildcardType)) { return wildcardType; } - const newTypes: Type[] = []; + const newTypes: ts.Type[] = []; const newTexts: string[] = []; let text = texts[0]; if (!addSpans(texts, types)) { @@ -15316,40 +14831,44 @@ namespace ts { return getStringLiteralType(text); } newTexts.push(text); - if (every(newTexts, t => t === "") && every(newTypes, t => !!(t.flags & TypeFlags.String))) { + if (ts.every(newTexts, t => t === "") && ts.every(newTypes, t => !!(t.flags & ts.TypeFlags.String))) { return stringType; } - const id = `${getTypeListId(newTypes)}|${map(newTexts, t => t.length).join(",")}|${newTexts.join("")}`; + const id = `${getTypeListId(newTypes)}|${ts.map(newTexts, t => t.length).join(",")}|${newTexts.join("")}`; let type = templateLiteralTypes.get(id); if (!type) { templateLiteralTypes.set(id, type = createTemplateLiteralType(newTexts, newTypes)); } return type; - function addSpans(texts: readonly string[] | string, types: readonly Type[]): boolean { - const isTextsArray = isArray(texts); + function addSpans(texts: readonly string[] | string, types: readonly ts.Type[]): boolean { + const isTextsArray = ts.isArray(texts); for (let i = 0; i < types.length; i++) { const t = types[i]; const addText = isTextsArray ? texts[i + 1] : texts; - if (t.flags & (TypeFlags.Literal | TypeFlags.Null | TypeFlags.Undefined)) { + if (t.flags & (ts.TypeFlags.Literal | ts.TypeFlags.Null | ts.TypeFlags.Undefined)) { text += getTemplateStringForType(t) || ""; text += addText; - if (!isTextsArray) return true; + if (!isTextsArray) + return true; } - else if (t.flags & TypeFlags.TemplateLiteral) { - text += (t as TemplateLiteralType).texts[0]; - if (!addSpans((t as TemplateLiteralType).texts, (t as TemplateLiteralType).types)) return false; + else if (t.flags & ts.TypeFlags.TemplateLiteral) { + text += (t as ts.TemplateLiteralType).texts[0]; + if (!addSpans((t as ts.TemplateLiteralType).texts, (t as ts.TemplateLiteralType).types)) + return false; text += addText; - if (!isTextsArray) return true; + if (!isTextsArray) + return true; } else if (isGenericIndexType(t) || isPatternLiteralPlaceholderType(t)) { newTypes.push(t); newTexts.push(text); text = addText; } - else if (t.flags & TypeFlags.Intersection) { - const added = addSpans(texts[i + 1], (t as IntersectionType).types); - if (!added) return false; + else if (t.flags & ts.TypeFlags.Intersection) { + const added = addSpans(texts[i + 1], (t as ts.IntersectionType).types); + if (!added) + return false; } else if (isTextsArray) { return false; @@ -15359,29 +14878,29 @@ namespace ts { } } - function getTemplateStringForType(type: Type) { - return type.flags & TypeFlags.StringLiteral ? (type as StringLiteralType).value : - type.flags & TypeFlags.NumberLiteral ? "" + (type as NumberLiteralType).value : - type.flags & TypeFlags.BigIntLiteral ? pseudoBigIntToString((type as BigIntLiteralType).value) : - type.flags & (TypeFlags.BooleanLiteral | TypeFlags.Nullable) ? (type as IntrinsicType).intrinsicName : + function getTemplateStringForType(type: ts.Type) { + return type.flags & ts.TypeFlags.StringLiteral ? (type as ts.StringLiteralType).value : + type.flags & ts.TypeFlags.NumberLiteral ? "" + (type as ts.NumberLiteralType).value : + type.flags & ts.TypeFlags.BigIntLiteral ? ts.pseudoBigIntToString((type as ts.BigIntLiteralType).value) : + type.flags & (ts.TypeFlags.BooleanLiteral | ts.TypeFlags.Nullable) ? (type as ts.IntrinsicType).intrinsicName : undefined; } - function createTemplateLiteralType(texts: readonly string[], types: readonly Type[]) { - const type = createType(TypeFlags.TemplateLiteral) as TemplateLiteralType; + function createTemplateLiteralType(texts: readonly string[], types: readonly ts.Type[]) { + const type = createType(ts.TypeFlags.TemplateLiteral) as ts.TemplateLiteralType; type.texts = texts; type.types = types; return type; } - function getStringMappingType(symbol: Symbol, type: Type): Type { - return type.flags & (TypeFlags.Union | TypeFlags.Never) ? mapType(type, t => getStringMappingType(symbol, t)) : + function getStringMappingType(symbol: ts.Symbol, type: ts.Type): ts.Type { + return type.flags & (ts.TypeFlags.Union | ts.TypeFlags.Never) ? mapType(type, t => getStringMappingType(symbol, t)) : isGenericIndexType(type) ? getStringMappingTypeForGenericType(symbol, type) : - type.flags & TypeFlags.StringLiteral ? getStringLiteralType(applyStringMapping(symbol, (type as StringLiteralType).value)) : + type.flags & ts.TypeFlags.StringLiteral ? getStringLiteralType(applyStringMapping(symbol, (type as ts.StringLiteralType).value)) : type; } - function applyStringMapping(symbol: Symbol, str: string) { + function applyStringMapping(symbol: ts.Symbol, str: string) { switch (intrinsicTypeKinds.get(symbol.escapedName as string)) { case IntrinsicTypeKind.Uppercase: return str.toUpperCase(); case IntrinsicTypeKind.Lowercase: return str.toLowerCase(); @@ -15391,7 +14910,7 @@ namespace ts { return str; } - function getStringMappingTypeForGenericType(symbol: Symbol, type: Type): Type { + function getStringMappingTypeForGenericType(symbol: ts.Symbol, type: ts.Type): ts.Type { const id = `${getSymbolId(symbol)},${getTypeId(type)}`; let result = stringMappingTypes.get(id); if (!result) { @@ -15400,15 +14919,15 @@ namespace ts { return result; } - function createStringMappingType(symbol: Symbol, type: Type) { - const result = createType(TypeFlags.StringMapping) as StringMappingType; + function createStringMappingType(symbol: ts.Symbol, type: ts.Type) { + const result = createType(ts.TypeFlags.StringMapping) as ts.StringMappingType; result.symbol = symbol; result.type = type; return result; } - function createIndexedAccessType(objectType: Type, indexType: Type, accessFlags: AccessFlags, aliasSymbol: Symbol | undefined, aliasTypeArguments: readonly Type[] | undefined) { - const type = createType(TypeFlags.IndexedAccess) as IndexedAccessType; + function createIndexedAccessType(objectType: ts.Type, indexType: ts.Type, accessFlags: ts.AccessFlags, aliasSymbol: ts.Symbol | undefined, aliasTypeArguments: readonly ts.Type[] | undefined) { + const type = createType(ts.TypeFlags.IndexedAccess) as ts.IndexedAccessType; type.objectType = objectType; type.indexType = indexType; type.accessFlags = accessFlags; @@ -15426,67 +14945,67 @@ namespace ts { * Should all count as literals and not print errors on access or assignment of possibly existing properties. * This mirrors the behavior of the index signature propagation, to which this behaves similarly (but doesn't affect assignability or inference). */ - function isJSLiteralType(type: Type): boolean { + function isJSLiteralType(type: ts.Type): boolean { if (noImplicitAny) { return false; // Flag is meaningless under `noImplicitAny` mode } - if (getObjectFlags(type) & ObjectFlags.JSLiteral) { + if (ts.getObjectFlags(type) & ts.ObjectFlags.JSLiteral) { return true; } - if (type.flags & TypeFlags.Union) { - return every((type as UnionType).types, isJSLiteralType); + if (type.flags & ts.TypeFlags.Union) { + return ts.every((type as ts.UnionType).types, isJSLiteralType); } - if (type.flags & TypeFlags.Intersection) { - return some((type as IntersectionType).types, isJSLiteralType); + if (type.flags & ts.TypeFlags.Intersection) { + return ts.some((type as ts.IntersectionType).types, isJSLiteralType); } - if (type.flags & TypeFlags.Instantiable) { + if (type.flags & ts.TypeFlags.Instantiable) { const constraint = getResolvedBaseConstraint(type); return constraint !== type && isJSLiteralType(constraint); } return false; } - function getPropertyNameFromIndex(indexType: Type, accessNode: StringLiteral | Identifier | PrivateIdentifier | ObjectBindingPattern | ArrayBindingPattern | ComputedPropertyName | NumericLiteral | IndexedAccessTypeNode | ElementAccessExpression | SyntheticExpression | undefined) { + function getPropertyNameFromIndex(indexType: ts.Type, accessNode: ts.StringLiteral | ts.Identifier | ts.PrivateIdentifier | ts.ObjectBindingPattern | ts.ArrayBindingPattern | ts.ComputedPropertyName | ts.NumericLiteral | ts.IndexedAccessTypeNode | ts.ElementAccessExpression | ts.SyntheticExpression | undefined) { return isTypeUsableAsPropertyName(indexType) ? getPropertyNameFromType(indexType) : - accessNode && isPropertyName(accessNode) ? + accessNode && ts.isPropertyName(accessNode) ? // late bound names are handled in the first branch, so here we only need to handle normal names - getPropertyNameForPropertyNameNode(accessNode) : + ts.getPropertyNameForPropertyNameNode(accessNode) : undefined; } - function isUncalledFunctionReference(node: Node, symbol: Symbol) { - if (symbol.flags & (SymbolFlags.Function | SymbolFlags.Method)) { - const parent = findAncestor(node.parent, n => !isAccessExpression(n)) || node.parent; - if (isCallLikeExpression(parent)) { - return isCallOrNewExpression(parent) && isIdentifier(node) && hasMatchingArgument(parent, node); + function isUncalledFunctionReference(node: ts.Node, symbol: ts.Symbol) { + if (symbol.flags & (ts.SymbolFlags.Function | ts.SymbolFlags.Method)) { + const parent = ts.findAncestor(node.parent, n => !ts.isAccessExpression(n)) || node.parent; + if (ts.isCallLikeExpression(parent)) { + return ts.isCallOrNewExpression(parent) && ts.isIdentifier(node) && hasMatchingArgument(parent, node); } - return every(symbol.declarations, d => !isFunctionLike(d) || !!(getCombinedNodeFlags(d) & NodeFlags.Deprecated)); + return ts.every(symbol.declarations, d => !ts.isFunctionLike(d) || !!(ts.getCombinedNodeFlags(d) & ts.NodeFlags.Deprecated)); } return true; } - function getPropertyTypeForIndexType(originalObjectType: Type, objectType: Type, indexType: Type, fullIndexType: Type, accessNode: ElementAccessExpression | IndexedAccessTypeNode | PropertyName | BindingName | SyntheticExpression | undefined, accessFlags: AccessFlags) { - const accessExpression = accessNode && accessNode.kind === SyntaxKind.ElementAccessExpression ? accessNode : undefined; - const propName = accessNode && isPrivateIdentifier(accessNode) ? undefined : getPropertyNameFromIndex(indexType, accessNode); + function getPropertyTypeForIndexType(originalObjectType: ts.Type, objectType: ts.Type, indexType: ts.Type, fullIndexType: ts.Type, accessNode: ts.ElementAccessExpression | ts.IndexedAccessTypeNode | ts.PropertyName | ts.BindingName | ts.SyntheticExpression | undefined, accessFlags: ts.AccessFlags) { + const accessExpression = accessNode && accessNode.kind === ts.SyntaxKind.ElementAccessExpression ? accessNode : undefined; + const propName = accessNode && ts.isPrivateIdentifier(accessNode) ? undefined : getPropertyNameFromIndex(indexType, accessNode); if (propName !== undefined) { - if (accessFlags & AccessFlags.Contextual) { + if (accessFlags & ts.AccessFlags.Contextual) { return getTypeOfPropertyOfContextualType(objectType, propName) || anyType; } const prop = getPropertyOfType(objectType, propName); if (prop) { - if (accessFlags & AccessFlags.ReportDeprecated && accessNode && prop.declarations && isDeprecatedSymbol(prop) && isUncalledFunctionReference(accessNode, prop)) { - const deprecatedNode = accessExpression?.argumentExpression ?? (isIndexedAccessTypeNode(accessNode) ? accessNode.indexType : accessNode); + if (accessFlags & ts.AccessFlags.ReportDeprecated && accessNode && prop.declarations && isDeprecatedSymbol(prop) && isUncalledFunctionReference(accessNode, prop)) { + const deprecatedNode = accessExpression?.argumentExpression ?? (ts.isIndexedAccessTypeNode(accessNode) ? accessNode.indexType : accessNode); addDeprecatedSuggestion(deprecatedNode, prop.declarations, propName as string); } if (accessExpression) { markPropertyAsReferenced(prop, accessExpression, isSelfTypeAccess(accessExpression.expression, objectType.symbol)); - if (isAssignmentToReadonlyEntity(accessExpression, prop, getAssignmentTargetKind(accessExpression))) { - error(accessExpression.argumentExpression, Diagnostics.Cannot_assign_to_0_because_it_is_a_read_only_property, symbolToString(prop)); + if (isAssignmentToReadonlyEntity(accessExpression, prop, ts.getAssignmentTargetKind(accessExpression))) { + error(accessExpression.argumentExpression, ts.Diagnostics.Cannot_assign_to_0_because_it_is_a_read_only_property, symbolToString(prop)); return undefined; } - if (accessFlags & AccessFlags.CacheSymbol) { + if (accessFlags & ts.AccessFlags.CacheSymbol) { getNodeLinks(accessNode!).resolvedSymbol = prop; } if (isThisPropertyAccessInConstructor(accessExpression, prop)) { @@ -15494,51 +15013,50 @@ namespace ts { } } const propType = getTypeOfSymbol(prop); - return accessExpression && getAssignmentTargetKind(accessExpression) !== AssignmentKind.Definite ? + return accessExpression && ts.getAssignmentTargetKind(accessExpression) !== ts.AssignmentKind.Definite ? getFlowTypeOfReference(accessExpression, propType) : propType; } - if (everyType(objectType, isTupleType) && isNumericLiteralName(propName) && +propName >= 0) { - if (accessNode && everyType(objectType, t => !(t as TupleTypeReference).target.hasRestElement) && !(accessFlags & AccessFlags.NoTupleBoundsCheck)) { + if (everyType(objectType, isTupleType) && ts.isNumericLiteralName(propName) && +propName >= 0) { + if (accessNode && everyType(objectType, t => !(t as ts.TupleTypeReference).target.hasRestElement) && !(accessFlags & ts.AccessFlags.NoTupleBoundsCheck)) { const indexNode = getIndexNodeForAccessExpression(accessNode); if (isTupleType(objectType)) { - error(indexNode, Diagnostics.Tuple_type_0_of_length_1_has_no_element_at_index_2, - typeToString(objectType), getTypeReferenceArity(objectType), unescapeLeadingUnderscores(propName)); + error(indexNode, ts.Diagnostics.Tuple_type_0_of_length_1_has_no_element_at_index_2, typeToString(objectType), getTypeReferenceArity(objectType), ts.unescapeLeadingUnderscores(propName)); } else { - error(indexNode, Diagnostics.Property_0_does_not_exist_on_type_1, unescapeLeadingUnderscores(propName), typeToString(objectType)); + error(indexNode, ts.Diagnostics.Property_0_does_not_exist_on_type_1, ts.unescapeLeadingUnderscores(propName), typeToString(objectType)); } } errorIfWritingToReadonlyIndex(getIndexInfoOfType(objectType, numberType)); return mapType(objectType, t => { - const restType = getRestTypeOfTupleType(t as TupleTypeReference) || undefinedType; - return accessFlags & AccessFlags.IncludeUndefined ? getUnionType([restType, undefinedType]) : restType; + const restType = getRestTypeOfTupleType(t as ts.TupleTypeReference) || undefinedType; + return accessFlags & ts.AccessFlags.IncludeUndefined ? getUnionType([restType, undefinedType]) : restType; }); } } - if (!(indexType.flags & TypeFlags.Nullable) && isTypeAssignableToKind(indexType, TypeFlags.StringLike | TypeFlags.NumberLike | TypeFlags.ESSymbolLike)) { - if (objectType.flags & (TypeFlags.Any | TypeFlags.Never)) { + if (!(indexType.flags & ts.TypeFlags.Nullable) && isTypeAssignableToKind(indexType, ts.TypeFlags.StringLike | ts.TypeFlags.NumberLike | ts.TypeFlags.ESSymbolLike)) { + if (objectType.flags & (ts.TypeFlags.Any | ts.TypeFlags.Never)) { return objectType; } // If no index signature is applicable, we default to the string index signature. In effect, this means the string // index signature applies even when accessing with a symbol-like type. const indexInfo = getApplicableIndexInfo(objectType, indexType) || getIndexInfoOfType(objectType, stringType); if (indexInfo) { - if (accessFlags & AccessFlags.NoIndexSignatures && indexInfo.keyType !== numberType) { + if (accessFlags & ts.AccessFlags.NoIndexSignatures && indexInfo.keyType !== numberType) { if (accessExpression) { - error(accessExpression, Diagnostics.Type_0_cannot_be_used_to_index_type_1, typeToString(indexType), typeToString(originalObjectType)); + error(accessExpression, ts.Diagnostics.Type_0_cannot_be_used_to_index_type_1, typeToString(indexType), typeToString(originalObjectType)); } return undefined; } - if (accessNode && indexInfo.keyType === stringType && !isTypeAssignableToKind(indexType, TypeFlags.String | TypeFlags.Number)) { + if (accessNode && indexInfo.keyType === stringType && !isTypeAssignableToKind(indexType, ts.TypeFlags.String | ts.TypeFlags.Number)) { const indexNode = getIndexNodeForAccessExpression(accessNode); - error(indexNode, Diagnostics.Type_0_cannot_be_used_as_an_index_type, typeToString(indexType)); - return accessFlags & AccessFlags.IncludeUndefined ? getUnionType([indexInfo.type, undefinedType]) : indexInfo.type; + error(indexNode, ts.Diagnostics.Type_0_cannot_be_used_as_an_index_type, typeToString(indexType)); + return accessFlags & ts.AccessFlags.IncludeUndefined ? getUnionType([indexInfo.type, undefinedType]) : indexInfo.type; } errorIfWritingToReadonlyIndex(indexInfo); - return accessFlags & AccessFlags.IncludeUndefined ? getUnionType([indexInfo.type, undefinedType]) : indexInfo.type; + return accessFlags & ts.AccessFlags.IncludeUndefined ? getUnionType([indexInfo.type, undefinedType]) : indexInfo.type; } - if (indexType.flags & TypeFlags.Never) { + if (indexType.flags & ts.TypeFlags.Never) { return neverType; } if (isJSLiteralType(objectType)) { @@ -15546,65 +15064,62 @@ namespace ts { } if (accessExpression && !isConstEnumObjectType(objectType)) { if (isObjectLiteralType(objectType)) { - if (noImplicitAny && indexType.flags & (TypeFlags.StringLiteral | TypeFlags.NumberLiteral)) { - diagnostics.add(createDiagnosticForNode(accessExpression, Diagnostics.Property_0_does_not_exist_on_type_1, (indexType as StringLiteralType).value, typeToString(objectType))); + if (noImplicitAny && indexType.flags & (ts.TypeFlags.StringLiteral | ts.TypeFlags.NumberLiteral)) { + diagnostics.add(ts.createDiagnosticForNode(accessExpression, ts.Diagnostics.Property_0_does_not_exist_on_type_1, (indexType as ts.StringLiteralType).value, typeToString(objectType))); return undefinedType; } - else if (indexType.flags & (TypeFlags.Number | TypeFlags.String)) { - const types = map((objectType as ResolvedType).properties, property => { + else if (indexType.flags & (ts.TypeFlags.Number | ts.TypeFlags.String)) { + const types = ts.map((objectType as ts.ResolvedType).properties, property => { return getTypeOfSymbol(property); }); - return getUnionType(append(types, undefinedType)); + return getUnionType(ts.append(types, undefinedType)); } } - if (objectType.symbol === globalThisSymbol && propName !== undefined && globalThisSymbol.exports!.has(propName) && (globalThisSymbol.exports!.get(propName)!.flags & SymbolFlags.BlockScoped)) { - error(accessExpression, Diagnostics.Property_0_does_not_exist_on_type_1, unescapeLeadingUnderscores(propName), typeToString(objectType)); + if (objectType.symbol === globalThisSymbol && propName !== undefined && globalThisSymbol.exports!.has(propName) && (globalThisSymbol.exports!.get(propName)!.flags & ts.SymbolFlags.BlockScoped)) { + error(accessExpression, ts.Diagnostics.Property_0_does_not_exist_on_type_1, ts.unescapeLeadingUnderscores(propName), typeToString(objectType)); } - else if (noImplicitAny && !compilerOptions.suppressImplicitAnyIndexErrors && !(accessFlags & AccessFlags.SuppressNoImplicitAnyError)) { + else if (noImplicitAny && !compilerOptions.suppressImplicitAnyIndexErrors && !(accessFlags & ts.AccessFlags.SuppressNoImplicitAnyError)) { if (propName !== undefined && typeHasStaticProperty(propName, objectType)) { const typeName = typeToString(objectType); - error(accessExpression, Diagnostics.Property_0_does_not_exist_on_type_1_Did_you_mean_to_access_the_static_member_2_instead, propName as string, typeName, typeName + "[" + getTextOfNode(accessExpression.argumentExpression) + "]"); + error(accessExpression, ts.Diagnostics.Property_0_does_not_exist_on_type_1_Did_you_mean_to_access_the_static_member_2_instead, propName as string, typeName, typeName + "[" + ts.getTextOfNode(accessExpression.argumentExpression) + "]"); } else if (getIndexTypeOfType(objectType, numberType)) { - error(accessExpression.argumentExpression, Diagnostics.Element_implicitly_has_an_any_type_because_index_expression_is_not_of_type_number); + error(accessExpression.argumentExpression, ts.Diagnostics.Element_implicitly_has_an_any_type_because_index_expression_is_not_of_type_number); } else { let suggestion: string | undefined; if (propName !== undefined && (suggestion = getSuggestionForNonexistentProperty(propName as string, objectType))) { if (suggestion !== undefined) { - error(accessExpression.argumentExpression, Diagnostics.Property_0_does_not_exist_on_type_1_Did_you_mean_2, propName as string, typeToString(objectType), suggestion); + error(accessExpression.argumentExpression, ts.Diagnostics.Property_0_does_not_exist_on_type_1_Did_you_mean_2, propName as string, typeToString(objectType), suggestion); } } else { const suggestion = getSuggestionForNonexistentIndexSignature(objectType, accessExpression, indexType); if (suggestion !== undefined) { - error(accessExpression, Diagnostics.Element_implicitly_has_an_any_type_because_type_0_has_no_index_signature_Did_you_mean_to_call_1, typeToString(objectType), suggestion); + error(accessExpression, ts.Diagnostics.Element_implicitly_has_an_any_type_because_type_0_has_no_index_signature_Did_you_mean_to_call_1, typeToString(objectType), suggestion); } else { - let errorInfo: DiagnosticMessageChain | undefined; - if (indexType.flags & TypeFlags.EnumLiteral) { - errorInfo = chainDiagnosticMessages(/* details */ undefined, Diagnostics.Property_0_does_not_exist_on_type_1, "[" + typeToString(indexType) + "]", typeToString(objectType)); + let errorInfo: ts.DiagnosticMessageChain | undefined; + if (indexType.flags & ts.TypeFlags.EnumLiteral) { + errorInfo = ts.chainDiagnosticMessages(/* details */ undefined, ts.Diagnostics.Property_0_does_not_exist_on_type_1, "[" + typeToString(indexType) + "]", typeToString(objectType)); } - else if (indexType.flags & TypeFlags.UniqueESSymbol) { - const symbolName = getFullyQualifiedName((indexType as UniqueESSymbolType).symbol, accessExpression); - errorInfo = chainDiagnosticMessages(/* details */ undefined, Diagnostics.Property_0_does_not_exist_on_type_1, "[" + symbolName + "]", typeToString(objectType)); + else if (indexType.flags & ts.TypeFlags.UniqueESSymbol) { + const symbolName = getFullyQualifiedName((indexType as ts.UniqueESSymbolType).symbol, accessExpression); + errorInfo = ts.chainDiagnosticMessages(/* details */ undefined, ts.Diagnostics.Property_0_does_not_exist_on_type_1, "[" + symbolName + "]", typeToString(objectType)); } - else if (indexType.flags & TypeFlags.StringLiteral) { - errorInfo = chainDiagnosticMessages(/* details */ undefined, Diagnostics.Property_0_does_not_exist_on_type_1, (indexType as StringLiteralType).value, typeToString(objectType)); + else if (indexType.flags & ts.TypeFlags.StringLiteral) { + errorInfo = ts.chainDiagnosticMessages(/* details */ undefined, ts.Diagnostics.Property_0_does_not_exist_on_type_1, (indexType as ts.StringLiteralType).value, typeToString(objectType)); } - else if (indexType.flags & TypeFlags.NumberLiteral) { - errorInfo = chainDiagnosticMessages(/* details */ undefined, Diagnostics.Property_0_does_not_exist_on_type_1, (indexType as NumberLiteralType).value, typeToString(objectType)); + else if (indexType.flags & ts.TypeFlags.NumberLiteral) { + errorInfo = ts.chainDiagnosticMessages(/* details */ undefined, ts.Diagnostics.Property_0_does_not_exist_on_type_1, (indexType as ts.NumberLiteralType).value, typeToString(objectType)); } - else if (indexType.flags & (TypeFlags.Number | TypeFlags.String)) { - errorInfo = chainDiagnosticMessages(/* details */ undefined, Diagnostics.No_index_signature_with_a_parameter_of_type_0_was_found_on_type_1, typeToString(indexType), typeToString(objectType)); + else if (indexType.flags & (ts.TypeFlags.Number | ts.TypeFlags.String)) { + errorInfo = ts.chainDiagnosticMessages(/* details */ undefined, ts.Diagnostics.No_index_signature_with_a_parameter_of_type_0_was_found_on_type_1, typeToString(indexType), typeToString(objectType)); } - errorInfo = chainDiagnosticMessages( - errorInfo, - Diagnostics.Element_implicitly_has_an_any_type_because_expression_of_type_0_can_t_be_used_to_index_type_1, typeToString(fullIndexType), typeToString(objectType) - ); - diagnostics.add(createDiagnosticForNodeFromMessageChain(accessExpression, errorInfo)); + errorInfo = ts.chainDiagnosticMessages(errorInfo, ts.Diagnostics.Element_implicitly_has_an_any_type_because_expression_of_type_0_can_t_be_used_to_index_type_1, typeToString(fullIndexType), typeToString(objectType)); + diagnostics.add(ts.createDiagnosticForNodeFromMessageChain(accessExpression, errorInfo)); } } } @@ -15617,14 +15132,14 @@ namespace ts { } if (accessNode) { const indexNode = getIndexNodeForAccessExpression(accessNode); - if (indexType.flags & (TypeFlags.StringLiteral | TypeFlags.NumberLiteral)) { - error(indexNode, Diagnostics.Property_0_does_not_exist_on_type_1, "" + (indexType as StringLiteralType | NumberLiteralType).value, typeToString(objectType)); + if (indexType.flags & (ts.TypeFlags.StringLiteral | ts.TypeFlags.NumberLiteral)) { + error(indexNode, ts.Diagnostics.Property_0_does_not_exist_on_type_1, "" + (indexType as ts.StringLiteralType | ts.NumberLiteralType).value, typeToString(objectType)); } - else if (indexType.flags & (TypeFlags.String | TypeFlags.Number)) { - error(indexNode, Diagnostics.Type_0_has_no_matching_index_signature_for_type_1, typeToString(objectType), typeToString(indexType)); + else if (indexType.flags & (ts.TypeFlags.String | ts.TypeFlags.Number)) { + error(indexNode, ts.Diagnostics.Type_0_has_no_matching_index_signature_for_type_1, typeToString(objectType), typeToString(indexType)); } else { - error(indexNode, Diagnostics.Type_0_cannot_be_used_as_an_index_type, typeToString(indexType)); + error(indexNode, ts.Diagnostics.Type_0_cannot_be_used_as_an_index_type, typeToString(indexType)); } } if (isTypeAny(indexType)) { @@ -15632,80 +15147,80 @@ namespace ts { } return undefined; - function errorIfWritingToReadonlyIndex(indexInfo: IndexInfo | undefined): void { - if (indexInfo && indexInfo.isReadonly && accessExpression && (isAssignmentTarget(accessExpression) || isDeleteTarget(accessExpression))) { - error(accessExpression, Diagnostics.Index_signature_in_type_0_only_permits_reading, typeToString(objectType)); + function errorIfWritingToReadonlyIndex(indexInfo: ts.IndexInfo | undefined): void { + if (indexInfo && indexInfo.isReadonly && accessExpression && (ts.isAssignmentTarget(accessExpression) || ts.isDeleteTarget(accessExpression))) { + error(accessExpression, ts.Diagnostics.Index_signature_in_type_0_only_permits_reading, typeToString(objectType)); } } } - function getIndexNodeForAccessExpression(accessNode: ElementAccessExpression | IndexedAccessTypeNode | PropertyName | BindingName | SyntheticExpression) { - return accessNode.kind === SyntaxKind.ElementAccessExpression ? accessNode.argumentExpression : - accessNode.kind === SyntaxKind.IndexedAccessType ? accessNode.indexType : - accessNode.kind === SyntaxKind.ComputedPropertyName ? accessNode.expression : + function getIndexNodeForAccessExpression(accessNode: ts.ElementAccessExpression | ts.IndexedAccessTypeNode | ts.PropertyName | ts.BindingName | ts.SyntheticExpression) { + return accessNode.kind === ts.SyntaxKind.ElementAccessExpression ? accessNode.argumentExpression : + accessNode.kind === ts.SyntaxKind.IndexedAccessType ? accessNode.indexType : + accessNode.kind === ts.SyntaxKind.ComputedPropertyName ? accessNode.expression : accessNode; } - function isPatternLiteralPlaceholderType(type: Type) { - return !!(type.flags & (TypeFlags.Any | TypeFlags.String | TypeFlags.Number | TypeFlags.BigInt)); + function isPatternLiteralPlaceholderType(type: ts.Type) { + return !!(type.flags & (ts.TypeFlags.Any | ts.TypeFlags.String | ts.TypeFlags.Number | ts.TypeFlags.BigInt)); } - function isPatternLiteralType(type: Type) { - return !!(type.flags & TypeFlags.TemplateLiteral) && every((type as TemplateLiteralType).types, isPatternLiteralPlaceholderType); + function isPatternLiteralType(type: ts.Type) { + return !!(type.flags & ts.TypeFlags.TemplateLiteral) && ts.every((type as ts.TemplateLiteralType).types, isPatternLiteralPlaceholderType); } - function isGenericType(type: Type): boolean { + function isGenericType(type: ts.Type): boolean { return !!getGenericObjectFlags(type); } - function isGenericObjectType(type: Type): boolean { - return !!(getGenericObjectFlags(type) & ObjectFlags.IsGenericObjectType); + function isGenericObjectType(type: ts.Type): boolean { + return !!(getGenericObjectFlags(type) & ts.ObjectFlags.IsGenericObjectType); } - function isGenericIndexType(type: Type): boolean { - return !!(getGenericObjectFlags(type) & ObjectFlags.IsGenericIndexType); + function isGenericIndexType(type: ts.Type): boolean { + return !!(getGenericObjectFlags(type) & ts.ObjectFlags.IsGenericIndexType); } - function getGenericObjectFlags(type: Type): ObjectFlags { - if (type.flags & TypeFlags.UnionOrIntersection) { - if (!((type as UnionOrIntersectionType).objectFlags & ObjectFlags.IsGenericTypeComputed)) { - (type as UnionOrIntersectionType).objectFlags |= ObjectFlags.IsGenericTypeComputed | - reduceLeft((type as UnionOrIntersectionType).types, (flags, t) => flags | getGenericObjectFlags(t), 0); + function getGenericObjectFlags(type: ts.Type): ts.ObjectFlags { + if (type.flags & ts.TypeFlags.UnionOrIntersection) { + if (!((type as ts.UnionOrIntersectionType).objectFlags & ts.ObjectFlags.IsGenericTypeComputed)) { + (type as ts.UnionOrIntersectionType).objectFlags |= ts.ObjectFlags.IsGenericTypeComputed | + ts.reduceLeft((type as ts.UnionOrIntersectionType).types, (flags, t) => flags | getGenericObjectFlags(t), 0); } - return (type as UnionOrIntersectionType).objectFlags & ObjectFlags.IsGenericType; + return (type as ts.UnionOrIntersectionType).objectFlags & ts.ObjectFlags.IsGenericType; } - if (type.flags & TypeFlags.Substitution) { - if (!((type as SubstitutionType).objectFlags & ObjectFlags.IsGenericTypeComputed)) { - (type as SubstitutionType).objectFlags |= ObjectFlags.IsGenericTypeComputed | - getGenericObjectFlags((type as SubstitutionType).substitute) | getGenericObjectFlags((type as SubstitutionType).baseType); + if (type.flags & ts.TypeFlags.Substitution) { + if (!((type as ts.SubstitutionType).objectFlags & ts.ObjectFlags.IsGenericTypeComputed)) { + (type as ts.SubstitutionType).objectFlags |= ts.ObjectFlags.IsGenericTypeComputed | + getGenericObjectFlags((type as ts.SubstitutionType).substitute) | getGenericObjectFlags((type as ts.SubstitutionType).baseType); } - return (type as SubstitutionType).objectFlags & ObjectFlags.IsGenericType; + return (type as ts.SubstitutionType).objectFlags & ts.ObjectFlags.IsGenericType; } - return (type.flags & TypeFlags.InstantiableNonPrimitive || isGenericMappedType(type) || isGenericTupleType(type) ? ObjectFlags.IsGenericObjectType : 0) | - (type.flags & (TypeFlags.InstantiableNonPrimitive | TypeFlags.Index | TypeFlags.TemplateLiteral | TypeFlags.StringMapping) && !isPatternLiteralType(type) ? ObjectFlags.IsGenericIndexType : 0); + return (type.flags & ts.TypeFlags.InstantiableNonPrimitive || isGenericMappedType(type) || isGenericTupleType(type) ? ts.ObjectFlags.IsGenericObjectType : 0) | + (type.flags & (ts.TypeFlags.InstantiableNonPrimitive | ts.TypeFlags.Index | ts.TypeFlags.TemplateLiteral | ts.TypeFlags.StringMapping) && !isPatternLiteralType(type) ? ts.ObjectFlags.IsGenericIndexType : 0); } - function getSimplifiedType(type: Type, writing: boolean): Type { - return type.flags & TypeFlags.IndexedAccess ? getSimplifiedIndexedAccessType(type as IndexedAccessType, writing) : - type.flags & TypeFlags.Conditional ? getSimplifiedConditionalType(type as ConditionalType, writing) : + function getSimplifiedType(type: ts.Type, writing: boolean): ts.Type { + return type.flags & ts.TypeFlags.IndexedAccess ? getSimplifiedIndexedAccessType(type as ts.IndexedAccessType, writing) : + type.flags & ts.TypeFlags.Conditional ? getSimplifiedConditionalType(type as ts.ConditionalType, writing) : type; } - function distributeIndexOverObjectType(objectType: Type, indexType: Type, writing: boolean) { + function distributeIndexOverObjectType(objectType: ts.Type, indexType: ts.Type, writing: boolean) { // (T | U)[K] -> T[K] | U[K] (reading) // (T | U)[K] -> T[K] & U[K] (writing) // (T & U)[K] -> T[K] & U[K] - if (objectType.flags & TypeFlags.UnionOrIntersection) { - const types = map((objectType as UnionOrIntersectionType).types, t => getSimplifiedType(getIndexedAccessType(t, indexType), writing)); - return objectType.flags & TypeFlags.Intersection || writing ? getIntersectionType(types) : getUnionType(types); + if (objectType.flags & ts.TypeFlags.UnionOrIntersection) { + const types = ts.map((objectType as ts.UnionOrIntersectionType).types, t => getSimplifiedType(getIndexedAccessType(t, indexType), writing)); + return objectType.flags & ts.TypeFlags.Intersection || writing ? getIntersectionType(types) : getUnionType(types); } } - function distributeObjectOverIndexType(objectType: Type, indexType: Type, writing: boolean) { + function distributeObjectOverIndexType(objectType: ts.Type, indexType: ts.Type, writing: boolean) { // T[A | B] -> T[A] | T[B] (reading) // T[A | B] -> T[A] & T[B] (writing) - if (indexType.flags & TypeFlags.Union) { - const types = map((indexType as UnionType).types, t => getSimplifiedType(getIndexedAccessType(objectType, t), writing)); + if (indexType.flags & ts.TypeFlags.Union) { + const types = ts.map((indexType as ts.UnionType).types, t => getSimplifiedType(getIndexedAccessType(objectType, t), writing)); return writing ? getIntersectionType(types) : getUnionType(types); } } @@ -15713,7 +15228,7 @@ namespace ts { // Transform an indexed access to a simpler form, if possible. Return the simpler form, or return // the type itself if no transformation is possible. The writing flag indicates that the type is // the target of an assignment. - function getSimplifiedIndexedAccessType(type: IndexedAccessType, writing: boolean): Type { + function getSimplifiedIndexedAccessType(type: ts.IndexedAccessType, writing: boolean): ts.Type { const cache = writing ? "simplifiedForWriting" : "simplifiedForReading"; if (type[cache]) { return type[cache] === circularConstraintType ? type : type[cache]!; @@ -15730,7 +15245,7 @@ namespace ts { return type[cache] = distributedOverIndex; } // Only do the inner distributions if the index can no longer be instantiated to cause index distribution again - if (!(indexType.flags & TypeFlags.Instantiable)) { + if (!(indexType.flags & ts.TypeFlags.Instantiable)) { // (T | U)[K] -> T[K] | U[K] (reading) // (T | U)[K] -> T[K] & U[K] (writing) // (T & U)[K] -> T[K] & U[K] @@ -15745,8 +15260,8 @@ namespace ts { // A generic tuple type indexed by a number exists only when the index type doesn't select a // fixed element. We simplify to either the combined type of all elements (when the index type // the actual number type) or to the combined type of all non-fixed elements. - if (isGenericTupleType(objectType) && indexType.flags & TypeFlags.NumberLike) { - const elementType = getElementTypeOfSliceOfTupleType(objectType, indexType.flags & TypeFlags.Number ? 0 : objectType.target.fixedLength, /*endSkipCount*/ 0, writing); + if (isGenericTupleType(objectType) && indexType.flags & ts.TypeFlags.NumberLike) { + const elementType = getElementTypeOfSliceOfTupleType(objectType, indexType.flags & ts.TypeFlags.Number ? 0 : objectType.target.fixedLength, /*endSkipCount*/ 0, writing); if (elementType) { return type[cache] = elementType; } @@ -15763,25 +15278,25 @@ namespace ts { return type[cache] = type; } - function getSimplifiedConditionalType(type: ConditionalType, writing: boolean) { + function getSimplifiedConditionalType(type: ts.ConditionalType, writing: boolean) { const checkType = type.checkType; const extendsType = type.extendsType; const trueType = getTrueTypeFromConditionalType(type); const falseType = getFalseTypeFromConditionalType(type); // Simplifications for types of the form `T extends U ? T : never` and `T extends U ? never : T`. - if (falseType.flags & TypeFlags.Never && getActualTypeVariable(trueType) === getActualTypeVariable(checkType)) { - if (checkType.flags & TypeFlags.Any || isTypeAssignableTo(getRestrictiveInstantiation(checkType), getRestrictiveInstantiation(extendsType))) { // Always true + if (falseType.flags & ts.TypeFlags.Never && getActualTypeVariable(trueType) === getActualTypeVariable(checkType)) { + if (checkType.flags & ts.TypeFlags.Any || isTypeAssignableTo(getRestrictiveInstantiation(checkType), getRestrictiveInstantiation(extendsType))) { // Always true return getSimplifiedType(trueType, writing); } else if (isIntersectionEmpty(checkType, extendsType)) { // Always false return neverType; } } - else if (trueType.flags & TypeFlags.Never && getActualTypeVariable(falseType) === getActualTypeVariable(checkType)) { - if (!(checkType.flags & TypeFlags.Any) && isTypeAssignableTo(getRestrictiveInstantiation(checkType), getRestrictiveInstantiation(extendsType))) { // Always true + else if (trueType.flags & ts.TypeFlags.Never && getActualTypeVariable(falseType) === getActualTypeVariable(checkType)) { + if (!(checkType.flags & ts.TypeFlags.Any) && isTypeAssignableTo(getRestrictiveInstantiation(checkType), getRestrictiveInstantiation(extendsType))) { // Always true return neverType; } - else if (checkType.flags & TypeFlags.Any || isIntersectionEmpty(checkType, extendsType)) { // Always false + else if (checkType.flags & ts.TypeFlags.Any || isIntersectionEmpty(checkType, extendsType)) { // Always false return getSimplifiedType(falseType, writing); } } @@ -15791,25 +15306,25 @@ namespace ts { /** * Invokes union simplification logic to determine if an intersection is considered empty as a union constituent */ - function isIntersectionEmpty(type1: Type, type2: Type) { - return !!(getUnionType([intersectTypes(type1, type2), neverType]).flags & TypeFlags.Never); + function isIntersectionEmpty(type1: ts.Type, type2: ts.Type) { + return !!(getUnionType([intersectTypes(type1, type2), neverType]).flags & ts.TypeFlags.Never); } - function substituteIndexedMappedType(objectType: MappedType, index: Type) { + function substituteIndexedMappedType(objectType: ts.MappedType, index: ts.Type) { const mapper = createTypeMapper([getTypeParameterFromMappedType(objectType)], [index]); const templateMapper = combineTypeMappers(objectType.mapper, mapper); return instantiateType(getTemplateTypeFromMappedType(objectType), templateMapper); } - function getIndexedAccessType(objectType: Type, indexType: Type, accessFlags = AccessFlags.None, accessNode?: ElementAccessExpression | IndexedAccessTypeNode | PropertyName | BindingName | SyntheticExpression, aliasSymbol?: Symbol, aliasTypeArguments?: readonly Type[]): Type { + function getIndexedAccessType(objectType: ts.Type, indexType: ts.Type, accessFlags = ts.AccessFlags.None, accessNode?: ts.ElementAccessExpression | ts.IndexedAccessTypeNode | ts.PropertyName | ts.BindingName | ts.SyntheticExpression, aliasSymbol?: ts.Symbol, aliasTypeArguments?: readonly ts.Type[]): ts.Type { return getIndexedAccessTypeOrUndefined(objectType, indexType, accessFlags, accessNode, aliasSymbol, aliasTypeArguments) || (accessNode ? errorType : unknownType); } - function indexTypeLessThan(indexType: Type, limit: number) { + function indexTypeLessThan(indexType: ts.Type, limit: number) { return everyType(indexType, t => { - if (t.flags & TypeFlags.StringOrNumberLiteral) { - const propName = getPropertyNameFromType(t as StringLiteralType | NumberLiteralType); - if (isNumericLiteralName(propName)) { + if (t.flags & ts.TypeFlags.StringOrNumberLiteral) { + const propName = getPropertyNameFromType(t as ts.StringLiteralType | ts.NumberLiteralType); + if (ts.isNumericLiteralName(propName)) { const index = +propName; return index >= 0 && index < limit; } @@ -15818,32 +15333,33 @@ namespace ts { }); } - function getIndexedAccessTypeOrUndefined(objectType: Type, indexType: Type, accessFlags = AccessFlags.None, accessNode?: ElementAccessExpression | IndexedAccessTypeNode | PropertyName | BindingName | SyntheticExpression, aliasSymbol?: Symbol, aliasTypeArguments?: readonly Type[]): Type | undefined { + function getIndexedAccessTypeOrUndefined(objectType: ts.Type, indexType: ts.Type, accessFlags = ts.AccessFlags.None, accessNode?: ts.ElementAccessExpression | ts.IndexedAccessTypeNode | ts.PropertyName | ts.BindingName | ts.SyntheticExpression, aliasSymbol?: ts.Symbol, aliasTypeArguments?: readonly ts.Type[]): ts.Type | undefined { if (objectType === wildcardType || indexType === wildcardType) { return wildcardType; } // If the object type has a string index signature and no other members we know that the result will // always be the type of that index signature and we can simplify accordingly. - if (isStringIndexSignatureOnlyType(objectType) && !(indexType.flags & TypeFlags.Nullable) && isTypeAssignableToKind(indexType, TypeFlags.String | TypeFlags.Number)) { + if (isStringIndexSignatureOnlyType(objectType) && !(indexType.flags & ts.TypeFlags.Nullable) && isTypeAssignableToKind(indexType, ts.TypeFlags.String | ts.TypeFlags.Number)) { indexType = stringType; } // In noUncheckedIndexedAccess mode, indexed access operations that occur in an expression in a read position and resolve to // an index signature have 'undefined' included in their type. - if (compilerOptions.noUncheckedIndexedAccess && accessFlags & AccessFlags.ExpressionPosition) accessFlags |= AccessFlags.IncludeUndefined; + if (compilerOptions.noUncheckedIndexedAccess && accessFlags & ts.AccessFlags.ExpressionPosition) + accessFlags |= ts.AccessFlags.IncludeUndefined; // If the index type is generic, or if the object type is generic and doesn't originate in an expression and // the operation isn't exclusively indexing the fixed (non-variadic) portion of a tuple type, we are performing // a higher-order index access where we cannot meaningfully access the properties of the object type. Note that // for a generic T and a non-generic K, we eagerly resolve T[K] if it originates in an expression. This is to // preserve backwards compatibility. For example, an element access 'this["foo"]' has always been resolved // eagerly using the constraint type of 'this' at the given location. - if (isGenericIndexType(indexType) || (accessNode && accessNode.kind !== SyntaxKind.IndexedAccessType ? + if (isGenericIndexType(indexType) || (accessNode && accessNode.kind !== ts.SyntaxKind.IndexedAccessType ? isGenericTupleType(objectType) && !indexTypeLessThan(indexType, objectType.target.fixedLength) : isGenericObjectType(objectType) && !(isTupleType(objectType) && indexTypeLessThan(indexType, objectType.target.fixedLength)))) { - if (objectType.flags & TypeFlags.AnyOrUnknown) { + if (objectType.flags & ts.TypeFlags.AnyOrUnknown) { return objectType; } // Defer the operation by creating an indexed access type. - const persistentAccessFlags = accessFlags & AccessFlags.Persistent; + const persistentAccessFlags = accessFlags & ts.AccessFlags.Persistent; const id = objectType.id + "," + indexType.id + "," + persistentAccessFlags + getAliasId(aliasSymbol, aliasTypeArguments); let type = indexedAccessTypes.get(id); if (!type) { @@ -15856,11 +15372,11 @@ namespace ts { // We treat boolean as different from other unions to improve errors; // skipping straight to getPropertyTypeForIndexType gives errors with 'boolean' instead of 'true'. const apparentObjectType = getReducedApparentType(objectType); - if (indexType.flags & TypeFlags.Union && !(indexType.flags & TypeFlags.Boolean)) { - const propTypes: Type[] = []; + if (indexType.flags & ts.TypeFlags.Union && !(indexType.flags & ts.TypeFlags.Boolean)) { + const propTypes: ts.Type[] = []; let wasMissingProp = false; - for (const t of (indexType as UnionType).types) { - const propType = getPropertyTypeForIndexType(objectType, apparentObjectType, t, indexType, accessNode, accessFlags | (wasMissingProp ? AccessFlags.SuppressNoImplicitAnyError : 0)); + for (const t of (indexType as ts.UnionType).types) { + const propType = getPropertyTypeForIndexType(objectType, apparentObjectType, t, indexType, accessNode, accessFlags | (wasMissingProp ? ts.AccessFlags.SuppressNoImplicitAnyError : 0)); if (propType) { propTypes.push(propType); } @@ -15876,32 +15392,32 @@ namespace ts { if (wasMissingProp) { return undefined; } - return accessFlags & AccessFlags.Writing + return accessFlags & ts.AccessFlags.Writing ? getIntersectionType(propTypes, aliasSymbol, aliasTypeArguments) - : getUnionType(propTypes, UnionReduction.Literal, aliasSymbol, aliasTypeArguments); + : getUnionType(propTypes, ts.UnionReduction.Literal, aliasSymbol, aliasTypeArguments); } - return getPropertyTypeForIndexType(objectType, apparentObjectType, indexType, indexType, accessNode, accessFlags | AccessFlags.CacheSymbol | AccessFlags.ReportDeprecated); + return getPropertyTypeForIndexType(objectType, apparentObjectType, indexType, indexType, accessNode, accessFlags | ts.AccessFlags.CacheSymbol | ts.AccessFlags.ReportDeprecated); } - function getTypeFromIndexedAccessTypeNode(node: IndexedAccessTypeNode) { + function getTypeFromIndexedAccessTypeNode(node: ts.IndexedAccessTypeNode) { const links = getNodeLinks(node); if (!links.resolvedType) { const objectType = getTypeFromTypeNode(node.objectType); const indexType = getTypeFromTypeNode(node.indexType); const potentialAlias = getAliasSymbolForTypeNode(node); - const resolved = getIndexedAccessType(objectType, indexType, AccessFlags.None, node, potentialAlias, getTypeArgumentsForAliasSymbol(potentialAlias)); - links.resolvedType = resolved.flags & TypeFlags.IndexedAccess && - (resolved as IndexedAccessType).objectType === objectType && - (resolved as IndexedAccessType).indexType === indexType ? + const resolved = getIndexedAccessType(objectType, indexType, ts.AccessFlags.None, node, potentialAlias, getTypeArgumentsForAliasSymbol(potentialAlias)); + links.resolvedType = resolved.flags & ts.TypeFlags.IndexedAccess && + (resolved as ts.IndexedAccessType).objectType === objectType && + (resolved as ts.IndexedAccessType).indexType === indexType ? getConditionalFlowTypeOfType(resolved, node) : resolved; } return links.resolvedType; } - function getTypeFromMappedTypeNode(node: MappedTypeNode): Type { + function getTypeFromMappedTypeNode(node: ts.MappedTypeNode): ts.Type { const links = getNodeLinks(node); if (!links.resolvedType) { - const type = createObjectType(ObjectFlags.Mapped, node.symbol) as MappedType; + const type = createObjectType(ts.ObjectFlags.Mapped, node.symbol) as ts.MappedType; type.declaration = node; type.aliasSymbol = getAliasSymbolForTypeNode(node); type.aliasTypeArguments = getTypeArgumentsForAliasSymbol(type.aliasSymbol); @@ -15913,33 +15429,32 @@ namespace ts { return links.resolvedType; } - function getActualTypeVariable(type: Type): Type { - if (type.flags & TypeFlags.Substitution) { - return (type as SubstitutionType).baseType; + function getActualTypeVariable(type: ts.Type): ts.Type { + if (type.flags & ts.TypeFlags.Substitution) { + return (type as ts.SubstitutionType).baseType; } - if (type.flags & TypeFlags.IndexedAccess && ( - (type as IndexedAccessType).objectType.flags & TypeFlags.Substitution || - (type as IndexedAccessType).indexType.flags & TypeFlags.Substitution)) { - return getIndexedAccessType(getActualTypeVariable((type as IndexedAccessType).objectType), getActualTypeVariable((type as IndexedAccessType).indexType)); + if (type.flags & ts.TypeFlags.IndexedAccess && ((type as ts.IndexedAccessType).objectType.flags & ts.TypeFlags.Substitution || + (type as ts.IndexedAccessType).indexType.flags & ts.TypeFlags.Substitution)) { + return getIndexedAccessType(getActualTypeVariable((type as ts.IndexedAccessType).objectType), getActualTypeVariable((type as ts.IndexedAccessType).indexType)); } return type; } - function maybeCloneTypeParameter(p: TypeParameter) { + function maybeCloneTypeParameter(p: ts.TypeParameter) { const constraint = getConstraintOfTypeParameter(p); return constraint && (isGenericObjectType(constraint) || isGenericIndexType(constraint)) ? cloneTypeParameter(p) : p; } - function isTypicalNondistributiveConditional(root: ConditionalRoot) { + function isTypicalNondistributiveConditional(root: ts.ConditionalRoot) { return !root.isDistributive && isSingletonTupleType(root.node.checkType) && isSingletonTupleType(root.node.extendsType); } - function isSingletonTupleType(node: TypeNode) { - return isTupleTypeNode(node) && - length(node.elements) === 1 && - !isOptionalTypeNode(node.elements[0]) && - !isRestTypeNode(node.elements[0]) && - !(isNamedTupleMember(node.elements[0]) && (node.elements[0].questionToken || node.elements[0].dotDotDotToken)); + function isSingletonTupleType(node: ts.TypeNode) { + return ts.isTupleTypeNode(node) && + ts.length(node.elements) === 1 && + !ts.isOptionalTypeNode(node.elements[0]) && + !ts.isRestTypeNode(node.elements[0]) && + !(ts.isNamedTupleMember(node.elements[0]) && (node.elements[0].questionToken || node.elements[0].dotDotDotToken)); } /** @@ -15947,13 +15462,13 @@ namespace ts { * the intended comparison - we do this so we can check if the unwrapped types are generic or * not and appropriately defer condition calculation */ - function unwrapNondistributiveConditionalTuple(root: ConditionalRoot, type: Type) { + function unwrapNondistributiveConditionalTuple(root: ts.ConditionalRoot, type: ts.Type) { return isTypicalNondistributiveConditional(root) && isTupleType(type) ? getTypeArguments(type)[0] : type; } - function getConditionalType(root: ConditionalRoot, mapper: TypeMapper | undefined, aliasSymbol?: Symbol, aliasTypeArguments?: readonly Type[]): Type { + function getConditionalType(root: ts.ConditionalRoot, mapper: ts.TypeMapper | undefined, aliasSymbol?: ts.Symbol, aliasTypeArguments?: readonly ts.Type[]): ts.Type { let result; - let extraTypes: Type[] | undefined; + let extraTypes: ts.Type[] | undefined; let tailCount = 0; // We loop here for an immediately nested conditional type in the false position, effectively treating // types of the form 'A extends B ? X : C extends D ? Y : E extends F ? Z : ...' as a single construct for @@ -15962,7 +15477,7 @@ namespace ts { // cases we increment the tail recursion counter and stop after 1000 iterations. while (true) { if (tailCount === 1000) { - error(currentNode, Diagnostics.Type_instantiation_is_excessively_deep_and_possibly_infinite); + error(currentNode, ts.Diagnostics.Type_instantiation_is_excessively_deep_and_possibly_infinite); result = errorType; break; } @@ -15973,7 +15488,7 @@ namespace ts { if (checkType === wildcardType || extendsType === wildcardType) { return wildcardType; } - let combinedMapper: TypeMapper | undefined; + let combinedMapper: ts.TypeMapper | undefined; if (root.inferTypeParameters) { // When we're looking at making an inference for an infer type, when we get its constraint, it'll automagically be // instantiated with the context, so it doesn't need the mapper for the inference contex - however the constraint @@ -15992,9 +15507,9 @@ namespace ts { // * The original `mapper` used to create this conditional // * The mapper that maps the old root type parameter to the clone (`freshMapper`) // * The mapper that maps the clone to its inference result (`context.mapper`) - const freshParams = sameMap(root.inferTypeParameters, maybeCloneTypeParameter); + const freshParams = ts.sameMap(root.inferTypeParameters, maybeCloneTypeParameter); const freshMapper = freshParams !== root.inferTypeParameters ? createTypeMapper(root.inferTypeParameters, freshParams) : undefined; - const context = createInferenceContext(freshParams, /*signature*/ undefined, InferenceFlags.None); + const context = createInferenceContext(freshParams, /*signature*/ undefined, ts.InferenceFlags.None); if (freshMapper) { const freshCombinedMapper = combineTypeMappers(mapper, freshMapper); for (const p of freshParams) { @@ -16007,11 +15522,11 @@ namespace ts { // if it was, it's trivial to say that extendsType = checkType, however such a pattern is used to // "reset" the type being build up during constraint calculation and avoid making an apparently "infinite" constraint // so in those cases we refain from performing inference and retain the uninfered type parameter - if (!checkTypeInstantiable || !some(root.inferTypeParameters, t => t === extendsType)) { + if (!checkTypeInstantiable || !ts.some(root.inferTypeParameters, t => t === extendsType)) { // We don't want inferences from constraints as they may cause us to eagerly resolve the // conditional type instead of deferring resolution. Also, we always want strict function // types rules (i.e. proper contravariance) for inferences. - inferTypes(context.inferences, checkType, instantiateType(extendsType, freshMapper), InferencePriority.NoConstraints | InferencePriority.AlwaysStrict); + inferTypes(context.inferences, checkType, instantiateType(extendsType, freshMapper), ts.InferencePriority.NoConstraints | ts.InferencePriority.AlwaysStrict); } const innerMapper = combineTypeMappers(freshMapper, context.mapper); // It's possible for 'infer T' type paramteters to be given uninstantiated constraints when the @@ -16027,16 +15542,16 @@ namespace ts { // types with type parameters mapped to the wildcard type, the most permissive instantiations // possible (the wildcard type is assignable to and from all types). If those are not related, // then no instantiations will be and we can just return the false branch type. - if (!(inferredExtendsType.flags & TypeFlags.AnyOrUnknown) && ((checkType.flags & TypeFlags.Any && !isUnwrapped) || !isTypeAssignableTo(getPermissiveInstantiation(checkType), getPermissiveInstantiation(inferredExtendsType)))) { + if (!(inferredExtendsType.flags & ts.TypeFlags.AnyOrUnknown) && ((checkType.flags & ts.TypeFlags.Any && !isUnwrapped) || !isTypeAssignableTo(getPermissiveInstantiation(checkType), getPermissiveInstantiation(inferredExtendsType)))) { // Return union of trueType and falseType for 'any' since it matches anything - if (checkType.flags & TypeFlags.Any && !isUnwrapped) { + if (checkType.flags & ts.TypeFlags.Any && !isUnwrapped) { (extraTypes || (extraTypes = [])).push(instantiateType(getTypeFromTypeNode(root.node.trueType), combinedMapper || mapper)); } // If falseType is an immediately nested conditional type that isn't distributive or has an // identical checkType, switch to that type and loop. const falseType = getTypeFromTypeNode(root.node.falseType); - if (falseType.flags & TypeFlags.Conditional) { - const newRoot = (falseType as ConditionalType).root; + if (falseType.flags & ts.TypeFlags.Conditional) { + const newRoot = (falseType as ts.ConditionalType).root; if (newRoot.node.parent === root.node && (!newRoot.isDistributive || newRoot.checkType === root.checkType)) { root = newRoot; continue; @@ -16053,7 +15568,7 @@ namespace ts { // that has no constraint. This ensures that, for example, the type // type Foo = T extends { x: string } ? string : number // doesn't immediately resolve to 'string' instead of being deferred. - if (inferredExtendsType.flags & TypeFlags.AnyOrUnknown || isTypeAssignableTo(getRestrictiveInstantiation(checkType), getRestrictiveInstantiation(inferredExtendsType))) { + if (inferredExtendsType.flags & ts.TypeFlags.AnyOrUnknown || isTypeAssignableTo(getRestrictiveInstantiation(checkType), getRestrictiveInstantiation(inferredExtendsType))) { const trueType = getTypeFromTypeNode(root.node.trueType); const trueMapper = combinedMapper || mapper; if (canTailRecurse(trueType, trueMapper)) { @@ -16064,7 +15579,7 @@ namespace ts { } } // Return a deferred type for a check that is neither definitely true nor definitely false - result = createType(TypeFlags.Conditional) as ConditionalType; + result = createType(ts.TypeFlags.Conditional) as ts.ConditionalType; result.root = root; result.checkType = instantiateType(root.checkType, mapper); result.extendsType = instantiateType(root.extendsType, mapper); @@ -16074,20 +15589,20 @@ namespace ts { result.aliasTypeArguments = aliasSymbol ? aliasTypeArguments : instantiateTypes(root.aliasTypeArguments, mapper!); // TODO: GH#18217 break; } - return extraTypes ? getUnionType(append(extraTypes, result)) : result; + return extraTypes ? getUnionType(ts.append(extraTypes, result)) : result; // We tail-recurse for generic conditional types that (a) have not already been evaluated and cached, and // (b) are non distributive, have a check type that is unaffected by instantiation, or have a non-union check // type. Note that recursion is possible only through aliased conditional types, so we only increment the tail // recursion counter for those. - function canTailRecurse(newType: Type, newMapper: TypeMapper | undefined) { - if (newType.flags & TypeFlags.Conditional && newMapper) { - const newRoot = (newType as ConditionalType).root; + function canTailRecurse(newType: ts.Type, newMapper: ts.TypeMapper | undefined) { + if (newType.flags & ts.TypeFlags.Conditional && newMapper) { + const newRoot = (newType as ts.ConditionalType).root; if (newRoot.outerTypeParameters) { - const typeParamMapper = combineTypeMappers((newType as ConditionalType).mapper, newMapper); - const typeArguments = map(newRoot.outerTypeParameters, t => getMappedType(t, typeParamMapper)); + const typeParamMapper = combineTypeMappers((newType as ts.ConditionalType).mapper, newMapper); + const typeArguments = ts.map(newRoot.outerTypeParameters, t => getMappedType(t, typeParamMapper)); const newRootMapper = createTypeMapper(newRoot.outerTypeParameters, typeArguments); const newCheckType = newRoot.isDistributive ? getMappedType(newRoot.checkType, newRootMapper) : undefined; - if (!newCheckType || newCheckType === newRoot.checkType || !(newCheckType.flags & (TypeFlags.Union | TypeFlags.Never))) { + if (!newCheckType || newCheckType === newRoot.checkType || !(newCheckType.flags & (ts.TypeFlags.Union | ts.TypeFlags.Never))) { root = newRoot; mapper = newRootMapper; aliasSymbol = undefined; @@ -16103,49 +15618,48 @@ namespace ts { } } - function getTrueTypeFromConditionalType(type: ConditionalType) { + function getTrueTypeFromConditionalType(type: ts.ConditionalType) { return type.resolvedTrueType || (type.resolvedTrueType = instantiateType(getTypeFromTypeNode(type.root.node.trueType), type.mapper)); } - function getFalseTypeFromConditionalType(type: ConditionalType) { + function getFalseTypeFromConditionalType(type: ts.ConditionalType) { return type.resolvedFalseType || (type.resolvedFalseType = instantiateType(getTypeFromTypeNode(type.root.node.falseType), type.mapper)); } - function getInferredTrueTypeFromConditionalType(type: ConditionalType) { + function getInferredTrueTypeFromConditionalType(type: ts.ConditionalType) { return type.resolvedInferredTrueType || (type.resolvedInferredTrueType = type.combinedMapper ? instantiateType(getTypeFromTypeNode(type.root.node.trueType), type.combinedMapper) : getTrueTypeFromConditionalType(type)); } - function getInferTypeParameters(node: ConditionalTypeNode): TypeParameter[] | undefined { - let result: TypeParameter[] | undefined; + function getInferTypeParameters(node: ts.ConditionalTypeNode): ts.TypeParameter[] | undefined { + let result: ts.TypeParameter[] | undefined; if (node.locals) { node.locals.forEach(symbol => { - if (symbol.flags & SymbolFlags.TypeParameter) { - result = append(result, getDeclaredTypeOfSymbol(symbol)); + if (symbol.flags & ts.SymbolFlags.TypeParameter) { + result = ts.append(result, getDeclaredTypeOfSymbol(symbol)); } }); } return result; } - function isDistributionDependent(root: ConditionalRoot) { - return root.isDistributive && ( - isTypeParameterPossiblyReferenced(root.checkType as TypeParameter, root.node.trueType) || - isTypeParameterPossiblyReferenced(root.checkType as TypeParameter, root.node.falseType)); + function isDistributionDependent(root: ts.ConditionalRoot) { + return root.isDistributive && (isTypeParameterPossiblyReferenced(root.checkType as ts.TypeParameter, root.node.trueType) || + isTypeParameterPossiblyReferenced(root.checkType as ts.TypeParameter, root.node.falseType)); } - function getTypeFromConditionalTypeNode(node: ConditionalTypeNode): Type { + function getTypeFromConditionalTypeNode(node: ts.ConditionalTypeNode): ts.Type { const links = getNodeLinks(node); if (!links.resolvedType) { const checkType = getTypeFromTypeNode(node.checkType); const aliasSymbol = getAliasSymbolForTypeNode(node); const aliasTypeArguments = getTypeArgumentsForAliasSymbol(aliasSymbol); const allOuterTypeParameters = getOuterTypeParameters(node, /*includeThisTypes*/ true); - const outerTypeParameters = aliasTypeArguments ? allOuterTypeParameters : filter(allOuterTypeParameters, tp => isTypeParameterPossiblyReferenced(tp, node)); - const root: ConditionalRoot = { + const outerTypeParameters = aliasTypeArguments ? allOuterTypeParameters : ts.filter(allOuterTypeParameters, tp => isTypeParameterPossiblyReferenced(tp, node)); + const root: ts.ConditionalRoot = { node, checkType, extendsType: getTypeFromTypeNode(node.extendsType), - isDistributive: !!(checkType.flags & TypeFlags.TypeParameter), + isDistributive: !!(checkType.flags & ts.TypeFlags.TypeParameter), inferTypeParameters: getInferTypeParameters(node), outerTypeParameters, instantiations: undefined, @@ -16154,14 +15668,14 @@ namespace ts { }; links.resolvedType = getConditionalType(root, /*mapper*/ undefined); if (outerTypeParameters) { - root.instantiations = new Map(); + root.instantiations = new ts.Map(); root.instantiations.set(getTypeListId(outerTypeParameters), links.resolvedType); } } return links.resolvedType; } - function getTypeFromInferTypeNode(node: InferTypeNode): Type { + function getTypeFromInferTypeNode(node: ts.InferTypeNode): ts.Type { const links = getNodeLinks(node); if (!links.resolvedType) { links.resolvedType = getDeclaredTypeOfTypeParameter(getSymbolOfNode(node.typeParameter)); @@ -16169,29 +15683,29 @@ namespace ts { return links.resolvedType; } - function getIdentifierChain(node: EntityName): Identifier[] { - if (isIdentifier(node)) { + function getIdentifierChain(node: ts.EntityName): ts.Identifier[] { + if (ts.isIdentifier(node)) { return [node]; } else { - return append(getIdentifierChain(node.left), node.right); + return ts.append(getIdentifierChain(node.left), node.right); } } - function getTypeFromImportTypeNode(node: ImportTypeNode): Type { + function getTypeFromImportTypeNode(node: ts.ImportTypeNode): ts.Type { const links = getNodeLinks(node); if (!links.resolvedType) { if (node.isTypeOf && node.typeArguments) { // Only the non-typeof form can make use of type arguments - error(node, Diagnostics.Type_arguments_cannot_be_used_here); + error(node, ts.Diagnostics.Type_arguments_cannot_be_used_here); links.resolvedSymbol = unknownSymbol; return links.resolvedType = errorType; } - if (!isLiteralImportTypeNode(node)) { - error(node.argument, Diagnostics.String_literal_expected); + if (!ts.isLiteralImportTypeNode(node)) { + error(node.argument, ts.Diagnostics.String_literal_expected); links.resolvedSymbol = unknownSymbol; return links.resolvedType = errorType; } - const targetMeaning = node.isTypeOf ? SymbolFlags.Value : node.flags & NodeFlags.JSDoc ? SymbolFlags.Value | SymbolFlags.Type : SymbolFlags.Type; + const targetMeaning = node.isTypeOf ? ts.SymbolFlags.Value : node.flags & ts.NodeFlags.JSDoc ? ts.SymbolFlags.Value | ts.SymbolFlags.Type : ts.SymbolFlags.Type; // TODO: Future work: support unions/generics/whatever via a deferred import-type const innerModuleSymbol = resolveExternalModuleName(node, node.argument.literal); if (!innerModuleSymbol) { @@ -16199,12 +15713,12 @@ namespace ts { return links.resolvedType = errorType; } const moduleSymbol = resolveExternalModuleSymbol(innerModuleSymbol, /*dontResolveAlias*/ false); - if (!nodeIsMissing(node.qualifier)) { - const nameStack: Identifier[] = getIdentifierChain(node.qualifier!); + if (!ts.nodeIsMissing(node.qualifier)) { + const nameStack: ts.Identifier[] = getIdentifierChain(node.qualifier!); let currentNamespace = moduleSymbol; - let current: Identifier | undefined; + let current: ts.Identifier | undefined; while (current = nameStack.shift()) { - const meaning = nameStack.length ? SymbolFlags.Namespace : targetMeaning; + const meaning = nameStack.length ? ts.SymbolFlags.Namespace : targetMeaning; // typeof a.b.c is normally resolved using `checkExpression` which in turn defers to `checkQualifiedName` // That, in turn, ultimately uses `getPropertyOfType` on the type of the symbol, which differs slightly from // the `exports` lookup process that only looks up namespace members which is used for most type references @@ -16213,7 +15727,7 @@ namespace ts { ? getPropertyOfType(getTypeOfSymbol(mergedResolvedSymbol), current.escapedText, /*skipObjectFunctionPropertyAugment*/ false, /*includeTypeOnlyMembers*/ true) : getSymbol(getExportsOfSymbol(mergedResolvedSymbol), current.escapedText, meaning); if (!next) { - error(current, Diagnostics.Namespace_0_has_no_exported_member_1, getFullyQualifiedName(currentNamespace), declarationNameToString(current)); + error(current, ts.Diagnostics.Namespace_0_has_no_exported_member_1, getFullyQualifiedName(currentNamespace), ts.declarationNameToString(current)); return links.resolvedType = errorType; } getNodeLinks(current).resolvedSymbol = next; @@ -16227,9 +15741,9 @@ namespace ts { links.resolvedType = resolveImportSymbolType(node, links, moduleSymbol, targetMeaning); } else { - const errorMessage = targetMeaning === SymbolFlags.Value - ? Diagnostics.Module_0_does_not_refer_to_a_value_but_is_used_as_a_value_here - : Diagnostics.Module_0_does_not_refer_to_a_type_but_is_used_as_a_type_here_Did_you_mean_typeof_import_0; + const errorMessage = targetMeaning === ts.SymbolFlags.Value + ? ts.Diagnostics.Module_0_does_not_refer_to_a_value_but_is_used_as_a_value_here + : ts.Diagnostics.Module_0_does_not_refer_to_a_type_but_is_used_as_a_type_here_Did_you_mean_typeof_import_0; error(node, errorMessage, node.argument.literal.text); @@ -16241,10 +15755,10 @@ namespace ts { return links.resolvedType; } - function resolveImportSymbolType(node: ImportTypeNode, links: NodeLinks, symbol: Symbol, meaning: SymbolFlags) { + function resolveImportSymbolType(node: ts.ImportTypeNode, links: ts.NodeLinks, symbol: ts.Symbol, meaning: ts.SymbolFlags) { const resolvedSymbol = resolveSymbol(symbol); links.resolvedSymbol = resolvedSymbol; - if (meaning === SymbolFlags.Value) { + if (meaning === ts.SymbolFlags.Value) { return getTypeOfSymbol(symbol); // intentionally doesn't use resolved symbol so type is cached as expected on the alias } else { @@ -16252,7 +15766,7 @@ namespace ts { } } - function getTypeFromTypeLiteralOrFunctionOrConstructorTypeNode(node: TypeNode): Type { + function getTypeFromTypeLiteralOrFunctionOrConstructorTypeNode(node: ts.TypeNode): ts.Type { const links = getNodeLinks(node); if (!links.resolvedType) { // Deferred resolution of members is handled by resolveObjectTypeMembers @@ -16261,10 +15775,10 @@ namespace ts { links.resolvedType = emptyTypeLiteralType; } else { - let type = createObjectType(ObjectFlags.Anonymous, node.symbol); + let type = createObjectType(ts.ObjectFlags.Anonymous, node.symbol); type.aliasSymbol = aliasSymbol; type.aliasTypeArguments = getTypeArgumentsForAliasSymbol(aliasSymbol); - if (isJSDocTypeLiteral(node) && node.isArrayType) { + if (ts.isJSDocTypeLiteral(node) && node.isArrayType) { type = createArrayType(type); } links.resolvedType = type; @@ -16273,54 +15787,54 @@ namespace ts { return links.resolvedType; } - function getAliasSymbolForTypeNode(node: Node) { + function getAliasSymbolForTypeNode(node: ts.Node) { let host = node.parent; - while (isParenthesizedTypeNode(host) || isJSDocTypeExpression(host) || isTypeOperatorNode(host) && host.operator === SyntaxKind.ReadonlyKeyword) { + while (ts.isParenthesizedTypeNode(host) || ts.isJSDocTypeExpression(host) || ts.isTypeOperatorNode(host) && host.operator === ts.SyntaxKind.ReadonlyKeyword) { host = host.parent; } - return isTypeAlias(host) ? getSymbolOfNode(host) : undefined; + return ts.isTypeAlias(host) ? getSymbolOfNode(host) : undefined; } - function getTypeArgumentsForAliasSymbol(symbol: Symbol | undefined) { + function getTypeArgumentsForAliasSymbol(symbol: ts.Symbol | undefined) { return symbol ? getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(symbol) : undefined; } - function isNonGenericObjectType(type: Type) { - return !!(type.flags & TypeFlags.Object) && !isGenericMappedType(type); + function isNonGenericObjectType(type: ts.Type) { + return !!(type.flags & ts.TypeFlags.Object) && !isGenericMappedType(type); } - function isEmptyObjectTypeOrSpreadsIntoEmptyObject(type: Type) { - return isEmptyObjectType(type) || !!(type.flags & (TypeFlags.Null | TypeFlags.Undefined | TypeFlags.BooleanLike | TypeFlags.NumberLike | TypeFlags.BigIntLike | TypeFlags.StringLike | TypeFlags.EnumLike | TypeFlags.NonPrimitive | TypeFlags.Index)); + function isEmptyObjectTypeOrSpreadsIntoEmptyObject(type: ts.Type) { + return isEmptyObjectType(type) || !!(type.flags & (ts.TypeFlags.Null | ts.TypeFlags.Undefined | ts.TypeFlags.BooleanLike | ts.TypeFlags.NumberLike | ts.TypeFlags.BigIntLike | ts.TypeFlags.StringLike | ts.TypeFlags.EnumLike | ts.TypeFlags.NonPrimitive | ts.TypeFlags.Index)); } - function tryMergeUnionOfObjectTypeAndEmptyObject(type: Type, readonly: boolean): Type { - if (!(type.flags & TypeFlags.Union)) { + function tryMergeUnionOfObjectTypeAndEmptyObject(type: ts.Type, readonly: boolean): ts.Type { + if (!(type.flags & ts.TypeFlags.Union)) { return type; } - if (every((type as UnionType).types, isEmptyObjectTypeOrSpreadsIntoEmptyObject)) { - return find((type as UnionType).types, isEmptyObjectType) || emptyObjectType; + if (ts.every((type as ts.UnionType).types, isEmptyObjectTypeOrSpreadsIntoEmptyObject)) { + return ts.find((type as ts.UnionType).types, isEmptyObjectType) || emptyObjectType; } - const firstType = find((type as UnionType).types, t => !isEmptyObjectTypeOrSpreadsIntoEmptyObject(t)); + const firstType = ts.find((type as ts.UnionType).types, t => !isEmptyObjectTypeOrSpreadsIntoEmptyObject(t)); if (!firstType) { return type; } - const secondType = find((type as UnionType).types, t => t !== firstType && !isEmptyObjectTypeOrSpreadsIntoEmptyObject(t)); + const secondType = ts.find((type as ts.UnionType).types, t => t !== firstType && !isEmptyObjectTypeOrSpreadsIntoEmptyObject(t)); if (secondType) { return type; } return getAnonymousPartialType(firstType); - function getAnonymousPartialType(type: Type) { + function getAnonymousPartialType(type: ts.Type) { // gets the type as if it had been spread, but where everything in the spread is made optional - const members = createSymbolTable(); + const members = ts.createSymbolTable(); for (const prop of getPropertiesOfType(type)) { - if (getDeclarationModifierFlagsFromSymbol(prop) & (ModifierFlags.Private | ModifierFlags.Protected)) { + if (ts.getDeclarationModifierFlagsFromSymbol(prop) & (ts.ModifierFlags.Private | ts.ModifierFlags.Protected)) { // do nothing, skip privates } else if (isSpreadableProperty(prop)) { - const isSetonlyAccessor = prop.flags & SymbolFlags.SetAccessor && !(prop.flags & SymbolFlags.GetAccessor); - const flags = SymbolFlags.Property | SymbolFlags.Optional; - const result = createSymbol(flags, prop.escapedName, getIsLateCheckFlag(prop) | (readonly ? CheckFlags.Readonly : 0)); + const isSetonlyAccessor = prop.flags & ts.SymbolFlags.SetAccessor && !(prop.flags & ts.SymbolFlags.GetAccessor); + const flags = ts.SymbolFlags.Property | ts.SymbolFlags.Optional; + const result = createSymbol(flags, prop.escapedName, getIsLateCheckFlag(prop) | (readonly ? ts.CheckFlags.Readonly : 0)); result.type = isSetonlyAccessor ? undefinedType : addOptionality(getTypeOfSymbol(prop), /*isProperty*/ true); result.declarations = prop.declarations; result.nameType = getSymbolLinks(prop).nameType; @@ -16328,8 +15842,8 @@ namespace ts { members.set(prop.escapedName, result); } } - const spread = createAnonymousType(type.symbol, members, emptyArray, emptyArray, getIndexInfosOfType(type)); - spread.objectFlags |= ObjectFlags.ObjectLiteral | ObjectFlags.ContainsObjectOrArrayLiteral; + const spread = createAnonymousType(type.symbol, members, ts.emptyArray, ts.emptyArray, getIndexInfosOfType(type)); + spread.objectFlags |= ts.ObjectFlags.ObjectLiteral | ts.ObjectFlags.ContainsObjectOrArrayLiteral; return spread; } } @@ -16339,32 +15853,32 @@ namespace ts { * this function should be called in a left folding style, with left = previous result of getSpreadType * and right = the new element to be spread. */ - function getSpreadType(left: Type, right: Type, symbol: Symbol | undefined, objectFlags: ObjectFlags, readonly: boolean): Type { - if (left.flags & TypeFlags.Any || right.flags & TypeFlags.Any) { + function getSpreadType(left: ts.Type, right: ts.Type, symbol: ts.Symbol | undefined, objectFlags: ts.ObjectFlags, readonly: boolean): ts.Type { + if (left.flags & ts.TypeFlags.Any || right.flags & ts.TypeFlags.Any) { return anyType; } - if (left.flags & TypeFlags.Unknown || right.flags & TypeFlags.Unknown) { + if (left.flags & ts.TypeFlags.Unknown || right.flags & ts.TypeFlags.Unknown) { return unknownType; } - if (left.flags & TypeFlags.Never) { + if (left.flags & ts.TypeFlags.Never) { return right; } - if (right.flags & TypeFlags.Never) { + if (right.flags & ts.TypeFlags.Never) { return left; } left = tryMergeUnionOfObjectTypeAndEmptyObject(left, readonly); - if (left.flags & TypeFlags.Union) { + if (left.flags & ts.TypeFlags.Union) { return checkCrossProductUnion([left, right]) ? mapType(left, t => getSpreadType(t, right, symbol, objectFlags, readonly)) : errorType; } right = tryMergeUnionOfObjectTypeAndEmptyObject(right, readonly); - if (right.flags & TypeFlags.Union) { + if (right.flags & ts.TypeFlags.Union) { return checkCrossProductUnion([left, right]) ? mapType(right, t => getSpreadType(left, t, symbol, objectFlags, readonly)) : errorType; } - if (right.flags & (TypeFlags.BooleanLike | TypeFlags.NumberLike | TypeFlags.BigIntLike | TypeFlags.StringLike | TypeFlags.EnumLike | TypeFlags.NonPrimitive | TypeFlags.Index)) { + if (right.flags & (ts.TypeFlags.BooleanLike | ts.TypeFlags.NumberLike | ts.TypeFlags.BigIntLike | ts.TypeFlags.StringLike | ts.TypeFlags.EnumLike | ts.TypeFlags.NonPrimitive | ts.TypeFlags.Index)) { return left; } @@ -16375,22 +15889,22 @@ namespace ts { // When the left type is an intersection, we may need to merge the last constituent of the // intersection with the right type. For example when the left type is 'T & { a: string }' // and the right type is '{ b: string }' we produce 'T & { a: string, b: string }'. - if (left.flags & TypeFlags.Intersection) { - const types = (left as IntersectionType).types; + if (left.flags & ts.TypeFlags.Intersection) { + const types = (left as ts.IntersectionType).types; const lastLeft = types[types.length - 1]; if (isNonGenericObjectType(lastLeft) && isNonGenericObjectType(right)) { - return getIntersectionType(concatenate(types.slice(0, types.length - 1), [getSpreadType(lastLeft, right, symbol, objectFlags, readonly)])); + return getIntersectionType(ts.concatenate(types.slice(0, types.length - 1), [getSpreadType(lastLeft, right, symbol, objectFlags, readonly)])); } } return getIntersectionType([left, right]); } - const members = createSymbolTable(); - const skippedPrivateMembers = new Set<__String>(); + const members = ts.createSymbolTable(); + const skippedPrivateMembers = new ts.Set(); const indexInfos = left === emptyObjectType ? getIndexInfosOfType(right) : getUnionIndexInfos([left, right]); for (const rightProp of getPropertiesOfType(right)) { - if (getDeclarationModifierFlagsFromSymbol(rightProp) & (ModifierFlags.Private | ModifierFlags.Protected)) { + if (ts.getDeclarationModifierFlagsFromSymbol(rightProp) & (ts.ModifierFlags.Private | ts.ModifierFlags.Protected)) { skippedPrivateMembers.add(rightProp.escapedName); } else if (isSpreadableProperty(rightProp)) { @@ -16405,11 +15919,11 @@ namespace ts { if (members.has(leftProp.escapedName)) { const rightProp = members.get(leftProp.escapedName)!; const rightType = getTypeOfSymbol(rightProp); - if (rightProp.flags & SymbolFlags.Optional) { - const declarations = concatenate(leftProp.declarations, rightProp.declarations); - const flags = SymbolFlags.Property | (leftProp.flags & SymbolFlags.Optional); + if (rightProp.flags & ts.SymbolFlags.Optional) { + const declarations = ts.concatenate(leftProp.declarations, rightProp.declarations); + const flags = ts.SymbolFlags.Property | (leftProp.flags & ts.SymbolFlags.Optional); const result = createSymbol(flags, leftProp.escapedName); - result.type = getUnionType([getTypeOfSymbol(leftProp), removeMissingOrUndefinedType(rightType)], UnionReduction.Subtype); + result.type = getUnionType([getTypeOfSymbol(leftProp), removeMissingOrUndefinedType(rightType)], ts.UnionReduction.Subtype); result.leftSpread = leftProp; result.rightSpread = rightProp; result.declarations = declarations; @@ -16422,25 +15936,25 @@ namespace ts { } } - const spread = createAnonymousType(symbol, members, emptyArray, emptyArray, sameMap(indexInfos, info => getIndexInfoWithReadonly(info, readonly))); - spread.objectFlags |= ObjectFlags.ObjectLiteral | ObjectFlags.ContainsObjectOrArrayLiteral | ObjectFlags.ContainsSpread | objectFlags; + const spread = createAnonymousType(symbol, members, ts.emptyArray, ts.emptyArray, ts.sameMap(indexInfos, info => getIndexInfoWithReadonly(info, readonly))); + spread.objectFlags |= ts.ObjectFlags.ObjectLiteral | ts.ObjectFlags.ContainsObjectOrArrayLiteral | ts.ObjectFlags.ContainsSpread | objectFlags; return spread; } /** We approximate own properties as non-methods plus methods that are inside the object literal */ - function isSpreadableProperty(prop: Symbol): boolean { - return !some(prop.declarations, isPrivateIdentifierClassElementDeclaration) && - (!(prop.flags & (SymbolFlags.Method | SymbolFlags.GetAccessor | SymbolFlags.SetAccessor)) || - !prop.declarations?.some(decl => isClassLike(decl.parent))); + function isSpreadableProperty(prop: ts.Symbol): boolean { + return !ts.some(prop.declarations, ts.isPrivateIdentifierClassElementDeclaration) && + (!(prop.flags & (ts.SymbolFlags.Method | ts.SymbolFlags.GetAccessor | ts.SymbolFlags.SetAccessor)) || + !prop.declarations?.some(decl => ts.isClassLike(decl.parent))); } - function getSpreadSymbol(prop: Symbol, readonly: boolean) { - const isSetonlyAccessor = prop.flags & SymbolFlags.SetAccessor && !(prop.flags & SymbolFlags.GetAccessor); + function getSpreadSymbol(prop: ts.Symbol, readonly: boolean) { + const isSetonlyAccessor = prop.flags & ts.SymbolFlags.SetAccessor && !(prop.flags & ts.SymbolFlags.GetAccessor); if (!isSetonlyAccessor && readonly === isReadonlySymbol(prop)) { return prop; } - const flags = SymbolFlags.Property | (prop.flags & SymbolFlags.Optional); - const result = createSymbol(flags, prop.escapedName, getIsLateCheckFlag(prop) | (readonly ? CheckFlags.Readonly : 0)); + const flags = ts.SymbolFlags.Property | (prop.flags & ts.SymbolFlags.Optional); + const result = createSymbol(flags, prop.escapedName, getIsLateCheckFlag(prop) | (readonly ? ts.CheckFlags.Readonly : 0)); result.type = isSetonlyAccessor ? undefinedType : getTypeOfSymbol(prop); result.declarations = prop.declarations; result.nameType = getSymbolLinks(prop).nameType; @@ -16448,70 +15962,70 @@ namespace ts { return result; } - function getIndexInfoWithReadonly(info: IndexInfo, readonly: boolean) { + function getIndexInfoWithReadonly(info: ts.IndexInfo, readonly: boolean) { return info.isReadonly !== readonly ? createIndexInfo(info.keyType, info.type, readonly, info.declaration) : info; } - function createLiteralType(flags: TypeFlags, value: string | number | PseudoBigInt, symbol?: Symbol, regularType?: LiteralType) { - const type = createType(flags) as LiteralType; + function createLiteralType(flags: ts.TypeFlags, value: string | number | ts.PseudoBigInt, symbol?: ts.Symbol, regularType?: ts.LiteralType) { + const type = createType(flags) as ts.LiteralType; type.symbol = symbol!; type.value = value; type.regularType = regularType || type; return type; } - function getFreshTypeOfLiteralType(type: Type): Type { - if (type.flags & TypeFlags.Literal) { - if (!(type as LiteralType).freshType) { - const freshType = createLiteralType(type.flags, (type as LiteralType).value, (type as LiteralType).symbol, type as LiteralType); + function getFreshTypeOfLiteralType(type: ts.Type): ts.Type { + if (type.flags & ts.TypeFlags.Literal) { + if (!(type as ts.LiteralType).freshType) { + const freshType = createLiteralType(type.flags, (type as ts.LiteralType).value, (type as ts.LiteralType).symbol, type as ts.LiteralType); freshType.freshType = freshType; - (type as LiteralType).freshType = freshType; + (type as ts.LiteralType).freshType = freshType; } - return (type as LiteralType).freshType; + return (type as ts.LiteralType).freshType; } return type; } - function getRegularTypeOfLiteralType(type: Type): Type { - return type.flags & TypeFlags.Literal ? (type as LiteralType).regularType : - type.flags & TypeFlags.Union ? ((type as UnionType).regularType || ((type as UnionType).regularType = mapType(type, getRegularTypeOfLiteralType) as UnionType)) : + function getRegularTypeOfLiteralType(type: ts.Type): ts.Type { + return type.flags & ts.TypeFlags.Literal ? (type as ts.LiteralType).regularType : + type.flags & ts.TypeFlags.Union ? ((type as ts.UnionType).regularType || ((type as ts.UnionType).regularType = mapType(type, getRegularTypeOfLiteralType) as ts.UnionType)) : type; } - function isFreshLiteralType(type: Type) { - return !!(type.flags & TypeFlags.Literal) && (type as LiteralType).freshType === type; + function isFreshLiteralType(type: ts.Type) { + return !!(type.flags & ts.TypeFlags.Literal) && (type as ts.LiteralType).freshType === type; } - function getStringLiteralType(value: string): StringLiteralType { + function getStringLiteralType(value: string): ts.StringLiteralType { let type; return stringLiteralTypes.get(value) || - (stringLiteralTypes.set(value, type = createLiteralType(TypeFlags.StringLiteral, value) as StringLiteralType), type); + (stringLiteralTypes.set(value, type = createLiteralType(ts.TypeFlags.StringLiteral, value) as ts.StringLiteralType), type); } - function getNumberLiteralType(value: number): NumberLiteralType { + function getNumberLiteralType(value: number): ts.NumberLiteralType { let type; return numberLiteralTypes.get(value) || - (numberLiteralTypes.set(value, type = createLiteralType(TypeFlags.NumberLiteral, value) as NumberLiteralType), type); + (numberLiteralTypes.set(value, type = createLiteralType(ts.TypeFlags.NumberLiteral, value) as ts.NumberLiteralType), type); } - function getBigIntLiteralType(value: PseudoBigInt): BigIntLiteralType { + function getBigIntLiteralType(value: ts.PseudoBigInt): ts.BigIntLiteralType { let type; - const key = pseudoBigIntToString(value); + const key = ts.pseudoBigIntToString(value); return bigIntLiteralTypes.get(key) || - (bigIntLiteralTypes.set(key, type = createLiteralType(TypeFlags.BigIntLiteral, value) as BigIntLiteralType), type); + (bigIntLiteralTypes.set(key, type = createLiteralType(ts.TypeFlags.BigIntLiteral, value) as ts.BigIntLiteralType), type); } - function getEnumLiteralType(value: string | number, enumId: number, symbol: Symbol): LiteralType { + function getEnumLiteralType(value: string | number, enumId: number, symbol: ts.Symbol): ts.LiteralType { let type; const qualifier = typeof value === "string" ? "@" : "#"; const key = enumId + qualifier + value; - const flags = TypeFlags.EnumLiteral | (typeof value === "string" ? TypeFlags.StringLiteral : TypeFlags.NumberLiteral); + const flags = ts.TypeFlags.EnumLiteral | (typeof value === "string" ? ts.TypeFlags.StringLiteral : ts.TypeFlags.NumberLiteral); return enumLiteralTypes.get(key) || (enumLiteralTypes.set(key, type = createLiteralType(flags, value, symbol)), type); } - function getTypeFromLiteralTypeNode(node: LiteralTypeNode): Type { - if (node.literal.kind === SyntaxKind.NullKeyword) { + function getTypeFromLiteralTypeNode(node: ts.LiteralTypeNode): ts.Type { + if (node.literal.kind === ts.SyntaxKind.NullKeyword) { return nullType; } const links = getNodeLinks(node); @@ -16521,16 +16035,16 @@ namespace ts { return links.resolvedType; } - function createUniqueESSymbolType(symbol: Symbol) { - const type = createType(TypeFlags.UniqueESSymbol) as UniqueESSymbolType; + function createUniqueESSymbolType(symbol: ts.Symbol) { + const type = createType(ts.TypeFlags.UniqueESSymbol) as ts.UniqueESSymbolType; type.symbol = symbol; - type.escapedName = `__@${type.symbol.escapedName}@${getSymbolId(type.symbol)}` as __String; + type.escapedName = `__@${type.symbol.escapedName}@${getSymbolId(type.symbol)}` as ts.__String; return type; } - function getESSymbolLikeTypeForNode(node: Node) { - if (isValidESSymbolDeclaration(node)) { - const symbol = isCommonJsExportPropertyAssignment(node) ? getSymbolOfNode((node as BinaryExpression).left) : getSymbolOfNode(node); + function getESSymbolLikeTypeForNode(node: ts.Node) { + if (ts.isValidESSymbolDeclaration(node)) { + const symbol = ts.isCommonJsExportPropertyAssignment(node) ? getSymbolOfNode((node as ts.BinaryExpression).left) : getSymbolOfNode(node); if (symbol) { const links = getSymbolLinks(symbol); return links.uniqueESSymbolType || (links.uniqueESSymbolType = createUniqueESSymbolType(symbol)); @@ -16539,35 +16053,35 @@ namespace ts { return esSymbolType; } - function getThisType(node: Node): Type { - const container = getThisContainer(node, /*includeArrowFunctions*/ false); + function getThisType(node: ts.Node): ts.Type { + const container = ts.getThisContainer(node, /*includeArrowFunctions*/ false); const parent = container && container.parent; - if (parent && (isClassLike(parent) || parent.kind === SyntaxKind.InterfaceDeclaration)) { - if (!isStatic(container) && - (!isConstructorDeclaration(container) || isNodeDescendantOf(node, container.body))) { - return getDeclaredTypeOfClassOrInterface(getSymbolOfNode(parent as ClassLikeDeclaration | InterfaceDeclaration)).thisType!; + if (parent && (ts.isClassLike(parent) || parent.kind === ts.SyntaxKind.InterfaceDeclaration)) { + if (!ts.isStatic(container) && + (!ts.isConstructorDeclaration(container) || ts.isNodeDescendantOf(node, container.body))) { + return getDeclaredTypeOfClassOrInterface(getSymbolOfNode(parent as ts.ClassLikeDeclaration | ts.InterfaceDeclaration)).thisType!; } } // inside x.prototype = { ... } - if (parent && isObjectLiteralExpression(parent) && isBinaryExpression(parent.parent) && getAssignmentDeclarationKind(parent.parent) === AssignmentDeclarationKind.Prototype) { + if (parent && ts.isObjectLiteralExpression(parent) && ts.isBinaryExpression(parent.parent) && ts.getAssignmentDeclarationKind(parent.parent) === ts.AssignmentDeclarationKind.Prototype) { return getDeclaredTypeOfClassOrInterface(getSymbolOfNode(parent.parent.left)!.parent!).thisType!; } // /** @return {this} */ // x.prototype.m = function() { ... } - const host = node.flags & NodeFlags.JSDoc ? getHostSignatureFromJSDoc(node) : undefined; - if (host && isFunctionExpression(host) && isBinaryExpression(host.parent) && getAssignmentDeclarationKind(host.parent) === AssignmentDeclarationKind.PrototypeProperty) { + const host = node.flags & ts.NodeFlags.JSDoc ? ts.getHostSignatureFromJSDoc(node) : undefined; + if (host && ts.isFunctionExpression(host) && ts.isBinaryExpression(host.parent) && ts.getAssignmentDeclarationKind(host.parent) === ts.AssignmentDeclarationKind.PrototypeProperty) { return getDeclaredTypeOfClassOrInterface(getSymbolOfNode(host.parent.left)!.parent!).thisType!; } // inside constructor function C() { ... } - if (isJSConstructor(container) && isNodeDescendantOf(node, container.body)) { + if (isJSConstructor(container) && ts.isNodeDescendantOf(node, container.body)) { return getDeclaredTypeOfClassOrInterface(getSymbolOfNode(container)).thisType!; } - error(node, Diagnostics.A_this_type_is_available_only_in_a_non_static_member_of_a_class_or_interface); + error(node, ts.Diagnostics.A_this_type_is_available_only_in_a_non_static_member_of_a_class_or_interface); return errorType; } - function getTypeFromThisTypeNode(node: ThisExpression | ThisTypeNode): Type { + function getTypeFromThisTypeNode(node: ts.ThisExpression | ts.ThisTypeNode): ts.Type { const links = getNodeLinks(node); if (!links.resolvedType) { links.resolvedType = getThisType(node); @@ -16575,134 +16089,134 @@ namespace ts { return links.resolvedType; } - function getTypeFromRestTypeNode(node: RestTypeNode | NamedTupleMember) { + function getTypeFromRestTypeNode(node: ts.RestTypeNode | ts.NamedTupleMember) { return getTypeFromTypeNode(getArrayElementTypeNode(node.type) || node.type); } - function getArrayElementTypeNode(node: TypeNode): TypeNode | undefined { + function getArrayElementTypeNode(node: ts.TypeNode): ts.TypeNode | undefined { switch (node.kind) { - case SyntaxKind.ParenthesizedType: - return getArrayElementTypeNode((node as ParenthesizedTypeNode).type); - case SyntaxKind.TupleType: - if ((node as TupleTypeNode).elements.length === 1) { - node = (node as TupleTypeNode).elements[0]; - if (node.kind === SyntaxKind.RestType || node.kind === SyntaxKind.NamedTupleMember && (node as NamedTupleMember).dotDotDotToken) { - return getArrayElementTypeNode((node as RestTypeNode | NamedTupleMember).type); + case ts.SyntaxKind.ParenthesizedType: + return getArrayElementTypeNode((node as ts.ParenthesizedTypeNode).type); + case ts.SyntaxKind.TupleType: + if ((node as ts.TupleTypeNode).elements.length === 1) { + node = (node as ts.TupleTypeNode).elements[0]; + if (node.kind === ts.SyntaxKind.RestType || node.kind === ts.SyntaxKind.NamedTupleMember && (node as ts.NamedTupleMember).dotDotDotToken) { + return getArrayElementTypeNode((node as ts.RestTypeNode | ts.NamedTupleMember).type); } } break; - case SyntaxKind.ArrayType: - return (node as ArrayTypeNode).elementType; + case ts.SyntaxKind.ArrayType: + return (node as ts.ArrayTypeNode).elementType; } return undefined; } - function getTypeFromNamedTupleTypeNode(node: NamedTupleMember): Type { + function getTypeFromNamedTupleTypeNode(node: ts.NamedTupleMember): ts.Type { const links = getNodeLinks(node); return links.resolvedType || (links.resolvedType = node.dotDotDotToken ? getTypeFromRestTypeNode(node) : addOptionality(getTypeFromTypeNode(node.type), /*isProperty*/ true, !!node.questionToken)); } - function getTypeFromTypeNode(node: TypeNode): Type { + function getTypeFromTypeNode(node: ts.TypeNode): ts.Type { return getConditionalFlowTypeOfType(getTypeFromTypeNodeWorker(node), node); } - function getTypeFromTypeNodeWorker(node: TypeNode): Type { + function getTypeFromTypeNodeWorker(node: ts.TypeNode): ts.Type { switch (node.kind) { - case SyntaxKind.AnyKeyword: - case SyntaxKind.JSDocAllType: - case SyntaxKind.JSDocUnknownType: + case ts.SyntaxKind.AnyKeyword: + case ts.SyntaxKind.JSDocAllType: + case ts.SyntaxKind.JSDocUnknownType: return anyType; - case SyntaxKind.UnknownKeyword: + case ts.SyntaxKind.UnknownKeyword: return unknownType; - case SyntaxKind.StringKeyword: + case ts.SyntaxKind.StringKeyword: return stringType; - case SyntaxKind.NumberKeyword: + case ts.SyntaxKind.NumberKeyword: return numberType; - case SyntaxKind.BigIntKeyword: + case ts.SyntaxKind.BigIntKeyword: return bigintType; - case SyntaxKind.BooleanKeyword: + case ts.SyntaxKind.BooleanKeyword: return booleanType; - case SyntaxKind.SymbolKeyword: + case ts.SyntaxKind.SymbolKeyword: return esSymbolType; - case SyntaxKind.VoidKeyword: + case ts.SyntaxKind.VoidKeyword: return voidType; - case SyntaxKind.UndefinedKeyword: + case ts.SyntaxKind.UndefinedKeyword: return undefinedType; - case SyntaxKind.NullKeyword as TypeNodeSyntaxKind: + case ts.SyntaxKind.NullKeyword as ts.TypeNodeSyntaxKind: // TODO(rbuckton): `NullKeyword` is no longer a `TypeNode`, but we defensively allow it here because of incorrect casts in the Language Service. return nullType; - case SyntaxKind.NeverKeyword: + case ts.SyntaxKind.NeverKeyword: return neverType; - case SyntaxKind.ObjectKeyword: - return node.flags & NodeFlags.JavaScriptFile && !noImplicitAny ? anyType : nonPrimitiveType; - case SyntaxKind.IntrinsicKeyword: + case ts.SyntaxKind.ObjectKeyword: + return node.flags & ts.NodeFlags.JavaScriptFile && !noImplicitAny ? anyType : nonPrimitiveType; + case ts.SyntaxKind.IntrinsicKeyword: return intrinsicMarkerType; - case SyntaxKind.ThisType: - case SyntaxKind.ThisKeyword as TypeNodeSyntaxKind: + case ts.SyntaxKind.ThisType: + case ts.SyntaxKind.ThisKeyword as ts.TypeNodeSyntaxKind: // TODO(rbuckton): `ThisKeyword` is no longer a `TypeNode`, but we defensively allow it here because of incorrect casts in the Language Service and because of `isPartOfTypeNode`. - return getTypeFromThisTypeNode(node as ThisExpression | ThisTypeNode); - case SyntaxKind.LiteralType: - return getTypeFromLiteralTypeNode(node as LiteralTypeNode); - case SyntaxKind.TypeReference: - return getTypeFromTypeReference(node as TypeReferenceNode); - case SyntaxKind.TypePredicate: - return (node as TypePredicateNode).assertsModifier ? voidType : booleanType; - case SyntaxKind.ExpressionWithTypeArguments: - return getTypeFromTypeReference(node as ExpressionWithTypeArguments); - case SyntaxKind.TypeQuery: - return getTypeFromTypeQueryNode(node as TypeQueryNode); - case SyntaxKind.ArrayType: - case SyntaxKind.TupleType: - return getTypeFromArrayOrTupleTypeNode(node as ArrayTypeNode | TupleTypeNode); - case SyntaxKind.OptionalType: - return getTypeFromOptionalTypeNode(node as OptionalTypeNode); - case SyntaxKind.UnionType: - return getTypeFromUnionTypeNode(node as UnionTypeNode); - case SyntaxKind.IntersectionType: - return getTypeFromIntersectionTypeNode(node as IntersectionTypeNode); - case SyntaxKind.JSDocNullableType: - return getTypeFromJSDocNullableTypeNode(node as JSDocNullableType); - case SyntaxKind.JSDocOptionalType: - return addOptionality(getTypeFromTypeNode((node as JSDocOptionalType).type)); - case SyntaxKind.NamedTupleMember: - return getTypeFromNamedTupleTypeNode(node as NamedTupleMember); - case SyntaxKind.ParenthesizedType: - case SyntaxKind.JSDocNonNullableType: - case SyntaxKind.JSDocTypeExpression: - return getTypeFromTypeNode((node as ParenthesizedTypeNode | JSDocTypeReferencingNode | JSDocTypeExpression | NamedTupleMember).type); - case SyntaxKind.RestType: - return getTypeFromRestTypeNode(node as RestTypeNode); - case SyntaxKind.JSDocVariadicType: - return getTypeFromJSDocVariadicType(node as JSDocVariadicType); - case SyntaxKind.FunctionType: - case SyntaxKind.ConstructorType: - case SyntaxKind.TypeLiteral: - case SyntaxKind.JSDocTypeLiteral: - case SyntaxKind.JSDocFunctionType: - case SyntaxKind.JSDocSignature: + return getTypeFromThisTypeNode(node as ts.ThisExpression | ts.ThisTypeNode); + case ts.SyntaxKind.LiteralType: + return getTypeFromLiteralTypeNode(node as ts.LiteralTypeNode); + case ts.SyntaxKind.TypeReference: + return getTypeFromTypeReference(node as ts.TypeReferenceNode); + case ts.SyntaxKind.TypePredicate: + return (node as ts.TypePredicateNode).assertsModifier ? voidType : booleanType; + case ts.SyntaxKind.ExpressionWithTypeArguments: + return getTypeFromTypeReference(node as ts.ExpressionWithTypeArguments); + case ts.SyntaxKind.TypeQuery: + return getTypeFromTypeQueryNode(node as ts.TypeQueryNode); + case ts.SyntaxKind.ArrayType: + case ts.SyntaxKind.TupleType: + return getTypeFromArrayOrTupleTypeNode(node as ts.ArrayTypeNode | ts.TupleTypeNode); + case ts.SyntaxKind.OptionalType: + return getTypeFromOptionalTypeNode(node as ts.OptionalTypeNode); + case ts.SyntaxKind.UnionType: + return getTypeFromUnionTypeNode(node as ts.UnionTypeNode); + case ts.SyntaxKind.IntersectionType: + return getTypeFromIntersectionTypeNode(node as ts.IntersectionTypeNode); + case ts.SyntaxKind.JSDocNullableType: + return getTypeFromJSDocNullableTypeNode(node as ts.JSDocNullableType); + case ts.SyntaxKind.JSDocOptionalType: + return addOptionality(getTypeFromTypeNode((node as ts.JSDocOptionalType).type)); + case ts.SyntaxKind.NamedTupleMember: + return getTypeFromNamedTupleTypeNode(node as ts.NamedTupleMember); + case ts.SyntaxKind.ParenthesizedType: + case ts.SyntaxKind.JSDocNonNullableType: + case ts.SyntaxKind.JSDocTypeExpression: + return getTypeFromTypeNode((node as ts.ParenthesizedTypeNode | ts.JSDocTypeReferencingNode | ts.JSDocTypeExpression | ts.NamedTupleMember).type); + case ts.SyntaxKind.RestType: + return getTypeFromRestTypeNode(node as ts.RestTypeNode); + case ts.SyntaxKind.JSDocVariadicType: + return getTypeFromJSDocVariadicType(node as ts.JSDocVariadicType); + case ts.SyntaxKind.FunctionType: + case ts.SyntaxKind.ConstructorType: + case ts.SyntaxKind.TypeLiteral: + case ts.SyntaxKind.JSDocTypeLiteral: + case ts.SyntaxKind.JSDocFunctionType: + case ts.SyntaxKind.JSDocSignature: return getTypeFromTypeLiteralOrFunctionOrConstructorTypeNode(node); - case SyntaxKind.TypeOperator: - return getTypeFromTypeOperatorNode(node as TypeOperatorNode); - case SyntaxKind.IndexedAccessType: - return getTypeFromIndexedAccessTypeNode(node as IndexedAccessTypeNode); - case SyntaxKind.MappedType: - return getTypeFromMappedTypeNode(node as MappedTypeNode); - case SyntaxKind.ConditionalType: - return getTypeFromConditionalTypeNode(node as ConditionalTypeNode); - case SyntaxKind.InferType: - return getTypeFromInferTypeNode(node as InferTypeNode); - case SyntaxKind.TemplateLiteralType: - return getTypeFromTemplateTypeNode(node as TemplateLiteralTypeNode); - case SyntaxKind.ImportType: - return getTypeFromImportTypeNode(node as ImportTypeNode); + case ts.SyntaxKind.TypeOperator: + return getTypeFromTypeOperatorNode(node as ts.TypeOperatorNode); + case ts.SyntaxKind.IndexedAccessType: + return getTypeFromIndexedAccessTypeNode(node as ts.IndexedAccessTypeNode); + case ts.SyntaxKind.MappedType: + return getTypeFromMappedTypeNode(node as ts.MappedTypeNode); + case ts.SyntaxKind.ConditionalType: + return getTypeFromConditionalTypeNode(node as ts.ConditionalTypeNode); + case ts.SyntaxKind.InferType: + return getTypeFromInferTypeNode(node as ts.InferTypeNode); + case ts.SyntaxKind.TemplateLiteralType: + return getTypeFromTemplateTypeNode(node as ts.TemplateLiteralTypeNode); + case ts.SyntaxKind.ImportType: + return getTypeFromImportTypeNode(node as ts.ImportTypeNode); // This function assumes that an identifier, qualified name, or property access expression is a type expression // Callers should first ensure this by calling `isPartOfTypeNode` // TODO(rbuckton): These aren't valid TypeNodes, but we treat them as such because of `isPartOfTypeNode`, which returns `true` for things that aren't `TypeNode`s. - case SyntaxKind.Identifier as TypeNodeSyntaxKind: - case SyntaxKind.QualifiedName as TypeNodeSyntaxKind: - case SyntaxKind.PropertyAccessExpression as TypeNodeSyntaxKind: + case ts.SyntaxKind.Identifier as ts.TypeNodeSyntaxKind: + case ts.SyntaxKind.QualifiedName as ts.TypeNodeSyntaxKind: + case ts.SyntaxKind.PropertyAccessExpression as ts.TypeNodeSyntaxKind: const symbol = getSymbolAtLocation(node); return symbol ? getDeclaredTypeOfSymbol(symbol) : errorType; default: @@ -16710,9 +16224,9 @@ namespace ts { } } - function instantiateList(items: readonly T[], mapper: TypeMapper, instantiator: (item: T, mapper: TypeMapper) => T): readonly T[]; - function instantiateList(items: readonly T[] | undefined, mapper: TypeMapper, instantiator: (item: T, mapper: TypeMapper) => T): readonly T[] | undefined; - function instantiateList(items: readonly T[] | undefined, mapper: TypeMapper, instantiator: (item: T, mapper: TypeMapper) => T): readonly T[] | undefined { + function instantiateList(items: readonly T[], mapper: ts.TypeMapper, instantiator: (item: T, mapper: ts.TypeMapper) => T): readonly T[]; + function instantiateList(items: readonly T[] | undefined, mapper: ts.TypeMapper, instantiator: (item: T, mapper: ts.TypeMapper) => T): readonly T[] | undefined; + function instantiateList(items: readonly T[] | undefined, mapper: ts.TypeMapper, instantiator: (item: T, mapper: ts.TypeMapper) => T): readonly T[] | undefined { if (items && items.length) { for (let i = 0; i < items.length; i++) { const item = items[i]; @@ -16730,29 +16244,29 @@ namespace ts { return items; } - function instantiateTypes(types: readonly Type[], mapper: TypeMapper): readonly Type[]; - function instantiateTypes(types: readonly Type[] | undefined, mapper: TypeMapper): readonly Type[] | undefined; - function instantiateTypes(types: readonly Type[] | undefined, mapper: TypeMapper): readonly Type[] | undefined { - return instantiateList(types, mapper, instantiateType); + function instantiateTypes(types: readonly ts.Type[], mapper: ts.TypeMapper): readonly ts.Type[]; + function instantiateTypes(types: readonly ts.Type[] | undefined, mapper: ts.TypeMapper): readonly ts.Type[] | undefined; + function instantiateTypes(types: readonly ts.Type[] | undefined, mapper: ts.TypeMapper): readonly ts.Type[] | undefined { + return instantiateList(types, mapper, instantiateType); } - function instantiateSignatures(signatures: readonly Signature[], mapper: TypeMapper): readonly Signature[] { - return instantiateList(signatures, mapper, instantiateSignature); + function instantiateSignatures(signatures: readonly ts.Signature[], mapper: ts.TypeMapper): readonly ts.Signature[] { + return instantiateList(signatures, mapper, instantiateSignature); } - function instantiateIndexInfos(indexInfos: readonly IndexInfo[], mapper: TypeMapper): readonly IndexInfo[] { - return instantiateList(indexInfos, mapper, instantiateIndexInfo); + function instantiateIndexInfos(indexInfos: readonly ts.IndexInfo[], mapper: ts.TypeMapper): readonly ts.IndexInfo[] { + return instantiateList(indexInfos, mapper, instantiateIndexInfo); } - function createTypeMapper(sources: readonly TypeParameter[], targets: readonly Type[] | undefined): TypeMapper { + function createTypeMapper(sources: readonly ts.TypeParameter[], targets: readonly ts.Type[] | undefined): ts.TypeMapper { return sources.length === 1 ? makeUnaryTypeMapper(sources[0], targets ? targets[0] : anyType) : makeArrayTypeMapper(sources, targets); } - function getMappedType(type: Type, mapper: TypeMapper): Type { + function getMappedType(type: ts.Type, mapper: ts.TypeMapper): ts.Type { switch (mapper.kind) { - case TypeMapKind.Simple: + case ts.TypeMapKind.Simple: return type === mapper.source ? mapper.target : type; - case TypeMapKind.Array: + case ts.TypeMapKind.Array: const sources = mapper.sources; const targets = mapper.targets; for (let i = 0; i < sources.length; i++) { @@ -16761,32 +16275,32 @@ namespace ts { } } return type; - case TypeMapKind.Function: + case ts.TypeMapKind.Function: return mapper.func(type); - case TypeMapKind.Composite: - case TypeMapKind.Merged: + case ts.TypeMapKind.Composite: + case ts.TypeMapKind.Merged: const t1 = getMappedType(type, mapper.mapper1); - return t1 !== type && mapper.kind === TypeMapKind.Composite ? instantiateType(t1, mapper.mapper2) : getMappedType(t1, mapper.mapper2); + return t1 !== type && mapper.kind === ts.TypeMapKind.Composite ? instantiateType(t1, mapper.mapper2) : getMappedType(t1, mapper.mapper2); } } - function makeUnaryTypeMapper(source: Type, target: Type): TypeMapper { - return { kind: TypeMapKind.Simple, source, target }; + function makeUnaryTypeMapper(source: ts.Type, target: ts.Type): ts.TypeMapper { + return { kind: ts.TypeMapKind.Simple, source, target }; } - function makeArrayTypeMapper(sources: readonly TypeParameter[], targets: readonly Type[] | undefined): TypeMapper { - return { kind: TypeMapKind.Array, sources, targets }; + function makeArrayTypeMapper(sources: readonly ts.TypeParameter[], targets: readonly ts.Type[] | undefined): ts.TypeMapper { + return { kind: ts.TypeMapKind.Array, sources, targets }; } - function makeFunctionTypeMapper(func: (t: Type) => Type): TypeMapper { - return { kind: TypeMapKind.Function, func }; + function makeFunctionTypeMapper(func: (t: ts.Type) => ts.Type): ts.TypeMapper { + return { kind: ts.TypeMapKind.Function, func }; } - function makeCompositeTypeMapper(kind: TypeMapKind.Composite | TypeMapKind.Merged, mapper1: TypeMapper, mapper2: TypeMapper): TypeMapper { + function makeCompositeTypeMapper(kind: ts.TypeMapKind.Composite | ts.TypeMapKind.Merged, mapper1: ts.TypeMapper, mapper2: ts.TypeMapper): ts.TypeMapper { return { kind, mapper1, mapper2 }; } - function createTypeEraser(sources: readonly TypeParameter[]): TypeMapper { + function createTypeEraser(sources: readonly ts.TypeParameter[]): ts.TypeMapper { return createTypeMapper(sources, /*targets*/ undefined); } @@ -16794,51 +16308,49 @@ namespace ts { * Maps forward-references to later types parameters to the empty object type. * This is used during inference when instantiating type parameter defaults. */ - function createBackreferenceMapper(context: InferenceContext, index: number): TypeMapper { - return makeFunctionTypeMapper(t => findIndex(context.inferences, info => info.typeParameter === t) >= index ? unknownType : t); + function createBackreferenceMapper(context: ts.InferenceContext, index: number): ts.TypeMapper { + return makeFunctionTypeMapper(t => ts.findIndex(context.inferences, info => info.typeParameter === t) >= index ? unknownType : t); } - function combineTypeMappers(mapper1: TypeMapper | undefined, mapper2: TypeMapper): TypeMapper { - return mapper1 ? makeCompositeTypeMapper(TypeMapKind.Composite, mapper1, mapper2) : mapper2; + function combineTypeMappers(mapper1: ts.TypeMapper | undefined, mapper2: ts.TypeMapper): ts.TypeMapper { + return mapper1 ? makeCompositeTypeMapper(ts.TypeMapKind.Composite, mapper1, mapper2) : mapper2; } - function mergeTypeMappers(mapper1: TypeMapper | undefined, mapper2: TypeMapper): TypeMapper { - return mapper1 ? makeCompositeTypeMapper(TypeMapKind.Merged, mapper1, mapper2) : mapper2; + function mergeTypeMappers(mapper1: ts.TypeMapper | undefined, mapper2: ts.TypeMapper): ts.TypeMapper { + return mapper1 ? makeCompositeTypeMapper(ts.TypeMapKind.Merged, mapper1, mapper2) : mapper2; } - function prependTypeMapping(source: Type, target: Type, mapper: TypeMapper | undefined) { - return !mapper ? makeUnaryTypeMapper(source, target) : makeCompositeTypeMapper(TypeMapKind.Merged, makeUnaryTypeMapper(source, target), mapper); + function prependTypeMapping(source: ts.Type, target: ts.Type, mapper: ts.TypeMapper | undefined) { + return !mapper ? makeUnaryTypeMapper(source, target) : makeCompositeTypeMapper(ts.TypeMapKind.Merged, makeUnaryTypeMapper(source, target), mapper); } - function appendTypeMapping(mapper: TypeMapper | undefined, source: Type, target: Type) { - return !mapper ? makeUnaryTypeMapper(source, target) : makeCompositeTypeMapper(TypeMapKind.Merged, mapper, makeUnaryTypeMapper(source, target)); + function appendTypeMapping(mapper: ts.TypeMapper | undefined, source: ts.Type, target: ts.Type) { + return !mapper ? makeUnaryTypeMapper(source, target) : makeCompositeTypeMapper(ts.TypeMapKind.Merged, mapper, makeUnaryTypeMapper(source, target)); } - function getRestrictiveTypeParameter(tp: TypeParameter) { - return tp.constraint === unknownType ? tp : tp.restrictiveInstantiation || ( - tp.restrictiveInstantiation = createTypeParameter(tp.symbol), - (tp.restrictiveInstantiation as TypeParameter).constraint = unknownType, - tp.restrictiveInstantiation - ); + function getRestrictiveTypeParameter(tp: ts.TypeParameter) { + return tp.constraint === unknownType ? tp : tp.restrictiveInstantiation || (tp.restrictiveInstantiation = createTypeParameter(tp.symbol), + (tp.restrictiveInstantiation as ts.TypeParameter).constraint = unknownType, + tp.restrictiveInstantiation); } - function cloneTypeParameter(typeParameter: TypeParameter): TypeParameter { + function cloneTypeParameter(typeParameter: ts.TypeParameter): ts.TypeParameter { const result = createTypeParameter(typeParameter.symbol); result.target = typeParameter; return result; } - function instantiateTypePredicate(predicate: TypePredicate, mapper: TypeMapper): TypePredicate { + function instantiateTypePredicate(predicate: ts.TypePredicate, mapper: ts.TypeMapper): ts.TypePredicate { return createTypePredicate(predicate.kind, predicate.parameterName, predicate.parameterIndex, instantiateType(predicate.type, mapper)); } - function instantiateSignature(signature: Signature, mapper: TypeMapper, eraseTypeParameters?: boolean): Signature { - let freshTypeParameters: TypeParameter[] | undefined; + function instantiateSignature(signature: ts.Signature, mapper: ts.TypeMapper, eraseTypeParameters?: boolean): ts.Signature { + let freshTypeParameters: ts.TypeParameter[] | undefined; if (signature.typeParameters && !eraseTypeParameters) { // First create a fresh set of type parameters, then include a mapping from the old to the // new type parameters in the mapper function. Finally store this mapper in the new type // parameters such that we can use it when instantiating constraints. - freshTypeParameters = map(signature.typeParameters, cloneTypeParameter); + freshTypeParameters = ts.map(signature.typeParameters, cloneTypeParameter); mapper = combineTypeMappers(createTypeMapper(signature.typeParameters, freshTypeParameters), mapper); for (const tp of freshTypeParameters) { tp.mapper = mapper; @@ -16847,26 +16359,22 @@ namespace ts { // Don't compute resolvedReturnType and resolvedTypePredicate now, // because using `mapper` now could trigger inferences to become fixed. (See `createInferenceContext`.) // See GH#17600. - const result = createSignature(signature.declaration, freshTypeParameters, - signature.thisParameter && instantiateSymbol(signature.thisParameter, mapper), - instantiateList(signature.parameters, mapper, instantiateSymbol), + const result = createSignature(signature.declaration, freshTypeParameters, signature.thisParameter && instantiateSymbol(signature.thisParameter, mapper), instantiateList(signature.parameters, mapper, instantiateSymbol), /*resolvedReturnType*/ undefined, - /*resolvedTypePredicate*/ undefined, - signature.minArgumentCount, - signature.flags & SignatureFlags.PropagatingFlags); + /*resolvedTypePredicate*/ undefined, signature.minArgumentCount, signature.flags & ts.SignatureFlags.PropagatingFlags); result.target = signature; result.mapper = mapper; return result; } - function instantiateSymbol(symbol: Symbol, mapper: TypeMapper): Symbol { + function instantiateSymbol(symbol: ts.Symbol, mapper: ts.TypeMapper): ts.Symbol { const links = getSymbolLinks(symbol); if (links.type && !couldContainTypeVariables(links.type)) { // If the type of the symbol is already resolved, and if that type could not possibly // be affected by instantiation, simply return the symbol itself. return symbol; } - if (getCheckFlags(symbol) & CheckFlags.Instantiated) { + if (ts.getCheckFlags(symbol) & ts.CheckFlags.Instantiated) { // If symbol being instantiated is itself a instantiation, fetch the original target and combine the // type mappers. This ensures that original type identities are properly preserved and that aliases // always reference a non-aliases. @@ -16875,7 +16383,7 @@ namespace ts { } // Keep the flags from the symbol we're instantiating. Mark that is instantiated, and // also transient so that we can just store data on it directly. - const result = createSymbol(symbol.flags, symbol.escapedName, CheckFlags.Instantiated | getCheckFlags(symbol) & (CheckFlags.Readonly | CheckFlags.Late | CheckFlags.OptionalParameter | CheckFlags.RestParameter)); + const result = createSymbol(symbol.flags, symbol.escapedName, ts.CheckFlags.Instantiated | ts.getCheckFlags(symbol) & (ts.CheckFlags.Readonly | ts.CheckFlags.Late | ts.CheckFlags.OptionalParameter | ts.CheckFlags.RestParameter)); result.declarations = symbol.declarations; result.parent = symbol.parent; result.target = symbol; @@ -16889,13 +16397,13 @@ namespace ts { return result; } - function getObjectTypeInstantiation(type: AnonymousType | DeferredTypeReference, mapper: TypeMapper, aliasSymbol?: Symbol, aliasTypeArguments?: readonly Type[]) { - const declaration = type.objectFlags & ObjectFlags.Reference ? (type as TypeReference).node! : - type.objectFlags & ObjectFlags.InstantiationExpressionType ? (type as InstantiationExpressionType).node : + function getObjectTypeInstantiation(type: ts.AnonymousType | ts.DeferredTypeReference, mapper: ts.TypeMapper, aliasSymbol?: ts.Symbol, aliasTypeArguments?: readonly ts.Type[]) { + const declaration = type.objectFlags & ts.ObjectFlags.Reference ? (type as ts.TypeReference).node! : + type.objectFlags & ts.ObjectFlags.InstantiationExpressionType ? (type as ts.InstantiationExpressionType).node : type.symbol.declarations![0]; const links = getNodeLinks(declaration); - const target = type.objectFlags & ObjectFlags.Reference ? links.resolvedType! as DeferredTypeReference : - type.objectFlags & ObjectFlags.Instantiated ? type.target! : type; + const target = type.objectFlags & ts.ObjectFlags.Reference ? links.resolvedType! as ts.DeferredTypeReference : + type.objectFlags & ts.ObjectFlags.Instantiated ? type.target! : type; let typeParameters = links.outerTypeParameters; if (!typeParameters) { // The first time an anonymous type is instantiated we compute and store a list of the type @@ -16904,13 +16412,13 @@ namespace ts { // set of type parameters to those that are possibly referenced in the literal. let outerTypeParameters = getOuterTypeParameters(declaration, /*includeThisTypes*/ true); if (isJSConstructor(declaration)) { - const templateTagParameters = getTypeParametersFromDeclaration(declaration as DeclarationWithTypeParameters); - outerTypeParameters = addRange(outerTypeParameters, templateTagParameters); + const templateTagParameters = getTypeParametersFromDeclaration(declaration as ts.DeclarationWithTypeParameters); + outerTypeParameters = ts.addRange(outerTypeParameters, templateTagParameters); } - typeParameters = outerTypeParameters || emptyArray; - const allDeclarations = type.objectFlags & (ObjectFlags.Reference | ObjectFlags.InstantiationExpressionType) ? [declaration] : type.symbol.declarations!; - typeParameters = (target.objectFlags & (ObjectFlags.Reference | ObjectFlags.InstantiationExpressionType) || target.symbol.flags & SymbolFlags.Method || target.symbol.flags & SymbolFlags.TypeLiteral) && !target.aliasTypeArguments ? - filter(typeParameters, tp => some(allDeclarations, d => isTypeParameterPossiblyReferenced(tp, d))) : + typeParameters = outerTypeParameters || ts.emptyArray; + const allDeclarations = type.objectFlags & (ts.ObjectFlags.Reference | ts.ObjectFlags.InstantiationExpressionType) ? [declaration] : type.symbol.declarations!; + typeParameters = (target.objectFlags & (ts.ObjectFlags.Reference | ts.ObjectFlags.InstantiationExpressionType) || target.symbol.flags & ts.SymbolFlags.Method || target.symbol.flags & ts.SymbolFlags.TypeLiteral) && !target.aliasTypeArguments ? + ts.filter(typeParameters, tp => ts.some(allDeclarations, d => isTypeParameterPossiblyReferenced(tp, d))) : typeParameters; links.outerTypeParameters = typeParameters; } @@ -16919,19 +16427,19 @@ namespace ts { // mapper to the type parameters to produce the effective list of type arguments, and compute the // instantiation cache key from the type IDs of the type arguments. const combinedMapper = combineTypeMappers(type.mapper, mapper); - const typeArguments = map(typeParameters, t => getMappedType(t, combinedMapper)); + const typeArguments = ts.map(typeParameters, t => getMappedType(t, combinedMapper)); const newAliasSymbol = aliasSymbol || type.aliasSymbol; const newAliasTypeArguments = aliasSymbol ? aliasTypeArguments : instantiateTypes(type.aliasTypeArguments, mapper); const id = getTypeListId(typeArguments) + getAliasId(newAliasSymbol, newAliasTypeArguments); if (!target.instantiations) { - target.instantiations = new Map(); + target.instantiations = new ts.Map(); target.instantiations.set(getTypeListId(typeParameters) + getAliasId(target.aliasSymbol, target.aliasTypeArguments), target); } let result = target.instantiations.get(id); if (!result) { const newMapper = createTypeMapper(typeParameters, typeArguments); - result = target.objectFlags & ObjectFlags.Reference ? createDeferredTypeReference((type as DeferredTypeReference).target, (type as DeferredTypeReference).node, newMapper, newAliasSymbol, newAliasTypeArguments) : - target.objectFlags & ObjectFlags.Mapped ? instantiateMappedType(target as MappedType, newMapper, newAliasSymbol, newAliasTypeArguments) : + result = target.objectFlags & ts.ObjectFlags.Reference ? createDeferredTypeReference((type as ts.DeferredTypeReference).target, (type as ts.DeferredTypeReference).node, newMapper, newAliasSymbol, newAliasTypeArguments) : + target.objectFlags & ts.ObjectFlags.Mapped ? instantiateMappedType(target as ts.MappedType, newMapper, newAliasSymbol, newAliasTypeArguments) : instantiateAnonymousType(target, newMapper, newAliasSymbol, newAliasTypeArguments); target.instantiations.set(id, result); } @@ -16940,57 +16448,57 @@ namespace ts { return type; } - function maybeTypeParameterReference(node: Node) { - return !(node.parent.kind === SyntaxKind.TypeReference && (node.parent as TypeReferenceNode).typeArguments && node === (node.parent as TypeReferenceNode).typeName || - node.parent.kind === SyntaxKind.ImportType && (node.parent as ImportTypeNode).typeArguments && node === (node.parent as ImportTypeNode).qualifier); + function maybeTypeParameterReference(node: ts.Node) { + return !(node.parent.kind === ts.SyntaxKind.TypeReference && (node.parent as ts.TypeReferenceNode).typeArguments && node === (node.parent as ts.TypeReferenceNode).typeName || + node.parent.kind === ts.SyntaxKind.ImportType && (node.parent as ts.ImportTypeNode).typeArguments && node === (node.parent as ts.ImportTypeNode).qualifier); } - function isTypeParameterPossiblyReferenced(tp: TypeParameter, node: Node) { + function isTypeParameterPossiblyReferenced(tp: ts.TypeParameter, node: ts.Node) { // If the type parameter doesn't have exactly one declaration, if there are invening statement blocks // between the node and the type parameter declaration, if the node contains actual references to the // type parameter, or if the node contains type queries, we consider the type parameter possibly referenced. if (tp.symbol && tp.symbol.declarations && tp.symbol.declarations.length === 1) { const container = tp.symbol.declarations[0].parent; for (let n = node; n !== container; n = n.parent) { - if (!n || n.kind === SyntaxKind.Block || n.kind === SyntaxKind.ConditionalType && forEachChild((n as ConditionalTypeNode).extendsType, containsReference)) { + if (!n || n.kind === ts.SyntaxKind.Block || n.kind === ts.SyntaxKind.ConditionalType && ts.forEachChild((n as ts.ConditionalTypeNode).extendsType, containsReference)) { return true; } } return containsReference(node); } return true; - function containsReference(node: Node): boolean { + function containsReference(node: ts.Node): boolean { switch (node.kind) { - case SyntaxKind.ThisType: + case ts.SyntaxKind.ThisType: return !!tp.isThisType; - case SyntaxKind.Identifier: - return !tp.isThisType && isPartOfTypeNode(node) && maybeTypeParameterReference(node) && - getTypeFromTypeNodeWorker(node as TypeNode) === tp; // use worker because we're looking for === equality - case SyntaxKind.TypeQuery: + case ts.SyntaxKind.Identifier: + return !tp.isThisType && ts.isPartOfTypeNode(node) && maybeTypeParameterReference(node) && + getTypeFromTypeNodeWorker(node as ts.TypeNode) === tp; // use worker because we're looking for === equality + case ts.SyntaxKind.TypeQuery: return true; - case SyntaxKind.MethodDeclaration: - case SyntaxKind.MethodSignature: - return !(node as FunctionLikeDeclaration).type && !!(node as FunctionLikeDeclaration).body || - some((node as FunctionLikeDeclaration).typeParameters, containsReference) || - some((node as FunctionLikeDeclaration).parameters, containsReference) || - !!(node as FunctionLikeDeclaration).type && containsReference((node as FunctionLikeDeclaration).type!); + case ts.SyntaxKind.MethodDeclaration: + case ts.SyntaxKind.MethodSignature: + return !(node as ts.FunctionLikeDeclaration).type && !!(node as ts.FunctionLikeDeclaration).body || + ts.some((node as ts.FunctionLikeDeclaration).typeParameters, containsReference) || + ts.some((node as ts.FunctionLikeDeclaration).parameters, containsReference) || + !!(node as ts.FunctionLikeDeclaration).type && containsReference((node as ts.FunctionLikeDeclaration).type!); } - return !!forEachChild(node, containsReference); + return !!ts.forEachChild(node, containsReference); } } - function getHomomorphicTypeVariable(type: MappedType) { + function getHomomorphicTypeVariable(type: ts.MappedType) { const constraintType = getConstraintTypeFromMappedType(type); - if (constraintType.flags & TypeFlags.Index) { - const typeVariable = getActualTypeVariable((constraintType as IndexType).type); - if (typeVariable.flags & TypeFlags.TypeParameter) { - return typeVariable as TypeParameter; + if (constraintType.flags & ts.TypeFlags.Index) { + const typeVariable = getActualTypeVariable((constraintType as ts.IndexType).type); + if (typeVariable.flags & ts.TypeFlags.TypeParameter) { + return typeVariable as ts.TypeParameter; } } return undefined; } - function instantiateMappedType(type: MappedType, mapper: TypeMapper, aliasSymbol?: Symbol, aliasTypeArguments?: readonly Type[]): Type { + function instantiateMappedType(type: ts.MappedType, mapper: ts.TypeMapper, aliasSymbol?: ts.Symbol, aliasTypeArguments?: readonly ts.Type[]): ts.Type { // For a homomorphic mapped type { [P in keyof T]: X }, where T is some type variable, the mapping // operation depends on T as follows: // * If T is a primitive type no mapping is performed and the result is simply T. @@ -17006,10 +16514,10 @@ namespace ts { const mappedTypeVariable = instantiateType(typeVariable, mapper); if (typeVariable !== mappedTypeVariable) { return mapTypeWithAlias(getReducedType(mappedTypeVariable), t => { - if (t.flags & (TypeFlags.AnyOrUnknown | TypeFlags.InstantiableNonPrimitive | TypeFlags.Object | TypeFlags.Intersection) && t !== wildcardType && !isErrorType(t)) { + if (t.flags & (ts.TypeFlags.AnyOrUnknown | ts.TypeFlags.InstantiableNonPrimitive | ts.TypeFlags.Object | ts.TypeFlags.Intersection) && t !== wildcardType && !isErrorType(t)) { if (!type.declaration.nameType) { let constraint; - if (isArrayType(t) || t.flags & TypeFlags.Any && findResolutionCycleStartIndex(typeVariable, TypeSystemPropertyName.ImmediateBaseConstraint) < 0 && + if (isArrayType(t) || t.flags & ts.TypeFlags.Any && findResolutionCycleStartIndex(typeVariable, TypeSystemPropertyName.ImmediateBaseConstraint) < 0 && (constraint = getConstraintOfTypeParameter(typeVariable)) && everyType(constraint, isArrayOrTupleType)) { return instantiateMappedArrayType(t, type, prependTypeMapping(typeVariable, t, mapper)); } @@ -17034,64 +16542,63 @@ namespace ts { return modifiers & MappedTypeModifiers.IncludeReadonly ? true : modifiers & MappedTypeModifiers.ExcludeReadonly ? false : state; } - function instantiateMappedGenericTupleType(tupleType: TupleTypeReference, mappedType: MappedType, typeVariable: TypeVariable, mapper: TypeMapper) { + function instantiateMappedGenericTupleType(tupleType: ts.TupleTypeReference, mappedType: ts.MappedType, typeVariable: ts.TypeVariable, mapper: ts.TypeMapper) { // When a tuple type is generic (i.e. when it contains variadic elements), we want to eagerly map the // non-generic elements and defer mapping the generic elements. In order to facilitate this, we transform // M<[A, B?, ...T, ...C[]] into [...M<[A]>, ...M<[B?]>, ...M, ...M] and then rely on tuple type // normalization to resolve the non-generic parts of the resulting tuple. const elementFlags = tupleType.target.elementFlags; - const elementTypes = map(getTypeArguments(tupleType), (t, i) => { - const singleton = elementFlags[i] & ElementFlags.Variadic ? t : - elementFlags[i] & ElementFlags.Rest ? createArrayType(t) : + const elementTypes = ts.map(getTypeArguments(tupleType), (t, i) => { + const singleton = elementFlags[i] & ts.ElementFlags.Variadic ? t : + elementFlags[i] & ts.ElementFlags.Rest ? createArrayType(t) : createTupleType([t], [elementFlags[i]]); // The singleton is never a generic tuple type, so it is safe to recurse here. return instantiateMappedType(mappedType, prependTypeMapping(typeVariable, singleton, mapper)); }); const newReadonly = getModifiedReadonlyState(tupleType.target.readonly, getMappedTypeModifiers(mappedType)); - return createTupleType(elementTypes, map(elementTypes, _ => ElementFlags.Variadic), newReadonly); + return createTupleType(elementTypes, ts.map(elementTypes, _ => ts.ElementFlags.Variadic), newReadonly); } - function instantiateMappedArrayType(arrayType: Type, mappedType: MappedType, mapper: TypeMapper) { + function instantiateMappedArrayType(arrayType: ts.Type, mappedType: ts.MappedType, mapper: ts.TypeMapper) { const elementType = instantiateMappedTypeTemplate(mappedType, numberType, /*isOptional*/ true, mapper); return isErrorType(elementType) ? errorType : createArrayType(elementType, getModifiedReadonlyState(isReadonlyArrayType(arrayType), getMappedTypeModifiers(mappedType))); } - function instantiateMappedTupleType(tupleType: TupleTypeReference, mappedType: MappedType, mapper: TypeMapper) { + function instantiateMappedTupleType(tupleType: ts.TupleTypeReference, mappedType: ts.MappedType, mapper: ts.TypeMapper) { const elementFlags = tupleType.target.elementFlags; - const elementTypes = map(getTypeArguments(tupleType), (_, i) => - instantiateMappedTypeTemplate(mappedType, getStringLiteralType("" + i), !!(elementFlags[i] & ElementFlags.Optional), mapper)); + const elementTypes = ts.map(getTypeArguments(tupleType), (_, i) => instantiateMappedTypeTemplate(mappedType, getStringLiteralType("" + i), !!(elementFlags[i] & ts.ElementFlags.Optional), mapper)); const modifiers = getMappedTypeModifiers(mappedType); - const newTupleModifiers = modifiers & MappedTypeModifiers.IncludeOptional ? map(elementFlags, f => f & ElementFlags.Required ? ElementFlags.Optional : f) : - modifiers & MappedTypeModifiers.ExcludeOptional ? map(elementFlags, f => f & ElementFlags.Optional ? ElementFlags.Required : f) : + const newTupleModifiers = modifiers & MappedTypeModifiers.IncludeOptional ? ts.map(elementFlags, f => f & ts.ElementFlags.Required ? ts.ElementFlags.Optional : f) : + modifiers & MappedTypeModifiers.ExcludeOptional ? ts.map(elementFlags, f => f & ts.ElementFlags.Optional ? ts.ElementFlags.Required : f) : elementFlags; const newReadonly = getModifiedReadonlyState(tupleType.target.readonly, modifiers); - return contains(elementTypes, errorType) ? errorType : + return ts.contains(elementTypes, errorType) ? errorType : createTupleType(elementTypes, newTupleModifiers, newReadonly, tupleType.target.labeledElementDeclarations); } - function instantiateMappedTypeTemplate(type: MappedType, key: Type, isOptional: boolean, mapper: TypeMapper) { + function instantiateMappedTypeTemplate(type: ts.MappedType, key: ts.Type, isOptional: boolean, mapper: ts.TypeMapper) { const templateMapper = appendTypeMapping(mapper, getTypeParameterFromMappedType(type), key); - const propType = instantiateType(getTemplateTypeFromMappedType(type.target as MappedType || type), templateMapper); + const propType = instantiateType(getTemplateTypeFromMappedType(type.target as ts.MappedType || type), templateMapper); const modifiers = getMappedTypeModifiers(type); - return strictNullChecks && modifiers & MappedTypeModifiers.IncludeOptional && !maybeTypeOfKind(propType, TypeFlags.Undefined | TypeFlags.Void) ? getOptionalType(propType, /*isProperty*/ true) : + return strictNullChecks && modifiers & MappedTypeModifiers.IncludeOptional && !maybeTypeOfKind(propType, ts.TypeFlags.Undefined | ts.TypeFlags.Void) ? getOptionalType(propType, /*isProperty*/ true) : strictNullChecks && modifiers & MappedTypeModifiers.ExcludeOptional && isOptional ? getTypeWithFacts(propType, TypeFacts.NEUndefined) : propType; } - function instantiateAnonymousType(type: AnonymousType, mapper: TypeMapper, aliasSymbol?: Symbol, aliasTypeArguments?: readonly Type[]): AnonymousType { - const result = createObjectType(type.objectFlags | ObjectFlags.Instantiated, type.symbol) as AnonymousType; - if (type.objectFlags & ObjectFlags.Mapped) { - (result as MappedType).declaration = (type as MappedType).declaration; + function instantiateAnonymousType(type: ts.AnonymousType, mapper: ts.TypeMapper, aliasSymbol?: ts.Symbol, aliasTypeArguments?: readonly ts.Type[]): ts.AnonymousType { + const result = createObjectType(type.objectFlags | ts.ObjectFlags.Instantiated, type.symbol) as ts.AnonymousType; + if (type.objectFlags & ts.ObjectFlags.Mapped) { + (result as ts.MappedType).declaration = (type as ts.MappedType).declaration; // C.f. instantiateSignature - const origTypeParameter = getTypeParameterFromMappedType(type as MappedType); + const origTypeParameter = getTypeParameterFromMappedType(type as ts.MappedType); const freshTypeParameter = cloneTypeParameter(origTypeParameter); - (result as MappedType).typeParameter = freshTypeParameter; + (result as ts.MappedType).typeParameter = freshTypeParameter; mapper = combineTypeMappers(makeUnaryTypeMapper(origTypeParameter, freshTypeParameter), mapper); freshTypeParameter.mapper = mapper; } - if (type.objectFlags & ObjectFlags.InstantiationExpressionType) { - (result as InstantiationExpressionType).node = (type as InstantiationExpressionType).node; + if (type.objectFlags & ts.ObjectFlags.InstantiationExpressionType) { + (result as ts.InstantiationExpressionType).node = (type as ts.InstantiationExpressionType).node; } result.target = type; result.mapper = mapper; @@ -17100,13 +16607,13 @@ namespace ts { return result; } - function getConditionalTypeInstantiation(type: ConditionalType, mapper: TypeMapper, aliasSymbol?: Symbol, aliasTypeArguments?: readonly Type[]): Type { + function getConditionalTypeInstantiation(type: ts.ConditionalType, mapper: ts.TypeMapper, aliasSymbol?: ts.Symbol, aliasTypeArguments?: readonly ts.Type[]): ts.Type { const root = type.root; if (root.outerTypeParameters) { // We are instantiating a conditional type that has one or more type parameters in scope. Apply the // mapper to the type parameters to produce the effective list of type arguments, and compute the // instantiation cache key from the type IDs of the type arguments. - const typeArguments = map(root.outerTypeParameters, t => getMappedType(t, mapper)); + const typeArguments = ts.map(root.outerTypeParameters, t => getMappedType(t, mapper)); const id = getTypeListId(typeArguments) + getAliasId(aliasSymbol, aliasTypeArguments); let result = root.instantiations!.get(id); if (!result) { @@ -17116,7 +16623,7 @@ namespace ts { // Distributive conditional types are distributed over union types. For example, when the // distributive conditional type T extends U ? X : Y is instantiated with A | B for T, the // result is (A extends U ? X : Y) | (B extends U ? X : Y). - result = distributionType && checkType !== distributionType && distributionType.flags & (TypeFlags.Union | TypeFlags.Never) ? + result = distributionType && checkType !== distributionType && distributionType.flags & (ts.TypeFlags.Union | ts.TypeFlags.Never) ? mapTypeWithAlias(getReducedType(distributionType), t => getConditionalType(root, prependTypeMapping(checkType, t, newMapper)), aliasSymbol, aliasTypeArguments) : getConditionalType(root, newMapper, aliasSymbol, aliasTypeArguments); root.instantiations!.set(id, result); @@ -17126,13 +16633,13 @@ namespace ts { return type; } - function instantiateType(type: Type, mapper: TypeMapper | undefined): Type; - function instantiateType(type: Type | undefined, mapper: TypeMapper | undefined): Type | undefined; - function instantiateType(type: Type | undefined, mapper: TypeMapper | undefined): Type | undefined { + function instantiateType(type: ts.Type, mapper: ts.TypeMapper | undefined): ts.Type; + function instantiateType(type: ts.Type | undefined, mapper: ts.TypeMapper | undefined): ts.Type | undefined; + function instantiateType(type: ts.Type | undefined, mapper: ts.TypeMapper | undefined): ts.Type | undefined { return type && mapper ? instantiateTypeWithAlias(type, mapper, /*aliasSymbol*/ undefined, /*aliasTypeArguments*/ undefined) : type; } - function instantiateTypeWithAlias(type: Type, mapper: TypeMapper, aliasSymbol: Symbol | undefined, aliasTypeArguments: readonly Type[] | undefined): Type { + function instantiateTypeWithAlias(type: ts.Type, mapper: ts.TypeMapper, aliasSymbol: ts.Symbol | undefined, aliasTypeArguments: readonly ts.Type[] | undefined): ts.Type { if (!couldContainTypeVariables(type)) { return type; } @@ -17140,8 +16647,8 @@ namespace ts { // We have reached 100 recursive type instantiations, or 5M type instantiations caused by the same statement // or expression. There is a very high likelyhood we're dealing with a combination of infinite generic types // that perpetually generate new type identities, so we stop the recursion here by yielding the error type. - tracing?.instant(tracing.Phase.CheckTypes, "instantiateType_DepthLimit", { typeId: type.id, instantiationDepth, instantiationCount }); - error(currentNode, Diagnostics.Type_instantiation_is_excessively_deep_and_possibly_infinite); + ts.tracing?.instant(ts.tracing.Phase.CheckTypes, "instantiateType_DepthLimit", { typeId: type.id, instantiationDepth, instantiationCount }); + error(currentNode, ts.Diagnostics.Type_instantiation_is_excessively_deep_and_possibly_infinite); return errorType; } totalInstantiationCount++; @@ -17152,64 +16659,64 @@ namespace ts { return result; } - function instantiateTypeWorker(type: Type, mapper: TypeMapper, aliasSymbol: Symbol | undefined, aliasTypeArguments: readonly Type[] | undefined): Type { + function instantiateTypeWorker(type: ts.Type, mapper: ts.TypeMapper, aliasSymbol: ts.Symbol | undefined, aliasTypeArguments: readonly ts.Type[] | undefined): ts.Type { const flags = type.flags; - if (flags & TypeFlags.TypeParameter) { + if (flags & ts.TypeFlags.TypeParameter) { return getMappedType(type, mapper); } - if (flags & TypeFlags.Object) { - const objectFlags = (type as ObjectType).objectFlags; - if (objectFlags & (ObjectFlags.Reference | ObjectFlags.Anonymous | ObjectFlags.Mapped)) { - if (objectFlags & ObjectFlags.Reference && !(type as TypeReference).node) { - const resolvedTypeArguments = (type as TypeReference).resolvedTypeArguments; + if (flags & ts.TypeFlags.Object) { + const objectFlags = (type as ts.ObjectType).objectFlags; + if (objectFlags & (ts.ObjectFlags.Reference | ts.ObjectFlags.Anonymous | ts.ObjectFlags.Mapped)) { + if (objectFlags & ts.ObjectFlags.Reference && !(type as ts.TypeReference).node) { + const resolvedTypeArguments = (type as ts.TypeReference).resolvedTypeArguments; const newTypeArguments = instantiateTypes(resolvedTypeArguments, mapper); - return newTypeArguments !== resolvedTypeArguments ? createNormalizedTypeReference((type as TypeReference).target, newTypeArguments) : type; + return newTypeArguments !== resolvedTypeArguments ? createNormalizedTypeReference((type as ts.TypeReference).target, newTypeArguments) : type; } - if (objectFlags & ObjectFlags.ReverseMapped) { - return instantiateReverseMappedType(type as ReverseMappedType, mapper); + if (objectFlags & ts.ObjectFlags.ReverseMapped) { + return instantiateReverseMappedType(type as ts.ReverseMappedType, mapper); } - return getObjectTypeInstantiation(type as TypeReference | AnonymousType | MappedType, mapper, aliasSymbol, aliasTypeArguments); + return getObjectTypeInstantiation(type as ts.TypeReference | ts.AnonymousType | ts.MappedType, mapper, aliasSymbol, aliasTypeArguments); } return type; } - if (flags & TypeFlags.UnionOrIntersection) { - const origin = type.flags & TypeFlags.Union ? (type as UnionType).origin : undefined; - const types = origin && origin.flags & TypeFlags.UnionOrIntersection ? (origin as UnionOrIntersectionType).types : (type as UnionOrIntersectionType).types; + if (flags & ts.TypeFlags.UnionOrIntersection) { + const origin = type.flags & ts.TypeFlags.Union ? (type as ts.UnionType).origin : undefined; + const types = origin && origin.flags & ts.TypeFlags.UnionOrIntersection ? (origin as ts.UnionOrIntersectionType).types : (type as ts.UnionOrIntersectionType).types; const newTypes = instantiateTypes(types, mapper); if (newTypes === types && aliasSymbol === type.aliasSymbol) { return type; } const newAliasSymbol = aliasSymbol || type.aliasSymbol; const newAliasTypeArguments = aliasSymbol ? aliasTypeArguments : instantiateTypes(type.aliasTypeArguments, mapper); - return flags & TypeFlags.Intersection || origin && origin.flags & TypeFlags.Intersection ? + return flags & ts.TypeFlags.Intersection || origin && origin.flags & ts.TypeFlags.Intersection ? getIntersectionType(newTypes, newAliasSymbol, newAliasTypeArguments) : - getUnionType(newTypes, UnionReduction.Literal, newAliasSymbol, newAliasTypeArguments); + getUnionType(newTypes, ts.UnionReduction.Literal, newAliasSymbol, newAliasTypeArguments); } - if (flags & TypeFlags.Index) { - return getIndexType(instantiateType((type as IndexType).type, mapper)); + if (flags & ts.TypeFlags.Index) { + return getIndexType(instantiateType((type as ts.IndexType).type, mapper)); } - if (flags & TypeFlags.TemplateLiteral) { - return getTemplateLiteralType((type as TemplateLiteralType).texts, instantiateTypes((type as TemplateLiteralType).types, mapper)); + if (flags & ts.TypeFlags.TemplateLiteral) { + return getTemplateLiteralType((type as ts.TemplateLiteralType).texts, instantiateTypes((type as ts.TemplateLiteralType).types, mapper)); } - if (flags & TypeFlags.StringMapping) { - return getStringMappingType((type as StringMappingType).symbol, instantiateType((type as StringMappingType).type, mapper)); + if (flags & ts.TypeFlags.StringMapping) { + return getStringMappingType((type as ts.StringMappingType).symbol, instantiateType((type as ts.StringMappingType).type, mapper)); } - if (flags & TypeFlags.IndexedAccess) { + if (flags & ts.TypeFlags.IndexedAccess) { const newAliasSymbol = aliasSymbol || type.aliasSymbol; const newAliasTypeArguments = aliasSymbol ? aliasTypeArguments : instantiateTypes(type.aliasTypeArguments, mapper); - return getIndexedAccessType(instantiateType((type as IndexedAccessType).objectType, mapper), instantiateType((type as IndexedAccessType).indexType, mapper), (type as IndexedAccessType).accessFlags, /*accessNode*/ undefined, newAliasSymbol, newAliasTypeArguments); + return getIndexedAccessType(instantiateType((type as ts.IndexedAccessType).objectType, mapper), instantiateType((type as ts.IndexedAccessType).indexType, mapper), (type as ts.IndexedAccessType).accessFlags, /*accessNode*/ undefined, newAliasSymbol, newAliasTypeArguments); } - if (flags & TypeFlags.Conditional) { - return getConditionalTypeInstantiation(type as ConditionalType, combineTypeMappers((type as ConditionalType).mapper, mapper), aliasSymbol, aliasTypeArguments); + if (flags & ts.TypeFlags.Conditional) { + return getConditionalTypeInstantiation(type as ts.ConditionalType, combineTypeMappers((type as ts.ConditionalType).mapper, mapper), aliasSymbol, aliasTypeArguments); } - if (flags & TypeFlags.Substitution) { - const maybeVariable = instantiateType((type as SubstitutionType).baseType, mapper); - if (maybeVariable.flags & TypeFlags.TypeVariable) { - return getSubstitutionType(maybeVariable as TypeVariable, instantiateType((type as SubstitutionType).substitute, mapper)); + if (flags & ts.TypeFlags.Substitution) { + const maybeVariable = instantiateType((type as ts.SubstitutionType).baseType, mapper); + if (maybeVariable.flags & ts.TypeFlags.TypeVariable) { + return getSubstitutionType(maybeVariable as ts.TypeVariable, instantiateType((type as ts.SubstitutionType).substitute, mapper)); } else { - const sub = instantiateType((type as SubstitutionType).substitute, mapper); - if (sub.flags & TypeFlags.AnyOrUnknown || isTypeAssignableTo(getRestrictiveInstantiation(maybeVariable), getRestrictiveInstantiation(sub))) { + const sub = instantiateType((type as ts.SubstitutionType).substitute, mapper); + if (sub.flags & ts.TypeFlags.AnyOrUnknown || isTypeAssignableTo(getRestrictiveInstantiation(maybeVariable), getRestrictiveInstantiation(sub))) { return maybeVariable; } return sub; @@ -17218,38 +16725,34 @@ namespace ts { return type; } - function instantiateReverseMappedType(type: ReverseMappedType, mapper: TypeMapper) { + function instantiateReverseMappedType(type: ts.ReverseMappedType, mapper: ts.TypeMapper) { const innerMappedType = instantiateType(type.mappedType, mapper); - if (!(getObjectFlags(innerMappedType) & ObjectFlags.Mapped)) { + if (!(ts.getObjectFlags(innerMappedType) & ts.ObjectFlags.Mapped)) { return type; } const innerIndexType = instantiateType(type.constraintType, mapper); - if (!(innerIndexType.flags & TypeFlags.Index)) { + if (!(innerIndexType.flags & ts.TypeFlags.Index)) { return type; } - const instantiated = inferTypeForHomomorphicMappedType( - instantiateType(type.source, mapper), - innerMappedType as MappedType, - innerIndexType as IndexType - ); + const instantiated = inferTypeForHomomorphicMappedType(instantiateType(type.source, mapper), innerMappedType as ts.MappedType, innerIndexType as ts.IndexType); if (instantiated) { return instantiated; } return type; // Nested invocation of `inferTypeForHomomorphicMappedType` or the `source` instantiated into something unmappable } - function getUniqueLiteralFilledInstantiation(type: Type) { - return type.flags & (TypeFlags.Primitive | TypeFlags.AnyOrUnknown | TypeFlags.Never) ? type : + function getUniqueLiteralFilledInstantiation(type: ts.Type) { + return type.flags & (ts.TypeFlags.Primitive | ts.TypeFlags.AnyOrUnknown | ts.TypeFlags.Never) ? type : type.uniqueLiteralFilledInstantiation || (type.uniqueLiteralFilledInstantiation = instantiateType(type, uniqueLiteralMapper)); } - function getPermissiveInstantiation(type: Type) { - return type.flags & (TypeFlags.Primitive | TypeFlags.AnyOrUnknown | TypeFlags.Never) ? type : + function getPermissiveInstantiation(type: ts.Type) { + return type.flags & (ts.TypeFlags.Primitive | ts.TypeFlags.AnyOrUnknown | ts.TypeFlags.Never) ? type : type.permissiveInstantiation || (type.permissiveInstantiation = instantiateType(type, permissiveMapper)); } - function getRestrictiveInstantiation(type: Type) { - if (type.flags & (TypeFlags.Primitive | TypeFlags.AnyOrUnknown | TypeFlags.Never)) { + function getRestrictiveInstantiation(type: ts.Type) { + if (type.flags & (ts.TypeFlags.Primitive | ts.TypeFlags.AnyOrUnknown | ts.TypeFlags.Never)) { return type; } if (type.restrictiveInstantiation) { @@ -17265,44 +16768,44 @@ namespace ts { return type.restrictiveInstantiation; } - function instantiateIndexInfo(info: IndexInfo, mapper: TypeMapper) { + function instantiateIndexInfo(info: ts.IndexInfo, mapper: ts.TypeMapper) { return createIndexInfo(info.keyType, instantiateType(info.type, mapper), info.isReadonly, info.declaration); } // Returns true if the given expression contains (at any level of nesting) a function or arrow expression // that is subject to contextual typing. - function isContextSensitive(node: Expression | MethodDeclaration | ObjectLiteralElementLike | JsxAttributeLike | JsxChild): boolean { - Debug.assert(node.kind !== SyntaxKind.MethodDeclaration || isObjectLiteralMethod(node)); + function isContextSensitive(node: ts.Expression | ts.MethodDeclaration | ts.ObjectLiteralElementLike | ts.JsxAttributeLike | ts.JsxChild): boolean { + ts.Debug.assert(node.kind !== ts.SyntaxKind.MethodDeclaration || ts.isObjectLiteralMethod(node)); switch (node.kind) { - case SyntaxKind.FunctionExpression: - case SyntaxKind.ArrowFunction: - case SyntaxKind.MethodDeclaration: - case SyntaxKind.FunctionDeclaration: // Function declarations can have context when annotated with a jsdoc @type - return isContextSensitiveFunctionLikeDeclaration(node as FunctionExpression | ArrowFunction | MethodDeclaration); - case SyntaxKind.ObjectLiteralExpression: - return some((node as ObjectLiteralExpression).properties, isContextSensitive); - case SyntaxKind.ArrayLiteralExpression: - return some((node as ArrayLiteralExpression).elements, isContextSensitive); - case SyntaxKind.ConditionalExpression: - return isContextSensitive((node as ConditionalExpression).whenTrue) || - isContextSensitive((node as ConditionalExpression).whenFalse); - case SyntaxKind.BinaryExpression: - return ((node as BinaryExpression).operatorToken.kind === SyntaxKind.BarBarToken || (node as BinaryExpression).operatorToken.kind === SyntaxKind.QuestionQuestionToken) && - (isContextSensitive((node as BinaryExpression).left) || isContextSensitive((node as BinaryExpression).right)); - case SyntaxKind.PropertyAssignment: - return isContextSensitive((node as PropertyAssignment).initializer); - case SyntaxKind.ParenthesizedExpression: - return isContextSensitive((node as ParenthesizedExpression).expression); - case SyntaxKind.JsxAttributes: - return some((node as JsxAttributes).properties, isContextSensitive) || isJsxOpeningElement(node.parent) && some(node.parent.parent.children, isContextSensitive); - case SyntaxKind.JsxAttribute: { + case ts.SyntaxKind.FunctionExpression: + case ts.SyntaxKind.ArrowFunction: + case ts.SyntaxKind.MethodDeclaration: + case ts.SyntaxKind.FunctionDeclaration: // Function declarations can have context when annotated with a jsdoc @type + return isContextSensitiveFunctionLikeDeclaration(node as ts.FunctionExpression | ts.ArrowFunction | ts.MethodDeclaration); + case ts.SyntaxKind.ObjectLiteralExpression: + return ts.some((node as ts.ObjectLiteralExpression).properties, isContextSensitive); + case ts.SyntaxKind.ArrayLiteralExpression: + return ts.some((node as ts.ArrayLiteralExpression).elements, isContextSensitive); + case ts.SyntaxKind.ConditionalExpression: + return isContextSensitive((node as ts.ConditionalExpression).whenTrue) || + isContextSensitive((node as ts.ConditionalExpression).whenFalse); + case ts.SyntaxKind.BinaryExpression: + return ((node as ts.BinaryExpression).operatorToken.kind === ts.SyntaxKind.BarBarToken || (node as ts.BinaryExpression).operatorToken.kind === ts.SyntaxKind.QuestionQuestionToken) && + (isContextSensitive((node as ts.BinaryExpression).left) || isContextSensitive((node as ts.BinaryExpression).right)); + case ts.SyntaxKind.PropertyAssignment: + return isContextSensitive((node as ts.PropertyAssignment).initializer); + case ts.SyntaxKind.ParenthesizedExpression: + return isContextSensitive((node as ts.ParenthesizedExpression).expression); + case ts.SyntaxKind.JsxAttributes: + return ts.some((node as ts.JsxAttributes).properties, isContextSensitive) || ts.isJsxOpeningElement(node.parent) && ts.some(node.parent.parent.children, isContextSensitive); + case ts.SyntaxKind.JsxAttribute: { // If there is no initializer, JSX attribute has a boolean value of true which is not context sensitive. - const { initializer } = node as JsxAttribute; + const { initializer } = node as ts.JsxAttribute; return !!initializer && isContextSensitive(initializer); } - case SyntaxKind.JsxExpression: { + case ts.SyntaxKind.JsxExpression: { // It is possible to that node.expression is undefined (e.g
) - const { expression } = node as JsxExpression; + const { expression } = node as ts.JsxExpression; return !!expression && isContextSensitive(expression); } } @@ -17310,63 +16813,63 @@ namespace ts { return false; } - function isContextSensitiveFunctionLikeDeclaration(node: FunctionLikeDeclaration): boolean { - return (!isFunctionDeclaration(node) || isInJSFile(node) && !!getTypeForDeclarationFromJSDocComment(node)) && - (hasContextSensitiveParameters(node) || hasContextSensitiveReturnExpression(node)); + function isContextSensitiveFunctionLikeDeclaration(node: ts.FunctionLikeDeclaration): boolean { + return (!ts.isFunctionDeclaration(node) || ts.isInJSFile(node) && !!getTypeForDeclarationFromJSDocComment(node)) && + (ts.hasContextSensitiveParameters(node) || hasContextSensitiveReturnExpression(node)); } - function hasContextSensitiveReturnExpression(node: FunctionLikeDeclaration) { + function hasContextSensitiveReturnExpression(node: ts.FunctionLikeDeclaration) { // TODO(anhans): A block should be context-sensitive if it has a context-sensitive return value. - return !node.typeParameters && !getEffectiveReturnTypeNode(node) && !!node.body && node.body.kind !== SyntaxKind.Block && isContextSensitive(node.body); + return !node.typeParameters && !ts.getEffectiveReturnTypeNode(node) && !!node.body && node.body.kind !== ts.SyntaxKind.Block && isContextSensitive(node.body); } - function isContextSensitiveFunctionOrObjectLiteralMethod(func: Node): func is FunctionExpression | ArrowFunction | MethodDeclaration { - return (isInJSFile(func) && isFunctionDeclaration(func) || isFunctionExpressionOrArrowFunction(func) || isObjectLiteralMethod(func)) && + function isContextSensitiveFunctionOrObjectLiteralMethod(func: ts.Node): func is ts.FunctionExpression | ts.ArrowFunction | ts.MethodDeclaration { + return (ts.isInJSFile(func) && ts.isFunctionDeclaration(func) || ts.isFunctionExpressionOrArrowFunction(func) || ts.isObjectLiteralMethod(func)) && isContextSensitiveFunctionLikeDeclaration(func); } - function getTypeWithoutSignatures(type: Type): Type { - if (type.flags & TypeFlags.Object) { - const resolved = resolveStructuredTypeMembers(type as ObjectType); + function getTypeWithoutSignatures(type: ts.Type): ts.Type { + if (type.flags & ts.TypeFlags.Object) { + const resolved = resolveStructuredTypeMembers(type as ts.ObjectType); if (resolved.constructSignatures.length || resolved.callSignatures.length) { - const result = createObjectType(ObjectFlags.Anonymous, type.symbol); + const result = createObjectType(ts.ObjectFlags.Anonymous, type.symbol); result.members = resolved.members; result.properties = resolved.properties; - result.callSignatures = emptyArray; - result.constructSignatures = emptyArray; - result.indexInfos = emptyArray; + result.callSignatures = ts.emptyArray; + result.constructSignatures = ts.emptyArray; + result.indexInfos = ts.emptyArray; return result; } } - else if (type.flags & TypeFlags.Intersection) { - return getIntersectionType(map((type as IntersectionType).types, getTypeWithoutSignatures)); + else if (type.flags & ts.TypeFlags.Intersection) { + return getIntersectionType(ts.map((type as ts.IntersectionType).types, getTypeWithoutSignatures)); } return type; } // TYPE CHECKING - function isTypeIdenticalTo(source: Type, target: Type): boolean { + function isTypeIdenticalTo(source: ts.Type, target: ts.Type): boolean { return isTypeRelatedTo(source, target, identityRelation); } - function compareTypesIdentical(source: Type, target: Type): Ternary { - return isTypeRelatedTo(source, target, identityRelation) ? Ternary.True : Ternary.False; + function compareTypesIdentical(source: ts.Type, target: ts.Type): ts.Ternary { + return isTypeRelatedTo(source, target, identityRelation) ? ts.Ternary.True : ts.Ternary.False; } - function compareTypesAssignable(source: Type, target: Type): Ternary { - return isTypeRelatedTo(source, target, assignableRelation) ? Ternary.True : Ternary.False; + function compareTypesAssignable(source: ts.Type, target: ts.Type): ts.Ternary { + return isTypeRelatedTo(source, target, assignableRelation) ? ts.Ternary.True : ts.Ternary.False; } - function compareTypesSubtypeOf(source: Type, target: Type): Ternary { - return isTypeRelatedTo(source, target, subtypeRelation) ? Ternary.True : Ternary.False; + function compareTypesSubtypeOf(source: ts.Type, target: ts.Type): ts.Ternary { + return isTypeRelatedTo(source, target, subtypeRelation) ? ts.Ternary.True : ts.Ternary.False; } - function isTypeSubtypeOf(source: Type, target: Type): boolean { + function isTypeSubtypeOf(source: ts.Type, target: ts.Type): boolean { return isTypeRelatedTo(source, target, subtypeRelation); } - function isTypeAssignableTo(source: Type, target: Type): boolean { + function isTypeAssignableTo(source: ts.Type, target: ts.Type): boolean { return isTypeRelatedTo(source, target, assignableRelation); } @@ -17378,12 +16881,12 @@ namespace ts { // T occurs directly or indirectly in an 'extends' clause of S. // Note that this check ignores type parameters and only considers the // inheritance hierarchy. - function isTypeDerivedFrom(source: Type, target: Type): boolean { - return source.flags & TypeFlags.Union ? every((source as UnionType).types, t => isTypeDerivedFrom(t, target)) : - target.flags & TypeFlags.Union ? some((target as UnionType).types, t => isTypeDerivedFrom(source, t)) : - source.flags & TypeFlags.InstantiableNonPrimitive ? isTypeDerivedFrom(getBaseConstraintOfType(source) || unknownType, target) : - target === globalObjectType ? !!(source.flags & (TypeFlags.Object | TypeFlags.NonPrimitive)) : - target === globalFunctionType ? !!(source.flags & TypeFlags.Object) && isFunctionObjectType(source as ObjectType) : + function isTypeDerivedFrom(source: ts.Type, target: ts.Type): boolean { + return source.flags & ts.TypeFlags.Union ? ts.every((source as ts.UnionType).types, t => isTypeDerivedFrom(t, target)) : + target.flags & ts.TypeFlags.Union ? ts.some((target as ts.UnionType).types, t => isTypeDerivedFrom(source, t)) : + source.flags & ts.TypeFlags.InstantiableNonPrimitive ? isTypeDerivedFrom(getBaseConstraintOfType(source) || unknownType, target) : + target === globalObjectType ? !!(source.flags & (ts.TypeFlags.Object | ts.TypeFlags.NonPrimitive)) : + target === globalFunctionType ? !!(source.flags & ts.TypeFlags.Object) && isFunctionObjectType(source as ts.ObjectType) : hasBaseType(source, getTargetType(target)) || (isArrayType(target) && !isReadonlyArrayType(target) && isTypeDerivedFrom(source, globalReadonlyArrayType)); } @@ -17397,15 +16900,17 @@ namespace ts { * - the types of `case` clause expressions and their respective `switch` expressions. * - the type of an expression in a type assertion with the type being asserted. */ - function isTypeComparableTo(source: Type, target: Type): boolean { + function isTypeComparableTo(source: ts.Type, target: ts.Type): boolean { return isTypeRelatedTo(source, target, comparableRelation); } - function areTypesComparable(type1: Type, type2: Type): boolean { + function areTypesComparable(type1: ts.Type, type2: ts.Type): boolean { return isTypeComparableTo(type1, type2) || isTypeComparableTo(type2, type1); } - function checkTypeAssignableTo(source: Type, target: Type, errorNode: Node | undefined, headMessage?: DiagnosticMessage, containingMessageChain?: () => DiagnosticMessageChain | undefined, errorOutputObject?: { errors?: Diagnostic[] }): boolean { + function checkTypeAssignableTo(source: ts.Type, target: ts.Type, errorNode: ts.Node | undefined, headMessage?: ts.DiagnosticMessage, containingMessageChain?: () => ts.DiagnosticMessageChain | undefined, errorOutputObject?: { + errors?: ts.Diagnostic[]; + }): boolean { return checkTypeRelatedTo(source, target, assignableRelation, errorNode, headMessage, containingMessageChain, errorOutputObject); } @@ -17413,148 +16918,123 @@ namespace ts { * Like `checkTypeAssignableTo`, but if it would issue an error, instead performs structural comparisons of the types using the given expression node to * attempt to issue more specific errors on, for example, specific object literal properties or tuple members. */ - function checkTypeAssignableToAndOptionallyElaborate(source: Type, target: Type, errorNode: Node | undefined, expr: Expression | undefined, headMessage?: DiagnosticMessage, containingMessageChain?: () => DiagnosticMessageChain | undefined): boolean { + function checkTypeAssignableToAndOptionallyElaborate(source: ts.Type, target: ts.Type, errorNode: ts.Node | undefined, expr: ts.Expression | undefined, headMessage?: ts.DiagnosticMessage, containingMessageChain?: () => ts.DiagnosticMessageChain | undefined): boolean { return checkTypeRelatedToAndOptionallyElaborate(source, target, assignableRelation, errorNode, expr, headMessage, containingMessageChain, /*errorOutputContainer*/ undefined); } - function checkTypeRelatedToAndOptionallyElaborate( - source: Type, - target: Type, - relation: ESMap, - errorNode: Node | undefined, - expr: Expression | undefined, - headMessage: DiagnosticMessage | undefined, - containingMessageChain: (() => DiagnosticMessageChain | undefined) | undefined, - errorOutputContainer: { errors?: Diagnostic[], skipLogging?: boolean } | undefined - ): boolean { - if (isTypeRelatedTo(source, target, relation)) return true; + function checkTypeRelatedToAndOptionallyElaborate(source: ts.Type, target: ts.Type, relation: ts.ESMap, errorNode: ts.Node | undefined, expr: ts.Expression | undefined, headMessage: ts.DiagnosticMessage | undefined, containingMessageChain: (() => ts.DiagnosticMessageChain | undefined) | undefined, errorOutputContainer: { + errors?: ts.Diagnostic[]; + skipLogging?: boolean; + } | undefined): boolean { + if (isTypeRelatedTo(source, target, relation)) + return true; if (!errorNode || !elaborateError(expr, source, target, relation, headMessage, containingMessageChain, errorOutputContainer)) { return checkTypeRelatedTo(source, target, relation, errorNode, headMessage, containingMessageChain, errorOutputContainer); } return false; } - function isOrHasGenericConditional(type: Type): boolean { - return !!(type.flags & TypeFlags.Conditional || (type.flags & TypeFlags.Intersection && some((type as IntersectionType).types, isOrHasGenericConditional))); + function isOrHasGenericConditional(type: ts.Type): boolean { + return !!(type.flags & ts.TypeFlags.Conditional || (type.flags & ts.TypeFlags.Intersection && ts.some((type as ts.IntersectionType).types, isOrHasGenericConditional))); } - function elaborateError( - node: Expression | undefined, - source: Type, - target: Type, - relation: ESMap, - headMessage: DiagnosticMessage | undefined, - containingMessageChain: (() => DiagnosticMessageChain | undefined) | undefined, - errorOutputContainer: { errors?: Diagnostic[], skipLogging?: boolean } | undefined - ): boolean { - if (!node || isOrHasGenericConditional(target)) return false; + function elaborateError(node: ts.Expression | undefined, source: ts.Type, target: ts.Type, relation: ts.ESMap, headMessage: ts.DiagnosticMessage | undefined, containingMessageChain: (() => ts.DiagnosticMessageChain | undefined) | undefined, errorOutputContainer: { + errors?: ts.Diagnostic[]; + skipLogging?: boolean; + } | undefined): boolean { + if (!node || isOrHasGenericConditional(target)) + return false; if (!checkTypeRelatedTo(source, target, relation, /*errorNode*/ undefined) && elaborateDidYouMeanToCallOrConstruct(node, source, target, relation, headMessage, containingMessageChain, errorOutputContainer)) { return true; } switch (node.kind) { - case SyntaxKind.JsxExpression: - case SyntaxKind.ParenthesizedExpression: - return elaborateError((node as ParenthesizedExpression | JsxExpression).expression, source, target, relation, headMessage, containingMessageChain, errorOutputContainer); - case SyntaxKind.BinaryExpression: - switch ((node as BinaryExpression).operatorToken.kind) { - case SyntaxKind.EqualsToken: - case SyntaxKind.CommaToken: - return elaborateError((node as BinaryExpression).right, source, target, relation, headMessage, containingMessageChain, errorOutputContainer); + case ts.SyntaxKind.JsxExpression: + case ts.SyntaxKind.ParenthesizedExpression: + return elaborateError((node as ts.ParenthesizedExpression | ts.JsxExpression).expression, source, target, relation, headMessage, containingMessageChain, errorOutputContainer); + case ts.SyntaxKind.BinaryExpression: + switch ((node as ts.BinaryExpression).operatorToken.kind) { + case ts.SyntaxKind.EqualsToken: + case ts.SyntaxKind.CommaToken: + return elaborateError((node as ts.BinaryExpression).right, source, target, relation, headMessage, containingMessageChain, errorOutputContainer); } break; - case SyntaxKind.ObjectLiteralExpression: - return elaborateObjectLiteral(node as ObjectLiteralExpression, source, target, relation, containingMessageChain, errorOutputContainer); - case SyntaxKind.ArrayLiteralExpression: - return elaborateArrayLiteral(node as ArrayLiteralExpression, source, target, relation, containingMessageChain, errorOutputContainer); - case SyntaxKind.JsxAttributes: - return elaborateJsxComponents(node as JsxAttributes, source, target, relation, containingMessageChain, errorOutputContainer); - case SyntaxKind.ArrowFunction: - return elaborateArrowFunction(node as ArrowFunction, source, target, relation, containingMessageChain, errorOutputContainer); + case ts.SyntaxKind.ObjectLiteralExpression: + return elaborateObjectLiteral(node as ts.ObjectLiteralExpression, source, target, relation, containingMessageChain, errorOutputContainer); + case ts.SyntaxKind.ArrayLiteralExpression: + return elaborateArrayLiteral(node as ts.ArrayLiteralExpression, source, target, relation, containingMessageChain, errorOutputContainer); + case ts.SyntaxKind.JsxAttributes: + return elaborateJsxComponents(node as ts.JsxAttributes, source, target, relation, containingMessageChain, errorOutputContainer); + case ts.SyntaxKind.ArrowFunction: + return elaborateArrowFunction(node as ts.ArrowFunction, source, target, relation, containingMessageChain, errorOutputContainer); } return false; } - - function elaborateDidYouMeanToCallOrConstruct( - node: Expression, - source: Type, - target: Type, - relation: ESMap, - headMessage: DiagnosticMessage | undefined, - containingMessageChain: (() => DiagnosticMessageChain | undefined) | undefined, - errorOutputContainer: { errors?: Diagnostic[], skipLogging?: boolean } | undefined - ): boolean { - const callSignatures = getSignaturesOfType(source, SignatureKind.Call); - const constructSignatures = getSignaturesOfType(source, SignatureKind.Construct); + function elaborateDidYouMeanToCallOrConstruct(node: ts.Expression, source: ts.Type, target: ts.Type, relation: ts.ESMap, headMessage: ts.DiagnosticMessage | undefined, containingMessageChain: (() => ts.DiagnosticMessageChain | undefined) | undefined, errorOutputContainer: { + errors?: ts.Diagnostic[]; + skipLogging?: boolean; + } | undefined): boolean { + const callSignatures = getSignaturesOfType(source, ts.SignatureKind.Call); + const constructSignatures = getSignaturesOfType(source, ts.SignatureKind.Construct); for (const signatures of [constructSignatures, callSignatures]) { - if (some(signatures, s => { + if (ts.some(signatures, s => { const returnType = getReturnTypeOfSignature(s); - return !(returnType.flags & (TypeFlags.Any | TypeFlags.Never)) && checkTypeRelatedTo(returnType, target, relation, /*errorNode*/ undefined); + return !(returnType.flags & (ts.TypeFlags.Any | ts.TypeFlags.Never)) && checkTypeRelatedTo(returnType, target, relation, /*errorNode*/ undefined); })) { - const resultObj: { errors?: Diagnostic[] } = errorOutputContainer || {}; + const resultObj: { + errors?: ts.Diagnostic[]; + } = errorOutputContainer || {}; checkTypeAssignableTo(source, target, node, headMessage, containingMessageChain, resultObj); const diagnostic = resultObj.errors![resultObj.errors!.length - 1]; - addRelatedInfo(diagnostic, createDiagnosticForNode( - node, - signatures === constructSignatures ? Diagnostics.Did_you_mean_to_use_new_with_this_expression : Diagnostics.Did_you_mean_to_call_this_expression - )); + ts.addRelatedInfo(diagnostic, ts.createDiagnosticForNode(node, signatures === constructSignatures ? ts.Diagnostics.Did_you_mean_to_use_new_with_this_expression : ts.Diagnostics.Did_you_mean_to_call_this_expression)); return true; } } return false; } - function elaborateArrowFunction( - node: ArrowFunction, - source: Type, - target: Type, - relation: ESMap, - containingMessageChain: (() => DiagnosticMessageChain | undefined) | undefined, - errorOutputContainer: { errors?: Diagnostic[], skipLogging?: boolean } | undefined - ): boolean { + function elaborateArrowFunction(node: ts.ArrowFunction, source: ts.Type, target: ts.Type, relation: ts.ESMap, containingMessageChain: (() => ts.DiagnosticMessageChain | undefined) | undefined, errorOutputContainer: { + errors?: ts.Diagnostic[]; + skipLogging?: boolean; + } | undefined): boolean { // Don't elaborate blocks - if (isBlock(node.body)) { + if (ts.isBlock(node.body)) { return false; } // Or functions with annotated parameter types - if (some(node.parameters, ts.hasType)) { + if (ts.some(node.parameters, ts.hasType)) { return false; } const sourceSig = getSingleCallSignature(source); if (!sourceSig) { return false; } - const targetSignatures = getSignaturesOfType(target, SignatureKind.Call); - if (!length(targetSignatures)) { + const targetSignatures = getSignaturesOfType(target, ts.SignatureKind.Call); + if (!ts.length(targetSignatures)) { return false; } const returnExpression = node.body; const sourceReturn = getReturnTypeOfSignature(sourceSig); - const targetReturn = getUnionType(map(targetSignatures, getReturnTypeOfSignature)); + const targetReturn = getUnionType(ts.map(targetSignatures, getReturnTypeOfSignature)); if (!checkTypeRelatedTo(sourceReturn, targetReturn, relation, /*errorNode*/ undefined)) { const elaborated = returnExpression && elaborateError(returnExpression, sourceReturn, targetReturn, relation, /*headMessage*/ undefined, containingMessageChain, errorOutputContainer); if (elaborated) { return elaborated; } - const resultObj: { errors?: Diagnostic[] } = errorOutputContainer || {}; + const resultObj: { + errors?: ts.Diagnostic[]; + } = errorOutputContainer || {}; checkTypeRelatedTo(sourceReturn, targetReturn, relation, returnExpression, /*message*/ undefined, containingMessageChain, resultObj); if (resultObj.errors) { - if (target.symbol && length(target.symbol.declarations)) { - addRelatedInfo(resultObj.errors[resultObj.errors.length - 1], createDiagnosticForNode( - target.symbol.declarations![0], - Diagnostics.The_expected_type_comes_from_the_return_type_of_this_signature, - )); + if (target.symbol && ts.length(target.symbol.declarations)) { + ts.addRelatedInfo(resultObj.errors[resultObj.errors.length - 1], ts.createDiagnosticForNode(target.symbol.declarations![0], ts.Diagnostics.The_expected_type_comes_from_the_return_type_of_this_signature)); } - if ((getFunctionFlags(node) & FunctionFlags.Async) === 0 + if ((ts.getFunctionFlags(node) & ts.FunctionFlags.Async) === 0 // exclude cases where source itself is promisy - this way we don't make a suggestion when relating // an IPromise and a Promise that are slightly different - && !getTypeOfPropertyOfType(sourceReturn, "then" as __String) - && checkTypeRelatedTo(createPromiseType(sourceReturn), targetReturn, relation, /*errorNode*/ undefined) - ) { - addRelatedInfo(resultObj.errors[resultObj.errors.length - 1], createDiagnosticForNode( - node, - Diagnostics.Did_you_mean_to_mark_this_function_as_async - )); + && !getTypeOfPropertyOfType(sourceReturn, "then" as ts.__String) + && checkTypeRelatedTo(createPromiseType(sourceReturn), targetReturn, relation, /*errorNode*/ undefined)) { + ts.addRelatedInfo(resultObj.errors[resultObj.errors.length - 1], ts.createDiagnosticForNode(node, ts.Diagnostics.Did_you_mean_to_mark_this_function_as_async)); } return true; } @@ -17562,20 +17042,20 @@ namespace ts { return false; } - function getBestMatchIndexedAccessTypeOrUndefined(source: Type, target: Type, nameType: Type) { + function getBestMatchIndexedAccessTypeOrUndefined(source: ts.Type, target: ts.Type, nameType: ts.Type) { const idx = getIndexedAccessTypeOrUndefined(target, nameType); if (idx) { return idx; } - if (target.flags & TypeFlags.Union) { - const best = getBestMatchingType(source, target as UnionType); + if (target.flags & ts.TypeFlags.Union) { + const best = getBestMatchingType(source, target as ts.UnionType); if (best) { return getIndexedAccessTypeOrUndefined(best, nameType); } } } - function checkExpressionForMutableLocationWithContextualType(next: Expression, sourcePropType: Type) { + function checkExpressionForMutableLocationWithContextualType(next: ts.Expression, sourcePropType: ts.Type) { next.contextualType = sourcePropType; try { return checkExpressionForMutableLocation(next, CheckMode.Contextual, sourcePropType); @@ -17585,45 +17065,50 @@ namespace ts { } } - type ElaborationIterator = IterableIterator<{ errorNode: Node, innerExpression: Expression | undefined, nameType: Type, errorMessage?: DiagnosticMessage | undefined }>; + type ElaborationIterator = IterableIterator<{ + errorNode: ts.Node; + innerExpression: ts.Expression | undefined; + nameType: ts.Type; + errorMessage?: ts.DiagnosticMessage | undefined; + }>; /** * For every element returned from the iterator, checks that element to issue an error on a property of that element's type * If that element would issue an error, we first attempt to dive into that element's inner expression and issue a more specific error by recuring into `elaborateError` * Otherwise, we issue an error on _every_ element which fail the assignability check */ - function elaborateElementwise( - iterator: ElaborationIterator, - source: Type, - target: Type, - relation: ESMap, - containingMessageChain: (() => DiagnosticMessageChain | undefined) | undefined, - errorOutputContainer: { errors?: Diagnostic[], skipLogging?: boolean } | undefined - ) { + function elaborateElementwise(iterator: ElaborationIterator, source: ts.Type, target: ts.Type, relation: ts.ESMap, containingMessageChain: (() => ts.DiagnosticMessageChain | undefined) | undefined, errorOutputContainer: { + errors?: ts.Diagnostic[]; + skipLogging?: boolean; + } | undefined) { // Assignability failure - check each prop individually, and if that fails, fall back on the bad error span let reportedError = false; for (let status = iterator.next(); !status.done; status = iterator.next()) { const { errorNode: prop, innerExpression: next, nameType, errorMessage } = status.value; let targetPropType = getBestMatchIndexedAccessTypeOrUndefined(source, target, nameType); - if (!targetPropType || targetPropType.flags & TypeFlags.IndexedAccess) continue; // Don't elaborate on indexes on generic variables + if (!targetPropType || targetPropType.flags & ts.TypeFlags.IndexedAccess) + continue; // Don't elaborate on indexes on generic variables let sourcePropType = getIndexedAccessTypeOrUndefined(source, nameType); - if (!sourcePropType) continue; + if (!sourcePropType) + continue; const propName = getPropertyNameFromIndex(nameType, /*accessNode*/ undefined); if (!checkTypeRelatedTo(sourcePropType, targetPropType, relation, /*errorNode*/ undefined)) { const elaborated = next && elaborateError(next, sourcePropType, targetPropType, relation, /*headMessage*/ undefined, containingMessageChain, errorOutputContainer); reportedError = true; if (!elaborated) { // Issue error on the prop itself, since the prop couldn't elaborate the error - const resultObj: { errors?: Diagnostic[] } = errorOutputContainer || {}; + const resultObj: { + errors?: ts.Diagnostic[]; + } = errorOutputContainer || {}; // Use the expression type, if available const specificSource = next ? checkExpressionForMutableLocationWithContextualType(next, sourcePropType) : sourcePropType; if (exactOptionalPropertyTypes && isExactOptionalPropertyMismatch(specificSource, targetPropType)) { - const diag = createDiagnosticForNode(prop, Diagnostics.Type_0_is_not_assignable_to_type_1_with_exactOptionalPropertyTypes_Colon_true_Consider_adding_undefined_to_the_type_of_the_target, typeToString(specificSource), typeToString(targetPropType)); + const diag = ts.createDiagnosticForNode(prop, ts.Diagnostics.Type_0_is_not_assignable_to_type_1_with_exactOptionalPropertyTypes_Colon_true_Consider_adding_undefined_to_the_type_of_the_target, typeToString(specificSource), typeToString(targetPropType)); diagnostics.add(diag); resultObj.errors = [diag]; } else { - const targetIsOptional = !!(propName && (getPropertyOfType(target, propName) || unknownSymbol).flags & SymbolFlags.Optional); - const sourceIsOptional = !!(propName && (getPropertyOfType(source, propName) || unknownSymbol).flags & SymbolFlags.Optional); + const targetIsOptional = !!(propName && (getPropertyOfType(target, propName) || unknownSymbol).flags & ts.SymbolFlags.Optional); + const sourceIsOptional = !!(propName && (getPropertyOfType(source, propName) || unknownSymbol).flags & ts.SymbolFlags.Optional); targetPropType = removeMissingType(targetPropType, targetIsOptional); sourcePropType = removeMissingType(sourcePropType, targetIsOptional && sourceIsOptional); const result = checkTypeRelatedTo(specificSource, targetPropType, relation, prop, errorMessage, containingMessageChain, resultObj); @@ -17640,21 +17125,16 @@ namespace ts { let issuedElaboration = false; if (!targetProp) { const indexInfo = getApplicableIndexInfo(target, nameType); - if (indexInfo && indexInfo.declaration && !getSourceFileOfNode(indexInfo.declaration).hasNoDefaultLib) { + if (indexInfo && indexInfo.declaration && !ts.getSourceFileOfNode(indexInfo.declaration).hasNoDefaultLib) { issuedElaboration = true; - addRelatedInfo(reportedDiag, createDiagnosticForNode(indexInfo.declaration, Diagnostics.The_expected_type_comes_from_this_index_signature)); + ts.addRelatedInfo(reportedDiag, ts.createDiagnosticForNode(indexInfo.declaration, ts.Diagnostics.The_expected_type_comes_from_this_index_signature)); } } - if (!issuedElaboration && (targetProp && length(targetProp.declarations) || target.symbol && length(target.symbol.declarations))) { - const targetNode = targetProp && length(targetProp.declarations) ? targetProp.declarations![0] : target.symbol.declarations![0]; - if (!getSourceFileOfNode(targetNode).hasNoDefaultLib) { - addRelatedInfo(reportedDiag, createDiagnosticForNode( - targetNode, - Diagnostics.The_expected_type_comes_from_property_0_which_is_declared_here_on_type_1, - propertyName && !(nameType.flags & TypeFlags.UniqueESSymbol) ? unescapeLeadingUnderscores(propertyName) : typeToString(nameType), - typeToString(target) - )); + if (!issuedElaboration && (targetProp && ts.length(targetProp.declarations) || target.symbol && ts.length(target.symbol.declarations))) { + const targetNode = targetProp && ts.length(targetProp.declarations) ? targetProp.declarations![0] : target.symbol.declarations![0]; + if (!ts.getSourceFileOfNode(targetNode).hasNoDefaultLib) { + ts.addRelatedInfo(reportedDiag, ts.createDiagnosticForNode(targetNode, ts.Diagnostics.The_expected_type_comes_from_property_0_which_is_declared_here_on_type_1, propertyName && !(nameType.flags & ts.TypeFlags.UniqueESSymbol) ? ts.unescapeLeadingUnderscores(propertyName) : typeToString(nameType), typeToString(target))); } } } @@ -17664,16 +17144,19 @@ namespace ts { return reportedError; } - function *generateJsxAttributes(node: JsxAttributes): ElaborationIterator { - if (!length(node.properties)) return; + function* generateJsxAttributes(node: ts.JsxAttributes): ElaborationIterator { + if (!ts.length(node.properties)) + return; for (const prop of node.properties) { - if (isJsxSpreadAttribute(prop) || isHyphenatedJsxName(idText(prop.name))) continue; - yield { errorNode: prop.name, innerExpression: prop.initializer, nameType: getStringLiteralType(idText(prop.name)) }; + if (ts.isJsxSpreadAttribute(prop) || isHyphenatedJsxName(ts.idText(prop.name))) + continue; + yield { errorNode: prop.name, innerExpression: prop.initializer, nameType: getStringLiteralType(ts.idText(prop.name)) }; } } - function *generateJsxChildren(node: JsxElement, getInvalidTextDiagnostic: () => DiagnosticMessage): ElaborationIterator { - if (!length(node.children)) return; + function* generateJsxChildren(node: ts.JsxElement, getInvalidTextDiagnostic: () => ts.DiagnosticMessage): ElaborationIterator { + if (!ts.length(node.children)) + return; let memberOffset = 0; for (let i = 0; i < node.children.length; i++) { const child = node.children[i]; @@ -17688,48 +17171,44 @@ namespace ts { } } - function getElaborationElementForJsxChild(child: JsxChild, nameType: LiteralType, getInvalidTextDiagnostic: () => DiagnosticMessage) { + function getElaborationElementForJsxChild(child: ts.JsxChild, nameType: ts.LiteralType, getInvalidTextDiagnostic: () => ts.DiagnosticMessage) { switch (child.kind) { - case SyntaxKind.JsxExpression: + case ts.SyntaxKind.JsxExpression: // child is of the type of the expression return { errorNode: child, innerExpression: child.expression, nameType }; - case SyntaxKind.JsxText: + case ts.SyntaxKind.JsxText: if (child.containsOnlyTriviaWhiteSpaces) { break; // Whitespace only jsx text isn't real jsx text } // child is a string return { errorNode: child, innerExpression: undefined, nameType, errorMessage: getInvalidTextDiagnostic() }; - case SyntaxKind.JsxElement: - case SyntaxKind.JsxSelfClosingElement: - case SyntaxKind.JsxFragment: + case ts.SyntaxKind.JsxElement: + case ts.SyntaxKind.JsxSelfClosingElement: + case ts.SyntaxKind.JsxFragment: // child is of type JSX.Element return { errorNode: child, innerExpression: child, nameType }; default: - return Debug.assertNever(child, "Found invalid jsx child"); + return ts.Debug.assertNever(child, "Found invalid jsx child"); } } - function elaborateJsxComponents( - node: JsxAttributes, - source: Type, - target: Type, - relation: ESMap, - containingMessageChain: (() => DiagnosticMessageChain | undefined) | undefined, - errorOutputContainer: { errors?: Diagnostic[], skipLogging?: boolean } | undefined - ) { + function elaborateJsxComponents(node: ts.JsxAttributes, source: ts.Type, target: ts.Type, relation: ts.ESMap, containingMessageChain: (() => ts.DiagnosticMessageChain | undefined) | undefined, errorOutputContainer: { + errors?: ts.Diagnostic[]; + skipLogging?: boolean; + } | undefined) { let result = elaborateElementwise(generateJsxAttributes(node), source, target, relation, containingMessageChain, errorOutputContainer); - let invalidTextDiagnostic: DiagnosticMessage | undefined; - if (isJsxOpeningElement(node.parent) && isJsxElement(node.parent.parent)) { + let invalidTextDiagnostic: ts.DiagnosticMessage | undefined; + if (ts.isJsxOpeningElement(node.parent) && ts.isJsxElement(node.parent.parent)) { const containingElement = node.parent.parent; const childPropName = getJsxElementChildrenPropertyName(getJsxNamespaceAt(node)); - const childrenPropName = childPropName === undefined ? "children" : unescapeLeadingUnderscores(childPropName); + const childrenPropName = childPropName === undefined ? "children" : ts.unescapeLeadingUnderscores(childPropName); const childrenNameType = getStringLiteralType(childrenPropName); const childrenTargetType = getIndexedAccessType(target, childrenNameType); - const validChildren = getSemanticJsxChildren(containingElement.children); - if (!length(validChildren)) { + const validChildren = ts.getSemanticJsxChildren(containingElement.children); + if (!ts.length(validChildren)) { return result; } - const moreThanOneRealChildren = length(validChildren) > 1; + const moreThanOneRealChildren = ts.length(validChildren) > 1; const arrayLikeTargetParts = filterType(childrenTargetType, isArrayOrTupleLikeType); const nonArrayLikeTargetParts = filterType(childrenTargetType, t => !isArrayOrTupleLikeType(t)); if (moreThanOneRealChildren) { @@ -17741,12 +17220,7 @@ namespace ts { else if (!isTypeRelatedTo(getIndexedAccessType(source, childrenNameType), childrenTargetType, relation)) { // arity mismatch result = true; - const diag = error( - containingElement.openingElement.tagName, - Diagnostics.This_JSX_tag_s_0_prop_expects_a_single_child_of_type_1_but_multiple_children_were_provided, - childrenPropName, - typeToString(childrenTargetType) - ); + const diag = error(containingElement.openingElement.tagName, ts.Diagnostics.This_JSX_tag_s_0_prop_expects_a_single_child_of_type_1_but_multiple_children_were_provided, childrenPropName, typeToString(childrenTargetType)); if (errorOutputContainer && errorOutputContainer.skipLogging) { (errorOutputContainer.errors || (errorOutputContainer.errors = [])).push(diag); } @@ -17757,25 +17231,13 @@ namespace ts { const child = validChildren[0]; const elem = getElaborationElementForJsxChild(child, childrenNameType, getInvalidTextualChildDiagnostic); if (elem) { - result = elaborateElementwise( - (function*() { yield elem; })(), - source, - target, - relation, - containingMessageChain, - errorOutputContainer - ) || result; + result = elaborateElementwise((function* () { yield elem; })(), source, target, relation, containingMessageChain, errorOutputContainer) || result; } } else if (!isTypeRelatedTo(getIndexedAccessType(source, childrenNameType), childrenTargetType, relation)) { // arity mismatch result = true; - const diag = error( - containingElement.openingElement.tagName, - Diagnostics.This_JSX_tag_s_0_prop_expects_type_1_which_requires_multiple_children_but_only_a_single_child_was_provided, - childrenPropName, - typeToString(childrenTargetType) - ); + const diag = error(containingElement.openingElement.tagName, ts.Diagnostics.This_JSX_tag_s_0_prop_expects_type_1_which_requires_multiple_children_but_only_a_single_child_was_provided, childrenPropName, typeToString(childrenTargetType)); if (errorOutputContainer && errorOutputContainer.skipLogging) { (errorOutputContainer.errors || (errorOutputContainer.errors = [])).push(diag); } @@ -17786,39 +17248,39 @@ namespace ts { function getInvalidTextualChildDiagnostic() { if (!invalidTextDiagnostic) { - const tagNameText = getTextOfNode(node.parent.tagName); + const tagNameText = ts.getTextOfNode(node.parent.tagName); const childPropName = getJsxElementChildrenPropertyName(getJsxNamespaceAt(node)); - const childrenPropName = childPropName === undefined ? "children" : unescapeLeadingUnderscores(childPropName); + const childrenPropName = childPropName === undefined ? "children" : ts.unescapeLeadingUnderscores(childPropName); const childrenTargetType = getIndexedAccessType(target, getStringLiteralType(childrenPropName)); - const diagnostic = Diagnostics._0_components_don_t_accept_text_as_child_elements_Text_in_JSX_has_the_type_string_but_the_expected_type_of_1_is_2; - invalidTextDiagnostic = { ...diagnostic, key: "!!ALREADY FORMATTED!!", message: formatMessage(/*_dummy*/ undefined, diagnostic, tagNameText, childrenPropName, typeToString(childrenTargetType)) }; + const diagnostic = ts.Diagnostics._0_components_don_t_accept_text_as_child_elements_Text_in_JSX_has_the_type_string_but_the_expected_type_of_1_is_2; + invalidTextDiagnostic = { ...diagnostic, key: "!!ALREADY FORMATTED!!", message: ts.formatMessage(/*_dummy*/ undefined, diagnostic, tagNameText, childrenPropName, typeToString(childrenTargetType)) }; } return invalidTextDiagnostic; } } - function *generateLimitedTupleElements(node: ArrayLiteralExpression, target: Type): ElaborationIterator { - const len = length(node.elements); - if (!len) return; + function* generateLimitedTupleElements(node: ts.ArrayLiteralExpression, target: ts.Type): ElaborationIterator { + const len = ts.length(node.elements); + if (!len) + return; for (let i = 0; i < len; i++) { // Skip elements which do not exist in the target - a length error on the tuple overall is likely better than an error on a mismatched index signature - if (isTupleLikeType(target) && !getPropertyOfType(target, ("" + i) as __String)) continue; + if (isTupleLikeType(target) && !getPropertyOfType(target, ("" + i) as ts.__String)) + continue; const elem = node.elements[i]; - if (isOmittedExpression(elem)) continue; + if (ts.isOmittedExpression(elem)) + continue; const nameType = getNumberLiteralType(i); yield { errorNode: elem, innerExpression: elem, nameType }; } } - function elaborateArrayLiteral( - node: ArrayLiteralExpression, - source: Type, - target: Type, - relation: ESMap, - containingMessageChain: (() => DiagnosticMessageChain | undefined) | undefined, - errorOutputContainer: { errors?: Diagnostic[], skipLogging?: boolean } | undefined - ) { - if (target.flags & TypeFlags.Primitive) return false; + function elaborateArrayLiteral(node: ts.ArrayLiteralExpression, source: ts.Type, target: ts.Type, relation: ts.ESMap, containingMessageChain: (() => ts.DiagnosticMessageChain | undefined) | undefined, errorOutputContainer: { + errors?: ts.Diagnostic[]; + skipLogging?: boolean; + } | undefined) { + if (target.flags & ts.TypeFlags.Primitive) + return false; if (isTupleLikeType(source)) { return elaborateElementwise(generateLimitedTupleElements(node, target), source, target, relation, containingMessageChain, errorOutputContainer); } @@ -17839,39 +17301,38 @@ namespace ts { } } - function *generateObjectLiteralElements(node: ObjectLiteralExpression): ElaborationIterator { - if (!length(node.properties)) return; + function* generateObjectLiteralElements(node: ts.ObjectLiteralExpression): ElaborationIterator { + if (!ts.length(node.properties)) + return; for (const prop of node.properties) { - if (isSpreadAssignment(prop)) continue; - const type = getLiteralTypeFromProperty(getSymbolOfNode(prop), TypeFlags.StringOrNumberLiteralOrUnique); - if (!type || (type.flags & TypeFlags.Never)) { + if (ts.isSpreadAssignment(prop)) + continue; + const type = getLiteralTypeFromProperty(getSymbolOfNode(prop), ts.TypeFlags.StringOrNumberLiteralOrUnique); + if (!type || (type.flags & ts.TypeFlags.Never)) { continue; } switch (prop.kind) { - case SyntaxKind.SetAccessor: - case SyntaxKind.GetAccessor: - case SyntaxKind.MethodDeclaration: - case SyntaxKind.ShorthandPropertyAssignment: + case ts.SyntaxKind.SetAccessor: + case ts.SyntaxKind.GetAccessor: + case ts.SyntaxKind.MethodDeclaration: + case ts.SyntaxKind.ShorthandPropertyAssignment: yield { errorNode: prop.name, innerExpression: undefined, nameType: type }; break; - case SyntaxKind.PropertyAssignment: - yield { errorNode: prop.name, innerExpression: prop.initializer, nameType: type, errorMessage: isComputedNonLiteralName(prop.name) ? Diagnostics.Type_of_computed_property_s_value_is_0_which_is_not_assignable_to_type_1 : undefined }; + case ts.SyntaxKind.PropertyAssignment: + yield { errorNode: prop.name, innerExpression: prop.initializer, nameType: type, errorMessage: ts.isComputedNonLiteralName(prop.name) ? ts.Diagnostics.Type_of_computed_property_s_value_is_0_which_is_not_assignable_to_type_1 : undefined }; break; default: - Debug.assertNever(prop); + ts.Debug.assertNever(prop); } } } - function elaborateObjectLiteral( - node: ObjectLiteralExpression, - source: Type, - target: Type, - relation: ESMap, - containingMessageChain: (() => DiagnosticMessageChain | undefined) | undefined, - errorOutputContainer: { errors?: Diagnostic[], skipLogging?: boolean } | undefined - ) { - if (target.flags & TypeFlags.Primitive) return false; + function elaborateObjectLiteral(node: ts.ObjectLiteralExpression, source: ts.Type, target: ts.Type, relation: ts.ESMap, containingMessageChain: (() => ts.DiagnosticMessageChain | undefined) | undefined, errorOutputContainer: { + errors?: ts.Diagnostic[]; + skipLogging?: boolean; + } | undefined) { + if (target.flags & ts.TypeFlags.Primitive) + return false; return elaborateElementwise(generateObjectLiteralElements(node), source, target, relation, containingMessageChain, errorOutputContainer); } @@ -17879,23 +17340,21 @@ namespace ts { * This is *not* a bi-directional relationship. * If one needs to check both directions for comparability, use a second call to this function or 'isTypeComparableTo'. */ - function checkTypeComparableTo(source: Type, target: Type, errorNode: Node, headMessage?: DiagnosticMessage, containingMessageChain?: () => DiagnosticMessageChain | undefined): boolean { + function checkTypeComparableTo(source: ts.Type, target: ts.Type, errorNode: ts.Node, headMessage?: ts.DiagnosticMessage, containingMessageChain?: () => ts.DiagnosticMessageChain | undefined): boolean { return checkTypeRelatedTo(source, target, comparableRelation, errorNode, headMessage, containingMessageChain); } - function isSignatureAssignableTo(source: Signature, - target: Signature, - ignoreReturnTypes: boolean): boolean { + function isSignatureAssignableTo(source: ts.Signature, target: ts.Signature, ignoreReturnTypes: boolean): boolean { return compareSignaturesRelated(source, target, ignoreReturnTypes ? SignatureCheckMode.IgnoreReturnTypes : 0, /*reportErrors*/ false, - /*errorReporter*/ undefined, /*errorReporter*/ undefined, compareTypesAssignable, /*reportUnreliableMarkers*/ undefined) !== Ternary.False; + /*errorReporter*/ undefined, /*errorReporter*/ undefined, compareTypesAssignable, /*reportUnreliableMarkers*/ undefined) !== ts.Ternary.False; } - type ErrorReporter = (message: DiagnosticMessage, arg0?: string, arg1?: string) => void; + type ErrorReporter = (message: ts.DiagnosticMessage, arg0?: string, arg1?: string) => void; /** * Returns true if `s` is `(...args: any[]) => any` or `(this: any, ...args: any[]) => any` */ - function isAnySignature(s: Signature) { + function isAnySignature(s: ts.Signature) { return !s.typeParameters && (!s.thisParameter || isTypeAny(getTypeOfParameter(s.thisParameter))) && s.parameters.length === 1 && signatureHasRestParameter(s) && (getTypeOfParameter(s.parameters[0]) === anyArrayType || isTypeAny(getTypeOfParameter(s.parameters[0]))) && isTypeAny(getReturnTypeOfSignature(s)); @@ -17904,28 +17363,21 @@ namespace ts { /** * See signatureRelatedTo, compareSignaturesIdentical */ - function compareSignaturesRelated(source: Signature, - target: Signature, - checkMode: SignatureCheckMode, - reportErrors: boolean, - errorReporter: ErrorReporter | undefined, - incompatibleErrorReporter: ((source: Type, target: Type) => void) | undefined, - compareTypes: TypeComparer, - reportUnreliableMarkers: TypeMapper | undefined): Ternary { + function compareSignaturesRelated(source: ts.Signature, target: ts.Signature, checkMode: SignatureCheckMode, reportErrors: boolean, errorReporter: ErrorReporter | undefined, incompatibleErrorReporter: ((source: ts.Type, target: ts.Type) => void) | undefined, compareTypes: ts.TypeComparer, reportUnreliableMarkers: ts.TypeMapper | undefined): ts.Ternary { // TODO (drosen): De-duplicate code between related functions. if (source === target) { - return Ternary.True; + return ts.Ternary.True; } if (isAnySignature(target)) { - return Ternary.True; + return ts.Ternary.True; } const targetCount = getParameterCount(target); const sourceHasMoreParameters = !hasEffectiveRestParameter(target) && (checkMode & SignatureCheckMode.StrictArity ? hasEffectiveRestParameter(source) || getParameterCount(source) > targetCount : getMinArgumentCount(source) > targetCount); if (sourceHasMoreParameters) { - return Ternary.False; + return ts.Ternary.False; } if (source.typeParameters && source.typeParameters !== target.typeParameters) { @@ -17940,10 +17392,10 @@ namespace ts { void instantiateType(sourceRestType || targetRestType, reportUnreliableMarkers); } - const kind = target.declaration ? target.declaration.kind : SyntaxKind.Unknown; - const strictVariance = !(checkMode & SignatureCheckMode.Callback) && strictFunctionTypes && kind !== SyntaxKind.MethodDeclaration && - kind !== SyntaxKind.MethodSignature && kind !== SyntaxKind.Constructor; - let result = Ternary.True; + const kind = target.declaration ? target.declaration.kind : ts.SyntaxKind.Unknown; + const strictVariance = !(checkMode & SignatureCheckMode.Callback) && strictFunctionTypes && kind !== ts.SyntaxKind.MethodDeclaration && + kind !== ts.SyntaxKind.MethodSignature && kind !== ts.SyntaxKind.Constructor; + let result = ts.Ternary.True; const sourceThisType = getThisTypeOfSignature(source); if (sourceThisType && sourceThisType !== voidType) { @@ -17954,9 +17406,9 @@ namespace ts { || compareTypes(targetThisType, sourceThisType, reportErrors); if (!related) { if (reportErrors) { - errorReporter!(Diagnostics.The_this_types_of_each_signature_are_incompatible); + errorReporter!(ts.Diagnostics.The_this_types_of_each_signature_are_incompatible); } - return Ternary.False; + return ts.Ternary.False; } result &= related; } @@ -17980,21 +17432,19 @@ namespace ts { const sourceSig = checkMode & SignatureCheckMode.Callback ? undefined : getSingleCallSignature(getNonNullableType(sourceType)); const targetSig = checkMode & SignatureCheckMode.Callback ? undefined : getSingleCallSignature(getNonNullableType(targetType)); const callbacks = sourceSig && targetSig && !getTypePredicateOfSignature(sourceSig) && !getTypePredicateOfSignature(targetSig) && - (getFalsyFlags(sourceType) & TypeFlags.Nullable) === (getFalsyFlags(targetType) & TypeFlags.Nullable); + (getFalsyFlags(sourceType) & ts.TypeFlags.Nullable) === (getFalsyFlags(targetType) & ts.TypeFlags.Nullable); let related = callbacks ? compareSignaturesRelated(targetSig, sourceSig, (checkMode & SignatureCheckMode.StrictArity) | (strictVariance ? SignatureCheckMode.StrictCallback : SignatureCheckMode.BivariantCallback), reportErrors, errorReporter, incompatibleErrorReporter, compareTypes, reportUnreliableMarkers) : !(checkMode & SignatureCheckMode.Callback) && !strictVariance && compareTypes(sourceType, targetType, /*reportErrors*/ false) || compareTypes(targetType, sourceType, reportErrors); // With strict arity, (x: number | undefined) => void is a subtype of (x?: number | undefined) => void if (related && checkMode & SignatureCheckMode.StrictArity && i >= getMinArgumentCount(source) && i < getMinArgumentCount(target) && compareTypes(sourceType, targetType, /*reportErrors*/ false)) { - related = Ternary.False; + related = ts.Ternary.False; } if (!related) { if (reportErrors) { - errorReporter!(Diagnostics.Types_of_parameters_0_and_1_are_incompatible, - unescapeLeadingUnderscores(getParameterNameAtPosition(source, i)), - unescapeLeadingUnderscores(getParameterNameAtPosition(target, i))); + errorReporter!(ts.Diagnostics.Types_of_parameters_0_and_1_are_incompatible, ts.unescapeLeadingUnderscores(getParameterNameAtPosition(source, i)), ts.unescapeLeadingUnderscores(getParameterNameAtPosition(target, i))); } - return Ternary.False; + return ts.Ternary.False; } result &= related; } @@ -18020,11 +17470,11 @@ namespace ts { if (sourceTypePredicate) { result &= compareTypePredicateRelatedTo(sourceTypePredicate, targetTypePredicate, reportErrors, errorReporter, compareTypes); } - else if (isIdentifierTypePredicate(targetTypePredicate)) { + else if (ts.isIdentifierTypePredicate(targetTypePredicate)) { if (reportErrors) { - errorReporter!(Diagnostics.Signature_0_must_be_a_type_predicate, signatureToString(source)); + errorReporter!(ts.Diagnostics.Signature_0_must_be_a_type_predicate, signatureToString(source)); } - return Ternary.False; + return ts.Ternary.False; } } else { @@ -18043,40 +17493,35 @@ namespace ts { return result; } - function compareTypePredicateRelatedTo( - source: TypePredicate, - target: TypePredicate, - reportErrors: boolean, - errorReporter: ErrorReporter | undefined, - compareTypes: (s: Type, t: Type, reportErrors?: boolean) => Ternary): Ternary { + function compareTypePredicateRelatedTo(source: ts.TypePredicate, target: ts.TypePredicate, reportErrors: boolean, errorReporter: ErrorReporter | undefined, compareTypes: (s: ts.Type, t: ts.Type, reportErrors?: boolean) => ts.Ternary): ts.Ternary { if (source.kind !== target.kind) { if (reportErrors) { - errorReporter!(Diagnostics.A_this_based_type_guard_is_not_compatible_with_a_parameter_based_type_guard); - errorReporter!(Diagnostics.Type_predicate_0_is_not_assignable_to_1, typePredicateToString(source), typePredicateToString(target)); + errorReporter!(ts.Diagnostics.A_this_based_type_guard_is_not_compatible_with_a_parameter_based_type_guard); + errorReporter!(ts.Diagnostics.Type_predicate_0_is_not_assignable_to_1, typePredicateToString(source), typePredicateToString(target)); } - return Ternary.False; + return ts.Ternary.False; } - if (source.kind === TypePredicateKind.Identifier || source.kind === TypePredicateKind.AssertsIdentifier) { - if (source.parameterIndex !== (target as IdentifierTypePredicate).parameterIndex) { + if (source.kind === ts.TypePredicateKind.Identifier || source.kind === ts.TypePredicateKind.AssertsIdentifier) { + if (source.parameterIndex !== (target as ts.IdentifierTypePredicate).parameterIndex) { if (reportErrors) { - errorReporter!(Diagnostics.Parameter_0_is_not_in_the_same_position_as_parameter_1, source.parameterName, (target as IdentifierTypePredicate).parameterName); - errorReporter!(Diagnostics.Type_predicate_0_is_not_assignable_to_1, typePredicateToString(source), typePredicateToString(target)); + errorReporter!(ts.Diagnostics.Parameter_0_is_not_in_the_same_position_as_parameter_1, source.parameterName, (target as ts.IdentifierTypePredicate).parameterName); + errorReporter!(ts.Diagnostics.Type_predicate_0_is_not_assignable_to_1, typePredicateToString(source), typePredicateToString(target)); } - return Ternary.False; + return ts.Ternary.False; } } - const related = source.type === target.type ? Ternary.True : + const related = source.type === target.type ? ts.Ternary.True : source.type && target.type ? compareTypes(source.type, target.type, reportErrors) : - Ternary.False; - if (related === Ternary.False && reportErrors) { - errorReporter!(Diagnostics.Type_predicate_0_is_not_assignable_to_1, typePredicateToString(source), typePredicateToString(target)); + ts.Ternary.False; + if (related === ts.Ternary.False && reportErrors) { + errorReporter!(ts.Diagnostics.Type_predicate_0_is_not_assignable_to_1, typePredicateToString(source), typePredicateToString(target)); } return related; } - function isImplementationCompatibleWithOverload(implementation: Signature, overload: Signature): boolean { + function isImplementationCompatibleWithOverload(implementation: ts.Signature, overload: ts.Signature): boolean { const erasedSource = getErasedSignature(implementation); const erasedTarget = getErasedSignature(overload); @@ -18093,7 +17538,7 @@ namespace ts { return false; } - function isEmptyResolvedType(t: ResolvedType) { + function isEmptyResolvedType(t: ts.ResolvedType) { return t !== anyFunctionType && t.properties.length === 0 && t.callSignatures.length === 0 && @@ -18101,145 +17546,162 @@ namespace ts { t.indexInfos.length === 0; } - function isEmptyObjectType(type: Type): boolean { - return type.flags & TypeFlags.Object ? !isGenericMappedType(type) && isEmptyResolvedType(resolveStructuredTypeMembers(type as ObjectType)) : - type.flags & TypeFlags.NonPrimitive ? true : - type.flags & TypeFlags.Union ? some((type as UnionType).types, isEmptyObjectType) : - type.flags & TypeFlags.Intersection ? every((type as UnionType).types, isEmptyObjectType) : + function isEmptyObjectType(type: ts.Type): boolean { + return type.flags & ts.TypeFlags.Object ? !isGenericMappedType(type) && isEmptyResolvedType(resolveStructuredTypeMembers(type as ts.ObjectType)) : + type.flags & ts.TypeFlags.NonPrimitive ? true : + type.flags & ts.TypeFlags.Union ? ts.some((type as ts.UnionType).types, isEmptyObjectType) : + type.flags & ts.TypeFlags.Intersection ? ts.every((type as ts.UnionType).types, isEmptyObjectType) : false; } - function isEmptyAnonymousObjectType(type: Type) { - return !!(getObjectFlags(type) & ObjectFlags.Anonymous && ( - (type as ResolvedType).members && isEmptyResolvedType(type as ResolvedType) || - type.symbol && type.symbol.flags & SymbolFlags.TypeLiteral && getMembersOfSymbol(type.symbol).size === 0)); + function isEmptyAnonymousObjectType(type: ts.Type) { + return !!(ts.getObjectFlags(type) & ts.ObjectFlags.Anonymous && ((type as ts.ResolvedType).members && isEmptyResolvedType(type as ts.ResolvedType) || + type.symbol && type.symbol.flags & ts.SymbolFlags.TypeLiteral && getMembersOfSymbol(type.symbol).size === 0)); } - function isStringIndexSignatureOnlyType(type: Type): boolean { - return type.flags & TypeFlags.Object && !isGenericMappedType(type) && getPropertiesOfType(type).length === 0 && getIndexInfosOfType(type).length === 1 && !!getIndexInfoOfType(type, stringType) || - type.flags & TypeFlags.UnionOrIntersection && every((type as UnionOrIntersectionType).types, isStringIndexSignatureOnlyType) || + function isStringIndexSignatureOnlyType(type: ts.Type): boolean { + return type.flags & ts.TypeFlags.Object && !isGenericMappedType(type) && getPropertiesOfType(type).length === 0 && getIndexInfosOfType(type).length === 1 && !!getIndexInfoOfType(type, stringType) || + type.flags & ts.TypeFlags.UnionOrIntersection && ts.every((type as ts.UnionOrIntersectionType).types, isStringIndexSignatureOnlyType) || false; } - function isEnumTypeRelatedTo(sourceSymbol: Symbol, targetSymbol: Symbol, errorReporter?: ErrorReporter) { + function isEnumTypeRelatedTo(sourceSymbol: ts.Symbol, targetSymbol: ts.Symbol, errorReporter?: ErrorReporter) { if (sourceSymbol === targetSymbol) { return true; } const id = getSymbolId(sourceSymbol) + "," + getSymbolId(targetSymbol); const entry = enumRelation.get(id); - if (entry !== undefined && !(!(entry & RelationComparisonResult.Reported) && entry & RelationComparisonResult.Failed && errorReporter)) { - return !!(entry & RelationComparisonResult.Succeeded); + if (entry !== undefined && !(!(entry & ts.RelationComparisonResult.Reported) && entry & ts.RelationComparisonResult.Failed && errorReporter)) { + return !!(entry & ts.RelationComparisonResult.Succeeded); } - if (sourceSymbol.escapedName !== targetSymbol.escapedName || !(sourceSymbol.flags & SymbolFlags.RegularEnum) || !(targetSymbol.flags & SymbolFlags.RegularEnum)) { - enumRelation.set(id, RelationComparisonResult.Failed | RelationComparisonResult.Reported); + if (sourceSymbol.escapedName !== targetSymbol.escapedName || !(sourceSymbol.flags & ts.SymbolFlags.RegularEnum) || !(targetSymbol.flags & ts.SymbolFlags.RegularEnum)) { + enumRelation.set(id, ts.RelationComparisonResult.Failed | ts.RelationComparisonResult.Reported); return false; } const targetEnumType = getTypeOfSymbol(targetSymbol); for (const property of getPropertiesOfType(getTypeOfSymbol(sourceSymbol))) { - if (property.flags & SymbolFlags.EnumMember) { + if (property.flags & ts.SymbolFlags.EnumMember) { const targetProperty = getPropertyOfType(targetEnumType, property.escapedName); - if (!targetProperty || !(targetProperty.flags & SymbolFlags.EnumMember)) { + if (!targetProperty || !(targetProperty.flags & ts.SymbolFlags.EnumMember)) { if (errorReporter) { - errorReporter(Diagnostics.Property_0_is_missing_in_type_1, symbolName(property), - typeToString(getDeclaredTypeOfSymbol(targetSymbol), /*enclosingDeclaration*/ undefined, TypeFormatFlags.UseFullyQualifiedType)); - enumRelation.set(id, RelationComparisonResult.Failed | RelationComparisonResult.Reported); + errorReporter(ts.Diagnostics.Property_0_is_missing_in_type_1, ts.symbolName(property), typeToString(getDeclaredTypeOfSymbol(targetSymbol), /*enclosingDeclaration*/ undefined, ts.TypeFormatFlags.UseFullyQualifiedType)); + enumRelation.set(id, ts.RelationComparisonResult.Failed | ts.RelationComparisonResult.Reported); } else { - enumRelation.set(id, RelationComparisonResult.Failed); + enumRelation.set(id, ts.RelationComparisonResult.Failed); } return false; } } } - enumRelation.set(id, RelationComparisonResult.Succeeded); + enumRelation.set(id, ts.RelationComparisonResult.Succeeded); return true; } - function isSimpleTypeRelatedTo(source: Type, target: Type, relation: ESMap, errorReporter?: ErrorReporter) { + function isSimpleTypeRelatedTo(source: ts.Type, target: ts.Type, relation: ts.ESMap, errorReporter?: ErrorReporter) { const s = source.flags; const t = target.flags; - if (t & TypeFlags.AnyOrUnknown || s & TypeFlags.Never || source === wildcardType) return true; - if (t & TypeFlags.Never) return false; - if (s & TypeFlags.StringLike && t & TypeFlags.String) return true; - if (s & TypeFlags.StringLiteral && s & TypeFlags.EnumLiteral && - t & TypeFlags.StringLiteral && !(t & TypeFlags.EnumLiteral) && - (source as StringLiteralType).value === (target as StringLiteralType).value) return true; - if (s & TypeFlags.NumberLike && t & TypeFlags.Number) return true; - if (s & TypeFlags.NumberLiteral && s & TypeFlags.EnumLiteral && - t & TypeFlags.NumberLiteral && !(t & TypeFlags.EnumLiteral) && - (source as NumberLiteralType).value === (target as NumberLiteralType).value) return true; - if (s & TypeFlags.BigIntLike && t & TypeFlags.BigInt) return true; - if (s & TypeFlags.BooleanLike && t & TypeFlags.Boolean) return true; - if (s & TypeFlags.ESSymbolLike && t & TypeFlags.ESSymbol) return true; - if (s & TypeFlags.Enum && t & TypeFlags.Enum && isEnumTypeRelatedTo(source.symbol, target.symbol, errorReporter)) return true; - if (s & TypeFlags.EnumLiteral && t & TypeFlags.EnumLiteral) { - if (s & TypeFlags.Union && t & TypeFlags.Union && isEnumTypeRelatedTo(source.symbol, target.symbol, errorReporter)) return true; - if (s & TypeFlags.Literal && t & TypeFlags.Literal && - (source as LiteralType).value === (target as LiteralType).value && - isEnumTypeRelatedTo(getParentOfSymbol(source.symbol)!, getParentOfSymbol(target.symbol)!, errorReporter)) return true; + if (t & ts.TypeFlags.AnyOrUnknown || s & ts.TypeFlags.Never || source === wildcardType) + return true; + if (t & ts.TypeFlags.Never) + return false; + if (s & ts.TypeFlags.StringLike && t & ts.TypeFlags.String) + return true; + if (s & ts.TypeFlags.StringLiteral && s & ts.TypeFlags.EnumLiteral && + t & ts.TypeFlags.StringLiteral && !(t & ts.TypeFlags.EnumLiteral) && + (source as ts.StringLiteralType).value === (target as ts.StringLiteralType).value) + return true; + if (s & ts.TypeFlags.NumberLike && t & ts.TypeFlags.Number) + return true; + if (s & ts.TypeFlags.NumberLiteral && s & ts.TypeFlags.EnumLiteral && + t & ts.TypeFlags.NumberLiteral && !(t & ts.TypeFlags.EnumLiteral) && + (source as ts.NumberLiteralType).value === (target as ts.NumberLiteralType).value) + return true; + if (s & ts.TypeFlags.BigIntLike && t & ts.TypeFlags.BigInt) + return true; + if (s & ts.TypeFlags.BooleanLike && t & ts.TypeFlags.Boolean) + return true; + if (s & ts.TypeFlags.ESSymbolLike && t & ts.TypeFlags.ESSymbol) + return true; + if (s & ts.TypeFlags.Enum && t & ts.TypeFlags.Enum && isEnumTypeRelatedTo(source.symbol, target.symbol, errorReporter)) + return true; + if (s & ts.TypeFlags.EnumLiteral && t & ts.TypeFlags.EnumLiteral) { + if (s & ts.TypeFlags.Union && t & ts.TypeFlags.Union && isEnumTypeRelatedTo(source.symbol, target.symbol, errorReporter)) + return true; + if (s & ts.TypeFlags.Literal && t & ts.TypeFlags.Literal && + (source as ts.LiteralType).value === (target as ts.LiteralType).value && + isEnumTypeRelatedTo(getParentOfSymbol(source.symbol)!, getParentOfSymbol(target.symbol)!, errorReporter)) + return true; } // In non-strictNullChecks mode, `undefined` and `null` are assignable to anything except `never`. // Since unions and intersections may reduce to `never`, we exclude them here. - if (s & TypeFlags.Undefined && (!strictNullChecks && !(t & TypeFlags.UnionOrIntersection) || t & (TypeFlags.Undefined | TypeFlags.Void))) return true; - if (s & TypeFlags.Null && (!strictNullChecks && !(t & TypeFlags.UnionOrIntersection) || t & TypeFlags.Null)) return true; - if (s & TypeFlags.Object && t & TypeFlags.NonPrimitive) return true; + if (s & ts.TypeFlags.Undefined && (!strictNullChecks && !(t & ts.TypeFlags.UnionOrIntersection) || t & (ts.TypeFlags.Undefined | ts.TypeFlags.Void))) + return true; + if (s & ts.TypeFlags.Null && (!strictNullChecks && !(t & ts.TypeFlags.UnionOrIntersection) || t & ts.TypeFlags.Null)) + return true; + if (s & ts.TypeFlags.Object && t & ts.TypeFlags.NonPrimitive) + return true; if (relation === assignableRelation || relation === comparableRelation) { - if (s & TypeFlags.Any) return true; + if (s & ts.TypeFlags.Any) + return true; // Type number or any numeric literal type is assignable to any numeric enum type or any // numeric enum literal type. This rule exists for backwards compatibility reasons because // bit-flag enum types sometimes look like literal enum types with numeric literal values. - if (s & (TypeFlags.Number | TypeFlags.NumberLiteral) && !(s & TypeFlags.EnumLiteral) && ( - t & TypeFlags.Enum || relation === assignableRelation && t & TypeFlags.NumberLiteral && t & TypeFlags.EnumLiteral)) return true; + if (s & (ts.TypeFlags.Number | ts.TypeFlags.NumberLiteral) && !(s & ts.TypeFlags.EnumLiteral) && (t & ts.TypeFlags.Enum || relation === assignableRelation && t & ts.TypeFlags.NumberLiteral && t & ts.TypeFlags.EnumLiteral)) + return true; } return false; } - function isTypeRelatedTo(source: Type, target: Type, relation: ESMap) { + function isTypeRelatedTo(source: ts.Type, target: ts.Type, relation: ts.ESMap) { if (isFreshLiteralType(source)) { - source = (source as FreshableType).regularType; + source = (source as ts.FreshableType).regularType; } if (isFreshLiteralType(target)) { - target = (target as FreshableType).regularType; + target = (target as ts.FreshableType).regularType; } if (source === target) { return true; } if (relation !== identityRelation) { - if (relation === comparableRelation && !(target.flags & TypeFlags.Never) && isSimpleTypeRelatedTo(target, source, relation) || isSimpleTypeRelatedTo(source, target, relation)) { + if (relation === comparableRelation && !(target.flags & ts.TypeFlags.Never) && isSimpleTypeRelatedTo(target, source, relation) || isSimpleTypeRelatedTo(source, target, relation)) { return true; } } - else if (!((source.flags | target.flags) & (TypeFlags.UnionOrIntersection | TypeFlags.IndexedAccess | TypeFlags.Conditional | TypeFlags.Substitution))) { + else if (!((source.flags | target.flags) & (ts.TypeFlags.UnionOrIntersection | ts.TypeFlags.IndexedAccess | ts.TypeFlags.Conditional | ts.TypeFlags.Substitution))) { // We have excluded types that may simplify to other forms, so types must have identical flags - if (source.flags !== target.flags) return false; - if (source.flags & TypeFlags.Singleton) return true; + if (source.flags !== target.flags) + return false; + if (source.flags & ts.TypeFlags.Singleton) + return true; } - if (source.flags & TypeFlags.Object && target.flags & TypeFlags.Object) { + if (source.flags & ts.TypeFlags.Object && target.flags & ts.TypeFlags.Object) { const related = relation.get(getRelationKey(source, target, IntersectionState.None, relation, /*ignoreConstraints*/ false)); if (related !== undefined) { - return !!(related & RelationComparisonResult.Succeeded); + return !!(related & ts.RelationComparisonResult.Succeeded); } } - if (source.flags & TypeFlags.StructuredOrInstantiable || target.flags & TypeFlags.StructuredOrInstantiable) { + if (source.flags & ts.TypeFlags.StructuredOrInstantiable || target.flags & ts.TypeFlags.StructuredOrInstantiable) { return checkTypeRelatedTo(source, target, relation, /*errorNode*/ undefined); } return false; } - function isIgnoredJsxProperty(source: Type, sourceProp: Symbol) { - return getObjectFlags(source) & ObjectFlags.JsxAttributes && isHyphenatedJsxName(sourceProp.escapedName); + function isIgnoredJsxProperty(source: ts.Type, sourceProp: ts.Symbol) { + return ts.getObjectFlags(source) & ts.ObjectFlags.JsxAttributes && isHyphenatedJsxName(sourceProp.escapedName); } - function getNormalizedType(type: Type, writing: boolean): Type { + function getNormalizedType(type: ts.Type, writing: boolean): ts.Type { while (true) { - let t = isFreshLiteralType(type) ? (type as FreshableType).regularType : - getObjectFlags(type) & ObjectFlags.Reference && (type as TypeReference).node ? createTypeReference((type as TypeReference).target, getTypeArguments(type as TypeReference)) : - type.flags & TypeFlags.UnionOrIntersection ? getReducedType(type) : - type.flags & TypeFlags.Substitution ? writing ? (type as SubstitutionType).baseType : (type as SubstitutionType).substitute : - type.flags & TypeFlags.Simplifiable ? getSimplifiedType(type, writing) : + let t = isFreshLiteralType(type) ? (type as ts.FreshableType).regularType : + ts.getObjectFlags(type) & ts.ObjectFlags.Reference && (type as ts.TypeReference).node ? createTypeReference((type as ts.TypeReference).target, getTypeArguments(type as ts.TypeReference)) : + type.flags & ts.TypeFlags.UnionOrIntersection ? getReducedType(type) : + type.flags & ts.TypeFlags.Substitution ? writing ? (type as ts.SubstitutionType).baseType : (type as ts.SubstitutionType).substitute : + type.flags & ts.TypeFlags.Simplifiable ? getSimplifiedType(type, writing) : type; t = getSingleBaseForNonAugmentingSubtype(t) || t; - if (t === type) break; + if (t === type) + break; type = t; } return type; @@ -18256,40 +17718,46 @@ namespace ts { * @param containingMessageChain A chain of errors to prepend any new errors found. * @param errorOutputContainer Return the diagnostic. Do not log if 'skipLogging' is truthy. */ - function checkTypeRelatedTo( - source: Type, - target: Type, - relation: ESMap, - errorNode: Node | undefined, - headMessage?: DiagnosticMessage, - containingMessageChain?: () => DiagnosticMessageChain | undefined, - errorOutputContainer?: { errors?: Diagnostic[], skipLogging?: boolean }, - ): boolean { - - let errorInfo: DiagnosticMessageChain | undefined; - let relatedInfo: [DiagnosticRelatedInformation, ...DiagnosticRelatedInformation[]] | undefined; + function checkTypeRelatedTo(source: ts.Type, target: ts.Type, relation: ts.ESMap, errorNode: ts.Node | undefined, headMessage?: ts.DiagnosticMessage, containingMessageChain?: () => ts.DiagnosticMessageChain | undefined, errorOutputContainer?: { + errors?: ts.Diagnostic[]; + skipLogging?: boolean; + }): boolean { + let errorInfo: ts.DiagnosticMessageChain | undefined; + let relatedInfo: [ + ts.DiagnosticRelatedInformation, + ...ts.DiagnosticRelatedInformation[] + ] | undefined; let maybeKeys: string[]; - let sourceStack: Type[]; - let targetStack: Type[]; + let sourceStack: ts.Type[]; + let targetStack: ts.Type[]; let maybeCount = 0; let sourceDepth = 0; let targetDepth = 0; let expandingFlags = ExpandingFlags.None; let overflow = false; let overrideNextErrorInfo = 0; // How many `reportRelationError` calls should be skipped in the elaboration pyramid - let lastSkippedInfo: [Type, Type] | undefined; - let incompatibleStack: [DiagnosticMessage, (string | number)?, (string | number)?, (string | number)?, (string | number)?][] | undefined; + let lastSkippedInfo: [ + ts.Type, + ts.Type + ] | undefined; + let incompatibleStack: [ + ts.DiagnosticMessage, + (string | number)?, + (string | number)?, + (string | number)?, + (string | number)? + ][] | undefined; let inPropertyCheck = false; - Debug.assert(relation !== identityRelation || !errorNode, "no error reporting in identity checking"); + ts.Debug.assert(relation !== identityRelation || !errorNode, "no error reporting in identity checking"); const result = isRelatedTo(source, target, RecursionFlags.Both, /*reportErrors*/ !!errorNode, headMessage); if (incompatibleStack) { reportIncompatibleStack(); } if (overflow) { - tracing?.instant(tracing.Phase.CheckTypes, "checkTypeRelatedTo_DepthLimit", { sourceId: source.id, targetId: target.id, depth: sourceDepth, targetDepth }); - const diag = error(errorNode || currentNode, Diagnostics.Excessive_stack_depth_comparing_types_0_and_1, typeToString(source), typeToString(target)); + ts.tracing?.instant(ts.tracing.Phase.CheckTypes, "checkTypeRelatedTo_DepthLimit", { sourceId: source.id, targetId: target.id, depth: sourceDepth, targetDepth }); + const diag = error(errorNode || currentNode, ts.Diagnostics.Excessive_stack_depth_comparing_types_0_and_1, typeToString(source), typeToString(target)); if (errorOutputContainer) { (errorOutputContainer.errors || (errorOutputContainer.errors = [])).push(diag); } @@ -18298,27 +17766,27 @@ namespace ts { if (containingMessageChain) { const chain = containingMessageChain(); if (chain) { - concatenateDiagnosticMessageChains(chain, errorInfo); + ts.concatenateDiagnosticMessageChains(chain, errorInfo); errorInfo = chain; } } - let relatedInformation: DiagnosticRelatedInformation[] | undefined; + let relatedInformation: ts.DiagnosticRelatedInformation[] | undefined; // Check if we should issue an extra diagnostic to produce a quickfix for a slightly incorrect import statement if (headMessage && errorNode && !result && source.symbol) { const links = getSymbolLinks(source.symbol); - if (links.originatingImport && !isImportCall(links.originatingImport)) { + if (links.originatingImport && !ts.isImportCall(links.originatingImport)) { const helpfulRetry = checkTypeRelatedTo(getTypeOfSymbol(links.target!), target, relation, /*errorNode*/ undefined); if (helpfulRetry) { // Likely an incorrect import. Issue a helpful diagnostic to produce a quickfix to change the import - const diag = createDiagnosticForNode(links.originatingImport, Diagnostics.Type_originates_at_this_import_A_namespace_style_import_cannot_be_called_or_constructed_and_will_cause_a_failure_at_runtime_Consider_using_a_default_import_or_import_require_here_instead); - relatedInformation = append(relatedInformation, diag); // Cause the error to appear with the error that triggered it + const diag = ts.createDiagnosticForNode(links.originatingImport, ts.Diagnostics.Type_originates_at_this_import_A_namespace_style_import_cannot_be_called_or_constructed_and_will_cause_a_failure_at_runtime_Consider_using_a_default_import_or_import_require_here_instead); + relatedInformation = ts.append(relatedInformation, diag); // Cause the error to appear with the error that triggered it } } } - const diag = createDiagnosticForNodeFromMessageChain(errorNode!, errorInfo, relatedInformation); + const diag = ts.createDiagnosticForNodeFromMessageChain(errorNode!, errorInfo, relatedInformation); if (relatedInfo) { - addRelatedInfo(diag, ...relatedInfo); + ts.addRelatedInfo(diag, ...relatedInfo); } if (errorOutputContainer) { (errorOutputContainer.errors || (errorOutputContainer.errors = [])).push(diag); @@ -18327,12 +17795,12 @@ namespace ts { diagnostics.add(diag); } } - if (errorNode && errorOutputContainer && errorOutputContainer.skipLogging && result === Ternary.False) { - Debug.assert(!!errorOutputContainer.errors, "missed opportunity to interact with error."); + if (errorNode && errorOutputContainer && errorOutputContainer.skipLogging && result === ts.Ternary.False) { + ts.Debug.assert(!!errorOutputContainer.errors, "missed opportunity to interact with error."); } - return result !== Ternary.False; + return result !== ts.Ternary.False; function resetErrorInfo(saved: ReturnType) { errorInfo = saved.errorInfo; @@ -18348,11 +17816,14 @@ namespace ts { lastSkippedInfo, incompatibleStack: incompatibleStack?.slice(), overrideNextErrorInfo, - relatedInfo: relatedInfo?.slice() as [DiagnosticRelatedInformation, ...DiagnosticRelatedInformation[]] | undefined, + relatedInfo: relatedInfo?.slice() as [ + ts.DiagnosticRelatedInformation, + ...ts.DiagnosticRelatedInformation[] + ] | undefined, }; } - function reportIncompatibleError(message: DiagnosticMessage, arg0?: string | number, arg1?: string | number, arg2?: string | number, arg3?: string | number) { + function reportIncompatibleError(message: ts.DiagnosticMessage, arg0?: string | number, arg1?: string | number, arg2?: string | number, arg3?: string | number) { overrideNextErrorInfo++; // Suppress the next relation error lastSkippedInfo = undefined; // Reset skipped info cache (incompatibleStack ||= []).push([message, arg0, arg1, arg2, arg3]); @@ -18374,11 +17845,17 @@ namespace ts { // The first error will be the innermost, while the last will be the outermost - so by popping off the end, // we can build from left to right let path = ""; - const secondaryRootErrors: [DiagnosticMessage, (string | number)?, (string | number)?, (string | number)?, (string | number)?][] = []; + const secondaryRootErrors: [ + ts.DiagnosticMessage, + (string | number)?, + (string | number)?, + (string | number)?, + (string | number)? + ][] = []; while (stack.length) { const [msg, ...args] = stack.pop()!; switch (msg.code) { - case Diagnostics.Types_of_property_0_are_incompatible.code: { + case ts.Diagnostics.Types_of_property_0_are_incompatible.code: { // Parenthesize a `new` if there is one if (path.indexOf("new ") === 0) { path = `(${path})`; @@ -18389,7 +17866,7 @@ namespace ts { path = `${str}`; } // Otherwise write a dotted name if possible - else if (isIdentifierText(str, getEmitScriptTarget(compilerOptions))) { + else if (ts.isIdentifierText(str, ts.getEmitScriptTarget(compilerOptions))) { path = `${path}.${str}`; } // Failing that, check if the name is already a computed name @@ -18402,53 +17879,51 @@ namespace ts { } break; } - case Diagnostics.Call_signature_return_types_0_and_1_are_incompatible.code: - case Diagnostics.Construct_signature_return_types_0_and_1_are_incompatible.code: - case Diagnostics.Call_signatures_with_no_arguments_have_incompatible_return_types_0_and_1.code: - case Diagnostics.Construct_signatures_with_no_arguments_have_incompatible_return_types_0_and_1.code: { + case ts.Diagnostics.Call_signature_return_types_0_and_1_are_incompatible.code: + case ts.Diagnostics.Construct_signature_return_types_0_and_1_are_incompatible.code: + case ts.Diagnostics.Call_signatures_with_no_arguments_have_incompatible_return_types_0_and_1.code: + case ts.Diagnostics.Construct_signatures_with_no_arguments_have_incompatible_return_types_0_and_1.code: { if (path.length === 0) { // Don't flatten signature compatability errors at the start of a chain - instead prefer // to unify (the with no arguments bit is excessive for printback) and print them back let mappedMsg = msg; - if (msg.code === Diagnostics.Call_signatures_with_no_arguments_have_incompatible_return_types_0_and_1.code) { - mappedMsg = Diagnostics.Call_signature_return_types_0_and_1_are_incompatible; + if (msg.code === ts.Diagnostics.Call_signatures_with_no_arguments_have_incompatible_return_types_0_and_1.code) { + mappedMsg = ts.Diagnostics.Call_signature_return_types_0_and_1_are_incompatible; } - else if (msg.code === Diagnostics.Construct_signatures_with_no_arguments_have_incompatible_return_types_0_and_1.code) { - mappedMsg = Diagnostics.Construct_signature_return_types_0_and_1_are_incompatible; + else if (msg.code === ts.Diagnostics.Construct_signatures_with_no_arguments_have_incompatible_return_types_0_and_1.code) { + mappedMsg = ts.Diagnostics.Construct_signature_return_types_0_and_1_are_incompatible; } secondaryRootErrors.unshift([mappedMsg, args[0], args[1]]); } else { - const prefix = (msg.code === Diagnostics.Construct_signature_return_types_0_and_1_are_incompatible.code || - msg.code === Diagnostics.Construct_signatures_with_no_arguments_have_incompatible_return_types_0_and_1.code) + const prefix = (msg.code === ts.Diagnostics.Construct_signature_return_types_0_and_1_are_incompatible.code || + msg.code === ts.Diagnostics.Construct_signatures_with_no_arguments_have_incompatible_return_types_0_and_1.code) ? "new " : ""; - const params = (msg.code === Diagnostics.Call_signatures_with_no_arguments_have_incompatible_return_types_0_and_1.code || - msg.code === Diagnostics.Construct_signatures_with_no_arguments_have_incompatible_return_types_0_and_1.code) + const params = (msg.code === ts.Diagnostics.Call_signatures_with_no_arguments_have_incompatible_return_types_0_and_1.code || + msg.code === ts.Diagnostics.Construct_signatures_with_no_arguments_have_incompatible_return_types_0_and_1.code) ? "" : "..."; path = `${prefix}${path}(${params})`; } break; } - case Diagnostics.Type_at_position_0_in_source_is_not_compatible_with_type_at_position_1_in_target.code: { - secondaryRootErrors.unshift([Diagnostics.Type_at_position_0_in_source_is_not_compatible_with_type_at_position_1_in_target, args[0], args[1]]); + case ts.Diagnostics.Type_at_position_0_in_source_is_not_compatible_with_type_at_position_1_in_target.code: { + secondaryRootErrors.unshift([ts.Diagnostics.Type_at_position_0_in_source_is_not_compatible_with_type_at_position_1_in_target, args[0], args[1]]); break; } - case Diagnostics.Type_at_positions_0_through_1_in_source_is_not_compatible_with_type_at_position_2_in_target.code: { - secondaryRootErrors.unshift([Diagnostics.Type_at_positions_0_through_1_in_source_is_not_compatible_with_type_at_position_2_in_target, args[0], args[1], args[2]]); + case ts.Diagnostics.Type_at_positions_0_through_1_in_source_is_not_compatible_with_type_at_position_2_in_target.code: { + secondaryRootErrors.unshift([ts.Diagnostics.Type_at_positions_0_through_1_in_source_is_not_compatible_with_type_at_position_2_in_target, args[0], args[1], args[2]]); break; } default: - return Debug.fail(`Unhandled Diagnostic: ${msg.code}`); + return ts.Debug.fail(`Unhandled Diagnostic: ${msg.code}`); } } if (path) { reportError(path[path.length - 1] === ")" - ? Diagnostics.The_types_returned_by_0_are_incompatible_between_these_types - : Diagnostics.The_types_of_0_are_incompatible_between_these_types, - path - ); + ? ts.Diagnostics.The_types_returned_by_0_are_incompatible_between_these_types + : ts.Diagnostics.The_types_of_0_are_incompatible_between_these_types, path); } else { // Remove the innermost secondary error as it will duplicate the error already reported by `reportRelationError` on entry @@ -18466,15 +17941,17 @@ namespace ts { } } - function reportError(message: DiagnosticMessage, arg0?: string | number, arg1?: string | number, arg2?: string | number, arg3?: string | number): void { - Debug.assert(!!errorNode); - if (incompatibleStack) reportIncompatibleStack(); - if (message.elidedInCompatabilityPyramid) return; - errorInfo = chainDiagnosticMessages(errorInfo, message, arg0, arg1, arg2, arg3); + function reportError(message: ts.DiagnosticMessage, arg0?: string | number, arg1?: string | number, arg2?: string | number, arg3?: string | number): void { + ts.Debug.assert(!!errorNode); + if (incompatibleStack) + reportIncompatibleStack(); + if (message.elidedInCompatabilityPyramid) + return; + errorInfo = ts.chainDiagnosticMessages(errorInfo, message, arg0, arg1, arg2, arg3); } - function associateRelatedInfo(info: DiagnosticRelatedInformation) { - Debug.assert(!!errorInfo); + function associateRelatedInfo(info: ts.DiagnosticRelatedInformation) { + ts.Debug.assert(!!errorInfo); if (!relatedInfo) { relatedInfo = [info]; } @@ -18483,70 +17960,62 @@ namespace ts { } } - function reportRelationError(message: DiagnosticMessage | undefined, source: Type, target: Type) { - if (incompatibleStack) reportIncompatibleStack(); + function reportRelationError(message: ts.DiagnosticMessage | undefined, source: ts.Type, target: ts.Type) { + if (incompatibleStack) + reportIncompatibleStack(); const [sourceType, targetType] = getTypeNamesForErrorDisplay(source, target); let generalizedSource = source; let generalizedSourceType = sourceType; if (isLiteralType(source) && !typeCouldHaveTopLevelSingletonTypes(target)) { generalizedSource = getBaseTypeOfLiteralType(source); - Debug.assert(!isTypeAssignableTo(generalizedSource, target), "generalized source shouldn't be assignable"); + ts.Debug.assert(!isTypeAssignableTo(generalizedSource, target), "generalized source shouldn't be assignable"); generalizedSourceType = getTypeNameForErrorDisplay(generalizedSource); } - if (target.flags & TypeFlags.TypeParameter && target !== markerSuperType && target !== markerSubType) { + if (target.flags & ts.TypeFlags.TypeParameter && target !== markerSuperType && target !== markerSubType) { const constraint = getBaseConstraintOfType(target); let needsOriginalSource; if (constraint && (isTypeAssignableTo(generalizedSource, constraint) || (needsOriginalSource = isTypeAssignableTo(source, constraint)))) { - reportError( - Diagnostics._0_is_assignable_to_the_constraint_of_type_1_but_1_could_be_instantiated_with_a_different_subtype_of_constraint_2, - needsOriginalSource ? sourceType : generalizedSourceType, - targetType, - typeToString(constraint), - ); + reportError(ts.Diagnostics._0_is_assignable_to_the_constraint_of_type_1_but_1_could_be_instantiated_with_a_different_subtype_of_constraint_2, needsOriginalSource ? sourceType : generalizedSourceType, targetType, typeToString(constraint)); } else { errorInfo = undefined; - reportError( - Diagnostics._0_could_be_instantiated_with_an_arbitrary_type_which_could_be_unrelated_to_1, - targetType, - generalizedSourceType - ); + reportError(ts.Diagnostics._0_could_be_instantiated_with_an_arbitrary_type_which_could_be_unrelated_to_1, targetType, generalizedSourceType); } } if (!message) { if (relation === comparableRelation) { - message = Diagnostics.Type_0_is_not_comparable_to_type_1; + message = ts.Diagnostics.Type_0_is_not_comparable_to_type_1; } else if (sourceType === targetType) { - message = Diagnostics.Type_0_is_not_assignable_to_type_1_Two_different_types_with_this_name_exist_but_they_are_unrelated; + message = ts.Diagnostics.Type_0_is_not_assignable_to_type_1_Two_different_types_with_this_name_exist_but_they_are_unrelated; } else if (exactOptionalPropertyTypes && getExactOptionalUnassignableProperties(source, target).length) { - message = Diagnostics.Type_0_is_not_assignable_to_type_1_with_exactOptionalPropertyTypes_Colon_true_Consider_adding_undefined_to_the_types_of_the_target_s_properties; + message = ts.Diagnostics.Type_0_is_not_assignable_to_type_1_with_exactOptionalPropertyTypes_Colon_true_Consider_adding_undefined_to_the_types_of_the_target_s_properties; } else { - if (source.flags & TypeFlags.StringLiteral && target.flags & TypeFlags.Union) { - const suggestedType = getSuggestedTypeForNonexistentStringLiteralType(source as StringLiteralType, target as UnionType); + if (source.flags & ts.TypeFlags.StringLiteral && target.flags & ts.TypeFlags.Union) { + const suggestedType = getSuggestedTypeForNonexistentStringLiteralType(source as ts.StringLiteralType, target as ts.UnionType); if (suggestedType) { - reportError(Diagnostics.Type_0_is_not_assignable_to_type_1_Did_you_mean_2, generalizedSourceType, targetType, typeToString(suggestedType)); + reportError(ts.Diagnostics.Type_0_is_not_assignable_to_type_1_Did_you_mean_2, generalizedSourceType, targetType, typeToString(suggestedType)); return; } } - message = Diagnostics.Type_0_is_not_assignable_to_type_1; + message = ts.Diagnostics.Type_0_is_not_assignable_to_type_1; } } - else if (message === Diagnostics.Argument_of_type_0_is_not_assignable_to_parameter_of_type_1 + else if (message === ts.Diagnostics.Argument_of_type_0_is_not_assignable_to_parameter_of_type_1 && exactOptionalPropertyTypes && getExactOptionalUnassignableProperties(source, target).length) { - message = Diagnostics.Argument_of_type_0_is_not_assignable_to_parameter_of_type_1_with_exactOptionalPropertyTypes_Colon_true_Consider_adding_undefined_to_the_types_of_the_target_s_properties; + message = ts.Diagnostics.Argument_of_type_0_is_not_assignable_to_parameter_of_type_1_with_exactOptionalPropertyTypes_Colon_true_Consider_adding_undefined_to_the_types_of_the_target_s_properties; } reportError(message, generalizedSourceType, targetType); } - function tryElaborateErrorsForPrimitivesAndObjects(source: Type, target: Type) { + function tryElaborateErrorsForPrimitivesAndObjects(source: ts.Type, target: ts.Type) { const sourceType = symbolValueDeclarationIsContextSensitive(source.symbol) ? typeToString(source, source.symbol.valueDeclaration) : typeToString(source); const targetType = symbolValueDeclarationIsContextSensitive(target.symbol) ? typeToString(target, target.symbol.valueDeclaration) : typeToString(target); @@ -18554,7 +18023,7 @@ namespace ts { (globalNumberType === source && numberType === target) || (globalBooleanType === source && booleanType === target) || (getGlobalESSymbolType(/*reportErrors*/ false) === source && esSymbolType === target)) { - reportError(Diagnostics._0_is_a_primitive_but_1_is_a_wrapper_object_Prefer_using_0_when_possible, targetType, sourceType); + reportError(ts.Diagnostics._0_is_a_primitive_but_1_is_a_wrapper_object_Prefer_using_0_when_possible, targetType, sourceType); } } @@ -18564,7 +18033,7 @@ namespace ts { * any other elaborations when relating the `source` and * `target` types. */ - function tryElaborateArrayLikeErrors(source: Type, target: Type, reportErrors: boolean): boolean { + function tryElaborateArrayLikeErrors(source: ts.Type, target: ts.Type, reportErrors: boolean): boolean { /** * The spec for elaboration is: * - If the source is a readonly tuple and the target is a mutable array or tuple, elaborate on mutability and skip property elaborations. @@ -18575,7 +18044,7 @@ namespace ts { if (isTupleType(source)) { if (source.target.readonly && isMutableArrayOrTuple(target)) { if (reportErrors) { - reportError(Diagnostics.The_type_0_is_readonly_and_cannot_be_assigned_to_the_mutable_type_1, typeToString(source), typeToString(target)); + reportError(ts.Diagnostics.The_type_0_is_readonly_and_cannot_be_assigned_to_the_mutable_type_1, typeToString(source), typeToString(target)); } return false; } @@ -18583,7 +18052,7 @@ namespace ts { } if (isReadonlyArrayType(source) && isMutableArrayOrTuple(target)) { if (reportErrors) { - reportError(Diagnostics.The_type_0_is_readonly_and_cannot_be_assigned_to_the_mutable_type_1, typeToString(source), typeToString(target)); + reportError(ts.Diagnostics.The_type_0_is_readonly_and_cannot_be_assigned_to_the_mutable_type_1, typeToString(source), typeToString(target)); } return false; } @@ -18593,7 +18062,7 @@ namespace ts { return true; } - function isRelatedToWorker(source: Type, target: Type, reportErrors: boolean) { + function isRelatedToWorker(source: ts.Type, target: ts.Type, reportErrors: boolean) { return isRelatedTo(source, target, RecursionFlags.Both, reportErrors); } @@ -18603,17 +18072,17 @@ namespace ts { * * Ternary.Maybe if they are related with assumptions of other relationships, or * * Ternary.False if they are not related. */ - function isRelatedTo(originalSource: Type, originalTarget: Type, recursionFlags: RecursionFlags = RecursionFlags.Both, reportErrors = false, headMessage?: DiagnosticMessage, intersectionState = IntersectionState.None): Ternary { + function isRelatedTo(originalSource: ts.Type, originalTarget: ts.Type, recursionFlags: RecursionFlags = RecursionFlags.Both, reportErrors = false, headMessage?: ts.DiagnosticMessage, intersectionState = IntersectionState.None): ts.Ternary { // Before normalization: if `source` is type an object type, and `target` is primitive, // skip all the checks we don't need and just return `isSimpleTypeRelatedTo` result - if (originalSource.flags & TypeFlags.Object && originalTarget.flags & TypeFlags.Primitive) { + if (originalSource.flags & ts.TypeFlags.Object && originalTarget.flags & ts.TypeFlags.Primitive) { if (isSimpleTypeRelatedTo(originalSource, originalTarget, relation, reportErrors ? reportError : undefined)) { - return Ternary.True; + return ts.Ternary.True; } if (reportErrors) { reportErrorResults(originalSource, originalTarget, originalSource, originalTarget, headMessage); } - return Ternary.False; + return ts.Ternary.False; } // Normalize the source and target types: Turn fresh literal types into regular literal types, @@ -18623,11 +18092,14 @@ namespace ts { const source = getNormalizedType(originalSource, /*writing*/ false); let target = getNormalizedType(originalTarget, /*writing*/ true); - if (source === target) return Ternary.True; + if (source === target) + return ts.Ternary.True; if (relation === identityRelation) { - if (source.flags !== target.flags) return Ternary.False; - if (source.flags & TypeFlags.Singleton) return Ternary.True; + if (source.flags !== target.flags) + return ts.Ternary.False; + if (source.flags & ts.TypeFlags.Singleton) + return ts.Ternary.True; traceUnionsOrIntersectionsTooLarge(source, target); return recursiveTypeRelatedTo(source, target, /*reportErrors*/ false, IntersectionState.None, recursionFlags); } @@ -18637,63 +18109,64 @@ namespace ts { // as we break down the _target_ union first, _then_ get the source constraint - so for every // member of the target, we attempt to find a match in the source. This avoids that in cases where // the target is exactly the constraint. - if (source.flags & TypeFlags.TypeParameter && getConstraintOfType(source) === target) { - return Ternary.True; + if (source.flags & ts.TypeFlags.TypeParameter && getConstraintOfType(source) === target) { + return ts.Ternary.True; } // See if we're relating a definitely non-nullable type to a union that includes null and/or undefined // plus a single non-nullable type. If so, remove null and/or undefined from the target type. - if (source.flags & TypeFlags.DefinitelyNonNullable && target.flags & TypeFlags.Union) { - const types = (target as UnionType).types; - const candidate = types.length === 2 && types[0].flags & TypeFlags.Nullable ? types[1] : - types.length === 3 && types[0].flags & TypeFlags.Nullable && types[1].flags & TypeFlags.Nullable ? types[2] : + if (source.flags & ts.TypeFlags.DefinitelyNonNullable && target.flags & ts.TypeFlags.Union) { + const types = (target as ts.UnionType).types; + const candidate = types.length === 2 && types[0].flags & ts.TypeFlags.Nullable ? types[1] : + types.length === 3 && types[0].flags & ts.TypeFlags.Nullable && types[1].flags & ts.TypeFlags.Nullable ? types[2] : undefined; - if (candidate && !(candidate.flags & TypeFlags.Nullable)) { + if (candidate && !(candidate.flags & ts.TypeFlags.Nullable)) { target = getNormalizedType(candidate, /*writing*/ true); - if (source === target) return Ternary.True; + if (source === target) + return ts.Ternary.True; } } - if (relation === comparableRelation && !(target.flags & TypeFlags.Never) && isSimpleTypeRelatedTo(target, source, relation) || - isSimpleTypeRelatedTo(source, target, relation, reportErrors ? reportError : undefined)) return Ternary.True; - - if (source.flags & TypeFlags.StructuredOrInstantiable || target.flags & TypeFlags.StructuredOrInstantiable) { - const isPerformingExcessPropertyChecks = !(intersectionState & IntersectionState.Target) && (isObjectLiteralType(source) && getObjectFlags(source) & ObjectFlags.FreshLiteral); + if (relation === comparableRelation && !(target.flags & ts.TypeFlags.Never) && isSimpleTypeRelatedTo(target, source, relation) || + isSimpleTypeRelatedTo(source, target, relation, reportErrors ? reportError : undefined)) + return ts.Ternary.True; + if (source.flags & ts.TypeFlags.StructuredOrInstantiable || target.flags & ts.TypeFlags.StructuredOrInstantiable) { + const isPerformingExcessPropertyChecks = !(intersectionState & IntersectionState.Target) && (isObjectLiteralType(source) && ts.getObjectFlags(source) & ts.ObjectFlags.FreshLiteral); if (isPerformingExcessPropertyChecks) { - if (hasExcessProperties(source as FreshObjectLiteralType, target, reportErrors)) { + if (hasExcessProperties(source as ts.FreshObjectLiteralType, target, reportErrors)) { if (reportErrors) { reportRelationError(headMessage, source, originalTarget.aliasSymbol ? originalTarget : target); } - return Ternary.False; + return ts.Ternary.False; } } const isPerformingCommonPropertyChecks = relation !== comparableRelation && !(intersectionState & IntersectionState.Target) && - source.flags & (TypeFlags.Primitive | TypeFlags.Object | TypeFlags.Intersection) && source !== globalObjectType && - target.flags & (TypeFlags.Object | TypeFlags.Intersection) && isWeakType(target) && + source.flags & (ts.TypeFlags.Primitive | ts.TypeFlags.Object | ts.TypeFlags.Intersection) && source !== globalObjectType && + target.flags & (ts.TypeFlags.Object | ts.TypeFlags.Intersection) && isWeakType(target) && (getPropertiesOfType(source).length > 0 || typeHasCallOrConstructSignatures(source)); - const isComparingJsxAttributes = !!(getObjectFlags(source) & ObjectFlags.JsxAttributes); + const isComparingJsxAttributes = !!(ts.getObjectFlags(source) & ts.ObjectFlags.JsxAttributes); if (isPerformingCommonPropertyChecks && !hasCommonProperties(source, target, isComparingJsxAttributes)) { if (reportErrors) { const sourceString = typeToString(originalSource.aliasSymbol ? originalSource : source); const targetString = typeToString(originalTarget.aliasSymbol ? originalTarget : target); - const calls = getSignaturesOfType(source, SignatureKind.Call); - const constructs = getSignaturesOfType(source, SignatureKind.Construct); + const calls = getSignaturesOfType(source, ts.SignatureKind.Call); + const constructs = getSignaturesOfType(source, ts.SignatureKind.Construct); if (calls.length > 0 && isRelatedTo(getReturnTypeOfSignature(calls[0]), target, RecursionFlags.Source, /*reportErrors*/ false) || constructs.length > 0 && isRelatedTo(getReturnTypeOfSignature(constructs[0]), target, RecursionFlags.Source, /*reportErrors*/ false)) { - reportError(Diagnostics.Value_of_type_0_has_no_properties_in_common_with_type_1_Did_you_mean_to_call_it, sourceString, targetString); + reportError(ts.Diagnostics.Value_of_type_0_has_no_properties_in_common_with_type_1_Did_you_mean_to_call_it, sourceString, targetString); } else { - reportError(Diagnostics.Type_0_has_no_properties_in_common_with_type_1, sourceString, targetString); + reportError(ts.Diagnostics.Type_0_has_no_properties_in_common_with_type_1, sourceString, targetString); } } - return Ternary.False; + return ts.Ternary.False; } traceUnionsOrIntersectionsTooLarge(source, target); - const skipCaching = source.flags & TypeFlags.Union && (source as UnionType).types.length < 4 && !(target.flags & TypeFlags.Union) || - target.flags & TypeFlags.Union && (target as UnionType).types.length < 4 && !(source.flags & TypeFlags.StructuredOrInstantiable); + const skipCaching = source.flags & ts.TypeFlags.Union && (source as ts.UnionType).types.length < 4 && !(target.flags & ts.TypeFlags.Union) || + target.flags & ts.TypeFlags.Union && (target as ts.UnionType).types.length < 4 && !(source.flags & ts.TypeFlags.StructuredOrInstantiable); let result = skipCaching ? unionOrIntersectionRelatedTo(source, target, reportErrors, intersectionState) : recursiveTypeRelatedTo(source, target, reportErrors, intersectionState, recursionFlags); @@ -18712,9 +18185,8 @@ namespace ts { // // We suppress recursive intersection property checks because they can generate lots of work when relating // recursive intersections that are structurally similar but not exactly identical. See #37854. - if (result && !inPropertyCheck && ( - target.flags & TypeFlags.Intersection && (isPerformingExcessPropertyChecks || isPerformingCommonPropertyChecks) || - isNonGenericObjectType(target) && !isArrayOrTupleType(target) && source.flags & TypeFlags.Intersection && getApparentType(source).flags & TypeFlags.StructuredType && !some((source as IntersectionType).types, t => !!(getObjectFlags(t) & ObjectFlags.NonInferrableType)))) { + if (result && !inPropertyCheck && (target.flags & ts.TypeFlags.Intersection && (isPerformingExcessPropertyChecks || isPerformingCommonPropertyChecks) || + isNonGenericObjectType(target) && !isArrayOrTupleType(target) && source.flags & ts.TypeFlags.Intersection && getApparentType(source).flags & ts.TypeFlags.StructuredType && !ts.some((source as ts.IntersectionType).types, t => !!(ts.getObjectFlags(t) & ts.ObjectFlags.NonInferrableType)))) { inPropertyCheck = true; result &= recursiveTypeRelatedTo(source, target, reportErrors, IntersectionState.PropertyCheck, recursionFlags); inPropertyCheck = false; @@ -18727,10 +18199,10 @@ namespace ts { if (reportErrors) { reportErrorResults(originalSource, originalTarget, source, target, headMessage); } - return Ternary.False; + return ts.Ternary.False; } - function reportErrorResults(originalSource: Type, originalTarget: Type, source: Type, target: Type, headMessage: DiagnosticMessage | undefined) { + function reportErrorResults(originalSource: ts.Type, originalTarget: ts.Type, source: ts.Type, target: ts.Type, headMessage: ts.DiagnosticMessage | undefined) { const sourceHasBase = !!getSingleBaseForNonAugmentingSubtype(originalSource); const targetHasBase = !!getSingleBaseForNonAugmentingSubtype(originalTarget); source = (originalSource.aliasSymbol || sourceHasBase) ? originalSource : source; @@ -18739,25 +18211,25 @@ namespace ts { if (maybeSuppress) { overrideNextErrorInfo--; } - if (source.flags & TypeFlags.Object && target.flags & TypeFlags.Object) { + if (source.flags & ts.TypeFlags.Object && target.flags & ts.TypeFlags.Object) { const currentError = errorInfo; tryElaborateArrayLikeErrors(source, target, /*reportErrors*/ true); if (errorInfo !== currentError) { maybeSuppress = !!errorInfo; } } - if (source.flags & TypeFlags.Object && target.flags & TypeFlags.Primitive) { + if (source.flags & ts.TypeFlags.Object && target.flags & ts.TypeFlags.Primitive) { tryElaborateErrorsForPrimitivesAndObjects(source, target); } - else if (source.symbol && source.flags & TypeFlags.Object && globalObjectType === source) { - reportError(Diagnostics.The_Object_type_is_assignable_to_very_few_other_types_Did_you_mean_to_use_the_any_type_instead); + else if (source.symbol && source.flags & ts.TypeFlags.Object && globalObjectType === source) { + reportError(ts.Diagnostics.The_Object_type_is_assignable_to_very_few_other_types_Did_you_mean_to_use_the_any_type_instead); } - else if (getObjectFlags(source) & ObjectFlags.JsxAttributes && target.flags & TypeFlags.Intersection) { - const targetTypes = (target as IntersectionType).types; + else if (ts.getObjectFlags(source) & ts.ObjectFlags.JsxAttributes && target.flags & ts.TypeFlags.Intersection) { + const targetTypes = (target as ts.IntersectionType).types; const intrinsicAttributes = getJsxType(JsxNames.IntrinsicAttributes, errorNode); const intrinsicClassAttributes = getJsxType(JsxNames.IntrinsicClassAttributes, errorNode); if (!isErrorType(intrinsicAttributes) && !isErrorType(intrinsicClassAttributes) && - (contains(targetTypes, intrinsicAttributes) || contains(targetTypes, intrinsicClassAttributes))) { + (ts.contains(targetTypes, intrinsicAttributes) || ts.contains(targetTypes, intrinsicClassAttributes))) { // do not report top error return; } @@ -18773,16 +18245,15 @@ namespace ts { reportRelationError(headMessage, source, target); } - function traceUnionsOrIntersectionsTooLarge(source: Type, target: Type): void { - if (!tracing) { + function traceUnionsOrIntersectionsTooLarge(source: ts.Type, target: ts.Type): void { + if (!ts.tracing) { return; } - if ((source.flags & TypeFlags.UnionOrIntersection) && (target.flags & TypeFlags.UnionOrIntersection)) { - const sourceUnionOrIntersection = source as UnionOrIntersectionType; - const targetUnionOrIntersection = target as UnionOrIntersectionType; - - if (sourceUnionOrIntersection.objectFlags & targetUnionOrIntersection.objectFlags & ObjectFlags.PrimitiveUnion) { + if ((source.flags & ts.TypeFlags.UnionOrIntersection) && (target.flags & ts.TypeFlags.UnionOrIntersection)) { + const sourceUnionOrIntersection = source as ts.UnionOrIntersectionType; + const targetUnionOrIntersection = target as ts.UnionOrIntersectionType; + if (sourceUnionOrIntersection.objectFlags & targetUnionOrIntersection.objectFlags & ts.ObjectFlags.PrimitiveUnion) { // There's a fast path for comparing primitive unions return; } @@ -18790,7 +18261,7 @@ namespace ts { const sourceSize = sourceUnionOrIntersection.types.length; const targetSize = targetUnionOrIntersection.types.length; if (sourceSize * targetSize > 1E6) { - tracing.instant(tracing.Phase.CheckTypes, "traceUnionsOrIntersectionsTooLarge_DepthLimit", { + ts.tracing.instant(ts.tracing.Phase.CheckTypes, "traceUnionsOrIntersectionsTooLarge_DepthLimit", { sourceId: source.id, sourceSize, targetId: target.id, @@ -18802,30 +18273,30 @@ namespace ts { } } - function getTypeOfPropertyInTypes(types: Type[], name: __String) { - const appendPropType = (propTypes: Type[] | undefined, type: Type) => { + function getTypeOfPropertyInTypes(types: ts.Type[], name: ts.__String) { + const appendPropType = (propTypes: ts.Type[] | undefined, type: ts.Type) => { type = getApparentType(type); - const prop = type.flags & TypeFlags.UnionOrIntersection ? getPropertyOfUnionOrIntersectionType(type as UnionOrIntersectionType, name) : getPropertyOfObjectType(type, name); + const prop = type.flags & ts.TypeFlags.UnionOrIntersection ? getPropertyOfUnionOrIntersectionType(type as ts.UnionOrIntersectionType, name) : getPropertyOfObjectType(type, name); const propType = prop && getTypeOfSymbol(prop) || getApplicableIndexInfoForName(type, name)?.type || undefinedType; - return append(propTypes, propType); + return ts.append(propTypes, propType); }; - return getUnionType(reduceLeft(types, appendPropType, /*initial*/ undefined) || emptyArray); + return getUnionType(ts.reduceLeft(types, appendPropType, /*initial*/ undefined) || ts.emptyArray); } - function hasExcessProperties(source: FreshObjectLiteralType, target: Type, reportErrors: boolean): boolean { - if (!isExcessPropertyCheckTarget(target) || !noImplicitAny && getObjectFlags(target) & ObjectFlags.JSLiteral) { + function hasExcessProperties(source: ts.FreshObjectLiteralType, target: ts.Type, reportErrors: boolean): boolean { + if (!isExcessPropertyCheckTarget(target) || !noImplicitAny && ts.getObjectFlags(target) & ts.ObjectFlags.JSLiteral) { return false; // Disable excess property checks on JS literals to simulate having an implicit "index signature" - but only outside of noImplicitAny } - const isComparingJsxAttributes = !!(getObjectFlags(source) & ObjectFlags.JsxAttributes); + const isComparingJsxAttributes = !!(ts.getObjectFlags(source) & ts.ObjectFlags.JsxAttributes); if ((relation === assignableRelation || relation === comparableRelation) && (isTypeSubsetOf(globalObjectType, target) || (!isComparingJsxAttributes && isEmptyObjectType(target)))) { return false; } let reducedTarget = target; - let checkTypes: Type[] | undefined; - if (target.flags & TypeFlags.Union) { - reducedTarget = findMatchingDiscriminantType(source, target as UnionType, isRelatedTo) || filterPrimitivesIfContainsNonPrimitive(target as UnionType); - checkTypes = reducedTarget.flags & TypeFlags.Union ? (reducedTarget as UnionType).types : [reducedTarget]; + let checkTypes: ts.Type[] | undefined; + if (target.flags & ts.TypeFlags.Union) { + reducedTarget = findMatchingDiscriminantType(source, target as ts.UnionType, isRelatedTo) || filterPrimitivesIfContainsNonPrimitive(target as ts.UnionType); + checkTypes = reducedTarget.flags & ts.TypeFlags.Union ? (reducedTarget as ts.UnionType).types : [reducedTarget]; } for (const prop of getPropertiesOfType(source)) { if (shouldCheckAsExcessProperty(prop, source.symbol) && !isIgnoredJsxProperty(source, prop)) { @@ -18837,11 +18308,12 @@ namespace ts { // We know *exactly* where things went wrong when comparing the types. // Use this property as the error node as this will be more helpful in // reasoning about what went wrong. - if (!errorNode) return Debug.fail(); - if (isJsxAttributes(errorNode) || isJsxOpeningLikeElement(errorNode) || isJsxOpeningLikeElement(errorNode.parent)) { + if (!errorNode) + return ts.Debug.fail(); + if (ts.isJsxAttributes(errorNode) || ts.isJsxOpeningLikeElement(errorNode) || ts.isJsxOpeningLikeElement(errorNode.parent)) { // JsxAttributes has an object-literal flag and undergo same type-assignablity check as normal object-literal. // However, using an object-literal error message will be very confusing to the users so we give different a message. - if (prop.valueDeclaration && isJsxAttribute(prop.valueDeclaration) && getSourceFileOfNode(errorNode) === getSourceFileOfNode(prop.valueDeclaration.name)) { + if (prop.valueDeclaration && ts.isJsxAttribute(prop.valueDeclaration) && ts.getSourceFileOfNode(errorNode) === ts.getSourceFileOfNode(prop.valueDeclaration.name)) { // Note that extraneous children (as in `extra`) don't pass this check, // since `children` is a SyntaxKind.PropertySignature instead of a SyntaxKind.JsxAttribute. errorNode = prop.valueDeclaration.name; @@ -18850,34 +18322,32 @@ namespace ts { const suggestionSymbol = getSuggestedSymbolForNonexistentJSXAttribute(propName, errorTarget); const suggestion = suggestionSymbol ? symbolToString(suggestionSymbol) : undefined; if (suggestion) { - reportError(Diagnostics.Property_0_does_not_exist_on_type_1_Did_you_mean_2, propName, typeToString(errorTarget), suggestion); + reportError(ts.Diagnostics.Property_0_does_not_exist_on_type_1_Did_you_mean_2, propName, typeToString(errorTarget), suggestion); } else { - reportError(Diagnostics.Property_0_does_not_exist_on_type_1, propName, typeToString(errorTarget)); + reportError(ts.Diagnostics.Property_0_does_not_exist_on_type_1, propName, typeToString(errorTarget)); } } else { // use the property's value declaration if the property is assigned inside the literal itself - const objectLiteralDeclaration = source.symbol?.declarations && firstOrUndefined(source.symbol.declarations); + const objectLiteralDeclaration = source.symbol?.declarations && ts.firstOrUndefined(source.symbol.declarations); let suggestion: string | undefined; - if (prop.valueDeclaration && findAncestor(prop.valueDeclaration, d => d === objectLiteralDeclaration) && getSourceFileOfNode(objectLiteralDeclaration) === getSourceFileOfNode(errorNode)) { - const propDeclaration = prop.valueDeclaration as ObjectLiteralElementLike; - Debug.assertNode(propDeclaration, isObjectLiteralElementLike); + if (prop.valueDeclaration && ts.findAncestor(prop.valueDeclaration, d => d === objectLiteralDeclaration) && ts.getSourceFileOfNode(objectLiteralDeclaration) === ts.getSourceFileOfNode(errorNode)) { + const propDeclaration = prop.valueDeclaration as ts.ObjectLiteralElementLike; + ts.Debug.assertNode(propDeclaration, ts.isObjectLiteralElementLike); errorNode = propDeclaration; const name = propDeclaration.name!; - if (isIdentifier(name)) { + if (ts.isIdentifier(name)) { suggestion = getSuggestionForNonexistentProperty(name, errorTarget); } } if (suggestion !== undefined) { - reportError(Diagnostics.Object_literal_may_only_specify_known_properties_but_0_does_not_exist_in_type_1_Did_you_mean_to_write_2, - symbolToString(prop), typeToString(errorTarget), suggestion); + reportError(ts.Diagnostics.Object_literal_may_only_specify_known_properties_but_0_does_not_exist_in_type_1_Did_you_mean_to_write_2, symbolToString(prop), typeToString(errorTarget), suggestion); } else { - reportError(Diagnostics.Object_literal_may_only_specify_known_properties_and_0_does_not_exist_in_type_1, - symbolToString(prop), typeToString(errorTarget)); + reportError(ts.Diagnostics.Object_literal_may_only_specify_known_properties_and_0_does_not_exist_in_type_1, symbolToString(prop), typeToString(errorTarget)); } } } @@ -18885,7 +18355,7 @@ namespace ts { } if (checkTypes && !isRelatedTo(getTypeOfSymbol(prop), getTypeOfPropertyInTypes(checkTypes, prop.escapedName), RecursionFlags.Both, reportErrors)) { if (reportErrors) { - reportIncompatibleError(Diagnostics.Types_of_property_0_are_incompatible, symbolToString(prop)); + reportIncompatibleError(ts.Diagnostics.Types_of_property_0_are_incompatible, symbolToString(prop)); } return true; } @@ -18894,35 +18364,35 @@ namespace ts { return false; } - function shouldCheckAsExcessProperty(prop: Symbol, container: Symbol) { + function shouldCheckAsExcessProperty(prop: ts.Symbol, container: ts.Symbol) { return prop.valueDeclaration && container.valueDeclaration && prop.valueDeclaration.parent === container.valueDeclaration; } - function unionOrIntersectionRelatedTo(source: Type, target: Type, reportErrors: boolean, intersectionState: IntersectionState): Ternary { + function unionOrIntersectionRelatedTo(source: ts.Type, target: ts.Type, reportErrors: boolean, intersectionState: IntersectionState): ts.Ternary { // Note that these checks are specifically ordered to produce correct results. In particular, // we need to deconstruct unions before intersections (because unions are always at the top), // and we need to handle "each" relations before "some" relations for the same kind of type. - if (source.flags & TypeFlags.Union) { + if (source.flags & ts.TypeFlags.Union) { return relation === comparableRelation ? - someTypeRelatedToType(source as UnionType, target, reportErrors && !(source.flags & TypeFlags.Primitive), intersectionState) : - eachTypeRelatedToType(source as UnionType, target, reportErrors && !(source.flags & TypeFlags.Primitive), intersectionState); + someTypeRelatedToType(source as ts.UnionType, target, reportErrors && !(source.flags & ts.TypeFlags.Primitive), intersectionState) : + eachTypeRelatedToType(source as ts.UnionType, target, reportErrors && !(source.flags & ts.TypeFlags.Primitive), intersectionState); } - if (target.flags & TypeFlags.Union) { - return typeRelatedToSomeType(getRegularTypeOfObjectLiteral(source), target as UnionType, reportErrors && !(source.flags & TypeFlags.Primitive) && !(target.flags & TypeFlags.Primitive)); + if (target.flags & ts.TypeFlags.Union) { + return typeRelatedToSomeType(getRegularTypeOfObjectLiteral(source), target as ts.UnionType, reportErrors && !(source.flags & ts.TypeFlags.Primitive) && !(target.flags & ts.TypeFlags.Primitive)); } - if (target.flags & TypeFlags.Intersection) { - return typeRelatedToEachType(getRegularTypeOfObjectLiteral(source), target as IntersectionType, reportErrors, IntersectionState.Target); + if (target.flags & ts.TypeFlags.Intersection) { + return typeRelatedToEachType(getRegularTypeOfObjectLiteral(source), target as ts.IntersectionType, reportErrors, IntersectionState.Target); } // Source is an intersection. For the comparable relation, if the target is a primitive type we hoist the // constraints of all non-primitive types in the source into a new intersection. We do this because the // intersection may further constrain the constraints of the non-primitive types. For example, given a type // parameter 'T extends 1 | 2', the intersection 'T & 1' should be reduced to '1' such that it doesn't // appear to be comparable to '2'. - if (relation === comparableRelation && target.flags & TypeFlags.Primitive) { - const constraints = sameMap((source as IntersectionType).types, getBaseConstraintOrType); - if (constraints !== (source as IntersectionType).types) { + if (relation === comparableRelation && target.flags & ts.TypeFlags.Primitive) { + const constraints = ts.sameMap((source as ts.IntersectionType).types, getBaseConstraintOrType); + if (constraints !== (source as ts.IntersectionType).types) { source = getIntersectionType(constraints); - if (!(source.flags & TypeFlags.Intersection)) { + if (!(source.flags & ts.TypeFlags.Intersection)) { return isRelatedTo(source, target, RecursionFlags.Source, /*reportErrors*/ false); } } @@ -18931,29 +18401,29 @@ namespace ts { // Don't report errors though. Elaborating on whether a source constituent is related to the target is // not actually useful and leads to some confusing error messages. Instead, we rely on the caller // checking whether the full intersection viewed as an object is related to the target. - return someTypeRelatedToType(source as IntersectionType, target, /*reportErrors*/ false, IntersectionState.Source); + return someTypeRelatedToType(source as ts.IntersectionType, target, /*reportErrors*/ false, IntersectionState.Source); } - function eachTypeRelatedToSomeType(source: UnionOrIntersectionType, target: UnionOrIntersectionType): Ternary { - let result = Ternary.True; + function eachTypeRelatedToSomeType(source: ts.UnionOrIntersectionType, target: ts.UnionOrIntersectionType): ts.Ternary { + let result = ts.Ternary.True; const sourceTypes = source.types; for (const sourceType of sourceTypes) { const related = typeRelatedToSomeType(sourceType, target, /*reportErrors*/ false); if (!related) { - return Ternary.False; + return ts.Ternary.False; } result &= related; } return result; } - function typeRelatedToSomeType(source: Type, target: UnionOrIntersectionType, reportErrors: boolean): Ternary { + function typeRelatedToSomeType(source: ts.Type, target: ts.UnionOrIntersectionType, reportErrors: boolean): ts.Ternary { const targetTypes = target.types; - if (target.flags & TypeFlags.Union) { + if (target.flags & ts.TypeFlags.Union) { if (containsType(targetTypes, source)) { - return Ternary.True; + return ts.Ternary.True; } - const match = getMatchingUnionConstituentForType(target as UnionType, source); + const match = getMatchingUnionConstituentForType(target as ts.UnionType, source); if (match) { const related = isRelatedTo(source, match, RecursionFlags.Target, /*reportErrors*/ false); if (related) { @@ -18974,26 +18444,26 @@ namespace ts { isRelatedTo(source, bestMatchingType, RecursionFlags.Target, /*reportErrors*/ true); } } - return Ternary.False; + return ts.Ternary.False; } - function typeRelatedToEachType(source: Type, target: IntersectionType, reportErrors: boolean, intersectionState: IntersectionState): Ternary { - let result = Ternary.True; + function typeRelatedToEachType(source: ts.Type, target: ts.IntersectionType, reportErrors: boolean, intersectionState: IntersectionState): ts.Ternary { + let result = ts.Ternary.True; const targetTypes = target.types; for (const targetType of targetTypes) { const related = isRelatedTo(source, targetType, RecursionFlags.Target, reportErrors, /*headMessage*/ undefined, intersectionState); if (!related) { - return Ternary.False; + return ts.Ternary.False; } result &= related; } return result; } - function someTypeRelatedToType(source: UnionOrIntersectionType, target: Type, reportErrors: boolean, intersectionState: IntersectionState): Ternary { + function someTypeRelatedToType(source: ts.UnionOrIntersectionType, target: ts.Type, reportErrors: boolean, intersectionState: IntersectionState): ts.Ternary { const sourceTypes = source.types; - if (source.flags & TypeFlags.Union && containsType(sourceTypes, target)) { - return Ternary.True; + if (source.flags & ts.TypeFlags.Union && containsType(sourceTypes, target)) { + return ts.Ternary.True; } const len = sourceTypes.length; for (let i = 0; i < len; i++) { @@ -19002,34 +18472,34 @@ namespace ts { return related; } } - return Ternary.False; + return ts.Ternary.False; } - function getUndefinedStrippedTargetIfNeeded(source: Type, target: Type) { + function getUndefinedStrippedTargetIfNeeded(source: ts.Type, target: ts.Type) { // As a builtin type, `undefined` is a very low type ID - making it almsot always first, making this a very fast check to see // if we need to strip `undefined` from the target - if (source.flags & TypeFlags.Union && target.flags & TypeFlags.Union && - !((source as UnionType).types[0].flags & TypeFlags.Undefined) && (target as UnionType).types[0].flags & TypeFlags.Undefined) { - return extractTypesOfKind(target, ~TypeFlags.Undefined); + if (source.flags & ts.TypeFlags.Union && target.flags & ts.TypeFlags.Union && + !((source as ts.UnionType).types[0].flags & ts.TypeFlags.Undefined) && (target as ts.UnionType).types[0].flags & ts.TypeFlags.Undefined) { + return extractTypesOfKind(target, ~ts.TypeFlags.Undefined); } return target; } - function eachTypeRelatedToType(source: UnionOrIntersectionType, target: Type, reportErrors: boolean, intersectionState: IntersectionState): Ternary { - let result = Ternary.True; + function eachTypeRelatedToType(source: ts.UnionOrIntersectionType, target: ts.Type, reportErrors: boolean, intersectionState: IntersectionState): ts.Ternary { + let result = ts.Ternary.True; const sourceTypes = source.types; // We strip `undefined` from the target if the `source` trivially doesn't contain it for our correspondence-checking fastpath // since `undefined` is frequently added by optionality and would otherwise spoil a potentially useful correspondence - const undefinedStrippedTarget = getUndefinedStrippedTargetIfNeeded(source, target as UnionType); + const undefinedStrippedTarget = getUndefinedStrippedTargetIfNeeded(source, target as ts.UnionType); for (let i = 0; i < sourceTypes.length; i++) { const sourceType = sourceTypes[i]; - if (undefinedStrippedTarget.flags & TypeFlags.Union && sourceTypes.length >= (undefinedStrippedTarget as UnionType).types.length && sourceTypes.length % (undefinedStrippedTarget as UnionType).types.length === 0) { + if (undefinedStrippedTarget.flags & ts.TypeFlags.Union && sourceTypes.length >= (undefinedStrippedTarget as ts.UnionType).types.length && sourceTypes.length % (undefinedStrippedTarget as ts.UnionType).types.length === 0) { // many unions are mappings of one another; in such cases, simply comparing members at the same index can shortcut the comparison // such unions will have identical lengths, and their corresponding elements will match up. Another common scenario is where a large // union has a union of objects intersected with it. In such cases, if the input was, eg `("a" | "b" | "c") & (string | boolean | {} | {whatever})`, // the result will have the structure `"a" | "b" | "c" | "a" & {} | "b" & {} | "c" & {} | "a" & {whatever} | "b" & {whatever} | "c" & {whatever}` // - the resulting union has a length which is a multiple of the original union, and the elements correspond modulo the length of the original union - const related = isRelatedTo(sourceType, (undefinedStrippedTarget as UnionType).types[i % (undefinedStrippedTarget as UnionType).types.length], RecursionFlags.Both, /*reportErrors*/ false, /*headMessage*/ undefined, intersectionState); + const related = isRelatedTo(sourceType, (undefinedStrippedTarget as ts.UnionType).types[i % (undefinedStrippedTarget as ts.UnionType).types.length], RecursionFlags.Both, /*reportErrors*/ false, /*headMessage*/ undefined, intersectionState); if (related) { result &= related; continue; @@ -19037,43 +18507,43 @@ namespace ts { } const related = isRelatedTo(sourceType, target, RecursionFlags.Source, reportErrors, /*headMessage*/ undefined, intersectionState); if (!related) { - return Ternary.False; + return ts.Ternary.False; } result &= related; } return result; } - function typeArgumentsRelatedTo(sources: readonly Type[] = emptyArray, targets: readonly Type[] = emptyArray, variances: readonly VarianceFlags[] = emptyArray, reportErrors: boolean, intersectionState: IntersectionState): Ternary { + function typeArgumentsRelatedTo(sources: readonly ts.Type[] = ts.emptyArray, targets: readonly ts.Type[] = ts.emptyArray, variances: readonly ts.VarianceFlags[] = ts.emptyArray, reportErrors: boolean, intersectionState: IntersectionState): ts.Ternary { if (sources.length !== targets.length && relation === identityRelation) { - return Ternary.False; + return ts.Ternary.False; } const length = sources.length <= targets.length ? sources.length : targets.length; - let result = Ternary.True; + let result = ts.Ternary.True; for (let i = 0; i < length; i++) { // When variance information isn't available we default to covariance. This happens // in the process of computing variance information for recursive types and when // comparing 'this' type arguments. - const varianceFlags = i < variances.length ? variances[i] : VarianceFlags.Covariant; - const variance = varianceFlags & VarianceFlags.VarianceMask; + const varianceFlags = i < variances.length ? variances[i] : ts.VarianceFlags.Covariant; + const variance = varianceFlags & ts.VarianceFlags.VarianceMask; // We ignore arguments for independent type parameters (because they're never witnessed). - if (variance !== VarianceFlags.Independent) { + if (variance !== ts.VarianceFlags.Independent) { const s = sources[i]; const t = targets[i]; - let related = Ternary.True; - if (varianceFlags & VarianceFlags.Unmeasurable) { + let related = ts.Ternary.True; + if (varianceFlags & ts.VarianceFlags.Unmeasurable) { // Even an `Unmeasurable` variance works out without a structural check if the source and target are _identical_. // We can't simply assume invariance, because `Unmeasurable` marks nonlinear relations, for example, a relation tained by // the `-?` modifier in a mapped type (where, no matter how the inputs are related, the outputs still might not be) related = relation === identityRelation ? isRelatedTo(s, t, RecursionFlags.Both, /*reportErrors*/ false) : compareTypesIdentical(s, t); } - else if (variance === VarianceFlags.Covariant) { + else if (variance === ts.VarianceFlags.Covariant) { related = isRelatedTo(s, t, RecursionFlags.Both, reportErrors, /*headMessage*/ undefined, intersectionState); } - else if (variance === VarianceFlags.Contravariant) { + else if (variance === ts.VarianceFlags.Contravariant) { related = isRelatedTo(t, s, RecursionFlags.Both, reportErrors, /*headMessage*/ undefined, intersectionState); } - else if (variance === VarianceFlags.Bivariant) { + else if (variance === ts.VarianceFlags.Bivariant) { // In the bivariant case we first compare contravariantly without reporting // errors. Then, if that doesn't succeed, we compare covariantly with error // reporting. Thus, error elaboration will be based on the the covariant check, @@ -19093,7 +18563,7 @@ namespace ts { } } if (!related) { - return Ternary.False; + return ts.Ternary.False; } result &= related; } @@ -19106,30 +18576,30 @@ namespace ts { // Third, check if both types are part of deeply nested chains of generic type instantiations and if so assume the types are // equal and infinitely expanding. Fourth, if we have reached a depth of 100 nested comparisons, assume we have runaway recursion // and issue an error. Otherwise, actually compare the structure of the two types. - function recursiveTypeRelatedTo(source: Type, target: Type, reportErrors: boolean, intersectionState: IntersectionState, recursionFlags: RecursionFlags): Ternary { + function recursiveTypeRelatedTo(source: ts.Type, target: ts.Type, reportErrors: boolean, intersectionState: IntersectionState, recursionFlags: RecursionFlags): ts.Ternary { if (overflow) { - return Ternary.False; + return ts.Ternary.False; } const keyIntersectionState = intersectionState | (inPropertyCheck ? IntersectionState.InPropertyCheck : 0); const id = getRelationKey(source, target, keyIntersectionState, relation, /*ingnoreConstraints*/ false); const entry = relation.get(id); if (entry !== undefined) { - if (reportErrors && entry & RelationComparisonResult.Failed && !(entry & RelationComparisonResult.Reported)) { + if (reportErrors && entry & ts.RelationComparisonResult.Failed && !(entry & ts.RelationComparisonResult.Reported)) { // We are elaborating errors and the cached result is an unreported failure. The result will be reported // as a failure, and should be updated as a reported failure by the bottom of this function. } else { if (outofbandVarianceMarkerHandler) { // We're in the middle of variance checking - integrate any unmeasurable/unreliable flags from this cached component - const saved = entry & RelationComparisonResult.ReportsMask; - if (saved & RelationComparisonResult.ReportsUnmeasurable) { + const saved = entry & ts.RelationComparisonResult.ReportsMask; + if (saved & ts.RelationComparisonResult.ReportsUnmeasurable) { instantiateType(source, makeFunctionTypeMapper(reportUnmeasurableMarkers)); } - if (saved & RelationComparisonResult.ReportsUnreliable) { + if (saved & ts.RelationComparisonResult.ReportsUnreliable) { instantiateType(source, makeFunctionTypeMapper(reportUnreliableMarkers)); } } - return entry & RelationComparisonResult.Succeeded ? Ternary.True : Ternary.False; + return entry & ts.RelationComparisonResult.Succeeded ? ts.Ternary.True : ts.Ternary.False; } } if (!maybeKeys) { @@ -19145,12 +18615,12 @@ namespace ts { for (let i = 0; i < maybeCount; i++) { // If source and target are already being compared, consider them related with assumptions if (id === maybeKeys[i] || broadestEquivalentId && broadestEquivalentId === maybeKeys[i]) { - return Ternary.Maybe; + return ts.Ternary.Maybe; } } if (sourceDepth === 100 || targetDepth === 100) { overflow = true; - return Ternary.False; + return ts.Ternary.False; } } const maybeStart = maybeCount; @@ -19160,26 +18630,28 @@ namespace ts { if (recursionFlags & RecursionFlags.Source) { sourceStack[sourceDepth] = source; sourceDepth++; - if (!(expandingFlags & ExpandingFlags.Source) && isDeeplyNestedType(source, sourceStack, sourceDepth)) expandingFlags |= ExpandingFlags.Source; + if (!(expandingFlags & ExpandingFlags.Source) && isDeeplyNestedType(source, sourceStack, sourceDepth)) + expandingFlags |= ExpandingFlags.Source; } if (recursionFlags & RecursionFlags.Target) { targetStack[targetDepth] = target; targetDepth++; - if (!(expandingFlags & ExpandingFlags.Target) && isDeeplyNestedType(target, targetStack, targetDepth)) expandingFlags |= ExpandingFlags.Target; + if (!(expandingFlags & ExpandingFlags.Target) && isDeeplyNestedType(target, targetStack, targetDepth)) + expandingFlags |= ExpandingFlags.Target; } let originalHandler: typeof outofbandVarianceMarkerHandler; - let propagatingVarianceFlags: RelationComparisonResult = 0; + let propagatingVarianceFlags: ts.RelationComparisonResult = 0; if (outofbandVarianceMarkerHandler) { originalHandler = outofbandVarianceMarkerHandler; outofbandVarianceMarkerHandler = onlyUnreliable => { - propagatingVarianceFlags |= onlyUnreliable ? RelationComparisonResult.ReportsUnreliable : RelationComparisonResult.ReportsUnmeasurable; + propagatingVarianceFlags |= onlyUnreliable ? ts.RelationComparisonResult.ReportsUnreliable : ts.RelationComparisonResult.ReportsUnmeasurable; return originalHandler!(onlyUnreliable); }; } - let result: Ternary; + let result: ts.Ternary; if (expandingFlags === ExpandingFlags.Both) { - tracing?.instant(tracing.Phase.CheckTypes, "recursiveTypeRelatedTo_DepthLimit", { + ts.tracing?.instant(ts.tracing.Phase.CheckTypes, "recursiveTypeRelatedTo_DepthLimit", { sourceId: source.id, sourceIdStack: sourceStack.map(t => t.id), targetId: target.id, @@ -19187,12 +18659,12 @@ namespace ts { depth: sourceDepth, targetDepth }); - result = Ternary.Maybe; + result = ts.Ternary.Maybe; } else { - tracing?.push(tracing.Phase.CheckTypes, "structuredTypeRelatedTo", { sourceId: source.id, targetId: target.id }); + ts.tracing?.push(ts.tracing.Phase.CheckTypes, "structuredTypeRelatedTo", { sourceId: source.id, targetId: target.id }); result = structuredTypeRelatedTo(source, target, reportErrors, intersectionState); - tracing?.pop(); + ts.tracing?.pop(); } if (outofbandVarianceMarkerHandler) { @@ -19206,12 +18678,12 @@ namespace ts { } expandingFlags = saveExpandingFlags; if (result) { - if (result === Ternary.True || (sourceDepth === 0 && targetDepth === 0)) { - if (result === Ternary.True || result === Ternary.Maybe) { + if (result === ts.Ternary.True || (sourceDepth === 0 && targetDepth === 0)) { + if (result === ts.Ternary.True || result === ts.Ternary.Maybe) { // If result is definitely true, record all maybe keys as having succeeded. Also, record Ternary.Maybe // results as having succeeded once we reach depth 0, but never record Ternary.Unknown results. for (let i = maybeStart; i < maybeCount; i++) { - relation.set(maybeKeys[i], RelationComparisonResult.Succeeded | propagatingVarianceFlags); + relation.set(maybeKeys[i], ts.RelationComparisonResult.Succeeded | propagatingVarianceFlags); } } maybeCount = maybeStart; @@ -19220,47 +18692,47 @@ namespace ts { else { // A false result goes straight into global cache (when something is false under // assumptions it will also be false without assumptions) - relation.set(id, (reportErrors ? RelationComparisonResult.Reported : 0) | RelationComparisonResult.Failed | propagatingVarianceFlags); + relation.set(id, (reportErrors ? ts.RelationComparisonResult.Reported : 0) | ts.RelationComparisonResult.Failed | propagatingVarianceFlags); maybeCount = maybeStart; } return result; } - function structuredTypeRelatedTo(source: Type, target: Type, reportErrors: boolean, intersectionState: IntersectionState): Ternary { + function structuredTypeRelatedTo(source: ts.Type, target: ts.Type, reportErrors: boolean, intersectionState: IntersectionState): ts.Ternary { if (intersectionState & IntersectionState.PropertyCheck) { return propertiesRelatedTo(source, target, reportErrors, /*excludedProperties*/ undefined, IntersectionState.None); } - let result: Ternary; - let originalErrorInfo: DiagnosticMessageChain | undefined; + let result: ts.Ternary; + let originalErrorInfo: ts.DiagnosticMessageChain | undefined; let varianceCheckFailed = false; const saveErrorInfo = captureErrorCalculationState(); let sourceFlags = source.flags; const targetFlags = target.flags; if (relation === identityRelation) { // We've already checked that source.flags and target.flags are identical - if (sourceFlags & TypeFlags.UnionOrIntersection) { - let result = eachTypeRelatedToSomeType(source as UnionOrIntersectionType, target as UnionOrIntersectionType); + if (sourceFlags & ts.TypeFlags.UnionOrIntersection) { + let result = eachTypeRelatedToSomeType(source as ts.UnionOrIntersectionType, target as ts.UnionOrIntersectionType); if (result) { - result &= eachTypeRelatedToSomeType(target as UnionOrIntersectionType, source as UnionOrIntersectionType); + result &= eachTypeRelatedToSomeType(target as ts.UnionOrIntersectionType, source as ts.UnionOrIntersectionType); } return result; } - if (sourceFlags & TypeFlags.Index) { - return isRelatedTo((source as IndexType).type, (target as IndexType).type, RecursionFlags.Both, /*reportErrors*/ false); + if (sourceFlags & ts.TypeFlags.Index) { + return isRelatedTo((source as ts.IndexType).type, (target as ts.IndexType).type, RecursionFlags.Both, /*reportErrors*/ false); } - if (sourceFlags & TypeFlags.IndexedAccess) { - if (result = isRelatedTo((source as IndexedAccessType).objectType, (target as IndexedAccessType).objectType, RecursionFlags.Both, /*reportErrors*/ false)) { - if (result &= isRelatedTo((source as IndexedAccessType).indexType, (target as IndexedAccessType).indexType, RecursionFlags.Both, /*reportErrors*/ false)) { + if (sourceFlags & ts.TypeFlags.IndexedAccess) { + if (result = isRelatedTo((source as ts.IndexedAccessType).objectType, (target as ts.IndexedAccessType).objectType, RecursionFlags.Both, /*reportErrors*/ false)) { + if (result &= isRelatedTo((source as ts.IndexedAccessType).indexType, (target as ts.IndexedAccessType).indexType, RecursionFlags.Both, /*reportErrors*/ false)) { return result; } } } - if (sourceFlags & TypeFlags.Conditional) { - if ((source as ConditionalType).root.isDistributive === (target as ConditionalType).root.isDistributive) { - if (result = isRelatedTo((source as ConditionalType).checkType, (target as ConditionalType).checkType, RecursionFlags.Both, /*reportErrors*/ false)) { - if (result &= isRelatedTo((source as ConditionalType).extendsType, (target as ConditionalType).extendsType, RecursionFlags.Both, /*reportErrors*/ false)) { - if (result &= isRelatedTo(getTrueTypeFromConditionalType(source as ConditionalType), getTrueTypeFromConditionalType(target as ConditionalType), RecursionFlags.Both, /*reportErrors*/ false)) { - if (result &= isRelatedTo(getFalseTypeFromConditionalType(source as ConditionalType), getFalseTypeFromConditionalType(target as ConditionalType), RecursionFlags.Both, /*reportErrors*/ false)) { + if (sourceFlags & ts.TypeFlags.Conditional) { + if ((source as ts.ConditionalType).root.isDistributive === (target as ts.ConditionalType).root.isDistributive) { + if (result = isRelatedTo((source as ts.ConditionalType).checkType, (target as ts.ConditionalType).checkType, RecursionFlags.Both, /*reportErrors*/ false)) { + if (result &= isRelatedTo((source as ts.ConditionalType).extendsType, (target as ts.ConditionalType).extendsType, RecursionFlags.Both, /*reportErrors*/ false)) { + if (result &= isRelatedTo(getTrueTypeFromConditionalType(source as ts.ConditionalType), getTrueTypeFromConditionalType(target as ts.ConditionalType), RecursionFlags.Both, /*reportErrors*/ false)) { + if (result &= isRelatedTo(getFalseTypeFromConditionalType(source as ts.ConditionalType), getFalseTypeFromConditionalType(target as ts.ConditionalType), RecursionFlags.Both, /*reportErrors*/ false)) { return result; } } @@ -19268,18 +18740,18 @@ namespace ts { } } } - if (sourceFlags & TypeFlags.Substitution) { - return isRelatedTo((source as SubstitutionType).substitute, (target as SubstitutionType).substitute, RecursionFlags.Both, /*reportErrors*/ false); + if (sourceFlags & ts.TypeFlags.Substitution) { + return isRelatedTo((source as ts.SubstitutionType).substitute, (target as ts.SubstitutionType).substitute, RecursionFlags.Both, /*reportErrors*/ false); } - if (!(sourceFlags & TypeFlags.Object)) { - return Ternary.False; + if (!(sourceFlags & ts.TypeFlags.Object)) { + return ts.Ternary.False; } } - else if (sourceFlags & TypeFlags.UnionOrIntersection || targetFlags & TypeFlags.UnionOrIntersection) { + else if (sourceFlags & ts.TypeFlags.UnionOrIntersection || targetFlags & ts.TypeFlags.UnionOrIntersection) { if (result = unionOrIntersectionRelatedTo(source, target, reportErrors, intersectionState)) { return result; } - if (source.flags & TypeFlags.Intersection || source.flags & TypeFlags.TypeParameter && target.flags & TypeFlags.Union) { + if (source.flags & ts.TypeFlags.Intersection || source.flags & ts.TypeFlags.TypeParameter && target.flags & ts.TypeFlags.Union) { // The combined constraint of an intersection type is the intersection of the constraints of // the constituents. When an intersection type contains instantiable types with union type // constraints, there are situations where we need to examine the combined constraint. One is @@ -19293,7 +18765,7 @@ namespace ts { // needs to have its constraint hoisted into an intersection with said type parameter, this way // the type param can be compared with itself in the target (with the influence of its constraint to match other parts) // For example, if `T extends 1 | 2` and `U extends 2 | 3` and we compare `T & U` to `T & U & (1 | 2 | 3)` - const constraint = getEffectiveConstraintOfIntersection(source.flags & TypeFlags.Intersection ? (source as IntersectionType).types: [source], !!(target.flags & TypeFlags.Union)); + const constraint = getEffectiveConstraintOfIntersection(source.flags & ts.TypeFlags.Intersection ? (source as ts.IntersectionType).types : [source], !!(target.flags & ts.TypeFlags.Union)); if (constraint && everyType(constraint, c => c !== source)) { // Skip comparison if expansion contains the source itself // TODO: Stack errors so we get a pyramid for the "normal" comparison above, _and_ a second for this if (result = isRelatedTo(constraint, target, RecursionFlags.Source, /*reportErrors*/ false, /*headMessage*/ undefined, intersectionState)) { @@ -19308,21 +18780,21 @@ namespace ts { // Source is an intersection, target is an object (e.g. { a } & { b } <=> { a, b }). // Source is an intersection, target is a union (e.g. { a } & { b: boolean } <=> { a, b: true } | { a, b: false }). // Source is an intersection, target instantiable (e.g. string & { tag } <=> T["a"] constrained to string & { tag }). - if (!(sourceFlags & TypeFlags.Instantiable || - sourceFlags & TypeFlags.Object && targetFlags & TypeFlags.Union || - sourceFlags & TypeFlags.Intersection && targetFlags & (TypeFlags.Object | TypeFlags.Union | TypeFlags.Instantiable))) { - return Ternary.False; + if (!(sourceFlags & ts.TypeFlags.Instantiable || + sourceFlags & ts.TypeFlags.Object && targetFlags & ts.TypeFlags.Union || + sourceFlags & ts.TypeFlags.Intersection && targetFlags & (ts.TypeFlags.Object | ts.TypeFlags.Union | ts.TypeFlags.Instantiable))) { + return ts.Ternary.False; } } // We limit alias variance probing to only object and conditional types since their alias behavior // is more predictable than other, interned types, which may or may not have an alias depending on // the order in which things were checked. - if (sourceFlags & (TypeFlags.Object | TypeFlags.Conditional) && source.aliasSymbol && source.aliasTypeArguments && + if (sourceFlags & (ts.TypeFlags.Object | ts.TypeFlags.Conditional) && source.aliasSymbol && source.aliasTypeArguments && source.aliasSymbol === target.aliasSymbol && !(isMarkerType(source) || isMarkerType(target))) { const variances = getAliasVariances(source.aliasSymbol); - if (variances === emptyArray) { - return Ternary.Unknown; + if (variances === ts.emptyArray) { + return ts.Ternary.Unknown; } const varianceResult = relateVariances(source.aliasTypeArguments, target.aliasTypeArguments, variances, intersectionState); if (varianceResult !== undefined) { @@ -19337,38 +18809,37 @@ namespace ts { return result; } - if (targetFlags & TypeFlags.TypeParameter) { + if (targetFlags & ts.TypeFlags.TypeParameter) { // A source type { [P in Q]: X } is related to a target type T if keyof T is related to Q and X is related to T[Q]. - if (getObjectFlags(source) & ObjectFlags.Mapped && !(source as MappedType).declaration.nameType && isRelatedTo(getIndexType(target), getConstraintTypeFromMappedType(source as MappedType), RecursionFlags.Both)) { - - if (!(getMappedTypeModifiers(source as MappedType) & MappedTypeModifiers.IncludeOptional)) { - const templateType = getTemplateTypeFromMappedType(source as MappedType); - const indexedAccessType = getIndexedAccessType(target, getTypeParameterFromMappedType(source as MappedType)); + if (ts.getObjectFlags(source) & ts.ObjectFlags.Mapped && !(source as ts.MappedType).declaration.nameType && isRelatedTo(getIndexType(target), getConstraintTypeFromMappedType(source as ts.MappedType), RecursionFlags.Both)) { + if (!(getMappedTypeModifiers(source as ts.MappedType) & MappedTypeModifiers.IncludeOptional)) { + const templateType = getTemplateTypeFromMappedType(source as ts.MappedType); + const indexedAccessType = getIndexedAccessType(target, getTypeParameterFromMappedType(source as ts.MappedType)); if (result = isRelatedTo(templateType, indexedAccessType, RecursionFlags.Both, reportErrors)) { return result; } } } - if (relation === comparableRelation && sourceFlags & TypeFlags.TypeParameter) { + if (relation === comparableRelation && sourceFlags & ts.TypeFlags.TypeParameter) { // This is a carve-out in comparability to essentially forbid comparing a type parameter // with another type parameter unless one extends the other. (Remember: comparability is mostly bidirectional!) let constraint = getConstraintOfTypeParameter(source); if (constraint && hasNonCircularBaseConstraint(source)) { - while (constraint && constraint.flags & TypeFlags.TypeParameter) { + while (constraint && constraint.flags & ts.TypeFlags.TypeParameter) { if (result = isRelatedTo(constraint, target, RecursionFlags.Source, /*reportErrors*/ false)) { return result; } constraint = getConstraintOfTypeParameter(constraint); } } - return Ternary.False; + return ts.Ternary.False; } } - else if (targetFlags & TypeFlags.Index) { - const targetType = (target as IndexType).type; + else if (targetFlags & ts.TypeFlags.Index) { + const targetType = (target as ts.IndexType).type; // A keyof S is related to a keyof T if T is related to S. - if (sourceFlags & TypeFlags.Index) { - if (result = isRelatedTo(targetType, (source as IndexType).type, RecursionFlags.Both, /*reportErrors*/ false)) { + if (sourceFlags & ts.TypeFlags.Index) { + if (result = isRelatedTo(targetType, (source as ts.IndexType).type, RecursionFlags.Both, /*reportErrors*/ false)) { return result; } } @@ -19388,8 +18859,8 @@ namespace ts { // false positives. For example, given 'T extends { [K in keyof T]: string }', // 'keyof T' has itself as its constraint and produces a Ternary.Maybe when // related to other types. - if (isRelatedTo(source, getIndexType(constraint, (target as IndexType).stringsOnly), RecursionFlags.Target, reportErrors) === Ternary.True) { - return Ternary.True; + if (isRelatedTo(source, getIndexType(constraint, (target as ts.IndexType).stringsOnly), RecursionFlags.Target, reportErrors) === ts.Ternary.True) { + return ts.Ternary.True; } } else if (isGenericMappedType(targetType)) { @@ -19404,31 +18875,27 @@ namespace ts { // we need to get the apparent mappings and union them with the generic mappings, since some properties may be // missing from the `constraintType` which will otherwise be mapped in the object const modifiersType = getApparentType(getModifiersTypeFromMappedType(targetType)); - const mappedKeys: Type[] = []; - forEachMappedTypePropertyKeyTypeAndIndexSignatureKeyType( - modifiersType, - TypeFlags.StringOrNumberLiteralOrUnique, - /*stringsOnly*/ false, - t => void mappedKeys.push(instantiateType(nameType, appendTypeMapping(targetType.mapper, getTypeParameterFromMappedType(targetType), t))) - ); + const mappedKeys: ts.Type[] = []; + forEachMappedTypePropertyKeyTypeAndIndexSignatureKeyType(modifiersType, ts.TypeFlags.StringOrNumberLiteralOrUnique, + /*stringsOnly*/ false, t => void mappedKeys.push(instantiateType(nameType, appendTypeMapping(targetType.mapper, getTypeParameterFromMappedType(targetType), t)))); // We still need to include the non-apparent (and thus still generic) keys in the target side of the comparison (in case they're in the source side) targetKeys = getUnionType([...mappedKeys, nameType]); } else { targetKeys = nameType || constraintType; } - if (isRelatedTo(source, targetKeys, RecursionFlags.Target, reportErrors) === Ternary.True) { - return Ternary.True; + if (isRelatedTo(source, targetKeys, RecursionFlags.Target, reportErrors) === ts.Ternary.True) { + return ts.Ternary.True; } } } } - else if (targetFlags & TypeFlags.IndexedAccess) { - if (sourceFlags & TypeFlags.IndexedAccess) { + else if (targetFlags & ts.TypeFlags.IndexedAccess) { + if (sourceFlags & ts.TypeFlags.IndexedAccess) { // Relate components directly before falling back to constraint relationships // A type S[K] is related to a type T[J] if S is related to T and K is related to J. - if (result = isRelatedTo((source as IndexedAccessType).objectType, (target as IndexedAccessType).objectType, RecursionFlags.Both, reportErrors)) { - result &= isRelatedTo((source as IndexedAccessType).indexType, (target as IndexedAccessType).indexType, RecursionFlags.Both, reportErrors); + if (result = isRelatedTo((source as ts.IndexedAccessType).objectType, (target as ts.IndexedAccessType).objectType, RecursionFlags.Both, reportErrors)) { + result &= isRelatedTo((source as ts.IndexedAccessType).indexType, (target as ts.IndexedAccessType).indexType, RecursionFlags.Both, reportErrors); } if (result) { resetErrorInfo(saveErrorInfo); @@ -19441,12 +18908,12 @@ namespace ts { // A type S is related to a type T[K] if S is related to C, where C is the base // constraint of T[K] for writing. if (relation === assignableRelation || relation === comparableRelation) { - const objectType = (target as IndexedAccessType).objectType; - const indexType = (target as IndexedAccessType).indexType; + const objectType = (target as ts.IndexedAccessType).objectType; + const indexType = (target as ts.IndexedAccessType).indexType; const baseObjectType = getBaseConstraintOfType(objectType) || objectType; const baseIndexType = getBaseConstraintOfType(indexType) || indexType; if (!isGenericObjectType(baseObjectType) && !isGenericIndexType(baseIndexType)) { - const accessFlags = AccessFlags.Writing | (baseObjectType !== objectType ? AccessFlags.NoIndexSignatures : 0); + const accessFlags = ts.AccessFlags.Writing | (baseObjectType !== objectType ? ts.AccessFlags.NoIndexSignatures : 0); const constraint = getIndexedAccessTypeOrUndefined(baseObjectType, baseIndexType, accessFlags); if (constraint) { if (reportErrors && originalErrorInfo) { @@ -19475,9 +18942,9 @@ namespace ts { if (!(modifiers & MappedTypeModifiers.ExcludeOptional)) { // If the mapped type has shape `{ [P in Q]: T[P] }`, // source `S` is related to target if `T` = `S`, i.e. `S` is related to `{ [P in Q]: S[P] }`. - if (!keysRemapped && templateType.flags & TypeFlags.IndexedAccess && (templateType as IndexedAccessType).objectType === source && - (templateType as IndexedAccessType).indexType === getTypeParameterFromMappedType(target)) { - return Ternary.True; + if (!keysRemapped && templateType.flags & ts.TypeFlags.IndexedAccess && (templateType as ts.IndexedAccessType).objectType === source && + (templateType as ts.IndexedAccessType).indexType === getTypeParameterFromMappedType(target)) { + return ts.Ternary.True; } if (!isGenericMappedType(source)) { // If target has shape `{ [P in Q as R]: T}`, then its keys have type `R`. @@ -19492,16 +18959,16 @@ namespace ts { // A source type `S` is related to a target type `{ [P in Q]?: T }` if some constituent `Q'` of `Q` is related to `keyof S` and `S[Q']` is related to `T`. // A source type `S` is related to a target type `{ [P in Q as R]?: T }` if some constituent `R'` of `R` is related to `keyof S` and `S[R']` is related to `T`. if (includeOptional - ? !(filteredByApplicability!.flags & TypeFlags.Never) + ? !(filteredByApplicability!.flags & ts.TypeFlags.Never) : isRelatedTo(targetKeys, sourceKeys, RecursionFlags.Both)) { const templateType = getTemplateTypeFromMappedType(target); const typeParameter = getTypeParameterFromMappedType(target); // Fastpath: When the template type has the form `Obj[P]` where `P` is the mapped type parameter, directly compare source `S` with `Obj` // to avoid creating the (potentially very large) number of new intermediate types made by manufacturing `S[P]`. - const nonNullComponent = extractTypesOfKind(templateType, ~TypeFlags.Nullable); - if (!keysRemapped && nonNullComponent.flags & TypeFlags.IndexedAccess && (nonNullComponent as IndexedAccessType).indexType === typeParameter) { - if (result = isRelatedTo(source, (nonNullComponent as IndexedAccessType).objectType, RecursionFlags.Target, reportErrors)) { + const nonNullComponent = extractTypesOfKind(templateType, ~ts.TypeFlags.Nullable); + if (!keysRemapped && nonNullComponent.flags & ts.TypeFlags.IndexedAccess && (nonNullComponent as ts.IndexedAccessType).indexType === typeParameter) { + if (result = isRelatedTo(source, (nonNullComponent as ts.IndexedAccessType).objectType, RecursionFlags.Target, reportErrors)) { return result; } } @@ -19532,14 +18999,14 @@ namespace ts { } } } - else if (targetFlags & TypeFlags.Conditional) { + else if (targetFlags & ts.TypeFlags.Conditional) { // If we reach 10 levels of nesting for the same conditional type, assume it is an infinitely expanding recursive // conditional type and bail out with a Ternary.Maybe result. if (isDeeplyNestedType(target, targetStack, targetDepth, 10)) { resetErrorInfo(saveErrorInfo); - return Ternary.Maybe; + return ts.Ternary.Maybe; } - const c = target as ConditionalType; + const c = target as ts.ConditionalType; // We check for a relationship to a conditional type target only when the conditional type has no // 'infer' positions and is not distributive or is distributive but doesn't reference the check type // parameter in either of the result types. @@ -19548,8 +19015,8 @@ namespace ts { const skipTrue = !isTypeAssignableTo(getPermissiveInstantiation(c.checkType), getPermissiveInstantiation(c.extendsType)); const skipFalse = !skipTrue && isTypeAssignableTo(getRestrictiveInstantiation(c.checkType), getRestrictiveInstantiation(c.extendsType)); // TODO: Find a nice way to include potential conditional type breakdowns in error output, if they seem good (they usually don't) - if (result = skipTrue ? Ternary.True : isRelatedTo(source, getTrueTypeFromConditionalType(c), RecursionFlags.Target, /*reportErrors*/ false)) { - result &= skipFalse ? Ternary.True : isRelatedTo(source, getFalseTypeFromConditionalType(c), RecursionFlags.Target, /*reportErrors*/ false); + if (result = skipTrue ? ts.Ternary.True : isRelatedTo(source, getTrueTypeFromConditionalType(c), RecursionFlags.Target, /*reportErrors*/ false)) { + result &= skipFalse ? ts.Ternary.True : isRelatedTo(source, getFalseTypeFromConditionalType(c), RecursionFlags.Target, /*reportErrors*/ false); if (result) { resetErrorInfo(saveErrorInfo); return result; @@ -19557,27 +19024,27 @@ namespace ts { } } } - else if (targetFlags & TypeFlags.TemplateLiteral) { - if (sourceFlags & TypeFlags.TemplateLiteral) { + else if (targetFlags & ts.TypeFlags.TemplateLiteral) { + if (sourceFlags & ts.TypeFlags.TemplateLiteral) { if (relation === comparableRelation) { - return templateLiteralTypesDefinitelyUnrelated(source as TemplateLiteralType, target as TemplateLiteralType) ? Ternary.False : Ternary.True; + return templateLiteralTypesDefinitelyUnrelated(source as ts.TemplateLiteralType, target as ts.TemplateLiteralType) ? ts.Ternary.False : ts.Ternary.True; } // Report unreliable variance for type variables referenced in template literal type placeholders. // For example, `foo-${number}` is related to `foo-${string}` even though number isn't related to string. instantiateType(source, makeFunctionTypeMapper(reportUnreliableMarkers)); } - if (isTypeMatchedByTemplateLiteralType(source, target as TemplateLiteralType)) { - return Ternary.True; + if (isTypeMatchedByTemplateLiteralType(source, target as ts.TemplateLiteralType)) { + return ts.Ternary.True; } } - if (sourceFlags & TypeFlags.TypeVariable) { + if (sourceFlags & ts.TypeFlags.TypeVariable) { // IndexedAccess comparisons are handled above in the `targetFlags & TypeFlage.IndexedAccess` branch - if (!(sourceFlags & TypeFlags.IndexedAccess && targetFlags & TypeFlags.IndexedAccess)) { - const constraint = getConstraintOfType(source as TypeVariable) || unknownType; - if (!getConstraintOfType(source as TypeVariable) || (sourceFlags & TypeFlags.TypeParameter && constraint.flags & TypeFlags.Any)) { + if (!(sourceFlags & ts.TypeFlags.IndexedAccess && targetFlags & ts.TypeFlags.IndexedAccess)) { + const constraint = getConstraintOfType(source as ts.TypeVariable) || unknownType; + if (!getConstraintOfType(source as ts.TypeVariable) || (sourceFlags & ts.TypeFlags.TypeParameter && constraint.flags & ts.TypeFlags.Any)) { // A type variable with no constraint is not related to the non-primitive object type. - if (result = isRelatedTo(emptyObjectType, extractTypesOfKind(target, ~TypeFlags.NonPrimitive), RecursionFlags.Both)) { + if (result = isRelatedTo(emptyObjectType, extractTypesOfKind(target, ~ts.TypeFlags.NonPrimitive), RecursionFlags.Both)) { resetErrorInfo(saveErrorInfo); return result; } @@ -19588,16 +19055,16 @@ namespace ts { return result; } // slower, fuller, this-instantiated check (necessary when comparing raw `this` types from base classes), see `subclassWithPolymorphicThisIsAssignable.ts` test for example - else if (result = isRelatedTo(getTypeWithThisArgument(constraint, source), target, RecursionFlags.Source, reportErrors && constraint !== unknownType && !(targetFlags & sourceFlags & TypeFlags.TypeParameter), /*headMessage*/ undefined, intersectionState)) { + else if (result = isRelatedTo(getTypeWithThisArgument(constraint, source), target, RecursionFlags.Source, reportErrors && constraint !== unknownType && !(targetFlags & sourceFlags & ts.TypeFlags.TypeParameter), /*headMessage*/ undefined, intersectionState)) { resetErrorInfo(saveErrorInfo); return result; } if (isMappedTypeGenericIndexedAccess(source)) { // For an indexed access type { [P in K]: E}[X], above we have already explored an instantiation of E with X // substituted for P. We also want to explore type { [P in K]: E }[C], where C is the constraint of X. - const indexConstraint = getConstraintOfType((source as IndexedAccessType).indexType); + const indexConstraint = getConstraintOfType((source as ts.IndexedAccessType).indexType); if (indexConstraint) { - if (result = isRelatedTo(getIndexedAccessType((source as IndexedAccessType).objectType, indexConstraint), target, RecursionFlags.Source, reportErrors)) { + if (result = isRelatedTo(getIndexedAccessType((source as ts.IndexedAccessType).objectType, indexConstraint), target, RecursionFlags.Source, reportErrors)) { resetErrorInfo(saveErrorInfo); return result; } @@ -19605,14 +19072,14 @@ namespace ts { } } } - else if (sourceFlags & TypeFlags.Index) { + else if (sourceFlags & ts.TypeFlags.Index) { if (result = isRelatedTo(keyofConstraintType, target, RecursionFlags.Source, reportErrors)) { resetErrorInfo(saveErrorInfo); return result; } } - else if (sourceFlags & TypeFlags.TemplateLiteral && !(targetFlags & TypeFlags.Object)) { - if (!(targetFlags & TypeFlags.TemplateLiteral)) { + else if (sourceFlags & ts.TypeFlags.TemplateLiteral && !(targetFlags & ts.TypeFlags.Object)) { + if (!(targetFlags & ts.TypeFlags.TemplateLiteral)) { const constraint = getBaseConstraintOfType(source); if (constraint && constraint !== source && (result = isRelatedTo(constraint, target, RecursionFlags.Source, reportErrors))) { resetErrorInfo(saveErrorInfo); @@ -19620,9 +19087,9 @@ namespace ts { } } } - else if (sourceFlags & TypeFlags.StringMapping) { - if (targetFlags & TypeFlags.StringMapping && (source as StringMappingType).symbol === (target as StringMappingType).symbol) { - if (result = isRelatedTo((source as StringMappingType).type, (target as StringMappingType).type, RecursionFlags.Both, reportErrors)) { + else if (sourceFlags & ts.TypeFlags.StringMapping) { + if (targetFlags & ts.TypeFlags.StringMapping && (source as ts.StringMappingType).symbol === (target as ts.StringMappingType).symbol) { + if (result = isRelatedTo((source as ts.StringMappingType).type, (target as ts.StringMappingType).type, RecursionFlags.Both, reportErrors)) { resetErrorInfo(saveErrorInfo); return result; } @@ -19635,31 +19102,31 @@ namespace ts { } } } - else if (sourceFlags & TypeFlags.Conditional) { + else if (sourceFlags & ts.TypeFlags.Conditional) { // If we reach 10 levels of nesting for the same conditional type, assume it is an infinitely expanding recursive // conditional type and bail out with a Ternary.Maybe result. if (isDeeplyNestedType(source, sourceStack, sourceDepth, 10)) { resetErrorInfo(saveErrorInfo); - return Ternary.Maybe; + return ts.Ternary.Maybe; } - if (targetFlags & TypeFlags.Conditional) { + if (targetFlags & ts.TypeFlags.Conditional) { // Two conditional types 'T1 extends U1 ? X1 : Y1' and 'T2 extends U2 ? X2 : Y2' are related if // one of T1 and T2 is related to the other, U1 and U2 are identical types, X1 is related to X2, // and Y1 is related to Y2. - const sourceParams = (source as ConditionalType).root.inferTypeParameters; - let sourceExtends = (source as ConditionalType).extendsType; - let mapper: TypeMapper | undefined; + const sourceParams = (source as ts.ConditionalType).root.inferTypeParameters; + let sourceExtends = (source as ts.ConditionalType).extendsType; + let mapper: ts.TypeMapper | undefined; if (sourceParams) { // If the source has infer type parameters, we instantiate them in the context of the target - const ctx = createInferenceContext(sourceParams, /*signature*/ undefined, InferenceFlags.None, isRelatedToWorker); - inferTypes(ctx.inferences, (target as ConditionalType).extendsType, sourceExtends, InferencePriority.NoConstraints | InferencePriority.AlwaysStrict); + const ctx = createInferenceContext(sourceParams, /*signature*/ undefined, ts.InferenceFlags.None, isRelatedToWorker); + inferTypes(ctx.inferences, (target as ts.ConditionalType).extendsType, sourceExtends, ts.InferencePriority.NoConstraints | ts.InferencePriority.AlwaysStrict); sourceExtends = instantiateType(sourceExtends, ctx.mapper); mapper = ctx.mapper; } - if (isTypeIdenticalTo(sourceExtends, (target as ConditionalType).extendsType) && - (isRelatedTo((source as ConditionalType).checkType, (target as ConditionalType).checkType, RecursionFlags.Both) || isRelatedTo((target as ConditionalType).checkType, (source as ConditionalType).checkType, RecursionFlags.Both))) { - if (result = isRelatedTo(instantiateType(getTrueTypeFromConditionalType(source as ConditionalType), mapper), getTrueTypeFromConditionalType(target as ConditionalType), RecursionFlags.Both, reportErrors)) { - result &= isRelatedTo(getFalseTypeFromConditionalType(source as ConditionalType), getFalseTypeFromConditionalType(target as ConditionalType), RecursionFlags.Both, reportErrors); + if (isTypeIdenticalTo(sourceExtends, (target as ts.ConditionalType).extendsType) && + (isRelatedTo((source as ts.ConditionalType).checkType, (target as ts.ConditionalType).checkType, RecursionFlags.Both) || isRelatedTo((target as ts.ConditionalType).checkType, (source as ts.ConditionalType).checkType, RecursionFlags.Both))) { + if (result = isRelatedTo(instantiateType(getTrueTypeFromConditionalType(source as ts.ConditionalType), mapper), getTrueTypeFromConditionalType(target as ts.ConditionalType), RecursionFlags.Both, reportErrors)) { + result &= isRelatedTo(getFalseTypeFromConditionalType(source as ts.ConditionalType), getFalseTypeFromConditionalType(target as ts.ConditionalType), RecursionFlags.Both, reportErrors); } if (result) { resetErrorInfo(saveErrorInfo); @@ -19670,7 +19137,7 @@ namespace ts { else { // conditionals aren't related to one another via distributive constraint as it is much too inaccurate and allows way // more assignments than are desirable (since it maps the source check type to its constraint, it loses information) - const distributiveConstraint = hasNonCircularBaseConstraint(source) ? getConstraintOfDistributiveConditionalType(source as ConditionalType) : undefined; + const distributiveConstraint = hasNonCircularBaseConstraint(source) ? getConstraintOfDistributiveConditionalType(source as ts.ConditionalType) : undefined; if (distributiveConstraint) { if (result = isRelatedTo(distributiveConstraint, target, RecursionFlags.Source, reportErrors)) { resetErrorInfo(saveErrorInfo); @@ -19681,7 +19148,7 @@ namespace ts { // conditionals _can_ be related to one another via normal constraint, as, eg, `A extends B ? O : never` should be assignable to `O` // when `O` is a conditional (`never` is trivially assignable to `O`, as is `O`!). - const defaultConstraint = getDefaultConstraintOfConditionalType(source as ConditionalType); + const defaultConstraint = getDefaultConstraintOfConditionalType(source as ts.ConditionalType); if (defaultConstraint) { if (result = isRelatedTo(defaultConstraint, target, RecursionFlags.Source, reportErrors)) { resetErrorInfo(saveErrorInfo); @@ -19692,7 +19159,7 @@ namespace ts { else { // An empty object type is related to any mapped type that includes a '?' modifier. if (relation !== subtypeRelation && relation !== strictSubtypeRelation && isPartialMappedType(target) && isEmptyObjectType(source)) { - return Ternary.True; + return ts.Ternary.True; } if (isGenericMappedType(target)) { if (isGenericMappedType(source)) { @@ -19701,34 +19168,34 @@ namespace ts { return result; } } - return Ternary.False; + return ts.Ternary.False; } - const sourceIsPrimitive = !!(sourceFlags & TypeFlags.Primitive); + const sourceIsPrimitive = !!(sourceFlags & ts.TypeFlags.Primitive); if (relation !== identityRelation) { source = getApparentType(source); sourceFlags = source.flags; } else if (isGenericMappedType(source)) { - return Ternary.False; + return ts.Ternary.False; } - if (getObjectFlags(source) & ObjectFlags.Reference && getObjectFlags(target) & ObjectFlags.Reference && (source as TypeReference).target === (target as TypeReference).target && + if (ts.getObjectFlags(source) & ts.ObjectFlags.Reference && ts.getObjectFlags(target) & ts.ObjectFlags.Reference && (source as ts.TypeReference).target === (target as ts.TypeReference).target && !isTupleType(source) && !(isMarkerType(source) || isMarkerType(target))) { // When strictNullChecks is disabled, the element type of the empty array literal is undefinedWideningType, // and an empty array literal wouldn't be assignable to a `never[]` without this check. if (isEmptyArrayLiteralType(source)) { - return Ternary.True; + return ts.Ternary.True; } // We have type references to the same generic type, and the type references are not marker // type references (which are intended by be compared structurally). Obtain the variance // information for the type parameters and relate the type arguments accordingly. - const variances = getVariances((source as TypeReference).target); + const variances = getVariances((source as ts.TypeReference).target); // We return Ternary.Maybe for a recursive invocation of getVariances (signalled by emptyArray). This // effectively means we measure variance only from type parameter occurrences that aren't nested in // recursive instantiations of the generic type. - if (variances === emptyArray) { - return Ternary.Unknown; + if (variances === ts.emptyArray) { + return ts.Ternary.Unknown; } - const varianceResult = relateVariances(getTypeArguments(source as TypeReference), getTypeArguments(target as TypeReference), variances, intersectionState); + const varianceResult = relateVariances(getTypeArguments(source as ts.TypeReference), getTypeArguments(target as ts.TypeReference), variances, intersectionState); if (varianceResult !== undefined) { return varianceResult; } @@ -19740,27 +19207,27 @@ namespace ts { else { // By flags alone, we know that the `target` is a readonly array while the source is a normal array or tuple // or `target` is an array and source is a tuple - in both cases the types cannot be identical, by construction - return Ternary.False; + return ts.Ternary.False; } } // Consider a fresh empty object literal type "closed" under the subtype relationship - this way `{} <- {[idx: string]: any} <- fresh({})` // and not `{} <- fresh({}) <- {[idx: string]: any}` - else if ((relation === subtypeRelation || relation === strictSubtypeRelation) && isEmptyObjectType(target) && getObjectFlags(target) & ObjectFlags.FreshLiteral && !isEmptyObjectType(source)) { - return Ternary.False; + else if ((relation === subtypeRelation || relation === strictSubtypeRelation) && isEmptyObjectType(target) && ts.getObjectFlags(target) & ts.ObjectFlags.FreshLiteral && !isEmptyObjectType(source)) { + return ts.Ternary.False; } // Even if relationship doesn't hold for unions, intersections, or generic type references, // it may hold in a structural comparison. // In a check of the form X = A & B, we will have previously checked if A relates to X or B relates // to X. Failing both of those we want to check if the aggregation of A and B's members structurally // relates to X. Thus, we include intersection types on the source side here. - if (sourceFlags & (TypeFlags.Object | TypeFlags.Intersection) && targetFlags & TypeFlags.Object) { + if (sourceFlags & (ts.TypeFlags.Object | ts.TypeFlags.Intersection) && targetFlags & ts.TypeFlags.Object) { // Report structural errors only if we haven't reported any errors yet const reportStructuralErrors = reportErrors && errorInfo === saveErrorInfo.errorInfo && !sourceIsPrimitive; result = propertiesRelatedTo(source, target, reportStructuralErrors, /*excludedProperties*/ undefined, intersectionState); if (result) { - result &= signaturesRelatedTo(source, target, SignatureKind.Call, reportStructuralErrors); + result &= signaturesRelatedTo(source, target, ts.SignatureKind.Call, reportStructuralErrors); if (result) { - result &= signaturesRelatedTo(source, target, SignatureKind.Construct, reportStructuralErrors); + result &= signaturesRelatedTo(source, target, ts.SignatureKind.Construct, reportStructuralErrors); if (result) { result &= indexSignaturesRelatedTo(source, target, sourceIsPrimitive, reportStructuralErrors, intersectionState); } @@ -19777,28 +19244,28 @@ namespace ts { // there exists a constituent of T for every combination of the discriminants of S // with respect to T. We do not report errors here, as we will use the existing // error result from checking each constituent of the union. - if (sourceFlags & (TypeFlags.Object | TypeFlags.Intersection) && targetFlags & TypeFlags.Union) { - const objectOnlyTarget = extractTypesOfKind(target, TypeFlags.Object | TypeFlags.Intersection | TypeFlags.Substitution); - if (objectOnlyTarget.flags & TypeFlags.Union) { - const result = typeRelatedToDiscriminatedType(source, objectOnlyTarget as UnionType); + if (sourceFlags & (ts.TypeFlags.Object | ts.TypeFlags.Intersection) && targetFlags & ts.TypeFlags.Union) { + const objectOnlyTarget = extractTypesOfKind(target, ts.TypeFlags.Object | ts.TypeFlags.Intersection | ts.TypeFlags.Substitution); + if (objectOnlyTarget.flags & ts.TypeFlags.Union) { + const result = typeRelatedToDiscriminatedType(source, objectOnlyTarget as ts.UnionType); if (result) { return result; } } } } - return Ternary.False; - - function countMessageChainBreadth(info: DiagnosticMessageChain[] | undefined): number { - if (!info) return 0; - return reduceLeft(info, (value, chain) => value + 1 + countMessageChainBreadth(chain.next), 0); + return ts.Ternary.False; + function countMessageChainBreadth(info: ts.DiagnosticMessageChain[] | undefined): number { + if (!info) + return 0; + return ts.reduceLeft(info, (value, chain) => value + 1 + countMessageChainBreadth(chain.next), 0); } - function relateVariances(sourceTypeArguments: readonly Type[] | undefined, targetTypeArguments: readonly Type[] | undefined, variances: VarianceFlags[], intersectionState: IntersectionState) { + function relateVariances(sourceTypeArguments: readonly ts.Type[] | undefined, targetTypeArguments: readonly ts.Type[] | undefined, variances: ts.VarianceFlags[], intersectionState: IntersectionState) { if (result = typeArgumentsRelatedTo(sourceTypeArguments, targetTypeArguments, variances, reportErrors, intersectionState)) { return result; } - if (some(variances, v => !!(v & VarianceFlags.AllowsStructuralFallback))) { + if (ts.some(variances, v => !!(v & ts.VarianceFlags.AllowsStructuralFallback))) { // If some type parameter was `Unmeasurable` or `Unreliable`, and we couldn't pass by assuming it was identical, then we // have to allow a structural fallback check // We elide the variance-based error elaborations, since those might not be too helpful, since we'll potentially @@ -19816,7 +19283,7 @@ namespace ts { // (in which case any type argument is permitted on the source side). In those cases we proceed // with a structural comparison. Otherwise, we know for certain the instantiations aren't // related and we can return here. - if (variances !== emptyArray && !allowStructuralFallback) { + if (variances !== ts.emptyArray && !allowStructuralFallback) { // In some cases generic types that are covariant in regular type checking mode become // invariant in --strictFunctionTypes mode because one or more type parameters are used in // both co- and contravariant positions. In order to make it easier to diagnose *why* such @@ -19825,8 +19292,8 @@ namespace ts { // reveal the reason). // We can switch on `reportErrors` here, since varianceCheckFailed guarantees we return `False`, // we can return `False` early here to skip calculating the structural error message we don't need. - if (varianceCheckFailed && !(reportErrors && some(variances, v => (v & VarianceFlags.VarianceMask) === VarianceFlags.Invariant))) { - return Ternary.False; + if (varianceCheckFailed && !(reportErrors && ts.some(variances, v => (v & ts.VarianceFlags.VarianceMask) === ts.VarianceFlags.Invariant))) { + return ts.Ternary.False; } // We remember the original error information so we can restore it in case the structural // comparison unexpectedly succeeds. This can happen when the structural comparison result @@ -19837,14 +19304,14 @@ namespace ts { } } - function reportUnmeasurableMarkers(p: TypeParameter) { + function reportUnmeasurableMarkers(p: ts.TypeParameter) { if (outofbandVarianceMarkerHandler && (p === markerSuperType || p === markerSubType || p === markerOtherType)) { outofbandVarianceMarkerHandler(/*onlyUnreliable*/ false); } return p; } - function reportUnreliableMarkers(p: TypeParameter) { + function reportUnreliableMarkers(p: ts.TypeParameter) { if (outofbandVarianceMarkerHandler && (p === markerSuperType || p === markerSubType || p === markerOtherType)) { outofbandVarianceMarkerHandler(/*onlyUnreliable*/ true); } @@ -19854,11 +19321,11 @@ namespace ts { // A type [P in S]: X is related to a type [Q in T]: Y if T is related to S and X' is // related to Y, where X' is an instantiation of X in which P is replaced with Q. Notice // that S and T are contra-variant whereas X and Y are co-variant. - function mappedTypeRelatedTo(source: MappedType, target: MappedType, reportErrors: boolean): Ternary { + function mappedTypeRelatedTo(source: ts.MappedType, target: ts.MappedType, reportErrors: boolean): ts.Ternary { const modifiersRelated = relation === comparableRelation || (relation === identityRelation ? getMappedTypeModifiers(source) === getMappedTypeModifiers(target) : getCombinedMappedTypeOptionality(source) <= getCombinedMappedTypeOptionality(target)); if (modifiersRelated) { - let result: Ternary; + let result: ts.Ternary; const targetConstraint = getConstraintTypeFromMappedType(target); const sourceConstraint = instantiateType(getConstraintTypeFromMappedType(source), makeFunctionTypeMapper(getCombinedMappedTypeOptionality(source) < 0 ? reportUnmeasurableMarkers : reportUnreliableMarkers)); if (result = isRelatedTo(targetConstraint, sourceConstraint, RecursionFlags.Both, reportErrors)) { @@ -19868,10 +19335,10 @@ namespace ts { } } } - return Ternary.False; + return ts.Ternary.False; } - function typeRelatedToDiscriminatedType(source: Type, target: UnionType) { + function typeRelatedToDiscriminatedType(source: ts.Type, target: ts.UnionType) { // 1. Generate the combinations of discriminant properties & types 'source' can satisfy. // a. If the number of combinations is above a set limit, the comparison is too complex. // 2. Filter 'target' to the subset of types whose discriminants exist in the matrix. @@ -19884,7 +19351,8 @@ namespace ts { const sourceProperties = getPropertiesOfType(source); const sourcePropertiesFiltered = findDiscriminantProperties(sourceProperties, target); - if (!sourcePropertiesFiltered) return Ternary.False; + if (!sourcePropertiesFiltered) + return ts.Ternary.False; // Though we could compute the number of combinations as we generate // the matrix, this would incur additional memory overhead due to @@ -19896,35 +19364,37 @@ namespace ts { numCombinations *= countTypes(getNonMissingTypeOfSymbol(sourceProperty)); if (numCombinations > 25) { // We've reached the complexity limit. - tracing?.instant(tracing.Phase.CheckTypes, "typeRelatedToDiscriminatedType_DepthLimit", { sourceId: source.id, targetId: target.id, numCombinations }); - return Ternary.False; + ts.tracing?.instant(ts.tracing.Phase.CheckTypes, "typeRelatedToDiscriminatedType_DepthLimit", { sourceId: source.id, targetId: target.id, numCombinations }); + return ts.Ternary.False; } } // Compute the set of types for each discriminant property. - const sourceDiscriminantTypes: Type[][] = new Array(sourcePropertiesFiltered.length); - const excludedProperties = new Set<__String>(); + const sourceDiscriminantTypes: ts.Type[][] = new Array(sourcePropertiesFiltered.length); + const excludedProperties = new ts.Set(); for (let i = 0; i < sourcePropertiesFiltered.length; i++) { const sourceProperty = sourcePropertiesFiltered[i]; const sourcePropertyType = getNonMissingTypeOfSymbol(sourceProperty); - sourceDiscriminantTypes[i] = sourcePropertyType.flags & TypeFlags.Union - ? (sourcePropertyType as UnionType).types + sourceDiscriminantTypes[i] = sourcePropertyType.flags & ts.TypeFlags.Union + ? (sourcePropertyType as ts.UnionType).types : [sourcePropertyType]; excludedProperties.add(sourceProperty.escapedName); } // Match each combination of the cartesian product of discriminant properties to one or more // constituents of 'target'. If any combination does not have a match then 'source' is not relatable. - const discriminantCombinations = cartesianProduct(sourceDiscriminantTypes); - const matchingTypes: Type[] = []; + const discriminantCombinations = ts.cartesianProduct(sourceDiscriminantTypes); + const matchingTypes: ts.Type[] = []; for (const combination of discriminantCombinations) { let hasMatch = false; outer: for (const type of target.types) { for (let i = 0; i < sourcePropertiesFiltered.length; i++) { const sourceProperty = sourcePropertiesFiltered[i]; const targetProperty = getPropertyOfType(type, sourceProperty.escapedName); - if (!targetProperty) continue outer; - if (sourceProperty === targetProperty) continue; + if (!targetProperty) + continue outer; + if (sourceProperty === targetProperty) + continue; // We compare the source property to the target in the context of a single discriminant type. const related = propertyRelatedTo(source, target, sourceProperty, targetProperty, _ => combination[i], /*reportErrors*/ false, IntersectionState.None, /*skipOptional*/ strictNullChecks || relation === comparableRelation); // If the target property could not be found, or if the properties were not related, @@ -19933,23 +19403,23 @@ namespace ts { continue outer; } } - pushIfUnique(matchingTypes, type, equateValues); + ts.pushIfUnique(matchingTypes, type, ts.equateValues); hasMatch = true; } if (!hasMatch) { // We failed to match any type for this combination. - return Ternary.False; + return ts.Ternary.False; } } // Compare the remaining non-discriminant properties of each match. - let result = Ternary.True; + let result = ts.Ternary.True; for (const type of matchingTypes) { result &= propertiesRelatedTo(source, type, /*reportErrors*/ false, excludedProperties, IntersectionState.None); if (result) { - result &= signaturesRelatedTo(source, type, SignatureKind.Call, /*reportStructuralErrors*/ false); + result &= signaturesRelatedTo(source, type, ts.SignatureKind.Call, /*reportStructuralErrors*/ false); if (result) { - result &= signaturesRelatedTo(source, type, SignatureKind.Construct, /*reportStructuralErrors*/ false); + result &= signaturesRelatedTo(source, type, ts.SignatureKind.Construct, /*reportStructuralErrors*/ false); if (result && !(isTupleType(source) && isTupleType(type))) { // Comparing numeric index types when both `source` and `type` are tuples is unnecessary as the // element types should be sufficiently covered by `propertiesRelatedTo`. It also causes problems @@ -19966,9 +19436,10 @@ namespace ts { return result; } - function excludeProperties(properties: Symbol[], excludedProperties: Set<__String> | undefined) { - if (!excludedProperties || properties.length === 0) return properties; - let result: Symbol[] | undefined; + function excludeProperties(properties: ts.Symbol[], excludedProperties: ts.Set | undefined) { + if (!excludedProperties || properties.length === 0) + return properties; + let result: ts.Symbol[] | undefined; for (let i = 0; i < properties.length; i++) { if (!excludedProperties.has(properties[i].escapedName)) { if (result) { @@ -19982,46 +19453,42 @@ namespace ts { return result || properties; } - function isPropertySymbolTypeRelated(sourceProp: Symbol, targetProp: Symbol, getTypeOfSourceProperty: (sym: Symbol) => Type, reportErrors: boolean, intersectionState: IntersectionState): Ternary { - const targetIsOptional = strictNullChecks && !!(getCheckFlags(targetProp) & CheckFlags.Partial); + function isPropertySymbolTypeRelated(sourceProp: ts.Symbol, targetProp: ts.Symbol, getTypeOfSourceProperty: (sym: ts.Symbol) => ts.Type, reportErrors: boolean, intersectionState: IntersectionState): ts.Ternary { + const targetIsOptional = strictNullChecks && !!(ts.getCheckFlags(targetProp) & ts.CheckFlags.Partial); const effectiveTarget = addOptionality(getNonMissingTypeOfSymbol(targetProp), /*isProperty*/ false, targetIsOptional); const effectiveSource = getTypeOfSourceProperty(sourceProp); return isRelatedTo(effectiveSource, effectiveTarget, RecursionFlags.Both, reportErrors, /*headMessage*/ undefined, intersectionState); } - function propertyRelatedTo(source: Type, target: Type, sourceProp: Symbol, targetProp: Symbol, getTypeOfSourceProperty: (sym: Symbol) => Type, reportErrors: boolean, intersectionState: IntersectionState, skipOptional: boolean): Ternary { - const sourcePropFlags = getDeclarationModifierFlagsFromSymbol(sourceProp); - const targetPropFlags = getDeclarationModifierFlagsFromSymbol(targetProp); - if (sourcePropFlags & ModifierFlags.Private || targetPropFlags & ModifierFlags.Private) { + function propertyRelatedTo(source: ts.Type, target: ts.Type, sourceProp: ts.Symbol, targetProp: ts.Symbol, getTypeOfSourceProperty: (sym: ts.Symbol) => ts.Type, reportErrors: boolean, intersectionState: IntersectionState, skipOptional: boolean): ts.Ternary { + const sourcePropFlags = ts.getDeclarationModifierFlagsFromSymbol(sourceProp); + const targetPropFlags = ts.getDeclarationModifierFlagsFromSymbol(targetProp); + if (sourcePropFlags & ts.ModifierFlags.Private || targetPropFlags & ts.ModifierFlags.Private) { if (sourceProp.valueDeclaration !== targetProp.valueDeclaration) { if (reportErrors) { - if (sourcePropFlags & ModifierFlags.Private && targetPropFlags & ModifierFlags.Private) { - reportError(Diagnostics.Types_have_separate_declarations_of_a_private_property_0, symbolToString(targetProp)); + if (sourcePropFlags & ts.ModifierFlags.Private && targetPropFlags & ts.ModifierFlags.Private) { + reportError(ts.Diagnostics.Types_have_separate_declarations_of_a_private_property_0, symbolToString(targetProp)); } else { - reportError(Diagnostics.Property_0_is_private_in_type_1_but_not_in_type_2, symbolToString(targetProp), - typeToString(sourcePropFlags & ModifierFlags.Private ? source : target), - typeToString(sourcePropFlags & ModifierFlags.Private ? target : source)); + reportError(ts.Diagnostics.Property_0_is_private_in_type_1_but_not_in_type_2, symbolToString(targetProp), typeToString(sourcePropFlags & ts.ModifierFlags.Private ? source : target), typeToString(sourcePropFlags & ts.ModifierFlags.Private ? target : source)); } } - return Ternary.False; + return ts.Ternary.False; } } - else if (targetPropFlags & ModifierFlags.Protected) { + else if (targetPropFlags & ts.ModifierFlags.Protected) { if (!isValidOverrideOf(sourceProp, targetProp)) { if (reportErrors) { - reportError(Diagnostics.Property_0_is_protected_but_type_1_is_not_a_class_derived_from_2, symbolToString(targetProp), - typeToString(getDeclaringClass(sourceProp) || source), typeToString(getDeclaringClass(targetProp) || target)); + reportError(ts.Diagnostics.Property_0_is_protected_but_type_1_is_not_a_class_derived_from_2, symbolToString(targetProp), typeToString(getDeclaringClass(sourceProp) || source), typeToString(getDeclaringClass(targetProp) || target)); } - return Ternary.False; + return ts.Ternary.False; } } - else if (sourcePropFlags & ModifierFlags.Protected) { + else if (sourcePropFlags & ts.ModifierFlags.Protected) { if (reportErrors) { - reportError(Diagnostics.Property_0_is_protected_in_type_1_but_public_in_type_2, - symbolToString(targetProp), typeToString(source), typeToString(target)); + reportError(ts.Diagnostics.Property_0_is_protected_in_type_1_but_public_in_type_2, symbolToString(targetProp), typeToString(source), typeToString(target)); } - return Ternary.False; + return ts.Ternary.False; } // Ensure {readonly a: whatever} is not a subtype of {a: whatever}, @@ -20030,22 +19497,20 @@ namespace ts { // from deciding which type "wins" in union subtype reduction. // They're still assignable to one another, since `readonly` doesn't affect assignability. // This is only applied during the strictSubtypeRelation -- currently used in subtype reduction - if ( - relation === strictSubtypeRelation && - isReadonlySymbol(sourceProp) && !isReadonlySymbol(targetProp) - ) { - return Ternary.False; + if (relation === strictSubtypeRelation && + isReadonlySymbol(sourceProp) && !isReadonlySymbol(targetProp)) { + return ts.Ternary.False; } // If the target comes from a partial union prop, allow `undefined` in the target type const related = isPropertySymbolTypeRelated(sourceProp, targetProp, getTypeOfSourceProperty, reportErrors, intersectionState); if (!related) { if (reportErrors) { - reportIncompatibleError(Diagnostics.Types_of_property_0_are_incompatible, symbolToString(targetProp)); + reportIncompatibleError(ts.Diagnostics.Types_of_property_0_are_incompatible, symbolToString(targetProp)); } - return Ternary.False; + return ts.Ternary.False; } // When checking for comparability, be more lenient with optional properties. - if (!skipOptional && sourceProp.flags & SymbolFlags.Optional && !(targetProp.flags & SymbolFlags.Optional)) { + if (!skipOptional && sourceProp.flags & ts.SymbolFlags.Optional && !(targetProp.flags & ts.SymbolFlags.Optional)) { // TypeScript 1.0 spec (April 2014): 3.8.3 // S is a subtype of a type T, and T is a supertype of S if ... // S' and T are object types and, for each member M in T.. @@ -20054,45 +19519,40 @@ namespace ts { // (M - property in T) // (N - property in S) if (reportErrors) { - reportError(Diagnostics.Property_0_is_optional_in_type_1_but_required_in_type_2, - symbolToString(targetProp), typeToString(source), typeToString(target)); + reportError(ts.Diagnostics.Property_0_is_optional_in_type_1_but_required_in_type_2, symbolToString(targetProp), typeToString(source), typeToString(target)); } - return Ternary.False; + return ts.Ternary.False; } return related; } - function reportUnmatchedProperty(source: Type, target: Type, unmatchedProperty: Symbol, requireOptionalProperties: boolean) { + function reportUnmatchedProperty(source: ts.Type, target: ts.Type, unmatchedProperty: ts.Symbol, requireOptionalProperties: boolean) { let shouldSkipElaboration = false; // give specific error in case where private names have the same description if (unmatchedProperty.valueDeclaration - && isNamedDeclaration(unmatchedProperty.valueDeclaration) - && isPrivateIdentifier(unmatchedProperty.valueDeclaration.name) + && ts.isNamedDeclaration(unmatchedProperty.valueDeclaration) + && ts.isPrivateIdentifier(unmatchedProperty.valueDeclaration.name) && source.symbol - && source.symbol.flags & SymbolFlags.Class) { + && source.symbol.flags & ts.SymbolFlags.Class) { const privateIdentifierDescription = unmatchedProperty.valueDeclaration.name.escapedText; - const symbolTableKey = getSymbolNameForPrivateIdentifier(source.symbol, privateIdentifierDescription); + const symbolTableKey = ts.getSymbolNameForPrivateIdentifier(source.symbol, privateIdentifierDescription); if (symbolTableKey && getPropertyOfType(source, symbolTableKey)) { - const sourceName = factory.getDeclarationName(source.symbol.valueDeclaration); - const targetName = factory.getDeclarationName(target.symbol.valueDeclaration); - reportError( - Diagnostics.Property_0_in_type_1_refers_to_a_different_member_that_cannot_be_accessed_from_within_type_2, - diagnosticName(privateIdentifierDescription), - diagnosticName(sourceName.escapedText === "" ? anon : sourceName), - diagnosticName(targetName.escapedText === "" ? anon : targetName)); + const sourceName = ts.factory.getDeclarationName(source.symbol.valueDeclaration); + const targetName = ts.factory.getDeclarationName(target.symbol.valueDeclaration); + reportError(ts.Diagnostics.Property_0_in_type_1_refers_to_a_different_member_that_cannot_be_accessed_from_within_type_2, diagnosticName(privateIdentifierDescription), diagnosticName(sourceName.escapedText === "" ? anon : sourceName), diagnosticName(targetName.escapedText === "" ? anon : targetName)); return; } } - const props = arrayFrom(getUnmatchedProperties(source, target, requireOptionalProperties, /*matchDiscriminantProperties*/ false)); - if (!headMessage || (headMessage.code !== Diagnostics.Class_0_incorrectly_implements_interface_1.code && - headMessage.code !== Diagnostics.Class_0_incorrectly_implements_class_1_Did_you_mean_to_extend_1_and_inherit_its_members_as_a_subclass.code)) { + const props = ts.arrayFrom(getUnmatchedProperties(source, target, requireOptionalProperties, /*matchDiscriminantProperties*/ false)); + if (!headMessage || (headMessage.code !== ts.Diagnostics.Class_0_incorrectly_implements_interface_1.code && + headMessage.code !== ts.Diagnostics.Class_0_incorrectly_implements_class_1_Did_you_mean_to_extend_1_and_inherit_its_members_as_a_subclass.code)) { shouldSkipElaboration = true; // Retain top-level error for interface implementing issues, otherwise omit it } if (props.length === 1) { const propName = symbolToString(unmatchedProperty); - reportError(Diagnostics.Property_0_is_missing_in_type_1_but_required_in_type_2, propName, ...getTypeNamesForErrorDisplay(source, target)); - if (length(unmatchedProperty.declarations)) { - associateRelatedInfo(createDiagnosticForNode(unmatchedProperty.declarations![0], Diagnostics._0_is_declared_here, propName)); + reportError(ts.Diagnostics.Property_0_is_missing_in_type_1_but_required_in_type_2, propName, ...getTypeNamesForErrorDisplay(source, target)); + if (ts.length(unmatchedProperty.declarations)) { + associateRelatedInfo(ts.createDiagnosticForNode(unmatchedProperty.declarations![0], ts.Diagnostics._0_is_declared_here, propName)); } if (shouldSkipElaboration && errorInfo) { overrideNextErrorInfo++; @@ -20100,10 +19560,10 @@ namespace ts { } else if (tryElaborateArrayLikeErrors(source, target, /*reportErrors*/ false)) { if (props.length > 5) { // arbitrary cutoff for too-long list form - reportError(Diagnostics.Type_0_is_missing_the_following_properties_from_type_1_Colon_2_and_3_more, typeToString(source), typeToString(target), map(props.slice(0, 4), p => symbolToString(p)).join(", "), props.length - 4); + reportError(ts.Diagnostics.Type_0_is_missing_the_following_properties_from_type_1_Colon_2_and_3_more, typeToString(source), typeToString(target), ts.map(props.slice(0, 4), p => symbolToString(p)).join(", "), props.length - 4); } else { - reportError(Diagnostics.Type_0_is_missing_the_following_properties_from_type_1_Colon_2, typeToString(source), typeToString(target), map(props, p => symbolToString(p)).join(", ")); + reportError(ts.Diagnostics.Type_0_is_missing_the_following_properties_from_type_1_Colon_2, typeToString(source), typeToString(target), ts.map(props, p => symbolToString(p)).join(", ")); } if (shouldSkipElaboration && errorInfo) { overrideNextErrorInfo++; @@ -20112,105 +19572,105 @@ namespace ts { // No array like or unmatched property error - just issue top level error (errorInfo = undefined) } - function propertiesRelatedTo(source: Type, target: Type, reportErrors: boolean, excludedProperties: Set<__String> | undefined, intersectionState: IntersectionState): Ternary { + function propertiesRelatedTo(source: ts.Type, target: ts.Type, reportErrors: boolean, excludedProperties: ts.Set | undefined, intersectionState: IntersectionState): ts.Ternary { if (relation === identityRelation) { return propertiesIdenticalTo(source, target, excludedProperties); } - let result = Ternary.True; + let result = ts.Ternary.True; if (isTupleType(target)) { if (isArrayOrTupleType(source)) { if (!target.target.readonly && (isReadonlyArrayType(source) || isTupleType(source) && source.target.readonly)) { - return Ternary.False; + return ts.Ternary.False; } const sourceArity = getTypeReferenceArity(source); const targetArity = getTypeReferenceArity(target); - const sourceRestFlag = isTupleType(source) ? source.target.combinedFlags & ElementFlags.Rest : ElementFlags.Rest; - const targetRestFlag = target.target.combinedFlags & ElementFlags.Rest; + const sourceRestFlag = isTupleType(source) ? source.target.combinedFlags & ts.ElementFlags.Rest : ts.ElementFlags.Rest; + const targetRestFlag = target.target.combinedFlags & ts.ElementFlags.Rest; const sourceMinLength = isTupleType(source) ? source.target.minLength : 0; const targetMinLength = target.target.minLength; if (!sourceRestFlag && sourceArity < targetMinLength) { if (reportErrors) { - reportError(Diagnostics.Source_has_0_element_s_but_target_requires_1, sourceArity, targetMinLength); + reportError(ts.Diagnostics.Source_has_0_element_s_but_target_requires_1, sourceArity, targetMinLength); } - return Ternary.False; + return ts.Ternary.False; } if (!targetRestFlag && targetArity < sourceMinLength) { if (reportErrors) { - reportError(Diagnostics.Source_has_0_element_s_but_target_allows_only_1, sourceMinLength, targetArity); + reportError(ts.Diagnostics.Source_has_0_element_s_but_target_allows_only_1, sourceMinLength, targetArity); } - return Ternary.False; + return ts.Ternary.False; } if (!targetRestFlag && (sourceRestFlag || targetArity < sourceArity)) { if (reportErrors) { if (sourceMinLength < targetMinLength) { - reportError(Diagnostics.Target_requires_0_element_s_but_source_may_have_fewer, targetMinLength); + reportError(ts.Diagnostics.Target_requires_0_element_s_but_source_may_have_fewer, targetMinLength); } else { - reportError(Diagnostics.Target_allows_only_0_element_s_but_source_may_have_more, targetArity); + reportError(ts.Diagnostics.Target_allows_only_0_element_s_but_source_may_have_more, targetArity); } } - return Ternary.False; + return ts.Ternary.False; } const sourceTypeArguments = getTypeArguments(source); const targetTypeArguments = getTypeArguments(target); - const startCount = Math.min(isTupleType(source) ? getStartElementCount(source.target, ElementFlags.NonRest) : 0, getStartElementCount(target.target, ElementFlags.NonRest)); - const endCount = Math.min(isTupleType(source) ? getEndElementCount(source.target, ElementFlags.NonRest) : 0, targetRestFlag ? getEndElementCount(target.target, ElementFlags.NonRest) : 0); + const startCount = Math.min(isTupleType(source) ? getStartElementCount(source.target, ts.ElementFlags.NonRest) : 0, getStartElementCount(target.target, ts.ElementFlags.NonRest)); + const endCount = Math.min(isTupleType(source) ? getEndElementCount(source.target, ts.ElementFlags.NonRest) : 0, targetRestFlag ? getEndElementCount(target.target, ts.ElementFlags.NonRest) : 0); let canExcludeDiscriminants = !!excludedProperties; for (let i = 0; i < targetArity; i++) { const sourceIndex = i < targetArity - endCount ? i : i + sourceArity - targetArity; - const sourceFlags = isTupleType(source) && (i < startCount || i >= targetArity - endCount) ? source.target.elementFlags[sourceIndex] : ElementFlags.Rest; + const sourceFlags = isTupleType(source) && (i < startCount || i >= targetArity - endCount) ? source.target.elementFlags[sourceIndex] : ts.ElementFlags.Rest; const targetFlags = target.target.elementFlags[i]; - if (targetFlags & ElementFlags.Variadic && !(sourceFlags & ElementFlags.Variadic)) { + if (targetFlags & ts.ElementFlags.Variadic && !(sourceFlags & ts.ElementFlags.Variadic)) { if (reportErrors) { - reportError(Diagnostics.Source_provides_no_match_for_variadic_element_at_position_0_in_target, i); + reportError(ts.Diagnostics.Source_provides_no_match_for_variadic_element_at_position_0_in_target, i); } - return Ternary.False; + return ts.Ternary.False; } - if (sourceFlags & ElementFlags.Variadic && !(targetFlags & ElementFlags.Variable)) { + if (sourceFlags & ts.ElementFlags.Variadic && !(targetFlags & ts.ElementFlags.Variable)) { if (reportErrors) { - reportError(Diagnostics.Variadic_element_at_position_0_in_source_does_not_match_element_at_position_1_in_target, sourceIndex, i); + reportError(ts.Diagnostics.Variadic_element_at_position_0_in_source_does_not_match_element_at_position_1_in_target, sourceIndex, i); } - return Ternary.False; + return ts.Ternary.False; } - if (targetFlags & ElementFlags.Required && !(sourceFlags & ElementFlags.Required)) { + if (targetFlags & ts.ElementFlags.Required && !(sourceFlags & ts.ElementFlags.Required)) { if (reportErrors) { - reportError(Diagnostics.Source_provides_no_match_for_required_element_at_position_0_in_target, i); + reportError(ts.Diagnostics.Source_provides_no_match_for_required_element_at_position_0_in_target, i); } - return Ternary.False; + return ts.Ternary.False; } // We can only exclude discriminant properties if we have not yet encountered a variable-length element. if (canExcludeDiscriminants) { - if (sourceFlags & ElementFlags.Variable || targetFlags & ElementFlags.Variable) { + if (sourceFlags & ts.ElementFlags.Variable || targetFlags & ts.ElementFlags.Variable) { canExcludeDiscriminants = false; } - if (canExcludeDiscriminants && excludedProperties?.has(("" + i) as __String)) { + if (canExcludeDiscriminants && excludedProperties?.has(("" + i) as ts.__String)) { continue; } } const sourceType = !isTupleType(source) ? sourceTypeArguments[0] : - i < startCount || i >= targetArity - endCount ? removeMissingType(sourceTypeArguments[sourceIndex], !!(sourceFlags & targetFlags & ElementFlags.Optional)) : + i < startCount || i >= targetArity - endCount ? removeMissingType(sourceTypeArguments[sourceIndex], !!(sourceFlags & targetFlags & ts.ElementFlags.Optional)) : getElementTypeOfSliceOfTupleType(source, startCount, endCount) || neverType; const targetType = targetTypeArguments[i]; - const targetCheckType = sourceFlags & ElementFlags.Variadic && targetFlags & ElementFlags.Rest ? createArrayType(targetType) : - removeMissingType(targetType, !!(targetFlags & ElementFlags.Optional)); + const targetCheckType = sourceFlags & ts.ElementFlags.Variadic && targetFlags & ts.ElementFlags.Rest ? createArrayType(targetType) : + removeMissingType(targetType, !!(targetFlags & ts.ElementFlags.Optional)); const related = isRelatedTo(sourceType, targetCheckType, RecursionFlags.Both, reportErrors, /*headMessage*/ undefined, intersectionState); if (!related) { if (reportErrors && (targetArity > 1 || sourceArity > 1)) { if (i < startCount || i >= targetArity - endCount || sourceArity - startCount - endCount === 1) { - reportIncompatibleError(Diagnostics.Type_at_position_0_in_source_is_not_compatible_with_type_at_position_1_in_target, sourceIndex, i); + reportIncompatibleError(ts.Diagnostics.Type_at_position_0_in_source_is_not_compatible_with_type_at_position_1_in_target, sourceIndex, i); } else { - reportIncompatibleError(Diagnostics.Type_at_positions_0_through_1_in_source_is_not_compatible_with_type_at_position_2_in_target, startCount, sourceArity - endCount - 1, i); + reportIncompatibleError(ts.Diagnostics.Type_at_positions_0_through_1_in_source_is_not_compatible_with_type_at_position_2_in_target, startCount, sourceArity - endCount - 1, i); } } - return Ternary.False; + return ts.Ternary.False; } result &= related; } return result; } - if (target.target.combinedFlags & ElementFlags.Variable) { - return Ternary.False; + if (target.target.combinedFlags & ts.ElementFlags.Variable) { + return ts.Ternary.False; } } const requireOptionalProperties = (relation === subtypeRelation || relation === strictSubtypeRelation) && !isObjectLiteralType(source) && !isEmptyArrayLiteralType(source) && !isTupleType(source); @@ -20219,17 +19679,17 @@ namespace ts { if (reportErrors && shouldReportUnmatchedPropertyError(source, target)) { reportUnmatchedProperty(source, target, unmatchedProperty, requireOptionalProperties); } - return Ternary.False; + return ts.Ternary.False; } if (isObjectLiteralType(target)) { for (const sourceProp of excludeProperties(getPropertiesOfType(source), excludedProperties)) { if (!getPropertyOfObjectType(target, sourceProp.escapedName)) { const sourceType = getTypeOfSymbol(sourceProp); - if (!(sourceType.flags & TypeFlags.Undefined)) { + if (!(sourceType.flags & ts.TypeFlags.Undefined)) { if (reportErrors) { - reportError(Diagnostics.Property_0_does_not_exist_on_type_1, symbolToString(sourceProp), typeToString(target)); + reportError(ts.Diagnostics.Property_0_does_not_exist_on_type_1, symbolToString(sourceProp), typeToString(target)); } - return Ternary.False; + return ts.Ternary.False; } } } @@ -20240,12 +19700,12 @@ namespace ts { const numericNamesOnly = isTupleType(source) && isTupleType(target); for (const targetProp of excludeProperties(properties, excludedProperties)) { const name = targetProp.escapedName; - if (!(targetProp.flags & SymbolFlags.Prototype) && (!numericNamesOnly || isNumericLiteralName(name) || name === "length")) { + if (!(targetProp.flags & ts.SymbolFlags.Prototype) && (!numericNamesOnly || ts.isNumericLiteralName(name) || name === "length")) { const sourceProp = getPropertyOfType(source, name); if (sourceProp && sourceProp !== targetProp) { const related = propertyRelatedTo(source, target, sourceProp, targetProp, getNonMissingTypeOfSymbol, reportErrors, intersectionState, relation === comparableRelation); if (!related) { - return Ternary.False; + return ts.Ternary.False; } result &= related; } @@ -20254,70 +19714,69 @@ namespace ts { return result; } - function propertiesIdenticalTo(source: Type, target: Type, excludedProperties: Set<__String> | undefined): Ternary { - if (!(source.flags & TypeFlags.Object && target.flags & TypeFlags.Object)) { - return Ternary.False; + function propertiesIdenticalTo(source: ts.Type, target: ts.Type, excludedProperties: ts.Set | undefined): ts.Ternary { + if (!(source.flags & ts.TypeFlags.Object && target.flags & ts.TypeFlags.Object)) { + return ts.Ternary.False; } const sourceProperties = excludeProperties(getPropertiesOfObjectType(source), excludedProperties); const targetProperties = excludeProperties(getPropertiesOfObjectType(target), excludedProperties); if (sourceProperties.length !== targetProperties.length) { - return Ternary.False; + return ts.Ternary.False; } - let result = Ternary.True; + let result = ts.Ternary.True; for (const sourceProp of sourceProperties) { const targetProp = getPropertyOfObjectType(target, sourceProp.escapedName); if (!targetProp) { - return Ternary.False; + return ts.Ternary.False; } const related = compareProperties(sourceProp, targetProp, isRelatedTo); if (!related) { - return Ternary.False; + return ts.Ternary.False; } result &= related; } return result; } - function signaturesRelatedTo(source: Type, target: Type, kind: SignatureKind, reportErrors: boolean): Ternary { + function signaturesRelatedTo(source: ts.Type, target: ts.Type, kind: ts.SignatureKind, reportErrors: boolean): ts.Ternary { if (relation === identityRelation) { return signaturesIdenticalTo(source, target, kind); } if (target === anyFunctionType || source === anyFunctionType) { - return Ternary.True; + return ts.Ternary.True; } const sourceIsJSConstructor = source.symbol && isJSConstructor(source.symbol.valueDeclaration); const targetIsJSConstructor = target.symbol && isJSConstructor(target.symbol.valueDeclaration); - const sourceSignatures = getSignaturesOfType(source, (sourceIsJSConstructor && kind === SignatureKind.Construct) ? - SignatureKind.Call : kind); - const targetSignatures = getSignaturesOfType(target, (targetIsJSConstructor && kind === SignatureKind.Construct) ? - SignatureKind.Call : kind); - - if (kind === SignatureKind.Construct && sourceSignatures.length && targetSignatures.length) { - const sourceIsAbstract = !!(sourceSignatures[0].flags & SignatureFlags.Abstract); - const targetIsAbstract = !!(targetSignatures[0].flags & SignatureFlags.Abstract); + const sourceSignatures = getSignaturesOfType(source, (sourceIsJSConstructor && kind === ts.SignatureKind.Construct) ? + ts.SignatureKind.Call : kind); + const targetSignatures = getSignaturesOfType(target, (targetIsJSConstructor && kind === ts.SignatureKind.Construct) ? + ts.SignatureKind.Call : kind); + if (kind === ts.SignatureKind.Construct && sourceSignatures.length && targetSignatures.length) { + const sourceIsAbstract = !!(sourceSignatures[0].flags & ts.SignatureFlags.Abstract); + const targetIsAbstract = !!(targetSignatures[0].flags & ts.SignatureFlags.Abstract); if (sourceIsAbstract && !targetIsAbstract) { // An abstract constructor type is not assignable to a non-abstract constructor type // as it would otherwise be possible to new an abstract class. Note that the assignability // check we perform for an extends clause excludes construct signatures from the target, // so this check never proceeds. if (reportErrors) { - reportError(Diagnostics.Cannot_assign_an_abstract_constructor_type_to_a_non_abstract_constructor_type); + reportError(ts.Diagnostics.Cannot_assign_an_abstract_constructor_type_to_a_non_abstract_constructor_type); } - return Ternary.False; + return ts.Ternary.False; } if (!constructorVisibilitiesAreCompatible(sourceSignatures[0], targetSignatures[0], reportErrors)) { - return Ternary.False; + return ts.Ternary.False; } } - let result = Ternary.True; - const incompatibleReporter = kind === SignatureKind.Construct ? reportIncompatibleConstructSignatureReturn : reportIncompatibleCallSignatureReturn; - const sourceObjectFlags = getObjectFlags(source); - const targetObjectFlags = getObjectFlags(target); - if (sourceObjectFlags & ObjectFlags.Instantiated && targetObjectFlags & ObjectFlags.Instantiated && source.symbol === target.symbol || - sourceObjectFlags & ObjectFlags.Reference && targetObjectFlags & ObjectFlags.Reference && (source as TypeReference).target === (target as TypeReference).target) { + let result = ts.Ternary.True; + const incompatibleReporter = kind === ts.SignatureKind.Construct ? reportIncompatibleConstructSignatureReturn : reportIncompatibleCallSignatureReturn; + const sourceObjectFlags = ts.getObjectFlags(source); + const targetObjectFlags = ts.getObjectFlags(target); + if (sourceObjectFlags & ts.ObjectFlags.Instantiated && targetObjectFlags & ts.ObjectFlags.Instantiated && source.symbol === target.symbol || + sourceObjectFlags & ts.ObjectFlags.Reference && targetObjectFlags & ts.ObjectFlags.Reference && (source as ts.TypeReference).target === (target as ts.TypeReference).target) { // We have instantiations of the same anonymous type (which typically will be the type of a // method). Simply do a pairwise comparison of the signatures in the two signature lists instead // of the much more expensive N * M comparison matrix we explore below. We erase type parameters @@ -20325,7 +19784,7 @@ namespace ts { for (let i = 0; i < targetSignatures.length; i++) { const related = signatureRelatedTo(sourceSignatures[i], targetSignatures[i], /*erase*/ true, reportErrors, incompatibleReporter(sourceSignatures[i], targetSignatures[i])); if (!related) { - return Ternary.False; + return ts.Ternary.False; } result &= related; } @@ -20337,15 +19796,14 @@ namespace ts { // this regardless of the number of signatures, but the potential costs are prohibitive due // to the quadratic nature of the logic below. const eraseGenerics = relation === comparableRelation || !!compilerOptions.noStrictGenericChecks; - const sourceSignature = first(sourceSignatures); - const targetSignature = first(targetSignatures); + const sourceSignature = ts.first(sourceSignatures); + const targetSignature = ts.first(targetSignatures); result = signatureRelatedTo(sourceSignature, targetSignature, eraseGenerics, reportErrors, incompatibleReporter(sourceSignature, targetSignature)); - if (!result && reportErrors && kind === SignatureKind.Construct && (sourceObjectFlags & targetObjectFlags) && - (targetSignature.declaration?.kind === SyntaxKind.Constructor || sourceSignature.declaration?.kind === SyntaxKind.Constructor)) { - const constructSignatureToString = (signature: Signature) => - signatureToString(signature, /*enclosingDeclaration*/ undefined, TypeFormatFlags.WriteArrowStyleSignature, kind); - reportError(Diagnostics.Type_0_is_not_assignable_to_type_1, constructSignatureToString(sourceSignature), constructSignatureToString(targetSignature)); - reportError(Diagnostics.Types_of_construct_signatures_are_incompatible); + if (!result && reportErrors && kind === ts.SignatureKind.Construct && (sourceObjectFlags & targetObjectFlags) && + (targetSignature.declaration?.kind === ts.SyntaxKind.Constructor || sourceSignature.declaration?.kind === ts.SyntaxKind.Constructor)) { + const constructSignatureToString = (signature: ts.Signature) => signatureToString(signature, /*enclosingDeclaration*/ undefined, ts.TypeFormatFlags.WriteArrowStyleSignature, kind); + reportError(ts.Diagnostics.Type_0_is_not_assignable_to_type_1, constructSignatureToString(sourceSignature), constructSignatureToString(targetSignature)); + reportError(ts.Diagnostics.Types_of_construct_signatures_are_incompatible); return result; } } @@ -20364,23 +19822,21 @@ namespace ts { shouldElaborateErrors = false; } if (shouldElaborateErrors) { - reportError(Diagnostics.Type_0_provides_no_match_for_the_signature_1, - typeToString(source), - signatureToString(t, /*enclosingDeclaration*/ undefined, /*flags*/ undefined, kind)); + reportError(ts.Diagnostics.Type_0_provides_no_match_for_the_signature_1, typeToString(source), signatureToString(t, /*enclosingDeclaration*/ undefined, /*flags*/ undefined, kind)); } - return Ternary.False; + return ts.Ternary.False; } } return result; } - function shouldReportUnmatchedPropertyError(source: Type, target: Type): boolean { - const typeCallSignatures = getSignaturesOfStructuredType(source, SignatureKind.Call); - const typeConstructSignatures = getSignaturesOfStructuredType(source, SignatureKind.Construct); + function shouldReportUnmatchedPropertyError(source: ts.Type, target: ts.Type): boolean { + const typeCallSignatures = getSignaturesOfStructuredType(source, ts.SignatureKind.Call); + const typeConstructSignatures = getSignaturesOfStructuredType(source, ts.SignatureKind.Construct); const typeProperties = getPropertiesOfObjectType(source); if ((typeCallSignatures.length || typeConstructSignatures.length) && !typeProperties.length) { - if ((getSignaturesOfType(target, SignatureKind.Call).length && typeCallSignatures.length) || - (getSignaturesOfType(target, SignatureKind.Construct).length && typeConstructSignatures.length)) { + if ((getSignaturesOfType(target, ts.SignatureKind.Call).length && typeCallSignatures.length) || + (getSignaturesOfType(target, ts.SignatureKind.Construct).length && typeConstructSignatures.length)) { return true; // target has similar signature kinds to source, still focus on the unmatched property } return false; @@ -20388,65 +19844,64 @@ namespace ts { return true; } - function reportIncompatibleCallSignatureReturn(siga: Signature, sigb: Signature) { + function reportIncompatibleCallSignatureReturn(siga: ts.Signature, sigb: ts.Signature) { if (siga.parameters.length === 0 && sigb.parameters.length === 0) { - return (source: Type, target: Type) => reportIncompatibleError(Diagnostics.Call_signatures_with_no_arguments_have_incompatible_return_types_0_and_1, typeToString(source), typeToString(target)); + return (source: ts.Type, target: ts.Type) => reportIncompatibleError(ts.Diagnostics.Call_signatures_with_no_arguments_have_incompatible_return_types_0_and_1, typeToString(source), typeToString(target)); } - return (source: Type, target: Type) => reportIncompatibleError(Diagnostics.Call_signature_return_types_0_and_1_are_incompatible, typeToString(source), typeToString(target)); + return (source: ts.Type, target: ts.Type) => reportIncompatibleError(ts.Diagnostics.Call_signature_return_types_0_and_1_are_incompatible, typeToString(source), typeToString(target)); } - function reportIncompatibleConstructSignatureReturn(siga: Signature, sigb: Signature) { + function reportIncompatibleConstructSignatureReturn(siga: ts.Signature, sigb: ts.Signature) { if (siga.parameters.length === 0 && sigb.parameters.length === 0) { - return (source: Type, target: Type) => reportIncompatibleError(Diagnostics.Construct_signatures_with_no_arguments_have_incompatible_return_types_0_and_1, typeToString(source), typeToString(target)); + return (source: ts.Type, target: ts.Type) => reportIncompatibleError(ts.Diagnostics.Construct_signatures_with_no_arguments_have_incompatible_return_types_0_and_1, typeToString(source), typeToString(target)); } - return (source: Type, target: Type) => reportIncompatibleError(Diagnostics.Construct_signature_return_types_0_and_1_are_incompatible, typeToString(source), typeToString(target)); + return (source: ts.Type, target: ts.Type) => reportIncompatibleError(ts.Diagnostics.Construct_signature_return_types_0_and_1_are_incompatible, typeToString(source), typeToString(target)); } /** * See signatureAssignableTo, compareSignaturesIdentical */ - function signatureRelatedTo(source: Signature, target: Signature, erase: boolean, reportErrors: boolean, incompatibleReporter: (source: Type, target: Type) => void): Ternary { - return compareSignaturesRelated(erase ? getErasedSignature(source) : source, erase ? getErasedSignature(target) : target, - relation === strictSubtypeRelation ? SignatureCheckMode.StrictArity : 0, reportErrors, reportError, incompatibleReporter, isRelatedToWorker, makeFunctionTypeMapper(reportUnreliableMarkers)); + function signatureRelatedTo(source: ts.Signature, target: ts.Signature, erase: boolean, reportErrors: boolean, incompatibleReporter: (source: ts.Type, target: ts.Type) => void): ts.Ternary { + return compareSignaturesRelated(erase ? getErasedSignature(source) : source, erase ? getErasedSignature(target) : target, relation === strictSubtypeRelation ? SignatureCheckMode.StrictArity : 0, reportErrors, reportError, incompatibleReporter, isRelatedToWorker, makeFunctionTypeMapper(reportUnreliableMarkers)); } - function signaturesIdenticalTo(source: Type, target: Type, kind: SignatureKind): Ternary { + function signaturesIdenticalTo(source: ts.Type, target: ts.Type, kind: ts.SignatureKind): ts.Ternary { const sourceSignatures = getSignaturesOfType(source, kind); const targetSignatures = getSignaturesOfType(target, kind); if (sourceSignatures.length !== targetSignatures.length) { - return Ternary.False; + return ts.Ternary.False; } - let result = Ternary.True; + let result = ts.Ternary.True; for (let i = 0; i < sourceSignatures.length; i++) { const related = compareSignaturesIdentical(sourceSignatures[i], targetSignatures[i], /*partialMatch*/ false, /*ignoreThisTypes*/ false, /*ignoreReturnTypes*/ false, isRelatedTo); if (!related) { - return Ternary.False; + return ts.Ternary.False; } result &= related; } return result; } - function membersRelatedToIndexInfo(source: Type, targetInfo: IndexInfo, reportErrors: boolean): Ternary { - let result = Ternary.True; + function membersRelatedToIndexInfo(source: ts.Type, targetInfo: ts.IndexInfo, reportErrors: boolean): ts.Ternary { + let result = ts.Ternary.True; const keyType = targetInfo.keyType; - const props = source.flags & TypeFlags.Intersection ? getPropertiesOfUnionOrIntersectionType(source as IntersectionType) : getPropertiesOfObjectType(source); + const props = source.flags & ts.TypeFlags.Intersection ? getPropertiesOfUnionOrIntersectionType(source as ts.IntersectionType) : getPropertiesOfObjectType(source); for (const prop of props) { // Skip over ignored JSX and symbol-named members if (isIgnoredJsxProperty(source, prop)) { continue; } - if (isApplicableIndexType(getLiteralTypeFromProperty(prop, TypeFlags.StringOrNumberLiteralOrUnique), keyType)) { + if (isApplicableIndexType(getLiteralTypeFromProperty(prop, ts.TypeFlags.StringOrNumberLiteralOrUnique), keyType)) { const propType = getNonMissingTypeOfSymbol(prop); - const type = exactOptionalPropertyTypes || propType.flags & TypeFlags.Undefined || keyType === numberType || !(prop.flags & SymbolFlags.Optional) + const type = exactOptionalPropertyTypes || propType.flags & ts.TypeFlags.Undefined || keyType === numberType || !(prop.flags & ts.SymbolFlags.Optional) ? propType : getTypeWithFacts(propType, TypeFacts.NEUndefined); const related = isRelatedTo(type, targetInfo.type, RecursionFlags.Both, reportErrors); if (!related) { if (reportErrors) { - reportError(Diagnostics.Property_0_is_incompatible_with_index_signature, symbolToString(prop)); + reportError(ts.Diagnostics.Property_0_is_incompatible_with_index_signature, symbolToString(prop)); } - return Ternary.False; + return ts.Ternary.False; } result &= related; } @@ -20455,7 +19910,7 @@ namespace ts { if (isApplicableIndexType(info.keyType, keyType)) { const related = indexInfoRelatedTo(info, targetInfo, reportErrors); if (!related) { - return Ternary.False; + return ts.Ternary.False; } result &= related; } @@ -20463,39 +19918,39 @@ namespace ts { return result; } - function indexInfoRelatedTo(sourceInfo: IndexInfo, targetInfo: IndexInfo, reportErrors: boolean) { + function indexInfoRelatedTo(sourceInfo: ts.IndexInfo, targetInfo: ts.IndexInfo, reportErrors: boolean) { const related = isRelatedTo(sourceInfo.type, targetInfo.type, RecursionFlags.Both, reportErrors); if (!related && reportErrors) { if (sourceInfo.keyType === targetInfo.keyType) { - reportError(Diagnostics._0_index_signatures_are_incompatible, typeToString(sourceInfo.keyType)); + reportError(ts.Diagnostics._0_index_signatures_are_incompatible, typeToString(sourceInfo.keyType)); } else { - reportError(Diagnostics._0_and_1_index_signatures_are_incompatible, typeToString(sourceInfo.keyType), typeToString(targetInfo.keyType)); + reportError(ts.Diagnostics._0_and_1_index_signatures_are_incompatible, typeToString(sourceInfo.keyType), typeToString(targetInfo.keyType)); } } return related; } - function indexSignaturesRelatedTo(source: Type, target: Type, sourceIsPrimitive: boolean, reportErrors: boolean, intersectionState: IntersectionState): Ternary { + function indexSignaturesRelatedTo(source: ts.Type, target: ts.Type, sourceIsPrimitive: boolean, reportErrors: boolean, intersectionState: IntersectionState): ts.Ternary { if (relation === identityRelation) { return indexSignaturesIdenticalTo(source, target); } const indexInfos = getIndexInfosOfType(target); - const targetHasStringIndex = some(indexInfos, info => info.keyType === stringType); - let result = Ternary.True; + const targetHasStringIndex = ts.some(indexInfos, info => info.keyType === stringType); + let result = ts.Ternary.True; for (const targetInfo of indexInfos) { - const related = !sourceIsPrimitive && targetHasStringIndex && targetInfo.type.flags & TypeFlags.Any ? Ternary.True : + const related = !sourceIsPrimitive && targetHasStringIndex && targetInfo.type.flags & ts.TypeFlags.Any ? ts.Ternary.True : isGenericMappedType(source) && targetHasStringIndex ? isRelatedTo(getTemplateTypeFromMappedType(source), targetInfo.type, RecursionFlags.Both, reportErrors) : typeRelatedToIndexInfo(source, targetInfo, reportErrors, intersectionState); if (!related) { - return Ternary.False; + return ts.Ternary.False; } result &= related; } return result; } - function typeRelatedToIndexInfo(source: Type, targetInfo: IndexInfo, reportErrors: boolean, intersectionState: IntersectionState): Ternary { + function typeRelatedToIndexInfo(source: ts.Type, targetInfo: ts.IndexInfo, reportErrors: boolean, intersectionState: IntersectionState): ts.Ternary { const sourceInfo = getApplicableIndexInfo(source, targetInfo.keyType); if (sourceInfo) { return indexInfoRelatedTo(sourceInfo, targetInfo, reportErrors); @@ -20505,94 +19960,95 @@ namespace ts { return membersRelatedToIndexInfo(source, targetInfo, reportErrors); } if (reportErrors) { - reportError(Diagnostics.Index_signature_for_type_0_is_missing_in_type_1, typeToString(targetInfo.keyType), typeToString(source)); + reportError(ts.Diagnostics.Index_signature_for_type_0_is_missing_in_type_1, typeToString(targetInfo.keyType), typeToString(source)); } - return Ternary.False; + return ts.Ternary.False; } - function indexSignaturesIdenticalTo(source: Type, target: Type): Ternary { + function indexSignaturesIdenticalTo(source: ts.Type, target: ts.Type): ts.Ternary { const sourceInfos = getIndexInfosOfType(source); const targetInfos = getIndexInfosOfType(target); if (sourceInfos.length !== targetInfos.length) { - return Ternary.False; + return ts.Ternary.False; } for (const targetInfo of targetInfos) { const sourceInfo = getIndexInfoOfType(source, targetInfo.keyType); if (!(sourceInfo && isRelatedTo(sourceInfo.type, targetInfo.type, RecursionFlags.Both) && sourceInfo.isReadonly === targetInfo.isReadonly)) { - return Ternary.False; + return ts.Ternary.False; } } - return Ternary.True; + return ts.Ternary.True; } - function constructorVisibilitiesAreCompatible(sourceSignature: Signature, targetSignature: Signature, reportErrors: boolean) { + function constructorVisibilitiesAreCompatible(sourceSignature: ts.Signature, targetSignature: ts.Signature, reportErrors: boolean) { if (!sourceSignature.declaration || !targetSignature.declaration) { return true; } - const sourceAccessibility = getSelectedEffectiveModifierFlags(sourceSignature.declaration, ModifierFlags.NonPublicAccessibilityModifier); - const targetAccessibility = getSelectedEffectiveModifierFlags(targetSignature.declaration, ModifierFlags.NonPublicAccessibilityModifier); + const sourceAccessibility = ts.getSelectedEffectiveModifierFlags(sourceSignature.declaration, ts.ModifierFlags.NonPublicAccessibilityModifier); + const targetAccessibility = ts.getSelectedEffectiveModifierFlags(targetSignature.declaration, ts.ModifierFlags.NonPublicAccessibilityModifier); // A public, protected and private signature is assignable to a private signature. - if (targetAccessibility === ModifierFlags.Private) { + if (targetAccessibility === ts.ModifierFlags.Private) { return true; } // A public and protected signature is assignable to a protected signature. - if (targetAccessibility === ModifierFlags.Protected && sourceAccessibility !== ModifierFlags.Private) { + if (targetAccessibility === ts.ModifierFlags.Protected && sourceAccessibility !== ts.ModifierFlags.Private) { return true; } // Only a public signature is assignable to public signature. - if (targetAccessibility !== ModifierFlags.Protected && !sourceAccessibility) { + if (targetAccessibility !== ts.ModifierFlags.Protected && !sourceAccessibility) { return true; } if (reportErrors) { - reportError(Diagnostics.Cannot_assign_a_0_constructor_type_to_a_1_constructor_type, visibilityToString(sourceAccessibility), visibilityToString(targetAccessibility)); + reportError(ts.Diagnostics.Cannot_assign_a_0_constructor_type_to_a_1_constructor_type, visibilityToString(sourceAccessibility), visibilityToString(targetAccessibility)); } return false; } } - function typeCouldHaveTopLevelSingletonTypes(type: Type): boolean { + function typeCouldHaveTopLevelSingletonTypes(type: ts.Type): boolean { // Okay, yes, 'boolean' is a union of 'true | false', but that's not useful // in error reporting scenarios. If you need to use this function but that detail matters, // feel free to add a flag. - if (type.flags & TypeFlags.Boolean) { + if (type.flags & ts.TypeFlags.Boolean) { return false; } - if (type.flags & TypeFlags.UnionOrIntersection) { - return !!forEach((type as IntersectionType).types, typeCouldHaveTopLevelSingletonTypes); + if (type.flags & ts.TypeFlags.UnionOrIntersection) { + return !!ts.forEach((type as ts.IntersectionType).types, typeCouldHaveTopLevelSingletonTypes); } - if (type.flags & TypeFlags.Instantiable) { + if (type.flags & ts.TypeFlags.Instantiable) { const constraint = getConstraintOfType(type); if (constraint && constraint !== type) { return typeCouldHaveTopLevelSingletonTypes(constraint); } } - return isUnitType(type) || !!(type.flags & TypeFlags.TemplateLiteral); + return isUnitType(type) || !!(type.flags & ts.TypeFlags.TemplateLiteral); } - function getExactOptionalUnassignableProperties(source: Type, target: Type) { - if (isTupleType(source) && isTupleType(target)) return emptyArray; + function getExactOptionalUnassignableProperties(source: ts.Type, target: ts.Type) { + if (isTupleType(source) && isTupleType(target)) + return ts.emptyArray; return getPropertiesOfType(target) .filter(targetProp => isExactOptionalPropertyMismatch(getTypeOfPropertyOfType(source, targetProp.escapedName), getTypeOfSymbol(targetProp))); } - function isExactOptionalPropertyMismatch(source: Type | undefined, target: Type | undefined) { - return !!source && !!target && maybeTypeOfKind(source, TypeFlags.Undefined) && !!containsMissingType(target); + function isExactOptionalPropertyMismatch(source: ts.Type | undefined, target: ts.Type | undefined) { + return !!source && !!target && maybeTypeOfKind(source, ts.TypeFlags.Undefined) && !!containsMissingType(target); } - function getExactOptionalProperties(type: Type) { + function getExactOptionalProperties(type: ts.Type) { return getPropertiesOfType(type).filter(targetProp => containsMissingType(getTypeOfSymbol(targetProp))); } - function getBestMatchingType(source: Type, target: UnionOrIntersectionType, isRelatedTo = compareTypesAssignable) { + function getBestMatchingType(source: ts.Type, target: ts.UnionOrIntersectionType, isRelatedTo = compareTypesAssignable) { return findMatchingDiscriminantType(source, target, isRelatedTo, /*skipPartial*/ true) || findMatchingTypeReferenceOrTypeAliasReference(source, target) || findBestTypeForObjectLiteral(source, target) || @@ -20600,15 +20056,24 @@ namespace ts { findMostOverlappyType(source, target); } - function discriminateTypeByDiscriminableItems(target: UnionType, discriminators: [() => Type, __String][], related: (source: Type, target: Type) => boolean | Ternary, defaultValue?: undefined, skipPartial?: boolean): Type | undefined; - function discriminateTypeByDiscriminableItems(target: UnionType, discriminators: [() => Type, __String][], related: (source: Type, target: Type) => boolean | Ternary, defaultValue: Type, skipPartial?: boolean): Type; - function discriminateTypeByDiscriminableItems(target: UnionType, discriminators: [() => Type, __String][], related: (source: Type, target: Type) => boolean | Ternary, defaultValue?: Type, skipPartial?: boolean) { + function discriminateTypeByDiscriminableItems(target: ts.UnionType, discriminators: [ + () => ts.Type, + ts.__String + ][], related: (source: ts.Type, target: ts.Type) => boolean | ts.Ternary, defaultValue?: undefined, skipPartial?: boolean): ts.Type | undefined; + function discriminateTypeByDiscriminableItems(target: ts.UnionType, discriminators: [ + () => ts.Type, + ts.__String + ][], related: (source: ts.Type, target: ts.Type) => boolean | ts.Ternary, defaultValue: ts.Type, skipPartial?: boolean): ts.Type; + function discriminateTypeByDiscriminableItems(target: ts.UnionType, discriminators: [ + () => ts.Type, + ts.__String + ][], related: (source: ts.Type, target: ts.Type) => boolean | ts.Ternary, defaultValue?: ts.Type, skipPartial?: boolean) { // undefined=unknown, true=discriminated, false=not discriminated // The state of each type progresses from left to right. Discriminated types stop at 'true'. const discriminable = target.types.map(_ => undefined) as (boolean | undefined)[]; for (const [getDiscriminatingType, propertyName] of discriminators) { const targetProp = getUnionOrIntersectionProperty(target, propertyName); - if (skipPartial && targetProp && getCheckFlags(targetProp) & CheckFlags.ReadPartial) { + if (skipPartial && targetProp && ts.getCheckFlags(targetProp) & ts.CheckFlags.ReadPartial) { continue; } let i = 0; @@ -20642,19 +20107,19 @@ namespace ts { * A type is 'weak' if it is an object type with at least one optional property * and no required properties, call/construct signatures or index signatures */ - function isWeakType(type: Type): boolean { - if (type.flags & TypeFlags.Object) { - const resolved = resolveStructuredTypeMembers(type as ObjectType); + function isWeakType(type: ts.Type): boolean { + if (type.flags & ts.TypeFlags.Object) { + const resolved = resolveStructuredTypeMembers(type as ts.ObjectType); return resolved.callSignatures.length === 0 && resolved.constructSignatures.length === 0 && resolved.indexInfos.length === 0 && - resolved.properties.length > 0 && every(resolved.properties, p => !!(p.flags & SymbolFlags.Optional)); + resolved.properties.length > 0 && ts.every(resolved.properties, p => !!(p.flags & ts.SymbolFlags.Optional)); } - if (type.flags & TypeFlags.Intersection) { - return every((type as IntersectionType).types, isWeakType); + if (type.flags & ts.TypeFlags.Intersection) { + return ts.every((type as ts.IntersectionType).types, isWeakType); } return false; } - function hasCommonProperties(source: Type, target: Type, isComparingJsxAttributes: boolean) { + function hasCommonProperties(source: ts.Type, target: ts.Type, isComparingJsxAttributes: boolean) { for (const prop of getPropertiesOfType(source)) { if (isKnownProperty(target, prop.escapedName, isComparingJsxAttributes)) { return true; @@ -20663,14 +20128,14 @@ namespace ts { return false; } - function getVariances(type: GenericType): VarianceFlags[] { + function getVariances(type: ts.GenericType): ts.VarianceFlags[] { // Arrays and tuples are known to be covariant, no need to spend time computing this. - return type === globalArrayType || type === globalReadonlyArrayType || type.objectFlags & ObjectFlags.Tuple ? + return type === globalArrayType || type === globalReadonlyArrayType || type.objectFlags & ts.ObjectFlags.Tuple ? arrayVariances : getVariancesWorker(type.symbol, type.typeParameters); } - function getAliasVariances(symbol: Symbol) { + function getAliasVariances(symbol: ts.Symbol) { return getVariancesWorker(symbol, getSymbolLinks(symbol).typeParameters); } @@ -20679,17 +20144,17 @@ namespace ts { // generic type are structurally compared. We infer the variance information by comparing // instantiations of the generic type for type arguments with known relations. The function // returns the emptyArray singleton when invoked recursively for the given generic type. - function getVariancesWorker(symbol: Symbol, typeParameters: readonly TypeParameter[] = emptyArray): VarianceFlags[] { + function getVariancesWorker(symbol: ts.Symbol, typeParameters: readonly ts.TypeParameter[] = ts.emptyArray): ts.VarianceFlags[] { const links = getSymbolLinks(symbol); if (!links.variances) { - tracing?.push(tracing.Phase.CheckTypes, "getVariancesWorker", { arity: typeParameters.length, id: getTypeId(getDeclaredTypeOfSymbol(symbol)) }); - links.variances = emptyArray; + ts.tracing?.push(ts.tracing.Phase.CheckTypes, "getVariancesWorker", { arity: typeParameters.length, id: getTypeId(getDeclaredTypeOfSymbol(symbol)) }); + links.variances = ts.emptyArray; const variances = []; for (const tp of typeParameters) { const modifiers = getVarianceModifiers(tp); - let variance = modifiers & ModifierFlags.Out ? - modifiers & ModifierFlags.In ? VarianceFlags.Invariant : VarianceFlags.Covariant : - modifiers & ModifierFlags.In ? VarianceFlags.Contravariant : undefined; + let variance = modifiers & ts.ModifierFlags.Out ? + modifiers & ts.ModifierFlags.In ? ts.VarianceFlags.Invariant : ts.VarianceFlags.Covariant : + modifiers & ts.ModifierFlags.In ? ts.VarianceFlags.Contravariant : undefined; if (variance === undefined) { let unmeasurable = false; let unreliable = false; @@ -20700,90 +20165,90 @@ namespace ts { // invariance, covariance, contravariance or bivariance. const typeWithSuper = createMarkerType(symbol, tp, markerSuperType); const typeWithSub = createMarkerType(symbol, tp, markerSubType); - variance = (isTypeAssignableTo(typeWithSub, typeWithSuper) ? VarianceFlags.Covariant : 0) | - (isTypeAssignableTo(typeWithSuper, typeWithSub) ? VarianceFlags.Contravariant : 0); + variance = (isTypeAssignableTo(typeWithSub, typeWithSuper) ? ts.VarianceFlags.Covariant : 0) | + (isTypeAssignableTo(typeWithSuper, typeWithSub) ? ts.VarianceFlags.Contravariant : 0); // If the instantiations appear to be related bivariantly it may be because the // type parameter is independent (i.e. it isn't witnessed anywhere in the generic // type). To determine this we compare instantiations where the type parameter is // replaced with marker types that are known to be unrelated. - if (variance === VarianceFlags.Bivariant && isTypeAssignableTo(createMarkerType(symbol, tp, markerOtherType), typeWithSuper)) { - variance = VarianceFlags.Independent; + if (variance === ts.VarianceFlags.Bivariant && isTypeAssignableTo(createMarkerType(symbol, tp, markerOtherType), typeWithSuper)) { + variance = ts.VarianceFlags.Independent; } outofbandVarianceMarkerHandler = oldHandler; if (unmeasurable || unreliable) { if (unmeasurable) { - variance |= VarianceFlags.Unmeasurable; + variance |= ts.VarianceFlags.Unmeasurable; } if (unreliable) { - variance |= VarianceFlags.Unreliable; + variance |= ts.VarianceFlags.Unreliable; } } } variances.push(variance); } links.variances = variances; - tracing?.pop(); + ts.tracing?.pop(); } return links.variances; } - function createMarkerType(symbol: Symbol, source: TypeParameter, target: Type) { + function createMarkerType(symbol: ts.Symbol, source: ts.TypeParameter, target: ts.Type) { const mapper = makeUnaryTypeMapper(source, target); const type = getDeclaredTypeOfSymbol(symbol); if (isErrorType(type)) { return type; } - const result = symbol.flags & SymbolFlags.TypeAlias ? + const result = symbol.flags & ts.SymbolFlags.TypeAlias ? getTypeAliasInstantiation(symbol, instantiateTypes(getSymbolLinks(symbol).typeParameters!, mapper)) : - createTypeReference(type as GenericType, instantiateTypes((type as GenericType).typeParameters, mapper)); + createTypeReference(type as ts.GenericType, instantiateTypes((type as ts.GenericType).typeParameters, mapper)); markerTypes.add(getTypeId(result)); return result; } - function isMarkerType(type: Type) { + function isMarkerType(type: ts.Type) { return markerTypes.has(getTypeId(type)); } - function getVarianceModifiers(tp: TypeParameter): ModifierFlags { - return (some(tp.symbol?.declarations, d => hasSyntacticModifier(d, ModifierFlags.In)) ? ModifierFlags.In : 0) | - (some(tp.symbol?.declarations, d => hasSyntacticModifier(d, ModifierFlags.Out)) ? ModifierFlags.Out: 0); + function getVarianceModifiers(tp: ts.TypeParameter): ts.ModifierFlags { + return (ts.some(tp.symbol?.declarations, d => ts.hasSyntacticModifier(d, ts.ModifierFlags.In)) ? ts.ModifierFlags.In : 0) | + (ts.some(tp.symbol?.declarations, d => ts.hasSyntacticModifier(d, ts.ModifierFlags.Out)) ? ts.ModifierFlags.Out : 0); } // Return true if the given type reference has a 'void' type argument for a covariant type parameter. // See comment at call in recursiveTypeRelatedTo for when this case matters. - function hasCovariantVoidArgument(typeArguments: readonly Type[], variances: VarianceFlags[]): boolean { + function hasCovariantVoidArgument(typeArguments: readonly ts.Type[], variances: ts.VarianceFlags[]): boolean { for (let i = 0; i < variances.length; i++) { - if ((variances[i] & VarianceFlags.VarianceMask) === VarianceFlags.Covariant && typeArguments[i].flags & TypeFlags.Void) { + if ((variances[i] & ts.VarianceFlags.VarianceMask) === ts.VarianceFlags.Covariant && typeArguments[i].flags & ts.TypeFlags.Void) { return true; } } return false; } - function isUnconstrainedTypeParameter(type: Type) { - return type.flags & TypeFlags.TypeParameter && !getConstraintOfTypeParameter(type as TypeParameter); + function isUnconstrainedTypeParameter(type: ts.Type) { + return type.flags & ts.TypeFlags.TypeParameter && !getConstraintOfTypeParameter(type as ts.TypeParameter); } - function isNonDeferredTypeReference(type: Type): type is TypeReference { - return !!(getObjectFlags(type) & ObjectFlags.Reference) && !(type as TypeReference).node; + function isNonDeferredTypeReference(type: ts.Type): type is ts.TypeReference { + return !!(ts.getObjectFlags(type) & ts.ObjectFlags.Reference) && !(type as ts.TypeReference).node; } - function isTypeReferenceWithGenericArguments(type: Type): boolean { - return isNonDeferredTypeReference(type) && some(getTypeArguments(type), t => !!(t.flags & TypeFlags.TypeParameter) || isTypeReferenceWithGenericArguments(t)); + function isTypeReferenceWithGenericArguments(type: ts.Type): boolean { + return isNonDeferredTypeReference(type) && ts.some(getTypeArguments(type), t => !!(t.flags & ts.TypeFlags.TypeParameter) || isTypeReferenceWithGenericArguments(t)); } - function getGenericTypeReferenceRelationKey(source: TypeReference, target: TypeReference, postFix: string, ignoreConstraints: boolean) { - const typeParameters: Type[] = []; + function getGenericTypeReferenceRelationKey(source: ts.TypeReference, target: ts.TypeReference, postFix: string, ignoreConstraints: boolean) { + const typeParameters: ts.Type[] = []; let constraintMarker = ""; const sourceId = getTypeReferenceId(source, 0); const targetId = getTypeReferenceId(target, 0); return `${constraintMarker}${sourceId},${targetId}${postFix}`; // getTypeReferenceId(A) returns "111=0-12=1" // where A.id=111 and number.id=12 - function getTypeReferenceId(type: TypeReference, depth = 0) { + function getTypeReferenceId(type: ts.TypeReference, depth = 0) { let result = "" + type.target.id; for (const t of getTypeArguments(type)) { - if (t.flags & TypeFlags.TypeParameter) { + if (t.flags & ts.TypeFlags.TypeParameter) { if (ignoreConstraints || isUnconstrainedTypeParameter(t)) { let index = typeParameters.indexOf(t); if (index < 0) { @@ -20798,7 +20263,7 @@ namespace ts { constraintMarker = "*"; } else if (depth < 4 && isTypeReferenceWithGenericArguments(t)) { - result += "<" + getTypeReferenceId(t as TypeReference, depth + 1) + ">"; + result += "<" + getTypeReferenceId(t as ts.TypeReference, depth + 1) + ">"; continue; } result += "-" + t.id; @@ -20811,7 +20276,7 @@ namespace ts { * To improve caching, the relation key for two generic types uses the target's id plus ids of the type parameters. * For other cases, the types ids are used. */ - function getRelationKey(source: Type, target: Type, intersectionState: IntersectionState, relation: ESMap, ignoreConstraints: boolean) { + function getRelationKey(source: ts.Type, target: ts.Type, intersectionState: IntersectionState, relation: ts.ESMap, ignoreConstraints: boolean) { if (relation === identityRelation && source.id > target.id) { const temp = source; source = target; @@ -20819,15 +20284,15 @@ namespace ts { } const postFix = intersectionState ? ":" + intersectionState : ""; return isTypeReferenceWithGenericArguments(source) && isTypeReferenceWithGenericArguments(target) ? - getGenericTypeReferenceRelationKey(source as TypeReference, target as TypeReference, postFix, ignoreConstraints) : + getGenericTypeReferenceRelationKey(source as ts.TypeReference, target as ts.TypeReference, postFix, ignoreConstraints) : `${source.id},${target.id}${postFix}`; } // Invoke the callback for each underlying property symbol of the given symbol and return the first // value that isn't undefined. - function forEachProperty(prop: Symbol, callback: (p: Symbol) => T): T | undefined { - if (getCheckFlags(prop) & CheckFlags.Synthetic) { - for (const t of (prop as TransientSymbol).containingType!.types) { + function forEachProperty(prop: ts.Symbol, callback: (p: ts.Symbol) => T): T | undefined { + if (ts.getCheckFlags(prop) & ts.CheckFlags.Synthetic) { + for (const t of (prop as ts.TransientSymbol).containingType!.types) { const p = getPropertyOfType(t, prop.escapedName); const result = p && forEachProperty(p, callback); if (result) { @@ -20840,12 +20305,12 @@ namespace ts { } // Return the declaring class type of a property or undefined if property not declared in class - function getDeclaringClass(prop: Symbol) { - return prop.parent && prop.parent.flags & SymbolFlags.Class ? getDeclaredTypeOfSymbol(getParentOfSymbol(prop)!) as InterfaceType : undefined; + function getDeclaringClass(prop: ts.Symbol) { + return prop.parent && prop.parent.flags & ts.SymbolFlags.Class ? getDeclaredTypeOfSymbol(getParentOfSymbol(prop)!) as ts.InterfaceType : undefined; } // Return the inherited type of the given property or undefined if property doesn't exist in a base class. - function getTypeOfPropertyInBaseClass(property: Symbol) { + function getTypeOfPropertyInBaseClass(property: ts.Symbol) { const classType = getDeclaringClass(property); const baseClassType = classType && getBaseTypes(classType)[0]; return baseClassType && getTypeOfPropertyOfType(baseClassType, property.escapedName); @@ -20853,7 +20318,7 @@ namespace ts { // Return true if some underlying source property is declared in a class that derives // from the given base class. - function isPropertyInClassDerivedFrom(prop: Symbol, baseClass: Type | undefined) { + function isPropertyInClassDerivedFrom(prop: ts.Symbol, baseClass: ts.Type | undefined) { return forEachProperty(prop, sp => { const sourceClass = getDeclaringClass(sp); return sourceClass ? hasBaseType(sourceClass, baseClass) : false; @@ -20861,15 +20326,15 @@ namespace ts { } // Return true if source property is a valid override of protected parts of target property. - function isValidOverrideOf(sourceProp: Symbol, targetProp: Symbol) { - return !forEachProperty(targetProp, tp => getDeclarationModifierFlagsFromSymbol(tp) & ModifierFlags.Protected ? + function isValidOverrideOf(sourceProp: ts.Symbol, targetProp: ts.Symbol) { + return !forEachProperty(targetProp, tp => ts.getDeclarationModifierFlagsFromSymbol(tp) & ts.ModifierFlags.Protected ? !isPropertyInClassDerivedFrom(sourceProp, getDeclaringClass(tp)) : false); } // Return true if the given class derives from each of the declaring classes of the protected // constituents of the given property. - function isClassDerivedFromDeclaringClasses(checkClass: T, prop: Symbol, writing: boolean) { - return forEachProperty(prop, p => getDeclarationModifierFlagsFromSymbol(p, writing) & ModifierFlags.Protected ? + function isClassDerivedFromDeclaringClasses(checkClass: T, prop: ts.Symbol, writing: boolean) { + return forEachProperty(prop, p => ts.getDeclarationModifierFlagsFromSymbol(p, writing) & ts.ModifierFlags.Protected ? !hasBaseType(checkClass, getDeclaringClass(p)) : false) ? undefined : checkClass; } @@ -20885,7 +20350,7 @@ namespace ts { // `type A = null extends T ? [A>] : [T]` // has expanded into `[A>>>>>]`. In such cases we need // to terminate the expansion, and we do so here. - function isDeeplyNestedType(type: Type, stack: Type[], depth: number, maxDepth = 3): boolean { + function isDeeplyNestedType(type: ts.Type, stack: ts.Type[], depth: number, maxDepth = 3): boolean { if (depth >= maxDepth) { const identity = getRecursionIdentity(type); let count = 0; @@ -20914,16 +20379,16 @@ namespace ts { // instantiations of that type have the same recursion identity. The default recursion identity is the object // identity of the type, meaning that every type is unique. Generally, types with constituents that could circularly // reference the type have a recursion identity that differs from the object identity. - function getRecursionIdentity(type: Type): object { + function getRecursionIdentity(type: ts.Type): object { // Object and array literals are known not to contain recursive references and don't need a recursion identity. - if (type.flags & TypeFlags.Object && !isObjectOrArrayLiteralType(type)) { - if (getObjectFlags(type) && ObjectFlags.Reference && (type as TypeReference).node) { + if (type.flags & ts.TypeFlags.Object && !isObjectOrArrayLiteralType(type)) { + if (ts.getObjectFlags(type) && ts.ObjectFlags.Reference && (type as ts.TypeReference).node) { // Deferred type references are tracked through their associated AST node. This gives us finer // granularity than using their associated target because each manifest type reference has a // unique AST node. - return (type as TypeReference).node!; + return (type as ts.TypeReference).node!; } - if (type.symbol && !(getObjectFlags(type) & ObjectFlags.Anonymous && type.symbol.flags & SymbolFlags.Class)) { + if (type.symbol && !(ts.getObjectFlags(type) & ts.ObjectFlags.Anonymous && type.symbol.flags & ts.SymbolFlags.Class)) { // We track all object types that have an associated symbol (representing the origin of the type), but // exclude the static side of classes from this check since it shares its symbol with the instance side. return type.symbol; @@ -20933,56 +20398,56 @@ namespace ts { return type.target; } } - if (type.flags & TypeFlags.TypeParameter) { + if (type.flags & ts.TypeFlags.TypeParameter) { return type.symbol; } - if (type.flags & TypeFlags.IndexedAccess) { + if (type.flags & ts.TypeFlags.IndexedAccess) { // Identity is the leftmost object type in a chain of indexed accesses, eg, in A[P][Q] it is A do { - type = (type as IndexedAccessType).objectType; - } while (type.flags & TypeFlags.IndexedAccess); + type = (type as ts.IndexedAccessType).objectType; + } while (type.flags & ts.TypeFlags.IndexedAccess); return type; } - if (type.flags & TypeFlags.Conditional) { + if (type.flags & ts.TypeFlags.Conditional) { // The root object represents the origin of the conditional type - return (type as ConditionalType).root; + return (type as ts.ConditionalType).root; } return type; } - function isPropertyIdenticalTo(sourceProp: Symbol, targetProp: Symbol): boolean { - return compareProperties(sourceProp, targetProp, compareTypesIdentical) !== Ternary.False; + function isPropertyIdenticalTo(sourceProp: ts.Symbol, targetProp: ts.Symbol): boolean { + return compareProperties(sourceProp, targetProp, compareTypesIdentical) !== ts.Ternary.False; } - function compareProperties(sourceProp: Symbol, targetProp: Symbol, compareTypes: (source: Type, target: Type) => Ternary): Ternary { + function compareProperties(sourceProp: ts.Symbol, targetProp: ts.Symbol, compareTypes: (source: ts.Type, target: ts.Type) => ts.Ternary): ts.Ternary { // Two members are considered identical when // - they are public properties with identical names, optionality, and types, // - they are private or protected properties originating in the same declaration and having identical types if (sourceProp === targetProp) { - return Ternary.True; + return ts.Ternary.True; } - const sourcePropAccessibility = getDeclarationModifierFlagsFromSymbol(sourceProp) & ModifierFlags.NonPublicAccessibilityModifier; - const targetPropAccessibility = getDeclarationModifierFlagsFromSymbol(targetProp) & ModifierFlags.NonPublicAccessibilityModifier; + const sourcePropAccessibility = ts.getDeclarationModifierFlagsFromSymbol(sourceProp) & ts.ModifierFlags.NonPublicAccessibilityModifier; + const targetPropAccessibility = ts.getDeclarationModifierFlagsFromSymbol(targetProp) & ts.ModifierFlags.NonPublicAccessibilityModifier; if (sourcePropAccessibility !== targetPropAccessibility) { - return Ternary.False; + return ts.Ternary.False; } if (sourcePropAccessibility) { if (getTargetSymbol(sourceProp) !== getTargetSymbol(targetProp)) { - return Ternary.False; + return ts.Ternary.False; } } else { - if ((sourceProp.flags & SymbolFlags.Optional) !== (targetProp.flags & SymbolFlags.Optional)) { - return Ternary.False; + if ((sourceProp.flags & ts.SymbolFlags.Optional) !== (targetProp.flags & ts.SymbolFlags.Optional)) { + return ts.Ternary.False; } } if (isReadonlySymbol(sourceProp) !== isReadonlySymbol(targetProp)) { - return Ternary.False; + return ts.Ternary.False; } return compareTypes(getTypeOfSymbol(sourceProp), getTypeOfSymbol(targetProp)); } - function isMatchingSignature(source: Signature, target: Signature, partialMatch: boolean) { + function isMatchingSignature(source: ts.Signature, target: ts.Signature, partialMatch: boolean) { const sourceParameterCount = getParameterCount(source); const targetParameterCount = getParameterCount(target); const sourceMinArgumentCount = getMinArgumentCount(source); @@ -21007,17 +20472,17 @@ namespace ts { /** * See signatureRelatedTo, compareSignaturesIdentical */ - function compareSignaturesIdentical(source: Signature, target: Signature, partialMatch: boolean, ignoreThisTypes: boolean, ignoreReturnTypes: boolean, compareTypes: (s: Type, t: Type) => Ternary): Ternary { + function compareSignaturesIdentical(source: ts.Signature, target: ts.Signature, partialMatch: boolean, ignoreThisTypes: boolean, ignoreReturnTypes: boolean, compareTypes: (s: ts.Type, t: ts.Type) => ts.Ternary): ts.Ternary { // TODO (drosen): De-duplicate code between related functions. if (source === target) { - return Ternary.True; + return ts.Ternary.True; } if (!(isMatchingSignature(source, target, partialMatch))) { - return Ternary.False; + return ts.Ternary.False; } // Check that the two signatures have the same number of type parameters. - if (length(source.typeParameters) !== length(target.typeParameters)) { - return Ternary.False; + if (ts.length(source.typeParameters) !== ts.length(target.typeParameters)) { + return ts.Ternary.False; } // Check that type parameter constraints and defaults match. If they do, instantiate the source // signature with the type parameters of the target signature and continue the comparison. @@ -21028,12 +20493,12 @@ namespace ts { const t = target.typeParameters[i]; if (!(s === t || compareTypes(instantiateType(getConstraintFromTypeParameter(s), mapper) || unknownType, getConstraintFromTypeParameter(t) || unknownType) && compareTypes(instantiateType(getDefaultFromTypeParameter(s), mapper) || unknownType, getDefaultFromTypeParameter(t) || unknownType))) { - return Ternary.False; + return ts.Ternary.False; } } source = instantiateSignature(source, mapper, /*eraseTypeParameters*/ true); } - let result = Ternary.True; + let result = ts.Ternary.True; if (!ignoreThisTypes) { const sourceThisType = getThisTypeOfSignature(source); if (sourceThisType) { @@ -21041,7 +20506,7 @@ namespace ts { if (targetThisType) { const related = compareTypes(sourceThisType, targetThisType); if (!related) { - return Ternary.False; + return ts.Ternary.False; } result &= related; } @@ -21053,7 +20518,7 @@ namespace ts { const t = getTypeAtPosition(target, i); const related = compareTypes(t, s); if (!related) { - return Ternary.False; + return ts.Ternary.False; } result &= related; } @@ -21067,15 +20532,15 @@ namespace ts { return result; } - function compareTypePredicatesIdentical(source: TypePredicate | undefined, target: TypePredicate | undefined, compareTypes: (s: Type, t: Type) => Ternary): Ternary { - return !(source && target && typePredicateKindsMatch(source, target)) ? Ternary.False : - source.type === target.type ? Ternary.True : + function compareTypePredicatesIdentical(source: ts.TypePredicate | undefined, target: ts.TypePredicate | undefined, compareTypes: (s: ts.Type, t: ts.Type) => ts.Ternary): ts.Ternary { + return !(source && target && typePredicateKindsMatch(source, target)) ? ts.Ternary.False : + source.type === target.type ? ts.Ternary.True : source.type && target.type ? compareTypes(source.type, target.type) : - Ternary.False; + ts.Ternary.False; } - function literalTypesWithSameBaseType(types: Type[]): boolean { - let commonBaseType: Type | undefined; + function literalTypesWithSameBaseType(types: ts.Type[]): boolean { + let commonBaseType: ts.Type | undefined; for (const t of types) { const baseType = getBaseTypeOfLiteralType(t); if (!commonBaseType) { @@ -21091,70 +20556,70 @@ namespace ts { // When the candidate types are all literal types with the same base type, return a union // of those literal types. Otherwise, return the leftmost type for which no type to the // right is a supertype. - function getSupertypeOrUnion(types: Type[]): Type { + function getSupertypeOrUnion(types: ts.Type[]): ts.Type { if (types.length === 1) { return types[0]; } return literalTypesWithSameBaseType(types) ? getUnionType(types) : - reduceLeft(types, (s, t) => isTypeSubtypeOf(s, t) ? t : s)!; + ts.reduceLeft(types, (s, t) => isTypeSubtypeOf(s, t) ? t : s)!; } - function getCommonSupertype(types: Type[]): Type { + function getCommonSupertype(types: ts.Type[]): ts.Type { if (!strictNullChecks) { return getSupertypeOrUnion(types); } - const primaryTypes = filter(types, t => !(t.flags & TypeFlags.Nullable)); + const primaryTypes = ts.filter(types, t => !(t.flags & ts.TypeFlags.Nullable)); return primaryTypes.length ? - getNullableType(getSupertypeOrUnion(primaryTypes), getFalsyFlagsOfTypes(types) & TypeFlags.Nullable) : - getUnionType(types, UnionReduction.Subtype); + getNullableType(getSupertypeOrUnion(primaryTypes), getFalsyFlagsOfTypes(types) & ts.TypeFlags.Nullable) : + getUnionType(types, ts.UnionReduction.Subtype); } // Return the leftmost type for which no type to the right is a subtype. - function getCommonSubtype(types: Type[]) { - return reduceLeft(types, (s, t) => isTypeSubtypeOf(t, s) ? t : s)!; + function getCommonSubtype(types: ts.Type[]) { + return ts.reduceLeft(types, (s, t) => isTypeSubtypeOf(t, s) ? t : s)!; } - function isArrayType(type: Type): type is TypeReference { - return !!(getObjectFlags(type) & ObjectFlags.Reference) && ((type as TypeReference).target === globalArrayType || (type as TypeReference).target === globalReadonlyArrayType); + function isArrayType(type: ts.Type): type is ts.TypeReference { + return !!(ts.getObjectFlags(type) & ts.ObjectFlags.Reference) && ((type as ts.TypeReference).target === globalArrayType || (type as ts.TypeReference).target === globalReadonlyArrayType); } - function isReadonlyArrayType(type: Type): boolean { - return !!(getObjectFlags(type) & ObjectFlags.Reference) && (type as TypeReference).target === globalReadonlyArrayType; + function isReadonlyArrayType(type: ts.Type): boolean { + return !!(ts.getObjectFlags(type) & ts.ObjectFlags.Reference) && (type as ts.TypeReference).target === globalReadonlyArrayType; } - function isArrayOrTupleType(type: Type): type is TypeReference { + function isArrayOrTupleType(type: ts.Type): type is ts.TypeReference { return isArrayType(type) || isTupleType(type); } - function isMutableArrayOrTuple(type: Type): boolean { + function isMutableArrayOrTuple(type: ts.Type): boolean { return isArrayType(type) && !isReadonlyArrayType(type) || isTupleType(type) && !type.target.readonly; } - function getElementTypeOfArrayType(type: Type): Type | undefined { + function getElementTypeOfArrayType(type: ts.Type): ts.Type | undefined { return isArrayType(type) ? getTypeArguments(type)[0] : undefined; } - function isArrayLikeType(type: Type): boolean { + function isArrayLikeType(type: ts.Type): boolean { // A type is array-like if it is a reference to the global Array or global ReadonlyArray type, // or if it is not the undefined or null type and if it is assignable to ReadonlyArray - return isArrayType(type) || !(type.flags & TypeFlags.Nullable) && isTypeAssignableTo(type, anyReadonlyArrayType); + return isArrayType(type) || !(type.flags & ts.TypeFlags.Nullable) && isTypeAssignableTo(type, anyReadonlyArrayType); } - function getSingleBaseForNonAugmentingSubtype(type: Type) { - if (!(getObjectFlags(type) & ObjectFlags.Reference) || !(getObjectFlags((type as TypeReference).target) & ObjectFlags.ClassOrInterface)) { + function getSingleBaseForNonAugmentingSubtype(type: ts.Type) { + if (!(ts.getObjectFlags(type) & ts.ObjectFlags.Reference) || !(ts.getObjectFlags((type as ts.TypeReference).target) & ts.ObjectFlags.ClassOrInterface)) { return undefined; } - if (getObjectFlags(type) & ObjectFlags.IdenticalBaseTypeCalculated) { - return getObjectFlags(type) & ObjectFlags.IdenticalBaseTypeExists ? (type as TypeReference).cachedEquivalentBaseType : undefined; + if (ts.getObjectFlags(type) & ts.ObjectFlags.IdenticalBaseTypeCalculated) { + return ts.getObjectFlags(type) & ts.ObjectFlags.IdenticalBaseTypeExists ? (type as ts.TypeReference).cachedEquivalentBaseType : undefined; } - (type as TypeReference).objectFlags |= ObjectFlags.IdenticalBaseTypeCalculated; - const target = (type as TypeReference).target as InterfaceType; - if (getObjectFlags(target) & ObjectFlags.Class) { + (type as ts.TypeReference).objectFlags |= ts.ObjectFlags.IdenticalBaseTypeCalculated; + const target = (type as ts.TypeReference).target as ts.InterfaceType; + if (ts.getObjectFlags(target) & ts.ObjectFlags.Class) { const baseTypeNode = getBaseTypeNodeOfClass(target); // A base type expression may circularly reference the class itself (e.g. as an argument to function call), so we only // check for base types specified as simple qualified names. - if (baseTypeNode && baseTypeNode.expression.kind !== SyntaxKind.Identifier && baseTypeNode.expression.kind !== SyntaxKind.PropertyAccessExpression) { + if (baseTypeNode && baseTypeNode.expression.kind !== ts.SyntaxKind.Identifier && baseTypeNode.expression.kind !== ts.SyntaxKind.PropertyAccessExpression) { return undefined; } } @@ -21165,99 +20630,99 @@ namespace ts { if (getMembersOfSymbol(type.symbol).size) { return undefined; // If the interface has any members, they may subtype members in the base, so we should do a full structural comparison } - let instantiatedBase = !length(target.typeParameters) ? bases[0] : instantiateType(bases[0], createTypeMapper(target.typeParameters!, getTypeArguments(type as TypeReference).slice(0, target.typeParameters!.length))); - if (length(getTypeArguments(type as TypeReference)) > length(target.typeParameters)) { - instantiatedBase = getTypeWithThisArgument(instantiatedBase, last(getTypeArguments(type as TypeReference))); + let instantiatedBase = !ts.length(target.typeParameters) ? bases[0] : instantiateType(bases[0], createTypeMapper(target.typeParameters!, getTypeArguments(type as ts.TypeReference).slice(0, target.typeParameters!.length))); + if (ts.length(getTypeArguments(type as ts.TypeReference)) > ts.length(target.typeParameters)) { + instantiatedBase = getTypeWithThisArgument(instantiatedBase, ts.last(getTypeArguments(type as ts.TypeReference))); } - (type as TypeReference).objectFlags |= ObjectFlags.IdenticalBaseTypeExists; - return (type as TypeReference).cachedEquivalentBaseType = instantiatedBase; + (type as ts.TypeReference).objectFlags |= ts.ObjectFlags.IdenticalBaseTypeExists; + return (type as ts.TypeReference).cachedEquivalentBaseType = instantiatedBase; } - function isEmptyLiteralType(type: Type): boolean { + function isEmptyLiteralType(type: ts.Type): boolean { return strictNullChecks ? type === implicitNeverType : type === undefinedWideningType; } - function isEmptyArrayLiteralType(type: Type): boolean { + function isEmptyArrayLiteralType(type: ts.Type): boolean { const elementType = getElementTypeOfArrayType(type); return !!elementType && isEmptyLiteralType(elementType); } - function isTupleLikeType(type: Type): boolean { - return isTupleType(type) || !!getPropertyOfType(type, "0" as __String); + function isTupleLikeType(type: ts.Type): boolean { + return isTupleType(type) || !!getPropertyOfType(type, "0" as ts.__String); } - function isArrayOrTupleLikeType(type: Type): boolean { + function isArrayOrTupleLikeType(type: ts.Type): boolean { return isArrayLikeType(type) || isTupleLikeType(type); } - function getTupleElementType(type: Type, index: number) { - const propType = getTypeOfPropertyOfType(type, "" + index as __String); + function getTupleElementType(type: ts.Type, index: number) { + const propType = getTypeOfPropertyOfType(type, "" + index as ts.__String); if (propType) { return propType; } if (everyType(type, isTupleType)) { - return mapType(type, t => getRestTypeOfTupleType(t as TupleTypeReference) || undefinedType); + return mapType(type, t => getRestTypeOfTupleType(t as ts.TupleTypeReference) || undefinedType); } return undefined; } - function isNeitherUnitTypeNorNever(type: Type): boolean { - return !(type.flags & (TypeFlags.Unit | TypeFlags.Never)); + function isNeitherUnitTypeNorNever(type: ts.Type): boolean { + return !(type.flags & (ts.TypeFlags.Unit | ts.TypeFlags.Never)); } - function isUnitType(type: Type): boolean { - return !!(type.flags & TypeFlags.Unit); + function isUnitType(type: ts.Type): boolean { + return !!(type.flags & ts.TypeFlags.Unit); } - function isUnitLikeType(type: Type): boolean { - return type.flags & TypeFlags.Intersection ? some((type as IntersectionType).types, isUnitType) : - !!(type.flags & TypeFlags.Unit); + function isUnitLikeType(type: ts.Type): boolean { + return type.flags & ts.TypeFlags.Intersection ? ts.some((type as ts.IntersectionType).types, isUnitType) : + !!(type.flags & ts.TypeFlags.Unit); } - function extractUnitType(type: Type) { - return type.flags & TypeFlags.Intersection ? find((type as IntersectionType).types, isUnitType) || type : type; + function extractUnitType(type: ts.Type) { + return type.flags & ts.TypeFlags.Intersection ? ts.find((type as ts.IntersectionType).types, isUnitType) || type : type; } - function isLiteralType(type: Type): boolean { - return type.flags & TypeFlags.Boolean ? true : - type.flags & TypeFlags.Union ? type.flags & TypeFlags.EnumLiteral ? true : every((type as UnionType).types, isUnitType) : + function isLiteralType(type: ts.Type): boolean { + return type.flags & ts.TypeFlags.Boolean ? true : + type.flags & ts.TypeFlags.Union ? type.flags & ts.TypeFlags.EnumLiteral ? true : ts.every((type as ts.UnionType).types, isUnitType) : isUnitType(type); } - function getBaseTypeOfLiteralType(type: Type): Type { - return type.flags & TypeFlags.EnumLiteral ? getBaseTypeOfEnumLiteralType(type as LiteralType) : - type.flags & (TypeFlags.StringLiteral | TypeFlags.TemplateLiteral | TypeFlags.StringMapping) ? stringType : - type.flags & TypeFlags.NumberLiteral ? numberType : - type.flags & TypeFlags.BigIntLiteral ? bigintType : - type.flags & TypeFlags.BooleanLiteral ? booleanType : - type.flags & TypeFlags.Union ? mapType(type as UnionType, getBaseTypeOfLiteralType) : + function getBaseTypeOfLiteralType(type: ts.Type): ts.Type { + return type.flags & ts.TypeFlags.EnumLiteral ? getBaseTypeOfEnumLiteralType(type as ts.LiteralType) : + type.flags & (ts.TypeFlags.StringLiteral | ts.TypeFlags.TemplateLiteral | ts.TypeFlags.StringMapping) ? stringType : + type.flags & ts.TypeFlags.NumberLiteral ? numberType : + type.flags & ts.TypeFlags.BigIntLiteral ? bigintType : + type.flags & ts.TypeFlags.BooleanLiteral ? booleanType : + type.flags & ts.TypeFlags.Union ? mapType(type as ts.UnionType, getBaseTypeOfLiteralType) : type; } - function getWidenedLiteralType(type: Type): Type { - return type.flags & TypeFlags.EnumLiteral && isFreshLiteralType(type) ? getBaseTypeOfEnumLiteralType(type as LiteralType) : - type.flags & TypeFlags.StringLiteral && isFreshLiteralType(type) ? stringType : - type.flags & TypeFlags.NumberLiteral && isFreshLiteralType(type) ? numberType : - type.flags & TypeFlags.BigIntLiteral && isFreshLiteralType(type) ? bigintType : - type.flags & TypeFlags.BooleanLiteral && isFreshLiteralType(type) ? booleanType : - type.flags & TypeFlags.Union ? mapType(type as UnionType, getWidenedLiteralType) : + function getWidenedLiteralType(type: ts.Type): ts.Type { + return type.flags & ts.TypeFlags.EnumLiteral && isFreshLiteralType(type) ? getBaseTypeOfEnumLiteralType(type as ts.LiteralType) : + type.flags & ts.TypeFlags.StringLiteral && isFreshLiteralType(type) ? stringType : + type.flags & ts.TypeFlags.NumberLiteral && isFreshLiteralType(type) ? numberType : + type.flags & ts.TypeFlags.BigIntLiteral && isFreshLiteralType(type) ? bigintType : + type.flags & ts.TypeFlags.BooleanLiteral && isFreshLiteralType(type) ? booleanType : + type.flags & ts.TypeFlags.Union ? mapType(type as ts.UnionType, getWidenedLiteralType) : type; } - function getWidenedUniqueESSymbolType(type: Type): Type { - return type.flags & TypeFlags.UniqueESSymbol ? esSymbolType : - type.flags & TypeFlags.Union ? mapType(type as UnionType, getWidenedUniqueESSymbolType) : + function getWidenedUniqueESSymbolType(type: ts.Type): ts.Type { + return type.flags & ts.TypeFlags.UniqueESSymbol ? esSymbolType : + type.flags & ts.TypeFlags.Union ? mapType(type as ts.UnionType, getWidenedUniqueESSymbolType) : type; } - function getWidenedLiteralLikeTypeForContextualType(type: Type, contextualType: Type | undefined) { + function getWidenedLiteralLikeTypeForContextualType(type: ts.Type, contextualType: ts.Type | undefined) { if (!isLiteralOfContextualType(type, contextualType)) { type = getWidenedUniqueESSymbolType(getWidenedLiteralType(type)); } return type; } - function getWidenedLiteralLikeTypeForContextualReturnTypeIfNeeded(type: Type | undefined, contextualSignatureReturnType: Type | undefined, isAsync: boolean) { + function getWidenedLiteralLikeTypeForContextualReturnTypeIfNeeded(type: ts.Type | undefined, contextualSignatureReturnType: ts.Type | undefined, isAsync: boolean) { if (type && isUnitType(type)) { const contextualType = !contextualSignatureReturnType ? undefined : isAsync ? getPromisedTypeOfPromise(contextualSignatureReturnType) : @@ -21267,7 +20732,7 @@ namespace ts { return type; } - function getWidenedLiteralLikeTypeForContextualIterationTypeIfNeeded(type: Type | undefined, contextualSignatureReturnType: Type | undefined, kind: IterationTypeKind, isAsyncGenerator: boolean) { + function getWidenedLiteralLikeTypeForContextualIterationTypeIfNeeded(type: ts.Type | undefined, contextualSignatureReturnType: ts.Type | undefined, kind: IterationTypeKind, isAsyncGenerator: boolean) { if (type && isUnitType(type)) { const contextualType = !contextualSignatureReturnType ? undefined : getIterationTypeOfGeneratorFunctionReturnType(kind, contextualSignatureReturnType, isAsyncGenerator); @@ -21280,52 +20745,52 @@ namespace ts { * Check if a Type was written as a tuple type literal. * Prefer using isTupleLikeType() unless the use of `elementTypes`/`getTypeArguments` is required. */ - function isTupleType(type: Type): type is TupleTypeReference { - return !!(getObjectFlags(type) & ObjectFlags.Reference && (type as TypeReference).target.objectFlags & ObjectFlags.Tuple); + function isTupleType(type: ts.Type): type is ts.TupleTypeReference { + return !!(ts.getObjectFlags(type) & ts.ObjectFlags.Reference && (type as ts.TypeReference).target.objectFlags & ts.ObjectFlags.Tuple); } - function isGenericTupleType(type: Type): type is TupleTypeReference { - return isTupleType(type) && !!(type.target.combinedFlags & ElementFlags.Variadic); + function isGenericTupleType(type: ts.Type): type is ts.TupleTypeReference { + return isTupleType(type) && !!(type.target.combinedFlags & ts.ElementFlags.Variadic); } - function isSingleElementGenericTupleType(type: Type): type is TupleTypeReference { + function isSingleElementGenericTupleType(type: ts.Type): type is ts.TupleTypeReference { return isGenericTupleType(type) && type.target.elementFlags.length === 1; } - function getRestTypeOfTupleType(type: TupleTypeReference) { + function getRestTypeOfTupleType(type: ts.TupleTypeReference) { return getElementTypeOfSliceOfTupleType(type, type.target.fixedLength); } - function getRestArrayTypeOfTupleType(type: TupleTypeReference) { + function getRestArrayTypeOfTupleType(type: ts.TupleTypeReference) { const restType = getRestTypeOfTupleType(type); return restType && createArrayType(restType); } - function getElementTypeOfSliceOfTupleType(type: TupleTypeReference, index: number, endSkipCount = 0, writing = false) { + function getElementTypeOfSliceOfTupleType(type: ts.TupleTypeReference, index: number, endSkipCount = 0, writing = false) { const length = getTypeReferenceArity(type) - endSkipCount; if (index < length) { const typeArguments = getTypeArguments(type); - const elementTypes: Type[] = []; + const elementTypes: ts.Type[] = []; for (let i = index; i < length; i++) { const t = typeArguments[i]; - elementTypes.push(type.target.elementFlags[i] & ElementFlags.Variadic ? getIndexedAccessType(t, numberType) : t); + elementTypes.push(type.target.elementFlags[i] & ts.ElementFlags.Variadic ? getIndexedAccessType(t, numberType) : t); } return writing ? getIntersectionType(elementTypes) : getUnionType(elementTypes); } return undefined; } - function isTupleTypeStructureMatching(t1: TupleTypeReference, t2: TupleTypeReference) { + function isTupleTypeStructureMatching(t1: ts.TupleTypeReference, t2: ts.TupleTypeReference) { return getTypeReferenceArity(t1) === getTypeReferenceArity(t2) && - every(t1.target.elementFlags, (f, i) => (f & ElementFlags.Variable) === (t2.target.elementFlags[i] & ElementFlags.Variable)); + ts.every(t1.target.elementFlags, (f, i) => (f & ts.ElementFlags.Variable) === (t2.target.elementFlags[i] & ts.ElementFlags.Variable)); } - function isZeroBigInt({value}: BigIntLiteralType) { + function isZeroBigInt({ value }: ts.BigIntLiteralType) { return value.base10Value === "0"; } - function getFalsyFlagsOfTypes(types: Type[]): TypeFlags { - let result: TypeFlags = 0; + function getFalsyFlagsOfTypes(types: ts.Type[]): ts.TypeFlags { + let result: ts.TypeFlags = 0; for (const t of types) { result |= getFalsyFlags(t); } @@ -21335,35 +20800,34 @@ namespace ts { // Returns the String, Number, Boolean, StringLiteral, NumberLiteral, BooleanLiteral, Void, Undefined, or Null // flags for the string, number, boolean, "", 0, false, void, undefined, or null types respectively. Returns // no flags for all other types (including non-falsy literal types). - function getFalsyFlags(type: Type): TypeFlags { - return type.flags & TypeFlags.Union ? getFalsyFlagsOfTypes((type as UnionType).types) : - type.flags & TypeFlags.StringLiteral ? (type as StringLiteralType).value === "" ? TypeFlags.StringLiteral : 0 : - type.flags & TypeFlags.NumberLiteral ? (type as NumberLiteralType).value === 0 ? TypeFlags.NumberLiteral : 0 : - type.flags & TypeFlags.BigIntLiteral ? isZeroBigInt(type as BigIntLiteralType) ? TypeFlags.BigIntLiteral : 0 : - type.flags & TypeFlags.BooleanLiteral ? (type === falseType || type === regularFalseType) ? TypeFlags.BooleanLiteral : 0 : - type.flags & TypeFlags.PossiblyFalsy; - } - - function removeDefinitelyFalsyTypes(type: Type): Type { - return getFalsyFlags(type) & TypeFlags.DefinitelyFalsy ? - filterType(type, t => !(getFalsyFlags(t) & TypeFlags.DefinitelyFalsy)) : + function getFalsyFlags(type: ts.Type): ts.TypeFlags { + return type.flags & ts.TypeFlags.Union ? getFalsyFlagsOfTypes((type as ts.UnionType).types) : + type.flags & ts.TypeFlags.StringLiteral ? (type as ts.StringLiteralType).value === "" ? ts.TypeFlags.StringLiteral : 0 : + type.flags & ts.TypeFlags.NumberLiteral ? (type as ts.NumberLiteralType).value === 0 ? ts.TypeFlags.NumberLiteral : 0 : + type.flags & ts.TypeFlags.BigIntLiteral ? isZeroBigInt(type as ts.BigIntLiteralType) ? ts.TypeFlags.BigIntLiteral : 0 : + type.flags & ts.TypeFlags.BooleanLiteral ? (type === falseType || type === regularFalseType) ? ts.TypeFlags.BooleanLiteral : 0 : + type.flags & ts.TypeFlags.PossiblyFalsy; + } + function removeDefinitelyFalsyTypes(type: ts.Type): ts.Type { + return getFalsyFlags(type) & ts.TypeFlags.DefinitelyFalsy ? + filterType(type, t => !(getFalsyFlags(t) & ts.TypeFlags.DefinitelyFalsy)) : type; } - function extractDefinitelyFalsyTypes(type: Type): Type { + function extractDefinitelyFalsyTypes(type: ts.Type): ts.Type { return mapType(type, getDefinitelyFalsyPartOfType); } - function getDefinitelyFalsyPartOfType(type: Type): Type { - return type.flags & TypeFlags.String ? emptyStringType : - type.flags & TypeFlags.Number ? zeroType : - type.flags & TypeFlags.BigInt ? zeroBigIntType : + function getDefinitelyFalsyPartOfType(type: ts.Type): ts.Type { + return type.flags & ts.TypeFlags.String ? emptyStringType : + type.flags & ts.TypeFlags.Number ? zeroType : + type.flags & ts.TypeFlags.BigInt ? zeroBigIntType : type === regularFalseType || type === falseType || - type.flags & (TypeFlags.Void | TypeFlags.Undefined | TypeFlags.Null | TypeFlags.AnyOrUnknown) || - type.flags & TypeFlags.StringLiteral && (type as StringLiteralType).value === "" || - type.flags & TypeFlags.NumberLiteral && (type as NumberLiteralType).value === 0 || - type.flags & TypeFlags.BigIntLiteral && isZeroBigInt(type as BigIntLiteralType) ? type : + type.flags & (ts.TypeFlags.Void | ts.TypeFlags.Undefined | ts.TypeFlags.Null | ts.TypeFlags.AnyOrUnknown) || + type.flags & ts.TypeFlags.StringLiteral && (type as ts.StringLiteralType).value === "" || + type.flags & ts.TypeFlags.NumberLiteral && (type as ts.NumberLiteralType).value === 0 || + type.flags & ts.TypeFlags.BigIntLiteral && isZeroBigInt(type as ts.BigIntLiteralType) ? type : neverType; } @@ -21372,26 +20836,26 @@ namespace ts { * @param type - type to add undefined and/or null to if not present * @param flags - Either TypeFlags.Undefined or TypeFlags.Null, or both */ - function getNullableType(type: Type, flags: TypeFlags): Type { - const missing = (flags & ~type.flags) & (TypeFlags.Undefined | TypeFlags.Null); + function getNullableType(type: ts.Type, flags: ts.TypeFlags): ts.Type { + const missing = (flags & ~type.flags) & (ts.TypeFlags.Undefined | ts.TypeFlags.Null); return missing === 0 ? type : - missing === TypeFlags.Undefined ? getUnionType([type, undefinedType]) : - missing === TypeFlags.Null ? getUnionType([type, nullType]) : + missing === ts.TypeFlags.Undefined ? getUnionType([type, undefinedType]) : + missing === ts.TypeFlags.Null ? getUnionType([type, nullType]) : getUnionType([type, undefinedType, nullType]); } - function getOptionalType(type: Type, isProperty = false): Type { - Debug.assert(strictNullChecks); - return type.flags & TypeFlags.Undefined ? type : getUnionType([type, isProperty ? missingType : undefinedType]); + function getOptionalType(type: ts.Type, isProperty = false): ts.Type { + ts.Debug.assert(strictNullChecks); + return type.flags & ts.TypeFlags.Undefined ? type : getUnionType([type, isProperty ? missingType : undefinedType]); } - function getGlobalNonNullableTypeInstantiation(type: Type) { + function getGlobalNonNullableTypeInstantiation(type: ts.Type) { // First reduce away any constituents that are assignable to 'undefined' or 'null'. This not only eliminates // 'undefined' and 'null', but also higher-order types such as a type parameter 'U extends undefined | null' // that isn't eliminated by a NonNullable instantiation. const reducedType = getTypeWithFacts(type, TypeFacts.NEUndefinedOrNull); if (!deferredGlobalNonNullableTypeAlias) { - deferredGlobalNonNullableTypeAlias = getGlobalSymbol("NonNullable" as __String, SymbolFlags.TypeAlias, /*diagnostic*/ undefined) || unknownSymbol; + deferredGlobalNonNullableTypeAlias = getGlobalSymbol("NonNullable" as ts.__String, ts.SymbolFlags.TypeAlias, /*diagnostic*/ undefined) || unknownSymbol; } // If the NonNullable type is available, return an instantiation. Otherwise just return the reduced type. return deferredGlobalNonNullableTypeAlias !== unknownSymbol ? @@ -21399,37 +20863,37 @@ namespace ts { reducedType; } - function getNonNullableType(type: Type): Type { + function getNonNullableType(type: ts.Type): ts.Type { return strictNullChecks ? getGlobalNonNullableTypeInstantiation(type) : type; } - function addOptionalTypeMarker(type: Type) { + function addOptionalTypeMarker(type: ts.Type) { return strictNullChecks ? getUnionType([type, optionalType]) : type; } - function removeOptionalTypeMarker(type: Type): Type { + function removeOptionalTypeMarker(type: ts.Type): ts.Type { return strictNullChecks ? removeType(type, optionalType) : type; } - function propagateOptionalTypeMarker(type: Type, node: OptionalChain, wasOptional: boolean) { - return wasOptional ? isOutermostOptionalChain(node) ? getOptionalType(type) : addOptionalTypeMarker(type) : type; + function propagateOptionalTypeMarker(type: ts.Type, node: ts.OptionalChain, wasOptional: boolean) { + return wasOptional ? ts.isOutermostOptionalChain(node) ? getOptionalType(type) : addOptionalTypeMarker(type) : type; } - function getOptionalExpressionType(exprType: Type, expression: Expression) { - return isExpressionOfOptionalChainRoot(expression) ? getNonNullableType(exprType) : - isOptionalChain(expression) ? removeOptionalTypeMarker(exprType) : + function getOptionalExpressionType(exprType: ts.Type, expression: ts.Expression) { + return ts.isExpressionOfOptionalChainRoot(expression) ? getNonNullableType(exprType) : + ts.isOptionalChain(expression) ? removeOptionalTypeMarker(exprType) : exprType; } - function removeMissingType(type: Type, isOptional: boolean) { + function removeMissingType(type: ts.Type, isOptional: boolean) { return exactOptionalPropertyTypes && isOptional ? removeType(type, missingType) : type; } - function containsMissingType(type: Type) { - return exactOptionalPropertyTypes && (type === missingType || type.flags & TypeFlags.Union && containsType((type as UnionType).types, missingType)); + function containsMissingType(type: ts.Type) { + return exactOptionalPropertyTypes && (type === missingType || type.flags & ts.TypeFlags.Union && containsType((type as ts.UnionType).types, missingType)); } - function removeMissingOrUndefinedType(type: Type): Type { + function removeMissingOrUndefinedType(type: ts.Type): ts.Type { return exactOptionalPropertyTypes ? removeType(type, missingType) : getTypeWithFacts(type, TypeFacts.NEUndefined); } @@ -21453,28 +20917,25 @@ namespace ts { * @param source * @param target */ - function isCoercibleUnderDoubleEquals(source: Type, target: Type): boolean { - return ((source.flags & (TypeFlags.Number | TypeFlags.String | TypeFlags.BooleanLiteral)) !== 0) - && ((target.flags & (TypeFlags.Number | TypeFlags.String | TypeFlags.Boolean)) !== 0); + function isCoercibleUnderDoubleEquals(source: ts.Type, target: ts.Type): boolean { + return ((source.flags & (ts.TypeFlags.Number | ts.TypeFlags.String | ts.TypeFlags.BooleanLiteral)) !== 0) + && ((target.flags & (ts.TypeFlags.Number | ts.TypeFlags.String | ts.TypeFlags.Boolean)) !== 0); } /** * Return true if type was inferred from an object literal, written as an object type literal, or is the shape of a module * with no call or construct signatures. */ - function isObjectTypeWithInferableIndex(type: Type): boolean { - return type.flags & TypeFlags.Intersection - ? every((type as IntersectionType).types, isObjectTypeWithInferableIndex) - : !!( - type.symbol - && (type.symbol.flags & (SymbolFlags.ObjectLiteral | SymbolFlags.TypeLiteral | SymbolFlags.Enum | SymbolFlags.ValueModule)) !== 0 - && !(type.symbol.flags & SymbolFlags.Class) - && !typeHasCallOrConstructSignatures(type) - ) || !!(getObjectFlags(type) & ObjectFlags.ReverseMapped && isObjectTypeWithInferableIndex((type as ReverseMappedType).source)); - } - - function createSymbolWithType(source: Symbol, type: Type | undefined) { - const symbol = createSymbol(source.flags, source.escapedName, getCheckFlags(source) & CheckFlags.Readonly); + function isObjectTypeWithInferableIndex(type: ts.Type): boolean { + return type.flags & ts.TypeFlags.Intersection + ? ts.every((type as ts.IntersectionType).types, isObjectTypeWithInferableIndex) + : !!(type.symbol + && (type.symbol.flags & (ts.SymbolFlags.ObjectLiteral | ts.SymbolFlags.TypeLiteral | ts.SymbolFlags.Enum | ts.SymbolFlags.ValueModule)) !== 0 + && !(type.symbol.flags & ts.SymbolFlags.Class) + && !typeHasCallOrConstructSignatures(type)) || !!(ts.getObjectFlags(type) & ts.ObjectFlags.ReverseMapped && isObjectTypeWithInferableIndex((type as ts.ReverseMappedType).source)); + } + function createSymbolWithType(source: ts.Symbol, type: ts.Type | undefined) { + const symbol = createSymbol(source.flags, source.escapedName, ts.getCheckFlags(source) & ts.CheckFlags.Readonly); symbol.declarations = source.declarations; symbol.parent = source.parent; symbol.type = type; @@ -21489,8 +20950,8 @@ namespace ts { return symbol; } - function transformTypeOfMembers(type: Type, f: (propertyType: Type) => Type) { - const members = createSymbolTable(); + function transformTypeOfMembers(type: ts.Type, f: (propertyType: ts.Type) => ts.Type) { + const members = ts.createSymbolTable(); for (const property of getPropertiesOfObjectType(type)) { const original = getTypeOfSymbol(property); const updated = f(original); @@ -21504,31 +20965,31 @@ namespace ts { * create a new that is exempt. Recursively mark object literal members as exempt. * Leave signatures alone since they are not subject to the check. */ - function getRegularTypeOfObjectLiteral(type: Type): Type { - if (!(isObjectLiteralType(type) && getObjectFlags(type) & ObjectFlags.FreshLiteral)) { + function getRegularTypeOfObjectLiteral(type: ts.Type): ts.Type { + if (!(isObjectLiteralType(type) && ts.getObjectFlags(type) & ts.ObjectFlags.FreshLiteral)) { return type; } - const regularType = (type as FreshObjectLiteralType).regularType; + const regularType = (type as ts.FreshObjectLiteralType).regularType; if (regularType) { return regularType; } - const resolved = type as ResolvedType; + const resolved = type as ts.ResolvedType; const members = transformTypeOfMembers(type, getRegularTypeOfObjectLiteral); const regularNew = createAnonymousType(resolved.symbol, members, resolved.callSignatures, resolved.constructSignatures, resolved.indexInfos); regularNew.flags = resolved.flags; - regularNew.objectFlags |= resolved.objectFlags & ~ObjectFlags.FreshLiteral; - (type as FreshObjectLiteralType).regularType = regularNew; + regularNew.objectFlags |= resolved.objectFlags & ~ts.ObjectFlags.FreshLiteral; + (type as ts.FreshObjectLiteralType).regularType = regularNew; return regularNew; } - function createWideningContext(parent: WideningContext | undefined, propertyName: __String | undefined, siblings: Type[] | undefined): WideningContext { + function createWideningContext(parent: ts.WideningContext | undefined, propertyName: ts.__String | undefined, siblings: ts.Type[] | undefined): ts.WideningContext { return { parent, propertyName, siblings, resolvedProperties: undefined }; } - function getSiblingsOfContext(context: WideningContext): Type[] { + function getSiblingsOfContext(context: ts.WideningContext): ts.Type[] { if (!context.siblings) { - const siblings: Type[] = []; + const siblings: ts.Type[] = []; for (const type of getSiblingsOfContext(context.parent!)) { if (isObjectLiteralType(type)) { const prop = getPropertyOfObjectType(type, context.propertyName!); @@ -21544,23 +21005,23 @@ namespace ts { return context.siblings; } - function getPropertiesOfContext(context: WideningContext): Symbol[] { + function getPropertiesOfContext(context: ts.WideningContext): ts.Symbol[] { if (!context.resolvedProperties) { - const names = new Map() as UnderscoreEscapedMap; + const names = new ts.Map() as ts.UnderscoreEscapedMap; for (const t of getSiblingsOfContext(context)) { - if (isObjectLiteralType(t) && !(getObjectFlags(t) & ObjectFlags.ContainsSpread)) { + if (isObjectLiteralType(t) && !(ts.getObjectFlags(t) & ts.ObjectFlags.ContainsSpread)) { for (const prop of getPropertiesOfType(t)) { names.set(prop.escapedName, prop); } } } - context.resolvedProperties = arrayFrom(names.values()); + context.resolvedProperties = ts.arrayFrom(names.values()); } return context.resolvedProperties; } - function getWidenedProperty(prop: Symbol, context: WideningContext | undefined): Symbol { - if (!(prop.flags & SymbolFlags.Property)) { + function getWidenedProperty(prop: ts.Symbol, context: ts.WideningContext | undefined): ts.Symbol { + if (!(prop.flags & ts.SymbolFlags.Property)) { // Since get accessors already widen their return value there is no need to // widen accessor based properties here. return prop; @@ -21571,19 +21032,19 @@ namespace ts { return widened === original ? prop : createSymbolWithType(prop, widened); } - function getUndefinedProperty(prop: Symbol) { + function getUndefinedProperty(prop: ts.Symbol) { const cached = undefinedProperties.get(prop.escapedName); if (cached) { return cached; } const result = createSymbolWithType(prop, missingType); - result.flags |= SymbolFlags.Optional; + result.flags |= ts.SymbolFlags.Optional; undefinedProperties.set(prop.escapedName, result); return result; } - function getWidenedTypeOfObjectLiteral(type: Type, context: WideningContext | undefined): Type { - const members = createSymbolTable(); + function getWidenedTypeOfObjectLiteral(type: ts.Type, context: ts.WideningContext | undefined): ts.Type { + const members = ts.createSymbolTable(); for (const prop of getPropertiesOfObjectType(type)) { members.set(prop.escapedName, getWidenedProperty(prop, context)); } @@ -21594,41 +21055,40 @@ namespace ts { } } } - const result = createAnonymousType(type.symbol, members, emptyArray, emptyArray, - sameMap(getIndexInfosOfType(type), info => createIndexInfo(info.keyType, getWidenedType(info.type), info.isReadonly))); - result.objectFlags |= (getObjectFlags(type) & (ObjectFlags.JSLiteral | ObjectFlags.NonInferrableType)); // Retain js literal flag through widening + const result = createAnonymousType(type.symbol, members, ts.emptyArray, ts.emptyArray, ts.sameMap(getIndexInfosOfType(type), info => createIndexInfo(info.keyType, getWidenedType(info.type), info.isReadonly))); + result.objectFlags |= (ts.getObjectFlags(type) & (ts.ObjectFlags.JSLiteral | ts.ObjectFlags.NonInferrableType)); // Retain js literal flag through widening return result; } - function getWidenedType(type: Type) { + function getWidenedType(type: ts.Type) { return getWidenedTypeWithContext(type, /*context*/ undefined); } - function getWidenedTypeWithContext(type: Type, context: WideningContext | undefined): Type { - if (getObjectFlags(type) & ObjectFlags.RequiresWidening) { + function getWidenedTypeWithContext(type: ts.Type, context: ts.WideningContext | undefined): ts.Type { + if (ts.getObjectFlags(type) & ts.ObjectFlags.RequiresWidening) { if (context === undefined && type.widened) { return type.widened; } - let result: Type | undefined; - if (type.flags & (TypeFlags.Any | TypeFlags.Nullable)) { + let result: ts.Type | undefined; + if (type.flags & (ts.TypeFlags.Any | ts.TypeFlags.Nullable)) { result = anyType; } else if (isObjectLiteralType(type)) { result = getWidenedTypeOfObjectLiteral(type, context); } - else if (type.flags & TypeFlags.Union) { - const unionContext = context || createWideningContext(/*parent*/ undefined, /*propertyName*/ undefined, (type as UnionType).types); - const widenedTypes = sameMap((type as UnionType).types, t => t.flags & TypeFlags.Nullable ? t : getWidenedTypeWithContext(t, unionContext)); + else if (type.flags & ts.TypeFlags.Union) { + const unionContext = context || createWideningContext(/*parent*/ undefined, /*propertyName*/ undefined, (type as ts.UnionType).types); + const widenedTypes = ts.sameMap((type as ts.UnionType).types, t => t.flags & ts.TypeFlags.Nullable ? t : getWidenedTypeWithContext(t, unionContext)); // Widening an empty object literal transitions from a highly restrictive type to // a highly inclusive one. For that reason we perform subtype reduction here if the // union includes empty object types (e.g. reducing {} | string to just {}). - result = getUnionType(widenedTypes, some(widenedTypes, isEmptyObjectType) ? UnionReduction.Subtype : UnionReduction.Literal); + result = getUnionType(widenedTypes, ts.some(widenedTypes, isEmptyObjectType) ? ts.UnionReduction.Subtype : ts.UnionReduction.Literal); } - else if (type.flags & TypeFlags.Intersection) { - result = getIntersectionType(sameMap((type as IntersectionType).types, getWidenedType)); + else if (type.flags & ts.TypeFlags.Intersection) { + result = getIntersectionType(ts.sameMap((type as ts.IntersectionType).types, getWidenedType)); } else if (isArrayOrTupleType(type)) { - result = createTypeReference(type.target, sameMap(getTypeArguments(type), getWidenedType)); + result = createTypeReference(type.target, ts.sameMap(getTypeArguments(type), getWidenedType)); } if (result && context === undefined) { type.widened = result; @@ -21649,15 +21109,15 @@ namespace ts { * an object literal property (arbitrarily deeply), this function reports an error. If no error is * reported, reportImplicitAnyError is a suitable fallback to report a general error. */ - function reportWideningErrorsInType(type: Type): boolean { + function reportWideningErrorsInType(type: ts.Type): boolean { let errorReported = false; - if (getObjectFlags(type) & ObjectFlags.ContainsWideningType) { - if (type.flags & TypeFlags.Union) { - if (some((type as UnionType).types, isEmptyObjectType)) { + if (ts.getObjectFlags(type) & ts.ObjectFlags.ContainsWideningType) { + if (type.flags & ts.TypeFlags.Union) { + if (ts.some((type as ts.UnionType).types, isEmptyObjectType)) { errorReported = true; } else { - for (const t of (type as UnionType).types) { + for (const t of (type as ts.UnionType).types) { if (reportWideningErrorsInType(t)) { errorReported = true; } @@ -21674,9 +21134,9 @@ namespace ts { if (isObjectLiteralType(type)) { for (const p of getPropertiesOfObjectType(type)) { const t = getTypeOfSymbol(p); - if (getObjectFlags(t) & ObjectFlags.ContainsWideningType) { + if (ts.getObjectFlags(t) & ts.ObjectFlags.ContainsWideningType) { if (!reportWideningErrorsInType(t)) { - error(p.valueDeclaration, Diagnostics.Object_literal_s_property_0_implicitly_has_an_1_type, symbolToString(p), typeToString(getWidenedType(t))); + error(p.valueDeclaration, ts.Diagnostics.Object_literal_s_property_0_implicitly_has_an_1_type, symbolToString(p), typeToString(getWidenedType(t))); } errorReported = true; } @@ -21686,79 +21146,79 @@ namespace ts { return errorReported; } - function reportImplicitAny(declaration: Declaration, type: Type, wideningKind?: WideningKind) { + function reportImplicitAny(declaration: ts.Declaration, type: ts.Type, wideningKind?: WideningKind) { const typeAsString = typeToString(getWidenedType(type)); - if (isInJSFile(declaration) && !isCheckJsEnabledForFile(getSourceFileOfNode(declaration), compilerOptions)) { + if (ts.isInJSFile(declaration) && !ts.isCheckJsEnabledForFile(ts.getSourceFileOfNode(declaration), compilerOptions)) { // Only report implicit any errors/suggestions in TS and ts-check JS files return; } - let diagnostic: DiagnosticMessage; + let diagnostic: ts.DiagnosticMessage; switch (declaration.kind) { - case SyntaxKind.BinaryExpression: - case SyntaxKind.PropertyDeclaration: - case SyntaxKind.PropertySignature: - diagnostic = noImplicitAny ? Diagnostics.Member_0_implicitly_has_an_1_type : Diagnostics.Member_0_implicitly_has_an_1_type_but_a_better_type_may_be_inferred_from_usage; + case ts.SyntaxKind.BinaryExpression: + case ts.SyntaxKind.PropertyDeclaration: + case ts.SyntaxKind.PropertySignature: + diagnostic = noImplicitAny ? ts.Diagnostics.Member_0_implicitly_has_an_1_type : ts.Diagnostics.Member_0_implicitly_has_an_1_type_but_a_better_type_may_be_inferred_from_usage; break; - case SyntaxKind.Parameter: - const param = declaration as ParameterDeclaration; - if (isIdentifier(param.name) && - (isCallSignatureDeclaration(param.parent) || isMethodSignature(param.parent) || isFunctionTypeNode(param.parent)) && + case ts.SyntaxKind.Parameter: + const param = declaration as ts.ParameterDeclaration; + if (ts.isIdentifier(param.name) && + (ts.isCallSignatureDeclaration(param.parent) || ts.isMethodSignature(param.parent) || ts.isFunctionTypeNode(param.parent)) && param.parent.parameters.indexOf(param) > -1 && - (resolveName(param, param.name.escapedText, SymbolFlags.Type, undefined, param.name.escapedText, /*isUse*/ true) || - param.name.originalKeywordKind && isTypeNodeKind(param.name.originalKeywordKind))) { + (resolveName(param, param.name.escapedText, ts.SymbolFlags.Type, undefined, param.name.escapedText, /*isUse*/ true) || + param.name.originalKeywordKind && ts.isTypeNodeKind(param.name.originalKeywordKind))) { const newName = "arg" + param.parent.parameters.indexOf(param); - const typeName = declarationNameToString(param.name) + (param.dotDotDotToken ? "[]" : ""); - errorOrSuggestion(noImplicitAny, declaration, Diagnostics.Parameter_has_a_name_but_no_type_Did_you_mean_0_Colon_1, newName, typeName); + const typeName = ts.declarationNameToString(param.name) + (param.dotDotDotToken ? "[]" : ""); + errorOrSuggestion(noImplicitAny, declaration, ts.Diagnostics.Parameter_has_a_name_but_no_type_Did_you_mean_0_Colon_1, newName, typeName); return; } - diagnostic = (declaration as ParameterDeclaration).dotDotDotToken ? - noImplicitAny ? Diagnostics.Rest_parameter_0_implicitly_has_an_any_type : Diagnostics.Rest_parameter_0_implicitly_has_an_any_type_but_a_better_type_may_be_inferred_from_usage : - noImplicitAny ? Diagnostics.Parameter_0_implicitly_has_an_1_type : Diagnostics.Parameter_0_implicitly_has_an_1_type_but_a_better_type_may_be_inferred_from_usage; + diagnostic = (declaration as ts.ParameterDeclaration).dotDotDotToken ? + noImplicitAny ? ts.Diagnostics.Rest_parameter_0_implicitly_has_an_any_type : ts.Diagnostics.Rest_parameter_0_implicitly_has_an_any_type_but_a_better_type_may_be_inferred_from_usage : + noImplicitAny ? ts.Diagnostics.Parameter_0_implicitly_has_an_1_type : ts.Diagnostics.Parameter_0_implicitly_has_an_1_type_but_a_better_type_may_be_inferred_from_usage; break; - case SyntaxKind.BindingElement: - diagnostic = Diagnostics.Binding_element_0_implicitly_has_an_1_type; + case ts.SyntaxKind.BindingElement: + diagnostic = ts.Diagnostics.Binding_element_0_implicitly_has_an_1_type; if (!noImplicitAny) { // Don't issue a suggestion for binding elements since the codefix doesn't yet support them. return; } break; - case SyntaxKind.JSDocFunctionType: - error(declaration, Diagnostics.Function_type_which_lacks_return_type_annotation_implicitly_has_an_0_return_type, typeAsString); + case ts.SyntaxKind.JSDocFunctionType: + error(declaration, ts.Diagnostics.Function_type_which_lacks_return_type_annotation_implicitly_has_an_0_return_type, typeAsString); return; - case SyntaxKind.FunctionDeclaration: - case SyntaxKind.MethodDeclaration: - case SyntaxKind.MethodSignature: - case SyntaxKind.GetAccessor: - case SyntaxKind.SetAccessor: - case SyntaxKind.FunctionExpression: - case SyntaxKind.ArrowFunction: - if (noImplicitAny && !(declaration as NamedDeclaration).name) { + case ts.SyntaxKind.FunctionDeclaration: + case ts.SyntaxKind.MethodDeclaration: + case ts.SyntaxKind.MethodSignature: + case ts.SyntaxKind.GetAccessor: + case ts.SyntaxKind.SetAccessor: + case ts.SyntaxKind.FunctionExpression: + case ts.SyntaxKind.ArrowFunction: + if (noImplicitAny && !(declaration as ts.NamedDeclaration).name) { if (wideningKind === WideningKind.GeneratorYield) { - error(declaration, Diagnostics.Generator_implicitly_has_yield_type_0_because_it_does_not_yield_any_values_Consider_supplying_a_return_type_annotation, typeAsString); + error(declaration, ts.Diagnostics.Generator_implicitly_has_yield_type_0_because_it_does_not_yield_any_values_Consider_supplying_a_return_type_annotation, typeAsString); } else { - error(declaration, Diagnostics.Function_expression_which_lacks_return_type_annotation_implicitly_has_an_0_return_type, typeAsString); + error(declaration, ts.Diagnostics.Function_expression_which_lacks_return_type_annotation_implicitly_has_an_0_return_type, typeAsString); } return; } - diagnostic = !noImplicitAny ? Diagnostics._0_implicitly_has_an_1_return_type_but_a_better_type_may_be_inferred_from_usage : - wideningKind === WideningKind.GeneratorYield ? Diagnostics._0_which_lacks_return_type_annotation_implicitly_has_an_1_yield_type : - Diagnostics._0_which_lacks_return_type_annotation_implicitly_has_an_1_return_type; + diagnostic = !noImplicitAny ? ts.Diagnostics._0_implicitly_has_an_1_return_type_but_a_better_type_may_be_inferred_from_usage : + wideningKind === WideningKind.GeneratorYield ? ts.Diagnostics._0_which_lacks_return_type_annotation_implicitly_has_an_1_yield_type : + ts.Diagnostics._0_which_lacks_return_type_annotation_implicitly_has_an_1_return_type; break; - case SyntaxKind.MappedType: + case ts.SyntaxKind.MappedType: if (noImplicitAny) { - error(declaration, Diagnostics.Mapped_object_type_implicitly_has_an_any_template_type); + error(declaration, ts.Diagnostics.Mapped_object_type_implicitly_has_an_any_template_type); } return; default: - diagnostic = noImplicitAny ? Diagnostics.Variable_0_implicitly_has_an_1_type : Diagnostics.Variable_0_implicitly_has_an_1_type_but_a_better_type_may_be_inferred_from_usage; + diagnostic = noImplicitAny ? ts.Diagnostics.Variable_0_implicitly_has_an_1_type : ts.Diagnostics.Variable_0_implicitly_has_an_1_type_but_a_better_type_may_be_inferred_from_usage; } - errorOrSuggestion(noImplicitAny, declaration, diagnostic, declarationNameToString(getNameOfDeclaration(declaration)), typeAsString); + errorOrSuggestion(noImplicitAny, declaration, diagnostic, ts.declarationNameToString(ts.getNameOfDeclaration(declaration)), typeAsString); } - function reportErrorsFromWidening(declaration: Declaration, type: Type, wideningKind?: WideningKind) { + function reportErrorsFromWidening(declaration: ts.Declaration, type: ts.Type, wideningKind?: WideningKind) { addLazyDiagnostic(() => { - if (noImplicitAny && getObjectFlags(type) & ObjectFlags.ContainsWideningType && (!wideningKind || !getContextualSignatureForFunctionLikeDeclaration(declaration as FunctionLikeDeclaration))) { + if (noImplicitAny && ts.getObjectFlags(type) & ts.ObjectFlags.ContainsWideningType && (!wideningKind || !getContextualSignatureForFunctionLikeDeclaration(declaration as ts.FunctionLikeDeclaration))) { // Report implicit any error within type if possible, otherwise report error on declaration if (!reportWideningErrorsInType(type)) { reportImplicitAny(declaration, type, wideningKind); @@ -21767,7 +21227,7 @@ namespace ts { }); } - function applyToParameterTypes(source: Signature, target: Signature, callback: (s: Type, t: Type) => void) { + function applyToParameterTypes(source: ts.Signature, target: ts.Signature, callback: (s: ts.Type, t: ts.Type) => void) { const sourceCount = getParameterCount(source); const targetCount = getParameterCount(target); const sourceRestType = getEffectiveRestType(source); @@ -21789,7 +21249,7 @@ namespace ts { } } - function applyToReturnTypes(source: Signature, target: Signature, callback: (s: Type, t: Type) => void) { + function applyToReturnTypes(source: ts.Signature, target: ts.Signature, callback: (s: ts.Type, t: ts.Type) => void) { const sourceTypePredicate = getTypePredicateOfSignature(source); const targetTypePredicate = getTypePredicateOfSignature(target); if (sourceTypePredicate && targetTypePredicate && typePredicateKindsMatch(sourceTypePredicate, targetTypePredicate) && sourceTypePredicate.type && targetTypePredicate.type) { @@ -21800,16 +21260,16 @@ namespace ts { } } - function createInferenceContext(typeParameters: readonly TypeParameter[], signature: Signature | undefined, flags: InferenceFlags, compareTypes?: TypeComparer): InferenceContext { + function createInferenceContext(typeParameters: readonly ts.TypeParameter[], signature: ts.Signature | undefined, flags: ts.InferenceFlags, compareTypes?: ts.TypeComparer): ts.InferenceContext { return createInferenceContextWorker(typeParameters.map(createInferenceInfo), signature, flags, compareTypes || compareTypesAssignable); } - function cloneInferenceContext(context: T, extraFlags: InferenceFlags = 0): InferenceContext | T & undefined { - return context && createInferenceContextWorker(map(context.inferences, cloneInferenceInfo), context.signature, context.flags | extraFlags, context.compareTypes); + function cloneInferenceContext(context: T, extraFlags: ts.InferenceFlags = 0): ts.InferenceContext | (T & undefined) { + return context && createInferenceContextWorker(ts.map(context.inferences, cloneInferenceInfo), context.signature, context.flags | extraFlags, context.compareTypes); } - function createInferenceContextWorker(inferences: InferenceInfo[], signature: Signature | undefined, flags: InferenceFlags, compareTypes: TypeComparer): InferenceContext { - const context: InferenceContext = { + function createInferenceContextWorker(inferences: ts.InferenceInfo[], signature: ts.Signature | undefined, flags: ts.InferenceFlags, compareTypes: ts.TypeComparer): ts.InferenceContext { + const context: ts.InferenceContext = { inferences, signature, flags, @@ -21820,7 +21280,7 @@ namespace ts { return context; } - function mapToInferredType(context: InferenceContext, t: Type, fix: boolean): Type { + function mapToInferredType(context: ts.InferenceContext, t: ts.Type, fix: boolean): ts.Type { const inferences = context.inferences; for (let i = 0; i < inferences.length; i++) { const inference = inferences[i]; @@ -21838,7 +21298,7 @@ namespace ts { return t; } - function clearCachedInferences(inferences: InferenceInfo[]) { + function clearCachedInferences(inferences: ts.InferenceInfo[]) { for (const inference of inferences) { if (!inference.isFixed) { inference.inferredType = undefined; @@ -21846,7 +21306,7 @@ namespace ts { } } - function addIntraExpressionInferenceSite(context: InferenceContext, node: Expression | MethodDeclaration, type: Type) { + function addIntraExpressionInferenceSite(context: ts.InferenceContext, node: ts.Expression | ts.MethodDeclaration, type: ts.Type) { (context.intraExpressionInferenceSites ??= []).push({ node, type }); } @@ -21863,12 +21323,12 @@ namespace ts { // arrow function. This happens automatically when the arrow functions are discrete arguments (because we // infer from each argument before processing the next), but when the arrow functions are elements of an // object or array literal, we need to perform intra-expression inferences early. - function inferFromIntraExpressionSites(context: InferenceContext) { + function inferFromIntraExpressionSites(context: ts.InferenceContext) { if (context.intraExpressionInferenceSites) { for (const { node, type } of context.intraExpressionInferenceSites) { - const contextualType = node.kind === SyntaxKind.MethodDeclaration ? - getContextualTypeForObjectLiteralMethod(node as MethodDeclaration, ContextFlags.NoConstraints) : - getContextualType(node, ContextFlags.NoConstraints); + const contextualType = node.kind === ts.SyntaxKind.MethodDeclaration ? + getContextualTypeForObjectLiteralMethod(node as ts.MethodDeclaration, ts.ContextFlags.NoConstraints) : + getContextualType(node, ts.ContextFlags.NoConstraints); if (contextualType) { inferTypes(context.inferences, type, contextualType); } @@ -21877,7 +21337,7 @@ namespace ts { } } - function createInferenceInfo(typeParameter: TypeParameter): InferenceInfo { + function createInferenceInfo(typeParameter: ts.TypeParameter): ts.InferenceInfo { return { typeParameter, candidates: undefined, @@ -21890,7 +21350,7 @@ namespace ts { }; } - function cloneInferenceInfo(inference: InferenceInfo): InferenceInfo { + function cloneInferenceInfo(inference: ts.InferenceInfo): ts.InferenceInfo { return { typeParameter: inference.typeParameter, candidates: inference.candidates && inference.candidates.slice(), @@ -21903,60 +21363,59 @@ namespace ts { }; } - function cloneInferredPartOfContext(context: InferenceContext): InferenceContext | undefined { - const inferences = filter(context.inferences, hasInferenceCandidates); + function cloneInferredPartOfContext(context: ts.InferenceContext): ts.InferenceContext | undefined { + const inferences = ts.filter(context.inferences, hasInferenceCandidates); return inferences.length ? - createInferenceContextWorker(map(inferences, cloneInferenceInfo), context.signature, context.flags, context.compareTypes) : + createInferenceContextWorker(ts.map(inferences, cloneInferenceInfo), context.signature, context.flags, context.compareTypes) : undefined; } - function getMapperFromContext(context: T): TypeMapper | T & undefined { + function getMapperFromContext(context: T): ts.TypeMapper | (T & undefined) { return context && context.mapper; } // Return true if the given type could possibly reference a type parameter for which // we perform type inference (i.e. a type parameter of a generic function). We cache // results for union and intersection types for performance reasons. - function couldContainTypeVariables(type: Type): boolean { - const objectFlags = getObjectFlags(type); - if (objectFlags & ObjectFlags.CouldContainTypeVariablesComputed) { - return !!(objectFlags & ObjectFlags.CouldContainTypeVariables); - } - const result = !!(type.flags & TypeFlags.Instantiable || - type.flags & TypeFlags.Object && !isNonGenericTopLevelType(type) && ( - objectFlags & ObjectFlags.Reference && ((type as TypeReference).node || forEach(getTypeArguments(type as TypeReference), couldContainTypeVariables)) || - objectFlags & ObjectFlags.Anonymous && type.symbol && type.symbol.flags & (SymbolFlags.Function | SymbolFlags.Method | SymbolFlags.Class | SymbolFlags.TypeLiteral | SymbolFlags.ObjectLiteral) && type.symbol.declarations || - objectFlags & (ObjectFlags.Mapped | ObjectFlags.ReverseMapped | ObjectFlags.ObjectRestType | ObjectFlags.InstantiationExpressionType)) || - type.flags & TypeFlags.UnionOrIntersection && !(type.flags & TypeFlags.EnumLiteral) && !isNonGenericTopLevelType(type) && some((type as UnionOrIntersectionType).types, couldContainTypeVariables)); - if (type.flags & TypeFlags.ObjectFlagsType) { - (type as ObjectFlagsType).objectFlags |= ObjectFlags.CouldContainTypeVariablesComputed | (result ? ObjectFlags.CouldContainTypeVariables : 0); + function couldContainTypeVariables(type: ts.Type): boolean { + const objectFlags = ts.getObjectFlags(type); + if (objectFlags & ts.ObjectFlags.CouldContainTypeVariablesComputed) { + return !!(objectFlags & ts.ObjectFlags.CouldContainTypeVariables); + } + const result = !!(type.flags & ts.TypeFlags.Instantiable || + type.flags & ts.TypeFlags.Object && !isNonGenericTopLevelType(type) && (objectFlags & ts.ObjectFlags.Reference && ((type as ts.TypeReference).node || ts.forEach(getTypeArguments(type as ts.TypeReference), couldContainTypeVariables)) || + objectFlags & ts.ObjectFlags.Anonymous && type.symbol && type.symbol.flags & (ts.SymbolFlags.Function | ts.SymbolFlags.Method | ts.SymbolFlags.Class | ts.SymbolFlags.TypeLiteral | ts.SymbolFlags.ObjectLiteral) && type.symbol.declarations || + objectFlags & (ts.ObjectFlags.Mapped | ts.ObjectFlags.ReverseMapped | ts.ObjectFlags.ObjectRestType | ts.ObjectFlags.InstantiationExpressionType)) || + type.flags & ts.TypeFlags.UnionOrIntersection && !(type.flags & ts.TypeFlags.EnumLiteral) && !isNonGenericTopLevelType(type) && ts.some((type as ts.UnionOrIntersectionType).types, couldContainTypeVariables)); + if (type.flags & ts.TypeFlags.ObjectFlagsType) { + (type as ts.ObjectFlagsType).objectFlags |= ts.ObjectFlags.CouldContainTypeVariablesComputed | (result ? ts.ObjectFlags.CouldContainTypeVariables : 0); } return result; } - function isNonGenericTopLevelType(type: Type) { + function isNonGenericTopLevelType(type: ts.Type) { if (type.aliasSymbol && !type.aliasTypeArguments) { - const declaration = getDeclarationOfKind(type.aliasSymbol, SyntaxKind.TypeAliasDeclaration); - return !!(declaration && findAncestor(declaration.parent, n => n.kind === SyntaxKind.SourceFile ? true : n.kind === SyntaxKind.ModuleDeclaration ? false : "quit")); + const declaration = ts.getDeclarationOfKind(type.aliasSymbol, ts.SyntaxKind.TypeAliasDeclaration); + return !!(declaration && ts.findAncestor(declaration.parent, n => n.kind === ts.SyntaxKind.SourceFile ? true : n.kind === ts.SyntaxKind.ModuleDeclaration ? false : "quit")); } return false; } - function isTypeParameterAtTopLevel(type: Type, typeParameter: TypeParameter): boolean { + function isTypeParameterAtTopLevel(type: ts.Type, typeParameter: ts.TypeParameter): boolean { return !!(type === typeParameter || - type.flags & TypeFlags.UnionOrIntersection && some((type as UnionOrIntersectionType).types, t => isTypeParameterAtTopLevel(t, typeParameter)) || - type.flags & TypeFlags.Conditional && (getTrueTypeFromConditionalType(type as ConditionalType) === typeParameter || getFalseTypeFromConditionalType(type as ConditionalType) === typeParameter)); + type.flags & ts.TypeFlags.UnionOrIntersection && ts.some((type as ts.UnionOrIntersectionType).types, t => isTypeParameterAtTopLevel(t, typeParameter)) || + type.flags & ts.TypeFlags.Conditional && (getTrueTypeFromConditionalType(type as ts.ConditionalType) === typeParameter || getFalseTypeFromConditionalType(type as ts.ConditionalType) === typeParameter)); } /** Create an object with properties named in the string literal type. Every property has type `any` */ - function createEmptyObjectTypeFromStringLiteral(type: Type) { - const members = createSymbolTable(); + function createEmptyObjectTypeFromStringLiteral(type: ts.Type) { + const members = ts.createSymbolTable(); forEachType(type, t => { - if (!(t.flags & TypeFlags.StringLiteral)) { + if (!(t.flags & ts.TypeFlags.StringLiteral)) { return; } - const name = escapeLeadingUnderscores((t as StringLiteralType).value); - const literalProp = createSymbol(SymbolFlags.Property, name); + const name = ts.escapeLeadingUnderscores((t as ts.StringLiteralType).value); + const literalProp = createSymbol(ts.SymbolFlags.Property, name); literalProp.type = anyType; if (t.symbol) { literalProp.declarations = t.symbol.declarations; @@ -21964,8 +21423,8 @@ namespace ts { } members.set(name, literalProp); }); - const indexInfos = type.flags & TypeFlags.String ? [createIndexInfo(stringType, emptyObjectType, /*isReadonly*/ false)] : emptyArray; - return createAnonymousType(undefined, members, emptyArray, emptyArray, indexInfos); + const indexInfos = type.flags & ts.TypeFlags.String ? [createIndexInfo(stringType, emptyObjectType, /*isReadonly*/ false)] : ts.emptyArray; + return createAnonymousType(undefined, members, ts.emptyArray, ts.emptyArray, indexInfos); } /** @@ -21974,7 +21433,7 @@ namespace ts { * property is computed by inferring from the source property type to X for the type * variable T[P] (i.e. we treat the type T[P] as the type variable we're inferring for). */ - function inferTypeForHomomorphicMappedType(source: Type, target: MappedType, constraint: IndexType): Type | undefined { + function inferTypeForHomomorphicMappedType(source: ts.Type, target: ts.MappedType, constraint: ts.IndexType): ts.Type | undefined { if (inInferTypeForHomomorphicMappedType) { return undefined; } @@ -21993,13 +21452,13 @@ namespace ts { // an object literal type with at least one property of an inferable type. For example, an object // literal { a: 123, b: x => true } is marked non-inferable because it contains a context sensitive // arrow function, but is considered partially inferable because property 'a' has an inferable type. - function isPartiallyInferableType(type: Type): boolean { - return !(getObjectFlags(type) & ObjectFlags.NonInferrableType) || - isObjectLiteralType(type) && some(getPropertiesOfType(type), prop => isPartiallyInferableType(getTypeOfSymbol(prop))) || - isTupleType(type) && some(getTypeArguments(type), isPartiallyInferableType); + function isPartiallyInferableType(type: ts.Type): boolean { + return !(ts.getObjectFlags(type) & ts.ObjectFlags.NonInferrableType) || + isObjectLiteralType(type) && ts.some(getPropertiesOfType(type), prop => isPartiallyInferableType(getTypeOfSymbol(prop))) || + isTupleType(type) && ts.some(getTypeArguments(type), isPartiallyInferableType); } - function createReverseMappedType(source: Type, target: MappedType, constraint: IndexType) { + function createReverseMappedType(source: ts.Type, target: ts.MappedType, constraint: ts.IndexType) { // We consider a source type reverse mappable if it has a string index signature or if // it has one or more properties and is of a partially inferable type. if (!(getIndexInfoOfType(source, stringType) || getPropertiesOfType(source).length !== 0 && isPartiallyInferableType(source))) { @@ -22011,22 +21470,22 @@ namespace ts { return createArrayType(inferReverseMappedType(getTypeArguments(source)[0], target, constraint), isReadonlyArrayType(source)); } if (isTupleType(source)) { - const elementTypes = map(getTypeArguments(source), t => inferReverseMappedType(t, target, constraint)); + const elementTypes = ts.map(getTypeArguments(source), t => inferReverseMappedType(t, target, constraint)); const elementFlags = getMappedTypeModifiers(target) & MappedTypeModifiers.IncludeOptional ? - sameMap(source.target.elementFlags, f => f & ElementFlags.Optional ? ElementFlags.Required : f) : + ts.sameMap(source.target.elementFlags, f => f & ts.ElementFlags.Optional ? ts.ElementFlags.Required : f) : source.target.elementFlags; return createTupleType(elementTypes, elementFlags, source.target.readonly, source.target.labeledElementDeclarations); } // For all other object types we infer a new object type where the reverse mapping has been // applied to the type of each property. - const reversed = createObjectType(ObjectFlags.ReverseMapped | ObjectFlags.Anonymous, /*symbol*/ undefined) as ReverseMappedType; + const reversed = createObjectType(ts.ObjectFlags.ReverseMapped | ts.ObjectFlags.Anonymous, /*symbol*/ undefined) as ts.ReverseMappedType; reversed.source = source; reversed.mappedType = target; reversed.constraintType = constraint; return reversed; } - function getTypeOfReverseMappedSymbol(symbol: ReverseMappedSymbol) { + function getTypeOfReverseMappedSymbol(symbol: ts.ReverseMappedSymbol) { const links = getSymbolLinks(symbol); if (!links.type) { links.type = inferReverseMappedType(symbol.propertyType, symbol.mappedType, symbol.constraintType); @@ -22034,31 +21493,31 @@ namespace ts { return links.type; } - function inferReverseMappedType(sourceType: Type, target: MappedType, constraint: IndexType): Type { - const typeParameter = getIndexedAccessType(constraint.type, getTypeParameterFromMappedType(target)) as TypeParameter; + function inferReverseMappedType(sourceType: ts.Type, target: ts.MappedType, constraint: ts.IndexType): ts.Type { + const typeParameter = getIndexedAccessType(constraint.type, getTypeParameterFromMappedType(target)) as ts.TypeParameter; const templateType = getTemplateTypeFromMappedType(target); const inference = createInferenceInfo(typeParameter); inferTypes([inference], sourceType, templateType); return getTypeFromInference(inference) || unknownType; } - function* getUnmatchedProperties(source: Type, target: Type, requireOptionalProperties: boolean, matchDiscriminantProperties: boolean): IterableIterator { + function* getUnmatchedProperties(source: ts.Type, target: ts.Type, requireOptionalProperties: boolean, matchDiscriminantProperties: boolean): IterableIterator { const properties = getPropertiesOfType(target); for (const targetProp of properties) { // TODO: remove this when we support static private identifier fields and find other solutions to get privateNamesAndStaticFields test to pass if (isStaticPrivateIdentifierProperty(targetProp)) { continue; } - if (requireOptionalProperties || !(targetProp.flags & SymbolFlags.Optional || getCheckFlags(targetProp) & CheckFlags.Partial)) { + if (requireOptionalProperties || !(targetProp.flags & ts.SymbolFlags.Optional || ts.getCheckFlags(targetProp) & ts.CheckFlags.Partial)) { const sourceProp = getPropertyOfType(source, targetProp.escapedName); if (!sourceProp) { yield targetProp; } else if (matchDiscriminantProperties) { const targetType = getTypeOfSymbol(targetProp); - if (targetType.flags & TypeFlags.Unit) { + if (targetType.flags & ts.TypeFlags.Unit) { const sourceType = getTypeOfSymbol(sourceProp); - if (!(sourceType.flags & TypeFlags.Any || getRegularTypeOfLiteralType(sourceType) === getRegularTypeOfLiteralType(targetType))) { + if (!(sourceType.flags & ts.TypeFlags.Any || getRegularTypeOfLiteralType(sourceType) === getRegularTypeOfLiteralType(targetType))) { yield targetProp; } } @@ -22067,17 +21526,18 @@ namespace ts { } } - function getUnmatchedProperty(source: Type, target: Type, requireOptionalProperties: boolean, matchDiscriminantProperties: boolean): Symbol | undefined { + function getUnmatchedProperty(source: ts.Type, target: ts.Type, requireOptionalProperties: boolean, matchDiscriminantProperties: boolean): ts.Symbol | undefined { const result = getUnmatchedProperties(source, target, requireOptionalProperties, matchDiscriminantProperties).next(); - if (!result.done) return result.value; + if (!result.done) + return result.value; } - function tupleTypesDefinitelyUnrelated(source: TupleTypeReference, target: TupleTypeReference) { - return !(target.target.combinedFlags & ElementFlags.Variadic) && target.target.minLength > source.target.minLength || + function tupleTypesDefinitelyUnrelated(source: ts.TupleTypeReference, target: ts.TupleTypeReference) { + return !(target.target.combinedFlags & ts.ElementFlags.Variadic) && target.target.minLength > source.target.minLength || !target.target.hasRestElement && (source.target.hasRestElement || target.target.fixedLength < source.target.fixedLength); } - function typesDefinitelyUnrelated(source: Type, target: Type) { + function typesDefinitelyUnrelated(source: ts.Type, target: ts.Type) { // Two tuple types with incompatible arities are definitely unrelated. // Two object types that each have a property that is unmatched in the other are definitely unrelated. return isTupleType(source) && isTupleType(target) ? tupleTypesDefinitelyUnrelated(source, target) : @@ -22085,21 +21545,21 @@ namespace ts { !!getUnmatchedProperty(target, source, /*requireOptionalProperties*/ false, /*matchDiscriminantProperties*/ false); } - function getTypeFromInference(inference: InferenceInfo) { - return inference.candidates ? getUnionType(inference.candidates, UnionReduction.Subtype) : + function getTypeFromInference(inference: ts.InferenceInfo) { + return inference.candidates ? getUnionType(inference.candidates, ts.UnionReduction.Subtype) : inference.contraCandidates ? getIntersectionType(inference.contraCandidates) : undefined; } - function hasSkipDirectInferenceFlag(node: Node) { + function hasSkipDirectInferenceFlag(node: ts.Node) { return !!getNodeLinks(node).skipDirectInference; } - function isFromInferenceBlockedSource(type: Type) { - return !!(type.symbol && some(type.symbol.declarations, hasSkipDirectInferenceFlag)); + function isFromInferenceBlockedSource(type: ts.Type) { + return !!(type.symbol && ts.some(type.symbol.declarations, hasSkipDirectInferenceFlag)); } - function templateLiteralTypesDefinitelyUnrelated(source: TemplateLiteralType, target: TemplateLiteralType) { + function templateLiteralTypesDefinitelyUnrelated(source: ts.TemplateLiteralType, target: ts.TemplateLiteralType) { // Two template literal types with diffences in their starting or ending text spans are definitely unrelated. const sourceStart = source.texts[0]; const targetStart = target.texts[0]; @@ -22112,12 +21572,12 @@ namespace ts { } function isValidBigIntString(s: string): boolean { - const scanner = createScanner(ScriptTarget.ESNext, /*skipTrivia*/ false); + const scanner = ts.createScanner(ts.ScriptTarget.ESNext, /*skipTrivia*/ false); let success = true; scanner.setOnError(() => success = false); scanner.setText(s + "n"); let result = scanner.scan(); - if (result === SyntaxKind.MinusToken) { + if (result === ts.SyntaxKind.MinusToken) { result = scanner.scan(); } const flags = scanner.getTokenFlags(); @@ -22126,41 +21586,41 @@ namespace ts { // * a bigint can be scanned, and that when it is scanned, it is // * the full length of the input string (so the scanner is one character beyond the augmented input length) // * it does not contain a numeric seperator (the `BigInt` constructor does not accept a numeric seperator in its input) - return success && result === SyntaxKind.BigIntLiteral && scanner.getTextPos() === (s.length + 1) && !(flags & TokenFlags.ContainsSeparator); + return success && result === ts.SyntaxKind.BigIntLiteral && scanner.getTextPos() === (s.length + 1) && !(flags & ts.TokenFlags.ContainsSeparator); } - function isValidTypeForTemplateLiteralPlaceholder(source: Type, target: Type): boolean { - if (source === target || target.flags & (TypeFlags.Any | TypeFlags.String)) { + function isValidTypeForTemplateLiteralPlaceholder(source: ts.Type, target: ts.Type): boolean { + if (source === target || target.flags & (ts.TypeFlags.Any | ts.TypeFlags.String)) { return true; } - if (source.flags & TypeFlags.StringLiteral) { - const value = (source as StringLiteralType).value; - return !!(target.flags & TypeFlags.Number && value !== "" && isFinite(+value) || - target.flags & TypeFlags.BigInt && value !== "" && isValidBigIntString(value) || - target.flags & (TypeFlags.BooleanLiteral | TypeFlags.Nullable) && value === (target as IntrinsicType).intrinsicName); + if (source.flags & ts.TypeFlags.StringLiteral) { + const value = (source as ts.StringLiteralType).value; + return !!(target.flags & ts.TypeFlags.Number && value !== "" && isFinite(+value) || + target.flags & ts.TypeFlags.BigInt && value !== "" && isValidBigIntString(value) || + target.flags & (ts.TypeFlags.BooleanLiteral | ts.TypeFlags.Nullable) && value === (target as ts.IntrinsicType).intrinsicName); } - if (source.flags & TypeFlags.TemplateLiteral) { - const texts = (source as TemplateLiteralType).texts; - return texts.length === 2 && texts[0] === "" && texts[1] === "" && isTypeAssignableTo((source as TemplateLiteralType).types[0], target); + if (source.flags & ts.TypeFlags.TemplateLiteral) { + const texts = (source as ts.TemplateLiteralType).texts; + return texts.length === 2 && texts[0] === "" && texts[1] === "" && isTypeAssignableTo((source as ts.TemplateLiteralType).types[0], target); } return isTypeAssignableTo(source, target); } - function inferTypesFromTemplateLiteralType(source: Type, target: TemplateLiteralType): Type[] | undefined { - return source.flags & TypeFlags.StringLiteral ? inferFromLiteralPartsToTemplateLiteral([(source as StringLiteralType).value], emptyArray, target) : - source.flags & TypeFlags.TemplateLiteral ? - arraysEqual((source as TemplateLiteralType).texts, target.texts) ? map((source as TemplateLiteralType).types, getStringLikeTypeForType) : - inferFromLiteralPartsToTemplateLiteral((source as TemplateLiteralType).texts, (source as TemplateLiteralType).types, target) : + function inferTypesFromTemplateLiteralType(source: ts.Type, target: ts.TemplateLiteralType): ts.Type[] | undefined { + return source.flags & ts.TypeFlags.StringLiteral ? inferFromLiteralPartsToTemplateLiteral([(source as ts.StringLiteralType).value], ts.emptyArray, target) : + source.flags & ts.TypeFlags.TemplateLiteral ? + ts.arraysEqual((source as ts.TemplateLiteralType).texts, target.texts) ? ts.map((source as ts.TemplateLiteralType).types, getStringLikeTypeForType) : + inferFromLiteralPartsToTemplateLiteral((source as ts.TemplateLiteralType).texts, (source as ts.TemplateLiteralType).types, target) : undefined; } - function isTypeMatchedByTemplateLiteralType(source: Type, target: TemplateLiteralType): boolean { + function isTypeMatchedByTemplateLiteralType(source: ts.Type, target: ts.TemplateLiteralType): boolean { const inferences = inferTypesFromTemplateLiteralType(source, target); - return !!inferences && every(inferences, (r, i) => isValidTypeForTemplateLiteralPlaceholder(r, target.types[i])); + return !!inferences && ts.every(inferences, (r, i) => isValidTypeForTemplateLiteralPlaceholder(r, target.types[i])); } - function getStringLikeTypeForType(type: Type) { - return type.flags & (TypeFlags.Any | TypeFlags.StringLike) ? type : getTemplateLiteralType(["", ""], [type]); + function getStringLikeTypeForType(type: ts.Type) { + return type.flags & (ts.TypeFlags.Any | ts.TypeFlags.StringLike) ? type : getTemplateLiteralType(["", ""], [type]); } // This function infers from the text parts and type parts of a source literal to a target template literal. The number @@ -22182,7 +21642,7 @@ namespace ts { // the source. The first match for the '.' in target occurs at character 1 in the source text part at index 1, and thus // the first inference is the template literal type `<${string}>`. The remainder of the source makes up the second // inference, the template literal type `<${number}-${number}>`. - function inferFromLiteralPartsToTemplateLiteral(sourceTexts: readonly string[], sourceTypes: readonly Type[], target: TemplateLiteralType): Type[] | undefined { + function inferFromLiteralPartsToTemplateLiteral(sourceTexts: readonly string[], sourceTypes: readonly ts.Type[], target: ts.TemplateLiteralType): ts.Type[] | undefined { const lastSourceIndex = sourceTexts.length - 1; const sourceStartText = sourceTexts[0]; const sourceEndText = sourceTexts[lastSourceIndex]; @@ -22191,9 +21651,10 @@ namespace ts { const targetStartText = targetTexts[0]; const targetEndText = targetTexts[lastTargetIndex]; if (lastSourceIndex === 0 && sourceStartText.length < targetStartText.length + targetEndText.length || - !sourceStartText.startsWith(targetStartText) || !sourceEndText.endsWith(targetEndText)) return undefined; + !sourceStartText.startsWith(targetStartText) || !sourceEndText.endsWith(targetEndText)) + return undefined; const remainingEndText = sourceEndText.slice(0, sourceEndText.length - targetEndText.length); - const matches: Type[] = []; + const matches: ts.Type[] = []; let seg = 0; let pos = targetStartText.length; for (let i = 1; i < lastTargetIndex; i++) { @@ -22203,9 +21664,11 @@ namespace ts { let p = pos; while (true) { p = getSourceText(s).indexOf(delim, p); - if (p >= 0) break; + if (p >= 0) + break; s++; - if (s === sourceTexts.length) return undefined; + if (s === sourceTexts.length) + return undefined; p = 0; } addMatch(s, p); @@ -22229,27 +21692,25 @@ namespace ts { function addMatch(s: number, p: number) { const matchType = s === seg ? getStringLiteralType(getSourceText(s).slice(pos, p)) : - getTemplateLiteralType( - [sourceTexts[seg].slice(pos), ...sourceTexts.slice(seg + 1, s), getSourceText(s).slice(0, p)], - sourceTypes.slice(seg, s)); + getTemplateLiteralType([sourceTexts[seg].slice(pos), ...sourceTexts.slice(seg + 1, s), getSourceText(s).slice(0, p)], sourceTypes.slice(seg, s)); matches.push(matchType); seg = s; pos = p; } } - function inferTypes(inferences: InferenceInfo[], originalSource: Type, originalTarget: Type, priority: InferencePriority = 0, contravariant = false) { + function inferTypes(inferences: ts.InferenceInfo[], originalSource: ts.Type, originalTarget: ts.Type, priority: ts.InferencePriority = 0, contravariant = false) { let bivariant = false; - let propagationType: Type; - let inferencePriority = InferencePriority.MaxValue; + let propagationType: ts.Type; + let inferencePriority = ts.InferencePriority.MaxValue; let allowComplexConstraintInference = true; - let visited: ESMap; + let visited: ts.ESMap; let sourceStack: object[]; let targetStack: object[]; let expandingFlags = ExpandingFlags.None; inferFromTypes(originalSource, originalTarget); - function inferFromTypes(source: Type, target: Type): void { + function inferFromTypes(source: ts.Type, target: ts.Type): void { if (!couldContainTypeVariables(target)) { return; } @@ -22269,18 +21730,18 @@ namespace ts { inferFromTypeArguments(source.aliasTypeArguments, target.aliasTypeArguments!, getAliasVariances(source.aliasSymbol)); return; } - if (source === target && source.flags & TypeFlags.UnionOrIntersection) { + if (source === target && source.flags & ts.TypeFlags.UnionOrIntersection) { // When source and target are the same union or intersection type, just relate each constituent // type to itself. - for (const t of (source as UnionOrIntersectionType).types) { + for (const t of (source as ts.UnionOrIntersectionType).types) { inferFromTypes(t, t); } return; } - if (target.flags & TypeFlags.Union) { + if (target.flags & ts.TypeFlags.Union) { // First, infer between identically matching source and target constituents and remove the // matching types. - const [tempSources, tempTargets] = inferFromMatchingTypes(source.flags & TypeFlags.Union ? (source as UnionType).types : [source], (target as UnionType).types, isTypeOrBaseIdenticalTo); + const [tempSources, tempTargets] = inferFromMatchingTypes(source.flags & ts.TypeFlags.Union ? (source as ts.UnionType).types : [source], (target as ts.UnionType).types, isTypeOrBaseIdenticalTo); // Next, infer between closely matching source and target constituents and remove // the matching types. Types closely match when they are instantiations of the same // object type or instantiations of the same type alias. @@ -22295,22 +21756,21 @@ namespace ts { // inferring a type parameter constraint. Instead, make a lower priority inference from // the full source to whatever remains in the target. For example, when inferring from // string to 'string | T', make a lower priority inference of string for T. - inferWithPriority(source, target, InferencePriority.NakedTypeVariable); + inferWithPriority(source, target, ts.InferencePriority.NakedTypeVariable); return; } source = getUnionType(sources); } - else if (target.flags & TypeFlags.Intersection && some((target as IntersectionType).types, - t => !!getInferenceInfoForType(t) || (isGenericMappedType(t) && !!getInferenceInfoForType(getHomomorphicTypeVariable(t) || neverType)))) { + else if (target.flags & ts.TypeFlags.Intersection && ts.some((target as ts.IntersectionType).types, t => !!getInferenceInfoForType(t) || (isGenericMappedType(t) && !!getInferenceInfoForType(getHomomorphicTypeVariable(t) || neverType)))) { // We reduce intersection types only when they contain naked type parameters. For example, when // inferring from 'string[] & { extra: any }' to 'string[] & T' we want to remove string[] and // infer { extra: any } for T. But when inferring to 'string[] & Iterable' we want to keep the // string[] on the source side and infer string for T. // Likewise, we consider a homomorphic mapped type constrainted to the target type parameter as similar to a "naked type variable" // in such scenarios. - if (!(source.flags & TypeFlags.Union)) { + if (!(source.flags & ts.TypeFlags.Union)) { // Infer between identically matching source and target constituents and remove the matching types. - const [sources, targets] = inferFromMatchingTypes(source.flags & TypeFlags.Intersection ? (source as IntersectionType).types : [source], (target as IntersectionType).types, isTypeIdenticalTo); + const [sources, targets] = inferFromMatchingTypes(source.flags & ts.TypeFlags.Intersection ? (source as ts.IntersectionType).types : [source], (target as ts.IntersectionType).types, isTypeIdenticalTo); if (sources.length === 0 || targets.length === 0) { return; } @@ -22318,10 +21778,10 @@ namespace ts { target = getIntersectionType(targets); } } - else if (target.flags & (TypeFlags.IndexedAccess | TypeFlags.Substitution)) { + else if (target.flags & (ts.TypeFlags.IndexedAccess | ts.TypeFlags.Substitution)) { target = getActualTypeVariable(target); } - if (target.flags & TypeFlags.TypeVariable) { + if (target.flags & ts.TypeFlags.TypeVariable) { // If target is a type parameter, make an inference, unless the source type contains // the anyFunctionType (the wildcard type that's used to avoid contextually typing functions). // Because the anyFunctionType is internal, it should not be exposed to the user by adding @@ -22329,12 +21789,12 @@ namespace ts { // not contain anyFunctionType when we come back to this argument for its second round // of inference. Also, we exclude inferences for silentNeverType (which is used as a wildcard // when constructing types from type parameters that had no inference candidates). - if (source === nonInferrableAnyType || source === silentNeverType || (priority & InferencePriority.ReturnType && (source === autoType || source === autoArrayType)) || isFromInferenceBlockedSource(source)) { + if (source === nonInferrableAnyType || source === silentNeverType || (priority & ts.InferencePriority.ReturnType && (source === autoType || source === autoArrayType)) || isFromInferenceBlockedSource(source)) { return; } const inference = getInferenceInfoForType(target); if (inference) { - if (getObjectFlags(source) & ObjectFlags.NonInferrableType) { + if (ts.getObjectFlags(source) & ts.ObjectFlags.NonInferrableType) { return; } if (!inference.isFixed) { @@ -22349,17 +21809,17 @@ namespace ts { // We make contravariant inferences only if we are in a pure contravariant position, // i.e. only if we have not descended into a bivariant position. if (contravariant && !bivariant) { - if (!contains(inference.contraCandidates, candidate)) { - inference.contraCandidates = append(inference.contraCandidates, candidate); + if (!ts.contains(inference.contraCandidates, candidate)) { + inference.contraCandidates = ts.append(inference.contraCandidates, candidate); clearCachedInferences(inferences); } } - else if (!contains(inference.candidates, candidate)) { - inference.candidates = append(inference.candidates, candidate); + else if (!ts.contains(inference.candidates, candidate)) { + inference.candidates = ts.append(inference.candidates, candidate); clearCachedInferences(inferences); } } - if (!(priority & InferencePriority.ReturnType) && target.flags & TypeFlags.TypeParameter && inference.topLevel && !isTypeParameterAtTopLevel(originalTarget, target as TypeParameter)) { + if (!(priority & ts.InferencePriority.ReturnType) && target.flags & ts.TypeFlags.TypeParameter && inference.topLevel && !isTypeParameterAtTopLevel(originalTarget, target as ts.TypeParameter)) { inference.topLevel = false; clearCachedInferences(inferences); } @@ -22372,75 +21832,74 @@ namespace ts { if (simplified !== target) { inferFromTypes(source, simplified); } - else if (target.flags & TypeFlags.IndexedAccess) { - const indexType = getSimplifiedType((target as IndexedAccessType).indexType, /*writing*/ false); + else if (target.flags & ts.TypeFlags.IndexedAccess) { + const indexType = getSimplifiedType((target as ts.IndexedAccessType).indexType, /*writing*/ false); // Generally simplifications of instantiable indexes are avoided to keep relationship checking correct, however if our target is an access, we can consider // that key of that access to be "instantiated", since we're looking to find the infernce goal in any way we can. - if (indexType.flags & TypeFlags.Instantiable) { - const simplified = distributeIndexOverObjectType(getSimplifiedType((target as IndexedAccessType).objectType, /*writing*/ false), indexType, /*writing*/ false); + if (indexType.flags & ts.TypeFlags.Instantiable) { + const simplified = distributeIndexOverObjectType(getSimplifiedType((target as ts.IndexedAccessType).objectType, /*writing*/ false), indexType, /*writing*/ false); if (simplified && simplified !== target) { inferFromTypes(source, simplified); } } } } - if (getObjectFlags(source) & ObjectFlags.Reference && getObjectFlags(target) & ObjectFlags.Reference && ( - (source as TypeReference).target === (target as TypeReference).target || isArrayType(source) && isArrayType(target)) && - !((source as TypeReference).node && (target as TypeReference).node)) { + if (ts.getObjectFlags(source) & ts.ObjectFlags.Reference && ts.getObjectFlags(target) & ts.ObjectFlags.Reference && ((source as ts.TypeReference).target === (target as ts.TypeReference).target || isArrayType(source) && isArrayType(target)) && + !((source as ts.TypeReference).node && (target as ts.TypeReference).node)) { // If source and target are references to the same generic type, infer from type arguments - inferFromTypeArguments(getTypeArguments(source as TypeReference), getTypeArguments(target as TypeReference), getVariances((source as TypeReference).target)); + inferFromTypeArguments(getTypeArguments(source as ts.TypeReference), getTypeArguments(target as ts.TypeReference), getVariances((source as ts.TypeReference).target)); } - else if (source.flags & TypeFlags.Index && target.flags & TypeFlags.Index) { + else if (source.flags & ts.TypeFlags.Index && target.flags & ts.TypeFlags.Index) { contravariant = !contravariant; - inferFromTypes((source as IndexType).type, (target as IndexType).type); + inferFromTypes((source as ts.IndexType).type, (target as ts.IndexType).type); contravariant = !contravariant; } - else if ((isLiteralType(source) || source.flags & TypeFlags.String) && target.flags & TypeFlags.Index) { + else if ((isLiteralType(source) || source.flags & ts.TypeFlags.String) && target.flags & ts.TypeFlags.Index) { const empty = createEmptyObjectTypeFromStringLiteral(source); contravariant = !contravariant; - inferWithPriority(empty, (target as IndexType).type, InferencePriority.LiteralKeyof); + inferWithPriority(empty, (target as ts.IndexType).type, ts.InferencePriority.LiteralKeyof); contravariant = !contravariant; } - else if (source.flags & TypeFlags.IndexedAccess && target.flags & TypeFlags.IndexedAccess) { - inferFromTypes((source as IndexedAccessType).objectType, (target as IndexedAccessType).objectType); - inferFromTypes((source as IndexedAccessType).indexType, (target as IndexedAccessType).indexType); + else if (source.flags & ts.TypeFlags.IndexedAccess && target.flags & ts.TypeFlags.IndexedAccess) { + inferFromTypes((source as ts.IndexedAccessType).objectType, (target as ts.IndexedAccessType).objectType); + inferFromTypes((source as ts.IndexedAccessType).indexType, (target as ts.IndexedAccessType).indexType); } - else if (source.flags & TypeFlags.StringMapping && target.flags & TypeFlags.StringMapping) { - if ((source as StringMappingType).symbol === (target as StringMappingType).symbol) { - inferFromTypes((source as StringMappingType).type, (target as StringMappingType).type); + else if (source.flags & ts.TypeFlags.StringMapping && target.flags & ts.TypeFlags.StringMapping) { + if ((source as ts.StringMappingType).symbol === (target as ts.StringMappingType).symbol) { + inferFromTypes((source as ts.StringMappingType).type, (target as ts.StringMappingType).type); } } - else if (source.flags & TypeFlags.Substitution) { - inferFromTypes((source as SubstitutionType).baseType, target); + else if (source.flags & ts.TypeFlags.Substitution) { + inferFromTypes((source as ts.SubstitutionType).baseType, target); const oldPriority = priority; - priority |= InferencePriority.SubstituteSource; - inferFromTypes((source as SubstitutionType).substitute, target); // Make substitute inference at a lower priority + priority |= ts.InferencePriority.SubstituteSource; + inferFromTypes((source as ts.SubstitutionType).substitute, target); // Make substitute inference at a lower priority priority = oldPriority; } - else if (target.flags & TypeFlags.Conditional) { + else if (target.flags & ts.TypeFlags.Conditional) { invokeOnce(source, target, inferToConditionalType); } - else if (target.flags & TypeFlags.UnionOrIntersection) { - inferToMultipleTypes(source, (target as UnionOrIntersectionType).types, target.flags); + else if (target.flags & ts.TypeFlags.UnionOrIntersection) { + inferToMultipleTypes(source, (target as ts.UnionOrIntersectionType).types, target.flags); } - else if (source.flags & TypeFlags.Union) { + else if (source.flags & ts.TypeFlags.Union) { // Source is a union or intersection type, infer from each constituent type - const sourceTypes = (source as UnionOrIntersectionType).types; + const sourceTypes = (source as ts.UnionOrIntersectionType).types; for (const sourceType of sourceTypes) { inferFromTypes(sourceType, target); } } - else if (target.flags & TypeFlags.TemplateLiteral) { - inferToTemplateLiteralType(source, target as TemplateLiteralType); + else if (target.flags & ts.TypeFlags.TemplateLiteral) { + inferToTemplateLiteralType(source, target as ts.TemplateLiteralType); } else { source = getReducedType(source); - if (!(priority & InferencePriority.NoConstraints && source.flags & (TypeFlags.Intersection | TypeFlags.Instantiable))) { + if (!(priority & ts.InferencePriority.NoConstraints && source.flags & (ts.TypeFlags.Intersection | ts.TypeFlags.Instantiable))) { const apparentSource = getApparentType(source); // getApparentType can return _any_ type, since an indexed access or conditional may simplify to any other type. // If that occurs and it doesn't simplify to an object or intersection, we'll need to restart `inferFromTypes` // with the simplified source. - if (apparentSource !== source && allowComplexConstraintInference && !(apparentSource.flags & (TypeFlags.Object | TypeFlags.Intersection))) { + if (apparentSource !== source && allowComplexConstraintInference && !(apparentSource.flags & (ts.TypeFlags.Object | ts.TypeFlags.Intersection))) { // TODO: The `allowComplexConstraintInference` flag is a hack! This forbids inference from complex constraints within constraints! // This isn't required algorithmically, but rather is used to lower the memory burden caused by performing inference // that is _too good_ in projects with complicated constraints (eg, fp-ts). In such cases, if we did not limit ourselves @@ -22453,36 +21912,38 @@ namespace ts { } source = apparentSource; } - if (source.flags & (TypeFlags.Object | TypeFlags.Intersection)) { + if (source.flags & (ts.TypeFlags.Object | ts.TypeFlags.Intersection)) { invokeOnce(source, target, inferFromObjectTypes); } } } - function inferWithPriority(source: Type, target: Type, newPriority: InferencePriority) { + function inferWithPriority(source: ts.Type, target: ts.Type, newPriority: ts.InferencePriority) { const savePriority = priority; priority |= newPriority; inferFromTypes(source, target); priority = savePriority; } - function invokeOnce(source: Type, target: Type, action: (source: Type, target: Type) => void) { + function invokeOnce(source: ts.Type, target: ts.Type, action: (source: ts.Type, target: ts.Type) => void) { const key = source.id + "," + target.id; const status = visited && visited.get(key); if (status !== undefined) { inferencePriority = Math.min(inferencePriority, status); return; } - (visited || (visited = new Map())).set(key, InferencePriority.Circularity); + (visited || (visited = new ts.Map())).set(key, ts.InferencePriority.Circularity); const saveInferencePriority = inferencePriority; - inferencePriority = InferencePriority.MaxValue; + inferencePriority = ts.InferencePriority.MaxValue; // We stop inferring and report a circularity if we encounter duplicate recursion identities on both // the source side and the target side. const saveExpandingFlags = expandingFlags; const sourceIdentity = getRecursionIdentity(source); const targetIdentity = getRecursionIdentity(target); - if (contains(sourceStack, sourceIdentity)) expandingFlags |= ExpandingFlags.Source; - if (contains(targetStack, targetIdentity)) expandingFlags |= ExpandingFlags.Target; + if (ts.contains(sourceStack, sourceIdentity)) + expandingFlags |= ExpandingFlags.Source; + if (ts.contains(targetStack, targetIdentity)) + expandingFlags |= ExpandingFlags.Target; if (expandingFlags !== ExpandingFlags.Both) { (sourceStack || (sourceStack = [])).push(sourceIdentity); (targetStack || (targetStack = [])).push(targetIdentity); @@ -22491,35 +21952,38 @@ namespace ts { sourceStack.pop(); } else { - inferencePriority = InferencePriority.Circularity; + inferencePriority = ts.InferencePriority.Circularity; } expandingFlags = saveExpandingFlags; visited.set(key, inferencePriority); inferencePriority = Math.min(inferencePriority, saveInferencePriority); } - function inferFromMatchingTypes(sources: Type[], targets: Type[], matches: (s: Type, t: Type) => boolean): [Type[], Type[]] { - let matchedSources: Type[] | undefined; - let matchedTargets: Type[] | undefined; + function inferFromMatchingTypes(sources: ts.Type[], targets: ts.Type[], matches: (s: ts.Type, t: ts.Type) => boolean): [ + ts.Type[], + ts.Type[] + ] { + let matchedSources: ts.Type[] | undefined; + let matchedTargets: ts.Type[] | undefined; for (const t of targets) { for (const s of sources) { if (matches(s, t)) { inferFromTypes(s, t); - matchedSources = appendIfUnique(matchedSources, s); - matchedTargets = appendIfUnique(matchedTargets, t); + matchedSources = ts.appendIfUnique(matchedSources, s); + matchedTargets = ts.appendIfUnique(matchedTargets, t); } } } return [ - matchedSources ? filter(sources, t => !contains(matchedSources, t)) : sources, - matchedTargets ? filter(targets, t => !contains(matchedTargets, t)) : targets, + matchedSources ? ts.filter(sources, t => !ts.contains(matchedSources, t)) : sources, + matchedTargets ? ts.filter(targets, t => !ts.contains(matchedTargets, t)) : targets, ]; } - function inferFromTypeArguments(sourceTypes: readonly Type[], targetTypes: readonly Type[], variances: readonly VarianceFlags[]) { + function inferFromTypeArguments(sourceTypes: readonly ts.Type[], targetTypes: readonly ts.Type[], variances: readonly ts.VarianceFlags[]) { const count = sourceTypes.length < targetTypes.length ? sourceTypes.length : targetTypes.length; for (let i = 0; i < count; i++) { - if (i < variances.length && (variances[i] & VarianceFlags.VarianceMask) === VarianceFlags.Contravariant) { + if (i < variances.length && (variances[i] & ts.VarianceFlags.VarianceMask) === ts.VarianceFlags.Contravariant) { inferFromContravariantTypes(sourceTypes[i], targetTypes[i]); } else { @@ -22528,8 +21992,8 @@ namespace ts { } } - function inferFromContravariantTypes(source: Type, target: Type) { - if (strictFunctionTypes || priority & InferencePriority.AlwaysStrict) { + function inferFromContravariantTypes(source: ts.Type, target: ts.Type) { + if (strictFunctionTypes || priority & ts.InferencePriority.AlwaysStrict) { contravariant = !contravariant; inferFromTypes(source, target); contravariant = !contravariant; @@ -22539,8 +22003,8 @@ namespace ts { } } - function getInferenceInfoForType(type: Type) { - if (type.flags & TypeFlags.TypeVariable) { + function getInferenceInfoForType(type: ts.Type) { + if (type.flags & ts.TypeFlags.TypeVariable) { for (const inference of inferences) { if (type === inference.typeParameter) { return inference; @@ -22550,10 +22014,10 @@ namespace ts { return undefined; } - function getSingleTypeVariableFromIntersectionTypes(types: Type[]) { - let typeVariable: Type | undefined; + function getSingleTypeVariableFromIntersectionTypes(types: ts.Type[]) { + let typeVariable: ts.Type | undefined; for (const type of types) { - const t = type.flags & TypeFlags.Intersection && find((type as IntersectionType).types, t => !!getInferenceInfoForType(t)); + const t = type.flags & ts.TypeFlags.Intersection && ts.find((type as ts.IntersectionType).types, t => !!getInferenceInfoForType(t)); if (!t || typeVariable && t !== typeVariable) { return undefined; } @@ -22562,11 +22026,11 @@ namespace ts { return typeVariable; } - function inferToMultipleTypes(source: Type, targets: Type[], targetFlags: TypeFlags) { + function inferToMultipleTypes(source: ts.Type, targets: ts.Type[], targetFlags: ts.TypeFlags) { let typeVariableCount = 0; - if (targetFlags & TypeFlags.Union) { - let nakedTypeVariable: Type | undefined; - const sources = source.flags & TypeFlags.Union ? (source as UnionType).types : [source]; + if (targetFlags & ts.TypeFlags.Union) { + let nakedTypeVariable: ts.Type | undefined; + const sources = source.flags & ts.TypeFlags.Union ? (source as ts.UnionType).types : [source]; const matched = new Array(sources.length); let inferenceCircularity = false; // First infer to types that are not naked type variables. For each source type we @@ -22581,10 +22045,11 @@ namespace ts { else { for (let i = 0; i < sources.length; i++) { const saveInferencePriority = inferencePriority; - inferencePriority = InferencePriority.MaxValue; + inferencePriority = ts.InferencePriority.MaxValue; inferFromTypes(sources[i], t); - if (inferencePriority === priority) matched[i] = true; - inferenceCircularity = inferenceCircularity || inferencePriority === InferencePriority.Circularity; + if (inferencePriority === priority) + matched[i] = true; + inferenceCircularity = inferenceCircularity || inferencePriority === ts.InferencePriority.Circularity; inferencePriority = Math.min(inferencePriority, saveInferencePriority); } } @@ -22595,7 +22060,7 @@ namespace ts { // 'A | B' to 'T & (X | Y)' where we want to infer 'A | B' for T. const intersectionTypeVariable = getSingleTypeVariableFromIntersectionTypes(targets); if (intersectionTypeVariable) { - inferWithPriority(source, intersectionTypeVariable, InferencePriority.NakedTypeVariable); + inferWithPriority(source, intersectionTypeVariable, ts.InferencePriority.NakedTypeVariable); } return; } @@ -22604,7 +22069,7 @@ namespace ts { // types from which no inferences have been made so far and infer from that union to the // naked type variable. if (typeVariableCount === 1 && !inferenceCircularity) { - const unmatched = flatMap(sources, (s, i) => matched[i] ? undefined : s); + const unmatched = ts.flatMap(sources, (s, i) => matched[i] ? undefined : s); if (unmatched.length) { inferFromTypes(getUnionType(unmatched), nakedTypeVariable!); return; @@ -22628,47 +22093,46 @@ namespace ts { // less specific. For example, when inferring from Promise to T | Promise, // we want to infer string for T, not Promise | string. For intersection types // we only infer to single naked type variables. - if (targetFlags & TypeFlags.Intersection ? typeVariableCount === 1 : typeVariableCount > 0) { + if (targetFlags & ts.TypeFlags.Intersection ? typeVariableCount === 1 : typeVariableCount > 0) { for (const t of targets) { if (getInferenceInfoForType(t)) { - inferWithPriority(source, t, InferencePriority.NakedTypeVariable); + inferWithPriority(source, t, ts.InferencePriority.NakedTypeVariable); } } } } - function inferToMappedType(source: Type, target: MappedType, constraintType: Type): boolean { - if (constraintType.flags & TypeFlags.Union) { + function inferToMappedType(source: ts.Type, target: ts.MappedType, constraintType: ts.Type): boolean { + if (constraintType.flags & ts.TypeFlags.Union) { let result = false; - for (const type of (constraintType as UnionType).types) { + for (const type of (constraintType as ts.UnionType).types) { result = inferToMappedType(source, target, type) || result; } return result; } - if (constraintType.flags & TypeFlags.Index) { + if (constraintType.flags & ts.TypeFlags.Index) { // We're inferring from some source type S to a homomorphic mapped type { [P in keyof T]: X }, // where T is a type variable. Use inferTypeForHomomorphicMappedType to infer a suitable source // type and then make a secondary inference from that type to T. We make a secondary inference // such that direct inferences to T get priority over inferences to Partial, for example. - const inference = getInferenceInfoForType((constraintType as IndexType).type); + const inference = getInferenceInfoForType((constraintType as ts.IndexType).type); if (inference && !inference.isFixed && !isFromInferenceBlockedSource(source)) { - const inferredType = inferTypeForHomomorphicMappedType(source, target, constraintType as IndexType); + const inferredType = inferTypeForHomomorphicMappedType(source, target, constraintType as ts.IndexType); if (inferredType) { // We assign a lower priority to inferences made from types containing non-inferrable // types because we may only have a partial result (i.e. we may have failed to make // reverse inferences for some properties). - inferWithPriority(inferredType, inference.typeParameter, - getObjectFlags(source) & ObjectFlags.NonInferrableType ? - InferencePriority.PartialHomomorphicMappedType : - InferencePriority.HomomorphicMappedType); + inferWithPriority(inferredType, inference.typeParameter, ts.getObjectFlags(source) & ts.ObjectFlags.NonInferrableType ? + ts.InferencePriority.PartialHomomorphicMappedType : + ts.InferencePriority.HomomorphicMappedType); } } return true; } - if (constraintType.flags & TypeFlags.TypeParameter) { + if (constraintType.flags & ts.TypeFlags.TypeParameter) { // We're inferring from some source type S to a mapped type { [P in K]: X }, where K is a type // parameter. First infer from 'keyof S' to K. - inferWithPriority(getIndexType(source), constraintType, InferencePriority.MappedTypeConstraint); + inferWithPriority(getIndexType(source), constraintType, ts.InferencePriority.MappedTypeConstraint); // If K is constrained to a type C, also infer to C. Thus, for a mapped type { [P in K]: X }, // where K extends keyof T, we make the same inferences as for a homomorphic mapped type // { [P in keyof T]: X }. This enables us to make meaningful inferences when the target is a @@ -22679,31 +22143,31 @@ namespace ts { } // If no inferences can be made to K's constraint, infer from a union of the property types // in the source to the template type X. - const propTypes = map(getPropertiesOfType(source), getTypeOfSymbol); - const indexTypes = map(getIndexInfosOfType(source), info => info !== enumNumberIndexInfo ? info.type : neverType); - inferFromTypes(getUnionType(concatenate(propTypes, indexTypes)), getTemplateTypeFromMappedType(target)); + const propTypes = ts.map(getPropertiesOfType(source), getTypeOfSymbol); + const indexTypes = ts.map(getIndexInfosOfType(source), info => info !== enumNumberIndexInfo ? info.type : neverType); + inferFromTypes(getUnionType(ts.concatenate(propTypes, indexTypes)), getTemplateTypeFromMappedType(target)); return true; } return false; } - function inferToConditionalType(source: Type, target: ConditionalType) { - if (source.flags & TypeFlags.Conditional) { - inferFromTypes((source as ConditionalType).checkType, target.checkType); - inferFromTypes((source as ConditionalType).extendsType, target.extendsType); - inferFromTypes(getTrueTypeFromConditionalType(source as ConditionalType), getTrueTypeFromConditionalType(target)); - inferFromTypes(getFalseTypeFromConditionalType(source as ConditionalType), getFalseTypeFromConditionalType(target)); + function inferToConditionalType(source: ts.Type, target: ts.ConditionalType) { + if (source.flags & ts.TypeFlags.Conditional) { + inferFromTypes((source as ts.ConditionalType).checkType, target.checkType); + inferFromTypes((source as ts.ConditionalType).extendsType, target.extendsType); + inferFromTypes(getTrueTypeFromConditionalType(source as ts.ConditionalType), getTrueTypeFromConditionalType(target)); + inferFromTypes(getFalseTypeFromConditionalType(source as ts.ConditionalType), getFalseTypeFromConditionalType(target)); } else { const savePriority = priority; - priority |= contravariant ? InferencePriority.ContravariantConditional : 0; + priority |= contravariant ? ts.InferencePriority.ContravariantConditional : 0; const targetTypes = [getTrueTypeFromConditionalType(target), getFalseTypeFromConditionalType(target)]; inferToMultipleTypes(source, targetTypes, target.flags); priority = savePriority; } } - function inferToTemplateLiteralType(source: Type, target: TemplateLiteralType) { + function inferToTemplateLiteralType(source: ts.Type, target: ts.TemplateLiteralType) { const matches = inferTypesFromTemplateLiteralType(source, target); const types = target.types; // When the target template literal contains only placeholders (meaning that inference is intended to extract @@ -22712,18 +22176,17 @@ namespace ts { // assignment check will fail. If we make no inferences, we'll likely end up with the constraint 'string' which, // upon instantiation, would collapse all the placeholders to just 'string', and an assignment check might // succeed. That would be a pointless and confusing outcome. - if (matches || every(target.texts, s => s.length === 0)) { + if (matches || ts.every(target.texts, s => s.length === 0)) { for (let i = 0; i < types.length; i++) { inferFromTypes(matches ? matches[i] : neverType, types[i]); } } } - function inferFromObjectTypes(source: Type, target: Type) { - if (getObjectFlags(source) & ObjectFlags.Reference && getObjectFlags(target) & ObjectFlags.Reference && ( - (source as TypeReference).target === (target as TypeReference).target || isArrayType(source) && isArrayType(target))) { + function inferFromObjectTypes(source: ts.Type, target: ts.Type) { + if (ts.getObjectFlags(source) & ts.ObjectFlags.Reference && ts.getObjectFlags(target) & ts.ObjectFlags.Reference && ((source as ts.TypeReference).target === (target as ts.TypeReference).target || isArrayType(source) && isArrayType(target))) { // If source and target are references to the same generic type, infer from type arguments - inferFromTypeArguments(getTypeArguments(source as TypeReference), getTypeArguments(target as TypeReference), getVariances((source as TypeReference).target)); + inferFromTypeArguments(getTypeArguments(source as ts.TypeReference), getTypeArguments(target as ts.TypeReference), getVariances((source as ts.TypeReference).target)); return; } if (isGenericMappedType(source) && isGenericMappedType(target)) { @@ -22733,11 +22196,12 @@ namespace ts { inferFromTypes(getTemplateTypeFromMappedType(source), getTemplateTypeFromMappedType(target)); const sourceNameType = getNameTypeFromMappedType(source); const targetNameType = getNameTypeFromMappedType(target); - if (sourceNameType && targetNameType) inferFromTypes(sourceNameType, targetNameType); + if (sourceNameType && targetNameType) + inferFromTypes(sourceNameType, targetNameType); } - if (getObjectFlags(target) & ObjectFlags.Mapped && !(target as MappedType).declaration.nameType) { - const constraintType = getConstraintTypeFromMappedType(target as MappedType); - if (inferToMappedType(source, target as MappedType, constraintType)) { + if (ts.getObjectFlags(target) & ts.ObjectFlags.Mapped && !(target as ts.MappedType).declaration.nameType) { + const constraintType = getConstraintTypeFromMappedType(target as ts.MappedType); + if (inferToMappedType(source, target as ts.MappedType, constraintType)) { return; } } @@ -22758,22 +22222,21 @@ namespace ts { return; } const startLength = isTupleType(source) ? Math.min(source.target.fixedLength, target.target.fixedLength) : 0; - const endLength = Math.min(isTupleType(source) ? getEndElementCount(source.target, ElementFlags.Fixed) : 0, - target.target.hasRestElement ? getEndElementCount(target.target, ElementFlags.Fixed) : 0); + const endLength = Math.min(isTupleType(source) ? getEndElementCount(source.target, ts.ElementFlags.Fixed) : 0, target.target.hasRestElement ? getEndElementCount(target.target, ts.ElementFlags.Fixed) : 0); // Infer between starting fixed elements. for (let i = 0; i < startLength; i++) { inferFromTypes(getTypeArguments(source)[i], elementTypes[i]); } - if (!isTupleType(source) || sourceArity - startLength - endLength === 1 && source.target.elementFlags[startLength] & ElementFlags.Rest) { + if (!isTupleType(source) || sourceArity - startLength - endLength === 1 && source.target.elementFlags[startLength] & ts.ElementFlags.Rest) { // Single rest element remains in source, infer from that to every element in target const restType = getTypeArguments(source)[startLength]; for (let i = startLength; i < targetArity - endLength; i++) { - inferFromTypes(elementFlags[i] & ElementFlags.Variadic ? createArrayType(restType) : restType, elementTypes[i]); + inferFromTypes(elementFlags[i] & ts.ElementFlags.Variadic ? createArrayType(restType) : restType, elementTypes[i]); } } else { const middleLength = targetArity - startLength - endLength; - if (middleLength === 2 && elementFlags[startLength] & elementFlags[startLength + 1] & ElementFlags.Variadic && isTupleType(source)) { + if (middleLength === 2 && elementFlags[startLength] & elementFlags[startLength + 1] & ts.ElementFlags.Variadic && isTupleType(source)) { // Middle of target is [...T, ...U] and source is tuple type const targetInfo = getInferenceInfoForType(elementTypes[startLength]); if (targetInfo && targetInfo.impliedArity !== undefined) { @@ -22782,14 +22245,14 @@ namespace ts { inferFromTypes(sliceTupleType(source, startLength + targetInfo.impliedArity, endLength), elementTypes[startLength + 1]); } } - else if (middleLength === 1 && elementFlags[startLength] & ElementFlags.Variadic) { + else if (middleLength === 1 && elementFlags[startLength] & ts.ElementFlags.Variadic) { // Middle of target is exactly one variadic element. Infer the slice between the fixed parts in the source. // If target ends in optional element(s), make a lower priority a speculative inference. - const endsInOptional = target.target.elementFlags[targetArity - 1] & ElementFlags.Optional; + const endsInOptional = target.target.elementFlags[targetArity - 1] & ts.ElementFlags.Optional; const sourceSlice = isTupleType(source) ? sliceTupleType(source, startLength, endLength) : createArrayType(getTypeArguments(source)[0]); - inferWithPriority(sourceSlice, elementTypes[startLength], endsInOptional ? InferencePriority.SpeculativeTuple : 0); + inferWithPriority(sourceSlice, elementTypes[startLength], endsInOptional ? ts.InferencePriority.SpeculativeTuple : 0); } - else if (middleLength === 1 && elementFlags[startLength] & ElementFlags.Rest) { + else if (middleLength === 1 && elementFlags[startLength] & ts.ElementFlags.Rest) { // Middle of target is exactly one rest element. If middle of source is not empty, infer union of middle element types. const restType = isTupleType(source) ? getElementTypeOfSliceOfTupleType(source, startLength, endLength) : getTypeArguments(source)[0]; if (restType) { @@ -22809,57 +22272,57 @@ namespace ts { } } inferFromProperties(source, target); - inferFromSignatures(source, target, SignatureKind.Call); - inferFromSignatures(source, target, SignatureKind.Construct); + inferFromSignatures(source, target, ts.SignatureKind.Call); + inferFromSignatures(source, target, ts.SignatureKind.Construct); inferFromIndexTypes(source, target); } } - function inferFromProperties(source: Type, target: Type) { + function inferFromProperties(source: ts.Type, target: ts.Type) { const properties = getPropertiesOfObjectType(target); for (const targetProp of properties) { const sourceProp = getPropertyOfType(source, targetProp.escapedName); - if (sourceProp && !some(sourceProp.declarations, hasSkipDirectInferenceFlag)) { + if (sourceProp && !ts.some(sourceProp.declarations, hasSkipDirectInferenceFlag)) { inferFromTypes(getTypeOfSymbol(sourceProp), getTypeOfSymbol(targetProp)); } } } - function inferFromSignatures(source: Type, target: Type, kind: SignatureKind) { + function inferFromSignatures(source: ts.Type, target: ts.Type, kind: ts.SignatureKind) { const sourceSignatures = getSignaturesOfType(source, kind); const targetSignatures = getSignaturesOfType(target, kind); const sourceLen = sourceSignatures.length; const targetLen = targetSignatures.length; const len = sourceLen < targetLen ? sourceLen : targetLen; - const skipParameters = !!(getObjectFlags(source) & ObjectFlags.NonInferrableType); + const skipParameters = !!(ts.getObjectFlags(source) & ts.ObjectFlags.NonInferrableType); for (let i = 0; i < len; i++) { inferFromSignature(getBaseSignature(sourceSignatures[sourceLen - len + i]), getErasedSignature(targetSignatures[targetLen - len + i]), skipParameters); } } - function inferFromSignature(source: Signature, target: Signature, skipParameters: boolean) { + function inferFromSignature(source: ts.Signature, target: ts.Signature, skipParameters: boolean) { if (!skipParameters) { const saveBivariant = bivariant; - const kind = target.declaration ? target.declaration.kind : SyntaxKind.Unknown; + const kind = target.declaration ? target.declaration.kind : ts.SyntaxKind.Unknown; // Once we descend into a bivariant signature we remain bivariant for all nested inferences - bivariant = bivariant || kind === SyntaxKind.MethodDeclaration || kind === SyntaxKind.MethodSignature || kind === SyntaxKind.Constructor; + bivariant = bivariant || kind === ts.SyntaxKind.MethodDeclaration || kind === ts.SyntaxKind.MethodSignature || kind === ts.SyntaxKind.Constructor; applyToParameterTypes(source, target, inferFromContravariantTypes); bivariant = saveBivariant; } applyToReturnTypes(source, target, inferFromTypes); } - function inferFromIndexTypes(source: Type, target: Type) { + function inferFromIndexTypes(source: ts.Type, target: ts.Type) { // Inferences across mapped type index signatures are pretty much the same a inferences to homomorphic variables - const priority = (getObjectFlags(source) & getObjectFlags(target) & ObjectFlags.Mapped) ? InferencePriority.HomomorphicMappedType : 0; + const priority = (ts.getObjectFlags(source) & ts.getObjectFlags(target) & ts.ObjectFlags.Mapped) ? ts.InferencePriority.HomomorphicMappedType : 0; const indexInfos = getIndexInfosOfType(target); if (isObjectTypeWithInferableIndex(source)) { for (const targetInfo of indexInfos) { - const propTypes: Type[] = []; + const propTypes: ts.Type[] = []; for (const prop of getPropertiesOfType(source)) { - if (isApplicableIndexType(getLiteralTypeFromProperty(prop, TypeFlags.StringOrNumberLiteralOrUnique), targetInfo.keyType)) { + if (isApplicableIndexType(getLiteralTypeFromProperty(prop, ts.TypeFlags.StringOrNumberLiteralOrUnique), targetInfo.keyType)) { const propType = getTypeOfSymbol(prop); - propTypes.push(prop.flags & SymbolFlags.Optional ? removeMissingOrUndefinedType(propType) : propType); + propTypes.push(prop.flags & ts.SymbolFlags.Optional ? removeMissingOrUndefinedType(propType) : propType); } } for (const info of getIndexInfosOfType(source)) { @@ -22881,45 +22344,45 @@ namespace ts { } } - function isTypeOrBaseIdenticalTo(s: Type, t: Type) { + function isTypeOrBaseIdenticalTo(s: ts.Type, t: ts.Type) { return exactOptionalPropertyTypes && t === missingType ? s === t : - (isTypeIdenticalTo(s, t) || !!(t.flags & TypeFlags.String && s.flags & TypeFlags.StringLiteral || t.flags & TypeFlags.Number && s.flags & TypeFlags.NumberLiteral)); + (isTypeIdenticalTo(s, t) || !!(t.flags & ts.TypeFlags.String && s.flags & ts.TypeFlags.StringLiteral || t.flags & ts.TypeFlags.Number && s.flags & ts.TypeFlags.NumberLiteral)); } - function isTypeCloselyMatchedBy(s: Type, t: Type) { - return !!(s.flags & TypeFlags.Object && t.flags & TypeFlags.Object && s.symbol && s.symbol === t.symbol || + function isTypeCloselyMatchedBy(s: ts.Type, t: ts.Type) { + return !!(s.flags & ts.TypeFlags.Object && t.flags & ts.TypeFlags.Object && s.symbol && s.symbol === t.symbol || s.aliasSymbol && s.aliasTypeArguments && s.aliasSymbol === t.aliasSymbol); } - function hasPrimitiveConstraint(type: TypeParameter): boolean { + function hasPrimitiveConstraint(type: ts.TypeParameter): boolean { const constraint = getConstraintOfTypeParameter(type); - return !!constraint && maybeTypeOfKind(constraint.flags & TypeFlags.Conditional ? getDefaultConstraintOfConditionalType(constraint as ConditionalType) : constraint, TypeFlags.Primitive | TypeFlags.Index | TypeFlags.TemplateLiteral | TypeFlags.StringMapping); + return !!constraint && maybeTypeOfKind(constraint.flags & ts.TypeFlags.Conditional ? getDefaultConstraintOfConditionalType(constraint as ts.ConditionalType) : constraint, ts.TypeFlags.Primitive | ts.TypeFlags.Index | ts.TypeFlags.TemplateLiteral | ts.TypeFlags.StringMapping); } - function isObjectLiteralType(type: Type) { - return !!(getObjectFlags(type) & ObjectFlags.ObjectLiteral); + function isObjectLiteralType(type: ts.Type) { + return !!(ts.getObjectFlags(type) & ts.ObjectFlags.ObjectLiteral); } - function isObjectOrArrayLiteralType(type: Type) { - return !!(getObjectFlags(type) & (ObjectFlags.ObjectLiteral | ObjectFlags.ArrayLiteral)); + function isObjectOrArrayLiteralType(type: ts.Type) { + return !!(ts.getObjectFlags(type) & (ts.ObjectFlags.ObjectLiteral | ts.ObjectFlags.ArrayLiteral)); } - function unionObjectAndArrayLiteralCandidates(candidates: Type[]): Type[] { + function unionObjectAndArrayLiteralCandidates(candidates: ts.Type[]): ts.Type[] { if (candidates.length > 1) { - const objectLiterals = filter(candidates, isObjectOrArrayLiteralType); + const objectLiterals = ts.filter(candidates, isObjectOrArrayLiteralType); if (objectLiterals.length) { - const literalsType = getUnionType(objectLiterals, UnionReduction.Subtype); - return concatenate(filter(candidates, t => !isObjectOrArrayLiteralType(t)), [literalsType]); + const literalsType = getUnionType(objectLiterals, ts.UnionReduction.Subtype); + return ts.concatenate(ts.filter(candidates, t => !isObjectOrArrayLiteralType(t)), [literalsType]); } } return candidates; } - function getContravariantInference(inference: InferenceInfo) { - return inference.priority! & InferencePriority.PriorityImpliesCombination ? getIntersectionType(inference.contraCandidates!) : getCommonSubtype(inference.contraCandidates!); + function getContravariantInference(inference: ts.InferenceInfo) { + return inference.priority! & ts.InferencePriority.PriorityImpliesCombination ? getIntersectionType(inference.contraCandidates!) : getCommonSubtype(inference.contraCandidates!); } - function getCovariantInference(inference: InferenceInfo, signature: Signature) { + function getCovariantInference(inference: ts.InferenceInfo, signature: ts.Signature) { // Extract all object and array literal types and replace them with a single widened and normalized type. const candidates = unionObjectAndArrayLiteralCandidates(inference.candidates!); // We widen inferred literal types if @@ -22929,35 +22392,35 @@ namespace ts { const primitiveConstraint = hasPrimitiveConstraint(inference.typeParameter); const widenLiteralTypes = !primitiveConstraint && inference.topLevel && (inference.isFixed || !isTypeParameterAtTopLevel(getReturnTypeOfSignature(signature), inference.typeParameter)); - const baseCandidates = primitiveConstraint ? sameMap(candidates, getRegularTypeOfLiteralType) : - widenLiteralTypes ? sameMap(candidates, getWidenedLiteralType) : + const baseCandidates = primitiveConstraint ? ts.sameMap(candidates, getRegularTypeOfLiteralType) : + widenLiteralTypes ? ts.sameMap(candidates, getWidenedLiteralType) : candidates; // If all inferences were made from a position that implies a combined result, infer a union type. // Otherwise, infer a common supertype. - const unwidenedType = inference.priority! & InferencePriority.PriorityImpliesCombination ? - getUnionType(baseCandidates, UnionReduction.Subtype) : + const unwidenedType = inference.priority! & ts.InferencePriority.PriorityImpliesCombination ? + getUnionType(baseCandidates, ts.UnionReduction.Subtype) : getCommonSupertype(baseCandidates); return getWidenedType(unwidenedType); } - function getInferredType(context: InferenceContext, index: number): Type { + function getInferredType(context: ts.InferenceContext, index: number): ts.Type { const inference = context.inferences[index]; if (!inference.inferredType) { - let inferredType: Type | undefined; + let inferredType: ts.Type | undefined; const signature = context.signature; if (signature) { const inferredCovariantType = inference.candidates ? getCovariantInference(inference, signature) : undefined; if (inference.contraCandidates) { // If we have both co- and contra-variant inferences, we prefer the contra-variant inference // unless the co-variant inference is a subtype of some contra-variant inference and not 'never'. - inferredType = inferredCovariantType && !(inferredCovariantType.flags & TypeFlags.Never) && - some(inference.contraCandidates, t => isTypeSubtypeOf(inferredCovariantType, t)) ? + inferredType = inferredCovariantType && !(inferredCovariantType.flags & ts.TypeFlags.Never) && + ts.some(inference.contraCandidates, t => isTypeSubtypeOf(inferredCovariantType, t)) ? inferredCovariantType : getContravariantInference(inference); } else if (inferredCovariantType) { inferredType = inferredCovariantType; } - else if (context.flags & InferenceFlags.NoDefault) { + else if (context.flags & ts.InferenceFlags.NoDefault) { // We use silentNeverType as the wildcard that signals no inferences. inferredType = silentNeverType; } @@ -22979,7 +22442,7 @@ namespace ts { inferredType = getTypeFromInference(inference); } - inference.inferredType = inferredType || getDefaultTypeArgumentType(!!(context.flags & InferenceFlags.AnyDefault)); + inference.inferredType = inferredType || getDefaultTypeArgumentType(!!(context.flags & ts.InferenceFlags.AnyDefault)); const constraint = getConstraintOfTypeParameter(inference.typeParameter); if (constraint) { @@ -22993,12 +22456,12 @@ namespace ts { return inference.inferredType; } - function getDefaultTypeArgumentType(isInJavaScriptFile: boolean): Type { + function getDefaultTypeArgumentType(isInJavaScriptFile: boolean): ts.Type { return isInJavaScriptFile ? anyType : unknownType; } - function getInferredTypes(context: InferenceContext): Type[] { - const result: Type[] = []; + function getInferredTypes(context: ts.InferenceContext): ts.Type[] { + const result: ts.Type[] = []; for (let i = 0; i < context.inferences.length; i++) { result.push(getInferredType(context, i)); } @@ -23007,29 +22470,29 @@ namespace ts { // EXPRESSION TYPE CHECKING - function getCannotFindNameDiagnosticForName(node: Identifier): DiagnosticMessage { + function getCannotFindNameDiagnosticForName(node: ts.Identifier): ts.DiagnosticMessage { switch (node.escapedText) { case "document": case "console": - return Diagnostics.Cannot_find_name_0_Do_you_need_to_change_your_target_library_Try_changing_the_lib_compiler_option_to_include_dom; + return ts.Diagnostics.Cannot_find_name_0_Do_you_need_to_change_your_target_library_Try_changing_the_lib_compiler_option_to_include_dom; case "$": return compilerOptions.types - ? Diagnostics.Cannot_find_name_0_Do_you_need_to_install_type_definitions_for_jQuery_Try_npm_i_save_dev_types_Slashjquery_and_then_add_jquery_to_the_types_field_in_your_tsconfig - : Diagnostics.Cannot_find_name_0_Do_you_need_to_install_type_definitions_for_jQuery_Try_npm_i_save_dev_types_Slashjquery; + ? ts.Diagnostics.Cannot_find_name_0_Do_you_need_to_install_type_definitions_for_jQuery_Try_npm_i_save_dev_types_Slashjquery_and_then_add_jquery_to_the_types_field_in_your_tsconfig + : ts.Diagnostics.Cannot_find_name_0_Do_you_need_to_install_type_definitions_for_jQuery_Try_npm_i_save_dev_types_Slashjquery; case "describe": case "suite": case "it": case "test": return compilerOptions.types - ? Diagnostics.Cannot_find_name_0_Do_you_need_to_install_type_definitions_for_a_test_runner_Try_npm_i_save_dev_types_Slashjest_or_npm_i_save_dev_types_Slashmocha_and_then_add_jest_or_mocha_to_the_types_field_in_your_tsconfig - : Diagnostics.Cannot_find_name_0_Do_you_need_to_install_type_definitions_for_a_test_runner_Try_npm_i_save_dev_types_Slashjest_or_npm_i_save_dev_types_Slashmocha; + ? ts.Diagnostics.Cannot_find_name_0_Do_you_need_to_install_type_definitions_for_a_test_runner_Try_npm_i_save_dev_types_Slashjest_or_npm_i_save_dev_types_Slashmocha_and_then_add_jest_or_mocha_to_the_types_field_in_your_tsconfig + : ts.Diagnostics.Cannot_find_name_0_Do_you_need_to_install_type_definitions_for_a_test_runner_Try_npm_i_save_dev_types_Slashjest_or_npm_i_save_dev_types_Slashmocha; case "process": case "require": case "Buffer": case "module": return compilerOptions.types - ? Diagnostics.Cannot_find_name_0_Do_you_need_to_install_type_definitions_for_node_Try_npm_i_save_dev_types_Slashnode_and_then_add_node_to_the_types_field_in_your_tsconfig - : Diagnostics.Cannot_find_name_0_Do_you_need_to_install_type_definitions_for_node_Try_npm_i_save_dev_types_Slashnode; + ? ts.Diagnostics.Cannot_find_name_0_Do_you_need_to_install_type_definitions_for_node_Try_npm_i_save_dev_types_Slashnode_and_then_add_node_to_the_types_field_in_your_tsconfig + : ts.Diagnostics.Cannot_find_name_0_Do_you_need_to_install_type_definitions_for_node_Try_npm_i_save_dev_types_Slashnode; case "Map": case "Set": case "Promise": @@ -23048,154 +22511,148 @@ namespace ts { case "Reflect": case "BigInt64Array": case "BigUint64Array": - return Diagnostics.Cannot_find_name_0_Do_you_need_to_change_your_target_library_Try_changing_the_lib_compiler_option_to_1_or_later; + return ts.Diagnostics.Cannot_find_name_0_Do_you_need_to_change_your_target_library_Try_changing_the_lib_compiler_option_to_1_or_later; case "await": - if (isCallExpression(node.parent)) { - return Diagnostics.Cannot_find_name_0_Did_you_mean_to_write_this_in_an_async_function; + if (ts.isCallExpression(node.parent)) { + return ts.Diagnostics.Cannot_find_name_0_Did_you_mean_to_write_this_in_an_async_function; } // falls through default: - if (node.parent.kind === SyntaxKind.ShorthandPropertyAssignment) { - return Diagnostics.No_value_exists_in_scope_for_the_shorthand_property_0_Either_declare_one_or_provide_an_initializer; + if (node.parent.kind === ts.SyntaxKind.ShorthandPropertyAssignment) { + return ts.Diagnostics.No_value_exists_in_scope_for_the_shorthand_property_0_Either_declare_one_or_provide_an_initializer; } else { - return Diagnostics.Cannot_find_name_0; + return ts.Diagnostics.Cannot_find_name_0; } } } - function getResolvedSymbol(node: Identifier): Symbol { + function getResolvedSymbol(node: ts.Identifier): ts.Symbol { const links = getNodeLinks(node); if (!links.resolvedSymbol) { - links.resolvedSymbol = !nodeIsMissing(node) && - resolveName( - node, - node.escapedText, - SymbolFlags.Value | SymbolFlags.ExportValue, - getCannotFindNameDiagnosticForName(node), - node, - !isWriteOnlyAccess(node), + links.resolvedSymbol = !ts.nodeIsMissing(node) && + resolveName(node, node.escapedText, ts.SymbolFlags.Value | ts.SymbolFlags.ExportValue, getCannotFindNameDiagnosticForName(node), node, !ts.isWriteOnlyAccess(node), /*excludeGlobals*/ false) || unknownSymbol; } return links.resolvedSymbol; } - function isInTypeQuery(node: Node): boolean { + function isInTypeQuery(node: ts.Node): boolean { // TypeScript 1.0 spec (April 2014): 3.6.3 // A type query consists of the keyword typeof followed by an expression. // The expression is restricted to a single identifier or a sequence of identifiers separated by periods - return !!findAncestor( - node, - n => n.kind === SyntaxKind.TypeQuery ? true : n.kind === SyntaxKind.Identifier || n.kind === SyntaxKind.QualifiedName ? false : "quit"); + return !!ts.findAncestor(node, n => n.kind === ts.SyntaxKind.TypeQuery ? true : n.kind === ts.SyntaxKind.Identifier || n.kind === ts.SyntaxKind.QualifiedName ? false : "quit"); } // Return the flow cache key for a "dotted name" (i.e. a sequence of identifiers // separated by dots). The key consists of the id of the symbol referenced by the // leftmost identifier followed by zero or more property names separated by dots. // The result is undefined if the reference isn't a dotted name. - function getFlowCacheKey(node: Node, declaredType: Type, initialType: Type, flowContainer: Node | undefined): string | undefined { + function getFlowCacheKey(node: ts.Node, declaredType: ts.Type, initialType: ts.Type, flowContainer: ts.Node | undefined): string | undefined { switch (node.kind) { - case SyntaxKind.Identifier: - if (!isThisInTypeQuery(node)) { - const symbol = getResolvedSymbol(node as Identifier); + case ts.SyntaxKind.Identifier: + if (!ts.isThisInTypeQuery(node)) { + const symbol = getResolvedSymbol(node as ts.Identifier); return symbol !== unknownSymbol ? `${flowContainer ? getNodeId(flowContainer) : "-1"}|${getTypeId(declaredType)}|${getTypeId(initialType)}|${getSymbolId(symbol)}` : undefined; } // falls through - case SyntaxKind.ThisKeyword: + case ts.SyntaxKind.ThisKeyword: return `0|${flowContainer ? getNodeId(flowContainer) : "-1"}|${getTypeId(declaredType)}|${getTypeId(initialType)}`; - case SyntaxKind.NonNullExpression: - case SyntaxKind.ParenthesizedExpression: - return getFlowCacheKey((node as NonNullExpression | ParenthesizedExpression).expression, declaredType, initialType, flowContainer); - case SyntaxKind.QualifiedName: - const left = getFlowCacheKey((node as QualifiedName).left, declaredType, initialType, flowContainer); - return left && left + "." + (node as QualifiedName).right.escapedText; - case SyntaxKind.PropertyAccessExpression: - case SyntaxKind.ElementAccessExpression: - const propName = getAccessedPropertyName(node as AccessExpression); + case ts.SyntaxKind.NonNullExpression: + case ts.SyntaxKind.ParenthesizedExpression: + return getFlowCacheKey((node as ts.NonNullExpression | ts.ParenthesizedExpression).expression, declaredType, initialType, flowContainer); + case ts.SyntaxKind.QualifiedName: + const left = getFlowCacheKey((node as ts.QualifiedName).left, declaredType, initialType, flowContainer); + return left && left + "." + (node as ts.QualifiedName).right.escapedText; + case ts.SyntaxKind.PropertyAccessExpression: + case ts.SyntaxKind.ElementAccessExpression: + const propName = getAccessedPropertyName(node as ts.AccessExpression); if (propName !== undefined) { - const key = getFlowCacheKey((node as AccessExpression).expression, declaredType, initialType, flowContainer); + const key = getFlowCacheKey((node as ts.AccessExpression).expression, declaredType, initialType, flowContainer); return key && key + "." + propName; } } return undefined; } - function isMatchingReference(source: Node, target: Node): boolean { + function isMatchingReference(source: ts.Node, target: ts.Node): boolean { switch (target.kind) { - case SyntaxKind.ParenthesizedExpression: - case SyntaxKind.NonNullExpression: - return isMatchingReference(source, (target as NonNullExpression | ParenthesizedExpression).expression); - case SyntaxKind.BinaryExpression: - return (isAssignmentExpression(target) && isMatchingReference(source, target.left)) || - (isBinaryExpression(target) && target.operatorToken.kind === SyntaxKind.CommaToken && isMatchingReference(source, target.right)); + case ts.SyntaxKind.ParenthesizedExpression: + case ts.SyntaxKind.NonNullExpression: + return isMatchingReference(source, (target as ts.NonNullExpression | ts.ParenthesizedExpression).expression); + case ts.SyntaxKind.BinaryExpression: + return (ts.isAssignmentExpression(target) && isMatchingReference(source, target.left)) || + (ts.isBinaryExpression(target) && target.operatorToken.kind === ts.SyntaxKind.CommaToken && isMatchingReference(source, target.right)); } switch (source.kind) { - case SyntaxKind.MetaProperty: - return target.kind === SyntaxKind.MetaProperty - && (source as MetaProperty).keywordToken === (target as MetaProperty).keywordToken - && (source as MetaProperty).name.escapedText === (target as MetaProperty).name.escapedText; - case SyntaxKind.Identifier: - case SyntaxKind.PrivateIdentifier: - return isThisInTypeQuery(source) ? - target.kind === SyntaxKind.ThisKeyword : - target.kind === SyntaxKind.Identifier && getResolvedSymbol(source as Identifier) === getResolvedSymbol(target as Identifier) || - (target.kind === SyntaxKind.VariableDeclaration || target.kind === SyntaxKind.BindingElement) && - getExportSymbolOfValueSymbolIfExported(getResolvedSymbol(source as Identifier)) === getSymbolOfNode(target); - case SyntaxKind.ThisKeyword: - return target.kind === SyntaxKind.ThisKeyword; - case SyntaxKind.SuperKeyword: - return target.kind === SyntaxKind.SuperKeyword; - case SyntaxKind.NonNullExpression: - case SyntaxKind.ParenthesizedExpression: - return isMatchingReference((source as NonNullExpression | ParenthesizedExpression).expression, target); - case SyntaxKind.PropertyAccessExpression: - case SyntaxKind.ElementAccessExpression: - const sourcePropertyName = getAccessedPropertyName(source as AccessExpression); - const targetPropertyName = isAccessExpression(target) ? getAccessedPropertyName(target) : undefined; + case ts.SyntaxKind.MetaProperty: + return target.kind === ts.SyntaxKind.MetaProperty + && (source as ts.MetaProperty).keywordToken === (target as ts.MetaProperty).keywordToken + && (source as ts.MetaProperty).name.escapedText === (target as ts.MetaProperty).name.escapedText; + case ts.SyntaxKind.Identifier: + case ts.SyntaxKind.PrivateIdentifier: + return ts.isThisInTypeQuery(source) ? + target.kind === ts.SyntaxKind.ThisKeyword : + target.kind === ts.SyntaxKind.Identifier && getResolvedSymbol(source as ts.Identifier) === getResolvedSymbol(target as ts.Identifier) || + (target.kind === ts.SyntaxKind.VariableDeclaration || target.kind === ts.SyntaxKind.BindingElement) && + getExportSymbolOfValueSymbolIfExported(getResolvedSymbol(source as ts.Identifier)) === getSymbolOfNode(target); + case ts.SyntaxKind.ThisKeyword: + return target.kind === ts.SyntaxKind.ThisKeyword; + case ts.SyntaxKind.SuperKeyword: + return target.kind === ts.SyntaxKind.SuperKeyword; + case ts.SyntaxKind.NonNullExpression: + case ts.SyntaxKind.ParenthesizedExpression: + return isMatchingReference((source as ts.NonNullExpression | ts.ParenthesizedExpression).expression, target); + case ts.SyntaxKind.PropertyAccessExpression: + case ts.SyntaxKind.ElementAccessExpression: + const sourcePropertyName = getAccessedPropertyName(source as ts.AccessExpression); + const targetPropertyName = ts.isAccessExpression(target) ? getAccessedPropertyName(target) : undefined; return sourcePropertyName !== undefined && targetPropertyName !== undefined && targetPropertyName === sourcePropertyName && - isMatchingReference((source as AccessExpression).expression, (target as AccessExpression).expression); - case SyntaxKind.QualifiedName: - return isAccessExpression(target) && - (source as QualifiedName).right.escapedText === getAccessedPropertyName(target) && - isMatchingReference((source as QualifiedName).left, target.expression); - case SyntaxKind.BinaryExpression: - return (isBinaryExpression(source) && source.operatorToken.kind === SyntaxKind.CommaToken && isMatchingReference(source.right, target)); + isMatchingReference((source as ts.AccessExpression).expression, (target as ts.AccessExpression).expression); + case ts.SyntaxKind.QualifiedName: + return ts.isAccessExpression(target) && + (source as ts.QualifiedName).right.escapedText === getAccessedPropertyName(target) && + isMatchingReference((source as ts.QualifiedName).left, target.expression); + case ts.SyntaxKind.BinaryExpression: + return (ts.isBinaryExpression(source) && source.operatorToken.kind === ts.SyntaxKind.CommaToken && isMatchingReference(source.right, target)); } return false; } - function getAccessedPropertyName(access: AccessExpression | BindingElement | ParameterDeclaration): __String | undefined { - if (isPropertyAccessExpression(access)) { + function getAccessedPropertyName(access: ts.AccessExpression | ts.BindingElement | ts.ParameterDeclaration): ts.__String | undefined { + if (ts.isPropertyAccessExpression(access)) { return access.name.escapedText; } - if (isElementAccessExpression(access)) { + if (ts.isElementAccessExpression(access)) { return tryGetElementAccessExpressionName(access); } - if (isBindingElement(access)) { + if (ts.isBindingElement(access)) { const name = getDestructuringPropertyName(access); - return name ? escapeLeadingUnderscores(name) : undefined; + return name ? ts.escapeLeadingUnderscores(name) : undefined; } - if (isParameter(access)) { - return ("" + access.parent.parameters.indexOf(access)) as __String; + if (ts.isParameter(access)) { + return ("" + access.parent.parameters.indexOf(access)) as ts.__String; } return undefined; } - function tryGetNameFromType(type: Type) { - return type.flags & TypeFlags.UniqueESSymbol ? (type as UniqueESSymbolType).escapedName : - type.flags & TypeFlags.StringOrNumberLiteral ? escapeLeadingUnderscores("" + (type as StringLiteralType | NumberLiteralType).value) : undefined; + function tryGetNameFromType(type: ts.Type) { + return type.flags & ts.TypeFlags.UniqueESSymbol ? (type as ts.UniqueESSymbolType).escapedName : + type.flags & ts.TypeFlags.StringOrNumberLiteral ? ts.escapeLeadingUnderscores("" + (type as ts.StringLiteralType | ts.NumberLiteralType).value) : undefined; } - function tryGetElementAccessExpressionName(node: ElementAccessExpression) { - if (isStringOrNumericLiteralLike(node.argumentExpression)) { - return escapeLeadingUnderscores(node.argumentExpression.text); + function tryGetElementAccessExpressionName(node: ts.ElementAccessExpression) { + if (ts.isStringOrNumericLiteralLike(node.argumentExpression)) { + return ts.escapeLeadingUnderscores(node.argumentExpression.text); } - if (isEntityNameExpression(node.argumentExpression)) { - const symbol = resolveEntityName(node.argumentExpression, SymbolFlags.Value, /*ignoreErrors*/ true); - if (!symbol || !isConstVariable(symbol)) return undefined; + if (ts.isEntityNameExpression(node.argumentExpression)) { + const symbol = resolveEntityName(node.argumentExpression, ts.SymbolFlags.Value, /*ignoreErrors*/ true); + if (!symbol || !isConstVariable(symbol)) + return undefined; const declaration = symbol.valueDeclaration; - if (declaration === undefined) return undefined; + if (declaration === undefined) + return undefined; const type = tryGetTypeFromEffectiveTypeNode(declaration); if (type) { @@ -23205,16 +22662,16 @@ namespace ts { } } - if (hasOnlyExpressionInitializer(declaration)) { - const initializer = getEffectiveInitializer(declaration); + if (ts.hasOnlyExpressionInitializer(declaration)) { + const initializer = ts.getEffectiveInitializer(declaration); return initializer && tryGetNameFromType(getTypeOfExpression(initializer)); } } return undefined; } - function containsMatchingReference(source: Node, target: Node) { - while (isAccessExpression(source)) { + function containsMatchingReference(source: ts.Node, target: ts.Node) { + while (ts.isAccessExpression(source)) { source = source.expression; if (isMatchingReference(source, target)) { return true; @@ -23223,8 +22680,8 @@ namespace ts { return false; } - function optionalChainContainsReference(source: Node, target: Node) { - while (isOptionalChain(source)) { + function optionalChainContainsReference(source: ts.Node, target: ts.Node) { + while (ts.isOptionalChain(source)) { source = source.expression; if (isMatchingReference(source, target)) { return true; @@ -23233,23 +22690,23 @@ namespace ts { return false; } - function isDiscriminantProperty(type: Type | undefined, name: __String) { - if (type && type.flags & TypeFlags.Union) { - const prop = getUnionOrIntersectionProperty(type as UnionType, name); - if (prop && getCheckFlags(prop) & CheckFlags.SyntheticProperty) { - if ((prop as TransientSymbol).isDiscriminantProperty === undefined) { - (prop as TransientSymbol).isDiscriminantProperty = - ((prop as TransientSymbol).checkFlags & CheckFlags.Discriminant) === CheckFlags.Discriminant && + function isDiscriminantProperty(type: ts.Type | undefined, name: ts.__String) { + if (type && type.flags & ts.TypeFlags.Union) { + const prop = getUnionOrIntersectionProperty(type as ts.UnionType, name); + if (prop && ts.getCheckFlags(prop) & ts.CheckFlags.SyntheticProperty) { + if ((prop as ts.TransientSymbol).isDiscriminantProperty === undefined) { + (prop as ts.TransientSymbol).isDiscriminantProperty = + ((prop as ts.TransientSymbol).checkFlags & ts.CheckFlags.Discriminant) === ts.CheckFlags.Discriminant && !isGenericType(getTypeOfSymbol(prop)); } - return !!(prop as TransientSymbol).isDiscriminantProperty; + return !!(prop as ts.TransientSymbol).isDiscriminantProperty; } } return false; } - function findDiscriminantProperties(sourceProperties: Symbol[], target: Type): Symbol[] | undefined { - let result: Symbol[] | undefined; + function findDiscriminantProperties(sourceProperties: ts.Symbol[], target: ts.Type): ts.Symbol[] | undefined { + let result: ts.Symbol[] | undefined; for (const sourceProperty of sourceProperties) { if (isDiscriminantProperty(target, sourceProperty.escapedName)) { if (result) { @@ -23266,11 +22723,11 @@ namespace ts { // types of the property by that name in each constituent type. No map is returned if some key property // has a non-literal type or if less than 10 or less than 50% of the constituents have a unique key. // Entries with duplicate keys have unknownType as the value. - function mapTypesByKeyProperty(types: Type[], name: __String) { - const map = new Map(); + function mapTypesByKeyProperty(types: ts.Type[], name: ts.__String) { + const map = new ts.Map(); let count = 0; for (const type of types) { - if (type.flags & (TypeFlags.Object | TypeFlags.Intersection | TypeFlags.InstantiableNonPrimitive)) { + if (type.flags & (ts.TypeFlags.Object | ts.TypeFlags.Intersection | ts.TypeFlags.InstantiableNonPrimitive)) { const discriminant = getTypeOfPropertyOfType(type, name); if (discriminant) { if (!isLiteralType(discriminant)) { @@ -23288,7 +22745,8 @@ namespace ts { duplicate = true; } }); - if (!duplicate) count++; + if (!duplicate) + count++; } } } @@ -23297,22 +22755,21 @@ namespace ts { // Return the name of a discriminant property for which it was possible and feasible to construct a map of // constituent types keyed by the literal types of the property by that name in each constituent type. - function getKeyPropertyName(unionType: UnionType): __String | undefined { + function getKeyPropertyName(unionType: ts.UnionType): ts.__String | undefined { const types = unionType.types; // We only construct maps for unions with many non-primitive constituents. - if (types.length < 10 || getObjectFlags(unionType) & ObjectFlags.PrimitiveUnion || - countWhere(types, t => !!(t.flags & (TypeFlags.Object | TypeFlags.InstantiableNonPrimitive))) < 10) { + if (types.length < 10 || ts.getObjectFlags(unionType) & ts.ObjectFlags.PrimitiveUnion || + ts.countWhere(types, t => !!(t.flags & (ts.TypeFlags.Object | ts.TypeFlags.InstantiableNonPrimitive))) < 10) { return undefined; } if (unionType.keyPropertyName === undefined) { // The candidate key property name is the name of the first property with a unit type in one of the // constituent types. - const keyPropertyName = forEach(types, t => - t.flags & (TypeFlags.Object | TypeFlags.InstantiableNonPrimitive) ? - forEach(getPropertiesOfType(t), p => isUnitType(getTypeOfSymbol(p)) ? p.escapedName : undefined) : + const keyPropertyName = ts.forEach(types, t => t.flags & (ts.TypeFlags.Object | ts.TypeFlags.InstantiableNonPrimitive) ? + ts.forEach(getPropertiesOfType(t), p => isUnitType(getTypeOfSymbol(p)) ? p.escapedName : undefined) : undefined); const mapByKeyProperty = keyPropertyName && mapTypesByKeyProperty(types, keyPropertyName); - unionType.keyPropertyName = mapByKeyProperty ? keyPropertyName : "" as __String; + unionType.keyPropertyName = mapByKeyProperty ? keyPropertyName : "" as ts.__String; unionType.constituentMap = mapByKeyProperty; } return (unionType.keyPropertyName as string).length ? unionType.keyPropertyName : undefined; @@ -23320,30 +22777,30 @@ namespace ts { // Given a union type for which getKeyPropertyName returned a non-undefined result, return the constituent // that corresponds to the given key type for that property name. - function getConstituentTypeForKeyType(unionType: UnionType, keyType: Type) { + function getConstituentTypeForKeyType(unionType: ts.UnionType, keyType: ts.Type) { const result = unionType.constituentMap?.get(getTypeId(getRegularTypeOfLiteralType(keyType))); return result !== unknownType ? result : undefined; } - function getMatchingUnionConstituentForType(unionType: UnionType, type: Type) { + function getMatchingUnionConstituentForType(unionType: ts.UnionType, type: ts.Type) { const keyPropertyName = getKeyPropertyName(unionType); const propType = keyPropertyName && getTypeOfPropertyOfType(type, keyPropertyName); return propType && getConstituentTypeForKeyType(unionType, propType); } - function getMatchingUnionConstituentForObjectLiteral(unionType: UnionType, node: ObjectLiteralExpression) { + function getMatchingUnionConstituentForObjectLiteral(unionType: ts.UnionType, node: ts.ObjectLiteralExpression) { const keyPropertyName = getKeyPropertyName(unionType); - const propNode = keyPropertyName && find(node.properties, p => p.symbol && p.kind === SyntaxKind.PropertyAssignment && + const propNode = keyPropertyName && ts.find(node.properties, p => p.symbol && p.kind === ts.SyntaxKind.PropertyAssignment && p.symbol.escapedName === keyPropertyName && isPossiblyDiscriminantValue(p.initializer)); - const propType = propNode && getContextFreeTypeOfExpression((propNode as PropertyAssignment).initializer); + const propType = propNode && getContextFreeTypeOfExpression((propNode as ts.PropertyAssignment).initializer); return propType && getConstituentTypeForKeyType(unionType, propType); } - function isOrContainsMatchingReference(source: Node, target: Node) { + function isOrContainsMatchingReference(source: ts.Node, target: ts.Node) { return isMatchingReference(source, target) || containsMatchingReference(source, target); } - function hasMatchingArgument(expression: CallExpression | NewExpression, reference: Node) { + function hasMatchingArgument(expression: ts.CallExpression | ts.NewExpression, reference: ts.Node) { if (expression.arguments) { for (const argument of expression.arguments) { if (isOrContainsMatchingReference(reference, argument)) { @@ -23351,14 +22808,14 @@ namespace ts { } } } - if (expression.expression.kind === SyntaxKind.PropertyAccessExpression && - isOrContainsMatchingReference(reference, (expression.expression as PropertyAccessExpression).expression)) { + if (expression.expression.kind === ts.SyntaxKind.PropertyAccessExpression && + isOrContainsMatchingReference(reference, (expression.expression as ts.PropertyAccessExpression).expression)) { return true; } return false; } - function getFlowNodeId(flow: FlowNode): number { + function getFlowNodeId(flow: ts.FlowNode): number { if (!flow.id || flow.id < 0) { flow.id = nextFlowId; nextFlowId++; @@ -23366,11 +22823,11 @@ namespace ts { return flow.id; } - function typeMaybeAssignableTo(source: Type, target: Type) { - if (!(source.flags & TypeFlags.Union)) { + function typeMaybeAssignableTo(source: ts.Type, target: ts.Type) { + if (!(source.flags & ts.TypeFlags.Union)) { return isTypeAssignableTo(source, target); } - for (const t of (source as UnionType).types) { + for (const t of (source as ts.UnionType).types) { if (isTypeAssignableTo(t, target)) { return true; } @@ -23381,13 +22838,13 @@ namespace ts { // Remove those constituent types of declaredType to which no constituent type of assignedType is assignable. // For example, when a variable of type number | string | boolean is assigned a value of type number | boolean, // we remove type string. - function getAssignmentReducedType(declaredType: UnionType, assignedType: Type) { + function getAssignmentReducedType(declaredType: ts.UnionType, assignedType: ts.Type) { if (declaredType !== assignedType) { - if (assignedType.flags & TypeFlags.Never) { + if (assignedType.flags & ts.TypeFlags.Never) { return assignedType; } let reducedType = filterType(declaredType, t => typeMaybeAssignableTo(assignedType, t)); - if (assignedType.flags & TypeFlags.BooleanLiteral && isFreshLiteralType(assignedType)) { + if (assignedType.flags & ts.TypeFlags.BooleanLiteral && isFreshLiteralType(assignedType)) { reducedType = mapType(reducedType, getFreshTypeOfLiteralType); // Ensure that if the assignment is a fresh type, that we narrow to fresh types } // Our crude heuristic produces an invalid result in some cases: see GH#26130. @@ -23401,93 +22858,93 @@ namespace ts { return declaredType; } - function isFunctionObjectType(type: ObjectType): boolean { + function isFunctionObjectType(type: ts.ObjectType): boolean { // We do a quick check for a "bind" property before performing the more expensive subtype // check. This gives us a quicker out in the common case where an object type is not a function. const resolved = resolveStructuredTypeMembers(type); return !!(resolved.callSignatures.length || resolved.constructSignatures.length || - resolved.members.get("bind" as __String) && isTypeSubtypeOf(type, globalFunctionType)); + resolved.members.get("bind" as ts.__String) && isTypeSubtypeOf(type, globalFunctionType)); } - function getTypeFacts(type: Type, ignoreObjects = false): TypeFacts { + function getTypeFacts(type: ts.Type, ignoreObjects = false): TypeFacts { const flags = type.flags; - if (flags & TypeFlags.String) { + if (flags & ts.TypeFlags.String) { return strictNullChecks ? TypeFacts.StringStrictFacts : TypeFacts.StringFacts; } - if (flags & TypeFlags.StringLiteral) { - const isEmpty = (type as StringLiteralType).value === ""; + if (flags & ts.TypeFlags.StringLiteral) { + const isEmpty = (type as ts.StringLiteralType).value === ""; return strictNullChecks ? isEmpty ? TypeFacts.EmptyStringStrictFacts : TypeFacts.NonEmptyStringStrictFacts : isEmpty ? TypeFacts.EmptyStringFacts : TypeFacts.NonEmptyStringFacts; } - if (flags & (TypeFlags.Number | TypeFlags.Enum)) { + if (flags & (ts.TypeFlags.Number | ts.TypeFlags.Enum)) { return strictNullChecks ? TypeFacts.NumberStrictFacts : TypeFacts.NumberFacts; } - if (flags & TypeFlags.NumberLiteral) { - const isZero = (type as NumberLiteralType).value === 0; + if (flags & ts.TypeFlags.NumberLiteral) { + const isZero = (type as ts.NumberLiteralType).value === 0; return strictNullChecks ? isZero ? TypeFacts.ZeroNumberStrictFacts : TypeFacts.NonZeroNumberStrictFacts : isZero ? TypeFacts.ZeroNumberFacts : TypeFacts.NonZeroNumberFacts; } - if (flags & TypeFlags.BigInt) { + if (flags & ts.TypeFlags.BigInt) { return strictNullChecks ? TypeFacts.BigIntStrictFacts : TypeFacts.BigIntFacts; } - if (flags & TypeFlags.BigIntLiteral) { - const isZero = isZeroBigInt(type as BigIntLiteralType); + if (flags & ts.TypeFlags.BigIntLiteral) { + const isZero = isZeroBigInt(type as ts.BigIntLiteralType); return strictNullChecks ? isZero ? TypeFacts.ZeroBigIntStrictFacts : TypeFacts.NonZeroBigIntStrictFacts : isZero ? TypeFacts.ZeroBigIntFacts : TypeFacts.NonZeroBigIntFacts; } - if (flags & TypeFlags.Boolean) { + if (flags & ts.TypeFlags.Boolean) { return strictNullChecks ? TypeFacts.BooleanStrictFacts : TypeFacts.BooleanFacts; } - if (flags & TypeFlags.BooleanLike) { + if (flags & ts.TypeFlags.BooleanLike) { return strictNullChecks ? (type === falseType || type === regularFalseType) ? TypeFacts.FalseStrictFacts : TypeFacts.TrueStrictFacts : (type === falseType || type === regularFalseType) ? TypeFacts.FalseFacts : TypeFacts.TrueFacts; } - if (flags & TypeFlags.Object) { + if (flags & ts.TypeFlags.Object) { if (ignoreObjects) { return TypeFacts.AndFactsMask; // This is the identity element for computing type facts of intersection. } - return getObjectFlags(type) & ObjectFlags.Anonymous && isEmptyObjectType(type as ObjectType) ? + return ts.getObjectFlags(type) & ts.ObjectFlags.Anonymous && isEmptyObjectType(type as ts.ObjectType) ? strictNullChecks ? TypeFacts.EmptyObjectStrictFacts : TypeFacts.EmptyObjectFacts : - isFunctionObjectType(type as ObjectType) ? + isFunctionObjectType(type as ts.ObjectType) ? strictNullChecks ? TypeFacts.FunctionStrictFacts : TypeFacts.FunctionFacts : strictNullChecks ? TypeFacts.ObjectStrictFacts : TypeFacts.ObjectFacts; } - if (flags & (TypeFlags.Void | TypeFlags.Undefined)) { + if (flags & (ts.TypeFlags.Void | ts.TypeFlags.Undefined)) { return TypeFacts.UndefinedFacts; } - if (flags & TypeFlags.Null) { + if (flags & ts.TypeFlags.Null) { return TypeFacts.NullFacts; } - if (flags & TypeFlags.ESSymbolLike) { + if (flags & ts.TypeFlags.ESSymbolLike) { return strictNullChecks ? TypeFacts.SymbolStrictFacts : TypeFacts.SymbolFacts; } - if (flags & TypeFlags.NonPrimitive) { + if (flags & ts.TypeFlags.NonPrimitive) { return strictNullChecks ? TypeFacts.ObjectStrictFacts : TypeFacts.ObjectFacts; } - if (flags & TypeFlags.Never) { + if (flags & ts.TypeFlags.Never) { return TypeFacts.None; } - if (flags & TypeFlags.Instantiable) { + if (flags & ts.TypeFlags.Instantiable) { return !isPatternLiteralType(type) ? getTypeFacts(getBaseConstraintOfType(type) || unknownType, ignoreObjects) : strictNullChecks ? TypeFacts.NonEmptyStringStrictFacts : TypeFacts.NonEmptyStringFacts; } - if (flags & TypeFlags.Union) { - return reduceLeft((type as UnionType).types, (facts, t) => facts | getTypeFacts(t, ignoreObjects), TypeFacts.None); + if (flags & ts.TypeFlags.Union) { + return ts.reduceLeft((type as ts.UnionType).types, (facts, t) => facts | getTypeFacts(t, ignoreObjects), TypeFacts.None); } - if (flags & TypeFlags.Intersection) { + if (flags & ts.TypeFlags.Intersection) { // When an intersection contains a primitive type we ignore object type constituents as they are // presumably type tags. For example, in string & { __kind__: "name" } we ignore the object type. - ignoreObjects ||= maybeTypeOfKind(type, TypeFlags.Primitive); - return getIntersectionTypeFacts(type as IntersectionType, ignoreObjects); + ignoreObjects ||= maybeTypeOfKind(type, ts.TypeFlags.Primitive); + return getIntersectionTypeFacts(type as ts.IntersectionType, ignoreObjects); } return TypeFacts.All; } - function getIntersectionTypeFacts(type: IntersectionType, ignoreObjects: boolean): TypeFacts { + function getIntersectionTypeFacts(type: ts.IntersectionType, ignoreObjects: boolean): TypeFacts { // When computing the type facts of an intersection type, certain type facts are computed as `and` // and others are computed as `or`. let oredFacts = TypeFacts.None; @@ -23500,105 +22957,106 @@ namespace ts { return oredFacts & TypeFacts.OrFactsMask | andedFacts & TypeFacts.AndFactsMask; } - function getTypeWithFacts(type: Type, include: TypeFacts) { + function getTypeWithFacts(type: ts.Type, include: TypeFacts) { return filterType(type, t => (getTypeFacts(t) & include) !== 0); } - function getTypeWithDefault(type: Type, defaultExpression: Expression) { + function getTypeWithDefault(type: ts.Type, defaultExpression: ts.Expression) { return defaultExpression ? getUnionType([getNonUndefinedType(type), getTypeOfExpression(defaultExpression)]) : type; } - function getTypeOfDestructuredProperty(type: Type, name: PropertyName) { + function getTypeOfDestructuredProperty(type: ts.Type, name: ts.PropertyName) { const nameType = getLiteralTypeFromPropertyName(name); - if (!isTypeUsableAsPropertyName(nameType)) return errorType; + if (!isTypeUsableAsPropertyName(nameType)) + return errorType; const text = getPropertyNameFromType(nameType); return getTypeOfPropertyOfType(type, text) || includeUndefinedInIndexSignature(getApplicableIndexInfoForName(type, text)?.type) || errorType; } - function getTypeOfDestructuredArrayElement(type: Type, index: number) { + function getTypeOfDestructuredArrayElement(type: ts.Type, index: number) { return everyType(type, isTupleLikeType) && getTupleElementType(type, index) || includeUndefinedInIndexSignature(checkIteratedTypeOrElementType(IterationUse.Destructuring, type, undefinedType, /*errorNode*/ undefined)) || errorType; } - function includeUndefinedInIndexSignature(type: Type | undefined): Type | undefined { - if (!type) return type; + function includeUndefinedInIndexSignature(type: ts.Type | undefined): ts.Type | undefined { + if (!type) + return type; return compilerOptions.noUncheckedIndexedAccess ? getUnionType([type, undefinedType]) : type; } - function getTypeOfDestructuredSpreadExpression(type: Type) { + function getTypeOfDestructuredSpreadExpression(type: ts.Type) { return createArrayType(checkIteratedTypeOrElementType(IterationUse.Destructuring, type, undefinedType, /*errorNode*/ undefined) || errorType); } - function getAssignedTypeOfBinaryExpression(node: BinaryExpression): Type { - const isDestructuringDefaultAssignment = - node.parent.kind === SyntaxKind.ArrayLiteralExpression && isDestructuringAssignmentTarget(node.parent) || - node.parent.kind === SyntaxKind.PropertyAssignment && isDestructuringAssignmentTarget(node.parent.parent); + function getAssignedTypeOfBinaryExpression(node: ts.BinaryExpression): ts.Type { + const isDestructuringDefaultAssignment = node.parent.kind === ts.SyntaxKind.ArrayLiteralExpression && isDestructuringAssignmentTarget(node.parent) || + node.parent.kind === ts.SyntaxKind.PropertyAssignment && isDestructuringAssignmentTarget(node.parent.parent); return isDestructuringDefaultAssignment ? getTypeWithDefault(getAssignedType(node), node.right) : getTypeOfExpression(node.right); } - function isDestructuringAssignmentTarget(parent: Node) { - return parent.parent.kind === SyntaxKind.BinaryExpression && (parent.parent as BinaryExpression).left === parent || - parent.parent.kind === SyntaxKind.ForOfStatement && (parent.parent as ForOfStatement).initializer === parent; + function isDestructuringAssignmentTarget(parent: ts.Node) { + return parent.parent.kind === ts.SyntaxKind.BinaryExpression && (parent.parent as ts.BinaryExpression).left === parent || + parent.parent.kind === ts.SyntaxKind.ForOfStatement && (parent.parent as ts.ForOfStatement).initializer === parent; } - function getAssignedTypeOfArrayLiteralElement(node: ArrayLiteralExpression, element: Expression): Type { + function getAssignedTypeOfArrayLiteralElement(node: ts.ArrayLiteralExpression, element: ts.Expression): ts.Type { return getTypeOfDestructuredArrayElement(getAssignedType(node), node.elements.indexOf(element)); } - function getAssignedTypeOfSpreadExpression(node: SpreadElement): Type { - return getTypeOfDestructuredSpreadExpression(getAssignedType(node.parent as ArrayLiteralExpression)); + function getAssignedTypeOfSpreadExpression(node: ts.SpreadElement): ts.Type { + return getTypeOfDestructuredSpreadExpression(getAssignedType(node.parent as ts.ArrayLiteralExpression)); } - function getAssignedTypeOfPropertyAssignment(node: PropertyAssignment | ShorthandPropertyAssignment): Type { + function getAssignedTypeOfPropertyAssignment(node: ts.PropertyAssignment | ts.ShorthandPropertyAssignment): ts.Type { return getTypeOfDestructuredProperty(getAssignedType(node.parent), node.name); } - function getAssignedTypeOfShorthandPropertyAssignment(node: ShorthandPropertyAssignment): Type { + function getAssignedTypeOfShorthandPropertyAssignment(node: ts.ShorthandPropertyAssignment): ts.Type { return getTypeWithDefault(getAssignedTypeOfPropertyAssignment(node), node.objectAssignmentInitializer!); } - function getAssignedType(node: Expression): Type { + function getAssignedType(node: ts.Expression): ts.Type { const { parent } = node; switch (parent.kind) { - case SyntaxKind.ForInStatement: + case ts.SyntaxKind.ForInStatement: return stringType; - case SyntaxKind.ForOfStatement: - return checkRightHandSideOfForOf(parent as ForOfStatement) || errorType; - case SyntaxKind.BinaryExpression: - return getAssignedTypeOfBinaryExpression(parent as BinaryExpression); - case SyntaxKind.DeleteExpression: + case ts.SyntaxKind.ForOfStatement: + return checkRightHandSideOfForOf(parent as ts.ForOfStatement) || errorType; + case ts.SyntaxKind.BinaryExpression: + return getAssignedTypeOfBinaryExpression(parent as ts.BinaryExpression); + case ts.SyntaxKind.DeleteExpression: return undefinedType; - case SyntaxKind.ArrayLiteralExpression: - return getAssignedTypeOfArrayLiteralElement(parent as ArrayLiteralExpression, node); - case SyntaxKind.SpreadElement: - return getAssignedTypeOfSpreadExpression(parent as SpreadElement); - case SyntaxKind.PropertyAssignment: - return getAssignedTypeOfPropertyAssignment(parent as PropertyAssignment); - case SyntaxKind.ShorthandPropertyAssignment: - return getAssignedTypeOfShorthandPropertyAssignment(parent as ShorthandPropertyAssignment); + case ts.SyntaxKind.ArrayLiteralExpression: + return getAssignedTypeOfArrayLiteralElement(parent as ts.ArrayLiteralExpression, node); + case ts.SyntaxKind.SpreadElement: + return getAssignedTypeOfSpreadExpression(parent as ts.SpreadElement); + case ts.SyntaxKind.PropertyAssignment: + return getAssignedTypeOfPropertyAssignment(parent as ts.PropertyAssignment); + case ts.SyntaxKind.ShorthandPropertyAssignment: + return getAssignedTypeOfShorthandPropertyAssignment(parent as ts.ShorthandPropertyAssignment); } return errorType; } - function getInitialTypeOfBindingElement(node: BindingElement): Type { + function getInitialTypeOfBindingElement(node: ts.BindingElement): ts.Type { const pattern = node.parent; - const parentType = getInitialType(pattern.parent as VariableDeclaration | BindingElement); - const type = pattern.kind === SyntaxKind.ObjectBindingPattern ? - getTypeOfDestructuredProperty(parentType, node.propertyName || node.name as Identifier) : + const parentType = getInitialType(pattern.parent as ts.VariableDeclaration | ts.BindingElement); + const type = pattern.kind === ts.SyntaxKind.ObjectBindingPattern ? + getTypeOfDestructuredProperty(parentType, node.propertyName || node.name as ts.Identifier) : !node.dotDotDotToken ? getTypeOfDestructuredArrayElement(parentType, pattern.elements.indexOf(node)) : getTypeOfDestructuredSpreadExpression(parentType); return getTypeWithDefault(type, node.initializer!); } - function getTypeOfInitializer(node: Expression) { + function getTypeOfInitializer(node: ts.Expression) { // Return the cached type if one is available. If the type of the variable was inferred // from its initializer, we'll already have cached the type. Otherwise we compute it now // without caching such that transient types are reflected. @@ -23606,66 +23064,66 @@ namespace ts { return links.resolvedType || getTypeOfExpression(node); } - function getInitialTypeOfVariableDeclaration(node: VariableDeclaration) { + function getInitialTypeOfVariableDeclaration(node: ts.VariableDeclaration) { if (node.initializer) { return getTypeOfInitializer(node.initializer); } - if (node.parent.parent.kind === SyntaxKind.ForInStatement) { + if (node.parent.parent.kind === ts.SyntaxKind.ForInStatement) { return stringType; } - if (node.parent.parent.kind === SyntaxKind.ForOfStatement) { + if (node.parent.parent.kind === ts.SyntaxKind.ForOfStatement) { return checkRightHandSideOfForOf(node.parent.parent) || errorType; } return errorType; } - function getInitialType(node: VariableDeclaration | BindingElement) { - return node.kind === SyntaxKind.VariableDeclaration ? + function getInitialType(node: ts.VariableDeclaration | ts.BindingElement) { + return node.kind === ts.SyntaxKind.VariableDeclaration ? getInitialTypeOfVariableDeclaration(node) : getInitialTypeOfBindingElement(node); } - function isEmptyArrayAssignment(node: VariableDeclaration | BindingElement | Expression) { - return node.kind === SyntaxKind.VariableDeclaration && (node as VariableDeclaration).initializer && - isEmptyArrayLiteral((node as VariableDeclaration).initializer!) || - node.kind !== SyntaxKind.BindingElement && node.parent.kind === SyntaxKind.BinaryExpression && - isEmptyArrayLiteral((node.parent as BinaryExpression).right); + function isEmptyArrayAssignment(node: ts.VariableDeclaration | ts.BindingElement | ts.Expression) { + return node.kind === ts.SyntaxKind.VariableDeclaration && (node as ts.VariableDeclaration).initializer && + isEmptyArrayLiteral((node as ts.VariableDeclaration).initializer!) || + node.kind !== ts.SyntaxKind.BindingElement && node.parent.kind === ts.SyntaxKind.BinaryExpression && + isEmptyArrayLiteral((node.parent as ts.BinaryExpression).right); } - function getReferenceCandidate(node: Expression): Expression { + function getReferenceCandidate(node: ts.Expression): ts.Expression { switch (node.kind) { - case SyntaxKind.ParenthesizedExpression: - return getReferenceCandidate((node as ParenthesizedExpression).expression); - case SyntaxKind.BinaryExpression: - switch ((node as BinaryExpression).operatorToken.kind) { - case SyntaxKind.EqualsToken: - case SyntaxKind.BarBarEqualsToken: - case SyntaxKind.AmpersandAmpersandEqualsToken: - case SyntaxKind.QuestionQuestionEqualsToken: - return getReferenceCandidate((node as BinaryExpression).left); - case SyntaxKind.CommaToken: - return getReferenceCandidate((node as BinaryExpression).right); + case ts.SyntaxKind.ParenthesizedExpression: + return getReferenceCandidate((node as ts.ParenthesizedExpression).expression); + case ts.SyntaxKind.BinaryExpression: + switch ((node as ts.BinaryExpression).operatorToken.kind) { + case ts.SyntaxKind.EqualsToken: + case ts.SyntaxKind.BarBarEqualsToken: + case ts.SyntaxKind.AmpersandAmpersandEqualsToken: + case ts.SyntaxKind.QuestionQuestionEqualsToken: + return getReferenceCandidate((node as ts.BinaryExpression).left); + case ts.SyntaxKind.CommaToken: + return getReferenceCandidate((node as ts.BinaryExpression).right); } } return node; } - function getReferenceRoot(node: Node): Node { + function getReferenceRoot(node: ts.Node): ts.Node { const { parent } = node; - return parent.kind === SyntaxKind.ParenthesizedExpression || - parent.kind === SyntaxKind.BinaryExpression && (parent as BinaryExpression).operatorToken.kind === SyntaxKind.EqualsToken && (parent as BinaryExpression).left === node || - parent.kind === SyntaxKind.BinaryExpression && (parent as BinaryExpression).operatorToken.kind === SyntaxKind.CommaToken && (parent as BinaryExpression).right === node ? + return parent.kind === ts.SyntaxKind.ParenthesizedExpression || + parent.kind === ts.SyntaxKind.BinaryExpression && (parent as ts.BinaryExpression).operatorToken.kind === ts.SyntaxKind.EqualsToken && (parent as ts.BinaryExpression).left === node || + parent.kind === ts.SyntaxKind.BinaryExpression && (parent as ts.BinaryExpression).operatorToken.kind === ts.SyntaxKind.CommaToken && (parent as ts.BinaryExpression).right === node ? getReferenceRoot(parent) : node; } - function getTypeOfSwitchClause(clause: CaseClause | DefaultClause) { - if (clause.kind === SyntaxKind.CaseClause) { + function getTypeOfSwitchClause(clause: ts.CaseClause | ts.DefaultClause) { + if (clause.kind === ts.SyntaxKind.CaseClause) { return getRegularTypeOfLiteralType(getTypeOfExpression(clause.expression)); } return neverType; } - function getSwitchClauseTypes(switchStatement: SwitchStatement): Type[] { + function getSwitchClauseTypes(switchStatement: ts.SwitchStatement): ts.Type[] { const links = getNodeLinks(switchStatement); if (!links.switchTypes) { links.switchTypes = []; @@ -23678,117 +23136,118 @@ namespace ts { // Get the types from all cases in a switch on `typeof`. An // `undefined` element denotes an explicit `default` clause. - function getSwitchClauseTypeOfWitnesses(switchStatement: SwitchStatement, retainDefault: false): string[]; - function getSwitchClauseTypeOfWitnesses(switchStatement: SwitchStatement, retainDefault: boolean): (string | undefined)[]; - function getSwitchClauseTypeOfWitnesses(switchStatement: SwitchStatement, retainDefault: boolean): (string | undefined)[] { + function getSwitchClauseTypeOfWitnesses(switchStatement: ts.SwitchStatement, retainDefault: false): string[]; + function getSwitchClauseTypeOfWitnesses(switchStatement: ts.SwitchStatement, retainDefault: boolean): (string | undefined)[]; + function getSwitchClauseTypeOfWitnesses(switchStatement: ts.SwitchStatement, retainDefault: boolean): (string | undefined)[] { const witnesses: (string | undefined)[] = []; for (const clause of switchStatement.caseBlock.clauses) { - if (clause.kind === SyntaxKind.CaseClause) { - if (isStringLiteralLike(clause.expression)) { + if (clause.kind === ts.SyntaxKind.CaseClause) { + if (ts.isStringLiteralLike(clause.expression)) { witnesses.push(clause.expression.text); continue; } - return emptyArray; + return ts.emptyArray; } - if (retainDefault) witnesses.push(/*explicitDefaultStatement*/ undefined); + if (retainDefault) + witnesses.push(/*explicitDefaultStatement*/ undefined); } return witnesses; } - function eachTypeContainedIn(source: Type, types: Type[]) { - return source.flags & TypeFlags.Union ? !forEach((source as UnionType).types, t => !contains(types, t)) : contains(types, source); + function eachTypeContainedIn(source: ts.Type, types: ts.Type[]) { + return source.flags & ts.TypeFlags.Union ? !ts.forEach((source as ts.UnionType).types, t => !ts.contains(types, t)) : ts.contains(types, source); } - function isTypeSubsetOf(source: Type, target: Type) { - return source === target || target.flags & TypeFlags.Union && isTypeSubsetOfUnion(source, target as UnionType); + function isTypeSubsetOf(source: ts.Type, target: ts.Type) { + return source === target || target.flags & ts.TypeFlags.Union && isTypeSubsetOfUnion(source, target as ts.UnionType); } - function isTypeSubsetOfUnion(source: Type, target: UnionType) { - if (source.flags & TypeFlags.Union) { - for (const t of (source as UnionType).types) { + function isTypeSubsetOfUnion(source: ts.Type, target: ts.UnionType) { + if (source.flags & ts.TypeFlags.Union) { + for (const t of (source as ts.UnionType).types) { if (!containsType(target.types, t)) { return false; } } return true; } - if (source.flags & TypeFlags.EnumLiteral && getBaseTypeOfEnumLiteralType(source as LiteralType) === target) { + if (source.flags & ts.TypeFlags.EnumLiteral && getBaseTypeOfEnumLiteralType(source as ts.LiteralType) === target) { return true; } return containsType(target.types, source); } - function forEachType(type: Type, f: (t: Type) => T | undefined): T | undefined { - return type.flags & TypeFlags.Union ? forEach((type as UnionType).types, f) : f(type); + function forEachType(type: ts.Type, f: (t: ts.Type) => T | undefined): T | undefined { + return type.flags & ts.TypeFlags.Union ? ts.forEach((type as ts.UnionType).types, f) : f(type); } - function someType(type: Type, f: (t: Type) => boolean): boolean { - return type.flags & TypeFlags.Union ? some((type as UnionType).types, f) : f(type); + function someType(type: ts.Type, f: (t: ts.Type) => boolean): boolean { + return type.flags & ts.TypeFlags.Union ? ts.some((type as ts.UnionType).types, f) : f(type); } - function everyType(type: Type, f: (t: Type) => boolean): boolean { - return type.flags & TypeFlags.Union ? every((type as UnionType).types, f) : f(type); + function everyType(type: ts.Type, f: (t: ts.Type) => boolean): boolean { + return type.flags & ts.TypeFlags.Union ? ts.every((type as ts.UnionType).types, f) : f(type); } - function everyContainedType(type: Type, f: (t: Type) => boolean): boolean { - return type.flags & TypeFlags.UnionOrIntersection ? every((type as UnionOrIntersectionType).types, f) : f(type); + function everyContainedType(type: ts.Type, f: (t: ts.Type) => boolean): boolean { + return type.flags & ts.TypeFlags.UnionOrIntersection ? ts.every((type as ts.UnionOrIntersectionType).types, f) : f(type); } - function filterType(type: Type, f: (t: Type) => boolean): Type { - if (type.flags & TypeFlags.Union) { - const types = (type as UnionType).types; - const filtered = filter(types, f); + function filterType(type: ts.Type, f: (t: ts.Type) => boolean): ts.Type { + if (type.flags & ts.TypeFlags.Union) { + const types = (type as ts.UnionType).types; + const filtered = ts.filter(types, f); if (filtered === types) { return type; } - const origin = (type as UnionType).origin; - let newOrigin: Type | undefined; - if (origin && origin.flags & TypeFlags.Union) { + const origin = (type as ts.UnionType).origin; + let newOrigin: ts.Type | undefined; + if (origin && origin.flags & ts.TypeFlags.Union) { // If the origin type is a (denormalized) union type, filter its non-union constituents. If that ends // up removing a smaller number of types than in the normalized constituent set (meaning some of the // filtered types are within nested unions in the origin), then we can't construct a new origin type. // Otherwise, if we have exactly one type left in the origin set, return that as the filtered type. // Otherwise, construct a new filtered origin type. - const originTypes = (origin as UnionType).types; - const originFiltered = filter(originTypes, t => !!(t.flags & TypeFlags.Union) || f(t)); + const originTypes = (origin as ts.UnionType).types; + const originFiltered = ts.filter(originTypes, t => !!(t.flags & ts.TypeFlags.Union) || f(t)); if (originTypes.length - originFiltered.length === types.length - filtered.length) { if (originFiltered.length === 1) { return originFiltered[0]; } - newOrigin = createOriginUnionOrIntersectionType(TypeFlags.Union, originFiltered); + newOrigin = createOriginUnionOrIntersectionType(ts.TypeFlags.Union, originFiltered); } } - return getUnionTypeFromSortedList(filtered, (type as UnionType).objectFlags, /*aliasSymbol*/ undefined, /*aliasTypeArguments*/ undefined, newOrigin); + return getUnionTypeFromSortedList(filtered, (type as ts.UnionType).objectFlags, /*aliasSymbol*/ undefined, /*aliasTypeArguments*/ undefined, newOrigin); } - return type.flags & TypeFlags.Never || f(type) ? type : neverType; + return type.flags & ts.TypeFlags.Never || f(type) ? type : neverType; } - function removeType(type: Type, targetType: Type) { + function removeType(type: ts.Type, targetType: ts.Type) { return filterType(type, t => t !== targetType); } - function countTypes(type: Type) { - return type.flags & TypeFlags.Union ? (type as UnionType).types.length : 1; + function countTypes(type: ts.Type) { + return type.flags & ts.TypeFlags.Union ? (type as ts.UnionType).types.length : 1; } // Apply a mapping function to a type and return the resulting type. If the source type // is a union type, the mapping function is applied to each constituent type and a union // of the resulting types is returned. - function mapType(type: Type, mapper: (t: Type) => Type, noReductions?: boolean): Type; - function mapType(type: Type, mapper: (t: Type) => Type | undefined, noReductions?: boolean): Type | undefined; - function mapType(type: Type, mapper: (t: Type) => Type | undefined, noReductions?: boolean): Type | undefined { - if (type.flags & TypeFlags.Never) { + function mapType(type: ts.Type, mapper: (t: ts.Type) => ts.Type, noReductions?: boolean): ts.Type; + function mapType(type: ts.Type, mapper: (t: ts.Type) => ts.Type | undefined, noReductions?: boolean): ts.Type | undefined; + function mapType(type: ts.Type, mapper: (t: ts.Type) => ts.Type | undefined, noReductions?: boolean): ts.Type | undefined { + if (type.flags & ts.TypeFlags.Never) { return type; } - if (!(type.flags & TypeFlags.Union)) { + if (!(type.flags & ts.TypeFlags.Union)) { return mapper(type); } - const origin = (type as UnionType).origin; - const types = origin && origin.flags & TypeFlags.Union ? (origin as UnionType).types : (type as UnionType).types; - let mappedTypes: Type[] | undefined; + const origin = (type as ts.UnionType).origin; + const types = origin && origin.flags & ts.TypeFlags.Union ? (origin as ts.UnionType).types : (type as ts.UnionType).types; + let mappedTypes: ts.Type[] | undefined; let changed = false; for (const t of types) { - const mapped = t.flags & TypeFlags.Union ? mapType(t, mapper, noReductions) : mapper(t); + const mapped = t.flags & ts.TypeFlags.Union ? mapType(t, mapper, noReductions) : mapper(t); changed ||= t !== mapped; if (mapped) { if (!mappedTypes) { @@ -23799,16 +23258,16 @@ namespace ts { } } } - return changed ? mappedTypes && getUnionType(mappedTypes, noReductions ? UnionReduction.None : UnionReduction.Literal) : type; + return changed ? mappedTypes && getUnionType(mappedTypes, noReductions ? ts.UnionReduction.None : ts.UnionReduction.Literal) : type; } - function mapTypeWithAlias(type: Type, mapper: (t: Type) => Type, aliasSymbol: Symbol | undefined, aliasTypeArguments: readonly Type[] | undefined) { - return type.flags & TypeFlags.Union && aliasSymbol ? - getUnionType(map((type as UnionType).types, mapper), UnionReduction.Literal, aliasSymbol, aliasTypeArguments) : + function mapTypeWithAlias(type: ts.Type, mapper: (t: ts.Type) => ts.Type, aliasSymbol: ts.Symbol | undefined, aliasTypeArguments: readonly ts.Type[] | undefined) { + return type.flags & ts.TypeFlags.Union && aliasSymbol ? + getUnionType(ts.map((type as ts.UnionType).types, mapper), ts.UnionReduction.Literal, aliasSymbol, aliasTypeArguments) : mapType(type, mapper); } - function extractTypesOfKind(type: Type, kind: TypeFlags) { + function extractTypesOfKind(type: ts.Type, kind: ts.TypeFlags) { return filterType(type, t => (t.flags & kind) !== 0); } @@ -23817,78 +23276,77 @@ namespace ts { // from typeWithLiterals. This is essentially a limited form of intersection between the two types. We avoid a // true intersection because it is more costly and, when applied to union types, generates a large number of // types we don't actually care about. - function replacePrimitivesWithLiterals(typeWithPrimitives: Type, typeWithLiterals: Type) { - if (maybeTypeOfKind(typeWithPrimitives, TypeFlags.String | TypeFlags.TemplateLiteral | TypeFlags.Number | TypeFlags.BigInt) && - maybeTypeOfKind(typeWithLiterals, TypeFlags.StringLiteral | TypeFlags.TemplateLiteral | TypeFlags.StringMapping | TypeFlags.NumberLiteral | TypeFlags.BigIntLiteral)) { - return mapType(typeWithPrimitives, t => - t.flags & TypeFlags.String ? extractTypesOfKind(typeWithLiterals, TypeFlags.String | TypeFlags.StringLiteral | TypeFlags.TemplateLiteral | TypeFlags.StringMapping) : - isPatternLiteralType(t) && !maybeTypeOfKind(typeWithLiterals, TypeFlags.String | TypeFlags.TemplateLiteral | TypeFlags.StringMapping) ? extractTypesOfKind(typeWithLiterals, TypeFlags.StringLiteral) : - t.flags & TypeFlags.Number ? extractTypesOfKind(typeWithLiterals, TypeFlags.Number | TypeFlags.NumberLiteral) : - t.flags & TypeFlags.BigInt ? extractTypesOfKind(typeWithLiterals, TypeFlags.BigInt | TypeFlags.BigIntLiteral) : t); + function replacePrimitivesWithLiterals(typeWithPrimitives: ts.Type, typeWithLiterals: ts.Type) { + if (maybeTypeOfKind(typeWithPrimitives, ts.TypeFlags.String | ts.TypeFlags.TemplateLiteral | ts.TypeFlags.Number | ts.TypeFlags.BigInt) && + maybeTypeOfKind(typeWithLiterals, ts.TypeFlags.StringLiteral | ts.TypeFlags.TemplateLiteral | ts.TypeFlags.StringMapping | ts.TypeFlags.NumberLiteral | ts.TypeFlags.BigIntLiteral)) { + return mapType(typeWithPrimitives, t => t.flags & ts.TypeFlags.String ? extractTypesOfKind(typeWithLiterals, ts.TypeFlags.String | ts.TypeFlags.StringLiteral | ts.TypeFlags.TemplateLiteral | ts.TypeFlags.StringMapping) : + isPatternLiteralType(t) && !maybeTypeOfKind(typeWithLiterals, ts.TypeFlags.String | ts.TypeFlags.TemplateLiteral | ts.TypeFlags.StringMapping) ? extractTypesOfKind(typeWithLiterals, ts.TypeFlags.StringLiteral) : + t.flags & ts.TypeFlags.Number ? extractTypesOfKind(typeWithLiterals, ts.TypeFlags.Number | ts.TypeFlags.NumberLiteral) : + t.flags & ts.TypeFlags.BigInt ? extractTypesOfKind(typeWithLiterals, ts.TypeFlags.BigInt | ts.TypeFlags.BigIntLiteral) : t); } return typeWithPrimitives; } - function isIncomplete(flowType: FlowType) { + function isIncomplete(flowType: ts.FlowType) { return flowType.flags === 0; } - function getTypeFromFlowType(flowType: FlowType) { - return flowType.flags === 0 ? (flowType as IncompleteType).type : flowType as Type; + function getTypeFromFlowType(flowType: ts.FlowType) { + return flowType.flags === 0 ? (flowType as ts.IncompleteType).type : flowType as ts.Type; } - function createFlowType(type: Type, incomplete: boolean): FlowType { - return incomplete ? { flags: 0, type: type.flags & TypeFlags.Never ? silentNeverType : type } : type; + function createFlowType(type: ts.Type, incomplete: boolean): ts.FlowType { + return incomplete ? { flags: 0, type: type.flags & ts.TypeFlags.Never ? silentNeverType : type } : type; } // An evolving array type tracks the element types that have so far been seen in an // 'x.push(value)' or 'x[n] = value' operation along the control flow graph. Evolving // array types are ultimately converted into manifest array types (using getFinalArrayType) // and never escape the getFlowTypeOfReference function. - function createEvolvingArrayType(elementType: Type): EvolvingArrayType { - const result = createObjectType(ObjectFlags.EvolvingArray) as EvolvingArrayType; + function createEvolvingArrayType(elementType: ts.Type): ts.EvolvingArrayType { + const result = createObjectType(ts.ObjectFlags.EvolvingArray) as ts.EvolvingArrayType; result.elementType = elementType; return result; } - function getEvolvingArrayType(elementType: Type): EvolvingArrayType { + function getEvolvingArrayType(elementType: ts.Type): ts.EvolvingArrayType { return evolvingArrayTypes[elementType.id] || (evolvingArrayTypes[elementType.id] = createEvolvingArrayType(elementType)); } // When adding evolving array element types we do not perform subtype reduction. Instead, // we defer subtype reduction until the evolving array type is finalized into a manifest // array type. - function addEvolvingArrayElementType(evolvingArrayType: EvolvingArrayType, node: Expression): EvolvingArrayType { + function addEvolvingArrayElementType(evolvingArrayType: ts.EvolvingArrayType, node: ts.Expression): ts.EvolvingArrayType { const elementType = getRegularTypeOfObjectLiteral(getBaseTypeOfLiteralType(getContextFreeTypeOfExpression(node))); return isTypeSubsetOf(elementType, evolvingArrayType.elementType) ? evolvingArrayType : getEvolvingArrayType(getUnionType([evolvingArrayType.elementType, elementType])); } - function createFinalArrayType(elementType: Type) { - return elementType.flags & TypeFlags.Never ? + function createFinalArrayType(elementType: ts.Type) { + return elementType.flags & ts.TypeFlags.Never ? autoArrayType : - createArrayType(elementType.flags & TypeFlags.Union ? - getUnionType((elementType as UnionType).types, UnionReduction.Subtype) : + createArrayType(elementType.flags & ts.TypeFlags.Union ? + getUnionType((elementType as ts.UnionType).types, ts.UnionReduction.Subtype) : elementType); } // We perform subtype reduction upon obtaining the final array type from an evolving array type. - function getFinalArrayType(evolvingArrayType: EvolvingArrayType): Type { + function getFinalArrayType(evolvingArrayType: ts.EvolvingArrayType): ts.Type { return evolvingArrayType.finalArrayType || (evolvingArrayType.finalArrayType = createFinalArrayType(evolvingArrayType.elementType)); } - function finalizeEvolvingArrayType(type: Type): Type { - return getObjectFlags(type) & ObjectFlags.EvolvingArray ? getFinalArrayType(type as EvolvingArrayType) : type; + function finalizeEvolvingArrayType(type: ts.Type): ts.Type { + return ts.getObjectFlags(type) & ts.ObjectFlags.EvolvingArray ? getFinalArrayType(type as ts.EvolvingArrayType) : type; } - function getElementTypeOfEvolvingArrayType(type: Type) { - return getObjectFlags(type) & ObjectFlags.EvolvingArray ? (type as EvolvingArrayType).elementType : neverType; + function getElementTypeOfEvolvingArrayType(type: ts.Type) { + return ts.getObjectFlags(type) & ts.ObjectFlags.EvolvingArray ? (type as ts.EvolvingArrayType).elementType : neverType; } - function isEvolvingArrayTypeList(types: Type[]) { + function isEvolvingArrayTypeList(types: ts.Type[]) { let hasEvolvingArrayType = false; for (const t of types) { - if (!(t.flags & TypeFlags.Never)) { - if (!(getObjectFlags(t) & ObjectFlags.EvolvingArray)) { + if (!(t.flags & ts.TypeFlags.Never)) { + if (!(ts.getObjectFlags(t) & ts.ObjectFlags.EvolvingArray)) { return false; } hasEvolvingArrayType = true; @@ -23899,37 +23357,36 @@ namespace ts { // Return true if the given node is 'x' in an 'x.length', x.push(value)', 'x.unshift(value)' or // 'x[n] = value' operation, where 'n' is an expression of type any, undefined, or a number-like type. - function isEvolvingArrayOperationTarget(node: Node) { + function isEvolvingArrayOperationTarget(node: ts.Node) { const root = getReferenceRoot(node); const parent = root.parent; - const isLengthPushOrUnshift = isPropertyAccessExpression(parent) && ( - parent.name.escapedText === "length" || - parent.parent.kind === SyntaxKind.CallExpression - && isIdentifier(parent.name) - && isPushOrUnshiftIdentifier(parent.name)); - const isElementAssignment = parent.kind === SyntaxKind.ElementAccessExpression && - (parent as ElementAccessExpression).expression === root && - parent.parent.kind === SyntaxKind.BinaryExpression && - (parent.parent as BinaryExpression).operatorToken.kind === SyntaxKind.EqualsToken && - (parent.parent as BinaryExpression).left === parent && - !isAssignmentTarget(parent.parent) && - isTypeAssignableToKind(getTypeOfExpression((parent as ElementAccessExpression).argumentExpression), TypeFlags.NumberLike); + const isLengthPushOrUnshift = ts.isPropertyAccessExpression(parent) && (parent.name.escapedText === "length" || + parent.parent.kind === ts.SyntaxKind.CallExpression + && ts.isIdentifier(parent.name) + && ts.isPushOrUnshiftIdentifier(parent.name)); + const isElementAssignment = parent.kind === ts.SyntaxKind.ElementAccessExpression && + (parent as ts.ElementAccessExpression).expression === root && + parent.parent.kind === ts.SyntaxKind.BinaryExpression && + (parent.parent as ts.BinaryExpression).operatorToken.kind === ts.SyntaxKind.EqualsToken && + (parent.parent as ts.BinaryExpression).left === parent && + !ts.isAssignmentTarget(parent.parent) && + isTypeAssignableToKind(getTypeOfExpression((parent as ts.ElementAccessExpression).argumentExpression), ts.TypeFlags.NumberLike); return isLengthPushOrUnshift || isElementAssignment; } - function isDeclarationWithExplicitTypeAnnotation(node: Declaration) { - return (isVariableDeclaration(node) || isPropertyDeclaration(node) || isPropertySignature(node) || isParameter(node)) && - !!(getEffectiveTypeAnnotationNode(node) || - isInJSFile(node) && hasInitializer(node) && node.initializer && isFunctionExpressionOrArrowFunction(node.initializer) && getEffectiveReturnTypeNode(node.initializer)); + function isDeclarationWithExplicitTypeAnnotation(node: ts.Declaration) { + return (ts.isVariableDeclaration(node) || ts.isPropertyDeclaration(node) || ts.isPropertySignature(node) || ts.isParameter(node)) && + !!(ts.getEffectiveTypeAnnotationNode(node) || + ts.isInJSFile(node) && ts.hasInitializer(node) && node.initializer && ts.isFunctionExpressionOrArrowFunction(node.initializer) && ts.getEffectiveReturnTypeNode(node.initializer)); } - function getExplicitTypeOfSymbol(symbol: Symbol, diagnostic?: Diagnostic) { - if (symbol.flags & (SymbolFlags.Function | SymbolFlags.Method | SymbolFlags.Class | SymbolFlags.ValueModule)) { + function getExplicitTypeOfSymbol(symbol: ts.Symbol, diagnostic?: ts.Diagnostic) { + if (symbol.flags & (ts.SymbolFlags.Function | ts.SymbolFlags.Method | ts.SymbolFlags.Class | ts.SymbolFlags.ValueModule)) { return getTypeOfSymbol(symbol); } - if (symbol.flags & (SymbolFlags.Variable | SymbolFlags.Property)) { - if (getCheckFlags(symbol) & CheckFlags.Mapped) { - const origin = (symbol as MappedSymbol).syntheticOrigin; + if (symbol.flags & (ts.SymbolFlags.Variable | ts.SymbolFlags.Property)) { + if (ts.getCheckFlags(symbol) & ts.CheckFlags.Mapped) { + const origin = (symbol as ts.MappedSymbol).syntheticOrigin; if (origin && getExplicitTypeOfSymbol(origin)) { return getTypeOfSymbol(symbol); } @@ -23939,7 +23396,7 @@ namespace ts { if (isDeclarationWithExplicitTypeAnnotation(declaration)) { return getTypeOfSymbol(symbol); } - if (isVariableDeclaration(declaration) && declaration.parent.parent.kind === SyntaxKind.ForOfStatement) { + if (ts.isVariableDeclaration(declaration) && declaration.parent.parent.kind === ts.SyntaxKind.ForOfStatement) { const statement = declaration.parent.parent; const expressionType = getTypeOfDottedName(statement.expression, /*diagnostic*/ undefined); if (expressionType) { @@ -23948,7 +23405,7 @@ namespace ts { } } if (diagnostic) { - addRelatedInfo(diagnostic, createDiagnosticForNode(declaration, Diagnostics._0_needs_an_explicit_type_annotation, symbolToString(symbol))); + ts.addRelatedInfo(diagnostic, ts.createDiagnosticForNode(declaration, ts.Diagnostics._0_needs_an_explicit_type_annotation, symbolToString(symbol))); } } } @@ -23958,26 +23415,26 @@ namespace ts { // that reference function, method, class or value module symbols; or variable, property or // parameter symbols with declarations that have explicit type annotations. Such references are // resolvable with no possibility of triggering circularities in control flow analysis. - function getTypeOfDottedName(node: Expression, diagnostic: Diagnostic | undefined): Type | undefined { - if (!(node.flags & NodeFlags.InWithStatement)) { + function getTypeOfDottedName(node: ts.Expression, diagnostic: ts.Diagnostic | undefined): ts.Type | undefined { + if (!(node.flags & ts.NodeFlags.InWithStatement)) { switch (node.kind) { - case SyntaxKind.Identifier: - const symbol = getExportSymbolOfValueSymbolIfExported(getResolvedSymbol(node as Identifier)); - return getExplicitTypeOfSymbol(symbol.flags & SymbolFlags.Alias ? resolveAlias(symbol) : symbol, diagnostic); - case SyntaxKind.ThisKeyword: + case ts.SyntaxKind.Identifier: + const symbol = getExportSymbolOfValueSymbolIfExported(getResolvedSymbol(node as ts.Identifier)); + return getExplicitTypeOfSymbol(symbol.flags & ts.SymbolFlags.Alias ? resolveAlias(symbol) : symbol, diagnostic); + case ts.SyntaxKind.ThisKeyword: return getExplicitThisType(node); - case SyntaxKind.SuperKeyword: + case ts.SyntaxKind.SuperKeyword: return checkSuperExpression(node); - case SyntaxKind.PropertyAccessExpression: { - const type = getTypeOfDottedName((node as PropertyAccessExpression).expression, diagnostic); + case ts.SyntaxKind.PropertyAccessExpression: { + const type = getTypeOfDottedName((node as ts.PropertyAccessExpression).expression, diagnostic); if (type) { - const name = (node as PropertyAccessExpression).name; - let prop: Symbol | undefined; - if (isPrivateIdentifier(name)) { + const name = (node as ts.PropertyAccessExpression).name; + let prop: ts.Symbol | undefined; + if (ts.isPrivateIdentifier(name)) { if (!type.symbol) { return undefined; } - prop = getPropertyOfType(type, getSymbolNameForPrivateIdentifier(type.symbol, name.escapedText)); + prop = getPropertyOfType(type, ts.getSymbolNameForPrivateIdentifier(type.symbol, name.escapedText)); } else { prop = getPropertyOfType(type, name.escapedText); @@ -23986,13 +23443,13 @@ namespace ts { } return undefined; } - case SyntaxKind.ParenthesizedExpression: - return getTypeOfDottedName((node as ParenthesizedExpression).expression, diagnostic); + case ts.SyntaxKind.ParenthesizedExpression: + return getTypeOfDottedName((node as ts.ParenthesizedExpression).expression, diagnostic); } } } - function getEffectsSignature(node: CallExpression) { + function getEffectsSignature(node: ts.CallExpression) { const links = getNodeLinks(node); let signature = links.effectsSignature; if (signature === undefined) { @@ -24000,71 +23457,67 @@ namespace ts { // expressions are potential type predicate function calls. In order to avoid triggering // circularities in control flow analysis, we use getTypeOfDottedName when resolving the call // target expression of an assertion. - let funcType: Type | undefined; - if (node.parent.kind === SyntaxKind.ExpressionStatement) { + let funcType: ts.Type | undefined; + if (node.parent.kind === ts.SyntaxKind.ExpressionStatement) { funcType = getTypeOfDottedName(node.expression, /*diagnostic*/ undefined); } - else if (node.expression.kind !== SyntaxKind.SuperKeyword) { - if (isOptionalChain(node)) { - funcType = checkNonNullType( - getOptionalExpressionType(checkExpression(node.expression), node.expression), - node.expression - ); + else if (node.expression.kind !== ts.SyntaxKind.SuperKeyword) { + if (ts.isOptionalChain(node)) { + funcType = checkNonNullType(getOptionalExpressionType(checkExpression(node.expression), node.expression), node.expression); } else { funcType = checkNonNullExpression(node.expression); } } - const signatures = getSignaturesOfType(funcType && getApparentType(funcType) || unknownType, SignatureKind.Call); + const signatures = getSignaturesOfType(funcType && getApparentType(funcType) || unknownType, ts.SignatureKind.Call); const candidate = signatures.length === 1 && !signatures[0].typeParameters ? signatures[0] : - some(signatures, hasTypePredicateOrNeverReturnType) ? getResolvedSignature(node) : + ts.some(signatures, hasTypePredicateOrNeverReturnType) ? getResolvedSignature(node) : undefined; signature = links.effectsSignature = candidate && hasTypePredicateOrNeverReturnType(candidate) ? candidate : unknownSignature; } return signature === unknownSignature ? undefined : signature; } - function hasTypePredicateOrNeverReturnType(signature: Signature) { + function hasTypePredicateOrNeverReturnType(signature: ts.Signature) { return !!(getTypePredicateOfSignature(signature) || - signature.declaration && (getReturnTypeFromAnnotation(signature.declaration) || unknownType).flags & TypeFlags.Never); + signature.declaration && (getReturnTypeFromAnnotation(signature.declaration) || unknownType).flags & ts.TypeFlags.Never); } - function getTypePredicateArgument(predicate: TypePredicate, callExpression: CallExpression) { - if (predicate.kind === TypePredicateKind.Identifier || predicate.kind === TypePredicateKind.AssertsIdentifier) { + function getTypePredicateArgument(predicate: ts.TypePredicate, callExpression: ts.CallExpression) { + if (predicate.kind === ts.TypePredicateKind.Identifier || predicate.kind === ts.TypePredicateKind.AssertsIdentifier) { return callExpression.arguments[predicate.parameterIndex]; } - const invokedExpression = skipParentheses(callExpression.expression); - return isAccessExpression(invokedExpression) ? skipParentheses(invokedExpression.expression) : undefined; + const invokedExpression = ts.skipParentheses(callExpression.expression); + return ts.isAccessExpression(invokedExpression) ? ts.skipParentheses(invokedExpression.expression) : undefined; } - function reportFlowControlError(node: Node) { - const block = findAncestor(node, isFunctionOrModuleBlock) as Block | ModuleBlock | SourceFile; - const sourceFile = getSourceFileOfNode(node); - const span = getSpanOfTokenAtPosition(sourceFile, block.statements.pos); - diagnostics.add(createFileDiagnostic(sourceFile, span.start, span.length, Diagnostics.The_containing_function_or_module_body_is_too_large_for_control_flow_analysis)); + function reportFlowControlError(node: ts.Node) { + const block = ts.findAncestor(node, ts.isFunctionOrModuleBlock) as ts.Block | ts.ModuleBlock | ts.SourceFile; + const sourceFile = ts.getSourceFileOfNode(node); + const span = ts.getSpanOfTokenAtPosition(sourceFile, block.statements.pos); + diagnostics.add(ts.createFileDiagnostic(sourceFile, span.start, span.length, ts.Diagnostics.The_containing_function_or_module_body_is_too_large_for_control_flow_analysis)); } - function isReachableFlowNode(flow: FlowNode) { + function isReachableFlowNode(flow: ts.FlowNode) { const result = isReachableFlowNodeWorker(flow, /*noCacheCheck*/ false); lastFlowNode = flow; lastFlowNodeReachable = result; return result; } - function isFalseExpression(expr: Expression): boolean { - const node = skipParentheses(expr, /*excludeJSDocTypeAssertions*/ true); - return node.kind === SyntaxKind.FalseKeyword || node.kind === SyntaxKind.BinaryExpression && ( - (node as BinaryExpression).operatorToken.kind === SyntaxKind.AmpersandAmpersandToken && (isFalseExpression((node as BinaryExpression).left) || isFalseExpression((node as BinaryExpression).right)) || - (node as BinaryExpression).operatorToken.kind === SyntaxKind.BarBarToken && isFalseExpression((node as BinaryExpression).left) && isFalseExpression((node as BinaryExpression).right)); + function isFalseExpression(expr: ts.Expression): boolean { + const node = ts.skipParentheses(expr, /*excludeJSDocTypeAssertions*/ true); + return node.kind === ts.SyntaxKind.FalseKeyword || node.kind === ts.SyntaxKind.BinaryExpression && ((node as ts.BinaryExpression).operatorToken.kind === ts.SyntaxKind.AmpersandAmpersandToken && (isFalseExpression((node as ts.BinaryExpression).left) || isFalseExpression((node as ts.BinaryExpression).right)) || + (node as ts.BinaryExpression).operatorToken.kind === ts.SyntaxKind.BarBarToken && isFalseExpression((node as ts.BinaryExpression).left) && isFalseExpression((node as ts.BinaryExpression).right)); } - function isReachableFlowNodeWorker(flow: FlowNode, noCacheCheck: boolean): boolean { + function isReachableFlowNodeWorker(flow: ts.FlowNode, noCacheCheck: boolean): boolean { while (true) { if (flow === lastFlowNode) { return lastFlowNodeReachable; } const flags = flow.flags; - if (flags & FlowFlags.Shared) { + if (flags & ts.FlowFlags.Shared) { if (!noCacheCheck) { const id = getFlowNodeId(flow); const reachable = flowNodeReachable[id]; @@ -24072,67 +23525,67 @@ namespace ts { } noCacheCheck = false; } - if (flags & (FlowFlags.Assignment | FlowFlags.Condition | FlowFlags.ArrayMutation)) { - flow = (flow as FlowAssignment | FlowCondition | FlowArrayMutation).antecedent; + if (flags & (ts.FlowFlags.Assignment | ts.FlowFlags.Condition | ts.FlowFlags.ArrayMutation)) { + flow = (flow as ts.FlowAssignment | ts.FlowCondition | ts.FlowArrayMutation).antecedent; } - else if (flags & FlowFlags.Call) { - const signature = getEffectsSignature((flow as FlowCall).node); + else if (flags & ts.FlowFlags.Call) { + const signature = getEffectsSignature((flow as ts.FlowCall).node); if (signature) { const predicate = getTypePredicateOfSignature(signature); - if (predicate && predicate.kind === TypePredicateKind.AssertsIdentifier && !predicate.type) { - const predicateArgument = (flow as FlowCall).node.arguments[predicate.parameterIndex]; + if (predicate && predicate.kind === ts.TypePredicateKind.AssertsIdentifier && !predicate.type) { + const predicateArgument = (flow as ts.FlowCall).node.arguments[predicate.parameterIndex]; if (predicateArgument && isFalseExpression(predicateArgument)) { return false; } } - if (getReturnTypeOfSignature(signature).flags & TypeFlags.Never) { + if (getReturnTypeOfSignature(signature).flags & ts.TypeFlags.Never) { return false; } } - flow = (flow as FlowCall).antecedent; + flow = (flow as ts.FlowCall).antecedent; } - else if (flags & FlowFlags.BranchLabel) { + else if (flags & ts.FlowFlags.BranchLabel) { // A branching point is reachable if any branch is reachable. - return some((flow as FlowLabel).antecedents, f => isReachableFlowNodeWorker(f, /*noCacheCheck*/ false)); + return ts.some((flow as ts.FlowLabel).antecedents, f => isReachableFlowNodeWorker(f, /*noCacheCheck*/ false)); } - else if (flags & FlowFlags.LoopLabel) { - const antecedents = (flow as FlowLabel).antecedents; + else if (flags & ts.FlowFlags.LoopLabel) { + const antecedents = (flow as ts.FlowLabel).antecedents; if (antecedents === undefined || antecedents.length === 0) { return false; } // A loop is reachable if the control flow path that leads to the top is reachable. flow = antecedents[0]; } - else if (flags & FlowFlags.SwitchClause) { + else if (flags & ts.FlowFlags.SwitchClause) { // The control flow path representing an unmatched value in a switch statement with // no default clause is unreachable if the switch statement is exhaustive. - if ((flow as FlowSwitchClause).clauseStart === (flow as FlowSwitchClause).clauseEnd && isExhaustiveSwitchStatement((flow as FlowSwitchClause).switchStatement)) { + if ((flow as ts.FlowSwitchClause).clauseStart === (flow as ts.FlowSwitchClause).clauseEnd && isExhaustiveSwitchStatement((flow as ts.FlowSwitchClause).switchStatement)) { return false; } - flow = (flow as FlowSwitchClause).antecedent; + flow = (flow as ts.FlowSwitchClause).antecedent; } - else if (flags & FlowFlags.ReduceLabel) { + else if (flags & ts.FlowFlags.ReduceLabel) { // Cache is unreliable once we start adjusting labels lastFlowNode = undefined; - const target = (flow as FlowReduceLabel).target; + const target = (flow as ts.FlowReduceLabel).target; const saveAntecedents = target.antecedents; - target.antecedents = (flow as FlowReduceLabel).antecedents; - const result = isReachableFlowNodeWorker((flow as FlowReduceLabel).antecedent, /*noCacheCheck*/ false); + target.antecedents = (flow as ts.FlowReduceLabel).antecedents; + const result = isReachableFlowNodeWorker((flow as ts.FlowReduceLabel).antecedent, /*noCacheCheck*/ false); target.antecedents = saveAntecedents; return result; } else { - return !(flags & FlowFlags.Unreachable); + return !(flags & ts.FlowFlags.Unreachable); } } } // Return true if the given flow node is preceded by a 'super(...)' call in every possible code path // leading to the node. - function isPostSuperFlowNode(flow: FlowNode, noCacheCheck: boolean): boolean { + function isPostSuperFlowNode(flow: ts.FlowNode, noCacheCheck: boolean): boolean { while (true) { const flags = flow.flags; - if (flags & FlowFlags.Shared) { + if (flags & ts.FlowFlags.Shared) { if (!noCacheCheck) { const id = getFlowNodeId(flow); const postSuper = flowNodePostSuper[id]; @@ -24140,53 +23593,53 @@ namespace ts { } noCacheCheck = false; } - if (flags & (FlowFlags.Assignment | FlowFlags.Condition | FlowFlags.ArrayMutation | FlowFlags.SwitchClause)) { - flow = (flow as FlowAssignment | FlowCondition | FlowArrayMutation | FlowSwitchClause).antecedent; + if (flags & (ts.FlowFlags.Assignment | ts.FlowFlags.Condition | ts.FlowFlags.ArrayMutation | ts.FlowFlags.SwitchClause)) { + flow = (flow as ts.FlowAssignment | ts.FlowCondition | ts.FlowArrayMutation | ts.FlowSwitchClause).antecedent; } - else if (flags & FlowFlags.Call) { - if ((flow as FlowCall).node.expression.kind === SyntaxKind.SuperKeyword) { + else if (flags & ts.FlowFlags.Call) { + if ((flow as ts.FlowCall).node.expression.kind === ts.SyntaxKind.SuperKeyword) { return true; } - flow = (flow as FlowCall).antecedent; + flow = (flow as ts.FlowCall).antecedent; } - else if (flags & FlowFlags.BranchLabel) { + else if (flags & ts.FlowFlags.BranchLabel) { // A branching point is post-super if every branch is post-super. - return every((flow as FlowLabel).antecedents, f => isPostSuperFlowNode(f, /*noCacheCheck*/ false)); + return ts.every((flow as ts.FlowLabel).antecedents, f => isPostSuperFlowNode(f, /*noCacheCheck*/ false)); } - else if (flags & FlowFlags.LoopLabel) { + else if (flags & ts.FlowFlags.LoopLabel) { // A loop is post-super if the control flow path that leads to the top is post-super. - flow = (flow as FlowLabel).antecedents![0]; + flow = (flow as ts.FlowLabel).antecedents![0]; } - else if (flags & FlowFlags.ReduceLabel) { - const target = (flow as FlowReduceLabel).target; + else if (flags & ts.FlowFlags.ReduceLabel) { + const target = (flow as ts.FlowReduceLabel).target; const saveAntecedents = target.antecedents; - target.antecedents = (flow as FlowReduceLabel).antecedents; - const result = isPostSuperFlowNode((flow as FlowReduceLabel).antecedent, /*noCacheCheck*/ false); + target.antecedents = (flow as ts.FlowReduceLabel).antecedents; + const result = isPostSuperFlowNode((flow as ts.FlowReduceLabel).antecedent, /*noCacheCheck*/ false); target.antecedents = saveAntecedents; return result; } else { // Unreachable nodes are considered post-super to silence errors - return !!(flags & FlowFlags.Unreachable); + return !!(flags & ts.FlowFlags.Unreachable); } } } - function isConstantReference(node: Node): boolean { + function isConstantReference(node: ts.Node): boolean { switch (node.kind) { - case SyntaxKind.Identifier: { - const symbol = getResolvedSymbol(node as Identifier); - return isConstVariable(symbol) || isParameterOrCatchClauseVariable(symbol) && !isSymbolAssigned(symbol); + case ts.SyntaxKind.Identifier: { + const symbol = getResolvedSymbol(node as ts.Identifier); + return isConstVariable(symbol) || ts.isParameterOrCatchClauseVariable(symbol) && !isSymbolAssigned(symbol); } - case SyntaxKind.PropertyAccessExpression: - case SyntaxKind.ElementAccessExpression: + case ts.SyntaxKind.PropertyAccessExpression: + case ts.SyntaxKind.ElementAccessExpression: // The resolvedSymbol property is initialized by checkPropertyAccess or checkElementAccess before we get here. - return isConstantReference((node as AccessExpression).expression) && isReadonlySymbol(getNodeLinks(node).resolvedSymbol || unknownSymbol); + return isConstantReference((node as ts.AccessExpression).expression) && isReadonlySymbol(getNodeLinks(node).resolvedSymbol || unknownSymbol); } return false; } - function getFlowTypeOfReference(reference: Node, declaredType: Type, initialType = declaredType, flowContainer?: Node, flowNode = reference.flowNode) { + function getFlowTypeOfReference(reference: ts.Node, declaredType: ts.Type, initialType = declaredType, flowContainer?: ts.Node, flowNode = reference.flowNode) { let key: string | undefined; let isKeySet = false; let flowDepth = 0; @@ -24204,8 +23657,8 @@ namespace ts { // we give type 'any[]' to 'x' instead of using the type determined by control flow analysis such that operations // on empty arrays are possible without implicit any errors and new element types can be inferred without // type mismatch errors. - const resultType = getObjectFlags(evolvedType) & ObjectFlags.EvolvingArray && isEvolvingArrayOperationTarget(reference) ? autoArrayType : finalizeEvolvingArrayType(evolvedType); - if (resultType === unreachableNeverType || reference.parent && reference.parent.kind === SyntaxKind.NonNullExpression && !(resultType.flags & TypeFlags.Never) && getTypeWithFacts(resultType, TypeFacts.NEUndefinedOrNull).flags & TypeFlags.Never) { + const resultType = ts.getObjectFlags(evolvedType) & ts.ObjectFlags.EvolvingArray && isEvolvingArrayOperationTarget(reference) ? autoArrayType : finalizeEvolvingArrayType(evolvedType); + if (resultType === unreachableNeverType || reference.parent && reference.parent.kind === ts.SyntaxKind.NonNullExpression && !(resultType.flags & ts.TypeFlags.Never) && getTypeWithFacts(resultType, TypeFacts.NEUndefinedOrNull).flags & ts.TypeFlags.Never) { return declaredType; } // The non-null unknown type should never escape control flow analysis. @@ -24219,20 +23672,20 @@ namespace ts { return key = getFlowCacheKey(reference, declaredType, initialType, flowContainer); } - function getTypeAtFlowNode(flow: FlowNode): FlowType { + function getTypeAtFlowNode(flow: ts.FlowNode): ts.FlowType { if (flowDepth === 2000) { // We have made 2000 recursive invocations. To avoid overflowing the call stack we report an error // and disable further control flow analysis in the containing function or module body. - tracing?.instant(tracing.Phase.CheckTypes, "getTypeAtFlowNode_DepthLimit", { flowId: flow.id }); + ts.tracing?.instant(ts.tracing.Phase.CheckTypes, "getTypeAtFlowNode_DepthLimit", { flowId: flow.id }); flowAnalysisDisabled = true; reportFlowControlError(reference); return errorType; } flowDepth++; - let sharedFlow: FlowNode | undefined; + let sharedFlow: ts.FlowNode | undefined; while (true) { const flags = flow.flags; - if (flags & FlowFlags.Shared) { + if (flags & ts.FlowFlags.Shared) { // We cache results of flow type resolution for shared nodes that were previously visited in // the same getFlowTypeOfReference invocation. A node is considered shared when it is the // antecedent of more than one node. @@ -24244,57 +23697,57 @@ namespace ts { } sharedFlow = flow; } - let type: FlowType | undefined; - if (flags & FlowFlags.Assignment) { - type = getTypeAtFlowAssignment(flow as FlowAssignment); + let type: ts.FlowType | undefined; + if (flags & ts.FlowFlags.Assignment) { + type = getTypeAtFlowAssignment(flow as ts.FlowAssignment); if (!type) { - flow = (flow as FlowAssignment).antecedent; + flow = (flow as ts.FlowAssignment).antecedent; continue; } } - else if (flags & FlowFlags.Call) { - type = getTypeAtFlowCall(flow as FlowCall); + else if (flags & ts.FlowFlags.Call) { + type = getTypeAtFlowCall(flow as ts.FlowCall); if (!type) { - flow = (flow as FlowCall).antecedent; + flow = (flow as ts.FlowCall).antecedent; continue; } } - else if (flags & FlowFlags.Condition) { - type = getTypeAtFlowCondition(flow as FlowCondition); + else if (flags & ts.FlowFlags.Condition) { + type = getTypeAtFlowCondition(flow as ts.FlowCondition); } - else if (flags & FlowFlags.SwitchClause) { - type = getTypeAtSwitchClause(flow as FlowSwitchClause); + else if (flags & ts.FlowFlags.SwitchClause) { + type = getTypeAtSwitchClause(flow as ts.FlowSwitchClause); } - else if (flags & FlowFlags.Label) { - if ((flow as FlowLabel).antecedents!.length === 1) { - flow = (flow as FlowLabel).antecedents![0]; + else if (flags & ts.FlowFlags.Label) { + if ((flow as ts.FlowLabel).antecedents!.length === 1) { + flow = (flow as ts.FlowLabel).antecedents![0]; continue; } - type = flags & FlowFlags.BranchLabel ? - getTypeAtFlowBranchLabel(flow as FlowLabel) : - getTypeAtFlowLoopLabel(flow as FlowLabel); + type = flags & ts.FlowFlags.BranchLabel ? + getTypeAtFlowBranchLabel(flow as ts.FlowLabel) : + getTypeAtFlowLoopLabel(flow as ts.FlowLabel); } - else if (flags & FlowFlags.ArrayMutation) { - type = getTypeAtFlowArrayMutation(flow as FlowArrayMutation); + else if (flags & ts.FlowFlags.ArrayMutation) { + type = getTypeAtFlowArrayMutation(flow as ts.FlowArrayMutation); if (!type) { - flow = (flow as FlowArrayMutation).antecedent; + flow = (flow as ts.FlowArrayMutation).antecedent; continue; } } - else if (flags & FlowFlags.ReduceLabel) { - const target = (flow as FlowReduceLabel).target; + else if (flags & ts.FlowFlags.ReduceLabel) { + const target = (flow as ts.FlowReduceLabel).target; const saveAntecedents = target.antecedents; - target.antecedents = (flow as FlowReduceLabel).antecedents; - type = getTypeAtFlowNode((flow as FlowReduceLabel).antecedent); + target.antecedents = (flow as ts.FlowReduceLabel).antecedents; + type = getTypeAtFlowNode((flow as ts.FlowReduceLabel).antecedent); target.antecedents = saveAntecedents; } - else if (flags & FlowFlags.Start) { + else if (flags & ts.FlowFlags.Start) { // Check if we should continue with the control flow of the containing function. - const container = (flow as FlowStart).node; + const container = (flow as ts.FlowStart).node; if (container && container !== flowContainer && - reference.kind !== SyntaxKind.PropertyAccessExpression && - reference.kind !== SyntaxKind.ElementAccessExpression && - reference.kind !== SyntaxKind.ThisKeyword) { + reference.kind !== ts.SyntaxKind.PropertyAccessExpression && + reference.kind !== ts.SyntaxKind.ElementAccessExpression && + reference.kind !== ts.SyntaxKind.ThisKeyword) { flow = container.flowNode!; continue; } @@ -24317,14 +23770,14 @@ namespace ts { } } - function getInitialOrAssignedType(flow: FlowAssignment) { + function getInitialOrAssignedType(flow: ts.FlowAssignment) { const node = flow.node; - return getNarrowableTypeForReference(node.kind === SyntaxKind.VariableDeclaration || node.kind === SyntaxKind.BindingElement ? - getInitialType(node as VariableDeclaration | BindingElement) : + return getNarrowableTypeForReference(node.kind === ts.SyntaxKind.VariableDeclaration || node.kind === ts.SyntaxKind.BindingElement ? + getInitialType(node as ts.VariableDeclaration | ts.BindingElement) : getAssignedType(node), reference); } - function getTypeAtFlowAssignment(flow: FlowAssignment) { + function getTypeAtFlowAssignment(flow: ts.FlowAssignment) { const node = flow.node; // Assignments only narrow the computed type if the declared type is a union type. Thus, we // only need to evaluate the assigned type if the declared type is a union type. @@ -24332,7 +23785,7 @@ namespace ts { if (!isReachableFlowNode(flow)) { return unreachableNeverType; } - if (getAssignmentTargetKind(node) === AssignmentKind.Compound) { + if (ts.getAssignmentTargetKind(node) === ts.AssignmentKind.Compound) { const flowType = getTypeAtFlowNode(flow.antecedent); return createFlowType(getBaseTypeOfLiteralType(getTypeFromFlowType(flowType)), isIncomplete(flowType)); } @@ -24343,8 +23796,8 @@ namespace ts { const assignedType = getWidenedLiteralType(getInitialOrAssignedType(flow)); return isTypeAssignableTo(assignedType, declaredType) ? assignedType : anyArrayType; } - if (declaredType.flags & TypeFlags.Union) { - return getAssignmentReducedType(declaredType as UnionType, getInitialOrAssignedType(flow)); + if (declaredType.flags & ts.TypeFlags.Union) { + return getAssignmentReducedType(declaredType as ts.UnionType, getInitialOrAssignedType(flow)); } return declaredType; } @@ -24358,77 +23811,77 @@ namespace ts { } // A matching dotted name might also be an expando property on a function *expression*, // in which case we continue control flow analysis back to the function's declaration - if (isVariableDeclaration(node) && (isInJSFile(node) || isVarConst(node))) { - const init = getDeclaredExpandoInitializer(node); - if (init && (init.kind === SyntaxKind.FunctionExpression || init.kind === SyntaxKind.ArrowFunction)) { + if (ts.isVariableDeclaration(node) && (ts.isInJSFile(node) || ts.isVarConst(node))) { + const init = ts.getDeclaredExpandoInitializer(node); + if (init && (init.kind === ts.SyntaxKind.FunctionExpression || init.kind === ts.SyntaxKind.ArrowFunction)) { return getTypeAtFlowNode(flow.antecedent); } } return declaredType; } // for (const _ in ref) acts as a nonnull on ref - if (isVariableDeclaration(node) && node.parent.parent.kind === SyntaxKind.ForInStatement && isMatchingReference(reference, node.parent.parent.expression)) { + if (ts.isVariableDeclaration(node) && node.parent.parent.kind === ts.SyntaxKind.ForInStatement && isMatchingReference(reference, node.parent.parent.expression)) { return getNonNullableTypeIfNeeded(getTypeFromFlowType(getTypeAtFlowNode(flow.antecedent))); } // Assignment doesn't affect reference return undefined; } - function narrowTypeByAssertion(type: Type, expr: Expression): Type { - const node = skipParentheses(expr, /*excludeJSDocTypeAssertions*/ true); - if (node.kind === SyntaxKind.FalseKeyword) { + function narrowTypeByAssertion(type: ts.Type, expr: ts.Expression): ts.Type { + const node = ts.skipParentheses(expr, /*excludeJSDocTypeAssertions*/ true); + if (node.kind === ts.SyntaxKind.FalseKeyword) { return unreachableNeverType; } - if (node.kind === SyntaxKind.BinaryExpression) { - if ((node as BinaryExpression).operatorToken.kind === SyntaxKind.AmpersandAmpersandToken) { - return narrowTypeByAssertion(narrowTypeByAssertion(type, (node as BinaryExpression).left), (node as BinaryExpression).right); + if (node.kind === ts.SyntaxKind.BinaryExpression) { + if ((node as ts.BinaryExpression).operatorToken.kind === ts.SyntaxKind.AmpersandAmpersandToken) { + return narrowTypeByAssertion(narrowTypeByAssertion(type, (node as ts.BinaryExpression).left), (node as ts.BinaryExpression).right); } - if ((node as BinaryExpression).operatorToken.kind === SyntaxKind.BarBarToken) { - return getUnionType([narrowTypeByAssertion(type, (node as BinaryExpression).left), narrowTypeByAssertion(type, (node as BinaryExpression).right)]); + if ((node as ts.BinaryExpression).operatorToken.kind === ts.SyntaxKind.BarBarToken) { + return getUnionType([narrowTypeByAssertion(type, (node as ts.BinaryExpression).left), narrowTypeByAssertion(type, (node as ts.BinaryExpression).right)]); } } return narrowType(type, node, /*assumeTrue*/ true); } - function getTypeAtFlowCall(flow: FlowCall): FlowType | undefined { + function getTypeAtFlowCall(flow: ts.FlowCall): ts.FlowType | undefined { const signature = getEffectsSignature(flow.node); if (signature) { const predicate = getTypePredicateOfSignature(signature); - if (predicate && (predicate.kind === TypePredicateKind.AssertsThis || predicate.kind === TypePredicateKind.AssertsIdentifier)) { + if (predicate && (predicate.kind === ts.TypePredicateKind.AssertsThis || predicate.kind === ts.TypePredicateKind.AssertsIdentifier)) { const flowType = getTypeAtFlowNode(flow.antecedent); const type = finalizeEvolvingArrayType(getTypeFromFlowType(flowType)); const narrowedType = predicate.type ? narrowTypeByTypePredicate(type, predicate, flow.node, /*assumeTrue*/ true) : - predicate.kind === TypePredicateKind.AssertsIdentifier && predicate.parameterIndex >= 0 && predicate.parameterIndex < flow.node.arguments.length ? narrowTypeByAssertion(type, flow.node.arguments[predicate.parameterIndex]) : + predicate.kind === ts.TypePredicateKind.AssertsIdentifier && predicate.parameterIndex >= 0 && predicate.parameterIndex < flow.node.arguments.length ? narrowTypeByAssertion(type, flow.node.arguments[predicate.parameterIndex]) : type; return narrowedType === type ? flowType : createFlowType(narrowedType, isIncomplete(flowType)); } - if (getReturnTypeOfSignature(signature).flags & TypeFlags.Never) { + if (getReturnTypeOfSignature(signature).flags & ts.TypeFlags.Never) { return unreachableNeverType; } } return undefined; } - function getTypeAtFlowArrayMutation(flow: FlowArrayMutation): FlowType | undefined { + function getTypeAtFlowArrayMutation(flow: ts.FlowArrayMutation): ts.FlowType | undefined { if (declaredType === autoType || declaredType === autoArrayType) { const node = flow.node; - const expr = node.kind === SyntaxKind.CallExpression ? - (node.expression as PropertyAccessExpression).expression : - (node.left as ElementAccessExpression).expression; + const expr = node.kind === ts.SyntaxKind.CallExpression ? + (node.expression as ts.PropertyAccessExpression).expression : + (node.left as ts.ElementAccessExpression).expression; if (isMatchingReference(reference, getReferenceCandidate(expr))) { const flowType = getTypeAtFlowNode(flow.antecedent); const type = getTypeFromFlowType(flowType); - if (getObjectFlags(type) & ObjectFlags.EvolvingArray) { - let evolvedType = type as EvolvingArrayType; - if (node.kind === SyntaxKind.CallExpression) { + if (ts.getObjectFlags(type) & ts.ObjectFlags.EvolvingArray) { + let evolvedType = type as ts.EvolvingArrayType; + if (node.kind === ts.SyntaxKind.CallExpression) { for (const arg of node.arguments) { evolvedType = addEvolvingArrayElementType(evolvedType, arg); } } else { // We must get the context free expression type so as to not recur in an uncached fashion on the LHS (which causes exponential blowup in compile time) - const indexType = getContextFreeTypeOfExpression((node.left as ElementAccessExpression).argumentExpression); - if (isTypeAssignableToKind(indexType, TypeFlags.NumberLike)) { + const indexType = getContextFreeTypeOfExpression((node.left as ts.ElementAccessExpression).argumentExpression); + if (isTypeAssignableToKind(indexType, ts.TypeFlags.NumberLike)) { evolvedType = addEvolvingArrayElementType(evolvedType, node.right); } } @@ -24440,10 +23893,10 @@ namespace ts { return undefined; } - function getTypeAtFlowCondition(flow: FlowCondition): FlowType { + function getTypeAtFlowCondition(flow: ts.FlowCondition): ts.FlowType { const flowType = getTypeAtFlowNode(flow.antecedent); const type = getTypeFromFlowType(flowType); - if (type.flags & TypeFlags.Never) { + if (type.flags & ts.TypeFlags.Never) { return flowType; } // If we have an antecedent type (meaning we're reachable in some way), we first @@ -24453,7 +23906,7 @@ namespace ts { // have the complete type. We proceed by switching to the silent never type which // doesn't report errors when operators are applied to it. Note that this is the // *only* place a silent never type is ever generated. - const assumeTrue = (flow.flags & FlowFlags.TrueCondition) !== 0; + const assumeTrue = (flow.flags & ts.FlowFlags.TrueCondition) !== 0; const nonEvolvingType = finalizeEvolvingArrayType(type); const narrowedType = narrowType(nonEvolvingType, flow.node, assumeTrue); if (narrowedType === nonEvolvingType) { @@ -24462,25 +23915,23 @@ namespace ts { return createFlowType(narrowedType, isIncomplete(flowType)); } - function getTypeAtSwitchClause(flow: FlowSwitchClause): FlowType { + function getTypeAtSwitchClause(flow: ts.FlowSwitchClause): ts.FlowType { const expr = flow.switchStatement.expression; const flowType = getTypeAtFlowNode(flow.antecedent); let type = getTypeFromFlowType(flowType); if (isMatchingReference(reference, expr)) { type = narrowTypeBySwitchOnDiscriminant(type, flow.switchStatement, flow.clauseStart, flow.clauseEnd); } - else if (expr.kind === SyntaxKind.TypeOfExpression && isMatchingReference(reference, (expr as TypeOfExpression).expression)) { + else if (expr.kind === ts.SyntaxKind.TypeOfExpression && isMatchingReference(reference, (expr as ts.TypeOfExpression).expression)) { type = narrowBySwitchOnTypeOf(type, flow.switchStatement, flow.clauseStart, flow.clauseEnd); } else { if (strictNullChecks) { if (optionalChainContainsReference(expr, reference)) { - type = narrowTypeBySwitchOptionalChainContainment(type, flow.switchStatement, flow.clauseStart, flow.clauseEnd, - t => !(t.flags & (TypeFlags.Undefined | TypeFlags.Never))); + type = narrowTypeBySwitchOptionalChainContainment(type, flow.switchStatement, flow.clauseStart, flow.clauseEnd, t => !(t.flags & (ts.TypeFlags.Undefined | ts.TypeFlags.Never))); } - else if (expr.kind === SyntaxKind.TypeOfExpression && optionalChainContainsReference((expr as TypeOfExpression).expression, reference)) { - type = narrowTypeBySwitchOptionalChainContainment(type, flow.switchStatement, flow.clauseStart, flow.clauseEnd, - t => !(t.flags & TypeFlags.Never || t.flags & TypeFlags.StringLiteral && (t as StringLiteralType).value === "undefined")); + else if (expr.kind === ts.SyntaxKind.TypeOfExpression && optionalChainContainsReference((expr as ts.TypeOfExpression).expression, reference)) { + type = narrowTypeBySwitchOptionalChainContainment(type, flow.switchStatement, flow.clauseStart, flow.clauseEnd, t => !(t.flags & ts.TypeFlags.Never || t.flags & ts.TypeFlags.StringLiteral && (t as ts.StringLiteralType).value === "undefined")); } } const access = getDiscriminantPropertyAccess(expr, type); @@ -24491,15 +23942,15 @@ namespace ts { return createFlowType(type, isIncomplete(flowType)); } - function getTypeAtFlowBranchLabel(flow: FlowLabel): FlowType { - const antecedentTypes: Type[] = []; + function getTypeAtFlowBranchLabel(flow: ts.FlowLabel): ts.FlowType { + const antecedentTypes: ts.Type[] = []; let subtypeReduction = false; let seenIncomplete = false; - let bypassFlow: FlowSwitchClause | undefined; + let bypassFlow: ts.FlowSwitchClause | undefined; for (const antecedent of flow.antecedents!) { - if (!bypassFlow && antecedent.flags & FlowFlags.SwitchClause && (antecedent as FlowSwitchClause).clauseStart === (antecedent as FlowSwitchClause).clauseEnd) { + if (!bypassFlow && antecedent.flags & ts.FlowFlags.SwitchClause && (antecedent as ts.FlowSwitchClause).clauseStart === (antecedent as ts.FlowSwitchClause).clauseEnd) { // The antecedent is the bypass branch of a potentially exhaustive switch statement. - bypassFlow = antecedent as FlowSwitchClause; + bypassFlow = antecedent as ts.FlowSwitchClause; continue; } const flowType = getTypeAtFlowNode(antecedent); @@ -24511,7 +23962,7 @@ namespace ts { if (type === declaredType && declaredType === initialType) { return type; } - pushIfUnique(antecedentTypes, type); + ts.pushIfUnique(antecedentTypes, type); // If an antecedent type is not a subset of the declared type, we need to perform // subtype reduction. This happens when a "foreign" type is injected into the control // flow using the instanceof operator or a user defined type predicate. @@ -24528,7 +23979,7 @@ namespace ts { // If the bypass flow contributes a type we haven't seen yet and the switch statement // isn't exhaustive, process the bypass flow type. Since exhaustiveness checks increase // the risk of circularities, we only want to perform them when they make a difference. - if (!contains(antecedentTypes, type) && !isExhaustiveSwitchStatement(bypassFlow.switchStatement)) { + if (!ts.contains(antecedentTypes, type) && !isExhaustiveSwitchStatement(bypassFlow.switchStatement)) { if (type === declaredType && declaredType === initialType) { return type; } @@ -24541,14 +23992,14 @@ namespace ts { } } } - return createFlowType(getUnionOrEvolvingArrayType(antecedentTypes, subtypeReduction ? UnionReduction.Subtype : UnionReduction.Literal), seenIncomplete); + return createFlowType(getUnionOrEvolvingArrayType(antecedentTypes, subtypeReduction ? ts.UnionReduction.Subtype : ts.UnionReduction.Literal), seenIncomplete); } - function getTypeAtFlowLoopLabel(flow: FlowLabel): FlowType { + function getTypeAtFlowLoopLabel(flow: ts.FlowLabel): ts.FlowType { // If we have previously computed the control flow type for the reference at // this flow loop junction, return the cached type. const id = getFlowNodeId(flow); - const cache = flowLoopCaches[id] || (flowLoopCaches[id] = new Map()); + const cache = flowLoopCaches[id] || (flowLoopCaches[id] = new ts.Map()); const key = getOrSetCacheKey(); if (!key) { // No cache key is generated when binding patterns are in unnarrowable situations @@ -24568,14 +24019,14 @@ namespace ts { // path that leads to the top. for (let i = flowLoopStart; i < flowLoopCount; i++) { if (flowLoopNodes[i] === flow && flowLoopKeys[i] === key && flowLoopTypes[i].length) { - return createFlowType(getUnionOrEvolvingArrayType(flowLoopTypes[i], UnionReduction.Literal), /*incomplete*/ true); + return createFlowType(getUnionOrEvolvingArrayType(flowLoopTypes[i], ts.UnionReduction.Literal), /*incomplete*/ true); } } // Add the flow loop junction and reference to the in-process stack and analyze // each antecedent code path. - const antecedentTypes: Type[] = []; + const antecedentTypes: ts.Type[] = []; let subtypeReduction = false; - let firstAntecedentType: FlowType | undefined; + let firstAntecedentType: ts.FlowType | undefined; for (const antecedent of flow.antecedents!) { let flowType; if (!firstAntecedentType) { @@ -24604,7 +24055,7 @@ namespace ts { } } const type = getTypeFromFlowType(flowType); - pushIfUnique(antecedentTypes, type); + ts.pushIfUnique(antecedentTypes, type); // If an antecedent type is not a subset of the declared type, we need to perform // subtype reduction. This happens when a "foreign" type is injected into the control // flow using the instanceof operator or a user defined type predicate. @@ -24620,7 +24071,7 @@ namespace ts { } // The result is incomplete if the first antecedent (the non-looping control flow path) // is incomplete. - const result = getUnionOrEvolvingArrayType(antecedentTypes, subtypeReduction ? UnionReduction.Subtype : UnionReduction.Literal); + const result = getUnionOrEvolvingArrayType(antecedentTypes, subtypeReduction ? ts.UnionReduction.Subtype : ts.UnionReduction.Literal); if (isIncomplete(firstAntecedentType!)) { return createFlowType(result, /*incomplete*/ true); } @@ -24631,49 +24082,49 @@ namespace ts { // At flow control branch or loop junctions, if the type along every antecedent code path // is an evolving array type, we construct a combined evolving array type. Otherwise we // finalize all evolving array types. - function getUnionOrEvolvingArrayType(types: Type[], subtypeReduction: UnionReduction) { + function getUnionOrEvolvingArrayType(types: ts.Type[], subtypeReduction: ts.UnionReduction) { if (isEvolvingArrayTypeList(types)) { - return getEvolvingArrayType(getUnionType(map(types, getElementTypeOfEvolvingArrayType))); + return getEvolvingArrayType(getUnionType(ts.map(types, getElementTypeOfEvolvingArrayType))); } - const result = getUnionType(sameMap(types, finalizeEvolvingArrayType), subtypeReduction); - if (result !== declaredType && result.flags & declaredType.flags & TypeFlags.Union && arraysEqual((result as UnionType).types, (declaredType as UnionType).types)) { + const result = getUnionType(ts.sameMap(types, finalizeEvolvingArrayType), subtypeReduction); + if (result !== declaredType && result.flags & declaredType.flags & ts.TypeFlags.Union && ts.arraysEqual((result as ts.UnionType).types, (declaredType as ts.UnionType).types)) { return declaredType; } return result; } - function getCandidateDiscriminantPropertyAccess(expr: Expression) { - if (isBindingPattern(reference) || isFunctionExpressionOrArrowFunction(reference) || isObjectLiteralMethod(reference)) { + function getCandidateDiscriminantPropertyAccess(expr: ts.Expression) { + if (ts.isBindingPattern(reference) || ts.isFunctionExpressionOrArrowFunction(reference) || ts.isObjectLiteralMethod(reference)) { // When the reference is a binding pattern or function or arrow expression, we are narrowing a pesudo-reference in // getNarrowedTypeOfSymbol. An identifier for a destructuring variable declared in the same binding pattern or // parameter declared in the same parameter list is a candidate. - if (isIdentifier(expr)) { + if (ts.isIdentifier(expr)) { const symbol = getResolvedSymbol(expr); const declaration = symbol.valueDeclaration; - if (declaration && (isBindingElement(declaration) || isParameter(declaration)) && reference === declaration.parent && !declaration.initializer && !declaration.dotDotDotToken) { + if (declaration && (ts.isBindingElement(declaration) || ts.isParameter(declaration)) && reference === declaration.parent && !declaration.initializer && !declaration.dotDotDotToken) { return declaration; } } } - else if (isAccessExpression(expr)) { + else if (ts.isAccessExpression(expr)) { // An access expression is a candidate if the reference matches the left hand expression. if (isMatchingReference(reference, expr.expression)) { return expr; } } - else if (isIdentifier(expr)) { + else if (ts.isIdentifier(expr)) { const symbol = getResolvedSymbol(expr); if (isConstVariable(symbol)) { const declaration = symbol.valueDeclaration!; // Given 'const x = obj.kind', allow 'x' as an alias for 'obj.kind' - if (isVariableDeclaration(declaration) && !declaration.type && declaration.initializer && isAccessExpression(declaration.initializer) && + if (ts.isVariableDeclaration(declaration) && !declaration.type && declaration.initializer && ts.isAccessExpression(declaration.initializer) && isMatchingReference(reference, declaration.initializer.expression)) { return declaration.initializer; } // Given 'const { kind: x } = obj', allow 'x' as an alias for 'obj.kind' - if (isBindingElement(declaration) && !declaration.initializer) { + if (ts.isBindingElement(declaration) && !declaration.initializer) { const parent = declaration.parent.parent; - if (isVariableDeclaration(parent) && !parent.type && parent.initializer && (isIdentifier(parent.initializer) || isAccessExpression(parent.initializer)) && + if (ts.isVariableDeclaration(parent) && !parent.type && parent.initializer && (ts.isIdentifier(parent.initializer) || ts.isAccessExpression(parent.initializer)) && isMatchingReference(reference, parent.initializer)) { return declaration; } @@ -24683,9 +24134,9 @@ namespace ts { return undefined; } - function getDiscriminantPropertyAccess(expr: Expression, computedType: Type) { - const type = declaredType.flags & TypeFlags.Union ? declaredType : computedType; - if (type.flags & TypeFlags.Union) { + function getDiscriminantPropertyAccess(expr: ts.Expression, computedType: ts.Type) { + const type = declaredType.flags & ts.TypeFlags.Union ? declaredType : computedType; + if (type.flags & ts.TypeFlags.Union) { const access = getCandidateDiscriminantPropertyAccess(expr); if (access) { const name = getAccessedPropertyName(access); @@ -24697,12 +24148,12 @@ namespace ts { return undefined; } - function narrowTypeByDiscriminant(type: Type, access: AccessExpression | BindingElement | ParameterDeclaration, narrowType: (t: Type) => Type): Type { + function narrowTypeByDiscriminant(type: ts.Type, access: ts.AccessExpression | ts.BindingElement | ts.ParameterDeclaration, narrowType: (t: ts.Type) => ts.Type): ts.Type { const propName = getAccessedPropertyName(access); if (propName === undefined) { return type; } - const removeNullable = strictNullChecks && isOptionalChain(access) && maybeTypeOfKind(type, TypeFlags.Nullable); + const removeNullable = strictNullChecks && ts.isOptionalChain(access) && maybeTypeOfKind(type, ts.TypeFlags.Nullable); let propType = getTypeOfPropertyOfType(removeNullable ? getTypeWithFacts(type, TypeFacts.NEUndefinedOrNull) : type, propName); if (!propType) { return type; @@ -24711,17 +24162,17 @@ namespace ts { const narrowedPropType = narrowType(propType); return filterType(type, t => { const discriminantType = getTypeOfPropertyOrIndexSignature(t, propName); - return !(narrowedPropType.flags & TypeFlags.Never) && isTypeComparableTo(narrowedPropType, discriminantType); + return !(narrowedPropType.flags & ts.TypeFlags.Never) && isTypeComparableTo(narrowedPropType, discriminantType); }); } - function narrowTypeByDiscriminantProperty(type: Type, access: AccessExpression | BindingElement | ParameterDeclaration, operator: SyntaxKind, value: Expression, assumeTrue: boolean) { - if ((operator === SyntaxKind.EqualsEqualsEqualsToken || operator === SyntaxKind.ExclamationEqualsEqualsToken) && type.flags & TypeFlags.Union) { - const keyPropertyName = getKeyPropertyName(type as UnionType); + function narrowTypeByDiscriminantProperty(type: ts.Type, access: ts.AccessExpression | ts.BindingElement | ts.ParameterDeclaration, operator: ts.SyntaxKind, value: ts.Expression, assumeTrue: boolean) { + if ((operator === ts.SyntaxKind.EqualsEqualsEqualsToken || operator === ts.SyntaxKind.ExclamationEqualsEqualsToken) && type.flags & ts.TypeFlags.Union) { + const keyPropertyName = getKeyPropertyName(type as ts.UnionType); if (keyPropertyName && keyPropertyName === getAccessedPropertyName(access)) { - const candidate = getConstituentTypeForKeyType(type as UnionType, getTypeOfExpression(value)); + const candidate = getConstituentTypeForKeyType(type as ts.UnionType, getTypeOfExpression(value)); if (candidate) { - return operator === (assumeTrue ? SyntaxKind.EqualsEqualsEqualsToken : SyntaxKind.ExclamationEqualsEqualsToken) ? candidate : + return operator === (assumeTrue ? ts.SyntaxKind.EqualsEqualsEqualsToken : ts.SyntaxKind.ExclamationEqualsEqualsToken) ? candidate : isUnitType(getTypeOfPropertyOfType(candidate, keyPropertyName) || unknownType) ? removeType(type, candidate) : type; } @@ -24730,10 +24181,10 @@ namespace ts { return narrowTypeByDiscriminant(type, access, t => narrowTypeByEquality(t, operator, value, assumeTrue)); } - function narrowTypeBySwitchOnDiscriminantProperty(type: Type, access: AccessExpression | BindingElement | ParameterDeclaration, switchStatement: SwitchStatement, clauseStart: number, clauseEnd: number) { - if (clauseStart < clauseEnd && type.flags & TypeFlags.Union && getKeyPropertyName(type as UnionType) === getAccessedPropertyName(access)) { + function narrowTypeBySwitchOnDiscriminantProperty(type: ts.Type, access: ts.AccessExpression | ts.BindingElement | ts.ParameterDeclaration, switchStatement: ts.SwitchStatement, clauseStart: number, clauseEnd: number) { + if (clauseStart < clauseEnd && type.flags & ts.TypeFlags.Union && getKeyPropertyName(type as ts.UnionType) === getAccessedPropertyName(access)) { const clauseTypes = getSwitchClauseTypes(switchStatement).slice(clauseStart, clauseEnd); - const candidate = getUnionType(map(clauseTypes, t => getConstituentTypeForKeyType(type as UnionType, t) || unknownType)); + const candidate = getUnionType(ts.map(clauseTypes, t => getConstituentTypeForKeyType(type as ts.UnionType, t) || unknownType)); if (candidate !== unknownType) { return candidate; } @@ -24741,9 +24192,9 @@ namespace ts { return narrowTypeByDiscriminant(type, access, t => narrowTypeBySwitchOnDiscriminant(t, switchStatement, clauseStart, clauseEnd)); } - function narrowTypeByTruthiness(type: Type, expr: Expression, assumeTrue: boolean): Type { + function narrowTypeByTruthiness(type: ts.Type, expr: ts.Expression, assumeTrue: boolean): ts.Type { if (isMatchingReference(reference, expr)) { - return type.flags & TypeFlags.Unknown && assumeTrue ? nonNullUnknownType : + return type.flags & ts.TypeFlags.Unknown && assumeTrue ? nonNullUnknownType : getTypeWithFacts(type, assumeTrue ? TypeFacts.Truthy : TypeFacts.Falsy); } if (strictNullChecks && assumeTrue && optionalChainContainsReference(expr, reference)) { @@ -24756,43 +24207,43 @@ namespace ts { return type; } - function isTypePresencePossible(type: Type, propName: __String, assumeTrue: boolean) { + function isTypePresencePossible(type: ts.Type, propName: ts.__String, assumeTrue: boolean) { const prop = getPropertyOfType(type, propName); if (prop) { - return prop.flags & SymbolFlags.Optional ? true : assumeTrue; + return prop.flags & ts.SymbolFlags.Optional ? true : assumeTrue; } return getApplicableIndexInfoForName(type, propName) ? true : !assumeTrue; } - function narrowByInKeyword(type: Type, name: __String, assumeTrue: boolean) { - if (type.flags & TypeFlags.Union - || type.flags & TypeFlags.Object && declaredType !== type - || isThisTypeParameter(type) - || type.flags & TypeFlags.Intersection && every((type as IntersectionType).types, t => t.symbol !== globalThisSymbol)) { + function narrowByInKeyword(type: ts.Type, name: ts.__String, assumeTrue: boolean) { + if (type.flags & ts.TypeFlags.Union + || type.flags & ts.TypeFlags.Object && declaredType !== type + || ts.isThisTypeParameter(type) + || type.flags & ts.TypeFlags.Intersection && ts.every((type as ts.IntersectionType).types, t => t.symbol !== globalThisSymbol)) { return filterType(type, t => isTypePresencePossible(t, name, assumeTrue)); } return type; } - function narrowTypeByBinaryExpression(type: Type, expr: BinaryExpression, assumeTrue: boolean): Type { + function narrowTypeByBinaryExpression(type: ts.Type, expr: ts.BinaryExpression, assumeTrue: boolean): ts.Type { switch (expr.operatorToken.kind) { - case SyntaxKind.EqualsToken: - case SyntaxKind.BarBarEqualsToken: - case SyntaxKind.AmpersandAmpersandEqualsToken: - case SyntaxKind.QuestionQuestionEqualsToken: + case ts.SyntaxKind.EqualsToken: + case ts.SyntaxKind.BarBarEqualsToken: + case ts.SyntaxKind.AmpersandAmpersandEqualsToken: + case ts.SyntaxKind.QuestionQuestionEqualsToken: return narrowTypeByTruthiness(narrowType(type, expr.right, assumeTrue), expr.left, assumeTrue); - case SyntaxKind.EqualsEqualsToken: - case SyntaxKind.ExclamationEqualsToken: - case SyntaxKind.EqualsEqualsEqualsToken: - case SyntaxKind.ExclamationEqualsEqualsToken: + case ts.SyntaxKind.EqualsEqualsToken: + case ts.SyntaxKind.ExclamationEqualsToken: + case ts.SyntaxKind.EqualsEqualsEqualsToken: + case ts.SyntaxKind.ExclamationEqualsEqualsToken: const operator = expr.operatorToken.kind; const left = getReferenceCandidate(expr.left); const right = getReferenceCandidate(expr.right); - if (left.kind === SyntaxKind.TypeOfExpression && isStringLiteralLike(right)) { - return narrowTypeByTypeof(type, left as TypeOfExpression, operator, right, assumeTrue); + if (left.kind === ts.SyntaxKind.TypeOfExpression && ts.isStringLiteralLike(right)) { + return narrowTypeByTypeof(type, left as ts.TypeOfExpression, operator, right, assumeTrue); } - if (right.kind === SyntaxKind.TypeOfExpression && isStringLiteralLike(left)) { - return narrowTypeByTypeof(type, right as TypeOfExpression, operator, left, assumeTrue); + if (right.kind === ts.SyntaxKind.TypeOfExpression && ts.isStringLiteralLike(left)) { + return narrowTypeByTypeof(type, right as ts.TypeOfExpression, operator, left, assumeTrue); } if (isMatchingReference(reference, left)) { return narrowTypeByEquality(type, operator, right, assumeTrue); @@ -24823,17 +24274,17 @@ namespace ts { return narrowTypeByConstructor(type, operator, left, assumeTrue); } break; - case SyntaxKind.InstanceOfKeyword: + case ts.SyntaxKind.InstanceOfKeyword: return narrowTypeByInstanceof(type, expr, assumeTrue); - case SyntaxKind.InKeyword: - if (isPrivateIdentifier(expr.left)) { + case ts.SyntaxKind.InKeyword: + if (ts.isPrivateIdentifier(expr.left)) { return narrowTypeByPrivateIdentifierInInExpression(type, expr, assumeTrue); } const target = getReferenceCandidate(expr.right); const leftType = getTypeOfNode(expr.left); - if (leftType.flags & TypeFlags.StringLiteral) { - const name = escapeLeadingUnderscores((leftType as StringLiteralType).value); - if (containsMissingType(type) && isAccessExpression(reference) && isMatchingReference(reference.expression, target) && + if (leftType.flags & ts.TypeFlags.StringLiteral) { + const name = ts.escapeLeadingUnderscores((leftType as ts.StringLiteralType).value); + if (containsMissingType(type) && ts.isAccessExpression(reference) && isMatchingReference(reference.expression, target) && getAccessedPropertyName(reference) === name) { return getTypeWithFacts(type, assumeTrue ? TypeFacts.NEUndefined : TypeFacts.EQUndefined); } @@ -24842,16 +24293,16 @@ namespace ts { } } break; - case SyntaxKind.CommaToken: + case ts.SyntaxKind.CommaToken: return narrowType(type, expr.right, assumeTrue); // Ordinarily we won't see && and || expressions in control flow analysis because the Binder breaks those // expressions down to individual conditional control flows. However, we may encounter them when analyzing // aliased conditional expressions. - case SyntaxKind.AmpersandAmpersandToken: + case ts.SyntaxKind.AmpersandAmpersandToken: return assumeTrue ? narrowType(narrowType(type, expr.left, /*assumeTrue*/ true), expr.right, /*assumeTrue*/ true) : getUnionType([narrowType(type, expr.left, /*assumeTrue*/ false), narrowType(type, expr.right, /*assumeTrue*/ false)]); - case SyntaxKind.BarBarToken: + case ts.SyntaxKind.BarBarToken: return assumeTrue ? getUnionType([narrowType(type, expr.left, /*assumeTrue*/ true), narrowType(type, expr.right, /*assumeTrue*/ true)]) : narrowType(narrowType(type, expr.left, /*assumeTrue*/ false), expr.right, /*assumeTrue*/ false); @@ -24859,25 +24310,25 @@ namespace ts { return type; } - function narrowTypeByPrivateIdentifierInInExpression(type: Type, expr: BinaryExpression, assumeTrue: boolean): Type { + function narrowTypeByPrivateIdentifierInInExpression(type: ts.Type, expr: ts.BinaryExpression, assumeTrue: boolean): ts.Type { const target = getReferenceCandidate(expr.right); if (!isMatchingReference(reference, target)) { return type; } - Debug.assertNode(expr.left, isPrivateIdentifier); + ts.Debug.assertNode(expr.left, ts.isPrivateIdentifier); const symbol = getSymbolForPrivateIdentifierExpression(expr.left); if (symbol === undefined) { return type; } const classSymbol = symbol.parent!; - const targetType = hasStaticModifier(Debug.checkDefined(symbol.valueDeclaration, "should always have a declaration")) - ? getTypeOfSymbol(classSymbol) as InterfaceType + const targetType = ts.hasStaticModifier(ts.Debug.checkDefined(symbol.valueDeclaration, "should always have a declaration")) + ? getTypeOfSymbol(classSymbol) as ts.InterfaceType : getDeclaredTypeOfSymbol(classSymbol); return getNarrowedType(type, targetType, assumeTrue, isTypeDerivedFrom); } - function narrowTypeByOptionalChainContainment(type: Type, operator: SyntaxKind, value: Expression, assumeTrue: boolean): Type { + function narrowTypeByOptionalChainContainment(type: ts.Type, operator: ts.SyntaxKind, value: ts.Expression, assumeTrue: boolean): ts.Type { // We are in a branch of obj?.foo === value (or any one of the other equality operators). We narrow obj as follows: // When operator is === and type of value excludes undefined, null and undefined is removed from type of obj in true branch. // When operator is !== and type of value excludes undefined, null and undefined is removed from type of obj in false branch. @@ -24887,49 +24338,49 @@ namespace ts { // When operator is !== and type of value is undefined, null and undefined is removed from type of obj in true branch. // When operator is == and type of value is null or undefined, null and undefined is removed from type of obj in false branch. // When operator is != and type of value is null or undefined, null and undefined is removed from type of obj in true branch. - const equalsOperator = operator === SyntaxKind.EqualsEqualsToken || operator === SyntaxKind.EqualsEqualsEqualsToken; - const nullableFlags = operator === SyntaxKind.EqualsEqualsToken || operator === SyntaxKind.ExclamationEqualsToken ? TypeFlags.Nullable : TypeFlags.Undefined; + const equalsOperator = operator === ts.SyntaxKind.EqualsEqualsToken || operator === ts.SyntaxKind.EqualsEqualsEqualsToken; + const nullableFlags = operator === ts.SyntaxKind.EqualsEqualsToken || operator === ts.SyntaxKind.ExclamationEqualsToken ? ts.TypeFlags.Nullable : ts.TypeFlags.Undefined; const valueType = getTypeOfExpression(value); // Note that we include any and unknown in the exclusion test because their domain includes null and undefined. const removeNullable = equalsOperator !== assumeTrue && everyType(valueType, t => !!(t.flags & nullableFlags)) || - equalsOperator === assumeTrue && everyType(valueType, t => !(t.flags & (TypeFlags.AnyOrUnknown | nullableFlags))); + equalsOperator === assumeTrue && everyType(valueType, t => !(t.flags & (ts.TypeFlags.AnyOrUnknown | nullableFlags))); return removeNullable ? getTypeWithFacts(type, TypeFacts.NEUndefinedOrNull) : type; } - function narrowTypeByEquality(type: Type, operator: SyntaxKind, value: Expression, assumeTrue: boolean): Type { - if (type.flags & TypeFlags.Any) { + function narrowTypeByEquality(type: ts.Type, operator: ts.SyntaxKind, value: ts.Expression, assumeTrue: boolean): ts.Type { + if (type.flags & ts.TypeFlags.Any) { return type; } - if (operator === SyntaxKind.ExclamationEqualsToken || operator === SyntaxKind.ExclamationEqualsEqualsToken) { + if (operator === ts.SyntaxKind.ExclamationEqualsToken || operator === ts.SyntaxKind.ExclamationEqualsEqualsToken) { assumeTrue = !assumeTrue; } const valueType = getTypeOfExpression(value); - if (assumeTrue && (type.flags & TypeFlags.Unknown) && (operator === SyntaxKind.EqualsEqualsToken || operator === SyntaxKind.ExclamationEqualsToken) && (valueType.flags & TypeFlags.Null)) { + if (assumeTrue && (type.flags & ts.TypeFlags.Unknown) && (operator === ts.SyntaxKind.EqualsEqualsToken || operator === ts.SyntaxKind.ExclamationEqualsToken) && (valueType.flags & ts.TypeFlags.Null)) { return getUnionType([nullType, undefinedType]); } - if ((type.flags & TypeFlags.Unknown) && assumeTrue && (operator === SyntaxKind.EqualsEqualsEqualsToken || operator === SyntaxKind.ExclamationEqualsEqualsToken)) { - if (valueType.flags & (TypeFlags.Primitive | TypeFlags.NonPrimitive)) { + if ((type.flags & ts.TypeFlags.Unknown) && assumeTrue && (operator === ts.SyntaxKind.EqualsEqualsEqualsToken || operator === ts.SyntaxKind.ExclamationEqualsEqualsToken)) { + if (valueType.flags & (ts.TypeFlags.Primitive | ts.TypeFlags.NonPrimitive)) { return valueType; } - if (valueType.flags & TypeFlags.Object) { + if (valueType.flags & ts.TypeFlags.Object) { return nonPrimitiveType; } return type; } - if (valueType.flags & TypeFlags.Nullable) { + if (valueType.flags & ts.TypeFlags.Nullable) { if (!strictNullChecks) { return type; } - const doubleEquals = operator === SyntaxKind.EqualsEqualsToken || operator === SyntaxKind.ExclamationEqualsToken; + const doubleEquals = operator === ts.SyntaxKind.EqualsEqualsToken || operator === ts.SyntaxKind.ExclamationEqualsToken; const facts = doubleEquals ? assumeTrue ? TypeFacts.EQUndefinedOrNull : TypeFacts.NEUndefinedOrNull : - valueType.flags & TypeFlags.Null ? + valueType.flags & ts.TypeFlags.Null ? assumeTrue ? TypeFacts.EQNull : TypeFacts.NENull : assumeTrue ? TypeFacts.EQUndefined : TypeFacts.NEUndefined; - return type.flags & TypeFlags.Unknown && facts & (TypeFacts.NENull | TypeFacts.NEUndefinedOrNull) ? nonNullUnknownType : getTypeWithFacts(type, facts); + return type.flags & ts.TypeFlags.Unknown && facts & (TypeFacts.NENull | TypeFacts.NEUndefinedOrNull) ? nonNullUnknownType : getTypeWithFacts(type, facts); } if (assumeTrue) { - const filterFn: (t: Type) => boolean = operator === SyntaxKind.EqualsEqualsToken ? + const filterFn: (t: ts.Type) => boolean = operator === ts.SyntaxKind.EqualsEqualsToken ? t => areTypesComparable(t, valueType) || isCoercibleUnderDoubleEquals(t, valueType) : t => areTypesComparable(t, valueType); return replacePrimitivesWithLiterals(filterType(type, filterFn), valueType); @@ -24940,9 +24391,9 @@ namespace ts { return type; } - function narrowTypeByTypeof(type: Type, typeOfExpr: TypeOfExpression, operator: SyntaxKind, literal: LiteralExpression, assumeTrue: boolean): Type { + function narrowTypeByTypeof(type: ts.Type, typeOfExpr: ts.TypeOfExpression, operator: ts.SyntaxKind, literal: ts.LiteralExpression, assumeTrue: boolean): ts.Type { // We have '==', '!=', '===', or !==' operator with 'typeof xxx' and string literal operands - if (operator === SyntaxKind.ExclamationEqualsToken || operator === SyntaxKind.ExclamationEqualsEqualsToken) { + if (operator === ts.SyntaxKind.ExclamationEqualsToken || operator === ts.SyntaxKind.ExclamationEqualsEqualsToken) { assumeTrue = !assumeTrue; } const target = getReferenceCandidate(typeOfExpr.expression); @@ -24952,10 +24403,10 @@ namespace ts { } return type; } - if (type.flags & TypeFlags.Any && literal.text === "function") { + if (type.flags & ts.TypeFlags.Any && literal.text === "function") { return type; } - if (assumeTrue && type.flags & TypeFlags.Unknown && literal.text === "object") { + if (assumeTrue && type.flags & ts.TypeFlags.Unknown && literal.text === "object") { // The non-null unknown type is used to track whether a previous narrowing operation has removed the null type // from the unknown type. For example, the expression `x && typeof x === 'object'` first narrows x to the non-null // unknown type, and then narrows that to the non-primitive type. @@ -24968,12 +24419,12 @@ namespace ts { return getTypeWithFacts(assumeTrue && impliedType ? mapType(type, narrowUnionMemberByTypeof(impliedType)) : type, facts); } - function narrowTypeBySwitchOptionalChainContainment(type: Type, switchStatement: SwitchStatement, clauseStart: number, clauseEnd: number, clauseCheck: (type: Type) => boolean) { - const everyClauseChecks = clauseStart !== clauseEnd && every(getSwitchClauseTypes(switchStatement).slice(clauseStart, clauseEnd), clauseCheck); + function narrowTypeBySwitchOptionalChainContainment(type: ts.Type, switchStatement: ts.SwitchStatement, clauseStart: number, clauseEnd: number, clauseCheck: (type: ts.Type) => boolean) { + const everyClauseChecks = clauseStart !== clauseEnd && ts.every(getSwitchClauseTypes(switchStatement).slice(clauseStart, clauseEnd), clauseCheck); return everyClauseChecks ? getTypeWithFacts(type, TypeFacts.NEUndefinedOrNull) : type; } - function narrowTypeBySwitchOnDiscriminant(type: Type, switchStatement: SwitchStatement, clauseStart: number, clauseEnd: number) { + function narrowTypeBySwitchOnDiscriminant(type: ts.Type, switchStatement: ts.SwitchStatement, clauseStart: number, clauseEnd: number) { // We only narrow if all case expressions specify // values with unit types, except for the case where // `type` is unknown. In this instance we map object @@ -24983,17 +24434,17 @@ namespace ts { return type; } const clauseTypes = switchTypes.slice(clauseStart, clauseEnd); - const hasDefaultClause = clauseStart === clauseEnd || contains(clauseTypes, neverType); - if ((type.flags & TypeFlags.Unknown) && !hasDefaultClause) { - let groundClauseTypes: Type[] | undefined; + const hasDefaultClause = clauseStart === clauseEnd || ts.contains(clauseTypes, neverType); + if ((type.flags & ts.TypeFlags.Unknown) && !hasDefaultClause) { + let groundClauseTypes: ts.Type[] | undefined; for (let i = 0; i < clauseTypes.length; i += 1) { const t = clauseTypes[i]; - if (t.flags & (TypeFlags.Primitive | TypeFlags.NonPrimitive)) { + if (t.flags & (ts.TypeFlags.Primitive | ts.TypeFlags.NonPrimitive)) { if (groundClauseTypes !== undefined) { groundClauseTypes.push(t); } } - else if (t.flags & TypeFlags.Object) { + else if (t.flags & ts.TypeFlags.Object) { if (groundClauseTypes === undefined) { groundClauseTypes = clauseTypes.slice(0, i); } @@ -25006,22 +24457,21 @@ namespace ts { return getUnionType(groundClauseTypes === undefined ? clauseTypes : groundClauseTypes); } const discriminantType = getUnionType(clauseTypes); - const caseType = - discriminantType.flags & TypeFlags.Never ? neverType : + const caseType = discriminantType.flags & ts.TypeFlags.Never ? neverType : replacePrimitivesWithLiterals(filterType(type, t => areTypesComparable(discriminantType, t)), discriminantType); if (!hasDefaultClause) { return caseType; } - const defaultType = filterType(type, t => !(isUnitLikeType(t) && contains(switchTypes, getRegularTypeOfLiteralType(extractUnitType(t))))); - return caseType.flags & TypeFlags.Never ? defaultType : getUnionType([caseType, defaultType]); + const defaultType = filterType(type, t => !(isUnitLikeType(t) && ts.contains(switchTypes, getRegularTypeOfLiteralType(extractUnitType(t))))); + return caseType.flags & ts.TypeFlags.Never ? defaultType : getUnionType([caseType, defaultType]); } - function getImpliedTypeFromTypeofGuard(type: Type, text: string) { + function getImpliedTypeFromTypeofGuard(type: ts.Type, text: string) { switch (text) { case "function": - return type.flags & TypeFlags.Any ? type : globalFunctionType; + return type.flags & ts.TypeFlags.Any ? type : globalFunctionType; case "object": - return type.flags & TypeFlags.Unknown ? getUnionType([nonPrimitiveType, nullType]) : type; + return type.flags & ts.TypeFlags.Unknown ? getUnionType([nonPrimitiveType, nullType]) : type; default: return typeofTypesByName.get(text); } @@ -25033,15 +24483,15 @@ namespace ts { // the guard. For example: narrowing `{} | undefined` by `"boolean"` should produce the type `boolean`, not // the filtered type `{}`. For this reason we narrow constituents of the union individually, in addition to // filtering by type-facts. - function narrowUnionMemberByTypeof(candidate: Type) { - return (type: Type) => { + function narrowUnionMemberByTypeof(candidate: ts.Type) { + return (type: ts.Type) => { if (isTypeSubtypeOf(type, candidate)) { return type; } if (isTypeSubtypeOf(candidate, type)) { return candidate; } - if (type.flags & TypeFlags.Instantiable) { + if (type.flags & ts.TypeFlags.Instantiable) { const constraint = getBaseConstraintOfType(type) || anyType; if (isTypeSubtypeOf(candidate, constraint)) { return getIntersectionType([type, candidate]); @@ -25051,13 +24501,13 @@ namespace ts { }; } - function narrowBySwitchOnTypeOf(type: Type, switchStatement: SwitchStatement, clauseStart: number, clauseEnd: number): Type { + function narrowBySwitchOnTypeOf(type: ts.Type, switchStatement: ts.SwitchStatement, clauseStart: number, clauseEnd: number): ts.Type { const switchWitnesses = getSwitchClauseTypeOfWitnesses(switchStatement, /*retainDefault*/ true); if (!switchWitnesses.length) { return type; } // Equal start and end denotes implicit fallthrough; undefined marks explicit default clause - const defaultCaseLocation = findIndex(switchWitnesses, elem => elem === undefined); + const defaultCaseLocation = ts.findIndex(switchWitnesses, elem => elem === undefined); const hasDefaultClause = clauseStart === clauseEnd || (defaultCaseLocation >= clauseStart && defaultCaseLocation < clauseEnd); let clauseWitnesses: string[]; let switchFacts: TypeFacts; @@ -25111,15 +24561,15 @@ namespace ts { return getTypeWithFacts(mapType(type, narrowUnionMemberByTypeof(impliedType)), switchFacts); } - function isMatchingConstructorReference(expr: Expression) { - return (isPropertyAccessExpression(expr) && idText(expr.name) === "constructor" || - isElementAccessExpression(expr) && isStringLiteralLike(expr.argumentExpression) && expr.argumentExpression.text === "constructor") && + function isMatchingConstructorReference(expr: ts.Expression) { + return (ts.isPropertyAccessExpression(expr) && ts.idText(expr.name) === "constructor" || + ts.isElementAccessExpression(expr) && ts.isStringLiteralLike(expr.argumentExpression) && expr.argumentExpression.text === "constructor") && isMatchingReference(reference, expr.expression); } - function narrowTypeByConstructor(type: Type, operator: SyntaxKind, identifier: Expression, assumeTrue: boolean): Type { + function narrowTypeByConstructor(type: ts.Type, operator: ts.SyntaxKind, identifier: ts.Expression, assumeTrue: boolean): ts.Type { // Do not narrow when checking inequality. - if (assumeTrue ? (operator !== SyntaxKind.EqualsEqualsToken && operator !== SyntaxKind.EqualsEqualsEqualsToken) : (operator !== SyntaxKind.ExclamationEqualsToken && operator !== SyntaxKind.ExclamationEqualsEqualsToken)) { + if (assumeTrue ? (operator !== ts.SyntaxKind.EqualsEqualsToken && operator !== ts.SyntaxKind.EqualsEqualsEqualsToken) : (operator !== ts.SyntaxKind.ExclamationEqualsToken && operator !== ts.SyntaxKind.ExclamationEqualsEqualsToken)) { return type; } @@ -25130,7 +24580,7 @@ namespace ts { } // Get the prototype property of the type identifier so we can find out its type. - const prototypeProperty = getPropertyOfType(identifierType, "prototype" as __String); + const prototypeProperty = getPropertyOfType(identifierType, "prototype" as ts.__String); if (!prototypeProperty) { return type; } @@ -25150,13 +24600,13 @@ namespace ts { // Filter out types that are not considered to be "constructed by" the `candidate` type. return filterType(type, t => isConstructedBy(t, candidate)); - function isConstructedBy(source: Type, target: Type) { + function isConstructedBy(source: ts.Type, target: ts.Type) { // If either the source or target type are a class type then we need to check that they are the same exact type. // This is because you may have a class `A` that defines some set of properties, and another class `B` // that defines the same set of properties as class `A`, in that case they are structurally the same // type, but when you do something like `instanceOfA.constructor === B` it will return false. - if (source.flags & TypeFlags.Object && getObjectFlags(source) & ObjectFlags.Class || - target.flags & TypeFlags.Object && getObjectFlags(target) & ObjectFlags.Class) { + if (source.flags & ts.TypeFlags.Object && ts.getObjectFlags(source) & ts.ObjectFlags.Class || + target.flags & ts.TypeFlags.Object && ts.getObjectFlags(target) & ts.ObjectFlags.Class) { return source.symbol === target.symbol; } @@ -25165,7 +24615,7 @@ namespace ts { } } - function narrowTypeByInstanceof(type: Type, expr: BinaryExpression, assumeTrue: boolean): Type { + function narrowTypeByInstanceof(type: ts.Type, expr: ts.BinaryExpression, assumeTrue: boolean): ts.Type { const left = getReferenceCandidate(expr.left); if (!isMatchingReference(reference, left)) { if (assumeTrue && strictNullChecks && optionalChainContainsReference(left, reference)) { @@ -25180,8 +24630,8 @@ namespace ts { return type; } - let targetType: Type | undefined; - const prototypeProperty = getPropertyOfType(rightType, "prototype" as __String); + let targetType: ts.Type | undefined; + const prototypeProperty = getPropertyOfType(rightType, "prototype" as ts.__String); if (prototypeProperty) { // Target type is type of the prototype property const prototypePropertyType = getTypeOfSymbol(prototypeProperty); @@ -25196,30 +24646,31 @@ namespace ts { } if (!targetType) { - const constructSignatures = getSignaturesOfType(rightType, SignatureKind.Construct); + const constructSignatures = getSignaturesOfType(rightType, ts.SignatureKind.Construct); targetType = constructSignatures.length ? - getUnionType(map(constructSignatures, signature => getReturnTypeOfSignature(getErasedSignature(signature)))) : + getUnionType(ts.map(constructSignatures, signature => getReturnTypeOfSignature(getErasedSignature(signature)))) : emptyObjectType; } // We can't narrow a union based off instanceof without negated types see #31576 for more info - if (!assumeTrue && rightType.flags & TypeFlags.Union) { - const nonConstructorTypeInUnion = find((rightType as UnionType).types, (t) => !isConstructorType(t)); - if (!nonConstructorTypeInUnion) return type; + if (!assumeTrue && rightType.flags & ts.TypeFlags.Union) { + const nonConstructorTypeInUnion = ts.find((rightType as ts.UnionType).types, (t) => !isConstructorType(t)); + if (!nonConstructorTypeInUnion) + return type; } return getNarrowedType(type, targetType, assumeTrue, isTypeDerivedFrom); } - function getNarrowedType(type: Type, candidate: Type, assumeTrue: boolean, isRelated: (source: Type, target: Type) => boolean) { + function getNarrowedType(type: ts.Type, candidate: ts.Type, assumeTrue: boolean, isRelated: (source: ts.Type, target: ts.Type) => boolean) { if (!assumeTrue) { return filterType(type, t => !isRelated(t, candidate)); } // If the current type is a union type, remove all constituents that couldn't be instances of // the candidate type. If one or more constituents remain, return a union of those. - if (type.flags & TypeFlags.Union) { + if (type.flags & ts.TypeFlags.Union) { const assignableType = filterType(type, t => isRelated(t, candidate)); - if (!(assignableType.flags & TypeFlags.Never)) { + if (!(assignableType.flags & ts.TypeFlags.Never)) { return assignableType; } } @@ -25235,20 +24686,20 @@ namespace ts { getIntersectionType([type, candidate]); } - function narrowTypeByCallExpression(type: Type, callExpression: CallExpression, assumeTrue: boolean): Type { + function narrowTypeByCallExpression(type: ts.Type, callExpression: ts.CallExpression, assumeTrue: boolean): ts.Type { if (hasMatchingArgument(callExpression, reference)) { - const signature = assumeTrue || !isCallChain(callExpression) ? getEffectsSignature(callExpression) : undefined; + const signature = assumeTrue || !ts.isCallChain(callExpression) ? getEffectsSignature(callExpression) : undefined; const predicate = signature && getTypePredicateOfSignature(signature); - if (predicate && (predicate.kind === TypePredicateKind.This || predicate.kind === TypePredicateKind.Identifier)) { + if (predicate && (predicate.kind === ts.TypePredicateKind.This || predicate.kind === ts.TypePredicateKind.Identifier)) { return narrowTypeByTypePredicate(type, predicate, callExpression, assumeTrue); } } - if (containsMissingType(type) && isAccessExpression(reference) && isPropertyAccessExpression(callExpression.expression)) { + if (containsMissingType(type) && ts.isAccessExpression(reference) && ts.isPropertyAccessExpression(callExpression.expression)) { const callAccess = callExpression.expression; if (isMatchingReference(reference.expression, getReferenceCandidate(callAccess.expression)) && - isIdentifier(callAccess.name) && callAccess.name.escapedText === "hasOwnProperty" && callExpression.arguments.length === 1) { + ts.isIdentifier(callAccess.name) && callAccess.name.escapedText === "hasOwnProperty" && callExpression.arguments.length === 1) { const argument = callExpression.arguments[0]; - if (isStringLiteralLike(argument) && getAccessedPropertyName(reference) === escapeLeadingUnderscores(argument.text)) { + if (ts.isStringLiteralLike(argument) && getAccessedPropertyName(reference) === ts.escapeLeadingUnderscores(argument.text)) { return getTypeWithFacts(type, assumeTrue ? TypeFacts.NEUndefined : TypeFacts.EQUndefined); } } @@ -25256,7 +24707,7 @@ namespace ts { return type; } - function narrowTypeByTypePredicate(type: Type, predicate: TypePredicate, callExpression: CallExpression, assumeTrue: boolean): Type { + function narrowTypeByTypePredicate(type: ts.Type, predicate: ts.TypePredicate, callExpression: ts.CallExpression, assumeTrue: boolean): ts.Type { // Don't narrow from 'any' if the predicate type is exactly 'Object' or 'Function' if (predicate.type && !(isTypeAny(type) && (predicate.type === globalObjectType || predicate.type === globalFunctionType))) { const predicateArgument = getTypePredicateArgument(predicate, callExpression); @@ -25279,21 +24730,21 @@ namespace ts { // Narrow the given type based on the given expression having the assumed boolean value. The returned type // will be a subtype or the same type as the argument. - function narrowType(type: Type, expr: Expression, assumeTrue: boolean): Type { + function narrowType(type: ts.Type, expr: ts.Expression, assumeTrue: boolean): ts.Type { // for `a?.b`, we emulate a synthetic `a !== null && a !== undefined` condition for `a` - if (isExpressionOfOptionalChainRoot(expr) || - isBinaryExpression(expr.parent) && expr.parent.operatorToken.kind === SyntaxKind.QuestionQuestionToken && expr.parent.left === expr) { + if (ts.isExpressionOfOptionalChainRoot(expr) || + ts.isBinaryExpression(expr.parent) && expr.parent.operatorToken.kind === ts.SyntaxKind.QuestionQuestionToken && expr.parent.left === expr) { return narrowTypeByOptionality(type, expr, assumeTrue); } switch (expr.kind) { - case SyntaxKind.Identifier: + case ts.SyntaxKind.Identifier: // When narrowing a reference to a const variable, non-assigned parameter, or readonly property, we inline // up to five levels of aliased conditional expressions that are themselves declared as const variables. if (!isMatchingReference(reference, expr) && inlineLevel < 5) { - const symbol = getResolvedSymbol(expr as Identifier); + const symbol = getResolvedSymbol(expr as ts.Identifier); if (isConstVariable(symbol)) { const declaration = symbol.valueDeclaration; - if (declaration && isVariableDeclaration(declaration) && !declaration.type && declaration.initializer && isConstantReference(reference)) { + if (declaration && ts.isVariableDeclaration(declaration) && !declaration.type && declaration.initializer && isConstantReference(reference)) { inlineLevel++; const result = narrowType(type, declaration.initializer, assumeTrue); inlineLevel--; @@ -25302,28 +24753,28 @@ namespace ts { } } // falls through - case SyntaxKind.ThisKeyword: - case SyntaxKind.SuperKeyword: - case SyntaxKind.PropertyAccessExpression: - case SyntaxKind.ElementAccessExpression: + case ts.SyntaxKind.ThisKeyword: + case ts.SyntaxKind.SuperKeyword: + case ts.SyntaxKind.PropertyAccessExpression: + case ts.SyntaxKind.ElementAccessExpression: return narrowTypeByTruthiness(type, expr, assumeTrue); - case SyntaxKind.CallExpression: - return narrowTypeByCallExpression(type, expr as CallExpression, assumeTrue); - case SyntaxKind.ParenthesizedExpression: - case SyntaxKind.NonNullExpression: - return narrowType(type, (expr as ParenthesizedExpression | NonNullExpression).expression, assumeTrue); - case SyntaxKind.BinaryExpression: - return narrowTypeByBinaryExpression(type, expr as BinaryExpression, assumeTrue); - case SyntaxKind.PrefixUnaryExpression: - if ((expr as PrefixUnaryExpression).operator === SyntaxKind.ExclamationToken) { - return narrowType(type, (expr as PrefixUnaryExpression).operand, !assumeTrue); + case ts.SyntaxKind.CallExpression: + return narrowTypeByCallExpression(type, expr as ts.CallExpression, assumeTrue); + case ts.SyntaxKind.ParenthesizedExpression: + case ts.SyntaxKind.NonNullExpression: + return narrowType(type, (expr as ts.ParenthesizedExpression | ts.NonNullExpression).expression, assumeTrue); + case ts.SyntaxKind.BinaryExpression: + return narrowTypeByBinaryExpression(type, expr as ts.BinaryExpression, assumeTrue); + case ts.SyntaxKind.PrefixUnaryExpression: + if ((expr as ts.PrefixUnaryExpression).operator === ts.SyntaxKind.ExclamationToken) { + return narrowType(type, (expr as ts.PrefixUnaryExpression).operand, !assumeTrue); } break; } return type; } - function narrowTypeByOptionality(type: Type, expr: Expression, assumePresent: boolean): Type { + function narrowTypeByOptionality(type: ts.Type, expr: ts.Expression, assumePresent: boolean): ts.Type { if (isMatchingReference(reference, expr)) { return getTypeWithFacts(type, assumePresent ? TypeFacts.NEUndefinedOrNull : TypeFacts.EQUndefinedOrNull); } @@ -25335,25 +24786,25 @@ namespace ts { } } - function getTypeOfSymbolAtLocation(symbol: Symbol, location: Node) { + function getTypeOfSymbolAtLocation(symbol: ts.Symbol, location: ts.Node) { symbol = symbol.exportSymbol || symbol; // If we have an identifier or a property access at the given location, if the location is // an dotted name expression, and if the location is not an assignment target, obtain the type // of the expression (which will reflect control flow analysis). If the expression indeed // resolved to the given symbol, return the narrowed type. - if (location.kind === SyntaxKind.Identifier || location.kind === SyntaxKind.PrivateIdentifier) { - if (isRightSideOfQualifiedNameOrPropertyAccess(location)) { + if (location.kind === ts.SyntaxKind.Identifier || location.kind === ts.SyntaxKind.PrivateIdentifier) { + if (ts.isRightSideOfQualifiedNameOrPropertyAccess(location)) { location = location.parent; } - if (isExpressionNode(location) && (!isAssignmentTarget(location) || isWriteAccess(location))) { - const type = getTypeOfExpression(location as Expression); + if (ts.isExpressionNode(location) && (!ts.isAssignmentTarget(location) || ts.isWriteAccess(location))) { + const type = getTypeOfExpression(location as ts.Expression); if (getExportSymbolOfValueSymbolIfExported(getNodeLinks(location).resolvedSymbol) === symbol) { return type; } } } - if (isDeclarationName(location) && isSetAccessor(location.parent) && getAnnotatedAccessorTypeNode(location.parent)) { + if (ts.isDeclarationName(location) && ts.isSetAccessor(location.parent) && getAnnotatedAccessorTypeNode(location.parent)) { return getWriteTypeOfAccessors(location.parent.symbol); } // The location isn't a reference to the given symbol, meaning we're being asked @@ -25364,23 +24815,22 @@ namespace ts { return getNonMissingTypeOfSymbol(symbol); } - function getControlFlowContainer(node: Node): Node { - return findAncestor(node.parent, node => - isFunctionLike(node) && !getImmediatelyInvokedFunctionExpression(node) || - node.kind === SyntaxKind.ModuleBlock || - node.kind === SyntaxKind.SourceFile || - node.kind === SyntaxKind.PropertyDeclaration)!; + function getControlFlowContainer(node: ts.Node): ts.Node { + return ts.findAncestor(node.parent, node => ts.isFunctionLike(node) && !ts.getImmediatelyInvokedFunctionExpression(node) || + node.kind === ts.SyntaxKind.ModuleBlock || + node.kind === ts.SyntaxKind.SourceFile || + node.kind === ts.SyntaxKind.PropertyDeclaration)!; } // Check if a parameter or catch variable is assigned anywhere - function isSymbolAssigned(symbol: Symbol) { + function isSymbolAssigned(symbol: ts.Symbol) { if (!symbol.valueDeclaration) { return false; } - const parent = getRootDeclaration(symbol.valueDeclaration).parent; + const parent = ts.getRootDeclaration(symbol.valueDeclaration).parent; const links = getNodeLinks(parent); - if (!(links.flags & NodeCheckFlags.AssignmentsMarked)) { - links.flags |= NodeCheckFlags.AssignmentsMarked; + if (!(links.flags & ts.NodeCheckFlags.AssignmentsMarked)) { + links.flags |= ts.NodeCheckFlags.AssignmentsMarked; if (!hasParentWithAssignmentsMarked(parent)) { markNodeAssignments(parent); } @@ -25388,37 +24838,36 @@ namespace ts { return symbol.isAssigned || false; } - function hasParentWithAssignmentsMarked(node: Node) { - return !!findAncestor(node.parent, node => - (isFunctionLike(node) || isCatchClause(node)) && !!(getNodeLinks(node).flags & NodeCheckFlags.AssignmentsMarked)); + function hasParentWithAssignmentsMarked(node: ts.Node) { + return !!ts.findAncestor(node.parent, node => (ts.isFunctionLike(node) || ts.isCatchClause(node)) && !!(getNodeLinks(node).flags & ts.NodeCheckFlags.AssignmentsMarked)); } - function markNodeAssignments(node: Node) { - if (node.kind === SyntaxKind.Identifier) { - if (isAssignmentTarget(node)) { - const symbol = getResolvedSymbol(node as Identifier); - if (isParameterOrCatchClauseVariable(symbol)) { + function markNodeAssignments(node: ts.Node) { + if (node.kind === ts.SyntaxKind.Identifier) { + if (ts.isAssignmentTarget(node)) { + const symbol = getResolvedSymbol(node as ts.Identifier); + if (ts.isParameterOrCatchClauseVariable(symbol)) { symbol.isAssigned = true; } } } else { - forEachChild(node, markNodeAssignments); + ts.forEachChild(node, markNodeAssignments); } } - function isConstVariable(symbol: Symbol) { - return symbol.flags & SymbolFlags.Variable && (getDeclarationNodeFlagsFromSymbol(symbol) & NodeFlags.Const) !== 0; + function isConstVariable(symbol: ts.Symbol) { + return symbol.flags & ts.SymbolFlags.Variable && (getDeclarationNodeFlagsFromSymbol(symbol) & ts.NodeFlags.Const) !== 0; } /** remove undefined from the annotated type of a parameter when there is an initializer (that doesn't include undefined) */ - function removeOptionalityFromDeclaredType(declaredType: Type, declaration: VariableLikeDeclaration): Type { + function removeOptionalityFromDeclaredType(declaredType: ts.Type, declaration: ts.VariableLikeDeclaration): ts.Type { if (pushTypeResolution(declaration.symbol, TypeSystemPropertyName.DeclaredType)) { const annotationIncludesUndefined = strictNullChecks && - declaration.kind === SyntaxKind.Parameter && + declaration.kind === ts.SyntaxKind.Parameter && declaration.initializer && - getFalsyFlags(declaredType) & TypeFlags.Undefined && - !(getFalsyFlags(checkExpression(declaration.initializer)) & TypeFlags.Undefined); + getFalsyFlags(declaredType) & ts.TypeFlags.Undefined && + !(getFalsyFlags(checkExpression(declaration.initializer)) & ts.TypeFlags.Undefined); popTypeResolution(); return annotationIncludesUndefined ? getTypeWithFacts(declaredType, TypeFacts.NEUndefined) : declaredType; @@ -25429,40 +24878,40 @@ namespace ts { } } - function isConstraintPosition(type: Type, node: Node) { + function isConstraintPosition(type: ts.Type, node: ts.Node) { const parent = node.parent; // In an element access obj[x], we consider obj to be in a constraint position, except when obj is of // a generic type without a nullable constraint and x is a generic type. This is because when both obj // and x are of generic types T and K, we want the resulting type to be T[K]. - return parent.kind === SyntaxKind.PropertyAccessExpression || - parent.kind === SyntaxKind.QualifiedName || - parent.kind === SyntaxKind.CallExpression && (parent as CallExpression).expression === node || - parent.kind === SyntaxKind.ElementAccessExpression && (parent as ElementAccessExpression).expression === node && - !(someType(type, isGenericTypeWithoutNullableConstraint) && isGenericIndexType(getTypeOfExpression((parent as ElementAccessExpression).argumentExpression))); + return parent.kind === ts.SyntaxKind.PropertyAccessExpression || + parent.kind === ts.SyntaxKind.QualifiedName || + parent.kind === ts.SyntaxKind.CallExpression && (parent as ts.CallExpression).expression === node || + parent.kind === ts.SyntaxKind.ElementAccessExpression && (parent as ts.ElementAccessExpression).expression === node && + !(someType(type, isGenericTypeWithoutNullableConstraint) && isGenericIndexType(getTypeOfExpression((parent as ts.ElementAccessExpression).argumentExpression))); } - function isGenericTypeWithUnionConstraint(type: Type) { - return !!(type.flags & TypeFlags.Instantiable && getBaseConstraintOrType(type).flags & (TypeFlags.Nullable | TypeFlags.Union)); + function isGenericTypeWithUnionConstraint(type: ts.Type) { + return !!(type.flags & ts.TypeFlags.Instantiable && getBaseConstraintOrType(type).flags & (ts.TypeFlags.Nullable | ts.TypeFlags.Union)); } - function isGenericTypeWithoutNullableConstraint(type: Type) { - return !!(type.flags & TypeFlags.Instantiable && !maybeTypeOfKind(getBaseConstraintOrType(type), TypeFlags.Nullable)); + function isGenericTypeWithoutNullableConstraint(type: ts.Type) { + return !!(type.flags & ts.TypeFlags.Instantiable && !maybeTypeOfKind(getBaseConstraintOrType(type), ts.TypeFlags.Nullable)); } - function hasContextualTypeWithNoGenericTypes(node: Node, checkMode: CheckMode | undefined) { + function hasContextualTypeWithNoGenericTypes(node: ts.Node, checkMode: CheckMode | undefined) { // Computing the contextual type for a child of a JSX element involves resolving the type of the // element's tag name, so we exclude that here to avoid circularities. // If check mode has `CheckMode.RestBindingElement`, we skip binding pattern contextual types, // as we want the type of a rest element to be generic when possible. - const contextualType = (isIdentifier(node) || isPropertyAccessExpression(node) || isElementAccessExpression(node)) && - !((isJsxOpeningElement(node.parent) || isJsxSelfClosingElement(node.parent)) && node.parent.tagName === node) && + const contextualType = (ts.isIdentifier(node) || ts.isPropertyAccessExpression(node) || ts.isElementAccessExpression(node)) && + !((ts.isJsxOpeningElement(node.parent) || ts.isJsxSelfClosingElement(node.parent)) && node.parent.tagName === node) && (checkMode && checkMode & CheckMode.RestBindingElement ? - getContextualType(node, ContextFlags.SkipBindingPatterns) + getContextualType(node, ts.ContextFlags.SkipBindingPatterns) : getContextualType(node)); return contextualType && !isGenericType(contextualType); } - function getNarrowableTypeForReference(type: Type, reference: Node, checkMode?: CheckMode) { + function getNarrowableTypeForReference(type: ts.Type, reference: ts.Node, checkMode?: CheckMode) { // When the type of a reference is or contains an instantiable type with a union type constraint, and // when the reference is in a constraint position (where it is known we'll obtain the apparent type) or // has a contextual type containing no top-level instantiables (meaning constraints will determine @@ -25473,36 +24922,35 @@ namespace ts { const substituteConstraints = !(checkMode && checkMode & CheckMode.Inferential) && someType(type, isGenericTypeWithUnionConstraint) && (isConstraintPosition(type, reference) || hasContextualTypeWithNoGenericTypes(reference, checkMode)); - return substituteConstraints ? mapType(type, t => t.flags & TypeFlags.Instantiable ? getBaseConstraintOrType(t) : t) : type; + return substituteConstraints ? mapType(type, t => t.flags & ts.TypeFlags.Instantiable ? getBaseConstraintOrType(t) : t) : type; } - function isExportOrExportExpression(location: Node) { - return !!findAncestor(location, n => { + function isExportOrExportExpression(location: ts.Node) { + return !!ts.findAncestor(location, n => { const parent = n.parent; if (parent === undefined) { return "quit"; } - if (isExportAssignment(parent)) { - return parent.expression === n && isEntityNameExpression(n); + if (ts.isExportAssignment(parent)) { + return parent.expression === n && ts.isEntityNameExpression(n); } - if (isExportSpecifier(parent)) { + if (ts.isExportSpecifier(parent)) { return parent.name === n || parent.propertyName === n; } return false; }); } - function markAliasReferenced(symbol: Symbol, location: Node) { - if (isNonLocalAlias(symbol, /*excludes*/ SymbolFlags.Value) && !isInTypeQuery(location) && !getTypeOnlyAliasDeclaration(symbol)) { + function markAliasReferenced(symbol: ts.Symbol, location: ts.Node) { + if (isNonLocalAlias(symbol, /*excludes*/ ts.SymbolFlags.Value) && !isInTypeQuery(location) && !getTypeOnlyAliasDeclaration(symbol)) { const target = resolveAlias(symbol); - if (target.flags & SymbolFlags.Value) { + if (target.flags & ts.SymbolFlags.Value) { // An alias resolving to a const enum cannot be elided if (1) 'isolatedModules' is enabled // (because the const enum value will not be inlined), or if (2) the alias is an export // of a const enum declaration that will be preserved. if (compilerOptions.isolatedModules || - shouldPreserveConstEnums(compilerOptions) && isExportOrExportExpression(location) || - !isConstEnumOrConstEnumOnlyModule(target) - ) { + ts.shouldPreserveConstEnums(compilerOptions) && isExportOrExportExpression(location) || + !isConstEnumOrConstEnumOnlyModule(target)) { markAliasSymbolAsReferenced(symbol); } else { @@ -25512,7 +24960,7 @@ namespace ts { } } - function getNarrowedTypeOfSymbol(symbol: Symbol, location: Identifier) { + function getNarrowedTypeOfSymbol(symbol: ts.Symbol, location: ts.Identifier) { const declaration = symbol.valueDeclaration; if (declaration) { // If we have a non-rest binding element with no initializer declared as a const variable or a const-like @@ -25538,18 +24986,18 @@ namespace ts { // the binding pattern AST instance for '{ kind, payload }' as a pseudo-reference and narrow this reference // as if it occurred in the specified location. We then recompute the narrowed binding element type by // destructuring from the narrowed parent type. - if (isBindingElement(declaration) && !declaration.initializer && !declaration.dotDotDotToken && declaration.parent.elements.length >= 2) { + if (ts.isBindingElement(declaration) && !declaration.initializer && !declaration.dotDotDotToken && declaration.parent.elements.length >= 2) { const parent = declaration.parent.parent; - if (parent.kind === SyntaxKind.VariableDeclaration && getCombinedNodeFlags(declaration) & NodeFlags.Const || parent.kind === SyntaxKind.Parameter) { + if (parent.kind === ts.SyntaxKind.VariableDeclaration && ts.getCombinedNodeFlags(declaration) & ts.NodeFlags.Const || parent.kind === ts.SyntaxKind.Parameter) { const links = getNodeLinks(parent); - if (!(links.flags & NodeCheckFlags.InCheckIdentifier)) { - links.flags |= NodeCheckFlags.InCheckIdentifier; + if (!(links.flags & ts.NodeCheckFlags.InCheckIdentifier)) { + links.flags |= ts.NodeCheckFlags.InCheckIdentifier; const parentType = getTypeForBindingElementParent(parent, CheckMode.Normal); - links.flags &= ~NodeCheckFlags.InCheckIdentifier; - if (parentType && parentType.flags & TypeFlags.Union && !(parent.kind === SyntaxKind.Parameter && isSymbolAssigned(symbol))) { + links.flags &= ~ts.NodeCheckFlags.InCheckIdentifier; + if (parentType && parentType.flags & ts.TypeFlags.Union && !(parent.kind === ts.SyntaxKind.Parameter && isSymbolAssigned(symbol))) { const pattern = declaration.parent; const narrowedType = getFlowTypeOfReference(pattern, parentType, parentType, /*flowContainer*/ undefined, location.flowNode); - if (narrowedType.flags & TypeFlags.Never) { + if (narrowedType.flags & ts.TypeFlags.Never) { return neverType; } return getBindingElementTypeFromParentType(declaration, narrowedType); @@ -25577,15 +25025,15 @@ namespace ts { // the arrow function AST node for '(kind, payload) => ...' as a pseudo-reference and narrow this reference as // if it occurred in the specified location. We then recompute the narrowed parameter type by indexing into the // narrowed tuple type. - if (isParameter(declaration) && !declaration.type && !declaration.initializer && !declaration.dotDotDotToken) { + if (ts.isParameter(declaration) && !declaration.type && !declaration.initializer && !declaration.dotDotDotToken) { const func = declaration.parent; if (func.parameters.length >= 2 && isContextSensitiveFunctionOrObjectLiteralMethod(func)) { const contextualSignature = getContextualSignature(func); if (contextualSignature && contextualSignature.parameters.length === 1 && signatureHasRestParameter(contextualSignature)) { const restType = getReducedApparentType(getTypeOfSymbol(contextualSignature.parameters[0])); - if (restType.flags & TypeFlags.Union && everyType(restType, isTupleType) && !isSymbolAssigned(symbol)) { + if (restType.flags & ts.TypeFlags.Union && everyType(restType, isTupleType) && !isSymbolAssigned(symbol)) { const narrowedType = getFlowTypeOfReference(func, restType, restType, /*flowContainer*/ undefined, location.flowNode); - const index = func.parameters.indexOf(declaration) - (getThisParameter(func) ? 1 : 0); + const index = func.parameters.indexOf(declaration) - (ts.getThisParameter(func) ? 1 : 0); return getIndexedAccessType(narrowedType, getNumberLiteralType(index)); } } @@ -25595,8 +25043,8 @@ namespace ts { return getTypeOfSymbol(symbol); } - function checkIdentifier(node: Identifier, checkMode: CheckMode | undefined): Type { - if (isThisInTypeQuery(node)) { + function checkIdentifier(node: ts.Identifier, checkMode: CheckMode | undefined): ts.Type { + if (ts.isThisInTypeQuery(node)) { return checkThisExpression(node); } @@ -25613,27 +25061,27 @@ namespace ts { // can explicitly bound arguments objects if (symbol === argumentsSymbol) { if (isInPropertyInitializerOrClassStaticBlock(node)) { - error(node, Diagnostics.arguments_cannot_be_referenced_in_property_initializers); + error(node, ts.Diagnostics.arguments_cannot_be_referenced_in_property_initializers); return errorType; } - const container = getContainingFunction(node)!; - if (languageVersion < ScriptTarget.ES2015) { - if (container.kind === SyntaxKind.ArrowFunction) { - error(node, Diagnostics.The_arguments_object_cannot_be_referenced_in_an_arrow_function_in_ES3_and_ES5_Consider_using_a_standard_function_expression); + const container = ts.getContainingFunction(node)!; + if (languageVersion < ts.ScriptTarget.ES2015) { + if (container.kind === ts.SyntaxKind.ArrowFunction) { + error(node, ts.Diagnostics.The_arguments_object_cannot_be_referenced_in_an_arrow_function_in_ES3_and_ES5_Consider_using_a_standard_function_expression); } - else if (hasSyntacticModifier(container, ModifierFlags.Async)) { - error(node, Diagnostics.The_arguments_object_cannot_be_referenced_in_an_async_function_or_method_in_ES3_and_ES5_Consider_using_a_standard_function_or_method); + else if (ts.hasSyntacticModifier(container, ts.ModifierFlags.Async)) { + error(node, ts.Diagnostics.The_arguments_object_cannot_be_referenced_in_an_async_function_or_method_in_ES3_and_ES5_Consider_using_a_standard_function_or_method); } } - getNodeLinks(container).flags |= NodeCheckFlags.CaptureArguments; + getNodeLinks(container).flags |= ts.NodeCheckFlags.CaptureArguments; return getTypeOfSymbol(symbol); } // We should only mark aliases as referenced if there isn't a local value declaration // for the symbol. Also, don't mark any property access expression LHS - checkPropertyAccessExpression will handle that - if (!(node.parent && isPropertyAccessExpression(node.parent) && node.parent.expression === node)) { + if (!(node.parent && ts.isPropertyAccessExpression(node.parent) && node.parent.expression === node)) { markAliasReferenced(symbol, node); } @@ -25644,38 +25092,38 @@ namespace ts { } let declaration = localOrExportSymbol.valueDeclaration; - if (declaration && localOrExportSymbol.flags & SymbolFlags.Class) { + if (declaration && localOrExportSymbol.flags & ts.SymbolFlags.Class) { // Due to the emit for class decorators, any reference to the class from inside of the class body // must instead be rewritten to point to a temporary variable to avoid issues with the double-bind // behavior of class names in ES6. - if (declaration.kind === SyntaxKind.ClassDeclaration - && nodeIsDecorated(declaration as ClassDeclaration)) { - let container = getContainingClass(node); + if (declaration.kind === ts.SyntaxKind.ClassDeclaration + && ts.nodeIsDecorated(declaration as ts.ClassDeclaration)) { + let container = ts.getContainingClass(node); while (container !== undefined) { if (container === declaration && container.name !== node) { - getNodeLinks(declaration).flags |= NodeCheckFlags.ClassWithConstructorReference; - getNodeLinks(node).flags |= NodeCheckFlags.ConstructorReferenceInClass; + getNodeLinks(declaration).flags |= ts.NodeCheckFlags.ClassWithConstructorReference; + getNodeLinks(node).flags |= ts.NodeCheckFlags.ConstructorReferenceInClass; break; } - container = getContainingClass(container); + container = ts.getContainingClass(container); } } - else if (declaration.kind === SyntaxKind.ClassExpression) { + else if (declaration.kind === ts.SyntaxKind.ClassExpression) { // When we emit a class expression with static members that contain a reference // to the constructor in the initializer, we will need to substitute that // binding with an alias as the class name is not in scope. - let container = getThisContainer(node, /*includeArrowFunctions*/ false); - while (container.kind !== SyntaxKind.SourceFile) { + let container = ts.getThisContainer(node, /*includeArrowFunctions*/ false); + while (container.kind !== ts.SyntaxKind.SourceFile) { if (container.parent === declaration) { - if (isPropertyDeclaration(container) && isStatic(container) || isClassStaticBlockDeclaration(container)) { - getNodeLinks(declaration).flags |= NodeCheckFlags.ClassWithConstructorReference; - getNodeLinks(node).flags |= NodeCheckFlags.ConstructorReferenceInClass; + if (ts.isPropertyDeclaration(container) && ts.isStatic(container) || ts.isClassStaticBlockDeclaration(container)) { + getNodeLinks(declaration).flags |= ts.NodeCheckFlags.ClassWithConstructorReference; + getNodeLinks(node).flags |= ts.NodeCheckFlags.ConstructorReferenceInClass; } break; } - container = getThisContainer(container, /*includeArrowFunctions*/ false); + container = ts.getThisContainer(container, /*includeArrowFunctions*/ false); } } } @@ -25683,38 +25131,38 @@ namespace ts { checkNestedBlockScopedBinding(node, symbol); let type = getNarrowedTypeOfSymbol(localOrExportSymbol, node); - const assignmentKind = getAssignmentTargetKind(node); + const assignmentKind = ts.getAssignmentTargetKind(node); if (assignmentKind) { - if (!(localOrExportSymbol.flags & SymbolFlags.Variable) && - !(isInJSFile(node) && localOrExportSymbol.flags & SymbolFlags.ValueModule)) { - const assignmentError = localOrExportSymbol.flags & SymbolFlags.Enum ? Diagnostics.Cannot_assign_to_0_because_it_is_an_enum - : localOrExportSymbol.flags & SymbolFlags.Class ? Diagnostics.Cannot_assign_to_0_because_it_is_a_class - : localOrExportSymbol.flags & SymbolFlags.Module ? Diagnostics.Cannot_assign_to_0_because_it_is_a_namespace - : localOrExportSymbol.flags & SymbolFlags.Function ? Diagnostics.Cannot_assign_to_0_because_it_is_a_function - : localOrExportSymbol.flags & SymbolFlags.Alias ? Diagnostics.Cannot_assign_to_0_because_it_is_an_import - : Diagnostics.Cannot_assign_to_0_because_it_is_not_a_variable; + if (!(localOrExportSymbol.flags & ts.SymbolFlags.Variable) && + !(ts.isInJSFile(node) && localOrExportSymbol.flags & ts.SymbolFlags.ValueModule)) { + const assignmentError = localOrExportSymbol.flags & ts.SymbolFlags.Enum ? ts.Diagnostics.Cannot_assign_to_0_because_it_is_an_enum + : localOrExportSymbol.flags & ts.SymbolFlags.Class ? ts.Diagnostics.Cannot_assign_to_0_because_it_is_a_class + : localOrExportSymbol.flags & ts.SymbolFlags.Module ? ts.Diagnostics.Cannot_assign_to_0_because_it_is_a_namespace + : localOrExportSymbol.flags & ts.SymbolFlags.Function ? ts.Diagnostics.Cannot_assign_to_0_because_it_is_a_function + : localOrExportSymbol.flags & ts.SymbolFlags.Alias ? ts.Diagnostics.Cannot_assign_to_0_because_it_is_an_import + : ts.Diagnostics.Cannot_assign_to_0_because_it_is_not_a_variable; error(node, assignmentError, symbolToString(symbol)); return errorType; } if (isReadonlySymbol(localOrExportSymbol)) { - if (localOrExportSymbol.flags & SymbolFlags.Variable) { - error(node, Diagnostics.Cannot_assign_to_0_because_it_is_a_constant, symbolToString(symbol)); + if (localOrExportSymbol.flags & ts.SymbolFlags.Variable) { + error(node, ts.Diagnostics.Cannot_assign_to_0_because_it_is_a_constant, symbolToString(symbol)); } else { - error(node, Diagnostics.Cannot_assign_to_0_because_it_is_a_read_only_property, symbolToString(symbol)); + error(node, ts.Diagnostics.Cannot_assign_to_0_because_it_is_a_read_only_property, symbolToString(symbol)); } return errorType; } } - const isAlias = localOrExportSymbol.flags & SymbolFlags.Alias; + const isAlias = localOrExportSymbol.flags & ts.SymbolFlags.Alias; // We only narrow variables and parameters occurring in a non-assignment position. For all other // entities we simply return the declared type. - if (localOrExportSymbol.flags & SymbolFlags.Variable) { - if (assignmentKind === AssignmentKind.Definite) { + if (localOrExportSymbol.flags & ts.SymbolFlags.Variable) { + if (assignmentKind === ts.AssignmentKind.Definite) { return type; } } @@ -25734,30 +25182,30 @@ namespace ts { // The declaration container is the innermost function that encloses the declaration of the variable // or parameter. The flow container is the innermost function starting with which we analyze the control // flow graph to determine the control flow based type. - const isParameter = getRootDeclaration(declaration).kind === SyntaxKind.Parameter; + const isParameter = ts.getRootDeclaration(declaration).kind === ts.SyntaxKind.Parameter; const declarationContainer = getControlFlowContainer(declaration); let flowContainer = getControlFlowContainer(node); const isOuterVariable = flowContainer !== declarationContainer; - const isSpreadDestructuringAssignmentTarget = node.parent && node.parent.parent && isSpreadAssignment(node.parent) && isDestructuringAssignmentTarget(node.parent.parent); - const isModuleExports = symbol.flags & SymbolFlags.ModuleExports; + const isSpreadDestructuringAssignmentTarget = node.parent && node.parent.parent && ts.isSpreadAssignment(node.parent) && isDestructuringAssignmentTarget(node.parent.parent); + const isModuleExports = symbol.flags & ts.SymbolFlags.ModuleExports; // When the control flow originates in a function expression or arrow function and we are referencing // a const variable or parameter from an outer function, we extend the origin of the control flow // analysis to include the immediately enclosing function. - while (flowContainer !== declarationContainer && (flowContainer.kind === SyntaxKind.FunctionExpression || - flowContainer.kind === SyntaxKind.ArrowFunction || isObjectLiteralOrClassExpressionMethodOrAccessor(flowContainer)) && + while (flowContainer !== declarationContainer && (flowContainer.kind === ts.SyntaxKind.FunctionExpression || + flowContainer.kind === ts.SyntaxKind.ArrowFunction || ts.isObjectLiteralOrClassExpressionMethodOrAccessor(flowContainer)) && (isConstVariable(localOrExportSymbol) && type !== autoArrayType || isParameter && !isSymbolAssigned(localOrExportSymbol))) { flowContainer = getControlFlowContainer(flowContainer); } // We only look for uninitialized variables in strict null checking mode, and only when we can analyze // the entire control flow graph from the variable's declaration (i.e. when the flow container and // declaration container are the same). - const assumeInitialized = isParameter || isAlias || isOuterVariable || isSpreadDestructuringAssignmentTarget || isModuleExports || isBindingElement(declaration) || - type !== autoType && type !== autoArrayType && (!strictNullChecks || (type.flags & (TypeFlags.AnyOrUnknown | TypeFlags.Void)) !== 0 || - isInTypeQuery(node) || node.parent.kind === SyntaxKind.ExportSpecifier) || - node.parent.kind === SyntaxKind.NonNullExpression || - declaration.kind === SyntaxKind.VariableDeclaration && (declaration as VariableDeclaration).exclamationToken || - declaration.flags & NodeFlags.Ambient; - const initialType = assumeInitialized ? (isParameter ? removeOptionalityFromDeclaredType(type, declaration as VariableLikeDeclaration) : type) : + const assumeInitialized = isParameter || isAlias || isOuterVariable || isSpreadDestructuringAssignmentTarget || isModuleExports || ts.isBindingElement(declaration) || + type !== autoType && type !== autoArrayType && (!strictNullChecks || (type.flags & (ts.TypeFlags.AnyOrUnknown | ts.TypeFlags.Void)) !== 0 || + isInTypeQuery(node) || node.parent.kind === ts.SyntaxKind.ExportSpecifier) || + node.parent.kind === ts.SyntaxKind.NonNullExpression || + declaration.kind === ts.SyntaxKind.VariableDeclaration && (declaration as ts.VariableDeclaration).exclamationToken || + declaration.flags & ts.NodeFlags.Ambient; + const initialType = assumeInitialized ? (isParameter ? removeOptionalityFromDeclaredType(type, declaration as ts.VariableLikeDeclaration) : type) : type === autoType || type === autoArrayType ? undefinedType : getOptionalType(type); const flowType = getFlowTypeOfReference(node, type, initialType, flowContainer); @@ -25767,40 +25215,38 @@ namespace ts { if (!isEvolvingArrayOperationTarget(node) && (type === autoType || type === autoArrayType)) { if (flowType === autoType || flowType === autoArrayType) { if (noImplicitAny) { - error(getNameOfDeclaration(declaration), Diagnostics.Variable_0_implicitly_has_type_1_in_some_locations_where_its_type_cannot_be_determined, symbolToString(symbol), typeToString(flowType)); - error(node, Diagnostics.Variable_0_implicitly_has_an_1_type, symbolToString(symbol), typeToString(flowType)); + error(ts.getNameOfDeclaration(declaration), ts.Diagnostics.Variable_0_implicitly_has_type_1_in_some_locations_where_its_type_cannot_be_determined, symbolToString(symbol), typeToString(flowType)); + error(node, ts.Diagnostics.Variable_0_implicitly_has_an_1_type, symbolToString(symbol), typeToString(flowType)); } return convertAutoToAny(flowType); } } - else if (!assumeInitialized && !(getFalsyFlags(type) & TypeFlags.Undefined) && getFalsyFlags(flowType) & TypeFlags.Undefined) { - error(node, Diagnostics.Variable_0_is_used_before_being_assigned, symbolToString(symbol)); + else if (!assumeInitialized && !(getFalsyFlags(type) & ts.TypeFlags.Undefined) && getFalsyFlags(flowType) & ts.TypeFlags.Undefined) { + error(node, ts.Diagnostics.Variable_0_is_used_before_being_assigned, symbolToString(symbol)); // Return the declared type to reduce follow-on errors return type; } return assignmentKind ? getBaseTypeOfLiteralType(flowType) : flowType; } - function isInsideFunctionOrInstancePropertyInitializer(node: Node, threshold: Node): boolean { - return !!findAncestor(node, n => n === threshold ? "quit" : isFunctionLike(n) || ( - n.parent && isPropertyDeclaration(n.parent) && !hasStaticModifier(n.parent) && n.parent.initializer === n - )); + function isInsideFunctionOrInstancePropertyInitializer(node: ts.Node, threshold: ts.Node): boolean { + return !!ts.findAncestor(node, n => n === threshold ? "quit" : ts.isFunctionLike(n) || (n.parent && ts.isPropertyDeclaration(n.parent) && !ts.hasStaticModifier(n.parent) && n.parent.initializer === n)); } - function getPartOfForStatementContainingNode(node: Node, container: ForStatement) { - return findAncestor(node, n => n === container ? "quit" : n === container.initializer || n === container.condition || n === container.incrementor || n === container.statement); + function getPartOfForStatementContainingNode(node: ts.Node, container: ts.ForStatement) { + return ts.findAncestor(node, n => n === container ? "quit" : n === container.initializer || n === container.condition || n === container.incrementor || n === container.statement); } - function getEnclosingIterationStatement(node: Node): Node | undefined { - return findAncestor(node, n => (!n || nodeStartsNewLexicalEnvironment(n)) ? "quit" : isIterationStatement(n, /*lookInLabeledStatements*/ false)); + function getEnclosingIterationStatement(node: ts.Node): ts.Node | undefined { + return ts.findAncestor(node, n => (!n || ts.nodeStartsNewLexicalEnvironment(n)) ? "quit" : ts.isIterationStatement(n, /*lookInLabeledStatements*/ false)); } - function checkNestedBlockScopedBinding(node: Identifier, symbol: Symbol): void { - if (languageVersion >= ScriptTarget.ES2015 || - (symbol.flags & (SymbolFlags.BlockScopedVariable | SymbolFlags.Class)) === 0 || + function checkNestedBlockScopedBinding(node: ts.Identifier, symbol: ts.Symbol): void { + if (languageVersion >= ts.ScriptTarget.ES2015 || + (symbol.flags & (ts.SymbolFlags.BlockScopedVariable | ts.SymbolFlags.Class)) === 0 || !symbol.valueDeclaration || - isSourceFile(symbol.valueDeclaration) || - symbol.valueDeclaration.parent.kind === SyntaxKind.CatchClause) { + ts.isSourceFile(symbol.valueDeclaration) || + symbol.valueDeclaration.parent.kind === ts.SyntaxKind.CatchClause) { return; } @@ -25809,7 +25255,7 @@ namespace ts { // 2. walk from the declaration up to the boundary of lexical environment and check // if there is an iteration statement in between declaration and boundary (is binding/class declared inside iteration statement) - const container = getEnclosingBlockScopeContainer(symbol.valueDeclaration); + const container = ts.getEnclosingBlockScopeContainer(symbol.valueDeclaration); const isCaptured = isInsideFunctionOrInstancePropertyInitializer(node, container); const enclosingIterationStatement = getEnclosingIterationStatement(container); @@ -25817,16 +25263,16 @@ namespace ts { if (isCaptured) { // mark iteration statement as containing block-scoped binding captured in some function let capturesBlockScopeBindingInLoopBody = true; - if (isForStatement(container)) { - const varDeclList = getAncestor(symbol.valueDeclaration, SyntaxKind.VariableDeclarationList); + if (ts.isForStatement(container)) { + const varDeclList = ts.getAncestor(symbol.valueDeclaration, ts.SyntaxKind.VariableDeclarationList); if (varDeclList && varDeclList.parent === container) { const part = getPartOfForStatementContainingNode(node.parent, container); if (part) { const links = getNodeLinks(part); - links.flags |= NodeCheckFlags.ContainsCapturedBlockScopeBinding; + links.flags |= ts.NodeCheckFlags.ContainsCapturedBlockScopeBinding; const capturedBindings = links.capturedBlockScopeBindings || (links.capturedBlockScopeBindings = []); - pushIfUnique(capturedBindings, symbol); + ts.pushIfUnique(capturedBindings, symbol); if (part === container.initializer) { capturesBlockScopeBindingInLoopBody = false; // Initializer is outside of loop body @@ -25835,48 +25281,48 @@ namespace ts { } } if (capturesBlockScopeBindingInLoopBody) { - getNodeLinks(enclosingIterationStatement).flags |= NodeCheckFlags.LoopWithCapturedBlockScopedBinding; + getNodeLinks(enclosingIterationStatement).flags |= ts.NodeCheckFlags.LoopWithCapturedBlockScopedBinding; } } // mark variables that are declared in loop initializer and reassigned inside the body of ForStatement. // if body of ForStatement will be converted to function then we'll need a extra machinery to propagate reassigned values back. - if (isForStatement(container)) { - const varDeclList = getAncestor(symbol.valueDeclaration, SyntaxKind.VariableDeclarationList); + if (ts.isForStatement(container)) { + const varDeclList = ts.getAncestor(symbol.valueDeclaration, ts.SyntaxKind.VariableDeclarationList); if (varDeclList && varDeclList.parent === container && isAssignedInBodyOfForStatement(node, container)) { - getNodeLinks(symbol.valueDeclaration).flags |= NodeCheckFlags.NeedsLoopOutParameter; + getNodeLinks(symbol.valueDeclaration).flags |= ts.NodeCheckFlags.NeedsLoopOutParameter; } } // set 'declared inside loop' bit on the block-scoped binding - getNodeLinks(symbol.valueDeclaration).flags |= NodeCheckFlags.BlockScopedBindingInLoop; + getNodeLinks(symbol.valueDeclaration).flags |= ts.NodeCheckFlags.BlockScopedBindingInLoop; } if (isCaptured) { - getNodeLinks(symbol.valueDeclaration).flags |= NodeCheckFlags.CapturedBlockScopedBinding; + getNodeLinks(symbol.valueDeclaration).flags |= ts.NodeCheckFlags.CapturedBlockScopedBinding; } } - function isBindingCapturedByNode(node: Node, decl: VariableDeclaration | BindingElement) { + function isBindingCapturedByNode(node: ts.Node, decl: ts.VariableDeclaration | ts.BindingElement) { const links = getNodeLinks(node); - return !!links && contains(links.capturedBlockScopeBindings, getSymbolOfNode(decl)); + return !!links && ts.contains(links.capturedBlockScopeBindings, getSymbolOfNode(decl)); } - function isAssignedInBodyOfForStatement(node: Identifier, container: ForStatement): boolean { + function isAssignedInBodyOfForStatement(node: ts.Identifier, container: ts.ForStatement): boolean { // skip parenthesized nodes - let current: Node = node; - while (current.parent.kind === SyntaxKind.ParenthesizedExpression) { + let current: ts.Node = node; + while (current.parent.kind === ts.SyntaxKind.ParenthesizedExpression) { current = current.parent; } // check if node is used as LHS in some assignment expression let isAssigned = false; - if (isAssignmentTarget(current)) { + if (ts.isAssignmentTarget(current)) { isAssigned = true; } - else if ((current.parent.kind === SyntaxKind.PrefixUnaryExpression || current.parent.kind === SyntaxKind.PostfixUnaryExpression)) { - const expr = current.parent as PrefixUnaryExpression | PostfixUnaryExpression; - isAssigned = expr.operator === SyntaxKind.PlusPlusToken || expr.operator === SyntaxKind.MinusMinusToken; + else if ((current.parent.kind === ts.SyntaxKind.PrefixUnaryExpression || current.parent.kind === ts.SyntaxKind.PostfixUnaryExpression)) { + const expr = current.parent as ts.PrefixUnaryExpression | ts.PostfixUnaryExpression; + isAssigned = expr.operator === ts.SyntaxKind.PlusPlusToken || expr.operator === ts.SyntaxKind.MinusMinusToken; } if (!isAssigned) { @@ -25885,24 +25331,24 @@ namespace ts { // at this point we know that node is the target of assignment // now check that modification happens inside the statement part of the ForStatement - return !!findAncestor(current, n => n === container ? "quit" : n === container.statement); + return !!ts.findAncestor(current, n => n === container ? "quit" : n === container.statement); } - function captureLexicalThis(node: Node, container: Node): void { - getNodeLinks(node).flags |= NodeCheckFlags.LexicalThis; - if (container.kind === SyntaxKind.PropertyDeclaration || container.kind === SyntaxKind.Constructor) { + function captureLexicalThis(node: ts.Node, container: ts.Node): void { + getNodeLinks(node).flags |= ts.NodeCheckFlags.LexicalThis; + if (container.kind === ts.SyntaxKind.PropertyDeclaration || container.kind === ts.SyntaxKind.Constructor) { const classNode = container.parent; - getNodeLinks(classNode).flags |= NodeCheckFlags.CaptureThis; + getNodeLinks(classNode).flags |= ts.NodeCheckFlags.CaptureThis; } else { - getNodeLinks(container).flags |= NodeCheckFlags.CaptureThis; + getNodeLinks(container).flags |= ts.NodeCheckFlags.CaptureThis; } } - function findFirstSuperCall(node: Node): SuperCall | undefined { - return isSuperCall(node) ? node : - isFunctionLike(node) ? undefined : - forEachChild(node, findFirstSuperCall); + function findFirstSuperCall(node: ts.Node): ts.SuperCall | undefined { + return ts.isSuperCall(node) ? node : + ts.isFunctionLike(node) ? undefined : + ts.forEachChild(node, findFirstSuperCall); } /** @@ -25910,17 +25356,17 @@ namespace ts { * Otherwise, return false * @param classDecl a class declaration to check if it extends null */ - function classDeclarationExtendsNull(classDecl: ClassDeclaration): boolean { + function classDeclarationExtendsNull(classDecl: ts.ClassDeclaration): boolean { const classSymbol = getSymbolOfNode(classDecl); - const classInstanceType = getDeclaredTypeOfSymbol(classSymbol) as InterfaceType; + const classInstanceType = getDeclaredTypeOfSymbol(classSymbol) as ts.InterfaceType; const baseConstructorType = getBaseConstructorTypeOfClass(classInstanceType); return baseConstructorType === nullWideningType; } - function checkThisBeforeSuper(node: Node, container: Node, diagnosticMessage: DiagnosticMessage) { - const containingClassDecl = container.parent as ClassDeclaration; - const baseTypeNode = getClassExtendsHeritageElement(containingClassDecl); + function checkThisBeforeSuper(node: ts.Node, container: ts.Node, diagnosticMessage: ts.DiagnosticMessage) { + const containingClassDecl = container.parent as ts.ClassDeclaration; + const baseTypeNode = ts.getClassExtendsHeritageElement(containingClassDecl); // If a containing class does not have extends clause or the class extends null // skip checking whether super statement is called before "this" accessing. @@ -25931,53 +25377,53 @@ namespace ts { } } - function checkThisInStaticClassFieldInitializerInDecoratedClass(thisExpression: Node, container: Node) { - if (isPropertyDeclaration(container) && hasStaticModifier(container) && - container.initializer && textRangeContainsPositionInclusive(container.initializer, thisExpression.pos) && length(container.parent.decorators)) { - error(thisExpression, Diagnostics.Cannot_use_this_in_a_static_property_initializer_of_a_decorated_class); + function checkThisInStaticClassFieldInitializerInDecoratedClass(thisExpression: ts.Node, container: ts.Node) { + if (ts.isPropertyDeclaration(container) && ts.hasStaticModifier(container) && + container.initializer && ts.textRangeContainsPositionInclusive(container.initializer, thisExpression.pos) && ts.length(container.parent.decorators)) { + error(thisExpression, ts.Diagnostics.Cannot_use_this_in_a_static_property_initializer_of_a_decorated_class); } } - function checkThisExpression(node: Node): Type { + function checkThisExpression(node: ts.Node): ts.Type { const isNodeInTypeQuery = isInTypeQuery(node); // Stop at the first arrow function so that we can // tell whether 'this' needs to be captured. - let container = getThisContainer(node, /* includeArrowFunctions */ true); + let container = ts.getThisContainer(node, /* includeArrowFunctions */ true); let capturedByArrowFunction = false; - if (container.kind === SyntaxKind.Constructor) { - checkThisBeforeSuper(node, container, Diagnostics.super_must_be_called_before_accessing_this_in_the_constructor_of_a_derived_class); + if (container.kind === ts.SyntaxKind.Constructor) { + checkThisBeforeSuper(node, container, ts.Diagnostics.super_must_be_called_before_accessing_this_in_the_constructor_of_a_derived_class); } // Now skip arrow functions to get the "real" owner of 'this'. - if (container.kind === SyntaxKind.ArrowFunction) { - container = getThisContainer(container, /* includeArrowFunctions */ false); + if (container.kind === ts.SyntaxKind.ArrowFunction) { + container = ts.getThisContainer(container, /* includeArrowFunctions */ false); capturedByArrowFunction = true; } checkThisInStaticClassFieldInitializerInDecoratedClass(node, container); switch (container.kind) { - case SyntaxKind.ModuleDeclaration: - error(node, Diagnostics.this_cannot_be_referenced_in_a_module_or_namespace_body); + case ts.SyntaxKind.ModuleDeclaration: + error(node, ts.Diagnostics.this_cannot_be_referenced_in_a_module_or_namespace_body); // do not return here so in case if lexical this is captured - it will be reflected in flags on NodeLinks break; - case SyntaxKind.EnumDeclaration: - error(node, Diagnostics.this_cannot_be_referenced_in_current_location); + case ts.SyntaxKind.EnumDeclaration: + error(node, ts.Diagnostics.this_cannot_be_referenced_in_current_location); // do not return here so in case if lexical this is captured - it will be reflected in flags on NodeLinks break; - case SyntaxKind.Constructor: + case ts.SyntaxKind.Constructor: if (isInConstructorArgumentInitializer(node, container)) { - error(node, Diagnostics.this_cannot_be_referenced_in_constructor_arguments); + error(node, ts.Diagnostics.this_cannot_be_referenced_in_constructor_arguments); // do not return here so in case if lexical this is captured - it will be reflected in flags on NodeLinks } break; - case SyntaxKind.ComputedPropertyName: - error(node, Diagnostics.this_cannot_be_referenced_in_a_computed_property_name); + case ts.SyntaxKind.ComputedPropertyName: + error(node, ts.Diagnostics.this_cannot_be_referenced_in_a_computed_property_name); break; } // When targeting es6, mark that we'll need to capture `this` in its lexically bound scope. - if (!isNodeInTypeQuery && capturedByArrowFunction && languageVersion < ScriptTarget.ES2015) { + if (!isNodeInTypeQuery && capturedByArrowFunction && languageVersion < ts.ScriptTarget.ES2015) { captureLexicalThis(node, container); } @@ -25985,15 +25431,15 @@ namespace ts { if (noImplicitThis) { const globalThisType = getTypeOfSymbol(globalThisSymbol); if (type === globalThisType && capturedByArrowFunction) { - error(node, Diagnostics.The_containing_arrow_function_captures_the_global_value_of_this); + error(node, ts.Diagnostics.The_containing_arrow_function_captures_the_global_value_of_this); } else if (!type) { // With noImplicitThis, functions may not reference 'this' if it has type 'any' - const diag = error(node, Diagnostics.this_implicitly_has_type_any_because_it_does_not_have_a_type_annotation); - if (!isSourceFile(container)) { + const diag = error(node, ts.Diagnostics.this_implicitly_has_type_any_because_it_does_not_have_a_type_annotation); + if (!ts.isSourceFile(container)) { const outsideThis = tryGetThisTypeAt(container); if (outsideThis && outsideThis !== globalThisType) { - addRelatedInfo(diag, createDiagnosticForNode(container, Diagnostics.An_outer_value_of_this_is_shadowed_by_this_container)); + ts.addRelatedInfo(diag, ts.createDiagnosticForNode(container, ts.Diagnostics.An_outer_value_of_this_is_shadowed_by_this_container)); } } } @@ -26001,10 +25447,10 @@ namespace ts { return type || anyType; } - function tryGetThisTypeAt(node: Node, includeGlobalThis = true, container = getThisContainer(node, /*includeArrowFunctions*/ false)): Type | undefined { - const isInJS = isInJSFile(node); - if (isFunctionLike(container) && - (!isInParameterInitializerBeforeContainingFunction(node) || getThisParameter(container))) { + function tryGetThisTypeAt(node: ts.Node, includeGlobalThis = true, container = ts.getThisContainer(node, /*includeArrowFunctions*/ false)): ts.Type | undefined { + const isInJS = ts.isInJSFile(node); + if (ts.isFunctionLike(container) && + (!isInParameterInitializerBeforeContainingFunction(node) || ts.getThisParameter(container))) { let thisType = getThisTypeOfDeclaration(container) || isInJS && getTypeForThisExpressionFromJSDoc(container); // Note: a parameter initializer should refer to class-this unless function-this is explicitly annotated. // If this is a function in a JS file, it might be a class method. @@ -26012,12 +25458,12 @@ namespace ts { const className = getClassNameFromPrototypeMethod(container); if (isInJS && className) { const classSymbol = checkExpression(className).symbol; - if (classSymbol && classSymbol.members && (classSymbol.flags & SymbolFlags.Function)) { - thisType = (getDeclaredTypeOfSymbol(classSymbol) as InterfaceType).thisType; + if (classSymbol && classSymbol.members && (classSymbol.flags & ts.SymbolFlags.Function)) { + thisType = (getDeclaredTypeOfSymbol(classSymbol) as ts.InterfaceType).thisType; } } else if (isJSConstructor(container)) { - thisType = (getDeclaredTypeOfSymbol(getMergedSymbol(container.symbol)) as InterfaceType).thisType; + thisType = (getDeclaredTypeOfSymbol(getMergedSymbol(container.symbol)) as ts.InterfaceType).thisType; } thisType ||= getContextualThisParameterType(container); } @@ -26027,13 +25473,13 @@ namespace ts { } } - if (isClassLike(container.parent)) { + if (ts.isClassLike(container.parent)) { const symbol = getSymbolOfNode(container.parent); - const type = isStatic(container) ? getTypeOfSymbol(symbol) : (getDeclaredTypeOfSymbol(symbol) as InterfaceType).thisType!; + const type = ts.isStatic(container) ? getTypeOfSymbol(symbol) : (getDeclaredTypeOfSymbol(symbol) as ts.InterfaceType).thisType!; return getFlowTypeOfReference(node, type); } - if (isSourceFile(container)) { + if (ts.isSourceFile(container)) { // look up in the source file's locals or exports if (container.commonJsModuleIndicator) { const fileSymbol = getSymbolOfNode(container); @@ -26049,110 +25495,109 @@ namespace ts { } } - function getExplicitThisType(node: Expression) { - const container = getThisContainer(node, /*includeArrowFunctions*/ false); - if (isFunctionLike(container)) { + function getExplicitThisType(node: ts.Expression) { + const container = ts.getThisContainer(node, /*includeArrowFunctions*/ false); + if (ts.isFunctionLike(container)) { const signature = getSignatureFromDeclaration(container); if (signature.thisParameter) { return getExplicitTypeOfSymbol(signature.thisParameter); } } - if (isClassLike(container.parent)) { + if (ts.isClassLike(container.parent)) { const symbol = getSymbolOfNode(container.parent); - return isStatic(container) ? getTypeOfSymbol(symbol) : (getDeclaredTypeOfSymbol(symbol) as InterfaceType).thisType!; + return ts.isStatic(container) ? getTypeOfSymbol(symbol) : (getDeclaredTypeOfSymbol(symbol) as ts.InterfaceType).thisType!; } } - function getClassNameFromPrototypeMethod(container: Node) { + function getClassNameFromPrototypeMethod(container: ts.Node) { // Check if it's the RHS of a x.prototype.y = function [name]() { .... } - if (container.kind === SyntaxKind.FunctionExpression && - isBinaryExpression(container.parent) && - getAssignmentDeclarationKind(container.parent) === AssignmentDeclarationKind.PrototypeProperty) { + if (container.kind === ts.SyntaxKind.FunctionExpression && + ts.isBinaryExpression(container.parent) && + ts.getAssignmentDeclarationKind(container.parent) === ts.AssignmentDeclarationKind.PrototypeProperty) { // Get the 'x' of 'x.prototype.y = container' return ((container.parent // x.prototype.y = container - .left as PropertyAccessExpression) // x.prototype.y - .expression as PropertyAccessExpression) // x.prototype + .left as ts.PropertyAccessExpression) // x.prototype.y + .expression as ts.PropertyAccessExpression) // x.prototype .expression; // x } // x.prototype = { method() { } } - else if (container.kind === SyntaxKind.MethodDeclaration && - container.parent.kind === SyntaxKind.ObjectLiteralExpression && - isBinaryExpression(container.parent.parent) && - getAssignmentDeclarationKind(container.parent.parent) === AssignmentDeclarationKind.Prototype) { - return (container.parent.parent.left as PropertyAccessExpression).expression; + else if (container.kind === ts.SyntaxKind.MethodDeclaration && + container.parent.kind === ts.SyntaxKind.ObjectLiteralExpression && + ts.isBinaryExpression(container.parent.parent) && + ts.getAssignmentDeclarationKind(container.parent.parent) === ts.AssignmentDeclarationKind.Prototype) { + return (container.parent.parent.left as ts.PropertyAccessExpression).expression; } // x.prototype = { method: function() { } } - else if (container.kind === SyntaxKind.FunctionExpression && - container.parent.kind === SyntaxKind.PropertyAssignment && - container.parent.parent.kind === SyntaxKind.ObjectLiteralExpression && - isBinaryExpression(container.parent.parent.parent) && - getAssignmentDeclarationKind(container.parent.parent.parent) === AssignmentDeclarationKind.Prototype) { - return (container.parent.parent.parent.left as PropertyAccessExpression).expression; + else if (container.kind === ts.SyntaxKind.FunctionExpression && + container.parent.kind === ts.SyntaxKind.PropertyAssignment && + container.parent.parent.kind === ts.SyntaxKind.ObjectLiteralExpression && + ts.isBinaryExpression(container.parent.parent.parent) && + ts.getAssignmentDeclarationKind(container.parent.parent.parent) === ts.AssignmentDeclarationKind.Prototype) { + return (container.parent.parent.parent.left as ts.PropertyAccessExpression).expression; } // Object.defineProperty(x, "method", { value: function() { } }); // Object.defineProperty(x, "method", { set: (x: () => void) => void }); // Object.defineProperty(x, "method", { get: () => function() { }) }); - else if (container.kind === SyntaxKind.FunctionExpression && - isPropertyAssignment(container.parent) && - isIdentifier(container.parent.name) && + else if (container.kind === ts.SyntaxKind.FunctionExpression && + ts.isPropertyAssignment(container.parent) && + ts.isIdentifier(container.parent.name) && (container.parent.name.escapedText === "value" || container.parent.name.escapedText === "get" || container.parent.name.escapedText === "set") && - isObjectLiteralExpression(container.parent.parent) && - isCallExpression(container.parent.parent.parent) && + ts.isObjectLiteralExpression(container.parent.parent) && + ts.isCallExpression(container.parent.parent.parent) && container.parent.parent.parent.arguments[2] === container.parent.parent && - getAssignmentDeclarationKind(container.parent.parent.parent) === AssignmentDeclarationKind.ObjectDefinePrototypeProperty) { - return (container.parent.parent.parent.arguments[0] as PropertyAccessExpression).expression; + ts.getAssignmentDeclarationKind(container.parent.parent.parent) === ts.AssignmentDeclarationKind.ObjectDefinePrototypeProperty) { + return (container.parent.parent.parent.arguments[0] as ts.PropertyAccessExpression).expression; } // Object.defineProperty(x, "method", { value() { } }); // Object.defineProperty(x, "method", { set(x: () => void) {} }); // Object.defineProperty(x, "method", { get() { return () => {} } }); - else if (isMethodDeclaration(container) && - isIdentifier(container.name) && + else if (ts.isMethodDeclaration(container) && + ts.isIdentifier(container.name) && (container.name.escapedText === "value" || container.name.escapedText === "get" || container.name.escapedText === "set") && - isObjectLiteralExpression(container.parent) && - isCallExpression(container.parent.parent) && + ts.isObjectLiteralExpression(container.parent) && + ts.isCallExpression(container.parent.parent) && container.parent.parent.arguments[2] === container.parent && - getAssignmentDeclarationKind(container.parent.parent) === AssignmentDeclarationKind.ObjectDefinePrototypeProperty) { - return (container.parent.parent.arguments[0] as PropertyAccessExpression).expression; + ts.getAssignmentDeclarationKind(container.parent.parent) === ts.AssignmentDeclarationKind.ObjectDefinePrototypeProperty) { + return (container.parent.parent.arguments[0] as ts.PropertyAccessExpression).expression; } } - function getTypeForThisExpressionFromJSDoc(node: Node) { - const jsdocType = getJSDocType(node); - if (jsdocType && jsdocType.kind === SyntaxKind.JSDocFunctionType) { - const jsDocFunctionType = jsdocType as JSDocFunctionType; + function getTypeForThisExpressionFromJSDoc(node: ts.Node) { + const jsdocType = ts.getJSDocType(node); + if (jsdocType && jsdocType.kind === ts.SyntaxKind.JSDocFunctionType) { + const jsDocFunctionType = jsdocType as ts.JSDocFunctionType; if (jsDocFunctionType.parameters.length > 0 && jsDocFunctionType.parameters[0].name && - (jsDocFunctionType.parameters[0].name as Identifier).escapedText === InternalSymbolName.This) { + (jsDocFunctionType.parameters[0].name as ts.Identifier).escapedText === ts.InternalSymbolName.This) { return getTypeFromTypeNode(jsDocFunctionType.parameters[0].type!); } } - const thisTag = getJSDocThisTag(node); + const thisTag = ts.getJSDocThisTag(node); if (thisTag && thisTag.typeExpression) { return getTypeFromTypeNode(thisTag.typeExpression); } } - function isInConstructorArgumentInitializer(node: Node, constructorDecl: Node): boolean { - return !!findAncestor(node, n => isFunctionLikeDeclaration(n) ? "quit" : n.kind === SyntaxKind.Parameter && n.parent === constructorDecl); + function isInConstructorArgumentInitializer(node: ts.Node, constructorDecl: ts.Node): boolean { + return !!ts.findAncestor(node, n => ts.isFunctionLikeDeclaration(n) ? "quit" : n.kind === ts.SyntaxKind.Parameter && n.parent === constructorDecl); } - function checkSuperExpression(node: Node): Type { - const isCallExpression = node.parent.kind === SyntaxKind.CallExpression && (node.parent as CallExpression).expression === node; - - const immediateContainer = getSuperContainer(node, /*stopOnFunctions*/ true); + function checkSuperExpression(node: ts.Node): ts.Type { + const isCallExpression = node.parent.kind === ts.SyntaxKind.CallExpression && (node.parent as ts.CallExpression).expression === node; + const immediateContainer = ts.getSuperContainer(node, /*stopOnFunctions*/ true); let container = immediateContainer; let needToCaptureLexicalThis = false; // adjust the container reference in case if super is used inside arrow functions with arbitrarily deep nesting if (!isCallExpression) { - while (container && container.kind === SyntaxKind.ArrowFunction) { - container = getSuperContainer(container, /*stopOnFunctions*/ true); - needToCaptureLexicalThis = languageVersion < ScriptTarget.ES2015; + while (container && container.kind === ts.SyntaxKind.ArrowFunction) { + container = ts.getSuperContainer(container, /*stopOnFunctions*/ true); + needToCaptureLexicalThis = languageVersion < ts.ScriptTarget.ES2015; } } const canUseSuperExpression = isLegalUsageOfSuperExpression(container); - let nodeCheckFlag: NodeCheckFlags = 0; + let nodeCheckFlag: ts.NodeCheckFlags = 0; if (!canUseSuperExpression) { // issue more specific error if super is used in computed property name @@ -26160,43 +25605,43 @@ namespace ts { // class B { // [super.foo()]() {} // } - const current = findAncestor(node, n => n === container ? "quit" : n.kind === SyntaxKind.ComputedPropertyName); - if (current && current.kind === SyntaxKind.ComputedPropertyName) { - error(node, Diagnostics.super_cannot_be_referenced_in_a_computed_property_name); + const current = ts.findAncestor(node, n => n === container ? "quit" : n.kind === ts.SyntaxKind.ComputedPropertyName); + if (current && current.kind === ts.SyntaxKind.ComputedPropertyName) { + error(node, ts.Diagnostics.super_cannot_be_referenced_in_a_computed_property_name); } else if (isCallExpression) { - error(node, Diagnostics.Super_calls_are_not_permitted_outside_constructors_or_in_nested_functions_inside_constructors); + error(node, ts.Diagnostics.Super_calls_are_not_permitted_outside_constructors_or_in_nested_functions_inside_constructors); } - else if (!container || !container.parent || !(isClassLike(container.parent) || container.parent.kind === SyntaxKind.ObjectLiteralExpression)) { - error(node, Diagnostics.super_can_only_be_referenced_in_members_of_derived_classes_or_object_literal_expressions); + else if (!container || !container.parent || !(ts.isClassLike(container.parent) || container.parent.kind === ts.SyntaxKind.ObjectLiteralExpression)) { + error(node, ts.Diagnostics.super_can_only_be_referenced_in_members_of_derived_classes_or_object_literal_expressions); } else { - error(node, Diagnostics.super_property_access_is_permitted_only_in_a_constructor_member_function_or_member_accessor_of_a_derived_class); + error(node, ts.Diagnostics.super_property_access_is_permitted_only_in_a_constructor_member_function_or_member_accessor_of_a_derived_class); } return errorType; } - if (!isCallExpression && immediateContainer.kind === SyntaxKind.Constructor) { - checkThisBeforeSuper(node, container, Diagnostics.super_must_be_called_before_accessing_a_property_of_super_in_the_constructor_of_a_derived_class); + if (!isCallExpression && immediateContainer.kind === ts.SyntaxKind.Constructor) { + checkThisBeforeSuper(node, container, ts.Diagnostics.super_must_be_called_before_accessing_a_property_of_super_in_the_constructor_of_a_derived_class); } - if (isStatic(container) || isCallExpression) { - nodeCheckFlag = NodeCheckFlags.SuperStatic; + if (ts.isStatic(container) || isCallExpression) { + nodeCheckFlag = ts.NodeCheckFlags.SuperStatic; if (!isCallExpression && - languageVersion >= ScriptTarget.ES2015 && languageVersion <= ScriptTarget.ES2021 && - (isPropertyDeclaration(container) || isClassStaticBlockDeclaration(container))) { + languageVersion >= ts.ScriptTarget.ES2015 && languageVersion <= ts.ScriptTarget.ES2021 && + (ts.isPropertyDeclaration(container) || ts.isClassStaticBlockDeclaration(container))) { // for `super.x` or `super[x]` in a static initializer, mark all enclosing // block scope containers so that we can report potential collisions with // `Reflect`. - forEachEnclosingBlockScopeContainer(node.parent, current => { - if (!isSourceFile(current) || isExternalOrCommonJsModule(current)) { - getNodeLinks(current).flags |= NodeCheckFlags.ContainsSuperPropertyInStaticInitializer; + ts.forEachEnclosingBlockScopeContainer(node.parent, current => { + if (!ts.isSourceFile(current) || ts.isExternalOrCommonJsModule(current)) { + getNodeLinks(current).flags |= ts.NodeCheckFlags.ContainsSuperPropertyInStaticInitializer; } }); } } else { - nodeCheckFlag = NodeCheckFlags.SuperInstance; + nodeCheckFlag = ts.NodeCheckFlags.SuperInstance; } getNodeLinks(node).flags |= nodeCheckFlag; @@ -26260,12 +25705,12 @@ namespace ts { // as a call expression cannot be used as the target of a destructuring assignment while a property access can. // // For element access expressions (`super[x]`), we emit a generic helper that forwards the element access in both situations. - if (container.kind === SyntaxKind.MethodDeclaration && hasSyntacticModifier(container, ModifierFlags.Async)) { - if (isSuperProperty(node.parent) && isAssignmentTarget(node.parent)) { - getNodeLinks(container).flags |= NodeCheckFlags.AsyncMethodWithSuperBinding; + if (container.kind === ts.SyntaxKind.MethodDeclaration && ts.hasSyntacticModifier(container, ts.ModifierFlags.Async)) { + if (ts.isSuperProperty(node.parent) && ts.isAssignmentTarget(node.parent)) { + getNodeLinks(container).flags |= ts.NodeCheckFlags.AsyncMethodWithSuperBinding; } else { - getNodeLinks(container).flags |= NodeCheckFlags.AsyncMethodWithSuper; + getNodeLinks(container).flags |= ts.NodeCheckFlags.AsyncMethodWithSuper; } } @@ -26276,9 +25721,9 @@ namespace ts { captureLexicalThis(node.parent, container); } - if (container.parent.kind === SyntaxKind.ObjectLiteralExpression) { - if (languageVersion < ScriptTarget.ES2015) { - error(node, Diagnostics.super_is_only_allowed_in_members_of_object_literal_expressions_when_option_target_is_ES2015_or_higher); + if (container.parent.kind === ts.SyntaxKind.ObjectLiteralExpression) { + if (languageVersion < ts.ScriptTarget.ES2015) { + error(node, ts.Diagnostics.super_is_only_allowed_in_members_of_object_literal_expressions_when_option_target_is_ES2015_or_higher); return errorType; } else { @@ -26288,29 +25733,29 @@ namespace ts { } // at this point the only legal case for parent is ClassLikeDeclaration - const classLikeDeclaration = container.parent as ClassLikeDeclaration; - if (!getClassExtendsHeritageElement(classLikeDeclaration)) { - error(node, Diagnostics.super_can_only_be_referenced_in_a_derived_class); + const classLikeDeclaration = container.parent as ts.ClassLikeDeclaration; + if (!ts.getClassExtendsHeritageElement(classLikeDeclaration)) { + error(node, ts.Diagnostics.super_can_only_be_referenced_in_a_derived_class); return errorType; } - const classType = getDeclaredTypeOfSymbol(getSymbolOfNode(classLikeDeclaration)) as InterfaceType; + const classType = getDeclaredTypeOfSymbol(getSymbolOfNode(classLikeDeclaration)) as ts.InterfaceType; const baseClassType = classType && getBaseTypes(classType)[0]; if (!baseClassType) { return errorType; } - if (container.kind === SyntaxKind.Constructor && isInConstructorArgumentInitializer(node, container)) { + if (container.kind === ts.SyntaxKind.Constructor && isInConstructorArgumentInitializer(node, container)) { // issue custom error message for super property access in constructor arguments (to be aligned with old compiler) - error(node, Diagnostics.super_cannot_be_referenced_in_constructor_arguments); + error(node, ts.Diagnostics.super_cannot_be_referenced_in_constructor_arguments); return errorType; } - return nodeCheckFlag === NodeCheckFlags.SuperStatic + return nodeCheckFlag === ts.NodeCheckFlags.SuperStatic ? getBaseConstructorTypeOfClass(classType) : getTypeWithThisArgument(baseClassType, classType.thisType); - function isLegalUsageOfSuperExpression(container: Node): boolean { + function isLegalUsageOfSuperExpression(container: ts.Node): boolean { if (!container) { return false; } @@ -26318,7 +25763,7 @@ namespace ts { if (isCallExpression) { // TS 1.0 SPEC (April 2014): 4.8.1 // Super calls are only permitted in constructors of derived classes - return container.kind === SyntaxKind.Constructor; + return container.kind === ts.SyntaxKind.Constructor; } else { // TS 1.0 SPEC (April 2014) @@ -26327,23 +25772,23 @@ namespace ts { // - In a static member function or static member accessor // topmost container must be something that is directly nested in the class declaration\object literal expression - if (isClassLike(container.parent) || container.parent.kind === SyntaxKind.ObjectLiteralExpression) { - if (isStatic(container)) { - return container.kind === SyntaxKind.MethodDeclaration || - container.kind === SyntaxKind.MethodSignature || - container.kind === SyntaxKind.GetAccessor || - container.kind === SyntaxKind.SetAccessor || - container.kind === SyntaxKind.PropertyDeclaration || - container.kind === SyntaxKind.ClassStaticBlockDeclaration; + if (ts.isClassLike(container.parent) || container.parent.kind === ts.SyntaxKind.ObjectLiteralExpression) { + if (ts.isStatic(container)) { + return container.kind === ts.SyntaxKind.MethodDeclaration || + container.kind === ts.SyntaxKind.MethodSignature || + container.kind === ts.SyntaxKind.GetAccessor || + container.kind === ts.SyntaxKind.SetAccessor || + container.kind === ts.SyntaxKind.PropertyDeclaration || + container.kind === ts.SyntaxKind.ClassStaticBlockDeclaration; } else { - return container.kind === SyntaxKind.MethodDeclaration || - container.kind === SyntaxKind.MethodSignature || - container.kind === SyntaxKind.GetAccessor || - container.kind === SyntaxKind.SetAccessor || - container.kind === SyntaxKind.PropertyDeclaration || - container.kind === SyntaxKind.PropertySignature || - container.kind === SyntaxKind.Constructor; + return container.kind === ts.SyntaxKind.MethodDeclaration || + container.kind === ts.SyntaxKind.MethodSignature || + container.kind === ts.SyntaxKind.GetAccessor || + container.kind === ts.SyntaxKind.SetAccessor || + container.kind === ts.SyntaxKind.PropertyDeclaration || + container.kind === ts.SyntaxKind.PropertySignature || + container.kind === ts.SyntaxKind.Constructor; } } } @@ -26352,26 +25797,26 @@ namespace ts { } } - function getContainingObjectLiteral(func: SignatureDeclaration): ObjectLiteralExpression | undefined { - return (func.kind === SyntaxKind.MethodDeclaration || - func.kind === SyntaxKind.GetAccessor || - func.kind === SyntaxKind.SetAccessor) && func.parent.kind === SyntaxKind.ObjectLiteralExpression ? func.parent : - func.kind === SyntaxKind.FunctionExpression && func.parent.kind === SyntaxKind.PropertyAssignment ? func.parent.parent as ObjectLiteralExpression : + function getContainingObjectLiteral(func: ts.SignatureDeclaration): ts.ObjectLiteralExpression | undefined { + return (func.kind === ts.SyntaxKind.MethodDeclaration || + func.kind === ts.SyntaxKind.GetAccessor || + func.kind === ts.SyntaxKind.SetAccessor) && func.parent.kind === ts.SyntaxKind.ObjectLiteralExpression ? func.parent : + func.kind === ts.SyntaxKind.FunctionExpression && func.parent.kind === ts.SyntaxKind.PropertyAssignment ? func.parent.parent as ts.ObjectLiteralExpression : undefined; } - function getThisTypeArgument(type: Type): Type | undefined { - return getObjectFlags(type) & ObjectFlags.Reference && (type as TypeReference).target === globalThisType ? getTypeArguments(type as TypeReference)[0] : undefined; + function getThisTypeArgument(type: ts.Type): ts.Type | undefined { + return ts.getObjectFlags(type) & ts.ObjectFlags.Reference && (type as ts.TypeReference).target === globalThisType ? getTypeArguments(type as ts.TypeReference)[0] : undefined; } - function getThisTypeFromContextualType(type: Type): Type | undefined { + function getThisTypeFromContextualType(type: ts.Type): ts.Type | undefined { return mapType(type, t => { - return t.flags & TypeFlags.Intersection ? forEach((t as IntersectionType).types, getThisTypeArgument) : getThisTypeArgument(t); + return t.flags & ts.TypeFlags.Intersection ? ts.forEach((t as ts.IntersectionType).types, getThisTypeArgument) : getThisTypeArgument(t); }); } - function getContextualThisParameterType(func: SignatureDeclaration): Type | undefined { - if (func.kind === SyntaxKind.ArrowFunction) { + function getContextualThisParameterType(func: ts.SignatureDeclaration): ts.Type | undefined { + if (func.kind === ts.SyntaxKind.ArrowFunction) { return undefined; } if (isContextSensitiveFunctionOrObjectLiteralMethod(func)) { @@ -26383,7 +25828,7 @@ namespace ts { } } } - const inJs = isInJSFile(func); + const inJs = ts.isInJSFile(func); if (noImplicitThis || inJs) { const containingLiteral = getContainingObjectLiteral(func); if (containingLiteral) { @@ -26398,10 +25843,10 @@ namespace ts { if (thisType) { return instantiateType(thisType, getMapperFromContext(getInferenceContext(containingLiteral))); } - if (literal.parent.kind !== SyntaxKind.PropertyAssignment) { + if (literal.parent.kind !== ts.SyntaxKind.PropertyAssignment) { break; } - literal = literal.parent.parent as ObjectLiteralExpression; + literal = literal.parent.parent as ts.ObjectLiteralExpression; type = getApparentTypeOfContextualType(literal); } // There was no contextual ThisType for the containing object literal, so the contextual type @@ -26411,14 +25856,14 @@ namespace ts { } // In an assignment of the form 'obj.xxx = function(...)' or 'obj[xxx] = function(...)', the // contextual type for 'this' is 'obj'. - const parent = walkUpParenthesizedExpressions(func.parent); - if (parent.kind === SyntaxKind.BinaryExpression && (parent as BinaryExpression).operatorToken.kind === SyntaxKind.EqualsToken) { - const target = (parent as BinaryExpression).left; - if (isAccessExpression(target)) { + const parent = ts.walkUpParenthesizedExpressions(func.parent); + if (parent.kind === ts.SyntaxKind.BinaryExpression && (parent as ts.BinaryExpression).operatorToken.kind === ts.SyntaxKind.EqualsToken) { + const target = (parent as ts.BinaryExpression).left; + if (ts.isAccessExpression(target)) { const { expression } = target; // Don't contextually type `this` as `exports` in `exports.Point = function(x, y) { this.x = x; this.y = y; }` - if (inJs && isIdentifier(expression)) { - const sourceFile = getSourceFileOfNode(parent); + if (inJs && ts.isIdentifier(expression)) { + const sourceFile = ts.getSourceFileOfNode(parent); if (sourceFile.commonJsModuleIndicator && getResolvedSymbol(expression) === sourceFile.symbol) { return undefined; } @@ -26432,12 +25877,12 @@ namespace ts { } // Return contextual type of parameter or undefined if no contextual type is available - function getContextuallyTypedParameterType(parameter: ParameterDeclaration): Type | undefined { + function getContextuallyTypedParameterType(parameter: ts.ParameterDeclaration): ts.Type | undefined { const func = parameter.parent; if (!isContextSensitiveFunctionOrObjectLiteralMethod(func)) { return undefined; } - const iife = getImmediatelyInvokedFunctionExpression(func); + const iife = ts.getImmediatelyInvokedFunctionExpression(func); if (iife && iife.arguments) { const args = getEffectiveCallArguments(iife); const indexOfParameter = func.parameters.indexOf(parameter); @@ -26455,40 +25900,42 @@ namespace ts { } const contextualSignature = getContextualSignature(func); if (contextualSignature) { - const index = func.parameters.indexOf(parameter) - (getThisParameter(func) ? 1 : 0); - return parameter.dotDotDotToken && lastOrUndefined(func.parameters) === parameter ? + const index = func.parameters.indexOf(parameter) - (ts.getThisParameter(func) ? 1 : 0); + return parameter.dotDotDotToken && ts.lastOrUndefined(func.parameters) === parameter ? getRestTypeAtPosition(contextualSignature, index) : tryGetTypeAtPosition(contextualSignature, index); } } - function getContextualTypeForVariableLikeDeclaration(declaration: VariableLikeDeclaration): Type | undefined { - const typeNode = getEffectiveTypeAnnotationNode(declaration); + function getContextualTypeForVariableLikeDeclaration(declaration: ts.VariableLikeDeclaration): ts.Type | undefined { + const typeNode = ts.getEffectiveTypeAnnotationNode(declaration); if (typeNode) { return getTypeFromTypeNode(typeNode); } switch (declaration.kind) { - case SyntaxKind.Parameter: + case ts.SyntaxKind.Parameter: return getContextuallyTypedParameterType(declaration); - case SyntaxKind.BindingElement: + case ts.SyntaxKind.BindingElement: return getContextualTypeForBindingElement(declaration); - case SyntaxKind.PropertyDeclaration: - if (isStatic(declaration)) { + case ts.SyntaxKind.PropertyDeclaration: + if (ts.isStatic(declaration)) { return getContextualTypeForStaticPropertyDeclaration(declaration); } // By default, do nothing and return undefined - only the above cases have context implied by a parent } } - function getContextualTypeForBindingElement(declaration: BindingElement): Type | undefined { + function getContextualTypeForBindingElement(declaration: ts.BindingElement): ts.Type | undefined { const parent = declaration.parent.parent; const name = declaration.propertyName || declaration.name; const parentType = getContextualTypeForVariableLikeDeclaration(parent) || - parent.kind !== SyntaxKind.BindingElement && parent.initializer && checkDeclarationInitializer(parent, declaration.dotDotDotToken ? CheckMode.RestBindingElement : CheckMode.Normal); - if (!parentType || isBindingPattern(name) || isComputedNonLiteralName(name)) return undefined; - if (parent.name.kind === SyntaxKind.ArrayBindingPattern) { - const index = indexOfNode(declaration.parent.elements, declaration); - if (index < 0) return undefined; + parent.kind !== ts.SyntaxKind.BindingElement && parent.initializer && checkDeclarationInitializer(parent, declaration.dotDotDotToken ? CheckMode.RestBindingElement : CheckMode.Normal); + if (!parentType || ts.isBindingPattern(name) || ts.isComputedNonLiteralName(name)) + return undefined; + if (parent.name.kind === ts.SyntaxKind.ArrayBindingPattern) { + const index = ts.indexOfNode(declaration.parent.elements, declaration); + if (index < 0) + return undefined; return getContextualTypeForElementExpression(parentType, index); } const nameType = getLiteralTypeFromPropertyName(name); @@ -26498,9 +25945,10 @@ namespace ts { } } - function getContextualTypeForStaticPropertyDeclaration(declaration: PropertyDeclaration): Type | undefined { - const parentType = isExpression(declaration.parent) && getContextualType(declaration.parent); - if (!parentType) return undefined; + function getContextualTypeForStaticPropertyDeclaration(declaration: ts.PropertyDeclaration): ts.Type | undefined { + const parentType = ts.isExpression(declaration.parent) && getContextualType(declaration.parent); + if (!parentType) + return undefined; return getTypeOfPropertyOfContextualType(parentType, getSymbolOfNode(declaration).escapedName); } @@ -26512,28 +25960,28 @@ namespace ts { // the contextual type of an initializer expression is the type implied by the binding pattern. // Otherwise, in a binding pattern inside a variable or parameter declaration, // the contextual type of an initializer expression is the type annotation of the containing declaration, if present. - function getContextualTypeForInitializerExpression(node: Expression, contextFlags?: ContextFlags): Type | undefined { - const declaration = node.parent as VariableLikeDeclaration; - if (hasInitializer(declaration) && node === declaration.initializer) { + function getContextualTypeForInitializerExpression(node: ts.Expression, contextFlags?: ts.ContextFlags): ts.Type | undefined { + const declaration = node.parent as ts.VariableLikeDeclaration; + if (ts.hasInitializer(declaration) && node === declaration.initializer) { const result = getContextualTypeForVariableLikeDeclaration(declaration); if (result) { return result; } - if (!(contextFlags! & ContextFlags.SkipBindingPatterns) && isBindingPattern(declaration.name)) { // This is less a contextual type and more an implied shape - in some cases, this may be undesirable + if (!(contextFlags! & ts.ContextFlags.SkipBindingPatterns) && ts.isBindingPattern(declaration.name)) { // This is less a contextual type and more an implied shape - in some cases, this may be undesirable return getTypeFromBindingPattern(declaration.name, /*includePatternInType*/ true, /*reportErrors*/ false); } } return undefined; } - function getContextualTypeForReturnExpression(node: Expression): Type | undefined { - const func = getContainingFunction(node); + function getContextualTypeForReturnExpression(node: ts.Expression): ts.Type | undefined { + const func = ts.getContainingFunction(node); if (func) { let contextualReturnType = getContextualReturnType(func); if (contextualReturnType) { - const functionFlags = getFunctionFlags(func); - if (functionFlags & FunctionFlags.Generator) { // Generator or AsyncGenerator function - const use = functionFlags & FunctionFlags.Async ? IterationUse.AsyncGeneratorReturnType : IterationUse.GeneratorReturnType; + const functionFlags = ts.getFunctionFlags(func); + if (functionFlags & ts.FunctionFlags.Generator) { // Generator or AsyncGenerator function + const use = functionFlags & ts.FunctionFlags.Async ? IterationUse.AsyncGeneratorReturnType : IterationUse.GeneratorReturnType; const iterationTypes = getIterationTypesOfIterable(contextualReturnType, use, /*errorNode*/ undefined); if (!iterationTypes) { return undefined; @@ -26542,7 +25990,7 @@ namespace ts { // falls through to unwrap Promise for AsyncGenerators } - if (functionFlags & FunctionFlags.Async) { // Async function or AsyncGenerator function + if (functionFlags & ts.FunctionFlags.Async) { // Async function or AsyncGenerator function // Get the awaited type without the `Awaited` alias const contextualAwaitedType = mapType(contextualReturnType, getAwaitedTypeNoAlias); return contextualAwaitedType && getUnionType([contextualAwaitedType, createPromiseLikeType(contextualAwaitedType)]); @@ -26554,7 +26002,7 @@ namespace ts { return undefined; } - function getContextualTypeForAwaitOperand(node: AwaitExpression, contextFlags?: ContextFlags): Type | undefined { + function getContextualTypeForAwaitOperand(node: ts.AwaitExpression, contextFlags?: ts.ContextFlags): ts.Type | undefined { const contextualType = getContextualType(node, contextFlags); if (contextualType) { const contextualAwaitedType = getAwaitedTypeNoAlias(contextualType); @@ -26563,28 +26011,28 @@ namespace ts { return undefined; } - function getContextualTypeForYieldOperand(node: YieldExpression): Type | undefined { - const func = getContainingFunction(node); + function getContextualTypeForYieldOperand(node: ts.YieldExpression): ts.Type | undefined { + const func = ts.getContainingFunction(node); if (func) { - const functionFlags = getFunctionFlags(func); + const functionFlags = ts.getFunctionFlags(func); const contextualReturnType = getContextualReturnType(func); if (contextualReturnType) { return node.asteriskToken ? contextualReturnType - : getIterationTypeOfGeneratorFunctionReturnType(IterationTypeKind.Yield, contextualReturnType, (functionFlags & FunctionFlags.Async) !== 0); + : getIterationTypeOfGeneratorFunctionReturnType(IterationTypeKind.Yield, contextualReturnType, (functionFlags & ts.FunctionFlags.Async) !== 0); } } return undefined; } - function isInParameterInitializerBeforeContainingFunction(node: Node) { + function isInParameterInitializerBeforeContainingFunction(node: ts.Node) { let inBindingInitializer = false; - while (node.parent && !isFunctionLike(node.parent)) { - if (isParameter(node.parent) && (inBindingInitializer || node.parent.initializer === node)) { + while (node.parent && !ts.isFunctionLike(node.parent)) { + if (ts.isParameter(node.parent) && (inBindingInitializer || node.parent.initializer === node)) { return true; } - if (isBindingElement(node.parent) && node.parent.initializer === node) { + if (ts.isBindingElement(node.parent) && node.parent.initializer === node) { inBindingInitializer = true; } @@ -26594,8 +26042,8 @@ namespace ts { return false; } - function getContextualIterationType(kind: IterationTypeKind, functionDecl: SignatureDeclaration): Type | undefined { - const isAsync = !!(getFunctionFlags(functionDecl) & FunctionFlags.Async); + function getContextualIterationType(kind: IterationTypeKind, functionDecl: ts.SignatureDeclaration): ts.Type | undefined { + const isAsync = !!(ts.getFunctionFlags(functionDecl) & ts.FunctionFlags.Async); const contextualReturnType = getContextualReturnType(functionDecl); if (contextualReturnType) { return getIterationTypeOfGeneratorFunctionReturnType(kind, contextualReturnType, isAsync) @@ -26605,7 +26053,7 @@ namespace ts { return undefined; } - function getContextualReturnType(functionDecl: SignatureDeclaration): Type | undefined { + function getContextualReturnType(functionDecl: ts.SignatureDeclaration): ts.Type | undefined { // If the containing function has a return type annotation, is a constructor, or is a get accessor whose // corresponding set accessor has a type annotation, return statements in the function are contextually typed const returnType = getReturnTypeFromAnnotation(functionDecl); @@ -26614,11 +26062,11 @@ namespace ts { } // Otherwise, if the containing function is contextually typed by a function type with exactly one call signature // and that call signature is non-generic, return statements are contextually typed by the return type of the signature - const signature = getContextualSignatureForFunctionLikeDeclaration(functionDecl as FunctionExpression); + const signature = getContextualSignatureForFunctionLikeDeclaration(functionDecl as ts.FunctionExpression); if (signature && !isResolvingReturnTypeOfSignature(signature)) { return getReturnTypeOfSignature(signature); } - const iife = getImmediatelyInvokedFunctionExpression(functionDecl); + const iife = ts.getImmediatelyInvokedFunctionExpression(functionDecl); if (iife) { return getContextualType(iife); } @@ -26626,14 +26074,14 @@ namespace ts { } // In a typed function call, an argument or substitution expression is contextually typed by the type of the corresponding parameter. - function getContextualTypeForArgument(callTarget: CallLikeExpression, arg: Expression): Type | undefined { + function getContextualTypeForArgument(callTarget: ts.CallLikeExpression, arg: ts.Expression): ts.Type | undefined { const args = getEffectiveCallArguments(callTarget); const argIndex = args.indexOf(arg); // -1 for e.g. the expression of a CallExpression, or the tag of a TaggedTemplateExpression return argIndex === -1 ? undefined : getContextualTypeForArgumentAtIndex(callTarget, argIndex); } - function getContextualTypeForArgumentAtIndex(callTarget: CallLikeExpression, argIndex: number): Type { - if (isImportCall(callTarget)) { + function getContextualTypeForArgumentAtIndex(callTarget: ts.CallLikeExpression, argIndex: number): ts.Type { + if (ts.isImportCall(callTarget)) { return argIndex === 0 ? stringType : argIndex === 1 ? getGlobalImportCallOptionsType(/*reportErrors*/ false) : anyType; @@ -26643,44 +26091,44 @@ namespace ts { // that could cause infinite recursion. Instead, return anySignature. const signature = getNodeLinks(callTarget).resolvedSignature === resolvingSignature ? resolvingSignature : getResolvedSignature(callTarget); - if (isJsxOpeningLikeElement(callTarget) && argIndex === 0) { + if (ts.isJsxOpeningLikeElement(callTarget) && argIndex === 0) { return getEffectiveFirstArgumentForJsxSignature(signature, callTarget); } const restIndex = signature.parameters.length - 1; return signatureHasRestParameter(signature) && argIndex >= restIndex ? - getIndexedAccessType(getTypeOfSymbol(signature.parameters[restIndex]), getNumberLiteralType(argIndex - restIndex), AccessFlags.Contextual) : + getIndexedAccessType(getTypeOfSymbol(signature.parameters[restIndex]), getNumberLiteralType(argIndex - restIndex), ts.AccessFlags.Contextual) : getTypeAtPosition(signature, argIndex); } - function getContextualTypeForSubstitutionExpression(template: TemplateExpression, substitutionExpression: Expression) { - if (template.parent.kind === SyntaxKind.TaggedTemplateExpression) { - return getContextualTypeForArgument(template.parent as TaggedTemplateExpression, substitutionExpression); + function getContextualTypeForSubstitutionExpression(template: ts.TemplateExpression, substitutionExpression: ts.Expression) { + if (template.parent.kind === ts.SyntaxKind.TaggedTemplateExpression) { + return getContextualTypeForArgument(template.parent as ts.TaggedTemplateExpression, substitutionExpression); } return undefined; } - function getContextualTypeForBinaryOperand(node: Expression, contextFlags?: ContextFlags): Type | undefined { - const binaryExpression = node.parent as BinaryExpression; + function getContextualTypeForBinaryOperand(node: ts.Expression, contextFlags?: ts.ContextFlags): ts.Type | undefined { + const binaryExpression = node.parent as ts.BinaryExpression; const { left, operatorToken, right } = binaryExpression; switch (operatorToken.kind) { - case SyntaxKind.EqualsToken: - case SyntaxKind.AmpersandAmpersandEqualsToken: - case SyntaxKind.BarBarEqualsToken: - case SyntaxKind.QuestionQuestionEqualsToken: + case ts.SyntaxKind.EqualsToken: + case ts.SyntaxKind.AmpersandAmpersandEqualsToken: + case ts.SyntaxKind.BarBarEqualsToken: + case ts.SyntaxKind.QuestionQuestionEqualsToken: return node === right ? getContextualTypeForAssignmentDeclaration(binaryExpression) : undefined; - case SyntaxKind.BarBarToken: - case SyntaxKind.QuestionQuestionToken: + case ts.SyntaxKind.BarBarToken: + case ts.SyntaxKind.QuestionQuestionToken: // When an || expression has a contextual type, the operands are contextually typed by that type, except // when that type originates in a binding pattern, the right operand is contextually typed by the type of // the left operand. When an || expression has no contextual type, the right operand is contextually typed // by the type of the left operand, except for the special case of Javascript declarations of the form // `namespace.prop = namespace.prop || {}`. const type = getContextualType(binaryExpression, contextFlags); - return node === right && (type && type.pattern || !type && !isDefaultedExpandoInitializer(binaryExpression)) ? + return node === right && (type && type.pattern || !type && !ts.isDefaultedExpandoInitializer(binaryExpression)) ? getTypeOfExpression(left) : type; - case SyntaxKind.AmpersandAmpersandToken: - case SyntaxKind.CommaToken: + case ts.SyntaxKind.AmpersandAmpersandToken: + case ts.SyntaxKind.CommaToken: return node === right ? getContextualType(binaryExpression, contextFlags) : undefined; default: return undefined; @@ -26691,20 +26139,20 @@ namespace ts { * Try to find a resolved symbol for an expression without also resolving its type, as * getSymbolAtLocation would (as that could be reentrant into contextual typing) */ - function getSymbolForExpression(e: Expression) { + function getSymbolForExpression(e: ts.Expression) { if (e.symbol) { return e.symbol; } - if (isIdentifier(e)) { + if (ts.isIdentifier(e)) { return getResolvedSymbol(e); } - if (isPropertyAccessExpression(e)) { + if (ts.isPropertyAccessExpression(e)) { const lhsType = getTypeOfExpression(e.expression); - return isPrivateIdentifier(e.name) ? tryGetPrivateIdentifierPropertyOfType(lhsType, e.name) : getPropertyOfType(lhsType, e.name.escapedText); + return ts.isPrivateIdentifier(e.name) ? tryGetPrivateIdentifierPropertyOfType(lhsType, e.name) : getPropertyOfType(lhsType, e.name.escapedText); } return undefined; - function tryGetPrivateIdentifierPropertyOfType(type: Type, id: PrivateIdentifier) { + function tryGetPrivateIdentifierPropertyOfType(type: ts.Type, id: ts.PrivateIdentifier) { const lexicallyScopedSymbol = lookupSymbolForPrivateIdentifierDeclaration(id.escapedText, id); return lexicallyScopedSymbol && getPrivateIdentifierPropertyOfType(type, lexicallyScopedSymbol); } @@ -26712,25 +26160,25 @@ namespace ts { // In an assignment expression, the right operand is contextually typed by the type of the left operand. // Don't do this for assignment declarations unless there is a type tag on the assignment, to avoid circularity from checking the right operand. - function getContextualTypeForAssignmentDeclaration(binaryExpression: BinaryExpression): Type | undefined { - const kind = getAssignmentDeclarationKind(binaryExpression); + function getContextualTypeForAssignmentDeclaration(binaryExpression: ts.BinaryExpression): ts.Type | undefined { + const kind = ts.getAssignmentDeclarationKind(binaryExpression); switch (kind) { - case AssignmentDeclarationKind.None: - case AssignmentDeclarationKind.ThisProperty: + case ts.AssignmentDeclarationKind.None: + case ts.AssignmentDeclarationKind.ThisProperty: const lhsSymbol = getSymbolForExpression(binaryExpression.left); const decl = lhsSymbol && lhsSymbol.valueDeclaration; // Unannotated, uninitialized property declarations have a type implied by their usage in the constructor. // We avoid calling back into `getTypeOfExpression` and reentering contextual typing to avoid a bogus circularity error in that case. - if (decl && (isPropertyDeclaration(decl) || isPropertySignature(decl))) { - const overallAnnotation = getEffectiveTypeAnnotationNode(decl); + if (decl && (ts.isPropertyDeclaration(decl) || ts.isPropertySignature(decl))) { + const overallAnnotation = ts.getEffectiveTypeAnnotationNode(decl); return (overallAnnotation && instantiateType(getTypeFromTypeNode(overallAnnotation), getSymbolLinks(lhsSymbol).mapper)) || (decl.initializer && getTypeOfExpression(binaryExpression.left)); } - if (kind === AssignmentDeclarationKind.None) { + if (kind === ts.AssignmentDeclarationKind.None) { return getTypeOfExpression(binaryExpression.left); } return getContextualTypeForThisPropertyAssignment(binaryExpression); - case AssignmentDeclarationKind.Property: + case ts.AssignmentDeclarationKind.Property: if (isPossiblyAliasedThisProperty(binaryExpression, kind)) { return getContextualTypeForThisPropertyAssignment(binaryExpression); } @@ -26744,18 +26192,18 @@ namespace ts { if (!decl) { return undefined; } - const lhs = cast(binaryExpression.left, isAccessExpression); - const overallAnnotation = getEffectiveTypeAnnotationNode(decl); + const lhs = ts.cast(binaryExpression.left, ts.isAccessExpression); + const overallAnnotation = ts.getEffectiveTypeAnnotationNode(decl); if (overallAnnotation) { return getTypeFromTypeNode(overallAnnotation); } - else if (isIdentifier(lhs.expression)) { + else if (ts.isIdentifier(lhs.expression)) { const id = lhs.expression; - const parentSymbol = resolveName(id, id.escapedText, SymbolFlags.Value, undefined, id.escapedText, /*isUse*/ true); + const parentSymbol = resolveName(id, id.escapedText, ts.SymbolFlags.Value, undefined, id.escapedText, /*isUse*/ true); if (parentSymbol) { - const annotated = parentSymbol.valueDeclaration && getEffectiveTypeAnnotationNode(parentSymbol.valueDeclaration); + const annotated = parentSymbol.valueDeclaration && ts.getEffectiveTypeAnnotationNode(parentSymbol.valueDeclaration); if (annotated) { - const nameStr = getElementOrPropertyAccessName(lhs); + const nameStr = ts.getElementOrPropertyAccessName(lhs); if (nameStr !== undefined) { return getTypeOfPropertyOfContextualType(getTypeFromTypeNode(annotated), nameStr); } @@ -26763,42 +26211,43 @@ namespace ts { return undefined; } } - return isInJSFile(decl) ? undefined : getTypeOfExpression(binaryExpression.left); + return ts.isInJSFile(decl) ? undefined : getTypeOfExpression(binaryExpression.left); } - case AssignmentDeclarationKind.ExportsProperty: - case AssignmentDeclarationKind.Prototype: - case AssignmentDeclarationKind.PrototypeProperty: + case ts.AssignmentDeclarationKind.ExportsProperty: + case ts.AssignmentDeclarationKind.Prototype: + case ts.AssignmentDeclarationKind.PrototypeProperty: let valueDeclaration = binaryExpression.left.symbol?.valueDeclaration; // falls through - case AssignmentDeclarationKind.ModuleExports: + case ts.AssignmentDeclarationKind.ModuleExports: valueDeclaration ||= binaryExpression.symbol?.valueDeclaration; - const annotated = valueDeclaration && getEffectiveTypeAnnotationNode(valueDeclaration); + const annotated = valueDeclaration && ts.getEffectiveTypeAnnotationNode(valueDeclaration); return annotated ? getTypeFromTypeNode(annotated) : undefined; - case AssignmentDeclarationKind.ObjectDefinePropertyValue: - case AssignmentDeclarationKind.ObjectDefinePropertyExports: - case AssignmentDeclarationKind.ObjectDefinePrototypeProperty: - return Debug.fail("Does not apply"); + case ts.AssignmentDeclarationKind.ObjectDefinePropertyValue: + case ts.AssignmentDeclarationKind.ObjectDefinePropertyExports: + case ts.AssignmentDeclarationKind.ObjectDefinePrototypeProperty: + return ts.Debug.fail("Does not apply"); default: - return Debug.assertNever(kind); + return ts.Debug.assertNever(kind); } } - function isPossiblyAliasedThisProperty(declaration: BinaryExpression, kind = getAssignmentDeclarationKind(declaration)) { - if (kind === AssignmentDeclarationKind.ThisProperty) { + function isPossiblyAliasedThisProperty(declaration: ts.BinaryExpression, kind = ts.getAssignmentDeclarationKind(declaration)) { + if (kind === ts.AssignmentDeclarationKind.ThisProperty) { return true; } - if (!isInJSFile(declaration) || kind !== AssignmentDeclarationKind.Property || !isIdentifier((declaration.left as AccessExpression).expression)) { + if (!ts.isInJSFile(declaration) || kind !== ts.AssignmentDeclarationKind.Property || !ts.isIdentifier((declaration.left as ts.AccessExpression).expression)) { return false; } - const name = ((declaration.left as AccessExpression).expression as Identifier).escapedText; - const symbol = resolveName(declaration.left, name, SymbolFlags.Value, undefined, undefined, /*isUse*/ true, /*excludeGlobals*/ true); - return isThisInitializedDeclaration(symbol?.valueDeclaration); + const name = ((declaration.left as ts.AccessExpression).expression as ts.Identifier).escapedText; + const symbol = resolveName(declaration.left, name, ts.SymbolFlags.Value, undefined, undefined, /*isUse*/ true, /*excludeGlobals*/ true); + return ts.isThisInitializedDeclaration(symbol?.valueDeclaration); } - function getContextualTypeForThisPropertyAssignment(binaryExpression: BinaryExpression): Type | undefined { - if (!binaryExpression.symbol) return getTypeOfExpression(binaryExpression.left); + function getContextualTypeForThisPropertyAssignment(binaryExpression: ts.BinaryExpression): ts.Type | undefined { + if (!binaryExpression.symbol) + return getTypeOfExpression(binaryExpression.left); if (binaryExpression.symbol.valueDeclaration) { - const annotated = getEffectiveTypeAnnotationNode(binaryExpression.symbol.valueDeclaration); + const annotated = ts.getEffectiveTypeAnnotationNode(binaryExpression.symbol.valueDeclaration); if (annotated) { const type = getTypeFromTypeNode(annotated); if (type) { @@ -26806,29 +26255,29 @@ namespace ts { } } } - const thisAccess = cast(binaryExpression.left, isAccessExpression); - if (!isObjectLiteralMethod(getThisContainer(thisAccess.expression, /*includeArrowFunctions*/ false))) { + const thisAccess = ts.cast(binaryExpression.left, ts.isAccessExpression); + if (!ts.isObjectLiteralMethod(ts.getThisContainer(thisAccess.expression, /*includeArrowFunctions*/ false))) { return undefined; } const thisType = checkThisExpression(thisAccess.expression); - const nameStr = getElementOrPropertyAccessName(thisAccess); + const nameStr = ts.getElementOrPropertyAccessName(thisAccess); return nameStr !== undefined && getTypeOfPropertyOfContextualType(thisType, nameStr) || undefined; } - function isCircularMappedProperty(symbol: Symbol) { - return !!(getCheckFlags(symbol) & CheckFlags.Mapped && !(symbol as MappedSymbol).type && findResolutionCycleStartIndex(symbol, TypeSystemPropertyName.Type) >= 0); + function isCircularMappedProperty(symbol: ts.Symbol) { + return !!(ts.getCheckFlags(symbol) & ts.CheckFlags.Mapped && !(symbol as ts.MappedSymbol).type && findResolutionCycleStartIndex(symbol, TypeSystemPropertyName.Type) >= 0); } - function getTypeOfPropertyOfContextualType(type: Type, name: __String, nameType?: Type) { - return mapType(type, (t): Type | undefined => { - if (t.flags & TypeFlags.Intersection) { - const intersection = t as IntersectionType; - let newTypes = mapDefined(intersection.types, getTypeOfConcretePropertyOfContextualType); + function getTypeOfPropertyOfContextualType(type: ts.Type, name: ts.__String, nameType?: ts.Type) { + return mapType(type, (t): ts.Type | undefined => { + if (t.flags & ts.TypeFlags.Intersection) { + const intersection = t as ts.IntersectionType; + let newTypes = ts.mapDefined(intersection.types, getTypeOfConcretePropertyOfContextualType); if (newTypes.length > 0) { return getIntersectionType(newTypes); } - newTypes = mapDefined(intersection.types, getTypeOfApplicableIndexInfoOfContextualType); + newTypes = ts.mapDefined(intersection.types, getTypeOfApplicableIndexInfoOfContextualType); if (newTypes.length > 0) { return getIntersectionType(newTypes); } @@ -26841,53 +26290,53 @@ namespace ts { return getTypeOfApplicableIndexInfoOfContextualType(t); }, /*noReductions*/ true); - function getTypeOfConcretePropertyOfContextualType(t: Type) { + function getTypeOfConcretePropertyOfContextualType(t: ts.Type) { if (isGenericMappedType(t) && !t.declaration.nameType) { const constraint = getConstraintTypeFromMappedType(t); const constraintOfConstraint = getBaseConstraintOfType(constraint) || constraint; - const propertyNameType = nameType || getStringLiteralType(unescapeLeadingUnderscores(name)); + const propertyNameType = nameType || getStringLiteralType(ts.unescapeLeadingUnderscores(name)); if (isTypeAssignableTo(propertyNameType, constraintOfConstraint)) { return substituteIndexedMappedType(t, propertyNameType); } return undefined; } - if (t.flags & TypeFlags.StructuredType) { + if (t.flags & ts.TypeFlags.StructuredType) { const prop = getPropertyOfType(t, name); if (prop) { return isCircularMappedProperty(prop) ? undefined : getTypeOfSymbol(prop); } if (isTupleType(t)) { const restType = getRestTypeOfTupleType(t); - if (restType && isNumericLiteralName(name) && +name >= 0) { + if (restType && ts.isNumericLiteralName(name) && +name >= 0) { return restType; } } } return undefined; } - function getTypeOfApplicableIndexInfoOfContextualType(t: Type) { - if (!(t.flags & TypeFlags.StructuredType)) { + function getTypeOfApplicableIndexInfoOfContextualType(t: ts.Type) { + if (!(t.flags & ts.TypeFlags.StructuredType)) { return undefined; } - return findApplicableIndexInfo(getIndexInfosOfStructuredType(t), nameType || getStringLiteralType(unescapeLeadingUnderscores(name)))?.type; + return findApplicableIndexInfo(getIndexInfosOfStructuredType(t), nameType || getStringLiteralType(ts.unescapeLeadingUnderscores(name)))?.type; } } // In an object literal contextually typed by a type T, the contextual type of a property assignment is the type of // the matching property in T, if one exists. Otherwise, it is the type of the numeric index signature in T, if one // exists. Otherwise, it is the type of the string index signature in T, if one exists. - function getContextualTypeForObjectLiteralMethod(node: MethodDeclaration, contextFlags?: ContextFlags): Type | undefined { - Debug.assert(isObjectLiteralMethod(node)); - if (node.flags & NodeFlags.InWithStatement) { + function getContextualTypeForObjectLiteralMethod(node: ts.MethodDeclaration, contextFlags?: ts.ContextFlags): ts.Type | undefined { + ts.Debug.assert(ts.isObjectLiteralMethod(node)); + if (node.flags & ts.NodeFlags.InWithStatement) { // We cannot answer semantic questions within a with block, do not proceed any further return undefined; } return getContextualTypeForObjectLiteralElement(node, contextFlags); } - function getContextualTypeForObjectLiteralElement(element: ObjectLiteralElementLike, contextFlags?: ContextFlags) { - const objectLiteral = element.parent as ObjectLiteralExpression; - const propertyAssignmentType = isPropertyAssignment(element) && getContextualTypeForVariableLikeDeclaration(element); + function getContextualTypeForObjectLiteralElement(element: ts.ObjectLiteralElementLike, contextFlags?: ts.ContextFlags) { + const objectLiteral = element.parent as ts.ObjectLiteralExpression; + const propertyAssignmentType = ts.isPropertyAssignment(element) && getContextualTypeForVariableLikeDeclaration(element); if (propertyAssignmentType) { return propertyAssignmentType; } @@ -26913,29 +26362,26 @@ namespace ts { // the type of the property with the numeric name N in T, if one exists. Otherwise, if T has a numeric index signature, // it is the type of the numeric index signature in T. Otherwise, in ES6 and higher, the contextual type is the iterated // type of T. - function getContextualTypeForElementExpression(arrayContextualType: Type | undefined, index: number): Type | undefined { - return arrayContextualType && ( - getTypeOfPropertyOfContextualType(arrayContextualType, "" + index as __String) - || mapType( - arrayContextualType, - t => getIteratedTypeOrElementType(IterationUse.Element, t, undefinedType, /*errorNode*/ undefined, /*checkAssignability*/ false), + function getContextualTypeForElementExpression(arrayContextualType: ts.Type | undefined, index: number): ts.Type | undefined { + return arrayContextualType && (getTypeOfPropertyOfContextualType(arrayContextualType, "" + index as ts.__String) + || mapType(arrayContextualType, t => getIteratedTypeOrElementType(IterationUse.Element, t, undefinedType, /*errorNode*/ undefined, /*checkAssignability*/ false), /*noReductions*/ true)); } // In a contextually typed conditional expression, the true/false expressions are contextually typed by the same type. - function getContextualTypeForConditionalOperand(node: Expression, contextFlags?: ContextFlags): Type | undefined { - const conditional = node.parent as ConditionalExpression; + function getContextualTypeForConditionalOperand(node: ts.Expression, contextFlags?: ts.ContextFlags): ts.Type | undefined { + const conditional = node.parent as ts.ConditionalExpression; return node === conditional.whenTrue || node === conditional.whenFalse ? getContextualType(conditional, contextFlags) : undefined; } - function getContextualTypeForChildJsxExpression(node: JsxElement, child: JsxChild) { + function getContextualTypeForChildJsxExpression(node: ts.JsxElement, child: ts.JsxChild) { const attributesType = getApparentTypeOfContextualType(node.openingElement.tagName); // JSX expression is in children of JSX Element, we will look for an "children" attribute (we get the name from JSX.ElementAttributesProperty) const jsxChildrenPropertyName = getJsxElementChildrenPropertyName(getJsxNamespaceAt(node)); if (!(attributesType && !isTypeAny(attributesType) && jsxChildrenPropertyName && jsxChildrenPropertyName !== "")) { return undefined; } - const realChildren = getSemanticJsxChildren(node.children); + const realChildren = ts.getSemanticJsxChildren(node.children); const childIndex = realChildren.indexOf(child); const childFieldType = getTypeOfPropertyOfContextualType(attributesType, jsxChildrenPropertyName); return childFieldType && (realChildren.length === 1 ? childFieldType : mapType(childFieldType, t => { @@ -26948,20 +26394,20 @@ namespace ts { }, /*noReductions*/ true)); } - function getContextualTypeForJsxExpression(node: JsxExpression): Type | undefined { + function getContextualTypeForJsxExpression(node: ts.JsxExpression): ts.Type | undefined { const exprParent = node.parent; - return isJsxAttributeLike(exprParent) + return ts.isJsxAttributeLike(exprParent) ? getContextualType(node) - : isJsxElement(exprParent) + : ts.isJsxElement(exprParent) ? getContextualTypeForChildJsxExpression(exprParent, node) : undefined; } - function getContextualTypeForJsxAttribute(attribute: JsxAttribute | JsxSpreadAttribute): Type | undefined { + function getContextualTypeForJsxAttribute(attribute: ts.JsxAttribute | ts.JsxSpreadAttribute): ts.Type | undefined { // When we trying to resolve JsxOpeningLikeElement as a stateless function element, we will already give its attributes a contextual type // which is a type of the parameter of the signature we are trying out. // If there is no contextual type (e.g. we are trying to resolve stateful component), get attributes type from resolving element's tagName - if (isJsxAttribute(attribute)) { + if (ts.isJsxAttribute(attribute)) { const attributesType = getApparentTypeOfContextualType(attribute.parent); if (!attributesType || isTypeAny(attributesType)) { return undefined; @@ -26976,87 +26422,71 @@ namespace ts { // Return true if the given expression is possibly a discriminant value. We limit the kinds of // expressions we check to those that don't depend on their contextual type in order not to cause // recursive (and possibly infinite) invocations of getContextualType. - function isPossiblyDiscriminantValue(node: Expression): boolean { + function isPossiblyDiscriminantValue(node: ts.Expression): boolean { switch (node.kind) { - case SyntaxKind.StringLiteral: - case SyntaxKind.NumericLiteral: - case SyntaxKind.BigIntLiteral: - case SyntaxKind.NoSubstitutionTemplateLiteral: - case SyntaxKind.TrueKeyword: - case SyntaxKind.FalseKeyword: - case SyntaxKind.NullKeyword: - case SyntaxKind.Identifier: - case SyntaxKind.UndefinedKeyword: + case ts.SyntaxKind.StringLiteral: + case ts.SyntaxKind.NumericLiteral: + case ts.SyntaxKind.BigIntLiteral: + case ts.SyntaxKind.NoSubstitutionTemplateLiteral: + case ts.SyntaxKind.TrueKeyword: + case ts.SyntaxKind.FalseKeyword: + case ts.SyntaxKind.NullKeyword: + case ts.SyntaxKind.Identifier: + case ts.SyntaxKind.UndefinedKeyword: return true; - case SyntaxKind.PropertyAccessExpression: - case SyntaxKind.ParenthesizedExpression: - return isPossiblyDiscriminantValue((node as PropertyAccessExpression | ParenthesizedExpression).expression); - case SyntaxKind.JsxExpression: - return !(node as JsxExpression).expression || isPossiblyDiscriminantValue((node as JsxExpression).expression!); + case ts.SyntaxKind.PropertyAccessExpression: + case ts.SyntaxKind.ParenthesizedExpression: + return isPossiblyDiscriminantValue((node as ts.PropertyAccessExpression | ts.ParenthesizedExpression).expression); + case ts.SyntaxKind.JsxExpression: + return !(node as ts.JsxExpression).expression || isPossiblyDiscriminantValue((node as ts.JsxExpression).expression!); } return false; } - - function discriminateContextualTypeByObjectMembers(node: ObjectLiteralExpression, contextualType: UnionType) { - return getMatchingUnionConstituentForObjectLiteral(contextualType, node) || discriminateTypeByDiscriminableItems(contextualType, - concatenate( - map( - filter(node.properties, p => !!p.symbol && p.kind === SyntaxKind.PropertyAssignment && isPossiblyDiscriminantValue(p.initializer) && isDiscriminantProperty(contextualType, p.symbol.escapedName)), - prop => ([() => getContextFreeTypeOfExpression((prop as PropertyAssignment).initializer), prop.symbol.escapedName] as [() => Type, __String]) - ), - map( - filter(getPropertiesOfType(contextualType), s => !!(s.flags & SymbolFlags.Optional) && !!node?.symbol?.members && !node.symbol.members.has(s.escapedName) && isDiscriminantProperty(contextualType, s.escapedName)), - s => [() => undefinedType, s.escapedName] as [() => Type, __String] - ) - ), - isTypeAssignableTo, - contextualType - ); - } - - function discriminateContextualTypeByJSXAttributes(node: JsxAttributes, contextualType: UnionType) { - return discriminateTypeByDiscriminableItems(contextualType, - concatenate( - map( - filter(node.properties, p => !!p.symbol && p.kind === SyntaxKind.JsxAttribute && isDiscriminantProperty(contextualType, p.symbol.escapedName) && (!p.initializer || isPossiblyDiscriminantValue(p.initializer))), - prop => ([!(prop as JsxAttribute).initializer ? (() => trueType) : (() => getContextFreeTypeOfExpression((prop as JsxAttribute).initializer!)), prop.symbol.escapedName] as [() => Type, __String]) - ), - map( - filter(getPropertiesOfType(contextualType), s => !!(s.flags & SymbolFlags.Optional) && !!node?.symbol?.members && !node.symbol.members.has(s.escapedName) && isDiscriminantProperty(contextualType, s.escapedName)), - s => [() => undefinedType, s.escapedName] as [() => Type, __String] - ) - ), - isTypeAssignableTo, - contextualType - ); + function discriminateContextualTypeByObjectMembers(node: ts.ObjectLiteralExpression, contextualType: ts.UnionType) { + return getMatchingUnionConstituentForObjectLiteral(contextualType, node) || discriminateTypeByDiscriminableItems(contextualType, ts.concatenate(ts.map(ts.filter(node.properties, p => !!p.symbol && p.kind === ts.SyntaxKind.PropertyAssignment && isPossiblyDiscriminantValue(p.initializer) && isDiscriminantProperty(contextualType, p.symbol.escapedName)), prop => ([() => getContextFreeTypeOfExpression((prop as ts.PropertyAssignment).initializer), prop.symbol.escapedName] as [ + () => ts.Type, + ts.__String + ])), ts.map(ts.filter(getPropertiesOfType(contextualType), s => !!(s.flags & ts.SymbolFlags.Optional) && !!node?.symbol?.members && !node.symbol.members.has(s.escapedName) && isDiscriminantProperty(contextualType, s.escapedName)), s => [() => undefinedType, s.escapedName] as [ + () => ts.Type, + ts.__String + ])), isTypeAssignableTo, contextualType); + } + function discriminateContextualTypeByJSXAttributes(node: ts.JsxAttributes, contextualType: ts.UnionType) { + return discriminateTypeByDiscriminableItems(contextualType, ts.concatenate(ts.map(ts.filter(node.properties, p => !!p.symbol && p.kind === ts.SyntaxKind.JsxAttribute && isDiscriminantProperty(contextualType, p.symbol.escapedName) && (!p.initializer || isPossiblyDiscriminantValue(p.initializer))), prop => ([!(prop as ts.JsxAttribute).initializer ? (() => trueType) : (() => getContextFreeTypeOfExpression((prop as ts.JsxAttribute).initializer!)), prop.symbol.escapedName] as [ + () => ts.Type, + ts.__String + ])), ts.map(ts.filter(getPropertiesOfType(contextualType), s => !!(s.flags & ts.SymbolFlags.Optional) && !!node?.symbol?.members && !node.symbol.members.has(s.escapedName) && isDiscriminantProperty(contextualType, s.escapedName)), s => [() => undefinedType, s.escapedName] as [ + () => ts.Type, + ts.__String + ])), isTypeAssignableTo, contextualType); } // Return the contextual type for a given expression node. During overload resolution, a contextual type may temporarily // be "pushed" onto a node using the contextualType property. - function getApparentTypeOfContextualType(node: Expression | MethodDeclaration, contextFlags?: ContextFlags): Type | undefined { - const contextualType = isObjectLiteralMethod(node) ? + function getApparentTypeOfContextualType(node: ts.Expression | ts.MethodDeclaration, contextFlags?: ts.ContextFlags): ts.Type | undefined { + const contextualType = ts.isObjectLiteralMethod(node) ? getContextualTypeForObjectLiteralMethod(node, contextFlags) : getContextualType(node, contextFlags); const instantiatedType = instantiateContextualType(contextualType, node, contextFlags); - if (instantiatedType && !(contextFlags && contextFlags & ContextFlags.NoConstraints && instantiatedType.flags & TypeFlags.TypeVariable)) { + if (instantiatedType && !(contextFlags && contextFlags & ts.ContextFlags.NoConstraints && instantiatedType.flags & ts.TypeFlags.TypeVariable)) { const apparentType = mapType(instantiatedType, getApparentType, /*noReductions*/ true); - return apparentType.flags & TypeFlags.Union && isObjectLiteralExpression(node) ? discriminateContextualTypeByObjectMembers(node, apparentType as UnionType) : - apparentType.flags & TypeFlags.Union && isJsxAttributes(node) ? discriminateContextualTypeByJSXAttributes(node, apparentType as UnionType) : + return apparentType.flags & ts.TypeFlags.Union && ts.isObjectLiteralExpression(node) ? discriminateContextualTypeByObjectMembers(node, apparentType as ts.UnionType) : + apparentType.flags & ts.TypeFlags.Union && ts.isJsxAttributes(node) ? discriminateContextualTypeByJSXAttributes(node, apparentType as ts.UnionType) : apparentType; } } // If the given contextual type contains instantiable types and if a mapper representing // return type inferences is available, instantiate those types using that mapper. - function instantiateContextualType(contextualType: Type | undefined, node: Node, contextFlags?: ContextFlags): Type | undefined { - if (contextualType && maybeTypeOfKind(contextualType, TypeFlags.Instantiable)) { + function instantiateContextualType(contextualType: ts.Type | undefined, node: ts.Node, contextFlags?: ts.ContextFlags): ts.Type | undefined { + if (contextualType && maybeTypeOfKind(contextualType, ts.TypeFlags.Instantiable)) { const inferenceContext = getInferenceContext(node); // If no inferences have been made, nothing is gained from instantiating as type parameters // would just be replaced with their defaults similar to the apparent type. - if (inferenceContext && some(inferenceContext.inferences, hasInferenceCandidates)) { + if (inferenceContext && ts.some(inferenceContext.inferences, hasInferenceCandidates)) { // For contextual signatures we incorporate all inferences made so far, e.g. from return // types as well as arguments to the left in a function call. - if (contextFlags && contextFlags & ContextFlags.Signature) { + if (contextFlags && contextFlags & ts.ContextFlags.Signature) { return instantiateInstantiableTypes(contextualType, inferenceContext.nonFixingMapper); } // For other purposes (e.g. determining whether to produce literal types) we only @@ -27065,7 +26495,7 @@ namespace ts { // literals actually end up widening to 'boolean' (see #48363). if (inferenceContext.returnMapper) { const type = instantiateInstantiableTypes(contextualType, inferenceContext.returnMapper); - return type.flags & TypeFlags.Union && containsType((type as UnionType).types, regularFalseType) && containsType((type as UnionType).types, regularTrueType) ? + return type.flags & ts.TypeFlags.Union && containsType((type as ts.UnionType).types, regularFalseType) && containsType((type as ts.UnionType).types, regularTrueType) ? filterType(type, t => t !== regularFalseType && t !== regularTrueType) : type; } @@ -27077,15 +26507,15 @@ namespace ts { // This function is similar to instantiateType, except that (a) it only instantiates types that // are classified as instantiable (i.e. it doesn't instantiate object types), and (b) it performs // no reductions on instantiated union types. - function instantiateInstantiableTypes(type: Type, mapper: TypeMapper): Type { - if (type.flags & TypeFlags.Instantiable) { + function instantiateInstantiableTypes(type: ts.Type, mapper: ts.TypeMapper): ts.Type { + if (type.flags & ts.TypeFlags.Instantiable) { return instantiateType(type, mapper); } - if (type.flags & TypeFlags.Union) { - return getUnionType(map((type as UnionType).types, t => instantiateInstantiableTypes(t, mapper)), UnionReduction.None); + if (type.flags & ts.TypeFlags.Union) { + return getUnionType(ts.map((type as ts.UnionType).types, t => instantiateInstantiableTypes(t, mapper)), ts.UnionReduction.None); } - if (type.flags & TypeFlags.Intersection) { - return getIntersectionType(map((type as IntersectionType).types, t => instantiateInstantiableTypes(t, mapper))); + if (type.flags & ts.TypeFlags.Intersection) { + return getIntersectionType(ts.map((type as ts.IntersectionType).types, t => instantiateInstantiableTypes(t, mapper))); } return type; } @@ -27107,8 +26537,8 @@ namespace ts { * @param node the expression whose contextual type will be returned. * @returns the contextual type of an expression. */ - function getContextualType(node: Expression, contextFlags?: ContextFlags): Type | undefined { - if (node.flags & NodeFlags.InWithStatement) { + function getContextualType(node: ts.Expression, contextFlags?: ts.ContextFlags): ts.Type | undefined { + if (node.flags & ts.NodeFlags.InWithStatement) { // We cannot answer semantic questions within a with block, do not proceed any further return undefined; } @@ -27117,76 +26547,76 @@ namespace ts { } const { parent } = node; switch (parent.kind) { - case SyntaxKind.VariableDeclaration: - case SyntaxKind.Parameter: - case SyntaxKind.PropertyDeclaration: - case SyntaxKind.PropertySignature: - case SyntaxKind.BindingElement: + case ts.SyntaxKind.VariableDeclaration: + case ts.SyntaxKind.Parameter: + case ts.SyntaxKind.PropertyDeclaration: + case ts.SyntaxKind.PropertySignature: + case ts.SyntaxKind.BindingElement: return getContextualTypeForInitializerExpression(node, contextFlags); - case SyntaxKind.ArrowFunction: - case SyntaxKind.ReturnStatement: + case ts.SyntaxKind.ArrowFunction: + case ts.SyntaxKind.ReturnStatement: return getContextualTypeForReturnExpression(node); - case SyntaxKind.YieldExpression: - return getContextualTypeForYieldOperand(parent as YieldExpression); - case SyntaxKind.AwaitExpression: - return getContextualTypeForAwaitOperand(parent as AwaitExpression, contextFlags); - case SyntaxKind.CallExpression: - case SyntaxKind.NewExpression: - return getContextualTypeForArgument(parent as CallExpression | NewExpression, node); - case SyntaxKind.TypeAssertionExpression: - case SyntaxKind.AsExpression: - return isConstTypeReference((parent as AssertionExpression).type) ? tryFindWhenConstTypeReference(parent as AssertionExpression) : getTypeFromTypeNode((parent as AssertionExpression).type); - case SyntaxKind.BinaryExpression: + case ts.SyntaxKind.YieldExpression: + return getContextualTypeForYieldOperand(parent as ts.YieldExpression); + case ts.SyntaxKind.AwaitExpression: + return getContextualTypeForAwaitOperand(parent as ts.AwaitExpression, contextFlags); + case ts.SyntaxKind.CallExpression: + case ts.SyntaxKind.NewExpression: + return getContextualTypeForArgument(parent as ts.CallExpression | ts.NewExpression, node); + case ts.SyntaxKind.TypeAssertionExpression: + case ts.SyntaxKind.AsExpression: + return ts.isConstTypeReference((parent as ts.AssertionExpression).type) ? tryFindWhenConstTypeReference(parent as ts.AssertionExpression) : getTypeFromTypeNode((parent as ts.AssertionExpression).type); + case ts.SyntaxKind.BinaryExpression: return getContextualTypeForBinaryOperand(node, contextFlags); - case SyntaxKind.PropertyAssignment: - case SyntaxKind.ShorthandPropertyAssignment: - return getContextualTypeForObjectLiteralElement(parent as PropertyAssignment | ShorthandPropertyAssignment, contextFlags); - case SyntaxKind.SpreadAssignment: - return getContextualType(parent.parent as ObjectLiteralExpression, contextFlags); - case SyntaxKind.ArrayLiteralExpression: { - const arrayLiteral = parent as ArrayLiteralExpression; + case ts.SyntaxKind.PropertyAssignment: + case ts.SyntaxKind.ShorthandPropertyAssignment: + return getContextualTypeForObjectLiteralElement(parent as ts.PropertyAssignment | ts.ShorthandPropertyAssignment, contextFlags); + case ts.SyntaxKind.SpreadAssignment: + return getContextualType(parent.parent as ts.ObjectLiteralExpression, contextFlags); + case ts.SyntaxKind.ArrayLiteralExpression: { + const arrayLiteral = parent as ts.ArrayLiteralExpression; const type = getApparentTypeOfContextualType(arrayLiteral, contextFlags); - return getContextualTypeForElementExpression(type, indexOfNode(arrayLiteral.elements, node)); + return getContextualTypeForElementExpression(type, ts.indexOfNode(arrayLiteral.elements, node)); } - case SyntaxKind.ConditionalExpression: + case ts.SyntaxKind.ConditionalExpression: return getContextualTypeForConditionalOperand(node, contextFlags); - case SyntaxKind.TemplateSpan: - Debug.assert(parent.parent.kind === SyntaxKind.TemplateExpression); - return getContextualTypeForSubstitutionExpression(parent.parent as TemplateExpression, node); - case SyntaxKind.ParenthesizedExpression: { + case ts.SyntaxKind.TemplateSpan: + ts.Debug.assert(parent.parent.kind === ts.SyntaxKind.TemplateExpression); + return getContextualTypeForSubstitutionExpression(parent.parent as ts.TemplateExpression, node); + case ts.SyntaxKind.ParenthesizedExpression: { // Like in `checkParenthesizedExpression`, an `/** @type {xyz} */` comment before a parenthesized expression acts as a type cast. - const tag = isInJSFile(parent) ? getJSDocTypeTag(parent) : undefined; - return !tag ? getContextualType(parent as ParenthesizedExpression, contextFlags) : - isJSDocTypeTag(tag) && isConstTypeReference(tag.typeExpression.type) ? tryFindWhenConstTypeReference(parent as ParenthesizedExpression) : + const tag = ts.isInJSFile(parent) ? ts.getJSDocTypeTag(parent) : undefined; + return !tag ? getContextualType(parent as ts.ParenthesizedExpression, contextFlags) : + ts.isJSDocTypeTag(tag) && ts.isConstTypeReference(tag.typeExpression.type) ? tryFindWhenConstTypeReference(parent as ts.ParenthesizedExpression) : getTypeFromTypeNode(tag.typeExpression.type); } - case SyntaxKind.NonNullExpression: - return getContextualType(parent as NonNullExpression, contextFlags); - case SyntaxKind.ExportAssignment: - return tryGetTypeFromEffectiveTypeNode(parent as ExportAssignment); - case SyntaxKind.JsxExpression: - return getContextualTypeForJsxExpression(parent as JsxExpression); - case SyntaxKind.JsxAttribute: - case SyntaxKind.JsxSpreadAttribute: - return getContextualTypeForJsxAttribute(parent as JsxAttribute | JsxSpreadAttribute); - case SyntaxKind.JsxOpeningElement: - case SyntaxKind.JsxSelfClosingElement: - return getContextualJsxElementAttributesType(parent as JsxOpeningLikeElement, contextFlags); + case ts.SyntaxKind.NonNullExpression: + return getContextualType(parent as ts.NonNullExpression, contextFlags); + case ts.SyntaxKind.ExportAssignment: + return tryGetTypeFromEffectiveTypeNode(parent as ts.ExportAssignment); + case ts.SyntaxKind.JsxExpression: + return getContextualTypeForJsxExpression(parent as ts.JsxExpression); + case ts.SyntaxKind.JsxAttribute: + case ts.SyntaxKind.JsxSpreadAttribute: + return getContextualTypeForJsxAttribute(parent as ts.JsxAttribute | ts.JsxSpreadAttribute); + case ts.SyntaxKind.JsxOpeningElement: + case ts.SyntaxKind.JsxSelfClosingElement: + return getContextualJsxElementAttributesType(parent as ts.JsxOpeningLikeElement, contextFlags); } return undefined; - function tryFindWhenConstTypeReference(node: Expression) { + function tryFindWhenConstTypeReference(node: ts.Expression) { return getContextualType(node); } } - function getInferenceContext(node: Node) { - const ancestor = findAncestor(node, n => !!n.inferenceContext); + function getInferenceContext(node: ts.Node) { + const ancestor = ts.findAncestor(node, n => !!n.inferenceContext); return ancestor && ancestor.inferenceContext!; } - function getContextualJsxElementAttributesType(node: JsxOpeningLikeElement, contextFlags?: ContextFlags) { - if (isJsxOpeningElement(node) && node.parent.contextualType && contextFlags !== ContextFlags.Completions) { + function getContextualJsxElementAttributesType(node: ts.JsxOpeningLikeElement, contextFlags?: ts.ContextFlags) { + if (ts.isJsxOpeningElement(node) && node.parent.contextualType && contextFlags !== ts.ContextFlags.Completions) { // Contextually applied type is moved from attributes up to the outer jsx attributes so when walking up from the children they get hit // _However_ to hit them from the _attributes_ we must look for them here; otherwise we'll used the declared type // (as below) instead! @@ -27195,13 +26625,13 @@ namespace ts { return getContextualTypeForArgumentAtIndex(node, 0); } - function getEffectiveFirstArgumentForJsxSignature(signature: Signature, node: JsxOpeningLikeElement) { - return getJsxReferenceKind(node) !== JsxReferenceKind.Component + function getEffectiveFirstArgumentForJsxSignature(signature: ts.Signature, node: ts.JsxOpeningLikeElement) { + return getJsxReferenceKind(node) !== ts.JsxReferenceKind.Component ? getJsxPropsTypeFromCallSignature(signature, node) : getJsxPropsTypeFromClassType(signature, node); } - function getJsxPropsTypeFromCallSignature(sig: Signature, context: JsxOpeningLikeElement) { + function getJsxPropsTypeFromCallSignature(sig: ts.Signature, context: ts.JsxOpeningLikeElement) { let propsType = getTypeOfFirstParameterOfSignatureWithFallback(sig, unknownType); propsType = getJsxManagedAttributesFromLocatedAttributes(context, getJsxNamespaceAt(context), propsType); const intrinsicAttribs = getJsxType(JsxNames.IntrinsicAttributes, context); @@ -27211,14 +26641,14 @@ namespace ts { return propsType; } - function getJsxPropsTypeForSignatureFromMember(sig: Signature, forcedLookupLocation: __String) { + function getJsxPropsTypeForSignatureFromMember(sig: ts.Signature, forcedLookupLocation: ts.__String) { if (sig.compositeSignatures) { // JSX Elements using the legacy `props`-field based lookup (eg, react class components) need to treat the `props` member as an input // instead of an output position when resolving the signature. We need to go back to the input signatures of the composite signature, // get the type of `props` on each return type individually, and then _intersect them_, rather than union them (as would normally occur // for a union signature). It's an unfortunate quirk of looking in the output of the signature for the type we want to use for the input. // The default behavior of `getTypeOfFirstParameterOfSignatureWithFallback` when no `props` member name is defined is much more sane. - const results: Type[] = []; + const results: ts.Type[] = []; for (const signature of sig.compositeSignatures) { const instance = getReturnTypeOfSignature(signature); if (isTypeAny(instance)) { @@ -27236,15 +26666,15 @@ namespace ts { return isTypeAny(instanceType) ? instanceType : getTypeOfPropertyOfType(instanceType, forcedLookupLocation); } - function getStaticTypeOfReferencedJsxConstructor(context: JsxOpeningLikeElement) { + function getStaticTypeOfReferencedJsxConstructor(context: ts.JsxOpeningLikeElement) { if (isJsxIntrinsicIdentifier(context.tagName)) { const result = getIntrinsicAttributesTypeFromJsxOpeningLikeElement(context); const fakeSignature = createSignatureForJSXIntrinsic(context, result); return getOrCreateTypeFromSignature(fakeSignature); } const tagType = checkExpressionCached(context.tagName); - if (tagType.flags & TypeFlags.StringLiteral) { - const result = getIntrinsicAttributesTypeFromStringLiteralType(tagType as StringLiteralType, context); + if (tagType.flags & ts.TypeFlags.StringLiteral) { + const result = getIntrinsicAttributesTypeFromStringLiteralType(tagType as ts.StringLiteralType, context); if (!result) { return errorType; } @@ -27254,27 +26684,27 @@ namespace ts { return tagType; } - function getJsxManagedAttributesFromLocatedAttributes(context: JsxOpeningLikeElement, ns: Symbol, attributesType: Type) { + function getJsxManagedAttributesFromLocatedAttributes(context: ts.JsxOpeningLikeElement, ns: ts.Symbol, attributesType: ts.Type) { const managedSym = getJsxLibraryManagedAttributes(ns); if (managedSym) { const declaredManagedType = getDeclaredTypeOfSymbol(managedSym); // fetches interface type, or initializes symbol links type parmaeters const ctorType = getStaticTypeOfReferencedJsxConstructor(context); - if (managedSym.flags & SymbolFlags.TypeAlias) { + if (managedSym.flags & ts.SymbolFlags.TypeAlias) { const params = getSymbolLinks(managedSym).typeParameters; - if (length(params) >= 2) { - const args = fillMissingTypeArguments([ctorType, attributesType], params, 2, isInJSFile(context)); + if (ts.length(params) >= 2) { + const args = fillMissingTypeArguments([ctorType, attributesType], params, 2, ts.isInJSFile(context)); return getTypeAliasInstantiation(managedSym, args); } } - if (length((declaredManagedType as GenericType).typeParameters) >= 2) { - const args = fillMissingTypeArguments([ctorType, attributesType], (declaredManagedType as GenericType).typeParameters, 2, isInJSFile(context)); - return createTypeReference((declaredManagedType as GenericType), args); + if (ts.length((declaredManagedType as ts.GenericType).typeParameters) >= 2) { + const args = fillMissingTypeArguments([ctorType, attributesType], (declaredManagedType as ts.GenericType).typeParameters, 2, ts.isInJSFile(context)); + return createTypeReference((declaredManagedType as ts.GenericType), args); } } return attributesType; } - function getJsxPropsTypeFromClassType(sig: Signature, context: JsxOpeningLikeElement) { + function getJsxPropsTypeFromClassType(sig: ts.Signature, context: ts.JsxOpeningLikeElement) { const ns = getJsxNamespaceAt(context); const forcedLookupLocation = getJsxElementPropertiesName(ns); let attributesType = forcedLookupLocation === undefined @@ -27288,8 +26718,8 @@ namespace ts { if (!attributesType) { // There is no property named 'props' on this instance type - if (!!forcedLookupLocation && !!length(context.attributes.properties)) { - error(context, Diagnostics.JSX_element_class_does_not_support_attributes_because_it_does_not_have_a_0_property, unescapeLeadingUnderscores(forcedLookupLocation)); + if (!!forcedLookupLocation && !!ts.length(context.attributes.properties)) { + error(context, ts.Diagnostics.JSX_element_class_does_not_support_attributes_because_it_does_not_have_a_0_property, ts.unescapeLeadingUnderscores(forcedLookupLocation)); } return unknownType; } @@ -27307,12 +26737,9 @@ namespace ts { if (!isErrorType(intrinsicClassAttribs)) { const typeParams = getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(intrinsicClassAttribs.symbol); const hostClassType = getReturnTypeOfSignature(sig); - apparentAttributesType = intersectTypes( - typeParams - ? createTypeReference(intrinsicClassAttribs as GenericType, fillMissingTypeArguments([hostClassType], typeParams, getMinTypeArgumentCount(typeParams), isInJSFile(context))) - : intrinsicClassAttribs, - apparentAttributesType - ); + apparentAttributesType = intersectTypes(typeParams + ? createTypeReference(intrinsicClassAttribs as ts.GenericType, fillMissingTypeArguments([hostClassType], typeParams, getMinTypeArgumentCount(typeParams), ts.isInJSFile(context))) + : intrinsicClassAttribs, apparentAttributesType); } const intrinsicAttribs = getJsxType(JsxNames.IntrinsicAttributes, context); @@ -27324,18 +26751,15 @@ namespace ts { } } - function getIntersectedSignatures(signatures: readonly Signature[]) { - return getStrictOptionValue(compilerOptions, "noImplicitAny") - ? reduceLeft( - signatures, - (left, right) => - left === right || !left ? left + function getIntersectedSignatures(signatures: readonly ts.Signature[]) { + return ts.getStrictOptionValue(compilerOptions, "noImplicitAny") + ? ts.reduceLeft(signatures, (left, right) => left === right || !left ? left : compareTypeParametersIdentical(left.typeParameters, right.typeParameters) ? combineSignaturesOfIntersectionMembers(left, right) : undefined) : undefined; } - function combineIntersectionThisParam(left: Symbol | undefined, right: Symbol | undefined, mapper: TypeMapper | undefined): Symbol | undefined { + function combineIntersectionThisParam(left: ts.Symbol | undefined, right: ts.Symbol | undefined, mapper: ts.TypeMapper | undefined): ts.Symbol | undefined { if (!left || !right) { return left || right; } @@ -27346,7 +26770,7 @@ namespace ts { return createSymbolWithType(left, thisType); } - function combineIntersectionParameters(left: Signature, right: Signature, mapper: TypeMapper | undefined) { + function combineIntersectionParameters(left: ts.Signature, right: ts.Signature, mapper: ts.TypeMapper | undefined) { const leftCount = getParameterCount(left); const rightCount = getParameterCount(right); const longest = leftCount >= rightCount ? left : right; @@ -27354,7 +26778,7 @@ namespace ts { const longestCount = longest === left ? leftCount : rightCount; const eitherHasEffectiveRest = (hasEffectiveRestParameter(left) || hasEffectiveRestParameter(right)); const needsExtraRestElement = eitherHasEffectiveRest && !hasEffectiveRestParameter(longest); - const params = new Array(longestCount + (needsExtraRestElement ? 1 : 0)); + const params = new Array(longestCount + (needsExtraRestElement ? 1 : 0)); for (let i = 0; i < longestCount; i++) { let longestParamType = tryGetTypeAtPosition(longest, i)!; if (longest === right) { @@ -27374,15 +26798,12 @@ namespace ts { !leftName ? rightName : !rightName ? leftName : undefined; - const paramSymbol = createSymbol( - SymbolFlags.FunctionScopedVariable | (isOptional && !isRestParam ? SymbolFlags.Optional : 0), - paramName || `arg${i}` as __String - ); + const paramSymbol = createSymbol(ts.SymbolFlags.FunctionScopedVariable | (isOptional && !isRestParam ? ts.SymbolFlags.Optional : 0), paramName || `arg${i}` as ts.__String); paramSymbol.type = isRestParam ? createArrayType(unionParamType) : unionParamType; params[i] = paramSymbol; } if (needsExtraRestElement) { - const restParamSymbol = createSymbol(SymbolFlags.FunctionScopedVariable, "args" as __String); + const restParamSymbol = createSymbol(ts.SymbolFlags.FunctionScopedVariable, "args" as ts.__String); restParamSymbol.type = createArrayType(getTypeAtPosition(shorter, longestCount)); if (shorter === right) { restParamSymbol.type = instantiateType(restParamSymbol.type, mapper); @@ -27392,9 +26813,9 @@ namespace ts { return params; } - function combineSignaturesOfIntersectionMembers(left: Signature, right: Signature): Signature { + function combineSignaturesOfIntersectionMembers(left: ts.Signature, right: ts.Signature): ts.Signature { const typeParams = left.typeParameters || right.typeParameters; - let paramMapper: TypeMapper | undefined; + let paramMapper: ts.TypeMapper | undefined; if (left.typeParameters && right.typeParameters) { paramMapper = createTypeMapper(right.typeParameters, left.typeParameters); // We just use the type parameter defaults from the first signature @@ -27403,34 +26824,27 @@ namespace ts { const params = combineIntersectionParameters(left, right, paramMapper); const thisParam = combineIntersectionThisParam(left.thisParameter, right.thisParameter, paramMapper); const minArgCount = Math.max(left.minArgumentCount, right.minArgumentCount); - const result = createSignature( - declaration, - typeParams, - thisParam, - params, + const result = createSignature(declaration, typeParams, thisParam, params, /*resolvedReturnType*/ undefined, - /*resolvedTypePredicate*/ undefined, - minArgCount, - (left.flags | right.flags) & SignatureFlags.PropagatingFlags - ); - result.compositeKind = TypeFlags.Intersection; - result.compositeSignatures = concatenate(left.compositeKind === TypeFlags.Intersection && left.compositeSignatures || [left], [right]); + /*resolvedTypePredicate*/ undefined, minArgCount, (left.flags | right.flags) & ts.SignatureFlags.PropagatingFlags); + result.compositeKind = ts.TypeFlags.Intersection; + result.compositeSignatures = ts.concatenate(left.compositeKind === ts.TypeFlags.Intersection && left.compositeSignatures || [left], [right]); if (paramMapper) { - result.mapper = left.compositeKind === TypeFlags.Intersection && left.mapper && left.compositeSignatures ? combineTypeMappers(left.mapper, paramMapper) : paramMapper; + result.mapper = left.compositeKind === ts.TypeFlags.Intersection && left.mapper && left.compositeSignatures ? combineTypeMappers(left.mapper, paramMapper) : paramMapper; } return result; } // If the given type is an object or union type with a single signature, and if that signature has at // least as many parameters as the given function, return the signature. Otherwise return undefined. - function getContextualCallSignature(type: Type, node: SignatureDeclaration): Signature | undefined { - const signatures = getSignaturesOfType(type, SignatureKind.Call); - const applicableByArity = filter(signatures, s => !isAritySmaller(s, node)); + function getContextualCallSignature(type: ts.Type, node: ts.SignatureDeclaration): ts.Signature | undefined { + const signatures = getSignaturesOfType(type, ts.SignatureKind.Call); + const applicableByArity = ts.filter(signatures, s => !isAritySmaller(s, node)); return applicableByArity.length === 1 ? applicableByArity[0] : getIntersectedSignatures(applicableByArity); } /** If the contextual signature has fewer parameters than the function expression, do not use it */ - function isAritySmaller(signature: Signature, target: SignatureDeclaration) { + function isAritySmaller(signature: ts.Signature, target: ts.SignatureDeclaration) { let targetParameterCount = 0; for (; targetParameterCount < target.parameters.length; targetParameterCount++) { const param = target.parameters[targetParameterCount]; @@ -27438,16 +26852,16 @@ namespace ts { break; } } - if (target.parameters.length && parameterIsThisKeyword(target.parameters[0])) { + if (target.parameters.length && ts.parameterIsThisKeyword(target.parameters[0])) { targetParameterCount--; } return !hasEffectiveRestParameter(signature) && getParameterCount(signature) < targetParameterCount; } - function getContextualSignatureForFunctionLikeDeclaration(node: FunctionLikeDeclaration): Signature | undefined { + function getContextualSignatureForFunctionLikeDeclaration(node: ts.FunctionLikeDeclaration): ts.Signature | undefined { // Only function expressions, arrow functions, and object literal methods are contextually typed. - return isFunctionExpressionOrArrowFunction(node) || isObjectLiteralMethod(node) - ? getContextualSignature(node as FunctionExpression) + return ts.isFunctionExpressionOrArrowFunction(node) || ts.isObjectLiteralMethod(node) + ? getContextualSignature(node as ts.FunctionExpression) : undefined; } @@ -27456,21 +26870,21 @@ namespace ts { // If the contextual type is a union type, get the signature from each type possible and if they are // all identical ignoring their return type, the result is same signature but with return type as // union type of return types from these signatures - function getContextualSignature(node: FunctionExpression | ArrowFunction | MethodDeclaration): Signature | undefined { - Debug.assert(node.kind !== SyntaxKind.MethodDeclaration || isObjectLiteralMethod(node)); + function getContextualSignature(node: ts.FunctionExpression | ts.ArrowFunction | ts.MethodDeclaration): ts.Signature | undefined { + ts.Debug.assert(node.kind !== ts.SyntaxKind.MethodDeclaration || ts.isObjectLiteralMethod(node)); const typeTagSignature = getSignatureOfTypeTag(node); if (typeTagSignature) { return typeTagSignature; } - const type = getApparentTypeOfContextualType(node, ContextFlags.Signature); + const type = getApparentTypeOfContextualType(node, ts.ContextFlags.Signature); if (!type) { return undefined; } - if (!(type.flags & TypeFlags.Union)) { + if (!(type.flags & ts.TypeFlags.Union)) { return getContextualCallSignature(type, node); } - let signatureList: Signature[] | undefined; - const types = (type as UnionType).types; + let signatureList: ts.Signature[] | undefined; + const types = (type as ts.UnionType).types; for (const current of types) { const signature = getContextualCallSignature(current, node); if (signature) { @@ -27494,43 +26908,43 @@ namespace ts { } } - function checkSpreadExpression(node: SpreadElement, checkMode?: CheckMode): Type { - if (languageVersion < ScriptTarget.ES2015) { - checkExternalEmitHelpers(node, compilerOptions.downlevelIteration ? ExternalEmitHelpers.SpreadIncludes : ExternalEmitHelpers.SpreadArray); + function checkSpreadExpression(node: ts.SpreadElement, checkMode?: CheckMode): ts.Type { + if (languageVersion < ts.ScriptTarget.ES2015) { + checkExternalEmitHelpers(node, compilerOptions.downlevelIteration ? ts.ExternalEmitHelpers.SpreadIncludes : ts.ExternalEmitHelpers.SpreadArray); } const arrayOrIterableType = checkExpression(node.expression, checkMode); return checkIteratedTypeOrElementType(IterationUse.Spread, arrayOrIterableType, undefinedType, node.expression); } - function checkSyntheticExpression(node: SyntheticExpression): Type { + function checkSyntheticExpression(node: ts.SyntheticExpression): ts.Type { return node.isSpread ? getIndexedAccessType(node.type, numberType) : node.type; } - function hasDefaultValue(node: BindingElement | Expression): boolean { - return (node.kind === SyntaxKind.BindingElement && !!(node as BindingElement).initializer) || - (node.kind === SyntaxKind.BinaryExpression && (node as BinaryExpression).operatorToken.kind === SyntaxKind.EqualsToken); + function hasDefaultValue(node: ts.BindingElement | ts.Expression): boolean { + return (node.kind === ts.SyntaxKind.BindingElement && !!(node as ts.BindingElement).initializer) || + (node.kind === ts.SyntaxKind.BinaryExpression && (node as ts.BinaryExpression).operatorToken.kind === ts.SyntaxKind.EqualsToken); } - function checkArrayLiteral(node: ArrayLiteralExpression, checkMode: CheckMode | undefined, forceTuple: boolean | undefined): Type { + function checkArrayLiteral(node: ts.ArrayLiteralExpression, checkMode: CheckMode | undefined, forceTuple: boolean | undefined): ts.Type { const elements = node.elements; const elementCount = elements.length; - const elementTypes: Type[] = []; - const elementFlags: ElementFlags[] = []; + const elementTypes: ts.Type[] = []; + const elementFlags: ts.ElementFlags[] = []; const contextualType = getApparentTypeOfContextualType(node); - const inDestructuringPattern = isAssignmentTarget(node); + const inDestructuringPattern = ts.isAssignmentTarget(node); const inConstContext = isConstContext(node); let hasOmittedExpression = false; for (let i = 0; i < elementCount; i++) { const e = elements[i]; - if (e.kind === SyntaxKind.SpreadElement) { - if (languageVersion < ScriptTarget.ES2015) { - checkExternalEmitHelpers(e, compilerOptions.downlevelIteration ? ExternalEmitHelpers.SpreadIncludes : ExternalEmitHelpers.SpreadArray); + if (e.kind === ts.SyntaxKind.SpreadElement) { + if (languageVersion < ts.ScriptTarget.ES2015) { + checkExternalEmitHelpers(e, compilerOptions.downlevelIteration ? ts.ExternalEmitHelpers.SpreadIncludes : ts.ExternalEmitHelpers.SpreadArray); } - const spreadType = checkExpression((e as SpreadElement).expression, checkMode, forceTuple); + const spreadType = checkExpression((e as ts.SpreadElement).expression, checkMode, forceTuple); if (isArrayLikeType(spreadType)) { elementTypes.push(spreadType); - elementFlags.push(ElementFlags.Variadic); + elementFlags.push(ts.ElementFlags.Variadic); } else if (inDestructuringPattern) { // Given the following situation: @@ -27549,26 +26963,26 @@ namespace ts { getIteratedTypeOrElementType(IterationUse.Destructuring, spreadType, undefinedType, /*errorNode*/ undefined, /*checkAssignability*/ false) || unknownType; elementTypes.push(restElementType); - elementFlags.push(ElementFlags.Rest); + elementFlags.push(ts.ElementFlags.Rest); } else { - elementTypes.push(checkIteratedTypeOrElementType(IterationUse.Spread, spreadType, undefinedType, (e as SpreadElement).expression)); - elementFlags.push(ElementFlags.Rest); + elementTypes.push(checkIteratedTypeOrElementType(IterationUse.Spread, spreadType, undefinedType, (e as ts.SpreadElement).expression)); + elementFlags.push(ts.ElementFlags.Rest); } } - else if (exactOptionalPropertyTypes && e.kind === SyntaxKind.OmittedExpression) { + else if (exactOptionalPropertyTypes && e.kind === ts.SyntaxKind.OmittedExpression) { hasOmittedExpression = true; elementTypes.push(missingType); - elementFlags.push(ElementFlags.Optional); + elementFlags.push(ts.ElementFlags.Optional); } else { const elementContextualType = getContextualTypeForElementExpression(contextualType, elementTypes.length); const type = checkExpressionForMutableLocation(e, checkMode, elementContextualType, forceTuple); elementTypes.push(addOptionality(type, /*isProperty*/ true, hasOmittedExpression)); - elementFlags.push(hasOmittedExpression ? ElementFlags.Optional : ElementFlags.Required); + elementFlags.push(hasOmittedExpression ? ts.ElementFlags.Optional : ts.ElementFlags.Required); if (contextualType && someType(contextualType, isTupleLikeType) && checkMode && checkMode & CheckMode.Inferential && !(checkMode & CheckMode.SkipContextSensitive) && isContextSensitive(e)) { const inferenceContext = getInferenceContext(node); - Debug.assert(inferenceContext); // In CheckMode.Inferential we should always have an inference context + ts.Debug.assert(inferenceContext); // In CheckMode.Inferential we should always have an inference context addIntraExpressionInferenceSite(inferenceContext, e, type); } } @@ -27580,90 +26994,90 @@ namespace ts { return createArrayLiteralType(createTupleType(elementTypes, elementFlags, /*readonly*/ inConstContext)); } return createArrayLiteralType(createArrayType(elementTypes.length ? - getUnionType(sameMap(elementTypes, (t, i) => elementFlags[i] & ElementFlags.Variadic ? getIndexedAccessTypeOrUndefined(t, numberType) || anyType : t), UnionReduction.Subtype) : + getUnionType(ts.sameMap(elementTypes, (t, i) => elementFlags[i] & ts.ElementFlags.Variadic ? getIndexedAccessTypeOrUndefined(t, numberType) || anyType : t), ts.UnionReduction.Subtype) : strictNullChecks ? implicitNeverType : undefinedWideningType, inConstContext)); } - function createArrayLiteralType(type: Type) { - if (!(getObjectFlags(type) & ObjectFlags.Reference)) { + function createArrayLiteralType(type: ts.Type) { + if (!(ts.getObjectFlags(type) & ts.ObjectFlags.Reference)) { return type; } - let literalType = (type as TypeReference).literalType; + let literalType = (type as ts.TypeReference).literalType; if (!literalType) { - literalType = (type as TypeReference).literalType = cloneTypeReference(type as TypeReference); - literalType.objectFlags |= ObjectFlags.ArrayLiteral | ObjectFlags.ContainsObjectOrArrayLiteral; + literalType = (type as ts.TypeReference).literalType = cloneTypeReference(type as ts.TypeReference); + literalType.objectFlags |= ts.ObjectFlags.ArrayLiteral | ts.ObjectFlags.ContainsObjectOrArrayLiteral; } return literalType; } - function isNumericName(name: DeclarationName): boolean { + function isNumericName(name: ts.DeclarationName): boolean { switch (name.kind) { - case SyntaxKind.ComputedPropertyName: + case ts.SyntaxKind.ComputedPropertyName: return isNumericComputedName(name); - case SyntaxKind.Identifier: - return isNumericLiteralName(name.escapedText); - case SyntaxKind.NumericLiteral: - case SyntaxKind.StringLiteral: - return isNumericLiteralName(name.text); + case ts.SyntaxKind.Identifier: + return ts.isNumericLiteralName(name.escapedText); + case ts.SyntaxKind.NumericLiteral: + case ts.SyntaxKind.StringLiteral: + return ts.isNumericLiteralName(name.text); default: return false; } } - function isNumericComputedName(name: ComputedPropertyName): boolean { + function isNumericComputedName(name: ts.ComputedPropertyName): boolean { // It seems odd to consider an expression of type Any to result in a numeric name, // but this behavior is consistent with checkIndexedAccess - return isTypeAssignableToKind(checkComputedPropertyName(name), TypeFlags.NumberLike); + return isTypeAssignableToKind(checkComputedPropertyName(name), ts.TypeFlags.NumberLike); } - function checkComputedPropertyName(node: ComputedPropertyName): Type { + function checkComputedPropertyName(node: ts.ComputedPropertyName): ts.Type { const links = getNodeLinks(node.expression); if (!links.resolvedType) { - if ((isTypeLiteralNode(node.parent.parent) || isClassLike(node.parent.parent) || isInterfaceDeclaration(node.parent.parent)) - && isBinaryExpression(node.expression) && node.expression.operatorToken.kind === SyntaxKind.InKeyword - && node.parent.kind !== SyntaxKind.GetAccessor && node.parent.kind !== SyntaxKind.SetAccessor) { + if ((ts.isTypeLiteralNode(node.parent.parent) || ts.isClassLike(node.parent.parent) || ts.isInterfaceDeclaration(node.parent.parent)) + && ts.isBinaryExpression(node.expression) && node.expression.operatorToken.kind === ts.SyntaxKind.InKeyword + && node.parent.kind !== ts.SyntaxKind.GetAccessor && node.parent.kind !== ts.SyntaxKind.SetAccessor) { return links.resolvedType = errorType; } links.resolvedType = checkExpression(node.expression); // The computed property name of a non-static class field within a loop must be stored in a block-scoped binding. // (It needs to be bound at class evaluation time.) - if (isPropertyDeclaration(node.parent) && !hasStaticModifier(node.parent) && isClassExpression(node.parent.parent)) { - const container = getEnclosingBlockScopeContainer(node.parent.parent); + if (ts.isPropertyDeclaration(node.parent) && !ts.hasStaticModifier(node.parent) && ts.isClassExpression(node.parent.parent)) { + const container = ts.getEnclosingBlockScopeContainer(node.parent.parent); const enclosingIterationStatement = getEnclosingIterationStatement(container); if (enclosingIterationStatement) { // The computed field name will use a block scoped binding which can be unique for each iteration of the loop. - getNodeLinks(enclosingIterationStatement).flags |= NodeCheckFlags.LoopWithCapturedBlockScopedBinding; + getNodeLinks(enclosingIterationStatement).flags |= ts.NodeCheckFlags.LoopWithCapturedBlockScopedBinding; // The generated variable which stores the computed field name must be block-scoped. - getNodeLinks(node).flags |= NodeCheckFlags.BlockScopedBindingInLoop; + getNodeLinks(node).flags |= ts.NodeCheckFlags.BlockScopedBindingInLoop; // The generated variable which stores the class must be block-scoped. - getNodeLinks(node.parent.parent).flags |= NodeCheckFlags.BlockScopedBindingInLoop; + getNodeLinks(node.parent.parent).flags |= ts.NodeCheckFlags.BlockScopedBindingInLoop; } } // This will allow types number, string, symbol or any. It will also allow enums, the unknown // type, and any union of these types (like string | number). - if (links.resolvedType.flags & TypeFlags.Nullable || - !isTypeAssignableToKind(links.resolvedType, TypeFlags.StringLike | TypeFlags.NumberLike | TypeFlags.ESSymbolLike) && + if (links.resolvedType.flags & ts.TypeFlags.Nullable || + !isTypeAssignableToKind(links.resolvedType, ts.TypeFlags.StringLike | ts.TypeFlags.NumberLike | ts.TypeFlags.ESSymbolLike) && !isTypeAssignableTo(links.resolvedType, stringNumberSymbolType)) { - error(node, Diagnostics.A_computed_property_name_must_be_of_type_string_number_symbol_or_any); + error(node, ts.Diagnostics.A_computed_property_name_must_be_of_type_string_number_symbol_or_any); } } return links.resolvedType; } - function isSymbolWithNumericName(symbol: Symbol) { + function isSymbolWithNumericName(symbol: ts.Symbol) { const firstDecl = symbol.declarations?.[0]; - return isNumericLiteralName(symbol.escapedName) || (firstDecl && isNamedDeclaration(firstDecl) && isNumericName(firstDecl.name)); + return ts.isNumericLiteralName(symbol.escapedName) || (firstDecl && ts.isNamedDeclaration(firstDecl) && isNumericName(firstDecl.name)); } - function isSymbolWithSymbolName(symbol: Symbol) { + function isSymbolWithSymbolName(symbol: ts.Symbol) { const firstDecl = symbol.declarations?.[0]; - return isKnownSymbol(symbol) || (firstDecl && isNamedDeclaration(firstDecl) && isComputedPropertyName(firstDecl.name) && - isTypeAssignableToKind(checkComputedPropertyName(firstDecl.name), TypeFlags.ESSymbol)); + return ts.isKnownSymbol(symbol) || (firstDecl && ts.isNamedDeclaration(firstDecl) && ts.isComputedPropertyName(firstDecl.name) && + isTypeAssignableToKind(checkComputedPropertyName(firstDecl.name), ts.TypeFlags.ESSymbol)); } - function getObjectLiteralIndexInfo(node: ObjectLiteralExpression, offset: number, properties: Symbol[], keyType: Type): IndexInfo { - const propTypes: Type[] = []; + function getObjectLiteralIndexInfo(node: ts.ObjectLiteralExpression, offset: number, properties: ts.Symbol[], keyType: ts.Type): ts.IndexInfo { + const propTypes: ts.Type[] = []; for (let i = offset; i < properties.length; i++) { const prop = properties[i]; if (keyType === stringType && !isSymbolWithSymbolName(prop) || @@ -27672,41 +27086,42 @@ namespace ts { propTypes.push(getTypeOfSymbol(properties[i])); } } - const unionType = propTypes.length ? getUnionType(propTypes, UnionReduction.Subtype) : undefinedType; + const unionType = propTypes.length ? getUnionType(propTypes, ts.UnionReduction.Subtype) : undefinedType; return createIndexInfo(keyType, unionType, isConstContext(node)); } - function getImmediateAliasedSymbol(symbol: Symbol): Symbol | undefined { - Debug.assert((symbol.flags & SymbolFlags.Alias) !== 0, "Should only get Alias here."); + function getImmediateAliasedSymbol(symbol: ts.Symbol): ts.Symbol | undefined { + ts.Debug.assert((symbol.flags & ts.SymbolFlags.Alias) !== 0, "Should only get Alias here."); const links = getSymbolLinks(symbol); if (!links.immediateTarget) { const node = getDeclarationOfAliasSymbol(symbol); - if (!node) return Debug.fail(); + if (!node) + return ts.Debug.fail(); links.immediateTarget = getTargetOfAliasDeclaration(node, /*dontRecursivelyResolve*/ true); } return links.immediateTarget; } - function checkObjectLiteral(node: ObjectLiteralExpression, checkMode?: CheckMode): Type { - const inDestructuringPattern = isAssignmentTarget(node); + function checkObjectLiteral(node: ts.ObjectLiteralExpression, checkMode?: CheckMode): ts.Type { + const inDestructuringPattern = ts.isAssignmentTarget(node); // Grammar checking checkGrammarObjectLiteralExpression(node, inDestructuringPattern); - const allPropertiesTable = strictNullChecks ? createSymbolTable() : undefined; - let propertiesTable = createSymbolTable(); - let propertiesArray: Symbol[] = []; - let spread: Type = emptyObjectType; + const allPropertiesTable = strictNullChecks ? ts.createSymbolTable() : undefined; + let propertiesTable = ts.createSymbolTable(); + let propertiesArray: ts.Symbol[] = []; + let spread: ts.Type = emptyObjectType; const contextualType = getApparentTypeOfContextualType(node); const contextualTypeHasPattern = contextualType && contextualType.pattern && - (contextualType.pattern.kind === SyntaxKind.ObjectBindingPattern || contextualType.pattern.kind === SyntaxKind.ObjectLiteralExpression); + (contextualType.pattern.kind === ts.SyntaxKind.ObjectBindingPattern || contextualType.pattern.kind === ts.SyntaxKind.ObjectLiteralExpression); const inConstContext = isConstContext(node); - const checkFlags = inConstContext ? CheckFlags.Readonly : 0; - const isInJavascript = isInJSFile(node) && !isInJsonFile(node); - const enumTag = getJSDocEnumTag(node); + const checkFlags = inConstContext ? ts.CheckFlags.Readonly : 0; + const isInJavascript = ts.isInJSFile(node) && !ts.isInJsonFile(node); + const enumTag = ts.getJSDocEnumTag(node); const isJSObjectLiteral = !contextualType && isInJavascript && !enumTag; - let objectFlags: ObjectFlags = freshObjectLiteralFlag; + let objectFlags: ts.ObjectFlags = freshObjectLiteralFlag; let patternWithComputedProperties = false; let hasComputedStringProperty = false; let hasComputedNumberProperty = false; @@ -27716,7 +27131,7 @@ namespace ts { // As otherwise they may not be checked until exports for the type at this position are retrieved, // which may never occur. for (const elem of node.properties) { - if (elem.name && isComputedPropertyName(elem.name)) { + if (elem.name && ts.isComputedPropertyName(elem.name)) { checkComputedPropertyName(elem.name); } } @@ -27724,16 +27139,16 @@ namespace ts { let offset = 0; for (const memberDecl of node.properties) { let member = getSymbolOfNode(memberDecl); - const computedNameType = memberDecl.name && memberDecl.name.kind === SyntaxKind.ComputedPropertyName ? + const computedNameType = memberDecl.name && memberDecl.name.kind === ts.SyntaxKind.ComputedPropertyName ? checkComputedPropertyName(memberDecl.name) : undefined; - if (memberDecl.kind === SyntaxKind.PropertyAssignment || - memberDecl.kind === SyntaxKind.ShorthandPropertyAssignment || - isObjectLiteralMethod(memberDecl)) { - let type = memberDecl.kind === SyntaxKind.PropertyAssignment ? checkPropertyAssignment(memberDecl, checkMode) : + if (memberDecl.kind === ts.SyntaxKind.PropertyAssignment || + memberDecl.kind === ts.SyntaxKind.ShorthandPropertyAssignment || + ts.isObjectLiteralMethod(memberDecl)) { + let type = memberDecl.kind === ts.SyntaxKind.PropertyAssignment ? checkPropertyAssignment(memberDecl, checkMode) : // avoid resolving the left side of the ShorthandPropertyAssignment outside of the destructuring // for error recovery purposes. For example, if a user wrote `{ a = 100 }` instead of `{ a: 100 }`. // we don't want to say "could not find 'a'". - memberDecl.kind === SyntaxKind.ShorthandPropertyAssignment ? checkExpressionForMutableLocation(!inDestructuringPattern && memberDecl.objectAssignmentInitializer ? memberDecl.objectAssignmentInitializer : memberDecl.name, checkMode) : + memberDecl.kind === ts.SyntaxKind.ShorthandPropertyAssignment ? checkExpressionForMutableLocation(!inDestructuringPattern && memberDecl.objectAssignmentInitializer ? memberDecl.objectAssignmentInitializer : memberDecl.name, checkMode) : checkObjectLiteralMethod(memberDecl, checkMode); if (isInJavascript) { const jsDocType = getTypeForDeclarationFromJSDocComment(memberDecl); @@ -27745,11 +27160,11 @@ namespace ts { checkTypeAssignableTo(type, getTypeFromTypeNode(enumTag.typeExpression), memberDecl); } } - objectFlags |= getObjectFlags(type) & ObjectFlags.PropagatingFlags; + objectFlags |= ts.getObjectFlags(type) & ts.ObjectFlags.PropagatingFlags; const nameType = computedNameType && isTypeUsableAsPropertyName(computedNameType) ? computedNameType : undefined; const prop = nameType ? - createSymbol(SymbolFlags.Property | member.flags, getPropertyNameFromType(nameType), checkFlags | CheckFlags.Late) : - createSymbol(SymbolFlags.Property | member.flags, member.escapedName, checkFlags); + createSymbol(ts.SymbolFlags.Property | member.flags, getPropertyNameFromType(nameType), checkFlags | ts.CheckFlags.Late) : + createSymbol(ts.SymbolFlags.Property | member.flags, member.escapedName, checkFlags); if (nameType) { prop.nameType = nameType; } @@ -27757,24 +27172,22 @@ namespace ts { if (inDestructuringPattern) { // If object literal is an assignment pattern and if the assignment pattern specifies a default value // for the property, make the property optional. - const isOptional = - (memberDecl.kind === SyntaxKind.PropertyAssignment && hasDefaultValue(memberDecl.initializer)) || - (memberDecl.kind === SyntaxKind.ShorthandPropertyAssignment && memberDecl.objectAssignmentInitializer); + const isOptional = (memberDecl.kind === ts.SyntaxKind.PropertyAssignment && hasDefaultValue(memberDecl.initializer)) || + (memberDecl.kind === ts.SyntaxKind.ShorthandPropertyAssignment && memberDecl.objectAssignmentInitializer); if (isOptional) { - prop.flags |= SymbolFlags.Optional; + prop.flags |= ts.SymbolFlags.Optional; } } - else if (contextualTypeHasPattern && !(getObjectFlags(contextualType) & ObjectFlags.ObjectLiteralPatternWithComputedProperties)) { + else if (contextualTypeHasPattern && !(ts.getObjectFlags(contextualType) & ts.ObjectFlags.ObjectLiteralPatternWithComputedProperties)) { // If object literal is contextually typed by the implied type of a binding pattern, and if the // binding pattern specifies a default value for the property, make the property optional. const impliedProp = getPropertyOfType(contextualType, member.escapedName); if (impliedProp) { - prop.flags |= impliedProp.flags & SymbolFlags.Optional; + prop.flags |= impliedProp.flags & ts.SymbolFlags.Optional; } else if (!compilerOptions.suppressExcessPropertyErrors && !getIndexInfoOfType(contextualType, stringType)) { - error(memberDecl.name, Diagnostics.Object_literal_may_only_specify_known_properties_and_0_does_not_exist_in_type_1, - symbolToString(member), typeToString(contextualType)); + error(memberDecl.name, ts.Diagnostics.Object_literal_may_only_specify_known_properties_and_0_does_not_exist_in_type_1, symbolToString(member), typeToString(contextualType)); } } @@ -27790,21 +27203,21 @@ namespace ts { allPropertiesTable?.set(prop.escapedName, prop); if (contextualType && checkMode && checkMode & CheckMode.Inferential && !(checkMode & CheckMode.SkipContextSensitive) && - (memberDecl.kind === SyntaxKind.PropertyAssignment || memberDecl.kind === SyntaxKind.MethodDeclaration) && isContextSensitive(memberDecl)) { + (memberDecl.kind === ts.SyntaxKind.PropertyAssignment || memberDecl.kind === ts.SyntaxKind.MethodDeclaration) && isContextSensitive(memberDecl)) { const inferenceContext = getInferenceContext(node); - Debug.assert(inferenceContext); // In CheckMode.Inferential we should always have an inference context - const inferenceNode = memberDecl.kind === SyntaxKind.PropertyAssignment ? memberDecl.initializer : memberDecl; + ts.Debug.assert(inferenceContext); // In CheckMode.Inferential we should always have an inference context + const inferenceNode = memberDecl.kind === ts.SyntaxKind.PropertyAssignment ? memberDecl.initializer : memberDecl; addIntraExpressionInferenceSite(inferenceContext, inferenceNode, type); } } - else if (memberDecl.kind === SyntaxKind.SpreadAssignment) { - if (languageVersion < ScriptTarget.ES2015) { - checkExternalEmitHelpers(memberDecl, ExternalEmitHelpers.Assign); + else if (memberDecl.kind === ts.SyntaxKind.SpreadAssignment) { + if (languageVersion < ts.ScriptTarget.ES2015) { + checkExternalEmitHelpers(memberDecl, ts.ExternalEmitHelpers.Assign); } if (propertiesArray.length > 0) { spread = getSpreadType(spread, createObjectLiteralType(), node.symbol, objectFlags, inConstContext); propertiesArray = []; - propertiesTable = createSymbolTable(); + propertiesTable = ts.createSymbolTable(); hasComputedStringProperty = false; hasComputedNumberProperty = false; hasComputedSymbolProperty = false; @@ -27822,7 +27235,7 @@ namespace ts { spread = getSpreadType(spread, mergedType, node.symbol, objectFlags, inConstContext); } else { - error(memberDecl, Diagnostics.Spread_types_may_only_be_created_from_object_types); + error(memberDecl, ts.Diagnostics.Spread_types_may_only_be_created_from_object_types); spread = errorType; } continue; @@ -27833,11 +27246,11 @@ namespace ts { // an ordinary function declaration(section 6.1) with no parameters. // A set accessor declaration is processed in the same manner // as an ordinary function declaration with a single parameter and a Void return type. - Debug.assert(memberDecl.kind === SyntaxKind.GetAccessor || memberDecl.kind === SyntaxKind.SetAccessor); + ts.Debug.assert(memberDecl.kind === ts.SyntaxKind.GetAccessor || memberDecl.kind === ts.SyntaxKind.SetAccessor); checkNodeDeferred(memberDecl); } - if (computedNameType && !(computedNameType.flags & TypeFlags.StringOrNumberLiteralOrUnique)) { + if (computedNameType && !(computedNameType.flags & ts.TypeFlags.StringOrNumberLiteralOrUnique)) { if (isTypeAssignableTo(computedNameType, stringNumberSymbolType)) { if (isTypeAssignableTo(computedNameType, numberType)) { hasComputedNumberProperty = true; @@ -27863,12 +27276,11 @@ namespace ts { // type with those properties for which the binding pattern specifies a default value. // If the object literal is spread into another object literal, skip this step and let the top-level object // literal handle it instead. - if (contextualTypeHasPattern && node.parent.kind !== SyntaxKind.SpreadAssignment) { + if (contextualTypeHasPattern && node.parent.kind !== ts.SyntaxKind.SpreadAssignment) { for (const prop of getPropertiesOfType(contextualType)) { if (!propertiesTable.get(prop.escapedName) && !getPropertyOfType(spread, prop.escapedName)) { - if (!(prop.flags & SymbolFlags.Optional)) { - error(prop.valueDeclaration || (prop as TransientSymbol).bindingElement, - Diagnostics.Initializer_provides_no_value_for_this_binding_element_and_the_binding_element_has_no_default_value); + if (!(prop.flags & ts.SymbolFlags.Optional)) { + error(prop.valueDeclaration || (prop as ts.TransientSymbol).bindingElement, ts.Diagnostics.Initializer_provides_no_value_for_this_binding_element_and_the_binding_element_has_no_default_value); } propertiesTable.set(prop.escapedName, prop); propertiesArray.push(prop); @@ -27884,7 +27296,7 @@ namespace ts { if (propertiesArray.length > 0) { spread = getSpreadType(spread, createObjectLiteralType(), node.symbol, objectFlags, inConstContext); propertiesArray = []; - propertiesTable = createSymbolTable(); + propertiesTable = ts.createSymbolTable(); hasComputedStringProperty = false; hasComputedNumberProperty = false; } @@ -27896,16 +27308,19 @@ namespace ts { function createObjectLiteralType() { const indexInfos = []; - if (hasComputedStringProperty) indexInfos.push(getObjectLiteralIndexInfo(node, offset, propertiesArray, stringType)); - if (hasComputedNumberProperty) indexInfos.push(getObjectLiteralIndexInfo(node, offset, propertiesArray, numberType)); - if (hasComputedSymbolProperty) indexInfos.push(getObjectLiteralIndexInfo(node, offset, propertiesArray, esSymbolType)); - const result = createAnonymousType(node.symbol, propertiesTable, emptyArray, emptyArray, indexInfos); - result.objectFlags |= objectFlags | ObjectFlags.ObjectLiteral | ObjectFlags.ContainsObjectOrArrayLiteral; + if (hasComputedStringProperty) + indexInfos.push(getObjectLiteralIndexInfo(node, offset, propertiesArray, stringType)); + if (hasComputedNumberProperty) + indexInfos.push(getObjectLiteralIndexInfo(node, offset, propertiesArray, numberType)); + if (hasComputedSymbolProperty) + indexInfos.push(getObjectLiteralIndexInfo(node, offset, propertiesArray, esSymbolType)); + const result = createAnonymousType(node.symbol, propertiesTable, ts.emptyArray, ts.emptyArray, indexInfos); + result.objectFlags |= objectFlags | ts.ObjectFlags.ObjectLiteral | ts.ObjectFlags.ContainsObjectOrArrayLiteral; if (isJSObjectLiteral) { - result.objectFlags |= ObjectFlags.JSLiteral; + result.objectFlags |= ts.ObjectFlags.JSLiteral; } if (patternWithComputedProperties) { - result.objectFlags |= ObjectFlags.ObjectLiteralPatternWithComputedProperties; + result.objectFlags |= ts.ObjectFlags.ObjectLiteralPatternWithComputedProperties; } if (inDestructuringPattern) { result.pattern = node; @@ -27914,22 +27329,22 @@ namespace ts { } } - function isValidSpreadType(type: Type): boolean { + function isValidSpreadType(type: ts.Type): boolean { const t = removeDefinitelyFalsyTypes(mapType(type, getBaseConstraintOrType)); - return !!(t.flags & (TypeFlags.Any | TypeFlags.NonPrimitive | TypeFlags.Object | TypeFlags.InstantiableNonPrimitive) || - t.flags & TypeFlags.UnionOrIntersection && every((t as UnionOrIntersectionType).types, isValidSpreadType)); + return !!(t.flags & (ts.TypeFlags.Any | ts.TypeFlags.NonPrimitive | ts.TypeFlags.Object | ts.TypeFlags.InstantiableNonPrimitive) || + t.flags & ts.TypeFlags.UnionOrIntersection && ts.every((t as ts.UnionOrIntersectionType).types, isValidSpreadType)); } - function checkJsxSelfClosingElementDeferred(node: JsxSelfClosingElement) { + function checkJsxSelfClosingElementDeferred(node: ts.JsxSelfClosingElement) { checkJsxOpeningLikeElementOrOpeningFragment(node); } - function checkJsxSelfClosingElement(node: JsxSelfClosingElement, _checkMode: CheckMode | undefined): Type { + function checkJsxSelfClosingElement(node: ts.JsxSelfClosingElement, _checkMode: CheckMode | undefined): ts.Type { checkNodeDeferred(node); return getJsxElementTypeAt(node) || anyType; } - function checkJsxElementDeferred(node: JsxElement) { + function checkJsxElementDeferred(node: ts.JsxElement) { // Check attributes checkJsxOpeningLikeElementOrOpeningFragment(node.openingElement); @@ -27944,41 +27359,41 @@ namespace ts { checkJsxChildren(node); } - function checkJsxElement(node: JsxElement, _checkMode: CheckMode | undefined): Type { + function checkJsxElement(node: ts.JsxElement, _checkMode: CheckMode | undefined): ts.Type { checkNodeDeferred(node); return getJsxElementTypeAt(node) || anyType; } - function checkJsxFragment(node: JsxFragment): Type { + function checkJsxFragment(node: ts.JsxFragment): ts.Type { checkJsxOpeningLikeElementOrOpeningFragment(node.openingFragment); // by default, jsx:'react' will use jsxFactory = React.createElement and jsxFragmentFactory = React.Fragment // if jsxFactory compiler option is provided, ensure jsxFragmentFactory compiler option or @jsxFrag pragma is provided too - const nodeSourceFile = getSourceFileOfNode(node); - if (getJSXTransformEnabled(compilerOptions) && (compilerOptions.jsxFactory || nodeSourceFile.pragmas.has("jsx")) + const nodeSourceFile = ts.getSourceFileOfNode(node); + if (ts.getJSXTransformEnabled(compilerOptions) && (compilerOptions.jsxFactory || nodeSourceFile.pragmas.has("jsx")) && !compilerOptions.jsxFragmentFactory && !nodeSourceFile.pragmas.has("jsxfrag")) { error(node, compilerOptions.jsxFactory - ? Diagnostics.The_jsxFragmentFactory_compiler_option_must_be_provided_to_use_JSX_fragments_with_the_jsxFactory_compiler_option - : Diagnostics.An_jsxFrag_pragma_is_required_when_using_an_jsx_pragma_with_JSX_fragments); + ? ts.Diagnostics.The_jsxFragmentFactory_compiler_option_must_be_provided_to_use_JSX_fragments_with_the_jsxFactory_compiler_option + : ts.Diagnostics.An_jsxFrag_pragma_is_required_when_using_an_jsx_pragma_with_JSX_fragments); } checkJsxChildren(node); return getJsxElementTypeAt(node) || anyType; } - function isHyphenatedJsxName(name: string | __String) { - return stringContains(name as string, "-"); + function isHyphenatedJsxName(name: string | ts.__String) { + return ts.stringContains(name as string, "-"); } /** * Returns true iff React would emit this tag name as a string rather than an identifier or qualified name */ - function isJsxIntrinsicIdentifier(tagName: JsxTagNameExpression): boolean { - return tagName.kind === SyntaxKind.Identifier && isIntrinsicJsxName(tagName.escapedText); + function isJsxIntrinsicIdentifier(tagName: ts.JsxTagNameExpression): boolean { + return tagName.kind === ts.SyntaxKind.Identifier && ts.isIntrinsicJsxName(tagName.escapedText); } - function checkJsxAttribute(node: JsxAttribute, checkMode?: CheckMode) { + function checkJsxAttribute(node: ts.JsxAttribute, checkMode?: CheckMode) { return node.initializer ? checkExpressionForMutableLocation(node.initializer, checkMode) : trueType; // is sugar for @@ -27993,24 +27408,23 @@ namespace ts { * @remarks Because this function calls getSpreadType, it needs to use the same checks as checkObjectLiteral, * which also calls getSpreadType. */ - function createJsxAttributesTypeFromAttributesProperty(openingLikeElement: JsxOpeningLikeElement, checkMode: CheckMode | undefined) { + function createJsxAttributesTypeFromAttributesProperty(openingLikeElement: ts.JsxOpeningLikeElement, checkMode: CheckMode | undefined) { const attributes = openingLikeElement.attributes; - const allAttributesTable = strictNullChecks ? createSymbolTable() : undefined; - let attributesTable = createSymbolTable(); - let spread: Type = emptyJsxObjectType; + const allAttributesTable = strictNullChecks ? ts.createSymbolTable() : undefined; + let attributesTable = ts.createSymbolTable(); + let spread: ts.Type = emptyJsxObjectType; let hasSpreadAnyType = false; - let typeToIntersect: Type | undefined; + let typeToIntersect: ts.Type | undefined; let explicitlySpecifyChildrenAttribute = false; - let objectFlags: ObjectFlags = ObjectFlags.JsxAttributes; + let objectFlags: ts.ObjectFlags = ts.ObjectFlags.JsxAttributes; const jsxChildrenPropertyName = getJsxElementChildrenPropertyName(getJsxNamespaceAt(openingLikeElement)); for (const attributeDecl of attributes.properties) { const member = attributeDecl.symbol; - if (isJsxAttribute(attributeDecl)) { + if (ts.isJsxAttribute(attributeDecl)) { const exprType = checkJsxAttribute(attributeDecl, checkMode); - objectFlags |= getObjectFlags(exprType) & ObjectFlags.PropagatingFlags; - - const attributeSymbol = createSymbol(SymbolFlags.Property | member.flags, member.escapedName); + objectFlags |= ts.getObjectFlags(exprType) & ts.ObjectFlags.PropagatingFlags; + const attributeSymbol = createSymbol(ts.SymbolFlags.Property | member.flags, member.escapedName); attributeSymbol.declarations = member.declarations; attributeSymbol.parent = member.parent; if (member.valueDeclaration) { @@ -28025,10 +27439,10 @@ namespace ts { } } else { - Debug.assert(attributeDecl.kind === SyntaxKind.JsxSpreadAttribute); + ts.Debug.assert(attributeDecl.kind === ts.SyntaxKind.JsxSpreadAttribute); if (attributesTable.size > 0) { spread = getSpreadType(spread, createJsxAttributesType(), attributes.symbol, objectFlags, /*readonly*/ false); - attributesTable = createSymbolTable(); + attributesTable = ts.createSymbolTable(); } const exprType = getReducedType(checkExpressionCached(attributeDecl.expression, checkMode)); if (isTypeAny(exprType)) { @@ -28041,7 +27455,7 @@ namespace ts { } } else { - error(attributeDecl.expression, Diagnostics.Spread_types_may_only_be_created_from_object_types); + error(attributeDecl.expression, ts.Diagnostics.Spread_types_may_only_be_created_from_object_types); typeToIntersect = typeToIntersect ? getIntersectionType([typeToIntersect, exprType]) : exprType; } } @@ -28054,34 +27468,33 @@ namespace ts { } // Handle children attribute - const parent = openingLikeElement.parent.kind === SyntaxKind.JsxElement ? openingLikeElement.parent as JsxElement : undefined; + const parent = openingLikeElement.parent.kind === ts.SyntaxKind.JsxElement ? openingLikeElement.parent as ts.JsxElement : undefined; // We have to check that openingElement of the parent is the one we are visiting as this may not be true for selfClosingElement if (parent && parent.openingElement === openingLikeElement && parent.children.length > 0) { - const childrenTypes: Type[] = checkJsxChildren(parent, checkMode); + const childrenTypes: ts.Type[] = checkJsxChildren(parent, checkMode); if (!hasSpreadAnyType && jsxChildrenPropertyName && jsxChildrenPropertyName !== "") { // Error if there is a attribute named "children" explicitly specified and children element. // This is because children element will overwrite the value from attributes. // Note: we will not warn "children" attribute overwritten if "children" attribute is specified in object spread. if (explicitlySpecifyChildrenAttribute) { - error(attributes, Diagnostics._0_are_specified_twice_The_attribute_named_0_will_be_overwritten, unescapeLeadingUnderscores(jsxChildrenPropertyName)); + error(attributes, ts.Diagnostics._0_are_specified_twice_The_attribute_named_0_will_be_overwritten, ts.unescapeLeadingUnderscores(jsxChildrenPropertyName)); } const contextualType = getApparentTypeOfContextualType(openingLikeElement.attributes); const childrenContextualType = contextualType && getTypeOfPropertyOfContextualType(contextualType, jsxChildrenPropertyName); // If there are children in the body of JSX element, create dummy attribute "children" with the union of children types so that it will pass the attribute checking process - const childrenPropSymbol = createSymbol(SymbolFlags.Property, jsxChildrenPropertyName); + const childrenPropSymbol = createSymbol(ts.SymbolFlags.Property, jsxChildrenPropertyName); childrenPropSymbol.type = childrenTypes.length === 1 ? childrenTypes[0] : childrenContextualType && someType(childrenContextualType, isTupleLikeType) ? createTupleType(childrenTypes) : createArrayType(getUnionType(childrenTypes)); // Fake up a property declaration for the children - childrenPropSymbol.valueDeclaration = factory.createPropertySignature(/*modifiers*/ undefined, unescapeLeadingUnderscores(jsxChildrenPropertyName), /*questionToken*/ undefined, /*type*/ undefined); - setParent(childrenPropSymbol.valueDeclaration, attributes); + childrenPropSymbol.valueDeclaration = ts.factory.createPropertySignature(/*modifiers*/ undefined, ts.unescapeLeadingUnderscores(jsxChildrenPropertyName), /*questionToken*/ undefined, /*type*/ undefined); + ts.setParent(childrenPropSymbol.valueDeclaration, attributes); childrenPropSymbol.valueDeclaration.symbol = childrenPropSymbol; - const childPropMap = createSymbolTable(); + const childPropMap = ts.createSymbolTable(); childPropMap.set(jsxChildrenPropertyName, childrenPropSymbol); - spread = getSpreadType(spread, createAnonymousType(attributes.symbol, childPropMap, emptyArray, emptyArray, emptyArray), - attributes.symbol, objectFlags, /*readonly*/ false); + spread = getSpreadType(spread, createAnonymousType(attributes.symbol, childPropMap, ts.emptyArray, ts.emptyArray, ts.emptyArray), attributes.symbol, objectFlags, /*readonly*/ false); } } @@ -28101,23 +27514,23 @@ namespace ts { */ function createJsxAttributesType() { objectFlags |= freshObjectLiteralFlag; - const result = createAnonymousType(attributes.symbol, attributesTable, emptyArray, emptyArray, emptyArray); - result.objectFlags |= objectFlags | ObjectFlags.ObjectLiteral | ObjectFlags.ContainsObjectOrArrayLiteral; + const result = createAnonymousType(attributes.symbol, attributesTable, ts.emptyArray, ts.emptyArray, ts.emptyArray); + result.objectFlags |= objectFlags | ts.ObjectFlags.ObjectLiteral | ts.ObjectFlags.ContainsObjectOrArrayLiteral; return result; } } - function checkJsxChildren(node: JsxElement | JsxFragment, checkMode?: CheckMode) { - const childrenTypes: Type[] = []; + function checkJsxChildren(node: ts.JsxElement | ts.JsxFragment, checkMode?: CheckMode) { + const childrenTypes: ts.Type[] = []; for (const child of node.children) { // In React, JSX text that contains only whitespaces will be ignored so we don't want to type-check that // because then type of children property will have constituent of string type. - if (child.kind === SyntaxKind.JsxText) { + if (child.kind === ts.SyntaxKind.JsxText) { if (!child.containsOnlyTriviaWhiteSpaces) { childrenTypes.push(stringType); } } - else if (child.kind === SyntaxKind.JsxExpression && !child.expression) { + else if (child.kind === ts.SyntaxKind.JsxExpression && !child.expression) { continue; // empty jsx expressions don't *really* count as present children } else { @@ -28127,13 +27540,13 @@ namespace ts { return childrenTypes; } - function checkSpreadPropOverrides(type: Type, props: SymbolTable, spread: SpreadAssignment | JsxSpreadAttribute) { + function checkSpreadPropOverrides(type: ts.Type, props: ts.SymbolTable, spread: ts.SpreadAssignment | ts.JsxSpreadAttribute) { for (const right of getPropertiesOfType(type)) { - if (!(right.flags & SymbolFlags.Optional)) { + if (!(right.flags & ts.SymbolFlags.Optional)) { const left = props.get(right.escapedName); if (left) { - const diagnostic = error(left.valueDeclaration, Diagnostics._0_is_specified_more_than_once_so_this_usage_will_be_overwritten, unescapeLeadingUnderscores(left.escapedName)); - addRelatedInfo(diagnostic, createDiagnosticForNode(spread, Diagnostics.This_spread_always_overwrites_this_property)); + const diagnostic = error(left.valueDeclaration, ts.Diagnostics._0_is_specified_more_than_once_so_this_usage_will_be_overwritten, ts.unescapeLeadingUnderscores(left.escapedName)); + ts.addRelatedInfo(diagnostic, ts.createDiagnosticForNode(spread, ts.Diagnostics.This_spread_always_overwrites_this_property)); } } } @@ -28144,14 +27557,14 @@ namespace ts { * (See "checkApplicableSignatureForJsxOpeningLikeElement" for how the function is used) * @param node a JSXAttributes to be resolved of its type */ - function checkJsxAttributes(node: JsxAttributes, checkMode: CheckMode | undefined) { + function checkJsxAttributes(node: ts.JsxAttributes, checkMode: CheckMode | undefined) { return createJsxAttributesTypeFromAttributesProperty(node.parent, checkMode); } - function getJsxType(name: __String, location: Node | undefined) { + function getJsxType(name: ts.__String, location: ts.Node | undefined) { const namespace = getJsxNamespaceAt(location); const exports = namespace && getExportsOfSymbol(namespace); - const typeSymbol = exports && getSymbol(exports, name, SymbolFlags.Type); + const typeSymbol = exports && getSymbol(exports, name, ts.SymbolFlags.Type); return typeSymbol ? getDeclaredTypeOfSymbol(typeSymbol) : errorType; } @@ -28161,33 +27574,34 @@ namespace ts { * string index signature (in which case nodeLinks.jsxFlags will be IntrinsicIndexedElement). * May also return unknownSymbol if both of these lookups fail. */ - function getIntrinsicTagSymbol(node: JsxOpeningLikeElement | JsxClosingElement): Symbol { + function getIntrinsicTagSymbol(node: ts.JsxOpeningLikeElement | ts.JsxClosingElement): ts.Symbol { const links = getNodeLinks(node); if (!links.resolvedSymbol) { const intrinsicElementsType = getJsxType(JsxNames.IntrinsicElements, node); if (!isErrorType(intrinsicElementsType)) { // Property case - if (!isIdentifier(node.tagName)) return Debug.fail(); + if (!ts.isIdentifier(node.tagName)) + return ts.Debug.fail(); const intrinsicProp = getPropertyOfType(intrinsicElementsType, node.tagName.escapedText); if (intrinsicProp) { - links.jsxFlags |= JsxFlags.IntrinsicNamedElement; + links.jsxFlags |= ts.JsxFlags.IntrinsicNamedElement; return links.resolvedSymbol = intrinsicProp; } // Intrinsic string indexer case const indexSignatureType = getIndexTypeOfType(intrinsicElementsType, stringType); if (indexSignatureType) { - links.jsxFlags |= JsxFlags.IntrinsicIndexedElement; + links.jsxFlags |= ts.JsxFlags.IntrinsicIndexedElement; return links.resolvedSymbol = intrinsicElementsType.symbol; } // Wasn't found - error(node, Diagnostics.Property_0_does_not_exist_on_type_1, idText(node.tagName), "JSX." + JsxNames.IntrinsicElements); + error(node, ts.Diagnostics.Property_0_does_not_exist_on_type_1, ts.idText(node.tagName), "JSX." + JsxNames.IntrinsicElements); return links.resolvedSymbol = unknownSymbol; } else { if (noImplicitAny) { - error(node, Diagnostics.JSX_element_implicitly_has_type_any_because_no_interface_JSX_0_exists, unescapeLeadingUnderscores(JsxNames.IntrinsicElements)); + error(node, ts.Diagnostics.JSX_element_implicitly_has_type_any_because_no_interface_JSX_0_exists, ts.unescapeLeadingUnderscores(JsxNames.IntrinsicElements)); } return links.resolvedSymbol = unknownSymbol; } @@ -28195,8 +27609,8 @@ namespace ts { return links.resolvedSymbol; } - function getJsxNamespaceContainerForImplicitImport(location: Node | undefined): Symbol | undefined { - const file = location && getSourceFileOfNode(location); + function getJsxNamespaceContainerForImplicitImport(location: ts.Node | undefined): ts.Symbol | undefined { + const file = location && ts.getSourceFileOfNode(location); const links = file && getNodeLinks(file); if (links && links.jsxImplicitImportContainer === false) { return undefined; @@ -28204,14 +27618,14 @@ namespace ts { if (links && links.jsxImplicitImportContainer) { return links.jsxImplicitImportContainer; } - const runtimeImportSpecifier = getJSXRuntimeImport(getJSXImplicitImportBase(compilerOptions, file), compilerOptions); + const runtimeImportSpecifier = ts.getJSXRuntimeImport(ts.getJSXImplicitImportBase(compilerOptions, file), compilerOptions); if (!runtimeImportSpecifier) { return undefined; } - const isClassic = getEmitModuleResolutionKind(compilerOptions) === ModuleResolutionKind.Classic; + const isClassic = ts.getEmitModuleResolutionKind(compilerOptions) === ts.ModuleResolutionKind.Classic; const errorMessage = isClassic - ? Diagnostics.Cannot_find_module_0_Did_you_mean_to_set_the_moduleResolution_option_to_node_or_to_add_aliases_to_the_paths_option - : Diagnostics.Cannot_find_module_0_or_its_corresponding_type_declarations; + ? ts.Diagnostics.Cannot_find_module_0_Did_you_mean_to_set_the_moduleResolution_option_to_node_or_to_add_aliases_to_the_paths_option + : ts.Diagnostics.Cannot_find_module_0_or_its_corresponding_type_declarations; const mod = resolveExternalModule(location!, runtimeImportSpecifier, errorMessage, location!); const result = mod && mod !== unknownSymbol ? getMergedSymbol(resolveSymbol(mod)) : undefined; if (links) { @@ -28220,7 +27634,7 @@ namespace ts { return result; } - function getJsxNamespaceAt(location: Node | undefined): Symbol { + function getJsxNamespaceAt(location: ts.Node | undefined): ts.Symbol { const links = location && getNodeLinks(location); if (links && links.jsxNamespace) { return links.jsxNamespace; @@ -28230,11 +27644,11 @@ namespace ts { if (!resolvedNamespace || resolvedNamespace === unknownSymbol) { const namespaceName = getJsxNamespace(location); - resolvedNamespace = resolveName(location, namespaceName, SymbolFlags.Namespace, /*diagnosticMessage*/ undefined, namespaceName, /*isUse*/ false); + resolvedNamespace = resolveName(location, namespaceName, ts.SymbolFlags.Namespace, /*diagnosticMessage*/ undefined, namespaceName, /*isUse*/ false); } if (resolvedNamespace) { - const candidate = resolveSymbol(getSymbol(getExportsOfSymbol(resolveSymbol(resolvedNamespace)), JsxNames.JSX, SymbolFlags.Namespace)); + const candidate = resolveSymbol(getSymbol(getExportsOfSymbol(resolveSymbol(resolvedNamespace)), JsxNames.JSX, ts.SymbolFlags.Namespace)); if (candidate && candidate !== unknownSymbol) { if (links) { links.jsxNamespace = candidate; @@ -28247,7 +27661,7 @@ namespace ts { } } // JSX global fallback - const s = resolveSymbol(getGlobalSymbol(JsxNames.JSX, SymbolFlags.Namespace, /*diagnosticMessage*/ undefined)); + const s = resolveSymbol(getGlobalSymbol(JsxNames.JSX, ts.SymbolFlags.Namespace, /*diagnosticMessage*/ undefined)); if (s === unknownSymbol) { return undefined!; // TODO: GH#18217 } @@ -28261,9 +27675,9 @@ namespace ts { * @param nameOfAttribPropContainer a string of value JsxNames.ElementAttributesPropertyNameContainer or JsxNames.ElementChildrenAttributeNameContainer * if other string is given or the container doesn't exist, return undefined. */ - function getNameFromJsxElementAttributesContainer(nameOfAttribPropContainer: __String, jsxNamespace: Symbol): __String | undefined { + function getNameFromJsxElementAttributesContainer(nameOfAttribPropContainer: ts.__String, jsxNamespace: ts.Symbol): ts.__String | undefined { // JSX.ElementAttributesProperty | JSX.ElementChildrenAttribute [symbol] - const jsxElementAttribPropInterfaceSym = jsxNamespace && getSymbol(jsxNamespace.exports!, nameOfAttribPropContainer, SymbolFlags.Type); + const jsxElementAttribPropInterfaceSym = jsxNamespace && getSymbol(jsxNamespace.exports!, nameOfAttribPropContainer, ts.SymbolFlags.Type); // JSX.ElementAttributesProperty | JSX.ElementChildrenAttribute [type] const jsxElementAttribPropInterfaceType = jsxElementAttribPropInterfaceSym && getDeclaredTypeOfSymbol(jsxElementAttribPropInterfaceSym); // The properties of JSX.ElementAttributesProperty | JSX.ElementChildrenAttribute @@ -28271,7 +27685,7 @@ namespace ts { if (propertiesOfJsxElementAttribPropInterface) { // Element Attributes has zero properties, so the element attributes type will be the class instance type if (propertiesOfJsxElementAttribPropInterface.length === 0) { - return "" as __String; + return "" as ts.__String; } // Element Attributes has one property, so the element attributes type will be the type of the corresponding // property of the class instance type @@ -28280,15 +27694,15 @@ namespace ts { } else if (propertiesOfJsxElementAttribPropInterface.length > 1 && jsxElementAttribPropInterfaceSym.declarations) { // More than one property on ElementAttributesProperty is an error - error(jsxElementAttribPropInterfaceSym.declarations[0], Diagnostics.The_global_type_JSX_0_may_not_have_more_than_one_property, unescapeLeadingUnderscores(nameOfAttribPropContainer)); + error(jsxElementAttribPropInterfaceSym.declarations[0], ts.Diagnostics.The_global_type_JSX_0_may_not_have_more_than_one_property, ts.unescapeLeadingUnderscores(nameOfAttribPropContainer)); } } return undefined; } - function getJsxLibraryManagedAttributes(jsxNamespace: Symbol) { + function getJsxLibraryManagedAttributes(jsxNamespace: ts.Symbol) { // JSX.LibraryManagedAttributes [symbol] - return jsxNamespace && getSymbol(jsxNamespace.exports!, JsxNames.LibraryManagedAttributes, SymbolFlags.Type); + return jsxNamespace && getSymbol(jsxNamespace.exports!, JsxNames.LibraryManagedAttributes, ts.SymbolFlags.Type); } /// e.g. "props" for React.d.ts, @@ -28296,23 +27710,23 @@ namespace ts { /// non-intrinsic elements' attributes type is 'any'), /// or '' if it has 0 properties (which means every /// non-intrinsic elements' attributes type is the element instance type) - function getJsxElementPropertiesName(jsxNamespace: Symbol) { + function getJsxElementPropertiesName(jsxNamespace: ts.Symbol) { return getNameFromJsxElementAttributesContainer(JsxNames.ElementAttributesPropertyNameContainer, jsxNamespace); } - function getJsxElementChildrenPropertyName(jsxNamespace: Symbol): __String | undefined { + function getJsxElementChildrenPropertyName(jsxNamespace: ts.Symbol): ts.__String | undefined { return getNameFromJsxElementAttributesContainer(JsxNames.ElementChildrenAttributeNameContainer, jsxNamespace); } - function getUninstantiatedJsxSignaturesOfType(elementType: Type, caller: JsxOpeningLikeElement): readonly Signature[] { - if (elementType.flags & TypeFlags.String) { + function getUninstantiatedJsxSignaturesOfType(elementType: ts.Type, caller: ts.JsxOpeningLikeElement): readonly ts.Signature[] { + if (elementType.flags & ts.TypeFlags.String) { return [anySignature]; } - else if (elementType.flags & TypeFlags.StringLiteral) { - const intrinsicType = getIntrinsicAttributesTypeFromStringLiteralType(elementType as StringLiteralType, caller); + else if (elementType.flags & ts.TypeFlags.StringLiteral) { + const intrinsicType = getIntrinsicAttributesTypeFromStringLiteralType(elementType as ts.StringLiteralType, caller); if (!intrinsicType) { - error(caller, Diagnostics.Property_0_does_not_exist_on_type_1, (elementType as StringLiteralType).value, "JSX." + JsxNames.IntrinsicElements); - return emptyArray; + error(caller, ts.Diagnostics.Property_0_does_not_exist_on_type_1, (elementType as ts.StringLiteralType).value, "JSX." + JsxNames.IntrinsicElements); + return ts.emptyArray; } else { const fakeSignature = createSignatureForJSXIntrinsic(caller, intrinsicType); @@ -28321,19 +27735,19 @@ namespace ts { } const apparentElemType = getApparentType(elementType); // Resolve the signatures, preferring constructor - let signatures = getSignaturesOfType(apparentElemType, SignatureKind.Construct); + let signatures = getSignaturesOfType(apparentElemType, ts.SignatureKind.Construct); if (signatures.length === 0) { // No construct signatures, try call signatures - signatures = getSignaturesOfType(apparentElemType, SignatureKind.Call); + signatures = getSignaturesOfType(apparentElemType, ts.SignatureKind.Call); } - if (signatures.length === 0 && apparentElemType.flags & TypeFlags.Union) { + if (signatures.length === 0 && apparentElemType.flags & ts.TypeFlags.Union) { // If each member has some combination of new/call signatures; make a union signature list for those - signatures = getUnionSignatures(map((apparentElemType as UnionType).types, t => getUninstantiatedJsxSignaturesOfType(t, caller))); + signatures = getUnionSignatures(ts.map((apparentElemType as ts.UnionType).types, t => getUninstantiatedJsxSignaturesOfType(t, caller))); } return signatures; } - function getIntrinsicAttributesTypeFromStringLiteralType(type: StringLiteralType, location: Node): Type | undefined { + function getIntrinsicAttributesTypeFromStringLiteralType(type: ts.StringLiteralType, location: ts.Node): ts.Type | undefined { // If the elemType is a stringLiteral type, we can then provide a check to make sure that the string literal type is one of the Jsx intrinsic element type // For example: // var CustomTag: "h1" = "h1"; @@ -28341,7 +27755,7 @@ namespace ts { const intrinsicElementsType = getJsxType(JsxNames.IntrinsicElements, location); if (!isErrorType(intrinsicElementsType)) { const stringLiteralTypeName = type.value; - const intrinsicProp = getPropertyOfType(intrinsicElementsType, escapeLeadingUnderscores(stringLiteralTypeName)); + const intrinsicProp = getPropertyOfType(intrinsicElementsType, ts.escapeLeadingUnderscores(stringLiteralTypeName)); if (intrinsicProp) { return getTypeOfSymbol(intrinsicProp); } @@ -28355,18 +27769,18 @@ namespace ts { return anyType; } - function checkJsxReturnAssignableToAppropriateBound(refKind: JsxReferenceKind, elemInstanceType: Type, openingLikeElement: JsxOpeningLikeElement) { - if (refKind === JsxReferenceKind.Function) { + function checkJsxReturnAssignableToAppropriateBound(refKind: ts.JsxReferenceKind, elemInstanceType: ts.Type, openingLikeElement: ts.JsxOpeningLikeElement) { + if (refKind === ts.JsxReferenceKind.Function) { const sfcReturnConstraint = getJsxStatelessElementTypeAt(openingLikeElement); if (sfcReturnConstraint) { - checkTypeRelatedTo(elemInstanceType, sfcReturnConstraint, assignableRelation, openingLikeElement.tagName, Diagnostics.Its_return_type_0_is_not_a_valid_JSX_element, generateInitialErrorChain); + checkTypeRelatedTo(elemInstanceType, sfcReturnConstraint, assignableRelation, openingLikeElement.tagName, ts.Diagnostics.Its_return_type_0_is_not_a_valid_JSX_element, generateInitialErrorChain); } } - else if (refKind === JsxReferenceKind.Component) { + else if (refKind === ts.JsxReferenceKind.Component) { const classConstraint = getJsxElementClassTypeAt(openingLikeElement); if (classConstraint) { // Issue an error if this return type isn't assignable to JSX.ElementClass, failing that - checkTypeRelatedTo(elemInstanceType, classConstraint, assignableRelation, openingLikeElement.tagName, Diagnostics.Its_instance_type_0_is_not_a_valid_JSX_element, generateInitialErrorChain); + checkTypeRelatedTo(elemInstanceType, classConstraint, assignableRelation, openingLikeElement.tagName, ts.Diagnostics.Its_instance_type_0_is_not_a_valid_JSX_element, generateInitialErrorChain); } } else { // Mixed @@ -28376,12 +27790,12 @@ namespace ts { return; } const combined = getUnionType([sfcReturnConstraint, classConstraint]); - checkTypeRelatedTo(elemInstanceType, combined, assignableRelation, openingLikeElement.tagName, Diagnostics.Its_element_type_0_is_not_a_valid_JSX_element, generateInitialErrorChain); + checkTypeRelatedTo(elemInstanceType, combined, assignableRelation, openingLikeElement.tagName, ts.Diagnostics.Its_element_type_0_is_not_a_valid_JSX_element, generateInitialErrorChain); } - function generateInitialErrorChain(): DiagnosticMessageChain { - const componentName = getTextOfNode(openingLikeElement.tagName); - return chainDiagnosticMessages(/* details */ undefined, Diagnostics._0_cannot_be_used_as_a_JSX_component, componentName); + function generateInitialErrorChain(): ts.DiagnosticMessageChain { + const componentName = ts.getTextOfNode(openingLikeElement.tagName); + return ts.chainDiagnosticMessages(/* details */ undefined, ts.Diagnostics._0_cannot_be_used_as_a_JSX_component, componentName); } } @@ -28390,15 +27804,15 @@ namespace ts { * The function is intended to be called from a function which has checked that the opening element is an intrinsic element. * @param node an intrinsic JSX opening-like element */ - function getIntrinsicAttributesTypeFromJsxOpeningLikeElement(node: JsxOpeningLikeElement): Type { - Debug.assert(isJsxIntrinsicIdentifier(node.tagName)); + function getIntrinsicAttributesTypeFromJsxOpeningLikeElement(node: ts.JsxOpeningLikeElement): ts.Type { + ts.Debug.assert(isJsxIntrinsicIdentifier(node.tagName)); const links = getNodeLinks(node); if (!links.resolvedJsxElementAttributesType) { const symbol = getIntrinsicTagSymbol(node); - if (links.jsxFlags & JsxFlags.IntrinsicNamedElement) { + if (links.jsxFlags & ts.JsxFlags.IntrinsicNamedElement) { return links.resolvedJsxElementAttributesType = getTypeOfSymbol(symbol) || errorType; } - else if (links.jsxFlags & JsxFlags.IntrinsicIndexedElement) { + else if (links.jsxFlags & ts.JsxFlags.IntrinsicIndexedElement) { return links.resolvedJsxElementAttributesType = getIndexTypeOfType(getJsxType(JsxNames.IntrinsicElements, node), stringType) || errorType; } @@ -28409,17 +27823,18 @@ namespace ts { return links.resolvedJsxElementAttributesType; } - function getJsxElementClassTypeAt(location: Node): Type | undefined { + function getJsxElementClassTypeAt(location: ts.Node): ts.Type | undefined { const type = getJsxType(JsxNames.ElementClass, location); - if (isErrorType(type)) return undefined; + if (isErrorType(type)) + return undefined; return type; } - function getJsxElementTypeAt(location: Node): Type { + function getJsxElementTypeAt(location: ts.Node): ts.Type { return getJsxType(JsxNames.Element, location); } - function getJsxStatelessElementTypeAt(location: Node): Type | undefined { + function getJsxStatelessElementTypeAt(location: ts.Node): ts.Type | undefined { const jsxElementType = getJsxElementTypeAt(location); if (jsxElementType) { return getUnionType([jsxElementType, nullType]); @@ -28429,26 +27844,26 @@ namespace ts { /** * Returns all the properties of the Jsx.IntrinsicElements interface */ - function getJsxIntrinsicTagNamesAt(location: Node): Symbol[] { + function getJsxIntrinsicTagNamesAt(location: ts.Node): ts.Symbol[] { const intrinsics = getJsxType(JsxNames.IntrinsicElements, location); - return intrinsics ? getPropertiesOfType(intrinsics) : emptyArray; + return intrinsics ? getPropertiesOfType(intrinsics) : ts.emptyArray; } - function checkJsxPreconditions(errorNode: Node) { + function checkJsxPreconditions(errorNode: ts.Node) { // Preconditions for using JSX - if ((compilerOptions.jsx || JsxEmit.None) === JsxEmit.None) { - error(errorNode, Diagnostics.Cannot_use_JSX_unless_the_jsx_flag_is_provided); + if ((compilerOptions.jsx || ts.JsxEmit.None) === ts.JsxEmit.None) { + error(errorNode, ts.Diagnostics.Cannot_use_JSX_unless_the_jsx_flag_is_provided); } if (getJsxElementTypeAt(errorNode) === undefined) { if (noImplicitAny) { - error(errorNode, Diagnostics.JSX_element_implicitly_has_type_any_because_the_global_type_JSX_Element_does_not_exist); + error(errorNode, ts.Diagnostics.JSX_element_implicitly_has_type_any_because_the_global_type_JSX_Element_does_not_exist); } } } - function checkJsxOpeningLikeElementOrOpeningFragment(node: JsxOpeningLikeElement | JsxOpeningFragment) { - const isNodeOpeningLikeElement = isJsxOpeningLikeElement(node); + function checkJsxOpeningLikeElementOrOpeningFragment(node: ts.JsxOpeningLikeElement | ts.JsxOpeningFragment) { + const isNodeOpeningLikeElement = ts.isJsxOpeningLikeElement(node); if (isNodeOpeningLikeElement) { checkGrammarJsxElement(node); @@ -28459,33 +27874,33 @@ namespace ts { if (!getJsxNamespaceContainerForImplicitImport(node)) { // The reactNamespace/jsxFactory's root symbol should be marked as 'used' so we don't incorrectly elide its import. // And if there is no reactNamespace/jsxFactory's symbol in scope when targeting React emit, we should issue an error. - const jsxFactoryRefErr = diagnostics && compilerOptions.jsx === JsxEmit.React ? Diagnostics.Cannot_find_name_0 : undefined; + const jsxFactoryRefErr = diagnostics && compilerOptions.jsx === ts.JsxEmit.React ? ts.Diagnostics.Cannot_find_name_0 : undefined; const jsxFactoryNamespace = getJsxNamespace(node); const jsxFactoryLocation = isNodeOpeningLikeElement ? node.tagName : node; // allow null as jsxFragmentFactory - let jsxFactorySym: Symbol | undefined; - if (!(isJsxOpeningFragment(node) && jsxFactoryNamespace === "null")) { - jsxFactorySym = resolveName(jsxFactoryLocation, jsxFactoryNamespace, SymbolFlags.Value, jsxFactoryRefErr, jsxFactoryNamespace, /*isUse*/ true); + let jsxFactorySym: ts.Symbol | undefined; + if (!(ts.isJsxOpeningFragment(node) && jsxFactoryNamespace === "null")) { + jsxFactorySym = resolveName(jsxFactoryLocation, jsxFactoryNamespace, ts.SymbolFlags.Value, jsxFactoryRefErr, jsxFactoryNamespace, /*isUse*/ true); } if (jsxFactorySym) { // Mark local symbol as referenced here because it might not have been marked // if jsx emit was not jsxFactory as there wont be error being emitted - jsxFactorySym.isReferenced = SymbolFlags.All; + jsxFactorySym.isReferenced = ts.SymbolFlags.All; // If react/jsxFactory symbol is alias, mark it as refereced - if (jsxFactorySym.flags & SymbolFlags.Alias && !getTypeOnlyAliasDeclaration(jsxFactorySym)) { + if (jsxFactorySym.flags & ts.SymbolFlags.Alias && !getTypeOnlyAliasDeclaration(jsxFactorySym)) { markAliasSymbolAsReferenced(jsxFactorySym); } } // For JsxFragment, mark jsx pragma as referenced via resolveName - if (isJsxOpeningFragment(node)) { - const file = getSourceFileOfNode(node); + if (ts.isJsxOpeningFragment(node)) { + const file = ts.getSourceFileOfNode(node); const localJsxNamespace = getLocalJsxNamespace(file); if (localJsxNamespace) { - resolveName(jsxFactoryLocation, localJsxNamespace, SymbolFlags.Value, jsxFactoryRefErr, localJsxNamespace, /*isUse*/ true); + resolveName(jsxFactoryLocation, localJsxNamespace, ts.SymbolFlags.Value, jsxFactoryRefErr, localJsxNamespace, /*isUse*/ true); } } } @@ -28511,8 +27926,8 @@ namespace ts { * @param name a property name to search * @param isComparingJsxAttributes a boolean flag indicating whether we are searching in JsxAttributesType */ - function isKnownProperty(targetType: Type, name: __String, isComparingJsxAttributes: boolean): boolean { - if (targetType.flags & TypeFlags.Object) { + function isKnownProperty(targetType: ts.Type, name: ts.__String, isComparingJsxAttributes: boolean): boolean { + if (targetType.flags & ts.TypeFlags.Object) { // For backwards compatibility a symbol-named property is satisfied by a string index signature. This // is incorrect and inconsistent with element access expressions, where it is an error, so eventually // we should remove this exception. @@ -28524,8 +27939,8 @@ namespace ts { return true; } } - else if (targetType.flags & TypeFlags.UnionOrIntersection && isExcessPropertyCheckTarget(targetType)) { - for (const t of (targetType as UnionOrIntersectionType).types) { + else if (targetType.flags & ts.TypeFlags.UnionOrIntersection && isExcessPropertyCheckTarget(targetType)) { + for (const t of (targetType as ts.UnionOrIntersectionType).types) { if (isKnownProperty(t, name, isComparingJsxAttributes)) { return true; } @@ -28534,19 +27949,19 @@ namespace ts { return false; } - function isExcessPropertyCheckTarget(type: Type): boolean { - return !!(type.flags & TypeFlags.Object && !(getObjectFlags(type) & ObjectFlags.ObjectLiteralPatternWithComputedProperties) || - type.flags & TypeFlags.NonPrimitive || - type.flags & TypeFlags.Union && some((type as UnionType).types, isExcessPropertyCheckTarget) || - type.flags & TypeFlags.Intersection && every((type as IntersectionType).types, isExcessPropertyCheckTarget)); + function isExcessPropertyCheckTarget(type: ts.Type): boolean { + return !!(type.flags & ts.TypeFlags.Object && !(ts.getObjectFlags(type) & ts.ObjectFlags.ObjectLiteralPatternWithComputedProperties) || + type.flags & ts.TypeFlags.NonPrimitive || + type.flags & ts.TypeFlags.Union && ts.some((type as ts.UnionType).types, isExcessPropertyCheckTarget) || + type.flags & ts.TypeFlags.Intersection && ts.every((type as ts.IntersectionType).types, isExcessPropertyCheckTarget)); } - function checkJsxExpression(node: JsxExpression, checkMode?: CheckMode) { + function checkJsxExpression(node: ts.JsxExpression, checkMode?: CheckMode) { checkGrammarJsxExpression(node); if (node.expression) { const type = checkExpression(node.expression, checkMode); if (node.dotDotDotToken && type !== anyType && !isArrayType(type)) { - error(node, Diagnostics.JSX_spread_child_must_be_an_array_type); + error(node, ts.Diagnostics.JSX_spread_child_must_be_an_array_type); } return type; } @@ -28555,22 +27970,22 @@ namespace ts { } } - function getDeclarationNodeFlagsFromSymbol(s: Symbol): NodeFlags { - return s.valueDeclaration ? getCombinedNodeFlags(s.valueDeclaration) : 0; + function getDeclarationNodeFlagsFromSymbol(s: ts.Symbol): ts.NodeFlags { + return s.valueDeclaration ? ts.getCombinedNodeFlags(s.valueDeclaration) : 0; } /** * Return whether this symbol is a member of a prototype somewhere * Note that this is not tracked well within the compiler, so the answer may be incorrect. */ - function isPrototypeProperty(symbol: Symbol) { - if (symbol.flags & SymbolFlags.Method || getCheckFlags(symbol) & CheckFlags.SyntheticMethod) { + function isPrototypeProperty(symbol: ts.Symbol) { + if (symbol.flags & ts.SymbolFlags.Method || ts.getCheckFlags(symbol) & ts.CheckFlags.SyntheticMethod) { return true; } - if (isInJSFile(symbol.valueDeclaration)) { + if (ts.isInJSFile(symbol.valueDeclaration)) { const parent = symbol.valueDeclaration!.parent; - return parent && isBinaryExpression(parent) && - getAssignmentDeclarationKind(parent) === AssignmentDeclarationKind.PrototypeProperty; + return parent && ts.isBinaryExpression(parent) && + ts.getAssignmentDeclarationKind(parent) === ts.AssignmentDeclarationKind.PrototypeProperty; } } @@ -28582,14 +27997,12 @@ namespace ts { * @param type The type of the object whose property is being accessed. (Not the type of the property.) * @param prop The symbol for the property being accessed. */ - function checkPropertyAccessibility( - node: PropertyAccessExpression | QualifiedName | PropertyAccessExpression | VariableDeclaration | ParameterDeclaration | ImportTypeNode | PropertyAssignment | ShorthandPropertyAssignment | BindingElement, - isSuper: boolean, writing: boolean, type: Type, prop: Symbol, reportError = true): boolean { + function checkPropertyAccessibility(node: ts.PropertyAccessExpression | ts.QualifiedName | ts.PropertyAccessExpression | ts.VariableDeclaration | ts.ParameterDeclaration | ts.ImportTypeNode | ts.PropertyAssignment | ts.ShorthandPropertyAssignment | ts.BindingElement, isSuper: boolean, writing: boolean, type: ts.Type, prop: ts.Symbol, reportError = true): boolean { const errorNode = !reportError ? undefined : - node.kind === SyntaxKind.QualifiedName ? node.right : - node.kind === SyntaxKind.ImportType ? node : - node.kind === SyntaxKind.BindingElement && node.propertyName ? node.propertyName : node.name; + node.kind === ts.SyntaxKind.QualifiedName ? node.right : + node.kind === ts.SyntaxKind.ImportType ? node : + node.kind === ts.SyntaxKind.BindingElement && node.propertyName ? node.propertyName : node.name; return checkPropertyAccessibilityAtLocation(node, isSuper, writing, type, prop, errorNode); } @@ -28604,11 +28017,8 @@ namespace ts { * @param prop The symbol for the property being accessed. * @param errorNode The node where we should report an invalid property access error, or undefined if we should not report errors. */ - function checkPropertyAccessibilityAtLocation(location: Node, - isSuper: boolean, writing: boolean, - containingType: Type, prop: Symbol, errorNode?: Node): boolean { - - const flags = getDeclarationModifierFlagsFromSymbol(prop, writing); + function checkPropertyAccessibilityAtLocation(location: ts.Node, isSuper: boolean, writing: boolean, containingType: ts.Type, prop: ts.Symbol, errorNode?: ts.Node): boolean { + const flags = ts.getDeclarationModifierFlagsFromSymbol(prop, writing); if (isSuper) { // TS 1.0 spec (April 2014): 4.8.2 @@ -28618,60 +28028,51 @@ namespace ts { // - In a static member function or static member accessor // where this references the constructor function object of a derived class, // a super property access is permitted and must specify a public static member function of the base class. - if (languageVersion < ScriptTarget.ES2015) { + if (languageVersion < ts.ScriptTarget.ES2015) { if (symbolHasNonMethodDeclaration(prop)) { if (errorNode) { - error(errorNode, Diagnostics.Only_public_and_protected_methods_of_the_base_class_are_accessible_via_the_super_keyword); + error(errorNode, ts.Diagnostics.Only_public_and_protected_methods_of_the_base_class_are_accessible_via_the_super_keyword); } return false; } } - if (flags & ModifierFlags.Abstract) { + if (flags & ts.ModifierFlags.Abstract) { // A method cannot be accessed in a super property access if the method is abstract. // This error could mask a private property access error. But, a member // cannot simultaneously be private and abstract, so this will trigger an // additional error elsewhere. if (errorNode) { - error(errorNode, - Diagnostics.Abstract_method_0_in_class_1_cannot_be_accessed_via_super_expression, - symbolToString(prop), - typeToString(getDeclaringClass(prop)!)); + error(errorNode, ts.Diagnostics.Abstract_method_0_in_class_1_cannot_be_accessed_via_super_expression, symbolToString(prop), typeToString(getDeclaringClass(prop)!)); } return false; } } // Referencing abstract properties within their own constructors is not allowed - if ((flags & ModifierFlags.Abstract) && symbolHasNonMethodDeclaration(prop) && - (isThisProperty(location) || isThisInitializedObjectBindingExpression(location) || isObjectBindingPattern(location.parent) && isThisInitializedDeclaration(location.parent.parent))) { - const declaringClassDeclaration = getClassLikeDeclarationOfSymbol(getParentOfSymbol(prop)!); + if ((flags & ts.ModifierFlags.Abstract) && symbolHasNonMethodDeclaration(prop) && + (ts.isThisProperty(location) || ts.isThisInitializedObjectBindingExpression(location) || ts.isObjectBindingPattern(location.parent) && ts.isThisInitializedDeclaration(location.parent.parent))) { + const declaringClassDeclaration = ts.getClassLikeDeclarationOfSymbol(getParentOfSymbol(prop)!); if (declaringClassDeclaration && isNodeUsedDuringClassInitialization(location)) { if (errorNode) { - error(errorNode, - Diagnostics.Abstract_property_0_in_class_1_cannot_be_accessed_in_the_constructor, - symbolToString(prop), - getTextOfIdentifierOrLiteral(declaringClassDeclaration.name!)); + error(errorNode, ts.Diagnostics.Abstract_property_0_in_class_1_cannot_be_accessed_in_the_constructor, symbolToString(prop), ts.getTextOfIdentifierOrLiteral(declaringClassDeclaration.name!)); } return false; } } // Public properties are otherwise accessible. - if (!(flags & ModifierFlags.NonPublicAccessibilityModifier)) { + if (!(flags & ts.ModifierFlags.NonPublicAccessibilityModifier)) { return true; } // Property is known to be private or protected at this point // Private property is accessible if the property is within the declaring class - if (flags & ModifierFlags.Private) { - const declaringClassDeclaration = getClassLikeDeclarationOfSymbol(getParentOfSymbol(prop)!)!; + if (flags & ts.ModifierFlags.Private) { + const declaringClassDeclaration = ts.getClassLikeDeclarationOfSymbol(getParentOfSymbol(prop)!)!; if (!isNodeWithinClass(location, declaringClassDeclaration)) { if (errorNode) { - error(errorNode, - Diagnostics.Property_0_is_private_and_only_accessible_within_class_1, - symbolToString(prop), - typeToString(getDeclaringClass(prop)!)); + error(errorNode, ts.Diagnostics.Property_0_is_private_and_only_accessible_within_class_1, symbolToString(prop), typeToString(getDeclaringClass(prop)!)); } return false; } @@ -28688,7 +28089,7 @@ namespace ts { // Find the first enclosing class that has the declaring classes of the protected constituents // of the property as base classes let enclosingClass = forEachEnclosingClass(location, enclosingDeclaration => { - const enclosingClass = getDeclaredTypeOfSymbol(getSymbolOfNode(enclosingDeclaration)!) as InterfaceType; + const enclosingClass = getDeclaredTypeOfSymbol(getSymbolOfNode(enclosingDeclaration)!) as ts.InterfaceType; return isClassDerivedFromDeclaringClasses(enclosingClass, prop, writing); }); // A protected property is accessible if the property is within the declaring class or classes derived from it @@ -28697,142 +28098,129 @@ namespace ts { // static member access is disallowed enclosingClass = getEnclosingClassFromThisParameter(location); enclosingClass = enclosingClass && isClassDerivedFromDeclaringClasses(enclosingClass, prop, writing); - if (flags & ModifierFlags.Static || !enclosingClass) { + if (flags & ts.ModifierFlags.Static || !enclosingClass) { if (errorNode) { - error(errorNode, - Diagnostics.Property_0_is_protected_and_only_accessible_within_class_1_and_its_subclasses, - symbolToString(prop), - typeToString(getDeclaringClass(prop) || containingType)); + error(errorNode, ts.Diagnostics.Property_0_is_protected_and_only_accessible_within_class_1_and_its_subclasses, symbolToString(prop), typeToString(getDeclaringClass(prop) || containingType)); } return false; } } // No further restrictions for static properties - if (flags & ModifierFlags.Static) { + if (flags & ts.ModifierFlags.Static) { return true; } - if (containingType.flags & TypeFlags.TypeParameter) { + if (containingType.flags & ts.TypeFlags.TypeParameter) { // get the original type -- represented as the type constraint of the 'this' type - containingType = (containingType as TypeParameter).isThisType ? getConstraintOfTypeParameter(containingType as TypeParameter)! : getBaseConstraintOfType(containingType as TypeParameter)!; // TODO: GH#18217 Use a different variable that's allowed to be undefined + containingType = (containingType as ts.TypeParameter).isThisType ? getConstraintOfTypeParameter(containingType as ts.TypeParameter)! : getBaseConstraintOfType(containingType as ts.TypeParameter)!; // TODO: GH#18217 Use a different variable that's allowed to be undefined } if (!containingType || !hasBaseType(containingType, enclosingClass)) { if (errorNode) { - error(errorNode, - Diagnostics.Property_0_is_protected_and_only_accessible_through_an_instance_of_class_1_This_is_an_instance_of_class_2, - symbolToString(prop), typeToString(enclosingClass), typeToString(containingType)); + error(errorNode, ts.Diagnostics.Property_0_is_protected_and_only_accessible_through_an_instance_of_class_1_This_is_an_instance_of_class_2, symbolToString(prop), typeToString(enclosingClass), typeToString(containingType)); } return false; } return true; } - function getEnclosingClassFromThisParameter(node: Node): InterfaceType | undefined { + function getEnclosingClassFromThisParameter(node: ts.Node): ts.InterfaceType | undefined { const thisParameter = getThisParameterFromNodeContext(node); let thisType = thisParameter?.type && getTypeFromTypeNode(thisParameter.type); - if (thisType && thisType.flags & TypeFlags.TypeParameter) { - thisType = getConstraintOfTypeParameter(thisType as TypeParameter); + if (thisType && thisType.flags & ts.TypeFlags.TypeParameter) { + thisType = getConstraintOfTypeParameter(thisType as ts.TypeParameter); } - if (thisType && getObjectFlags(thisType) & (ObjectFlags.ClassOrInterface | ObjectFlags.Reference)) { - return getTargetType(thisType) as InterfaceType; + if (thisType && ts.getObjectFlags(thisType) & (ts.ObjectFlags.ClassOrInterface | ts.ObjectFlags.Reference)) { + return getTargetType(thisType) as ts.InterfaceType; } return undefined; } - function getThisParameterFromNodeContext(node: Node) { - const thisContainer = getThisContainer(node, /* includeArrowFunctions */ false); - return thisContainer && isFunctionLike(thisContainer) ? getThisParameter(thisContainer) : undefined; + function getThisParameterFromNodeContext(node: ts.Node) { + const thisContainer = ts.getThisContainer(node, /* includeArrowFunctions */ false); + return thisContainer && ts.isFunctionLike(thisContainer) ? ts.getThisParameter(thisContainer) : undefined; } - function symbolHasNonMethodDeclaration(symbol: Symbol) { - return !!forEachProperty(symbol, prop => !(prop.flags & SymbolFlags.Method)); + function symbolHasNonMethodDeclaration(symbol: ts.Symbol) { + return !!forEachProperty(symbol, prop => !(prop.flags & ts.SymbolFlags.Method)); } - function checkNonNullExpression(node: Expression | QualifiedName) { + function checkNonNullExpression(node: ts.Expression | ts.QualifiedName) { return checkNonNullType(checkExpression(node), node); } - function isNullableType(type: Type) { - return !!((strictNullChecks ? getFalsyFlags(type) : type.flags) & TypeFlags.Nullable); + function isNullableType(type: ts.Type) { + return !!((strictNullChecks ? getFalsyFlags(type) : type.flags) & ts.TypeFlags.Nullable); } - function getNonNullableTypeIfNeeded(type: Type) { + function getNonNullableTypeIfNeeded(type: ts.Type) { return isNullableType(type) ? getNonNullableType(type) : type; } - function reportObjectPossiblyNullOrUndefinedError(node: Node, flags: TypeFlags) { - error(node, flags & TypeFlags.Undefined ? flags & TypeFlags.Null ? - Diagnostics.Object_is_possibly_null_or_undefined : - Diagnostics.Object_is_possibly_undefined : - Diagnostics.Object_is_possibly_null - ); + function reportObjectPossiblyNullOrUndefinedError(node: ts.Node, flags: ts.TypeFlags) { + error(node, flags & ts.TypeFlags.Undefined ? flags & ts.TypeFlags.Null ? + ts.Diagnostics.Object_is_possibly_null_or_undefined : + ts.Diagnostics.Object_is_possibly_undefined : + ts.Diagnostics.Object_is_possibly_null); } - - function reportCannotInvokePossiblyNullOrUndefinedError(node: Node, flags: TypeFlags) { - error(node, flags & TypeFlags.Undefined ? flags & TypeFlags.Null ? - Diagnostics.Cannot_invoke_an_object_which_is_possibly_null_or_undefined : - Diagnostics.Cannot_invoke_an_object_which_is_possibly_undefined : - Diagnostics.Cannot_invoke_an_object_which_is_possibly_null - ); + function reportCannotInvokePossiblyNullOrUndefinedError(node: ts.Node, flags: ts.TypeFlags) { + error(node, flags & ts.TypeFlags.Undefined ? flags & ts.TypeFlags.Null ? + ts.Diagnostics.Cannot_invoke_an_object_which_is_possibly_null_or_undefined : + ts.Diagnostics.Cannot_invoke_an_object_which_is_possibly_undefined : + ts.Diagnostics.Cannot_invoke_an_object_which_is_possibly_null); } - - function checkNonNullTypeWithReporter( - type: Type, - node: Node, - reportError: (node: Node, kind: TypeFlags) => void - ): Type { - if (strictNullChecks && type.flags & TypeFlags.Unknown) { - error(node, Diagnostics.Object_is_of_type_unknown); + function checkNonNullTypeWithReporter(type: ts.Type, node: ts.Node, reportError: (node: ts.Node, kind: ts.TypeFlags) => void): ts.Type { + if (strictNullChecks && type.flags & ts.TypeFlags.Unknown) { + error(node, ts.Diagnostics.Object_is_of_type_unknown); return errorType; } - const kind = (strictNullChecks ? getFalsyFlags(type) : type.flags) & TypeFlags.Nullable; + const kind = (strictNullChecks ? getFalsyFlags(type) : type.flags) & ts.TypeFlags.Nullable; if (kind) { reportError(node, kind); const t = getNonNullableType(type); - return t.flags & (TypeFlags.Nullable | TypeFlags.Never) ? errorType : t; + return t.flags & (ts.TypeFlags.Nullable | ts.TypeFlags.Never) ? errorType : t; } return type; } - function checkNonNullType(type: Type, node: Node) { + function checkNonNullType(type: ts.Type, node: ts.Node) { return checkNonNullTypeWithReporter(type, node, reportObjectPossiblyNullOrUndefinedError); } - function checkNonNullNonVoidType(type: Type, node: Node): Type { + function checkNonNullNonVoidType(type: ts.Type, node: ts.Node): ts.Type { const nonNullType = checkNonNullType(type, node); - if (nonNullType.flags & TypeFlags.Void) { - error(node, Diagnostics.Object_is_possibly_undefined); + if (nonNullType.flags & ts.TypeFlags.Void) { + error(node, ts.Diagnostics.Object_is_possibly_undefined); } return nonNullType; } - function checkPropertyAccessExpression(node: PropertyAccessExpression, checkMode: CheckMode | undefined) { - return node.flags & NodeFlags.OptionalChain ? checkPropertyAccessChain(node as PropertyAccessChain, checkMode) : + function checkPropertyAccessExpression(node: ts.PropertyAccessExpression, checkMode: CheckMode | undefined) { + return node.flags & ts.NodeFlags.OptionalChain ? checkPropertyAccessChain(node as ts.PropertyAccessChain, checkMode) : checkPropertyAccessExpressionOrQualifiedName(node, node.expression, checkNonNullExpression(node.expression), node.name, checkMode); } - function checkPropertyAccessChain(node: PropertyAccessChain, checkMode: CheckMode | undefined) { + function checkPropertyAccessChain(node: ts.PropertyAccessChain, checkMode: CheckMode | undefined) { const leftType = checkExpression(node.expression); const nonOptionalType = getOptionalExpressionType(leftType, node.expression); return propagateOptionalTypeMarker(checkPropertyAccessExpressionOrQualifiedName(node, node.expression, checkNonNullType(nonOptionalType, node.expression), node.name, checkMode), node, nonOptionalType !== leftType); } - function checkQualifiedName(node: QualifiedName, checkMode: CheckMode | undefined) { - const leftType = isPartOfTypeQuery(node) && isThisIdentifier(node.left) ? checkNonNullType(checkThisExpression(node.left), node.left) : checkNonNullExpression(node.left); + function checkQualifiedName(node: ts.QualifiedName, checkMode: CheckMode | undefined) { + const leftType = ts.isPartOfTypeQuery(node) && ts.isThisIdentifier(node.left) ? checkNonNullType(checkThisExpression(node.left), node.left) : checkNonNullExpression(node.left); return checkPropertyAccessExpressionOrQualifiedName(node, node.left, leftType, node.right, checkMode); } - function isMethodAccessForCall(node: Node) { - while (node.parent.kind === SyntaxKind.ParenthesizedExpression) { + function isMethodAccessForCall(node: ts.Node) { + while (node.parent.kind === ts.SyntaxKind.ParenthesizedExpression) { node = node.parent; } - return isCallOrNewExpression(node.parent) && node.parent.expression === node; + return ts.isCallOrNewExpression(node.parent) && node.parent.expression === node; } // Lookup the private identifier lexically. - function lookupSymbolForPrivateIdentifierDeclaration(propName: __String, location: Node): Symbol | undefined { - for (let containingClass = getContainingClass(location); !!containingClass; containingClass = getContainingClass(containingClass)) { + function lookupSymbolForPrivateIdentifierDeclaration(propName: ts.__String, location: ts.Node): ts.Symbol | undefined { + for (let containingClass = ts.getContainingClass(location); !!containingClass; containingClass = ts.getContainingClass(containingClass)) { const { symbol } = containingClass; - const name = getSymbolNameForPrivateIdentifier(symbol, propName); + const name = ts.getSymbolNameForPrivateIdentifier(symbol, propName); const prop = (symbol.members && symbol.members.get(name)) || (symbol.exports && symbol.exports.get(name)); if (prop) { return prop; @@ -28840,26 +28228,26 @@ namespace ts { } } - function checkGrammarPrivateIdentifierExpression(privId: PrivateIdentifier): boolean { - if (!getContainingClass(privId)) { - return grammarErrorOnNode(privId, Diagnostics.Private_identifiers_are_not_allowed_outside_class_bodies); + function checkGrammarPrivateIdentifierExpression(privId: ts.PrivateIdentifier): boolean { + if (!ts.getContainingClass(privId)) { + return grammarErrorOnNode(privId, ts.Diagnostics.Private_identifiers_are_not_allowed_outside_class_bodies); } - if (!isForInStatement(privId.parent)) { - if (!isExpressionNode(privId)) { - return grammarErrorOnNode(privId, Diagnostics.Private_identifiers_are_only_allowed_in_class_bodies_and_may_only_be_used_as_part_of_a_class_member_declaration_property_access_or_on_the_left_hand_side_of_an_in_expression); + if (!ts.isForInStatement(privId.parent)) { + if (!ts.isExpressionNode(privId)) { + return grammarErrorOnNode(privId, ts.Diagnostics.Private_identifiers_are_only_allowed_in_class_bodies_and_may_only_be_used_as_part_of_a_class_member_declaration_property_access_or_on_the_left_hand_side_of_an_in_expression); } - const isInOperation = isBinaryExpression(privId.parent) && privId.parent.operatorToken.kind === SyntaxKind.InKeyword; + const isInOperation = ts.isBinaryExpression(privId.parent) && privId.parent.operatorToken.kind === ts.SyntaxKind.InKeyword; if (!getSymbolForPrivateIdentifierExpression(privId) && !isInOperation) { - return grammarErrorOnNode(privId, Diagnostics.Cannot_find_name_0, idText(privId)); + return grammarErrorOnNode(privId, ts.Diagnostics.Cannot_find_name_0, ts.idText(privId)); } } return false; } - function checkPrivateIdentifierExpression(privId: PrivateIdentifier): Type { + function checkPrivateIdentifierExpression(privId: ts.PrivateIdentifier): ts.Type { checkGrammarPrivateIdentifierExpression(privId); const symbol = getSymbolForPrivateIdentifierExpression(privId); if (symbol) { @@ -28868,8 +28256,8 @@ namespace ts { return anyType; } - function getSymbolForPrivateIdentifierExpression(privId: PrivateIdentifier): Symbol | undefined { - if (!isExpressionNode(privId)) { + function getSymbolForPrivateIdentifierExpression(privId: ts.PrivateIdentifier): ts.Symbol | undefined { + if (!ts.isExpressionNode(privId)) { return undefined; } @@ -28880,19 +28268,19 @@ namespace ts { return links.resolvedSymbol; } - function getPrivateIdentifierPropertyOfType(leftType: Type, lexicallyScopedIdentifier: Symbol): Symbol | undefined { + function getPrivateIdentifierPropertyOfType(leftType: ts.Type, lexicallyScopedIdentifier: ts.Symbol): ts.Symbol | undefined { return getPropertyOfType(leftType, lexicallyScopedIdentifier.escapedName); } - function checkPrivateIdentifierPropertyAccess(leftType: Type, right: PrivateIdentifier, lexicallyScopedIdentifier: Symbol | undefined): boolean { + function checkPrivateIdentifierPropertyAccess(leftType: ts.Type, right: ts.PrivateIdentifier, lexicallyScopedIdentifier: ts.Symbol | undefined): boolean { // Either the identifier could not be looked up in the lexical scope OR the lexically scoped identifier did not exist on the type. // Find a private identifier with the same description on the type. - let propertyOnType: Symbol | undefined; + let propertyOnType: ts.Symbol | undefined; const properties = getPropertiesOfType(leftType); if (properties) { - forEach(properties, (symbol: Symbol) => { + ts.forEach(properties, (symbol: ts.Symbol) => { const decl = symbol.valueDeclaration; - if (decl && isNamedDeclaration(decl) && isPrivateIdentifier(decl.name) && decl.name.escapedText === right.escapedText) { + if (decl && ts.isNamedDeclaration(decl) && ts.isPrivateIdentifier(decl.name) && decl.name.escapedText === right.escapedText) { propertyOnType = symbol; return true; } @@ -28900,83 +28288,60 @@ namespace ts { } const diagName = diagnosticName(right); if (propertyOnType) { - const typeValueDecl = Debug.checkDefined(propertyOnType.valueDeclaration); - const typeClass = Debug.checkDefined(getContainingClass(typeValueDecl)); + const typeValueDecl = ts.Debug.checkDefined(propertyOnType.valueDeclaration); + const typeClass = ts.Debug.checkDefined(ts.getContainingClass(typeValueDecl)); // We found a private identifier property with the same description. // Either: // - There is a lexically scoped private identifier AND it shadows the one we found on the type. // - It is an attempt to access the private identifier outside of the class. if (lexicallyScopedIdentifier?.valueDeclaration) { const lexicalValueDecl = lexicallyScopedIdentifier.valueDeclaration; - const lexicalClass = getContainingClass(lexicalValueDecl); - Debug.assert(!!lexicalClass); - if (findAncestor(lexicalClass, n => typeClass === n)) { - const diagnostic = error( - right, - Diagnostics.The_property_0_cannot_be_accessed_on_type_1_within_this_class_because_it_is_shadowed_by_another_private_identifier_with_the_same_spelling, - diagName, - typeToString(leftType) - ); - - addRelatedInfo( - diagnostic, - createDiagnosticForNode( - lexicalValueDecl, - Diagnostics.The_shadowing_declaration_of_0_is_defined_here, - diagName - ), - createDiagnosticForNode( - typeValueDecl, - Diagnostics.The_declaration_of_0_that_you_probably_intended_to_use_is_defined_here, - diagName - ) - ); + const lexicalClass = ts.getContainingClass(lexicalValueDecl); + ts.Debug.assert(!!lexicalClass); + if (ts.findAncestor(lexicalClass, n => typeClass === n)) { + const diagnostic = error(right, ts.Diagnostics.The_property_0_cannot_be_accessed_on_type_1_within_this_class_because_it_is_shadowed_by_another_private_identifier_with_the_same_spelling, diagName, typeToString(leftType)); + ts.addRelatedInfo(diagnostic, ts.createDiagnosticForNode(lexicalValueDecl, ts.Diagnostics.The_shadowing_declaration_of_0_is_defined_here, diagName), ts.createDiagnosticForNode(typeValueDecl, ts.Diagnostics.The_declaration_of_0_that_you_probably_intended_to_use_is_defined_here, diagName)); return true; } } - error( - right, - Diagnostics.Property_0_is_not_accessible_outside_class_1_because_it_has_a_private_identifier, - diagName, - diagnosticName(typeClass.name || anon) - ); + error(right, ts.Diagnostics.Property_0_is_not_accessible_outside_class_1_because_it_has_a_private_identifier, diagName, diagnosticName(typeClass.name || anon)); return true; } return false; } - function isThisPropertyAccessInConstructor(node: ElementAccessExpression | PropertyAccessExpression | QualifiedName, prop: Symbol) { - return (isConstructorDeclaredProperty(prop) || isThisProperty(node) && isAutoTypedProperty(prop)) - && getThisContainer(node, /*includeArrowFunctions*/ true) === getDeclaringConstructor(prop); + function isThisPropertyAccessInConstructor(node: ts.ElementAccessExpression | ts.PropertyAccessExpression | ts.QualifiedName, prop: ts.Symbol) { + return (isConstructorDeclaredProperty(prop) || ts.isThisProperty(node) && isAutoTypedProperty(prop)) + && ts.getThisContainer(node, /*includeArrowFunctions*/ true) === getDeclaringConstructor(prop); } - function checkPropertyAccessExpressionOrQualifiedName(node: PropertyAccessExpression | QualifiedName, left: Expression | QualifiedName, leftType: Type, right: Identifier | PrivateIdentifier, checkMode: CheckMode | undefined) { + function checkPropertyAccessExpressionOrQualifiedName(node: ts.PropertyAccessExpression | ts.QualifiedName, left: ts.Expression | ts.QualifiedName, leftType: ts.Type, right: ts.Identifier | ts.PrivateIdentifier, checkMode: CheckMode | undefined) { const parentSymbol = getNodeLinks(left).resolvedSymbol; - const assignmentKind = getAssignmentTargetKind(node); - const apparentType = getApparentType(assignmentKind !== AssignmentKind.None || isMethodAccessForCall(node) ? getWidenedType(leftType) : leftType); + const assignmentKind = ts.getAssignmentTargetKind(node); + const apparentType = getApparentType(assignmentKind !== ts.AssignmentKind.None || isMethodAccessForCall(node) ? getWidenedType(leftType) : leftType); const isAnyLike = isTypeAny(apparentType) || apparentType === silentNeverType; - let prop: Symbol | undefined; - if (isPrivateIdentifier(right)) { - if (languageVersion < ScriptTarget.ESNext) { - if (assignmentKind !== AssignmentKind.None) { - checkExternalEmitHelpers(node, ExternalEmitHelpers.ClassPrivateFieldSet); + let prop: ts.Symbol | undefined; + if (ts.isPrivateIdentifier(right)) { + if (languageVersion < ts.ScriptTarget.ESNext) { + if (assignmentKind !== ts.AssignmentKind.None) { + checkExternalEmitHelpers(node, ts.ExternalEmitHelpers.ClassPrivateFieldSet); } - if (assignmentKind !== AssignmentKind.Definite) { - checkExternalEmitHelpers(node, ExternalEmitHelpers.ClassPrivateFieldGet); + if (assignmentKind !== ts.AssignmentKind.Definite) { + checkExternalEmitHelpers(node, ts.ExternalEmitHelpers.ClassPrivateFieldGet); } } const lexicallyScopedSymbol = lookupSymbolForPrivateIdentifierDeclaration(right.escapedText, right); - if (assignmentKind && lexicallyScopedSymbol && lexicallyScopedSymbol.valueDeclaration && isMethodDeclaration(lexicallyScopedSymbol.valueDeclaration)) { - grammarErrorOnNode(right, Diagnostics.Cannot_assign_to_private_method_0_Private_methods_are_not_writable, idText(right)); + if (assignmentKind && lexicallyScopedSymbol && lexicallyScopedSymbol.valueDeclaration && ts.isMethodDeclaration(lexicallyScopedSymbol.valueDeclaration)) { + grammarErrorOnNode(right, ts.Diagnostics.Cannot_assign_to_private_method_0_Private_methods_are_not_writable, ts.idText(right)); } if (isAnyLike) { if (lexicallyScopedSymbol) { return isErrorType(apparentType) ? errorType : apparentType; } - if (!getContainingClass(right)) { - grammarErrorOnNode(right, Diagnostics.Private_identifiers_are_not_allowed_outside_class_bodies); + if (!ts.getContainingClass(right)) { + grammarErrorOnNode(right, ts.Diagnostics.Private_identifiers_are_not_allowed_outside_class_bodies); return anyType; } } @@ -28986,20 +28351,20 @@ namespace ts { return errorType; } else { - const isSetonlyAccessor = prop && prop.flags & SymbolFlags.SetAccessor && !(prop.flags & SymbolFlags.GetAccessor); - if (isSetonlyAccessor && assignmentKind !== AssignmentKind.Definite) { - error(node, Diagnostics.Private_accessor_was_defined_without_a_getter); + const isSetonlyAccessor = prop && prop.flags & ts.SymbolFlags.SetAccessor && !(prop.flags & ts.SymbolFlags.GetAccessor); + if (isSetonlyAccessor && assignmentKind !== ts.AssignmentKind.Definite) { + error(node, ts.Diagnostics.Private_accessor_was_defined_without_a_getter); } } } else { if (isAnyLike) { - if (isIdentifier(left) && parentSymbol) { + if (ts.isIdentifier(left) && parentSymbol) { markAliasReferenced(parentSymbol, node); } return isErrorType(apparentType) ? errorType : apparentType; } - prop = getPropertyOfType(apparentType, right.escapedText, /*skipObjectFunctionPropertyAugment*/ false, /*includeTypeOnlyMembers*/ node.kind === SyntaxKind.QualifiedName); + prop = getPropertyOfType(apparentType, right.escapedText, /*skipObjectFunctionPropertyAugment*/ false, /*includeTypeOnlyMembers*/ node.kind === ts.SyntaxKind.QualifiedName); } // In `Foo.Bar.Baz`, 'Foo' is not referenced if 'Bar' is a const enum or a module containing only const enums. // `Foo` is also not referenced in `enum FooCopy { Bar = Foo.Bar }`, because the enum member value gets inlined @@ -29008,17 +28373,15 @@ namespace ts { // The exceptions are: // 1. if 'isolatedModules' is enabled, because the const enum value will not be inlined, and // 2. if 'preserveConstEnums' is enabled and the expression is itself an export, e.g. `export = Foo.Bar.Baz`. - if (isIdentifier(left) && parentSymbol && ( - compilerOptions.isolatedModules || - !(prop && (isConstEnumOrConstEnumOnlyModule(prop) || prop.flags & SymbolFlags.EnumMember && node.parent.kind === SyntaxKind.EnumMember)) || - shouldPreserveConstEnums(compilerOptions) && isExportOrExportExpression(node) - )) { + if (ts.isIdentifier(left) && parentSymbol && (compilerOptions.isolatedModules || + !(prop && (isConstEnumOrConstEnumOnlyModule(prop) || prop.flags & ts.SymbolFlags.EnumMember && node.parent.kind === ts.SyntaxKind.EnumMember)) || + ts.shouldPreserveConstEnums(compilerOptions) && isExportOrExportExpression(node))) { markAliasReferenced(parentSymbol, node); } - let propType: Type; + let propType: ts.Type; if (!prop) { - const indexInfo = !isPrivateIdentifier(right) && (assignmentKind === AssignmentKind.None || !isGenericObjectType(leftType) || isThisTypeParameter(leftType)) ? + const indexInfo = !ts.isPrivateIdentifier(right) && (assignmentKind === ts.AssignmentKind.None || !isGenericObjectType(leftType) || ts.isThisTypeParameter(leftType)) ? getApplicableIndexInfoForName(apparentType, right.escapedText) : undefined; if (!(indexInfo && indexInfo.type)) { const isUncheckedJS = isUncheckedJSSuggestion(node, leftType.symbol, /*excludeClasses*/ true); @@ -29026,28 +28389,28 @@ namespace ts { return anyType; } if (leftType.symbol === globalThisSymbol) { - if (globalThisSymbol.exports!.has(right.escapedText) && (globalThisSymbol.exports!.get(right.escapedText)!.flags & SymbolFlags.BlockScoped)) { - error(right, Diagnostics.Property_0_does_not_exist_on_type_1, unescapeLeadingUnderscores(right.escapedText), typeToString(leftType)); + if (globalThisSymbol.exports!.has(right.escapedText) && (globalThisSymbol.exports!.get(right.escapedText)!.flags & ts.SymbolFlags.BlockScoped)) { + error(right, ts.Diagnostics.Property_0_does_not_exist_on_type_1, ts.unescapeLeadingUnderscores(right.escapedText), typeToString(leftType)); } else if (noImplicitAny) { - error(right, Diagnostics.Element_implicitly_has_an_any_type_because_type_0_has_no_index_signature, typeToString(leftType)); + error(right, ts.Diagnostics.Element_implicitly_has_an_any_type_because_type_0_has_no_index_signature, typeToString(leftType)); } return anyType; } if (right.escapedText && !checkAndReportErrorForExtendingInterface(node)) { - reportNonexistentProperty(right, isThisTypeParameter(leftType) ? apparentType : leftType, isUncheckedJS); + reportNonexistentProperty(right, ts.isThisTypeParameter(leftType) ? apparentType : leftType, isUncheckedJS); } return errorType; } - if (indexInfo.isReadonly && (isAssignmentTarget(node) || isDeleteTarget(node))) { - error(node, Diagnostics.Index_signature_in_type_0_only_permits_reading, typeToString(apparentType)); + if (indexInfo.isReadonly && (ts.isAssignmentTarget(node) || ts.isDeleteTarget(node))) { + error(node, ts.Diagnostics.Index_signature_in_type_0_only_permits_reading, typeToString(apparentType)); } - propType = (compilerOptions.noUncheckedIndexedAccess && !isAssignmentTarget(node)) ? getUnionType([indexInfo.type, undefinedType]) : indexInfo.type; - if (compilerOptions.noPropertyAccessFromIndexSignature && isPropertyAccessExpression(node)) { - error(right, Diagnostics.Property_0_comes_from_an_index_signature_so_it_must_be_accessed_with_0, unescapeLeadingUnderscores(right.escapedText)); + propType = (compilerOptions.noUncheckedIndexedAccess && !ts.isAssignmentTarget(node)) ? getUnionType([indexInfo.type, undefinedType]) : indexInfo.type; + if (compilerOptions.noPropertyAccessFromIndexSignature && ts.isPropertyAccessExpression(node)) { + error(right, ts.Diagnostics.Property_0_comes_from_an_index_signature_so_it_must_be_accessed_with_0, ts.unescapeLeadingUnderscores(right.escapedText)); } - if (indexInfo.declaration && getCombinedNodeFlags(indexInfo.declaration) & NodeFlags.Deprecated) { + if (indexInfo.declaration && ts.getCombinedNodeFlags(indexInfo.declaration) & ts.NodeFlags.Deprecated) { addDeprecatedSuggestion(right, [indexInfo.declaration], right.escapedText as string); } } @@ -29058,10 +28421,10 @@ namespace ts { checkPropertyNotUsedBeforeDeclaration(prop, node, right); markPropertyAsReferenced(prop, node, isSelfTypeAccess(left, parentSymbol)); getNodeLinks(node).resolvedSymbol = prop; - const writing = isWriteAccess(node); - checkPropertyAccessibility(node, left.kind === SyntaxKind.SuperKeyword, writing, apparentType, prop); - if (isAssignmentToReadonlyEntity(node as Expression, prop, assignmentKind)) { - error(right, Diagnostics.Cannot_assign_to_0_because_it_is_a_read_only_property, idText(right)); + const writing = ts.isWriteAccess(node); + checkPropertyAccessibility(node, left.kind === ts.SyntaxKind.SuperKeyword, writing, apparentType, prop); + if (isAssignmentToReadonlyEntity(node as ts.Expression, prop, assignmentKind)) { + error(right, ts.Diagnostics.Cannot_assign_to_0_because_it_is_a_read_only_property, ts.idText(right)); return errorType; } @@ -29078,30 +28441,30 @@ namespace ts { * - Is from a global file that is different from the reference file, or * - (optionally) Is a class, or is a this.x property access expression */ - function isUncheckedJSSuggestion(node: Node | undefined, suggestion: Symbol | undefined, excludeClasses: boolean): boolean { - const file = getSourceFileOfNode(node); + function isUncheckedJSSuggestion(node: ts.Node | undefined, suggestion: ts.Symbol | undefined, excludeClasses: boolean): boolean { + const file = ts.getSourceFileOfNode(node); if (file) { - if (compilerOptions.checkJs === undefined && file.checkJsDirective === undefined && (file.scriptKind === ScriptKind.JS || file.scriptKind === ScriptKind.JSX)) { - const declarationFile = forEach(suggestion?.declarations, getSourceFileOfNode); + if (compilerOptions.checkJs === undefined && file.checkJsDirective === undefined && (file.scriptKind === ts.ScriptKind.JS || file.scriptKind === ts.ScriptKind.JSX)) { + const declarationFile = ts.forEach(suggestion?.declarations, ts.getSourceFileOfNode); return !(file !== declarationFile && !!declarationFile && isGlobalSourceFile(declarationFile)) - && !(excludeClasses && suggestion && suggestion.flags & SymbolFlags.Class) - && !(!!node && excludeClasses && isPropertyAccessExpression(node) && node.expression.kind === SyntaxKind.ThisKeyword); + && !(excludeClasses && suggestion && suggestion.flags & ts.SymbolFlags.Class) + && !(!!node && excludeClasses && ts.isPropertyAccessExpression(node) && node.expression.kind === ts.SyntaxKind.ThisKeyword); } } return false; } - function getFlowTypeOfAccessExpression(node: ElementAccessExpression | PropertyAccessExpression | QualifiedName, prop: Symbol | undefined, propType: Type, errorNode: Node, checkMode: CheckMode | undefined) { + function getFlowTypeOfAccessExpression(node: ts.ElementAccessExpression | ts.PropertyAccessExpression | ts.QualifiedName, prop: ts.Symbol | undefined, propType: ts.Type, errorNode: ts.Node, checkMode: CheckMode | undefined) { // Only compute control flow type if this is a property access expression that isn't an // assignment target, and the referenced property was declared as a variable, property, // accessor, or optional method. - const assignmentKind = getAssignmentTargetKind(node); - if (assignmentKind === AssignmentKind.Definite) { - return removeMissingType(propType, !!(prop && prop.flags & SymbolFlags.Optional)); + const assignmentKind = ts.getAssignmentTargetKind(node); + if (assignmentKind === ts.AssignmentKind.Definite) { + return removeMissingType(propType, !!(prop && prop.flags & ts.SymbolFlags.Optional)); } if (prop && - !(prop.flags & (SymbolFlags.Variable | SymbolFlags.Property | SymbolFlags.Accessor)) - && !(prop.flags & SymbolFlags.Method && propType.flags & TypeFlags.Union) + !(prop.flags & (ts.SymbolFlags.Variable | ts.SymbolFlags.Property | ts.SymbolFlags.Accessor)) + && !(prop.flags & ts.SymbolFlags.Method && propType.flags & ts.TypeFlags.Union) && !isDuplicatedCommonJSExport(prop.declarations)) { return propType; } @@ -29114,87 +28477,85 @@ namespace ts { // and if we are in a constructor of the same class as the property declaration, assume that // the property is uninitialized at the top of the control flow. let assumeUninitialized = false; - if (strictNullChecks && strictPropertyInitialization && isAccessExpression(node) && node.expression.kind === SyntaxKind.ThisKeyword) { + if (strictNullChecks && strictPropertyInitialization && ts.isAccessExpression(node) && node.expression.kind === ts.SyntaxKind.ThisKeyword) { const declaration = prop && prop.valueDeclaration; if (declaration && isPropertyWithoutInitializer(declaration)) { - if (!isStatic(declaration)) { + if (!ts.isStatic(declaration)) { const flowContainer = getControlFlowContainer(node); - if (flowContainer.kind === SyntaxKind.Constructor && flowContainer.parent === declaration.parent && !(declaration.flags & NodeFlags.Ambient)) { + if (flowContainer.kind === ts.SyntaxKind.Constructor && flowContainer.parent === declaration.parent && !(declaration.flags & ts.NodeFlags.Ambient)) { assumeUninitialized = true; } } } } else if (strictNullChecks && prop && prop.valueDeclaration && - isPropertyAccessExpression(prop.valueDeclaration) && - getAssignmentDeclarationPropertyAccessKind(prop.valueDeclaration) && + ts.isPropertyAccessExpression(prop.valueDeclaration) && + ts.getAssignmentDeclarationPropertyAccessKind(prop.valueDeclaration) && getControlFlowContainer(node) === getControlFlowContainer(prop.valueDeclaration)) { assumeUninitialized = true; } const flowType = getFlowTypeOfReference(node, propType, assumeUninitialized ? getOptionalType(propType) : propType); - if (assumeUninitialized && !(getFalsyFlags(propType) & TypeFlags.Undefined) && getFalsyFlags(flowType) & TypeFlags.Undefined) { - error(errorNode, Diagnostics.Property_0_is_used_before_being_assigned, symbolToString(prop!)); // TODO: GH#18217 + if (assumeUninitialized && !(getFalsyFlags(propType) & ts.TypeFlags.Undefined) && getFalsyFlags(flowType) & ts.TypeFlags.Undefined) { + error(errorNode, ts.Diagnostics.Property_0_is_used_before_being_assigned, symbolToString(prop!)); // TODO: GH#18217 // Return the declared type to reduce follow-on errors return propType; } return assignmentKind ? getBaseTypeOfLiteralType(flowType) : flowType; } - function checkPropertyNotUsedBeforeDeclaration(prop: Symbol, node: PropertyAccessExpression | QualifiedName, right: Identifier | PrivateIdentifier): void { + function checkPropertyNotUsedBeforeDeclaration(prop: ts.Symbol, node: ts.PropertyAccessExpression | ts.QualifiedName, right: ts.Identifier | ts.PrivateIdentifier): void { const { valueDeclaration } = prop; - if (!valueDeclaration || getSourceFileOfNode(node).isDeclarationFile) { + if (!valueDeclaration || ts.getSourceFileOfNode(node).isDeclarationFile) { return; } let diagnosticMessage; - const declarationName = idText(right); + const declarationName = ts.idText(right); if (isInPropertyInitializerOrClassStaticBlock(node) && !isOptionalPropertyDeclaration(valueDeclaration) - && !(isAccessExpression(node) && isAccessExpression(node.expression)) + && !(ts.isAccessExpression(node) && ts.isAccessExpression(node.expression)) && !isBlockScopedNameDeclaredBeforeUse(valueDeclaration, right) - && !(isMethodDeclaration(valueDeclaration) && getCombinedModifierFlags(valueDeclaration) & ModifierFlags.Static) + && !(ts.isMethodDeclaration(valueDeclaration) && ts.getCombinedModifierFlags(valueDeclaration) & ts.ModifierFlags.Static) && (compilerOptions.useDefineForClassFields || !isPropertyDeclaredInAncestorClass(prop))) { - diagnosticMessage = error(right, Diagnostics.Property_0_is_used_before_its_initialization, declarationName); + diagnosticMessage = error(right, ts.Diagnostics.Property_0_is_used_before_its_initialization, declarationName); } - else if (valueDeclaration.kind === SyntaxKind.ClassDeclaration && - node.parent.kind !== SyntaxKind.TypeReference && - !(valueDeclaration.flags & NodeFlags.Ambient) && + else if (valueDeclaration.kind === ts.SyntaxKind.ClassDeclaration && + node.parent.kind !== ts.SyntaxKind.TypeReference && + !(valueDeclaration.flags & ts.NodeFlags.Ambient) && !isBlockScopedNameDeclaredBeforeUse(valueDeclaration, right)) { - diagnosticMessage = error(right, Diagnostics.Class_0_used_before_its_declaration, declarationName); + diagnosticMessage = error(right, ts.Diagnostics.Class_0_used_before_its_declaration, declarationName); } if (diagnosticMessage) { - addRelatedInfo(diagnosticMessage, - createDiagnosticForNode(valueDeclaration, Diagnostics._0_is_declared_here, declarationName) - ); + ts.addRelatedInfo(diagnosticMessage, ts.createDiagnosticForNode(valueDeclaration, ts.Diagnostics._0_is_declared_here, declarationName)); } } - function isInPropertyInitializerOrClassStaticBlock(node: Node): boolean { - return !!findAncestor(node, node => { + function isInPropertyInitializerOrClassStaticBlock(node: ts.Node): boolean { + return !!ts.findAncestor(node, node => { switch (node.kind) { - case SyntaxKind.PropertyDeclaration: + case ts.SyntaxKind.PropertyDeclaration: return true; - case SyntaxKind.PropertyAssignment: - case SyntaxKind.MethodDeclaration: - case SyntaxKind.GetAccessor: - case SyntaxKind.SetAccessor: - case SyntaxKind.SpreadAssignment: - case SyntaxKind.ComputedPropertyName: - case SyntaxKind.TemplateSpan: - case SyntaxKind.JsxExpression: - case SyntaxKind.JsxAttribute: - case SyntaxKind.JsxAttributes: - case SyntaxKind.JsxSpreadAttribute: - case SyntaxKind.JsxOpeningElement: - case SyntaxKind.ExpressionWithTypeArguments: - case SyntaxKind.HeritageClause: + case ts.SyntaxKind.PropertyAssignment: + case ts.SyntaxKind.MethodDeclaration: + case ts.SyntaxKind.GetAccessor: + case ts.SyntaxKind.SetAccessor: + case ts.SyntaxKind.SpreadAssignment: + case ts.SyntaxKind.ComputedPropertyName: + case ts.SyntaxKind.TemplateSpan: + case ts.SyntaxKind.JsxExpression: + case ts.SyntaxKind.JsxAttribute: + case ts.SyntaxKind.JsxAttributes: + case ts.SyntaxKind.JsxSpreadAttribute: + case ts.SyntaxKind.JsxOpeningElement: + case ts.SyntaxKind.ExpressionWithTypeArguments: + case ts.SyntaxKind.HeritageClause: return false; - case SyntaxKind.ArrowFunction: - case SyntaxKind.ExpressionStatement: - return isBlock(node.parent) && isClassStaticBlockDeclaration(node.parent.parent) ? true : "quit"; + case ts.SyntaxKind.ArrowFunction: + case ts.SyntaxKind.ExpressionStatement: + return ts.isBlock(node.parent) && ts.isClassStaticBlockDeclaration(node.parent.parent) ? true : "quit"; default: - return isExpressionNode(node) ? false : "quit"; + return ts.isExpressionNode(node) ? false : "quit"; } }); } @@ -29203,13 +28564,13 @@ namespace ts { * It's possible that "prop.valueDeclaration" is a local declaration, but the property was also declared in a superclass. * In that case we won't consider it used before its declaration, because it gets its value from the superclass' declaration. */ - function isPropertyDeclaredInAncestorClass(prop: Symbol): boolean { - if (!(prop.parent!.flags & SymbolFlags.Class)) { + function isPropertyDeclaredInAncestorClass(prop: ts.Symbol): boolean { + if (!(prop.parent!.flags & ts.SymbolFlags.Class)) { return false; } - let classType: InterfaceType | undefined = getTypeOfSymbol(prop.parent!) as InterfaceType; + let classType: ts.InterfaceType | undefined = getTypeOfSymbol(prop.parent!) as ts.InterfaceType; while (true) { - classType = classType.symbol && getSuperClass(classType) as InterfaceType | undefined; + classType = classType.symbol && getSuperClass(classType) as ts.InterfaceType | undefined; if (!classType) { return false; } @@ -29220,7 +28581,7 @@ namespace ts { } } - function getSuperClass(classType: InterfaceType): Type | undefined { + function getSuperClass(classType: ts.InterfaceType): ts.Type | undefined { const x = getBaseTypes(classType); if (x.length === 0) { return undefined; @@ -29228,185 +28589,184 @@ namespace ts { return getIntersectionType(x); } - function reportNonexistentProperty(propNode: Identifier | PrivateIdentifier, containingType: Type, isUncheckedJS: boolean) { - let errorInfo: DiagnosticMessageChain | undefined; - let relatedInfo: Diagnostic | undefined; - if (!isPrivateIdentifier(propNode) && containingType.flags & TypeFlags.Union && !(containingType.flags & TypeFlags.Primitive)) { - for (const subtype of (containingType as UnionType).types) { + function reportNonexistentProperty(propNode: ts.Identifier | ts.PrivateIdentifier, containingType: ts.Type, isUncheckedJS: boolean) { + let errorInfo: ts.DiagnosticMessageChain | undefined; + let relatedInfo: ts.Diagnostic | undefined; + if (!ts.isPrivateIdentifier(propNode) && containingType.flags & ts.TypeFlags.Union && !(containingType.flags & ts.TypeFlags.Primitive)) { + for (const subtype of (containingType as ts.UnionType).types) { if (!getPropertyOfType(subtype, propNode.escapedText) && !getApplicableIndexInfoForName(subtype, propNode.escapedText)) { - errorInfo = chainDiagnosticMessages(errorInfo, Diagnostics.Property_0_does_not_exist_on_type_1, declarationNameToString(propNode), typeToString(subtype)); + errorInfo = ts.chainDiagnosticMessages(errorInfo, ts.Diagnostics.Property_0_does_not_exist_on_type_1, ts.declarationNameToString(propNode), typeToString(subtype)); break; } } } if (typeHasStaticProperty(propNode.escapedText, containingType)) { - const propName = declarationNameToString(propNode); + const propName = ts.declarationNameToString(propNode); const typeName = typeToString(containingType); - errorInfo = chainDiagnosticMessages(errorInfo, Diagnostics.Property_0_does_not_exist_on_type_1_Did_you_mean_to_access_the_static_member_2_instead, propName, typeName, typeName + "." + propName); + errorInfo = ts.chainDiagnosticMessages(errorInfo, ts.Diagnostics.Property_0_does_not_exist_on_type_1_Did_you_mean_to_access_the_static_member_2_instead, propName, typeName, typeName + "." + propName); } else { const promisedType = getPromisedTypeOfPromise(containingType); if (promisedType && getPropertyOfType(promisedType, propNode.escapedText)) { - errorInfo = chainDiagnosticMessages(errorInfo, Diagnostics.Property_0_does_not_exist_on_type_1, declarationNameToString(propNode), typeToString(containingType)); - relatedInfo = createDiagnosticForNode(propNode, Diagnostics.Did_you_forget_to_use_await); + errorInfo = ts.chainDiagnosticMessages(errorInfo, ts.Diagnostics.Property_0_does_not_exist_on_type_1, ts.declarationNameToString(propNode), typeToString(containingType)); + relatedInfo = ts.createDiagnosticForNode(propNode, ts.Diagnostics.Did_you_forget_to_use_await); } else { - const missingProperty = declarationNameToString(propNode); + const missingProperty = ts.declarationNameToString(propNode); const container = typeToString(containingType); const libSuggestion = getSuggestedLibForNonExistentProperty(missingProperty, containingType); if (libSuggestion !== undefined) { - errorInfo = chainDiagnosticMessages(errorInfo, Diagnostics.Property_0_does_not_exist_on_type_1_Do_you_need_to_change_your_target_library_Try_changing_the_lib_compiler_option_to_2_or_later, missingProperty, container, libSuggestion); + errorInfo = ts.chainDiagnosticMessages(errorInfo, ts.Diagnostics.Property_0_does_not_exist_on_type_1_Do_you_need_to_change_your_target_library_Try_changing_the_lib_compiler_option_to_2_or_later, missingProperty, container, libSuggestion); } else { const suggestion = getSuggestedSymbolForNonexistentProperty(propNode, containingType); if (suggestion !== undefined) { - const suggestedName = symbolName(suggestion); - const message = isUncheckedJS ? Diagnostics.Property_0_may_not_exist_on_type_1_Did_you_mean_2 : Diagnostics.Property_0_does_not_exist_on_type_1_Did_you_mean_2; - errorInfo = chainDiagnosticMessages(errorInfo, message, missingProperty, container, suggestedName); - relatedInfo = suggestion.valueDeclaration && createDiagnosticForNode(suggestion.valueDeclaration, Diagnostics._0_is_declared_here, suggestedName); + const suggestedName = ts.symbolName(suggestion); + const message = isUncheckedJS ? ts.Diagnostics.Property_0_may_not_exist_on_type_1_Did_you_mean_2 : ts.Diagnostics.Property_0_does_not_exist_on_type_1_Did_you_mean_2; + errorInfo = ts.chainDiagnosticMessages(errorInfo, message, missingProperty, container, suggestedName); + relatedInfo = suggestion.valueDeclaration && ts.createDiagnosticForNode(suggestion.valueDeclaration, ts.Diagnostics._0_is_declared_here, suggestedName); } else { const diagnostic = containerSeemsToBeEmptyDomElement(containingType) - ? Diagnostics.Property_0_does_not_exist_on_type_1_Try_changing_the_lib_compiler_option_to_include_dom - : Diagnostics.Property_0_does_not_exist_on_type_1; - errorInfo = chainDiagnosticMessages(elaborateNeverIntersection(errorInfo, containingType), diagnostic, missingProperty, container); + ? ts.Diagnostics.Property_0_does_not_exist_on_type_1_Try_changing_the_lib_compiler_option_to_include_dom + : ts.Diagnostics.Property_0_does_not_exist_on_type_1; + errorInfo = ts.chainDiagnosticMessages(elaborateNeverIntersection(errorInfo, containingType), diagnostic, missingProperty, container); } } } } - const resultDiagnostic = createDiagnosticForNodeFromMessageChain(propNode, errorInfo); + const resultDiagnostic = ts.createDiagnosticForNodeFromMessageChain(propNode, errorInfo); if (relatedInfo) { - addRelatedInfo(resultDiagnostic, relatedInfo); + ts.addRelatedInfo(resultDiagnostic, relatedInfo); } - addErrorOrSuggestion(!isUncheckedJS || errorInfo.code !== Diagnostics.Property_0_may_not_exist_on_type_1_Did_you_mean_2.code, resultDiagnostic); + addErrorOrSuggestion(!isUncheckedJS || errorInfo.code !== ts.Diagnostics.Property_0_may_not_exist_on_type_1_Did_you_mean_2.code, resultDiagnostic); } - function containerSeemsToBeEmptyDomElement(containingType: Type) { + function containerSeemsToBeEmptyDomElement(containingType: ts.Type) { return (compilerOptions.lib && !compilerOptions.lib.includes("dom")) && - everyContainedType(containingType, type => type.symbol && /^(EventTarget|Node|((HTML[a-zA-Z]*)?Element))$/.test(unescapeLeadingUnderscores(type.symbol.escapedName))) && + everyContainedType(containingType, type => type.symbol && /^(EventTarget|Node|((HTML[a-zA-Z]*)?Element))$/.test(ts.unescapeLeadingUnderscores(type.symbol.escapedName))) && isEmptyObjectType(containingType); } - function typeHasStaticProperty(propName: __String, containingType: Type): boolean { + function typeHasStaticProperty(propName: ts.__String, containingType: ts.Type): boolean { const prop = containingType.symbol && getPropertyOfType(getTypeOfSymbol(containingType.symbol), propName); - return prop !== undefined && !!prop.valueDeclaration && isStatic(prop.valueDeclaration); + return prop !== undefined && !!prop.valueDeclaration && ts.isStatic(prop.valueDeclaration); } - function getSuggestedLibForNonExistentName(name: __String | Identifier) { + function getSuggestedLibForNonExistentName(name: ts.__String | ts.Identifier) { const missingName = diagnosticName(name); - const allFeatures = getScriptTargetFeatures(); - const libTargets = getOwnKeys(allFeatures); + const allFeatures = ts.getScriptTargetFeatures(); + const libTargets = ts.getOwnKeys(allFeatures); for (const libTarget of libTargets) { - const containingTypes = getOwnKeys(allFeatures[libTarget]); - if (containingTypes !== undefined && contains(containingTypes, missingName)) { + const containingTypes = ts.getOwnKeys(allFeatures[libTarget]); + if (containingTypes !== undefined && ts.contains(containingTypes, missingName)) { return libTarget; } } } - function getSuggestedLibForNonExistentProperty(missingProperty: string, containingType: Type) { + function getSuggestedLibForNonExistentProperty(missingProperty: string, containingType: ts.Type) { const container = getApparentType(containingType).symbol; if (!container) { return undefined; } - const allFeatures = getScriptTargetFeatures(); - const libTargets = getOwnKeys(allFeatures); + const allFeatures = ts.getScriptTargetFeatures(); + const libTargets = ts.getOwnKeys(allFeatures); for (const libTarget of libTargets) { const featuresOfLib = allFeatures[libTarget]; - const featuresOfContainingType = featuresOfLib[symbolName(container)]; - if (featuresOfContainingType !== undefined && contains(featuresOfContainingType, missingProperty)) { + const featuresOfContainingType = featuresOfLib[ts.symbolName(container)]; + if (featuresOfContainingType !== undefined && ts.contains(featuresOfContainingType, missingProperty)) { return libTarget; } } } - function getSuggestedSymbolForNonexistentClassMember(name: string, baseType: Type): Symbol | undefined { - return getSpellingSuggestionForName(name, getPropertiesOfType(baseType), SymbolFlags.ClassMember); + function getSuggestedSymbolForNonexistentClassMember(name: string, baseType: ts.Type): ts.Symbol | undefined { + return getSpellingSuggestionForName(name, getPropertiesOfType(baseType), ts.SymbolFlags.ClassMember); } - function getSuggestedSymbolForNonexistentProperty(name: Identifier | PrivateIdentifier | string, containingType: Type): Symbol | undefined { + function getSuggestedSymbolForNonexistentProperty(name: ts.Identifier | ts.PrivateIdentifier | string, containingType: ts.Type): ts.Symbol | undefined { let props = getPropertiesOfType(containingType); if (typeof name !== "string") { const parent = name.parent; - if (isPropertyAccessExpression(parent)) { - props = filter(props, prop => isValidPropertyAccessForCompletions(parent, containingType, prop)); + if (ts.isPropertyAccessExpression(parent)) { + props = ts.filter(props, prop => isValidPropertyAccessForCompletions(parent, containingType, prop)); } - name = idText(name); + name = ts.idText(name); } - return getSpellingSuggestionForName(name, props, SymbolFlags.Value); + return getSpellingSuggestionForName(name, props, ts.SymbolFlags.Value); } - function getSuggestedSymbolForNonexistentJSXAttribute(name: Identifier | PrivateIdentifier | string, containingType: Type): Symbol | undefined { - const strName = isString(name) ? name : idText(name); + function getSuggestedSymbolForNonexistentJSXAttribute(name: ts.Identifier | ts.PrivateIdentifier | string, containingType: ts.Type): ts.Symbol | undefined { + const strName = ts.isString(name) ? name : ts.idText(name); const properties = getPropertiesOfType(containingType); - const jsxSpecific = strName === "for" ? find(properties, x => symbolName(x) === "htmlFor") - : strName === "class" ? find(properties, x => symbolName(x) === "className") + const jsxSpecific = strName === "for" ? ts.find(properties, x => ts.symbolName(x) === "htmlFor") + : strName === "class" ? ts.find(properties, x => ts.symbolName(x) === "className") : undefined; - return jsxSpecific ?? getSpellingSuggestionForName(strName, properties, SymbolFlags.Value); + return jsxSpecific ?? getSpellingSuggestionForName(strName, properties, ts.SymbolFlags.Value); } - function getSuggestionForNonexistentProperty(name: Identifier | PrivateIdentifier | string, containingType: Type): string | undefined { + function getSuggestionForNonexistentProperty(name: ts.Identifier | ts.PrivateIdentifier | string, containingType: ts.Type): string | undefined { const suggestion = getSuggestedSymbolForNonexistentProperty(name, containingType); - return suggestion && symbolName(suggestion); + return suggestion && ts.symbolName(suggestion); } - function getSuggestedSymbolForNonexistentSymbol(location: Node | undefined, outerName: __String, meaning: SymbolFlags): Symbol | undefined { - Debug.assert(outerName !== undefined, "outername should always be defined"); + function getSuggestedSymbolForNonexistentSymbol(location: ts.Node | undefined, outerName: ts.__String, meaning: ts.SymbolFlags): ts.Symbol | undefined { + ts.Debug.assert(outerName !== undefined, "outername should always be defined"); const result = resolveNameHelper(location, outerName, meaning, /*nameNotFoundMessage*/ undefined, outerName, /*isUse*/ false, /*excludeGlobals*/ false, /*getSpellingSuggestions*/ true, (symbols, name, meaning) => { - Debug.assertEqual(outerName, name, "name should equal outerName"); + ts.Debug.assertEqual(outerName, name, "name should equal outerName"); const symbol = getSymbol(symbols, name, meaning); // Sometimes the symbol is found when location is a return type of a function: `typeof x` and `x` is declared in the body of the function // So the table *contains* `x` but `x` isn't actually in scope. // However, resolveNameHelper will continue and call this callback again, so we'll eventually get a correct suggestion. - if (symbol) return symbol; - let candidates: Symbol[]; + if (symbol) + return symbol; + let candidates: ts.Symbol[]; if (symbols === globals) { - const primitives = mapDefined( - ["string", "number", "boolean", "object", "bigint", "symbol"], - s => symbols.has((s.charAt(0).toUpperCase() + s.slice(1)) as __String) - ? createSymbol(SymbolFlags.TypeAlias, s as __String) as Symbol + const primitives = ts.mapDefined(["string", "number", "boolean", "object", "bigint", "symbol"], s => symbols.has((s.charAt(0).toUpperCase() + s.slice(1)) as ts.__String) + ? createSymbol(ts.SymbolFlags.TypeAlias, s as ts.__String) as ts.Symbol : undefined); - candidates = primitives.concat(arrayFrom(symbols.values())); + candidates = primitives.concat(ts.arrayFrom(symbols.values())); } else { - candidates = arrayFrom(symbols.values()); + candidates = ts.arrayFrom(symbols.values()); } - return getSpellingSuggestionForName(unescapeLeadingUnderscores(name), candidates, meaning); + return getSpellingSuggestionForName(ts.unescapeLeadingUnderscores(name), candidates, meaning); }); return result; } - function getSuggestionForNonexistentSymbol(location: Node | undefined, outerName: __String, meaning: SymbolFlags): string | undefined { + function getSuggestionForNonexistentSymbol(location: ts.Node | undefined, outerName: ts.__String, meaning: ts.SymbolFlags): string | undefined { const symbolResult = getSuggestedSymbolForNonexistentSymbol(location, outerName, meaning); - return symbolResult && symbolName(symbolResult); + return symbolResult && ts.symbolName(symbolResult); } - function getSuggestedSymbolForNonexistentModule(name: Identifier, targetModule: Symbol): Symbol | undefined { - return targetModule.exports && getSpellingSuggestionForName(idText(name), getExportsOfModuleAsArray(targetModule), SymbolFlags.ModuleMember); + function getSuggestedSymbolForNonexistentModule(name: ts.Identifier, targetModule: ts.Symbol): ts.Symbol | undefined { + return targetModule.exports && getSpellingSuggestionForName(ts.idText(name), getExportsOfModuleAsArray(targetModule), ts.SymbolFlags.ModuleMember); } - function getSuggestionForNonexistentExport(name: Identifier, targetModule: Symbol): string | undefined { + function getSuggestionForNonexistentExport(name: ts.Identifier, targetModule: ts.Symbol): string | undefined { const suggestion = getSuggestedSymbolForNonexistentModule(name, targetModule); - return suggestion && symbolName(suggestion); + return suggestion && ts.symbolName(suggestion); } - function getSuggestionForNonexistentIndexSignature(objectType: Type, expr: ElementAccessExpression, keyedType: Type): string | undefined { + function getSuggestionForNonexistentIndexSignature(objectType: ts.Type, expr: ts.ElementAccessExpression, keyedType: ts.Type): string | undefined { // check if object type has setter or getter function hasProp(name: "set" | "get") { - const prop = getPropertyOfObjectType(objectType, name as __String); + const prop = getPropertyOfObjectType(objectType, name as ts.__String); if (prop) { const s = getSingleCallSignature(getTypeOfSymbol(prop)); return !!s && getMinArgumentCount(s) >= 1 && isTypeAssignableTo(keyedType, getTypeAtPosition(s, 0)); } return false; - }; - - const suggestedMethod = isAssignmentTarget(expr) ? "set" : "get"; + } + ; + const suggestedMethod = ts.isAssignmentTarget(expr) ? "set" : "get"; if (!hasProp(suggestedMethod)) { return undefined; } - let suggestion = tryGetPropertyAccessOrIdentifierToString(expr.expression); + let suggestion = ts.tryGetPropertyAccessOrIdentifierToString(expr.expression); if (suggestion === undefined) { suggestion = suggestedMethod; } @@ -29417,9 +28777,9 @@ namespace ts { return suggestion; } - function getSuggestedTypeForNonexistentStringLiteralType(source: StringLiteralType, target: UnionType): StringLiteralType | undefined { - const candidates = target.types.filter((type): type is StringLiteralType => !!(type.flags & TypeFlags.StringLiteral)); - return getSpellingSuggestion(source.value, candidates, type => type.value); + function getSuggestedTypeForNonexistentStringLiteralType(source: ts.StringLiteralType, target: ts.UnionType): ts.StringLiteralType | undefined { + const candidates = target.types.filter((type): type is ts.StringLiteralType => !!(type.flags & ts.TypeFlags.StringLiteral)); + return ts.getSpellingSuggestion(source.value, candidates, type => type.value); } /** @@ -29437,12 +28797,11 @@ namespace ts { * (0.4 allows 1 substitution/transposition for every 5 characters, * and 1 insertion/deletion at 3 characters) */ - function getSpellingSuggestionForName(name: string, symbols: Symbol[], meaning: SymbolFlags): Symbol | undefined { - return getSpellingSuggestion(name, symbols, getCandidateName); - - function getCandidateName(candidate: Symbol) { - const candidateName = symbolName(candidate); - if (startsWith(candidateName, "\"")) { + function getSpellingSuggestionForName(name: string, symbols: ts.Symbol[], meaning: ts.SymbolFlags): ts.Symbol | undefined { + return ts.getSpellingSuggestion(name, symbols, getCandidateName); + function getCandidateName(candidate: ts.Symbol) { + const candidateName = ts.symbolName(candidate); + if (ts.startsWith(candidateName, "\"")) { return undefined; } @@ -29450,7 +28809,7 @@ namespace ts { return candidateName; } - if (candidate.flags & SymbolFlags.Alias) { + if (candidate.flags & ts.SymbolFlags.Alias) { const alias = tryResolveAlias(candidate); if (alias && alias.flags & meaning) { return candidateName; @@ -29461,42 +28820,42 @@ namespace ts { } } - function markPropertyAsReferenced(prop: Symbol, nodeForCheckWriteOnly: Node | undefined, isSelfTypeAccess: boolean) { - const valueDeclaration = prop && (prop.flags & SymbolFlags.ClassMember) && prop.valueDeclaration; + function markPropertyAsReferenced(prop: ts.Symbol, nodeForCheckWriteOnly: ts.Node | undefined, isSelfTypeAccess: boolean) { + const valueDeclaration = prop && (prop.flags & ts.SymbolFlags.ClassMember) && prop.valueDeclaration; if (!valueDeclaration) { return; } - const hasPrivateModifier = hasEffectiveModifier(valueDeclaration, ModifierFlags.Private); - const hasPrivateIdentifier = prop.valueDeclaration && isNamedDeclaration(prop.valueDeclaration) && isPrivateIdentifier(prop.valueDeclaration.name); + const hasPrivateModifier = ts.hasEffectiveModifier(valueDeclaration, ts.ModifierFlags.Private); + const hasPrivateIdentifier = prop.valueDeclaration && ts.isNamedDeclaration(prop.valueDeclaration) && ts.isPrivateIdentifier(prop.valueDeclaration.name); if (!hasPrivateModifier && !hasPrivateIdentifier) { return; } - if (nodeForCheckWriteOnly && isWriteOnlyAccess(nodeForCheckWriteOnly) && !(prop.flags & SymbolFlags.SetAccessor)) { + if (nodeForCheckWriteOnly && ts.isWriteOnlyAccess(nodeForCheckWriteOnly) && !(prop.flags & ts.SymbolFlags.SetAccessor)) { return; } if (isSelfTypeAccess) { // Find any FunctionLikeDeclaration because those create a new 'this' binding. But this should only matter for methods (or getters/setters). - const containingMethod = findAncestor(nodeForCheckWriteOnly, isFunctionLikeDeclaration); + const containingMethod = ts.findAncestor(nodeForCheckWriteOnly, ts.isFunctionLikeDeclaration); if (containingMethod && containingMethod.symbol === prop) { return; } } - (getCheckFlags(prop) & CheckFlags.Instantiated ? getSymbolLinks(prop).target : prop)!.isReferenced = SymbolFlags.All; + (ts.getCheckFlags(prop) & ts.CheckFlags.Instantiated ? getSymbolLinks(prop).target : prop)!.isReferenced = ts.SymbolFlags.All; } - function isSelfTypeAccess(name: Expression | QualifiedName, parent: Symbol | undefined) { - return name.kind === SyntaxKind.ThisKeyword - || !!parent && isEntityNameExpression(name) && parent === getResolvedSymbol(getFirstIdentifier(name)); + function isSelfTypeAccess(name: ts.Expression | ts.QualifiedName, parent: ts.Symbol | undefined) { + return name.kind === ts.SyntaxKind.ThisKeyword + || !!parent && ts.isEntityNameExpression(name) && parent === getResolvedSymbol(ts.getFirstIdentifier(name)); } - function isValidPropertyAccess(node: PropertyAccessExpression | QualifiedName | ImportTypeNode, propertyName: __String): boolean { + function isValidPropertyAccess(node: ts.PropertyAccessExpression | ts.QualifiedName | ts.ImportTypeNode, propertyName: ts.__String): boolean { switch (node.kind) { - case SyntaxKind.PropertyAccessExpression: - return isValidPropertyAccessWithType(node, node.expression.kind === SyntaxKind.SuperKeyword, propertyName, getWidenedType(checkExpression(node.expression))); - case SyntaxKind.QualifiedName: + case ts.SyntaxKind.PropertyAccessExpression: + return isValidPropertyAccessWithType(node, node.expression.kind === ts.SyntaxKind.SuperKeyword, propertyName, getWidenedType(checkExpression(node.expression))); + case ts.SyntaxKind.QualifiedName: return isValidPropertyAccessWithType(node, /*isSuper*/ false, propertyName, getWidenedType(checkExpression(node.left))); - case SyntaxKind.ImportType: + case ts.SyntaxKind.ImportType: return isValidPropertyAccessWithType(node, /*isSuper*/ false, propertyName, getTypeFromTypeNode(node)); } } @@ -29511,20 +28870,13 @@ namespace ts { * @param type the type whose property we are checking. * @param property the accessed property's symbol. */ - function isValidPropertyAccessForCompletions(node: PropertyAccessExpression | ImportTypeNode | QualifiedName, type: Type, property: Symbol): boolean { - return isPropertyAccessible(node, - node.kind === SyntaxKind.PropertyAccessExpression && node.expression.kind === SyntaxKind.SuperKeyword, - /* isWrite */ false, - type, - property); + function isValidPropertyAccessForCompletions(node: ts.PropertyAccessExpression | ts.ImportTypeNode | ts.QualifiedName, type: ts.Type, property: ts.Symbol): boolean { + return isPropertyAccessible(node, node.kind === ts.SyntaxKind.PropertyAccessExpression && node.expression.kind === ts.SyntaxKind.SuperKeyword, + /* isWrite */ false, type, property); // Previously we validated the 'this' type of methods but this adversely affected performance. See #31377 for more context. } - function isValidPropertyAccessWithType( - node: PropertyAccessExpression | QualifiedName | ImportTypeNode, - isSuper: boolean, - propertyName: __String, - type: Type): boolean { + function isValidPropertyAccessWithType(node: ts.PropertyAccessExpression | ts.QualifiedName | ts.ImportTypeNode, isSuper: boolean, propertyName: ts.__String, type: ts.Type): boolean { // Short-circuiting for improved performance. if (isTypeAny(type)) { @@ -29545,12 +28897,7 @@ namespace ts { * @param containingType type where the property comes from. * @param property property symbol. */ - function isPropertyAccessible( - node: Node, - isSuper: boolean, - isWrite: boolean, - containingType: Type, - property: Symbol): boolean { + function isPropertyAccessible(node: ts.Node, isSuper: boolean, isWrite: boolean, containingType: ts.Type, property: ts.Symbol): boolean { // Short-circuiting for improved performance. if (isTypeAny(containingType)) { @@ -29559,9 +28906,9 @@ namespace ts { // A #private property access in an optional chain is an error dealt with by the parser. // The checker does not check for it, so we need to do our own check here. - if (property.valueDeclaration && isPrivateIdentifierClassElementDeclaration(property.valueDeclaration)) { - const declClass = getContainingClass(property.valueDeclaration); - return !isOptionalChain(node) && !!findAncestor(node, parent => parent === declClass); + if (property.valueDeclaration && ts.isPrivateIdentifierClassElementDeclaration(property.valueDeclaration)) { + const declClass = ts.getContainingClass(property.valueDeclaration); + return !ts.isOptionalChain(node) && !!ts.findAncestor(node, parent => parent === declClass); } return checkPropertyAccessibilityAtLocation(node, isSuper, isWrite, containingType, property); @@ -29570,16 +28917,16 @@ namespace ts { /** * Return the symbol of the for-in variable declared or referenced by the given for-in statement. */ - function getForInVariableSymbol(node: ForInStatement): Symbol | undefined { + function getForInVariableSymbol(node: ts.ForInStatement): ts.Symbol | undefined { const initializer = node.initializer; - if (initializer.kind === SyntaxKind.VariableDeclarationList) { - const variable = (initializer as VariableDeclarationList).declarations[0]; - if (variable && !isBindingPattern(variable.name)) { + if (initializer.kind === ts.SyntaxKind.VariableDeclarationList) { + const variable = (initializer as ts.VariableDeclarationList).declarations[0]; + if (variable && !ts.isBindingPattern(variable.name)) { return getSymbolOfNode(variable); } } - else if (initializer.kind === SyntaxKind.Identifier) { - return getResolvedSymbol(initializer as Identifier); + else if (initializer.kind === ts.SyntaxKind.Identifier) { + return getResolvedSymbol(initializer as ts.Identifier); } return undefined; } @@ -29587,7 +28934,7 @@ namespace ts { /** * Return true if the given type is considered to have numeric property names. */ - function hasNumericPropertyNames(type: Type) { + function hasNumericPropertyNames(type: ts.Type) { return getIndexInfosOfType(type).length === 1 && !!getIndexInfoOfType(type, numberType); } @@ -29595,18 +28942,18 @@ namespace ts { * Return true if given node is an expression consisting of an identifier (possibly parenthesized) * that references a for-in variable for an object with numeric property names. */ - function isForInVariableForNumericPropertyNames(expr: Expression) { - const e = skipParentheses(expr); - if (e.kind === SyntaxKind.Identifier) { - const symbol = getResolvedSymbol(e as Identifier); - if (symbol.flags & SymbolFlags.Variable) { - let child: Node = expr; + function isForInVariableForNumericPropertyNames(expr: ts.Expression) { + const e = ts.skipParentheses(expr); + if (e.kind === ts.SyntaxKind.Identifier) { + const symbol = getResolvedSymbol(e as ts.Identifier); + if (symbol.flags & ts.SymbolFlags.Variable) { + let child: ts.Node = expr; let node = expr.parent; while (node) { - if (node.kind === SyntaxKind.ForInStatement && - child === (node as ForInStatement).statement && - getForInVariableSymbol(node as ForInStatement) === symbol && - hasNumericPropertyNames(getTypeOfExpression((node as ForInStatement).expression))) { + if (node.kind === ts.SyntaxKind.ForInStatement && + child === (node as ts.ForInStatement).statement && + getForInVariableSymbol(node as ts.ForInStatement) === symbol && + hasNumericPropertyNames(getTypeOfExpression((node as ts.ForInStatement).expression))) { return true; } child = node; @@ -29617,19 +28964,19 @@ namespace ts { return false; } - function checkIndexedAccess(node: ElementAccessExpression, checkMode: CheckMode | undefined): Type { - return node.flags & NodeFlags.OptionalChain ? checkElementAccessChain(node as ElementAccessChain, checkMode) : + function checkIndexedAccess(node: ts.ElementAccessExpression, checkMode: CheckMode | undefined): ts.Type { + return node.flags & ts.NodeFlags.OptionalChain ? checkElementAccessChain(node as ts.ElementAccessChain, checkMode) : checkElementAccessExpression(node, checkNonNullExpression(node.expression), checkMode); } - function checkElementAccessChain(node: ElementAccessChain, checkMode: CheckMode | undefined) { + function checkElementAccessChain(node: ts.ElementAccessChain, checkMode: CheckMode | undefined) { const exprType = checkExpression(node.expression); const nonOptionalType = getOptionalExpressionType(exprType, node.expression); return propagateOptionalTypeMarker(checkElementAccessExpression(node, checkNonNullType(nonOptionalType, node.expression), checkMode), node, nonOptionalType !== exprType); } - function checkElementAccessExpression(node: ElementAccessExpression, exprType: Type, checkMode: CheckMode | undefined): Type { - const objectType = getAssignmentTargetKind(node) !== AssignmentKind.None || isMethodAccessForCall(node) ? getWidenedType(exprType) : exprType; + function checkElementAccessExpression(node: ts.ElementAccessExpression, exprType: ts.Type, checkMode: CheckMode | undefined): ts.Type { + const objectType = ts.getAssignmentTargetKind(node) !== ts.AssignmentKind.None || isMethodAccessForCall(node) ? getWidenedType(exprType) : exprType; const indexExpression = node.argumentExpression; const indexType = checkExpression(indexExpression); @@ -29637,45 +28984,45 @@ namespace ts { return objectType; } - if (isConstEnumObjectType(objectType) && !isStringLiteralLike(indexExpression)) { - error(indexExpression, Diagnostics.A_const_enum_member_can_only_be_accessed_using_a_string_literal); + if (isConstEnumObjectType(objectType) && !ts.isStringLiteralLike(indexExpression)) { + error(indexExpression, ts.Diagnostics.A_const_enum_member_can_only_be_accessed_using_a_string_literal); return errorType; } const effectiveIndexType = isForInVariableForNumericPropertyNames(indexExpression) ? numberType : indexType; - const accessFlags = isAssignmentTarget(node) ? - AccessFlags.Writing | (isGenericObjectType(objectType) && !isThisTypeParameter(objectType) ? AccessFlags.NoIndexSignatures : 0) : - AccessFlags.ExpressionPosition; + const accessFlags = ts.isAssignmentTarget(node) ? + ts.AccessFlags.Writing | (isGenericObjectType(objectType) && !ts.isThisTypeParameter(objectType) ? ts.AccessFlags.NoIndexSignatures : 0) : + ts.AccessFlags.ExpressionPosition; const indexedAccessType = getIndexedAccessTypeOrUndefined(objectType, effectiveIndexType, accessFlags, node) || errorType; return checkIndexedAccessIndexType(getFlowTypeOfAccessExpression(node, getNodeLinks(node).resolvedSymbol, indexedAccessType, indexExpression, checkMode), node); } - function callLikeExpressionMayHaveTypeArguments(node: CallLikeExpression): node is CallExpression | NewExpression | TaggedTemplateExpression | JsxOpeningElement { - return isCallOrNewExpression(node) || isTaggedTemplateExpression(node) || isJsxOpeningLikeElement(node); + function callLikeExpressionMayHaveTypeArguments(node: ts.CallLikeExpression): node is ts.CallExpression | ts.NewExpression | ts.TaggedTemplateExpression | ts.JsxOpeningElement { + return ts.isCallOrNewExpression(node) || ts.isTaggedTemplateExpression(node) || ts.isJsxOpeningLikeElement(node); } - function resolveUntypedCall(node: CallLikeExpression): Signature { + function resolveUntypedCall(node: ts.CallLikeExpression): ts.Signature { if (callLikeExpressionMayHaveTypeArguments(node)) { // Check type arguments even though we will give an error that untyped calls may not accept type arguments. // This gets us diagnostics for the type arguments and marks them as referenced. - forEach(node.typeArguments, checkSourceElement); + ts.forEach(node.typeArguments, checkSourceElement); } - if (node.kind === SyntaxKind.TaggedTemplateExpression) { + if (node.kind === ts.SyntaxKind.TaggedTemplateExpression) { checkExpression(node.template); } - else if (isJsxOpeningLikeElement(node)) { + else if (ts.isJsxOpeningLikeElement(node)) { checkExpression(node.attributes); } - else if (node.kind !== SyntaxKind.Decorator) { - forEach((node as CallExpression).arguments, argument => { + else if (node.kind !== ts.SyntaxKind.Decorator) { + ts.forEach((node as ts.CallExpression).arguments, argument => { checkExpression(argument); }); } return anySignature; } - function resolveErrorCall(node: CallLikeExpression): Signature { + function resolveErrorCall(node: ts.CallLikeExpression): ts.Signature { resolveUntypedCall(node); return unknownSignature; } @@ -29688,14 +29035,14 @@ namespace ts { // interface B extends A { (x: 'foo'): string } // const b: B; // b('foo') // <- here overloads should be processed as [(x:'foo'): string, (x: string): void] - function reorderCandidates(signatures: readonly Signature[], result: Signature[], callChainFlags: SignatureFlags): void { - let lastParent: Node | undefined; - let lastSymbol: Symbol | undefined; + function reorderCandidates(signatures: readonly ts.Signature[], result: ts.Signature[], callChainFlags: ts.SignatureFlags): void { + let lastParent: ts.Node | undefined; + let lastSymbol: ts.Symbol | undefined; let cutoffIndex = 0; let index: number | undefined; let specializedIndex = -1; let spliceIndex: number; - Debug.assert(!result.length); + ts.Debug.assert(!result.length); for (const signature of signatures) { const symbol = signature.declaration && getSymbolOfNode(signature.declaration); const parent = signature.declaration && signature.declaration.parent; @@ -29734,49 +29081,49 @@ namespace ts { } } - function isSpreadArgument(arg: Expression | undefined): arg is Expression { - return !!arg && (arg.kind === SyntaxKind.SpreadElement || arg.kind === SyntaxKind.SyntheticExpression && (arg as SyntheticExpression).isSpread); + function isSpreadArgument(arg: ts.Expression | undefined): arg is ts.Expression { + return !!arg && (arg.kind === ts.SyntaxKind.SpreadElement || arg.kind === ts.SyntaxKind.SyntheticExpression && (arg as ts.SyntheticExpression).isSpread); } - function getSpreadArgumentIndex(args: readonly Expression[]): number { - return findIndex(args, isSpreadArgument); + function getSpreadArgumentIndex(args: readonly ts.Expression[]): number { + return ts.findIndex(args, isSpreadArgument); } - function acceptsVoid(t: Type): boolean { - return !!(t.flags & TypeFlags.Void); + function acceptsVoid(t: ts.Type): boolean { + return !!(t.flags & ts.TypeFlags.Void); } - function acceptsVoidUndefinedUnknownOrAny(t: Type): boolean { - return !!(t.flags & (TypeFlags.Void | TypeFlags.Undefined | TypeFlags.Unknown | TypeFlags.Any)); + function acceptsVoidUndefinedUnknownOrAny(t: ts.Type): boolean { + return !!(t.flags & (ts.TypeFlags.Void | ts.TypeFlags.Undefined | ts.TypeFlags.Unknown | ts.TypeFlags.Any)); } - function hasCorrectArity(node: CallLikeExpression, args: readonly Expression[], signature: Signature, signatureHelpTrailingComma = false) { + function hasCorrectArity(node: ts.CallLikeExpression, args: readonly ts.Expression[], signature: ts.Signature, signatureHelpTrailingComma = false) { let argCount: number; let callIsIncomplete = false; // In incomplete call we want to be lenient when we have too few arguments let effectiveParameterCount = getParameterCount(signature); let effectiveMinimumArguments = getMinArgumentCount(signature); - if (node.kind === SyntaxKind.TaggedTemplateExpression) { + if (node.kind === ts.SyntaxKind.TaggedTemplateExpression) { argCount = args.length; - if (node.template.kind === SyntaxKind.TemplateExpression) { + if (node.template.kind === ts.SyntaxKind.TemplateExpression) { // If a tagged template expression lacks a tail literal, the call is incomplete. // Specifically, a template only can end in a TemplateTail or a Missing literal. - const lastSpan = last(node.template.templateSpans); // we should always have at least one span. - callIsIncomplete = nodeIsMissing(lastSpan.literal) || !!lastSpan.literal.isUnterminated; + const lastSpan = ts.last(node.template.templateSpans); // we should always have at least one span. + callIsIncomplete = ts.nodeIsMissing(lastSpan.literal) || !!lastSpan.literal.isUnterminated; } else { // If the template didn't end in a backtick, or its beginning occurred right prior to EOF, // then this might actually turn out to be a TemplateHead in the future; // so we consider the call to be incomplete. - const templateLiteral = node.template as LiteralExpression; - Debug.assert(templateLiteral.kind === SyntaxKind.NoSubstitutionTemplateLiteral); + const templateLiteral = node.template as ts.LiteralExpression; + ts.Debug.assert(templateLiteral.kind === ts.SyntaxKind.NoSubstitutionTemplateLiteral); callIsIncomplete = !!templateLiteral.isUnterminated; } } - else if (node.kind === SyntaxKind.Decorator) { + else if (node.kind === ts.SyntaxKind.Decorator) { argCount = getDecoratorArgumentCount(node, signature); } - else if (isJsxOpeningLikeElement(node)) { + else if (ts.isJsxOpeningLikeElement(node)) { callIsIncomplete = node.attributes.end === node.end; if (callIsIncomplete) { return true; @@ -29787,7 +29134,7 @@ namespace ts { } else if (!node.arguments) { // This only happens when we have something of the form: 'new C' - Debug.assert(node.kind === SyntaxKind.NewExpression); + ts.Debug.assert(node.kind === ts.SyntaxKind.NewExpression); return getMinArgumentCount(signature) === 0; } else { @@ -29815,40 +29162,40 @@ namespace ts { } for (let i = argCount; i < effectiveMinimumArguments; i++) { const type = getTypeAtPosition(signature, i); - if (filterType(type, isInJSFile(node) && !strictNullChecks ? acceptsVoidUndefinedUnknownOrAny : acceptsVoid).flags & TypeFlags.Never) { + if (filterType(type, ts.isInJSFile(node) && !strictNullChecks ? acceptsVoidUndefinedUnknownOrAny : acceptsVoid).flags & ts.TypeFlags.Never) { return false; } } return true; } - function hasCorrectTypeArgumentArity(signature: Signature, typeArguments: NodeArray | undefined) { + function hasCorrectTypeArgumentArity(signature: ts.Signature, typeArguments: ts.NodeArray | undefined) { // If the user supplied type arguments, but the number of type arguments does not match // the declared number of type parameters, the call has an incorrect arity. - const numTypeParameters = length(signature.typeParameters); + const numTypeParameters = ts.length(signature.typeParameters); const minTypeArgumentCount = getMinTypeArgumentCount(signature.typeParameters); - return !some(typeArguments) || + return !ts.some(typeArguments) || (typeArguments.length >= minTypeArgumentCount && typeArguments.length <= numTypeParameters); } // If type has a single call signature and no other members, return that signature. Otherwise, return undefined. - function getSingleCallSignature(type: Type): Signature | undefined { - return getSingleSignature(type, SignatureKind.Call, /*allowMembers*/ false); + function getSingleCallSignature(type: ts.Type): ts.Signature | undefined { + return getSingleSignature(type, ts.SignatureKind.Call, /*allowMembers*/ false); } - function getSingleCallOrConstructSignature(type: Type): Signature | undefined { - return getSingleSignature(type, SignatureKind.Call, /*allowMembers*/ false) || - getSingleSignature(type, SignatureKind.Construct, /*allowMembers*/ false); + function getSingleCallOrConstructSignature(type: ts.Type): ts.Signature | undefined { + return getSingleSignature(type, ts.SignatureKind.Call, /*allowMembers*/ false) || + getSingleSignature(type, ts.SignatureKind.Construct, /*allowMembers*/ false); } - function getSingleSignature(type: Type, kind: SignatureKind, allowMembers: boolean): Signature | undefined { - if (type.flags & TypeFlags.Object) { - const resolved = resolveStructuredTypeMembers(type as ObjectType); + function getSingleSignature(type: ts.Type, kind: ts.SignatureKind, allowMembers: boolean): ts.Signature | undefined { + if (type.flags & ts.TypeFlags.Object) { + const resolved = resolveStructuredTypeMembers(type as ts.ObjectType); if (allowMembers || resolved.properties.length === 0 && resolved.indexInfos.length === 0) { - if (kind === SignatureKind.Call && resolved.callSignatures.length === 1 && resolved.constructSignatures.length === 0) { + if (kind === ts.SignatureKind.Call && resolved.callSignatures.length === 1 && resolved.constructSignatures.length === 0) { return resolved.callSignatures[0]; } - if (kind === SignatureKind.Construct && resolved.constructSignatures.length === 1 && resolved.callSignatures.length === 0) { + if (kind === ts.SignatureKind.Construct && resolved.constructSignatures.length === 1 && resolved.callSignatures.length === 0) { return resolved.constructSignatures[0]; } } @@ -29857,13 +29204,13 @@ namespace ts { } // Instantiate a generic signature in the context of a non-generic signature (section 3.8.5 in TypeScript spec) - function instantiateSignatureInContextOf(signature: Signature, contextualSignature: Signature, inferenceContext?: InferenceContext, compareTypes?: TypeComparer): Signature { - const context = createInferenceContext(signature.typeParameters!, signature, InferenceFlags.None, compareTypes); + function instantiateSignatureInContextOf(signature: ts.Signature, contextualSignature: ts.Signature, inferenceContext?: ts.InferenceContext, compareTypes?: ts.TypeComparer): ts.Signature { + const context = createInferenceContext(signature.typeParameters!, signature, ts.InferenceFlags.None, compareTypes); // We clone the inferenceContext to avoid fixing. For example, when the source signature is (x: T) => T[] and // the contextual signature is (...args: A) => B, we want to infer the element type of A's constraint (say 'any') // for T but leave it possible to later infer '[any]' back to A. const restType = getEffectiveRestType(contextualSignature); - const mapper = inferenceContext && (restType && restType.flags & TypeFlags.TypeParameter ? inferenceContext.nonFixingMapper : inferenceContext.mapper); + const mapper = inferenceContext && (restType && restType.flags & ts.TypeFlags.TypeParameter ? inferenceContext.nonFixingMapper : inferenceContext.mapper); const sourceSignature = mapper ? instantiateSignature(contextualSignature, mapper) : contextualSignature; applyToParameterTypes(sourceSignature, signature, (source, target) => { // Type parameters from outer context referenced by source type are fixed by instantiation of the source type @@ -29871,31 +29218,31 @@ namespace ts { }); if (!inferenceContext) { applyToReturnTypes(contextualSignature, signature, (source, target) => { - inferTypes(context.inferences, source, target, InferencePriority.ReturnType); + inferTypes(context.inferences, source, target, ts.InferencePriority.ReturnType); }); } - return getSignatureInstantiation(signature, getInferredTypes(context), isInJSFile(contextualSignature.declaration)); + return getSignatureInstantiation(signature, getInferredTypes(context), ts.isInJSFile(contextualSignature.declaration)); } - function inferJsxTypeArguments(node: JsxOpeningLikeElement, signature: Signature, checkMode: CheckMode, context: InferenceContext): Type[] { + function inferJsxTypeArguments(node: ts.JsxOpeningLikeElement, signature: ts.Signature, checkMode: CheckMode, context: ts.InferenceContext): ts.Type[] { const paramType = getEffectiveFirstArgumentForJsxSignature(signature, node); const checkAttrType = checkExpressionWithContextualType(node.attributes, paramType, context, checkMode); inferTypes(context.inferences, checkAttrType, paramType); return getInferredTypes(context); } - function getThisArgumentType(thisArgumentNode: LeftHandSideExpression | undefined) { + function getThisArgumentType(thisArgumentNode: ts.LeftHandSideExpression | undefined) { if (!thisArgumentNode) { return voidType; } const thisArgumentType = checkExpression(thisArgumentNode); - return isOptionalChainRoot(thisArgumentNode.parent) ? getNonNullableType(thisArgumentType) : - isOptionalChain(thisArgumentNode.parent) ? removeOptionalTypeMarker(thisArgumentType) : + return ts.isOptionalChainRoot(thisArgumentNode.parent) ? getNonNullableType(thisArgumentType) : + ts.isOptionalChain(thisArgumentNode.parent) ? removeOptionalTypeMarker(thisArgumentType) : thisArgumentType; } - function inferTypeArguments(node: CallLikeExpression, signature: Signature, args: readonly Expression[], checkMode: CheckMode, context: InferenceContext): Type[] { - if (isJsxOpeningLikeElement(node)) { + function inferTypeArguments(node: ts.CallLikeExpression, signature: ts.Signature, args: readonly ts.Expression[], checkMode: CheckMode, context: ts.InferenceContext): ts.Type[] { + if (ts.isJsxOpeningLikeElement(node)) { return inferJsxTypeArguments(node, signature, checkMode, context); } @@ -29903,8 +29250,8 @@ namespace ts { // example, given a 'function wrap(cb: (x: T) => U): (x: T) => U' and a call expression // 'let f: (x: string) => number = wrap(s => s.length)', we infer from the declared type of 'f' to the // return type of 'wrap'. - if (node.kind !== SyntaxKind.Decorator) { - const contextualType = getContextualType(node, every(signature.typeParameters, p => !!getDefaultFromTypeParameter(p)) ? ContextFlags.SkipBindingPatterns : ContextFlags.None); + if (node.kind !== ts.SyntaxKind.Decorator) { + const contextualType = getContextualType(node, ts.every(signature.typeParameters, p => !!getDefaultFromTypeParameter(p)) ? ts.ContextFlags.SkipBindingPatterns : ts.ContextFlags.None); if (contextualType) { const inferenceTargetType = getReturnTypeOfSignature(signature); if (couldContainTypeVariables(inferenceTargetType)) { @@ -29912,7 +29259,7 @@ namespace ts { // outer call expression. Effectively we just want a snapshot of whatever has been // inferred for any outer call expression so far. const outerContext = getInferenceContext(node); - const outerMapper = getMapperFromContext(cloneInferenceContext(outerContext, InferenceFlags.NoDefault)); + const outerMapper = getMapperFromContext(cloneInferenceContext(outerContext, ts.InferenceFlags.NoDefault)); const instantiatedType = instantiateType(contextualType, outerMapper); // If the contextual type is a generic function type with a single call signature, we // instantiate the type with its own type parameters and type arguments. This ensures that @@ -29926,7 +29273,7 @@ namespace ts { getOrCreateTypeFromSignature(getSignatureInstantiationWithoutFillingInTypeArguments(contextualSignature, contextualSignature.typeParameters)) : instantiatedType; // Inferences made from return types have lower priority than all other inferences. - inferTypes(context.inferences, inferenceSourceType, inferenceTargetType, InferencePriority.ReturnType); + inferTypes(context.inferences, inferenceSourceType, inferenceTargetType, ts.InferencePriority.ReturnType); // Create a type mapper for instantiating generic contextual types using the inferences made // from the return type. We need a separate inference pass here because (a) instantiation of // the source type uses the outer context's return mapper (which excludes inferences made from @@ -29934,17 +29281,17 @@ namespace ts { const returnContext = createInferenceContext(signature.typeParameters!, signature, context.flags); const returnSourceType = instantiateType(contextualType, outerContext && outerContext.returnMapper); inferTypes(returnContext.inferences, returnSourceType, inferenceTargetType); - context.returnMapper = some(returnContext.inferences, hasInferenceCandidates) ? getMapperFromContext(cloneInferredPartOfContext(returnContext)) : undefined; + context.returnMapper = ts.some(returnContext.inferences, hasInferenceCandidates) ? getMapperFromContext(cloneInferredPartOfContext(returnContext)) : undefined; } } } const restType = getNonArrayRestType(signature); const argCount = restType ? Math.min(getParameterCount(signature) - 1, args.length) : args.length; - if (restType && restType.flags & TypeFlags.TypeParameter) { - const info = find(context.inferences, info => info.typeParameter === restType); + if (restType && restType.flags & ts.TypeFlags.TypeParameter) { + const info = ts.find(context.inferences, info => info.typeParameter === restType); if (info) { - info.impliedArity = findIndex(args, isSpreadArgument, argCount) < 0 ? args.length - argCount : undefined; + info.impliedArity = ts.findIndex(args, isSpreadArgument, argCount) < 0 ? args.length - argCount : undefined; } } @@ -29956,7 +29303,7 @@ namespace ts { for (let i = 0; i < argCount; i++) { const arg = args[i]; - if (arg.kind !== SyntaxKind.OmittedExpression && !(checkMode & CheckMode.IsForStringLiteralArgumentCompletions && hasSkipDirectInferenceFlag(arg))) { + if (arg.kind !== ts.SyntaxKind.OmittedExpression && !(checkMode & CheckMode.IsForStringLiteralArgumentCompletions && hasSkipDirectInferenceFlag(arg))) { const paramType = getTypeAtPosition(signature, i); if (couldContainTypeVariables(paramType)) { const argType = checkExpressionWithContextualType(arg, paramType, context, checkMode); @@ -29973,21 +29320,21 @@ namespace ts { return getInferredTypes(context); } - function getMutableArrayOrTupleType(type: Type) { - return type.flags & TypeFlags.Union ? mapType(type, getMutableArrayOrTupleType) : - type.flags & TypeFlags.Any || isMutableArrayOrTuple(getBaseConstraintOfType(type) || type) ? type : + function getMutableArrayOrTupleType(type: ts.Type) { + return type.flags & ts.TypeFlags.Union ? mapType(type, getMutableArrayOrTupleType) : + type.flags & ts.TypeFlags.Any || isMutableArrayOrTuple(getBaseConstraintOfType(type) || type) ? type : isTupleType(type) ? createTupleType(getTypeArguments(type), type.target.elementFlags, /*readonly*/ false, type.target.labeledElementDeclarations) : - createTupleType([type], [ElementFlags.Variadic]); + createTupleType([type], [ts.ElementFlags.Variadic]); } - function getSpreadArgumentType(args: readonly Expression[], index: number, argCount: number, restType: Type, context: InferenceContext | undefined, checkMode: CheckMode) { + function getSpreadArgumentType(args: readonly ts.Expression[], index: number, argCount: number, restType: ts.Type, context: ts.InferenceContext | undefined, checkMode: CheckMode) { if (index >= argCount - 1) { const arg = args[argCount - 1]; if (isSpreadArgument(arg)) { // We are inferring from a spread expression in the last argument position, i.e. both the parameter // and the argument are ...x forms. - return getMutableArrayOrTupleType(arg.kind === SyntaxKind.SyntheticExpression ? (arg as SyntheticExpression).type : - checkExpressionWithContextualType((arg as SpreadElement).expression, restType, context, checkMode)); + return getMutableArrayOrTupleType(arg.kind === ts.SyntaxKind.SyntheticExpression ? (arg as ts.SyntheticExpression).type : + checkExpressionWithContextualType((arg as ts.SpreadElement).expression, restType, context, checkMode)); } } const types = []; @@ -29996,51 +29343,46 @@ namespace ts { for (let i = index; i < argCount; i++) { const arg = args[i]; if (isSpreadArgument(arg)) { - const spreadType = arg.kind === SyntaxKind.SyntheticExpression ? (arg as SyntheticExpression).type : checkExpression((arg as SpreadElement).expression); + const spreadType = arg.kind === ts.SyntaxKind.SyntheticExpression ? (arg as ts.SyntheticExpression).type : checkExpression((arg as ts.SpreadElement).expression); if (isArrayLikeType(spreadType)) { types.push(spreadType); - flags.push(ElementFlags.Variadic); + flags.push(ts.ElementFlags.Variadic); } else { - types.push(checkIteratedTypeOrElementType(IterationUse.Spread, spreadType, undefinedType, arg.kind === SyntaxKind.SpreadElement ? (arg as SpreadElement).expression : arg)); - flags.push(ElementFlags.Rest); + types.push(checkIteratedTypeOrElementType(IterationUse.Spread, spreadType, undefinedType, arg.kind === ts.SyntaxKind.SpreadElement ? (arg as ts.SpreadElement).expression : arg)); + flags.push(ts.ElementFlags.Rest); } } else { - const contextualType = getIndexedAccessType(restType, getNumberLiteralType(i - index), AccessFlags.Contextual); + const contextualType = getIndexedAccessType(restType, getNumberLiteralType(i - index), ts.AccessFlags.Contextual); const argType = checkExpressionWithContextualType(arg, contextualType, context, checkMode); - const hasPrimitiveContextualType = maybeTypeOfKind(contextualType, TypeFlags.Primitive | TypeFlags.Index | TypeFlags.TemplateLiteral | TypeFlags.StringMapping); + const hasPrimitiveContextualType = maybeTypeOfKind(contextualType, ts.TypeFlags.Primitive | ts.TypeFlags.Index | ts.TypeFlags.TemplateLiteral | ts.TypeFlags.StringMapping); types.push(hasPrimitiveContextualType ? getRegularTypeOfLiteralType(argType) : getWidenedLiteralType(argType)); - flags.push(ElementFlags.Required); + flags.push(ts.ElementFlags.Required); } - if (arg.kind === SyntaxKind.SyntheticExpression && (arg as SyntheticExpression).tupleNameSource) { - names.push((arg as SyntheticExpression).tupleNameSource!); + if (arg.kind === ts.SyntaxKind.SyntheticExpression && (arg as ts.SyntheticExpression).tupleNameSource) { + names.push((arg as ts.SyntheticExpression).tupleNameSource!); } } - return createTupleType(types, flags, /*readonly*/ false, length(names) === length(types) ? names : undefined); + return createTupleType(types, flags, /*readonly*/ false, ts.length(names) === ts.length(types) ? names : undefined); } - function checkTypeArguments(signature: Signature, typeArgumentNodes: readonly TypeNode[], reportErrors: boolean, headMessage?: DiagnosticMessage): Type[] | undefined { - const isJavascript = isInJSFile(signature.declaration); + function checkTypeArguments(signature: ts.Signature, typeArgumentNodes: readonly ts.TypeNode[], reportErrors: boolean, headMessage?: ts.DiagnosticMessage): ts.Type[] | undefined { + const isJavascript = ts.isInJSFile(signature.declaration); const typeParameters = signature.typeParameters!; - const typeArgumentTypes = fillMissingTypeArguments(map(typeArgumentNodes, getTypeFromTypeNode), typeParameters, getMinTypeArgumentCount(typeParameters), isJavascript); - let mapper: TypeMapper | undefined; + const typeArgumentTypes = fillMissingTypeArguments(ts.map(typeArgumentNodes, getTypeFromTypeNode), typeParameters, getMinTypeArgumentCount(typeParameters), isJavascript); + let mapper: ts.TypeMapper | undefined; for (let i = 0; i < typeArgumentNodes.length; i++) { - Debug.assert(typeParameters[i] !== undefined, "Should not call checkTypeArguments with too many type arguments"); + ts.Debug.assert(typeParameters[i] !== undefined, "Should not call checkTypeArguments with too many type arguments"); const constraint = getConstraintOfTypeParameter(typeParameters[i]); if (constraint) { - const errorInfo = reportErrors && headMessage ? (() => chainDiagnosticMessages(/*details*/ undefined, Diagnostics.Type_0_does_not_satisfy_the_constraint_1)) : undefined; - const typeArgumentHeadMessage = headMessage || Diagnostics.Type_0_does_not_satisfy_the_constraint_1; + const errorInfo = reportErrors && headMessage ? (() => ts.chainDiagnosticMessages(/*details*/ undefined, ts.Diagnostics.Type_0_does_not_satisfy_the_constraint_1)) : undefined; + const typeArgumentHeadMessage = headMessage || ts.Diagnostics.Type_0_does_not_satisfy_the_constraint_1; if (!mapper) { mapper = createTypeMapper(typeParameters, typeArgumentTypes); } const typeArgument = typeArgumentTypes[i]; - if (!checkTypeAssignableTo( - typeArgument, - getTypeWithThisArgument(instantiateType(constraint, mapper), typeArgument), - reportErrors ? typeArgumentNodes[i] : undefined, - typeArgumentHeadMessage, - errorInfo)) { + if (!checkTypeAssignableTo(typeArgument, getTypeWithThisArgument(instantiateType(constraint, mapper), typeArgument), reportErrors ? typeArgumentNodes[i] : undefined, typeArgumentHeadMessage, errorInfo)) { return undefined; } } @@ -30048,18 +29390,18 @@ namespace ts { return typeArgumentTypes; } - function getJsxReferenceKind(node: JsxOpeningLikeElement): JsxReferenceKind { + function getJsxReferenceKind(node: ts.JsxOpeningLikeElement): ts.JsxReferenceKind { if (isJsxIntrinsicIdentifier(node.tagName)) { - return JsxReferenceKind.Mixed; + return ts.JsxReferenceKind.Mixed; } const tagType = getApparentType(checkExpression(node.tagName)); - if (length(getSignaturesOfType(tagType, SignatureKind.Construct))) { - return JsxReferenceKind.Component; + if (ts.length(getSignaturesOfType(tagType, ts.SignatureKind.Construct))) { + return ts.JsxReferenceKind.Component; } - if (length(getSignaturesOfType(tagType, SignatureKind.Call))) { - return JsxReferenceKind.Function; + if (ts.length(getSignaturesOfType(tagType, ts.SignatureKind.Call))) { + return ts.JsxReferenceKind.Function; } - return JsxReferenceKind.Mixed; + return ts.JsxReferenceKind.Mixed; } /** @@ -30068,54 +29410,42 @@ namespace ts { * @param signature a candidate signature we are trying whether it is a call signature * @param relation a relationship to check parameter and argument type */ - function checkApplicableSignatureForJsxOpeningLikeElement( - node: JsxOpeningLikeElement, - signature: Signature, - relation: ESMap, - checkMode: CheckMode, - reportErrors: boolean, - containingMessageChain: (() => DiagnosticMessageChain | undefined) | undefined, - errorOutputContainer: { errors?: Diagnostic[], skipLogging?: boolean } - ) { + function checkApplicableSignatureForJsxOpeningLikeElement(node: ts.JsxOpeningLikeElement, signature: ts.Signature, relation: ts.ESMap, checkMode: CheckMode, reportErrors: boolean, containingMessageChain: (() => ts.DiagnosticMessageChain | undefined) | undefined, errorOutputContainer: { + errors?: ts.Diagnostic[]; + skipLogging?: boolean; + }) { // Stateless function components can have maximum of three arguments: "props", "context", and "updater". // However "context" and "updater" are implicit and can't be specify by users. Only the first parameter, props, // can be specified by users through attributes property. const paramType = getEffectiveFirstArgumentForJsxSignature(signature, node); const attributesType = checkExpressionWithContextualType(node.attributes, paramType, /*inferenceContext*/ undefined, checkMode); - return checkTagNameDoesNotExpectTooManyArguments() && checkTypeRelatedToAndOptionallyElaborate( - attributesType, - paramType, - relation, - reportErrors ? node.tagName : undefined, - node.attributes, - /*headMessage*/ undefined, - containingMessageChain, - errorOutputContainer); + return checkTagNameDoesNotExpectTooManyArguments() && checkTypeRelatedToAndOptionallyElaborate(attributesType, paramType, relation, reportErrors ? node.tagName : undefined, node.attributes, + /*headMessage*/ undefined, containingMessageChain, errorOutputContainer); function checkTagNameDoesNotExpectTooManyArguments(): boolean { if (getJsxNamespaceContainerForImplicitImport(node)) { return true; // factory is implicitly jsx/jsxdev - assume it fits the bill, since we don't strongly look for the jsx/jsxs/jsxDEV factory APIs anywhere else (at least not yet) } - const tagType = isJsxOpeningElement(node) || isJsxSelfClosingElement(node) && !isJsxIntrinsicIdentifier(node.tagName) ? checkExpression(node.tagName) : undefined; + const tagType = ts.isJsxOpeningElement(node) || ts.isJsxSelfClosingElement(node) && !isJsxIntrinsicIdentifier(node.tagName) ? checkExpression(node.tagName) : undefined; if (!tagType) { return true; } - const tagCallSignatures = getSignaturesOfType(tagType, SignatureKind.Call); - if (!length(tagCallSignatures)) { + const tagCallSignatures = getSignaturesOfType(tagType, ts.SignatureKind.Call); + if (!ts.length(tagCallSignatures)) { return true; } const factory = getJsxFactoryEntity(node); if (!factory) { return true; } - const factorySymbol = resolveEntityName(factory, SymbolFlags.Value, /*ignoreErrors*/ true, /*dontResolveAlias*/ false, node); + const factorySymbol = resolveEntityName(factory, ts.SymbolFlags.Value, /*ignoreErrors*/ true, /*dontResolveAlias*/ false, node); if (!factorySymbol) { return true; } const factoryType = getTypeOfSymbol(factorySymbol); - const callSignatures = getSignaturesOfType(factoryType, SignatureKind.Call); - if (!length(callSignatures)) { + const callSignatures = getSignaturesOfType(factoryType, ts.SignatureKind.Call); + if (!ts.length(callSignatures)) { return true; } @@ -30124,8 +29454,9 @@ namespace ts { // Check that _some_ first parameter expects a FC-like thing, and that some overload of the SFC expects an acceptable number of arguments for (const sig of callSignatures) { const firstparam = getTypeAtPosition(sig, 0); - const signaturesOfParam = getSignaturesOfType(firstparam, SignatureKind.Call); - if (!length(signaturesOfParam)) continue; + const signaturesOfParam = getSignaturesOfType(firstparam, ts.SignatureKind.Call); + if (!ts.length(signaturesOfParam)) + continue; for (const paramSig of signaturesOfParam) { hasFirstParamSignatures = true; if (hasEffectiveRestParameter(paramSig)) { @@ -30154,10 +29485,10 @@ namespace ts { } if (reportErrors) { - const diag = createDiagnosticForNode(node.tagName, Diagnostics.Tag_0_expects_at_least_1_arguments_but_the_JSX_factory_2_provides_at_most_3, entityNameToString(node.tagName), absoluteMinArgCount, entityNameToString(factory), maxParamCount); + const diag = ts.createDiagnosticForNode(node.tagName, ts.Diagnostics.Tag_0_expects_at_least_1_arguments_but_the_JSX_factory_2_provides_at_most_3, ts.entityNameToString(node.tagName), absoluteMinArgCount, ts.entityNameToString(factory), maxParamCount); const tagNameDeclaration = getSymbolAtLocation(node.tagName)?.valueDeclaration; if (tagNameDeclaration) { - addRelatedInfo(diag, createDiagnosticForNode(tagNameDeclaration, Diagnostics._0_is_declared_here, entityNameToString(node.tagName))); + ts.addRelatedInfo(diag, ts.createDiagnosticForNode(tagNameDeclaration, ts.Diagnostics._0_is_declared_here, ts.entityNameToString(node.tagName))); } if (errorOutputContainer && errorOutputContainer.skipLogging) { (errorOutputContainer.errors || (errorOutputContainer.errors = [])).push(diag); @@ -30170,44 +29501,38 @@ namespace ts { } } - function getSignatureApplicabilityError( - node: CallLikeExpression, - args: readonly Expression[], - signature: Signature, - relation: ESMap, - checkMode: CheckMode, - reportErrors: boolean, - containingMessageChain: (() => DiagnosticMessageChain | undefined) | undefined, - ): readonly Diagnostic[] | undefined { - - const errorOutputContainer: { errors?: Diagnostic[], skipLogging?: boolean } = { errors: undefined, skipLogging: true }; - if (isJsxOpeningLikeElement(node)) { + function getSignatureApplicabilityError(node: ts.CallLikeExpression, args: readonly ts.Expression[], signature: ts.Signature, relation: ts.ESMap, checkMode: CheckMode, reportErrors: boolean, containingMessageChain: (() => ts.DiagnosticMessageChain | undefined) | undefined): readonly ts.Diagnostic[] | undefined { + const errorOutputContainer: { + errors?: ts.Diagnostic[]; + skipLogging?: boolean; + } = { errors: undefined, skipLogging: true }; + if (ts.isJsxOpeningLikeElement(node)) { if (!checkApplicableSignatureForJsxOpeningLikeElement(node, signature, relation, checkMode, reportErrors, containingMessageChain, errorOutputContainer)) { - Debug.assert(!reportErrors || !!errorOutputContainer.errors, "jsx should have errors when reporting errors"); - return errorOutputContainer.errors || emptyArray; + ts.Debug.assert(!reportErrors || !!errorOutputContainer.errors, "jsx should have errors when reporting errors"); + return errorOutputContainer.errors || ts.emptyArray; } return undefined; } const thisType = getThisTypeOfSignature(signature); - if (thisType && thisType !== voidType && node.kind !== SyntaxKind.NewExpression) { + if (thisType && thisType !== voidType && node.kind !== ts.SyntaxKind.NewExpression) { // If the called expression is not of the form `x.f` or `x["f"]`, then sourceType = voidType // If the signature's 'this' type is voidType, then the check is skipped -- anything is compatible. // If the expression is a new expression, then the check is skipped. const thisArgumentNode = getThisArgumentOfCall(node); const thisArgumentType = getThisArgumentType(thisArgumentNode); const errorNode = reportErrors ? (thisArgumentNode || node) : undefined; - const headMessage = Diagnostics.The_this_context_of_type_0_is_not_assignable_to_method_s_this_of_type_1; + const headMessage = ts.Diagnostics.The_this_context_of_type_0_is_not_assignable_to_method_s_this_of_type_1; if (!checkTypeRelatedTo(thisArgumentType, thisType, relation, errorNode, headMessage, containingMessageChain, errorOutputContainer)) { - Debug.assert(!reportErrors || !!errorOutputContainer.errors, "this parameter should have errors when reporting errors"); - return errorOutputContainer.errors || emptyArray; + ts.Debug.assert(!reportErrors || !!errorOutputContainer.errors, "this parameter should have errors when reporting errors"); + return errorOutputContainer.errors || ts.emptyArray; } } - const headMessage = Diagnostics.Argument_of_type_0_is_not_assignable_to_parameter_of_type_1; + const headMessage = ts.Diagnostics.Argument_of_type_0_is_not_assignable_to_parameter_of_type_1; const restType = getNonArrayRestType(signature); const argCount = restType ? Math.min(getParameterCount(signature) - 1, args.length) : args.length; for (let i = 0; i < argCount; i++) { const arg = args[i]; - if (arg.kind !== SyntaxKind.OmittedExpression) { + if (arg.kind !== ts.SyntaxKind.OmittedExpression) { const paramType = getTypeAtPosition(signature, i); const argType = checkExpressionWithContextualType(arg, paramType, /*inferenceContext*/ undefined, checkMode); // If one or more arguments are still excluded (as indicated by CheckMode.SkipContextSensitive), @@ -30215,9 +29540,9 @@ namespace ts { // parameter types yet and therefore excess property checks may yield false positives (see #17041). const checkArgType = checkMode & CheckMode.SkipContextSensitive ? getRegularTypeOfObjectLiteral(argType) : argType; if (!checkTypeRelatedToAndOptionallyElaborate(checkArgType, paramType, relation, reportErrors ? arg : undefined, arg, headMessage, containingMessageChain, errorOutputContainer)) { - Debug.assert(!reportErrors || !!errorOutputContainer.errors, "parameter should have errors when reporting errors"); + ts.Debug.assert(!reportErrors || !!errorOutputContainer.errors, "parameter should have errors when reporting errors"); maybeAddMissingAwaitInfo(arg, checkArgType, paramType); - return errorOutputContainer.errors || emptyArray; + return errorOutputContainer.errors || ts.emptyArray; } } } @@ -30227,16 +29552,16 @@ namespace ts { const errorNode = !reportErrors ? undefined : restArgCount === 0 ? node : restArgCount === 1 ? args[argCount] : - setTextRangePosEnd(createSyntheticExpression(node, spreadType), args[argCount].pos, args[args.length - 1].end); + ts.setTextRangePosEnd(createSyntheticExpression(node, spreadType), args[argCount].pos, args[args.length - 1].end); if (!checkTypeRelatedTo(spreadType, restType, relation, errorNode, headMessage, /*containingMessageChain*/ undefined, errorOutputContainer)) { - Debug.assert(!reportErrors || !!errorOutputContainer.errors, "rest parameter should have errors when reporting errors"); + ts.Debug.assert(!reportErrors || !!errorOutputContainer.errors, "rest parameter should have errors when reporting errors"); maybeAddMissingAwaitInfo(errorNode, spreadType, restType); - return errorOutputContainer.errors || emptyArray; + return errorOutputContainer.errors || ts.emptyArray; } } return undefined; - function maybeAddMissingAwaitInfo(errorNode: Node | undefined, source: Type, target: Type) { + function maybeAddMissingAwaitInfo(errorNode: ts.Node | undefined, source: ts.Type, target: ts.Type) { if (errorNode && reportErrors && errorOutputContainer.errors && errorOutputContainer.errors.length) { // Bail if target is Promise-like---something else is wrong if (getAwaitedTypeOfPromise(target)) { @@ -30244,7 +29569,7 @@ namespace ts { } const awaitedTypeOfSource = getAwaitedTypeOfPromise(source); if (awaitedTypeOfSource && isTypeRelatedTo(awaitedTypeOfSource, target, relation)) { - addRelatedInfo(errorOutputContainer.errors[0], createDiagnosticForNode(errorNode, Diagnostics.Did_you_forget_to_use_await)); + ts.addRelatedInfo(errorOutputContainer.errors[0], ts.createDiagnosticForNode(errorNode, ts.Diagnostics.Did_you_forget_to_use_await)); } } } @@ -30253,45 +29578,45 @@ namespace ts { /** * Returns the this argument in calls like x.f(...) and x[f](...). Undefined otherwise. */ - function getThisArgumentOfCall(node: CallLikeExpression): LeftHandSideExpression | undefined { - const expression = node.kind === SyntaxKind.CallExpression ? node.expression : - node.kind === SyntaxKind.TaggedTemplateExpression ? node.tag : undefined; + function getThisArgumentOfCall(node: ts.CallLikeExpression): ts.LeftHandSideExpression | undefined { + const expression = node.kind === ts.SyntaxKind.CallExpression ? node.expression : + node.kind === ts.SyntaxKind.TaggedTemplateExpression ? node.tag : undefined; if (expression) { - const callee = skipOuterExpressions(expression); - if (isAccessExpression(callee)) { + const callee = ts.skipOuterExpressions(expression); + if (ts.isAccessExpression(callee)) { return callee.expression; } } } - function createSyntheticExpression(parent: Node, type: Type, isSpread?: boolean, tupleNameSource?: ParameterDeclaration | NamedTupleMember) { - const result = parseNodeFactory.createSyntheticExpression(type, isSpread, tupleNameSource); - setTextRange(result, parent); - setParent(result, parent); + function createSyntheticExpression(parent: ts.Node, type: ts.Type, isSpread?: boolean, tupleNameSource?: ts.ParameterDeclaration | ts.NamedTupleMember) { + const result = ts.parseNodeFactory.createSyntheticExpression(type, isSpread, tupleNameSource); + ts.setTextRange(result, parent); + ts.setParent(result, parent); return result; } /** * Returns the effective arguments for an expression that works like a function invocation. */ - function getEffectiveCallArguments(node: CallLikeExpression): readonly Expression[] { - if (node.kind === SyntaxKind.TaggedTemplateExpression) { + function getEffectiveCallArguments(node: ts.CallLikeExpression): readonly ts.Expression[] { + if (node.kind === ts.SyntaxKind.TaggedTemplateExpression) { const template = node.template; - const args: Expression[] = [createSyntheticExpression(template, getGlobalTemplateStringsArrayType())]; - if (template.kind === SyntaxKind.TemplateExpression) { - forEach(template.templateSpans, span => { + const args: ts.Expression[] = [createSyntheticExpression(template, getGlobalTemplateStringsArrayType())]; + if (template.kind === ts.SyntaxKind.TemplateExpression) { + ts.forEach(template.templateSpans, span => { args.push(span.expression); }); } return args; } - if (node.kind === SyntaxKind.Decorator) { + if (node.kind === ts.SyntaxKind.Decorator) { return getEffectiveDecoratorArguments(node); } - if (isJsxOpeningLikeElement(node)) { - return node.attributes.properties.length > 0 || (isJsxOpeningElement(node) && node.parent.children.length > 0) ? [node.attributes] : emptyArray; + if (ts.isJsxOpeningLikeElement(node)) { + return node.attributes.properties.length > 0 || (ts.isJsxOpeningElement(node) && node.parent.children.length > 0) ? [node.attributes] : ts.emptyArray; } - const args = node.arguments || emptyArray; + const args = node.arguments || ts.emptyArray; const spreadIndex = getSpreadArgumentIndex(args); if (spreadIndex >= 0) { // Create synthetic arguments from spreads of tuple types. @@ -30299,12 +29624,11 @@ namespace ts { for (let i = spreadIndex; i < args.length; i++) { const arg = args[i]; // We can call checkExpressionCached because spread expressions never have a contextual type. - const spreadType = arg.kind === SyntaxKind.SpreadElement && (flowLoopCount ? checkExpression((arg as SpreadElement).expression) : checkExpressionCached((arg as SpreadElement).expression)); + const spreadType = arg.kind === ts.SyntaxKind.SpreadElement && (flowLoopCount ? checkExpression((arg as ts.SpreadElement).expression) : checkExpressionCached((arg as ts.SpreadElement).expression)); if (spreadType && isTupleType(spreadType)) { - forEach(getTypeArguments(spreadType), (t, i) => { + ts.forEach(getTypeArguments(spreadType), (t, i) => { const flags = spreadType.target.elementFlags[i]; - const syntheticArg = createSyntheticExpression(arg, flags & ElementFlags.Rest ? createArrayType(t) : t, - !!(flags & ElementFlags.Variable), spreadType.target.labeledElementDeclarations?.[i]); + const syntheticArg = createSyntheticExpression(arg, flags & ts.ElementFlags.Rest ? createArrayType(t) : t, !!(flags & ts.ElementFlags.Variable), spreadType.target.labeledElementDeclarations?.[i]); effectiveArgs.push(syntheticArg); }); } @@ -30320,118 +29644,118 @@ namespace ts { /** * Returns the synthetic argument list for a decorator invocation. */ - function getEffectiveDecoratorArguments(node: Decorator): readonly Expression[] { + function getEffectiveDecoratorArguments(node: ts.Decorator): readonly ts.Expression[] { const parent = node.parent; const expr = node.expression; switch (parent.kind) { - case SyntaxKind.ClassDeclaration: - case SyntaxKind.ClassExpression: + case ts.SyntaxKind.ClassDeclaration: + case ts.SyntaxKind.ClassExpression: // For a class decorator, the `target` is the type of the class (e.g. the // "static" or "constructor" side of the class). return [ createSyntheticExpression(expr, getTypeOfSymbol(getSymbolOfNode(parent))) ]; - case SyntaxKind.Parameter: + case ts.SyntaxKind.Parameter: // A parameter declaration decorator will have three arguments (see // `ParameterDecorator` in core.d.ts). - const func = parent.parent as FunctionLikeDeclaration; + const func = parent.parent as ts.FunctionLikeDeclaration; return [ - createSyntheticExpression(expr, parent.parent.kind === SyntaxKind.Constructor ? getTypeOfSymbol(getSymbolOfNode(func)) : errorType), + createSyntheticExpression(expr, parent.parent.kind === ts.SyntaxKind.Constructor ? getTypeOfSymbol(getSymbolOfNode(func)) : errorType), createSyntheticExpression(expr, anyType), createSyntheticExpression(expr, numberType) ]; - case SyntaxKind.PropertyDeclaration: - case SyntaxKind.MethodDeclaration: - case SyntaxKind.GetAccessor: - case SyntaxKind.SetAccessor: + case ts.SyntaxKind.PropertyDeclaration: + case ts.SyntaxKind.MethodDeclaration: + case ts.SyntaxKind.GetAccessor: + case ts.SyntaxKind.SetAccessor: // A method or accessor declaration decorator will have two or three arguments (see // `PropertyDecorator` and `MethodDecorator` in core.d.ts). If we are emitting decorators // for ES3, we will only pass two arguments. - const hasPropDesc = parent.kind !== SyntaxKind.PropertyDeclaration && languageVersion !== ScriptTarget.ES3; + const hasPropDesc = parent.kind !== ts.SyntaxKind.PropertyDeclaration && languageVersion !== ts.ScriptTarget.ES3; return [ - createSyntheticExpression(expr, getParentTypeOfClassElement(parent as ClassElement)), - createSyntheticExpression(expr, getClassElementPropertyKeyType(parent as ClassElement)), + createSyntheticExpression(expr, getParentTypeOfClassElement(parent as ts.ClassElement)), + createSyntheticExpression(expr, getClassElementPropertyKeyType(parent as ts.ClassElement)), createSyntheticExpression(expr, hasPropDesc ? createTypedPropertyDescriptorType(getTypeOfNode(parent)) : anyType) ]; } - return Debug.fail(); + return ts.Debug.fail(); } /** * Returns the argument count for a decorator node that works like a function invocation. */ - function getDecoratorArgumentCount(node: Decorator, signature: Signature) { + function getDecoratorArgumentCount(node: ts.Decorator, signature: ts.Signature) { switch (node.parent.kind) { - case SyntaxKind.ClassDeclaration: - case SyntaxKind.ClassExpression: + case ts.SyntaxKind.ClassDeclaration: + case ts.SyntaxKind.ClassExpression: return 1; - case SyntaxKind.PropertyDeclaration: + case ts.SyntaxKind.PropertyDeclaration: return 2; - case SyntaxKind.MethodDeclaration: - case SyntaxKind.GetAccessor: - case SyntaxKind.SetAccessor: + case ts.SyntaxKind.MethodDeclaration: + case ts.SyntaxKind.GetAccessor: + case ts.SyntaxKind.SetAccessor: // For ES3 or decorators with only two parameters we supply only two arguments - return languageVersion === ScriptTarget.ES3 || signature.parameters.length <= 2 ? 2 : 3; - case SyntaxKind.Parameter: + return languageVersion === ts.ScriptTarget.ES3 || signature.parameters.length <= 2 ? 2 : 3; + case ts.SyntaxKind.Parameter: return 3; default: - return Debug.fail(); + return ts.Debug.fail(); } } - function getDiagnosticSpanForCallNode(node: CallExpression, doNotIncludeArguments?: boolean) { + function getDiagnosticSpanForCallNode(node: ts.CallExpression, doNotIncludeArguments?: boolean) { let start: number; let length: number; - const sourceFile = getSourceFileOfNode(node); - - if (isPropertyAccessExpression(node.expression)) { - const nameSpan = getErrorSpanForNode(sourceFile, node.expression.name); + const sourceFile = ts.getSourceFileOfNode(node); + if (ts.isPropertyAccessExpression(node.expression)) { + const nameSpan = ts.getErrorSpanForNode(sourceFile, node.expression.name); start = nameSpan.start; length = doNotIncludeArguments ? nameSpan.length : node.end - start; } else { - const expressionSpan = getErrorSpanForNode(sourceFile, node.expression); + const expressionSpan = ts.getErrorSpanForNode(sourceFile, node.expression); start = expressionSpan.start; length = doNotIncludeArguments ? expressionSpan.length : node.end - start; } return { start, length, sourceFile }; } - function getDiagnosticForCallNode(node: CallLikeExpression, message: DiagnosticMessage, arg0?: string | number, arg1?: string | number, arg2?: string | number, arg3?: string | number): DiagnosticWithLocation { - if (isCallExpression(node)) { + function getDiagnosticForCallNode(node: ts.CallLikeExpression, message: ts.DiagnosticMessage, arg0?: string | number, arg1?: string | number, arg2?: string | number, arg3?: string | number): ts.DiagnosticWithLocation { + if (ts.isCallExpression(node)) { const { sourceFile, start, length } = getDiagnosticSpanForCallNode(node); - return createFileDiagnostic(sourceFile, start, length, message, arg0, arg1, arg2, arg3); + return ts.createFileDiagnostic(sourceFile, start, length, message, arg0, arg1, arg2, arg3); } else { - return createDiagnosticForNode(node, message, arg0, arg1, arg2, arg3); + return ts.createDiagnosticForNode(node, message, arg0, arg1, arg2, arg3); } } - function isPromiseResolveArityError(node: CallLikeExpression) { - if (!isCallExpression(node) || !isIdentifier(node.expression)) return false; - - const symbol = resolveName(node.expression, node.expression.escapedText, SymbolFlags.Value, undefined, undefined, false); + function isPromiseResolveArityError(node: ts.CallLikeExpression) { + if (!ts.isCallExpression(node) || !ts.isIdentifier(node.expression)) + return false; + const symbol = resolveName(node.expression, node.expression.escapedText, ts.SymbolFlags.Value, undefined, undefined, false); const decl = symbol?.valueDeclaration; - if (!decl || !isParameter(decl) || !isFunctionExpressionOrArrowFunction(decl.parent) || !isNewExpression(decl.parent.parent) || !isIdentifier(decl.parent.parent.expression)) { + if (!decl || !ts.isParameter(decl) || !ts.isFunctionExpressionOrArrowFunction(decl.parent) || !ts.isNewExpression(decl.parent.parent) || !ts.isIdentifier(decl.parent.parent.expression)) { return false; } const globalPromiseSymbol = getGlobalPromiseConstructorSymbol(/*reportErrors*/ false); - if (!globalPromiseSymbol) return false; + if (!globalPromiseSymbol) + return false; const constructorSymbol = getSymbolAtLocation(decl.parent.parent.expression, /*ignoreErrors*/ true); return constructorSymbol === globalPromiseSymbol; } - function getArgumentArityError(node: CallLikeExpression, signatures: readonly Signature[], args: readonly Expression[]) { + function getArgumentArityError(node: ts.CallLikeExpression, signatures: readonly ts.Signature[], args: readonly ts.Expression[]) { const spreadIndex = getSpreadArgumentIndex(args); if (spreadIndex > -1) { - return createDiagnosticForNode(args[spreadIndex], Diagnostics.A_spread_argument_must_either_have_a_tuple_type_or_be_passed_to_a_rest_parameter); + return ts.createDiagnosticForNode(args[spreadIndex], ts.Diagnostics.A_spread_argument_must_either_have_a_tuple_type_or_be_passed_to_a_rest_parameter); } let min = Number.POSITIVE_INFINITY; // smallest parameter count let max = Number.NEGATIVE_INFINITY; // largest parameter count let maxBelow = Number.NEGATIVE_INFINITY; // largest parameter count that is smaller than the number of arguments let minAbove = Number.POSITIVE_INFINITY; // smallest parameter count that is larger than the number of arguments - let closestSignature: Signature | undefined; + let closestSignature: ts.Signature | undefined; for (const sig of signatures) { const minParameter = getMinArgumentCount(sig); const maxParameter = getParameterCount(sig); @@ -30442,70 +29766,68 @@ namespace ts { } max = Math.max(max, maxParameter); // shortest parameter count *longer than the call*/longest parameter count *shorter than the call* - if (minParameter < args.length && minParameter > maxBelow) maxBelow = minParameter; - if (args.length < maxParameter && maxParameter < minAbove) minAbove = maxParameter; + if (minParameter < args.length && minParameter > maxBelow) + maxBelow = minParameter; + if (args.length < maxParameter && maxParameter < minAbove) + minAbove = maxParameter; } - const hasRestParameter = some(signatures, hasEffectiveRestParameter); + const hasRestParameter = ts.some(signatures, hasEffectiveRestParameter); const parameterRange = hasRestParameter ? min : min < max ? min + "-" + max : min; const isVoidPromiseError = !hasRestParameter && parameterRange === 1 && args.length === 0 && isPromiseResolveArityError(node); - if (isVoidPromiseError && isInJSFile(node)) { - return getDiagnosticForCallNode(node, Diagnostics.Expected_1_argument_but_got_0_new_Promise_needs_a_JSDoc_hint_to_produce_a_resolve_that_can_be_called_without_arguments); + if (isVoidPromiseError && ts.isInJSFile(node)) { + return getDiagnosticForCallNode(node, ts.Diagnostics.Expected_1_argument_but_got_0_new_Promise_needs_a_JSDoc_hint_to_produce_a_resolve_that_can_be_called_without_arguments); } const error = hasRestParameter - ? Diagnostics.Expected_at_least_0_arguments_but_got_1 + ? ts.Diagnostics.Expected_at_least_0_arguments_but_got_1 : isVoidPromiseError - ? Diagnostics.Expected_0_arguments_but_got_1_Did_you_forget_to_include_void_in_your_type_argument_to_Promise - : Diagnostics.Expected_0_arguments_but_got_1; + ? ts.Diagnostics.Expected_0_arguments_but_got_1_Did_you_forget_to_include_void_in_your_type_argument_to_Promise + : ts.Diagnostics.Expected_0_arguments_but_got_1; if (min < args.length && args.length < max) { // between min and max, but with no matching overload - return getDiagnosticForCallNode(node, Diagnostics.No_overload_expects_0_arguments_but_overloads_do_exist_that_expect_either_1_or_2_arguments, args.length, maxBelow, minAbove); + return getDiagnosticForCallNode(node, ts.Diagnostics.No_overload_expects_0_arguments_but_overloads_do_exist_that_expect_either_1_or_2_arguments, args.length, maxBelow, minAbove); } else if (args.length < min) { // too short: put the error span on the call expression, not any of the args const diagnostic = getDiagnosticForCallNode(node, error, parameterRange, args.length); const parameter = closestSignature?.declaration?.parameters[closestSignature.thisParameter ? args.length + 1 : args.length]; if (parameter) { - const parameterError = createDiagnosticForNode( - parameter, - isBindingPattern(parameter.name) ? Diagnostics.An_argument_matching_this_binding_pattern_was_not_provided - : isRestParameter(parameter) ? Diagnostics.Arguments_for_the_rest_parameter_0_were_not_provided - : Diagnostics.An_argument_for_0_was_not_provided, - !parameter.name ? args.length : !isBindingPattern(parameter.name) ? idText(getFirstIdentifier(parameter.name)) : undefined - ); - return addRelatedInfo(diagnostic, parameterError); + const parameterError = ts.createDiagnosticForNode(parameter, ts.isBindingPattern(parameter.name) ? ts.Diagnostics.An_argument_matching_this_binding_pattern_was_not_provided + : ts.isRestParameter(parameter) ? ts.Diagnostics.Arguments_for_the_rest_parameter_0_were_not_provided + : ts.Diagnostics.An_argument_for_0_was_not_provided, !parameter.name ? args.length : !ts.isBindingPattern(parameter.name) ? ts.idText(ts.getFirstIdentifier(parameter.name)) : undefined); + return ts.addRelatedInfo(diagnostic, parameterError); } return diagnostic; } else { // too long; error goes on the excess parameters - const errorSpan = factory.createNodeArray(args.slice(max)); - const pos = first(errorSpan).pos; - let end = last(errorSpan).end; + const errorSpan = ts.factory.createNodeArray(args.slice(max)); + const pos = ts.first(errorSpan).pos; + let end = ts.last(errorSpan).end; if (end === pos) { end++; } - setTextRangePosEnd(errorSpan, pos, end); - return createDiagnosticForNodeArray(getSourceFileOfNode(node), errorSpan, error, parameterRange, args.length); + ts.setTextRangePosEnd(errorSpan, pos, end); + return ts.createDiagnosticForNodeArray(ts.getSourceFileOfNode(node), errorSpan, error, parameterRange, args.length); } } - function getTypeArgumentArityError(node: Node, signatures: readonly Signature[], typeArguments: NodeArray) { + function getTypeArgumentArityError(node: ts.Node, signatures: readonly ts.Signature[], typeArguments: ts.NodeArray) { const argCount = typeArguments.length; // No overloads exist if (signatures.length === 1) { const sig = signatures[0]; const min = getMinTypeArgumentCount(sig.typeParameters); - const max = length(sig.typeParameters); - return createDiagnosticForNodeArray(getSourceFileOfNode(node), typeArguments, Diagnostics.Expected_0_type_arguments_but_got_1, min < max ? min + "-" + max : min , argCount); + const max = ts.length(sig.typeParameters); + return ts.createDiagnosticForNodeArray(ts.getSourceFileOfNode(node), typeArguments, ts.Diagnostics.Expected_0_type_arguments_but_got_1, min < max ? min + "-" + max : min, argCount); } // Overloads exist let belowArgCount = -Infinity; let aboveArgCount = Infinity; for (const sig of signatures) { const min = getMinTypeArgumentCount(sig.typeParameters); - const max = length(sig.typeParameters); + const max = ts.length(sig.typeParameters); if (min > argCount) { aboveArgCount = Math.min(aboveArgCount, min); } @@ -30514,25 +29836,25 @@ namespace ts { } } if (belowArgCount !== -Infinity && aboveArgCount !== Infinity) { - return createDiagnosticForNodeArray(getSourceFileOfNode(node), typeArguments, Diagnostics.No_overload_expects_0_type_arguments_but_overloads_do_exist_that_expect_either_1_or_2_type_arguments, argCount, belowArgCount, aboveArgCount); + return ts.createDiagnosticForNodeArray(ts.getSourceFileOfNode(node), typeArguments, ts.Diagnostics.No_overload_expects_0_type_arguments_but_overloads_do_exist_that_expect_either_1_or_2_type_arguments, argCount, belowArgCount, aboveArgCount); } - return createDiagnosticForNodeArray(getSourceFileOfNode(node), typeArguments, Diagnostics.Expected_0_type_arguments_but_got_1, belowArgCount === -Infinity ? aboveArgCount : belowArgCount, argCount); + return ts.createDiagnosticForNodeArray(ts.getSourceFileOfNode(node), typeArguments, ts.Diagnostics.Expected_0_type_arguments_but_got_1, belowArgCount === -Infinity ? aboveArgCount : belowArgCount, argCount); } - function resolveCall(node: CallLikeExpression, signatures: readonly Signature[], candidatesOutArray: Signature[] | undefined, checkMode: CheckMode, callChainFlags: SignatureFlags, fallbackError?: DiagnosticMessage): Signature { - const isTaggedTemplate = node.kind === SyntaxKind.TaggedTemplateExpression; - const isDecorator = node.kind === SyntaxKind.Decorator; - const isJsxOpeningOrSelfClosingElement = isJsxOpeningLikeElement(node); + function resolveCall(node: ts.CallLikeExpression, signatures: readonly ts.Signature[], candidatesOutArray: ts.Signature[] | undefined, checkMode: CheckMode, callChainFlags: ts.SignatureFlags, fallbackError?: ts.DiagnosticMessage): ts.Signature { + const isTaggedTemplate = node.kind === ts.SyntaxKind.TaggedTemplateExpression; + const isDecorator = node.kind === ts.SyntaxKind.Decorator; + const isJsxOpeningOrSelfClosingElement = ts.isJsxOpeningLikeElement(node); const reportErrors = !candidatesOutArray; - let typeArguments: NodeArray | undefined; + let typeArguments: ts.NodeArray | undefined; if (!isDecorator) { - typeArguments = (node as CallExpression).typeArguments; + typeArguments = (node as ts.CallExpression).typeArguments; // We already perform checking on the type arguments on the class declaration itself. - if (isTaggedTemplate || isJsxOpeningOrSelfClosingElement || (node as CallExpression).expression.kind !== SyntaxKind.SuperKeyword) { - forEach(typeArguments, checkSourceElement); + if (isTaggedTemplate || isJsxOpeningOrSelfClosingElement || (node as ts.CallExpression).expression.kind !== ts.SyntaxKind.SuperKeyword) { + ts.forEach(typeArguments, checkSourceElement); } } @@ -30541,7 +29863,7 @@ namespace ts { reorderCandidates(signatures, candidates, callChainFlags); if (!candidates.length) { if (reportErrors) { - diagnostics.add(getDiagnosticForCallNode(node, Diagnostics.Call_target_does_not_contain_any_signatures)); + diagnostics.add(getDiagnosticForCallNode(node, ts.Diagnostics.Call_target_does_not_contain_any_signatures)); } return resolveErrorCall(node); } @@ -30561,7 +29883,7 @@ namespace ts { // For a decorator, no arguments are susceptible to contextual typing due to the fact // decorators are applied to a declaration by the emitter, and not to an expression. const isSingleNonGenericCandidate = candidates.length === 1 && !candidates[0].typeParameters; - let argCheckMode = !isDecorator && !isSingleNonGenericCandidate && some(args, isContextSensitive) ? CheckMode.SkipContextSensitive : CheckMode.Normal; + let argCheckMode = !isDecorator && !isSingleNonGenericCandidate && ts.some(args, isContextSensitive) ? CheckMode.SkipContextSensitive : CheckMode.Normal; argCheckMode |= checkMode & CheckMode.IsForStringLiteralArgumentCompletions; // The following variables are captured and modified by calls to chooseOverload. @@ -30585,15 +29907,14 @@ namespace ts { // function foo(): void; // foo(0); // - let candidatesForArgumentError: Signature[] | undefined; - let candidateForArgumentArityError: Signature | undefined; - let candidateForTypeArgumentError: Signature | undefined; - let result: Signature | undefined; + let candidatesForArgumentError: ts.Signature[] | undefined; + let candidateForArgumentArityError: ts.Signature | undefined; + let candidateForTypeArgumentError: ts.Signature | undefined; + let result: ts.Signature | undefined; // If we are in signature help, a trailing comma indicates that we intend to provide another argument, // so we will only accept overloads with arity at least 1 higher than the current number of provided arguments. - const signatureHelpTrailingComma = - !!(checkMode & CheckMode.IsForSignatureHelp) && node.kind === SyntaxKind.CallExpression && node.arguments.hasTrailingComma; + const signatureHelpTrailingComma = !!(checkMode & CheckMode.IsForSignatureHelp) && node.kind === ts.SyntaxKind.CallExpression && node.arguments.hasTrailingComma; // Section 4.12.1: // if the candidate list contains one or more signatures for which the type of each argument @@ -30623,33 +29944,33 @@ namespace ts { if (candidatesForArgumentError) { if (candidatesForArgumentError.length === 1 || candidatesForArgumentError.length > 3) { const last = candidatesForArgumentError[candidatesForArgumentError.length - 1]; - let chain: DiagnosticMessageChain | undefined; + let chain: ts.DiagnosticMessageChain | undefined; if (candidatesForArgumentError.length > 3) { - chain = chainDiagnosticMessages(chain, Diagnostics.The_last_overload_gave_the_following_error); - chain = chainDiagnosticMessages(chain, Diagnostics.No_overload_matches_this_call); + chain = ts.chainDiagnosticMessages(chain, ts.Diagnostics.The_last_overload_gave_the_following_error); + chain = ts.chainDiagnosticMessages(chain, ts.Diagnostics.No_overload_matches_this_call); } const diags = getSignatureApplicabilityError(node, args, last, assignableRelation, CheckMode.Normal, /*reportErrors*/ true, () => chain); if (diags) { for (const d of diags) { if (last.declaration && candidatesForArgumentError.length > 3) { - addRelatedInfo(d, createDiagnosticForNode(last.declaration, Diagnostics.The_last_overload_is_declared_here)); + ts.addRelatedInfo(d, ts.createDiagnosticForNode(last.declaration, ts.Diagnostics.The_last_overload_is_declared_here)); } addImplementationSuccessElaboration(last, d); diagnostics.add(d); } } else { - Debug.fail("No error for last overload signature"); + ts.Debug.fail("No error for last overload signature"); } } else { - const allDiagnostics: (readonly DiagnosticRelatedInformation[])[] = []; + const allDiagnostics: (readonly ts.DiagnosticRelatedInformation[])[] = []; let max = 0; let min = Number.MAX_VALUE; let minIndex = 0; let i = 0; for (const c of candidatesForArgumentError) { - const chain = () => chainDiagnosticMessages(/*details*/ undefined, Diagnostics.Overload_0_of_1_2_gave_the_following_error, i + 1, candidates.length, signatureToString(c)); + const chain = () => ts.chainDiagnosticMessages(/*details*/ undefined, ts.Diagnostics.Overload_0_of_1_2_gave_the_following_error, i + 1, candidates.length, signatureToString(c)); const diags = getSignatureApplicabilityError(node, args, c, assignableRelation, CheckMode.Normal, /*reportErrors*/ true, chain); if (diags) { if (diags.length <= min) { @@ -30660,26 +29981,24 @@ namespace ts { allDiagnostics.push(diags); } else { - Debug.fail("No error for 3 or fewer overload signatures"); + ts.Debug.fail("No error for 3 or fewer overload signatures"); } i++; } - const diags = max > 1 ? allDiagnostics[minIndex] : flatten(allDiagnostics); - Debug.assert(diags.length > 0, "No errors reported for 3 or fewer overload signatures"); - const chain = chainDiagnosticMessages( - map(diags, createDiagnosticMessageChainFromDiagnostic), - Diagnostics.No_overload_matches_this_call); + const diags = max > 1 ? allDiagnostics[minIndex] : ts.flatten(allDiagnostics); + ts.Debug.assert(diags.length > 0, "No errors reported for 3 or fewer overload signatures"); + const chain = ts.chainDiagnosticMessages(ts.map(diags, ts.createDiagnosticMessageChainFromDiagnostic), ts.Diagnostics.No_overload_matches_this_call); // The below is a spread to guarantee we get a new (mutable) array - our `flatMap` helper tries to do "smart" optimizations where it reuses input // arrays and the emptyArray singleton where possible, which is decidedly not what we want while we're still constructing this diagnostic - const related = [...flatMap(diags, d => (d as Diagnostic).relatedInformation) as DiagnosticRelatedInformation[]]; - let diag: Diagnostic; - if (every(diags, d => d.start === diags[0].start && d.length === diags[0].length && d.file === diags[0].file)) { + const related = [...ts.flatMap(diags, d => (d as ts.Diagnostic).relatedInformation) as ts.DiagnosticRelatedInformation[]]; + let diag: ts.Diagnostic; + if (ts.every(diags, d => d.start === diags[0].start && d.length === diags[0].length && d.file === diags[0].file)) { const { file, start, length } = diags[0]; diag = { file, start, length, code: chain.code, category: chain.category, messageText: chain, relatedInformation: related }; } else { - diag = createDiagnosticForNodeFromMessageChain(node, chain, related); + diag = ts.createDiagnosticForNodeFromMessageChain(node, chain, related); } addImplementationSuccessElaboration(candidatesForArgumentError[0], diag); diagnostics.add(diag); @@ -30689,10 +30008,10 @@ namespace ts { diagnostics.add(getArgumentArityError(node, [candidateForArgumentArityError], args)); } else if (candidateForTypeArgumentError) { - checkTypeArguments(candidateForTypeArgumentError, (node as CallExpression | TaggedTemplateExpression | JsxOpeningLikeElement).typeArguments!, /*reportErrors*/ true, fallbackError); + checkTypeArguments(candidateForTypeArgumentError, (node as ts.CallExpression | ts.TaggedTemplateExpression | ts.JsxOpeningLikeElement).typeArguments!, /*reportErrors*/ true, fallbackError); } else { - const signaturesWithCorrectTypeArgumentArity = filter(signatures, s => hasCorrectTypeArgumentArity(s, typeArguments)); + const signaturesWithCorrectTypeArgumentArity = ts.filter(signatures, s => hasCorrectTypeArgumentArity(s, typeArguments)); if (signaturesWithCorrectTypeArgumentArity.length === 0) { diagnostics.add(getTypeArgumentArityError(node, signatures, typeArguments!)); } @@ -30707,19 +30026,19 @@ namespace ts { return getCandidateForOverloadFailure(node, candidates, args, !!candidatesOutArray, checkMode); - function addImplementationSuccessElaboration(failed: Signature, diagnostic: Diagnostic) { + function addImplementationSuccessElaboration(failed: ts.Signature, diagnostic: ts.Diagnostic) { const oldCandidatesForArgumentError = candidatesForArgumentError; const oldCandidateForArgumentArityError = candidateForArgumentArityError; const oldCandidateForTypeArgumentError = candidateForTypeArgumentError; - const failedSignatureDeclarations = failed.declaration?.symbol?.declarations || emptyArray; + const failedSignatureDeclarations = failed.declaration?.symbol?.declarations || ts.emptyArray; const isOverload = failedSignatureDeclarations.length > 1; - const implDecl = isOverload ? find(failedSignatureDeclarations, d => isFunctionLikeDeclaration(d) && nodeIsPresent(d.body)) : undefined; + const implDecl = isOverload ? ts.find(failedSignatureDeclarations, d => ts.isFunctionLikeDeclaration(d) && ts.nodeIsPresent(d.body)) : undefined; if (implDecl) { - const candidate = getSignatureFromDeclaration(implDecl as FunctionLikeDeclaration); + const candidate = getSignatureFromDeclaration(implDecl as ts.FunctionLikeDeclaration); const isSingleNonGenericCandidate = !candidate.typeParameters; if (chooseOverload([candidate], assignableRelation, isSingleNonGenericCandidate)) { - addRelatedInfo(diagnostic, createDiagnosticForNode(implDecl, Diagnostics.The_call_would_have_succeeded_against_this_implementation_but_implementation_signatures_of_overloads_are_not_externally_visible)); + ts.addRelatedInfo(diagnostic, ts.createDiagnosticForNode(implDecl, ts.Diagnostics.The_call_would_have_succeeded_against_this_implementation_but_implementation_signatures_of_overloads_are_not_externally_visible)); } } @@ -30728,14 +30047,14 @@ namespace ts { candidateForTypeArgumentError = oldCandidateForTypeArgumentError; } - function chooseOverload(candidates: Signature[], relation: ESMap, isSingleNonGenericCandidate: boolean, signatureHelpTrailingComma = false) { + function chooseOverload(candidates: ts.Signature[], relation: ts.ESMap, isSingleNonGenericCandidate: boolean, signatureHelpTrailingComma = false) { candidatesForArgumentError = undefined; candidateForArgumentArityError = undefined; candidateForTypeArgumentError = undefined; if (isSingleNonGenericCandidate) { const candidate = candidates[0]; - if (some(typeArguments) || !hasCorrectArity(node, args, candidate, signatureHelpTrailingComma)) { + if (ts.some(typeArguments) || !hasCorrectArity(node, args, candidate, signatureHelpTrailingComma)) { return undefined; } if (getSignatureApplicabilityError(node, args, candidate, relation, CheckMode.Normal, /*reportErrors*/ false, /*containingMessageChain*/ undefined)) { @@ -30751,12 +30070,12 @@ namespace ts { continue; } - let checkCandidate: Signature; - let inferenceContext: InferenceContext | undefined; + let checkCandidate: ts.Signature; + let inferenceContext: ts.InferenceContext | undefined; if (candidate.typeParameters) { - let typeArgumentTypes: Type[] | undefined; - if (some(typeArguments)) { + let typeArgumentTypes: ts.Type[] | undefined; + if (ts.some(typeArguments)) { typeArgumentTypes = checkTypeArguments(candidate, typeArguments, /*reportErrors*/ false); if (!typeArgumentTypes) { candidateForTypeArgumentError = candidate; @@ -30764,11 +30083,11 @@ namespace ts { } } else { - inferenceContext = createInferenceContext(candidate.typeParameters, candidate, /*flags*/ isInJSFile(node) ? InferenceFlags.AnyDefault : InferenceFlags.None); + inferenceContext = createInferenceContext(candidate.typeParameters, candidate, /*flags*/ ts.isInJSFile(node) ? ts.InferenceFlags.AnyDefault : ts.InferenceFlags.None); typeArgumentTypes = inferTypeArguments(node, candidate, args, argCheckMode | CheckMode.SkipGenericFunctions, inferenceContext); - argCheckMode |= inferenceContext.flags & InferenceFlags.SkippedGenericFunction ? CheckMode.SkipGenericFunctions : CheckMode.Normal; + argCheckMode |= inferenceContext.flags & ts.InferenceFlags.SkippedGenericFunction ? CheckMode.SkipGenericFunctions : CheckMode.Normal; } - checkCandidate = getSignatureInstantiation(candidate, typeArgumentTypes, isInJSFile(candidate.declaration), inferenceContext && inferenceContext.inferredTypeParameters); + checkCandidate = getSignatureInstantiation(candidate, typeArgumentTypes, ts.isInJSFile(candidate.declaration), inferenceContext && inferenceContext.inferredTypeParameters); // If the original signature has a generic rest type, instantiation may produce a // signature with different arity and we need to perform another arity check. if (getNonArrayRestType(candidate) && !hasCorrectArity(node, args, checkCandidate, signatureHelpTrailingComma)) { @@ -30791,7 +30110,7 @@ namespace ts { argCheckMode = checkMode & CheckMode.IsForStringLiteralArgumentCompletions; if (inferenceContext) { const typeArgumentTypes = inferTypeArguments(node, candidate, args, argCheckMode, inferenceContext); - checkCandidate = getSignatureInstantiation(candidate, typeArgumentTypes, isInJSFile(candidate.declaration), inferenceContext && inferenceContext.inferredTypeParameters); + checkCandidate = getSignatureInstantiation(candidate, typeArgumentTypes, ts.isInJSFile(candidate.declaration), inferenceContext && inferenceContext.inferredTypeParameters); // If the original signature has a generic rest type, instantiation may produce a // signature with different arity and we need to perform another arity check. if (getNonArrayRestType(candidate) && !hasCorrectArity(node, args, checkCandidate, signatureHelpTrailingComma)) { @@ -30814,14 +30133,8 @@ namespace ts { } // No signature was applicable. We have already reported the errors for the invalid signature. - function getCandidateForOverloadFailure( - node: CallLikeExpression, - candidates: Signature[], - args: readonly Expression[], - hasCandidatesOutArray: boolean, - checkMode: CheckMode, - ): Signature { - Debug.assert(candidates.length > 0); // Else should not have called this. + function getCandidateForOverloadFailure(node: ts.CallLikeExpression, candidates: ts.Signature[], args: readonly ts.Expression[], hasCandidatesOutArray: boolean, checkMode: CheckMode): ts.Signature { + ts.Debug.assert(candidates.length > 0); // Else should not have called this. checkNodeDeferred(node); // Normally we will combine overloads. Skip this if they have type parameters since that's hard to combine. // Don't do this if there is a `candidatesOutArray`, @@ -30831,57 +30144,53 @@ namespace ts { : createUnionOfSignaturesForOverloadFailure(candidates); } - function createUnionOfSignaturesForOverloadFailure(candidates: readonly Signature[]): Signature { - const thisParameters = mapDefined(candidates, c => c.thisParameter); - let thisParameter: Symbol | undefined; + function createUnionOfSignaturesForOverloadFailure(candidates: readonly ts.Signature[]): ts.Signature { + const thisParameters = ts.mapDefined(candidates, c => c.thisParameter); + let thisParameter: ts.Symbol | undefined; if (thisParameters.length) { thisParameter = createCombinedSymbolFromTypes(thisParameters, thisParameters.map(getTypeOfParameter)); } - const { min: minArgumentCount, max: maxNonRestParam } = minAndMax(candidates, getNumNonRestParameters); - const parameters: Symbol[] = []; + const { min: minArgumentCount, max: maxNonRestParam } = ts.minAndMax(candidates, getNumNonRestParameters); + const parameters: ts.Symbol[] = []; for (let i = 0; i < maxNonRestParam; i++) { - const symbols = mapDefined(candidates, s => signatureHasRestParameter(s) ? - i < s.parameters.length - 1 ? s.parameters[i] : last(s.parameters) : + const symbols = ts.mapDefined(candidates, s => signatureHasRestParameter(s) ? + i < s.parameters.length - 1 ? s.parameters[i] : ts.last(s.parameters) : i < s.parameters.length ? s.parameters[i] : undefined); - Debug.assert(symbols.length !== 0); - parameters.push(createCombinedSymbolFromTypes(symbols, mapDefined(candidates, candidate => tryGetTypeAtPosition(candidate, i)))); + ts.Debug.assert(symbols.length !== 0); + parameters.push(createCombinedSymbolFromTypes(symbols, ts.mapDefined(candidates, candidate => tryGetTypeAtPosition(candidate, i)))); } - const restParameterSymbols = mapDefined(candidates, c => signatureHasRestParameter(c) ? last(c.parameters) : undefined); - let flags = SignatureFlags.None; + const restParameterSymbols = ts.mapDefined(candidates, c => signatureHasRestParameter(c) ? ts.last(c.parameters) : undefined); + let flags = ts.SignatureFlags.None; if (restParameterSymbols.length !== 0) { - const type = createArrayType(getUnionType(mapDefined(candidates, tryGetRestTypeOfSignature), UnionReduction.Subtype)); + const type = createArrayType(getUnionType(ts.mapDefined(candidates, tryGetRestTypeOfSignature), ts.UnionReduction.Subtype)); parameters.push(createCombinedSymbolForOverloadFailure(restParameterSymbols, type)); - flags |= SignatureFlags.HasRestParameter; + flags |= ts.SignatureFlags.HasRestParameter; } if (candidates.some(signatureHasLiteralTypes)) { - flags |= SignatureFlags.HasLiteralTypes; + flags |= ts.SignatureFlags.HasLiteralTypes; } - return createSignature( - candidates[0].declaration, + return createSignature(candidates[0].declaration, /*typeParameters*/ undefined, // Before calling this we tested for `!candidates.some(c => !!c.typeParameters)`. - thisParameter, - parameters, + thisParameter, parameters, /*resolvedReturnType*/ getIntersectionType(candidates.map(getReturnTypeOfSignature)), - /*typePredicate*/ undefined, - minArgumentCount, - flags); + /*typePredicate*/ undefined, minArgumentCount, flags); } - function getNumNonRestParameters(signature: Signature): number { + function getNumNonRestParameters(signature: ts.Signature): number { const numParams = signature.parameters.length; return signatureHasRestParameter(signature) ? numParams - 1 : numParams; } - function createCombinedSymbolFromTypes(sources: readonly Symbol[], types: Type[]): Symbol { - return createCombinedSymbolForOverloadFailure(sources, getUnionType(types, UnionReduction.Subtype)); + function createCombinedSymbolFromTypes(sources: readonly ts.Symbol[], types: ts.Type[]): ts.Symbol { + return createCombinedSymbolForOverloadFailure(sources, getUnionType(types, ts.UnionReduction.Subtype)); } - function createCombinedSymbolForOverloadFailure(sources: readonly Symbol[], type: Type): Symbol { + function createCombinedSymbolForOverloadFailure(sources: readonly ts.Symbol[], type: ts.Type): ts.Symbol { // This function is currently only used for erroneous overloads, so it's good enough to just use the first source. - return createSymbolWithType(first(sources), type); + return createSymbolWithType(ts.first(sources), type); } - function pickLongestCandidateSignature(node: CallLikeExpression, candidates: Signature[], args: readonly Expression[], checkMode: CheckMode): Signature { + function pickLongestCandidateSignature(node: ts.CallLikeExpression, candidates: ts.Signature[], args: readonly ts.Expression[], checkMode: CheckMode): ts.Signature { // Pick the longest signature. This way we can get a contextual type for cases like: // declare function f(a: { xa: number; xb: number; }, b: number); // f({ | @@ -30895,15 +30204,15 @@ namespace ts { return candidate; } - const typeArgumentNodes: readonly TypeNode[] | undefined = callLikeExpressionMayHaveTypeArguments(node) ? node.typeArguments : undefined; + const typeArgumentNodes: readonly ts.TypeNode[] | undefined = callLikeExpressionMayHaveTypeArguments(node) ? node.typeArguments : undefined; const instantiated = typeArgumentNodes - ? createSignatureInstantiation(candidate, getTypeArgumentsFromNodes(typeArgumentNodes, typeParameters, isInJSFile(node))) + ? createSignatureInstantiation(candidate, getTypeArgumentsFromNodes(typeArgumentNodes, typeParameters, ts.isInJSFile(node))) : inferSignatureInstantiationForOverloadFailure(node, typeParameters, candidate, args, checkMode); candidates[bestIndex] = instantiated; return instantiated; } - function getTypeArgumentsFromNodes(typeArgumentNodes: readonly TypeNode[], typeParameters: readonly TypeParameter[], isJs: boolean): readonly Type[] { + function getTypeArgumentsFromNodes(typeArgumentNodes: readonly ts.TypeNode[], typeParameters: readonly ts.TypeParameter[], isJs: boolean): readonly ts.Type[] { const typeArguments = typeArgumentNodes.map(getTypeOfNode); while (typeArguments.length > typeParameters.length) { typeArguments.pop(); @@ -30914,13 +30223,13 @@ namespace ts { return typeArguments; } - function inferSignatureInstantiationForOverloadFailure(node: CallLikeExpression, typeParameters: readonly TypeParameter[], candidate: Signature, args: readonly Expression[], checkMode: CheckMode): Signature { - const inferenceContext = createInferenceContext(typeParameters, candidate, /*flags*/ isInJSFile(node) ? InferenceFlags.AnyDefault : InferenceFlags.None); + function inferSignatureInstantiationForOverloadFailure(node: ts.CallLikeExpression, typeParameters: readonly ts.TypeParameter[], candidate: ts.Signature, args: readonly ts.Expression[], checkMode: CheckMode): ts.Signature { + const inferenceContext = createInferenceContext(typeParameters, candidate, /*flags*/ ts.isInJSFile(node) ? ts.InferenceFlags.AnyDefault : ts.InferenceFlags.None); const typeArgumentTypes = inferTypeArguments(node, candidate, args, checkMode | CheckMode.SkipContextSensitive | CheckMode.SkipGenericFunctions, inferenceContext); return createSignatureInstantiation(candidate, typeArgumentTypes); } - function getLongestCandidateIndex(candidates: Signature[], argsCount: number): number { + function getLongestCandidateIndex(candidates: ts.Signature[], argsCount: number): number { let maxParamsIndex = -1; let maxParams = -1; @@ -30939,8 +30248,8 @@ namespace ts { return maxParamsIndex; } - function resolveCallExpression(node: CallExpression, candidatesOutArray: Signature[] | undefined, checkMode: CheckMode): Signature { - if (node.expression.kind === SyntaxKind.SuperKeyword) { + function resolveCallExpression(node: ts.CallExpression, candidatesOutArray: ts.Signature[] | undefined, checkMode: CheckMode): ts.Signature { + if (node.expression.kind === ts.SyntaxKind.SuperKeyword) { const superType = checkSuperExpression(node.expression); if (isTypeAny(superType)) { for (const arg of node.arguments) { @@ -30951,33 +30260,29 @@ namespace ts { if (!isErrorType(superType)) { // In super call, the candidate signatures are the matching arity signatures of the base constructor function instantiated // with the type arguments specified in the extends clause. - const baseTypeNode = getEffectiveBaseTypeNode(getContainingClass(node)!); + const baseTypeNode = ts.getEffectiveBaseTypeNode(ts.getContainingClass(node)!); if (baseTypeNode) { const baseConstructors = getInstantiatedConstructorsForTypeArguments(superType, baseTypeNode.typeArguments, baseTypeNode); - return resolveCall(node, baseConstructors, candidatesOutArray, checkMode, SignatureFlags.None); + return resolveCall(node, baseConstructors, candidatesOutArray, checkMode, ts.SignatureFlags.None); } } return resolveUntypedCall(node); } - let callChainFlags: SignatureFlags; + let callChainFlags: ts.SignatureFlags; let funcType = checkExpression(node.expression); - if (isCallChain(node)) { + if (ts.isCallChain(node)) { const nonOptionalType = getOptionalExpressionType(funcType, node.expression); - callChainFlags = nonOptionalType === funcType ? SignatureFlags.None : - isOutermostOptionalChain(node) ? SignatureFlags.IsOuterCallChain : - SignatureFlags.IsInnerCallChain; + callChainFlags = nonOptionalType === funcType ? ts.SignatureFlags.None : + ts.isOutermostOptionalChain(node) ? ts.SignatureFlags.IsOuterCallChain : + ts.SignatureFlags.IsInnerCallChain; funcType = nonOptionalType; } else { - callChainFlags = SignatureFlags.None; + callChainFlags = ts.SignatureFlags.None; } - funcType = checkNonNullTypeWithReporter( - funcType, - node.expression, - reportCannotInvokePossiblyNullOrUndefinedError - ); + funcType = checkNonNullTypeWithReporter(funcType, node.expression, reportCannotInvokePossiblyNullOrUndefinedError); if (funcType === silentNeverType) { return silentNeverSignature; @@ -30993,8 +30298,8 @@ namespace ts { // but we are not including call signatures that may have been added to the Object or // Function interface, since they have none by default. This is a bit of a leap of faith // that the user will not add any. - const callSignatures = getSignaturesOfType(apparentType, SignatureKind.Call); - const numConstructSignatures = getSignaturesOfType(apparentType, SignatureKind.Construct).length; + const callSignatures = getSignaturesOfType(apparentType, ts.SignatureKind.Call); + const numConstructSignatures = getSignaturesOfType(apparentType, ts.SignatureKind.Construct).length; // TS 1.0 Spec: 4.12 // In an untyped function call no TypeArgs are permitted, Args can be any argument list, no contextual @@ -31003,7 +30308,7 @@ namespace ts { // The unknownType indicates that an error already occurred (and was reported). No // need to report another error in this case. if (!isErrorType(funcType) && node.typeArguments) { - error(node, Diagnostics.Untyped_function_calls_may_not_accept_type_arguments); + error(node, ts.Diagnostics.Untyped_function_calls_may_not_accept_type_arguments); } return resolveUntypedCall(node); } @@ -31012,17 +30317,17 @@ namespace ts { // with multiple call signatures. if (!callSignatures.length) { if (numConstructSignatures) { - error(node, Diagnostics.Value_of_type_0_is_not_callable_Did_you_mean_to_include_new, typeToString(funcType)); + error(node, ts.Diagnostics.Value_of_type_0_is_not_callable_Did_you_mean_to_include_new, typeToString(funcType)); } else { - let relatedInformation: DiagnosticRelatedInformation | undefined; + let relatedInformation: ts.DiagnosticRelatedInformation | undefined; if (node.arguments.length === 1) { - const text = getSourceFileOfNode(node).text; - if (isLineBreak(text.charCodeAt(skipTrivia(text, node.expression.end, /* stopAfterLineBreak */ true) - 1))) { - relatedInformation = createDiagnosticForNode(node.expression, Diagnostics.Are_you_missing_a_semicolon); + const text = ts.getSourceFileOfNode(node).text; + if (ts.isLineBreak(text.charCodeAt(ts.skipTrivia(text, node.expression.end, /* stopAfterLineBreak */ true) - 1))) { + relatedInformation = ts.createDiagnosticForNode(node.expression, ts.Diagnostics.Are_you_missing_a_semicolon); } } - invocationError(node.expression, apparentType, SignatureKind.Call, relatedInformation); + invocationError(node.expression, apparentType, ts.SignatureKind.Call, relatedInformation); } return resolveErrorCall(node); } @@ -31043,15 +30348,15 @@ namespace ts { return resolvingSignature; } // If the function is explicitly marked with `@class`, then it must be constructed. - if (callSignatures.some(sig => isInJSFile(sig.declaration) && !!getJSDocClassTag(sig.declaration!))) { - error(node, Diagnostics.Value_of_type_0_is_not_callable_Did_you_mean_to_include_new, typeToString(funcType)); + if (callSignatures.some(sig => ts.isInJSFile(sig.declaration) && !!ts.getJSDocClassTag(sig.declaration!))) { + error(node, ts.Diagnostics.Value_of_type_0_is_not_callable_Did_you_mean_to_include_new, typeToString(funcType)); return resolveErrorCall(node); } return resolveCall(node, callSignatures, candidatesOutArray, checkMode, callChainFlags); } - function isGenericFunctionReturningFunction(signature: Signature) { + function isGenericFunctionReturningFunction(signature: ts.Signature) { return !!(signature.typeParameters && isFunctionType(getReturnTypeOfSignature(signature))); } @@ -31060,17 +30365,17 @@ namespace ts { * If FuncExpr is of type Any, or of an object type that has no call or construct signatures * but is a subtype of the Function interface, the call is an untyped function call. */ - function isUntypedFunctionCall(funcType: Type, apparentFuncType: Type, numCallSignatures: number, numConstructSignatures: number): boolean { + function isUntypedFunctionCall(funcType: ts.Type, apparentFuncType: ts.Type, numCallSignatures: number, numConstructSignatures: number): boolean { // We exclude union types because we may have a union of function types that happen to have no common signatures. - return isTypeAny(funcType) || isTypeAny(apparentFuncType) && !!(funcType.flags & TypeFlags.TypeParameter) || - !numCallSignatures && !numConstructSignatures && !(apparentFuncType.flags & TypeFlags.Union) && !(getReducedType(apparentFuncType).flags & TypeFlags.Never) && isTypeAssignableTo(funcType, globalFunctionType); + return isTypeAny(funcType) || isTypeAny(apparentFuncType) && !!(funcType.flags & ts.TypeFlags.TypeParameter) || + !numCallSignatures && !numConstructSignatures && !(apparentFuncType.flags & ts.TypeFlags.Union) && !(getReducedType(apparentFuncType).flags & ts.TypeFlags.Never) && isTypeAssignableTo(funcType, globalFunctionType); } - function resolveNewExpression(node: NewExpression, candidatesOutArray: Signature[] | undefined, checkMode: CheckMode): Signature { - if (node.arguments && languageVersion < ScriptTarget.ES5) { + function resolveNewExpression(node: ts.NewExpression, candidatesOutArray: ts.Signature[] | undefined, checkMode: CheckMode): ts.Signature { + if (node.arguments && languageVersion < ts.ScriptTarget.ES5) { const spreadIndex = getSpreadArgumentIndex(node.arguments); if (spreadIndex >= 0) { - error(node.arguments[spreadIndex], Diagnostics.Spread_operator_in_new_expressions_is_only_available_when_targeting_ECMAScript_5_and_higher); + error(node.arguments[spreadIndex], ts.Diagnostics.Spread_operator_in_new_expressions_is_only_available_when_targeting_ECMAScript_5_and_higher); } } @@ -31095,7 +30400,7 @@ namespace ts { // list and the result of the operation is of type Any. if (isTypeAny(expressionType)) { if (node.typeArguments) { - error(node, Diagnostics.Untyped_function_calls_may_not_accept_type_arguments); + error(node, ts.Diagnostics.Untyped_function_calls_may_not_accept_type_arguments); } return resolveUntypedCall(node); } @@ -31104,7 +30409,7 @@ namespace ts { // but we are not including construct signatures that may have been added to the Object or // Function interface, since they have none by default. This is a bit of a leap of faith // that the user will not add any. - const constructSignatures = getSignaturesOfType(expressionType, SignatureKind.Construct); + const constructSignatures = getSignaturesOfType(expressionType, ts.SignatureKind.Construct); if (constructSignatures.length) { if (!isConstructorAccessible(node, constructSignatures[0])) { return resolveErrorCall(node); @@ -31113,66 +30418,66 @@ namespace ts { // then it cannot be instantiated. // In the case of a merged class-module or class-interface declaration, // only the class declaration node will have the Abstract flag set. - if (someSignature(constructSignatures, signature => !!(signature.flags & SignatureFlags.Abstract))) { - error(node, Diagnostics.Cannot_create_an_instance_of_an_abstract_class); + if (someSignature(constructSignatures, signature => !!(signature.flags & ts.SignatureFlags.Abstract))) { + error(node, ts.Diagnostics.Cannot_create_an_instance_of_an_abstract_class); return resolveErrorCall(node); } - const valueDecl = expressionType.symbol && getClassLikeDeclarationOfSymbol(expressionType.symbol); - if (valueDecl && hasSyntacticModifier(valueDecl, ModifierFlags.Abstract)) { - error(node, Diagnostics.Cannot_create_an_instance_of_an_abstract_class); + const valueDecl = expressionType.symbol && ts.getClassLikeDeclarationOfSymbol(expressionType.symbol); + if (valueDecl && ts.hasSyntacticModifier(valueDecl, ts.ModifierFlags.Abstract)) { + error(node, ts.Diagnostics.Cannot_create_an_instance_of_an_abstract_class); return resolveErrorCall(node); } - return resolveCall(node, constructSignatures, candidatesOutArray, checkMode, SignatureFlags.None); + return resolveCall(node, constructSignatures, candidatesOutArray, checkMode, ts.SignatureFlags.None); } // If expressionType's apparent type is an object type with no construct signatures but // one or more call signatures, the expression is processed as a function call. A compile-time // error occurs if the result of the function call is not Void. The type of the result of the // operation is Any. It is an error to have a Void this type. - const callSignatures = getSignaturesOfType(expressionType, SignatureKind.Call); + const callSignatures = getSignaturesOfType(expressionType, ts.SignatureKind.Call); if (callSignatures.length) { - const signature = resolveCall(node, callSignatures, candidatesOutArray, checkMode, SignatureFlags.None); + const signature = resolveCall(node, callSignatures, candidatesOutArray, checkMode, ts.SignatureFlags.None); if (!noImplicitAny) { if (signature.declaration && !isJSConstructor(signature.declaration) && getReturnTypeOfSignature(signature) !== voidType) { - error(node, Diagnostics.Only_a_void_function_can_be_called_with_the_new_keyword); + error(node, ts.Diagnostics.Only_a_void_function_can_be_called_with_the_new_keyword); } if (getThisTypeOfSignature(signature) === voidType) { - error(node, Diagnostics.A_function_that_is_called_with_the_new_keyword_cannot_have_a_this_type_that_is_void); + error(node, ts.Diagnostics.A_function_that_is_called_with_the_new_keyword_cannot_have_a_this_type_that_is_void); } } return signature; } - invocationError(node.expression, expressionType, SignatureKind.Construct); + invocationError(node.expression, expressionType, ts.SignatureKind.Construct); return resolveErrorCall(node); } - function someSignature(signatures: Signature | readonly Signature[], f: (s: Signature) => boolean): boolean { - if (isArray(signatures)) { - return some(signatures, signature => someSignature(signature, f)); + function someSignature(signatures: ts.Signature | readonly ts.Signature[], f: (s: ts.Signature) => boolean): boolean { + if (ts.isArray(signatures)) { + return ts.some(signatures, signature => someSignature(signature, f)); } - return signatures.compositeKind === TypeFlags.Union ? some(signatures.compositeSignatures, f) : f(signatures); + return signatures.compositeKind === ts.TypeFlags.Union ? ts.some(signatures.compositeSignatures, f) : f(signatures); } - function typeHasProtectedAccessibleBase(target: Symbol, type: InterfaceType): boolean { + function typeHasProtectedAccessibleBase(target: ts.Symbol, type: ts.InterfaceType): boolean { const baseTypes = getBaseTypes(type); - if (!length(baseTypes)) { + if (!ts.length(baseTypes)) { return false; } const firstBase = baseTypes[0]; - if (firstBase.flags & TypeFlags.Intersection) { - const types = (firstBase as IntersectionType).types; + if (firstBase.flags & ts.TypeFlags.Intersection) { + const types = (firstBase as ts.IntersectionType).types; const mixinFlags = findMixins(types); let i = 0; - for (const intersectionMember of (firstBase as IntersectionType).types) { + for (const intersectionMember of (firstBase as ts.IntersectionType).types) { // We want to ignore mixin ctors if (!mixinFlags[i]) { - if (getObjectFlags(intersectionMember) & (ObjectFlags.Class | ObjectFlags.Interface)) { + if (ts.getObjectFlags(intersectionMember) & (ts.ObjectFlags.Class | ts.ObjectFlags.Interface)) { if (intersectionMember.symbol === target) { return true; } - if (typeHasProtectedAccessibleBase(target, intersectionMember as InterfaceType)) { + if (typeHasProtectedAccessibleBase(target, intersectionMember as ts.InterfaceType)) { return true; } } @@ -31184,39 +30489,39 @@ namespace ts { if (firstBase.symbol === target) { return true; } - return typeHasProtectedAccessibleBase(target, firstBase as InterfaceType); + return typeHasProtectedAccessibleBase(target, firstBase as ts.InterfaceType); } - function isConstructorAccessible(node: NewExpression, signature: Signature) { + function isConstructorAccessible(node: ts.NewExpression, signature: ts.Signature) { if (!signature || !signature.declaration) { return true; } const declaration = signature.declaration; - const modifiers = getSelectedEffectiveModifierFlags(declaration, ModifierFlags.NonPublicAccessibilityModifier); + const modifiers = ts.getSelectedEffectiveModifierFlags(declaration, ts.ModifierFlags.NonPublicAccessibilityModifier); // (1) Public constructors and (2) constructor functions are always accessible. - if (!modifiers || declaration.kind !== SyntaxKind.Constructor) { + if (!modifiers || declaration.kind !== ts.SyntaxKind.Constructor) { return true; } - const declaringClassDeclaration = getClassLikeDeclarationOfSymbol(declaration.parent.symbol)!; - const declaringClass = getDeclaredTypeOfSymbol(declaration.parent.symbol) as InterfaceType; + const declaringClassDeclaration = ts.getClassLikeDeclarationOfSymbol(declaration.parent.symbol)!; + const declaringClass = getDeclaredTypeOfSymbol(declaration.parent.symbol) as ts.InterfaceType; // A private or protected constructor can only be instantiated within its own class (or a subclass, for protected) if (!isNodeWithinClass(node, declaringClassDeclaration)) { - const containingClass = getContainingClass(node); - if (containingClass && modifiers & ModifierFlags.Protected) { + const containingClass = ts.getContainingClass(node); + if (containingClass && modifiers & ts.ModifierFlags.Protected) { const containingType = getTypeOfNode(containingClass); - if (typeHasProtectedAccessibleBase(declaration.parent.symbol, containingType as InterfaceType)) { + if (typeHasProtectedAccessibleBase(declaration.parent.symbol, containingType as ts.InterfaceType)) { return true; } } - if (modifiers & ModifierFlags.Private) { - error(node, Diagnostics.Constructor_of_class_0_is_private_and_only_accessible_within_the_class_declaration, typeToString(declaringClass)); + if (modifiers & ts.ModifierFlags.Private) { + error(node, ts.Diagnostics.Constructor_of_class_0_is_private_and_only_accessible_within_the_class_declaration, typeToString(declaringClass)); } - if (modifiers & ModifierFlags.Protected) { - error(node, Diagnostics.Constructor_of_class_0_is_protected_and_only_accessible_within_the_class_declaration, typeToString(declaringClass)); + if (modifiers & ts.ModifierFlags.Protected) { + error(node, ts.Diagnostics.Constructor_of_class_0_is_protected_and_only_accessible_within_the_class_declaration, typeToString(declaringClass)); } return false; } @@ -31224,13 +30529,16 @@ namespace ts { return true; } - function invocationErrorDetails(errorTarget: Node, apparentType: Type, kind: SignatureKind): { messageChain: DiagnosticMessageChain, relatedMessage: DiagnosticMessage | undefined } { - let errorInfo: DiagnosticMessageChain | undefined; - const isCall = kind === SignatureKind.Call; + function invocationErrorDetails(errorTarget: ts.Node, apparentType: ts.Type, kind: ts.SignatureKind): { + messageChain: ts.DiagnosticMessageChain; + relatedMessage: ts.DiagnosticMessage | undefined; + } { + let errorInfo: ts.DiagnosticMessageChain | undefined; + const isCall = kind === ts.SignatureKind.Call; const awaitedType = getAwaitedType(apparentType); const maybeMissingAwait = awaitedType && getSignaturesOfType(awaitedType, kind).length > 0; - if (apparentType.flags & TypeFlags.Union) { - const types = (apparentType as UnionType).types; + if (apparentType.flags & ts.TypeFlags.Union) { + const types = (apparentType as ts.UnionType).types; let hasSignatures = false; for (const constituent of types) { const signatures = getSignaturesOfType(constituent, kind); @@ -31244,20 +30552,12 @@ namespace ts { else { // Error on the first non callable constituent only if (!errorInfo) { - errorInfo = chainDiagnosticMessages( - errorInfo, - isCall ? - Diagnostics.Type_0_has_no_call_signatures : - Diagnostics.Type_0_has_no_construct_signatures, - typeToString(constituent) - ); - errorInfo = chainDiagnosticMessages( - errorInfo, - isCall ? - Diagnostics.Not_all_constituents_of_type_0_are_callable : - Diagnostics.Not_all_constituents_of_type_0_are_constructable, - typeToString(apparentType) - ); + errorInfo = ts.chainDiagnosticMessages(errorInfo, isCall ? + ts.Diagnostics.Type_0_has_no_call_signatures : + ts.Diagnostics.Type_0_has_no_construct_signatures, typeToString(constituent)); + errorInfo = ts.chainDiagnosticMessages(errorInfo, isCall ? + ts.Diagnostics.Not_all_constituents_of_type_0_are_callable : + ts.Diagnostics.Not_all_constituents_of_type_0_are_constructable, typeToString(apparentType)); } if (hasSignatures) { // Bail early if we already found a siganture, no chance of "No constituent of type is callable" @@ -31266,82 +30566,69 @@ namespace ts { } } if (!hasSignatures) { - errorInfo = chainDiagnosticMessages( - /* detials */ undefined, - isCall ? - Diagnostics.No_constituent_of_type_0_is_callable : - Diagnostics.No_constituent_of_type_0_is_constructable, - typeToString(apparentType) - ); + errorInfo = ts.chainDiagnosticMessages( + /* detials */ undefined, isCall ? + ts.Diagnostics.No_constituent_of_type_0_is_callable : + ts.Diagnostics.No_constituent_of_type_0_is_constructable, typeToString(apparentType)); } if (!errorInfo) { - errorInfo = chainDiagnosticMessages( - errorInfo, - isCall ? - Diagnostics.Each_member_of_the_union_type_0_has_signatures_but_none_of_those_signatures_are_compatible_with_each_other : - Diagnostics.Each_member_of_the_union_type_0_has_construct_signatures_but_none_of_those_signatures_are_compatible_with_each_other, - typeToString(apparentType) - ); + errorInfo = ts.chainDiagnosticMessages(errorInfo, isCall ? + ts.Diagnostics.Each_member_of_the_union_type_0_has_signatures_but_none_of_those_signatures_are_compatible_with_each_other : + ts.Diagnostics.Each_member_of_the_union_type_0_has_construct_signatures_but_none_of_those_signatures_are_compatible_with_each_other, typeToString(apparentType)); } } else { - errorInfo = chainDiagnosticMessages( - errorInfo, - isCall ? - Diagnostics.Type_0_has_no_call_signatures : - Diagnostics.Type_0_has_no_construct_signatures, - typeToString(apparentType) - ); + errorInfo = ts.chainDiagnosticMessages(errorInfo, isCall ? + ts.Diagnostics.Type_0_has_no_call_signatures : + ts.Diagnostics.Type_0_has_no_construct_signatures, typeToString(apparentType)); } - let headMessage = isCall ? Diagnostics.This_expression_is_not_callable : Diagnostics.This_expression_is_not_constructable; + let headMessage = isCall ? ts.Diagnostics.This_expression_is_not_callable : ts.Diagnostics.This_expression_is_not_constructable; // Diagnose get accessors incorrectly called as functions - if (isCallExpression(errorTarget.parent) && errorTarget.parent.arguments.length === 0) { + if (ts.isCallExpression(errorTarget.parent) && errorTarget.parent.arguments.length === 0) { const { resolvedSymbol } = getNodeLinks(errorTarget); - if (resolvedSymbol && resolvedSymbol.flags & SymbolFlags.GetAccessor) { - headMessage = Diagnostics.This_expression_is_not_callable_because_it_is_a_get_accessor_Did_you_mean_to_use_it_without; + if (resolvedSymbol && resolvedSymbol.flags & ts.SymbolFlags.GetAccessor) { + headMessage = ts.Diagnostics.This_expression_is_not_callable_because_it_is_a_get_accessor_Did_you_mean_to_use_it_without; } } return { - messageChain: chainDiagnosticMessages(errorInfo, headMessage), - relatedMessage: maybeMissingAwait ? Diagnostics.Did_you_forget_to_use_await : undefined, + messageChain: ts.chainDiagnosticMessages(errorInfo, headMessage), + relatedMessage: maybeMissingAwait ? ts.Diagnostics.Did_you_forget_to_use_await : undefined, }; } - function invocationError(errorTarget: Node, apparentType: Type, kind: SignatureKind, relatedInformation?: DiagnosticRelatedInformation) { + function invocationError(errorTarget: ts.Node, apparentType: ts.Type, kind: ts.SignatureKind, relatedInformation?: ts.DiagnosticRelatedInformation) { const { messageChain, relatedMessage: relatedInfo } = invocationErrorDetails(errorTarget, apparentType, kind); - const diagnostic = createDiagnosticForNodeFromMessageChain(errorTarget, messageChain); + const diagnostic = ts.createDiagnosticForNodeFromMessageChain(errorTarget, messageChain); if (relatedInfo) { - addRelatedInfo(diagnostic, createDiagnosticForNode(errorTarget, relatedInfo)); + ts.addRelatedInfo(diagnostic, ts.createDiagnosticForNode(errorTarget, relatedInfo)); } - if (isCallExpression(errorTarget.parent)) { + if (ts.isCallExpression(errorTarget.parent)) { const { start, length } = getDiagnosticSpanForCallNode(errorTarget.parent, /* doNotIncludeArguments */ true); diagnostic.start = start; diagnostic.length = length; } diagnostics.add(diagnostic); - invocationErrorRecovery(apparentType, kind, relatedInformation ? addRelatedInfo(diagnostic, relatedInformation) : diagnostic); + invocationErrorRecovery(apparentType, kind, relatedInformation ? ts.addRelatedInfo(diagnostic, relatedInformation) : diagnostic); } - function invocationErrorRecovery(apparentType: Type, kind: SignatureKind, diagnostic: Diagnostic) { + function invocationErrorRecovery(apparentType: ts.Type, kind: ts.SignatureKind, diagnostic: ts.Diagnostic) { if (!apparentType.symbol) { return; } const importNode = getSymbolLinks(apparentType.symbol).originatingImport; // Create a diagnostic on the originating import if possible onto which we can attach a quickfix // An import call expression cannot be rewritten into another form to correct the error - the only solution is to use `.default` at the use-site - if (importNode && !isImportCall(importNode)) { + if (importNode && !ts.isImportCall(importNode)) { const sigs = getSignaturesOfType(getTypeOfSymbol(getSymbolLinks(apparentType.symbol).target!), kind); - if (!sigs || !sigs.length) return; - - addRelatedInfo(diagnostic, - createDiagnosticForNode(importNode, Diagnostics.Type_originates_at_this_import_A_namespace_style_import_cannot_be_called_or_constructed_and_will_cause_a_failure_at_runtime_Consider_using_a_default_import_or_import_require_here_instead) - ); + if (!sigs || !sigs.length) + return; + ts.addRelatedInfo(diagnostic, ts.createDiagnosticForNode(importNode, ts.Diagnostics.Type_originates_at_this_import_A_namespace_style_import_cannot_be_called_or_constructed_and_will_cause_a_failure_at_runtime_Consider_using_a_default_import_or_import_require_here_instead)); } } - function resolveTaggedTemplateExpression(node: TaggedTemplateExpression, candidatesOutArray: Signature[] | undefined, checkMode: CheckMode): Signature { + function resolveTaggedTemplateExpression(node: ts.TaggedTemplateExpression, candidatesOutArray: ts.Signature[] | undefined, checkMode: CheckMode): ts.Signature { const tagType = checkExpression(node.tag); const apparentType = getApparentType(tagType); @@ -31350,123 +30637,111 @@ namespace ts { return resolveErrorCall(node); } - const callSignatures = getSignaturesOfType(apparentType, SignatureKind.Call); - const numConstructSignatures = getSignaturesOfType(apparentType, SignatureKind.Construct).length; + const callSignatures = getSignaturesOfType(apparentType, ts.SignatureKind.Call); + const numConstructSignatures = getSignaturesOfType(apparentType, ts.SignatureKind.Construct).length; if (isUntypedFunctionCall(tagType, apparentType, callSignatures.length, numConstructSignatures)) { return resolveUntypedCall(node); } if (!callSignatures.length) { - if (isArrayLiteralExpression(node.parent)) { - const diagnostic = createDiagnosticForNode(node.tag, Diagnostics.It_is_likely_that_you_are_missing_a_comma_to_separate_these_two_template_expressions_They_form_a_tagged_template_expression_which_cannot_be_invoked); + if (ts.isArrayLiteralExpression(node.parent)) { + const diagnostic = ts.createDiagnosticForNode(node.tag, ts.Diagnostics.It_is_likely_that_you_are_missing_a_comma_to_separate_these_two_template_expressions_They_form_a_tagged_template_expression_which_cannot_be_invoked); diagnostics.add(diagnostic); return resolveErrorCall(node); } - invocationError(node.tag, apparentType, SignatureKind.Call); + invocationError(node.tag, apparentType, ts.SignatureKind.Call); return resolveErrorCall(node); } - return resolveCall(node, callSignatures, candidatesOutArray, checkMode, SignatureFlags.None); + return resolveCall(node, callSignatures, candidatesOutArray, checkMode, ts.SignatureFlags.None); } /** * Gets the localized diagnostic head message to use for errors when resolving a decorator as a call expression. */ - function getDiagnosticHeadMessageForDecoratorResolution(node: Decorator) { + function getDiagnosticHeadMessageForDecoratorResolution(node: ts.Decorator) { switch (node.parent.kind) { - case SyntaxKind.ClassDeclaration: - case SyntaxKind.ClassExpression: - return Diagnostics.Unable_to_resolve_signature_of_class_decorator_when_called_as_an_expression; - - case SyntaxKind.Parameter: - return Diagnostics.Unable_to_resolve_signature_of_parameter_decorator_when_called_as_an_expression; - - case SyntaxKind.PropertyDeclaration: - return Diagnostics.Unable_to_resolve_signature_of_property_decorator_when_called_as_an_expression; - - case SyntaxKind.MethodDeclaration: - case SyntaxKind.GetAccessor: - case SyntaxKind.SetAccessor: - return Diagnostics.Unable_to_resolve_signature_of_method_decorator_when_called_as_an_expression; + case ts.SyntaxKind.ClassDeclaration: + case ts.SyntaxKind.ClassExpression: + return ts.Diagnostics.Unable_to_resolve_signature_of_class_decorator_when_called_as_an_expression; + case ts.SyntaxKind.Parameter: + return ts.Diagnostics.Unable_to_resolve_signature_of_parameter_decorator_when_called_as_an_expression; + case ts.SyntaxKind.PropertyDeclaration: + return ts.Diagnostics.Unable_to_resolve_signature_of_property_decorator_when_called_as_an_expression; + case ts.SyntaxKind.MethodDeclaration: + case ts.SyntaxKind.GetAccessor: + case ts.SyntaxKind.SetAccessor: + return ts.Diagnostics.Unable_to_resolve_signature_of_method_decorator_when_called_as_an_expression; default: - return Debug.fail(); + return ts.Debug.fail(); } } /** * Resolves a decorator as if it were a call expression. */ - function resolveDecorator(node: Decorator, candidatesOutArray: Signature[] | undefined, checkMode: CheckMode): Signature { + function resolveDecorator(node: ts.Decorator, candidatesOutArray: ts.Signature[] | undefined, checkMode: CheckMode): ts.Signature { const funcType = checkExpression(node.expression); const apparentType = getApparentType(funcType); if (isErrorType(apparentType)) { return resolveErrorCall(node); } - const callSignatures = getSignaturesOfType(apparentType, SignatureKind.Call); - const numConstructSignatures = getSignaturesOfType(apparentType, SignatureKind.Construct).length; + const callSignatures = getSignaturesOfType(apparentType, ts.SignatureKind.Call); + const numConstructSignatures = getSignaturesOfType(apparentType, ts.SignatureKind.Construct).length; if (isUntypedFunctionCall(funcType, apparentType, callSignatures.length, numConstructSignatures)) { return resolveUntypedCall(node); } if (isPotentiallyUncalledDecorator(node, callSignatures)) { - const nodeStr = getTextOfNode(node.expression, /*includeTrivia*/ false); - error(node, Diagnostics._0_accepts_too_few_arguments_to_be_used_as_a_decorator_here_Did_you_mean_to_call_it_first_and_write_0, nodeStr); + const nodeStr = ts.getTextOfNode(node.expression, /*includeTrivia*/ false); + error(node, ts.Diagnostics._0_accepts_too_few_arguments_to_be_used_as_a_decorator_here_Did_you_mean_to_call_it_first_and_write_0, nodeStr); return resolveErrorCall(node); } const headMessage = getDiagnosticHeadMessageForDecoratorResolution(node); if (!callSignatures.length) { - const errorDetails = invocationErrorDetails(node.expression, apparentType, SignatureKind.Call); - const messageChain = chainDiagnosticMessages(errorDetails.messageChain, headMessage); - const diag = createDiagnosticForNodeFromMessageChain(node.expression, messageChain); + const errorDetails = invocationErrorDetails(node.expression, apparentType, ts.SignatureKind.Call); + const messageChain = ts.chainDiagnosticMessages(errorDetails.messageChain, headMessage); + const diag = ts.createDiagnosticForNodeFromMessageChain(node.expression, messageChain); if (errorDetails.relatedMessage) { - addRelatedInfo(diag, createDiagnosticForNode(node.expression, errorDetails.relatedMessage)); + ts.addRelatedInfo(diag, ts.createDiagnosticForNode(node.expression, errorDetails.relatedMessage)); } diagnostics.add(diag); - invocationErrorRecovery(apparentType, SignatureKind.Call, diag); + invocationErrorRecovery(apparentType, ts.SignatureKind.Call, diag); return resolveErrorCall(node); } - return resolveCall(node, callSignatures, candidatesOutArray, checkMode, SignatureFlags.None, headMessage); + return resolveCall(node, callSignatures, candidatesOutArray, checkMode, ts.SignatureFlags.None, headMessage); } - function createSignatureForJSXIntrinsic(node: JsxOpeningLikeElement, result: Type): Signature { + function createSignatureForJSXIntrinsic(node: ts.JsxOpeningLikeElement, result: ts.Type): ts.Signature { const namespace = getJsxNamespaceAt(node); const exports = namespace && getExportsOfSymbol(namespace); // We fake up a SFC signature for each intrinsic, however a more specific per-element signature drawn from the JSX declaration // file would probably be preferable. - const typeSymbol = exports && getSymbol(exports, JsxNames.Element, SymbolFlags.Type); - const returnNode = typeSymbol && nodeBuilder.symbolToEntityName(typeSymbol, SymbolFlags.Type, node); - const declaration = factory.createFunctionTypeNode(/*typeParameters*/ undefined, - [factory.createParameterDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotdotdot*/ undefined, "props", /*questionMark*/ undefined, nodeBuilder.typeToTypeNode(result, node))], - returnNode ? factory.createTypeReferenceNode(returnNode, /*typeArguments*/ undefined) : factory.createKeywordTypeNode(SyntaxKind.AnyKeyword) - ); - const parameterSymbol = createSymbol(SymbolFlags.FunctionScopedVariable, "props" as __String); + const typeSymbol = exports && getSymbol(exports, JsxNames.Element, ts.SymbolFlags.Type); + const returnNode = typeSymbol && nodeBuilder.symbolToEntityName(typeSymbol, ts.SymbolFlags.Type, node); + const declaration = ts.factory.createFunctionTypeNode(/*typeParameters*/ undefined, [ts.factory.createParameterDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotdotdot*/ undefined, "props", /*questionMark*/ undefined, nodeBuilder.typeToTypeNode(result, node))], returnNode ? ts.factory.createTypeReferenceNode(returnNode, /*typeArguments*/ undefined) : ts.factory.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword)); + const parameterSymbol = createSymbol(ts.SymbolFlags.FunctionScopedVariable, "props" as ts.__String); parameterSymbol.type = result; - return createSignature( - declaration, + return createSignature(declaration, /*typeParameters*/ undefined, - /*thisParameter*/ undefined, - [parameterSymbol], - typeSymbol ? getDeclaredTypeOfSymbol(typeSymbol) : errorType, - /*returnTypePredicate*/ undefined, - 1, - SignatureFlags.None - ); + /*thisParameter*/ undefined, [parameterSymbol], typeSymbol ? getDeclaredTypeOfSymbol(typeSymbol) : errorType, + /*returnTypePredicate*/ undefined, 1, ts.SignatureFlags.None); } - function resolveJsxOpeningLikeElement(node: JsxOpeningLikeElement, candidatesOutArray: Signature[] | undefined, checkMode: CheckMode): Signature { + function resolveJsxOpeningLikeElement(node: ts.JsxOpeningLikeElement, candidatesOutArray: ts.Signature[] | undefined, checkMode: CheckMode): ts.Signature { if (isJsxIntrinsicIdentifier(node.tagName)) { const result = getIntrinsicAttributesTypeFromJsxOpeningLikeElement(node); const fakeSignature = createSignatureForJSXIntrinsic(node, result); checkTypeAssignableToAndOptionallyElaborate(checkExpressionWithContextualType(node.attributes, getEffectiveFirstArgumentForJsxSignature(fakeSignature, node), /*mapper*/ undefined, CheckMode.Normal), result, node.tagName, node.attributes); - if (length(node.typeArguments)) { - forEach(node.typeArguments, checkSourceElement); - diagnostics.add(createDiagnosticForNodeArray(getSourceFileOfNode(node), node.typeArguments!, Diagnostics.Expected_0_type_arguments_but_got_1, 0, length(node.typeArguments))); + if (ts.length(node.typeArguments)) { + ts.forEach(node.typeArguments, checkSourceElement); + diagnostics.add(ts.createDiagnosticForNodeArray(ts.getSourceFileOfNode(node), node.typeArguments!, ts.Diagnostics.Expected_0_type_arguments_but_got_1, 0, ts.length(node.typeArguments))); } return fakeSignature; } @@ -31483,11 +30758,11 @@ namespace ts { if (signatures.length === 0) { // We found no signatures at all, which is an error - error(node.tagName, Diagnostics.JSX_element_type_0_does_not_have_any_construct_or_call_signatures, getTextOfNode(node.tagName)); + error(node.tagName, ts.Diagnostics.JSX_element_type_0_does_not_have_any_construct_or_call_signatures, ts.getTextOfNode(node.tagName)); return resolveErrorCall(node); } - return resolveCall(node, signatures, candidatesOutArray, checkMode, SignatureFlags.None); + return resolveCall(node, signatures, candidatesOutArray, checkMode, ts.SignatureFlags.None); } /** @@ -31495,28 +30770,27 @@ namespace ts { * but is receiving too many arguments as part of the decorator invocation. * In those cases, a user may have meant to *call* the expression before using it as a decorator. */ - function isPotentiallyUncalledDecorator(decorator: Decorator, signatures: readonly Signature[]) { - return signatures.length && every(signatures, signature => - signature.minArgumentCount === 0 && + function isPotentiallyUncalledDecorator(decorator: ts.Decorator, signatures: readonly ts.Signature[]) { + return signatures.length && ts.every(signatures, signature => signature.minArgumentCount === 0 && !signatureHasRestParameter(signature) && signature.parameters.length < getDecoratorArgumentCount(decorator, signature)); } - function resolveSignature(node: CallLikeExpression, candidatesOutArray: Signature[] | undefined, checkMode: CheckMode): Signature { + function resolveSignature(node: ts.CallLikeExpression, candidatesOutArray: ts.Signature[] | undefined, checkMode: CheckMode): ts.Signature { switch (node.kind) { - case SyntaxKind.CallExpression: + case ts.SyntaxKind.CallExpression: return resolveCallExpression(node, candidatesOutArray, checkMode); - case SyntaxKind.NewExpression: + case ts.SyntaxKind.NewExpression: return resolveNewExpression(node, candidatesOutArray, checkMode); - case SyntaxKind.TaggedTemplateExpression: + case ts.SyntaxKind.TaggedTemplateExpression: return resolveTaggedTemplateExpression(node, candidatesOutArray, checkMode); - case SyntaxKind.Decorator: + case ts.SyntaxKind.Decorator: return resolveDecorator(node, candidatesOutArray, checkMode); - case SyntaxKind.JsxOpeningElement: - case SyntaxKind.JsxSelfClosingElement: + case ts.SyntaxKind.JsxOpeningElement: + case ts.SyntaxKind.JsxSelfClosingElement: return resolveJsxOpeningLikeElement(node, candidatesOutArray, checkMode); } - throw Debug.assertNever(node, "Branch in 'resolveSignature' should be unreachable."); + throw ts.Debug.assertNever(node, "Branch in 'resolveSignature' should be unreachable."); } /** @@ -31526,7 +30800,7 @@ namespace ts { * the function will fill it up with appropriate candidate signatures * @return a signature of the call-like expression or undefined if one can't be found */ - function getResolvedSignature(node: CallLikeExpression, candidatesOutArray?: Signature[] | undefined, checkMode?: CheckMode): Signature { + function getResolvedSignature(node: ts.CallLikeExpression, candidatesOutArray?: ts.Signature[] | undefined, checkMode?: CheckMode): ts.Signature { const links = getNodeLinks(node); // If getResolvedSignature has already been called, we will have cached the resolvedSignature. // However, it is possible that either candidatesOutArray was not passed in the first time, @@ -31553,16 +30827,17 @@ namespace ts { * Indicates whether a declaration can be treated as a constructor in a JavaScript * file. */ - function isJSConstructor(node: Node | undefined): node is FunctionDeclaration | FunctionExpression { - if (!node || !isInJSFile(node)) { + function isJSConstructor(node: ts.Node | undefined): node is ts.FunctionDeclaration | ts.FunctionExpression { + if (!node || !ts.isInJSFile(node)) { return false; } - const func = isFunctionDeclaration(node) || isFunctionExpression(node) ? node : - isVariableDeclaration(node) && node.initializer && isFunctionExpression(node.initializer) ? node.initializer : + const func = ts.isFunctionDeclaration(node) || ts.isFunctionExpression(node) ? node : + ts.isVariableDeclaration(node) && node.initializer && ts.isFunctionExpression(node.initializer) ? node.initializer : undefined; if (func) { // If the node has a @class tag, treat it like a constructor. - if (getJSDocClassTag(node)) return true; + if (ts.getJSDocClassTag(node)) + return true; // If the symbol of the node has members, treat it like a constructor. const symbol = getSymbolOfNode(func); @@ -31571,92 +30846,92 @@ namespace ts { return false; } - function mergeJSSymbols(target: Symbol, source: Symbol | undefined) { + function mergeJSSymbols(target: ts.Symbol, source: ts.Symbol | undefined) { if (source) { const links = getSymbolLinks(source); if (!links.inferredClassSymbol || !links.inferredClassSymbol.has(getSymbolId(target))) { - const inferred = isTransientSymbol(target) ? target : cloneSymbol(target) as TransientSymbol; - inferred.exports = inferred.exports || createSymbolTable(); - inferred.members = inferred.members || createSymbolTable(); - inferred.flags |= source.flags & SymbolFlags.Class; + const inferred = ts.isTransientSymbol(target) ? target : cloneSymbol(target) as ts.TransientSymbol; + inferred.exports = inferred.exports || ts.createSymbolTable(); + inferred.members = inferred.members || ts.createSymbolTable(); + inferred.flags |= source.flags & ts.SymbolFlags.Class; if (source.exports?.size) { mergeSymbolTable(inferred.exports, source.exports); } if (source.members?.size) { mergeSymbolTable(inferred.members, source.members); } - (links.inferredClassSymbol || (links.inferredClassSymbol = new Map())).set(getSymbolId(inferred), inferred); + (links.inferredClassSymbol || (links.inferredClassSymbol = new ts.Map())).set(getSymbolId(inferred), inferred); return inferred; } return links.inferredClassSymbol.get(getSymbolId(target)); } } - function getAssignedClassSymbol(decl: Declaration): Symbol | undefined { + function getAssignedClassSymbol(decl: ts.Declaration): ts.Symbol | undefined { const assignmentSymbol = decl && getSymbolOfExpando(decl, /*allowDeclaration*/ true); - const prototype = assignmentSymbol?.exports?.get("prototype" as __String); + const prototype = assignmentSymbol?.exports?.get("prototype" as ts.__String); const init = prototype?.valueDeclaration && getAssignedJSPrototype(prototype.valueDeclaration); return init ? getSymbolOfNode(init) : undefined; } - function getSymbolOfExpando(node: Node, allowDeclaration: boolean): Symbol | undefined { + function getSymbolOfExpando(node: ts.Node, allowDeclaration: boolean): ts.Symbol | undefined { if (!node.parent) { return undefined; } - let name: Expression | BindingName | undefined; - let decl: Node | undefined; - if (isVariableDeclaration(node.parent) && node.parent.initializer === node) { - if (!isInJSFile(node) && !(isVarConst(node.parent) && isFunctionLikeDeclaration(node))) { + let name: ts.Expression | ts.BindingName | undefined; + let decl: ts.Node | undefined; + if (ts.isVariableDeclaration(node.parent) && node.parent.initializer === node) { + if (!ts.isInJSFile(node) && !(ts.isVarConst(node.parent) && ts.isFunctionLikeDeclaration(node))) { return undefined; } name = node.parent.name; decl = node.parent; } - else if (isBinaryExpression(node.parent)) { + else if (ts.isBinaryExpression(node.parent)) { const parentNode = node.parent; const parentNodeOperator = node.parent.operatorToken.kind; - if (parentNodeOperator === SyntaxKind.EqualsToken && (allowDeclaration || parentNode.right === node)) { + if (parentNodeOperator === ts.SyntaxKind.EqualsToken && (allowDeclaration || parentNode.right === node)) { name = parentNode.left; decl = name; } - else if (parentNodeOperator === SyntaxKind.BarBarToken || parentNodeOperator === SyntaxKind.QuestionQuestionToken) { - if (isVariableDeclaration(parentNode.parent) && parentNode.parent.initializer === parentNode) { + else if (parentNodeOperator === ts.SyntaxKind.BarBarToken || parentNodeOperator === ts.SyntaxKind.QuestionQuestionToken) { + if (ts.isVariableDeclaration(parentNode.parent) && parentNode.parent.initializer === parentNode) { name = parentNode.parent.name; decl = parentNode.parent; } - else if (isBinaryExpression(parentNode.parent) && parentNode.parent.operatorToken.kind === SyntaxKind.EqualsToken && (allowDeclaration || parentNode.parent.right === parentNode)) { + else if (ts.isBinaryExpression(parentNode.parent) && parentNode.parent.operatorToken.kind === ts.SyntaxKind.EqualsToken && (allowDeclaration || parentNode.parent.right === parentNode)) { name = parentNode.parent.left; decl = name; } - if (!name || !isBindableStaticNameExpression(name) || !isSameEntityName(name, parentNode.left)) { + if (!name || !ts.isBindableStaticNameExpression(name) || !ts.isSameEntityName(name, parentNode.left)) { return undefined; } } } - else if (allowDeclaration && isFunctionDeclaration(node)) { + else if (allowDeclaration && ts.isFunctionDeclaration(node)) { name = node.name; decl = node; } - if (!decl || !name || (!allowDeclaration && !getExpandoInitializer(node, isPrototypeAccess(name)))) { + if (!decl || !name || (!allowDeclaration && !ts.getExpandoInitializer(node, ts.isPrototypeAccess(name)))) { return undefined; } return getSymbolOfNode(decl); } - function getAssignedJSPrototype(node: Node) { + function getAssignedJSPrototype(node: ts.Node) { if (!node.parent) { return false; } - let parent: Node = node.parent; - while (parent && parent.kind === SyntaxKind.PropertyAccessExpression) { + let parent: ts.Node = node.parent; + while (parent && parent.kind === ts.SyntaxKind.PropertyAccessExpression) { parent = parent.parent; } - if (parent && isBinaryExpression(parent) && isPrototypeAccess(parent.left) && parent.operatorToken.kind === SyntaxKind.EqualsToken) { - const right = getInitializerOfBinaryExpression(parent); - return isObjectLiteralExpression(right) && right; + if (parent && ts.isBinaryExpression(parent) && ts.isPrototypeAccess(parent.left) && parent.operatorToken.kind === ts.SyntaxKind.EqualsToken) { + const right = ts.getInitializerOfBinaryExpression(parent); + return ts.isObjectLiteralExpression(right) && right; } } @@ -31665,7 +30940,7 @@ namespace ts { * @param node The call/new expression to be checked. * @returns On success, the expression's signature's return type. On failure, anyType. */ - function checkCallExpression(node: CallExpression | NewExpression, checkMode?: CheckMode): Type { + function checkCallExpression(node: ts.CallExpression | ts.NewExpression, checkMode?: CheckMode): ts.Type { checkGrammarTypeArguments(node, node.typeArguments); const signature = getResolvedSignature(node, /*candidatesOutArray*/ undefined, checkMode); @@ -31677,55 +30952,55 @@ namespace ts { checkDeprecatedSignature(signature, node); - if (node.expression.kind === SyntaxKind.SuperKeyword) { + if (node.expression.kind === ts.SyntaxKind.SuperKeyword) { return voidType; } - if (node.kind === SyntaxKind.NewExpression) { + if (node.kind === ts.SyntaxKind.NewExpression) { const declaration = signature.declaration; if (declaration && - declaration.kind !== SyntaxKind.Constructor && - declaration.kind !== SyntaxKind.ConstructSignature && - declaration.kind !== SyntaxKind.ConstructorType && - !isJSDocConstructSignature(declaration) && + declaration.kind !== ts.SyntaxKind.Constructor && + declaration.kind !== ts.SyntaxKind.ConstructSignature && + declaration.kind !== ts.SyntaxKind.ConstructorType && + !ts.isJSDocConstructSignature(declaration) && !isJSConstructor(declaration)) { // When resolved signature is a call signature (and not a construct signature) the result type is any if (noImplicitAny) { - error(node, Diagnostics.new_expression_whose_target_lacks_a_construct_signature_implicitly_has_an_any_type); + error(node, ts.Diagnostics.new_expression_whose_target_lacks_a_construct_signature_implicitly_has_an_any_type); } return anyType; } } // In JavaScript files, calls to any identifier 'require' are treated as external module imports - if (isInJSFile(node) && isCommonJsRequire(node)) { - return resolveExternalModuleTypeByLiteral(node.arguments![0] as StringLiteral); + if (ts.isInJSFile(node) && isCommonJsRequire(node)) { + return resolveExternalModuleTypeByLiteral(node.arguments![0] as ts.StringLiteral); } const returnType = getReturnTypeOfSignature(signature); // Treat any call to the global 'Symbol' function that is part of a const variable or readonly property // as a fresh unique symbol literal type. - if (returnType.flags & TypeFlags.ESSymbolLike && isSymbolOrSymbolForCall(node)) { - return getESSymbolLikeTypeForNode(walkUpParenthesizedExpressions(node.parent)); + if (returnType.flags & ts.TypeFlags.ESSymbolLike && isSymbolOrSymbolForCall(node)) { + return getESSymbolLikeTypeForNode(ts.walkUpParenthesizedExpressions(node.parent)); } - if (node.kind === SyntaxKind.CallExpression && !node.questionDotToken && node.parent.kind === SyntaxKind.ExpressionStatement && - returnType.flags & TypeFlags.Void && getTypePredicateOfSignature(signature)) { - if (!isDottedName(node.expression)) { - error(node.expression, Diagnostics.Assertions_require_the_call_target_to_be_an_identifier_or_qualified_name); + if (node.kind === ts.SyntaxKind.CallExpression && !node.questionDotToken && node.parent.kind === ts.SyntaxKind.ExpressionStatement && + returnType.flags & ts.TypeFlags.Void && getTypePredicateOfSignature(signature)) { + if (!ts.isDottedName(node.expression)) { + error(node.expression, ts.Diagnostics.Assertions_require_the_call_target_to_be_an_identifier_or_qualified_name); } else if (!getEffectsSignature(node)) { - const diagnostic = error(node.expression, Diagnostics.Assertions_require_every_name_in_the_call_target_to_be_declared_with_an_explicit_type_annotation); + const diagnostic = error(node.expression, ts.Diagnostics.Assertions_require_every_name_in_the_call_target_to_be_declared_with_an_explicit_type_annotation); getTypeOfDottedName(node.expression, diagnostic); } } - if (isInJSFile(node)) { + if (ts.isInJSFile(node)) { const jsSymbol = getSymbolOfExpando(node, /*allowDeclaration*/ false); if (jsSymbol?.exports?.size) { - const jsAssignmentType = createAnonymousType(jsSymbol, jsSymbol.exports, emptyArray, emptyArray, emptyArray); - jsAssignmentType.objectFlags |= ObjectFlags.JSLiteral; + const jsAssignmentType = createAnonymousType(jsSymbol, jsSymbol.exports, ts.emptyArray, ts.emptyArray, ts.emptyArray); + jsAssignmentType.objectFlags |= ts.ObjectFlags.JSLiteral; return getIntersectionType([returnType, jsAssignmentType]); } } @@ -31733,45 +31008,46 @@ namespace ts { return returnType; } - function checkDeprecatedSignature(signature: Signature, node: CallLikeExpression) { - if (signature.declaration && signature.declaration.flags & NodeFlags.Deprecated) { + function checkDeprecatedSignature(signature: ts.Signature, node: ts.CallLikeExpression) { + if (signature.declaration && signature.declaration.flags & ts.NodeFlags.Deprecated) { const suggestionNode = getDeprecatedSuggestionNode(node); - const name = tryGetPropertyAccessOrIdentifierToString(getInvokedExpression(node)); + const name = ts.tryGetPropertyAccessOrIdentifierToString(ts.getInvokedExpression(node)); addDeprecatedSuggestionWithSignature(suggestionNode, signature.declaration, name, signatureToString(signature)); } } - function getDeprecatedSuggestionNode(node: Node): Node { - node = skipParentheses(node); + function getDeprecatedSuggestionNode(node: ts.Node): ts.Node { + node = ts.skipParentheses(node); switch (node.kind) { - case SyntaxKind.CallExpression: - case SyntaxKind.Decorator: - case SyntaxKind.NewExpression: - return getDeprecatedSuggestionNode((node as Decorator | CallExpression | NewExpression).expression); - case SyntaxKind.TaggedTemplateExpression: - return getDeprecatedSuggestionNode((node as TaggedTemplateExpression).tag); - case SyntaxKind.JsxOpeningElement: - case SyntaxKind.JsxSelfClosingElement: - return getDeprecatedSuggestionNode((node as JsxOpeningLikeElement).tagName); - case SyntaxKind.ElementAccessExpression: - return (node as ElementAccessExpression).argumentExpression; - case SyntaxKind.PropertyAccessExpression: - return (node as PropertyAccessExpression).name; - case SyntaxKind.TypeReference: - const typeReference = node as TypeReferenceNode; - return isQualifiedName(typeReference.typeName) ? typeReference.typeName.right : typeReference; + case ts.SyntaxKind.CallExpression: + case ts.SyntaxKind.Decorator: + case ts.SyntaxKind.NewExpression: + return getDeprecatedSuggestionNode((node as ts.Decorator | ts.CallExpression | ts.NewExpression).expression); + case ts.SyntaxKind.TaggedTemplateExpression: + return getDeprecatedSuggestionNode((node as ts.TaggedTemplateExpression).tag); + case ts.SyntaxKind.JsxOpeningElement: + case ts.SyntaxKind.JsxSelfClosingElement: + return getDeprecatedSuggestionNode((node as ts.JsxOpeningLikeElement).tagName); + case ts.SyntaxKind.ElementAccessExpression: + return (node as ts.ElementAccessExpression).argumentExpression; + case ts.SyntaxKind.PropertyAccessExpression: + return (node as ts.PropertyAccessExpression).name; + case ts.SyntaxKind.TypeReference: + const typeReference = node as ts.TypeReferenceNode; + return ts.isQualifiedName(typeReference.typeName) ? typeReference.typeName.right : typeReference; default: return node; } } - function isSymbolOrSymbolForCall(node: Node) { - if (!isCallExpression(node)) return false; + function isSymbolOrSymbolForCall(node: ts.Node) { + if (!ts.isCallExpression(node)) + return false; let left = node.expression; - if (isPropertyAccessExpression(left) && left.name.escapedText === "for") { + if (ts.isPropertyAccessExpression(left) && left.name.escapedText === "for") { left = left.expression; } - if (!isIdentifier(left) || left.escapedText !== "Symbol") { + if (!ts.isIdentifier(left) || left.escapedText !== "Symbol") { return false; } @@ -31781,10 +31057,10 @@ namespace ts { return false; } - return globalESSymbol === resolveName(left, "Symbol" as __String, SymbolFlags.Value, /*nameNotFoundMessage*/ undefined, /*nameArg*/ undefined, /*isUse*/ false); + return globalESSymbol === resolveName(left, "Symbol" as ts.__String, ts.SymbolFlags.Value, /*nameNotFoundMessage*/ undefined, /*nameArg*/ undefined, /*isUse*/ false); } - function checkImportCallExpression(node: ImportCall): Type { + function checkImportCallExpression(node: ts.ImportCall): ts.Type { // Check grammar of dynamic import checkGrammarImportCallExpression(node); @@ -31800,14 +31076,14 @@ namespace ts { checkExpressionCached(node.arguments[i]); } - if (specifierType.flags & TypeFlags.Undefined || specifierType.flags & TypeFlags.Null || !isTypeAssignableTo(specifierType, stringType)) { - error(specifier, Diagnostics.Dynamic_import_s_specifier_must_be_of_type_string_but_here_has_type_0, typeToString(specifierType)); + if (specifierType.flags & ts.TypeFlags.Undefined || specifierType.flags & ts.TypeFlags.Null || !isTypeAssignableTo(specifierType, stringType)) { + error(specifier, ts.Diagnostics.Dynamic_import_s_specifier_must_be_of_type_string_but_here_has_type_0, typeToString(specifierType)); } if (optionsType) { const importCallOptionsType = getGlobalImportCallOptionsType(/*reportErrors*/ true); if (importCallOptionsType !== emptyObjectType) { - checkTypeAssignableTo(optionsType, getNullableType(importCallOptionsType, TypeFlags.Undefined), node.arguments[1]); + checkTypeAssignableTo(optionsType, getNullableType(importCallOptionsType, ts.TypeFlags.Undefined), node.arguments[1]); } } @@ -31816,29 +31092,27 @@ namespace ts { if (moduleSymbol) { const esModuleSymbol = resolveESModuleSymbol(moduleSymbol, specifier, /*dontRecursivelyResolve*/ true, /*suppressUsageError*/ false); if (esModuleSymbol) { - return createPromiseReturnType(node, - getTypeWithSyntheticDefaultOnly(getTypeOfSymbol(esModuleSymbol), esModuleSymbol, moduleSymbol, specifier) || - getTypeWithSyntheticDefaultImportType(getTypeOfSymbol(esModuleSymbol), esModuleSymbol, moduleSymbol, specifier) - ); + return createPromiseReturnType(node, getTypeWithSyntheticDefaultOnly(getTypeOfSymbol(esModuleSymbol), esModuleSymbol, moduleSymbol, specifier) || + getTypeWithSyntheticDefaultImportType(getTypeOfSymbol(esModuleSymbol), esModuleSymbol, moduleSymbol, specifier)); } } return createPromiseReturnType(node, anyType); } - function createDefaultPropertyWrapperForModule(symbol: Symbol, originalSymbol: Symbol, anonymousSymbol?: Symbol | undefined) { - const memberTable = createSymbolTable(); - const newSymbol = createSymbol(SymbolFlags.Alias, InternalSymbolName.Default); + function createDefaultPropertyWrapperForModule(symbol: ts.Symbol, originalSymbol: ts.Symbol, anonymousSymbol?: ts.Symbol | undefined) { + const memberTable = ts.createSymbolTable(); + const newSymbol = createSymbol(ts.SymbolFlags.Alias, ts.InternalSymbolName.Default); newSymbol.parent = originalSymbol; newSymbol.nameType = getStringLiteralType("default"); newSymbol.aliasTarget = resolveSymbol(symbol); - memberTable.set(InternalSymbolName.Default, newSymbol); - return createAnonymousType(anonymousSymbol, memberTable, emptyArray, emptyArray, emptyArray); + memberTable.set(ts.InternalSymbolName.Default, newSymbol); + return createAnonymousType(anonymousSymbol, memberTable, ts.emptyArray, ts.emptyArray, ts.emptyArray); } - function getTypeWithSyntheticDefaultOnly(type: Type, symbol: Symbol, originalSymbol: Symbol, moduleSpecifier: Expression) { + function getTypeWithSyntheticDefaultOnly(type: ts.Type, symbol: ts.Symbol, originalSymbol: ts.Symbol, moduleSpecifier: ts.Expression) { const hasDefaultOnly = isOnlyImportedAsDefault(moduleSpecifier); if (hasDefaultOnly && type && !isErrorType(type)) { - const synthType = type as SyntheticDefaultModuleType; + const synthType = type as ts.SyntheticDefaultModuleType; if (!synthType.defaultOnlyType) { const type = createDefaultPropertyWrapperForModule(symbol, originalSymbol); synthType.defaultOnlyType = type; @@ -31848,14 +31122,14 @@ namespace ts { return undefined; } - function getTypeWithSyntheticDefaultImportType(type: Type, symbol: Symbol, originalSymbol: Symbol, moduleSpecifier: Expression): Type { + function getTypeWithSyntheticDefaultImportType(type: ts.Type, symbol: ts.Symbol, originalSymbol: ts.Symbol, moduleSpecifier: ts.Expression): ts.Type { if (allowSyntheticDefaultImports && type && !isErrorType(type)) { - const synthType = type as SyntheticDefaultModuleType; + const synthType = type as ts.SyntheticDefaultModuleType; if (!synthType.syntheticType) { - const file = originalSymbol.declarations?.find(isSourceFile); + const file = originalSymbol.declarations?.find(ts.isSourceFile); const hasSyntheticDefault = canHaveSyntheticDefault(file, originalSymbol, /*dontResolveAlias*/ false, moduleSpecifier); if (hasSyntheticDefault) { - const anonymousSymbol = createSymbol(SymbolFlags.TypeLiteral, InternalSymbolName.Type); + const anonymousSymbol = createSymbol(ts.SymbolFlags.TypeLiteral, ts.InternalSymbolName.Type); const defaultContainingObject = createDefaultPropertyWrapperForModule(symbol, originalSymbol, anonymousSymbol); anonymousSymbol.type = defaultContainingObject; synthType.syntheticType = isValidSpreadType(type) ? getSpreadType(type, defaultContainingObject, anonymousSymbol, /*objectFlags*/ 0, /*readonly*/ false) : defaultContainingObject; @@ -31869,91 +31143,93 @@ namespace ts { return type; } - function isCommonJsRequire(node: Node): boolean { - if (!isRequireCall(node, /*checkArgumentIsStringLiteralLike*/ true)) { + function isCommonJsRequire(node: ts.Node): boolean { + if (!ts.isRequireCall(node, /*checkArgumentIsStringLiteralLike*/ true)) { return false; } // Make sure require is not a local function - if (!isIdentifier(node.expression)) return Debug.fail(); - const resolvedRequire = resolveName(node.expression, node.expression.escapedText, SymbolFlags.Value, /*nameNotFoundMessage*/ undefined, /*nameArg*/ undefined, /*isUse*/ true)!; // TODO: GH#18217 + if (!ts.isIdentifier(node.expression)) + return ts.Debug.fail(); + const resolvedRequire = resolveName(node.expression, node.expression.escapedText, ts.SymbolFlags.Value, /*nameNotFoundMessage*/ undefined, /*nameArg*/ undefined, /*isUse*/ true)!; // TODO: GH#18217 if (resolvedRequire === requireSymbol) { return true; } // project includes symbol named 'require' - make sure that it is ambient and local non-alias - if (resolvedRequire.flags & SymbolFlags.Alias) { + if (resolvedRequire.flags & ts.SymbolFlags.Alias) { return false; } - const targetDeclarationKind = resolvedRequire.flags & SymbolFlags.Function - ? SyntaxKind.FunctionDeclaration - : resolvedRequire.flags & SymbolFlags.Variable - ? SyntaxKind.VariableDeclaration - : SyntaxKind.Unknown; - if (targetDeclarationKind !== SyntaxKind.Unknown) { - const decl = getDeclarationOfKind(resolvedRequire, targetDeclarationKind)!; + const targetDeclarationKind = resolvedRequire.flags & ts.SymbolFlags.Function + ? ts.SyntaxKind.FunctionDeclaration + : resolvedRequire.flags & ts.SymbolFlags.Variable + ? ts.SyntaxKind.VariableDeclaration + : ts.SyntaxKind.Unknown; + if (targetDeclarationKind !== ts.SyntaxKind.Unknown) { + const decl = ts.getDeclarationOfKind(resolvedRequire, targetDeclarationKind)!; // function/variable declaration should be ambient - return !!decl && !!(decl.flags & NodeFlags.Ambient); + return !!decl && !!(decl.flags & ts.NodeFlags.Ambient); } return false; } - function checkTaggedTemplateExpression(node: TaggedTemplateExpression): Type { - if (!checkGrammarTaggedTemplateChain(node)) checkGrammarTypeArguments(node, node.typeArguments); - if (languageVersion < ScriptTarget.ES2015) { - checkExternalEmitHelpers(node, ExternalEmitHelpers.MakeTemplateObject); + function checkTaggedTemplateExpression(node: ts.TaggedTemplateExpression): ts.Type { + if (!checkGrammarTaggedTemplateChain(node)) + checkGrammarTypeArguments(node, node.typeArguments); + if (languageVersion < ts.ScriptTarget.ES2015) { + checkExternalEmitHelpers(node, ts.ExternalEmitHelpers.MakeTemplateObject); } const signature = getResolvedSignature(node); checkDeprecatedSignature(signature, node); return getReturnTypeOfSignature(signature); } - function checkAssertion(node: AssertionExpression) { - if (node.kind === SyntaxKind.TypeAssertionExpression) { - const file = getSourceFileOfNode(node); - if (file && fileExtensionIsOneOf(file.fileName, [Extension.Cts, Extension.Mts])) { - grammarErrorOnNode(node, Diagnostics.This_syntax_is_reserved_in_files_with_the_mts_or_cts_extension_Use_an_as_expression_instead); + function checkAssertion(node: ts.AssertionExpression) { + if (node.kind === ts.SyntaxKind.TypeAssertionExpression) { + const file = ts.getSourceFileOfNode(node); + if (file && ts.fileExtensionIsOneOf(file.fileName, [ts.Extension.Cts, ts.Extension.Mts])) { + grammarErrorOnNode(node, ts.Diagnostics.This_syntax_is_reserved_in_files_with_the_mts_or_cts_extension_Use_an_as_expression_instead); } } return checkAssertionWorker(node, node.type, node.expression); } - function isValidConstAssertionArgument(node: Node): boolean { + function isValidConstAssertionArgument(node: ts.Node): boolean { switch (node.kind) { - case SyntaxKind.StringLiteral: - case SyntaxKind.NoSubstitutionTemplateLiteral: - case SyntaxKind.NumericLiteral: - case SyntaxKind.BigIntLiteral: - case SyntaxKind.TrueKeyword: - case SyntaxKind.FalseKeyword: - case SyntaxKind.ArrayLiteralExpression: - case SyntaxKind.ObjectLiteralExpression: - case SyntaxKind.TemplateExpression: + case ts.SyntaxKind.StringLiteral: + case ts.SyntaxKind.NoSubstitutionTemplateLiteral: + case ts.SyntaxKind.NumericLiteral: + case ts.SyntaxKind.BigIntLiteral: + case ts.SyntaxKind.TrueKeyword: + case ts.SyntaxKind.FalseKeyword: + case ts.SyntaxKind.ArrayLiteralExpression: + case ts.SyntaxKind.ObjectLiteralExpression: + case ts.SyntaxKind.TemplateExpression: return true; - case SyntaxKind.ParenthesizedExpression: - return isValidConstAssertionArgument((node as ParenthesizedExpression).expression); - case SyntaxKind.PrefixUnaryExpression: - const op = (node as PrefixUnaryExpression).operator; - const arg = (node as PrefixUnaryExpression).operand; - return op === SyntaxKind.MinusToken && (arg.kind === SyntaxKind.NumericLiteral || arg.kind === SyntaxKind.BigIntLiteral) || - op === SyntaxKind.PlusToken && arg.kind === SyntaxKind.NumericLiteral; - case SyntaxKind.PropertyAccessExpression: - case SyntaxKind.ElementAccessExpression: - const expr = (node as PropertyAccessExpression | ElementAccessExpression).expression; + case ts.SyntaxKind.ParenthesizedExpression: + return isValidConstAssertionArgument((node as ts.ParenthesizedExpression).expression); + case ts.SyntaxKind.PrefixUnaryExpression: + const op = (node as ts.PrefixUnaryExpression).operator; + const arg = (node as ts.PrefixUnaryExpression).operand; + return op === ts.SyntaxKind.MinusToken && (arg.kind === ts.SyntaxKind.NumericLiteral || arg.kind === ts.SyntaxKind.BigIntLiteral) || + op === ts.SyntaxKind.PlusToken && arg.kind === ts.SyntaxKind.NumericLiteral; + case ts.SyntaxKind.PropertyAccessExpression: + case ts.SyntaxKind.ElementAccessExpression: + const expr = (node as ts.PropertyAccessExpression | ts.ElementAccessExpression).expression; let symbol = getTypeOfNode(expr).symbol; - if (symbol && symbol.flags & SymbolFlags.Alias) { + if (symbol && symbol.flags & ts.SymbolFlags.Alias) { symbol = resolveAlias(symbol); } - return !!(symbol && (symbol.flags & SymbolFlags.Enum) && getEnumKind(symbol) === EnumKind.Literal); + return !!(symbol && (symbol.flags & ts.SymbolFlags.Enum) && getEnumKind(symbol) === ts.EnumKind.Literal); } return false; } - function checkAssertionWorker(errNode: Node, type: TypeNode, expression: UnaryExpression | Expression, checkMode?: CheckMode) { + function checkAssertionWorker(errNode: ts.Node, type: ts.TypeNode, expression: ts.UnaryExpression | ts.Expression, checkMode?: CheckMode) { let exprType = checkExpression(expression, checkMode); - if (isConstTypeReference(type)) { + if (ts.isConstTypeReference(type)) { if (!isValidConstAssertionArgument(expression)) { - error(expression, Diagnostics.A_const_assertions_can_only_be_applied_to_references_to_enum_members_or_string_number_boolean_array_or_object_literals); + error(expression, ts.Diagnostics.A_const_assertions_can_only_be_applied_to_references_to_enum_members_or_string_number_boolean_array_or_object_literals); } return getRegularTypeOfLiteralType(exprType); } @@ -31964,44 +31240,43 @@ namespace ts { addLazyDiagnostic(() => { const widenedType = getWidenedType(exprType); if (!isTypeComparableTo(targetType, widenedType)) { - checkTypeComparableTo(exprType, targetType, errNode, - Diagnostics.Conversion_of_type_0_to_type_1_may_be_a_mistake_because_neither_type_sufficiently_overlaps_with_the_other_If_this_was_intentional_convert_the_expression_to_unknown_first); + checkTypeComparableTo(exprType, targetType, errNode, ts.Diagnostics.Conversion_of_type_0_to_type_1_may_be_a_mistake_because_neither_type_sufficiently_overlaps_with_the_other_If_this_was_intentional_convert_the_expression_to_unknown_first); } }); } return targetType; } - function checkNonNullChain(node: NonNullChain) { + function checkNonNullChain(node: ts.NonNullChain) { const leftType = checkExpression(node.expression); const nonOptionalType = getOptionalExpressionType(leftType, node.expression); return propagateOptionalTypeMarker(getNonNullableType(nonOptionalType), node, nonOptionalType !== leftType); } - function checkNonNullAssertion(node: NonNullExpression) { - return node.flags & NodeFlags.OptionalChain ? checkNonNullChain(node as NonNullChain) : + function checkNonNullAssertion(node: ts.NonNullExpression) { + return node.flags & ts.NodeFlags.OptionalChain ? checkNonNullChain(node as ts.NonNullChain) : getNonNullableType(checkExpression(node.expression)); } - function checkExpressionWithTypeArguments(node: ExpressionWithTypeArguments | TypeQueryNode) { + function checkExpressionWithTypeArguments(node: ts.ExpressionWithTypeArguments | ts.TypeQueryNode) { checkGrammarExpressionWithTypeArguments(node); - const exprType = node.kind === SyntaxKind.ExpressionWithTypeArguments ? checkExpression(node.expression) : - isThisIdentifier(node.exprName) ? checkThisExpression(node.exprName) : + const exprType = node.kind === ts.SyntaxKind.ExpressionWithTypeArguments ? checkExpression(node.expression) : + ts.isThisIdentifier(node.exprName) ? checkThisExpression(node.exprName) : checkExpression(node.exprName); const typeArguments = node.typeArguments; - if (exprType === silentNeverType || isErrorType(exprType) || !some(typeArguments)) { + if (exprType === silentNeverType || isErrorType(exprType) || !ts.some(typeArguments)) { return exprType; } let hasSomeApplicableSignature = false; - let nonApplicableType: Type | undefined; + let nonApplicableType: ts.Type | undefined; const result = getInstantiatedType(exprType); const errorType = hasSomeApplicableSignature ? nonApplicableType : exprType; if (errorType) { - diagnostics.add(createDiagnosticForNodeArray(getSourceFileOfNode(node), typeArguments, Diagnostics.Type_0_has_no_signatures_for_which_the_type_argument_list_is_applicable, typeToString(errorType))); + diagnostics.add(ts.createDiagnosticForNodeArray(ts.getSourceFileOfNode(node), typeArguments, ts.Diagnostics.Type_0_has_no_signatures_for_which_the_type_argument_list_is_applicable, typeToString(errorType))); } return result; - function getInstantiatedType(type: Type): Type { + function getInstantiatedType(type: ts.Type): ts.Type { let hasSignatures = false; let hasApplicableSignature = false; const result = getInstantiatedTypePart(type); @@ -32011,21 +31286,21 @@ namespace ts { } return result; - function getInstantiatedTypePart(type: Type): Type { - if (type.flags & TypeFlags.Object) { - const resolved = resolveStructuredTypeMembers(type as ObjectType); + function getInstantiatedTypePart(type: ts.Type): ts.Type { + if (type.flags & ts.TypeFlags.Object) { + const resolved = resolveStructuredTypeMembers(type as ts.ObjectType); const callSignatures = getInstantiatedSignatures(resolved.callSignatures); const constructSignatures = getInstantiatedSignatures(resolved.constructSignatures); hasSignatures ||= resolved.callSignatures.length !== 0 || resolved.constructSignatures.length !== 0; hasApplicableSignature ||= callSignatures.length !== 0 || constructSignatures.length !== 0; if (callSignatures !== resolved.callSignatures || constructSignatures !== resolved.constructSignatures) { - const result = createAnonymousType(undefined, resolved.members, callSignatures, constructSignatures, resolved.indexInfos) as ResolvedType & InstantiationExpressionType; - result.objectFlags |= ObjectFlags.InstantiationExpressionType; + const result = createAnonymousType(undefined, resolved.members, callSignatures, constructSignatures, resolved.indexInfos) as ts.ResolvedType & ts.InstantiationExpressionType; + result.objectFlags |= ts.ObjectFlags.InstantiationExpressionType; result.node = node; return result; } } - else if (type.flags & TypeFlags.InstantiableNonPrimitive) { + else if (type.flags & ts.TypeFlags.InstantiableNonPrimitive) { const constraint = getBaseConstraintOfType(type); if (constraint) { const instantiated = getInstantiatedTypePart(constraint); @@ -32034,59 +31309,59 @@ namespace ts { } } } - else if (type.flags & TypeFlags.Union) { + else if (type.flags & ts.TypeFlags.Union) { return mapType(type, getInstantiatedType); } - else if (type.flags & TypeFlags.Intersection) { - return getIntersectionType(sameMap((type as IntersectionType).types, getInstantiatedTypePart)); + else if (type.flags & ts.TypeFlags.Intersection) { + return getIntersectionType(ts.sameMap((type as ts.IntersectionType).types, getInstantiatedTypePart)); } return type; } } - function getInstantiatedSignatures(signatures: readonly Signature[]) { - const applicableSignatures = filter(signatures, sig => !!sig.typeParameters && hasCorrectTypeArgumentArity(sig, typeArguments)); - return sameMap(applicableSignatures, sig => { + function getInstantiatedSignatures(signatures: readonly ts.Signature[]) { + const applicableSignatures = ts.filter(signatures, sig => !!sig.typeParameters && hasCorrectTypeArgumentArity(sig, typeArguments)); + return ts.sameMap(applicableSignatures, sig => { const typeArgumentTypes = checkTypeArguments(sig, typeArguments!, /*reportErrors*/ true); - return typeArgumentTypes ? getSignatureInstantiation(sig, typeArgumentTypes, isInJSFile(sig.declaration)) : sig; + return typeArgumentTypes ? getSignatureInstantiation(sig, typeArgumentTypes, ts.isInJSFile(sig.declaration)) : sig; }); } } - function checkMetaProperty(node: MetaProperty): Type { + function checkMetaProperty(node: ts.MetaProperty): ts.Type { checkGrammarMetaProperty(node); - if (node.keywordToken === SyntaxKind.NewKeyword) { + if (node.keywordToken === ts.SyntaxKind.NewKeyword) { return checkNewTargetMetaProperty(node); } - if (node.keywordToken === SyntaxKind.ImportKeyword) { + if (node.keywordToken === ts.SyntaxKind.ImportKeyword) { return checkImportMetaProperty(node); } - return Debug.assertNever(node.keywordToken); + return ts.Debug.assertNever(node.keywordToken); } - function checkMetaPropertyKeyword(node: MetaProperty): Type { + function checkMetaPropertyKeyword(node: ts.MetaProperty): ts.Type { switch (node.keywordToken) { - case SyntaxKind.ImportKeyword: + case ts.SyntaxKind.ImportKeyword: return getGlobalImportMetaExpressionType(); - case SyntaxKind.NewKeyword: + case ts.SyntaxKind.NewKeyword: const type = checkNewTargetMetaProperty(node); return isErrorType(type) ? errorType : createNewTargetExpressionType(type); default: - Debug.assertNever(node.keywordToken); + ts.Debug.assertNever(node.keywordToken); } } - function checkNewTargetMetaProperty(node: MetaProperty) { - const container = getNewTargetContainer(node); + function checkNewTargetMetaProperty(node: ts.MetaProperty) { + const container = ts.getNewTargetContainer(node); if (!container) { - error(node, Diagnostics.Meta_property_0_is_only_allowed_in_the_body_of_a_function_declaration_function_expression_or_constructor, "new.target"); + error(node, ts.Diagnostics.Meta_property_0_is_only_allowed_in_the_body_of_a_function_declaration_function_expression_or_constructor, "new.target"); return errorType; } - else if (container.kind === SyntaxKind.Constructor) { - const symbol = getSymbolOfNode(container.parent as ClassLikeDeclaration); + else if (container.kind === ts.SyntaxKind.Constructor) { + const symbol = getSymbolOfNode(container.parent as ts.ClassLikeDeclaration); return getTypeOfSymbol(symbol); } else { @@ -32095,37 +31370,37 @@ namespace ts { } } - function checkImportMetaProperty(node: MetaProperty) { - if (moduleKind === ModuleKind.Node16 || moduleKind === ModuleKind.NodeNext) { - if (getSourceFileOfNode(node).impliedNodeFormat !== ModuleKind.ESNext) { - error(node, Diagnostics.The_import_meta_meta_property_is_not_allowed_in_files_which_will_build_into_CommonJS_output); + function checkImportMetaProperty(node: ts.MetaProperty) { + if (moduleKind === ts.ModuleKind.Node16 || moduleKind === ts.ModuleKind.NodeNext) { + if (ts.getSourceFileOfNode(node).impliedNodeFormat !== ts.ModuleKind.ESNext) { + error(node, ts.Diagnostics.The_import_meta_meta_property_is_not_allowed_in_files_which_will_build_into_CommonJS_output); } } - else if (moduleKind < ModuleKind.ES2020 && moduleKind !== ModuleKind.System) { - error(node, Diagnostics.The_import_meta_meta_property_is_only_allowed_when_the_module_option_is_es2020_es2022_esnext_system_node16_or_nodenext); + else if (moduleKind < ts.ModuleKind.ES2020 && moduleKind !== ts.ModuleKind.System) { + error(node, ts.Diagnostics.The_import_meta_meta_property_is_only_allowed_when_the_module_option_is_es2020_es2022_esnext_system_node16_or_nodenext); } - const file = getSourceFileOfNode(node); - Debug.assert(!!(file.flags & NodeFlags.PossiblyContainsImportMeta), "Containing file is missing import meta node flag."); + const file = ts.getSourceFileOfNode(node); + ts.Debug.assert(!!(file.flags & ts.NodeFlags.PossiblyContainsImportMeta), "Containing file is missing import meta node flag."); return node.name.escapedText === "meta" ? getGlobalImportMetaType() : errorType; } - function getTypeOfParameter(symbol: Symbol) { + function getTypeOfParameter(symbol: ts.Symbol) { const type = getTypeOfSymbol(symbol); if (strictNullChecks) { const declaration = symbol.valueDeclaration; - if (declaration && hasInitializer(declaration)) { + if (declaration && ts.hasInitializer(declaration)) { return getOptionalType(type); } } return type; } - function getTupleElementLabel(d: ParameterDeclaration | NamedTupleMember) { - Debug.assert(isIdentifier(d.name)); // Parameter declarations could be binding patterns, but we only allow identifier names + function getTupleElementLabel(d: ts.ParameterDeclaration | ts.NamedTupleMember) { + ts.Debug.assert(ts.isIdentifier(d.name)); // Parameter declarations could be binding patterns, but we only allow identifier names return d.name.escapedText; } - function getParameterNameAtPosition(signature: Signature, pos: number, overrideRestType?: Type) { + function getParameterNameAtPosition(signature: ts.Signature, pos: number, overrideRestType?: ts.Type) { const paramCount = signature.parameters.length - (signatureHasRestParameter(signature) ? 1 : 0); if (pos < paramCount) { return signature.parameters[pos].escapedName; @@ -32133,15 +31408,18 @@ namespace ts { const restParameter = signature.parameters[paramCount] || unknownSymbol; const restType = overrideRestType || getTypeOfSymbol(restParameter); if (isTupleType(restType)) { - const associatedNames = ((restType as TypeReference).target as TupleType).labeledElementDeclarations; + const associatedNames = ((restType as ts.TypeReference).target as ts.TupleType).labeledElementDeclarations; const index = pos - paramCount; - return associatedNames && getTupleElementLabel(associatedNames[index]) || restParameter.escapedName + "_" + index as __String; + return associatedNames && getTupleElementLabel(associatedNames[index]) || restParameter.escapedName + "_" + index as ts.__String; } return restParameter.escapedName; } - function getParameterIdentifierNameAtPosition(signature: Signature, pos: number): [parameterName: __String, isRestParameter: boolean] | undefined { - if (signature.declaration?.kind === SyntaxKind.JSDocFunctionType) { + function getParameterIdentifierNameAtPosition(signature: ts.Signature, pos: number): [ + parameterName: ts.__String, + isRestParameter: boolean + ] | undefined { + if (signature.declaration?.kind === ts.SyntaxKind.JSDocFunctionType) { return undefined; } const paramCount = signature.parameters.length - (signatureHasRestParameter(signature) ? 1 : 0); @@ -32157,7 +31435,7 @@ namespace ts { const restType = getTypeOfSymbol(restParameter); if (isTupleType(restType)) { - const associatedNames = ((restType as TypeReference).target as TupleType).labeledElementDeclarations; + const associatedNames = ((restType as ts.TypeReference).target as ts.TupleType).labeledElementDeclarations; const index = pos - paramCount; const associatedName = associatedNames?.[index]; const isRestTupleElement = !!associatedName?.dotDotDotToken; @@ -32173,14 +31451,16 @@ namespace ts { return undefined; } - function isParameterDeclarationWithIdentifierName(symbol: Symbol) { - return symbol.valueDeclaration && isParameter(symbol.valueDeclaration) && isIdentifier(symbol.valueDeclaration.name); + function isParameterDeclarationWithIdentifierName(symbol: ts.Symbol) { + return symbol.valueDeclaration && ts.isParameter(symbol.valueDeclaration) && ts.isIdentifier(symbol.valueDeclaration.name); } - function isValidDeclarationForTupleLabel(d: Declaration): d is NamedTupleMember | (ParameterDeclaration & { name: Identifier }) { - return d.kind === SyntaxKind.NamedTupleMember || (isParameter(d) && d.name && isIdentifier(d.name)); + function isValidDeclarationForTupleLabel(d: ts.Declaration): d is ts.NamedTupleMember | (ts.ParameterDeclaration & { + name: ts.Identifier; + }) { + return d.kind === ts.SyntaxKind.NamedTupleMember || (ts.isParameter(d) && d.name && ts.isIdentifier(d.name)); } - function getNameableDeclarationAtPosition(signature: Signature, pos: number) { + function getNameableDeclarationAtPosition(signature: ts.Signature, pos: number) { const paramCount = signature.parameters.length - (signatureHasRestParameter(signature) ? 1 : 0); if (pos < paramCount) { const decl = signature.parameters[pos].valueDeclaration; @@ -32189,18 +31469,18 @@ namespace ts { const restParameter = signature.parameters[paramCount] || unknownSymbol; const restType = getTypeOfSymbol(restParameter); if (isTupleType(restType)) { - const associatedNames = ((restType as TypeReference).target as TupleType).labeledElementDeclarations; + const associatedNames = ((restType as ts.TypeReference).target as ts.TupleType).labeledElementDeclarations; const index = pos - paramCount; return associatedNames && associatedNames[index]; } return restParameter.valueDeclaration && isValidDeclarationForTupleLabel(restParameter.valueDeclaration) ? restParameter.valueDeclaration : undefined; } - function getTypeAtPosition(signature: Signature, pos: number): Type { + function getTypeAtPosition(signature: ts.Signature, pos: number): ts.Type { return tryGetTypeAtPosition(signature, pos) || anyType; } - function tryGetTypeAtPosition(signature: Signature, pos: number): Type | undefined { + function tryGetTypeAtPosition(signature: ts.Signature, pos: number): ts.Type | undefined { const paramCount = signature.parameters.length - (signatureHasRestParameter(signature) ? 1 : 0); if (pos < paramCount) { return getTypeOfParameter(signature.parameters[pos]); @@ -32218,7 +31498,7 @@ namespace ts { return undefined; } - function getRestTypeAtPosition(source: Signature, pos: number): Type { + function getRestTypeAtPosition(source: ts.Signature, pos: number): ts.Type { const parameterCount = getParameterCount(source); const minArgumentCount = getMinArgumentCount(source); const restType = getEffectiveRestType(source); @@ -32231,25 +31511,25 @@ namespace ts { for (let i = pos; i < parameterCount; i++) { if (!restType || i < parameterCount - 1) { types.push(getTypeAtPosition(source, i)); - flags.push(i < minArgumentCount ? ElementFlags.Required : ElementFlags.Optional); + flags.push(i < minArgumentCount ? ts.ElementFlags.Required : ts.ElementFlags.Optional); } else { types.push(restType); - flags.push(ElementFlags.Variadic); + flags.push(ts.ElementFlags.Variadic); } const name = getNameableDeclarationAtPosition(source, i); if (name) { names.push(name); } } - return createTupleType(types, flags, /*readonly*/ false, length(names) === length(types) ? names : undefined); + return createTupleType(types, flags, /*readonly*/ false, ts.length(names) === ts.length(types) ? names : undefined); } // Return the number of parameters in a signature. The rest parameter, if present, counts as one // parameter. For example, the parameter count of (x: number, y: number, ...z: string[]) is 3 and // the parameter count of (x: number, ...args: [number, ...string[], boolean])) is also 3. In the // latter example, the effective rest type is [...string[], boolean]. - function getParameterCount(signature: Signature) { + function getParameterCount(signature: ts.Signature) { const length = signature.parameters.length; if (signatureHasRestParameter(signature)) { const restType = getTypeOfSymbol(signature.parameters[length - 1]); @@ -32260,7 +31540,7 @@ namespace ts { return length; } - function getMinArgumentCount(signature: Signature, flags?: MinArgumentCountFlags) { + function getMinArgumentCount(signature: ts.Signature, flags?: MinArgumentCountFlags) { const strongArityForUntypedJS = flags! & MinArgumentCountFlags.StrongArityForUntypedJS; const voidIsNonOptional = flags! & MinArgumentCountFlags.VoidIsNonOptional; if (voidIsNonOptional || signature.resolvedMinArgumentCount === undefined) { @@ -32268,7 +31548,7 @@ namespace ts { if (signatureHasRestParameter(signature)) { const restType = getTypeOfSymbol(signature.parameters[signature.parameters.length - 1]); if (isTupleType(restType)) { - const firstOptionalIndex = findIndex(restType.target.elementFlags, f => !(f & ElementFlags.Required)); + const firstOptionalIndex = ts.findIndex(restType.target.elementFlags, f => !(f & ts.ElementFlags.Required)); const requiredCount = firstOptionalIndex < 0 ? restType.target.fixedLength : firstOptionalIndex; if (requiredCount > 0) { minArgumentCount = signature.parameters.length - 1 + requiredCount; @@ -32276,7 +31556,7 @@ namespace ts { } } if (minArgumentCount === undefined) { - if (!strongArityForUntypedJS && signature.flags & SignatureFlags.IsUntypedSignatureInJSFile) { + if (!strongArityForUntypedJS && signature.flags & ts.SignatureFlags.IsUntypedSignatureInJSFile) { return 0; } minArgumentCount = signature.minArgumentCount; @@ -32286,7 +31566,7 @@ namespace ts { } for (let i = minArgumentCount - 1; i >= 0; i--) { const type = getTypeAtPosition(signature, i); - if (filterType(type, acceptsVoid).flags & TypeFlags.Never) { + if (filterType(type, acceptsVoid).flags & ts.TypeFlags.Never) { break; } minArgumentCount = i; @@ -32296,7 +31576,7 @@ namespace ts { return signature.resolvedMinArgumentCount; } - function hasEffectiveRestParameter(signature: Signature) { + function hasEffectiveRestParameter(signature: ts.Signature) { if (signatureHasRestParameter(signature)) { const restType = getTypeOfSymbol(signature.parameters[signature.parameters.length - 1]); return !isTupleType(restType) || restType.target.hasRestElement; @@ -32304,7 +31584,7 @@ namespace ts { return false; } - function getEffectiveRestType(signature: Signature) { + function getEffectiveRestType(signature: ts.Signature) { if (signatureHasRestParameter(signature)) { const restType = getTypeOfSymbol(signature.parameters[signature.parameters.length - 1]); if (!isTupleType(restType)) { @@ -32317,32 +31597,32 @@ namespace ts { return undefined; } - function getNonArrayRestType(signature: Signature) { + function getNonArrayRestType(signature: ts.Signature) { const restType = getEffectiveRestType(signature); - return restType && !isArrayType(restType) && !isTypeAny(restType) && (getReducedType(restType).flags & TypeFlags.Never) === 0 ? restType : undefined; + return restType && !isArrayType(restType) && !isTypeAny(restType) && (getReducedType(restType).flags & ts.TypeFlags.Never) === 0 ? restType : undefined; } - function getTypeOfFirstParameterOfSignature(signature: Signature) { + function getTypeOfFirstParameterOfSignature(signature: ts.Signature) { return getTypeOfFirstParameterOfSignatureWithFallback(signature, neverType); } - function getTypeOfFirstParameterOfSignatureWithFallback(signature: Signature, fallbackType: Type) { + function getTypeOfFirstParameterOfSignatureWithFallback(signature: ts.Signature, fallbackType: ts.Type) { return signature.parameters.length > 0 ? getTypeAtPosition(signature, 0) : fallbackType; } - function inferFromAnnotatedParameters(signature: Signature, context: Signature, inferenceContext: InferenceContext) { + function inferFromAnnotatedParameters(signature: ts.Signature, context: ts.Signature, inferenceContext: ts.InferenceContext) { const len = signature.parameters.length - (signatureHasRestParameter(signature) ? 1 : 0); for (let i = 0; i < len; i++) { - const declaration = signature.parameters[i].valueDeclaration as ParameterDeclaration; + const declaration = signature.parameters[i].valueDeclaration as ts.ParameterDeclaration; if (declaration.type) { - const typeNode = getEffectiveTypeAnnotationNode(declaration); + const typeNode = ts.getEffectiveTypeAnnotationNode(declaration); if (typeNode) { inferTypes(inferenceContext.inferences, getTypeFromTypeNode(typeNode), getTypeAtPosition(context, i)); } } } const restType = getEffectiveRestType(context); - if (restType && restType.flags & TypeFlags.TypeParameter) { + if (restType && restType.flags & ts.TypeFlags.TypeParameter) { // The contextual signature has a generic rest parameter. We first instantiate the contextual // signature (without fixing type parameters) and assign types to contextually typed parameters. const instantiatedContext = instantiateSignature(context, inferenceContext.nonFixingMapper); @@ -32354,7 +31634,7 @@ namespace ts { } } - function assignContextualParameterTypes(signature: Signature, context: Signature) { + function assignContextualParameterTypes(signature: ts.Signature, context: ts.Signature) { if (context.typeParameters) { if (!signature.typeParameters) { signature.typeParameters = context.typeParameters; @@ -32365,7 +31645,7 @@ namespace ts { } if (context.thisParameter) { const parameter = signature.thisParameter; - if (!parameter || parameter.valueDeclaration && !(parameter.valueDeclaration as ParameterDeclaration).type) { + if (!parameter || parameter.valueDeclaration && !(parameter.valueDeclaration as ts.ParameterDeclaration).type) { if (!parameter) { signature.thisParameter = createSymbolWithType(context.thisParameter, /*type*/ undefined); } @@ -32375,27 +31655,26 @@ namespace ts { const len = signature.parameters.length - (signatureHasRestParameter(signature) ? 1 : 0); for (let i = 0; i < len; i++) { const parameter = signature.parameters[i]; - if (!getEffectiveTypeAnnotationNode(parameter.valueDeclaration as ParameterDeclaration)) { + if (!ts.getEffectiveTypeAnnotationNode(parameter.valueDeclaration as ts.ParameterDeclaration)) { const contextualParameterType = tryGetTypeAtPosition(context, i); assignParameterType(parameter, contextualParameterType); } } if (signatureHasRestParameter(signature)) { // parameter might be a transient symbol generated by use of `arguments` in the function body. - const parameter = last(signature.parameters); + const parameter = ts.last(signature.parameters); if (parameter.valueDeclaration - ? !getEffectiveTypeAnnotationNode(parameter.valueDeclaration as ParameterDeclaration) + ? !ts.getEffectiveTypeAnnotationNode(parameter.valueDeclaration as ts.ParameterDeclaration) // a declarationless parameter may still have a `.type` already set by its construction logic // (which may pull a type from a jsdoc) - only allow fixing on `DeferredType` parameters with a fallback type - : !!(getCheckFlags(parameter) & CheckFlags.DeferredType) - ) { + : !!(ts.getCheckFlags(parameter) & ts.CheckFlags.DeferredType)) { const contextualParameterType = getRestTypeAtPosition(context, len); assignParameterType(parameter, contextualParameterType); } } } - function assignNonContextualParameterTypes(signature: Signature) { + function assignNonContextualParameterTypes(signature: ts.Signature) { if (signature.thisParameter) { assignParameterType(signature.thisParameter); } @@ -32404,12 +31683,12 @@ namespace ts { } } - function assignParameterType(parameter: Symbol, type?: Type) { + function assignParameterType(parameter: ts.Symbol, type?: ts.Type) { const links = getSymbolLinks(parameter); if (!links.type) { - const declaration = parameter.valueDeclaration as ParameterDeclaration | undefined; + const declaration = parameter.valueDeclaration as ts.ParameterDeclaration | undefined; links.type = type || (declaration ? getWidenedTypeForVariableLikeDeclaration(declaration, /*reportErrors*/ true) : getTypeOfSymbol(parameter)); - if (declaration && declaration.name.kind !== SyntaxKind.Identifier) { + if (declaration && declaration.name.kind !== ts.SyntaxKind.Identifier) { // if inference didn't come up with anything but unknown, fall back to the binding pattern if present. if (links.type === unknownType) { links.type = getTypeFromBindingPattern(declaration.name); @@ -32418,17 +31697,17 @@ namespace ts { } } else if (type) { - Debug.assertEqual(links.type, type, "Parameter symbol already has a cached type which differs from newly assigned type"); + ts.Debug.assertEqual(links.type, type, "Parameter symbol already has a cached type which differs from newly assigned type"); } } // When contextual typing assigns a type to a parameter that contains a binding pattern, we also need to push // the destructured type into the contained binding elements. - function assignBindingElementTypes(pattern: BindingPattern, parentType: Type) { + function assignBindingElementTypes(pattern: ts.BindingPattern, parentType: ts.Type) { for (const element of pattern.elements) { - if (!isOmittedExpression(element)) { + if (!ts.isOmittedExpression(element)) { const type = getBindingElementTypeFromParentType(element, parentType); - if (element.name.kind === SyntaxKind.Identifier) { + if (element.name.kind === ts.SyntaxKind.Identifier) { getSymbolLinks(getSymbolOfNode(element)).type = type; } else { @@ -32438,7 +31717,7 @@ namespace ts { } } - function createPromiseType(promisedType: Type): Type { + function createPromiseType(promisedType: ts.Type): ts.Type { // creates a `Promise` type where `T` is the promisedType argument const globalPromiseType = getGlobalPromiseType(/*reportErrors*/ true); if (globalPromiseType !== emptyGenericType) { @@ -32451,7 +31730,7 @@ namespace ts { return unknownType; } - function createPromiseLikeType(promisedType: Type): Type { + function createPromiseLikeType(promisedType: ts.Type): ts.Type { // creates a `PromiseLike` type where `T` is the promisedType argument const globalPromiseLikeType = getGlobalPromiseLikeType(/*reportErrors*/ true); if (globalPromiseLikeType !== emptyGenericType) { @@ -32464,57 +31743,55 @@ namespace ts { return unknownType; } - function createPromiseReturnType(func: FunctionLikeDeclaration | ImportCall, promisedType: Type) { + function createPromiseReturnType(func: ts.FunctionLikeDeclaration | ts.ImportCall, promisedType: ts.Type) { const promiseType = createPromiseType(promisedType); if (promiseType === unknownType) { - error(func, isImportCall(func) ? - Diagnostics.A_dynamic_import_call_returns_a_Promise_Make_sure_you_have_a_declaration_for_Promise_or_include_ES2015_in_your_lib_option : - Diagnostics.An_async_function_or_method_must_return_a_Promise_Make_sure_you_have_a_declaration_for_Promise_or_include_ES2015_in_your_lib_option); + error(func, ts.isImportCall(func) ? + ts.Diagnostics.A_dynamic_import_call_returns_a_Promise_Make_sure_you_have_a_declaration_for_Promise_or_include_ES2015_in_your_lib_option : + ts.Diagnostics.An_async_function_or_method_must_return_a_Promise_Make_sure_you_have_a_declaration_for_Promise_or_include_ES2015_in_your_lib_option); return errorType; } else if (!getGlobalPromiseConstructorSymbol(/*reportErrors*/ true)) { - error(func, isImportCall(func) ? - Diagnostics.A_dynamic_import_call_in_ES5_SlashES3_requires_the_Promise_constructor_Make_sure_you_have_a_declaration_for_the_Promise_constructor_or_include_ES2015_in_your_lib_option : - Diagnostics.An_async_function_or_method_in_ES5_SlashES3_requires_the_Promise_constructor_Make_sure_you_have_a_declaration_for_the_Promise_constructor_or_include_ES2015_in_your_lib_option); + error(func, ts.isImportCall(func) ? + ts.Diagnostics.A_dynamic_import_call_in_ES5_SlashES3_requires_the_Promise_constructor_Make_sure_you_have_a_declaration_for_the_Promise_constructor_or_include_ES2015_in_your_lib_option : + ts.Diagnostics.An_async_function_or_method_in_ES5_SlashES3_requires_the_Promise_constructor_Make_sure_you_have_a_declaration_for_the_Promise_constructor_or_include_ES2015_in_your_lib_option); } return promiseType; } - function createNewTargetExpressionType(targetType: Type): Type { + function createNewTargetExpressionType(targetType: ts.Type): ts.Type { // Create a synthetic type `NewTargetExpression { target: TargetType; }` - const symbol = createSymbol(SymbolFlags.None, "NewTargetExpression" as __String); - - const targetPropertySymbol = createSymbol(SymbolFlags.Property, "target" as __String, CheckFlags.Readonly); + const symbol = createSymbol(ts.SymbolFlags.None, "NewTargetExpression" as ts.__String); + const targetPropertySymbol = createSymbol(ts.SymbolFlags.Property, "target" as ts.__String, ts.CheckFlags.Readonly); targetPropertySymbol.parent = symbol; targetPropertySymbol.type = targetType; - const members = createSymbolTable([targetPropertySymbol]); + const members = ts.createSymbolTable([targetPropertySymbol]); symbol.members = members; - return createAnonymousType(symbol, members, emptyArray, emptyArray, emptyArray); + return createAnonymousType(symbol, members, ts.emptyArray, ts.emptyArray, ts.emptyArray); } - function getReturnTypeFromBody(func: FunctionLikeDeclaration, checkMode?: CheckMode): Type { + function getReturnTypeFromBody(func: ts.FunctionLikeDeclaration, checkMode?: CheckMode): ts.Type { if (!func.body) { return errorType; } - const functionFlags = getFunctionFlags(func); - const isAsync = (functionFlags & FunctionFlags.Async) !== 0; - const isGenerator = (functionFlags & FunctionFlags.Generator) !== 0; - - let returnType: Type | undefined; - let yieldType: Type | undefined; - let nextType: Type | undefined; - let fallbackReturnType: Type = voidType; - if (func.body.kind !== SyntaxKind.Block) { // Async or normal arrow function + const functionFlags = ts.getFunctionFlags(func); + const isAsync = (functionFlags & ts.FunctionFlags.Async) !== 0; + const isGenerator = (functionFlags & ts.FunctionFlags.Generator) !== 0; + let returnType: ts.Type | undefined; + let yieldType: ts.Type | undefined; + let nextType: ts.Type | undefined; + let fallbackReturnType: ts.Type = voidType; + if (func.body.kind !== ts.SyntaxKind.Block) { // Async or normal arrow function returnType = checkExpressionCached(func.body, checkMode && checkMode & ~CheckMode.SkipGenericFunctions); if (isAsync) { // From within an async function you can return either a non-promise value or a promise. Any // Promise/A+ compatible implementation will always assimilate any foreign promise, so the // return type of the body should be unwrapped to its awaited type, which we will wrap in // the native Promise type later in this function. - returnType = unwrapAwaitedType(checkAwaitedType(returnType, /*withAlias*/ false, /*errorNode*/ func, Diagnostics.The_return_type_of_an_async_function_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member)); + returnType = unwrapAwaitedType(checkAwaitedType(returnType, /*withAlias*/ false, /*errorNode*/ func, ts.Diagnostics.The_return_type_of_an_async_function_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member)); } } else if (isGenerator) { // Generator or AsyncGenerator function @@ -32523,35 +31800,38 @@ namespace ts { fallbackReturnType = neverType; } else if (returnTypes.length > 0) { - returnType = getUnionType(returnTypes, UnionReduction.Subtype); + returnType = getUnionType(returnTypes, ts.UnionReduction.Subtype); } const { yieldTypes, nextTypes } = checkAndAggregateYieldOperandTypes(func, checkMode); - yieldType = some(yieldTypes) ? getUnionType(yieldTypes, UnionReduction.Subtype) : undefined; - nextType = some(nextTypes) ? getIntersectionType(nextTypes) : undefined; + yieldType = ts.some(yieldTypes) ? getUnionType(yieldTypes, ts.UnionReduction.Subtype) : undefined; + nextType = ts.some(nextTypes) ? getIntersectionType(nextTypes) : undefined; } else { // Async or normal function const types = checkAndAggregateReturnExpressionTypes(func, checkMode); if (!types) { // For an async function, the return type will not be never, but rather a Promise for never. - return functionFlags & FunctionFlags.Async + return functionFlags & ts.FunctionFlags.Async ? createPromiseReturnType(func, neverType) // Async function : neverType; // Normal function } if (types.length === 0) { // For an async function, the return type will not be void, but rather a Promise for void. - return functionFlags & FunctionFlags.Async + return functionFlags & ts.FunctionFlags.Async ? createPromiseReturnType(func, voidType) // Async function : voidType; // Normal function } // Return a union of the return expression types. - returnType = getUnionType(types, UnionReduction.Subtype); + returnType = getUnionType(types, ts.UnionReduction.Subtype); } if (returnType || yieldType || nextType) { - if (yieldType) reportErrorsFromWidening(func, yieldType, WideningKind.GeneratorYield); - if (returnType) reportErrorsFromWidening(func, returnType, WideningKind.FunctionReturn); - if (nextType) reportErrorsFromWidening(func, nextType, WideningKind.GeneratorNext); + if (yieldType) + reportErrorsFromWidening(func, yieldType, WideningKind.GeneratorYield); + if (returnType) + reportErrorsFromWidening(func, returnType, WideningKind.FunctionReturn); + if (nextType) + reportErrorsFromWidening(func, nextType, WideningKind.GeneratorNext); if (returnType && isUnitType(returnType) || yieldType && isUnitType(yieldType) || nextType && isUnitType(nextType)) { @@ -32569,17 +31849,16 @@ namespace ts { } } - if (yieldType) yieldType = getWidenedType(yieldType); - if (returnType) returnType = getWidenedType(returnType); - if (nextType) nextType = getWidenedType(nextType); + if (yieldType) + yieldType = getWidenedType(yieldType); + if (returnType) + returnType = getWidenedType(returnType); + if (nextType) + nextType = getWidenedType(nextType); } if (isGenerator) { - return createGeneratorReturnType( - yieldType || neverType, - returnType || fallbackReturnType, - nextType || getContextualIterationType(IterationTypeKind.Next, func) || unknownType, - isAsync); + return createGeneratorReturnType(yieldType || neverType, returnType || fallbackReturnType, nextType || getContextualIterationType(IterationTypeKind.Next, func) || unknownType, isAsync); } else { // From within an async function you can return either a non-promise value or a promise. Any @@ -32591,7 +31870,7 @@ namespace ts { } } - function createGeneratorReturnType(yieldType: Type, returnType: Type, nextType: Type, isAsyncGenerator: boolean) { + function createGeneratorReturnType(yieldType: ts.Type, returnType: ts.Type, nextType: ts.Type, isAsyncGenerator: boolean) { const resolver = isAsyncGenerator ? asyncIterationTypesResolver : syncIterationTypesResolver; const globalGeneratorType = resolver.getGlobalGeneratorType(/*reportErrors*/ false); yieldType = resolver.resolveIterationType(yieldType, /*errorNode*/ undefined) || unknownType; @@ -32624,36 +31903,34 @@ namespace ts { return createTypeFromGenericGlobalType(globalGeneratorType, [yieldType, returnType, nextType]); } - function checkAndAggregateYieldOperandTypes(func: FunctionLikeDeclaration, checkMode: CheckMode | undefined) { - const yieldTypes: Type[] = []; - const nextTypes: Type[] = []; - const isAsync = (getFunctionFlags(func) & FunctionFlags.Async) !== 0; - forEachYieldExpression(func.body as Block, yieldExpression => { + function checkAndAggregateYieldOperandTypes(func: ts.FunctionLikeDeclaration, checkMode: CheckMode | undefined) { + const yieldTypes: ts.Type[] = []; + const nextTypes: ts.Type[] = []; + const isAsync = (ts.getFunctionFlags(func) & ts.FunctionFlags.Async) !== 0; + ts.forEachYieldExpression(func.body as ts.Block, yieldExpression => { const yieldExpressionType = yieldExpression.expression ? checkExpression(yieldExpression.expression, checkMode) : undefinedWideningType; - pushIfUnique(yieldTypes, getYieldedTypeOfYieldExpression(yieldExpression, yieldExpressionType, anyType, isAsync)); - let nextType: Type | undefined; + ts.pushIfUnique(yieldTypes, getYieldedTypeOfYieldExpression(yieldExpression, yieldExpressionType, anyType, isAsync)); + let nextType: ts.Type | undefined; if (yieldExpression.asteriskToken) { - const iterationTypes = getIterationTypesOfIterable( - yieldExpressionType, - isAsync ? IterationUse.AsyncYieldStar : IterationUse.YieldStar, - yieldExpression.expression); + const iterationTypes = getIterationTypesOfIterable(yieldExpressionType, isAsync ? IterationUse.AsyncYieldStar : IterationUse.YieldStar, yieldExpression.expression); nextType = iterationTypes && iterationTypes.nextType; } else { nextType = getContextualType(yieldExpression); } - if (nextType) pushIfUnique(nextTypes, nextType); + if (nextType) + ts.pushIfUnique(nextTypes, nextType); }); return { yieldTypes, nextTypes }; } - function getYieldedTypeOfYieldExpression(node: YieldExpression, expressionType: Type, sentType: Type, isAsync: boolean): Type | undefined { + function getYieldedTypeOfYieldExpression(node: ts.YieldExpression, expressionType: ts.Type, sentType: ts.Type, isAsync: boolean): ts.Type | undefined { const errorNode = node.expression || node; // A `yield*` expression effectively yields everything that its operand yields const yieldedType = node.asteriskToken ? checkIteratedTypeOrElementType(isAsync ? IterationUse.AsyncYieldStar : IterationUse.YieldStar, expressionType, sentType, errorNode) : expressionType; return !isAsync ? yieldedType : getAwaitedType(yieldedType, errorNode, node.asteriskToken - ? Diagnostics.Type_of_iterated_elements_of_a_yield_Asterisk_operand_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member - : Diagnostics.Type_of_yield_operand_in_an_async_generator_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member); + ? ts.Diagnostics.Type_of_iterated_elements_of_a_yield_Asterisk_operand_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member + : ts.Diagnostics.Type_of_yield_operand_in_an_async_generator_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member); } /** @@ -32699,60 +31976,60 @@ namespace ts { return facts; } - function isExhaustiveSwitchStatement(node: SwitchStatement): boolean { + function isExhaustiveSwitchStatement(node: ts.SwitchStatement): boolean { const links = getNodeLinks(node); return links.isExhaustive !== undefined ? links.isExhaustive : (links.isExhaustive = computeExhaustiveSwitchStatement(node)); } - function computeExhaustiveSwitchStatement(node: SwitchStatement): boolean { - if (node.expression.kind === SyntaxKind.TypeOfExpression) { - const operandType = getTypeOfExpression((node.expression as TypeOfExpression).expression); + function computeExhaustiveSwitchStatement(node: ts.SwitchStatement): boolean { + if (node.expression.kind === ts.SyntaxKind.TypeOfExpression) { + const operandType = getTypeOfExpression((node.expression as ts.TypeOfExpression).expression); const witnesses = getSwitchClauseTypeOfWitnesses(node, /*retainDefault*/ false); // notEqualFacts states that the type of the switched value is not equal to every type in the switch. const notEqualFacts = getFactsFromTypeofSwitch(0, 0, witnesses, /*hasDefault*/ true); const type = getBaseConstraintOfType(operandType) || operandType; // Take any/unknown as a special condition. Or maybe we could change `type` to a union containing all primitive types. - if (type.flags & TypeFlags.AnyOrUnknown) { + if (type.flags & ts.TypeFlags.AnyOrUnknown) { return (TypeFacts.AllTypeofNE & notEqualFacts) === TypeFacts.AllTypeofNE; } - return !!(filterType(type, t => (getTypeFacts(t) & notEqualFacts) === notEqualFacts).flags & TypeFlags.Never); + return !!(filterType(type, t => (getTypeFacts(t) & notEqualFacts) === notEqualFacts).flags & ts.TypeFlags.Never); } const type = getTypeOfExpression(node.expression); if (!isLiteralType(type)) { return false; } const switchTypes = getSwitchClauseTypes(node); - if (!switchTypes.length || some(switchTypes, isNeitherUnitTypeNorNever)) { + if (!switchTypes.length || ts.some(switchTypes, isNeitherUnitTypeNorNever)) { return false; } return eachTypeContainedIn(mapType(type, getRegularTypeOfLiteralType), switchTypes); } - function functionHasImplicitReturn(func: FunctionLikeDeclaration) { + function functionHasImplicitReturn(func: ts.FunctionLikeDeclaration) { return func.endFlowNode && isReachableFlowNode(func.endFlowNode); } /** NOTE: Return value of `[]` means a different thing than `undefined`. `[]` means func returns `void`, `undefined` means it returns `never`. */ - function checkAndAggregateReturnExpressionTypes(func: FunctionLikeDeclaration, checkMode: CheckMode | undefined): Type[] | undefined { - const functionFlags = getFunctionFlags(func); - const aggregatedTypes: Type[] = []; + function checkAndAggregateReturnExpressionTypes(func: ts.FunctionLikeDeclaration, checkMode: CheckMode | undefined): ts.Type[] | undefined { + const functionFlags = ts.getFunctionFlags(func); + const aggregatedTypes: ts.Type[] = []; let hasReturnWithNoExpression = functionHasImplicitReturn(func); let hasReturnOfTypeNever = false; - forEachReturnStatement(func.body as Block, returnStatement => { + ts.forEachReturnStatement(func.body as ts.Block, returnStatement => { const expr = returnStatement.expression; if (expr) { let type = checkExpressionCached(expr, checkMode && checkMode & ~CheckMode.SkipGenericFunctions); - if (functionFlags & FunctionFlags.Async) { + if (functionFlags & ts.FunctionFlags.Async) { // From within an async function you can return either a non-promise value or a promise. Any // Promise/A+ compatible implementation will always assimilate any foreign promise, so the // return type of the body should be unwrapped to its awaited type, which should be wrapped in // the native Promise type by the caller. - type = unwrapAwaitedType(checkAwaitedType(type, /*withAlias*/ false, func, Diagnostics.The_return_type_of_an_async_function_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member)); + type = unwrapAwaitedType(checkAwaitedType(type, /*withAlias*/ false, func, ts.Diagnostics.The_return_type_of_an_async_function_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member)); } - if (type.flags & TypeFlags.Never) { + if (type.flags & ts.TypeFlags.Never) { hasReturnOfTypeNever = true; } - pushIfUnique(aggregatedTypes, type); + ts.pushIfUnique(aggregatedTypes, type); } else { hasReturnWithNoExpression = true; @@ -32764,17 +32041,17 @@ namespace ts { if (strictNullChecks && aggregatedTypes.length && hasReturnWithNoExpression && !(isJSConstructor(func) && aggregatedTypes.some(t => t.symbol === func.symbol))) { // Javascript "callable constructors", containing eg `if (!(this instanceof A)) return new A()` should not add undefined - pushIfUnique(aggregatedTypes, undefinedType); + ts.pushIfUnique(aggregatedTypes, undefinedType); } return aggregatedTypes; } - function mayReturnNever(func: FunctionLikeDeclaration): boolean { + function mayReturnNever(func: ts.FunctionLikeDeclaration): boolean { switch (func.kind) { - case SyntaxKind.FunctionExpression: - case SyntaxKind.ArrowFunction: + case ts.SyntaxKind.FunctionExpression: + case ts.SyntaxKind.ArrowFunction: return true; - case SyntaxKind.MethodDeclaration: - return func.parent.kind === SyntaxKind.ObjectLiteralExpression; + case ts.SyntaxKind.MethodDeclaration: + return func.parent.kind === ts.SyntaxKind.ObjectLiteralExpression; default: return false; } @@ -32789,38 +32066,37 @@ namespace ts { * * @param returnType - return type of the function, can be undefined if return type is not explicitly specified */ - function checkAllCodePathsInNonVoidFunctionReturnOrThrow(func: FunctionLikeDeclaration | MethodSignature, returnType: Type | undefined) { + function checkAllCodePathsInNonVoidFunctionReturnOrThrow(func: ts.FunctionLikeDeclaration | ts.MethodSignature, returnType: ts.Type | undefined) { addLazyDiagnostic(checkAllCodePathsInNonVoidFunctionReturnOrThrowDiagnostics); return; function checkAllCodePathsInNonVoidFunctionReturnOrThrowDiagnostics(): void { - const functionFlags = getFunctionFlags(func); + const functionFlags = ts.getFunctionFlags(func); const type = returnType && unwrapReturnType(returnType, functionFlags); // Functions with with an explicitly specified 'void' or 'any' return type don't need any return expressions. - if (type && maybeTypeOfKind(type, TypeFlags.Any | TypeFlags.Void)) { + if (type && maybeTypeOfKind(type, ts.TypeFlags.Any | ts.TypeFlags.Void)) { return; } // If all we have is a function signature, or an arrow function with an expression body, then there is nothing to check. // also if HasImplicitReturn flag is not set this means that all codepaths in function body end with return or throw - if (func.kind === SyntaxKind.MethodSignature || nodeIsMissing(func.body) || func.body!.kind !== SyntaxKind.Block || !functionHasImplicitReturn(func)) { + if (func.kind === ts.SyntaxKind.MethodSignature || ts.nodeIsMissing(func.body) || func.body!.kind !== ts.SyntaxKind.Block || !functionHasImplicitReturn(func)) { return; } - const hasExplicitReturn = func.flags & NodeFlags.HasExplicitReturn; - const errorNode = getEffectiveReturnTypeNode(func) || func; - - if (type && type.flags & TypeFlags.Never) { - error(errorNode, Diagnostics.A_function_returning_never_cannot_have_a_reachable_end_point); + const hasExplicitReturn = func.flags & ts.NodeFlags.HasExplicitReturn; + const errorNode = ts.getEffectiveReturnTypeNode(func) || func; + if (type && type.flags & ts.TypeFlags.Never) { + error(errorNode, ts.Diagnostics.A_function_returning_never_cannot_have_a_reachable_end_point); } else if (type && !hasExplicitReturn) { // minimal check: function has syntactic return type annotation and no explicit return statements in the body // this function does not conform to the specification. - error(errorNode, Diagnostics.A_function_whose_declared_type_is_neither_void_nor_any_must_return_a_value); + error(errorNode, ts.Diagnostics.A_function_whose_declared_type_is_neither_void_nor_any_must_return_a_value); } else if (type && strictNullChecks && !isTypeAssignableTo(undefinedType, type)) { - error(errorNode, Diagnostics.Function_lacks_ending_return_statement_and_return_type_does_not_include_undefined); + error(errorNode, ts.Diagnostics.Function_lacks_ending_return_statement_and_return_type_does_not_include_undefined); } else if (compilerOptions.noImplicitReturns) { if (!type) { @@ -32835,23 +32111,23 @@ namespace ts { return; } } - error(errorNode, Diagnostics.Not_all_code_paths_return_a_value); + error(errorNode, ts.Diagnostics.Not_all_code_paths_return_a_value); } } } - function checkFunctionExpressionOrObjectLiteralMethod(node: FunctionExpression | ArrowFunction | MethodDeclaration, checkMode?: CheckMode): Type { - Debug.assert(node.kind !== SyntaxKind.MethodDeclaration || isObjectLiteralMethod(node)); + function checkFunctionExpressionOrObjectLiteralMethod(node: ts.FunctionExpression | ts.ArrowFunction | ts.MethodDeclaration, checkMode?: CheckMode): ts.Type { + ts.Debug.assert(node.kind !== ts.SyntaxKind.MethodDeclaration || ts.isObjectLiteralMethod(node)); checkNodeDeferred(node); - if (isFunctionExpression(node)) { + if (ts.isFunctionExpression(node)) { checkCollisionsForDeclarationName(node, node.name); } // The identityMapper object is used to indicate that function expressions are wildcards if (checkMode && checkMode & CheckMode.SkipContextSensitive && isContextSensitive(node)) { // Skip parameters, return signature with return type that retains noncontextual parts so inferences can still be drawn in an early stage - if (!getEffectiveReturnTypeNode(node) && !hasContextSensitiveParameters(node)) { + if (!ts.getEffectiveReturnTypeNode(node) && !ts.hasContextSensitiveParameters(node)) { // Return plain anyFunctionType if there is no possibility we'll make inferences from the return type const contextualSignature = getContextualSignature(node); if (contextualSignature && couldContainTypeVariables(getReturnTypeOfSignature(contextualSignature))) { @@ -32860,9 +32136,9 @@ namespace ts { return links.contextFreeType; } const returnType = getReturnTypeFromBody(node, checkMode); - const returnOnlySignature = createSignature(undefined, undefined, undefined, emptyArray, returnType, /*resolvedTypePredicate*/ undefined, 0, SignatureFlags.None); - const returnOnlyType = createAnonymousType(node.symbol, emptySymbols, [returnOnlySignature], emptyArray, emptyArray); - returnOnlyType.objectFlags |= ObjectFlags.NonInferrableType; + const returnOnlySignature = createSignature(undefined, undefined, undefined, ts.emptyArray, returnType, /*resolvedTypePredicate*/ undefined, 0, ts.SignatureFlags.None); + const returnOnlyType = createAnonymousType(node.symbol, emptySymbols, [returnOnlySignature], ts.emptyArray, ts.emptyArray); + returnOnlyType.objectFlags |= ts.ObjectFlags.NonInferrableType; return links.contextFreeType = returnOnlyType; } } @@ -32871,7 +32147,7 @@ namespace ts { // Grammar checking const hasGrammarError = checkGrammarFunctionLikeDeclaration(node); - if (!hasGrammarError && node.kind === SyntaxKind.FunctionExpression) { + if (!hasGrammarError && node.kind === ts.SyntaxKind.FunctionExpression) { checkGrammarForGenerator(node); } @@ -32880,17 +32156,17 @@ namespace ts { return getTypeOfSymbol(getSymbolOfNode(node)); } - function contextuallyCheckFunctionExpressionOrObjectLiteralMethod(node: FunctionExpression | ArrowFunction | MethodDeclaration, checkMode?: CheckMode) { + function contextuallyCheckFunctionExpressionOrObjectLiteralMethod(node: ts.FunctionExpression | ts.ArrowFunction | ts.MethodDeclaration, checkMode?: CheckMode) { const links = getNodeLinks(node); // Check if function expression is contextually typed and assign parameter types if so. - if (!(links.flags & NodeCheckFlags.ContextChecked)) { + if (!(links.flags & ts.NodeCheckFlags.ContextChecked)) { const contextualSignature = getContextualSignature(node); // If a type check is started at a function expression that is an argument of a function call, obtaining the // contextual type may recursively get back to here during overload resolution of the call. If so, we will have // already assigned contextual types. - if (!(links.flags & NodeCheckFlags.ContextChecked)) { - links.flags |= NodeCheckFlags.ContextChecked; - const signature = firstOrUndefined(getSignaturesOfType(getTypeOfSymbol(getSymbolOfNode(node)), SignatureKind.Call)); + if (!(links.flags & ts.NodeCheckFlags.ContextChecked)) { + links.flags |= ts.NodeCheckFlags.ContextChecked; + const signature = ts.firstOrUndefined(getSignaturesOfType(getTypeOfSymbol(getSymbolOfNode(node)), ts.SignatureKind.Call)); if (!signature) { return; } @@ -32920,15 +32196,14 @@ namespace ts { } } - function checkFunctionExpressionOrObjectLiteralMethodDeferred(node: ArrowFunction | FunctionExpression | MethodDeclaration) { - Debug.assert(node.kind !== SyntaxKind.MethodDeclaration || isObjectLiteralMethod(node)); - - const functionFlags = getFunctionFlags(node); + function checkFunctionExpressionOrObjectLiteralMethodDeferred(node: ts.ArrowFunction | ts.FunctionExpression | ts.MethodDeclaration) { + ts.Debug.assert(node.kind !== ts.SyntaxKind.MethodDeclaration || ts.isObjectLiteralMethod(node)); + const functionFlags = ts.getFunctionFlags(node); const returnType = getReturnTypeFromAnnotation(node); checkAllCodePathsInNonVoidFunctionReturnOrThrow(node, returnType); if (node.body) { - if (!getEffectiveReturnTypeNode(node)) { + if (!ts.getEffectiveReturnTypeNode(node)) { // There are some checks that are only performed in getReturnTypeFromBody, that may produce errors // we need. An example is the noImplicitAny errors resulting from widening the return expression // of a function. Because checking of function expression bodies is deferred, there was never an @@ -32937,7 +32212,7 @@ namespace ts { getReturnTypeOfSignature(getSignatureFromDeclaration(node)); } - if (node.body.kind === SyntaxKind.Block) { + if (node.body.kind === ts.SyntaxKind.Block) { checkSourceElement(node.body); } else { @@ -32949,8 +32224,8 @@ namespace ts { const exprType = checkExpression(node.body); const returnOrPromisedType = returnType && unwrapReturnType(returnType, functionFlags); if (returnOrPromisedType) { - if ((functionFlags & FunctionFlags.AsyncGenerator) === FunctionFlags.Async) { // Async function - const awaitedType = checkAwaitedType(exprType, /*withAlias*/ false, node.body, Diagnostics.The_return_type_of_an_async_function_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member); + if ((functionFlags & ts.FunctionFlags.AsyncGenerator) === ts.FunctionFlags.Async) { // Async function + const awaitedType = checkAwaitedType(exprType, /*withAlias*/ false, node.body, ts.Diagnostics.The_return_type_of_an_async_function_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member); checkTypeAssignableToAndOptionallyElaborate(awaitedType, returnOrPromisedType, node.body, node.body); } else { // Normal function @@ -32961,29 +32236,26 @@ namespace ts { } } - function checkArithmeticOperandType(operand: Node, type: Type, diagnostic: DiagnosticMessage, isAwaitValid = false): boolean { + function checkArithmeticOperandType(operand: ts.Node, type: ts.Type, diagnostic: ts.DiagnosticMessage, isAwaitValid = false): boolean { if (!isTypeAssignableTo(type, numberOrBigIntType)) { const awaitedType = isAwaitValid && getAwaitedTypeOfPromise(type); - errorAndMaybeSuggestAwait( - operand, - !!awaitedType && isTypeAssignableTo(awaitedType, numberOrBigIntType), - diagnostic); + errorAndMaybeSuggestAwait(operand, !!awaitedType && isTypeAssignableTo(awaitedType, numberOrBigIntType), diagnostic); return false; } return true; } - function isReadonlyAssignmentDeclaration(d: Declaration) { - if (!isCallExpression(d)) { + function isReadonlyAssignmentDeclaration(d: ts.Declaration) { + if (!ts.isCallExpression(d)) { return false; } - if (!isBindableObjectDefinePropertyCall(d)) { + if (!ts.isBindableObjectDefinePropertyCall(d)) { return false; } const objectLitType = checkExpressionCached(d.arguments[2]); - const valueType = getTypeOfPropertyOfType(objectLitType, "value" as __String); + const valueType = getTypeOfPropertyOfType(objectLitType, "value" as ts.__String); if (valueType) { - const writableProp = getPropertyOfType(objectLitType, "writable" as __String); + const writableProp = getPropertyOfType(objectLitType, "writable" as ts.__String); const writableType = writableProp && getTypeOfSymbol(writableProp); if (!writableType || writableType === falseType || writableType === regularFalseType) { return true; @@ -32991,7 +32263,7 @@ namespace ts { // We include this definition whereupon we walk back and check the type at the declaration because // The usual definition of `Object.defineProperty` will _not_ cause literal types to be preserved in the // argument types, should the type be contextualized by the call itself. - if (writableProp && writableProp.valueDeclaration && isPropertyAssignment(writableProp.valueDeclaration)) { + if (writableProp && writableProp.valueDeclaration && ts.isPropertyAssignment(writableProp.valueDeclaration)) { const initializer = writableProp.valueDeclaration.initializer; const rawOriginalType = checkExpression(initializer); if (rawOriginalType === falseType || rawOriginalType === regularFalseType) { @@ -33000,11 +32272,11 @@ namespace ts { } return false; } - const setProp = getPropertyOfType(objectLitType, "set" as __String); + const setProp = getPropertyOfType(objectLitType, "set" as ts.__String); return !setProp; } - function isReadonlySymbol(symbol: Symbol): boolean { + function isReadonlySymbol(symbol: ts.Symbol): boolean { // The following symbols are considered read-only: // Properties with a 'readonly' modifier // Variables declared with 'const' @@ -33012,38 +32284,35 @@ namespace ts { // Enum members // Object.defineProperty assignments with writable false or no setter // Unions and intersections of the above (unions and intersections eagerly set isReadonly on creation) - return !!(getCheckFlags(symbol) & CheckFlags.Readonly || - symbol.flags & SymbolFlags.Property && getDeclarationModifierFlagsFromSymbol(symbol) & ModifierFlags.Readonly || - symbol.flags & SymbolFlags.Variable && getDeclarationNodeFlagsFromSymbol(symbol) & NodeFlags.Const || - symbol.flags & SymbolFlags.Accessor && !(symbol.flags & SymbolFlags.SetAccessor) || - symbol.flags & SymbolFlags.EnumMember || - some(symbol.declarations, isReadonlyAssignmentDeclaration) - ); - } - - function isAssignmentToReadonlyEntity(expr: Expression, symbol: Symbol, assignmentKind: AssignmentKind) { - if (assignmentKind === AssignmentKind.None) { + return !!(ts.getCheckFlags(symbol) & ts.CheckFlags.Readonly || + symbol.flags & ts.SymbolFlags.Property && ts.getDeclarationModifierFlagsFromSymbol(symbol) & ts.ModifierFlags.Readonly || + symbol.flags & ts.SymbolFlags.Variable && getDeclarationNodeFlagsFromSymbol(symbol) & ts.NodeFlags.Const || + symbol.flags & ts.SymbolFlags.Accessor && !(symbol.flags & ts.SymbolFlags.SetAccessor) || + symbol.flags & ts.SymbolFlags.EnumMember || + ts.some(symbol.declarations, isReadonlyAssignmentDeclaration)); + } + function isAssignmentToReadonlyEntity(expr: ts.Expression, symbol: ts.Symbol, assignmentKind: ts.AssignmentKind) { + if (assignmentKind === ts.AssignmentKind.None) { // no assigment means it doesn't matter whether the entity is readonly return false; } if (isReadonlySymbol(symbol)) { // Allow assignments to readonly properties within constructors of the same class declaration. - if (symbol.flags & SymbolFlags.Property && - isAccessExpression(expr) && - expr.expression.kind === SyntaxKind.ThisKeyword) { + if (symbol.flags & ts.SymbolFlags.Property && + ts.isAccessExpression(expr) && + expr.expression.kind === ts.SyntaxKind.ThisKeyword) { // Look for if this is the constructor for the class that `symbol` is a property of. - const ctor = getContainingFunction(expr); - if (!(ctor && (ctor.kind === SyntaxKind.Constructor || isJSConstructor(ctor)))) { + const ctor = ts.getContainingFunction(expr); + if (!(ctor && (ctor.kind === ts.SyntaxKind.Constructor || isJSConstructor(ctor)))) { return true; } if (symbol.valueDeclaration) { - const isAssignmentDeclaration = isBinaryExpression(symbol.valueDeclaration); + const isAssignmentDeclaration = ts.isBinaryExpression(symbol.valueDeclaration); const isLocalPropertyDeclaration = ctor.parent === symbol.valueDeclaration.parent; const isLocalParameterProperty = ctor === symbol.valueDeclaration.parent; const isLocalThisPropertyAssignment = isAssignmentDeclaration && symbol.parent?.valueDeclaration === ctor.parent; const isLocalThisPropertyAssignmentConstructorFunction = isAssignmentDeclaration && symbol.parent?.valueDeclaration === ctor; - const isWriteableSymbol = - isLocalPropertyDeclaration + const isWriteableSymbol = isLocalPropertyDeclaration || isLocalParameterProperty || isLocalThisPropertyAssignment || isLocalThisPropertyAssignmentConstructorFunction; @@ -33052,129 +32321,122 @@ namespace ts { } return true; } - if (isAccessExpression(expr)) { + if (ts.isAccessExpression(expr)) { // references through namespace import should be readonly - const node = skipParentheses(expr.expression); - if (node.kind === SyntaxKind.Identifier) { + const node = ts.skipParentheses(expr.expression); + if (node.kind === ts.SyntaxKind.Identifier) { const symbol = getNodeLinks(node).resolvedSymbol!; - if (symbol.flags & SymbolFlags.Alias) { + if (symbol.flags & ts.SymbolFlags.Alias) { const declaration = getDeclarationOfAliasSymbol(symbol); - return !!declaration && declaration.kind === SyntaxKind.NamespaceImport; + return !!declaration && declaration.kind === ts.SyntaxKind.NamespaceImport; } } } return false; } - function checkReferenceExpression(expr: Expression, invalidReferenceMessage: DiagnosticMessage, invalidOptionalChainMessage: DiagnosticMessage): boolean { + function checkReferenceExpression(expr: ts.Expression, invalidReferenceMessage: ts.DiagnosticMessage, invalidOptionalChainMessage: ts.DiagnosticMessage): boolean { // References are combinations of identifiers, parentheses, and property accesses. - const node = skipOuterExpressions(expr, OuterExpressionKinds.Assertions | OuterExpressionKinds.Parentheses); - if (node.kind !== SyntaxKind.Identifier && !isAccessExpression(node)) { + const node = ts.skipOuterExpressions(expr, ts.OuterExpressionKinds.Assertions | ts.OuterExpressionKinds.Parentheses); + if (node.kind !== ts.SyntaxKind.Identifier && !ts.isAccessExpression(node)) { error(expr, invalidReferenceMessage); return false; } - if (node.flags & NodeFlags.OptionalChain) { + if (node.flags & ts.NodeFlags.OptionalChain) { error(expr, invalidOptionalChainMessage); return false; } return true; } - function checkDeleteExpression(node: DeleteExpression): Type { + function checkDeleteExpression(node: ts.DeleteExpression): ts.Type { checkExpression(node.expression); - const expr = skipParentheses(node.expression); - if (!isAccessExpression(expr)) { - error(expr, Diagnostics.The_operand_of_a_delete_operator_must_be_a_property_reference); + const expr = ts.skipParentheses(node.expression); + if (!ts.isAccessExpression(expr)) { + error(expr, ts.Diagnostics.The_operand_of_a_delete_operator_must_be_a_property_reference); return booleanType; } - if (isPropertyAccessExpression(expr) && isPrivateIdentifier(expr.name)) { - error(expr, Diagnostics.The_operand_of_a_delete_operator_cannot_be_a_private_identifier); + if (ts.isPropertyAccessExpression(expr) && ts.isPrivateIdentifier(expr.name)) { + error(expr, ts.Diagnostics.The_operand_of_a_delete_operator_cannot_be_a_private_identifier); } const links = getNodeLinks(expr); const symbol = getExportSymbolOfValueSymbolIfExported(links.resolvedSymbol); if (symbol) { if (isReadonlySymbol(symbol)) { - error(expr, Diagnostics.The_operand_of_a_delete_operator_cannot_be_a_read_only_property); + error(expr, ts.Diagnostics.The_operand_of_a_delete_operator_cannot_be_a_read_only_property); } checkDeleteExpressionMustBeOptional(expr, symbol); } return booleanType; } - function checkDeleteExpressionMustBeOptional(expr: AccessExpression, symbol: Symbol) { + function checkDeleteExpressionMustBeOptional(expr: ts.AccessExpression, symbol: ts.Symbol) { const type = getTypeOfSymbol(symbol); if (strictNullChecks && - !(type.flags & (TypeFlags.AnyOrUnknown | TypeFlags.Never)) && - !(exactOptionalPropertyTypes ? symbol.flags & SymbolFlags.Optional : getFalsyFlags(type) & TypeFlags.Undefined)) { - error(expr, Diagnostics.The_operand_of_a_delete_operator_must_be_optional); + !(type.flags & (ts.TypeFlags.AnyOrUnknown | ts.TypeFlags.Never)) && + !(exactOptionalPropertyTypes ? symbol.flags & ts.SymbolFlags.Optional : getFalsyFlags(type) & ts.TypeFlags.Undefined)) { + error(expr, ts.Diagnostics.The_operand_of_a_delete_operator_must_be_optional); } } - function checkTypeOfExpression(node: TypeOfExpression): Type { + function checkTypeOfExpression(node: ts.TypeOfExpression): ts.Type { checkExpression(node.expression); return typeofType; } - function checkVoidExpression(node: VoidExpression): Type { + function checkVoidExpression(node: ts.VoidExpression): ts.Type { checkExpression(node.expression); return undefinedWideningType; } - function checkAwaitExpressionGrammar(node: AwaitExpression): void { + function checkAwaitExpressionGrammar(node: ts.AwaitExpression): void { // Grammar checking - const container = getContainingFunctionOrClassStaticBlock(node); - if (container && isClassStaticBlockDeclaration(container)) { - error(node, Diagnostics.Await_expression_cannot_be_used_inside_a_class_static_block); + const container = ts.getContainingFunctionOrClassStaticBlock(node); + if (container && ts.isClassStaticBlockDeclaration(container)) { + error(node, ts.Diagnostics.Await_expression_cannot_be_used_inside_a_class_static_block); } - else if (!(node.flags & NodeFlags.AwaitContext)) { - if (isInTopLevelContext(node)) { - const sourceFile = getSourceFileOfNode(node); + else if (!(node.flags & ts.NodeFlags.AwaitContext)) { + if (ts.isInTopLevelContext(node)) { + const sourceFile = ts.getSourceFileOfNode(node); if (!hasParseDiagnostics(sourceFile)) { - let span: TextSpan | undefined; - if (!isEffectiveExternalModule(sourceFile, compilerOptions)) { - span ??= getSpanOfTokenAtPosition(sourceFile, node.pos); - const diagnostic = createFileDiagnostic(sourceFile, span.start, span.length, - Diagnostics.await_expressions_are_only_allowed_at_the_top_level_of_a_file_when_that_file_is_a_module_but_this_file_has_no_imports_or_exports_Consider_adding_an_empty_export_to_make_this_file_a_module); + let span: ts.TextSpan | undefined; + if (!ts.isEffectiveExternalModule(sourceFile, compilerOptions)) { + span ??= ts.getSpanOfTokenAtPosition(sourceFile, node.pos); + const diagnostic = ts.createFileDiagnostic(sourceFile, span.start, span.length, ts.Diagnostics.await_expressions_are_only_allowed_at_the_top_level_of_a_file_when_that_file_is_a_module_but_this_file_has_no_imports_or_exports_Consider_adding_an_empty_export_to_make_this_file_a_module); diagnostics.add(diagnostic); } switch (moduleKind) { - case ModuleKind.Node16: - case ModuleKind.NodeNext: - if (sourceFile.impliedNodeFormat === ModuleKind.CommonJS) { - span ??= getSpanOfTokenAtPosition(sourceFile, node.pos); - diagnostics.add( - createFileDiagnostic(sourceFile, span.start, span.length, Diagnostics.The_current_file_is_a_CommonJS_module_and_cannot_use_await_at_the_top_level) - ); + case ts.ModuleKind.Node16: + case ts.ModuleKind.NodeNext: + if (sourceFile.impliedNodeFormat === ts.ModuleKind.CommonJS) { + span ??= ts.getSpanOfTokenAtPosition(sourceFile, node.pos); + diagnostics.add(ts.createFileDiagnostic(sourceFile, span.start, span.length, ts.Diagnostics.The_current_file_is_a_CommonJS_module_and_cannot_use_await_at_the_top_level)); break; } // fallthrough - case ModuleKind.ES2022: - case ModuleKind.ESNext: - case ModuleKind.System: - if (languageVersion >= ScriptTarget.ES2017) { + case ts.ModuleKind.ES2022: + case ts.ModuleKind.ESNext: + case ts.ModuleKind.System: + if (languageVersion >= ts.ScriptTarget.ES2017) { break; } // fallthrough default: - span ??= getSpanOfTokenAtPosition(sourceFile, node.pos); - diagnostics.add( - createFileDiagnostic(sourceFile, span.start, span.length, - Diagnostics.Top_level_await_expressions_are_only_allowed_when_the_module_option_is_set_to_es2022_esnext_system_node16_or_nodenext_and_the_target_option_is_set_to_es2017_or_higher - ) - ); + span ??= ts.getSpanOfTokenAtPosition(sourceFile, node.pos); + diagnostics.add(ts.createFileDiagnostic(sourceFile, span.start, span.length, ts.Diagnostics.Top_level_await_expressions_are_only_allowed_when_the_module_option_is_set_to_es2022_esnext_system_node16_or_nodenext_and_the_target_option_is_set_to_es2017_or_higher)); break; } } } else { // use of 'await' in non-async function - const sourceFile = getSourceFileOfNode(node); + const sourceFile = ts.getSourceFileOfNode(node); if (!hasParseDiagnostics(sourceFile)) { - const span = getSpanOfTokenAtPosition(sourceFile, node.pos); - const diagnostic = createFileDiagnostic(sourceFile, span.start, span.length, Diagnostics.await_expressions_are_only_allowed_within_async_functions_and_at_the_top_levels_of_modules); - if (container && container.kind !== SyntaxKind.Constructor && (getFunctionFlags(container) & FunctionFlags.Async) === 0) { - const relatedInfo = createDiagnosticForNode(container, Diagnostics.Did_you_mean_to_mark_this_function_as_async); - addRelatedInfo(diagnostic, relatedInfo); + const span = ts.getSpanOfTokenAtPosition(sourceFile, node.pos); + const diagnostic = ts.createFileDiagnostic(sourceFile, span.start, span.length, ts.Diagnostics.await_expressions_are_only_allowed_within_async_functions_and_at_the_top_levels_of_modules); + if (container && container.kind !== ts.SyntaxKind.Constructor && (ts.getFunctionFlags(container) & ts.FunctionFlags.Async) === 0) { + const relatedInfo = ts.createDiagnosticForNode(container, ts.Diagnostics.Did_you_mean_to_mark_this_function_as_async); + ts.addRelatedInfo(diagnostic, relatedInfo); } diagnostics.add(diagnostic); } @@ -33182,102 +32444,92 @@ namespace ts { } if (isInParameterInitializerBeforeContainingFunction(node)) { - error(node, Diagnostics.await_expressions_cannot_be_used_in_a_parameter_initializer); + error(node, ts.Diagnostics.await_expressions_cannot_be_used_in_a_parameter_initializer); } } - function checkAwaitExpression(node: AwaitExpression): Type { + function checkAwaitExpression(node: ts.AwaitExpression): ts.Type { addLazyDiagnostic(() => checkAwaitExpressionGrammar(node)); const operandType = checkExpression(node.expression); - const awaitedType = checkAwaitedType(operandType, /*withAlias*/ true, node, Diagnostics.Type_of_await_operand_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member); - if (awaitedType === operandType && !isErrorType(awaitedType) && !(operandType.flags & TypeFlags.AnyOrUnknown)) { - addErrorOrSuggestion(/*isError*/ false, createDiagnosticForNode(node, Diagnostics.await_has_no_effect_on_the_type_of_this_expression)); + const awaitedType = checkAwaitedType(operandType, /*withAlias*/ true, node, ts.Diagnostics.Type_of_await_operand_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member); + if (awaitedType === operandType && !isErrorType(awaitedType) && !(operandType.flags & ts.TypeFlags.AnyOrUnknown)) { + addErrorOrSuggestion(/*isError*/ false, ts.createDiagnosticForNode(node, ts.Diagnostics.await_has_no_effect_on_the_type_of_this_expression)); } return awaitedType; } - function checkPrefixUnaryExpression(node: PrefixUnaryExpression): Type { + function checkPrefixUnaryExpression(node: ts.PrefixUnaryExpression): ts.Type { const operandType = checkExpression(node.operand); if (operandType === silentNeverType) { return silentNeverType; } switch (node.operand.kind) { - case SyntaxKind.NumericLiteral: + case ts.SyntaxKind.NumericLiteral: switch (node.operator) { - case SyntaxKind.MinusToken: - return getFreshTypeOfLiteralType(getNumberLiteralType(-(node.operand as NumericLiteral).text)); - case SyntaxKind.PlusToken: - return getFreshTypeOfLiteralType(getNumberLiteralType(+(node.operand as NumericLiteral).text)); + case ts.SyntaxKind.MinusToken: + return getFreshTypeOfLiteralType(getNumberLiteralType(-(node.operand as ts.NumericLiteral).text)); + case ts.SyntaxKind.PlusToken: + return getFreshTypeOfLiteralType(getNumberLiteralType(+(node.operand as ts.NumericLiteral).text)); } break; - case SyntaxKind.BigIntLiteral: - if (node.operator === SyntaxKind.MinusToken) { + case ts.SyntaxKind.BigIntLiteral: + if (node.operator === ts.SyntaxKind.MinusToken) { return getFreshTypeOfLiteralType(getBigIntLiteralType({ negative: true, - base10Value: parsePseudoBigInt((node.operand as BigIntLiteral).text) + base10Value: ts.parsePseudoBigInt((node.operand as ts.BigIntLiteral).text) })); } } switch (node.operator) { - case SyntaxKind.PlusToken: - case SyntaxKind.MinusToken: - case SyntaxKind.TildeToken: + case ts.SyntaxKind.PlusToken: + case ts.SyntaxKind.MinusToken: + case ts.SyntaxKind.TildeToken: checkNonNullType(operandType, node.operand); - if (maybeTypeOfKindConsideringBaseConstraint(operandType, TypeFlags.ESSymbolLike)) { - error(node.operand, Diagnostics.The_0_operator_cannot_be_applied_to_type_symbol, tokenToString(node.operator)); + if (maybeTypeOfKindConsideringBaseConstraint(operandType, ts.TypeFlags.ESSymbolLike)) { + error(node.operand, ts.Diagnostics.The_0_operator_cannot_be_applied_to_type_symbol, ts.tokenToString(node.operator)); } - if (node.operator === SyntaxKind.PlusToken) { - if (maybeTypeOfKind(operandType, TypeFlags.BigIntLike)) { - error(node.operand, Diagnostics.Operator_0_cannot_be_applied_to_type_1, tokenToString(node.operator), typeToString(getBaseTypeOfLiteralType(operandType))); + if (node.operator === ts.SyntaxKind.PlusToken) { + if (maybeTypeOfKind(operandType, ts.TypeFlags.BigIntLike)) { + error(node.operand, ts.Diagnostics.Operator_0_cannot_be_applied_to_type_1, ts.tokenToString(node.operator), typeToString(getBaseTypeOfLiteralType(operandType))); } return numberType; } return getUnaryResultType(operandType); - case SyntaxKind.ExclamationToken: + case ts.SyntaxKind.ExclamationToken: checkTruthinessExpression(node.operand); const facts = getTypeFacts(operandType) & (TypeFacts.Truthy | TypeFacts.Falsy); return facts === TypeFacts.Truthy ? falseType : facts === TypeFacts.Falsy ? trueType : booleanType; - case SyntaxKind.PlusPlusToken: - case SyntaxKind.MinusMinusToken: - const ok = checkArithmeticOperandType(node.operand, checkNonNullType(operandType, node.operand), - Diagnostics.An_arithmetic_operand_must_be_of_type_any_number_bigint_or_an_enum_type); + case ts.SyntaxKind.PlusPlusToken: + case ts.SyntaxKind.MinusMinusToken: + const ok = checkArithmeticOperandType(node.operand, checkNonNullType(operandType, node.operand), ts.Diagnostics.An_arithmetic_operand_must_be_of_type_any_number_bigint_or_an_enum_type); if (ok) { // run check only if former checks succeeded to avoid reporting cascading errors - checkReferenceExpression( - node.operand, - Diagnostics.The_operand_of_an_increment_or_decrement_operator_must_be_a_variable_or_a_property_access, - Diagnostics.The_operand_of_an_increment_or_decrement_operator_may_not_be_an_optional_property_access); + checkReferenceExpression(node.operand, ts.Diagnostics.The_operand_of_an_increment_or_decrement_operator_must_be_a_variable_or_a_property_access, ts.Diagnostics.The_operand_of_an_increment_or_decrement_operator_may_not_be_an_optional_property_access); } return getUnaryResultType(operandType); } return errorType; } - function checkPostfixUnaryExpression(node: PostfixUnaryExpression): Type { + function checkPostfixUnaryExpression(node: ts.PostfixUnaryExpression): ts.Type { const operandType = checkExpression(node.operand); if (operandType === silentNeverType) { return silentNeverType; } - const ok = checkArithmeticOperandType( - node.operand, - checkNonNullType(operandType, node.operand), - Diagnostics.An_arithmetic_operand_must_be_of_type_any_number_bigint_or_an_enum_type); + const ok = checkArithmeticOperandType(node.operand, checkNonNullType(operandType, node.operand), ts.Diagnostics.An_arithmetic_operand_must_be_of_type_any_number_bigint_or_an_enum_type); if (ok) { // run check only if former checks succeeded to avoid reporting cascading errors - checkReferenceExpression( - node.operand, - Diagnostics.The_operand_of_an_increment_or_decrement_operator_must_be_a_variable_or_a_property_access, - Diagnostics.The_operand_of_an_increment_or_decrement_operator_may_not_be_an_optional_property_access); + checkReferenceExpression(node.operand, ts.Diagnostics.The_operand_of_an_increment_or_decrement_operator_must_be_a_variable_or_a_property_access, ts.Diagnostics.The_operand_of_an_increment_or_decrement_operator_may_not_be_an_optional_property_access); } return getUnaryResultType(operandType); } - function getUnaryResultType(operandType: Type): Type { - if (maybeTypeOfKind(operandType, TypeFlags.BigIntLike)) { - return isTypeAssignableToKind(operandType, TypeFlags.AnyOrUnknown) || maybeTypeOfKind(operandType, TypeFlags.NumberLike) + function getUnaryResultType(operandType: ts.Type): ts.Type { + if (maybeTypeOfKind(operandType, ts.TypeFlags.BigIntLike)) { + return isTypeAssignableToKind(operandType, ts.TypeFlags.AnyOrUnknown) || maybeTypeOfKind(operandType, ts.TypeFlags.NumberLike) ? numberOrBigIntType : bigintType; } @@ -33285,7 +32537,7 @@ namespace ts { return numberType; } - function maybeTypeOfKindConsideringBaseConstraint(type: Type, kind: TypeFlags): boolean { + function maybeTypeOfKindConsideringBaseConstraint(type: ts.Type, kind: ts.TypeFlags): boolean { if (maybeTypeOfKind(type, kind)) { return true; } @@ -33296,12 +32548,12 @@ namespace ts { // Return true if type might be of the given kind. A union or intersection type might be of a given // kind if at least one constituent type is of the given kind. - function maybeTypeOfKind(type: Type, kind: TypeFlags): boolean { + function maybeTypeOfKind(type: ts.Type, kind: ts.TypeFlags): boolean { if (type.flags & kind) { return true; } - if (type.flags & TypeFlags.UnionOrIntersection) { - const types = (type as UnionOrIntersectionType).types; + if (type.flags & ts.TypeFlags.UnionOrIntersection) { + const types = (type as ts.UnionOrIntersectionType).types; for (const t of types) { if (maybeTypeOfKind(t, kind)) { return true; @@ -33311,40 +32563,40 @@ namespace ts { return false; } - function isTypeAssignableToKind(source: Type, kind: TypeFlags, strict?: boolean): boolean { + function isTypeAssignableToKind(source: ts.Type, kind: ts.TypeFlags, strict?: boolean): boolean { if (source.flags & kind) { return true; } - if (strict && source.flags & (TypeFlags.AnyOrUnknown | TypeFlags.Void | TypeFlags.Undefined | TypeFlags.Null)) { + if (strict && source.flags & (ts.TypeFlags.AnyOrUnknown | ts.TypeFlags.Void | ts.TypeFlags.Undefined | ts.TypeFlags.Null)) { return false; } - return !!(kind & TypeFlags.NumberLike) && isTypeAssignableTo(source, numberType) || - !!(kind & TypeFlags.BigIntLike) && isTypeAssignableTo(source, bigintType) || - !!(kind & TypeFlags.StringLike) && isTypeAssignableTo(source, stringType) || - !!(kind & TypeFlags.BooleanLike) && isTypeAssignableTo(source, booleanType) || - !!(kind & TypeFlags.Void) && isTypeAssignableTo(source, voidType) || - !!(kind & TypeFlags.Never) && isTypeAssignableTo(source, neverType) || - !!(kind & TypeFlags.Null) && isTypeAssignableTo(source, nullType) || - !!(kind & TypeFlags.Undefined) && isTypeAssignableTo(source, undefinedType) || - !!(kind & TypeFlags.ESSymbol) && isTypeAssignableTo(source, esSymbolType) || - !!(kind & TypeFlags.NonPrimitive) && isTypeAssignableTo(source, nonPrimitiveType); - } - - function allTypesAssignableToKind(source: Type, kind: TypeFlags, strict?: boolean): boolean { - return source.flags & TypeFlags.Union ? - every((source as UnionType).types, subType => allTypesAssignableToKind(subType, kind, strict)) : + return !!(kind & ts.TypeFlags.NumberLike) && isTypeAssignableTo(source, numberType) || + !!(kind & ts.TypeFlags.BigIntLike) && isTypeAssignableTo(source, bigintType) || + !!(kind & ts.TypeFlags.StringLike) && isTypeAssignableTo(source, stringType) || + !!(kind & ts.TypeFlags.BooleanLike) && isTypeAssignableTo(source, booleanType) || + !!(kind & ts.TypeFlags.Void) && isTypeAssignableTo(source, voidType) || + !!(kind & ts.TypeFlags.Never) && isTypeAssignableTo(source, neverType) || + !!(kind & ts.TypeFlags.Null) && isTypeAssignableTo(source, nullType) || + !!(kind & ts.TypeFlags.Undefined) && isTypeAssignableTo(source, undefinedType) || + !!(kind & ts.TypeFlags.ESSymbol) && isTypeAssignableTo(source, esSymbolType) || + !!(kind & ts.TypeFlags.NonPrimitive) && isTypeAssignableTo(source, nonPrimitiveType); + } + + function allTypesAssignableToKind(source: ts.Type, kind: ts.TypeFlags, strict?: boolean): boolean { + return source.flags & ts.TypeFlags.Union ? + ts.every((source as ts.UnionType).types, subType => allTypesAssignableToKind(subType, kind, strict)) : isTypeAssignableToKind(source, kind, strict); } - function isConstEnumObjectType(type: Type): boolean { - return !!(getObjectFlags(type) & ObjectFlags.Anonymous) && !!type.symbol && isConstEnumSymbol(type.symbol); + function isConstEnumObjectType(type: ts.Type): boolean { + return !!(ts.getObjectFlags(type) & ts.ObjectFlags.Anonymous) && !!type.symbol && isConstEnumSymbol(type.symbol); } - function isConstEnumSymbol(symbol: Symbol): boolean { - return (symbol.flags & SymbolFlags.ConstEnum) !== 0; + function isConstEnumSymbol(symbol: ts.Symbol): boolean { + return (symbol.flags & ts.SymbolFlags.ConstEnum) !== 0; } - function checkInstanceOfExpression(left: Expression, right: Expression, leftType: Type, rightType: Type): Type { + function checkInstanceOfExpression(left: ts.Expression, right: ts.Expression, leftType: ts.Type, rightType: ts.Type): ts.Type { if (leftType === silentNeverType || rightType === silentNeverType) { return silentNeverType; } @@ -33354,27 +32606,27 @@ namespace ts { // The result is always of the Boolean primitive type. // NOTE: do not raise error if leftType is unknown as related error was already reported if (!isTypeAny(leftType) && - allTypesAssignableToKind(leftType, TypeFlags.Primitive)) { - error(left, Diagnostics.The_left_hand_side_of_an_instanceof_expression_must_be_of_type_any_an_object_type_or_a_type_parameter); + allTypesAssignableToKind(leftType, ts.TypeFlags.Primitive)) { + error(left, ts.Diagnostics.The_left_hand_side_of_an_instanceof_expression_must_be_of_type_any_an_object_type_or_a_type_parameter); } // NOTE: do not raise error if right is unknown as related error was already reported if (!(isTypeAny(rightType) || typeHasCallOrConstructSignatures(rightType) || isTypeSubtypeOf(rightType, globalFunctionType))) { - error(right, Diagnostics.The_right_hand_side_of_an_instanceof_expression_must_be_of_type_any_or_of_a_type_assignable_to_the_Function_interface_type); + error(right, ts.Diagnostics.The_right_hand_side_of_an_instanceof_expression_must_be_of_type_any_or_of_a_type_assignable_to_the_Function_interface_type); } return booleanType; } - function checkInExpression(left: Expression, right: Expression, leftType: Type, rightType: Type): Type { + function checkInExpression(left: ts.Expression, right: ts.Expression, leftType: ts.Type, rightType: ts.Type): ts.Type { if (leftType === silentNeverType || rightType === silentNeverType) { return silentNeverType; } - if (isPrivateIdentifier(left)) { - if (languageVersion < ScriptTarget.ESNext) { - checkExternalEmitHelpers(left, ExternalEmitHelpers.ClassPrivateFieldIn); + if (ts.isPrivateIdentifier(left)) { + if (languageVersion < ts.ScriptTarget.ESNext) { + checkExternalEmitHelpers(left, ts.ExternalEmitHelpers.ClassPrivateFieldIn); } // Unlike in 'checkPrivateIdentifierExpression' we now have access to the RHS type // which provides us with the opportunity to emit more detailed errors - if (!getNodeLinks(left).resolvedSymbol && getContainingClass(left)) { + if (!getNodeLinks(left).resolvedSymbol && ts.getContainingClass(left)) { const isUncheckedJS = isUncheckedJSSuggestion(left, rightType.symbol, /*excludeClasses*/ true); reportNonexistentProperty(left, rightType, isUncheckedJS); } @@ -33383,9 +32635,9 @@ namespace ts { leftType = checkNonNullType(leftType, left); // TypeScript 1.0 spec (April 2014): 4.15.5 // Require the left operand to be of type Any, the String primitive type, or the Number primitive type. - if (!(allTypesAssignableToKind(leftType, TypeFlags.StringLike | TypeFlags.NumberLike | TypeFlags.ESSymbolLike) || - isTypeAssignableToKind(leftType, TypeFlags.Index | TypeFlags.TemplateLiteral | TypeFlags.StringMapping | TypeFlags.TypeParameter))) { - error(left, Diagnostics.The_left_hand_side_of_an_in_expression_must_be_a_private_identifier_or_of_type_any_string_number_or_symbol); + if (!(allTypesAssignableToKind(leftType, ts.TypeFlags.StringLike | ts.TypeFlags.NumberLike | ts.TypeFlags.ESSymbolLike) || + isTypeAssignableToKind(leftType, ts.TypeFlags.Index | ts.TypeFlags.TemplateLiteral | ts.TypeFlags.StringMapping | ts.TypeFlags.TypeParameter))) { + error(left, ts.Diagnostics.The_left_hand_side_of_an_in_expression_must_be_a_private_identifier_or_of_type_any_string_number_or_symbol); } } rightType = checkNonNullType(rightType, right); @@ -33409,18 +32661,15 @@ namespace ts { // // The result is always of the Boolean primitive type. const rightTypeConstraint = getConstraintOfType(rightType); - if (!allTypesAssignableToKind(rightType, TypeFlags.NonPrimitive | TypeFlags.InstantiableNonPrimitive) || - rightTypeConstraint && ( - isTypeAssignableToKind(rightType, TypeFlags.UnionOrIntersection) && !allTypesAssignableToKind(rightTypeConstraint, TypeFlags.NonPrimitive | TypeFlags.InstantiableNonPrimitive) || - !maybeTypeOfKind(rightTypeConstraint, TypeFlags.NonPrimitive | TypeFlags.InstantiableNonPrimitive | TypeFlags.Object) - ) - ) { - error(right, Diagnostics.The_right_hand_side_of_an_in_expression_must_not_be_a_primitive); + if (!allTypesAssignableToKind(rightType, ts.TypeFlags.NonPrimitive | ts.TypeFlags.InstantiableNonPrimitive) || + rightTypeConstraint && (isTypeAssignableToKind(rightType, ts.TypeFlags.UnionOrIntersection) && !allTypesAssignableToKind(rightTypeConstraint, ts.TypeFlags.NonPrimitive | ts.TypeFlags.InstantiableNonPrimitive) || + !maybeTypeOfKind(rightTypeConstraint, ts.TypeFlags.NonPrimitive | ts.TypeFlags.InstantiableNonPrimitive | ts.TypeFlags.Object))) { + error(right, ts.Diagnostics.The_right_hand_side_of_an_in_expression_must_not_be_a_primitive); } return booleanType; } - function checkObjectLiteralAssignment(node: ObjectLiteralExpression, sourceType: Type, rightIsThis?: boolean): Type { + function checkObjectLiteralAssignment(node: ts.ObjectLiteralExpression, sourceType: ts.Type, rightIsThis?: boolean): ts.Type { const properties = node.properties; if (strictNullChecks && properties.length === 0) { return checkNonNullType(sourceType, node); @@ -33432,10 +32681,10 @@ namespace ts { } /** Note: If property cannot be a SpreadAssignment, then allProperties does not need to be provided */ - function checkObjectLiteralDestructuringPropertyAssignment(node: ObjectLiteralExpression, objectLiteralType: Type, propertyIndex: number, allProperties?: NodeArray, rightIsThis = false) { + function checkObjectLiteralDestructuringPropertyAssignment(node: ts.ObjectLiteralExpression, objectLiteralType: ts.Type, propertyIndex: number, allProperties?: ts.NodeArray, rightIsThis = false) { const properties = node.properties; const property = properties[propertyIndex]; - if (property.kind === SyntaxKind.PropertyAssignment || property.kind === SyntaxKind.ShorthandPropertyAssignment) { + if (property.kind === ts.SyntaxKind.PropertyAssignment || property.kind === ts.SyntaxKind.ShorthandPropertyAssignment) { const name = property.name; const exprType = getLiteralTypeFromPropertyName(name); if (isTypeUsableAsPropertyName(exprType)) { @@ -33446,49 +32695,49 @@ namespace ts { checkPropertyAccessibility(property, /*isSuper*/ false, /*writing*/ true, objectLiteralType, prop); } } - const elementType = getIndexedAccessType(objectLiteralType, exprType, AccessFlags.ExpressionPosition, name); + const elementType = getIndexedAccessType(objectLiteralType, exprType, ts.AccessFlags.ExpressionPosition, name); const type = getFlowTypeOfDestructuring(property, elementType); - return checkDestructuringAssignment(property.kind === SyntaxKind.ShorthandPropertyAssignment ? property : property.initializer, type); + return checkDestructuringAssignment(property.kind === ts.SyntaxKind.ShorthandPropertyAssignment ? property : property.initializer, type); } - else if (property.kind === SyntaxKind.SpreadAssignment) { + else if (property.kind === ts.SyntaxKind.SpreadAssignment) { if (propertyIndex < properties.length - 1) { - error(property, Diagnostics.A_rest_element_must_be_last_in_a_destructuring_pattern); + error(property, ts.Diagnostics.A_rest_element_must_be_last_in_a_destructuring_pattern); } else { - if (languageVersion < ScriptTarget.ESNext) { - checkExternalEmitHelpers(property, ExternalEmitHelpers.Rest); + if (languageVersion < ts.ScriptTarget.ESNext) { + checkExternalEmitHelpers(property, ts.ExternalEmitHelpers.Rest); } - const nonRestNames: PropertyName[] = []; + const nonRestNames: ts.PropertyName[] = []; if (allProperties) { for (const otherProperty of allProperties) { - if (!isSpreadAssignment(otherProperty)) { + if (!ts.isSpreadAssignment(otherProperty)) { nonRestNames.push(otherProperty.name); } } } const type = getRestType(objectLiteralType, nonRestNames, objectLiteralType.symbol); - checkGrammarForDisallowedTrailingComma(allProperties, Diagnostics.A_rest_parameter_or_binding_pattern_may_not_have_a_trailing_comma); + checkGrammarForDisallowedTrailingComma(allProperties, ts.Diagnostics.A_rest_parameter_or_binding_pattern_may_not_have_a_trailing_comma); return checkDestructuringAssignment(property.expression, type); } } else { - error(property, Diagnostics.Property_assignment_expected); + error(property, ts.Diagnostics.Property_assignment_expected); } } - function checkArrayLiteralAssignment(node: ArrayLiteralExpression, sourceType: Type, checkMode?: CheckMode): Type { + function checkArrayLiteralAssignment(node: ts.ArrayLiteralExpression, sourceType: ts.Type, checkMode?: CheckMode): ts.Type { const elements = node.elements; - if (languageVersion < ScriptTarget.ES2015 && compilerOptions.downlevelIteration) { - checkExternalEmitHelpers(node, ExternalEmitHelpers.Read); + if (languageVersion < ts.ScriptTarget.ES2015 && compilerOptions.downlevelIteration) { + checkExternalEmitHelpers(node, ts.ExternalEmitHelpers.Read); } // This elementType will be used if the specific property corresponding to this index is not // present (aka the tuple element property). This call also checks that the parentType is in // fact an iterable or array (depending on target language). const possiblyOutOfBoundsType = checkIteratedTypeOrElementType(IterationUse.Destructuring | IterationUse.PossiblyOutOfBounds, sourceType, undefinedType, node) || errorType; - let inBoundsType: Type | undefined = compilerOptions.noUncheckedIndexedAccess ? undefined: possiblyOutOfBoundsType; + let inBoundsType: ts.Type | undefined = compilerOptions.noUncheckedIndexedAccess ? undefined : possiblyOutOfBoundsType; for (let i = 0; i < elements.length; i++) { let type = possiblyOutOfBoundsType; - if (node.elements[i].kind === SyntaxKind.SpreadElement) { + if (node.elements[i].kind === ts.SyntaxKind.SpreadElement) { type = inBoundsType = inBoundsType ?? (checkIteratedTypeOrElementType(IterationUse.Destructuring, sourceType, undefinedType, node) || errorType); } checkArrayLiteralDestructuringElementAssignment(node, sourceType, i, type, checkMode); @@ -33496,17 +32745,16 @@ namespace ts { return sourceType; } - function checkArrayLiteralDestructuringElementAssignment(node: ArrayLiteralExpression, sourceType: Type, - elementIndex: number, elementType: Type, checkMode?: CheckMode) { + function checkArrayLiteralDestructuringElementAssignment(node: ts.ArrayLiteralExpression, sourceType: ts.Type, elementIndex: number, elementType: ts.Type, checkMode?: CheckMode) { const elements = node.elements; const element = elements[elementIndex]; - if (element.kind !== SyntaxKind.OmittedExpression) { - if (element.kind !== SyntaxKind.SpreadElement) { + if (element.kind !== ts.SyntaxKind.OmittedExpression) { + if (element.kind !== ts.SyntaxKind.SpreadElement) { const indexType = getNumberLiteralType(elementIndex); if (isArrayLikeType(sourceType)) { // We create a synthetic expression so that getIndexedAccessType doesn't get confused // when the element is a SyntaxKind.ElementAccessExpression. - const accessFlags = AccessFlags.ExpressionPosition | (hasDefaultValue(element) ? AccessFlags.NoTupleBoundsCheck : 0); + const accessFlags = ts.AccessFlags.ExpressionPosition | (hasDefaultValue(element) ? ts.AccessFlags.NoTupleBoundsCheck : 0); const elementType = getIndexedAccessTypeOrUndefined(sourceType, indexType, accessFlags, createSyntheticExpression(element, indexType)) || errorType; const assignedType = hasDefaultValue(element) ? getTypeWithFacts(elementType, TypeFacts.NEUndefined) : elementType; const type = getFlowTypeOfDestructuring(element, assignedType); @@ -33515,17 +32763,17 @@ namespace ts { return checkDestructuringAssignment(element, elementType, checkMode); } if (elementIndex < elements.length - 1) { - error(element, Diagnostics.A_rest_element_must_be_last_in_a_destructuring_pattern); + error(element, ts.Diagnostics.A_rest_element_must_be_last_in_a_destructuring_pattern); } else { - const restExpression = (element as SpreadElement).expression; - if (restExpression.kind === SyntaxKind.BinaryExpression && (restExpression as BinaryExpression).operatorToken.kind === SyntaxKind.EqualsToken) { - error((restExpression as BinaryExpression).operatorToken, Diagnostics.A_rest_element_cannot_have_an_initializer); + const restExpression = (element as ts.SpreadElement).expression; + if (restExpression.kind === ts.SyntaxKind.BinaryExpression && (restExpression as ts.BinaryExpression).operatorToken.kind === ts.SyntaxKind.EqualsToken) { + error((restExpression as ts.BinaryExpression).operatorToken, ts.Diagnostics.A_rest_element_cannot_have_an_initializer); } else { - checkGrammarForDisallowedTrailingComma(node.elements, Diagnostics.A_rest_parameter_or_binding_pattern_may_not_have_a_trailing_comma); + checkGrammarForDisallowedTrailingComma(node.elements, ts.Diagnostics.A_rest_parameter_or_binding_pattern_may_not_have_a_trailing_comma); const type = everyType(sourceType, isTupleType) ? - mapType(sourceType, t => sliceTupleType(t as TupleTypeReference, elementIndex)) : + mapType(sourceType, t => sliceTupleType(t as ts.TupleTypeReference, elementIndex)) : createArrayType(elementType); return checkDestructuringAssignment(restExpression, type, checkMode); } @@ -33534,51 +32782,51 @@ namespace ts { return undefined; } - function checkDestructuringAssignment(exprOrAssignment: Expression | ShorthandPropertyAssignment, sourceType: Type, checkMode?: CheckMode, rightIsThis?: boolean): Type { - let target: Expression; - if (exprOrAssignment.kind === SyntaxKind.ShorthandPropertyAssignment) { - const prop = exprOrAssignment as ShorthandPropertyAssignment; + function checkDestructuringAssignment(exprOrAssignment: ts.Expression | ts.ShorthandPropertyAssignment, sourceType: ts.Type, checkMode?: CheckMode, rightIsThis?: boolean): ts.Type { + let target: ts.Expression; + if (exprOrAssignment.kind === ts.SyntaxKind.ShorthandPropertyAssignment) { + const prop = exprOrAssignment as ts.ShorthandPropertyAssignment; if (prop.objectAssignmentInitializer) { // In strict null checking mode, if a default value of a non-undefined type is specified, remove // undefined from the final type. if (strictNullChecks && - !(getFalsyFlags(checkExpression(prop.objectAssignmentInitializer)) & TypeFlags.Undefined)) { + !(getFalsyFlags(checkExpression(prop.objectAssignmentInitializer)) & ts.TypeFlags.Undefined)) { sourceType = getTypeWithFacts(sourceType, TypeFacts.NEUndefined); } checkBinaryLikeExpression(prop.name, prop.equalsToken!, prop.objectAssignmentInitializer, checkMode); } - target = (exprOrAssignment as ShorthandPropertyAssignment).name; + target = (exprOrAssignment as ts.ShorthandPropertyAssignment).name; } else { target = exprOrAssignment; } - if (target.kind === SyntaxKind.BinaryExpression && (target as BinaryExpression).operatorToken.kind === SyntaxKind.EqualsToken) { - checkBinaryExpression(target as BinaryExpression, checkMode); - target = (target as BinaryExpression).left; + if (target.kind === ts.SyntaxKind.BinaryExpression && (target as ts.BinaryExpression).operatorToken.kind === ts.SyntaxKind.EqualsToken) { + checkBinaryExpression(target as ts.BinaryExpression, checkMode); + target = (target as ts.BinaryExpression).left; } - if (target.kind === SyntaxKind.ObjectLiteralExpression) { - return checkObjectLiteralAssignment(target as ObjectLiteralExpression, sourceType, rightIsThis); + if (target.kind === ts.SyntaxKind.ObjectLiteralExpression) { + return checkObjectLiteralAssignment(target as ts.ObjectLiteralExpression, sourceType, rightIsThis); } - if (target.kind === SyntaxKind.ArrayLiteralExpression) { - return checkArrayLiteralAssignment(target as ArrayLiteralExpression, sourceType, checkMode); + if (target.kind === ts.SyntaxKind.ArrayLiteralExpression) { + return checkArrayLiteralAssignment(target as ts.ArrayLiteralExpression, sourceType, checkMode); } return checkReferenceAssignment(target, sourceType, checkMode); } - function checkReferenceAssignment(target: Expression, sourceType: Type, checkMode?: CheckMode): Type { + function checkReferenceAssignment(target: ts.Expression, sourceType: ts.Type, checkMode?: CheckMode): ts.Type { const targetType = checkExpression(target, checkMode); - const error = target.parent.kind === SyntaxKind.SpreadAssignment ? - Diagnostics.The_target_of_an_object_rest_assignment_must_be_a_variable_or_a_property_access : - Diagnostics.The_left_hand_side_of_an_assignment_expression_must_be_a_variable_or_a_property_access; - const optionalError = target.parent.kind === SyntaxKind.SpreadAssignment ? - Diagnostics.The_target_of_an_object_rest_assignment_may_not_be_an_optional_property_access : - Diagnostics.The_left_hand_side_of_an_assignment_expression_may_not_be_an_optional_property_access; + const error = target.parent.kind === ts.SyntaxKind.SpreadAssignment ? + ts.Diagnostics.The_target_of_an_object_rest_assignment_must_be_a_variable_or_a_property_access : + ts.Diagnostics.The_left_hand_side_of_an_assignment_expression_must_be_a_variable_or_a_property_access; + const optionalError = target.parent.kind === ts.SyntaxKind.SpreadAssignment ? + ts.Diagnostics.The_target_of_an_object_rest_assignment_may_not_be_an_optional_property_access : + ts.Diagnostics.The_left_hand_side_of_an_assignment_expression_may_not_be_an_optional_property_access; if (checkReferenceExpression(target, error, optionalError)) { checkTypeAssignableToAndOptionallyElaborate(sourceType, targetType, target, target); } - if (isPrivateIdentifierPropertyAccessExpression(target)) { - checkExternalEmitHelpers(target.parent, ExternalEmitHelpers.ClassPrivateFieldSet); + if (ts.isPrivateIdentifierPropertyAccessExpression(target)) { + checkExternalEmitHelpers(target.parent, ts.ExternalEmitHelpers.ClassPrivateFieldSet); } return sourceType; } @@ -33591,67 +32839,65 @@ namespace ts { * The intent is to "smell test" an expression for correctness in positions where * its value is discarded (e.g. the left side of the comma operator). */ - function isSideEffectFree(node: Node): boolean { - node = skipParentheses(node); + function isSideEffectFree(node: ts.Node): boolean { + node = ts.skipParentheses(node); switch (node.kind) { - case SyntaxKind.Identifier: - case SyntaxKind.StringLiteral: - case SyntaxKind.RegularExpressionLiteral: - case SyntaxKind.TaggedTemplateExpression: - case SyntaxKind.TemplateExpression: - case SyntaxKind.NoSubstitutionTemplateLiteral: - case SyntaxKind.NumericLiteral: - case SyntaxKind.BigIntLiteral: - case SyntaxKind.TrueKeyword: - case SyntaxKind.FalseKeyword: - case SyntaxKind.NullKeyword: - case SyntaxKind.UndefinedKeyword: - case SyntaxKind.FunctionExpression: - case SyntaxKind.ClassExpression: - case SyntaxKind.ArrowFunction: - case SyntaxKind.ArrayLiteralExpression: - case SyntaxKind.ObjectLiteralExpression: - case SyntaxKind.TypeOfExpression: - case SyntaxKind.NonNullExpression: - case SyntaxKind.JsxSelfClosingElement: - case SyntaxKind.JsxElement: + case ts.SyntaxKind.Identifier: + case ts.SyntaxKind.StringLiteral: + case ts.SyntaxKind.RegularExpressionLiteral: + case ts.SyntaxKind.TaggedTemplateExpression: + case ts.SyntaxKind.TemplateExpression: + case ts.SyntaxKind.NoSubstitutionTemplateLiteral: + case ts.SyntaxKind.NumericLiteral: + case ts.SyntaxKind.BigIntLiteral: + case ts.SyntaxKind.TrueKeyword: + case ts.SyntaxKind.FalseKeyword: + case ts.SyntaxKind.NullKeyword: + case ts.SyntaxKind.UndefinedKeyword: + case ts.SyntaxKind.FunctionExpression: + case ts.SyntaxKind.ClassExpression: + case ts.SyntaxKind.ArrowFunction: + case ts.SyntaxKind.ArrayLiteralExpression: + case ts.SyntaxKind.ObjectLiteralExpression: + case ts.SyntaxKind.TypeOfExpression: + case ts.SyntaxKind.NonNullExpression: + case ts.SyntaxKind.JsxSelfClosingElement: + case ts.SyntaxKind.JsxElement: return true; - case SyntaxKind.ConditionalExpression: - return isSideEffectFree((node as ConditionalExpression).whenTrue) && - isSideEffectFree((node as ConditionalExpression).whenFalse); - - case SyntaxKind.BinaryExpression: - if (isAssignmentOperator((node as BinaryExpression).operatorToken.kind)) { + case ts.SyntaxKind.ConditionalExpression: + return isSideEffectFree((node as ts.ConditionalExpression).whenTrue) && + isSideEffectFree((node as ts.ConditionalExpression).whenFalse); + case ts.SyntaxKind.BinaryExpression: + if (ts.isAssignmentOperator((node as ts.BinaryExpression).operatorToken.kind)) { return false; } - return isSideEffectFree((node as BinaryExpression).left) && - isSideEffectFree((node as BinaryExpression).right); - - case SyntaxKind.PrefixUnaryExpression: - case SyntaxKind.PostfixUnaryExpression: + return isSideEffectFree((node as ts.BinaryExpression).left) && + isSideEffectFree((node as ts.BinaryExpression).right); + case ts.SyntaxKind.PrefixUnaryExpression: + case ts.SyntaxKind.PostfixUnaryExpression: // Unary operators ~, !, +, and - have no side effects. // The rest do. - switch ((node as PrefixUnaryExpression).operator) { - case SyntaxKind.ExclamationToken: - case SyntaxKind.PlusToken: - case SyntaxKind.MinusToken: - case SyntaxKind.TildeToken: + switch ((node as ts.PrefixUnaryExpression).operator) { + case ts.SyntaxKind.ExclamationToken: + case ts.SyntaxKind.PlusToken: + case ts.SyntaxKind.MinusToken: + case ts.SyntaxKind.TildeToken: return true; } return false; // Some forms listed here for clarity - case SyntaxKind.VoidExpression: // Explicit opt-out - case SyntaxKind.TypeAssertionExpression: // Not SEF, but can produce useful type warnings - case SyntaxKind.AsExpression: // Not SEF, but can produce useful type warnings + case ts.SyntaxKind.VoidExpression: // Explicit opt-out + case ts.SyntaxKind.TypeAssertionExpression: // Not SEF, but can produce useful type warnings + case ts.SyntaxKind.AsExpression: // Not SEF, but can produce useful type warnings default: return false; } } - function isTypeEqualityComparableTo(source: Type, target: Type) { - return (target.flags & TypeFlags.Nullable) !== 0 || isTypeComparableTo(source, target); + function isTypeEqualityComparableTo(source: ts.Type, target: ts.Type) { + return (target.flags & ts.TypeFlags.Nullable) !== 0 || isTypeComparableTo(source, target); } function createCheckBinaryExpression() { @@ -33664,18 +32910,17 @@ namespace ts { * Holds the type of the result at stackIndex+1. This allows us to reuse existing stack entries * and avoid storing an extra property on the object (i.e., `lastResult`). */ - typeStack: (Type | undefined)[]; + typeStack: (ts.Type | undefined)[]; } - const trampoline = createBinaryExpressionTrampoline(onEnter, onLeft, onOperator, onRight, onExit, foldState); - - return (node: BinaryExpression, checkMode: CheckMode | undefined) => { + const trampoline = ts.createBinaryExpressionTrampoline(onEnter, onLeft, onOperator, onRight, onExit, foldState); + return (node: ts.BinaryExpression, checkMode: CheckMode | undefined) => { const result = trampoline(node, checkMode); - Debug.assertIsDefined(result); + ts.Debug.assertIsDefined(result); return result; }; - function onEnter(node: BinaryExpression, state: WorkArea | undefined, checkMode: CheckMode | undefined) { + function onEnter(node: ts.BinaryExpression, state: WorkArea | undefined, checkMode: CheckMode | undefined) { if (state) { state.stackIndex++; state.skip = false; @@ -33691,7 +32936,7 @@ namespace ts { }; } - if (isInJSFile(node) && getAssignedExpandoInitializer(node)) { + if (ts.isInJSFile(node) && ts.getAssignedExpandoInitializer(node)) { state.skip = true; setLastResult(state, checkExpression(node.right, checkMode)); return state; @@ -33700,55 +32945,55 @@ namespace ts { checkGrammarNullishCoalesceWithLogicalExpression(node); const operator = node.operatorToken.kind; - if (operator === SyntaxKind.EqualsToken && (node.left.kind === SyntaxKind.ObjectLiteralExpression || node.left.kind === SyntaxKind.ArrayLiteralExpression)) { + if (operator === ts.SyntaxKind.EqualsToken && (node.left.kind === ts.SyntaxKind.ObjectLiteralExpression || node.left.kind === ts.SyntaxKind.ArrayLiteralExpression)) { state.skip = true; - setLastResult(state, checkDestructuringAssignment(node.left, checkExpression(node.right, checkMode), checkMode, node.right.kind === SyntaxKind.ThisKeyword)); + setLastResult(state, checkDestructuringAssignment(node.left, checkExpression(node.right, checkMode), checkMode, node.right.kind === ts.SyntaxKind.ThisKeyword)); return state; } return state; } - function onLeft(left: Expression, state: WorkArea, _node: BinaryExpression) { + function onLeft(left: ts.Expression, state: WorkArea, _node: ts.BinaryExpression) { if (!state.skip) { return maybeCheckExpression(state, left); } } - function onOperator(operatorToken: BinaryOperatorToken, state: WorkArea, node: BinaryExpression) { + function onOperator(operatorToken: ts.BinaryOperatorToken, state: WorkArea, node: ts.BinaryExpression) { if (!state.skip) { const leftType = getLastResult(state); - Debug.assertIsDefined(leftType); + ts.Debug.assertIsDefined(leftType); setLeftType(state, leftType); setLastResult(state, /*type*/ undefined); const operator = operatorToken.kind; - if (operator === SyntaxKind.AmpersandAmpersandToken || operator === SyntaxKind.BarBarToken || operator === SyntaxKind.QuestionQuestionToken) { - if (operator === SyntaxKind.AmpersandAmpersandToken) { - const parent = walkUpParenthesizedExpressions(node.parent); - checkTestingKnownTruthyCallableOrAwaitableType(node.left, isIfStatement(parent) ? parent.thenStatement : undefined); + if (operator === ts.SyntaxKind.AmpersandAmpersandToken || operator === ts.SyntaxKind.BarBarToken || operator === ts.SyntaxKind.QuestionQuestionToken) { + if (operator === ts.SyntaxKind.AmpersandAmpersandToken) { + const parent = ts.walkUpParenthesizedExpressions(node.parent); + checkTestingKnownTruthyCallableOrAwaitableType(node.left, ts.isIfStatement(parent) ? parent.thenStatement : undefined); } checkTruthinessOfType(leftType, node.left); } } } - function onRight(right: Expression, state: WorkArea, _node: BinaryExpression) { + function onRight(right: ts.Expression, state: WorkArea, _node: ts.BinaryExpression) { if (!state.skip) { return maybeCheckExpression(state, right); } } - function onExit(node: BinaryExpression, state: WorkArea): Type | undefined { - let result: Type | undefined; + function onExit(node: ts.BinaryExpression, state: WorkArea): ts.Type | undefined { + let result: ts.Type | undefined; if (state.skip) { result = getLastResult(state); } else { const leftType = getLeftType(state); - Debug.assertIsDefined(leftType); + ts.Debug.assertIsDefined(leftType); const rightType = getLastResult(state); - Debug.assertIsDefined(rightType); + ts.Debug.assertIsDefined(rightType); result = checkBinaryLikeExpressionWorker(node.left, node.operatorToken, node.right, leftType, rightType, node); } @@ -33760,13 +33005,13 @@ namespace ts { return result; } - function foldState(state: WorkArea, result: Type | undefined, _side: "left" | "right") { + function foldState(state: WorkArea, result: ts.Type | undefined, _side: "left" | "right") { setLastResult(state, result); return state; } - function maybeCheckExpression(state: WorkArea, node: Expression): BinaryExpression | undefined { - if (isBinaryExpression(node)) { + function maybeCheckExpression(state: WorkArea, node: ts.Expression): ts.BinaryExpression | undefined { + if (ts.isBinaryExpression(node)) { return node; } setLastResult(state, checkExpression(node, state.checkMode)); @@ -33776,7 +33021,7 @@ namespace ts { return state.typeStack[state.stackIndex]; } - function setLeftType(state: WorkArea, type: Type | undefined) { + function setLeftType(state: WorkArea, type: ts.Type | undefined) { state.typeStack[state.stackIndex] = type; } @@ -33784,7 +33029,7 @@ namespace ts { return state.typeStack[state.stackIndex + 1]; } - function setLastResult(state: WorkArea, type: Type | undefined) { + function setLastResult(state: WorkArea, type: ts.Type | undefined) { // To reduce overhead, reuse the next stack entry to store the // last result. This avoids the overhead of an additional property // on `WorkArea` and reuses empty stack entries as we walk back up @@ -33793,27 +33038,27 @@ namespace ts { } } - function checkGrammarNullishCoalesceWithLogicalExpression(node: BinaryExpression) { + function checkGrammarNullishCoalesceWithLogicalExpression(node: ts.BinaryExpression) { const { left, operatorToken, right } = node; - if (operatorToken.kind === SyntaxKind.QuestionQuestionToken) { - if (isBinaryExpression(left) && (left.operatorToken.kind === SyntaxKind.BarBarToken || left.operatorToken.kind === SyntaxKind.AmpersandAmpersandToken)) { - grammarErrorOnNode(left, Diagnostics._0_and_1_operations_cannot_be_mixed_without_parentheses, tokenToString(left.operatorToken.kind), tokenToString(operatorToken.kind)); + if (operatorToken.kind === ts.SyntaxKind.QuestionQuestionToken) { + if (ts.isBinaryExpression(left) && (left.operatorToken.kind === ts.SyntaxKind.BarBarToken || left.operatorToken.kind === ts.SyntaxKind.AmpersandAmpersandToken)) { + grammarErrorOnNode(left, ts.Diagnostics._0_and_1_operations_cannot_be_mixed_without_parentheses, ts.tokenToString(left.operatorToken.kind), ts.tokenToString(operatorToken.kind)); } - if (isBinaryExpression(right) && (right.operatorToken.kind === SyntaxKind.BarBarToken || right.operatorToken.kind === SyntaxKind.AmpersandAmpersandToken)) { - grammarErrorOnNode(right, Diagnostics._0_and_1_operations_cannot_be_mixed_without_parentheses, tokenToString(right.operatorToken.kind), tokenToString(operatorToken.kind)); + if (ts.isBinaryExpression(right) && (right.operatorToken.kind === ts.SyntaxKind.BarBarToken || right.operatorToken.kind === ts.SyntaxKind.AmpersandAmpersandToken)) { + grammarErrorOnNode(right, ts.Diagnostics._0_and_1_operations_cannot_be_mixed_without_parentheses, ts.tokenToString(right.operatorToken.kind), ts.tokenToString(operatorToken.kind)); } } } // Note that this and `checkBinaryExpression` above should behave mostly the same, except this elides some // expression-wide checks and does not use a work stack to fold nested binary expressions into the same callstack frame - function checkBinaryLikeExpression(left: Expression, operatorToken: Node, right: Expression, checkMode?: CheckMode, errorNode?: Node): Type { + function checkBinaryLikeExpression(left: ts.Expression, operatorToken: ts.Node, right: ts.Expression, checkMode?: CheckMode, errorNode?: ts.Node): ts.Type { const operator = operatorToken.kind; - if (operator === SyntaxKind.EqualsToken && (left.kind === SyntaxKind.ObjectLiteralExpression || left.kind === SyntaxKind.ArrayLiteralExpression)) { - return checkDestructuringAssignment(left, checkExpression(right, checkMode), checkMode, right.kind === SyntaxKind.ThisKeyword); + if (operator === ts.SyntaxKind.EqualsToken && (left.kind === ts.SyntaxKind.ObjectLiteralExpression || left.kind === ts.SyntaxKind.ArrayLiteralExpression)) { + return checkDestructuringAssignment(left, checkExpression(right, checkMode), checkMode, right.kind === ts.SyntaxKind.ThisKeyword); } - let leftType: Type; - if (operator === SyntaxKind.AmpersandAmpersandToken || operator === SyntaxKind.BarBarToken || operator === SyntaxKind.QuestionQuestionToken) { + let leftType: ts.Type; + if (operator === ts.SyntaxKind.AmpersandAmpersandToken || operator === ts.SyntaxKind.BarBarToken || operator === ts.SyntaxKind.QuestionQuestionToken) { leftType = checkTruthinessExpression(left, checkMode); } else { @@ -33824,38 +33069,31 @@ namespace ts { return checkBinaryLikeExpressionWorker(left, operatorToken, right, leftType, rightType, errorNode); } - function checkBinaryLikeExpressionWorker( - left: Expression, - operatorToken: Node, - right: Expression, - leftType: Type, - rightType: Type, - errorNode?: Node - ): Type { + function checkBinaryLikeExpressionWorker(left: ts.Expression, operatorToken: ts.Node, right: ts.Expression, leftType: ts.Type, rightType: ts.Type, errorNode?: ts.Node): ts.Type { const operator = operatorToken.kind; switch (operator) { - case SyntaxKind.AsteriskToken: - case SyntaxKind.AsteriskAsteriskToken: - case SyntaxKind.AsteriskEqualsToken: - case SyntaxKind.AsteriskAsteriskEqualsToken: - case SyntaxKind.SlashToken: - case SyntaxKind.SlashEqualsToken: - case SyntaxKind.PercentToken: - case SyntaxKind.PercentEqualsToken: - case SyntaxKind.MinusToken: - case SyntaxKind.MinusEqualsToken: - case SyntaxKind.LessThanLessThanToken: - case SyntaxKind.LessThanLessThanEqualsToken: - case SyntaxKind.GreaterThanGreaterThanToken: - case SyntaxKind.GreaterThanGreaterThanEqualsToken: - case SyntaxKind.GreaterThanGreaterThanGreaterThanToken: - case SyntaxKind.GreaterThanGreaterThanGreaterThanEqualsToken: - case SyntaxKind.BarToken: - case SyntaxKind.BarEqualsToken: - case SyntaxKind.CaretToken: - case SyntaxKind.CaretEqualsToken: - case SyntaxKind.AmpersandToken: - case SyntaxKind.AmpersandEqualsToken: + case ts.SyntaxKind.AsteriskToken: + case ts.SyntaxKind.AsteriskAsteriskToken: + case ts.SyntaxKind.AsteriskEqualsToken: + case ts.SyntaxKind.AsteriskAsteriskEqualsToken: + case ts.SyntaxKind.SlashToken: + case ts.SyntaxKind.SlashEqualsToken: + case ts.SyntaxKind.PercentToken: + case ts.SyntaxKind.PercentEqualsToken: + case ts.SyntaxKind.MinusToken: + case ts.SyntaxKind.MinusEqualsToken: + case ts.SyntaxKind.LessThanLessThanToken: + case ts.SyntaxKind.LessThanLessThanEqualsToken: + case ts.SyntaxKind.GreaterThanGreaterThanToken: + case ts.SyntaxKind.GreaterThanGreaterThanEqualsToken: + case ts.SyntaxKind.GreaterThanGreaterThanGreaterThanToken: + case ts.SyntaxKind.GreaterThanGreaterThanGreaterThanEqualsToken: + case ts.SyntaxKind.BarToken: + case ts.SyntaxKind.BarEqualsToken: + case ts.SyntaxKind.CaretToken: + case ts.SyntaxKind.CaretEqualsToken: + case ts.SyntaxKind.AmpersandToken: + case ts.SyntaxKind.AmpersandEqualsToken: if (leftType === silentNeverType || rightType === silentNeverType) { return silentNeverType; } @@ -33863,38 +33101,37 @@ namespace ts { leftType = checkNonNullType(leftType, left); rightType = checkNonNullType(rightType, right); - let suggestedOperator: SyntaxKind | undefined; + let suggestedOperator: ts.SyntaxKind | undefined; // if a user tries to apply a bitwise operator to 2 boolean operands // try and return them a helpful suggestion - if ((leftType.flags & TypeFlags.BooleanLike) && - (rightType.flags & TypeFlags.BooleanLike) && + if ((leftType.flags & ts.TypeFlags.BooleanLike) && + (rightType.flags & ts.TypeFlags.BooleanLike) && (suggestedOperator = getSuggestedBooleanOperator(operatorToken.kind)) !== undefined) { - error(errorNode || operatorToken, Diagnostics.The_0_operator_is_not_allowed_for_boolean_types_Consider_using_1_instead, tokenToString(operatorToken.kind), tokenToString(suggestedOperator)); + error(errorNode || operatorToken, ts.Diagnostics.The_0_operator_is_not_allowed_for_boolean_types_Consider_using_1_instead, ts.tokenToString(operatorToken.kind), ts.tokenToString(suggestedOperator)); return numberType; } else { // otherwise just check each operand separately and report errors as normal - const leftOk = checkArithmeticOperandType(left, leftType, Diagnostics.The_left_hand_side_of_an_arithmetic_operation_must_be_of_type_any_number_bigint_or_an_enum_type, /*isAwaitValid*/ true); - const rightOk = checkArithmeticOperandType(right, rightType, Diagnostics.The_right_hand_side_of_an_arithmetic_operation_must_be_of_type_any_number_bigint_or_an_enum_type, /*isAwaitValid*/ true); - let resultType: Type; + const leftOk = checkArithmeticOperandType(left, leftType, ts.Diagnostics.The_left_hand_side_of_an_arithmetic_operation_must_be_of_type_any_number_bigint_or_an_enum_type, /*isAwaitValid*/ true); + const rightOk = checkArithmeticOperandType(right, rightType, ts.Diagnostics.The_right_hand_side_of_an_arithmetic_operation_must_be_of_type_any_number_bigint_or_an_enum_type, /*isAwaitValid*/ true); + let resultType: ts.Type; // If both are any or unknown, allow operation; assume it will resolve to number - if ((isTypeAssignableToKind(leftType, TypeFlags.AnyOrUnknown) && isTypeAssignableToKind(rightType, TypeFlags.AnyOrUnknown)) || + if ((isTypeAssignableToKind(leftType, ts.TypeFlags.AnyOrUnknown) && isTypeAssignableToKind(rightType, ts.TypeFlags.AnyOrUnknown)) || // Or, if neither could be bigint, implicit coercion results in a number result - !(maybeTypeOfKind(leftType, TypeFlags.BigIntLike) || maybeTypeOfKind(rightType, TypeFlags.BigIntLike)) - ) { + !(maybeTypeOfKind(leftType, ts.TypeFlags.BigIntLike) || maybeTypeOfKind(rightType, ts.TypeFlags.BigIntLike))) { resultType = numberType; } // At least one is assignable to bigint, so check that both are else if (bothAreBigIntLike(leftType, rightType)) { switch (operator) { - case SyntaxKind.GreaterThanGreaterThanGreaterThanToken: - case SyntaxKind.GreaterThanGreaterThanGreaterThanEqualsToken: + case ts.SyntaxKind.GreaterThanGreaterThanGreaterThanToken: + case ts.SyntaxKind.GreaterThanGreaterThanGreaterThanEqualsToken: reportOperatorError(); break; - case SyntaxKind.AsteriskAsteriskToken: - case SyntaxKind.AsteriskAsteriskEqualsToken: - if (languageVersion < ScriptTarget.ES2016) { - error(errorNode, Diagnostics.Exponentiation_cannot_be_performed_on_bigint_values_unless_the_target_option_is_set_to_es2016_or_later); + case ts.SyntaxKind.AsteriskAsteriskToken: + case ts.SyntaxKind.AsteriskAsteriskEqualsToken: + if (languageVersion < ts.ScriptTarget.ES2016) { + error(errorNode, ts.Diagnostics.Exponentiation_cannot_be_performed_on_bigint_values_unless_the_target_option_is_set_to_es2016_or_later); } } resultType = bigintType; @@ -33909,28 +33146,28 @@ namespace ts { } return resultType; } - case SyntaxKind.PlusToken: - case SyntaxKind.PlusEqualsToken: + case ts.SyntaxKind.PlusToken: + case ts.SyntaxKind.PlusEqualsToken: if (leftType === silentNeverType || rightType === silentNeverType) { return silentNeverType; } - if (!isTypeAssignableToKind(leftType, TypeFlags.StringLike) && !isTypeAssignableToKind(rightType, TypeFlags.StringLike)) { + if (!isTypeAssignableToKind(leftType, ts.TypeFlags.StringLike) && !isTypeAssignableToKind(rightType, ts.TypeFlags.StringLike)) { leftType = checkNonNullType(leftType, left); rightType = checkNonNullType(rightType, right); } - let resultType: Type | undefined; - if (isTypeAssignableToKind(leftType, TypeFlags.NumberLike, /*strict*/ true) && isTypeAssignableToKind(rightType, TypeFlags.NumberLike, /*strict*/ true)) { + let resultType: ts.Type | undefined; + if (isTypeAssignableToKind(leftType, ts.TypeFlags.NumberLike, /*strict*/ true) && isTypeAssignableToKind(rightType, ts.TypeFlags.NumberLike, /*strict*/ true)) { // Operands of an enum type are treated as having the primitive type Number. // If both operands are of the Number primitive type, the result is of the Number primitive type. resultType = numberType; } - else if (isTypeAssignableToKind(leftType, TypeFlags.BigIntLike, /*strict*/ true) && isTypeAssignableToKind(rightType, TypeFlags.BigIntLike, /*strict*/ true)) { + else if (isTypeAssignableToKind(leftType, ts.TypeFlags.BigIntLike, /*strict*/ true) && isTypeAssignableToKind(rightType, ts.TypeFlags.BigIntLike, /*strict*/ true)) { // If both operands are of the BigInt primitive type, the result is of the BigInt primitive type. resultType = bigintType; } - else if (isTypeAssignableToKind(leftType, TypeFlags.StringLike, /*strict*/ true) || isTypeAssignableToKind(rightType, TypeFlags.StringLike, /*strict*/ true)) { + else if (isTypeAssignableToKind(leftType, ts.TypeFlags.StringLike, /*strict*/ true) || isTypeAssignableToKind(rightType, ts.TypeFlags.StringLike, /*strict*/ true)) { // If one or both operands are of the String primitive type, the result is of the String primitive type. resultType = stringType; } @@ -33950,84 +33187,81 @@ namespace ts { // If both types have an awaited type of one of these, we'll assume the user // might be missing an await without doing an exhaustive check that inserting // await(s) will actually be a completely valid binary expression. - const closeEnoughKind = TypeFlags.NumberLike | TypeFlags.BigIntLike | TypeFlags.StringLike | TypeFlags.AnyOrUnknown; - reportOperatorError((left, right) => - isTypeAssignableToKind(left, closeEnoughKind) && + const closeEnoughKind = ts.TypeFlags.NumberLike | ts.TypeFlags.BigIntLike | ts.TypeFlags.StringLike | ts.TypeFlags.AnyOrUnknown; + reportOperatorError((left, right) => isTypeAssignableToKind(left, closeEnoughKind) && isTypeAssignableToKind(right, closeEnoughKind)); return anyType; } - if (operator === SyntaxKind.PlusEqualsToken) { + if (operator === ts.SyntaxKind.PlusEqualsToken) { checkAssignmentOperator(resultType); } return resultType; - case SyntaxKind.LessThanToken: - case SyntaxKind.GreaterThanToken: - case SyntaxKind.LessThanEqualsToken: - case SyntaxKind.GreaterThanEqualsToken: + case ts.SyntaxKind.LessThanToken: + case ts.SyntaxKind.GreaterThanToken: + case ts.SyntaxKind.LessThanEqualsToken: + case ts.SyntaxKind.GreaterThanEqualsToken: if (checkForDisallowedESSymbolOperand(operator)) { leftType = getBaseTypeOfLiteralType(checkNonNullType(leftType, left)); rightType = getBaseTypeOfLiteralType(checkNonNullType(rightType, right)); - reportOperatorErrorUnless((left, right) => - isTypeComparableTo(left, right) || isTypeComparableTo(right, left) || ( - isTypeAssignableTo(left, numberOrBigIntType) && isTypeAssignableTo(right, numberOrBigIntType))); + reportOperatorErrorUnless((left, right) => isTypeComparableTo(left, right) || isTypeComparableTo(right, left) || (isTypeAssignableTo(left, numberOrBigIntType) && isTypeAssignableTo(right, numberOrBigIntType))); } return booleanType; - case SyntaxKind.EqualsEqualsToken: - case SyntaxKind.ExclamationEqualsToken: - case SyntaxKind.EqualsEqualsEqualsToken: - case SyntaxKind.ExclamationEqualsEqualsToken: - if (isLiteralExpressionOfObject(left) || isLiteralExpressionOfObject(right)) { - const eqType = operator === SyntaxKind.EqualsEqualsToken || operator === SyntaxKind.EqualsEqualsEqualsToken; - error(errorNode, Diagnostics.This_condition_will_always_return_0_since_JavaScript_compares_objects_by_reference_not_value, eqType ? "false" : "true"); + case ts.SyntaxKind.EqualsEqualsToken: + case ts.SyntaxKind.ExclamationEqualsToken: + case ts.SyntaxKind.EqualsEqualsEqualsToken: + case ts.SyntaxKind.ExclamationEqualsEqualsToken: + if (ts.isLiteralExpressionOfObject(left) || ts.isLiteralExpressionOfObject(right)) { + const eqType = operator === ts.SyntaxKind.EqualsEqualsToken || operator === ts.SyntaxKind.EqualsEqualsEqualsToken; + error(errorNode, ts.Diagnostics.This_condition_will_always_return_0_since_JavaScript_compares_objects_by_reference_not_value, eqType ? "false" : "true"); } reportOperatorErrorUnless((left, right) => isTypeEqualityComparableTo(left, right) || isTypeEqualityComparableTo(right, left)); return booleanType; - case SyntaxKind.InstanceOfKeyword: + case ts.SyntaxKind.InstanceOfKeyword: return checkInstanceOfExpression(left, right, leftType, rightType); - case SyntaxKind.InKeyword: + case ts.SyntaxKind.InKeyword: return checkInExpression(left, right, leftType, rightType); - case SyntaxKind.AmpersandAmpersandToken: - case SyntaxKind.AmpersandAmpersandEqualsToken: { + case ts.SyntaxKind.AmpersandAmpersandToken: + case ts.SyntaxKind.AmpersandAmpersandEqualsToken: { const resultType = getTypeFacts(leftType) & TypeFacts.Truthy ? getUnionType([extractDefinitelyFalsyTypes(strictNullChecks ? leftType : getBaseTypeOfLiteralType(rightType)), rightType]) : leftType; - if (operator === SyntaxKind.AmpersandAmpersandEqualsToken) { + if (operator === ts.SyntaxKind.AmpersandAmpersandEqualsToken) { checkAssignmentOperator(rightType); } return resultType; } - case SyntaxKind.BarBarToken: - case SyntaxKind.BarBarEqualsToken: { + case ts.SyntaxKind.BarBarToken: + case ts.SyntaxKind.BarBarEqualsToken: { const resultType = getTypeFacts(leftType) & TypeFacts.Falsy ? - getUnionType([removeDefinitelyFalsyTypes(leftType), rightType], UnionReduction.Subtype) : + getUnionType([removeDefinitelyFalsyTypes(leftType), rightType], ts.UnionReduction.Subtype) : leftType; - if (operator === SyntaxKind.BarBarEqualsToken) { + if (operator === ts.SyntaxKind.BarBarEqualsToken) { checkAssignmentOperator(rightType); } return resultType; } - case SyntaxKind.QuestionQuestionToken: - case SyntaxKind.QuestionQuestionEqualsToken: { + case ts.SyntaxKind.QuestionQuestionToken: + case ts.SyntaxKind.QuestionQuestionEqualsToken: { const resultType = getTypeFacts(leftType) & TypeFacts.EQUndefinedOrNull ? - getUnionType([getNonNullableType(leftType), rightType], UnionReduction.Subtype) : + getUnionType([getNonNullableType(leftType), rightType], ts.UnionReduction.Subtype) : leftType; - if (operator === SyntaxKind.QuestionQuestionEqualsToken) { + if (operator === ts.SyntaxKind.QuestionQuestionEqualsToken) { checkAssignmentOperator(rightType); } return resultType; } - case SyntaxKind.EqualsToken: - const declKind = isBinaryExpression(left.parent) ? getAssignmentDeclarationKind(left.parent) : AssignmentDeclarationKind.None; + case ts.SyntaxKind.EqualsToken: + const declKind = ts.isBinaryExpression(left.parent) ? ts.getAssignmentDeclarationKind(left.parent) : ts.AssignmentDeclarationKind.None; checkAssignmentDeclaration(declKind, rightType); if (isAssignmentDeclaration(declKind)) { - if (!(rightType.flags & TypeFlags.Object) || - declKind !== AssignmentDeclarationKind.ModuleExports && - declKind !== AssignmentDeclarationKind.Prototype && + if (!(rightType.flags & ts.TypeFlags.Object) || + declKind !== ts.AssignmentDeclarationKind.ModuleExports && + declKind !== ts.AssignmentDeclarationKind.Prototype && !isEmptyObjectType(rightType) && - !isFunctionObjectType(rightType as ObjectType) && - !(getObjectFlags(rightType) & ObjectFlags.Class)) { + !isFunctionObjectType(rightType as ts.ObjectType) && + !(ts.getObjectFlags(rightType) & ts.ObjectFlags.Class)) { // don't check assignability of module.exports=, C.prototype=, or expando types because they will necessarily be incomplete checkAssignmentOperator(rightType); } @@ -34037,80 +33271,81 @@ namespace ts { checkAssignmentOperator(rightType); return getRegularTypeOfObjectLiteral(rightType); } - case SyntaxKind.CommaToken: + case ts.SyntaxKind.CommaToken: if (!compilerOptions.allowUnreachableCode && isSideEffectFree(left) && !isEvalNode(right)) { - const sf = getSourceFileOfNode(left); + const sf = ts.getSourceFileOfNode(left); const sourceText = sf.text; - const start = skipTrivia(sourceText, left.pos); + const start = ts.skipTrivia(sourceText, left.pos); const isInDiag2657 = sf.parseDiagnostics.some(diag => { - if (diag.code !== Diagnostics.JSX_expressions_must_have_one_parent_element.code) return false; - return textSpanContainsPosition(diag, start); + if (diag.code !== ts.Diagnostics.JSX_expressions_must_have_one_parent_element.code) + return false; + return ts.textSpanContainsPosition(diag, start); }); - if (!isInDiag2657) error(left, Diagnostics.Left_side_of_comma_operator_is_unused_and_has_no_side_effects); + if (!isInDiag2657) + error(left, ts.Diagnostics.Left_side_of_comma_operator_is_unused_and_has_no_side_effects); } return rightType; default: - return Debug.fail(); + return ts.Debug.fail(); } - function bothAreBigIntLike(left: Type, right: Type): boolean { - return isTypeAssignableToKind(left, TypeFlags.BigIntLike) && isTypeAssignableToKind(right, TypeFlags.BigIntLike); + function bothAreBigIntLike(left: ts.Type, right: ts.Type): boolean { + return isTypeAssignableToKind(left, ts.TypeFlags.BigIntLike) && isTypeAssignableToKind(right, ts.TypeFlags.BigIntLike); } - function checkAssignmentDeclaration(kind: AssignmentDeclarationKind, rightType: Type) { - if (kind === AssignmentDeclarationKind.ModuleExports) { + function checkAssignmentDeclaration(kind: ts.AssignmentDeclarationKind, rightType: ts.Type) { + if (kind === ts.AssignmentDeclarationKind.ModuleExports) { for (const prop of getPropertiesOfObjectType(rightType)) { const propType = getTypeOfSymbol(prop); - if (propType.symbol && propType.symbol.flags & SymbolFlags.Class) { + if (propType.symbol && propType.symbol.flags & ts.SymbolFlags.Class) { const name = prop.escapedName; - const symbol = resolveName(prop.valueDeclaration, name, SymbolFlags.Type, undefined, name, /*isUse*/ false); - if (symbol?.declarations && symbol.declarations.some(isJSDocTypedefTag)) { - addDuplicateDeclarationErrorsForSymbols(symbol, Diagnostics.Duplicate_identifier_0, unescapeLeadingUnderscores(name), prop); - addDuplicateDeclarationErrorsForSymbols(prop, Diagnostics.Duplicate_identifier_0, unescapeLeadingUnderscores(name), symbol); + const symbol = resolveName(prop.valueDeclaration, name, ts.SymbolFlags.Type, undefined, name, /*isUse*/ false); + if (symbol?.declarations && symbol.declarations.some(ts.isJSDocTypedefTag)) { + addDuplicateDeclarationErrorsForSymbols(symbol, ts.Diagnostics.Duplicate_identifier_0, ts.unescapeLeadingUnderscores(name), prop); + addDuplicateDeclarationErrorsForSymbols(prop, ts.Diagnostics.Duplicate_identifier_0, ts.unescapeLeadingUnderscores(name), symbol); } } } } } - function isEvalNode(node: Expression) { - return node.kind === SyntaxKind.Identifier && (node as Identifier).escapedText === "eval"; + function isEvalNode(node: ts.Expression) { + return node.kind === ts.SyntaxKind.Identifier && (node as ts.Identifier).escapedText === "eval"; } // Return true if there was no error, false if there was an error. - function checkForDisallowedESSymbolOperand(operator: SyntaxKind): boolean { - const offendingSymbolOperand = - maybeTypeOfKindConsideringBaseConstraint(leftType, TypeFlags.ESSymbolLike) ? left : - maybeTypeOfKindConsideringBaseConstraint(rightType, TypeFlags.ESSymbolLike) ? right : + function checkForDisallowedESSymbolOperand(operator: ts.SyntaxKind): boolean { + const offendingSymbolOperand = maybeTypeOfKindConsideringBaseConstraint(leftType, ts.TypeFlags.ESSymbolLike) ? left : + maybeTypeOfKindConsideringBaseConstraint(rightType, ts.TypeFlags.ESSymbolLike) ? right : undefined; if (offendingSymbolOperand) { - error(offendingSymbolOperand, Diagnostics.The_0_operator_cannot_be_applied_to_type_symbol, tokenToString(operator)); + error(offendingSymbolOperand, ts.Diagnostics.The_0_operator_cannot_be_applied_to_type_symbol, ts.tokenToString(operator)); return false; } return true; } - function getSuggestedBooleanOperator(operator: SyntaxKind): SyntaxKind | undefined { + function getSuggestedBooleanOperator(operator: ts.SyntaxKind): ts.SyntaxKind | undefined { switch (operator) { - case SyntaxKind.BarToken: - case SyntaxKind.BarEqualsToken: - return SyntaxKind.BarBarToken; - case SyntaxKind.CaretToken: - case SyntaxKind.CaretEqualsToken: - return SyntaxKind.ExclamationEqualsEqualsToken; - case SyntaxKind.AmpersandToken: - case SyntaxKind.AmpersandEqualsToken: - return SyntaxKind.AmpersandAmpersandToken; + case ts.SyntaxKind.BarToken: + case ts.SyntaxKind.BarEqualsToken: + return ts.SyntaxKind.BarBarToken; + case ts.SyntaxKind.CaretToken: + case ts.SyntaxKind.CaretEqualsToken: + return ts.SyntaxKind.ExclamationEqualsEqualsToken; + case ts.SyntaxKind.AmpersandToken: + case ts.SyntaxKind.AmpersandEqualsToken: + return ts.SyntaxKind.AmpersandAmpersandToken; default: return undefined; } } - function checkAssignmentOperator(valueType: Type): void { - if (isAssignmentOperator(operator)) { + function checkAssignmentOperator(valueType: ts.Type): void { + if (ts.isAssignmentOperator(operator)) { addLazyDiagnostic(checkAssignmentOperatorWorker); } @@ -34122,16 +33357,13 @@ namespace ts { // A compound assignment furthermore requires VarExpr to be classified as a reference (section 4.1) // and the type of the non-compound operation to be assignable to the type of VarExpr. - if (checkReferenceExpression(left, - Diagnostics.The_left_hand_side_of_an_assignment_expression_must_be_a_variable_or_a_property_access, - Diagnostics.The_left_hand_side_of_an_assignment_expression_may_not_be_an_optional_property_access) - && (!isIdentifier(left) || unescapeLeadingUnderscores(left.escapedText) !== "exports")) { - - let headMessage: DiagnosticMessage | undefined; - if (exactOptionalPropertyTypes && isPropertyAccessExpression(left) && maybeTypeOfKind(valueType, TypeFlags.Undefined)) { + if (checkReferenceExpression(left, ts.Diagnostics.The_left_hand_side_of_an_assignment_expression_must_be_a_variable_or_a_property_access, ts.Diagnostics.The_left_hand_side_of_an_assignment_expression_may_not_be_an_optional_property_access) + && (!ts.isIdentifier(left) || ts.unescapeLeadingUnderscores(left.escapedText) !== "exports")) { + let headMessage: ts.DiagnosticMessage | undefined; + if (exactOptionalPropertyTypes && ts.isPropertyAccessExpression(left) && maybeTypeOfKind(valueType, ts.TypeFlags.Undefined)) { const target = getTypeOfPropertyOfType(getTypeOfExpression(left.expression), left.name.escapedText); if (isExactOptionalPropertyMismatch(valueType, target)) { - headMessage = Diagnostics.Type_0_is_not_assignable_to_type_1_with_exactOptionalPropertyTypes_Colon_true_Consider_adding_undefined_to_the_type_of_the_target; + headMessage = ts.Diagnostics.Type_0_is_not_assignable_to_type_1_with_exactOptionalPropertyTypes_Colon_true_Consider_adding_undefined_to_the_type_of_the_target; } } // to avoid cascading errors check assignability only if 'isReference' check succeeded and no errors were reported @@ -34140,18 +33372,18 @@ namespace ts { } } - function isAssignmentDeclaration(kind: AssignmentDeclarationKind) { + function isAssignmentDeclaration(kind: ts.AssignmentDeclarationKind) { switch (kind) { - case AssignmentDeclarationKind.ModuleExports: + case ts.AssignmentDeclarationKind.ModuleExports: return true; - case AssignmentDeclarationKind.ExportsProperty: - case AssignmentDeclarationKind.Property: - case AssignmentDeclarationKind.Prototype: - case AssignmentDeclarationKind.PrototypeProperty: - case AssignmentDeclarationKind.ThisProperty: + case ts.AssignmentDeclarationKind.ExportsProperty: + case ts.AssignmentDeclarationKind.Property: + case ts.AssignmentDeclarationKind.Prototype: + case ts.AssignmentDeclarationKind.PrototypeProperty: + case ts.AssignmentDeclarationKind.ThisProperty: const symbol = getSymbolOfNode(left); - const init = getAssignedExpandoInitializer(right); - return !!init && isObjectLiteralExpression(init) && + const init = ts.getAssignedExpandoInitializer(right); + return !!init && ts.isObjectLiteralExpression(init) && !!symbol?.exports?.size; default: return false; @@ -34161,7 +33393,7 @@ namespace ts { /** * Returns true if an error is reported */ - function reportOperatorErrorUnless(typesAreCompatible: (left: Type, right: Type) => boolean): boolean { + function reportOperatorErrorUnless(typesAreCompatible: (left: ts.Type, right: ts.Type) => boolean): boolean { if (!typesAreCompatible(leftType, rightType)) { reportOperatorError(typesAreCompatible); return true; @@ -34169,7 +33401,7 @@ namespace ts { return false; } - function reportOperatorError(isRelated?: (left: Type, right: Type) => boolean) { + function reportOperatorError(isRelated?: (left: ts.Type, right: ts.Type) => boolean) { let wouldWorkWithAwait = false; const errNode = errorNode || operatorToken; if (isRelated) { @@ -34187,42 +33419,34 @@ namespace ts { } const [leftStr, rightStr] = getTypeNamesForErrorDisplay(effectiveLeft, effectiveRight); if (!tryGiveBetterPrimaryError(errNode, wouldWorkWithAwait, leftStr, rightStr)) { - errorAndMaybeSuggestAwait( - errNode, - wouldWorkWithAwait, - Diagnostics.Operator_0_cannot_be_applied_to_types_1_and_2, - tokenToString(operatorToken.kind), - leftStr, - rightStr, - ); + errorAndMaybeSuggestAwait(errNode, wouldWorkWithAwait, ts.Diagnostics.Operator_0_cannot_be_applied_to_types_1_and_2, ts.tokenToString(operatorToken.kind), leftStr, rightStr); } } - function tryGiveBetterPrimaryError(errNode: Node, maybeMissingAwait: boolean, leftStr: string, rightStr: string) { + function tryGiveBetterPrimaryError(errNode: ts.Node, maybeMissingAwait: boolean, leftStr: string, rightStr: string) { let typeName: string | undefined; switch (operatorToken.kind) { - case SyntaxKind.EqualsEqualsEqualsToken: - case SyntaxKind.EqualsEqualsToken: + case ts.SyntaxKind.EqualsEqualsEqualsToken: + case ts.SyntaxKind.EqualsEqualsToken: typeName = "false"; break; - case SyntaxKind.ExclamationEqualsEqualsToken: - case SyntaxKind.ExclamationEqualsToken: + case ts.SyntaxKind.ExclamationEqualsEqualsToken: + case ts.SyntaxKind.ExclamationEqualsToken: typeName = "true"; } if (typeName) { - return errorAndMaybeSuggestAwait( - errNode, - maybeMissingAwait, - Diagnostics.This_condition_will_always_return_0_since_the_types_1_and_2_have_no_overlap, - typeName, leftStr, rightStr); + return errorAndMaybeSuggestAwait(errNode, maybeMissingAwait, ts.Diagnostics.This_condition_will_always_return_0_since_the_types_1_and_2_have_no_overlap, typeName, leftStr, rightStr); } return undefined; } } - function getBaseTypesIfUnrelated(leftType: Type, rightType: Type, isRelated: (left: Type, right: Type) => boolean): [Type, Type] { + function getBaseTypesIfUnrelated(leftType: ts.Type, rightType: ts.Type, isRelated: (left: ts.Type, right: ts.Type) => boolean): [ + ts.Type, + ts.Type + ] { let effectiveLeft = leftType; let effectiveRight = rightType; const leftBase = getBaseTypeOfLiteralType(leftType); @@ -34234,29 +33458,29 @@ namespace ts { return [ effectiveLeft, effectiveRight ]; } - function checkYieldExpression(node: YieldExpression): Type { + function checkYieldExpression(node: ts.YieldExpression): ts.Type { addLazyDiagnostic(checkYieldExpressionGrammar); - const func = getContainingFunction(node); - if (!func) return anyType; - const functionFlags = getFunctionFlags(func); - - if (!(functionFlags & FunctionFlags.Generator)) { + const func = ts.getContainingFunction(node); + if (!func) + return anyType; + const functionFlags = ts.getFunctionFlags(func); + if (!(functionFlags & ts.FunctionFlags.Generator)) { // If the user's code is syntactically correct, the func should always have a star. After all, we are in a yield context. return anyType; } - const isAsync = (functionFlags & FunctionFlags.Async) !== 0; + const isAsync = (functionFlags & ts.FunctionFlags.Async) !== 0; if (node.asteriskToken) { // Async generator functions prior to ESNext require the __await, __asyncDelegator, // and __asyncValues helpers - if (isAsync && languageVersion < ScriptTarget.ESNext) { - checkExternalEmitHelpers(node, ExternalEmitHelpers.AsyncDelegatorIncludes); + if (isAsync && languageVersion < ts.ScriptTarget.ESNext) { + checkExternalEmitHelpers(node, ts.ExternalEmitHelpers.AsyncDelegatorIncludes); } // Generator functions prior to ES2015 require the __values helper - if (!isAsync && languageVersion < ScriptTarget.ES2015 && compilerOptions.downlevelIteration) { - checkExternalEmitHelpers(node, ExternalEmitHelpers.Values); + if (!isAsync && languageVersion < ts.ScriptTarget.ES2015 && compilerOptions.downlevelIteration) { + checkExternalEmitHelpers(node, ts.ExternalEmitHelpers.Values); } } @@ -34287,10 +33511,10 @@ namespace ts { if (!type) { type = anyType; addLazyDiagnostic(() => { - if (noImplicitAny && !expressionResultIsUnused(node)) { + if (noImplicitAny && !ts.expressionResultIsUnused(node)) { const contextualType = getContextualType(node); if (!contextualType || isTypeAny(contextualType)) { - error(node, Diagnostics.yield_expression_implicitly_results_in_an_any_type_because_its_containing_generator_lacks_a_return_type_annotation); + error(node, ts.Diagnostics.yield_expression_implicitly_results_in_an_any_type_because_its_containing_generator_lacks_a_return_type_annotation); } } }); @@ -34298,37 +33522,37 @@ namespace ts { return type; function checkYieldExpressionGrammar() { - if (!(node.flags & NodeFlags.YieldContext)) { - grammarErrorOnFirstToken(node, Diagnostics.A_yield_expression_is_only_allowed_in_a_generator_body); + if (!(node.flags & ts.NodeFlags.YieldContext)) { + grammarErrorOnFirstToken(node, ts.Diagnostics.A_yield_expression_is_only_allowed_in_a_generator_body); } if (isInParameterInitializerBeforeContainingFunction(node)) { - error(node, Diagnostics.yield_expressions_cannot_be_used_in_a_parameter_initializer); + error(node, ts.Diagnostics.yield_expressions_cannot_be_used_in_a_parameter_initializer); } } } - function checkConditionalExpression(node: ConditionalExpression, checkMode?: CheckMode): Type { + function checkConditionalExpression(node: ts.ConditionalExpression, checkMode?: CheckMode): ts.Type { checkTruthinessExpression(node.condition); checkTestingKnownTruthyCallableOrAwaitableType(node.condition, node.whenTrue); const type1 = checkExpression(node.whenTrue, checkMode); const type2 = checkExpression(node.whenFalse, checkMode); - return getUnionType([type1, type2], UnionReduction.Subtype); + return getUnionType([type1, type2], ts.UnionReduction.Subtype); } - function isTemplateLiteralContext(node: Node): boolean { + function isTemplateLiteralContext(node: ts.Node): boolean { const parent = node.parent; - return isParenthesizedExpression(parent) && isTemplateLiteralContext(parent) || - isElementAccessExpression(parent) && parent.argumentExpression === node; + return ts.isParenthesizedExpression(parent) && isTemplateLiteralContext(parent) || + ts.isElementAccessExpression(parent) && parent.argumentExpression === node; } - function checkTemplateExpression(node: TemplateExpression): Type { + function checkTemplateExpression(node: ts.TemplateExpression): ts.Type { const texts = [node.head.text]; const types = []; for (const span of node.templateSpans) { const type = checkExpression(span.expression); - if (maybeTypeOfKindConsideringBaseConstraint(type, TypeFlags.ESSymbolLike)) { - error(span.expression, Diagnostics.Implicit_conversion_of_a_symbol_to_a_string_will_fail_at_runtime_Consider_wrapping_this_expression_in_String); + if (maybeTypeOfKindConsideringBaseConstraint(type, ts.TypeFlags.ESSymbolLike)) { + error(span.expression, ts.Diagnostics.Implicit_conversion_of_a_symbol_to_a_string_will_fail_at_runtime_Consider_wrapping_this_expression_in_String); } texts.push(span.literal.text); types.push(isTypeAssignableTo(type, templateConstraintType) ? type : stringType); @@ -34336,19 +33560,19 @@ namespace ts { return isConstContext(node) || isTemplateLiteralContext(node) || someType(getContextualType(node) || unknownType, isTemplateLiteralContextualType) ? getTemplateLiteralType(texts, types) : stringType; } - function isTemplateLiteralContextualType(type: Type): boolean { - return !!(type.flags & (TypeFlags.StringLiteral | TypeFlags.TemplateLiteral) || - type.flags & TypeFlags.InstantiableNonPrimitive && maybeTypeOfKind(getBaseConstraintOfType(type) || unknownType, TypeFlags.StringLike)); + function isTemplateLiteralContextualType(type: ts.Type): boolean { + return !!(type.flags & (ts.TypeFlags.StringLiteral | ts.TypeFlags.TemplateLiteral) || + type.flags & ts.TypeFlags.InstantiableNonPrimitive && maybeTypeOfKind(getBaseConstraintOfType(type) || unknownType, ts.TypeFlags.StringLike)); } - function getContextNode(node: Expression): Node { - if (node.kind === SyntaxKind.JsxAttributes && !isJsxSelfClosingElement(node.parent)) { + function getContextNode(node: ts.Expression): ts.Node { + if (node.kind === ts.SyntaxKind.JsxAttributes && !ts.isJsxSelfClosingElement(node.parent)) { return node.parent.parent; // Needs to be the root JsxElement, so it encompasses the attributes _and_ the children (which are essentially part of the attributes) } return node; } - function checkExpressionWithContextualType(node: Expression, contextualType: Type, inferenceContext: InferenceContext | undefined, checkMode: CheckMode): Type { + function checkExpressionWithContextualType(node: ts.Expression, contextualType: ts.Type, inferenceContext: ts.InferenceContext | undefined, checkMode: CheckMode): ts.Type { const context = getContextNode(node); const saveContextualType = context.contextualType; const saveInferenceContext = context.inferenceContext; @@ -34364,7 +33588,7 @@ namespace ts { // We strip literal freshness when an appropriate contextual type is present such that contextually typed // literals always preserve their literal types (otherwise they might widen during type inference). An alternative // here would be to not mark contextually typed literals as fresh in the first place. - const result = maybeTypeOfKind(type, TypeFlags.Literal) && isLiteralOfContextualType(type, instantiateContextualType(contextualType, node)) ? + const result = maybeTypeOfKind(type, ts.TypeFlags.Literal) && isLiteralOfContextualType(type, instantiateContextualType(contextualType, node)) ? getRegularTypeOfLiteralType(type) : type; return result; } @@ -34377,7 +33601,7 @@ namespace ts { } } - function checkExpressionCached(node: Expression | QualifiedName, checkMode?: CheckMode): Type { + function checkExpressionCached(node: ts.Expression | ts.QualifiedName, checkMode?: CheckMode): ts.Type { if (checkMode && checkMode !== CheckMode.Normal) { return checkExpression(node, checkMode); } @@ -34397,38 +33621,34 @@ namespace ts { return links.resolvedType; } - function isTypeAssertion(node: Expression) { - node = skipParentheses(node, /*excludeJSDocTypeAssertions*/ true); - return node.kind === SyntaxKind.TypeAssertionExpression || - node.kind === SyntaxKind.AsExpression || - isJSDocTypeAssertion(node); + function isTypeAssertion(node: ts.Expression) { + node = ts.skipParentheses(node, /*excludeJSDocTypeAssertions*/ true); + return node.kind === ts.SyntaxKind.TypeAssertionExpression || + node.kind === ts.SyntaxKind.AsExpression || + ts.isJSDocTypeAssertion(node); } - function checkDeclarationInitializer( - declaration: HasExpressionInitializer, - checkMode: CheckMode, - contextualType?: Type | undefined - ) { - const initializer = getEffectiveInitializer(declaration)!; + function checkDeclarationInitializer(declaration: ts.HasExpressionInitializer, checkMode: CheckMode, contextualType?: ts.Type | undefined) { + const initializer = ts.getEffectiveInitializer(declaration)!; const type = getQuickTypeOfExpression(initializer) || (contextualType ? checkExpressionWithContextualType(initializer, contextualType, /*inferenceContext*/ undefined, checkMode || CheckMode.Normal) : checkExpressionCached(initializer, checkMode)); - return isParameter(declaration) && declaration.name.kind === SyntaxKind.ArrayBindingPattern && + return ts.isParameter(declaration) && declaration.name.kind === ts.SyntaxKind.ArrayBindingPattern && isTupleType(type) && !type.target.hasRestElement && getTypeReferenceArity(type) < declaration.name.elements.length ? padTupleType(type, declaration.name) : type; } - function padTupleType(type: TupleTypeReference, pattern: ArrayBindingPattern) { + function padTupleType(type: ts.TupleTypeReference, pattern: ts.ArrayBindingPattern) { const patternElements = pattern.elements; const elementTypes = getTypeArguments(type).slice(); const elementFlags = type.target.elementFlags.slice(); for (let i = getTypeReferenceArity(type); i < patternElements.length; i++) { const e = patternElements[i]; - if (i < patternElements.length - 1 || !(e.kind === SyntaxKind.BindingElement && e.dotDotDotToken)) { - elementTypes.push(!isOmittedExpression(e) && hasDefaultValue(e) ? getTypeFromBindingElement(e, /*includePatternInType*/ false, /*reportErrors*/ false) : anyType); - elementFlags.push(ElementFlags.Optional); - if (!isOmittedExpression(e) && !hasDefaultValue(e)) { + if (i < patternElements.length - 1 || !(e.kind === ts.SyntaxKind.BindingElement && e.dotDotDotToken)) { + elementTypes.push(!ts.isOmittedExpression(e) && hasDefaultValue(e) ? getTypeFromBindingElement(e, /*includePatternInType*/ false, /*reportErrors*/ false) : anyType); + elementFlags.push(ts.ElementFlags.Optional); + if (!ts.isOmittedExpression(e) && !hasDefaultValue(e)) { reportImplicitAny(e, anyType); } } @@ -34436,9 +33656,9 @@ namespace ts { return createTupleType(elementTypes, elementFlags, type.target.readonly); } - function widenTypeInferredFromInitializer(declaration: HasExpressionInitializer, type: Type) { - const widened = getCombinedNodeFlags(declaration) & NodeFlags.Const || isDeclarationReadonly(declaration) ? type : getWidenedLiteralType(type); - if (isInJSFile(declaration)) { + function widenTypeInferredFromInitializer(declaration: ts.HasExpressionInitializer, type: ts.Type) { + const widened = ts.getCombinedNodeFlags(declaration) & ts.NodeFlags.Const || ts.isDeclarationReadonly(declaration) ? type : getWidenedLiteralType(type); + if (ts.isInJSFile(declaration)) { if (isEmptyLiteralType(widened)) { reportImplicitAny(declaration, anyType); return anyType; @@ -34451,68 +33671,68 @@ namespace ts { return widened; } - function isLiteralOfContextualType(candidateType: Type, contextualType: Type | undefined): boolean { + function isLiteralOfContextualType(candidateType: ts.Type, contextualType: ts.Type | undefined): boolean { if (contextualType) { - if (contextualType.flags & TypeFlags.UnionOrIntersection) { - const types = (contextualType as UnionType).types; - return some(types, t => isLiteralOfContextualType(candidateType, t)); + if (contextualType.flags & ts.TypeFlags.UnionOrIntersection) { + const types = (contextualType as ts.UnionType).types; + return ts.some(types, t => isLiteralOfContextualType(candidateType, t)); } - if (contextualType.flags & TypeFlags.InstantiableNonPrimitive) { + if (contextualType.flags & ts.TypeFlags.InstantiableNonPrimitive) { // If the contextual type is a type variable constrained to a primitive type, consider // this a literal context for literals of that primitive type. For example, given a // type parameter 'T extends string', infer string literal types for T. const constraint = getBaseConstraintOfType(contextualType) || unknownType; - return maybeTypeOfKind(constraint, TypeFlags.String) && maybeTypeOfKind(candidateType, TypeFlags.StringLiteral) || - maybeTypeOfKind(constraint, TypeFlags.Number) && maybeTypeOfKind(candidateType, TypeFlags.NumberLiteral) || - maybeTypeOfKind(constraint, TypeFlags.BigInt) && maybeTypeOfKind(candidateType, TypeFlags.BigIntLiteral) || - maybeTypeOfKind(constraint, TypeFlags.ESSymbol) && maybeTypeOfKind(candidateType, TypeFlags.UniqueESSymbol) || + return maybeTypeOfKind(constraint, ts.TypeFlags.String) && maybeTypeOfKind(candidateType, ts.TypeFlags.StringLiteral) || + maybeTypeOfKind(constraint, ts.TypeFlags.Number) && maybeTypeOfKind(candidateType, ts.TypeFlags.NumberLiteral) || + maybeTypeOfKind(constraint, ts.TypeFlags.BigInt) && maybeTypeOfKind(candidateType, ts.TypeFlags.BigIntLiteral) || + maybeTypeOfKind(constraint, ts.TypeFlags.ESSymbol) && maybeTypeOfKind(candidateType, ts.TypeFlags.UniqueESSymbol) || isLiteralOfContextualType(candidateType, constraint); } // If the contextual type is a literal of a particular primitive type, we consider this a // literal context for all literals of that primitive type. - return !!(contextualType.flags & (TypeFlags.StringLiteral | TypeFlags.Index | TypeFlags.TemplateLiteral | TypeFlags.StringMapping) && maybeTypeOfKind(candidateType, TypeFlags.StringLiteral) || - contextualType.flags & TypeFlags.NumberLiteral && maybeTypeOfKind(candidateType, TypeFlags.NumberLiteral) || - contextualType.flags & TypeFlags.BigIntLiteral && maybeTypeOfKind(candidateType, TypeFlags.BigIntLiteral) || - contextualType.flags & TypeFlags.BooleanLiteral && maybeTypeOfKind(candidateType, TypeFlags.BooleanLiteral) || - contextualType.flags & TypeFlags.UniqueESSymbol && maybeTypeOfKind(candidateType, TypeFlags.UniqueESSymbol)); + return !!(contextualType.flags & (ts.TypeFlags.StringLiteral | ts.TypeFlags.Index | ts.TypeFlags.TemplateLiteral | ts.TypeFlags.StringMapping) && maybeTypeOfKind(candidateType, ts.TypeFlags.StringLiteral) || + contextualType.flags & ts.TypeFlags.NumberLiteral && maybeTypeOfKind(candidateType, ts.TypeFlags.NumberLiteral) || + contextualType.flags & ts.TypeFlags.BigIntLiteral && maybeTypeOfKind(candidateType, ts.TypeFlags.BigIntLiteral) || + contextualType.flags & ts.TypeFlags.BooleanLiteral && maybeTypeOfKind(candidateType, ts.TypeFlags.BooleanLiteral) || + contextualType.flags & ts.TypeFlags.UniqueESSymbol && maybeTypeOfKind(candidateType, ts.TypeFlags.UniqueESSymbol)); } return false; } - function isConstContext(node: Expression): boolean { + function isConstContext(node: ts.Expression): boolean { const parent = node.parent; - return isAssertionExpression(parent) && isConstTypeReference(parent.type) || - isJSDocTypeAssertion(parent) && isConstTypeReference(getJSDocTypeAssertionType(parent)) || - (isParenthesizedExpression(parent) || isArrayLiteralExpression(parent) || isSpreadElement(parent)) && isConstContext(parent) || - (isPropertyAssignment(parent) || isShorthandPropertyAssignment(parent) || isTemplateSpan(parent)) && isConstContext(parent.parent); + return ts.isAssertionExpression(parent) && ts.isConstTypeReference(parent.type) || + ts.isJSDocTypeAssertion(parent) && ts.isConstTypeReference(ts.getJSDocTypeAssertionType(parent)) || + (ts.isParenthesizedExpression(parent) || ts.isArrayLiteralExpression(parent) || ts.isSpreadElement(parent)) && isConstContext(parent) || + (ts.isPropertyAssignment(parent) || ts.isShorthandPropertyAssignment(parent) || ts.isTemplateSpan(parent)) && isConstContext(parent.parent); } - function checkExpressionForMutableLocation(node: Expression, checkMode: CheckMode | undefined, contextualType?: Type, forceTuple?: boolean): Type { + function checkExpressionForMutableLocation(node: ts.Expression, checkMode: CheckMode | undefined, contextualType?: ts.Type, forceTuple?: boolean): ts.Type { const type = checkExpression(node, checkMode, forceTuple); - return isConstContext(node) || isCommonJsExportedExpression(node) ? getRegularTypeOfLiteralType(type) : + return isConstContext(node) || ts.isCommonJsExportedExpression(node) ? getRegularTypeOfLiteralType(type) : isTypeAssertion(node) ? type : getWidenedLiteralLikeTypeForContextualType(type, instantiateContextualType(arguments.length === 2 ? getContextualType(node) : contextualType, node)); } - function checkPropertyAssignment(node: PropertyAssignment, checkMode?: CheckMode): Type { + function checkPropertyAssignment(node: ts.PropertyAssignment, checkMode?: CheckMode): ts.Type { // Do not use hasDynamicName here, because that returns false for well known symbols. // We want to perform checkComputedPropertyName for all computed properties, including // well known symbols. - if (node.name.kind === SyntaxKind.ComputedPropertyName) { + if (node.name.kind === ts.SyntaxKind.ComputedPropertyName) { checkComputedPropertyName(node.name); } return checkExpressionForMutableLocation(node.initializer, checkMode); } - function checkObjectLiteralMethod(node: MethodDeclaration, checkMode?: CheckMode): Type { + function checkObjectLiteralMethod(node: ts.MethodDeclaration, checkMode?: CheckMode): ts.Type { // Grammar checking checkGrammarMethod(node); // Do not use hasDynamicName here, because that returns false for well known symbols. // We want to perform checkComputedPropertyName for all computed properties, including // well known symbols. - if (node.name.kind === SyntaxKind.ComputedPropertyName) { + if (node.name.kind === ts.SyntaxKind.ComputedPropertyName) { checkComputedPropertyName(node.name); } @@ -34520,15 +33740,15 @@ namespace ts { return instantiateTypeWithSingleGenericCallSignature(node, uninstantiatedType, checkMode); } - function instantiateTypeWithSingleGenericCallSignature(node: Expression | MethodDeclaration | QualifiedName, type: Type, checkMode?: CheckMode) { + function instantiateTypeWithSingleGenericCallSignature(node: ts.Expression | ts.MethodDeclaration | ts.QualifiedName, type: ts.Type, checkMode?: CheckMode) { if (checkMode && checkMode & (CheckMode.Inferential | CheckMode.SkipGenericFunctions)) { - const callSignature = getSingleSignature(type, SignatureKind.Call, /*allowMembers*/ true); - const constructSignature = getSingleSignature(type, SignatureKind.Construct, /*allowMembers*/ true); + const callSignature = getSingleSignature(type, ts.SignatureKind.Call, /*allowMembers*/ true); + const constructSignature = getSingleSignature(type, ts.SignatureKind.Construct, /*allowMembers*/ true); const signature = callSignature || constructSignature; if (signature && signature.typeParameters) { - const contextualType = getApparentTypeOfContextualType(node as Expression, ContextFlags.NoConstraints); + const contextualType = getApparentTypeOfContextualType(node as ts.Expression, ts.ContextFlags.NoConstraints); if (contextualType) { - const contextualSignature = getSingleSignature(getNonNullableType(contextualType), callSignature ? SignatureKind.Call : SignatureKind.Construct, /*allowMembers*/ false); + const contextualSignature = getSingleSignature(getNonNullableType(contextualType), callSignature ? ts.SignatureKind.Call : ts.SignatureKind.Construct, /*allowMembers*/ false); if (contextualSignature && !contextualSignature.typeParameters) { if (checkMode & CheckMode.SkipGenericFunctions) { skippedGenericFunction(node, checkMode); @@ -34543,18 +33763,18 @@ namespace ts { // potentially add inferred type parameters to the outer function return type. const returnType = context.signature && getReturnTypeOfSignature(context.signature); const returnSignature = returnType && getSingleCallOrConstructSignature(returnType); - if (returnSignature && !returnSignature.typeParameters && !every(context.inferences, hasInferenceCandidates)) { + if (returnSignature && !returnSignature.typeParameters && !ts.every(context.inferences, hasInferenceCandidates)) { // Instantiate the signature with its own type parameters as type arguments, possibly // renaming the type parameters to ensure they have unique names. const uniqueTypeParameters = getUniqueTypeParameters(context, signature.typeParameters); const instantiatedSignature = getSignatureInstantiationWithoutFillingInTypeArguments(signature, uniqueTypeParameters); // Infer from the parameters of the instantiated signature to the parameters of the // contextual signature starting with an empty set of inference candidates. - const inferences = map(context.inferences, info => createInferenceInfo(info.typeParameter)); + const inferences = ts.map(context.inferences, info => createInferenceInfo(info.typeParameter)); applyToParameterTypes(instantiatedSignature, contextualSignature, (source, target) => { inferTypes(inferences, source, target, /*priority*/ 0, /*contravariant*/ true); }); - if (some(inferences, hasInferenceCandidates)) { + if (ts.some(inferences, hasInferenceCandidates)) { // We have inference candidates, indicating that one or more type parameters are referenced // in the parameter types of the contextual signature. Now also infer from the return type. applyToReturnTypes(instantiatedSignature, contextualSignature, (source, target) => { @@ -34565,7 +33785,7 @@ namespace ts { // to the set of inferred type parameters for the outer function return type. if (!hasOverlappingInferences(context.inferences, inferences)) { mergeInferences(context.inferences, inferences); - context.inferredTypeParameters = concatenate(context.inferredTypeParameters, uniqueTypeParameters); + context.inferredTypeParameters = ts.concatenate(context.inferredTypeParameters, uniqueTypeParameters); return getOrCreateTypeFromSignature(instantiatedSignature); } } @@ -34578,20 +33798,20 @@ namespace ts { return type; } - function skippedGenericFunction(node: Node, checkMode: CheckMode) { + function skippedGenericFunction(node: ts.Node, checkMode: CheckMode) { if (checkMode & CheckMode.Inferential) { // We have skipped a generic function during inferential typing. Obtain the inference context and // indicate this has occurred such that we know a second pass of inference is be needed. const context = getInferenceContext(node)!; - context.flags |= InferenceFlags.SkippedGenericFunction; + context.flags |= ts.InferenceFlags.SkippedGenericFunction; } } - function hasInferenceCandidates(info: InferenceInfo) { + function hasInferenceCandidates(info: ts.InferenceInfo) { return !!(info.candidates || info.contraCandidates); } - function hasOverlappingInferences(a: InferenceInfo[], b: InferenceInfo[]) { + function hasOverlappingInferences(a: ts.InferenceInfo[], b: ts.InferenceInfo[]) { for (let i = 0; i < a.length; i++) { if (hasInferenceCandidates(a[i]) && hasInferenceCandidates(b[i])) { return true; @@ -34600,7 +33820,7 @@ namespace ts { return false; } - function mergeInferences(target: InferenceInfo[], source: InferenceInfo[]) { + function mergeInferences(target: ts.InferenceInfo[], source: ts.InferenceInfo[]) { for (let i = 0; i < target.length; i++) { if (!hasInferenceCandidates(target[i]) && hasInferenceCandidates(source[i])) { target[i] = source[i]; @@ -34608,19 +33828,19 @@ namespace ts { } } - function getUniqueTypeParameters(context: InferenceContext, typeParameters: readonly TypeParameter[]): readonly TypeParameter[] { - const result: TypeParameter[] = []; - let oldTypeParameters: TypeParameter[] | undefined; - let newTypeParameters: TypeParameter[] | undefined; + function getUniqueTypeParameters(context: ts.InferenceContext, typeParameters: readonly ts.TypeParameter[]): readonly ts.TypeParameter[] { + const result: ts.TypeParameter[] = []; + let oldTypeParameters: ts.TypeParameter[] | undefined; + let newTypeParameters: ts.TypeParameter[] | undefined; for (const tp of typeParameters) { const name = tp.symbol.escapedName; if (hasTypeParameterByName(context.inferredTypeParameters, name) || hasTypeParameterByName(result, name)) { - const newName = getUniqueTypeParameterName(concatenate(context.inferredTypeParameters, result), name); - const symbol = createSymbol(SymbolFlags.TypeParameter, newName); + const newName = getUniqueTypeParameterName(ts.concatenate(context.inferredTypeParameters, result), name); + const symbol = createSymbol(ts.SymbolFlags.TypeParameter, newName); const newTypeParameter = createTypeParameter(symbol); newTypeParameter.target = tp; - oldTypeParameters = append(oldTypeParameters, tp); - newTypeParameters = append(newTypeParameters, newTypeParameter); + oldTypeParameters = ts.append(oldTypeParameters, tp); + newTypeParameters = ts.append(newTypeParameters, newTypeParameter); result.push(newTypeParameter); } else { @@ -34636,30 +33856,31 @@ namespace ts { return result; } - function hasTypeParameterByName(typeParameters: readonly TypeParameter[] | undefined, name: __String) { - return some(typeParameters, tp => tp.symbol.escapedName === name); + function hasTypeParameterByName(typeParameters: readonly ts.TypeParameter[] | undefined, name: ts.__String) { + return ts.some(typeParameters, tp => tp.symbol.escapedName === name); } - function getUniqueTypeParameterName(typeParameters: readonly TypeParameter[], baseName: __String) { + function getUniqueTypeParameterName(typeParameters: readonly ts.TypeParameter[], baseName: ts.__String) { let len = (baseName as string).length; - while (len > 1 && (baseName as string).charCodeAt(len - 1) >= CharacterCodes._0 && (baseName as string).charCodeAt(len - 1) <= CharacterCodes._9) len--; + while (len > 1 && (baseName as string).charCodeAt(len - 1) >= ts.CharacterCodes._0 && (baseName as string).charCodeAt(len - 1) <= ts.CharacterCodes._9) + len--; const s = (baseName as string).slice(0, len); for (let index = 1; true; index++) { - const augmentedName = (s + index as __String); + const augmentedName = (s + index as ts.__String); if (!hasTypeParameterByName(typeParameters, augmentedName)) { return augmentedName; } } } - function getReturnTypeOfSingleNonGenericCallSignature(funcType: Type) { + function getReturnTypeOfSingleNonGenericCallSignature(funcType: ts.Type) { const signature = getSingleCallSignature(funcType); if (signature && !signature.typeParameters) { return getReturnTypeOfSignature(signature); } } - function getReturnTypeOfSingleNonGenericSignatureOfCallChain(expr: CallChain) { + function getReturnTypeOfSingleNonGenericSignatureOfCallChain(expr: ts.CallChain) { const funcType = checkExpression(expr.expression); const nonOptionalType = getOptionalExpressionType(funcType, expr.expression); const returnType = getReturnTypeOfSingleNonGenericCallSignature(funcType); @@ -34670,14 +33891,14 @@ namespace ts { * Returns the type of an expression. Unlike checkExpression, this function is simply concerned * with computing the type and may not fully check all contained sub-expressions for errors. */ - function getTypeOfExpression(node: Expression) { + function getTypeOfExpression(node: ts.Expression) { // Don't bother caching types that require no flow analysis and are quick to compute. const quickType = getQuickTypeOfExpression(node); if (quickType) { return quickType; } // If a type has been cached for the node, return it. - if (node.flags & NodeFlags.TypeCached && flowTypeCache) { + if (node.flags & ts.NodeFlags.TypeCached && flowTypeCache) { const cachedType = flowTypeCache[getNodeId(node)]; if (cachedType) { return cachedType; @@ -34689,34 +33910,34 @@ namespace ts { if (flowInvocationCount !== startInvocationCount) { const cache = flowTypeCache || (flowTypeCache = []); cache[getNodeId(node)] = type; - setNodeFlags(node, node.flags | NodeFlags.TypeCached); + ts.setNodeFlags(node, node.flags | ts.NodeFlags.TypeCached); } return type; } - function getQuickTypeOfExpression(node: Expression) { - let expr = skipParentheses(node, /*excludeJSDocTypeAssertions*/ true); - if (isJSDocTypeAssertion(expr)) { - const type = getJSDocTypeAssertionType(expr); - if (!isConstTypeReference(type)) { + function getQuickTypeOfExpression(node: ts.Expression) { + let expr = ts.skipParentheses(node, /*excludeJSDocTypeAssertions*/ true); + if (ts.isJSDocTypeAssertion(expr)) { + const type = ts.getJSDocTypeAssertionType(expr); + if (!ts.isConstTypeReference(type)) { return getTypeFromTypeNode(type); } } - expr = skipParentheses(node); + expr = ts.skipParentheses(node); // Optimize for the common case of a call to a function with a single non-generic call // signature where we can just fetch the return type without checking the arguments. - if (isCallExpression(expr) && expr.expression.kind !== SyntaxKind.SuperKeyword && !isRequireCall(expr, /*checkArgumentIsStringLiteralLike*/ true) && !isSymbolOrSymbolForCall(expr)) { - const type = isCallChain(expr) ? getReturnTypeOfSingleNonGenericSignatureOfCallChain(expr) : + if (ts.isCallExpression(expr) && expr.expression.kind !== ts.SyntaxKind.SuperKeyword && !ts.isRequireCall(expr, /*checkArgumentIsStringLiteralLike*/ true) && !isSymbolOrSymbolForCall(expr)) { + const type = ts.isCallChain(expr) ? getReturnTypeOfSingleNonGenericSignatureOfCallChain(expr) : getReturnTypeOfSingleNonGenericCallSignature(checkNonNullExpression(expr.expression)); if (type) { return type; } } - else if (isAssertionExpression(expr) && !isConstTypeReference(expr.type)) { - return getTypeFromTypeNode((expr as TypeAssertion).type); + else if (ts.isAssertionExpression(expr) && !ts.isConstTypeReference(expr.type)) { + return getTypeFromTypeNode((expr as ts.TypeAssertion).type); } - else if (node.kind === SyntaxKind.NumericLiteral || node.kind === SyntaxKind.StringLiteral || - node.kind === SyntaxKind.TrueKeyword || node.kind === SyntaxKind.FalseKeyword) { + else if (node.kind === ts.SyntaxKind.NumericLiteral || node.kind === ts.SyntaxKind.StringLiteral || + node.kind === ts.SyntaxKind.TrueKeyword || node.kind === ts.SyntaxKind.FalseKeyword) { return checkExpression(node); } return undefined; @@ -34729,7 +33950,7 @@ namespace ts { * and requesting the contextual type might cause a circularity or other bad behaviour. * It sets the contextual type of the node to any before calling getTypeOfExpression. */ - function getContextFreeTypeOfExpression(node: Expression) { + function getContextFreeTypeOfExpression(node: ts.Expression) { const links = getNodeLinks(node); if (links.contextFreeType) { return links.contextFreeType; @@ -34748,8 +33969,8 @@ namespace ts { } } - function checkExpression(node: Expression | QualifiedName, checkMode?: CheckMode, forceTuple?: boolean): Type { - tracing?.push(tracing.Phase.Check, "checkExpression", { kind: node.kind, pos: node.pos, end: node.end, path: (node as TracingNode).tracingPath }); + function checkExpression(node: ts.Expression | ts.QualifiedName, checkMode?: CheckMode, forceTuple?: boolean): ts.Type { + ts.tracing?.push(ts.tracing.Phase.Check, "checkExpression", { kind: node.kind, pos: node.pos, end: node.end, path: (node as ts.TracingNode).tracingPath }); const saveCurrentNode = currentNode; currentNode = node; instantiationCount = 0; @@ -34759,168 +33980,167 @@ namespace ts { checkConstEnumAccess(node, type); } currentNode = saveCurrentNode; - tracing?.pop(); + ts.tracing?.pop(); return type; } - function checkConstEnumAccess(node: Expression | QualifiedName, type: Type) { + function checkConstEnumAccess(node: ts.Expression | ts.QualifiedName, type: ts.Type) { // enum object type for const enums are only permitted in: // - 'left' in property access // - 'object' in indexed access // - target in rhs of import statement - const ok = - (node.parent.kind === SyntaxKind.PropertyAccessExpression && (node.parent as PropertyAccessExpression).expression === node) || - (node.parent.kind === SyntaxKind.ElementAccessExpression && (node.parent as ElementAccessExpression).expression === node) || - ((node.kind === SyntaxKind.Identifier || node.kind === SyntaxKind.QualifiedName) && isInRightSideOfImportOrExportAssignment(node as Identifier) || - (node.parent.kind === SyntaxKind.TypeQuery && (node.parent as TypeQueryNode).exprName === node)) || - (node.parent.kind === SyntaxKind.ExportSpecifier); // We allow reexporting const enums + const ok = (node.parent.kind === ts.SyntaxKind.PropertyAccessExpression && (node.parent as ts.PropertyAccessExpression).expression === node) || + (node.parent.kind === ts.SyntaxKind.ElementAccessExpression && (node.parent as ts.ElementAccessExpression).expression === node) || + ((node.kind === ts.SyntaxKind.Identifier || node.kind === ts.SyntaxKind.QualifiedName) && isInRightSideOfImportOrExportAssignment(node as ts.Identifier) || + (node.parent.kind === ts.SyntaxKind.TypeQuery && (node.parent as ts.TypeQueryNode).exprName === node)) || + (node.parent.kind === ts.SyntaxKind.ExportSpecifier); // We allow reexporting const enums if (!ok) { - error(node, Diagnostics.const_enums_can_only_be_used_in_property_or_index_access_expressions_or_the_right_hand_side_of_an_import_declaration_or_export_assignment_or_type_query); + error(node, ts.Diagnostics.const_enums_can_only_be_used_in_property_or_index_access_expressions_or_the_right_hand_side_of_an_import_declaration_or_export_assignment_or_type_query); } if (compilerOptions.isolatedModules) { - Debug.assert(!!(type.symbol.flags & SymbolFlags.ConstEnum)); - const constEnumDeclaration = type.symbol.valueDeclaration as EnumDeclaration; - if (constEnumDeclaration.flags & NodeFlags.Ambient) { - error(node, Diagnostics.Cannot_access_ambient_const_enums_when_the_isolatedModules_flag_is_provided); + ts.Debug.assert(!!(type.symbol.flags & ts.SymbolFlags.ConstEnum)); + const constEnumDeclaration = type.symbol.valueDeclaration as ts.EnumDeclaration; + if (constEnumDeclaration.flags & ts.NodeFlags.Ambient) { + error(node, ts.Diagnostics.Cannot_access_ambient_const_enums_when_the_isolatedModules_flag_is_provided); } } } - function checkParenthesizedExpression(node: ParenthesizedExpression, checkMode?: CheckMode): Type { - if (hasJSDocNodes(node) && isJSDocTypeAssertion(node)) { - const type = getJSDocTypeAssertionType(node); + function checkParenthesizedExpression(node: ts.ParenthesizedExpression, checkMode?: CheckMode): ts.Type { + if (ts.hasJSDocNodes(node) && ts.isJSDocTypeAssertion(node)) { + const type = ts.getJSDocTypeAssertionType(node); return checkAssertionWorker(type, type, node.expression, checkMode); } return checkExpression(node.expression, checkMode); } - function checkExpressionWorker(node: Expression | QualifiedName, checkMode: CheckMode | undefined, forceTuple?: boolean): Type { + function checkExpressionWorker(node: ts.Expression | ts.QualifiedName, checkMode: CheckMode | undefined, forceTuple?: boolean): ts.Type { const kind = node.kind; if (cancellationToken) { // Only bother checking on a few construct kinds. We don't want to be excessively // hitting the cancellation token on every node we check. switch (kind) { - case SyntaxKind.ClassExpression: - case SyntaxKind.FunctionExpression: - case SyntaxKind.ArrowFunction: + case ts.SyntaxKind.ClassExpression: + case ts.SyntaxKind.FunctionExpression: + case ts.SyntaxKind.ArrowFunction: cancellationToken.throwIfCancellationRequested(); } } switch (kind) { - case SyntaxKind.Identifier: - return checkIdentifier(node as Identifier, checkMode); - case SyntaxKind.PrivateIdentifier: - return checkPrivateIdentifierExpression(node as PrivateIdentifier); - case SyntaxKind.ThisKeyword: + case ts.SyntaxKind.Identifier: + return checkIdentifier(node as ts.Identifier, checkMode); + case ts.SyntaxKind.PrivateIdentifier: + return checkPrivateIdentifierExpression(node as ts.PrivateIdentifier); + case ts.SyntaxKind.ThisKeyword: return checkThisExpression(node); - case SyntaxKind.SuperKeyword: + case ts.SyntaxKind.SuperKeyword: return checkSuperExpression(node); - case SyntaxKind.NullKeyword: + case ts.SyntaxKind.NullKeyword: return nullWideningType; - case SyntaxKind.NoSubstitutionTemplateLiteral: - case SyntaxKind.StringLiteral: - return getFreshTypeOfLiteralType(getStringLiteralType((node as StringLiteralLike).text)); - case SyntaxKind.NumericLiteral: - checkGrammarNumericLiteral(node as NumericLiteral); - return getFreshTypeOfLiteralType(getNumberLiteralType(+(node as NumericLiteral).text)); - case SyntaxKind.BigIntLiteral: - checkGrammarBigIntLiteral(node as BigIntLiteral); + case ts.SyntaxKind.NoSubstitutionTemplateLiteral: + case ts.SyntaxKind.StringLiteral: + return getFreshTypeOfLiteralType(getStringLiteralType((node as ts.StringLiteralLike).text)); + case ts.SyntaxKind.NumericLiteral: + checkGrammarNumericLiteral(node as ts.NumericLiteral); + return getFreshTypeOfLiteralType(getNumberLiteralType(+(node as ts.NumericLiteral).text)); + case ts.SyntaxKind.BigIntLiteral: + checkGrammarBigIntLiteral(node as ts.BigIntLiteral); return getFreshTypeOfLiteralType(getBigIntLiteralType({ negative: false, - base10Value: parsePseudoBigInt((node as BigIntLiteral).text) + base10Value: ts.parsePseudoBigInt((node as ts.BigIntLiteral).text) })); - case SyntaxKind.TrueKeyword: + case ts.SyntaxKind.TrueKeyword: return trueType; - case SyntaxKind.FalseKeyword: + case ts.SyntaxKind.FalseKeyword: return falseType; - case SyntaxKind.TemplateExpression: - return checkTemplateExpression(node as TemplateExpression); - case SyntaxKind.RegularExpressionLiteral: + case ts.SyntaxKind.TemplateExpression: + return checkTemplateExpression(node as ts.TemplateExpression); + case ts.SyntaxKind.RegularExpressionLiteral: return globalRegExpType; - case SyntaxKind.ArrayLiteralExpression: - return checkArrayLiteral(node as ArrayLiteralExpression, checkMode, forceTuple); - case SyntaxKind.ObjectLiteralExpression: - return checkObjectLiteral(node as ObjectLiteralExpression, checkMode); - case SyntaxKind.PropertyAccessExpression: - return checkPropertyAccessExpression(node as PropertyAccessExpression, checkMode); - case SyntaxKind.QualifiedName: - return checkQualifiedName(node as QualifiedName, checkMode); - case SyntaxKind.ElementAccessExpression: - return checkIndexedAccess(node as ElementAccessExpression, checkMode); - case SyntaxKind.CallExpression: - if ((node as CallExpression).expression.kind === SyntaxKind.ImportKeyword) { - return checkImportCallExpression(node as ImportCall); + case ts.SyntaxKind.ArrayLiteralExpression: + return checkArrayLiteral(node as ts.ArrayLiteralExpression, checkMode, forceTuple); + case ts.SyntaxKind.ObjectLiteralExpression: + return checkObjectLiteral(node as ts.ObjectLiteralExpression, checkMode); + case ts.SyntaxKind.PropertyAccessExpression: + return checkPropertyAccessExpression(node as ts.PropertyAccessExpression, checkMode); + case ts.SyntaxKind.QualifiedName: + return checkQualifiedName(node as ts.QualifiedName, checkMode); + case ts.SyntaxKind.ElementAccessExpression: + return checkIndexedAccess(node as ts.ElementAccessExpression, checkMode); + case ts.SyntaxKind.CallExpression: + if ((node as ts.CallExpression).expression.kind === ts.SyntaxKind.ImportKeyword) { + return checkImportCallExpression(node as ts.ImportCall); } // falls through - case SyntaxKind.NewExpression: - return checkCallExpression(node as CallExpression, checkMode); - case SyntaxKind.TaggedTemplateExpression: - return checkTaggedTemplateExpression(node as TaggedTemplateExpression); - case SyntaxKind.ParenthesizedExpression: - return checkParenthesizedExpression(node as ParenthesizedExpression, checkMode); - case SyntaxKind.ClassExpression: - return checkClassExpression(node as ClassExpression); - case SyntaxKind.FunctionExpression: - case SyntaxKind.ArrowFunction: - return checkFunctionExpressionOrObjectLiteralMethod(node as FunctionExpression | ArrowFunction, checkMode); - case SyntaxKind.TypeOfExpression: - return checkTypeOfExpression(node as TypeOfExpression); - case SyntaxKind.TypeAssertionExpression: - case SyntaxKind.AsExpression: - return checkAssertion(node as AssertionExpression); - case SyntaxKind.NonNullExpression: - return checkNonNullAssertion(node as NonNullExpression); - case SyntaxKind.ExpressionWithTypeArguments: - return checkExpressionWithTypeArguments(node as ExpressionWithTypeArguments); - case SyntaxKind.MetaProperty: - return checkMetaProperty(node as MetaProperty); - case SyntaxKind.DeleteExpression: - return checkDeleteExpression(node as DeleteExpression); - case SyntaxKind.VoidExpression: - return checkVoidExpression(node as VoidExpression); - case SyntaxKind.AwaitExpression: - return checkAwaitExpression(node as AwaitExpression); - case SyntaxKind.PrefixUnaryExpression: - return checkPrefixUnaryExpression(node as PrefixUnaryExpression); - case SyntaxKind.PostfixUnaryExpression: - return checkPostfixUnaryExpression(node as PostfixUnaryExpression); - case SyntaxKind.BinaryExpression: - return checkBinaryExpression(node as BinaryExpression, checkMode); - case SyntaxKind.ConditionalExpression: - return checkConditionalExpression(node as ConditionalExpression, checkMode); - case SyntaxKind.SpreadElement: - return checkSpreadExpression(node as SpreadElement, checkMode); - case SyntaxKind.OmittedExpression: + case ts.SyntaxKind.NewExpression: + return checkCallExpression(node as ts.CallExpression, checkMode); + case ts.SyntaxKind.TaggedTemplateExpression: + return checkTaggedTemplateExpression(node as ts.TaggedTemplateExpression); + case ts.SyntaxKind.ParenthesizedExpression: + return checkParenthesizedExpression(node as ts.ParenthesizedExpression, checkMode); + case ts.SyntaxKind.ClassExpression: + return checkClassExpression(node as ts.ClassExpression); + case ts.SyntaxKind.FunctionExpression: + case ts.SyntaxKind.ArrowFunction: + return checkFunctionExpressionOrObjectLiteralMethod(node as ts.FunctionExpression | ts.ArrowFunction, checkMode); + case ts.SyntaxKind.TypeOfExpression: + return checkTypeOfExpression(node as ts.TypeOfExpression); + case ts.SyntaxKind.TypeAssertionExpression: + case ts.SyntaxKind.AsExpression: + return checkAssertion(node as ts.AssertionExpression); + case ts.SyntaxKind.NonNullExpression: + return checkNonNullAssertion(node as ts.NonNullExpression); + case ts.SyntaxKind.ExpressionWithTypeArguments: + return checkExpressionWithTypeArguments(node as ts.ExpressionWithTypeArguments); + case ts.SyntaxKind.MetaProperty: + return checkMetaProperty(node as ts.MetaProperty); + case ts.SyntaxKind.DeleteExpression: + return checkDeleteExpression(node as ts.DeleteExpression); + case ts.SyntaxKind.VoidExpression: + return checkVoidExpression(node as ts.VoidExpression); + case ts.SyntaxKind.AwaitExpression: + return checkAwaitExpression(node as ts.AwaitExpression); + case ts.SyntaxKind.PrefixUnaryExpression: + return checkPrefixUnaryExpression(node as ts.PrefixUnaryExpression); + case ts.SyntaxKind.PostfixUnaryExpression: + return checkPostfixUnaryExpression(node as ts.PostfixUnaryExpression); + case ts.SyntaxKind.BinaryExpression: + return checkBinaryExpression(node as ts.BinaryExpression, checkMode); + case ts.SyntaxKind.ConditionalExpression: + return checkConditionalExpression(node as ts.ConditionalExpression, checkMode); + case ts.SyntaxKind.SpreadElement: + return checkSpreadExpression(node as ts.SpreadElement, checkMode); + case ts.SyntaxKind.OmittedExpression: return undefinedWideningType; - case SyntaxKind.YieldExpression: - return checkYieldExpression(node as YieldExpression); - case SyntaxKind.SyntheticExpression: - return checkSyntheticExpression(node as SyntheticExpression); - case SyntaxKind.JsxExpression: - return checkJsxExpression(node as JsxExpression, checkMode); - case SyntaxKind.JsxElement: - return checkJsxElement(node as JsxElement, checkMode); - case SyntaxKind.JsxSelfClosingElement: - return checkJsxSelfClosingElement(node as JsxSelfClosingElement, checkMode); - case SyntaxKind.JsxFragment: - return checkJsxFragment(node as JsxFragment); - case SyntaxKind.JsxAttributes: - return checkJsxAttributes(node as JsxAttributes, checkMode); - case SyntaxKind.JsxOpeningElement: - Debug.fail("Shouldn't ever directly check a JsxOpeningElement"); + case ts.SyntaxKind.YieldExpression: + return checkYieldExpression(node as ts.YieldExpression); + case ts.SyntaxKind.SyntheticExpression: + return checkSyntheticExpression(node as ts.SyntheticExpression); + case ts.SyntaxKind.JsxExpression: + return checkJsxExpression(node as ts.JsxExpression, checkMode); + case ts.SyntaxKind.JsxElement: + return checkJsxElement(node as ts.JsxElement, checkMode); + case ts.SyntaxKind.JsxSelfClosingElement: + return checkJsxSelfClosingElement(node as ts.JsxSelfClosingElement, checkMode); + case ts.SyntaxKind.JsxFragment: + return checkJsxFragment(node as ts.JsxFragment); + case ts.SyntaxKind.JsxAttributes: + return checkJsxAttributes(node as ts.JsxAttributes, checkMode); + case ts.SyntaxKind.JsxOpeningElement: + ts.Debug.fail("Shouldn't ever directly check a JsxOpeningElement"); } return errorType; } // DECLARATION AND STATEMENT TYPE CHECKING - function checkTypeParameter(node: TypeParameterDeclaration) { + function checkTypeParameter(node: ts.TypeParameterDeclaration) { // Grammar Checking checkGrammarModifiers(node); if (node.expression) { - grammarErrorOnFirstToken(node.expression, Diagnostics.Type_expected); + grammarErrorOnFirstToken(node.expression, ts.Diagnostics.Type_expected); } checkSourceElement(node.constraint); @@ -34929,39 +34149,39 @@ namespace ts { // Resolve base constraint to reveal circularity errors getBaseConstraintOfType(typeParameter); if (!hasNonCircularTypeParameterDefault(typeParameter)) { - error(node.default, Diagnostics.Type_parameter_0_has_a_circular_default, typeToString(typeParameter)); + error(node.default, ts.Diagnostics.Type_parameter_0_has_a_circular_default, typeToString(typeParameter)); } const constraintType = getConstraintOfTypeParameter(typeParameter); const defaultType = getDefaultFromTypeParameter(typeParameter); if (constraintType && defaultType) { - checkTypeAssignableTo(defaultType, getTypeWithThisArgument(instantiateType(constraintType, makeUnaryTypeMapper(typeParameter, defaultType)), defaultType), node.default, Diagnostics.Type_0_does_not_satisfy_the_constraint_1); + checkTypeAssignableTo(defaultType, getTypeWithThisArgument(instantiateType(constraintType, makeUnaryTypeMapper(typeParameter, defaultType)), defaultType), node.default, ts.Diagnostics.Type_0_does_not_satisfy_the_constraint_1); } checkNodeDeferred(node); - addLazyDiagnostic(() => checkTypeNameIsReserved(node.name, Diagnostics.Type_parameter_name_cannot_be_0)); + addLazyDiagnostic(() => checkTypeNameIsReserved(node.name, ts.Diagnostics.Type_parameter_name_cannot_be_0)); } - function checkTypeParameterDeferred(node: TypeParameterDeclaration) { - if (isInterfaceDeclaration(node.parent) || isClassLike(node.parent) || isTypeAliasDeclaration(node.parent)) { + function checkTypeParameterDeferred(node: ts.TypeParameterDeclaration) { + if (ts.isInterfaceDeclaration(node.parent) || ts.isClassLike(node.parent) || ts.isTypeAliasDeclaration(node.parent)) { const typeParameter = getDeclaredTypeOfTypeParameter(getSymbolOfNode(node)); const modifiers = getVarianceModifiers(typeParameter); if (modifiers) { const symbol = getSymbolOfNode(node.parent); - if (isTypeAliasDeclaration(node.parent) && !(getObjectFlags(getDeclaredTypeOfSymbol(symbol)) & (ObjectFlags.Anonymous | ObjectFlags.Mapped))) { - error(node, Diagnostics.Variance_annotations_are_only_supported_in_type_aliases_for_object_function_constructor_and_mapped_types); + if (ts.isTypeAliasDeclaration(node.parent) && !(ts.getObjectFlags(getDeclaredTypeOfSymbol(symbol)) & (ts.ObjectFlags.Anonymous | ts.ObjectFlags.Mapped))) { + error(node, ts.Diagnostics.Variance_annotations_are_only_supported_in_type_aliases_for_object_function_constructor_and_mapped_types); } - else if (modifiers === ModifierFlags.In || modifiers === ModifierFlags.Out) { - const source = createMarkerType(symbol, typeParameter, modifiers === ModifierFlags.Out ? markerSubType : markerSuperType); - const target = createMarkerType(symbol, typeParameter, modifiers === ModifierFlags.Out ? markerSuperType : markerSubType); + else if (modifiers === ts.ModifierFlags.In || modifiers === ts.ModifierFlags.Out) { + const source = createMarkerType(symbol, typeParameter, modifiers === ts.ModifierFlags.Out ? markerSubType : markerSuperType); + const target = createMarkerType(symbol, typeParameter, modifiers === ts.ModifierFlags.Out ? markerSuperType : markerSubType); const saveVarianceTypeParameter = typeParameter; varianceTypeParameter = typeParameter; - checkTypeAssignableTo(source, target, node, Diagnostics.Type_0_is_not_assignable_to_type_1_as_implied_by_variance_annotation); + checkTypeAssignableTo(source, target, node, ts.Diagnostics.Type_0_is_not_assignable_to_type_1_as_implied_by_variance_annotation); varianceTypeParameter = saveVarianceTypeParameter; } } } } - function checkParameter(node: ParameterDeclaration) { + function checkParameter(node: ts.ParameterDeclaration) { // Grammar checking // It is a SyntaxError if the Identifier "eval" or the Identifier "arguments" occurs as the // Identifier in a PropertySetParameterList of a PropertyAssignment that is contained in strict code @@ -34969,45 +34189,45 @@ namespace ts { checkGrammarDecoratorsAndModifiers(node); checkVariableLikeDeclaration(node); - const func = getContainingFunction(node)!; - if (hasSyntacticModifier(node, ModifierFlags.ParameterPropertyModifier)) { - if (!(func.kind === SyntaxKind.Constructor && nodeIsPresent(func.body))) { - error(node, Diagnostics.A_parameter_property_is_only_allowed_in_a_constructor_implementation); + const func = ts.getContainingFunction(node)!; + if (ts.hasSyntacticModifier(node, ts.ModifierFlags.ParameterPropertyModifier)) { + if (!(func.kind === ts.SyntaxKind.Constructor && ts.nodeIsPresent(func.body))) { + error(node, ts.Diagnostics.A_parameter_property_is_only_allowed_in_a_constructor_implementation); } - if (func.kind === SyntaxKind.Constructor && isIdentifier(node.name) && node.name.escapedText === "constructor") { - error(node.name, Diagnostics.constructor_cannot_be_used_as_a_parameter_property_name); + if (func.kind === ts.SyntaxKind.Constructor && ts.isIdentifier(node.name) && node.name.escapedText === "constructor") { + error(node.name, ts.Diagnostics.constructor_cannot_be_used_as_a_parameter_property_name); } } - if (node.questionToken && isBindingPattern(node.name) && (func as FunctionLikeDeclaration).body) { - error(node, Diagnostics.A_binding_pattern_parameter_cannot_be_optional_in_an_implementation_signature); + if (node.questionToken && ts.isBindingPattern(node.name) && (func as ts.FunctionLikeDeclaration).body) { + error(node, ts.Diagnostics.A_binding_pattern_parameter_cannot_be_optional_in_an_implementation_signature); } - if (node.name && isIdentifier(node.name) && (node.name.escapedText === "this" || node.name.escapedText === "new")) { + if (node.name && ts.isIdentifier(node.name) && (node.name.escapedText === "this" || node.name.escapedText === "new")) { if (func.parameters.indexOf(node) !== 0) { - error(node, Diagnostics.A_0_parameter_must_be_the_first_parameter, node.name.escapedText as string); + error(node, ts.Diagnostics.A_0_parameter_must_be_the_first_parameter, node.name.escapedText as string); } - if (func.kind === SyntaxKind.Constructor || func.kind === SyntaxKind.ConstructSignature || func.kind === SyntaxKind.ConstructorType) { - error(node, Diagnostics.A_constructor_cannot_have_a_this_parameter); + if (func.kind === ts.SyntaxKind.Constructor || func.kind === ts.SyntaxKind.ConstructSignature || func.kind === ts.SyntaxKind.ConstructorType) { + error(node, ts.Diagnostics.A_constructor_cannot_have_a_this_parameter); } - if (func.kind === SyntaxKind.ArrowFunction) { - error(node, Diagnostics.An_arrow_function_cannot_have_a_this_parameter); + if (func.kind === ts.SyntaxKind.ArrowFunction) { + error(node, ts.Diagnostics.An_arrow_function_cannot_have_a_this_parameter); } - if (func.kind === SyntaxKind.GetAccessor || func.kind === SyntaxKind.SetAccessor) { - error(node, Diagnostics.get_and_set_accessors_cannot_declare_this_parameters); + if (func.kind === ts.SyntaxKind.GetAccessor || func.kind === ts.SyntaxKind.SetAccessor) { + error(node, ts.Diagnostics.get_and_set_accessors_cannot_declare_this_parameters); } } // Only check rest parameter type if it's not a binding pattern. Since binding patterns are // not allowed in a rest parameter, we already have an error from checkGrammarParameterList. - if (node.dotDotDotToken && !isBindingPattern(node.name) && !isTypeAssignableTo(getReducedType(getTypeOfSymbol(node.symbol)), anyReadonlyArrayType)) { - error(node, Diagnostics.A_rest_parameter_must_be_of_an_array_type); + if (node.dotDotDotToken && !ts.isBindingPattern(node.name) && !isTypeAssignableTo(getReducedType(getTypeOfSymbol(node.symbol)), anyReadonlyArrayType)) { + error(node, ts.Diagnostics.A_rest_parameter_must_be_of_an_array_type); } } - function checkTypePredicate(node: TypePredicateNode): void { + function checkTypePredicate(node: ts.TypePredicateNode): void { const parent = getTypePredicateParent(node); if (!parent) { // The parent must not be valid. - error(node, Diagnostics.A_type_predicate_is_only_allowed_in_return_type_position_for_functions_and_methods); + error(node, ts.Diagnostics.A_type_predicate_is_only_allowed_in_return_type_position_for_functions_and_methods); return; } @@ -35020,119 +34240,108 @@ namespace ts { checkSourceElement(node.type); const { parameterName } = node; - if (typePredicate.kind === TypePredicateKind.This || typePredicate.kind === TypePredicateKind.AssertsThis) { - getTypeFromThisTypeNode(parameterName as ThisTypeNode); + if (typePredicate.kind === ts.TypePredicateKind.This || typePredicate.kind === ts.TypePredicateKind.AssertsThis) { + getTypeFromThisTypeNode(parameterName as ts.ThisTypeNode); } else { if (typePredicate.parameterIndex >= 0) { if (signatureHasRestParameter(signature) && typePredicate.parameterIndex === signature.parameters.length - 1) { - error(parameterName, Diagnostics.A_type_predicate_cannot_reference_a_rest_parameter); + error(parameterName, ts.Diagnostics.A_type_predicate_cannot_reference_a_rest_parameter); } else { if (typePredicate.type) { - const leadingError = () => chainDiagnosticMessages(/*details*/ undefined, Diagnostics.A_type_predicate_s_type_must_be_assignable_to_its_parameter_s_type); - checkTypeAssignableTo(typePredicate.type, - getTypeOfSymbol(signature.parameters[typePredicate.parameterIndex]), - node.type, - /*headMessage*/ undefined, - leadingError); + const leadingError = () => ts.chainDiagnosticMessages(/*details*/ undefined, ts.Diagnostics.A_type_predicate_s_type_must_be_assignable_to_its_parameter_s_type); + checkTypeAssignableTo(typePredicate.type, getTypeOfSymbol(signature.parameters[typePredicate.parameterIndex]), node.type, + /*headMessage*/ undefined, leadingError); } } } else if (parameterName) { let hasReportedError = false; for (const { name } of parent.parameters) { - if (isBindingPattern(name) && + if (ts.isBindingPattern(name) && checkIfTypePredicateVariableIsDeclaredInBindingPattern(name, parameterName, typePredicate.parameterName)) { hasReportedError = true; break; } } if (!hasReportedError) { - error(node.parameterName, Diagnostics.Cannot_find_parameter_0, typePredicate.parameterName); + error(node.parameterName, ts.Diagnostics.Cannot_find_parameter_0, typePredicate.parameterName); } } } } - function getTypePredicateParent(node: Node): SignatureDeclaration | undefined { + function getTypePredicateParent(node: ts.Node): ts.SignatureDeclaration | undefined { switch (node.parent.kind) { - case SyntaxKind.ArrowFunction: - case SyntaxKind.CallSignature: - case SyntaxKind.FunctionDeclaration: - case SyntaxKind.FunctionExpression: - case SyntaxKind.FunctionType: - case SyntaxKind.MethodDeclaration: - case SyntaxKind.MethodSignature: - const parent = node.parent as SignatureDeclaration; + case ts.SyntaxKind.ArrowFunction: + case ts.SyntaxKind.CallSignature: + case ts.SyntaxKind.FunctionDeclaration: + case ts.SyntaxKind.FunctionExpression: + case ts.SyntaxKind.FunctionType: + case ts.SyntaxKind.MethodDeclaration: + case ts.SyntaxKind.MethodSignature: + const parent = node.parent as ts.SignatureDeclaration; if (node === parent.type) { return parent; } } } - function checkIfTypePredicateVariableIsDeclaredInBindingPattern( - pattern: BindingPattern, - predicateVariableNode: Node, - predicateVariableName: string) { + function checkIfTypePredicateVariableIsDeclaredInBindingPattern(pattern: ts.BindingPattern, predicateVariableNode: ts.Node, predicateVariableName: string) { for (const element of pattern.elements) { - if (isOmittedExpression(element)) { + if (ts.isOmittedExpression(element)) { continue; } const name = element.name; - if (name.kind === SyntaxKind.Identifier && name.escapedText === predicateVariableName) { - error(predicateVariableNode, - Diagnostics.A_type_predicate_cannot_reference_element_0_in_a_binding_pattern, - predicateVariableName); + if (name.kind === ts.SyntaxKind.Identifier && name.escapedText === predicateVariableName) { + error(predicateVariableNode, ts.Diagnostics.A_type_predicate_cannot_reference_element_0_in_a_binding_pattern, predicateVariableName); return true; } - else if (name.kind === SyntaxKind.ArrayBindingPattern || name.kind === SyntaxKind.ObjectBindingPattern) { - if (checkIfTypePredicateVariableIsDeclaredInBindingPattern( - name, - predicateVariableNode, - predicateVariableName)) { + else if (name.kind === ts.SyntaxKind.ArrayBindingPattern || name.kind === ts.SyntaxKind.ObjectBindingPattern) { + if (checkIfTypePredicateVariableIsDeclaredInBindingPattern(name, predicateVariableNode, predicateVariableName)) { return true; } } } } - function checkSignatureDeclaration(node: SignatureDeclaration) { + function checkSignatureDeclaration(node: ts.SignatureDeclaration) { // Grammar checking - if (node.kind === SyntaxKind.IndexSignature) { - checkGrammarIndexSignature(node as SignatureDeclaration); + if (node.kind === ts.SyntaxKind.IndexSignature) { + checkGrammarIndexSignature(node as ts.SignatureDeclaration); } // TODO (yuisu): Remove this check in else-if when SyntaxKind.Construct is moved and ambient context is handled - else if (node.kind === SyntaxKind.FunctionType || node.kind === SyntaxKind.FunctionDeclaration || node.kind === SyntaxKind.ConstructorType || - node.kind === SyntaxKind.CallSignature || node.kind === SyntaxKind.Constructor || - node.kind === SyntaxKind.ConstructSignature) { - checkGrammarFunctionLikeDeclaration(node as FunctionLikeDeclaration); + else if (node.kind === ts.SyntaxKind.FunctionType || node.kind === ts.SyntaxKind.FunctionDeclaration || node.kind === ts.SyntaxKind.ConstructorType || + node.kind === ts.SyntaxKind.CallSignature || node.kind === ts.SyntaxKind.Constructor || + node.kind === ts.SyntaxKind.ConstructSignature) { + checkGrammarFunctionLikeDeclaration(node as ts.FunctionLikeDeclaration); } - const functionFlags = getFunctionFlags(node as FunctionLikeDeclaration); - if (!(functionFlags & FunctionFlags.Invalid)) { + const functionFlags = ts.getFunctionFlags(node as ts.FunctionLikeDeclaration); + if (!(functionFlags & ts.FunctionFlags.Invalid)) { // Async generators prior to ESNext require the __await and __asyncGenerator helpers - if ((functionFlags & FunctionFlags.AsyncGenerator) === FunctionFlags.AsyncGenerator && languageVersion < ScriptTarget.ESNext) { - checkExternalEmitHelpers(node, ExternalEmitHelpers.AsyncGeneratorIncludes); + if ((functionFlags & ts.FunctionFlags.AsyncGenerator) === ts.FunctionFlags.AsyncGenerator && languageVersion < ts.ScriptTarget.ESNext) { + checkExternalEmitHelpers(node, ts.ExternalEmitHelpers.AsyncGeneratorIncludes); } // Async functions prior to ES2017 require the __awaiter helper - if ((functionFlags & FunctionFlags.AsyncGenerator) === FunctionFlags.Async && languageVersion < ScriptTarget.ES2017) { - checkExternalEmitHelpers(node, ExternalEmitHelpers.Awaiter); + if ((functionFlags & ts.FunctionFlags.AsyncGenerator) === ts.FunctionFlags.Async && languageVersion < ts.ScriptTarget.ES2017) { + checkExternalEmitHelpers(node, ts.ExternalEmitHelpers.Awaiter); } // Generator functions, Async functions, and Async Generator functions prior to // ES2015 require the __generator helper - if ((functionFlags & FunctionFlags.AsyncGenerator) !== FunctionFlags.Normal && languageVersion < ScriptTarget.ES2015) { - checkExternalEmitHelpers(node, ExternalEmitHelpers.Generator); + if ((functionFlags & ts.FunctionFlags.AsyncGenerator) !== ts.FunctionFlags.Normal && languageVersion < ts.ScriptTarget.ES2015) { + checkExternalEmitHelpers(node, ts.ExternalEmitHelpers.Generator); } } - checkTypeParameters(getEffectiveTypeParameterDeclarations(node)); + checkTypeParameters(ts.getEffectiveTypeParameterDeclarations(node)); checkUnmatchedJSDocParameters(node); - forEach(node.parameters, checkParameter); + ts.forEach(node.parameters, checkParameter); // TODO(rbuckton): Should we start checking JSDoc types? if (node.type) { @@ -35143,24 +34352,24 @@ namespace ts { function checkSignatureDeclarationDiagnostics() { checkCollisionWithArgumentsInGeneratedCode(node); - const returnTypeNode = getEffectiveReturnTypeNode(node); + const returnTypeNode = ts.getEffectiveReturnTypeNode(node); if (noImplicitAny && !returnTypeNode) { switch (node.kind) { - case SyntaxKind.ConstructSignature: - error(node, Diagnostics.Construct_signature_which_lacks_return_type_annotation_implicitly_has_an_any_return_type); + case ts.SyntaxKind.ConstructSignature: + error(node, ts.Diagnostics.Construct_signature_which_lacks_return_type_annotation_implicitly_has_an_any_return_type); break; - case SyntaxKind.CallSignature: - error(node, Diagnostics.Call_signature_which_lacks_return_type_annotation_implicitly_has_an_any_return_type); + case ts.SyntaxKind.CallSignature: + error(node, ts.Diagnostics.Call_signature_which_lacks_return_type_annotation_implicitly_has_an_any_return_type); break; } } if (returnTypeNode) { - const functionFlags = getFunctionFlags(node as FunctionDeclaration); - if ((functionFlags & (FunctionFlags.Invalid | FunctionFlags.Generator)) === FunctionFlags.Generator) { + const functionFlags = ts.getFunctionFlags(node as ts.FunctionDeclaration); + if ((functionFlags & (ts.FunctionFlags.Invalid | ts.FunctionFlags.Generator)) === ts.FunctionFlags.Generator) { const returnType = getTypeFromTypeNode(returnTypeNode); if (returnType === voidType) { - error(returnTypeNode, Diagnostics.A_generator_cannot_have_a_void_type_annotation); + error(returnTypeNode, ts.Diagnostics.A_generator_cannot_have_a_void_type_annotation); } else { // Naively, one could check that Generator is assignable to the return type annotation. @@ -35169,65 +34378,64 @@ namespace ts { // interface BadGenerator extends Iterable, Iterator { } // function* g(): BadGenerator { } // Iterable and Iterator have different types! // - const generatorYieldType = getIterationTypeOfGeneratorFunctionReturnType(IterationTypeKind.Yield, returnType, (functionFlags & FunctionFlags.Async) !== 0) || anyType; - const generatorReturnType = getIterationTypeOfGeneratorFunctionReturnType(IterationTypeKind.Return, returnType, (functionFlags & FunctionFlags.Async) !== 0) || generatorYieldType; - const generatorNextType = getIterationTypeOfGeneratorFunctionReturnType(IterationTypeKind.Next, returnType, (functionFlags & FunctionFlags.Async) !== 0) || unknownType; - const generatorInstantiation = createGeneratorReturnType(generatorYieldType, generatorReturnType, generatorNextType, !!(functionFlags & FunctionFlags.Async)); + const generatorYieldType = getIterationTypeOfGeneratorFunctionReturnType(IterationTypeKind.Yield, returnType, (functionFlags & ts.FunctionFlags.Async) !== 0) || anyType; + const generatorReturnType = getIterationTypeOfGeneratorFunctionReturnType(IterationTypeKind.Return, returnType, (functionFlags & ts.FunctionFlags.Async) !== 0) || generatorYieldType; + const generatorNextType = getIterationTypeOfGeneratorFunctionReturnType(IterationTypeKind.Next, returnType, (functionFlags & ts.FunctionFlags.Async) !== 0) || unknownType; + const generatorInstantiation = createGeneratorReturnType(generatorYieldType, generatorReturnType, generatorNextType, !!(functionFlags & ts.FunctionFlags.Async)); checkTypeAssignableTo(generatorInstantiation, returnType, returnTypeNode); } } - else if ((functionFlags & FunctionFlags.AsyncGenerator) === FunctionFlags.Async) { - checkAsyncFunctionReturnType(node as FunctionLikeDeclaration, returnTypeNode); + else if ((functionFlags & ts.FunctionFlags.AsyncGenerator) === ts.FunctionFlags.Async) { + checkAsyncFunctionReturnType(node as ts.FunctionLikeDeclaration, returnTypeNode); } } - if (node.kind !== SyntaxKind.IndexSignature && node.kind !== SyntaxKind.JSDocFunctionType) { + if (node.kind !== ts.SyntaxKind.IndexSignature && node.kind !== ts.SyntaxKind.JSDocFunctionType) { registerForUnusedIdentifiersCheck(node); } } } - function checkClassForDuplicateDeclarations(node: ClassLikeDeclaration) { - const instanceNames = new Map<__String, DeclarationMeaning>(); - const staticNames = new Map<__String, DeclarationMeaning>(); + function checkClassForDuplicateDeclarations(node: ts.ClassLikeDeclaration) { + const instanceNames = new ts.Map(); + const staticNames = new ts.Map(); // instance and static private identifiers share the same scope - const privateIdentifiers = new Map<__String, DeclarationMeaning>(); + const privateIdentifiers = new ts.Map(); for (const member of node.members) { - if (member.kind === SyntaxKind.Constructor) { - for (const param of (member as ConstructorDeclaration).parameters) { - if (isParameterPropertyDeclaration(param, member) && !isBindingPattern(param.name)) { + if (member.kind === ts.SyntaxKind.Constructor) { + for (const param of (member as ts.ConstructorDeclaration).parameters) { + if (ts.isParameterPropertyDeclaration(param, member) && !ts.isBindingPattern(param.name)) { addName(instanceNames, param.name, param.name.escapedText, DeclarationMeaning.GetOrSetAccessor); } } } else { - const isStaticMember = isStatic(member); + const isStaticMember = ts.isStatic(member); const name = member.name; if (!name) { continue; } - const isPrivate = isPrivateIdentifier(name); + const isPrivate = ts.isPrivateIdentifier(name); const privateStaticFlags = isPrivate && isStaticMember ? DeclarationMeaning.PrivateStatic : 0; - const names = - isPrivate ? privateIdentifiers : + const names = isPrivate ? privateIdentifiers : isStaticMember ? staticNames : instanceNames; - const memberName = name && getPropertyNameForPropertyNameNode(name); + const memberName = name && ts.getPropertyNameForPropertyNameNode(name); if (memberName) { switch (member.kind) { - case SyntaxKind.GetAccessor: + case ts.SyntaxKind.GetAccessor: addName(names, name, memberName, DeclarationMeaning.GetAccessor | privateStaticFlags); break; - case SyntaxKind.SetAccessor: + case ts.SyntaxKind.SetAccessor: addName(names, name, memberName, DeclarationMeaning.SetAccessor | privateStaticFlags); break; - case SyntaxKind.PropertyDeclaration: + case ts.SyntaxKind.PropertyDeclaration: addName(names, name, memberName, DeclarationMeaning.GetOrSetAccessor | privateStaticFlags); break; - case SyntaxKind.MethodDeclaration: + case ts.SyntaxKind.MethodDeclaration: addName(names, name, memberName, DeclarationMeaning.Method | privateStaticFlags); break; } @@ -35235,24 +34443,24 @@ namespace ts { } } - function addName(names: UnderscoreEscapedMap, location: Node, name: __String, meaning: DeclarationMeaning) { + function addName(names: ts.UnderscoreEscapedMap, location: ts.Node, name: ts.__String, meaning: DeclarationMeaning) { const prev = names.get(name); if (prev) { // For private identifiers, do not allow mixing of static and instance members with the same name if ((prev & DeclarationMeaning.PrivateStatic) !== (meaning & DeclarationMeaning.PrivateStatic)) { - error(location, Diagnostics.Duplicate_identifier_0_Static_and_instance_elements_cannot_share_the_same_private_name, getTextOfNode(location)); + error(location, ts.Diagnostics.Duplicate_identifier_0_Static_and_instance_elements_cannot_share_the_same_private_name, ts.getTextOfNode(location)); } else { const prevIsMethod = !!(prev & DeclarationMeaning.Method); const isMethod = !!(meaning & DeclarationMeaning.Method); if (prevIsMethod || isMethod) { if (prevIsMethod !== isMethod) { - error(location, Diagnostics.Duplicate_identifier_0, getTextOfNode(location)); + error(location, ts.Diagnostics.Duplicate_identifier_0, ts.getTextOfNode(location)); } // If this is a method/method duplication is might be an overload, so this will be handled when overloads are considered } else if (prev & meaning & ~DeclarationMeaning.PrivateStatic) { - error(location, Diagnostics.Duplicate_identifier_0, getTextOfNode(location)); + error(location, ts.Diagnostics.Duplicate_identifier_0, ts.getTextOfNode(location)); } else { names.set(name, prev | meaning); @@ -35276,19 +34484,19 @@ namespace ts { * @see http://www.ecma-international.org/ecma-262/6.0/#sec-properties-of-the-function-constructor * @see http://www.ecma-international.org/ecma-262/6.0/#sec-function-instances */ - function checkClassForStaticPropertyNameConflicts(node: ClassLikeDeclaration) { + function checkClassForStaticPropertyNameConflicts(node: ts.ClassLikeDeclaration) { for (const member of node.members) { const memberNameNode = member.name; - const isStaticMember = isStatic(member); + const isStaticMember = ts.isStatic(member); if (isStaticMember && memberNameNode) { - const memberName = getPropertyNameForPropertyNameNode(memberNameNode); + const memberName = ts.getPropertyNameForPropertyNameNode(memberNameNode); switch (memberName) { case "name": case "length": case "caller": case "arguments": case "prototype": - const message = Diagnostics.Static_property_0_conflicts_with_built_in_property_Function_0_of_constructor_function_1; + const message = ts.Diagnostics.Static_property_0_conflicts_with_built_in_property_Function_0_of_constructor_function_1; const className = getNameOfSymbolAsWritten(getSymbolOfNode(node)); error(memberNameNode, message, memberName, className); break; @@ -35297,27 +34505,27 @@ namespace ts { } } - function checkObjectTypeForDuplicateDeclarations(node: TypeLiteralNode | InterfaceDeclaration) { - const names = new Map(); + function checkObjectTypeForDuplicateDeclarations(node: ts.TypeLiteralNode | ts.InterfaceDeclaration) { + const names = new ts.Map(); for (const member of node.members) { - if (member.kind === SyntaxKind.PropertySignature) { + if (member.kind === ts.SyntaxKind.PropertySignature) { let memberName: string; const name = member.name!; switch (name.kind) { - case SyntaxKind.StringLiteral: - case SyntaxKind.NumericLiteral: + case ts.SyntaxKind.StringLiteral: + case ts.SyntaxKind.NumericLiteral: memberName = name.text; break; - case SyntaxKind.Identifier: - memberName = idText(name); + case ts.SyntaxKind.Identifier: + memberName = ts.idText(name); break; default: continue; } if (names.get(memberName)) { - error(getNameOfDeclaration(member.symbol.valueDeclaration), Diagnostics.Duplicate_identifier_0, memberName); - error(member.name, Diagnostics.Duplicate_identifier_0, memberName); + error(ts.getNameOfDeclaration(member.symbol.valueDeclaration), ts.Diagnostics.Duplicate_identifier_0, memberName); + error(member.name, ts.Diagnostics.Duplicate_identifier_0, memberName); } else { names.set(memberName, true); @@ -35326,9 +34534,9 @@ namespace ts { } } - function checkTypeForDuplicateIndexSignatures(node: Node) { - if (node.kind === SyntaxKind.InterfaceDeclaration) { - const nodeSymbol = getSymbolOfNode(node as InterfaceDeclaration); + function checkTypeForDuplicateIndexSignatures(node: ts.Node) { + if (node.kind === ts.SyntaxKind.InterfaceDeclaration) { + const nodeSymbol = getSymbolOfNode(node as ts.InterfaceDeclaration); // in case of merging interface declaration it is possible that we'll enter this check procedure several times for every declaration // to prevent this run check only for the first declaration of a given kind if (nodeSymbol.declarations && nodeSymbol.declarations.length > 0 && nodeSymbol.declarations[0] !== node) { @@ -35341,8 +34549,11 @@ namespace ts { // 8.5: A class declaration can have at most one string index member declaration and one numeric index member declaration const indexSymbol = getIndexSymbol(getSymbolOfNode(node)!); if (indexSymbol?.declarations) { - const indexSignatureMap = new Map(); - for (const declaration of (indexSymbol.declarations as IndexSignatureDeclaration[])) { + const indexSignatureMap = new ts.Map(); + for (const declaration of (indexSymbol.declarations as ts.IndexSignatureDeclaration[])) { if (declaration.parameters.length === 1 && declaration.parameters[0].type) { forEachType(getTypeFromTypeNode(declaration.parameters[0].type), type => { const entry = indexSignatureMap.get(getTypeId(type)); @@ -35358,88 +34569,91 @@ namespace ts { indexSignatureMap.forEach(entry => { if (entry.declarations.length > 1) { for (const declaration of entry.declarations) { - error(declaration, Diagnostics.Duplicate_index_signature_for_type_0, typeToString(entry.type)); + error(declaration, ts.Diagnostics.Duplicate_index_signature_for_type_0, typeToString(entry.type)); } } }); } } - function checkPropertyDeclaration(node: PropertyDeclaration | PropertySignature) { + function checkPropertyDeclaration(node: ts.PropertyDeclaration | ts.PropertySignature) { // Grammar checking - if (!checkGrammarDecoratorsAndModifiers(node) && !checkGrammarProperty(node)) checkGrammarComputedPropertyName(node.name); + if (!checkGrammarDecoratorsAndModifiers(node) && !checkGrammarProperty(node)) + checkGrammarComputedPropertyName(node.name); checkVariableLikeDeclaration(node); setNodeLinksForPrivateIdentifierScope(node); // property signatures already report "initializer not allowed in ambient context" elsewhere - if (hasSyntacticModifier(node, ModifierFlags.Abstract) && node.kind === SyntaxKind.PropertyDeclaration && node.initializer) { - error(node, Diagnostics.Property_0_cannot_have_an_initializer_because_it_is_marked_abstract, declarationNameToString(node.name)); + if (ts.hasSyntacticModifier(node, ts.ModifierFlags.Abstract) && node.kind === ts.SyntaxKind.PropertyDeclaration && node.initializer) { + error(node, ts.Diagnostics.Property_0_cannot_have_an_initializer_because_it_is_marked_abstract, ts.declarationNameToString(node.name)); } } - function checkPropertySignature(node: PropertySignature) { - if (isPrivateIdentifier(node.name)) { - error(node, Diagnostics.Private_identifiers_are_not_allowed_outside_class_bodies); + function checkPropertySignature(node: ts.PropertySignature) { + if (ts.isPrivateIdentifier(node.name)) { + error(node, ts.Diagnostics.Private_identifiers_are_not_allowed_outside_class_bodies); } return checkPropertyDeclaration(node); } - function checkMethodDeclaration(node: MethodDeclaration | MethodSignature) { + function checkMethodDeclaration(node: ts.MethodDeclaration | ts.MethodSignature) { // Grammar checking - if (!checkGrammarMethod(node)) checkGrammarComputedPropertyName(node.name); + if (!checkGrammarMethod(node)) + checkGrammarComputedPropertyName(node.name); // Grammar checking for modifiers is done inside the function checkGrammarFunctionLikeDeclaration checkFunctionOrMethodDeclaration(node); // method signatures already report "implementation not allowed in ambient context" elsewhere - if (hasSyntacticModifier(node, ModifierFlags.Abstract) && node.kind === SyntaxKind.MethodDeclaration && node.body) { - error(node, Diagnostics.Method_0_cannot_have_an_implementation_because_it_is_marked_abstract, declarationNameToString(node.name)); + if (ts.hasSyntacticModifier(node, ts.ModifierFlags.Abstract) && node.kind === ts.SyntaxKind.MethodDeclaration && node.body) { + error(node, ts.Diagnostics.Method_0_cannot_have_an_implementation_because_it_is_marked_abstract, ts.declarationNameToString(node.name)); } // Private named methods are only allowed in class declarations - if (isPrivateIdentifier(node.name) && !getContainingClass(node)) { - error(node, Diagnostics.Private_identifiers_are_not_allowed_outside_class_bodies); + if (ts.isPrivateIdentifier(node.name) && !ts.getContainingClass(node)) { + error(node, ts.Diagnostics.Private_identifiers_are_not_allowed_outside_class_bodies); } setNodeLinksForPrivateIdentifierScope(node); } - function setNodeLinksForPrivateIdentifierScope(node: PropertyDeclaration | PropertySignature | MethodDeclaration | MethodSignature | AccessorDeclaration) { - if (isPrivateIdentifier(node.name) && languageVersion < ScriptTarget.ESNext) { - for (let lexicalScope = getEnclosingBlockScopeContainer(node); !!lexicalScope; lexicalScope = getEnclosingBlockScopeContainer(lexicalScope)) { - getNodeLinks(lexicalScope).flags |= NodeCheckFlags.ContainsClassWithPrivateIdentifiers; + function setNodeLinksForPrivateIdentifierScope(node: ts.PropertyDeclaration | ts.PropertySignature | ts.MethodDeclaration | ts.MethodSignature | ts.AccessorDeclaration) { + if (ts.isPrivateIdentifier(node.name) && languageVersion < ts.ScriptTarget.ESNext) { + for (let lexicalScope = ts.getEnclosingBlockScopeContainer(node); !!lexicalScope; lexicalScope = ts.getEnclosingBlockScopeContainer(lexicalScope)) { + getNodeLinks(lexicalScope).flags |= ts.NodeCheckFlags.ContainsClassWithPrivateIdentifiers; } // If this is a private element in a class expression inside the body of a loop, // then we must use a block-scoped binding to store the additional variables required // to transform private elements. - if (isClassExpression(node.parent)) { + if (ts.isClassExpression(node.parent)) { const enclosingIterationStatement = getEnclosingIterationStatement(node.parent); if (enclosingIterationStatement) { - getNodeLinks(node.name).flags |= NodeCheckFlags.BlockScopedBindingInLoop; - getNodeLinks(enclosingIterationStatement).flags |= NodeCheckFlags.LoopWithCapturedBlockScopedBinding; + getNodeLinks(node.name).flags |= ts.NodeCheckFlags.BlockScopedBindingInLoop; + getNodeLinks(enclosingIterationStatement).flags |= ts.NodeCheckFlags.LoopWithCapturedBlockScopedBinding; } } } } - function checkClassStaticBlockDeclaration(node: ClassStaticBlockDeclaration) { + function checkClassStaticBlockDeclaration(node: ts.ClassStaticBlockDeclaration) { checkGrammarDecoratorsAndModifiers(node); - forEachChild(node, checkSourceElement); + ts.forEachChild(node, checkSourceElement); } - function checkConstructorDeclaration(node: ConstructorDeclaration) { + function checkConstructorDeclaration(node: ts.ConstructorDeclaration) { // Grammar check on signature of constructor and modifier of the constructor is done in checkSignatureDeclaration function. checkSignatureDeclaration(node); // Grammar check for checking only related to constructorDeclaration - if (!checkGrammarConstructorTypeParameters(node)) checkGrammarConstructorTypeAnnotation(node); + if (!checkGrammarConstructorTypeParameters(node)) + checkGrammarConstructorTypeAnnotation(node); checkSourceElement(node.body); const symbol = getSymbolOfNode(node); - const firstDeclaration = getDeclarationOfKind(symbol, node.kind); + const firstDeclaration = ts.getDeclarationOfKind(symbol, node.kind); // Only type check the symbol once if (node === firstDeclaration) { @@ -35447,7 +34661,7 @@ namespace ts { } // exit early in the case of signature - super checks are not relevant to them - if (nodeIsMissing(node.body)) { + if (ts.nodeIsMissing(node.body)) { return; } @@ -35455,27 +34669,27 @@ namespace ts { return; - function isInstancePropertyWithInitializerOrPrivateIdentifierProperty(n: Node): boolean { - if (isPrivateIdentifierClassElementDeclaration(n)) { + function isInstancePropertyWithInitializerOrPrivateIdentifierProperty(n: ts.Node): boolean { + if (ts.isPrivateIdentifierClassElementDeclaration(n)) { return true; } - return n.kind === SyntaxKind.PropertyDeclaration && - !isStatic(n) && - !!(n as PropertyDeclaration).initializer; + return n.kind === ts.SyntaxKind.PropertyDeclaration && + !ts.isStatic(n) && + !!(n as ts.PropertyDeclaration).initializer; } function checkConstructorDeclarationDiagnostics() { // TS 1.0 spec (April 2014): 8.3.2 // Constructors of classes with no extends clause may not contain super calls, whereas // constructors of derived classes must contain at least one super call somewhere in their function body. - const containingClassDecl = node.parent as ClassDeclaration; - if (getClassExtendsHeritageElement(containingClassDecl)) { + const containingClassDecl = node.parent as ts.ClassDeclaration; + if (ts.getClassExtendsHeritageElement(containingClassDecl)) { captureLexicalThis(node.parent, containingClassDecl); const classExtendsNull = classDeclarationExtendsNull(containingClassDecl); const superCall = findFirstSuperCall(node.body!); if (superCall) { if (classExtendsNull) { - error(superCall, Diagnostics.A_constructor_cannot_contain_a_super_call_when_its_class_extends_null); + error(superCall, ts.Diagnostics.A_constructor_cannot_contain_a_super_call_when_its_class_extends_null); } // A super call must be root-level in a constructor if both of the following are true: @@ -35483,23 +34697,22 @@ namespace ts { // - The constructor declares parameter properties // or the containing class declares instance member variables with initializers. - const superCallShouldBeRootLevel = - (getEmitScriptTarget(compilerOptions) !== ScriptTarget.ESNext || !useDefineForClassFields) && - (some((node.parent as ClassDeclaration).members, isInstancePropertyWithInitializerOrPrivateIdentifierProperty) || - some(node.parameters, p => hasSyntacticModifier(p, ModifierFlags.ParameterPropertyModifier))); + const superCallShouldBeRootLevel = (ts.getEmitScriptTarget(compilerOptions) !== ts.ScriptTarget.ESNext || !useDefineForClassFields) && + (ts.some((node.parent as ts.ClassDeclaration).members, isInstancePropertyWithInitializerOrPrivateIdentifierProperty) || + ts.some(node.parameters, p => ts.hasSyntacticModifier(p, ts.ModifierFlags.ParameterPropertyModifier))); if (superCallShouldBeRootLevel) { // Until we have better flow analysis, it is an error to place the super call within any kind of block or conditional // See GH #8277 if (!superCallIsRootLevelInConstructor(superCall, node.body!)) { - error(superCall, Diagnostics.A_super_call_must_be_a_root_level_statement_within_a_constructor_of_a_derived_class_that_contains_initialized_properties_parameter_properties_or_private_identifiers); + error(superCall, ts.Diagnostics.A_super_call_must_be_a_root_level_statement_within_a_constructor_of_a_derived_class_that_contains_initialized_properties_parameter_properties_or_private_identifiers); } // Skip past any prologue directives to check statements for referring to 'super' or 'this' before a super call else { - let superCallStatement: ExpressionStatement | undefined; + let superCallStatement: ts.ExpressionStatement | undefined; for (const statement of node.body!.statements) { - if (isExpressionStatement(statement) && isSuperCall(skipOuterExpressions(statement.expression))) { + if (ts.isExpressionStatement(statement) && ts.isSuperCall(ts.skipOuterExpressions(statement.expression))) { superCallStatement = statement; break; } @@ -35511,57 +34724,58 @@ namespace ts { // Until we have better flow analysis, it is an error to place the super call within any kind of block or conditional // See GH #8277 if (superCallStatement === undefined) { - error(node, Diagnostics.A_super_call_must_be_the_first_statement_in_the_constructor_to_refer_to_super_or_this_when_a_derived_class_contains_initialized_properties_parameter_properties_or_private_identifiers); + error(node, ts.Diagnostics.A_super_call_must_be_the_first_statement_in_the_constructor_to_refer_to_super_or_this_when_a_derived_class_contains_initialized_properties_parameter_properties_or_private_identifiers); } } } } else if (!classExtendsNull) { - error(node, Diagnostics.Constructors_for_derived_classes_must_contain_a_super_call); + error(node, ts.Diagnostics.Constructors_for_derived_classes_must_contain_a_super_call); } } } } - function superCallIsRootLevelInConstructor(superCall: Node, body: Block) { - const superCallParent = walkUpParenthesizedExpressions(superCall.parent); - return isExpressionStatement(superCallParent) && superCallParent.parent === body; + function superCallIsRootLevelInConstructor(superCall: ts.Node, body: ts.Block) { + const superCallParent = ts.walkUpParenthesizedExpressions(superCall.parent); + return ts.isExpressionStatement(superCallParent) && superCallParent.parent === body; } - function nodeImmediatelyReferencesSuperOrThis(node: Node): boolean { - if (node.kind === SyntaxKind.SuperKeyword || node.kind === SyntaxKind.ThisKeyword) { + function nodeImmediatelyReferencesSuperOrThis(node: ts.Node): boolean { + if (node.kind === ts.SyntaxKind.SuperKeyword || node.kind === ts.SyntaxKind.ThisKeyword) { return true; } - if (isThisContainerOrFunctionBlock(node)) { + if (ts.isThisContainerOrFunctionBlock(node)) { return false; } - return !!forEachChild(node, nodeImmediatelyReferencesSuperOrThis); + return !!ts.forEachChild(node, nodeImmediatelyReferencesSuperOrThis); } - function checkAccessorDeclaration(node: AccessorDeclaration) { + function checkAccessorDeclaration(node: ts.AccessorDeclaration) { addLazyDiagnostic(checkAccessorDeclarationDiagnostics); checkSourceElement(node.body); setNodeLinksForPrivateIdentifierScope(node); function checkAccessorDeclarationDiagnostics() { // Grammar checking accessors - if (!checkGrammarFunctionLikeDeclaration(node) && !checkGrammarAccessor(node)) checkGrammarComputedPropertyName(node.name); + if (!checkGrammarFunctionLikeDeclaration(node) && !checkGrammarAccessor(node)) + checkGrammarComputedPropertyName(node.name); checkDecorators(node); checkSignatureDeclaration(node); - if (node.kind === SyntaxKind.GetAccessor) { - if (!(node.flags & NodeFlags.Ambient) && nodeIsPresent(node.body) && (node.flags & NodeFlags.HasImplicitReturn)) { - if (!(node.flags & NodeFlags.HasExplicitReturn)) { - error(node.name, Diagnostics.A_get_accessor_must_return_a_value); + if (node.kind === ts.SyntaxKind.GetAccessor) { + if (!(node.flags & ts.NodeFlags.Ambient) && ts.nodeIsPresent(node.body) && (node.flags & ts.NodeFlags.HasImplicitReturn)) { + if (!(node.flags & ts.NodeFlags.HasExplicitReturn)) { + error(node.name, ts.Diagnostics.A_get_accessor_must_return_a_value); } } } // Do not use hasDynamicName here, because that returns false for well known symbols. // We want to perform checkComputedPropertyName for all computed properties, including // well known symbols. - if (node.name.kind === SyntaxKind.ComputedPropertyName) { + if (node.name.kind === ts.SyntaxKind.ComputedPropertyName) { checkComputedPropertyName(node.name); } @@ -35569,48 +34783,47 @@ namespace ts { // TypeScript 1.0 spec (April 2014): 8.4.3 // Accessors for the same member name must specify the same accessibility. const symbol = getSymbolOfNode(node); - const getter = getDeclarationOfKind(symbol, SyntaxKind.GetAccessor); - const setter = getDeclarationOfKind(symbol, SyntaxKind.SetAccessor); - if (getter && setter && !(getNodeCheckFlags(getter) & NodeCheckFlags.TypeChecked)) { - getNodeLinks(getter).flags |= NodeCheckFlags.TypeChecked; - const getterFlags = getEffectiveModifierFlags(getter); - const setterFlags = getEffectiveModifierFlags(setter); - if ((getterFlags & ModifierFlags.Abstract) !== (setterFlags & ModifierFlags.Abstract)) { - error(getter.name, Diagnostics.Accessors_must_both_be_abstract_or_non_abstract); - error(setter.name, Diagnostics.Accessors_must_both_be_abstract_or_non_abstract); - } - if (((getterFlags & ModifierFlags.Protected) && !(setterFlags & (ModifierFlags.Protected | ModifierFlags.Private))) || - ((getterFlags & ModifierFlags.Private) && !(setterFlags & ModifierFlags.Private))) { - error(getter.name, Diagnostics.A_get_accessor_must_be_at_least_as_accessible_as_the_setter); - error(setter.name, Diagnostics.A_get_accessor_must_be_at_least_as_accessible_as_the_setter); + const getter = ts.getDeclarationOfKind(symbol, ts.SyntaxKind.GetAccessor); + const setter = ts.getDeclarationOfKind(symbol, ts.SyntaxKind.SetAccessor); + if (getter && setter && !(getNodeCheckFlags(getter) & ts.NodeCheckFlags.TypeChecked)) { + getNodeLinks(getter).flags |= ts.NodeCheckFlags.TypeChecked; + const getterFlags = ts.getEffectiveModifierFlags(getter); + const setterFlags = ts.getEffectiveModifierFlags(setter); + if ((getterFlags & ts.ModifierFlags.Abstract) !== (setterFlags & ts.ModifierFlags.Abstract)) { + error(getter.name, ts.Diagnostics.Accessors_must_both_be_abstract_or_non_abstract); + error(setter.name, ts.Diagnostics.Accessors_must_both_be_abstract_or_non_abstract); + } + if (((getterFlags & ts.ModifierFlags.Protected) && !(setterFlags & (ts.ModifierFlags.Protected | ts.ModifierFlags.Private))) || + ((getterFlags & ts.ModifierFlags.Private) && !(setterFlags & ts.ModifierFlags.Private))) { + error(getter.name, ts.Diagnostics.A_get_accessor_must_be_at_least_as_accessible_as_the_setter); + error(setter.name, ts.Diagnostics.A_get_accessor_must_be_at_least_as_accessible_as_the_setter); } const getterType = getAnnotatedAccessorType(getter); const setterType = getAnnotatedAccessorType(setter); if (getterType && setterType) { - checkTypeAssignableTo(getterType, setterType, getter, Diagnostics.The_return_type_of_a_get_accessor_must_be_assignable_to_its_set_accessor_type); + checkTypeAssignableTo(getterType, setterType, getter, ts.Diagnostics.The_return_type_of_a_get_accessor_must_be_assignable_to_its_set_accessor_type); } } } const returnType = getTypeOfAccessors(getSymbolOfNode(node)); - if (node.kind === SyntaxKind.GetAccessor) { + if (node.kind === ts.SyntaxKind.GetAccessor) { checkAllCodePathsInNonVoidFunctionReturnOrThrow(node, returnType); } } } - function checkMissingDeclaration(node: Node) { + function checkMissingDeclaration(node: ts.Node) { checkDecorators(node); } - function getEffectiveTypeArguments(node: TypeReferenceNode | ExpressionWithTypeArguments, typeParameters: readonly TypeParameter[]): Type[] { - return fillMissingTypeArguments(map(node.typeArguments!, getTypeFromTypeNode), typeParameters, - getMinTypeArgumentCount(typeParameters), isInJSFile(node)); + function getEffectiveTypeArguments(node: ts.TypeReferenceNode | ts.ExpressionWithTypeArguments, typeParameters: readonly ts.TypeParameter[]): ts.Type[] { + return fillMissingTypeArguments(ts.map(node.typeArguments!, getTypeFromTypeNode), typeParameters, getMinTypeArgumentCount(typeParameters), ts.isInJSFile(node)); } - function checkTypeArgumentConstraints(node: TypeReferenceNode | ExpressionWithTypeArguments, typeParameters: readonly TypeParameter[]): boolean { - let typeArguments: Type[] | undefined; - let mapper: TypeMapper | undefined; + function checkTypeArgumentConstraints(node: ts.TypeReferenceNode | ts.ExpressionWithTypeArguments, typeParameters: readonly ts.TypeParameter[]): boolean { + let typeArguments: ts.Type[] | undefined; + let mapper: ts.TypeMapper | undefined; let result = true; for (let i = 0; i < typeParameters.length; i++) { const constraint = getConstraintOfTypeParameter(typeParameters[i]); @@ -35619,34 +34832,30 @@ namespace ts { typeArguments = getEffectiveTypeArguments(node, typeParameters); mapper = createTypeMapper(typeParameters, typeArguments); } - result = result && checkTypeAssignableTo( - typeArguments[i], - instantiateType(constraint, mapper), - node.typeArguments![i], - Diagnostics.Type_0_does_not_satisfy_the_constraint_1); + result = result && checkTypeAssignableTo(typeArguments[i], instantiateType(constraint, mapper), node.typeArguments![i], ts.Diagnostics.Type_0_does_not_satisfy_the_constraint_1); } } return result; } - function getTypeParametersForTypeReference(node: TypeReferenceNode | ExpressionWithTypeArguments) { + function getTypeParametersForTypeReference(node: ts.TypeReferenceNode | ts.ExpressionWithTypeArguments) { const type = getTypeFromTypeReference(node); if (!isErrorType(type)) { const symbol = getNodeLinks(node).resolvedSymbol; if (symbol) { - return symbol.flags & SymbolFlags.TypeAlias && getSymbolLinks(symbol).typeParameters || - (getObjectFlags(type) & ObjectFlags.Reference ? (type as TypeReference).target.localTypeParameters : undefined); + return symbol.flags & ts.SymbolFlags.TypeAlias && getSymbolLinks(symbol).typeParameters || + (ts.getObjectFlags(type) & ts.ObjectFlags.Reference ? (type as ts.TypeReference).target.localTypeParameters : undefined); } } return undefined; } - function checkTypeReferenceNode(node: TypeReferenceNode | ExpressionWithTypeArguments) { + function checkTypeReferenceNode(node: ts.TypeReferenceNode | ts.ExpressionWithTypeArguments) { checkGrammarTypeArguments(node, node.typeArguments); - if (node.kind === SyntaxKind.TypeReference && node.typeName.jsdocDotPos !== undefined && !isInJSFile(node) && !isInJSDoc(node)) { - grammarErrorAtPos(node, node.typeName.jsdocDotPos, 1, Diagnostics.JSDoc_types_can_only_be_used_inside_documentation_comments); + if (node.kind === ts.SyntaxKind.TypeReference && node.typeName.jsdocDotPos !== undefined && !ts.isInJSFile(node) && !ts.isInJSDoc(node)) { + grammarErrorAtPos(node, node.typeName.jsdocDotPos, 1, ts.Diagnostics.JSDoc_types_can_only_be_used_inside_documentation_comments); } - forEach(node.typeArguments, checkSourceElement); + ts.forEach(node.typeArguments, checkSourceElement); const type = getTypeFromTypeReference(node); if (!isErrorType(type)) { if (node.typeArguments) { @@ -35659,35 +34868,33 @@ namespace ts { } const symbol = getNodeLinks(node).resolvedSymbol; if (symbol) { - if (some(symbol.declarations, d => isTypeDeclaration(d) && !!(d.flags & NodeFlags.Deprecated))) { - addDeprecatedSuggestion( - getDeprecatedSuggestionNode(node), - symbol.declarations!, - symbol.escapedName as string - ); + if (ts.some(symbol.declarations, d => isTypeDeclaration(d) && !!(d.flags & ts.NodeFlags.Deprecated))) { + addDeprecatedSuggestion(getDeprecatedSuggestionNode(node), symbol.declarations!, symbol.escapedName as string); } - if (type.flags & TypeFlags.Enum && symbol.flags & SymbolFlags.EnumMember) { - error(node, Diagnostics.Enum_type_0_has_members_with_initializers_that_are_not_literals, typeToString(type)); + if (type.flags & ts.TypeFlags.Enum && symbol.flags & ts.SymbolFlags.EnumMember) { + error(node, ts.Diagnostics.Enum_type_0_has_members_with_initializers_that_are_not_literals, typeToString(type)); } } } } - function getTypeArgumentConstraint(node: TypeNode): Type | undefined { - const typeReferenceNode = tryCast(node.parent, isTypeReferenceType); - if (!typeReferenceNode) return undefined; + function getTypeArgumentConstraint(node: ts.TypeNode): ts.Type | undefined { + const typeReferenceNode = ts.tryCast(node.parent, ts.isTypeReferenceType); + if (!typeReferenceNode) + return undefined; const typeParameters = getTypeParametersForTypeReference(typeReferenceNode); - if (!typeParameters) return undefined; + if (!typeParameters) + return undefined; const constraint = getConstraintOfTypeParameter(typeParameters[typeReferenceNode.typeArguments!.indexOf(node)]); return constraint && instantiateType(constraint, createTypeMapper(typeParameters, getEffectiveTypeArguments(typeReferenceNode, typeParameters))); } - function checkTypeQuery(node: TypeQueryNode) { + function checkTypeQuery(node: ts.TypeQueryNode) { getTypeFromTypeQueryNode(node); } - function checkTypeLiteral(node: TypeLiteralNode) { - forEach(node.members, checkSourceElement); + function checkTypeLiteral(node: ts.TypeLiteralNode) { + ts.forEach(node.members, checkSourceElement); addLazyDiagnostic(checkTypeLiteralDiagnostics); function checkTypeLiteralDiagnostics() { @@ -35698,100 +34905,100 @@ namespace ts { } } - function checkArrayType(node: ArrayTypeNode) { + function checkArrayType(node: ts.ArrayTypeNode) { checkSourceElement(node.elementType); } - function checkTupleType(node: TupleTypeNode) { + function checkTupleType(node: ts.TupleTypeNode) { const elementTypes = node.elements; let seenOptionalElement = false; let seenRestElement = false; - const hasNamedElement = some(elementTypes, isNamedTupleMember); + const hasNamedElement = ts.some(elementTypes, ts.isNamedTupleMember); for (const e of elementTypes) { - if (e.kind !== SyntaxKind.NamedTupleMember && hasNamedElement) { - grammarErrorOnNode(e, Diagnostics.Tuple_members_must_all_have_names_or_all_not_have_names); + if (e.kind !== ts.SyntaxKind.NamedTupleMember && hasNamedElement) { + grammarErrorOnNode(e, ts.Diagnostics.Tuple_members_must_all_have_names_or_all_not_have_names); break; } const flags = getTupleElementFlags(e); - if (flags & ElementFlags.Variadic) { - const type = getTypeFromTypeNode((e as RestTypeNode | NamedTupleMember).type); + if (flags & ts.ElementFlags.Variadic) { + const type = getTypeFromTypeNode((e as ts.RestTypeNode | ts.NamedTupleMember).type); if (!isArrayLikeType(type)) { - error(e, Diagnostics.A_rest_element_type_must_be_an_array_type); + error(e, ts.Diagnostics.A_rest_element_type_must_be_an_array_type); break; } - if (isArrayType(type) || isTupleType(type) && type.target.combinedFlags & ElementFlags.Rest) { + if (isArrayType(type) || isTupleType(type) && type.target.combinedFlags & ts.ElementFlags.Rest) { seenRestElement = true; } } - else if (flags & ElementFlags.Rest) { + else if (flags & ts.ElementFlags.Rest) { if (seenRestElement) { - grammarErrorOnNode(e, Diagnostics.A_rest_element_cannot_follow_another_rest_element); + grammarErrorOnNode(e, ts.Diagnostics.A_rest_element_cannot_follow_another_rest_element); break; } seenRestElement = true; } - else if (flags & ElementFlags.Optional) { + else if (flags & ts.ElementFlags.Optional) { if (seenRestElement) { - grammarErrorOnNode(e, Diagnostics.An_optional_element_cannot_follow_a_rest_element); + grammarErrorOnNode(e, ts.Diagnostics.An_optional_element_cannot_follow_a_rest_element); break; } seenOptionalElement = true; } else if (seenOptionalElement) { - grammarErrorOnNode(e, Diagnostics.A_required_element_cannot_follow_an_optional_element); + grammarErrorOnNode(e, ts.Diagnostics.A_required_element_cannot_follow_an_optional_element); break; } } - forEach(node.elements, checkSourceElement); + ts.forEach(node.elements, checkSourceElement); getTypeFromTypeNode(node); } - function checkUnionOrIntersectionType(node: UnionOrIntersectionTypeNode) { - forEach(node.types, checkSourceElement); + function checkUnionOrIntersectionType(node: ts.UnionOrIntersectionTypeNode) { + ts.forEach(node.types, checkSourceElement); getTypeFromTypeNode(node); } - function checkIndexedAccessIndexType(type: Type, accessNode: IndexedAccessTypeNode | ElementAccessExpression) { - if (!(type.flags & TypeFlags.IndexedAccess)) { + function checkIndexedAccessIndexType(type: ts.Type, accessNode: ts.IndexedAccessTypeNode | ts.ElementAccessExpression) { + if (!(type.flags & ts.TypeFlags.IndexedAccess)) { return type; } // Check if the index type is assignable to 'keyof T' for the object type. - const objectType = (type as IndexedAccessType).objectType; - const indexType = (type as IndexedAccessType).indexType; + const objectType = (type as ts.IndexedAccessType).objectType; + const indexType = (type as ts.IndexedAccessType).indexType; if (isTypeAssignableTo(indexType, getIndexType(objectType, /*stringsOnly*/ false))) { - if (accessNode.kind === SyntaxKind.ElementAccessExpression && isAssignmentTarget(accessNode) && - getObjectFlags(objectType) & ObjectFlags.Mapped && getMappedTypeModifiers(objectType as MappedType) & MappedTypeModifiers.IncludeReadonly) { - error(accessNode, Diagnostics.Index_signature_in_type_0_only_permits_reading, typeToString(objectType)); + if (accessNode.kind === ts.SyntaxKind.ElementAccessExpression && ts.isAssignmentTarget(accessNode) && + ts.getObjectFlags(objectType) & ts.ObjectFlags.Mapped && getMappedTypeModifiers(objectType as ts.MappedType) & MappedTypeModifiers.IncludeReadonly) { + error(accessNode, ts.Diagnostics.Index_signature_in_type_0_only_permits_reading, typeToString(objectType)); } return type; } // Check if we're indexing with a numeric type and if either object or index types // is a generic type with a constraint that has a numeric index signature. const apparentObjectType = getApparentType(objectType); - if (getIndexInfoOfType(apparentObjectType, numberType) && isTypeAssignableToKind(indexType, TypeFlags.NumberLike)) { + if (getIndexInfoOfType(apparentObjectType, numberType) && isTypeAssignableToKind(indexType, ts.TypeFlags.NumberLike)) { return type; } if (isGenericObjectType(objectType)) { const propertyName = getPropertyNameFromIndex(indexType, accessNode); if (propertyName) { const propertySymbol = forEachType(apparentObjectType, t => getPropertyOfType(t, propertyName)); - if (propertySymbol && getDeclarationModifierFlagsFromSymbol(propertySymbol) & ModifierFlags.NonPublicAccessibilityModifier) { - error(accessNode, Diagnostics.Private_or_protected_member_0_cannot_be_accessed_on_a_type_parameter, unescapeLeadingUnderscores(propertyName)); + if (propertySymbol && ts.getDeclarationModifierFlagsFromSymbol(propertySymbol) & ts.ModifierFlags.NonPublicAccessibilityModifier) { + error(accessNode, ts.Diagnostics.Private_or_protected_member_0_cannot_be_accessed_on_a_type_parameter, ts.unescapeLeadingUnderscores(propertyName)); return errorType; } } } - error(accessNode, Diagnostics.Type_0_cannot_be_used_to_index_type_1, typeToString(indexType), typeToString(objectType)); + error(accessNode, ts.Diagnostics.Type_0_cannot_be_used_to_index_type_1, typeToString(indexType), typeToString(objectType)); return errorType; } - function checkIndexedAccessType(node: IndexedAccessTypeNode) { + function checkIndexedAccessType(node: ts.IndexedAccessTypeNode) { checkSourceElement(node.objectType); checkSourceElement(node.indexType); checkIndexedAccessIndexType(getTypeFromIndexedAccessTypeNode(node), node); } - function checkMappedType(node: MappedTypeNode) { + function checkMappedType(node: ts.MappedTypeNode) { checkGrammarMappedType(node); checkSourceElement(node.typeParameter); checkSourceElement(node.nameType); @@ -35801,39 +35008,39 @@ namespace ts { reportImplicitAny(node, anyType); } - const type = getTypeFromMappedTypeNode(node) as MappedType; + const type = getTypeFromMappedTypeNode(node) as ts.MappedType; const nameType = getNameTypeFromMappedType(type); if (nameType) { checkTypeAssignableTo(nameType, keyofConstraintType, node.nameType); } else { const constraintType = getConstraintTypeFromMappedType(type); - checkTypeAssignableTo(constraintType, keyofConstraintType, getEffectiveConstraintOfTypeParameter(node.typeParameter)); + checkTypeAssignableTo(constraintType, keyofConstraintType, ts.getEffectiveConstraintOfTypeParameter(node.typeParameter)); } } - function checkGrammarMappedType(node: MappedTypeNode) { + function checkGrammarMappedType(node: ts.MappedTypeNode) { if (node.members?.length) { - return grammarErrorOnNode(node.members[0], Diagnostics.A_mapped_type_may_not_declare_properties_or_methods); + return grammarErrorOnNode(node.members[0], ts.Diagnostics.A_mapped_type_may_not_declare_properties_or_methods); } } - function checkThisType(node: ThisTypeNode) { + function checkThisType(node: ts.ThisTypeNode) { getTypeFromThisTypeNode(node); } - function checkTypeOperator(node: TypeOperatorNode) { + function checkTypeOperator(node: ts.TypeOperatorNode) { checkGrammarTypeOperatorNode(node); checkSourceElement(node.type); } - function checkConditionalType(node: ConditionalTypeNode) { - forEachChild(node, checkSourceElement); + function checkConditionalType(node: ts.ConditionalTypeNode) { + ts.forEachChild(node, checkSourceElement); } - function checkInferType(node: InferTypeNode) { - if (!findAncestor(node, n => n.parent && n.parent.kind === SyntaxKind.ConditionalType && (n.parent as ConditionalTypeNode).extendsType === n)) { - grammarErrorOnNode(node, Diagnostics.infer_declarations_are_only_permitted_in_the_extends_clause_of_a_conditional_type); + function checkInferType(node: ts.InferTypeNode) { + if (!ts.findAncestor(node, n => n.parent && n.parent.kind === ts.SyntaxKind.ConditionalType && (n.parent as ts.ConditionalTypeNode).extendsType === n)) { + grammarErrorOnNode(node, ts.Diagnostics.infer_declarations_are_only_permitted_in_the_extends_clause_of_a_conditional_type); } checkSourceElement(node.typeParameter); const symbol = getSymbolOfNode(node.typeParameter); @@ -35842,12 +35049,12 @@ namespace ts { if (!links.typeParametersChecked) { links.typeParametersChecked = true; const typeParameter = getDeclaredTypeOfTypeParameter(symbol); - const declarations: TypeParameterDeclaration[] = getDeclarationsOfKind(symbol, SyntaxKind.TypeParameter); + const declarations: ts.TypeParameterDeclaration[] = ts.getDeclarationsOfKind(symbol, ts.SyntaxKind.TypeParameter); if (!areTypeParametersIdentical(declarations, [typeParameter], decl => [decl])) { // Report an error on every conflicting declaration. const name = symbolToString(symbol); for (const declaration of declarations) { - error(declaration.name, Diagnostics.All_declarations_of_0_must_have_identical_constraints, name); + error(declaration.name, ts.Diagnostics.All_declarations_of_0_must_have_identical_constraints, name); } } } @@ -35855,7 +35062,7 @@ namespace ts { registerForUnusedIdentifiersCheck(node); } - function checkTemplateLiteralType(node: TemplateLiteralTypeNode) { + function checkTemplateLiteralType(node: ts.TemplateLiteralTypeNode) { for (const span of node.templateSpans) { checkSourceElement(span.type); const type = getTypeFromTypeNode(span.type); @@ -35864,14 +35071,14 @@ namespace ts { getTypeFromTypeNode(node); } - function checkImportType(node: ImportTypeNode) { + function checkImportType(node: ts.ImportTypeNode) { checkSourceElement(node.argument); if (node.assertions) { - const override = getResolutionModeOverrideForClause(node.assertions.assertClause, grammarErrorOnNode); + const override = ts.getResolutionModeOverrideForClause(node.assertions.assertClause, grammarErrorOnNode); if (override) { - if (getEmitModuleResolutionKind(compilerOptions) !== ModuleResolutionKind.Node16 && getEmitModuleResolutionKind(compilerOptions) !== ModuleResolutionKind.NodeNext) { - grammarErrorOnNode(node.assertions.assertClause, Diagnostics.Resolution_modes_are_only_supported_when_moduleResolution_is_node16_or_nodenext); + if (ts.getEmitModuleResolutionKind(compilerOptions) !== ts.ModuleResolutionKind.Node16 && ts.getEmitModuleResolutionKind(compilerOptions) !== ts.ModuleResolutionKind.NodeNext) { + grammarErrorOnNode(node.assertions.assertClause, ts.Diagnostics.Resolution_modes_are_only_supported_when_moduleResolution_is_node16_or_nodenext); } } } @@ -35879,49 +35086,49 @@ namespace ts { getTypeFromTypeNode(node); } - function checkNamedTupleMember(node: NamedTupleMember) { + function checkNamedTupleMember(node: ts.NamedTupleMember) { if (node.dotDotDotToken && node.questionToken) { - grammarErrorOnNode(node, Diagnostics.A_tuple_member_cannot_be_both_optional_and_rest); + grammarErrorOnNode(node, ts.Diagnostics.A_tuple_member_cannot_be_both_optional_and_rest); } - if (node.type.kind === SyntaxKind.OptionalType) { - grammarErrorOnNode(node.type, Diagnostics.A_labeled_tuple_element_is_declared_as_optional_with_a_question_mark_after_the_name_and_before_the_colon_rather_than_after_the_type); + if (node.type.kind === ts.SyntaxKind.OptionalType) { + grammarErrorOnNode(node.type, ts.Diagnostics.A_labeled_tuple_element_is_declared_as_optional_with_a_question_mark_after_the_name_and_before_the_colon_rather_than_after_the_type); } - if (node.type.kind === SyntaxKind.RestType) { - grammarErrorOnNode(node.type, Diagnostics.A_labeled_tuple_element_is_declared_as_rest_with_a_before_the_name_rather_than_before_the_type); + if (node.type.kind === ts.SyntaxKind.RestType) { + grammarErrorOnNode(node.type, ts.Diagnostics.A_labeled_tuple_element_is_declared_as_rest_with_a_before_the_name_rather_than_before_the_type); } checkSourceElement(node.type); getTypeFromTypeNode(node); } - function isPrivateWithinAmbient(node: Node): boolean { - return (hasEffectiveModifier(node, ModifierFlags.Private) || isPrivateIdentifierClassElementDeclaration(node)) && !!(node.flags & NodeFlags.Ambient); + function isPrivateWithinAmbient(node: ts.Node): boolean { + return (ts.hasEffectiveModifier(node, ts.ModifierFlags.Private) || ts.isPrivateIdentifierClassElementDeclaration(node)) && !!(node.flags & ts.NodeFlags.Ambient); } - function getEffectiveDeclarationFlags(n: Declaration, flagsToCheck: ModifierFlags): ModifierFlags { - let flags = getCombinedModifierFlags(n); + function getEffectiveDeclarationFlags(n: ts.Declaration, flagsToCheck: ts.ModifierFlags): ts.ModifierFlags { + let flags = ts.getCombinedModifierFlags(n); // children of classes (even ambient classes) should not be marked as ambient or export // because those flags have no useful semantics there. - if (n.parent.kind !== SyntaxKind.InterfaceDeclaration && - n.parent.kind !== SyntaxKind.ClassDeclaration && - n.parent.kind !== SyntaxKind.ClassExpression && - n.flags & NodeFlags.Ambient) { - if (!(flags & ModifierFlags.Ambient) && !(isModuleBlock(n.parent) && isModuleDeclaration(n.parent.parent) && isGlobalScopeAugmentation(n.parent.parent))) { + if (n.parent.kind !== ts.SyntaxKind.InterfaceDeclaration && + n.parent.kind !== ts.SyntaxKind.ClassDeclaration && + n.parent.kind !== ts.SyntaxKind.ClassExpression && + n.flags & ts.NodeFlags.Ambient) { + if (!(flags & ts.ModifierFlags.Ambient) && !(ts.isModuleBlock(n.parent) && ts.isModuleDeclaration(n.parent.parent) && ts.isGlobalScopeAugmentation(n.parent.parent))) { // It is nested in an ambient context, which means it is automatically exported - flags |= ModifierFlags.Export; + flags |= ts.ModifierFlags.Export; } - flags |= ModifierFlags.Ambient; + flags |= ts.ModifierFlags.Ambient; } return flags & flagsToCheck; } - function checkFunctionOrConstructorSymbol(symbol: Symbol): void { + function checkFunctionOrConstructorSymbol(symbol: ts.Symbol): void { addLazyDiagnostic(() => checkFunctionOrConstructorSymbolWorker(symbol)); } - function checkFunctionOrConstructorSymbolWorker(symbol: Symbol): void { - function getCanonicalOverload(overloads: Declaration[], implementation: FunctionLikeDeclaration | undefined): Declaration { + function checkFunctionOrConstructorSymbolWorker(symbol: ts.Symbol): void { + function getCanonicalOverload(overloads: ts.Declaration[], implementation: ts.FunctionLikeDeclaration | undefined): ts.Declaration { // Consider the canonical set of flags to be the flags of the bodyDeclaration or the first declaration // Error on all deviations from this canonical set of flags // The caveat is that if some overloads are defined in lib.d.ts, we don't want to @@ -35931,62 +35138,61 @@ namespace ts { return implementationSharesContainerWithFirstOverload ? implementation : overloads[0]; } - function checkFlagAgreementBetweenOverloads(overloads: Declaration[], implementation: FunctionLikeDeclaration | undefined, flagsToCheck: ModifierFlags, someOverloadFlags: ModifierFlags, allOverloadFlags: ModifierFlags): void { + function checkFlagAgreementBetweenOverloads(overloads: ts.Declaration[], implementation: ts.FunctionLikeDeclaration | undefined, flagsToCheck: ts.ModifierFlags, someOverloadFlags: ts.ModifierFlags, allOverloadFlags: ts.ModifierFlags): void { // Error if some overloads have a flag that is not shared by all overloads. To find the // deviations, we XOR someOverloadFlags with allOverloadFlags const someButNotAllOverloadFlags = someOverloadFlags ^ allOverloadFlags; if (someButNotAllOverloadFlags !== 0) { const canonicalFlags = getEffectiveDeclarationFlags(getCanonicalOverload(overloads, implementation), flagsToCheck); - forEach(overloads, o => { + ts.forEach(overloads, o => { const deviation = getEffectiveDeclarationFlags(o, flagsToCheck) ^ canonicalFlags; - if (deviation & ModifierFlags.Export) { - error(getNameOfDeclaration(o), Diagnostics.Overload_signatures_must_all_be_exported_or_non_exported); + if (deviation & ts.ModifierFlags.Export) { + error(ts.getNameOfDeclaration(o), ts.Diagnostics.Overload_signatures_must_all_be_exported_or_non_exported); } - else if (deviation & ModifierFlags.Ambient) { - error(getNameOfDeclaration(o), Diagnostics.Overload_signatures_must_all_be_ambient_or_non_ambient); + else if (deviation & ts.ModifierFlags.Ambient) { + error(ts.getNameOfDeclaration(o), ts.Diagnostics.Overload_signatures_must_all_be_ambient_or_non_ambient); } - else if (deviation & (ModifierFlags.Private | ModifierFlags.Protected)) { - error(getNameOfDeclaration(o) || o, Diagnostics.Overload_signatures_must_all_be_public_private_or_protected); + else if (deviation & (ts.ModifierFlags.Private | ts.ModifierFlags.Protected)) { + error(ts.getNameOfDeclaration(o) || o, ts.Diagnostics.Overload_signatures_must_all_be_public_private_or_protected); } - else if (deviation & ModifierFlags.Abstract) { - error(getNameOfDeclaration(o), Diagnostics.Overload_signatures_must_all_be_abstract_or_non_abstract); + else if (deviation & ts.ModifierFlags.Abstract) { + error(ts.getNameOfDeclaration(o), ts.Diagnostics.Overload_signatures_must_all_be_abstract_or_non_abstract); } }); } } - function checkQuestionTokenAgreementBetweenOverloads(overloads: Declaration[], implementation: FunctionLikeDeclaration | undefined, someHaveQuestionToken: boolean, allHaveQuestionToken: boolean): void { + function checkQuestionTokenAgreementBetweenOverloads(overloads: ts.Declaration[], implementation: ts.FunctionLikeDeclaration | undefined, someHaveQuestionToken: boolean, allHaveQuestionToken: boolean): void { if (someHaveQuestionToken !== allHaveQuestionToken) { - const canonicalHasQuestionToken = hasQuestionToken(getCanonicalOverload(overloads, implementation)); - forEach(overloads, o => { - const deviation = hasQuestionToken(o) !== canonicalHasQuestionToken; + const canonicalHasQuestionToken = ts.hasQuestionToken(getCanonicalOverload(overloads, implementation)); + ts.forEach(overloads, o => { + const deviation = ts.hasQuestionToken(o) !== canonicalHasQuestionToken; if (deviation) { - error(getNameOfDeclaration(o), Diagnostics.Overload_signatures_must_all_be_optional_or_required); + error(ts.getNameOfDeclaration(o), ts.Diagnostics.Overload_signatures_must_all_be_optional_or_required); } }); } } - const flagsToCheck: ModifierFlags = ModifierFlags.Export | ModifierFlags.Ambient | ModifierFlags.Private | ModifierFlags.Protected | ModifierFlags.Abstract; - let someNodeFlags: ModifierFlags = ModifierFlags.None; + const flagsToCheck: ts.ModifierFlags = ts.ModifierFlags.Export | ts.ModifierFlags.Ambient | ts.ModifierFlags.Private | ts.ModifierFlags.Protected | ts.ModifierFlags.Abstract; + let someNodeFlags: ts.ModifierFlags = ts.ModifierFlags.None; let allNodeFlags = flagsToCheck; let someHaveQuestionToken = false; let allHaveQuestionToken = true; let hasOverloads = false; - let bodyDeclaration: FunctionLikeDeclaration | undefined; - let lastSeenNonAmbientDeclaration: FunctionLikeDeclaration | undefined; - let previousDeclaration: SignatureDeclaration | undefined; + let bodyDeclaration: ts.FunctionLikeDeclaration | undefined; + let lastSeenNonAmbientDeclaration: ts.FunctionLikeDeclaration | undefined; + let previousDeclaration: ts.SignatureDeclaration | undefined; const declarations = symbol.declarations; - const isConstructor = (symbol.flags & SymbolFlags.Constructor) !== 0; - - function reportImplementationExpectedError(node: SignatureDeclaration): void { - if (node.name && nodeIsMissing(node.name)) { + const isConstructor = (symbol.flags & ts.SymbolFlags.Constructor) !== 0; + function reportImplementationExpectedError(node: ts.SignatureDeclaration): void { + if (node.name && ts.nodeIsMissing(node.name)) { return; } let seen = false; - const subsequentNode = forEachChild(node.parent, c => { + const subsequentNode = ts.forEachChild(node.parent, c => { if (seen) { return c; } @@ -35998,49 +35204,47 @@ namespace ts { // In this case the subsequent node is not really consecutive (.pos !== node.end), and we must ignore it here. if (subsequentNode && subsequentNode.pos === node.end) { if (subsequentNode.kind === node.kind) { - const errorNode: Node = (subsequentNode as FunctionLikeDeclaration).name || subsequentNode; - const subsequentName = (subsequentNode as FunctionLikeDeclaration).name; + const errorNode: ts.Node = (subsequentNode as ts.FunctionLikeDeclaration).name || subsequentNode; + const subsequentName = (subsequentNode as ts.FunctionLikeDeclaration).name; if (node.name && subsequentName && ( // both are private identifiers - isPrivateIdentifier(node.name) && isPrivateIdentifier(subsequentName) && node.name.escapedText === subsequentName.escapedText || + ts.isPrivateIdentifier(node.name) && ts.isPrivateIdentifier(subsequentName) && node.name.escapedText === subsequentName.escapedText || // Both are computed property names // TODO: GH#17345: These are methods, so handle computed name case. (`Always allowing computed property names is *not* the correct behavior!) - isComputedPropertyName(node.name) && isComputedPropertyName(subsequentName) || + ts.isComputedPropertyName(node.name) && ts.isComputedPropertyName(subsequentName) || // Both are literal property names that are the same. - isPropertyNameLiteral(node.name) && isPropertyNameLiteral(subsequentName) && - getEscapedTextOfIdentifierOrLiteral(node.name) === getEscapedTextOfIdentifierOrLiteral(subsequentName) - )) { - const reportError = - (node.kind === SyntaxKind.MethodDeclaration || node.kind === SyntaxKind.MethodSignature) && - isStatic(node) !== isStatic(subsequentNode); + ts.isPropertyNameLiteral(node.name) && ts.isPropertyNameLiteral(subsequentName) && + ts.getEscapedTextOfIdentifierOrLiteral(node.name) === ts.getEscapedTextOfIdentifierOrLiteral(subsequentName))) { + const reportError = (node.kind === ts.SyntaxKind.MethodDeclaration || node.kind === ts.SyntaxKind.MethodSignature) && + ts.isStatic(node) !== ts.isStatic(subsequentNode); // we can get here in two cases // 1. mixed static and instance class members // 2. something with the same name was defined before the set of overloads that prevents them from merging // here we'll report error only for the first case since for second we should already report error in binder if (reportError) { - const diagnostic = isStatic(node) ? Diagnostics.Function_overload_must_be_static : Diagnostics.Function_overload_must_not_be_static; + const diagnostic = ts.isStatic(node) ? ts.Diagnostics.Function_overload_must_be_static : ts.Diagnostics.Function_overload_must_not_be_static; error(errorNode, diagnostic); } return; } - if (nodeIsPresent((subsequentNode as FunctionLikeDeclaration).body)) { - error(errorNode, Diagnostics.Function_implementation_name_must_be_0, declarationNameToString(node.name)); + if (ts.nodeIsPresent((subsequentNode as ts.FunctionLikeDeclaration).body)) { + error(errorNode, ts.Diagnostics.Function_implementation_name_must_be_0, ts.declarationNameToString(node.name)); return; } } } - const errorNode: Node = node.name || node; + const errorNode: ts.Node = node.name || node; if (isConstructor) { - error(errorNode, Diagnostics.Constructor_implementation_is_missing); + error(errorNode, ts.Diagnostics.Constructor_implementation_is_missing); } else { // Report different errors regarding non-consecutive blocks of declarations depending on whether // the node in question is abstract. - if (hasSyntacticModifier(node, ModifierFlags.Abstract)) { - error(errorNode, Diagnostics.All_declarations_of_an_abstract_method_must_be_consecutive); + if (ts.hasSyntacticModifier(node, ts.ModifierFlags.Abstract)) { + error(errorNode, ts.Diagnostics.All_declarations_of_an_abstract_method_must_be_consecutive); } else { - error(errorNode, Diagnostics.Function_implementation_is_missing_or_not_immediately_following_the_declaration); + error(errorNode, ts.Diagnostics.Function_implementation_is_missing_or_not_immediately_following_the_declaration); } } } @@ -36048,12 +35252,12 @@ namespace ts { let duplicateFunctionDeclaration = false; let multipleConstructorImplementation = false; let hasNonAmbientClass = false; - const functionDeclarations = [] as Declaration[]; + const functionDeclarations = [] as ts.Declaration[]; if (declarations) { for (const current of declarations) { - const node = current as SignatureDeclaration | ClassDeclaration | ClassExpression; - const inAmbientContext = node.flags & NodeFlags.Ambient; - const inAmbientContextOrInterface = node.parent && (node.parent.kind === SyntaxKind.InterfaceDeclaration || node.parent.kind === SyntaxKind.TypeLiteral) || inAmbientContext; + const node = current as ts.SignatureDeclaration | ts.ClassDeclaration | ts.ClassExpression; + const inAmbientContext = node.flags & ts.NodeFlags.Ambient; + const inAmbientContextOrInterface = node.parent && (node.parent.kind === ts.SyntaxKind.InterfaceDeclaration || node.parent.kind === ts.SyntaxKind.TypeLiteral) || inAmbientContext; if (inAmbientContextOrInterface) { // check if declarations are consecutive only if they are non-ambient // 1. ambient declarations can be interleaved @@ -36065,18 +35269,18 @@ namespace ts { previousDeclaration = undefined; } - if ((node.kind === SyntaxKind.ClassDeclaration || node.kind === SyntaxKind.ClassExpression) && !inAmbientContext) { + if ((node.kind === ts.SyntaxKind.ClassDeclaration || node.kind === ts.SyntaxKind.ClassExpression) && !inAmbientContext) { hasNonAmbientClass = true; } - if (node.kind === SyntaxKind.FunctionDeclaration || node.kind === SyntaxKind.MethodDeclaration || node.kind === SyntaxKind.MethodSignature || node.kind === SyntaxKind.Constructor) { + if (node.kind === ts.SyntaxKind.FunctionDeclaration || node.kind === ts.SyntaxKind.MethodDeclaration || node.kind === ts.SyntaxKind.MethodSignature || node.kind === ts.SyntaxKind.Constructor) { functionDeclarations.push(node); const currentNodeFlags = getEffectiveDeclarationFlags(node, flagsToCheck); someNodeFlags |= currentNodeFlags; allNodeFlags &= currentNodeFlags; - someHaveQuestionToken = someHaveQuestionToken || hasQuestionToken(node); - allHaveQuestionToken = allHaveQuestionToken && hasQuestionToken(node); - const bodyIsPresent = nodeIsPresent((node as FunctionLikeDeclaration).body); + someHaveQuestionToken = someHaveQuestionToken || ts.hasQuestionToken(node); + allHaveQuestionToken = allHaveQuestionToken && ts.hasQuestionToken(node); + const bodyIsPresent = ts.nodeIsPresent((node as ts.FunctionLikeDeclaration).body); if (bodyIsPresent && bodyDeclaration) { if (isConstructor) { @@ -36092,7 +35296,7 @@ namespace ts { if (bodyIsPresent) { if (!bodyDeclaration) { - bodyDeclaration = node as FunctionLikeDeclaration; + bodyDeclaration = node as ts.FunctionLikeDeclaration; } } else { @@ -36102,46 +35306,42 @@ namespace ts { previousDeclaration = node; if (!inAmbientContextOrInterface) { - lastSeenNonAmbientDeclaration = node as FunctionLikeDeclaration; + lastSeenNonAmbientDeclaration = node as ts.FunctionLikeDeclaration; } } } } if (multipleConstructorImplementation) { - forEach(functionDeclarations, declaration => { - error(declaration, Diagnostics.Multiple_constructor_implementations_are_not_allowed); + ts.forEach(functionDeclarations, declaration => { + error(declaration, ts.Diagnostics.Multiple_constructor_implementations_are_not_allowed); }); } if (duplicateFunctionDeclaration) { - forEach(functionDeclarations, declaration => { - error(getNameOfDeclaration(declaration) || declaration, Diagnostics.Duplicate_function_implementation); + ts.forEach(functionDeclarations, declaration => { + error(ts.getNameOfDeclaration(declaration) || declaration, ts.Diagnostics.Duplicate_function_implementation); }); } - if (hasNonAmbientClass && !isConstructor && symbol.flags & SymbolFlags.Function && declarations) { - const relatedDiagnostics = filter(declarations, d => d.kind === SyntaxKind.ClassDeclaration) - .map(d => createDiagnosticForNode(d, Diagnostics.Consider_adding_a_declare_modifier_to_this_class)); - - forEach(declarations, declaration => { - const diagnostic = declaration.kind === SyntaxKind.ClassDeclaration - ? Diagnostics.Class_declaration_cannot_implement_overload_list_for_0 - : declaration.kind === SyntaxKind.FunctionDeclaration - ? Diagnostics.Function_with_bodies_can_only_merge_with_classes_that_are_ambient + if (hasNonAmbientClass && !isConstructor && symbol.flags & ts.SymbolFlags.Function && declarations) { + const relatedDiagnostics = ts.filter(declarations, d => d.kind === ts.SyntaxKind.ClassDeclaration) + .map(d => ts.createDiagnosticForNode(d, ts.Diagnostics.Consider_adding_a_declare_modifier_to_this_class)); + ts.forEach(declarations, declaration => { + const diagnostic = declaration.kind === ts.SyntaxKind.ClassDeclaration + ? ts.Diagnostics.Class_declaration_cannot_implement_overload_list_for_0 + : declaration.kind === ts.SyntaxKind.FunctionDeclaration + ? ts.Diagnostics.Function_with_bodies_can_only_merge_with_classes_that_are_ambient : undefined; if (diagnostic) { - addRelatedInfo( - error(getNameOfDeclaration(declaration) || declaration, diagnostic, symbolName(symbol)), - ...relatedDiagnostics - ); + ts.addRelatedInfo(error(ts.getNameOfDeclaration(declaration) || declaration, diagnostic, ts.symbolName(symbol)), ...relatedDiagnostics); } }); } // Abstract methods can't have an implementation -- in particular, they don't need one. if (lastSeenNonAmbientDeclaration && !lastSeenNonAmbientDeclaration.body && - !hasSyntacticModifier(lastSeenNonAmbientDeclaration, ModifierFlags.Abstract) && !lastSeenNonAmbientDeclaration.questionToken) { + !ts.hasSyntacticModifier(lastSeenNonAmbientDeclaration, ts.ModifierFlags.Abstract) && !lastSeenNonAmbientDeclaration.questionToken) { reportImplementationExpectedError(lastSeenNonAmbientDeclaration); } @@ -36156,10 +35356,7 @@ namespace ts { const bodySignature = getSignatureFromDeclaration(bodyDeclaration); for (const signature of signatures) { if (!isImplementationCompatibleWithOverload(bodySignature, signature)) { - addRelatedInfo( - error(signature.declaration, Diagnostics.This_overload_signature_is_not_compatible_with_its_implementation_signature), - createDiagnosticForNode(bodyDeclaration, Diagnostics.The_implementation_signature_is_declared_here) - ); + ts.addRelatedInfo(error(signature.declaration, ts.Diagnostics.This_overload_signature_is_not_compatible_with_its_implementation_signature), ts.createDiagnosticForNode(bodyDeclaration, ts.Diagnostics.The_implementation_signature_is_declared_here)); break; } } @@ -36167,11 +35364,11 @@ namespace ts { } } - function checkExportsOnMergedDeclarations(node: Declaration): void { + function checkExportsOnMergedDeclarations(node: ts.Declaration): void { addLazyDiagnostic(() => checkExportsOnMergedDeclarationsWorker(node)); } - function checkExportsOnMergedDeclarationsWorker(node: Declaration): void { + function checkExportsOnMergedDeclarationsWorker(node: ts.Declaration): void { // if localSymbol is defined on node then node itself is exported - check is required let symbol = node.localSymbol; if (!symbol) { @@ -36185,7 +35382,7 @@ namespace ts { } // run the check only for the first declaration in the list - if (getDeclarationOfKind(symbol, node.kind) !== node) { + if (ts.getDeclarationOfKind(symbol, node.kind) !== node) { return; } @@ -36194,10 +35391,9 @@ namespace ts { let defaultExportedDeclarationSpaces = DeclarationSpaces.None; for (const d of symbol.declarations!) { const declarationSpaces = getDeclarationSpaces(d); - const effectiveDeclarationFlags = getEffectiveDeclarationFlags(d, ModifierFlags.Export | ModifierFlags.Default); - - if (effectiveDeclarationFlags & ModifierFlags.Export) { - if (effectiveDeclarationFlags & ModifierFlags.Default) { + const effectiveDeclarationFlags = getEffectiveDeclarationFlags(d, ts.ModifierFlags.Export | ts.ModifierFlags.Default); + if (effectiveDeclarationFlags & ts.ModifierFlags.Export) { + if (effectiveDeclarationFlags & ts.ModifierFlags.Default) { defaultExportedDeclarationSpaces |= declarationSpaces; } else { @@ -36220,65 +35416,65 @@ namespace ts { for (const d of symbol.declarations!) { const declarationSpaces = getDeclarationSpaces(d); - const name = getNameOfDeclaration(d); + const name = ts.getNameOfDeclaration(d); // Only error on the declarations that contributed to the intersecting spaces. if (declarationSpaces & commonDeclarationSpacesForDefaultAndNonDefault) { - error(name, Diagnostics.Merged_declaration_0_cannot_include_a_default_export_declaration_Consider_adding_a_separate_export_default_0_declaration_instead, declarationNameToString(name)); + error(name, ts.Diagnostics.Merged_declaration_0_cannot_include_a_default_export_declaration_Consider_adding_a_separate_export_default_0_declaration_instead, ts.declarationNameToString(name)); } else if (declarationSpaces & commonDeclarationSpacesForExportsAndLocals) { - error(name, Diagnostics.Individual_declarations_in_merged_declaration_0_must_be_all_exported_or_all_local, declarationNameToString(name)); + error(name, ts.Diagnostics.Individual_declarations_in_merged_declaration_0_must_be_all_exported_or_all_local, ts.declarationNameToString(name)); } } } - function getDeclarationSpaces(decl: Declaration): DeclarationSpaces { - let d = decl as Node; + function getDeclarationSpaces(decl: ts.Declaration): DeclarationSpaces { + let d = decl as ts.Node; switch (d.kind) { - case SyntaxKind.InterfaceDeclaration: - case SyntaxKind.TypeAliasDeclaration: + case ts.SyntaxKind.InterfaceDeclaration: + case ts.SyntaxKind.TypeAliasDeclaration: // A jsdoc typedef and callback are, by definition, type aliases. // falls through - case SyntaxKind.JSDocTypedefTag: - case SyntaxKind.JSDocCallbackTag: - case SyntaxKind.JSDocEnumTag: + case ts.SyntaxKind.JSDocTypedefTag: + case ts.SyntaxKind.JSDocCallbackTag: + case ts.SyntaxKind.JSDocEnumTag: return DeclarationSpaces.ExportType; - case SyntaxKind.ModuleDeclaration: - return isAmbientModule(d as ModuleDeclaration) || getModuleInstanceState(d as ModuleDeclaration) !== ModuleInstanceState.NonInstantiated + case ts.SyntaxKind.ModuleDeclaration: + return ts.isAmbientModule(d as ts.ModuleDeclaration) || ts.getModuleInstanceState(d as ts.ModuleDeclaration) !== ts.ModuleInstanceState.NonInstantiated ? DeclarationSpaces.ExportNamespace | DeclarationSpaces.ExportValue : DeclarationSpaces.ExportNamespace; - case SyntaxKind.ClassDeclaration: - case SyntaxKind.EnumDeclaration: - case SyntaxKind.EnumMember: + case ts.SyntaxKind.ClassDeclaration: + case ts.SyntaxKind.EnumDeclaration: + case ts.SyntaxKind.EnumMember: return DeclarationSpaces.ExportType | DeclarationSpaces.ExportValue; - case SyntaxKind.SourceFile: + case ts.SyntaxKind.SourceFile: return DeclarationSpaces.ExportType | DeclarationSpaces.ExportValue | DeclarationSpaces.ExportNamespace; - case SyntaxKind.ExportAssignment: - case SyntaxKind.BinaryExpression: - const node = d as ExportAssignment | BinaryExpression; - const expression = isExportAssignment(node) ? node.expression : node.right; + case ts.SyntaxKind.ExportAssignment: + case ts.SyntaxKind.BinaryExpression: + const node = d as ts.ExportAssignment | ts.BinaryExpression; + const expression = ts.isExportAssignment(node) ? node.expression : node.right; // Export assigned entity name expressions act as aliases and should fall through, otherwise they export values - if (!isEntityNameExpression(expression)) { + if (!ts.isEntityNameExpression(expression)) { return DeclarationSpaces.ExportValue; } d = expression; // The below options all declare an Alias, which is allowed to merge with other values within the importing module. // falls through - case SyntaxKind.ImportEqualsDeclaration: - case SyntaxKind.NamespaceImport: - case SyntaxKind.ImportClause: + case ts.SyntaxKind.ImportEqualsDeclaration: + case ts.SyntaxKind.NamespaceImport: + case ts.SyntaxKind.ImportClause: let result = DeclarationSpaces.None; const target = resolveAlias(getSymbolOfNode(d)!); - forEach(target.declarations, d => { + ts.forEach(target.declarations, d => { result |= getDeclarationSpaces(d); }); return result; - case SyntaxKind.VariableDeclaration: - case SyntaxKind.BindingElement: - case SyntaxKind.FunctionDeclaration: - case SyntaxKind.ImportSpecifier: // https://github.com/Microsoft/TypeScript/pull/7591 - case SyntaxKind.Identifier: // https://github.com/microsoft/TypeScript/issues/36098 + case ts.SyntaxKind.VariableDeclaration: + case ts.SyntaxKind.BindingElement: + case ts.SyntaxKind.FunctionDeclaration: + case ts.SyntaxKind.ImportSpecifier: // https://github.com/Microsoft/TypeScript/pull/7591 + case ts.SyntaxKind.Identifier: // https://github.com/microsoft/TypeScript/issues/36098 // Identifiers are used as declarations of assignment declarations whose parents may be // SyntaxKind.CallExpression - `Object.defineProperty(thing, "aField", {value: 42});` // SyntaxKind.ElementAccessExpression - `thing["aField"] = 42;` or `thing["aField"];` (with a doc comment on it) @@ -36287,12 +35483,12 @@ namespace ts { // It may be apprpriate to treat these as aliases in the future. return DeclarationSpaces.ExportValue; default: - return Debug.failBadSyntaxKind(d); + return ts.Debug.failBadSyntaxKind(d); } } } - function getAwaitedTypeOfPromise(type: Type, errorNode?: Node, diagnosticMessage?: DiagnosticMessage, arg0?: string | number): Type | undefined { + function getAwaitedTypeOfPromise(type: ts.Type, errorNode?: ts.Node, diagnosticMessage?: ts.DiagnosticMessage, arg0?: string | number): ts.Type | undefined { const promisedType = getPromisedTypeOfPromise(type, errorNode); return promisedType && getAwaitedType(promisedType, errorNode, diagnosticMessage, arg0); } @@ -36302,7 +35498,9 @@ namespace ts { * @param type The type of the promise. * @remarks The "promised type" of a type is the type of the "value" parameter of the "onfulfilled" callback. */ - function getPromisedTypeOfPromise(type: Type, errorNode?: Node, thisTypeForErrorOut?: { value?: Type }): Type | undefined { + function getPromisedTypeOfPromise(type: ts.Type, errorNode?: ts.Node, thisTypeForErrorOut?: { + value?: ts.Type; + }): ts.Type | undefined { // // { // type // then( // thenFunction @@ -36317,70 +35515,70 @@ namespace ts { return undefined; } - const typeAsPromise = type as PromiseOrAwaitableType; + const typeAsPromise = type as ts.PromiseOrAwaitableType; if (typeAsPromise.promisedTypeOfPromise) { return typeAsPromise.promisedTypeOfPromise; } if (isReferenceToType(type, getGlobalPromiseType(/*reportErrors*/ false))) { - return typeAsPromise.promisedTypeOfPromise = getTypeArguments(type as GenericType)[0]; + return typeAsPromise.promisedTypeOfPromise = getTypeArguments(type as ts.GenericType)[0]; } // primitives with a `{ then() }` won't be unwrapped/adopted. - if (allTypesAssignableToKind(type, TypeFlags.Primitive | TypeFlags.Never)) { + if (allTypesAssignableToKind(type, ts.TypeFlags.Primitive | ts.TypeFlags.Never)) { return undefined; } - const thenFunction = getTypeOfPropertyOfType(type, "then" as __String)!; // TODO: GH#18217 + const thenFunction = getTypeOfPropertyOfType(type, "then" as ts.__String)!; // TODO: GH#18217 if (isTypeAny(thenFunction)) { return undefined; } - const thenSignatures = thenFunction ? getSignaturesOfType(thenFunction, SignatureKind.Call) : emptyArray; + const thenSignatures = thenFunction ? getSignaturesOfType(thenFunction, ts.SignatureKind.Call) : ts.emptyArray; if (thenSignatures.length === 0) { if (errorNode) { - error(errorNode, Diagnostics.A_promise_must_have_a_then_method); + error(errorNode, ts.Diagnostics.A_promise_must_have_a_then_method); } return undefined; } - let thisTypeForError: Type | undefined; - let candidates: Signature[] | undefined; + let thisTypeForError: ts.Type | undefined; + let candidates: ts.Signature[] | undefined; for (const thenSignature of thenSignatures) { const thisType = getThisTypeOfSignature(thenSignature); if (thisType && thisType !== voidType && !isTypeRelatedTo(type, thisType, subtypeRelation)) { thisTypeForError = thisType; } else { - candidates = append(candidates, thenSignature); + candidates = ts.append(candidates, thenSignature); } } if (!candidates) { - Debug.assertIsDefined(thisTypeForError); + ts.Debug.assertIsDefined(thisTypeForError); if (thisTypeForErrorOut) { thisTypeForErrorOut.value = thisTypeForError; } if (errorNode) { - error(errorNode, Diagnostics.The_this_context_of_type_0_is_not_assignable_to_method_s_this_of_type_1, typeToString(type), typeToString(thisTypeForError)); + error(errorNode, ts.Diagnostics.The_this_context_of_type_0_is_not_assignable_to_method_s_this_of_type_1, typeToString(type), typeToString(thisTypeForError)); } return undefined; } - const onfulfilledParameterType = getTypeWithFacts(getUnionType(map(candidates, getTypeOfFirstParameterOfSignature)), TypeFacts.NEUndefinedOrNull); + const onfulfilledParameterType = getTypeWithFacts(getUnionType(ts.map(candidates, getTypeOfFirstParameterOfSignature)), TypeFacts.NEUndefinedOrNull); if (isTypeAny(onfulfilledParameterType)) { return undefined; } - const onfulfilledParameterSignatures = getSignaturesOfType(onfulfilledParameterType, SignatureKind.Call); + const onfulfilledParameterSignatures = getSignaturesOfType(onfulfilledParameterType, ts.SignatureKind.Call); if (onfulfilledParameterSignatures.length === 0) { if (errorNode) { - error(errorNode, Diagnostics.The_first_parameter_of_the_then_method_of_a_promise_must_be_a_callback); + error(errorNode, ts.Diagnostics.The_first_parameter_of_the_then_method_of_a_promise_must_be_a_callback); } return undefined; } - return typeAsPromise.promisedTypeOfPromise = getUnionType(map(onfulfilledParameterSignatures, getTypeOfFirstParameterOfSignature), UnionReduction.Subtype); + return typeAsPromise.promisedTypeOfPromise = getUnionType(ts.map(onfulfilledParameterSignatures, getTypeOfFirstParameterOfSignature), ts.UnionReduction.Subtype); } /** @@ -36391,7 +35589,7 @@ namespace ts { * Promise-like type; otherwise, it is the type of the expression. This is used to reflect * The runtime behavior of the `await` keyword. */ - function checkAwaitedType(type: Type, withAlias: boolean, errorNode: Node, diagnosticMessage: DiagnosticMessage, arg0?: string | number): Type { + function checkAwaitedType(type: ts.Type, withAlias: boolean, errorNode: ts.Node, diagnosticMessage: ts.DiagnosticMessage, arg0?: string | number): ts.Type { const awaitedType = withAlias ? getAwaitedType(type, errorNode, diagnosticMessage, arg0) : getAwaitedTypeNoAlias(type, errorNode, diagnosticMessage, arg0); @@ -36401,24 +35599,24 @@ namespace ts { /** * Determines whether a type is an object with a callable `then` member. */ - function isThenableType(type: Type): boolean { - if (allTypesAssignableToKind(type, TypeFlags.Primitive | TypeFlags.Never)) { + function isThenableType(type: ts.Type): boolean { + if (allTypesAssignableToKind(type, ts.TypeFlags.Primitive | ts.TypeFlags.Never)) { // primitive types cannot be considered "thenable" since they are not objects. return false; } - const thenFunction = getTypeOfPropertyOfType(type, "then" as __String); - return !!thenFunction && getSignaturesOfType(getTypeWithFacts(thenFunction, TypeFacts.NEUndefinedOrNull), SignatureKind.Call).length > 0; + const thenFunction = getTypeOfPropertyOfType(type, "then" as ts.__String); + return !!thenFunction && getSignaturesOfType(getTypeWithFacts(thenFunction, TypeFacts.NEUndefinedOrNull), ts.SignatureKind.Call).length > 0; } - interface AwaitedTypeInstantiation extends Type { + interface AwaitedTypeInstantiation extends ts.Type { _awaitedTypeBrand: never; - aliasSymbol: Symbol; - aliasTypeArguments: readonly Type[]; + aliasSymbol: ts.Symbol; + aliasTypeArguments: readonly ts.Type[]; } - function isAwaitedTypeInstantiation(type: Type): type is AwaitedTypeInstantiation { - if (type.flags & TypeFlags.Conditional) { + function isAwaitedTypeInstantiation(type: ts.Type): type is AwaitedTypeInstantiation { + if (type.flags & ts.TypeFlags.Conditional) { const awaitedSymbol = getGlobalAwaitedSymbol(/*reportErrors*/ false); return !!awaitedSymbol && type.aliasSymbol === awaitedSymbol && type.aliasTypeArguments?.length === 1; } @@ -36428,13 +35626,13 @@ namespace ts { /** * For a generic `Awaited`, gets `T`. */ - function unwrapAwaitedType(type: Type) { - return type.flags & TypeFlags.Union ? mapType(type, unwrapAwaitedType) : + function unwrapAwaitedType(type: ts.Type) { + return type.flags & ts.TypeFlags.Union ? mapType(type, unwrapAwaitedType) : isAwaitedTypeInstantiation(type) ? type.aliasTypeArguments[0] : type; } - function createAwaitedTypeIfNeeded(type: Type): Type { + function createAwaitedTypeIfNeeded(type: ts.Type): ts.Type { // We wrap type `T` in `Awaited` based on the following conditions: // - `T` is not already an `Awaited`, and // - `T` is generic, and @@ -36457,7 +35655,7 @@ namespace ts { const baseConstraint = getBaseConstraintOfType(type); // Only instantiate `Awaited` if `T` has no base constraint, or the base constraint of `T` is `any`, `unknown`, `{}`, `object`, // or is promise-like. - if (!baseConstraint || (baseConstraint.flags & TypeFlags.AnyOrUnknown) || isEmptyObjectType(baseConstraint) || isThenableType(baseConstraint)) { + if (!baseConstraint || (baseConstraint.flags & ts.TypeFlags.AnyOrUnknown) || isEmptyObjectType(baseConstraint) || isThenableType(baseConstraint)) { // Nothing to do if `Awaited` doesn't exist const awaitedSymbol = getGlobalAwaitedSymbol(/*reportErrors*/ true); if (awaitedSymbol) { @@ -36468,7 +35666,7 @@ namespace ts { } } - Debug.assert(getPromisedTypeOfPromise(type) === undefined, "type provided should not be a non-generic 'promise'-like."); + ts.Debug.assert(getPromisedTypeOfPromise(type) === undefined, "type provided should not be a non-generic 'promise'-like."); return type; } @@ -36482,7 +35680,7 @@ namespace ts { * * This is used to reflect the runtime behavior of the `await` keyword. */ - function getAwaitedType(type: Type, errorNode?: Node, diagnosticMessage?: DiagnosticMessage, arg0?: string | number): Type | undefined { + function getAwaitedType(type: ts.Type, errorNode?: ts.Node, diagnosticMessage?: ts.DiagnosticMessage, arg0?: string | number): ts.Type | undefined { const awaitedType = getAwaitedTypeNoAlias(type, errorNode, diagnosticMessage, arg0); return awaitedType && createAwaitedTypeIfNeeded(awaitedType); } @@ -36492,7 +35690,7 @@ namespace ts { * * @see {@link getAwaitedType} */ - function getAwaitedTypeNoAlias(type: Type, errorNode?: Node, diagnosticMessage?: DiagnosticMessage, arg0?: string | number): Type | undefined { + function getAwaitedTypeNoAlias(type: ts.Type, errorNode?: ts.Node, diagnosticMessage?: ts.DiagnosticMessage, arg0?: string | number): ts.Type | undefined { if (isTypeAny(type)) { return type; } @@ -36503,18 +35701,20 @@ namespace ts { } // If we've already cached an awaited type, return a possible `Awaited` for it. - const typeAsAwaitable = type as PromiseOrAwaitableType; + const typeAsAwaitable = type as ts.PromiseOrAwaitableType; if (typeAsAwaitable.awaitedTypeOfType) { return typeAsAwaitable.awaitedTypeOfType; } // For a union, get a union of the awaited types of each constituent. - if (type.flags & TypeFlags.Union) { - const mapper = errorNode ? (constituentType: Type) => getAwaitedTypeNoAlias(constituentType, errorNode, diagnosticMessage, arg0) : getAwaitedTypeNoAlias; + if (type.flags & ts.TypeFlags.Union) { + const mapper = errorNode ? (constituentType: ts.Type) => getAwaitedTypeNoAlias(constituentType, errorNode, diagnosticMessage, arg0) : getAwaitedTypeNoAlias; return typeAsAwaitable.awaitedTypeOfType = mapType(type, mapper); } - const thisTypeForErrorOut: { value: Type | undefined } = { value: undefined }; + const thisTypeForErrorOut: { + value: ts.Type | undefined; + } = { value: undefined }; const promisedType = getPromisedTypeOfPromise(type, /*errorNode*/ undefined, thisTypeForErrorOut); if (promisedType) { if (type.id === promisedType.id || awaitedTypeStack.lastIndexOf(promisedType.id) >= 0) { @@ -36552,7 +35752,7 @@ namespace ts { // } // if (errorNode) { - error(errorNode, Diagnostics.Type_is_referenced_directly_or_indirectly_in_the_fulfillment_callback_of_its_own_then_method); + error(errorNode, ts.Diagnostics.Type_is_referenced_directly_or_indirectly_in_the_fulfillment_callback_of_its_own_then_method); } return undefined; } @@ -36587,13 +35787,13 @@ namespace ts { // be treated as a promise, they can cast to . if (isThenableType(type)) { if (errorNode) { - Debug.assertIsDefined(diagnosticMessage); - let chain: DiagnosticMessageChain | undefined; + ts.Debug.assertIsDefined(diagnosticMessage); + let chain: ts.DiagnosticMessageChain | undefined; if (thisTypeForErrorOut.value) { - chain = chainDiagnosticMessages(chain, Diagnostics.The_this_context_of_type_0_is_not_assignable_to_method_s_this_of_type_1, typeToString(type), typeToString(thisTypeForErrorOut.value)); + chain = ts.chainDiagnosticMessages(chain, ts.Diagnostics.The_this_context_of_type_0_is_not_assignable_to_method_s_this_of_type_1, typeToString(type), typeToString(thisTypeForErrorOut.value)); } - chain = chainDiagnosticMessages(chain, diagnosticMessage, arg0); - diagnostics.add(createDiagnosticForNodeFromMessageChain(errorNode, chain)); + chain = ts.chainDiagnosticMessages(chain, diagnosticMessage, arg0); + diagnostics.add(ts.createDiagnosticForNodeFromMessageChain(errorNode, chain)); } return undefined; } @@ -36613,7 +35813,7 @@ namespace ts { * * @param node The signature to check */ - function checkAsyncFunctionReturnType(node: FunctionLikeDeclaration | MethodSignature, returnTypeNode: TypeNode) { + function checkAsyncFunctionReturnType(node: ts.FunctionLikeDeclaration | ts.MethodSignature, returnTypeNode: ts.TypeNode) { // As part of our emit for an async function, we will need to emit the entity name of // the return type annotation as an expression. To meet the necessary runtime semantics // for __awaiter, we must also check that the type of the declaration (e.g. the static @@ -36640,7 +35840,7 @@ namespace ts { // const returnType = getTypeFromTypeNode(returnTypeNode); - if (languageVersion >= ScriptTarget.ES2015) { + if (languageVersion >= ts.ScriptTarget.ES2015) { if (isErrorType(returnType)) { return; } @@ -36648,7 +35848,7 @@ namespace ts { if (globalPromiseType !== emptyGenericType && !isReferenceToType(returnType, globalPromiseType)) { // The promise type was not a valid type reference to the global promise type, so we // report an error and return the unknown type. - error(returnTypeNode, Diagnostics.The_return_type_of_an_async_function_or_method_must_be_the_global_Promise_T_type_Did_you_mean_to_write_Promise_0, typeToString(getAwaitedTypeNoAlias(returnType) || voidType)); + error(returnTypeNode, ts.Diagnostics.The_return_type_of_an_async_function_or_method_must_be_the_global_Promise_T_type_Did_you_mean_to_write_Promise_0, typeToString(getAwaitedTypeNoAlias(returnType) || voidType)); return; } } @@ -36660,20 +35860,20 @@ namespace ts { return; } - const promiseConstructorName = getEntityNameFromTypeNode(returnTypeNode); + const promiseConstructorName = ts.getEntityNameFromTypeNode(returnTypeNode); if (promiseConstructorName === undefined) { - error(returnTypeNode, Diagnostics.Type_0_is_not_a_valid_async_function_return_type_in_ES5_SlashES3_because_it_does_not_refer_to_a_Promise_compatible_constructor_value, typeToString(returnType)); + error(returnTypeNode, ts.Diagnostics.Type_0_is_not_a_valid_async_function_return_type_in_ES5_SlashES3_because_it_does_not_refer_to_a_Promise_compatible_constructor_value, typeToString(returnType)); return; } - const promiseConstructorSymbol = resolveEntityName(promiseConstructorName, SymbolFlags.Value, /*ignoreErrors*/ true); + const promiseConstructorSymbol = resolveEntityName(promiseConstructorName, ts.SymbolFlags.Value, /*ignoreErrors*/ true); const promiseConstructorType = promiseConstructorSymbol ? getTypeOfSymbol(promiseConstructorSymbol) : errorType; if (isErrorType(promiseConstructorType)) { - if (promiseConstructorName.kind === SyntaxKind.Identifier && promiseConstructorName.escapedText === "Promise" && getTargetType(returnType) === getGlobalPromiseType(/*reportErrors*/ false)) { - error(returnTypeNode, Diagnostics.An_async_function_or_method_in_ES5_SlashES3_requires_the_Promise_constructor_Make_sure_you_have_a_declaration_for_the_Promise_constructor_or_include_ES2015_in_your_lib_option); + if (promiseConstructorName.kind === ts.SyntaxKind.Identifier && promiseConstructorName.escapedText === "Promise" && getTargetType(returnType) === getGlobalPromiseType(/*reportErrors*/ false)) { + error(returnTypeNode, ts.Diagnostics.An_async_function_or_method_in_ES5_SlashES3_requires_the_Promise_constructor_Make_sure_you_have_a_declaration_for_the_Promise_constructor_or_include_ES2015_in_your_lib_option); } else { - error(returnTypeNode, Diagnostics.Type_0_is_not_a_valid_async_function_return_type_in_ES5_SlashES3_because_it_does_not_refer_to_a_Promise_compatible_constructor_value, entityNameToString(promiseConstructorName)); + error(returnTypeNode, ts.Diagnostics.Type_0_is_not_a_valid_async_function_return_type_in_ES5_SlashES3_because_it_does_not_refer_to_a_Promise_compatible_constructor_value, ts.entityNameToString(promiseConstructorName)); } return; } @@ -36682,88 +35882,81 @@ namespace ts { if (globalPromiseConstructorLikeType === emptyObjectType) { // If we couldn't resolve the global PromiseConstructorLike type we cannot verify // compatibility with __awaiter. - error(returnTypeNode, Diagnostics.Type_0_is_not_a_valid_async_function_return_type_in_ES5_SlashES3_because_it_does_not_refer_to_a_Promise_compatible_constructor_value, entityNameToString(promiseConstructorName)); + error(returnTypeNode, ts.Diagnostics.Type_0_is_not_a_valid_async_function_return_type_in_ES5_SlashES3_because_it_does_not_refer_to_a_Promise_compatible_constructor_value, ts.entityNameToString(promiseConstructorName)); return; } - if (!checkTypeAssignableTo(promiseConstructorType, globalPromiseConstructorLikeType, returnTypeNode, - Diagnostics.Type_0_is_not_a_valid_async_function_return_type_in_ES5_SlashES3_because_it_does_not_refer_to_a_Promise_compatible_constructor_value)) { + if (!checkTypeAssignableTo(promiseConstructorType, globalPromiseConstructorLikeType, returnTypeNode, ts.Diagnostics.Type_0_is_not_a_valid_async_function_return_type_in_ES5_SlashES3_because_it_does_not_refer_to_a_Promise_compatible_constructor_value)) { return; } // Verify there is no local declaration that could collide with the promise constructor. - const rootName = promiseConstructorName && getFirstIdentifier(promiseConstructorName); - const collidingSymbol = getSymbol(node.locals!, rootName.escapedText, SymbolFlags.Value); + const rootName = promiseConstructorName && ts.getFirstIdentifier(promiseConstructorName); + const collidingSymbol = getSymbol(node.locals!, rootName.escapedText, ts.SymbolFlags.Value); if (collidingSymbol) { - error(collidingSymbol.valueDeclaration, Diagnostics.Duplicate_identifier_0_Compiler_uses_declaration_1_to_support_async_functions, - idText(rootName), - entityNameToString(promiseConstructorName)); + error(collidingSymbol.valueDeclaration, ts.Diagnostics.Duplicate_identifier_0_Compiler_uses_declaration_1_to_support_async_functions, ts.idText(rootName), ts.entityNameToString(promiseConstructorName)); return; } } - checkAwaitedType(returnType, /*withAlias*/ false, node, Diagnostics.The_return_type_of_an_async_function_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member); + checkAwaitedType(returnType, /*withAlias*/ false, node, ts.Diagnostics.The_return_type_of_an_async_function_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member); } /** Check a decorator */ - function checkDecorator(node: Decorator): void { + function checkDecorator(node: ts.Decorator): void { const signature = getResolvedSignature(node); checkDeprecatedSignature(signature, node); const returnType = getReturnTypeOfSignature(signature); - if (returnType.flags & TypeFlags.Any) { + if (returnType.flags & ts.TypeFlags.Any) { return; } - let headMessage: DiagnosticMessage; - let expectedReturnType: Type; + let headMessage: ts.DiagnosticMessage; + let expectedReturnType: ts.Type; switch (node.parent.kind) { - case SyntaxKind.ClassDeclaration: - headMessage = Diagnostics.Decorator_function_return_type_0_is_not_assignable_to_type_1; + case ts.SyntaxKind.ClassDeclaration: + headMessage = ts.Diagnostics.Decorator_function_return_type_0_is_not_assignable_to_type_1; const classSymbol = getSymbolOfNode(node.parent); const classConstructorType = getTypeOfSymbol(classSymbol); expectedReturnType = getUnionType([classConstructorType, voidType]); break; - case SyntaxKind.PropertyDeclaration: - case SyntaxKind.Parameter: - headMessage = Diagnostics.Decorator_function_return_type_is_0_but_is_expected_to_be_void_or_any; + case ts.SyntaxKind.PropertyDeclaration: + case ts.SyntaxKind.Parameter: + headMessage = ts.Diagnostics.Decorator_function_return_type_is_0_but_is_expected_to_be_void_or_any; expectedReturnType = voidType; break; - case SyntaxKind.MethodDeclaration: - case SyntaxKind.GetAccessor: - case SyntaxKind.SetAccessor: - headMessage = Diagnostics.Decorator_function_return_type_0_is_not_assignable_to_type_1; + case ts.SyntaxKind.MethodDeclaration: + case ts.SyntaxKind.GetAccessor: + case ts.SyntaxKind.SetAccessor: + headMessage = ts.Diagnostics.Decorator_function_return_type_0_is_not_assignable_to_type_1; const methodType = getTypeOfNode(node.parent); const descriptorType = createTypedPropertyDescriptorType(methodType); expectedReturnType = getUnionType([descriptorType, voidType]); break; default: - return Debug.fail(); + return ts.Debug.fail(); } - checkTypeAssignableTo( - returnType, - expectedReturnType, - node, - headMessage); + checkTypeAssignableTo(returnType, expectedReturnType, node, headMessage); } /** * If a TypeNode can be resolved to a value symbol imported from an external module, it is * marked as referenced to prevent import elision. */ - function markTypeNodeAsReferenced(node: TypeNode) { - markEntityNameOrEntityExpressionAsReference(node && getEntityNameFromTypeNode(node), /*forDecoratorMetadata*/ false); + function markTypeNodeAsReferenced(node: ts.TypeNode) { + markEntityNameOrEntityExpressionAsReference(node && ts.getEntityNameFromTypeNode(node), /*forDecoratorMetadata*/ false); } - function markEntityNameOrEntityExpressionAsReference(typeName: EntityNameOrEntityNameExpression | undefined, forDecoratorMetadata: boolean) { - if (!typeName) return; - - const rootName = getFirstIdentifier(typeName); - const meaning = (typeName.kind === SyntaxKind.Identifier ? SymbolFlags.Type : SymbolFlags.Namespace) | SymbolFlags.Alias; + function markEntityNameOrEntityExpressionAsReference(typeName: ts.EntityNameOrEntityNameExpression | undefined, forDecoratorMetadata: boolean) { + if (!typeName) + return; + const rootName = ts.getFirstIdentifier(typeName); + const meaning = (typeName.kind === ts.SyntaxKind.Identifier ? ts.SymbolFlags.Type : ts.SymbolFlags.Namespace) | ts.SymbolFlags.Alias; const rootSymbol = resolveName(rootName, rootName.escapedText, meaning, /*nameNotFoundMessage*/ undefined, /*nameArg*/ undefined, /*isReference*/ true); - if (rootSymbol && rootSymbol.flags & SymbolFlags.Alias) { + if (rootSymbol && rootSymbol.flags & ts.SymbolFlags.Alias) { if (symbolIsValue(rootSymbol) && !isConstEnumOrConstEnumOnlyModule(resolveAlias(rootSymbol)) && !getTypeOnlyAliasDeclaration(rootSymbol)) { @@ -36771,13 +35964,13 @@ namespace ts { } else if (forDecoratorMetadata && compilerOptions.isolatedModules - && getEmitModuleKind(compilerOptions) >= ModuleKind.ES2015 + && ts.getEmitModuleKind(compilerOptions) >= ts.ModuleKind.ES2015 && !symbolIsValue(rootSymbol) - && !some(rootSymbol.declarations, isTypeOnlyImportOrExportDeclaration)) { - const diag = error(typeName, Diagnostics.A_type_referenced_in_a_decorated_signature_must_be_imported_with_import_type_or_a_namespace_import_when_isolatedModules_and_emitDecoratorMetadata_are_enabled); - const aliasDeclaration = find(rootSymbol.declarations || emptyArray, isAliasSymbolDeclaration); + && !ts.some(rootSymbol.declarations, ts.isTypeOnlyImportOrExportDeclaration)) { + const diag = error(typeName, ts.Diagnostics.A_type_referenced_in_a_decorated_signature_must_be_imported_with_import_type_or_a_namespace_import_when_isolatedModules_and_emitDecoratorMetadata_are_enabled); + const aliasDeclaration = ts.find(rootSymbol.declarations || ts.emptyArray, isAliasSymbolDeclaration); if (aliasDeclaration) { - addRelatedInfo(diag, createDiagnosticForNode(aliasDeclaration, Diagnostics._0_was_imported_here, idText(rootName))); + ts.addRelatedInfo(diag, ts.createDiagnosticForNode(aliasDeclaration, ts.Diagnostics._0_was_imported_here, ts.idText(rootName))); } } } @@ -36790,43 +35983,40 @@ namespace ts { * union and intersection type * @param node */ - function markDecoratorMedataDataTypeNodeAsReferenced(node: TypeNode | undefined): void { + function markDecoratorMedataDataTypeNodeAsReferenced(node: ts.TypeNode | undefined): void { const entityName = getEntityNameForDecoratorMetadata(node); - if (entityName && isEntityName(entityName)) { + if (entityName && ts.isEntityName(entityName)) { markEntityNameOrEntityExpressionAsReference(entityName, /*forDecoratorMetadata*/ true); } } - function getEntityNameForDecoratorMetadata(node: TypeNode | undefined): EntityName | undefined { + function getEntityNameForDecoratorMetadata(node: ts.TypeNode | undefined): ts.EntityName | undefined { if (node) { switch (node.kind) { - case SyntaxKind.IntersectionType: - case SyntaxKind.UnionType: - return getEntityNameForDecoratorMetadataFromTypeList((node as UnionOrIntersectionTypeNode).types); - - case SyntaxKind.ConditionalType: - return getEntityNameForDecoratorMetadataFromTypeList([(node as ConditionalTypeNode).trueType, (node as ConditionalTypeNode).falseType]); - - case SyntaxKind.ParenthesizedType: - case SyntaxKind.NamedTupleMember: - return getEntityNameForDecoratorMetadata((node as ParenthesizedTypeNode).type); - - case SyntaxKind.TypeReference: - return (node as TypeReferenceNode).typeName; + case ts.SyntaxKind.IntersectionType: + case ts.SyntaxKind.UnionType: + return getEntityNameForDecoratorMetadataFromTypeList((node as ts.UnionOrIntersectionTypeNode).types); + case ts.SyntaxKind.ConditionalType: + return getEntityNameForDecoratorMetadataFromTypeList([(node as ts.ConditionalTypeNode).trueType, (node as ts.ConditionalTypeNode).falseType]); + case ts.SyntaxKind.ParenthesizedType: + case ts.SyntaxKind.NamedTupleMember: + return getEntityNameForDecoratorMetadata((node as ts.ParenthesizedTypeNode).type); + case ts.SyntaxKind.TypeReference: + return (node as ts.TypeReferenceNode).typeName; } } } - function getEntityNameForDecoratorMetadataFromTypeList(types: readonly TypeNode[]): EntityName | undefined { - let commonEntityName: EntityName | undefined; + function getEntityNameForDecoratorMetadataFromTypeList(types: readonly ts.TypeNode[]): ts.EntityName | undefined { + let commonEntityName: ts.EntityName | undefined; for (let typeNode of types) { - while (typeNode.kind === SyntaxKind.ParenthesizedType || typeNode.kind === SyntaxKind.NamedTupleMember) { - typeNode = (typeNode as ParenthesizedTypeNode | NamedTupleMember).type; // Skip parens if need be + while (typeNode.kind === ts.SyntaxKind.ParenthesizedType || typeNode.kind === ts.SyntaxKind.NamedTupleMember) { + typeNode = (typeNode as ts.ParenthesizedTypeNode | ts.NamedTupleMember).type; // Skip parens if need be } - if (typeNode.kind === SyntaxKind.NeverKeyword) { + if (typeNode.kind === ts.SyntaxKind.NeverKeyword) { continue; // Always elide `never` from the union/intersection if possible } - if (!strictNullChecks && (typeNode.kind === SyntaxKind.LiteralType && (typeNode as LiteralTypeNode).literal.kind === SyntaxKind.NullKeyword || typeNode.kind === SyntaxKind.UndefinedKeyword)) { + if (!strictNullChecks && (typeNode.kind === ts.SyntaxKind.LiteralType && (typeNode as ts.LiteralTypeNode).literal.kind === ts.SyntaxKind.NullKeyword || typeNode.kind === ts.SyntaxKind.UndefinedKeyword)) { continue; // Elide null and undefined from unions for metadata, just like what we did prior to the implementation of strict null checks } const individualEntityName = getEntityNameForDecoratorMetadata(typeNode); @@ -36842,8 +36032,8 @@ namespace ts { // Keep this in sync with serializeUnionOrIntersectionType // Verify if they refer to same entity and is identifier // return undefined if they dont match because we would emit object - if (!isIdentifier(commonEntityName) || - !isIdentifier(individualEntityName) || + if (!ts.isIdentifier(commonEntityName) || + !ts.isIdentifier(individualEntityName) || commonEntityName.escapedText !== individualEntityName.escapedText) { return undefined; } @@ -36855,40 +36045,40 @@ namespace ts { return commonEntityName; } - function getParameterTypeNodeForDecoratorCheck(node: ParameterDeclaration): TypeNode | undefined { - const typeNode = getEffectiveTypeAnnotationNode(node); - return isRestParameter(node) ? getRestParameterElementType(typeNode) : typeNode; + function getParameterTypeNodeForDecoratorCheck(node: ts.ParameterDeclaration): ts.TypeNode | undefined { + const typeNode = ts.getEffectiveTypeAnnotationNode(node); + return ts.isRestParameter(node) ? ts.getRestParameterElementType(typeNode) : typeNode; } /** Check the decorators of a node */ - function checkDecorators(node: Node): void { + function checkDecorators(node: ts.Node): void { if (!node.decorators) { return; } // skip this check for nodes that cannot have decorators. These should have already had an error reported by // checkGrammarDecorators. - if (!nodeCanBeDecorated(node, node.parent, node.parent.parent)) { + if (!ts.nodeCanBeDecorated(node, node.parent, node.parent.parent)) { return; } if (!compilerOptions.experimentalDecorators) { - error(node, Diagnostics.Experimental_support_for_decorators_is_a_feature_that_is_subject_to_change_in_a_future_release_Set_the_experimentalDecorators_option_in_your_tsconfig_or_jsconfig_to_remove_this_warning); + error(node, ts.Diagnostics.Experimental_support_for_decorators_is_a_feature_that_is_subject_to_change_in_a_future_release_Set_the_experimentalDecorators_option_in_your_tsconfig_or_jsconfig_to_remove_this_warning); } const firstDecorator = node.decorators[0]; - checkExternalEmitHelpers(firstDecorator, ExternalEmitHelpers.Decorate); - if (node.kind === SyntaxKind.Parameter) { - checkExternalEmitHelpers(firstDecorator, ExternalEmitHelpers.Param); + checkExternalEmitHelpers(firstDecorator, ts.ExternalEmitHelpers.Decorate); + if (node.kind === ts.SyntaxKind.Parameter) { + checkExternalEmitHelpers(firstDecorator, ts.ExternalEmitHelpers.Param); } if (compilerOptions.emitDecoratorMetadata) { - checkExternalEmitHelpers(firstDecorator, ExternalEmitHelpers.Metadata); + checkExternalEmitHelpers(firstDecorator, ts.ExternalEmitHelpers.Metadata); // we only need to perform these checks if we are emitting serialized type metadata for the target of a decorator. switch (node.kind) { - case SyntaxKind.ClassDeclaration: - const constructor = getFirstConstructorWithBody(node as ClassDeclaration); + case ts.SyntaxKind.ClassDeclaration: + const constructor = ts.getFirstConstructorWithBody(node as ts.ClassDeclaration); if (constructor) { for (const parameter of constructor.parameters) { markDecoratorMedataDataTypeNodeAsReferenced(getParameterTypeNodeForDecoratorCheck(parameter)); @@ -36896,27 +36086,27 @@ namespace ts { } break; - case SyntaxKind.GetAccessor: - case SyntaxKind.SetAccessor: - const otherKind = node.kind === SyntaxKind.GetAccessor ? SyntaxKind.SetAccessor : SyntaxKind.GetAccessor; - const otherAccessor = getDeclarationOfKind(getSymbolOfNode(node as AccessorDeclaration), otherKind); - markDecoratorMedataDataTypeNodeAsReferenced(getAnnotatedAccessorTypeNode(node as AccessorDeclaration) || otherAccessor && getAnnotatedAccessorTypeNode(otherAccessor)); + case ts.SyntaxKind.GetAccessor: + case ts.SyntaxKind.SetAccessor: + const otherKind = node.kind === ts.SyntaxKind.GetAccessor ? ts.SyntaxKind.SetAccessor : ts.SyntaxKind.GetAccessor; + const otherAccessor = ts.getDeclarationOfKind(getSymbolOfNode(node as ts.AccessorDeclaration), otherKind); + markDecoratorMedataDataTypeNodeAsReferenced(getAnnotatedAccessorTypeNode(node as ts.AccessorDeclaration) || otherAccessor && getAnnotatedAccessorTypeNode(otherAccessor)); break; - case SyntaxKind.MethodDeclaration: - for (const parameter of (node as FunctionLikeDeclaration).parameters) { + case ts.SyntaxKind.MethodDeclaration: + for (const parameter of (node as ts.FunctionLikeDeclaration).parameters) { markDecoratorMedataDataTypeNodeAsReferenced(getParameterTypeNodeForDecoratorCheck(parameter)); } - markDecoratorMedataDataTypeNodeAsReferenced(getEffectiveReturnTypeNode(node as FunctionLikeDeclaration)); + markDecoratorMedataDataTypeNodeAsReferenced(ts.getEffectiveReturnTypeNode(node as ts.FunctionLikeDeclaration)); break; - case SyntaxKind.PropertyDeclaration: - markDecoratorMedataDataTypeNodeAsReferenced(getEffectiveTypeAnnotationNode(node as ParameterDeclaration)); + case ts.SyntaxKind.PropertyDeclaration: + markDecoratorMedataDataTypeNodeAsReferenced(ts.getEffectiveTypeAnnotationNode(node as ts.ParameterDeclaration)); break; - case SyntaxKind.Parameter: - markDecoratorMedataDataTypeNodeAsReferenced(getParameterTypeNodeForDecoratorCheck(node as ParameterDeclaration)); - const containingSignature = (node as ParameterDeclaration).parent; + case ts.SyntaxKind.Parameter: + markDecoratorMedataDataTypeNodeAsReferenced(getParameterTypeNodeForDecoratorCheck(node as ts.ParameterDeclaration)); + const containingSignature = (node as ts.ParameterDeclaration).parent; for (const parameter of containingSignature.parameters) { markDecoratorMedataDataTypeNodeAsReferenced(getParameterTypeNodeForDecoratorCheck(parameter)); } @@ -36924,10 +36114,10 @@ namespace ts { } } - forEach(node.decorators, checkDecorator); + ts.forEach(node.decorators, checkDecorator); } - function checkFunctionDeclaration(node: FunctionDeclaration): void { + function checkFunctionDeclaration(node: ts.FunctionDeclaration): void { addLazyDiagnostic(checkFunctionDeclarationDiagnostics); function checkFunctionDeclarationDiagnostics() { @@ -36937,107 +36127,107 @@ namespace ts { } } - function checkJSDocTypeAliasTag(node: JSDocTypedefTag | JSDocCallbackTag) { + function checkJSDocTypeAliasTag(node: ts.JSDocTypedefTag | ts.JSDocCallbackTag) { if (!node.typeExpression) { // If the node had `@property` tags, `typeExpression` would have been set to the first property tag. - error(node.name, Diagnostics.JSDoc_typedef_tag_should_either_have_a_type_annotation_or_be_followed_by_property_or_member_tags); + error(node.name, ts.Diagnostics.JSDoc_typedef_tag_should_either_have_a_type_annotation_or_be_followed_by_property_or_member_tags); } if (node.name) { - checkTypeNameIsReserved(node.name, Diagnostics.Type_alias_name_cannot_be_0); + checkTypeNameIsReserved(node.name, ts.Diagnostics.Type_alias_name_cannot_be_0); } checkSourceElement(node.typeExpression); - checkTypeParameters(getEffectiveTypeParameterDeclarations(node)); + checkTypeParameters(ts.getEffectiveTypeParameterDeclarations(node)); } - function checkJSDocTemplateTag(node: JSDocTemplateTag): void { + function checkJSDocTemplateTag(node: ts.JSDocTemplateTag): void { checkSourceElement(node.constraint); for (const tp of node.typeParameters) { checkSourceElement(tp); } } - function checkJSDocTypeTag(node: JSDocTypeTag) { + function checkJSDocTypeTag(node: ts.JSDocTypeTag) { checkSourceElement(node.typeExpression); } - function checkJSDocParameterTag(node: JSDocParameterTag) { + function checkJSDocParameterTag(node: ts.JSDocParameterTag) { checkSourceElement(node.typeExpression); } - function checkJSDocPropertyTag(node: JSDocPropertyTag) { + function checkJSDocPropertyTag(node: ts.JSDocPropertyTag) { checkSourceElement(node.typeExpression); } - function checkJSDocFunctionType(node: JSDocFunctionType): void { + function checkJSDocFunctionType(node: ts.JSDocFunctionType): void { addLazyDiagnostic(checkJSDocFunctionTypeImplicitAny); checkSignatureDeclaration(node); function checkJSDocFunctionTypeImplicitAny() { - if (!node.type && !isJSDocConstructSignature(node)) { + if (!node.type && !ts.isJSDocConstructSignature(node)) { reportImplicitAny(node, anyType); } } } - function checkJSDocImplementsTag(node: JSDocImplementsTag): void { - const classLike = getEffectiveJSDocHost(node); - if (!classLike || !isClassDeclaration(classLike) && !isClassExpression(classLike)) { - error(classLike, Diagnostics.JSDoc_0_is_not_attached_to_a_class, idText(node.tagName)); + function checkJSDocImplementsTag(node: ts.JSDocImplementsTag): void { + const classLike = ts.getEffectiveJSDocHost(node); + if (!classLike || !ts.isClassDeclaration(classLike) && !ts.isClassExpression(classLike)) { + error(classLike, ts.Diagnostics.JSDoc_0_is_not_attached_to_a_class, ts.idText(node.tagName)); } } - function checkJSDocAugmentsTag(node: JSDocAugmentsTag): void { - const classLike = getEffectiveJSDocHost(node); - if (!classLike || !isClassDeclaration(classLike) && !isClassExpression(classLike)) { - error(classLike, Diagnostics.JSDoc_0_is_not_attached_to_a_class, idText(node.tagName)); + function checkJSDocAugmentsTag(node: ts.JSDocAugmentsTag): void { + const classLike = ts.getEffectiveJSDocHost(node); + if (!classLike || !ts.isClassDeclaration(classLike) && !ts.isClassExpression(classLike)) { + error(classLike, ts.Diagnostics.JSDoc_0_is_not_attached_to_a_class, ts.idText(node.tagName)); return; } - const augmentsTags = getJSDocTags(classLike).filter(isJSDocAugmentsTag); - Debug.assert(augmentsTags.length > 0); + const augmentsTags = ts.getJSDocTags(classLike).filter(ts.isJSDocAugmentsTag); + ts.Debug.assert(augmentsTags.length > 0); if (augmentsTags.length > 1) { - error(augmentsTags[1], Diagnostics.Class_declarations_cannot_have_more_than_one_augments_or_extends_tag); + error(augmentsTags[1], ts.Diagnostics.Class_declarations_cannot_have_more_than_one_augments_or_extends_tag); } const name = getIdentifierFromEntityNameExpression(node.class.expression); - const extend = getClassExtendsHeritageElement(classLike); + const extend = ts.getClassExtendsHeritageElement(classLike); if (extend) { const className = getIdentifierFromEntityNameExpression(extend.expression); if (className && name.escapedText !== className.escapedText) { - error(name, Diagnostics.JSDoc_0_1_does_not_match_the_extends_2_clause, idText(node.tagName), idText(name), idText(className)); + error(name, ts.Diagnostics.JSDoc_0_1_does_not_match_the_extends_2_clause, ts.idText(node.tagName), ts.idText(name), ts.idText(className)); } } } - function checkJSDocAccessibilityModifiers(node: JSDocPublicTag | JSDocProtectedTag | JSDocPrivateTag): void { - const host = getJSDocHost(node); - if (host && isPrivateIdentifierClassElementDeclaration(host)) { - error(node, Diagnostics.An_accessibility_modifier_cannot_be_used_with_a_private_identifier); + function checkJSDocAccessibilityModifiers(node: ts.JSDocPublicTag | ts.JSDocProtectedTag | ts.JSDocPrivateTag): void { + const host = ts.getJSDocHost(node); + if (host && ts.isPrivateIdentifierClassElementDeclaration(host)) { + error(node, ts.Diagnostics.An_accessibility_modifier_cannot_be_used_with_a_private_identifier); } } - function getIdentifierFromEntityNameExpression(node: Identifier | PropertyAccessExpression): Identifier | PrivateIdentifier; - function getIdentifierFromEntityNameExpression(node: Expression): Identifier | PrivateIdentifier | undefined; - function getIdentifierFromEntityNameExpression(node: Expression): Identifier | PrivateIdentifier | undefined { + function getIdentifierFromEntityNameExpression(node: ts.Identifier | ts.PropertyAccessExpression): ts.Identifier | ts.PrivateIdentifier; + function getIdentifierFromEntityNameExpression(node: ts.Expression): ts.Identifier | ts.PrivateIdentifier | undefined; + function getIdentifierFromEntityNameExpression(node: ts.Expression): ts.Identifier | ts.PrivateIdentifier | undefined { switch (node.kind) { - case SyntaxKind.Identifier: - return node as Identifier; - case SyntaxKind.PropertyAccessExpression: - return (node as PropertyAccessExpression).name; + case ts.SyntaxKind.Identifier: + return node as ts.Identifier; + case ts.SyntaxKind.PropertyAccessExpression: + return (node as ts.PropertyAccessExpression).name; default: return undefined; } } - function checkFunctionOrMethodDeclaration(node: FunctionDeclaration | MethodDeclaration | MethodSignature): void { + function checkFunctionOrMethodDeclaration(node: ts.FunctionDeclaration | ts.MethodDeclaration | ts.MethodSignature): void { checkDecorators(node); checkSignatureDeclaration(node); - const functionFlags = getFunctionFlags(node); + const functionFlags = ts.getFunctionFlags(node); // Do not use hasDynamicName here, because that returns false for well known symbols. // We want to perform checkComputedPropertyName for all computed properties, including // well known symbols. - if (node.name && node.name.kind === SyntaxKind.ComputedPropertyName) { + if (node.name && node.name.kind === ts.SyntaxKind.ComputedPropertyName) { // This check will account for methods in class/interface declarations, // as well as accessors in classes/object literals checkComputedPropertyName(node.name); @@ -37055,7 +36245,7 @@ namespace ts { // checkFunctionOrConstructorSymbol wouldn't be called if we didnt ignore javascript function. const firstDeclaration = localSymbol.declarations?.find( // Get first non javascript function declaration - declaration => declaration.kind === node.kind && !(declaration.flags & NodeFlags.JavaScriptFile)); + declaration => declaration.kind === node.kind && !(declaration.flags & ts.NodeFlags.JavaScriptFile)); // Only type check the symbol once if (node === firstDeclaration) { @@ -37068,29 +36258,29 @@ namespace ts { } } - const body = node.kind === SyntaxKind.MethodSignature ? undefined : node.body; + const body = node.kind === ts.SyntaxKind.MethodSignature ? undefined : node.body; checkSourceElement(body); checkAllCodePathsInNonVoidFunctionReturnOrThrow(node, getReturnTypeFromAnnotation(node)); addLazyDiagnostic(checkFunctionOrMethodDeclarationDiagnostics); // A js function declaration can have a @type tag instead of a return type node, but that type must have a call signature - if (isInJSFile(node)) { - const typeTag = getJSDocTypeTag(node); + if (ts.isInJSFile(node)) { + const typeTag = ts.getJSDocTypeTag(node); if (typeTag && typeTag.typeExpression && !getContextualCallSignature(getTypeFromTypeNode(typeTag.typeExpression), node)) { - error(typeTag.typeExpression.type, Diagnostics.The_type_of_a_function_declaration_must_match_the_function_s_signature); + error(typeTag.typeExpression.type, ts.Diagnostics.The_type_of_a_function_declaration_must_match_the_function_s_signature); } } function checkFunctionOrMethodDeclarationDiagnostics() { - if (!getEffectiveReturnTypeNode(node)) { + if (!ts.getEffectiveReturnTypeNode(node)) { // Report an implicit any error if there is no body, no explicit return type, and node is not a private method // in an ambient context - if (nodeIsMissing(body) && !isPrivateWithinAmbient(node)) { + if (ts.nodeIsMissing(body) && !isPrivateWithinAmbient(node)) { reportImplicitAny(node, anyType); } - if (functionFlags & FunctionFlags.Generator && nodeIsPresent(body)) { + if (functionFlags & ts.FunctionFlags.Generator && ts.nodeIsPresent(body)) { // A generator with a body and no type annotation can still cause errors. It can error if the // yielded values have no common supertype, or it can give an implicit any error if it has no // yielded values. The only way to trigger these errors is to try checking its return type. @@ -37105,7 +36295,7 @@ namespace ts { function registerForUnusedIdentifiersCheckDiagnostics() { // May be in a call such as getTypeOfNode that happened to call this. But potentiallyUnusedIdentifiers is only defined in the scope of `checkSourceFile`. - const sourceFile = getSourceFileOfNode(node); + const sourceFile = ts.getSourceFileOfNode(node); let potentiallyUnusedIdentifiers = allPotentiallyUnusedIdentifiers.get(sourceFile.path); if (!potentiallyUnusedIdentifiers) { potentiallyUnusedIdentifiers = []; @@ -37117,152 +36307,151 @@ namespace ts { } } - type PotentiallyUnusedIdentifier = - | SourceFile | ModuleDeclaration | ClassLikeDeclaration | InterfaceDeclaration - | Block | CaseBlock | ForStatement | ForInStatement | ForOfStatement - | Exclude | TypeAliasDeclaration - | InferTypeNode; + type PotentiallyUnusedIdentifier = ts.SourceFile | ts.ModuleDeclaration | ts.ClassLikeDeclaration | ts.InterfaceDeclaration | ts.Block | ts.CaseBlock | ts.ForStatement | ts.ForInStatement | ts.ForOfStatement | Exclude | ts.TypeAliasDeclaration | ts.InferTypeNode; function checkUnusedIdentifiers(potentiallyUnusedIdentifiers: readonly PotentiallyUnusedIdentifier[], addDiagnostic: AddUnusedDiagnostic) { for (const node of potentiallyUnusedIdentifiers) { switch (node.kind) { - case SyntaxKind.ClassDeclaration: - case SyntaxKind.ClassExpression: + case ts.SyntaxKind.ClassDeclaration: + case ts.SyntaxKind.ClassExpression: checkUnusedClassMembers(node, addDiagnostic); checkUnusedTypeParameters(node, addDiagnostic); break; - case SyntaxKind.SourceFile: - case SyntaxKind.ModuleDeclaration: - case SyntaxKind.Block: - case SyntaxKind.CaseBlock: - case SyntaxKind.ForStatement: - case SyntaxKind.ForInStatement: - case SyntaxKind.ForOfStatement: + case ts.SyntaxKind.SourceFile: + case ts.SyntaxKind.ModuleDeclaration: + case ts.SyntaxKind.Block: + case ts.SyntaxKind.CaseBlock: + case ts.SyntaxKind.ForStatement: + case ts.SyntaxKind.ForInStatement: + case ts.SyntaxKind.ForOfStatement: checkUnusedLocalsAndParameters(node, addDiagnostic); break; - case SyntaxKind.Constructor: - case SyntaxKind.FunctionExpression: - case SyntaxKind.FunctionDeclaration: - case SyntaxKind.ArrowFunction: - case SyntaxKind.MethodDeclaration: - case SyntaxKind.GetAccessor: - case SyntaxKind.SetAccessor: + case ts.SyntaxKind.Constructor: + case ts.SyntaxKind.FunctionExpression: + case ts.SyntaxKind.FunctionDeclaration: + case ts.SyntaxKind.ArrowFunction: + case ts.SyntaxKind.MethodDeclaration: + case ts.SyntaxKind.GetAccessor: + case ts.SyntaxKind.SetAccessor: if (node.body) { // Don't report unused parameters in overloads checkUnusedLocalsAndParameters(node, addDiagnostic); } checkUnusedTypeParameters(node, addDiagnostic); break; - case SyntaxKind.MethodSignature: - case SyntaxKind.CallSignature: - case SyntaxKind.ConstructSignature: - case SyntaxKind.FunctionType: - case SyntaxKind.ConstructorType: - case SyntaxKind.TypeAliasDeclaration: - case SyntaxKind.InterfaceDeclaration: + case ts.SyntaxKind.MethodSignature: + case ts.SyntaxKind.CallSignature: + case ts.SyntaxKind.ConstructSignature: + case ts.SyntaxKind.FunctionType: + case ts.SyntaxKind.ConstructorType: + case ts.SyntaxKind.TypeAliasDeclaration: + case ts.SyntaxKind.InterfaceDeclaration: checkUnusedTypeParameters(node, addDiagnostic); break; - case SyntaxKind.InferType: + case ts.SyntaxKind.InferType: checkUnusedInferTypeParameter(node, addDiagnostic); break; default: - Debug.assertNever(node, "Node should not have been registered for unused identifiers check"); + ts.Debug.assertNever(node, "Node should not have been registered for unused identifiers check"); } } } - function errorUnusedLocal(declaration: Declaration, name: string, addDiagnostic: AddUnusedDiagnostic) { - const node = getNameOfDeclaration(declaration) || declaration; - const message = isTypeDeclaration(declaration) ? Diagnostics._0_is_declared_but_never_used : Diagnostics._0_is_declared_but_its_value_is_never_read; - addDiagnostic(declaration, UnusedKind.Local, createDiagnosticForNode(node, message, name)); + function errorUnusedLocal(declaration: ts.Declaration, name: string, addDiagnostic: AddUnusedDiagnostic) { + const node = ts.getNameOfDeclaration(declaration) || declaration; + const message = isTypeDeclaration(declaration) ? ts.Diagnostics._0_is_declared_but_never_used : ts.Diagnostics._0_is_declared_but_its_value_is_never_read; + addDiagnostic(declaration, UnusedKind.Local, ts.createDiagnosticForNode(node, message, name)); } - function isIdentifierThatStartsWithUnderscore(node: Node) { - return isIdentifier(node) && idText(node).charCodeAt(0) === CharacterCodes._; + function isIdentifierThatStartsWithUnderscore(node: ts.Node) { + return ts.isIdentifier(node) && ts.idText(node).charCodeAt(0) === ts.CharacterCodes._; } - function checkUnusedClassMembers(node: ClassDeclaration | ClassExpression, addDiagnostic: AddUnusedDiagnostic): void { + function checkUnusedClassMembers(node: ts.ClassDeclaration | ts.ClassExpression, addDiagnostic: AddUnusedDiagnostic): void { for (const member of node.members) { switch (member.kind) { - case SyntaxKind.MethodDeclaration: - case SyntaxKind.PropertyDeclaration: - case SyntaxKind.GetAccessor: - case SyntaxKind.SetAccessor: - if (member.kind === SyntaxKind.SetAccessor && member.symbol.flags & SymbolFlags.GetAccessor) { + case ts.SyntaxKind.MethodDeclaration: + case ts.SyntaxKind.PropertyDeclaration: + case ts.SyntaxKind.GetAccessor: + case ts.SyntaxKind.SetAccessor: + if (member.kind === ts.SyntaxKind.SetAccessor && member.symbol.flags & ts.SymbolFlags.GetAccessor) { // Already would have reported an error on the getter. break; } const symbol = getSymbolOfNode(member); if (!symbol.isReferenced - && (hasEffectiveModifier(member, ModifierFlags.Private) || isNamedDeclaration(member) && isPrivateIdentifier(member.name)) - && !(member.flags & NodeFlags.Ambient)) { - addDiagnostic(member, UnusedKind.Local, createDiagnosticForNode(member.name!, Diagnostics._0_is_declared_but_its_value_is_never_read, symbolToString(symbol))); + && (ts.hasEffectiveModifier(member, ts.ModifierFlags.Private) || ts.isNamedDeclaration(member) && ts.isPrivateIdentifier(member.name)) + && !(member.flags & ts.NodeFlags.Ambient)) { + addDiagnostic(member, UnusedKind.Local, ts.createDiagnosticForNode(member.name!, ts.Diagnostics._0_is_declared_but_its_value_is_never_read, symbolToString(symbol))); } break; - case SyntaxKind.Constructor: - for (const parameter of (member as ConstructorDeclaration).parameters) { - if (!parameter.symbol.isReferenced && hasSyntacticModifier(parameter, ModifierFlags.Private)) { - addDiagnostic(parameter, UnusedKind.Local, createDiagnosticForNode(parameter.name, Diagnostics.Property_0_is_declared_but_its_value_is_never_read, symbolName(parameter.symbol))); + case ts.SyntaxKind.Constructor: + for (const parameter of (member as ts.ConstructorDeclaration).parameters) { + if (!parameter.symbol.isReferenced && ts.hasSyntacticModifier(parameter, ts.ModifierFlags.Private)) { + addDiagnostic(parameter, UnusedKind.Local, ts.createDiagnosticForNode(parameter.name, ts.Diagnostics.Property_0_is_declared_but_its_value_is_never_read, ts.symbolName(parameter.symbol))); } } break; - case SyntaxKind.IndexSignature: - case SyntaxKind.SemicolonClassElement: - case SyntaxKind.ClassStaticBlockDeclaration: + case ts.SyntaxKind.IndexSignature: + case ts.SyntaxKind.SemicolonClassElement: + case ts.SyntaxKind.ClassStaticBlockDeclaration: // Can't be private break; default: - Debug.fail("Unexpected class member"); + ts.Debug.fail("Unexpected class member"); } } } - function checkUnusedInferTypeParameter(node: InferTypeNode, addDiagnostic: AddUnusedDiagnostic): void { + function checkUnusedInferTypeParameter(node: ts.InferTypeNode, addDiagnostic: AddUnusedDiagnostic): void { const { typeParameter } = node; if (isTypeParameterUnused(typeParameter)) { - addDiagnostic(node, UnusedKind.Parameter, createDiagnosticForNode(node, Diagnostics._0_is_declared_but_its_value_is_never_read, idText(typeParameter.name))); + addDiagnostic(node, UnusedKind.Parameter, ts.createDiagnosticForNode(node, ts.Diagnostics._0_is_declared_but_its_value_is_never_read, ts.idText(typeParameter.name))); } } - function checkUnusedTypeParameters(node: ClassLikeDeclaration | SignatureDeclaration | InterfaceDeclaration | TypeAliasDeclaration, addDiagnostic: AddUnusedDiagnostic): void { + function checkUnusedTypeParameters(node: ts.ClassLikeDeclaration | ts.SignatureDeclaration | ts.InterfaceDeclaration | ts.TypeAliasDeclaration, addDiagnostic: AddUnusedDiagnostic): void { // Only report errors on the last declaration for the type parameter container; // this ensures that all uses have been accounted for. const declarations = getSymbolOfNode(node).declarations; - if (!declarations || last(declarations) !== node) return; - - const typeParameters = getEffectiveTypeParameterDeclarations(node); - const seenParentsWithEveryUnused = new Set(); + if (!declarations || ts.last(declarations) !== node) + return; + const typeParameters = ts.getEffectiveTypeParameterDeclarations(node); + const seenParentsWithEveryUnused = new ts.Set(); for (const typeParameter of typeParameters) { - if (!isTypeParameterUnused(typeParameter)) continue; - - const name = idText(typeParameter.name); + if (!isTypeParameterUnused(typeParameter)) + continue; + const name = ts.idText(typeParameter.name); const { parent } = typeParameter; - if (parent.kind !== SyntaxKind.InferType && parent.typeParameters!.every(isTypeParameterUnused)) { - if (tryAddToSet(seenParentsWithEveryUnused, parent)) { - const sourceFile = getSourceFileOfNode(parent); - const range = isJSDocTemplateTag(parent) + if (parent.kind !== ts.SyntaxKind.InferType && parent.typeParameters!.every(isTypeParameterUnused)) { + if (ts.tryAddToSet(seenParentsWithEveryUnused, parent)) { + const sourceFile = ts.getSourceFileOfNode(parent); + const range = ts.isJSDocTemplateTag(parent) // Whole @template tag - ? rangeOfNode(parent) + ? ts.rangeOfNode(parent) // Include the `<>` in the error message - : rangeOfTypeParameters(sourceFile, parent.typeParameters!); + : ts.rangeOfTypeParameters(sourceFile, parent.typeParameters!); const only = parent.typeParameters!.length === 1; //TODO: following line is possible reason for bug #41974, unusedTypeParameters_TemplateTag - const message = only ? Diagnostics._0_is_declared_but_its_value_is_never_read : Diagnostics.All_type_parameters_are_unused; + const message = only ? ts.Diagnostics._0_is_declared_but_its_value_is_never_read : ts.Diagnostics.All_type_parameters_are_unused; const arg0 = only ? name : undefined; - addDiagnostic(typeParameter, UnusedKind.Parameter, createFileDiagnostic(sourceFile, range.pos, range.end - range.pos, message, arg0)); + addDiagnostic(typeParameter, UnusedKind.Parameter, ts.createFileDiagnostic(sourceFile, range.pos, range.end - range.pos, message, arg0)); } } else { //TODO: following line is possible reason for bug #41974, unusedTypeParameters_TemplateTag - addDiagnostic(typeParameter, UnusedKind.Parameter, createDiagnosticForNode(typeParameter, Diagnostics._0_is_declared_but_its_value_is_never_read, name)); + addDiagnostic(typeParameter, UnusedKind.Parameter, ts.createDiagnosticForNode(typeParameter, ts.Diagnostics._0_is_declared_but_its_value_is_never_read, name)); } } } - function isTypeParameterUnused(typeParameter: TypeParameterDeclaration): boolean { - return !(getMergedSymbol(typeParameter.symbol).isReferenced! & SymbolFlags.TypeParameter) && !isIdentifierThatStartsWithUnderscore(typeParameter.name); + function isTypeParameterUnused(typeParameter: ts.TypeParameterDeclaration): boolean { + return !(getMergedSymbol(typeParameter.symbol).isReferenced! & ts.SymbolFlags.TypeParameter) && !isIdentifierThatStartsWithUnderscore(typeParameter.name); } - function addToGroup(map: ESMap, key: K, value: V, getKey: (key: K) => number | string): void { + function addToGroup(map: ts.ESMap, key: K, value: V, getKey: (key: K) => number | string): void { const keyString = String(getKey(key)); const group = map.get(keyString); if (group) { @@ -37273,13 +36462,13 @@ namespace ts { } } - function tryGetRootParameterDeclaration(node: Node): ParameterDeclaration | undefined { - return tryCast(getRootDeclaration(node), isParameter); + function tryGetRootParameterDeclaration(node: ts.Node): ts.ParameterDeclaration | undefined { + return ts.tryCast(ts.getRootDeclaration(node), ts.isParameter); } - function isValidUnusedLocalDeclaration(declaration: Declaration): boolean { - if (isBindingElement(declaration)) { - if (isObjectBindingPattern(declaration.parent)) { + function isValidUnusedLocalDeclaration(declaration: ts.Declaration): boolean { + if (ts.isBindingElement(declaration)) { + if (ts.isObjectBindingPattern(declaration.parent)) { /** * ignore starts with underscore names _ * const { a: _a } = { a: 1 } @@ -37288,19 +36477,28 @@ namespace ts { } return isIdentifierThatStartsWithUnderscore(declaration.name); } - return isAmbientModule(declaration) || - (isVariableDeclaration(declaration) && isForInOrOfStatement(declaration.parent.parent) || isImportedDeclaration(declaration)) && isIdentifierThatStartsWithUnderscore(declaration.name!); + return ts.isAmbientModule(declaration) || + (ts.isVariableDeclaration(declaration) && ts.isForInOrOfStatement(declaration.parent.parent) || isImportedDeclaration(declaration)) && isIdentifierThatStartsWithUnderscore(declaration.name!); } - function checkUnusedLocalsAndParameters(nodeWithLocals: Node, addDiagnostic: AddUnusedDiagnostic): void { + function checkUnusedLocalsAndParameters(nodeWithLocals: ts.Node, addDiagnostic: AddUnusedDiagnostic): void { // Ideally we could use the ImportClause directly as a key, but must wait until we have full ES6 maps. So must store key along with value. - const unusedImports = new Map(); - const unusedDestructures = new Map(); - const unusedVariables = new Map(); + const unusedImports = new ts.Map(); + const unusedDestructures = new ts.Map(); + const unusedVariables = new ts.Map(); nodeWithLocals.locals!.forEach(local => { // If it's purely a type parameter, ignore, will be checked in `checkUnusedTypeParameters`. // If it's a type parameter merged with a parameter, check if the parameter-side is used. - if (local.flags & SymbolFlags.TypeParameter ? !(local.flags & SymbolFlags.Variable && !(local.isReferenced! & SymbolFlags.Variable)) : local.isReferenced || local.exportSymbol) { + if (local.flags & ts.SymbolFlags.TypeParameter ? !(local.flags & ts.SymbolFlags.Variable && !(local.isReferenced! & ts.SymbolFlags.Variable)) : local.isReferenced || local.exportSymbol) { return; } @@ -37313,31 +36511,31 @@ namespace ts { if (isImportedDeclaration(declaration)) { addToGroup(unusedImports, importClauseFromImported(declaration), declaration, getNodeId); } - else if (isBindingElement(declaration) && isObjectBindingPattern(declaration.parent)) { + else if (ts.isBindingElement(declaration) && ts.isObjectBindingPattern(declaration.parent)) { // In `{ a, ...b }, `a` is considered used since it removes a property from `b`. `b` may still be unused though. - const lastElement = last(declaration.parent.elements); - if (declaration === lastElement || !last(declaration.parent.elements).dotDotDotToken) { + const lastElement = ts.last(declaration.parent.elements); + if (declaration === lastElement || !ts.last(declaration.parent.elements).dotDotDotToken) { addToGroup(unusedDestructures, declaration.parent, declaration, getNodeId); } } - else if (isVariableDeclaration(declaration)) { + else if (ts.isVariableDeclaration(declaration)) { addToGroup(unusedVariables, declaration.parent, declaration, getNodeId); } else { const parameter = local.valueDeclaration && tryGetRootParameterDeclaration(local.valueDeclaration); - const name = local.valueDeclaration && getNameOfDeclaration(local.valueDeclaration); + const name = local.valueDeclaration && ts.getNameOfDeclaration(local.valueDeclaration); if (parameter && name) { - if (!isParameterPropertyDeclaration(parameter, parameter.parent) && !parameterIsThisKeyword(parameter) && !isIdentifierThatStartsWithUnderscore(name)) { - if (isBindingElement(declaration) && isArrayBindingPattern(declaration.parent)) { + if (!ts.isParameterPropertyDeclaration(parameter, parameter.parent) && !ts.parameterIsThisKeyword(parameter) && !isIdentifierThatStartsWithUnderscore(name)) { + if (ts.isBindingElement(declaration) && ts.isArrayBindingPattern(declaration.parent)) { addToGroup(unusedDestructures, declaration.parent, declaration, getNodeId); } else { - addDiagnostic(parameter, UnusedKind.Parameter, createDiagnosticForNode(name, Diagnostics._0_is_declared_but_its_value_is_never_read, symbolName(local))); + addDiagnostic(parameter, UnusedKind.Parameter, ts.createDiagnosticForNode(name, ts.Diagnostics._0_is_declared_but_its_value_is_never_read, ts.symbolName(local))); } } } else { - errorUnusedLocal(declaration, symbolName(local), addDiagnostic); + errorUnusedLocal(declaration, ts.symbolName(local), addDiagnostic); } } } @@ -37347,96 +36545,97 @@ namespace ts { const importDecl = importClause.parent; const nDeclarations = (importClause.name ? 1 : 0) + (importClause.namedBindings ? - (importClause.namedBindings.kind === SyntaxKind.NamespaceImport ? 1 : importClause.namedBindings.elements.length) + (importClause.namedBindings.kind === ts.SyntaxKind.NamespaceImport ? 1 : importClause.namedBindings.elements.length) : 0); if (nDeclarations === unuseds.length) { addDiagnostic(importDecl, UnusedKind.Local, unuseds.length === 1 - ? createDiagnosticForNode(importDecl, Diagnostics._0_is_declared_but_its_value_is_never_read, idText(first(unuseds).name!)) - : createDiagnosticForNode(importDecl, Diagnostics.All_imports_in_import_declaration_are_unused)); + ? ts.createDiagnosticForNode(importDecl, ts.Diagnostics._0_is_declared_but_its_value_is_never_read, ts.idText(ts.first(unuseds).name!)) + : ts.createDiagnosticForNode(importDecl, ts.Diagnostics.All_imports_in_import_declaration_are_unused)); } else { - for (const unused of unuseds) errorUnusedLocal(unused, idText(unused.name!), addDiagnostic); + for (const unused of unuseds) + errorUnusedLocal(unused, ts.idText(unused.name!), addDiagnostic); } }); unusedDestructures.forEach(([bindingPattern, bindingElements]) => { const kind = tryGetRootParameterDeclaration(bindingPattern.parent) ? UnusedKind.Parameter : UnusedKind.Local; if (bindingPattern.elements.length === bindingElements.length) { - if (bindingElements.length === 1 && bindingPattern.parent.kind === SyntaxKind.VariableDeclaration && bindingPattern.parent.parent.kind === SyntaxKind.VariableDeclarationList) { + if (bindingElements.length === 1 && bindingPattern.parent.kind === ts.SyntaxKind.VariableDeclaration && bindingPattern.parent.parent.kind === ts.SyntaxKind.VariableDeclarationList) { addToGroup(unusedVariables, bindingPattern.parent.parent, bindingPattern.parent, getNodeId); } else { addDiagnostic(bindingPattern, kind, bindingElements.length === 1 - ? createDiagnosticForNode(bindingPattern, Diagnostics._0_is_declared_but_its_value_is_never_read, bindingNameText(first(bindingElements).name)) - : createDiagnosticForNode(bindingPattern, Diagnostics.All_destructured_elements_are_unused)); + ? ts.createDiagnosticForNode(bindingPattern, ts.Diagnostics._0_is_declared_but_its_value_is_never_read, bindingNameText(ts.first(bindingElements).name)) + : ts.createDiagnosticForNode(bindingPattern, ts.Diagnostics.All_destructured_elements_are_unused)); } } else { for (const e of bindingElements) { - addDiagnostic(e, kind, createDiagnosticForNode(e, Diagnostics._0_is_declared_but_its_value_is_never_read, bindingNameText(e.name))); + addDiagnostic(e, kind, ts.createDiagnosticForNode(e, ts.Diagnostics._0_is_declared_but_its_value_is_never_read, bindingNameText(e.name))); } } }); unusedVariables.forEach(([declarationList, declarations]) => { if (declarationList.declarations.length === declarations.length) { addDiagnostic(declarationList, UnusedKind.Local, declarations.length === 1 - ? createDiagnosticForNode(first(declarations).name, Diagnostics._0_is_declared_but_its_value_is_never_read, bindingNameText(first(declarations).name)) - : createDiagnosticForNode(declarationList.parent.kind === SyntaxKind.VariableStatement ? declarationList.parent : declarationList, Diagnostics.All_variables_are_unused)); + ? ts.createDiagnosticForNode(ts.first(declarations).name, ts.Diagnostics._0_is_declared_but_its_value_is_never_read, bindingNameText(ts.first(declarations).name)) + : ts.createDiagnosticForNode(declarationList.parent.kind === ts.SyntaxKind.VariableStatement ? declarationList.parent : declarationList, ts.Diagnostics.All_variables_are_unused)); } else { for (const decl of declarations) { - addDiagnostic(decl, UnusedKind.Local, createDiagnosticForNode(decl, Diagnostics._0_is_declared_but_its_value_is_never_read, bindingNameText(decl.name))); + addDiagnostic(decl, UnusedKind.Local, ts.createDiagnosticForNode(decl, ts.Diagnostics._0_is_declared_but_its_value_is_never_read, bindingNameText(decl.name))); } } }); } - function bindingNameText(name: BindingName): string { + function bindingNameText(name: ts.BindingName): string { switch (name.kind) { - case SyntaxKind.Identifier: - return idText(name); - case SyntaxKind.ArrayBindingPattern: - case SyntaxKind.ObjectBindingPattern: - return bindingNameText(cast(first(name.elements), isBindingElement).name); + case ts.SyntaxKind.Identifier: + return ts.idText(name); + case ts.SyntaxKind.ArrayBindingPattern: + case ts.SyntaxKind.ObjectBindingPattern: + return bindingNameText(ts.cast(ts.first(name.elements), ts.isBindingElement).name); default: - return Debug.assertNever(name); + return ts.Debug.assertNever(name); } } - type ImportedDeclaration = ImportClause | ImportSpecifier | NamespaceImport; - function isImportedDeclaration(node: Node): node is ImportedDeclaration { - return node.kind === SyntaxKind.ImportClause || node.kind === SyntaxKind.ImportSpecifier || node.kind === SyntaxKind.NamespaceImport; + type ImportedDeclaration = ts.ImportClause | ts.ImportSpecifier | ts.NamespaceImport; + function isImportedDeclaration(node: ts.Node): node is ImportedDeclaration { + return node.kind === ts.SyntaxKind.ImportClause || node.kind === ts.SyntaxKind.ImportSpecifier || node.kind === ts.SyntaxKind.NamespaceImport; } - function importClauseFromImported(decl: ImportedDeclaration): ImportClause { - return decl.kind === SyntaxKind.ImportClause ? decl : decl.kind === SyntaxKind.NamespaceImport ? decl.parent : decl.parent.parent; + function importClauseFromImported(decl: ImportedDeclaration): ts.ImportClause { + return decl.kind === ts.SyntaxKind.ImportClause ? decl : decl.kind === ts.SyntaxKind.NamespaceImport ? decl.parent : decl.parent.parent; } - function checkBlock(node: Block) { + function checkBlock(node: ts.Block) { // Grammar checking for SyntaxKind.Block - if (node.kind === SyntaxKind.Block) { + if (node.kind === ts.SyntaxKind.Block) { checkGrammarStatementInAmbientContext(node); } - if (isFunctionOrModuleBlock(node)) { + if (ts.isFunctionOrModuleBlock(node)) { const saveFlowAnalysisDisabled = flowAnalysisDisabled; - forEach(node.statements, checkSourceElement); + ts.forEach(node.statements, checkSourceElement); flowAnalysisDisabled = saveFlowAnalysisDisabled; } else { - forEach(node.statements, checkSourceElement); + ts.forEach(node.statements, checkSourceElement); } if (node.locals) { registerForUnusedIdentifiersCheck(node); } } - function checkCollisionWithArgumentsInGeneratedCode(node: SignatureDeclaration) { + function checkCollisionWithArgumentsInGeneratedCode(node: ts.SignatureDeclaration) { // no rest parameters \ declaration context \ overload - no codegen impact - if (languageVersion >= ScriptTarget.ES2015 || !hasRestParameter(node) || node.flags & NodeFlags.Ambient || nodeIsMissing((node as FunctionLikeDeclaration).body)) { + if (languageVersion >= ts.ScriptTarget.ES2015 || !ts.hasRestParameter(node) || node.flags & ts.NodeFlags.Ambient || ts.nodeIsMissing((node as ts.FunctionLikeDeclaration).body)) { return; } - forEach(node.parameters, p => { - if (p.name && !isBindingPattern(p.name) && p.name.escapedText === argumentsSymbol.escapedName) { - errorSkippedOn("noEmit", p, Diagnostics.Duplicate_identifier_arguments_Compiler_uses_arguments_to_initialize_rest_parameters); + ts.forEach(node.parameters, p => { + if (p.name && !ts.isBindingPattern(p.name) && p.name.escapedText === argumentsSymbol.escapedName) { + errorSkippedOn("noEmit", p, ts.Diagnostics.Duplicate_identifier_arguments_Compiler_uses_arguments_to_initialize_rest_parameters); } }); } @@ -37446,36 +36645,36 @@ namespace ts { * of {@link name} in an outer scope. This is used to check for collisions for downlevel transformations that * require names like `Object`, `Promise`, `Reflect`, `require`, `exports`, etc. */ - function needCollisionCheckForIdentifier(node: Node, identifier: Identifier | undefined, name: string): boolean { + function needCollisionCheckForIdentifier(node: ts.Node, identifier: ts.Identifier | undefined, name: string): boolean { if (identifier?.escapedText !== name) { return false; } - if (node.kind === SyntaxKind.PropertyDeclaration || - node.kind === SyntaxKind.PropertySignature || - node.kind === SyntaxKind.MethodDeclaration || - node.kind === SyntaxKind.MethodSignature || - node.kind === SyntaxKind.GetAccessor || - node.kind === SyntaxKind.SetAccessor || - node.kind === SyntaxKind.PropertyAssignment) { + if (node.kind === ts.SyntaxKind.PropertyDeclaration || + node.kind === ts.SyntaxKind.PropertySignature || + node.kind === ts.SyntaxKind.MethodDeclaration || + node.kind === ts.SyntaxKind.MethodSignature || + node.kind === ts.SyntaxKind.GetAccessor || + node.kind === ts.SyntaxKind.SetAccessor || + node.kind === ts.SyntaxKind.PropertyAssignment) { // it is ok to have member named '_super', '_this', `Promise`, etc. - member access is always qualified return false; } - if (node.flags & NodeFlags.Ambient) { + if (node.flags & ts.NodeFlags.Ambient) { // ambient context - no codegen impact return false; } - if (isImportClause(node) || isImportEqualsDeclaration(node) || isImportSpecifier(node)) { + if (ts.isImportClause(node) || ts.isImportEqualsDeclaration(node) || ts.isImportSpecifier(node)) { // type-only imports do not require collision checks against runtime values. - if (isTypeOnlyImportOrExportDeclaration(node)) { + if (ts.isTypeOnlyImportOrExportDeclaration(node)) { return false; } } - const root = getRootDeclaration(node); - if (isParameter(root) && nodeIsMissing((root.parent as FunctionLikeDeclaration).body)) { + const root = ts.getRootDeclaration(node); + if (ts.isParameter(root) && ts.nodeIsMissing((root.parent as ts.FunctionLikeDeclaration).body)) { // just an overload - no codegen impact return false; } @@ -37484,15 +36683,15 @@ namespace ts { } // this function will run after checking the source file so 'CaptureThis' is correct for all nodes - function checkIfThisIsCapturedInEnclosingScope(node: Node): void { - findAncestor(node, current => { - if (getNodeCheckFlags(current) & NodeCheckFlags.CaptureThis) { - const isDeclaration = node.kind !== SyntaxKind.Identifier; + function checkIfThisIsCapturedInEnclosingScope(node: ts.Node): void { + ts.findAncestor(node, current => { + if (getNodeCheckFlags(current) & ts.NodeCheckFlags.CaptureThis) { + const isDeclaration = node.kind !== ts.SyntaxKind.Identifier; if (isDeclaration) { - error(getNameOfDeclaration(node as Declaration), Diagnostics.Duplicate_identifier_this_Compiler_uses_variable_declaration_this_to_capture_this_reference); + error(ts.getNameOfDeclaration(node as ts.Declaration), ts.Diagnostics.Duplicate_identifier_this_Compiler_uses_variable_declaration_this_to_capture_this_reference); } else { - error(node, Diagnostics.Expression_resolves_to_variable_declaration_this_that_compiler_uses_to_capture_this_reference); + error(node, ts.Diagnostics.Expression_resolves_to_variable_declaration_this_that_compiler_uses_to_capture_this_reference); } return true; } @@ -37500,15 +36699,15 @@ namespace ts { }); } - function checkIfNewTargetIsCapturedInEnclosingScope(node: Node): void { - findAncestor(node, current => { - if (getNodeCheckFlags(current) & NodeCheckFlags.CaptureNewTarget) { - const isDeclaration = node.kind !== SyntaxKind.Identifier; + function checkIfNewTargetIsCapturedInEnclosingScope(node: ts.Node): void { + ts.findAncestor(node, current => { + if (getNodeCheckFlags(current) & ts.NodeCheckFlags.CaptureNewTarget) { + const isDeclaration = node.kind !== ts.SyntaxKind.Identifier; if (isDeclaration) { - error(getNameOfDeclaration(node as Declaration), Diagnostics.Duplicate_identifier_newTarget_Compiler_uses_variable_declaration_newTarget_to_capture_new_target_meta_property_reference); + error(ts.getNameOfDeclaration(node as ts.Declaration), ts.Diagnostics.Duplicate_identifier_newTarget_Compiler_uses_variable_declaration_newTarget_to_capture_new_target_meta_property_reference); } else { - error(node, Diagnostics.Expression_resolves_to_variable_declaration_newTarget_that_compiler_uses_to_capture_new_target_meta_property_reference); + error(node, ts.Diagnostics.Expression_resolves_to_variable_declaration_newTarget_that_compiler_uses_to_capture_new_target_meta_property_reference); } return true; } @@ -37516,9 +36715,9 @@ namespace ts { }); } - function checkCollisionWithRequireExportsInGeneratedCode(node: Node, name: Identifier | undefined) { + function checkCollisionWithRequireExportsInGeneratedCode(node: ts.Node, name: ts.Identifier | undefined) { // No need to check for require or exports for ES6 modules and later - if (moduleKind >= ModuleKind.ES2015 && !(moduleKind >= ModuleKind.Node16 && getSourceFileOfNode(node).impliedNodeFormat === ModuleKind.CommonJS)) { + if (moduleKind >= ts.ModuleKind.ES2015 && !(moduleKind >= ts.ModuleKind.Node16 && ts.getSourceFileOfNode(node).impliedNodeFormat === ts.ModuleKind.CommonJS)) { return; } @@ -37527,109 +36726,106 @@ namespace ts { } // Uninstantiated modules shouldnt do this check - if (isModuleDeclaration(node) && getModuleInstanceState(node) !== ModuleInstanceState.Instantiated) { + if (ts.isModuleDeclaration(node) && ts.getModuleInstanceState(node) !== ts.ModuleInstanceState.Instantiated) { return; } // In case of variable declaration, node.parent is variable statement so look at the variable statement's parent const parent = getDeclarationContainer(node); - if (parent.kind === SyntaxKind.SourceFile && isExternalOrCommonJsModule(parent as SourceFile)) { + if (parent.kind === ts.SyntaxKind.SourceFile && ts.isExternalOrCommonJsModule(parent as ts.SourceFile)) { // If the declaration happens to be in external module, report error that require and exports are reserved keywords - errorSkippedOn("noEmit", name, Diagnostics.Duplicate_identifier_0_Compiler_reserves_name_1_in_top_level_scope_of_a_module, - declarationNameToString(name), declarationNameToString(name)); + errorSkippedOn("noEmit", name, ts.Diagnostics.Duplicate_identifier_0_Compiler_reserves_name_1_in_top_level_scope_of_a_module, ts.declarationNameToString(name), ts.declarationNameToString(name)); } } - function checkCollisionWithGlobalPromiseInGeneratedCode(node: Node, name: Identifier | undefined): void { - if (!name || languageVersion >= ScriptTarget.ES2017 || !needCollisionCheckForIdentifier(node, name, "Promise")) { + function checkCollisionWithGlobalPromiseInGeneratedCode(node: ts.Node, name: ts.Identifier | undefined): void { + if (!name || languageVersion >= ts.ScriptTarget.ES2017 || !needCollisionCheckForIdentifier(node, name, "Promise")) { return; } // Uninstantiated modules shouldnt do this check - if (isModuleDeclaration(node) && getModuleInstanceState(node) !== ModuleInstanceState.Instantiated) { + if (ts.isModuleDeclaration(node) && ts.getModuleInstanceState(node) !== ts.ModuleInstanceState.Instantiated) { return; } // In case of variable declaration, node.parent is variable statement so look at the variable statement's parent const parent = getDeclarationContainer(node); - if (parent.kind === SyntaxKind.SourceFile && isExternalOrCommonJsModule(parent as SourceFile) && parent.flags & NodeFlags.HasAsyncFunctions) { + if (parent.kind === ts.SyntaxKind.SourceFile && ts.isExternalOrCommonJsModule(parent as ts.SourceFile) && parent.flags & ts.NodeFlags.HasAsyncFunctions) { // If the declaration happens to be in external module, report error that Promise is a reserved identifier. - errorSkippedOn("noEmit", name, Diagnostics.Duplicate_identifier_0_Compiler_reserves_name_1_in_top_level_scope_of_a_module_containing_async_functions, - declarationNameToString(name), declarationNameToString(name)); + errorSkippedOn("noEmit", name, ts.Diagnostics.Duplicate_identifier_0_Compiler_reserves_name_1_in_top_level_scope_of_a_module_containing_async_functions, ts.declarationNameToString(name), ts.declarationNameToString(name)); } } - function recordPotentialCollisionWithWeakMapSetInGeneratedCode(node: Node, name: Identifier): void { - if (languageVersion <= ScriptTarget.ES2021 + function recordPotentialCollisionWithWeakMapSetInGeneratedCode(node: ts.Node, name: ts.Identifier): void { + if (languageVersion <= ts.ScriptTarget.ES2021 && (needCollisionCheckForIdentifier(node, name, "WeakMap") || needCollisionCheckForIdentifier(node, name, "WeakSet"))) { potentialWeakMapSetCollisions.push(node); } } - function checkWeakMapSetCollision(node: Node) { - const enclosingBlockScope = getEnclosingBlockScopeContainer(node); - if (getNodeCheckFlags(enclosingBlockScope) & NodeCheckFlags.ContainsClassWithPrivateIdentifiers) { - Debug.assert(isNamedDeclaration(node) && isIdentifier(node.name) && typeof node.name.escapedText === "string", "The target of a WeakMap/WeakSet collision check should be an identifier"); - errorSkippedOn("noEmit", node, Diagnostics.Compiler_reserves_name_0_when_emitting_private_identifier_downlevel, node.name.escapedText); + function checkWeakMapSetCollision(node: ts.Node) { + const enclosingBlockScope = ts.getEnclosingBlockScopeContainer(node); + if (getNodeCheckFlags(enclosingBlockScope) & ts.NodeCheckFlags.ContainsClassWithPrivateIdentifiers) { + ts.Debug.assert(ts.isNamedDeclaration(node) && ts.isIdentifier(node.name) && typeof node.name.escapedText === "string", "The target of a WeakMap/WeakSet collision check should be an identifier"); + errorSkippedOn("noEmit", node, ts.Diagnostics.Compiler_reserves_name_0_when_emitting_private_identifier_downlevel, node.name.escapedText); } } - function recordPotentialCollisionWithReflectInGeneratedCode(node: Node, name: Identifier | undefined): void { - if (name && languageVersion >= ScriptTarget.ES2015 && languageVersion <= ScriptTarget.ES2021 + function recordPotentialCollisionWithReflectInGeneratedCode(node: ts.Node, name: ts.Identifier | undefined): void { + if (name && languageVersion >= ts.ScriptTarget.ES2015 && languageVersion <= ts.ScriptTarget.ES2021 && needCollisionCheckForIdentifier(node, name, "Reflect")) { potentialReflectCollisions.push(node); } } - function checkReflectCollision(node: Node) { + function checkReflectCollision(node: ts.Node) { let hasCollision = false; - if (isClassExpression(node)) { + if (ts.isClassExpression(node)) { // ClassExpression names don't contribute to their containers, but do matter for any of their block-scoped members. for (const member of node.members) { - if (getNodeCheckFlags(member) & NodeCheckFlags.ContainsSuperPropertyInStaticInitializer) { + if (getNodeCheckFlags(member) & ts.NodeCheckFlags.ContainsSuperPropertyInStaticInitializer) { hasCollision = true; break; } } } - else if (isFunctionExpression(node)) { + else if (ts.isFunctionExpression(node)) { // FunctionExpression names don't contribute to their containers, but do matter for their contents - if (getNodeCheckFlags(node) & NodeCheckFlags.ContainsSuperPropertyInStaticInitializer) { + if (getNodeCheckFlags(node) & ts.NodeCheckFlags.ContainsSuperPropertyInStaticInitializer) { hasCollision = true; } } else { - const container = getEnclosingBlockScopeContainer(node); - if (container && getNodeCheckFlags(container) & NodeCheckFlags.ContainsSuperPropertyInStaticInitializer) { + const container = ts.getEnclosingBlockScopeContainer(node); + if (container && getNodeCheckFlags(container) & ts.NodeCheckFlags.ContainsSuperPropertyInStaticInitializer) { hasCollision = true; } } if (hasCollision) { - Debug.assert(isNamedDeclaration(node) && isIdentifier(node.name), "The target of a Reflect collision check should be an identifier"); - errorSkippedOn("noEmit", node, Diagnostics.Duplicate_identifier_0_Compiler_reserves_name_1_when_emitting_super_references_in_static_initializers, - declarationNameToString(node.name), - "Reflect"); + ts.Debug.assert(ts.isNamedDeclaration(node) && ts.isIdentifier(node.name), "The target of a Reflect collision check should be an identifier"); + errorSkippedOn("noEmit", node, ts.Diagnostics.Duplicate_identifier_0_Compiler_reserves_name_1_when_emitting_super_references_in_static_initializers, ts.declarationNameToString(node.name), "Reflect"); } } - function checkCollisionsForDeclarationName(node: Node, name: Identifier | undefined) { - if (!name) return; + function checkCollisionsForDeclarationName(node: ts.Node, name: ts.Identifier | undefined) { + if (!name) + return; checkCollisionWithRequireExportsInGeneratedCode(node, name); checkCollisionWithGlobalPromiseInGeneratedCode(node, name); recordPotentialCollisionWithWeakMapSetInGeneratedCode(node, name); recordPotentialCollisionWithReflectInGeneratedCode(node, name); - if (isClassLike(node)) { - checkTypeNameIsReserved(name, Diagnostics.Class_name_cannot_be_0); - if (!(node.flags & NodeFlags.Ambient)) { + if (ts.isClassLike(node)) { + checkTypeNameIsReserved(name, ts.Diagnostics.Class_name_cannot_be_0); + if (!(node.flags & ts.NodeFlags.Ambient)) { checkClassNameCollisionWithObject(name); } } - else if (isEnumDeclaration(node)) { - checkTypeNameIsReserved(name, Diagnostics.Enum_name_cannot_be_0); + else if (ts.isEnumDeclaration(node)) { + checkTypeNameIsReserved(name, ts.Diagnostics.Enum_name_cannot_be_0); } } - function checkVarDeclaredNamesNotShadowed(node: VariableDeclaration | BindingElement) { + function checkVarDeclaredNamesNotShadowed(node: ts.VariableDeclaration | ts.BindingElement) { // - ScriptBody : StatementList // It is a Syntax Error if any element of the LexicallyDeclaredNames of StatementList // also occurs in the VarDeclaredNames of StatementList. @@ -37656,39 +36852,38 @@ namespace ts { // } // skip block-scoped variables and parameters - if ((getCombinedNodeFlags(node) & NodeFlags.BlockScoped) !== 0 || isParameterDeclaration(node)) { + if ((ts.getCombinedNodeFlags(node) & ts.NodeFlags.BlockScoped) !== 0 || ts.isParameterDeclaration(node)) { return; } // skip variable declarations that don't have initializers // NOTE: in ES6 spec initializer is required in variable declarations where name is binding pattern // so we'll always treat binding elements as initialized - if (node.kind === SyntaxKind.VariableDeclaration && !node.initializer) { + if (node.kind === ts.SyntaxKind.VariableDeclaration && !node.initializer) { return; } const symbol = getSymbolOfNode(node); - if (symbol.flags & SymbolFlags.FunctionScopedVariable) { - if (!isIdentifier(node.name)) return Debug.fail(); - const localDeclarationSymbol = resolveName(node, node.name.escapedText, SymbolFlags.Variable, /*nodeNotFoundErrorMessage*/ undefined, /*nameArg*/ undefined, /*isUse*/ false); + if (symbol.flags & ts.SymbolFlags.FunctionScopedVariable) { + if (!ts.isIdentifier(node.name)) + return ts.Debug.fail(); + const localDeclarationSymbol = resolveName(node, node.name.escapedText, ts.SymbolFlags.Variable, /*nodeNotFoundErrorMessage*/ undefined, /*nameArg*/ undefined, /*isUse*/ false); if (localDeclarationSymbol && localDeclarationSymbol !== symbol && - localDeclarationSymbol.flags & SymbolFlags.BlockScopedVariable) { - if (getDeclarationNodeFlagsFromSymbol(localDeclarationSymbol) & NodeFlags.BlockScoped) { - const varDeclList = getAncestor(localDeclarationSymbol.valueDeclaration, SyntaxKind.VariableDeclarationList)!; - const container = - varDeclList.parent.kind === SyntaxKind.VariableStatement && varDeclList.parent.parent + localDeclarationSymbol.flags & ts.SymbolFlags.BlockScopedVariable) { + if (getDeclarationNodeFlagsFromSymbol(localDeclarationSymbol) & ts.NodeFlags.BlockScoped) { + const varDeclList = ts.getAncestor(localDeclarationSymbol.valueDeclaration, ts.SyntaxKind.VariableDeclarationList)!; + const container = varDeclList.parent.kind === ts.SyntaxKind.VariableStatement && varDeclList.parent.parent ? varDeclList.parent.parent : undefined; // names of block-scoped and function scoped variables can collide only // if block scoped variable is defined in the function\module\source file scope (because of variable hoisting) - const namesShareScope = - container && - (container.kind === SyntaxKind.Block && isFunctionLike(container.parent) || - container.kind === SyntaxKind.ModuleBlock || - container.kind === SyntaxKind.ModuleDeclaration || - container.kind === SyntaxKind.SourceFile); + const namesShareScope = container && + (container.kind === ts.SyntaxKind.Block && ts.isFunctionLike(container.parent) || + container.kind === ts.SyntaxKind.ModuleBlock || + container.kind === ts.SyntaxKind.ModuleDeclaration || + container.kind === ts.SyntaxKind.SourceFile); // here we know that function scoped variable is shadowed by block scoped one // if they are defined in the same scope - binder has already reported redeclaration error @@ -37696,21 +36891,21 @@ namespace ts { // since LHS will be block scoped name instead of function scoped if (!namesShareScope) { const name = symbolToString(localDeclarationSymbol); - error(node, Diagnostics.Cannot_initialize_outer_scoped_variable_0_in_the_same_scope_as_block_scoped_declaration_1, name, name); + error(node, ts.Diagnostics.Cannot_initialize_outer_scoped_variable_0_in_the_same_scope_as_block_scoped_declaration_1, name, name); } } } } } - function convertAutoToAny(type: Type) { + function convertAutoToAny(type: ts.Type) { return type === autoType ? anyType : type === autoArrayType ? anyArrayType : type; } // Check variable, parameter, or property declaration - function checkVariableLikeDeclaration(node: ParameterDeclaration | PropertyDeclaration | PropertySignature | VariableDeclaration | BindingElement) { + function checkVariableLikeDeclaration(node: ts.ParameterDeclaration | ts.PropertyDeclaration | ts.PropertySignature | ts.VariableDeclaration | ts.BindingElement) { checkDecorators(node); - if (!isBindingElement(node)) { + if (!ts.isBindingElement(node)) { checkSourceElement(node.type); } @@ -37723,19 +36918,19 @@ namespace ts { // Do not use hasDynamicName here, because that returns false for well known symbols. // We want to perform checkComputedPropertyName for all computed properties, including // well known symbols. - if (node.name.kind === SyntaxKind.ComputedPropertyName) { + if (node.name.kind === ts.SyntaxKind.ComputedPropertyName) { checkComputedPropertyName(node.name); if (node.initializer) { checkExpressionCached(node.initializer); } } - if (isBindingElement(node)) { - if (isObjectBindingPattern(node.parent) && node.dotDotDotToken && languageVersion < ScriptTarget.ES2018) { - checkExternalEmitHelpers(node, ExternalEmitHelpers.Rest); + if (ts.isBindingElement(node)) { + if (ts.isObjectBindingPattern(node.parent) && node.dotDotDotToken && languageVersion < ts.ScriptTarget.ES2018) { + checkExternalEmitHelpers(node, ts.ExternalEmitHelpers.Rest); } // check computed properties inside property names of binding elements - if (node.propertyName && node.propertyName.kind === SyntaxKind.ComputedPropertyName) { + if (node.propertyName && node.propertyName.kind === ts.SyntaxKind.ComputedPropertyName) { checkComputedPropertyName(node.propertyName); } @@ -37744,35 +36939,35 @@ namespace ts { const parentCheckMode = node.dotDotDotToken ? CheckMode.RestBindingElement : CheckMode.Normal; const parentType = getTypeForBindingElementParent(parent, parentCheckMode); const name = node.propertyName || node.name; - if (parentType && !isBindingPattern(name)) { + if (parentType && !ts.isBindingPattern(name)) { const exprType = getLiteralTypeFromPropertyName(name); if (isTypeUsableAsPropertyName(exprType)) { const nameText = getPropertyNameFromType(exprType); const property = getPropertyOfType(parentType, nameText); if (property) { markPropertyAsReferenced(property, /*nodeForCheckWriteOnly*/ undefined, /*isSelfTypeAccess*/ false); // A destructuring is never a write-only reference. - checkPropertyAccessibility(node, !!parent.initializer && parent.initializer.kind === SyntaxKind.SuperKeyword, /*writing*/ false, parentType, property); + checkPropertyAccessibility(node, !!parent.initializer && parent.initializer.kind === ts.SyntaxKind.SuperKeyword, /*writing*/ false, parentType, property); } } } } // For a binding pattern, check contained binding elements - if (isBindingPattern(node.name)) { - if (node.name.kind === SyntaxKind.ArrayBindingPattern && languageVersion < ScriptTarget.ES2015 && compilerOptions.downlevelIteration) { - checkExternalEmitHelpers(node, ExternalEmitHelpers.Read); + if (ts.isBindingPattern(node.name)) { + if (node.name.kind === ts.SyntaxKind.ArrayBindingPattern && languageVersion < ts.ScriptTarget.ES2015 && compilerOptions.downlevelIteration) { + checkExternalEmitHelpers(node, ts.ExternalEmitHelpers.Read); } - forEach(node.name.elements, checkSourceElement); + ts.forEach(node.name.elements, checkSourceElement); } // For a parameter declaration with an initializer, error and exit if the containing function doesn't have a body - if (node.initializer && isParameterDeclaration(node) && nodeIsMissing((getContainingFunction(node) as FunctionLikeDeclaration).body)) { - error(node, Diagnostics.A_parameter_initializer_is_only_allowed_in_a_function_or_constructor_implementation); + if (node.initializer && ts.isParameterDeclaration(node) && ts.nodeIsMissing((ts.getContainingFunction(node) as ts.FunctionLikeDeclaration).body)) { + error(node, ts.Diagnostics.A_parameter_initializer_is_only_allowed_in_a_function_or_constructor_implementation); return; } // For a binding pattern, validate the initializer and exit - if (isBindingPattern(node.name)) { - const needCheckInitializer = node.initializer && node.parent.parent.kind !== SyntaxKind.ForInStatement; + if (ts.isBindingPattern(node.name)) { + const needCheckInitializer = node.initializer && node.parent.parent.kind !== ts.SyntaxKind.ForInStatement; const needCheckWidenedType = node.name.elements.length === 0; if (needCheckInitializer || needCheckWidenedType) { // Don't validate for-in initializer as it is already an error @@ -37788,7 +36983,7 @@ namespace ts { } // check the binding pattern with empty elements if (needCheckWidenedType) { - if (isArrayBindingPattern(node.name)) { + if (ts.isArrayBindingPattern(node.name)) { checkIteratedTypeOrElementType(IterationUse.Destructuring, widenedType, undefinedType, node); } else if (strictNullChecks) { @@ -37800,7 +36995,7 @@ namespace ts { } // For a commonjs `const x = require`, validate the alias and exit const symbol = getSymbolOfNode(node); - if (symbol.flags & SymbolFlags.Alias && isVariableDeclarationInitializedToBareOrAccessedRequire(node)) { + if (symbol.flags & ts.SymbolFlags.Alias && ts.isVariableDeclarationInitializedToBareOrAccessedRequire(node)) { checkAliasSymbol(node); return; } @@ -37809,19 +37004,19 @@ namespace ts { if (node === symbol.valueDeclaration) { // Node is the primary declaration of the symbol, just validate the initializer // Don't validate for-in initializer as it is already an error - const initializer = getEffectiveInitializer(node); + const initializer = ts.getEffectiveInitializer(node); if (initializer) { - const isJSObjectLiteralInitializer = isInJSFile(node) && - isObjectLiteralExpression(initializer) && - (initializer.properties.length === 0 || isPrototypeAccess(node.name)) && + const isJSObjectLiteralInitializer = ts.isInJSFile(node) && + ts.isObjectLiteralExpression(initializer) && + (initializer.properties.length === 0 || ts.isPrototypeAccess(node.name)) && !!symbol.exports?.size; - if (!isJSObjectLiteralInitializer && node.parent.parent.kind !== SyntaxKind.ForInStatement) { + if (!isJSObjectLiteralInitializer && node.parent.parent.kind !== ts.SyntaxKind.ForInStatement) { checkTypeAssignableToAndOptionallyElaborate(checkExpressionCached(initializer), type, node, initializer, /*headMessage*/ undefined); } } if (symbol.declarations && symbol.declarations.length > 1) { - if (some(symbol.declarations, d => d !== node && isVariableLike(d) && !areDeclarationFlagsIdentical(d, node))) { - error(node.name, Diagnostics.All_declarations_of_0_must_have_identical_modifiers, declarationNameToString(node.name)); + if (ts.some(symbol.declarations, d => d !== node && ts.isVariableLike(d) && !areDeclarationFlagsIdentical(d, node))) { + error(node.name, ts.Diagnostics.All_declarations_of_0_must_have_identical_modifiers, ts.declarationNameToString(node.name)); } } } @@ -37832,187 +37027,179 @@ namespace ts { if (!isErrorType(type) && !isErrorType(declarationType) && !isTypeIdenticalTo(type, declarationType) && - !(symbol.flags & SymbolFlags.Assignment)) { + !(symbol.flags & ts.SymbolFlags.Assignment)) { errorNextVariableOrPropertyDeclarationMustHaveSameType(symbol.valueDeclaration, type, node, declarationType); } if (node.initializer) { checkTypeAssignableToAndOptionallyElaborate(checkExpressionCached(node.initializer), declarationType, node, node.initializer, /*headMessage*/ undefined); } if (symbol.valueDeclaration && !areDeclarationFlagsIdentical(node, symbol.valueDeclaration)) { - error(node.name, Diagnostics.All_declarations_of_0_must_have_identical_modifiers, declarationNameToString(node.name)); + error(node.name, ts.Diagnostics.All_declarations_of_0_must_have_identical_modifiers, ts.declarationNameToString(node.name)); } } - if (node.kind !== SyntaxKind.PropertyDeclaration && node.kind !== SyntaxKind.PropertySignature) { + if (node.kind !== ts.SyntaxKind.PropertyDeclaration && node.kind !== ts.SyntaxKind.PropertySignature) { // We know we don't have a binding pattern or computed name here checkExportsOnMergedDeclarations(node); - if (node.kind === SyntaxKind.VariableDeclaration || node.kind === SyntaxKind.BindingElement) { + if (node.kind === ts.SyntaxKind.VariableDeclaration || node.kind === ts.SyntaxKind.BindingElement) { checkVarDeclaredNamesNotShadowed(node); } checkCollisionsForDeclarationName(node, node.name); } } - function errorNextVariableOrPropertyDeclarationMustHaveSameType(firstDeclaration: Declaration | undefined, firstType: Type, nextDeclaration: Declaration, nextType: Type): void { - const nextDeclarationName = getNameOfDeclaration(nextDeclaration); - const message = nextDeclaration.kind === SyntaxKind.PropertyDeclaration || nextDeclaration.kind === SyntaxKind.PropertySignature - ? Diagnostics.Subsequent_property_declarations_must_have_the_same_type_Property_0_must_be_of_type_1_but_here_has_type_2 - : Diagnostics.Subsequent_variable_declarations_must_have_the_same_type_Variable_0_must_be_of_type_1_but_here_has_type_2; - const declName = declarationNameToString(nextDeclarationName); - const err = error( - nextDeclarationName, - message, - declName, - typeToString(firstType), - typeToString(nextType) - ); + function errorNextVariableOrPropertyDeclarationMustHaveSameType(firstDeclaration: ts.Declaration | undefined, firstType: ts.Type, nextDeclaration: ts.Declaration, nextType: ts.Type): void { + const nextDeclarationName = ts.getNameOfDeclaration(nextDeclaration); + const message = nextDeclaration.kind === ts.SyntaxKind.PropertyDeclaration || nextDeclaration.kind === ts.SyntaxKind.PropertySignature + ? ts.Diagnostics.Subsequent_property_declarations_must_have_the_same_type_Property_0_must_be_of_type_1_but_here_has_type_2 + : ts.Diagnostics.Subsequent_variable_declarations_must_have_the_same_type_Variable_0_must_be_of_type_1_but_here_has_type_2; + const declName = ts.declarationNameToString(nextDeclarationName); + const err = error(nextDeclarationName, message, declName, typeToString(firstType), typeToString(nextType)); if (firstDeclaration) { - addRelatedInfo(err, - createDiagnosticForNode(firstDeclaration, Diagnostics._0_was_also_declared_here, declName) - ); + ts.addRelatedInfo(err, ts.createDiagnosticForNode(firstDeclaration, ts.Diagnostics._0_was_also_declared_here, declName)); } } - function areDeclarationFlagsIdentical(left: Declaration, right: Declaration) { - if ((left.kind === SyntaxKind.Parameter && right.kind === SyntaxKind.VariableDeclaration) || - (left.kind === SyntaxKind.VariableDeclaration && right.kind === SyntaxKind.Parameter)) { + function areDeclarationFlagsIdentical(left: ts.Declaration, right: ts.Declaration) { + if ((left.kind === ts.SyntaxKind.Parameter && right.kind === ts.SyntaxKind.VariableDeclaration) || + (left.kind === ts.SyntaxKind.VariableDeclaration && right.kind === ts.SyntaxKind.Parameter)) { // Differences in optionality between parameters and variables are allowed. return true; } - if (hasQuestionToken(left) !== hasQuestionToken(right)) { + if (ts.hasQuestionToken(left) !== ts.hasQuestionToken(right)) { return false; } - const interestingFlags = ModifierFlags.Private | - ModifierFlags.Protected | - ModifierFlags.Async | - ModifierFlags.Abstract | - ModifierFlags.Readonly | - ModifierFlags.Static; - - return getSelectedEffectiveModifierFlags(left, interestingFlags) === getSelectedEffectiveModifierFlags(right, interestingFlags); + const interestingFlags = ts.ModifierFlags.Private | + ts.ModifierFlags.Protected | + ts.ModifierFlags.Async | + ts.ModifierFlags.Abstract | + ts.ModifierFlags.Readonly | + ts.ModifierFlags.Static; + return ts.getSelectedEffectiveModifierFlags(left, interestingFlags) === ts.getSelectedEffectiveModifierFlags(right, interestingFlags); } - function checkVariableDeclaration(node: VariableDeclaration) { - tracing?.push(tracing.Phase.Check, "checkVariableDeclaration", { kind: node.kind, pos: node.pos, end: node.end, path: (node as TracingNode).tracingPath }); + function checkVariableDeclaration(node: ts.VariableDeclaration) { + ts.tracing?.push(ts.tracing.Phase.Check, "checkVariableDeclaration", { kind: node.kind, pos: node.pos, end: node.end, path: (node as ts.TracingNode).tracingPath }); checkGrammarVariableDeclaration(node); checkVariableLikeDeclaration(node); - tracing?.pop(); + ts.tracing?.pop(); } - function checkBindingElement(node: BindingElement) { + function checkBindingElement(node: ts.BindingElement) { checkGrammarBindingElement(node); return checkVariableLikeDeclaration(node); } - function checkVariableStatement(node: VariableStatement) { + function checkVariableStatement(node: ts.VariableStatement) { // Grammar checking - if (!checkGrammarDecoratorsAndModifiers(node) && !checkGrammarVariableDeclarationList(node.declarationList)) checkGrammarForDisallowedLetOrConstStatement(node); - forEach(node.declarationList.declarations, checkSourceElement); + if (!checkGrammarDecoratorsAndModifiers(node) && !checkGrammarVariableDeclarationList(node.declarationList)) + checkGrammarForDisallowedLetOrConstStatement(node); + ts.forEach(node.declarationList.declarations, checkSourceElement); } - function checkExpressionStatement(node: ExpressionStatement) { + function checkExpressionStatement(node: ts.ExpressionStatement) { // Grammar checking checkGrammarStatementInAmbientContext(node); checkExpression(node.expression); } - function checkIfStatement(node: IfStatement) { + function checkIfStatement(node: ts.IfStatement) { // Grammar checking checkGrammarStatementInAmbientContext(node); checkTruthinessExpression(node.expression); checkTestingKnownTruthyCallableOrAwaitableType(node.expression, node.thenStatement); checkSourceElement(node.thenStatement); - if (node.thenStatement.kind === SyntaxKind.EmptyStatement) { - error(node.thenStatement, Diagnostics.The_body_of_an_if_statement_cannot_be_the_empty_statement); + if (node.thenStatement.kind === ts.SyntaxKind.EmptyStatement) { + error(node.thenStatement, ts.Diagnostics.The_body_of_an_if_statement_cannot_be_the_empty_statement); } checkSourceElement(node.elseStatement); } - function checkTestingKnownTruthyCallableOrAwaitableType(condExpr: Expression, body?: Statement | Expression) { - if (!strictNullChecks) return; + function checkTestingKnownTruthyCallableOrAwaitableType(condExpr: ts.Expression, body?: ts.Statement | ts.Expression) { + if (!strictNullChecks) + return; helper(condExpr, body); - while (isBinaryExpression(condExpr) && condExpr.operatorToken.kind === SyntaxKind.BarBarToken) { + while (ts.isBinaryExpression(condExpr) && condExpr.operatorToken.kind === ts.SyntaxKind.BarBarToken) { condExpr = condExpr.left; helper(condExpr, body); } - function helper(condExpr: Expression, body: Expression | Statement | undefined) { - const location = isBinaryExpression(condExpr) && - (condExpr.operatorToken.kind === SyntaxKind.BarBarToken || condExpr.operatorToken.kind === SyntaxKind.AmpersandAmpersandToken) + function helper(condExpr: ts.Expression, body: ts.Expression | ts.Statement | undefined) { + const location = ts.isBinaryExpression(condExpr) && + (condExpr.operatorToken.kind === ts.SyntaxKind.BarBarToken || condExpr.operatorToken.kind === ts.SyntaxKind.AmpersandAmpersandToken) ? condExpr.right : condExpr; - if (isModuleExportsAccessExpression(location)) return; + if (ts.isModuleExportsAccessExpression(location)) + return; const type = checkTruthinessExpression(location); - const isPropertyExpressionCast = isPropertyAccessExpression(location) && isTypeAssertion(location.expression); - if (getFalsyFlags(type) || isPropertyExpressionCast) return; + const isPropertyExpressionCast = ts.isPropertyAccessExpression(location) && isTypeAssertion(location.expression); + if (getFalsyFlags(type) || isPropertyExpressionCast) + return; // While it technically should be invalid for any known-truthy value // to be tested, we de-scope to functions and Promises unreferenced in // the block as a heuristic to identify the most common bugs. There // are too many false positives for values sourced from type // definitions without strictNullChecks otherwise. - const callSignatures = getSignaturesOfType(type, SignatureKind.Call); + const callSignatures = getSignaturesOfType(type, ts.SignatureKind.Call); const isPromise = !!getAwaitedTypeOfPromise(type); if (callSignatures.length === 0 && !isPromise) { return; } - const testedNode = isIdentifier(location) ? location - : isPropertyAccessExpression(location) ? location.name - : isBinaryExpression(location) && isIdentifier(location.right) ? location.right + const testedNode = ts.isIdentifier(location) ? location + : ts.isPropertyAccessExpression(location) ? location.name + : ts.isBinaryExpression(location) && ts.isIdentifier(location.right) ? location.right : undefined; const testedSymbol = testedNode && getSymbolAtLocation(testedNode); if (!testedSymbol && !isPromise) { return; } - const isUsed = testedSymbol && isBinaryExpression(condExpr.parent) && isSymbolUsedInBinaryExpressionChain(condExpr.parent, testedSymbol) + const isUsed = testedSymbol && ts.isBinaryExpression(condExpr.parent) && isSymbolUsedInBinaryExpressionChain(condExpr.parent, testedSymbol) || testedSymbol && body && isSymbolUsedInConditionBody(condExpr, body, testedNode, testedSymbol); if (!isUsed) { if (isPromise) { - errorAndMaybeSuggestAwait( - location, - /*maybeMissingAwait*/ true, - Diagnostics.This_condition_will_always_return_true_since_this_0_is_always_defined, - getTypeNameForErrorDisplay(type)); + errorAndMaybeSuggestAwait(location, + /*maybeMissingAwait*/ true, ts.Diagnostics.This_condition_will_always_return_true_since_this_0_is_always_defined, getTypeNameForErrorDisplay(type)); } else { - error(location, Diagnostics.This_condition_will_always_return_true_since_this_function_is_always_defined_Did_you_mean_to_call_it_instead); + error(location, ts.Diagnostics.This_condition_will_always_return_true_since_this_function_is_always_defined_Did_you_mean_to_call_it_instead); } } } } - function isSymbolUsedInConditionBody(expr: Expression, body: Statement | Expression, testedNode: Node, testedSymbol: Symbol): boolean { - return !!forEachChild(body, function check(childNode): boolean | undefined { - if (isIdentifier(childNode)) { + function isSymbolUsedInConditionBody(expr: ts.Expression, body: ts.Statement | ts.Expression, testedNode: ts.Node, testedSymbol: ts.Symbol): boolean { + return !!ts.forEachChild(body, function check(childNode): boolean | undefined { + if (ts.isIdentifier(childNode)) { const childSymbol = getSymbolAtLocation(childNode); if (childSymbol && childSymbol === testedSymbol) { // If the test was a simple identifier, the above check is sufficient - if (isIdentifier(expr)) { + if (ts.isIdentifier(expr)) { return true; } // Otherwise we need to ensure the symbol is called on the same target let testedExpression = testedNode.parent; let childExpression = childNode.parent; while (testedExpression && childExpression) { - if (isIdentifier(testedExpression) && isIdentifier(childExpression) || - testedExpression.kind === SyntaxKind.ThisKeyword && childExpression.kind === SyntaxKind.ThisKeyword) { + if (ts.isIdentifier(testedExpression) && ts.isIdentifier(childExpression) || + testedExpression.kind === ts.SyntaxKind.ThisKeyword && childExpression.kind === ts.SyntaxKind.ThisKeyword) { return getSymbolAtLocation(testedExpression) === getSymbolAtLocation(childExpression); } - else if (isPropertyAccessExpression(testedExpression) && isPropertyAccessExpression(childExpression)) { + else if (ts.isPropertyAccessExpression(testedExpression) && ts.isPropertyAccessExpression(childExpression)) { if (getSymbolAtLocation(testedExpression.name) !== getSymbolAtLocation(childExpression.name)) { return false; } childExpression = childExpression.expression; testedExpression = testedExpression.expression; } - else if (isCallExpression(testedExpression) && isCallExpression(childExpression)) { + else if (ts.isCallExpression(testedExpression) && ts.isCallExpression(childExpression)) { childExpression = childExpression.expression; testedExpression = testedExpression.expression; } @@ -38022,20 +37209,20 @@ namespace ts { } } } - return forEachChild(childNode, check); + return ts.forEachChild(childNode, check); }); } - function isSymbolUsedInBinaryExpressionChain(node: Node, testedSymbol: Symbol): boolean { - while (isBinaryExpression(node) && node.operatorToken.kind === SyntaxKind.AmpersandAmpersandToken) { - const isUsed = forEachChild(node.right, function visit(child): boolean | undefined { - if (isIdentifier(child)) { + function isSymbolUsedInBinaryExpressionChain(node: ts.Node, testedSymbol: ts.Symbol): boolean { + while (ts.isBinaryExpression(node) && node.operatorToken.kind === ts.SyntaxKind.AmpersandAmpersandToken) { + const isUsed = ts.forEachChild(node.right, function visit(child): boolean | undefined { + if (ts.isIdentifier(child)) { const symbol = getSymbolAtLocation(child); if (symbol && symbol === testedSymbol) { return true; } } - return forEachChild(child, visit); + return ts.forEachChild(child, visit); }); if (isUsed) { return true; @@ -38045,7 +37232,7 @@ namespace ts { return false; } - function checkDoStatement(node: DoStatement) { + function checkDoStatement(node: ts.DoStatement) { // Grammar checking checkGrammarStatementInAmbientContext(node); @@ -38053,7 +37240,7 @@ namespace ts { checkTruthinessExpression(node.expression); } - function checkWhileStatement(node: WhileStatement) { + function checkWhileStatement(node: ts.WhileStatement) { // Grammar checking checkGrammarStatementInAmbientContext(node); @@ -38061,61 +37248,63 @@ namespace ts { checkSourceElement(node.statement); } - function checkTruthinessOfType(type: Type, node: Node) { - if (type.flags & TypeFlags.Void) { - error(node, Diagnostics.An_expression_of_type_void_cannot_be_tested_for_truthiness); + function checkTruthinessOfType(type: ts.Type, node: ts.Node) { + if (type.flags & ts.TypeFlags.Void) { + error(node, ts.Diagnostics.An_expression_of_type_void_cannot_be_tested_for_truthiness); } return type; } - function checkTruthinessExpression(node: Expression, checkMode?: CheckMode) { + function checkTruthinessExpression(node: ts.Expression, checkMode?: CheckMode) { return checkTruthinessOfType(checkExpression(node, checkMode), node); } - function checkForStatement(node: ForStatement) { + function checkForStatement(node: ts.ForStatement) { // Grammar checking if (!checkGrammarStatementInAmbientContext(node)) { - if (node.initializer && node.initializer.kind === SyntaxKind.VariableDeclarationList) { - checkGrammarVariableDeclarationList(node.initializer as VariableDeclarationList); + if (node.initializer && node.initializer.kind === ts.SyntaxKind.VariableDeclarationList) { + checkGrammarVariableDeclarationList(node.initializer as ts.VariableDeclarationList); } } if (node.initializer) { - if (node.initializer.kind === SyntaxKind.VariableDeclarationList) { - forEach((node.initializer as VariableDeclarationList).declarations, checkVariableDeclaration); + if (node.initializer.kind === ts.SyntaxKind.VariableDeclarationList) { + ts.forEach((node.initializer as ts.VariableDeclarationList).declarations, checkVariableDeclaration); } else { checkExpression(node.initializer); } } - if (node.condition) checkTruthinessExpression(node.condition); - if (node.incrementor) checkExpression(node.incrementor); + if (node.condition) + checkTruthinessExpression(node.condition); + if (node.incrementor) + checkExpression(node.incrementor); checkSourceElement(node.statement); if (node.locals) { registerForUnusedIdentifiersCheck(node); } } - function checkForOfStatement(node: ForOfStatement): void { + function checkForOfStatement(node: ts.ForOfStatement): void { checkGrammarForInOrForOfStatement(node); - const container = getContainingFunctionOrClassStaticBlock(node); + const container = ts.getContainingFunctionOrClassStaticBlock(node); if (node.awaitModifier) { - if (container && isClassStaticBlockDeclaration(container)) { - grammarErrorOnNode(node.awaitModifier, Diagnostics.For_await_loops_cannot_be_used_inside_a_class_static_block); + if (container && ts.isClassStaticBlockDeclaration(container)) { + grammarErrorOnNode(node.awaitModifier, ts.Diagnostics.For_await_loops_cannot_be_used_inside_a_class_static_block); } else { - const functionFlags = getFunctionFlags(container); - if ((functionFlags & (FunctionFlags.Invalid | FunctionFlags.Async)) === FunctionFlags.Async && languageVersion < ScriptTarget.ESNext) { + const functionFlags = ts.getFunctionFlags(container); + if ((functionFlags & (ts.FunctionFlags.Invalid | ts.FunctionFlags.Async)) === ts.FunctionFlags.Async && languageVersion < ts.ScriptTarget.ESNext) { // for..await..of in an async function or async generator function prior to ESNext requires the __asyncValues helper - checkExternalEmitHelpers(node, ExternalEmitHelpers.ForAwaitOfIncludes); + checkExternalEmitHelpers(node, ts.ExternalEmitHelpers.ForAwaitOfIncludes); } } } - else if (compilerOptions.downlevelIteration && languageVersion < ScriptTarget.ES2015) { + else if (compilerOptions.downlevelIteration && languageVersion < ts.ScriptTarget.ES2015) { // for..of prior to ES2015 requires the __values helper when downlevelIteration is enabled - checkExternalEmitHelpers(node, ExternalEmitHelpers.ForOfIncludes); + checkExternalEmitHelpers(node, ts.ExternalEmitHelpers.ForOfIncludes); } // Check the LHS and RHS @@ -38123,7 +37312,7 @@ namespace ts { // via checkRightHandSideOfForOf. // If the LHS is an expression, check the LHS, as a destructuring assignment or as a reference. // Then check that the RHS is assignable to it. - if (node.initializer.kind === SyntaxKind.VariableDeclarationList) { + if (node.initializer.kind === ts.SyntaxKind.VariableDeclarationList) { checkForInOrForOfVariableDeclaration(node); } else { @@ -38131,7 +37320,7 @@ namespace ts { const iteratedType = checkRightHandSideOfForOf(node); // There may be a destructuring assignment on the left side - if (varExpr.kind === SyntaxKind.ArrayLiteralExpression || varExpr.kind === SyntaxKind.ObjectLiteralExpression) { + if (varExpr.kind === ts.SyntaxKind.ArrayLiteralExpression || varExpr.kind === ts.SyntaxKind.ObjectLiteralExpression) { // iteratedType may be undefined. In this case, we still want to check the structure of // varExpr, in particular making sure it's a valid LeftHandSideExpression. But we'd like // to short circuit the type relation checking as much as possible, so we pass the unknownType. @@ -38139,10 +37328,7 @@ namespace ts { } else { const leftType = checkExpression(varExpr); - checkReferenceExpression( - varExpr, - Diagnostics.The_left_hand_side_of_a_for_of_statement_must_be_a_variable_or_a_property_access, - Diagnostics.The_left_hand_side_of_a_for_of_statement_may_not_be_an_optional_property_access); + checkReferenceExpression(varExpr, ts.Diagnostics.The_left_hand_side_of_a_for_of_statement_must_be_a_variable_or_a_property_access, ts.Diagnostics.The_left_hand_side_of_a_for_of_statement_may_not_be_an_optional_property_access); // iteratedType will be undefined if the rightType was missing properties/signatures // required to get its iteratedType (like [Symbol.iterator] or next). This may be @@ -38160,7 +37346,7 @@ namespace ts { } } - function checkForInStatement(node: ForInStatement) { + function checkForInStatement(node: ts.ForInStatement) { // Grammar checking checkGrammarForInOrForOfStatement(node); @@ -38170,10 +37356,10 @@ namespace ts { // for (let VarDecl in Expr) Statement // VarDecl must be a variable declaration without a type annotation that declares a variable of type Any, // and Expr must be an expression of type Any, an object type, or a type parameter type. - if (node.initializer.kind === SyntaxKind.VariableDeclarationList) { - const variable = (node.initializer as VariableDeclarationList).declarations[0]; - if (variable && isBindingPattern(variable.name)) { - error(variable.name, Diagnostics.The_left_hand_side_of_a_for_in_statement_cannot_be_a_destructuring_pattern); + if (node.initializer.kind === ts.SyntaxKind.VariableDeclarationList) { + const variable = (node.initializer as ts.VariableDeclarationList).declarations[0]; + if (variable && ts.isBindingPattern(variable.name)) { + error(variable.name, ts.Diagnostics.The_left_hand_side_of_a_for_in_statement_cannot_be_a_destructuring_pattern); } checkForInOrForOfVariableDeclaration(node); } @@ -38184,25 +37370,22 @@ namespace ts { // and Expr must be an expression of type Any, an object type, or a type parameter type. const varExpr = node.initializer; const leftType = checkExpression(varExpr); - if (varExpr.kind === SyntaxKind.ArrayLiteralExpression || varExpr.kind === SyntaxKind.ObjectLiteralExpression) { - error(varExpr, Diagnostics.The_left_hand_side_of_a_for_in_statement_cannot_be_a_destructuring_pattern); + if (varExpr.kind === ts.SyntaxKind.ArrayLiteralExpression || varExpr.kind === ts.SyntaxKind.ObjectLiteralExpression) { + error(varExpr, ts.Diagnostics.The_left_hand_side_of_a_for_in_statement_cannot_be_a_destructuring_pattern); } else if (!isTypeAssignableTo(getIndexTypeOrString(rightType), leftType)) { - error(varExpr, Diagnostics.The_left_hand_side_of_a_for_in_statement_must_be_of_type_string_or_any); + error(varExpr, ts.Diagnostics.The_left_hand_side_of_a_for_in_statement_must_be_of_type_string_or_any); } else { // run check only former check succeeded to avoid cascading errors - checkReferenceExpression( - varExpr, - Diagnostics.The_left_hand_side_of_a_for_in_statement_must_be_a_variable_or_a_property_access, - Diagnostics.The_left_hand_side_of_a_for_in_statement_may_not_be_an_optional_property_access); + checkReferenceExpression(varExpr, ts.Diagnostics.The_left_hand_side_of_a_for_in_statement_must_be_a_variable_or_a_property_access, ts.Diagnostics.The_left_hand_side_of_a_for_in_statement_may_not_be_an_optional_property_access); } } // unknownType is returned i.e. if node.expression is identifier whose name cannot be resolved // in this case error about missing name is already reported - do not report extra one - if (rightType === neverType || !isTypeAssignableToKind(rightType, TypeFlags.NonPrimitive | TypeFlags.InstantiableNonPrimitive)) { - error(node.expression, Diagnostics.The_right_hand_side_of_a_for_in_statement_must_be_of_type_any_an_object_type_or_a_type_parameter_but_here_has_type_0, typeToString(rightType)); + if (rightType === neverType || !isTypeAssignableToKind(rightType, ts.TypeFlags.NonPrimitive | ts.TypeFlags.InstantiableNonPrimitive)) { + error(node.expression, ts.Diagnostics.The_right_hand_side_of_a_for_in_statement_must_be_of_type_any_an_object_type_or_a_type_parameter_but_here_has_type_0, typeToString(rightType)); } checkSourceElement(node.statement); @@ -38211,8 +37394,8 @@ namespace ts { } } - function checkForInOrForOfVariableDeclaration(iterationStatement: ForInOrOfStatement): void { - const variableDeclarationList = iterationStatement.initializer as VariableDeclarationList; + function checkForInOrForOfVariableDeclaration(iterationStatement: ts.ForInOrOfStatement): void { + const variableDeclarationList = iterationStatement.initializer as ts.VariableDeclarationList; // checkGrammarForInOrForOfStatement will check that there is exactly one declaration. if (variableDeclarationList.declarations.length >= 1) { const decl = variableDeclarationList.declarations[0]; @@ -38220,12 +37403,12 @@ namespace ts { } } - function checkRightHandSideOfForOf(statement: ForOfStatement): Type { + function checkRightHandSideOfForOf(statement: ts.ForOfStatement): ts.Type { const use = statement.awaitModifier ? IterationUse.ForAwaitOf : IterationUse.ForOf; return checkIteratedTypeOrElementType(use, checkNonNullExpression(statement.expression), undefinedType, statement.expression); } - function checkIteratedTypeOrElementType(use: IterationUse, inputType: Type, sentType: Type, errorNode: Node | undefined): Type { + function checkIteratedTypeOrElementType(use: IterationUse, inputType: ts.Type, sentType: ts.Type, errorNode: ts.Node | undefined): ts.Type { if (isTypeAny(inputType)) { return inputType; } @@ -38237,14 +37420,14 @@ namespace ts { * we want to get the iterated type of an iterable for ES2015 or later, or the iterated type * of a iterable (if defined globally) or element type of an array like for ES2015 or earlier. */ - function getIteratedTypeOrElementType(use: IterationUse, inputType: Type, sentType: Type, errorNode: Node | undefined, checkAssignability: boolean): Type | undefined { + function getIteratedTypeOrElementType(use: IterationUse, inputType: ts.Type, sentType: ts.Type, errorNode: ts.Node | undefined, checkAssignability: boolean): ts.Type | undefined { const allowAsyncIterables = (use & IterationUse.AllowsAsyncIterablesFlag) !== 0; if (inputType === neverType) { reportTypeNotIterableError(errorNode!, inputType, allowAsyncIterables); // TODO: GH#18217 return undefined; } - const uplevelIteration = languageVersion >= ScriptTarget.ES2015; + const uplevelIteration = languageVersion >= ts.ScriptTarget.ES2015; const downlevelIteration = !uplevelIteration && compilerOptions.downlevelIteration; const possibleOutOfBounds = compilerOptions.noUncheckedIndexedAccess && !!(use & IterationUse.PossiblyOutOfBounds); @@ -38256,11 +37439,10 @@ namespace ts { const iterationTypes = getIterationTypesOfIterable(inputType, use, uplevelIteration ? errorNode : undefined); if (checkAssignability) { if (iterationTypes) { - const diagnostic = - use & IterationUse.ForOfFlag ? Diagnostics.Cannot_iterate_value_because_the_next_method_of_its_iterator_expects_type_1_but_for_of_will_always_send_0 : - use & IterationUse.SpreadFlag ? Diagnostics.Cannot_iterate_value_because_the_next_method_of_its_iterator_expects_type_1_but_array_spread_will_always_send_0 : - use & IterationUse.DestructuringFlag ? Diagnostics.Cannot_iterate_value_because_the_next_method_of_its_iterator_expects_type_1_but_array_destructuring_will_always_send_0 : - use & IterationUse.YieldStarFlag ? Diagnostics.Cannot_delegate_iteration_to_value_because_the_next_method_of_its_iterator_expects_type_1_but_the_containing_generator_will_always_send_0 : + const diagnostic = use & IterationUse.ForOfFlag ? ts.Diagnostics.Cannot_iterate_value_because_the_next_method_of_its_iterator_expects_type_1_but_for_of_will_always_send_0 : + use & IterationUse.SpreadFlag ? ts.Diagnostics.Cannot_iterate_value_because_the_next_method_of_its_iterator_expects_type_1_but_array_spread_will_always_send_0 : + use & IterationUse.DestructuringFlag ? ts.Diagnostics.Cannot_iterate_value_because_the_next_method_of_its_iterator_expects_type_1_but_array_destructuring_will_always_send_0 : + use & IterationUse.YieldStarFlag ? ts.Diagnostics.Cannot_delegate_iteration_to_value_because_the_next_method_of_its_iterator_expects_type_1_but_the_containing_generator_will_always_send_0 : undefined; if (diagnostic) { checkTypeAssignableTo(sentType, iterationTypes.nextType, errorNode, diagnostic); @@ -38280,31 +37462,31 @@ namespace ts { // This allows us to find other non-string element types from an array unioned with // a string. if (use & IterationUse.AllowsStringInputFlag) { - if (arrayType.flags & TypeFlags.Union) { + if (arrayType.flags & ts.TypeFlags.Union) { // After we remove all types that are StringLike, we will know if there was a string constituent // based on whether the result of filter is a new array. - const arrayTypes = (inputType as UnionType).types; - const filteredTypes = filter(arrayTypes, t => !(t.flags & TypeFlags.StringLike)); + const arrayTypes = (inputType as ts.UnionType).types; + const filteredTypes = ts.filter(arrayTypes, t => !(t.flags & ts.TypeFlags.StringLike)); if (filteredTypes !== arrayTypes) { - arrayType = getUnionType(filteredTypes, UnionReduction.Subtype); + arrayType = getUnionType(filteredTypes, ts.UnionReduction.Subtype); } } - else if (arrayType.flags & TypeFlags.StringLike) { + else if (arrayType.flags & ts.TypeFlags.StringLike) { arrayType = neverType; } hasStringConstituent = arrayType !== inputType; if (hasStringConstituent) { - if (languageVersion < ScriptTarget.ES5) { + if (languageVersion < ts.ScriptTarget.ES5) { if (errorNode) { - error(errorNode, Diagnostics.Using_a_string_in_a_for_of_statement_is_only_supported_in_ECMAScript_5_and_higher); + error(errorNode, ts.Diagnostics.Using_a_string_in_a_for_of_statement_is_only_supported_in_ECMAScript_5_and_higher); reportedError = true; } } // Now that we've removed all the StringLike types, if no constituents remain, then the entire // arrayOrStringType was a string. - if (arrayType.flags & TypeFlags.Never) { + if (arrayType.flags & ts.TypeFlags.Never) { return possibleOutOfBounds ? includeUndefinedInIndexSignature(stringType) : stringType; } } @@ -38319,11 +37501,7 @@ namespace ts { // array type or a string type. const allowsStrings = !!(use & IterationUse.AllowsStringInputFlag) && !hasStringConstituent; const [defaultDiagnostic, maybeMissingAwait] = getIterationDiagnosticDetails(allowsStrings, downlevelIteration); - errorAndMaybeSuggestAwait( - errorNode, - maybeMissingAwait && !!getAwaitedTypeOfPromise(arrayType), - defaultDiagnostic, - typeToString(arrayType)); + errorAndMaybeSuggestAwait(errorNode, maybeMissingAwait && !!getAwaitedTypeOfPromise(arrayType), defaultDiagnostic, typeToString(arrayType)); } return hasStringConstituent ? possibleOutOfBounds ? includeUndefinedInIndexSignature(stringType) : stringType : undefined; } @@ -38331,39 +37509,42 @@ namespace ts { const arrayElementType = getIndexTypeOfType(arrayType, numberType); if (hasStringConstituent && arrayElementType) { // This is just an optimization for the case where arrayOrStringType is string | string[] - if (arrayElementType.flags & TypeFlags.StringLike && !compilerOptions.noUncheckedIndexedAccess) { + if (arrayElementType.flags & ts.TypeFlags.StringLike && !compilerOptions.noUncheckedIndexedAccess) { return stringType; } - return getUnionType(possibleOutOfBounds ? [arrayElementType, stringType, undefinedType] : [arrayElementType, stringType], UnionReduction.Subtype); + return getUnionType(possibleOutOfBounds ? [arrayElementType, stringType, undefinedType] : [arrayElementType, stringType], ts.UnionReduction.Subtype); } return (use & IterationUse.PossiblyOutOfBounds) ? includeUndefinedInIndexSignature(arrayElementType) : arrayElementType; - function getIterationDiagnosticDetails(allowsStrings: boolean, downlevelIteration: boolean | undefined): [error: DiagnosticMessage, maybeMissingAwait: boolean] { + function getIterationDiagnosticDetails(allowsStrings: boolean, downlevelIteration: boolean | undefined): [ + error: ts.DiagnosticMessage, + maybeMissingAwait: boolean + ] { if (downlevelIteration) { return allowsStrings - ? [Diagnostics.Type_0_is_not_an_array_type_or_a_string_type_or_does_not_have_a_Symbol_iterator_method_that_returns_an_iterator, true] - : [Diagnostics.Type_0_is_not_an_array_type_or_does_not_have_a_Symbol_iterator_method_that_returns_an_iterator, true]; + ? [ts.Diagnostics.Type_0_is_not_an_array_type_or_a_string_type_or_does_not_have_a_Symbol_iterator_method_that_returns_an_iterator, true] + : [ts.Diagnostics.Type_0_is_not_an_array_type_or_does_not_have_a_Symbol_iterator_method_that_returns_an_iterator, true]; } const yieldType = getIterationTypeOfIterable(use, IterationTypeKind.Yield, inputType, /*errorNode*/ undefined); if (yieldType) { - return [Diagnostics.Type_0_can_only_be_iterated_through_when_using_the_downlevelIteration_flag_or_with_a_target_of_es2015_or_higher, false]; + return [ts.Diagnostics.Type_0_can_only_be_iterated_through_when_using_the_downlevelIteration_flag_or_with_a_target_of_es2015_or_higher, false]; } if (isES2015OrLaterIterable(inputType.symbol?.escapedName)) { - return [Diagnostics.Type_0_can_only_be_iterated_through_when_using_the_downlevelIteration_flag_or_with_a_target_of_es2015_or_higher, true]; + return [ts.Diagnostics.Type_0_can_only_be_iterated_through_when_using_the_downlevelIteration_flag_or_with_a_target_of_es2015_or_higher, true]; } return allowsStrings - ? [Diagnostics.Type_0_is_not_an_array_type_or_a_string_type, true] - : [Diagnostics.Type_0_is_not_an_array_type, true]; + ? [ts.Diagnostics.Type_0_is_not_an_array_type_or_a_string_type, true] + : [ts.Diagnostics.Type_0_is_not_an_array_type, true]; } } - function isES2015OrLaterIterable(n: __String) { + function isES2015OrLaterIterable(n: ts.__String) { switch (n) { case "Float32Array": case "Float64Array": @@ -38383,7 +37564,7 @@ namespace ts { /** * Gets the requested "iteration type" from an `Iterable`-like or `AsyncIterable`-like type. */ - function getIterationTypeOfIterable(use: IterationUse, typeKind: IterationTypeKind, inputType: Type, errorNode: Node | undefined): Type | undefined { + function getIterationTypeOfIterable(use: IterationUse, typeKind: IterationTypeKind, inputType: ts.Type, errorNode: ts.Node | undefined): ts.Type | undefined { if (isTypeAny(inputType)) { return undefined; } @@ -38392,7 +37573,7 @@ namespace ts { return iterationTypes && iterationTypes[getIterationTypesKeyFromIterationTypeKind(typeKind)]; } - function createIterationTypes(yieldType: Type = neverType, returnType: Type = neverType, nextType: Type = unknownType): IterationTypes { + function createIterationTypes(yieldType: ts.Type = neverType, returnType: ts.Type = neverType, nextType: ts.Type = unknownType): ts.IterationTypes { // `yieldType` and `returnType` are defaulted to `neverType` they each will be combined // via `getUnionType` when merging iteration types. `nextType` is defined as `unknownType` // as it is combined via `getIntersectionType` when merging iteration types. @@ -38401,9 +37582,9 @@ namespace ts { // more frequently created (i.e. `Iterator`). Iteration types // are also cached on the type they are requested for, so we shouldn't need to maintain // the cache for less-frequently used types. - if (yieldType.flags & TypeFlags.Intrinsic && - returnType.flags & (TypeFlags.Any | TypeFlags.Never | TypeFlags.Unknown | TypeFlags.Void | TypeFlags.Undefined) && - nextType.flags & (TypeFlags.Any | TypeFlags.Never | TypeFlags.Unknown | TypeFlags.Void | TypeFlags.Undefined)) { + if (yieldType.flags & ts.TypeFlags.Intrinsic && + returnType.flags & (ts.TypeFlags.Any | ts.TypeFlags.Never | ts.TypeFlags.Unknown | ts.TypeFlags.Void | ts.TypeFlags.Undefined) && + nextType.flags & (ts.TypeFlags.Any | ts.TypeFlags.Never | ts.TypeFlags.Unknown | ts.TypeFlags.Void | ts.TypeFlags.Undefined)) { const id = getTypeListId([yieldType, returnType, nextType]); let iterationTypes = iterationTypesCache.get(id); if (!iterationTypes) { @@ -38422,10 +37603,10 @@ namespace ts { * then `noIterationTypes` is returned. Otherwise, an `IterationTypes` record is returned * for the combined iteration types. */ - function combineIterationTypes(array: (IterationTypes | undefined)[]) { - let yieldTypes: Type[] | undefined; - let returnTypes: Type[] | undefined; - let nextTypes: Type[] | undefined; + function combineIterationTypes(array: (ts.IterationTypes | undefined)[]) { + let yieldTypes: ts.Type[] | undefined; + let returnTypes: ts.Type[] | undefined; + let nextTypes: ts.Type[] | undefined; for (const iterationTypes of array) { if (iterationTypes === undefined || iterationTypes === noIterationTypes) { continue; @@ -38433,25 +37614,22 @@ namespace ts { if (iterationTypes === anyIterationTypes) { return anyIterationTypes; } - yieldTypes = append(yieldTypes, iterationTypes.yieldType); - returnTypes = append(returnTypes, iterationTypes.returnType); - nextTypes = append(nextTypes, iterationTypes.nextType); + yieldTypes = ts.append(yieldTypes, iterationTypes.yieldType); + returnTypes = ts.append(returnTypes, iterationTypes.returnType); + nextTypes = ts.append(nextTypes, iterationTypes.nextType); } if (yieldTypes || returnTypes || nextTypes) { - return createIterationTypes( - yieldTypes && getUnionType(yieldTypes), - returnTypes && getUnionType(returnTypes), - nextTypes && getIntersectionType(nextTypes)); + return createIterationTypes(yieldTypes && getUnionType(yieldTypes), returnTypes && getUnionType(returnTypes), nextTypes && getIntersectionType(nextTypes)); } return noIterationTypes; } - function getCachedIterationTypes(type: Type, cacheKey: MatchingKeys) { - return (type as IterableOrIteratorType)[cacheKey]; + function getCachedIterationTypes(type: ts.Type, cacheKey: ts.MatchingKeys) { + return (type as ts.IterableOrIteratorType)[cacheKey]; } - function setCachedIterationTypes(type: Type, cacheKey: MatchingKeys, cachedTypes: IterationTypes) { - return (type as IterableOrIteratorType)[cacheKey] = cachedTypes; + function setCachedIterationTypes(type: ts.Type, cacheKey: ts.MatchingKeys, cachedTypes: ts.IterationTypes) { + return (type as ts.IterableOrIteratorType)[cacheKey] = cachedTypes; } /** @@ -38475,12 +37653,12 @@ namespace ts { * For a **for-await-of** statement or a `yield*` in an async generator we will look for * the `[Symbol.asyncIterator]()` method first, and then the `[Symbol.iterator]()` method. */ - function getIterationTypesOfIterable(type: Type, use: IterationUse, errorNode: Node | undefined) { + function getIterationTypesOfIterable(type: ts.Type, use: IterationUse, errorNode: ts.Node | undefined) { if (isTypeAny(type)) { return anyIterationTypes; } - if (!(type.flags & TypeFlags.Union)) { + if (!(type.flags & ts.TypeFlags.Union)) { const iterationTypes = getIterationTypesOfIterableWorker(type, use, errorNode); if (iterationTypes === noIterationTypes) { if (errorNode) { @@ -38493,10 +37671,10 @@ namespace ts { const cacheKey = use & IterationUse.AllowsAsyncIterablesFlag ? "iterationTypesOfAsyncIterable" : "iterationTypesOfIterable"; const cachedTypes = getCachedIterationTypes(type, cacheKey); - if (cachedTypes) return cachedTypes === noIterationTypes ? undefined : cachedTypes; - - let allIterationTypes: IterationTypes[] | undefined; - for (const constituent of (type as UnionType).types) { + if (cachedTypes) + return cachedTypes === noIterationTypes ? undefined : cachedTypes; + let allIterationTypes: ts.IterationTypes[] | undefined; + for (const constituent of (type as ts.UnionType).types) { const iterationTypes = getIterationTypesOfIterableWorker(constituent, use, errorNode); if (iterationTypes === noIterationTypes) { if (errorNode) { @@ -38506,7 +37684,7 @@ namespace ts { return undefined; } else { - allIterationTypes = append(allIterationTypes, iterationTypes); + allIterationTypes = ts.append(allIterationTypes, iterationTypes); } } @@ -38515,18 +37693,17 @@ namespace ts { return iterationTypes === noIterationTypes ? undefined : iterationTypes; } - function getAsyncFromSyncIterationTypes(iterationTypes: IterationTypes, errorNode: Node | undefined) { - if (iterationTypes === noIterationTypes) return noIterationTypes; - if (iterationTypes === anyIterationTypes) return anyIterationTypes; + function getAsyncFromSyncIterationTypes(iterationTypes: ts.IterationTypes, errorNode: ts.Node | undefined) { + if (iterationTypes === noIterationTypes) + return noIterationTypes; + if (iterationTypes === anyIterationTypes) + return anyIterationTypes; const { yieldType, returnType, nextType } = iterationTypes; // if we're requesting diagnostics, report errors for a missing `Awaited`. if (errorNode) { getGlobalAwaitedSymbol(/*reportErrors*/ true); } - return createIterationTypes( - getAwaitedType(yieldType, errorNode) || anyType, - getAwaitedType(returnType, errorNode) || anyType, - nextType); + return createIterationTypes(getAwaitedType(yieldType, errorNode) || anyType, getAwaitedType(returnType, errorNode) || anyType, nextType); } /** @@ -38539,14 +37716,13 @@ namespace ts { * NOTE: You probably don't want to call this directly and should be calling * `getIterationTypesOfIterable` instead. */ - function getIterationTypesOfIterableWorker(type: Type, use: IterationUse, errorNode: Node | undefined) { + function getIterationTypesOfIterableWorker(type: ts.Type, use: IterationUse, errorNode: ts.Node | undefined) { if (isTypeAny(type)) { return anyIterationTypes; } if (use & IterationUse.AllowsAsyncIterablesFlag) { - const iterationTypes = - getIterationTypesOfIterableCached(type, asyncIterationTypesResolver) || + const iterationTypes = getIterationTypesOfIterableCached(type, asyncIterationTypesResolver) || getIterationTypesOfIterableFast(type, asyncIterationTypesResolver); if (iterationTypes) { return use & IterationUse.ForOfFlag ? @@ -38556,8 +37732,7 @@ namespace ts { } if (use & IterationUse.AllowsSyncIterablesFlag) { - const iterationTypes = - getIterationTypesOfIterableCached(type, syncIterationTypesResolver) || + const iterationTypes = getIterationTypesOfIterableCached(type, syncIterationTypesResolver) || getIterationTypesOfIterableFast(type, syncIterationTypesResolver); if (iterationTypes) { if (use & IterationUse.AllowsAsyncIterablesFlag) { @@ -38603,13 +37778,12 @@ namespace ts { * NOTE: You probably don't want to call this directly and should be calling * `getIterationTypesOfIterable` instead. */ - function getIterationTypesOfIterableCached(type: Type, resolver: IterationTypesResolver) { + function getIterationTypesOfIterableCached(type: ts.Type, resolver: IterationTypesResolver) { return getCachedIterationTypes(type, resolver.iterableCacheKey); } - function getIterationTypesOfGlobalIterableType(globalType: Type, resolver: IterationTypesResolver) { - const globalIterationTypes = - getIterationTypesOfIterableCached(globalType, resolver) || + function getIterationTypesOfGlobalIterableType(globalType: ts.Type, resolver: IterationTypesResolver) { + const globalIterationTypes = getIterationTypesOfIterableCached(globalType, resolver) || getIterationTypesOfIterableSlow(globalType, resolver, /*errorNode*/ undefined); return globalIterationTypes === noIterationTypes ? defaultIterationTypes : globalIterationTypes; } @@ -38626,15 +37800,15 @@ namespace ts { * NOTE: You probably don't want to call this directly and should be calling * `getIterationTypesOfIterable` instead. */ - function getIterationTypesOfIterableFast(type: Type, resolver: IterationTypesResolver) { + function getIterationTypesOfIterableFast(type: ts.Type, resolver: IterationTypesResolver) { // As an optimization, if the type is an instantiation of one of the following global types, then // just grab its related type argument: // - `Iterable` or `AsyncIterable` // - `IterableIterator` or `AsyncIterableIterator` - let globalType: Type; + let globalType: ts.Type; if (isReferenceToType(type, globalType = resolver.getGlobalIterableType(/*reportErrors*/ false)) || isReferenceToType(type, globalType = resolver.getGlobalIterableIteratorType(/*reportErrors*/ false))) { - const [yieldType] = getTypeArguments(type as GenericType); + const [yieldType] = getTypeArguments(type as ts.GenericType); // The "return" and "next" types of `Iterable` and `IterableIterator` are defined by the // iteration types of their `[Symbol.iterator]()` method. The same is true for their async cousins. // While we define these as `any` and `undefined` in our libs by default, a custom lib *could* use @@ -38647,15 +37821,15 @@ namespace ts { // just grab its related type arguments: // - `Generator` or `AsyncGenerator` if (isReferenceToType(type, resolver.getGlobalGeneratorType(/*reportErrors*/ false))) { - const [yieldType, returnType, nextType] = getTypeArguments(type as GenericType); + const [yieldType, returnType, nextType] = getTypeArguments(type as ts.GenericType); return setCachedIterationTypes(type, resolver.iterableCacheKey, createIterationTypes(resolver.resolveIterationType(yieldType, /*errorNode*/ undefined) || yieldType, resolver.resolveIterationType(returnType, /*errorNode*/ undefined) || returnType, nextType)); } } - function getPropertyNameForKnownSymbolName(symbolName: string): __String { + function getPropertyNameForKnownSymbolName(symbolName: string): ts.__String { const ctorType = getGlobalESSymbolConstructorSymbol(/*reportErrors*/ false); - const uniqueType = ctorType && getTypeOfPropertyOfType(getTypeOfSymbol(ctorType), escapeLeadingUnderscores(symbolName)); - return uniqueType && isTypeUsableAsPropertyName(uniqueType) ? getPropertyNameFromType(uniqueType) : `__@${symbolName}` as __String; + const uniqueType = ctorType && getTypeOfPropertyOfType(getTypeOfSymbol(ctorType), ts.escapeLeadingUnderscores(symbolName)); + return uniqueType && isTypeUsableAsPropertyName(uniqueType) ? getPropertyNameFromType(uniqueType) : `__@${symbolName}` as ts.__String; } /** @@ -38668,27 +37842,27 @@ namespace ts { * NOTE: You probably don't want to call this directly and should be calling * `getIterationTypesOfIterable` instead. */ - function getIterationTypesOfIterableSlow(type: Type, resolver: IterationTypesResolver, errorNode: Node | undefined) { + function getIterationTypesOfIterableSlow(type: ts.Type, resolver: IterationTypesResolver, errorNode: ts.Node | undefined) { const method = getPropertyOfType(type, getPropertyNameForKnownSymbolName(resolver.iteratorSymbolName)); - const methodType = method && !(method.flags & SymbolFlags.Optional) ? getTypeOfSymbol(method) : undefined; + const methodType = method && !(method.flags & ts.SymbolFlags.Optional) ? getTypeOfSymbol(method) : undefined; if (isTypeAny(methodType)) { return setCachedIterationTypes(type, resolver.iterableCacheKey, anyIterationTypes); } - const signatures = methodType ? getSignaturesOfType(methodType, SignatureKind.Call) : undefined; - if (!some(signatures)) { + const signatures = methodType ? getSignaturesOfType(methodType, ts.SignatureKind.Call) : undefined; + if (!ts.some(signatures)) { return setCachedIterationTypes(type, resolver.iterableCacheKey, noIterationTypes); } - const iteratorType = getIntersectionType(map(signatures, getReturnTypeOfSignature)); + const iteratorType = getIntersectionType(ts.map(signatures, getReturnTypeOfSignature)); const iterationTypes = getIterationTypesOfIterator(iteratorType, resolver, errorNode) ?? noIterationTypes; return setCachedIterationTypes(type, resolver.iterableCacheKey, iterationTypes); } - function reportTypeNotIterableError(errorNode: Node, type: Type, allowAsyncIterables: boolean): void { + function reportTypeNotIterableError(errorNode: ts.Node, type: ts.Type, allowAsyncIterables: boolean): void { const message = allowAsyncIterables - ? Diagnostics.Type_0_must_have_a_Symbol_asyncIterator_method_that_returns_an_async_iterator - : Diagnostics.Type_0_must_have_a_Symbol_iterator_method_that_returns_an_iterator; + ? ts.Diagnostics.Type_0_must_have_a_Symbol_asyncIterator_method_that_returns_an_async_iterator + : ts.Diagnostics.Type_0_must_have_a_Symbol_iterator_method_that_returns_an_iterator; errorAndMaybeSuggestAwait(errorNode, !!getAwaitedTypeOfPromise(type), message, typeToString(type)); } @@ -38698,13 +37872,12 @@ namespace ts { * If we successfully found the *yield*, *return*, and *next* types, an `IterationTypes` * record is returned. Otherwise, `undefined` is returned. */ - function getIterationTypesOfIterator(type: Type, resolver: IterationTypesResolver, errorNode: Node | undefined) { + function getIterationTypesOfIterator(type: ts.Type, resolver: IterationTypesResolver, errorNode: ts.Node | undefined) { if (isTypeAny(type)) { return anyIterationTypes; } - const iterationTypes = - getIterationTypesOfIteratorCached(type, resolver) || + const iterationTypes = getIterationTypesOfIteratorCached(type, resolver) || getIterationTypesOfIteratorFast(type, resolver) || getIterationTypesOfIteratorSlow(type, resolver, errorNode); return iterationTypes === noIterationTypes ? undefined : iterationTypes; @@ -38717,7 +37890,7 @@ namespace ts { * NOTE: You probably don't want to call this directly and should be calling * `getIterationTypesOfIterator` instead. */ - function getIterationTypesOfIteratorCached(type: Type, resolver: IterationTypesResolver) { + function getIterationTypesOfIteratorCached(type: ts.Type, resolver: IterationTypesResolver) { return getCachedIterationTypes(type, resolver.iteratorCacheKey); } @@ -38733,7 +37906,7 @@ namespace ts { * NOTE: You probably don't want to call this directly and should be calling * `getIterationTypesOfIterator` instead. */ - function getIterationTypesOfIteratorFast(type: Type, resolver: IterationTypesResolver) { + function getIterationTypesOfIteratorFast(type: ts.Type, resolver: IterationTypesResolver) { // As an optimization, if the type is an instantiation of one of the following global types, // then just grab its related type argument: // - `IterableIterator` or `AsyncIterableIterator` @@ -38741,37 +37914,36 @@ namespace ts { // - `Generator` or `AsyncGenerator` const globalType = resolver.getGlobalIterableIteratorType(/*reportErrors*/ false); if (isReferenceToType(type, globalType)) { - const [yieldType] = getTypeArguments(type as GenericType); + const [yieldType] = getTypeArguments(type as ts.GenericType); // The "return" and "next" types of `IterableIterator` and `AsyncIterableIterator` are defined by the // iteration types of their `next`, `return`, and `throw` methods. While we define these as `any` // and `undefined` in our libs by default, a custom lib *could* use different definitions. - const globalIterationTypes = - getIterationTypesOfIteratorCached(globalType, resolver) || + const globalIterationTypes = getIterationTypesOfIteratorCached(globalType, resolver) || getIterationTypesOfIteratorSlow(globalType, resolver, /*errorNode*/ undefined); const { returnType, nextType } = globalIterationTypes === noIterationTypes ? defaultIterationTypes : globalIterationTypes; return setCachedIterationTypes(type, resolver.iteratorCacheKey, createIterationTypes(yieldType, returnType, nextType)); } if (isReferenceToType(type, resolver.getGlobalIteratorType(/*reportErrors*/ false)) || isReferenceToType(type, resolver.getGlobalGeneratorType(/*reportErrors*/ false))) { - const [yieldType, returnType, nextType] = getTypeArguments(type as GenericType); + const [yieldType, returnType, nextType] = getTypeArguments(type as ts.GenericType); return setCachedIterationTypes(type, resolver.iteratorCacheKey, createIterationTypes(yieldType, returnType, nextType)); } } - function isIteratorResult(type: Type, kind: IterationTypeKind.Yield | IterationTypeKind.Return) { + function isIteratorResult(type: ts.Type, kind: IterationTypeKind.Yield | IterationTypeKind.Return) { // From https://tc39.github.io/ecma262/#sec-iteratorresult-interface: // > [done] is the result status of an iterator `next` method call. If the end of the iterator was reached `done` is `true`. // > If the end was not reached `done` is `false` and a value is available. // > If a `done` property (either own or inherited) does not exist, it is consider to have the value `false`. - const doneType = getTypeOfPropertyOfType(type, "done" as __String) || falseType; + const doneType = getTypeOfPropertyOfType(type, "done" as ts.__String) || falseType; return isTypeAssignableTo(kind === IterationTypeKind.Yield ? falseType : trueType, doneType); } - function isYieldIteratorResult(type: Type) { + function isYieldIteratorResult(type: ts.Type) { return isIteratorResult(type, IterationTypeKind.Yield); } - function isReturnIteratorResult(type: Type) { + function isReturnIteratorResult(type: ts.Type) { return isIteratorResult(type, IterationTypeKind.Return); } @@ -38782,7 +37954,7 @@ namespace ts { * returned to indicate to the caller that it should handle the error. Otherwise, an * `IterationTypes` record is returned. */ - function getIterationTypesOfIteratorResult(type: Type) { + function getIterationTypesOfIteratorResult(type: ts.Type) { if (isTypeAny(type)) { return anyIterationTypes; } @@ -38795,20 +37967,20 @@ namespace ts { // As an optimization, if the type is an instantiation of one of the global `IteratorYieldResult` // or `IteratorReturnResult` types, then just grab its type argument. if (isReferenceToType(type, getGlobalIteratorYieldResultType(/*reportErrors*/ false))) { - const yieldType = getTypeArguments(type as GenericType)[0]; + const yieldType = getTypeArguments(type as ts.GenericType)[0]; return setCachedIterationTypes(type, "iterationTypesOfIteratorResult", createIterationTypes(yieldType, /*returnType*/ undefined, /*nextType*/ undefined)); } if (isReferenceToType(type, getGlobalIteratorReturnResultType(/*reportErrors*/ false))) { - const returnType = getTypeArguments(type as GenericType)[0]; + const returnType = getTypeArguments(type as ts.GenericType)[0]; return setCachedIterationTypes(type, "iterationTypesOfIteratorResult", createIterationTypes(/*yieldType*/ undefined, returnType, /*nextType*/ undefined)); } // Choose any constituents that can produce the requested iteration type. const yieldIteratorResult = filterType(type, isYieldIteratorResult); - const yieldType = yieldIteratorResult !== neverType ? getTypeOfPropertyOfType(yieldIteratorResult, "value" as __String) : undefined; + const yieldType = yieldIteratorResult !== neverType ? getTypeOfPropertyOfType(yieldIteratorResult, "value" as ts.__String) : undefined; const returnIteratorResult = filterType(type, isReturnIteratorResult); - const returnType = returnIteratorResult !== neverType ? getTypeOfPropertyOfType(returnIteratorResult, "value" as __String) : undefined; + const returnType = returnIteratorResult !== neverType ? getTypeOfPropertyOfType(returnIteratorResult, "value" as ts.__String) : undefined; if (!yieldType && !returnType) { return setCachedIterationTypes(type, "iterationTypesOfIteratorResult", noIterationTypes); @@ -38828,15 +38000,15 @@ namespace ts { * If we successfully found the *yield*, *return*, and *next* types, an `IterationTypes` * record is returned. Otherwise, we return `undefined`. */ - function getIterationTypesOfMethod(type: Type, resolver: IterationTypesResolver, methodName: "next" | "return" | "throw", errorNode: Node | undefined): IterationTypes | undefined { - const method = getPropertyOfType(type, methodName as __String); + function getIterationTypesOfMethod(type: ts.Type, resolver: IterationTypesResolver, methodName: "next" | "return" | "throw", errorNode: ts.Node | undefined): ts.IterationTypes | undefined { + const method = getPropertyOfType(type, methodName as ts.__String); // Ignore 'return' or 'throw' if they are missing. if (!method && methodName !== "next") { return undefined; } - const methodType = method && !(methodName === "next" && (method.flags & SymbolFlags.Optional)) + const methodType = method && !(methodName === "next" && (method.flags & ts.SymbolFlags.Optional)) ? methodName === "next" ? getTypeOfSymbol(method) : getTypeWithFacts(getTypeOfSymbol(method), TypeFacts.NEUndefinedOrNull) : undefined; @@ -38846,7 +38018,7 @@ namespace ts { } // Both async and non-async iterators *must* have a `next` method. - const methodSignatures = methodType ? getSignaturesOfType(methodType, SignatureKind.Call) : emptyArray; + const methodSignatures = methodType ? getSignaturesOfType(methodType, ts.SignatureKind.Call) : ts.emptyArray; if (methodSignatures.length === 0) { if (errorNode) { const diagnostic = methodName === "next" @@ -38867,32 +38039,29 @@ namespace ts { if (methodType?.symbol && methodSignatures.length === 1) { const globalGeneratorType = resolver.getGlobalGeneratorType(/*reportErrors*/ false); const globalIteratorType = resolver.getGlobalIteratorType(/*reportErrors*/ false); - const isGeneratorMethod = globalGeneratorType.symbol?.members?.get(methodName as __String) === methodType.symbol; - const isIteratorMethod = !isGeneratorMethod && globalIteratorType.symbol?.members?.get(methodName as __String) === methodType.symbol; + const isGeneratorMethod = globalGeneratorType.symbol?.members?.get(methodName as ts.__String) === methodType.symbol; + const isIteratorMethod = !isGeneratorMethod && globalIteratorType.symbol?.members?.get(methodName as ts.__String) === methodType.symbol; if (isGeneratorMethod || isIteratorMethod) { const globalType = isGeneratorMethod ? globalGeneratorType : globalIteratorType; - const { mapper } = methodType as AnonymousType; - return createIterationTypes( - getMappedType(globalType.typeParameters![0], mapper!), - getMappedType(globalType.typeParameters![1], mapper!), - methodName === "next" ? getMappedType(globalType.typeParameters![2], mapper!) : undefined); + const { mapper } = methodType as ts.AnonymousType; + return createIterationTypes(getMappedType(globalType.typeParameters![0], mapper!), getMappedType(globalType.typeParameters![1], mapper!), methodName === "next" ? getMappedType(globalType.typeParameters![2], mapper!) : undefined); } } // Extract the first parameter and return type of each signature. - let methodParameterTypes: Type[] | undefined; - let methodReturnTypes: Type[] | undefined; + let methodParameterTypes: ts.Type[] | undefined; + let methodReturnTypes: ts.Type[] | undefined; for (const signature of methodSignatures) { - if (methodName !== "throw" && some(signature.parameters)) { - methodParameterTypes = append(methodParameterTypes, getTypeAtPosition(signature, 0)); + if (methodName !== "throw" && ts.some(signature.parameters)) { + methodParameterTypes = ts.append(methodParameterTypes, getTypeAtPosition(signature, 0)); } - methodReturnTypes = append(methodReturnTypes, getReturnTypeOfSignature(signature)); + methodReturnTypes = ts.append(methodReturnTypes, getReturnTypeOfSignature(signature)); } // Resolve the *next* or *return* type from the first parameter of a `next()` or // `return()` method, respectively. - let returnTypes: Type[] | undefined; - let nextType: Type | undefined; + let returnTypes: ts.Type[] | undefined; + let nextType: ts.Type | undefined; if (methodName !== "throw") { const methodParameterType = methodParameterTypes ? getUnionType(methodParameterTypes) : unknownType; if (methodName === "next") { @@ -38902,12 +38071,12 @@ namespace ts { else if (methodName === "return") { // The value of `return(value)` *is* awaited by async generators const resolvedMethodParameterType = resolver.resolveIterationType(methodParameterType, errorNode) || anyType; - returnTypes = append(returnTypes, resolvedMethodParameterType); + returnTypes = ts.append(returnTypes, resolvedMethodParameterType); } } // Resolve the *yield* and *return* types from the return type of the method (i.e. `IteratorResult`) - let yieldType: Type; + let yieldType: ts.Type; const methodReturnType = methodReturnTypes ? getIntersectionType(methodReturnTypes) : neverType; const resolvedMethodReturnType = resolver.resolveIterationType(methodReturnType, errorNode) || anyType; const iterationTypes = getIterationTypesOfIteratorResult(resolvedMethodReturnType); @@ -38916,11 +38085,11 @@ namespace ts { error(errorNode, resolver.mustHaveAValueDiagnostic, methodName); } yieldType = anyType; - returnTypes = append(returnTypes, anyType); + returnTypes = ts.append(returnTypes, anyType); } else { yieldType = iterationTypes.yieldType; - returnTypes = append(returnTypes, iterationTypes.returnType); + returnTypes = ts.append(returnTypes, iterationTypes.returnType); } return createIterationTypes(yieldType, getUnionType(returnTypes), nextType); @@ -38936,7 +38105,7 @@ namespace ts { * NOTE: You probably don't want to call this directly and should be calling * `getIterationTypesOfIterator` instead. */ - function getIterationTypesOfIteratorSlow(type: Type, resolver: IterationTypesResolver, errorNode: Node | undefined) { + function getIterationTypesOfIteratorSlow(type: ts.Type, resolver: IterationTypesResolver, errorNode: ts.Node | undefined) { const iterationTypes = combineIterationTypes([ getIterationTypesOfMethod(type, resolver, "next", errorNode), getIterationTypesOfMethod(type, resolver, "return", errorNode), @@ -38950,7 +38119,7 @@ namespace ts { * `IterableIterator`-like, or `Generator`-like (for a non-async generator); or `AsyncIterable`-like, * `AsyncIterator`-like, `AsyncIterableIterator`-like, or `AsyncGenerator`-like (for an async generator). */ - function getIterationTypeOfGeneratorFunctionReturnType(kind: IterationTypeKind, returnType: Type, isAsyncGenerator: boolean): Type | undefined { + function getIterationTypeOfGeneratorFunctionReturnType(kind: IterationTypeKind, returnType: ts.Type, isAsyncGenerator: boolean): ts.Type | undefined { if (isTypeAny(returnType)) { return undefined; } @@ -38959,7 +38128,7 @@ namespace ts { return iterationTypes && iterationTypes[getIterationTypesKeyFromIterationTypeKind(kind)]; } - function getIterationTypesOfGeneratorFunctionReturnType(type: Type, isAsyncGenerator: boolean) { + function getIterationTypesOfGeneratorFunctionReturnType(type: ts.Type, isAsyncGenerator: boolean) { if (isTypeAny(type)) { return anyIterationTypes; } @@ -38970,62 +38139,63 @@ namespace ts { getIterationTypesOfIterator(type, resolver, /*errorNode*/ undefined); } - function checkBreakOrContinueStatement(node: BreakOrContinueStatement) { + function checkBreakOrContinueStatement(node: ts.BreakOrContinueStatement) { // Grammar checking - if (!checkGrammarStatementInAmbientContext(node)) checkGrammarBreakOrContinueStatement(node); + if (!checkGrammarStatementInAmbientContext(node)) + checkGrammarBreakOrContinueStatement(node); // TODO: Check that target label is valid } - function unwrapReturnType(returnType: Type, functionFlags: FunctionFlags) { - const isGenerator = !!(functionFlags & FunctionFlags.Generator); - const isAsync = !!(functionFlags & FunctionFlags.Async); + function unwrapReturnType(returnType: ts.Type, functionFlags: ts.FunctionFlags) { + const isGenerator = !!(functionFlags & ts.FunctionFlags.Generator); + const isAsync = !!(functionFlags & ts.FunctionFlags.Async); return isGenerator ? getIterationTypeOfGeneratorFunctionReturnType(IterationTypeKind.Return, returnType, isAsync) || errorType : isAsync ? getAwaitedTypeNoAlias(returnType) || errorType : returnType; } - function isUnwrappedReturnTypeVoidOrAny(func: SignatureDeclaration, returnType: Type): boolean { - const unwrappedReturnType = unwrapReturnType(returnType, getFunctionFlags(func)); - return !!unwrappedReturnType && maybeTypeOfKind(unwrappedReturnType, TypeFlags.Void | TypeFlags.AnyOrUnknown); + function isUnwrappedReturnTypeVoidOrAny(func: ts.SignatureDeclaration, returnType: ts.Type): boolean { + const unwrappedReturnType = unwrapReturnType(returnType, ts.getFunctionFlags(func)); + return !!unwrappedReturnType && maybeTypeOfKind(unwrappedReturnType, ts.TypeFlags.Void | ts.TypeFlags.AnyOrUnknown); } - function checkReturnStatement(node: ReturnStatement) { + function checkReturnStatement(node: ts.ReturnStatement) { // Grammar checking if (checkGrammarStatementInAmbientContext(node)) { return; } - const container = getContainingFunctionOrClassStaticBlock(node); - if(container && isClassStaticBlockDeclaration(container)) { - grammarErrorOnFirstToken(node, Diagnostics.A_return_statement_cannot_be_used_inside_a_class_static_block); + const container = ts.getContainingFunctionOrClassStaticBlock(node); + if (container && ts.isClassStaticBlockDeclaration(container)) { + grammarErrorOnFirstToken(node, ts.Diagnostics.A_return_statement_cannot_be_used_inside_a_class_static_block); return; } if (!container) { - grammarErrorOnFirstToken(node, Diagnostics.A_return_statement_can_only_be_used_within_a_function_body); + grammarErrorOnFirstToken(node, ts.Diagnostics.A_return_statement_can_only_be_used_within_a_function_body); return; } const signature = getSignatureFromDeclaration(container); const returnType = getReturnTypeOfSignature(signature); - const functionFlags = getFunctionFlags(container); - if (strictNullChecks || node.expression || returnType.flags & TypeFlags.Never) { + const functionFlags = ts.getFunctionFlags(container); + if (strictNullChecks || node.expression || returnType.flags & ts.TypeFlags.Never) { const exprType = node.expression ? checkExpressionCached(node.expression) : undefinedType; - if (container.kind === SyntaxKind.SetAccessor) { + if (container.kind === ts.SyntaxKind.SetAccessor) { if (node.expression) { - error(node, Diagnostics.Setters_cannot_return_a_value); + error(node, ts.Diagnostics.Setters_cannot_return_a_value); } } - else if (container.kind === SyntaxKind.Constructor) { + else if (container.kind === ts.SyntaxKind.Constructor) { if (node.expression && !checkTypeAssignableToAndOptionallyElaborate(exprType, returnType, node, node.expression)) { - error(node, Diagnostics.Return_type_of_constructor_signature_must_be_assignable_to_the_instance_type_of_the_class); + error(node, ts.Diagnostics.Return_type_of_constructor_signature_must_be_assignable_to_the_instance_type_of_the_class); } } else if (getReturnTypeFromAnnotation(container)) { const unwrappedReturnType = unwrapReturnType(returnType, functionFlags) ?? returnType; - const unwrappedExprType = functionFlags & FunctionFlags.Async - ? checkAwaitedType(exprType, /*withAlias*/ false, node, Diagnostics.The_return_type_of_an_async_function_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member) + const unwrappedExprType = functionFlags & ts.FunctionFlags.Async + ? checkAwaitedType(exprType, /*withAlias*/ false, node, ts.Diagnostics.The_return_type_of_an_async_function_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member) : exprType; if (unwrappedReturnType) { // If the function has a return type, but promisedType is @@ -39035,60 +38205,60 @@ namespace ts { } } } - else if (container.kind !== SyntaxKind.Constructor && compilerOptions.noImplicitReturns && !isUnwrappedReturnTypeVoidOrAny(container, returnType)) { + else if (container.kind !== ts.SyntaxKind.Constructor && compilerOptions.noImplicitReturns && !isUnwrappedReturnTypeVoidOrAny(container, returnType)) { // The function has a return type, but the return statement doesn't have an expression. - error(node, Diagnostics.Not_all_code_paths_return_a_value); + error(node, ts.Diagnostics.Not_all_code_paths_return_a_value); } } - function checkWithStatement(node: WithStatement) { + function checkWithStatement(node: ts.WithStatement) { // Grammar checking for withStatement if (!checkGrammarStatementInAmbientContext(node)) { - if (node.flags & NodeFlags.AwaitContext) { - grammarErrorOnFirstToken(node, Diagnostics.with_statements_are_not_allowed_in_an_async_function_block); + if (node.flags & ts.NodeFlags.AwaitContext) { + grammarErrorOnFirstToken(node, ts.Diagnostics.with_statements_are_not_allowed_in_an_async_function_block); } } checkExpression(node.expression); - const sourceFile = getSourceFileOfNode(node); + const sourceFile = ts.getSourceFileOfNode(node); if (!hasParseDiagnostics(sourceFile)) { - const start = getSpanOfTokenAtPosition(sourceFile, node.pos).start; + const start = ts.getSpanOfTokenAtPosition(sourceFile, node.pos).start; const end = node.statement.pos; - grammarErrorAtPos(sourceFile, start, end - start, Diagnostics.The_with_statement_is_not_supported_All_symbols_in_a_with_block_will_have_type_any); + grammarErrorAtPos(sourceFile, start, end - start, ts.Diagnostics.The_with_statement_is_not_supported_All_symbols_in_a_with_block_will_have_type_any); } } - function checkSwitchStatement(node: SwitchStatement) { + function checkSwitchStatement(node: ts.SwitchStatement) { // Grammar checking checkGrammarStatementInAmbientContext(node); - let firstDefaultClause: CaseOrDefaultClause; + let firstDefaultClause: ts.CaseOrDefaultClause; let hasDuplicateDefaultClause = false; const expressionType = checkExpression(node.expression); const expressionIsLiteral = isLiteralType(expressionType); - forEach(node.caseBlock.clauses, clause => { + ts.forEach(node.caseBlock.clauses, clause => { // Grammar check for duplicate default clauses, skip if we already report duplicate default clause - if (clause.kind === SyntaxKind.DefaultClause && !hasDuplicateDefaultClause) { + if (clause.kind === ts.SyntaxKind.DefaultClause && !hasDuplicateDefaultClause) { if (firstDefaultClause === undefined) { firstDefaultClause = clause; } else { - grammarErrorOnNode(clause, Diagnostics.A_default_clause_cannot_appear_more_than_once_in_a_switch_statement); + grammarErrorOnNode(clause, ts.Diagnostics.A_default_clause_cannot_appear_more_than_once_in_a_switch_statement); hasDuplicateDefaultClause = true; } } - if (clause.kind === SyntaxKind.CaseClause) { + if (clause.kind === ts.SyntaxKind.CaseClause) { addLazyDiagnostic(createLazyCaseClauseDiagnostics(clause)); } - forEach(clause.statements, checkSourceElement); + ts.forEach(clause.statements, checkSourceElement); if (compilerOptions.noFallthroughCasesInSwitch && clause.fallthroughFlowNode && isReachableFlowNode(clause.fallthroughFlowNode)) { - error(clause, Diagnostics.Fallthrough_case_in_switch); + error(clause, ts.Diagnostics.Fallthrough_case_in_switch); } - function createLazyCaseClauseDiagnostics(clause: CaseClause) { + function createLazyCaseClauseDiagnostics(clause: ts.CaseClause) { return () => { // TypeScript 1.0 spec (April 2014): 5.9 // In a 'switch' statement, each 'case' expression must be of a type that is comparable @@ -39112,15 +38282,15 @@ namespace ts { } } - function checkLabeledStatement(node: LabeledStatement) { + function checkLabeledStatement(node: ts.LabeledStatement) { // Grammar checking if (!checkGrammarStatementInAmbientContext(node)) { - findAncestor(node.parent, current => { - if (isFunctionLike(current)) { + ts.findAncestor(node.parent, current => { + if (ts.isFunctionLike(current)) { return "quit"; } - if (current.kind === SyntaxKind.LabeledStatement && (current as LabeledStatement).label.escapedText === node.label.escapedText) { - grammarErrorOnNode(node.label, Diagnostics.Duplicate_label_0, getTextOfNode(node.label)); + if (current.kind === ts.SyntaxKind.LabeledStatement && (current as ts.LabeledStatement).label.escapedText === node.label.escapedText) { + grammarErrorOnNode(node.label, ts.Diagnostics.Duplicate_label_0, ts.getTextOfNode(node.label)); return true; } return false; @@ -39131,11 +38301,11 @@ namespace ts { checkSourceElement(node.statement); } - function checkThrowStatement(node: ThrowStatement) { + function checkThrowStatement(node: ts.ThrowStatement) { // Grammar checking if (!checkGrammarStatementInAmbientContext(node)) { - if (isIdentifier(node.expression) && !node.expression.escapedText) { - grammarErrorAfterFirstToken(node, Diagnostics.Line_break_not_permitted_here); + if (ts.isIdentifier(node.expression) && !node.expression.escapedText) { + grammarErrorAfterFirstToken(node, ts.Diagnostics.Line_break_not_permitted_here); } } @@ -39144,7 +38314,7 @@ namespace ts { } } - function checkTryStatement(node: TryStatement) { + function checkTryStatement(node: ts.TryStatement) { // Grammar checking checkGrammarStatementInAmbientContext(node); @@ -39154,23 +38324,23 @@ namespace ts { // Grammar checking if (catchClause.variableDeclaration) { const declaration = catchClause.variableDeclaration; - const typeNode = getEffectiveTypeAnnotationNode(getRootDeclaration(declaration)); + const typeNode = ts.getEffectiveTypeAnnotationNode(ts.getRootDeclaration(declaration)); if (typeNode) { const type = getTypeForVariableLikeDeclaration(declaration, /*includeOptionality*/ false, CheckMode.Normal); - if (type && !(type.flags & TypeFlags.AnyOrUnknown)) { - grammarErrorOnFirstToken(typeNode, Diagnostics.Catch_clause_variable_type_annotation_must_be_any_or_unknown_if_specified); + if (type && !(type.flags & ts.TypeFlags.AnyOrUnknown)) { + grammarErrorOnFirstToken(typeNode, ts.Diagnostics.Catch_clause_variable_type_annotation_must_be_any_or_unknown_if_specified); } } else if (declaration.initializer) { - grammarErrorOnFirstToken(declaration.initializer, Diagnostics.Catch_clause_variable_cannot_have_an_initializer); + grammarErrorOnFirstToken(declaration.initializer, ts.Diagnostics.Catch_clause_variable_cannot_have_an_initializer); } else { const blockLocals = catchClause.block.locals; if (blockLocals) { - forEachKey(catchClause.locals!, caughtName => { + ts.forEachKey(catchClause.locals!, caughtName => { const blockLocal = blockLocals.get(caughtName); - if (blockLocal?.valueDeclaration && (blockLocal.flags & SymbolFlags.BlockScopedVariable) !== 0) { - grammarErrorOnNode(blockLocal.valueDeclaration, Diagnostics.Cannot_redeclare_identifier_0_in_catch_clause, caughtName); + if (blockLocal?.valueDeclaration && (blockLocal.flags & ts.SymbolFlags.BlockScopedVariable) !== 0) { + grammarErrorOnNode(blockLocal.valueDeclaration, ts.Diagnostics.Cannot_redeclare_identifier_0_in_catch_clause, caughtName); } }); } @@ -39185,24 +38355,24 @@ namespace ts { } } - function checkIndexConstraints(type: Type, symbol: Symbol, isStaticIndex?: boolean) { + function checkIndexConstraints(type: ts.Type, symbol: ts.Symbol, isStaticIndex?: boolean) { const indexInfos = getIndexInfosOfType(type); if (indexInfos.length === 0) { return; } for (const prop of getPropertiesOfObjectType(type)) { - if (!(isStaticIndex && prop.flags & SymbolFlags.Prototype)) { - checkIndexConstraintForProperty(type, prop, getLiteralTypeFromProperty(prop, TypeFlags.StringOrNumberLiteralOrUnique, /*includeNonPublic*/ true), getNonMissingTypeOfSymbol(prop)); + if (!(isStaticIndex && prop.flags & ts.SymbolFlags.Prototype)) { + checkIndexConstraintForProperty(type, prop, getLiteralTypeFromProperty(prop, ts.TypeFlags.StringOrNumberLiteralOrUnique, /*includeNonPublic*/ true), getNonMissingTypeOfSymbol(prop)); } } const typeDeclaration = symbol.valueDeclaration; - if (typeDeclaration && isClassLike(typeDeclaration)) { + if (typeDeclaration && ts.isClassLike(typeDeclaration)) { for (const member of typeDeclaration.members) { // Only process instance properties with computed names here. Static properties cannot be in conflict with indexers, // and properties with literal names were already checked. - if (!isStatic(member) && !hasBindableName(member)) { + if (!ts.isStatic(member) && !hasBindableName(member)) { const symbol = getSymbolOfNode(member); - checkIndexConstraintForProperty(type, symbol, getTypeOfExpression((member as DynamicNamedDeclaration).name.expression), getNonMissingTypeOfSymbol(symbol)); + checkIndexConstraintForProperty(type, symbol, getTypeOfExpression((member as ts.DynamicNamedDeclaration).name.expression), getNonMissingTypeOfSymbol(symbol)); } } } @@ -39213,51 +38383,50 @@ namespace ts { } } - function checkIndexConstraintForProperty(type: Type, prop: Symbol, propNameType: Type, propType: Type) { + function checkIndexConstraintForProperty(type: ts.Type, prop: ts.Symbol, propNameType: ts.Type, propType: ts.Type) { const declaration = prop.valueDeclaration; - const name = getNameOfDeclaration(declaration); - if (name && isPrivateIdentifier(name)) { + const name = ts.getNameOfDeclaration(declaration); + if (name && ts.isPrivateIdentifier(name)) { return; } const indexInfos = getApplicableIndexInfos(type, propNameType); - const interfaceDeclaration = getObjectFlags(type) & ObjectFlags.Interface ? getDeclarationOfKind(type.symbol, SyntaxKind.InterfaceDeclaration) : undefined; - const localPropDeclaration = declaration && declaration.kind === SyntaxKind.BinaryExpression || - name && name.kind === SyntaxKind.ComputedPropertyName || getParentOfSymbol(prop) === type.symbol ? declaration : undefined; + const interfaceDeclaration = ts.getObjectFlags(type) & ts.ObjectFlags.Interface ? ts.getDeclarationOfKind(type.symbol, ts.SyntaxKind.InterfaceDeclaration) : undefined; + const localPropDeclaration = declaration && declaration.kind === ts.SyntaxKind.BinaryExpression || + name && name.kind === ts.SyntaxKind.ComputedPropertyName || getParentOfSymbol(prop) === type.symbol ? declaration : undefined; for (const info of indexInfos) { const localIndexDeclaration = info.declaration && getParentOfSymbol(getSymbolOfNode(info.declaration)) === type.symbol ? info.declaration : undefined; // We check only when (a) the property is declared in the containing type, or (b) the applicable index signature is declared // in the containing type, or (c) the containing type is an interface and no base interface contains both the property and // the index signature (i.e. property and index signature are declared in separate inherited interfaces). const errorNode = localPropDeclaration || localIndexDeclaration || - (interfaceDeclaration && !some(getBaseTypes(type as InterfaceType), base => !!getPropertyOfObjectType(base, prop.escapedName) && !!getIndexTypeOfType(base, info.keyType)) ? interfaceDeclaration : undefined); + (interfaceDeclaration && !ts.some(getBaseTypes(type as ts.InterfaceType), base => !!getPropertyOfObjectType(base, prop.escapedName) && !!getIndexTypeOfType(base, info.keyType)) ? interfaceDeclaration : undefined); if (errorNode && !isTypeAssignableTo(propType, info.type)) { - error(errorNode, Diagnostics.Property_0_of_type_1_is_not_assignable_to_2_index_type_3, - symbolToString(prop), typeToString(propType), typeToString(info.keyType), typeToString(info.type)); + error(errorNode, ts.Diagnostics.Property_0_of_type_1_is_not_assignable_to_2_index_type_3, symbolToString(prop), typeToString(propType), typeToString(info.keyType), typeToString(info.type)); } } } - function checkIndexConstraintForIndexSignature(type: Type, checkInfo: IndexInfo) { + function checkIndexConstraintForIndexSignature(type: ts.Type, checkInfo: ts.IndexInfo) { const declaration = checkInfo.declaration; const indexInfos = getApplicableIndexInfos(type, checkInfo.keyType); - const interfaceDeclaration = getObjectFlags(type) & ObjectFlags.Interface ? getDeclarationOfKind(type.symbol, SyntaxKind.InterfaceDeclaration) : undefined; + const interfaceDeclaration = ts.getObjectFlags(type) & ts.ObjectFlags.Interface ? ts.getDeclarationOfKind(type.symbol, ts.SyntaxKind.InterfaceDeclaration) : undefined; const localCheckDeclaration = declaration && getParentOfSymbol(getSymbolOfNode(declaration)) === type.symbol ? declaration : undefined; for (const info of indexInfos) { - if (info === checkInfo) continue; + if (info === checkInfo) + continue; const localIndexDeclaration = info.declaration && getParentOfSymbol(getSymbolOfNode(info.declaration)) === type.symbol ? info.declaration : undefined; // We check only when (a) the check index signature is declared in the containing type, or (b) the applicable index // signature is declared in the containing type, or (c) the containing type is an interface and no base interface contains // both index signatures (i.e. the index signatures are declared in separate inherited interfaces). const errorNode = localCheckDeclaration || localIndexDeclaration || - (interfaceDeclaration && !some(getBaseTypes(type as InterfaceType), base => !!getIndexInfoOfType(base, checkInfo.keyType) && !!getIndexTypeOfType(base, info.keyType)) ? interfaceDeclaration : undefined); + (interfaceDeclaration && !ts.some(getBaseTypes(type as ts.InterfaceType), base => !!getIndexInfoOfType(base, checkInfo.keyType) && !!getIndexTypeOfType(base, info.keyType)) ? interfaceDeclaration : undefined); if (errorNode && !isTypeAssignableTo(checkInfo.type, info.type)) { - error(errorNode, Diagnostics._0_index_type_1_is_not_assignable_to_2_index_type_3, - typeToString(checkInfo.keyType), typeToString(checkInfo.type), typeToString(info.keyType), typeToString(info.type)); + error(errorNode, ts.Diagnostics._0_index_type_1_is_not_assignable_to_2_index_type_3, typeToString(checkInfo.keyType), typeToString(checkInfo.type), typeToString(info.keyType), typeToString(info.type)); } } } - function checkTypeNameIsReserved(name: Identifier, message: DiagnosticMessage): void { + function checkTypeNameIsReserved(name: ts.Identifier, message: ts.DiagnosticMessage): void { // TS 1.0 spec (April 2014): 3.6.1 // The predefined type keywords are reserved and cannot be used as names of user defined types. switch (name.escapedText) { @@ -39278,49 +38447,49 @@ namespace ts { /** * The name cannot be used as 'Object' of user defined types with special target. */ - function checkClassNameCollisionWithObject(name: Identifier): void { - if (languageVersion >= ScriptTarget.ES5 && name.escapedText === "Object" - && (moduleKind < ModuleKind.ES2015 || getSourceFileOfNode(name).impliedNodeFormat === ModuleKind.CommonJS)) { - error(name, Diagnostics.Class_name_cannot_be_Object_when_targeting_ES5_with_module_0, ModuleKind[moduleKind]); // https://github.com/Microsoft/TypeScript/issues/17494 + function checkClassNameCollisionWithObject(name: ts.Identifier): void { + if (languageVersion >= ts.ScriptTarget.ES5 && name.escapedText === "Object" + && (moduleKind < ts.ModuleKind.ES2015 || ts.getSourceFileOfNode(name).impliedNodeFormat === ts.ModuleKind.CommonJS)) { + error(name, ts.Diagnostics.Class_name_cannot_be_Object_when_targeting_ES5_with_module_0, ts.ModuleKind[moduleKind]); // https://github.com/Microsoft/TypeScript/issues/17494 } } - function checkUnmatchedJSDocParameters(node: SignatureDeclaration) { - const jsdocParameters = filter(getJSDocTags(node), isJSDocParameterTag); - if (!length(jsdocParameters)) return; - - const isJs = isInJSFile(node); - const parameters = new Set<__String>(); - const excludedParameters = new Set(); - forEach(node.parameters, ({ name }, index) => { - if (isIdentifier(name)) { + function checkUnmatchedJSDocParameters(node: ts.SignatureDeclaration) { + const jsdocParameters = ts.filter(ts.getJSDocTags(node), ts.isJSDocParameterTag); + if (!ts.length(jsdocParameters)) + return; + const isJs = ts.isInJSFile(node); + const parameters = new ts.Set(); + const excludedParameters = new ts.Set(); + ts.forEach(node.parameters, ({ name }, index) => { + if (ts.isIdentifier(name)) { parameters.add(name.escapedText); } - if (isBindingPattern(name)) { + if (ts.isBindingPattern(name)) { excludedParameters.add(index); } }); const containsArguments = containsArgumentsReference(node); if (containsArguments) { - const lastJSDocParam = lastOrUndefined(jsdocParameters); - if (isJs && lastJSDocParam && isIdentifier(lastJSDocParam.name) && lastJSDocParam.typeExpression && + const lastJSDocParam = ts.lastOrUndefined(jsdocParameters); + if (isJs && lastJSDocParam && ts.isIdentifier(lastJSDocParam.name) && lastJSDocParam.typeExpression && lastJSDocParam.typeExpression.type && !parameters.has(lastJSDocParam.name.escapedText) && !isArrayType(getTypeFromTypeNode(lastJSDocParam.typeExpression.type))) { - error(lastJSDocParam.name, Diagnostics.JSDoc_param_tag_has_name_0_but_there_is_no_parameter_with_that_name_It_would_match_arguments_if_it_had_an_array_type, idText(lastJSDocParam.name)); + error(lastJSDocParam.name, ts.Diagnostics.JSDoc_param_tag_has_name_0_but_there_is_no_parameter_with_that_name_It_would_match_arguments_if_it_had_an_array_type, ts.idText(lastJSDocParam.name)); } } else { - forEach(jsdocParameters, ({ name }, index) => { - if (excludedParameters.has(index) || isIdentifier(name) && parameters.has(name.escapedText)) { + ts.forEach(jsdocParameters, ({ name }, index) => { + if (excludedParameters.has(index) || ts.isIdentifier(name) && parameters.has(name.escapedText)) { return; } - if (isQualifiedName(name)) { + if (ts.isQualifiedName(name)) { if (isJs) { - error(name, Diagnostics.Qualified_name_0_is_not_allowed_without_a_leading_param_object_1, entityNameToString(name), entityNameToString(name.left)); + error(name, ts.Diagnostics.Qualified_name_0_is_not_allowed_without_a_leading_param_object_1, ts.entityNameToString(name), ts.entityNameToString(name.left)); } } else { - errorOrSuggestion(isJs, name, Diagnostics.JSDoc_param_tag_has_name_0_but_there_is_no_parameter_with_that_name, idText(name)); + errorOrSuggestion(isJs, name, ts.Diagnostics.JSDoc_param_tag_has_name_0_but_there_is_no_parameter_with_that_name, ts.idText(name)); } }); } @@ -39329,7 +38498,7 @@ namespace ts { /** * Check each type parameter and check that type parameters have no duplicate type parameter declarations */ - function checkTypeParameters(typeParameterDeclarations: readonly TypeParameterDeclaration[] | undefined) { + function checkTypeParameters(typeParameterDeclarations: readonly ts.TypeParameterDeclaration[] | undefined) { let seenDefault = false; if (typeParameterDeclarations) { for (let i = 0; i < typeParameterDeclarations.length; i++) { @@ -39340,18 +38509,18 @@ namespace ts { } } - function createCheckTypeParameterDiagnostic(node: TypeParameterDeclaration, i: number) { + function createCheckTypeParameterDiagnostic(node: ts.TypeParameterDeclaration, i: number) { return () => { if (node.default) { seenDefault = true; checkTypeParametersNotReferenced(node.default, typeParameterDeclarations!, i); } else if (seenDefault) { - error(node, Diagnostics.Required_type_parameters_may_not_follow_optional_type_parameters); + error(node, ts.Diagnostics.Required_type_parameters_may_not_follow_optional_type_parameters); } for (let j = 0; j < i; j++) { if (typeParameterDeclarations![j].symbol === node.symbol) { - error(node.name, Diagnostics.Duplicate_identifier_0, declarationNameToString(node.name)); + error(node.name, ts.Diagnostics.Duplicate_identifier_0, ts.declarationNameToString(node.name)); } } }; @@ -39359,25 +38528,25 @@ namespace ts { } /** Check that type parameter defaults only reference previously declared type parameters */ - function checkTypeParametersNotReferenced(root: TypeNode, typeParameters: readonly TypeParameterDeclaration[], index: number) { + function checkTypeParametersNotReferenced(root: ts.TypeNode, typeParameters: readonly ts.TypeParameterDeclaration[], index: number) { visit(root); - function visit(node: Node) { - if (node.kind === SyntaxKind.TypeReference) { - const type = getTypeFromTypeReference(node as TypeReferenceNode); - if (type.flags & TypeFlags.TypeParameter) { + function visit(node: ts.Node) { + if (node.kind === ts.SyntaxKind.TypeReference) { + const type = getTypeFromTypeReference(node as ts.TypeReferenceNode); + if (type.flags & ts.TypeFlags.TypeParameter) { for (let i = index; i < typeParameters.length; i++) { if (type.symbol === getSymbolOfNode(typeParameters[i])) { - error(node, Diagnostics.Type_parameter_defaults_can_only_reference_previously_declared_type_parameters); + error(node, ts.Diagnostics.Type_parameter_defaults_can_only_reference_previously_declared_type_parameters); } } } } - forEachChild(node, visit); + ts.forEachChild(node, visit); } } /** Check that type parameter lists are identical across multiple declarations */ - function checkTypeParameterListsIdentical(symbol: Symbol) { + function checkTypeParameterListsIdentical(symbol: ts.Symbol) { if (symbol.declarations && symbol.declarations.length === 1) { return; } @@ -39390,19 +38559,19 @@ namespace ts { return; } - const type = getDeclaredTypeOfSymbol(symbol) as InterfaceType; - if (!areTypeParametersIdentical(declarations, type.localTypeParameters!, getEffectiveTypeParameterDeclarations)) { + const type = getDeclaredTypeOfSymbol(symbol) as ts.InterfaceType; + if (!areTypeParametersIdentical(declarations, type.localTypeParameters!, ts.getEffectiveTypeParameterDeclarations)) { // Report an error on every conflicting declaration. const name = symbolToString(symbol); for (const declaration of declarations) { - error(declaration.name, Diagnostics.All_declarations_of_0_must_have_identical_type_parameters, name); + error(declaration.name, ts.Diagnostics.All_declarations_of_0_must_have_identical_type_parameters, name); } } } } - function areTypeParametersIdentical(declarations: readonly T[], targetParameters: TypeParameter[], getTypeParameterDeclarations: (node: T) => readonly TypeParameterDeclaration[]) { - const maxTypeArgumentCount = length(targetParameters); + function areTypeParametersIdentical(declarations: readonly T[], targetParameters: ts.TypeParameter[], getTypeParameterDeclarations: (node: T) => readonly ts.TypeParameterDeclaration[]) { + const maxTypeArgumentCount = ts.length(targetParameters); const minTypeArgumentCount = getMinTypeArgumentCount(targetParameters); for (const declaration of declarations) { @@ -39425,7 +38594,7 @@ namespace ts { // If the type parameter node does not have an identical constraint as the resolved // type parameter at this position, we report an error. - const constraint = getEffectiveConstraintOfTypeParameter(source); + const constraint = ts.getEffectiveConstraintOfTypeParameter(source); const sourceConstraint = constraint && getTypeFromTypeNode(constraint); const targetConstraint = getConstraintOfTypeParameter(target); // relax check if later interface augmentation has no constraint, it's more broad and is OK to merge with @@ -39447,58 +38616,58 @@ namespace ts { return true; } - function checkClassExpression(node: ClassExpression): Type { + function checkClassExpression(node: ts.ClassExpression): ts.Type { checkClassLikeDeclaration(node); checkNodeDeferred(node); return getTypeOfSymbol(getSymbolOfNode(node)); } - function checkClassExpressionDeferred(node: ClassExpression) { - forEach(node.members, checkSourceElement); + function checkClassExpressionDeferred(node: ts.ClassExpression) { + ts.forEach(node.members, checkSourceElement); registerForUnusedIdentifiersCheck(node); } - function checkClassDeclaration(node: ClassDeclaration) { - if (some(node.decorators) && some(node.members, p => hasStaticModifier(p) && isPrivateIdentifierClassElementDeclaration(p))) { - grammarErrorOnNode(node.decorators[0], Diagnostics.Class_decorators_can_t_be_used_with_static_private_identifier_Consider_removing_the_experimental_decorator); + function checkClassDeclaration(node: ts.ClassDeclaration) { + if (ts.some(node.decorators) && ts.some(node.members, p => ts.hasStaticModifier(p) && ts.isPrivateIdentifierClassElementDeclaration(p))) { + grammarErrorOnNode(node.decorators[0], ts.Diagnostics.Class_decorators_can_t_be_used_with_static_private_identifier_Consider_removing_the_experimental_decorator); } - if (!node.name && !hasSyntacticModifier(node, ModifierFlags.Default)) { - grammarErrorOnFirstToken(node, Diagnostics.A_class_declaration_without_the_default_modifier_must_have_a_name); + if (!node.name && !ts.hasSyntacticModifier(node, ts.ModifierFlags.Default)) { + grammarErrorOnFirstToken(node, ts.Diagnostics.A_class_declaration_without_the_default_modifier_must_have_a_name); } checkClassLikeDeclaration(node); - forEach(node.members, checkSourceElement); + ts.forEach(node.members, checkSourceElement); registerForUnusedIdentifiersCheck(node); } - function checkClassLikeDeclaration(node: ClassLikeDeclaration) { + function checkClassLikeDeclaration(node: ts.ClassLikeDeclaration) { checkGrammarClassLikeDeclaration(node); checkDecorators(node); checkCollisionsForDeclarationName(node, node.name); - checkTypeParameters(getEffectiveTypeParameterDeclarations(node)); + checkTypeParameters(ts.getEffectiveTypeParameterDeclarations(node)); checkExportsOnMergedDeclarations(node); const symbol = getSymbolOfNode(node); - const type = getDeclaredTypeOfSymbol(symbol) as InterfaceType; + const type = getDeclaredTypeOfSymbol(symbol) as ts.InterfaceType; const typeWithThis = getTypeWithThisArgument(type); - const staticType = getTypeOfSymbol(symbol) as ObjectType; + const staticType = getTypeOfSymbol(symbol) as ts.ObjectType; checkTypeParameterListsIdentical(symbol); checkFunctionOrConstructorSymbol(symbol); checkClassForDuplicateDeclarations(node); // Only check for reserved static identifiers on non-ambient context. - const nodeInAmbientContext = !!(node.flags & NodeFlags.Ambient); + const nodeInAmbientContext = !!(node.flags & ts.NodeFlags.Ambient); if (!nodeInAmbientContext) { checkClassForStaticPropertyNameConflicts(node); } - const baseTypeNode = getEffectiveBaseTypeNode(node); + const baseTypeNode = ts.getEffectiveBaseTypeNode(node); if (baseTypeNode) { - forEach(baseTypeNode.typeArguments, checkSourceElement); - if (languageVersion < ScriptTarget.ES2015) { - checkExternalEmitHelpers(baseTypeNode.parent, ExternalEmitHelpers.Extends); + ts.forEach(baseTypeNode.typeArguments, checkSourceElement); + if (languageVersion < ts.ScriptTarget.ES2015) { + checkExternalEmitHelpers(baseTypeNode.parent, ts.ExternalEmitHelpers.Extends); } // check both @extends and extends if both are specified. - const extendsNode = getClassExtendsHeritageElement(node); + const extendsNode = ts.getClassExtendsHeritageElement(node); if (extendsNode && extendsNode !== baseTypeNode) { checkExpression(extendsNode.expression); } @@ -39511,8 +38680,8 @@ namespace ts { const staticBaseType = getApparentType(baseConstructorType); checkBaseTypeAccessibility(staticBaseType, baseTypeNode); checkSourceElement(baseTypeNode.expression); - if (some(baseTypeNode.typeArguments)) { - forEach(baseTypeNode.typeArguments, checkSourceElement); + if (ts.some(baseTypeNode.typeArguments)) { + ts.forEach(baseTypeNode.typeArguments, checkSourceElement); for (const constructor of getConstructorsForTypeArguments(staticBaseType, baseTypeNode.typeArguments, baseTypeNode)) { if (!checkTypeArgumentConstraints(baseTypeNode, constructor.typeParameters!)) { break; @@ -39521,31 +38690,30 @@ namespace ts { } const baseWithThis = getTypeWithThisArgument(baseType, type.thisType); if (!checkTypeAssignableTo(typeWithThis, baseWithThis, /*errorNode*/ undefined)) { - issueMemberSpecificError(node, typeWithThis, baseWithThis, Diagnostics.Class_0_incorrectly_extends_base_class_1); + issueMemberSpecificError(node, typeWithThis, baseWithThis, ts.Diagnostics.Class_0_incorrectly_extends_base_class_1); } else { // Report static side error only when instance type is assignable - checkTypeAssignableTo(staticType, getTypeWithoutSignatures(staticBaseType), node.name || node, - Diagnostics.Class_static_side_0_incorrectly_extends_base_class_static_side_1); + checkTypeAssignableTo(staticType, getTypeWithoutSignatures(staticBaseType), node.name || node, ts.Diagnostics.Class_static_side_0_incorrectly_extends_base_class_static_side_1); } - if (baseConstructorType.flags & TypeFlags.TypeVariable) { + if (baseConstructorType.flags & ts.TypeFlags.TypeVariable) { if (!isMixinConstructorType(staticType)) { - error(node.name || node, Diagnostics.A_mixin_class_must_have_a_constructor_with_a_single_rest_parameter_of_type_any); + error(node.name || node, ts.Diagnostics.A_mixin_class_must_have_a_constructor_with_a_single_rest_parameter_of_type_any); } else { - const constructSignatures = getSignaturesOfType(baseConstructorType, SignatureKind.Construct); - if (constructSignatures.some(signature => signature.flags & SignatureFlags.Abstract) && !hasSyntacticModifier(node, ModifierFlags.Abstract)) { - error(node.name || node, Diagnostics.A_mixin_class_that_extends_from_a_type_variable_containing_an_abstract_construct_signature_must_also_be_declared_abstract); + const constructSignatures = getSignaturesOfType(baseConstructorType, ts.SignatureKind.Construct); + if (constructSignatures.some(signature => signature.flags & ts.SignatureFlags.Abstract) && !ts.hasSyntacticModifier(node, ts.ModifierFlags.Abstract)) { + error(node.name || node, ts.Diagnostics.A_mixin_class_that_extends_from_a_type_variable_containing_an_abstract_construct_signature_must_also_be_declared_abstract); } } } - if (!(staticBaseType.symbol && staticBaseType.symbol.flags & SymbolFlags.Class) && !(baseConstructorType.flags & TypeFlags.TypeVariable)) { + if (!(staticBaseType.symbol && staticBaseType.symbol.flags & ts.SymbolFlags.Class) && !(baseConstructorType.flags & ts.TypeFlags.TypeVariable)) { // When the static base type is a "class-like" constructor function (but not actually a class), we verify // that all instantiated base constructor signatures return the same type. const constructors = getInstantiatedConstructorsForTypeArguments(staticBaseType, baseTypeNode.typeArguments, baseTypeNode); - if (forEach(constructors, sig => !isJSConstructor(sig.declaration) && !isTypeIdenticalTo(getReturnTypeOfSignature(sig), baseType))) { - error(baseTypeNode.expression, Diagnostics.Base_constructors_must_all_have_the_same_return_type); + if (ts.forEach(constructors, sig => !isJSConstructor(sig.declaration) && !isTypeIdenticalTo(getReturnTypeOfSignature(sig), baseType))) { + error(baseTypeNode.expression, ts.Diagnostics.Base_constructors_must_all_have_the_same_return_type); } } checkKindsOfPropertyMemberOverrides(type, baseType); @@ -39555,11 +38723,11 @@ namespace ts { checkMembersForOverrideModifier(node, type, typeWithThis, staticType); - const implementedTypeNodes = getEffectiveImplementsTypeNodes(node); + const implementedTypeNodes = ts.getEffectiveImplementsTypeNodes(node); if (implementedTypeNodes) { for (const typeRefNode of implementedTypeNodes) { - if (!isEntityNameExpression(typeRefNode.expression) || isOptionalChain(typeRefNode.expression)) { - error(typeRefNode.expression, Diagnostics.A_class_can_only_implement_an_identifier_Slashqualified_name_with_optional_type_arguments); + if (!ts.isEntityNameExpression(typeRefNode.expression) || ts.isOptionalChain(typeRefNode.expression)) { + error(typeRefNode.expression, ts.Diagnostics.A_class_can_only_implement_an_identifier_Slashqualified_name_with_optional_type_arguments); } checkTypeReferenceNode(typeRefNode); addLazyDiagnostic(createImplementsDiagnostics(typeRefNode)); @@ -39573,64 +38741,48 @@ namespace ts { checkPropertyInitialization(node); }); - function createImplementsDiagnostics(typeRefNode: ExpressionWithTypeArguments) { + function createImplementsDiagnostics(typeRefNode: ts.ExpressionWithTypeArguments) { return () => { const t = getReducedType(getTypeFromTypeNode(typeRefNode)); if (!isErrorType(t)) { if (isValidBaseType(t)) { - const genericDiag = t.symbol && t.symbol.flags & SymbolFlags.Class ? - Diagnostics.Class_0_incorrectly_implements_class_1_Did_you_mean_to_extend_1_and_inherit_its_members_as_a_subclass : - Diagnostics.Class_0_incorrectly_implements_interface_1; + const genericDiag = t.symbol && t.symbol.flags & ts.SymbolFlags.Class ? + ts.Diagnostics.Class_0_incorrectly_implements_class_1_Did_you_mean_to_extend_1_and_inherit_its_members_as_a_subclass : + ts.Diagnostics.Class_0_incorrectly_implements_interface_1; const baseWithThis = getTypeWithThisArgument(t, type.thisType); if (!checkTypeAssignableTo(typeWithThis, baseWithThis, /*errorNode*/ undefined)) { issueMemberSpecificError(node, typeWithThis, baseWithThis, genericDiag); } } else { - error(typeRefNode, Diagnostics.A_class_can_only_implement_an_object_type_or_intersection_of_object_types_with_statically_known_members); + error(typeRefNode, ts.Diagnostics.A_class_can_only_implement_an_object_type_or_intersection_of_object_types_with_statically_known_members); } } }; } } - function checkMembersForOverrideModifier(node: ClassLikeDeclaration, type: InterfaceType, typeWithThis: Type, staticType: ObjectType) { - const baseTypeNode = getEffectiveBaseTypeNode(node); + function checkMembersForOverrideModifier(node: ts.ClassLikeDeclaration, type: ts.InterfaceType, typeWithThis: ts.Type, staticType: ts.ObjectType) { + const baseTypeNode = ts.getEffectiveBaseTypeNode(node); const baseTypes = baseTypeNode && getBaseTypes(type); - const baseWithThis = baseTypes?.length ? getTypeWithThisArgument(first(baseTypes), type.thisType) : undefined; + const baseWithThis = baseTypes?.length ? getTypeWithThisArgument(ts.first(baseTypes), type.thisType) : undefined; const baseStaticType = getBaseConstructorTypeOfClass(type); for (const member of node.members) { - if (hasAmbientModifier(member)) { + if (ts.hasAmbientModifier(member)) { continue; } - if (isConstructorDeclaration(member)) { - forEach(member.parameters, param => { - if (isParameterPropertyDeclaration(param, member)) { - checkExistingMemberForOverrideModifier( - node, - staticType, - baseStaticType, - baseWithThis, - type, - typeWithThis, - param, - /* memberIsParameterProperty */ true - ); + if (ts.isConstructorDeclaration(member)) { + ts.forEach(member.parameters, param => { + if (ts.isParameterPropertyDeclaration(param, member)) { + checkExistingMemberForOverrideModifier(node, staticType, baseStaticType, baseWithThis, type, typeWithThis, param, + /* memberIsParameterProperty */ true); } }); } - checkExistingMemberForOverrideModifier( - node, - staticType, - baseStaticType, - baseWithThis, - type, - typeWithThis, - member, - /* memberIsParameterProperty */ false, - ); + checkExistingMemberForOverrideModifier(node, staticType, baseStaticType, baseWithThis, type, typeWithThis, member, + /* memberIsParameterProperty */ false); } } @@ -39638,38 +38790,15 @@ namespace ts { * @param member Existing member node to be checked. * Note: `member` cannot be a synthetic node. */ - function checkExistingMemberForOverrideModifier( - node: ClassLikeDeclaration, - staticType: ObjectType, - baseStaticType: Type, - baseWithThis: Type | undefined, - type: InterfaceType, - typeWithThis: Type, - member: ClassElement | ParameterPropertyDeclaration, - memberIsParameterProperty: boolean, - reportErrors = true, - ): MemberOverrideStatus { + function checkExistingMemberForOverrideModifier(node: ts.ClassLikeDeclaration, staticType: ts.ObjectType, baseStaticType: ts.Type, baseWithThis: ts.Type | undefined, type: ts.InterfaceType, typeWithThis: ts.Type, member: ts.ClassElement | ts.ParameterPropertyDeclaration, memberIsParameterProperty: boolean, reportErrors = true): ts.MemberOverrideStatus { const declaredProp = member.name && getSymbolAtLocation(member.name) || getSymbolAtLocation(member); if (!declaredProp) { - return MemberOverrideStatus.Ok; + return ts.MemberOverrideStatus.Ok; } - return checkMemberForOverrideModifier( - node, - staticType, - baseStaticType, - baseWithThis, - type, - typeWithThis, - hasOverrideModifier(member), - hasAbstractModifier(member), - isStatic(member), - memberIsParameterProperty, - symbolName(declaredProp), - reportErrors ? member : undefined, - ); + return checkMemberForOverrideModifier(node, staticType, baseStaticType, baseWithThis, type, typeWithThis, ts.hasOverrideModifier(member), ts.hasAbstractModifier(member), ts.isStatic(member), memberIsParameterProperty, ts.symbolName(declaredProp), reportErrors ? member : undefined); } /** @@ -39680,24 +38809,11 @@ namespace ts { * when offering a method declaration as completion. * @param errorNode The node where we should report an error, or undefined if we should not report errors. */ - function checkMemberForOverrideModifier( - node: ClassLikeDeclaration, - staticType: ObjectType, - baseStaticType: Type, - baseWithThis: Type | undefined, - type: InterfaceType, - typeWithThis: Type, - memberHasOverrideModifier: boolean, - memberHasAbstractModifier: boolean, - memberIsStatic: boolean, - memberIsParameterProperty: boolean, - memberName: string, - errorNode?: Node, - ): MemberOverrideStatus { - const isJs = isInJSFile(node); - const nodeInAmbientContext = !!(node.flags & NodeFlags.Ambient); + function checkMemberForOverrideModifier(node: ts.ClassLikeDeclaration, staticType: ts.ObjectType, baseStaticType: ts.Type, baseWithThis: ts.Type | undefined, type: ts.InterfaceType, typeWithThis: ts.Type, memberHasOverrideModifier: boolean, memberHasAbstractModifier: boolean, memberIsStatic: boolean, memberIsParameterProperty: boolean, memberName: string, errorNode?: ts.Node): ts.MemberOverrideStatus { + const isJs = ts.isInJSFile(node); + const nodeInAmbientContext = !!(node.flags & ts.NodeFlags.Ambient); if (baseWithThis && (memberHasOverrideModifier || compilerOptions.noImplicitOverride)) { - const memberEscapedName = escapeLeadingUnderscores(memberName); + const memberEscapedName = ts.escapeLeadingUnderscores(memberName); const thisType = memberIsStatic ? staticType : typeWithThis; const baseType = memberIsStatic ? baseStaticType : baseWithThis; const prop = getPropertyOfType(thisType, memberEscapedName); @@ -39708,70 +38824,60 @@ namespace ts { if (errorNode) { const suggestion = getSuggestedSymbolForNonexistentClassMember(memberName, baseType); // Again, using symbol name: note that's different from `symbol.escapedName` suggestion ? - error( - errorNode, - isJs ? - Diagnostics.This_member_cannot_have_a_JSDoc_comment_with_an_override_tag_because_it_is_not_declared_in_the_base_class_0_Did_you_mean_1 : - Diagnostics.This_member_cannot_have_an_override_modifier_because_it_is_not_declared_in_the_base_class_0_Did_you_mean_1, - baseClassName, - symbolToString(suggestion)) : - error( - errorNode, - isJs ? - Diagnostics.This_member_cannot_have_a_JSDoc_comment_with_an_override_tag_because_it_is_not_declared_in_the_base_class_0 : - Diagnostics.This_member_cannot_have_an_override_modifier_because_it_is_not_declared_in_the_base_class_0, - baseClassName); + error(errorNode, isJs ? + ts.Diagnostics.This_member_cannot_have_a_JSDoc_comment_with_an_override_tag_because_it_is_not_declared_in_the_base_class_0_Did_you_mean_1 : + ts.Diagnostics.This_member_cannot_have_an_override_modifier_because_it_is_not_declared_in_the_base_class_0_Did_you_mean_1, baseClassName, symbolToString(suggestion)) : + error(errorNode, isJs ? + ts.Diagnostics.This_member_cannot_have_a_JSDoc_comment_with_an_override_tag_because_it_is_not_declared_in_the_base_class_0 : + ts.Diagnostics.This_member_cannot_have_an_override_modifier_because_it_is_not_declared_in_the_base_class_0, baseClassName); } - return MemberOverrideStatus.HasInvalidOverride; + return ts.MemberOverrideStatus.HasInvalidOverride; } else if (prop && baseProp?.declarations && compilerOptions.noImplicitOverride && !nodeInAmbientContext) { - const baseHasAbstract = some(baseProp.declarations, hasAbstractModifier); + const baseHasAbstract = ts.some(baseProp.declarations, ts.hasAbstractModifier); if (memberHasOverrideModifier) { - return MemberOverrideStatus.Ok; + return ts.MemberOverrideStatus.Ok; } if (!baseHasAbstract) { if (errorNode) { const diag = memberIsParameterProperty ? isJs ? - Diagnostics.This_parameter_property_must_have_a_JSDoc_comment_with_an_override_tag_because_it_overrides_a_member_in_the_base_class_0 : - Diagnostics.This_parameter_property_must_have_an_override_modifier_because_it_overrides_a_member_in_base_class_0 : + ts.Diagnostics.This_parameter_property_must_have_a_JSDoc_comment_with_an_override_tag_because_it_overrides_a_member_in_the_base_class_0 : + ts.Diagnostics.This_parameter_property_must_have_an_override_modifier_because_it_overrides_a_member_in_base_class_0 : isJs ? - Diagnostics.This_member_must_have_a_JSDoc_comment_with_an_override_tag_because_it_overrides_a_member_in_the_base_class_0 : - Diagnostics.This_member_must_have_an_override_modifier_because_it_overrides_a_member_in_the_base_class_0; + ts.Diagnostics.This_member_must_have_a_JSDoc_comment_with_an_override_tag_because_it_overrides_a_member_in_the_base_class_0 : + ts.Diagnostics.This_member_must_have_an_override_modifier_because_it_overrides_a_member_in_the_base_class_0; error(errorNode, diag, baseClassName); } - return MemberOverrideStatus.NeedsOverride; + return ts.MemberOverrideStatus.NeedsOverride; } else if (memberHasAbstractModifier && baseHasAbstract) { if (errorNode) { - error(errorNode, Diagnostics.This_member_must_have_an_override_modifier_because_it_overrides_an_abstract_method_that_is_declared_in_the_base_class_0, baseClassName); + error(errorNode, ts.Diagnostics.This_member_must_have_an_override_modifier_because_it_overrides_an_abstract_method_that_is_declared_in_the_base_class_0, baseClassName); } - return MemberOverrideStatus.NeedsOverride; + return ts.MemberOverrideStatus.NeedsOverride; } } } else if (memberHasOverrideModifier) { if (errorNode) { const className = typeToString(type); - error( - errorNode, - isJs ? - Diagnostics.This_member_cannot_have_a_JSDoc_comment_with_an_override_tag_because_its_containing_class_0_does_not_extend_another_class : - Diagnostics.This_member_cannot_have_an_override_modifier_because_its_containing_class_0_does_not_extend_another_class, - className); + error(errorNode, isJs ? + ts.Diagnostics.This_member_cannot_have_a_JSDoc_comment_with_an_override_tag_because_its_containing_class_0_does_not_extend_another_class : + ts.Diagnostics.This_member_cannot_have_an_override_modifier_because_its_containing_class_0_does_not_extend_another_class, className); } - return MemberOverrideStatus.HasInvalidOverride; + return ts.MemberOverrideStatus.HasInvalidOverride; } - return MemberOverrideStatus.Ok; + return ts.MemberOverrideStatus.Ok; } - function issueMemberSpecificError(node: ClassLikeDeclaration, typeWithThis: Type, baseWithThis: Type, broadDiag: DiagnosticMessage) { + function issueMemberSpecificError(node: ts.ClassLikeDeclaration, typeWithThis: ts.Type, baseWithThis: ts.Type, broadDiag: ts.DiagnosticMessage) { // iterate over all implemented properties and issue errors on each one which isn't compatible, rather than the class as a whole, if possible let issuedMemberError = false; for (const member of node.members) { - if (isStatic(member)) { + if (ts.isStatic(member)) { continue; } const declaredProp = member.name && getSymbolAtLocation(member.name) || getSymbolAtLocation(member); @@ -39779,13 +38885,8 @@ namespace ts { const prop = getPropertyOfType(typeWithThis, declaredProp.escapedName); const baseProp = getPropertyOfType(baseWithThis, declaredProp.escapedName); if (prop && baseProp) { - const rootChain = () => chainDiagnosticMessages( - /*details*/ undefined, - Diagnostics.Property_0_in_type_1_is_not_assignable_to_the_same_property_in_base_type_2, - symbolToString(declaredProp), - typeToString(typeWithThis), - typeToString(baseWithThis) - ); + const rootChain = () => ts.chainDiagnosticMessages( + /*details*/ undefined, ts.Diagnostics.Property_0_in_type_1_is_not_assignable_to_the_same_property_in_base_type_2, symbolToString(declaredProp), typeToString(typeWithThis), typeToString(baseWithThis)); if (!checkTypeAssignableTo(getTypeOfSymbol(prop), getTypeOfSymbol(baseProp), member.name || member, /*message*/ undefined, rootChain)) { issuedMemberError = true; } @@ -39798,14 +38899,14 @@ namespace ts { } } - function checkBaseTypeAccessibility(type: Type, node: ExpressionWithTypeArguments) { - const signatures = getSignaturesOfType(type, SignatureKind.Construct); + function checkBaseTypeAccessibility(type: ts.Type, node: ts.ExpressionWithTypeArguments) { + const signatures = getSignaturesOfType(type, ts.SignatureKind.Construct); if (signatures.length) { const declaration = signatures[0].declaration; - if (declaration && hasEffectiveModifier(declaration, ModifierFlags.Private)) { - const typeClassDeclaration = getClassLikeDeclarationOfSymbol(type.symbol)!; + if (declaration && ts.hasEffectiveModifier(declaration, ts.ModifierFlags.Private)) { + const typeClassDeclaration = ts.getClassLikeDeclarationOfSymbol(type.symbol)!; if (!isNodeWithinClass(node, typeClassDeclaration)) { - error(node, Diagnostics.Cannot_extend_a_class_0_Class_constructor_is_marked_as_private, getFullyQualifiedName(type.symbol)); + error(node, ts.Diagnostics.Cannot_extend_a_class_0_Class_constructor_is_marked_as_private, getFullyQualifiedName(type.symbol)); } } } @@ -39817,54 +38918,39 @@ namespace ts { * @param member Member declaration node. * Note: `member` can be a synthetic node without a parent. */ - function getMemberOverrideModifierStatus(node: ClassLikeDeclaration, member: ClassElement): MemberOverrideStatus { + function getMemberOverrideModifierStatus(node: ts.ClassLikeDeclaration, member: ts.ClassElement): ts.MemberOverrideStatus { if (!member.name) { - return MemberOverrideStatus.Ok; + return ts.MemberOverrideStatus.Ok; } const symbol = getSymbolOfNode(node); - const type = getDeclaredTypeOfSymbol(symbol) as InterfaceType; + const type = getDeclaredTypeOfSymbol(symbol) as ts.InterfaceType; const typeWithThis = getTypeWithThisArgument(type); - const staticType = getTypeOfSymbol(symbol) as ObjectType; - - const baseTypeNode = getEffectiveBaseTypeNode(node); + const staticType = getTypeOfSymbol(symbol) as ts.ObjectType; + const baseTypeNode = ts.getEffectiveBaseTypeNode(node); const baseTypes = baseTypeNode && getBaseTypes(type); - const baseWithThis = baseTypes?.length ? getTypeWithThisArgument(first(baseTypes), type.thisType) : undefined; + const baseWithThis = baseTypes?.length ? getTypeWithThisArgument(ts.first(baseTypes), type.thisType) : undefined; const baseStaticType = getBaseConstructorTypeOfClass(type); const memberHasOverrideModifier = member.parent - ? hasOverrideModifier(member) - : hasSyntacticModifier(member, ModifierFlags.Override); - - const memberName = unescapeLeadingUnderscores(getTextOfPropertyName(member.name)); - - return checkMemberForOverrideModifier( - node, - staticType, - baseStaticType, - baseWithThis, - type, - typeWithThis, - memberHasOverrideModifier, - hasAbstractModifier(member), - isStatic(member), - /* memberIsParameterProperty */ false, - memberName, - ); - } - - function getTargetSymbol(s: Symbol) { + ? ts.hasOverrideModifier(member) + : ts.hasSyntacticModifier(member, ts.ModifierFlags.Override); + const memberName = ts.unescapeLeadingUnderscores(ts.getTextOfPropertyName(member.name)); + return checkMemberForOverrideModifier(node, staticType, baseStaticType, baseWithThis, type, typeWithThis, memberHasOverrideModifier, ts.hasAbstractModifier(member), ts.isStatic(member), + /* memberIsParameterProperty */ false, memberName); + } + + function getTargetSymbol(s: ts.Symbol) { // if symbol is instantiated its flags are not copied from the 'target' // so we'll need to get back original 'target' symbol to work with correct set of flags - return getCheckFlags(s) & CheckFlags.Instantiated ? (s as TransientSymbol).target! : s; + return ts.getCheckFlags(s) & ts.CheckFlags.Instantiated ? (s as ts.TransientSymbol).target! : s; } - function getClassOrInterfaceDeclarationsOfSymbol(symbol: Symbol) { - return filter(symbol.declarations, (d: Declaration): d is ClassDeclaration | InterfaceDeclaration => - d.kind === SyntaxKind.ClassDeclaration || d.kind === SyntaxKind.InterfaceDeclaration); + function getClassOrInterfaceDeclarationsOfSymbol(symbol: ts.Symbol) { + return ts.filter(symbol.declarations, (d: ts.Declaration): d is ts.ClassDeclaration | ts.InterfaceDeclaration => d.kind === ts.SyntaxKind.ClassDeclaration || d.kind === ts.SyntaxKind.InterfaceDeclaration); } - function checkKindsOfPropertyMemberOverrides(type: InterfaceType, baseType: BaseType): void { + function checkKindsOfPropertyMemberOverrides(type: ts.InterfaceType, baseType: ts.BaseType): void { // TypeScript 1.0 spec (April 2014): 8.2.3 // A derived class inherits all members from its base class it doesn't override. // Inheritance means that a derived class implicitly contains all non - overridden members of the base class. @@ -39884,7 +38970,7 @@ namespace ts { basePropertyCheck: for (const baseProperty of baseProperties) { const base = getTargetSymbol(baseProperty); - if (base.flags & SymbolFlags.Prototype) { + if (base.flags & ts.SymbolFlags.Prototype) { continue; } const baseSymbol = getPropertyOfObjectType(type, base.escapedName); @@ -39892,26 +38978,26 @@ namespace ts { continue; } const derived = getTargetSymbol(baseSymbol); - const baseDeclarationFlags = getDeclarationModifierFlagsFromSymbol(base); - - Debug.assert(!!derived, "derived should point to something, even if it is the base class' declaration."); + const baseDeclarationFlags = ts.getDeclarationModifierFlagsFromSymbol(base); + ts.Debug.assert(!!derived, "derived should point to something, even if it is the base class' declaration."); // In order to resolve whether the inherited method was overridden in the base class or not, // we compare the Symbols obtained. Since getTargetSymbol returns the symbol on the *uninstantiated* // type declaration, derived and base resolve to the same symbol even in the case of generic classes. if (derived === base) { // derived class inherits base without override/redeclaration - const derivedClassDecl = getClassLikeDeclarationOfSymbol(type.symbol)!; + const derivedClassDecl = ts.getClassLikeDeclarationOfSymbol(type.symbol)!; // It is an error to inherit an abstract member without implementing it or being declared abstract. // If there is no declaration for the derived class (as in the case of class expressions), // then the class cannot be declared abstract. - if (baseDeclarationFlags & ModifierFlags.Abstract && (!derivedClassDecl || !hasSyntacticModifier(derivedClassDecl, ModifierFlags.Abstract))) { + if (baseDeclarationFlags & ts.ModifierFlags.Abstract && (!derivedClassDecl || !ts.hasSyntacticModifier(derivedClassDecl, ts.ModifierFlags.Abstract))) { // Searches other base types for a declaration that would satisfy the inherited abstract member. // (The class may have more than one base type via declaration merging with an interface with the // same name.) for (const otherBaseType of getBaseTypes(type)) { - if (otherBaseType === baseType) continue; + if (otherBaseType === baseType) + continue; const baseSymbol = getPropertyOfObjectType(otherBaseType, base.escapedName); const derivedElsewhere = baseSymbol && getTargetSymbol(baseSymbol); if (derivedElsewhere && derivedElsewhere !== base) { @@ -39919,61 +39005,59 @@ namespace ts { } } - if (derivedClassDecl.kind === SyntaxKind.ClassExpression) { - error(derivedClassDecl, Diagnostics.Non_abstract_class_expression_does_not_implement_inherited_abstract_member_0_from_class_1, - symbolToString(baseProperty), typeToString(baseType)); + if (derivedClassDecl.kind === ts.SyntaxKind.ClassExpression) { + error(derivedClassDecl, ts.Diagnostics.Non_abstract_class_expression_does_not_implement_inherited_abstract_member_0_from_class_1, symbolToString(baseProperty), typeToString(baseType)); } else { - error(derivedClassDecl, Diagnostics.Non_abstract_class_0_does_not_implement_inherited_abstract_member_1_from_class_2, - typeToString(type), symbolToString(baseProperty), typeToString(baseType)); + error(derivedClassDecl, ts.Diagnostics.Non_abstract_class_0_does_not_implement_inherited_abstract_member_1_from_class_2, typeToString(type), symbolToString(baseProperty), typeToString(baseType)); } } } else { // derived overrides base. - const derivedDeclarationFlags = getDeclarationModifierFlagsFromSymbol(derived); - if (baseDeclarationFlags & ModifierFlags.Private || derivedDeclarationFlags & ModifierFlags.Private) { + const derivedDeclarationFlags = ts.getDeclarationModifierFlagsFromSymbol(derived); + if (baseDeclarationFlags & ts.ModifierFlags.Private || derivedDeclarationFlags & ts.ModifierFlags.Private) { // either base or derived property is private - not override, skip it continue; } - let errorMessage: DiagnosticMessage; - const basePropertyFlags = base.flags & SymbolFlags.PropertyOrAccessor; - const derivedPropertyFlags = derived.flags & SymbolFlags.PropertyOrAccessor; + let errorMessage: ts.DiagnosticMessage; + const basePropertyFlags = base.flags & ts.SymbolFlags.PropertyOrAccessor; + const derivedPropertyFlags = derived.flags & ts.SymbolFlags.PropertyOrAccessor; if (basePropertyFlags && derivedPropertyFlags) { // property/accessor is overridden with property/accessor - if (baseDeclarationFlags & ModifierFlags.Abstract && !(base.valueDeclaration && isPropertyDeclaration(base.valueDeclaration) && base.valueDeclaration.initializer) - || base.valueDeclaration && base.valueDeclaration.parent.kind === SyntaxKind.InterfaceDeclaration - || derived.valueDeclaration && isBinaryExpression(derived.valueDeclaration)) { + if (baseDeclarationFlags & ts.ModifierFlags.Abstract && !(base.valueDeclaration && ts.isPropertyDeclaration(base.valueDeclaration) && base.valueDeclaration.initializer) + || base.valueDeclaration && base.valueDeclaration.parent.kind === ts.SyntaxKind.InterfaceDeclaration + || derived.valueDeclaration && ts.isBinaryExpression(derived.valueDeclaration)) { // when the base property is abstract or from an interface, base/derived flags don't need to match // same when the derived property is from an assignment continue; } - const overriddenInstanceProperty = basePropertyFlags !== SymbolFlags.Property && derivedPropertyFlags === SymbolFlags.Property; - const overriddenInstanceAccessor = basePropertyFlags === SymbolFlags.Property && derivedPropertyFlags !== SymbolFlags.Property; + const overriddenInstanceProperty = basePropertyFlags !== ts.SymbolFlags.Property && derivedPropertyFlags === ts.SymbolFlags.Property; + const overriddenInstanceAccessor = basePropertyFlags === ts.SymbolFlags.Property && derivedPropertyFlags !== ts.SymbolFlags.Property; if (overriddenInstanceProperty || overriddenInstanceAccessor) { const errorMessage = overriddenInstanceProperty ? - Diagnostics._0_is_defined_as_an_accessor_in_class_1_but_is_overridden_here_in_2_as_an_instance_property : - Diagnostics._0_is_defined_as_a_property_in_class_1_but_is_overridden_here_in_2_as_an_accessor; - error(getNameOfDeclaration(derived.valueDeclaration) || derived.valueDeclaration, errorMessage, symbolToString(base), typeToString(baseType), typeToString(type)); + ts.Diagnostics._0_is_defined_as_an_accessor_in_class_1_but_is_overridden_here_in_2_as_an_instance_property : + ts.Diagnostics._0_is_defined_as_a_property_in_class_1_but_is_overridden_here_in_2_as_an_accessor; + error(ts.getNameOfDeclaration(derived.valueDeclaration) || derived.valueDeclaration, errorMessage, symbolToString(base), typeToString(baseType), typeToString(type)); } else if (useDefineForClassFields) { - const uninitialized = derived.declarations?.find(d => d.kind === SyntaxKind.PropertyDeclaration && !(d as PropertyDeclaration).initializer); + const uninitialized = derived.declarations?.find(d => d.kind === ts.SyntaxKind.PropertyDeclaration && !(d as ts.PropertyDeclaration).initializer); if (uninitialized - && !(derived.flags & SymbolFlags.Transient) - && !(baseDeclarationFlags & ModifierFlags.Abstract) - && !(derivedDeclarationFlags & ModifierFlags.Abstract) - && !derived.declarations?.some(d => !!(d.flags & NodeFlags.Ambient))) { - const constructor = findConstructorDeclaration(getClassLikeDeclarationOfSymbol(type.symbol)!); - const propName = (uninitialized as PropertyDeclaration).name; - if ((uninitialized as PropertyDeclaration).exclamationToken + && !(derived.flags & ts.SymbolFlags.Transient) + && !(baseDeclarationFlags & ts.ModifierFlags.Abstract) + && !(derivedDeclarationFlags & ts.ModifierFlags.Abstract) + && !derived.declarations?.some(d => !!(d.flags & ts.NodeFlags.Ambient))) { + const constructor = findConstructorDeclaration(ts.getClassLikeDeclarationOfSymbol(type.symbol)!); + const propName = (uninitialized as ts.PropertyDeclaration).name; + if ((uninitialized as ts.PropertyDeclaration).exclamationToken || !constructor - || !isIdentifier(propName) + || !ts.isIdentifier(propName) || !strictNullChecks || !isPropertyInitializedInConstructor(propName, type, constructor)) { - const errorMessage = Diagnostics.Property_0_will_overwrite_the_base_property_in_1_If_this_is_intentional_add_an_initializer_Otherwise_add_a_declare_modifier_or_remove_the_redundant_declaration; - error(getNameOfDeclaration(derived.valueDeclaration) || derived.valueDeclaration, errorMessage, symbolToString(base), typeToString(baseType)); + const errorMessage = ts.Diagnostics.Property_0_will_overwrite_the_base_property_in_1_If_this_is_intentional_add_an_initializer_Otherwise_add_a_declare_modifier_or_remove_the_redundant_declaration; + error(ts.getNameOfDeclaration(derived.valueDeclaration) || derived.valueDeclaration, errorMessage, symbolToString(base), typeToString(baseType)); } } } @@ -39982,33 +39066,33 @@ namespace ts { continue; } else if (isPrototypeProperty(base)) { - if (isPrototypeProperty(derived) || derived.flags & SymbolFlags.Property) { + if (isPrototypeProperty(derived) || derived.flags & ts.SymbolFlags.Property) { // method is overridden with method or property -- correct case continue; } else { - Debug.assert(!!(derived.flags & SymbolFlags.Accessor)); - errorMessage = Diagnostics.Class_0_defines_instance_member_function_1_but_extended_class_2_defines_it_as_instance_member_accessor; + ts.Debug.assert(!!(derived.flags & ts.SymbolFlags.Accessor)); + errorMessage = ts.Diagnostics.Class_0_defines_instance_member_function_1_but_extended_class_2_defines_it_as_instance_member_accessor; } } - else if (base.flags & SymbolFlags.Accessor) { - errorMessage = Diagnostics.Class_0_defines_instance_member_accessor_1_but_extended_class_2_defines_it_as_instance_member_function; + else if (base.flags & ts.SymbolFlags.Accessor) { + errorMessage = ts.Diagnostics.Class_0_defines_instance_member_accessor_1_but_extended_class_2_defines_it_as_instance_member_function; } else { - errorMessage = Diagnostics.Class_0_defines_instance_member_property_1_but_extended_class_2_defines_it_as_instance_member_function; + errorMessage = ts.Diagnostics.Class_0_defines_instance_member_property_1_but_extended_class_2_defines_it_as_instance_member_function; } - error(getNameOfDeclaration(derived.valueDeclaration) || derived.valueDeclaration, errorMessage, typeToString(baseType), symbolToString(base), typeToString(type)); + error(ts.getNameOfDeclaration(derived.valueDeclaration) || derived.valueDeclaration, errorMessage, typeToString(baseType), symbolToString(base), typeToString(type)); } } } - function getNonInterhitedProperties(type: InterfaceType, baseTypes: BaseType[], properties: Symbol[]) { - if (!length(baseTypes)) { + function getNonInterhitedProperties(type: ts.InterfaceType, baseTypes: ts.BaseType[], properties: ts.Symbol[]) { + if (!ts.length(baseTypes)) { return properties; } - const seen = new Map<__String, Symbol>(); - forEach(properties, p => { + const seen = new ts.Map(); + ts.forEach(properties, p => { seen.set(p.escapedName, p); }); @@ -40022,18 +39106,21 @@ namespace ts { } } - return arrayFrom(seen.values()); + return ts.arrayFrom(seen.values()); } - function checkInheritedPropertiesAreIdentical(type: InterfaceType, typeNode: Node): boolean { + function checkInheritedPropertiesAreIdentical(type: ts.InterfaceType, typeNode: ts.Node): boolean { const baseTypes = getBaseTypes(type); if (baseTypes.length < 2) { return true; } - interface InheritanceInfoMap { prop: Symbol; containingType: Type; } - const seen = new Map<__String, InheritanceInfoMap>(); - forEach(resolveDeclaredMembers(type).declaredProperties, p => { + interface InheritanceInfoMap { + prop: ts.Symbol; + containingType: ts.Type; + } + const seen = new ts.Map(); + ts.forEach(resolveDeclaredMembers(type).declaredProperties, p => { seen.set(p.escapedName, { prop: p, containingType: type }); }); let ok = true; @@ -40053,9 +39140,9 @@ namespace ts { const typeName1 = typeToString(existing.containingType); const typeName2 = typeToString(base); - let errorInfo = chainDiagnosticMessages(/*details*/ undefined, Diagnostics.Named_property_0_of_types_1_and_2_are_not_identical, symbolToString(prop), typeName1, typeName2); - errorInfo = chainDiagnosticMessages(errorInfo, Diagnostics.Interface_0_cannot_simultaneously_extend_types_1_and_2, typeToString(type), typeName1, typeName2); - diagnostics.add(createDiagnosticForNodeFromMessageChain(typeNode, errorInfo)); + let errorInfo = ts.chainDiagnosticMessages(/*details*/ undefined, ts.Diagnostics.Named_property_0_of_types_1_and_2_are_not_identical, symbolToString(prop), typeName1, typeName2); + errorInfo = ts.chainDiagnosticMessages(errorInfo, ts.Diagnostics.Interface_0_cannot_simultaneously_extend_types_1_and_2, typeToString(type), typeName1, typeName2); + diagnostics.add(ts.createDiagnosticForNodeFromMessageChain(typeNode, errorInfo)); } } } @@ -40064,22 +39151,22 @@ namespace ts { return ok; } - function checkPropertyInitialization(node: ClassLikeDeclaration) { - if (!strictNullChecks || !strictPropertyInitialization || node.flags & NodeFlags.Ambient) { + function checkPropertyInitialization(node: ts.ClassLikeDeclaration) { + if (!strictNullChecks || !strictPropertyInitialization || node.flags & ts.NodeFlags.Ambient) { return; } const constructor = findConstructorDeclaration(node); for (const member of node.members) { - if (getEffectiveModifierFlags(member) & ModifierFlags.Ambient) { + if (ts.getEffectiveModifierFlags(member) & ts.ModifierFlags.Ambient) { continue; } - if (!isStatic(member) && isPropertyWithoutInitializer(member)) { - const propName = (member as PropertyDeclaration).name; - if (isIdentifier(propName) || isPrivateIdentifier(propName) || isComputedPropertyName(propName)) { + if (!ts.isStatic(member) && isPropertyWithoutInitializer(member)) { + const propName = (member as ts.PropertyDeclaration).name; + if (ts.isIdentifier(propName) || ts.isPrivateIdentifier(propName) || ts.isComputedPropertyName(propName)) { const type = getTypeOfSymbol(getSymbolOfNode(member)); - if (!(type.flags & TypeFlags.AnyOrUnknown || getFalsyFlags(type) & TypeFlags.Undefined)) { + if (!(type.flags & ts.TypeFlags.AnyOrUnknown || getFalsyFlags(type) & ts.TypeFlags.Undefined)) { if (!constructor || !isPropertyInitializedInConstructor(propName, type, constructor)) { - error(member.name, Diagnostics.Property_0_has_no_initializer_and_is_not_definitely_assigned_in_the_constructor, declarationNameToString(propName)); + error(member.name, ts.Diagnostics.Property_0_has_no_initializer_and_is_not_definitely_assigned_in_the_constructor, ts.declarationNameToString(propName)); } } } @@ -40087,23 +39174,23 @@ namespace ts { } } - function isPropertyWithoutInitializer(node: Node) { - return node.kind === SyntaxKind.PropertyDeclaration && - !hasAbstractModifier(node) && - !(node as PropertyDeclaration).exclamationToken && - !(node as PropertyDeclaration).initializer; + function isPropertyWithoutInitializer(node: ts.Node) { + return node.kind === ts.SyntaxKind.PropertyDeclaration && + !ts.hasAbstractModifier(node) && + !(node as ts.PropertyDeclaration).exclamationToken && + !(node as ts.PropertyDeclaration).initializer; } - function isPropertyInitializedInStaticBlocks(propName: Identifier | PrivateIdentifier, propType: Type, staticBlocks: readonly ClassStaticBlockDeclaration[], startPos: number, endPos: number) { + function isPropertyInitializedInStaticBlocks(propName: ts.Identifier | ts.PrivateIdentifier, propType: ts.Type, staticBlocks: readonly ts.ClassStaticBlockDeclaration[], startPos: number, endPos: number) { for (const staticBlock of staticBlocks) { // static block must be within the provided range as they are evaluated in document order (unlike constructors) if (staticBlock.pos >= startPos && staticBlock.pos <= endPos) { - const reference = factory.createPropertyAccessExpression(factory.createThis(), propName); - setParent(reference.expression, reference); - setParent(reference, staticBlock); + const reference = ts.factory.createPropertyAccessExpression(ts.factory.createThis(), propName); + ts.setParent(reference.expression, reference); + ts.setParent(reference, staticBlock); reference.flowNode = staticBlock.returnFlowNode; const flowType = getFlowTypeOfReference(reference, propType, getOptionalType(propType)); - if (!(getFalsyFlags(flowType) & TypeFlags.Undefined)) { + if (!(getFalsyFlags(flowType) & ts.TypeFlags.Undefined)) { return true; } } @@ -40111,53 +39198,54 @@ namespace ts { return false; } - function isPropertyInitializedInConstructor(propName: Identifier | PrivateIdentifier | ComputedPropertyName, propType: Type, constructor: ConstructorDeclaration) { - const reference = isComputedPropertyName(propName) - ? factory.createElementAccessExpression(factory.createThis(), propName.expression) - : factory.createPropertyAccessExpression(factory.createThis(), propName); - setParent(reference.expression, reference); - setParent(reference, constructor); + function isPropertyInitializedInConstructor(propName: ts.Identifier | ts.PrivateIdentifier | ts.ComputedPropertyName, propType: ts.Type, constructor: ts.ConstructorDeclaration) { + const reference = ts.isComputedPropertyName(propName) + ? ts.factory.createElementAccessExpression(ts.factory.createThis(), propName.expression) + : ts.factory.createPropertyAccessExpression(ts.factory.createThis(), propName); + ts.setParent(reference.expression, reference); + ts.setParent(reference, constructor); reference.flowNode = constructor.returnFlowNode; const flowType = getFlowTypeOfReference(reference, propType, getOptionalType(propType)); - return !(getFalsyFlags(flowType) & TypeFlags.Undefined); + return !(getFalsyFlags(flowType) & ts.TypeFlags.Undefined); } - function checkInterfaceDeclaration(node: InterfaceDeclaration) { + function checkInterfaceDeclaration(node: ts.InterfaceDeclaration) { // Grammar checking - if (!checkGrammarDecoratorsAndModifiers(node)) checkGrammarInterfaceDeclaration(node); + if (!checkGrammarDecoratorsAndModifiers(node)) + checkGrammarInterfaceDeclaration(node); checkTypeParameters(node.typeParameters); addLazyDiagnostic(() => { - checkTypeNameIsReserved(node.name, Diagnostics.Interface_name_cannot_be_0); + checkTypeNameIsReserved(node.name, ts.Diagnostics.Interface_name_cannot_be_0); checkExportsOnMergedDeclarations(node); const symbol = getSymbolOfNode(node); checkTypeParameterListsIdentical(symbol); // Only check this symbol once - const firstInterfaceDecl = getDeclarationOfKind(symbol, SyntaxKind.InterfaceDeclaration); + const firstInterfaceDecl = ts.getDeclarationOfKind(symbol, ts.SyntaxKind.InterfaceDeclaration); if (node === firstInterfaceDecl) { - const type = getDeclaredTypeOfSymbol(symbol) as InterfaceType; + const type = getDeclaredTypeOfSymbol(symbol) as ts.InterfaceType; const typeWithThis = getTypeWithThisArgument(type); // run subsequent checks only if first set succeeded if (checkInheritedPropertiesAreIdentical(type, node.name)) { for (const baseType of getBaseTypes(type)) { - checkTypeAssignableTo(typeWithThis, getTypeWithThisArgument(baseType, type.thisType), node.name, Diagnostics.Interface_0_incorrectly_extends_interface_1); + checkTypeAssignableTo(typeWithThis, getTypeWithThisArgument(baseType, type.thisType), node.name, ts.Diagnostics.Interface_0_incorrectly_extends_interface_1); } checkIndexConstraints(type, symbol); } } checkObjectTypeForDuplicateDeclarations(node); }); - forEach(getInterfaceBaseTypeNodes(node), heritageElement => { - if (!isEntityNameExpression(heritageElement.expression) || isOptionalChain(heritageElement.expression)) { - error(heritageElement.expression, Diagnostics.An_interface_can_only_extend_an_identifier_Slashqualified_name_with_optional_type_arguments); + ts.forEach(ts.getInterfaceBaseTypeNodes(node), heritageElement => { + if (!ts.isEntityNameExpression(heritageElement.expression) || ts.isOptionalChain(heritageElement.expression)) { + error(heritageElement.expression, ts.Diagnostics.An_interface_can_only_extend_an_identifier_Slashqualified_name_with_optional_type_arguments); } checkTypeReferenceNode(heritageElement); }); - forEach(node.members, checkSourceElement); + ts.forEach(node.members, checkSourceElement); addLazyDiagnostic(() => { checkTypeForDuplicateIndexSignatures(node); @@ -40165,15 +39253,15 @@ namespace ts { }); } - function checkTypeAliasDeclaration(node: TypeAliasDeclaration) { + function checkTypeAliasDeclaration(node: ts.TypeAliasDeclaration) { // Grammar checking checkGrammarDecoratorsAndModifiers(node); - checkTypeNameIsReserved(node.name, Diagnostics.Type_alias_name_cannot_be_0); + checkTypeNameIsReserved(node.name, ts.Diagnostics.Type_alias_name_cannot_be_0); checkExportsOnMergedDeclarations(node); checkTypeParameters(node.typeParameters); - if (node.type.kind === SyntaxKind.IntrinsicKeyword) { - if (!intrinsicTypeKinds.has(node.name.escapedText as string) || length(node.typeParameters) !== 1) { - error(node.type, Diagnostics.The_intrinsic_keyword_can_only_be_used_to_declare_compiler_provided_intrinsic_types); + if (node.type.kind === ts.SyntaxKind.IntrinsicKeyword) { + if (!intrinsicTypeKinds.has(node.name.escapedText as string) || ts.length(node.typeParameters) !== 1) { + error(node.type, ts.Diagnostics.The_intrinsic_keyword_can_only_be_used_to_declare_compiler_provided_intrinsic_types); } } else { @@ -40182,10 +39270,10 @@ namespace ts { } } - function computeEnumMemberValues(node: EnumDeclaration) { + function computeEnumMemberValues(node: ts.EnumDeclaration) { const nodeLinks = getNodeLinks(node); - if (!(nodeLinks.flags & NodeCheckFlags.EnumValuesComputed)) { - nodeLinks.flags |= NodeCheckFlags.EnumValuesComputed; + if (!(nodeLinks.flags & ts.NodeCheckFlags.EnumValuesComputed)) { + nodeLinks.flags |= ts.NodeCheckFlags.EnumValuesComputed; let autoValue: number | undefined = 0; for (const member of node.members) { const value = computeMemberValue(member, autoValue); @@ -40195,14 +39283,14 @@ namespace ts { } } - function computeMemberValue(member: EnumMember, autoValue: number | undefined) { - if (isComputedNonLiteralName(member.name)) { - error(member.name, Diagnostics.Computed_property_names_are_not_allowed_in_enums); + function computeMemberValue(member: ts.EnumMember, autoValue: number | undefined) { + if (ts.isComputedNonLiteralName(member.name)) { + error(member.name, ts.Diagnostics.Computed_property_names_are_not_allowed_in_enums); } else { - const text = getTextOfPropertyName(member.name); - if (isNumericLiteralName(text) && !isInfinityOrNaNString(text)) { - error(member.name, Diagnostics.An_enum_member_cannot_have_a_numeric_name); + const text = ts.getTextOfPropertyName(member.name); + if (ts.isNumericLiteralName(text) && !ts.isInfinityOrNaNString(text)) { + error(member.name, ts.Diagnostics.An_enum_member_cannot_have_a_numeric_name); } } if (member.initializer) { @@ -40210,7 +39298,7 @@ namespace ts { } // In ambient non-const numeric enum declarations, enum members without initializers are // considered computed members (as opposed to having auto-incremented values). - if (member.parent.flags & NodeFlags.Ambient && !isEnumConst(member.parent) && getEnumKind(getSymbolOfNode(member.parent)) === EnumKind.Numeric) { + if (member.parent.flags & ts.NodeFlags.Ambient && !ts.isEnumConst(member.parent) && getEnumKind(getSymbolOfNode(member.parent)) === ts.EnumKind.Numeric) { return undefined; } // If the member declaration specifies no value, the member is considered a constant enum member. @@ -40220,37 +39308,37 @@ namespace ts { if (autoValue !== undefined) { return autoValue; } - error(member.name, Diagnostics.Enum_member_must_have_initializer); + error(member.name, ts.Diagnostics.Enum_member_must_have_initializer); return undefined; } - function computeConstantValue(member: EnumMember): string | number | undefined { + function computeConstantValue(member: ts.EnumMember): string | number | undefined { const enumKind = getEnumKind(getSymbolOfNode(member.parent)); - const isConstEnum = isEnumConst(member.parent); + const isConstEnum = ts.isEnumConst(member.parent); const initializer = member.initializer!; - const value = enumKind === EnumKind.Literal && !isLiteralEnumMember(member) ? undefined : evaluate(initializer); + const value = enumKind === ts.EnumKind.Literal && !isLiteralEnumMember(member) ? undefined : evaluate(initializer); if (value !== undefined) { if (isConstEnum && typeof value === "number" && !isFinite(value)) { error(initializer, isNaN(value) ? - Diagnostics.const_enum_member_initializer_was_evaluated_to_disallowed_value_NaN : - Diagnostics.const_enum_member_initializer_was_evaluated_to_a_non_finite_value); + ts.Diagnostics.const_enum_member_initializer_was_evaluated_to_disallowed_value_NaN : + ts.Diagnostics.const_enum_member_initializer_was_evaluated_to_a_non_finite_value); } } - else if (enumKind === EnumKind.Literal) { - error(initializer, Diagnostics.Computed_values_are_not_permitted_in_an_enum_with_string_valued_members); + else if (enumKind === ts.EnumKind.Literal) { + error(initializer, ts.Diagnostics.Computed_values_are_not_permitted_in_an_enum_with_string_valued_members); return 0; } else if (isConstEnum) { - error(initializer, Diagnostics.const_enum_member_initializers_can_only_contain_literal_values_and_other_computed_enum_values); + error(initializer, ts.Diagnostics.const_enum_member_initializers_can_only_contain_literal_values_and_other_computed_enum_values); } - else if (member.parent.flags & NodeFlags.Ambient) { - error(initializer, Diagnostics.In_ambient_enum_declarations_member_initializer_must_be_constant_expression); + else if (member.parent.flags & ts.NodeFlags.Ambient) { + error(initializer, ts.Diagnostics.In_ambient_enum_declarations_member_initializer_must_be_constant_expression); } else { // Only here do we need to check that the initializer is assignable to the enum type. const source = checkExpression(initializer); - if (!isTypeAssignableToKind(source, TypeFlags.NumberLike)) { - error(initializer, Diagnostics.Only_numeric_enums_can_have_computed_members_but_this_expression_has_type_0_If_you_do_not_need_exhaustiveness_checks_consider_using_an_object_literal_instead, typeToString(source)); + if (!isTypeAssignableToKind(source, ts.TypeFlags.NumberLike)) { + error(initializer, ts.Diagnostics.Only_numeric_enums_can_have_computed_members_but_this_expression_has_type_0_If_you_do_not_need_exhaustiveness_checks_consider_using_an_object_literal_instead, typeToString(source)); } else { checkTypeAssignableTo(source, getDeclaredTypeOfSymbol(getSymbolOfNode(member.parent)), initializer, /*headMessage*/ undefined); @@ -40258,66 +39346,66 @@ namespace ts { } return value; - function evaluate(expr: Expression): string | number | undefined { + function evaluate(expr: ts.Expression): string | number | undefined { switch (expr.kind) { - case SyntaxKind.PrefixUnaryExpression: - const value = evaluate((expr as PrefixUnaryExpression).operand); + case ts.SyntaxKind.PrefixUnaryExpression: + const value = evaluate((expr as ts.PrefixUnaryExpression).operand); if (typeof value === "number") { - switch ((expr as PrefixUnaryExpression).operator) { - case SyntaxKind.PlusToken: return value; - case SyntaxKind.MinusToken: return -value; - case SyntaxKind.TildeToken: return ~value; + switch ((expr as ts.PrefixUnaryExpression).operator) { + case ts.SyntaxKind.PlusToken: return value; + case ts.SyntaxKind.MinusToken: return -value; + case ts.SyntaxKind.TildeToken: return ~value; } } break; - case SyntaxKind.BinaryExpression: - const left = evaluate((expr as BinaryExpression).left); - const right = evaluate((expr as BinaryExpression).right); + case ts.SyntaxKind.BinaryExpression: + const left = evaluate((expr as ts.BinaryExpression).left); + const right = evaluate((expr as ts.BinaryExpression).right); if (typeof left === "number" && typeof right === "number") { - switch ((expr as BinaryExpression).operatorToken.kind) { - case SyntaxKind.BarToken: return left | right; - case SyntaxKind.AmpersandToken: return left & right; - case SyntaxKind.GreaterThanGreaterThanToken: return left >> right; - case SyntaxKind.GreaterThanGreaterThanGreaterThanToken: return left >>> right; - case SyntaxKind.LessThanLessThanToken: return left << right; - case SyntaxKind.CaretToken: return left ^ right; - case SyntaxKind.AsteriskToken: return left * right; - case SyntaxKind.SlashToken: return left / right; - case SyntaxKind.PlusToken: return left + right; - case SyntaxKind.MinusToken: return left - right; - case SyntaxKind.PercentToken: return left % right; - case SyntaxKind.AsteriskAsteriskToken: return left ** right; - } - } - else if (typeof left === "string" && typeof right === "string" && (expr as BinaryExpression).operatorToken.kind === SyntaxKind.PlusToken) { + switch ((expr as ts.BinaryExpression).operatorToken.kind) { + case ts.SyntaxKind.BarToken: return left | right; + case ts.SyntaxKind.AmpersandToken: return left & right; + case ts.SyntaxKind.GreaterThanGreaterThanToken: return left >> right; + case ts.SyntaxKind.GreaterThanGreaterThanGreaterThanToken: return left >>> right; + case ts.SyntaxKind.LessThanLessThanToken: return left << right; + case ts.SyntaxKind.CaretToken: return left ^ right; + case ts.SyntaxKind.AsteriskToken: return left * right; + case ts.SyntaxKind.SlashToken: return left / right; + case ts.SyntaxKind.PlusToken: return left + right; + case ts.SyntaxKind.MinusToken: return left - right; + case ts.SyntaxKind.PercentToken: return left % right; + case ts.SyntaxKind.AsteriskAsteriskToken: return left ** right; + } + } + else if (typeof left === "string" && typeof right === "string" && (expr as ts.BinaryExpression).operatorToken.kind === ts.SyntaxKind.PlusToken) { return left + right; } break; - case SyntaxKind.StringLiteral: - case SyntaxKind.NoSubstitutionTemplateLiteral: - return (expr as StringLiteralLike).text; - case SyntaxKind.NumericLiteral: - checkGrammarNumericLiteral(expr as NumericLiteral); - return +(expr as NumericLiteral).text; - case SyntaxKind.ParenthesizedExpression: - return evaluate((expr as ParenthesizedExpression).expression); - case SyntaxKind.Identifier: - const identifier = expr as Identifier; - if (isInfinityOrNaNString(identifier.escapedText)) { + case ts.SyntaxKind.StringLiteral: + case ts.SyntaxKind.NoSubstitutionTemplateLiteral: + return (expr as ts.StringLiteralLike).text; + case ts.SyntaxKind.NumericLiteral: + checkGrammarNumericLiteral(expr as ts.NumericLiteral); + return +(expr as ts.NumericLiteral).text; + case ts.SyntaxKind.ParenthesizedExpression: + return evaluate((expr as ts.ParenthesizedExpression).expression); + case ts.SyntaxKind.Identifier: + const identifier = expr as ts.Identifier; + if (ts.isInfinityOrNaNString(identifier.escapedText)) { return +(identifier.escapedText); } - return nodeIsMissing(expr) ? 0 : evaluateEnumMember(expr, getSymbolOfNode(member.parent), identifier.escapedText); - case SyntaxKind.ElementAccessExpression: - case SyntaxKind.PropertyAccessExpression: + return ts.nodeIsMissing(expr) ? 0 : evaluateEnumMember(expr, getSymbolOfNode(member.parent), identifier.escapedText); + case ts.SyntaxKind.ElementAccessExpression: + case ts.SyntaxKind.PropertyAccessExpression: if (isConstantMemberAccess(expr)) { const type = getTypeOfExpression(expr.expression); - if (type.symbol && type.symbol.flags & SymbolFlags.Enum) { - let name: __String; - if (expr.kind === SyntaxKind.PropertyAccessExpression) { + if (type.symbol && type.symbol.flags & ts.SymbolFlags.Enum) { + let name: ts.__String; + if (expr.kind === ts.SyntaxKind.PropertyAccessExpression) { name = expr.name.escapedText; } else { - name = escapeLeadingUnderscores(cast(expr.argumentExpression, isLiteralExpression).text); + name = ts.escapeLeadingUnderscores(ts.cast(expr.argumentExpression, ts.isLiteralExpression).text); } return evaluateEnumMember(expr, type.symbol, name); } @@ -40327,42 +39415,42 @@ namespace ts { return undefined; } - function evaluateEnumMember(expr: Expression, enumSymbol: Symbol, name: __String) { + function evaluateEnumMember(expr: ts.Expression, enumSymbol: ts.Symbol, name: ts.__String) { const memberSymbol = enumSymbol.exports!.get(name); if (memberSymbol) { const declaration = memberSymbol.valueDeclaration; if (declaration !== member) { - if (declaration && isBlockScopedNameDeclaredBeforeUse(declaration, member) && isEnumDeclaration(declaration.parent)) { - return getEnumMemberValue(declaration as EnumMember); + if (declaration && isBlockScopedNameDeclaredBeforeUse(declaration, member) && ts.isEnumDeclaration(declaration.parent)) { + return getEnumMemberValue(declaration as ts.EnumMember); } - error(expr, Diagnostics.A_member_initializer_in_a_enum_declaration_cannot_reference_members_declared_after_it_including_members_defined_in_other_enums); + error(expr, ts.Diagnostics.A_member_initializer_in_a_enum_declaration_cannot_reference_members_declared_after_it_including_members_defined_in_other_enums); return 0; } else { - error(expr, Diagnostics.Property_0_is_used_before_being_assigned, symbolToString(memberSymbol)); + error(expr, ts.Diagnostics.Property_0_is_used_before_being_assigned, symbolToString(memberSymbol)); } } return undefined; } } - function isConstantMemberAccess(node: Expression): node is AccessExpression { + function isConstantMemberAccess(node: ts.Expression): node is ts.AccessExpression { const type = getTypeOfExpression(node); if (type === errorType) { return false; } - return node.kind === SyntaxKind.Identifier || - node.kind === SyntaxKind.PropertyAccessExpression && isConstantMemberAccess((node as PropertyAccessExpression).expression) || - node.kind === SyntaxKind.ElementAccessExpression && isConstantMemberAccess((node as ElementAccessExpression).expression) && - isStringLiteralLike((node as ElementAccessExpression).argumentExpression); + return node.kind === ts.SyntaxKind.Identifier || + node.kind === ts.SyntaxKind.PropertyAccessExpression && isConstantMemberAccess((node as ts.PropertyAccessExpression).expression) || + node.kind === ts.SyntaxKind.ElementAccessExpression && isConstantMemberAccess((node as ts.ElementAccessExpression).expression) && + ts.isStringLiteralLike((node as ts.ElementAccessExpression).argumentExpression); } - function checkEnumDeclaration(node: EnumDeclaration) { + function checkEnumDeclaration(node: ts.EnumDeclaration) { addLazyDiagnostic(() => checkEnumDeclarationWorker(node)); } - function checkEnumDeclarationWorker(node: EnumDeclaration) { + function checkEnumDeclarationWorker(node: ts.EnumDeclaration) { // Grammar checking checkGrammarDecoratorsAndModifiers(node); @@ -40379,26 +39467,26 @@ namespace ts { // // Only perform this check once per symbol const enumSymbol = getSymbolOfNode(node); - const firstDeclaration = getDeclarationOfKind(enumSymbol, node.kind); + const firstDeclaration = ts.getDeclarationOfKind(enumSymbol, node.kind); if (node === firstDeclaration) { if (enumSymbol.declarations && enumSymbol.declarations.length > 1) { - const enumIsConst = isEnumConst(node); + const enumIsConst = ts.isEnumConst(node); // check that const is placed\omitted on all enum declarations - forEach(enumSymbol.declarations, decl => { - if (isEnumDeclaration(decl) && isEnumConst(decl) !== enumIsConst) { - error(getNameOfDeclaration(decl), Diagnostics.Enum_declarations_must_all_be_const_or_non_const); + ts.forEach(enumSymbol.declarations, decl => { + if (ts.isEnumDeclaration(decl) && ts.isEnumConst(decl) !== enumIsConst) { + error(ts.getNameOfDeclaration(decl), ts.Diagnostics.Enum_declarations_must_all_be_const_or_non_const); } }); } let seenEnumMissingInitialInitializer = false; - forEach(enumSymbol.declarations, declaration => { + ts.forEach(enumSymbol.declarations, declaration => { // return true if we hit a violation of the rule, false otherwise - if (declaration.kind !== SyntaxKind.EnumDeclaration) { + if (declaration.kind !== ts.SyntaxKind.EnumDeclaration) { return false; } - const enumDeclaration = declaration as EnumDeclaration; + const enumDeclaration = declaration as ts.EnumDeclaration; if (!enumDeclaration.members.length) { return false; } @@ -40406,7 +39494,7 @@ namespace ts { const firstEnumMember = enumDeclaration.members[0]; if (!firstEnumMember.initializer) { if (seenEnumMissingInitialInitializer) { - error(firstEnumMember.name, Diagnostics.In_an_enum_with_multiple_declarations_only_one_declaration_can_omit_an_initializer_for_its_first_enum_element); + error(firstEnumMember.name, ts.Diagnostics.In_an_enum_with_multiple_declarations_only_one_declaration_can_omit_an_initializer_for_its_first_enum_element); } else { seenEnumMissingInitialInitializer = true; @@ -40416,19 +39504,19 @@ namespace ts { } } - function checkEnumMember(node: EnumMember) { - if (isPrivateIdentifier(node.name)) { - error(node, Diagnostics.An_enum_member_cannot_be_named_with_a_private_identifier); + function checkEnumMember(node: ts.EnumMember) { + if (ts.isPrivateIdentifier(node.name)) { + error(node, ts.Diagnostics.An_enum_member_cannot_be_named_with_a_private_identifier); } } - function getFirstNonAmbientClassOrFunctionDeclaration(symbol: Symbol): Declaration | undefined { + function getFirstNonAmbientClassOrFunctionDeclaration(symbol: ts.Symbol): ts.Declaration | undefined { const declarations = symbol.declarations; if (declarations) { for (const declaration of declarations) { - if ((declaration.kind === SyntaxKind.ClassDeclaration || - (declaration.kind === SyntaxKind.FunctionDeclaration && nodeIsPresent((declaration as FunctionLikeDeclaration).body))) && - !(declaration.flags & NodeFlags.Ambient)) { + if ((declaration.kind === ts.SyntaxKind.ClassDeclaration || + (declaration.kind === ts.SyntaxKind.FunctionDeclaration && ts.nodeIsPresent((declaration as ts.FunctionLikeDeclaration).body))) && + !(declaration.flags & ts.NodeFlags.Ambient)) { return declaration; } } @@ -40436,9 +39524,9 @@ namespace ts { return undefined; } - function inSameLexicalScope(node1: Node, node2: Node) { - const container1 = getEnclosingBlockScopeContainer(node1); - const container2 = getEnclosingBlockScopeContainer(node2); + function inSameLexicalScope(node1: ts.Node, node2: ts.Node) { + const container1 = ts.getEnclosingBlockScopeContainer(node1); + const container2 = ts.getEnclosingBlockScopeContainer(node2); if (isGlobalSourceFile(container1)) { return isGlobalSourceFile(container2); } @@ -40450,10 +39538,10 @@ namespace ts { } } - function checkModuleDeclaration(node: ModuleDeclaration) { + function checkModuleDeclaration(node: ts.ModuleDeclaration) { if (node.body) { checkSourceElement(node.body); - if (!isGlobalScopeAugmentation(node)) { + if (!ts.isGlobalScopeAugmentation(node)) { registerForUnusedIdentifiersCheck(node); } } @@ -40462,28 +39550,28 @@ namespace ts { function checkModuleDeclarationDiagnostics() { // Grammar checking - const isGlobalAugmentation = isGlobalScopeAugmentation(node); - const inAmbientContext = node.flags & NodeFlags.Ambient; + const isGlobalAugmentation = ts.isGlobalScopeAugmentation(node); + const inAmbientContext = node.flags & ts.NodeFlags.Ambient; if (isGlobalAugmentation && !inAmbientContext) { - error(node.name, Diagnostics.Augmentations_for_the_global_scope_should_have_declare_modifier_unless_they_appear_in_already_ambient_context); + error(node.name, ts.Diagnostics.Augmentations_for_the_global_scope_should_have_declare_modifier_unless_they_appear_in_already_ambient_context); } - const isAmbientExternalModule: boolean = isAmbientModule(node); + const isAmbientExternalModule: boolean = ts.isAmbientModule(node); const contextErrorMessage = isAmbientExternalModule - ? Diagnostics.An_ambient_module_declaration_is_only_allowed_at_the_top_level_in_a_file - : Diagnostics.A_namespace_declaration_is_only_allowed_at_the_top_level_of_a_namespace_or_module; + ? ts.Diagnostics.An_ambient_module_declaration_is_only_allowed_at_the_top_level_in_a_file + : ts.Diagnostics.A_namespace_declaration_is_only_allowed_at_the_top_level_of_a_namespace_or_module; if (checkGrammarModuleElementContext(node, contextErrorMessage)) { // If we hit a module declaration in an illegal context, just bail out to avoid cascading errors. return; } if (!checkGrammarDecoratorsAndModifiers(node)) { - if (!inAmbientContext && node.name.kind === SyntaxKind.StringLiteral) { - grammarErrorOnNode(node.name, Diagnostics.Only_ambient_modules_can_use_quoted_names); + if (!inAmbientContext && node.name.kind === ts.SyntaxKind.StringLiteral) { + grammarErrorOnNode(node.name, ts.Diagnostics.Only_ambient_modules_can_use_quoted_names); } } - if (isIdentifier(node.name)) { + if (ts.isIdentifier(node.name)) { checkCollisionsForDeclarationName(node, node.name); } @@ -40491,38 +39579,38 @@ namespace ts { const symbol = getSymbolOfNode(node); // The following checks only apply on a non-ambient instantiated module declaration. - if (symbol.flags & SymbolFlags.ValueModule + if (symbol.flags & ts.SymbolFlags.ValueModule && !inAmbientContext && symbol.declarations && symbol.declarations.length > 1 - && isInstantiatedModule(node, shouldPreserveConstEnums(compilerOptions))) { + && isInstantiatedModule(node, ts.shouldPreserveConstEnums(compilerOptions))) { const firstNonAmbientClassOrFunc = getFirstNonAmbientClassOrFunctionDeclaration(symbol); if (firstNonAmbientClassOrFunc) { - if (getSourceFileOfNode(node) !== getSourceFileOfNode(firstNonAmbientClassOrFunc)) { - error(node.name, Diagnostics.A_namespace_declaration_cannot_be_in_a_different_file_from_a_class_or_function_with_which_it_is_merged); + if (ts.getSourceFileOfNode(node) !== ts.getSourceFileOfNode(firstNonAmbientClassOrFunc)) { + error(node.name, ts.Diagnostics.A_namespace_declaration_cannot_be_in_a_different_file_from_a_class_or_function_with_which_it_is_merged); } else if (node.pos < firstNonAmbientClassOrFunc.pos) { - error(node.name, Diagnostics.A_namespace_declaration_cannot_be_located_prior_to_a_class_or_function_with_which_it_is_merged); + error(node.name, ts.Diagnostics.A_namespace_declaration_cannot_be_located_prior_to_a_class_or_function_with_which_it_is_merged); } } // if the module merges with a class declaration in the same lexical scope, // we need to track this to ensure the correct emit. - const mergedClass = getDeclarationOfKind(symbol, SyntaxKind.ClassDeclaration); + const mergedClass = ts.getDeclarationOfKind(symbol, ts.SyntaxKind.ClassDeclaration); if (mergedClass && inSameLexicalScope(node, mergedClass)) { - getNodeLinks(node).flags |= NodeCheckFlags.LexicalModuleMergesWithClass; + getNodeLinks(node).flags |= ts.NodeCheckFlags.LexicalModuleMergesWithClass; } } if (isAmbientExternalModule) { - if (isExternalModuleAugmentation(node)) { + if (ts.isExternalModuleAugmentation(node)) { // body of the augmentation should be checked for consistency only if augmentation was applied to its target (either global scope or module) // otherwise we'll be swamped in cascading errors. // We can detect if augmentation was applied using following rules: // - augmentation for a global scope is always applied // - augmentation for some external module is applied if symbol for augmentation is merged (it was combined with target module). - const checkBody = isGlobalAugmentation || (getSymbolOfNode(node).flags & SymbolFlags.Transient); + const checkBody = isGlobalAugmentation || (getSymbolOfNode(node).flags & ts.SymbolFlags.Transient); if (checkBody && node.body) { for (const statement of node.body.statements) { checkModuleAugmentationElement(statement, isGlobalAugmentation); @@ -40531,46 +39619,46 @@ namespace ts { } else if (isGlobalSourceFile(node.parent)) { if (isGlobalAugmentation) { - error(node.name, Diagnostics.Augmentations_for_the_global_scope_can_only_be_directly_nested_in_external_modules_or_ambient_module_declarations); + error(node.name, ts.Diagnostics.Augmentations_for_the_global_scope_can_only_be_directly_nested_in_external_modules_or_ambient_module_declarations); } - else if (isExternalModuleNameRelative(getTextOfIdentifierOrLiteral(node.name))) { - error(node.name, Diagnostics.Ambient_module_declaration_cannot_specify_relative_module_name); + else if (ts.isExternalModuleNameRelative(ts.getTextOfIdentifierOrLiteral(node.name))) { + error(node.name, ts.Diagnostics.Ambient_module_declaration_cannot_specify_relative_module_name); } } else { if (isGlobalAugmentation) { - error(node.name, Diagnostics.Augmentations_for_the_global_scope_can_only_be_directly_nested_in_external_modules_or_ambient_module_declarations); + error(node.name, ts.Diagnostics.Augmentations_for_the_global_scope_can_only_be_directly_nested_in_external_modules_or_ambient_module_declarations); } else { // Node is not an augmentation and is not located on the script level. // This means that this is declaration of ambient module that is located in other module or namespace which is prohibited. - error(node.name, Diagnostics.Ambient_modules_cannot_be_nested_in_other_modules_or_namespaces); + error(node.name, ts.Diagnostics.Ambient_modules_cannot_be_nested_in_other_modules_or_namespaces); } } } } } - function checkModuleAugmentationElement(node: Node, isGlobalAugmentation: boolean): void { + function checkModuleAugmentationElement(node: ts.Node, isGlobalAugmentation: boolean): void { switch (node.kind) { - case SyntaxKind.VariableStatement: + case ts.SyntaxKind.VariableStatement: // error each individual name in variable statement instead of marking the entire variable statement - for (const decl of (node as VariableStatement).declarationList.declarations) { + for (const decl of (node as ts.VariableStatement).declarationList.declarations) { checkModuleAugmentationElement(decl, isGlobalAugmentation); } break; - case SyntaxKind.ExportAssignment: - case SyntaxKind.ExportDeclaration: - grammarErrorOnFirstToken(node, Diagnostics.Exports_and_export_assignments_are_not_permitted_in_module_augmentations); + case ts.SyntaxKind.ExportAssignment: + case ts.SyntaxKind.ExportDeclaration: + grammarErrorOnFirstToken(node, ts.Diagnostics.Exports_and_export_assignments_are_not_permitted_in_module_augmentations); break; - case SyntaxKind.ImportEqualsDeclaration: - case SyntaxKind.ImportDeclaration: - grammarErrorOnFirstToken(node, Diagnostics.Imports_are_not_permitted_in_module_augmentations_Consider_moving_them_to_the_enclosing_external_module); + case ts.SyntaxKind.ImportEqualsDeclaration: + case ts.SyntaxKind.ImportDeclaration: + grammarErrorOnFirstToken(node, ts.Diagnostics.Imports_are_not_permitted_in_module_augmentations_Consider_moving_them_to_the_enclosing_external_module); break; - case SyntaxKind.BindingElement: - case SyntaxKind.VariableDeclaration: - const name = (node as VariableDeclaration | BindingElement).name; - if (isBindingPattern(name)) { + case ts.SyntaxKind.BindingElement: + case ts.SyntaxKind.VariableDeclaration: + const name = (node as ts.VariableDeclaration | ts.BindingElement).name; + if (ts.isBindingPattern(name)) { for (const el of name.elements) { // mark individual names in binding pattern checkModuleAugmentationElement(el, isGlobalAugmentation); @@ -40578,12 +39666,12 @@ namespace ts { break; } // falls through - case SyntaxKind.ClassDeclaration: - case SyntaxKind.EnumDeclaration: - case SyntaxKind.FunctionDeclaration: - case SyntaxKind.InterfaceDeclaration: - case SyntaxKind.ModuleDeclaration: - case SyntaxKind.TypeAliasDeclaration: + case ts.SyntaxKind.ClassDeclaration: + case ts.SyntaxKind.EnumDeclaration: + case ts.SyntaxKind.FunctionDeclaration: + case ts.SyntaxKind.InterfaceDeclaration: + case ts.SyntaxKind.ModuleDeclaration: + case ts.SyntaxKind.TypeAliasDeclaration: if (isGlobalAugmentation) { return; } @@ -40593,54 +39681,54 @@ namespace ts { // this is done it two steps // 1. quick check - if symbol for node is not merged - this is local symbol to this augmentation - report error // 2. main check - report error if value declaration of the parent symbol is module augmentation) - let reportError = !(symbol.flags & SymbolFlags.Transient); + let reportError = !(symbol.flags & ts.SymbolFlags.Transient); if (!reportError) { // symbol should not originate in augmentation - reportError = !!symbol.parent?.declarations && isExternalModuleAugmentation(symbol.parent.declarations[0]); + reportError = !!symbol.parent?.declarations && ts.isExternalModuleAugmentation(symbol.parent.declarations[0]); } } break; } } - function getFirstNonModuleExportsIdentifier(node: EntityNameOrEntityNameExpression): Identifier { + function getFirstNonModuleExportsIdentifier(node: ts.EntityNameOrEntityNameExpression): ts.Identifier { switch (node.kind) { - case SyntaxKind.Identifier: + case ts.SyntaxKind.Identifier: return node; - case SyntaxKind.QualifiedName: + case ts.SyntaxKind.QualifiedName: do { node = node.left; - } while (node.kind !== SyntaxKind.Identifier); + } while (node.kind !== ts.SyntaxKind.Identifier); return node; - case SyntaxKind.PropertyAccessExpression: + case ts.SyntaxKind.PropertyAccessExpression: do { - if (isModuleExportsAccessExpression(node.expression) && !isPrivateIdentifier(node.name)) { + if (ts.isModuleExportsAccessExpression(node.expression) && !ts.isPrivateIdentifier(node.name)) { return node.name; } node = node.expression; - } while (node.kind !== SyntaxKind.Identifier); + } while (node.kind !== ts.SyntaxKind.Identifier); return node; } } - function checkExternalImportOrExportDeclaration(node: ImportDeclaration | ImportEqualsDeclaration | ExportDeclaration): boolean { - const moduleName = getExternalModuleName(node); - if (!moduleName || nodeIsMissing(moduleName)) { + function checkExternalImportOrExportDeclaration(node: ts.ImportDeclaration | ts.ImportEqualsDeclaration | ts.ExportDeclaration): boolean { + const moduleName = ts.getExternalModuleName(node); + if (!moduleName || ts.nodeIsMissing(moduleName)) { // Should be a parse error. return false; } - if (!isStringLiteral(moduleName)) { - error(moduleName, Diagnostics.String_literal_expected); + if (!ts.isStringLiteral(moduleName)) { + error(moduleName, ts.Diagnostics.String_literal_expected); return false; } - const inAmbientExternalModule = node.parent.kind === SyntaxKind.ModuleBlock && isAmbientModule(node.parent.parent); - if (node.parent.kind !== SyntaxKind.SourceFile && !inAmbientExternalModule) { - error(moduleName, node.kind === SyntaxKind.ExportDeclaration ? - Diagnostics.Export_declarations_are_not_permitted_in_a_namespace : - Diagnostics.Import_declarations_in_a_namespace_cannot_reference_a_module); + const inAmbientExternalModule = node.parent.kind === ts.SyntaxKind.ModuleBlock && ts.isAmbientModule(node.parent.parent); + if (node.parent.kind !== ts.SyntaxKind.SourceFile && !inAmbientExternalModule) { + error(moduleName, node.kind === ts.SyntaxKind.ExportDeclaration ? + ts.Diagnostics.Export_declarations_are_not_permitted_in_a_namespace : + ts.Diagnostics.Import_declarations_in_a_namespace_cannot_reference_a_module); return false; } - if (inAmbientExternalModule && isExternalModuleNameRelative(moduleName.text)) { + if (inAmbientExternalModule && ts.isExternalModuleNameRelative(moduleName.text)) { // we have already reported errors on top level imports/exports in external module augmentations in checkModuleDeclaration // no need to do this again. if (!isTopLevelInExternalModuleAugmentation(node)) { @@ -40648,16 +39736,16 @@ namespace ts { // An ExternalImportDeclaration in an AmbientExternalModuleDeclaration may reference // other external modules only through top - level external module names. // Relative external module names are not permitted. - error(node, Diagnostics.Import_or_export_declaration_in_an_ambient_module_declaration_cannot_reference_module_through_relative_module_name); + error(node, ts.Diagnostics.Import_or_export_declaration_in_an_ambient_module_declaration_cannot_reference_module_through_relative_module_name); return false; } } - if (!isImportEqualsDeclaration(node) && node.assertClause) { + if (!ts.isImportEqualsDeclaration(node) && node.assertClause) { let hasError = false; for (const clause of node.assertClause.elements) { - if (!isStringLiteral(clause.value)) { + if (!ts.isStringLiteral(clause.value)) { hasError = true; - error(clause.value, Diagnostics.Import_assertion_values_must_be_string_literal_expressions); + error(clause.value, ts.Diagnostics.Import_assertion_values_must_be_string_literal_expressions); } } return !hasError; @@ -40665,7 +39753,7 @@ namespace ts { return true; } - function checkAliasSymbol(node: ImportEqualsDeclaration | VariableDeclaration | ImportClause | NamespaceImport | ImportSpecifier | ExportSpecifier | NamespaceExport) { + function checkAliasSymbol(node: ts.ImportEqualsDeclaration | ts.VariableDeclaration | ts.ImportClause | ts.NamespaceImport | ts.ImportSpecifier | ts.ExportSpecifier | ts.NamespaceExport) { let symbol = getSymbolOfNode(node); const target = resolveAlias(symbol); @@ -40677,58 +39765,49 @@ namespace ts { // otherwise it will conflict with some local declaration). Note that in addition to normal flags we include matching SymbolFlags.Export* // in order to prevent collisions with declarations that were exported from the current module (they still contribute to local names). symbol = getMergedSymbol(symbol.exportSymbol || symbol); - const excludedMeanings = - (symbol.flags & (SymbolFlags.Value | SymbolFlags.ExportValue) ? SymbolFlags.Value : 0) | - (symbol.flags & SymbolFlags.Type ? SymbolFlags.Type : 0) | - (symbol.flags & SymbolFlags.Namespace ? SymbolFlags.Namespace : 0); + const excludedMeanings = (symbol.flags & (ts.SymbolFlags.Value | ts.SymbolFlags.ExportValue) ? ts.SymbolFlags.Value : 0) | + (symbol.flags & ts.SymbolFlags.Type ? ts.SymbolFlags.Type : 0) | + (symbol.flags & ts.SymbolFlags.Namespace ? ts.SymbolFlags.Namespace : 0); if (target.flags & excludedMeanings) { - const message = node.kind === SyntaxKind.ExportSpecifier ? - Diagnostics.Export_declaration_conflicts_with_exported_declaration_of_0 : - Diagnostics.Import_declaration_conflicts_with_local_declaration_of_0; + const message = node.kind === ts.SyntaxKind.ExportSpecifier ? + ts.Diagnostics.Export_declaration_conflicts_with_exported_declaration_of_0 : + ts.Diagnostics.Import_declaration_conflicts_with_local_declaration_of_0; error(node, message, symbolToString(symbol)); } if (compilerOptions.isolatedModules - && !isTypeOnlyImportOrExportDeclaration(node) - && !(node.flags & NodeFlags.Ambient)) { + && !ts.isTypeOnlyImportOrExportDeclaration(node) + && !(node.flags & ts.NodeFlags.Ambient)) { const typeOnlyAlias = getTypeOnlyAliasDeclaration(symbol); - const isType = !(target.flags & SymbolFlags.Value); + const isType = !(target.flags & ts.SymbolFlags.Value); if (isType || typeOnlyAlias) { switch (node.kind) { - case SyntaxKind.ImportClause: - case SyntaxKind.ImportSpecifier: - case SyntaxKind.ImportEqualsDeclaration: { + case ts.SyntaxKind.ImportClause: + case ts.SyntaxKind.ImportSpecifier: + case ts.SyntaxKind.ImportEqualsDeclaration: { if (compilerOptions.preserveValueImports) { - Debug.assertIsDefined(node.name, "An ImportClause with a symbol should have a name"); + ts.Debug.assertIsDefined(node.name, "An ImportClause with a symbol should have a name"); const message = isType - ? Diagnostics._0_is_a_type_and_must_be_imported_using_a_type_only_import_when_preserveValueImports_and_isolatedModules_are_both_enabled - : Diagnostics._0_resolves_to_a_type_only_declaration_and_must_be_imported_using_a_type_only_import_when_preserveValueImports_and_isolatedModules_are_both_enabled; - const name = idText(node.kind === SyntaxKind.ImportSpecifier ? node.propertyName || node.name : node.name); - addTypeOnlyDeclarationRelatedInfo( - error(node, message, name), - isType ? undefined : typeOnlyAlias, - name - ); + ? ts.Diagnostics._0_is_a_type_and_must_be_imported_using_a_type_only_import_when_preserveValueImports_and_isolatedModules_are_both_enabled + : ts.Diagnostics._0_resolves_to_a_type_only_declaration_and_must_be_imported_using_a_type_only_import_when_preserveValueImports_and_isolatedModules_are_both_enabled; + const name = ts.idText(node.kind === ts.SyntaxKind.ImportSpecifier ? node.propertyName || node.name : node.name); + addTypeOnlyDeclarationRelatedInfo(error(node, message, name), isType ? undefined : typeOnlyAlias, name); } - if (isType && node.kind === SyntaxKind.ImportEqualsDeclaration && hasEffectiveModifier(node, ModifierFlags.Export)) { - error(node, Diagnostics.Cannot_use_export_import_on_a_type_or_type_only_namespace_when_the_isolatedModules_flag_is_provided); + if (isType && node.kind === ts.SyntaxKind.ImportEqualsDeclaration && ts.hasEffectiveModifier(node, ts.ModifierFlags.Export)) { + error(node, ts.Diagnostics.Cannot_use_export_import_on_a_type_or_type_only_namespace_when_the_isolatedModules_flag_is_provided); } break; } - case SyntaxKind.ExportSpecifier: { + case ts.SyntaxKind.ExportSpecifier: { // Don't allow re-exporting an export that will be elided when `--isolatedModules` is set. // The exception is that `import type { A } from './a'; export { A }` is allowed // because single-file analysis can determine that the export should be dropped. - if (getSourceFileOfNode(typeOnlyAlias) !== getSourceFileOfNode(node)) { + if (ts.getSourceFileOfNode(typeOnlyAlias) !== ts.getSourceFileOfNode(node)) { const message = isType - ? Diagnostics.Re_exporting_a_type_when_the_isolatedModules_flag_is_provided_requires_using_export_type - : Diagnostics._0_resolves_to_a_type_only_declaration_and_must_be_re_exported_using_a_type_only_re_export_when_isolatedModules_is_enabled; - const name = idText(node.propertyName || node.name); - addTypeOnlyDeclarationRelatedInfo( - error(node, message, name), - isType ? undefined : typeOnlyAlias, - name - ); + ? ts.Diagnostics.Re_exporting_a_type_when_the_isolatedModules_flag_is_provided_requires_using_export_type + : ts.Diagnostics._0_resolves_to_a_type_only_declaration_and_must_be_re_exported_using_a_type_only_re_export_when_isolatedModules_is_enabled; + const name = ts.idText(node.propertyName || node.name); + addTypeOnlyDeclarationRelatedInfo(error(node, message, name), isType ? undefined : typeOnlyAlias, name); return; } } @@ -40736,7 +39815,7 @@ namespace ts { } } - if (isImportSpecifier(node)) { + if (ts.isImportSpecifier(node)) { const targetSymbol = checkDeprecatedAliasedSymbol(symbol, node); if (isDeprecatedAliasedSymbol(targetSymbol) && targetSymbol.declarations) { addDeprecatedSuggestion(node, targetSymbol.declarations, targetSymbol.escapedName as string); @@ -40745,27 +39824,30 @@ namespace ts { } } - function isDeprecatedAliasedSymbol(symbol: Symbol) { - return !!symbol.declarations && every(symbol.declarations, d => !!(getCombinedNodeFlags(d) & NodeFlags.Deprecated)); + function isDeprecatedAliasedSymbol(symbol: ts.Symbol) { + return !!symbol.declarations && ts.every(symbol.declarations, d => !!(ts.getCombinedNodeFlags(d) & ts.NodeFlags.Deprecated)); } - function checkDeprecatedAliasedSymbol(symbol: Symbol, location: Node) { - if (!(symbol.flags & SymbolFlags.Alias)) return symbol; + function checkDeprecatedAliasedSymbol(symbol: ts.Symbol, location: ts.Node) { + if (!(symbol.flags & ts.SymbolFlags.Alias)) + return symbol; const targetSymbol = resolveAlias(symbol); - if (targetSymbol === unknownSymbol) return targetSymbol; - - while (symbol.flags & SymbolFlags.Alias) { + if (targetSymbol === unknownSymbol) + return targetSymbol; + while (symbol.flags & ts.SymbolFlags.Alias) { const target = getImmediateAliasedSymbol(symbol); if (target) { - if (target === targetSymbol) break; - if (target.declarations && length(target.declarations)) { + if (target === targetSymbol) + break; + if (target.declarations && ts.length(target.declarations)) { if (isDeprecatedAliasedSymbol(target)) { addDeprecatedSuggestion(location, target.declarations, target.escapedName as string); break; } else { - if (symbol === targetSymbol) break; + if (symbol === targetSymbol) + break; symbol = target; } } @@ -40777,57 +39859,56 @@ namespace ts { return targetSymbol; } - function checkImportBinding(node: ImportEqualsDeclaration | ImportClause | NamespaceImport | ImportSpecifier) { + function checkImportBinding(node: ts.ImportEqualsDeclaration | ts.ImportClause | ts.NamespaceImport | ts.ImportSpecifier) { checkCollisionsForDeclarationName(node, node.name); checkAliasSymbol(node); - if (node.kind === SyntaxKind.ImportSpecifier && - idText(node.propertyName || node.name) === "default" && - getESModuleInterop(compilerOptions) && - moduleKind !== ModuleKind.System && (moduleKind < ModuleKind.ES2015 || getSourceFileOfNode(node).impliedNodeFormat === ModuleKind.CommonJS)) { - checkExternalEmitHelpers(node, ExternalEmitHelpers.ImportDefault); + if (node.kind === ts.SyntaxKind.ImportSpecifier && + ts.idText(node.propertyName || node.name) === "default" && + ts.getESModuleInterop(compilerOptions) && + moduleKind !== ts.ModuleKind.System && (moduleKind < ts.ModuleKind.ES2015 || ts.getSourceFileOfNode(node).impliedNodeFormat === ts.ModuleKind.CommonJS)) { + checkExternalEmitHelpers(node, ts.ExternalEmitHelpers.ImportDefault); } } - function checkAssertClause(declaration: ImportDeclaration | ExportDeclaration) { + function checkAssertClause(declaration: ts.ImportDeclaration | ts.ExportDeclaration) { if (declaration.assertClause) { - const validForTypeAssertions = isExclusivelyTypeOnlyImportOrExport(declaration); - const override = getResolutionModeOverrideForClause(declaration.assertClause, validForTypeAssertions ? grammarErrorOnNode : undefined); + const validForTypeAssertions = ts.isExclusivelyTypeOnlyImportOrExport(declaration); + const override = ts.getResolutionModeOverrideForClause(declaration.assertClause, validForTypeAssertions ? grammarErrorOnNode : undefined); if (validForTypeAssertions && override) { - if (!isNightly()) { - grammarErrorOnNode(declaration.assertClause, Diagnostics.Resolution_mode_assertions_are_unstable_Use_nightly_TypeScript_to_silence_this_error_Try_updating_with_npm_install_D_typescript_next); + if (!ts.isNightly()) { + grammarErrorOnNode(declaration.assertClause, ts.Diagnostics.Resolution_mode_assertions_are_unstable_Use_nightly_TypeScript_to_silence_this_error_Try_updating_with_npm_install_D_typescript_next); } - if (getEmitModuleResolutionKind(compilerOptions) !== ModuleResolutionKind.Node16 && getEmitModuleResolutionKind(compilerOptions) !== ModuleResolutionKind.NodeNext) { - return grammarErrorOnNode(declaration.assertClause, Diagnostics.Resolution_modes_are_only_supported_when_moduleResolution_is_node16_or_nodenext); + if (ts.getEmitModuleResolutionKind(compilerOptions) !== ts.ModuleResolutionKind.Node16 && ts.getEmitModuleResolutionKind(compilerOptions) !== ts.ModuleResolutionKind.NodeNext) { + return grammarErrorOnNode(declaration.assertClause, ts.Diagnostics.Resolution_modes_are_only_supported_when_moduleResolution_is_node16_or_nodenext); } return; // Other grammar checks do not apply to type-only imports with resolution mode assertions } - const mode = (moduleKind === ModuleKind.NodeNext) && declaration.moduleSpecifier && getUsageModeForExpression(declaration.moduleSpecifier); - if (mode !== ModuleKind.ESNext && moduleKind !== ModuleKind.ESNext) { - return grammarErrorOnNode(declaration.assertClause, - moduleKind === ModuleKind.NodeNext - ? Diagnostics.Import_assertions_are_not_allowed_on_statements_that_transpile_to_commonjs_require_calls - : Diagnostics.Import_assertions_are_only_supported_when_the_module_option_is_set_to_esnext_or_nodenext); + const mode = (moduleKind === ts.ModuleKind.NodeNext) && declaration.moduleSpecifier && getUsageModeForExpression(declaration.moduleSpecifier); + if (mode !== ts.ModuleKind.ESNext && moduleKind !== ts.ModuleKind.ESNext) { + return grammarErrorOnNode(declaration.assertClause, moduleKind === ts.ModuleKind.NodeNext + ? ts.Diagnostics.Import_assertions_are_not_allowed_on_statements_that_transpile_to_commonjs_require_calls + : ts.Diagnostics.Import_assertions_are_only_supported_when_the_module_option_is_set_to_esnext_or_nodenext); } - if (isImportDeclaration(declaration) ? declaration.importClause?.isTypeOnly : declaration.isTypeOnly) { - return grammarErrorOnNode(declaration.assertClause, Diagnostics.Import_assertions_cannot_be_used_with_type_only_imports_or_exports); + if (ts.isImportDeclaration(declaration) ? declaration.importClause?.isTypeOnly : declaration.isTypeOnly) { + return grammarErrorOnNode(declaration.assertClause, ts.Diagnostics.Import_assertions_cannot_be_used_with_type_only_imports_or_exports); } if (override) { - return grammarErrorOnNode(declaration.assertClause, Diagnostics.resolution_mode_can_only_be_set_for_type_only_imports); + return grammarErrorOnNode(declaration.assertClause, ts.Diagnostics.resolution_mode_can_only_be_set_for_type_only_imports); } } } - function checkImportDeclaration(node: ImportDeclaration) { - if (checkGrammarModuleElementContext(node, isInJSFile(node) ? Diagnostics.An_import_declaration_can_only_be_used_at_the_top_level_of_a_module : Diagnostics.An_import_declaration_can_only_be_used_at_the_top_level_of_a_namespace_or_module)) { + function checkImportDeclaration(node: ts.ImportDeclaration) { + if (checkGrammarModuleElementContext(node, ts.isInJSFile(node) ? ts.Diagnostics.An_import_declaration_can_only_be_used_at_the_top_level_of_a_module : ts.Diagnostics.An_import_declaration_can_only_be_used_at_the_top_level_of_a_namespace_or_module)) { // If we hit an import declaration in an illegal context, just bail out to avoid cascading errors. return; } - if (!checkGrammarDecoratorsAndModifiers(node) && hasEffectiveModifiers(node)) { - grammarErrorOnFirstToken(node, Diagnostics.An_import_declaration_cannot_have_modifiers); + if (!checkGrammarDecoratorsAndModifiers(node) && ts.hasEffectiveModifiers(node)) { + grammarErrorOnFirstToken(node, ts.Diagnostics.An_import_declaration_cannot_have_modifiers); } if (checkExternalImportOrExportDeclaration(node)) { const importClause = node.importClause; @@ -40836,17 +39917,17 @@ namespace ts { checkImportBinding(importClause); } if (importClause.namedBindings) { - if (importClause.namedBindings.kind === SyntaxKind.NamespaceImport) { + if (importClause.namedBindings.kind === ts.SyntaxKind.NamespaceImport) { checkImportBinding(importClause.namedBindings); - if (moduleKind !== ModuleKind.System && (moduleKind < ModuleKind.ES2015 || getSourceFileOfNode(node).impliedNodeFormat === ModuleKind.CommonJS) && getESModuleInterop(compilerOptions)) { + if (moduleKind !== ts.ModuleKind.System && (moduleKind < ts.ModuleKind.ES2015 || ts.getSourceFileOfNode(node).impliedNodeFormat === ts.ModuleKind.CommonJS) && ts.getESModuleInterop(compilerOptions)) { // import * as ns from "foo"; - checkExternalEmitHelpers(node, ExternalEmitHelpers.ImportStar); + checkExternalEmitHelpers(node, ts.ExternalEmitHelpers.ImportStar); } } else { const moduleExisted = resolveExternalModuleName(node, node.moduleSpecifier); if (moduleExisted) { - forEach(importClause.namedBindings.elements, checkImportBinding); + ts.forEach(importClause.namedBindings.elements, checkImportBinding); } } } @@ -40855,70 +39936,70 @@ namespace ts { checkAssertClause(node); } - function checkImportEqualsDeclaration(node: ImportEqualsDeclaration) { - if (checkGrammarModuleElementContext(node, isInJSFile(node) ? Diagnostics.An_import_declaration_can_only_be_used_at_the_top_level_of_a_module : Diagnostics.An_import_declaration_can_only_be_used_at_the_top_level_of_a_namespace_or_module)) { + function checkImportEqualsDeclaration(node: ts.ImportEqualsDeclaration) { + if (checkGrammarModuleElementContext(node, ts.isInJSFile(node) ? ts.Diagnostics.An_import_declaration_can_only_be_used_at_the_top_level_of_a_module : ts.Diagnostics.An_import_declaration_can_only_be_used_at_the_top_level_of_a_namespace_or_module)) { // If we hit an import declaration in an illegal context, just bail out to avoid cascading errors. return; } checkGrammarDecoratorsAndModifiers(node); - if (isInternalModuleImportEqualsDeclaration(node) || checkExternalImportOrExportDeclaration(node)) { + if (ts.isInternalModuleImportEqualsDeclaration(node) || checkExternalImportOrExportDeclaration(node)) { checkImportBinding(node); - if (hasSyntacticModifier(node, ModifierFlags.Export)) { + if (ts.hasSyntacticModifier(node, ts.ModifierFlags.Export)) { markExportAsReferenced(node); } - if (node.moduleReference.kind !== SyntaxKind.ExternalModuleReference) { + if (node.moduleReference.kind !== ts.SyntaxKind.ExternalModuleReference) { const target = resolveAlias(getSymbolOfNode(node)); if (target !== unknownSymbol) { - if (target.flags & SymbolFlags.Value) { + if (target.flags & ts.SymbolFlags.Value) { // Target is a value symbol, check that it is not hidden by a local declaration with the same name - const moduleName = getFirstIdentifier(node.moduleReference); - if (!(resolveEntityName(moduleName, SymbolFlags.Value | SymbolFlags.Namespace)!.flags & SymbolFlags.Namespace)) { - error(moduleName, Diagnostics.Module_0_is_hidden_by_a_local_declaration_with_the_same_name, declarationNameToString(moduleName)); + const moduleName = ts.getFirstIdentifier(node.moduleReference); + if (!(resolveEntityName(moduleName, ts.SymbolFlags.Value | ts.SymbolFlags.Namespace)!.flags & ts.SymbolFlags.Namespace)) { + error(moduleName, ts.Diagnostics.Module_0_is_hidden_by_a_local_declaration_with_the_same_name, ts.declarationNameToString(moduleName)); } } - if (target.flags & SymbolFlags.Type) { - checkTypeNameIsReserved(node.name, Diagnostics.Import_name_cannot_be_0); + if (target.flags & ts.SymbolFlags.Type) { + checkTypeNameIsReserved(node.name, ts.Diagnostics.Import_name_cannot_be_0); } } if (node.isTypeOnly) { - grammarErrorOnNode(node, Diagnostics.An_import_alias_cannot_use_import_type); + grammarErrorOnNode(node, ts.Diagnostics.An_import_alias_cannot_use_import_type); } } else { - if (moduleKind >= ModuleKind.ES2015 && getSourceFileOfNode(node).impliedNodeFormat === undefined && !node.isTypeOnly && !(node.flags & NodeFlags.Ambient)) { + if (moduleKind >= ts.ModuleKind.ES2015 && ts.getSourceFileOfNode(node).impliedNodeFormat === undefined && !node.isTypeOnly && !(node.flags & ts.NodeFlags.Ambient)) { // Import equals declaration is deprecated in es6 or above - grammarErrorOnNode(node, Diagnostics.Import_assignment_cannot_be_used_when_targeting_ECMAScript_modules_Consider_using_import_Asterisk_as_ns_from_mod_import_a_from_mod_import_d_from_mod_or_another_module_format_instead); + grammarErrorOnNode(node, ts.Diagnostics.Import_assignment_cannot_be_used_when_targeting_ECMAScript_modules_Consider_using_import_Asterisk_as_ns_from_mod_import_a_from_mod_import_d_from_mod_or_another_module_format_instead); } } } } - function checkExportDeclaration(node: ExportDeclaration) { - if (checkGrammarModuleElementContext(node, isInJSFile(node) ? Diagnostics.An_export_declaration_can_only_be_used_at_the_top_level_of_a_module : Diagnostics.An_export_declaration_can_only_be_used_at_the_top_level_of_a_namespace_or_module)) { + function checkExportDeclaration(node: ts.ExportDeclaration) { + if (checkGrammarModuleElementContext(node, ts.isInJSFile(node) ? ts.Diagnostics.An_export_declaration_can_only_be_used_at_the_top_level_of_a_module : ts.Diagnostics.An_export_declaration_can_only_be_used_at_the_top_level_of_a_namespace_or_module)) { // If we hit an export in an illegal context, just bail out to avoid cascading errors. return; } - if (!checkGrammarDecoratorsAndModifiers(node) && hasSyntacticModifiers(node)) { - grammarErrorOnFirstToken(node, Diagnostics.An_export_declaration_cannot_have_modifiers); + if (!checkGrammarDecoratorsAndModifiers(node) && ts.hasSyntacticModifiers(node)) { + grammarErrorOnFirstToken(node, ts.Diagnostics.An_export_declaration_cannot_have_modifiers); } - if (node.moduleSpecifier && node.exportClause && isNamedExports(node.exportClause) && length(node.exportClause.elements) && languageVersion === ScriptTarget.ES3) { - checkExternalEmitHelpers(node, ExternalEmitHelpers.CreateBinding); + if (node.moduleSpecifier && node.exportClause && ts.isNamedExports(node.exportClause) && ts.length(node.exportClause.elements) && languageVersion === ts.ScriptTarget.ES3) { + checkExternalEmitHelpers(node, ts.ExternalEmitHelpers.CreateBinding); } checkGrammarExportDeclaration(node); if (!node.moduleSpecifier || checkExternalImportOrExportDeclaration(node)) { - if (node.exportClause && !isNamespaceExport(node.exportClause)) { + if (node.exportClause && !ts.isNamespaceExport(node.exportClause)) { // export { x, y } // export { x, y } from "foo" - forEach(node.exportClause.elements, checkExportSpecifier); - const inAmbientExternalModule = node.parent.kind === SyntaxKind.ModuleBlock && isAmbientModule(node.parent.parent); - const inAmbientNamespaceDeclaration = !inAmbientExternalModule && node.parent.kind === SyntaxKind.ModuleBlock && - !node.moduleSpecifier && node.flags & NodeFlags.Ambient; - if (node.parent.kind !== SyntaxKind.SourceFile && !inAmbientExternalModule && !inAmbientNamespaceDeclaration) { - error(node, Diagnostics.Export_declarations_are_not_permitted_in_a_namespace); + ts.forEach(node.exportClause.elements, checkExportSpecifier); + const inAmbientExternalModule = node.parent.kind === ts.SyntaxKind.ModuleBlock && ts.isAmbientModule(node.parent.parent); + const inAmbientNamespaceDeclaration = !inAmbientExternalModule && node.parent.kind === ts.SyntaxKind.ModuleBlock && + !node.moduleSpecifier && node.flags & ts.NodeFlags.Ambient; + if (node.parent.kind !== ts.SyntaxKind.SourceFile && !inAmbientExternalModule && !inAmbientNamespaceDeclaration) { + error(node, ts.Diagnostics.Export_declarations_are_not_permitted_in_a_namespace); } } else { @@ -40926,23 +40007,23 @@ namespace ts { // export * as ns from "foo"; const moduleSymbol = resolveExternalModuleName(node, node.moduleSpecifier!); if (moduleSymbol && hasExportAssignmentSymbol(moduleSymbol)) { - error(node.moduleSpecifier, Diagnostics.Module_0_uses_export_and_cannot_be_used_with_export_Asterisk, symbolToString(moduleSymbol)); + error(node.moduleSpecifier, ts.Diagnostics.Module_0_uses_export_and_cannot_be_used_with_export_Asterisk, symbolToString(moduleSymbol)); } else if (node.exportClause) { checkAliasSymbol(node.exportClause); } - if (moduleKind !== ModuleKind.System && (moduleKind < ModuleKind.ES2015 || getSourceFileOfNode(node).impliedNodeFormat === ModuleKind.CommonJS)) { + if (moduleKind !== ts.ModuleKind.System && (moduleKind < ts.ModuleKind.ES2015 || ts.getSourceFileOfNode(node).impliedNodeFormat === ts.ModuleKind.CommonJS)) { if (node.exportClause) { // export * as ns from "foo"; // For ES2015 modules, we emit it as a pair of `import * as a_1 ...; export { a_1 as ns }` and don't need the helper. // We only use the helper here when in esModuleInterop - if (getESModuleInterop(compilerOptions)) { - checkExternalEmitHelpers(node, ExternalEmitHelpers.ImportStar); + if (ts.getESModuleInterop(compilerOptions)) { + checkExternalEmitHelpers(node, ts.ExternalEmitHelpers.ImportStar); } } else { // export * from "foo" - checkExternalEmitHelpers(node, ExternalEmitHelpers.ExportStar); + checkExternalEmitHelpers(node, ts.ExternalEmitHelpers.ExportStar); } } } @@ -40950,40 +40031,40 @@ namespace ts { checkAssertClause(node); } - function checkGrammarExportDeclaration(node: ExportDeclaration): boolean { + function checkGrammarExportDeclaration(node: ts.ExportDeclaration): boolean { if (node.isTypeOnly) { - if (node.exportClause?.kind === SyntaxKind.NamedExports) { + if (node.exportClause?.kind === ts.SyntaxKind.NamedExports) { return checkGrammarNamedImportsOrExports(node.exportClause); } else { - return grammarErrorOnNode(node, Diagnostics.Only_named_exports_may_use_export_type); + return grammarErrorOnNode(node, ts.Diagnostics.Only_named_exports_may_use_export_type); } } return false; } - function checkGrammarModuleElementContext(node: Statement, errorMessage: DiagnosticMessage): boolean { - const isInAppropriateContext = node.parent.kind === SyntaxKind.SourceFile || node.parent.kind === SyntaxKind.ModuleBlock || node.parent.kind === SyntaxKind.ModuleDeclaration; + function checkGrammarModuleElementContext(node: ts.Statement, errorMessage: ts.DiagnosticMessage): boolean { + const isInAppropriateContext = node.parent.kind === ts.SyntaxKind.SourceFile || node.parent.kind === ts.SyntaxKind.ModuleBlock || node.parent.kind === ts.SyntaxKind.ModuleDeclaration; if (!isInAppropriateContext) { grammarErrorOnFirstToken(node, errorMessage); } return !isInAppropriateContext; } - function importClauseContainsReferencedImport(importClause: ImportClause) { - return forEachImportClauseDeclaration(importClause, declaration => { + function importClauseContainsReferencedImport(importClause: ts.ImportClause) { + return ts.forEachImportClauseDeclaration(importClause, declaration => { return !!getSymbolOfNode(declaration).isReferenced; }); } - function importClauseContainsConstEnumUsedAsValue(importClause: ImportClause) { - return forEachImportClauseDeclaration(importClause, declaration => { + function importClauseContainsConstEnumUsedAsValue(importClause: ts.ImportClause) { + return ts.forEachImportClauseDeclaration(importClause, declaration => { return !!getSymbolLinks(getSymbolOfNode(declaration)).constEnumReferenced; }); } - function canConvertImportDeclarationToTypeOnly(statement: Statement) { - return isImportDeclaration(statement) && + function canConvertImportDeclarationToTypeOnly(statement: ts.Statement) { + return ts.isImportDeclaration(statement) && statement.importClause && !statement.importClause.isTypeOnly && importClauseContainsReferencedImport(statement.importClause) && @@ -40991,94 +40072,92 @@ namespace ts { !importClauseContainsConstEnumUsedAsValue(statement.importClause); } - function canConvertImportEqualsDeclarationToTypeOnly(statement: Statement) { - return isImportEqualsDeclaration(statement) && - isExternalModuleReference(statement.moduleReference) && + function canConvertImportEqualsDeclarationToTypeOnly(statement: ts.Statement) { + return ts.isImportEqualsDeclaration(statement) && + ts.isExternalModuleReference(statement.moduleReference) && !statement.isTypeOnly && getSymbolOfNode(statement).isReferenced && !isReferencedAliasDeclaration(statement, /*checkChildren*/ false) && !getSymbolLinks(getSymbolOfNode(statement)).constEnumReferenced; } - function checkImportsForTypeOnlyConversion(sourceFile: SourceFile) { + function checkImportsForTypeOnlyConversion(sourceFile: ts.SourceFile) { for (const statement of sourceFile.statements) { if (canConvertImportDeclarationToTypeOnly(statement) || canConvertImportEqualsDeclarationToTypeOnly(statement)) { - error( - statement, - Diagnostics.This_import_is_never_used_as_a_value_and_must_use_import_type_because_importsNotUsedAsValues_is_set_to_error); + error(statement, ts.Diagnostics.This_import_is_never_used_as_a_value_and_must_use_import_type_because_importsNotUsedAsValues_is_set_to_error); } } } - function checkExportSpecifier(node: ExportSpecifier) { + function checkExportSpecifier(node: ts.ExportSpecifier) { checkAliasSymbol(node); - if (getEmitDeclarations(compilerOptions)) { + if (ts.getEmitDeclarations(compilerOptions)) { collectLinkedAliases(node.propertyName || node.name, /*setVisibility*/ true); } if (!node.parent.parent.moduleSpecifier) { const exportedName = node.propertyName || node.name; // find immediate value referenced by exported name (SymbolFlags.Alias is set so we don't chase down aliases) - const symbol = resolveName(exportedName, exportedName.escapedText, SymbolFlags.Value | SymbolFlags.Type | SymbolFlags.Namespace | SymbolFlags.Alias, + const symbol = resolveName(exportedName, exportedName.escapedText, ts.SymbolFlags.Value | ts.SymbolFlags.Type | ts.SymbolFlags.Namespace | ts.SymbolFlags.Alias, /*nameNotFoundMessage*/ undefined, /*nameArg*/ undefined, /*isUse*/ true); if (symbol && (symbol === undefinedSymbol || symbol === globalThisSymbol || symbol.declarations && isGlobalSourceFile(getDeclarationContainer(symbol.declarations[0])))) { - error(exportedName, Diagnostics.Cannot_export_0_Only_local_declarations_can_be_exported_from_a_module, idText(exportedName)); + error(exportedName, ts.Diagnostics.Cannot_export_0_Only_local_declarations_can_be_exported_from_a_module, ts.idText(exportedName)); } else { markExportAsReferenced(node); - const target = symbol && (symbol.flags & SymbolFlags.Alias ? resolveAlias(symbol) : symbol); - if (!target || target === unknownSymbol || target.flags & SymbolFlags.Value) { + const target = symbol && (symbol.flags & ts.SymbolFlags.Alias ? resolveAlias(symbol) : symbol); + if (!target || target === unknownSymbol || target.flags & ts.SymbolFlags.Value) { checkExpressionCached(node.propertyName || node.name); } } } else { - if (getESModuleInterop(compilerOptions) && - moduleKind !== ModuleKind.System && - (moduleKind < ModuleKind.ES2015 || getSourceFileOfNode(node).impliedNodeFormat === ModuleKind.CommonJS) && - idText(node.propertyName || node.name) === "default") { - checkExternalEmitHelpers(node, ExternalEmitHelpers.ImportDefault); + if (ts.getESModuleInterop(compilerOptions) && + moduleKind !== ts.ModuleKind.System && + (moduleKind < ts.ModuleKind.ES2015 || ts.getSourceFileOfNode(node).impliedNodeFormat === ts.ModuleKind.CommonJS) && + ts.idText(node.propertyName || node.name) === "default") { + checkExternalEmitHelpers(node, ts.ExternalEmitHelpers.ImportDefault); } } } - function checkExportAssignment(node: ExportAssignment) { + function checkExportAssignment(node: ts.ExportAssignment) { const illegalContextMessage = node.isExportEquals - ? Diagnostics.An_export_assignment_must_be_at_the_top_level_of_a_file_or_module_declaration - : Diagnostics.A_default_export_must_be_at_the_top_level_of_a_file_or_module_declaration; + ? ts.Diagnostics.An_export_assignment_must_be_at_the_top_level_of_a_file_or_module_declaration + : ts.Diagnostics.A_default_export_must_be_at_the_top_level_of_a_file_or_module_declaration; if (checkGrammarModuleElementContext(node, illegalContextMessage)) { // If we hit an export assignment in an illegal context, just bail out to avoid cascading errors. return; } - const container = node.parent.kind === SyntaxKind.SourceFile ? node.parent : node.parent.parent as ModuleDeclaration; - if (container.kind === SyntaxKind.ModuleDeclaration && !isAmbientModule(container)) { + const container = node.parent.kind === ts.SyntaxKind.SourceFile ? node.parent : node.parent.parent as ts.ModuleDeclaration; + if (container.kind === ts.SyntaxKind.ModuleDeclaration && !ts.isAmbientModule(container)) { if (node.isExportEquals) { - error(node, Diagnostics.An_export_assignment_cannot_be_used_in_a_namespace); + error(node, ts.Diagnostics.An_export_assignment_cannot_be_used_in_a_namespace); } else { - error(node, Diagnostics.A_default_export_can_only_be_used_in_an_ECMAScript_style_module); + error(node, ts.Diagnostics.A_default_export_can_only_be_used_in_an_ECMAScript_style_module); } return; } // Grammar checking - if (!checkGrammarDecoratorsAndModifiers(node) && hasEffectiveModifiers(node)) { - grammarErrorOnFirstToken(node, Diagnostics.An_export_assignment_cannot_have_modifiers); + if (!checkGrammarDecoratorsAndModifiers(node) && ts.hasEffectiveModifiers(node)) { + grammarErrorOnFirstToken(node, ts.Diagnostics.An_export_assignment_cannot_have_modifiers); } - const typeAnnotationNode = getEffectiveTypeAnnotationNode(node); + const typeAnnotationNode = ts.getEffectiveTypeAnnotationNode(node); if (typeAnnotationNode) { checkTypeAssignableTo(checkExpressionCached(node.expression), getTypeFromTypeNode(typeAnnotationNode), node.expression); } - if (node.expression.kind === SyntaxKind.Identifier) { - const id = node.expression as Identifier; - const sym = resolveEntityName(id, SymbolFlags.All, /*ignoreErrors*/ true, /*dontResolveAlias*/ true, node); + if (node.expression.kind === ts.SyntaxKind.Identifier) { + const id = node.expression as ts.Identifier; + const sym = resolveEntityName(id, ts.SymbolFlags.All, /*ignoreErrors*/ true, /*dontResolveAlias*/ true, node); if (sym) { markAliasReferenced(sym, id); // If not a value, we're interpreting the identifier as a type export, along the lines of (`export { Id as default }`) - const target = sym.flags & SymbolFlags.Alias ? resolveAlias(sym) : sym; - if (target === unknownSymbol || target.flags & SymbolFlags.Value) { + const target = sym.flags & ts.SymbolFlags.Alias ? resolveAlias(sym) : sym; + if (target === unknownSymbol || target.flags & ts.SymbolFlags.Value) { // However if it is a value, we need to check it's being used correctly checkExpressionCached(node.expression); } @@ -41087,8 +40166,8 @@ namespace ts { checkExpressionCached(node.expression); // doesn't resolve, check as expression to mark as error } - if (getEmitDeclarations(compilerOptions)) { - collectLinkedAliases(node.expression as Identifier, /*setVisibility*/ true); + if (ts.getEmitDeclarations(compilerOptions)) { + collectLinkedAliases(node.expression as ts.Identifier, /*setVisibility*/ true); } } else { @@ -41097,35 +40176,35 @@ namespace ts { checkExternalModuleExports(container); - if ((node.flags & NodeFlags.Ambient) && !isEntityNameExpression(node.expression)) { - grammarErrorOnNode(node.expression, Diagnostics.The_expression_of_an_export_assignment_must_be_an_identifier_or_qualified_name_in_an_ambient_context); + if ((node.flags & ts.NodeFlags.Ambient) && !ts.isEntityNameExpression(node.expression)) { + grammarErrorOnNode(node.expression, ts.Diagnostics.The_expression_of_an_export_assignment_must_be_an_identifier_or_qualified_name_in_an_ambient_context); } - if (node.isExportEquals && !(node.flags & NodeFlags.Ambient)) { - if (moduleKind >= ModuleKind.ES2015 && getSourceFileOfNode(node).impliedNodeFormat !== ModuleKind.CommonJS) { + if (node.isExportEquals && !(node.flags & ts.NodeFlags.Ambient)) { + if (moduleKind >= ts.ModuleKind.ES2015 && ts.getSourceFileOfNode(node).impliedNodeFormat !== ts.ModuleKind.CommonJS) { // export assignment is not supported in es6 modules - grammarErrorOnNode(node, Diagnostics.Export_assignment_cannot_be_used_when_targeting_ECMAScript_modules_Consider_using_export_default_or_another_module_format_instead); + grammarErrorOnNode(node, ts.Diagnostics.Export_assignment_cannot_be_used_when_targeting_ECMAScript_modules_Consider_using_export_default_or_another_module_format_instead); } - else if (moduleKind === ModuleKind.System) { + else if (moduleKind === ts.ModuleKind.System) { // system modules does not support export assignment - grammarErrorOnNode(node, Diagnostics.Export_assignment_is_not_supported_when_module_flag_is_system); + grammarErrorOnNode(node, ts.Diagnostics.Export_assignment_is_not_supported_when_module_flag_is_system); } } } - function hasExportedMembers(moduleSymbol: Symbol) { - return forEachEntry(moduleSymbol.exports!, (_, id) => id !== "export="); + function hasExportedMembers(moduleSymbol: ts.Symbol) { + return ts.forEachEntry(moduleSymbol.exports!, (_, id) => id !== "export="); } - function checkExternalModuleExports(node: SourceFile | ModuleDeclaration) { + function checkExternalModuleExports(node: ts.SourceFile | ts.ModuleDeclaration) { const moduleSymbol = getSymbolOfNode(node); const links = getSymbolLinks(moduleSymbol); if (!links.exportsChecked) { - const exportEqualsSymbol = moduleSymbol.exports!.get("export=" as __String); + const exportEqualsSymbol = moduleSymbol.exports!.get("export=" as ts.__String); if (exportEqualsSymbol && hasExportedMembers(moduleSymbol)) { const declaration = getDeclarationOfAliasSymbol(exportEqualsSymbol) || exportEqualsSymbol.valueDeclaration; - if (declaration && !isTopLevelInExternalModuleAugmentation(declaration) && !isInJSFile(declaration)) { - error(declaration, Diagnostics.An_export_assignment_cannot_be_used_in_a_module_with_other_exported_elements); + if (declaration && !isTopLevelInExternalModuleAugmentation(declaration) && !ts.isInJSFile(declaration)) { + error(declaration, ts.Diagnostics.An_export_assignment_cannot_be_used_in_a_module_with_other_exported_elements); } } // Checks for export * conflicts @@ -41137,11 +40216,11 @@ namespace ts { } // ECMA262: 15.2.1.1 It is a Syntax Error if the ExportedNames of ModuleItemList contains any duplicate entries. // (TS Exceptions: namespaces, function overloads, enums, and interfaces) - if (flags & (SymbolFlags.Namespace | SymbolFlags.Enum)) { + if (flags & (ts.SymbolFlags.Namespace | ts.SymbolFlags.Enum)) { return; } - const exportedDeclarationsCount = countWhere(declarations, and(isNotOverloadAndNotAccessor, not(isInterfaceDeclaration))); - if (flags & SymbolFlags.TypeAlias && exportedDeclarationsCount <= 2) { + const exportedDeclarationsCount = ts.countWhere(declarations, ts.and(isNotOverloadAndNotAccessor, ts.not(ts.isInterfaceDeclaration))); + if (flags & ts.SymbolFlags.TypeAlias && exportedDeclarationsCount <= 2) { // it is legal to merge type alias with other values // so count should be either 1 (just type alias) or 2 (type alias + merged value) return; @@ -41150,7 +40229,7 @@ namespace ts { if (!isDuplicatedCommonJSExport(declarations)) { for (const declaration of declarations!) { if (isNotOverload(declaration)) { - diagnostics.add(createDiagnosticForNode(declaration, Diagnostics.Cannot_redeclare_exported_variable_0, unescapeLeadingUnderscores(id))); + diagnostics.add(ts.createDiagnosticForNode(declaration, ts.Diagnostics.Cannot_redeclare_exported_variable_0, ts.unescapeLeadingUnderscores(id))); } } } @@ -41161,13 +40240,13 @@ namespace ts { } } - function isDuplicatedCommonJSExport(declarations: Declaration[] | undefined) { + function isDuplicatedCommonJSExport(declarations: ts.Declaration[] | undefined) { return declarations && declarations.length > 1 - && declarations.every(d => isInJSFile(d) && isAccessExpression(d) && (isExportsIdentifier(d.expression) || isModuleExportsAccessExpression(d.expression))); + && declarations.every(d => ts.isInJSFile(d) && ts.isAccessExpression(d) && (ts.isExportsIdentifier(d.expression) || ts.isModuleExportsAccessExpression(d.expression))); } - function checkSourceElement(node: Node | undefined): void { + function checkSourceElement(node: ts.Node | undefined): void { if (node) { const saveCurrentNode = currentNode; currentNode = node; @@ -41177,9 +40256,9 @@ namespace ts { } } - function checkSourceElementWorker(node: Node): void { - if (isInJSFile(node)) { - forEach((node as JSDocContainer).jsDoc, ({ tags }) => forEach(tags, checkSourceElement)); + function checkSourceElementWorker(node: ts.Node): void { + if (ts.isInJSFile(node)) { + ts.forEach((node as ts.JSDocContainer).jsDoc, ({ tags }) => ts.forEach(tags, checkSourceElement)); } const kind = node.kind; @@ -41187,231 +40266,231 @@ namespace ts { // Only bother checking on a few construct kinds. We don't want to be excessively // hitting the cancellation token on every node we check. switch (kind) { - case SyntaxKind.ModuleDeclaration: - case SyntaxKind.ClassDeclaration: - case SyntaxKind.InterfaceDeclaration: - case SyntaxKind.FunctionDeclaration: + case ts.SyntaxKind.ModuleDeclaration: + case ts.SyntaxKind.ClassDeclaration: + case ts.SyntaxKind.InterfaceDeclaration: + case ts.SyntaxKind.FunctionDeclaration: cancellationToken.throwIfCancellationRequested(); } } - if (kind >= SyntaxKind.FirstStatement && kind <= SyntaxKind.LastStatement && node.flowNode && !isReachableFlowNode(node.flowNode)) { - errorOrSuggestion(compilerOptions.allowUnreachableCode === false, node, Diagnostics.Unreachable_code_detected); + if (kind >= ts.SyntaxKind.FirstStatement && kind <= ts.SyntaxKind.LastStatement && node.flowNode && !isReachableFlowNode(node.flowNode)) { + errorOrSuggestion(compilerOptions.allowUnreachableCode === false, node, ts.Diagnostics.Unreachable_code_detected); } switch (kind) { - case SyntaxKind.TypeParameter: - return checkTypeParameter(node as TypeParameterDeclaration); - case SyntaxKind.Parameter: - return checkParameter(node as ParameterDeclaration); - case SyntaxKind.PropertyDeclaration: - return checkPropertyDeclaration(node as PropertyDeclaration); - case SyntaxKind.PropertySignature: - return checkPropertySignature(node as PropertySignature); - case SyntaxKind.ConstructorType: - case SyntaxKind.FunctionType: - case SyntaxKind.CallSignature: - case SyntaxKind.ConstructSignature: - case SyntaxKind.IndexSignature: - return checkSignatureDeclaration(node as SignatureDeclaration); - case SyntaxKind.MethodDeclaration: - case SyntaxKind.MethodSignature: - return checkMethodDeclaration(node as MethodDeclaration | MethodSignature); - case SyntaxKind.ClassStaticBlockDeclaration: - return checkClassStaticBlockDeclaration(node as ClassStaticBlockDeclaration); - case SyntaxKind.Constructor: - return checkConstructorDeclaration(node as ConstructorDeclaration); - case SyntaxKind.GetAccessor: - case SyntaxKind.SetAccessor: - return checkAccessorDeclaration(node as AccessorDeclaration); - case SyntaxKind.TypeReference: - return checkTypeReferenceNode(node as TypeReferenceNode); - case SyntaxKind.TypePredicate: - return checkTypePredicate(node as TypePredicateNode); - case SyntaxKind.TypeQuery: - return checkTypeQuery(node as TypeQueryNode); - case SyntaxKind.TypeLiteral: - return checkTypeLiteral(node as TypeLiteralNode); - case SyntaxKind.ArrayType: - return checkArrayType(node as ArrayTypeNode); - case SyntaxKind.TupleType: - return checkTupleType(node as TupleTypeNode); - case SyntaxKind.UnionType: - case SyntaxKind.IntersectionType: - return checkUnionOrIntersectionType(node as UnionOrIntersectionTypeNode); - case SyntaxKind.ParenthesizedType: - case SyntaxKind.OptionalType: - case SyntaxKind.RestType: - return checkSourceElement((node as ParenthesizedTypeNode | OptionalTypeNode | RestTypeNode).type); - case SyntaxKind.ThisType: - return checkThisType(node as ThisTypeNode); - case SyntaxKind.TypeOperator: - return checkTypeOperator(node as TypeOperatorNode); - case SyntaxKind.ConditionalType: - return checkConditionalType(node as ConditionalTypeNode); - case SyntaxKind.InferType: - return checkInferType(node as InferTypeNode); - case SyntaxKind.TemplateLiteralType: - return checkTemplateLiteralType(node as TemplateLiteralTypeNode); - case SyntaxKind.ImportType: - return checkImportType(node as ImportTypeNode); - case SyntaxKind.NamedTupleMember: - return checkNamedTupleMember(node as NamedTupleMember); - case SyntaxKind.JSDocAugmentsTag: - return checkJSDocAugmentsTag(node as JSDocAugmentsTag); - case SyntaxKind.JSDocImplementsTag: - return checkJSDocImplementsTag(node as JSDocImplementsTag); - case SyntaxKind.JSDocTypedefTag: - case SyntaxKind.JSDocCallbackTag: - case SyntaxKind.JSDocEnumTag: - return checkJSDocTypeAliasTag(node as JSDocTypedefTag); - case SyntaxKind.JSDocTemplateTag: - return checkJSDocTemplateTag(node as JSDocTemplateTag); - case SyntaxKind.JSDocTypeTag: - return checkJSDocTypeTag(node as JSDocTypeTag); - case SyntaxKind.JSDocParameterTag: - return checkJSDocParameterTag(node as JSDocParameterTag); - case SyntaxKind.JSDocPropertyTag: - return checkJSDocPropertyTag(node as JSDocPropertyTag); - case SyntaxKind.JSDocFunctionType: - checkJSDocFunctionType(node as JSDocFunctionType); + case ts.SyntaxKind.TypeParameter: + return checkTypeParameter(node as ts.TypeParameterDeclaration); + case ts.SyntaxKind.Parameter: + return checkParameter(node as ts.ParameterDeclaration); + case ts.SyntaxKind.PropertyDeclaration: + return checkPropertyDeclaration(node as ts.PropertyDeclaration); + case ts.SyntaxKind.PropertySignature: + return checkPropertySignature(node as ts.PropertySignature); + case ts.SyntaxKind.ConstructorType: + case ts.SyntaxKind.FunctionType: + case ts.SyntaxKind.CallSignature: + case ts.SyntaxKind.ConstructSignature: + case ts.SyntaxKind.IndexSignature: + return checkSignatureDeclaration(node as ts.SignatureDeclaration); + case ts.SyntaxKind.MethodDeclaration: + case ts.SyntaxKind.MethodSignature: + return checkMethodDeclaration(node as ts.MethodDeclaration | ts.MethodSignature); + case ts.SyntaxKind.ClassStaticBlockDeclaration: + return checkClassStaticBlockDeclaration(node as ts.ClassStaticBlockDeclaration); + case ts.SyntaxKind.Constructor: + return checkConstructorDeclaration(node as ts.ConstructorDeclaration); + case ts.SyntaxKind.GetAccessor: + case ts.SyntaxKind.SetAccessor: + return checkAccessorDeclaration(node as ts.AccessorDeclaration); + case ts.SyntaxKind.TypeReference: + return checkTypeReferenceNode(node as ts.TypeReferenceNode); + case ts.SyntaxKind.TypePredicate: + return checkTypePredicate(node as ts.TypePredicateNode); + case ts.SyntaxKind.TypeQuery: + return checkTypeQuery(node as ts.TypeQueryNode); + case ts.SyntaxKind.TypeLiteral: + return checkTypeLiteral(node as ts.TypeLiteralNode); + case ts.SyntaxKind.ArrayType: + return checkArrayType(node as ts.ArrayTypeNode); + case ts.SyntaxKind.TupleType: + return checkTupleType(node as ts.TupleTypeNode); + case ts.SyntaxKind.UnionType: + case ts.SyntaxKind.IntersectionType: + return checkUnionOrIntersectionType(node as ts.UnionOrIntersectionTypeNode); + case ts.SyntaxKind.ParenthesizedType: + case ts.SyntaxKind.OptionalType: + case ts.SyntaxKind.RestType: + return checkSourceElement((node as ts.ParenthesizedTypeNode | ts.OptionalTypeNode | ts.RestTypeNode).type); + case ts.SyntaxKind.ThisType: + return checkThisType(node as ts.ThisTypeNode); + case ts.SyntaxKind.TypeOperator: + return checkTypeOperator(node as ts.TypeOperatorNode); + case ts.SyntaxKind.ConditionalType: + return checkConditionalType(node as ts.ConditionalTypeNode); + case ts.SyntaxKind.InferType: + return checkInferType(node as ts.InferTypeNode); + case ts.SyntaxKind.TemplateLiteralType: + return checkTemplateLiteralType(node as ts.TemplateLiteralTypeNode); + case ts.SyntaxKind.ImportType: + return checkImportType(node as ts.ImportTypeNode); + case ts.SyntaxKind.NamedTupleMember: + return checkNamedTupleMember(node as ts.NamedTupleMember); + case ts.SyntaxKind.JSDocAugmentsTag: + return checkJSDocAugmentsTag(node as ts.JSDocAugmentsTag); + case ts.SyntaxKind.JSDocImplementsTag: + return checkJSDocImplementsTag(node as ts.JSDocImplementsTag); + case ts.SyntaxKind.JSDocTypedefTag: + case ts.SyntaxKind.JSDocCallbackTag: + case ts.SyntaxKind.JSDocEnumTag: + return checkJSDocTypeAliasTag(node as ts.JSDocTypedefTag); + case ts.SyntaxKind.JSDocTemplateTag: + return checkJSDocTemplateTag(node as ts.JSDocTemplateTag); + case ts.SyntaxKind.JSDocTypeTag: + return checkJSDocTypeTag(node as ts.JSDocTypeTag); + case ts.SyntaxKind.JSDocParameterTag: + return checkJSDocParameterTag(node as ts.JSDocParameterTag); + case ts.SyntaxKind.JSDocPropertyTag: + return checkJSDocPropertyTag(node as ts.JSDocPropertyTag); + case ts.SyntaxKind.JSDocFunctionType: + checkJSDocFunctionType(node as ts.JSDocFunctionType); // falls through - case SyntaxKind.JSDocNonNullableType: - case SyntaxKind.JSDocNullableType: - case SyntaxKind.JSDocAllType: - case SyntaxKind.JSDocUnknownType: - case SyntaxKind.JSDocTypeLiteral: + case ts.SyntaxKind.JSDocNonNullableType: + case ts.SyntaxKind.JSDocNullableType: + case ts.SyntaxKind.JSDocAllType: + case ts.SyntaxKind.JSDocUnknownType: + case ts.SyntaxKind.JSDocTypeLiteral: checkJSDocTypeIsInJsFile(node); - forEachChild(node, checkSourceElement); + ts.forEachChild(node, checkSourceElement); return; - case SyntaxKind.JSDocVariadicType: - checkJSDocVariadicType(node as JSDocVariadicType); + case ts.SyntaxKind.JSDocVariadicType: + checkJSDocVariadicType(node as ts.JSDocVariadicType); return; - case SyntaxKind.JSDocTypeExpression: - return checkSourceElement((node as JSDocTypeExpression).type); - case SyntaxKind.JSDocPublicTag: - case SyntaxKind.JSDocProtectedTag: - case SyntaxKind.JSDocPrivateTag: - return checkJSDocAccessibilityModifiers(node as JSDocPublicTag | JSDocProtectedTag | JSDocPrivateTag); - case SyntaxKind.IndexedAccessType: - return checkIndexedAccessType(node as IndexedAccessTypeNode); - case SyntaxKind.MappedType: - return checkMappedType(node as MappedTypeNode); - case SyntaxKind.FunctionDeclaration: - return checkFunctionDeclaration(node as FunctionDeclaration); - case SyntaxKind.Block: - case SyntaxKind.ModuleBlock: - return checkBlock(node as Block); - case SyntaxKind.VariableStatement: - return checkVariableStatement(node as VariableStatement); - case SyntaxKind.ExpressionStatement: - return checkExpressionStatement(node as ExpressionStatement); - case SyntaxKind.IfStatement: - return checkIfStatement(node as IfStatement); - case SyntaxKind.DoStatement: - return checkDoStatement(node as DoStatement); - case SyntaxKind.WhileStatement: - return checkWhileStatement(node as WhileStatement); - case SyntaxKind.ForStatement: - return checkForStatement(node as ForStatement); - case SyntaxKind.ForInStatement: - return checkForInStatement(node as ForInStatement); - case SyntaxKind.ForOfStatement: - return checkForOfStatement(node as ForOfStatement); - case SyntaxKind.ContinueStatement: - case SyntaxKind.BreakStatement: - return checkBreakOrContinueStatement(node as BreakOrContinueStatement); - case SyntaxKind.ReturnStatement: - return checkReturnStatement(node as ReturnStatement); - case SyntaxKind.WithStatement: - return checkWithStatement(node as WithStatement); - case SyntaxKind.SwitchStatement: - return checkSwitchStatement(node as SwitchStatement); - case SyntaxKind.LabeledStatement: - return checkLabeledStatement(node as LabeledStatement); - case SyntaxKind.ThrowStatement: - return checkThrowStatement(node as ThrowStatement); - case SyntaxKind.TryStatement: - return checkTryStatement(node as TryStatement); - case SyntaxKind.VariableDeclaration: - return checkVariableDeclaration(node as VariableDeclaration); - case SyntaxKind.BindingElement: - return checkBindingElement(node as BindingElement); - case SyntaxKind.ClassDeclaration: - return checkClassDeclaration(node as ClassDeclaration); - case SyntaxKind.InterfaceDeclaration: - return checkInterfaceDeclaration(node as InterfaceDeclaration); - case SyntaxKind.TypeAliasDeclaration: - return checkTypeAliasDeclaration(node as TypeAliasDeclaration); - case SyntaxKind.EnumDeclaration: - return checkEnumDeclaration(node as EnumDeclaration); - case SyntaxKind.ModuleDeclaration: - return checkModuleDeclaration(node as ModuleDeclaration); - case SyntaxKind.ImportDeclaration: - return checkImportDeclaration(node as ImportDeclaration); - case SyntaxKind.ImportEqualsDeclaration: - return checkImportEqualsDeclaration(node as ImportEqualsDeclaration); - case SyntaxKind.ExportDeclaration: - return checkExportDeclaration(node as ExportDeclaration); - case SyntaxKind.ExportAssignment: - return checkExportAssignment(node as ExportAssignment); - case SyntaxKind.EmptyStatement: - case SyntaxKind.DebuggerStatement: + case ts.SyntaxKind.JSDocTypeExpression: + return checkSourceElement((node as ts.JSDocTypeExpression).type); + case ts.SyntaxKind.JSDocPublicTag: + case ts.SyntaxKind.JSDocProtectedTag: + case ts.SyntaxKind.JSDocPrivateTag: + return checkJSDocAccessibilityModifiers(node as ts.JSDocPublicTag | ts.JSDocProtectedTag | ts.JSDocPrivateTag); + case ts.SyntaxKind.IndexedAccessType: + return checkIndexedAccessType(node as ts.IndexedAccessTypeNode); + case ts.SyntaxKind.MappedType: + return checkMappedType(node as ts.MappedTypeNode); + case ts.SyntaxKind.FunctionDeclaration: + return checkFunctionDeclaration(node as ts.FunctionDeclaration); + case ts.SyntaxKind.Block: + case ts.SyntaxKind.ModuleBlock: + return checkBlock(node as ts.Block); + case ts.SyntaxKind.VariableStatement: + return checkVariableStatement(node as ts.VariableStatement); + case ts.SyntaxKind.ExpressionStatement: + return checkExpressionStatement(node as ts.ExpressionStatement); + case ts.SyntaxKind.IfStatement: + return checkIfStatement(node as ts.IfStatement); + case ts.SyntaxKind.DoStatement: + return checkDoStatement(node as ts.DoStatement); + case ts.SyntaxKind.WhileStatement: + return checkWhileStatement(node as ts.WhileStatement); + case ts.SyntaxKind.ForStatement: + return checkForStatement(node as ts.ForStatement); + case ts.SyntaxKind.ForInStatement: + return checkForInStatement(node as ts.ForInStatement); + case ts.SyntaxKind.ForOfStatement: + return checkForOfStatement(node as ts.ForOfStatement); + case ts.SyntaxKind.ContinueStatement: + case ts.SyntaxKind.BreakStatement: + return checkBreakOrContinueStatement(node as ts.BreakOrContinueStatement); + case ts.SyntaxKind.ReturnStatement: + return checkReturnStatement(node as ts.ReturnStatement); + case ts.SyntaxKind.WithStatement: + return checkWithStatement(node as ts.WithStatement); + case ts.SyntaxKind.SwitchStatement: + return checkSwitchStatement(node as ts.SwitchStatement); + case ts.SyntaxKind.LabeledStatement: + return checkLabeledStatement(node as ts.LabeledStatement); + case ts.SyntaxKind.ThrowStatement: + return checkThrowStatement(node as ts.ThrowStatement); + case ts.SyntaxKind.TryStatement: + return checkTryStatement(node as ts.TryStatement); + case ts.SyntaxKind.VariableDeclaration: + return checkVariableDeclaration(node as ts.VariableDeclaration); + case ts.SyntaxKind.BindingElement: + return checkBindingElement(node as ts.BindingElement); + case ts.SyntaxKind.ClassDeclaration: + return checkClassDeclaration(node as ts.ClassDeclaration); + case ts.SyntaxKind.InterfaceDeclaration: + return checkInterfaceDeclaration(node as ts.InterfaceDeclaration); + case ts.SyntaxKind.TypeAliasDeclaration: + return checkTypeAliasDeclaration(node as ts.TypeAliasDeclaration); + case ts.SyntaxKind.EnumDeclaration: + return checkEnumDeclaration(node as ts.EnumDeclaration); + case ts.SyntaxKind.ModuleDeclaration: + return checkModuleDeclaration(node as ts.ModuleDeclaration); + case ts.SyntaxKind.ImportDeclaration: + return checkImportDeclaration(node as ts.ImportDeclaration); + case ts.SyntaxKind.ImportEqualsDeclaration: + return checkImportEqualsDeclaration(node as ts.ImportEqualsDeclaration); + case ts.SyntaxKind.ExportDeclaration: + return checkExportDeclaration(node as ts.ExportDeclaration); + case ts.SyntaxKind.ExportAssignment: + return checkExportAssignment(node as ts.ExportAssignment); + case ts.SyntaxKind.EmptyStatement: + case ts.SyntaxKind.DebuggerStatement: checkGrammarStatementInAmbientContext(node); return; - case SyntaxKind.MissingDeclaration: + case ts.SyntaxKind.MissingDeclaration: return checkMissingDeclaration(node); } } - function checkJSDocTypeIsInJsFile(node: Node): void { - if (!isInJSFile(node)) { - grammarErrorOnNode(node, Diagnostics.JSDoc_types_can_only_be_used_inside_documentation_comments); + function checkJSDocTypeIsInJsFile(node: ts.Node): void { + if (!ts.isInJSFile(node)) { + grammarErrorOnNode(node, ts.Diagnostics.JSDoc_types_can_only_be_used_inside_documentation_comments); } } - function checkJSDocVariadicType(node: JSDocVariadicType): void { + function checkJSDocVariadicType(node: ts.JSDocVariadicType): void { checkJSDocTypeIsInJsFile(node); checkSourceElement(node.type); // Only legal location is in the *last* parameter tag or last parameter of a JSDoc function. const { parent } = node; - if (isParameter(parent) && isJSDocFunctionType(parent.parent)) { - if (last(parent.parent.parameters) !== parent) { - error(node, Diagnostics.A_rest_parameter_must_be_last_in_a_parameter_list); + if (ts.isParameter(parent) && ts.isJSDocFunctionType(parent.parent)) { + if (ts.last(parent.parent.parameters) !== parent) { + error(node, ts.Diagnostics.A_rest_parameter_must_be_last_in_a_parameter_list); } return; } - if (!isJSDocTypeExpression(parent)) { - error(node, Diagnostics.JSDoc_may_only_appear_in_the_last_parameter_of_a_signature); + if (!ts.isJSDocTypeExpression(parent)) { + error(node, ts.Diagnostics.JSDoc_may_only_appear_in_the_last_parameter_of_a_signature); } const paramTag = node.parent.parent; - if (!isJSDocParameterTag(paramTag)) { - error(node, Diagnostics.JSDoc_may_only_appear_in_the_last_parameter_of_a_signature); + if (!ts.isJSDocParameterTag(paramTag)) { + error(node, ts.Diagnostics.JSDoc_may_only_appear_in_the_last_parameter_of_a_signature); return; } - const param = getParameterSymbolFromJSDoc(paramTag); + const param = ts.getParameterSymbolFromJSDoc(paramTag); if (!param) { // We will error in `checkJSDocParameterTag`. return; } - const host = getHostSignatureFromJSDoc(paramTag); - if (!host || last(host.parameters).symbol !== param) { - error(node, Diagnostics.A_rest_parameter_must_be_last_in_a_parameter_list); + const host = ts.getHostSignatureFromJSDoc(paramTag); + if (!host || ts.last(host.parameters).symbol !== param) { + error(node, ts.Diagnostics.A_rest_parameter_must_be_last_in_a_parameter_list); } } - function getTypeFromJSDocVariadicType(node: JSDocVariadicType): Type { + function getTypeFromJSDocVariadicType(node: ts.JSDocVariadicType): ts.Type { const type = getTypeFromTypeNode(node.type); const { parent } = node; const paramTag = node.parent.parent; - if (isJSDocTypeExpression(node.parent) && isJSDocParameterTag(paramTag)) { + if (ts.isJSDocTypeExpression(node.parent) && ts.isJSDocParameterTag(paramTag)) { // Else we will add a diagnostic, see `checkJSDocVariadicType`. - const host = getHostSignatureFromJSDoc(paramTag); - const isCallbackTag = isJSDocCallbackTag(paramTag.parent.parent); + const host = ts.getHostSignatureFromJSDoc(paramTag); + const isCallbackTag = ts.isJSDocCallbackTag(paramTag.parent.parent); if (host || isCallbackTag) { /* Only return an array type if the corresponding parameter is marked as a rest parameter, or if there are no parameters. @@ -41421,16 +40500,16 @@ namespace ts { Because `a` will just be of type `number | undefined`. A synthetic `...args` will also be added, which *will* get an array type. */ const lastParamDeclaration = isCallbackTag - ? lastOrUndefined((paramTag.parent.parent as unknown as JSDocCallbackTag).typeExpression.parameters) - : lastOrUndefined(host!.parameters); - const symbol = getParameterSymbolFromJSDoc(paramTag); + ? ts.lastOrUndefined((paramTag.parent.parent as unknown as ts.JSDocCallbackTag).typeExpression.parameters) + : ts.lastOrUndefined(host!.parameters); + const symbol = ts.getParameterSymbolFromJSDoc(paramTag); if (!lastParamDeclaration || - symbol && lastParamDeclaration.symbol === symbol && isRestParameter(lastParamDeclaration)) { + symbol && lastParamDeclaration.symbol === symbol && ts.isRestParameter(lastParamDeclaration)) { return createArrayType(type); } } } - if (isParameter(parent) && isJSDocFunctionType(parent.parent)) { + if (ts.isParameter(parent) && ts.isJSDocFunctionType(parent.parent)) { return createArrayType(type); } return addOptionality(type); @@ -41445,72 +40524,72 @@ namespace ts { // Here, performing a full type check of the body of the function expression whilst in the process of // determining the type of foo would cause foo to be given type any because of the recursive reference. // Delaying the type check of the body ensures foo has been assigned a type. - function checkNodeDeferred(node: Node) { - const enclosingFile = getSourceFileOfNode(node); + function checkNodeDeferred(node: ts.Node) { + const enclosingFile = ts.getSourceFileOfNode(node); const links = getNodeLinks(enclosingFile); - if (!(links.flags & NodeCheckFlags.TypeChecked)) { - links.deferredNodes ||= new Set(); + if (!(links.flags & ts.NodeCheckFlags.TypeChecked)) { + links.deferredNodes ||= new ts.Set(); links.deferredNodes.add(node); } } - function checkDeferredNodes(context: SourceFile) { + function checkDeferredNodes(context: ts.SourceFile) { const links = getNodeLinks(context); if (links.deferredNodes) { links.deferredNodes.forEach(checkDeferredNode); } } - function checkDeferredNode(node: Node) { - tracing?.push(tracing.Phase.Check, "checkDeferredNode", { kind: node.kind, pos: node.pos, end: node.end, path: (node as TracingNode).tracingPath }); + function checkDeferredNode(node: ts.Node) { + ts.tracing?.push(ts.tracing.Phase.Check, "checkDeferredNode", { kind: node.kind, pos: node.pos, end: node.end, path: (node as ts.TracingNode).tracingPath }); const saveCurrentNode = currentNode; currentNode = node; instantiationCount = 0; switch (node.kind) { - case SyntaxKind.CallExpression: - case SyntaxKind.NewExpression: - case SyntaxKind.TaggedTemplateExpression: - case SyntaxKind.Decorator: - case SyntaxKind.JsxOpeningElement: + case ts.SyntaxKind.CallExpression: + case ts.SyntaxKind.NewExpression: + case ts.SyntaxKind.TaggedTemplateExpression: + case ts.SyntaxKind.Decorator: + case ts.SyntaxKind.JsxOpeningElement: // These node kinds are deferred checked when overload resolution fails // To save on work, we ensure the arguments are checked just once, in // a deferred way - resolveUntypedCall(node as CallLikeExpression); + resolveUntypedCall(node as ts.CallLikeExpression); break; - case SyntaxKind.FunctionExpression: - case SyntaxKind.ArrowFunction: - case SyntaxKind.MethodDeclaration: - case SyntaxKind.MethodSignature: - checkFunctionExpressionOrObjectLiteralMethodDeferred(node as FunctionExpression); + case ts.SyntaxKind.FunctionExpression: + case ts.SyntaxKind.ArrowFunction: + case ts.SyntaxKind.MethodDeclaration: + case ts.SyntaxKind.MethodSignature: + checkFunctionExpressionOrObjectLiteralMethodDeferred(node as ts.FunctionExpression); break; - case SyntaxKind.GetAccessor: - case SyntaxKind.SetAccessor: - checkAccessorDeclaration(node as AccessorDeclaration); + case ts.SyntaxKind.GetAccessor: + case ts.SyntaxKind.SetAccessor: + checkAccessorDeclaration(node as ts.AccessorDeclaration); break; - case SyntaxKind.ClassExpression: - checkClassExpressionDeferred(node as ClassExpression); + case ts.SyntaxKind.ClassExpression: + checkClassExpressionDeferred(node as ts.ClassExpression); break; - case SyntaxKind.TypeParameter: - checkTypeParameterDeferred(node as TypeParameterDeclaration); + case ts.SyntaxKind.TypeParameter: + checkTypeParameterDeferred(node as ts.TypeParameterDeclaration); break; - case SyntaxKind.JsxSelfClosingElement: - checkJsxSelfClosingElementDeferred(node as JsxSelfClosingElement); + case ts.SyntaxKind.JsxSelfClosingElement: + checkJsxSelfClosingElementDeferred(node as ts.JsxSelfClosingElement); break; - case SyntaxKind.JsxElement: - checkJsxElementDeferred(node as JsxElement); + case ts.SyntaxKind.JsxElement: + checkJsxElementDeferred(node as ts.JsxElement); break; } currentNode = saveCurrentNode; - tracing?.pop(); + ts.tracing?.pop(); } - function checkSourceFile(node: SourceFile) { - tracing?.push(tracing.Phase.Check, "checkSourceFile", { path: node.path }, /*separateBeginAndEnd*/ true); - performance.mark("beforeCheck"); + function checkSourceFile(node: ts.SourceFile) { + ts.tracing?.push(ts.tracing.Phase.Check, "checkSourceFile", { path: node.path }, /*separateBeginAndEnd*/ true); + ts.performance.mark("beforeCheck"); checkSourceFileWorker(node); - performance.mark("afterCheck"); - performance.measure("Check", "beforeCheck", "afterCheck"); - tracing?.pop(); + ts.performance.mark("afterCheck"); + ts.performance.measure("Check", "beforeCheck", "afterCheck"); + ts.tracing?.pop(); } function unusedIsError(kind: UnusedKind, isAmbient: boolean): boolean { @@ -41523,36 +40602,35 @@ namespace ts { case UnusedKind.Parameter: return !!compilerOptions.noUnusedParameters; default: - return Debug.assertNever(kind); + return ts.Debug.assertNever(kind); } } - function getPotentiallyUnusedIdentifiers(sourceFile: SourceFile): readonly PotentiallyUnusedIdentifier[] { - return allPotentiallyUnusedIdentifiers.get(sourceFile.path) || emptyArray; + function getPotentiallyUnusedIdentifiers(sourceFile: ts.SourceFile): readonly PotentiallyUnusedIdentifier[] { + return allPotentiallyUnusedIdentifiers.get(sourceFile.path) || ts.emptyArray; } // Fully type check a source file and collect the relevant diagnostics. - function checkSourceFileWorker(node: SourceFile) { + function checkSourceFileWorker(node: ts.SourceFile) { const links = getNodeLinks(node); - if (!(links.flags & NodeCheckFlags.TypeChecked)) { - if (skipTypeChecking(node, compilerOptions, host)) { + if (!(links.flags & ts.NodeCheckFlags.TypeChecked)) { + if (ts.skipTypeChecking(node, compilerOptions, host)) { return; } // Grammar checking checkGrammarSourceFile(node); - clear(potentialThisCollisions); - clear(potentialNewTargetCollisions); - clear(potentialWeakMapSetCollisions); - clear(potentialReflectCollisions); - - forEach(node.statements, checkSourceElement); + ts.clear(potentialThisCollisions); + ts.clear(potentialNewTargetCollisions); + ts.clear(potentialWeakMapSetCollisions); + ts.clear(potentialReflectCollisions); + ts.forEach(node.statements, checkSourceElement); checkSourceElement(node.endOfFileToken); checkDeferredNodes(node); - if (isExternalOrCommonJsModule(node)) { + if (ts.isExternalOrCommonJsModule(node)) { registerForUnusedIdentifiersCheck(node); } @@ -41560,49 +40638,48 @@ namespace ts { // This relies on the results of other lazy diagnostics, so must be computed after them if (!node.isDeclarationFile && (compilerOptions.noUnusedLocals || compilerOptions.noUnusedParameters)) { checkUnusedIdentifiers(getPotentiallyUnusedIdentifiers(node), (containingNode, kind, diag) => { - if (!containsParseError(containingNode) && unusedIsError(kind, !!(containingNode.flags & NodeFlags.Ambient))) { + if (!ts.containsParseError(containingNode) && unusedIsError(kind, !!(containingNode.flags & ts.NodeFlags.Ambient))) { diagnostics.add(diag); } }); } }); - if (compilerOptions.importsNotUsedAsValues === ImportsNotUsedAsValues.Error && + if (compilerOptions.importsNotUsedAsValues === ts.ImportsNotUsedAsValues.Error && !node.isDeclarationFile && - isExternalModule(node) - ) { + ts.isExternalModule(node)) { checkImportsForTypeOnlyConversion(node); } - if (isExternalOrCommonJsModule(node)) { + if (ts.isExternalOrCommonJsModule(node)) { checkExternalModuleExports(node); } if (potentialThisCollisions.length) { - forEach(potentialThisCollisions, checkIfThisIsCapturedInEnclosingScope); - clear(potentialThisCollisions); + ts.forEach(potentialThisCollisions, checkIfThisIsCapturedInEnclosingScope); + ts.clear(potentialThisCollisions); } if (potentialNewTargetCollisions.length) { - forEach(potentialNewTargetCollisions, checkIfNewTargetIsCapturedInEnclosingScope); - clear(potentialNewTargetCollisions); + ts.forEach(potentialNewTargetCollisions, checkIfNewTargetIsCapturedInEnclosingScope); + ts.clear(potentialNewTargetCollisions); } if (potentialWeakMapSetCollisions.length) { - forEach(potentialWeakMapSetCollisions, checkWeakMapSetCollision); - clear(potentialWeakMapSetCollisions); + ts.forEach(potentialWeakMapSetCollisions, checkWeakMapSetCollision); + ts.clear(potentialWeakMapSetCollisions); } if (potentialReflectCollisions.length) { - forEach(potentialReflectCollisions, checkReflectCollision); - clear(potentialReflectCollisions); + ts.forEach(potentialReflectCollisions, checkReflectCollision); + ts.clear(potentialReflectCollisions); } - links.flags |= NodeCheckFlags.TypeChecked; + links.flags |= ts.NodeCheckFlags.TypeChecked; } } - function getDiagnostics(sourceFile: SourceFile, ct: CancellationToken): Diagnostic[] { + function getDiagnostics(sourceFile: ts.SourceFile, ct: ts.CancellationToken): ts.Diagnostic[] { try { // Record the cancellation token so it can be checked later on during checkSourceElement. // Do this in a finally block so we can ensure that it gets reset back to nothing after @@ -41623,7 +40700,7 @@ namespace ts { deferredDiagnosticsCallbacks = []; } - function checkSourceFileWithEagerDiagnostics(sourceFile: SourceFile) { + function checkSourceFileWithEagerDiagnostics(sourceFile: ts.SourceFile) { ensurePendingDiagnosticWorkComplete(); // then setup diagnostics for immediate invocation (as we are about to collect them, and // this avoids the overhead of longer-lived callbacks we don't need to allocate) @@ -41636,7 +40713,7 @@ namespace ts { addLazyDiagnostic = oldAddLazyDiagnostics; } - function getDiagnosticsWorker(sourceFile: SourceFile): Diagnostic[] { + function getDiagnosticsWorker(sourceFile: ts.SourceFile): ts.Diagnostic[] { if (sourceFile) { ensurePendingDiagnosticWorkComplete(); // Some global diagnostics are deferred until they are needed and @@ -41651,14 +40728,14 @@ namespace ts { const currentGlobalDiagnostics = diagnostics.getGlobalDiagnostics(); if (currentGlobalDiagnostics !== previousGlobalDiagnostics) { // If the arrays are not the same reference, new diagnostics were added. - const deferredGlobalDiagnostics = relativeComplement(previousGlobalDiagnostics, currentGlobalDiagnostics, compareDiagnostics); - return concatenate(deferredGlobalDiagnostics, semanticDiagnostics); + const deferredGlobalDiagnostics = ts.relativeComplement(previousGlobalDiagnostics, currentGlobalDiagnostics, ts.compareDiagnostics); + return ts.concatenate(deferredGlobalDiagnostics, semanticDiagnostics); } else if (previousGlobalDiagnosticsSize === 0 && currentGlobalDiagnostics.length > 0) { // If the arrays are the same reference, but the length has changed, a single // new diagnostic was added as DiagnosticCollection attempts to reuse the // same array. - return concatenate(currentGlobalDiagnostics, semanticDiagnostics); + return ts.concatenate(currentGlobalDiagnostics, semanticDiagnostics); } return semanticDiagnostics; @@ -41666,29 +40743,29 @@ namespace ts { // Global diagnostics are always added when a file is not provided to // getDiagnostics - forEach(host.getSourceFiles(), checkSourceFileWithEagerDiagnostics); + ts.forEach(host.getSourceFiles(), checkSourceFileWithEagerDiagnostics); return diagnostics.getDiagnostics(); } - function getGlobalDiagnostics(): Diagnostic[] { + function getGlobalDiagnostics(): ts.Diagnostic[] { ensurePendingDiagnosticWorkComplete(); return diagnostics.getGlobalDiagnostics(); } // Language service support - function getSymbolsInScope(location: Node, meaning: SymbolFlags): Symbol[] { - if (location.flags & NodeFlags.InWithStatement) { + function getSymbolsInScope(location: ts.Node, meaning: ts.SymbolFlags): ts.Symbol[] { + if (location.flags & ts.NodeFlags.InWithStatement) { // We cannot answer semantic questions within a with block, do not proceed any further return []; } - const symbols = createSymbolTable(); + const symbols = ts.createSymbolTable(); let isStaticSymbol = false; populateSymbols(); - symbols.delete(InternalSymbolName.This); // Not a symbol, a keyword + symbols.delete(ts.InternalSymbolName.This); // Not a symbol, a keyword return symbolsToArray(symbols); function populateSymbols() { @@ -41698,17 +40775,18 @@ namespace ts { } switch (location.kind) { - case SyntaxKind.SourceFile: - if (!isExternalModule(location as SourceFile)) break; + case ts.SyntaxKind.SourceFile: + if (!ts.isExternalModule(location as ts.SourceFile)) + break; // falls through - case SyntaxKind.ModuleDeclaration: - copyLocallyVisibleExportSymbols(getSymbolOfNode(location as ModuleDeclaration | SourceFile).exports!, meaning & SymbolFlags.ModuleMember); + case ts.SyntaxKind.ModuleDeclaration: + copyLocallyVisibleExportSymbols(getSymbolOfNode(location as ts.ModuleDeclaration | ts.SourceFile).exports!, meaning & ts.SymbolFlags.ModuleMember); break; - case SyntaxKind.EnumDeclaration: - copySymbols(getSymbolOfNode(location as EnumDeclaration).exports!, meaning & SymbolFlags.EnumMember); + case ts.SyntaxKind.EnumDeclaration: + copySymbols(getSymbolOfNode(location as ts.EnumDeclaration).exports!, meaning & ts.SymbolFlags.EnumMember); break; - case SyntaxKind.ClassExpression: - const className = (location as ClassExpression).name; + case ts.SyntaxKind.ClassExpression: + const className = (location as ts.ClassExpression).name; if (className) { copySymbol(location.symbol, meaning); } @@ -41716,29 +40794,29 @@ namespace ts { // this fall-through is necessary because we would like to handle // type parameter inside class expression similar to how we handle it in classDeclaration and interface Declaration. // falls through - case SyntaxKind.ClassDeclaration: - case SyntaxKind.InterfaceDeclaration: + case ts.SyntaxKind.ClassDeclaration: + case ts.SyntaxKind.InterfaceDeclaration: // If we didn't come from static member of class or interface, // add the type parameters into the symbol table // (type parameters of classDeclaration/classExpression and interface are in member property of the symbol. // Note: that the memberFlags come from previous iteration. if (!isStaticSymbol) { - copySymbols(getMembersOfSymbol(getSymbolOfNode(location as ClassDeclaration | InterfaceDeclaration)), meaning & SymbolFlags.Type); + copySymbols(getMembersOfSymbol(getSymbolOfNode(location as ts.ClassDeclaration | ts.InterfaceDeclaration)), meaning & ts.SymbolFlags.Type); } break; - case SyntaxKind.FunctionExpression: - const funcName = (location as FunctionExpression).name; + case ts.SyntaxKind.FunctionExpression: + const funcName = (location as ts.FunctionExpression).name; if (funcName) { copySymbol(location.symbol, meaning); } break; } - if (introducesArgumentsExoticObject(location)) { + if (ts.introducesArgumentsExoticObject(location)) { copySymbol(argumentsSymbol, meaning); } - isStaticSymbol = isStatic(location); + isStaticSymbol = ts.isStatic(location); location = location.parent; } @@ -41752,8 +40830,8 @@ namespace ts { * @param symbol the symbol to be added into symbol table * @param meaning meaning of symbol to filter by before adding to symbol table */ - function copySymbol(symbol: Symbol, meaning: SymbolFlags): void { - if (getCombinedLocalAndExportSymbolFlags(symbol) & meaning) { + function copySymbol(symbol: ts.Symbol, meaning: ts.SymbolFlags): void { + if (ts.getCombinedLocalAndExportSymbolFlags(symbol) & meaning) { const id = symbol.escapedName; // We will copy all symbol regardless of its reserved name because // symbolsToArray will check whether the key is a reserved name and @@ -41764,7 +40842,7 @@ namespace ts { } } - function copySymbols(source: SymbolTable, meaning: SymbolFlags): void { + function copySymbols(source: ts.SymbolTable, meaning: ts.SymbolFlags): void { if (meaning) { source.forEach(symbol => { copySymbol(symbol, meaning); @@ -41772,11 +40850,11 @@ namespace ts { } } - function copyLocallyVisibleExportSymbols(source: SymbolTable, meaning: SymbolFlags): void { + function copyLocallyVisibleExportSymbols(source: ts.SymbolTable, meaning: ts.SymbolFlags): void { if (meaning) { source.forEach(symbol => { // Similar condition as in `resolveNameHelper` - if (!getDeclarationOfKind(symbol, SyntaxKind.ExportSpecifier) && !getDeclarationOfKind(symbol, SyntaxKind.NamespaceExport)) { + if (!ts.getDeclarationOfKind(symbol, ts.SyntaxKind.ExportSpecifier) && !ts.getDeclarationOfKind(symbol, ts.SyntaxKind.NamespaceExport)) { copySymbol(symbol, meaning); } }); @@ -41784,68 +40862,70 @@ namespace ts { } } - function isTypeDeclarationName(name: Node): boolean { - return name.kind === SyntaxKind.Identifier && + function isTypeDeclarationName(name: ts.Node): boolean { + return name.kind === ts.SyntaxKind.Identifier && isTypeDeclaration(name.parent) && - getNameOfDeclaration(name.parent) === name; + ts.getNameOfDeclaration(name.parent) === name; } - function isTypeDeclaration(node: Node): node is TypeParameterDeclaration | ClassDeclaration | InterfaceDeclaration | TypeAliasDeclaration | JSDocTypedefTag | JSDocCallbackTag | JSDocEnumTag | EnumDeclaration | ImportClause | ImportSpecifier | ExportSpecifier { + function isTypeDeclaration(node: ts.Node): node is ts.TypeParameterDeclaration | ts.ClassDeclaration | ts.InterfaceDeclaration | ts.TypeAliasDeclaration | ts.JSDocTypedefTag | ts.JSDocCallbackTag | ts.JSDocEnumTag | ts.EnumDeclaration | ts.ImportClause | ts.ImportSpecifier | ts.ExportSpecifier { switch (node.kind) { - case SyntaxKind.TypeParameter: - case SyntaxKind.ClassDeclaration: - case SyntaxKind.InterfaceDeclaration: - case SyntaxKind.TypeAliasDeclaration: - case SyntaxKind.EnumDeclaration: - case SyntaxKind.JSDocTypedefTag: - case SyntaxKind.JSDocCallbackTag: - case SyntaxKind.JSDocEnumTag: + case ts.SyntaxKind.TypeParameter: + case ts.SyntaxKind.ClassDeclaration: + case ts.SyntaxKind.InterfaceDeclaration: + case ts.SyntaxKind.TypeAliasDeclaration: + case ts.SyntaxKind.EnumDeclaration: + case ts.SyntaxKind.JSDocTypedefTag: + case ts.SyntaxKind.JSDocCallbackTag: + case ts.SyntaxKind.JSDocEnumTag: return true; - case SyntaxKind.ImportClause: - return (node as ImportClause).isTypeOnly; - case SyntaxKind.ImportSpecifier: - case SyntaxKind.ExportSpecifier: - return (node as ImportSpecifier | ExportSpecifier).parent.parent.isTypeOnly; + case ts.SyntaxKind.ImportClause: + return (node as ts.ImportClause).isTypeOnly; + case ts.SyntaxKind.ImportSpecifier: + case ts.SyntaxKind.ExportSpecifier: + return (node as ts.ImportSpecifier | ts.ExportSpecifier).parent.parent.isTypeOnly; default: return false; } } // True if the given identifier is part of a type reference - function isTypeReferenceIdentifier(node: EntityName): boolean { - while (node.parent.kind === SyntaxKind.QualifiedName) { - node = node.parent as QualifiedName; + function isTypeReferenceIdentifier(node: ts.EntityName): boolean { + while (node.parent.kind === ts.SyntaxKind.QualifiedName) { + node = node.parent as ts.QualifiedName; } - return node.parent.kind === SyntaxKind.TypeReference; + return node.parent.kind === ts.SyntaxKind.TypeReference; } - function isHeritageClauseElementIdentifier(node: Node): boolean { - while (node.parent.kind === SyntaxKind.PropertyAccessExpression) { + function isHeritageClauseElementIdentifier(node: ts.Node): boolean { + while (node.parent.kind === ts.SyntaxKind.PropertyAccessExpression) { node = node.parent; } - return node.parent.kind === SyntaxKind.ExpressionWithTypeArguments; + return node.parent.kind === ts.SyntaxKind.ExpressionWithTypeArguments; } - function forEachEnclosingClass(node: Node, callback: (node: Node) => T | undefined): T | undefined { + function forEachEnclosingClass(node: ts.Node, callback: (node: ts.Node) => T | undefined): T | undefined { let result: T | undefined; while (true) { - node = getContainingClass(node)!; - if (!node) break; - if (result = callback(node)) break; + node = ts.getContainingClass(node)!; + if (!node) + break; + if (result = callback(node)) + break; } return result; } - function isNodeUsedDuringClassInitialization(node: Node) { - return !!findAncestor(node, element => { - if (isConstructorDeclaration(element) && nodeIsPresent(element.body) || isPropertyDeclaration(element)) { + function isNodeUsedDuringClassInitialization(node: ts.Node) { + return !!ts.findAncestor(node, element => { + if (ts.isConstructorDeclaration(element) && ts.nodeIsPresent(element.body) || ts.isPropertyDeclaration(element)) { return true; } - else if (isClassLike(element) || isFunctionLikeDeclaration(element)) { + else if (ts.isClassLike(element) || ts.isFunctionLikeDeclaration(element)) { return "quit"; } @@ -41853,65 +40933,65 @@ namespace ts { }); } - function isNodeWithinClass(node: Node, classDeclaration: ClassLikeDeclaration) { + function isNodeWithinClass(node: ts.Node, classDeclaration: ts.ClassLikeDeclaration) { return !!forEachEnclosingClass(node, n => n === classDeclaration); } - function getLeftSideOfImportEqualsOrExportAssignment(nodeOnRightSide: EntityName): ImportEqualsDeclaration | ExportAssignment | undefined { - while (nodeOnRightSide.parent.kind === SyntaxKind.QualifiedName) { - nodeOnRightSide = nodeOnRightSide.parent as QualifiedName; + function getLeftSideOfImportEqualsOrExportAssignment(nodeOnRightSide: ts.EntityName): ts.ImportEqualsDeclaration | ts.ExportAssignment | undefined { + while (nodeOnRightSide.parent.kind === ts.SyntaxKind.QualifiedName) { + nodeOnRightSide = nodeOnRightSide.parent as ts.QualifiedName; } - if (nodeOnRightSide.parent.kind === SyntaxKind.ImportEqualsDeclaration) { - return (nodeOnRightSide.parent as ImportEqualsDeclaration).moduleReference === nodeOnRightSide ? nodeOnRightSide.parent as ImportEqualsDeclaration : undefined; + if (nodeOnRightSide.parent.kind === ts.SyntaxKind.ImportEqualsDeclaration) { + return (nodeOnRightSide.parent as ts.ImportEqualsDeclaration).moduleReference === nodeOnRightSide ? nodeOnRightSide.parent as ts.ImportEqualsDeclaration : undefined; } - if (nodeOnRightSide.parent.kind === SyntaxKind.ExportAssignment) { - return (nodeOnRightSide.parent as ExportAssignment).expression === nodeOnRightSide as Node ? nodeOnRightSide.parent as ExportAssignment : undefined; + if (nodeOnRightSide.parent.kind === ts.SyntaxKind.ExportAssignment) { + return (nodeOnRightSide.parent as ts.ExportAssignment).expression === nodeOnRightSide as ts.Node ? nodeOnRightSide.parent as ts.ExportAssignment : undefined; } return undefined; } - function isInRightSideOfImportOrExportAssignment(node: EntityName) { + function isInRightSideOfImportOrExportAssignment(node: ts.EntityName) { return getLeftSideOfImportEqualsOrExportAssignment(node) !== undefined; } - function getSpecialPropertyAssignmentSymbolFromEntityName(entityName: EntityName | PropertyAccessExpression) { - const specialPropertyAssignmentKind = getAssignmentDeclarationKind(entityName.parent.parent as BinaryExpression); + function getSpecialPropertyAssignmentSymbolFromEntityName(entityName: ts.EntityName | ts.PropertyAccessExpression) { + const specialPropertyAssignmentKind = ts.getAssignmentDeclarationKind(entityName.parent.parent as ts.BinaryExpression); switch (specialPropertyAssignmentKind) { - case AssignmentDeclarationKind.ExportsProperty: - case AssignmentDeclarationKind.PrototypeProperty: + case ts.AssignmentDeclarationKind.ExportsProperty: + case ts.AssignmentDeclarationKind.PrototypeProperty: return getSymbolOfNode(entityName.parent); - case AssignmentDeclarationKind.ThisProperty: - case AssignmentDeclarationKind.ModuleExports: - case AssignmentDeclarationKind.Property: + case ts.AssignmentDeclarationKind.ThisProperty: + case ts.AssignmentDeclarationKind.ModuleExports: + case ts.AssignmentDeclarationKind.Property: return getSymbolOfNode(entityName.parent.parent); } } - function isImportTypeQualifierPart(node: EntityName): ImportTypeNode | undefined { + function isImportTypeQualifierPart(node: ts.EntityName): ts.ImportTypeNode | undefined { let parent = node.parent; - while (isQualifiedName(parent)) { + while (ts.isQualifiedName(parent)) { node = parent; parent = parent.parent; } - if (parent && parent.kind === SyntaxKind.ImportType && (parent as ImportTypeNode).qualifier === node) { - return parent as ImportTypeNode; + if (parent && parent.kind === ts.SyntaxKind.ImportType && (parent as ts.ImportTypeNode).qualifier === node) { + return parent as ts.ImportTypeNode; } return undefined; } - function getSymbolOfNameOrPropertyAccessExpression(name: EntityName | PrivateIdentifier | PropertyAccessExpression | JSDocMemberName): Symbol | undefined { - if (isDeclarationName(name)) { + function getSymbolOfNameOrPropertyAccessExpression(name: ts.EntityName | ts.PrivateIdentifier | ts.PropertyAccessExpression | ts.JSDocMemberName): ts.Symbol | undefined { + if (ts.isDeclarationName(name)) { return getSymbolOfNode(name.parent); } - if (isInJSFile(name) && - name.parent.kind === SyntaxKind.PropertyAccessExpression && - name.parent === (name.parent.parent as BinaryExpression).left) { + if (ts.isInJSFile(name) && + name.parent.kind === ts.SyntaxKind.PropertyAccessExpression && + name.parent === (name.parent.parent as ts.BinaryExpression).left) { // Check if this is a special property assignment - if (!isPrivateIdentifier(name) && !isJSDocMemberName(name)) { + if (!ts.isPrivateIdentifier(name) && !ts.isJSDocMemberName(name)) { const specialPropertyAssignmentSymbol = getSpecialPropertyAssignmentSymbolFromEntityName(name); if (specialPropertyAssignmentSymbol) { return specialPropertyAssignmentSymbol; @@ -41919,22 +40999,22 @@ namespace ts { } } - if (name.parent.kind === SyntaxKind.ExportAssignment && isEntityNameExpression(name)) { + if (name.parent.kind === ts.SyntaxKind.ExportAssignment && ts.isEntityNameExpression(name)) { // Even an entity name expression that doesn't resolve as an entityname may still typecheck as a property access expression const success = resolveEntityName(name, - /*all meanings*/ SymbolFlags.Value | SymbolFlags.Type | SymbolFlags.Namespace | SymbolFlags.Alias, /*ignoreErrors*/ true); + /*all meanings*/ ts.SymbolFlags.Value | ts.SymbolFlags.Type | ts.SymbolFlags.Namespace | ts.SymbolFlags.Alias, /*ignoreErrors*/ true); if (success && success !== unknownSymbol) { return success; } } - else if (isEntityName(name) && isInRightSideOfImportOrExportAssignment(name)) { + else if (ts.isEntityName(name) && isInRightSideOfImportOrExportAssignment(name)) { // Since we already checked for ExportAssignment, this really could only be an Import - const importEqualsDeclaration = getAncestor(name, SyntaxKind.ImportEqualsDeclaration); - Debug.assert(importEqualsDeclaration !== undefined); + const importEqualsDeclaration = ts.getAncestor(name, ts.SyntaxKind.ImportEqualsDeclaration); + ts.Debug.assert(importEqualsDeclaration !== undefined); return getSymbolOfPartOfRightHandSideOfImportEquals(name, /*dontResolveAlias*/ true); } - if (isEntityName(name)) { + if (ts.isEntityName(name)) { const possibleImportNode = isImportTypeQualifierPart(name); if (possibleImportNode) { getTypeFromTypeNode(possibleImportNode); @@ -41943,95 +41023,97 @@ namespace ts { } } - while (isRightSideOfQualifiedNameOrPropertyAccessOrJSDocMemberName(name)) { - name = name.parent as QualifiedName | PropertyAccessEntityNameExpression | JSDocMemberName; + while (ts.isRightSideOfQualifiedNameOrPropertyAccessOrJSDocMemberName(name)) { + name = name.parent as ts.QualifiedName | ts.PropertyAccessEntityNameExpression | ts.JSDocMemberName; } if (isHeritageClauseElementIdentifier(name)) { - let meaning = SymbolFlags.None; + let meaning = ts.SymbolFlags.None; // In an interface or class, we're definitely interested in a type. - if (name.parent.kind === SyntaxKind.ExpressionWithTypeArguments) { - meaning = SymbolFlags.Type; + if (name.parent.kind === ts.SyntaxKind.ExpressionWithTypeArguments) { + meaning = ts.SymbolFlags.Type; // In a class 'extends' clause we are also looking for a value. - if (isExpressionWithTypeArgumentsInClassExtendsClause(name.parent)) { - meaning |= SymbolFlags.Value; + if (ts.isExpressionWithTypeArgumentsInClassExtendsClause(name.parent)) { + meaning |= ts.SymbolFlags.Value; } } else { - meaning = SymbolFlags.Namespace; + meaning = ts.SymbolFlags.Namespace; } - meaning |= SymbolFlags.Alias; - const entityNameSymbol = isEntityNameExpression(name) ? resolveEntityName(name, meaning) : undefined; + meaning |= ts.SymbolFlags.Alias; + const entityNameSymbol = ts.isEntityNameExpression(name) ? resolveEntityName(name, meaning) : undefined; if (entityNameSymbol) { return entityNameSymbol; } } - if (name.parent.kind === SyntaxKind.JSDocParameterTag) { - return getParameterSymbolFromJSDoc(name.parent as JSDocParameterTag); + if (name.parent.kind === ts.SyntaxKind.JSDocParameterTag) { + return ts.getParameterSymbolFromJSDoc(name.parent as ts.JSDocParameterTag); } - if (name.parent.kind === SyntaxKind.TypeParameter && name.parent.parent.kind === SyntaxKind.JSDocTemplateTag) { - Debug.assert(!isInJSFile(name)); // Otherwise `isDeclarationName` would have been true. - const typeParameter = getTypeParameterFromJsDoc(name.parent as TypeParameterDeclaration & { parent: JSDocTemplateTag }); + if (name.parent.kind === ts.SyntaxKind.TypeParameter && name.parent.parent.kind === ts.SyntaxKind.JSDocTemplateTag) { + ts.Debug.assert(!ts.isInJSFile(name)); // Otherwise `isDeclarationName` would have been true. + const typeParameter = ts.getTypeParameterFromJsDoc(name.parent as ts.TypeParameterDeclaration & { + parent: ts.JSDocTemplateTag; + }); return typeParameter && typeParameter.symbol; } - if (isExpressionNode(name)) { - if (nodeIsMissing(name)) { + if (ts.isExpressionNode(name)) { + if (ts.nodeIsMissing(name)) { // Missing entity name. return undefined; } - const isJSDoc = findAncestor(name, or(isJSDocLinkLike, isJSDocNameReference, isJSDocMemberName)); - const meaning = isJSDoc ? SymbolFlags.Type | SymbolFlags.Namespace | SymbolFlags.Value : SymbolFlags.Value; - if (name.kind === SyntaxKind.Identifier) { - if (isJSXTagName(name) && isJsxIntrinsicIdentifier(name)) { - const symbol = getIntrinsicTagSymbol(name.parent as JsxOpeningLikeElement); + const isJSDoc = ts.findAncestor(name, ts.or(ts.isJSDocLinkLike, ts.isJSDocNameReference, ts.isJSDocMemberName)); + const meaning = isJSDoc ? ts.SymbolFlags.Type | ts.SymbolFlags.Namespace | ts.SymbolFlags.Value : ts.SymbolFlags.Value; + if (name.kind === ts.SyntaxKind.Identifier) { + if (ts.isJSXTagName(name) && isJsxIntrinsicIdentifier(name)) { + const symbol = getIntrinsicTagSymbol(name.parent as ts.JsxOpeningLikeElement); return symbol === unknownSymbol ? undefined : symbol; } - const result = resolveEntityName(name, meaning, /*ignoreErrors*/ false, /* dontResolveAlias */ true, getHostSignatureFromJSDoc(name)); + const result = resolveEntityName(name, meaning, /*ignoreErrors*/ false, /* dontResolveAlias */ true, ts.getHostSignatureFromJSDoc(name)); if (!result && isJSDoc) { - const container = findAncestor(name, or(isClassLike, isInterfaceDeclaration)); + const container = ts.findAncestor(name, ts.or(ts.isClassLike, ts.isInterfaceDeclaration)); if (container) { return resolveJSDocMemberName(name, getSymbolOfNode(container)); } } return result; } - else if (isPrivateIdentifier(name)) { + else if (ts.isPrivateIdentifier(name)) { return getSymbolForPrivateIdentifierExpression(name); } - else if (name.kind === SyntaxKind.PropertyAccessExpression || name.kind === SyntaxKind.QualifiedName) { + else if (name.kind === ts.SyntaxKind.PropertyAccessExpression || name.kind === ts.SyntaxKind.QualifiedName) { const links = getNodeLinks(name); if (links.resolvedSymbol) { return links.resolvedSymbol; } - if (name.kind === SyntaxKind.PropertyAccessExpression) { + if (name.kind === ts.SyntaxKind.PropertyAccessExpression) { checkPropertyAccessExpression(name, CheckMode.Normal); } else { checkQualifiedName(name, CheckMode.Normal); } - if (!links.resolvedSymbol && isJSDoc && isQualifiedName(name)) { + if (!links.resolvedSymbol && isJSDoc && ts.isQualifiedName(name)) { return resolveJSDocMemberName(name); } return links.resolvedSymbol; } - else if (isJSDocMemberName(name)) { + else if (ts.isJSDocMemberName(name)) { return resolveJSDocMemberName(name); } } - else if (isTypeReferenceIdentifier(name as EntityName)) { - const meaning = name.parent.kind === SyntaxKind.TypeReference ? SymbolFlags.Type : SymbolFlags.Namespace; - const symbol = resolveEntityName(name as EntityName, meaning, /*ignoreErrors*/ false, /*dontResolveAlias*/ true); - return symbol && symbol !== unknownSymbol ? symbol : getUnresolvedSymbolForEntityName(name as EntityName); + else if (isTypeReferenceIdentifier(name as ts.EntityName)) { + const meaning = name.parent.kind === ts.SyntaxKind.TypeReference ? ts.SymbolFlags.Type : ts.SymbolFlags.Namespace; + const symbol = resolveEntityName(name as ts.EntityName, meaning, /*ignoreErrors*/ false, /*dontResolveAlias*/ true); + return symbol && symbol !== unknownSymbol ? symbol : getUnresolvedSymbolForEntityName(name as ts.EntityName); } - if (name.parent.kind === SyntaxKind.TypePredicate) { - return resolveEntityName(name as Identifier, /*meaning*/ SymbolFlags.FunctionScopedVariable); + if (name.parent.kind === ts.SyntaxKind.TypePredicate) { + return resolveEntityName(name as ts.Identifier, /*meaning*/ ts.SymbolFlags.FunctionScopedVariable); } return undefined; @@ -42045,35 +41127,35 @@ namespace ts { * * For unqualified names, a container K may be provided as a second argument. */ - function resolveJSDocMemberName(name: EntityName | JSDocMemberName, container?: Symbol): Symbol | undefined { - if (isEntityName(name)) { + function resolveJSDocMemberName(name: ts.EntityName | ts.JSDocMemberName, container?: ts.Symbol): ts.Symbol | undefined { + if (ts.isEntityName(name)) { // resolve static values first - const meaning = SymbolFlags.Type | SymbolFlags.Namespace | SymbolFlags.Value; - let symbol = resolveEntityName(name, meaning, /*ignoreErrors*/ false, /*dontResolveAlias*/ true, getHostSignatureFromJSDoc(name)); - if (!symbol && isIdentifier(name) && container) { + const meaning = ts.SymbolFlags.Type | ts.SymbolFlags.Namespace | ts.SymbolFlags.Value; + let symbol = resolveEntityName(name, meaning, /*ignoreErrors*/ false, /*dontResolveAlias*/ true, ts.getHostSignatureFromJSDoc(name)); + if (!symbol && ts.isIdentifier(name) && container) { symbol = getMergedSymbol(getSymbol(getExportsOfSymbol(container), name.escapedText, meaning)); } if (symbol) { return symbol; } } - const left = isIdentifier(name) ? container : resolveJSDocMemberName(name.left); - const right = isIdentifier(name) ? name.escapedText : name.right.escapedText; + const left = ts.isIdentifier(name) ? container : resolveJSDocMemberName(name.left); + const right = ts.isIdentifier(name) ? name.escapedText : name.right.escapedText; if (left) { - const proto = left.flags & SymbolFlags.Value && getPropertyOfType(getTypeOfSymbol(left), "prototype" as __String); + const proto = left.flags & ts.SymbolFlags.Value && getPropertyOfType(getTypeOfSymbol(left), "prototype" as ts.__String); const t = proto ? getTypeOfSymbol(proto) : getDeclaredTypeOfSymbol(left); return getPropertyOfType(t, right); } } - function getSymbolAtLocation(node: Node, ignoreErrors?: boolean): Symbol | undefined { - if (node.kind === SyntaxKind.SourceFile) { - return isExternalModule(node as SourceFile) ? getMergedSymbol(node.symbol) : undefined; + function getSymbolAtLocation(node: ts.Node, ignoreErrors?: boolean): ts.Symbol | undefined { + if (node.kind === ts.SyntaxKind.SourceFile) { + return ts.isExternalModule(node as ts.SourceFile) ? getMergedSymbol(node.symbol) : undefined; } const { parent } = node; const grandParent = parent.parent; - if (node.flags & NodeFlags.InWithStatement) { + if (node.flags & ts.NodeFlags.InWithStatement) { // We cannot answer semantic questions within a with block, do not proceed any further return undefined; } @@ -42081,30 +41163,30 @@ namespace ts { if (isDeclarationNameOrImportPropertyName(node)) { // This is a declaration, call getSymbolOfNode const parentSymbol = getSymbolOfNode(parent)!; - return isImportOrExportSpecifier(node.parent) && node.parent.propertyName === node + return ts.isImportOrExportSpecifier(node.parent) && node.parent.propertyName === node ? getImmediateAliasedSymbol(parentSymbol) : parentSymbol; } - else if (isLiteralComputedPropertyDeclarationName(node)) { + else if (ts.isLiteralComputedPropertyDeclarationName(node)) { return getSymbolOfNode(parent.parent); } - if (node.kind === SyntaxKind.Identifier) { - if (isInRightSideOfImportOrExportAssignment(node as Identifier)) { - return getSymbolOfNameOrPropertyAccessExpression(node as Identifier); + if (node.kind === ts.SyntaxKind.Identifier) { + if (isInRightSideOfImportOrExportAssignment(node as ts.Identifier)) { + return getSymbolOfNameOrPropertyAccessExpression(node as ts.Identifier); } - else if (parent.kind === SyntaxKind.BindingElement && - grandParent.kind === SyntaxKind.ObjectBindingPattern && - node === (parent as BindingElement).propertyName) { + else if (parent.kind === ts.SyntaxKind.BindingElement && + grandParent.kind === ts.SyntaxKind.ObjectBindingPattern && + node === (parent as ts.BindingElement).propertyName) { const typeOfPattern = getTypeOfNode(grandParent); - const propertyDeclaration = getPropertyOfType(typeOfPattern, (node as Identifier).escapedText); + const propertyDeclaration = getPropertyOfType(typeOfPattern, (node as ts.Identifier).escapedText); if (propertyDeclaration) { return propertyDeclaration; } } - else if (isMetaProperty(parent) && parent.name === node) { - if (parent.keywordToken === SyntaxKind.NewKeyword && idText(node as Identifier) === "target") { + else if (ts.isMetaProperty(parent) && parent.name === node) { + if (parent.keywordToken === ts.SyntaxKind.NewKeyword && ts.idText(node as ts.Identifier) === "target") { // `target` in `new.target` return checkNewTargetMetaProperty(parent).symbol; } @@ -42112,8 +41194,8 @@ namespace ts { // we have a fake expression type made for other reasons already, whose transient `meta` // member should more exactly be the kind of (declarationless) symbol we want. // (See #44364 and #45031 for relevant implementation PRs) - if (parent.keywordToken === SyntaxKind.ImportKeyword && idText(node as Identifier) === "meta") { - return getGlobalImportMetaExpressionType().members!.get("meta" as __String); + if (parent.keywordToken === ts.SyntaxKind.ImportKeyword && ts.idText(node as ts.Identifier) === "meta") { + return getGlobalImportMetaExpressionType().members!.get("meta" as ts.__String); } // no other meta properties are valid syntax, thus no others should have symbols return undefined; @@ -42121,145 +41203,139 @@ namespace ts { } switch (node.kind) { - case SyntaxKind.Identifier: - case SyntaxKind.PrivateIdentifier: - case SyntaxKind.PropertyAccessExpression: - case SyntaxKind.QualifiedName: - if (!isThisInTypeQuery(node)) { - return getSymbolOfNameOrPropertyAccessExpression(node as EntityName | PrivateIdentifier | PropertyAccessExpression); + case ts.SyntaxKind.Identifier: + case ts.SyntaxKind.PrivateIdentifier: + case ts.SyntaxKind.PropertyAccessExpression: + case ts.SyntaxKind.QualifiedName: + if (!ts.isThisInTypeQuery(node)) { + return getSymbolOfNameOrPropertyAccessExpression(node as ts.EntityName | ts.PrivateIdentifier | ts.PropertyAccessExpression); } // falls through - case SyntaxKind.ThisKeyword: - const container = getThisContainer(node, /*includeArrowFunctions*/ false); - if (isFunctionLike(container)) { + case ts.SyntaxKind.ThisKeyword: + const container = ts.getThisContainer(node, /*includeArrowFunctions*/ false); + if (ts.isFunctionLike(container)) { const sig = getSignatureFromDeclaration(container); if (sig.thisParameter) { return sig.thisParameter; } } - if (isInExpressionContext(node)) { - return checkExpression(node as Expression).symbol; + if (ts.isInExpressionContext(node)) { + return checkExpression(node as ts.Expression).symbol; } // falls through - case SyntaxKind.ThisType: - return getTypeFromThisTypeNode(node as ThisExpression | ThisTypeNode).symbol; - - case SyntaxKind.SuperKeyword: - return checkExpression(node as Expression).symbol; - - case SyntaxKind.ConstructorKeyword: + case ts.SyntaxKind.ThisType: + return getTypeFromThisTypeNode(node as ts.ThisExpression | ts.ThisTypeNode).symbol; + case ts.SyntaxKind.SuperKeyword: + return checkExpression(node as ts.Expression).symbol; + case ts.SyntaxKind.ConstructorKeyword: // constructor keyword for an overload, should take us to the definition if it exist const constructorDeclaration = node.parent; - if (constructorDeclaration && constructorDeclaration.kind === SyntaxKind.Constructor) { - return (constructorDeclaration.parent as ClassDeclaration).symbol; + if (constructorDeclaration && constructorDeclaration.kind === ts.SyntaxKind.Constructor) { + return (constructorDeclaration.parent as ts.ClassDeclaration).symbol; } return undefined; - case SyntaxKind.StringLiteral: - case SyntaxKind.NoSubstitutionTemplateLiteral: + case ts.SyntaxKind.StringLiteral: + case ts.SyntaxKind.NoSubstitutionTemplateLiteral: // 1). import x = require("./mo/*gotToDefinitionHere*/d") // 2). External module name in an import declaration // 3). Dynamic import call or require in javascript // 4). type A = import("./f/*gotToDefinitionHere*/oo") - if ((isExternalModuleImportEqualsDeclaration(node.parent.parent) && getExternalModuleImportEqualsDeclarationExpression(node.parent.parent) === node) || - ((node.parent.kind === SyntaxKind.ImportDeclaration || node.parent.kind === SyntaxKind.ExportDeclaration) && (node.parent as ImportDeclaration).moduleSpecifier === node) || - ((isInJSFile(node) && isRequireCall(node.parent, /*checkArgumentIsStringLiteralLike*/ false)) || isImportCall(node.parent)) || - (isLiteralTypeNode(node.parent) && isLiteralImportTypeNode(node.parent.parent) && node.parent.parent.argument === node.parent) - ) { - return resolveExternalModuleName(node, node as LiteralExpression, ignoreErrors); - } - if (isCallExpression(parent) && isBindableObjectDefinePropertyCall(parent) && parent.arguments[1] === node) { + if ((ts.isExternalModuleImportEqualsDeclaration(node.parent.parent) && ts.getExternalModuleImportEqualsDeclarationExpression(node.parent.parent) === node) || + ((node.parent.kind === ts.SyntaxKind.ImportDeclaration || node.parent.kind === ts.SyntaxKind.ExportDeclaration) && (node.parent as ts.ImportDeclaration).moduleSpecifier === node) || + ((ts.isInJSFile(node) && ts.isRequireCall(node.parent, /*checkArgumentIsStringLiteralLike*/ false)) || ts.isImportCall(node.parent)) || + (ts.isLiteralTypeNode(node.parent) && ts.isLiteralImportTypeNode(node.parent.parent) && node.parent.parent.argument === node.parent)) { + return resolveExternalModuleName(node, node as ts.LiteralExpression, ignoreErrors); + } + if (ts.isCallExpression(parent) && ts.isBindableObjectDefinePropertyCall(parent) && parent.arguments[1] === node) { return getSymbolOfNode(parent); } // falls through - case SyntaxKind.NumericLiteral: + case ts.SyntaxKind.NumericLiteral: // index access - const objectType = isElementAccessExpression(parent) + const objectType = ts.isElementAccessExpression(parent) ? parent.argumentExpression === node ? getTypeOfExpression(parent.expression) : undefined - : isLiteralTypeNode(parent) && isIndexedAccessTypeNode(grandParent) + : ts.isLiteralTypeNode(parent) && ts.isIndexedAccessTypeNode(grandParent) ? getTypeFromTypeNode(grandParent.objectType) : undefined; - return objectType && getPropertyOfType(objectType, escapeLeadingUnderscores((node as StringLiteral | NumericLiteral).text)); - - case SyntaxKind.DefaultKeyword: - case SyntaxKind.FunctionKeyword: - case SyntaxKind.EqualsGreaterThanToken: - case SyntaxKind.ClassKeyword: + return objectType && getPropertyOfType(objectType, ts.escapeLeadingUnderscores((node as ts.StringLiteral | ts.NumericLiteral).text)); + case ts.SyntaxKind.DefaultKeyword: + case ts.SyntaxKind.FunctionKeyword: + case ts.SyntaxKind.EqualsGreaterThanToken: + case ts.SyntaxKind.ClassKeyword: return getSymbolOfNode(node.parent); - case SyntaxKind.ImportType: - return isLiteralImportTypeNode(node) ? getSymbolAtLocation(node.argument.literal, ignoreErrors) : undefined; - - case SyntaxKind.ExportKeyword: - return isExportAssignment(node.parent) ? Debug.checkDefined(node.parent.symbol) : undefined; - - case SyntaxKind.ImportKeyword: - case SyntaxKind.NewKeyword: - return isMetaProperty(node.parent) ? checkMetaPropertyKeyword(node.parent).symbol : undefined; - case SyntaxKind.MetaProperty: - return checkExpression(node as Expression).symbol; + case ts.SyntaxKind.ImportType: + return ts.isLiteralImportTypeNode(node) ? getSymbolAtLocation(node.argument.literal, ignoreErrors) : undefined; + case ts.SyntaxKind.ExportKeyword: + return ts.isExportAssignment(node.parent) ? ts.Debug.checkDefined(node.parent.symbol) : undefined; + case ts.SyntaxKind.ImportKeyword: + case ts.SyntaxKind.NewKeyword: + return ts.isMetaProperty(node.parent) ? checkMetaPropertyKeyword(node.parent).symbol : undefined; + case ts.SyntaxKind.MetaProperty: + return checkExpression(node as ts.Expression).symbol; default: return undefined; } } - function getIndexInfosAtLocation(node: Node): readonly IndexInfo[] | undefined { - if (isIdentifier(node) && isPropertyAccessExpression(node.parent) && node.parent.name === node) { + function getIndexInfosAtLocation(node: ts.Node): readonly ts.IndexInfo[] | undefined { + if (ts.isIdentifier(node) && ts.isPropertyAccessExpression(node.parent) && node.parent.name === node) { const keyType = getLiteralTypeFromPropertyName(node); const objectType = getTypeOfExpression(node.parent.expression); - const objectTypes = objectType.flags & TypeFlags.Union ? (objectType as UnionType).types : [objectType]; - return flatMap(objectTypes, t => filter(getIndexInfosOfType(t), info => isApplicableIndexType(keyType, info.keyType))); + const objectTypes = objectType.flags & ts.TypeFlags.Union ? (objectType as ts.UnionType).types : [objectType]; + return ts.flatMap(objectTypes, t => ts.filter(getIndexInfosOfType(t), info => isApplicableIndexType(keyType, info.keyType))); } return undefined; } - function getShorthandAssignmentValueSymbol(location: Node | undefined): Symbol | undefined { - if (location && location.kind === SyntaxKind.ShorthandPropertyAssignment) { - return resolveEntityName((location as ShorthandPropertyAssignment).name, SymbolFlags.Value | SymbolFlags.Alias); + function getShorthandAssignmentValueSymbol(location: ts.Node | undefined): ts.Symbol | undefined { + if (location && location.kind === ts.SyntaxKind.ShorthandPropertyAssignment) { + return resolveEntityName((location as ts.ShorthandPropertyAssignment).name, ts.SymbolFlags.Value | ts.SymbolFlags.Alias); } return undefined; } /** Returns the target of an export specifier without following aliases */ - function getExportSpecifierLocalTargetSymbol(node: ExportSpecifier | Identifier): Symbol | undefined { - if (isExportSpecifier(node)) { + function getExportSpecifierLocalTargetSymbol(node: ts.ExportSpecifier | ts.Identifier): ts.Symbol | undefined { + if (ts.isExportSpecifier(node)) { return node.parent.parent.moduleSpecifier ? getExternalModuleMember(node.parent.parent, node) : - resolveEntityName(node.propertyName || node.name, SymbolFlags.Value | SymbolFlags.Type | SymbolFlags.Namespace | SymbolFlags.Alias); + resolveEntityName(node.propertyName || node.name, ts.SymbolFlags.Value | ts.SymbolFlags.Type | ts.SymbolFlags.Namespace | ts.SymbolFlags.Alias); } else { - return resolveEntityName(node, SymbolFlags.Value | SymbolFlags.Type | SymbolFlags.Namespace | SymbolFlags.Alias); + return resolveEntityName(node, ts.SymbolFlags.Value | ts.SymbolFlags.Type | ts.SymbolFlags.Namespace | ts.SymbolFlags.Alias); } } - function getTypeOfNode(node: Node): Type { - if (isSourceFile(node) && !isExternalModule(node)) { + function getTypeOfNode(node: ts.Node): ts.Type { + if (ts.isSourceFile(node) && !ts.isExternalModule(node)) { return errorType; } - if (node.flags & NodeFlags.InWithStatement) { + if (node.flags & ts.NodeFlags.InWithStatement) { // We cannot answer semantic questions within a with block, do not proceed any further return errorType; } - const classDecl = tryGetClassImplementingOrExtendingExpressionWithTypeArguments(node); + const classDecl = ts.tryGetClassImplementingOrExtendingExpressionWithTypeArguments(node); const classType = classDecl && getDeclaredTypeOfClassOrInterface(getSymbolOfNode(classDecl.class)); - if (isPartOfTypeNode(node)) { - const typeFromTypeNode = getTypeFromTypeNode(node as TypeNode); + if (ts.isPartOfTypeNode(node)) { + const typeFromTypeNode = getTypeFromTypeNode(node as ts.TypeNode); return classType ? getTypeWithThisArgument(typeFromTypeNode, classType.thisType) : typeFromTypeNode; } - if (isExpressionNode(node)) { - return getRegularTypeOfExpression(node as Expression); + if (ts.isExpressionNode(node)) { + return getRegularTypeOfExpression(node as ts.Expression); } if (classType && !classDecl.isImplements) { // A SyntaxKind.ExpressionWithTypeArguments is considered a type node, except when it occurs in the // extends clause of a class. We handle that case here. - const baseType = firstOrUndefined(getBaseTypes(classType)); + const baseType = ts.firstOrUndefined(getBaseTypes(classType)); return baseType ? getTypeWithThisArgument(baseType, classType.thisType) : errorType; } @@ -42274,7 +41350,7 @@ namespace ts { return symbol ? getDeclaredTypeOfSymbol(symbol) : errorType; } - if (isDeclaration(node)) { + if (ts.isDeclaration(node)) { // In this case, we call getSymbolOfNode instead of getSymbolAtLocation because it is a declaration const symbol = getSymbolOfNode(node); return symbol ? getTypeOfSymbol(symbol) : errorType; @@ -42288,11 +41364,11 @@ namespace ts { return errorType; } - if (isBindingPattern(node)) { + if (ts.isBindingPattern(node)) { return getTypeForVariableLikeDeclaration(node.parent, /*includeOptionality*/ true, CheckMode.Normal) || errorType; } - if (isInRightSideOfImportOrExportAssignment(node as Identifier)) { + if (isInRightSideOfImportOrExportAssignment(node as ts.Identifier)) { const symbol = getSymbolAtLocation(node); if (symbol) { const declaredType = getDeclaredTypeOfSymbol(symbol); @@ -42300,7 +41376,7 @@ namespace ts { } } - if (isMetaProperty(node.parent) && node.parent.keywordToken === node.kind) { + if (ts.isMetaProperty(node.parent) && node.parent.keywordToken === node.kind) { return checkMetaPropertyKeyword(node.parent); } @@ -42313,31 +41389,31 @@ namespace ts { // } // [ a ] from // [a] = [ some array ...] - function getTypeOfAssignmentPattern(expr: AssignmentPattern): Type | undefined { - Debug.assert(expr.kind === SyntaxKind.ObjectLiteralExpression || expr.kind === SyntaxKind.ArrayLiteralExpression); + function getTypeOfAssignmentPattern(expr: ts.AssignmentPattern): ts.Type | undefined { + ts.Debug.assert(expr.kind === ts.SyntaxKind.ObjectLiteralExpression || expr.kind === ts.SyntaxKind.ArrayLiteralExpression); // If this is from "for of" // for ( { a } of elems) { // } - if (expr.parent.kind === SyntaxKind.ForOfStatement) { - const iteratedType = checkRightHandSideOfForOf(expr.parent as ForOfStatement); + if (expr.parent.kind === ts.SyntaxKind.ForOfStatement) { + const iteratedType = checkRightHandSideOfForOf(expr.parent as ts.ForOfStatement); return checkDestructuringAssignment(expr, iteratedType || errorType); } // If this is from "for" initializer // for ({a } = elems[0];.....) { } - if (expr.parent.kind === SyntaxKind.BinaryExpression) { - const iteratedType = getTypeOfExpression((expr.parent as BinaryExpression).right); + if (expr.parent.kind === ts.SyntaxKind.BinaryExpression) { + const iteratedType = getTypeOfExpression((expr.parent as ts.BinaryExpression).right); return checkDestructuringAssignment(expr, iteratedType || errorType); } // If this is from nested object binding pattern // for ({ skills: { primary, secondary } } = multiRobot, i = 0; i < 1; i++) { - if (expr.parent.kind === SyntaxKind.PropertyAssignment) { - const node = cast(expr.parent.parent, isObjectLiteralExpression); + if (expr.parent.kind === ts.SyntaxKind.PropertyAssignment) { + const node = ts.cast(expr.parent.parent, ts.isObjectLiteralExpression); const typeOfParentObjectLiteral = getTypeOfAssignmentPattern(node) || errorType; - const propertyIndex = indexOfNode(node.properties, expr.parent); + const propertyIndex = ts.indexOfNode(node.properties, expr.parent); return checkObjectLiteralDestructuringPropertyAssignment(node, typeOfParentObjectLiteral, propertyIndex); } // Array literal assignment - array destructuring pattern - const node = cast(expr.parent, isArrayLiteralExpression); + const node = ts.cast(expr.parent, ts.isArrayLiteralExpression); // [{ property1: p1, property2 }] = elems; const typeOfArrayLiteral = getTypeOfAssignmentPattern(node) || errorType; const elementType = checkIteratedTypeOrElementType(IterationUse.Destructuring, typeOfArrayLiteral, undefinedType, expr.parent) || errorType; @@ -42350,15 +41426,15 @@ namespace ts { // } // 'property1' at location 'a' from: // [a] = [ property1, property2 ] - function getPropertySymbolOfDestructuringAssignment(location: Identifier) { + function getPropertySymbolOfDestructuringAssignment(location: ts.Identifier) { // Get the type of the object or array literal and then look for property of given name in the type - const typeOfObjectLiteral = getTypeOfAssignmentPattern(cast(location.parent.parent, isAssignmentPattern)); + const typeOfObjectLiteral = getTypeOfAssignmentPattern(ts.cast(location.parent.parent, ts.isAssignmentPattern)); return typeOfObjectLiteral && getPropertyOfType(typeOfObjectLiteral, location.escapedText); } - function getRegularTypeOfExpression(expr: Expression): Type { - if (isRightSideOfQualifiedNameOrPropertyAccess(expr)) { - expr = expr.parent as Expression; + function getRegularTypeOfExpression(expr: ts.Expression): ts.Type { + if (ts.isRightSideOfQualifiedNameOrPropertyAccess(expr)) { + expr = expr.parent as ts.Expression; } return getRegularTypeOfLiteralType(getTypeOfExpression(expr)); } @@ -42367,39 +41443,39 @@ namespace ts { * Gets either the static or instance type of a class element, based on * whether the element is declared as "static". */ - function getParentTypeOfClassElement(node: ClassElement) { + function getParentTypeOfClassElement(node: ts.ClassElement) { const classSymbol = getSymbolOfNode(node.parent)!; - return isStatic(node) + return ts.isStatic(node) ? getTypeOfSymbol(classSymbol) : getDeclaredTypeOfSymbol(classSymbol); } - function getClassElementPropertyKeyType(element: ClassElement) { + function getClassElementPropertyKeyType(element: ts.ClassElement) { const name = element.name!; switch (name.kind) { - case SyntaxKind.Identifier: - return getStringLiteralType(idText(name)); - case SyntaxKind.NumericLiteral: - case SyntaxKind.StringLiteral: + case ts.SyntaxKind.Identifier: + return getStringLiteralType(ts.idText(name)); + case ts.SyntaxKind.NumericLiteral: + case ts.SyntaxKind.StringLiteral: return getStringLiteralType(name.text); - case SyntaxKind.ComputedPropertyName: + case ts.SyntaxKind.ComputedPropertyName: const nameType = checkComputedPropertyName(name); - return isTypeAssignableToKind(nameType, TypeFlags.ESSymbolLike) ? nameType : stringType; + return isTypeAssignableToKind(nameType, ts.TypeFlags.ESSymbolLike) ? nameType : stringType; default: - return Debug.fail("Unsupported property name."); + return ts.Debug.fail("Unsupported property name."); } } // Return the list of properties of the given type, augmented with properties from Function // if the type has call or construct signatures - function getAugmentedPropertiesOfType(type: Type): Symbol[] { + function getAugmentedPropertiesOfType(type: ts.Type): ts.Symbol[] { type = getApparentType(type); - const propsByName = createSymbolTable(getPropertiesOfType(type)); - const functionType = getSignaturesOfType(type, SignatureKind.Call).length ? globalCallableFunctionType : - getSignaturesOfType(type, SignatureKind.Construct).length ? globalNewableFunctionType : + const propsByName = ts.createSymbolTable(getPropertiesOfType(type)); + const functionType = getSignaturesOfType(type, ts.SignatureKind.Call).length ? globalCallableFunctionType : + getSignaturesOfType(type, ts.SignatureKind.Construct).length ? globalNewableFunctionType : undefined; if (functionType) { - forEach(getPropertiesOfType(functionType), p => { + ts.forEach(getPropertiesOfType(functionType), p => { if (!propsByName.has(p.escapedName)) { propsByName.set(p.escapedName, p); } @@ -42408,29 +41484,29 @@ namespace ts { return getNamedMembers(propsByName); } - function typeHasCallOrConstructSignatures(type: Type): boolean { + function typeHasCallOrConstructSignatures(type: ts.Type): boolean { return ts.typeHasCallOrConstructSignatures(type, checker); } - function getRootSymbols(symbol: Symbol): readonly Symbol[] { + function getRootSymbols(symbol: ts.Symbol): readonly ts.Symbol[] { const roots = getImmediateRootSymbols(symbol); - return roots ? flatMap(roots, getRootSymbols) : [symbol]; + return roots ? ts.flatMap(roots, getRootSymbols) : [symbol]; } - function getImmediateRootSymbols(symbol: Symbol): readonly Symbol[] | undefined { - if (getCheckFlags(symbol) & CheckFlags.Synthetic) { - return mapDefined(getSymbolLinks(symbol).containingType!.types, type => getPropertyOfType(type, symbol.escapedName)); + function getImmediateRootSymbols(symbol: ts.Symbol): readonly ts.Symbol[] | undefined { + if (ts.getCheckFlags(symbol) & ts.CheckFlags.Synthetic) { + return ts.mapDefined(getSymbolLinks(symbol).containingType!.types, type => getPropertyOfType(type, symbol.escapedName)); } - else if (symbol.flags & SymbolFlags.Transient) { - const { leftSpread, rightSpread, syntheticOrigin } = symbol as TransientSymbol; + else if (symbol.flags & ts.SymbolFlags.Transient) { + const { leftSpread, rightSpread, syntheticOrigin } = symbol as ts.TransientSymbol; return leftSpread ? [leftSpread, rightSpread!] : syntheticOrigin ? [syntheticOrigin] - : singleElementArray(tryGetTarget(symbol)); + : ts.singleElementArray(tryGetTarget(symbol)); } return undefined; } - function tryGetTarget(symbol: Symbol): Symbol | undefined { - let target: Symbol | undefined; - let next: Symbol | undefined = symbol; + function tryGetTarget(symbol: ts.Symbol): ts.Symbol | undefined { + let target: ts.Symbol | undefined; + let next: ts.Symbol | undefined = symbol; while (next = getSymbolLinks(next).target) { target = next; } @@ -42439,22 +41515,25 @@ namespace ts { // Emitter support - function isArgumentsLocalBinding(nodeIn: Identifier): boolean { + function isArgumentsLocalBinding(nodeIn: ts.Identifier): boolean { // Note: does not handle isShorthandPropertyAssignment (and probably a few more) - if (isGeneratedIdentifier(nodeIn)) return false; - const node = getParseTreeNode(nodeIn, isIdentifier); - if (!node) return false; + if (ts.isGeneratedIdentifier(nodeIn)) + return false; + const node = ts.getParseTreeNode(nodeIn, ts.isIdentifier); + if (!node) + return false; const parent = node.parent; - if (!parent) return false; - const isPropertyName = ((isPropertyAccessExpression(parent) - || isPropertyAssignment(parent)) + if (!parent) + return false; + const isPropertyName = ((ts.isPropertyAccessExpression(parent) + || ts.isPropertyAssignment(parent)) && parent.name === node); return !isPropertyName && getReferencedValueSymbol(node) === argumentsSymbol; } - function moduleExportsSomeValue(moduleReferenceExpression: Expression): boolean { + function moduleExportsSomeValue(moduleReferenceExpression: ts.Expression): boolean { let moduleSymbol = resolveExternalModuleName(moduleReferenceExpression.parent, moduleReferenceExpression); - if (!moduleSymbol || isShorthandAmbientModuleSymbol(moduleSymbol)) { + if (!moduleSymbol || ts.isShorthandAmbientModuleSymbol(moduleSymbol)) { // If the module is not found or is shorthand, assume that it may export a value. return true; } @@ -42469,26 +41548,26 @@ namespace ts { // for export assignments - check if resolved symbol for RHS is itself a value // otherwise - check if at least one export is value symbolLinks.exportsSomeValue = hasExportAssignment - ? !!(moduleSymbol.flags & SymbolFlags.Value) - : forEachEntry(getExportsOfModule(moduleSymbol), isValue); + ? !!(moduleSymbol.flags & ts.SymbolFlags.Value) + : ts.forEachEntry(getExportsOfModule(moduleSymbol), isValue); } return symbolLinks.exportsSomeValue!; - function isValue(s: Symbol): boolean { + function isValue(s: ts.Symbol): boolean { s = resolveSymbol(s); - return s && !!(s.flags & SymbolFlags.Value); + return s && !!(s.flags & ts.SymbolFlags.Value); } } - function isNameOfModuleOrEnumDeclaration(node: Identifier) { - return isModuleOrEnumDeclaration(node.parent) && node === node.parent.name; + function isNameOfModuleOrEnumDeclaration(node: ts.Identifier) { + return ts.isModuleOrEnumDeclaration(node.parent) && node === node.parent.name; } // When resolved as an expression identifier, if the given node references an exported entity, return the declaration // node of the exported entity's container. Otherwise, return undefined. - function getReferencedExportContainer(nodeIn: Identifier, prefixLocals?: boolean): SourceFile | ModuleDeclaration | EnumDeclaration | undefined { - const node = getParseTreeNode(nodeIn, isIdentifier); + function getReferencedExportContainer(nodeIn: ts.Identifier, prefixLocals?: boolean): ts.SourceFile | ts.ModuleDeclaration | ts.EnumDeclaration | undefined { + const node = ts.getParseTreeNode(nodeIn, ts.isIdentifier); if (node) { // When resolving the export container for the name of a module or enum // declaration, we need to start resolution at the declaration's container. @@ -42496,26 +41575,26 @@ namespace ts { // declaration if it contains an exported member with the same name. let symbol = getReferencedValueSymbol(node, /*startInDeclarationContainer*/ isNameOfModuleOrEnumDeclaration(node)); if (symbol) { - if (symbol.flags & SymbolFlags.ExportValue) { + if (symbol.flags & ts.SymbolFlags.ExportValue) { // If we reference an exported entity within the same module declaration, then whether // we prefix depends on the kind of entity. SymbolFlags.ExportHasLocal encompasses all the // kinds that we do NOT prefix. const exportSymbol = getMergedSymbol(symbol.exportSymbol!); - if (!prefixLocals && exportSymbol.flags & SymbolFlags.ExportHasLocal && !(exportSymbol.flags & SymbolFlags.Variable)) { + if (!prefixLocals && exportSymbol.flags & ts.SymbolFlags.ExportHasLocal && !(exportSymbol.flags & ts.SymbolFlags.Variable)) { return undefined; } symbol = exportSymbol; } const parentSymbol = getParentOfSymbol(symbol); if (parentSymbol) { - if (parentSymbol.flags & SymbolFlags.ValueModule && parentSymbol.valueDeclaration?.kind === SyntaxKind.SourceFile) { - const symbolFile = parentSymbol.valueDeclaration as SourceFile; - const referenceFile = getSourceFileOfNode(node); + if (parentSymbol.flags & ts.SymbolFlags.ValueModule && parentSymbol.valueDeclaration?.kind === ts.SyntaxKind.SourceFile) { + const symbolFile = parentSymbol.valueDeclaration as ts.SourceFile; + const referenceFile = ts.getSourceFileOfNode(node); // If `node` accesses an export and that export isn't in the same file, then symbol is a namespace export, so return undefined. const symbolIsUmdExport = symbolFile !== referenceFile; return symbolIsUmdExport ? undefined : symbolFile; } - return findAncestor(node.parent, (n): n is ModuleDeclaration | EnumDeclaration => isModuleOrEnumDeclaration(n) && getSymbolOfNode(n) === parentSymbol); + return ts.findAncestor(node.parent, (n): n is ts.ModuleDeclaration | ts.EnumDeclaration => ts.isModuleOrEnumDeclaration(n) && getSymbolOfNode(n) === parentSymbol); } } } @@ -42523,16 +41602,16 @@ namespace ts { // When resolved as an expression identifier, if the given node references an import, return the declaration of // that import. Otherwise, return undefined. - function getReferencedImportDeclaration(nodeIn: Identifier): Declaration | undefined { + function getReferencedImportDeclaration(nodeIn: ts.Identifier): ts.Declaration | undefined { if (nodeIn.generatedImportReference) { return nodeIn.generatedImportReference; } - const node = getParseTreeNode(nodeIn, isIdentifier); + const node = ts.getParseTreeNode(nodeIn, ts.isIdentifier); if (node) { const symbol = getReferencedValueSymbol(node); // We should only get the declaration of an alias if there isn't a local value // declaration for the symbol - if (isNonLocalAlias(symbol, /*excludes*/ SymbolFlags.Value) && !getTypeOnlyAliasDeclaration(symbol)) { + if (isNonLocalAlias(symbol, /*excludes*/ ts.SymbolFlags.Value) && !getTypeOnlyAliasDeclaration(symbol)) { return getDeclarationOfAliasSymbol(symbol); } } @@ -42540,24 +41619,24 @@ namespace ts { return undefined; } - function isSymbolOfDestructuredElementOfCatchBinding(symbol: Symbol) { + function isSymbolOfDestructuredElementOfCatchBinding(symbol: ts.Symbol) { return symbol.valueDeclaration - && isBindingElement(symbol.valueDeclaration) - && walkUpBindingElementsAndPatterns(symbol.valueDeclaration).parent.kind === SyntaxKind.CatchClause; + && ts.isBindingElement(symbol.valueDeclaration) + && ts.walkUpBindingElementsAndPatterns(symbol.valueDeclaration).parent.kind === ts.SyntaxKind.CatchClause; } - function isSymbolOfDeclarationWithCollidingName(symbol: Symbol): boolean { - if (symbol.flags & SymbolFlags.BlockScoped && symbol.valueDeclaration && !isSourceFile(symbol.valueDeclaration)) { + function isSymbolOfDeclarationWithCollidingName(symbol: ts.Symbol): boolean { + if (symbol.flags & ts.SymbolFlags.BlockScoped && symbol.valueDeclaration && !ts.isSourceFile(symbol.valueDeclaration)) { const links = getSymbolLinks(symbol); if (links.isDeclarationWithCollidingName === undefined) { - const container = getEnclosingBlockScopeContainer(symbol.valueDeclaration); - if (isStatementWithLocals(container) || isSymbolOfDestructuredElementOfCatchBinding(symbol)) { + const container = ts.getEnclosingBlockScopeContainer(symbol.valueDeclaration); + if (ts.isStatementWithLocals(container) || isSymbolOfDestructuredElementOfCatchBinding(symbol)) { const nodeLinks = getNodeLinks(symbol.valueDeclaration); - if (resolveName(container.parent, symbol.escapedName, SymbolFlags.Value, /*nameNotFoundMessage*/ undefined, /*nameArg*/ undefined, /*isUse*/ false)) { + if (resolveName(container.parent, symbol.escapedName, ts.SymbolFlags.Value, /*nameNotFoundMessage*/ undefined, /*nameArg*/ undefined, /*isUse*/ false)) { // redeclaration - always should be renamed links.isDeclarationWithCollidingName = true; } - else if (nodeLinks.flags & NodeCheckFlags.CapturedBlockScopedBinding) { + else if (nodeLinks.flags & ts.NodeCheckFlags.CapturedBlockScopedBinding) { // binding is captured in the function // should be renamed if: // - binding is not top level - top level bindings never collide with anything @@ -42573,11 +41652,10 @@ namespace ts { // * variables from initializer are passed to rewritten loop body as parameters so they are not captured directly // * variables that are declared immediately in loop body will become top level variable after loop is rewritten and thus // they will not collide with anything - const isDeclaredInLoop = nodeLinks.flags & NodeCheckFlags.BlockScopedBindingInLoop; - const inLoopInitializer = isIterationStatement(container, /*lookInLabeledStatements*/ false); - const inLoopBodyBlock = container.kind === SyntaxKind.Block && isIterationStatement(container.parent, /*lookInLabeledStatements*/ false); - - links.isDeclarationWithCollidingName = !isBlockScopedContainerTopLevel(container) && (!isDeclaredInLoop || (!inLoopInitializer && !inLoopBodyBlock)); + const isDeclaredInLoop = nodeLinks.flags & ts.NodeCheckFlags.BlockScopedBindingInLoop; + const inLoopInitializer = ts.isIterationStatement(container, /*lookInLabeledStatements*/ false); + const inLoopBodyBlock = container.kind === ts.SyntaxKind.Block && ts.isIterationStatement(container.parent, /*lookInLabeledStatements*/ false); + links.isDeclarationWithCollidingName = !ts.isBlockScopedContainerTopLevel(container) && (!isDeclaredInLoop || (!inLoopInitializer && !inLoopBodyBlock)); } else { links.isDeclarationWithCollidingName = false; @@ -42592,9 +41670,9 @@ namespace ts { // When resolved as an expression identifier, if the given node references a nested block scoped entity with // a name that either hides an existing name or might hide it when compiled downlevel, // return the declaration of that entity. Otherwise, return undefined. - function getReferencedDeclarationWithCollidingName(nodeIn: Identifier): Declaration | undefined { - if (!isGeneratedIdentifier(nodeIn)) { - const node = getParseTreeNode(nodeIn, isIdentifier); + function getReferencedDeclarationWithCollidingName(nodeIn: ts.Identifier): ts.Declaration | undefined { + if (!ts.isGeneratedIdentifier(nodeIn)) { + const node = ts.getParseTreeNode(nodeIn, ts.isIdentifier); if (node) { const symbol = getReferencedValueSymbol(node); if (symbol && isSymbolOfDeclarationWithCollidingName(symbol)) { @@ -42608,8 +41686,8 @@ namespace ts { // Return true if the given node is a declaration of a nested block scoped entity with a name that either hides an // existing name or might hide a name when compiled downlevel - function isDeclarationWithCollidingName(nodeIn: Declaration): boolean { - const node = getParseTreeNode(nodeIn, isDeclaration); + function isDeclarationWithCollidingName(nodeIn: ts.Declaration): boolean { + const node = ts.getParseTreeNode(nodeIn, ts.isDeclaration); if (node) { const symbol = getSymbolOfNode(node); if (symbol) { @@ -42620,42 +41698,40 @@ namespace ts { return false; } - function isValueAliasDeclaration(node: Node): boolean { + function isValueAliasDeclaration(node: ts.Node): boolean { switch (node.kind) { - case SyntaxKind.ImportEqualsDeclaration: + case ts.SyntaxKind.ImportEqualsDeclaration: return isAliasResolvedToValue(getSymbolOfNode(node)); - case SyntaxKind.ImportClause: - case SyntaxKind.NamespaceImport: - case SyntaxKind.ImportSpecifier: - case SyntaxKind.ExportSpecifier: + case ts.SyntaxKind.ImportClause: + case ts.SyntaxKind.NamespaceImport: + case ts.SyntaxKind.ImportSpecifier: + case ts.SyntaxKind.ExportSpecifier: const symbol = getSymbolOfNode(node); return !!symbol && isAliasResolvedToValue(symbol) && !getTypeOnlyAliasDeclaration(symbol); - case SyntaxKind.ExportDeclaration: - const exportClause = (node as ExportDeclaration).exportClause; - return !!exportClause && ( - isNamespaceExport(exportClause) || - some(exportClause.elements, isValueAliasDeclaration) - ); - case SyntaxKind.ExportAssignment: - return (node as ExportAssignment).expression && (node as ExportAssignment).expression.kind === SyntaxKind.Identifier ? + case ts.SyntaxKind.ExportDeclaration: + const exportClause = (node as ts.ExportDeclaration).exportClause; + return !!exportClause && (ts.isNamespaceExport(exportClause) || + ts.some(exportClause.elements, isValueAliasDeclaration)); + case ts.SyntaxKind.ExportAssignment: + return (node as ts.ExportAssignment).expression && (node as ts.ExportAssignment).expression.kind === ts.SyntaxKind.Identifier ? isAliasResolvedToValue(getSymbolOfNode(node)) : true; } return false; } - function isTopLevelValueImportEqualsWithEntityName(nodeIn: ImportEqualsDeclaration): boolean { - const node = getParseTreeNode(nodeIn, isImportEqualsDeclaration); - if (node === undefined || node.parent.kind !== SyntaxKind.SourceFile || !isInternalModuleImportEqualsDeclaration(node)) { + function isTopLevelValueImportEqualsWithEntityName(nodeIn: ts.ImportEqualsDeclaration): boolean { + const node = ts.getParseTreeNode(nodeIn, ts.isImportEqualsDeclaration); + if (node === undefined || node.parent.kind !== ts.SyntaxKind.SourceFile || !ts.isInternalModuleImportEqualsDeclaration(node)) { // parent is not source file or it is not reference to internal module return false; } const isValue = isAliasResolvedToValue(getSymbolOfNode(node)); - return isValue && node.moduleReference && !nodeIsMissing(node.moduleReference); + return isValue && node.moduleReference && !ts.nodeIsMissing(node.moduleReference); } - function isAliasResolvedToValue(symbol: Symbol | undefined): boolean { + function isAliasResolvedToValue(symbol: ts.Symbol | undefined): boolean { if (!symbol) { return false; } @@ -42665,15 +41741,15 @@ namespace ts { } // const enums and modules that contain only const enums are not considered values from the emit perspective // unless 'preserveConstEnums' option is set to true - return !!(target.flags & SymbolFlags.Value) && - (shouldPreserveConstEnums(compilerOptions) || !isConstEnumOrConstEnumOnlyModule(target)); + return !!(target.flags & ts.SymbolFlags.Value) && + (ts.shouldPreserveConstEnums(compilerOptions) || !isConstEnumOrConstEnumOnlyModule(target)); } - function isConstEnumOrConstEnumOnlyModule(s: Symbol): boolean { + function isConstEnumOrConstEnumOnlyModule(s: ts.Symbol): boolean { return isConstEnumSymbol(s) || !!s.constEnumOnlyModule; } - function isReferencedAliasDeclaration(node: Node, checkChildren?: boolean): boolean { + function isReferencedAliasDeclaration(node: ts.Node, checkChildren?: boolean): boolean { if (isAliasSymbolDeclaration(node)) { const symbol = getSymbolOfNode(node); const links = symbol && getSymbolLinks(symbol); @@ -42681,23 +41757,24 @@ namespace ts { return true; } const target = getSymbolLinks(symbol!).aliasTarget; // TODO: GH#18217 - if (target && getEffectiveModifierFlags(node) & ModifierFlags.Export && - target.flags & SymbolFlags.Value && - (shouldPreserveConstEnums(compilerOptions) || !isConstEnumOrConstEnumOnlyModule(target))) { + if (target && ts.getEffectiveModifierFlags(node) & ts.ModifierFlags.Export && + target.flags & ts.SymbolFlags.Value && + (ts.shouldPreserveConstEnums(compilerOptions) || !isConstEnumOrConstEnumOnlyModule(target))) { // An `export import ... =` of a value symbol is always considered referenced return true; } } if (checkChildren) { - return !!forEachChild(node, node => isReferencedAliasDeclaration(node, checkChildren)); + return !!ts.forEachChild(node, node => isReferencedAliasDeclaration(node, checkChildren)); } return false; } - function isImplementationOfOverload(node: SignatureDeclaration) { - if (nodeIsPresent((node as FunctionLikeDeclaration).body)) { - if (isGetAccessor(node) || isSetAccessor(node)) return false; // Get or set accessors can never be overload implementations, but can have up to 2 signatures + function isImplementationOfOverload(node: ts.SignatureDeclaration) { + if (ts.nodeIsPresent((node as ts.FunctionLikeDeclaration).body)) { + if (ts.isGetAccessor(node) || ts.isSetAccessor(node)) + return false; // Get or set accessors can never be overload implementations, but can have up to 2 signatures const symbol = getSymbolOfNode(node); const signaturesOfSymbol = getSignaturesOfSymbol(symbol); // If this function body corresponds to function with multiple signature, it is implementation of overload @@ -42717,73 +41794,74 @@ namespace ts { return false; } - function isRequiredInitializedParameter(parameter: ParameterDeclaration | JSDocParameterTag): boolean { + function isRequiredInitializedParameter(parameter: ts.ParameterDeclaration | ts.JSDocParameterTag): boolean { return !!strictNullChecks && !isOptionalParameter(parameter) && - !isJSDocParameterTag(parameter) && + !ts.isJSDocParameterTag(parameter) && !!parameter.initializer && - !hasSyntacticModifier(parameter, ModifierFlags.ParameterPropertyModifier); + !ts.hasSyntacticModifier(parameter, ts.ModifierFlags.ParameterPropertyModifier); } - function isOptionalUninitializedParameterProperty(parameter: ParameterDeclaration) { + function isOptionalUninitializedParameterProperty(parameter: ts.ParameterDeclaration) { return strictNullChecks && isOptionalParameter(parameter) && !parameter.initializer && - hasSyntacticModifier(parameter, ModifierFlags.ParameterPropertyModifier); + ts.hasSyntacticModifier(parameter, ts.ModifierFlags.ParameterPropertyModifier); } - function isExpandoFunctionDeclaration(node: Declaration): boolean { - const declaration = getParseTreeNode(node, isFunctionDeclaration); + function isExpandoFunctionDeclaration(node: ts.Declaration): boolean { + const declaration = ts.getParseTreeNode(node, ts.isFunctionDeclaration); if (!declaration) { return false; } const symbol = getSymbolOfNode(declaration); - if (!symbol || !(symbol.flags & SymbolFlags.Function)) { + if (!symbol || !(symbol.flags & ts.SymbolFlags.Function)) { return false; } - return !!forEachEntry(getExportsOfSymbol(symbol), p => p.flags & SymbolFlags.Value && p.valueDeclaration && isPropertyAccessExpression(p.valueDeclaration)); + return !!ts.forEachEntry(getExportsOfSymbol(symbol), p => p.flags & ts.SymbolFlags.Value && p.valueDeclaration && ts.isPropertyAccessExpression(p.valueDeclaration)); } - function getPropertiesOfContainerFunction(node: Declaration): Symbol[] { - const declaration = getParseTreeNode(node, isFunctionDeclaration); + function getPropertiesOfContainerFunction(node: ts.Declaration): ts.Symbol[] { + const declaration = ts.getParseTreeNode(node, ts.isFunctionDeclaration); if (!declaration) { - return emptyArray; + return ts.emptyArray; } const symbol = getSymbolOfNode(declaration); - return symbol && getPropertiesOfType(getTypeOfSymbol(symbol)) || emptyArray; + return symbol && getPropertiesOfType(getTypeOfSymbol(symbol)) || ts.emptyArray; } - function getNodeCheckFlags(node: Node): NodeCheckFlags { + function getNodeCheckFlags(node: ts.Node): ts.NodeCheckFlags { const nodeId = node.id || 0; - if (nodeId < 0 || nodeId >= nodeLinks.length) return 0; + if (nodeId < 0 || nodeId >= nodeLinks.length) + return 0; return nodeLinks[nodeId]?.flags || 0; } - function getEnumMemberValue(node: EnumMember): string | number | undefined { + function getEnumMemberValue(node: ts.EnumMember): string | number | undefined { computeEnumMemberValues(node.parent); return getNodeLinks(node).enumMemberValue; } - function canHaveConstantValue(node: Node): node is EnumMember | AccessExpression { + function canHaveConstantValue(node: ts.Node): node is ts.EnumMember | ts.AccessExpression { switch (node.kind) { - case SyntaxKind.EnumMember: - case SyntaxKind.PropertyAccessExpression: - case SyntaxKind.ElementAccessExpression: + case ts.SyntaxKind.EnumMember: + case ts.SyntaxKind.PropertyAccessExpression: + case ts.SyntaxKind.ElementAccessExpression: return true; } return false; } - function getConstantValue(node: EnumMember | AccessExpression): string | number | undefined { - if (node.kind === SyntaxKind.EnumMember) { + function getConstantValue(node: ts.EnumMember | ts.AccessExpression): string | number | undefined { + if (node.kind === ts.SyntaxKind.EnumMember) { return getEnumMemberValue(node); } const symbol = getNodeLinks(node).resolvedSymbol; - if (symbol && (symbol.flags & SymbolFlags.EnumMember)) { + if (symbol && (symbol.flags & ts.SymbolFlags.EnumMember)) { // inline property\index accesses only for const enums - const member = symbol.valueDeclaration as EnumMember; - if (isEnumConst(member.parent)) { + const member = symbol.valueDeclaration as ts.EnumMember; + if (ts.isEnumConst(member.parent)) { return getEnumMemberValue(member); } } @@ -42791,151 +41869,153 @@ namespace ts { return undefined; } - function isFunctionType(type: Type): boolean { - return !!(type.flags & TypeFlags.Object) && getSignaturesOfType(type, SignatureKind.Call).length > 0; + function isFunctionType(type: ts.Type): boolean { + return !!(type.flags & ts.TypeFlags.Object) && getSignaturesOfType(type, ts.SignatureKind.Call).length > 0; } - function getTypeReferenceSerializationKind(typeNameIn: EntityName, location?: Node): TypeReferenceSerializationKind { + function getTypeReferenceSerializationKind(typeNameIn: ts.EntityName, location?: ts.Node): ts.TypeReferenceSerializationKind { // ensure both `typeName` and `location` are parse tree nodes. - const typeName = getParseTreeNode(typeNameIn, isEntityName); - if (!typeName) return TypeReferenceSerializationKind.Unknown; + const typeName = ts.getParseTreeNode(typeNameIn, ts.isEntityName); + if (!typeName) + return ts.TypeReferenceSerializationKind.Unknown; if (location) { - location = getParseTreeNode(location); - if (!location) return TypeReferenceSerializationKind.Unknown; + location = ts.getParseTreeNode(location); + if (!location) + return ts.TypeReferenceSerializationKind.Unknown; } // Resolve the symbol as a value to ensure the type can be reached at runtime during emit. let isTypeOnly = false; - if (isQualifiedName(typeName)) { - const rootValueSymbol = resolveEntityName(getFirstIdentifier(typeName), SymbolFlags.Value, /*ignoreErrors*/ true, /*dontResolveAlias*/ true, location); - isTypeOnly = !!rootValueSymbol?.declarations?.every(isTypeOnlyImportOrExportDeclaration); + if (ts.isQualifiedName(typeName)) { + const rootValueSymbol = resolveEntityName(ts.getFirstIdentifier(typeName), ts.SymbolFlags.Value, /*ignoreErrors*/ true, /*dontResolveAlias*/ true, location); + isTypeOnly = !!rootValueSymbol?.declarations?.every(ts.isTypeOnlyImportOrExportDeclaration); } - const valueSymbol = resolveEntityName(typeName, SymbolFlags.Value, /*ignoreErrors*/ true, /*dontResolveAlias*/ true, location); - const resolvedSymbol = valueSymbol && valueSymbol.flags & SymbolFlags.Alias ? resolveAlias(valueSymbol) : valueSymbol; - isTypeOnly ||= !!valueSymbol?.declarations?.every(isTypeOnlyImportOrExportDeclaration); + const valueSymbol = resolveEntityName(typeName, ts.SymbolFlags.Value, /*ignoreErrors*/ true, /*dontResolveAlias*/ true, location); + const resolvedSymbol = valueSymbol && valueSymbol.flags & ts.SymbolFlags.Alias ? resolveAlias(valueSymbol) : valueSymbol; + isTypeOnly ||= !!valueSymbol?.declarations?.every(ts.isTypeOnlyImportOrExportDeclaration); // Resolve the symbol as a type so that we can provide a more useful hint for the type serializer. - const typeSymbol = resolveEntityName(typeName, SymbolFlags.Type, /*ignoreErrors*/ true, /*dontResolveAlias*/ false, location); + const typeSymbol = resolveEntityName(typeName, ts.SymbolFlags.Type, /*ignoreErrors*/ true, /*dontResolveAlias*/ false, location); if (resolvedSymbol && resolvedSymbol === typeSymbol) { const globalPromiseSymbol = getGlobalPromiseConstructorSymbol(/*reportErrors*/ false); if (globalPromiseSymbol && resolvedSymbol === globalPromiseSymbol) { - return TypeReferenceSerializationKind.Promise; + return ts.TypeReferenceSerializationKind.Promise; } const constructorType = getTypeOfSymbol(resolvedSymbol); if (constructorType && isConstructorType(constructorType)) { - return isTypeOnly ? TypeReferenceSerializationKind.TypeWithCallSignature : TypeReferenceSerializationKind.TypeWithConstructSignatureAndValue; + return isTypeOnly ? ts.TypeReferenceSerializationKind.TypeWithCallSignature : ts.TypeReferenceSerializationKind.TypeWithConstructSignatureAndValue; } } // We might not be able to resolve type symbol so use unknown type in that case (eg error case) if (!typeSymbol) { - return isTypeOnly ? TypeReferenceSerializationKind.ObjectType : TypeReferenceSerializationKind.Unknown; + return isTypeOnly ? ts.TypeReferenceSerializationKind.ObjectType : ts.TypeReferenceSerializationKind.Unknown; } const type = getDeclaredTypeOfSymbol(typeSymbol); if (isErrorType(type)) { - return isTypeOnly ? TypeReferenceSerializationKind.ObjectType : TypeReferenceSerializationKind.Unknown; + return isTypeOnly ? ts.TypeReferenceSerializationKind.ObjectType : ts.TypeReferenceSerializationKind.Unknown; } - else if (type.flags & TypeFlags.AnyOrUnknown) { - return TypeReferenceSerializationKind.ObjectType; + else if (type.flags & ts.TypeFlags.AnyOrUnknown) { + return ts.TypeReferenceSerializationKind.ObjectType; } - else if (isTypeAssignableToKind(type, TypeFlags.Void | TypeFlags.Nullable | TypeFlags.Never)) { - return TypeReferenceSerializationKind.VoidNullableOrNeverType; + else if (isTypeAssignableToKind(type, ts.TypeFlags.Void | ts.TypeFlags.Nullable | ts.TypeFlags.Never)) { + return ts.TypeReferenceSerializationKind.VoidNullableOrNeverType; } - else if (isTypeAssignableToKind(type, TypeFlags.BooleanLike)) { - return TypeReferenceSerializationKind.BooleanType; + else if (isTypeAssignableToKind(type, ts.TypeFlags.BooleanLike)) { + return ts.TypeReferenceSerializationKind.BooleanType; } - else if (isTypeAssignableToKind(type, TypeFlags.NumberLike)) { - return TypeReferenceSerializationKind.NumberLikeType; + else if (isTypeAssignableToKind(type, ts.TypeFlags.NumberLike)) { + return ts.TypeReferenceSerializationKind.NumberLikeType; } - else if (isTypeAssignableToKind(type, TypeFlags.BigIntLike)) { - return TypeReferenceSerializationKind.BigIntLikeType; + else if (isTypeAssignableToKind(type, ts.TypeFlags.BigIntLike)) { + return ts.TypeReferenceSerializationKind.BigIntLikeType; } - else if (isTypeAssignableToKind(type, TypeFlags.StringLike)) { - return TypeReferenceSerializationKind.StringLikeType; + else if (isTypeAssignableToKind(type, ts.TypeFlags.StringLike)) { + return ts.TypeReferenceSerializationKind.StringLikeType; } else if (isTupleType(type)) { - return TypeReferenceSerializationKind.ArrayLikeType; + return ts.TypeReferenceSerializationKind.ArrayLikeType; } - else if (isTypeAssignableToKind(type, TypeFlags.ESSymbolLike)) { - return TypeReferenceSerializationKind.ESSymbolType; + else if (isTypeAssignableToKind(type, ts.TypeFlags.ESSymbolLike)) { + return ts.TypeReferenceSerializationKind.ESSymbolType; } else if (isFunctionType(type)) { - return TypeReferenceSerializationKind.TypeWithCallSignature; + return ts.TypeReferenceSerializationKind.TypeWithCallSignature; } else if (isArrayType(type)) { - return TypeReferenceSerializationKind.ArrayLikeType; + return ts.TypeReferenceSerializationKind.ArrayLikeType; } else { - return TypeReferenceSerializationKind.ObjectType; + return ts.TypeReferenceSerializationKind.ObjectType; } } - function createTypeOfDeclaration(declarationIn: AccessorDeclaration | VariableLikeDeclaration | PropertyAccessExpression, enclosingDeclaration: Node, flags: NodeBuilderFlags, tracker: SymbolTracker, addUndefined?: boolean) { - const declaration = getParseTreeNode(declarationIn, isVariableLikeOrAccessor); + function createTypeOfDeclaration(declarationIn: ts.AccessorDeclaration | ts.VariableLikeDeclaration | ts.PropertyAccessExpression, enclosingDeclaration: ts.Node, flags: ts.NodeBuilderFlags, tracker: ts.SymbolTracker, addUndefined?: boolean) { + const declaration = ts.getParseTreeNode(declarationIn, ts.isVariableLikeOrAccessor); if (!declaration) { - return factory.createToken(SyntaxKind.AnyKeyword) as KeywordTypeNode; + return ts.factory.createToken(ts.SyntaxKind.AnyKeyword) as ts.KeywordTypeNode; } // Get type of the symbol if this is the valid symbol otherwise get type at location const symbol = getSymbolOfNode(declaration); - let type = symbol && !(symbol.flags & (SymbolFlags.TypeLiteral | SymbolFlags.Signature)) + let type = symbol && !(symbol.flags & (ts.SymbolFlags.TypeLiteral | ts.SymbolFlags.Signature)) ? getWidenedLiteralType(getTypeOfSymbol(symbol)) : errorType; - if (type.flags & TypeFlags.UniqueESSymbol && + if (type.flags & ts.TypeFlags.UniqueESSymbol && type.symbol === symbol) { - flags |= NodeBuilderFlags.AllowUniqueESSymbolType; + flags |= ts.NodeBuilderFlags.AllowUniqueESSymbolType; } if (addUndefined) { type = getOptionalType(type); } - return nodeBuilder.typeToTypeNode(type, enclosingDeclaration, flags | NodeBuilderFlags.MultilineObjectLiterals, tracker); + return nodeBuilder.typeToTypeNode(type, enclosingDeclaration, flags | ts.NodeBuilderFlags.MultilineObjectLiterals, tracker); } - function createReturnTypeOfSignatureDeclaration(signatureDeclarationIn: SignatureDeclaration, enclosingDeclaration: Node, flags: NodeBuilderFlags, tracker: SymbolTracker) { - const signatureDeclaration = getParseTreeNode(signatureDeclarationIn, isFunctionLike); + function createReturnTypeOfSignatureDeclaration(signatureDeclarationIn: ts.SignatureDeclaration, enclosingDeclaration: ts.Node, flags: ts.NodeBuilderFlags, tracker: ts.SymbolTracker) { + const signatureDeclaration = ts.getParseTreeNode(signatureDeclarationIn, ts.isFunctionLike); if (!signatureDeclaration) { - return factory.createToken(SyntaxKind.AnyKeyword) as KeywordTypeNode; + return ts.factory.createToken(ts.SyntaxKind.AnyKeyword) as ts.KeywordTypeNode; } const signature = getSignatureFromDeclaration(signatureDeclaration); - return nodeBuilder.typeToTypeNode(getReturnTypeOfSignature(signature), enclosingDeclaration, flags | NodeBuilderFlags.MultilineObjectLiterals, tracker); + return nodeBuilder.typeToTypeNode(getReturnTypeOfSignature(signature), enclosingDeclaration, flags | ts.NodeBuilderFlags.MultilineObjectLiterals, tracker); } - function createTypeOfExpression(exprIn: Expression, enclosingDeclaration: Node, flags: NodeBuilderFlags, tracker: SymbolTracker) { - const expr = getParseTreeNode(exprIn, isExpression); + function createTypeOfExpression(exprIn: ts.Expression, enclosingDeclaration: ts.Node, flags: ts.NodeBuilderFlags, tracker: ts.SymbolTracker) { + const expr = ts.getParseTreeNode(exprIn, ts.isExpression); if (!expr) { - return factory.createToken(SyntaxKind.AnyKeyword) as KeywordTypeNode; + return ts.factory.createToken(ts.SyntaxKind.AnyKeyword) as ts.KeywordTypeNode; } const type = getWidenedType(getRegularTypeOfExpression(expr)); - return nodeBuilder.typeToTypeNode(type, enclosingDeclaration, flags | NodeBuilderFlags.MultilineObjectLiterals, tracker); + return nodeBuilder.typeToTypeNode(type, enclosingDeclaration, flags | ts.NodeBuilderFlags.MultilineObjectLiterals, tracker); } function hasGlobalName(name: string): boolean { - return globals.has(escapeLeadingUnderscores(name)); + return globals.has(ts.escapeLeadingUnderscores(name)); } - function getReferencedValueSymbol(reference: Identifier, startInDeclarationContainer?: boolean): Symbol | undefined { + function getReferencedValueSymbol(reference: ts.Identifier, startInDeclarationContainer?: boolean): ts.Symbol | undefined { const resolvedSymbol = getNodeLinks(reference).resolvedSymbol; if (resolvedSymbol) { return resolvedSymbol; } - let location: Node = reference; + let location: ts.Node = reference; if (startInDeclarationContainer) { // When resolving the name of a declaration as a value, we need to start resolution // at a point outside of the declaration. const parent = reference.parent; - if (isDeclaration(parent) && reference === parent.name) { + if (ts.isDeclaration(parent) && reference === parent.name) { location = getDeclarationContainer(parent); } } - return resolveName(location, reference.escapedText, SymbolFlags.Value | SymbolFlags.ExportValue | SymbolFlags.Alias, /*nodeNotFoundMessage*/ undefined, /*nameArg*/ undefined, /*isUse*/ true); + return resolveName(location, reference.escapedText, ts.SymbolFlags.Value | ts.SymbolFlags.ExportValue | ts.SymbolFlags.Alias, /*nodeNotFoundMessage*/ undefined, /*nameArg*/ undefined, /*isUse*/ true); } - function getReferencedValueDeclaration(referenceIn: Identifier): Declaration | undefined { - if (!isGeneratedIdentifier(referenceIn)) { - const reference = getParseTreeNode(referenceIn, isIdentifier); + function getReferencedValueDeclaration(referenceIn: ts.Identifier): ts.Declaration | undefined { + if (!ts.isGeneratedIdentifier(referenceIn)) { + const reference = ts.getParseTreeNode(referenceIn, ts.isIdentifier); if (reference) { const symbol = getReferencedValueSymbol(reference); if (symbol) { @@ -42947,61 +42027,68 @@ namespace ts { return undefined; } - function isLiteralConstDeclaration(node: VariableDeclaration | PropertyDeclaration | PropertySignature | ParameterDeclaration): boolean { - if (isDeclarationReadonly(node) || isVariableDeclaration(node) && isVarConst(node)) { + function isLiteralConstDeclaration(node: ts.VariableDeclaration | ts.PropertyDeclaration | ts.PropertySignature | ts.ParameterDeclaration): boolean { + if (ts.isDeclarationReadonly(node) || ts.isVariableDeclaration(node) && ts.isVarConst(node)) { return isFreshLiteralType(getTypeOfSymbol(getSymbolOfNode(node))); } return false; } - function literalTypeToNode(type: FreshableType, enclosing: Node, tracker: SymbolTracker): Expression { - const enumResult = type.flags & TypeFlags.EnumLiteral ? nodeBuilder.symbolToExpression(type.symbol, SymbolFlags.Value, enclosing, /*flags*/ undefined, tracker) - : type === trueType ? factory.createTrue() : type === falseType && factory.createFalse(); - if (enumResult) return enumResult; - const literalValue = (type as LiteralType).value; - return typeof literalValue === "object" ? factory.createBigIntLiteral(literalValue) : - typeof literalValue === "number" ? factory.createNumericLiteral(literalValue) : - factory.createStringLiteral(literalValue); + function literalTypeToNode(type: ts.FreshableType, enclosing: ts.Node, tracker: ts.SymbolTracker): ts.Expression { + const enumResult = type.flags & ts.TypeFlags.EnumLiteral ? nodeBuilder.symbolToExpression(type.symbol, ts.SymbolFlags.Value, enclosing, /*flags*/ undefined, tracker) + : type === trueType ? ts.factory.createTrue() : type === falseType && ts.factory.createFalse(); + if (enumResult) + return enumResult; + const literalValue = (type as ts.LiteralType).value; + return typeof literalValue === "object" ? ts.factory.createBigIntLiteral(literalValue) : + typeof literalValue === "number" ? ts.factory.createNumericLiteral(literalValue) : + ts.factory.createStringLiteral(literalValue); } - function createLiteralConstValue(node: VariableDeclaration | PropertyDeclaration | PropertySignature | ParameterDeclaration, tracker: SymbolTracker) { + function createLiteralConstValue(node: ts.VariableDeclaration | ts.PropertyDeclaration | ts.PropertySignature | ts.ParameterDeclaration, tracker: ts.SymbolTracker) { const type = getTypeOfSymbol(getSymbolOfNode(node)); - return literalTypeToNode(type as FreshableType, node, tracker); + return literalTypeToNode(type as ts.FreshableType, node, tracker); } - function getJsxFactoryEntity(location: Node): EntityName | undefined { - return location ? (getJsxNamespace(location), (getSourceFileOfNode(location).localJsxFactory || _jsxFactoryEntity)) : _jsxFactoryEntity; + function getJsxFactoryEntity(location: ts.Node): ts.EntityName | undefined { + return location ? (getJsxNamespace(location), (ts.getSourceFileOfNode(location).localJsxFactory || _jsxFactoryEntity)) : _jsxFactoryEntity; } - function getJsxFragmentFactoryEntity(location: Node): EntityName | undefined { + function getJsxFragmentFactoryEntity(location: ts.Node): ts.EntityName | undefined { if (location) { - const file = getSourceFileOfNode(location); + const file = ts.getSourceFileOfNode(location); if (file) { if (file.localJsxFragmentFactory) { return file.localJsxFragmentFactory; } const jsxFragPragmas = file.pragmas.get("jsxfrag"); - const jsxFragPragma = isArray(jsxFragPragmas) ? jsxFragPragmas[0] : jsxFragPragmas; + const jsxFragPragma = ts.isArray(jsxFragPragmas) ? jsxFragPragmas[0] : jsxFragPragmas; if (jsxFragPragma) { - file.localJsxFragmentFactory = parseIsolatedEntityName(jsxFragPragma.arguments.factory, languageVersion); + file.localJsxFragmentFactory = ts.parseIsolatedEntityName(jsxFragPragma.arguments.factory, languageVersion); return file.localJsxFragmentFactory; } } } if (compilerOptions.jsxFragmentFactory) { - return parseIsolatedEntityName(compilerOptions.jsxFragmentFactory, languageVersion); + return ts.parseIsolatedEntityName(compilerOptions.jsxFragmentFactory, languageVersion); } } - function createResolver(): EmitResolver { + function createResolver(): ts.EmitResolver { // this variable and functions that use it are deliberately moved here from the outer scope // to avoid scope pollution const resolvedTypeReferenceDirectives = host.getResolvedTypeReferenceDirectives(); - let fileToDirective: ESMap; + let fileToDirective: ts.ESMap; if (resolvedTypeReferenceDirectives) { // populate reverse mapping: file path -> type reference directive that was resolved to this file - fileToDirective = new Map(); + fileToDirective = new ts.Map(); resolvedTypeReferenceDirectives.forEach((resolvedDirective, key, mode) => { if (!resolvedDirective || !resolvedDirective.resolvedFileName) { return; @@ -43021,18 +42108,18 @@ namespace ts { getReferencedDeclarationWithCollidingName, isDeclarationWithCollidingName, isValueAliasDeclaration: nodeIn => { - const node = getParseTreeNode(nodeIn); + const node = ts.getParseTreeNode(nodeIn); // Synthesized nodes are always treated like values. return node ? isValueAliasDeclaration(node) : true; }, hasGlobalName, isReferencedAliasDeclaration: (nodeIn, checkChildren?) => { - const node = getParseTreeNode(nodeIn); + const node = ts.getParseTreeNode(nodeIn); // Synthesized nodes are always treated as referenced. return node ? isReferencedAliasDeclaration(node, checkChildren) : true; }, getNodeCheckFlags: nodeIn => { - const node = getParseTreeNode(nodeIn); + const node = ts.getParseTreeNode(nodeIn); return node ? getNodeCheckFlags(node) : 0; }, isTopLevelValueImportEqualsWithEntityName, @@ -43049,7 +42136,7 @@ namespace ts { isSymbolAccessible, isEntityNameVisible, getConstantValue: nodeIn => { - const node = getParseTreeNode(nodeIn, canHaveConstantValue); + const node = ts.getParseTreeNode(nodeIn, canHaveConstantValue); return node ? getConstantValue(node) : undefined; }, collectLinkedAliases, @@ -43059,27 +42146,27 @@ namespace ts { moduleExportsSomeValue, isArgumentsLocalBinding, getExternalModuleFileFromDeclaration: nodeIn => { - const node = getParseTreeNode(nodeIn, hasPossibleExternalModuleReference); + const node = ts.getParseTreeNode(nodeIn, ts.hasPossibleExternalModuleReference); return node && getExternalModuleFileFromDeclaration(node); }, getTypeReferenceDirectivesForEntityName, getTypeReferenceDirectivesForSymbol, isLiteralConstDeclaration, - isLateBound: (nodeIn: Declaration): nodeIn is LateBoundDeclaration => { - const node = getParseTreeNode(nodeIn, isDeclaration); + isLateBound: (nodeIn: ts.Declaration): nodeIn is ts.LateBoundDeclaration => { + const node = ts.getParseTreeNode(nodeIn, ts.isDeclaration); const symbol = node && getSymbolOfNode(node); - return !!(symbol && getCheckFlags(symbol) & CheckFlags.Late); + return !!(symbol && ts.getCheckFlags(symbol) & ts.CheckFlags.Late); }, getJsxFactoryEntity, getJsxFragmentFactoryEntity, - getAllAccessorDeclarations(accessor: AccessorDeclaration): AllAccessorDeclarations { - accessor = getParseTreeNode(accessor, isGetOrSetAccessorDeclaration)!; // TODO: GH#18217 - const otherKind = accessor.kind === SyntaxKind.SetAccessor ? SyntaxKind.GetAccessor : SyntaxKind.SetAccessor; - const otherAccessor = getDeclarationOfKind(getSymbolOfNode(accessor), otherKind); + getAllAccessorDeclarations(accessor: ts.AccessorDeclaration): ts.AllAccessorDeclarations { + accessor = ts.getParseTreeNode(accessor, ts.isGetOrSetAccessorDeclaration)!; // TODO: GH#18217 + const otherKind = accessor.kind === ts.SyntaxKind.SetAccessor ? ts.SyntaxKind.GetAccessor : ts.SyntaxKind.SetAccessor; + const otherAccessor = ts.getDeclarationOfKind(getSymbolOfNode(accessor), otherKind); const firstAccessor = otherAccessor && (otherAccessor.pos < accessor.pos) ? otherAccessor : accessor; const secondAccessor = otherAccessor && (otherAccessor.pos < accessor.pos) ? accessor : otherAccessor; - const setAccessor = accessor.kind === SyntaxKind.SetAccessor ? accessor : otherAccessor as SetAccessorDeclaration; - const getAccessor = accessor.kind === SyntaxKind.GetAccessor ? accessor : otherAccessor as GetAccessorDeclaration; + const setAccessor = accessor.kind === ts.SyntaxKind.SetAccessor ? accessor : otherAccessor as ts.SetAccessorDeclaration; + const getAccessor = accessor.kind === ts.SyntaxKind.GetAccessor ? accessor : otherAccessor as ts.GetAccessorDeclaration; return { firstAccessor, secondAccessor, @@ -43089,13 +42176,13 @@ namespace ts { }, getSymbolOfExternalModuleSpecifier: moduleName => resolveExternalModuleNameWorker(moduleName, moduleName, /*moduleNotFoundError*/ undefined), isBindingCapturedByNode: (node, decl) => { - const parseNode = getParseTreeNode(node); - const parseDecl = getParseTreeNode(decl); - return !!parseNode && !!parseDecl && (isVariableDeclaration(parseDecl) || isBindingElement(parseDecl)) && isBindingCapturedByNode(parseNode, parseDecl); + const parseNode = ts.getParseTreeNode(node); + const parseDecl = ts.getParseTreeNode(decl); + return !!parseNode && !!parseDecl && (ts.isVariableDeclaration(parseDecl) || ts.isBindingElement(parseDecl)) && isBindingCapturedByNode(parseNode, parseDecl); }, getDeclarationStatementsForSourceFile: (node, flags, tracker, bundled) => { - const n = getParseTreeNode(node) as SourceFile; - Debug.assert(n && n.kind === SyntaxKind.SourceFile, "Non-sourcefile node passed into getDeclarationsForSourceFile"); + const n = ts.getParseTreeNode(node) as ts.SourceFile; + ts.Debug.assert(n && n.kind === ts.SyntaxKind.SourceFile, "Non-sourcefile node passed into getDeclarationsForSourceFile"); const sym = getSymbolOfNode(node); if (!sym) { return !node.locals ? [] : nodeBuilder.symbolTableToDeclarationStatements(node.locals, node, flags, tracker, bundled); @@ -43105,19 +42192,22 @@ namespace ts { isImportRequiredByAugmentation, }; - function isImportRequiredByAugmentation(node: ImportDeclaration) { - const file = getSourceFileOfNode(node); - if (!file.symbol) return false; + function isImportRequiredByAugmentation(node: ts.ImportDeclaration) { + const file = ts.getSourceFileOfNode(node); + if (!file.symbol) + return false; const importTarget = getExternalModuleFileFromDeclaration(node); - if (!importTarget) return false; - if (importTarget === file) return false; + if (!importTarget) + return false; + if (importTarget === file) + return false; const exports = getExportsOfModule(file.symbol); - for (const s of arrayFrom(exports.values())) { + for (const s of ts.arrayFrom(exports.values())) { if (s.mergeId) { const merged = getMergedSymbol(s); if (merged.declarations) { for (const d of merged.declarations) { - const declFile = getSourceFileOfNode(d); + const declFile = ts.getSourceFileOfNode(d); if (declFile === importTarget) { return true; } @@ -43128,12 +42218,15 @@ namespace ts { return false; } - function isInHeritageClause(node: PropertyAccessEntityNameExpression) { - return node.parent && node.parent.kind === SyntaxKind.ExpressionWithTypeArguments && node.parent.parent && node.parent.parent.kind === SyntaxKind.HeritageClause; + function isInHeritageClause(node: ts.PropertyAccessEntityNameExpression) { + return node.parent && node.parent.kind === ts.SyntaxKind.ExpressionWithTypeArguments && node.parent.parent && node.parent.parent.kind === ts.SyntaxKind.HeritageClause; } // defined here to avoid outer scope pollution - function getTypeReferenceDirectivesForEntityName(node: EntityNameOrEntityNameExpression): [specifier: string, mode: SourceFile["impliedNodeFormat"] | undefined][] | undefined { + function getTypeReferenceDirectivesForEntityName(node: ts.EntityNameOrEntityNameExpression): [ + specifier: string, + mode: ts.SourceFile["impliedNodeFormat"] | undefined + ][] | undefined { // program does not have any files with type reference directives - bail out if (!fileToDirective) { return undefined; @@ -43141,9 +42234,9 @@ namespace ts { // property access can only be used as values, or types when within an expression with type arguments inside a heritage clause // qualified names can only be used as types\namespaces // identifiers are treated as values only if they appear in type queries - let meaning = SymbolFlags.Type | SymbolFlags.Namespace; - if ((node.kind === SyntaxKind.Identifier && isInTypeQuery(node)) || (node.kind === SyntaxKind.PropertyAccessExpression && !isInHeritageClause(node))) { - meaning = SymbolFlags.Value | SymbolFlags.ExportValue; + let meaning = ts.SymbolFlags.Type | ts.SymbolFlags.Namespace; + if ((node.kind === ts.SyntaxKind.Identifier && isInTypeQuery(node)) || (node.kind === ts.SyntaxKind.PropertyAccessExpression && !isInHeritageClause(node))) { + meaning = ts.SymbolFlags.Value | ts.SymbolFlags.ExportValue; } const symbol = resolveEntityName(node, meaning, /*ignoreErrors*/ true); @@ -43151,17 +42244,23 @@ namespace ts { } // defined here to avoid outer scope pollution - function getTypeReferenceDirectivesForSymbol(symbol: Symbol, meaning?: SymbolFlags): [specifier: string, mode: SourceFile["impliedNodeFormat"] | undefined][] | undefined { + function getTypeReferenceDirectivesForSymbol(symbol: ts.Symbol, meaning?: ts.SymbolFlags): [ + specifier: string, + mode: ts.SourceFile["impliedNodeFormat"] | undefined + ][] | undefined { // program does not have any files with type reference directives - bail out if (!fileToDirective || !isSymbolFromTypeDeclarationFile(symbol)) { return undefined; } // check what declarations in the symbol can contribute to the target meaning - let typeReferenceDirectives: [specifier: string, mode: SourceFile["impliedNodeFormat"] | undefined][] | undefined; + let typeReferenceDirectives: [ + specifier: string, + mode: ts.SourceFile["impliedNodeFormat"] | undefined + ][] | undefined; for (const decl of symbol.declarations!) { // check meaning of the local symbol to see if declaration needs to be analyzed further if (decl.symbol && decl.symbol.flags & meaning!) { - const file = getSourceFileOfNode(decl); + const file = ts.getSourceFileOfNode(decl); const typeReferenceDirective = fileToDirective.get(file.path); if (typeReferenceDirective) { (typeReferenceDirectives || (typeReferenceDirectives = [])).push(typeReferenceDirective); @@ -43175,7 +42274,7 @@ namespace ts { return typeReferenceDirectives; } - function isSymbolFromTypeDeclarationFile(symbol: Symbol): boolean { + function isSymbolFromTypeDeclarationFile(symbol: ts.Symbol): boolean { // bail out if symbol does not have associated declarations (i.e. this is transient symbol created for property in binding pattern) if (!symbol.declarations) { return false; @@ -43194,13 +42293,13 @@ namespace ts { } } - if (current.valueDeclaration && current.valueDeclaration.kind === SyntaxKind.SourceFile && current.flags & SymbolFlags.ValueModule) { + if (current.valueDeclaration && current.valueDeclaration.kind === ts.SyntaxKind.SourceFile && current.flags & ts.SymbolFlags.ValueModule) { return false; } // check that at least one declaration of top level symbol originates from type declaration file for (const decl of symbol.declarations) { - const file = getSourceFileOfNode(decl); + const file = ts.getSourceFileOfNode(decl); if (fileToDirective.has(file.path)) { return true; } @@ -43208,11 +42307,12 @@ namespace ts { return false; } - function addReferencedFilesToTypeDirective(file: SourceFile, key: string, mode: SourceFile["impliedNodeFormat"] | undefined) { - if (fileToDirective.has(file.path)) return; + function addReferencedFilesToTypeDirective(file: ts.SourceFile, key: string, mode: ts.SourceFile["impliedNodeFormat"] | undefined) { + if (fileToDirective.has(file.path)) + return; fileToDirective.set(file.path, [key, mode]); for (const { fileName, resolutionMode } of file.referencedFiles) { - const resolvedFile = resolveTripleslashReference(fileName, file.fileName); + const resolvedFile = ts.resolveTripleslashReference(fileName, file.fileName); const referencedFile = host.getSourceFile(resolvedFile); if (referencedFile) { addReferencedFilesToTypeDirective(referencedFile, key, resolutionMode || file.impliedNodeFormat); @@ -43221,36 +42321,36 @@ namespace ts { } } - function getExternalModuleFileFromDeclaration(declaration: AnyImportOrReExport | ModuleDeclaration | ImportTypeNode | ImportCall): SourceFile | undefined { - const specifier = declaration.kind === SyntaxKind.ModuleDeclaration ? tryCast(declaration.name, isStringLiteral) : getExternalModuleName(declaration); + function getExternalModuleFileFromDeclaration(declaration: ts.AnyImportOrReExport | ts.ModuleDeclaration | ts.ImportTypeNode | ts.ImportCall): ts.SourceFile | undefined { + const specifier = declaration.kind === ts.SyntaxKind.ModuleDeclaration ? ts.tryCast(declaration.name, ts.isStringLiteral) : ts.getExternalModuleName(declaration); const moduleSymbol = resolveExternalModuleNameWorker(specifier!, specifier!, /*moduleNotFoundError*/ undefined); // TODO: GH#18217 if (!moduleSymbol) { return undefined; } - return getDeclarationOfKind(moduleSymbol, SyntaxKind.SourceFile); + return ts.getDeclarationOfKind(moduleSymbol, ts.SyntaxKind.SourceFile); } function initializeTypeChecker() { // Bind all source files and propagate errors for (const file of host.getSourceFiles()) { - bindSourceFile(file, compilerOptions); + ts.bindSourceFile(file, compilerOptions); } - amalgamatedDuplicates = new Map(); + amalgamatedDuplicates = new ts.Map(); // Initialize global symbol table - let augmentations: (readonly (StringLiteral | Identifier)[])[] | undefined; + let augmentations: (readonly (ts.StringLiteral | ts.Identifier)[])[] | undefined; for (const file of host.getSourceFiles()) { if (file.redirectInfo) { continue; } - if (!isExternalOrCommonJsModule(file)) { + if (!ts.isExternalOrCommonJsModule(file)) { // It is an error for a non-external-module (i.e. script) to declare its own `globalThis`. // We can't use `builtinGlobals` for this due to synthetic expando-namespace generation in JS files. - const fileGlobalThisSymbol = file.locals!.get("globalThis" as __String); + const fileGlobalThisSymbol = file.locals!.get("globalThis" as ts.__String); if (fileGlobalThisSymbol?.declarations) { for (const declaration of fileGlobalThisSymbol.declarations) { - diagnostics.add(createDiagnosticForNode(declaration, Diagnostics.Declaration_name_conflicts_with_built_in_global_identifier_0, "globalThis")); + diagnostics.add(ts.createDiagnosticForNode(declaration, ts.Diagnostics.Declaration_name_conflicts_with_built_in_global_identifier_0, "globalThis")); } } mergeSymbolTable(globals, file.locals!); @@ -43259,7 +42359,7 @@ namespace ts { mergeSymbolTable(globals, file.jsGlobalAugmentations); } if (file.patternAmbientModules && file.patternAmbientModules.length) { - patternAmbientModules = concatenate(patternAmbientModules, file.patternAmbientModules); + patternAmbientModules = ts.concatenate(patternAmbientModules, file.patternAmbientModules); } if (file.moduleAugmentations.length) { (augmentations || (augmentations = [])).push(file.moduleAugmentations); @@ -43286,48 +42386,50 @@ namespace ts { // this needs to be done after global symbol table is initialized to make sure that all ambient modules are indexed for (const list of augmentations) { for (const augmentation of list) { - if (!isGlobalScopeAugmentation(augmentation.parent as ModuleDeclaration)) continue; + if (!ts.isGlobalScopeAugmentation(augmentation.parent as ts.ModuleDeclaration)) + continue; mergeModuleAugmentation(augmentation); } } } // Setup global builtins - addToSymbolTable(globals, builtinGlobals, Diagnostics.Declaration_name_conflicts_with_built_in_global_identifier_0); + addToSymbolTable(globals, builtinGlobals, ts.Diagnostics.Declaration_name_conflicts_with_built_in_global_identifier_0); getSymbolLinks(undefinedSymbol).type = undefinedWideningType; - getSymbolLinks(argumentsSymbol).type = getGlobalType("IArguments" as __String, /*arity*/ 0, /*reportErrors*/ true); + getSymbolLinks(argumentsSymbol).type = getGlobalType("IArguments" as ts.__String, /*arity*/ 0, /*reportErrors*/ true); getSymbolLinks(unknownSymbol).type = errorType; - getSymbolLinks(globalThisSymbol).type = createObjectType(ObjectFlags.Anonymous, globalThisSymbol); + getSymbolLinks(globalThisSymbol).type = createObjectType(ts.ObjectFlags.Anonymous, globalThisSymbol); // Initialize special types - globalArrayType = getGlobalType("Array" as __String, /*arity*/ 1, /*reportErrors*/ true); - globalObjectType = getGlobalType("Object" as __String, /*arity*/ 0, /*reportErrors*/ true); - globalFunctionType = getGlobalType("Function" as __String, /*arity*/ 0, /*reportErrors*/ true); - globalCallableFunctionType = strictBindCallApply && getGlobalType("CallableFunction" as __String, /*arity*/ 0, /*reportErrors*/ true) || globalFunctionType; - globalNewableFunctionType = strictBindCallApply && getGlobalType("NewableFunction" as __String, /*arity*/ 0, /*reportErrors*/ true) || globalFunctionType; - globalStringType = getGlobalType("String" as __String, /*arity*/ 0, /*reportErrors*/ true); - globalNumberType = getGlobalType("Number" as __String, /*arity*/ 0, /*reportErrors*/ true); - globalBooleanType = getGlobalType("Boolean" as __String, /*arity*/ 0, /*reportErrors*/ true); - globalRegExpType = getGlobalType("RegExp" as __String, /*arity*/ 0, /*reportErrors*/ true); + globalArrayType = getGlobalType("Array" as ts.__String, /*arity*/ 1, /*reportErrors*/ true); + globalObjectType = getGlobalType("Object" as ts.__String, /*arity*/ 0, /*reportErrors*/ true); + globalFunctionType = getGlobalType("Function" as ts.__String, /*arity*/ 0, /*reportErrors*/ true); + globalCallableFunctionType = strictBindCallApply && getGlobalType("CallableFunction" as ts.__String, /*arity*/ 0, /*reportErrors*/ true) || globalFunctionType; + globalNewableFunctionType = strictBindCallApply && getGlobalType("NewableFunction" as ts.__String, /*arity*/ 0, /*reportErrors*/ true) || globalFunctionType; + globalStringType = getGlobalType("String" as ts.__String, /*arity*/ 0, /*reportErrors*/ true); + globalNumberType = getGlobalType("Number" as ts.__String, /*arity*/ 0, /*reportErrors*/ true); + globalBooleanType = getGlobalType("Boolean" as ts.__String, /*arity*/ 0, /*reportErrors*/ true); + globalRegExpType = getGlobalType("RegExp" as ts.__String, /*arity*/ 0, /*reportErrors*/ true); anyArrayType = createArrayType(anyType); autoArrayType = createArrayType(autoType); if (autoArrayType === emptyObjectType) { // autoArrayType is used as a marker, so even if global Array type is not defined, it needs to be a unique type - autoArrayType = createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, emptyArray); + autoArrayType = createAnonymousType(undefined, emptySymbols, ts.emptyArray, ts.emptyArray, ts.emptyArray); } - globalReadonlyArrayType = getGlobalTypeOrUndefined("ReadonlyArray" as __String, /*arity*/ 1) as GenericType || globalArrayType; + globalReadonlyArrayType = getGlobalTypeOrUndefined("ReadonlyArray" as ts.__String, /*arity*/ 1) as ts.GenericType || globalArrayType; anyReadonlyArrayType = globalReadonlyArrayType ? createTypeFromGenericGlobalType(globalReadonlyArrayType, [anyType]) : anyArrayType; - globalThisType = getGlobalTypeOrUndefined("ThisType" as __String, /*arity*/ 1) as GenericType; + globalThisType = getGlobalTypeOrUndefined("ThisType" as ts.__String, /*arity*/ 1) as ts.GenericType; if (augmentations) { // merge _nonglobal_ module augmentations. // this needs to be done after global symbol table is initialized to make sure that all ambient modules are indexed for (const list of augmentations) { for (const augmentation of list) { - if (isGlobalScopeAugmentation(augmentation.parent as ModuleDeclaration)) continue; + if (ts.isGlobalScopeAugmentation(augmentation.parent as ts.ModuleDeclaration)) + continue; mergeModuleAugmentation(augmentation); } } @@ -43337,7 +42439,7 @@ namespace ts { // If not many things conflict, issue individual errors if (conflictingSymbols.size < 8) { conflictingSymbols.forEach(({ isBlockScoped, firstFileLocations, secondFileLocations }, symbolName) => { - const message = isBlockScoped ? Diagnostics.Cannot_redeclare_block_scoped_variable_0 : Diagnostics.Duplicate_identifier_0; + const message = isBlockScoped ? ts.Diagnostics.Cannot_redeclare_block_scoped_variable_0 : ts.Diagnostics.Duplicate_identifier_0; for (const node of firstFileLocations) { addDuplicateDeclarationError(node, message, symbolName, secondFileLocations); } @@ -43348,47 +42450,41 @@ namespace ts { } else { // Otherwise issue top-level error since the files appear very identical in terms of what they contain - const list = arrayFrom(conflictingSymbols.keys()).join(", "); - diagnostics.add(addRelatedInfo( - createDiagnosticForNode(firstFile, Diagnostics.Definitions_of_the_following_identifiers_conflict_with_those_in_another_file_Colon_0, list), - createDiagnosticForNode(secondFile, Diagnostics.Conflicts_are_in_this_file) - )); - diagnostics.add(addRelatedInfo( - createDiagnosticForNode(secondFile, Diagnostics.Definitions_of_the_following_identifiers_conflict_with_those_in_another_file_Colon_0, list), - createDiagnosticForNode(firstFile, Diagnostics.Conflicts_are_in_this_file) - )); + const list = ts.arrayFrom(conflictingSymbols.keys()).join(", "); + diagnostics.add(ts.addRelatedInfo(ts.createDiagnosticForNode(firstFile, ts.Diagnostics.Definitions_of_the_following_identifiers_conflict_with_those_in_another_file_Colon_0, list), ts.createDiagnosticForNode(secondFile, ts.Diagnostics.Conflicts_are_in_this_file))); + diagnostics.add(ts.addRelatedInfo(ts.createDiagnosticForNode(secondFile, ts.Diagnostics.Definitions_of_the_following_identifiers_conflict_with_those_in_another_file_Colon_0, list), ts.createDiagnosticForNode(firstFile, ts.Diagnostics.Conflicts_are_in_this_file))); } }); amalgamatedDuplicates = undefined; } - function checkExternalEmitHelpers(location: Node, helpers: ExternalEmitHelpers) { + function checkExternalEmitHelpers(location: ts.Node, helpers: ts.ExternalEmitHelpers) { if ((requestedExternalEmitHelpers & helpers) !== helpers && compilerOptions.importHelpers) { - const sourceFile = getSourceFileOfNode(location); - if (isEffectiveExternalModule(sourceFile, compilerOptions) && !(location.flags & NodeFlags.Ambient)) { + const sourceFile = ts.getSourceFileOfNode(location); + if (ts.isEffectiveExternalModule(sourceFile, compilerOptions) && !(location.flags & ts.NodeFlags.Ambient)) { const helpersModule = resolveHelpersModule(sourceFile, location); if (helpersModule !== unknownSymbol) { const uncheckedHelpers = helpers & ~requestedExternalEmitHelpers; - for (let helper = ExternalEmitHelpers.FirstEmitHelper; helper <= ExternalEmitHelpers.LastEmitHelper; helper <<= 1) { + for (let helper = ts.ExternalEmitHelpers.FirstEmitHelper; helper <= ts.ExternalEmitHelpers.LastEmitHelper; helper <<= 1) { if (uncheckedHelpers & helper) { const name = getHelperName(helper); - const symbol = getSymbol(helpersModule.exports!, escapeLeadingUnderscores(name), SymbolFlags.Value); + const symbol = getSymbol(helpersModule.exports!, ts.escapeLeadingUnderscores(name), ts.SymbolFlags.Value); if (!symbol) { - error(location, Diagnostics.This_syntax_requires_an_imported_helper_named_1_which_does_not_exist_in_0_Consider_upgrading_your_version_of_0, externalHelpersModuleNameText, name); + error(location, ts.Diagnostics.This_syntax_requires_an_imported_helper_named_1_which_does_not_exist_in_0_Consider_upgrading_your_version_of_0, ts.externalHelpersModuleNameText, name); } - else if (helper & ExternalEmitHelpers.ClassPrivateFieldGet) { - if (!some(getSignaturesOfSymbol(symbol), signature => getParameterCount(signature) > 3)) { - error(location, Diagnostics.This_syntax_requires_an_imported_helper_named_1_with_2_parameters_which_is_not_compatible_with_the_one_in_0_Consider_upgrading_your_version_of_0, externalHelpersModuleNameText, name, 4); + else if (helper & ts.ExternalEmitHelpers.ClassPrivateFieldGet) { + if (!ts.some(getSignaturesOfSymbol(symbol), signature => getParameterCount(signature) > 3)) { + error(location, ts.Diagnostics.This_syntax_requires_an_imported_helper_named_1_with_2_parameters_which_is_not_compatible_with_the_one_in_0_Consider_upgrading_your_version_of_0, ts.externalHelpersModuleNameText, name, 4); } } - else if (helper & ExternalEmitHelpers.ClassPrivateFieldSet) { - if (!some(getSignaturesOfSymbol(symbol), signature => getParameterCount(signature) > 4)) { - error(location, Diagnostics.This_syntax_requires_an_imported_helper_named_1_with_2_parameters_which_is_not_compatible_with_the_one_in_0_Consider_upgrading_your_version_of_0, externalHelpersModuleNameText, name, 5); + else if (helper & ts.ExternalEmitHelpers.ClassPrivateFieldSet) { + if (!ts.some(getSignaturesOfSymbol(symbol), signature => getParameterCount(signature) > 4)) { + error(location, ts.Diagnostics.This_syntax_requires_an_imported_helper_named_1_with_2_parameters_which_is_not_compatible_with_the_one_in_0_Consider_upgrading_your_version_of_0, ts.externalHelpersModuleNameText, name, 5); } } - else if (helper & ExternalEmitHelpers.SpreadArray) { - if (!some(getSignaturesOfSymbol(symbol), signature => getParameterCount(signature) > 2)) { - error(location, Diagnostics.This_syntax_requires_an_imported_helper_named_1_with_2_parameters_which_is_not_compatible_with_the_one_in_0_Consider_upgrading_your_version_of_0, externalHelpersModuleNameText, name, 3); + else if (helper & ts.ExternalEmitHelpers.SpreadArray) { + if (!ts.some(getSignaturesOfSymbol(symbol), signature => getParameterCount(signature) > 2)) { + error(location, ts.Diagnostics.This_syntax_requires_an_imported_helper_named_1_with_2_parameters_which_is_not_compatible_with_the_one_in_0_Consider_upgrading_your_version_of_0, ts.externalHelpersModuleNameText, name, 3); } } } @@ -43399,338 +42495,336 @@ namespace ts { } } - function getHelperName(helper: ExternalEmitHelpers) { + function getHelperName(helper: ts.ExternalEmitHelpers) { switch (helper) { - case ExternalEmitHelpers.Extends: return "__extends"; - case ExternalEmitHelpers.Assign: return "__assign"; - case ExternalEmitHelpers.Rest: return "__rest"; - case ExternalEmitHelpers.Decorate: return "__decorate"; - case ExternalEmitHelpers.Metadata: return "__metadata"; - case ExternalEmitHelpers.Param: return "__param"; - case ExternalEmitHelpers.Awaiter: return "__awaiter"; - case ExternalEmitHelpers.Generator: return "__generator"; - case ExternalEmitHelpers.Values: return "__values"; - case ExternalEmitHelpers.Read: return "__read"; - case ExternalEmitHelpers.SpreadArray: return "__spreadArray"; - case ExternalEmitHelpers.Await: return "__await"; - case ExternalEmitHelpers.AsyncGenerator: return "__asyncGenerator"; - case ExternalEmitHelpers.AsyncDelegator: return "__asyncDelegator"; - case ExternalEmitHelpers.AsyncValues: return "__asyncValues"; - case ExternalEmitHelpers.ExportStar: return "__exportStar"; - case ExternalEmitHelpers.ImportStar: return "__importStar"; - case ExternalEmitHelpers.ImportDefault: return "__importDefault"; - case ExternalEmitHelpers.MakeTemplateObject: return "__makeTemplateObject"; - case ExternalEmitHelpers.ClassPrivateFieldGet: return "__classPrivateFieldGet"; - case ExternalEmitHelpers.ClassPrivateFieldSet: return "__classPrivateFieldSet"; - case ExternalEmitHelpers.ClassPrivateFieldIn: return "__classPrivateFieldIn"; - case ExternalEmitHelpers.CreateBinding: return "__createBinding"; - default: return Debug.fail("Unrecognized helper"); - } - } - - function resolveHelpersModule(node: SourceFile, errorNode: Node) { + case ts.ExternalEmitHelpers.Extends: return "__extends"; + case ts.ExternalEmitHelpers.Assign: return "__assign"; + case ts.ExternalEmitHelpers.Rest: return "__rest"; + case ts.ExternalEmitHelpers.Decorate: return "__decorate"; + case ts.ExternalEmitHelpers.Metadata: return "__metadata"; + case ts.ExternalEmitHelpers.Param: return "__param"; + case ts.ExternalEmitHelpers.Awaiter: return "__awaiter"; + case ts.ExternalEmitHelpers.Generator: return "__generator"; + case ts.ExternalEmitHelpers.Values: return "__values"; + case ts.ExternalEmitHelpers.Read: return "__read"; + case ts.ExternalEmitHelpers.SpreadArray: return "__spreadArray"; + case ts.ExternalEmitHelpers.Await: return "__await"; + case ts.ExternalEmitHelpers.AsyncGenerator: return "__asyncGenerator"; + case ts.ExternalEmitHelpers.AsyncDelegator: return "__asyncDelegator"; + case ts.ExternalEmitHelpers.AsyncValues: return "__asyncValues"; + case ts.ExternalEmitHelpers.ExportStar: return "__exportStar"; + case ts.ExternalEmitHelpers.ImportStar: return "__importStar"; + case ts.ExternalEmitHelpers.ImportDefault: return "__importDefault"; + case ts.ExternalEmitHelpers.MakeTemplateObject: return "__makeTemplateObject"; + case ts.ExternalEmitHelpers.ClassPrivateFieldGet: return "__classPrivateFieldGet"; + case ts.ExternalEmitHelpers.ClassPrivateFieldSet: return "__classPrivateFieldSet"; + case ts.ExternalEmitHelpers.ClassPrivateFieldIn: return "__classPrivateFieldIn"; + case ts.ExternalEmitHelpers.CreateBinding: return "__createBinding"; + default: return ts.Debug.fail("Unrecognized helper"); + } + } + function resolveHelpersModule(node: ts.SourceFile, errorNode: ts.Node) { if (!externalHelpersModule) { - externalHelpersModule = resolveExternalModule(node, externalHelpersModuleNameText, Diagnostics.This_syntax_requires_an_imported_helper_but_module_0_cannot_be_found, errorNode) || unknownSymbol; + externalHelpersModule = resolveExternalModule(node, ts.externalHelpersModuleNameText, ts.Diagnostics.This_syntax_requires_an_imported_helper_but_module_0_cannot_be_found, errorNode) || unknownSymbol; } return externalHelpersModule; } // GRAMMAR CHECKING - function checkGrammarDecoratorsAndModifiers(node: Node): boolean { + function checkGrammarDecoratorsAndModifiers(node: ts.Node): boolean { return checkGrammarDecorators(node) || checkGrammarModifiers(node); } - function checkGrammarDecorators(node: Node): boolean { + function checkGrammarDecorators(node: ts.Node): boolean { if (!node.decorators) { return false; } - if (!nodeCanBeDecorated(node, node.parent, node.parent.parent)) { - if (node.kind === SyntaxKind.MethodDeclaration && !nodeIsPresent((node as MethodDeclaration).body)) { - return grammarErrorOnFirstToken(node, Diagnostics.A_decorator_can_only_decorate_a_method_implementation_not_an_overload); + if (!ts.nodeCanBeDecorated(node, node.parent, node.parent.parent)) { + if (node.kind === ts.SyntaxKind.MethodDeclaration && !ts.nodeIsPresent((node as ts.MethodDeclaration).body)) { + return grammarErrorOnFirstToken(node, ts.Diagnostics.A_decorator_can_only_decorate_a_method_implementation_not_an_overload); } else { - return grammarErrorOnFirstToken(node, Diagnostics.Decorators_are_not_valid_here); + return grammarErrorOnFirstToken(node, ts.Diagnostics.Decorators_are_not_valid_here); } } - else if (node.kind === SyntaxKind.GetAccessor || node.kind === SyntaxKind.SetAccessor) { - const accessors = getAllAccessorDeclarations((node.parent as ClassDeclaration).members, node as AccessorDeclaration); + else if (node.kind === ts.SyntaxKind.GetAccessor || node.kind === ts.SyntaxKind.SetAccessor) { + const accessors = ts.getAllAccessorDeclarations((node.parent as ts.ClassDeclaration).members, node as ts.AccessorDeclaration); if (accessors.firstAccessor.decorators && node === accessors.secondAccessor) { - return grammarErrorOnFirstToken(node, Diagnostics.Decorators_cannot_be_applied_to_multiple_get_Slashset_accessors_of_the_same_name); + return grammarErrorOnFirstToken(node, ts.Diagnostics.Decorators_cannot_be_applied_to_multiple_get_Slashset_accessors_of_the_same_name); } } return false; } - function checkGrammarModifiers(node: Node): boolean { + function checkGrammarModifiers(node: ts.Node): boolean { const quickResult = reportObviousModifierErrors(node); if (quickResult !== undefined) { return quickResult; } - let lastStatic: Node | undefined, lastDeclare: Node | undefined, lastAsync: Node | undefined, lastOverride: Node | undefined; - let flags = ModifierFlags.None; + let lastStatic: ts.Node | undefined, lastDeclare: ts.Node | undefined, lastAsync: ts.Node | undefined, lastOverride: ts.Node | undefined; + let flags = ts.ModifierFlags.None; for (const modifier of node.modifiers!) { - if (modifier.kind !== SyntaxKind.ReadonlyKeyword) { - if (node.kind === SyntaxKind.PropertySignature || node.kind === SyntaxKind.MethodSignature) { - return grammarErrorOnNode(modifier, Diagnostics._0_modifier_cannot_appear_on_a_type_member, tokenToString(modifier.kind)); + if (modifier.kind !== ts.SyntaxKind.ReadonlyKeyword) { + if (node.kind === ts.SyntaxKind.PropertySignature || node.kind === ts.SyntaxKind.MethodSignature) { + return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_cannot_appear_on_a_type_member, ts.tokenToString(modifier.kind)); } - if (node.kind === SyntaxKind.IndexSignature && (modifier.kind !== SyntaxKind.StaticKeyword || !isClassLike(node.parent))) { - return grammarErrorOnNode(modifier, Diagnostics._0_modifier_cannot_appear_on_an_index_signature, tokenToString(modifier.kind)); + if (node.kind === ts.SyntaxKind.IndexSignature && (modifier.kind !== ts.SyntaxKind.StaticKeyword || !ts.isClassLike(node.parent))) { + return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_cannot_appear_on_an_index_signature, ts.tokenToString(modifier.kind)); } } - if (modifier.kind !== SyntaxKind.InKeyword && modifier.kind !== SyntaxKind.OutKeyword) { - if (node.kind === SyntaxKind.TypeParameter) { - return grammarErrorOnNode(modifier, Diagnostics._0_modifier_cannot_appear_on_a_type_parameter, tokenToString(modifier.kind)); + if (modifier.kind !== ts.SyntaxKind.InKeyword && modifier.kind !== ts.SyntaxKind.OutKeyword) { + if (node.kind === ts.SyntaxKind.TypeParameter) { + return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_cannot_appear_on_a_type_parameter, ts.tokenToString(modifier.kind)); } } switch (modifier.kind) { - case SyntaxKind.ConstKeyword: - if (node.kind !== SyntaxKind.EnumDeclaration) { - return grammarErrorOnNode(node, Diagnostics.A_class_member_cannot_have_the_0_keyword, tokenToString(SyntaxKind.ConstKeyword)); + case ts.SyntaxKind.ConstKeyword: + if (node.kind !== ts.SyntaxKind.EnumDeclaration) { + return grammarErrorOnNode(node, ts.Diagnostics.A_class_member_cannot_have_the_0_keyword, ts.tokenToString(ts.SyntaxKind.ConstKeyword)); } break; - case SyntaxKind.OverrideKeyword: + case ts.SyntaxKind.OverrideKeyword: // If node.kind === SyntaxKind.Parameter, checkParameter reports an error if it's not a parameter property. - if (flags & ModifierFlags.Override) { - return grammarErrorOnNode(modifier, Diagnostics._0_modifier_already_seen, "override"); + if (flags & ts.ModifierFlags.Override) { + return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_already_seen, "override"); } - else if (flags & ModifierFlags.Ambient) { - return grammarErrorOnNode(modifier, Diagnostics._0_modifier_cannot_be_used_with_1_modifier, "override", "declare"); + else if (flags & ts.ModifierFlags.Ambient) { + return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_cannot_be_used_with_1_modifier, "override", "declare"); } - else if (flags & ModifierFlags.Readonly) { - return grammarErrorOnNode(modifier, Diagnostics._0_modifier_must_precede_1_modifier, "override", "readonly"); + else if (flags & ts.ModifierFlags.Readonly) { + return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_must_precede_1_modifier, "override", "readonly"); } - else if (flags & ModifierFlags.Async) { - return grammarErrorOnNode(modifier, Diagnostics._0_modifier_must_precede_1_modifier, "override", "async"); + else if (flags & ts.ModifierFlags.Async) { + return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_must_precede_1_modifier, "override", "async"); } - flags |= ModifierFlags.Override; + flags |= ts.ModifierFlags.Override; lastOverride = modifier; break; - case SyntaxKind.PublicKeyword: - case SyntaxKind.ProtectedKeyword: - case SyntaxKind.PrivateKeyword: - const text = visibilityToString(modifierToFlag(modifier.kind)); - - if (flags & ModifierFlags.AccessibilityModifier) { - return grammarErrorOnNode(modifier, Diagnostics.Accessibility_modifier_already_seen); + case ts.SyntaxKind.PublicKeyword: + case ts.SyntaxKind.ProtectedKeyword: + case ts.SyntaxKind.PrivateKeyword: + const text = visibilityToString(ts.modifierToFlag(modifier.kind)); + if (flags & ts.ModifierFlags.AccessibilityModifier) { + return grammarErrorOnNode(modifier, ts.Diagnostics.Accessibility_modifier_already_seen); } - else if (flags & ModifierFlags.Override) { - return grammarErrorOnNode(modifier, Diagnostics._0_modifier_must_precede_1_modifier, text, "override"); + else if (flags & ts.ModifierFlags.Override) { + return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_must_precede_1_modifier, text, "override"); } - else if (flags & ModifierFlags.Static) { - return grammarErrorOnNode(modifier, Diagnostics._0_modifier_must_precede_1_modifier, text, "static"); + else if (flags & ts.ModifierFlags.Static) { + return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_must_precede_1_modifier, text, "static"); } - else if (flags & ModifierFlags.Readonly) { - return grammarErrorOnNode(modifier, Diagnostics._0_modifier_must_precede_1_modifier, text, "readonly"); + else if (flags & ts.ModifierFlags.Readonly) { + return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_must_precede_1_modifier, text, "readonly"); } - else if (flags & ModifierFlags.Async) { - return grammarErrorOnNode(modifier, Diagnostics._0_modifier_must_precede_1_modifier, text, "async"); + else if (flags & ts.ModifierFlags.Async) { + return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_must_precede_1_modifier, text, "async"); } - else if (node.parent.kind === SyntaxKind.ModuleBlock || node.parent.kind === SyntaxKind.SourceFile) { - return grammarErrorOnNode(modifier, Diagnostics._0_modifier_cannot_appear_on_a_module_or_namespace_element, text); + else if (node.parent.kind === ts.SyntaxKind.ModuleBlock || node.parent.kind === ts.SyntaxKind.SourceFile) { + return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_cannot_appear_on_a_module_or_namespace_element, text); } - else if (flags & ModifierFlags.Abstract) { - if (modifier.kind === SyntaxKind.PrivateKeyword) { - return grammarErrorOnNode(modifier, Diagnostics._0_modifier_cannot_be_used_with_1_modifier, text, "abstract"); + else if (flags & ts.ModifierFlags.Abstract) { + if (modifier.kind === ts.SyntaxKind.PrivateKeyword) { + return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_cannot_be_used_with_1_modifier, text, "abstract"); } else { - return grammarErrorOnNode(modifier, Diagnostics._0_modifier_must_precede_1_modifier, text, "abstract"); + return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_must_precede_1_modifier, text, "abstract"); } } - else if (isPrivateIdentifierClassElementDeclaration(node)) { - return grammarErrorOnNode(modifier, Diagnostics.An_accessibility_modifier_cannot_be_used_with_a_private_identifier); + else if (ts.isPrivateIdentifierClassElementDeclaration(node)) { + return grammarErrorOnNode(modifier, ts.Diagnostics.An_accessibility_modifier_cannot_be_used_with_a_private_identifier); } - flags |= modifierToFlag(modifier.kind); + flags |= ts.modifierToFlag(modifier.kind); break; - case SyntaxKind.StaticKeyword: - if (flags & ModifierFlags.Static) { - return grammarErrorOnNode(modifier, Diagnostics._0_modifier_already_seen, "static"); + case ts.SyntaxKind.StaticKeyword: + if (flags & ts.ModifierFlags.Static) { + return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_already_seen, "static"); } - else if (flags & ModifierFlags.Readonly) { - return grammarErrorOnNode(modifier, Diagnostics._0_modifier_must_precede_1_modifier, "static", "readonly"); + else if (flags & ts.ModifierFlags.Readonly) { + return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_must_precede_1_modifier, "static", "readonly"); } - else if (flags & ModifierFlags.Async) { - return grammarErrorOnNode(modifier, Diagnostics._0_modifier_must_precede_1_modifier, "static", "async"); + else if (flags & ts.ModifierFlags.Async) { + return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_must_precede_1_modifier, "static", "async"); } - else if (node.parent.kind === SyntaxKind.ModuleBlock || node.parent.kind === SyntaxKind.SourceFile) { - return grammarErrorOnNode(modifier, Diagnostics._0_modifier_cannot_appear_on_a_module_or_namespace_element, "static"); + else if (node.parent.kind === ts.SyntaxKind.ModuleBlock || node.parent.kind === ts.SyntaxKind.SourceFile) { + return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_cannot_appear_on_a_module_or_namespace_element, "static"); } - else if (node.kind === SyntaxKind.Parameter) { - return grammarErrorOnNode(modifier, Diagnostics._0_modifier_cannot_appear_on_a_parameter, "static"); + else if (node.kind === ts.SyntaxKind.Parameter) { + return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_cannot_appear_on_a_parameter, "static"); } - else if (flags & ModifierFlags.Abstract) { - return grammarErrorOnNode(modifier, Diagnostics._0_modifier_cannot_be_used_with_1_modifier, "static", "abstract"); + else if (flags & ts.ModifierFlags.Abstract) { + return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_cannot_be_used_with_1_modifier, "static", "abstract"); } - else if (flags & ModifierFlags.Override) { - return grammarErrorOnNode(modifier, Diagnostics._0_modifier_must_precede_1_modifier, "static", "override"); + else if (flags & ts.ModifierFlags.Override) { + return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_must_precede_1_modifier, "static", "override"); } - flags |= ModifierFlags.Static; + flags |= ts.ModifierFlags.Static; lastStatic = modifier; break; - case SyntaxKind.ReadonlyKeyword: - if (flags & ModifierFlags.Readonly) { - return grammarErrorOnNode(modifier, Diagnostics._0_modifier_already_seen, "readonly"); + case ts.SyntaxKind.ReadonlyKeyword: + if (flags & ts.ModifierFlags.Readonly) { + return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_already_seen, "readonly"); } - else if (node.kind !== SyntaxKind.PropertyDeclaration && node.kind !== SyntaxKind.PropertySignature && node.kind !== SyntaxKind.IndexSignature && node.kind !== SyntaxKind.Parameter) { + else if (node.kind !== ts.SyntaxKind.PropertyDeclaration && node.kind !== ts.SyntaxKind.PropertySignature && node.kind !== ts.SyntaxKind.IndexSignature && node.kind !== ts.SyntaxKind.Parameter) { // If node.kind === SyntaxKind.Parameter, checkParameter reports an error if it's not a parameter property. - return grammarErrorOnNode(modifier, Diagnostics.readonly_modifier_can_only_appear_on_a_property_declaration_or_index_signature); + return grammarErrorOnNode(modifier, ts.Diagnostics.readonly_modifier_can_only_appear_on_a_property_declaration_or_index_signature); } - flags |= ModifierFlags.Readonly; + flags |= ts.ModifierFlags.Readonly; break; - case SyntaxKind.ExportKeyword: - if (flags & ModifierFlags.Export) { - return grammarErrorOnNode(modifier, Diagnostics._0_modifier_already_seen, "export"); + case ts.SyntaxKind.ExportKeyword: + if (flags & ts.ModifierFlags.Export) { + return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_already_seen, "export"); } - else if (flags & ModifierFlags.Ambient) { - return grammarErrorOnNode(modifier, Diagnostics._0_modifier_must_precede_1_modifier, "export", "declare"); + else if (flags & ts.ModifierFlags.Ambient) { + return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_must_precede_1_modifier, "export", "declare"); } - else if (flags & ModifierFlags.Abstract) { - return grammarErrorOnNode(modifier, Diagnostics._0_modifier_must_precede_1_modifier, "export", "abstract"); + else if (flags & ts.ModifierFlags.Abstract) { + return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_must_precede_1_modifier, "export", "abstract"); } - else if (flags & ModifierFlags.Async) { - return grammarErrorOnNode(modifier, Diagnostics._0_modifier_must_precede_1_modifier, "export", "async"); + else if (flags & ts.ModifierFlags.Async) { + return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_must_precede_1_modifier, "export", "async"); } - else if (isClassLike(node.parent)) { - return grammarErrorOnNode(modifier, Diagnostics._0_modifier_cannot_appear_on_class_elements_of_this_kind, "export"); + else if (ts.isClassLike(node.parent)) { + return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_cannot_appear_on_class_elements_of_this_kind, "export"); } - else if (node.kind === SyntaxKind.Parameter) { - return grammarErrorOnNode(modifier, Diagnostics._0_modifier_cannot_appear_on_a_parameter, "export"); + else if (node.kind === ts.SyntaxKind.Parameter) { + return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_cannot_appear_on_a_parameter, "export"); } - flags |= ModifierFlags.Export; + flags |= ts.ModifierFlags.Export; break; - case SyntaxKind.DefaultKeyword: - const container = node.parent.kind === SyntaxKind.SourceFile ? node.parent : node.parent.parent; - if (container.kind === SyntaxKind.ModuleDeclaration && !isAmbientModule(container)) { - return grammarErrorOnNode(modifier, Diagnostics.A_default_export_can_only_be_used_in_an_ECMAScript_style_module); + case ts.SyntaxKind.DefaultKeyword: + const container = node.parent.kind === ts.SyntaxKind.SourceFile ? node.parent : node.parent.parent; + if (container.kind === ts.SyntaxKind.ModuleDeclaration && !ts.isAmbientModule(container)) { + return grammarErrorOnNode(modifier, ts.Diagnostics.A_default_export_can_only_be_used_in_an_ECMAScript_style_module); } - else if (!(flags & ModifierFlags.Export)) { - return grammarErrorOnNode(modifier, Diagnostics._0_modifier_must_precede_1_modifier, "export", "default"); + else if (!(flags & ts.ModifierFlags.Export)) { + return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_must_precede_1_modifier, "export", "default"); } - flags |= ModifierFlags.Default; + flags |= ts.ModifierFlags.Default; break; - case SyntaxKind.DeclareKeyword: - if (flags & ModifierFlags.Ambient) { - return grammarErrorOnNode(modifier, Diagnostics._0_modifier_already_seen, "declare"); + case ts.SyntaxKind.DeclareKeyword: + if (flags & ts.ModifierFlags.Ambient) { + return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_already_seen, "declare"); } - else if (flags & ModifierFlags.Async) { - return grammarErrorOnNode(modifier, Diagnostics._0_modifier_cannot_be_used_in_an_ambient_context, "async"); + else if (flags & ts.ModifierFlags.Async) { + return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_cannot_be_used_in_an_ambient_context, "async"); } - else if (flags & ModifierFlags.Override) { - return grammarErrorOnNode(modifier, Diagnostics._0_modifier_cannot_be_used_in_an_ambient_context, "override"); + else if (flags & ts.ModifierFlags.Override) { + return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_cannot_be_used_in_an_ambient_context, "override"); } - else if (isClassLike(node.parent) && !isPropertyDeclaration(node)) { - return grammarErrorOnNode(modifier, Diagnostics._0_modifier_cannot_appear_on_class_elements_of_this_kind, "declare"); + else if (ts.isClassLike(node.parent) && !ts.isPropertyDeclaration(node)) { + return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_cannot_appear_on_class_elements_of_this_kind, "declare"); } - else if (node.kind === SyntaxKind.Parameter) { - return grammarErrorOnNode(modifier, Diagnostics._0_modifier_cannot_appear_on_a_parameter, "declare"); + else if (node.kind === ts.SyntaxKind.Parameter) { + return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_cannot_appear_on_a_parameter, "declare"); } - else if ((node.parent.flags & NodeFlags.Ambient) && node.parent.kind === SyntaxKind.ModuleBlock) { - return grammarErrorOnNode(modifier, Diagnostics.A_declare_modifier_cannot_be_used_in_an_already_ambient_context); + else if ((node.parent.flags & ts.NodeFlags.Ambient) && node.parent.kind === ts.SyntaxKind.ModuleBlock) { + return grammarErrorOnNode(modifier, ts.Diagnostics.A_declare_modifier_cannot_be_used_in_an_already_ambient_context); } - else if (isPrivateIdentifierClassElementDeclaration(node)) { - return grammarErrorOnNode(modifier, Diagnostics._0_modifier_cannot_be_used_with_a_private_identifier, "declare"); + else if (ts.isPrivateIdentifierClassElementDeclaration(node)) { + return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_cannot_be_used_with_a_private_identifier, "declare"); } - flags |= ModifierFlags.Ambient; + flags |= ts.ModifierFlags.Ambient; lastDeclare = modifier; break; - case SyntaxKind.AbstractKeyword: - if (flags & ModifierFlags.Abstract) { - return grammarErrorOnNode(modifier, Diagnostics._0_modifier_already_seen, "abstract"); + case ts.SyntaxKind.AbstractKeyword: + if (flags & ts.ModifierFlags.Abstract) { + return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_already_seen, "abstract"); } - if (node.kind !== SyntaxKind.ClassDeclaration && - node.kind !== SyntaxKind.ConstructorType) { - if (node.kind !== SyntaxKind.MethodDeclaration && - node.kind !== SyntaxKind.PropertyDeclaration && - node.kind !== SyntaxKind.GetAccessor && - node.kind !== SyntaxKind.SetAccessor) { - return grammarErrorOnNode(modifier, Diagnostics.abstract_modifier_can_only_appear_on_a_class_method_or_property_declaration); + if (node.kind !== ts.SyntaxKind.ClassDeclaration && + node.kind !== ts.SyntaxKind.ConstructorType) { + if (node.kind !== ts.SyntaxKind.MethodDeclaration && + node.kind !== ts.SyntaxKind.PropertyDeclaration && + node.kind !== ts.SyntaxKind.GetAccessor && + node.kind !== ts.SyntaxKind.SetAccessor) { + return grammarErrorOnNode(modifier, ts.Diagnostics.abstract_modifier_can_only_appear_on_a_class_method_or_property_declaration); } - if (!(node.parent.kind === SyntaxKind.ClassDeclaration && hasSyntacticModifier(node.parent, ModifierFlags.Abstract))) { - return grammarErrorOnNode(modifier, Diagnostics.Abstract_methods_can_only_appear_within_an_abstract_class); + if (!(node.parent.kind === ts.SyntaxKind.ClassDeclaration && ts.hasSyntacticModifier(node.parent, ts.ModifierFlags.Abstract))) { + return grammarErrorOnNode(modifier, ts.Diagnostics.Abstract_methods_can_only_appear_within_an_abstract_class); } - if (flags & ModifierFlags.Static) { - return grammarErrorOnNode(modifier, Diagnostics._0_modifier_cannot_be_used_with_1_modifier, "static", "abstract"); + if (flags & ts.ModifierFlags.Static) { + return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_cannot_be_used_with_1_modifier, "static", "abstract"); } - if (flags & ModifierFlags.Private) { - return grammarErrorOnNode(modifier, Diagnostics._0_modifier_cannot_be_used_with_1_modifier, "private", "abstract"); + if (flags & ts.ModifierFlags.Private) { + return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_cannot_be_used_with_1_modifier, "private", "abstract"); } - if (flags & ModifierFlags.Async && lastAsync) { - return grammarErrorOnNode(lastAsync, Diagnostics._0_modifier_cannot_be_used_with_1_modifier, "async", "abstract"); + if (flags & ts.ModifierFlags.Async && lastAsync) { + return grammarErrorOnNode(lastAsync, ts.Diagnostics._0_modifier_cannot_be_used_with_1_modifier, "async", "abstract"); } - if (flags & ModifierFlags.Override) { - return grammarErrorOnNode(modifier, Diagnostics._0_modifier_must_precede_1_modifier, "abstract", "override"); + if (flags & ts.ModifierFlags.Override) { + return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_must_precede_1_modifier, "abstract", "override"); } } - if (isNamedDeclaration(node) && node.name.kind === SyntaxKind.PrivateIdentifier) { - return grammarErrorOnNode(modifier, Diagnostics._0_modifier_cannot_be_used_with_a_private_identifier, "abstract"); + if (ts.isNamedDeclaration(node) && node.name.kind === ts.SyntaxKind.PrivateIdentifier) { + return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_cannot_be_used_with_a_private_identifier, "abstract"); } - flags |= ModifierFlags.Abstract; + flags |= ts.ModifierFlags.Abstract; break; - case SyntaxKind.AsyncKeyword: - if (flags & ModifierFlags.Async) { - return grammarErrorOnNode(modifier, Diagnostics._0_modifier_already_seen, "async"); + case ts.SyntaxKind.AsyncKeyword: + if (flags & ts.ModifierFlags.Async) { + return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_already_seen, "async"); } - else if (flags & ModifierFlags.Ambient || node.parent.flags & NodeFlags.Ambient) { - return grammarErrorOnNode(modifier, Diagnostics._0_modifier_cannot_be_used_in_an_ambient_context, "async"); + else if (flags & ts.ModifierFlags.Ambient || node.parent.flags & ts.NodeFlags.Ambient) { + return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_cannot_be_used_in_an_ambient_context, "async"); } - else if (node.kind === SyntaxKind.Parameter) { - return grammarErrorOnNode(modifier, Diagnostics._0_modifier_cannot_appear_on_a_parameter, "async"); + else if (node.kind === ts.SyntaxKind.Parameter) { + return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_cannot_appear_on_a_parameter, "async"); } - if (flags & ModifierFlags.Abstract) { - return grammarErrorOnNode(modifier, Diagnostics._0_modifier_cannot_be_used_with_1_modifier, "async", "abstract"); + if (flags & ts.ModifierFlags.Abstract) { + return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_cannot_be_used_with_1_modifier, "async", "abstract"); } - flags |= ModifierFlags.Async; + flags |= ts.ModifierFlags.Async; lastAsync = modifier; break; - case SyntaxKind.InKeyword: - case SyntaxKind.OutKeyword: - const inOutFlag = modifier.kind === SyntaxKind.InKeyword ? ModifierFlags.In : ModifierFlags.Out; - const inOutText = modifier.kind === SyntaxKind.InKeyword ? "in" : "out"; - if (node.kind !== SyntaxKind.TypeParameter || !(isInterfaceDeclaration(node.parent) || isClassLike(node.parent) || isTypeAliasDeclaration(node.parent))) { - return grammarErrorOnNode(modifier, Diagnostics._0_modifier_can_only_appear_on_a_type_parameter_of_a_class_interface_or_type_alias, inOutText); + case ts.SyntaxKind.InKeyword: + case ts.SyntaxKind.OutKeyword: + const inOutFlag = modifier.kind === ts.SyntaxKind.InKeyword ? ts.ModifierFlags.In : ts.ModifierFlags.Out; + const inOutText = modifier.kind === ts.SyntaxKind.InKeyword ? "in" : "out"; + if (node.kind !== ts.SyntaxKind.TypeParameter || !(ts.isInterfaceDeclaration(node.parent) || ts.isClassLike(node.parent) || ts.isTypeAliasDeclaration(node.parent))) { + return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_can_only_appear_on_a_type_parameter_of_a_class_interface_or_type_alias, inOutText); } if (flags & inOutFlag) { - return grammarErrorOnNode(modifier, Diagnostics._0_modifier_already_seen, inOutText); + return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_already_seen, inOutText); } - if (inOutFlag & ModifierFlags.In && flags & ModifierFlags.Out) { - return grammarErrorOnNode(modifier, Diagnostics._0_modifier_must_precede_1_modifier, "in", "out"); + if (inOutFlag & ts.ModifierFlags.In && flags & ts.ModifierFlags.Out) { + return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_must_precede_1_modifier, "in", "out"); } flags |= inOutFlag; break; } } - if (node.kind === SyntaxKind.Constructor) { - if (flags & ModifierFlags.Static) { - return grammarErrorOnNode(lastStatic!, Diagnostics._0_modifier_cannot_appear_on_a_constructor_declaration, "static"); + if (node.kind === ts.SyntaxKind.Constructor) { + if (flags & ts.ModifierFlags.Static) { + return grammarErrorOnNode(lastStatic!, ts.Diagnostics._0_modifier_cannot_appear_on_a_constructor_declaration, "static"); } - if (flags & ModifierFlags.Override) { - return grammarErrorOnNode(lastOverride!, Diagnostics._0_modifier_cannot_appear_on_a_constructor_declaration, "override"); // TODO: GH#18217 + if (flags & ts.ModifierFlags.Override) { + return grammarErrorOnNode(lastOverride!, ts.Diagnostics._0_modifier_cannot_appear_on_a_constructor_declaration, "override"); // TODO: GH#18217 } - if (flags & ModifierFlags.Async) { - return grammarErrorOnNode(lastAsync!, Diagnostics._0_modifier_cannot_appear_on_a_constructor_declaration, "async"); + if (flags & ts.ModifierFlags.Async) { + return grammarErrorOnNode(lastAsync!, ts.Diagnostics._0_modifier_cannot_appear_on_a_constructor_declaration, "async"); } return false; } - else if ((node.kind === SyntaxKind.ImportDeclaration || node.kind === SyntaxKind.ImportEqualsDeclaration) && flags & ModifierFlags.Ambient) { - return grammarErrorOnNode(lastDeclare!, Diagnostics.A_0_modifier_cannot_be_used_with_an_import_declaration, "declare"); + else if ((node.kind === ts.SyntaxKind.ImportDeclaration || node.kind === ts.SyntaxKind.ImportEqualsDeclaration) && flags & ts.ModifierFlags.Ambient) { + return grammarErrorOnNode(lastDeclare!, ts.Diagnostics.A_0_modifier_cannot_be_used_with_an_import_declaration, "declare"); } - else if (node.kind === SyntaxKind.Parameter && (flags & ModifierFlags.ParameterPropertyModifier) && isBindingPattern((node as ParameterDeclaration).name)) { - return grammarErrorOnNode(node, Diagnostics.A_parameter_property_may_not_be_declared_using_a_binding_pattern); + else if (node.kind === ts.SyntaxKind.Parameter && (flags & ts.ModifierFlags.ParameterPropertyModifier) && ts.isBindingPattern((node as ts.ParameterDeclaration).name)) { + return grammarErrorOnNode(node, ts.Diagnostics.A_parameter_property_may_not_be_declared_using_a_binding_pattern); } - else if (node.kind === SyntaxKind.Parameter && (flags & ModifierFlags.ParameterPropertyModifier) && (node as ParameterDeclaration).dotDotDotToken) { - return grammarErrorOnNode(node, Diagnostics.A_parameter_property_cannot_be_declared_using_a_rest_parameter); + else if (node.kind === ts.SyntaxKind.Parameter && (flags & ts.ModifierFlags.ParameterPropertyModifier) && (node as ts.ParameterDeclaration).dotDotDotToken) { + return grammarErrorOnNode(node, ts.Diagnostics.A_parameter_property_cannot_be_declared_using_a_rest_parameter); } - if (flags & ModifierFlags.Async) { + if (flags & ts.ModifierFlags.Async) { return checkGrammarAsyncModifier(node, lastAsync!); } return false; @@ -43740,88 +42834,88 @@ namespace ts { * true | false: Early return this value from checkGrammarModifiers. * undefined: Need to do full checking on the modifiers. */ - function reportObviousModifierErrors(node: Node): boolean | undefined { + function reportObviousModifierErrors(node: ts.Node): boolean | undefined { return !node.modifiers ? false : shouldReportBadModifier(node) - ? grammarErrorOnFirstToken(node, Diagnostics.Modifiers_cannot_appear_here) + ? grammarErrorOnFirstToken(node, ts.Diagnostics.Modifiers_cannot_appear_here) : undefined; } - function shouldReportBadModifier(node: Node): boolean { + function shouldReportBadModifier(node: ts.Node): boolean { switch (node.kind) { - case SyntaxKind.GetAccessor: - case SyntaxKind.SetAccessor: - case SyntaxKind.Constructor: - case SyntaxKind.PropertyDeclaration: - case SyntaxKind.PropertySignature: - case SyntaxKind.MethodDeclaration: - case SyntaxKind.MethodSignature: - case SyntaxKind.IndexSignature: - case SyntaxKind.ModuleDeclaration: - case SyntaxKind.ImportDeclaration: - case SyntaxKind.ImportEqualsDeclaration: - case SyntaxKind.ExportDeclaration: - case SyntaxKind.ExportAssignment: - case SyntaxKind.FunctionExpression: - case SyntaxKind.ArrowFunction: - case SyntaxKind.Parameter: - case SyntaxKind.TypeParameter: + case ts.SyntaxKind.GetAccessor: + case ts.SyntaxKind.SetAccessor: + case ts.SyntaxKind.Constructor: + case ts.SyntaxKind.PropertyDeclaration: + case ts.SyntaxKind.PropertySignature: + case ts.SyntaxKind.MethodDeclaration: + case ts.SyntaxKind.MethodSignature: + case ts.SyntaxKind.IndexSignature: + case ts.SyntaxKind.ModuleDeclaration: + case ts.SyntaxKind.ImportDeclaration: + case ts.SyntaxKind.ImportEqualsDeclaration: + case ts.SyntaxKind.ExportDeclaration: + case ts.SyntaxKind.ExportAssignment: + case ts.SyntaxKind.FunctionExpression: + case ts.SyntaxKind.ArrowFunction: + case ts.SyntaxKind.Parameter: + case ts.SyntaxKind.TypeParameter: return false; default: - if (node.parent.kind === SyntaxKind.ModuleBlock || node.parent.kind === SyntaxKind.SourceFile) { + if (node.parent.kind === ts.SyntaxKind.ModuleBlock || node.parent.kind === ts.SyntaxKind.SourceFile) { return false; } switch (node.kind) { - case SyntaxKind.FunctionDeclaration: - return nodeHasAnyModifiersExcept(node, SyntaxKind.AsyncKeyword); - case SyntaxKind.ClassDeclaration: - case SyntaxKind.ConstructorType: - return nodeHasAnyModifiersExcept(node, SyntaxKind.AbstractKeyword); - case SyntaxKind.InterfaceDeclaration: - case SyntaxKind.VariableStatement: - case SyntaxKind.TypeAliasDeclaration: - case SyntaxKind.ClassStaticBlockDeclaration: + case ts.SyntaxKind.FunctionDeclaration: + return nodeHasAnyModifiersExcept(node, ts.SyntaxKind.AsyncKeyword); + case ts.SyntaxKind.ClassDeclaration: + case ts.SyntaxKind.ConstructorType: + return nodeHasAnyModifiersExcept(node, ts.SyntaxKind.AbstractKeyword); + case ts.SyntaxKind.InterfaceDeclaration: + case ts.SyntaxKind.VariableStatement: + case ts.SyntaxKind.TypeAliasDeclaration: + case ts.SyntaxKind.ClassStaticBlockDeclaration: return true; - case SyntaxKind.EnumDeclaration: - return nodeHasAnyModifiersExcept(node, SyntaxKind.ConstKeyword); + case ts.SyntaxKind.EnumDeclaration: + return nodeHasAnyModifiersExcept(node, ts.SyntaxKind.ConstKeyword); default: - Debug.fail(); + ts.Debug.fail(); } } } - function nodeHasAnyModifiersExcept(node: Node, allowedModifier: SyntaxKind): boolean { + function nodeHasAnyModifiersExcept(node: ts.Node, allowedModifier: ts.SyntaxKind): boolean { return node.modifiers!.length > 1 || node.modifiers![0].kind !== allowedModifier; } - function checkGrammarAsyncModifier(node: Node, asyncModifier: Node): boolean { + function checkGrammarAsyncModifier(node: ts.Node, asyncModifier: ts.Node): boolean { switch (node.kind) { - case SyntaxKind.MethodDeclaration: - case SyntaxKind.FunctionDeclaration: - case SyntaxKind.FunctionExpression: - case SyntaxKind.ArrowFunction: + case ts.SyntaxKind.MethodDeclaration: + case ts.SyntaxKind.FunctionDeclaration: + case ts.SyntaxKind.FunctionExpression: + case ts.SyntaxKind.ArrowFunction: return false; } - return grammarErrorOnNode(asyncModifier, Diagnostics._0_modifier_cannot_be_used_here, "async"); + return grammarErrorOnNode(asyncModifier, ts.Diagnostics._0_modifier_cannot_be_used_here, "async"); } - function checkGrammarForDisallowedTrailingComma(list: NodeArray | undefined, diag = Diagnostics.Trailing_comma_not_allowed): boolean { + function checkGrammarForDisallowedTrailingComma(list: ts.NodeArray | undefined, diag = ts.Diagnostics.Trailing_comma_not_allowed): boolean { if (list && list.hasTrailingComma) { return grammarErrorAtPos(list[0], list.end - ",".length, ",".length, diag); } return false; } - function checkGrammarTypeParameterList(typeParameters: NodeArray | undefined, file: SourceFile): boolean { + function checkGrammarTypeParameterList(typeParameters: ts.NodeArray | undefined, file: ts.SourceFile): boolean { if (typeParameters && typeParameters.length === 0) { const start = typeParameters.pos - "<".length; - const end = skipTrivia(file.text, typeParameters.end) + ">".length; - return grammarErrorAtPos(file, start, end - start, Diagnostics.Type_parameter_list_cannot_be_empty); + const end = ts.skipTrivia(file.text, typeParameters.end) + ">".length; + return grammarErrorAtPos(file, start, end - start, ts.Diagnostics.Type_parameter_list_cannot_be_empty); } return false; } - function checkGrammarParameterList(parameters: NodeArray) { + function checkGrammarParameterList(parameters: ts.NodeArray) { let seenOptionalParameter = false; const parameterCount = parameters.length; @@ -43829,53 +42923,51 @@ namespace ts { const parameter = parameters[i]; if (parameter.dotDotDotToken) { if (i !== (parameterCount - 1)) { - return grammarErrorOnNode(parameter.dotDotDotToken, Diagnostics.A_rest_parameter_must_be_last_in_a_parameter_list); + return grammarErrorOnNode(parameter.dotDotDotToken, ts.Diagnostics.A_rest_parameter_must_be_last_in_a_parameter_list); } - if (!(parameter.flags & NodeFlags.Ambient)) { // Allow `...foo,` in ambient declarations; see GH#23070 - checkGrammarForDisallowedTrailingComma(parameters, Diagnostics.A_rest_parameter_or_binding_pattern_may_not_have_a_trailing_comma); + if (!(parameter.flags & ts.NodeFlags.Ambient)) { // Allow `...foo,` in ambient declarations; see GH#23070 + checkGrammarForDisallowedTrailingComma(parameters, ts.Diagnostics.A_rest_parameter_or_binding_pattern_may_not_have_a_trailing_comma); } if (parameter.questionToken) { - return grammarErrorOnNode(parameter.questionToken, Diagnostics.A_rest_parameter_cannot_be_optional); + return grammarErrorOnNode(parameter.questionToken, ts.Diagnostics.A_rest_parameter_cannot_be_optional); } if (parameter.initializer) { - return grammarErrorOnNode(parameter.name, Diagnostics.A_rest_parameter_cannot_have_an_initializer); + return grammarErrorOnNode(parameter.name, ts.Diagnostics.A_rest_parameter_cannot_have_an_initializer); } } else if (isOptionalParameter(parameter)) { seenOptionalParameter = true; if (parameter.questionToken && parameter.initializer) { - return grammarErrorOnNode(parameter.name, Diagnostics.Parameter_cannot_have_question_mark_and_initializer); + return grammarErrorOnNode(parameter.name, ts.Diagnostics.Parameter_cannot_have_question_mark_and_initializer); } } else if (seenOptionalParameter && !parameter.initializer) { - return grammarErrorOnNode(parameter.name, Diagnostics.A_required_parameter_cannot_follow_an_optional_parameter); + return grammarErrorOnNode(parameter.name, ts.Diagnostics.A_required_parameter_cannot_follow_an_optional_parameter); } } } - function getNonSimpleParameters(parameters: readonly ParameterDeclaration[]): readonly ParameterDeclaration[] { - return filter(parameters, parameter => !!parameter.initializer || isBindingPattern(parameter.name) || isRestParameter(parameter)); + function getNonSimpleParameters(parameters: readonly ts.ParameterDeclaration[]): readonly ts.ParameterDeclaration[] { + return ts.filter(parameters, parameter => !!parameter.initializer || ts.isBindingPattern(parameter.name) || ts.isRestParameter(parameter)); } - function checkGrammarForUseStrictSimpleParameterList(node: FunctionLikeDeclaration): boolean { - if (languageVersion >= ScriptTarget.ES2016) { - const useStrictDirective = node.body && isBlock(node.body) && findUseStrictPrologue(node.body.statements); + function checkGrammarForUseStrictSimpleParameterList(node: ts.FunctionLikeDeclaration): boolean { + if (languageVersion >= ts.ScriptTarget.ES2016) { + const useStrictDirective = node.body && ts.isBlock(node.body) && ts.findUseStrictPrologue(node.body.statements); if (useStrictDirective) { const nonSimpleParameters = getNonSimpleParameters(node.parameters); - if (length(nonSimpleParameters)) { - forEach(nonSimpleParameters, parameter => { - addRelatedInfo( - error(parameter, Diagnostics.This_parameter_is_not_allowed_with_use_strict_directive), - createDiagnosticForNode(useStrictDirective, Diagnostics.use_strict_directive_used_here) - ); + if (ts.length(nonSimpleParameters)) { + ts.forEach(nonSimpleParameters, parameter => { + ts.addRelatedInfo(error(parameter, ts.Diagnostics.This_parameter_is_not_allowed_with_use_strict_directive), ts.createDiagnosticForNode(useStrictDirective, ts.Diagnostics.use_strict_directive_used_here)); }); - const diagnostics = nonSimpleParameters.map((parameter, index) => ( - index === 0 ? createDiagnosticForNode(parameter, Diagnostics.Non_simple_parameter_declared_here) : createDiagnosticForNode(parameter, Diagnostics.and_here) - )) as [DiagnosticWithLocation, ...DiagnosticWithLocation[]]; - addRelatedInfo(error(useStrictDirective, Diagnostics.use_strict_directive_cannot_be_used_with_non_simple_parameter_list), ...diagnostics); + const diagnostics = nonSimpleParameters.map((parameter, index) => (index === 0 ? ts.createDiagnosticForNode(parameter, ts.Diagnostics.Non_simple_parameter_declared_here) : ts.createDiagnosticForNode(parameter, ts.Diagnostics.and_here))) as [ + ts.DiagnosticWithLocation, + ...ts.DiagnosticWithLocation[] + ]; + ts.addRelatedInfo(error(useStrictDirective, ts.Diagnostics.use_strict_directive_cannot_be_used_with_non_simple_parameter_list), ...diagnostics); return true; } } @@ -43883,149 +42975,149 @@ namespace ts { return false; } - function checkGrammarFunctionLikeDeclaration(node: FunctionLikeDeclaration | MethodSignature): boolean { + function checkGrammarFunctionLikeDeclaration(node: ts.FunctionLikeDeclaration | ts.MethodSignature): boolean { // Prevent cascading error by short-circuit - const file = getSourceFileOfNode(node); + const file = ts.getSourceFileOfNode(node); return checkGrammarDecoratorsAndModifiers(node) || checkGrammarTypeParameterList(node.typeParameters, file) || checkGrammarParameterList(node.parameters) || checkGrammarArrowFunction(node, file) || - (isFunctionLikeDeclaration(node) && checkGrammarForUseStrictSimpleParameterList(node)); + (ts.isFunctionLikeDeclaration(node) && checkGrammarForUseStrictSimpleParameterList(node)); } - function checkGrammarClassLikeDeclaration(node: ClassLikeDeclaration): boolean { - const file = getSourceFileOfNode(node); + function checkGrammarClassLikeDeclaration(node: ts.ClassLikeDeclaration): boolean { + const file = ts.getSourceFileOfNode(node); return checkGrammarClassDeclarationHeritageClauses(node) || checkGrammarTypeParameterList(node.typeParameters, file); } - function checkGrammarArrowFunction(node: Node, file: SourceFile): boolean { - if (!isArrowFunction(node)) { + function checkGrammarArrowFunction(node: ts.Node, file: ts.SourceFile): boolean { + if (!ts.isArrowFunction(node)) { return false; } - if (node.typeParameters && !(length(node.typeParameters) > 1 || node.typeParameters.hasTrailingComma || node.typeParameters[0].constraint)) { - if (file && fileExtensionIsOneOf(file.fileName, [Extension.Mts, Extension.Cts])) { - grammarErrorOnNode(node.typeParameters[0], Diagnostics.This_syntax_is_reserved_in_files_with_the_mts_or_cts_extension_Add_a_trailing_comma_or_explicit_constraint); + if (node.typeParameters && !(ts.length(node.typeParameters) > 1 || node.typeParameters.hasTrailingComma || node.typeParameters[0].constraint)) { + if (file && ts.fileExtensionIsOneOf(file.fileName, [ts.Extension.Mts, ts.Extension.Cts])) { + grammarErrorOnNode(node.typeParameters[0], ts.Diagnostics.This_syntax_is_reserved_in_files_with_the_mts_or_cts_extension_Add_a_trailing_comma_or_explicit_constraint); } } const { equalsGreaterThanToken } = node; - const startLine = getLineAndCharacterOfPosition(file, equalsGreaterThanToken.pos).line; - const endLine = getLineAndCharacterOfPosition(file, equalsGreaterThanToken.end).line; - return startLine !== endLine && grammarErrorOnNode(equalsGreaterThanToken, Diagnostics.Line_terminator_not_permitted_before_arrow); + const startLine = ts.getLineAndCharacterOfPosition(file, equalsGreaterThanToken.pos).line; + const endLine = ts.getLineAndCharacterOfPosition(file, equalsGreaterThanToken.end).line; + return startLine !== endLine && grammarErrorOnNode(equalsGreaterThanToken, ts.Diagnostics.Line_terminator_not_permitted_before_arrow); } - function checkGrammarIndexSignatureParameters(node: SignatureDeclaration): boolean { + function checkGrammarIndexSignatureParameters(node: ts.SignatureDeclaration): boolean { const parameter = node.parameters[0]; if (node.parameters.length !== 1) { if (parameter) { - return grammarErrorOnNode(parameter.name, Diagnostics.An_index_signature_must_have_exactly_one_parameter); + return grammarErrorOnNode(parameter.name, ts.Diagnostics.An_index_signature_must_have_exactly_one_parameter); } else { - return grammarErrorOnNode(node, Diagnostics.An_index_signature_must_have_exactly_one_parameter); + return grammarErrorOnNode(node, ts.Diagnostics.An_index_signature_must_have_exactly_one_parameter); } } - checkGrammarForDisallowedTrailingComma(node.parameters, Diagnostics.An_index_signature_cannot_have_a_trailing_comma); + checkGrammarForDisallowedTrailingComma(node.parameters, ts.Diagnostics.An_index_signature_cannot_have_a_trailing_comma); if (parameter.dotDotDotToken) { - return grammarErrorOnNode(parameter.dotDotDotToken, Diagnostics.An_index_signature_cannot_have_a_rest_parameter); + return grammarErrorOnNode(parameter.dotDotDotToken, ts.Diagnostics.An_index_signature_cannot_have_a_rest_parameter); } - if (hasEffectiveModifiers(parameter)) { - return grammarErrorOnNode(parameter.name, Diagnostics.An_index_signature_parameter_cannot_have_an_accessibility_modifier); + if (ts.hasEffectiveModifiers(parameter)) { + return grammarErrorOnNode(parameter.name, ts.Diagnostics.An_index_signature_parameter_cannot_have_an_accessibility_modifier); } if (parameter.questionToken) { - return grammarErrorOnNode(parameter.questionToken, Diagnostics.An_index_signature_parameter_cannot_have_a_question_mark); + return grammarErrorOnNode(parameter.questionToken, ts.Diagnostics.An_index_signature_parameter_cannot_have_a_question_mark); } if (parameter.initializer) { - return grammarErrorOnNode(parameter.name, Diagnostics.An_index_signature_parameter_cannot_have_an_initializer); + return grammarErrorOnNode(parameter.name, ts.Diagnostics.An_index_signature_parameter_cannot_have_an_initializer); } if (!parameter.type) { - return grammarErrorOnNode(parameter.name, Diagnostics.An_index_signature_parameter_must_have_a_type_annotation); + return grammarErrorOnNode(parameter.name, ts.Diagnostics.An_index_signature_parameter_must_have_a_type_annotation); } const type = getTypeFromTypeNode(parameter.type); - if (someType(type, t => !!(t.flags & TypeFlags.StringOrNumberLiteralOrUnique)) || isGenericType(type)) { - return grammarErrorOnNode(parameter.name, Diagnostics.An_index_signature_parameter_type_cannot_be_a_literal_type_or_generic_type_Consider_using_a_mapped_object_type_instead); + if (someType(type, t => !!(t.flags & ts.TypeFlags.StringOrNumberLiteralOrUnique)) || isGenericType(type)) { + return grammarErrorOnNode(parameter.name, ts.Diagnostics.An_index_signature_parameter_type_cannot_be_a_literal_type_or_generic_type_Consider_using_a_mapped_object_type_instead); } if (!everyType(type, isValidIndexKeyType)) { - return grammarErrorOnNode(parameter.name, Diagnostics.An_index_signature_parameter_type_must_be_string_number_symbol_or_a_template_literal_type); + return grammarErrorOnNode(parameter.name, ts.Diagnostics.An_index_signature_parameter_type_must_be_string_number_symbol_or_a_template_literal_type); } if (!node.type) { - return grammarErrorOnNode(node, Diagnostics.An_index_signature_must_have_a_type_annotation); + return grammarErrorOnNode(node, ts.Diagnostics.An_index_signature_must_have_a_type_annotation); } return false; } - function checkGrammarIndexSignature(node: SignatureDeclaration) { + function checkGrammarIndexSignature(node: ts.SignatureDeclaration) { // Prevent cascading error by short-circuit return checkGrammarDecoratorsAndModifiers(node) || checkGrammarIndexSignatureParameters(node); } - function checkGrammarForAtLeastOneTypeArgument(node: Node, typeArguments: NodeArray | undefined): boolean { + function checkGrammarForAtLeastOneTypeArgument(node: ts.Node, typeArguments: ts.NodeArray | undefined): boolean { if (typeArguments && typeArguments.length === 0) { - const sourceFile = getSourceFileOfNode(node); + const sourceFile = ts.getSourceFileOfNode(node); const start = typeArguments.pos - "<".length; - const end = skipTrivia(sourceFile.text, typeArguments.end) + ">".length; - return grammarErrorAtPos(sourceFile, start, end - start, Diagnostics.Type_argument_list_cannot_be_empty); + const end = ts.skipTrivia(sourceFile.text, typeArguments.end) + ">".length; + return grammarErrorAtPos(sourceFile, start, end - start, ts.Diagnostics.Type_argument_list_cannot_be_empty); } return false; } - function checkGrammarTypeArguments(node: Node, typeArguments: NodeArray | undefined): boolean { + function checkGrammarTypeArguments(node: ts.Node, typeArguments: ts.NodeArray | undefined): boolean { return checkGrammarForDisallowedTrailingComma(typeArguments) || checkGrammarForAtLeastOneTypeArgument(node, typeArguments); } - function checkGrammarTaggedTemplateChain(node: TaggedTemplateExpression): boolean { - if (node.questionDotToken || node.flags & NodeFlags.OptionalChain) { - return grammarErrorOnNode(node.template, Diagnostics.Tagged_template_expressions_are_not_permitted_in_an_optional_chain); + function checkGrammarTaggedTemplateChain(node: ts.TaggedTemplateExpression): boolean { + if (node.questionDotToken || node.flags & ts.NodeFlags.OptionalChain) { + return grammarErrorOnNode(node.template, ts.Diagnostics.Tagged_template_expressions_are_not_permitted_in_an_optional_chain); } return false; } - function checkGrammarHeritageClause(node: HeritageClause): boolean { + function checkGrammarHeritageClause(node: ts.HeritageClause): boolean { const types = node.types; if (checkGrammarForDisallowedTrailingComma(types)) { return true; } if (types && types.length === 0) { - const listType = tokenToString(node.token); - return grammarErrorAtPos(node, types.pos, 0, Diagnostics._0_list_cannot_be_empty, listType); + const listType = ts.tokenToString(node.token); + return grammarErrorAtPos(node, types.pos, 0, ts.Diagnostics._0_list_cannot_be_empty, listType); } - return some(types, checkGrammarExpressionWithTypeArguments); + return ts.some(types, checkGrammarExpressionWithTypeArguments); } - function checkGrammarExpressionWithTypeArguments(node: ExpressionWithTypeArguments | TypeQueryNode) { - if (isExpressionWithTypeArguments(node) && isImportKeyword(node.expression) && node.typeArguments) { - return grammarErrorOnNode(node, Diagnostics.This_use_of_import_is_invalid_import_calls_can_be_written_but_they_must_have_parentheses_and_cannot_have_type_arguments); + function checkGrammarExpressionWithTypeArguments(node: ts.ExpressionWithTypeArguments | ts.TypeQueryNode) { + if (ts.isExpressionWithTypeArguments(node) && ts.isImportKeyword(node.expression) && node.typeArguments) { + return grammarErrorOnNode(node, ts.Diagnostics.This_use_of_import_is_invalid_import_calls_can_be_written_but_they_must_have_parentheses_and_cannot_have_type_arguments); } return checkGrammarTypeArguments(node, node.typeArguments); } - function checkGrammarClassDeclarationHeritageClauses(node: ClassLikeDeclaration) { + function checkGrammarClassDeclarationHeritageClauses(node: ts.ClassLikeDeclaration) { let seenExtendsClause = false; let seenImplementsClause = false; if (!checkGrammarDecoratorsAndModifiers(node) && node.heritageClauses) { for (const heritageClause of node.heritageClauses) { - if (heritageClause.token === SyntaxKind.ExtendsKeyword) { + if (heritageClause.token === ts.SyntaxKind.ExtendsKeyword) { if (seenExtendsClause) { - return grammarErrorOnFirstToken(heritageClause, Diagnostics.extends_clause_already_seen); + return grammarErrorOnFirstToken(heritageClause, ts.Diagnostics.extends_clause_already_seen); } if (seenImplementsClause) { - return grammarErrorOnFirstToken(heritageClause, Diagnostics.extends_clause_must_precede_implements_clause); + return grammarErrorOnFirstToken(heritageClause, ts.Diagnostics.extends_clause_must_precede_implements_clause); } if (heritageClause.types.length > 1) { - return grammarErrorOnFirstToken(heritageClause.types[1], Diagnostics.Classes_can_only_extend_a_single_class); + return grammarErrorOnFirstToken(heritageClause.types[1], ts.Diagnostics.Classes_can_only_extend_a_single_class); } seenExtendsClause = true; } else { - Debug.assert(heritageClause.token === SyntaxKind.ImplementsKeyword); + ts.Debug.assert(heritageClause.token === ts.SyntaxKind.ImplementsKeyword); if (seenImplementsClause) { - return grammarErrorOnFirstToken(heritageClause, Diagnostics.implements_clause_already_seen); + return grammarErrorOnFirstToken(heritageClause, ts.Diagnostics.implements_clause_already_seen); } seenImplementsClause = true; @@ -44037,21 +43129,21 @@ namespace ts { } } - function checkGrammarInterfaceDeclaration(node: InterfaceDeclaration) { + function checkGrammarInterfaceDeclaration(node: ts.InterfaceDeclaration) { let seenExtendsClause = false; if (node.heritageClauses) { for (const heritageClause of node.heritageClauses) { - if (heritageClause.token === SyntaxKind.ExtendsKeyword) { + if (heritageClause.token === ts.SyntaxKind.ExtendsKeyword) { if (seenExtendsClause) { - return grammarErrorOnFirstToken(heritageClause, Diagnostics.extends_clause_already_seen); + return grammarErrorOnFirstToken(heritageClause, ts.Diagnostics.extends_clause_already_seen); } seenExtendsClause = true; } else { - Debug.assert(heritageClause.token === SyntaxKind.ImplementsKeyword); - return grammarErrorOnFirstToken(heritageClause, Diagnostics.Interface_declaration_cannot_have_implements_clause); + ts.Debug.assert(heritageClause.token === ts.SyntaxKind.ImplementsKeyword); + return grammarErrorOnFirstToken(heritageClause, ts.Diagnostics.Interface_declaration_cannot_have_implements_clause); } // Grammar checking heritageClause inside class declaration @@ -44061,77 +43153,76 @@ namespace ts { return false; } - function checkGrammarComputedPropertyName(node: Node): boolean { + function checkGrammarComputedPropertyName(node: ts.Node): boolean { // If node is not a computedPropertyName, just skip the grammar checking - if (node.kind !== SyntaxKind.ComputedPropertyName) { + if (node.kind !== ts.SyntaxKind.ComputedPropertyName) { return false; } - const computedPropertyName = node as ComputedPropertyName; - if (computedPropertyName.expression.kind === SyntaxKind.BinaryExpression && (computedPropertyName.expression as BinaryExpression).operatorToken.kind === SyntaxKind.CommaToken) { - return grammarErrorOnNode(computedPropertyName.expression, Diagnostics.A_comma_expression_is_not_allowed_in_a_computed_property_name); + const computedPropertyName = node as ts.ComputedPropertyName; + if (computedPropertyName.expression.kind === ts.SyntaxKind.BinaryExpression && (computedPropertyName.expression as ts.BinaryExpression).operatorToken.kind === ts.SyntaxKind.CommaToken) { + return grammarErrorOnNode(computedPropertyName.expression, ts.Diagnostics.A_comma_expression_is_not_allowed_in_a_computed_property_name); } return false; } - function checkGrammarForGenerator(node: FunctionLikeDeclaration) { + function checkGrammarForGenerator(node: ts.FunctionLikeDeclaration) { if (node.asteriskToken) { - Debug.assert( - node.kind === SyntaxKind.FunctionDeclaration || - node.kind === SyntaxKind.FunctionExpression || - node.kind === SyntaxKind.MethodDeclaration); - if (node.flags & NodeFlags.Ambient) { - return grammarErrorOnNode(node.asteriskToken, Diagnostics.Generators_are_not_allowed_in_an_ambient_context); + ts.Debug.assert(node.kind === ts.SyntaxKind.FunctionDeclaration || + node.kind === ts.SyntaxKind.FunctionExpression || + node.kind === ts.SyntaxKind.MethodDeclaration); + if (node.flags & ts.NodeFlags.Ambient) { + return grammarErrorOnNode(node.asteriskToken, ts.Diagnostics.Generators_are_not_allowed_in_an_ambient_context); } if (!node.body) { - return grammarErrorOnNode(node.asteriskToken, Diagnostics.An_overload_signature_cannot_be_declared_as_a_generator); + return grammarErrorOnNode(node.asteriskToken, ts.Diagnostics.An_overload_signature_cannot_be_declared_as_a_generator); } } } - function checkGrammarForInvalidQuestionMark(questionToken: QuestionToken | undefined, message: DiagnosticMessage): boolean { + function checkGrammarForInvalidQuestionMark(questionToken: ts.QuestionToken | undefined, message: ts.DiagnosticMessage): boolean { return !!questionToken && grammarErrorOnNode(questionToken, message); } - function checkGrammarForInvalidExclamationToken(exclamationToken: ExclamationToken | undefined, message: DiagnosticMessage): boolean { + function checkGrammarForInvalidExclamationToken(exclamationToken: ts.ExclamationToken | undefined, message: ts.DiagnosticMessage): boolean { return !!exclamationToken && grammarErrorOnNode(exclamationToken, message); } - function checkGrammarObjectLiteralExpression(node: ObjectLiteralExpression, inDestructuring: boolean) { - const seen = new Map<__String, DeclarationMeaning>(); + function checkGrammarObjectLiteralExpression(node: ts.ObjectLiteralExpression, inDestructuring: boolean) { + const seen = new ts.Map(); for (const prop of node.properties) { - if (prop.kind === SyntaxKind.SpreadAssignment) { + if (prop.kind === ts.SyntaxKind.SpreadAssignment) { if (inDestructuring) { // a rest property cannot be destructured any further - const expression = skipParentheses(prop.expression); - if (isArrayLiteralExpression(expression) || isObjectLiteralExpression(expression)) { - return grammarErrorOnNode(prop.expression, Diagnostics.A_rest_element_cannot_contain_a_binding_pattern); + const expression = ts.skipParentheses(prop.expression); + if (ts.isArrayLiteralExpression(expression) || ts.isObjectLiteralExpression(expression)) { + return grammarErrorOnNode(prop.expression, ts.Diagnostics.A_rest_element_cannot_contain_a_binding_pattern); } } continue; } const name = prop.name; - if (name.kind === SyntaxKind.ComputedPropertyName) { + if (name.kind === ts.SyntaxKind.ComputedPropertyName) { // If the name is not a ComputedPropertyName, the grammar checking will skip it checkGrammarComputedPropertyName(name); } - if (prop.kind === SyntaxKind.ShorthandPropertyAssignment && !inDestructuring && prop.objectAssignmentInitializer) { + if (prop.kind === ts.SyntaxKind.ShorthandPropertyAssignment && !inDestructuring && prop.objectAssignmentInitializer) { // having objectAssignmentInitializer is only valid in ObjectAssignmentPattern // outside of destructuring it is a syntax error - grammarErrorOnNode(prop.equalsToken!, Diagnostics.Did_you_mean_to_use_a_Colon_An_can_only_follow_a_property_name_when_the_containing_object_literal_is_part_of_a_destructuring_pattern); + grammarErrorOnNode(prop.equalsToken!, ts.Diagnostics.Did_you_mean_to_use_a_Colon_An_can_only_follow_a_property_name_when_the_containing_object_literal_is_part_of_a_destructuring_pattern); } - if (name.kind === SyntaxKind.PrivateIdentifier) { - grammarErrorOnNode(name, Diagnostics.Private_identifiers_are_not_allowed_outside_class_bodies); + if (name.kind === ts.SyntaxKind.PrivateIdentifier) { + grammarErrorOnNode(name, ts.Diagnostics.Private_identifiers_are_not_allowed_outside_class_bodies); } // Modifiers are never allowed on properties except for 'async' on a method declaration if (prop.modifiers) { for (const mod of prop.modifiers) { - if (mod.kind !== SyntaxKind.AsyncKeyword || prop.kind !== SyntaxKind.MethodDeclaration) { - grammarErrorOnNode(mod, Diagnostics._0_modifier_cannot_be_used_here, getTextOfNode(mod)); + if (mod.kind !== ts.SyntaxKind.AsyncKeyword || prop.kind !== ts.SyntaxKind.MethodDeclaration) { + grammarErrorOnNode(mod, ts.Diagnostics._0_modifier_cannot_be_used_here, ts.getTextOfNode(mod)); } } } @@ -44146,32 +43237,32 @@ namespace ts { // and either both previous and propId.descriptor have[[Get]] fields or both previous and propId.descriptor have[[Set]] fields let currentKind: DeclarationMeaning; switch (prop.kind) { - case SyntaxKind.ShorthandPropertyAssignment: - checkGrammarForInvalidExclamationToken(prop.exclamationToken, Diagnostics.A_definite_assignment_assertion_is_not_permitted_in_this_context); + case ts.SyntaxKind.ShorthandPropertyAssignment: + checkGrammarForInvalidExclamationToken(prop.exclamationToken, ts.Diagnostics.A_definite_assignment_assertion_is_not_permitted_in_this_context); // falls through - case SyntaxKind.PropertyAssignment: + case ts.SyntaxKind.PropertyAssignment: // Grammar checking for computedPropertyName and shorthandPropertyAssignment - checkGrammarForInvalidQuestionMark(prop.questionToken, Diagnostics.An_object_member_cannot_be_declared_optional); - if (name.kind === SyntaxKind.NumericLiteral) { + checkGrammarForInvalidQuestionMark(prop.questionToken, ts.Diagnostics.An_object_member_cannot_be_declared_optional); + if (name.kind === ts.SyntaxKind.NumericLiteral) { checkGrammarNumericLiteral(name); } currentKind = DeclarationMeaning.PropertyAssignment; break; - case SyntaxKind.MethodDeclaration: + case ts.SyntaxKind.MethodDeclaration: currentKind = DeclarationMeaning.Method; break; - case SyntaxKind.GetAccessor: + case ts.SyntaxKind.GetAccessor: currentKind = DeclarationMeaning.GetAccessor; break; - case SyntaxKind.SetAccessor: + case ts.SyntaxKind.SetAccessor: currentKind = DeclarationMeaning.SetAccessor; break; default: - throw Debug.assertNever(prop, "Unexpected syntax kind:" + (prop as Node).kind); + throw ts.Debug.assertNever(prop, "Unexpected syntax kind:" + (prop as ts.Node).kind); } if (!inDestructuring) { - const effectiveName = getPropertyNameForPropertyNameNode(name); + const effectiveName = ts.getPropertyNameForPropertyNameNode(name); if (effectiveName === undefined) { continue; } @@ -44182,34 +43273,34 @@ namespace ts { } else { if ((currentKind & DeclarationMeaning.Method) && (existingKind & DeclarationMeaning.Method)) { - grammarErrorOnNode(name, Diagnostics.Duplicate_identifier_0, getTextOfNode(name)); + grammarErrorOnNode(name, ts.Diagnostics.Duplicate_identifier_0, ts.getTextOfNode(name)); } else if ((currentKind & DeclarationMeaning.PropertyAssignment) && (existingKind & DeclarationMeaning.PropertyAssignment)) { - grammarErrorOnNode(name, Diagnostics.An_object_literal_cannot_have_multiple_properties_with_the_same_name, getTextOfNode(name)); + grammarErrorOnNode(name, ts.Diagnostics.An_object_literal_cannot_have_multiple_properties_with_the_same_name, ts.getTextOfNode(name)); } else if ((currentKind & DeclarationMeaning.GetOrSetAccessor) && (existingKind & DeclarationMeaning.GetOrSetAccessor)) { if (existingKind !== DeclarationMeaning.GetOrSetAccessor && currentKind !== existingKind) { seen.set(effectiveName, currentKind | existingKind); } else { - return grammarErrorOnNode(name, Diagnostics.An_object_literal_cannot_have_multiple_get_Slashset_accessors_with_the_same_name); + return grammarErrorOnNode(name, ts.Diagnostics.An_object_literal_cannot_have_multiple_get_Slashset_accessors_with_the_same_name); } } else { - return grammarErrorOnNode(name, Diagnostics.An_object_literal_cannot_have_property_and_accessor_with_the_same_name); + return grammarErrorOnNode(name, ts.Diagnostics.An_object_literal_cannot_have_property_and_accessor_with_the_same_name); } } } } } - function checkGrammarJsxElement(node: JsxOpeningLikeElement) { + function checkGrammarJsxElement(node: ts.JsxOpeningLikeElement) { checkGrammarJsxName(node.tagName); checkGrammarTypeArguments(node, node.typeArguments); - const seen = new Map<__String, boolean>(); + const seen = new ts.Map(); for (const attr of node.attributes.properties) { - if (attr.kind === SyntaxKind.JsxSpreadAttribute) { + if (attr.kind === ts.SyntaxKind.JsxSpreadAttribute) { continue; } @@ -44218,81 +43309,74 @@ namespace ts { seen.set(name.escapedText, true); } else { - return grammarErrorOnNode(name, Diagnostics.JSX_elements_cannot_have_multiple_attributes_with_the_same_name); + return grammarErrorOnNode(name, ts.Diagnostics.JSX_elements_cannot_have_multiple_attributes_with_the_same_name); } - if (initializer && initializer.kind === SyntaxKind.JsxExpression && !initializer.expression) { - return grammarErrorOnNode(initializer, Diagnostics.JSX_attributes_must_only_be_assigned_a_non_empty_expression); + if (initializer && initializer.kind === ts.SyntaxKind.JsxExpression && !initializer.expression) { + return grammarErrorOnNode(initializer, ts.Diagnostics.JSX_attributes_must_only_be_assigned_a_non_empty_expression); } } } - function checkGrammarJsxName(node: JsxTagNameExpression) { - if (isPropertyAccessExpression(node)) { - let propName: JsxTagNameExpression = node; + function checkGrammarJsxName(node: ts.JsxTagNameExpression) { + if (ts.isPropertyAccessExpression(node)) { + let propName: ts.JsxTagNameExpression = node; do { const check = checkGrammarJsxNestedIdentifier(propName.name); if (check) { return check; } propName = propName.expression; - } while (isPropertyAccessExpression(propName)); + } while (ts.isPropertyAccessExpression(propName)); const check = checkGrammarJsxNestedIdentifier(propName); if (check) { return check; } } - function checkGrammarJsxNestedIdentifier(name: MemberName | ThisExpression) { - if (isIdentifier(name) && idText(name).indexOf(":") !== -1) { - return grammarErrorOnNode(name, Diagnostics.JSX_property_access_expressions_cannot_include_JSX_namespace_names); + function checkGrammarJsxNestedIdentifier(name: ts.MemberName | ts.ThisExpression) { + if (ts.isIdentifier(name) && ts.idText(name).indexOf(":") !== -1) { + return grammarErrorOnNode(name, ts.Diagnostics.JSX_property_access_expressions_cannot_include_JSX_namespace_names); } } } - function checkGrammarJsxExpression(node: JsxExpression) { - if (node.expression && isCommaSequence(node.expression)) { - return grammarErrorOnNode(node.expression, Diagnostics.JSX_expressions_may_not_use_the_comma_operator_Did_you_mean_to_write_an_array); + function checkGrammarJsxExpression(node: ts.JsxExpression) { + if (node.expression && ts.isCommaSequence(node.expression)) { + return grammarErrorOnNode(node.expression, ts.Diagnostics.JSX_expressions_may_not_use_the_comma_operator_Did_you_mean_to_write_an_array); } } - function checkGrammarForInOrForOfStatement(forInOrOfStatement: ForInOrOfStatement): boolean { + function checkGrammarForInOrForOfStatement(forInOrOfStatement: ts.ForInOrOfStatement): boolean { if (checkGrammarStatementInAmbientContext(forInOrOfStatement)) { return true; } - if (forInOrOfStatement.kind === SyntaxKind.ForOfStatement && forInOrOfStatement.awaitModifier) { - if (!(forInOrOfStatement.flags & NodeFlags.AwaitContext)) { - const sourceFile = getSourceFileOfNode(forInOrOfStatement); - if (isInTopLevelContext(forInOrOfStatement)) { + if (forInOrOfStatement.kind === ts.SyntaxKind.ForOfStatement && forInOrOfStatement.awaitModifier) { + if (!(forInOrOfStatement.flags & ts.NodeFlags.AwaitContext)) { + const sourceFile = ts.getSourceFileOfNode(forInOrOfStatement); + if (ts.isInTopLevelContext(forInOrOfStatement)) { if (!hasParseDiagnostics(sourceFile)) { - if (!isEffectiveExternalModule(sourceFile, compilerOptions)) { - diagnostics.add(createDiagnosticForNode(forInOrOfStatement.awaitModifier, - Diagnostics.for_await_loops_are_only_allowed_at_the_top_level_of_a_file_when_that_file_is_a_module_but_this_file_has_no_imports_or_exports_Consider_adding_an_empty_export_to_make_this_file_a_module)); + if (!ts.isEffectiveExternalModule(sourceFile, compilerOptions)) { + diagnostics.add(ts.createDiagnosticForNode(forInOrOfStatement.awaitModifier, ts.Diagnostics.for_await_loops_are_only_allowed_at_the_top_level_of_a_file_when_that_file_is_a_module_but_this_file_has_no_imports_or_exports_Consider_adding_an_empty_export_to_make_this_file_a_module)); } switch (moduleKind) { - case ModuleKind.Node16: - case ModuleKind.NodeNext: - if (sourceFile.impliedNodeFormat === ModuleKind.CommonJS) { - diagnostics.add( - createDiagnosticForNode(forInOrOfStatement.awaitModifier, Diagnostics.The_current_file_is_a_CommonJS_module_and_cannot_use_await_at_the_top_level) - ); + case ts.ModuleKind.Node16: + case ts.ModuleKind.NodeNext: + if (sourceFile.impliedNodeFormat === ts.ModuleKind.CommonJS) { + diagnostics.add(ts.createDiagnosticForNode(forInOrOfStatement.awaitModifier, ts.Diagnostics.The_current_file_is_a_CommonJS_module_and_cannot_use_await_at_the_top_level)); break; } // fallthrough - case ModuleKind.ES2022: - case ModuleKind.ESNext: - case ModuleKind.System: - if (languageVersion >= ScriptTarget.ES2017) { + case ts.ModuleKind.ES2022: + case ts.ModuleKind.ESNext: + case ts.ModuleKind.System: + if (languageVersion >= ts.ScriptTarget.ES2017) { break; } // fallthrough default: - diagnostics.add( - createDiagnosticForNode(forInOrOfStatement.awaitModifier, - Diagnostics.Top_level_for_await_loops_are_only_allowed_when_the_module_option_is_set_to_es2022_esnext_system_node16_or_nodenext_and_the_target_option_is_set_to_es2017_or_higher - ) - ); + diagnostics.add(ts.createDiagnosticForNode(forInOrOfStatement.awaitModifier, ts.Diagnostics.Top_level_for_await_loops_are_only_allowed_when_the_module_option_is_set_to_es2022_esnext_system_node16_or_nodenext_and_the_target_option_is_set_to_es2017_or_higher)); break; } } @@ -44300,12 +43384,12 @@ namespace ts { else { // use of 'for-await-of' in non-async function if (!hasParseDiagnostics(sourceFile)) { - const diagnostic = createDiagnosticForNode(forInOrOfStatement.awaitModifier, Diagnostics.for_await_loops_are_only_allowed_within_async_functions_and_at_the_top_levels_of_modules); - const func = getContainingFunction(forInOrOfStatement); - if (func && func.kind !== SyntaxKind.Constructor) { - Debug.assert((getFunctionFlags(func) & FunctionFlags.Async) === 0, "Enclosing function should never be an async function."); - const relatedInfo = createDiagnosticForNode(func, Diagnostics.Did_you_mean_to_mark_this_function_as_async); - addRelatedInfo(diagnostic, relatedInfo); + const diagnostic = ts.createDiagnosticForNode(forInOrOfStatement.awaitModifier, ts.Diagnostics.for_await_loops_are_only_allowed_within_async_functions_and_at_the_top_levels_of_modules); + const func = ts.getContainingFunction(forInOrOfStatement); + if (func && func.kind !== ts.SyntaxKind.Constructor) { + ts.Debug.assert((ts.getFunctionFlags(func) & ts.FunctionFlags.Async) === 0, "Enclosing function should never be an async function."); + const relatedInfo = ts.createDiagnosticForNode(func, ts.Diagnostics.Did_you_mean_to_mark_this_function_as_async); + ts.addRelatedInfo(diagnostic, relatedInfo); } diagnostics.add(diagnostic); return true; @@ -44315,14 +43399,14 @@ namespace ts { } } - if (isForOfStatement(forInOrOfStatement) && !(forInOrOfStatement.flags & NodeFlags.AwaitContext) && - isIdentifier(forInOrOfStatement.initializer) && forInOrOfStatement.initializer.escapedText === "async") { - grammarErrorOnNode(forInOrOfStatement.initializer, Diagnostics.The_left_hand_side_of_a_for_of_statement_may_not_be_async); + if (ts.isForOfStatement(forInOrOfStatement) && !(forInOrOfStatement.flags & ts.NodeFlags.AwaitContext) && + ts.isIdentifier(forInOrOfStatement.initializer) && forInOrOfStatement.initializer.escapedText === "async") { + grammarErrorOnNode(forInOrOfStatement.initializer, ts.Diagnostics.The_left_hand_side_of_a_for_of_statement_may_not_be_async); return false; } - if (forInOrOfStatement.initializer.kind === SyntaxKind.VariableDeclarationList) { - const variableList = forInOrOfStatement.initializer as VariableDeclarationList; + if (forInOrOfStatement.initializer.kind === ts.SyntaxKind.VariableDeclarationList) { + const variableList = forInOrOfStatement.initializer as ts.VariableDeclarationList; if (!checkGrammarVariableDeclarationList(variableList)) { const declarations = variableList.declarations; @@ -44338,23 +43422,23 @@ namespace ts { } if (declarations.length > 1) { - const diagnostic = forInOrOfStatement.kind === SyntaxKind.ForInStatement - ? Diagnostics.Only_a_single_variable_declaration_is_allowed_in_a_for_in_statement - : Diagnostics.Only_a_single_variable_declaration_is_allowed_in_a_for_of_statement; + const diagnostic = forInOrOfStatement.kind === ts.SyntaxKind.ForInStatement + ? ts.Diagnostics.Only_a_single_variable_declaration_is_allowed_in_a_for_in_statement + : ts.Diagnostics.Only_a_single_variable_declaration_is_allowed_in_a_for_of_statement; return grammarErrorOnFirstToken(variableList.declarations[1], diagnostic); } const firstDeclaration = declarations[0]; if (firstDeclaration.initializer) { - const diagnostic = forInOrOfStatement.kind === SyntaxKind.ForInStatement - ? Diagnostics.The_variable_declaration_of_a_for_in_statement_cannot_have_an_initializer - : Diagnostics.The_variable_declaration_of_a_for_of_statement_cannot_have_an_initializer; + const diagnostic = forInOrOfStatement.kind === ts.SyntaxKind.ForInStatement + ? ts.Diagnostics.The_variable_declaration_of_a_for_in_statement_cannot_have_an_initializer + : ts.Diagnostics.The_variable_declaration_of_a_for_of_statement_cannot_have_an_initializer; return grammarErrorOnNode(firstDeclaration.name, diagnostic); } if (firstDeclaration.type) { - const diagnostic = forInOrOfStatement.kind === SyntaxKind.ForInStatement - ? Diagnostics.The_left_hand_side_of_a_for_in_statement_cannot_use_a_type_annotation - : Diagnostics.The_left_hand_side_of_a_for_of_statement_cannot_use_a_type_annotation; + const diagnostic = forInOrOfStatement.kind === ts.SyntaxKind.ForInStatement + ? ts.Diagnostics.The_left_hand_side_of_a_for_in_statement_cannot_use_a_type_annotation + : ts.Diagnostics.The_left_hand_side_of_a_for_of_statement_cannot_use_a_type_annotation; return grammarErrorOnNode(firstDeclaration, diagnostic); } } @@ -44363,48 +43447,47 @@ namespace ts { return false; } - function checkGrammarAccessor(accessor: AccessorDeclaration): boolean { - if (!(accessor.flags & NodeFlags.Ambient) && (accessor.parent.kind !== SyntaxKind.TypeLiteral) && (accessor.parent.kind !== SyntaxKind.InterfaceDeclaration)) { - if (languageVersion < ScriptTarget.ES5) { - return grammarErrorOnNode(accessor.name, Diagnostics.Accessors_are_only_available_when_targeting_ECMAScript_5_and_higher); + function checkGrammarAccessor(accessor: ts.AccessorDeclaration): boolean { + if (!(accessor.flags & ts.NodeFlags.Ambient) && (accessor.parent.kind !== ts.SyntaxKind.TypeLiteral) && (accessor.parent.kind !== ts.SyntaxKind.InterfaceDeclaration)) { + if (languageVersion < ts.ScriptTarget.ES5) { + return grammarErrorOnNode(accessor.name, ts.Diagnostics.Accessors_are_only_available_when_targeting_ECMAScript_5_and_higher); } - if (languageVersion < ScriptTarget.ES2015 && isPrivateIdentifier(accessor.name)) { - return grammarErrorOnNode(accessor.name, Diagnostics.Private_identifiers_are_only_available_when_targeting_ECMAScript_2015_and_higher); + if (languageVersion < ts.ScriptTarget.ES2015 && ts.isPrivateIdentifier(accessor.name)) { + return grammarErrorOnNode(accessor.name, ts.Diagnostics.Private_identifiers_are_only_available_when_targeting_ECMAScript_2015_and_higher); } - if (accessor.body === undefined && !hasSyntacticModifier(accessor, ModifierFlags.Abstract)) { - return grammarErrorAtPos(accessor, accessor.end - 1, ";".length, Diagnostics._0_expected, "{"); + if (accessor.body === undefined && !ts.hasSyntacticModifier(accessor, ts.ModifierFlags.Abstract)) { + return grammarErrorAtPos(accessor, accessor.end - 1, ";".length, ts.Diagnostics._0_expected, "{"); } } if (accessor.body) { - if (hasSyntacticModifier(accessor, ModifierFlags.Abstract)) { - return grammarErrorOnNode(accessor, Diagnostics.An_abstract_accessor_cannot_have_an_implementation); + if (ts.hasSyntacticModifier(accessor, ts.ModifierFlags.Abstract)) { + return grammarErrorOnNode(accessor, ts.Diagnostics.An_abstract_accessor_cannot_have_an_implementation); } - if (accessor.parent.kind === SyntaxKind.TypeLiteral || accessor.parent.kind === SyntaxKind.InterfaceDeclaration) { - return grammarErrorOnNode(accessor.body, Diagnostics.An_implementation_cannot_be_declared_in_ambient_contexts); + if (accessor.parent.kind === ts.SyntaxKind.TypeLiteral || accessor.parent.kind === ts.SyntaxKind.InterfaceDeclaration) { + return grammarErrorOnNode(accessor.body, ts.Diagnostics.An_implementation_cannot_be_declared_in_ambient_contexts); } } if (accessor.typeParameters) { - return grammarErrorOnNode(accessor.name, Diagnostics.An_accessor_cannot_have_type_parameters); + return grammarErrorOnNode(accessor.name, ts.Diagnostics.An_accessor_cannot_have_type_parameters); } if (!doesAccessorHaveCorrectParameterCount(accessor)) { - return grammarErrorOnNode(accessor.name, - accessor.kind === SyntaxKind.GetAccessor ? - Diagnostics.A_get_accessor_cannot_have_parameters : - Diagnostics.A_set_accessor_must_have_exactly_one_parameter); + return grammarErrorOnNode(accessor.name, accessor.kind === ts.SyntaxKind.GetAccessor ? + ts.Diagnostics.A_get_accessor_cannot_have_parameters : + ts.Diagnostics.A_set_accessor_must_have_exactly_one_parameter); } - if (accessor.kind === SyntaxKind.SetAccessor) { + if (accessor.kind === ts.SyntaxKind.SetAccessor) { if (accessor.type) { - return grammarErrorOnNode(accessor.name, Diagnostics.A_set_accessor_cannot_have_a_return_type_annotation); + return grammarErrorOnNode(accessor.name, ts.Diagnostics.A_set_accessor_cannot_have_a_return_type_annotation); } - const parameter = Debug.checkDefined(getSetAccessorValueParameter(accessor), "Return value does not match parameter count assertion."); + const parameter = ts.Debug.checkDefined(ts.getSetAccessorValueParameter(accessor), "Return value does not match parameter count assertion."); if (parameter.dotDotDotToken) { - return grammarErrorOnNode(parameter.dotDotDotToken, Diagnostics.A_set_accessor_cannot_have_rest_parameter); + return grammarErrorOnNode(parameter.dotDotDotToken, ts.Diagnostics.A_set_accessor_cannot_have_rest_parameter); } if (parameter.questionToken) { - return grammarErrorOnNode(parameter.questionToken, Diagnostics.A_set_accessor_cannot_have_an_optional_parameter); + return grammarErrorOnNode(parameter.questionToken, ts.Diagnostics.A_set_accessor_cannot_have_an_optional_parameter); } if (parameter.initializer) { - return grammarErrorOnNode(accessor.name, Diagnostics.A_set_accessor_parameter_cannot_have_an_initializer); + return grammarErrorOnNode(accessor.name, ts.Diagnostics.A_set_accessor_parameter_cannot_have_an_initializer); } } return false; @@ -44414,91 +43497,91 @@ namespace ts { * A get accessor has no parameters or a single `this` parameter. * A set accessor has one parameter or a `this` parameter and one more parameter. */ - function doesAccessorHaveCorrectParameterCount(accessor: AccessorDeclaration) { - return getAccessorThisParameter(accessor) || accessor.parameters.length === (accessor.kind === SyntaxKind.GetAccessor ? 0 : 1); + function doesAccessorHaveCorrectParameterCount(accessor: ts.AccessorDeclaration) { + return getAccessorThisParameter(accessor) || accessor.parameters.length === (accessor.kind === ts.SyntaxKind.GetAccessor ? 0 : 1); } - function getAccessorThisParameter(accessor: AccessorDeclaration): ParameterDeclaration | undefined { - if (accessor.parameters.length === (accessor.kind === SyntaxKind.GetAccessor ? 1 : 2)) { - return getThisParameter(accessor); + function getAccessorThisParameter(accessor: ts.AccessorDeclaration): ts.ParameterDeclaration | undefined { + if (accessor.parameters.length === (accessor.kind === ts.SyntaxKind.GetAccessor ? 1 : 2)) { + return ts.getThisParameter(accessor); } } - function checkGrammarTypeOperatorNode(node: TypeOperatorNode) { - if (node.operator === SyntaxKind.UniqueKeyword) { - if (node.type.kind !== SyntaxKind.SymbolKeyword) { - return grammarErrorOnNode(node.type, Diagnostics._0_expected, tokenToString(SyntaxKind.SymbolKeyword)); + function checkGrammarTypeOperatorNode(node: ts.TypeOperatorNode) { + if (node.operator === ts.SyntaxKind.UniqueKeyword) { + if (node.type.kind !== ts.SyntaxKind.SymbolKeyword) { + return grammarErrorOnNode(node.type, ts.Diagnostics._0_expected, ts.tokenToString(ts.SyntaxKind.SymbolKeyword)); } - let parent = walkUpParenthesizedTypes(node.parent); - if (isInJSFile(parent) && isJSDocTypeExpression(parent)) { - const host = getJSDocHost(parent); + let parent = ts.walkUpParenthesizedTypes(node.parent); + if (ts.isInJSFile(parent) && ts.isJSDocTypeExpression(parent)) { + const host = ts.getJSDocHost(parent); if (host) { - parent = getSingleVariableOfVariableStatement(host) || host; + parent = ts.getSingleVariableOfVariableStatement(host) || host; } } switch (parent.kind) { - case SyntaxKind.VariableDeclaration: - const decl = parent as VariableDeclaration; - if (decl.name.kind !== SyntaxKind.Identifier) { - return grammarErrorOnNode(node, Diagnostics.unique_symbol_types_may_not_be_used_on_a_variable_declaration_with_a_binding_name); + case ts.SyntaxKind.VariableDeclaration: + const decl = parent as ts.VariableDeclaration; + if (decl.name.kind !== ts.SyntaxKind.Identifier) { + return grammarErrorOnNode(node, ts.Diagnostics.unique_symbol_types_may_not_be_used_on_a_variable_declaration_with_a_binding_name); } - if (!isVariableDeclarationInVariableStatement(decl)) { - return grammarErrorOnNode(node, Diagnostics.unique_symbol_types_are_only_allowed_on_variables_in_a_variable_statement); + if (!ts.isVariableDeclarationInVariableStatement(decl)) { + return grammarErrorOnNode(node, ts.Diagnostics.unique_symbol_types_are_only_allowed_on_variables_in_a_variable_statement); } - if (!(decl.parent.flags & NodeFlags.Const)) { - return grammarErrorOnNode((parent as VariableDeclaration).name, Diagnostics.A_variable_whose_type_is_a_unique_symbol_type_must_be_const); + if (!(decl.parent.flags & ts.NodeFlags.Const)) { + return grammarErrorOnNode((parent as ts.VariableDeclaration).name, ts.Diagnostics.A_variable_whose_type_is_a_unique_symbol_type_must_be_const); } break; - case SyntaxKind.PropertyDeclaration: - if (!isStatic(parent) || - !hasEffectiveReadonlyModifier(parent)) { - return grammarErrorOnNode((parent as PropertyDeclaration).name, Diagnostics.A_property_of_a_class_whose_type_is_a_unique_symbol_type_must_be_both_static_and_readonly); + case ts.SyntaxKind.PropertyDeclaration: + if (!ts.isStatic(parent) || + !ts.hasEffectiveReadonlyModifier(parent)) { + return grammarErrorOnNode((parent as ts.PropertyDeclaration).name, ts.Diagnostics.A_property_of_a_class_whose_type_is_a_unique_symbol_type_must_be_both_static_and_readonly); } break; - case SyntaxKind.PropertySignature: - if (!hasSyntacticModifier(parent, ModifierFlags.Readonly)) { - return grammarErrorOnNode((parent as PropertySignature).name, Diagnostics.A_property_of_an_interface_or_type_literal_whose_type_is_a_unique_symbol_type_must_be_readonly); + case ts.SyntaxKind.PropertySignature: + if (!ts.hasSyntacticModifier(parent, ts.ModifierFlags.Readonly)) { + return grammarErrorOnNode((parent as ts.PropertySignature).name, ts.Diagnostics.A_property_of_an_interface_or_type_literal_whose_type_is_a_unique_symbol_type_must_be_readonly); } break; default: - return grammarErrorOnNode(node, Diagnostics.unique_symbol_types_are_not_allowed_here); + return grammarErrorOnNode(node, ts.Diagnostics.unique_symbol_types_are_not_allowed_here); } } - else if (node.operator === SyntaxKind.ReadonlyKeyword) { - if (node.type.kind !== SyntaxKind.ArrayType && node.type.kind !== SyntaxKind.TupleType) { - return grammarErrorOnFirstToken(node, Diagnostics.readonly_type_modifier_is_only_permitted_on_array_and_tuple_literal_types, tokenToString(SyntaxKind.SymbolKeyword)); + else if (node.operator === ts.SyntaxKind.ReadonlyKeyword) { + if (node.type.kind !== ts.SyntaxKind.ArrayType && node.type.kind !== ts.SyntaxKind.TupleType) { + return grammarErrorOnFirstToken(node, ts.Diagnostics.readonly_type_modifier_is_only_permitted_on_array_and_tuple_literal_types, ts.tokenToString(ts.SyntaxKind.SymbolKeyword)); } } } - function checkGrammarForInvalidDynamicName(node: DeclarationName, message: DiagnosticMessage) { + function checkGrammarForInvalidDynamicName(node: ts.DeclarationName, message: ts.DiagnosticMessage) { if (isNonBindableDynamicName(node)) { return grammarErrorOnNode(node, message); } } - function checkGrammarMethod(node: MethodDeclaration | MethodSignature) { + function checkGrammarMethod(node: ts.MethodDeclaration | ts.MethodSignature) { if (checkGrammarFunctionLikeDeclaration(node)) { return true; } - if (node.kind === SyntaxKind.MethodDeclaration) { - if (node.parent.kind === SyntaxKind.ObjectLiteralExpression) { + if (node.kind === ts.SyntaxKind.MethodDeclaration) { + if (node.parent.kind === ts.SyntaxKind.ObjectLiteralExpression) { // We only disallow modifier on a method declaration if it is a property of object-literal-expression - if (node.modifiers && !(node.modifiers.length === 1 && first(node.modifiers).kind === SyntaxKind.AsyncKeyword)) { - return grammarErrorOnFirstToken(node, Diagnostics.Modifiers_cannot_appear_here); + if (node.modifiers && !(node.modifiers.length === 1 && ts.first(node.modifiers).kind === ts.SyntaxKind.AsyncKeyword)) { + return grammarErrorOnFirstToken(node, ts.Diagnostics.Modifiers_cannot_appear_here); } - else if (checkGrammarForInvalidQuestionMark(node.questionToken, Diagnostics.An_object_member_cannot_be_declared_optional)) { + else if (checkGrammarForInvalidQuestionMark(node.questionToken, ts.Diagnostics.An_object_member_cannot_be_declared_optional)) { return true; } - else if (checkGrammarForInvalidExclamationToken(node.exclamationToken, Diagnostics.A_definite_assignment_assertion_is_not_permitted_in_this_context)) { + else if (checkGrammarForInvalidExclamationToken(node.exclamationToken, ts.Diagnostics.A_definite_assignment_assertion_is_not_permitted_in_this_context)) { return true; } else if (node.body === undefined) { - return grammarErrorAtPos(node, node.end - 1, ";".length, Diagnostics._0_expected, "{"); + return grammarErrorAtPos(node, node.end - 1, ";".length, ts.Diagnostics._0_expected, "{"); } } if (checkGrammarForGenerator(node)) { @@ -44506,60 +43589,60 @@ namespace ts { } } - if (isClassLike(node.parent)) { - if (languageVersion < ScriptTarget.ES2015 && isPrivateIdentifier(node.name)) { - return grammarErrorOnNode(node.name, Diagnostics.Private_identifiers_are_only_available_when_targeting_ECMAScript_2015_and_higher); + if (ts.isClassLike(node.parent)) { + if (languageVersion < ts.ScriptTarget.ES2015 && ts.isPrivateIdentifier(node.name)) { + return grammarErrorOnNode(node.name, ts.Diagnostics.Private_identifiers_are_only_available_when_targeting_ECMAScript_2015_and_higher); } // Technically, computed properties in ambient contexts is disallowed // for property declarations and accessors too, not just methods. // However, property declarations disallow computed names in general, // and accessors are not allowed in ambient contexts in general, // so this error only really matters for methods. - if (node.flags & NodeFlags.Ambient) { - return checkGrammarForInvalidDynamicName(node.name, Diagnostics.A_computed_property_name_in_an_ambient_context_must_refer_to_an_expression_whose_type_is_a_literal_type_or_a_unique_symbol_type); + if (node.flags & ts.NodeFlags.Ambient) { + return checkGrammarForInvalidDynamicName(node.name, ts.Diagnostics.A_computed_property_name_in_an_ambient_context_must_refer_to_an_expression_whose_type_is_a_literal_type_or_a_unique_symbol_type); } - else if (node.kind === SyntaxKind.MethodDeclaration && !node.body) { - return checkGrammarForInvalidDynamicName(node.name, Diagnostics.A_computed_property_name_in_a_method_overload_must_refer_to_an_expression_whose_type_is_a_literal_type_or_a_unique_symbol_type); + else if (node.kind === ts.SyntaxKind.MethodDeclaration && !node.body) { + return checkGrammarForInvalidDynamicName(node.name, ts.Diagnostics.A_computed_property_name_in_a_method_overload_must_refer_to_an_expression_whose_type_is_a_literal_type_or_a_unique_symbol_type); } } - else if (node.parent.kind === SyntaxKind.InterfaceDeclaration) { - return checkGrammarForInvalidDynamicName(node.name, Diagnostics.A_computed_property_name_in_an_interface_must_refer_to_an_expression_whose_type_is_a_literal_type_or_a_unique_symbol_type); + else if (node.parent.kind === ts.SyntaxKind.InterfaceDeclaration) { + return checkGrammarForInvalidDynamicName(node.name, ts.Diagnostics.A_computed_property_name_in_an_interface_must_refer_to_an_expression_whose_type_is_a_literal_type_or_a_unique_symbol_type); } - else if (node.parent.kind === SyntaxKind.TypeLiteral) { - return checkGrammarForInvalidDynamicName(node.name, Diagnostics.A_computed_property_name_in_a_type_literal_must_refer_to_an_expression_whose_type_is_a_literal_type_or_a_unique_symbol_type); + else if (node.parent.kind === ts.SyntaxKind.TypeLiteral) { + return checkGrammarForInvalidDynamicName(node.name, ts.Diagnostics.A_computed_property_name_in_a_type_literal_must_refer_to_an_expression_whose_type_is_a_literal_type_or_a_unique_symbol_type); } } - function checkGrammarBreakOrContinueStatement(node: BreakOrContinueStatement): boolean { - let current: Node = node; + function checkGrammarBreakOrContinueStatement(node: ts.BreakOrContinueStatement): boolean { + let current: ts.Node = node; while (current) { - if (isFunctionLikeOrClassStaticBlockDeclaration(current)) { - return grammarErrorOnNode(node, Diagnostics.Jump_target_cannot_cross_function_boundary); + if (ts.isFunctionLikeOrClassStaticBlockDeclaration(current)) { + return grammarErrorOnNode(node, ts.Diagnostics.Jump_target_cannot_cross_function_boundary); } switch (current.kind) { - case SyntaxKind.LabeledStatement: - if (node.label && (current as LabeledStatement).label.escapedText === node.label.escapedText) { + case ts.SyntaxKind.LabeledStatement: + if (node.label && (current as ts.LabeledStatement).label.escapedText === node.label.escapedText) { // found matching label - verify that label usage is correct // continue can only target labels that are on iteration statements - const isMisplacedContinueLabel = node.kind === SyntaxKind.ContinueStatement - && !isIterationStatement((current as LabeledStatement).statement, /*lookInLabeledStatement*/ true); + const isMisplacedContinueLabel = node.kind === ts.SyntaxKind.ContinueStatement + && !ts.isIterationStatement((current as ts.LabeledStatement).statement, /*lookInLabeledStatement*/ true); if (isMisplacedContinueLabel) { - return grammarErrorOnNode(node, Diagnostics.A_continue_statement_can_only_jump_to_a_label_of_an_enclosing_iteration_statement); + return grammarErrorOnNode(node, ts.Diagnostics.A_continue_statement_can_only_jump_to_a_label_of_an_enclosing_iteration_statement); } return false; } break; - case SyntaxKind.SwitchStatement: - if (node.kind === SyntaxKind.BreakStatement && !node.label) { + case ts.SyntaxKind.SwitchStatement: + if (node.kind === ts.SyntaxKind.BreakStatement && !node.label) { // unlabeled break within switch statement - ok return false; } break; default: - if (isIterationStatement(current, /*lookInLabeledStatement*/ false) && !node.label) { + if (ts.isIterationStatement(current, /*lookInLabeledStatement*/ false) && !node.label) { // unlabeled break or continue within iteration statement - ok return false; } @@ -44570,112 +43653,110 @@ namespace ts { } if (node.label) { - const message = node.kind === SyntaxKind.BreakStatement - ? Diagnostics.A_break_statement_can_only_jump_to_a_label_of_an_enclosing_statement - : Diagnostics.A_continue_statement_can_only_jump_to_a_label_of_an_enclosing_iteration_statement; + const message = node.kind === ts.SyntaxKind.BreakStatement + ? ts.Diagnostics.A_break_statement_can_only_jump_to_a_label_of_an_enclosing_statement + : ts.Diagnostics.A_continue_statement_can_only_jump_to_a_label_of_an_enclosing_iteration_statement; return grammarErrorOnNode(node, message); } else { - const message = node.kind === SyntaxKind.BreakStatement - ? Diagnostics.A_break_statement_can_only_be_used_within_an_enclosing_iteration_or_switch_statement - : Diagnostics.A_continue_statement_can_only_be_used_within_an_enclosing_iteration_statement; + const message = node.kind === ts.SyntaxKind.BreakStatement + ? ts.Diagnostics.A_break_statement_can_only_be_used_within_an_enclosing_iteration_or_switch_statement + : ts.Diagnostics.A_continue_statement_can_only_be_used_within_an_enclosing_iteration_statement; return grammarErrorOnNode(node, message); } } - function checkGrammarBindingElement(node: BindingElement) { + function checkGrammarBindingElement(node: ts.BindingElement) { if (node.dotDotDotToken) { const elements = node.parent.elements; - if (node !== last(elements)) { - return grammarErrorOnNode(node, Diagnostics.A_rest_element_must_be_last_in_a_destructuring_pattern); + if (node !== ts.last(elements)) { + return grammarErrorOnNode(node, ts.Diagnostics.A_rest_element_must_be_last_in_a_destructuring_pattern); } - checkGrammarForDisallowedTrailingComma(elements, Diagnostics.A_rest_parameter_or_binding_pattern_may_not_have_a_trailing_comma); + checkGrammarForDisallowedTrailingComma(elements, ts.Diagnostics.A_rest_parameter_or_binding_pattern_may_not_have_a_trailing_comma); if (node.propertyName) { - return grammarErrorOnNode(node.name, Diagnostics.A_rest_element_cannot_have_a_property_name); + return grammarErrorOnNode(node.name, ts.Diagnostics.A_rest_element_cannot_have_a_property_name); } } if (node.dotDotDotToken && node.initializer) { // Error on equals token which immediately precedes the initializer - return grammarErrorAtPos(node, node.initializer.pos - 1, 1, Diagnostics.A_rest_element_cannot_have_an_initializer); + return grammarErrorAtPos(node, node.initializer.pos - 1, 1, ts.Diagnostics.A_rest_element_cannot_have_an_initializer); } } - function isStringOrNumberLiteralExpression(expr: Expression) { - return isStringOrNumericLiteralLike(expr) || - expr.kind === SyntaxKind.PrefixUnaryExpression && (expr as PrefixUnaryExpression).operator === SyntaxKind.MinusToken && - (expr as PrefixUnaryExpression).operand.kind === SyntaxKind.NumericLiteral; + function isStringOrNumberLiteralExpression(expr: ts.Expression) { + return ts.isStringOrNumericLiteralLike(expr) || + expr.kind === ts.SyntaxKind.PrefixUnaryExpression && (expr as ts.PrefixUnaryExpression).operator === ts.SyntaxKind.MinusToken && + (expr as ts.PrefixUnaryExpression).operand.kind === ts.SyntaxKind.NumericLiteral; } - function isBigIntLiteralExpression(expr: Expression) { - return expr.kind === SyntaxKind.BigIntLiteral || - expr.kind === SyntaxKind.PrefixUnaryExpression && (expr as PrefixUnaryExpression).operator === SyntaxKind.MinusToken && - (expr as PrefixUnaryExpression).operand.kind === SyntaxKind.BigIntLiteral; + function isBigIntLiteralExpression(expr: ts.Expression) { + return expr.kind === ts.SyntaxKind.BigIntLiteral || + expr.kind === ts.SyntaxKind.PrefixUnaryExpression && (expr as ts.PrefixUnaryExpression).operator === ts.SyntaxKind.MinusToken && + (expr as ts.PrefixUnaryExpression).operand.kind === ts.SyntaxKind.BigIntLiteral; } - function isSimpleLiteralEnumReference(expr: Expression) { - if ((isPropertyAccessExpression(expr) || (isElementAccessExpression(expr) && isStringOrNumberLiteralExpression(expr.argumentExpression))) && - isEntityNameExpression(expr.expression)) { - return !!(checkExpressionCached(expr).flags & TypeFlags.EnumLiteral); + function isSimpleLiteralEnumReference(expr: ts.Expression) { + if ((ts.isPropertyAccessExpression(expr) || (ts.isElementAccessExpression(expr) && isStringOrNumberLiteralExpression(expr.argumentExpression))) && + ts.isEntityNameExpression(expr.expression)) { + return !!(checkExpressionCached(expr).flags & ts.TypeFlags.EnumLiteral); } } - function checkAmbientInitializer(node: VariableDeclaration | PropertyDeclaration | PropertySignature) { + function checkAmbientInitializer(node: ts.VariableDeclaration | ts.PropertyDeclaration | ts.PropertySignature) { const {initializer} = node; if (initializer) { - const isInvalidInitializer = !( - isStringOrNumberLiteralExpression(initializer) || + const isInvalidInitializer = !(isStringOrNumberLiteralExpression(initializer) || isSimpleLiteralEnumReference(initializer) || - initializer.kind === SyntaxKind.TrueKeyword || initializer.kind === SyntaxKind.FalseKeyword || - isBigIntLiteralExpression(initializer) - ); - const isConstOrReadonly = isDeclarationReadonly(node) || isVariableDeclaration(node) && isVarConst(node); + initializer.kind === ts.SyntaxKind.TrueKeyword || initializer.kind === ts.SyntaxKind.FalseKeyword || + isBigIntLiteralExpression(initializer)); + const isConstOrReadonly = ts.isDeclarationReadonly(node) || ts.isVariableDeclaration(node) && ts.isVarConst(node); if (isConstOrReadonly && !node.type) { if (isInvalidInitializer) { - return grammarErrorOnNode(initializer, Diagnostics.A_const_initializer_in_an_ambient_context_must_be_a_string_or_numeric_literal_or_literal_enum_reference); + return grammarErrorOnNode(initializer, ts.Diagnostics.A_const_initializer_in_an_ambient_context_must_be_a_string_or_numeric_literal_or_literal_enum_reference); } } else { - return grammarErrorOnNode(initializer, Diagnostics.Initializers_are_not_allowed_in_ambient_contexts); + return grammarErrorOnNode(initializer, ts.Diagnostics.Initializers_are_not_allowed_in_ambient_contexts); } if (!isConstOrReadonly || isInvalidInitializer) { - return grammarErrorOnNode(initializer, Diagnostics.Initializers_are_not_allowed_in_ambient_contexts); + return grammarErrorOnNode(initializer, ts.Diagnostics.Initializers_are_not_allowed_in_ambient_contexts); } } } - function checkGrammarVariableDeclaration(node: VariableDeclaration) { - if (node.parent.parent.kind !== SyntaxKind.ForInStatement && node.parent.parent.kind !== SyntaxKind.ForOfStatement) { - if (node.flags & NodeFlags.Ambient) { + function checkGrammarVariableDeclaration(node: ts.VariableDeclaration) { + if (node.parent.parent.kind !== ts.SyntaxKind.ForInStatement && node.parent.parent.kind !== ts.SyntaxKind.ForOfStatement) { + if (node.flags & ts.NodeFlags.Ambient) { checkAmbientInitializer(node); } else if (!node.initializer) { - if (isBindingPattern(node.name) && !isBindingPattern(node.parent)) { - return grammarErrorOnNode(node, Diagnostics.A_destructuring_declaration_must_have_an_initializer); + if (ts.isBindingPattern(node.name) && !ts.isBindingPattern(node.parent)) { + return grammarErrorOnNode(node, ts.Diagnostics.A_destructuring_declaration_must_have_an_initializer); } - if (isVarConst(node)) { - return grammarErrorOnNode(node, Diagnostics.const_declarations_must_be_initialized); + if (ts.isVarConst(node)) { + return grammarErrorOnNode(node, ts.Diagnostics.const_declarations_must_be_initialized); } } } - if (node.exclamationToken && (node.parent.parent.kind !== SyntaxKind.VariableStatement || !node.type || node.initializer || node.flags & NodeFlags.Ambient)) { + if (node.exclamationToken && (node.parent.parent.kind !== ts.SyntaxKind.VariableStatement || !node.type || node.initializer || node.flags & ts.NodeFlags.Ambient)) { const message = node.initializer - ? Diagnostics.Declarations_with_initializers_cannot_also_have_definite_assignment_assertions + ? ts.Diagnostics.Declarations_with_initializers_cannot_also_have_definite_assignment_assertions : !node.type - ? Diagnostics.Declarations_with_definite_assignment_assertions_must_also_have_type_annotations - : Diagnostics.A_definite_assignment_assertion_is_not_permitted_in_this_context; + ? ts.Diagnostics.Declarations_with_definite_assignment_assertions_must_also_have_type_annotations + : ts.Diagnostics.A_definite_assignment_assertion_is_not_permitted_in_this_context; return grammarErrorOnNode(node.exclamationToken, message); } - if ((moduleKind < ModuleKind.ES2015 || getSourceFileOfNode(node).impliedNodeFormat === ModuleKind.CommonJS) && moduleKind !== ModuleKind.System && - !(node.parent.parent.flags & NodeFlags.Ambient) && hasSyntacticModifier(node.parent.parent, ModifierFlags.Export)) { + if ((moduleKind < ts.ModuleKind.ES2015 || ts.getSourceFileOfNode(node).impliedNodeFormat === ts.ModuleKind.CommonJS) && moduleKind !== ts.ModuleKind.System && + !(node.parent.parent.flags & ts.NodeFlags.Ambient) && ts.hasSyntacticModifier(node.parent.parent, ts.ModifierFlags.Export)) { checkESModuleMarker(node.name); } - const checkLetConstNames = (isLet(node) || isVarConst(node)); + const checkLetConstNames = (ts.isLet(node) || ts.isVarConst(node)); // 1. LexicalDeclaration : LetOrConst BindingList ; // It is a Syntax Error if the BoundNames of BindingList contains "let". @@ -44687,16 +43768,16 @@ namespace ts { return checkLetConstNames && checkGrammarNameInLetOrConstDeclarations(node.name); } - function checkESModuleMarker(name: Identifier | BindingPattern): boolean { - if (name.kind === SyntaxKind.Identifier) { - if (idText(name) === "__esModule") { - return grammarErrorOnNodeSkippedOn("noEmit", name, Diagnostics.Identifier_expected_esModule_is_reserved_as_an_exported_marker_when_transforming_ECMAScript_modules); + function checkESModuleMarker(name: ts.Identifier | ts.BindingPattern): boolean { + if (name.kind === ts.SyntaxKind.Identifier) { + if (ts.idText(name) === "__esModule") { + return grammarErrorOnNodeSkippedOn("noEmit", name, ts.Diagnostics.Identifier_expected_esModule_is_reserved_as_an_exported_marker_when_transforming_ECMAScript_modules); } } else { const elements = name.elements; for (const element of elements) { - if (!isOmittedExpression(element)) { + if (!ts.isOmittedExpression(element)) { return checkESModuleMarker(element.name); } } @@ -44704,16 +43785,16 @@ namespace ts { return false; } - function checkGrammarNameInLetOrConstDeclarations(name: Identifier | BindingPattern): boolean { - if (name.kind === SyntaxKind.Identifier) { - if (name.originalKeywordKind === SyntaxKind.LetKeyword) { - return grammarErrorOnNode(name, Diagnostics.let_is_not_allowed_to_be_used_as_a_name_in_let_or_const_declarations); + function checkGrammarNameInLetOrConstDeclarations(name: ts.Identifier | ts.BindingPattern): boolean { + if (name.kind === ts.SyntaxKind.Identifier) { + if (name.originalKeywordKind === ts.SyntaxKind.LetKeyword) { + return grammarErrorOnNode(name, ts.Diagnostics.let_is_not_allowed_to_be_used_as_a_name_in_let_or_const_declarations); } } else { const elements = name.elements; for (const element of elements) { - if (!isOmittedExpression(element)) { + if (!ts.isOmittedExpression(element)) { checkGrammarNameInLetOrConstDeclarations(element.name); } } @@ -44721,87 +43802,87 @@ namespace ts { return false; } - function checkGrammarVariableDeclarationList(declarationList: VariableDeclarationList): boolean { + function checkGrammarVariableDeclarationList(declarationList: ts.VariableDeclarationList): boolean { const declarations = declarationList.declarations; if (checkGrammarForDisallowedTrailingComma(declarationList.declarations)) { return true; } if (!declarationList.declarations.length) { - return grammarErrorAtPos(declarationList, declarations.pos, declarations.end - declarations.pos, Diagnostics.Variable_declaration_list_cannot_be_empty); + return grammarErrorAtPos(declarationList, declarations.pos, declarations.end - declarations.pos, ts.Diagnostics.Variable_declaration_list_cannot_be_empty); } return false; } - function allowLetAndConstDeclarations(parent: Node): boolean { + function allowLetAndConstDeclarations(parent: ts.Node): boolean { switch (parent.kind) { - case SyntaxKind.IfStatement: - case SyntaxKind.DoStatement: - case SyntaxKind.WhileStatement: - case SyntaxKind.WithStatement: - case SyntaxKind.ForStatement: - case SyntaxKind.ForInStatement: - case SyntaxKind.ForOfStatement: + case ts.SyntaxKind.IfStatement: + case ts.SyntaxKind.DoStatement: + case ts.SyntaxKind.WhileStatement: + case ts.SyntaxKind.WithStatement: + case ts.SyntaxKind.ForStatement: + case ts.SyntaxKind.ForInStatement: + case ts.SyntaxKind.ForOfStatement: return false; - case SyntaxKind.LabeledStatement: + case ts.SyntaxKind.LabeledStatement: return allowLetAndConstDeclarations(parent.parent); } return true; } - function checkGrammarForDisallowedLetOrConstStatement(node: VariableStatement) { + function checkGrammarForDisallowedLetOrConstStatement(node: ts.VariableStatement) { if (!allowLetAndConstDeclarations(node.parent)) { - if (isLet(node.declarationList)) { - return grammarErrorOnNode(node, Diagnostics.let_declarations_can_only_be_declared_inside_a_block); + if (ts.isLet(node.declarationList)) { + return grammarErrorOnNode(node, ts.Diagnostics.let_declarations_can_only_be_declared_inside_a_block); } - else if (isVarConst(node.declarationList)) { - return grammarErrorOnNode(node, Diagnostics.const_declarations_can_only_be_declared_inside_a_block); + else if (ts.isVarConst(node.declarationList)) { + return grammarErrorOnNode(node, ts.Diagnostics.const_declarations_can_only_be_declared_inside_a_block); } } } - function checkGrammarMetaProperty(node: MetaProperty) { + function checkGrammarMetaProperty(node: ts.MetaProperty) { const escapedText = node.name.escapedText; switch (node.keywordToken) { - case SyntaxKind.NewKeyword: + case ts.SyntaxKind.NewKeyword: if (escapedText !== "target") { - return grammarErrorOnNode(node.name, Diagnostics._0_is_not_a_valid_meta_property_for_keyword_1_Did_you_mean_2, node.name.escapedText, tokenToString(node.keywordToken), "target"); + return grammarErrorOnNode(node.name, ts.Diagnostics._0_is_not_a_valid_meta_property_for_keyword_1_Did_you_mean_2, node.name.escapedText, ts.tokenToString(node.keywordToken), "target"); } break; - case SyntaxKind.ImportKeyword: + case ts.SyntaxKind.ImportKeyword: if (escapedText !== "meta") { - return grammarErrorOnNode(node.name, Diagnostics._0_is_not_a_valid_meta_property_for_keyword_1_Did_you_mean_2, node.name.escapedText, tokenToString(node.keywordToken), "meta"); + return grammarErrorOnNode(node.name, ts.Diagnostics._0_is_not_a_valid_meta_property_for_keyword_1_Did_you_mean_2, node.name.escapedText, ts.tokenToString(node.keywordToken), "meta"); } break; } } - function hasParseDiagnostics(sourceFile: SourceFile): boolean { + function hasParseDiagnostics(sourceFile: ts.SourceFile): boolean { return sourceFile.parseDiagnostics.length > 0; } - function grammarErrorOnFirstToken(node: Node, message: DiagnosticMessage, arg0?: any, arg1?: any, arg2?: any): boolean { - const sourceFile = getSourceFileOfNode(node); + function grammarErrorOnFirstToken(node: ts.Node, message: ts.DiagnosticMessage, arg0?: any, arg1?: any, arg2?: any): boolean { + const sourceFile = ts.getSourceFileOfNode(node); if (!hasParseDiagnostics(sourceFile)) { - const span = getSpanOfTokenAtPosition(sourceFile, node.pos); - diagnostics.add(createFileDiagnostic(sourceFile, span.start, span.length, message, arg0, arg1, arg2)); + const span = ts.getSpanOfTokenAtPosition(sourceFile, node.pos); + diagnostics.add(ts.createFileDiagnostic(sourceFile, span.start, span.length, message, arg0, arg1, arg2)); return true; } return false; } - function grammarErrorAtPos(nodeForSourceFile: Node, start: number, length: number, message: DiagnosticMessage, arg0?: any, arg1?: any, arg2?: any): boolean { - const sourceFile = getSourceFileOfNode(nodeForSourceFile); + function grammarErrorAtPos(nodeForSourceFile: ts.Node, start: number, length: number, message: ts.DiagnosticMessage, arg0?: any, arg1?: any, arg2?: any): boolean { + const sourceFile = ts.getSourceFileOfNode(nodeForSourceFile); if (!hasParseDiagnostics(sourceFile)) { - diagnostics.add(createFileDiagnostic(sourceFile, start, length, message, arg0, arg1, arg2)); + diagnostics.add(ts.createFileDiagnostic(sourceFile, start, length, message, arg0, arg1, arg2)); return true; } return false; } - function grammarErrorOnNodeSkippedOn(key: keyof CompilerOptions, node: Node, message: DiagnosticMessage, arg0?: any, arg1?: any, arg2?: any): boolean { - const sourceFile = getSourceFileOfNode(node); + function grammarErrorOnNodeSkippedOn(key: keyof ts.CompilerOptions, node: ts.Node, message: ts.DiagnosticMessage, arg0?: any, arg1?: any, arg2?: any): boolean { + const sourceFile = ts.getSourceFileOfNode(node); if (!hasParseDiagnostics(sourceFile)) { errorSkippedOn(key, node, message, arg0, arg1, arg2); return true; @@ -44809,81 +43890,79 @@ namespace ts { return false; } - function grammarErrorOnNode(node: Node, message: DiagnosticMessage, arg0?: any, arg1?: any, arg2?: any): boolean { - const sourceFile = getSourceFileOfNode(node); + function grammarErrorOnNode(node: ts.Node, message: ts.DiagnosticMessage, arg0?: any, arg1?: any, arg2?: any): boolean { + const sourceFile = ts.getSourceFileOfNode(node); if (!hasParseDiagnostics(sourceFile)) { - diagnostics.add(createDiagnosticForNode(node, message, arg0, arg1, arg2)); + diagnostics.add(ts.createDiagnosticForNode(node, message, arg0, arg1, arg2)); return true; } return false; } - function checkGrammarConstructorTypeParameters(node: ConstructorDeclaration) { - const jsdocTypeParameters = isInJSFile(node) ? getJSDocTypeParameterDeclarations(node) : undefined; - const range = node.typeParameters || jsdocTypeParameters && firstOrUndefined(jsdocTypeParameters); + function checkGrammarConstructorTypeParameters(node: ts.ConstructorDeclaration) { + const jsdocTypeParameters = ts.isInJSFile(node) ? ts.getJSDocTypeParameterDeclarations(node) : undefined; + const range = node.typeParameters || jsdocTypeParameters && ts.firstOrUndefined(jsdocTypeParameters); if (range) { - const pos = range.pos === range.end ? range.pos : skipTrivia(getSourceFileOfNode(node).text, range.pos); - return grammarErrorAtPos(node, pos, range.end - pos, Diagnostics.Type_parameters_cannot_appear_on_a_constructor_declaration); + const pos = range.pos === range.end ? range.pos : ts.skipTrivia(ts.getSourceFileOfNode(node).text, range.pos); + return grammarErrorAtPos(node, pos, range.end - pos, ts.Diagnostics.Type_parameters_cannot_appear_on_a_constructor_declaration); } } - function checkGrammarConstructorTypeAnnotation(node: ConstructorDeclaration) { - const type = getEffectiveReturnTypeNode(node); + function checkGrammarConstructorTypeAnnotation(node: ts.ConstructorDeclaration) { + const type = ts.getEffectiveReturnTypeNode(node); if (type) { - return grammarErrorOnNode(type, Diagnostics.Type_annotation_cannot_appear_on_a_constructor_declaration); + return grammarErrorOnNode(type, ts.Diagnostics.Type_annotation_cannot_appear_on_a_constructor_declaration); } } - function checkGrammarProperty(node: PropertyDeclaration | PropertySignature) { - if (isComputedPropertyName(node.name) && isBinaryExpression(node.name.expression) && node.name.expression.operatorToken.kind === SyntaxKind.InKeyword) { - return grammarErrorOnNode( - (node.parent as ClassLikeDeclaration | InterfaceDeclaration | TypeLiteralNode).members[0], - Diagnostics.A_mapped_type_may_not_declare_properties_or_methods); + function checkGrammarProperty(node: ts.PropertyDeclaration | ts.PropertySignature) { + if (ts.isComputedPropertyName(node.name) && ts.isBinaryExpression(node.name.expression) && node.name.expression.operatorToken.kind === ts.SyntaxKind.InKeyword) { + return grammarErrorOnNode((node.parent as ts.ClassLikeDeclaration | ts.InterfaceDeclaration | ts.TypeLiteralNode).members[0], ts.Diagnostics.A_mapped_type_may_not_declare_properties_or_methods); } - if (isClassLike(node.parent)) { - if (isStringLiteral(node.name) && node.name.text === "constructor") { - return grammarErrorOnNode(node.name, Diagnostics.Classes_may_not_have_a_field_named_constructor); + if (ts.isClassLike(node.parent)) { + if (ts.isStringLiteral(node.name) && node.name.text === "constructor") { + return grammarErrorOnNode(node.name, ts.Diagnostics.Classes_may_not_have_a_field_named_constructor); } - if (checkGrammarForInvalidDynamicName(node.name, Diagnostics.A_computed_property_name_in_a_class_property_declaration_must_have_a_simple_literal_type_or_a_unique_symbol_type)) { + if (checkGrammarForInvalidDynamicName(node.name, ts.Diagnostics.A_computed_property_name_in_a_class_property_declaration_must_have_a_simple_literal_type_or_a_unique_symbol_type)) { return true; } - if (languageVersion < ScriptTarget.ES2015 && isPrivateIdentifier(node.name)) { - return grammarErrorOnNode(node.name, Diagnostics.Private_identifiers_are_only_available_when_targeting_ECMAScript_2015_and_higher); + if (languageVersion < ts.ScriptTarget.ES2015 && ts.isPrivateIdentifier(node.name)) { + return grammarErrorOnNode(node.name, ts.Diagnostics.Private_identifiers_are_only_available_when_targeting_ECMAScript_2015_and_higher); } } - else if (node.parent.kind === SyntaxKind.InterfaceDeclaration) { - if (checkGrammarForInvalidDynamicName(node.name, Diagnostics.A_computed_property_name_in_an_interface_must_refer_to_an_expression_whose_type_is_a_literal_type_or_a_unique_symbol_type)) { + else if (node.parent.kind === ts.SyntaxKind.InterfaceDeclaration) { + if (checkGrammarForInvalidDynamicName(node.name, ts.Diagnostics.A_computed_property_name_in_an_interface_must_refer_to_an_expression_whose_type_is_a_literal_type_or_a_unique_symbol_type)) { return true; } if (node.initializer) { - return grammarErrorOnNode(node.initializer, Diagnostics.An_interface_property_cannot_have_an_initializer); + return grammarErrorOnNode(node.initializer, ts.Diagnostics.An_interface_property_cannot_have_an_initializer); } } - else if (isTypeLiteralNode(node.parent)) { - if (checkGrammarForInvalidDynamicName(node.name, Diagnostics.A_computed_property_name_in_a_type_literal_must_refer_to_an_expression_whose_type_is_a_literal_type_or_a_unique_symbol_type)) { + else if (ts.isTypeLiteralNode(node.parent)) { + if (checkGrammarForInvalidDynamicName(node.name, ts.Diagnostics.A_computed_property_name_in_a_type_literal_must_refer_to_an_expression_whose_type_is_a_literal_type_or_a_unique_symbol_type)) { return true; } if (node.initializer) { - return grammarErrorOnNode(node.initializer, Diagnostics.A_type_literal_property_cannot_have_an_initializer); + return grammarErrorOnNode(node.initializer, ts.Diagnostics.A_type_literal_property_cannot_have_an_initializer); } } - if (node.flags & NodeFlags.Ambient) { + if (node.flags & ts.NodeFlags.Ambient) { checkAmbientInitializer(node); } - if (isPropertyDeclaration(node) && node.exclamationToken && (!isClassLike(node.parent) || !node.type || node.initializer || - node.flags & NodeFlags.Ambient || isStatic(node) || hasAbstractModifier(node))) { + if (ts.isPropertyDeclaration(node) && node.exclamationToken && (!ts.isClassLike(node.parent) || !node.type || node.initializer || + node.flags & ts.NodeFlags.Ambient || ts.isStatic(node) || ts.hasAbstractModifier(node))) { const message = node.initializer - ? Diagnostics.Declarations_with_initializers_cannot_also_have_definite_assignment_assertions + ? ts.Diagnostics.Declarations_with_initializers_cannot_also_have_definite_assignment_assertions : !node.type - ? Diagnostics.Declarations_with_definite_assignment_assertions_must_also_have_type_annotations - : Diagnostics.A_definite_assignment_assertion_is_not_permitted_in_this_context; + ? ts.Diagnostics.Declarations_with_definite_assignment_assertions_must_also_have_type_annotations + : ts.Diagnostics.A_definite_assignment_assertion_is_not_permitted_in_this_context; return grammarErrorOnNode(node.exclamationToken, message); } } - function checkGrammarTopLevelElementForRequiredDeclareModifier(node: Node): boolean { + function checkGrammarTopLevelElementForRequiredDeclareModifier(node: ts.Node): boolean { // A declare modifier is required for any top level .d.ts declaration except export=, export default, export as namespace // interfaces and imports categories: // @@ -44896,23 +43975,23 @@ namespace ts { // export_opt AmbientDeclaration // // TODO: The spec needs to be amended to reflect this grammar. - if (node.kind === SyntaxKind.InterfaceDeclaration || - node.kind === SyntaxKind.TypeAliasDeclaration || - node.kind === SyntaxKind.ImportDeclaration || - node.kind === SyntaxKind.ImportEqualsDeclaration || - node.kind === SyntaxKind.ExportDeclaration || - node.kind === SyntaxKind.ExportAssignment || - node.kind === SyntaxKind.NamespaceExportDeclaration || - hasSyntacticModifier(node, ModifierFlags.Ambient | ModifierFlags.Export | ModifierFlags.Default)) { + if (node.kind === ts.SyntaxKind.InterfaceDeclaration || + node.kind === ts.SyntaxKind.TypeAliasDeclaration || + node.kind === ts.SyntaxKind.ImportDeclaration || + node.kind === ts.SyntaxKind.ImportEqualsDeclaration || + node.kind === ts.SyntaxKind.ExportDeclaration || + node.kind === ts.SyntaxKind.ExportAssignment || + node.kind === ts.SyntaxKind.NamespaceExportDeclaration || + ts.hasSyntacticModifier(node, ts.ModifierFlags.Ambient | ts.ModifierFlags.Export | ts.ModifierFlags.Default)) { return false; } - return grammarErrorOnFirstToken(node, Diagnostics.Top_level_declarations_in_d_ts_files_must_start_with_either_a_declare_or_export_modifier); + return grammarErrorOnFirstToken(node, ts.Diagnostics.Top_level_declarations_in_d_ts_files_must_start_with_either_a_declare_or_export_modifier); } - function checkGrammarTopLevelElementsForRequiredDeclareModifier(file: SourceFile): boolean { + function checkGrammarTopLevelElementsForRequiredDeclareModifier(file: ts.SourceFile): boolean { for (const decl of file.statements) { - if (isDeclaration(decl) || decl.kind === SyntaxKind.VariableStatement) { + if (ts.isDeclaration(decl) || decl.kind === ts.SyntaxKind.VariableStatement) { if (checkGrammarTopLevelElementForRequiredDeclareModifier(decl)) { return true; } @@ -44921,16 +44000,16 @@ namespace ts { return false; } - function checkGrammarSourceFile(node: SourceFile): boolean { - return !!(node.flags & NodeFlags.Ambient) && checkGrammarTopLevelElementsForRequiredDeclareModifier(node); + function checkGrammarSourceFile(node: ts.SourceFile): boolean { + return !!(node.flags & ts.NodeFlags.Ambient) && checkGrammarTopLevelElementsForRequiredDeclareModifier(node); } - function checkGrammarStatementInAmbientContext(node: Node): boolean { - if (node.flags & NodeFlags.Ambient) { + function checkGrammarStatementInAmbientContext(node: ts.Node): boolean { + if (node.flags & ts.NodeFlags.Ambient) { // Find containing block which is either Block, ModuleBlock, SourceFile const links = getNodeLinks(node); - if (!links.hasReportedStatementInAmbientContext && (isFunctionLike(node.parent) || isAccessor(node.parent))) { - return getNodeLinks(node).hasReportedStatementInAmbientContext = grammarErrorOnFirstToken(node, Diagnostics.An_implementation_cannot_be_declared_in_ambient_contexts); + if (!links.hasReportedStatementInAmbientContext && (ts.isFunctionLike(node.parent) || ts.isAccessor(node.parent))) { + return getNodeLinks(node).hasReportedStatementInAmbientContext = grammarErrorOnFirstToken(node, ts.Diagnostics.An_implementation_cannot_be_declared_in_ambient_contexts); } // We are either parented by another statement, or some sort of block. @@ -44938,11 +44017,11 @@ namespace ts { // to prevent noisiness. So use a bit on the block to indicate if // this has already been reported, and don't report if it has. // - if (node.parent.kind === SyntaxKind.Block || node.parent.kind === SyntaxKind.ModuleBlock || node.parent.kind === SyntaxKind.SourceFile) { + if (node.parent.kind === ts.SyntaxKind.Block || node.parent.kind === ts.SyntaxKind.ModuleBlock || node.parent.kind === ts.SyntaxKind.SourceFile) { const links = getNodeLinks(node.parent); // Check if the containing block ever report this error if (!links.hasReportedStatementInAmbientContext) { - return links.hasReportedStatementInAmbientContext = grammarErrorOnFirstToken(node, Diagnostics.Statements_are_not_allowed_in_ambient_contexts); + return links.hasReportedStatementInAmbientContext = grammarErrorOnFirstToken(node, ts.Diagnostics.Statements_are_not_allowed_in_ambient_contexts); } } else { @@ -44954,21 +44033,21 @@ namespace ts { return false; } - function checkGrammarNumericLiteral(node: NumericLiteral): boolean { + function checkGrammarNumericLiteral(node: ts.NumericLiteral): boolean { // Grammar checking - if (node.numericLiteralFlags & TokenFlags.Octal) { - let diagnosticMessage: DiagnosticMessage | undefined; - if (languageVersion >= ScriptTarget.ES5) { - diagnosticMessage = Diagnostics.Octal_literals_are_not_available_when_targeting_ECMAScript_5_and_higher_Use_the_syntax_0; + if (node.numericLiteralFlags & ts.TokenFlags.Octal) { + let diagnosticMessage: ts.DiagnosticMessage | undefined; + if (languageVersion >= ts.ScriptTarget.ES5) { + diagnosticMessage = ts.Diagnostics.Octal_literals_are_not_available_when_targeting_ECMAScript_5_and_higher_Use_the_syntax_0; } - else if (isChildOfNodeWithKind(node, SyntaxKind.LiteralType)) { - diagnosticMessage = Diagnostics.Octal_literal_types_must_use_ES2015_syntax_Use_the_syntax_0; + else if (ts.isChildOfNodeWithKind(node, ts.SyntaxKind.LiteralType)) { + diagnosticMessage = ts.Diagnostics.Octal_literal_types_must_use_ES2015_syntax_Use_the_syntax_0; } - else if (isChildOfNodeWithKind(node, SyntaxKind.EnumMember)) { - diagnosticMessage = Diagnostics.Octal_literals_are_not_allowed_in_enums_members_initializer_Use_the_syntax_0; + else if (ts.isChildOfNodeWithKind(node, ts.SyntaxKind.EnumMember)) { + diagnosticMessage = ts.Diagnostics.Octal_literals_are_not_allowed_in_enums_members_initializer_Use_the_syntax_0; } if (diagnosticMessage) { - const withMinus = isPrefixUnaryExpression(node.parent) && node.parent.operator === SyntaxKind.MinusToken; + const withMinus = ts.isPrefixUnaryExpression(node.parent) && node.parent.operator === ts.SyntaxKind.MinusToken; const literal = (withMinus ? "-" : "") + "0o" + node.text; return grammarErrorOnNode(withMinus ? node.parent : node, diagnosticMessage, literal); } @@ -44980,11 +44059,11 @@ namespace ts { return false; } - function checkNumericLiteralValueSize(node: NumericLiteral) { + function checkNumericLiteralValueSize(node: ts.NumericLiteral) { // We should test against `getTextOfNode(node)` rather than `node.text`, because `node.text` for large numeric literals can contain "." // e.g. `node.text` for numeric literal `1100000000000000000000` is `1.1e21`. - const isFractional = getTextOfNode(node).indexOf(".") !== -1; - const isScientific = node.numericLiteralFlags & TokenFlags.Scientific; + const isFractional = ts.getTextOfNode(node).indexOf(".") !== -1; + const isScientific = node.numericLiteralFlags & ts.TokenFlags.Scientific; // Scientific notation (e.g. 2e54 and 1e00000000010) can't be converted to bigint // Fractional numbers (e.g. 9000000000000000.001) are inherently imprecise anyway @@ -45002,15 +44081,15 @@ namespace ts { return; } - addErrorOrSuggestion(/*isError*/ false, createDiagnosticForNode(node, Diagnostics.Numeric_literals_with_absolute_values_equal_to_2_53_or_greater_are_too_large_to_be_represented_accurately_as_integers)); + addErrorOrSuggestion(/*isError*/ false, ts.createDiagnosticForNode(node, ts.Diagnostics.Numeric_literals_with_absolute_values_equal_to_2_53_or_greater_are_too_large_to_be_represented_accurately_as_integers)); } - function checkGrammarBigIntLiteral(node: BigIntLiteral): boolean { - const literalType = isLiteralTypeNode(node.parent) || - isPrefixUnaryExpression(node.parent) && isLiteralTypeNode(node.parent.parent); + function checkGrammarBigIntLiteral(node: ts.BigIntLiteral): boolean { + const literalType = ts.isLiteralTypeNode(node.parent) || + ts.isPrefixUnaryExpression(node.parent) && ts.isLiteralTypeNode(node.parent.parent); if (!literalType) { - if (languageVersion < ScriptTarget.ES2020) { - if (grammarErrorOnNode(node, Diagnostics.BigInt_literals_are_not_available_when_targeting_lower_than_ES2020)) { + if (languageVersion < ts.ScriptTarget.ES2020) { + if (grammarErrorOnNode(node, ts.Diagnostics.BigInt_literals_are_not_available_when_targeting_lower_than_ES2020)) { return true; } } @@ -45018,17 +44097,17 @@ namespace ts { return false; } - function grammarErrorAfterFirstToken(node: Node, message: DiagnosticMessage, arg0?: any, arg1?: any, arg2?: any): boolean { - const sourceFile = getSourceFileOfNode(node); + function grammarErrorAfterFirstToken(node: ts.Node, message: ts.DiagnosticMessage, arg0?: any, arg1?: any, arg2?: any): boolean { + const sourceFile = ts.getSourceFileOfNode(node); if (!hasParseDiagnostics(sourceFile)) { - const span = getSpanOfTokenAtPosition(sourceFile, node.pos); - diagnostics.add(createFileDiagnostic(sourceFile, textSpanEnd(span), /*length*/ 0, message, arg0, arg1, arg2)); + const span = ts.getSpanOfTokenAtPosition(sourceFile, node.pos); + diagnostics.add(ts.createFileDiagnostic(sourceFile, ts.textSpanEnd(span), /*length*/ 0, message, arg0, arg1, arg2)); return true; } return false; } - function getAmbientModules(): Symbol[] { + function getAmbientModules(): ts.Symbol[] { if (!ambientModulesCache) { ambientModulesCache = []; globals.forEach((global, sym) => { @@ -45041,72 +44120,70 @@ namespace ts { return ambientModulesCache; } - function checkGrammarImportClause(node: ImportClause): boolean { + function checkGrammarImportClause(node: ts.ImportClause): boolean { if (node.isTypeOnly && node.name && node.namedBindings) { - return grammarErrorOnNode(node, Diagnostics.A_type_only_import_can_specify_a_default_import_or_named_bindings_but_not_both); + return grammarErrorOnNode(node, ts.Diagnostics.A_type_only_import_can_specify_a_default_import_or_named_bindings_but_not_both); } - if (node.isTypeOnly && node.namedBindings?.kind === SyntaxKind.NamedImports) { + if (node.isTypeOnly && node.namedBindings?.kind === ts.SyntaxKind.NamedImports) { return checkGrammarNamedImportsOrExports(node.namedBindings); } return false; } - function checkGrammarNamedImportsOrExports(namedBindings: NamedImportsOrExports): boolean { - return !!forEach(namedBindings.elements, specifier => { + function checkGrammarNamedImportsOrExports(namedBindings: ts.NamedImportsOrExports): boolean { + return !!ts.forEach(namedBindings.elements, specifier => { if (specifier.isTypeOnly) { - return grammarErrorOnFirstToken( - specifier, - specifier.kind === SyntaxKind.ImportSpecifier - ? Diagnostics.The_type_modifier_cannot_be_used_on_a_named_import_when_import_type_is_used_on_its_import_statement - : Diagnostics.The_type_modifier_cannot_be_used_on_a_named_export_when_export_type_is_used_on_its_export_statement); + return grammarErrorOnFirstToken(specifier, specifier.kind === ts.SyntaxKind.ImportSpecifier + ? ts.Diagnostics.The_type_modifier_cannot_be_used_on_a_named_import_when_import_type_is_used_on_its_import_statement + : ts.Diagnostics.The_type_modifier_cannot_be_used_on_a_named_export_when_export_type_is_used_on_its_export_statement); } }); } - function checkGrammarImportCallExpression(node: ImportCall): boolean { - if (moduleKind === ModuleKind.ES2015) { - return grammarErrorOnNode(node, Diagnostics.Dynamic_imports_are_only_supported_when_the_module_flag_is_set_to_es2020_es2022_esnext_commonjs_amd_system_umd_node16_or_nodenext); + function checkGrammarImportCallExpression(node: ts.ImportCall): boolean { + if (moduleKind === ts.ModuleKind.ES2015) { + return grammarErrorOnNode(node, ts.Diagnostics.Dynamic_imports_are_only_supported_when_the_module_flag_is_set_to_es2020_es2022_esnext_commonjs_amd_system_umd_node16_or_nodenext); } if (node.typeArguments) { - return grammarErrorOnNode(node, Diagnostics.This_use_of_import_is_invalid_import_calls_can_be_written_but_they_must_have_parentheses_and_cannot_have_type_arguments); + return grammarErrorOnNode(node, ts.Diagnostics.This_use_of_import_is_invalid_import_calls_can_be_written_but_they_must_have_parentheses_and_cannot_have_type_arguments); } const nodeArguments = node.arguments; - if (moduleKind !== ModuleKind.ESNext && moduleKind !== ModuleKind.NodeNext) { + if (moduleKind !== ts.ModuleKind.ESNext && moduleKind !== ts.ModuleKind.NodeNext) { // We are allowed trailing comma after proposal-import-assertions. checkGrammarForDisallowedTrailingComma(nodeArguments); if (nodeArguments.length > 1) { const assertionArgument = nodeArguments[1]; - return grammarErrorOnNode(assertionArgument, Diagnostics.Dynamic_imports_only_support_a_second_argument_when_the_module_option_is_set_to_esnext_node16_or_nodenext); + return grammarErrorOnNode(assertionArgument, ts.Diagnostics.Dynamic_imports_only_support_a_second_argument_when_the_module_option_is_set_to_esnext_node16_or_nodenext); } } if (nodeArguments.length === 0 || nodeArguments.length > 2) { - return grammarErrorOnNode(node, Diagnostics.Dynamic_imports_can_only_accept_a_module_specifier_and_an_optional_assertion_as_arguments); + return grammarErrorOnNode(node, ts.Diagnostics.Dynamic_imports_can_only_accept_a_module_specifier_and_an_optional_assertion_as_arguments); } // see: parseArgumentOrArrayLiteralElement...we use this function which parse arguments of callExpression to parse specifier for dynamic import. // parseArgumentOrArrayLiteralElement allows spread element to be in an argument list which is not allowed as specifier in dynamic import. - const spreadElement = find(nodeArguments, isSpreadElement); + const spreadElement = ts.find(nodeArguments, ts.isSpreadElement); if (spreadElement) { - return grammarErrorOnNode(spreadElement, Diagnostics.Argument_of_dynamic_import_cannot_be_spread_element); + return grammarErrorOnNode(spreadElement, ts.Diagnostics.Argument_of_dynamic_import_cannot_be_spread_element); } return false; } - function findMatchingTypeReferenceOrTypeAliasReference(source: Type, unionTarget: UnionOrIntersectionType) { - const sourceObjectFlags = getObjectFlags(source); - if (sourceObjectFlags & (ObjectFlags.Reference | ObjectFlags.Anonymous) && unionTarget.flags & TypeFlags.Union) { - return find(unionTarget.types, target => { - if (target.flags & TypeFlags.Object) { - const overlapObjFlags = sourceObjectFlags & getObjectFlags(target); - if (overlapObjFlags & ObjectFlags.Reference) { - return (source as TypeReference).target === (target as TypeReference).target; + function findMatchingTypeReferenceOrTypeAliasReference(source: ts.Type, unionTarget: ts.UnionOrIntersectionType) { + const sourceObjectFlags = ts.getObjectFlags(source); + if (sourceObjectFlags & (ts.ObjectFlags.Reference | ts.ObjectFlags.Anonymous) && unionTarget.flags & ts.TypeFlags.Union) { + return ts.find(unionTarget.types, target => { + if (target.flags & ts.TypeFlags.Object) { + const overlapObjFlags = sourceObjectFlags & ts.getObjectFlags(target); + if (overlapObjFlags & ts.ObjectFlags.Reference) { + return (source as ts.TypeReference).target === (target as ts.TypeReference).target; } - if (overlapObjFlags & ObjectFlags.Anonymous) { - return !!(source as AnonymousType).aliasSymbol && (source as AnonymousType).aliasSymbol === (target as AnonymousType).aliasSymbol; + if (overlapObjFlags & ts.ObjectFlags.Anonymous) { + return !!(source as ts.AnonymousType).aliasSymbol && (source as ts.AnonymousType).aliasSymbol === (target as ts.AnonymousType).aliasSymbol; } } return false; @@ -45114,37 +44191,37 @@ namespace ts { } } - function findBestTypeForObjectLiteral(source: Type, unionTarget: UnionOrIntersectionType) { - if (getObjectFlags(source) & ObjectFlags.ObjectLiteral && someType(unionTarget, isArrayLikeType)) { - return find(unionTarget.types, t => !isArrayLikeType(t)); + function findBestTypeForObjectLiteral(source: ts.Type, unionTarget: ts.UnionOrIntersectionType) { + if (ts.getObjectFlags(source) & ts.ObjectFlags.ObjectLiteral && someType(unionTarget, isArrayLikeType)) { + return ts.find(unionTarget.types, t => !isArrayLikeType(t)); } } - function findBestTypeForInvokable(source: Type, unionTarget: UnionOrIntersectionType) { - let signatureKind = SignatureKind.Call; + function findBestTypeForInvokable(source: ts.Type, unionTarget: ts.UnionOrIntersectionType) { + let signatureKind = ts.SignatureKind.Call; const hasSignatures = getSignaturesOfType(source, signatureKind).length > 0 || - (signatureKind = SignatureKind.Construct, getSignaturesOfType(source, signatureKind).length > 0); + (signatureKind = ts.SignatureKind.Construct, getSignaturesOfType(source, signatureKind).length > 0); if (hasSignatures) { - return find(unionTarget.types, t => getSignaturesOfType(t, signatureKind).length > 0); + return ts.find(unionTarget.types, t => getSignaturesOfType(t, signatureKind).length > 0); } } - function findMostOverlappyType(source: Type, unionTarget: UnionOrIntersectionType) { - let bestMatch: Type | undefined; - if (!(source.flags & (TypeFlags.Primitive | TypeFlags.InstantiablePrimitive))) { + function findMostOverlappyType(source: ts.Type, unionTarget: ts.UnionOrIntersectionType) { + let bestMatch: ts.Type | undefined; + if (!(source.flags & (ts.TypeFlags.Primitive | ts.TypeFlags.InstantiablePrimitive))) { let matchingCount = 0; for (const target of unionTarget.types) { - if (!(target.flags & (TypeFlags.Primitive | TypeFlags.InstantiablePrimitive))) { + if (!(target.flags & (ts.TypeFlags.Primitive | ts.TypeFlags.InstantiablePrimitive))) { const overlap = getIntersectionType([getIndexType(source), getIndexType(target)]); - if (overlap.flags & TypeFlags.Index) { + if (overlap.flags & ts.TypeFlags.Index) { // perfect overlap of keys return target; } - else if (isUnitType(overlap) || overlap.flags & TypeFlags.Union) { + else if (isUnitType(overlap) || overlap.flags & ts.TypeFlags.Union) { // We only want to account for literal types otherwise. // If we have a union of index types, it seems likely that we // needed to elaborate between two generic mapped types anyway. - const len = overlap.flags & TypeFlags.Union ? countWhere((overlap as UnionType).types, isUnitType) : 1; + const len = overlap.flags & ts.TypeFlags.Union ? ts.countWhere((overlap as ts.UnionType).types, isUnitType) : 1; if (len >= matchingCount) { bestMatch = target; matchingCount = len; @@ -45156,10 +44233,10 @@ namespace ts { return bestMatch; } - function filterPrimitivesIfContainsNonPrimitive(type: UnionType) { - if (maybeTypeOfKind(type, TypeFlags.NonPrimitive)) { - const result = filterType(type, t => !(t.flags & TypeFlags.Primitive)); - if (!(result.flags & TypeFlags.Never)) { + function filterPrimitivesIfContainsNonPrimitive(type: ts.UnionType) { + if (maybeTypeOfKind(type, ts.TypeFlags.NonPrimitive)) { + const result = filterType(type, t => !(t.flags & ts.TypeFlags.Primitive)); + if (!(result.flags & ts.TypeFlags.Never)) { return result; } } @@ -45167,9 +44244,9 @@ namespace ts { } // Keep this up-to-date with the same logic within `getApparentTypeOfContextualType`, since they should behave similarly - function findMatchingDiscriminantType(source: Type, target: Type, isRelatedTo: (source: Type, target: Type) => Ternary, skipPartial?: boolean) { - if (target.flags & TypeFlags.Union && source.flags & (TypeFlags.Intersection | TypeFlags.Object)) { - const match = getMatchingUnionConstituentForType(target as UnionType, source); + function findMatchingDiscriminantType(source: ts.Type, target: ts.Type, isRelatedTo: (source: ts.Type, target: ts.Type) => ts.Ternary, skipPartial?: boolean) { + if (target.flags & ts.TypeFlags.Union && source.flags & (ts.TypeFlags.Intersection | ts.TypeFlags.Object)) { + const match = getMatchingUnionConstituentForType(target as ts.UnionType, source); if (match) { return match; } @@ -45177,7 +44254,10 @@ namespace ts { if (sourceProperties) { const sourcePropertiesFiltered = findDiscriminantProperties(sourceProperties, target); if (sourcePropertiesFiltered) { - return discriminateTypeByDiscriminableItems(target as UnionType, map(sourcePropertiesFiltered, p => ([() => getTypeOfSymbol(p), p.escapedName] as [() => Type, __String])), isRelatedTo, /*defaultValue*/ undefined, skipPartial); + return discriminateTypeByDiscriminableItems(target as ts.UnionType, ts.map(sourcePropertiesFiltered, p => ([() => getTypeOfSymbol(p), p.escapedName] as [ + () => ts.Type, + ts.__String + ])), isRelatedTo, /*defaultValue*/ undefined, skipPartial); } } } @@ -45185,37 +44265,37 @@ namespace ts { } } - function isNotAccessor(declaration: Declaration): boolean { + function isNotAccessor(declaration: ts.Declaration): boolean { // Accessors check for their own matching duplicates, and in contexts where they are valid, there are already duplicate identifier checks - return !isAccessor(declaration); + return !ts.isAccessor(declaration); } - function isNotOverload(declaration: Declaration): boolean { - return (declaration.kind !== SyntaxKind.FunctionDeclaration && declaration.kind !== SyntaxKind.MethodDeclaration) || - !!(declaration as FunctionDeclaration).body; + function isNotOverload(declaration: ts.Declaration): boolean { + return (declaration.kind !== ts.SyntaxKind.FunctionDeclaration && declaration.kind !== ts.SyntaxKind.MethodDeclaration) || + !!(declaration as ts.FunctionDeclaration).body; } /** Like 'isDeclarationName', but returns true for LHS of `import { x as y }` or `export { x as y }`. */ - function isDeclarationNameOrImportPropertyName(name: Node): boolean { + function isDeclarationNameOrImportPropertyName(name: ts.Node): boolean { switch (name.parent.kind) { - case SyntaxKind.ImportSpecifier: - case SyntaxKind.ExportSpecifier: - return isIdentifier(name); + case ts.SyntaxKind.ImportSpecifier: + case ts.SyntaxKind.ExportSpecifier: + return ts.isIdentifier(name); default: - return isDeclarationName(name); + return ts.isDeclarationName(name); } } namespace JsxNames { - export const JSX = "JSX" as __String; - export const IntrinsicElements = "IntrinsicElements" as __String; - export const ElementClass = "ElementClass" as __String; - export const ElementAttributesPropertyNameContainer = "ElementAttributesProperty" as __String; // TODO: Deprecate and remove support - export const ElementChildrenAttributeNameContainer = "ElementChildrenAttribute" as __String; - export const Element = "Element" as __String; - export const IntrinsicAttributes = "IntrinsicAttributes" as __String; - export const IntrinsicClassAttributes = "IntrinsicClassAttributes" as __String; - export const LibraryManagedAttributes = "LibraryManagedAttributes" as __String; + export const JSX = "JSX" as ts.__String; + export const IntrinsicElements = "IntrinsicElements" as ts.__String; + export const ElementClass = "ElementClass" as ts.__String; + export const ElementAttributesPropertyNameContainer = "ElementAttributesProperty" as ts.__String; // TODO: Deprecate and remove support + export const ElementChildrenAttributeNameContainer = "ElementChildrenAttribute" as ts.__String; + export const Element = "Element" as ts.__String; + export const IntrinsicAttributes = "IntrinsicAttributes" as ts.__String; + export const IntrinsicClassAttributes = "IntrinsicClassAttributes" as ts.__String; + export const LibraryManagedAttributes = "LibraryManagedAttributes" as ts.__String; } function getIterationTypesKeyFromIterationTypeKind(typeKind: IterationTypeKind) { @@ -45226,11 +44306,11 @@ namespace ts { } } - export function signatureHasRestParameter(s: Signature) { - return !!(s.flags & SignatureFlags.HasRestParameter); + export function signatureHasRestParameter(s: ts.Signature) { + return !!(s.flags & ts.SignatureFlags.HasRestParameter); } - export function signatureHasLiteralTypes(s: Signature) { - return !!(s.flags & SignatureFlags.HasLiteralTypes); + export function signatureHasLiteralTypes(s: ts.Signature) { + return !!(s.flags & ts.SignatureFlags.HasLiteralTypes); } } diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index ba368e3c56695..8b513dfddea47 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -1,27 +1,33 @@ namespace ts { /* @internal */ - export const compileOnSaveCommandLineOption: CommandLineOption = { + export const compileOnSaveCommandLineOption: ts.CommandLineOption = { name: "compileOnSave", type: "boolean", defaultValueDescription: false, }; - const jsxOptionMap = new Map(getEntries({ - "preserve": JsxEmit.Preserve, - "react-native": JsxEmit.ReactNative, - "react": JsxEmit.React, - "react-jsx": JsxEmit.ReactJSX, - "react-jsxdev": JsxEmit.ReactJSXDev, + const jsxOptionMap = new ts.Map(ts.getEntries({ + "preserve": ts.JsxEmit.Preserve, + "react-native": ts.JsxEmit.ReactNative, + "react": ts.JsxEmit.React, + "react-jsx": ts.JsxEmit.ReactJSX, + "react-jsxdev": ts.JsxEmit.ReactJSXDev, })); /* @internal */ - export const inverseJsxOptionMap = new Map(arrayFrom(mapIterator(jsxOptionMap.entries(), ([key, value]: [string, JsxEmit]) => ["" + value, key] as const))); + export const inverseJsxOptionMap = new ts.Map(ts.arrayFrom(ts.mapIterator(jsxOptionMap.entries(), ([key, value]: [ + string, + ts.JsxEmit + ]) => ["" + value, key] as const))); // NOTE: The order here is important to default lib ordering as entries will have the same // order in the generated program (see `getDefaultLibPriority` in program.ts). This // order also affects overload resolution when a type declared in one lib is // augmented in another lib. - const libEntries: [string, string][] = [ + const libEntries: [ + string, + string + ][] = [ // JavaScript only ["es5", "lib.es5.d.ts"], ["es6", "lib.es2015.d.ts"], @@ -107,54 +113,54 @@ namespace ts { * option as well as for resolving lib reference directives. */ /* @internal */ - export const libMap = new Map(libEntries); + export const libMap = new ts.Map(libEntries); // Watch related options /* @internal */ - export const optionsForWatch: CommandLineOption[] = [ + export const optionsForWatch: ts.CommandLineOption[] = [ { name: "watchFile", - type: new Map(getEntries({ - fixedpollinginterval: WatchFileKind.FixedPollingInterval, - prioritypollinginterval: WatchFileKind.PriorityPollingInterval, - dynamicprioritypolling: WatchFileKind.DynamicPriorityPolling, - fixedchunksizepolling: WatchFileKind.FixedChunkSizePolling, - usefsevents: WatchFileKind.UseFsEvents, - usefseventsonparentdirectory: WatchFileKind.UseFsEventsOnParentDirectory, + type: new ts.Map(ts.getEntries({ + fixedpollinginterval: ts.WatchFileKind.FixedPollingInterval, + prioritypollinginterval: ts.WatchFileKind.PriorityPollingInterval, + dynamicprioritypolling: ts.WatchFileKind.DynamicPriorityPolling, + fixedchunksizepolling: ts.WatchFileKind.FixedChunkSizePolling, + usefsevents: ts.WatchFileKind.UseFsEvents, + usefseventsonparentdirectory: ts.WatchFileKind.UseFsEventsOnParentDirectory, })), - category: Diagnostics.Watch_and_Build_Modes, - description: Diagnostics.Specify_how_the_TypeScript_watch_mode_works, - defaultValueDescription: WatchFileKind.UseFsEvents, + category: ts.Diagnostics.Watch_and_Build_Modes, + description: ts.Diagnostics.Specify_how_the_TypeScript_watch_mode_works, + defaultValueDescription: ts.WatchFileKind.UseFsEvents, }, { name: "watchDirectory", - type: new Map(getEntries({ - usefsevents: WatchDirectoryKind.UseFsEvents, - fixedpollinginterval: WatchDirectoryKind.FixedPollingInterval, - dynamicprioritypolling: WatchDirectoryKind.DynamicPriorityPolling, - fixedchunksizepolling: WatchDirectoryKind.FixedChunkSizePolling, + type: new ts.Map(ts.getEntries({ + usefsevents: ts.WatchDirectoryKind.UseFsEvents, + fixedpollinginterval: ts.WatchDirectoryKind.FixedPollingInterval, + dynamicprioritypolling: ts.WatchDirectoryKind.DynamicPriorityPolling, + fixedchunksizepolling: ts.WatchDirectoryKind.FixedChunkSizePolling, })), - category: Diagnostics.Watch_and_Build_Modes, - description: Diagnostics.Specify_how_directories_are_watched_on_systems_that_lack_recursive_file_watching_functionality, - defaultValueDescription: WatchDirectoryKind.UseFsEvents, + category: ts.Diagnostics.Watch_and_Build_Modes, + description: ts.Diagnostics.Specify_how_directories_are_watched_on_systems_that_lack_recursive_file_watching_functionality, + defaultValueDescription: ts.WatchDirectoryKind.UseFsEvents, }, { name: "fallbackPolling", - type: new Map(getEntries({ - fixedinterval: PollingWatchKind.FixedInterval, - priorityinterval: PollingWatchKind.PriorityInterval, - dynamicpriority: PollingWatchKind.DynamicPriority, - fixedchunksize: PollingWatchKind.FixedChunkSize, + type: new ts.Map(ts.getEntries({ + fixedinterval: ts.PollingWatchKind.FixedInterval, + priorityinterval: ts.PollingWatchKind.PriorityInterval, + dynamicpriority: ts.PollingWatchKind.DynamicPriority, + fixedchunksize: ts.PollingWatchKind.FixedChunkSize, })), - category: Diagnostics.Watch_and_Build_Modes, - description: Diagnostics.Specify_what_approach_the_watcher_should_use_if_the_system_runs_out_of_native_file_watchers, - defaultValueDescription: PollingWatchKind.PriorityInterval, + category: ts.Diagnostics.Watch_and_Build_Modes, + description: ts.Diagnostics.Specify_what_approach_the_watcher_should_use_if_the_system_runs_out_of_native_file_watchers, + defaultValueDescription: ts.PollingWatchKind.PriorityInterval, }, { name: "synchronousWatchDirectory", type: "boolean", - category: Diagnostics.Watch_and_Build_Modes, - description: Diagnostics.Synchronously_call_callbacks_and_update_the_state_of_directory_watchers_on_platforms_that_don_t_support_recursive_watching_natively, + category: ts.Diagnostics.Watch_and_Build_Modes, + description: ts.Diagnostics.Synchronously_call_callbacks_and_update_the_state_of_directory_watchers_on_platforms_that_don_t_support_recursive_watching_natively, defaultValueDescription: false, }, { @@ -166,8 +172,8 @@ namespace ts { isFilePath: true, extraValidation: specToDiagnostic }, - category: Diagnostics.Watch_and_Build_Modes, - description: Diagnostics.Remove_a_list_of_directories_from_the_watch_process, + category: ts.Diagnostics.Watch_and_Build_Modes, + description: ts.Diagnostics.Remove_a_list_of_directories_from_the_watch_process, }, { name: "excludeFiles", @@ -178,20 +184,20 @@ namespace ts { isFilePath: true, extraValidation: specToDiagnostic }, - category: Diagnostics.Watch_and_Build_Modes, - description: Diagnostics.Remove_a_list_of_files_from_the_watch_mode_s_processing, + category: ts.Diagnostics.Watch_and_Build_Modes, + description: ts.Diagnostics.Remove_a_list_of_files_from_the_watch_mode_s_processing, }, ]; /* @internal */ - export const commonOptionsWithBuild: CommandLineOption[] = [ + export const commonOptionsWithBuild: ts.CommandLineOption[] = [ { name: "help", shortName: "h", type: "boolean", showInSimplifiedHelpView: true, - category: Diagnostics.Command_line_Options, - description: Diagnostics.Print_this_message, + category: ts.Diagnostics.Command_line_Options, + description: ts.Diagnostics.Print_this_message, defaultValueDescription: false, }, { @@ -206,75 +212,75 @@ namespace ts { type: "boolean", showInSimplifiedHelpView: true, isCommandLineOnly: true, - category: Diagnostics.Command_line_Options, - description: Diagnostics.Watch_input_files, + category: ts.Diagnostics.Command_line_Options, + description: ts.Diagnostics.Watch_input_files, defaultValueDescription: false, }, { name: "preserveWatchOutput", type: "boolean", showInSimplifiedHelpView: false, - category: Diagnostics.Output_Formatting, - description: Diagnostics.Disable_wiping_the_console_in_watch_mode, + category: ts.Diagnostics.Output_Formatting, + description: ts.Diagnostics.Disable_wiping_the_console_in_watch_mode, defaultValueDescription: false, }, { name: "listFiles", type: "boolean", - category: Diagnostics.Compiler_Diagnostics, - description: Diagnostics.Print_all_of_the_files_read_during_the_compilation, + category: ts.Diagnostics.Compiler_Diagnostics, + description: ts.Diagnostics.Print_all_of_the_files_read_during_the_compilation, defaultValueDescription: false, }, { name: "explainFiles", type: "boolean", - category: Diagnostics.Compiler_Diagnostics, - description: Diagnostics.Print_files_read_during_the_compilation_including_why_it_was_included, + category: ts.Diagnostics.Compiler_Diagnostics, + description: ts.Diagnostics.Print_files_read_during_the_compilation_including_why_it_was_included, defaultValueDescription: false, }, { name: "listEmittedFiles", type: "boolean", - category: Diagnostics.Compiler_Diagnostics, - description: Diagnostics.Print_the_names_of_emitted_files_after_a_compilation, + category: ts.Diagnostics.Compiler_Diagnostics, + description: ts.Diagnostics.Print_the_names_of_emitted_files_after_a_compilation, defaultValueDescription: false, }, { name: "pretty", type: "boolean", showInSimplifiedHelpView: true, - category: Diagnostics.Output_Formatting, - description: Diagnostics.Enable_color_and_formatting_in_TypeScript_s_output_to_make_compiler_errors_easier_to_read, + category: ts.Diagnostics.Output_Formatting, + description: ts.Diagnostics.Enable_color_and_formatting_in_TypeScript_s_output_to_make_compiler_errors_easier_to_read, defaultValueDescription: true, }, { name: "traceResolution", type: "boolean", - category: Diagnostics.Compiler_Diagnostics, - description: Diagnostics.Log_paths_used_during_the_moduleResolution_process, + category: ts.Diagnostics.Compiler_Diagnostics, + description: ts.Diagnostics.Log_paths_used_during_the_moduleResolution_process, defaultValueDescription: false, }, { name: "diagnostics", type: "boolean", - category: Diagnostics.Compiler_Diagnostics, - description: Diagnostics.Output_compiler_performance_information_after_building, + category: ts.Diagnostics.Compiler_Diagnostics, + description: ts.Diagnostics.Output_compiler_performance_information_after_building, defaultValueDescription: false, }, { name: "extendedDiagnostics", type: "boolean", - category: Diagnostics.Compiler_Diagnostics, - description: Diagnostics.Output_more_detailed_compiler_performance_information_after_building, + category: ts.Diagnostics.Compiler_Diagnostics, + description: ts.Diagnostics.Output_more_detailed_compiler_performance_information_after_building, defaultValueDescription: false, }, { name: "generateCpuProfile", type: "string", isFilePath: true, - paramType: Diagnostics.FILE_OR_DIRECTORY, - category: Diagnostics.Compiler_Diagnostics, - description: Diagnostics.Emit_a_v8_CPU_profile_of_the_compiler_run_for_debugging, + paramType: ts.Diagnostics.FILE_OR_DIRECTORY, + category: ts.Diagnostics.Compiler_Diagnostics, + description: ts.Diagnostics.Emit_a_v8_CPU_profile_of_the_compiler_run_for_debugging, defaultValueDescription: "profile.cpuprofile" }, { @@ -282,74 +288,74 @@ namespace ts { type: "string", isFilePath: true, isCommandLineOnly: true, - paramType: Diagnostics.DIRECTORY, - category: Diagnostics.Compiler_Diagnostics, - description: Diagnostics.Generates_an_event_trace_and_a_list_of_types + paramType: ts.Diagnostics.DIRECTORY, + category: ts.Diagnostics.Compiler_Diagnostics, + description: ts.Diagnostics.Generates_an_event_trace_and_a_list_of_types }, { name: "incremental", shortName: "i", type: "boolean", - category: Diagnostics.Projects, - description: Diagnostics.Save_tsbuildinfo_files_to_allow_for_incremental_compilation_of_projects, + category: ts.Diagnostics.Projects, + description: ts.Diagnostics.Save_tsbuildinfo_files_to_allow_for_incremental_compilation_of_projects, transpileOptionValue: undefined, - defaultValueDescription: Diagnostics.false_unless_composite_is_set + defaultValueDescription: ts.Diagnostics.false_unless_composite_is_set }, { name: "assumeChangesOnlyAffectDirectDependencies", type: "boolean", affectsSemanticDiagnostics: true, affectsEmit: true, - category: Diagnostics.Watch_and_Build_Modes, - description: Diagnostics.Have_recompiles_in_projects_that_use_incremental_and_watch_mode_assume_that_changes_within_a_file_will_only_affect_files_directly_depending_on_it, + category: ts.Diagnostics.Watch_and_Build_Modes, + description: ts.Diagnostics.Have_recompiles_in_projects_that_use_incremental_and_watch_mode_assume_that_changes_within_a_file_will_only_affect_files_directly_depending_on_it, defaultValueDescription: false, }, { name: "locale", type: "string", - category: Diagnostics.Command_line_Options, + category: ts.Diagnostics.Command_line_Options, isCommandLineOnly: true, - description: Diagnostics.Set_the_language_of_the_messaging_from_TypeScript_This_does_not_affect_emit, - defaultValueDescription: Diagnostics.Platform_specific + description: ts.Diagnostics.Set_the_language_of_the_messaging_from_TypeScript_This_does_not_affect_emit, + defaultValueDescription: ts.Diagnostics.Platform_specific }, ]; /* @internal */ - export const targetOptionDeclaration: CommandLineOptionOfCustomType = { + export const targetOptionDeclaration: ts.CommandLineOptionOfCustomType = { name: "target", shortName: "t", - type: new Map(getEntries({ - es3: ScriptTarget.ES3, - es5: ScriptTarget.ES5, - es6: ScriptTarget.ES2015, - es2015: ScriptTarget.ES2015, - es2016: ScriptTarget.ES2016, - es2017: ScriptTarget.ES2017, - es2018: ScriptTarget.ES2018, - es2019: ScriptTarget.ES2019, - es2020: ScriptTarget.ES2020, - es2021: ScriptTarget.ES2021, - es2022: ScriptTarget.ES2022, - esnext: ScriptTarget.ESNext, + type: new ts.Map(ts.getEntries({ + es3: ts.ScriptTarget.ES3, + es5: ts.ScriptTarget.ES5, + es6: ts.ScriptTarget.ES2015, + es2015: ts.ScriptTarget.ES2015, + es2016: ts.ScriptTarget.ES2016, + es2017: ts.ScriptTarget.ES2017, + es2018: ts.ScriptTarget.ES2018, + es2019: ts.ScriptTarget.ES2019, + es2020: ts.ScriptTarget.ES2020, + es2021: ts.ScriptTarget.ES2021, + es2022: ts.ScriptTarget.ES2022, + esnext: ts.ScriptTarget.ESNext, })), affectsSourceFile: true, affectsModuleResolution: true, affectsEmit: true, - paramType: Diagnostics.VERSION, + paramType: ts.Diagnostics.VERSION, showInSimplifiedHelpView: true, - category: Diagnostics.Language_and_Environment, - description: Diagnostics.Set_the_JavaScript_language_version_for_emitted_JavaScript_and_include_compatible_library_declarations, - defaultValueDescription: ScriptTarget.ES3, + category: ts.Diagnostics.Language_and_Environment, + description: ts.Diagnostics.Set_the_JavaScript_language_version_for_emitted_JavaScript_and_include_compatible_library_declarations, + defaultValueDescription: ts.ScriptTarget.ES3, }; - const commandOptionsWithoutBuild: CommandLineOption[] = [ + const commandOptionsWithoutBuild: ts.CommandLineOption[] = [ // CommandLine only options { name: "all", type: "boolean", showInSimplifiedHelpView: true, - category: Diagnostics.Command_line_Options, - description: Diagnostics.Show_all_compiler_options, + category: ts.Diagnostics.Command_line_Options, + description: ts.Diagnostics.Show_all_compiler_options, defaultValueDescription: false, }, { @@ -357,16 +363,16 @@ namespace ts { shortName: "v", type: "boolean", showInSimplifiedHelpView: true, - category: Diagnostics.Command_line_Options, - description: Diagnostics.Print_the_compiler_s_version, + category: ts.Diagnostics.Command_line_Options, + description: ts.Diagnostics.Print_the_compiler_s_version, defaultValueDescription: false, }, { name: "init", type: "boolean", showInSimplifiedHelpView: true, - category: Diagnostics.Command_line_Options, - description: Diagnostics.Initializes_a_TypeScript_project_and_creates_a_tsconfig_json_file, + category: ts.Diagnostics.Command_line_Options, + description: ts.Diagnostics.Initializes_a_TypeScript_project_and_creates_a_tsconfig_json_file, defaultValueDescription: false, }, { @@ -375,36 +381,36 @@ namespace ts { type: "string", isFilePath: true, showInSimplifiedHelpView: true, - category: Diagnostics.Command_line_Options, - paramType: Diagnostics.FILE_OR_DIRECTORY, - description: Diagnostics.Compile_the_project_given_the_path_to_its_configuration_file_or_to_a_folder_with_a_tsconfig_json, + category: ts.Diagnostics.Command_line_Options, + paramType: ts.Diagnostics.FILE_OR_DIRECTORY, + description: ts.Diagnostics.Compile_the_project_given_the_path_to_its_configuration_file_or_to_a_folder_with_a_tsconfig_json, }, { name: "build", type: "boolean", shortName: "b", showInSimplifiedHelpView: true, - category: Diagnostics.Command_line_Options, - description: Diagnostics.Build_one_or_more_projects_and_their_dependencies_if_out_of_date, + category: ts.Diagnostics.Command_line_Options, + description: ts.Diagnostics.Build_one_or_more_projects_and_their_dependencies_if_out_of_date, defaultValueDescription: false, }, { name: "showConfig", type: "boolean", showInSimplifiedHelpView: true, - category: Diagnostics.Command_line_Options, + category: ts.Diagnostics.Command_line_Options, isCommandLineOnly: true, - description: Diagnostics.Print_the_final_configuration_instead_of_building, + description: ts.Diagnostics.Print_the_final_configuration_instead_of_building, defaultValueDescription: false, }, { name: "listFilesOnly", type: "boolean", - category: Diagnostics.Command_line_Options, + category: ts.Diagnostics.Command_line_Options, affectsSemanticDiagnostics: true, affectsEmit: true, isCommandLineOnly: true, - description: Diagnostics.Print_names_of_files_that_are_part_of_the_compilation_and_then_stop_processing, + description: ts.Diagnostics.Print_names_of_files_that_are_part_of_the_compilation_and_then_stop_processing, defaultValueDescription: false, }, @@ -413,26 +419,26 @@ namespace ts { { name: "module", shortName: "m", - type: new Map(getEntries({ - none: ModuleKind.None, - commonjs: ModuleKind.CommonJS, - amd: ModuleKind.AMD, - system: ModuleKind.System, - umd: ModuleKind.UMD, - es6: ModuleKind.ES2015, - es2015: ModuleKind.ES2015, - es2020: ModuleKind.ES2020, - es2022: ModuleKind.ES2022, - esnext: ModuleKind.ESNext, - node16: ModuleKind.Node16, - nodenext: ModuleKind.NodeNext, + type: new ts.Map(ts.getEntries({ + none: ts.ModuleKind.None, + commonjs: ts.ModuleKind.CommonJS, + amd: ts.ModuleKind.AMD, + system: ts.ModuleKind.System, + umd: ts.ModuleKind.UMD, + es6: ts.ModuleKind.ES2015, + es2015: ts.ModuleKind.ES2015, + es2020: ts.ModuleKind.ES2020, + es2022: ts.ModuleKind.ES2022, + esnext: ts.ModuleKind.ESNext, + node16: ts.ModuleKind.Node16, + nodenext: ts.ModuleKind.NodeNext, })), affectsModuleResolution: true, affectsEmit: true, - paramType: Diagnostics.KIND, + paramType: ts.Diagnostics.KIND, showInSimplifiedHelpView: true, - category: Diagnostics.Modules, - description: Diagnostics.Specify_what_module_code_is_generated, + category: ts.Diagnostics.Modules, + description: ts.Diagnostics.Specify_what_module_code_is_generated, defaultValueDescription: undefined, }, { @@ -445,8 +451,8 @@ namespace ts { }, affectsProgramStructure: true, showInSimplifiedHelpView: true, - category: Diagnostics.Language_and_Environment, - description: Diagnostics.Specify_a_set_of_bundled_library_declaration_files_that_describe_the_target_runtime_environment, + category: ts.Diagnostics.Language_and_Environment, + description: ts.Diagnostics.Specify_a_set_of_bundled_library_declaration_files_that_describe_the_target_runtime_environment, transpileOptionValue: undefined }, { @@ -454,16 +460,16 @@ namespace ts { type: "boolean", affectsModuleResolution: true, showInSimplifiedHelpView: true, - category: Diagnostics.JavaScript_Support, - description: Diagnostics.Allow_JavaScript_files_to_be_a_part_of_your_program_Use_the_checkJS_option_to_get_errors_from_these_files, + category: ts.Diagnostics.JavaScript_Support, + description: ts.Diagnostics.Allow_JavaScript_files_to_be_a_part_of_your_program_Use_the_checkJS_option_to_get_errors_from_these_files, defaultValueDescription: false, }, { name: "checkJs", type: "boolean", showInSimplifiedHelpView: true, - category: Diagnostics.JavaScript_Support, - description: Diagnostics.Enable_error_reporting_in_type_checked_JavaScript_files, + category: ts.Diagnostics.JavaScript_Support, + description: ts.Diagnostics.Enable_error_reporting_in_type_checked_JavaScript_files, defaultValueDescription: false, }, { @@ -472,10 +478,10 @@ namespace ts { affectsSourceFile: true, affectsEmit: true, affectsModuleResolution: true, - paramType: Diagnostics.KIND, + paramType: ts.Diagnostics.KIND, showInSimplifiedHelpView: true, - category: Diagnostics.Language_and_Environment, - description: Diagnostics.Specify_what_JSX_code_is_generated, + category: ts.Diagnostics.Language_and_Environment, + description: ts.Diagnostics.Specify_what_JSX_code_is_generated, defaultValueDescription: undefined, }, { @@ -484,20 +490,20 @@ namespace ts { type: "boolean", affectsEmit: true, showInSimplifiedHelpView: true, - category: Diagnostics.Emit, + category: ts.Diagnostics.Emit, transpileOptionValue: undefined, - description: Diagnostics.Generate_d_ts_files_from_TypeScript_and_JavaScript_files_in_your_project, - defaultValueDescription: Diagnostics.false_unless_composite_is_set, + description: ts.Diagnostics.Generate_d_ts_files_from_TypeScript_and_JavaScript_files_in_your_project, + defaultValueDescription: ts.Diagnostics.false_unless_composite_is_set, }, { name: "declarationMap", type: "boolean", affectsEmit: true, showInSimplifiedHelpView: true, - category: Diagnostics.Emit, + category: ts.Diagnostics.Emit, transpileOptionValue: undefined, defaultValueDescription: false, - description: Diagnostics.Create_sourcemaps_for_d_ts_files + description: ts.Diagnostics.Create_sourcemaps_for_d_ts_files }, { name: "emitDeclarationOnly", @@ -505,8 +511,8 @@ namespace ts { affectsEmit: true, showInSimplifiedHelpView: true, - category: Diagnostics.Emit, - description: Diagnostics.Only_output_d_ts_files_and_not_JavaScript_files, + category: ts.Diagnostics.Emit, + description: ts.Diagnostics.Only_output_d_ts_files_and_not_JavaScript_files, transpileOptionValue: undefined, defaultValueDescription: false, }, @@ -515,19 +521,19 @@ namespace ts { type: "boolean", affectsEmit: true, showInSimplifiedHelpView: true, - category: Diagnostics.Emit, + category: ts.Diagnostics.Emit, defaultValueDescription: false, - description: Diagnostics.Create_source_map_files_for_emitted_JavaScript_files, + description: ts.Diagnostics.Create_source_map_files_for_emitted_JavaScript_files, }, { name: "outFile", type: "string", affectsEmit: true, isFilePath: true, - paramType: Diagnostics.FILE, + paramType: ts.Diagnostics.FILE, showInSimplifiedHelpView: true, - category: Diagnostics.Emit, - description: Diagnostics.Specify_a_file_that_bundles_all_outputs_into_one_JavaScript_file_If_declaration_is_true_also_designates_a_file_that_bundles_all_d_ts_output, + category: ts.Diagnostics.Emit, + description: ts.Diagnostics.Specify_a_file_that_bundles_all_outputs_into_one_JavaScript_file_If_declaration_is_true_also_designates_a_file_that_bundles_all_d_ts_output, transpileOptionValue: undefined, }, { @@ -535,57 +541,57 @@ namespace ts { type: "string", affectsEmit: true, isFilePath: true, - paramType: Diagnostics.DIRECTORY, + paramType: ts.Diagnostics.DIRECTORY, showInSimplifiedHelpView: true, - category: Diagnostics.Emit, - description: Diagnostics.Specify_an_output_folder_for_all_emitted_files, + category: ts.Diagnostics.Emit, + description: ts.Diagnostics.Specify_an_output_folder_for_all_emitted_files, }, { name: "rootDir", type: "string", affectsEmit: true, isFilePath: true, - paramType: Diagnostics.LOCATION, - category: Diagnostics.Modules, - description: Diagnostics.Specify_the_root_folder_within_your_source_files, - defaultValueDescription: Diagnostics.Computed_from_the_list_of_input_files + paramType: ts.Diagnostics.LOCATION, + category: ts.Diagnostics.Modules, + description: ts.Diagnostics.Specify_the_root_folder_within_your_source_files, + defaultValueDescription: ts.Diagnostics.Computed_from_the_list_of_input_files }, { name: "composite", type: "boolean", affectsEmit: true, isTSConfigOnly: true, - category: Diagnostics.Projects, + category: ts.Diagnostics.Projects, transpileOptionValue: undefined, defaultValueDescription: false, - description: Diagnostics.Enable_constraints_that_allow_a_TypeScript_project_to_be_used_with_project_references, + description: ts.Diagnostics.Enable_constraints_that_allow_a_TypeScript_project_to_be_used_with_project_references, }, { name: "tsBuildInfoFile", type: "string", affectsEmit: true, isFilePath: true, - paramType: Diagnostics.FILE, - category: Diagnostics.Projects, + paramType: ts.Diagnostics.FILE, + category: ts.Diagnostics.Projects, transpileOptionValue: undefined, defaultValueDescription: ".tsbuildinfo", - description: Diagnostics.Specify_the_path_to_tsbuildinfo_incremental_compilation_file, + description: ts.Diagnostics.Specify_the_path_to_tsbuildinfo_incremental_compilation_file, }, { name: "removeComments", type: "boolean", affectsEmit: true, showInSimplifiedHelpView: true, - category: Diagnostics.Emit, + category: ts.Diagnostics.Emit, defaultValueDescription: false, - description: Diagnostics.Disable_emitting_comments, + description: ts.Diagnostics.Disable_emitting_comments, }, { name: "noEmit", type: "boolean", showInSimplifiedHelpView: true, - category: Diagnostics.Emit, - description: Diagnostics.Disable_emitting_files_from_a_compilation, + category: ts.Diagnostics.Emit, + description: ts.Diagnostics.Disable_emitting_files_from_a_compilation, transpileOptionValue: undefined, defaultValueDescription: false, }, @@ -593,36 +599,36 @@ namespace ts { name: "importHelpers", type: "boolean", affectsEmit: true, - category: Diagnostics.Emit, - description: Diagnostics.Allow_importing_helper_functions_from_tslib_once_per_project_instead_of_including_them_per_file, + category: ts.Diagnostics.Emit, + description: ts.Diagnostics.Allow_importing_helper_functions_from_tslib_once_per_project_instead_of_including_them_per_file, defaultValueDescription: false, }, { name: "importsNotUsedAsValues", - type: new Map(getEntries({ - remove: ImportsNotUsedAsValues.Remove, - preserve: ImportsNotUsedAsValues.Preserve, - error: ImportsNotUsedAsValues.Error, + type: new ts.Map(ts.getEntries({ + remove: ts.ImportsNotUsedAsValues.Remove, + preserve: ts.ImportsNotUsedAsValues.Preserve, + error: ts.ImportsNotUsedAsValues.Error, })), affectsEmit: true, affectsSemanticDiagnostics: true, - category: Diagnostics.Emit, - description: Diagnostics.Specify_emit_Slashchecking_behavior_for_imports_that_are_only_used_for_types, - defaultValueDescription: ImportsNotUsedAsValues.Remove, + category: ts.Diagnostics.Emit, + description: ts.Diagnostics.Specify_emit_Slashchecking_behavior_for_imports_that_are_only_used_for_types, + defaultValueDescription: ts.ImportsNotUsedAsValues.Remove, }, { name: "downlevelIteration", type: "boolean", affectsEmit: true, - category: Diagnostics.Emit, - description: Diagnostics.Emit_more_compliant_but_verbose_and_less_performant_JavaScript_for_iteration, + category: ts.Diagnostics.Emit, + description: ts.Diagnostics.Emit_more_compliant_but_verbose_and_less_performant_JavaScript_for_iteration, defaultValueDescription: false, }, { name: "isolatedModules", type: "boolean", - category: Diagnostics.Interop_Constraints, - description: Diagnostics.Ensure_that_each_file_can_be_safely_transpiled_without_relying_on_other_imports, + category: ts.Diagnostics.Interop_Constraints, + description: ts.Diagnostics.Ensure_that_each_file_can_be_safely_transpiled_without_relying_on_other_imports, transpileOptionValue: true, defaultValueDescription: false, }, @@ -634,8 +640,8 @@ namespace ts { // Though this affects semantic diagnostics, affectsSemanticDiagnostics is not set here // The value of each strictFlag depends on own strictFlag value or this and never accessed directly. showInSimplifiedHelpView: true, - category: Diagnostics.Type_Checking, - description: Diagnostics.Enable_all_strict_type_checking_options, + category: ts.Diagnostics.Type_Checking, + description: ts.Diagnostics.Enable_all_strict_type_checking_options, defaultValueDescription: false, }, { @@ -643,60 +649,60 @@ namespace ts { type: "boolean", affectsSemanticDiagnostics: true, strictFlag: true, - category: Diagnostics.Type_Checking, - description: Diagnostics.Enable_error_reporting_for_expressions_and_declarations_with_an_implied_any_type, - defaultValueDescription: Diagnostics.false_unless_strict_is_set + category: ts.Diagnostics.Type_Checking, + description: ts.Diagnostics.Enable_error_reporting_for_expressions_and_declarations_with_an_implied_any_type, + defaultValueDescription: ts.Diagnostics.false_unless_strict_is_set }, { name: "strictNullChecks", type: "boolean", affectsSemanticDiagnostics: true, strictFlag: true, - category: Diagnostics.Type_Checking, - description: Diagnostics.When_type_checking_take_into_account_null_and_undefined, - defaultValueDescription: Diagnostics.false_unless_strict_is_set + category: ts.Diagnostics.Type_Checking, + description: ts.Diagnostics.When_type_checking_take_into_account_null_and_undefined, + defaultValueDescription: ts.Diagnostics.false_unless_strict_is_set }, { name: "strictFunctionTypes", type: "boolean", strictFlag: true, - category: Diagnostics.Type_Checking, - description: Diagnostics.When_assigning_functions_check_to_ensure_parameters_and_the_return_values_are_subtype_compatible, - defaultValueDescription: Diagnostics.false_unless_strict_is_set + category: ts.Diagnostics.Type_Checking, + description: ts.Diagnostics.When_assigning_functions_check_to_ensure_parameters_and_the_return_values_are_subtype_compatible, + defaultValueDescription: ts.Diagnostics.false_unless_strict_is_set }, { name: "strictBindCallApply", type: "boolean", strictFlag: true, - category: Diagnostics.Type_Checking, - description: Diagnostics.Check_that_the_arguments_for_bind_call_and_apply_methods_match_the_original_function, - defaultValueDescription: Diagnostics.false_unless_strict_is_set + category: ts.Diagnostics.Type_Checking, + description: ts.Diagnostics.Check_that_the_arguments_for_bind_call_and_apply_methods_match_the_original_function, + defaultValueDescription: ts.Diagnostics.false_unless_strict_is_set }, { name: "strictPropertyInitialization", type: "boolean", affectsSemanticDiagnostics: true, strictFlag: true, - category: Diagnostics.Type_Checking, - description: Diagnostics.Check_for_class_properties_that_are_declared_but_not_set_in_the_constructor, - defaultValueDescription: Diagnostics.false_unless_strict_is_set + category: ts.Diagnostics.Type_Checking, + description: ts.Diagnostics.Check_for_class_properties_that_are_declared_but_not_set_in_the_constructor, + defaultValueDescription: ts.Diagnostics.false_unless_strict_is_set }, { name: "noImplicitThis", type: "boolean", affectsSemanticDiagnostics: true, strictFlag: true, - category: Diagnostics.Type_Checking, - description: Diagnostics.Enable_error_reporting_when_this_is_given_the_type_any, - defaultValueDescription: Diagnostics.false_unless_strict_is_set + category: ts.Diagnostics.Type_Checking, + description: ts.Diagnostics.Enable_error_reporting_when_this_is_given_the_type_any, + defaultValueDescription: ts.Diagnostics.false_unless_strict_is_set }, { name: "useUnknownInCatchVariables", type: "boolean", affectsSemanticDiagnostics: true, strictFlag: true, - category: Diagnostics.Type_Checking, - description: Diagnostics.Default_catch_clause_variables_as_unknown_instead_of_any, + category: ts.Diagnostics.Type_Checking, + description: ts.Diagnostics.Default_catch_clause_variables_as_unknown_instead_of_any, defaultValueDescription: false, }, { @@ -704,9 +710,9 @@ namespace ts { type: "boolean", affectsSourceFile: true, strictFlag: true, - category: Diagnostics.Type_Checking, - description: Diagnostics.Ensure_use_strict_is_always_emitted, - defaultValueDescription: Diagnostics.false_unless_strict_is_set + category: ts.Diagnostics.Type_Checking, + description: ts.Diagnostics.Ensure_use_strict_is_always_emitted, + defaultValueDescription: ts.Diagnostics.false_unless_strict_is_set }, // Additional Checks @@ -714,32 +720,32 @@ namespace ts { name: "noUnusedLocals", type: "boolean", affectsSemanticDiagnostics: true, - category: Diagnostics.Type_Checking, - description: Diagnostics.Enable_error_reporting_when_local_variables_aren_t_read, + category: ts.Diagnostics.Type_Checking, + description: ts.Diagnostics.Enable_error_reporting_when_local_variables_aren_t_read, defaultValueDescription: false, }, { name: "noUnusedParameters", type: "boolean", affectsSemanticDiagnostics: true, - category: Diagnostics.Type_Checking, - description: Diagnostics.Raise_an_error_when_a_function_parameter_isn_t_read, + category: ts.Diagnostics.Type_Checking, + description: ts.Diagnostics.Raise_an_error_when_a_function_parameter_isn_t_read, defaultValueDescription: false, }, { name: "exactOptionalPropertyTypes", type: "boolean", affectsSemanticDiagnostics: true, - category: Diagnostics.Type_Checking, - description: Diagnostics.Interpret_optional_property_types_as_written_rather_than_adding_undefined, + category: ts.Diagnostics.Type_Checking, + description: ts.Diagnostics.Interpret_optional_property_types_as_written_rather_than_adding_undefined, defaultValueDescription: false, }, { name: "noImplicitReturns", type: "boolean", affectsSemanticDiagnostics: true, - category: Diagnostics.Type_Checking, - description: Diagnostics.Enable_error_reporting_for_codepaths_that_do_not_explicitly_return_in_a_function, + category: ts.Diagnostics.Type_Checking, + description: ts.Diagnostics.Enable_error_reporting_for_codepaths_that_do_not_explicitly_return_in_a_function, defaultValueDescription: false, }, { @@ -747,57 +753,57 @@ namespace ts { type: "boolean", affectsBindDiagnostics: true, affectsSemanticDiagnostics: true, - category: Diagnostics.Type_Checking, - description: Diagnostics.Enable_error_reporting_for_fallthrough_cases_in_switch_statements, + category: ts.Diagnostics.Type_Checking, + description: ts.Diagnostics.Enable_error_reporting_for_fallthrough_cases_in_switch_statements, defaultValueDescription: false, }, { name: "noUncheckedIndexedAccess", type: "boolean", affectsSemanticDiagnostics: true, - category: Diagnostics.Type_Checking, - description: Diagnostics.Add_undefined_to_a_type_when_accessed_using_an_index, + category: ts.Diagnostics.Type_Checking, + description: ts.Diagnostics.Add_undefined_to_a_type_when_accessed_using_an_index, defaultValueDescription: false, }, { name: "noImplicitOverride", type: "boolean", affectsSemanticDiagnostics: true, - category: Diagnostics.Type_Checking, - description: Diagnostics.Ensure_overriding_members_in_derived_classes_are_marked_with_an_override_modifier, + category: ts.Diagnostics.Type_Checking, + description: ts.Diagnostics.Ensure_overriding_members_in_derived_classes_are_marked_with_an_override_modifier, defaultValueDescription: false, }, { name: "noPropertyAccessFromIndexSignature", type: "boolean", showInSimplifiedHelpView: false, - category: Diagnostics.Type_Checking, - description: Diagnostics.Enforces_using_indexed_accessors_for_keys_declared_using_an_indexed_type, + category: ts.Diagnostics.Type_Checking, + description: ts.Diagnostics.Enforces_using_indexed_accessors_for_keys_declared_using_an_indexed_type, defaultValueDescription: false, }, // Module Resolution { name: "moduleResolution", - type: new Map(getEntries({ - node: ModuleResolutionKind.NodeJs, - classic: ModuleResolutionKind.Classic, - node16: ModuleResolutionKind.Node16, - nodenext: ModuleResolutionKind.NodeNext, + type: new ts.Map(ts.getEntries({ + node: ts.ModuleResolutionKind.NodeJs, + classic: ts.ModuleResolutionKind.Classic, + node16: ts.ModuleResolutionKind.Node16, + nodenext: ts.ModuleResolutionKind.NodeNext, })), affectsModuleResolution: true, - paramType: Diagnostics.STRATEGY, - category: Diagnostics.Modules, - description: Diagnostics.Specify_how_TypeScript_looks_up_a_file_from_a_given_module_specifier, - defaultValueDescription: Diagnostics.module_AMD_or_UMD_or_System_or_ES6_then_Classic_Otherwise_Node + paramType: ts.Diagnostics.STRATEGY, + category: ts.Diagnostics.Modules, + description: ts.Diagnostics.Specify_how_TypeScript_looks_up_a_file_from_a_given_module_specifier, + defaultValueDescription: ts.Diagnostics.module_AMD_or_UMD_or_System_or_ES6_then_Classic_Otherwise_Node }, { name: "baseUrl", type: "string", affectsModuleResolution: true, isFilePath: true, - category: Diagnostics.Modules, - description: Diagnostics.Specify_the_base_directory_to_resolve_non_relative_module_names + category: ts.Diagnostics.Modules, + description: ts.Diagnostics.Specify_the_base_directory_to_resolve_non_relative_module_names }, { // this option can only be specified in tsconfig.json @@ -806,8 +812,8 @@ namespace ts { type: "object", affectsModuleResolution: true, isTSConfigOnly: true, - category: Diagnostics.Modules, - description: Diagnostics.Specify_a_set_of_entries_that_re_map_imports_to_additional_lookup_locations, + category: ts.Diagnostics.Modules, + description: ts.Diagnostics.Specify_a_set_of_entries_that_re_map_imports_to_additional_lookup_locations, transpileOptionValue: undefined }, { @@ -822,10 +828,10 @@ namespace ts { isFilePath: true }, affectsModuleResolution: true, - category: Diagnostics.Modules, - description: Diagnostics.Allow_multiple_folders_to_be_treated_as_one_when_resolving_modules, + category: ts.Diagnostics.Modules, + description: ts.Diagnostics.Allow_multiple_folders_to_be_treated_as_one_when_resolving_modules, transpileOptionValue: undefined, - defaultValueDescription: Diagnostics.Computed_from_the_list_of_input_files + defaultValueDescription: ts.Diagnostics.Computed_from_the_list_of_input_files }, { name: "typeRoots", @@ -836,8 +842,8 @@ namespace ts { isFilePath: true }, affectsModuleResolution: true, - category: Diagnostics.Modules, - description: Diagnostics.Specify_multiple_folders_that_act_like_Slashnode_modules_Slash_types + category: ts.Diagnostics.Modules, + description: ts.Diagnostics.Specify_multiple_folders_that_act_like_Slashnode_modules_Slash_types }, { name: "types", @@ -848,17 +854,17 @@ namespace ts { }, affectsProgramStructure: true, showInSimplifiedHelpView: true, - category: Diagnostics.Modules, - description: Diagnostics.Specify_type_package_names_to_be_included_without_being_referenced_in_a_source_file, + category: ts.Diagnostics.Modules, + description: ts.Diagnostics.Specify_type_package_names_to_be_included_without_being_referenced_in_a_source_file, transpileOptionValue: undefined }, { name: "allowSyntheticDefaultImports", type: "boolean", affectsSemanticDiagnostics: true, - category: Diagnostics.Interop_Constraints, - description: Diagnostics.Allow_import_x_from_y_when_a_module_doesn_t_have_a_default_export, - defaultValueDescription: Diagnostics.module_system_or_esModuleInterop + category: ts.Diagnostics.Interop_Constraints, + description: ts.Diagnostics.Allow_import_x_from_y_when_a_module_doesn_t_have_a_default_export, + defaultValueDescription: ts.Diagnostics.module_system_or_esModuleInterop }, { name: "esModuleInterop", @@ -866,23 +872,23 @@ namespace ts { affectsSemanticDiagnostics: true, affectsEmit: true, showInSimplifiedHelpView: true, - category: Diagnostics.Interop_Constraints, - description: Diagnostics.Emit_additional_JavaScript_to_ease_support_for_importing_CommonJS_modules_This_enables_allowSyntheticDefaultImports_for_type_compatibility, + category: ts.Diagnostics.Interop_Constraints, + description: ts.Diagnostics.Emit_additional_JavaScript_to_ease_support_for_importing_CommonJS_modules_This_enables_allowSyntheticDefaultImports_for_type_compatibility, defaultValueDescription: false, }, { name: "preserveSymlinks", type: "boolean", - category: Diagnostics.Interop_Constraints, - description: Diagnostics.Disable_resolving_symlinks_to_their_realpath_This_correlates_to_the_same_flag_in_node, + category: ts.Diagnostics.Interop_Constraints, + description: ts.Diagnostics.Disable_resolving_symlinks_to_their_realpath_This_correlates_to_the_same_flag_in_node, defaultValueDescription: false, }, { name: "allowUmdGlobalAccess", type: "boolean", affectsSemanticDiagnostics: true, - category: Diagnostics.Modules, - description: Diagnostics.Allow_accessing_UMD_globals_from_modules, + category: ts.Diagnostics.Modules, + description: ts.Diagnostics.Allow_accessing_UMD_globals_from_modules, defaultValueDescription: false, }, { @@ -894,8 +900,8 @@ namespace ts { }, listPreserveFalsyValues: true, affectsModuleResolution: true, - category: Diagnostics.Modules, - description: Diagnostics.List_of_file_name_suffixes_to_search_when_resolving_a_module, + category: ts.Diagnostics.Modules, + description: ts.Diagnostics.List_of_file_name_suffixes_to_search_when_resolving_a_module, }, // Source Maps @@ -903,32 +909,32 @@ namespace ts { name: "sourceRoot", type: "string", affectsEmit: true, - paramType: Diagnostics.LOCATION, - category: Diagnostics.Emit, - description: Diagnostics.Specify_the_root_path_for_debuggers_to_find_the_reference_source_code, + paramType: ts.Diagnostics.LOCATION, + category: ts.Diagnostics.Emit, + description: ts.Diagnostics.Specify_the_root_path_for_debuggers_to_find_the_reference_source_code, }, { name: "mapRoot", type: "string", affectsEmit: true, - paramType: Diagnostics.LOCATION, - category: Diagnostics.Emit, - description: Diagnostics.Specify_the_location_where_debugger_should_locate_map_files_instead_of_generated_locations, + paramType: ts.Diagnostics.LOCATION, + category: ts.Diagnostics.Emit, + description: ts.Diagnostics.Specify_the_location_where_debugger_should_locate_map_files_instead_of_generated_locations, }, { name: "inlineSourceMap", type: "boolean", affectsEmit: true, - category: Diagnostics.Emit, - description: Diagnostics.Include_sourcemap_files_inside_the_emitted_JavaScript, + category: ts.Diagnostics.Emit, + description: ts.Diagnostics.Include_sourcemap_files_inside_the_emitted_JavaScript, defaultValueDescription: false, }, { name: "inlineSources", type: "boolean", affectsEmit: true, - category: Diagnostics.Emit, - description: Diagnostics.Include_source_code_in_the_sourcemaps_inside_the_emitted_JavaScript, + category: ts.Diagnostics.Emit, + description: ts.Diagnostics.Include_source_code_in_the_sourcemaps_inside_the_emitted_JavaScript, defaultValueDescription: false, }, @@ -937,8 +943,8 @@ namespace ts { name: "experimentalDecorators", type: "boolean", affectsSemanticDiagnostics: true, - category: Diagnostics.Language_and_Environment, - description: Diagnostics.Enable_experimental_support_for_TC39_stage_2_draft_decorators, + category: ts.Diagnostics.Language_and_Environment, + description: ts.Diagnostics.Enable_experimental_support_for_TC39_stage_2_draft_decorators, defaultValueDescription: false, }, { @@ -946,8 +952,8 @@ namespace ts { type: "boolean", affectsSemanticDiagnostics: true, affectsEmit: true, - category: Diagnostics.Language_and_Environment, - description: Diagnostics.Emit_design_type_metadata_for_decorated_declarations_in_source_files, + category: ts.Diagnostics.Language_and_Environment, + description: ts.Diagnostics.Emit_design_type_metadata_for_decorated_declarations_in_source_files, defaultValueDescription: false, }, @@ -955,15 +961,15 @@ namespace ts { { name: "jsxFactory", type: "string", - category: Diagnostics.Language_and_Environment, - description: Diagnostics.Specify_the_JSX_factory_function_used_when_targeting_React_JSX_emit_e_g_React_createElement_or_h, + category: ts.Diagnostics.Language_and_Environment, + description: ts.Diagnostics.Specify_the_JSX_factory_function_used_when_targeting_React_JSX_emit_e_g_React_createElement_or_h, defaultValueDescription: "`React.createElement`" }, { name: "jsxFragmentFactory", type: "string", - category: Diagnostics.Language_and_Environment, - description: Diagnostics.Specify_the_JSX_Fragment_reference_used_for_fragments_when_targeting_React_JSX_emit_e_g_React_Fragment_or_Fragment, + category: ts.Diagnostics.Language_and_Environment, + description: ts.Diagnostics.Specify_the_JSX_Fragment_reference_used_for_fragments_when_targeting_React_JSX_emit_e_g_React_Fragment_or_Fragment, defaultValueDescription: "React.Fragment", }, { @@ -972,16 +978,16 @@ namespace ts { affectsSemanticDiagnostics: true, affectsEmit: true, affectsModuleResolution: true, - category: Diagnostics.Language_and_Environment, - description: Diagnostics.Specify_module_specifier_used_to_import_the_JSX_factory_functions_when_using_jsx_Colon_react_jsx_Asterisk, + category: ts.Diagnostics.Language_and_Environment, + description: ts.Diagnostics.Specify_module_specifier_used_to_import_the_JSX_factory_functions_when_using_jsx_Colon_react_jsx_Asterisk, defaultValueDescription: "react" }, { name: "resolveJsonModule", type: "boolean", affectsModuleResolution: true, - category: Diagnostics.Modules, - description: Diagnostics.Enable_importing_json_files, + category: ts.Diagnostics.Modules, + description: ts.Diagnostics.Enable_importing_json_files, defaultValueDescription: false, }, @@ -989,69 +995,69 @@ namespace ts { name: "out", type: "string", affectsEmit: true, - isFilePath: false, // This is intentionally broken to support compatability with existing tsconfig files + isFilePath: false, // for correct behaviour, please use outFile - category: Diagnostics.Backwards_Compatibility, - paramType: Diagnostics.FILE, + category: ts.Diagnostics.Backwards_Compatibility, + paramType: ts.Diagnostics.FILE, transpileOptionValue: undefined, - description: Diagnostics.Deprecated_setting_Use_outFile_instead, + description: ts.Diagnostics.Deprecated_setting_Use_outFile_instead, }, { name: "reactNamespace", type: "string", affectsEmit: true, - category: Diagnostics.Language_and_Environment, - description: Diagnostics.Specify_the_object_invoked_for_createElement_This_only_applies_when_targeting_react_JSX_emit, + category: ts.Diagnostics.Language_and_Environment, + description: ts.Diagnostics.Specify_the_object_invoked_for_createElement_This_only_applies_when_targeting_react_JSX_emit, defaultValueDescription: "`React`", }, { name: "skipDefaultLibCheck", type: "boolean", - category: Diagnostics.Completeness, - description: Diagnostics.Skip_type_checking_d_ts_files_that_are_included_with_TypeScript, + category: ts.Diagnostics.Completeness, + description: ts.Diagnostics.Skip_type_checking_d_ts_files_that_are_included_with_TypeScript, defaultValueDescription: false, }, { name: "charset", type: "string", - category: Diagnostics.Backwards_Compatibility, - description: Diagnostics.No_longer_supported_In_early_versions_manually_set_the_text_encoding_for_reading_files, + category: ts.Diagnostics.Backwards_Compatibility, + description: ts.Diagnostics.No_longer_supported_In_early_versions_manually_set_the_text_encoding_for_reading_files, defaultValueDescription: "utf8" }, { name: "emitBOM", type: "boolean", affectsEmit: true, - category: Diagnostics.Emit, - description: Diagnostics.Emit_a_UTF_8_Byte_Order_Mark_BOM_in_the_beginning_of_output_files, + category: ts.Diagnostics.Emit, + description: ts.Diagnostics.Emit_a_UTF_8_Byte_Order_Mark_BOM_in_the_beginning_of_output_files, defaultValueDescription: false, }, { name: "newLine", - type: new Map(getEntries({ - crlf: NewLineKind.CarriageReturnLineFeed, - lf: NewLineKind.LineFeed + type: new ts.Map(ts.getEntries({ + crlf: ts.NewLineKind.CarriageReturnLineFeed, + lf: ts.NewLineKind.LineFeed })), affectsEmit: true, - paramType: Diagnostics.NEWLINE, - category: Diagnostics.Emit, - description: Diagnostics.Set_the_newline_character_for_emitting_files, - defaultValueDescription: Diagnostics.Platform_specific + paramType: ts.Diagnostics.NEWLINE, + category: ts.Diagnostics.Emit, + description: ts.Diagnostics.Set_the_newline_character_for_emitting_files, + defaultValueDescription: ts.Diagnostics.Platform_specific }, { name: "noErrorTruncation", type: "boolean", affectsSemanticDiagnostics: true, - category: Diagnostics.Output_Formatting, - description: Diagnostics.Disable_truncating_types_in_error_messages, + category: ts.Diagnostics.Output_Formatting, + description: ts.Diagnostics.Disable_truncating_types_in_error_messages, defaultValueDescription: false, }, { name: "noLib", type: "boolean", - category: Diagnostics.Language_and_Environment, + category: ts.Diagnostics.Language_and_Environment, affectsProgramStructure: true, - description: Diagnostics.Disable_including_any_library_files_including_the_default_lib_d_ts, + description: ts.Diagnostics.Disable_including_any_library_files_including_the_default_lib_d_ts, // We are not returning a sourceFile for lib file when asked by the program, // so pass --noLib to avoid reporting a file not found error. transpileOptionValue: true, @@ -1061,8 +1067,8 @@ namespace ts { name: "noResolve", type: "boolean", affectsModuleResolution: true, - category: Diagnostics.Modules, - description: Diagnostics.Disallow_import_s_require_s_or_reference_s_from_expanding_the_number_of_files_TypeScript_should_add_to_a_project, + category: ts.Diagnostics.Modules, + description: ts.Diagnostics.Disallow_import_s_require_s_or_reference_s_from_expanding_the_number_of_files_TypeScript_should_add_to_a_project, // We are not doing a full typecheck, we are not resolving the whole context, // so pass --noResolve to avoid reporting missing file errors. transpileOptionValue: true, @@ -1072,73 +1078,73 @@ namespace ts { name: "stripInternal", type: "boolean", affectsEmit: true, - category: Diagnostics.Emit, - description: Diagnostics.Disable_emitting_declarations_that_have_internal_in_their_JSDoc_comments, + category: ts.Diagnostics.Emit, + description: ts.Diagnostics.Disable_emitting_declarations_that_have_internal_in_their_JSDoc_comments, defaultValueDescription: false, }, { name: "disableSizeLimit", type: "boolean", affectsProgramStructure: true, - category: Diagnostics.Editor_Support, - description: Diagnostics.Remove_the_20mb_cap_on_total_source_code_size_for_JavaScript_files_in_the_TypeScript_language_server, + category: ts.Diagnostics.Editor_Support, + description: ts.Diagnostics.Remove_the_20mb_cap_on_total_source_code_size_for_JavaScript_files_in_the_TypeScript_language_server, defaultValueDescription: false, }, { name: "disableSourceOfProjectReferenceRedirect", type: "boolean", isTSConfigOnly: true, - category: Diagnostics.Projects, - description: Diagnostics.Disable_preferring_source_files_instead_of_declaration_files_when_referencing_composite_projects, + category: ts.Diagnostics.Projects, + description: ts.Diagnostics.Disable_preferring_source_files_instead_of_declaration_files_when_referencing_composite_projects, defaultValueDescription: false, }, { name: "disableSolutionSearching", type: "boolean", isTSConfigOnly: true, - category: Diagnostics.Projects, - description: Diagnostics.Opt_a_project_out_of_multi_project_reference_checking_when_editing, + category: ts.Diagnostics.Projects, + description: ts.Diagnostics.Opt_a_project_out_of_multi_project_reference_checking_when_editing, defaultValueDescription: false, }, { name: "disableReferencedProjectLoad", type: "boolean", isTSConfigOnly: true, - category: Diagnostics.Projects, - description: Diagnostics.Reduce_the_number_of_projects_loaded_automatically_by_TypeScript, + category: ts.Diagnostics.Projects, + description: ts.Diagnostics.Reduce_the_number_of_projects_loaded_automatically_by_TypeScript, defaultValueDescription: false, }, { name: "noImplicitUseStrict", type: "boolean", affectsSemanticDiagnostics: true, - category: Diagnostics.Backwards_Compatibility, - description: Diagnostics.Disable_adding_use_strict_directives_in_emitted_JavaScript_files, + category: ts.Diagnostics.Backwards_Compatibility, + description: ts.Diagnostics.Disable_adding_use_strict_directives_in_emitted_JavaScript_files, defaultValueDescription: false, }, { name: "noEmitHelpers", type: "boolean", affectsEmit: true, - category: Diagnostics.Emit, - description: Diagnostics.Disable_generating_custom_helper_functions_like_extends_in_compiled_output, + category: ts.Diagnostics.Emit, + description: ts.Diagnostics.Disable_generating_custom_helper_functions_like_extends_in_compiled_output, defaultValueDescription: false, }, { name: "noEmitOnError", type: "boolean", affectsEmit: true, - category: Diagnostics.Emit, + category: ts.Diagnostics.Emit, transpileOptionValue: undefined, - description: Diagnostics.Disable_emitting_files_if_any_type_checking_errors_are_reported, + description: ts.Diagnostics.Disable_emitting_files_if_any_type_checking_errors_are_reported, defaultValueDescription: false, }, { name: "preserveConstEnums", type: "boolean", affectsEmit: true, - category: Diagnostics.Emit, - description: Diagnostics.Disable_erasing_const_enum_declarations_in_generated_code, + category: ts.Diagnostics.Emit, + description: ts.Diagnostics.Disable_erasing_const_enum_declarations_in_generated_code, defaultValueDescription: false, }, { @@ -1146,16 +1152,16 @@ namespace ts { type: "string", affectsEmit: true, isFilePath: true, - paramType: Diagnostics.DIRECTORY, - category: Diagnostics.Emit, + paramType: ts.Diagnostics.DIRECTORY, + category: ts.Diagnostics.Emit, transpileOptionValue: undefined, - description: Diagnostics.Specify_the_output_directory_for_generated_declaration_files, + description: ts.Diagnostics.Specify_the_output_directory_for_generated_declaration_files, }, { name: "skipLibCheck", type: "boolean", - category: Diagnostics.Completeness, - description: Diagnostics.Skip_type_checking_all_d_ts_files, + category: ts.Diagnostics.Completeness, + description: ts.Diagnostics.Skip_type_checking_all_d_ts_files, defaultValueDescription: false, }, { @@ -1163,8 +1169,8 @@ namespace ts { type: "boolean", affectsBindDiagnostics: true, affectsSemanticDiagnostics: true, - category: Diagnostics.Type_Checking, - description: Diagnostics.Disable_error_reporting_for_unused_labels, + category: ts.Diagnostics.Type_Checking, + description: ts.Diagnostics.Disable_error_reporting_for_unused_labels, defaultValueDescription: undefined, }, { @@ -1172,48 +1178,48 @@ namespace ts { type: "boolean", affectsBindDiagnostics: true, affectsSemanticDiagnostics: true, - category: Diagnostics.Type_Checking, - description: Diagnostics.Disable_error_reporting_for_unreachable_code, + category: ts.Diagnostics.Type_Checking, + description: ts.Diagnostics.Disable_error_reporting_for_unreachable_code, defaultValueDescription: undefined, }, { name: "suppressExcessPropertyErrors", type: "boolean", affectsSemanticDiagnostics: true, - category: Diagnostics.Backwards_Compatibility, - description: Diagnostics.Disable_reporting_of_excess_property_errors_during_the_creation_of_object_literals, + category: ts.Diagnostics.Backwards_Compatibility, + description: ts.Diagnostics.Disable_reporting_of_excess_property_errors_during_the_creation_of_object_literals, defaultValueDescription: false, }, { name: "suppressImplicitAnyIndexErrors", type: "boolean", affectsSemanticDiagnostics: true, - category: Diagnostics.Backwards_Compatibility, - description: Diagnostics.Suppress_noImplicitAny_errors_when_indexing_objects_that_lack_index_signatures, + category: ts.Diagnostics.Backwards_Compatibility, + description: ts.Diagnostics.Suppress_noImplicitAny_errors_when_indexing_objects_that_lack_index_signatures, defaultValueDescription: false, }, { name: "forceConsistentCasingInFileNames", type: "boolean", affectsModuleResolution: true, - category: Diagnostics.Interop_Constraints, - description: Diagnostics.Ensure_that_casing_is_correct_in_imports, + category: ts.Diagnostics.Interop_Constraints, + description: ts.Diagnostics.Ensure_that_casing_is_correct_in_imports, defaultValueDescription: false, }, { name: "maxNodeModuleJsDepth", type: "number", affectsModuleResolution: true, - category: Diagnostics.JavaScript_Support, - description: Diagnostics.Specify_the_maximum_folder_depth_used_for_checking_JavaScript_files_from_node_modules_Only_applicable_with_allowJs, + category: ts.Diagnostics.JavaScript_Support, + description: ts.Diagnostics.Specify_the_maximum_folder_depth_used_for_checking_JavaScript_files_from_node_modules_Only_applicable_with_allowJs, defaultValueDescription: 0, }, { name: "noStrictGenericChecks", type: "boolean", affectsSemanticDiagnostics: true, - category: Diagnostics.Backwards_Compatibility, - description: Diagnostics.Disable_strict_checking_of_generic_signatures_in_function_types, + category: ts.Diagnostics.Backwards_Compatibility, + description: ts.Diagnostics.Disable_strict_checking_of_generic_signatures_in_function_types, defaultValueDescription: false, }, { @@ -1221,24 +1227,24 @@ namespace ts { type: "boolean", affectsSemanticDiagnostics: true, affectsEmit: true, - category: Diagnostics.Language_and_Environment, - description: Diagnostics.Emit_ECMAScript_standard_compliant_class_fields, - defaultValueDescription: Diagnostics.true_for_ES2022_and_above_including_ESNext + category: ts.Diagnostics.Language_and_Environment, + description: ts.Diagnostics.Emit_ECMAScript_standard_compliant_class_fields, + defaultValueDescription: ts.Diagnostics.true_for_ES2022_and_above_including_ESNext }, { name: "preserveValueImports", type: "boolean", affectsEmit: true, - category: Diagnostics.Emit, - description: Diagnostics.Preserve_unused_imported_values_in_the_JavaScript_output_that_would_otherwise_be_removed, + category: ts.Diagnostics.Emit, + description: ts.Diagnostics.Preserve_unused_imported_values_in_the_JavaScript_output_that_would_otherwise_be_removed, defaultValueDescription: false, }, { name: "keyofStringsOnly", type: "boolean", - category: Diagnostics.Backwards_Compatibility, - description: Diagnostics.Make_keyof_only_return_strings_instead_of_string_numbers_or_symbols_Legacy_option, + category: ts.Diagnostics.Backwards_Compatibility, + description: ts.Diagnostics.Make_keyof_only_return_strings_instead_of_string_numbers_or_symbols_Legacy_option, defaultValueDescription: false, }, { @@ -1250,98 +1256,92 @@ namespace ts { name: "plugin", type: "object" }, - description: Diagnostics.Specify_a_list_of_language_service_plugins_to_include, - category: Diagnostics.Editor_Support, + description: ts.Diagnostics.Specify_a_list_of_language_service_plugins_to_include, + category: ts.Diagnostics.Editor_Support, }, { name: "moduleDetection", - type: new Map(getEntries({ - auto: ModuleDetectionKind.Auto, - legacy: ModuleDetectionKind.Legacy, - force: ModuleDetectionKind.Force, + type: new ts.Map(ts.getEntries({ + auto: ts.ModuleDetectionKind.Auto, + legacy: ts.ModuleDetectionKind.Legacy, + force: ts.ModuleDetectionKind.Force, })), affectsModuleResolution: true, - description: Diagnostics.Control_what_method_is_used_to_detect_module_format_JS_files, - category: Diagnostics.Language_and_Environment, - defaultValueDescription: Diagnostics.auto_Colon_Treat_files_with_imports_exports_import_meta_jsx_with_jsx_Colon_react_jsx_or_esm_format_with_module_Colon_node16_as_modules, + description: ts.Diagnostics.Control_what_method_is_used_to_detect_module_format_JS_files, + category: ts.Diagnostics.Language_and_Environment, + defaultValueDescription: ts.Diagnostics.auto_Colon_Treat_files_with_imports_exports_import_meta_jsx_with_jsx_Colon_react_jsx_or_esm_format_with_module_Colon_node16_as_modules, } ]; /* @internal */ - export const optionDeclarations: CommandLineOption[] = [ + export const optionDeclarations: ts.CommandLineOption[] = [ ...commonOptionsWithBuild, ...commandOptionsWithoutBuild, ]; /* @internal */ - export const semanticDiagnosticsOptionDeclarations: readonly CommandLineOption[] = - optionDeclarations.filter(option => !!option.affectsSemanticDiagnostics); + export const semanticDiagnosticsOptionDeclarations: readonly ts.CommandLineOption[] = optionDeclarations.filter(option => !!option.affectsSemanticDiagnostics); /* @internal */ - export const affectsEmitOptionDeclarations: readonly CommandLineOption[] = - optionDeclarations.filter(option => !!option.affectsEmit); + export const affectsEmitOptionDeclarations: readonly ts.CommandLineOption[] = optionDeclarations.filter(option => !!option.affectsEmit); /* @internal */ - export const moduleResolutionOptionDeclarations: readonly CommandLineOption[] = - optionDeclarations.filter(option => !!option.affectsModuleResolution); + export const moduleResolutionOptionDeclarations: readonly ts.CommandLineOption[] = optionDeclarations.filter(option => !!option.affectsModuleResolution); /* @internal */ - export const sourceFileAffectingCompilerOptions: readonly CommandLineOption[] = optionDeclarations.filter(option => - !!option.affectsSourceFile || !!option.affectsModuleResolution || !!option.affectsBindDiagnostics); + export const sourceFileAffectingCompilerOptions: readonly ts.CommandLineOption[] = optionDeclarations.filter(option => !!option.affectsSourceFile || !!option.affectsModuleResolution || !!option.affectsBindDiagnostics); /* @internal */ - export const optionsAffectingProgramStructure: readonly CommandLineOption[] = - optionDeclarations.filter(option => !!option.affectsProgramStructure); + export const optionsAffectingProgramStructure: readonly ts.CommandLineOption[] = optionDeclarations.filter(option => !!option.affectsProgramStructure); /* @internal */ - export const transpileOptionValueCompilerOptions: readonly CommandLineOption[] = optionDeclarations.filter(option => - hasProperty(option, "transpileOptionValue")); + export const transpileOptionValueCompilerOptions: readonly ts.CommandLineOption[] = optionDeclarations.filter(option => ts.hasProperty(option, "transpileOptionValue")); // Build related options /* @internal */ - export const optionsForBuild: CommandLineOption[] = [ + export const optionsForBuild: ts.CommandLineOption[] = [ { name: "verbose", shortName: "v", - category: Diagnostics.Command_line_Options, - description: Diagnostics.Enable_verbose_logging, + category: ts.Diagnostics.Command_line_Options, + description: ts.Diagnostics.Enable_verbose_logging, type: "boolean", defaultValueDescription: false, }, { name: "dry", shortName: "d", - category: Diagnostics.Command_line_Options, - description: Diagnostics.Show_what_would_be_built_or_deleted_if_specified_with_clean, + category: ts.Diagnostics.Command_line_Options, + description: ts.Diagnostics.Show_what_would_be_built_or_deleted_if_specified_with_clean, type: "boolean", defaultValueDescription: false, }, { name: "force", shortName: "f", - category: Diagnostics.Command_line_Options, - description: Diagnostics.Build_all_projects_including_those_that_appear_to_be_up_to_date, + category: ts.Diagnostics.Command_line_Options, + description: ts.Diagnostics.Build_all_projects_including_those_that_appear_to_be_up_to_date, type: "boolean", defaultValueDescription: false, }, { name: "clean", - category: Diagnostics.Command_line_Options, - description: Diagnostics.Delete_the_outputs_of_all_projects, + category: ts.Diagnostics.Command_line_Options, + description: ts.Diagnostics.Delete_the_outputs_of_all_projects, type: "boolean", defaultValueDescription: false, } ]; /* @internal */ - export const buildOpts: CommandLineOption[] = [ + export const buildOpts: ts.CommandLineOption[] = [ ...commonOptionsWithBuild, ...optionsForBuild ]; /* @internal */ - export const typeAcquisitionDeclarations: CommandLineOption[] = [ + export const typeAcquisitionDeclarations: ts.CommandLineOption[] = [ { /* @deprecated typingOptions.enableAutoDiscovery * Use typeAcquisition.enable instead. @@ -1380,15 +1380,15 @@ namespace ts { /* @internal */ export interface OptionsNameMap { - optionsNameMap: ESMap; - shortOptionNames: ESMap; + optionsNameMap: ts.ESMap; + shortOptionNames: ts.ESMap; } /*@internal*/ - export function createOptionNameMap(optionDeclarations: readonly CommandLineOption[]): OptionsNameMap { - const optionsNameMap = new Map(); - const shortOptionNames = new Map(); - forEach(optionDeclarations, option => { + export function createOptionNameMap(optionDeclarations: readonly ts.CommandLineOption[]): OptionsNameMap { + const optionsNameMap = new ts.Map(); + const shortOptionNames = new ts.Map(); + ts.forEach(optionDeclarations, option => { optionsNameMap.set(option.name.toLowerCase(), option); if (option.shortName) { shortOptionNames.set(option.shortName, option.name); @@ -1405,15 +1405,15 @@ namespace ts { return optionsNameMapCache ||= createOptionNameMap(optionDeclarations); } - const compilerOptionsAlternateMode: AlternateModeDiagnostics = { - diagnostic: Diagnostics.Compiler_option_0_may_only_be_used_with_build, + const compilerOptionsAlternateMode: ts.AlternateModeDiagnostics = { + diagnostic: ts.Diagnostics.Compiler_option_0_may_only_be_used_with_build, getOptionsNameMap: getBuildOptionsNameMap }; /* @internal */ - export const defaultInitCompilerOptions: CompilerOptions = { - module: ModuleKind.CommonJS, - target: ScriptTarget.ES2016, + export const defaultInitCompilerOptions: ts.CompilerOptions = { + module: ts.ModuleKind.CommonJS, + target: ts.ScriptTarget.ES2016, strict: true, esModuleInterop: true, forceConsistentCasingInFileNames: true, @@ -1421,7 +1421,7 @@ namespace ts { }; /* @internal */ - export function convertEnableAutoDiscoveryToEnable(typeAcquisition: TypeAcquisition): TypeAcquisition { + export function convertEnableAutoDiscoveryToEnable(typeAcquisition: ts.TypeAcquisition): ts.TypeAcquisition { // Convert deprecated typingOptions.enableAutoDiscovery to typeAcquisition.enable if (typeAcquisition && typeAcquisition.enableAutoDiscovery !== undefined && typeAcquisition.enable === undefined) { return { @@ -1434,24 +1434,24 @@ namespace ts { } /* @internal */ - export function createCompilerDiagnosticForInvalidCustomType(opt: CommandLineOptionOfCustomType): Diagnostic { - return createDiagnosticForInvalidCustomType(opt, createCompilerDiagnostic); + export function createCompilerDiagnosticForInvalidCustomType(opt: ts.CommandLineOptionOfCustomType): ts.Diagnostic { + return createDiagnosticForInvalidCustomType(opt, ts.createCompilerDiagnostic); } - function createDiagnosticForInvalidCustomType(opt: CommandLineOptionOfCustomType, createDiagnostic: (message: DiagnosticMessage, arg0: string, arg1: string) => Diagnostic): Diagnostic { - const namesOfType = arrayFrom(opt.type.keys()).map(key => `'${key}'`).join(", "); - return createDiagnostic(Diagnostics.Argument_for_0_option_must_be_Colon_1, `--${opt.name}`, namesOfType); + function createDiagnosticForInvalidCustomType(opt: ts.CommandLineOptionOfCustomType, createDiagnostic: (message: ts.DiagnosticMessage, arg0: string, arg1: string) => ts.Diagnostic): ts.Diagnostic { + const namesOfType = ts.arrayFrom(opt.type.keys()).map(key => `'${key}'`).join(", "); + return createDiagnostic(ts.Diagnostics.Argument_for_0_option_must_be_Colon_1, `--${opt.name}`, namesOfType); } /* @internal */ - export function parseCustomTypeOption(opt: CommandLineOptionOfCustomType, value: string, errors: Push) { - return convertJsonOptionOfCustomType(opt, trimString(value || ""), errors); + export function parseCustomTypeOption(opt: ts.CommandLineOptionOfCustomType, value: string, errors: ts.Push) { + return convertJsonOptionOfCustomType(opt, ts.trimString(value || ""), errors); } /* @internal */ - export function parseListTypeOption(opt: CommandLineOptionOfListType, value = "", errors: Push): (string | number)[] | undefined { - value = trimString(value); - if (startsWith(value, "-")) { + export function parseListTypeOption(opt: ts.CommandLineOptionOfListType, value = "", errors: ts.Push): (string | number)[] | undefined { + value = ts.trimString(value); + if (ts.startsWith(value, "-")) { return undefined; } if (value === "") { @@ -1460,54 +1460,46 @@ namespace ts { const values = value.split(","); switch (opt.element.type) { case "number": - return mapDefined(values, v => validateJsonOptionValue(opt.element, parseInt(v), errors)); + return ts.mapDefined(values, v => validateJsonOptionValue(opt.element, parseInt(v), errors)); case "string": - return mapDefined(values, v => validateJsonOptionValue(opt.element, v || "", errors)); + return ts.mapDefined(values, v => validateJsonOptionValue(opt.element, v || "", errors)); default: - return mapDefined(values, v => parseCustomTypeOption(opt.element as CommandLineOptionOfCustomType, v, errors)); + return ts.mapDefined(values, v => parseCustomTypeOption(opt.element as ts.CommandLineOptionOfCustomType, v, errors)); } } /*@internal*/ export interface OptionsBase { - [option: string]: CompilerOptionsValue | TsConfigSourceFile | undefined; + [option: string]: ts.CompilerOptionsValue | ts.TsConfigSourceFile | undefined; } /*@internal*/ - export interface ParseCommandLineWorkerDiagnostics extends DidYouMeanOptionsDiagnostics { + export interface ParseCommandLineWorkerDiagnostics extends ts.DidYouMeanOptionsDiagnostics { getOptionsNameMap: () => OptionsNameMap; - optionTypeMismatchDiagnostic: DiagnosticMessage; + optionTypeMismatchDiagnostic: ts.DiagnosticMessage; } - function getOptionName(option: CommandLineOption) { + function getOptionName(option: ts.CommandLineOption) { return option.name; } - function createUnknownOptionError( - unknownOption: string, - diagnostics: DidYouMeanOptionsDiagnostics, - createDiagnostics: (message: DiagnosticMessage, arg0: string, arg1?: string) => Diagnostic, - unknownOptionErrorText?: string - ) { + function createUnknownOptionError(unknownOption: string, diagnostics: ts.DidYouMeanOptionsDiagnostics, createDiagnostics: (message: ts.DiagnosticMessage, arg0: string, arg1?: string) => ts.Diagnostic, unknownOptionErrorText?: string) { if (diagnostics.alternateMode?.getOptionsNameMap().optionsNameMap.has(unknownOption.toLowerCase())) { return createDiagnostics(diagnostics.alternateMode.diagnostic, unknownOption); } - const possibleOption = getSpellingSuggestion(unknownOption, diagnostics.optionDeclarations, getOptionName); + const possibleOption = ts.getSpellingSuggestion(unknownOption, diagnostics.optionDeclarations, getOptionName); return possibleOption ? createDiagnostics(diagnostics.unknownDidYouMeanDiagnostic, unknownOptionErrorText || unknownOption, possibleOption.name) : createDiagnostics(diagnostics.unknownOptionDiagnostic, unknownOptionErrorText || unknownOption); } /*@internal*/ - export function parseCommandLineWorker( - diagnostics: ParseCommandLineWorkerDiagnostics, - commandLine: readonly string[], - readFile?: (path: string) => string | undefined) { + export function parseCommandLineWorker(diagnostics: ParseCommandLineWorkerDiagnostics, commandLine: readonly string[], readFile?: (path: string) => string | undefined) { const options = {} as OptionsBase; - let watchOptions: WatchOptions | undefined; + let watchOptions: ts.WatchOptions | undefined; const fileNames: string[] = []; - const errors: Diagnostic[] = []; + const errors: ts.Diagnostic[] = []; parseStrings(commandLine); return { @@ -1522,11 +1514,11 @@ namespace ts { while (i < args.length) { const s = args[i]; i++; - if (s.charCodeAt(0) === CharacterCodes.at) { + if (s.charCodeAt(0) === ts.CharacterCodes.at) { parseResponseFile(s.slice(1)); } - else if (s.charCodeAt(0) === CharacterCodes.minus) { - const inputOptionName = s.slice(s.charCodeAt(1) === CharacterCodes.minus ? 2 : 1); + else if (s.charCodeAt(0) === ts.CharacterCodes.minus) { + const inputOptionName = s.slice(s.charCodeAt(1) === ts.CharacterCodes.minus ? 2 : 1); const opt = getOptionDeclarationFromName(diagnostics.getOptionsNameMap, inputOptionName, /*allowShort*/ true); if (opt) { i = parseOptionValue(args, i, diagnostics, opt, options, errors); @@ -1537,7 +1529,7 @@ namespace ts { i = parseOptionValue(args, i, watchOptionsDidYouMeanDiagnostics, watchOpt, watchOptions || (watchOptions = {}), errors); } else { - errors.push(createUnknownOptionError(inputOptionName, diagnostics, createCompilerDiagnostic, s)); + errors.push(createUnknownOptionError(inputOptionName, diagnostics, ts.createCompilerDiagnostic, s)); } } } @@ -1548,8 +1540,8 @@ namespace ts { } function parseResponseFile(fileName: string) { - const text = tryReadFile(fileName, readFile || (fileName => sys.readFile(fileName))); - if (!isString(text)) { + const text = tryReadFile(fileName, readFile || (fileName => ts.sys.readFile(fileName))); + if (!ts.isString(text)) { errors.push(text); return; } @@ -1557,22 +1549,26 @@ namespace ts { const args: string[] = []; let pos = 0; while (true) { - while (pos < text.length && text.charCodeAt(pos) <= CharacterCodes.space) pos++; - if (pos >= text.length) break; + while (pos < text.length && text.charCodeAt(pos) <= ts.CharacterCodes.space) + pos++; + if (pos >= text.length) + break; const start = pos; - if (text.charCodeAt(start) === CharacterCodes.doubleQuote) { + if (text.charCodeAt(start) === ts.CharacterCodes.doubleQuote) { + pos++; + while (pos < text.length && text.charCodeAt(pos) !== ts.CharacterCodes.doubleQuote) pos++; - while (pos < text.length && text.charCodeAt(pos) !== CharacterCodes.doubleQuote) pos++; if (pos < text.length) { args.push(text.substring(start + 1, pos)); pos++; } else { - errors.push(createCompilerDiagnostic(Diagnostics.Unterminated_quoted_string_in_response_file_0, fileName)); + errors.push(ts.createCompilerDiagnostic(ts.Diagnostics.Unterminated_quoted_string_in_response_file_0, fileName)); } } else { - while (text.charCodeAt(pos) > CharacterCodes.space) pos++; + while (text.charCodeAt(pos) > ts.CharacterCodes.space) + pos++; args.push(text.substring(start, pos)); } } @@ -1580,14 +1576,7 @@ namespace ts { } } - function parseOptionValue( - args: readonly string[], - i: number, - diagnostics: ParseCommandLineWorkerDiagnostics, - opt: CommandLineOption, - options: OptionsBase, - errors: Diagnostic[] - ) { + function parseOptionValue(args: readonly string[], i: number, diagnostics: ParseCommandLineWorkerDiagnostics, opt: ts.CommandLineOption, options: OptionsBase, errors: ts.Diagnostic[]) { if (opt.isTSConfigOnly) { const optValue = args[i]; if (optValue === "null") { @@ -1600,19 +1589,21 @@ namespace ts { i++; } else { - if (optValue === "true") i++; - errors.push(createCompilerDiagnostic(Diagnostics.Option_0_can_only_be_specified_in_tsconfig_json_file_or_set_to_false_or_null_on_command_line, opt.name)); + if (optValue === "true") + i++; + errors.push(ts.createCompilerDiagnostic(ts.Diagnostics.Option_0_can_only_be_specified_in_tsconfig_json_file_or_set_to_false_or_null_on_command_line, opt.name)); } } else { - errors.push(createCompilerDiagnostic(Diagnostics.Option_0_can_only_be_specified_in_tsconfig_json_file_or_set_to_null_on_command_line, opt.name)); - if (optValue && !startsWith(optValue, "-")) i++; + errors.push(ts.createCompilerDiagnostic(ts.Diagnostics.Option_0_can_only_be_specified_in_tsconfig_json_file_or_set_to_null_on_command_line, opt.name)); + if (optValue && !ts.startsWith(optValue, "-")) + i++; } } else { // Check to see if no argument was provided (e.g. "--locale" is the last command-line argument). if (!args[i] && opt.type !== "boolean") { - errors.push(createCompilerDiagnostic(diagnostics.optionTypeMismatchDiagnostic, opt.name, getCompilerOptionValueTypeString(opt))); + errors.push(ts.createCompilerDiagnostic(diagnostics.optionTypeMismatchDiagnostic, opt.name, getCompilerOptionValueTypeString(opt))); } if (args[i] !== "null") { @@ -1643,7 +1634,7 @@ namespace ts { break; // If not a primitive, the possible types are specified in what is effectively a map of options. default: - options[opt.name] = parseCustomTypeOption(opt as CommandLineOptionOfCustomType, args[i], errors); + options[opt.name] = parseCustomTypeOption(opt as ts.CommandLineOptionOfCustomType, args[i], errors); i++; break; } @@ -1661,20 +1652,20 @@ namespace ts { alternateMode: compilerOptionsAlternateMode, getOptionsNameMap, optionDeclarations, - unknownOptionDiagnostic: Diagnostics.Unknown_compiler_option_0, - unknownDidYouMeanDiagnostic: Diagnostics.Unknown_compiler_option_0_Did_you_mean_1, - optionTypeMismatchDiagnostic: Diagnostics.Compiler_option_0_expects_an_argument + unknownOptionDiagnostic: ts.Diagnostics.Unknown_compiler_option_0, + unknownDidYouMeanDiagnostic: ts.Diagnostics.Unknown_compiler_option_0_Did_you_mean_1, + optionTypeMismatchDiagnostic: ts.Diagnostics.Compiler_option_0_expects_an_argument }; - export function parseCommandLine(commandLine: readonly string[], readFile?: (path: string) => string | undefined): ParsedCommandLine { + export function parseCommandLine(commandLine: readonly string[], readFile?: (path: string) => string | undefined): ts.ParsedCommandLine { return parseCommandLineWorker(compilerOptionsDidYouMeanDiagnostics, commandLine, readFile); } /** @internal */ - export function getOptionFromName(optionName: string, allowShort?: boolean): CommandLineOption | undefined { + export function getOptionFromName(optionName: string, allowShort?: boolean): ts.CommandLineOption | undefined { return getOptionDeclarationFromName(getOptionsNameMap, optionName, allowShort); } - function getOptionDeclarationFromName(getOptionNameMap: () => OptionsNameMap, optionName: string, allowShort = false): CommandLineOption | undefined { + function getOptionDeclarationFromName(getOptionNameMap: () => OptionsNameMap, optionName: string, allowShort = false): ts.CommandLineOption | undefined { optionName = optionName.toLowerCase(); const { optionsNameMap, shortOptionNames } = getOptionNameMap(); // Try to translate short option names to their full equivalents. @@ -1689,10 +1680,10 @@ namespace ts { /*@internal*/ export interface ParsedBuildCommand { - buildOptions: BuildOptions; - watchOptions: WatchOptions | undefined; + buildOptions: ts.BuildOptions; + watchOptions: ts.WatchOptions | undefined; projects: string[]; - errors: Diagnostic[]; + errors: ts.Diagnostic[]; } let buildOptionsNameMapCache: OptionsNameMap; @@ -1700,8 +1691,8 @@ namespace ts { return buildOptionsNameMapCache || (buildOptionsNameMapCache = createOptionNameMap(buildOpts)); } - const buildOptionsAlternateMode: AlternateModeDiagnostics = { - diagnostic: Diagnostics.Compiler_option_0_may_not_be_used_with_build, + const buildOptionsAlternateMode: ts.AlternateModeDiagnostics = { + diagnostic: ts.Diagnostics.Compiler_option_0_may_not_be_used_with_build, getOptionsNameMap }; @@ -1709,18 +1700,15 @@ namespace ts { alternateMode: buildOptionsAlternateMode, getOptionsNameMap: getBuildOptionsNameMap, optionDeclarations: buildOpts, - unknownOptionDiagnostic: Diagnostics.Unknown_build_option_0, - unknownDidYouMeanDiagnostic: Diagnostics.Unknown_build_option_0_Did_you_mean_1, - optionTypeMismatchDiagnostic: Diagnostics.Build_option_0_requires_a_value_of_type_1 + unknownOptionDiagnostic: ts.Diagnostics.Unknown_build_option_0, + unknownDidYouMeanDiagnostic: ts.Diagnostics.Unknown_build_option_0_Did_you_mean_1, + optionTypeMismatchDiagnostic: ts.Diagnostics.Build_option_0_requires_a_value_of_type_1 }; /*@internal*/ export function parseBuildCommand(args: readonly string[]): ParsedBuildCommand { - const { options, watchOptions, fileNames: projects, errors } = parseCommandLineWorker( - buildOptionsDidYouMeanDiagnostics, - args - ); - const buildOptions = options as BuildOptions; + const { options, watchOptions, fileNames: projects, errors } = parseCommandLineWorker(buildOptionsDidYouMeanDiagnostics, args); + const buildOptions = options as ts.BuildOptions; if (projects.length === 0) { // tsc -b invoked with no extra arguments; act as if invoked with "tsc -b ." @@ -1729,28 +1717,28 @@ namespace ts { // Nonsensical combinations if (buildOptions.clean && buildOptions.force) { - errors.push(createCompilerDiagnostic(Diagnostics.Options_0_and_1_cannot_be_combined, "clean", "force")); + errors.push(ts.createCompilerDiagnostic(ts.Diagnostics.Options_0_and_1_cannot_be_combined, "clean", "force")); } if (buildOptions.clean && buildOptions.verbose) { - errors.push(createCompilerDiagnostic(Diagnostics.Options_0_and_1_cannot_be_combined, "clean", "verbose")); + errors.push(ts.createCompilerDiagnostic(ts.Diagnostics.Options_0_and_1_cannot_be_combined, "clean", "verbose")); } if (buildOptions.clean && buildOptions.watch) { - errors.push(createCompilerDiagnostic(Diagnostics.Options_0_and_1_cannot_be_combined, "clean", "watch")); + errors.push(ts.createCompilerDiagnostic(ts.Diagnostics.Options_0_and_1_cannot_be_combined, "clean", "watch")); } if (buildOptions.watch && buildOptions.dry) { - errors.push(createCompilerDiagnostic(Diagnostics.Options_0_and_1_cannot_be_combined, "watch", "dry")); + errors.push(ts.createCompilerDiagnostic(ts.Diagnostics.Options_0_and_1_cannot_be_combined, "watch", "dry")); } return { buildOptions, watchOptions, projects, errors }; } /* @internal */ - export function getDiagnosticText(_message: DiagnosticMessage, ..._args: any[]): string { - const diagnostic = createCompilerDiagnostic.apply(undefined, arguments); + export function getDiagnosticText(_message: ts.DiagnosticMessage, ..._args: any[]): string { + const diagnostic = ts.createCompilerDiagnostic.apply(undefined, arguments); return diagnostic.messageText as string; } - export type DiagnosticReporter = (diagnostic: Diagnostic) => void; + export type DiagnosticReporter = (diagnostic: ts.Diagnostic) => void; /** * Reports config file diagnostics */ @@ -1764,52 +1752,39 @@ namespace ts { /** * Interface extending ParseConfigHost to support ParseConfigFile that reads config file and reports errors */ - export interface ParseConfigFileHost extends ParseConfigHost, ConfigFileDiagnosticsReporter { + export interface ParseConfigFileHost extends ts.ParseConfigHost, ConfigFileDiagnosticsReporter { getCurrentDirectory(): string; } /** * Reads the config file, reports errors if any and exits if the config file cannot be found */ - export function getParsedCommandLineOfConfigFile( - configFileName: string, - optionsToExtend: CompilerOptions | undefined, - host: ParseConfigFileHost, - extendedConfigCache?: Map, - watchOptionsToExtend?: WatchOptions, - extraFileExtensions?: readonly FileExtensionInfo[], - ): ParsedCommandLine | undefined { + export function getParsedCommandLineOfConfigFile(configFileName: string, optionsToExtend: ts.CompilerOptions | undefined, host: ParseConfigFileHost, extendedConfigCache?: ts.Map, watchOptionsToExtend?: ts.WatchOptions, extraFileExtensions?: readonly ts.FileExtensionInfo[]): ts.ParsedCommandLine | undefined { const configFileText = tryReadFile(configFileName, fileName => host.readFile(fileName)); - if (!isString(configFileText)) { + if (!ts.isString(configFileText)) { host.onUnRecoverableConfigFileDiagnostic(configFileText); return undefined; } - const result = parseJsonText(configFileName, configFileText); + const result = ts.parseJsonText(configFileName, configFileText); const cwd = host.getCurrentDirectory(); - result.path = toPath(configFileName, cwd, createGetCanonicalFileName(host.useCaseSensitiveFileNames)); + result.path = ts.toPath(configFileName, cwd, ts.createGetCanonicalFileName(host.useCaseSensitiveFileNames)); result.resolvedPath = result.path; result.originalFileName = result.fileName; - return parseJsonSourceFileConfigFileContent( - result, - host, - getNormalizedAbsolutePath(getDirectoryPath(configFileName), cwd), - optionsToExtend, - getNormalizedAbsolutePath(configFileName, cwd), - /*resolutionStack*/ undefined, - extraFileExtensions, - extendedConfigCache, - watchOptionsToExtend - ); + return parseJsonSourceFileConfigFileContent(result, host, ts.getNormalizedAbsolutePath(ts.getDirectoryPath(configFileName), cwd), optionsToExtend, ts.getNormalizedAbsolutePath(configFileName, cwd), + /*resolutionStack*/ undefined, extraFileExtensions, extendedConfigCache, watchOptionsToExtend); } /** * Read tsconfig.json file * @param fileName The path to the config file */ - export function readConfigFile(fileName: string, readFile: (path: string) => string | undefined): { config?: any; error?: Diagnostic } { + export function readConfigFile(fileName: string, readFile: (path: string) => string | undefined): { + config?: any; + error?: ts.Diagnostic; + } { const textOrDiagnostic = tryReadFile(fileName, readFile); - return isString(textOrDiagnostic) ? parseConfigFileTextToJson(fileName, textOrDiagnostic) : { config: {}, error: textOrDiagnostic }; + return ts.isString(textOrDiagnostic) ? parseConfigFileTextToJson(fileName, textOrDiagnostic) : { config: {}, error: textOrDiagnostic }; } /** @@ -1817,8 +1792,11 @@ namespace ts { * @param fileName The path to the config file * @param jsonText The text of the config file */ - export function parseConfigFileTextToJson(fileName: string, jsonText: string): { config?: any; error?: Diagnostic } { - const jsonSourceFile = parseJsonText(fileName, jsonText); + export function parseConfigFileTextToJson(fileName: string, jsonText: string): { + config?: any; + error?: ts.Diagnostic; + } { + const jsonSourceFile = ts.parseJsonText(fileName, jsonText); return { config: convertConfigFileToObject(jsonSourceFile, jsonSourceFile.parseDiagnostics, /*reportOptionsErrors*/ false, /*optionsIterator*/ undefined), error: jsonSourceFile.parseDiagnostics.length ? jsonSourceFile.parseDiagnostics[0] : undefined @@ -1829,31 +1807,31 @@ namespace ts { * Read tsconfig.json file * @param fileName The path to the config file */ - export function readJsonConfigFile(fileName: string, readFile: (path: string) => string | undefined): TsConfigSourceFile { + export function readJsonConfigFile(fileName: string, readFile: (path: string) => string | undefined): ts.TsConfigSourceFile { const textOrDiagnostic = tryReadFile(fileName, readFile); - return isString(textOrDiagnostic) ? parseJsonText(fileName, textOrDiagnostic) : { fileName, parseDiagnostics: [textOrDiagnostic] } as TsConfigSourceFile; + return ts.isString(textOrDiagnostic) ? ts.parseJsonText(fileName, textOrDiagnostic) : { fileName, parseDiagnostics: [textOrDiagnostic] } as ts.TsConfigSourceFile; } /*@internal*/ - export function tryReadFile(fileName: string, readFile: (path: string) => string | undefined): string | Diagnostic { + export function tryReadFile(fileName: string, readFile: (path: string) => string | undefined): string | ts.Diagnostic { let text: string | undefined; try { text = readFile(fileName); } catch (e) { - return createCompilerDiagnostic(Diagnostics.Cannot_read_file_0_Colon_1, fileName, e.message); + return ts.createCompilerDiagnostic(ts.Diagnostics.Cannot_read_file_0_Colon_1, fileName, e.message); } - return text === undefined ? createCompilerDiagnostic(Diagnostics.Cannot_read_file_0, fileName) : text; + return text === undefined ? ts.createCompilerDiagnostic(ts.Diagnostics.Cannot_read_file_0, fileName) : text; } - function commandLineOptionsToMap(options: readonly CommandLineOption[]) { - return arrayToMap(options, getOptionName); + function commandLineOptionsToMap(options: readonly ts.CommandLineOption[]) { + return ts.arrayToMap(options, getOptionName); } - const typeAcquisitionDidYouMeanDiagnostics: DidYouMeanOptionsDiagnostics = { + const typeAcquisitionDidYouMeanDiagnostics: ts.DidYouMeanOptionsDiagnostics = { optionDeclarations: typeAcquisitionDeclarations, - unknownOptionDiagnostic: Diagnostics.Unknown_type_acquisition_option_0, - unknownDidYouMeanDiagnostic: Diagnostics.Unknown_type_acquisition_option_0_Did_you_mean_1, + unknownOptionDiagnostic: ts.Diagnostics.Unknown_type_acquisition_option_0, + unknownDidYouMeanDiagnostic: ts.Diagnostics.Unknown_type_acquisition_option_0_Did_you_mean_1, }; let watchOptionsNameMapCache: OptionsNameMap; @@ -1863,29 +1841,29 @@ namespace ts { const watchOptionsDidYouMeanDiagnostics: ParseCommandLineWorkerDiagnostics = { getOptionsNameMap: getWatchOptionsNameMap, optionDeclarations: optionsForWatch, - unknownOptionDiagnostic: Diagnostics.Unknown_watch_option_0, - unknownDidYouMeanDiagnostic: Diagnostics.Unknown_watch_option_0_Did_you_mean_1, - optionTypeMismatchDiagnostic: Diagnostics.Watch_option_0_requires_a_value_of_type_1 + unknownOptionDiagnostic: ts.Diagnostics.Unknown_watch_option_0, + unknownDidYouMeanDiagnostic: ts.Diagnostics.Unknown_watch_option_0_Did_you_mean_1, + optionTypeMismatchDiagnostic: ts.Diagnostics.Watch_option_0_requires_a_value_of_type_1 }; - let commandLineCompilerOptionsMapCache: ESMap; + let commandLineCompilerOptionsMapCache: ts.ESMap; function getCommandLineCompilerOptionsMap() { return commandLineCompilerOptionsMapCache || (commandLineCompilerOptionsMapCache = commandLineOptionsToMap(optionDeclarations)); } - let commandLineWatchOptionsMapCache: ESMap; + let commandLineWatchOptionsMapCache: ts.ESMap; function getCommandLineWatchOptionsMap() { return commandLineWatchOptionsMapCache || (commandLineWatchOptionsMapCache = commandLineOptionsToMap(optionsForWatch)); } - let commandLineTypeAcquisitionMapCache: ESMap; + let commandLineTypeAcquisitionMapCache: ts.ESMap; function getCommandLineTypeAcquisitionMap() { return commandLineTypeAcquisitionMapCache || (commandLineTypeAcquisitionMapCache = commandLineOptionsToMap(typeAcquisitionDeclarations)); } - let _tsconfigRootOptions: TsConfigOnlyOption; + let _tsconfigRootOptions: ts.TsConfigOnlyOption; function getTsconfigRootOptionsMap() { if (_tsconfigRootOptions === undefined) { _tsconfigRootOptions = { - name: undefined!, // should never be needed since this is root + name: undefined!, type: "object", elementOptions: commandLineOptionsToMap([ { @@ -1915,7 +1893,7 @@ namespace ts { { name: "extends", type: "string", - category: Diagnostics.File_Management, + category: ts.Diagnostics.File_Management, }, { name: "references", @@ -1924,7 +1902,7 @@ namespace ts { name: "references", type: "object" }, - category: Diagnostics.Projects, + category: ts.Diagnostics.Projects, }, { name: "files", @@ -1933,7 +1911,7 @@ namespace ts { name: "files", type: "string" }, - category: Diagnostics.File_Management, + category: ts.Diagnostics.File_Management, }, { name: "include", @@ -1942,8 +1920,8 @@ namespace ts { name: "include", type: "string" }, - category: Diagnostics.File_Management, - defaultValueDescription: Diagnostics.if_files_is_specified_otherwise_Asterisk_Asterisk_Slash_Asterisk + category: ts.Diagnostics.File_Management, + defaultValueDescription: ts.Diagnostics.if_files_is_specified_otherwise_Asterisk_Asterisk_Slash_Asterisk }, { name: "exclude", @@ -1952,8 +1930,8 @@ namespace ts { name: "exclude", type: "string" }, - category: Diagnostics.File_Management, - defaultValueDescription: Diagnostics.node_modules_bower_components_jspm_packages_plus_the_value_of_outDir_if_one_is_specified + category: ts.Diagnostics.File_Management, + defaultValueDescription: ts.Diagnostics.node_modules_bower_components_jspm_packages_plus_the_value_of_outDir_if_one_is_specified }, compileOnSaveCommandLineOption ]) @@ -1972,7 +1950,7 @@ namespace ts { * @param option option declaration which is being set with the value * @param value value of the option */ - onSetValidOptionKeyValueInParent(parentOption: string, option: CommandLineOption, value: CompilerOptionsValue): void; + onSetValidOptionKeyValueInParent(parentOption: string, option: ts.CommandLineOption, value: ts.CompilerOptionsValue): void; /** * Notify when valid root key value option is being set * @param key option key @@ -1980,7 +1958,7 @@ namespace ts { * @param value computed value of the key * @param ValueNode node corresponding to value in the source file */ - onSetValidOptionKeyValueInRoot(key: string, keyNode: PropertyName, value: CompilerOptionsValue, valueNode: Expression): void; + onSetValidOptionKeyValueInRoot(key: string, keyNode: ts.PropertyName, value: ts.CompilerOptionsValue, valueNode: ts.Expression): void; /** * Notify when unknown root key value option is being set * @param key option key @@ -1988,24 +1966,19 @@ namespace ts { * @param value computed value of the key * @param ValueNode node corresponding to value in the source file */ - onSetUnknownOptionKeyValueInRoot(key: string, keyNode: PropertyName, value: CompilerOptionsValue, valueNode: Expression): void; + onSetUnknownOptionKeyValueInRoot(key: string, keyNode: ts.PropertyName, value: ts.CompilerOptionsValue, valueNode: ts.Expression): void; } - function convertConfigFileToObject(sourceFile: JsonSourceFile, errors: Push, reportOptionsErrors: boolean, optionsIterator: JsonConversionNotifier | undefined): any { - const rootExpression: Expression | undefined = sourceFile.statements[0]?.expression; + function convertConfigFileToObject(sourceFile: ts.JsonSourceFile, errors: ts.Push, reportOptionsErrors: boolean, optionsIterator: JsonConversionNotifier | undefined): any { + const rootExpression: ts.Expression | undefined = sourceFile.statements[0]?.expression; const knownRootOptions = reportOptionsErrors ? getTsconfigRootOptionsMap() : undefined; - if (rootExpression && rootExpression.kind !== SyntaxKind.ObjectLiteralExpression) { - errors.push(createDiagnosticForNodeInSourceFile( - sourceFile, - rootExpression, - Diagnostics.The_root_value_of_a_0_file_must_be_an_object, - getBaseFileName(sourceFile.fileName) === "jsconfig.json" ? "jsconfig.json" : "tsconfig.json" - )); + if (rootExpression && rootExpression.kind !== ts.SyntaxKind.ObjectLiteralExpression) { + errors.push(ts.createDiagnosticForNodeInSourceFile(sourceFile, rootExpression, ts.Diagnostics.The_root_value_of_a_0_file_must_be_an_object, ts.getBaseFileName(sourceFile.fileName) === "jsconfig.json" ? "jsconfig.json" : "tsconfig.json")); // Last-ditch error recovery. Somewhat useful because the JSON parser will recover from some parse errors by // synthesizing a top-level array literal expression. There's a reasonable chance the first element of that // array is a well-formed configuration object, made into an array element by stray characters. - if (isArrayLiteralExpression(rootExpression)) { - const firstObject = find(rootExpression.elements, isObjectLiteralExpression); + if (ts.isArrayLiteralExpression(rootExpression)) { + const firstObject = ts.find(rootExpression.elements, ts.isObjectLiteralExpression); if (firstObject) { return convertToObjectWorker(sourceFile, firstObject, errors, /*returnValue*/ true, knownRootOptions, optionsIterator); } @@ -2018,7 +1991,7 @@ namespace ts { /** * Convert the json syntax tree into the json value */ - export function convertToObject(sourceFile: JsonSourceFile, errors: Push): any { + export function convertToObject(sourceFile: ts.JsonSourceFile, errors: ts.Push): any { return convertToObjectWorker(sourceFile, sourceFile.statements[0]?.expression, errors, /*returnValue*/ true, /*knownRootOptions*/ undefined, /*jsonConversionNotifier*/ undefined); } @@ -2028,56 +2001,40 @@ namespace ts { * Otherwise it just checks the errors and returns undefined */ /*@internal*/ - export function convertToObjectWorker( - sourceFile: JsonSourceFile, - rootExpression: Expression | undefined, - errors: Push, - returnValue: boolean, - knownRootOptions: CommandLineOption | undefined, - jsonConversionNotifier: JsonConversionNotifier | undefined): any { + export function convertToObjectWorker(sourceFile: ts.JsonSourceFile, rootExpression: ts.Expression | undefined, errors: ts.Push, returnValue: boolean, knownRootOptions: ts.CommandLineOption | undefined, jsonConversionNotifier: JsonConversionNotifier | undefined): any { if (!rootExpression) { return returnValue ? {} : undefined; } return convertPropertyValueToJson(rootExpression, knownRootOptions); - function isRootOptionMap(knownOptions: ESMap | undefined) { - return knownRootOptions && (knownRootOptions as TsConfigOnlyOption).elementOptions === knownOptions; + function isRootOptionMap(knownOptions: ts.ESMap | undefined) { + return knownRootOptions && (knownRootOptions as ts.TsConfigOnlyOption).elementOptions === knownOptions; } - - function convertObjectLiteralExpressionToJson( - node: ObjectLiteralExpression, - knownOptions: ESMap | undefined, - extraKeyDiagnostics: DidYouMeanOptionsDiagnostics | undefined, - parentOption: string | undefined - ): any { + function convertObjectLiteralExpressionToJson(node: ts.ObjectLiteralExpression, knownOptions: ts.ESMap | undefined, extraKeyDiagnostics: ts.DidYouMeanOptionsDiagnostics | undefined, parentOption: string | undefined): any { const result: any = returnValue ? {} : undefined; for (const element of node.properties) { - if (element.kind !== SyntaxKind.PropertyAssignment) { - errors.push(createDiagnosticForNodeInSourceFile(sourceFile, element, Diagnostics.Property_assignment_expected)); + if (element.kind !== ts.SyntaxKind.PropertyAssignment) { + errors.push(ts.createDiagnosticForNodeInSourceFile(sourceFile, element, ts.Diagnostics.Property_assignment_expected)); continue; } if (element.questionToken) { - errors.push(createDiagnosticForNodeInSourceFile(sourceFile, element.questionToken, Diagnostics.The_0_modifier_can_only_be_used_in_TypeScript_files, "?")); + errors.push(ts.createDiagnosticForNodeInSourceFile(sourceFile, element.questionToken, ts.Diagnostics.The_0_modifier_can_only_be_used_in_TypeScript_files, "?")); } if (!isDoubleQuotedString(element.name)) { - errors.push(createDiagnosticForNodeInSourceFile(sourceFile, element.name, Diagnostics.String_literal_with_double_quotes_expected)); + errors.push(ts.createDiagnosticForNodeInSourceFile(sourceFile, element.name, ts.Diagnostics.String_literal_with_double_quotes_expected)); } - const textOfKey = isComputedNonLiteralName(element.name) ? undefined : getTextOfPropertyName(element.name); - const keyText = textOfKey && unescapeLeadingUnderscores(textOfKey); + const textOfKey = ts.isComputedNonLiteralName(element.name) ? undefined : ts.getTextOfPropertyName(element.name); + const keyText = textOfKey && ts.unescapeLeadingUnderscores(textOfKey); const option = keyText && knownOptions ? knownOptions.get(keyText) : undefined; if (keyText && extraKeyDiagnostics && !option) { if (knownOptions) { - errors.push(createUnknownOptionError( - keyText, - extraKeyDiagnostics, - (message, arg0, arg1) => createDiagnosticForNodeInSourceFile(sourceFile, element.name, message, arg0, arg1) - )); + errors.push(createUnknownOptionError(keyText, extraKeyDiagnostics, (message, arg0, arg1) => ts.createDiagnosticForNodeInSourceFile(sourceFile, element.name, message, arg0, arg1))); } else { - errors.push(createDiagnosticForNodeInSourceFile(sourceFile, element.name, extraKeyDiagnostics.unknownOptionDiagnostic, keyText)); + errors.push(ts.createDiagnosticForNodeInSourceFile(sourceFile, element.name, extraKeyDiagnostics.unknownOptionDiagnostic, keyText)); } } const value = convertPropertyValueToJson(element.initializer, option); @@ -2112,69 +2069,59 @@ namespace ts { return result; } - function convertArrayLiteralExpressionToJson( - elements: NodeArray, - elementOption: CommandLineOption | undefined - ) { + function convertArrayLiteralExpressionToJson(elements: ts.NodeArray, elementOption: ts.CommandLineOption | undefined) { if (!returnValue) { elements.forEach(element => convertPropertyValueToJson(element, elementOption)); return undefined; } // Filter out invalid values - return filter(elements.map(element => convertPropertyValueToJson(element, elementOption)), v => v !== undefined); + return ts.filter(elements.map(element => convertPropertyValueToJson(element, elementOption)), v => v !== undefined); } - function convertPropertyValueToJson(valueExpression: Expression, option: CommandLineOption | undefined): any { + function convertPropertyValueToJson(valueExpression: ts.Expression, option: ts.CommandLineOption | undefined): any { let invalidReported: boolean | undefined; switch (valueExpression.kind) { - case SyntaxKind.TrueKeyword: + case ts.SyntaxKind.TrueKeyword: reportInvalidOptionValue(option && option.type !== "boolean"); return validateValue(/*value*/ true); - case SyntaxKind.FalseKeyword: + case ts.SyntaxKind.FalseKeyword: reportInvalidOptionValue(option && option.type !== "boolean"); return validateValue(/*value*/ false); - case SyntaxKind.NullKeyword: + case ts.SyntaxKind.NullKeyword: reportInvalidOptionValue(option && option.name === "extends"); // "extends" is the only option we don't allow null/undefined for return validateValue(/*value*/ null); // eslint-disable-line no-null/no-null - case SyntaxKind.StringLiteral: + case ts.SyntaxKind.StringLiteral: if (!isDoubleQuotedString(valueExpression)) { - errors.push(createDiagnosticForNodeInSourceFile(sourceFile, valueExpression, Diagnostics.String_literal_with_double_quotes_expected)); + errors.push(ts.createDiagnosticForNodeInSourceFile(sourceFile, valueExpression, ts.Diagnostics.String_literal_with_double_quotes_expected)); } - reportInvalidOptionValue(option && (isString(option.type) && option.type !== "string")); - const text = (valueExpression as StringLiteral).text; - if (option && !isString(option.type)) { - const customOption = option as CommandLineOptionOfCustomType; + reportInvalidOptionValue(option && (ts.isString(option.type) && option.type !== "string")); + const text = (valueExpression as ts.StringLiteral).text; + if (option && !ts.isString(option.type)) { + const customOption = option as ts.CommandLineOptionOfCustomType; // Validate custom option type if (!customOption.type.has(text.toLowerCase())) { - errors.push( - createDiagnosticForInvalidCustomType( - customOption, - (message, arg0, arg1) => createDiagnosticForNodeInSourceFile(sourceFile, valueExpression, message, arg0, arg1) - ) - ); + errors.push(createDiagnosticForInvalidCustomType(customOption, (message, arg0, arg1) => ts.createDiagnosticForNodeInSourceFile(sourceFile, valueExpression, message, arg0, arg1))); invalidReported = true; } } return validateValue(text); - case SyntaxKind.NumericLiteral: + case ts.SyntaxKind.NumericLiteral: reportInvalidOptionValue(option && option.type !== "number"); - return validateValue(Number((valueExpression as NumericLiteral).text)); - - case SyntaxKind.PrefixUnaryExpression: - if ((valueExpression as PrefixUnaryExpression).operator !== SyntaxKind.MinusToken || (valueExpression as PrefixUnaryExpression).operand.kind !== SyntaxKind.NumericLiteral) { + return validateValue(Number((valueExpression as ts.NumericLiteral).text)); + case ts.SyntaxKind.PrefixUnaryExpression: + if ((valueExpression as ts.PrefixUnaryExpression).operator !== ts.SyntaxKind.MinusToken || (valueExpression as ts.PrefixUnaryExpression).operand.kind !== ts.SyntaxKind.NumericLiteral) { break; // not valid JSON syntax } reportInvalidOptionValue(option && option.type !== "number"); - return validateValue(-Number(((valueExpression as PrefixUnaryExpression).operand as NumericLiteral).text)); - - case SyntaxKind.ObjectLiteralExpression: + return validateValue(-Number(((valueExpression as ts.PrefixUnaryExpression).operand as ts.NumericLiteral).text)); + case ts.SyntaxKind.ObjectLiteralExpression: reportInvalidOptionValue(option && option.type !== "object"); - const objectLiteralExpression = valueExpression as ObjectLiteralExpression; + const objectLiteralExpression = valueExpression as ts.ObjectLiteralExpression; // Currently having element option declaration in the tsconfig with type "object" // determines if it needs onSetValidOptionKeyValueInParent callback or not @@ -2183,21 +2130,17 @@ namespace ts { // vs what we set in the json // If need arises, we can modify this interface and callbacks as needed if (option) { - const { elementOptions, extraKeyDiagnostics, name: optionName } = option as TsConfigOnlyOption; - return validateValue(convertObjectLiteralExpressionToJson(objectLiteralExpression, - elementOptions, extraKeyDiagnostics, optionName)); + const { elementOptions, extraKeyDiagnostics, name: optionName } = option as ts.TsConfigOnlyOption; + return validateValue(convertObjectLiteralExpressionToJson(objectLiteralExpression, elementOptions, extraKeyDiagnostics, optionName)); } else { - return validateValue(convertObjectLiteralExpressionToJson( - objectLiteralExpression, /* knownOptions*/ undefined, + return validateValue(convertObjectLiteralExpressionToJson(objectLiteralExpression, /* knownOptions*/ undefined, /*extraKeyDiagnosticMessage */ undefined, /*parentOption*/ undefined)); } - case SyntaxKind.ArrayLiteralExpression: + case ts.SyntaxKind.ArrayLiteralExpression: reportInvalidOptionValue(option && option.type !== "list"); - return validateValue(convertArrayLiteralExpressionToJson( - (valueExpression as ArrayLiteralExpression).elements, - option && (option as CommandLineOptionOfListType).element)); + return validateValue(convertArrayLiteralExpressionToJson((valueExpression as ts.ArrayLiteralExpression).elements, option && (option as ts.CommandLineOptionOfListType).element)); } // Not in expected format @@ -2205,16 +2148,16 @@ namespace ts { reportInvalidOptionValue(/*isError*/ true); } else { - errors.push(createDiagnosticForNodeInSourceFile(sourceFile, valueExpression, Diagnostics.Property_value_can_only_be_string_literal_numeric_literal_true_false_null_object_literal_or_array_literal)); + errors.push(ts.createDiagnosticForNodeInSourceFile(sourceFile, valueExpression, ts.Diagnostics.Property_value_can_only_be_string_literal_numeric_literal_true_false_null_object_literal_or_array_literal)); } return undefined; - function validateValue(value: CompilerOptionsValue) { + function validateValue(value: ts.CompilerOptionsValue) { if (!invalidReported) { const diagnostic = option?.extraValidation?.(value); if (diagnostic) { - errors.push(createDiagnosticForNodeInSourceFile(sourceFile, valueExpression, ...diagnostic)); + errors.push(ts.createDiagnosticForNodeInSourceFile(sourceFile, valueExpression, ...diagnostic)); return undefined; } } @@ -2223,30 +2166,31 @@ namespace ts { function reportInvalidOptionValue(isError: boolean | undefined) { if (isError) { - errors.push(createDiagnosticForNodeInSourceFile(sourceFile, valueExpression, Diagnostics.Compiler_option_0_requires_a_value_of_type_1, option!.name, getCompilerOptionValueTypeString(option!))); + errors.push(ts.createDiagnosticForNodeInSourceFile(sourceFile, valueExpression, ts.Diagnostics.Compiler_option_0_requires_a_value_of_type_1, option!.name, getCompilerOptionValueTypeString(option!))); invalidReported = true; } } } - function isDoubleQuotedString(node: Node): boolean { - return isStringLiteral(node) && isStringDoubleQuoted(node, sourceFile); + function isDoubleQuotedString(node: ts.Node): boolean { + return ts.isStringLiteral(node) && ts.isStringDoubleQuoted(node, sourceFile); } } - function getCompilerOptionValueTypeString(option: CommandLineOption) { + function getCompilerOptionValueTypeString(option: ts.CommandLineOption) { return option.type === "list" ? "Array" : - isString(option.type) ? option.type : "string"; + ts.isString(option.type) ? option.type : "string"; } - function isCompilerOptionsValue(option: CommandLineOption | undefined, value: any): value is CompilerOptionsValue { + function isCompilerOptionsValue(option: ts.CommandLineOption | undefined, value: any): value is ts.CompilerOptionsValue { if (option) { - if (isNullOrUndefined(value)) return true; // All options are undefinable/nullable + if (isNullOrUndefined(value)) + return true; // All options are undefinable/nullable if (option.type === "list") { - return isArray(value); + return ts.isArray(value); } - const expectedType = isString(option.type) ? option.type : "string"; + const expectedType = ts.isString(option.type) ? option.type : "string"; return typeof value === expectedType; } return false; @@ -2254,12 +2198,12 @@ namespace ts { /** @internal */ export interface TSConfig { - compilerOptions: CompilerOptions; + compilerOptions: ts.CompilerOptions; compileOnSave: boolean | undefined; exclude?: readonly string[]; files: readonly string[] | undefined; include?: readonly string[]; - references: readonly ProjectReference[] | undefined; + references: readonly ts.ProjectReference[] | undefined; } /** @internal */ @@ -2275,21 +2219,10 @@ namespace ts { * @param host provides current directory and case sensitivity services */ /** @internal */ - export function convertToTSConfig(configParseResult: ParsedCommandLine, configFileName: string, host: ConvertToTSConfigHost): TSConfig { - const getCanonicalFileName = createGetCanonicalFileName(host.useCaseSensitiveFileNames); - const files = map( - filter( - configParseResult.fileNames, - !configParseResult.options.configFile?.configFileSpecs?.validatedIncludeSpecs ? returnTrue : matchesSpecs( - configFileName, - configParseResult.options.configFile.configFileSpecs.validatedIncludeSpecs, - configParseResult.options.configFile.configFileSpecs.validatedExcludeSpecs, - host, - ) - ), - f => getRelativePathFromFile(getNormalizedAbsolutePath(configFileName, host.getCurrentDirectory()), getNormalizedAbsolutePath(f, host.getCurrentDirectory()), getCanonicalFileName) - ); - const optionMap = serializeCompilerOptions(configParseResult.options, { configFilePath: getNormalizedAbsolutePath(configFileName, host.getCurrentDirectory()), useCaseSensitiveFileNames: host.useCaseSensitiveFileNames }); + export function convertToTSConfig(configParseResult: ts.ParsedCommandLine, configFileName: string, host: ConvertToTSConfigHost): TSConfig { + const getCanonicalFileName = ts.createGetCanonicalFileName(host.useCaseSensitiveFileNames); + const files = ts.map(ts.filter(configParseResult.fileNames, !configParseResult.options.configFile?.configFileSpecs?.validatedIncludeSpecs ? ts.returnTrue : matchesSpecs(configFileName, configParseResult.options.configFile.configFileSpecs.validatedIncludeSpecs, configParseResult.options.configFile.configFileSpecs.validatedExcludeSpecs, host)), f => ts.getRelativePathFromFile(ts.getNormalizedAbsolutePath(configFileName, host.getCurrentDirectory()), ts.getNormalizedAbsolutePath(f, host.getCurrentDirectory()), getCanonicalFileName)); + const optionMap = serializeCompilerOptions(configParseResult.options, { configFilePath: ts.getNormalizedAbsolutePath(configFileName, host.getCurrentDirectory()), useCaseSensitiveFileNames: host.useCaseSensitiveFileNames }); const watchOptionMap = configParseResult.watchOptions && serializeWatchOptions(configParseResult.watchOptions); const config = { compilerOptions: { @@ -2306,8 +2239,8 @@ namespace ts { version: undefined, }, watchOptions: watchOptionMap && optionMapToObject(watchOptionMap), - references: map(configParseResult.projectReferences, r => ({ ...r, path: r.originalPath ? r.originalPath : "", originalPath: undefined })), - files: length(files) ? files : undefined, + references: ts.map(configParseResult.projectReferences, r => ({ ...r, path: r.originalPath ? r.originalPath : "", originalPath: undefined })), + files: ts.length(files) ? files : undefined, ...(configParseResult.options.configFile?.configFileSpecs ? { include: filterSameAsDefaultInclude(configParseResult.options.configFile.configFileSpecs.validatedIncludeSpecs), exclude: configParseResult.options.configFile.configFileSpecs.validatedExcludeSpecs @@ -2317,24 +2250,28 @@ namespace ts { return config; } - function optionMapToObject(optionMap: ESMap): object { + function optionMapToObject(optionMap: ts.ESMap): object { return { - ...arrayFrom(optionMap.entries()).reduce((prev, cur) => ({ ...prev, [cur[0]]: cur[1] }), {}), + ...ts.arrayFrom(optionMap.entries()).reduce((prev, cur) => ({ ...prev, [cur[0]]: cur[1] }), {}), }; } function filterSameAsDefaultInclude(specs: readonly string[] | undefined) { - if (!length(specs)) return undefined; - if (length(specs) !== 1) return specs; - if (specs![0] === defaultIncludeSpec) return undefined; + if (!ts.length(specs)) + return undefined; + if (ts.length(specs) !== 1) + return specs; + if (specs![0] === defaultIncludeSpec) + return undefined; return specs; } function matchesSpecs(path: string, includeSpecs: readonly string[] | undefined, excludeSpecs: readonly string[] | undefined, host: ConvertToTSConfigHost): (path: string) => boolean { - if (!includeSpecs) return returnTrue; - const patterns = getFileMatcherPatterns(path, excludeSpecs, includeSpecs, host.useCaseSensitiveFileNames, host.getCurrentDirectory()); - const excludeRe = patterns.excludePattern && getRegexFromPattern(patterns.excludePattern, host.useCaseSensitiveFileNames); - const includeRe = patterns.includeFilePattern && getRegexFromPattern(patterns.includeFilePattern, host.useCaseSensitiveFileNames); + if (!includeSpecs) + return ts.returnTrue; + const patterns = ts.getFileMatcherPatterns(path, excludeSpecs, includeSpecs, host.useCaseSensitiveFileNames, host.getCurrentDirectory()); + const excludeRe = patterns.excludePattern && ts.getRegexFromPattern(patterns.excludePattern, host.useCaseSensitiveFileNames); + const includeRe = patterns.includeFilePattern && ts.getRegexFromPattern(patterns.includeFilePattern, host.useCaseSensitiveFileNames); if (includeRe) { if (excludeRe) { return path => !(includeRe.test(path) && !excludeRe.test(path)); @@ -2344,10 +2281,10 @@ namespace ts { if (excludeRe) { return path => excludeRe.test(path); } - return returnTrue; + return ts.returnTrue; } - function getCustomTypeMapOfCommandLineOption(optionDefinition: CommandLineOption): ESMap | undefined { + function getCustomTypeMapOfCommandLineOption(optionDefinition: ts.CommandLineOption): ts.ESMap | undefined { if (optionDefinition.type === "string" || optionDefinition.type === "number" || optionDefinition.type === "boolean" || optionDefinition.type === "object") { // this is of a type CommandLineOptionOfPrimitiveType return undefined; @@ -2360,42 +2297,41 @@ namespace ts { } } - function getNameOfCompilerOptionValue(value: CompilerOptionsValue, customTypeMap: ESMap): string | undefined { + function getNameOfCompilerOptionValue(value: ts.CompilerOptionsValue, customTypeMap: ts.ESMap): string | undefined { // There is a typeMap associated with this command-line option so use it to map value back to its name - return forEachEntry(customTypeMap, (mapValue, key) => { + return ts.forEachEntry(customTypeMap, (mapValue, key) => { if (mapValue === value) { return key; } }); } - function serializeCompilerOptions( - options: CompilerOptions, - pathOptions?: { configFilePath: string, useCaseSensitiveFileNames: boolean } - ): ESMap { + function serializeCompilerOptions(options: ts.CompilerOptions, pathOptions?: { + configFilePath: string; + useCaseSensitiveFileNames: boolean; + }): ts.ESMap { return serializeOptionBaseObject(options, getOptionsNameMap(), pathOptions); } - function serializeWatchOptions(options: WatchOptions) { + function serializeWatchOptions(options: ts.WatchOptions) { return serializeOptionBaseObject(options, getWatchOptionsNameMap()); } - function serializeOptionBaseObject( - options: OptionsBase, - { optionsNameMap }: OptionsNameMap, - pathOptions?: { configFilePath: string, useCaseSensitiveFileNames: boolean } - ): ESMap { - const result = new Map(); - const getCanonicalFileName = pathOptions && createGetCanonicalFileName(pathOptions.useCaseSensitiveFileNames); + function serializeOptionBaseObject(options: OptionsBase, { optionsNameMap }: OptionsNameMap, pathOptions?: { + configFilePath: string; + useCaseSensitiveFileNames: boolean; + }): ts.ESMap { + const result = new ts.Map(); + const getCanonicalFileName = pathOptions && ts.createGetCanonicalFileName(pathOptions.useCaseSensitiveFileNames); for (const name in options) { - if (hasProperty(options, name)) { + if (ts.hasProperty(options, name)) { // tsconfig only options cannot be specified via command line, // so we can assume that only types that can appear here string | number | boolean - if (optionsNameMap.has(name) && (optionsNameMap.get(name)!.category === Diagnostics.Command_line_Options || optionsNameMap.get(name)!.category === Diagnostics.Output_Formatting)) { + if (optionsNameMap.has(name) && (optionsNameMap.get(name)!.category === ts.Diagnostics.Command_line_Options || optionsNameMap.get(name)!.category === ts.Diagnostics.Output_Formatting)) { continue; } - const value = options[name] as CompilerOptionsValue; + const value = options[name] as ts.CompilerOptionsValue; const optionDefinition = optionsNameMap.get(name.toLowerCase()); if (optionDefinition) { const customTypeMap = getCustomTypeMapOfCommandLineOption(optionDefinition); @@ -2403,7 +2339,7 @@ namespace ts { // There is no map associated with this compiler option then use the value as-is // This is the case if the value is expect to be string, number, boolean or list of string if (pathOptions && optionDefinition.isFilePath) { - result.set(name, getRelativePathFromFile(pathOptions.configFilePath, getNormalizedAbsolutePath(value as string, getDirectoryPath(pathOptions.configFilePath)), getCanonicalFileName!)); + result.set(name, ts.getRelativePathFromFile(pathOptions.configFilePath, ts.getNormalizedAbsolutePath(value as string, ts.getDirectoryPath(pathOptions.configFilePath)), getCanonicalFileName!)); } else { result.set(name, value); @@ -2428,7 +2364,7 @@ namespace ts { * Generate a list of the compiler options whose value is not the default. * @param options compilerOptions to be evaluated. /** @internal */ - export function getCompilerOptionsDiffValue(options: CompilerOptions, newLine: string): string { + export function getCompilerOptionsDiffValue(options: ts.CompilerOptions, newLine: string): string { const compilerOptionsMap = getSerializedCompilerOption(options); return getOverwrittenDefaultOptions(); @@ -2449,7 +2385,7 @@ namespace ts { if (newValue !== defaultValue) { result.push(`${tab}${cmd.name}: ${newValue}`); } - else if (hasProperty(defaultInitCompilerOptions, cmd.name)) { + else if (ts.hasProperty(defaultInitCompilerOptions, cmd.name)) { result.push(`${tab}${cmd.name}: ${defaultValue}`); } }); @@ -2461,8 +2397,8 @@ namespace ts { * Get the compiler options to be written into the tsconfig.json. * @param options commandlineOptions to be included in the compileOptions. */ - function getSerializedCompilerOption(options: CompilerOptions): ESMap { - const compilerOptions = extend(options, defaultInitCompilerOptions); + function getSerializedCompilerOption(options: ts.CompilerOptions): ts.ESMap { + const compilerOptions = ts.extend(options, defaultInitCompilerOptions); return serializeCompilerOptions(compilerOptions); } /** @@ -2471,7 +2407,7 @@ namespace ts { * @param fileNames array of filenames to be generated into tsconfig.json */ /* @internal */ - export function generateTSConfig(options: CompilerOptions, fileNames: readonly string[], newLine: string): string { + export function generateTSConfig(options: ts.CompilerOptions, fileNames: readonly string[], newLine: string): string { const compilerOptionsMap = getSerializedCompilerOption(options); return writeConfigurations(); @@ -2479,27 +2415,30 @@ namespace ts { return Array(paddingLength + 1).join(" "); } - function isAllowedOptionForOutput({ category, name, isCommandLineOnly }: CommandLineOption): boolean { + function isAllowedOptionForOutput({ category, name, isCommandLineOnly }: ts.CommandLineOption): boolean { // Skip options which do not have a category or have categories which are more niche - const categoriesToSkip = [Diagnostics.Command_line_Options, Diagnostics.Editor_Support, Diagnostics.Compiler_Diagnostics, Diagnostics.Backwards_Compatibility, Diagnostics.Watch_and_Build_Modes, Diagnostics.Output_Formatting]; + const categoriesToSkip = [ts.Diagnostics.Command_line_Options, ts.Diagnostics.Editor_Support, ts.Diagnostics.Compiler_Diagnostics, ts.Diagnostics.Backwards_Compatibility, ts.Diagnostics.Watch_and_Build_Modes, ts.Diagnostics.Output_Formatting]; return !isCommandLineOnly && category !== undefined && (!categoriesToSkip.includes(category) || compilerOptionsMap.has(name)); } function writeConfigurations() { // Filter applicable options to place in the file - const categorizedOptions = createMultiMap(); + const categorizedOptions = ts.createMultiMap(); for (const option of optionDeclarations) { const { category } = option; if (isAllowedOptionForOutput(option)) { - categorizedOptions.add(getLocaleSpecificMessage(category!), option); + categorizedOptions.add(ts.getLocaleSpecificMessage(category!), option); } } // Serialize all options and their descriptions let marginLength = 0; let seenKnownKeys = 0; - const entries: { value: string, description?: string }[] = []; + const entries: { + value: string; + description?: string; + }[] = []; categorizedOptions.forEach((options, category) => { if (entries.length !== 0) { entries.push({ value: "" }); @@ -2515,7 +2454,7 @@ namespace ts { } entries.push({ value: optionName, - description: `/* ${option.description && getLocaleSpecificMessage(option.description) || option.name} */` + description: `/* ${option.description && ts.getLocaleSpecificMessage(option.description) || option.name} */` }); marginLength = Math.max(optionName.length, marginLength); } @@ -2526,7 +2465,7 @@ namespace ts { const result: string[] = []; result.push(`{`); result.push(`${tab}"compilerOptions": {`); - result.push(`${tab}${tab}/* ${getLocaleSpecificMessage(Diagnostics.Visit_https_Colon_Slash_Slashaka_ms_Slashtsconfig_to_read_more_about_this_file)} */`); + result.push(`${tab}${tab}/* ${ts.getLocaleSpecificMessage(ts.Diagnostics.Visit_https_Colon_Slash_Slashaka_ms_Slashtsconfig_to_read_more_about_this_file)} */`); result.push(""); // Print out each row, aligning all the descriptions on the same column. for (const entry of entries) { @@ -2551,17 +2490,13 @@ namespace ts { } /* @internal */ - export function convertToOptionsWithAbsolutePaths(options: CompilerOptions, toAbsolutePath: (path: string) => string) { - const result: CompilerOptions = {}; + export function convertToOptionsWithAbsolutePaths(options: ts.CompilerOptions, toAbsolutePath: (path: string) => string) { + const result: ts.CompilerOptions = {}; const optionsNameMap = getOptionsNameMap().optionsNameMap; for (const name in options) { - if (hasProperty(options, name)) { - result[name] = convertToOptionValueWithAbsolutePaths( - optionsNameMap.get(name.toLowerCase()), - options[name] as CompilerOptionsValue, - toAbsolutePath - ); + if (ts.hasProperty(options, name)) { + result[name] = convertToOptionValueWithAbsolutePaths(optionsNameMap.get(name.toLowerCase()), options[name] as ts.CompilerOptionsValue, toAbsolutePath); } } if (result.configFilePath) { @@ -2570,7 +2505,7 @@ namespace ts { return result; } - function convertToOptionValueWithAbsolutePaths(option: CommandLineOption | undefined, value: CompilerOptionsValue, toAbsolutePath: (path: string) => string) { + function convertToOptionValueWithAbsolutePaths(option: ts.CommandLineOption | undefined, value: ts.CompilerOptionsValue, toAbsolutePath: (path: string) => string) { if (option && !isNullOrUndefined(value)) { if (option.type === "list") { const values = value as readonly (string | number)[]; @@ -2592,7 +2527,7 @@ namespace ts { * @param basePath A root directory to resolve relative path entries in the config * file to. e.g. outDir */ - export function parseJsonConfigFileContent(json: any, host: ParseConfigHost, basePath: string, existingOptions?: CompilerOptions, configFileName?: string, resolutionStack?: Path[], extraFileExtensions?: readonly FileExtensionInfo[], extendedConfigCache?: Map, existingWatchOptions?: WatchOptions): ParsedCommandLine { + export function parseJsonConfigFileContent(json: any, host: ts.ParseConfigHost, basePath: string, existingOptions?: ts.CompilerOptions, configFileName?: string, resolutionStack?: ts.Path[], extraFileExtensions?: readonly ts.FileExtensionInfo[], extendedConfigCache?: ts.Map, existingWatchOptions?: ts.WatchOptions): ts.ParsedCommandLine { return parseJsonConfigFileContentWorker(json, /*sourceFile*/ undefined, host, basePath, existingOptions, existingWatchOptions, configFileName, resolutionStack, extraFileExtensions, extendedConfigCache); } @@ -2603,15 +2538,15 @@ namespace ts { * @param basePath A root directory to resolve relative path entries in the config * file to. e.g. outDir */ - export function parseJsonSourceFileConfigFileContent(sourceFile: TsConfigSourceFile, host: ParseConfigHost, basePath: string, existingOptions?: CompilerOptions, configFileName?: string, resolutionStack?: Path[], extraFileExtensions?: readonly FileExtensionInfo[], extendedConfigCache?: Map, existingWatchOptions?: WatchOptions): ParsedCommandLine { - tracing?.push(tracing.Phase.Parse, "parseJsonSourceFileConfigFileContent", { path: sourceFile.fileName }); + export function parseJsonSourceFileConfigFileContent(sourceFile: ts.TsConfigSourceFile, host: ts.ParseConfigHost, basePath: string, existingOptions?: ts.CompilerOptions, configFileName?: string, resolutionStack?: ts.Path[], extraFileExtensions?: readonly ts.FileExtensionInfo[], extendedConfigCache?: ts.Map, existingWatchOptions?: ts.WatchOptions): ts.ParsedCommandLine { + ts.tracing?.push(ts.tracing.Phase.Parse, "parseJsonSourceFileConfigFileContent", { path: sourceFile.fileName }); const result = parseJsonConfigFileContentWorker(/*json*/ undefined, sourceFile, host, basePath, existingOptions, existingWatchOptions, configFileName, resolutionStack, extraFileExtensions, extendedConfigCache); - tracing?.pop(); + ts.tracing?.pop(); return result; } /*@internal*/ - export function setConfigFileInOptions(options: CompilerOptions, configFile: TsConfigSourceFile | undefined) { + export function setConfigFileInOptions(options: ts.CompilerOptions, configFile: ts.TsConfigSourceFile | undefined) { if (configFile) { Object.defineProperty(options, "configFile", { enumerable: false, writable: false, value: configFile }); } @@ -2624,7 +2559,7 @@ namespace ts { function directoryOfCombinedPath(fileName: string, basePath: string) { // Use the `getNormalizedAbsolutePath` function to avoid canonicalizing the path, as it must remain noncanonical // until consistent casing errors are reported - return getDirectoryPath(getNormalizedAbsolutePath(fileName, basePath)); + return ts.getDirectoryPath(ts.getNormalizedAbsolutePath(fileName, basePath)); } /*@internal*/ @@ -2639,34 +2574,24 @@ namespace ts { * file to. e.g. outDir * @param resolutionStack Only present for backwards-compatibility. Should be empty. */ - function parseJsonConfigFileContentWorker( - json: any, - sourceFile: TsConfigSourceFile | undefined, - host: ParseConfigHost, - basePath: string, - existingOptions: CompilerOptions = {}, - existingWatchOptions: WatchOptions | undefined, - configFileName?: string, - resolutionStack: Path[] = [], - extraFileExtensions: readonly FileExtensionInfo[] = [], - extendedConfigCache?: ESMap - ): ParsedCommandLine { - Debug.assert((json === undefined && sourceFile !== undefined) || (json !== undefined && sourceFile === undefined)); - const errors: Diagnostic[] = []; + function parseJsonConfigFileContentWorker(json: any, sourceFile: ts.TsConfigSourceFile | undefined, host: ts.ParseConfigHost, basePath: string, existingOptions: ts.CompilerOptions = {}, existingWatchOptions: ts.WatchOptions | undefined, configFileName?: string, resolutionStack: ts.Path[] = [], extraFileExtensions: readonly ts.FileExtensionInfo[] = [], extendedConfigCache?: ts.ESMap): ts.ParsedCommandLine { + ts.Debug.assert((json === undefined && sourceFile !== undefined) || (json !== undefined && sourceFile === undefined)); + const errors: ts.Diagnostic[] = []; const parsedConfig = parseConfig(json, sourceFile, host, basePath, configFileName, resolutionStack, errors, extendedConfigCache); const { raw } = parsedConfig; - const options = extend(existingOptions, parsedConfig.options || {}); + const options = ts.extend(existingOptions, parsedConfig.options || {}); const watchOptions = existingWatchOptions && parsedConfig.watchOptions ? - extend(existingWatchOptions, parsedConfig.watchOptions) : + ts.extend(existingWatchOptions, parsedConfig.watchOptions) : parsedConfig.watchOptions || existingWatchOptions; - options.configFilePath = configFileName && normalizeSlashes(configFileName); + options.configFilePath = configFileName && ts.normalizeSlashes(configFileName); const configFileSpecs = getConfigFileSpecs(); - if (sourceFile) sourceFile.configFileSpecs = configFileSpecs; + if (sourceFile) + sourceFile.configFileSpecs = configFileSpecs; setConfigFileInOptions(options, sourceFile); - const basePathForFileNames = normalizePath(configFileName ? directoryOfCombinedPath(configFileName, basePath) : basePath); + const basePathForFileNames = ts.normalizePath(configFileName ? directoryOfCombinedPath(configFileName, basePath) : basePath); return { options, watchOptions, @@ -2683,24 +2608,24 @@ namespace ts { compileOnSave: !!raw.compileOnSave, }; - function getConfigFileSpecs(): ConfigFileSpecs { - const referencesOfRaw = getPropFromRaw("references", element => typeof element === "object", "object"); + function getConfigFileSpecs(): ts.ConfigFileSpecs { + const referencesOfRaw = getPropFromRaw("references", element => typeof element === "object", "object"); const filesSpecs = toPropValue(getSpecsFromRaw("files")); if (filesSpecs) { - const hasZeroOrNoReferences = referencesOfRaw === "no-prop" || isArray(referencesOfRaw) && referencesOfRaw.length === 0; - const hasExtends = hasProperty(raw, "extends"); + const hasZeroOrNoReferences = referencesOfRaw === "no-prop" || ts.isArray(referencesOfRaw) && referencesOfRaw.length === 0; + const hasExtends = ts.hasProperty(raw, "extends"); if (filesSpecs.length === 0 && hasZeroOrNoReferences && !hasExtends) { if (sourceFile) { const fileName = configFileName || "tsconfig.json"; - const diagnosticMessage = Diagnostics.The_files_list_in_config_file_0_is_empty; - const nodeValue = firstDefined(getTsConfigPropArray(sourceFile, "files"), property => property.initializer); + const diagnosticMessage = ts.Diagnostics.The_files_list_in_config_file_0_is_empty; + const nodeValue = ts.firstDefined(ts.getTsConfigPropArray(sourceFile, "files"), property => property.initializer); const error = nodeValue - ? createDiagnosticForNodeInSourceFile(sourceFile, nodeValue, diagnosticMessage, fileName) - : createCompilerDiagnostic(diagnosticMessage, fileName); + ? ts.createDiagnosticForNodeInSourceFile(sourceFile, nodeValue, diagnosticMessage, fileName) + : ts.createCompilerDiagnostic(diagnosticMessage, fileName); errors.push(error); } else { - createCompilerDiagnosticOnlyIfJson(Diagnostics.The_files_list_in_config_file_0_is_empty, configFileName || "tsconfig.json"); + createCompilerDiagnosticOnlyIfJson(ts.Diagnostics.The_files_list_in_config_file_0_is_empty, configFileName || "tsconfig.json"); } } } @@ -2741,10 +2666,10 @@ namespace ts { filesSpecs, includeSpecs, excludeSpecs, - validatedFilesSpec: filter(filesSpecs, isString), + validatedFilesSpec: ts.filter(filesSpecs, ts.isString), validatedIncludeSpecs, validatedExcludeSpecs, - pathPatterns: undefined, // Initialized on first use + pathPatterns: undefined, isDefaultIncludeSpec, }; } @@ -2757,17 +2682,17 @@ namespace ts { return fileNames; } - function getProjectReferences(basePath: string): readonly ProjectReference[] | undefined { - let projectReferences: ProjectReference[] | undefined; - const referencesOfRaw = getPropFromRaw("references", element => typeof element === "object", "object"); - if (isArray(referencesOfRaw)) { + function getProjectReferences(basePath: string): readonly ts.ProjectReference[] | undefined { + let projectReferences: ts.ProjectReference[] | undefined; + const referencesOfRaw = getPropFromRaw("references", element => typeof element === "object", "object"); + if (ts.isArray(referencesOfRaw)) { for (const ref of referencesOfRaw) { if (typeof ref.path !== "string") { - createCompilerDiagnosticOnlyIfJson(Diagnostics.Compiler_option_0_requires_a_value_of_type_1, "reference.path", "string"); + createCompilerDiagnosticOnlyIfJson(ts.Diagnostics.Compiler_option_0_requires_a_value_of_type_1, "reference.path", "string"); } else { (projectReferences || (projectReferences = [])).push({ - path: getNormalizedAbsolutePath(ref.path, basePath), + path: ts.getNormalizedAbsolutePath(ref.path, basePath), originalPath: ref.path, prepend: ref.prepend, circular: ref.circular @@ -2780,75 +2705,71 @@ namespace ts { type PropOfRaw = readonly T[] | "not-array" | "no-prop"; function toPropValue(specResult: PropOfRaw) { - return isArray(specResult) ? specResult : undefined; + return ts.isArray(specResult) ? specResult : undefined; } function getSpecsFromRaw(prop: "files" | "include" | "exclude"): PropOfRaw { - return getPropFromRaw(prop, isString, "string"); + return getPropFromRaw(prop, ts.isString, "string"); } function getPropFromRaw(prop: "files" | "include" | "exclude" | "references", validateElement: (value: unknown) => boolean, elementTypeName: string): PropOfRaw { - if (hasProperty(raw, prop) && !isNullOrUndefined(raw[prop])) { - if (isArray(raw[prop])) { + if (ts.hasProperty(raw, prop) && !isNullOrUndefined(raw[prop])) { + if (ts.isArray(raw[prop])) { const result = raw[prop] as T[]; - if (!sourceFile && !every(result, validateElement)) { - errors.push(createCompilerDiagnostic(Diagnostics.Compiler_option_0_requires_a_value_of_type_1, prop, elementTypeName)); + if (!sourceFile && !ts.every(result, validateElement)) { + errors.push(ts.createCompilerDiagnostic(ts.Diagnostics.Compiler_option_0_requires_a_value_of_type_1, prop, elementTypeName)); } return result; } else { - createCompilerDiagnosticOnlyIfJson(Diagnostics.Compiler_option_0_requires_a_value_of_type_1, prop, "Array"); + createCompilerDiagnosticOnlyIfJson(ts.Diagnostics.Compiler_option_0_requires_a_value_of_type_1, prop, "Array"); return "not-array"; } } return "no-prop"; } - function createCompilerDiagnosticOnlyIfJson(message: DiagnosticMessage, arg0?: string, arg1?: string) { + function createCompilerDiagnosticOnlyIfJson(message: ts.DiagnosticMessage, arg0?: string, arg1?: string) { if (!sourceFile) { - errors.push(createCompilerDiagnostic(message, arg0, arg1)); + errors.push(ts.createCompilerDiagnostic(message, arg0, arg1)); } } } - function isErrorNoInputFiles(error: Diagnostic) { - return error.code === Diagnostics.No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2.code; + function isErrorNoInputFiles(error: ts.Diagnostic) { + return error.code === ts.Diagnostics.No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2.code; } - function getErrorForNoInputFiles({ includeSpecs, excludeSpecs }: ConfigFileSpecs, configFileName: string | undefined) { - return createCompilerDiagnostic( - Diagnostics.No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2, - configFileName || "tsconfig.json", - JSON.stringify(includeSpecs || []), - JSON.stringify(excludeSpecs || [])); + function getErrorForNoInputFiles({ includeSpecs, excludeSpecs }: ts.ConfigFileSpecs, configFileName: string | undefined) { + return ts.createCompilerDiagnostic(ts.Diagnostics.No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2, configFileName || "tsconfig.json", JSON.stringify(includeSpecs || []), JSON.stringify(excludeSpecs || [])); } - function shouldReportNoInputFiles(fileNames: string[], canJsonReportNoInutFiles: boolean, resolutionStack?: Path[]) { + function shouldReportNoInputFiles(fileNames: string[], canJsonReportNoInutFiles: boolean, resolutionStack?: ts.Path[]) { return fileNames.length === 0 && canJsonReportNoInutFiles && (!resolutionStack || resolutionStack.length === 0); } /*@internal*/ export function canJsonReportNoInputFiles(raw: any) { - return !hasProperty(raw, "files") && !hasProperty(raw, "references"); + return !ts.hasProperty(raw, "files") && !ts.hasProperty(raw, "references"); } /*@internal*/ - export function updateErrorForNoInputFiles(fileNames: string[], configFileName: string, configFileSpecs: ConfigFileSpecs, configParseDiagnostics: Diagnostic[], canJsonReportNoInutFiles: boolean) { + export function updateErrorForNoInputFiles(fileNames: string[], configFileName: string, configFileSpecs: ts.ConfigFileSpecs, configParseDiagnostics: ts.Diagnostic[], canJsonReportNoInutFiles: boolean) { const existingErrors = configParseDiagnostics.length; if (shouldReportNoInputFiles(fileNames, canJsonReportNoInutFiles)) { configParseDiagnostics.push(getErrorForNoInputFiles(configFileSpecs, configFileName)); } else { - filterMutate(configParseDiagnostics, error => !isErrorNoInputFiles(error)); + ts.filterMutate(configParseDiagnostics, error => !isErrorNoInputFiles(error)); } return existingErrors !== configParseDiagnostics.length; } export interface ParsedTsconfig { raw: any; - options?: CompilerOptions; - watchOptions?: WatchOptions; - typeAcquisition?: TypeAcquisition; + options?: ts.CompilerOptions; + watchOptions?: ts.WatchOptions; + typeAcquisition?: ts.TypeAcquisition; /** * Note that the case of the config path has not yet been normalized, as no files have been imported into the project yet */ @@ -2863,21 +2784,12 @@ namespace ts { * This *just* extracts options/include/exclude/files out of a config file. * It does *not* resolve the included files. */ - function parseConfig( - json: any, - sourceFile: TsConfigSourceFile | undefined, - host: ParseConfigHost, - basePath: string, - configFileName: string | undefined, - resolutionStack: string[], - errors: Push, - extendedConfigCache?: ESMap - ): ParsedTsconfig { - basePath = normalizeSlashes(basePath); - const resolvedPath = getNormalizedAbsolutePath(configFileName || "", basePath); + function parseConfig(json: any, sourceFile: ts.TsConfigSourceFile | undefined, host: ts.ParseConfigHost, basePath: string, configFileName: string | undefined, resolutionStack: string[], errors: ts.Push, extendedConfigCache?: ts.ESMap): ParsedTsconfig { + basePath = ts.normalizeSlashes(basePath); + const resolvedPath = ts.getNormalizedAbsolutePath(configFileName || "", basePath); if (resolutionStack.indexOf(resolvedPath) >= 0) { - errors.push(createCompilerDiagnostic(Diagnostics.Circularity_detected_while_resolving_configuration_Colon_0, [...resolutionStack, resolvedPath].join(" -> "))); + errors.push(ts.createCompilerDiagnostic(ts.Diagnostics.Circularity_detected_while_resolving_configuration_Colon_0, [...resolutionStack, resolvedPath].join(" -> "))); return { raw: json || convertToObject(sourceFile!, errors) }; } @@ -2902,10 +2814,7 @@ namespace ts { let relativeDifference: string | undefined ; const setPropertyInRawIfNotUndefined = (propertyName: string) => { if (!raw[propertyName] && baseRaw[propertyName]) { - raw[propertyName] = map(baseRaw[propertyName], (path: string) => isRootedDiskPath(path) ? path : combinePaths( - relativeDifference ||= convertToRelativePath(getDirectoryPath(ownConfig.extendedConfigPath!), basePath, createGetCanonicalFileName(host.useCaseSensitiveFileNames)), - path - )); + raw[propertyName] = ts.map(baseRaw[propertyName], (path: string) => ts.isRootedDiskPath(path) ? path : ts.combinePaths(relativeDifference ||= ts.convertToRelativePath(ts.getDirectoryPath(ownConfig.extendedConfigPath!), basePath, ts.createGetCanonicalFileName(host.useCaseSensitiveFileNames)), path)); } }; setPropertyInRawIfNotUndefined("include"); @@ -2914,9 +2823,9 @@ namespace ts { if (raw.compileOnSave === undefined) { raw.compileOnSave = baseRaw.compileOnSave; } - ownConfig.options = assign({}, extendedConfig.options, ownConfig.options); + ownConfig.options = ts.assign({}, extendedConfig.options, ownConfig.options); ownConfig.watchOptions = ownConfig.watchOptions && extendedConfig.watchOptions ? - assign({}, extendedConfig.watchOptions, ownConfig.watchOptions) : + ts.assign({}, extendedConfig.watchOptions, ownConfig.watchOptions) : ownConfig.watchOptions || extendedConfig.watchOptions; // TODO extend type typeAcquisition } @@ -2925,15 +2834,9 @@ namespace ts { return ownConfig; } - function parseOwnConfigOfJson( - json: any, - host: ParseConfigHost, - basePath: string, - configFileName: string | undefined, - errors: Push - ): ParsedTsconfig { - if (hasProperty(json, "excludes")) { - errors.push(createCompilerDiagnostic(Diagnostics.Unknown_option_excludes_Did_you_mean_exclude)); + function parseOwnConfigOfJson(json: any, host: ts.ParseConfigHost, basePath: string, configFileName: string | undefined, errors: ts.Push): ParsedTsconfig { + if (ts.hasProperty(json, "excludes")) { + errors.push(ts.createCompilerDiagnostic(ts.Diagnostics.Unknown_option_excludes_Did_you_mean_exclude)); } const options = convertCompilerOptionsFromJsonWorker(json.compilerOptions, basePath, errors, configFileName); @@ -2945,32 +2848,26 @@ namespace ts { let extendedConfigPath: string | undefined; if (json.extends) { - if (!isString(json.extends)) { - errors.push(createCompilerDiagnostic(Diagnostics.Compiler_option_0_requires_a_value_of_type_1, "extends", "string")); + if (!ts.isString(json.extends)) { + errors.push(ts.createCompilerDiagnostic(ts.Diagnostics.Compiler_option_0_requires_a_value_of_type_1, "extends", "string")); } else { const newBase = configFileName ? directoryOfCombinedPath(configFileName, basePath) : basePath; - extendedConfigPath = getExtendsConfigPath(json.extends, host, newBase, errors, createCompilerDiagnostic); + extendedConfigPath = getExtendsConfigPath(json.extends, host, newBase, errors, ts.createCompilerDiagnostic); } } return { raw: json, options, watchOptions, typeAcquisition, extendedConfigPath }; } - function parseOwnConfigOfJsonSourceFile( - sourceFile: TsConfigSourceFile, - host: ParseConfigHost, - basePath: string, - configFileName: string | undefined, - errors: Push - ): ParsedTsconfig { + function parseOwnConfigOfJsonSourceFile(sourceFile: ts.TsConfigSourceFile, host: ts.ParseConfigHost, basePath: string, configFileName: string | undefined, errors: ts.Push): ParsedTsconfig { const options = getDefaultCompilerOptions(configFileName); - let typeAcquisition: TypeAcquisition | undefined, typingOptionstypeAcquisition: TypeAcquisition | undefined; - let watchOptions: WatchOptions | undefined; + let typeAcquisition: ts.TypeAcquisition | undefined, typingOptionstypeAcquisition: ts.TypeAcquisition | undefined; + let watchOptions: ts.WatchOptions | undefined; let extendedConfigPath: string | undefined; - let rootCompilerOptions: PropertyName[] | undefined; + let rootCompilerOptions: ts.PropertyName[] | undefined; const optionsIterator: JsonConversionNotifier = { - onSetValidOptionKeyValueInParent(parentOption: string, option: CommandLineOption, value: CompilerOptionsValue) { + onSetValidOptionKeyValueInParent(parentOption: string, option: ts.CommandLineOption, value: ts.CompilerOptionsValue) { let currentOption; switch (parentOption) { case "compilerOptions": @@ -2986,32 +2883,25 @@ namespace ts { currentOption = (typingOptionstypeAcquisition || (typingOptionstypeAcquisition = getDefaultTypeAcquisition(configFileName))); break; default: - Debug.fail("Unknown option"); + ts.Debug.fail("Unknown option"); } currentOption[option.name] = normalizeOptionValue(option, basePath, value); }, - onSetValidOptionKeyValueInRoot(key: string, _keyNode: PropertyName, value: CompilerOptionsValue, valueNode: Expression) { + onSetValidOptionKeyValueInRoot(key: string, _keyNode: ts.PropertyName, value: ts.CompilerOptionsValue, valueNode: ts.Expression) { switch (key) { case "extends": const newBase = configFileName ? directoryOfCombinedPath(configFileName, basePath) : basePath; - extendedConfigPath = getExtendsConfigPath( - value as string, - host, - newBase, - errors, - (message, arg0) => - createDiagnosticForNodeInSourceFile(sourceFile, valueNode, message, arg0) - ); + extendedConfigPath = getExtendsConfigPath(value as string, host, newBase, errors, (message, arg0) => ts.createDiagnosticForNodeInSourceFile(sourceFile, valueNode, message, arg0)); return; } }, - onSetUnknownOptionKeyValueInRoot(key: string, keyNode: PropertyName, _value: CompilerOptionsValue, _valueNode: Expression) { + onSetUnknownOptionKeyValueInRoot(key: string, keyNode: ts.PropertyName, _value: ts.CompilerOptionsValue, _valueNode: ts.Expression) { if (key === "excludes") { - errors.push(createDiagnosticForNodeInSourceFile(sourceFile, keyNode, Diagnostics.Unknown_option_excludes_Did_you_mean_exclude)); + errors.push(ts.createDiagnosticForNodeInSourceFile(sourceFile, keyNode, ts.Diagnostics.Unknown_option_excludes_Did_you_mean_exclude)); } - if (find(commandOptionsWithoutBuild, (opt) => opt.name === key)) { - rootCompilerOptions = append(rootCompilerOptions, keyNode); + if (ts.find(commandOptionsWithoutBuild, (opt) => opt.name === key)) { + rootCompilerOptions = ts.append(rootCompilerOptions, keyNode); } } }; @@ -3033,55 +2923,43 @@ namespace ts { } if (rootCompilerOptions && json && json.compilerOptions === undefined) { - errors.push(createDiagnosticForNodeInSourceFile(sourceFile, rootCompilerOptions[0], Diagnostics._0_should_be_set_inside_the_compilerOptions_object_of_the_config_json_file, getTextOfPropertyName(rootCompilerOptions[0]) as string)); + errors.push(ts.createDiagnosticForNodeInSourceFile(sourceFile, rootCompilerOptions[0], ts.Diagnostics._0_should_be_set_inside_the_compilerOptions_object_of_the_config_json_file, ts.getTextOfPropertyName(rootCompilerOptions[0]) as string)); } return { raw: json, options, watchOptions, typeAcquisition, extendedConfigPath }; } - function getExtendsConfigPath( - extendedConfig: string, - host: ParseConfigHost, - basePath: string, - errors: Push, - createDiagnostic: (message: DiagnosticMessage, arg1?: string) => Diagnostic) { - extendedConfig = normalizeSlashes(extendedConfig); - if (isRootedDiskPath(extendedConfig) || startsWith(extendedConfig, "./") || startsWith(extendedConfig, "../")) { - let extendedConfigPath = getNormalizedAbsolutePath(extendedConfig, basePath); - if (!host.fileExists(extendedConfigPath) && !endsWith(extendedConfigPath, Extension.Json)) { + function getExtendsConfigPath(extendedConfig: string, host: ts.ParseConfigHost, basePath: string, errors: ts.Push, createDiagnostic: (message: ts.DiagnosticMessage, arg1?: string) => ts.Diagnostic) { + extendedConfig = ts.normalizeSlashes(extendedConfig); + if (ts.isRootedDiskPath(extendedConfig) || ts.startsWith(extendedConfig, "./") || ts.startsWith(extendedConfig, "../")) { + let extendedConfigPath = ts.getNormalizedAbsolutePath(extendedConfig, basePath); + if (!host.fileExists(extendedConfigPath) && !ts.endsWith(extendedConfigPath, ts.Extension.Json)) { extendedConfigPath = `${extendedConfigPath}.json`; if (!host.fileExists(extendedConfigPath)) { - errors.push(createDiagnostic(Diagnostics.File_0_not_found, extendedConfig)); + errors.push(createDiagnostic(ts.Diagnostics.File_0_not_found, extendedConfig)); return undefined; } } return extendedConfigPath; } // If the path isn't a rooted or relative path, resolve like a module - const resolved = nodeModuleNameResolver(extendedConfig, combinePaths(basePath, "tsconfig.json"), { moduleResolution: ModuleResolutionKind.NodeJs }, host, /*cache*/ undefined, /*projectRefs*/ undefined, /*lookupConfig*/ true); + const resolved = ts.nodeModuleNameResolver(extendedConfig, ts.combinePaths(basePath, "tsconfig.json"), { moduleResolution: ts.ModuleResolutionKind.NodeJs }, host, /*cache*/ undefined, /*projectRefs*/ undefined, /*lookupConfig*/ true); if (resolved.resolvedModule) { return resolved.resolvedModule.resolvedFileName; } - errors.push(createDiagnostic(Diagnostics.File_0_not_found, extendedConfig)); + errors.push(createDiagnostic(ts.Diagnostics.File_0_not_found, extendedConfig)); return undefined; } export interface ExtendedConfigCacheEntry { - extendedResult: TsConfigSourceFile; + extendedResult: ts.TsConfigSourceFile; extendedConfig: ParsedTsconfig | undefined; } - function getExtendedConfig( - sourceFile: TsConfigSourceFile | undefined, - extendedConfigPath: string, - host: ParseConfigHost, - resolutionStack: string[], - errors: Push, - extendedConfigCache?: ESMap - ): ParsedTsconfig | undefined { - const path = host.useCaseSensitiveFileNames ? extendedConfigPath : toFileNameLowerCase(extendedConfigPath); + function getExtendedConfig(sourceFile: ts.TsConfigSourceFile | undefined, extendedConfigPath: string, host: ts.ParseConfigHost, resolutionStack: string[], errors: ts.Push, extendedConfigCache?: ts.ESMap): ParsedTsconfig | undefined { + const path = host.useCaseSensitiveFileNames ? extendedConfigPath : ts.toFileNameLowerCase(extendedConfigPath); let value: ExtendedConfigCacheEntry | undefined; - let extendedResult: TsConfigSourceFile; + let extendedResult: ts.TsConfigSourceFile; let extendedConfig: ParsedTsconfig | undefined; if (extendedConfigCache && (value = extendedConfigCache.get(path))) { ({ extendedResult, extendedConfig } = value); @@ -3089,8 +2967,7 @@ namespace ts { else { extendedResult = readJsonConfigFile(extendedConfigPath, path => host.readFile(path)); if (!extendedResult.parseDiagnostics.length) { - extendedConfig = parseConfig(/*json*/ undefined, extendedResult, host, getDirectoryPath(extendedConfigPath), - getBaseFileName(extendedConfigPath), resolutionStack, errors, extendedConfigCache); + extendedConfig = parseConfig(/*json*/ undefined, extendedResult, host, ts.getDirectoryPath(extendedConfigPath), ts.getBaseFileName(extendedConfigPath), resolutionStack, errors, extendedConfigCache); } if (extendedConfigCache) { extendedConfigCache.set(path, { extendedResult, extendedConfig }); @@ -3109,50 +2986,54 @@ namespace ts { return extendedConfig!; } - function convertCompileOnSaveOptionFromJson(jsonOption: any, basePath: string, errors: Push): boolean { - if (!hasProperty(jsonOption, compileOnSaveCommandLineOption.name)) { + function convertCompileOnSaveOptionFromJson(jsonOption: any, basePath: string, errors: ts.Push): boolean { + if (!ts.hasProperty(jsonOption, compileOnSaveCommandLineOption.name)) { return false; } const result = convertJsonOption(compileOnSaveCommandLineOption, jsonOption.compileOnSave, basePath, errors); return typeof result === "boolean" && result; } - export function convertCompilerOptionsFromJson(jsonOptions: any, basePath: string, configFileName?: string): { options: CompilerOptions, errors: Diagnostic[] } { - const errors: Diagnostic[] = []; + export function convertCompilerOptionsFromJson(jsonOptions: any, basePath: string, configFileName?: string): { + options: ts.CompilerOptions; + errors: ts.Diagnostic[]; + } { + const errors: ts.Diagnostic[] = []; const options = convertCompilerOptionsFromJsonWorker(jsonOptions, basePath, errors, configFileName); return { options, errors }; } - export function convertTypeAcquisitionFromJson(jsonOptions: any, basePath: string, configFileName?: string): { options: TypeAcquisition, errors: Diagnostic[] } { - const errors: Diagnostic[] = []; + export function convertTypeAcquisitionFromJson(jsonOptions: any, basePath: string, configFileName?: string): { + options: ts.TypeAcquisition; + errors: ts.Diagnostic[]; + } { + const errors: ts.Diagnostic[] = []; const options = convertTypeAcquisitionFromJsonWorker(jsonOptions, basePath, errors, configFileName); return { options, errors }; } function getDefaultCompilerOptions(configFileName?: string) { - const options: CompilerOptions = configFileName && getBaseFileName(configFileName) === "jsconfig.json" + const options: ts.CompilerOptions = configFileName && ts.getBaseFileName(configFileName) === "jsconfig.json" ? { allowJs: true, maxNodeModuleJsDepth: 2, allowSyntheticDefaultImports: true, skipLibCheck: true, noEmit: true } : {}; return options; } - function convertCompilerOptionsFromJsonWorker(jsonOptions: any, - basePath: string, errors: Push, configFileName?: string): CompilerOptions { + function convertCompilerOptionsFromJsonWorker(jsonOptions: any, basePath: string, errors: ts.Push, configFileName?: string): ts.CompilerOptions { const options = getDefaultCompilerOptions(configFileName); convertOptionsFromJson(getCommandLineCompilerOptionsMap(), jsonOptions, basePath, options, compilerOptionsDidYouMeanDiagnostics, errors); if (configFileName) { - options.configFilePath = normalizeSlashes(configFileName); + options.configFilePath = ts.normalizeSlashes(configFileName); } return options; } - function getDefaultTypeAcquisition(configFileName?: string): TypeAcquisition { - return { enable: !!configFileName && getBaseFileName(configFileName) === "jsconfig.json", include: [], exclude: [] }; + function getDefaultTypeAcquisition(configFileName?: string): ts.TypeAcquisition { + return { enable: !!configFileName && ts.getBaseFileName(configFileName) === "jsconfig.json", include: [], exclude: [] }; } - function convertTypeAcquisitionFromJsonWorker(jsonOptions: any, - basePath: string, errors: Push, configFileName?: string): TypeAcquisition { + function convertTypeAcquisitionFromJsonWorker(jsonOptions: any, basePath: string, errors: ts.Push, configFileName?: string): ts.TypeAcquisition { const options = getDefaultTypeAcquisition(configFileName); const typeAcquisition = convertEnableAutoDiscoveryToEnable(jsonOptions); @@ -3161,16 +3042,13 @@ namespace ts { return options; } - function convertWatchOptionsFromJsonWorker(jsonOptions: any, basePath: string, errors: Push): WatchOptions | undefined { + function convertWatchOptionsFromJsonWorker(jsonOptions: any, basePath: string, errors: ts.Push): ts.WatchOptions | undefined { return convertOptionsFromJson(getCommandLineWatchOptionsMap(), jsonOptions, basePath, /*defaultOptions*/ undefined, watchOptionsDidYouMeanDiagnostics, errors); } - function convertOptionsFromJson(optionsNameMap: ESMap, jsonOptions: any, basePath: string, - defaultOptions: undefined, diagnostics: DidYouMeanOptionsDiagnostics, errors: Push): WatchOptions | undefined; - function convertOptionsFromJson(optionsNameMap: ESMap, jsonOptions: any, basePath: string, - defaultOptions: CompilerOptions | TypeAcquisition, diagnostics: DidYouMeanOptionsDiagnostics, errors: Push): CompilerOptions | TypeAcquisition; - function convertOptionsFromJson(optionsNameMap: ESMap, jsonOptions: any, basePath: string, - defaultOptions: CompilerOptions | TypeAcquisition | WatchOptions | undefined, diagnostics: DidYouMeanOptionsDiagnostics, errors: Push) { + function convertOptionsFromJson(optionsNameMap: ts.ESMap, jsonOptions: any, basePath: string, defaultOptions: undefined, diagnostics: ts.DidYouMeanOptionsDiagnostics, errors: ts.Push): ts.WatchOptions | undefined; + function convertOptionsFromJson(optionsNameMap: ts.ESMap, jsonOptions: any, basePath: string, defaultOptions: ts.CompilerOptions | ts.TypeAcquisition, diagnostics: ts.DidYouMeanOptionsDiagnostics, errors: ts.Push): ts.CompilerOptions | ts.TypeAcquisition; + function convertOptionsFromJson(optionsNameMap: ts.ESMap, jsonOptions: any, basePath: string, defaultOptions: ts.CompilerOptions | ts.TypeAcquisition | ts.WatchOptions | undefined, diagnostics: ts.DidYouMeanOptionsDiagnostics, errors: ts.Push) { if (!jsonOptions) { return; @@ -3182,48 +3060,49 @@ namespace ts { (defaultOptions || (defaultOptions = {}))[opt.name] = convertJsonOption(opt, jsonOptions[id], basePath, errors); } else { - errors.push(createUnknownOptionError(id, diagnostics, createCompilerDiagnostic)); + errors.push(createUnknownOptionError(id, diagnostics, ts.createCompilerDiagnostic)); } } return defaultOptions; } /*@internal*/ - export function convertJsonOption(opt: CommandLineOption, value: any, basePath: string, errors: Push): CompilerOptionsValue { + export function convertJsonOption(opt: ts.CommandLineOption, value: any, basePath: string, errors: ts.Push): ts.CompilerOptionsValue { if (isCompilerOptionsValue(opt, value)) { const optType = opt.type; - if (optType === "list" && isArray(value)) { + if (optType === "list" && ts.isArray(value)) { return convertJsonOptionOfListType(opt , value, basePath, errors); } - else if (!isString(optType)) { - return convertJsonOptionOfCustomType(opt as CommandLineOptionOfCustomType, value as string, errors); + else if (!ts.isString(optType)) { + return convertJsonOptionOfCustomType(opt as ts.CommandLineOptionOfCustomType, value as string, errors); } const validatedValue = validateJsonOptionValue(opt, value, errors); return isNullOrUndefined(validatedValue) ? validatedValue : normalizeNonListOptionValue(opt, basePath, validatedValue); } else { - errors.push(createCompilerDiagnostic(Diagnostics.Compiler_option_0_requires_a_value_of_type_1, opt.name, getCompilerOptionValueTypeString(opt))); + errors.push(ts.createCompilerDiagnostic(ts.Diagnostics.Compiler_option_0_requires_a_value_of_type_1, opt.name, getCompilerOptionValueTypeString(opt))); } } - function normalizeOptionValue(option: CommandLineOption, basePath: string, value: any): CompilerOptionsValue { - if (isNullOrUndefined(value)) return undefined; + function normalizeOptionValue(option: ts.CommandLineOption, basePath: string, value: any): ts.CompilerOptionsValue { + if (isNullOrUndefined(value)) + return undefined; if (option.type === "list") { const listOption = option; - if (listOption.element.isFilePath || !isString(listOption.element.type)) { - return filter(map(value, v => normalizeOptionValue(listOption.element, basePath, v)), v => listOption.listPreserveFalsyValues ? true : !!v) as CompilerOptionsValue; + if (listOption.element.isFilePath || !ts.isString(listOption.element.type)) { + return ts.filter(ts.map(value, v => normalizeOptionValue(listOption.element, basePath, v)), v => listOption.listPreserveFalsyValues ? true : !!v) as ts.CompilerOptionsValue; } return value; } - else if (!isString(option.type)) { - return option.type.get(isString(value) ? value.toLowerCase() : value); + else if (!ts.isString(option.type)) { + return option.type.get(ts.isString(value) ? value.toLowerCase() : value); } return normalizeNonListOptionValue(option, basePath, value); } - function normalizeNonListOptionValue(option: CommandLineOption, basePath: string, value: any): CompilerOptionsValue { + function normalizeNonListOptionValue(option: ts.CommandLineOption, basePath: string, value: any): ts.CompilerOptionsValue { if (option.isFilePath) { - value = getNormalizedAbsolutePath(value, basePath); + value = ts.getNormalizedAbsolutePath(value, basePath); if (value === "") { value = "."; } @@ -3231,16 +3110,19 @@ namespace ts { return value; } - function validateJsonOptionValue(opt: CommandLineOption, value: T, errors: Push): T | undefined { - if (isNullOrUndefined(value)) return undefined; + function validateJsonOptionValue(opt: ts.CommandLineOption, value: T, errors: ts.Push): T | undefined { + if (isNullOrUndefined(value)) + return undefined; const d = opt.extraValidation?.(value); - if (!d) return value; - errors.push(createCompilerDiagnostic(...d)); + if (!d) + return value; + errors.push(ts.createCompilerDiagnostic(...d)); return undefined; } - function convertJsonOptionOfCustomType(opt: CommandLineOptionOfCustomType, value: string, errors: Push) { - if (isNullOrUndefined(value)) return undefined; + function convertJsonOptionOfCustomType(opt: ts.CommandLineOptionOfCustomType, value: string, errors: ts.Push) { + if (isNullOrUndefined(value)) + return undefined; const key = value.toLowerCase(); const val = opt.type.get(key); if (val !== undefined) { @@ -3251,8 +3133,8 @@ namespace ts { } } - function convertJsonOptionOfListType(option: CommandLineOptionOfListType, values: readonly any[], basePath: string, errors: Push): any[] { - return filter(map(values, v => convertJsonOption(option.element, v, basePath, errors)), v => option.listPreserveFalsyValues ? true : !!v); + function convertJsonOptionOfListType(option: ts.CommandLineOptionOfListType, values: readonly any[], basePath: string, errors: ts.Push): any[] { + return ts.filter(ts.map(values, v => convertJsonOption(option.element, v, basePath, errors)), v => option.listPreserveFalsyValues ? true : !!v); } /** @@ -3292,58 +3174,51 @@ namespace ts { * @param extraFileExtensions optionaly file extra file extension information from host */ /* @internal */ - export function getFileNamesFromConfigSpecs( - configFileSpecs: ConfigFileSpecs, - basePath: string, - options: CompilerOptions, - host: ParseConfigHost, - extraFileExtensions: readonly FileExtensionInfo[] = emptyArray - ): string[] { - basePath = normalizePath(basePath); - - const keyMapper = createGetCanonicalFileName(host.useCaseSensitiveFileNames); + export function getFileNamesFromConfigSpecs(configFileSpecs: ts.ConfigFileSpecs, basePath: string, options: ts.CompilerOptions, host: ts.ParseConfigHost, extraFileExtensions: readonly ts.FileExtensionInfo[] = ts.emptyArray): string[] { + basePath = ts.normalizePath(basePath); + const keyMapper = ts.createGetCanonicalFileName(host.useCaseSensitiveFileNames); // Literal file names (provided via the "files" array in tsconfig.json) are stored in a // file map with a possibly case insensitive key. We use this map later when when including // wildcard paths. - const literalFileMap = new Map(); + const literalFileMap = new ts.Map(); // Wildcard paths (provided via the "includes" array in tsconfig.json) are stored in a // file map with a possibly case insensitive key. We use this map to store paths matched // via wildcard, and to handle extension priority. - const wildcardFileMap = new Map(); + const wildcardFileMap = new ts.Map(); // Wildcard paths of json files (provided via the "includes" array in tsconfig.json) are stored in a // file map with a possibly case insensitive key. We use this map to store paths matched // via wildcard of *.json kind - const wildCardJsonFileMap = new Map(); + const wildCardJsonFileMap = new ts.Map(); const { validatedFilesSpec, validatedIncludeSpecs, validatedExcludeSpecs } = configFileSpecs; // Rather than re-query this for each file and filespec, we query the supported extensions // once and store it on the expansion context. - const supportedExtensions = getSupportedExtensions(options, extraFileExtensions); - const supportedExtensionsWithJsonIfResolveJsonModule = getSupportedExtensionsWithJsonIfResolveJsonModule(options, supportedExtensions); + const supportedExtensions = ts.getSupportedExtensions(options, extraFileExtensions); + const supportedExtensionsWithJsonIfResolveJsonModule = ts.getSupportedExtensionsWithJsonIfResolveJsonModule(options, supportedExtensions); // Literal files are always included verbatim. An "include" or "exclude" specification cannot // remove a literal file. if (validatedFilesSpec) { for (const fileName of validatedFilesSpec) { - const file = getNormalizedAbsolutePath(fileName, basePath); + const file = ts.getNormalizedAbsolutePath(fileName, basePath); literalFileMap.set(keyMapper(file), file); } } let jsonOnlyIncludeRegexes: readonly RegExp[] | undefined; if (validatedIncludeSpecs && validatedIncludeSpecs.length > 0) { - for (const file of host.readDirectory(basePath, flatten(supportedExtensionsWithJsonIfResolveJsonModule), validatedExcludeSpecs, validatedIncludeSpecs, /*depth*/ undefined)) { - if (fileExtensionIs(file, Extension.Json)) { + for (const file of host.readDirectory(basePath, ts.flatten(supportedExtensionsWithJsonIfResolveJsonModule), validatedExcludeSpecs, validatedIncludeSpecs, /*depth*/ undefined)) { + if (ts.fileExtensionIs(file, ts.Extension.Json)) { // Valid only if *.json specified if (!jsonOnlyIncludeRegexes) { - const includes = validatedIncludeSpecs.filter(s => endsWith(s, Extension.Json)); - const includeFilePatterns = map(getRegularExpressionsForWildcards(includes, basePath, "files"), pattern => `^${pattern}$`); - jsonOnlyIncludeRegexes = includeFilePatterns ? includeFilePatterns.map(pattern => getRegexFromPattern(pattern, host.useCaseSensitiveFileNames)) : emptyArray; + const includes = validatedIncludeSpecs.filter(s => ts.endsWith(s, ts.Extension.Json)); + const includeFilePatterns = ts.map(ts.getRegularExpressionsForWildcards(includes, basePath, "files"), pattern => `^${pattern}$`); + jsonOnlyIncludeRegexes = includeFilePatterns ? includeFilePatterns.map(pattern => ts.getRegexFromPattern(pattern, host.useCaseSensitiveFileNames)) : ts.emptyArray; } - const includeIndex = findIndex(jsonOnlyIncludeRegexes, re => re.test(file)); + const includeIndex = ts.findIndex(jsonOnlyIncludeRegexes, re => re.test(file)); if (includeIndex !== -1) { const key = keyMapper(file); if (!literalFileMap.has(key) && !wildCardJsonFileMap.has(key)) { @@ -3375,29 +3250,22 @@ namespace ts { } } - const literalFiles = arrayFrom(literalFileMap.values()); - const wildcardFiles = arrayFrom(wildcardFileMap.values()); - - return literalFiles.concat(wildcardFiles, arrayFrom(wildCardJsonFileMap.values())); + const literalFiles = ts.arrayFrom(literalFileMap.values()); + const wildcardFiles = ts.arrayFrom(wildcardFileMap.values()); + return literalFiles.concat(wildcardFiles, ts.arrayFrom(wildCardJsonFileMap.values())); } /* @internal */ - export function isExcludedFile( - pathToCheck: string, - spec: ConfigFileSpecs, - basePath: string, - useCaseSensitiveFileNames: boolean, - currentDirectory: string - ): boolean { + export function isExcludedFile(pathToCheck: string, spec: ts.ConfigFileSpecs, basePath: string, useCaseSensitiveFileNames: boolean, currentDirectory: string): boolean { const { validatedFilesSpec, validatedIncludeSpecs, validatedExcludeSpecs } = spec; - if (!length(validatedIncludeSpecs) || !length(validatedExcludeSpecs)) return false; - - basePath = normalizePath(basePath); - - const keyMapper = createGetCanonicalFileName(useCaseSensitiveFileNames); + if (!ts.length(validatedIncludeSpecs) || !ts.length(validatedExcludeSpecs)) + return false; + basePath = ts.normalizePath(basePath); + const keyMapper = ts.createGetCanonicalFileName(useCaseSensitiveFileNames); if (validatedFilesSpec) { for (const fileName of validatedFilesSpec) { - if (keyMapper(getNormalizedAbsolutePath(fileName, basePath)) === pathToCheck) return false; + if (keyMapper(ts.getNormalizedAbsolutePath(fileName, basePath)) === pathToCheck) + return false; } } @@ -3410,46 +3278,31 @@ namespace ts { // can be matched in many arbitrary positions when multiple are present, resulting // in bad backtracking (and we don't care which is matched - just that some /.. segment // comes after some **/ segment). - const wildcardIndex = startsWith(s, "**/") ? 0 : s.indexOf("/**/"); + const wildcardIndex = ts.startsWith(s, "**/") ? 0 : s.indexOf("/**/"); if (wildcardIndex === -1) { return false; } - const lastDotIndex = endsWith(s, "/..") ? s.length : s.lastIndexOf("/../"); + const lastDotIndex = ts.endsWith(s, "/..") ? s.length : s.lastIndexOf("/../"); return lastDotIndex > wildcardIndex; } /* @internal */ - export function matchesExclude( - pathToCheck: string, - excludeSpecs: readonly string[] | undefined, - useCaseSensitiveFileNames: boolean, - currentDirectory: string - ) { - return matchesExcludeWorker( - pathToCheck, - filter(excludeSpecs, spec => !invalidDotDotAfterRecursiveWildcard(spec)), - useCaseSensitiveFileNames, - currentDirectory - ); - } - - function matchesExcludeWorker( - pathToCheck: string, - excludeSpecs: readonly string[] | undefined, - useCaseSensitiveFileNames: boolean, - currentDirectory: string, - basePath?: string - ) { - const excludePattern = getRegularExpressionForWildcard(excludeSpecs, combinePaths(normalizePath(currentDirectory), basePath), "exclude"); - const excludeRegex = excludePattern && getRegexFromPattern(excludePattern, useCaseSensitiveFileNames); - if (!excludeRegex) return false; - if (excludeRegex.test(pathToCheck)) return true; - return !hasExtension(pathToCheck) && excludeRegex.test(ensureTrailingDirectorySeparator(pathToCheck)); - } - - function validateSpecs(specs: readonly string[], errors: Push, disallowTrailingRecursion: boolean, jsonSourceFile: TsConfigSourceFile | undefined, specKey: string): readonly string[] { + export function matchesExclude(pathToCheck: string, excludeSpecs: readonly string[] | undefined, useCaseSensitiveFileNames: boolean, currentDirectory: string) { + return matchesExcludeWorker(pathToCheck, ts.filter(excludeSpecs, spec => !invalidDotDotAfterRecursiveWildcard(spec)), useCaseSensitiveFileNames, currentDirectory); + } + function matchesExcludeWorker(pathToCheck: string, excludeSpecs: readonly string[] | undefined, useCaseSensitiveFileNames: boolean, currentDirectory: string, basePath?: string) { + const excludePattern = ts.getRegularExpressionForWildcard(excludeSpecs, ts.combinePaths(ts.normalizePath(currentDirectory), basePath), "exclude"); + const excludeRegex = excludePattern && ts.getRegexFromPattern(excludePattern, useCaseSensitiveFileNames); + if (!excludeRegex) + return false; + if (excludeRegex.test(pathToCheck)) + return true; + return !ts.hasExtension(pathToCheck) && excludeRegex.test(ts.ensureTrailingDirectorySeparator(pathToCheck)); + } + function validateSpecs(specs: readonly string[], errors: ts.Push, disallowTrailingRecursion: boolean, jsonSourceFile: ts.TsConfigSourceFile | undefined, specKey: string): readonly string[] { return specs.filter(spec => { - if (!isString(spec)) return false; + if (!ts.isString(spec)) + return false; const diag = specToDiagnostic(spec, disallowTrailingRecursion); if (diag !== undefined) { errors.push(createDiagnostic(...diag)); @@ -3457,27 +3310,30 @@ namespace ts { return diag === undefined; }); - function createDiagnostic(message: DiagnosticMessage, spec: string): Diagnostic { - const element = getTsConfigPropArrayElementValue(jsonSourceFile, specKey, spec); + function createDiagnostic(message: ts.DiagnosticMessage, spec: string): ts.Diagnostic { + const element = ts.getTsConfigPropArrayElementValue(jsonSourceFile, specKey, spec); return element ? - createDiagnosticForNodeInSourceFile(jsonSourceFile!, element, message, spec) : - createCompilerDiagnostic(message, spec); + ts.createDiagnosticForNodeInSourceFile(jsonSourceFile!, element, message, spec) : + ts.createCompilerDiagnostic(message, spec); } } - function specToDiagnostic(spec: string, disallowTrailingRecursion?: boolean): [DiagnosticMessage, string] | undefined { + function specToDiagnostic(spec: string, disallowTrailingRecursion?: boolean): [ + ts.DiagnosticMessage, + string + ] | undefined { if (disallowTrailingRecursion && invalidTrailingRecursionPattern.test(spec)) { - return [Diagnostics.File_specification_cannot_end_in_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0, spec]; + return [ts.Diagnostics.File_specification_cannot_end_in_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0, spec]; } else if (invalidDotDotAfterRecursiveWildcard(spec)) { - return [Diagnostics.File_specification_cannot_contain_a_parent_directory_that_appears_after_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0, spec]; + return [ts.Diagnostics.File_specification_cannot_contain_a_parent_directory_that_appears_after_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0, spec]; } } /** * Gets directories in a set of include patterns that should be watched for changes. */ - function getWildcardDirectories({ validatedIncludeSpecs: include, validatedExcludeSpecs: exclude }: ConfigFileSpecs, path: string, useCaseSensitiveFileNames: boolean): MapLike { + function getWildcardDirectories({ validatedIncludeSpecs: include, validatedExcludeSpecs: exclude }: ts.ConfigFileSpecs, path: string, useCaseSensitiveFileNames: boolean): ts.MapLike { // We watch a directory recursively if it contains a wildcard anywhere in a directory segment // of the pattern: // @@ -3490,13 +3346,13 @@ namespace ts { // // /a/b/* - Watch /a/b directly to catch any new file // /a/b/a?z - Watch /a/b directly to catch any new file matching a?z - const rawExcludeRegex = getRegularExpressionForWildcard(exclude, path, "exclude"); + const rawExcludeRegex = ts.getRegularExpressionForWildcard(exclude, path, "exclude"); const excludeRegex = rawExcludeRegex && new RegExp(rawExcludeRegex, useCaseSensitiveFileNames ? "" : "i"); - const wildcardDirectories: MapLike = {}; + const wildcardDirectories: ts.MapLike = {}; if (include !== undefined) { const recursiveKeys: string[] = []; for (const file of include) { - const spec = normalizePath(combinePaths(path, file)); + const spec = ts.normalizePath(ts.combinePaths(path, file)); if (excludeRegex && excludeRegex.test(spec)) { continue; } @@ -3507,7 +3363,7 @@ namespace ts { const existingFlags = wildcardDirectories[key]; if (existingFlags === undefined || existingFlags < flags) { wildcardDirectories[key] = flags; - if (flags === WatchDirectoryFlags.Recursive) { + if (flags === ts.WatchDirectoryFlags.Recursive) { recursiveKeys.push(key); } } @@ -3516,9 +3372,9 @@ namespace ts { // Remove any subpaths under an existing recursively watched directory. for (const key in wildcardDirectories) { - if (hasProperty(wildcardDirectories, key)) { + if (ts.hasProperty(wildcardDirectories, key)) { for (const recursiveKey of recursiveKeys) { - if (key !== recursiveKey && containsPath(recursiveKey, key, path, !useCaseSensitiveFileNames)) { + if (key !== recursiveKey && ts.containsPath(recursiveKey, key, path, !useCaseSensitiveFileNames)) { delete wildcardDirectories[key]; } } @@ -3529,7 +3385,10 @@ namespace ts { return wildcardDirectories; } - function getWildcardDirectoryFromSpec(spec: string, useCaseSensitiveFileNames: boolean): { key: string, flags: WatchDirectoryFlags } | undefined { + function getWildcardDirectoryFromSpec(spec: string, useCaseSensitiveFileNames: boolean): { + key: string; + flags: ts.WatchDirectoryFlags; + } | undefined { const match = wildcardDirectoryPattern.exec(spec); if (match) { // We check this with a few `indexOf` calls because 3 `indexOf`/`lastIndexOf` calls is @@ -3538,18 +3397,18 @@ namespace ts { // characters could match any of the central patterns, resulting in bad backtracking. const questionWildcardIndex = spec.indexOf("?"); const starWildcardIndex = spec.indexOf("*"); - const lastDirectorySeperatorIndex = spec.lastIndexOf(directorySeparator); + const lastDirectorySeperatorIndex = spec.lastIndexOf(ts.directorySeparator); return { - key: useCaseSensitiveFileNames ? match[0] : toFileNameLowerCase(match[0]), + key: useCaseSensitiveFileNames ? match[0] : ts.toFileNameLowerCase(match[0]), flags: (questionWildcardIndex !== -1 && questionWildcardIndex < lastDirectorySeperatorIndex) || (starWildcardIndex !== -1 && starWildcardIndex < lastDirectorySeperatorIndex) - ? WatchDirectoryFlags.Recursive : WatchDirectoryFlags.None + ? ts.WatchDirectoryFlags.Recursive : ts.WatchDirectoryFlags.None }; } - if (isImplicitGlob(spec.substring(spec.lastIndexOf(directorySeparator) + 1))) { + if (ts.isImplicitGlob(spec.substring(spec.lastIndexOf(ts.directorySeparator) + 1))) { return { - key: useCaseSensitiveFileNames ? spec : toFileNameLowerCase(spec), - flags: WatchDirectoryFlags.Recursive + key: useCaseSensitiveFileNames ? spec : ts.toFileNameLowerCase(spec), + flags: ts.WatchDirectoryFlags.Recursive }; } return undefined; @@ -3561,18 +3420,18 @@ namespace ts { * * @param file The path to the file. */ - function hasFileWithHigherPriorityExtension(file: string, literalFiles: ESMap, wildcardFiles: ESMap, extensions: readonly string[][], keyMapper: (value: string) => string) { - const extensionGroup = forEach(extensions, group => fileExtensionIsOneOf(file, group) ? group : undefined); + function hasFileWithHigherPriorityExtension(file: string, literalFiles: ts.ESMap, wildcardFiles: ts.ESMap, extensions: readonly string[][], keyMapper: (value: string) => string) { + const extensionGroup = ts.forEach(extensions, group => ts.fileExtensionIsOneOf(file, group) ? group : undefined); if (!extensionGroup) { return false; } for (const ext of extensionGroup) { - if (fileExtensionIs(file, ext)) { + if (ts.fileExtensionIs(file, ext)) { return false; } - const higherPriorityPath = keyMapper(changeExtension(file, ext)); + const higherPriorityPath = keyMapper(ts.changeExtension(file, ext)); if (literalFiles.has(higherPriorityPath) || wildcardFiles.has(higherPriorityPath)) { - if (ext === Extension.Dts && (fileExtensionIs(file, Extension.Js) || fileExtensionIs(file, Extension.Jsx))) { + if (ext === ts.Extension.Dts && (ts.fileExtensionIs(file, ts.Extension.Js) || ts.fileExtensionIs(file, ts.Extension.Jsx))) { // LEGACY BEHAVIOR: An off-by-one bug somewhere in the extension priority system for wildcard module loading allowed declaration // files to be loaded alongside their js(x) counterparts. We regard this as generally undesirable, but retain the behavior to // prevent breakage. @@ -3591,17 +3450,17 @@ namespace ts { * * @param file The path to the file. */ - function removeWildcardFilesWithLowerPriorityExtension(file: string, wildcardFiles: ESMap, extensions: readonly string[][], keyMapper: (value: string) => string) { - const extensionGroup = forEach(extensions, group => fileExtensionIsOneOf(file, group) ? group : undefined); + function removeWildcardFilesWithLowerPriorityExtension(file: string, wildcardFiles: ts.ESMap, extensions: readonly string[][], keyMapper: (value: string) => string) { + const extensionGroup = ts.forEach(extensions, group => ts.fileExtensionIsOneOf(file, group) ? group : undefined); if (!extensionGroup) { return; } for (let i = extensionGroup.length - 1; i >= 0; i--) { const ext = extensionGroup[i]; - if (fileExtensionIs(file, ext)) { + if (ts.fileExtensionIs(file, ext)) { return; } - const lowerPriorityPath = keyMapper(changeExtension(file, ext)); + const lowerPriorityPath = keyMapper(ts.changeExtension(file, ext)); wildcardFiles.delete(lowerPriorityPath); } } @@ -3611,8 +3470,8 @@ namespace ts { * Also converts enum values back to strings. */ /* @internal */ - export function convertCompilerOptionsForTelemetry(opts: CompilerOptions): CompilerOptions { - const out: CompilerOptions = {}; + export function convertCompilerOptionsForTelemetry(opts: ts.CompilerOptions): ts.CompilerOptions { + const out: ts.CompilerOptions = {}; for (const key in opts) { if (opts.hasOwnProperty(key)) { const type = getOptionFromName(key); @@ -3624,7 +3483,7 @@ namespace ts { return out; } - function getOptionValueWithEmptyStrings(value: any, option: CommandLineOption): {} { + function getOptionValueWithEmptyStrings(value: any, option: ts.CommandLineOption): {} { switch (option.type) { case "object": // "paths". Can't get any useful information from the value since we blank out strings, so just return "". return ""; @@ -3636,9 +3495,9 @@ namespace ts { return typeof value === "boolean" ? value : ""; case "list": const elementType = option.element; - return isArray(value) ? value.map(v => getOptionValueWithEmptyStrings(v, elementType)) : ""; + return ts.isArray(value) ? value.map(v => getOptionValueWithEmptyStrings(v, elementType)) : ""; default: - return forEachEntry(option.type, (optionEnumValue, optionStringValue) => { + return ts.forEachEntry(option.type, (optionEnumValue, optionStringValue) => { if (optionEnumValue === value) { return optionStringValue; } @@ -3647,7 +3506,7 @@ namespace ts { } - function getDefaultValueForOption(option: CommandLineOption) { + function getDefaultValueForOption(option: ts.CommandLineOption) { switch (option.type) { case "number": return 1; @@ -3662,8 +3521,9 @@ namespace ts { return {}; default: const iterResult = option.type.keys().next(); - if (!iterResult.done) return iterResult.value; - return Debug.fail("Expected 'option.type' to have entries."); + if (!iterResult.done) + return iterResult.value; + return ts.Debug.fail("Expected 'option.type' to have entries."); } } } diff --git a/src/compiler/core.ts b/src/compiler/core.ts index a3be6f976cdc9..eafdcb28a826f 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -1,27 +1,34 @@ /* @internal */ namespace ts { - export function getIterator | ReadonlyESMap | undefined>(iterable: I): Iterator< - I extends ReadonlyESMap ? [K, V] : - I extends ReadonlySet ? T : - I extends readonly (infer T)[] ? T : - I extends undefined ? undefined : - never>; - export function getIterator(iterable: ReadonlyESMap): Iterator<[K, V]>; - export function getIterator(iterable: ReadonlyESMap | undefined): Iterator<[K, V]> | undefined; - export function getIterator(iterable: readonly T[] | ReadonlySet): Iterator; - export function getIterator(iterable: readonly T[] | ReadonlySet | undefined): Iterator | undefined; - export function getIterator(iterable: readonly any[] | ReadonlySet | ReadonlyESMap | undefined): Iterator | undefined { + export function getIterator | ts.ReadonlyESMap | undefined>(iterable: I): ts.Iterator ? [ + K, + V + ] : I extends ts.ReadonlySet ? T : I extends readonly (infer T)[] ? T : I extends undefined ? undefined : never>; + export function getIterator(iterable: ts.ReadonlyESMap): ts.Iterator<[ + K, + V + ]>; + export function getIterator(iterable: ts.ReadonlyESMap | undefined): ts.Iterator<[ + K, + V + ]> | undefined; + export function getIterator(iterable: readonly T[] | ts.ReadonlySet): ts.Iterator; + export function getIterator(iterable: readonly T[] | ts.ReadonlySet | undefined): ts.Iterator | undefined; + export function getIterator(iterable: readonly any[] | ts.ReadonlySet | ts.ReadonlyESMap | undefined): ts.Iterator | undefined { if (iterable) { - if (isArray(iterable)) return arrayIterator(iterable); - if (iterable instanceof Map) return iterable.entries(); - if (iterable instanceof Set) return iterable.values(); + if (isArray(iterable)) + return arrayIterator(iterable); + if (iterable instanceof ts.Map) + return iterable.entries(); + if (iterable instanceof ts.Set) + return iterable.values(); throw new Error("Iteration not supported."); } } export const emptyArray: never[] = [] as never[]; - export const emptyMap: ReadonlyESMap = new Map(); - export const emptySet: ReadonlySet = new Set(); + export const emptyMap: ts.ReadonlyESMap = new ts.Map(); + export const emptySet: ts.ReadonlySet = new ts.Set(); export function length(array: readonly any[] | undefined): number { return array ? array.length : 0; @@ -74,7 +81,7 @@ namespace ts { return undefined; } - export function firstDefinedIterator(iter: Iterator, callback: (element: T) => U | undefined): U | undefined { + export function firstDefinedIterator(iter: ts.Iterator, callback: (element: T) => U | undefined): U | undefined { while (true) { const iterResult = iter.next(); if (iterResult.done) { @@ -87,7 +94,7 @@ namespace ts { } } - export function reduceLeftIterator(iterator: Iterator | undefined, f: (memo: U, value: T, i: number) => U, initial: U): U { + export function reduceLeftIterator(iterator: ts.Iterator | undefined, f: (memo: U, value: T, i: number) => U, initial: U): U { let result = initial; if (iterator) { for (let step = iterator.next(), pos = 0; !step.done; step = iterator.next(), pos++) { @@ -99,15 +106,18 @@ namespace ts { export function zipWith(arrayA: readonly T[], arrayB: readonly U[], callback: (a: T, b: U, index: number) => V): V[] { const result: V[] = []; - Debug.assertEqual(arrayA.length, arrayB.length); + ts.Debug.assertEqual(arrayA.length, arrayB.length); for (let i = 0; i < arrayA.length; i++) { result.push(callback(arrayA[i], arrayB[i], i)); } return result; } - export function zipToIterator(arrayA: readonly T[], arrayB: readonly U[]): Iterator<[T, U]> { - Debug.assertEqual(arrayA.length, arrayB.length); + export function zipToIterator(arrayA: readonly T[], arrayB: readonly U[]): ts.Iterator<[ + T, + U + ]> { + ts.Debug.assertEqual(arrayA.length, arrayB.length); let i = 0; return { next() { @@ -115,14 +125,17 @@ namespace ts { return { value: undefined as never, done: true }; } i++; - return { value: [arrayA[i - 1], arrayB[i - 1]] as [T, U], done: false }; + return { value: [arrayA[i - 1], arrayB[i - 1]] as [ + T, + U + ], done: false }; } }; } - export function zipToMap(keys: readonly K[], values: readonly V[]): ESMap { - Debug.assert(keys.length === values.length); - const map = new Map(); + export function zipToMap(keys: readonly K[], values: readonly V[]): ts.ESMap { + ts.Debug.assert(keys.length === values.length); + const map = new ts.Map(); for (let i = 0; i < keys.length; ++i) { map.set(keys[i], values[i]); } @@ -139,7 +152,8 @@ namespace ts { } const result: T[] = []; for (let i = 0, n = input.length; i < n; i++) { - if (i) result.push(element); + if (i) + result.push(element); result.push(input[i]); } return result; @@ -217,10 +231,10 @@ namespace ts { return result; } } - return Debug.fail(); + return ts.Debug.fail(); } - export function contains(array: readonly T[] | undefined, value: T, equalityComparer: EqualityComparer = equateValues): boolean { + export function contains(array: readonly T[] | undefined, value: T, equalityComparer: ts.EqualityComparer = equateValues): boolean { if (array) { for (const v of array) { if (equalityComparer(v, value)) { @@ -231,7 +245,7 @@ namespace ts { return false; } - export function arraysEqual(a: readonly T[], b: readonly T[], equalityComparer: EqualityComparer = equateValues): boolean { + export function arraysEqual(a: readonly T[], b: readonly T[], equalityComparer: ts.EqualityComparer = equateValues): boolean { return a.length === b.length && a.every((x, i) => equalityComparer(x, b[i])); } @@ -273,7 +287,8 @@ namespace ts { if (array) { const len = array.length; let i = 0; - while (i < len && f(array[i])) i++; + while (i < len && f(array[i])) + i++; if (i < len) { const result = array.slice(0, i); i++; @@ -319,11 +334,14 @@ namespace ts { } - export function mapIterator(iter: Iterator, mapFn: (x: T) => U): Iterator { + export function mapIterator(iter: ts.Iterator, mapFn: (x: T) => U): ts.Iterator { return { next() { const iterRes = iter.next(); - return iterRes.done ? iterRes as { done: true, value: never } : { value: mapFn(iterRes.value), done: false }; + return iterRes.done ? iterRes as { + done: true; + value: never; + } : { value: mapFn(iterRes.value), done: false }; } }; } @@ -413,7 +431,7 @@ namespace ts { return result; } - export function flatMapIterator(iter: Iterator, mapfn: (x: T) => readonly U[] | Iterator | undefined): Iterator { + export function flatMapIterator(iter: ts.Iterator, mapfn: (x: T) => readonly U[] | ts.Iterator | undefined): ts.Iterator { const first = iter.next(); if (first.done) { return emptyIterator; @@ -428,14 +446,17 @@ namespace ts { } const iterRes = iter.next(); if (iterRes.done) { - return iterRes as { done: true, value: never }; + return iterRes as { + done: true; + value: never; + }; } currentIter = getIterator(iterRes.value); } }, }; - function getIterator(x: T): Iterator { + function getIterator(x: T): ts.Iterator { const res = mapfn(x); return res === undefined ? emptyIterator : isArray(res) ? arrayIterator(res) : res; } @@ -497,13 +518,16 @@ namespace ts { return result; } - export function mapDefinedIterator(iter: Iterator, mapFn: (x: T) => U | undefined): Iterator { + export function mapDefinedIterator(iter: ts.Iterator, mapFn: (x: T) => U | undefined): ts.Iterator { return { next() { while (true) { const res = iter.next(); if (res.done) { - return res as { done: true, value: never }; + return res as { + done: true; + value: never; + }; } const value = mapFn(res.value); if (value !== undefined) { @@ -514,14 +538,23 @@ namespace ts { }; } - export function mapDefinedEntries(map: ReadonlyESMap, f: (key: K1, value: V1) => readonly [K2, V2] | undefined): ESMap; - export function mapDefinedEntries(map: ReadonlyESMap | undefined, f: (key: K1, value: V1) => readonly [K2 | undefined, V2 | undefined] | undefined): ESMap | undefined; - export function mapDefinedEntries(map: ReadonlyESMap | undefined, f: (key: K1, value: V1) => readonly [K2 | undefined, V2 | undefined] | undefined): ESMap | undefined { + export function mapDefinedEntries(map: ts.ReadonlyESMap, f: (key: K1, value: V1) => readonly [ + K2, + V2 + ] | undefined): ts.ESMap; + export function mapDefinedEntries(map: ts.ReadonlyESMap | undefined, f: (key: K1, value: V1) => readonly [ + K2 | undefined, + V2 | undefined + ] | undefined): ts.ESMap | undefined; + export function mapDefinedEntries(map: ts.ReadonlyESMap | undefined, f: (key: K1, value: V1) => readonly [ + K2 | undefined, + V2 | undefined + ] | undefined): ts.ESMap | undefined { if (!map) { return undefined; } - const result = new Map(); + const result = new ts.Map(); map.forEach((value, key) => { const entry = f(key, value); if (entry !== undefined) { @@ -535,11 +568,11 @@ namespace ts { return result; } - export function mapDefinedValues(set: ReadonlySet, f: (value: V1) => V2 | undefined): Set; - export function mapDefinedValues(set: ReadonlySet | undefined, f: (value: V1) => V2 | undefined): Set | undefined; - export function mapDefinedValues(set: ReadonlySet | undefined, f: (value: V1) => V2 | undefined): Set | undefined { + export function mapDefinedValues(set: ts.ReadonlySet, f: (value: V1) => V2 | undefined): ts.Set; + export function mapDefinedValues(set: ts.ReadonlySet | undefined, f: (value: V1) => V2 | undefined): ts.Set | undefined; + export function mapDefinedValues(set: ts.ReadonlySet | undefined, f: (value: V1) => V2 | undefined): ts.Set | undefined { if (set) { - const result = new Set(); + const result = new ts.Set(); set.forEach(value => { const newValue = f(value); if (newValue !== undefined) { @@ -550,7 +583,7 @@ namespace ts { } } - export function getOrUpdate(map: ESMap, key: K, callback: () => V) { + export function getOrUpdate(map: ts.ESMap, key: K, callback: () => V) { if (map.has(key)) { return map.get(key)!; } @@ -559,7 +592,7 @@ namespace ts { return value; } - export function tryAddToSet(set: Set, value: T) { + export function tryAddToSet(set: ts.Set, value: T) { if (!set.has(value)) { set.add(value); return true; @@ -567,9 +600,8 @@ namespace ts { return false; } - export const emptyIterator: Iterator = { next: () => ({ value: undefined as never, done: true }) }; - - export function singleIterator(value: T): Iterator { + export const emptyIterator: ts.Iterator = { next: () => ({ value: undefined as never, done: true }) }; + export function singleIterator(value: T): ts.Iterator { let done = false; return { next() { @@ -629,14 +661,23 @@ namespace ts { return result; } - export function mapEntries(map: ReadonlyESMap, f: (key: K1, value: V1) => readonly [K2, V2]): ESMap; - export function mapEntries(map: ReadonlyESMap | undefined, f: (key: K1, value: V1) => readonly [K2, V2]): ESMap | undefined; - export function mapEntries(map: ReadonlyESMap | undefined, f: (key: K1, value: V1) => readonly [K2, V2]): ESMap | undefined { + export function mapEntries(map: ts.ReadonlyESMap, f: (key: K1, value: V1) => readonly [ + K2, + V2 + ]): ts.ESMap; + export function mapEntries(map: ts.ReadonlyESMap | undefined, f: (key: K1, value: V1) => readonly [ + K2, + V2 + ]): ts.ESMap | undefined; + export function mapEntries(map: ts.ReadonlyESMap | undefined, f: (key: K1, value: V1) => readonly [ + K2, + V2 + ]): ts.ESMap | undefined { if (!map) { return undefined; } - const result = new Map(); + const result = new ts.Map(); map.forEach((value, key) => { const [newKey, newValue] = f(key, value); result.set(newKey, newValue); @@ -676,7 +717,8 @@ namespace ts { } } } - if (start !== undefined) cb(start, arr.length); + if (start !== undefined) + cb(start, arr.length); } export function concatenate(array1: T[], array2: T[]): T[]; @@ -684,8 +726,10 @@ namespace ts { export function concatenate(array1: T[] | undefined, array2: T[] | undefined): T[]; export function concatenate(array1: readonly T[] | undefined, array2: readonly T[] | undefined): readonly T[]; export function concatenate(array1: T[], array2: T[]): T[] { - if (!some(array2)) return array1; - if (!some(array1)) return array2; + if (!some(array2)) + return array1; + if (!some(array1)) + return array2; return [...array1, ...array2]; } @@ -697,7 +741,7 @@ namespace ts { return array.map(selectIndex); } - function deduplicateRelational(array: readonly T[], equalityComparer: EqualityComparer, comparer: Comparer) { + function deduplicateRelational(array: readonly T[], equalityComparer: ts.EqualityComparer, comparer: ts.Comparer) { // Perform a stable sort of the array. This ensures the first entry in a list of // duplicates remains the first entry in the result. const indices = indicesOf(array); @@ -719,7 +763,7 @@ namespace ts { return deduplicated.map(i => array[i]); } - function deduplicateEquality(array: readonly T[], equalityComparer: EqualityComparer) { + function deduplicateEquality(array: readonly T[], equalityComparer: ts.EqualityComparer) { const result: T[] = []; for (const item of array) { pushIfUnique(result, item, equalityComparer); @@ -733,7 +777,7 @@ namespace ts { * @param comparer An optional `Comparer` used to sort entries before comparison, though the * result will remain in the original order in `array`. */ - export function deduplicate(array: readonly T[], equalityComparer: EqualityComparer, comparer?: Comparer): T[] { + export function deduplicate(array: readonly T[], equalityComparer: ts.EqualityComparer, comparer?: ts.Comparer): T[] { return array.length === 0 ? [] : array.length === 1 ? array.slice() : comparer ? deduplicateRelational(array, equalityComparer, comparer) : @@ -743,8 +787,9 @@ namespace ts { /** * Deduplicates an array that has already been sorted. */ - function deduplicateSorted(array: SortedReadonlyArray, comparer: EqualityComparer | Comparer): SortedReadonlyArray { - if (array.length === 0) return emptyArray as any as SortedReadonlyArray; + function deduplicateSorted(array: ts.SortedReadonlyArray, comparer: ts.EqualityComparer | ts.Comparer): ts.SortedReadonlyArray { + if (array.length === 0) + return emptyArray as any as ts.SortedReadonlyArray; let last = array[0]; const deduplicated: T[] = [last]; @@ -756,25 +801,25 @@ namespace ts { // relational comparison // falls through - case Comparison.EqualTo: + case ts.Comparison.EqualTo: continue; - case Comparison.LessThan: + case ts.Comparison.LessThan: // If `array` is sorted, `next` should **never** be less than `last`. - return Debug.fail("Array is unsorted."); + return ts.Debug.fail("Array is unsorted."); } deduplicated.push(last = next); } - return deduplicated as any as SortedReadonlyArray; + return deduplicated as any as ts.SortedReadonlyArray; } - export function createSortedArray(): SortedArray { - return [] as any as SortedArray; // TODO: GH#19873 + export function createSortedArray(): ts.SortedArray { + return [] as any as ts.SortedArray; // TODO: GH#19873 } - export function insertSorted(array: SortedArray, insert: T, compare: Comparer, allowDuplicates?: boolean): void { + export function insertSorted(array: ts.SortedArray, insert: T, compare: ts.Comparer, allowDuplicates?: boolean): void { if (array.length === 0) { array.push(insert); return; @@ -789,17 +834,18 @@ namespace ts { } } - export function sortAndDeduplicate(array: readonly string[]): SortedReadonlyArray; - export function sortAndDeduplicate(array: readonly T[], comparer: Comparer, equalityComparer?: EqualityComparer): SortedReadonlyArray; - export function sortAndDeduplicate(array: readonly T[], comparer?: Comparer, equalityComparer?: EqualityComparer): SortedReadonlyArray { - return deduplicateSorted(sort(array, comparer), equalityComparer || comparer || compareStringsCaseSensitive as any as Comparer); + export function sortAndDeduplicate(array: readonly string[]): ts.SortedReadonlyArray; + export function sortAndDeduplicate(array: readonly T[], comparer: ts.Comparer, equalityComparer?: ts.EqualityComparer): ts.SortedReadonlyArray; + export function sortAndDeduplicate(array: readonly T[], comparer?: ts.Comparer, equalityComparer?: ts.EqualityComparer): ts.SortedReadonlyArray { + return deduplicateSorted(sort(array, comparer), equalityComparer || comparer || compareStringsCaseSensitive as any as ts.Comparer); } - export function arrayIsSorted(array: readonly T[], comparer: Comparer) { - if (array.length < 2) return true; + export function arrayIsSorted(array: readonly T[], comparer: ts.Comparer) { + if (array.length < 2) + return true; let prevElement = array[0]; for (const element of array.slice(1)) { - if (comparer(prevElement, element) === Comparison.GreaterThan) { + if (comparer(prevElement, element) === ts.Comparison.GreaterThan) { return false; } prevElement = element; @@ -856,35 +902,36 @@ namespace ts { * are not present in `arrayA` but are present in `arrayB`. Assumes both arrays are sorted * based on the provided comparer. */ - export function relativeComplement(arrayA: T[] | undefined, arrayB: T[] | undefined, comparer: Comparer): T[] | undefined { - if (!arrayB || !arrayA || arrayB.length === 0 || arrayA.length === 0) return arrayB; + export function relativeComplement(arrayA: T[] | undefined, arrayB: T[] | undefined, comparer: ts.Comparer): T[] | undefined { + if (!arrayB || !arrayA || arrayB.length === 0 || arrayA.length === 0) + return arrayB; const result: T[] = []; loopB: for (let offsetA = 0, offsetB = 0; offsetB < arrayB.length; offsetB++) { if (offsetB > 0) { // Ensure `arrayB` is properly sorted. - Debug.assertGreaterThanOrEqual(comparer(arrayB[offsetB], arrayB[offsetB - 1]), Comparison.EqualTo); + ts.Debug.assertGreaterThanOrEqual(comparer(arrayB[offsetB], arrayB[offsetB - 1]), ts.Comparison.EqualTo); } loopA: for (const startA = offsetA; offsetA < arrayA.length; offsetA++) { if (offsetA > startA) { // Ensure `arrayA` is properly sorted. We only need to perform this check if // `offsetA` has changed since we entered the loop. - Debug.assertGreaterThanOrEqual(comparer(arrayA[offsetA], arrayA[offsetA - 1]), Comparison.EqualTo); + ts.Debug.assertGreaterThanOrEqual(comparer(arrayA[offsetA], arrayA[offsetA - 1]), ts.Comparison.EqualTo); } switch (comparer(arrayB[offsetB], arrayA[offsetA])) { - case Comparison.LessThan: + case ts.Comparison.LessThan: // If B is less than A, B does not exist in arrayA. Add B to the result and // move to the next element in arrayB without changing the current position // in arrayA. result.push(arrayB[offsetB]); continue loopB; - case Comparison.EqualTo: + case ts.Comparison.EqualTo: // If B is equal to A, B exists in arrayA. Move to the next element in // arrayB without adding B to the result or changing the current position // in arrayA. continue loopB; - case Comparison.GreaterThan: + case ts.Comparison.GreaterThan: // If B is greater than A, we need to keep looking for B in arrayA. Move to // the next element in arrayA and recheck. continue loopA; @@ -910,14 +957,22 @@ namespace ts { * @param value The value to append to the array. If `value` is `undefined`, nothing is * appended. */ - export function append[number] | undefined>(to: TArray, value: TValue): [undefined, undefined] extends [TArray, TValue] ? TArray : NonNullable[number][]; + export function append[number] | undefined>(to: TArray, value: TValue): [ + undefined, + undefined + ] extends [ + TArray, + TValue + ] ? TArray : NonNullable[number][]; export function append(to: T[], value: T | undefined): T[]; export function append(to: T[] | undefined, value: T): T[]; export function append(to: T[] | undefined, value: T | undefined): T[] | undefined; - export function append(to: Push, value: T | undefined): void; + export function append(to: ts.Push, value: T | undefined): void; export function append(to: T[], value: T | undefined): T[] | undefined { - if (value === undefined) return to; - if (to === undefined) return [value]; + if (value === undefined) + return to; + if (to === undefined) + return [value]; to.push(value); return to; } @@ -937,10 +992,14 @@ namespace ts { export function combine(xs: T | readonly T[] | undefined, ys: T | readonly T[] | undefined): T | readonly T[] | undefined; export function combine(xs: T | T[] | undefined, ys: T | T[] | undefined): T | T[] | undefined; export function combine(xs: T | T[] | undefined, ys: T | T[] | undefined) { - if (xs === undefined) return ys; - if (ys === undefined) return xs; - if (isArray(xs)) return isArray(ys) ? concatenate(xs, ys) : append(xs, ys); - if (isArray(ys)) return append(ys, xs); + if (xs === undefined) + return ys; + if (ys === undefined) + return xs; + if (isArray(xs)) + return isArray(ys) ? concatenate(xs, ys) : append(xs, ys); + if (isArray(ys)) + return append(ys, xs); return [xs, ys]; } @@ -965,8 +1024,10 @@ namespace ts { export function addRange(to: T[], from: readonly T[] | undefined, start?: number, end?: number): T[]; export function addRange(to: T[] | undefined, from: readonly T[] | undefined, start?: number, end?: number): T[] | undefined; export function addRange(to: T[] | undefined, from: readonly T[] | undefined, start?: number, end?: number): T[] | undefined { - if (from === undefined || from.length === 0) return to; - if (to === undefined) return from.slice(start, end); + if (from === undefined || from.length === 0) + return to; + if (to === undefined) + return from.slice(start, end); start = start === undefined ? 0 : toOffset(from, start); end = end === undefined ? from.length : toOffset(from, end); for (let i = start; i < end && i < from.length; i++) { @@ -980,7 +1041,7 @@ namespace ts { /** * @return Whether the value was added. */ - export function pushIfUnique(array: T[], toAdd: T, equalityComparer?: EqualityComparer): boolean { + export function pushIfUnique(array: T[], toAdd: T, equalityComparer?: ts.EqualityComparer): boolean { if (contains(array, toAdd, equalityComparer)) { return false; } @@ -993,7 +1054,7 @@ namespace ts { /** * Unlike `pushIfUnique`, this can take `undefined` as an input, and returns a new array. */ - export function appendIfUnique(array: T[] | undefined, toAdd: T, equalityComparer?: EqualityComparer): T[] { + export function appendIfUnique(array: T[] | undefined, toAdd: T, equalityComparer?: ts.EqualityComparer): T[] { if (array) { pushIfUnique(array, toAdd, equalityComparer); return array; @@ -1003,7 +1064,7 @@ namespace ts { } } - function stableSortIndices(array: readonly T[], indices: number[], comparer: Comparer) { + function stableSortIndices(array: readonly T[], indices: number[], comparer: ts.Comparer) { // sort indices by value then position indices.sort((x, y) => comparer(array[x], array[y]) || compareValues(x, y)); } @@ -1011,11 +1072,11 @@ namespace ts { /** * Returns a new sorted array. */ - export function sort(array: readonly T[], comparer?: Comparer): SortedReadonlyArray { - return (array.length === 0 ? array : array.slice().sort(comparer)) as SortedReadonlyArray; + export function sort(array: readonly T[], comparer?: ts.Comparer): ts.SortedReadonlyArray { + return (array.length === 0 ? array : array.slice().sort(comparer)) as ts.SortedReadonlyArray; } - export function arrayIterator(array: readonly T[]): Iterator { + export function arrayIterator(array: readonly T[]): ts.Iterator { let i = 0; return { next: () => { if (i === array.length) { @@ -1028,7 +1089,7 @@ namespace ts { }}; } - export function arrayReverseIterator(array: readonly T[]): Iterator { + export function arrayReverseIterator(array: readonly T[]): ts.Iterator { let i = array.length; return { next: () => { @@ -1046,10 +1107,10 @@ namespace ts { /** * Stable sort of an array. Elements equal to each other maintain their relative position in the array. */ - export function stableSort(array: readonly T[], comparer: Comparer): SortedReadonlyArray { + export function stableSort(array: readonly T[], comparer: ts.Comparer): ts.SortedReadonlyArray { const indices = indicesOf(array); stableSortIndices(array, indices, comparer); - return indices.map(i => array[i]) as SortedArray as SortedReadonlyArray; + return indices.map(i => array[i]) as ts.SortedArray as ts.SortedReadonlyArray; } export function rangeEquals(array1: readonly T[], array2: readonly T[], pos: number, end: number) { @@ -1084,7 +1145,7 @@ namespace ts { } export function first(array: readonly T[]): T { - Debug.assert(array.length !== 0); + ts.Debug.assert(array.length !== 0); return array[0]; } @@ -1096,7 +1157,7 @@ namespace ts { } export function last(array: readonly T[]): T { - Debug.assert(array.length !== 0); + ts.Debug.assert(array.length !== 0); return array[array.length - 1]; } @@ -1140,7 +1201,7 @@ namespace ts { * @param keyComparer A callback used to compare two keys in a sorted array. * @param offset An offset into `array` at which to start the search. */ - export function binarySearch(array: readonly T[], value: T, keySelector: (v: T) => U, keyComparer: Comparer, offset?: number): number { + export function binarySearch(array: readonly T[], value: T, keySelector: (v: T) => U, keyComparer: ts.Comparer, offset?: number): number { return binarySearchKey(array, keySelector(value), keySelector, keyComparer, offset); } @@ -1154,7 +1215,7 @@ namespace ts { * @param keyComparer A callback used to compare two keys in a sorted array. * @param offset An offset into `array` at which to start the search. */ - export function binarySearchKey(array: readonly T[], key: U, keySelector: (v: T, i: number) => U, keyComparer: Comparer, offset?: number): number { + export function binarySearchKey(array: readonly T[], key: U, keySelector: (v: T, i: number) => U, keyComparer: ts.Comparer, offset?: number): number { if (!some(array)) { return -1; } @@ -1165,12 +1226,12 @@ namespace ts { const middle = low + ((high - low) >> 1); const midKey = keySelector(array[middle], middle); switch (keyComparer(midKey, key)) { - case Comparison.LessThan: + case ts.Comparison.LessThan: low = middle + 1; break; - case Comparison.EqualTo: + case ts.Comparison.EqualTo: return middle; - case Comparison.GreaterThan: + case ts.Comparison.GreaterThan: high = middle - 1; break; } @@ -1213,7 +1274,7 @@ namespace ts { * @param map A map-like. * @param key A property key. */ - export function hasProperty(map: MapLike, key: string): boolean { + export function hasProperty(map: ts.MapLike, key: string): boolean { return hasOwnProperty.call(map, key); } @@ -1223,14 +1284,14 @@ namespace ts { * @param map A map-like. * @param key A property key. */ - export function getProperty(map: MapLike, key: string): T | undefined { + export function getProperty(map: ts.MapLike, key: string): T | undefined { return hasOwnProperty.call(map, key) ? map[key] : undefined; } /** * Gets the owned, enumerable property keys of a map-like. */ - export function getOwnKeys(map: MapLike): string[] { + export function getOwnKeys(map: ts.MapLike): string[] { const keys: string[] = []; for (const key in map) { if (hasOwnProperty.call(map, key)) { @@ -1252,27 +1313,33 @@ namespace ts { return result; } - export function getOwnValues(collection: MapLike | T[]): T[] { + export function getOwnValues(collection: ts.MapLike | T[]): T[] { const values: T[] = []; for (const key in collection) { if (hasOwnProperty.call(collection, key)) { - values.push((collection as MapLike)[key]); + values.push((collection as ts.MapLike)[key]); } } return values; } - const _entries = Object.entries || ((obj: MapLike) => { + const _entries = Object.entries || ((obj: ts.MapLike) => { const keys = getOwnKeys(obj); - const result: [string, T][] = Array(keys.length); + const result: [ + string, + T + ][] = Array(keys.length); for (let i = 0; i < keys.length; i++) { result[i] = [keys[i], obj[keys[i]]]; } return result; }); - export function getEntries(obj: MapLike): [string, T][] { + export function getEntries(obj: ts.MapLike): [ + string, + T + ][] { return obj ? _entries(obj) : []; } @@ -1285,9 +1352,9 @@ namespace ts { } /** Shims `Array.from`. */ - export function arrayFrom(iterator: Iterator | IterableIterator, map: (t: T) => U): U[]; - export function arrayFrom(iterator: Iterator | IterableIterator): T[]; - export function arrayFrom(iterator: Iterator | IterableIterator, map?: (t: T) => U): (T | U)[] { + export function arrayFrom(iterator: ts.Iterator | IterableIterator, map: (t: T) => U): U[]; + export function arrayFrom(iterator: ts.Iterator | IterableIterator): T[]; + export function arrayFrom(iterator: ts.Iterator | IterableIterator, map?: (t: T) => U): (T | U)[] { const result: (T | U)[] = []; for (let iterResult = iterator.next(); !iterResult.done; iterResult = iterator.next()) { result.push(map ? map(iterResult.value) : iterResult.value); @@ -1298,7 +1365,8 @@ namespace ts { export function assign(t: T, ...args: (T | undefined)[]) { for (const arg of args) { - if (arg === undefined) continue; + if (arg === undefined) + continue; for (const p in arg) { if (hasProperty(arg, p)) { t[p] = arg[p]; @@ -1314,19 +1382,24 @@ namespace ts { * @param left A map-like whose properties should be compared. * @param right A map-like whose properties should be compared. */ - export function equalOwnProperties(left: MapLike | undefined, right: MapLike | undefined, equalityComparer: EqualityComparer = equateValues) { - if (left === right) return true; - if (!left || !right) return false; + export function equalOwnProperties(left: ts.MapLike | undefined, right: ts.MapLike | undefined, equalityComparer: ts.EqualityComparer = equateValues) { + if (left === right) + return true; + if (!left || !right) + return false; for (const key in left) { if (hasOwnProperty.call(left, key)) { - if (!hasOwnProperty.call(right, key)) return false; - if (!equalityComparer(left[key], right[key])) return false; + if (!hasOwnProperty.call(right, key)) + return false; + if (!equalityComparer(left[key], right[key])) + return false; } } for (const key in right) { if (hasOwnProperty.call(right, key)) { - if (!hasOwnProperty.call(left, key)) return false; + if (!hasOwnProperty.call(left, key)) + return false; } } @@ -1343,15 +1416,16 @@ namespace ts { * the same key with the given 'makeKey' function, then the element with the higher * index in the array will be the one associated with the produced key. */ - export function arrayToMap(array: readonly V[], makeKey: (value: V) => K | undefined): ESMap; - export function arrayToMap(array: readonly V1[], makeKey: (value: V1) => K | undefined, makeValue: (value: V1) => V2): ESMap; - export function arrayToMap(array: readonly T[], makeKey: (value: T) => string | undefined): ESMap; - export function arrayToMap(array: readonly T[], makeKey: (value: T) => string | undefined, makeValue: (value: T) => U): ESMap; - export function arrayToMap(array: readonly V1[], makeKey: (value: V1) => K | undefined, makeValue: (value: V1) => V1 | V2 = identity): ESMap { - const result = new Map(); + export function arrayToMap(array: readonly V[], makeKey: (value: V) => K | undefined): ts.ESMap; + export function arrayToMap(array: readonly V1[], makeKey: (value: V1) => K | undefined, makeValue: (value: V1) => V2): ts.ESMap; + export function arrayToMap(array: readonly T[], makeKey: (value: T) => string | undefined): ts.ESMap; + export function arrayToMap(array: readonly T[], makeKey: (value: T) => string | undefined, makeValue: (value: T) => U): ts.ESMap; + export function arrayToMap(array: readonly V1[], makeKey: (value: V1) => K | undefined, makeValue: (value: V1) => V1 | V2 = identity): ts.ESMap { + const result = new ts.Map(); for (const value of array) { const key = makeKey(value); - if (key !== undefined) result.set(key, makeValue(value)); + if (key !== undefined) + result.set(key, makeValue(value)); } return result; } @@ -1428,7 +1502,7 @@ namespace ts { return fn ? fn.bind(obj) : undefined; } - export interface MultiMap extends ESMap { + export interface MultiMap extends ts.ESMap { /** * Adds the value to an array of values associated with the key, and returns the array. * Creates the array if it does not already exist. @@ -1445,7 +1519,7 @@ namespace ts { export function createMultiMap(): MultiMap; export function createMultiMap(): MultiMap; export function createMultiMap(): MultiMap { - const map = new Map() as MultiMap; + const map = new ts.Map() as MultiMap; map.add = multiMapAdd; map.remove = multiMapRemove; return map; @@ -1470,18 +1544,18 @@ namespace ts { } } - export interface UnderscoreEscapedMultiMap extends UnderscoreEscapedMap { + export interface UnderscoreEscapedMultiMap extends ts.UnderscoreEscapedMap { /** * Adds the value to an array of values associated with the key, and returns the array. * Creates the array if it does not already exist. */ - add(key: __String, value: T): T[]; + add(key: ts.__String, value: T): T[]; /** * Removes a value from an array of values associated with the key. * Does not preserve the order of those values. * Does nothing if `key` is not in `map`, or `value` is not in `map[key]`. */ - remove(key: __String, value: T): void; + remove(key: ts.__String, value: T): void; } export function createUnderscoreEscapedMultiMap(): UnderscoreEscapedMultiMap { @@ -1498,13 +1572,13 @@ namespace ts { * To facilitate a perf optimization (lazy allocation of bucket arrays), `TElement` is * assumed not to be an array type. */ - export function createSet(getHashCode: (element: TElement) => THash, equals: EqualityComparer): Set { - const multiMap = new Map(); + export function createSet(getHashCode: (element: TElement) => THash, equals: ts.EqualityComparer): ts.Set { + const multiMap = new ts.Map(); let size = 0; - function getElementIterator(): Iterator { + function getElementIterator(): ts.Iterator { const valueIt = multiMap.values(); - let arrayIt: Iterator | undefined; + let arrayIt: ts.Iterator | undefined; return { next: () => { while (true) { @@ -1530,12 +1604,14 @@ namespace ts { }; } - const set: Set = { + const set: ts.Set = { has(element: TElement): boolean { const hash = getHashCode(element); - if (!multiMap.has(hash)) return false; + if (!multiMap.has(hash)) + return false; const candidates = multiMap.get(hash)!; - if (!isArray(candidates)) return equals(candidates, element); + if (!isArray(candidates)) + return equals(candidates, element); for (const candidate of candidates) { if (equals(candidate, element)) { @@ -1544,7 +1620,7 @@ namespace ts { } return false; }, - add(element: TElement): Set { + add(element: TElement): ts.Set { const hash = getHashCode(element); if (multiMap.has(hash)) { const values = multiMap.get(hash)!; @@ -1571,7 +1647,8 @@ namespace ts { }, delete(element: TElement): boolean { const hash = getHashCode(element); - if (!multiMap.has(hash)) return false; + if (!multiMap.has(hash)) + return false; const candidates = multiMap.get(hash)!; if (isArray(candidates)) { for (let i = 0; i < candidates.length; i++) { @@ -1621,13 +1698,16 @@ namespace ts { } } }, - keys(): Iterator { + keys(): ts.Iterator { return getElementIterator(); }, - values(): Iterator { + values(): ts.Iterator { return getElementIterator(); }, - entries(): Iterator<[TElement, TElement]> { + entries(): ts.Iterator<[ + TElement, + TElement + ]> { const it = getElementIterator(); return { next: () => { @@ -1671,9 +1751,9 @@ namespace ts { } export function cast(value: TIn | undefined, test: (value: TIn) => value is TOut): TOut { - if (value !== undefined && test(value)) return value; - - return Debug.fail(`Invalid cast. The supplied value ${value} did not pass the test '${Debug.getFunctionName(test)}'.`); + if (value !== undefined && test(value)) + return value; + return ts.Debug.fail(`Invalid cast. The supplied value ${value} did not pass the test '${ts.Debug.getFunctionName(test)}'.`); } /** Does nothing. */ @@ -1762,7 +1842,7 @@ namespace ts { /** A version of `memoize` that supports a single primitive argument */ export function memoizeOne(callback: (arg: A) => T): (arg: A) => T { - const map = new Map(); + const map = new ts.Map(); return (arg: A) => { const key = `${typeof arg}:${arg}`; let value = map.get(key); @@ -1811,7 +1891,7 @@ namespace ts { None = 0, Normal = 1, Aggressive = 2, - VeryAggressive = 3, + VeryAggressive = 3 } /** @@ -1850,33 +1930,33 @@ namespace ts { return equateValues(a, b); } - function compareComparableValues(a: string | undefined, b: string | undefined): Comparison; - function compareComparableValues(a: number | undefined, b: number | undefined): Comparison; + function compareComparableValues(a: string | undefined, b: string | undefined): ts.Comparison; + function compareComparableValues(a: number | undefined, b: number | undefined): ts.Comparison; function compareComparableValues(a: string | number | undefined, b: string | number | undefined) { - return a === b ? Comparison.EqualTo : - a === undefined ? Comparison.LessThan : - b === undefined ? Comparison.GreaterThan : - a < b ? Comparison.LessThan : - Comparison.GreaterThan; + return a === b ? ts.Comparison.EqualTo : + a === undefined ? ts.Comparison.LessThan : + b === undefined ? ts.Comparison.GreaterThan : + a < b ? ts.Comparison.LessThan : + ts.Comparison.GreaterThan; } /** * Compare two numeric values for their order relative to each other. * To compare strings, use any of the `compareStrings` functions. */ - export function compareValues(a: number | undefined, b: number | undefined): Comparison { + export function compareValues(a: number | undefined, b: number | undefined): ts.Comparison { return compareComparableValues(a, b); } /** * Compare two TextSpans, first by `start`, then by `length`. */ - export function compareTextSpans(a: Partial | undefined, b: Partial | undefined): Comparison { + export function compareTextSpans(a: Partial | undefined, b: Partial | undefined): ts.Comparison { return compareValues(a?.start, b?.start) || compareValues(a?.length, b?.length); } - export function min(a: T, b: T, compare: Comparer): T { - return compare(a, b) === Comparison.LessThan ? a : b; + export function min(a: T, b: T, compare: ts.Comparer): T { + return compare(a, b) === ts.Comparison.LessThan ? a : b; } /** @@ -1892,12 +1972,15 @@ namespace ts { * lowercase (such as `ẞ` (German sharp capital s)). */ export function compareStringsCaseInsensitive(a: string, b: string) { - if (a === b) return Comparison.EqualTo; - if (a === undefined) return Comparison.LessThan; - if (b === undefined) return Comparison.GreaterThan; + if (a === b) + return ts.Comparison.EqualTo; + if (a === undefined) + return ts.Comparison.LessThan; + if (b === undefined) + return ts.Comparison.GreaterThan; a = a.toUpperCase(); b = b.toUpperCase(); - return a < b ? Comparison.LessThan : a > b ? Comparison.GreaterThan : Comparison.EqualTo; + return a < b ? ts.Comparison.LessThan : a > b ? ts.Comparison.GreaterThan : ts.Comparison.EqualTo; } /** @@ -1910,7 +1993,7 @@ namespace ts { * Case-sensitive comparisons compare both strings one code-point at a time using the integer * value of each code-point. */ - export function compareStringsCaseSensitive(a: string | undefined, b: string | undefined): Comparison { + export function compareStringsCaseSensitive(a: string | undefined, b: string | undefined): ts.Comparison { return compareComparableValues(a, b); } @@ -1922,30 +2005,34 @@ namespace ts { * Creates a string comparer for use with string collation in the UI. */ const createUIStringComparer = (() => { - let defaultComparer: Comparer | undefined; - let enUSComparer: Comparer | undefined; + let defaultComparer: ts.Comparer | undefined; + let enUSComparer: ts.Comparer | undefined; const stringComparerFactory = getStringComparerFactory(); return createStringComparer; function compareWithCallback(a: string | undefined, b: string | undefined, comparer: (a: string, b: string) => number) { - if (a === b) return Comparison.EqualTo; - if (a === undefined) return Comparison.LessThan; - if (b === undefined) return Comparison.GreaterThan; + if (a === b) + return ts.Comparison.EqualTo; + if (a === undefined) + return ts.Comparison.LessThan; + if (b === undefined) + return ts.Comparison.GreaterThan; const value = comparer(a, b); - return value < 0 ? Comparison.LessThan : value > 0 ? Comparison.GreaterThan : Comparison.EqualTo; + return value < 0 ? ts.Comparison.LessThan : value > 0 ? ts.Comparison.GreaterThan : ts.Comparison.EqualTo; } - function createIntlCollatorStringComparer(locale: string | undefined): Comparer { + function createIntlCollatorStringComparer(locale: string | undefined): ts.Comparer { // Intl.Collator.prototype.compare is bound to the collator. See NOTE in // http://www.ecma-international.org/ecma-402/2.0/#sec-Intl.Collator.prototype.compare const comparer = new Intl.Collator(locale, { usage: "sort", sensitivity: "variant" }).compare; return (a, b) => compareWithCallback(a, b, comparer); } - function createLocaleCompareStringComparer(locale: string | undefined): Comparer { + function createLocaleCompareStringComparer(locale: string | undefined): ts.Comparer { // if the locale is not the default locale (`undefined`), use the fallback comparer. - if (locale !== undefined) return createFallbackStringComparer(); + if (locale !== undefined) + return createFallbackStringComparer(); return (a, b) => compareWithCallback(a, b, compareStrings); @@ -1954,7 +2041,7 @@ namespace ts { } } - function createFallbackStringComparer(): Comparer { + function createFallbackStringComparer(): ts.Comparer { // An ordinal comparison puts "A" after "b", but for the UI we want "A" before "b". // We first sort case insensitively. So "Aaa" will come before "baa". // Then we sort case sensitively, so "aaa" will come before "Aaa". @@ -1969,7 +2056,7 @@ namespace ts { } function compareStrings(a: string, b: string) { - return a < b ? Comparison.LessThan : a > b ? Comparison.GreaterThan : Comparison.EqualTo; + return a < b ? ts.Comparison.LessThan : a > b ? ts.Comparison.GreaterThan : ts.Comparison.EqualTo; } } @@ -2006,7 +2093,7 @@ namespace ts { } })(); - let uiComparerCaseSensitive: Comparer | undefined; + let uiComparerCaseSensitive: ts.Comparer | undefined; let uiLocale: string | undefined; export function getUILocale() { @@ -2035,15 +2122,15 @@ namespace ts { return comparer(a, b); } - export function compareProperties(a: T | undefined, b: T | undefined, key: K, comparer: Comparer): Comparison { - return a === b ? Comparison.EqualTo : - a === undefined ? Comparison.LessThan : - b === undefined ? Comparison.GreaterThan : + export function compareProperties(a: T | undefined, b: T | undefined, key: K, comparer: ts.Comparer): ts.Comparison { + return a === b ? ts.Comparison.EqualTo : + a === undefined ? ts.Comparison.LessThan : + b === undefined ? ts.Comparison.GreaterThan : comparer(a[key], b[key]); } /** True is greater than false. */ - export function compareBooleans(a: boolean, b: boolean): Comparison { + export function compareBooleans(a: boolean, b: boolean): ts.Comparison { return compareValues(a ? 1 : 0, b ? 1 : 0); } @@ -2080,7 +2167,7 @@ namespace ts { continue; } - Debug.assert(distance < bestDistance); // Else `levenshteinWithMax` should return undefined + ts.Debug.assert(distance < bestDistance); // Else `levenshteinWithMax` should return undefined bestDistance = distance; bestCandidate = candidate; } @@ -2165,24 +2252,24 @@ namespace ts { for (let pos = end - 1; pos > 0; pos--) { let ch: number = fileName.charCodeAt(pos); - if (ch >= CharacterCodes._0 && ch <= CharacterCodes._9) { + if (ch >= ts.CharacterCodes._0 && ch <= ts.CharacterCodes._9) { // Match a \d+ segment do { --pos; ch = fileName.charCodeAt(pos); - } while (pos > 0 && ch >= CharacterCodes._0 && ch <= CharacterCodes._9); + } while (pos > 0 && ch >= ts.CharacterCodes._0 && ch <= ts.CharacterCodes._9); } - else if (pos > 4 && (ch === CharacterCodes.n || ch === CharacterCodes.N)) { + else if (pos > 4 && (ch === ts.CharacterCodes.n || ch === ts.CharacterCodes.N)) { // Looking for "min" or "min" // Already matched the 'n' --pos; ch = fileName.charCodeAt(pos); - if (ch !== CharacterCodes.i && ch !== CharacterCodes.I) { + if (ch !== ts.CharacterCodes.i && ch !== ts.CharacterCodes.I) { break; } --pos; ch = fileName.charCodeAt(pos); - if (ch !== CharacterCodes.m && ch !== CharacterCodes.M) { + if (ch !== ts.CharacterCodes.m && ch !== ts.CharacterCodes.M) { break; } --pos; @@ -2193,7 +2280,7 @@ namespace ts { break; } - if (ch !== CharacterCodes.minus && ch !== CharacterCodes.dot) { + if (ch !== ts.CharacterCodes.minus && ch !== ts.CharacterCodes.dot) { break; } @@ -2266,7 +2353,7 @@ namespace ts { * E.g.: matchedText(tryParsePattern("foo*baz"), "foobarbaz") === "bar" */ export function matchedText(pattern: Pattern, candidate: string): string { - Debug.assert(isPatternMatch(pattern, candidate)); + ts.Debug.assert(isPatternMatch(pattern, candidate)); return candidate.substring(pattern.prefix.length, candidate.length - pattern.suffix.length); } @@ -2332,7 +2419,7 @@ namespace ts { return t === undefined ? undefined : [t]; } - export function enumerateInsertsAndDeletes(newItems: readonly T[], oldItems: readonly U[], comparer: (a: T, b: U) => Comparison, inserted: (newItem: T) => void, deleted: (oldItem: U) => void, unchanged?: (oldItem: U, newItem: T) => void) { + export function enumerateInsertsAndDeletes(newItems: readonly T[], oldItems: readonly U[], comparer: (a: T, b: U) => ts.Comparison, inserted: (newItem: T) => void, deleted: (oldItem: U) => void, unchanged?: (oldItem: U, newItem: T) => void) { unchanged = unchanged || noop; let newIndex = 0; let oldIndex = 0; @@ -2343,12 +2430,12 @@ namespace ts { const newItem = newItems[newIndex]; const oldItem = oldItems[oldIndex]; const compareResult = comparer(newItem, oldItem); - if (compareResult === Comparison.LessThan) { + if (compareResult === ts.Comparison.LessThan) { inserted(newItem); newIndex++; hasChanges = true; } - else if (compareResult === Comparison.GreaterThan) { + else if (compareResult === ts.Comparison.GreaterThan) { deleted(oldItem); oldIndex++; hasChanges = true; @@ -2460,7 +2547,8 @@ namespace ts { function trimEndImpl(s: string) { let end = s.length - 1; while (end >= 0) { - if (!isWhiteSpaceLike(s.charCodeAt(end))) break; + if (!ts.isWhiteSpaceLike(s.charCodeAt(end))) + break; end--; } return s.slice(0, end + 1); diff --git a/src/compiler/corePublic.ts b/src/compiler/corePublic.ts index aabd9ac8333a5..75b43fdcb622d 100644 --- a/src/compiler/corePublic.ts +++ b/src/compiler/corePublic.ts @@ -41,7 +41,10 @@ namespace ts { export interface ReadonlyESMap extends ReadonlyCollection { get(key: K): V | undefined; values(): Iterator; - entries(): Iterator<[K, V]>; + entries(): Iterator<[ + K, + V + ]>; forEach(action: (value: V, key: K) => void): void; } @@ -65,14 +68,20 @@ namespace ts { /* @internal */ export interface MapConstructor { // eslint-disable-next-line @typescript-eslint/prefer-function-type - new (iterable?: readonly (readonly [K, V])[] | ReadonlyESMap): ESMap; + new (iterable?: readonly (readonly [ + K, + V + ])[] | ReadonlyESMap): ESMap; } /** ES6 Set interface, only read methods included. */ export interface ReadonlySet extends ReadonlyCollection { has(value: T): boolean; values(): Iterator; - entries(): Iterator<[T, T]>; + entries(): Iterator<[ + T, + T + ]>; forEach(action: (value: T, key: T) => void): void; } @@ -90,7 +99,13 @@ namespace ts { /** ES6 Iterator type. */ export interface Iterator { - next(): { value: T, done?: false } | { value: void, done: true }; + next(): { + value: T; + done?: false; + } | { + value: void; + done: true; + }; } /** Array that is only intended to be pushed to, never read. */ @@ -148,21 +163,17 @@ namespace ts { export const Set = getCollectionImplementation("Set", "tryGetNativeSet", "createSetShim"); /* @internal */ - type GetIteratorCallback = | ReadonlyESMap | undefined>(iterable: I) => Iterator< - I extends ReadonlyESMap ? [K, V] : - I extends ReadonlySet ? T : - I extends readonly (infer T)[] ? T : - I extends undefined ? undefined : - never>; + type GetIteratorCallback = | ReadonlyESMap | undefined>(iterable: I) => Iterator ? [ + K, + V + ] : I extends ReadonlySet ? T : I extends readonly (infer T)[] ? T : I extends undefined ? undefined : never>; /* @internal */ - function getCollectionImplementation< - K1 extends MatchingKeys any>, - K2 extends MatchingKeys ReturnType<(typeof NativeCollections)[K1]>> - >(name: string, nativeFactory: K1, shimFactory: K2): NonNullable> { + function getCollectionImplementation any>, K2 extends ts.MatchingKeys ReturnType<(typeof NativeCollections)[K1]>>>(name: string, nativeFactory: K1, shimFactory: K2): NonNullable> { // NOTE: ts.ShimCollections will be defined for typescriptServices.js but not for tsc.js, so we must test for it. - const constructor = NativeCollections[nativeFactory]() ?? ShimCollections?.[shimFactory](getIterator); - if (constructor) return constructor as NonNullable>; + const constructor = NativeCollections[nativeFactory]() ?? ts.ShimCollections?.[shimFactory](ts.getIterator); + if (constructor) + return constructor as NonNullable>; throw new Error(`TypeScript requires an environment that provides a compatible native ${name} implementation.`); } } diff --git a/src/compiler/debug.ts b/src/compiler/debug.ts index 8ab5de5b77832..598db30ef67a9 100644 --- a/src/compiler/debug.ts +++ b/src/compiler/debug.ts @@ -15,25 +15,25 @@ namespace ts { export interface DeprecationOptions { message?: string; error?: boolean; - since?: Version | string; - warnAfter?: Version | string; - errorAfter?: Version | string; - typeScriptVersion?: Version | string; + since?: ts.Version | string; + warnAfter?: ts.Version | string; + errorAfter?: ts.Version | string; + typeScriptVersion?: ts.Version | string; } export namespace Debug { - let typeScriptVersion: Version | undefined; + let typeScriptVersion: ts.Version | undefined; /* eslint-disable prefer-const */ - let currentAssertionLevel = AssertionLevel.None; + let currentAssertionLevel = ts.AssertionLevel.None; export let currentLogLevel = LogLevel.Warning; export let isDebugging = false; export let loggingHost: LoggingHost | undefined; /* eslint-enable prefer-const */ - type AssertionKeys = MatchingKeys; + type AssertionKeys = ts.MatchingKeys; export function getTypeScriptVersion() { - return typeScriptVersion ?? (typeScriptVersion = new Version(version)); + return typeScriptVersion ?? (typeScriptVersion = new ts.Version(ts.version)); } export function shouldLog(level: LogLevel): boolean { @@ -68,19 +68,22 @@ namespace ts { } } - const assertionCache: Partial> = {}; + const assertionCache: Partial> = {}; export function getAssertionLevel() { return currentAssertionLevel; } - export function setAssertionLevel(level: AssertionLevel) { + export function setAssertionLevel(level: ts.AssertionLevel) { const prevAssertionLevel = currentAssertionLevel; currentAssertionLevel = level; if (level > prevAssertionLevel) { // restore assertion functions for the current assertion level (see `shouldAssertFunction`). - for (const key of getOwnKeys(assertionCache) as AssertionKeys[]) { + for (const key of ts.getOwnKeys(assertionCache) as AssertionKeys[]) { const cachedFunc = assertionCache[key]; if (cachedFunc !== undefined && Debug[key] !== cachedFunc.assertion && level >= cachedFunc.level) { (Debug as any)[key] = cachedFunc; @@ -90,7 +93,7 @@ namespace ts { } } - export function shouldAssert(level: AssertionLevel): boolean { + export function shouldAssert(level: ts.AssertionLevel): boolean { return currentAssertionLevel >= level; } @@ -100,16 +103,16 @@ namespace ts { * @param level The minimum assertion level required. * @param name The name of the current assertion function. */ - function shouldAssertFunction(level: AssertionLevel, name: K): boolean { + function shouldAssertFunction(level: ts.AssertionLevel, name: K): boolean { if (!shouldAssert(level)) { assertionCache[name] = { level, assertion: Debug[name] }; - (Debug as any)[name] = noop; + (Debug as any)[name] = ts.noop; return false; } return true; } - export function fail(message?: string, stackCrawlMark?: AnyFunction): never { + export function fail(message?: string, stackCrawlMark?: ts.AnyFunction): never { debugger; const e = new Error(message ? `Debug Failure. ${message}` : "Debug Failure."); if ((Error as any).captureStackTrace) { @@ -118,13 +121,11 @@ namespace ts { throw e; } - export function failBadSyntaxKind(node: Node, message?: string, stackCrawlMark?: AnyFunction): never { - return fail( - `${message || "Unexpected node."}\r\nNode ${formatSyntaxKind(node.kind)} was unexpected.`, - stackCrawlMark || failBadSyntaxKind); + export function failBadSyntaxKind(node: ts.Node, message?: string, stackCrawlMark?: ts.AnyFunction): never { + return fail(`${message || "Unexpected node."}\r\nNode ${formatSyntaxKind(node.kind)} was unexpected.`, stackCrawlMark || failBadSyntaxKind); } - export function assert(expression: unknown, message?: string, verboseDebugInfo?: string | (() => string), stackCrawlMark?: AnyFunction): asserts expression { + export function assert(expression: unknown, message?: string, verboseDebugInfo?: string | (() => string), stackCrawlMark?: ts.AnyFunction): asserts expression { if (!expression) { message = message ? `False expression: ${message}` : "False expression."; if (verboseDebugInfo) { @@ -134,132 +135,107 @@ namespace ts { } } - export function assertEqual(a: T, b: T, msg?: string, msg2?: string, stackCrawlMark?: AnyFunction): void { + export function assertEqual(a: T, b: T, msg?: string, msg2?: string, stackCrawlMark?: ts.AnyFunction): void { if (a !== b) { const message = msg ? msg2 ? `${msg} ${msg2}` : msg : ""; fail(`Expected ${a} === ${b}. ${message}`, stackCrawlMark || assertEqual); } } - export function assertLessThan(a: number, b: number, msg?: string, stackCrawlMark?: AnyFunction): void { + export function assertLessThan(a: number, b: number, msg?: string, stackCrawlMark?: ts.AnyFunction): void { if (a >= b) { fail(`Expected ${a} < ${b}. ${msg || ""}`, stackCrawlMark || assertLessThan); } } - export function assertLessThanOrEqual(a: number, b: number, stackCrawlMark?: AnyFunction): void { + export function assertLessThanOrEqual(a: number, b: number, stackCrawlMark?: ts.AnyFunction): void { if (a > b) { fail(`Expected ${a} <= ${b}`, stackCrawlMark || assertLessThanOrEqual); } } - export function assertGreaterThanOrEqual(a: number, b: number, stackCrawlMark?: AnyFunction): void { + export function assertGreaterThanOrEqual(a: number, b: number, stackCrawlMark?: ts.AnyFunction): void { if (a < b) { fail(`Expected ${a} >= ${b}`, stackCrawlMark || assertGreaterThanOrEqual); } } - export function assertIsDefined(value: T, message?: string, stackCrawlMark?: AnyFunction): asserts value is NonNullable { + export function assertIsDefined(value: T, message?: string, stackCrawlMark?: ts.AnyFunction): asserts value is NonNullable { // eslint-disable-next-line no-null/no-null if (value === undefined || value === null) { fail(message, stackCrawlMark || assertIsDefined); } } - export function checkDefined(value: T | null | undefined, message?: string, stackCrawlMark?: AnyFunction): T { + export function checkDefined(value: T | null | undefined, message?: string, stackCrawlMark?: ts.AnyFunction): T { assertIsDefined(value, message, stackCrawlMark || checkDefined); return value; } - export function assertEachIsDefined(value: NodeArray, message?: string, stackCrawlMark?: AnyFunction): asserts value is NodeArray; - export function assertEachIsDefined(value: readonly T[], message?: string, stackCrawlMark?: AnyFunction): asserts value is readonly NonNullable[]; - export function assertEachIsDefined(value: readonly T[], message?: string, stackCrawlMark?: AnyFunction) { + export function assertEachIsDefined(value: ts.NodeArray, message?: string, stackCrawlMark?: ts.AnyFunction): asserts value is ts.NodeArray; + export function assertEachIsDefined(value: readonly T[], message?: string, stackCrawlMark?: ts.AnyFunction): asserts value is readonly NonNullable[]; + export function assertEachIsDefined(value: readonly T[], message?: string, stackCrawlMark?: ts.AnyFunction) { for (const v of value) { assertIsDefined(v, message, stackCrawlMark || assertEachIsDefined); } } - export function checkEachDefined(value: A, message?: string, stackCrawlMark?: AnyFunction): A { + export function checkEachDefined(value: A, message?: string, stackCrawlMark?: ts.AnyFunction): A { assertEachIsDefined(value, message, stackCrawlMark || checkEachDefined); return value; } - export function assertNever(member: never, message = "Illegal value:", stackCrawlMark?: AnyFunction): never { - const detail = typeof member === "object" && hasProperty(member, "kind") && hasProperty(member, "pos") ? "SyntaxKind: " + formatSyntaxKind((member as Node).kind) : JSON.stringify(member); + export function assertNever(member: never, message = "Illegal value:", stackCrawlMark?: ts.AnyFunction): never { + const detail = typeof member === "object" && ts.hasProperty(member, "kind") && ts.hasProperty(member, "pos") ? "SyntaxKind: " + formatSyntaxKind((member as ts.Node).kind) : JSON.stringify(member); return fail(`${message} ${detail}`, stackCrawlMark || assertNever); } - export function assertEachNode(nodes: NodeArray, test: (node: T) => node is U, message?: string, stackCrawlMark?: AnyFunction): asserts nodes is NodeArray; - export function assertEachNode(nodes: readonly T[], test: (node: T) => node is U, message?: string, stackCrawlMark?: AnyFunction): asserts nodes is readonly U[]; - export function assertEachNode(nodes: readonly Node[], test: (node: Node) => boolean, message?: string, stackCrawlMark?: AnyFunction): void; - export function assertEachNode(nodes: readonly Node[], test: (node: Node) => boolean, message?: string, stackCrawlMark?: AnyFunction) { - if (shouldAssertFunction(AssertionLevel.Normal, "assertEachNode")) { - assert( - test === undefined || every(nodes, test), - message || "Unexpected node.", - () => `Node array did not pass test '${getFunctionName(test)}'.`, - stackCrawlMark || assertEachNode); + export function assertEachNode(nodes: ts.NodeArray, test: (node: T) => node is U, message?: string, stackCrawlMark?: ts.AnyFunction): asserts nodes is ts.NodeArray; + export function assertEachNode(nodes: readonly T[], test: (node: T) => node is U, message?: string, stackCrawlMark?: ts.AnyFunction): asserts nodes is readonly U[]; + export function assertEachNode(nodes: readonly ts.Node[], test: (node: ts.Node) => boolean, message?: string, stackCrawlMark?: ts.AnyFunction): void; + export function assertEachNode(nodes: readonly ts.Node[], test: (node: ts.Node) => boolean, message?: string, stackCrawlMark?: ts.AnyFunction) { + if (shouldAssertFunction(ts.AssertionLevel.Normal, "assertEachNode")) { + assert(test === undefined || ts.every(nodes, test), message || "Unexpected node.", () => `Node array did not pass test '${getFunctionName(test)}'.`, stackCrawlMark || assertEachNode); } } - - export function assertNode(node: T | undefined, test: (node: T) => node is U, message?: string, stackCrawlMark?: AnyFunction): asserts node is U; - export function assertNode(node: Node | undefined, test: ((node: Node) => boolean) | undefined, message?: string, stackCrawlMark?: AnyFunction): void; - export function assertNode(node: Node | undefined, test: ((node: Node) => boolean) | undefined, message?: string, stackCrawlMark?: AnyFunction) { - if (shouldAssertFunction(AssertionLevel.Normal, "assertNode")) { - assert( - node !== undefined && (test === undefined || test(node)), - message || "Unexpected node.", - () => `Node ${formatSyntaxKind(node?.kind)} did not pass test '${getFunctionName(test!)}'.`, - stackCrawlMark || assertNode); + export function assertNode(node: T | undefined, test: (node: T) => node is U, message?: string, stackCrawlMark?: ts.AnyFunction): asserts node is U; + export function assertNode(node: ts.Node | undefined, test: ((node: ts.Node) => boolean) | undefined, message?: string, stackCrawlMark?: ts.AnyFunction): void; + export function assertNode(node: ts.Node | undefined, test: ((node: ts.Node) => boolean) | undefined, message?: string, stackCrawlMark?: ts.AnyFunction) { + if (shouldAssertFunction(ts.AssertionLevel.Normal, "assertNode")) { + assert(node !== undefined && (test === undefined || test(node)), message || "Unexpected node.", () => `Node ${formatSyntaxKind(node?.kind)} did not pass test '${getFunctionName(test!)}'.`, stackCrawlMark || assertNode); } } - - export function assertNotNode(node: T | undefined, test: (node: Node) => node is U, message?: string, stackCrawlMark?: AnyFunction): asserts node is Exclude; - export function assertNotNode(node: Node | undefined, test: ((node: Node) => boolean) | undefined, message?: string, stackCrawlMark?: AnyFunction): void; - export function assertNotNode(node: Node | undefined, test: ((node: Node) => boolean) | undefined, message?: string, stackCrawlMark?: AnyFunction) { - if (shouldAssertFunction(AssertionLevel.Normal, "assertNotNode")) { - assert( - node === undefined || test === undefined || !test(node), - message || "Unexpected node.", - () => `Node ${formatSyntaxKind(node!.kind)} should not have passed test '${getFunctionName(test!)}'.`, - stackCrawlMark || assertNotNode); + export function assertNotNode(node: T | undefined, test: (node: ts.Node) => node is U, message?: string, stackCrawlMark?: ts.AnyFunction): asserts node is Exclude; + export function assertNotNode(node: ts.Node | undefined, test: ((node: ts.Node) => boolean) | undefined, message?: string, stackCrawlMark?: ts.AnyFunction): void; + export function assertNotNode(node: ts.Node | undefined, test: ((node: ts.Node) => boolean) | undefined, message?: string, stackCrawlMark?: ts.AnyFunction) { + if (shouldAssertFunction(ts.AssertionLevel.Normal, "assertNotNode")) { + assert(node === undefined || test === undefined || !test(node), message || "Unexpected node.", () => `Node ${formatSyntaxKind(node!.kind)} should not have passed test '${getFunctionName(test!)}'.`, stackCrawlMark || assertNotNode); } } - - export function assertOptionalNode(node: T, test: (node: T) => node is U, message?: string, stackCrawlMark?: AnyFunction): asserts node is U; - export function assertOptionalNode(node: T | undefined, test: (node: T) => node is U, message?: string, stackCrawlMark?: AnyFunction): asserts node is U | undefined; - export function assertOptionalNode(node: Node | undefined, test: ((node: Node) => boolean) | undefined, message?: string, stackCrawlMark?: AnyFunction): void; - export function assertOptionalNode(node: Node | undefined, test: ((node: Node) => boolean) | undefined, message?: string, stackCrawlMark?: AnyFunction) { - if (shouldAssertFunction(AssertionLevel.Normal, "assertOptionalNode")) { - assert( - test === undefined || node === undefined || test(node), - message || "Unexpected node.", - () => `Node ${formatSyntaxKind(node?.kind)} did not pass test '${getFunctionName(test!)}'.`, - stackCrawlMark || assertOptionalNode); + export function assertOptionalNode(node: T, test: (node: T) => node is U, message?: string, stackCrawlMark?: ts.AnyFunction): asserts node is U; + export function assertOptionalNode(node: T | undefined, test: (node: T) => node is U, message?: string, stackCrawlMark?: ts.AnyFunction): asserts node is U | undefined; + export function assertOptionalNode(node: ts.Node | undefined, test: ((node: ts.Node) => boolean) | undefined, message?: string, stackCrawlMark?: ts.AnyFunction): void; + export function assertOptionalNode(node: ts.Node | undefined, test: ((node: ts.Node) => boolean) | undefined, message?: string, stackCrawlMark?: ts.AnyFunction) { + if (shouldAssertFunction(ts.AssertionLevel.Normal, "assertOptionalNode")) { + assert(test === undefined || node === undefined || test(node), message || "Unexpected node.", () => `Node ${formatSyntaxKind(node?.kind)} did not pass test '${getFunctionName(test!)}'.`, stackCrawlMark || assertOptionalNode); } } - - export function assertOptionalToken(node: T, kind: K, message?: string, stackCrawlMark?: AnyFunction): asserts node is Extract; - export function assertOptionalToken(node: T | undefined, kind: K, message?: string, stackCrawlMark?: AnyFunction): asserts node is Extract | undefined; - export function assertOptionalToken(node: Node | undefined, kind: SyntaxKind | undefined, message?: string, stackCrawlMark?: AnyFunction): void; - export function assertOptionalToken(node: Node | undefined, kind: SyntaxKind | undefined, message?: string, stackCrawlMark?: AnyFunction) { - if (shouldAssertFunction(AssertionLevel.Normal, "assertOptionalToken")) { - assert( - kind === undefined || node === undefined || node.kind === kind, - message || "Unexpected node.", - () => `Node ${formatSyntaxKind(node?.kind)} was not a '${formatSyntaxKind(kind)}' token.`, - stackCrawlMark || assertOptionalToken); + export function assertOptionalToken(node: T, kind: K, message?: string, stackCrawlMark?: ts.AnyFunction): asserts node is Extract; + export function assertOptionalToken(node: T | undefined, kind: K, message?: string, stackCrawlMark?: ts.AnyFunction): asserts node is Extract | undefined; + export function assertOptionalToken(node: ts.Node | undefined, kind: ts.SyntaxKind | undefined, message?: string, stackCrawlMark?: ts.AnyFunction): void; + export function assertOptionalToken(node: ts.Node | undefined, kind: ts.SyntaxKind | undefined, message?: string, stackCrawlMark?: ts.AnyFunction) { + if (shouldAssertFunction(ts.AssertionLevel.Normal, "assertOptionalToken")) { + assert(kind === undefined || node === undefined || node.kind === kind, message || "Unexpected node.", () => `Node ${formatSyntaxKind(node?.kind)} was not a '${formatSyntaxKind(kind)}' token.`, stackCrawlMark || assertOptionalToken); } } - - export function assertMissingNode(node: Node | undefined, message?: string, stackCrawlMark?: AnyFunction): asserts node is undefined; - export function assertMissingNode(node: Node | undefined, message?: string, stackCrawlMark?: AnyFunction) { - if (shouldAssertFunction(AssertionLevel.Normal, "assertMissingNode")) { - assert( - node === undefined, - message || "Unexpected node.", - () => `Node ${formatSyntaxKind(node!.kind)} was unexpected'.`, - stackCrawlMark || assertMissingNode); + export function assertMissingNode(node: ts.Node | undefined, message?: string, stackCrawlMark?: ts.AnyFunction): asserts node is undefined; + export function assertMissingNode(node: ts.Node | undefined, message?: string, stackCrawlMark?: ts.AnyFunction) { + if (shouldAssertFunction(ts.AssertionLevel.Normal, "assertMissingNode")) { + assert(node === undefined, message || "Unexpected node.", () => `Node ${formatSyntaxKind(node!.kind)} was unexpected'.`, stackCrawlMark || assertMissingNode); } } @@ -271,7 +247,7 @@ namespace ts { export function type(value: unknown): asserts value is T; export function type(_value: unknown) { } - export function getFunctionName(func: AnyFunction) { + export function getFunctionName(func: ts.AnyFunction) { if (typeof func !== "function") { return ""; } @@ -285,8 +261,8 @@ namespace ts { } } - export function formatSymbol(symbol: Symbol): string { - return `{ name: ${unescapeLeadingUnderscores(symbol.escapedName)}; flags: ${formatSymbolFlags(symbol.flags)}; declarations: ${map(symbol.declarations, node => formatSyntaxKind(node.kind))} }`; + export function formatSymbol(symbol: ts.Symbol): string { + return `{ name: ${ts.unescapeLeadingUnderscores(symbol.escapedName)}; flags: ${formatSymbolFlags(symbol.flags)}; declarations: ${ts.map(symbol.declarations, node => formatSyntaxKind(node.kind))} }`; } /** @@ -324,7 +300,10 @@ namespace ts { } function getEnumMembers(enumObject: any) { - const result: [number, string][] = []; + const result: [ + number, + string + ][] = []; for (const name in enumObject) { const value = enumObject[name]; if (typeof value === "number") { @@ -332,50 +311,53 @@ namespace ts { } } - return stableSort<[number, string]>(result, (x, y) => compareValues(x[0], y[0])); + return ts.stableSort<[ + number, + string + ]>(result, (x, y) => ts.compareValues(x[0], y[0])); } - export function formatSyntaxKind(kind: SyntaxKind | undefined): string { + export function formatSyntaxKind(kind: ts.SyntaxKind | undefined): string { return formatEnum(kind, (ts as any).SyntaxKind, /*isFlags*/ false); } - export function formatSnippetKind(kind: SnippetKind | undefined): string { + export function formatSnippetKind(kind: ts.SnippetKind | undefined): string { return formatEnum(kind, (ts as any).SnippetKind, /*isFlags*/ false); } - export function formatNodeFlags(flags: NodeFlags | undefined): string { + export function formatNodeFlags(flags: ts.NodeFlags | undefined): string { return formatEnum(flags, (ts as any).NodeFlags, /*isFlags*/ true); } - export function formatModifierFlags(flags: ModifierFlags | undefined): string { + export function formatModifierFlags(flags: ts.ModifierFlags | undefined): string { return formatEnum(flags, (ts as any).ModifierFlags, /*isFlags*/ true); } - export function formatTransformFlags(flags: TransformFlags | undefined): string { + export function formatTransformFlags(flags: ts.TransformFlags | undefined): string { return formatEnum(flags, (ts as any).TransformFlags, /*isFlags*/ true); } - export function formatEmitFlags(flags: EmitFlags | undefined): string { + export function formatEmitFlags(flags: ts.EmitFlags | undefined): string { return formatEnum(flags, (ts as any).EmitFlags, /*isFlags*/ true); } - export function formatSymbolFlags(flags: SymbolFlags | undefined): string { + export function formatSymbolFlags(flags: ts.SymbolFlags | undefined): string { return formatEnum(flags, (ts as any).SymbolFlags, /*isFlags*/ true); } - export function formatTypeFlags(flags: TypeFlags | undefined): string { + export function formatTypeFlags(flags: ts.TypeFlags | undefined): string { return formatEnum(flags, (ts as any).TypeFlags, /*isFlags*/ true); } - export function formatSignatureFlags(flags: SignatureFlags | undefined): string { + export function formatSignatureFlags(flags: ts.SignatureFlags | undefined): string { return formatEnum(flags, (ts as any).SignatureFlags, /*isFlags*/ true); } - export function formatObjectFlags(flags: ObjectFlags | undefined): string { + export function formatObjectFlags(flags: ts.ObjectFlags | undefined): string { return formatEnum(flags, (ts as any).ObjectFlags, /*isFlags*/ true); } - export function formatFlowFlags(flags: FlowFlags | undefined): string { + export function formatFlowFlags(flags: ts.FlowFlags | undefined): string { return formatEnum(flags, (ts as any).FlowFlags, /*isFlags*/ true); } @@ -383,7 +365,7 @@ namespace ts { interface ExtendedDebugModule { init(_ts: typeof ts): void; - formatControlFlowGraph(flowNode: FlowNode): string; + formatControlFlowGraph(flowNode: ts.FlowNode): string; } let extendedDebugModule: ExtendedDebugModule | undefined; @@ -396,52 +378,50 @@ namespace ts { return extendedDebugModule; } - export function printControlFlowGraph(flowNode: FlowNode) { + export function printControlFlowGraph(flowNode: ts.FlowNode) { return console.log(formatControlFlowGraph(flowNode)); } - export function formatControlFlowGraph(flowNode: FlowNode) { + export function formatControlFlowGraph(flowNode: ts.FlowNode) { return extendedDebug().formatControlFlowGraph(flowNode); } - let flowNodeProto: FlowNodeBase | undefined; - - function attachFlowNodeDebugInfoWorker(flowNode: FlowNodeBase) { + let flowNodeProto: ts.FlowNodeBase | undefined; + function attachFlowNodeDebugInfoWorker(flowNode: ts.FlowNodeBase) { if (!("__debugFlowFlags" in flowNode)) { // eslint-disable-line no-in-operator Object.defineProperties(flowNode, { // for use with vscode-js-debug's new customDescriptionGenerator in launch.json __tsDebuggerDisplay: { - value(this: FlowNodeBase) { - const flowHeader = - this.flags & FlowFlags.Start ? "FlowStart" : - this.flags & FlowFlags.BranchLabel ? "FlowBranchLabel" : - this.flags & FlowFlags.LoopLabel ? "FlowLoopLabel" : - this.flags & FlowFlags.Assignment ? "FlowAssignment" : - this.flags & FlowFlags.TrueCondition ? "FlowTrueCondition" : - this.flags & FlowFlags.FalseCondition ? "FlowFalseCondition" : - this.flags & FlowFlags.SwitchClause ? "FlowSwitchClause" : - this.flags & FlowFlags.ArrayMutation ? "FlowArrayMutation" : - this.flags & FlowFlags.Call ? "FlowCall" : - this.flags & FlowFlags.ReduceLabel ? "FlowReduceLabel" : - this.flags & FlowFlags.Unreachable ? "FlowUnreachable" : + value(this: ts.FlowNodeBase) { + const flowHeader = this.flags & ts.FlowFlags.Start ? "FlowStart" : + this.flags & ts.FlowFlags.BranchLabel ? "FlowBranchLabel" : + this.flags & ts.FlowFlags.LoopLabel ? "FlowLoopLabel" : + this.flags & ts.FlowFlags.Assignment ? "FlowAssignment" : + this.flags & ts.FlowFlags.TrueCondition ? "FlowTrueCondition" : + this.flags & ts.FlowFlags.FalseCondition ? "FlowFalseCondition" : + this.flags & ts.FlowFlags.SwitchClause ? "FlowSwitchClause" : + this.flags & ts.FlowFlags.ArrayMutation ? "FlowArrayMutation" : + this.flags & ts.FlowFlags.Call ? "FlowCall" : + this.flags & ts.FlowFlags.ReduceLabel ? "FlowReduceLabel" : + this.flags & ts.FlowFlags.Unreachable ? "FlowUnreachable" : "UnknownFlow"; - const remainingFlags = this.flags & ~(FlowFlags.Referenced - 1); + const remainingFlags = this.flags & ~(ts.FlowFlags.Referenced - 1); return `${flowHeader}${remainingFlags ? ` (${formatFlowFlags(remainingFlags)})`: ""}`; } }, - __debugFlowFlags: { get(this: FlowNodeBase) { return formatEnum(this.flags, (ts as any).FlowFlags, /*isFlags*/ true); } }, - __debugToString: { value(this: FlowNodeBase) { return formatControlFlowGraph(this); } } + __debugFlowFlags: { get(this: ts.FlowNodeBase) { return formatEnum(this.flags, (ts as any).FlowFlags, /*isFlags*/ true); } }, + __debugToString: { value(this: ts.FlowNodeBase) { return formatControlFlowGraph(this); } } }); } } - export function attachFlowNodeDebugInfo(flowNode: FlowNodeBase) { + export function attachFlowNodeDebugInfo(flowNode: ts.FlowNodeBase) { if (isDebugInfoEnabled) { if (typeof Object.setPrototypeOf === "function") { // if we're in es2015, attach the method to a shared prototype for `FlowNode` // so the method doesn't show up in the watch window. if (!flowNodeProto) { - flowNodeProto = Object.create(Object.prototype) as FlowNodeBase; + flowNodeProto = Object.create(Object.prototype) as ts.FlowNodeBase; attachFlowNodeDebugInfoWorker(flowNodeProto); } Object.setPrototypeOf(flowNode, flowNodeProto); @@ -453,13 +433,12 @@ namespace ts { } } - let nodeArrayProto: NodeArray | undefined; - - function attachNodeArrayDebugInfoWorker(array: NodeArray) { + let nodeArrayProto: ts.NodeArray | undefined; + function attachNodeArrayDebugInfoWorker(array: ts.NodeArray) { if (!("__tsDebuggerDisplay" in array)) { // eslint-disable-line no-in-operator Object.defineProperties(array, { __tsDebuggerDisplay: { - value(this: NodeArray, defaultValue: string) { + value(this: ts.NodeArray, defaultValue: string) { // An `Array` with extra properties is rendered as `[A, B, prop1: 1, prop2: 2]`. Most of // these aren't immediately useful so we trim off the `prop1: ..., prop2: ...` part from the // formatted string. @@ -474,13 +453,13 @@ namespace ts { } } - export function attachNodeArrayDebugInfo(array: NodeArray) { + export function attachNodeArrayDebugInfo(array: ts.NodeArray) { if (isDebugInfoEnabled) { if (typeof Object.setPrototypeOf === "function") { // if we're in es2015, attach the method to a shared prototype for `NodeArray` // so the method doesn't show up in the watch window. if (!nodeArrayProto) { - nodeArrayProto = Object.create(Array.prototype) as NodeArray; + nodeArrayProto = Object.create(Array.prototype) as ts.NodeArray; attachNodeArrayDebugInfoWorker(nodeArrayProto); } Object.setPrototypeOf(array, nodeArrayProto); @@ -496,78 +475,79 @@ namespace ts { * Injects debug information into frequently used types. */ export function enableDebugInfo() { - if (isDebugInfoEnabled) return; + if (isDebugInfoEnabled) + return; // avoid recomputing - let weakTypeTextMap: WeakMap | undefined; - let weakNodeTextMap: WeakMap | undefined; + let weakTypeTextMap: WeakMap | undefined; + let weakNodeTextMap: WeakMap | undefined; function getWeakTypeTextMap() { if (weakTypeTextMap === undefined) { - if (typeof WeakMap === "function") weakTypeTextMap = new WeakMap(); + if (typeof WeakMap === "function") + weakTypeTextMap = new WeakMap(); } return weakTypeTextMap; } function getWeakNodeTextMap() { if (weakNodeTextMap === undefined) { - if (typeof WeakMap === "function") weakNodeTextMap = new WeakMap(); + if (typeof WeakMap === "function") + weakNodeTextMap = new WeakMap(); } return weakNodeTextMap; } // Add additional properties in debug mode to assist with debugging. - Object.defineProperties(objectAllocator.getSymbolConstructor().prototype, { + Object.defineProperties(ts.objectAllocator.getSymbolConstructor().prototype, { // for use with vscode-js-debug's new customDescriptionGenerator in launch.json __tsDebuggerDisplay: { - value(this: Symbol) { - const symbolHeader = - this.flags & SymbolFlags.Transient ? "TransientSymbol" : + value(this: ts.Symbol) { + const symbolHeader = this.flags & ts.SymbolFlags.Transient ? "TransientSymbol" : "Symbol"; - const remainingSymbolFlags = this.flags & ~SymbolFlags.Transient; - return `${symbolHeader} '${symbolName(this)}'${remainingSymbolFlags ? ` (${formatSymbolFlags(remainingSymbolFlags)})` : ""}`; + const remainingSymbolFlags = this.flags & ~ts.SymbolFlags.Transient; + return `${symbolHeader} '${ts.symbolName(this)}'${remainingSymbolFlags ? ` (${formatSymbolFlags(remainingSymbolFlags)})` : ""}`; } }, - __debugFlags: { get(this: Symbol) { return formatSymbolFlags(this.flags); } } + __debugFlags: { get(this: ts.Symbol) { return formatSymbolFlags(this.flags); } } }); - Object.defineProperties(objectAllocator.getTypeConstructor().prototype, { + Object.defineProperties(ts.objectAllocator.getTypeConstructor().prototype, { // for use with vscode-js-debug's new customDescriptionGenerator in launch.json __tsDebuggerDisplay: { - value(this: Type) { - const typeHeader = - this.flags & TypeFlags.Nullable ? "NullableType" : - this.flags & TypeFlags.StringOrNumberLiteral ? `LiteralType ${JSON.stringify((this as LiteralType).value)}` : - this.flags & TypeFlags.BigIntLiteral ? `LiteralType ${(this as BigIntLiteralType).value.negative ? "-" : ""}${(this as BigIntLiteralType).value.base10Value}n` : - this.flags & TypeFlags.UniqueESSymbol ? "UniqueESSymbolType" : - this.flags & TypeFlags.Enum ? "EnumType" : - this.flags & TypeFlags.Intrinsic ? `IntrinsicType ${(this as IntrinsicType).intrinsicName}` : - this.flags & TypeFlags.Union ? "UnionType" : - this.flags & TypeFlags.Intersection ? "IntersectionType" : - this.flags & TypeFlags.Index ? "IndexType" : - this.flags & TypeFlags.IndexedAccess ? "IndexedAccessType" : - this.flags & TypeFlags.Conditional ? "ConditionalType" : - this.flags & TypeFlags.Substitution ? "SubstitutionType" : - this.flags & TypeFlags.TypeParameter ? "TypeParameter" : - this.flags & TypeFlags.Object ? - (this as ObjectType).objectFlags & ObjectFlags.ClassOrInterface ? "InterfaceType" : - (this as ObjectType).objectFlags & ObjectFlags.Reference ? "TypeReference" : - (this as ObjectType).objectFlags & ObjectFlags.Tuple ? "TupleType" : - (this as ObjectType).objectFlags & ObjectFlags.Anonymous ? "AnonymousType" : - (this as ObjectType).objectFlags & ObjectFlags.Mapped ? "MappedType" : - (this as ObjectType).objectFlags & ObjectFlags.ReverseMapped ? "ReverseMappedType" : - (this as ObjectType).objectFlags & ObjectFlags.EvolvingArray ? "EvolvingArrayType" : + value(this: ts.Type) { + const typeHeader = this.flags & ts.TypeFlags.Nullable ? "NullableType" : + this.flags & ts.TypeFlags.StringOrNumberLiteral ? `LiteralType ${JSON.stringify((this as ts.LiteralType).value)}` : + this.flags & ts.TypeFlags.BigIntLiteral ? `LiteralType ${(this as ts.BigIntLiteralType).value.negative ? "-" : ""}${(this as ts.BigIntLiteralType).value.base10Value}n` : + this.flags & ts.TypeFlags.UniqueESSymbol ? "UniqueESSymbolType" : + this.flags & ts.TypeFlags.Enum ? "EnumType" : + this.flags & ts.TypeFlags.Intrinsic ? `IntrinsicType ${(this as ts.IntrinsicType).intrinsicName}` : + this.flags & ts.TypeFlags.Union ? "UnionType" : + this.flags & ts.TypeFlags.Intersection ? "IntersectionType" : + this.flags & ts.TypeFlags.Index ? "IndexType" : + this.flags & ts.TypeFlags.IndexedAccess ? "IndexedAccessType" : + this.flags & ts.TypeFlags.Conditional ? "ConditionalType" : + this.flags & ts.TypeFlags.Substitution ? "SubstitutionType" : + this.flags & ts.TypeFlags.TypeParameter ? "TypeParameter" : + this.flags & ts.TypeFlags.Object ? + (this as ts.ObjectType).objectFlags & ts.ObjectFlags.ClassOrInterface ? "InterfaceType" : + (this as ts.ObjectType).objectFlags & ts.ObjectFlags.Reference ? "TypeReference" : + (this as ts.ObjectType).objectFlags & ts.ObjectFlags.Tuple ? "TupleType" : + (this as ts.ObjectType).objectFlags & ts.ObjectFlags.Anonymous ? "AnonymousType" : + (this as ts.ObjectType).objectFlags & ts.ObjectFlags.Mapped ? "MappedType" : + (this as ts.ObjectType).objectFlags & ts.ObjectFlags.ReverseMapped ? "ReverseMappedType" : + (this as ts.ObjectType).objectFlags & ts.ObjectFlags.EvolvingArray ? "EvolvingArrayType" : "ObjectType" : "Type"; - const remainingObjectFlags = this.flags & TypeFlags.Object ? (this as ObjectType).objectFlags & ~ObjectFlags.ObjectTypeKindMask : 0; - return `${typeHeader}${this.symbol ? ` '${symbolName(this.symbol)}'` : ""}${remainingObjectFlags ? ` (${formatObjectFlags(remainingObjectFlags)})` : ""}`; + const remainingObjectFlags = this.flags & ts.TypeFlags.Object ? (this as ts.ObjectType).objectFlags & ~ts.ObjectFlags.ObjectTypeKindMask : 0; + return `${typeHeader}${this.symbol ? ` '${ts.symbolName(this.symbol)}'` : ""}${remainingObjectFlags ? ` (${formatObjectFlags(remainingObjectFlags)})` : ""}`; } }, - __debugFlags: { get(this: Type) { return formatTypeFlags(this.flags); } }, - __debugObjectFlags: { get(this: Type) { return this.flags & TypeFlags.Object ? formatObjectFlags((this as ObjectType).objectFlags) : ""; } }, + __debugFlags: { get(this: ts.Type) { return formatTypeFlags(this.flags); } }, + __debugObjectFlags: { get(this: ts.Type) { return this.flags & ts.TypeFlags.Object ? formatObjectFlags((this as ts.ObjectType).objectFlags) : ""; } }, __debugTypeToString: { - value(this: Type) { + value(this: ts.Type) { // avoid recomputing const map = getWeakTypeTextMap(); let text = map?.get(this); @@ -580,16 +560,16 @@ namespace ts { }, }); - Object.defineProperties(objectAllocator.getSignatureConstructor().prototype, { - __debugFlags: { get(this: Signature) { return formatSignatureFlags(this.flags); } }, - __debugSignatureToString: { value(this: Signature) { return this.checker?.signatureToString(this); } } + Object.defineProperties(ts.objectAllocator.getSignatureConstructor().prototype, { + __debugFlags: { get(this: ts.Signature) { return formatSignatureFlags(this.flags); } }, + __debugSignatureToString: { value(this: ts.Signature) { return this.checker?.signatureToString(this); } } }); const nodeConstructors = [ - objectAllocator.getNodeConstructor(), - objectAllocator.getIdentifierConstructor(), - objectAllocator.getTokenConstructor(), - objectAllocator.getSourceFileConstructor() + ts.objectAllocator.getNodeConstructor(), + ts.objectAllocator.getIdentifierConstructor(), + ts.objectAllocator.getTokenConstructor(), + ts.objectAllocator.getSourceFileConstructor() ]; for (const ctor of nodeConstructors) { @@ -597,64 +577,64 @@ namespace ts { Object.defineProperties(ctor.prototype, { // for use with vscode-js-debug's new customDescriptionGenerator in launch.json __tsDebuggerDisplay: { - value(this: Node) { - const nodeHeader = - isGeneratedIdentifier(this) ? "GeneratedIdentifier" : - isIdentifier(this) ? `Identifier '${idText(this)}'` : - isPrivateIdentifier(this) ? `PrivateIdentifier '${idText(this)}'` : - isStringLiteral(this) ? `StringLiteral ${JSON.stringify(this.text.length < 10 ? this.text : this.text.slice(10) + "...")}` : - isNumericLiteral(this) ? `NumericLiteral ${this.text}` : - isBigIntLiteral(this) ? `BigIntLiteral ${this.text}n` : - isTypeParameterDeclaration(this) ? "TypeParameterDeclaration" : - isParameter(this) ? "ParameterDeclaration" : - isConstructorDeclaration(this) ? "ConstructorDeclaration" : - isGetAccessorDeclaration(this) ? "GetAccessorDeclaration" : - isSetAccessorDeclaration(this) ? "SetAccessorDeclaration" : - isCallSignatureDeclaration(this) ? "CallSignatureDeclaration" : - isConstructSignatureDeclaration(this) ? "ConstructSignatureDeclaration" : - isIndexSignatureDeclaration(this) ? "IndexSignatureDeclaration" : - isTypePredicateNode(this) ? "TypePredicateNode" : - isTypeReferenceNode(this) ? "TypeReferenceNode" : - isFunctionTypeNode(this) ? "FunctionTypeNode" : - isConstructorTypeNode(this) ? "ConstructorTypeNode" : - isTypeQueryNode(this) ? "TypeQueryNode" : - isTypeLiteralNode(this) ? "TypeLiteralNode" : - isArrayTypeNode(this) ? "ArrayTypeNode" : - isTupleTypeNode(this) ? "TupleTypeNode" : - isOptionalTypeNode(this) ? "OptionalTypeNode" : - isRestTypeNode(this) ? "RestTypeNode" : - isUnionTypeNode(this) ? "UnionTypeNode" : - isIntersectionTypeNode(this) ? "IntersectionTypeNode" : - isConditionalTypeNode(this) ? "ConditionalTypeNode" : - isInferTypeNode(this) ? "InferTypeNode" : - isParenthesizedTypeNode(this) ? "ParenthesizedTypeNode" : - isThisTypeNode(this) ? "ThisTypeNode" : - isTypeOperatorNode(this) ? "TypeOperatorNode" : - isIndexedAccessTypeNode(this) ? "IndexedAccessTypeNode" : - isMappedTypeNode(this) ? "MappedTypeNode" : - isLiteralTypeNode(this) ? "LiteralTypeNode" : - isNamedTupleMember(this) ? "NamedTupleMember" : - isImportTypeNode(this) ? "ImportTypeNode" : + value(this: ts.Node) { + const nodeHeader = ts.isGeneratedIdentifier(this) ? "GeneratedIdentifier" : + ts.isIdentifier(this) ? `Identifier '${ts.idText(this)}'` : + ts.isPrivateIdentifier(this) ? `PrivateIdentifier '${ts.idText(this)}'` : + ts.isStringLiteral(this) ? `StringLiteral ${JSON.stringify(this.text.length < 10 ? this.text : this.text.slice(10) + "...")}` : + ts.isNumericLiteral(this) ? `NumericLiteral ${this.text}` : + ts.isBigIntLiteral(this) ? `BigIntLiteral ${this.text}n` : + ts.isTypeParameterDeclaration(this) ? "TypeParameterDeclaration" : + ts.isParameter(this) ? "ParameterDeclaration" : + ts.isConstructorDeclaration(this) ? "ConstructorDeclaration" : + ts.isGetAccessorDeclaration(this) ? "GetAccessorDeclaration" : + ts.isSetAccessorDeclaration(this) ? "SetAccessorDeclaration" : + ts.isCallSignatureDeclaration(this) ? "CallSignatureDeclaration" : + ts.isConstructSignatureDeclaration(this) ? "ConstructSignatureDeclaration" : + ts.isIndexSignatureDeclaration(this) ? "IndexSignatureDeclaration" : + ts.isTypePredicateNode(this) ? "TypePredicateNode" : + ts.isTypeReferenceNode(this) ? "TypeReferenceNode" : + ts.isFunctionTypeNode(this) ? "FunctionTypeNode" : + ts.isConstructorTypeNode(this) ? "ConstructorTypeNode" : + ts.isTypeQueryNode(this) ? "TypeQueryNode" : + ts.isTypeLiteralNode(this) ? "TypeLiteralNode" : + ts.isArrayTypeNode(this) ? "ArrayTypeNode" : + ts.isTupleTypeNode(this) ? "TupleTypeNode" : + ts.isOptionalTypeNode(this) ? "OptionalTypeNode" : + ts.isRestTypeNode(this) ? "RestTypeNode" : + ts.isUnionTypeNode(this) ? "UnionTypeNode" : + ts.isIntersectionTypeNode(this) ? "IntersectionTypeNode" : + ts.isConditionalTypeNode(this) ? "ConditionalTypeNode" : + ts.isInferTypeNode(this) ? "InferTypeNode" : + ts.isParenthesizedTypeNode(this) ? "ParenthesizedTypeNode" : + ts.isThisTypeNode(this) ? "ThisTypeNode" : + ts.isTypeOperatorNode(this) ? "TypeOperatorNode" : + ts.isIndexedAccessTypeNode(this) ? "IndexedAccessTypeNode" : + ts.isMappedTypeNode(this) ? "MappedTypeNode" : + ts.isLiteralTypeNode(this) ? "LiteralTypeNode" : + ts.isNamedTupleMember(this) ? "NamedTupleMember" : + ts.isImportTypeNode(this) ? "ImportTypeNode" : formatSyntaxKind(this.kind); return `${nodeHeader}${this.flags ? ` (${formatNodeFlags(this.flags)})` : ""}`; } }, - __debugKind: { get(this: Node) { return formatSyntaxKind(this.kind); } }, - __debugNodeFlags: { get(this: Node) { return formatNodeFlags(this.flags); } }, - __debugModifierFlags: { get(this: Node) { return formatModifierFlags(getEffectiveModifierFlagsNoCache(this)); } }, - __debugTransformFlags: { get(this: Node) { return formatTransformFlags(this.transformFlags); } }, - __debugIsParseTreeNode: { get(this: Node) { return isParseTreeNode(this); } }, - __debugEmitFlags: { get(this: Node) { return formatEmitFlags(getEmitFlags(this)); } }, + __debugKind: { get(this: ts.Node) { return formatSyntaxKind(this.kind); } }, + __debugNodeFlags: { get(this: ts.Node) { return formatNodeFlags(this.flags); } }, + __debugModifierFlags: { get(this: ts.Node) { return formatModifierFlags(ts.getEffectiveModifierFlagsNoCache(this)); } }, + __debugTransformFlags: { get(this: ts.Node) { return formatTransformFlags(this.transformFlags); } }, + __debugIsParseTreeNode: { get(this: ts.Node) { return ts.isParseTreeNode(this); } }, + __debugEmitFlags: { get(this: ts.Node) { return formatEmitFlags(ts.getEmitFlags(this)); } }, __debugGetText: { - value(this: Node, includeTrivia?: boolean) { - if (nodeIsSynthesized(this)) return ""; + value(this: ts.Node, includeTrivia?: boolean) { + if (ts.nodeIsSynthesized(this)) + return ""; // avoid recomputing const map = getWeakNodeTextMap(); let text = map?.get(this); if (text === undefined) { - const parseNode = getParseTreeNode(this); - const sourceFile = parseNode && getSourceFileOfNode(parseNode); - text = sourceFile ? getSourceTextOfNodeFromSourceFile(sourceFile, parseNode, includeTrivia) : ""; + const parseNode = ts.getParseTreeNode(this); + const sourceFile = parseNode && ts.getSourceFileOfNode(parseNode); + text = sourceFile ? ts.getSourceTextOfNodeFromSourceFile(sourceFile, parseNode, includeTrivia) : ""; map?.set(this, text); } return text; @@ -666,9 +646,9 @@ namespace ts { // attempt to load extended debugging information try { - if (sys && sys.require) { - const basePath = getDirectoryPath(resolvePath(sys.getExecutingFilePath())); - const result = sys.require(basePath, "./compiler-debug") as RequireResult; + if (ts.sys && ts.sys.require) { + const basePath = ts.getDirectoryPath(ts.resolvePath(ts.sys.getExecutingFilePath())); + const result = ts.sys.require(basePath, "./compiler-debug") as ts.RequireResult; if (!result.error) { result.module.init(ts); extendedDebugModule = result.module; @@ -682,23 +662,23 @@ namespace ts { isDebugInfoEnabled = true; } - function formatDeprecationMessage(name: string, error: boolean | undefined, errorAfter: Version | undefined, since: Version | undefined, message: string | undefined) { + function formatDeprecationMessage(name: string, error: boolean | undefined, errorAfter: ts.Version | undefined, since: ts.Version | undefined, message: string | undefined) { let deprecationMessage = error ? "DeprecationError: " : "DeprecationWarning: "; deprecationMessage += `'${name}' `; deprecationMessage += since ? `has been deprecated since v${since}` : "is deprecated"; deprecationMessage += error ? " and can no longer be used." : errorAfter ? ` and will no longer be usable after v${errorAfter}.` : "."; - deprecationMessage += message ? ` ${formatStringFromArgs(message, [name], 0)}` : ""; + deprecationMessage += message ? ` ${ts.formatStringFromArgs(message, [name], 0)}` : ""; return deprecationMessage; } - function createErrorDeprecation(name: string, errorAfter: Version | undefined, since: Version | undefined, message: string | undefined) { + function createErrorDeprecation(name: string, errorAfter: ts.Version | undefined, since: ts.Version | undefined, message: string | undefined) { const deprecationMessage = formatDeprecationMessage(name, /*error*/ true, errorAfter, since, message); return () => { throw new TypeError(deprecationMessage); }; } - function createWarningDeprecation(name: string, errorAfter: Version | undefined, since: Version | undefined, message: string | undefined) { + function createWarningDeprecation(name: string, errorAfter: ts.Version | undefined, since: ts.Version | undefined, message: string | undefined) { let hasWrittenDeprecation = false; return () => { if (!hasWrittenDeprecation) { @@ -708,18 +688,19 @@ namespace ts { }; } - function createDeprecation(name: string, options: DeprecationOptions & { error: true }): () => never; + function createDeprecation(name: string, options: DeprecationOptions & { + error: true; + }): () => never; function createDeprecation(name: string, options?: DeprecationOptions): () => void; function createDeprecation(name: string, options: DeprecationOptions = {}) { - const version = typeof options.typeScriptVersion === "string" ? new Version(options.typeScriptVersion) : options.typeScriptVersion ?? getTypeScriptVersion(); - const errorAfter = typeof options.errorAfter === "string" ? new Version(options.errorAfter) : options.errorAfter; - const warnAfter = typeof options.warnAfter === "string" ? new Version(options.warnAfter) : options.warnAfter; - const since = typeof options.since === "string" ? new Version(options.since) : options.since ?? warnAfter; + const version = typeof options.typeScriptVersion === "string" ? new ts.Version(options.typeScriptVersion) : options.typeScriptVersion ?? getTypeScriptVersion(); + const errorAfter = typeof options.errorAfter === "string" ? new ts.Version(options.errorAfter) : options.errorAfter; + const warnAfter = typeof options.warnAfter === "string" ? new ts.Version(options.warnAfter) : options.warnAfter; + const since = typeof options.since === "string" ? new ts.Version(options.since) : options.since ?? warnAfter; const error = options.error || errorAfter && version.compareTo(errorAfter) <= 0; const warn = !warnAfter || version.compareTo(warnAfter) >= 0; return error ? createErrorDeprecation(name, errorAfter, since, options.message) : - warn ? createWarningDeprecation(name, errorAfter, since, options.message) : - noop; + warn ? createWarningDeprecation(name, errorAfter, since, options.message) : ts.noop; } function wrapFunction any>(deprecation: () => void, func: F): F { diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index c83713750f2a6..db9574f00b52a 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -3,7 +3,7 @@ namespace ts { /*@internal*/ export function isBuildInfoFile(file: string) { - return fileExtensionIs(file, Extension.TsBuildInfo); + return ts.fileExtensionIs(file, ts.Extension.TsBuildInfo); } /*@internal*/ @@ -16,18 +16,13 @@ namespace ts { * If an array, the full list of source files to emit. * Else, calls `getSourceFilesToEmit` with the (optional) target source file to determine the list of source files to emit. */ - export function forEachEmittedFile( - host: EmitHost, action: (emitFileNames: EmitFileNames, sourceFileOrBundle: SourceFile | Bundle | undefined) => T, - sourceFilesOrTargetSourceFile?: readonly SourceFile[] | SourceFile, - forceDtsEmit = false, - onlyBuildInfo?: boolean, - includeBuildInfo?: boolean) { - const sourceFiles = isArray(sourceFilesOrTargetSourceFile) ? sourceFilesOrTargetSourceFile : getSourceFilesToEmit(host, sourceFilesOrTargetSourceFile, forceDtsEmit); + export function forEachEmittedFile(host: ts.EmitHost, action: (emitFileNames: ts.EmitFileNames, sourceFileOrBundle: ts.SourceFile | ts.Bundle | undefined) => T, sourceFilesOrTargetSourceFile?: readonly ts.SourceFile[] | ts.SourceFile, forceDtsEmit = false, onlyBuildInfo?: boolean, includeBuildInfo?: boolean) { + const sourceFiles = ts.isArray(sourceFilesOrTargetSourceFile) ? sourceFilesOrTargetSourceFile : ts.getSourceFilesToEmit(host, sourceFilesOrTargetSourceFile, forceDtsEmit); const options = host.getCompilerOptions(); - if (outFile(options)) { + if (ts.outFile(options)) { const prepends = host.getPrependNodes(); if (sourceFiles.length || prepends.length) { - const bundle = factory.createBundle(sourceFiles, prepends); + const bundle = ts.factory.createBundle(sourceFiles, prepends); const result = action(getOutputPathsFor(bundle, host, forceDtsEmit), bundle); if (result) { return result; @@ -45,101 +40,95 @@ namespace ts { } if (includeBuildInfo) { const buildInfoPath = getTsBuildInfoEmitOutputFilePath(options); - if (buildInfoPath) return action({ buildInfoPath }, /*sourceFileOrBundle*/ undefined); + if (buildInfoPath) + return action({ buildInfoPath }, /*sourceFileOrBundle*/ undefined); } } } - export function getTsBuildInfoEmitOutputFilePath(options: CompilerOptions) { + export function getTsBuildInfoEmitOutputFilePath(options: ts.CompilerOptions) { const configFile = options.configFilePath; - if (!isIncrementalCompilation(options)) return undefined; - if (options.tsBuildInfoFile) return options.tsBuildInfoFile; - const outPath = outFile(options); + if (!ts.isIncrementalCompilation(options)) + return undefined; + if (options.tsBuildInfoFile) + return options.tsBuildInfoFile; + const outPath = ts.outFile(options); let buildInfoExtensionLess: string; if (outPath) { - buildInfoExtensionLess = removeFileExtension(outPath); + buildInfoExtensionLess = ts.removeFileExtension(outPath); } else { - if (!configFile) return undefined; - const configFileExtensionLess = removeFileExtension(configFile); + if (!configFile) + return undefined; + const configFileExtensionLess = ts.removeFileExtension(configFile); buildInfoExtensionLess = options.outDir ? options.rootDir ? - resolvePath(options.outDir, getRelativePathFromDirectory(options.rootDir, configFileExtensionLess, /*ignoreCase*/ true)) : - combinePaths(options.outDir, getBaseFileName(configFileExtensionLess)) : + ts.resolvePath(options.outDir, ts.getRelativePathFromDirectory(options.rootDir, configFileExtensionLess, /*ignoreCase*/ true)) : + ts.combinePaths(options.outDir, ts.getBaseFileName(configFileExtensionLess)) : configFileExtensionLess; } - return buildInfoExtensionLess + Extension.TsBuildInfo; + return buildInfoExtensionLess + ts.Extension.TsBuildInfo; } /*@internal*/ - export function getOutputPathsForBundle(options: CompilerOptions, forceDtsPaths: boolean): EmitFileNames { - const outPath = outFile(options)!; + export function getOutputPathsForBundle(options: ts.CompilerOptions, forceDtsPaths: boolean): ts.EmitFileNames { + const outPath = ts.outFile(options)!; const jsFilePath = options.emitDeclarationOnly ? undefined : outPath; const sourceMapFilePath = jsFilePath && getSourceMapFilePath(jsFilePath, options); - const declarationFilePath = (forceDtsPaths || getEmitDeclarations(options)) ? removeFileExtension(outPath) + Extension.Dts : undefined; - const declarationMapPath = declarationFilePath && getAreDeclarationMapsEnabled(options) ? declarationFilePath + ".map" : undefined; + const declarationFilePath = (forceDtsPaths || ts.getEmitDeclarations(options)) ? ts.removeFileExtension(outPath) + ts.Extension.Dts : undefined; + const declarationMapPath = declarationFilePath && ts.getAreDeclarationMapsEnabled(options) ? declarationFilePath + ".map" : undefined; const buildInfoPath = getTsBuildInfoEmitOutputFilePath(options); return { jsFilePath, sourceMapFilePath, declarationFilePath, declarationMapPath, buildInfoPath }; } /*@internal*/ - export function getOutputPathsFor(sourceFile: SourceFile | Bundle, host: EmitHost, forceDtsPaths: boolean): EmitFileNames { + export function getOutputPathsFor(sourceFile: ts.SourceFile | ts.Bundle, host: ts.EmitHost, forceDtsPaths: boolean): ts.EmitFileNames { const options = host.getCompilerOptions(); - if (sourceFile.kind === SyntaxKind.Bundle) { + if (sourceFile.kind === ts.SyntaxKind.Bundle) { return getOutputPathsForBundle(options, forceDtsPaths); } else { - const ownOutputFilePath = getOwnEmitOutputFilePath(sourceFile.fileName, host, getOutputExtension(sourceFile.fileName, options)); - const isJsonFile = isJsonSourceFile(sourceFile); + const ownOutputFilePath = ts.getOwnEmitOutputFilePath(sourceFile.fileName, host, getOutputExtension(sourceFile.fileName, options)); + const isJsonFile = ts.isJsonSourceFile(sourceFile); // If json file emits to the same location skip writing it, if emitDeclarationOnly skip writing it const isJsonEmittedToSameLocation = isJsonFile && - comparePaths(sourceFile.fileName, ownOutputFilePath, host.getCurrentDirectory(), !host.useCaseSensitiveFileNames()) === Comparison.EqualTo; + ts.comparePaths(sourceFile.fileName, ownOutputFilePath, host.getCurrentDirectory(), !host.useCaseSensitiveFileNames()) === ts.Comparison.EqualTo; const jsFilePath = options.emitDeclarationOnly || isJsonEmittedToSameLocation ? undefined : ownOutputFilePath; - const sourceMapFilePath = !jsFilePath || isJsonSourceFile(sourceFile) ? undefined : getSourceMapFilePath(jsFilePath, options); - const declarationFilePath = (forceDtsPaths || (getEmitDeclarations(options) && !isJsonFile)) ? getDeclarationEmitOutputFilePath(sourceFile.fileName, host) : undefined; - const declarationMapPath = declarationFilePath && getAreDeclarationMapsEnabled(options) ? declarationFilePath + ".map" : undefined; + const sourceMapFilePath = !jsFilePath || ts.isJsonSourceFile(sourceFile) ? undefined : getSourceMapFilePath(jsFilePath, options); + const declarationFilePath = (forceDtsPaths || (ts.getEmitDeclarations(options) && !isJsonFile)) ? ts.getDeclarationEmitOutputFilePath(sourceFile.fileName, host) : undefined; + const declarationMapPath = declarationFilePath && ts.getAreDeclarationMapsEnabled(options) ? declarationFilePath + ".map" : undefined; return { jsFilePath, sourceMapFilePath, declarationFilePath, declarationMapPath, buildInfoPath: undefined }; } } - function getSourceMapFilePath(jsFilePath: string, options: CompilerOptions) { + function getSourceMapFilePath(jsFilePath: string, options: ts.CompilerOptions) { return (options.sourceMap && !options.inlineSourceMap) ? jsFilePath + ".map" : undefined; } /* @internal */ - export function getOutputExtension(fileName: string, options: CompilerOptions): Extension { - return fileExtensionIs(fileName, Extension.Json) ? Extension.Json : - options.jsx === JsxEmit.Preserve && fileExtensionIsOneOf(fileName, [Extension.Jsx, Extension.Tsx]) ? Extension.Jsx : - fileExtensionIsOneOf(fileName, [Extension.Mts, Extension.Mjs]) ? Extension.Mjs : - fileExtensionIsOneOf(fileName, [Extension.Cts, Extension.Cjs]) ? Extension.Cjs : - Extension.Js; + export function getOutputExtension(fileName: string, options: ts.CompilerOptions): ts.Extension { + return ts.fileExtensionIs(fileName, ts.Extension.Json) ? ts.Extension.Json : + options.jsx === ts.JsxEmit.Preserve && ts.fileExtensionIsOneOf(fileName, [ts.Extension.Jsx, ts.Extension.Tsx]) ? ts.Extension.Jsx : + ts.fileExtensionIsOneOf(fileName, [ts.Extension.Mts, ts.Extension.Mjs]) ? ts.Extension.Mjs : + ts.fileExtensionIsOneOf(fileName, [ts.Extension.Cts, ts.Extension.Cjs]) ? ts.Extension.Cjs : + ts.Extension.Js; } - - function getOutputPathWithoutChangingExt(inputFileName: string, configFile: ParsedCommandLine, ignoreCase: boolean, outputDir: string | undefined, getCommonSourceDirectory?: () => string) { + function getOutputPathWithoutChangingExt(inputFileName: string, configFile: ts.ParsedCommandLine, ignoreCase: boolean, outputDir: string | undefined, getCommonSourceDirectory?: () => string) { return outputDir ? - resolvePath( - outputDir, - getRelativePathFromDirectory(getCommonSourceDirectory ? getCommonSourceDirectory() : getCommonSourceDirectoryOfConfig(configFile, ignoreCase), inputFileName, ignoreCase) - ) : + ts.resolvePath(outputDir, ts.getRelativePathFromDirectory(getCommonSourceDirectory ? getCommonSourceDirectory() : getCommonSourceDirectoryOfConfig(configFile, ignoreCase), inputFileName, ignoreCase)) : inputFileName; } /* @internal */ - export function getOutputDeclarationFileName(inputFileName: string, configFile: ParsedCommandLine, ignoreCase: boolean, getCommonSourceDirectory?: () => string) { - return changeExtension( - getOutputPathWithoutChangingExt(inputFileName, configFile, ignoreCase, configFile.options.declarationDir || configFile.options.outDir, getCommonSourceDirectory), - getDeclarationEmitExtensionForPath(inputFileName) - ); + export function getOutputDeclarationFileName(inputFileName: string, configFile: ts.ParsedCommandLine, ignoreCase: boolean, getCommonSourceDirectory?: () => string) { + return ts.changeExtension(getOutputPathWithoutChangingExt(inputFileName, configFile, ignoreCase, configFile.options.declarationDir || configFile.options.outDir, getCommonSourceDirectory), ts.getDeclarationEmitExtensionForPath(inputFileName)); } - - function getOutputJSFileName(inputFileName: string, configFile: ParsedCommandLine, ignoreCase: boolean, getCommonSourceDirectory?: () => string) { - if (configFile.options.emitDeclarationOnly) return undefined; - const isJsonFile = fileExtensionIs(inputFileName, Extension.Json); - const outputFileName = changeExtension( - getOutputPathWithoutChangingExt(inputFileName, configFile, ignoreCase, configFile.options.outDir, getCommonSourceDirectory), - getOutputExtension(inputFileName, configFile.options) - ); - return !isJsonFile || comparePaths(inputFileName, outputFileName, Debug.checkDefined(configFile.options.configFilePath), ignoreCase) !== Comparison.EqualTo ? + function getOutputJSFileName(inputFileName: string, configFile: ts.ParsedCommandLine, ignoreCase: boolean, getCommonSourceDirectory?: () => string) { + if (configFile.options.emitDeclarationOnly) + return undefined; + const isJsonFile = ts.fileExtensionIs(inputFileName, ts.Extension.Json); + const outputFileName = ts.changeExtension(getOutputPathWithoutChangingExt(inputFileName, configFile, ignoreCase, configFile.options.outDir, getCommonSourceDirectory), getOutputExtension(inputFileName, configFile.options)); + return !isJsonFile || ts.comparePaths(inputFileName, outputFileName, ts.Debug.checkDefined(configFile.options.configFilePath), ignoreCase) !== ts.Comparison.EqualTo ? outputFileName : undefined; } @@ -153,11 +142,11 @@ namespace ts { } } function getOutputs(): readonly string[] { - return outputs || emptyArray; + return outputs || ts.emptyArray; } } - function getSingleOutputFileNames(configFile: ParsedCommandLine, addOutput: ReturnType["addOutput"]) { + function getSingleOutputFileNames(configFile: ts.ParsedCommandLine, addOutput: ReturnType["addOutput"]) { const { jsFilePath, sourceMapFilePath, declarationFilePath, declarationMapPath, buildInfoPath } = getOutputPathsForBundle(configFile.options, /*forceDtsPaths*/ false); addOutput(jsFilePath); addOutput(sourceMapFilePath); @@ -166,15 +155,17 @@ namespace ts { addOutput(buildInfoPath); } - function getOwnOutputFileNames(configFile: ParsedCommandLine, inputFileName: string, ignoreCase: boolean, addOutput: ReturnType["addOutput"], getCommonSourceDirectory?: () => string) { - if (isDeclarationFileName(inputFileName)) return; + function getOwnOutputFileNames(configFile: ts.ParsedCommandLine, inputFileName: string, ignoreCase: boolean, addOutput: ReturnType["addOutput"], getCommonSourceDirectory?: () => string) { + if (ts.isDeclarationFileName(inputFileName)) + return; const js = getOutputJSFileName(inputFileName, configFile, ignoreCase, getCommonSourceDirectory); addOutput(js); - if (fileExtensionIs(inputFileName, Extension.Json)) return; + if (ts.fileExtensionIs(inputFileName, ts.Extension.Json)) + return; if (js && configFile.options.sourceMap) { addOutput(`${js}.map`); } - if (getEmitDeclarations(configFile.options)) { + if (ts.getEmitDeclarations(configFile.options)) { const dts = getOutputDeclarationFileName(inputFileName, configFile, ignoreCase, getCommonSourceDirectory); addOutput(dts); if (configFile.options.declarationMap) { @@ -184,55 +175,44 @@ namespace ts { } /*@internal*/ - export function getCommonSourceDirectory( - options: CompilerOptions, - emittedFiles: () => readonly string[], - currentDirectory: string, - getCanonicalFileName: GetCanonicalFileName, - checkSourceFilesBelongToPath?: (commonSourceDirectory: string) => void - ): string { + export function getCommonSourceDirectory(options: ts.CompilerOptions, emittedFiles: () => readonly string[], currentDirectory: string, getCanonicalFileName: ts.GetCanonicalFileName, checkSourceFilesBelongToPath?: (commonSourceDirectory: string) => void): string { let commonSourceDirectory; if (options.rootDir) { // If a rootDir is specified use it as the commonSourceDirectory - commonSourceDirectory = getNormalizedAbsolutePath(options.rootDir, currentDirectory); + commonSourceDirectory = ts.getNormalizedAbsolutePath(options.rootDir, currentDirectory); checkSourceFilesBelongToPath?.(options.rootDir); } else if (options.composite && options.configFilePath) { // Project compilations never infer their root from the input source paths - commonSourceDirectory = getDirectoryPath(normalizeSlashes(options.configFilePath)); + commonSourceDirectory = ts.getDirectoryPath(ts.normalizeSlashes(options.configFilePath)); checkSourceFilesBelongToPath?.(commonSourceDirectory); } else { - commonSourceDirectory = computeCommonSourceDirectoryOfFilenames(emittedFiles(), currentDirectory, getCanonicalFileName); + commonSourceDirectory = ts.computeCommonSourceDirectoryOfFilenames(emittedFiles(), currentDirectory, getCanonicalFileName); } - if (commonSourceDirectory && commonSourceDirectory[commonSourceDirectory.length - 1] !== directorySeparator) { + if (commonSourceDirectory && commonSourceDirectory[commonSourceDirectory.length - 1] !== ts.directorySeparator) { // Make sure directory path ends with directory separator so this string can directly // used to replace with "" to get the relative path of the source file and the relative path doesn't // start with / making it rooted path - commonSourceDirectory += directorySeparator; + commonSourceDirectory += ts.directorySeparator; } return commonSourceDirectory; } /*@internal*/ - export function getCommonSourceDirectoryOfConfig({ options, fileNames }: ParsedCommandLine, ignoreCase: boolean): string { - return getCommonSourceDirectory( - options, - () => filter(fileNames, file => !(options.noEmitForJsFiles && fileExtensionIsOneOf(file, supportedJSExtensionsFlat)) && !isDeclarationFileName(file)), - getDirectoryPath(normalizeSlashes(Debug.checkDefined(options.configFilePath))), - createGetCanonicalFileName(!ignoreCase) - ); + export function getCommonSourceDirectoryOfConfig({ options, fileNames }: ts.ParsedCommandLine, ignoreCase: boolean): string { + return getCommonSourceDirectory(options, () => ts.filter(fileNames, file => !(options.noEmitForJsFiles && ts.fileExtensionIsOneOf(file, ts.supportedJSExtensionsFlat)) && !ts.isDeclarationFileName(file)), ts.getDirectoryPath(ts.normalizeSlashes(ts.Debug.checkDefined(options.configFilePath))), ts.createGetCanonicalFileName(!ignoreCase)); } /*@internal*/ - export function getAllProjectOutputs(configFile: ParsedCommandLine, ignoreCase: boolean): readonly string[] { + export function getAllProjectOutputs(configFile: ts.ParsedCommandLine, ignoreCase: boolean): readonly string[] { const { addOutput, getOutputs } = createAddOutput(); - if (outFile(configFile.options)) { + if (ts.outFile(configFile.options)) { getSingleOutputFileNames(configFile, addOutput); } else { - const getCommonSourceDirectory = memoize(() => getCommonSourceDirectoryOfConfig(configFile, ignoreCase)); + const getCommonSourceDirectory = ts.memoize(() => getCommonSourceDirectoryOfConfig(configFile, ignoreCase)); for (const inputFileName of configFile.fileNames) { getOwnOutputFileNames(configFile, inputFileName, ignoreCase, addOutput, getCommonSourceDirectory); } @@ -241,11 +221,11 @@ namespace ts { return getOutputs(); } - export function getOutputFileNames(commandLine: ParsedCommandLine, inputFileName: string, ignoreCase: boolean): readonly string[] { - inputFileName = normalizePath(inputFileName); - Debug.assert(contains(commandLine.fileNames, inputFileName), `Expected fileName to be present in command line`); + export function getOutputFileNames(commandLine: ts.ParsedCommandLine, inputFileName: string, ignoreCase: boolean): readonly string[] { + inputFileName = ts.normalizePath(inputFileName); + ts.Debug.assert(ts.contains(commandLine.fileNames, inputFileName), `Expected fileName to be present in command line`); const { addOutput, getOutputs } = createAddOutput(); - if (outFile(commandLine.options)) { + if (ts.outFile(commandLine.options)) { getSingleOutputFileNames(commandLine, addOutput); } else { @@ -255,51 +235,48 @@ namespace ts { } /*@internal*/ - export function getFirstProjectOutput(configFile: ParsedCommandLine, ignoreCase: boolean): string { - if (outFile(configFile.options)) { + export function getFirstProjectOutput(configFile: ts.ParsedCommandLine, ignoreCase: boolean): string { + if (ts.outFile(configFile.options)) { const { jsFilePath } = getOutputPathsForBundle(configFile.options, /*forceDtsPaths*/ false); - return Debug.checkDefined(jsFilePath, `project ${configFile.options.configFilePath} expected to have at least one output`); + return ts.Debug.checkDefined(jsFilePath, `project ${configFile.options.configFilePath} expected to have at least one output`); } - const getCommonSourceDirectory = memoize(() => getCommonSourceDirectoryOfConfig(configFile, ignoreCase)); + const getCommonSourceDirectory = ts.memoize(() => getCommonSourceDirectoryOfConfig(configFile, ignoreCase)); for (const inputFileName of configFile.fileNames) { - if (isDeclarationFileName(inputFileName)) continue; + if (ts.isDeclarationFileName(inputFileName)) + continue; const jsFilePath = getOutputJSFileName(inputFileName, configFile, ignoreCase, getCommonSourceDirectory); - if (jsFilePath) return jsFilePath; - if (fileExtensionIs(inputFileName, Extension.Json)) continue; - if (getEmitDeclarations(configFile.options)) { + if (jsFilePath) + return jsFilePath; + if (ts.fileExtensionIs(inputFileName, ts.Extension.Json)) + continue; + if (ts.getEmitDeclarations(configFile.options)) { return getOutputDeclarationFileName(inputFileName, configFile, ignoreCase, getCommonSourceDirectory); } } const buildInfoPath = getTsBuildInfoEmitOutputFilePath(configFile.options); - if (buildInfoPath) return buildInfoPath; - return Debug.fail(`project ${configFile.options.configFilePath} expected to have at least one output`); + if (buildInfoPath) + return buildInfoPath; + return ts.Debug.fail(`project ${configFile.options.configFilePath} expected to have at least one output`); } /*@internal*/ // targetSourceFile is when users only want one file in entire project to be emitted. This is used in compileOnSave feature - export function emitFiles(resolver: EmitResolver, host: EmitHost, targetSourceFile: SourceFile | undefined, { scriptTransformers, declarationTransformers }: EmitTransformers, emitOnlyDtsFiles?: boolean, onlyBuildInfo?: boolean, forceDtsEmit?: boolean): EmitResult { + export function emitFiles(resolver: ts.EmitResolver, host: ts.EmitHost, targetSourceFile: ts.SourceFile | undefined, { scriptTransformers, declarationTransformers }: ts.EmitTransformers, emitOnlyDtsFiles?: boolean, onlyBuildInfo?: boolean, forceDtsEmit?: boolean): ts.EmitResult { const compilerOptions = host.getCompilerOptions(); - const sourceMapDataList: SourceMapEmitResult[] | undefined = (compilerOptions.sourceMap || compilerOptions.inlineSourceMap || getAreDeclarationMapsEnabled(compilerOptions)) ? [] : undefined; + const sourceMapDataList: ts.SourceMapEmitResult[] | undefined = (compilerOptions.sourceMap || compilerOptions.inlineSourceMap || ts.getAreDeclarationMapsEnabled(compilerOptions)) ? [] : undefined; const emittedFilesList: string[] | undefined = compilerOptions.listEmittedFiles ? [] : undefined; - const emitterDiagnostics = createDiagnosticCollection(); - const newLine = getNewLineCharacter(compilerOptions, () => host.getNewLine()); - const writer = createTextWriter(newLine); - const { enter, exit } = performance.createTimer("printTime", "beforePrint", "afterPrint"); - let bundleBuildInfo: BundleBuildInfo | undefined; + const emitterDiagnostics = ts.createDiagnosticCollection(); + const newLine = ts.getNewLineCharacter(compilerOptions, () => host.getNewLine()); + const writer = ts.createTextWriter(newLine); + const { enter, exit } = ts.performance.createTimer("printTime", "beforePrint", "afterPrint"); + let bundleBuildInfo: ts.BundleBuildInfo | undefined; let emitSkipped = false; - let exportedModulesFromDeclarationEmit: ExportedModulesFromDeclarationEmit | undefined; + let exportedModulesFromDeclarationEmit: ts.ExportedModulesFromDeclarationEmit | undefined; // Emit each output file enter(); - forEachEmittedFile( - host, - emitSourceFileOrBundle, - getSourceFilesToEmit(host, targetSourceFile, forceDtsEmit), - forceDtsEmit, - onlyBuildInfo, - !targetSourceFile - ); + forEachEmittedFile(host, emitSourceFileOrBundle, ts.getSourceFilesToEmit(host, targetSourceFile, forceDtsEmit), forceDtsEmit, onlyBuildInfo, !targetSourceFile); exit(); @@ -311,26 +288,24 @@ namespace ts { exportedModulesFromDeclarationEmit }; - function emitSourceFileOrBundle({ jsFilePath, sourceMapFilePath, declarationFilePath, declarationMapPath, buildInfoPath }: EmitFileNames, sourceFileOrBundle: SourceFile | Bundle | undefined) { + function emitSourceFileOrBundle({ jsFilePath, sourceMapFilePath, declarationFilePath, declarationMapPath, buildInfoPath }: ts.EmitFileNames, sourceFileOrBundle: ts.SourceFile | ts.Bundle | undefined) { let buildInfoDirectory: string | undefined; - if (buildInfoPath && sourceFileOrBundle && isBundle(sourceFileOrBundle)) { - buildInfoDirectory = getDirectoryPath(getNormalizedAbsolutePath(buildInfoPath, host.getCurrentDirectory())); + if (buildInfoPath && sourceFileOrBundle && ts.isBundle(sourceFileOrBundle)) { + buildInfoDirectory = ts.getDirectoryPath(ts.getNormalizedAbsolutePath(buildInfoPath, host.getCurrentDirectory())); bundleBuildInfo = { commonSourceDirectory: relativeToBuildInfo(host.getCommonSourceDirectory()), - sourceFiles: sourceFileOrBundle.sourceFiles.map(file => relativeToBuildInfo(getNormalizedAbsolutePath(file.fileName, host.getCurrentDirectory()))) + sourceFiles: sourceFileOrBundle.sourceFiles.map(file => relativeToBuildInfo(ts.getNormalizedAbsolutePath(file.fileName, host.getCurrentDirectory()))) }; } - tracing?.push(tracing.Phase.Emit, "emitJsFileOrBundle", { jsFilePath }); + ts.tracing?.push(ts.tracing.Phase.Emit, "emitJsFileOrBundle", { jsFilePath }); emitJsFileOrBundle(sourceFileOrBundle, jsFilePath, sourceMapFilePath, relativeToBuildInfo); - tracing?.pop(); - - tracing?.push(tracing.Phase.Emit, "emitDeclarationFileOrBundle", { declarationFilePath }); + ts.tracing?.pop(); + ts.tracing?.push(ts.tracing.Phase.Emit, "emitDeclarationFileOrBundle", { declarationFilePath }); emitDeclarationFileOrBundle(sourceFileOrBundle, declarationFilePath, declarationMapPath, relativeToBuildInfo); - tracing?.pop(); - - tracing?.push(tracing.Phase.Emit, "emitBuildInfo", { buildInfoPath }); + ts.tracing?.pop(); + ts.tracing?.push(ts.tracing.Phase.Emit, "emitBuildInfo", { buildInfoPath }); emitBuildInfo(bundleBuildInfo, buildInfoPath); - tracing?.pop(); + ts.tracing?.pop(); if (!emitSkipped && emittedFilesList) { if (!emitOnlyDtsFiles) { @@ -353,27 +328,23 @@ namespace ts { } function relativeToBuildInfo(path: string) { - return ensurePathIsNonModuleName(getRelativePathFromDirectory(buildInfoDirectory!, path, host.getCanonicalFileName)); + return ts.ensurePathIsNonModuleName(ts.getRelativePathFromDirectory(buildInfoDirectory!, path, host.getCanonicalFileName)); } } - function emitBuildInfo(bundle: BundleBuildInfo | undefined, buildInfoPath: string | undefined) { + function emitBuildInfo(bundle: ts.BundleBuildInfo | undefined, buildInfoPath: string | undefined) { // Write build information if applicable - if (!buildInfoPath || targetSourceFile || emitSkipped) return; + if (!buildInfoPath || targetSourceFile || emitSkipped) + return; const program = host.getProgramBuildInfo(); if (host.isEmitBlocked(buildInfoPath)) { emitSkipped = true; return; } const version = ts.version; // Extracted into a const so the form is stable between namespace and module - writeFile(host, emitterDiagnostics, buildInfoPath, getBuildInfoText({ bundle, program, version }), /*writeByteOrderMark*/ false); + ts.writeFile(host, emitterDiagnostics, buildInfoPath, getBuildInfoText({ bundle, program, version }), /*writeByteOrderMark*/ false); } - - function emitJsFileOrBundle( - sourceFileOrBundle: SourceFile | Bundle | undefined, - jsFilePath: string | undefined, - sourceMapFilePath: string | undefined, - relativeToBuildInfo: (path: string) => string) { + function emitJsFileOrBundle(sourceFileOrBundle: ts.SourceFile | ts.Bundle | undefined, jsFilePath: string | undefined, sourceMapFilePath: string | undefined, relativeToBuildInfo: (path: string) => string) { if (!sourceFileOrBundle || emitOnlyDtsFiles || !jsFilePath) { return; } @@ -384,9 +355,8 @@ namespace ts { return; } // Transform the source files - const transform = transformNodes(resolver, host, factory, compilerOptions, [sourceFileOrBundle], scriptTransformers, /*allowDtsFiles*/ false); - - const printerOptions: PrinterOptions = { + const transform = ts.transformNodes(resolver, host, ts.factory, compilerOptions, [sourceFileOrBundle], scriptTransformers, /*allowDtsFiles*/ false); + const printerOptions: ts.PrinterOptions = { removeComments: compilerOptions.removeComments, newLine: compilerOptions.newLine, noEmitHelpers: compilerOptions.noEmitHelpers, @@ -411,41 +381,39 @@ namespace ts { substituteNode: transform.substituteNode, }); - Debug.assert(transform.transformed.length === 1, "Should only see one output from the transform"); + ts.Debug.assert(transform.transformed.length === 1, "Should only see one output from the transform"); printSourceFileOrBundle(jsFilePath, sourceMapFilePath, transform.transformed[0], printer, compilerOptions); // Clean up emit nodes on parse tree transform.dispose(); - if (bundleBuildInfo) bundleBuildInfo.js = printer.bundleFileInfo; + if (bundleBuildInfo) + bundleBuildInfo.js = printer.bundleFileInfo; } - - function emitDeclarationFileOrBundle( - sourceFileOrBundle: SourceFile | Bundle | undefined, - declarationFilePath: string | undefined, - declarationMapPath: string | undefined, - relativeToBuildInfo: (path: string) => string) { - if (!sourceFileOrBundle) return; + function emitDeclarationFileOrBundle(sourceFileOrBundle: ts.SourceFile | ts.Bundle | undefined, declarationFilePath: string | undefined, declarationMapPath: string | undefined, relativeToBuildInfo: (path: string) => string) { + if (!sourceFileOrBundle) + return; if (!declarationFilePath) { - if (emitOnlyDtsFiles || compilerOptions.emitDeclarationOnly) emitSkipped = true; + if (emitOnlyDtsFiles || compilerOptions.emitDeclarationOnly) + emitSkipped = true; return; } - const sourceFiles = isSourceFile(sourceFileOrBundle) ? [sourceFileOrBundle] : sourceFileOrBundle.sourceFiles; - const filesForEmit = forceDtsEmit ? sourceFiles : filter(sourceFiles, isSourceFileNotJson); + const sourceFiles = ts.isSourceFile(sourceFileOrBundle) ? [sourceFileOrBundle] : sourceFileOrBundle.sourceFiles; + const filesForEmit = forceDtsEmit ? sourceFiles : ts.filter(sourceFiles, ts.isSourceFileNotJson); // Setup and perform the transformation to retrieve declarations from the input files - const inputListOrBundle = outFile(compilerOptions) ? [factory.createBundle(filesForEmit, !isSourceFile(sourceFileOrBundle) ? sourceFileOrBundle.prepends : undefined)] : filesForEmit; - if (emitOnlyDtsFiles && !getEmitDeclarations(compilerOptions)) { + const inputListOrBundle = ts.outFile(compilerOptions) ? [ts.factory.createBundle(filesForEmit, !ts.isSourceFile(sourceFileOrBundle) ? sourceFileOrBundle.prepends : undefined)] : filesForEmit; + if (emitOnlyDtsFiles && !ts.getEmitDeclarations(compilerOptions)) { // Checker wont collect the linked aliases since thats only done when declaration is enabled. // Do that here when emitting only dts files filesForEmit.forEach(collectLinkedAliases); } - const declarationTransform = transformNodes(resolver, host, factory, compilerOptions, inputListOrBundle, declarationTransformers, /*allowDtsFiles*/ false); - if (length(declarationTransform.diagnostics)) { + const declarationTransform = ts.transformNodes(resolver, host, ts.factory, compilerOptions, inputListOrBundle, declarationTransformers, /*allowDtsFiles*/ false); + if (ts.length(declarationTransform.diagnostics)) { for (const diagnostic of declarationTransform.diagnostics!) { emitterDiagnostics.add(diagnostic); } } - const printerOptions: PrinterOptions = { + const printerOptions: ts.PrinterOptions = { removeComments: compilerOptions.removeComments, newLine: compilerOptions.newLine, noEmitHelpers: true, @@ -472,56 +440,46 @@ namespace ts { const declBlocked = (!!declarationTransform.diagnostics && !!declarationTransform.diagnostics.length) || !!host.isEmitBlocked(declarationFilePath) || !!compilerOptions.noEmit; emitSkipped = emitSkipped || declBlocked; if (!declBlocked || forceDtsEmit) { - Debug.assert(declarationTransform.transformed.length === 1, "Should only see one output from the decl transform"); - printSourceFileOrBundle( - declarationFilePath, - declarationMapPath, - declarationTransform.transformed[0], - declarationPrinter, - { + ts.Debug.assert(declarationTransform.transformed.length === 1, "Should only see one output from the decl transform"); + printSourceFileOrBundle(declarationFilePath, declarationMapPath, declarationTransform.transformed[0], declarationPrinter, { sourceMap: !forceDtsEmit && compilerOptions.declarationMap, sourceRoot: compilerOptions.sourceRoot, mapRoot: compilerOptions.mapRoot, extendedDiagnostics: compilerOptions.extendedDiagnostics, // Explicitly do not passthru either `inline` option - } - ); - if (forceDtsEmit && declarationTransform.transformed[0].kind === SyntaxKind.SourceFile) { + }); + if (forceDtsEmit && declarationTransform.transformed[0].kind === ts.SyntaxKind.SourceFile) { const sourceFile = declarationTransform.transformed[0]; exportedModulesFromDeclarationEmit = sourceFile.exportedModulesFromDeclarationEmit; } } declarationTransform.dispose(); - if (bundleBuildInfo) bundleBuildInfo.dts = declarationPrinter.bundleFileInfo; + if (bundleBuildInfo) + bundleBuildInfo.dts = declarationPrinter.bundleFileInfo; } - function collectLinkedAliases(node: Node) { - if (isExportAssignment(node)) { - if (node.expression.kind === SyntaxKind.Identifier) { - resolver.collectLinkedAliases(node.expression as Identifier, /*setVisibility*/ true); + function collectLinkedAliases(node: ts.Node) { + if (ts.isExportAssignment(node)) { + if (node.expression.kind === ts.SyntaxKind.Identifier) { + resolver.collectLinkedAliases(node.expression as ts.Identifier, /*setVisibility*/ true); } return; } - else if (isExportSpecifier(node)) { + else if (ts.isExportSpecifier(node)) { resolver.collectLinkedAliases(node.propertyName || node.name, /*setVisibility*/ true); return; } - forEachChild(node, collectLinkedAliases); + ts.forEachChild(node, collectLinkedAliases); } - function printSourceFileOrBundle(jsFilePath: string, sourceMapFilePath: string | undefined, sourceFileOrBundle: SourceFile | Bundle, printer: Printer, mapOptions: SourceMapOptions) { - const bundle = sourceFileOrBundle.kind === SyntaxKind.Bundle ? sourceFileOrBundle : undefined; - const sourceFile = sourceFileOrBundle.kind === SyntaxKind.SourceFile ? sourceFileOrBundle : undefined; + function printSourceFileOrBundle(jsFilePath: string, sourceMapFilePath: string | undefined, sourceFileOrBundle: ts.SourceFile | ts.Bundle, printer: ts.Printer, mapOptions: SourceMapOptions) { + const bundle = sourceFileOrBundle.kind === ts.SyntaxKind.Bundle ? sourceFileOrBundle : undefined; + const sourceFile = sourceFileOrBundle.kind === ts.SyntaxKind.SourceFile ? sourceFileOrBundle : undefined; const sourceFiles = bundle ? bundle.sourceFiles : [sourceFile!]; - let sourceMapGenerator: SourceMapGenerator | undefined; + let sourceMapGenerator: ts.SourceMapGenerator | undefined; if (shouldEmitSourceMaps(mapOptions, sourceFileOrBundle)) { - sourceMapGenerator = createSourceMapGenerator( - host, - getBaseFileName(normalizeSlashes(jsFilePath)), - getSourceRoot(mapOptions), - getSourceMapDirectory(mapOptions, jsFilePath, sourceFile), - mapOptions); + sourceMapGenerator = ts.createSourceMapGenerator(host, ts.getBaseFileName(ts.normalizeSlashes(jsFilePath)), getSourceRoot(mapOptions), getSourceMapDirectory(mapOptions, jsFilePath, sourceFile), mapOptions); } if (bundle) { @@ -540,15 +498,11 @@ namespace ts { }); } - const sourceMappingURL = getSourceMappingURL( - mapOptions, - sourceMapGenerator, - jsFilePath, - sourceMapFilePath, - sourceFile); + const sourceMappingURL = getSourceMappingURL(mapOptions, sourceMapGenerator, jsFilePath, sourceMapFilePath, sourceFile); if (sourceMappingURL) { - if (!writer.isAtStartOfLine()) writer.rawWrite(newLine); + if (!writer.isAtStartOfLine()) + writer.rawWrite(newLine); sourceMapUrlPos = writer.getTextPos(); writer.writeComment(`//# ${"sourceMappingURL"}=${sourceMappingURL}`); // Tools can sometimes see this line as a source mapping url comment } @@ -556,7 +510,7 @@ namespace ts { // Write the source map if (sourceMapFilePath) { const sourceMap = sourceMapGenerator.toString(); - writeFile(host, emitterDiagnostics, sourceMapFilePath, sourceMap, /*writeByteOrderMark*/ false, sourceFiles); + ts.writeFile(host, emitterDiagnostics, sourceMapFilePath, sourceMap, /*writeByteOrderMark*/ false, sourceFiles); } } else { @@ -564,7 +518,7 @@ namespace ts { } // Write the output file - writeFile(host, emitterDiagnostics, jsFilePath, writer.getText(), !!compilerOptions.emitBOM, sourceFiles, { sourceMapUrlPos }); + ts.writeFile(host, emitterDiagnostics, jsFilePath, writer.getText(), !!compilerOptions.emitBOM, sourceFiles, { sourceMapUrlPos }); // Reset state writer.clear(); @@ -579,65 +533,63 @@ namespace ts { extendedDiagnostics?: boolean; } - function shouldEmitSourceMaps(mapOptions: SourceMapOptions, sourceFileOrBundle: SourceFile | Bundle) { + function shouldEmitSourceMaps(mapOptions: SourceMapOptions, sourceFileOrBundle: ts.SourceFile | ts.Bundle) { return (mapOptions.sourceMap || mapOptions.inlineSourceMap) - && (sourceFileOrBundle.kind !== SyntaxKind.SourceFile || !fileExtensionIs(sourceFileOrBundle.fileName, Extension.Json)); + && (sourceFileOrBundle.kind !== ts.SyntaxKind.SourceFile || !ts.fileExtensionIs(sourceFileOrBundle.fileName, ts.Extension.Json)); } function getSourceRoot(mapOptions: SourceMapOptions) { // Normalize source root and make sure it has trailing "/" so that it can be used to combine paths with the // relative paths of the sources list in the sourcemap - const sourceRoot = normalizeSlashes(mapOptions.sourceRoot || ""); - return sourceRoot ? ensureTrailingDirectorySeparator(sourceRoot) : sourceRoot; + const sourceRoot = ts.normalizeSlashes(mapOptions.sourceRoot || ""); + return sourceRoot ? ts.ensureTrailingDirectorySeparator(sourceRoot) : sourceRoot; } - function getSourceMapDirectory(mapOptions: SourceMapOptions, filePath: string, sourceFile: SourceFile | undefined) { - if (mapOptions.sourceRoot) return host.getCommonSourceDirectory(); + function getSourceMapDirectory(mapOptions: SourceMapOptions, filePath: string, sourceFile: ts.SourceFile | undefined) { + if (mapOptions.sourceRoot) + return host.getCommonSourceDirectory(); if (mapOptions.mapRoot) { - let sourceMapDir = normalizeSlashes(mapOptions.mapRoot); + let sourceMapDir = ts.normalizeSlashes(mapOptions.mapRoot); if (sourceFile) { // For modules or multiple emit files the mapRoot will have directory structure like the sources // So if src\a.ts and src\lib\b.ts are compiled together user would be moving the maps into mapRoot\a.js.map and mapRoot\lib\b.js.map - sourceMapDir = getDirectoryPath(getSourceFilePathInNewDir(sourceFile.fileName, host, sourceMapDir)); + sourceMapDir = ts.getDirectoryPath(ts.getSourceFilePathInNewDir(sourceFile.fileName, host, sourceMapDir)); } - if (getRootLength(sourceMapDir) === 0) { + if (ts.getRootLength(sourceMapDir) === 0) { // The relative paths are relative to the common directory - sourceMapDir = combinePaths(host.getCommonSourceDirectory(), sourceMapDir); + sourceMapDir = ts.combinePaths(host.getCommonSourceDirectory(), sourceMapDir); } return sourceMapDir; } - return getDirectoryPath(normalizePath(filePath)); + return ts.getDirectoryPath(ts.normalizePath(filePath)); } - function getSourceMappingURL(mapOptions: SourceMapOptions, sourceMapGenerator: SourceMapGenerator, filePath: string, sourceMapFilePath: string | undefined, sourceFile: SourceFile | undefined) { + function getSourceMappingURL(mapOptions: SourceMapOptions, sourceMapGenerator: ts.SourceMapGenerator, filePath: string, sourceMapFilePath: string | undefined, sourceFile: ts.SourceFile | undefined) { if (mapOptions.inlineSourceMap) { // Encode the sourceMap into the sourceMap url const sourceMapText = sourceMapGenerator.toString(); - const base64SourceMapText = base64encode(sys, sourceMapText); + const base64SourceMapText = ts.base64encode(ts.sys, sourceMapText); return `data:application/json;base64,${base64SourceMapText}`; } - const sourceMapFile = getBaseFileName(normalizeSlashes(Debug.checkDefined(sourceMapFilePath))); + const sourceMapFile = ts.getBaseFileName(ts.normalizeSlashes(ts.Debug.checkDefined(sourceMapFilePath))); if (mapOptions.mapRoot) { - let sourceMapDir = normalizeSlashes(mapOptions.mapRoot); + let sourceMapDir = ts.normalizeSlashes(mapOptions.mapRoot); if (sourceFile) { // For modules or multiple emit files the mapRoot will have directory structure like the sources // So if src\a.ts and src\lib\b.ts are compiled together user would be moving the maps into mapRoot\a.js.map and mapRoot\lib\b.js.map - sourceMapDir = getDirectoryPath(getSourceFilePathInNewDir(sourceFile.fileName, host, sourceMapDir)); + sourceMapDir = ts.getDirectoryPath(ts.getSourceFilePathInNewDir(sourceFile.fileName, host, sourceMapDir)); } - if (getRootLength(sourceMapDir) === 0) { + if (ts.getRootLength(sourceMapDir) === 0) { // The relative paths are relative to the common directory - sourceMapDir = combinePaths(host.getCommonSourceDirectory(), sourceMapDir); - return encodeURI( - getRelativePathToDirectoryOrUrl( - getDirectoryPath(normalizePath(filePath)), // get the relative sourceMapDir path based on jsFilePath - combinePaths(sourceMapDir, sourceMapFile), // this is where user expects to see sourceMap - host.getCurrentDirectory(), - host.getCanonicalFileName, + sourceMapDir = ts.combinePaths(host.getCommonSourceDirectory(), sourceMapDir); + return encodeURI(ts.getRelativePathToDirectoryOrUrl(ts.getDirectoryPath(ts.normalizePath(filePath)), // get the relative sourceMapDir path based on jsFilePath + ts.combinePaths(sourceMapDir, sourceMapFile), // this is where user expects to see sourceMap + host.getCurrentDirectory(), host.getCanonicalFileName, /*isAbsolutePathAnUrl*/ true)); } else { - return encodeURI(combinePaths(sourceMapDir, sourceMapFile)); + return encodeURI(ts.combinePaths(sourceMapDir, sourceMapFile)); } } return encodeURI(sourceMapFile); @@ -645,162 +597,150 @@ namespace ts { } /*@internal*/ - export function getBuildInfoText(buildInfo: BuildInfo) { + export function getBuildInfoText(buildInfo: ts.BuildInfo) { return JSON.stringify(buildInfo); } /*@internal*/ export function getBuildInfo(buildInfoText: string) { - return JSON.parse(buildInfoText) as BuildInfo; + return JSON.parse(buildInfoText) as ts.BuildInfo; } /*@internal*/ - export const notImplementedResolver: EmitResolver = { - hasGlobalName: notImplemented, - getReferencedExportContainer: notImplemented, - getReferencedImportDeclaration: notImplemented, - getReferencedDeclarationWithCollidingName: notImplemented, - isDeclarationWithCollidingName: notImplemented, - isValueAliasDeclaration: notImplemented, - isReferencedAliasDeclaration: notImplemented, - isTopLevelValueImportEqualsWithEntityName: notImplemented, - getNodeCheckFlags: notImplemented, - isDeclarationVisible: notImplemented, - isLateBound: (_node): _node is LateBoundDeclaration => false, - collectLinkedAliases: notImplemented, - isImplementationOfOverload: notImplemented, - isRequiredInitializedParameter: notImplemented, - isOptionalUninitializedParameterProperty: notImplemented, - isExpandoFunctionDeclaration: notImplemented, - getPropertiesOfContainerFunction: notImplemented, - createTypeOfDeclaration: notImplemented, - createReturnTypeOfSignatureDeclaration: notImplemented, - createTypeOfExpression: notImplemented, - createLiteralConstValue: notImplemented, - isSymbolAccessible: notImplemented, - isEntityNameVisible: notImplemented, + export const notImplementedResolver: ts.EmitResolver = { + hasGlobalName: ts.notImplemented, + getReferencedExportContainer: ts.notImplemented, + getReferencedImportDeclaration: ts.notImplemented, + getReferencedDeclarationWithCollidingName: ts.notImplemented, + isDeclarationWithCollidingName: ts.notImplemented, + isValueAliasDeclaration: ts.notImplemented, + isReferencedAliasDeclaration: ts.notImplemented, + isTopLevelValueImportEqualsWithEntityName: ts.notImplemented, + getNodeCheckFlags: ts.notImplemented, + isDeclarationVisible: ts.notImplemented, + isLateBound: (_node): _node is ts.LateBoundDeclaration => false, + collectLinkedAliases: ts.notImplemented, + isImplementationOfOverload: ts.notImplemented, + isRequiredInitializedParameter: ts.notImplemented, + isOptionalUninitializedParameterProperty: ts.notImplemented, + isExpandoFunctionDeclaration: ts.notImplemented, + getPropertiesOfContainerFunction: ts.notImplemented, + createTypeOfDeclaration: ts.notImplemented, + createReturnTypeOfSignatureDeclaration: ts.notImplemented, + createTypeOfExpression: ts.notImplemented, + createLiteralConstValue: ts.notImplemented, + isSymbolAccessible: ts.notImplemented, + isEntityNameVisible: ts.notImplemented, // Returns the constant value this property access resolves to: notImplemented, or 'undefined' for a non-constant - getConstantValue: notImplemented, - getReferencedValueDeclaration: notImplemented, - getTypeReferenceSerializationKind: notImplemented, - isOptionalParameter: notImplemented, - moduleExportsSomeValue: notImplemented, - isArgumentsLocalBinding: notImplemented, - getExternalModuleFileFromDeclaration: notImplemented, - getTypeReferenceDirectivesForEntityName: notImplemented, - getTypeReferenceDirectivesForSymbol: notImplemented, - isLiteralConstDeclaration: notImplemented, - getJsxFactoryEntity: notImplemented, - getJsxFragmentFactoryEntity: notImplemented, - getAllAccessorDeclarations: notImplemented, - getSymbolOfExternalModuleSpecifier: notImplemented, - isBindingCapturedByNode: notImplemented, - getDeclarationStatementsForSourceFile: notImplemented, - isImportRequiredByAugmentation: notImplemented, + getConstantValue: ts.notImplemented, + getReferencedValueDeclaration: ts.notImplemented, + getTypeReferenceSerializationKind: ts.notImplemented, + isOptionalParameter: ts.notImplemented, + moduleExportsSomeValue: ts.notImplemented, + isArgumentsLocalBinding: ts.notImplemented, + getExternalModuleFileFromDeclaration: ts.notImplemented, + getTypeReferenceDirectivesForEntityName: ts.notImplemented, + getTypeReferenceDirectivesForSymbol: ts.notImplemented, + isLiteralConstDeclaration: ts.notImplemented, + getJsxFactoryEntity: ts.notImplemented, + getJsxFragmentFactoryEntity: ts.notImplemented, + getAllAccessorDeclarations: ts.notImplemented, + getSymbolOfExternalModuleSpecifier: ts.notImplemented, + isBindingCapturedByNode: ts.notImplemented, + getDeclarationStatementsForSourceFile: ts.notImplemented, + isImportRequiredByAugmentation: ts.notImplemented, }; /*@internal*/ /** File that isnt present resulting in error or output files */ - export type EmitUsingBuildInfoResult = string | readonly OutputFile[]; + export type EmitUsingBuildInfoResult = string | readonly ts.OutputFile[]; /*@internal*/ - export interface EmitUsingBuildInfoHost extends ModuleResolutionHost { + export interface EmitUsingBuildInfoHost extends ts.ModuleResolutionHost { getCurrentDirectory(): string; getCanonicalFileName(fileName: string): string; useCaseSensitiveFileNames(): boolean; getNewLine(): string; } - function createSourceFilesFromBundleBuildInfo(bundle: BundleBuildInfo, buildInfoDirectory: string, host: EmitUsingBuildInfoHost): readonly SourceFile[] { - const jsBundle = Debug.checkDefined(bundle.js); - const prologueMap = jsBundle.sources?.prologues && arrayToMap(jsBundle.sources.prologues, prologueInfo => prologueInfo.file); + function createSourceFilesFromBundleBuildInfo(bundle: ts.BundleBuildInfo, buildInfoDirectory: string, host: EmitUsingBuildInfoHost): readonly ts.SourceFile[] { + const jsBundle = ts.Debug.checkDefined(bundle.js); + const prologueMap = jsBundle.sources?.prologues && ts.arrayToMap(jsBundle.sources.prologues, prologueInfo => prologueInfo.file); return bundle.sourceFiles.map((fileName, index) => { const prologueInfo = prologueMap?.get(index); const statements = prologueInfo?.directives.map(directive => { - const literal = setTextRange(factory.createStringLiteral(directive.expression.text), directive.expression); - const statement = setTextRange(factory.createExpressionStatement(literal), directive); - setParent(literal, statement); + const literal = ts.setTextRange(ts.factory.createStringLiteral(directive.expression.text), directive.expression); + const statement = ts.setTextRange(ts.factory.createExpressionStatement(literal), directive); + ts.setParent(literal, statement); return statement; }); - const eofToken = factory.createToken(SyntaxKind.EndOfFileToken); - const sourceFile = factory.createSourceFile(statements ?? [], eofToken, NodeFlags.None); - sourceFile.fileName = getRelativePathFromDirectory( - host.getCurrentDirectory(), - getNormalizedAbsolutePath(fileName, buildInfoDirectory), - !host.useCaseSensitiveFileNames() - ); + const eofToken = ts.factory.createToken(ts.SyntaxKind.EndOfFileToken); + const sourceFile = ts.factory.createSourceFile(statements ?? [], eofToken, ts.NodeFlags.None); + sourceFile.fileName = ts.getRelativePathFromDirectory(host.getCurrentDirectory(), ts.getNormalizedAbsolutePath(fileName, buildInfoDirectory), !host.useCaseSensitiveFileNames()); sourceFile.text = prologueInfo?.text ?? ""; - setTextRangePosWidth(sourceFile, 0, prologueInfo?.text.length ?? 0); - setEachParent(sourceFile.statements, sourceFile); - setTextRangePosWidth(eofToken, sourceFile.end, 0); - setParent(eofToken, sourceFile); + ts.setTextRangePosWidth(sourceFile, 0, prologueInfo?.text.length ?? 0); + ts.setEachParent(sourceFile.statements, sourceFile); + ts.setTextRangePosWidth(eofToken, sourceFile.end, 0); + ts.setParent(eofToken, sourceFile); return sourceFile; }); } /*@internal*/ - export function emitUsingBuildInfo( - config: ParsedCommandLine, - host: EmitUsingBuildInfoHost, - getCommandLine: (ref: ProjectReference) => ParsedCommandLine | undefined, - customTransformers?: CustomTransformers - ): EmitUsingBuildInfoResult { + export function emitUsingBuildInfo(config: ts.ParsedCommandLine, host: EmitUsingBuildInfoHost, getCommandLine: (ref: ts.ProjectReference) => ts.ParsedCommandLine | undefined, customTransformers?: ts.CustomTransformers): EmitUsingBuildInfoResult { const { buildInfoPath, jsFilePath, sourceMapFilePath, declarationFilePath, declarationMapPath } = getOutputPathsForBundle(config.options, /*forceDtsPaths*/ false); - const buildInfoText = host.readFile(Debug.checkDefined(buildInfoPath)); - if (!buildInfoText) return buildInfoPath!; - const jsFileText = host.readFile(Debug.checkDefined(jsFilePath)); - if (!jsFileText) return jsFilePath!; + const buildInfoText = host.readFile(ts.Debug.checkDefined(buildInfoPath)); + if (!buildInfoText) + return buildInfoPath!; + const jsFileText = host.readFile(ts.Debug.checkDefined(jsFilePath)); + if (!jsFileText) + return jsFilePath!; const sourceMapText = sourceMapFilePath && host.readFile(sourceMapFilePath); // error if no source map or for now if inline sourcemap - if ((sourceMapFilePath && !sourceMapText) || config.options.inlineSourceMap) return sourceMapFilePath || "inline sourcemap decoding"; + if ((sourceMapFilePath && !sourceMapText) || config.options.inlineSourceMap) + return sourceMapFilePath || "inline sourcemap decoding"; // read declaration text const declarationText = declarationFilePath && host.readFile(declarationFilePath); - if (declarationFilePath && !declarationText) return declarationFilePath; + if (declarationFilePath && !declarationText) + return declarationFilePath; const declarationMapText = declarationMapPath && host.readFile(declarationMapPath); // error if no source map or for now if inline sourcemap - if ((declarationMapPath && !declarationMapText) || config.options.inlineSourceMap) return declarationMapPath || "inline sourcemap decoding"; + if ((declarationMapPath && !declarationMapText) || config.options.inlineSourceMap) + return declarationMapPath || "inline sourcemap decoding"; const buildInfo = getBuildInfo(buildInfoText); - if (!buildInfo.bundle || !buildInfo.bundle.js || (declarationText && !buildInfo.bundle.dts)) return buildInfoPath!; - const buildInfoDirectory = getDirectoryPath(getNormalizedAbsolutePath(buildInfoPath!, host.getCurrentDirectory())); - const ownPrependInput = createInputFiles( - jsFileText, - declarationText!, - sourceMapFilePath, - sourceMapText, - declarationMapPath, - declarationMapText, - jsFilePath, - declarationFilePath, - buildInfoPath, - buildInfo, - /*onlyOwnText*/ true - ); - const outputFiles: OutputFile[] = []; - const prependNodes = createPrependNodes(config.projectReferences, getCommandLine, f => host.readFile(f)); + if (!buildInfo.bundle || !buildInfo.bundle.js || (declarationText && !buildInfo.bundle.dts)) + return buildInfoPath!; + const buildInfoDirectory = ts.getDirectoryPath(ts.getNormalizedAbsolutePath(buildInfoPath!, host.getCurrentDirectory())); + const ownPrependInput = ts.createInputFiles(jsFileText, declarationText!, sourceMapFilePath, sourceMapText, declarationMapPath, declarationMapText, jsFilePath, declarationFilePath, buildInfoPath, buildInfo, + /*onlyOwnText*/ true); + const outputFiles: ts.OutputFile[] = []; + const prependNodes = ts.createPrependNodes(config.projectReferences, getCommandLine, f => host.readFile(f)); const sourceFilesForJsEmit = createSourceFilesFromBundleBuildInfo(buildInfo.bundle, buildInfoDirectory, host); - const emitHost: EmitHost = { - getPrependNodes: memoize(() => [...prependNodes, ownPrependInput]), + const emitHost: ts.EmitHost = { + getPrependNodes: ts.memoize(() => [...prependNodes, ownPrependInput]), getCanonicalFileName: host.getCanonicalFileName, - getCommonSourceDirectory: () => getNormalizedAbsolutePath(buildInfo.bundle!.commonSourceDirectory, buildInfoDirectory), + getCommonSourceDirectory: () => ts.getNormalizedAbsolutePath(buildInfo.bundle!.commonSourceDirectory, buildInfoDirectory), getCompilerOptions: () => config.options, getCurrentDirectory: () => host.getCurrentDirectory(), getNewLine: () => host.getNewLine(), - getSourceFile: returnUndefined, - getSourceFileByPath: returnUndefined, + getSourceFile: ts.returnUndefined, + getSourceFileByPath: ts.returnUndefined, getSourceFiles: () => sourceFilesForJsEmit, - getLibFileFromReference: notImplemented, - isSourceFileFromExternalLibrary: returnFalse, - getResolvedProjectReferenceToRedirect: returnUndefined, - getProjectReferenceRedirect: returnUndefined, - isSourceOfProjectReferenceRedirect: returnFalse, + getLibFileFromReference: ts.notImplemented, + isSourceFileFromExternalLibrary: ts.returnFalse, + getResolvedProjectReferenceToRedirect: ts.returnUndefined, + getProjectReferenceRedirect: ts.returnUndefined, + isSourceOfProjectReferenceRedirect: ts.returnFalse, writeFile: (name, text, writeByteOrderMark) => { switch (name) { case jsFilePath: - if (jsFileText === text) return; + if (jsFileText === text) + return; break; case sourceMapFilePath: - if (sourceMapText === text) return; + if (sourceMapText === text) + return; break; case buildInfoPath: const newBuildInfo = getBuildInfo(text); @@ -815,31 +755,29 @@ namespace ts { outputFiles.push({ name, text: getBuildInfoText(newBuildInfo), writeByteOrderMark }); return; case declarationFilePath: - if (declarationText === text) return; + if (declarationText === text) + return; break; case declarationMapPath: - if (declarationMapText === text) return; + if (declarationMapText === text) + return; break; default: - Debug.fail(`Unexpected path: ${name}`); + ts.Debug.fail(`Unexpected path: ${name}`); } outputFiles.push({ name, text, writeByteOrderMark }); }, - isEmitBlocked: returnFalse, + isEmitBlocked: ts.returnFalse, readFile: f => host.readFile(f), fileExists: f => host.fileExists(f), useCaseSensitiveFileNames: () => host.useCaseSensitiveFileNames(), - getProgramBuildInfo: returnUndefined, - getSourceFileFromReference: returnUndefined, - redirectTargetsMap: createMultiMap(), - getFileIncludeReasons: notImplemented, + getProgramBuildInfo: ts.returnUndefined, + getSourceFileFromReference: ts.returnUndefined, + redirectTargetsMap: ts.createMultiMap(), + getFileIncludeReasons: ts.notImplemented, }; - emitFiles( - notImplementedResolver, - emitHost, - /*targetSourceFile*/ undefined, - getTransformers(config.options, customTransformers) - ); + emitFiles(notImplementedResolver, emitHost, + /*targetSourceFile*/ undefined, ts.getTransformers(config.options, customTransformers)); return outputFiles; } @@ -848,55 +786,42 @@ namespace ts { Substitution, Comments, SourceMaps, - Emit, + Emit } - - export function createPrinter(printerOptions: PrinterOptions = {}, handlers: PrintHandlers = {}): Printer { - const { - hasGlobalName, - onEmitNode = noEmitNotification, - isEmitNotificationEnabled, - substituteNode = noEmitSubstitution, - onBeforeEmitNode, - onAfterEmitNode, - onBeforeEmitNodeArray, - onAfterEmitNodeArray, - onBeforeEmitToken, - onAfterEmitToken - } = handlers; + export function createPrinter(printerOptions: ts.PrinterOptions = {}, handlers: ts.PrintHandlers = {}): ts.Printer { + const { hasGlobalName, onEmitNode = ts.noEmitNotification, isEmitNotificationEnabled, substituteNode = ts.noEmitSubstitution, onBeforeEmitNode, onAfterEmitNode, onBeforeEmitNodeArray, onAfterEmitNodeArray, onBeforeEmitToken, onAfterEmitToken } = handlers; const extendedDiagnostics = !!printerOptions.extendedDiagnostics; - const newLine = getNewLineCharacter(printerOptions); - const moduleKind = getEmitModuleKind(printerOptions); - const bundledHelpers = new Map(); - - let currentSourceFile: SourceFile | undefined; + const newLine = ts.getNewLineCharacter(printerOptions); + const moduleKind = ts.getEmitModuleKind(printerOptions); + const bundledHelpers = new ts.Map(); + let currentSourceFile: ts.SourceFile | undefined; let nodeIdToGeneratedName: string[]; // Map of generated names for specific nodes. let autoGeneratedIdToGeneratedName: string[]; // Map of generated names for temp and loop variables. - let generatedNames: Set; // Set of names generated by the NameGenerator. + let generatedNames: ts.Set; // Set of names generated by the NameGenerator. let tempFlagsStack: TempFlags[]; // Stack of enclosing name generation scopes. let tempFlags: TempFlags; // TempFlags for the current name generation scope. - let reservedNamesStack: Set[]; // Stack of TempFlags reserved in enclosing name generation scopes. - let reservedNames: Set; // TempFlags to reserve in nested name generation scopes. + let reservedNamesStack: ts.Set[]; // Stack of TempFlags reserved in enclosing name generation scopes. + let reservedNames: ts.Set; // TempFlags to reserve in nested name generation scopes. let preserveSourceNewlines = printerOptions.preserveSourceNewlines; // Can be overridden inside nodes with the `IgnoreSourceNewlines` emit flag. let nextListElementPos: number | undefined; // See comment in `getLeadingLineTerminatorCount`. - let writer: EmitTextWriter; - let ownWriter: EmitTextWriter; // Reusable `EmitTextWriter` for basic printing. + let writer: ts.EmitTextWriter; + let ownWriter: ts.EmitTextWriter; // Reusable `EmitTextWriter` for basic printing. let write = writeBase; let isOwnFileEmit: boolean; - const bundleFileInfo = printerOptions.writeBundleFileInfo ? { sections: [] } as BundleFileInfo : undefined; - const relativeToBuildInfo = bundleFileInfo ? Debug.checkDefined(printerOptions.relativeToBuildInfo) : undefined; + const bundleFileInfo = printerOptions.writeBundleFileInfo ? { sections: [] } as ts.BundleFileInfo : undefined; + const relativeToBuildInfo = bundleFileInfo ? ts.Debug.checkDefined(printerOptions.relativeToBuildInfo) : undefined; const recordInternalSection = printerOptions.recordInternalSection; let sourceFileTextPos = 0; - let sourceFileTextKind: BundleFileTextLikeKind = BundleFileSectionKind.Text; + let sourceFileTextKind: ts.BundleFileTextLikeKind = ts.BundleFileSectionKind.Text; // Source Maps let sourceMapsDisabled = true; - let sourceMapGenerator: SourceMapGenerator | undefined; - let sourceMapSource: SourceMapSource; + let sourceMapGenerator: ts.SourceMapGenerator | undefined; + let sourceMapSource: ts.SourceMapSource; let sourceMapSourceIndex = -1; - let mostRecentlyAddedSourceMapSource: SourceMapSource; + let mostRecentlyAddedSourceMapSource: ts.SourceMapSource; let mostRecentlyAddedSourceMapSourceIndex = -1; // Comments @@ -904,14 +829,17 @@ namespace ts { let containerEnd = -1; let declarationListContainerEnd = -1; let currentLineMap: readonly number[] | undefined; - let detachedCommentsInfo: { nodePos: number, detachedCommentEndPos: number }[] | undefined; + let detachedCommentsInfo: { + nodePos: number; + detachedCommentEndPos: number; + }[] | undefined; let hasWrittenComment = false; let commentsDisabled = !!printerOptions.removeComments; - let lastSubstitution: Node | undefined; - let currentParenthesizerRule: ((node: Node) => Node) | undefined; - const { enter: enterComment, exit: exitComment } = performance.createTimerIf(extendedDiagnostics, "commentTime", "beforeComment", "afterComment"); - const parenthesizer = factory.parenthesizer; - const typeArgumentParenthesizerRuleSelector: OrdinalParentheizerRuleSelector = { + let lastSubstitution: ts.Node | undefined; + let currentParenthesizerRule: ((node: ts.Node) => ts.Node) | undefined; + const { enter: enterComment, exit: exitComment } = ts.performance.createTimerIf(extendedDiagnostics, "commentTime", "beforeComment", "afterComment"); + const parenthesizer = ts.factory.parenthesizer; + const typeArgumentParenthesizerRuleSelector: OrdinalParentheizerRuleSelector = { select: index => index === 0 ? parenthesizer.parenthesizeLeadingTypeArgument : undefined }; const emitBinaryExpression = createEmitBinaryExpression(); @@ -932,43 +860,43 @@ namespace ts { bundleFileInfo }; - function printNode(hint: EmitHint, node: Node, sourceFile: SourceFile): string { + function printNode(hint: ts.EmitHint, node: ts.Node, sourceFile: ts.SourceFile): string { switch (hint) { - case EmitHint.SourceFile: - Debug.assert(isSourceFile(node), "Expected a SourceFile node."); + case ts.EmitHint.SourceFile: + ts.Debug.assert(ts.isSourceFile(node), "Expected a SourceFile node."); break; - case EmitHint.IdentifierName: - Debug.assert(isIdentifier(node), "Expected an Identifier node."); + case ts.EmitHint.IdentifierName: + ts.Debug.assert(ts.isIdentifier(node), "Expected an Identifier node."); break; - case EmitHint.Expression: - Debug.assert(isExpression(node), "Expected an Expression node."); + case ts.EmitHint.Expression: + ts.Debug.assert(ts.isExpression(node), "Expected an Expression node."); break; } switch (node.kind) { - case SyntaxKind.SourceFile: return printFile(node as SourceFile); - case SyntaxKind.Bundle: return printBundle(node as Bundle); - case SyntaxKind.UnparsedSource: return printUnparsedSource(node as UnparsedSource); + case ts.SyntaxKind.SourceFile: return printFile(node as ts.SourceFile); + case ts.SyntaxKind.Bundle: return printBundle(node as ts.Bundle); + case ts.SyntaxKind.UnparsedSource: return printUnparsedSource(node as ts.UnparsedSource); } writeNode(hint, node, sourceFile, beginPrint()); return endPrint(); } - function printList(format: ListFormat, nodes: NodeArray, sourceFile: SourceFile) { + function printList(format: ts.ListFormat, nodes: ts.NodeArray, sourceFile: ts.SourceFile) { writeList(format, nodes, sourceFile, beginPrint()); return endPrint(); } - function printBundle(bundle: Bundle): string { + function printBundle(bundle: ts.Bundle): string { writeBundle(bundle, beginPrint(), /*sourceMapEmitter*/ undefined); return endPrint(); } - function printFile(sourceFile: SourceFile): string { + function printFile(sourceFile: ts.SourceFile): string { writeFile(sourceFile, beginPrint(), /*sourceMapEmitter*/ undefined); return endPrint(); } - function printUnparsedSource(unparsed: UnparsedSource): string { + function printUnparsedSource(unparsed: ts.UnparsedSource): string { writeUnparsedSource(unparsed, beginPrint()); return endPrint(); } @@ -976,9 +904,9 @@ namespace ts { /** * If `sourceFile` is `undefined`, `node` must be a synthesized `TypeNode`. */ - function writeNode(hint: EmitHint, node: TypeNode, sourceFile: undefined, output: EmitTextWriter): void; - function writeNode(hint: EmitHint, node: Node, sourceFile: SourceFile, output: EmitTextWriter): void; - function writeNode(hint: EmitHint, node: Node, sourceFile: SourceFile | undefined, output: EmitTextWriter) { + function writeNode(hint: ts.EmitHint, node: ts.TypeNode, sourceFile: undefined, output: ts.EmitTextWriter): void; + function writeNode(hint: ts.EmitHint, node: ts.Node, sourceFile: ts.SourceFile, output: ts.EmitTextWriter): void; + function writeNode(hint: ts.EmitHint, node: ts.Node, sourceFile: ts.SourceFile | undefined, output: ts.EmitTextWriter) { const previousWriter = writer; setWriter(output, /*_sourceMapGenerator*/ undefined); print(hint, node, sourceFile); @@ -986,7 +914,7 @@ namespace ts { writer = previousWriter; } - function writeList(format: ListFormat, nodes: NodeArray, sourceFile: SourceFile | undefined, output: EmitTextWriter) { + function writeList(format: ts.ListFormat, nodes: ts.NodeArray, sourceFile: ts.SourceFile | undefined, output: ts.EmitTextWriter) { const previousWriter = writer; setWriter(output, /*_sourceMapGenerator*/ undefined); if (sourceFile) { @@ -1001,8 +929,8 @@ namespace ts { return writer.getTextPosWithWriteLine ? writer.getTextPosWithWriteLine() : writer.getTextPos(); } - function updateOrPushBundleFileTextLike(pos: number, end: number, kind: BundleFileTextLikeKind) { - const last = lastOrUndefined(bundleFileInfo!.sections); + function updateOrPushBundleFileTextLike(pos: number, end: number, kind: ts.BundleFileTextLikeKind) { + const last = ts.lastOrUndefined(bundleFileInfo!.sections); if (last && last.kind === kind) { last.end = end; } @@ -1011,17 +939,17 @@ namespace ts { } } - function recordBundleFileInternalSectionStart(node: Node) { + function recordBundleFileInternalSectionStart(node: ts.Node) { if (recordInternalSection && bundleFileInfo && currentSourceFile && - (isDeclaration(node) || isVariableStatement(node)) && - isInternalDeclaration(node, currentSourceFile) && - sourceFileTextKind !== BundleFileSectionKind.Internal) { + (ts.isDeclaration(node) || ts.isVariableStatement(node)) && + ts.isInternalDeclaration(node, currentSourceFile) && + sourceFileTextKind !== ts.BundleFileSectionKind.Internal) { const prevSourceFileTextKind = sourceFileTextKind; recordBundleFileTextLikeSection(writer.getTextPos()); sourceFileTextPos = getTextPosWithWriteLine(); - sourceFileTextKind = BundleFileSectionKind.Internal; + sourceFileTextKind = ts.BundleFileSectionKind.Internal; return prevSourceFileTextKind; } return undefined; @@ -1043,7 +971,7 @@ namespace ts { return false; } - function writeBundle(bundle: Bundle, output: EmitTextWriter, sourceMapGenerator: SourceMapGenerator | undefined) { + function writeBundle(bundle: ts.Bundle, output: ts.EmitTextWriter, sourceMapGenerator: ts.SourceMapGenerator | undefined) { isOwnFileEmit = false; const previousWriter = writer; setWriter(output, sourceMapGenerator); @@ -1056,20 +984,22 @@ namespace ts { writeLine(); const pos = writer.getTextPos(); const savedSections = bundleFileInfo && bundleFileInfo.sections; - if (savedSections) bundleFileInfo.sections = []; - print(EmitHint.Unspecified, prepend, /*sourceFile*/ undefined); + if (savedSections) + bundleFileInfo.sections = []; + print(ts.EmitHint.Unspecified, prepend, /*sourceFile*/ undefined); if (bundleFileInfo) { const newSections = bundleFileInfo.sections; bundleFileInfo.sections = savedSections!; - if (prepend.oldFileOfCurrentEmit) bundleFileInfo.sections.push(...newSections); + if (prepend.oldFileOfCurrentEmit) + bundleFileInfo.sections.push(...newSections); else { - newSections.forEach(section => Debug.assert(isBundleFileTextLike(section))); + newSections.forEach(section => ts.Debug.assert(ts.isBundleFileTextLike(section))); bundleFileInfo.sections.push({ pos, end: writer.getTextPos(), - kind: BundleFileSectionKind.Prepend, - data: relativeToBuildInfo!((prepend as UnparsedSource).fileName), - texts: newSections as BundleFileTextLike[] + kind: ts.BundleFileSectionKind.Prepend, + data: relativeToBuildInfo!((prepend as ts.UnparsedSource).fileName), + texts: newSections as ts.BundleFileTextLike[] }); } } @@ -1077,7 +1007,7 @@ namespace ts { sourceFileTextPos = getTextPosWithWriteLine(); for (const sourceFile of bundle.sourceFiles) { - print(EmitHint.SourceFile, sourceFile, sourceFile); + print(ts.EmitHint.SourceFile, sourceFile, sourceFile); } if (bundleFileInfo && bundle.sourceFiles.length) { const end = writer.getTextPos(); @@ -1085,14 +1015,16 @@ namespace ts { // Store prologues const prologues = getPrologueDirectivesFromBundledSourceFiles(bundle); if (prologues) { - if (!bundleFileInfo.sources) bundleFileInfo.sources = {}; + if (!bundleFileInfo.sources) + bundleFileInfo.sources = {}; bundleFileInfo.sources.prologues = prologues; } // Store helpes const helpers = getHelpersFromBundledSourceFiles(bundle); if (helpers) { - if (!bundleFileInfo.sources) bundleFileInfo.sources = {}; + if (!bundleFileInfo.sources) + bundleFileInfo.sources = {}; bundleFileInfo.sources.helpers = helpers; } } @@ -1102,27 +1034,27 @@ namespace ts { writer = previousWriter; } - function writeUnparsedSource(unparsed: UnparsedSource, output: EmitTextWriter) { + function writeUnparsedSource(unparsed: ts.UnparsedSource, output: ts.EmitTextWriter) { const previousWriter = writer; setWriter(output, /*_sourceMapGenerator*/ undefined); - print(EmitHint.Unspecified, unparsed, /*sourceFile*/ undefined); + print(ts.EmitHint.Unspecified, unparsed, /*sourceFile*/ undefined); reset(); writer = previousWriter; } - function writeFile(sourceFile: SourceFile, output: EmitTextWriter, sourceMapGenerator: SourceMapGenerator | undefined) { + function writeFile(sourceFile: ts.SourceFile, output: ts.EmitTextWriter, sourceMapGenerator: ts.SourceMapGenerator | undefined) { isOwnFileEmit = true; const previousWriter = writer; setWriter(output, sourceMapGenerator); emitShebangIfNeeded(sourceFile); emitPrologueDirectivesIfNeeded(sourceFile); - print(EmitHint.SourceFile, sourceFile, sourceFile); + print(ts.EmitHint.SourceFile, sourceFile, sourceFile); reset(); writer = previousWriter; } function beginPrint() { - return ownWriter || (ownWriter = createTextWriter(newLine)); + return ownWriter || (ownWriter = ts.createTextWriter(newLine)); } function endPrint() { @@ -1131,7 +1063,7 @@ namespace ts { return text; } - function print(hint: EmitHint, node: Node, sourceFile: SourceFile | undefined) { + function print(hint: ts.EmitHint, node: ts.Node, sourceFile: ts.SourceFile | undefined) { if (sourceFile) { setSourceFile(sourceFile); } @@ -1139,7 +1071,7 @@ namespace ts { pipelineEmit(hint, node, /*parenthesizerRule*/ undefined); } - function setSourceFile(sourceFile: SourceFile | undefined) { + function setSourceFile(sourceFile: ts.SourceFile | undefined) { currentSourceFile = sourceFile; currentLineMap = undefined; detachedCommentsInfo = undefined; @@ -1148,9 +1080,9 @@ namespace ts { } } - function setWriter(_writer: EmitTextWriter | undefined, _sourceMapGenerator: SourceMapGenerator | undefined) { + function setWriter(_writer: ts.EmitTextWriter | undefined, _sourceMapGenerator: ts.SourceMapGenerator | undefined) { if (_writer && printerOptions.omitTrailingSemicolon) { - _writer = getTrailingSemicolonDeferringWriter(_writer); + _writer = ts.getTrailingSemicolonDeferringWriter(_writer); } writer = _writer!; // TODO: GH#18217 @@ -1161,7 +1093,7 @@ namespace ts { function reset() { nodeIdToGeneratedName = []; autoGeneratedIdToGeneratedName = []; - generatedNames = new Set(); + generatedNames = new ts.Set(); tempFlagsStack = []; tempFlags = TempFlags.Auto; reservedNamesStack = []; @@ -1172,38 +1104,38 @@ namespace ts { } function getCurrentLineMap() { - return currentLineMap || (currentLineMap = getLineStarts(Debug.checkDefined(currentSourceFile))); + return currentLineMap || (currentLineMap = ts.getLineStarts(ts.Debug.checkDefined(currentSourceFile))); } - function emit(node: Node, parenthesizerRule?: (node: Node) => Node): void; - function emit(node: Node | undefined, parenthesizerRule?: (node: Node) => Node): void; - function emit(node: Node | undefined, parenthesizerRule?: (node: Node) => Node) { - if (node === undefined) return; + function emit(node: ts.Node, parenthesizerRule?: (node: ts.Node) => ts.Node): void; + function emit(node: ts.Node | undefined, parenthesizerRule?: (node: ts.Node) => ts.Node): void; + function emit(node: ts.Node | undefined, parenthesizerRule?: (node: ts.Node) => ts.Node) { + if (node === undefined) + return; const prevSourceFileTextKind = recordBundleFileInternalSectionStart(node); - pipelineEmit(EmitHint.Unspecified, node, parenthesizerRule); + pipelineEmit(ts.EmitHint.Unspecified, node, parenthesizerRule); recordBundleFileInternalSectionEnd(prevSourceFileTextKind); } - function emitIdentifierName(node: Identifier): void; - function emitIdentifierName(node: Identifier | undefined): void; - function emitIdentifierName(node: Identifier | undefined) { - if (node === undefined) return; - pipelineEmit(EmitHint.IdentifierName, node, /*parenthesizerRule*/ undefined); + function emitIdentifierName(node: ts.Identifier): void; + function emitIdentifierName(node: ts.Identifier | undefined): void; + function emitIdentifierName(node: ts.Identifier | undefined) { + if (node === undefined) + return; + pipelineEmit(ts.EmitHint.IdentifierName, node, /*parenthesizerRule*/ undefined); } - - function emitExpression(node: Expression, parenthesizerRule?: (node: Expression) => Expression): void; - function emitExpression(node: Expression | undefined, parenthesizerRule?: (node: Expression) => Expression): void; - function emitExpression(node: Expression | undefined, parenthesizerRule?: (node: Expression) => Expression) { - if (node === undefined) return; - pipelineEmit(EmitHint.Expression, node, parenthesizerRule); + function emitExpression(node: ts.Expression, parenthesizerRule?: (node: ts.Expression) => ts.Expression): void; + function emitExpression(node: ts.Expression | undefined, parenthesizerRule?: (node: ts.Expression) => ts.Expression): void; + function emitExpression(node: ts.Expression | undefined, parenthesizerRule?: (node: ts.Expression) => ts.Expression) { + if (node === undefined) + return; + pipelineEmit(ts.EmitHint.Expression, node, parenthesizerRule); } - - function emitJsxAttributeValue(node: StringLiteral | JsxExpression): void { - pipelineEmit(isStringLiteral(node) ? EmitHint.JsxAttributeValue : EmitHint.Unspecified, node); + function emitJsxAttributeValue(node: ts.StringLiteral | ts.JsxExpression): void { + pipelineEmit(ts.isStringLiteral(node) ? ts.EmitHint.JsxAttributeValue : ts.EmitHint.Unspecified, node); } - - function beforeEmitNode(node: Node) { - if (preserveSourceNewlines && (getEmitFlags(node) & EmitFlags.IgnoreSourceNewlines)) { + function beforeEmitNode(node: ts.Node) { + if (preserveSourceNewlines && (ts.getEmitFlags(node) & ts.EmitFlags.IgnoreSourceNewlines)) { preserveSourceNewlines = false; } } @@ -1212,34 +1144,34 @@ namespace ts { preserveSourceNewlines = savedPreserveSourceNewlines; } - function pipelineEmit(emitHint: EmitHint, node: Node, parenthesizerRule?: (node: Node) => Node) { + function pipelineEmit(emitHint: ts.EmitHint, node: ts.Node, parenthesizerRule?: (node: ts.Node) => ts.Node) { currentParenthesizerRule = parenthesizerRule; const pipelinePhase = getPipelinePhase(PipelinePhase.Notification, emitHint, node); pipelinePhase(emitHint, node); currentParenthesizerRule = undefined; } - function shouldEmitComments(node: Node) { - return !commentsDisabled && !isSourceFile(node); + function shouldEmitComments(node: ts.Node) { + return !commentsDisabled && !ts.isSourceFile(node); } - function shouldEmitSourceMaps(node: Node) { + function shouldEmitSourceMaps(node: ts.Node) { return !sourceMapsDisabled && - !isSourceFile(node) && - !isInJsonFile(node) && - !isUnparsedSource(node) && - !isUnparsedPrepend(node); + !ts.isSourceFile(node) && + !ts.isInJsonFile(node) && + !ts.isUnparsedSource(node) && + !ts.isUnparsedPrepend(node); } - function getPipelinePhase(phase: PipelinePhase, emitHint: EmitHint, node: Node) { + function getPipelinePhase(phase: PipelinePhase, emitHint: ts.EmitHint, node: ts.Node) { switch (phase) { case PipelinePhase.Notification: - if (onEmitNode !== noEmitNotification && (!isEmitNotificationEnabled || isEmitNotificationEnabled(node))) { + if (onEmitNode !== ts.noEmitNotification && (!isEmitNotificationEnabled || isEmitNotificationEnabled(node))) { return pipelineEmitWithNotification; } // falls through case PipelinePhase.Substitution: - if (substituteNode !== noEmitSubstitution && (lastSubstitution = substituteNode(emitHint, node) || node) !== node) { + if (substituteNode !== ts.noEmitSubstitution && (lastSubstitution = substituteNode(emitHint, node) || node) !== node) { if (currentParenthesizerRule) { lastSubstitution = currentParenthesizerRule(lastSubstitution); } @@ -1259,20 +1191,20 @@ namespace ts { case PipelinePhase.Emit: return pipelineEmitWithHint; default: - return Debug.assertNever(phase); + return ts.Debug.assertNever(phase); } } - function getNextPipelinePhase(currentPhase: PipelinePhase, emitHint: EmitHint, node: Node) { + function getNextPipelinePhase(currentPhase: PipelinePhase, emitHint: ts.EmitHint, node: ts.Node) { return getPipelinePhase(currentPhase + 1, emitHint, node); } - function pipelineEmitWithNotification(hint: EmitHint, node: Node) { + function pipelineEmitWithNotification(hint: ts.EmitHint, node: ts.Node) { const pipelinePhase = getNextPipelinePhase(PipelinePhase.Notification, hint, node); onEmitNode(hint, node, pipelinePhase); } - function pipelineEmitWithHint(hint: EmitHint, node: Node): void { + function pipelineEmitWithHint(hint: ts.EmitHint, node: ts.Node): void { onBeforeEmitNode?.(node); if (preserveSourceNewlines) { const savedPreserveSourceNewlines = preserveSourceNewlines; @@ -1288,369 +1220,373 @@ namespace ts { currentParenthesizerRule = undefined; } - function pipelineEmitWithHintWorker(hint: EmitHint, node: Node, allowSnippets = true): void { + function pipelineEmitWithHintWorker(hint: ts.EmitHint, node: ts.Node, allowSnippets = true): void { if (allowSnippets) { - const snippet = getSnippetElement(node); + const snippet = ts.getSnippetElement(node); if (snippet) { return emitSnippetNode(hint, node, snippet); } } - if (hint === EmitHint.SourceFile) return emitSourceFile(cast(node, isSourceFile)); - if (hint === EmitHint.IdentifierName) return emitIdentifier(cast(node, isIdentifier)); - if (hint === EmitHint.JsxAttributeValue) return emitLiteral(cast(node, isStringLiteral), /*jsxAttributeEscape*/ true); - if (hint === EmitHint.MappedTypeParameter) return emitMappedTypeParameter(cast(node, isTypeParameterDeclaration)); - if (hint === EmitHint.EmbeddedStatement) { - Debug.assertNode(node, isEmptyStatement); + if (hint === ts.EmitHint.SourceFile) + return emitSourceFile(ts.cast(node, ts.isSourceFile)); + if (hint === ts.EmitHint.IdentifierName) + return emitIdentifier(ts.cast(node, ts.isIdentifier)); + if (hint === ts.EmitHint.JsxAttributeValue) + return emitLiteral(ts.cast(node, ts.isStringLiteral), /*jsxAttributeEscape*/ true); + if (hint === ts.EmitHint.MappedTypeParameter) + return emitMappedTypeParameter(ts.cast(node, ts.isTypeParameterDeclaration)); + if (hint === ts.EmitHint.EmbeddedStatement) { + ts.Debug.assertNode(node, ts.isEmptyStatement); return emitEmptyStatement(/*isEmbeddedStatement*/ true); } - if (hint === EmitHint.Unspecified) { + if (hint === ts.EmitHint.Unspecified) { switch (node.kind) { // Pseudo-literals - case SyntaxKind.TemplateHead: - case SyntaxKind.TemplateMiddle: - case SyntaxKind.TemplateTail: - return emitLiteral(node as LiteralExpression, /*jsxAttributeEscape*/ false); + case ts.SyntaxKind.TemplateHead: + case ts.SyntaxKind.TemplateMiddle: + case ts.SyntaxKind.TemplateTail: + return emitLiteral(node as ts.LiteralExpression, /*jsxAttributeEscape*/ false); // Identifiers - case SyntaxKind.Identifier: - return emitIdentifier(node as Identifier); + case ts.SyntaxKind.Identifier: + return emitIdentifier(node as ts.Identifier); // PrivateIdentifiers - case SyntaxKind.PrivateIdentifier: - return emitPrivateIdentifier(node as PrivateIdentifier); + case ts.SyntaxKind.PrivateIdentifier: + return emitPrivateIdentifier(node as ts.PrivateIdentifier); // Parse tree nodes // Names - case SyntaxKind.QualifiedName: - return emitQualifiedName(node as QualifiedName); - case SyntaxKind.ComputedPropertyName: - return emitComputedPropertyName(node as ComputedPropertyName); + case ts.SyntaxKind.QualifiedName: + return emitQualifiedName(node as ts.QualifiedName); + case ts.SyntaxKind.ComputedPropertyName: + return emitComputedPropertyName(node as ts.ComputedPropertyName); // Signature elements - case SyntaxKind.TypeParameter: - return emitTypeParameter(node as TypeParameterDeclaration); - case SyntaxKind.Parameter: - return emitParameter(node as ParameterDeclaration); - case SyntaxKind.Decorator: - return emitDecorator(node as Decorator); + case ts.SyntaxKind.TypeParameter: + return emitTypeParameter(node as ts.TypeParameterDeclaration); + case ts.SyntaxKind.Parameter: + return emitParameter(node as ts.ParameterDeclaration); + case ts.SyntaxKind.Decorator: + return emitDecorator(node as ts.Decorator); // Type members - case SyntaxKind.PropertySignature: - return emitPropertySignature(node as PropertySignature); - case SyntaxKind.PropertyDeclaration: - return emitPropertyDeclaration(node as PropertyDeclaration); - case SyntaxKind.MethodSignature: - return emitMethodSignature(node as MethodSignature); - case SyntaxKind.MethodDeclaration: - return emitMethodDeclaration(node as MethodDeclaration); - case SyntaxKind.ClassStaticBlockDeclaration: - return emitClassStaticBlockDeclaration(node as ClassStaticBlockDeclaration); - case SyntaxKind.Constructor: - return emitConstructor(node as ConstructorDeclaration); - case SyntaxKind.GetAccessor: - case SyntaxKind.SetAccessor: - return emitAccessorDeclaration(node as AccessorDeclaration); - case SyntaxKind.CallSignature: - return emitCallSignature(node as CallSignatureDeclaration); - case SyntaxKind.ConstructSignature: - return emitConstructSignature(node as ConstructSignatureDeclaration); - case SyntaxKind.IndexSignature: - return emitIndexSignature(node as IndexSignatureDeclaration); + case ts.SyntaxKind.PropertySignature: + return emitPropertySignature(node as ts.PropertySignature); + case ts.SyntaxKind.PropertyDeclaration: + return emitPropertyDeclaration(node as ts.PropertyDeclaration); + case ts.SyntaxKind.MethodSignature: + return emitMethodSignature(node as ts.MethodSignature); + case ts.SyntaxKind.MethodDeclaration: + return emitMethodDeclaration(node as ts.MethodDeclaration); + case ts.SyntaxKind.ClassStaticBlockDeclaration: + return emitClassStaticBlockDeclaration(node as ts.ClassStaticBlockDeclaration); + case ts.SyntaxKind.Constructor: + return emitConstructor(node as ts.ConstructorDeclaration); + case ts.SyntaxKind.GetAccessor: + case ts.SyntaxKind.SetAccessor: + return emitAccessorDeclaration(node as ts.AccessorDeclaration); + case ts.SyntaxKind.CallSignature: + return emitCallSignature(node as ts.CallSignatureDeclaration); + case ts.SyntaxKind.ConstructSignature: + return emitConstructSignature(node as ts.ConstructSignatureDeclaration); + case ts.SyntaxKind.IndexSignature: + return emitIndexSignature(node as ts.IndexSignatureDeclaration); // Types - case SyntaxKind.TypePredicate: - return emitTypePredicate(node as TypePredicateNode); - case SyntaxKind.TypeReference: - return emitTypeReference(node as TypeReferenceNode); - case SyntaxKind.FunctionType: - return emitFunctionType(node as FunctionTypeNode); - case SyntaxKind.ConstructorType: - return emitConstructorType(node as ConstructorTypeNode); - case SyntaxKind.TypeQuery: - return emitTypeQuery(node as TypeQueryNode); - case SyntaxKind.TypeLiteral: - return emitTypeLiteral(node as TypeLiteralNode); - case SyntaxKind.ArrayType: - return emitArrayType(node as ArrayTypeNode); - case SyntaxKind.TupleType: - return emitTupleType(node as TupleTypeNode); - case SyntaxKind.OptionalType: - return emitOptionalType(node as OptionalTypeNode); + case ts.SyntaxKind.TypePredicate: + return emitTypePredicate(node as ts.TypePredicateNode); + case ts.SyntaxKind.TypeReference: + return emitTypeReference(node as ts.TypeReferenceNode); + case ts.SyntaxKind.FunctionType: + return emitFunctionType(node as ts.FunctionTypeNode); + case ts.SyntaxKind.ConstructorType: + return emitConstructorType(node as ts.ConstructorTypeNode); + case ts.SyntaxKind.TypeQuery: + return emitTypeQuery(node as ts.TypeQueryNode); + case ts.SyntaxKind.TypeLiteral: + return emitTypeLiteral(node as ts.TypeLiteralNode); + case ts.SyntaxKind.ArrayType: + return emitArrayType(node as ts.ArrayTypeNode); + case ts.SyntaxKind.TupleType: + return emitTupleType(node as ts.TupleTypeNode); + case ts.SyntaxKind.OptionalType: + return emitOptionalType(node as ts.OptionalTypeNode); // SyntaxKind.RestType is handled below - case SyntaxKind.UnionType: - return emitUnionType(node as UnionTypeNode); - case SyntaxKind.IntersectionType: - return emitIntersectionType(node as IntersectionTypeNode); - case SyntaxKind.ConditionalType: - return emitConditionalType(node as ConditionalTypeNode); - case SyntaxKind.InferType: - return emitInferType(node as InferTypeNode); - case SyntaxKind.ParenthesizedType: - return emitParenthesizedType(node as ParenthesizedTypeNode); - case SyntaxKind.ExpressionWithTypeArguments: - return emitExpressionWithTypeArguments(node as ExpressionWithTypeArguments); - case SyntaxKind.ThisType: + case ts.SyntaxKind.UnionType: + return emitUnionType(node as ts.UnionTypeNode); + case ts.SyntaxKind.IntersectionType: + return emitIntersectionType(node as ts.IntersectionTypeNode); + case ts.SyntaxKind.ConditionalType: + return emitConditionalType(node as ts.ConditionalTypeNode); + case ts.SyntaxKind.InferType: + return emitInferType(node as ts.InferTypeNode); + case ts.SyntaxKind.ParenthesizedType: + return emitParenthesizedType(node as ts.ParenthesizedTypeNode); + case ts.SyntaxKind.ExpressionWithTypeArguments: + return emitExpressionWithTypeArguments(node as ts.ExpressionWithTypeArguments); + case ts.SyntaxKind.ThisType: return emitThisType(); - case SyntaxKind.TypeOperator: - return emitTypeOperator(node as TypeOperatorNode); - case SyntaxKind.IndexedAccessType: - return emitIndexedAccessType(node as IndexedAccessTypeNode); - case SyntaxKind.MappedType: - return emitMappedType(node as MappedTypeNode); - case SyntaxKind.LiteralType: - return emitLiteralType(node as LiteralTypeNode); - case SyntaxKind.NamedTupleMember: - return emitNamedTupleMember(node as NamedTupleMember); - case SyntaxKind.TemplateLiteralType: - return emitTemplateType(node as TemplateLiteralTypeNode); - case SyntaxKind.TemplateLiteralTypeSpan: - return emitTemplateTypeSpan(node as TemplateLiteralTypeSpan); - case SyntaxKind.ImportType: - return emitImportTypeNode(node as ImportTypeNode); + case ts.SyntaxKind.TypeOperator: + return emitTypeOperator(node as ts.TypeOperatorNode); + case ts.SyntaxKind.IndexedAccessType: + return emitIndexedAccessType(node as ts.IndexedAccessTypeNode); + case ts.SyntaxKind.MappedType: + return emitMappedType(node as ts.MappedTypeNode); + case ts.SyntaxKind.LiteralType: + return emitLiteralType(node as ts.LiteralTypeNode); + case ts.SyntaxKind.NamedTupleMember: + return emitNamedTupleMember(node as ts.NamedTupleMember); + case ts.SyntaxKind.TemplateLiteralType: + return emitTemplateType(node as ts.TemplateLiteralTypeNode); + case ts.SyntaxKind.TemplateLiteralTypeSpan: + return emitTemplateTypeSpan(node as ts.TemplateLiteralTypeSpan); + case ts.SyntaxKind.ImportType: + return emitImportTypeNode(node as ts.ImportTypeNode); // Binding patterns - case SyntaxKind.ObjectBindingPattern: - return emitObjectBindingPattern(node as ObjectBindingPattern); - case SyntaxKind.ArrayBindingPattern: - return emitArrayBindingPattern(node as ArrayBindingPattern); - case SyntaxKind.BindingElement: - return emitBindingElement(node as BindingElement); + case ts.SyntaxKind.ObjectBindingPattern: + return emitObjectBindingPattern(node as ts.ObjectBindingPattern); + case ts.SyntaxKind.ArrayBindingPattern: + return emitArrayBindingPattern(node as ts.ArrayBindingPattern); + case ts.SyntaxKind.BindingElement: + return emitBindingElement(node as ts.BindingElement); // Misc - case SyntaxKind.TemplateSpan: - return emitTemplateSpan(node as TemplateSpan); - case SyntaxKind.SemicolonClassElement: + case ts.SyntaxKind.TemplateSpan: + return emitTemplateSpan(node as ts.TemplateSpan); + case ts.SyntaxKind.SemicolonClassElement: return emitSemicolonClassElement(); // Statements - case SyntaxKind.Block: - return emitBlock(node as Block); - case SyntaxKind.VariableStatement: - return emitVariableStatement(node as VariableStatement); - case SyntaxKind.EmptyStatement: + case ts.SyntaxKind.Block: + return emitBlock(node as ts.Block); + case ts.SyntaxKind.VariableStatement: + return emitVariableStatement(node as ts.VariableStatement); + case ts.SyntaxKind.EmptyStatement: return emitEmptyStatement(/*isEmbeddedStatement*/ false); - case SyntaxKind.ExpressionStatement: - return emitExpressionStatement(node as ExpressionStatement); - case SyntaxKind.IfStatement: - return emitIfStatement(node as IfStatement); - case SyntaxKind.DoStatement: - return emitDoStatement(node as DoStatement); - case SyntaxKind.WhileStatement: - return emitWhileStatement(node as WhileStatement); - case SyntaxKind.ForStatement: - return emitForStatement(node as ForStatement); - case SyntaxKind.ForInStatement: - return emitForInStatement(node as ForInStatement); - case SyntaxKind.ForOfStatement: - return emitForOfStatement(node as ForOfStatement); - case SyntaxKind.ContinueStatement: - return emitContinueStatement(node as ContinueStatement); - case SyntaxKind.BreakStatement: - return emitBreakStatement(node as BreakStatement); - case SyntaxKind.ReturnStatement: - return emitReturnStatement(node as ReturnStatement); - case SyntaxKind.WithStatement: - return emitWithStatement(node as WithStatement); - case SyntaxKind.SwitchStatement: - return emitSwitchStatement(node as SwitchStatement); - case SyntaxKind.LabeledStatement: - return emitLabeledStatement(node as LabeledStatement); - case SyntaxKind.ThrowStatement: - return emitThrowStatement(node as ThrowStatement); - case SyntaxKind.TryStatement: - return emitTryStatement(node as TryStatement); - case SyntaxKind.DebuggerStatement: - return emitDebuggerStatement(node as DebuggerStatement); + case ts.SyntaxKind.ExpressionStatement: + return emitExpressionStatement(node as ts.ExpressionStatement); + case ts.SyntaxKind.IfStatement: + return emitIfStatement(node as ts.IfStatement); + case ts.SyntaxKind.DoStatement: + return emitDoStatement(node as ts.DoStatement); + case ts.SyntaxKind.WhileStatement: + return emitWhileStatement(node as ts.WhileStatement); + case ts.SyntaxKind.ForStatement: + return emitForStatement(node as ts.ForStatement); + case ts.SyntaxKind.ForInStatement: + return emitForInStatement(node as ts.ForInStatement); + case ts.SyntaxKind.ForOfStatement: + return emitForOfStatement(node as ts.ForOfStatement); + case ts.SyntaxKind.ContinueStatement: + return emitContinueStatement(node as ts.ContinueStatement); + case ts.SyntaxKind.BreakStatement: + return emitBreakStatement(node as ts.BreakStatement); + case ts.SyntaxKind.ReturnStatement: + return emitReturnStatement(node as ts.ReturnStatement); + case ts.SyntaxKind.WithStatement: + return emitWithStatement(node as ts.WithStatement); + case ts.SyntaxKind.SwitchStatement: + return emitSwitchStatement(node as ts.SwitchStatement); + case ts.SyntaxKind.LabeledStatement: + return emitLabeledStatement(node as ts.LabeledStatement); + case ts.SyntaxKind.ThrowStatement: + return emitThrowStatement(node as ts.ThrowStatement); + case ts.SyntaxKind.TryStatement: + return emitTryStatement(node as ts.TryStatement); + case ts.SyntaxKind.DebuggerStatement: + return emitDebuggerStatement(node as ts.DebuggerStatement); // Declarations - case SyntaxKind.VariableDeclaration: - return emitVariableDeclaration(node as VariableDeclaration); - case SyntaxKind.VariableDeclarationList: - return emitVariableDeclarationList(node as VariableDeclarationList); - case SyntaxKind.FunctionDeclaration: - return emitFunctionDeclaration(node as FunctionDeclaration); - case SyntaxKind.ClassDeclaration: - return emitClassDeclaration(node as ClassDeclaration); - case SyntaxKind.InterfaceDeclaration: - return emitInterfaceDeclaration(node as InterfaceDeclaration); - case SyntaxKind.TypeAliasDeclaration: - return emitTypeAliasDeclaration(node as TypeAliasDeclaration); - case SyntaxKind.EnumDeclaration: - return emitEnumDeclaration(node as EnumDeclaration); - case SyntaxKind.ModuleDeclaration: - return emitModuleDeclaration(node as ModuleDeclaration); - case SyntaxKind.ModuleBlock: - return emitModuleBlock(node as ModuleBlock); - case SyntaxKind.CaseBlock: - return emitCaseBlock(node as CaseBlock); - case SyntaxKind.NamespaceExportDeclaration: - return emitNamespaceExportDeclaration(node as NamespaceExportDeclaration); - case SyntaxKind.ImportEqualsDeclaration: - return emitImportEqualsDeclaration(node as ImportEqualsDeclaration); - case SyntaxKind.ImportDeclaration: - return emitImportDeclaration(node as ImportDeclaration); - case SyntaxKind.ImportClause: - return emitImportClause(node as ImportClause); - case SyntaxKind.NamespaceImport: - return emitNamespaceImport(node as NamespaceImport); - case SyntaxKind.NamespaceExport: - return emitNamespaceExport(node as NamespaceExport); - case SyntaxKind.NamedImports: - return emitNamedImports(node as NamedImports); - case SyntaxKind.ImportSpecifier: - return emitImportSpecifier(node as ImportSpecifier); - case SyntaxKind.ExportAssignment: - return emitExportAssignment(node as ExportAssignment); - case SyntaxKind.ExportDeclaration: - return emitExportDeclaration(node as ExportDeclaration); - case SyntaxKind.NamedExports: - return emitNamedExports(node as NamedExports); - case SyntaxKind.ExportSpecifier: - return emitExportSpecifier(node as ExportSpecifier); - case SyntaxKind.AssertClause: - return emitAssertClause(node as AssertClause); - case SyntaxKind.AssertEntry: - return emitAssertEntry(node as AssertEntry); - case SyntaxKind.MissingDeclaration: + case ts.SyntaxKind.VariableDeclaration: + return emitVariableDeclaration(node as ts.VariableDeclaration); + case ts.SyntaxKind.VariableDeclarationList: + return emitVariableDeclarationList(node as ts.VariableDeclarationList); + case ts.SyntaxKind.FunctionDeclaration: + return emitFunctionDeclaration(node as ts.FunctionDeclaration); + case ts.SyntaxKind.ClassDeclaration: + return emitClassDeclaration(node as ts.ClassDeclaration); + case ts.SyntaxKind.InterfaceDeclaration: + return emitInterfaceDeclaration(node as ts.InterfaceDeclaration); + case ts.SyntaxKind.TypeAliasDeclaration: + return emitTypeAliasDeclaration(node as ts.TypeAliasDeclaration); + case ts.SyntaxKind.EnumDeclaration: + return emitEnumDeclaration(node as ts.EnumDeclaration); + case ts.SyntaxKind.ModuleDeclaration: + return emitModuleDeclaration(node as ts.ModuleDeclaration); + case ts.SyntaxKind.ModuleBlock: + return emitModuleBlock(node as ts.ModuleBlock); + case ts.SyntaxKind.CaseBlock: + return emitCaseBlock(node as ts.CaseBlock); + case ts.SyntaxKind.NamespaceExportDeclaration: + return emitNamespaceExportDeclaration(node as ts.NamespaceExportDeclaration); + case ts.SyntaxKind.ImportEqualsDeclaration: + return emitImportEqualsDeclaration(node as ts.ImportEqualsDeclaration); + case ts.SyntaxKind.ImportDeclaration: + return emitImportDeclaration(node as ts.ImportDeclaration); + case ts.SyntaxKind.ImportClause: + return emitImportClause(node as ts.ImportClause); + case ts.SyntaxKind.NamespaceImport: + return emitNamespaceImport(node as ts.NamespaceImport); + case ts.SyntaxKind.NamespaceExport: + return emitNamespaceExport(node as ts.NamespaceExport); + case ts.SyntaxKind.NamedImports: + return emitNamedImports(node as ts.NamedImports); + case ts.SyntaxKind.ImportSpecifier: + return emitImportSpecifier(node as ts.ImportSpecifier); + case ts.SyntaxKind.ExportAssignment: + return emitExportAssignment(node as ts.ExportAssignment); + case ts.SyntaxKind.ExportDeclaration: + return emitExportDeclaration(node as ts.ExportDeclaration); + case ts.SyntaxKind.NamedExports: + return emitNamedExports(node as ts.NamedExports); + case ts.SyntaxKind.ExportSpecifier: + return emitExportSpecifier(node as ts.ExportSpecifier); + case ts.SyntaxKind.AssertClause: + return emitAssertClause(node as ts.AssertClause); + case ts.SyntaxKind.AssertEntry: + return emitAssertEntry(node as ts.AssertEntry); + case ts.SyntaxKind.MissingDeclaration: return; // Module references - case SyntaxKind.ExternalModuleReference: - return emitExternalModuleReference(node as ExternalModuleReference); + case ts.SyntaxKind.ExternalModuleReference: + return emitExternalModuleReference(node as ts.ExternalModuleReference); // JSX (non-expression) - case SyntaxKind.JsxText: - return emitJsxText(node as JsxText); - case SyntaxKind.JsxOpeningElement: - case SyntaxKind.JsxOpeningFragment: - return emitJsxOpeningElementOrFragment(node as JsxOpeningElement); - case SyntaxKind.JsxClosingElement: - case SyntaxKind.JsxClosingFragment: - return emitJsxClosingElementOrFragment(node as JsxClosingElement); - case SyntaxKind.JsxAttribute: - return emitJsxAttribute(node as JsxAttribute); - case SyntaxKind.JsxAttributes: - return emitJsxAttributes(node as JsxAttributes); - case SyntaxKind.JsxSpreadAttribute: - return emitJsxSpreadAttribute(node as JsxSpreadAttribute); - case SyntaxKind.JsxExpression: - return emitJsxExpression(node as JsxExpression); + case ts.SyntaxKind.JsxText: + return emitJsxText(node as ts.JsxText); + case ts.SyntaxKind.JsxOpeningElement: + case ts.SyntaxKind.JsxOpeningFragment: + return emitJsxOpeningElementOrFragment(node as ts.JsxOpeningElement); + case ts.SyntaxKind.JsxClosingElement: + case ts.SyntaxKind.JsxClosingFragment: + return emitJsxClosingElementOrFragment(node as ts.JsxClosingElement); + case ts.SyntaxKind.JsxAttribute: + return emitJsxAttribute(node as ts.JsxAttribute); + case ts.SyntaxKind.JsxAttributes: + return emitJsxAttributes(node as ts.JsxAttributes); + case ts.SyntaxKind.JsxSpreadAttribute: + return emitJsxSpreadAttribute(node as ts.JsxSpreadAttribute); + case ts.SyntaxKind.JsxExpression: + return emitJsxExpression(node as ts.JsxExpression); // Clauses - case SyntaxKind.CaseClause: - return emitCaseClause(node as CaseClause); - case SyntaxKind.DefaultClause: - return emitDefaultClause(node as DefaultClause); - case SyntaxKind.HeritageClause: - return emitHeritageClause(node as HeritageClause); - case SyntaxKind.CatchClause: - return emitCatchClause(node as CatchClause); + case ts.SyntaxKind.CaseClause: + return emitCaseClause(node as ts.CaseClause); + case ts.SyntaxKind.DefaultClause: + return emitDefaultClause(node as ts.DefaultClause); + case ts.SyntaxKind.HeritageClause: + return emitHeritageClause(node as ts.HeritageClause); + case ts.SyntaxKind.CatchClause: + return emitCatchClause(node as ts.CatchClause); // Property assignments - case SyntaxKind.PropertyAssignment: - return emitPropertyAssignment(node as PropertyAssignment); - case SyntaxKind.ShorthandPropertyAssignment: - return emitShorthandPropertyAssignment(node as ShorthandPropertyAssignment); - case SyntaxKind.SpreadAssignment: - return emitSpreadAssignment(node as SpreadAssignment); + case ts.SyntaxKind.PropertyAssignment: + return emitPropertyAssignment(node as ts.PropertyAssignment); + case ts.SyntaxKind.ShorthandPropertyAssignment: + return emitShorthandPropertyAssignment(node as ts.ShorthandPropertyAssignment); + case ts.SyntaxKind.SpreadAssignment: + return emitSpreadAssignment(node as ts.SpreadAssignment); // Enum - case SyntaxKind.EnumMember: - return emitEnumMember(node as EnumMember); + case ts.SyntaxKind.EnumMember: + return emitEnumMember(node as ts.EnumMember); // Unparsed - case SyntaxKind.UnparsedPrologue: - return writeUnparsedNode(node as UnparsedNode); - case SyntaxKind.UnparsedSource: - case SyntaxKind.UnparsedPrepend: - return emitUnparsedSourceOrPrepend(node as UnparsedSource); - case SyntaxKind.UnparsedText: - case SyntaxKind.UnparsedInternalText: - return emitUnparsedTextLike(node as UnparsedTextLike); - case SyntaxKind.UnparsedSyntheticReference: - return emitUnparsedSyntheticReference(node as UnparsedSyntheticReference); + case ts.SyntaxKind.UnparsedPrologue: + return writeUnparsedNode(node as ts.UnparsedNode); + case ts.SyntaxKind.UnparsedSource: + case ts.SyntaxKind.UnparsedPrepend: + return emitUnparsedSourceOrPrepend(node as ts.UnparsedSource); + case ts.SyntaxKind.UnparsedText: + case ts.SyntaxKind.UnparsedInternalText: + return emitUnparsedTextLike(node as ts.UnparsedTextLike); + case ts.SyntaxKind.UnparsedSyntheticReference: + return emitUnparsedSyntheticReference(node as ts.UnparsedSyntheticReference); // Top-level nodes - case SyntaxKind.SourceFile: - return emitSourceFile(node as SourceFile); - case SyntaxKind.Bundle: - return Debug.fail("Bundles should be printed using printBundle"); + case ts.SyntaxKind.SourceFile: + return emitSourceFile(node as ts.SourceFile); + case ts.SyntaxKind.Bundle: + return ts.Debug.fail("Bundles should be printed using printBundle"); // SyntaxKind.UnparsedSource (handled above) - case SyntaxKind.InputFiles: - return Debug.fail("InputFiles should not be printed"); + case ts.SyntaxKind.InputFiles: + return ts.Debug.fail("InputFiles should not be printed"); // JSDoc nodes (only used in codefixes currently) - case SyntaxKind.JSDocTypeExpression: - return emitJSDocTypeExpression(node as JSDocTypeExpression); - case SyntaxKind.JSDocNameReference: - return emitJSDocNameReference(node as JSDocNameReference); - case SyntaxKind.JSDocAllType: + case ts.SyntaxKind.JSDocTypeExpression: + return emitJSDocTypeExpression(node as ts.JSDocTypeExpression); + case ts.SyntaxKind.JSDocNameReference: + return emitJSDocNameReference(node as ts.JSDocNameReference); + case ts.SyntaxKind.JSDocAllType: return writePunctuation("*"); - case SyntaxKind.JSDocUnknownType: + case ts.SyntaxKind.JSDocUnknownType: return writePunctuation("?"); - case SyntaxKind.JSDocNullableType: - return emitJSDocNullableType(node as JSDocNullableType); - case SyntaxKind.JSDocNonNullableType: - return emitJSDocNonNullableType(node as JSDocNonNullableType); - case SyntaxKind.JSDocOptionalType: - return emitJSDocOptionalType(node as JSDocOptionalType); - case SyntaxKind.JSDocFunctionType: - return emitJSDocFunctionType(node as JSDocFunctionType); - case SyntaxKind.RestType: - case SyntaxKind.JSDocVariadicType: - return emitRestOrJSDocVariadicType(node as RestTypeNode | JSDocVariadicType); - case SyntaxKind.JSDocNamepathType: + case ts.SyntaxKind.JSDocNullableType: + return emitJSDocNullableType(node as ts.JSDocNullableType); + case ts.SyntaxKind.JSDocNonNullableType: + return emitJSDocNonNullableType(node as ts.JSDocNonNullableType); + case ts.SyntaxKind.JSDocOptionalType: + return emitJSDocOptionalType(node as ts.JSDocOptionalType); + case ts.SyntaxKind.JSDocFunctionType: + return emitJSDocFunctionType(node as ts.JSDocFunctionType); + case ts.SyntaxKind.RestType: + case ts.SyntaxKind.JSDocVariadicType: + return emitRestOrJSDocVariadicType(node as ts.RestTypeNode | ts.JSDocVariadicType); + case ts.SyntaxKind.JSDocNamepathType: return; - case SyntaxKind.JSDoc: - return emitJSDoc(node as JSDoc); - case SyntaxKind.JSDocTypeLiteral: - return emitJSDocTypeLiteral(node as JSDocTypeLiteral); - case SyntaxKind.JSDocSignature: - return emitJSDocSignature(node as JSDocSignature); - case SyntaxKind.JSDocTag: - case SyntaxKind.JSDocClassTag: - case SyntaxKind.JSDocOverrideTag: - return emitJSDocSimpleTag(node as JSDocTag); - case SyntaxKind.JSDocAugmentsTag: - case SyntaxKind.JSDocImplementsTag: - return emitJSDocHeritageTag(node as JSDocImplementsTag | JSDocAugmentsTag); - case SyntaxKind.JSDocAuthorTag: - case SyntaxKind.JSDocDeprecatedTag: + case ts.SyntaxKind.JSDoc: + return emitJSDoc(node as ts.JSDoc); + case ts.SyntaxKind.JSDocTypeLiteral: + return emitJSDocTypeLiteral(node as ts.JSDocTypeLiteral); + case ts.SyntaxKind.JSDocSignature: + return emitJSDocSignature(node as ts.JSDocSignature); + case ts.SyntaxKind.JSDocTag: + case ts.SyntaxKind.JSDocClassTag: + case ts.SyntaxKind.JSDocOverrideTag: + return emitJSDocSimpleTag(node as ts.JSDocTag); + case ts.SyntaxKind.JSDocAugmentsTag: + case ts.SyntaxKind.JSDocImplementsTag: + return emitJSDocHeritageTag(node as ts.JSDocImplementsTag | ts.JSDocAugmentsTag); + case ts.SyntaxKind.JSDocAuthorTag: + case ts.SyntaxKind.JSDocDeprecatedTag: return; // SyntaxKind.JSDocClassTag (see JSDocTag, above) - case SyntaxKind.JSDocPublicTag: - case SyntaxKind.JSDocPrivateTag: - case SyntaxKind.JSDocProtectedTag: - case SyntaxKind.JSDocReadonlyTag: + case ts.SyntaxKind.JSDocPublicTag: + case ts.SyntaxKind.JSDocPrivateTag: + case ts.SyntaxKind.JSDocProtectedTag: + case ts.SyntaxKind.JSDocReadonlyTag: return; - case SyntaxKind.JSDocCallbackTag: - return emitJSDocCallbackTag(node as JSDocCallbackTag); + case ts.SyntaxKind.JSDocCallbackTag: + return emitJSDocCallbackTag(node as ts.JSDocCallbackTag); // SyntaxKind.JSDocEnumTag (see below) - case SyntaxKind.JSDocParameterTag: - case SyntaxKind.JSDocPropertyTag: - return emitJSDocPropertyLikeTag(node as JSDocPropertyLikeTag); - case SyntaxKind.JSDocEnumTag: - case SyntaxKind.JSDocReturnTag: - case SyntaxKind.JSDocThisTag: - case SyntaxKind.JSDocTypeTag: - return emitJSDocSimpleTypedTag(node as JSDocTypeTag); - case SyntaxKind.JSDocTemplateTag: - return emitJSDocTemplateTag(node as JSDocTemplateTag); - case SyntaxKind.JSDocTypedefTag: - return emitJSDocTypedefTag(node as JSDocTypedefTag); - case SyntaxKind.JSDocSeeTag: - return emitJSDocSeeTag(node as JSDocSeeTag); + case ts.SyntaxKind.JSDocParameterTag: + case ts.SyntaxKind.JSDocPropertyTag: + return emitJSDocPropertyLikeTag(node as ts.JSDocPropertyLikeTag); + case ts.SyntaxKind.JSDocEnumTag: + case ts.SyntaxKind.JSDocReturnTag: + case ts.SyntaxKind.JSDocThisTag: + case ts.SyntaxKind.JSDocTypeTag: + return emitJSDocSimpleTypedTag(node as ts.JSDocTypeTag); + case ts.SyntaxKind.JSDocTemplateTag: + return emitJSDocTemplateTag(node as ts.JSDocTemplateTag); + case ts.SyntaxKind.JSDocTypedefTag: + return emitJSDocTypedefTag(node as ts.JSDocTypedefTag); + case ts.SyntaxKind.JSDocSeeTag: + return emitJSDocSeeTag(node as ts.JSDocSeeTag); // SyntaxKind.JSDocPropertyTag (see JSDocParameterTag, above) // Transformation nodes - case SyntaxKind.NotEmittedStatement: - case SyntaxKind.EndOfDeclarationMarker: - case SyntaxKind.MergeDeclarationMarker: + case ts.SyntaxKind.NotEmittedStatement: + case ts.SyntaxKind.EndOfDeclarationMarker: + case ts.SyntaxKind.MergeDeclarationMarker: return; } - if (isExpression(node)) { - hint = EmitHint.Expression; - if (substituteNode !== noEmitSubstitution) { + if (ts.isExpression(node)) { + hint = ts.EmitHint.Expression; + if (substituteNode !== ts.noEmitSubstitution) { const substitute = substituteNode(hint, node) || node; if (substitute !== node) { node = substitute; @@ -1661,116 +1597,117 @@ namespace ts { } } } - if (hint === EmitHint.Expression) { + if (hint === ts.EmitHint.Expression) { switch (node.kind) { // Literals - case SyntaxKind.NumericLiteral: - case SyntaxKind.BigIntLiteral: - return emitNumericOrBigIntLiteral(node as NumericLiteral | BigIntLiteral); - - case SyntaxKind.StringLiteral: - case SyntaxKind.RegularExpressionLiteral: - case SyntaxKind.NoSubstitutionTemplateLiteral: - return emitLiteral(node as LiteralExpression, /*jsxAttributeEscape*/ false); + case ts.SyntaxKind.NumericLiteral: + case ts.SyntaxKind.BigIntLiteral: + return emitNumericOrBigIntLiteral(node as ts.NumericLiteral | ts.BigIntLiteral); + case ts.SyntaxKind.StringLiteral: + case ts.SyntaxKind.RegularExpressionLiteral: + case ts.SyntaxKind.NoSubstitutionTemplateLiteral: + return emitLiteral(node as ts.LiteralExpression, /*jsxAttributeEscape*/ false); // Identifiers - case SyntaxKind.Identifier: - return emitIdentifier(node as Identifier); - case SyntaxKind.PrivateIdentifier: - return emitPrivateIdentifier(node as PrivateIdentifier); + case ts.SyntaxKind.Identifier: + return emitIdentifier(node as ts.Identifier); + case ts.SyntaxKind.PrivateIdentifier: + return emitPrivateIdentifier(node as ts.PrivateIdentifier); // Expressions - case SyntaxKind.ArrayLiteralExpression: - return emitArrayLiteralExpression(node as ArrayLiteralExpression); - case SyntaxKind.ObjectLiteralExpression: - return emitObjectLiteralExpression(node as ObjectLiteralExpression); - case SyntaxKind.PropertyAccessExpression: - return emitPropertyAccessExpression(node as PropertyAccessExpression); - case SyntaxKind.ElementAccessExpression: - return emitElementAccessExpression(node as ElementAccessExpression); - case SyntaxKind.CallExpression: - return emitCallExpression(node as CallExpression); - case SyntaxKind.NewExpression: - return emitNewExpression(node as NewExpression); - case SyntaxKind.TaggedTemplateExpression: - return emitTaggedTemplateExpression(node as TaggedTemplateExpression); - case SyntaxKind.TypeAssertionExpression: - return emitTypeAssertionExpression(node as TypeAssertion); - case SyntaxKind.ParenthesizedExpression: - return emitParenthesizedExpression(node as ParenthesizedExpression); - case SyntaxKind.FunctionExpression: - return emitFunctionExpression(node as FunctionExpression); - case SyntaxKind.ArrowFunction: - return emitArrowFunction(node as ArrowFunction); - case SyntaxKind.DeleteExpression: - return emitDeleteExpression(node as DeleteExpression); - case SyntaxKind.TypeOfExpression: - return emitTypeOfExpression(node as TypeOfExpression); - case SyntaxKind.VoidExpression: - return emitVoidExpression(node as VoidExpression); - case SyntaxKind.AwaitExpression: - return emitAwaitExpression(node as AwaitExpression); - case SyntaxKind.PrefixUnaryExpression: - return emitPrefixUnaryExpression(node as PrefixUnaryExpression); - case SyntaxKind.PostfixUnaryExpression: - return emitPostfixUnaryExpression(node as PostfixUnaryExpression); - case SyntaxKind.BinaryExpression: - return emitBinaryExpression(node as BinaryExpression); - case SyntaxKind.ConditionalExpression: - return emitConditionalExpression(node as ConditionalExpression); - case SyntaxKind.TemplateExpression: - return emitTemplateExpression(node as TemplateExpression); - case SyntaxKind.YieldExpression: - return emitYieldExpression(node as YieldExpression); - case SyntaxKind.SpreadElement: - return emitSpreadElement(node as SpreadElement); - case SyntaxKind.ClassExpression: - return emitClassExpression(node as ClassExpression); - case SyntaxKind.OmittedExpression: + case ts.SyntaxKind.ArrayLiteralExpression: + return emitArrayLiteralExpression(node as ts.ArrayLiteralExpression); + case ts.SyntaxKind.ObjectLiteralExpression: + return emitObjectLiteralExpression(node as ts.ObjectLiteralExpression); + case ts.SyntaxKind.PropertyAccessExpression: + return emitPropertyAccessExpression(node as ts.PropertyAccessExpression); + case ts.SyntaxKind.ElementAccessExpression: + return emitElementAccessExpression(node as ts.ElementAccessExpression); + case ts.SyntaxKind.CallExpression: + return emitCallExpression(node as ts.CallExpression); + case ts.SyntaxKind.NewExpression: + return emitNewExpression(node as ts.NewExpression); + case ts.SyntaxKind.TaggedTemplateExpression: + return emitTaggedTemplateExpression(node as ts.TaggedTemplateExpression); + case ts.SyntaxKind.TypeAssertionExpression: + return emitTypeAssertionExpression(node as ts.TypeAssertion); + case ts.SyntaxKind.ParenthesizedExpression: + return emitParenthesizedExpression(node as ts.ParenthesizedExpression); + case ts.SyntaxKind.FunctionExpression: + return emitFunctionExpression(node as ts.FunctionExpression); + case ts.SyntaxKind.ArrowFunction: + return emitArrowFunction(node as ts.ArrowFunction); + case ts.SyntaxKind.DeleteExpression: + return emitDeleteExpression(node as ts.DeleteExpression); + case ts.SyntaxKind.TypeOfExpression: + return emitTypeOfExpression(node as ts.TypeOfExpression); + case ts.SyntaxKind.VoidExpression: + return emitVoidExpression(node as ts.VoidExpression); + case ts.SyntaxKind.AwaitExpression: + return emitAwaitExpression(node as ts.AwaitExpression); + case ts.SyntaxKind.PrefixUnaryExpression: + return emitPrefixUnaryExpression(node as ts.PrefixUnaryExpression); + case ts.SyntaxKind.PostfixUnaryExpression: + return emitPostfixUnaryExpression(node as ts.PostfixUnaryExpression); + case ts.SyntaxKind.BinaryExpression: + return emitBinaryExpression(node as ts.BinaryExpression); + case ts.SyntaxKind.ConditionalExpression: + return emitConditionalExpression(node as ts.ConditionalExpression); + case ts.SyntaxKind.TemplateExpression: + return emitTemplateExpression(node as ts.TemplateExpression); + case ts.SyntaxKind.YieldExpression: + return emitYieldExpression(node as ts.YieldExpression); + case ts.SyntaxKind.SpreadElement: + return emitSpreadElement(node as ts.SpreadElement); + case ts.SyntaxKind.ClassExpression: + return emitClassExpression(node as ts.ClassExpression); + case ts.SyntaxKind.OmittedExpression: return; - case SyntaxKind.AsExpression: - return emitAsExpression(node as AsExpression); - case SyntaxKind.NonNullExpression: - return emitNonNullExpression(node as NonNullExpression); - case SyntaxKind.ExpressionWithTypeArguments: - return emitExpressionWithTypeArguments(node as ExpressionWithTypeArguments); - case SyntaxKind.MetaProperty: - return emitMetaProperty(node as MetaProperty); - case SyntaxKind.SyntheticExpression: - return Debug.fail("SyntheticExpression should never be printed."); + case ts.SyntaxKind.AsExpression: + return emitAsExpression(node as ts.AsExpression); + case ts.SyntaxKind.NonNullExpression: + return emitNonNullExpression(node as ts.NonNullExpression); + case ts.SyntaxKind.ExpressionWithTypeArguments: + return emitExpressionWithTypeArguments(node as ts.ExpressionWithTypeArguments); + case ts.SyntaxKind.MetaProperty: + return emitMetaProperty(node as ts.MetaProperty); + case ts.SyntaxKind.SyntheticExpression: + return ts.Debug.fail("SyntheticExpression should never be printed."); // JSX - case SyntaxKind.JsxElement: - return emitJsxElement(node as JsxElement); - case SyntaxKind.JsxSelfClosingElement: - return emitJsxSelfClosingElement(node as JsxSelfClosingElement); - case SyntaxKind.JsxFragment: - return emitJsxFragment(node as JsxFragment); + case ts.SyntaxKind.JsxElement: + return emitJsxElement(node as ts.JsxElement); + case ts.SyntaxKind.JsxSelfClosingElement: + return emitJsxSelfClosingElement(node as ts.JsxSelfClosingElement); + case ts.SyntaxKind.JsxFragment: + return emitJsxFragment(node as ts.JsxFragment); // Synthesized list - case SyntaxKind.SyntaxList: - return Debug.fail("SyntaxList should not be printed"); + case ts.SyntaxKind.SyntaxList: + return ts.Debug.fail("SyntaxList should not be printed"); // Transformation nodes - case SyntaxKind.NotEmittedStatement: + case ts.SyntaxKind.NotEmittedStatement: return; - case SyntaxKind.PartiallyEmittedExpression: - return emitPartiallyEmittedExpression(node as PartiallyEmittedExpression); - case SyntaxKind.CommaListExpression: - return emitCommaList(node as CommaListExpression); - case SyntaxKind.MergeDeclarationMarker: - case SyntaxKind.EndOfDeclarationMarker: + case ts.SyntaxKind.PartiallyEmittedExpression: + return emitPartiallyEmittedExpression(node as ts.PartiallyEmittedExpression); + case ts.SyntaxKind.CommaListExpression: + return emitCommaList(node as ts.CommaListExpression); + case ts.SyntaxKind.MergeDeclarationMarker: + case ts.SyntaxKind.EndOfDeclarationMarker: return; - case SyntaxKind.SyntheticReferenceExpression: - return Debug.fail("SyntheticReferenceExpression should not be printed"); + case ts.SyntaxKind.SyntheticReferenceExpression: + return ts.Debug.fail("SyntheticReferenceExpression should not be printed"); } } - if (isKeyword(node.kind)) return writeTokenNode(node, writeKeyword); - if (isTokenKind(node.kind)) return writeTokenNode(node, writePunctuation); - Debug.fail(`Unhandled SyntaxKind: ${Debug.formatSyntaxKind(node.kind)}.`); + if (ts.isKeyword(node.kind)) + return writeTokenNode(node, writeKeyword); + if (ts.isTokenKind(node.kind)) + return writeTokenNode(node, writePunctuation); + ts.Debug.fail(`Unhandled SyntaxKind: ${ts.Debug.formatSyntaxKind(node.kind)}.`); } - function emitMappedTypeParameter(node: TypeParameterDeclaration): void { + function emitMappedTypeParameter(node: ts.TypeParameterDeclaration): void { emit(node.name); writeSpace(); writeKeyword("in"); @@ -1778,24 +1715,25 @@ namespace ts { emit(node.constraint); } - function pipelineEmitWithSubstitution(hint: EmitHint, node: Node) { + function pipelineEmitWithSubstitution(hint: ts.EmitHint, node: ts.Node) { const pipelinePhase = getNextPipelinePhase(PipelinePhase.Substitution, hint, node); - Debug.assertIsDefined(lastSubstitution); + ts.Debug.assertIsDefined(lastSubstitution); node = lastSubstitution; lastSubstitution = undefined; pipelinePhase(hint, node); } - function getHelpersFromBundledSourceFiles(bundle: Bundle): string[] | undefined { + function getHelpersFromBundledSourceFiles(bundle: ts.Bundle): string[] | undefined { let result: string[] | undefined; - if (moduleKind === ModuleKind.None || printerOptions.noEmitHelpers) { + if (moduleKind === ts.ModuleKind.None || printerOptions.noEmitHelpers) { return undefined; } - const bundledHelpers = new Map(); + const bundledHelpers = new ts.Map(); for (const sourceFile of bundle.sourceFiles) { - const shouldSkip = getExternalHelpersModuleName(sourceFile) !== undefined; + const shouldSkip = ts.getExternalHelpersModuleName(sourceFile) !== undefined; const helpers = getSortedEmitHelpers(sourceFile); - if (!helpers) continue; + if (!helpers) + continue; for (const helper of helpers) { if (!helper.scoped && !shouldSkip && !bundledHelpers.get(helper.name)) { bundledHelpers.set(helper.name, true); @@ -1807,27 +1745,28 @@ namespace ts { return result; } - function emitHelpers(node: Node) { + function emitHelpers(node: ts.Node) { let helpersEmitted = false; - const bundle = node.kind === SyntaxKind.Bundle ? node as Bundle : undefined; - if (bundle && moduleKind === ModuleKind.None) { + const bundle = node.kind === ts.SyntaxKind.Bundle ? node as ts.Bundle : undefined; + if (bundle && moduleKind === ts.ModuleKind.None) { return; } const numPrepends = bundle ? bundle.prepends.length : 0; const numNodes = bundle ? bundle.sourceFiles.length + numPrepends : 1; for (let i = 0; i < numNodes; i++) { const currentNode = bundle ? i < numPrepends ? bundle.prepends[i] : bundle.sourceFiles[i - numPrepends] : node; - const sourceFile = isSourceFile(currentNode) ? currentNode : isUnparsedSource(currentNode) ? undefined : currentSourceFile; - const shouldSkip = printerOptions.noEmitHelpers || (!!sourceFile && hasRecordedExternalHelpers(sourceFile)); - const shouldBundle = (isSourceFile(currentNode) || isUnparsedSource(currentNode)) && !isOwnFileEmit; - const helpers = isUnparsedSource(currentNode) ? currentNode.helpers : getSortedEmitHelpers(currentNode); + const sourceFile = ts.isSourceFile(currentNode) ? currentNode : ts.isUnparsedSource(currentNode) ? undefined : currentSourceFile; + const shouldSkip = printerOptions.noEmitHelpers || (!!sourceFile && ts.hasRecordedExternalHelpers(sourceFile)); + const shouldBundle = (ts.isSourceFile(currentNode) || ts.isUnparsedSource(currentNode)) && !isOwnFileEmit; + const helpers = ts.isUnparsedSource(currentNode) ? currentNode.helpers : getSortedEmitHelpers(currentNode); if (helpers) { for (const helper of helpers) { if (!helper.scoped) { // Skip the helper if it can be skipped and the noEmitHelpers compiler // option is set, or if it can be imported and the importHelpers compiler // option is set. - if (shouldSkip) continue; + if (shouldSkip) + continue; // Skip the helper if it can be bundled but hasn't already been emitted and we // are emitting a bundled module. @@ -1850,7 +1789,8 @@ namespace ts { else { writeLines(helper.text(makeFileLevelOptimisticUniqueName)); } - if (bundleFileInfo) bundleFileInfo.sections.push({ pos, end: writer.getTextPos(), kind: BundleFileSectionKind.EmitHelpers, data: helper.name }); + if (bundleFileInfo) + bundleFileInfo.sections.push({ pos, end: writer.getTextPos(), kind: ts.BundleFileSectionKind.EmitHelpers, data: helper.name }); helpersEmitted = true; } } @@ -1859,9 +1799,9 @@ namespace ts { return helpersEmitted; } - function getSortedEmitHelpers(node: Node) { - const helpers = getEmitHelpers(node); - return helpers && stableSort(helpers, compareEmitHelpers); + function getSortedEmitHelpers(node: ts.Node) { + const helpers = ts.getEmitHelpers(node); + return helpers && ts.stableSort(helpers, ts.compareEmitHelpers); } // @@ -1870,7 +1810,7 @@ namespace ts { // SyntaxKind.NumericLiteral // SyntaxKind.BigIntLiteral - function emitNumericOrBigIntLiteral(node: NumericLiteral | BigIntLiteral) { + function emitNumericOrBigIntLiteral(node: ts.NumericLiteral | ts.BigIntLiteral) { emitLiteral(node, /*jsxAttributeEscape*/ false); } @@ -1880,10 +1820,10 @@ namespace ts { // SyntaxKind.TemplateHead // SyntaxKind.TemplateMiddle // SyntaxKind.TemplateTail - function emitLiteral(node: LiteralLikeNode, jsxAttributeEscape: boolean) { + function emitLiteral(node: ts.LiteralLikeNode, jsxAttributeEscape: boolean) { const text = getLiteralTextOfNode(node, printerOptions.neverAsciiEscape, jsxAttributeEscape); if ((printerOptions.sourceMap || printerOptions.inlineSourceMap) - && (node.kind === SyntaxKind.StringLiteral || isTemplateLiteralKind(node.kind))) { + && (node.kind === ts.SyntaxKind.StringLiteral || ts.isTemplateLiteralKind(node.kind))) { writeLiteral(text); } else { @@ -1894,7 +1834,7 @@ namespace ts { // SyntaxKind.UnparsedSource // SyntaxKind.UnparsedPrepend - function emitUnparsedSourceOrPrepend(unparsed: UnparsedSource | UnparsedPrepend) { + function emitUnparsedSourceOrPrepend(unparsed: ts.UnparsedSource | ts.UnparsedPrepend) { for (const text of unparsed.texts) { writeLine(); emit(text); @@ -1905,32 +1845,28 @@ namespace ts { // SyntaxKind.UnparsedText // SyntaxKind.UnparsedInternal // SyntaxKind.UnparsedSyntheticReference - function writeUnparsedNode(unparsed: UnparsedNode) { + function writeUnparsedNode(unparsed: ts.UnparsedNode) { writer.rawWrite(unparsed.parent.text.substring(unparsed.pos, unparsed.end)); } // SyntaxKind.UnparsedText // SyntaxKind.UnparsedInternal - function emitUnparsedTextLike(unparsed: UnparsedTextLike) { + function emitUnparsedTextLike(unparsed: ts.UnparsedTextLike) { const pos = getTextPosWithWriteLine(); writeUnparsedNode(unparsed); if (bundleFileInfo) { - updateOrPushBundleFileTextLike( - pos, - writer.getTextPos(), - unparsed.kind === SyntaxKind.UnparsedText ? - BundleFileSectionKind.Text : - BundleFileSectionKind.Internal - ); + updateOrPushBundleFileTextLike(pos, writer.getTextPos(), unparsed.kind === ts.SyntaxKind.UnparsedText ? + ts.BundleFileSectionKind.Text : + ts.BundleFileSectionKind.Internal); } } // SyntaxKind.UnparsedSyntheticReference - function emitUnparsedSyntheticReference(unparsed: UnparsedSyntheticReference) { + function emitUnparsedSyntheticReference(unparsed: ts.UnparsedSyntheticReference) { const pos = getTextPosWithWriteLine(); writeUnparsedNode(unparsed); if (bundleFileInfo) { - const section = clone(unparsed.section); + const section = ts.clone(unparsed.section); section.pos = pos; section.end = writer.getTextPos(); bundleFileInfo.sections.push(section); @@ -1941,30 +1877,28 @@ namespace ts { // Snippet Elements // - function emitSnippetNode(hint: EmitHint, node: Node, snippet: SnippetElement) { + function emitSnippetNode(hint: ts.EmitHint, node: ts.Node, snippet: ts.SnippetElement) { switch (snippet.kind) { - case SnippetKind.Placeholder: + case ts.SnippetKind.Placeholder: emitPlaceholder(hint, node, snippet); break; - case SnippetKind.TabStop: + case ts.SnippetKind.TabStop: emitTabStop(hint, node, snippet); break; } } - function emitPlaceholder(hint: EmitHint, node: Node, snippet: Placeholder) { + function emitPlaceholder(hint: ts.EmitHint, node: ts.Node, snippet: ts.Placeholder) { nonEscapingWrite(`\$\{${snippet.order}:`); // `${2:` pipelineEmitWithHintWorker(hint, node, /*allowSnippets*/ false); // `...` nonEscapingWrite(`\}`); // `}` // `${2:...}` } - function emitTabStop(hint: EmitHint, node: Node, snippet: TabStop) { + function emitTabStop(hint: ts.EmitHint, node: ts.Node, snippet: ts.TabStop) { // A tab stop should only be attached to an empty node, i.e. a node that doesn't emit any text. - Debug.assert(node.kind === SyntaxKind.EmptyStatement, - `A tab stop cannot be attached to a node of kind ${Debug.formatSyntaxKind(node.kind)}.`); - Debug.assert(hint !== EmitHint.EmbeddedStatement, - `A tab stop cannot be attached to an embedded statement.`); + ts.Debug.assert(node.kind === ts.SyntaxKind.EmptyStatement, `A tab stop cannot be attached to a node of kind ${ts.Debug.formatSyntaxKind(node.kind)}.`); + ts.Debug.assert(hint !== ts.EmitHint.EmbeddedStatement, `A tab stop cannot be attached to an embedded statement.`); nonEscapingWrite(`\$${snippet.order}`); } @@ -1972,30 +1906,30 @@ namespace ts { // Identifiers // - function emitIdentifier(node: Identifier) { + function emitIdentifier(node: ts.Identifier) { const writeText = node.symbol ? writeSymbol : write; writeText(getTextOfNode(node, /*includeTrivia*/ false), node.symbol); - emitList(node, node.typeArguments, ListFormat.TypeParameters); // Call emitList directly since it could be an array of TypeParameterDeclarations _or_ type arguments + emitList(node, node.typeArguments, ts.ListFormat.TypeParameters); // Call emitList directly since it could be an array of TypeParameterDeclarations _or_ type arguments } // // Names // - function emitPrivateIdentifier(node: PrivateIdentifier) { + function emitPrivateIdentifier(node: ts.PrivateIdentifier) { const writeText = node.symbol ? writeSymbol : write; writeText(getTextOfNode(node, /*includeTrivia*/ false), node.symbol); } - function emitQualifiedName(node: QualifiedName) { + function emitQualifiedName(node: ts.QualifiedName) { emitEntityName(node.left); writePunctuation("."); emit(node.right); } - function emitEntityName(node: EntityName) { - if (node.kind === SyntaxKind.Identifier) { + function emitEntityName(node: ts.EntityName) { + if (node.kind === ts.SyntaxKind.Identifier) { emitExpression(node); } else { @@ -2003,7 +1937,7 @@ namespace ts { } } - function emitComputedPropertyName(node: ComputedPropertyName) { + function emitComputedPropertyName(node: ts.ComputedPropertyName) { writePunctuation("["); emitExpression(node.expression, parenthesizer.parenthesizeExpressionOfComputedPropertyName); writePunctuation("]"); @@ -2013,7 +1947,7 @@ namespace ts { // Signature elements // - function emitTypeParameter(node: TypeParameterDeclaration) { + function emitTypeParameter(node: ts.TypeParameterDeclaration) { emitModifiers(node, node.modifiers); emit(node.name); if (node.constraint) { @@ -2030,13 +1964,13 @@ namespace ts { } } - function emitParameter(node: ParameterDeclaration) { + function emitParameter(node: ts.ParameterDeclaration) { emitDecorators(node, node.decorators); emitModifiers(node, node.modifiers); emit(node.dotDotDotToken); emitNodeWithWriter(node.name, writeParameter); emit(node.questionToken); - if (node.parent && node.parent.kind === SyntaxKind.JSDocFunctionType && !node.name) { + if (node.parent && node.parent.kind === ts.SyntaxKind.JSDocFunctionType && !node.name) { emit(node.type); } else { @@ -2046,7 +1980,7 @@ namespace ts { emitInitializer(node.initializer, node.type ? node.type.end : node.questionToken ? node.questionToken.end : node.name ? node.name.end : node.modifiers ? node.modifiers.end : node.decorators ? node.decorators.end : node.pos, node, parenthesizer.parenthesizeExpressionForDisallowedComma); } - function emitDecorator(decorator: Decorator) { + function emitDecorator(decorator: ts.Decorator) { writePunctuation("@"); emitExpression(decorator.expression, parenthesizer.parenthesizeLeftSideOfAccess); } @@ -2055,7 +1989,7 @@ namespace ts { // Type members // - function emitPropertySignature(node: PropertySignature) { + function emitPropertySignature(node: ts.PropertySignature) { emitDecorators(node, node.decorators); emitModifiers(node, node.modifiers); emitNodeWithWriter(node.name, writeProperty); @@ -2064,7 +1998,7 @@ namespace ts { writeTrailingSemicolon(); } - function emitPropertyDeclaration(node: PropertyDeclaration) { + function emitPropertyDeclaration(node: ts.PropertyDeclaration) { emitDecorators(node, node.decorators); emitModifiers(node, node.modifiers); emit(node.name); @@ -2075,7 +2009,7 @@ namespace ts { writeTrailingSemicolon(); } - function emitMethodSignature(node: MethodSignature) { + function emitMethodSignature(node: ts.MethodSignature) { pushNameGenerationScope(node); emitDecorators(node, node.decorators); emitModifiers(node, node.modifiers); @@ -2088,7 +2022,7 @@ namespace ts { popNameGenerationScope(node); } - function emitMethodDeclaration(node: MethodDeclaration) { + function emitMethodDeclaration(node: ts.MethodDeclaration) { emitDecorators(node, node.decorators); emitModifiers(node, node.modifiers); emit(node.asteriskToken); @@ -2097,29 +2031,29 @@ namespace ts { emitSignatureAndBody(node, emitSignatureHead); } - function emitClassStaticBlockDeclaration(node: ClassStaticBlockDeclaration) { + function emitClassStaticBlockDeclaration(node: ts.ClassStaticBlockDeclaration) { emitDecorators(node, node.decorators); emitModifiers(node, node.modifiers); writeKeyword("static"); emitBlockFunctionBody(node.body); } - function emitConstructor(node: ConstructorDeclaration) { + function emitConstructor(node: ts.ConstructorDeclaration) { emitModifiers(node, node.modifiers); writeKeyword("constructor"); emitSignatureAndBody(node, emitSignatureHead); } - function emitAccessorDeclaration(node: AccessorDeclaration) { + function emitAccessorDeclaration(node: ts.AccessorDeclaration) { emitDecorators(node, node.decorators); emitModifiers(node, node.modifiers); - writeKeyword(node.kind === SyntaxKind.GetAccessor ? "get" : "set"); + writeKeyword(node.kind === ts.SyntaxKind.GetAccessor ? "get" : "set"); writeSpace(); emit(node.name); emitSignatureAndBody(node, emitSignatureHead); } - function emitCallSignature(node: CallSignatureDeclaration) { + function emitCallSignature(node: ts.CallSignatureDeclaration) { pushNameGenerationScope(node); emitDecorators(node, node.decorators); emitModifiers(node, node.modifiers); @@ -2130,7 +2064,7 @@ namespace ts { popNameGenerationScope(node); } - function emitConstructSignature(node: ConstructSignatureDeclaration) { + function emitConstructSignature(node: ts.ConstructSignatureDeclaration) { pushNameGenerationScope(node); emitDecorators(node, node.decorators); emitModifiers(node, node.modifiers); @@ -2143,7 +2077,7 @@ namespace ts { popNameGenerationScope(node); } - function emitIndexSignature(node: IndexSignatureDeclaration) { + function emitIndexSignature(node: ts.IndexSignatureDeclaration) { emitDecorators(node, node.decorators); emitModifiers(node, node.modifiers); emitParametersForIndexSignature(node, node.parameters); @@ -2151,7 +2085,7 @@ namespace ts { writeTrailingSemicolon(); } - function emitTemplateTypeSpan(node: TemplateLiteralTypeSpan) { + function emitTemplateTypeSpan(node: ts.TemplateLiteralTypeSpan) { emit(node.type); emit(node.literal); } @@ -2164,7 +2098,7 @@ namespace ts { // Types // - function emitTypePredicate(node: TypePredicateNode) { + function emitTypePredicate(node: ts.TypePredicateNode) { if (node.assertsModifier) { emit(node.assertsModifier); writeSpace(); @@ -2178,12 +2112,12 @@ namespace ts { } } - function emitTypeReference(node: TypeReferenceNode) { + function emitTypeReference(node: ts.TypeReferenceNode) { emit(node.typeName); emitTypeArguments(node, node.typeArguments); } - function emitFunctionType(node: FunctionTypeNode) { + function emitFunctionType(node: ts.FunctionTypeNode) { pushNameGenerationScope(node); emitTypeParameters(node, node.typeParameters); emitParametersForArrow(node, node.parameters); @@ -2194,7 +2128,7 @@ namespace ts { popNameGenerationScope(node); } - function emitJSDocFunctionType(node: JSDocFunctionType) { + function emitJSDocFunctionType(node: ts.JSDocFunctionType) { writeKeyword("function"); emitParameters(node, node.parameters); writePunctuation(":"); @@ -2202,22 +2136,22 @@ namespace ts { } - function emitJSDocNullableType(node: JSDocNullableType) { + function emitJSDocNullableType(node: ts.JSDocNullableType) { writePunctuation("?"); emit(node.type); } - function emitJSDocNonNullableType(node: JSDocNonNullableType) { + function emitJSDocNonNullableType(node: ts.JSDocNonNullableType) { writePunctuation("!"); emit(node.type); } - function emitJSDocOptionalType(node: JSDocOptionalType) { + function emitJSDocOptionalType(node: ts.JSDocOptionalType) { emit(node.type); writePunctuation("="); } - function emitConstructorType(node: ConstructorTypeNode) { + function emitConstructorType(node: ts.ConstructorTypeNode) { pushNameGenerationScope(node); emitModifiers(node, node.modifiers); writeKeyword("new"); @@ -2231,61 +2165,61 @@ namespace ts { popNameGenerationScope(node); } - function emitTypeQuery(node: TypeQueryNode) { + function emitTypeQuery(node: ts.TypeQueryNode) { writeKeyword("typeof"); writeSpace(); emit(node.exprName); emitTypeArguments(node, node.typeArguments); } - function emitTypeLiteral(node: TypeLiteralNode) { + function emitTypeLiteral(node: ts.TypeLiteralNode) { writePunctuation("{"); - const flags = getEmitFlags(node) & EmitFlags.SingleLine ? ListFormat.SingleLineTypeLiteralMembers : ListFormat.MultiLineTypeLiteralMembers; - emitList(node, node.members, flags | ListFormat.NoSpaceIfEmpty); + const flags = ts.getEmitFlags(node) & ts.EmitFlags.SingleLine ? ts.ListFormat.SingleLineTypeLiteralMembers : ts.ListFormat.MultiLineTypeLiteralMembers; + emitList(node, node.members, flags | ts.ListFormat.NoSpaceIfEmpty); writePunctuation("}"); } - function emitArrayType(node: ArrayTypeNode) { + function emitArrayType(node: ts.ArrayTypeNode) { emit(node.elementType, parenthesizer.parenthesizeNonArrayTypeOfPostfixType); writePunctuation("["); writePunctuation("]"); } - function emitRestOrJSDocVariadicType(node: RestTypeNode | JSDocVariadicType) { + function emitRestOrJSDocVariadicType(node: ts.RestTypeNode | ts.JSDocVariadicType) { writePunctuation("..."); emit(node.type); } - function emitTupleType(node: TupleTypeNode) { - emitTokenWithComment(SyntaxKind.OpenBracketToken, node.pos, writePunctuation, node); - const flags = getEmitFlags(node) & EmitFlags.SingleLine ? ListFormat.SingleLineTupleTypeElements : ListFormat.MultiLineTupleTypeElements; - emitList(node, node.elements, flags | ListFormat.NoSpaceIfEmpty, parenthesizer.parenthesizeElementTypeOfTupleType); - emitTokenWithComment(SyntaxKind.CloseBracketToken, node.elements.end, writePunctuation, node); + function emitTupleType(node: ts.TupleTypeNode) { + emitTokenWithComment(ts.SyntaxKind.OpenBracketToken, node.pos, writePunctuation, node); + const flags = ts.getEmitFlags(node) & ts.EmitFlags.SingleLine ? ts.ListFormat.SingleLineTupleTypeElements : ts.ListFormat.MultiLineTupleTypeElements; + emitList(node, node.elements, flags | ts.ListFormat.NoSpaceIfEmpty, parenthesizer.parenthesizeElementTypeOfTupleType); + emitTokenWithComment(ts.SyntaxKind.CloseBracketToken, node.elements.end, writePunctuation, node); } - function emitNamedTupleMember(node: NamedTupleMember) { + function emitNamedTupleMember(node: ts.NamedTupleMember) { emit(node.dotDotDotToken); emit(node.name); emit(node.questionToken); - emitTokenWithComment(SyntaxKind.ColonToken, node.name.end, writePunctuation, node); + emitTokenWithComment(ts.SyntaxKind.ColonToken, node.name.end, writePunctuation, node); writeSpace(); emit(node.type); } - function emitOptionalType(node: OptionalTypeNode) { + function emitOptionalType(node: ts.OptionalTypeNode) { emit(node.type, parenthesizer.parenthesizeTypeOfOptionalType); writePunctuation("?"); } - function emitUnionType(node: UnionTypeNode) { - emitList(node, node.types, ListFormat.UnionTypeConstituents, parenthesizer.parenthesizeConstituentTypeOfUnionType); + function emitUnionType(node: ts.UnionTypeNode) { + emitList(node, node.types, ts.ListFormat.UnionTypeConstituents, parenthesizer.parenthesizeConstituentTypeOfUnionType); } - function emitIntersectionType(node: IntersectionTypeNode) { - emitList(node, node.types, ListFormat.IntersectionTypeConstituents, parenthesizer.parenthesizeConstituentTypeOfIntersectionType); + function emitIntersectionType(node: ts.IntersectionTypeNode) { + emitList(node, node.types, ts.ListFormat.IntersectionTypeConstituents, parenthesizer.parenthesizeConstituentTypeOfIntersectionType); } - function emitConditionalType(node: ConditionalTypeNode) { + function emitConditionalType(node: ts.ConditionalTypeNode) { emit(node.checkType, parenthesizer.parenthesizeCheckTypeOfConditionalType); writeSpace(); writeKeyword("extends"); @@ -2301,13 +2235,13 @@ namespace ts { emit(node.falseType); } - function emitInferType(node: InferTypeNode) { + function emitInferType(node: ts.InferTypeNode) { writeKeyword("infer"); writeSpace(); emit(node.typeParameter); } - function emitParenthesizedType(node: ParenthesizedTypeNode) { + function emitParenthesizedType(node: ts.ParenthesizedTypeNode) { writePunctuation("("); emit(node.type); writePunctuation(")"); @@ -2317,27 +2251,27 @@ namespace ts { writeKeyword("this"); } - function emitTypeOperator(node: TypeOperatorNode) { + function emitTypeOperator(node: ts.TypeOperatorNode) { writeTokenText(node.operator, writeKeyword); writeSpace(); - const parenthesizerRule = node.operator === SyntaxKind.ReadonlyKeyword ? + const parenthesizerRule = node.operator === ts.SyntaxKind.ReadonlyKeyword ? parenthesizer.parenthesizeOperandOfReadonlyTypeOperator : parenthesizer.parenthesizeOperandOfTypeOperator; emit(node.type, parenthesizerRule); } - function emitIndexedAccessType(node: IndexedAccessTypeNode) { + function emitIndexedAccessType(node: ts.IndexedAccessTypeNode) { emit(node.objectType, parenthesizer.parenthesizeNonArrayTypeOfPostfixType); writePunctuation("["); emit(node.indexType); writePunctuation("]"); } - function emitMappedType(node: MappedTypeNode) { - const emitFlags = getEmitFlags(node); + function emitMappedType(node: ts.MappedTypeNode) { + const emitFlags = ts.getEmitFlags(node); writePunctuation("{"); - if (emitFlags & EmitFlags.SingleLine) { + if (emitFlags & ts.EmitFlags.SingleLine) { writeSpace(); } else { @@ -2346,14 +2280,14 @@ namespace ts { } if (node.readonlyToken) { emit(node.readonlyToken); - if (node.readonlyToken.kind !== SyntaxKind.ReadonlyKeyword) { + if (node.readonlyToken.kind !== ts.SyntaxKind.ReadonlyKeyword) { writeKeyword("readonly"); } writeSpace(); } writePunctuation("["); - pipelineEmit(EmitHint.MappedTypeParameter, node.typeParameter); + pipelineEmit(ts.EmitHint.MappedTypeParameter, node.typeParameter); if (node.nameType) { writeSpace(); writeKeyword("as"); @@ -2364,7 +2298,7 @@ namespace ts { writePunctuation("]"); if (node.questionToken) { emit(node.questionToken); - if (node.questionToken.kind !== SyntaxKind.QuestionToken) { + if (node.questionToken.kind !== ts.SyntaxKind.QuestionToken) { writePunctuation("?"); } } @@ -2372,27 +2306,27 @@ namespace ts { writeSpace(); emit(node.type); writeTrailingSemicolon(); - if (emitFlags & EmitFlags.SingleLine) { + if (emitFlags & ts.EmitFlags.SingleLine) { writeSpace(); } else { writeLine(); decreaseIndent(); } - emitList(node, node.members, ListFormat.PreserveLines); + emitList(node, node.members, ts.ListFormat.PreserveLines); writePunctuation("}"); } - function emitLiteralType(node: LiteralTypeNode) { + function emitLiteralType(node: ts.LiteralTypeNode) { emitExpression(node.literal); } - function emitTemplateType(node: TemplateLiteralTypeNode) { + function emitTemplateType(node: ts.TemplateLiteralTypeNode) { emit(node.head); - emitList(node, node.templateSpans, ListFormat.TemplateExpressionSpans); + emitList(node, node.templateSpans, ts.ListFormat.TemplateExpressionSpans); } - function emitImportTypeNode(node: ImportTypeNode) { + function emitImportTypeNode(node: ts.ImportTypeNode) { if (node.isTypeOf) { writeKeyword("typeof"); writeSpace(); @@ -2409,7 +2343,7 @@ namespace ts { writePunctuation(":"); writeSpace(); const elements = node.assertions.assertClause.elements; - emitList(node.assertions.assertClause, elements, ListFormat.ImportClauseEntries); + emitList(node.assertions.assertClause, elements, ts.ListFormat.ImportClauseEntries); writeSpace(); writePunctuation("}"); } @@ -2425,19 +2359,19 @@ namespace ts { // Binding patterns // - function emitObjectBindingPattern(node: ObjectBindingPattern) { + function emitObjectBindingPattern(node: ts.ObjectBindingPattern) { writePunctuation("{"); - emitList(node, node.elements, ListFormat.ObjectBindingPatternElements); + emitList(node, node.elements, ts.ListFormat.ObjectBindingPatternElements); writePunctuation("}"); } - function emitArrayBindingPattern(node: ArrayBindingPattern) { + function emitArrayBindingPattern(node: ts.ArrayBindingPattern) { writePunctuation("["); - emitList(node, node.elements, ListFormat.ArrayBindingPatternElements); + emitList(node, node.elements, ts.ListFormat.ArrayBindingPatternElements); writePunctuation("]"); } - function emitBindingElement(node: BindingElement) { + function emitBindingElement(node: ts.BindingElement) { emit(node.dotDotDotToken); if (node.propertyName) { emit(node.propertyName); @@ -2452,39 +2386,36 @@ namespace ts { // Expressions // - function emitArrayLiteralExpression(node: ArrayLiteralExpression) { + function emitArrayLiteralExpression(node: ts.ArrayLiteralExpression) { const elements = node.elements; - const preferNewLine = node.multiLine ? ListFormat.PreferNewLine : ListFormat.None; - emitExpressionList(node, elements, ListFormat.ArrayLiteralExpressionElements | preferNewLine, parenthesizer.parenthesizeExpressionForDisallowedComma); + const preferNewLine = node.multiLine ? ts.ListFormat.PreferNewLine : ts.ListFormat.None; + emitExpressionList(node, elements, ts.ListFormat.ArrayLiteralExpressionElements | preferNewLine, parenthesizer.parenthesizeExpressionForDisallowedComma); } - - function emitObjectLiteralExpression(node: ObjectLiteralExpression) { - forEach(node.properties, generateMemberNames); - - const indentedFlag = getEmitFlags(node) & EmitFlags.Indented; + function emitObjectLiteralExpression(node: ts.ObjectLiteralExpression) { + ts.forEach(node.properties, generateMemberNames); + const indentedFlag = ts.getEmitFlags(node) & ts.EmitFlags.Indented; if (indentedFlag) { increaseIndent(); } - const preferNewLine = node.multiLine ? ListFormat.PreferNewLine : ListFormat.None; - const allowTrailingComma = currentSourceFile && currentSourceFile.languageVersion >= ScriptTarget.ES5 && !isJsonSourceFile(currentSourceFile) ? ListFormat.AllowTrailingComma : ListFormat.None; - emitList(node, node.properties, ListFormat.ObjectLiteralExpressionProperties | allowTrailingComma | preferNewLine); + const preferNewLine = node.multiLine ? ts.ListFormat.PreferNewLine : ts.ListFormat.None; + const allowTrailingComma = currentSourceFile && currentSourceFile.languageVersion >= ts.ScriptTarget.ES5 && !ts.isJsonSourceFile(currentSourceFile) ? ts.ListFormat.AllowTrailingComma : ts.ListFormat.None; + emitList(node, node.properties, ts.ListFormat.ObjectLiteralExpressionProperties | allowTrailingComma | preferNewLine); if (indentedFlag) { decreaseIndent(); } } - function emitPropertyAccessExpression(node: PropertyAccessExpression) { + function emitPropertyAccessExpression(node: ts.PropertyAccessExpression) { emitExpression(node.expression, parenthesizer.parenthesizeLeftSideOfAccess); - const token = node.questionDotToken || setTextRangePosEnd(factory.createToken(SyntaxKind.DotToken) as DotToken, node.expression.end, node.name.pos); + const token = node.questionDotToken || ts.setTextRangePosEnd(ts.factory.createToken(ts.SyntaxKind.DotToken) as ts.DotToken, node.expression.end, node.name.pos); const linesBeforeDot = getLinesBetweenNodes(node, node.expression, token); const linesAfterDot = getLinesBetweenNodes(node, token, node.name); writeLinesAndIndent(linesBeforeDot, /*writeSpaceIfNotIndenting*/ false); - const shouldEmitDotDot = - token.kind !== SyntaxKind.QuestionDotToken && + const shouldEmitDotDot = token.kind !== ts.SyntaxKind.QuestionDotToken && mayNeedDotDotForPropertyAccess(node.expression) && !writer.hasTrailingComment() && !writer.hasTrailingWhitespace(); @@ -2506,34 +2437,34 @@ namespace ts { // 1..toString is a valid property access, emit a dot after the literal // Also emit a dot if expression is a integer const enum value - it will appear in generated code as numeric literal - function mayNeedDotDotForPropertyAccess(expression: Expression) { - expression = skipPartiallyEmittedExpressions(expression); - if (isNumericLiteral(expression)) { + function mayNeedDotDotForPropertyAccess(expression: ts.Expression) { + expression = ts.skipPartiallyEmittedExpressions(expression); + if (ts.isNumericLiteral(expression)) { // check if numeric literal is a decimal literal that was originally written with a dot - const text = getLiteralTextOfNode(expression as LiteralExpression, /*neverAsciiEscape*/ true, /*jsxAttributeEscape*/ false); + const text = getLiteralTextOfNode(expression as ts.LiteralExpression, /*neverAsciiEscape*/ true, /*jsxAttributeEscape*/ false); // If he number will be printed verbatim and it doesn't already contain a dot, add one // if the expression doesn't have any comments that will be emitted. - return !expression.numericLiteralFlags && !stringContains(text, tokenToString(SyntaxKind.DotToken)!); + return !expression.numericLiteralFlags && !ts.stringContains(text, ts.tokenToString(ts.SyntaxKind.DotToken)!); } - else if (isAccessExpression(expression)) { + else if (ts.isAccessExpression(expression)) { // check if constant enum value is integer - const constantValue = getConstantValue(expression); + const constantValue = ts.getConstantValue(expression); // isFinite handles cases when constantValue is undefined return typeof constantValue === "number" && isFinite(constantValue) && Math.floor(constantValue) === constantValue; } } - function emitElementAccessExpression(node: ElementAccessExpression) { + function emitElementAccessExpression(node: ts.ElementAccessExpression) { emitExpression(node.expression, parenthesizer.parenthesizeLeftSideOfAccess); emit(node.questionDotToken); - emitTokenWithComment(SyntaxKind.OpenBracketToken, node.expression.end, writePunctuation, node); + emitTokenWithComment(ts.SyntaxKind.OpenBracketToken, node.expression.end, writePunctuation, node); emitExpression(node.argumentExpression); - emitTokenWithComment(SyntaxKind.CloseBracketToken, node.argumentExpression.end, writePunctuation, node); + emitTokenWithComment(ts.SyntaxKind.CloseBracketToken, node.argumentExpression.end, writePunctuation, node); } - function emitCallExpression(node: CallExpression) { - const indirectCall = getEmitFlags(node) & EmitFlags.IndirectCall; + function emitCallExpression(node: ts.CallExpression) { + const indirectCall = ts.getEmitFlags(node) & ts.EmitFlags.IndirectCall; if (indirectCall) { writePunctuation("("); writeLiteral("0"); @@ -2546,19 +2477,19 @@ namespace ts { } emit(node.questionDotToken); emitTypeArguments(node, node.typeArguments); - emitExpressionList(node, node.arguments, ListFormat.CallExpressionArguments, parenthesizer.parenthesizeExpressionForDisallowedComma); + emitExpressionList(node, node.arguments, ts.ListFormat.CallExpressionArguments, parenthesizer.parenthesizeExpressionForDisallowedComma); } - function emitNewExpression(node: NewExpression) { - emitTokenWithComment(SyntaxKind.NewKeyword, node.pos, writeKeyword, node); + function emitNewExpression(node: ts.NewExpression) { + emitTokenWithComment(ts.SyntaxKind.NewKeyword, node.pos, writeKeyword, node); writeSpace(); emitExpression(node.expression, parenthesizer.parenthesizeExpressionOfNew); emitTypeArguments(node, node.typeArguments); - emitExpressionList(node, node.arguments, ListFormat.NewExpressionArguments, parenthesizer.parenthesizeExpressionForDisallowedComma); + emitExpressionList(node, node.arguments, ts.ListFormat.NewExpressionArguments, parenthesizer.parenthesizeExpressionForDisallowedComma); } - function emitTaggedTemplateExpression(node: TaggedTemplateExpression) { - const indirectCall = getEmitFlags(node) & EmitFlags.IndirectCall; + function emitTaggedTemplateExpression(node: ts.TaggedTemplateExpression) { + const indirectCall = ts.getEmitFlags(node) & ts.EmitFlags.IndirectCall; if (indirectCall) { writePunctuation("("); writeLiteral("0"); @@ -2574,34 +2505,34 @@ namespace ts { emitExpression(node.template); } - function emitTypeAssertionExpression(node: TypeAssertion) { + function emitTypeAssertionExpression(node: ts.TypeAssertion) { writePunctuation("<"); emit(node.type); writePunctuation(">"); emitExpression(node.expression, parenthesizer.parenthesizeOperandOfPrefixUnary); } - function emitParenthesizedExpression(node: ParenthesizedExpression) { - const openParenPos = emitTokenWithComment(SyntaxKind.OpenParenToken, node.pos, writePunctuation, node); + function emitParenthesizedExpression(node: ts.ParenthesizedExpression) { + const openParenPos = emitTokenWithComment(ts.SyntaxKind.OpenParenToken, node.pos, writePunctuation, node); const indented = writeLineSeparatorsAndIndentBefore(node.expression, node); emitExpression(node.expression, /*parenthesizerRules*/ undefined); writeLineSeparatorsAfter(node.expression, node); decreaseIndentIf(indented); - emitTokenWithComment(SyntaxKind.CloseParenToken, node.expression ? node.expression.end : openParenPos, writePunctuation, node); + emitTokenWithComment(ts.SyntaxKind.CloseParenToken, node.expression ? node.expression.end : openParenPos, writePunctuation, node); } - function emitFunctionExpression(node: FunctionExpression) { + function emitFunctionExpression(node: ts.FunctionExpression) { generateNameIfNeeded(node.name); emitFunctionDeclarationOrExpression(node); } - function emitArrowFunction(node: ArrowFunction) { + function emitArrowFunction(node: ts.ArrowFunction) { emitDecorators(node, node.decorators); emitModifiers(node, node.modifiers); emitSignatureAndBody(node, emitArrowFunctionHead); } - function emitArrowFunctionHead(node: ArrowFunction) { + function emitArrowFunctionHead(node: ts.ArrowFunction) { emitTypeParameters(node, node.typeParameters); emitParametersForArrow(node, node.parameters); emitTypeAnnotation(node.type); @@ -2609,31 +2540,31 @@ namespace ts { emit(node.equalsGreaterThanToken); } - function emitDeleteExpression(node: DeleteExpression) { - emitTokenWithComment(SyntaxKind.DeleteKeyword, node.pos, writeKeyword, node); + function emitDeleteExpression(node: ts.DeleteExpression) { + emitTokenWithComment(ts.SyntaxKind.DeleteKeyword, node.pos, writeKeyword, node); writeSpace(); emitExpression(node.expression, parenthesizer.parenthesizeOperandOfPrefixUnary); } - function emitTypeOfExpression(node: TypeOfExpression) { - emitTokenWithComment(SyntaxKind.TypeOfKeyword, node.pos, writeKeyword, node); + function emitTypeOfExpression(node: ts.TypeOfExpression) { + emitTokenWithComment(ts.SyntaxKind.TypeOfKeyword, node.pos, writeKeyword, node); writeSpace(); emitExpression(node.expression, parenthesizer.parenthesizeOperandOfPrefixUnary); } - function emitVoidExpression(node: VoidExpression) { - emitTokenWithComment(SyntaxKind.VoidKeyword, node.pos, writeKeyword, node); + function emitVoidExpression(node: ts.VoidExpression) { + emitTokenWithComment(ts.SyntaxKind.VoidKeyword, node.pos, writeKeyword, node); writeSpace(); emitExpression(node.expression, parenthesizer.parenthesizeOperandOfPrefixUnary); } - function emitAwaitExpression(node: AwaitExpression) { - emitTokenWithComment(SyntaxKind.AwaitKeyword, node.pos, writeKeyword, node); + function emitAwaitExpression(node: ts.AwaitExpression) { + emitTokenWithComment(ts.SyntaxKind.AwaitKeyword, node.pos, writeKeyword, node); writeSpace(); emitExpression(node.expression, parenthesizer.parenthesizeOperandOfPrefixUnary); } - function emitPrefixUnaryExpression(node: PrefixUnaryExpression) { + function emitPrefixUnaryExpression(node: ts.PrefixUnaryExpression) { writeTokenText(node.operator, writeOperator); if (shouldEmitWhitespaceBeforeOperand(node)) { writeSpace(); @@ -2641,7 +2572,7 @@ namespace ts { emitExpression(node.operand, parenthesizer.parenthesizeOperandOfPrefixUnary); } - function shouldEmitWhitespaceBeforeOperand(node: PrefixUnaryExpression) { + function shouldEmitWhitespaceBeforeOperand(node: ts.PrefixUnaryExpression) { // In some cases, we need to emit a space between the operator and the operand. One obvious case // is when the operator is an identifier, like delete or typeof. We also need to do this for plus // and minus expressions in certain cases. Specifically, consider the following two cases (parens @@ -2655,12 +2586,12 @@ namespace ts { // expression a prefix increment whose operand is a plus expression - (++(+x)) // The same is true of minus of course. const operand = node.operand; - return operand.kind === SyntaxKind.PrefixUnaryExpression - && ((node.operator === SyntaxKind.PlusToken && ((operand as PrefixUnaryExpression).operator === SyntaxKind.PlusToken || (operand as PrefixUnaryExpression).operator === SyntaxKind.PlusPlusToken)) - || (node.operator === SyntaxKind.MinusToken && ((operand as PrefixUnaryExpression).operator === SyntaxKind.MinusToken || (operand as PrefixUnaryExpression).operator === SyntaxKind.MinusMinusToken))); + return operand.kind === ts.SyntaxKind.PrefixUnaryExpression + && ((node.operator === ts.SyntaxKind.PlusToken && ((operand as ts.PrefixUnaryExpression).operator === ts.SyntaxKind.PlusToken || (operand as ts.PrefixUnaryExpression).operator === ts.SyntaxKind.PlusPlusToken)) + || (node.operator === ts.SyntaxKind.MinusToken && ((operand as ts.PrefixUnaryExpression).operator === ts.SyntaxKind.MinusToken || (operand as ts.PrefixUnaryExpression).operator === ts.SyntaxKind.MinusMinusToken))); } - function emitPostfixUnaryExpression(node: PostfixUnaryExpression) { + function emitPostfixUnaryExpression(node: ts.PostfixUnaryExpression) { emitExpression(node.operand, parenthesizer.parenthesizeOperandOfPostfixUnary); writeTokenText(node.operator, writeOperator); } @@ -2676,9 +2607,8 @@ namespace ts { shouldEmitSourceMapsStack: boolean[]; } - return createBinaryExpressionTrampoline(onEnter, onLeft, onOperator, onRight, onExit, /*foldState*/ undefined); - - function onEnter(node: BinaryExpression, state: WorkArea | undefined) { + return ts.createBinaryExpressionTrampoline(onEnter, onLeft, onOperator, onRight, onExit, /*foldState*/ undefined); + function onEnter(node: ts.BinaryExpression, state: WorkArea | undefined) { if (state) { state.stackIndex++; state.preserveSourceNewlinesStack[state.stackIndex] = preserveSourceNewlines; @@ -2688,8 +2618,10 @@ namespace ts { const emitComments = state.shouldEmitCommentsStack[state.stackIndex] = shouldEmitComments(node); const emitSourceMaps = state.shouldEmitSourceMapsStack[state.stackIndex] = shouldEmitSourceMaps(node); onBeforeEmitNode?.(node); - if (emitComments) emitCommentsBeforeNode(node); - if (emitSourceMaps) emitSourceMapsBeforeNode(node); + if (emitComments) + emitCommentsBeforeNode(node); + if (emitSourceMaps) + emitSourceMapsBeforeNode(node); beforeEmitNode(node); } else { @@ -2706,26 +2638,26 @@ namespace ts { return state; } - function onLeft(next: Expression, _workArea: WorkArea, parent: BinaryExpression) { + function onLeft(next: ts.Expression, _workArea: WorkArea, parent: ts.BinaryExpression) { return maybeEmitExpression(next, parent, "left"); } - function onOperator(operatorToken: BinaryOperatorToken, _state: WorkArea, node: BinaryExpression) { - const isCommaOperator = operatorToken.kind !== SyntaxKind.CommaToken; + function onOperator(operatorToken: ts.BinaryOperatorToken, _state: WorkArea, node: ts.BinaryExpression) { + const isCommaOperator = operatorToken.kind !== ts.SyntaxKind.CommaToken; const linesBeforeOperator = getLinesBetweenNodes(node, node.left, operatorToken); const linesAfterOperator = getLinesBetweenNodes(node, operatorToken, node.right); writeLinesAndIndent(linesBeforeOperator, isCommaOperator); emitLeadingCommentsOfPosition(operatorToken.pos); - writeTokenNode(operatorToken, operatorToken.kind === SyntaxKind.InKeyword ? writeKeyword : writeOperator); + writeTokenNode(operatorToken, operatorToken.kind === ts.SyntaxKind.InKeyword ? writeKeyword : writeOperator); emitTrailingCommentsOfPosition(operatorToken.end, /*prefixSpace*/ true); // Binary operators should have a space before the comment starts writeLinesAndIndent(linesAfterOperator, /*writeSpaceIfNotIndenting*/ true); } - function onRight(next: Expression, _workArea: WorkArea, parent: BinaryExpression) { + function onRight(next: ts.Expression, _workArea: WorkArea, parent: ts.BinaryExpression) { return maybeEmitExpression(next, parent, "right"); } - function onExit(node: BinaryExpression, state: WorkArea) { + function onExit(node: ts.BinaryExpression, state: WorkArea) { const linesBeforeOperator = getLinesBetweenNodes(node, node.left, node.operatorToken); const linesAfterOperator = getLinesBetweenNodes(node, node.operatorToken, node.right); decreaseIndentIf(linesBeforeOperator, linesAfterOperator); @@ -2737,40 +2669,42 @@ namespace ts { const shouldEmitComments = state.shouldEmitCommentsStack[state.stackIndex]; const shouldEmitSourceMaps = state.shouldEmitSourceMapsStack[state.stackIndex]; afterEmitNode(savedPreserveSourceNewlines); - if (shouldEmitSourceMaps) emitSourceMapsAfterNode(node); - if (shouldEmitComments) emitCommentsAfterNode(node, savedContainerPos, savedContainerEnd, savedDeclarationListContainerEnd); + if (shouldEmitSourceMaps) + emitSourceMapsAfterNode(node); + if (shouldEmitComments) + emitCommentsAfterNode(node, savedContainerPos, savedContainerEnd, savedDeclarationListContainerEnd); onAfterEmitNode?.(node); state.stackIndex--; } } - function maybeEmitExpression(next: Expression, parent: BinaryExpression, side: "left" | "right") { + function maybeEmitExpression(next: ts.Expression, parent: ts.BinaryExpression, side: "left" | "right") { const parenthesizerRule = side === "left" ? parenthesizer.getParenthesizeLeftSideOfBinaryForOperator(parent.operatorToken.kind) : parenthesizer.getParenthesizeRightSideOfBinaryForOperator(parent.operatorToken.kind); - let pipelinePhase = getPipelinePhase(PipelinePhase.Notification, EmitHint.Expression, next); + let pipelinePhase = getPipelinePhase(PipelinePhase.Notification, ts.EmitHint.Expression, next); if (pipelinePhase === pipelineEmitWithSubstitution) { - Debug.assertIsDefined(lastSubstitution); - next = parenthesizerRule(cast(lastSubstitution, isExpression)); - pipelinePhase = getNextPipelinePhase(PipelinePhase.Substitution, EmitHint.Expression, next); + ts.Debug.assertIsDefined(lastSubstitution); + next = parenthesizerRule(ts.cast(lastSubstitution, ts.isExpression)); + pipelinePhase = getNextPipelinePhase(PipelinePhase.Substitution, ts.EmitHint.Expression, next); lastSubstitution = undefined; } if (pipelinePhase === pipelineEmitWithComments || pipelinePhase === pipelineEmitWithSourceMaps || pipelinePhase === pipelineEmitWithHint) { - if (isBinaryExpression(next)) { + if (ts.isBinaryExpression(next)) { return next; } } currentParenthesizerRule = parenthesizerRule; - pipelinePhase(EmitHint.Expression, next); + pipelinePhase(ts.EmitHint.Expression, next); } } - function emitConditionalExpression(node: ConditionalExpression) { + function emitConditionalExpression(node: ts.ConditionalExpression) { const linesBeforeQuestion = getLinesBetweenNodes(node, node.condition, node.questionToken); const linesAfterQuestion = getLinesBetweenNodes(node, node.questionToken, node.whenTrue); const linesBeforeColon = getLinesBetweenNodes(node, node.whenTrue, node.colonToken); @@ -2790,33 +2724,33 @@ namespace ts { decreaseIndentIf(linesBeforeColon, linesAfterColon); } - function emitTemplateExpression(node: TemplateExpression) { + function emitTemplateExpression(node: ts.TemplateExpression) { emit(node.head); - emitList(node, node.templateSpans, ListFormat.TemplateExpressionSpans); + emitList(node, node.templateSpans, ts.ListFormat.TemplateExpressionSpans); } - function emitYieldExpression(node: YieldExpression) { - emitTokenWithComment(SyntaxKind.YieldKeyword, node.pos, writeKeyword, node); + function emitYieldExpression(node: ts.YieldExpression) { + emitTokenWithComment(ts.SyntaxKind.YieldKeyword, node.pos, writeKeyword, node); emit(node.asteriskToken); emitExpressionWithLeadingSpace(node.expression && parenthesizeExpressionForNoAsi(node.expression), parenthesizeExpressionForNoAsiAndDisallowedComma); } - function emitSpreadElement(node: SpreadElement) { - emitTokenWithComment(SyntaxKind.DotDotDotToken, node.pos, writePunctuation, node); + function emitSpreadElement(node: ts.SpreadElement) { + emitTokenWithComment(ts.SyntaxKind.DotDotDotToken, node.pos, writePunctuation, node); emitExpression(node.expression, parenthesizer.parenthesizeExpressionForDisallowedComma); } - function emitClassExpression(node: ClassExpression) { + function emitClassExpression(node: ts.ClassExpression) { generateNameIfNeeded(node.name); emitClassDeclarationOrExpression(node); } - function emitExpressionWithTypeArguments(node: ExpressionWithTypeArguments) { + function emitExpressionWithTypeArguments(node: ts.ExpressionWithTypeArguments) { emitExpression(node.expression, parenthesizer.parenthesizeLeftSideOfAccess); emitTypeArguments(node, node.typeArguments); } - function emitAsExpression(node: AsExpression) { + function emitAsExpression(node: ts.AsExpression) { emitExpression(node.expression, /*parenthesizerRules*/ undefined); if (node.type) { writeSpace(); @@ -2826,12 +2760,12 @@ namespace ts { } } - function emitNonNullExpression(node: NonNullExpression) { + function emitNonNullExpression(node: ts.NonNullExpression) { emitExpression(node.expression, parenthesizer.parenthesizeLeftSideOfAccess); writeOperator("!"); } - function emitMetaProperty(node: MetaProperty) { + function emitMetaProperty(node: ts.MetaProperty) { writeToken(node.keywordToken, node.pos, writePunctuation); writePunctuation("."); emit(node.name); @@ -2841,7 +2775,7 @@ namespace ts { // Misc // - function emitTemplateSpan(node: TemplateSpan) { + function emitTemplateSpan(node: ts.TemplateSpan) { emitExpression(node.expression); emit(node.literal); } @@ -2850,18 +2784,18 @@ namespace ts { // Statements // - function emitBlock(node: Block) { + function emitBlock(node: ts.Block) { emitBlockStatements(node, /*forceSingleLine*/ !node.multiLine && isEmptyBlock(node)); } - function emitBlockStatements(node: BlockLike, forceSingleLine: boolean) { - emitTokenWithComment(SyntaxKind.OpenBraceToken, node.pos, writePunctuation, /*contextNode*/ node); - const format = forceSingleLine || getEmitFlags(node) & EmitFlags.SingleLine ? ListFormat.SingleLineBlockStatements : ListFormat.MultiLineBlockStatements; + function emitBlockStatements(node: ts.BlockLike, forceSingleLine: boolean) { + emitTokenWithComment(ts.SyntaxKind.OpenBraceToken, node.pos, writePunctuation, /*contextNode*/ node); + const format = forceSingleLine || ts.getEmitFlags(node) & ts.EmitFlags.SingleLine ? ts.ListFormat.SingleLineBlockStatements : ts.ListFormat.MultiLineBlockStatements; emitList(node, node.statements, format); - emitTokenWithComment(SyntaxKind.CloseBraceToken, node.statements.end, writePunctuation, /*contextNode*/ node, /*indentLeading*/ !!(format & ListFormat.MultiLine)); + emitTokenWithComment(ts.SyntaxKind.CloseBraceToken, node.statements.end, writePunctuation, /*contextNode*/ node, /*indentLeading*/ !!(format & ts.ListFormat.MultiLine)); } - function emitVariableStatement(node: VariableStatement) { + function emitVariableStatement(node: ts.VariableStatement) { emitModifiers(node, node.modifiers); emit(node.declarationList); writeTrailingSemicolon(); @@ -2878,26 +2812,26 @@ namespace ts { } } - function emitExpressionStatement(node: ExpressionStatement) { + function emitExpressionStatement(node: ts.ExpressionStatement) { emitExpression(node.expression, parenthesizer.parenthesizeExpressionOfExpressionStatement); // Emit semicolon in non json files // or if json file that created synthesized expression(eg.define expression statement when --out and amd code generation) - if (!currentSourceFile || !isJsonSourceFile(currentSourceFile) || nodeIsSynthesized(node.expression)) { + if (!currentSourceFile || !ts.isJsonSourceFile(currentSourceFile) || ts.nodeIsSynthesized(node.expression)) { writeTrailingSemicolon(); } } - function emitIfStatement(node: IfStatement) { - const openParenPos = emitTokenWithComment(SyntaxKind.IfKeyword, node.pos, writeKeyword, node); + function emitIfStatement(node: ts.IfStatement) { + const openParenPos = emitTokenWithComment(ts.SyntaxKind.IfKeyword, node.pos, writeKeyword, node); writeSpace(); - emitTokenWithComment(SyntaxKind.OpenParenToken, openParenPos, writePunctuation, node); + emitTokenWithComment(ts.SyntaxKind.OpenParenToken, openParenPos, writePunctuation, node); emitExpression(node.expression); - emitTokenWithComment(SyntaxKind.CloseParenToken, node.expression.end, writePunctuation, node); + emitTokenWithComment(ts.SyntaxKind.CloseParenToken, node.expression.end, writePunctuation, node); emitEmbeddedStatement(node, node.thenStatement); if (node.elseStatement) { writeLineOrSpace(node, node.thenStatement, node.elseStatement); - emitTokenWithComment(SyntaxKind.ElseKeyword, node.thenStatement.end, writeKeyword, node); - if (node.elseStatement.kind === SyntaxKind.IfStatement) { + emitTokenWithComment(ts.SyntaxKind.ElseKeyword, node.thenStatement.end, writeKeyword, node); + if (node.elseStatement.kind === ts.SyntaxKind.IfStatement) { writeSpace(); emit(node.elseStatement); } @@ -2907,18 +2841,18 @@ namespace ts { } } - function emitWhileClause(node: WhileStatement | DoStatement, startPos: number) { - const openParenPos = emitTokenWithComment(SyntaxKind.WhileKeyword, startPos, writeKeyword, node); + function emitWhileClause(node: ts.WhileStatement | ts.DoStatement, startPos: number) { + const openParenPos = emitTokenWithComment(ts.SyntaxKind.WhileKeyword, startPos, writeKeyword, node); writeSpace(); - emitTokenWithComment(SyntaxKind.OpenParenToken, openParenPos, writePunctuation, node); + emitTokenWithComment(ts.SyntaxKind.OpenParenToken, openParenPos, writePunctuation, node); emitExpression(node.expression); - emitTokenWithComment(SyntaxKind.CloseParenToken, node.expression.end, writePunctuation, node); + emitTokenWithComment(ts.SyntaxKind.CloseParenToken, node.expression.end, writePunctuation, node); } - function emitDoStatement(node: DoStatement) { - emitTokenWithComment(SyntaxKind.DoKeyword, node.pos, writeKeyword, node); + function emitDoStatement(node: ts.DoStatement) { + emitTokenWithComment(ts.SyntaxKind.DoKeyword, node.pos, writeKeyword, node); emitEmbeddedStatement(node, node.statement); - if (isBlock(node.statement) && !preserveSourceNewlines) { + if (ts.isBlock(node.statement) && !preserveSourceNewlines) { writeSpace(); } else { @@ -2929,54 +2863,54 @@ namespace ts { writeTrailingSemicolon(); } - function emitWhileStatement(node: WhileStatement) { + function emitWhileStatement(node: ts.WhileStatement) { emitWhileClause(node, node.pos); emitEmbeddedStatement(node, node.statement); } - function emitForStatement(node: ForStatement) { - const openParenPos = emitTokenWithComment(SyntaxKind.ForKeyword, node.pos, writeKeyword, node); + function emitForStatement(node: ts.ForStatement) { + const openParenPos = emitTokenWithComment(ts.SyntaxKind.ForKeyword, node.pos, writeKeyword, node); writeSpace(); - let pos = emitTokenWithComment(SyntaxKind.OpenParenToken, openParenPos, writePunctuation, /*contextNode*/ node); + let pos = emitTokenWithComment(ts.SyntaxKind.OpenParenToken, openParenPos, writePunctuation, /*contextNode*/ node); emitForBinding(node.initializer); - pos = emitTokenWithComment(SyntaxKind.SemicolonToken, node.initializer ? node.initializer.end : pos, writePunctuation, node); + pos = emitTokenWithComment(ts.SyntaxKind.SemicolonToken, node.initializer ? node.initializer.end : pos, writePunctuation, node); emitExpressionWithLeadingSpace(node.condition); - pos = emitTokenWithComment(SyntaxKind.SemicolonToken, node.condition ? node.condition.end : pos, writePunctuation, node); + pos = emitTokenWithComment(ts.SyntaxKind.SemicolonToken, node.condition ? node.condition.end : pos, writePunctuation, node); emitExpressionWithLeadingSpace(node.incrementor); - emitTokenWithComment(SyntaxKind.CloseParenToken, node.incrementor ? node.incrementor.end : pos, writePunctuation, node); + emitTokenWithComment(ts.SyntaxKind.CloseParenToken, node.incrementor ? node.incrementor.end : pos, writePunctuation, node); emitEmbeddedStatement(node, node.statement); } - function emitForInStatement(node: ForInStatement) { - const openParenPos = emitTokenWithComment(SyntaxKind.ForKeyword, node.pos, writeKeyword, node); + function emitForInStatement(node: ts.ForInStatement) { + const openParenPos = emitTokenWithComment(ts.SyntaxKind.ForKeyword, node.pos, writeKeyword, node); writeSpace(); - emitTokenWithComment(SyntaxKind.OpenParenToken, openParenPos, writePunctuation, node); + emitTokenWithComment(ts.SyntaxKind.OpenParenToken, openParenPos, writePunctuation, node); emitForBinding(node.initializer); writeSpace(); - emitTokenWithComment(SyntaxKind.InKeyword, node.initializer.end, writeKeyword, node); + emitTokenWithComment(ts.SyntaxKind.InKeyword, node.initializer.end, writeKeyword, node); writeSpace(); emitExpression(node.expression); - emitTokenWithComment(SyntaxKind.CloseParenToken, node.expression.end, writePunctuation, node); + emitTokenWithComment(ts.SyntaxKind.CloseParenToken, node.expression.end, writePunctuation, node); emitEmbeddedStatement(node, node.statement); } - function emitForOfStatement(node: ForOfStatement) { - const openParenPos = emitTokenWithComment(SyntaxKind.ForKeyword, node.pos, writeKeyword, node); + function emitForOfStatement(node: ts.ForOfStatement) { + const openParenPos = emitTokenWithComment(ts.SyntaxKind.ForKeyword, node.pos, writeKeyword, node); writeSpace(); emitWithTrailingSpace(node.awaitModifier); - emitTokenWithComment(SyntaxKind.OpenParenToken, openParenPos, writePunctuation, node); + emitTokenWithComment(ts.SyntaxKind.OpenParenToken, openParenPos, writePunctuation, node); emitForBinding(node.initializer); writeSpace(); - emitTokenWithComment(SyntaxKind.OfKeyword, node.initializer.end, writeKeyword, node); + emitTokenWithComment(ts.SyntaxKind.OfKeyword, node.initializer.end, writeKeyword, node); writeSpace(); emitExpression(node.expression); - emitTokenWithComment(SyntaxKind.CloseParenToken, node.expression.end, writePunctuation, node); + emitTokenWithComment(ts.SyntaxKind.CloseParenToken, node.expression.end, writePunctuation, node); emitEmbeddedStatement(node, node.statement); } - function emitForBinding(node: VariableDeclarationList | Expression | undefined) { + function emitForBinding(node: ts.VariableDeclarationList | ts.Expression | undefined) { if (node !== undefined) { - if (node.kind === SyntaxKind.VariableDeclarationList) { + if (node.kind === ts.SyntaxKind.VariableDeclarationList) { emit(node); } else { @@ -2985,27 +2919,27 @@ namespace ts { } } - function emitContinueStatement(node: ContinueStatement) { - emitTokenWithComment(SyntaxKind.ContinueKeyword, node.pos, writeKeyword, node); + function emitContinueStatement(node: ts.ContinueStatement) { + emitTokenWithComment(ts.SyntaxKind.ContinueKeyword, node.pos, writeKeyword, node); emitWithLeadingSpace(node.label); writeTrailingSemicolon(); } - function emitBreakStatement(node: BreakStatement) { - emitTokenWithComment(SyntaxKind.BreakKeyword, node.pos, writeKeyword, node); + function emitBreakStatement(node: ts.BreakStatement) { + emitTokenWithComment(ts.SyntaxKind.BreakKeyword, node.pos, writeKeyword, node); emitWithLeadingSpace(node.label); writeTrailingSemicolon(); } - function emitTokenWithComment(token: SyntaxKind, pos: number, writer: (s: string) => void, contextNode: Node, indentLeading?: boolean) { - const node = getParseTreeNode(contextNode); + function emitTokenWithComment(token: ts.SyntaxKind, pos: number, writer: (s: string) => void, contextNode: ts.Node, indentLeading?: boolean) { + const node = ts.getParseTreeNode(contextNode); const isSimilarNode = node && node.kind === contextNode.kind; const startPos = pos; if (isSimilarNode && currentSourceFile) { - pos = skipTrivia(currentSourceFile.text, pos); + pos = ts.skipTrivia(currentSourceFile.text, pos); } if (isSimilarNode && contextNode.pos !== startPos) { - const needsIndent = indentLeading && currentSourceFile && !positionsAreOnSameLine(startPos, pos, currentSourceFile); + const needsIndent = indentLeading && currentSourceFile && !ts.positionsAreOnSameLine(startPos, pos, currentSourceFile); if (needsIndent) { increaseIndent(); } @@ -3016,23 +2950,27 @@ namespace ts { } pos = writeTokenText(token, writer, pos); if (isSimilarNode && contextNode.end !== pos) { - const isJsxExprContext = contextNode.kind === SyntaxKind.JsxExpression; + const isJsxExprContext = contextNode.kind === ts.SyntaxKind.JsxExpression; emitTrailingCommentsOfPosition(pos, /*prefixSpace*/ !isJsxExprContext, /*forceNoNewline*/ isJsxExprContext); } return pos; } - function commentWillEmitNewLine(node: CommentRange) { - return node.kind === SyntaxKind.SingleLineCommentTrivia || !!node.hasTrailingNewLine; + function commentWillEmitNewLine(node: ts.CommentRange) { + return node.kind === ts.SyntaxKind.SingleLineCommentTrivia || !!node.hasTrailingNewLine; } - function willEmitLeadingNewLine(node: Expression): boolean { - if (!currentSourceFile) return false; - if (some(getLeadingCommentRanges(currentSourceFile.text, node.pos), commentWillEmitNewLine)) return true; - if (some(getSyntheticLeadingComments(node), commentWillEmitNewLine)) return true; - if (isPartiallyEmittedExpression(node)) { + function willEmitLeadingNewLine(node: ts.Expression): boolean { + if (!currentSourceFile) + return false; + if (ts.some(ts.getLeadingCommentRanges(currentSourceFile.text, node.pos), commentWillEmitNewLine)) + return true; + if (ts.some(ts.getSyntheticLeadingComments(node), commentWillEmitNewLine)) + return true; + if (ts.isPartiallyEmittedExpression(node)) { if (node.pos !== node.expression.pos) { - if (some(getTrailingCommentRanges(currentSourceFile.text, node.expression.pos), commentWillEmitNewLine)) return true; + if (ts.some(ts.getTrailingCommentRanges(currentSourceFile.text, node.expression.pos), commentWillEmitNewLine)) + return true; } return willEmitLeadingNewLine(node.expression); } @@ -3043,65 +2981,65 @@ namespace ts { * Wraps an expression in parens if we would emit a leading comment that would introduce a line separator * between the node and its parent. */ - function parenthesizeExpressionForNoAsi(node: Expression) { - if (!commentsDisabled && isPartiallyEmittedExpression(node) && willEmitLeadingNewLine(node)) { - const parseNode = getParseTreeNode(node); - if (parseNode && isParenthesizedExpression(parseNode)) { + function parenthesizeExpressionForNoAsi(node: ts.Expression) { + if (!commentsDisabled && ts.isPartiallyEmittedExpression(node) && willEmitLeadingNewLine(node)) { + const parseNode = ts.getParseTreeNode(node); + if (parseNode && ts.isParenthesizedExpression(parseNode)) { // If the original node was a parenthesized expression, restore it to preserve comment and source map emit - const parens = factory.createParenthesizedExpression(node.expression); - setOriginalNode(parens, node); - setTextRange(parens, parseNode); + const parens = ts.factory.createParenthesizedExpression(node.expression); + ts.setOriginalNode(parens, node); + ts.setTextRange(parens, parseNode); return parens; } - return factory.createParenthesizedExpression(node); + return ts.factory.createParenthesizedExpression(node); } return node; } - function parenthesizeExpressionForNoAsiAndDisallowedComma(node: Expression) { + function parenthesizeExpressionForNoAsiAndDisallowedComma(node: ts.Expression) { return parenthesizeExpressionForNoAsi(parenthesizer.parenthesizeExpressionForDisallowedComma(node)); } - function emitReturnStatement(node: ReturnStatement) { - emitTokenWithComment(SyntaxKind.ReturnKeyword, node.pos, writeKeyword, /*contextNode*/ node); + function emitReturnStatement(node: ts.ReturnStatement) { + emitTokenWithComment(ts.SyntaxKind.ReturnKeyword, node.pos, writeKeyword, /*contextNode*/ node); emitExpressionWithLeadingSpace(node.expression && parenthesizeExpressionForNoAsi(node.expression), parenthesizeExpressionForNoAsi); writeTrailingSemicolon(); } - function emitWithStatement(node: WithStatement) { - const openParenPos = emitTokenWithComment(SyntaxKind.WithKeyword, node.pos, writeKeyword, node); + function emitWithStatement(node: ts.WithStatement) { + const openParenPos = emitTokenWithComment(ts.SyntaxKind.WithKeyword, node.pos, writeKeyword, node); writeSpace(); - emitTokenWithComment(SyntaxKind.OpenParenToken, openParenPos, writePunctuation, node); + emitTokenWithComment(ts.SyntaxKind.OpenParenToken, openParenPos, writePunctuation, node); emitExpression(node.expression); - emitTokenWithComment(SyntaxKind.CloseParenToken, node.expression.end, writePunctuation, node); + emitTokenWithComment(ts.SyntaxKind.CloseParenToken, node.expression.end, writePunctuation, node); emitEmbeddedStatement(node, node.statement); } - function emitSwitchStatement(node: SwitchStatement) { - const openParenPos = emitTokenWithComment(SyntaxKind.SwitchKeyword, node.pos, writeKeyword, node); + function emitSwitchStatement(node: ts.SwitchStatement) { + const openParenPos = emitTokenWithComment(ts.SyntaxKind.SwitchKeyword, node.pos, writeKeyword, node); writeSpace(); - emitTokenWithComment(SyntaxKind.OpenParenToken, openParenPos, writePunctuation, node); + emitTokenWithComment(ts.SyntaxKind.OpenParenToken, openParenPos, writePunctuation, node); emitExpression(node.expression); - emitTokenWithComment(SyntaxKind.CloseParenToken, node.expression.end, writePunctuation, node); + emitTokenWithComment(ts.SyntaxKind.CloseParenToken, node.expression.end, writePunctuation, node); writeSpace(); emit(node.caseBlock); } - function emitLabeledStatement(node: LabeledStatement) { + function emitLabeledStatement(node: ts.LabeledStatement) { emit(node.label); - emitTokenWithComment(SyntaxKind.ColonToken, node.label.end, writePunctuation, node); + emitTokenWithComment(ts.SyntaxKind.ColonToken, node.label.end, writePunctuation, node); writeSpace(); emit(node.statement); } - function emitThrowStatement(node: ThrowStatement) { - emitTokenWithComment(SyntaxKind.ThrowKeyword, node.pos, writeKeyword, node); + function emitThrowStatement(node: ts.ThrowStatement) { + emitTokenWithComment(ts.SyntaxKind.ThrowKeyword, node.pos, writeKeyword, node); emitExpressionWithLeadingSpace(parenthesizeExpressionForNoAsi(node.expression), parenthesizeExpressionForNoAsi); writeTrailingSemicolon(); } - function emitTryStatement(node: TryStatement) { - emitTokenWithComment(SyntaxKind.TryKeyword, node.pos, writeKeyword, node); + function emitTryStatement(node: ts.TryStatement) { + emitTokenWithComment(ts.SyntaxKind.TryKeyword, node.pos, writeKeyword, node); writeSpace(); emit(node.tryBlock); if (node.catchClause) { @@ -3110,14 +3048,14 @@ namespace ts { } if (node.finallyBlock) { writeLineOrSpace(node, node.catchClause || node.tryBlock, node.finallyBlock); - emitTokenWithComment(SyntaxKind.FinallyKeyword, (node.catchClause || node.tryBlock).end, writeKeyword, node); + emitTokenWithComment(ts.SyntaxKind.FinallyKeyword, (node.catchClause || node.tryBlock).end, writeKeyword, node); writeSpace(); emit(node.finallyBlock); } } - function emitDebuggerStatement(node: DebuggerStatement) { - writeToken(SyntaxKind.DebuggerKeyword, node.pos, writeKeyword); + function emitDebuggerStatement(node: ts.DebuggerStatement) { + writeToken(ts.SyntaxKind.DebuggerKeyword, node.pos, writeKeyword); writeTrailingSemicolon(); } @@ -3125,24 +3063,24 @@ namespace ts { // Declarations // - function emitVariableDeclaration(node: VariableDeclaration) { + function emitVariableDeclaration(node: ts.VariableDeclaration) { emit(node.name); emit(node.exclamationToken); emitTypeAnnotation(node.type); emitInitializer(node.initializer, node.type?.end ?? node.name.emitNode?.typeNode?.end ?? node.name.end, node, parenthesizer.parenthesizeExpressionForDisallowedComma); } - function emitVariableDeclarationList(node: VariableDeclarationList) { - writeKeyword(isLet(node) ? "let" : isVarConst(node) ? "const" : "var"); + function emitVariableDeclarationList(node: ts.VariableDeclarationList) { + writeKeyword(ts.isLet(node) ? "let" : ts.isVarConst(node) ? "const" : "var"); writeSpace(); - emitList(node, node.declarations, ListFormat.VariableDeclarationList); + emitList(node, node.declarations, ts.ListFormat.VariableDeclarationList); } - function emitFunctionDeclaration(node: FunctionDeclaration) { + function emitFunctionDeclaration(node: ts.FunctionDeclaration) { emitFunctionDeclarationOrExpression(node); } - function emitFunctionDeclarationOrExpression(node: FunctionDeclaration | FunctionExpression) { + function emitFunctionDeclarationOrExpression(node: ts.FunctionDeclaration | ts.FunctionExpression) { emitDecorators(node, node.decorators); emitModifiers(node, node.modifiers); writeKeyword("function"); @@ -3152,17 +3090,17 @@ namespace ts { emitSignatureAndBody(node, emitSignatureHead); } - function emitSignatureAndBody(node: FunctionLikeDeclaration, emitSignatureHead: (node: SignatureDeclaration) => void) { + function emitSignatureAndBody(node: ts.FunctionLikeDeclaration, emitSignatureHead: (node: ts.SignatureDeclaration) => void) { const body = node.body; if (body) { - if (isBlock(body)) { - const indentedFlag = getEmitFlags(node) & EmitFlags.Indented; + if (ts.isBlock(body)) { + const indentedFlag = ts.getEmitFlags(node) & ts.EmitFlags.Indented; if (indentedFlag) { increaseIndent(); } pushNameGenerationScope(node); - forEach(node.parameters, generateNames); + ts.forEach(node.parameters, generateNames); generateNames(node.body); emitSignatureHead(node); @@ -3186,13 +3124,13 @@ namespace ts { } - function emitSignatureHead(node: FunctionDeclaration | FunctionExpression | MethodDeclaration | AccessorDeclaration | ConstructorDeclaration) { + function emitSignatureHead(node: ts.FunctionDeclaration | ts.FunctionExpression | ts.MethodDeclaration | ts.AccessorDeclaration | ts.ConstructorDeclaration) { emitTypeParameters(node, node.typeParameters); emitParameters(node, node.parameters); emitTypeAnnotation(node.type); } - function shouldEmitBlockFunctionBodyOnSingleLine(body: Block) { + function shouldEmitBlockFunctionBodyOnSingleLine(body: ts.Block) { // We must emit a function body as a single-line body in the following case: // * The body has NodeEmitFlags.SingleLine specified. @@ -3201,7 +3139,7 @@ namespace ts { // * A non-synthesized body's start and end position are on different lines. // * Any statement in the body starts on a new line. - if (getEmitFlags(body) & EmitFlags.SingleLine) { + if (ts.getEmitFlags(body) & ts.EmitFlags.SingleLine) { return true; } @@ -3209,18 +3147,18 @@ namespace ts { return false; } - if (!nodeIsSynthesized(body) && currentSourceFile && !rangeIsOnSingleLine(body, currentSourceFile)) { + if (!ts.nodeIsSynthesized(body) && currentSourceFile && !ts.rangeIsOnSingleLine(body, currentSourceFile)) { return false; } - if (getLeadingLineTerminatorCount(body, body.statements, ListFormat.PreserveLines) - || getClosingLineTerminatorCount(body, body.statements, ListFormat.PreserveLines)) { + if (getLeadingLineTerminatorCount(body, body.statements, ts.ListFormat.PreserveLines) + || getClosingLineTerminatorCount(body, body.statements, ts.ListFormat.PreserveLines)) { return false; } - let previousStatement: Statement | undefined; + let previousStatement: ts.Statement | undefined; for (const statement of body.statements) { - if (getSeparatingLineTerminatorCount(previousStatement, statement, ListFormat.PreserveLines) > 0) { + if (getSeparatingLineTerminatorCount(previousStatement, statement, ts.ListFormat.PreserveLines) > 0) { return false; } @@ -3230,7 +3168,7 @@ namespace ts { return true; } - function emitBlockFunctionBody(body: Block) { + function emitBlockFunctionBody(body: ts.Block) { onBeforeEmitNode?.(body); writeSpace(); writePunctuation("{"); @@ -3243,35 +3181,35 @@ namespace ts { emitBodyWithDetachedComments(body, body.statements, emitBlockFunctionBody); decreaseIndent(); - writeToken(SyntaxKind.CloseBraceToken, body.statements.end, writePunctuation, body); + writeToken(ts.SyntaxKind.CloseBraceToken, body.statements.end, writePunctuation, body); onAfterEmitNode?.(body); } - function emitBlockFunctionBodyOnSingleLine(body: Block) { + function emitBlockFunctionBodyOnSingleLine(body: ts.Block) { emitBlockFunctionBodyWorker(body, /*emitBlockFunctionBodyOnSingleLine*/ true); } - function emitBlockFunctionBodyWorker(body: Block, emitBlockFunctionBodyOnSingleLine?: boolean) { + function emitBlockFunctionBodyWorker(body: ts.Block, emitBlockFunctionBodyOnSingleLine?: boolean) { // Emit all the prologue directives (like "use strict"). const statementOffset = emitPrologueDirectives(body.statements); const pos = writer.getTextPos(); emitHelpers(body); if (statementOffset === 0 && pos === writer.getTextPos() && emitBlockFunctionBodyOnSingleLine) { decreaseIndent(); - emitList(body, body.statements, ListFormat.SingleLineFunctionBodyStatements); + emitList(body, body.statements, ts.ListFormat.SingleLineFunctionBodyStatements); increaseIndent(); } else { - emitList(body, body.statements, ListFormat.MultiLineFunctionBodyStatements, /*parenthesizerRule*/ undefined, statementOffset); + emitList(body, body.statements, ts.ListFormat.MultiLineFunctionBodyStatements, /*parenthesizerRule*/ undefined, statementOffset); } } - function emitClassDeclaration(node: ClassDeclaration) { + function emitClassDeclaration(node: ts.ClassDeclaration) { emitClassDeclarationOrExpression(node); } - function emitClassDeclarationOrExpression(node: ClassDeclaration | ClassExpression) { - forEach(node.members, generateMemberNames); + function emitClassDeclarationOrExpression(node: ts.ClassDeclaration | ts.ClassExpression) { + ts.forEach(node.members, generateMemberNames); emitDecorators(node, node.decorators); emitModifiers(node, node.modifiers); @@ -3281,17 +3219,17 @@ namespace ts { emitIdentifierName(node.name); } - const indentedFlag = getEmitFlags(node) & EmitFlags.Indented; + const indentedFlag = ts.getEmitFlags(node) & ts.EmitFlags.Indented; if (indentedFlag) { increaseIndent(); } emitTypeParameters(node, node.typeParameters); - emitList(node, node.heritageClauses, ListFormat.ClassHeritageClauses); + emitList(node, node.heritageClauses, ts.ListFormat.ClassHeritageClauses); writeSpace(); writePunctuation("{"); - emitList(node, node.members, ListFormat.ClassMembers); + emitList(node, node.members, ts.ListFormat.ClassMembers); writePunctuation("}"); if (indentedFlag) { @@ -3299,21 +3237,21 @@ namespace ts { } } - function emitInterfaceDeclaration(node: InterfaceDeclaration) { + function emitInterfaceDeclaration(node: ts.InterfaceDeclaration) { emitDecorators(node, node.decorators); emitModifiers(node, node.modifiers); writeKeyword("interface"); writeSpace(); emit(node.name); emitTypeParameters(node, node.typeParameters); - emitList(node, node.heritageClauses, ListFormat.HeritageClauses); + emitList(node, node.heritageClauses, ts.ListFormat.HeritageClauses); writeSpace(); writePunctuation("{"); - emitList(node, node.members, ListFormat.InterfaceMembers); + emitList(node, node.members, ts.ListFormat.InterfaceMembers); writePunctuation("}"); } - function emitTypeAliasDeclaration(node: TypeAliasDeclaration) { + function emitTypeAliasDeclaration(node: ts.TypeAliasDeclaration) { emitDecorators(node, node.decorators); emitModifiers(node, node.modifiers); writeKeyword("type"); @@ -3327,7 +3265,7 @@ namespace ts { writeTrailingSemicolon(); } - function emitEnumDeclaration(node: EnumDeclaration) { + function emitEnumDeclaration(node: ts.EnumDeclaration) { emitModifiers(node, node.modifiers); writeKeyword("enum"); writeSpace(); @@ -3335,21 +3273,22 @@ namespace ts { writeSpace(); writePunctuation("{"); - emitList(node, node.members, ListFormat.EnumMembers); + emitList(node, node.members, ts.ListFormat.EnumMembers); writePunctuation("}"); } - function emitModuleDeclaration(node: ModuleDeclaration) { + function emitModuleDeclaration(node: ts.ModuleDeclaration) { emitModifiers(node, node.modifiers); - if (~node.flags & NodeFlags.GlobalAugmentation) { - writeKeyword(node.flags & NodeFlags.Namespace ? "namespace" : "module"); + if (~node.flags & ts.NodeFlags.GlobalAugmentation) { + writeKeyword(node.flags & ts.NodeFlags.Namespace ? "namespace" : "module"); writeSpace(); } emit(node.name); let body = node.body; - if (!body) return writeTrailingSemicolon(); - while (body && isModuleDeclaration(body)) { + if (!body) + return writeTrailingSemicolon(); + while (body && ts.isModuleDeclaration(body)) { writePunctuation("."); emit(body.name); body = body.body; @@ -3359,37 +3298,37 @@ namespace ts { emit(body); } - function emitModuleBlock(node: ModuleBlock) { + function emitModuleBlock(node: ts.ModuleBlock) { pushNameGenerationScope(node); - forEach(node.statements, generateNames); + ts.forEach(node.statements, generateNames); emitBlockStatements(node, /*forceSingleLine*/ isEmptyBlock(node)); popNameGenerationScope(node); } - function emitCaseBlock(node: CaseBlock) { - emitTokenWithComment(SyntaxKind.OpenBraceToken, node.pos, writePunctuation, node); - emitList(node, node.clauses, ListFormat.CaseBlockClauses); - emitTokenWithComment(SyntaxKind.CloseBraceToken, node.clauses.end, writePunctuation, node, /*indentLeading*/ true); + function emitCaseBlock(node: ts.CaseBlock) { + emitTokenWithComment(ts.SyntaxKind.OpenBraceToken, node.pos, writePunctuation, node); + emitList(node, node.clauses, ts.ListFormat.CaseBlockClauses); + emitTokenWithComment(ts.SyntaxKind.CloseBraceToken, node.clauses.end, writePunctuation, node, /*indentLeading*/ true); } - function emitImportEqualsDeclaration(node: ImportEqualsDeclaration) { + function emitImportEqualsDeclaration(node: ts.ImportEqualsDeclaration) { emitModifiers(node, node.modifiers); - emitTokenWithComment(SyntaxKind.ImportKeyword, node.modifiers ? node.modifiers.end : node.pos, writeKeyword, node); + emitTokenWithComment(ts.SyntaxKind.ImportKeyword, node.modifiers ? node.modifiers.end : node.pos, writeKeyword, node); writeSpace(); if (node.isTypeOnly) { - emitTokenWithComment(SyntaxKind.TypeKeyword, node.pos, writeKeyword, node); + emitTokenWithComment(ts.SyntaxKind.TypeKeyword, node.pos, writeKeyword, node); writeSpace(); } emit(node.name); writeSpace(); - emitTokenWithComment(SyntaxKind.EqualsToken, node.name.end, writePunctuation, node); + emitTokenWithComment(ts.SyntaxKind.EqualsToken, node.name.end, writePunctuation, node); writeSpace(); emitModuleReference(node.moduleReference); writeTrailingSemicolon(); } - function emitModuleReference(node: ModuleReference) { - if (node.kind === SyntaxKind.Identifier) { + function emitModuleReference(node: ts.ModuleReference) { + if (node.kind === ts.SyntaxKind.Identifier) { emitExpression(node); } else { @@ -3397,14 +3336,14 @@ namespace ts { } } - function emitImportDeclaration(node: ImportDeclaration) { + function emitImportDeclaration(node: ts.ImportDeclaration) { emitModifiers(node, node.modifiers); - emitTokenWithComment(SyntaxKind.ImportKeyword, node.modifiers ? node.modifiers.end : node.pos, writeKeyword, node); + emitTokenWithComment(ts.SyntaxKind.ImportKeyword, node.modifiers ? node.modifiers.end : node.pos, writeKeyword, node); writeSpace(); if (node.importClause) { emit(node.importClause); writeSpace(); - emitTokenWithComment(SyntaxKind.FromKeyword, node.importClause.end, writeKeyword, node); + emitTokenWithComment(ts.SyntaxKind.FromKeyword, node.importClause.end, writeKeyword, node); writeSpace(); } emitExpression(node.moduleSpecifier); @@ -3414,68 +3353,68 @@ namespace ts { writeTrailingSemicolon(); } - function emitImportClause(node: ImportClause) { + function emitImportClause(node: ts.ImportClause) { if (node.isTypeOnly) { - emitTokenWithComment(SyntaxKind.TypeKeyword, node.pos, writeKeyword, node); + emitTokenWithComment(ts.SyntaxKind.TypeKeyword, node.pos, writeKeyword, node); writeSpace(); } emit(node.name); if (node.name && node.namedBindings) { - emitTokenWithComment(SyntaxKind.CommaToken, node.name.end, writePunctuation, node); + emitTokenWithComment(ts.SyntaxKind.CommaToken, node.name.end, writePunctuation, node); writeSpace(); } emit(node.namedBindings); } - function emitNamespaceImport(node: NamespaceImport) { - const asPos = emitTokenWithComment(SyntaxKind.AsteriskToken, node.pos, writePunctuation, node); + function emitNamespaceImport(node: ts.NamespaceImport) { + const asPos = emitTokenWithComment(ts.SyntaxKind.AsteriskToken, node.pos, writePunctuation, node); writeSpace(); - emitTokenWithComment(SyntaxKind.AsKeyword, asPos, writeKeyword, node); + emitTokenWithComment(ts.SyntaxKind.AsKeyword, asPos, writeKeyword, node); writeSpace(); emit(node.name); } - function emitNamedImports(node: NamedImports) { + function emitNamedImports(node: ts.NamedImports) { emitNamedImportsOrExports(node); } - function emitImportSpecifier(node: ImportSpecifier) { + function emitImportSpecifier(node: ts.ImportSpecifier) { emitImportOrExportSpecifier(node); } - function emitExportAssignment(node: ExportAssignment) { - const nextPos = emitTokenWithComment(SyntaxKind.ExportKeyword, node.pos, writeKeyword, node); + function emitExportAssignment(node: ts.ExportAssignment) { + const nextPos = emitTokenWithComment(ts.SyntaxKind.ExportKeyword, node.pos, writeKeyword, node); writeSpace(); if (node.isExportEquals) { - emitTokenWithComment(SyntaxKind.EqualsToken, nextPos, writeOperator, node); + emitTokenWithComment(ts.SyntaxKind.EqualsToken, nextPos, writeOperator, node); } else { - emitTokenWithComment(SyntaxKind.DefaultKeyword, nextPos, writeKeyword, node); + emitTokenWithComment(ts.SyntaxKind.DefaultKeyword, nextPos, writeKeyword, node); } writeSpace(); emitExpression(node.expression, node.isExportEquals ? - parenthesizer.getParenthesizeRightSideOfBinaryForOperator(SyntaxKind.EqualsToken) : + parenthesizer.getParenthesizeRightSideOfBinaryForOperator(ts.SyntaxKind.EqualsToken) : parenthesizer.parenthesizeExpressionOfExportDefault); writeTrailingSemicolon(); } - function emitExportDeclaration(node: ExportDeclaration) { - let nextPos = emitTokenWithComment(SyntaxKind.ExportKeyword, node.pos, writeKeyword, node); + function emitExportDeclaration(node: ts.ExportDeclaration) { + let nextPos = emitTokenWithComment(ts.SyntaxKind.ExportKeyword, node.pos, writeKeyword, node); writeSpace(); if (node.isTypeOnly) { - nextPos = emitTokenWithComment(SyntaxKind.TypeKeyword, nextPos, writeKeyword, node); + nextPos = emitTokenWithComment(ts.SyntaxKind.TypeKeyword, nextPos, writeKeyword, node); writeSpace(); } if (node.exportClause) { emit(node.exportClause); } else { - nextPos = emitTokenWithComment(SyntaxKind.AsteriskToken, nextPos, writePunctuation, node); + nextPos = emitTokenWithComment(ts.SyntaxKind.AsteriskToken, nextPos, writePunctuation, node); } if (node.moduleSpecifier) { writeSpace(); const fromPos = node.exportClause ? node.exportClause.end : nextPos; - emitTokenWithComment(SyntaxKind.FromKeyword, fromPos, writeKeyword, node); + emitTokenWithComment(ts.SyntaxKind.FromKeyword, fromPos, writeKeyword, node); writeSpace(); emitExpression(node.moduleSpecifier); } @@ -3485,61 +3424,61 @@ namespace ts { writeTrailingSemicolon(); } - function emitAssertClause(node: AssertClause) { - emitTokenWithComment(SyntaxKind.AssertKeyword, node.pos, writeKeyword, node); + function emitAssertClause(node: ts.AssertClause) { + emitTokenWithComment(ts.SyntaxKind.AssertKeyword, node.pos, writeKeyword, node); writeSpace(); const elements = node.elements; - emitList(node, elements, ListFormat.ImportClauseEntries); + emitList(node, elements, ts.ListFormat.ImportClauseEntries); } - function emitAssertEntry(node: AssertEntry) { + function emitAssertEntry(node: ts.AssertEntry) { emit(node.name); writePunctuation(":"); writeSpace(); const value = node.value; /** @see {emitPropertyAssignment} */ - if ((getEmitFlags(value) & EmitFlags.NoLeadingComments) === 0) { - const commentRange = getCommentRange(value); + if ((ts.getEmitFlags(value) & ts.EmitFlags.NoLeadingComments) === 0) { + const commentRange = ts.getCommentRange(value); emitTrailingCommentsOfPosition(commentRange.pos); } emit(value); } - function emitNamespaceExportDeclaration(node: NamespaceExportDeclaration) { - let nextPos = emitTokenWithComment(SyntaxKind.ExportKeyword, node.pos, writeKeyword, node); + function emitNamespaceExportDeclaration(node: ts.NamespaceExportDeclaration) { + let nextPos = emitTokenWithComment(ts.SyntaxKind.ExportKeyword, node.pos, writeKeyword, node); writeSpace(); - nextPos = emitTokenWithComment(SyntaxKind.AsKeyword, nextPos, writeKeyword, node); + nextPos = emitTokenWithComment(ts.SyntaxKind.AsKeyword, nextPos, writeKeyword, node); writeSpace(); - nextPos = emitTokenWithComment(SyntaxKind.NamespaceKeyword, nextPos, writeKeyword, node); + nextPos = emitTokenWithComment(ts.SyntaxKind.NamespaceKeyword, nextPos, writeKeyword, node); writeSpace(); emit(node.name); writeTrailingSemicolon(); } - function emitNamespaceExport(node: NamespaceExport) { - const asPos = emitTokenWithComment(SyntaxKind.AsteriskToken, node.pos, writePunctuation, node); + function emitNamespaceExport(node: ts.NamespaceExport) { + const asPos = emitTokenWithComment(ts.SyntaxKind.AsteriskToken, node.pos, writePunctuation, node); writeSpace(); - emitTokenWithComment(SyntaxKind.AsKeyword, asPos, writeKeyword, node); + emitTokenWithComment(ts.SyntaxKind.AsKeyword, asPos, writeKeyword, node); writeSpace(); emit(node.name); } - function emitNamedExports(node: NamedExports) { + function emitNamedExports(node: ts.NamedExports) { emitNamedImportsOrExports(node); } - function emitExportSpecifier(node: ExportSpecifier) { + function emitExportSpecifier(node: ts.ExportSpecifier) { emitImportOrExportSpecifier(node); } - function emitNamedImportsOrExports(node: NamedImportsOrExports) { + function emitNamedImportsOrExports(node: ts.NamedImportsOrExports) { writePunctuation("{"); - emitList(node, node.elements, ListFormat.NamedImportsOrExportsElements); + emitList(node, node.elements, ts.ListFormat.NamedImportsOrExportsElements); writePunctuation("}"); } - function emitImportOrExportSpecifier(node: ImportOrExportSpecifier) { + function emitImportOrExportSpecifier(node: ts.ImportOrExportSpecifier) { if (node.isTypeOnly) { writeKeyword("type"); writeSpace(); @@ -3547,7 +3486,7 @@ namespace ts { if (node.propertyName) { emit(node.propertyName); writeSpace(); - emitTokenWithComment(SyntaxKind.AsKeyword, node.propertyName.end, writeKeyword, node); + emitTokenWithComment(ts.SyntaxKind.AsKeyword, node.propertyName.end, writeKeyword, node); writeSpace(); } @@ -3558,7 +3497,7 @@ namespace ts { // Module references // - function emitExternalModuleReference(node: ExternalModuleReference) { + function emitExternalModuleReference(node: ts.ExternalModuleReference) { writeKeyword("require"); writePunctuation("("); emitExpression(node.expression); @@ -3569,13 +3508,13 @@ namespace ts { // JSX // - function emitJsxElement(node: JsxElement) { + function emitJsxElement(node: ts.JsxElement) { emit(node.openingElement); - emitList(node, node.children, ListFormat.JsxElementOrFragmentChildren); + emitList(node, node.children, ts.ListFormat.JsxElementOrFragmentChildren); emit(node.closingElement); } - function emitJsxSelfClosingElement(node: JsxSelfClosingElement) { + function emitJsxSelfClosingElement(node: ts.JsxSelfClosingElement) { writePunctuation("<"); emitJsxTagName(node.tagName); emitTypeArguments(node, node.typeArguments); @@ -3584,16 +3523,16 @@ namespace ts { writePunctuation("/>"); } - function emitJsxFragment(node: JsxFragment) { + function emitJsxFragment(node: ts.JsxFragment) { emit(node.openingFragment); - emitList(node, node.children, ListFormat.JsxElementOrFragmentChildren); + emitList(node, node.children, ts.ListFormat.JsxElementOrFragmentChildren); emit(node.closingFragment); } - function emitJsxOpeningElementOrFragment(node: JsxOpeningElement | JsxOpeningFragment) { + function emitJsxOpeningElementOrFragment(node: ts.JsxOpeningElement | ts.JsxOpeningFragment) { writePunctuation("<"); - if (isJsxOpeningElement(node)) { + if (ts.isJsxOpeningElement(node)) { const indented = writeLineSeparatorsAndIndentBefore(node.tagName, node); emitJsxTagName(node.tagName); emitTypeArguments(node, node.typeArguments); @@ -3608,28 +3547,28 @@ namespace ts { writePunctuation(">"); } - function emitJsxText(node: JsxText) { + function emitJsxText(node: ts.JsxText) { writer.writeLiteral(node.text); } - function emitJsxClosingElementOrFragment(node: JsxClosingElement | JsxClosingFragment) { + function emitJsxClosingElementOrFragment(node: ts.JsxClosingElement | ts.JsxClosingFragment) { writePunctuation(""); } - function emitJsxAttributes(node: JsxAttributes) { - emitList(node, node.properties, ListFormat.JsxElementAttributes); + function emitJsxAttributes(node: ts.JsxAttributes) { + emitList(node, node.properties, ts.ListFormat.JsxElementAttributes); } - function emitJsxAttribute(node: JsxAttribute) { + function emitJsxAttribute(node: ts.JsxAttribute) { emit(node.name); emitNodeWithPrefix("=", writePunctuation, node.initializer, emitJsxAttributeValue); } - function emitJsxSpreadAttribute(node: JsxSpreadAttribute) { + function emitJsxSpreadAttribute(node: ts.JsxSpreadAttribute) { writePunctuation("{..."); emitExpression(node.expression); writePunctuation("}"); @@ -3637,13 +3576,13 @@ namespace ts { function hasTrailingCommentsAtPosition(pos: number) { let result = false; - forEachTrailingCommentRange(currentSourceFile?.text || "", pos + 1, () => result = true); + ts.forEachTrailingCommentRange(currentSourceFile?.text || "", pos + 1, () => result = true); return result; } function hasLeadingCommentsAtPosition(pos: number) { let result = false; - forEachLeadingCommentRange(currentSourceFile?.text || "", pos + 1, () => result = true); + ts.forEachLeadingCommentRange(currentSourceFile?.text || "", pos + 1, () => result = true); return result; } @@ -3651,24 +3590,24 @@ namespace ts { return hasTrailingCommentsAtPosition(pos) || hasLeadingCommentsAtPosition(pos); } - function emitJsxExpression(node: JsxExpression) { - if (node.expression || (!commentsDisabled && !nodeIsSynthesized(node) && hasCommentsAtPosition(node.pos))) { // preserve empty expressions if they contain comments! - const isMultiline = currentSourceFile && !nodeIsSynthesized(node) && getLineAndCharacterOfPosition(currentSourceFile, node.pos).line !== getLineAndCharacterOfPosition(currentSourceFile, node.end).line; + function emitJsxExpression(node: ts.JsxExpression) { + if (node.expression || (!commentsDisabled && !ts.nodeIsSynthesized(node) && hasCommentsAtPosition(node.pos))) { // preserve empty expressions if they contain comments! + const isMultiline = currentSourceFile && !ts.nodeIsSynthesized(node) && ts.getLineAndCharacterOfPosition(currentSourceFile, node.pos).line !== ts.getLineAndCharacterOfPosition(currentSourceFile, node.end).line; if (isMultiline) { writer.increaseIndent(); } - const end = emitTokenWithComment(SyntaxKind.OpenBraceToken, node.pos, writePunctuation, node); + const end = emitTokenWithComment(ts.SyntaxKind.OpenBraceToken, node.pos, writePunctuation, node); emit(node.dotDotDotToken); emitExpression(node.expression); - emitTokenWithComment(SyntaxKind.CloseBraceToken, node.expression?.end || end, writePunctuation, node); + emitTokenWithComment(ts.SyntaxKind.CloseBraceToken, node.expression?.end || end, writePunctuation, node); if (isMultiline) { writer.decreaseIndent(); } } } - function emitJsxTagName(node: JsxTagNameExpression) { - if (node.kind === SyntaxKind.Identifier) { + function emitJsxTagName(node: ts.JsxTagNameExpression) { + if (node.kind === ts.SyntaxKind.Identifier) { emitExpression(node); } else { @@ -3680,56 +3619,53 @@ namespace ts { // Clauses // - function emitCaseClause(node: CaseClause) { - emitTokenWithComment(SyntaxKind.CaseKeyword, node.pos, writeKeyword, node); + function emitCaseClause(node: ts.CaseClause) { + emitTokenWithComment(ts.SyntaxKind.CaseKeyword, node.pos, writeKeyword, node); writeSpace(); emitExpression(node.expression, parenthesizer.parenthesizeExpressionForDisallowedComma); emitCaseOrDefaultClauseRest(node, node.statements, node.expression.end); } - function emitDefaultClause(node: DefaultClause) { - const pos = emitTokenWithComment(SyntaxKind.DefaultKeyword, node.pos, writeKeyword, node); + function emitDefaultClause(node: ts.DefaultClause) { + const pos = emitTokenWithComment(ts.SyntaxKind.DefaultKeyword, node.pos, writeKeyword, node); emitCaseOrDefaultClauseRest(node, node.statements, pos); } - function emitCaseOrDefaultClauseRest(parentNode: Node, statements: NodeArray, colonPos: number) { - const emitAsSingleStatement = - statements.length === 1 && + function emitCaseOrDefaultClauseRest(parentNode: ts.Node, statements: ts.NodeArray, colonPos: number) { + const emitAsSingleStatement = statements.length === 1 && ( // treat synthesized nodes as located on the same line for emit purposes !currentSourceFile || - nodeIsSynthesized(parentNode) || - nodeIsSynthesized(statements[0]) || - rangeStartPositionsAreOnSameLine(parentNode, statements[0], currentSourceFile) - ); - - let format = ListFormat.CaseOrDefaultClauseStatements; + ts.nodeIsSynthesized(parentNode) || + ts.nodeIsSynthesized(statements[0]) || + ts.rangeStartPositionsAreOnSameLine(parentNode, statements[0], currentSourceFile)); + let format = ts.ListFormat.CaseOrDefaultClauseStatements; if (emitAsSingleStatement) { - writeToken(SyntaxKind.ColonToken, colonPos, writePunctuation, parentNode); + writeToken(ts.SyntaxKind.ColonToken, colonPos, writePunctuation, parentNode); writeSpace(); - format &= ~(ListFormat.MultiLine | ListFormat.Indented); + format &= ~(ts.ListFormat.MultiLine | ts.ListFormat.Indented); } else { - emitTokenWithComment(SyntaxKind.ColonToken, colonPos, writePunctuation, parentNode); + emitTokenWithComment(ts.SyntaxKind.ColonToken, colonPos, writePunctuation, parentNode); } emitList(parentNode, statements, format); } - function emitHeritageClause(node: HeritageClause) { + function emitHeritageClause(node: ts.HeritageClause) { writeSpace(); writeTokenText(node.token, writeKeyword); writeSpace(); - emitList(node, node.types, ListFormat.HeritageClauseTypes); + emitList(node, node.types, ts.ListFormat.HeritageClauseTypes); } - function emitCatchClause(node: CatchClause) { - const openParenPos = emitTokenWithComment(SyntaxKind.CatchKeyword, node.pos, writeKeyword, node); + function emitCatchClause(node: ts.CatchClause) { + const openParenPos = emitTokenWithComment(ts.SyntaxKind.CatchKeyword, node.pos, writeKeyword, node); writeSpace(); if (node.variableDeclaration) { - emitTokenWithComment(SyntaxKind.OpenParenToken, openParenPos, writePunctuation, node); + emitTokenWithComment(ts.SyntaxKind.OpenParenToken, openParenPos, writePunctuation, node); emit(node.variableDeclaration); - emitTokenWithComment(SyntaxKind.CloseParenToken, node.variableDeclaration.end, writePunctuation, node); + emitTokenWithComment(ts.SyntaxKind.CloseParenToken, node.variableDeclaration.end, writePunctuation, node); writeSpace(); } emit(node.block); @@ -3739,7 +3675,7 @@ namespace ts { // Property assignments // - function emitPropertyAssignment(node: PropertyAssignment) { + function emitPropertyAssignment(node: ts.PropertyAssignment) { emit(node.name); writePunctuation(":"); writeSpace(); @@ -3751,14 +3687,14 @@ namespace ts { // "comment1" is not considered to be leading comment for node.initializer // but rather a trailing comment on the previous node. const initializer = node.initializer; - if ((getEmitFlags(initializer) & EmitFlags.NoLeadingComments) === 0) { - const commentRange = getCommentRange(initializer); + if ((ts.getEmitFlags(initializer) & ts.EmitFlags.NoLeadingComments) === 0) { + const commentRange = ts.getCommentRange(initializer); emitTrailingCommentsOfPosition(commentRange.pos); } emitExpression(initializer, parenthesizer.parenthesizeExpressionForDisallowedComma); } - function emitShorthandPropertyAssignment(node: ShorthandPropertyAssignment) { + function emitShorthandPropertyAssignment(node: ts.ShorthandPropertyAssignment) { emit(node.name); if (node.objectAssignmentInitializer) { writeSpace(); @@ -3768,9 +3704,9 @@ namespace ts { } } - function emitSpreadAssignment(node: SpreadAssignment) { + function emitSpreadAssignment(node: ts.SpreadAssignment) { if (node.expression) { - emitTokenWithComment(SyntaxKind.DotDotDotToken, node.pos, writePunctuation, node); + emitTokenWithComment(ts.SyntaxKind.DotDotDotToken, node.pos, writePunctuation, node); emitExpression(node.expression, parenthesizer.parenthesizeExpressionForDisallowedComma); } } @@ -3779,7 +3715,7 @@ namespace ts { // Enum // - function emitEnumMember(node: EnumMember) { + function emitEnumMember(node: ts.EnumMember) { emit(node.name); emitInitializer(node.initializer, node.name.end, node, parenthesizer.parenthesizeExpressionForDisallowedComma); } @@ -3787,10 +3723,10 @@ namespace ts { // // JSDoc // - function emitJSDoc(node: JSDoc) { + function emitJSDoc(node: ts.JSDoc) { write("/**"); if (node.comment) { - const text = getTextOfJSDocComment(node.comment); + const text = ts.getTextOfJSDocComment(node.comment); if (text) { const lines = text.split(/\r\n?|\n/g); for (const line of lines) { @@ -3803,38 +3739,38 @@ namespace ts { } } if (node.tags) { - if (node.tags.length === 1 && node.tags[0].kind === SyntaxKind.JSDocTypeTag && !node.comment) { + if (node.tags.length === 1 && node.tags[0].kind === ts.SyntaxKind.JSDocTypeTag && !node.comment) { writeSpace(); emit(node.tags[0]); } else { - emitList(node, node.tags, ListFormat.JSDocComment); + emitList(node, node.tags, ts.ListFormat.JSDocComment); } } writeSpace(); write("*/"); } - function emitJSDocSimpleTypedTag(tag: JSDocTypeTag | JSDocThisTag | JSDocEnumTag | JSDocReturnTag) { + function emitJSDocSimpleTypedTag(tag: ts.JSDocTypeTag | ts.JSDocThisTag | ts.JSDocEnumTag | ts.JSDocReturnTag) { emitJSDocTagName(tag.tagName); emitJSDocTypeExpression(tag.typeExpression); emitJSDocComment(tag.comment); } - function emitJSDocSeeTag(tag: JSDocSeeTag) { + function emitJSDocSeeTag(tag: ts.JSDocSeeTag) { emitJSDocTagName(tag.tagName); emit(tag.name); emitJSDocComment(tag.comment); } - function emitJSDocNameReference(node: JSDocNameReference) { + function emitJSDocNameReference(node: ts.JSDocNameReference) { writeSpace(); writePunctuation("{"); emit(node.name); writePunctuation("}"); } - function emitJSDocHeritageTag(tag: JSDocImplementsTag | JSDocAugmentsTag) { + function emitJSDocHeritageTag(tag: ts.JSDocImplementsTag | ts.JSDocAugmentsTag) { emitJSDocTagName(tag.tagName); writeSpace(); writePunctuation("{"); @@ -3843,18 +3779,18 @@ namespace ts { emitJSDocComment(tag.comment); } - function emitJSDocTemplateTag(tag: JSDocTemplateTag) { + function emitJSDocTemplateTag(tag: ts.JSDocTemplateTag) { emitJSDocTagName(tag.tagName); emitJSDocTypeExpression(tag.constraint); writeSpace(); - emitList(tag, tag.typeParameters, ListFormat.CommaListElements); + emitList(tag, tag.typeParameters, ts.ListFormat.CommaListElements); emitJSDocComment(tag.comment); } - function emitJSDocTypedefTag(tag: JSDocTypedefTag) { + function emitJSDocTypedefTag(tag: ts.JSDocTypedefTag) { emitJSDocTagName(tag.tagName); if (tag.typeExpression) { - if (tag.typeExpression.kind === SyntaxKind.JSDocTypeExpression) { + if (tag.typeExpression.kind === ts.SyntaxKind.JSDocTypeExpression) { emitJSDocTypeExpression(tag.typeExpression); } else { @@ -3873,12 +3809,12 @@ namespace ts { emit(tag.fullName); } emitJSDocComment(tag.comment); - if (tag.typeExpression && tag.typeExpression.kind === SyntaxKind.JSDocTypeLiteral) { + if (tag.typeExpression && tag.typeExpression.kind === ts.SyntaxKind.JSDocTypeLiteral) { emitJSDocTypeLiteral(tag.typeExpression); } } - function emitJSDocCallbackTag(tag: JSDocCallbackTag) { + function emitJSDocCallbackTag(tag: ts.JSDocCallbackTag) { emitJSDocTagName(tag.tagName); if (tag.name) { writeSpace(); @@ -3888,21 +3824,21 @@ namespace ts { emitJSDocSignature(tag.typeExpression); } - function emitJSDocSimpleTag(tag: JSDocTag) { + function emitJSDocSimpleTag(tag: ts.JSDocTag) { emitJSDocTagName(tag.tagName); emitJSDocComment(tag.comment); } - function emitJSDocTypeLiteral(lit: JSDocTypeLiteral) { - emitList(lit, factory.createNodeArray(lit.jsDocPropertyTags), ListFormat.JSDocComment); + function emitJSDocTypeLiteral(lit: ts.JSDocTypeLiteral) { + emitList(lit, ts.factory.createNodeArray(lit.jsDocPropertyTags), ts.ListFormat.JSDocComment); } - function emitJSDocSignature(sig: JSDocSignature) { + function emitJSDocSignature(sig: ts.JSDocSignature) { if (sig.typeParameters) { - emitList(sig, factory.createNodeArray(sig.typeParameters), ListFormat.JSDocComment); + emitList(sig, ts.factory.createNodeArray(sig.typeParameters), ts.ListFormat.JSDocComment); } if (sig.parameters) { - emitList(sig, factory.createNodeArray(sig.parameters), ListFormat.JSDocComment); + emitList(sig, ts.factory.createNodeArray(sig.parameters), ts.ListFormat.JSDocComment); } if (sig.type) { writeLine(); @@ -3913,7 +3849,7 @@ namespace ts { } } - function emitJSDocPropertyLikeTag(param: JSDocPropertyLikeTag) { + function emitJSDocPropertyLikeTag(param: ts.JSDocPropertyLikeTag) { emitJSDocTagName(param.tagName); emitJSDocTypeExpression(param.typeExpression); writeSpace(); @@ -3927,20 +3863,20 @@ namespace ts { emitJSDocComment(param.comment); } - function emitJSDocTagName(tagName: Identifier) { + function emitJSDocTagName(tagName: ts.Identifier) { writePunctuation("@"); emit(tagName); } - function emitJSDocComment(comment: string | NodeArray | undefined) { - const text = getTextOfJSDocComment(comment); + function emitJSDocComment(comment: string | ts.NodeArray | undefined) { + const text = ts.getTextOfJSDocComment(comment); if (text) { writeSpace(); write(text); } } - function emitJSDocTypeExpression(typeExpression: JSDocTypeExpression | undefined) { + function emitJSDocTypeExpression(typeExpression: ts.JSDocTypeExpression | undefined) { if (typeExpression) { writeSpace(); writePunctuation("{"); @@ -3953,14 +3889,14 @@ namespace ts { // Top-level nodes // - function emitSourceFile(node: SourceFile) { + function emitSourceFile(node: ts.SourceFile) { writeLine(); const statements = node.statements; // Emit detached comment if there are no prologue directives or if the first node is synthesized. // The synthesized node will have no leading comment so some comments may be missed. const shouldEmitDetachedComment = statements.length === 0 || - !isPrologueDirective(statements[0]) || - nodeIsSynthesized(statements[0]); + !ts.isPrologueDirective(statements[0]) || + ts.nodeIsSynthesized(statements[0]); if (shouldEmitDetachedComment) { emitBodyWithDetachedComments(node, statements, emitSourceFileWorker); return; @@ -3968,10 +3904,10 @@ namespace ts { emitSourceFileWorker(node); } - function emitSyntheticTripleSlashReferencesIfNeeded(node: Bundle) { + function emitSyntheticTripleSlashReferencesIfNeeded(node: ts.Bundle) { emitTripleSlashDirectives(!!node.hasNoDefaultLib, node.syntheticFileReferences || [], node.syntheticTypeReferences || [], node.syntheticLibReferences || []); for (const prepend of node.prepends) { - if (isUnparsedSource(prepend) && prepend.syntheticReferences) { + if (ts.isUnparsedSource(prepend) && prepend.syntheticReferences) { for (const ref of prepend.syntheticReferences) { emit(ref); writeLine(); @@ -3980,15 +3916,17 @@ namespace ts { } } - function emitTripleSlashDirectivesIfNeeded(node: SourceFile) { - if (node.isDeclarationFile) emitTripleSlashDirectives(node.hasNoDefaultLib, node.referencedFiles, node.typeReferenceDirectives, node.libReferenceDirectives); + function emitTripleSlashDirectivesIfNeeded(node: ts.SourceFile) { + if (node.isDeclarationFile) + emitTripleSlashDirectives(node.hasNoDefaultLib, node.referencedFiles, node.typeReferenceDirectives, node.libReferenceDirectives); } - function emitTripleSlashDirectives(hasNoDefaultLib: boolean, files: readonly FileReference[], types: readonly FileReference[], libs: readonly FileReference[]) { + function emitTripleSlashDirectives(hasNoDefaultLib: boolean, files: readonly ts.FileReference[], types: readonly ts.FileReference[], libs: readonly ts.FileReference[]) { if (hasNoDefaultLib) { const pos = writer.getTextPos(); writeComment(`/// `); - if (bundleFileInfo) bundleFileInfo.sections.push({ pos, end: writer.getTextPos(), kind: BundleFileSectionKind.NoDefaultLib }); + if (bundleFileInfo) + bundleFileInfo.sections.push({ pos, end: writer.getTextPos(), kind: ts.BundleFileSectionKind.NoDefaultLib }); writeLine(); } if (currentSourceFile && currentSourceFile.moduleName) { @@ -4009,63 +3947,66 @@ namespace ts { for (const directive of files) { const pos = writer.getTextPos(); writeComment(`/// `); - if (bundleFileInfo) bundleFileInfo.sections.push({ pos, end: writer.getTextPos(), kind: BundleFileSectionKind.Reference, data: directive.fileName }); + if (bundleFileInfo) + bundleFileInfo.sections.push({ pos, end: writer.getTextPos(), kind: ts.BundleFileSectionKind.Reference, data: directive.fileName }); writeLine(); } for (const directive of types) { const pos = writer.getTextPos(); const resolutionMode = directive.resolutionMode && directive.resolutionMode !== currentSourceFile?.impliedNodeFormat - ? `resolution-mode="${directive.resolutionMode === ModuleKind.ESNext ? "import" : "require"}"` + ? `resolution-mode="${directive.resolutionMode === ts.ModuleKind.ESNext ? "import" : "require"}"` : ""; writeComment(`/// `); - if (bundleFileInfo) bundleFileInfo.sections.push({ pos, end: writer.getTextPos(), kind: !directive.resolutionMode ? BundleFileSectionKind.Type : directive.resolutionMode === ModuleKind.ESNext ? BundleFileSectionKind.TypeResolutionModeImport : BundleFileSectionKind.TypeResolutionModeRequire, data: directive.fileName }); + if (bundleFileInfo) + bundleFileInfo.sections.push({ pos, end: writer.getTextPos(), kind: !directive.resolutionMode ? ts.BundleFileSectionKind.Type : directive.resolutionMode === ts.ModuleKind.ESNext ? ts.BundleFileSectionKind.TypeResolutionModeImport : ts.BundleFileSectionKind.TypeResolutionModeRequire, data: directive.fileName }); writeLine(); } for (const directive of libs) { const pos = writer.getTextPos(); writeComment(`/// `); - if (bundleFileInfo) bundleFileInfo.sections.push({ pos, end: writer.getTextPos(), kind: BundleFileSectionKind.Lib, data: directive.fileName }); + if (bundleFileInfo) + bundleFileInfo.sections.push({ pos, end: writer.getTextPos(), kind: ts.BundleFileSectionKind.Lib, data: directive.fileName }); writeLine(); } } - function emitSourceFileWorker(node: SourceFile) { + function emitSourceFileWorker(node: ts.SourceFile) { const statements = node.statements; pushNameGenerationScope(node); - forEach(node.statements, generateNames); + ts.forEach(node.statements, generateNames); emitHelpers(node); - const index = findIndex(statements, statement => !isPrologueDirective(statement)); + const index = ts.findIndex(statements, statement => !ts.isPrologueDirective(statement)); emitTripleSlashDirectivesIfNeeded(node); - emitList(node, statements, ListFormat.MultiLine, /*parenthesizerRule*/ undefined, index === -1 ? statements.length : index); + emitList(node, statements, ts.ListFormat.MultiLine, /*parenthesizerRule*/ undefined, index === -1 ? statements.length : index); popNameGenerationScope(node); } // Transformation nodes - function emitPartiallyEmittedExpression(node: PartiallyEmittedExpression) { - const emitFlags = getEmitFlags(node); - if (!(emitFlags & EmitFlags.NoLeadingComments) && node.pos !== node.expression.pos) { + function emitPartiallyEmittedExpression(node: ts.PartiallyEmittedExpression) { + const emitFlags = ts.getEmitFlags(node); + if (!(emitFlags & ts.EmitFlags.NoLeadingComments) && node.pos !== node.expression.pos) { emitTrailingCommentsOfPosition(node.expression.pos); } emitExpression(node.expression); - if (!(emitFlags & EmitFlags.NoTrailingComments) && node.end !== node.expression.end) { + if (!(emitFlags & ts.EmitFlags.NoTrailingComments) && node.end !== node.expression.end) { emitLeadingCommentsOfPosition(node.expression.end); } } - function emitCommaList(node: CommaListExpression) { - emitExpressionList(node, node.elements, ListFormat.CommaListElements, /*parenthesizerRule*/ undefined); + function emitCommaList(node: ts.CommaListExpression) { + emitExpressionList(node, node.elements, ts.ListFormat.CommaListElements, /*parenthesizerRule*/ undefined); } /** * Emits any prologue directives at the start of a Statement list, returning the * number of prologue directives written to the output. */ - function emitPrologueDirectives(statements: readonly Node[], sourceFile?: SourceFile, seenPrologueDirectives?: Set, recordBundleFileSection?: true): number { + function emitPrologueDirectives(statements: readonly ts.Node[], sourceFile?: ts.SourceFile, seenPrologueDirectives?: ts.Set, recordBundleFileSection?: true): number { let needsToSetSourceFile = !!sourceFile; for (let i = 0; i < statements.length; i++) { const statement = statements[i]; - if (isPrologueDirective(statement)) { + if (ts.isPrologueDirective(statement)) { const shouldEmitPrologueDirective = seenPrologueDirectives ? !seenPrologueDirectives.has(statement.expression.text) : true; if (shouldEmitPrologueDirective) { if (needsToSetSourceFile) { @@ -4075,7 +4016,8 @@ namespace ts { writeLine(); const pos = writer.getTextPos(); emit(statement); - if (recordBundleFileSection && bundleFileInfo) bundleFileInfo.sections.push({ pos, end: writer.getTextPos(), kind: BundleFileSectionKind.Prologue, data: statement.expression.text }); + if (recordBundleFileSection && bundleFileInfo) + bundleFileInfo.sections.push({ pos, end: writer.getTextPos(), kind: ts.BundleFileSectionKind.Prologue, data: statement.expression.text }); if (seenPrologueDirectives) { seenPrologueDirectives.add(statement.expression.text); } @@ -4090,13 +4032,14 @@ namespace ts { return statements.length; } - function emitUnparsedPrologues(prologues: readonly UnparsedPrologue[], seenPrologueDirectives: Set) { + function emitUnparsedPrologues(prologues: readonly ts.UnparsedPrologue[], seenPrologueDirectives: ts.Set) { for (const prologue of prologues) { if (!seenPrologueDirectives.has(prologue.data)) { writeLine(); const pos = writer.getTextPos(); emit(prologue); - if (bundleFileInfo) bundleFileInfo.sections.push({ pos, end: writer.getTextPos(), kind: BundleFileSectionKind.Prologue, data: prologue.data }); + if (bundleFileInfo) + bundleFileInfo.sections.push({ pos, end: writer.getTextPos(), kind: ts.BundleFileSectionKind.Prologue, data: prologue.data }); if (seenPrologueDirectives) { seenPrologueDirectives.add(prologue.data); } @@ -4104,14 +4047,14 @@ namespace ts { } } - function emitPrologueDirectivesIfNeeded(sourceFileOrBundle: Bundle | SourceFile) { - if (isSourceFile(sourceFileOrBundle)) { + function emitPrologueDirectivesIfNeeded(sourceFileOrBundle: ts.Bundle | ts.SourceFile) { + if (ts.isSourceFile(sourceFileOrBundle)) { emitPrologueDirectives(sourceFileOrBundle.statements, sourceFileOrBundle); } else { - const seenPrologueDirectives = new Set(); + const seenPrologueDirectives = new ts.Set(); for (const prepend of sourceFileOrBundle.prepends) { - emitUnparsedPrologues((prepend as UnparsedSource).prologues, seenPrologueDirectives); + emitUnparsedPrologues((prepend as ts.UnparsedSource).prologues, seenPrologueDirectives); } for (const sourceFile of sourceFileOrBundle.sourceFiles) { emitPrologueDirectives(sourceFile.statements, sourceFile, seenPrologueDirectives, /*recordBundleFileSection*/ true); @@ -4120,16 +4063,18 @@ namespace ts { } } - function getPrologueDirectivesFromBundledSourceFiles(bundle: Bundle): SourceFilePrologueInfo[] | undefined { - const seenPrologueDirectives = new Set(); - let prologues: SourceFilePrologueInfo[] | undefined; + function getPrologueDirectivesFromBundledSourceFiles(bundle: ts.Bundle): ts.SourceFilePrologueInfo[] | undefined { + const seenPrologueDirectives = new ts.Set(); + let prologues: ts.SourceFilePrologueInfo[] | undefined; for (let index = 0; index < bundle.sourceFiles.length; index++) { const sourceFile = bundle.sourceFiles[index]; - let directives: SourceFilePrologueDirective[] | undefined; + let directives: ts.SourceFilePrologueDirective[] | undefined; let end = 0; for (const statement of sourceFile.statements) { - if (!isPrologueDirective(statement)) break; - if (seenPrologueDirectives.has(statement.expression.text)) continue; + if (!ts.isPrologueDirective(statement)) + break; + if (seenPrologueDirectives.has(statement.expression.text)) + continue; seenPrologueDirectives.add(statement.expression.text); (directives || (directives = [])).push({ pos: statement.pos, @@ -4142,14 +4087,15 @@ namespace ts { }); end = end < statement.end ? statement.end : end; } - if (directives) (prologues || (prologues = [])).push({ file: index, text: sourceFile.text.substring(0, end), directives }); + if (directives) + (prologues || (prologues = [])).push({ file: index, text: sourceFile.text.substring(0, end), directives }); } return prologues; } - function emitShebangIfNeeded(sourceFileOrBundle: Bundle | SourceFile | UnparsedSource) { - if (isSourceFile(sourceFileOrBundle) || isUnparsedSource(sourceFileOrBundle)) { - const shebang = getShebang(sourceFileOrBundle.text); + function emitShebangIfNeeded(sourceFileOrBundle: ts.Bundle | ts.SourceFile | ts.UnparsedSource) { + if (ts.isSourceFile(sourceFileOrBundle) || ts.isUnparsedSource(sourceFileOrBundle)) { + const shebang = ts.getShebang(sourceFileOrBundle.text); if (shebang) { writeComment(shebang); writeLine(); @@ -4158,7 +4104,7 @@ namespace ts { } else { for (const prepend of sourceFileOrBundle.prepends) { - Debug.assertNode(prepend, isUnparsedSource); + ts.Debug.assertNode(prepend, ts.isUnparsedSource); if (emitShebangIfNeeded(prepend)) { return true; } @@ -4176,22 +4122,23 @@ namespace ts { // Helpers // - function emitNodeWithWriter(node: Node | undefined, writer: typeof write) { - if (!node) return; + function emitNodeWithWriter(node: ts.Node | undefined, writer: typeof write) { + if (!node) + return; const savedWrite = write; write = writer; emit(node); write = savedWrite; } - function emitModifiers(node: Node, modifiers: NodeArray | undefined) { + function emitModifiers(node: ts.Node, modifiers: ts.NodeArray | undefined) { if (modifiers && modifiers.length) { - emitList(node, modifiers, ListFormat.Modifiers); + emitList(node, modifiers, ts.ListFormat.Modifiers); writeSpace(); } } - function emitTypeAnnotation(node: TypeNode | undefined) { + function emitTypeAnnotation(node: ts.TypeNode | undefined) { if (node) { writePunctuation(":"); writeSpace(); @@ -4199,53 +4146,53 @@ namespace ts { } } - function emitInitializer(node: Expression | undefined, equalCommentStartPos: number, container: Node, parenthesizerRule?: (node: Expression) => Expression) { + function emitInitializer(node: ts.Expression | undefined, equalCommentStartPos: number, container: ts.Node, parenthesizerRule?: (node: ts.Expression) => ts.Expression) { if (node) { writeSpace(); - emitTokenWithComment(SyntaxKind.EqualsToken, equalCommentStartPos, writeOperator, container); + emitTokenWithComment(ts.SyntaxKind.EqualsToken, equalCommentStartPos, writeOperator, container); writeSpace(); emitExpression(node, parenthesizerRule); } } - function emitNodeWithPrefix(prefix: string, prefixWriter: (s: string) => void, node: T | undefined, emit: (node: T) => void) { + function emitNodeWithPrefix(prefix: string, prefixWriter: (s: string) => void, node: T | undefined, emit: (node: T) => void) { if (node) { prefixWriter(prefix); emit(node); } } - function emitWithLeadingSpace(node: Node | undefined) { + function emitWithLeadingSpace(node: ts.Node | undefined) { if (node) { writeSpace(); emit(node); } } - function emitExpressionWithLeadingSpace(node: Expression | undefined, parenthesizerRule?: (node: Expression) => Expression) { + function emitExpressionWithLeadingSpace(node: ts.Expression | undefined, parenthesizerRule?: (node: ts.Expression) => ts.Expression) { if (node) { writeSpace(); emitExpression(node, parenthesizerRule); } } - function emitWithTrailingSpace(node: Node | undefined) { + function emitWithTrailingSpace(node: ts.Node | undefined) { if (node) { emit(node); writeSpace(); } } - function emitEmbeddedStatement(parent: Node, node: Statement) { - if (isBlock(node) || getEmitFlags(parent) & EmitFlags.SingleLine) { + function emitEmbeddedStatement(parent: ts.Node, node: ts.Statement) { + if (ts.isBlock(node) || ts.getEmitFlags(parent) & ts.EmitFlags.SingleLine) { writeSpace(); emit(node); } else { writeLine(); increaseIndent(); - if (isEmptyStatement(node)) { - pipelineEmit(EmitHint.EmbeddedStatement, node); + if (ts.isEmptyStatement(node)) { + pipelineEmit(ts.EmitHint.EmbeddedStatement, node); } else { emit(node); @@ -4254,95 +4201,95 @@ namespace ts { } } - function emitDecorators(parentNode: Node, decorators: NodeArray | undefined) { - emitList(parentNode, decorators, ListFormat.Decorators); + function emitDecorators(parentNode: ts.Node, decorators: ts.NodeArray | undefined) { + emitList(parentNode, decorators, ts.ListFormat.Decorators); } - function emitTypeArguments(parentNode: Node, typeArguments: NodeArray | undefined) { - emitList(parentNode, typeArguments, ListFormat.TypeArguments, typeArgumentParenthesizerRuleSelector); + function emitTypeArguments(parentNode: ts.Node, typeArguments: ts.NodeArray | undefined) { + emitList(parentNode, typeArguments, ts.ListFormat.TypeArguments, typeArgumentParenthesizerRuleSelector); } - function emitTypeParameters(parentNode: SignatureDeclaration | InterfaceDeclaration | TypeAliasDeclaration | ClassDeclaration | ClassExpression, typeParameters: NodeArray | undefined) { - if (isFunctionLike(parentNode) && parentNode.typeArguments) { // Quick info uses type arguments in place of type parameters on instantiated signatures + function emitTypeParameters(parentNode: ts.SignatureDeclaration | ts.InterfaceDeclaration | ts.TypeAliasDeclaration | ts.ClassDeclaration | ts.ClassExpression, typeParameters: ts.NodeArray | undefined) { + if (ts.isFunctionLike(parentNode) && parentNode.typeArguments) { // Quick info uses type arguments in place of type parameters on instantiated signatures return emitTypeArguments(parentNode, parentNode.typeArguments); } - emitList(parentNode, typeParameters, ListFormat.TypeParameters); + emitList(parentNode, typeParameters, ts.ListFormat.TypeParameters); } - function emitParameters(parentNode: Node, parameters: NodeArray) { - emitList(parentNode, parameters, ListFormat.Parameters); + function emitParameters(parentNode: ts.Node, parameters: ts.NodeArray) { + emitList(parentNode, parameters, ts.ListFormat.Parameters); } - function canEmitSimpleArrowHead(parentNode: FunctionTypeNode | ArrowFunction, parameters: NodeArray) { - const parameter = singleOrUndefined(parameters); + function canEmitSimpleArrowHead(parentNode: ts.FunctionTypeNode | ts.ArrowFunction, parameters: ts.NodeArray) { + const parameter = ts.singleOrUndefined(parameters); return parameter && parameter.pos === parentNode.pos // may not have parsed tokens between parent and parameter - && isArrowFunction(parentNode) // only arrow functions may have simple arrow head + && ts.isArrowFunction(parentNode) // only arrow functions may have simple arrow head && !parentNode.type // arrow function may not have return type annotation - && !some(parentNode.decorators) // parent may not have decorators - && !some(parentNode.modifiers) // parent may not have modifiers - && !some(parentNode.typeParameters) // parent may not have type parameters - && !some(parameter.decorators) // parameter may not have decorators - && !some(parameter.modifiers) // parameter may not have modifiers + && !ts.some(parentNode.decorators) // parent may not have decorators + && !ts.some(parentNode.modifiers) // parent may not have modifiers + && !ts.some(parentNode.typeParameters) // parent may not have type parameters + && !ts.some(parameter.decorators) // parameter may not have decorators + && !ts.some(parameter.modifiers) // parameter may not have modifiers && !parameter.dotDotDotToken // parameter may not be rest && !parameter.questionToken // parameter may not be optional && !parameter.type // parameter may not have a type annotation && !parameter.initializer // parameter may not have an initializer - && isIdentifier(parameter.name); // parameter name must be identifier + && ts.isIdentifier(parameter.name); // parameter name must be identifier } - function emitParametersForArrow(parentNode: FunctionTypeNode | ArrowFunction, parameters: NodeArray) { + function emitParametersForArrow(parentNode: ts.FunctionTypeNode | ts.ArrowFunction, parameters: ts.NodeArray) { if (canEmitSimpleArrowHead(parentNode, parameters)) { - emitList(parentNode, parameters, ListFormat.Parameters & ~ListFormat.Parenthesis); + emitList(parentNode, parameters, ts.ListFormat.Parameters & ~ts.ListFormat.Parenthesis); } else { emitParameters(parentNode, parameters); } } - function emitParametersForIndexSignature(parentNode: Node, parameters: NodeArray) { - emitList(parentNode, parameters, ListFormat.IndexSignatureParameters); + function emitParametersForIndexSignature(parentNode: ts.Node, parameters: ts.NodeArray) { + emitList(parentNode, parameters, ts.ListFormat.IndexSignatureParameters); } - function writeDelimiter(format: ListFormat) { - switch (format & ListFormat.DelimitersMask) { - case ListFormat.None: + function writeDelimiter(format: ts.ListFormat) { + switch (format & ts.ListFormat.DelimitersMask) { + case ts.ListFormat.None: break; - case ListFormat.CommaDelimited: + case ts.ListFormat.CommaDelimited: writePunctuation(","); break; - case ListFormat.BarDelimited: + case ts.ListFormat.BarDelimited: writeSpace(); writePunctuation("|"); break; - case ListFormat.AsteriskDelimited: + case ts.ListFormat.AsteriskDelimited: writeSpace(); writePunctuation("*"); writeSpace(); break; - case ListFormat.AmpersandDelimited: + case ts.ListFormat.AmpersandDelimited: writeSpace(); writePunctuation("&"); break; } } - function emitList(parentNode: Node | undefined, children: NodeArray | undefined, format: ListFormat, parenthesizerRule?: ParenthesizerRuleOrSelector, start?: number, count?: number) { + function emitList(parentNode: ts.Node | undefined, children: ts.NodeArray | undefined, format: ts.ListFormat, parenthesizerRule?: ParenthesizerRuleOrSelector, start?: number, count?: number) { emitNodeList(emit, parentNode, children, format, parenthesizerRule, start, count); } - function emitExpressionList(parentNode: Node | undefined, children: NodeArray | undefined, format: ListFormat, parenthesizerRule?: ParenthesizerRuleOrSelector, start?: number, count?: number) { + function emitExpressionList(parentNode: ts.Node | undefined, children: ts.NodeArray | undefined, format: ts.ListFormat, parenthesizerRule?: ParenthesizerRuleOrSelector, start?: number, count?: number) { emitNodeList(emitExpression, parentNode, children, format, parenthesizerRule, start, count); } - function emitNodeList(emit: (node: Node, parenthesizerRule?: ((node: Node) => Node) | undefined) => void, parentNode: Node | undefined, children: NodeArray | undefined, format: ListFormat, parenthesizerRule: ParenthesizerRuleOrSelector | undefined, start = 0, count = children ? children.length - start : 0) { + function emitNodeList(emit: (node: ts.Node, parenthesizerRule?: ((node: ts.Node) => ts.Node) | undefined) => void, parentNode: ts.Node | undefined, children: ts.NodeArray | undefined, format: ts.ListFormat, parenthesizerRule: ParenthesizerRuleOrSelector | undefined, start = 0, count = children ? children.length - start : 0) { const isUndefined = children === undefined; - if (isUndefined && format & ListFormat.OptionalIfUndefined) { + if (isUndefined && format & ts.ListFormat.OptionalIfUndefined) { return; } const isEmpty = children === undefined || start >= children.length || count === 0; - if (isEmpty && format & ListFormat.OptionalIfEmpty) { + if (isEmpty && format & ts.ListFormat.OptionalIfEmpty) { if (onBeforeEmitNodeArray) { onBeforeEmitNodeArray(children); } @@ -4352,7 +4299,7 @@ namespace ts { return; } - if (format & ListFormat.BracketsMask) { + if (format & ts.ListFormat.BracketsMask) { writePunctuation(getOpeningBracket(format)); if (isEmpty && children) { emitTrailingCommentsOfPosition(children.pos, /*prefixSpace*/ true); // Emit comments within empty bracketed lists @@ -4365,43 +4312,43 @@ namespace ts { if (isEmpty) { // Write a line terminator if the parent node was multi-line - if (format & ListFormat.MultiLine && !(preserveSourceNewlines && (!parentNode || currentSourceFile && rangeIsOnSingleLine(parentNode, currentSourceFile)))) { + if (format & ts.ListFormat.MultiLine && !(preserveSourceNewlines && (!parentNode || currentSourceFile && ts.rangeIsOnSingleLine(parentNode, currentSourceFile)))) { writeLine(); } - else if (format & ListFormat.SpaceBetweenBraces && !(format & ListFormat.NoSpaceIfEmpty)) { + else if (format & ts.ListFormat.SpaceBetweenBraces && !(format & ts.ListFormat.NoSpaceIfEmpty)) { writeSpace(); } } else { - Debug.type>(children); + ts.Debug.type>(children); // Write the opening line terminator or leading whitespace. - const mayEmitInterveningComments = (format & ListFormat.NoInterveningComments) === 0; + const mayEmitInterveningComments = (format & ts.ListFormat.NoInterveningComments) === 0; let shouldEmitInterveningComments = mayEmitInterveningComments; const leadingLineTerminatorCount = getLeadingLineTerminatorCount(parentNode, children, format); // TODO: GH#18217 if (leadingLineTerminatorCount) { writeLine(leadingLineTerminatorCount); shouldEmitInterveningComments = false; } - else if (format & ListFormat.SpaceBetweenBraces) { + else if (format & ts.ListFormat.SpaceBetweenBraces) { writeSpace(); } // Increase the indent, if requested. - if (format & ListFormat.Indented) { + if (format & ts.ListFormat.Indented) { increaseIndent(); } const emitListItem = getEmitListItem(emit, parenthesizerRule); // Emit each child. - let previousSibling: Node | undefined; + let previousSibling: ts.Node | undefined; let previousSourceFileTextKind: ReturnType; let shouldDecreaseIndentAfterEmit = false; for (let i = 0; i < count; i++) { const child = children[start + i]; // Write the delimiter if this is not the first node. - if (format & ListFormat.AsteriskDelimited) { + if (format & ts.ListFormat.AsteriskDelimited) { // always write JSDoc in the format "\n *" writeLine(); writeDelimiter(format); @@ -4413,7 +4360,7 @@ namespace ts { // a // /* End of parameter a */ -> this comment isn't considered to be trailing comment of parameter "a" due to newline // , - if (format & ListFormat.DelimitersMask && previousSibling.end !== (parentNode ? parentNode.end : -1)) { + if (format & ts.ListFormat.DelimitersMask && previousSibling.end !== (parentNode ? parentNode.end : -1)) { emitLeadingCommentsOfPosition(previousSibling.end); } writeDelimiter(format); @@ -4424,7 +4371,7 @@ namespace ts { if (separatingLineTerminatorCount > 0) { // If a synthesized node in a single-line list starts on a new // line, we should increase the indent. - if ((format & (ListFormat.LinesMask | ListFormat.Indented)) === ListFormat.SingleLine) { + if ((format & (ts.ListFormat.LinesMask | ts.ListFormat.Indented)) === ts.ListFormat.SingleLine) { increaseIndent(); shouldDecreaseIndentAfterEmit = true; } @@ -4432,7 +4379,7 @@ namespace ts { writeLine(separatingLineTerminatorCount); shouldEmitInterveningComments = false; } - else if (previousSibling && format & ListFormat.SpaceBetweenSiblings) { + else if (previousSibling && format & ts.ListFormat.SpaceBetweenSiblings) { writeSpace(); } } @@ -4440,7 +4387,7 @@ namespace ts { // Emit this child. previousSourceFileTextKind = recordBundleFileInternalSectionStart(child); if (shouldEmitInterveningComments) { - const commentRange = getCommentRange(child); + const commentRange = ts.getCommentRange(child); emitTrailingCommentsOfPosition(commentRange.pos); } else { @@ -4459,12 +4406,12 @@ namespace ts { } // Write a trailing comma, if requested. - const emitFlags = previousSibling ? getEmitFlags(previousSibling) : 0; - const skipTrailingComments = commentsDisabled || !!(emitFlags & EmitFlags.NoTrailingComments); - const hasTrailingComma = children?.hasTrailingComma && (format & ListFormat.AllowTrailingComma) && (format & ListFormat.CommaDelimited); + const emitFlags = previousSibling ? ts.getEmitFlags(previousSibling) : 0; + const skipTrailingComments = commentsDisabled || !!(emitFlags & ts.EmitFlags.NoTrailingComments); + const hasTrailingComma = children?.hasTrailingComma && (format & ts.ListFormat.AllowTrailingComma) && (format & ts.ListFormat.CommaDelimited); if (hasTrailingComma) { if (previousSibling && !skipTrailingComments) { - emitTokenWithComment(SyntaxKind.CommaToken, previousSibling.end, writePunctuation, previousSibling); + emitTokenWithComment(ts.SyntaxKind.CommaToken, previousSibling.end, writePunctuation, previousSibling); } else { writePunctuation(","); @@ -4477,12 +4424,12 @@ namespace ts { // 2 // /* end of element 2 */ // ]; - if (previousSibling && (parentNode ? parentNode.end : -1) !== previousSibling.end && (format & ListFormat.DelimitersMask) && !skipTrailingComments) { + if (previousSibling && (parentNode ? parentNode.end : -1) !== previousSibling.end && (format & ts.ListFormat.DelimitersMask) && !skipTrailingComments) { emitLeadingCommentsOfPosition(hasTrailingComma && children?.end ? children.end : previousSibling.end); } // Decrease the indent, if requested. - if (format & ListFormat.Indented) { + if (format & ts.ListFormat.Indented) { decreaseIndent(); } @@ -4493,7 +4440,7 @@ namespace ts { if (closingLineTerminatorCount) { writeLine(closingLineTerminatorCount); } - else if (format & (ListFormat.SpaceAfterList | ListFormat.SpaceBetweenBraces)) { + else if (format & (ts.ListFormat.SpaceAfterList | ts.ListFormat.SpaceBetweenBraces)) { writeSpace(); } } @@ -4502,7 +4449,7 @@ namespace ts { onAfterEmitNodeArray(children); } - if (format & ListFormat.BracketsMask) { + if (format & ts.ListFormat.BracketsMask) { if (isEmpty && children) { emitLeadingCommentsOfPosition(children.end); // Emit leading comments within empty lists } @@ -4524,7 +4471,7 @@ namespace ts { writer.write(s); } - function writeSymbol(s: string, sym: Symbol) { + function writeSymbol(s: string, sym: ts.Symbol) { writer.writeSymbol(s, sym); } @@ -4584,32 +4531,32 @@ namespace ts { writer.decreaseIndent(); } - function writeToken(token: SyntaxKind, pos: number, writer: (s: string) => void, contextNode?: Node) { + function writeToken(token: ts.SyntaxKind, pos: number, writer: (s: string) => void, contextNode?: ts.Node) { return !sourceMapsDisabled ? emitTokenWithSourceMap(contextNode, token, writer, pos, writeTokenText) : writeTokenText(token, writer, pos); } - function writeTokenNode(node: Node, writer: (s: string) => void) { + function writeTokenNode(node: ts.Node, writer: (s: string) => void) { if (onBeforeEmitToken) { onBeforeEmitToken(node); } - writer(tokenToString(node.kind)!); + writer(ts.tokenToString(node.kind)!); if (onAfterEmitToken) { onAfterEmitToken(node); } } - function writeTokenText(token: SyntaxKind, writer: (s: string) => void): void; - function writeTokenText(token: SyntaxKind, writer: (s: string) => void, pos: number): number; - function writeTokenText(token: SyntaxKind, writer: (s: string) => void, pos?: number): number { - const tokenString = tokenToString(token)!; + function writeTokenText(token: ts.SyntaxKind, writer: (s: string) => void): void; + function writeTokenText(token: ts.SyntaxKind, writer: (s: string) => void, pos: number): number; + function writeTokenText(token: ts.SyntaxKind, writer: (s: string) => void, pos?: number): number { + const tokenString = ts.tokenToString(token)!; writer(tokenString); return pos! < 0 ? pos! : pos! + tokenString.length; } - function writeLineOrSpace(parentNode: Node, prevChildNode: Node, nextChildNode: Node) { - if (getEmitFlags(parentNode) & EmitFlags.SingleLine) { + function writeLineOrSpace(parentNode: ts.Node, prevChildNode: ts.Node, nextChildNode: ts.Node) { + if (ts.getEmitFlags(parentNode) & ts.EmitFlags.SingleLine) { writeSpace(); } else if (preserveSourceNewlines) { @@ -4628,7 +4575,7 @@ namespace ts { function writeLines(text: string): void { const lines = text.split(/\r\n?|\n/g); - const indentation = guessIndentation(lines); + const indentation = ts.guessIndentation(lines); for (const lineText of lines) { const line = indentation ? lineText.slice(indentation) : lineText; if (line.length) { @@ -4661,15 +4608,15 @@ namespace ts { } } - function getLeadingLineTerminatorCount(parentNode: Node | undefined, children: readonly Node[], format: ListFormat): number { - if (format & ListFormat.PreserveLines || preserveSourceNewlines) { - if (format & ListFormat.PreferNewLine) { + function getLeadingLineTerminatorCount(parentNode: ts.Node | undefined, children: readonly ts.Node[], format: ts.ListFormat): number { + if (format & ts.ListFormat.PreserveLines || preserveSourceNewlines) { + if (format & ts.ListFormat.PreferNewLine) { return 1; } const firstChild = children[0]; if (firstChild === undefined) { - return !parentNode || currentSourceFile && rangeIsOnSingleLine(parentNode, currentSourceFile) ? 0 : 1; + return !parentNode || currentSourceFile && ts.rangeIsOnSingleLine(parentNode, currentSourceFile) ? 0 : 1; } if (firstChild.pos === nextListElementPos) { // If this child starts at the beginning of a list item in a parent list, its leading @@ -4689,49 +4636,38 @@ namespace ts { // leading newline to start the modifiers. return 0; } - if (firstChild.kind === SyntaxKind.JsxText) { + if (firstChild.kind === ts.SyntaxKind.JsxText) { // JsxText will be written with its leading whitespace, so don't add more manually. return 0; } if (currentSourceFile && parentNode && - !positionIsSynthesized(parentNode.pos) && - !nodeIsSynthesized(firstChild) && - (!firstChild.parent || getOriginalNode(firstChild.parent) === getOriginalNode(parentNode)) - ) { + !ts.positionIsSynthesized(parentNode.pos) && + !ts.nodeIsSynthesized(firstChild) && + (!firstChild.parent || ts.getOriginalNode(firstChild.parent) === ts.getOriginalNode(parentNode))) { if (preserveSourceNewlines) { - return getEffectiveLines( - includeComments => getLinesBetweenPositionAndPrecedingNonWhitespaceCharacter( - firstChild.pos, - parentNode.pos, - currentSourceFile!, - includeComments)); + return getEffectiveLines(includeComments => ts.getLinesBetweenPositionAndPrecedingNonWhitespaceCharacter(firstChild.pos, parentNode.pos, currentSourceFile!, includeComments)); } - return rangeStartPositionsAreOnSameLine(parentNode, firstChild, currentSourceFile) ? 0 : 1; + return ts.rangeStartPositionsAreOnSameLine(parentNode, firstChild, currentSourceFile) ? 0 : 1; } if (synthesizedNodeStartsOnNewLine(firstChild, format)) { return 1; } } - return format & ListFormat.MultiLine ? 1 : 0; + return format & ts.ListFormat.MultiLine ? 1 : 0; } - function getSeparatingLineTerminatorCount(previousNode: Node | undefined, nextNode: Node, format: ListFormat): number { - if (format & ListFormat.PreserveLines || preserveSourceNewlines) { + function getSeparatingLineTerminatorCount(previousNode: ts.Node | undefined, nextNode: ts.Node, format: ts.ListFormat): number { + if (format & ts.ListFormat.PreserveLines || preserveSourceNewlines) { if (previousNode === undefined || nextNode === undefined) { return 0; } - if (nextNode.kind === SyntaxKind.JsxText) { + if (nextNode.kind === ts.SyntaxKind.JsxText) { // JsxText will be written with its leading whitespace, so don't add more manually. return 0; } - else if (currentSourceFile && !nodeIsSynthesized(previousNode) && !nodeIsSynthesized(nextNode)) { + else if (currentSourceFile && !ts.nodeIsSynthesized(previousNode) && !ts.nodeIsSynthesized(nextNode)) { if (preserveSourceNewlines && siblingNodePositionsAreComparable(previousNode, nextNode)) { - return getEffectiveLines( - includeComments => getLinesBetweenRangeEndAndRangeStart( - previousNode, - nextNode, - currentSourceFile!, - includeComments)); + return getEffectiveLines(includeComments => ts.getLinesBetweenRangeEndAndRangeStart(previousNode, nextNode, currentSourceFile!, includeComments)); } // If `preserveSourceNewlines` is `false` we do not intend to preserve the effective lines between the // previous and next node. Instead we naively check whether nodes are on separate lines within the @@ -4739,49 +4675,44 @@ namespace ts { // expensive than checking with `preserveSourceNewlines` as above, but the goal is not to preserve the // effective source lines between two sibling nodes. else if (!preserveSourceNewlines && originalNodesHaveSameParent(previousNode, nextNode)) { - return rangeEndIsOnSameLineAsRangeStart(previousNode, nextNode, currentSourceFile) ? 0 : 1; + return ts.rangeEndIsOnSameLineAsRangeStart(previousNode, nextNode, currentSourceFile) ? 0 : 1; } // If the two nodes are not comparable, add a line terminator based on the format that can indicate // whether new lines are preferred or not. - return format & ListFormat.PreferNewLine ? 1 : 0; + return format & ts.ListFormat.PreferNewLine ? 1 : 0; } else if (synthesizedNodeStartsOnNewLine(previousNode, format) || synthesizedNodeStartsOnNewLine(nextNode, format)) { return 1; } } - else if (getStartsOnNewLine(nextNode)) { + else if (ts.getStartsOnNewLine(nextNode)) { return 1; } - return format & ListFormat.MultiLine ? 1 : 0; + return format & ts.ListFormat.MultiLine ? 1 : 0; } - function getClosingLineTerminatorCount(parentNode: Node | undefined, children: readonly Node[], format: ListFormat): number { - if (format & ListFormat.PreserveLines || preserveSourceNewlines) { - if (format & ListFormat.PreferNewLine) { + function getClosingLineTerminatorCount(parentNode: ts.Node | undefined, children: readonly ts.Node[], format: ts.ListFormat): number { + if (format & ts.ListFormat.PreserveLines || preserveSourceNewlines) { + if (format & ts.ListFormat.PreferNewLine) { return 1; } - const lastChild = lastOrUndefined(children); + const lastChild = ts.lastOrUndefined(children); if (lastChild === undefined) { - return !parentNode || currentSourceFile && rangeIsOnSingleLine(parentNode, currentSourceFile) ? 0 : 1; + return !parentNode || currentSourceFile && ts.rangeIsOnSingleLine(parentNode, currentSourceFile) ? 0 : 1; } - if (currentSourceFile && parentNode && !positionIsSynthesized(parentNode.pos) && !nodeIsSynthesized(lastChild) && (!lastChild.parent || lastChild.parent === parentNode)) { + if (currentSourceFile && parentNode && !ts.positionIsSynthesized(parentNode.pos) && !ts.nodeIsSynthesized(lastChild) && (!lastChild.parent || lastChild.parent === parentNode)) { if (preserveSourceNewlines) { - const end = isNodeArray(children) && !positionIsSynthesized(children.end) ? children.end : lastChild.end; - return getEffectiveLines( - includeComments => getLinesBetweenPositionAndNextNonWhitespaceCharacter( - end, - parentNode.end, - currentSourceFile!, - includeComments)); + const end = ts.isNodeArray(children) && !ts.positionIsSynthesized(children.end) ? children.end : lastChild.end; + return getEffectiveLines(includeComments => ts.getLinesBetweenPositionAndNextNonWhitespaceCharacter(end, parentNode.end, currentSourceFile!, includeComments)); } - return rangeEndPositionsAreOnSameLine(parentNode, lastChild, currentSourceFile) ? 0 : 1; + return ts.rangeEndPositionsAreOnSameLine(parentNode, lastChild, currentSourceFile) ? 0 : 1; } if (synthesizedNodeStartsOnNewLine(lastChild, format)) { return 1; } } - if (format & ListFormat.MultiLine && !(format & ListFormat.NoTrailingNewLine)) { + if (format & ts.ListFormat.MultiLine && !(format & ts.ListFormat.NoTrailingNewLine)) { return 1; } return 0; @@ -4790,7 +4721,7 @@ namespace ts { function getEffectiveLines(getLineDifference: (includeComments: boolean) => number) { // If 'preserveSourceNewlines' is disabled, we should never call this function // because it could be more expensive than alternative approximations. - Debug.assert(!!preserveSourceNewlines); + ts.Debug.assert(!!preserveSourceNewlines); // We start by measuring the line difference from a position to its adjacent comments, // so that this is counted as a one-line difference, not two: // @@ -4811,36 +4742,36 @@ namespace ts { return lines; } - function writeLineSeparatorsAndIndentBefore(node: Node, parent: Node): boolean { - const leadingNewlines = preserveSourceNewlines && getLeadingLineTerminatorCount(parent, [node], ListFormat.None); + function writeLineSeparatorsAndIndentBefore(node: ts.Node, parent: ts.Node): boolean { + const leadingNewlines = preserveSourceNewlines && getLeadingLineTerminatorCount(parent, [node], ts.ListFormat.None); if (leadingNewlines) { writeLinesAndIndent(leadingNewlines, /*writeSpaceIfNotIndenting*/ false); } return !!leadingNewlines; } - function writeLineSeparatorsAfter(node: Node, parent: Node) { - const trailingNewlines = preserveSourceNewlines && getClosingLineTerminatorCount(parent, [node], ListFormat.None); + function writeLineSeparatorsAfter(node: ts.Node, parent: ts.Node) { + const trailingNewlines = preserveSourceNewlines && getClosingLineTerminatorCount(parent, [node], ts.ListFormat.None); if (trailingNewlines) { writeLine(trailingNewlines); } } - function synthesizedNodeStartsOnNewLine(node: Node, format: ListFormat) { - if (nodeIsSynthesized(node)) { - const startsOnNewLine = getStartsOnNewLine(node); + function synthesizedNodeStartsOnNewLine(node: ts.Node, format: ts.ListFormat) { + if (ts.nodeIsSynthesized(node)) { + const startsOnNewLine = ts.getStartsOnNewLine(node); if (startsOnNewLine === undefined) { - return (format & ListFormat.PreferNewLine) !== 0; + return (format & ts.ListFormat.PreferNewLine) !== 0; } return startsOnNewLine; } - return (format & ListFormat.PreferNewLine) !== 0; + return (format & ts.ListFormat.PreferNewLine) !== 0; } - function getLinesBetweenNodes(parent: Node, node1: Node, node2: Node): number { - if (getEmitFlags(parent) & EmitFlags.NoIndentation) { + function getLinesBetweenNodes(parent: ts.Node, node1: ts.Node, node2: ts.Node): number { + if (ts.getEmitFlags(parent) & ts.EmitFlags.NoIndentation) { return 0; } @@ -4849,88 +4780,82 @@ namespace ts { node2 = skipSynthesizedParentheses(node2); // Always use a newline for synthesized code if the synthesizer desires it. - if (getStartsOnNewLine(node2)) { + if (ts.getStartsOnNewLine(node2)) { return 1; } - if (currentSourceFile && !nodeIsSynthesized(parent) && !nodeIsSynthesized(node1) && !nodeIsSynthesized(node2)) { + if (currentSourceFile && !ts.nodeIsSynthesized(parent) && !ts.nodeIsSynthesized(node1) && !ts.nodeIsSynthesized(node2)) { if (preserveSourceNewlines) { - return getEffectiveLines( - includeComments => getLinesBetweenRangeEndAndRangeStart( - node1, - node2, - currentSourceFile!, - includeComments)); + return getEffectiveLines(includeComments => ts.getLinesBetweenRangeEndAndRangeStart(node1, node2, currentSourceFile!, includeComments)); } - return rangeEndIsOnSameLineAsRangeStart(node1, node2, currentSourceFile) ? 0 : 1; + return ts.rangeEndIsOnSameLineAsRangeStart(node1, node2, currentSourceFile) ? 0 : 1; } return 0; } - function isEmptyBlock(block: BlockLike) { + function isEmptyBlock(block: ts.BlockLike) { return block.statements.length === 0 - && (!currentSourceFile || rangeEndIsOnSameLineAsRangeStart(block, block, currentSourceFile)); + && (!currentSourceFile || ts.rangeEndIsOnSameLineAsRangeStart(block, block, currentSourceFile)); } - function skipSynthesizedParentheses(node: Node) { - while (node.kind === SyntaxKind.ParenthesizedExpression && nodeIsSynthesized(node)) { - node = (node as ParenthesizedExpression).expression; + function skipSynthesizedParentheses(node: ts.Node) { + while (node.kind === ts.SyntaxKind.ParenthesizedExpression && ts.nodeIsSynthesized(node)) { + node = (node as ts.ParenthesizedExpression).expression; } return node; } - function getTextOfNode(node: Identifier | PrivateIdentifier | LiteralExpression, includeTrivia?: boolean): string { - if (isGeneratedIdentifier(node)) { + function getTextOfNode(node: ts.Identifier | ts.PrivateIdentifier | ts.LiteralExpression, includeTrivia?: boolean): string { + if (ts.isGeneratedIdentifier(node)) { return generateName(node); } - if (isStringLiteral(node) && node.textSourceNode) { + if (ts.isStringLiteral(node) && node.textSourceNode) { return getTextOfNode(node.textSourceNode, includeTrivia); } const sourceFile = currentSourceFile; // const needed for control flow - const canUseSourceFile = !!sourceFile && !!node.parent && !nodeIsSynthesized(node); - if (isMemberName(node)) { - if (!canUseSourceFile || getSourceFileOfNode(node) !== getOriginalNode(sourceFile)) { - return idText(node); + const canUseSourceFile = !!sourceFile && !!node.parent && !ts.nodeIsSynthesized(node); + if (ts.isMemberName(node)) { + if (!canUseSourceFile || ts.getSourceFileOfNode(node) !== ts.getOriginalNode(sourceFile)) { + return ts.idText(node); } } else { - Debug.assertNode(node, isLiteralExpression); // not strictly necessary + ts.Debug.assertNode(node, ts.isLiteralExpression); // not strictly necessary if (!canUseSourceFile) { return node.text; } } - return getSourceTextOfNodeFromSourceFile(sourceFile, node, includeTrivia); + return ts.getSourceTextOfNodeFromSourceFile(sourceFile, node, includeTrivia); } - function getLiteralTextOfNode(node: LiteralLikeNode, neverAsciiEscape: boolean | undefined, jsxAttributeEscape: boolean): string { - if (node.kind === SyntaxKind.StringLiteral && (node as StringLiteral).textSourceNode) { - const textSourceNode = (node as StringLiteral).textSourceNode!; - if (isIdentifier(textSourceNode) || isNumericLiteral(textSourceNode)) { - const text = isNumericLiteral(textSourceNode) ? textSourceNode.text : getTextOfNode(textSourceNode); - return jsxAttributeEscape ? `"${escapeJsxAttributeString(text)}"` : - neverAsciiEscape || (getEmitFlags(node) & EmitFlags.NoAsciiEscaping) ? `"${escapeString(text)}"` : - `"${escapeNonAsciiString(text)}"`; + function getLiteralTextOfNode(node: ts.LiteralLikeNode, neverAsciiEscape: boolean | undefined, jsxAttributeEscape: boolean): string { + if (node.kind === ts.SyntaxKind.StringLiteral && (node as ts.StringLiteral).textSourceNode) { + const textSourceNode = (node as ts.StringLiteral).textSourceNode!; + if (ts.isIdentifier(textSourceNode) || ts.isNumericLiteral(textSourceNode)) { + const text = ts.isNumericLiteral(textSourceNode) ? textSourceNode.text : getTextOfNode(textSourceNode); + return jsxAttributeEscape ? `"${ts.escapeJsxAttributeString(text)}"` : + neverAsciiEscape || (ts.getEmitFlags(node) & ts.EmitFlags.NoAsciiEscaping) ? `"${ts.escapeString(text)}"` : + `"${ts.escapeNonAsciiString(text)}"`; } else { return getLiteralTextOfNode(textSourceNode, neverAsciiEscape, jsxAttributeEscape); } } - const flags = (neverAsciiEscape ? GetLiteralTextFlags.NeverAsciiEscape : 0) - | (jsxAttributeEscape ? GetLiteralTextFlags.JsxAttributeEscape : 0) - | (printerOptions.terminateUnterminatedLiterals ? GetLiteralTextFlags.TerminateUnterminatedLiterals : 0) - | (printerOptions.target && printerOptions.target === ScriptTarget.ESNext ? GetLiteralTextFlags.AllowNumericSeparator : 0); - - return getLiteralText(node, currentSourceFile, flags); + const flags = (neverAsciiEscape ? ts.GetLiteralTextFlags.NeverAsciiEscape : 0) + | (jsxAttributeEscape ? ts.GetLiteralTextFlags.JsxAttributeEscape : 0) + | (printerOptions.terminateUnterminatedLiterals ? ts.GetLiteralTextFlags.TerminateUnterminatedLiterals : 0) + | (printerOptions.target && printerOptions.target === ts.ScriptTarget.ESNext ? ts.GetLiteralTextFlags.AllowNumericSeparator : 0); + return ts.getLiteralText(node, currentSourceFile, flags); } /** * Push a new name generation scope. */ - function pushNameGenerationScope(node: Node | undefined) { - if (node && getEmitFlags(node) & EmitFlags.ReuseTempVariableScope) { + function pushNameGenerationScope(node: ts.Node | undefined) { + if (node && ts.getEmitFlags(node) & ts.EmitFlags.ReuseTempVariableScope) { return; } tempFlagsStack.push(tempFlags); @@ -4941,8 +4866,8 @@ namespace ts { /** * Pop the current name generation scope. */ - function popNameGenerationScope(node: Node | undefined) { - if (node && getEmitFlags(node) & EmitFlags.ReuseTempVariableScope) { + function popNameGenerationScope(node: ts.Node | undefined) { + if (node && ts.getEmitFlags(node) & ts.EmitFlags.ReuseTempVariableScope) { return; } tempFlags = tempFlagsStack.pop()!; @@ -4950,118 +4875,120 @@ namespace ts { } function reserveNameInNestedScopes(name: string) { - if (!reservedNames || reservedNames === lastOrUndefined(reservedNamesStack)) { - reservedNames = new Set(); + if (!reservedNames || reservedNames === ts.lastOrUndefined(reservedNamesStack)) { + reservedNames = new ts.Set(); } reservedNames.add(name); } - function generateNames(node: Node | undefined) { - if (!node) return; + function generateNames(node: ts.Node | undefined) { + if (!node) + return; switch (node.kind) { - case SyntaxKind.Block: - forEach((node as Block).statements, generateNames); + case ts.SyntaxKind.Block: + ts.forEach((node as ts.Block).statements, generateNames); break; - case SyntaxKind.LabeledStatement: - case SyntaxKind.WithStatement: - case SyntaxKind.DoStatement: - case SyntaxKind.WhileStatement: - generateNames((node as LabeledStatement | WithStatement | DoStatement | WhileStatement).statement); + case ts.SyntaxKind.LabeledStatement: + case ts.SyntaxKind.WithStatement: + case ts.SyntaxKind.DoStatement: + case ts.SyntaxKind.WhileStatement: + generateNames((node as ts.LabeledStatement | ts.WithStatement | ts.DoStatement | ts.WhileStatement).statement); break; - case SyntaxKind.IfStatement: - generateNames((node as IfStatement).thenStatement); - generateNames((node as IfStatement).elseStatement); + case ts.SyntaxKind.IfStatement: + generateNames((node as ts.IfStatement).thenStatement); + generateNames((node as ts.IfStatement).elseStatement); break; - case SyntaxKind.ForStatement: - case SyntaxKind.ForOfStatement: - case SyntaxKind.ForInStatement: - generateNames((node as ForStatement | ForInOrOfStatement).initializer); - generateNames((node as ForStatement | ForInOrOfStatement).statement); + case ts.SyntaxKind.ForStatement: + case ts.SyntaxKind.ForOfStatement: + case ts.SyntaxKind.ForInStatement: + generateNames((node as ts.ForStatement | ts.ForInOrOfStatement).initializer); + generateNames((node as ts.ForStatement | ts.ForInOrOfStatement).statement); break; - case SyntaxKind.SwitchStatement: - generateNames((node as SwitchStatement).caseBlock); + case ts.SyntaxKind.SwitchStatement: + generateNames((node as ts.SwitchStatement).caseBlock); break; - case SyntaxKind.CaseBlock: - forEach((node as CaseBlock).clauses, generateNames); + case ts.SyntaxKind.CaseBlock: + ts.forEach((node as ts.CaseBlock).clauses, generateNames); break; - case SyntaxKind.CaseClause: - case SyntaxKind.DefaultClause: - forEach((node as CaseOrDefaultClause).statements, generateNames); + case ts.SyntaxKind.CaseClause: + case ts.SyntaxKind.DefaultClause: + ts.forEach((node as ts.CaseOrDefaultClause).statements, generateNames); break; - case SyntaxKind.TryStatement: - generateNames((node as TryStatement).tryBlock); - generateNames((node as TryStatement).catchClause); - generateNames((node as TryStatement).finallyBlock); + case ts.SyntaxKind.TryStatement: + generateNames((node as ts.TryStatement).tryBlock); + generateNames((node as ts.TryStatement).catchClause); + generateNames((node as ts.TryStatement).finallyBlock); break; - case SyntaxKind.CatchClause: - generateNames((node as CatchClause).variableDeclaration); - generateNames((node as CatchClause).block); + case ts.SyntaxKind.CatchClause: + generateNames((node as ts.CatchClause).variableDeclaration); + generateNames((node as ts.CatchClause).block); break; - case SyntaxKind.VariableStatement: - generateNames((node as VariableStatement).declarationList); + case ts.SyntaxKind.VariableStatement: + generateNames((node as ts.VariableStatement).declarationList); break; - case SyntaxKind.VariableDeclarationList: - forEach((node as VariableDeclarationList).declarations, generateNames); + case ts.SyntaxKind.VariableDeclarationList: + ts.forEach((node as ts.VariableDeclarationList).declarations, generateNames); break; - case SyntaxKind.VariableDeclaration: - case SyntaxKind.Parameter: - case SyntaxKind.BindingElement: - case SyntaxKind.ClassDeclaration: - generateNameIfNeeded((node as NamedDeclaration).name); + case ts.SyntaxKind.VariableDeclaration: + case ts.SyntaxKind.Parameter: + case ts.SyntaxKind.BindingElement: + case ts.SyntaxKind.ClassDeclaration: + generateNameIfNeeded((node as ts.NamedDeclaration).name); break; - case SyntaxKind.FunctionDeclaration: - generateNameIfNeeded((node as FunctionDeclaration).name); - if (getEmitFlags(node) & EmitFlags.ReuseTempVariableScope) { - forEach((node as FunctionDeclaration).parameters, generateNames); - generateNames((node as FunctionDeclaration).body); + case ts.SyntaxKind.FunctionDeclaration: + generateNameIfNeeded((node as ts.FunctionDeclaration).name); + if (ts.getEmitFlags(node) & ts.EmitFlags.ReuseTempVariableScope) { + ts.forEach((node as ts.FunctionDeclaration).parameters, generateNames); + generateNames((node as ts.FunctionDeclaration).body); } break; - case SyntaxKind.ObjectBindingPattern: - case SyntaxKind.ArrayBindingPattern: - forEach((node as BindingPattern).elements, generateNames); + case ts.SyntaxKind.ObjectBindingPattern: + case ts.SyntaxKind.ArrayBindingPattern: + ts.forEach((node as ts.BindingPattern).elements, generateNames); break; - case SyntaxKind.ImportDeclaration: - generateNames((node as ImportDeclaration).importClause); + case ts.SyntaxKind.ImportDeclaration: + generateNames((node as ts.ImportDeclaration).importClause); break; - case SyntaxKind.ImportClause: - generateNameIfNeeded((node as ImportClause).name); - generateNames((node as ImportClause).namedBindings); + case ts.SyntaxKind.ImportClause: + generateNameIfNeeded((node as ts.ImportClause).name); + generateNames((node as ts.ImportClause).namedBindings); break; - case SyntaxKind.NamespaceImport: - generateNameIfNeeded((node as NamespaceImport).name); + case ts.SyntaxKind.NamespaceImport: + generateNameIfNeeded((node as ts.NamespaceImport).name); break; - case SyntaxKind.NamespaceExport: - generateNameIfNeeded((node as NamespaceExport).name); + case ts.SyntaxKind.NamespaceExport: + generateNameIfNeeded((node as ts.NamespaceExport).name); break; - case SyntaxKind.NamedImports: - forEach((node as NamedImports).elements, generateNames); + case ts.SyntaxKind.NamedImports: + ts.forEach((node as ts.NamedImports).elements, generateNames); break; - case SyntaxKind.ImportSpecifier: - generateNameIfNeeded((node as ImportSpecifier).propertyName || (node as ImportSpecifier).name); + case ts.SyntaxKind.ImportSpecifier: + generateNameIfNeeded((node as ts.ImportSpecifier).propertyName || (node as ts.ImportSpecifier).name); break; } } - function generateMemberNames(node: Node | undefined) { - if (!node) return; + function generateMemberNames(node: ts.Node | undefined) { + if (!node) + return; switch (node.kind) { - case SyntaxKind.PropertyAssignment: - case SyntaxKind.ShorthandPropertyAssignment: - case SyntaxKind.PropertyDeclaration: - case SyntaxKind.MethodDeclaration: - case SyntaxKind.GetAccessor: - case SyntaxKind.SetAccessor: - generateNameIfNeeded((node as NamedDeclaration).name); + case ts.SyntaxKind.PropertyAssignment: + case ts.SyntaxKind.ShorthandPropertyAssignment: + case ts.SyntaxKind.PropertyDeclaration: + case ts.SyntaxKind.MethodDeclaration: + case ts.SyntaxKind.GetAccessor: + case ts.SyntaxKind.SetAccessor: + generateNameIfNeeded((node as ts.NamedDeclaration).name); break; } } - function generateNameIfNeeded(name: DeclarationName | undefined) { + function generateNameIfNeeded(name: ts.DeclarationName | undefined) { if (name) { - if (isGeneratedIdentifier(name)) { + if (ts.isGeneratedIdentifier(name)) { generateName(name); } - else if (isBindingPattern(name)) { + else if (ts.isBindingPattern(name)) { generateNames(name); } } @@ -5070,8 +4997,8 @@ namespace ts { /** * Generate the text for a generated identifier. */ - function generateName(name: GeneratedIdentifier) { - if ((name.autoGenerateFlags & GeneratedIdentifierFlags.KindMask) === GeneratedIdentifierFlags.Node) { + function generateName(name: ts.GeneratedIdentifier) { + if ((name.autoGenerateFlags & ts.GeneratedIdentifierFlags.KindMask) === ts.GeneratedIdentifierFlags.Node) { // Node names generate unique names based on their original node // and are cached based on that node's id. return generateNameCached(getNodeForGeneratedName(name), name.autoGenerateFlags); @@ -5084,8 +5011,8 @@ namespace ts { } } - function generateNameCached(node: Node, flags?: GeneratedIdentifierFlags) { - const nodeId = getNodeId(node); + function generateNameCached(node: ts.Node, flags?: ts.GeneratedIdentifierFlags) { + const nodeId = ts.getNodeId(node); return nodeIdToGeneratedName[nodeId] || (nodeIdToGeneratedName[nodeId] = generateNameForNode(node, flags)); } @@ -5109,12 +5036,12 @@ namespace ts { /** * Returns a value indicating whether a name is unique within a container. */ - function isUniqueLocalName(name: string, container: Node): boolean { - for (let node = container; isNodeDescendantOf(node, container); node = node.nextContainer!) { + function isUniqueLocalName(name: string, container: ts.Node): boolean { + for (let node = container; ts.isNodeDescendantOf(node, container); node = node.nextContainer!) { if (node.locals) { - const local = node.locals.get(escapeLeadingUnderscores(name)); + const local = node.locals.get(ts.escapeLeadingUnderscores(name)); // We conservatively include alias symbols to cover cases where they're emitted as locals - if (local && local.flags & (SymbolFlags.Value | SymbolFlags.ExportValue | SymbolFlags.Alias)) { + if (local && local.flags & (ts.SymbolFlags.Value | ts.SymbolFlags.ExportValue | ts.SymbolFlags.Alias)) { return false; } } @@ -5144,7 +5071,7 @@ namespace ts { // Skip over 'i' and 'n' if (count !== 8 && count !== 13) { const name = count < 26 - ? "_" + String.fromCharCode(CharacterCodes.a + count) + ? "_" + String.fromCharCode(ts.CharacterCodes.a + count) : "_" + (count - 26); if (isUniqueName(name)) { if (reservedInNestedScopes) { @@ -5176,7 +5103,7 @@ namespace ts { } } // Find the first unique 'name_n', where n is a positive number - if (baseName.charCodeAt(baseName.length - 1) !== CharacterCodes._) { + if (baseName.charCodeAt(baseName.length - 1) !== ts.CharacterCodes._) { baseName += "_"; } let i = 1; @@ -5202,7 +5129,7 @@ namespace ts { /** * Generates a unique name for a ModuleDeclaration or EnumDeclaration. */ - function generateNameForModuleOrEnum(node: ModuleDeclaration | EnumDeclaration) { + function generateNameForModuleOrEnum(node: ts.ModuleDeclaration | ts.EnumDeclaration) { const name = getTextOfNode(node.name); // Use module/enum name itself if it is unique, otherwise make a unique variation return isUniqueLocalName(name, node) ? name : makeUniqueName(name); @@ -5211,10 +5138,10 @@ namespace ts { /** * Generates a unique name for an ImportDeclaration or ExportDeclaration. */ - function generateNameForImportOrExportDeclaration(node: ImportDeclaration | ExportDeclaration) { - const expr = getExternalModuleName(node)!; // TODO: GH#18217 - const baseName = isStringLiteral(expr) ? - makeIdentifierFromModuleName(expr.text) : "module"; + function generateNameForImportOrExportDeclaration(node: ts.ImportDeclaration | ts.ExportDeclaration) { + const expr = ts.getExternalModuleName(node)!; // TODO: GH#18217 + const baseName = ts.isStringLiteral(expr) ? + ts.makeIdentifierFromModuleName(expr.text) : "module"; return makeUniqueName(baseName); } @@ -5232,8 +5159,8 @@ namespace ts { return makeUniqueName("class"); } - function generateNameForMethodOrAccessor(node: MethodDeclaration | AccessorDeclaration) { - if (isIdentifier(node.name)) { + function generateNameForMethodOrAccessor(node: ts.MethodDeclaration | ts.AccessorDeclaration) { + if (ts.isIdentifier(node.name)) { return generateNameCached(node.name); } return makeTempVariableName(TempFlags.Auto); @@ -5242,32 +5169,27 @@ namespace ts { /** * Generates a unique name from a node. */ - function generateNameForNode(node: Node, flags?: GeneratedIdentifierFlags): string { + function generateNameForNode(node: ts.Node, flags?: ts.GeneratedIdentifierFlags): string { switch (node.kind) { - case SyntaxKind.Identifier: - return makeUniqueName( - getTextOfNode(node as Identifier), - isUniqueName, - !!(flags! & GeneratedIdentifierFlags.Optimistic), - !!(flags! & GeneratedIdentifierFlags.ReservedInNestedScopes) - ); - case SyntaxKind.ModuleDeclaration: - case SyntaxKind.EnumDeclaration: - return generateNameForModuleOrEnum(node as ModuleDeclaration | EnumDeclaration); - case SyntaxKind.ImportDeclaration: - case SyntaxKind.ExportDeclaration: - return generateNameForImportOrExportDeclaration(node as ImportDeclaration | ExportDeclaration); - case SyntaxKind.FunctionDeclaration: - case SyntaxKind.ClassDeclaration: - case SyntaxKind.ExportAssignment: + case ts.SyntaxKind.Identifier: + return makeUniqueName(getTextOfNode(node as ts.Identifier), isUniqueName, !!(flags! & ts.GeneratedIdentifierFlags.Optimistic), !!(flags! & ts.GeneratedIdentifierFlags.ReservedInNestedScopes)); + case ts.SyntaxKind.ModuleDeclaration: + case ts.SyntaxKind.EnumDeclaration: + return generateNameForModuleOrEnum(node as ts.ModuleDeclaration | ts.EnumDeclaration); + case ts.SyntaxKind.ImportDeclaration: + case ts.SyntaxKind.ExportDeclaration: + return generateNameForImportOrExportDeclaration(node as ts.ImportDeclaration | ts.ExportDeclaration); + case ts.SyntaxKind.FunctionDeclaration: + case ts.SyntaxKind.ClassDeclaration: + case ts.SyntaxKind.ExportAssignment: return generateNameForExportDefault(); - case SyntaxKind.ClassExpression: + case ts.SyntaxKind.ClassExpression: return generateNameForClassExpression(); - case SyntaxKind.MethodDeclaration: - case SyntaxKind.GetAccessor: - case SyntaxKind.SetAccessor: - return generateNameForMethodOrAccessor(node as MethodDeclaration | AccessorDeclaration); - case SyntaxKind.ComputedPropertyName: + case ts.SyntaxKind.MethodDeclaration: + case ts.SyntaxKind.GetAccessor: + case ts.SyntaxKind.SetAccessor: + return generateNameForMethodOrAccessor(node as ts.MethodDeclaration | ts.AccessorDeclaration); + case ts.SyntaxKind.ComputedPropertyName: return makeTempVariableName(TempFlags.Auto, /*reserveInNestedScopes*/ true); default: return makeTempVariableName(TempFlags.Auto); @@ -5277,38 +5199,32 @@ namespace ts { /** * Generates a unique identifier for a node. */ - function makeName(name: GeneratedIdentifier) { - switch (name.autoGenerateFlags & GeneratedIdentifierFlags.KindMask) { - case GeneratedIdentifierFlags.Auto: - return makeTempVariableName(TempFlags.Auto, !!(name.autoGenerateFlags & GeneratedIdentifierFlags.ReservedInNestedScopes)); - case GeneratedIdentifierFlags.Loop: - return makeTempVariableName(TempFlags._i, !!(name.autoGenerateFlags & GeneratedIdentifierFlags.ReservedInNestedScopes)); - case GeneratedIdentifierFlags.Unique: - return makeUniqueName( - idText(name), - (name.autoGenerateFlags & GeneratedIdentifierFlags.FileLevel) ? isFileLevelUniqueName : isUniqueName, - !!(name.autoGenerateFlags & GeneratedIdentifierFlags.Optimistic), - !!(name.autoGenerateFlags & GeneratedIdentifierFlags.ReservedInNestedScopes) - ); + function makeName(name: ts.GeneratedIdentifier) { + switch (name.autoGenerateFlags & ts.GeneratedIdentifierFlags.KindMask) { + case ts.GeneratedIdentifierFlags.Auto: + return makeTempVariableName(TempFlags.Auto, !!(name.autoGenerateFlags & ts.GeneratedIdentifierFlags.ReservedInNestedScopes)); + case ts.GeneratedIdentifierFlags.Loop: + return makeTempVariableName(TempFlags._i, !!(name.autoGenerateFlags & ts.GeneratedIdentifierFlags.ReservedInNestedScopes)); + case ts.GeneratedIdentifierFlags.Unique: + return makeUniqueName(ts.idText(name), (name.autoGenerateFlags & ts.GeneratedIdentifierFlags.FileLevel) ? isFileLevelUniqueName : isUniqueName, !!(name.autoGenerateFlags & ts.GeneratedIdentifierFlags.Optimistic), !!(name.autoGenerateFlags & ts.GeneratedIdentifierFlags.ReservedInNestedScopes)); } - - return Debug.fail("Unsupported GeneratedIdentifierKind."); + return ts.Debug.fail("Unsupported GeneratedIdentifierKind."); } /** * Gets the node from which a name should be generated. */ - function getNodeForGeneratedName(name: GeneratedIdentifier) { + function getNodeForGeneratedName(name: ts.GeneratedIdentifier) { const autoGenerateId = name.autoGenerateId; - let node = name as Node; + let node = name as ts.Node; let original = node.original; while (original) { node = original; // if "node" is a different generated name (having a different // "autoGenerateId"), use it and stop traversing. - if (isIdentifier(node) - && !!(node.autoGenerateFlags! & GeneratedIdentifierFlags.Node) + if (ts.isIdentifier(node) + && !!(node.autoGenerateFlags! & ts.GeneratedIdentifierFlags.Node) && node.autoGenerateId !== autoGenerateId) { break; } @@ -5322,7 +5238,7 @@ namespace ts { // Comments - function pipelineEmitWithComments(hint: EmitHint, node: Node) { + function pipelineEmitWithComments(hint: ts.EmitHint, node: ts.Node) { const pipelinePhase = getNextPipelinePhase(PipelinePhase.Comments, hint, node); const savedContainerPos = containerPos; const savedContainerEnd = containerEnd; @@ -5332,73 +5248,73 @@ namespace ts { emitCommentsAfterNode(node, savedContainerPos, savedContainerEnd, savedDeclarationListContainerEnd); } - function emitCommentsBeforeNode(node: Node) { - const emitFlags = getEmitFlags(node); - const commentRange = getCommentRange(node); + function emitCommentsBeforeNode(node: ts.Node) { + const emitFlags = ts.getEmitFlags(node); + const commentRange = ts.getCommentRange(node); // Emit leading comments emitLeadingCommentsOfNode(node, emitFlags, commentRange.pos, commentRange.end); - if (emitFlags & EmitFlags.NoNestedComments) { + if (emitFlags & ts.EmitFlags.NoNestedComments) { commentsDisabled = true; } } - function emitCommentsAfterNode(node: Node, savedContainerPos: number, savedContainerEnd: number, savedDeclarationListContainerEnd: number) { - const emitFlags = getEmitFlags(node); - const commentRange = getCommentRange(node); + function emitCommentsAfterNode(node: ts.Node, savedContainerPos: number, savedContainerEnd: number, savedDeclarationListContainerEnd: number) { + const emitFlags = ts.getEmitFlags(node); + const commentRange = ts.getCommentRange(node); // Emit trailing comments - if (emitFlags & EmitFlags.NoNestedComments) { + if (emitFlags & ts.EmitFlags.NoNestedComments) { commentsDisabled = false; } emitTrailingCommentsOfNode(node, emitFlags, commentRange.pos, commentRange.end, savedContainerPos, savedContainerEnd, savedDeclarationListContainerEnd); - const typeNode = getTypeNode(node); + const typeNode = ts.getTypeNode(node); if (typeNode) { emitTrailingCommentsOfNode(node, emitFlags, typeNode.pos, typeNode.end, savedContainerPos, savedContainerEnd, savedDeclarationListContainerEnd); } } - function emitLeadingCommentsOfNode(node: Node, emitFlags: EmitFlags, pos: number, end: number) { + function emitLeadingCommentsOfNode(node: ts.Node, emitFlags: ts.EmitFlags, pos: number, end: number) { enterComment(); hasWrittenComment = false; // We have to explicitly check that the node is JsxText because if the compilerOptions.jsx is "preserve" we will not do any transformation. // It is expensive to walk entire tree just to set one kind of node to have no comments. - const skipLeadingComments = pos < 0 || (emitFlags & EmitFlags.NoLeadingComments) !== 0 || node.kind === SyntaxKind.JsxText; - const skipTrailingComments = end < 0 || (emitFlags & EmitFlags.NoTrailingComments) !== 0 || node.kind === SyntaxKind.JsxText; + const skipLeadingComments = pos < 0 || (emitFlags & ts.EmitFlags.NoLeadingComments) !== 0 || node.kind === ts.SyntaxKind.JsxText; + const skipTrailingComments = end < 0 || (emitFlags & ts.EmitFlags.NoTrailingComments) !== 0 || node.kind === ts.SyntaxKind.JsxText; // Save current container state on the stack. if ((pos > 0 || end > 0) && pos !== end) { // Emit leading comments if the position is not synthesized and the node // has not opted out from emitting leading comments. if (!skipLeadingComments) { - emitLeadingComments(pos, /*isEmittedNode*/ node.kind !== SyntaxKind.NotEmittedStatement); + emitLeadingComments(pos, /*isEmittedNode*/ node.kind !== ts.SyntaxKind.NotEmittedStatement); } - if (!skipLeadingComments || (pos >= 0 && (emitFlags & EmitFlags.NoLeadingComments) !== 0)) { + if (!skipLeadingComments || (pos >= 0 && (emitFlags & ts.EmitFlags.NoLeadingComments) !== 0)) { // Advance the container position if comments get emitted or if they've been disabled explicitly using NoLeadingComments. containerPos = pos; } - if (!skipTrailingComments || (end >= 0 && (emitFlags & EmitFlags.NoTrailingComments) !== 0)) { + if (!skipTrailingComments || (end >= 0 && (emitFlags & ts.EmitFlags.NoTrailingComments) !== 0)) { // As above. containerEnd = end; // To avoid invalid comment emit in a down-level binding pattern, we // keep track of the last declaration list container's end - if (node.kind === SyntaxKind.VariableDeclarationList) { + if (node.kind === ts.SyntaxKind.VariableDeclarationList) { declarationListContainerEnd = end; } } } - forEach(getSyntheticLeadingComments(node), emitLeadingSynthesizedComment); + ts.forEach(ts.getSyntheticLeadingComments(node), emitLeadingSynthesizedComment); exitComment(); } - function emitTrailingCommentsOfNode(node: Node, emitFlags: EmitFlags, pos: number, end: number, savedContainerPos: number, savedContainerEnd: number, savedDeclarationListContainerEnd: number) { + function emitTrailingCommentsOfNode(node: ts.Node, emitFlags: ts.EmitFlags, pos: number, end: number, savedContainerPos: number, savedContainerEnd: number, savedDeclarationListContainerEnd: number) { enterComment(); - const skipTrailingComments = end < 0 || (emitFlags & EmitFlags.NoTrailingComments) !== 0 || node.kind === SyntaxKind.JsxText; - forEach(getSyntheticTrailingComments(node), emitTrailingSynthesizedComment); + const skipTrailingComments = end < 0 || (emitFlags & ts.EmitFlags.NoTrailingComments) !== 0 || node.kind === ts.SyntaxKind.JsxText; + ts.forEach(ts.getSyntheticTrailingComments(node), emitTrailingSynthesizedComment); if ((pos > 0 || end > 0) && pos !== end) { // Restore previous container state. containerPos = savedContainerPos; @@ -5407,19 +5323,19 @@ namespace ts { // Emit trailing comments if the position is not synthesized and the node // has not opted out from emitting leading comments and is an emitted node. - if (!skipTrailingComments && node.kind !== SyntaxKind.NotEmittedStatement) { + if (!skipTrailingComments && node.kind !== ts.SyntaxKind.NotEmittedStatement) { emitTrailingComments(end); } } exitComment(); } - function emitLeadingSynthesizedComment(comment: SynthesizedComment) { - if (comment.hasLeadingNewline || comment.kind === SyntaxKind.SingleLineCommentTrivia) { + function emitLeadingSynthesizedComment(comment: ts.SynthesizedComment) { + if (comment.hasLeadingNewline || comment.kind === ts.SyntaxKind.SingleLineCommentTrivia) { writer.writeLine(); } writeSynthesizedComment(comment); - if (comment.hasTrailingNewLine || comment.kind === SyntaxKind.SingleLineCommentTrivia) { + if (comment.hasTrailingNewLine || comment.kind === ts.SyntaxKind.SingleLineCommentTrivia) { writer.writeLine(); } else { @@ -5427,7 +5343,7 @@ namespace ts { } } - function emitTrailingSynthesizedComment(comment: SynthesizedComment) { + function emitTrailingSynthesizedComment(comment: ts.SynthesizedComment) { if (!writer.isAtStartOfLine()) { writer.writeSpace(" "); } @@ -5437,30 +5353,30 @@ namespace ts { } } - function writeSynthesizedComment(comment: SynthesizedComment) { + function writeSynthesizedComment(comment: ts.SynthesizedComment) { const text = formatSynthesizedComment(comment); - const lineMap = comment.kind === SyntaxKind.MultiLineCommentTrivia ? computeLineStarts(text) : undefined; - writeCommentRange(text, lineMap!, writer, 0, text.length, newLine); + const lineMap = comment.kind === ts.SyntaxKind.MultiLineCommentTrivia ? ts.computeLineStarts(text) : undefined; + ts.writeCommentRange(text, lineMap!, writer, 0, text.length, newLine); } - function formatSynthesizedComment(comment: SynthesizedComment) { - return comment.kind === SyntaxKind.MultiLineCommentTrivia + function formatSynthesizedComment(comment: ts.SynthesizedComment) { + return comment.kind === ts.SyntaxKind.MultiLineCommentTrivia ? `/*${comment.text}*/` : `//${comment.text}`; } - function emitBodyWithDetachedComments(node: Node, detachedRange: TextRange, emitCallback: (node: Node) => void) { + function emitBodyWithDetachedComments(node: ts.Node, detachedRange: ts.TextRange, emitCallback: (node: ts.Node) => void) { enterComment(); const { pos, end } = detachedRange; - const emitFlags = getEmitFlags(node); - const skipLeadingComments = pos < 0 || (emitFlags & EmitFlags.NoLeadingComments) !== 0; - const skipTrailingComments = commentsDisabled || end < 0 || (emitFlags & EmitFlags.NoTrailingComments) !== 0; + const emitFlags = ts.getEmitFlags(node); + const skipLeadingComments = pos < 0 || (emitFlags & ts.EmitFlags.NoLeadingComments) !== 0; + const skipTrailingComments = commentsDisabled || end < 0 || (emitFlags & ts.EmitFlags.NoTrailingComments) !== 0; if (!skipLeadingComments) { emitDetachedCommentsAndUpdateCommentsInfo(detachedRange); } exitComment(); - if (emitFlags & EmitFlags.NoNestedComments && !commentsDisabled) { + if (emitFlags & ts.EmitFlags.NoNestedComments && !commentsDisabled) { commentsDisabled = true; emitCallback(node); commentsDisabled = false; @@ -5480,26 +5396,26 @@ namespace ts { } - function originalNodesHaveSameParent(nodeA: Node, nodeB: Node) { - nodeA = getOriginalNode(nodeA); + function originalNodesHaveSameParent(nodeA: ts.Node, nodeB: ts.Node) { + nodeA = ts.getOriginalNode(nodeA); // For performance, do not call `getOriginalNode` for `nodeB` if `nodeA` doesn't even // have a parent node. - return nodeA.parent && nodeA.parent === getOriginalNode(nodeB).parent; + return nodeA.parent && nodeA.parent === ts.getOriginalNode(nodeB).parent; } - function siblingNodePositionsAreComparable(previousNode: Node, nextNode: Node) { + function siblingNodePositionsAreComparable(previousNode: ts.Node, nextNode: ts.Node) { if (nextNode.pos < previousNode.end) { return false; } - previousNode = getOriginalNode(previousNode); - nextNode = getOriginalNode(nextNode); + previousNode = ts.getOriginalNode(previousNode); + nextNode = ts.getOriginalNode(nextNode); const parent = previousNode.parent; if (!parent || parent !== nextNode.parent) { return false; } - const parentNodeArray = getContainingNodeArray(previousNode); + const parentNodeArray = ts.getContainingNodeArray(previousNode); const prevNodeIndex = parentNodeArray?.indexOf(previousNode); return prevNodeIndex !== undefined && prevNodeIndex > -1 && parentNodeArray!.indexOf(nextNode) === prevNodeIndex + 1; } @@ -5528,13 +5444,13 @@ namespace ts { } } - function emitTripleSlashLeadingComment(commentPos: number, commentEnd: number, kind: SyntaxKind, hasTrailingNewLine: boolean, rangePos: number) { + function emitTripleSlashLeadingComment(commentPos: number, commentEnd: number, kind: ts.SyntaxKind, hasTrailingNewLine: boolean, rangePos: number) { if (isTripleSlashComment(commentPos, commentEnd)) { emitLeadingComment(commentPos, commentEnd, kind, hasTrailingNewLine, rangePos); } } - function emitNonTripleSlashLeadingComment(commentPos: number, commentEnd: number, kind: SyntaxKind, hasTrailingNewLine: boolean, rangePos: number) { + function emitNonTripleSlashLeadingComment(commentPos: number, commentEnd: number, kind: ts.SyntaxKind, hasTrailingNewLine: boolean, rangePos: number) { if (!isTripleSlashComment(commentPos, commentEnd)) { emitLeadingComment(commentPos, commentEnd, kind, hasTrailingNewLine, rangePos); } @@ -5542,27 +5458,28 @@ namespace ts { function shouldWriteComment(text: string, pos: number) { if (printerOptions.onlyPrintJsDocStyle) { - return (isJSDocLikeText(text, pos) || isPinnedComment(text, pos)); + return (ts.isJSDocLikeText(text, pos) || ts.isPinnedComment(text, pos)); } return true; } - function emitLeadingComment(commentPos: number, commentEnd: number, kind: SyntaxKind, hasTrailingNewLine: boolean, rangePos: number) { - if (!currentSourceFile || !shouldWriteComment(currentSourceFile.text, commentPos)) return; + function emitLeadingComment(commentPos: number, commentEnd: number, kind: ts.SyntaxKind, hasTrailingNewLine: boolean, rangePos: number) { + if (!currentSourceFile || !shouldWriteComment(currentSourceFile.text, commentPos)) + return; if (!hasWrittenComment) { - emitNewLineBeforeLeadingCommentOfPosition(getCurrentLineMap(), writer, rangePos, commentPos); + ts.emitNewLineBeforeLeadingCommentOfPosition(getCurrentLineMap(), writer, rangePos, commentPos); hasWrittenComment = true; } // Leading comments are emitted at /*leading comment1 */space/*leading comment*/space emitPos(commentPos); - writeCommentRange(currentSourceFile.text, getCurrentLineMap(), writer, commentPos, commentEnd, newLine); + ts.writeCommentRange(currentSourceFile.text, getCurrentLineMap(), writer, commentPos, commentEnd, newLine); emitPos(commentEnd); if (hasTrailingNewLine) { writer.writeLine(); } - else if (kind === SyntaxKind.MultiLineCommentTrivia) { + else if (kind === ts.SyntaxKind.MultiLineCommentTrivia) { writer.writeSpace(" "); } } @@ -5579,15 +5496,16 @@ namespace ts { forEachTrailingCommentToEmit(pos, emitTrailingComment); } - function emitTrailingComment(commentPos: number, commentEnd: number, _kind: SyntaxKind, hasTrailingNewLine: boolean) { - if (!currentSourceFile || !shouldWriteComment(currentSourceFile.text, commentPos)) return; + function emitTrailingComment(commentPos: number, commentEnd: number, _kind: ts.SyntaxKind, hasTrailingNewLine: boolean) { + if (!currentSourceFile || !shouldWriteComment(currentSourceFile.text, commentPos)) + return; // trailing comments are emitted at space/*trailing comment1 */space/*trailing comment2*/ if (!writer.isAtStartOfLine()) { writer.writeSpace(" "); } emitPos(commentPos); - writeCommentRange(currentSourceFile.text, getCurrentLineMap(), writer, commentPos, commentEnd, newLine); + ts.writeCommentRange(currentSourceFile.text, getCurrentLineMap(), writer, commentPos, commentEnd, newLine); emitPos(commentEnd); if (hasTrailingNewLine) { @@ -5604,25 +5522,27 @@ namespace ts { exitComment(); } - function emitTrailingCommentOfPositionNoNewline(commentPos: number, commentEnd: number, kind: SyntaxKind) { - if (!currentSourceFile) return; + function emitTrailingCommentOfPositionNoNewline(commentPos: number, commentEnd: number, kind: ts.SyntaxKind) { + if (!currentSourceFile) + return; // trailing comments of a position are emitted at /*trailing comment1 */space/*trailing comment*/space emitPos(commentPos); - writeCommentRange(currentSourceFile.text, getCurrentLineMap(), writer, commentPos, commentEnd, newLine); + ts.writeCommentRange(currentSourceFile.text, getCurrentLineMap(), writer, commentPos, commentEnd, newLine); emitPos(commentEnd); - if (kind === SyntaxKind.SingleLineCommentTrivia) { + if (kind === ts.SyntaxKind.SingleLineCommentTrivia) { writer.writeLine(); // still write a newline for single-line comments, so closing tokens aren't written on the same line } } - function emitTrailingCommentOfPosition(commentPos: number, commentEnd: number, _kind: SyntaxKind, hasTrailingNewLine: boolean) { - if(!currentSourceFile) return; + function emitTrailingCommentOfPosition(commentPos: number, commentEnd: number, _kind: ts.SyntaxKind, hasTrailingNewLine: boolean) { + if (!currentSourceFile) + return; // trailing comments of a position are emitted at /*trailing comment1 */space/*trailing comment*/space emitPos(commentPos); - writeCommentRange(currentSourceFile.text, getCurrentLineMap(), writer, commentPos, commentEnd, newLine); + ts.writeCommentRange(currentSourceFile.text, getCurrentLineMap(), writer, commentPos, commentEnd, newLine); emitPos(commentEnd); if (hasTrailingNewLine) { @@ -5633,33 +5553,34 @@ namespace ts { } } - function forEachLeadingCommentToEmit(pos: number, cb: (commentPos: number, commentEnd: number, kind: SyntaxKind, hasTrailingNewLine: boolean, rangePos: number) => void) { + function forEachLeadingCommentToEmit(pos: number, cb: (commentPos: number, commentEnd: number, kind: ts.SyntaxKind, hasTrailingNewLine: boolean, rangePos: number) => void) { // Emit the leading comments only if the container's pos doesn't match because the container should take care of emitting these comments if (currentSourceFile && (containerPos === -1 || pos !== containerPos)) { if (hasDetachedComments(pos)) { forEachLeadingCommentWithoutDetachedComments(cb); } else { - forEachLeadingCommentRange(currentSourceFile.text, pos, cb, /*state*/ pos); + ts.forEachLeadingCommentRange(currentSourceFile.text, pos, cb, /*state*/ pos); } } } - function forEachTrailingCommentToEmit(end: number, cb: (commentPos: number, commentEnd: number, kind: SyntaxKind, hasTrailingNewLine: boolean) => void) { + function forEachTrailingCommentToEmit(end: number, cb: (commentPos: number, commentEnd: number, kind: ts.SyntaxKind, hasTrailingNewLine: boolean) => void) { // Emit the trailing comments only if the container's end doesn't match because the container should take care of emitting these comments if (currentSourceFile && (containerEnd === -1 || (end !== containerEnd && end !== declarationListContainerEnd))) { - forEachTrailingCommentRange(currentSourceFile.text, end, cb); + ts.forEachTrailingCommentRange(currentSourceFile.text, end, cb); } } function hasDetachedComments(pos: number) { - return detachedCommentsInfo !== undefined && last(detachedCommentsInfo).nodePos === pos; + return detachedCommentsInfo !== undefined && ts.last(detachedCommentsInfo).nodePos === pos; } - function forEachLeadingCommentWithoutDetachedComments(cb: (commentPos: number, commentEnd: number, kind: SyntaxKind, hasTrailingNewLine: boolean, rangePos: number) => void) { - if (!currentSourceFile) return; + function forEachLeadingCommentWithoutDetachedComments(cb: (commentPos: number, commentEnd: number, kind: ts.SyntaxKind, hasTrailingNewLine: boolean, rangePos: number) => void) { + if (!currentSourceFile) + return; // get the leading comments from detachedPos - const pos = last(detachedCommentsInfo!).detachedCommentEndPos; + const pos = ts.last(detachedCommentsInfo!).detachedCommentEndPos; if (detachedCommentsInfo!.length - 1) { detachedCommentsInfo!.pop(); } @@ -5667,11 +5588,11 @@ namespace ts { detachedCommentsInfo = undefined; } - forEachLeadingCommentRange(currentSourceFile.text, pos, cb, /*state*/ pos); + ts.forEachLeadingCommentRange(currentSourceFile.text, pos, cb, /*state*/ pos); } - function emitDetachedCommentsAndUpdateCommentsInfo(range: TextRange) { - const currentDetachedCommentInfo = currentSourceFile && emitDetachedComments(currentSourceFile.text, getCurrentLineMap(), writer, emitComment, range, newLine, commentsDisabled); + function emitDetachedCommentsAndUpdateCommentsInfo(range: ts.TextRange) { + const currentDetachedCommentInfo = currentSourceFile && ts.emitDetachedComments(currentSourceFile.text, getCurrentLineMap(), writer, emitComment, range, newLine, commentsDisabled); if (currentDetachedCommentInfo) { if (detachedCommentsInfo) { detachedCommentsInfo.push(currentDetachedCommentInfo); @@ -5682,10 +5603,11 @@ namespace ts { } } - function emitComment(text: string, lineMap: number[], writer: EmitTextWriter, commentPos: number, commentEnd: number, newLine: string) { - if (!currentSourceFile || !shouldWriteComment(currentSourceFile.text, commentPos)) return; + function emitComment(text: string, lineMap: number[], writer: ts.EmitTextWriter, commentPos: number, commentEnd: number, newLine: string) { + if (!currentSourceFile || !shouldWriteComment(currentSourceFile.text, commentPos)) + return; emitPos(commentPos); - writeCommentRange(text, lineMap, writer, commentPos, commentEnd, newLine); + ts.writeCommentRange(text, lineMap, writer, commentPos, commentEnd, newLine); emitPos(commentEnd); } @@ -5695,68 +5617,61 @@ namespace ts { * @return true if the comment is a triple-slash comment else false */ function isTripleSlashComment(commentPos: number, commentEnd: number) { - return !!currentSourceFile && isRecognizedTripleSlashComment(currentSourceFile.text, commentPos, commentEnd); + return !!currentSourceFile && ts.isRecognizedTripleSlashComment(currentSourceFile.text, commentPos, commentEnd); } // Source Maps - function getParsedSourceMap(node: UnparsedSource) { + function getParsedSourceMap(node: ts.UnparsedSource) { if (node.parsedSourceMap === undefined && node.sourceMapText !== undefined) { - node.parsedSourceMap = tryParseRawSourceMap(node.sourceMapText) || false; + node.parsedSourceMap = ts.tryParseRawSourceMap(node.sourceMapText) || false; } return node.parsedSourceMap || undefined; } - function pipelineEmitWithSourceMaps(hint: EmitHint, node: Node) { + function pipelineEmitWithSourceMaps(hint: ts.EmitHint, node: ts.Node) { const pipelinePhase = getNextPipelinePhase(PipelinePhase.SourceMaps, hint, node); emitSourceMapsBeforeNode(node); pipelinePhase(hint, node); emitSourceMapsAfterNode(node); } - function emitSourceMapsBeforeNode(node: Node) { - const emitFlags = getEmitFlags(node); - const sourceMapRange = getSourceMapRange(node); + function emitSourceMapsBeforeNode(node: ts.Node) { + const emitFlags = ts.getEmitFlags(node); + const sourceMapRange = ts.getSourceMapRange(node); // Emit leading sourcemap - if (isUnparsedNode(node)) { - Debug.assertIsDefined(node.parent, "UnparsedNodes must have parent pointers"); + if (ts.isUnparsedNode(node)) { + ts.Debug.assertIsDefined(node.parent, "UnparsedNodes must have parent pointers"); const parsed = getParsedSourceMap(node.parent); if (parsed && sourceMapGenerator) { - sourceMapGenerator.appendSourceMap( - writer.getLine(), - writer.getColumn(), - parsed, - node.parent.sourceMapPath!, - node.parent.getLineAndCharacterOfPosition(node.pos), - node.parent.getLineAndCharacterOfPosition(node.end) - ); + sourceMapGenerator.appendSourceMap(writer.getLine(), writer.getColumn(), parsed, node.parent.sourceMapPath!, node.parent.getLineAndCharacterOfPosition(node.pos), node.parent.getLineAndCharacterOfPosition(node.end)); } } else { const source = sourceMapRange.source || sourceMapSource; - if (node.kind !== SyntaxKind.NotEmittedStatement - && (emitFlags & EmitFlags.NoLeadingSourceMap) === 0 + if (node.kind !== ts.SyntaxKind.NotEmittedStatement + && (emitFlags & ts.EmitFlags.NoLeadingSourceMap) === 0 && sourceMapRange.pos >= 0) { emitSourcePos(sourceMapRange.source || sourceMapSource, skipSourceTrivia(source, sourceMapRange.pos)); } - if (emitFlags & EmitFlags.NoNestedSourceMaps) { + if (emitFlags & ts.EmitFlags.NoNestedSourceMaps) { sourceMapsDisabled = true; } } } - function emitSourceMapsAfterNode(node: Node) { - const emitFlags = getEmitFlags(node); - const sourceMapRange = getSourceMapRange(node); + function emitSourceMapsAfterNode(node: ts.Node) { + const emitFlags = ts.getEmitFlags(node); + const sourceMapRange = ts.getSourceMapRange(node); // Emit trailing sourcemap - if (!isUnparsedNode(node)) { - if (emitFlags & EmitFlags.NoNestedSourceMaps) { + if (!ts.isUnparsedNode(node)) { + if (emitFlags & ts.EmitFlags.NoNestedSourceMaps) { sourceMapsDisabled = false; } - if (node.kind !== SyntaxKind.NotEmittedStatement - && (emitFlags & EmitFlags.NoTrailingSourceMap) === 0 + if (node.kind !== ts.SyntaxKind.NotEmittedStatement + && (emitFlags & ts.EmitFlags.NoTrailingSourceMap) === 0 && sourceMapRange.end >= 0) { emitSourcePos(sourceMapRange.source || sourceMapSource, sourceMapRange.end); } @@ -5766,8 +5681,8 @@ namespace ts { /** * Skips trivia such as comments and white-space that can be optionally overridden by the source-map source */ - function skipSourceTrivia(source: SourceMapSource, pos: number): number { - return source.skipTrivia ? source.skipTrivia(pos) : skipTrivia(source.text, pos); + function skipSourceTrivia(source: ts.SourceMapSource, pos: number): number { + return source.skipTrivia ? source.skipTrivia(pos) : ts.skipTrivia(source.text, pos); } /** @@ -5779,21 +5694,16 @@ namespace ts { * @param pos The position. */ function emitPos(pos: number) { - if (sourceMapsDisabled || positionIsSynthesized(pos) || isJsonSourceMapSource(sourceMapSource)) { + if (sourceMapsDisabled || ts.positionIsSynthesized(pos) || isJsonSourceMapSource(sourceMapSource)) { return; } - const { line: sourceLine, character: sourceCharacter } = getLineAndCharacterOfPosition(sourceMapSource, pos); - sourceMapGenerator!.addMapping( - writer.getLine(), - writer.getColumn(), - sourceMapSourceIndex, - sourceLine, - sourceCharacter, + const { line: sourceLine, character: sourceCharacter } = ts.getLineAndCharacterOfPosition(sourceMapSource, pos); + sourceMapGenerator!.addMapping(writer.getLine(), writer.getColumn(), sourceMapSourceIndex, sourceLine, sourceCharacter, /*nameIndex*/ undefined); } - function emitSourcePos(source: SourceMapSource, pos: number) { + function emitSourcePos(source: ts.SourceMapSource, pos: number) { if (source !== sourceMapSource) { const savedSourceMapSource = sourceMapSource; const savedSourceMapSourceIndex = sourceMapSourceIndex; @@ -5814,32 +5724,33 @@ namespace ts { * @param tokenStartPos The start pos of the token. * @param emitCallback The callback used to emit the token. */ - function emitTokenWithSourceMap(node: Node | undefined, token: SyntaxKind, writer: (s: string) => void, tokenPos: number, emitCallback: (token: SyntaxKind, writer: (s: string) => void, tokenStartPos: number) => number) { - if (sourceMapsDisabled || node && isInJsonFile(node)) { + function emitTokenWithSourceMap(node: ts.Node | undefined, token: ts.SyntaxKind, writer: (s: string) => void, tokenPos: number, emitCallback: (token: ts.SyntaxKind, writer: (s: string) => void, tokenStartPos: number) => number) { + if (sourceMapsDisabled || node && ts.isInJsonFile(node)) { return emitCallback(token, writer, tokenPos); } const emitNode = node && node.emitNode; - const emitFlags = emitNode && emitNode.flags || EmitFlags.None; + const emitFlags = emitNode && emitNode.flags || ts.EmitFlags.None; const range = emitNode && emitNode.tokenSourceMapRanges && emitNode.tokenSourceMapRanges[token]; const source = range && range.source || sourceMapSource; tokenPos = skipSourceTrivia(source, range ? range.pos : tokenPos); - if ((emitFlags & EmitFlags.NoTokenLeadingSourceMaps) === 0 && tokenPos >= 0) { + if ((emitFlags & ts.EmitFlags.NoTokenLeadingSourceMaps) === 0 && tokenPos >= 0) { emitSourcePos(source, tokenPos); } tokenPos = emitCallback(token, writer, tokenPos); - if (range) tokenPos = range.end; - if ((emitFlags & EmitFlags.NoTokenTrailingSourceMaps) === 0 && tokenPos >= 0) { + if (range) + tokenPos = range.end; + if ((emitFlags & ts.EmitFlags.NoTokenTrailingSourceMaps) === 0 && tokenPos >= 0) { emitSourcePos(source, tokenPos); } return tokenPos; } - function setSourceMapSource(source: SourceMapSource) { + function setSourceMapSource(source: ts.SourceMapSource) { if (sourceMapsDisabled) { return; } @@ -5866,61 +5777,59 @@ namespace ts { mostRecentlyAddedSourceMapSourceIndex = sourceMapSourceIndex; } - function resetSourceMapSource(source: SourceMapSource, sourceIndex: number) { + function resetSourceMapSource(source: ts.SourceMapSource, sourceIndex: number) { sourceMapSource = source; sourceMapSourceIndex = sourceIndex; } - function isJsonSourceMapSource(sourceFile: SourceMapSource) { - return fileExtensionIs(sourceFile.fileName, Extension.Json); + function isJsonSourceMapSource(sourceFile: ts.SourceMapSource) { + return ts.fileExtensionIs(sourceFile.fileName, ts.Extension.Json); } } function createBracketsMap() { const brackets: string[][] = []; - brackets[ListFormat.Braces] = ["{", "}"]; - brackets[ListFormat.Parenthesis] = ["(", ")"]; - brackets[ListFormat.AngleBrackets] = ["<", ">"]; - brackets[ListFormat.SquareBrackets] = ["[", "]"]; + brackets[ts.ListFormat.Braces] = ["{", "}"]; + brackets[ts.ListFormat.Parenthesis] = ["(", ")"]; + brackets[ts.ListFormat.AngleBrackets] = ["<", ">"]; + brackets[ts.ListFormat.SquareBrackets] = ["[", "]"]; return brackets; } - function getOpeningBracket(format: ListFormat) { - return brackets[format & ListFormat.BracketsMask][0]; + function getOpeningBracket(format: ts.ListFormat) { + return brackets[format & ts.ListFormat.BracketsMask][0]; } - function getClosingBracket(format: ListFormat) { - return brackets[format & ListFormat.BracketsMask][1]; + function getClosingBracket(format: ts.ListFormat) { + return brackets[format & ts.ListFormat.BracketsMask][1]; } // Flags enum to track count of temp variables and a few dedicated names const enum TempFlags { - Auto = 0x00000000, // No preferred name - CountMask = 0x0FFFFFFF, // Temp variable counter - _i = 0x10000000, // Use/preference flag for '_i' + Auto = 0x00000000, + CountMask = 0x0FFFFFFF, + _i = 0x10000000 } - interface OrdinalParentheizerRuleSelector { + interface OrdinalParentheizerRuleSelector { select(index: number): ((node: T) => T) | undefined; } - type ParenthesizerRule = (node: T) => T; - - type ParenthesizerRuleOrSelector = OrdinalParentheizerRuleSelector | ParenthesizerRule; - - function emitListItemNoParenthesizer(node: Node, emit: (node: Node, parenthesizerRule?: ((node: Node) => Node) | undefined) => void, _parenthesizerRule: ParenthesizerRuleOrSelector | undefined, _index: number) { + type ParenthesizerRule = (node: T) => T; + type ParenthesizerRuleOrSelector = OrdinalParentheizerRuleSelector | ParenthesizerRule; + function emitListItemNoParenthesizer(node: ts.Node, emit: (node: ts.Node, parenthesizerRule?: ((node: ts.Node) => ts.Node) | undefined) => void, _parenthesizerRule: ParenthesizerRuleOrSelector | undefined, _index: number) { emit(node); } - function emitListItemWithParenthesizerRuleSelector(node: Node, emit: (node: Node, parenthesizerRule?: ((node: Node) => Node) | undefined) => void, parenthesizerRuleSelector: OrdinalParentheizerRuleSelector, index: number) { + function emitListItemWithParenthesizerRuleSelector(node: ts.Node, emit: (node: ts.Node, parenthesizerRule?: ((node: ts.Node) => ts.Node) | undefined) => void, parenthesizerRuleSelector: OrdinalParentheizerRuleSelector, index: number) { emit(node, parenthesizerRuleSelector.select(index)); } - function emitListItemWithParenthesizerRule(node: Node, emit: (node: Node, parenthesizerRule?: ((node: Node) => Node) | undefined) => void, parenthesizerRule: ParenthesizerRule | undefined, _index: number) { + function emitListItemWithParenthesizerRule(node: ts.Node, emit: (node: ts.Node, parenthesizerRule?: ((node: ts.Node) => ts.Node) | undefined) => void, parenthesizerRule: ParenthesizerRule | undefined, _index: number) { emit(node, parenthesizerRule); } - function getEmitListItem | undefined>(emit: (node: Node, parenthesizerRule?: ((node: Node) => Node) | undefined) => void, parenthesizerRule: R): (node: Node, emit: (node: Node, parenthesizerRule?: ((node: Node) => Node) | undefined) => void, parenthesizerRule: R, index: number) => void { + function getEmitListItem | undefined>(emit: (node: ts.Node, parenthesizerRule?: ((node: ts.Node) => ts.Node) | undefined) => void, parenthesizerRule: R): (node: ts.Node, emit: (node: ts.Node, parenthesizerRule?: ((node: ts.Node) => ts.Node) | undefined) => void, parenthesizerRule: R, index: number) => void { return emit.length === 1 ? emitListItemNoParenthesizer : typeof parenthesizerRule === "object" ? emitListItemWithParenthesizerRuleSelector : emitListItemWithParenthesizerRule; diff --git a/src/compiler/factory/baseNodeFactory.ts b/src/compiler/factory/baseNodeFactory.ts index 26be7e95ef237..44da062531637 100644 --- a/src/compiler/factory/baseNodeFactory.ts +++ b/src/compiler/factory/baseNodeFactory.ts @@ -6,11 +6,11 @@ namespace ts { */ /* @internal */ export interface BaseNodeFactory { - createBaseSourceFileNode(kind: SyntaxKind): Node; - createBaseIdentifierNode(kind: SyntaxKind): Node; - createBasePrivateIdentifierNode(kind: SyntaxKind): Node; - createBaseTokenNode(kind: SyntaxKind): Node; - createBaseNode(kind: SyntaxKind): Node; + createBaseSourceFileNode(kind: ts.SyntaxKind): ts.Node; + createBaseIdentifierNode(kind: ts.SyntaxKind): ts.Node; + createBasePrivateIdentifierNode(kind: ts.SyntaxKind): ts.Node; + createBaseTokenNode(kind: ts.SyntaxKind): ts.Node; + createBaseNode(kind: ts.SyntaxKind): ts.Node; } /** @@ -18,11 +18,11 @@ namespace ts { */ export function createBaseNodeFactory(): BaseNodeFactory { // tslint:disable variable-name - let NodeConstructor: new (kind: SyntaxKind, pos?: number, end?: number) => Node; - let TokenConstructor: new (kind: SyntaxKind, pos?: number, end?: number) => Node; - let IdentifierConstructor: new (kind: SyntaxKind, pos?: number, end?: number) => Node; - let PrivateIdentifierConstructor: new (kind: SyntaxKind, pos?: number, end?: number) => Node; - let SourceFileConstructor: new (kind: SyntaxKind, pos?: number, end?: number) => Node; + let NodeConstructor: new (kind: ts.SyntaxKind, pos?: number, end?: number) => ts.Node; + let TokenConstructor: new (kind: ts.SyntaxKind, pos?: number, end?: number) => ts.Node; + let IdentifierConstructor: new (kind: ts.SyntaxKind, pos?: number, end?: number) => ts.Node; + let PrivateIdentifierConstructor: new (kind: ts.SyntaxKind, pos?: number, end?: number) => ts.Node; + let SourceFileConstructor: new (kind: ts.SyntaxKind, pos?: number, end?: number) => ts.Node; // tslint:enable variable-name return { @@ -33,24 +33,24 @@ namespace ts { createBaseNode }; - function createBaseSourceFileNode(kind: SyntaxKind): Node { - return new (SourceFileConstructor || (SourceFileConstructor = objectAllocator.getSourceFileConstructor()))(kind, /*pos*/ -1, /*end*/ -1); + function createBaseSourceFileNode(kind: ts.SyntaxKind): ts.Node { + return new (SourceFileConstructor || (SourceFileConstructor = ts.objectAllocator.getSourceFileConstructor()))(kind, /*pos*/ -1, /*end*/ -1); } - function createBaseIdentifierNode(kind: SyntaxKind): Node { - return new (IdentifierConstructor || (IdentifierConstructor = objectAllocator.getIdentifierConstructor()))(kind, /*pos*/ -1, /*end*/ -1); + function createBaseIdentifierNode(kind: ts.SyntaxKind): ts.Node { + return new (IdentifierConstructor || (IdentifierConstructor = ts.objectAllocator.getIdentifierConstructor()))(kind, /*pos*/ -1, /*end*/ -1); } - function createBasePrivateIdentifierNode(kind: SyntaxKind): Node { - return new (PrivateIdentifierConstructor || (PrivateIdentifierConstructor = objectAllocator.getPrivateIdentifierConstructor()))(kind, /*pos*/ -1, /*end*/ -1); + function createBasePrivateIdentifierNode(kind: ts.SyntaxKind): ts.Node { + return new (PrivateIdentifierConstructor || (PrivateIdentifierConstructor = ts.objectAllocator.getPrivateIdentifierConstructor()))(kind, /*pos*/ -1, /*end*/ -1); } - function createBaseTokenNode(kind: SyntaxKind): Node { - return new (TokenConstructor || (TokenConstructor = objectAllocator.getTokenConstructor()))(kind, /*pos*/ -1, /*end*/ -1); + function createBaseTokenNode(kind: ts.SyntaxKind): ts.Node { + return new (TokenConstructor || (TokenConstructor = ts.objectAllocator.getTokenConstructor()))(kind, /*pos*/ -1, /*end*/ -1); } - function createBaseNode(kind: SyntaxKind): Node { - return new (NodeConstructor || (NodeConstructor = objectAllocator.getNodeConstructor()))(kind, /*pos*/ -1, /*end*/ -1); + function createBaseNode(kind: ts.SyntaxKind): ts.Node { + return new (NodeConstructor || (NodeConstructor = ts.objectAllocator.getNodeConstructor()))(kind, /*pos*/ -1, /*end*/ -1); } } } \ No newline at end of file diff --git a/src/compiler/factory/emitHelpers.ts b/src/compiler/factory/emitHelpers.ts index 85a12581965f8..1e23dc5dd775f 100644 --- a/src/compiler/factory/emitHelpers.ts +++ b/src/compiler/factory/emitHelpers.ts @@ -1,46 +1,46 @@ /* @internal */ namespace ts { export interface EmitHelperFactory { - getUnscopedHelperName(name: string): Identifier; + getUnscopedHelperName(name: string): ts.Identifier; // TypeScript Helpers - createDecorateHelper(decoratorExpressions: readonly Expression[], target: Expression, memberName?: Expression, descriptor?: Expression): Expression; - createMetadataHelper(metadataKey: string, metadataValue: Expression): Expression; - createParamHelper(expression: Expression, parameterOffset: number): Expression; + createDecorateHelper(decoratorExpressions: readonly ts.Expression[], target: ts.Expression, memberName?: ts.Expression, descriptor?: ts.Expression): ts.Expression; + createMetadataHelper(metadataKey: string, metadataValue: ts.Expression): ts.Expression; + createParamHelper(expression: ts.Expression, parameterOffset: number): ts.Expression; // ES2018 Helpers - createAssignHelper(attributesSegments: readonly Expression[]): Expression; - createAwaitHelper(expression: Expression): Expression; - createAsyncGeneratorHelper(generatorFunc: FunctionExpression, hasLexicalThis: boolean): Expression; - createAsyncDelegatorHelper(expression: Expression): Expression; - createAsyncValuesHelper(expression: Expression): Expression; + createAssignHelper(attributesSegments: readonly ts.Expression[]): ts.Expression; + createAwaitHelper(expression: ts.Expression): ts.Expression; + createAsyncGeneratorHelper(generatorFunc: ts.FunctionExpression, hasLexicalThis: boolean): ts.Expression; + createAsyncDelegatorHelper(expression: ts.Expression): ts.Expression; + createAsyncValuesHelper(expression: ts.Expression): ts.Expression; // ES2018 Destructuring Helpers - createRestHelper(value: Expression, elements: readonly BindingOrAssignmentElement[], computedTempVariables: readonly Expression[] | undefined, location: TextRange): Expression; + createRestHelper(value: ts.Expression, elements: readonly ts.BindingOrAssignmentElement[], computedTempVariables: readonly ts.Expression[] | undefined, location: ts.TextRange): ts.Expression; // ES2017 Helpers - createAwaiterHelper(hasLexicalThis: boolean, hasLexicalArguments: boolean, promiseConstructor: EntityName | Expression | undefined, body: Block): Expression; + createAwaiterHelper(hasLexicalThis: boolean, hasLexicalArguments: boolean, promiseConstructor: ts.EntityName | ts.Expression | undefined, body: ts.Block): ts.Expression; // ES2015 Helpers - createExtendsHelper(name: Identifier): Expression; - createTemplateObjectHelper(cooked: ArrayLiteralExpression, raw: ArrayLiteralExpression): Expression; - createSpreadArrayHelper(to: Expression, from: Expression, packFrom: boolean): Expression; + createExtendsHelper(name: ts.Identifier): ts.Expression; + createTemplateObjectHelper(cooked: ts.ArrayLiteralExpression, raw: ts.ArrayLiteralExpression): ts.Expression; + createSpreadArrayHelper(to: ts.Expression, from: ts.Expression, packFrom: boolean): ts.Expression; // ES2015 Destructuring Helpers - createValuesHelper(expression: Expression): Expression; - createReadHelper(iteratorRecord: Expression, count: number | undefined): Expression; + createValuesHelper(expression: ts.Expression): ts.Expression; + createReadHelper(iteratorRecord: ts.Expression, count: number | undefined): ts.Expression; // ES2015 Generator Helpers - createGeneratorHelper(body: FunctionExpression): Expression; + createGeneratorHelper(body: ts.FunctionExpression): ts.Expression; // ES Module Helpers - createCreateBindingHelper(module: Expression, inputName: Expression, outputName: Expression | undefined): Expression; - createImportStarHelper(expression: Expression): Expression; - createImportStarCallbackHelper(): Expression; - createImportDefaultHelper(expression: Expression): Expression; - createExportStarHelper(moduleExpression: Expression, exportsExpression?: Expression): Expression; + createCreateBindingHelper(module: ts.Expression, inputName: ts.Expression, outputName: ts.Expression | undefined): ts.Expression; + createImportStarHelper(expression: ts.Expression): ts.Expression; + createImportStarCallbackHelper(): ts.Expression; + createImportDefaultHelper(expression: ts.Expression): ts.Expression; + createExportStarHelper(moduleExpression: ts.Expression, exportsExpression?: ts.Expression): ts.Expression; // Class Fields Helpers - createClassPrivateFieldGetHelper(receiver: Expression, state: Identifier, kind: PrivateIdentifierKind, f: Identifier | undefined): Expression; - createClassPrivateFieldSetHelper(receiver: Expression, state: Identifier, value: Expression, kind: PrivateIdentifierKind, f: Identifier | undefined): Expression; - createClassPrivateFieldInHelper(state: Identifier, receiver: Expression): Expression; + createClassPrivateFieldGetHelper(receiver: ts.Expression, state: ts.Identifier, kind: ts.PrivateIdentifierKind, f: ts.Identifier | undefined): ts.Expression; + createClassPrivateFieldSetHelper(receiver: ts.Expression, state: ts.Identifier, value: ts.Expression, kind: ts.PrivateIdentifierKind, f: ts.Identifier | undefined): ts.Expression; + createClassPrivateFieldInHelper(state: ts.Identifier, receiver: ts.Expression): ts.Expression; } - export function createEmitHelperFactory(context: TransformationContext): EmitHelperFactory { + export function createEmitHelperFactory(context: ts.TransformationContext): EmitHelperFactory { const factory = context.factory; - const immutableTrue = memoize(() => setEmitFlags(factory.createTrue(), EmitFlags.Immutable)); - const immutableFalse = memoize(() => setEmitFlags(factory.createFalse(), EmitFlags.Immutable)); + const immutableTrue = ts.memoize(() => ts.setEmitFlags(factory.createTrue(), ts.EmitFlags.Immutable)); + const immutableFalse = ts.memoize(() => ts.setEmitFlags(factory.createFalse(), ts.EmitFlags.Immutable)); return { getUnscopedHelperName, @@ -83,15 +83,15 @@ namespace ts { * Gets an identifier for the name of an *unscoped* emit helper. */ function getUnscopedHelperName(name: string) { - return setEmitFlags(factory.createIdentifier(name), EmitFlags.HelperName | EmitFlags.AdviseOnEmitNode); + return ts.setEmitFlags(factory.createIdentifier(name), ts.EmitFlags.HelperName | ts.EmitFlags.AdviseOnEmitNode); } // TypeScript Helpers - function createDecorateHelper(decoratorExpressions: Expression[], target: Expression, memberName?: Expression, descriptor?: Expression) { + function createDecorateHelper(decoratorExpressions: ts.Expression[], target: ts.Expression, memberName?: ts.Expression, descriptor?: ts.Expression) { context.requestEmitHelper(decorateHelper); - const argumentsArray: Expression[] = []; + const argumentsArray: ts.Expression[] = []; argumentsArray.push(factory.createArrayLiteralExpression(decoratorExpressions, /*multiLine*/ true)); argumentsArray.push(target); if (memberName) { @@ -101,96 +101,70 @@ namespace ts { } } - return factory.createCallExpression( - getUnscopedHelperName("__decorate"), - /*typeArguments*/ undefined, - argumentsArray - ); + return factory.createCallExpression(getUnscopedHelperName("__decorate"), + /*typeArguments*/ undefined, argumentsArray); } - function createMetadataHelper(metadataKey: string, metadataValue: Expression) { + function createMetadataHelper(metadataKey: string, metadataValue: ts.Expression) { context.requestEmitHelper(metadataHelper); - return factory.createCallExpression( - getUnscopedHelperName("__metadata"), - /*typeArguments*/ undefined, - [ + return factory.createCallExpression(getUnscopedHelperName("__metadata"), + /*typeArguments*/ undefined, [ factory.createStringLiteral(metadataKey), metadataValue - ] - ); + ]); } - function createParamHelper(expression: Expression, parameterOffset: number, location?: TextRange) { + function createParamHelper(expression: ts.Expression, parameterOffset: number, location?: ts.TextRange) { context.requestEmitHelper(paramHelper); - return setTextRange( - factory.createCallExpression( - getUnscopedHelperName("__param"), - /*typeArguments*/ undefined, - [ + return ts.setTextRange(factory.createCallExpression(getUnscopedHelperName("__param"), + /*typeArguments*/ undefined, [ factory.createNumericLiteral(parameterOffset + ""), expression - ] - ), - location - ); + ]), location); } // ES2018 Helpers - function createAssignHelper(attributesSegments: Expression[]) { - if (getEmitScriptTarget(context.getCompilerOptions()) >= ScriptTarget.ES2015) { + function createAssignHelper(attributesSegments: ts.Expression[]) { + if (ts.getEmitScriptTarget(context.getCompilerOptions()) >= ts.ScriptTarget.ES2015) { return factory.createCallExpression(factory.createPropertyAccessExpression(factory.createIdentifier("Object"), "assign"), - /*typeArguments*/ undefined, - attributesSegments); + /*typeArguments*/ undefined, attributesSegments); } context.requestEmitHelper(assignHelper); - return factory.createCallExpression( - getUnscopedHelperName("__assign"), - /*typeArguments*/ undefined, - attributesSegments - ); + return factory.createCallExpression(getUnscopedHelperName("__assign"), + /*typeArguments*/ undefined, attributesSegments); } - function createAwaitHelper(expression: Expression) { + function createAwaitHelper(expression: ts.Expression) { context.requestEmitHelper(awaitHelper); return factory.createCallExpression(getUnscopedHelperName("__await"), /*typeArguments*/ undefined, [expression]); } - function createAsyncGeneratorHelper(generatorFunc: FunctionExpression, hasLexicalThis: boolean) { + function createAsyncGeneratorHelper(generatorFunc: ts.FunctionExpression, hasLexicalThis: boolean) { context.requestEmitHelper(awaitHelper); context.requestEmitHelper(asyncGeneratorHelper); // Mark this node as originally an async function - (generatorFunc.emitNode || (generatorFunc.emitNode = {} as EmitNode)).flags |= EmitFlags.AsyncFunctionBody | EmitFlags.ReuseTempVariableScope; - - return factory.createCallExpression( - getUnscopedHelperName("__asyncGenerator"), - /*typeArguments*/ undefined, - [ + (generatorFunc.emitNode || (generatorFunc.emitNode = {} as ts.EmitNode)).flags |= ts.EmitFlags.AsyncFunctionBody | ts.EmitFlags.ReuseTempVariableScope; + return factory.createCallExpression(getUnscopedHelperName("__asyncGenerator"), + /*typeArguments*/ undefined, [ hasLexicalThis ? factory.createThis() : factory.createVoidZero(), factory.createIdentifier("arguments"), generatorFunc - ] - ); + ]); } - function createAsyncDelegatorHelper(expression: Expression) { + function createAsyncDelegatorHelper(expression: ts.Expression) { context.requestEmitHelper(awaitHelper); context.requestEmitHelper(asyncDelegator); - return factory.createCallExpression( - getUnscopedHelperName("__asyncDelegator"), - /*typeArguments*/ undefined, - [expression] - ); + return factory.createCallExpression(getUnscopedHelperName("__asyncDelegator"), + /*typeArguments*/ undefined, [expression]); } - function createAsyncValuesHelper(expression: Expression) { + function createAsyncValuesHelper(expression: ts.Expression) { context.requestEmitHelper(asyncValues); - return factory.createCallExpression( - getUnscopedHelperName("__asyncValues"), - /*typeArguments*/ undefined, - [expression] - ); + return factory.createCallExpression(getUnscopedHelperName("__asyncValues"), + /*typeArguments*/ undefined, [expression]); } // ES2018 Destructuring Helpers @@ -198,153 +172,113 @@ namespace ts { /** Given value: o, propName: p, pattern: { a, b, ...p } from the original statement * `{ a, b, ...p } = o`, create `p = __rest(o, ["a", "b"]);` */ - function createRestHelper(value: Expression, elements: readonly BindingOrAssignmentElement[], computedTempVariables: readonly Expression[] | undefined, location: TextRange): Expression { + function createRestHelper(value: ts.Expression, elements: readonly ts.BindingOrAssignmentElement[], computedTempVariables: readonly ts.Expression[] | undefined, location: ts.TextRange): ts.Expression { context.requestEmitHelper(restHelper); - const propertyNames: Expression[] = []; + const propertyNames: ts.Expression[] = []; let computedTempVariableOffset = 0; for (let i = 0; i < elements.length - 1; i++) { - const propertyName = getPropertyNameOfBindingOrAssignmentElement(elements[i]); + const propertyName = ts.getPropertyNameOfBindingOrAssignmentElement(elements[i]); if (propertyName) { - if (isComputedPropertyName(propertyName)) { - Debug.assertIsDefined(computedTempVariables, "Encountered computed property name but 'computedTempVariables' argument was not provided."); + if (ts.isComputedPropertyName(propertyName)) { + ts.Debug.assertIsDefined(computedTempVariables, "Encountered computed property name but 'computedTempVariables' argument was not provided."); const temp = computedTempVariables[computedTempVariableOffset]; computedTempVariableOffset++; // typeof _tmp === "symbol" ? _tmp : _tmp + "" - propertyNames.push( - factory.createConditionalExpression( - factory.createTypeCheck(temp, "symbol"), - /*questionToken*/ undefined, - temp, - /*colonToken*/ undefined, - factory.createAdd(temp, factory.createStringLiteral("")) - ) - ); + propertyNames.push(factory.createConditionalExpression(factory.createTypeCheck(temp, "symbol"), + /*questionToken*/ undefined, temp, + /*colonToken*/ undefined, factory.createAdd(temp, factory.createStringLiteral("")))); } else { propertyNames.push(factory.createStringLiteralFromNode(propertyName)); } } } - return factory.createCallExpression( - getUnscopedHelperName("__rest"), - /*typeArguments*/ undefined, - [ + return factory.createCallExpression(getUnscopedHelperName("__rest"), + /*typeArguments*/ undefined, [ value, - setTextRange( - factory.createArrayLiteralExpression(propertyNames), - location - )] - ); + ts.setTextRange(factory.createArrayLiteralExpression(propertyNames), location) + ]); } // ES2017 Helpers - function createAwaiterHelper(hasLexicalThis: boolean, hasLexicalArguments: boolean, promiseConstructor: EntityName | Expression | undefined, body: Block) { + function createAwaiterHelper(hasLexicalThis: boolean, hasLexicalArguments: boolean, promiseConstructor: ts.EntityName | ts.Expression | undefined, body: ts.Block) { context.requestEmitHelper(awaiterHelper); const generatorFunc = factory.createFunctionExpression( - /*modifiers*/ undefined, - factory.createToken(SyntaxKind.AsteriskToken), + /*modifiers*/ undefined, factory.createToken(ts.SyntaxKind.AsteriskToken), /*name*/ undefined, /*typeParameters*/ undefined, /*parameters*/ [], - /*type*/ undefined, - body - ); + /*type*/ undefined, body); // Mark this node as originally an async function - (generatorFunc.emitNode || (generatorFunc.emitNode = {} as EmitNode)).flags |= EmitFlags.AsyncFunctionBody | EmitFlags.ReuseTempVariableScope; - - return factory.createCallExpression( - getUnscopedHelperName("__awaiter"), - /*typeArguments*/ undefined, - [ + (generatorFunc.emitNode || (generatorFunc.emitNode = {} as ts.EmitNode)).flags |= ts.EmitFlags.AsyncFunctionBody | ts.EmitFlags.ReuseTempVariableScope; + return factory.createCallExpression(getUnscopedHelperName("__awaiter"), + /*typeArguments*/ undefined, [ hasLexicalThis ? factory.createThis() : factory.createVoidZero(), hasLexicalArguments ? factory.createIdentifier("arguments") : factory.createVoidZero(), - promiseConstructor ? createExpressionFromEntityName(factory, promiseConstructor) : factory.createVoidZero(), + promiseConstructor ? ts.createExpressionFromEntityName(factory, promiseConstructor) : factory.createVoidZero(), generatorFunc - ] - ); + ]); } // ES2015 Helpers - function createExtendsHelper(name: Identifier) { + function createExtendsHelper(name: ts.Identifier) { context.requestEmitHelper(extendsHelper); - return factory.createCallExpression( - getUnscopedHelperName("__extends"), - /*typeArguments*/ undefined, - [name, factory.createUniqueName("_super", GeneratedIdentifierFlags.Optimistic | GeneratedIdentifierFlags.FileLevel)] - ); + return factory.createCallExpression(getUnscopedHelperName("__extends"), + /*typeArguments*/ undefined, [name, factory.createUniqueName("_super", ts.GeneratedIdentifierFlags.Optimistic | ts.GeneratedIdentifierFlags.FileLevel)]); } - function createTemplateObjectHelper(cooked: ArrayLiteralExpression, raw: ArrayLiteralExpression) { + function createTemplateObjectHelper(cooked: ts.ArrayLiteralExpression, raw: ts.ArrayLiteralExpression) { context.requestEmitHelper(templateObjectHelper); - return factory.createCallExpression( - getUnscopedHelperName("__makeTemplateObject"), - /*typeArguments*/ undefined, - [cooked, raw] - ); + return factory.createCallExpression(getUnscopedHelperName("__makeTemplateObject"), + /*typeArguments*/ undefined, [cooked, raw]); } - function createSpreadArrayHelper(to: Expression, from: Expression, packFrom: boolean) { + function createSpreadArrayHelper(to: ts.Expression, from: ts.Expression, packFrom: boolean) { context.requestEmitHelper(spreadArrayHelper); - return factory.createCallExpression( - getUnscopedHelperName("__spreadArray"), - /*typeArguments*/ undefined, - [to, from, packFrom ? immutableTrue() : immutableFalse()] - ); + return factory.createCallExpression(getUnscopedHelperName("__spreadArray"), + /*typeArguments*/ undefined, [to, from, packFrom ? immutableTrue() : immutableFalse()]); } // ES2015 Destructuring Helpers - function createValuesHelper(expression: Expression) { + function createValuesHelper(expression: ts.Expression) { context.requestEmitHelper(valuesHelper); - return factory.createCallExpression( - getUnscopedHelperName("__values"), - /*typeArguments*/ undefined, - [expression] - ); + return factory.createCallExpression(getUnscopedHelperName("__values"), + /*typeArguments*/ undefined, [expression]); } - function createReadHelper(iteratorRecord: Expression, count: number | undefined) { + function createReadHelper(iteratorRecord: ts.Expression, count: number | undefined) { context.requestEmitHelper(readHelper); - return factory.createCallExpression( - getUnscopedHelperName("__read"), - /*typeArguments*/ undefined, - count !== undefined + return factory.createCallExpression(getUnscopedHelperName("__read"), + /*typeArguments*/ undefined, count !== undefined ? [iteratorRecord, factory.createNumericLiteral(count + "")] - : [iteratorRecord] - ); + : [iteratorRecord]); } // ES2015 Generator Helpers - function createGeneratorHelper(body: FunctionExpression) { + function createGeneratorHelper(body: ts.FunctionExpression) { context.requestEmitHelper(generatorHelper); - return factory.createCallExpression( - getUnscopedHelperName("__generator"), - /*typeArguments*/ undefined, - [factory.createThis(), body]); + return factory.createCallExpression(getUnscopedHelperName("__generator"), + /*typeArguments*/ undefined, [factory.createThis(), body]); } // ES Module Helpers - function createCreateBindingHelper(module: Expression, inputName: Expression, outputName: Expression | undefined) { + function createCreateBindingHelper(module: ts.Expression, inputName: ts.Expression, outputName: ts.Expression | undefined) { context.requestEmitHelper(createBindingHelper); - return factory.createCallExpression( - getUnscopedHelperName("__createBinding"), - /*typeArguments*/ undefined, - [factory.createIdentifier("exports"), module, inputName, ...(outputName ? [outputName] : [])]); + return factory.createCallExpression(getUnscopedHelperName("__createBinding"), + /*typeArguments*/ undefined, [factory.createIdentifier("exports"), module, inputName, ...(outputName ? [outputName] : [])]); } - function createImportStarHelper(expression: Expression) { + function createImportStarHelper(expression: ts.Expression) { context.requestEmitHelper(importStarHelper); - return factory.createCallExpression( - getUnscopedHelperName("__importStar"), - /*typeArguments*/ undefined, - [expression] - ); + return factory.createCallExpression(getUnscopedHelperName("__importStar"), + /*typeArguments*/ undefined, [expression]); } function createImportStarCallbackHelper() { @@ -352,28 +286,22 @@ namespace ts { return getUnscopedHelperName("__importStar"); } - function createImportDefaultHelper(expression: Expression) { + function createImportDefaultHelper(expression: ts.Expression) { context.requestEmitHelper(importDefaultHelper); - return factory.createCallExpression( - getUnscopedHelperName("__importDefault"), - /*typeArguments*/ undefined, - [expression] - ); + return factory.createCallExpression(getUnscopedHelperName("__importDefault"), + /*typeArguments*/ undefined, [expression]); } - function createExportStarHelper(moduleExpression: Expression, exportsExpression: Expression = factory.createIdentifier("exports")) { + function createExportStarHelper(moduleExpression: ts.Expression, exportsExpression: ts.Expression = factory.createIdentifier("exports")) { context.requestEmitHelper(exportStarHelper); context.requestEmitHelper(createBindingHelper); - return factory.createCallExpression( - getUnscopedHelperName("__exportStar"), - /*typeArguments*/ undefined, - [moduleExpression, exportsExpression] - ); + return factory.createCallExpression(getUnscopedHelperName("__exportStar"), + /*typeArguments*/ undefined, [moduleExpression, exportsExpression]); } // Class Fields Helpers - function createClassPrivateFieldGetHelper(receiver: Expression, state: Identifier, kind: PrivateIdentifierKind, f: Identifier | undefined) { + function createClassPrivateFieldGetHelper(receiver: ts.Expression, state: ts.Identifier, kind: ts.PrivateIdentifierKind, f: ts.Identifier | undefined) { context.requestEmitHelper(classPrivateFieldGetHelper); let args; if (!f) { @@ -385,7 +313,7 @@ namespace ts { return factory.createCallExpression(getUnscopedHelperName("__classPrivateFieldGet"), /*typeArguments*/ undefined, args); } - function createClassPrivateFieldSetHelper(receiver: Expression, state: Identifier, value: Expression, kind: PrivateIdentifierKind, f: Identifier | undefined) { + function createClassPrivateFieldSetHelper(receiver: ts.Expression, state: ts.Identifier, value: ts.Expression, kind: ts.PrivateIdentifierKind, f: ts.Identifier | undefined) { context.requestEmitHelper(classPrivateFieldSetHelper); let args; if (!f) { @@ -397,19 +325,23 @@ namespace ts { return factory.createCallExpression(getUnscopedHelperName("__classPrivateFieldSet"), /*typeArguments*/ undefined, args); } - function createClassPrivateFieldInHelper(state: Identifier, receiver: Expression) { + function createClassPrivateFieldInHelper(state: ts.Identifier, receiver: ts.Expression) { context.requestEmitHelper(classPrivateFieldInHelper); return factory.createCallExpression(getUnscopedHelperName("__classPrivateFieldIn"), /* typeArguments*/ undefined, [state, receiver]); } } /* @internal */ - export function compareEmitHelpers(x: EmitHelper, y: EmitHelper) { - if (x === y) return Comparison.EqualTo; - if (x.priority === y.priority) return Comparison.EqualTo; - if (x.priority === undefined) return Comparison.GreaterThan; - if (y.priority === undefined) return Comparison.LessThan; - return compareValues(x.priority, y.priority); + export function compareEmitHelpers(x: ts.EmitHelper, y: ts.EmitHelper) { + if (x === y) + return ts.Comparison.EqualTo; + if (x.priority === y.priority) + return ts.Comparison.EqualTo; + if (x.priority === undefined) + return ts.Comparison.GreaterThan; + if (y.priority === undefined) + return ts.Comparison.LessThan; + return ts.compareValues(x.priority, y.priority); } /** @@ -417,7 +349,7 @@ namespace ts { * @param args Names which need to be made file-level unique */ export function helperString(input: TemplateStringsArray, ...args: string[]) { - return (uniqueName: EmitHelperUniqueNameCallback) => { + return (uniqueName: ts.EmitHelperUniqueNameCallback) => { let result = ""; for (let i = 0; i < args.length; i++) { result += input[i]; @@ -430,7 +362,7 @@ namespace ts { // TypeScript Helpers - export const decorateHelper: UnscopedEmitHelper = { + export const decorateHelper: ts.UnscopedEmitHelper = { name: "typescript:decorate", importName: "__decorate", scoped: false, @@ -444,7 +376,7 @@ namespace ts { };` }; - export const metadataHelper: UnscopedEmitHelper = { + export const metadataHelper: ts.UnscopedEmitHelper = { name: "typescript:metadata", importName: "__metadata", scoped: false, @@ -455,7 +387,7 @@ namespace ts { };` }; - export const paramHelper: UnscopedEmitHelper = { + export const paramHelper: ts.UnscopedEmitHelper = { name: "typescript:param", importName: "__param", scoped: false, @@ -468,7 +400,7 @@ namespace ts { // ES2018 Helpers - export const assignHelper: UnscopedEmitHelper = { + export const assignHelper: ts.UnscopedEmitHelper = { name: "typescript:assign", importName: "__assign", scoped: false, @@ -487,7 +419,7 @@ namespace ts { };` }; - export const awaitHelper: UnscopedEmitHelper = { + export const awaitHelper: ts.UnscopedEmitHelper = { name: "typescript:await", importName: "__await", scoped: false, @@ -495,7 +427,7 @@ namespace ts { var __await = (this && this.__await) || function (v) { return this instanceof __await ? (this.v = v, this) : new __await(v); }` }; - export const asyncGeneratorHelper: UnscopedEmitHelper = { + export const asyncGeneratorHelper: ts.UnscopedEmitHelper = { name: "typescript:asyncGenerator", importName: "__asyncGenerator", scoped: false, @@ -514,7 +446,7 @@ namespace ts { };` }; - export const asyncDelegator: UnscopedEmitHelper = { + export const asyncDelegator: ts.UnscopedEmitHelper = { name: "typescript:asyncDelegator", importName: "__asyncDelegator", scoped: false, @@ -527,7 +459,7 @@ namespace ts { };` }; - export const asyncValues: UnscopedEmitHelper = { + export const asyncValues: ts.UnscopedEmitHelper = { name: "typescript:asyncValues", importName: "__asyncValues", scoped: false, @@ -543,7 +475,7 @@ namespace ts { // ES2018 Destructuring Helpers - export const restHelper: UnscopedEmitHelper = { + export const restHelper: ts.UnscopedEmitHelper = { name: "typescript:rest", importName: "__rest", scoped: false, @@ -563,7 +495,7 @@ namespace ts { // ES2017 Helpers - export const awaiterHelper: UnscopedEmitHelper = { + export const awaiterHelper: ts.UnscopedEmitHelper = { name: "typescript:awaiter", importName: "__awaiter", scoped: false, @@ -582,7 +514,7 @@ namespace ts { // ES2015 Helpers - export const extendsHelper: UnscopedEmitHelper = { + export const extendsHelper: ts.UnscopedEmitHelper = { name: "typescript:extends", importName: "__extends", scoped: false, @@ -606,7 +538,7 @@ namespace ts { })();` }; - export const templateObjectHelper: UnscopedEmitHelper = { + export const templateObjectHelper: ts.UnscopedEmitHelper = { name: "typescript:makeTemplateObject", importName: "__makeTemplateObject", scoped: false, @@ -618,7 +550,7 @@ namespace ts { };` }; - export const readHelper: UnscopedEmitHelper = { + export const readHelper: ts.UnscopedEmitHelper = { name: "typescript:read", importName: "__read", scoped: false, @@ -641,7 +573,7 @@ namespace ts { };` }; - export const spreadArrayHelper: UnscopedEmitHelper = { + export const spreadArrayHelper: ts.UnscopedEmitHelper = { name: "typescript:spreadArray", importName: "__spreadArray", scoped: false, @@ -659,7 +591,7 @@ namespace ts { // ES2015 Destructuring Helpers - export const valuesHelper: UnscopedEmitHelper = { + export const valuesHelper: ts.UnscopedEmitHelper = { name: "typescript:values", importName: "__values", scoped: false, @@ -738,7 +670,7 @@ namespace ts { // entering a finally block. // // For examples of how these are used, see the comments in ./transformers/generators.ts - export const generatorHelper: UnscopedEmitHelper = { + export const generatorHelper: ts.UnscopedEmitHelper = { name: "typescript:generator", importName: "__generator", scoped: false, @@ -775,7 +707,7 @@ namespace ts { // ES Module Helpers - export const createBindingHelper: UnscopedEmitHelper = { + export const createBindingHelper: ts.UnscopedEmitHelper = { name: "typescript:commonjscreatebinding", importName: "__createBinding", scoped: false, @@ -794,7 +726,7 @@ namespace ts { }));` }; - export const setModuleDefaultHelper: UnscopedEmitHelper = { + export const setModuleDefaultHelper: ts.UnscopedEmitHelper = { name: "typescript:commonjscreatevalue", importName: "__setModuleDefault", scoped: false, @@ -808,7 +740,7 @@ namespace ts { }; // emit helper for `import * as Name from "foo"` - export const importStarHelper: UnscopedEmitHelper = { + export const importStarHelper: ts.UnscopedEmitHelper = { name: "typescript:commonjsimportstar", importName: "__importStar", scoped: false, @@ -825,7 +757,7 @@ namespace ts { }; // emit helper for `import Name from "foo"` - export const importDefaultHelper: UnscopedEmitHelper = { + export const importDefaultHelper: ts.UnscopedEmitHelper = { name: "typescript:commonjsimportdefault", importName: "__importDefault", scoped: false, @@ -835,7 +767,7 @@ namespace ts { };` }; - export const exportStarHelper: UnscopedEmitHelper = { + export const exportStarHelper: ts.UnscopedEmitHelper = { name: "typescript:export-star", importName: "__exportStar", scoped: false, @@ -895,7 +827,7 @@ namespace ts { * Reading from a private static method (TS 4.3+): * __classPrivateFieldGet(, , "m", ) */ - export const classPrivateFieldGetHelper: UnscopedEmitHelper = { + export const classPrivateFieldGetHelper: ts.UnscopedEmitHelper = { name: "typescript:classPrivateFieldGet", importName: "__classPrivateFieldGet", scoped: false, @@ -958,7 +890,7 @@ namespace ts { * __classPrivateFieldSet(, , , "m", ) * NOTE: This always results in a runtime error. */ - export const classPrivateFieldSetHelper: UnscopedEmitHelper = { + export const classPrivateFieldSetHelper: ts.UnscopedEmitHelper = { name: "typescript:classPrivateFieldSet", importName: "__classPrivateFieldSet", scoped: false, @@ -983,7 +915,7 @@ namespace ts { * This helper is used to transform `#field in expression` to * `__classPrivateFieldIn(, expression)` */ - export const classPrivateFieldInHelper: UnscopedEmitHelper = { + export const classPrivateFieldInHelper: ts.UnscopedEmitHelper = { name: "typescript:classPrivateFieldIn", importName: "__classPrivateFieldIn", scoped: false, @@ -994,10 +926,10 @@ namespace ts { };` }; - let allUnscopedEmitHelpers: ReadonlyESMap | undefined; + let allUnscopedEmitHelpers: ts.ReadonlyESMap | undefined; export function getAllUnscopedEmitHelpers() { - return allUnscopedEmitHelpers || (allUnscopedEmitHelpers = arrayToMap([ + return allUnscopedEmitHelpers || (allUnscopedEmitHelpers = ts.arrayToMap([ decorateHelper, metadataHelper, paramHelper, @@ -1025,14 +957,14 @@ namespace ts { ], helper => helper.name)); } - export const asyncSuperHelper: EmitHelper = { + export const asyncSuperHelper: ts.EmitHelper = { name: "typescript:async-super", scoped: true, text: helperString` const ${"_superIndex"} = name => super[name];` }; - export const advancedAsyncSuperHelper: EmitHelper = { + export const advancedAsyncSuperHelper: ts.EmitHelper = { name: "typescript:advanced-async-super", scoped: true, text: helperString` @@ -1042,10 +974,10 @@ namespace ts { })(name => super[name], (name, value) => super[name] = value);` }; - export function isCallToHelper(firstSegment: Expression, helperName: __String): boolean { - return isCallExpression(firstSegment) - && isIdentifier(firstSegment.expression) - && (getEmitFlags(firstSegment.expression) & EmitFlags.HelperName) !== 0 + export function isCallToHelper(firstSegment: ts.Expression, helperName: ts.__String): boolean { + return ts.isCallExpression(firstSegment) + && ts.isIdentifier(firstSegment.expression) + && (ts.getEmitFlags(firstSegment.expression) & ts.EmitFlags.HelperName) !== 0 && firstSegment.expression.escapedText === helperName; } } diff --git a/src/compiler/factory/emitNode.ts b/src/compiler/factory/emitNode.ts index 19ebfd53ba2ba..3b37f3fc5f6d3 100644 --- a/src/compiler/factory/emitNode.ts +++ b/src/compiler/factory/emitNode.ts @@ -4,24 +4,24 @@ namespace ts { * various transient transformation properties. * @internal */ - export function getOrCreateEmitNode(node: Node): EmitNode { + export function getOrCreateEmitNode(node: ts.Node): ts.EmitNode { if (!node.emitNode) { - if (isParseTreeNode(node)) { + if (ts.isParseTreeNode(node)) { // To avoid holding onto transformation artifacts, we keep track of any // parse tree node we are annotating. This allows us to clean them up after // all transformations have completed. - if (node.kind === SyntaxKind.SourceFile) { - return node.emitNode = { annotatedNodes: [node] } as EmitNode; + if (node.kind === ts.SyntaxKind.SourceFile) { + return node.emitNode = { annotatedNodes: [node] } as ts.EmitNode; } - const sourceFile = getSourceFileOfNode(getParseTreeNode(getSourceFileOfNode(node))) ?? Debug.fail("Could not determine parsed source file."); + const sourceFile = ts.getSourceFileOfNode(ts.getParseTreeNode(ts.getSourceFileOfNode(node))) ?? ts.Debug.fail("Could not determine parsed source file."); getOrCreateEmitNode(sourceFile).annotatedNodes!.push(node); } - node.emitNode = {} as EmitNode; + node.emitNode = {} as ts.EmitNode; } else { - Debug.assert(!(node.emitNode.flags & EmitFlags.Immutable), "Invalid attempt to mutate an immutable node."); + ts.Debug.assert(!(node.emitNode.flags & ts.EmitFlags.Immutable), "Invalid attempt to mutate an immutable node."); } return node.emitNode; } @@ -30,14 +30,14 @@ namespace ts { * Clears any `EmitNode` entries from parse-tree nodes. * @param sourceFile A source file. */ - export function disposeEmitNodes(sourceFile: SourceFile | undefined) { + export function disposeEmitNodes(sourceFile: ts.SourceFile | undefined) { // During transformation we may need to annotate a parse tree node with transient // transformation properties. As parse tree nodes live longer than transformation // nodes, we need to make sure we reclaim any memory allocated for custom ranges // from these nodes to ensure we do not hold onto entire subtrees just for position // information. We also need to reset these nodes to a pre-transformation state // for incremental parsing scenarios so that we do not impact later emit. - const annotatedNodes = getSourceFileOfNode(getParseTreeNode(sourceFile))?.emitNode?.annotatedNodes; + const annotatedNodes = ts.getSourceFileOfNode(ts.getParseTreeNode(sourceFile))?.emitNode?.annotatedNodes; if (annotatedNodes) { for (const node of annotatedNodes) { node.emitNode = undefined; @@ -49,9 +49,9 @@ namespace ts { * Sets `EmitFlags.NoComments` on a node and removes any leading and trailing synthetic comments. * @internal */ - export function removeAllComments(node: T): T { + export function removeAllComments(node: T): T { const emitNode = getOrCreateEmitNode(node); - emitNode.flags |= EmitFlags.NoComments; + emitNode.flags |= ts.EmitFlags.NoComments; emitNode.leadingComments = undefined; emitNode.trailingComments = undefined; return node; @@ -60,7 +60,7 @@ namespace ts { /** * Sets flags that control emit behavior of a node. */ - export function setEmitFlags(node: T, emitFlags: EmitFlags) { + export function setEmitFlags(node: T, emitFlags: ts.EmitFlags) { getOrCreateEmitNode(node).flags = emitFlags; return node; } @@ -69,7 +69,7 @@ namespace ts { * Sets flags that control emit behavior of a node. */ /* @internal */ - export function addEmitFlags(node: T, emitFlags: EmitFlags) { + export function addEmitFlags(node: T, emitFlags: ts.EmitFlags) { const emitNode = getOrCreateEmitNode(node); emitNode.flags = emitNode.flags | emitFlags; return node; @@ -78,14 +78,14 @@ namespace ts { /** * Gets a custom text range to use when emitting source maps. */ - export function getSourceMapRange(node: Node): SourceMapRange { + export function getSourceMapRange(node: ts.Node): ts.SourceMapRange { return node.emitNode?.sourceMapRange ?? node; } /** * Sets a custom text range to use when emitting source maps. */ - export function setSourceMapRange(node: T, range: SourceMapRange | undefined) { + export function setSourceMapRange(node: T, range: ts.SourceMapRange | undefined) { getOrCreateEmitNode(node).sourceMapRange = range; return node; } @@ -93,14 +93,14 @@ namespace ts { /** * Gets the TextRange to use for source maps for a token of a node. */ - export function getTokenSourceMapRange(node: Node, token: SyntaxKind): SourceMapRange | undefined { + export function getTokenSourceMapRange(node: ts.Node, token: ts.SyntaxKind): ts.SourceMapRange | undefined { return node.emitNode?.tokenSourceMapRanges?.[token]; } /** * Sets the TextRange to use for source maps for a token of a node. */ - export function setTokenSourceMapRange(node: T, token: SyntaxKind, range: SourceMapRange | undefined) { + export function setTokenSourceMapRange(node: T, token: ts.SyntaxKind, range: ts.SourceMapRange | undefined) { const emitNode = getOrCreateEmitNode(node); const tokenSourceMapRanges = emitNode.tokenSourceMapRanges ?? (emitNode.tokenSourceMapRanges = []); tokenSourceMapRanges[token] = range; @@ -111,7 +111,7 @@ namespace ts { * Gets a custom text range to use when emitting comments. */ /*@internal*/ - export function getStartsOnNewLine(node: Node) { + export function getStartsOnNewLine(node: ts.Node) { return node.emitNode?.startsOnNewLine; } @@ -119,7 +119,7 @@ namespace ts { * Sets a custom text range to use when emitting comments. */ /*@internal*/ - export function setStartsOnNewLine(node: T, newLine: boolean) { + export function setStartsOnNewLine(node: T, newLine: boolean) { getOrCreateEmitNode(node).startsOnNewLine = newLine; return node; } @@ -127,45 +127,45 @@ namespace ts { /** * Gets a custom text range to use when emitting comments. */ - export function getCommentRange(node: Node): TextRange { + export function getCommentRange(node: ts.Node): ts.TextRange { return node.emitNode?.commentRange ?? node; } /** * Sets a custom text range to use when emitting comments. */ - export function setCommentRange(node: T, range: TextRange) { + export function setCommentRange(node: T, range: ts.TextRange) { getOrCreateEmitNode(node).commentRange = range; return node; } - export function getSyntheticLeadingComments(node: Node): SynthesizedComment[] | undefined { + export function getSyntheticLeadingComments(node: ts.Node): ts.SynthesizedComment[] | undefined { return node.emitNode?.leadingComments; } - export function setSyntheticLeadingComments(node: T, comments: SynthesizedComment[] | undefined) { + export function setSyntheticLeadingComments(node: T, comments: ts.SynthesizedComment[] | undefined) { getOrCreateEmitNode(node).leadingComments = comments; return node; } - export function addSyntheticLeadingComment(node: T, kind: SyntaxKind.SingleLineCommentTrivia | SyntaxKind.MultiLineCommentTrivia, text: string, hasTrailingNewLine?: boolean) { - return setSyntheticLeadingComments(node, append(getSyntheticLeadingComments(node), { kind, pos: -1, end: -1, hasTrailingNewLine, text })); + export function addSyntheticLeadingComment(node: T, kind: ts.SyntaxKind.SingleLineCommentTrivia | ts.SyntaxKind.MultiLineCommentTrivia, text: string, hasTrailingNewLine?: boolean) { + return setSyntheticLeadingComments(node, ts.append(getSyntheticLeadingComments(node), { kind, pos: -1, end: -1, hasTrailingNewLine, text })); } - export function getSyntheticTrailingComments(node: Node): SynthesizedComment[] | undefined { + export function getSyntheticTrailingComments(node: ts.Node): ts.SynthesizedComment[] | undefined { return node.emitNode?.trailingComments; } - export function setSyntheticTrailingComments(node: T, comments: SynthesizedComment[] | undefined) { + export function setSyntheticTrailingComments(node: T, comments: ts.SynthesizedComment[] | undefined) { getOrCreateEmitNode(node).trailingComments = comments; return node; } - export function addSyntheticTrailingComment(node: T, kind: SyntaxKind.SingleLineCommentTrivia | SyntaxKind.MultiLineCommentTrivia, text: string, hasTrailingNewLine?: boolean) { - return setSyntheticTrailingComments(node, append(getSyntheticTrailingComments(node), { kind, pos: -1, end: -1, hasTrailingNewLine, text })); + export function addSyntheticTrailingComment(node: T, kind: ts.SyntaxKind.SingleLineCommentTrivia | ts.SyntaxKind.MultiLineCommentTrivia, text: string, hasTrailingNewLine?: boolean) { + return setSyntheticTrailingComments(node, ts.append(getSyntheticTrailingComments(node), { kind, pos: -1, end: -1, hasTrailingNewLine, text })); } - export function moveSyntheticComments(node: T, original: Node): T { + export function moveSyntheticComments(node: T, original: ts.Node): T { setSyntheticLeadingComments(node, getSyntheticLeadingComments(original)); setSyntheticTrailingComments(node, getSyntheticTrailingComments(original)); const emit = getOrCreateEmitNode(original); @@ -177,14 +177,14 @@ namespace ts { /** * Gets the constant value to emit for an expression representing an enum. */ - export function getConstantValue(node: AccessExpression): string | number | undefined { + export function getConstantValue(node: ts.AccessExpression): string | number | undefined { return node.emitNode?.constantValue; } /** * Sets the constant value to emit for an expression. */ - export function setConstantValue(node: AccessExpression, value: string | number): AccessExpression { + export function setConstantValue(node: ts.AccessExpression, value: string | number): ts.AccessExpression { const emitNode = getOrCreateEmitNode(node); emitNode.constantValue = value; return node; @@ -193,20 +193,20 @@ namespace ts { /** * Adds an EmitHelper to a node. */ - export function addEmitHelper(node: T, helper: EmitHelper): T { + export function addEmitHelper(node: T, helper: ts.EmitHelper): T { const emitNode = getOrCreateEmitNode(node); - emitNode.helpers = append(emitNode.helpers, helper); + emitNode.helpers = ts.append(emitNode.helpers, helper); return node; } /** * Add EmitHelpers to a node. */ - export function addEmitHelpers(node: T, helpers: EmitHelper[] | undefined): T { - if (some(helpers)) { + export function addEmitHelpers(node: T, helpers: ts.EmitHelper[] | undefined): T { + if (ts.some(helpers)) { const emitNode = getOrCreateEmitNode(node); for (const helper of helpers) { - emitNode.helpers = appendIfUnique(emitNode.helpers, helper); + emitNode.helpers = ts.appendIfUnique(emitNode.helpers, helper); } } return node; @@ -215,10 +215,10 @@ namespace ts { /** * Removes an EmitHelper from a node. */ - export function removeEmitHelper(node: Node, helper: EmitHelper): boolean { + export function removeEmitHelper(node: ts.Node, helper: ts.EmitHelper): boolean { const helpers = node.emitNode?.helpers; if (helpers) { - return orderedRemoveItem(helpers, helper); + return ts.orderedRemoveItem(helpers, helper); } return false; } @@ -226,17 +226,18 @@ namespace ts { /** * Gets the EmitHelpers of a node. */ - export function getEmitHelpers(node: Node): EmitHelper[] | undefined { + export function getEmitHelpers(node: ts.Node): ts.EmitHelper[] | undefined { return node.emitNode?.helpers; } /** * Moves matching emit helpers from a source node to a target node. */ - export function moveEmitHelpers(source: Node, target: Node, predicate: (helper: EmitHelper) => boolean) { + export function moveEmitHelpers(source: ts.Node, target: ts.Node, predicate: (helper: ts.EmitHelper) => boolean) { const sourceEmitNode = source.emitNode; const sourceEmitHelpers = sourceEmitNode && sourceEmitNode.helpers; - if (!some(sourceEmitHelpers)) return; + if (!ts.some(sourceEmitHelpers)) + return; const targetEmitNode = getOrCreateEmitNode(target); let helpersRemoved = 0; @@ -244,7 +245,7 @@ namespace ts { const helper = sourceEmitHelpers[i]; if (predicate(helper)) { helpersRemoved++; - targetEmitNode.helpers = appendIfUnique(targetEmitNode.helpers, helper); + targetEmitNode.helpers = ts.appendIfUnique(targetEmitNode.helpers, helper); } else if (helpersRemoved > 0) { sourceEmitHelpers[i - helpersRemoved] = helper; @@ -260,7 +261,7 @@ namespace ts { * Gets the SnippetElement of a node. */ /* @internal */ - export function getSnippetElement(node: Node): SnippetElement | undefined { + export function getSnippetElement(node: ts.Node): ts.SnippetElement | undefined { return node.emitNode?.snippetElement; } @@ -268,27 +269,27 @@ namespace ts { * Sets the SnippetElement of a node. */ /* @internal */ - export function setSnippetElement(node: T, snippet: SnippetElement): T { + export function setSnippetElement(node: T, snippet: ts.SnippetElement): T { const emitNode = getOrCreateEmitNode(node); emitNode.snippetElement = snippet; return node; } /* @internal */ - export function ignoreSourceNewlines(node: T): T { - getOrCreateEmitNode(node).flags |= EmitFlags.IgnoreSourceNewlines; + export function ignoreSourceNewlines(node: T): T { + getOrCreateEmitNode(node).flags |= ts.EmitFlags.IgnoreSourceNewlines; return node; } /* @internal */ - export function setTypeNode(node: T, type: TypeNode): T { + export function setTypeNode(node: T, type: ts.TypeNode): T { const emitNode = getOrCreateEmitNode(node); emitNode.typeNode = type; return node; } /* @internal */ - export function getTypeNode(node: T): TypeNode | undefined { + export function getTypeNode(node: T): ts.TypeNode | undefined { return node.emitNode?.typeNode; } } diff --git a/src/compiler/factory/nodeConverters.ts b/src/compiler/factory/nodeConverters.ts index 08aff2a91cd87..52b0facacfd13 100644 --- a/src/compiler/factory/nodeConverters.ts +++ b/src/compiler/factory/nodeConverters.ts @@ -1,6 +1,6 @@ /* @internal */ namespace ts { - export function createNodeConverters(factory: NodeFactory): NodeConverters { + export function createNodeConverters(factory: ts.NodeFactory): ts.NodeConverters { return { convertToFunctionBlock, convertToFunctionExpression, @@ -12,126 +12,100 @@ namespace ts { convertToAssignmentElementTarget, }; - function convertToFunctionBlock(node: ConciseBody, multiLine?: boolean): Block { - if (isBlock(node)) return node; + function convertToFunctionBlock(node: ts.ConciseBody, multiLine?: boolean): ts.Block { + if (ts.isBlock(node)) + return node; const returnStatement = factory.createReturnStatement(node); - setTextRange(returnStatement, node); + ts.setTextRange(returnStatement, node); const body = factory.createBlock([returnStatement], multiLine); - setTextRange(body, node); + ts.setTextRange(body, node); return body; } - function convertToFunctionExpression(node: FunctionDeclaration) { - if (!node.body) return Debug.fail(`Cannot convert a FunctionDeclaration without a body`); - const updated = factory.createFunctionExpression( - node.modifiers, - node.asteriskToken, - node.name, - node.typeParameters, - node.parameters, - node.type, - node.body - ); - setOriginalNode(updated, node); - setTextRange(updated, node); - if (getStartsOnNewLine(node)) { - setStartsOnNewLine(updated, /*newLine*/ true); + function convertToFunctionExpression(node: ts.FunctionDeclaration) { + if (!node.body) + return ts.Debug.fail(`Cannot convert a FunctionDeclaration without a body`); + const updated = factory.createFunctionExpression(node.modifiers, node.asteriskToken, node.name, node.typeParameters, node.parameters, node.type, node.body); + ts.setOriginalNode(updated, node); + ts.setTextRange(updated, node); + if (ts.getStartsOnNewLine(node)) { + ts.setStartsOnNewLine(updated, /*newLine*/ true); } return updated; } - function convertToArrayAssignmentElement(element: ArrayBindingOrAssignmentElement) { - if (isBindingElement(element)) { + function convertToArrayAssignmentElement(element: ts.ArrayBindingOrAssignmentElement) { + if (ts.isBindingElement(element)) { if (element.dotDotDotToken) { - Debug.assertNode(element.name, isIdentifier); - return setOriginalNode(setTextRange(factory.createSpreadElement(element.name), element), element); + ts.Debug.assertNode(element.name, ts.isIdentifier); + return ts.setOriginalNode(ts.setTextRange(factory.createSpreadElement(element.name), element), element); } const expression = convertToAssignmentElementTarget(element.name); return element.initializer - ? setOriginalNode( - setTextRange( - factory.createAssignment(expression, element.initializer), - element - ), - element - ) + ? ts.setOriginalNode(ts.setTextRange(factory.createAssignment(expression, element.initializer), element), element) : expression; } - return cast(element, isExpression); + return ts.cast(element, ts.isExpression); } - function convertToObjectAssignmentElement(element: ObjectBindingOrAssignmentElement) { - if (isBindingElement(element)) { + function convertToObjectAssignmentElement(element: ts.ObjectBindingOrAssignmentElement) { + if (ts.isBindingElement(element)) { if (element.dotDotDotToken) { - Debug.assertNode(element.name, isIdentifier); - return setOriginalNode(setTextRange(factory.createSpreadAssignment(element.name), element), element); + ts.Debug.assertNode(element.name, ts.isIdentifier); + return ts.setOriginalNode(ts.setTextRange(factory.createSpreadAssignment(element.name), element), element); } if (element.propertyName) { const expression = convertToAssignmentElementTarget(element.name); - return setOriginalNode(setTextRange(factory.createPropertyAssignment(element.propertyName, element.initializer ? factory.createAssignment(expression, element.initializer) : expression), element), element); + return ts.setOriginalNode(ts.setTextRange(factory.createPropertyAssignment(element.propertyName, element.initializer ? factory.createAssignment(expression, element.initializer) : expression), element), element); } - Debug.assertNode(element.name, isIdentifier); - return setOriginalNode(setTextRange(factory.createShorthandPropertyAssignment(element.name, element.initializer), element), element); + ts.Debug.assertNode(element.name, ts.isIdentifier); + return ts.setOriginalNode(ts.setTextRange(factory.createShorthandPropertyAssignment(element.name, element.initializer), element), element); } - return cast(element, isObjectLiteralElementLike); + return ts.cast(element, ts.isObjectLiteralElementLike); } - function convertToAssignmentPattern(node: BindingOrAssignmentPattern): AssignmentPattern { + function convertToAssignmentPattern(node: ts.BindingOrAssignmentPattern): ts.AssignmentPattern { switch (node.kind) { - case SyntaxKind.ArrayBindingPattern: - case SyntaxKind.ArrayLiteralExpression: + case ts.SyntaxKind.ArrayBindingPattern: + case ts.SyntaxKind.ArrayLiteralExpression: return convertToArrayAssignmentPattern(node); - case SyntaxKind.ObjectBindingPattern: - case SyntaxKind.ObjectLiteralExpression: + case ts.SyntaxKind.ObjectBindingPattern: + case ts.SyntaxKind.ObjectLiteralExpression: return convertToObjectAssignmentPattern(node); } } - function convertToObjectAssignmentPattern(node: ObjectBindingOrAssignmentPattern) { - if (isObjectBindingPattern(node)) { - return setOriginalNode( - setTextRange( - factory.createObjectLiteralExpression(map(node.elements, convertToObjectAssignmentElement)), - node - ), - node - ); + function convertToObjectAssignmentPattern(node: ts.ObjectBindingOrAssignmentPattern) { + if (ts.isObjectBindingPattern(node)) { + return ts.setOriginalNode(ts.setTextRange(factory.createObjectLiteralExpression(ts.map(node.elements, convertToObjectAssignmentElement)), node), node); } - return cast(node, isObjectLiteralExpression); + return ts.cast(node, ts.isObjectLiteralExpression); } - - function convertToArrayAssignmentPattern(node: ArrayBindingOrAssignmentPattern) { - if (isArrayBindingPattern(node)) { - return setOriginalNode( - setTextRange( - factory.createArrayLiteralExpression(map(node.elements, convertToArrayAssignmentElement)), - node - ), - node - ); + function convertToArrayAssignmentPattern(node: ts.ArrayBindingOrAssignmentPattern) { + if (ts.isArrayBindingPattern(node)) { + return ts.setOriginalNode(ts.setTextRange(factory.createArrayLiteralExpression(ts.map(node.elements, convertToArrayAssignmentElement)), node), node); } - return cast(node, isArrayLiteralExpression); + return ts.cast(node, ts.isArrayLiteralExpression); } - - function convertToAssignmentElementTarget(node: BindingOrAssignmentElementTarget): Expression { - if (isBindingPattern(node)) { + function convertToAssignmentElementTarget(node: ts.BindingOrAssignmentElementTarget): ts.Expression { + if (ts.isBindingPattern(node)) { return convertToAssignmentPattern(node); } - return cast(node, isExpression); + return ts.cast(node, ts.isExpression); } } - export const nullNodeConverters: NodeConverters = { - convertToFunctionBlock: notImplemented, - convertToFunctionExpression: notImplemented, - convertToArrayAssignmentElement: notImplemented, - convertToObjectAssignmentElement: notImplemented, - convertToAssignmentPattern: notImplemented, - convertToObjectAssignmentPattern: notImplemented, - convertToArrayAssignmentPattern: notImplemented, - convertToAssignmentElementTarget: notImplemented, + export const nullNodeConverters: ts.NodeConverters = { + convertToFunctionBlock: ts.notImplemented, + convertToFunctionExpression: ts.notImplemented, + convertToArrayAssignmentElement: ts.notImplemented, + convertToObjectAssignmentElement: ts.notImplemented, + convertToAssignmentPattern: ts.notImplemented, + convertToObjectAssignmentPattern: ts.notImplemented, + convertToArrayAssignmentPattern: ts.notImplemented, + convertToAssignmentElementTarget: ts.notImplemented, }; } \ No newline at end of file diff --git a/src/compiler/factory/nodeFactory.ts b/src/compiler/factory/nodeFactory.ts index 4d171a842c234..5814cdb1d3f7d 100644 --- a/src/compiler/factory/nodeFactory.ts +++ b/src/compiler/factory/nodeFactory.ts @@ -11,7 +11,7 @@ namespace ts { // Ensures new `PropertyAccessExpression` nodes are created with the `NoIndentation` emit flag set. NoIndentationOnFreshPropertyAccess = 1 << 2, // Do not set an `original` pointer when updating a node. - NoOriginalNode = 1 << 3, + NoOriginalNode = 1 << 3 } /** @@ -20,28 +20,41 @@ namespace ts { * @param baseFactory A `BaseNodeFactory` used to create the base `Node` objects. */ /* @internal */ - export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNodeFactory): NodeFactory { + export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: ts.BaseNodeFactory): ts.NodeFactory { const update = flags & NodeFactoryFlags.NoOriginalNode ? updateWithoutOriginal : updateWithOriginal; // Lazily load the parenthesizer, node converters, and some factory methods until they are used. - const parenthesizerRules = memoize(() => flags & NodeFactoryFlags.NoParenthesizerRules ? nullParenthesizerRules : createParenthesizerRules(factory)); - const converters = memoize(() => flags & NodeFactoryFlags.NoNodeConverters ? nullNodeConverters : createNodeConverters(factory)); + const parenthesizerRules = ts.memoize(() => flags & NodeFactoryFlags.NoParenthesizerRules ? ts.nullParenthesizerRules : ts.createParenthesizerRules(factory)); + const converters = ts.memoize(() => flags & NodeFactoryFlags.NoNodeConverters ? ts.nullNodeConverters : ts.createNodeConverters(factory)); // lazy initializaton of common operator factories - const getBinaryCreateFunction = memoizeOne((operator: BinaryOperator) => (left: Expression, right: Expression) => createBinaryExpression(left, operator, right)); - const getPrefixUnaryCreateFunction = memoizeOne((operator: PrefixUnaryOperator) => (operand: Expression) => createPrefixUnaryExpression(operator, operand)); - const getPostfixUnaryCreateFunction = memoizeOne((operator: PostfixUnaryOperator) => (operand: Expression) => createPostfixUnaryExpression(operand, operator)); - const getJSDocPrimaryTypeCreateFunction = memoizeOne((kind: T["kind"]) => () => createJSDocPrimaryTypeWorker(kind)); - const getJSDocUnaryTypeCreateFunction = memoizeOne((kind: T["kind"]) => (type: T["type"]) => createJSDocUnaryTypeWorker(kind, type)); - const getJSDocUnaryTypeUpdateFunction = memoizeOne((kind: T["kind"]) => (node: T, type: T["type"]) => updateJSDocUnaryTypeWorker(kind, node, type)); - const getJSDocPrePostfixUnaryTypeCreateFunction = memoizeOne((kind: T["kind"]) => (type: T["type"], postfix?: boolean) => createJSDocPrePostfixUnaryTypeWorker(kind, type, postfix)); - const getJSDocPrePostfixUnaryTypeUpdateFunction = memoizeOne((kind: T["kind"]) => (node: T, type: T["type"]) => updateJSDocPrePostfixUnaryTypeWorker(kind, node, type)); - const getJSDocSimpleTagCreateFunction = memoizeOne((kind: T["kind"]) => (tagName: Identifier | undefined, comment?: NodeArray) => createJSDocSimpleTagWorker(kind, tagName, comment)); - const getJSDocSimpleTagUpdateFunction = memoizeOne((kind: T["kind"]) => (node: T, tagName: Identifier | undefined, comment?: NodeArray) => updateJSDocSimpleTagWorker(kind, node, tagName, comment)); - const getJSDocTypeLikeTagCreateFunction = memoizeOne((kind: T["kind"]) => (tagName: Identifier | undefined, typeExpression?: JSDocTypeExpression, comment?: NodeArray) => createJSDocTypeLikeTagWorker(kind, tagName, typeExpression, comment)); - const getJSDocTypeLikeTagUpdateFunction = memoizeOne((kind: T["kind"]) => (node: T, tagName: Identifier | undefined, typeExpression?: JSDocTypeExpression, comment?: NodeArray) => updateJSDocTypeLikeTagWorker(kind, node, tagName, typeExpression, comment)); - - const factory: NodeFactory = { + const getBinaryCreateFunction = ts.memoizeOne((operator: ts.BinaryOperator) => (left: ts.Expression, right: ts.Expression) => createBinaryExpression(left, operator, right)); + const getPrefixUnaryCreateFunction = ts.memoizeOne((operator: ts.PrefixUnaryOperator) => (operand: ts.Expression) => createPrefixUnaryExpression(operator, operand)); + const getPostfixUnaryCreateFunction = ts.memoizeOne((operator: ts.PostfixUnaryOperator) => (operand: ts.Expression) => createPostfixUnaryExpression(operand, operator)); + const getJSDocPrimaryTypeCreateFunction = ts.memoizeOne((kind: T["kind"]) => () => createJSDocPrimaryTypeWorker(kind)); + const getJSDocUnaryTypeCreateFunction = ts.memoizeOne((kind: T["kind"]) => (type: T["type"]) => createJSDocUnaryTypeWorker(kind, type)); + const getJSDocUnaryTypeUpdateFunction = ts.memoizeOne((kind: T["kind"]) => (node: T, type: T["type"]) => updateJSDocUnaryTypeWorker(kind, node, type)); + const getJSDocPrePostfixUnaryTypeCreateFunction = ts.memoizeOne((kind: T["kind"]) => (type: T["type"], postfix?: boolean) => createJSDocPrePostfixUnaryTypeWorker(kind, type, postfix)); + const getJSDocPrePostfixUnaryTypeUpdateFunction = ts.memoizeOne((kind: T["kind"]) => (node: T, type: T["type"]) => updateJSDocPrePostfixUnaryTypeWorker(kind, node, type)); + const getJSDocSimpleTagCreateFunction = ts.memoizeOne((kind: T["kind"]) => (tagName: ts.Identifier | undefined, comment?: ts.NodeArray) => createJSDocSimpleTagWorker(kind, tagName, comment)); + const getJSDocSimpleTagUpdateFunction = ts.memoizeOne((kind: T["kind"]) => (node: T, tagName: ts.Identifier | undefined, comment?: ts.NodeArray) => updateJSDocSimpleTagWorker(kind, node, tagName, comment)); + const getJSDocTypeLikeTagCreateFunction = ts.memoizeOne((kind: T["kind"]) => (tagName: ts.Identifier | undefined, typeExpression?: ts.JSDocTypeExpression, comment?: ts.NodeArray) => createJSDocTypeLikeTagWorker(kind, tagName, typeExpression, comment)); + const getJSDocTypeLikeTagUpdateFunction = ts.memoizeOne((kind: T["kind"]) => (node: T, tagName: ts.Identifier | undefined, typeExpression?: ts.JSDocTypeExpression, comment?: ts.NodeArray) => updateJSDocTypeLikeTagWorker(kind, node, tagName, typeExpression, comment)); + const factory: ts.NodeFactory = { get parenthesizer() { return parenthesizerRules(); }, get converters() { return converters(); }, baseFactory, @@ -159,11 +172,11 @@ namespace ts { createObjectLiteralExpression, updateObjectLiteralExpression, createPropertyAccessExpression: flags & NodeFactoryFlags.NoIndentationOnFreshPropertyAccess ? - (expression, name) => setEmitFlags(createPropertyAccessExpression(expression, name), EmitFlags.NoIndentation) : + (expression, name) => ts.setEmitFlags(createPropertyAccessExpression(expression, name), ts.EmitFlags.NoIndentation) : createPropertyAccessExpression, updatePropertyAccessExpression, createPropertyAccessChain: flags & NodeFactoryFlags.NoIndentationOnFreshPropertyAccess ? - (expression, questionDotToken, name) => setEmitFlags(createPropertyAccessChain(expression, questionDotToken, name), EmitFlags.NoIndentation) : + (expression, questionDotToken, name) => ts.setEmitFlags(createPropertyAccessChain(expression, questionDotToken, name), ts.EmitFlags.NoIndentation) : createPropertyAccessChain, updatePropertyAccessChain, createElementAccessExpression, @@ -319,18 +332,18 @@ namespace ts { createExternalModuleReference, updateExternalModuleReference, // lazily load factory members for JSDoc types with similar structure - get createJSDocAllType() { return getJSDocPrimaryTypeCreateFunction(SyntaxKind.JSDocAllType); }, - get createJSDocUnknownType() { return getJSDocPrimaryTypeCreateFunction(SyntaxKind.JSDocUnknownType); }, - get createJSDocNonNullableType() { return getJSDocPrePostfixUnaryTypeCreateFunction(SyntaxKind.JSDocNonNullableType); }, - get updateJSDocNonNullableType() { return getJSDocPrePostfixUnaryTypeUpdateFunction(SyntaxKind.JSDocNonNullableType); }, - get createJSDocNullableType() { return getJSDocPrePostfixUnaryTypeCreateFunction(SyntaxKind.JSDocNullableType); }, - get updateJSDocNullableType() { return getJSDocPrePostfixUnaryTypeUpdateFunction(SyntaxKind.JSDocNullableType); }, - get createJSDocOptionalType() { return getJSDocUnaryTypeCreateFunction(SyntaxKind.JSDocOptionalType); }, - get updateJSDocOptionalType() { return getJSDocUnaryTypeUpdateFunction(SyntaxKind.JSDocOptionalType); }, - get createJSDocVariadicType() { return getJSDocUnaryTypeCreateFunction(SyntaxKind.JSDocVariadicType); }, - get updateJSDocVariadicType() { return getJSDocUnaryTypeUpdateFunction(SyntaxKind.JSDocVariadicType); }, - get createJSDocNamepathType() { return getJSDocUnaryTypeCreateFunction(SyntaxKind.JSDocNamepathType); }, - get updateJSDocNamepathType() { return getJSDocUnaryTypeUpdateFunction(SyntaxKind.JSDocNamepathType); }, + get createJSDocAllType() { return getJSDocPrimaryTypeCreateFunction(ts.SyntaxKind.JSDocAllType); }, + get createJSDocUnknownType() { return getJSDocPrimaryTypeCreateFunction(ts.SyntaxKind.JSDocUnknownType); }, + get createJSDocNonNullableType() { return getJSDocPrePostfixUnaryTypeCreateFunction(ts.SyntaxKind.JSDocNonNullableType); }, + get updateJSDocNonNullableType() { return getJSDocPrePostfixUnaryTypeUpdateFunction(ts.SyntaxKind.JSDocNonNullableType); }, + get createJSDocNullableType() { return getJSDocPrePostfixUnaryTypeCreateFunction(ts.SyntaxKind.JSDocNullableType); }, + get updateJSDocNullableType() { return getJSDocPrePostfixUnaryTypeUpdateFunction(ts.SyntaxKind.JSDocNullableType); }, + get createJSDocOptionalType() { return getJSDocUnaryTypeCreateFunction(ts.SyntaxKind.JSDocOptionalType); }, + get updateJSDocOptionalType() { return getJSDocUnaryTypeUpdateFunction(ts.SyntaxKind.JSDocOptionalType); }, + get createJSDocVariadicType() { return getJSDocUnaryTypeCreateFunction(ts.SyntaxKind.JSDocVariadicType); }, + get updateJSDocVariadicType() { return getJSDocUnaryTypeUpdateFunction(ts.SyntaxKind.JSDocVariadicType); }, + get createJSDocNamepathType() { return getJSDocUnaryTypeCreateFunction(ts.SyntaxKind.JSDocNamepathType); }, + get updateJSDocNamepathType() { return getJSDocUnaryTypeUpdateFunction(ts.SyntaxKind.JSDocNamepathType); }, createJSDocFunctionType, updateJSDocFunctionType, createJSDocTypeLiteral, @@ -366,30 +379,30 @@ namespace ts { createJSDocLinkPlain, updateJSDocLinkPlain, // lazily load factory members for JSDoc tags with similar structure - get createJSDocTypeTag() { return getJSDocTypeLikeTagCreateFunction(SyntaxKind.JSDocTypeTag); }, - get updateJSDocTypeTag() { return getJSDocTypeLikeTagUpdateFunction(SyntaxKind.JSDocTypeTag); }, - get createJSDocReturnTag() { return getJSDocTypeLikeTagCreateFunction(SyntaxKind.JSDocReturnTag); }, - get updateJSDocReturnTag() { return getJSDocTypeLikeTagUpdateFunction(SyntaxKind.JSDocReturnTag); }, - get createJSDocThisTag() { return getJSDocTypeLikeTagCreateFunction(SyntaxKind.JSDocThisTag); }, - get updateJSDocThisTag() { return getJSDocTypeLikeTagUpdateFunction(SyntaxKind.JSDocThisTag); }, - get createJSDocEnumTag() { return getJSDocTypeLikeTagCreateFunction(SyntaxKind.JSDocEnumTag); }, - get updateJSDocEnumTag() { return getJSDocTypeLikeTagUpdateFunction(SyntaxKind.JSDocEnumTag); }, - get createJSDocAuthorTag() { return getJSDocSimpleTagCreateFunction(SyntaxKind.JSDocAuthorTag); }, - get updateJSDocAuthorTag() { return getJSDocSimpleTagUpdateFunction(SyntaxKind.JSDocAuthorTag); }, - get createJSDocClassTag() { return getJSDocSimpleTagCreateFunction(SyntaxKind.JSDocClassTag); }, - get updateJSDocClassTag() { return getJSDocSimpleTagUpdateFunction(SyntaxKind.JSDocClassTag); }, - get createJSDocPublicTag() { return getJSDocSimpleTagCreateFunction(SyntaxKind.JSDocPublicTag); }, - get updateJSDocPublicTag() { return getJSDocSimpleTagUpdateFunction(SyntaxKind.JSDocPublicTag); }, - get createJSDocPrivateTag() { return getJSDocSimpleTagCreateFunction(SyntaxKind.JSDocPrivateTag); }, - get updateJSDocPrivateTag() { return getJSDocSimpleTagUpdateFunction(SyntaxKind.JSDocPrivateTag); }, - get createJSDocProtectedTag() { return getJSDocSimpleTagCreateFunction(SyntaxKind.JSDocProtectedTag); }, - get updateJSDocProtectedTag() { return getJSDocSimpleTagUpdateFunction(SyntaxKind.JSDocProtectedTag); }, - get createJSDocReadonlyTag() { return getJSDocSimpleTagCreateFunction(SyntaxKind.JSDocReadonlyTag); }, - get updateJSDocReadonlyTag() { return getJSDocSimpleTagUpdateFunction(SyntaxKind.JSDocReadonlyTag); }, - get createJSDocOverrideTag() { return getJSDocSimpleTagCreateFunction(SyntaxKind.JSDocOverrideTag); }, - get updateJSDocOverrideTag() { return getJSDocSimpleTagUpdateFunction(SyntaxKind.JSDocOverrideTag); }, - get createJSDocDeprecatedTag() { return getJSDocSimpleTagCreateFunction(SyntaxKind.JSDocDeprecatedTag); }, - get updateJSDocDeprecatedTag() { return getJSDocSimpleTagUpdateFunction(SyntaxKind.JSDocDeprecatedTag); }, + get createJSDocTypeTag() { return getJSDocTypeLikeTagCreateFunction(ts.SyntaxKind.JSDocTypeTag); }, + get updateJSDocTypeTag() { return getJSDocTypeLikeTagUpdateFunction(ts.SyntaxKind.JSDocTypeTag); }, + get createJSDocReturnTag() { return getJSDocTypeLikeTagCreateFunction(ts.SyntaxKind.JSDocReturnTag); }, + get updateJSDocReturnTag() { return getJSDocTypeLikeTagUpdateFunction(ts.SyntaxKind.JSDocReturnTag); }, + get createJSDocThisTag() { return getJSDocTypeLikeTagCreateFunction(ts.SyntaxKind.JSDocThisTag); }, + get updateJSDocThisTag() { return getJSDocTypeLikeTagUpdateFunction(ts.SyntaxKind.JSDocThisTag); }, + get createJSDocEnumTag() { return getJSDocTypeLikeTagCreateFunction(ts.SyntaxKind.JSDocEnumTag); }, + get updateJSDocEnumTag() { return getJSDocTypeLikeTagUpdateFunction(ts.SyntaxKind.JSDocEnumTag); }, + get createJSDocAuthorTag() { return getJSDocSimpleTagCreateFunction(ts.SyntaxKind.JSDocAuthorTag); }, + get updateJSDocAuthorTag() { return getJSDocSimpleTagUpdateFunction(ts.SyntaxKind.JSDocAuthorTag); }, + get createJSDocClassTag() { return getJSDocSimpleTagCreateFunction(ts.SyntaxKind.JSDocClassTag); }, + get updateJSDocClassTag() { return getJSDocSimpleTagUpdateFunction(ts.SyntaxKind.JSDocClassTag); }, + get createJSDocPublicTag() { return getJSDocSimpleTagCreateFunction(ts.SyntaxKind.JSDocPublicTag); }, + get updateJSDocPublicTag() { return getJSDocSimpleTagUpdateFunction(ts.SyntaxKind.JSDocPublicTag); }, + get createJSDocPrivateTag() { return getJSDocSimpleTagCreateFunction(ts.SyntaxKind.JSDocPrivateTag); }, + get updateJSDocPrivateTag() { return getJSDocSimpleTagUpdateFunction(ts.SyntaxKind.JSDocPrivateTag); }, + get createJSDocProtectedTag() { return getJSDocSimpleTagCreateFunction(ts.SyntaxKind.JSDocProtectedTag); }, + get updateJSDocProtectedTag() { return getJSDocSimpleTagUpdateFunction(ts.SyntaxKind.JSDocProtectedTag); }, + get createJSDocReadonlyTag() { return getJSDocSimpleTagCreateFunction(ts.SyntaxKind.JSDocReadonlyTag); }, + get updateJSDocReadonlyTag() { return getJSDocSimpleTagUpdateFunction(ts.SyntaxKind.JSDocReadonlyTag); }, + get createJSDocOverrideTag() { return getJSDocSimpleTagCreateFunction(ts.SyntaxKind.JSDocOverrideTag); }, + get updateJSDocOverrideTag() { return getJSDocSimpleTagUpdateFunction(ts.SyntaxKind.JSDocOverrideTag); }, + get createJSDocDeprecatedTag() { return getJSDocSimpleTagCreateFunction(ts.SyntaxKind.JSDocDeprecatedTag); }, + get updateJSDocDeprecatedTag() { return getJSDocSimpleTagUpdateFunction(ts.SyntaxKind.JSDocDeprecatedTag); }, createJSDocUnknownTag, updateJSDocUnknownTag, createJSDocText, @@ -458,38 +471,38 @@ namespace ts { cloneNode, // Lazily load factory methods for common operator factories and utilities - get createComma() { return getBinaryCreateFunction(SyntaxKind.CommaToken); }, - get createAssignment() { return getBinaryCreateFunction(SyntaxKind.EqualsToken) as NodeFactory["createAssignment"]; }, - get createLogicalOr() { return getBinaryCreateFunction(SyntaxKind.BarBarToken); }, - get createLogicalAnd() { return getBinaryCreateFunction(SyntaxKind.AmpersandAmpersandToken); }, - get createBitwiseOr() { return getBinaryCreateFunction(SyntaxKind.BarToken); }, - get createBitwiseXor() { return getBinaryCreateFunction(SyntaxKind.CaretToken); }, - get createBitwiseAnd() { return getBinaryCreateFunction(SyntaxKind.AmpersandToken); }, - get createStrictEquality() { return getBinaryCreateFunction(SyntaxKind.EqualsEqualsEqualsToken); }, - get createStrictInequality() { return getBinaryCreateFunction(SyntaxKind.ExclamationEqualsEqualsToken); }, - get createEquality() { return getBinaryCreateFunction(SyntaxKind.EqualsEqualsToken); }, - get createInequality() { return getBinaryCreateFunction(SyntaxKind.ExclamationEqualsToken); }, - get createLessThan() { return getBinaryCreateFunction(SyntaxKind.LessThanToken); }, - get createLessThanEquals() { return getBinaryCreateFunction(SyntaxKind.LessThanEqualsToken); }, - get createGreaterThan() { return getBinaryCreateFunction(SyntaxKind.GreaterThanToken); }, - get createGreaterThanEquals() { return getBinaryCreateFunction(SyntaxKind.GreaterThanEqualsToken); }, - get createLeftShift() { return getBinaryCreateFunction(SyntaxKind.LessThanLessThanToken); }, - get createRightShift() { return getBinaryCreateFunction(SyntaxKind.GreaterThanGreaterThanToken); }, - get createUnsignedRightShift() { return getBinaryCreateFunction(SyntaxKind.GreaterThanGreaterThanGreaterThanToken); }, - get createAdd() { return getBinaryCreateFunction(SyntaxKind.PlusToken); }, - get createSubtract() { return getBinaryCreateFunction(SyntaxKind.MinusToken); }, - get createMultiply() { return getBinaryCreateFunction(SyntaxKind.AsteriskToken); }, - get createDivide() { return getBinaryCreateFunction(SyntaxKind.SlashToken); }, - get createModulo() { return getBinaryCreateFunction(SyntaxKind.PercentToken); }, - get createExponent() { return getBinaryCreateFunction(SyntaxKind.AsteriskAsteriskToken); }, - get createPrefixPlus() { return getPrefixUnaryCreateFunction(SyntaxKind.PlusToken); }, - get createPrefixMinus() { return getPrefixUnaryCreateFunction(SyntaxKind.MinusToken); }, - get createPrefixIncrement() { return getPrefixUnaryCreateFunction(SyntaxKind.PlusPlusToken); }, - get createPrefixDecrement() { return getPrefixUnaryCreateFunction(SyntaxKind.MinusMinusToken); }, - get createBitwiseNot() { return getPrefixUnaryCreateFunction(SyntaxKind.TildeToken); }, - get createLogicalNot() { return getPrefixUnaryCreateFunction(SyntaxKind.ExclamationToken); }, - get createPostfixIncrement() { return getPostfixUnaryCreateFunction(SyntaxKind.PlusPlusToken); }, - get createPostfixDecrement() { return getPostfixUnaryCreateFunction(SyntaxKind.MinusMinusToken); }, + get createComma() { return getBinaryCreateFunction(ts.SyntaxKind.CommaToken); }, + get createAssignment() { return getBinaryCreateFunction(ts.SyntaxKind.EqualsToken) as ts.NodeFactory["createAssignment"]; }, + get createLogicalOr() { return getBinaryCreateFunction(ts.SyntaxKind.BarBarToken); }, + get createLogicalAnd() { return getBinaryCreateFunction(ts.SyntaxKind.AmpersandAmpersandToken); }, + get createBitwiseOr() { return getBinaryCreateFunction(ts.SyntaxKind.BarToken); }, + get createBitwiseXor() { return getBinaryCreateFunction(ts.SyntaxKind.CaretToken); }, + get createBitwiseAnd() { return getBinaryCreateFunction(ts.SyntaxKind.AmpersandToken); }, + get createStrictEquality() { return getBinaryCreateFunction(ts.SyntaxKind.EqualsEqualsEqualsToken); }, + get createStrictInequality() { return getBinaryCreateFunction(ts.SyntaxKind.ExclamationEqualsEqualsToken); }, + get createEquality() { return getBinaryCreateFunction(ts.SyntaxKind.EqualsEqualsToken); }, + get createInequality() { return getBinaryCreateFunction(ts.SyntaxKind.ExclamationEqualsToken); }, + get createLessThan() { return getBinaryCreateFunction(ts.SyntaxKind.LessThanToken); }, + get createLessThanEquals() { return getBinaryCreateFunction(ts.SyntaxKind.LessThanEqualsToken); }, + get createGreaterThan() { return getBinaryCreateFunction(ts.SyntaxKind.GreaterThanToken); }, + get createGreaterThanEquals() { return getBinaryCreateFunction(ts.SyntaxKind.GreaterThanEqualsToken); }, + get createLeftShift() { return getBinaryCreateFunction(ts.SyntaxKind.LessThanLessThanToken); }, + get createRightShift() { return getBinaryCreateFunction(ts.SyntaxKind.GreaterThanGreaterThanToken); }, + get createUnsignedRightShift() { return getBinaryCreateFunction(ts.SyntaxKind.GreaterThanGreaterThanGreaterThanToken); }, + get createAdd() { return getBinaryCreateFunction(ts.SyntaxKind.PlusToken); }, + get createSubtract() { return getBinaryCreateFunction(ts.SyntaxKind.MinusToken); }, + get createMultiply() { return getBinaryCreateFunction(ts.SyntaxKind.AsteriskToken); }, + get createDivide() { return getBinaryCreateFunction(ts.SyntaxKind.SlashToken); }, + get createModulo() { return getBinaryCreateFunction(ts.SyntaxKind.PercentToken); }, + get createExponent() { return getBinaryCreateFunction(ts.SyntaxKind.AsteriskAsteriskToken); }, + get createPrefixPlus() { return getPrefixUnaryCreateFunction(ts.SyntaxKind.PlusToken); }, + get createPrefixMinus() { return getPrefixUnaryCreateFunction(ts.SyntaxKind.MinusToken); }, + get createPrefixIncrement() { return getPrefixUnaryCreateFunction(ts.SyntaxKind.PlusPlusToken); }, + get createPrefixDecrement() { return getPrefixUnaryCreateFunction(ts.SyntaxKind.MinusMinusToken); }, + get createBitwiseNot() { return getPrefixUnaryCreateFunction(ts.SyntaxKind.TildeToken); }, + get createLogicalNot() { return getPrefixUnaryCreateFunction(ts.SyntaxKind.ExclamationToken); }, + get createPostfixIncrement() { return getPostfixUnaryCreateFunction(ts.SyntaxKind.PlusPlusToken); }, + get createPostfixDecrement() { return getPostfixUnaryCreateFunction(ts.SyntaxKind.MinusMinusToken); }, // Compound nodes createImmediatelyInvokedFunctionExpression, @@ -535,29 +548,29 @@ namespace ts { return factory; // @api - function createNodeArray(elements?: readonly T[], hasTrailingComma?: boolean): NodeArray { - if (elements === undefined || elements === emptyArray) { + function createNodeArray(elements?: readonly T[], hasTrailingComma?: boolean): ts.NodeArray { + if (elements === undefined || elements === ts.emptyArray) { elements = []; } - else if (isNodeArray(elements)) { + else if (ts.isNodeArray(elements)) { if (hasTrailingComma === undefined || elements.hasTrailingComma === hasTrailingComma) { // Ensure the transform flags have been aggregated for this NodeArray if (elements.transformFlags === undefined) { - aggregateChildrenFlags(elements as MutableNodeArray); + aggregateChildrenFlags(elements as ts.MutableNodeArray); } - Debug.attachNodeArrayDebugInfo(elements); + ts.Debug.attachNodeArrayDebugInfo(elements); return elements; } // This *was* a `NodeArray`, but the `hasTrailingComma` option differs. Recreate the // array with the same elements, text range, and transform flags but with the updated // value for `hasTrailingComma` - const array = elements.slice() as MutableNodeArray; + const array = elements.slice() as ts.MutableNodeArray; array.pos = elements.pos; array.end = elements.end; array.hasTrailingComma = hasTrailingComma; array.transformFlags = elements.transformFlags; - Debug.attachNodeArrayDebugInfo(array); + ts.Debug.attachNodeArrayDebugInfo(array); return array; } @@ -565,23 +578,19 @@ namespace ts { // repeatedly calling push(), the list may not have the optimal memory layout. We invoke slice() for // small arrays (1 to 4 elements) to give the VM a chance to allocate an optimal representation. const length = elements.length; - const array = (length >= 1 && length <= 4 ? elements.slice() : elements) as MutableNodeArray; - setTextRangePosEnd(array, -1, -1); + const array = (length >= 1 && length <= 4 ? elements.slice() : elements) as ts.MutableNodeArray; + ts.setTextRangePosEnd(array, -1, -1); array.hasTrailingComma = !!hasTrailingComma; aggregateChildrenFlags(array); - Debug.attachNodeArrayDebugInfo(array); + ts.Debug.attachNodeArrayDebugInfo(array); return array; } - function createBaseNode(kind: T["kind"]) { - return baseFactory.createBaseNode(kind) as Mutable; + function createBaseNode(kind: T["kind"]) { + return baseFactory.createBaseNode(kind) as ts.Mutable; } - function createBaseDeclaration( - kind: T["kind"], - decorators: readonly Decorator[] | undefined, - modifiers: readonly Modifier[] | undefined - ) { + function createBaseDeclaration(kind: T["kind"], decorators: readonly ts.Decorator[] | undefined, modifiers: readonly ts.Modifier[] | undefined) { const node = createBaseNode(kind); node.decorators = asNodeArray(decorators); node.modifiers = asNodeArray(modifiers); @@ -597,17 +606,8 @@ namespace ts { return node; } - function createBaseNamedDeclaration( - kind: T["kind"], - decorators: readonly Decorator[] | undefined, - modifiers: readonly Modifier[] | undefined, - name: Identifier | PrivateIdentifier | StringLiteralLike | NumericLiteral | ComputedPropertyName | BindingPattern | string | undefined - ) { - const node = createBaseDeclaration( - kind, - decorators, - modifiers - ); + function createBaseNamedDeclaration(kind: T["kind"], decorators: readonly ts.Decorator[] | undefined, modifiers: readonly ts.Modifier[] | undefined, name: ts.Identifier | ts.PrivateIdentifier | ts.StringLiteralLike | ts.NumericLiteral | ts.ComputedPropertyName | ts.BindingPattern | string | undefined) { + const node = createBaseDeclaration(kind, decorators, modifiers); name = asName(name); node.name = name; @@ -616,12 +616,12 @@ namespace ts { // don't propagate child flags. if (name) { switch (node.kind) { - case SyntaxKind.MethodDeclaration: - case SyntaxKind.GetAccessor: - case SyntaxKind.SetAccessor: - case SyntaxKind.PropertyDeclaration: - case SyntaxKind.PropertyAssignment: - if (isIdentifier(name)) { + case ts.SyntaxKind.MethodDeclaration: + case ts.SyntaxKind.GetAccessor: + case ts.SyntaxKind.SetAccessor: + case ts.SyntaxKind.PropertyDeclaration: + case ts.SyntaxKind.PropertyAssignment: + if (ts.isIdentifier(name)) { node.transformFlags |= propagateIdentifierNameFlags(name); break; } @@ -634,166 +634,80 @@ namespace ts { return node; } - function createBaseGenericNamedDeclaration }>( - kind: T["kind"], - decorators: readonly Decorator[] | undefined, - modifiers: readonly Modifier[] | undefined, - name: Identifier | PrivateIdentifier | StringLiteralLike | NumericLiteral | ComputedPropertyName | BindingPattern | string | undefined, - typeParameters: readonly TypeParameterDeclaration[] | undefined - ) { - const node = createBaseNamedDeclaration( - kind, - decorators, - modifiers, - name - ); + function createBaseGenericNamedDeclaration; + }>(kind: T["kind"], decorators: readonly ts.Decorator[] | undefined, modifiers: readonly ts.Modifier[] | undefined, name: ts.Identifier | ts.PrivateIdentifier | ts.StringLiteralLike | ts.NumericLiteral | ts.ComputedPropertyName | ts.BindingPattern | string | undefined, typeParameters: readonly ts.TypeParameterDeclaration[] | undefined) { + const node = createBaseNamedDeclaration(kind, decorators, modifiers, name); node.typeParameters = asNodeArray(typeParameters); node.transformFlags |= propagateChildrenFlags(node.typeParameters); - if (typeParameters) node.transformFlags |= TransformFlags.ContainsTypeScript; - return node; - } - - function createBaseSignatureDeclaration( - kind: T["kind"], - decorators: readonly Decorator[] | undefined, - modifiers: readonly Modifier[] | undefined, - name: Identifier | PrivateIdentifier | StringLiteralLike | NumericLiteral | ComputedPropertyName | BindingPattern | string | undefined, - typeParameters: readonly TypeParameterDeclaration[] | undefined, - parameters: readonly ParameterDeclaration[] | undefined, - type: TypeNode | undefined - ) { - const node = createBaseGenericNamedDeclaration( - kind, - decorators, - modifiers, - name, - typeParameters - ); + if (typeParameters) + node.transformFlags |= ts.TransformFlags.ContainsTypeScript; + return node; + } + function createBaseSignatureDeclaration(kind: T["kind"], decorators: readonly ts.Decorator[] | undefined, modifiers: readonly ts.Modifier[] | undefined, name: ts.Identifier | ts.PrivateIdentifier | ts.StringLiteralLike | ts.NumericLiteral | ts.ComputedPropertyName | ts.BindingPattern | string | undefined, typeParameters: readonly ts.TypeParameterDeclaration[] | undefined, parameters: readonly ts.ParameterDeclaration[] | undefined, type: ts.TypeNode | undefined) { + const node = createBaseGenericNamedDeclaration(kind, decorators, modifiers, name, typeParameters); node.parameters = createNodeArray(parameters); node.type = type; node.transformFlags |= propagateChildrenFlags(node.parameters) | propagateChildFlags(node.type); - if (type) node.transformFlags |= TransformFlags.ContainsTypeScript; + if (type) + node.transformFlags |= ts.TransformFlags.ContainsTypeScript; return node; } - function updateBaseSignatureDeclaration(updated: Mutable, original: T) { + function updateBaseSignatureDeclaration(updated: ts.Mutable, original: T) { // copy children used only for error reporting - if (original.typeArguments) updated.typeArguments = original.typeArguments; + if (original.typeArguments) + updated.typeArguments = original.typeArguments; return update(updated, original); } - function createBaseFunctionLikeDeclaration( - kind: T["kind"], - decorators: readonly Decorator[] | undefined, - modifiers: readonly Modifier[] | undefined, - name: Identifier | PrivateIdentifier | StringLiteralLike | NumericLiteral | ComputedPropertyName | BindingPattern | string | undefined, - typeParameters: readonly TypeParameterDeclaration[] | undefined, - parameters: readonly ParameterDeclaration[] | undefined, - type: TypeNode | undefined, - body: T["body"] - ) { - const node = createBaseSignatureDeclaration( - kind, - decorators, - modifiers, - name, - typeParameters, - parameters, - type - ); + function createBaseFunctionLikeDeclaration(kind: T["kind"], decorators: readonly ts.Decorator[] | undefined, modifiers: readonly ts.Modifier[] | undefined, name: ts.Identifier | ts.PrivateIdentifier | ts.StringLiteralLike | ts.NumericLiteral | ts.ComputedPropertyName | ts.BindingPattern | string | undefined, typeParameters: readonly ts.TypeParameterDeclaration[] | undefined, parameters: readonly ts.ParameterDeclaration[] | undefined, type: ts.TypeNode | undefined, body: T["body"]) { + const node = createBaseSignatureDeclaration(kind, decorators, modifiers, name, typeParameters, parameters, type); node.body = body; - node.transformFlags |= propagateChildFlags(node.body) & ~TransformFlags.ContainsPossibleTopLevelAwait; - if (!body) node.transformFlags |= TransformFlags.ContainsTypeScript; + node.transformFlags |= propagateChildFlags(node.body) & ~ts.TransformFlags.ContainsPossibleTopLevelAwait; + if (!body) + node.transformFlags |= ts.TransformFlags.ContainsTypeScript; return node; } - function updateBaseFunctionLikeDeclaration(updated: Mutable, original: T) { + function updateBaseFunctionLikeDeclaration(updated: ts.Mutable, original: T) { // copy children used only for error reporting - if (original.exclamationToken) updated.exclamationToken = original.exclamationToken; - if (original.typeArguments) updated.typeArguments = original.typeArguments; + if (original.exclamationToken) + updated.exclamationToken = original.exclamationToken; + if (original.typeArguments) + updated.typeArguments = original.typeArguments; return updateBaseSignatureDeclaration(updated, original); } - function createBaseInterfaceOrClassLikeDeclaration( - kind: T["kind"], - decorators: readonly Decorator[] | undefined, - modifiers: readonly Modifier[] | undefined, - name: string | Identifier | undefined, - typeParameters: readonly TypeParameterDeclaration[] | undefined, - heritageClauses: readonly HeritageClause[] | undefined - ) { - const node = createBaseGenericNamedDeclaration( - kind, - decorators, - modifiers, - name, - typeParameters - ); + function createBaseInterfaceOrClassLikeDeclaration(kind: T["kind"], decorators: readonly ts.Decorator[] | undefined, modifiers: readonly ts.Modifier[] | undefined, name: string | ts.Identifier | undefined, typeParameters: readonly ts.TypeParameterDeclaration[] | undefined, heritageClauses: readonly ts.HeritageClause[] | undefined) { + const node = createBaseGenericNamedDeclaration(kind, decorators, modifiers, name, typeParameters); node.heritageClauses = asNodeArray(heritageClauses); node.transformFlags |= propagateChildrenFlags(node.heritageClauses); return node; } - function createBaseClassLikeDeclaration( - kind: T["kind"], - decorators: readonly Decorator[] | undefined, - modifiers: readonly Modifier[] | undefined, - name: string | Identifier | undefined, - typeParameters: readonly TypeParameterDeclaration[] | undefined, - heritageClauses: readonly HeritageClause[] | undefined, - members: readonly ClassElement[] - ) { - const node = createBaseInterfaceOrClassLikeDeclaration( - kind, - decorators, - modifiers, - name, - typeParameters, - heritageClauses - ); + function createBaseClassLikeDeclaration(kind: T["kind"], decorators: readonly ts.Decorator[] | undefined, modifiers: readonly ts.Modifier[] | undefined, name: string | ts.Identifier | undefined, typeParameters: readonly ts.TypeParameterDeclaration[] | undefined, heritageClauses: readonly ts.HeritageClause[] | undefined, members: readonly ts.ClassElement[]) { + const node = createBaseInterfaceOrClassLikeDeclaration(kind, decorators, modifiers, name, typeParameters, heritageClauses); node.members = createNodeArray(members); node.transformFlags |= propagateChildrenFlags(node.members); return node; } - function createBaseBindingLikeDeclaration( - kind: T["kind"], - decorators: readonly Decorator[] | undefined, - modifiers: readonly Modifier[] | undefined, - name: string | T["name"] | undefined, - initializer: Expression | undefined - ) { - const node = createBaseNamedDeclaration( - kind, - decorators, - modifiers, - name - ); + function createBaseBindingLikeDeclaration(kind: T["kind"], decorators: readonly ts.Decorator[] | undefined, modifiers: readonly ts.Modifier[] | undefined, name: string | T["name"] | undefined, initializer: ts.Expression | undefined) { + const node = createBaseNamedDeclaration(kind, decorators, modifiers, name); node.initializer = initializer; node.transformFlags |= propagateChildFlags(node.initializer); return node; } - function createBaseVariableLikeDeclaration( - kind: T["kind"], - decorators: readonly Decorator[] | undefined, - modifiers: readonly Modifier[] | undefined, - name: string | T["name"] | undefined, - type: TypeNode | undefined, - initializer: Expression | undefined - ) { - const node = createBaseBindingLikeDeclaration( - kind, - decorators, - modifiers, - name, - initializer - ); + function createBaseVariableLikeDeclaration(kind: T["kind"], decorators: readonly ts.Decorator[] | undefined, modifiers: readonly ts.Modifier[] | undefined, name: string | T["name"] | undefined, type: ts.TypeNode | undefined, initializer: ts.Expression | undefined) { + const node = createBaseBindingLikeDeclaration(kind, decorators, modifiers, name, initializer); node.type = type; node.transformFlags |= propagateChildFlags(type); - if (type) node.transformFlags |= TransformFlags.ContainsTypeScript; + if (type) + node.transformFlags |= ts.TransformFlags.ContainsTypeScript; return node; } @@ -801,67 +715,66 @@ namespace ts { // Literals // - function createBaseLiteral( - kind: T["kind"], - text: string - ) { + function createBaseLiteral(kind: T["kind"], text: string) { const node = createBaseToken(kind); node.text = text; return node; } // @api - function createNumericLiteral(value: string | number, numericLiteralFlags: TokenFlags = TokenFlags.None): NumericLiteral { - const node = createBaseLiteral(SyntaxKind.NumericLiteral, typeof value === "number" ? value + "" : value); + function createNumericLiteral(value: string | number, numericLiteralFlags: ts.TokenFlags = ts.TokenFlags.None): ts.NumericLiteral { + const node = createBaseLiteral(ts.SyntaxKind.NumericLiteral, typeof value === "number" ? value + "" : value); node.numericLiteralFlags = numericLiteralFlags; - if (numericLiteralFlags & TokenFlags.BinaryOrOctalSpecifier) node.transformFlags |= TransformFlags.ContainsES2015; + if (numericLiteralFlags & ts.TokenFlags.BinaryOrOctalSpecifier) + node.transformFlags |= ts.TransformFlags.ContainsES2015; return node; } // @api - function createBigIntLiteral(value: string | PseudoBigInt): BigIntLiteral { - const node = createBaseLiteral(SyntaxKind.BigIntLiteral, typeof value === "string" ? value : pseudoBigIntToString(value) + "n"); - node.transformFlags |= TransformFlags.ContainsESNext; + function createBigIntLiteral(value: string | ts.PseudoBigInt): ts.BigIntLiteral { + const node = createBaseLiteral(ts.SyntaxKind.BigIntLiteral, typeof value === "string" ? value : ts.pseudoBigIntToString(value) + "n"); + node.transformFlags |= ts.TransformFlags.ContainsESNext; return node; } function createBaseStringLiteral(text: string, isSingleQuote?: boolean) { - const node = createBaseLiteral(SyntaxKind.StringLiteral, text); + const node = createBaseLiteral(ts.SyntaxKind.StringLiteral, text); node.singleQuote = isSingleQuote; return node; } // @api - function createStringLiteral(text: string, isSingleQuote?: boolean, hasExtendedUnicodeEscape?: boolean): StringLiteral { + function createStringLiteral(text: string, isSingleQuote?: boolean, hasExtendedUnicodeEscape?: boolean): ts.StringLiteral { const node = createBaseStringLiteral(text, isSingleQuote); node.hasExtendedUnicodeEscape = hasExtendedUnicodeEscape; - if (hasExtendedUnicodeEscape) node.transformFlags |= TransformFlags.ContainsES2015; + if (hasExtendedUnicodeEscape) + node.transformFlags |= ts.TransformFlags.ContainsES2015; return node; } // @api - function createStringLiteralFromNode(sourceNode: PropertyNameLiteral): StringLiteral { - const node = createBaseStringLiteral(getTextOfIdentifierOrLiteral(sourceNode), /*isSingleQuote*/ undefined); + function createStringLiteralFromNode(sourceNode: ts.PropertyNameLiteral): ts.StringLiteral { + const node = createBaseStringLiteral(ts.getTextOfIdentifierOrLiteral(sourceNode), /*isSingleQuote*/ undefined); node.textSourceNode = sourceNode; return node; } // @api - function createRegularExpressionLiteral(text: string): RegularExpressionLiteral { - const node = createBaseLiteral(SyntaxKind.RegularExpressionLiteral, text); + function createRegularExpressionLiteral(text: string): ts.RegularExpressionLiteral { + const node = createBaseLiteral(ts.SyntaxKind.RegularExpressionLiteral, text); return node; } // @api - function createLiteralLikeNode(kind: LiteralToken["kind"] | SyntaxKind.JsxTextAllWhiteSpaces, text: string): LiteralToken { + function createLiteralLikeNode(kind: ts.LiteralToken["kind"] | ts.SyntaxKind.JsxTextAllWhiteSpaces, text: string): ts.LiteralToken { switch (kind) { - case SyntaxKind.NumericLiteral: return createNumericLiteral(text, /*numericLiteralFlags*/ 0); - case SyntaxKind.BigIntLiteral: return createBigIntLiteral(text); - case SyntaxKind.StringLiteral: return createStringLiteral(text, /*isSingleQuote*/ undefined); - case SyntaxKind.JsxText: return createJsxText(text, /*containsOnlyTriviaWhiteSpaces*/ false); - case SyntaxKind.JsxTextAllWhiteSpaces: return createJsxText(text, /*containsOnlyTriviaWhiteSpaces*/ true); - case SyntaxKind.RegularExpressionLiteral: return createRegularExpressionLiteral(text); - case SyntaxKind.NoSubstitutionTemplateLiteral: return createTemplateLiteralLikeNode(kind, text, /*rawText*/ undefined, /*templateFlags*/ 0) as NoSubstitutionTemplateLiteral; + case ts.SyntaxKind.NumericLiteral: return createNumericLiteral(text, /*numericLiteralFlags*/ 0); + case ts.SyntaxKind.BigIntLiteral: return createBigIntLiteral(text); + case ts.SyntaxKind.StringLiteral: return createStringLiteral(text, /*isSingleQuote*/ undefined); + case ts.SyntaxKind.JsxText: return createJsxText(text, /*containsOnlyTriviaWhiteSpaces*/ false); + case ts.SyntaxKind.JsxTextAllWhiteSpaces: return createJsxText(text, /*containsOnlyTriviaWhiteSpaces*/ true); + case ts.SyntaxKind.RegularExpressionLiteral: return createRegularExpressionLiteral(text); + case ts.SyntaxKind.NoSubstitutionTemplateLiteral: return createTemplateLiteralLikeNode(kind, text, /*rawText*/ undefined, /*templateFlags*/ 0) as ts.NoSubstitutionTemplateLiteral; } } @@ -869,21 +782,21 @@ namespace ts { // Identifiers // - function createBaseIdentifier(text: string, originalKeywordKind: SyntaxKind | undefined) { + function createBaseIdentifier(text: string, originalKeywordKind: ts.SyntaxKind | undefined) { if (originalKeywordKind === undefined && text) { - originalKeywordKind = stringToToken(text); + originalKeywordKind = ts.stringToToken(text); } - if (originalKeywordKind === SyntaxKind.Identifier) { + if (originalKeywordKind === ts.SyntaxKind.Identifier) { originalKeywordKind = undefined; } - const node = baseFactory.createBaseIdentifierNode(SyntaxKind.Identifier) as Mutable; + const node = baseFactory.createBaseIdentifierNode(ts.SyntaxKind.Identifier) as ts.Mutable; node.originalKeywordKind = originalKeywordKind; - node.escapedText = escapeLeadingUnderscores(text); + node.escapedText = ts.escapeLeadingUnderscores(text); return node; } - function createBaseGeneratedIdentifier(text: string, autoGenerateFlags: GeneratedIdentifierFlags) { - const node = createBaseIdentifier(text, /*originalKeywordKind*/ undefined) as Mutable; + function createBaseGeneratedIdentifier(text: string, autoGenerateFlags: ts.GeneratedIdentifierFlags) { + const node = createBaseIdentifier(text, /*originalKeywordKind*/ undefined) as ts.Mutable; node.autoGenerateFlags = autoGenerateFlags; node.autoGenerateId = nextAutoGenerateId; nextAutoGenerateId++; @@ -891,29 +804,30 @@ namespace ts { } // @api - function createIdentifier(text: string, typeArguments?: readonly (TypeNode | TypeParameterDeclaration)[], originalKeywordKind?: SyntaxKind): Identifier { + function createIdentifier(text: string, typeArguments?: readonly (ts.TypeNode | ts.TypeParameterDeclaration)[], originalKeywordKind?: ts.SyntaxKind): ts.Identifier { const node = createBaseIdentifier(text, originalKeywordKind); if (typeArguments) { // NOTE: we do not use `setChildren` here because typeArguments in an identifier do not contribute to transformations node.typeArguments = createNodeArray(typeArguments); } - if (node.originalKeywordKind === SyntaxKind.AwaitKeyword) { - node.transformFlags |= TransformFlags.ContainsPossibleTopLevelAwait; + if (node.originalKeywordKind === ts.SyntaxKind.AwaitKeyword) { + node.transformFlags |= ts.TransformFlags.ContainsPossibleTopLevelAwait; } return node; } // @api - function updateIdentifier(node: Identifier, typeArguments?: NodeArray | undefined): Identifier { + function updateIdentifier(node: ts.Identifier, typeArguments?: ts.NodeArray | undefined): ts.Identifier { return node.typeArguments !== typeArguments - ? update(createIdentifier(idText(node), typeArguments), node) + ? update(createIdentifier(ts.idText(node), typeArguments), node) : node; } // @api - function createTempVariable(recordTempVariable: ((node: Identifier) => void) | undefined, reservedInNestedScopes?: boolean): GeneratedIdentifier { - let flags = GeneratedIdentifierFlags.Auto; - if (reservedInNestedScopes) flags |= GeneratedIdentifierFlags.ReservedInNestedScopes; + function createTempVariable(recordTempVariable: ((node: ts.Identifier) => void) | undefined, reservedInNestedScopes?: boolean): ts.GeneratedIdentifier { + let flags = ts.GeneratedIdentifierFlags.Auto; + if (reservedInNestedScopes) + flags |= ts.GeneratedIdentifierFlags.ReservedInNestedScopes; const name = createBaseGeneratedIdentifier("", flags); if (recordTempVariable) { recordTempVariable(name); @@ -923,35 +837,37 @@ namespace ts { /** Create a unique temporary variable for use in a loop. */ // @api - function createLoopVariable(reservedInNestedScopes?: boolean): Identifier { - let flags = GeneratedIdentifierFlags.Loop; - if (reservedInNestedScopes) flags |= GeneratedIdentifierFlags.ReservedInNestedScopes; + function createLoopVariable(reservedInNestedScopes?: boolean): ts.Identifier { + let flags = ts.GeneratedIdentifierFlags.Loop; + if (reservedInNestedScopes) + flags |= ts.GeneratedIdentifierFlags.ReservedInNestedScopes; return createBaseGeneratedIdentifier("", flags); } /** Create a unique name based on the supplied text. */ // @api - function createUniqueName(text: string, flags: GeneratedIdentifierFlags = GeneratedIdentifierFlags.None): Identifier { - Debug.assert(!(flags & GeneratedIdentifierFlags.KindMask), "Argument out of range: flags"); - Debug.assert((flags & (GeneratedIdentifierFlags.Optimistic | GeneratedIdentifierFlags.FileLevel)) !== GeneratedIdentifierFlags.FileLevel, "GeneratedIdentifierFlags.FileLevel cannot be set without also setting GeneratedIdentifierFlags.Optimistic"); - return createBaseGeneratedIdentifier(text, GeneratedIdentifierFlags.Unique | flags); + function createUniqueName(text: string, flags: ts.GeneratedIdentifierFlags = ts.GeneratedIdentifierFlags.None): ts.Identifier { + ts.Debug.assert(!(flags & ts.GeneratedIdentifierFlags.KindMask), "Argument out of range: flags"); + ts.Debug.assert((flags & (ts.GeneratedIdentifierFlags.Optimistic | ts.GeneratedIdentifierFlags.FileLevel)) !== ts.GeneratedIdentifierFlags.FileLevel, "GeneratedIdentifierFlags.FileLevel cannot be set without also setting GeneratedIdentifierFlags.Optimistic"); + return createBaseGeneratedIdentifier(text, ts.GeneratedIdentifierFlags.Unique | flags); } /** Create a unique name generated for a node. */ // @api - function getGeneratedNameForNode(node: Node | undefined, flags: GeneratedIdentifierFlags = 0): Identifier { - Debug.assert(!(flags & GeneratedIdentifierFlags.KindMask), "Argument out of range: flags"); - const name = createBaseGeneratedIdentifier(node && isIdentifier(node) ? idText(node) : "", GeneratedIdentifierFlags.Node | flags); + function getGeneratedNameForNode(node: ts.Node | undefined, flags: ts.GeneratedIdentifierFlags = 0): ts.Identifier { + ts.Debug.assert(!(flags & ts.GeneratedIdentifierFlags.KindMask), "Argument out of range: flags"); + const name = createBaseGeneratedIdentifier(node && ts.isIdentifier(node) ? ts.idText(node) : "", ts.GeneratedIdentifierFlags.Node | flags); name.original = node; return name; } // @api - function createPrivateIdentifier(text: string): PrivateIdentifier { - if (!startsWith(text, "#")) Debug.fail("First character of private identifier must be #: " + text); - const node = baseFactory.createBasePrivateIdentifierNode(SyntaxKind.PrivateIdentifier) as Mutable; - node.escapedText = escapeLeadingUnderscores(text); - node.transformFlags |= TransformFlags.ContainsClassFields; + function createPrivateIdentifier(text: string): ts.PrivateIdentifier { + if (!ts.startsWith(text, "#")) + ts.Debug.fail("First character of private identifier must be #: " + text); + const node = baseFactory.createBasePrivateIdentifierNode(ts.SyntaxKind.PrivateIdentifier) as ts.Mutable; + node.escapedText = ts.escapeLeadingUnderscores(text); + node.transformFlags |= ts.TransformFlags.ContainsClassFields; return node; } @@ -959,69 +875,68 @@ namespace ts { // Punctuation // - function createBaseToken(kind: T["kind"]) { - return baseFactory.createBaseTokenNode(kind) as Mutable; - } - - // @api - function createToken(token: SyntaxKind.SuperKeyword): SuperExpression; - function createToken(token: SyntaxKind.ThisKeyword): ThisExpression; - function createToken(token: SyntaxKind.NullKeyword): NullLiteral; - function createToken(token: SyntaxKind.TrueKeyword): TrueLiteral; - function createToken(token: SyntaxKind.FalseKeyword): FalseLiteral; - function createToken(token: TKind): PunctuationToken; - function createToken(token: TKind): KeywordTypeNode; - function createToken(token: TKind): ModifierToken; - function createToken(token: TKind): KeywordToken; - function createToken(token: TKind): Token; - function createToken(token: TKind): Token; - function createToken(token: TKind) { - Debug.assert(token >= SyntaxKind.FirstToken && token <= SyntaxKind.LastToken, "Invalid token"); - Debug.assert(token <= SyntaxKind.FirstTemplateToken || token >= SyntaxKind.LastTemplateToken, "Invalid token. Use 'createTemplateLiteralLikeNode' to create template literals."); - Debug.assert(token <= SyntaxKind.FirstLiteralToken || token >= SyntaxKind.LastLiteralToken, "Invalid token. Use 'createLiteralLikeNode' to create literals."); - Debug.assert(token !== SyntaxKind.Identifier, "Invalid token. Use 'createIdentifier' to create identifiers"); - const node = createBaseToken>(token); - let transformFlags = TransformFlags.None; + function createBaseToken(kind: T["kind"]) { + return baseFactory.createBaseTokenNode(kind) as ts.Mutable; + } + // @api + function createToken(token: ts.SyntaxKind.SuperKeyword): ts.SuperExpression; + function createToken(token: ts.SyntaxKind.ThisKeyword): ts.ThisExpression; + function createToken(token: ts.SyntaxKind.NullKeyword): ts.NullLiteral; + function createToken(token: ts.SyntaxKind.TrueKeyword): ts.TrueLiteral; + function createToken(token: ts.SyntaxKind.FalseKeyword): ts.FalseLiteral; + function createToken(token: TKind): ts.PunctuationToken; + function createToken(token: TKind): ts.KeywordTypeNode; + function createToken(token: TKind): ts.ModifierToken; + function createToken(token: TKind): ts.KeywordToken; + function createToken(token: TKind): ts.Token; + function createToken(token: TKind): ts.Token; + function createToken(token: TKind) { + ts.Debug.assert(token >= ts.SyntaxKind.FirstToken && token <= ts.SyntaxKind.LastToken, "Invalid token"); + ts.Debug.assert(token <= ts.SyntaxKind.FirstTemplateToken || token >= ts.SyntaxKind.LastTemplateToken, "Invalid token. Use 'createTemplateLiteralLikeNode' to create template literals."); + ts.Debug.assert(token <= ts.SyntaxKind.FirstLiteralToken || token >= ts.SyntaxKind.LastLiteralToken, "Invalid token. Use 'createLiteralLikeNode' to create literals."); + ts.Debug.assert(token !== ts.SyntaxKind.Identifier, "Invalid token. Use 'createIdentifier' to create identifiers"); + const node = createBaseToken>(token); + let transformFlags = ts.TransformFlags.None; switch (token) { - case SyntaxKind.AsyncKeyword: + case ts.SyntaxKind.AsyncKeyword: // 'async' modifier is ES2017 (async functions) or ES2018 (async generators) transformFlags = - TransformFlags.ContainsES2017 | - TransformFlags.ContainsES2018; + ts.TransformFlags.ContainsES2017 | + ts.TransformFlags.ContainsES2018; break; - case SyntaxKind.PublicKeyword: - case SyntaxKind.PrivateKeyword: - case SyntaxKind.ProtectedKeyword: - case SyntaxKind.ReadonlyKeyword: - case SyntaxKind.AbstractKeyword: - case SyntaxKind.DeclareKeyword: - case SyntaxKind.ConstKeyword: - case SyntaxKind.AnyKeyword: - case SyntaxKind.NumberKeyword: - case SyntaxKind.BigIntKeyword: - case SyntaxKind.NeverKeyword: - case SyntaxKind.ObjectKeyword: - case SyntaxKind.InKeyword: - case SyntaxKind.OutKeyword: - case SyntaxKind.OverrideKeyword: - case SyntaxKind.StringKeyword: - case SyntaxKind.BooleanKeyword: - case SyntaxKind.SymbolKeyword: - case SyntaxKind.VoidKeyword: - case SyntaxKind.UnknownKeyword: - case SyntaxKind.UndefinedKeyword: // `undefined` is an Identifier in the expression case. - transformFlags = TransformFlags.ContainsTypeScript; + case ts.SyntaxKind.PublicKeyword: + case ts.SyntaxKind.PrivateKeyword: + case ts.SyntaxKind.ProtectedKeyword: + case ts.SyntaxKind.ReadonlyKeyword: + case ts.SyntaxKind.AbstractKeyword: + case ts.SyntaxKind.DeclareKeyword: + case ts.SyntaxKind.ConstKeyword: + case ts.SyntaxKind.AnyKeyword: + case ts.SyntaxKind.NumberKeyword: + case ts.SyntaxKind.BigIntKeyword: + case ts.SyntaxKind.NeverKeyword: + case ts.SyntaxKind.ObjectKeyword: + case ts.SyntaxKind.InKeyword: + case ts.SyntaxKind.OutKeyword: + case ts.SyntaxKind.OverrideKeyword: + case ts.SyntaxKind.StringKeyword: + case ts.SyntaxKind.BooleanKeyword: + case ts.SyntaxKind.SymbolKeyword: + case ts.SyntaxKind.VoidKeyword: + case ts.SyntaxKind.UnknownKeyword: + case ts.SyntaxKind.UndefinedKeyword: // `undefined` is an Identifier in the expression case. + transformFlags = ts.TransformFlags.ContainsTypeScript; break; - case SyntaxKind.SuperKeyword: - transformFlags = TransformFlags.ContainsES2015 | TransformFlags.ContainsLexicalSuper; + case ts.SyntaxKind.SuperKeyword: + transformFlags = ts.TransformFlags.ContainsES2015 | ts.TransformFlags.ContainsLexicalSuper; break; - case SyntaxKind.StaticKeyword: - transformFlags = TransformFlags.ContainsES2015; + case ts.SyntaxKind.StaticKeyword: + transformFlags = ts.TransformFlags.ContainsES2015; break; - case SyntaxKind.ThisKeyword: + case ts.SyntaxKind.ThisKeyword: // 'this' indicates a lexical 'this' - transformFlags = TransformFlags.ContainsLexicalThis; + transformFlags = ts.TransformFlags.ContainsLexicalThis; break; } if (transformFlags) { @@ -1036,27 +951,27 @@ namespace ts { // @api function createSuper() { - return createToken(SyntaxKind.SuperKeyword); + return createToken(ts.SyntaxKind.SuperKeyword); } // @api function createThis() { - return createToken(SyntaxKind.ThisKeyword); + return createToken(ts.SyntaxKind.ThisKeyword); } // @api function createNull() { - return createToken(SyntaxKind.NullKeyword); + return createToken(ts.SyntaxKind.NullKeyword); } // @api function createTrue() { - return createToken(SyntaxKind.TrueKeyword); + return createToken(ts.SyntaxKind.TrueKeyword); } // @api function createFalse() { - return createToken(SyntaxKind.FalseKeyword); + return createToken(ts.SyntaxKind.FalseKeyword); } // @@ -1064,27 +979,41 @@ namespace ts { // // @api - function createModifier(kind: T) { + function createModifier(kind: T) { return createToken(kind); } // @api - function createModifiersFromModifierFlags(flags: ModifierFlags) { - const result: Modifier[] = []; - if (flags & ModifierFlags.Export) result.push(createModifier(SyntaxKind.ExportKeyword)); - if (flags & ModifierFlags.Ambient) result.push(createModifier(SyntaxKind.DeclareKeyword)); - if (flags & ModifierFlags.Default) result.push(createModifier(SyntaxKind.DefaultKeyword)); - if (flags & ModifierFlags.Const) result.push(createModifier(SyntaxKind.ConstKeyword)); - if (flags & ModifierFlags.Public) result.push(createModifier(SyntaxKind.PublicKeyword)); - if (flags & ModifierFlags.Private) result.push(createModifier(SyntaxKind.PrivateKeyword)); - if (flags & ModifierFlags.Protected) result.push(createModifier(SyntaxKind.ProtectedKeyword)); - if (flags & ModifierFlags.Abstract) result.push(createModifier(SyntaxKind.AbstractKeyword)); - if (flags & ModifierFlags.Static) result.push(createModifier(SyntaxKind.StaticKeyword)); - if (flags & ModifierFlags.Override) result.push(createModifier(SyntaxKind.OverrideKeyword)); - if (flags & ModifierFlags.Readonly) result.push(createModifier(SyntaxKind.ReadonlyKeyword)); - if (flags & ModifierFlags.Async) result.push(createModifier(SyntaxKind.AsyncKeyword)); - if (flags & ModifierFlags.In) result.push(createModifier(SyntaxKind.InKeyword)); - if (flags & ModifierFlags.Out) result.push(createModifier(SyntaxKind.OutKeyword)); + function createModifiersFromModifierFlags(flags: ts.ModifierFlags) { + const result: ts.Modifier[] = []; + if (flags & ts.ModifierFlags.Export) + result.push(createModifier(ts.SyntaxKind.ExportKeyword)); + if (flags & ts.ModifierFlags.Ambient) + result.push(createModifier(ts.SyntaxKind.DeclareKeyword)); + if (flags & ts.ModifierFlags.Default) + result.push(createModifier(ts.SyntaxKind.DefaultKeyword)); + if (flags & ts.ModifierFlags.Const) + result.push(createModifier(ts.SyntaxKind.ConstKeyword)); + if (flags & ts.ModifierFlags.Public) + result.push(createModifier(ts.SyntaxKind.PublicKeyword)); + if (flags & ts.ModifierFlags.Private) + result.push(createModifier(ts.SyntaxKind.PrivateKeyword)); + if (flags & ts.ModifierFlags.Protected) + result.push(createModifier(ts.SyntaxKind.ProtectedKeyword)); + if (flags & ts.ModifierFlags.Abstract) + result.push(createModifier(ts.SyntaxKind.AbstractKeyword)); + if (flags & ts.ModifierFlags.Static) + result.push(createModifier(ts.SyntaxKind.StaticKeyword)); + if (flags & ts.ModifierFlags.Override) + result.push(createModifier(ts.SyntaxKind.OverrideKeyword)); + if (flags & ts.ModifierFlags.Readonly) + result.push(createModifier(ts.SyntaxKind.ReadonlyKeyword)); + if (flags & ts.ModifierFlags.Async) + result.push(createModifier(ts.SyntaxKind.AsyncKeyword)); + if (flags & ts.ModifierFlags.In) + result.push(createModifier(ts.SyntaxKind.InKeyword)); + if (flags & ts.ModifierFlags.Out) + result.push(createModifier(ts.SyntaxKind.OutKeyword)); return result.length ? result : undefined; } @@ -1093,8 +1022,8 @@ namespace ts { // // @api - function createQualifiedName(left: EntityName, right: string | Identifier) { - const node = createBaseNode(SyntaxKind.QualifiedName); + function createQualifiedName(left: ts.EntityName, right: string | ts.Identifier) { + const node = createBaseNode(ts.SyntaxKind.QualifiedName); node.left = left; node.right = asName(right); node.transformFlags |= @@ -1104,7 +1033,7 @@ namespace ts { } // @api - function updateQualifiedName(node: QualifiedName, left: EntityName, right: Identifier) { + function updateQualifiedName(node: ts.QualifiedName, left: ts.EntityName, right: ts.Identifier) { return node.left !== left || node.right !== right ? update(createQualifiedName(left, right), node) @@ -1112,18 +1041,18 @@ namespace ts { } // @api - function createComputedPropertyName(expression: Expression) { - const node = createBaseNode(SyntaxKind.ComputedPropertyName); + function createComputedPropertyName(expression: ts.Expression) { + const node = createBaseNode(ts.SyntaxKind.ComputedPropertyName); node.expression = parenthesizerRules().parenthesizeExpressionOfComputedPropertyName(expression); node.transformFlags |= propagateChildFlags(node.expression) | - TransformFlags.ContainsES2015 | - TransformFlags.ContainsComputedPropertyName; + ts.TransformFlags.ContainsES2015 | + ts.TransformFlags.ContainsComputedPropertyName; return node; } // @api - function updateComputedPropertyName(node: ComputedPropertyName, expression: Expression) { + function updateComputedPropertyName(node: ts.ComputedPropertyName, expression: ts.Expression) { return node.expression !== expression ? update(createComputedPropertyName(expression), node) : node; @@ -1134,52 +1063,48 @@ namespace ts { // // @api - function createTypeParameterDeclaration(modifiers: readonly Modifier[] | undefined, name: string | Identifier, constraint?: TypeNode, defaultType?: TypeNode): TypeParameterDeclaration; + function createTypeParameterDeclaration(modifiers: readonly ts.Modifier[] | undefined, name: string | ts.Identifier, constraint?: ts.TypeNode, defaultType?: ts.TypeNode): ts.TypeParameterDeclaration; /** @deprecated */ - function createTypeParameterDeclaration(name: string | Identifier, constraint?: TypeNode, defaultType?: TypeNode): TypeParameterDeclaration; - function createTypeParameterDeclaration(modifiersOrName: readonly Modifier[] | string | Identifier | undefined , nameOrConstraint?: string | Identifier | TypeNode, constraintOrDefault?: TypeNode, defaultType?: TypeNode) { + function createTypeParameterDeclaration(name: string | ts.Identifier, constraint?: ts.TypeNode, defaultType?: ts.TypeNode): ts.TypeParameterDeclaration; + function createTypeParameterDeclaration(modifiersOrName: readonly ts.Modifier[] | string | ts.Identifier | undefined, nameOrConstraint?: string | ts.Identifier | ts.TypeNode, constraintOrDefault?: ts.TypeNode, defaultType?: ts.TypeNode) { let name; let modifiers; let constraint; - if (modifiersOrName === undefined || isArray(modifiersOrName)) { + if (modifiersOrName === undefined || ts.isArray(modifiersOrName)) { modifiers = modifiersOrName; - name = nameOrConstraint as string | Identifier; + name = nameOrConstraint as string | ts.Identifier; constraint = constraintOrDefault; } else { modifiers = undefined; name = modifiersOrName; - constraint = nameOrConstraint as TypeNode | undefined; + constraint = nameOrConstraint as ts.TypeNode | undefined; } - const node = createBaseNamedDeclaration( - SyntaxKind.TypeParameter, - /*decorators*/ undefined, - modifiers, - name - ); + const node = createBaseNamedDeclaration(ts.SyntaxKind.TypeParameter, + /*decorators*/ undefined, modifiers, name); node.constraint = constraint; node.default = defaultType; - node.transformFlags = TransformFlags.ContainsTypeScript; + node.transformFlags = ts.TransformFlags.ContainsTypeScript; return node; } // @api - function updateTypeParameterDeclaration(node: TypeParameterDeclaration, modifiers: readonly Modifier[] | undefined, name: Identifier, constraint: TypeNode | undefined, defaultType: TypeNode | undefined): TypeParameterDeclaration; + function updateTypeParameterDeclaration(node: ts.TypeParameterDeclaration, modifiers: readonly ts.Modifier[] | undefined, name: ts.Identifier, constraint: ts.TypeNode | undefined, defaultType: ts.TypeNode | undefined): ts.TypeParameterDeclaration; /** @deprecated */ - function updateTypeParameterDeclaration(node: TypeParameterDeclaration, name: Identifier, constraint: TypeNode | undefined, defaultType: TypeNode | undefined): TypeParameterDeclaration; - function updateTypeParameterDeclaration(node: TypeParameterDeclaration, modifiersOrName: readonly Modifier[] | Identifier | undefined, nameOrConstraint: Identifier | TypeNode | undefined, constraintOrDefault: TypeNode | undefined, defaultType?: TypeNode | undefined) { + function updateTypeParameterDeclaration(node: ts.TypeParameterDeclaration, name: ts.Identifier, constraint: ts.TypeNode | undefined, defaultType: ts.TypeNode | undefined): ts.TypeParameterDeclaration; + function updateTypeParameterDeclaration(node: ts.TypeParameterDeclaration, modifiersOrName: readonly ts.Modifier[] | ts.Identifier | undefined, nameOrConstraint: ts.Identifier | ts.TypeNode | undefined, constraintOrDefault: ts.TypeNode | undefined, defaultType?: ts.TypeNode | undefined) { let name; let modifiers; let constraint; - if (modifiersOrName === undefined || isArray(modifiersOrName)) { + if (modifiersOrName === undefined || ts.isArray(modifiersOrName)) { modifiers = modifiersOrName; - name = nameOrConstraint as Identifier; + name = nameOrConstraint as ts.Identifier; constraint = constraintOrDefault; } else { modifiers = undefined; name = modifiersOrName; - constraint = nameOrConstraint as TypeNode | undefined; + constraint = nameOrConstraint as ts.TypeNode | undefined; } return node.modifiers !== modifiers || node.name !== name @@ -1190,50 +1115,29 @@ namespace ts { } // @api - function createParameterDeclaration( - decorators: readonly Decorator[] | undefined, - modifiers: readonly Modifier[] | undefined, - dotDotDotToken: DotDotDotToken | undefined, - name: string | BindingName, - questionToken?: QuestionToken, - type?: TypeNode, - initializer?: Expression - ) { - const node = createBaseVariableLikeDeclaration( - SyntaxKind.Parameter, - decorators, - modifiers, - name, - type, - initializer && parenthesizerRules().parenthesizeExpressionForDisallowedComma(initializer) - ); + function createParameterDeclaration(decorators: readonly ts.Decorator[] | undefined, modifiers: readonly ts.Modifier[] | undefined, dotDotDotToken: ts.DotDotDotToken | undefined, name: string | ts.BindingName, questionToken?: ts.QuestionToken, type?: ts.TypeNode, initializer?: ts.Expression) { + const node = createBaseVariableLikeDeclaration(ts.SyntaxKind.Parameter, decorators, modifiers, name, type, initializer && parenthesizerRules().parenthesizeExpressionForDisallowedComma(initializer)); node.dotDotDotToken = dotDotDotToken; node.questionToken = questionToken; - if (isThisIdentifier(node.name)) { - node.transformFlags = TransformFlags.ContainsTypeScript; + if (ts.isThisIdentifier(node.name)) { + node.transformFlags = ts.TransformFlags.ContainsTypeScript; } else { node.transformFlags |= propagateChildFlags(node.dotDotDotToken) | propagateChildFlags(node.questionToken); - if (questionToken) node.transformFlags |= TransformFlags.ContainsTypeScript; - if (modifiersToFlags(node.modifiers) & ModifierFlags.ParameterPropertyModifier) node.transformFlags |= TransformFlags.ContainsTypeScriptClassSyntax; - if (initializer || dotDotDotToken) node.transformFlags |= TransformFlags.ContainsES2015; + if (questionToken) + node.transformFlags |= ts.TransformFlags.ContainsTypeScript; + if (ts.modifiersToFlags(node.modifiers) & ts.ModifierFlags.ParameterPropertyModifier) + node.transformFlags |= ts.TransformFlags.ContainsTypeScriptClassSyntax; + if (initializer || dotDotDotToken) + node.transformFlags |= ts.TransformFlags.ContainsES2015; } return node; } // @api - function updateParameterDeclaration( - node: ParameterDeclaration, - decorators: readonly Decorator[] | undefined, - modifiers: readonly Modifier[] | undefined, - dotDotDotToken: DotDotDotToken | undefined, - name: string | BindingName, - questionToken: QuestionToken | undefined, - type: TypeNode | undefined, - initializer: Expression | undefined - ) { + function updateParameterDeclaration(node: ts.ParameterDeclaration, decorators: readonly ts.Decorator[] | undefined, modifiers: readonly ts.Modifier[] | undefined, dotDotDotToken: ts.DotDotDotToken | undefined, name: string | ts.BindingName, questionToken: ts.QuestionToken | undefined, type: ts.TypeNode | undefined, initializer: ts.Expression | undefined) { return node.decorators !== decorators || node.modifiers !== modifiers || node.dotDotDotToken !== dotDotDotToken @@ -1246,18 +1150,18 @@ namespace ts { } // @api - function createDecorator(expression: Expression) { - const node = createBaseNode(SyntaxKind.Decorator); + function createDecorator(expression: ts.Expression) { + const node = createBaseNode(ts.SyntaxKind.Decorator); node.expression = parenthesizerRules().parenthesizeLeftSideOfAccess(expression); node.transformFlags |= propagateChildFlags(node.expression) | - TransformFlags.ContainsTypeScript | - TransformFlags.ContainsTypeScriptClassSyntax; + ts.TransformFlags.ContainsTypeScript | + ts.TransformFlags.ContainsTypeScriptClassSyntax; return node; } // @api - function updateDecorator(node: Decorator, expression: Expression) { + function updateDecorator(node: ts.Decorator, expression: ts.Expression) { return node.expression !== expression ? update(createDecorator(expression), node) : node; @@ -1268,32 +1172,17 @@ namespace ts { // // @api - function createPropertySignature( - modifiers: readonly Modifier[] | undefined, - name: PropertyName | string, - questionToken: QuestionToken | undefined, - type: TypeNode | undefined - ): PropertySignature { - const node = createBaseNamedDeclaration( - SyntaxKind.PropertySignature, - /*decorators*/ undefined, - modifiers, - name - ); + function createPropertySignature(modifiers: readonly ts.Modifier[] | undefined, name: ts.PropertyName | string, questionToken: ts.QuestionToken | undefined, type: ts.TypeNode | undefined): ts.PropertySignature { + const node = createBaseNamedDeclaration(ts.SyntaxKind.PropertySignature, + /*decorators*/ undefined, modifiers, name); node.type = type; node.questionToken = questionToken; - node.transformFlags = TransformFlags.ContainsTypeScript; + node.transformFlags = ts.TransformFlags.ContainsTypeScript; return node; } // @api - function updatePropertySignature( - node: PropertySignature, - modifiers: readonly Modifier[] | undefined, - name: PropertyName, - questionToken: QuestionToken | undefined, - type: TypeNode | undefined - ) { + function updatePropertySignature(node: ts.PropertySignature, modifiers: readonly ts.Modifier[] | undefined, name: ts.PropertyName, questionToken: ts.QuestionToken | undefined, type: ts.TypeNode | undefined) { return node.modifiers !== modifiers || node.name !== name || node.questionToken !== questionToken @@ -1303,52 +1192,30 @@ namespace ts { } // @api - function createPropertyDeclaration( - decorators: readonly Decorator[] | undefined, - modifiers: readonly Modifier[] | undefined, - name: string | PropertyName, - questionOrExclamationToken: QuestionToken | ExclamationToken | undefined, - type: TypeNode | undefined, - initializer: Expression | undefined - ) { - const node = createBaseVariableLikeDeclaration( - SyntaxKind.PropertyDeclaration, - decorators, - modifiers, - name, - type, - initializer - ); - node.questionToken = questionOrExclamationToken && isQuestionToken(questionOrExclamationToken) ? questionOrExclamationToken : undefined; - node.exclamationToken = questionOrExclamationToken && isExclamationToken(questionOrExclamationToken) ? questionOrExclamationToken : undefined; + function createPropertyDeclaration(decorators: readonly ts.Decorator[] | undefined, modifiers: readonly ts.Modifier[] | undefined, name: string | ts.PropertyName, questionOrExclamationToken: ts.QuestionToken | ts.ExclamationToken | undefined, type: ts.TypeNode | undefined, initializer: ts.Expression | undefined) { + const node = createBaseVariableLikeDeclaration(ts.SyntaxKind.PropertyDeclaration, decorators, modifiers, name, type, initializer); + node.questionToken = questionOrExclamationToken && ts.isQuestionToken(questionOrExclamationToken) ? questionOrExclamationToken : undefined; + node.exclamationToken = questionOrExclamationToken && ts.isExclamationToken(questionOrExclamationToken) ? questionOrExclamationToken : undefined; node.transformFlags |= propagateChildFlags(node.questionToken) | propagateChildFlags(node.exclamationToken) | - TransformFlags.ContainsClassFields; - if (isComputedPropertyName(node.name) || (hasStaticModifier(node) && node.initializer)) { - node.transformFlags |= TransformFlags.ContainsTypeScriptClassSyntax; + ts.TransformFlags.ContainsClassFields; + if (ts.isComputedPropertyName(node.name) || (ts.hasStaticModifier(node) && node.initializer)) { + node.transformFlags |= ts.TransformFlags.ContainsTypeScriptClassSyntax; } - if (questionOrExclamationToken || modifiersToFlags(node.modifiers) & ModifierFlags.Ambient) { - node.transformFlags |= TransformFlags.ContainsTypeScript; + if (questionOrExclamationToken || ts.modifiersToFlags(node.modifiers) & ts.ModifierFlags.Ambient) { + node.transformFlags |= ts.TransformFlags.ContainsTypeScript; } return node; } // @api - function updatePropertyDeclaration( - node: PropertyDeclaration, - decorators: readonly Decorator[] | undefined, - modifiers: readonly Modifier[] | undefined, - name: string | PropertyName, - questionOrExclamationToken: QuestionToken | ExclamationToken | undefined, - type: TypeNode | undefined, - initializer: Expression | undefined - ) { + function updatePropertyDeclaration(node: ts.PropertyDeclaration, decorators: readonly ts.Decorator[] | undefined, modifiers: readonly ts.Modifier[] | undefined, name: string | ts.PropertyName, questionOrExclamationToken: ts.QuestionToken | ts.ExclamationToken | undefined, type: ts.TypeNode | undefined, initializer: ts.Expression | undefined) { return node.decorators !== decorators || node.modifiers !== modifiers || node.name !== name - || node.questionToken !== (questionOrExclamationToken !== undefined && isQuestionToken(questionOrExclamationToken) ? questionOrExclamationToken : undefined) - || node.exclamationToken !== (questionOrExclamationToken !== undefined && isExclamationToken(questionOrExclamationToken) ? questionOrExclamationToken : undefined) + || node.questionToken !== (questionOrExclamationToken !== undefined && ts.isQuestionToken(questionOrExclamationToken) ? questionOrExclamationToken : undefined) + || node.exclamationToken !== (questionOrExclamationToken !== undefined && ts.isExclamationToken(questionOrExclamationToken) ? questionOrExclamationToken : undefined) || node.type !== type || node.initializer !== initializer ? update(createPropertyDeclaration(decorators, modifiers, name, questionOrExclamationToken, type, initializer), node) @@ -1356,38 +1223,16 @@ namespace ts { } // @api - function createMethodSignature( - modifiers: readonly Modifier[] | undefined, - name: string | PropertyName, - questionToken: QuestionToken | undefined, - typeParameters: readonly TypeParameterDeclaration[] | undefined, - parameters: readonly ParameterDeclaration[], - type: TypeNode | undefined - ) { - const node = createBaseSignatureDeclaration( - SyntaxKind.MethodSignature, - /*decorators*/ undefined, - modifiers, - name, - typeParameters, - parameters, - type - ); + function createMethodSignature(modifiers: readonly ts.Modifier[] | undefined, name: string | ts.PropertyName, questionToken: ts.QuestionToken | undefined, typeParameters: readonly ts.TypeParameterDeclaration[] | undefined, parameters: readonly ts.ParameterDeclaration[], type: ts.TypeNode | undefined) { + const node = createBaseSignatureDeclaration(ts.SyntaxKind.MethodSignature, + /*decorators*/ undefined, modifiers, name, typeParameters, parameters, type); node.questionToken = questionToken; - node.transformFlags = TransformFlags.ContainsTypeScript; + node.transformFlags = ts.TransformFlags.ContainsTypeScript; return node; } // @api - function updateMethodSignature( - node: MethodSignature, - modifiers: readonly Modifier[] | undefined, - name: PropertyName, - questionToken: QuestionToken | undefined, - typeParameters: NodeArray | undefined, - parameters: NodeArray, - type: TypeNode | undefined - ) { + function updateMethodSignature(node: ts.MethodSignature, modifiers: readonly ts.Modifier[] | undefined, name: ts.PropertyName, questionToken: ts.QuestionToken | undefined, typeParameters: ts.NodeArray | undefined, parameters: ts.NodeArray, type: ts.TypeNode | undefined) { return node.modifiers !== modifiers || node.name !== name || node.questionToken !== questionToken @@ -1399,63 +1244,33 @@ namespace ts { } // @api - function createMethodDeclaration( - decorators: readonly Decorator[] | undefined, - modifiers: readonly Modifier[] | undefined, - asteriskToken: AsteriskToken | undefined, - name: string | PropertyName, - questionToken: QuestionToken | undefined, - typeParameters: readonly TypeParameterDeclaration[] | undefined, - parameters: readonly ParameterDeclaration[], - type: TypeNode | undefined, - body: Block | undefined - ) { - const node = createBaseFunctionLikeDeclaration( - SyntaxKind.MethodDeclaration, - decorators, - modifiers, - name, - typeParameters, - parameters, - type, - body - ); + function createMethodDeclaration(decorators: readonly ts.Decorator[] | undefined, modifiers: readonly ts.Modifier[] | undefined, asteriskToken: ts.AsteriskToken | undefined, name: string | ts.PropertyName, questionToken: ts.QuestionToken | undefined, typeParameters: readonly ts.TypeParameterDeclaration[] | undefined, parameters: readonly ts.ParameterDeclaration[], type: ts.TypeNode | undefined, body: ts.Block | undefined) { + const node = createBaseFunctionLikeDeclaration(ts.SyntaxKind.MethodDeclaration, decorators, modifiers, name, typeParameters, parameters, type, body); node.asteriskToken = asteriskToken; node.questionToken = questionToken; node.transformFlags |= propagateChildFlags(node.asteriskToken) | propagateChildFlags(node.questionToken) | - TransformFlags.ContainsES2015; + ts.TransformFlags.ContainsES2015; if (questionToken) { - node.transformFlags |= TransformFlags.ContainsTypeScript; + node.transformFlags |= ts.TransformFlags.ContainsTypeScript; } - if (modifiersToFlags(node.modifiers) & ModifierFlags.Async) { + if (ts.modifiersToFlags(node.modifiers) & ts.ModifierFlags.Async) { if (asteriskToken) { - node.transformFlags |= TransformFlags.ContainsES2018; + node.transformFlags |= ts.TransformFlags.ContainsES2018; } else { - node.transformFlags |= TransformFlags.ContainsES2017; + node.transformFlags |= ts.TransformFlags.ContainsES2017; } } else if (asteriskToken) { - node.transformFlags |= TransformFlags.ContainsGenerator; + node.transformFlags |= ts.TransformFlags.ContainsGenerator; } return node; } // @api - function updateMethodDeclaration( - node: MethodDeclaration, - decorators: readonly Decorator[] | undefined, - modifiers: readonly Modifier[] | undefined, - asteriskToken: AsteriskToken | undefined, - name: PropertyName, - questionToken: QuestionToken | undefined, - typeParameters: readonly TypeParameterDeclaration[] | undefined, - parameters: readonly ParameterDeclaration[], - type: TypeNode | undefined, - body: Block | undefined - ) { + function updateMethodDeclaration(node: ts.MethodDeclaration, decorators: readonly ts.Decorator[] | undefined, modifiers: readonly ts.Modifier[] | undefined, asteriskToken: ts.AsteriskToken | undefined, name: ts.PropertyName, questionToken: ts.QuestionToken | undefined, typeParameters: readonly ts.TypeParameterDeclaration[] | undefined, parameters: readonly ts.ParameterDeclaration[], type: ts.TypeNode | undefined, body: ts.Block | undefined) { return node.decorators !== decorators || node.modifiers !== modifiers || node.asteriskToken !== asteriskToken @@ -1470,30 +1285,17 @@ namespace ts { } // @api - function createClassStaticBlockDeclaration( - decorators: readonly Decorator[] | undefined, - modifiers: readonly Modifier[] | undefined, - body: Block - ): ClassStaticBlockDeclaration { - const node = createBaseGenericNamedDeclaration( - SyntaxKind.ClassStaticBlockDeclaration, - decorators, - modifiers, + function createClassStaticBlockDeclaration(decorators: readonly ts.Decorator[] | undefined, modifiers: readonly ts.Modifier[] | undefined, body: ts.Block): ts.ClassStaticBlockDeclaration { + const node = createBaseGenericNamedDeclaration(ts.SyntaxKind.ClassStaticBlockDeclaration, decorators, modifiers, /*name*/ undefined, - /*typeParameters*/ undefined - ); + /*typeParameters*/ undefined); node.body = body; - node.transformFlags = propagateChildFlags(body) | TransformFlags.ContainsClassFields; + node.transformFlags = propagateChildFlags(body) | ts.TransformFlags.ContainsClassFields; return node; } // @api - function updateClassStaticBlockDeclaration( - node: ClassStaticBlockDeclaration, - decorators: readonly Decorator[] | undefined, - modifiers: readonly Modifier[] | undefined, - body: Block - ): ClassStaticBlockDeclaration { + function updateClassStaticBlockDeclaration(node: ts.ClassStaticBlockDeclaration, decorators: readonly ts.Decorator[] | undefined, modifiers: readonly ts.Modifier[] | undefined, body: ts.Block): ts.ClassStaticBlockDeclaration { return node.decorators !== decorators || node.modifier !== modifiers || node.body !== body @@ -1502,34 +1304,17 @@ namespace ts { } // @api - function createConstructorDeclaration( - decorators: readonly Decorator[] | undefined, - modifiers: readonly Modifier[] | undefined, - parameters: readonly ParameterDeclaration[], - body: Block | undefined - ) { - const node = createBaseFunctionLikeDeclaration( - SyntaxKind.Constructor, - decorators, - modifiers, + function createConstructorDeclaration(decorators: readonly ts.Decorator[] | undefined, modifiers: readonly ts.Modifier[] | undefined, parameters: readonly ts.ParameterDeclaration[], body: ts.Block | undefined) { + const node = createBaseFunctionLikeDeclaration(ts.SyntaxKind.Constructor, decorators, modifiers, /*name*/ undefined, - /*typeParameters*/ undefined, - parameters, - /*type*/ undefined, - body - ); - node.transformFlags |= TransformFlags.ContainsES2015; + /*typeParameters*/ undefined, parameters, + /*type*/ undefined, body); + node.transformFlags |= ts.TransformFlags.ContainsES2015; return node; } // @api - function updateConstructorDeclaration( - node: ConstructorDeclaration, - decorators: readonly Decorator[] | undefined, - modifiers: readonly Modifier[] | undefined, - parameters: readonly ParameterDeclaration[], - body: Block | undefined - ) { + function updateConstructorDeclaration(node: ts.ConstructorDeclaration, decorators: readonly ts.Decorator[] | undefined, modifiers: readonly ts.Modifier[] | undefined, parameters: readonly ts.ParameterDeclaration[], body: ts.Block | undefined) { return node.decorators !== decorators || node.modifiers !== modifiers || node.parameters !== parameters @@ -1539,36 +1324,12 @@ namespace ts { } // @api - function createGetAccessorDeclaration( - decorators: readonly Decorator[] | undefined, - modifiers: readonly Modifier[] | undefined, - name: string | PropertyName, - parameters: readonly ParameterDeclaration[], - type: TypeNode | undefined, - body: Block | undefined - ) { - return createBaseFunctionLikeDeclaration( - SyntaxKind.GetAccessor, - decorators, - modifiers, - name, - /*typeParameters*/ undefined, - parameters, - type, - body - ); - } - - // @api - function updateGetAccessorDeclaration( - node: GetAccessorDeclaration, - decorators: readonly Decorator[] | undefined, - modifiers: readonly Modifier[] | undefined, - name: PropertyName, - parameters: readonly ParameterDeclaration[], - type: TypeNode | undefined, - body: Block | undefined - ) { + function createGetAccessorDeclaration(decorators: readonly ts.Decorator[] | undefined, modifiers: readonly ts.Modifier[] | undefined, name: string | ts.PropertyName, parameters: readonly ts.ParameterDeclaration[], type: ts.TypeNode | undefined, body: ts.Block | undefined) { + return createBaseFunctionLikeDeclaration(ts.SyntaxKind.GetAccessor, decorators, modifiers, name, + /*typeParameters*/ undefined, parameters, type, body); + } + // @api + function updateGetAccessorDeclaration(node: ts.GetAccessorDeclaration, decorators: readonly ts.Decorator[] | undefined, modifiers: readonly ts.Modifier[] | undefined, name: ts.PropertyName, parameters: readonly ts.ParameterDeclaration[], type: ts.TypeNode | undefined, body: ts.Block | undefined) { return node.decorators !== decorators || node.modifiers !== modifiers || node.name !== name @@ -1580,34 +1341,13 @@ namespace ts { } // @api - function createSetAccessorDeclaration( - decorators: readonly Decorator[] | undefined, - modifiers: readonly Modifier[] | undefined, - name: string | PropertyName, - parameters: readonly ParameterDeclaration[], - body: Block | undefined - ) { - return createBaseFunctionLikeDeclaration( - SyntaxKind.SetAccessor, - decorators, - modifiers, - name, - /*typeParameters*/ undefined, - parameters, - /*type*/ undefined, - body - ); - } - - // @api - function updateSetAccessorDeclaration( - node: SetAccessorDeclaration, - decorators: readonly Decorator[] | undefined, - modifiers: readonly Modifier[] | undefined, - name: PropertyName, - parameters: readonly ParameterDeclaration[], - body: Block | undefined - ) { + function createSetAccessorDeclaration(decorators: readonly ts.Decorator[] | undefined, modifiers: readonly ts.Modifier[] | undefined, name: string | ts.PropertyName, parameters: readonly ts.ParameterDeclaration[], body: ts.Block | undefined) { + return createBaseFunctionLikeDeclaration(ts.SyntaxKind.SetAccessor, decorators, modifiers, name, + /*typeParameters*/ undefined, parameters, + /*type*/ undefined, body); + } + // @api + function updateSetAccessorDeclaration(node: ts.SetAccessorDeclaration, decorators: readonly ts.Decorator[] | undefined, modifiers: readonly ts.Modifier[] | undefined, name: ts.PropertyName, parameters: readonly ts.ParameterDeclaration[], body: ts.Block | undefined) { return node.decorators !== decorators || node.modifiers !== modifiers || node.name !== name @@ -1618,31 +1358,17 @@ namespace ts { } // @api - function createCallSignature( - typeParameters: readonly TypeParameterDeclaration[] | undefined, - parameters: readonly ParameterDeclaration[], - type: TypeNode | undefined - ): CallSignatureDeclaration { - const node = createBaseSignatureDeclaration( - SyntaxKind.CallSignature, + function createCallSignature(typeParameters: readonly ts.TypeParameterDeclaration[] | undefined, parameters: readonly ts.ParameterDeclaration[], type: ts.TypeNode | undefined): ts.CallSignatureDeclaration { + const node = createBaseSignatureDeclaration(ts.SyntaxKind.CallSignature, /*decorators*/ undefined, /*modifiers*/ undefined, - /*name*/ undefined, - typeParameters, - parameters, - type - ); - node.transformFlags = TransformFlags.ContainsTypeScript; + /*name*/ undefined, typeParameters, parameters, type); + node.transformFlags = ts.TransformFlags.ContainsTypeScript; return node; } // @api - function updateCallSignature( - node: CallSignatureDeclaration, - typeParameters: NodeArray | undefined, - parameters: NodeArray, - type: TypeNode | undefined - ) { + function updateCallSignature(node: ts.CallSignatureDeclaration, typeParameters: ts.NodeArray | undefined, parameters: ts.NodeArray, type: ts.TypeNode | undefined) { return node.typeParameters !== typeParameters || node.parameters !== parameters || node.type !== type @@ -1651,31 +1377,17 @@ namespace ts { } // @api - function createConstructSignature( - typeParameters: readonly TypeParameterDeclaration[] | undefined, - parameters: readonly ParameterDeclaration[], - type: TypeNode | undefined - ): ConstructSignatureDeclaration { - const node = createBaseSignatureDeclaration( - SyntaxKind.ConstructSignature, + function createConstructSignature(typeParameters: readonly ts.TypeParameterDeclaration[] | undefined, parameters: readonly ts.ParameterDeclaration[], type: ts.TypeNode | undefined): ts.ConstructSignatureDeclaration { + const node = createBaseSignatureDeclaration(ts.SyntaxKind.ConstructSignature, /*decorators*/ undefined, /*modifiers*/ undefined, - /*name*/ undefined, - typeParameters, - parameters, - type - ); - node.transformFlags = TransformFlags.ContainsTypeScript; + /*name*/ undefined, typeParameters, parameters, type); + node.transformFlags = ts.TransformFlags.ContainsTypeScript; return node; } // @api - function updateConstructSignature( - node: ConstructSignatureDeclaration, - typeParameters: NodeArray | undefined, - parameters: NodeArray, - type: TypeNode | undefined - ) { + function updateConstructSignature(node: ts.ConstructSignatureDeclaration, typeParameters: ts.NodeArray | undefined, parameters: ts.NodeArray, type: ts.TypeNode | undefined) { return node.typeParameters !== typeParameters || node.parameters !== parameters || node.type !== type @@ -1684,33 +1396,16 @@ namespace ts { } // @api - function createIndexSignature( - decorators: readonly Decorator[] | undefined, - modifiers: readonly Modifier[] | undefined, - parameters: readonly ParameterDeclaration[], - type: TypeNode | undefined - ): IndexSignatureDeclaration { - const node = createBaseSignatureDeclaration( - SyntaxKind.IndexSignature, - decorators, - modifiers, + function createIndexSignature(decorators: readonly ts.Decorator[] | undefined, modifiers: readonly ts.Modifier[] | undefined, parameters: readonly ts.ParameterDeclaration[], type: ts.TypeNode | undefined): ts.IndexSignatureDeclaration { + const node = createBaseSignatureDeclaration(ts.SyntaxKind.IndexSignature, decorators, modifiers, /*name*/ undefined, - /*typeParameters*/ undefined, - parameters, - type - ); - node.transformFlags = TransformFlags.ContainsTypeScript; + /*typeParameters*/ undefined, parameters, type); + node.transformFlags = ts.TransformFlags.ContainsTypeScript; return node; } // @api - function updateIndexSignature( - node: IndexSignatureDeclaration, - decorators: readonly Decorator[] | undefined, - modifiers: readonly Modifier[] | undefined, - parameters: readonly ParameterDeclaration[], - type: TypeNode - ) { + function updateIndexSignature(node: ts.IndexSignatureDeclaration, decorators: readonly ts.Decorator[] | undefined, modifiers: readonly ts.Modifier[] | undefined, parameters: readonly ts.ParameterDeclaration[], type: ts.TypeNode) { return node.parameters !== parameters || node.type !== type || node.decorators !== decorators @@ -1720,16 +1415,16 @@ namespace ts { } // @api - function createTemplateLiteralTypeSpan(type: TypeNode, literal: TemplateMiddle | TemplateTail) { - const node = createBaseNode(SyntaxKind.TemplateLiteralTypeSpan); + function createTemplateLiteralTypeSpan(type: ts.TypeNode, literal: ts.TemplateMiddle | ts.TemplateTail) { + const node = createBaseNode(ts.SyntaxKind.TemplateLiteralTypeSpan); node.type = type; node.literal = literal; - node.transformFlags = TransformFlags.ContainsTypeScript; + node.transformFlags = ts.TransformFlags.ContainsTypeScript; return node; } // @api - function updateTemplateLiteralTypeSpan(node: TemplateLiteralTypeSpan, type: TypeNode, literal: TemplateMiddle | TemplateTail) { + function updateTemplateLiteralTypeSpan(node: ts.TemplateLiteralTypeSpan, type: ts.TypeNode, literal: ts.TemplateMiddle | ts.TemplateTail) { return node.type !== type || node.literal !== literal ? update(createTemplateLiteralTypeSpan(type, literal), node) @@ -1741,22 +1436,22 @@ namespace ts { // // @api - function createKeywordTypeNode(kind: TKind) { + function createKeywordTypeNode(kind: TKind) { return createToken(kind); } // @api - function createTypePredicateNode(assertsModifier: AssertsKeyword | undefined, parameterName: Identifier | ThisTypeNode | string, type: TypeNode | undefined) { - const node = createBaseNode(SyntaxKind.TypePredicate); + function createTypePredicateNode(assertsModifier: ts.AssertsKeyword | undefined, parameterName: ts.Identifier | ts.ThisTypeNode | string, type: ts.TypeNode | undefined) { + const node = createBaseNode(ts.SyntaxKind.TypePredicate); node.assertsModifier = assertsModifier; node.parameterName = asName(parameterName); node.type = type; - node.transformFlags = TransformFlags.ContainsTypeScript; + node.transformFlags = ts.TransformFlags.ContainsTypeScript; return node; } // @api - function updateTypePredicateNode(node: TypePredicateNode, assertsModifier: AssertsKeyword | undefined, parameterName: Identifier | ThisTypeNode, type: TypeNode | undefined) { + function updateTypePredicateNode(node: ts.TypePredicateNode, assertsModifier: ts.AssertsKeyword | undefined, parameterName: ts.Identifier | ts.ThisTypeNode, type: ts.TypeNode | undefined) { return node.assertsModifier !== assertsModifier || node.parameterName !== parameterName || node.type !== type @@ -1765,16 +1460,16 @@ namespace ts { } // @api - function createTypeReferenceNode(typeName: string | EntityName, typeArguments: readonly TypeNode[] | undefined) { - const node = createBaseNode(SyntaxKind.TypeReference); + function createTypeReferenceNode(typeName: string | ts.EntityName, typeArguments: readonly ts.TypeNode[] | undefined) { + const node = createBaseNode(ts.SyntaxKind.TypeReference); node.typeName = asName(typeName); node.typeArguments = typeArguments && parenthesizerRules().parenthesizeTypeArguments(createNodeArray(typeArguments)); - node.transformFlags = TransformFlags.ContainsTypeScript; + node.transformFlags = ts.TransformFlags.ContainsTypeScript; return node; } // @api - function updateTypeReferenceNode(node: TypeReferenceNode, typeName: EntityName, typeArguments: NodeArray | undefined) { + function updateTypeReferenceNode(node: ts.TypeReferenceNode, typeName: ts.EntityName, typeArguments: ts.NodeArray | undefined) { return node.typeName !== typeName || node.typeArguments !== typeArguments ? update(createTypeReferenceNode(typeName, typeArguments), node) @@ -1782,31 +1477,17 @@ namespace ts { } // @api - function createFunctionTypeNode( - typeParameters: readonly TypeParameterDeclaration[] | undefined, - parameters: readonly ParameterDeclaration[], - type: TypeNode | undefined - ): FunctionTypeNode { - const node = createBaseSignatureDeclaration( - SyntaxKind.FunctionType, + function createFunctionTypeNode(typeParameters: readonly ts.TypeParameterDeclaration[] | undefined, parameters: readonly ts.ParameterDeclaration[], type: ts.TypeNode | undefined): ts.FunctionTypeNode { + const node = createBaseSignatureDeclaration(ts.SyntaxKind.FunctionType, /*decorators*/ undefined, /*modifiers*/ undefined, - /*name*/ undefined, - typeParameters, - parameters, - type - ); - node.transformFlags = TransformFlags.ContainsTypeScript; + /*name*/ undefined, typeParameters, parameters, type); + node.transformFlags = ts.TransformFlags.ContainsTypeScript; return node; } // @api - function updateFunctionTypeNode( - node: FunctionTypeNode, - typeParameters: NodeArray | undefined, - parameters: NodeArray, - type: TypeNode | undefined - ) { + function updateFunctionTypeNode(node: ts.FunctionTypeNode, typeParameters: ts.NodeArray | undefined, parameters: ts.NodeArray, type: ts.TypeNode | undefined) { return node.typeParameters !== typeParameters || node.parameters !== parameters || node.type !== type @@ -1818,34 +1499,18 @@ namespace ts { function createConstructorTypeNode(...args: Parameters) { return args.length === 4 ? createConstructorTypeNode1(...args) : args.length === 3 ? createConstructorTypeNode2(...args) : - Debug.fail("Incorrect number of arguments specified."); + ts.Debug.fail("Incorrect number of arguments specified."); } - - function createConstructorTypeNode1( - modifiers: readonly Modifier[] | undefined, - typeParameters: readonly TypeParameterDeclaration[] | undefined, - parameters: readonly ParameterDeclaration[], - type: TypeNode | undefined - ): ConstructorTypeNode { - const node = createBaseSignatureDeclaration( - SyntaxKind.ConstructorType, - /*decorators*/ undefined, - modifiers, - /*name*/ undefined, - typeParameters, - parameters, - type - ); - node.transformFlags = TransformFlags.ContainsTypeScript; + function createConstructorTypeNode1(modifiers: readonly ts.Modifier[] | undefined, typeParameters: readonly ts.TypeParameterDeclaration[] | undefined, parameters: readonly ts.ParameterDeclaration[], type: ts.TypeNode | undefined): ts.ConstructorTypeNode { + const node = createBaseSignatureDeclaration(ts.SyntaxKind.ConstructorType, + /*decorators*/ undefined, modifiers, + /*name*/ undefined, typeParameters, parameters, type); + node.transformFlags = ts.TransformFlags.ContainsTypeScript; return node; } /** @deprecated */ - function createConstructorTypeNode2( - typeParameters: readonly TypeParameterDeclaration[] | undefined, - parameters: readonly ParameterDeclaration[], - type: TypeNode | undefined - ): ConstructorTypeNode { + function createConstructorTypeNode2(typeParameters: readonly ts.TypeParameterDeclaration[] | undefined, parameters: readonly ts.ParameterDeclaration[], type: ts.TypeNode | undefined): ts.ConstructorTypeNode { return createConstructorTypeNode1(/*modifiers*/ undefined, typeParameters, parameters, type); } @@ -1853,16 +1518,9 @@ namespace ts { function updateConstructorTypeNode(...args: Parameters) { return args.length === 5 ? updateConstructorTypeNode1(...args) : args.length === 4 ? updateConstructorTypeNode2(...args) : - Debug.fail("Incorrect number of arguments specified."); + ts.Debug.fail("Incorrect number of arguments specified."); } - - function updateConstructorTypeNode1( - node: ConstructorTypeNode, - modifiers: readonly Modifier[] | undefined, - typeParameters: NodeArray | undefined, - parameters: NodeArray, - type: TypeNode | undefined - ) { + function updateConstructorTypeNode1(node: ts.ConstructorTypeNode, modifiers: readonly ts.Modifier[] | undefined, typeParameters: ts.NodeArray | undefined, parameters: ts.NodeArray, type: ts.TypeNode | undefined) { return node.modifiers !== modifiers || node.typeParameters !== typeParameters || node.parameters !== parameters @@ -1872,26 +1530,21 @@ namespace ts { } /** @deprecated */ - function updateConstructorTypeNode2( - node: ConstructorTypeNode, - typeParameters: NodeArray | undefined, - parameters: NodeArray, - type: TypeNode | undefined - ) { + function updateConstructorTypeNode2(node: ts.ConstructorTypeNode, typeParameters: ts.NodeArray | undefined, parameters: ts.NodeArray, type: ts.TypeNode | undefined) { return updateConstructorTypeNode1(node, node.modifiers, typeParameters, parameters, type); } // @api - function createTypeQueryNode(exprName: EntityName, typeArguments?: readonly TypeNode[]) { - const node = createBaseNode(SyntaxKind.TypeQuery); + function createTypeQueryNode(exprName: ts.EntityName, typeArguments?: readonly ts.TypeNode[]) { + const node = createBaseNode(ts.SyntaxKind.TypeQuery); node.exprName = exprName; node.typeArguments = typeArguments && parenthesizerRules().parenthesizeTypeArguments(typeArguments); - node.transformFlags = TransformFlags.ContainsTypeScript; + node.transformFlags = ts.TransformFlags.ContainsTypeScript; return node; } // @api - function updateTypeQueryNode(node: TypeQueryNode, exprName: EntityName, typeArguments?: readonly TypeNode[]) { + function updateTypeQueryNode(node: ts.TypeQueryNode, exprName: ts.EntityName, typeArguments?: readonly ts.TypeNode[]) { return node.exprName !== exprName || node.typeArguments !== typeArguments ? update(createTypeQueryNode(exprName, typeArguments), node) @@ -1899,63 +1552,63 @@ namespace ts { } // @api - function createTypeLiteralNode(members: readonly TypeElement[] | undefined) { - const node = createBaseNode(SyntaxKind.TypeLiteral); + function createTypeLiteralNode(members: readonly ts.TypeElement[] | undefined) { + const node = createBaseNode(ts.SyntaxKind.TypeLiteral); node.members = createNodeArray(members); - node.transformFlags = TransformFlags.ContainsTypeScript; + node.transformFlags = ts.TransformFlags.ContainsTypeScript; return node; } // @api - function updateTypeLiteralNode(node: TypeLiteralNode, members: NodeArray) { + function updateTypeLiteralNode(node: ts.TypeLiteralNode, members: ts.NodeArray) { return node.members !== members ? update(createTypeLiteralNode(members), node) : node; } // @api - function createArrayTypeNode(elementType: TypeNode) { - const node = createBaseNode(SyntaxKind.ArrayType); + function createArrayTypeNode(elementType: ts.TypeNode) { + const node = createBaseNode(ts.SyntaxKind.ArrayType); node.elementType = parenthesizerRules().parenthesizeNonArrayTypeOfPostfixType(elementType); - node.transformFlags = TransformFlags.ContainsTypeScript; + node.transformFlags = ts.TransformFlags.ContainsTypeScript; return node; } // @api - function updateArrayTypeNode(node: ArrayTypeNode, elementType: TypeNode): ArrayTypeNode { + function updateArrayTypeNode(node: ts.ArrayTypeNode, elementType: ts.TypeNode): ts.ArrayTypeNode { return node.elementType !== elementType ? update(createArrayTypeNode(elementType), node) : node; } // @api - function createTupleTypeNode(elements: readonly (TypeNode | NamedTupleMember)[]) { - const node = createBaseNode(SyntaxKind.TupleType); + function createTupleTypeNode(elements: readonly (ts.TypeNode | ts.NamedTupleMember)[]) { + const node = createBaseNode(ts.SyntaxKind.TupleType); node.elements = createNodeArray(parenthesizerRules().parenthesizeElementTypesOfTupleType(elements)); - node.transformFlags = TransformFlags.ContainsTypeScript; + node.transformFlags = ts.TransformFlags.ContainsTypeScript; return node; } // @api - function updateTupleTypeNode(node: TupleTypeNode, elements: readonly (TypeNode | NamedTupleMember)[]) { + function updateTupleTypeNode(node: ts.TupleTypeNode, elements: readonly (ts.TypeNode | ts.NamedTupleMember)[]) { return node.elements !== elements ? update(createTupleTypeNode(elements), node) : node; } // @api - function createNamedTupleMember(dotDotDotToken: DotDotDotToken | undefined, name: Identifier, questionToken: QuestionToken | undefined, type: TypeNode) { - const node = createBaseNode(SyntaxKind.NamedTupleMember); + function createNamedTupleMember(dotDotDotToken: ts.DotDotDotToken | undefined, name: ts.Identifier, questionToken: ts.QuestionToken | undefined, type: ts.TypeNode) { + const node = createBaseNode(ts.SyntaxKind.NamedTupleMember); node.dotDotDotToken = dotDotDotToken; node.name = name; node.questionToken = questionToken; node.type = type; - node.transformFlags = TransformFlags.ContainsTypeScript; + node.transformFlags = ts.TransformFlags.ContainsTypeScript; return node; } // @api - function updateNamedTupleMember(node: NamedTupleMember, dotDotDotToken: DotDotDotToken | undefined, name: Identifier, questionToken: QuestionToken | undefined, type: TypeNode) { + function updateNamedTupleMember(node: ts.NamedTupleMember, dotDotDotToken: ts.DotDotDotToken | undefined, name: ts.Identifier, questionToken: ts.QuestionToken | undefined, type: ts.TypeNode) { return node.dotDotDotToken !== dotDotDotToken || node.name !== name || node.questionToken !== questionToken @@ -1965,81 +1618,81 @@ namespace ts { } // @api - function createOptionalTypeNode(type: TypeNode) { - const node = createBaseNode(SyntaxKind.OptionalType); + function createOptionalTypeNode(type: ts.TypeNode) { + const node = createBaseNode(ts.SyntaxKind.OptionalType); node.type = parenthesizerRules().parenthesizeTypeOfOptionalType(type); - node.transformFlags = TransformFlags.ContainsTypeScript; + node.transformFlags = ts.TransformFlags.ContainsTypeScript; return node; } // @api - function updateOptionalTypeNode(node: OptionalTypeNode, type: TypeNode): OptionalTypeNode { + function updateOptionalTypeNode(node: ts.OptionalTypeNode, type: ts.TypeNode): ts.OptionalTypeNode { return node.type !== type ? update(createOptionalTypeNode(type), node) : node; } // @api - function createRestTypeNode(type: TypeNode) { - const node = createBaseNode(SyntaxKind.RestType); + function createRestTypeNode(type: ts.TypeNode) { + const node = createBaseNode(ts.SyntaxKind.RestType); node.type = type; - node.transformFlags = TransformFlags.ContainsTypeScript; + node.transformFlags = ts.TransformFlags.ContainsTypeScript; return node; } // @api - function updateRestTypeNode(node: RestTypeNode, type: TypeNode): RestTypeNode { + function updateRestTypeNode(node: ts.RestTypeNode, type: ts.TypeNode): ts.RestTypeNode { return node.type !== type ? update(createRestTypeNode(type), node) : node; } - function createUnionOrIntersectionTypeNode(kind: SyntaxKind.UnionType | SyntaxKind.IntersectionType, types: readonly TypeNode[], parenthesize: (nodes: readonly TypeNode[]) => readonly TypeNode[]) { - const node = createBaseNode(kind); + function createUnionOrIntersectionTypeNode(kind: ts.SyntaxKind.UnionType | ts.SyntaxKind.IntersectionType, types: readonly ts.TypeNode[], parenthesize: (nodes: readonly ts.TypeNode[]) => readonly ts.TypeNode[]) { + const node = createBaseNode(kind); node.types = factory.createNodeArray(parenthesize(types)); - node.transformFlags = TransformFlags.ContainsTypeScript; + node.transformFlags = ts.TransformFlags.ContainsTypeScript; return node; } - function updateUnionOrIntersectionTypeNode(node: T, types: NodeArray, parenthesize: (nodes: readonly TypeNode[]) => readonly TypeNode[]): T { + function updateUnionOrIntersectionTypeNode(node: T, types: ts.NodeArray, parenthesize: (nodes: readonly ts.TypeNode[]) => readonly ts.TypeNode[]): T { return node.types !== types ? update(createUnionOrIntersectionTypeNode(node.kind, types, parenthesize) as T, node) : node; } // @api - function createUnionTypeNode(types: readonly TypeNode[]): UnionTypeNode { - return createUnionOrIntersectionTypeNode(SyntaxKind.UnionType, types, parenthesizerRules().parenthesizeConstituentTypesOfUnionType) as UnionTypeNode; + function createUnionTypeNode(types: readonly ts.TypeNode[]): ts.UnionTypeNode { + return createUnionOrIntersectionTypeNode(ts.SyntaxKind.UnionType, types, parenthesizerRules().parenthesizeConstituentTypesOfUnionType) as ts.UnionTypeNode; } // @api - function updateUnionTypeNode(node: UnionTypeNode, types: NodeArray) { + function updateUnionTypeNode(node: ts.UnionTypeNode, types: ts.NodeArray) { return updateUnionOrIntersectionTypeNode(node, types, parenthesizerRules().parenthesizeConstituentTypesOfUnionType); } // @api - function createIntersectionTypeNode(types: readonly TypeNode[]): IntersectionTypeNode { - return createUnionOrIntersectionTypeNode(SyntaxKind.IntersectionType, types, parenthesizerRules().parenthesizeConstituentTypesOfIntersectionType) as IntersectionTypeNode; + function createIntersectionTypeNode(types: readonly ts.TypeNode[]): ts.IntersectionTypeNode { + return createUnionOrIntersectionTypeNode(ts.SyntaxKind.IntersectionType, types, parenthesizerRules().parenthesizeConstituentTypesOfIntersectionType) as ts.IntersectionTypeNode; } // @api - function updateIntersectionTypeNode(node: IntersectionTypeNode, types: NodeArray) { + function updateIntersectionTypeNode(node: ts.IntersectionTypeNode, types: ts.NodeArray) { return updateUnionOrIntersectionTypeNode(node, types, parenthesizerRules().parenthesizeConstituentTypesOfIntersectionType); } // @api - function createConditionalTypeNode(checkType: TypeNode, extendsType: TypeNode, trueType: TypeNode, falseType: TypeNode) { - const node = createBaseNode(SyntaxKind.ConditionalType); + function createConditionalTypeNode(checkType: ts.TypeNode, extendsType: ts.TypeNode, trueType: ts.TypeNode, falseType: ts.TypeNode) { + const node = createBaseNode(ts.SyntaxKind.ConditionalType); node.checkType = parenthesizerRules().parenthesizeCheckTypeOfConditionalType(checkType); node.extendsType = parenthesizerRules().parenthesizeExtendsTypeOfConditionalType(extendsType); node.trueType = trueType; node.falseType = falseType; - node.transformFlags = TransformFlags.ContainsTypeScript; + node.transformFlags = ts.TransformFlags.ContainsTypeScript; return node; } // @api - function updateConditionalTypeNode(node: ConditionalTypeNode, checkType: TypeNode, extendsType: TypeNode, trueType: TypeNode, falseType: TypeNode) { + function updateConditionalTypeNode(node: ts.ConditionalTypeNode, checkType: ts.TypeNode, extendsType: ts.TypeNode, trueType: ts.TypeNode, falseType: ts.TypeNode) { return node.checkType !== checkType || node.extendsType !== extendsType || node.trueType !== trueType @@ -2049,31 +1702,31 @@ namespace ts { } // @api - function createInferTypeNode(typeParameter: TypeParameterDeclaration) { - const node = createBaseNode(SyntaxKind.InferType); + function createInferTypeNode(typeParameter: ts.TypeParameterDeclaration) { + const node = createBaseNode(ts.SyntaxKind.InferType); node.typeParameter = typeParameter; - node.transformFlags = TransformFlags.ContainsTypeScript; + node.transformFlags = ts.TransformFlags.ContainsTypeScript; return node; } // @api - function updateInferTypeNode(node: InferTypeNode, typeParameter: TypeParameterDeclaration) { + function updateInferTypeNode(node: ts.InferTypeNode, typeParameter: ts.TypeParameterDeclaration) { return node.typeParameter !== typeParameter ? update(createInferTypeNode(typeParameter), node) : node; } // @api - function createTemplateLiteralType(head: TemplateHead, templateSpans: readonly TemplateLiteralTypeSpan[]) { - const node = createBaseNode(SyntaxKind.TemplateLiteralType); + function createTemplateLiteralType(head: ts.TemplateHead, templateSpans: readonly ts.TemplateLiteralTypeSpan[]) { + const node = createBaseNode(ts.SyntaxKind.TemplateLiteralType); node.head = head; node.templateSpans = createNodeArray(templateSpans); - node.transformFlags = TransformFlags.ContainsTypeScript; + node.transformFlags = ts.TransformFlags.ContainsTypeScript; return node; } // @api - function updateTemplateLiteralType(node: TemplateLiteralTypeNode, head: TemplateHead, templateSpans: readonly TemplateLiteralTypeSpan[]) { + function updateTemplateLiteralType(node: ts.TemplateLiteralTypeNode, head: ts.TemplateHead, templateSpans: readonly ts.TemplateLiteralTypeSpan[]) { return node.head !== head || node.templateSpans !== templateSpans ? update(createTemplateLiteralType(head, templateSpans), node) @@ -2081,46 +1734,32 @@ namespace ts { } // @api - function createImportTypeNode(argument: TypeNode, qualifier?: EntityName, typeArguments?: readonly TypeNode[], isTypeOf?: boolean): ImportTypeNode; - function createImportTypeNode(argument: TypeNode, assertions?: ImportTypeAssertionContainer, qualifier?: EntityName, typeArguments?: readonly TypeNode[], isTypeOf?: boolean): ImportTypeNode; - function createImportTypeNode( - argument: TypeNode, - qualifierOrAssertions?: EntityName | ImportTypeAssertionContainer, - typeArgumentsOrQualifier?: readonly TypeNode[] | EntityName, - isTypeOfOrTypeArguments?: boolean | readonly TypeNode[], - isTypeOf?: boolean - ) { - const assertion = qualifierOrAssertions && qualifierOrAssertions.kind === SyntaxKind.ImportTypeAssertionContainer ? qualifierOrAssertions : undefined; - const qualifier = qualifierOrAssertions && isEntityName(qualifierOrAssertions) ? qualifierOrAssertions - : typeArgumentsOrQualifier && !isArray(typeArgumentsOrQualifier) ? typeArgumentsOrQualifier : undefined; - const typeArguments = isArray(typeArgumentsOrQualifier) ? typeArgumentsOrQualifier : isArray(isTypeOfOrTypeArguments) ? isTypeOfOrTypeArguments : undefined; + function createImportTypeNode(argument: ts.TypeNode, qualifier?: ts.EntityName, typeArguments?: readonly ts.TypeNode[], isTypeOf?: boolean): ts.ImportTypeNode; + function createImportTypeNode(argument: ts.TypeNode, assertions?: ts.ImportTypeAssertionContainer, qualifier?: ts.EntityName, typeArguments?: readonly ts.TypeNode[], isTypeOf?: boolean): ts.ImportTypeNode; + function createImportTypeNode(argument: ts.TypeNode, qualifierOrAssertions?: ts.EntityName | ts.ImportTypeAssertionContainer, typeArgumentsOrQualifier?: readonly ts.TypeNode[] | ts.EntityName, isTypeOfOrTypeArguments?: boolean | readonly ts.TypeNode[], isTypeOf?: boolean) { + const assertion = qualifierOrAssertions && qualifierOrAssertions.kind === ts.SyntaxKind.ImportTypeAssertionContainer ? qualifierOrAssertions : undefined; + const qualifier = qualifierOrAssertions && ts.isEntityName(qualifierOrAssertions) ? qualifierOrAssertions + : typeArgumentsOrQualifier && !ts.isArray(typeArgumentsOrQualifier) ? typeArgumentsOrQualifier : undefined; + const typeArguments = ts.isArray(typeArgumentsOrQualifier) ? typeArgumentsOrQualifier : ts.isArray(isTypeOfOrTypeArguments) ? isTypeOfOrTypeArguments : undefined; isTypeOf = typeof isTypeOfOrTypeArguments === "boolean" ? isTypeOfOrTypeArguments : typeof isTypeOf === "boolean" ? isTypeOf : false; - const node = createBaseNode(SyntaxKind.ImportType); + const node = createBaseNode(ts.SyntaxKind.ImportType); node.argument = argument; node.assertions = assertion; node.qualifier = qualifier; node.typeArguments = typeArguments && parenthesizerRules().parenthesizeTypeArguments(typeArguments); node.isTypeOf = isTypeOf; - node.transformFlags = TransformFlags.ContainsTypeScript; + node.transformFlags = ts.TransformFlags.ContainsTypeScript; return node; } - // @api - function updateImportTypeNode(node: ImportTypeNode, argument: TypeNode, qualifier: EntityName | undefined, typeArguments: readonly TypeNode[] | undefined, isTypeOf?: boolean | undefined): ImportTypeNode; - function updateImportTypeNode(node: ImportTypeNode, argument: TypeNode, assertions: ImportTypeAssertionContainer | undefined, qualifier: EntityName | undefined, typeArguments: readonly TypeNode[] | undefined, isTypeOf?: boolean | undefined): ImportTypeNode; - function updateImportTypeNode( - node: ImportTypeNode, - argument: TypeNode, - qualifierOrAssertions: EntityName | ImportTypeAssertionContainer | undefined, - typeArgumentsOrQualifier: readonly TypeNode[] | EntityName | undefined, - isTypeOfOrTypeArguments: boolean | readonly TypeNode[] | undefined, - isTypeOf?: boolean | undefined - ) { - const assertion = qualifierOrAssertions && qualifierOrAssertions.kind === SyntaxKind.ImportTypeAssertionContainer ? qualifierOrAssertions : undefined; - const qualifier = qualifierOrAssertions && isEntityName(qualifierOrAssertions) ? qualifierOrAssertions - : typeArgumentsOrQualifier && !isArray(typeArgumentsOrQualifier) ? typeArgumentsOrQualifier : undefined; - const typeArguments = isArray(typeArgumentsOrQualifier) ? typeArgumentsOrQualifier : isArray(isTypeOfOrTypeArguments) ? isTypeOfOrTypeArguments : undefined; + function updateImportTypeNode(node: ts.ImportTypeNode, argument: ts.TypeNode, qualifier: ts.EntityName | undefined, typeArguments: readonly ts.TypeNode[] | undefined, isTypeOf?: boolean | undefined): ts.ImportTypeNode; + function updateImportTypeNode(node: ts.ImportTypeNode, argument: ts.TypeNode, assertions: ts.ImportTypeAssertionContainer | undefined, qualifier: ts.EntityName | undefined, typeArguments: readonly ts.TypeNode[] | undefined, isTypeOf?: boolean | undefined): ts.ImportTypeNode; + function updateImportTypeNode(node: ts.ImportTypeNode, argument: ts.TypeNode, qualifierOrAssertions: ts.EntityName | ts.ImportTypeAssertionContainer | undefined, typeArgumentsOrQualifier: readonly ts.TypeNode[] | ts.EntityName | undefined, isTypeOfOrTypeArguments: boolean | readonly ts.TypeNode[] | undefined, isTypeOf?: boolean | undefined) { + const assertion = qualifierOrAssertions && qualifierOrAssertions.kind === ts.SyntaxKind.ImportTypeAssertionContainer ? qualifierOrAssertions : undefined; + const qualifier = qualifierOrAssertions && ts.isEntityName(qualifierOrAssertions) ? qualifierOrAssertions + : typeArgumentsOrQualifier && !ts.isArray(typeArgumentsOrQualifier) ? typeArgumentsOrQualifier : undefined; + const typeArguments = ts.isArray(typeArgumentsOrQualifier) ? typeArgumentsOrQualifier : ts.isArray(isTypeOfOrTypeArguments) ? isTypeOfOrTypeArguments : undefined; isTypeOf = typeof isTypeOfOrTypeArguments === "boolean" ? isTypeOfOrTypeArguments : typeof isTypeOf === "boolean" ? isTypeOf : node.isTypeOf; return node.argument !== argument @@ -2133,15 +1772,15 @@ namespace ts { } // @api - function createParenthesizedType(type: TypeNode) { - const node = createBaseNode(SyntaxKind.ParenthesizedType); + function createParenthesizedType(type: ts.TypeNode) { + const node = createBaseNode(ts.SyntaxKind.ParenthesizedType); node.type = type; - node.transformFlags = TransformFlags.ContainsTypeScript; + node.transformFlags = ts.TransformFlags.ContainsTypeScript; return node; } // @api - function updateParenthesizedType(node: ParenthesizedTypeNode, type: TypeNode) { + function updateParenthesizedType(node: ts.ParenthesizedTypeNode, type: ts.TypeNode) { return node.type !== type ? update(createParenthesizedType(type), node) : node; @@ -2149,40 +1788,40 @@ namespace ts { // @api function createThisTypeNode() { - const node = createBaseNode(SyntaxKind.ThisType); - node.transformFlags = TransformFlags.ContainsTypeScript; + const node = createBaseNode(ts.SyntaxKind.ThisType); + node.transformFlags = ts.TransformFlags.ContainsTypeScript; return node; } // @api - function createTypeOperatorNode(operator: SyntaxKind.KeyOfKeyword | SyntaxKind.UniqueKeyword | SyntaxKind.ReadonlyKeyword, type: TypeNode): TypeOperatorNode { - const node = createBaseNode(SyntaxKind.TypeOperator); + function createTypeOperatorNode(operator: ts.SyntaxKind.KeyOfKeyword | ts.SyntaxKind.UniqueKeyword | ts.SyntaxKind.ReadonlyKeyword, type: ts.TypeNode): ts.TypeOperatorNode { + const node = createBaseNode(ts.SyntaxKind.TypeOperator); node.operator = operator; - node.type = operator === SyntaxKind.ReadonlyKeyword ? + node.type = operator === ts.SyntaxKind.ReadonlyKeyword ? parenthesizerRules().parenthesizeOperandOfReadonlyTypeOperator(type) : parenthesizerRules().parenthesizeOperandOfTypeOperator(type); - node.transformFlags = TransformFlags.ContainsTypeScript; + node.transformFlags = ts.TransformFlags.ContainsTypeScript; return node; } // @api - function updateTypeOperatorNode(node: TypeOperatorNode, type: TypeNode) { + function updateTypeOperatorNode(node: ts.TypeOperatorNode, type: ts.TypeNode) { return node.type !== type ? update(createTypeOperatorNode(node.operator, type), node) : node; } // @api - function createIndexedAccessTypeNode(objectType: TypeNode, indexType: TypeNode) { - const node = createBaseNode(SyntaxKind.IndexedAccessType); + function createIndexedAccessTypeNode(objectType: ts.TypeNode, indexType: ts.TypeNode) { + const node = createBaseNode(ts.SyntaxKind.IndexedAccessType); node.objectType = parenthesizerRules().parenthesizeNonArrayTypeOfPostfixType(objectType); node.indexType = indexType; - node.transformFlags = TransformFlags.ContainsTypeScript; + node.transformFlags = ts.TransformFlags.ContainsTypeScript; return node; } // @api - function updateIndexedAccessTypeNode(node: IndexedAccessTypeNode, objectType: TypeNode, indexType: TypeNode) { + function updateIndexedAccessTypeNode(node: ts.IndexedAccessTypeNode, objectType: ts.TypeNode, indexType: ts.TypeNode) { return node.objectType !== objectType || node.indexType !== indexType ? update(createIndexedAccessTypeNode(objectType, indexType), node) @@ -2190,20 +1829,20 @@ namespace ts { } // @api - function createMappedTypeNode(readonlyToken: ReadonlyKeyword | PlusToken | MinusToken | undefined, typeParameter: TypeParameterDeclaration, nameType: TypeNode | undefined, questionToken: QuestionToken | PlusToken | MinusToken | undefined, type: TypeNode | undefined, members: readonly TypeElement[] | undefined): MappedTypeNode { - const node = createBaseNode(SyntaxKind.MappedType); + function createMappedTypeNode(readonlyToken: ts.ReadonlyKeyword | ts.PlusToken | ts.MinusToken | undefined, typeParameter: ts.TypeParameterDeclaration, nameType: ts.TypeNode | undefined, questionToken: ts.QuestionToken | ts.PlusToken | ts.MinusToken | undefined, type: ts.TypeNode | undefined, members: readonly ts.TypeElement[] | undefined): ts.MappedTypeNode { + const node = createBaseNode(ts.SyntaxKind.MappedType); node.readonlyToken = readonlyToken; node.typeParameter = typeParameter; node.nameType = nameType; node.questionToken = questionToken; node.type = type; node.members = members && createNodeArray(members); - node.transformFlags = TransformFlags.ContainsTypeScript; + node.transformFlags = ts.TransformFlags.ContainsTypeScript; return node; } // @api - function updateMappedTypeNode(node: MappedTypeNode, readonlyToken: ReadonlyKeyword | PlusToken | MinusToken | undefined, typeParameter: TypeParameterDeclaration, nameType: TypeNode | undefined, questionToken: QuestionToken | PlusToken | MinusToken | undefined, type: TypeNode | undefined, members: readonly TypeElement[] | undefined): MappedTypeNode { + function updateMappedTypeNode(node: ts.MappedTypeNode, readonlyToken: ts.ReadonlyKeyword | ts.PlusToken | ts.MinusToken | undefined, typeParameter: ts.TypeParameterDeclaration, nameType: ts.TypeNode | undefined, questionToken: ts.QuestionToken | ts.PlusToken | ts.MinusToken | undefined, type: ts.TypeNode | undefined, members: readonly ts.TypeElement[] | undefined): ts.MappedTypeNode { return node.readonlyToken !== readonlyToken || node.typeParameter !== typeParameter || node.nameType !== nameType @@ -2215,15 +1854,15 @@ namespace ts { } // @api - function createLiteralTypeNode(literal: LiteralTypeNode["literal"]) { - const node = createBaseNode(SyntaxKind.LiteralType); + function createLiteralTypeNode(literal: ts.LiteralTypeNode["literal"]) { + const node = createBaseNode(ts.SyntaxKind.LiteralType); node.literal = literal; - node.transformFlags = TransformFlags.ContainsTypeScript; + node.transformFlags = ts.TransformFlags.ContainsTypeScript; return node; } // @api - function updateLiteralTypeNode(node: LiteralTypeNode, literal: LiteralTypeNode["literal"]) { + function updateLiteralTypeNode(node: ts.LiteralTypeNode, literal: ts.LiteralTypeNode["literal"]) { return node.literal !== literal ? update(createLiteralTypeNode(literal), node) : node; @@ -2234,71 +1873,68 @@ namespace ts { // // @api - function createObjectBindingPattern(elements: readonly BindingElement[]) { - const node = createBaseNode(SyntaxKind.ObjectBindingPattern); + function createObjectBindingPattern(elements: readonly ts.BindingElement[]) { + const node = createBaseNode(ts.SyntaxKind.ObjectBindingPattern); node.elements = createNodeArray(elements); node.transformFlags |= propagateChildrenFlags(node.elements) | - TransformFlags.ContainsES2015 | - TransformFlags.ContainsBindingPattern; - if (node.transformFlags & TransformFlags.ContainsRestOrSpread) { + ts.TransformFlags.ContainsES2015 | + ts.TransformFlags.ContainsBindingPattern; + if (node.transformFlags & ts.TransformFlags.ContainsRestOrSpread) { node.transformFlags |= - TransformFlags.ContainsES2018 | - TransformFlags.ContainsObjectRestOrSpread; + ts.TransformFlags.ContainsES2018 | + ts.TransformFlags.ContainsObjectRestOrSpread; } return node; } // @api - function updateObjectBindingPattern(node: ObjectBindingPattern, elements: readonly BindingElement[]) { + function updateObjectBindingPattern(node: ts.ObjectBindingPattern, elements: readonly ts.BindingElement[]) { return node.elements !== elements ? update(createObjectBindingPattern(elements), node) : node; } // @api - function createArrayBindingPattern(elements: readonly ArrayBindingElement[]) { - const node = createBaseNode(SyntaxKind.ArrayBindingPattern); + function createArrayBindingPattern(elements: readonly ts.ArrayBindingElement[]) { + const node = createBaseNode(ts.SyntaxKind.ArrayBindingPattern); node.elements = createNodeArray(elements); node.transformFlags |= propagateChildrenFlags(node.elements) | - TransformFlags.ContainsES2015 | - TransformFlags.ContainsBindingPattern; + ts.TransformFlags.ContainsES2015 | + ts.TransformFlags.ContainsBindingPattern; return node; } // @api - function updateArrayBindingPattern(node: ArrayBindingPattern, elements: readonly ArrayBindingElement[]) { + function updateArrayBindingPattern(node: ts.ArrayBindingPattern, elements: readonly ts.ArrayBindingElement[]) { return node.elements !== elements ? update(createArrayBindingPattern(elements), node) : node; } // @api - function createBindingElement(dotDotDotToken: DotDotDotToken | undefined, propertyName: string | PropertyName | undefined, name: string | BindingName, initializer?: Expression) { - const node = createBaseBindingLikeDeclaration( - SyntaxKind.BindingElement, + function createBindingElement(dotDotDotToken: ts.DotDotDotToken | undefined, propertyName: string | ts.PropertyName | undefined, name: string | ts.BindingName, initializer?: ts.Expression) { + const node = createBaseBindingLikeDeclaration(ts.SyntaxKind.BindingElement, /*decorators*/ undefined, - /*modifiers*/ undefined, - name, - initializer && parenthesizerRules().parenthesizeExpressionForDisallowedComma(initializer) - ); + /*modifiers*/ undefined, name, initializer && parenthesizerRules().parenthesizeExpressionForDisallowedComma(initializer)); node.propertyName = asName(propertyName); node.dotDotDotToken = dotDotDotToken; node.transformFlags |= propagateChildFlags(node.dotDotDotToken) | - TransformFlags.ContainsES2015; + ts.TransformFlags.ContainsES2015; if (node.propertyName) { - node.transformFlags |= isIdentifier(node.propertyName) ? + node.transformFlags |= ts.isIdentifier(node.propertyName) ? propagateIdentifierNameFlags(node.propertyName) : propagateChildFlags(node.propertyName); } - if (dotDotDotToken) node.transformFlags |= TransformFlags.ContainsRestOrSpread; + if (dotDotDotToken) + node.transformFlags |= ts.TransformFlags.ContainsRestOrSpread; return node; } // @api - function updateBindingElement(node: BindingElement, dotDotDotToken: DotDotDotToken | undefined, propertyName: PropertyName | undefined, name: BindingName, initializer: Expression | undefined) { + function updateBindingElement(node: ts.BindingElement, dotDotDotToken: ts.DotDotDotToken | undefined, propertyName: ts.PropertyName | undefined, name: ts.BindingName, initializer: ts.Expression | undefined) { return node.propertyName !== propertyName || node.dotDotDotToken !== dotDotDotToken || node.name !== name @@ -2311,20 +1947,20 @@ namespace ts { // Expression // - function createBaseExpression(kind: T["kind"]) { + function createBaseExpression(kind: T["kind"]) { const node = createBaseNode(kind); // the following properties are commonly set by the checker/binder return node; } // @api - function createArrayLiteralExpression(elements?: readonly Expression[], multiLine?: boolean) { - const node = createBaseExpression(SyntaxKind.ArrayLiteralExpression); + function createArrayLiteralExpression(elements?: readonly ts.Expression[], multiLine?: boolean) { + const node = createBaseExpression(ts.SyntaxKind.ArrayLiteralExpression); // Ensure we add a trailing comma for something like `[NumericLiteral(1), NumericLiteral(2), OmittedExpresion]` so that // we end up with `[1, 2, ,]` instead of `[1, 2, ]` otherwise the `OmittedExpression` will just end up being treated like // a trailing comma. - const lastElement = elements && lastOrUndefined(elements); - const elementsArray = createNodeArray(elements, lastElement && isOmittedExpression(lastElement) ? true : undefined); + const lastElement = elements && ts.lastOrUndefined(elements); + const elementsArray = createNodeArray(elements, lastElement && ts.isOmittedExpression(lastElement) ? true : undefined); node.elements = parenthesizerRules().parenthesizeExpressionsOfCommaDelimitedList(elementsArray); node.multiLine = multiLine; node.transformFlags |= propagateChildrenFlags(node.elements); @@ -2332,15 +1968,15 @@ namespace ts { } // @api - function updateArrayLiteralExpression(node: ArrayLiteralExpression, elements: readonly Expression[]) { + function updateArrayLiteralExpression(node: ts.ArrayLiteralExpression, elements: readonly ts.Expression[]) { return node.elements !== elements ? update(createArrayLiteralExpression(elements, node.multiLine), node) : node; } // @api - function createObjectLiteralExpression(properties?: readonly ObjectLiteralElementLike[], multiLine?: boolean) { - const node = createBaseExpression(SyntaxKind.ObjectLiteralExpression); + function createObjectLiteralExpression(properties?: readonly ts.ObjectLiteralElementLike[], multiLine?: boolean) { + const node = createBaseExpression(ts.SyntaxKind.ObjectLiteralExpression); node.properties = createNodeArray(properties); node.multiLine = multiLine; node.transformFlags |= propagateChildrenFlags(node.properties); @@ -2348,36 +1984,36 @@ namespace ts { } // @api - function updateObjectLiteralExpression(node: ObjectLiteralExpression, properties: readonly ObjectLiteralElementLike[]) { + function updateObjectLiteralExpression(node: ts.ObjectLiteralExpression, properties: readonly ts.ObjectLiteralElementLike[]) { return node.properties !== properties ? update(createObjectLiteralExpression(properties, node.multiLine), node) : node; } // @api - function createPropertyAccessExpression(expression: Expression, name: string | Identifier | PrivateIdentifier) { - const node = createBaseExpression(SyntaxKind.PropertyAccessExpression); + function createPropertyAccessExpression(expression: ts.Expression, name: string | ts.Identifier | ts.PrivateIdentifier) { + const node = createBaseExpression(ts.SyntaxKind.PropertyAccessExpression); node.expression = parenthesizerRules().parenthesizeLeftSideOfAccess(expression); node.name = asName(name); node.transformFlags = propagateChildFlags(node.expression) | - (isIdentifier(node.name) ? + (ts.isIdentifier(node.name) ? propagateIdentifierNameFlags(node.name) : propagateChildFlags(node.name)); - if (isSuperKeyword(expression)) { + if (ts.isSuperKeyword(expression)) { // super method calls require a lexical 'this' // super method calls require 'super' hoisting in ES2017 and ES2018 async functions and async generators node.transformFlags |= - TransformFlags.ContainsES2017 | - TransformFlags.ContainsES2018; + ts.TransformFlags.ContainsES2017 | + ts.TransformFlags.ContainsES2018; } return node; } // @api - function updatePropertyAccessExpression(node: PropertyAccessExpression, expression: Expression, name: Identifier | PrivateIdentifier) { - if (isPropertyAccessChain(node)) { - return updatePropertyAccessChain(node, expression, node.questionDotToken, cast(name, isIdentifier)); + function updatePropertyAccessExpression(node: ts.PropertyAccessExpression, expression: ts.Expression, name: ts.Identifier | ts.PrivateIdentifier) { + if (ts.isPropertyAccessChain(node)) { + return updatePropertyAccessChain(node, expression, node.questionDotToken, ts.cast(name, ts.isIdentifier)); } return node.expression !== expression || node.name !== name @@ -2386,25 +2022,25 @@ namespace ts { } // @api - function createPropertyAccessChain(expression: Expression, questionDotToken: QuestionDotToken | undefined, name: string | Identifier | PrivateIdentifier) { - const node = createBaseExpression(SyntaxKind.PropertyAccessExpression); - node.flags |= NodeFlags.OptionalChain; + function createPropertyAccessChain(expression: ts.Expression, questionDotToken: ts.QuestionDotToken | undefined, name: string | ts.Identifier | ts.PrivateIdentifier) { + const node = createBaseExpression(ts.SyntaxKind.PropertyAccessExpression); + node.flags |= ts.NodeFlags.OptionalChain; node.expression = parenthesizerRules().parenthesizeLeftSideOfAccess(expression); node.questionDotToken = questionDotToken; node.name = asName(name); node.transformFlags |= - TransformFlags.ContainsES2020 | + ts.TransformFlags.ContainsES2020 | propagateChildFlags(node.expression) | propagateChildFlags(node.questionDotToken) | - (isIdentifier(node.name) ? + (ts.isIdentifier(node.name) ? propagateIdentifierNameFlags(node.name) : propagateChildFlags(node.name)); return node; } // @api - function updatePropertyAccessChain(node: PropertyAccessChain, expression: Expression, questionDotToken: QuestionDotToken | undefined, name: Identifier | PrivateIdentifier) { - Debug.assert(!!(node.flags & NodeFlags.OptionalChain), "Cannot update a PropertyAccessExpression using updatePropertyAccessChain. Use updatePropertyAccess instead."); + function updatePropertyAccessChain(node: ts.PropertyAccessChain, expression: ts.Expression, questionDotToken: ts.QuestionDotToken | undefined, name: ts.Identifier | ts.PrivateIdentifier) { + ts.Debug.assert(!!(node.flags & ts.NodeFlags.OptionalChain), "Cannot update a PropertyAccessExpression using updatePropertyAccessChain. Use updatePropertyAccess instead."); // Because we are updating an existing PropertyAccessChain we want to inherit its emitFlags // instead of using the default from createPropertyAccess return node.expression !== expression @@ -2415,26 +2051,26 @@ namespace ts { } // @api - function createElementAccessExpression(expression: Expression, index: number | Expression) { - const node = createBaseExpression(SyntaxKind.ElementAccessExpression); + function createElementAccessExpression(expression: ts.Expression, index: number | ts.Expression) { + const node = createBaseExpression(ts.SyntaxKind.ElementAccessExpression); node.expression = parenthesizerRules().parenthesizeLeftSideOfAccess(expression); node.argumentExpression = asExpression(index); node.transformFlags |= propagateChildFlags(node.expression) | propagateChildFlags(node.argumentExpression); - if (isSuperKeyword(expression)) { + if (ts.isSuperKeyword(expression)) { // super method calls require a lexical 'this' // super method calls require 'super' hoisting in ES2017 and ES2018 async functions and async generators node.transformFlags |= - TransformFlags.ContainsES2017 | - TransformFlags.ContainsES2018; + ts.TransformFlags.ContainsES2017 | + ts.TransformFlags.ContainsES2018; } return node; } // @api - function updateElementAccessExpression(node: ElementAccessExpression, expression: Expression, argumentExpression: Expression) { - if (isElementAccessChain(node)) { + function updateElementAccessExpression(node: ts.ElementAccessExpression, expression: ts.Expression, argumentExpression: ts.Expression) { + if (ts.isElementAccessChain(node)) { return updateElementAccessChain(node, expression, node.questionDotToken, argumentExpression); } return node.expression !== expression @@ -2444,9 +2080,9 @@ namespace ts { } // @api - function createElementAccessChain(expression: Expression, questionDotToken: QuestionDotToken | undefined, index: number | Expression) { - const node = createBaseExpression(SyntaxKind.ElementAccessExpression); - node.flags |= NodeFlags.OptionalChain; + function createElementAccessChain(expression: ts.Expression, questionDotToken: ts.QuestionDotToken | undefined, index: number | ts.Expression) { + const node = createBaseExpression(ts.SyntaxKind.ElementAccessExpression); + node.flags |= ts.NodeFlags.OptionalChain; node.expression = parenthesizerRules().parenthesizeLeftSideOfAccess(expression); node.questionDotToken = questionDotToken; node.argumentExpression = asExpression(index); @@ -2454,13 +2090,13 @@ namespace ts { propagateChildFlags(node.expression) | propagateChildFlags(node.questionDotToken) | propagateChildFlags(node.argumentExpression) | - TransformFlags.ContainsES2020; + ts.TransformFlags.ContainsES2020; return node; } // @api - function updateElementAccessChain(node: ElementAccessChain, expression: Expression, questionDotToken: QuestionDotToken | undefined, argumentExpression: Expression) { - Debug.assert(!!(node.flags & NodeFlags.OptionalChain), "Cannot update a ElementAccessExpression using updateElementAccessChain. Use updateElementAccess instead."); + function updateElementAccessChain(node: ts.ElementAccessChain, expression: ts.Expression, questionDotToken: ts.QuestionDotToken | undefined, argumentExpression: ts.Expression) { + ts.Debug.assert(!!(node.flags & ts.NodeFlags.OptionalChain), "Cannot update a ElementAccessExpression using updateElementAccessChain. Use updateElementAccess instead."); // Because we are updating an existing ElementAccessChain we want to inherit its emitFlags // instead of using the default from createElementAccess return node.expression !== expression @@ -2471,8 +2107,8 @@ namespace ts { } // @api - function createCallExpression(expression: Expression, typeArguments: readonly TypeNode[] | undefined, argumentsArray: readonly Expression[] | undefined) { - const node = createBaseExpression(SyntaxKind.CallExpression); + function createCallExpression(expression: ts.Expression, typeArguments: readonly ts.TypeNode[] | undefined, argumentsArray: readonly ts.Expression[] | undefined) { + const node = createBaseExpression(ts.SyntaxKind.CallExpression); node.expression = parenthesizerRules().parenthesizeLeftSideOfAccess(expression); node.typeArguments = asNodeArray(typeArguments); node.arguments = parenthesizerRules().parenthesizeExpressionsOfCommaDelimitedList(createNodeArray(argumentsArray)); @@ -2481,20 +2117,20 @@ namespace ts { propagateChildrenFlags(node.typeArguments) | propagateChildrenFlags(node.arguments); if (node.typeArguments) { - node.transformFlags |= TransformFlags.ContainsTypeScript; + node.transformFlags |= ts.TransformFlags.ContainsTypeScript; } - if (isImportKeyword(node.expression)) { - node.transformFlags |= TransformFlags.ContainsDynamicImport; + if (ts.isImportKeyword(node.expression)) { + node.transformFlags |= ts.TransformFlags.ContainsDynamicImport; } - else if (isSuperProperty(node.expression)) { - node.transformFlags |= TransformFlags.ContainsLexicalThis; + else if (ts.isSuperProperty(node.expression)) { + node.transformFlags |= ts.TransformFlags.ContainsLexicalThis; } return node; } // @api - function updateCallExpression(node: CallExpression, expression: Expression, typeArguments: readonly TypeNode[] | undefined, argumentsArray: readonly Expression[]) { - if (isCallChain(node)) { + function updateCallExpression(node: ts.CallExpression, expression: ts.Expression, typeArguments: readonly ts.TypeNode[] | undefined, argumentsArray: readonly ts.Expression[]) { + if (ts.isCallChain(node)) { return updateCallChain(node, expression, node.questionDotToken, typeArguments, argumentsArray); } return node.expression !== expression @@ -2505,9 +2141,9 @@ namespace ts { } // @api - function createCallChain(expression: Expression, questionDotToken: QuestionDotToken | undefined, typeArguments: readonly TypeNode[] | undefined, argumentsArray: readonly Expression[] | undefined) { - const node = createBaseExpression(SyntaxKind.CallExpression); - node.flags |= NodeFlags.OptionalChain; + function createCallChain(expression: ts.Expression, questionDotToken: ts.QuestionDotToken | undefined, typeArguments: readonly ts.TypeNode[] | undefined, argumentsArray: readonly ts.Expression[] | undefined) { + const node = createBaseExpression(ts.SyntaxKind.CallExpression); + node.flags |= ts.NodeFlags.OptionalChain; node.expression = parenthesizerRules().parenthesizeLeftSideOfAccess(expression); node.questionDotToken = questionDotToken; node.typeArguments = asNodeArray(typeArguments); @@ -2517,19 +2153,19 @@ namespace ts { propagateChildFlags(node.questionDotToken) | propagateChildrenFlags(node.typeArguments) | propagateChildrenFlags(node.arguments) | - TransformFlags.ContainsES2020; + ts.TransformFlags.ContainsES2020; if (node.typeArguments) { - node.transformFlags |= TransformFlags.ContainsTypeScript; + node.transformFlags |= ts.TransformFlags.ContainsTypeScript; } - if (isSuperProperty(node.expression)) { - node.transformFlags |= TransformFlags.ContainsLexicalThis; + if (ts.isSuperProperty(node.expression)) { + node.transformFlags |= ts.TransformFlags.ContainsLexicalThis; } return node; } // @api - function updateCallChain(node: CallChain, expression: Expression, questionDotToken: QuestionDotToken | undefined, typeArguments: readonly TypeNode[] | undefined, argumentsArray: readonly Expression[]) { - Debug.assert(!!(node.flags & NodeFlags.OptionalChain), "Cannot update a CallExpression using updateCallChain. Use updateCall instead."); + function updateCallChain(node: ts.CallChain, expression: ts.Expression, questionDotToken: ts.QuestionDotToken | undefined, typeArguments: readonly ts.TypeNode[] | undefined, argumentsArray: readonly ts.Expression[]) { + ts.Debug.assert(!!(node.flags & ts.NodeFlags.OptionalChain), "Cannot update a CallExpression using updateCallChain. Use updateCall instead."); return node.expression !== expression || node.questionDotToken !== questionDotToken || node.typeArguments !== typeArguments @@ -2539,8 +2175,8 @@ namespace ts { } // @api - function createNewExpression(expression: Expression, typeArguments: readonly TypeNode[] | undefined, argumentsArray: readonly Expression[] | undefined) { - const node = createBaseExpression(SyntaxKind.NewExpression); + function createNewExpression(expression: ts.Expression, typeArguments: readonly ts.TypeNode[] | undefined, argumentsArray: readonly ts.Expression[] | undefined) { + const node = createBaseExpression(ts.SyntaxKind.NewExpression); node.expression = parenthesizerRules().parenthesizeExpressionOfNew(expression); node.typeArguments = asNodeArray(typeArguments); node.arguments = argumentsArray ? parenthesizerRules().parenthesizeExpressionsOfCommaDelimitedList(argumentsArray) : undefined; @@ -2548,15 +2184,15 @@ namespace ts { propagateChildFlags(node.expression) | propagateChildrenFlags(node.typeArguments) | propagateChildrenFlags(node.arguments) | - TransformFlags.ContainsES2020; + ts.TransformFlags.ContainsES2020; if (node.typeArguments) { - node.transformFlags |= TransformFlags.ContainsTypeScript; + node.transformFlags |= ts.TransformFlags.ContainsTypeScript; } return node; } // @api - function updateNewExpression(node: NewExpression, expression: Expression, typeArguments: readonly TypeNode[] | undefined, argumentsArray: readonly Expression[] | undefined) { + function updateNewExpression(node: ts.NewExpression, expression: ts.Expression, typeArguments: readonly ts.TypeNode[] | undefined, argumentsArray: readonly ts.Expression[] | undefined) { return node.expression !== expression || node.typeArguments !== typeArguments || node.arguments !== argumentsArray @@ -2565,8 +2201,8 @@ namespace ts { } // @api - function createTaggedTemplateExpression(tag: Expression, typeArguments: readonly TypeNode[] | undefined, template: TemplateLiteral) { - const node = createBaseExpression(SyntaxKind.TaggedTemplateExpression); + function createTaggedTemplateExpression(tag: ts.Expression, typeArguments: readonly ts.TypeNode[] | undefined, template: ts.TemplateLiteral) { + const node = createBaseExpression(ts.SyntaxKind.TaggedTemplateExpression); node.tag = parenthesizerRules().parenthesizeLeftSideOfAccess(tag); node.typeArguments = asNodeArray(typeArguments); node.template = template; @@ -2574,18 +2210,18 @@ namespace ts { propagateChildFlags(node.tag) | propagateChildrenFlags(node.typeArguments) | propagateChildFlags(node.template) | - TransformFlags.ContainsES2015; + ts.TransformFlags.ContainsES2015; if (node.typeArguments) { - node.transformFlags |= TransformFlags.ContainsTypeScript; + node.transformFlags |= ts.TransformFlags.ContainsTypeScript; } - if (hasInvalidEscape(node.template)) { - node.transformFlags |= TransformFlags.ContainsES2018; + if (ts.hasInvalidEscape(node.template)) { + node.transformFlags |= ts.TransformFlags.ContainsES2018; } return node; } // @api - function updateTaggedTemplateExpression(node: TaggedTemplateExpression, tag: Expression, typeArguments: readonly TypeNode[] | undefined, template: TemplateLiteral) { + function updateTaggedTemplateExpression(node: ts.TaggedTemplateExpression, tag: ts.Expression, typeArguments: readonly ts.TypeNode[] | undefined, template: ts.TemplateLiteral) { return node.tag !== tag || node.typeArguments !== typeArguments || node.template !== template @@ -2594,19 +2230,19 @@ namespace ts { } // @api - function createTypeAssertion(type: TypeNode, expression: Expression) { - const node = createBaseExpression(SyntaxKind.TypeAssertionExpression); + function createTypeAssertion(type: ts.TypeNode, expression: ts.Expression) { + const node = createBaseExpression(ts.SyntaxKind.TypeAssertionExpression); node.expression = parenthesizerRules().parenthesizeOperandOfPrefixUnary(expression); node.type = type; node.transformFlags |= propagateChildFlags(node.expression) | propagateChildFlags(node.type) | - TransformFlags.ContainsTypeScript; + ts.TransformFlags.ContainsTypeScript; return node; } // @api - function updateTypeAssertion(node: TypeAssertion, type: TypeNode, expression: Expression) { + function updateTypeAssertion(node: ts.TypeAssertion, type: ts.TypeNode, expression: ts.Expression) { return node.type !== type || node.expression !== expression ? update(createTypeAssertion(type, expression), node) @@ -2614,70 +2250,45 @@ namespace ts { } // @api - function createParenthesizedExpression(expression: Expression) { - const node = createBaseExpression(SyntaxKind.ParenthesizedExpression); + function createParenthesizedExpression(expression: ts.Expression) { + const node = createBaseExpression(ts.SyntaxKind.ParenthesizedExpression); node.expression = expression; node.transformFlags = propagateChildFlags(node.expression); return node; } // @api - function updateParenthesizedExpression(node: ParenthesizedExpression, expression: Expression) { + function updateParenthesizedExpression(node: ts.ParenthesizedExpression, expression: ts.Expression) { return node.expression !== expression ? update(createParenthesizedExpression(expression), node) : node; } // @api - function createFunctionExpression( - modifiers: readonly Modifier[] | undefined, - asteriskToken: AsteriskToken | undefined, - name: string | Identifier | undefined, - typeParameters: readonly TypeParameterDeclaration[] | undefined, - parameters: readonly ParameterDeclaration[] | undefined, - type: TypeNode | undefined, - body: Block - ) { - const node = createBaseFunctionLikeDeclaration( - SyntaxKind.FunctionExpression, - /*decorators*/ undefined, - modifiers, - name, - typeParameters, - parameters, - type, - body - ); + function createFunctionExpression(modifiers: readonly ts.Modifier[] | undefined, asteriskToken: ts.AsteriskToken | undefined, name: string | ts.Identifier | undefined, typeParameters: readonly ts.TypeParameterDeclaration[] | undefined, parameters: readonly ts.ParameterDeclaration[] | undefined, type: ts.TypeNode | undefined, body: ts.Block) { + const node = createBaseFunctionLikeDeclaration(ts.SyntaxKind.FunctionExpression, + /*decorators*/ undefined, modifiers, name, typeParameters, parameters, type, body); node.asteriskToken = asteriskToken; node.transformFlags |= propagateChildFlags(node.asteriskToken); if (node.typeParameters) { - node.transformFlags |= TransformFlags.ContainsTypeScript; + node.transformFlags |= ts.TransformFlags.ContainsTypeScript; } - if (modifiersToFlags(node.modifiers) & ModifierFlags.Async) { + if (ts.modifiersToFlags(node.modifiers) & ts.ModifierFlags.Async) { if (node.asteriskToken) { - node.transformFlags |= TransformFlags.ContainsES2018; + node.transformFlags |= ts.TransformFlags.ContainsES2018; } else { - node.transformFlags |= TransformFlags.ContainsES2017; + node.transformFlags |= ts.TransformFlags.ContainsES2017; } } else if (node.asteriskToken) { - node.transformFlags |= TransformFlags.ContainsGenerator; + node.transformFlags |= ts.TransformFlags.ContainsGenerator; } return node; } // @api - function updateFunctionExpression( - node: FunctionExpression, - modifiers: readonly Modifier[] | undefined, - asteriskToken: AsteriskToken | undefined, - name: Identifier | undefined, - typeParameters: readonly TypeParameterDeclaration[] | undefined, - parameters: readonly ParameterDeclaration[], - type: TypeNode | undefined, - body: Block - ) { + function updateFunctionExpression(node: ts.FunctionExpression, modifiers: readonly ts.Modifier[] | undefined, asteriskToken: ts.AsteriskToken | undefined, name: ts.Identifier | undefined, typeParameters: readonly ts.TypeParameterDeclaration[] | undefined, parameters: readonly ts.ParameterDeclaration[], type: ts.TypeNode | undefined, body: ts.Block) { return node.name !== name || node.modifiers !== modifiers || node.asteriskToken !== asteriskToken @@ -2690,44 +2301,22 @@ namespace ts { } // @api - function createArrowFunction( - modifiers: readonly Modifier[] | undefined, - typeParameters: readonly TypeParameterDeclaration[] | undefined, - parameters: readonly ParameterDeclaration[], - type: TypeNode | undefined, - equalsGreaterThanToken: EqualsGreaterThanToken | undefined, - body: ConciseBody - ) { - const node = createBaseFunctionLikeDeclaration( - SyntaxKind.ArrowFunction, - /*decorators*/ undefined, - modifiers, - /*name*/ undefined, - typeParameters, - parameters, - type, - parenthesizerRules().parenthesizeConciseBodyOfArrowFunction(body) - ); - node.equalsGreaterThanToken = equalsGreaterThanToken ?? createToken(SyntaxKind.EqualsGreaterThanToken); + function createArrowFunction(modifiers: readonly ts.Modifier[] | undefined, typeParameters: readonly ts.TypeParameterDeclaration[] | undefined, parameters: readonly ts.ParameterDeclaration[], type: ts.TypeNode | undefined, equalsGreaterThanToken: ts.EqualsGreaterThanToken | undefined, body: ts.ConciseBody) { + const node = createBaseFunctionLikeDeclaration(ts.SyntaxKind.ArrowFunction, + /*decorators*/ undefined, modifiers, + /*name*/ undefined, typeParameters, parameters, type, parenthesizerRules().parenthesizeConciseBodyOfArrowFunction(body)); + node.equalsGreaterThanToken = equalsGreaterThanToken ?? createToken(ts.SyntaxKind.EqualsGreaterThanToken); node.transformFlags |= propagateChildFlags(node.equalsGreaterThanToken) | - TransformFlags.ContainsES2015; - if (modifiersToFlags(node.modifiers) & ModifierFlags.Async) { - node.transformFlags |= TransformFlags.ContainsES2017 | TransformFlags.ContainsLexicalThis; + ts.TransformFlags.ContainsES2015; + if (ts.modifiersToFlags(node.modifiers) & ts.ModifierFlags.Async) { + node.transformFlags |= ts.TransformFlags.ContainsES2017 | ts.TransformFlags.ContainsLexicalThis; } return node; } // @api - function updateArrowFunction( - node: ArrowFunction, - modifiers: readonly Modifier[] | undefined, - typeParameters: readonly TypeParameterDeclaration[] | undefined, - parameters: readonly ParameterDeclaration[], - type: TypeNode | undefined, - equalsGreaterThanToken: EqualsGreaterThanToken, - body: ConciseBody - ): ArrowFunction { + function updateArrowFunction(node: ts.ArrowFunction, modifiers: readonly ts.Modifier[] | undefined, typeParameters: readonly ts.TypeParameterDeclaration[] | undefined, parameters: readonly ts.ParameterDeclaration[], type: ts.TypeNode | undefined, equalsGreaterThanToken: ts.EqualsGreaterThanToken, body: ts.ConciseBody): ts.ArrowFunction { return node.modifiers !== modifiers || node.typeParameters !== typeParameters || node.parameters !== parameters @@ -2739,119 +2328,119 @@ namespace ts { } // @api - function createDeleteExpression(expression: Expression) { - const node = createBaseExpression(SyntaxKind.DeleteExpression); + function createDeleteExpression(expression: ts.Expression) { + const node = createBaseExpression(ts.SyntaxKind.DeleteExpression); node.expression = parenthesizerRules().parenthesizeOperandOfPrefixUnary(expression); node.transformFlags |= propagateChildFlags(node.expression); return node; } // @api - function updateDeleteExpression(node: DeleteExpression, expression: Expression) { + function updateDeleteExpression(node: ts.DeleteExpression, expression: ts.Expression) { return node.expression !== expression ? update(createDeleteExpression(expression), node) : node; } // @api - function createTypeOfExpression(expression: Expression) { - const node = createBaseExpression(SyntaxKind.TypeOfExpression); + function createTypeOfExpression(expression: ts.Expression) { + const node = createBaseExpression(ts.SyntaxKind.TypeOfExpression); node.expression = parenthesizerRules().parenthesizeOperandOfPrefixUnary(expression); node.transformFlags |= propagateChildFlags(node.expression); return node; } // @api - function updateTypeOfExpression(node: TypeOfExpression, expression: Expression) { + function updateTypeOfExpression(node: ts.TypeOfExpression, expression: ts.Expression) { return node.expression !== expression ? update(createTypeOfExpression(expression), node) : node; } // @api - function createVoidExpression(expression: Expression) { - const node = createBaseExpression(SyntaxKind.VoidExpression); + function createVoidExpression(expression: ts.Expression) { + const node = createBaseExpression(ts.SyntaxKind.VoidExpression); node.expression = parenthesizerRules().parenthesizeOperandOfPrefixUnary(expression); node.transformFlags |= propagateChildFlags(node.expression); return node; } // @api - function updateVoidExpression(node: VoidExpression, expression: Expression) { + function updateVoidExpression(node: ts.VoidExpression, expression: ts.Expression) { return node.expression !== expression ? update(createVoidExpression(expression), node) : node; } // @api - function createAwaitExpression(expression: Expression) { - const node = createBaseExpression(SyntaxKind.AwaitExpression); + function createAwaitExpression(expression: ts.Expression) { + const node = createBaseExpression(ts.SyntaxKind.AwaitExpression); node.expression = parenthesizerRules().parenthesizeOperandOfPrefixUnary(expression); node.transformFlags |= propagateChildFlags(node.expression) | - TransformFlags.ContainsES2017 | - TransformFlags.ContainsES2018 | - TransformFlags.ContainsAwait; + ts.TransformFlags.ContainsES2017 | + ts.TransformFlags.ContainsES2018 | + ts.TransformFlags.ContainsAwait; return node; } // @api - function updateAwaitExpression(node: AwaitExpression, expression: Expression) { + function updateAwaitExpression(node: ts.AwaitExpression, expression: ts.Expression) { return node.expression !== expression ? update(createAwaitExpression(expression), node) : node; } // @api - function createPrefixUnaryExpression(operator: PrefixUnaryOperator, operand: Expression) { - const node = createBaseExpression(SyntaxKind.PrefixUnaryExpression); + function createPrefixUnaryExpression(operator: ts.PrefixUnaryOperator, operand: ts.Expression) { + const node = createBaseExpression(ts.SyntaxKind.PrefixUnaryExpression); node.operator = operator; node.operand = parenthesizerRules().parenthesizeOperandOfPrefixUnary(operand); node.transformFlags |= propagateChildFlags(node.operand); // Only set this flag for non-generated identifiers and non-"local" names. See the // comment in `visitPreOrPostfixUnaryExpression` in module.ts - if ((operator === SyntaxKind.PlusPlusToken || operator === SyntaxKind.MinusMinusToken) && - isIdentifier(node.operand) && - !isGeneratedIdentifier(node.operand) && - !isLocalName(node.operand)) { - node.transformFlags |= TransformFlags.ContainsUpdateExpressionForIdentifier; + if ((operator === ts.SyntaxKind.PlusPlusToken || operator === ts.SyntaxKind.MinusMinusToken) && + ts.isIdentifier(node.operand) && + !ts.isGeneratedIdentifier(node.operand) && + !ts.isLocalName(node.operand)) { + node.transformFlags |= ts.TransformFlags.ContainsUpdateExpressionForIdentifier; } return node; } // @api - function updatePrefixUnaryExpression(node: PrefixUnaryExpression, operand: Expression) { + function updatePrefixUnaryExpression(node: ts.PrefixUnaryExpression, operand: ts.Expression) { return node.operand !== operand ? update(createPrefixUnaryExpression(node.operator, operand), node) : node; } // @api - function createPostfixUnaryExpression(operand: Expression, operator: PostfixUnaryOperator) { - const node = createBaseExpression(SyntaxKind.PostfixUnaryExpression); + function createPostfixUnaryExpression(operand: ts.Expression, operator: ts.PostfixUnaryOperator) { + const node = createBaseExpression(ts.SyntaxKind.PostfixUnaryExpression); node.operator = operator; node.operand = parenthesizerRules().parenthesizeOperandOfPostfixUnary(operand); node.transformFlags |= propagateChildFlags(node.operand); // Only set this flag for non-generated identifiers and non-"local" names. See the // comment in `visitPreOrPostfixUnaryExpression` in module.ts - if (isIdentifier(node.operand) && - !isGeneratedIdentifier(node.operand) && - !isLocalName(node.operand)) { - node.transformFlags |= TransformFlags.ContainsUpdateExpressionForIdentifier; + if (ts.isIdentifier(node.operand) && + !ts.isGeneratedIdentifier(node.operand) && + !ts.isLocalName(node.operand)) { + node.transformFlags |= ts.TransformFlags.ContainsUpdateExpressionForIdentifier; } return node; } // @api - function updatePostfixUnaryExpression(node: PostfixUnaryExpression, operand: Expression) { + function updatePostfixUnaryExpression(node: ts.PostfixUnaryExpression, operand: ts.Expression) { return node.operand !== operand ? update(createPostfixUnaryExpression(operand, node.operator), node) : node; } // @api - function createBinaryExpression(left: Expression, operator: BinaryOperator | BinaryOperatorToken, right: Expression) { - const node = createBaseExpression(SyntaxKind.BinaryExpression); + function createBinaryExpression(left: ts.Expression, operator: ts.BinaryOperator | ts.BinaryOperatorToken, right: ts.Expression) { + const node = createBaseExpression(ts.SyntaxKind.BinaryExpression); const operatorToken = asToken(operator); const operatorKind = operatorToken.kind; node.left = parenthesizerRules().parenthesizeLeftSideOfBinary(operatorKind, left); @@ -2861,56 +2450,58 @@ namespace ts { propagateChildFlags(node.left) | propagateChildFlags(node.operatorToken) | propagateChildFlags(node.right); - if (operatorKind === SyntaxKind.QuestionQuestionToken) { - node.transformFlags |= TransformFlags.ContainsES2020; + if (operatorKind === ts.SyntaxKind.QuestionQuestionToken) { + node.transformFlags |= ts.TransformFlags.ContainsES2020; } - else if (operatorKind === SyntaxKind.EqualsToken) { - if (isObjectLiteralExpression(node.left)) { + else if (operatorKind === ts.SyntaxKind.EqualsToken) { + if (ts.isObjectLiteralExpression(node.left)) { node.transformFlags |= - TransformFlags.ContainsES2015 | - TransformFlags.ContainsES2018 | - TransformFlags.ContainsDestructuringAssignment | + ts.TransformFlags.ContainsES2015 | + ts.TransformFlags.ContainsES2018 | + ts.TransformFlags.ContainsDestructuringAssignment | propagateAssignmentPatternFlags(node.left); } - else if (isArrayLiteralExpression(node.left)) { + else if (ts.isArrayLiteralExpression(node.left)) { node.transformFlags |= - TransformFlags.ContainsES2015 | - TransformFlags.ContainsDestructuringAssignment | + ts.TransformFlags.ContainsES2015 | + ts.TransformFlags.ContainsDestructuringAssignment | propagateAssignmentPatternFlags(node.left); } } - else if (operatorKind === SyntaxKind.AsteriskAsteriskToken || operatorKind === SyntaxKind.AsteriskAsteriskEqualsToken) { - node.transformFlags |= TransformFlags.ContainsES2016; + else if (operatorKind === ts.SyntaxKind.AsteriskAsteriskToken || operatorKind === ts.SyntaxKind.AsteriskAsteriskEqualsToken) { + node.transformFlags |= ts.TransformFlags.ContainsES2016; } - else if (isLogicalOrCoalescingAssignmentOperator(operatorKind)) { - node.transformFlags |= TransformFlags.ContainsES2021; + else if (ts.isLogicalOrCoalescingAssignmentOperator(operatorKind)) { + node.transformFlags |= ts.TransformFlags.ContainsES2021; } return node; } - function propagateAssignmentPatternFlags(node: AssignmentPattern): TransformFlags { - if (node.transformFlags & TransformFlags.ContainsObjectRestOrSpread) return TransformFlags.ContainsObjectRestOrSpread; - if (node.transformFlags & TransformFlags.ContainsES2018) { + function propagateAssignmentPatternFlags(node: ts.AssignmentPattern): ts.TransformFlags { + if (node.transformFlags & ts.TransformFlags.ContainsObjectRestOrSpread) + return ts.TransformFlags.ContainsObjectRestOrSpread; + if (node.transformFlags & ts.TransformFlags.ContainsES2018) { // check for nested spread assignments, otherwise '{ x: { a, ...b } = foo } = c' // will not be correctly interpreted by the ES2018 transformer - for (const element of getElementsOfBindingOrAssignmentPattern(node)) { - const target = getTargetOfBindingOrAssignmentElement(element); - if (target && isAssignmentPattern(target)) { - if (target.transformFlags & TransformFlags.ContainsObjectRestOrSpread) { - return TransformFlags.ContainsObjectRestOrSpread; + for (const element of ts.getElementsOfBindingOrAssignmentPattern(node)) { + const target = ts.getTargetOfBindingOrAssignmentElement(element); + if (target && ts.isAssignmentPattern(target)) { + if (target.transformFlags & ts.TransformFlags.ContainsObjectRestOrSpread) { + return ts.TransformFlags.ContainsObjectRestOrSpread; } - if (target.transformFlags & TransformFlags.ContainsES2018) { + if (target.transformFlags & ts.TransformFlags.ContainsES2018) { const flags = propagateAssignmentPatternFlags(target); - if (flags) return flags; + if (flags) + return flags; } } } } - return TransformFlags.None; + return ts.TransformFlags.None; } // @api - function updateBinaryExpression(node: BinaryExpression, left: Expression, operator: BinaryOperatorToken, right: Expression) { + function updateBinaryExpression(node: ts.BinaryExpression, left: ts.Expression, operator: ts.BinaryOperatorToken, right: ts.Expression) { return node.left !== left || node.operatorToken !== operator || node.right !== right @@ -2919,12 +2510,12 @@ namespace ts { } // @api - function createConditionalExpression(condition: Expression, questionToken: QuestionToken | undefined, whenTrue: Expression, colonToken: ColonToken | undefined, whenFalse: Expression) { - const node = createBaseExpression(SyntaxKind.ConditionalExpression); + function createConditionalExpression(condition: ts.Expression, questionToken: ts.QuestionToken | undefined, whenTrue: ts.Expression, colonToken: ts.ColonToken | undefined, whenFalse: ts.Expression) { + const node = createBaseExpression(ts.SyntaxKind.ConditionalExpression); node.condition = parenthesizerRules().parenthesizeConditionOfConditionalExpression(condition); - node.questionToken = questionToken ?? createToken(SyntaxKind.QuestionToken); + node.questionToken = questionToken ?? createToken(ts.SyntaxKind.QuestionToken); node.whenTrue = parenthesizerRules().parenthesizeBranchOfConditionalExpression(whenTrue); - node.colonToken = colonToken ?? createToken(SyntaxKind.ColonToken); + node.colonToken = colonToken ?? createToken(ts.SyntaxKind.ColonToken); node.whenFalse = parenthesizerRules().parenthesizeBranchOfConditionalExpression(whenFalse); node.transformFlags |= propagateChildFlags(node.condition) | @@ -2936,14 +2527,7 @@ namespace ts { } // @api - function updateConditionalExpression( - node: ConditionalExpression, - condition: Expression, - questionToken: Token, - whenTrue: Expression, - colonToken: Token, - whenFalse: Expression - ): ConditionalExpression { + function updateConditionalExpression(node: ts.ConditionalExpression, condition: ts.Expression, questionToken: ts.Token, whenTrue: ts.Expression, colonToken: ts.Token, whenFalse: ts.Expression): ts.ConditionalExpression { return node.condition !== condition || node.questionToken !== questionToken || node.whenTrue !== whenTrue @@ -2954,98 +2538,98 @@ namespace ts { } // @api - function createTemplateExpression(head: TemplateHead, templateSpans: readonly TemplateSpan[]) { - const node = createBaseExpression(SyntaxKind.TemplateExpression); + function createTemplateExpression(head: ts.TemplateHead, templateSpans: readonly ts.TemplateSpan[]) { + const node = createBaseExpression(ts.SyntaxKind.TemplateExpression); node.head = head; node.templateSpans = createNodeArray(templateSpans); node.transformFlags |= propagateChildFlags(node.head) | propagateChildrenFlags(node.templateSpans) | - TransformFlags.ContainsES2015; + ts.TransformFlags.ContainsES2015; return node; } // @api - function updateTemplateExpression(node: TemplateExpression, head: TemplateHead, templateSpans: readonly TemplateSpan[]) { + function updateTemplateExpression(node: ts.TemplateExpression, head: ts.TemplateHead, templateSpans: readonly ts.TemplateSpan[]) { return node.head !== head || node.templateSpans !== templateSpans ? update(createTemplateExpression(head, templateSpans), node) : node; } - function createTemplateLiteralLikeNodeChecked(kind: TemplateLiteralToken["kind"], text: string | undefined, rawText: string | undefined, templateFlags = TokenFlags.None) { - Debug.assert(!(templateFlags & ~TokenFlags.TemplateLiteralLikeFlags), "Unsupported template flags."); + function createTemplateLiteralLikeNodeChecked(kind: ts.TemplateLiteralToken["kind"], text: string | undefined, rawText: string | undefined, templateFlags = ts.TokenFlags.None) { + ts.Debug.assert(!(templateFlags & ~ts.TokenFlags.TemplateLiteralLikeFlags), "Unsupported template flags."); // NOTE: without the assignment to `undefined`, we don't narrow the initial type of `cooked`. // eslint-disable-next-line no-undef-init let cooked: string | object | undefined = undefined; if (rawText !== undefined && rawText !== text) { cooked = getCookedText(kind, rawText); if (typeof cooked === "object") { - return Debug.fail("Invalid raw text"); + return ts.Debug.fail("Invalid raw text"); } } if (text === undefined) { if (cooked === undefined) { - return Debug.fail("Arguments 'text' and 'rawText' may not both be undefined."); + return ts.Debug.fail("Arguments 'text' and 'rawText' may not both be undefined."); } text = cooked; } else if (cooked !== undefined) { - Debug.assert(text === cooked, "Expected argument 'text' to be the normalized (i.e. 'cooked') version of argument 'rawText'."); + ts.Debug.assert(text === cooked, "Expected argument 'text' to be the normalized (i.e. 'cooked') version of argument 'rawText'."); } return createTemplateLiteralLikeNode(kind, text, rawText, templateFlags); } // @api - function createTemplateLiteralLikeNode(kind: TemplateLiteralToken["kind"], text: string, rawText: string | undefined, templateFlags: TokenFlags | undefined) { - const node = createBaseToken(kind); + function createTemplateLiteralLikeNode(kind: ts.TemplateLiteralToken["kind"], text: string, rawText: string | undefined, templateFlags: ts.TokenFlags | undefined) { + const node = createBaseToken(kind); node.text = text; node.rawText = rawText; - node.templateFlags = templateFlags! & TokenFlags.TemplateLiteralLikeFlags; - node.transformFlags |= TransformFlags.ContainsES2015; + node.templateFlags = templateFlags! & ts.TokenFlags.TemplateLiteralLikeFlags; + node.transformFlags |= ts.TransformFlags.ContainsES2015; if (node.templateFlags) { - node.transformFlags |= TransformFlags.ContainsES2018; + node.transformFlags |= ts.TransformFlags.ContainsES2018; } return node; } // @api - function createTemplateHead(text: string | undefined, rawText?: string, templateFlags?: TokenFlags) { - return createTemplateLiteralLikeNodeChecked(SyntaxKind.TemplateHead, text, rawText, templateFlags) as TemplateHead; + function createTemplateHead(text: string | undefined, rawText?: string, templateFlags?: ts.TokenFlags) { + return createTemplateLiteralLikeNodeChecked(ts.SyntaxKind.TemplateHead, text, rawText, templateFlags) as ts.TemplateHead; } // @api - function createTemplateMiddle(text: string | undefined, rawText?: string, templateFlags?: TokenFlags) { - return createTemplateLiteralLikeNodeChecked(SyntaxKind.TemplateMiddle, text, rawText, templateFlags) as TemplateMiddle; + function createTemplateMiddle(text: string | undefined, rawText?: string, templateFlags?: ts.TokenFlags) { + return createTemplateLiteralLikeNodeChecked(ts.SyntaxKind.TemplateMiddle, text, rawText, templateFlags) as ts.TemplateMiddle; } // @api - function createTemplateTail(text: string | undefined, rawText?: string, templateFlags?: TokenFlags) { - return createTemplateLiteralLikeNodeChecked(SyntaxKind.TemplateTail, text, rawText, templateFlags) as TemplateTail; + function createTemplateTail(text: string | undefined, rawText?: string, templateFlags?: ts.TokenFlags) { + return createTemplateLiteralLikeNodeChecked(ts.SyntaxKind.TemplateTail, text, rawText, templateFlags) as ts.TemplateTail; } // @api - function createNoSubstitutionTemplateLiteral(text: string | undefined, rawText?: string, templateFlags?: TokenFlags) { - return createTemplateLiteralLikeNodeChecked(SyntaxKind.NoSubstitutionTemplateLiteral, text, rawText, templateFlags) as NoSubstitutionTemplateLiteral; + function createNoSubstitutionTemplateLiteral(text: string | undefined, rawText?: string, templateFlags?: ts.TokenFlags) { + return createTemplateLiteralLikeNodeChecked(ts.SyntaxKind.NoSubstitutionTemplateLiteral, text, rawText, templateFlags) as ts.NoSubstitutionTemplateLiteral; } // @api - function createYieldExpression(asteriskToken: AsteriskToken | undefined, expression: Expression | undefined): YieldExpression { - Debug.assert(!asteriskToken || !!expression, "A `YieldExpression` with an asteriskToken must have an expression."); - const node = createBaseExpression(SyntaxKind.YieldExpression); + function createYieldExpression(asteriskToken: ts.AsteriskToken | undefined, expression: ts.Expression | undefined): ts.YieldExpression { + ts.Debug.assert(!asteriskToken || !!expression, "A `YieldExpression` with an asteriskToken must have an expression."); + const node = createBaseExpression(ts.SyntaxKind.YieldExpression); node.expression = expression && parenthesizerRules().parenthesizeExpressionForDisallowedComma(expression); node.asteriskToken = asteriskToken; node.transformFlags |= propagateChildFlags(node.expression) | propagateChildFlags(node.asteriskToken) | - TransformFlags.ContainsES2015 | - TransformFlags.ContainsES2018 | - TransformFlags.ContainsYield; + ts.TransformFlags.ContainsES2015 | + ts.TransformFlags.ContainsES2018 | + ts.TransformFlags.ContainsYield; return node; } // @api - function updateYieldExpression(node: YieldExpression, asteriskToken: AsteriskToken | undefined, expression: Expression) { + function updateYieldExpression(node: ts.YieldExpression, asteriskToken: ts.AsteriskToken | undefined, expression: ts.Expression) { return node.expression !== expression || node.asteriskToken !== asteriskToken ? update(createYieldExpression(asteriskToken, expression), node) @@ -3053,55 +2637,31 @@ namespace ts { } // @api - function createSpreadElement(expression: Expression) { - const node = createBaseExpression(SyntaxKind.SpreadElement); + function createSpreadElement(expression: ts.Expression) { + const node = createBaseExpression(ts.SyntaxKind.SpreadElement); node.expression = parenthesizerRules().parenthesizeExpressionForDisallowedComma(expression); node.transformFlags |= propagateChildFlags(node.expression) | - TransformFlags.ContainsES2015 | - TransformFlags.ContainsRestOrSpread; + ts.TransformFlags.ContainsES2015 | + ts.TransformFlags.ContainsRestOrSpread; return node; } // @api - function updateSpreadElement(node: SpreadElement, expression: Expression) { + function updateSpreadElement(node: ts.SpreadElement, expression: ts.Expression) { return node.expression !== expression ? update(createSpreadElement(expression), node) : node; } // @api - function createClassExpression( - decorators: readonly Decorator[] | undefined, - modifiers: readonly Modifier[] | undefined, - name: string | Identifier | undefined, - typeParameters: readonly TypeParameterDeclaration[] | undefined, - heritageClauses: readonly HeritageClause[] | undefined, - members: readonly ClassElement[] - ) { - const node = createBaseClassLikeDeclaration( - SyntaxKind.ClassExpression, - decorators, - modifiers, - name, - typeParameters, - heritageClauses, - members - ); - node.transformFlags |= TransformFlags.ContainsES2015; + function createClassExpression(decorators: readonly ts.Decorator[] | undefined, modifiers: readonly ts.Modifier[] | undefined, name: string | ts.Identifier | undefined, typeParameters: readonly ts.TypeParameterDeclaration[] | undefined, heritageClauses: readonly ts.HeritageClause[] | undefined, members: readonly ts.ClassElement[]) { + const node = createBaseClassLikeDeclaration(ts.SyntaxKind.ClassExpression, decorators, modifiers, name, typeParameters, heritageClauses, members); + node.transformFlags |= ts.TransformFlags.ContainsES2015; return node; } - // @api - function updateClassExpression( - node: ClassExpression, - decorators: readonly Decorator[] | undefined, - modifiers: readonly Modifier[] | undefined, - name: Identifier | undefined, - typeParameters: readonly TypeParameterDeclaration[] | undefined, - heritageClauses: readonly HeritageClause[] | undefined, - members: readonly ClassElement[] - ) { + function updateClassExpression(node: ts.ClassExpression, decorators: readonly ts.Decorator[] | undefined, modifiers: readonly ts.Modifier[] | undefined, name: ts.Identifier | undefined, typeParameters: readonly ts.TypeParameterDeclaration[] | undefined, heritageClauses: readonly ts.HeritageClause[] | undefined, members: readonly ts.ClassElement[]) { return node.decorators !== decorators || node.modifiers !== modifiers || node.name !== name @@ -3114,23 +2674,23 @@ namespace ts { // @api function createOmittedExpression() { - return createBaseExpression(SyntaxKind.OmittedExpression); + return createBaseExpression(ts.SyntaxKind.OmittedExpression); } // @api - function createExpressionWithTypeArguments(expression: Expression, typeArguments: readonly TypeNode[] | undefined) { - const node = createBaseNode(SyntaxKind.ExpressionWithTypeArguments); + function createExpressionWithTypeArguments(expression: ts.Expression, typeArguments: readonly ts.TypeNode[] | undefined) { + const node = createBaseNode(ts.SyntaxKind.ExpressionWithTypeArguments); node.expression = parenthesizerRules().parenthesizeLeftSideOfAccess(expression); node.typeArguments = typeArguments && parenthesizerRules().parenthesizeTypeArguments(typeArguments); node.transformFlags |= propagateChildFlags(node.expression) | propagateChildrenFlags(node.typeArguments) | - TransformFlags.ContainsES2015; + ts.TransformFlags.ContainsES2015; return node; } // @api - function updateExpressionWithTypeArguments(node: ExpressionWithTypeArguments, expression: Expression, typeArguments: readonly TypeNode[] | undefined) { + function updateExpressionWithTypeArguments(node: ts.ExpressionWithTypeArguments, expression: ts.Expression, typeArguments: readonly ts.TypeNode[] | undefined) { return node.expression !== expression || node.typeArguments !== typeArguments ? update(createExpressionWithTypeArguments(expression, typeArguments), node) @@ -3138,19 +2698,19 @@ namespace ts { } // @api - function createAsExpression(expression: Expression, type: TypeNode) { - const node = createBaseExpression(SyntaxKind.AsExpression); + function createAsExpression(expression: ts.Expression, type: ts.TypeNode) { + const node = createBaseExpression(ts.SyntaxKind.AsExpression); node.expression = expression; node.type = type; node.transformFlags |= propagateChildFlags(node.expression) | propagateChildFlags(node.type) | - TransformFlags.ContainsTypeScript; + ts.TransformFlags.ContainsTypeScript; return node; } // @api - function updateAsExpression(node: AsExpression, expression: Expression, type: TypeNode) { + function updateAsExpression(node: ts.AsExpression, expression: ts.Expression, type: ts.TypeNode) { return node.expression !== expression || node.type !== type ? update(createAsExpression(expression, type), node) @@ -3158,18 +2718,18 @@ namespace ts { } // @api - function createNonNullExpression(expression: Expression) { - const node = createBaseExpression(SyntaxKind.NonNullExpression); + function createNonNullExpression(expression: ts.Expression) { + const node = createBaseExpression(ts.SyntaxKind.NonNullExpression); node.expression = parenthesizerRules().parenthesizeLeftSideOfAccess(expression); node.transformFlags |= propagateChildFlags(node.expression) | - TransformFlags.ContainsTypeScript; + ts.TransformFlags.ContainsTypeScript; return node; } // @api - function updateNonNullExpression(node: NonNullExpression, expression: Expression) { - if (isNonNullChain(node)) { + function updateNonNullExpression(node: ts.NonNullExpression, expression: ts.Expression) { + if (ts.isNonNullChain(node)) { return updateNonNullChain(node, expression); } return node.expression !== expression @@ -3178,45 +2738,45 @@ namespace ts { } // @api - function createNonNullChain(expression: Expression) { - const node = createBaseExpression(SyntaxKind.NonNullExpression); - node.flags |= NodeFlags.OptionalChain; + function createNonNullChain(expression: ts.Expression) { + const node = createBaseExpression(ts.SyntaxKind.NonNullExpression); + node.flags |= ts.NodeFlags.OptionalChain; node.expression = parenthesizerRules().parenthesizeLeftSideOfAccess(expression); node.transformFlags |= propagateChildFlags(node.expression) | - TransformFlags.ContainsTypeScript; + ts.TransformFlags.ContainsTypeScript; return node; } // @api - function updateNonNullChain(node: NonNullChain, expression: Expression) { - Debug.assert(!!(node.flags & NodeFlags.OptionalChain), "Cannot update a NonNullExpression using updateNonNullChain. Use updateNonNullExpression instead."); + function updateNonNullChain(node: ts.NonNullChain, expression: ts.Expression) { + ts.Debug.assert(!!(node.flags & ts.NodeFlags.OptionalChain), "Cannot update a NonNullExpression using updateNonNullChain. Use updateNonNullExpression instead."); return node.expression !== expression ? update(createNonNullChain(expression), node) : node; } // @api - function createMetaProperty(keywordToken: MetaProperty["keywordToken"], name: Identifier) { - const node = createBaseExpression(SyntaxKind.MetaProperty); + function createMetaProperty(keywordToken: ts.MetaProperty["keywordToken"], name: ts.Identifier) { + const node = createBaseExpression(ts.SyntaxKind.MetaProperty); node.keywordToken = keywordToken; node.name = name; node.transformFlags |= propagateChildFlags(node.name); switch (keywordToken) { - case SyntaxKind.NewKeyword: - node.transformFlags |= TransformFlags.ContainsES2015; + case ts.SyntaxKind.NewKeyword: + node.transformFlags |= ts.TransformFlags.ContainsES2015; break; - case SyntaxKind.ImportKeyword: - node.transformFlags |= TransformFlags.ContainsESNext; + case ts.SyntaxKind.ImportKeyword: + node.transformFlags |= ts.TransformFlags.ContainsESNext; break; default: - return Debug.assertNever(keywordToken); + return ts.Debug.assertNever(keywordToken); } return node; } // @api - function updateMetaProperty(node: MetaProperty, name: Identifier) { + function updateMetaProperty(node: ts.MetaProperty, name: ts.Identifier) { return node.name !== name ? update(createMetaProperty(node.keywordToken, name), node) : node; @@ -3227,19 +2787,19 @@ namespace ts { // // @api - function createTemplateSpan(expression: Expression, literal: TemplateMiddle | TemplateTail) { - const node = createBaseNode(SyntaxKind.TemplateSpan); + function createTemplateSpan(expression: ts.Expression, literal: ts.TemplateMiddle | ts.TemplateTail) { + const node = createBaseNode(ts.SyntaxKind.TemplateSpan); node.expression = expression; node.literal = literal; node.transformFlags |= propagateChildFlags(node.expression) | propagateChildFlags(node.literal) | - TransformFlags.ContainsES2015; + ts.TransformFlags.ContainsES2015; return node; } // @api - function updateTemplateSpan(node: TemplateSpan, expression: Expression, literal: TemplateMiddle | TemplateTail) { + function updateTemplateSpan(node: ts.TemplateSpan, expression: ts.Expression, literal: ts.TemplateMiddle | ts.TemplateTail) { return node.expression !== expression || node.literal !== literal ? update(createTemplateSpan(expression, literal), node) @@ -3248,8 +2808,8 @@ namespace ts { // @api function createSemicolonClassElement() { - const node = createBaseNode(SyntaxKind.SemicolonClassElement); - node.transformFlags |= TransformFlags.ContainsES2015; + const node = createBaseNode(ts.SyntaxKind.SemicolonClassElement); + node.transformFlags |= ts.TransformFlags.ContainsES2015; return node; } @@ -3258,8 +2818,8 @@ namespace ts { // // @api - function createBlock(statements: readonly Statement[], multiLine?: boolean): Block { - const node = createBaseNode(SyntaxKind.Block); + function createBlock(statements: readonly ts.Statement[], multiLine?: boolean): ts.Block { + const node = createBaseNode(ts.SyntaxKind.Block); node.statements = createNodeArray(statements); node.multiLine = multiLine; node.transformFlags |= propagateChildrenFlags(node.statements); @@ -3267,26 +2827,26 @@ namespace ts { } // @api - function updateBlock(node: Block, statements: readonly Statement[]) { + function updateBlock(node: ts.Block, statements: readonly ts.Statement[]) { return node.statements !== statements ? update(createBlock(statements, node.multiLine), node) : node; } // @api - function createVariableStatement(modifiers: readonly Modifier[] | undefined, declarationList: VariableDeclarationList | readonly VariableDeclaration[]) { - const node = createBaseDeclaration(SyntaxKind.VariableStatement, /*decorators*/ undefined, modifiers); - node.declarationList = isArray(declarationList) ? createVariableDeclarationList(declarationList) : declarationList; + function createVariableStatement(modifiers: readonly ts.Modifier[] | undefined, declarationList: ts.VariableDeclarationList | readonly ts.VariableDeclaration[]) { + const node = createBaseDeclaration(ts.SyntaxKind.VariableStatement, /*decorators*/ undefined, modifiers); + node.declarationList = ts.isArray(declarationList) ? createVariableDeclarationList(declarationList) : declarationList; node.transformFlags |= propagateChildFlags(node.declarationList); - if (modifiersToFlags(node.modifiers) & ModifierFlags.Ambient) { - node.transformFlags = TransformFlags.ContainsTypeScript; + if (ts.modifiersToFlags(node.modifiers) & ts.ModifierFlags.Ambient) { + node.transformFlags = ts.TransformFlags.ContainsTypeScript; } return node; } // @api - function updateVariableStatement(node: VariableStatement, modifiers: readonly Modifier[] | undefined, declarationList: VariableDeclarationList) { + function updateVariableStatement(node: ts.VariableStatement, modifiers: readonly ts.Modifier[] | undefined, declarationList: ts.VariableDeclarationList) { return node.modifiers !== modifiers || node.declarationList !== declarationList ? update(createVariableStatement(modifiers, declarationList), node) @@ -3295,27 +2855,27 @@ namespace ts { // @api function createEmptyStatement() { - return createBaseNode(SyntaxKind.EmptyStatement); + return createBaseNode(ts.SyntaxKind.EmptyStatement); } // @api - function createExpressionStatement(expression: Expression): ExpressionStatement { - const node = createBaseNode(SyntaxKind.ExpressionStatement); + function createExpressionStatement(expression: ts.Expression): ts.ExpressionStatement { + const node = createBaseNode(ts.SyntaxKind.ExpressionStatement); node.expression = parenthesizerRules().parenthesizeExpressionOfExpressionStatement(expression); node.transformFlags |= propagateChildFlags(node.expression); return node; } // @api - function updateExpressionStatement(node: ExpressionStatement, expression: Expression) { + function updateExpressionStatement(node: ts.ExpressionStatement, expression: ts.Expression) { return node.expression !== expression ? update(createExpressionStatement(expression), node) : node; } // @api - function createIfStatement(expression: Expression, thenStatement: Statement, elseStatement?: Statement) { - const node = createBaseNode(SyntaxKind.IfStatement); + function createIfStatement(expression: ts.Expression, thenStatement: ts.Statement, elseStatement?: ts.Statement) { + const node = createBaseNode(ts.SyntaxKind.IfStatement); node.expression = expression; node.thenStatement = asEmbeddedStatement(thenStatement); node.elseStatement = asEmbeddedStatement(elseStatement); @@ -3327,7 +2887,7 @@ namespace ts { } // @api - function updateIfStatement(node: IfStatement, expression: Expression, thenStatement: Statement, elseStatement: Statement | undefined) { + function updateIfStatement(node: ts.IfStatement, expression: ts.Expression, thenStatement: ts.Statement, elseStatement: ts.Statement | undefined) { return node.expression !== expression || node.thenStatement !== thenStatement || node.elseStatement !== elseStatement @@ -3336,8 +2896,8 @@ namespace ts { } // @api - function createDoStatement(statement: Statement, expression: Expression) { - const node = createBaseNode(SyntaxKind.DoStatement); + function createDoStatement(statement: ts.Statement, expression: ts.Expression) { + const node = createBaseNode(ts.SyntaxKind.DoStatement); node.statement = asEmbeddedStatement(statement); node.expression = expression; node.transformFlags |= @@ -3347,7 +2907,7 @@ namespace ts { } // @api - function updateDoStatement(node: DoStatement, statement: Statement, expression: Expression) { + function updateDoStatement(node: ts.DoStatement, statement: ts.Statement, expression: ts.Expression) { return node.statement !== statement || node.expression !== expression ? update(createDoStatement(statement, expression), node) @@ -3355,8 +2915,8 @@ namespace ts { } // @api - function createWhileStatement(expression: Expression, statement: Statement) { - const node = createBaseNode(SyntaxKind.WhileStatement); + function createWhileStatement(expression: ts.Expression, statement: ts.Statement) { + const node = createBaseNode(ts.SyntaxKind.WhileStatement); node.expression = expression; node.statement = asEmbeddedStatement(statement); node.transformFlags |= @@ -3366,7 +2926,7 @@ namespace ts { } // @api - function updateWhileStatement(node: WhileStatement, expression: Expression, statement: Statement) { + function updateWhileStatement(node: ts.WhileStatement, expression: ts.Expression, statement: ts.Statement) { return node.expression !== expression || node.statement !== statement ? update(createWhileStatement(expression, statement), node) @@ -3374,8 +2934,8 @@ namespace ts { } // @api - function createForStatement(initializer: ForInitializer | undefined, condition: Expression | undefined, incrementor: Expression | undefined, statement: Statement) { - const node = createBaseNode(SyntaxKind.ForStatement); + function createForStatement(initializer: ts.ForInitializer | undefined, condition: ts.Expression | undefined, incrementor: ts.Expression | undefined, statement: ts.Statement) { + const node = createBaseNode(ts.SyntaxKind.ForStatement); node.initializer = initializer; node.condition = condition; node.incrementor = incrementor; @@ -3389,7 +2949,7 @@ namespace ts { } // @api - function updateForStatement(node: ForStatement, initializer: ForInitializer | undefined, condition: Expression | undefined, incrementor: Expression | undefined, statement: Statement) { + function updateForStatement(node: ts.ForStatement, initializer: ts.ForInitializer | undefined, condition: ts.Expression | undefined, incrementor: ts.Expression | undefined, statement: ts.Statement) { return node.initializer !== initializer || node.condition !== condition || node.incrementor !== incrementor @@ -3399,8 +2959,8 @@ namespace ts { } // @api - function createForInStatement(initializer: ForInitializer, expression: Expression, statement: Statement) { - const node = createBaseNode(SyntaxKind.ForInStatement); + function createForInStatement(initializer: ts.ForInitializer, expression: ts.Expression, statement: ts.Statement) { + const node = createBaseNode(ts.SyntaxKind.ForInStatement); node.initializer = initializer; node.expression = expression; node.statement = asEmbeddedStatement(statement); @@ -3412,7 +2972,7 @@ namespace ts { } // @api - function updateForInStatement(node: ForInStatement, initializer: ForInitializer, expression: Expression, statement: Statement) { + function updateForInStatement(node: ts.ForInStatement, initializer: ts.ForInitializer, expression: ts.Expression, statement: ts.Statement) { return node.initializer !== initializer || node.expression !== expression || node.statement !== statement @@ -3421,8 +2981,8 @@ namespace ts { } // @api - function createForOfStatement(awaitModifier: AwaitKeyword | undefined, initializer: ForInitializer, expression: Expression, statement: Statement) { - const node = createBaseNode(SyntaxKind.ForOfStatement); + function createForOfStatement(awaitModifier: ts.AwaitKeyword | undefined, initializer: ts.ForInitializer, expression: ts.Expression, statement: ts.Statement) { + const node = createBaseNode(ts.SyntaxKind.ForOfStatement); node.awaitModifier = awaitModifier; node.initializer = initializer; node.expression = parenthesizerRules().parenthesizeExpressionForDisallowedComma(expression); @@ -3432,13 +2992,14 @@ namespace ts { propagateChildFlags(node.initializer) | propagateChildFlags(node.expression) | propagateChildFlags(node.statement) | - TransformFlags.ContainsES2015; - if (awaitModifier) node.transformFlags |= TransformFlags.ContainsES2018; + ts.TransformFlags.ContainsES2015; + if (awaitModifier) + node.transformFlags |= ts.TransformFlags.ContainsES2018; return node; } // @api - function updateForOfStatement(node: ForOfStatement, awaitModifier: AwaitKeyword | undefined, initializer: ForInitializer, expression: Expression, statement: Statement) { + function updateForOfStatement(node: ts.ForOfStatement, awaitModifier: ts.AwaitKeyword | undefined, initializer: ts.ForInitializer, expression: ts.Expression, statement: ts.Statement) { return node.awaitModifier !== awaitModifier || node.initializer !== initializer || node.expression !== expression @@ -3448,61 +3009,61 @@ namespace ts { } // @api - function createContinueStatement(label?: string | Identifier): ContinueStatement { - const node = createBaseNode(SyntaxKind.ContinueStatement); + function createContinueStatement(label?: string | ts.Identifier): ts.ContinueStatement { + const node = createBaseNode(ts.SyntaxKind.ContinueStatement); node.label = asName(label); node.transformFlags |= propagateChildFlags(node.label) | - TransformFlags.ContainsHoistedDeclarationOrCompletion; + ts.TransformFlags.ContainsHoistedDeclarationOrCompletion; return node; } // @api - function updateContinueStatement(node: ContinueStatement, label: Identifier | undefined) { + function updateContinueStatement(node: ts.ContinueStatement, label: ts.Identifier | undefined) { return node.label !== label ? update(createContinueStatement(label), node) : node; } // @api - function createBreakStatement(label?: string | Identifier): BreakStatement { - const node = createBaseNode(SyntaxKind.BreakStatement); + function createBreakStatement(label?: string | ts.Identifier): ts.BreakStatement { + const node = createBaseNode(ts.SyntaxKind.BreakStatement); node.label = asName(label); node.transformFlags |= propagateChildFlags(node.label) | - TransformFlags.ContainsHoistedDeclarationOrCompletion; + ts.TransformFlags.ContainsHoistedDeclarationOrCompletion; return node; } // @api - function updateBreakStatement(node: BreakStatement, label: Identifier | undefined) { + function updateBreakStatement(node: ts.BreakStatement, label: ts.Identifier | undefined) { return node.label !== label ? update(createBreakStatement(label), node) : node; } // @api - function createReturnStatement(expression?: Expression): ReturnStatement { - const node = createBaseNode(SyntaxKind.ReturnStatement); + function createReturnStatement(expression?: ts.Expression): ts.ReturnStatement { + const node = createBaseNode(ts.SyntaxKind.ReturnStatement); node.expression = expression; // return in an ES2018 async generator must be awaited node.transformFlags |= propagateChildFlags(node.expression) | - TransformFlags.ContainsES2018 | - TransformFlags.ContainsHoistedDeclarationOrCompletion; + ts.TransformFlags.ContainsES2018 | + ts.TransformFlags.ContainsHoistedDeclarationOrCompletion; return node; } // @api - function updateReturnStatement(node: ReturnStatement, expression: Expression | undefined) { + function updateReturnStatement(node: ts.ReturnStatement, expression: ts.Expression | undefined) { return node.expression !== expression ? update(createReturnStatement(expression), node) : node; } // @api - function createWithStatement(expression: Expression, statement: Statement) { - const node = createBaseNode(SyntaxKind.WithStatement); + function createWithStatement(expression: ts.Expression, statement: ts.Statement) { + const node = createBaseNode(ts.SyntaxKind.WithStatement); node.expression = expression; node.statement = asEmbeddedStatement(statement); node.transformFlags |= @@ -3512,7 +3073,7 @@ namespace ts { } // @api - function updateWithStatement(node: WithStatement, expression: Expression, statement: Statement) { + function updateWithStatement(node: ts.WithStatement, expression: ts.Expression, statement: ts.Statement) { return node.expression !== expression || node.statement !== statement ? update(createWithStatement(expression, statement), node) @@ -3520,8 +3081,8 @@ namespace ts { } // @api - function createSwitchStatement(expression: Expression, caseBlock: CaseBlock): SwitchStatement { - const node = createBaseNode(SyntaxKind.SwitchStatement); + function createSwitchStatement(expression: ts.Expression, caseBlock: ts.CaseBlock): ts.SwitchStatement { + const node = createBaseNode(ts.SyntaxKind.SwitchStatement); node.expression = parenthesizerRules().parenthesizeExpressionForDisallowedComma(expression); node.caseBlock = caseBlock; node.transformFlags |= @@ -3531,7 +3092,7 @@ namespace ts { } // @api - function updateSwitchStatement(node: SwitchStatement, expression: Expression, caseBlock: CaseBlock) { + function updateSwitchStatement(node: ts.SwitchStatement, expression: ts.Expression, caseBlock: ts.CaseBlock) { return node.expression !== expression || node.caseBlock !== caseBlock ? update(createSwitchStatement(expression, caseBlock), node) @@ -3539,8 +3100,8 @@ namespace ts { } // @api - function createLabeledStatement(label: string | Identifier, statement: Statement) { - const node = createBaseNode(SyntaxKind.LabeledStatement); + function createLabeledStatement(label: string | ts.Identifier, statement: ts.Statement) { + const node = createBaseNode(ts.SyntaxKind.LabeledStatement); node.label = asName(label); node.statement = asEmbeddedStatement(statement); node.transformFlags |= @@ -3550,7 +3111,7 @@ namespace ts { } // @api - function updateLabeledStatement(node: LabeledStatement, label: Identifier, statement: Statement) { + function updateLabeledStatement(node: ts.LabeledStatement, label: ts.Identifier, statement: ts.Statement) { return node.label !== label || node.statement !== statement ? update(createLabeledStatement(label, statement), node) @@ -3558,23 +3119,23 @@ namespace ts { } // @api - function createThrowStatement(expression: Expression) { - const node = createBaseNode(SyntaxKind.ThrowStatement); + function createThrowStatement(expression: ts.Expression) { + const node = createBaseNode(ts.SyntaxKind.ThrowStatement); node.expression = expression; node.transformFlags |= propagateChildFlags(node.expression); return node; } // @api - function updateThrowStatement(node: ThrowStatement, expression: Expression) { + function updateThrowStatement(node: ts.ThrowStatement, expression: ts.Expression) { return node.expression !== expression ? update(createThrowStatement(expression), node) : node; } // @api - function createTryStatement(tryBlock: Block, catchClause: CatchClause | undefined, finallyBlock: Block | undefined) { - const node = createBaseNode(SyntaxKind.TryStatement); + function createTryStatement(tryBlock: ts.Block, catchClause: ts.CatchClause | undefined, finallyBlock: ts.Block | undefined) { + const node = createBaseNode(ts.SyntaxKind.TryStatement); node.tryBlock = tryBlock; node.catchClause = catchClause; node.finallyBlock = finallyBlock; @@ -3586,7 +3147,7 @@ namespace ts { } // @api - function updateTryStatement(node: TryStatement, tryBlock: Block, catchClause: CatchClause | undefined, finallyBlock: Block | undefined) { + function updateTryStatement(node: ts.TryStatement, tryBlock: ts.Block, catchClause: ts.CatchClause | undefined, finallyBlock: ts.Block | undefined) { return node.tryBlock !== tryBlock || node.catchClause !== catchClause || node.finallyBlock !== finallyBlock @@ -3596,29 +3157,24 @@ namespace ts { // @api function createDebuggerStatement() { - return createBaseNode(SyntaxKind.DebuggerStatement); + return createBaseNode(ts.SyntaxKind.DebuggerStatement); } // @api - function createVariableDeclaration(name: string | BindingName, exclamationToken: ExclamationToken | undefined, type: TypeNode | undefined, initializer: Expression | undefined) { - const node = createBaseVariableLikeDeclaration( - SyntaxKind.VariableDeclaration, + function createVariableDeclaration(name: string | ts.BindingName, exclamationToken: ts.ExclamationToken | undefined, type: ts.TypeNode | undefined, initializer: ts.Expression | undefined) { + const node = createBaseVariableLikeDeclaration(ts.SyntaxKind.VariableDeclaration, /*decorators*/ undefined, - /*modifiers*/ undefined, - name, - type, - initializer && parenthesizerRules().parenthesizeExpressionForDisallowedComma(initializer) - ); + /*modifiers*/ undefined, name, type, initializer && parenthesizerRules().parenthesizeExpressionForDisallowedComma(initializer)); node.exclamationToken = exclamationToken; node.transformFlags |= propagateChildFlags(node.exclamationToken); if (exclamationToken) { - node.transformFlags |= TransformFlags.ContainsTypeScript; + node.transformFlags |= ts.TransformFlags.ContainsTypeScript; } return node; } // @api - function updateVariableDeclaration(node: VariableDeclaration, name: BindingName, exclamationToken: ExclamationToken | undefined, type: TypeNode | undefined, initializer: Expression | undefined) { + function updateVariableDeclaration(node: ts.VariableDeclaration, name: ts.BindingName, exclamationToken: ts.ExclamationToken | undefined, type: ts.TypeNode | undefined, initializer: ts.Expression | undefined) { return node.name !== name || node.type !== type || node.exclamationToken !== exclamationToken @@ -3628,84 +3184,56 @@ namespace ts { } // @api - function createVariableDeclarationList(declarations: readonly VariableDeclaration[], flags = NodeFlags.None) { - const node = createBaseNode(SyntaxKind.VariableDeclarationList); - node.flags |= flags & NodeFlags.BlockScoped; + function createVariableDeclarationList(declarations: readonly ts.VariableDeclaration[], flags = ts.NodeFlags.None) { + const node = createBaseNode(ts.SyntaxKind.VariableDeclarationList); + node.flags |= flags & ts.NodeFlags.BlockScoped; node.declarations = createNodeArray(declarations); node.transformFlags |= propagateChildrenFlags(node.declarations) | - TransformFlags.ContainsHoistedDeclarationOrCompletion; - if (flags & NodeFlags.BlockScoped) { + ts.TransformFlags.ContainsHoistedDeclarationOrCompletion; + if (flags & ts.NodeFlags.BlockScoped) { node.transformFlags |= - TransformFlags.ContainsES2015 | - TransformFlags.ContainsBlockScopedBinding; + ts.TransformFlags.ContainsES2015 | + ts.TransformFlags.ContainsBlockScopedBinding; } return node; } // @api - function updateVariableDeclarationList(node: VariableDeclarationList, declarations: readonly VariableDeclaration[]) { + function updateVariableDeclarationList(node: ts.VariableDeclarationList, declarations: readonly ts.VariableDeclaration[]) { return node.declarations !== declarations ? update(createVariableDeclarationList(declarations, node.flags), node) : node; } // @api - function createFunctionDeclaration( - decorators: readonly Decorator[] | undefined, - modifiers: readonly Modifier[] | undefined, - asteriskToken: AsteriskToken | undefined, - name: string | Identifier | undefined, - typeParameters: readonly TypeParameterDeclaration[] | undefined, - parameters: readonly ParameterDeclaration[], - type: TypeNode | undefined, - body: Block | undefined - ) { - const node = createBaseFunctionLikeDeclaration( - SyntaxKind.FunctionDeclaration, - decorators, - modifiers, - name, - typeParameters, - parameters, - type, - body - ); + function createFunctionDeclaration(decorators: readonly ts.Decorator[] | undefined, modifiers: readonly ts.Modifier[] | undefined, asteriskToken: ts.AsteriskToken | undefined, name: string | ts.Identifier | undefined, typeParameters: readonly ts.TypeParameterDeclaration[] | undefined, parameters: readonly ts.ParameterDeclaration[], type: ts.TypeNode | undefined, body: ts.Block | undefined) { + const node = createBaseFunctionLikeDeclaration(ts.SyntaxKind.FunctionDeclaration, decorators, modifiers, name, typeParameters, parameters, type, body); node.asteriskToken = asteriskToken; - if (!node.body || modifiersToFlags(node.modifiers) & ModifierFlags.Ambient) { - node.transformFlags = TransformFlags.ContainsTypeScript; + if (!node.body || ts.modifiersToFlags(node.modifiers) & ts.ModifierFlags.Ambient) { + node.transformFlags = ts.TransformFlags.ContainsTypeScript; } else { node.transformFlags |= propagateChildFlags(node.asteriskToken) | - TransformFlags.ContainsHoistedDeclarationOrCompletion; - if (modifiersToFlags(node.modifiers) & ModifierFlags.Async) { + ts.TransformFlags.ContainsHoistedDeclarationOrCompletion; + if (ts.modifiersToFlags(node.modifiers) & ts.ModifierFlags.Async) { if (node.asteriskToken) { - node.transformFlags |= TransformFlags.ContainsES2018; + node.transformFlags |= ts.TransformFlags.ContainsES2018; } else { - node.transformFlags |= TransformFlags.ContainsES2017; + node.transformFlags |= ts.TransformFlags.ContainsES2017; } } else if (node.asteriskToken) { - node.transformFlags |= TransformFlags.ContainsGenerator; + node.transformFlags |= ts.TransformFlags.ContainsGenerator; } } return node; } // @api - function updateFunctionDeclaration( - node: FunctionDeclaration, - decorators: readonly Decorator[] | undefined, - modifiers: readonly Modifier[] | undefined, - asteriskToken: AsteriskToken | undefined, - name: Identifier | undefined, - typeParameters: readonly TypeParameterDeclaration[] | undefined, - parameters: readonly ParameterDeclaration[], - type: TypeNode | undefined, - body: Block | undefined - ) { + function updateFunctionDeclaration(node: ts.FunctionDeclaration, decorators: readonly ts.Decorator[] | undefined, modifiers: readonly ts.Modifier[] | undefined, asteriskToken: ts.AsteriskToken | undefined, name: ts.Identifier | undefined, typeParameters: readonly ts.TypeParameterDeclaration[] | undefined, parameters: readonly ts.ParameterDeclaration[], type: ts.TypeNode | undefined, body: ts.Block | undefined) { return node.decorators !== decorators || node.modifiers !== modifiers || node.asteriskToken !== asteriskToken @@ -3719,45 +3247,22 @@ namespace ts { } // @api - function createClassDeclaration( - decorators: readonly Decorator[] | undefined, - modifiers: readonly Modifier[] | undefined, - name: string | Identifier | undefined, - typeParameters: readonly TypeParameterDeclaration[] | undefined, - heritageClauses: readonly HeritageClause[] | undefined, - members: readonly ClassElement[] - ) { - const node = createBaseClassLikeDeclaration( - SyntaxKind.ClassDeclaration, - decorators, - modifiers, - name, - typeParameters, - heritageClauses, - members - ); - if (modifiersToFlags(node.modifiers) & ModifierFlags.Ambient) { - node.transformFlags = TransformFlags.ContainsTypeScript; + function createClassDeclaration(decorators: readonly ts.Decorator[] | undefined, modifiers: readonly ts.Modifier[] | undefined, name: string | ts.Identifier | undefined, typeParameters: readonly ts.TypeParameterDeclaration[] | undefined, heritageClauses: readonly ts.HeritageClause[] | undefined, members: readonly ts.ClassElement[]) { + const node = createBaseClassLikeDeclaration(ts.SyntaxKind.ClassDeclaration, decorators, modifiers, name, typeParameters, heritageClauses, members); + if (ts.modifiersToFlags(node.modifiers) & ts.ModifierFlags.Ambient) { + node.transformFlags = ts.TransformFlags.ContainsTypeScript; } else { - node.transformFlags |= TransformFlags.ContainsES2015; - if (node.transformFlags & TransformFlags.ContainsTypeScriptClassSyntax) { - node.transformFlags |= TransformFlags.ContainsTypeScript; + node.transformFlags |= ts.TransformFlags.ContainsES2015; + if (node.transformFlags & ts.TransformFlags.ContainsTypeScriptClassSyntax) { + node.transformFlags |= ts.TransformFlags.ContainsTypeScript; } } return node; } // @api - function updateClassDeclaration( - node: ClassDeclaration, - decorators: readonly Decorator[] | undefined, - modifiers: readonly Modifier[] | undefined, - name: Identifier | undefined, - typeParameters: readonly TypeParameterDeclaration[] | undefined, - heritageClauses: readonly HeritageClause[] | undefined, - members: readonly ClassElement[] - ) { + function updateClassDeclaration(node: ts.ClassDeclaration, decorators: readonly ts.Decorator[] | undefined, modifiers: readonly ts.Modifier[] | undefined, name: ts.Identifier | undefined, typeParameters: readonly ts.TypeParameterDeclaration[] | undefined, heritageClauses: readonly ts.HeritageClause[] | undefined, members: readonly ts.ClassElement[]) { return node.decorators !== decorators || node.modifiers !== modifiers || node.name !== name @@ -3769,37 +3274,15 @@ namespace ts { } // @api - function createInterfaceDeclaration( - decorators: readonly Decorator[] | undefined, - modifiers: readonly Modifier[] | undefined, - name: string | Identifier, - typeParameters: readonly TypeParameterDeclaration[] | undefined, - heritageClauses: readonly HeritageClause[] | undefined, - members: readonly TypeElement[] - ) { - const node = createBaseInterfaceOrClassLikeDeclaration( - SyntaxKind.InterfaceDeclaration, - decorators, - modifiers, - name, - typeParameters, - heritageClauses - ); + function createInterfaceDeclaration(decorators: readonly ts.Decorator[] | undefined, modifiers: readonly ts.Modifier[] | undefined, name: string | ts.Identifier, typeParameters: readonly ts.TypeParameterDeclaration[] | undefined, heritageClauses: readonly ts.HeritageClause[] | undefined, members: readonly ts.TypeElement[]) { + const node = createBaseInterfaceOrClassLikeDeclaration(ts.SyntaxKind.InterfaceDeclaration, decorators, modifiers, name, typeParameters, heritageClauses); node.members = createNodeArray(members); - node.transformFlags = TransformFlags.ContainsTypeScript; + node.transformFlags = ts.TransformFlags.ContainsTypeScript; return node; } // @api - function updateInterfaceDeclaration( - node: InterfaceDeclaration, - decorators: readonly Decorator[] | undefined, - modifiers: readonly Modifier[] | undefined, - name: Identifier, - typeParameters: readonly TypeParameterDeclaration[] | undefined, - heritageClauses: readonly HeritageClause[] | undefined, - members: readonly TypeElement[] - ) { + function updateInterfaceDeclaration(node: ts.InterfaceDeclaration, decorators: readonly ts.Decorator[] | undefined, modifiers: readonly ts.Modifier[] | undefined, name: ts.Identifier, typeParameters: readonly ts.TypeParameterDeclaration[] | undefined, heritageClauses: readonly ts.HeritageClause[] | undefined, members: readonly ts.TypeElement[]) { return node.decorators !== decorators || node.modifiers !== modifiers || node.name !== name @@ -3811,34 +3294,15 @@ namespace ts { } // @api - function createTypeAliasDeclaration( - decorators: readonly Decorator[] | undefined, - modifiers: readonly Modifier[] | undefined, - name: string | Identifier, - typeParameters: readonly TypeParameterDeclaration[] | undefined, - type: TypeNode - ) { - const node = createBaseGenericNamedDeclaration( - SyntaxKind.TypeAliasDeclaration, - decorators, - modifiers, - name, - typeParameters - ); + function createTypeAliasDeclaration(decorators: readonly ts.Decorator[] | undefined, modifiers: readonly ts.Modifier[] | undefined, name: string | ts.Identifier, typeParameters: readonly ts.TypeParameterDeclaration[] | undefined, type: ts.TypeNode) { + const node = createBaseGenericNamedDeclaration(ts.SyntaxKind.TypeAliasDeclaration, decorators, modifiers, name, typeParameters); node.type = type; - node.transformFlags = TransformFlags.ContainsTypeScript; + node.transformFlags = ts.TransformFlags.ContainsTypeScript; return node; } // @api - function updateTypeAliasDeclaration( - node: TypeAliasDeclaration, - decorators: readonly Decorator[] | undefined, - modifiers: readonly Modifier[] | undefined, - name: Identifier, - typeParameters: readonly TypeParameterDeclaration[] | undefined, - type: TypeNode - ) { + function updateTypeAliasDeclaration(node: ts.TypeAliasDeclaration, decorators: readonly ts.Decorator[] | undefined, modifiers: readonly ts.Modifier[] | undefined, name: ts.Identifier, typeParameters: readonly ts.TypeParameterDeclaration[] | undefined, type: ts.TypeNode) { return node.decorators !== decorators || node.modifiers !== modifiers || node.name !== name @@ -3849,33 +3313,18 @@ namespace ts { } // @api - function createEnumDeclaration( - decorators: readonly Decorator[] | undefined, - modifiers: readonly Modifier[] | undefined, - name: string | Identifier, - members: readonly EnumMember[] - ) { - const node = createBaseNamedDeclaration( - SyntaxKind.EnumDeclaration, - decorators, - modifiers, - name - ); + function createEnumDeclaration(decorators: readonly ts.Decorator[] | undefined, modifiers: readonly ts.Modifier[] | undefined, name: string | ts.Identifier, members: readonly ts.EnumMember[]) { + const node = createBaseNamedDeclaration(ts.SyntaxKind.EnumDeclaration, decorators, modifiers, name); node.members = createNodeArray(members); node.transformFlags |= propagateChildrenFlags(node.members) | - TransformFlags.ContainsTypeScript; - node.transformFlags &= ~TransformFlags.ContainsPossibleTopLevelAwait; // Enum declarations cannot contain `await` + ts.TransformFlags.ContainsTypeScript; + node.transformFlags &= ~ts.TransformFlags.ContainsPossibleTopLevelAwait; // Enum declarations cannot contain `await` return node; } // @api - function updateEnumDeclaration( - node: EnumDeclaration, - decorators: readonly Decorator[] | undefined, - modifiers: readonly Modifier[] | undefined, - name: Identifier, - members: readonly EnumMember[]) { + function updateEnumDeclaration(node: ts.EnumDeclaration, decorators: readonly ts.Decorator[] | undefined, modifiers: readonly ts.Modifier[] | undefined, name: ts.Identifier, members: readonly ts.EnumMember[]) { return node.decorators !== decorators || node.modifiers !== modifiers || node.name !== name @@ -3885,42 +3334,26 @@ namespace ts { } // @api - function createModuleDeclaration( - decorators: readonly Decorator[] | undefined, - modifiers: readonly Modifier[] | undefined, - name: ModuleName, - body: ModuleBody | undefined, - flags = NodeFlags.None - ) { - const node = createBaseDeclaration( - SyntaxKind.ModuleDeclaration, - decorators, - modifiers - ); - node.flags |= flags & (NodeFlags.Namespace | NodeFlags.NestedNamespace | NodeFlags.GlobalAugmentation); + function createModuleDeclaration(decorators: readonly ts.Decorator[] | undefined, modifiers: readonly ts.Modifier[] | undefined, name: ts.ModuleName, body: ts.ModuleBody | undefined, flags = ts.NodeFlags.None) { + const node = createBaseDeclaration(ts.SyntaxKind.ModuleDeclaration, decorators, modifiers); + node.flags |= flags & (ts.NodeFlags.Namespace | ts.NodeFlags.NestedNamespace | ts.NodeFlags.GlobalAugmentation); node.name = name; node.body = body; - if (modifiersToFlags(node.modifiers) & ModifierFlags.Ambient) { - node.transformFlags = TransformFlags.ContainsTypeScript; + if (ts.modifiersToFlags(node.modifiers) & ts.ModifierFlags.Ambient) { + node.transformFlags = ts.TransformFlags.ContainsTypeScript; } else { node.transformFlags |= propagateChildFlags(node.name) | propagateChildFlags(node.body) | - TransformFlags.ContainsTypeScript; + ts.TransformFlags.ContainsTypeScript; } - node.transformFlags &= ~TransformFlags.ContainsPossibleTopLevelAwait; // Module declarations cannot contain `await`. + node.transformFlags &= ~ts.TransformFlags.ContainsPossibleTopLevelAwait; // Module declarations cannot contain `await`. return node; } // @api - function updateModuleDeclaration( - node: ModuleDeclaration, - decorators: readonly Decorator[] | undefined, - modifiers: readonly Modifier[] | undefined, - name: ModuleName, - body: ModuleBody | undefined - ) { + function updateModuleDeclaration(node: ts.ModuleDeclaration, decorators: readonly ts.Decorator[] | undefined, modifiers: readonly ts.Modifier[] | undefined, name: ts.ModuleName, body: ts.ModuleBody | undefined) { return node.decorators !== decorators || node.modifiers !== modifiers || node.name !== name @@ -3930,85 +3363,65 @@ namespace ts { } // @api - function createModuleBlock(statements: readonly Statement[]) { - const node = createBaseNode(SyntaxKind.ModuleBlock); + function createModuleBlock(statements: readonly ts.Statement[]) { + const node = createBaseNode(ts.SyntaxKind.ModuleBlock); node.statements = createNodeArray(statements); node.transformFlags |= propagateChildrenFlags(node.statements); return node; } // @api - function updateModuleBlock(node: ModuleBlock, statements: readonly Statement[]) { + function updateModuleBlock(node: ts.ModuleBlock, statements: readonly ts.Statement[]) { return node.statements !== statements ? update(createModuleBlock(statements), node) : node; } // @api - function createCaseBlock(clauses: readonly CaseOrDefaultClause[]): CaseBlock { - const node = createBaseNode(SyntaxKind.CaseBlock); + function createCaseBlock(clauses: readonly ts.CaseOrDefaultClause[]): ts.CaseBlock { + const node = createBaseNode(ts.SyntaxKind.CaseBlock); node.clauses = createNodeArray(clauses); node.transformFlags |= propagateChildrenFlags(node.clauses); return node; } // @api - function updateCaseBlock(node: CaseBlock, clauses: readonly CaseOrDefaultClause[]) { + function updateCaseBlock(node: ts.CaseBlock, clauses: readonly ts.CaseOrDefaultClause[]) { return node.clauses !== clauses ? update(createCaseBlock(clauses), node) : node; } // @api - function createNamespaceExportDeclaration(name: string | Identifier) { - const node = createBaseNamedDeclaration( - SyntaxKind.NamespaceExportDeclaration, + function createNamespaceExportDeclaration(name: string | ts.Identifier) { + const node = createBaseNamedDeclaration(ts.SyntaxKind.NamespaceExportDeclaration, /*decorators*/ undefined, - /*modifiers*/ undefined, - name - ); - node.transformFlags = TransformFlags.ContainsTypeScript; + /*modifiers*/ undefined, name); + node.transformFlags = ts.TransformFlags.ContainsTypeScript; return node; } // @api - function updateNamespaceExportDeclaration(node: NamespaceExportDeclaration, name: Identifier) { + function updateNamespaceExportDeclaration(node: ts.NamespaceExportDeclaration, name: ts.Identifier) { return node.name !== name ? update(createNamespaceExportDeclaration(name), node) : node; } // @api - function createImportEqualsDeclaration( - decorators: readonly Decorator[] | undefined, - modifiers: readonly Modifier[] | undefined, - isTypeOnly: boolean, - name: string | Identifier, - moduleReference: ModuleReference - ) { - const node = createBaseNamedDeclaration( - SyntaxKind.ImportEqualsDeclaration, - decorators, - modifiers, - name - ); + function createImportEqualsDeclaration(decorators: readonly ts.Decorator[] | undefined, modifiers: readonly ts.Modifier[] | undefined, isTypeOnly: boolean, name: string | ts.Identifier, moduleReference: ts.ModuleReference) { + const node = createBaseNamedDeclaration(ts.SyntaxKind.ImportEqualsDeclaration, decorators, modifiers, name); node.isTypeOnly = isTypeOnly; node.moduleReference = moduleReference; node.transformFlags |= propagateChildFlags(node.moduleReference); - if (!isExternalModuleReference(node.moduleReference)) node.transformFlags |= TransformFlags.ContainsTypeScript; - node.transformFlags &= ~TransformFlags.ContainsPossibleTopLevelAwait; // Import= declaration is always parsed in an Await context + if (!ts.isExternalModuleReference(node.moduleReference)) + node.transformFlags |= ts.TransformFlags.ContainsTypeScript; + node.transformFlags &= ~ts.TransformFlags.ContainsPossibleTopLevelAwait; // Import= declaration is always parsed in an Await context return node; } // @api - function updateImportEqualsDeclaration( - node: ImportEqualsDeclaration, - decorators: readonly Decorator[] | undefined, - modifiers: readonly Modifier[] | undefined, - isTypeOnly: boolean, - name: Identifier, - moduleReference: ModuleReference - ) { + function updateImportEqualsDeclaration(node: ts.ImportEqualsDeclaration, decorators: readonly ts.Decorator[] | undefined, modifiers: readonly ts.Modifier[] | undefined, isTypeOnly: boolean, name: ts.Identifier, moduleReference: ts.ModuleReference) { return node.decorators !== decorators || node.modifiers !== modifiers || node.isTypeOnly !== isTypeOnly @@ -4019,37 +3432,20 @@ namespace ts { } // @api - function createImportDeclaration( - decorators: readonly Decorator[] | undefined, - modifiers: readonly Modifier[] | undefined, - importClause: ImportClause | undefined, - moduleSpecifier: Expression, - assertClause: AssertClause | undefined - ): ImportDeclaration { - const node = createBaseDeclaration( - SyntaxKind.ImportDeclaration, - decorators, - modifiers - ); + function createImportDeclaration(decorators: readonly ts.Decorator[] | undefined, modifiers: readonly ts.Modifier[] | undefined, importClause: ts.ImportClause | undefined, moduleSpecifier: ts.Expression, assertClause: ts.AssertClause | undefined): ts.ImportDeclaration { + const node = createBaseDeclaration(ts.SyntaxKind.ImportDeclaration, decorators, modifiers); node.importClause = importClause; node.moduleSpecifier = moduleSpecifier; node.assertClause = assertClause; node.transformFlags |= propagateChildFlags(node.importClause) | propagateChildFlags(node.moduleSpecifier); - node.transformFlags &= ~TransformFlags.ContainsPossibleTopLevelAwait; // always parsed in an Await context + node.transformFlags &= ~ts.TransformFlags.ContainsPossibleTopLevelAwait; // always parsed in an Await context return node; } // @api - function updateImportDeclaration( - node: ImportDeclaration, - decorators: readonly Decorator[] | undefined, - modifiers: readonly Modifier[] | undefined, - importClause: ImportClause | undefined, - moduleSpecifier: Expression, - assertClause: AssertClause | undefined - ) { + function updateImportDeclaration(node: ts.ImportDeclaration, decorators: readonly ts.Decorator[] | undefined, modifiers: readonly ts.Modifier[] | undefined, importClause: ts.ImportClause | undefined, moduleSpecifier: ts.Expression, assertClause: ts.AssertClause | undefined) { return node.decorators !== decorators || node.modifiers !== modifiers || node.importClause !== importClause @@ -4060,8 +3456,8 @@ namespace ts { } // @api - function createImportClause(isTypeOnly: boolean, name: Identifier | undefined, namedBindings: NamedImportBindings | undefined): ImportClause { - const node = createBaseNode(SyntaxKind.ImportClause); + function createImportClause(isTypeOnly: boolean, name: ts.Identifier | undefined, namedBindings: ts.NamedImportBindings | undefined): ts.ImportClause { + const node = createBaseNode(ts.SyntaxKind.ImportClause); node.isTypeOnly = isTypeOnly; node.name = name; node.namedBindings = namedBindings; @@ -4069,14 +3465,14 @@ namespace ts { propagateChildFlags(node.name) | propagateChildFlags(node.namedBindings); if (isTypeOnly) { - node.transformFlags |= TransformFlags.ContainsTypeScript; + node.transformFlags |= ts.TransformFlags.ContainsTypeScript; } - node.transformFlags &= ~TransformFlags.ContainsPossibleTopLevelAwait; // always parsed in an Await context + node.transformFlags &= ~ts.TransformFlags.ContainsPossibleTopLevelAwait; // always parsed in an Await context return node; } // @api - function updateImportClause(node: ImportClause, isTypeOnly: boolean, name: Identifier | undefined, namedBindings: NamedImportBindings | undefined) { + function updateImportClause(node: ts.ImportClause, isTypeOnly: boolean, name: ts.Identifier | undefined, namedBindings: ts.NamedImportBindings | undefined) { return node.isTypeOnly !== isTypeOnly || node.name !== name || node.namedBindings !== namedBindings @@ -4085,16 +3481,16 @@ namespace ts { } // @api - function createAssertClause(elements: readonly AssertEntry[], multiLine?: boolean): AssertClause { - const node = createBaseNode(SyntaxKind.AssertClause); + function createAssertClause(elements: readonly ts.AssertEntry[], multiLine?: boolean): ts.AssertClause { + const node = createBaseNode(ts.SyntaxKind.AssertClause); node.elements = createNodeArray(elements); node.multiLine = multiLine; - node.transformFlags |= TransformFlags.ContainsESNext; + node.transformFlags |= ts.TransformFlags.ContainsESNext; return node; } // @api - function updateAssertClause(node: AssertClause, elements: readonly AssertEntry[], multiLine?: boolean): AssertClause { + function updateAssertClause(node: ts.AssertClause, elements: readonly ts.AssertEntry[], multiLine?: boolean): ts.AssertClause { return node.elements !== elements || node.multiLine !== multiLine ? update(createAssertClause(elements, multiLine), node) @@ -4102,16 +3498,16 @@ namespace ts { } // @api - function createAssertEntry(name: AssertionKey, value: Expression): AssertEntry { - const node = createBaseNode(SyntaxKind.AssertEntry); + function createAssertEntry(name: ts.AssertionKey, value: ts.Expression): ts.AssertEntry { + const node = createBaseNode(ts.SyntaxKind.AssertEntry); node.name = name; node.value = value; - node.transformFlags |= TransformFlags.ContainsESNext; + node.transformFlags |= ts.TransformFlags.ContainsESNext; return node; } // @api - function updateAssertEntry(node: AssertEntry, name: AssertionKey, value: Expression): AssertEntry { + function updateAssertEntry(node: ts.AssertEntry, name: ts.AssertionKey, value: ts.Expression): ts.AssertEntry { return node.name !== name || node.value !== value ? update(createAssertEntry(name, value), node) @@ -4119,15 +3515,15 @@ namespace ts { } // @api - function createImportTypeAssertionContainer(clause: AssertClause, multiLine?: boolean): ImportTypeAssertionContainer { - const node = createBaseNode(SyntaxKind.ImportTypeAssertionContainer); + function createImportTypeAssertionContainer(clause: ts.AssertClause, multiLine?: boolean): ts.ImportTypeAssertionContainer { + const node = createBaseNode(ts.SyntaxKind.ImportTypeAssertionContainer); node.assertClause = clause; node.multiLine = multiLine; return node; } // @api - function updateImportTypeAssertionContainer(node: ImportTypeAssertionContainer, clause: AssertClause, multiLine?: boolean): ImportTypeAssertionContainer { + function updateImportTypeAssertionContainer(node: ts.ImportTypeAssertionContainer, clause: ts.AssertClause, multiLine?: boolean): ts.ImportTypeAssertionContainer { return node.assertClause !== clause || node.multiLine !== multiLine ? update(createImportTypeAssertionContainer(clause, multiLine), node) @@ -4135,70 +3531,70 @@ namespace ts { } // @api - function createNamespaceImport(name: Identifier): NamespaceImport { - const node = createBaseNode(SyntaxKind.NamespaceImport); + function createNamespaceImport(name: ts.Identifier): ts.NamespaceImport { + const node = createBaseNode(ts.SyntaxKind.NamespaceImport); node.name = name; node.transformFlags |= propagateChildFlags(node.name); - node.transformFlags &= ~TransformFlags.ContainsPossibleTopLevelAwait; // always parsed in an Await context + node.transformFlags &= ~ts.TransformFlags.ContainsPossibleTopLevelAwait; // always parsed in an Await context return node; } // @api - function updateNamespaceImport(node: NamespaceImport, name: Identifier) { + function updateNamespaceImport(node: ts.NamespaceImport, name: ts.Identifier) { return node.name !== name ? update(createNamespaceImport(name), node) : node; } // @api - function createNamespaceExport(name: Identifier): NamespaceExport { - const node = createBaseNode(SyntaxKind.NamespaceExport); + function createNamespaceExport(name: ts.Identifier): ts.NamespaceExport { + const node = createBaseNode(ts.SyntaxKind.NamespaceExport); node.name = name; node.transformFlags |= propagateChildFlags(node.name) | - TransformFlags.ContainsESNext; - node.transformFlags &= ~TransformFlags.ContainsPossibleTopLevelAwait; // always parsed in an Await context + ts.TransformFlags.ContainsESNext; + node.transformFlags &= ~ts.TransformFlags.ContainsPossibleTopLevelAwait; // always parsed in an Await context return node; } // @api - function updateNamespaceExport(node: NamespaceExport, name: Identifier) { + function updateNamespaceExport(node: ts.NamespaceExport, name: ts.Identifier) { return node.name !== name ? update(createNamespaceExport(name), node) : node; } // @api - function createNamedImports(elements: readonly ImportSpecifier[]): NamedImports { - const node = createBaseNode(SyntaxKind.NamedImports); + function createNamedImports(elements: readonly ts.ImportSpecifier[]): ts.NamedImports { + const node = createBaseNode(ts.SyntaxKind.NamedImports); node.elements = createNodeArray(elements); node.transformFlags |= propagateChildrenFlags(node.elements); - node.transformFlags &= ~TransformFlags.ContainsPossibleTopLevelAwait; // always parsed in an Await context + node.transformFlags &= ~ts.TransformFlags.ContainsPossibleTopLevelAwait; // always parsed in an Await context return node; } // @api - function updateNamedImports(node: NamedImports, elements: readonly ImportSpecifier[]) { + function updateNamedImports(node: ts.NamedImports, elements: readonly ts.ImportSpecifier[]) { return node.elements !== elements ? update(createNamedImports(elements), node) : node; } // @api - function createImportSpecifier(isTypeOnly: boolean, propertyName: Identifier | undefined, name: Identifier) { - const node = createBaseNode(SyntaxKind.ImportSpecifier); + function createImportSpecifier(isTypeOnly: boolean, propertyName: ts.Identifier | undefined, name: ts.Identifier) { + const node = createBaseNode(ts.SyntaxKind.ImportSpecifier); node.isTypeOnly = isTypeOnly; node.propertyName = propertyName; node.name = name; node.transformFlags |= propagateChildFlags(node.propertyName) | propagateChildFlags(node.name); - node.transformFlags &= ~TransformFlags.ContainsPossibleTopLevelAwait; // always parsed in an Await context + node.transformFlags &= ~ts.TransformFlags.ContainsPossibleTopLevelAwait; // always parsed in an Await context return node; } // @api - function updateImportSpecifier(node: ImportSpecifier, isTypeOnly: boolean, propertyName: Identifier | undefined, name: Identifier) { + function updateImportSpecifier(node: ts.ImportSpecifier, isTypeOnly: boolean, propertyName: ts.Identifier | undefined, name: ts.Identifier) { return node.isTypeOnly !== isTypeOnly || node.propertyName !== propertyName || node.name !== name @@ -4207,33 +3603,19 @@ namespace ts { } // @api - function createExportAssignment( - decorators: readonly Decorator[] | undefined, - modifiers: readonly Modifier[] | undefined, - isExportEquals: boolean | undefined, - expression: Expression - ) { - const node = createBaseDeclaration( - SyntaxKind.ExportAssignment, - decorators, - modifiers - ); + function createExportAssignment(decorators: readonly ts.Decorator[] | undefined, modifiers: readonly ts.Modifier[] | undefined, isExportEquals: boolean | undefined, expression: ts.Expression) { + const node = createBaseDeclaration(ts.SyntaxKind.ExportAssignment, decorators, modifiers); node.isExportEquals = isExportEquals; node.expression = isExportEquals - ? parenthesizerRules().parenthesizeRightSideOfBinary(SyntaxKind.EqualsToken, /*leftSide*/ undefined, expression) + ? parenthesizerRules().parenthesizeRightSideOfBinary(ts.SyntaxKind.EqualsToken, /*leftSide*/ undefined, expression) : parenthesizerRules().parenthesizeExpressionOfExportDefault(expression); node.transformFlags |= propagateChildFlags(node.expression); - node.transformFlags &= ~TransformFlags.ContainsPossibleTopLevelAwait; // always parsed in an Await context + node.transformFlags &= ~ts.TransformFlags.ContainsPossibleTopLevelAwait; // always parsed in an Await context return node; } // @api - function updateExportAssignment( - node: ExportAssignment, - decorators: readonly Decorator[] | undefined, - modifiers: readonly Modifier[] | undefined, - expression: Expression - ) { + function updateExportAssignment(node: ts.ExportAssignment, decorators: readonly ts.Decorator[] | undefined, modifiers: readonly ts.Modifier[] | undefined, expression: ts.Expression) { return node.decorators !== decorators || node.modifiers !== modifiers || node.expression !== expression @@ -4242,19 +3624,8 @@ namespace ts { } // @api - function createExportDeclaration( - decorators: readonly Decorator[] | undefined, - modifiers: readonly Modifier[] | undefined, - isTypeOnly: boolean, - exportClause: NamedExportBindings | undefined, - moduleSpecifier?: Expression, - assertClause?: AssertClause - ) { - const node = createBaseDeclaration( - SyntaxKind.ExportDeclaration, - decorators, - modifiers - ); + function createExportDeclaration(decorators: readonly ts.Decorator[] | undefined, modifiers: readonly ts.Modifier[] | undefined, isTypeOnly: boolean, exportClause: ts.NamedExportBindings | undefined, moduleSpecifier?: ts.Expression, assertClause?: ts.AssertClause) { + const node = createBaseDeclaration(ts.SyntaxKind.ExportDeclaration, decorators, modifiers); node.isTypeOnly = isTypeOnly; node.exportClause = exportClause; node.moduleSpecifier = moduleSpecifier; @@ -4262,20 +3633,12 @@ namespace ts { node.transformFlags |= propagateChildFlags(node.exportClause) | propagateChildFlags(node.moduleSpecifier); - node.transformFlags &= ~TransformFlags.ContainsPossibleTopLevelAwait; // always parsed in an Await context + node.transformFlags &= ~ts.TransformFlags.ContainsPossibleTopLevelAwait; // always parsed in an Await context return node; } // @api - function updateExportDeclaration( - node: ExportDeclaration, - decorators: readonly Decorator[] | undefined, - modifiers: readonly Modifier[] | undefined, - isTypeOnly: boolean, - exportClause: NamedExportBindings | undefined, - moduleSpecifier: Expression | undefined, - assertClause: AssertClause | undefined - ) { + function updateExportDeclaration(node: ts.ExportDeclaration, decorators: readonly ts.Decorator[] | undefined, modifiers: readonly ts.Modifier[] | undefined, isTypeOnly: boolean, exportClause: ts.NamedExportBindings | undefined, moduleSpecifier: ts.Expression | undefined, assertClause: ts.AssertClause | undefined) { return node.decorators !== decorators || node.modifiers !== modifiers || node.isTypeOnly !== isTypeOnly @@ -4287,36 +3650,36 @@ namespace ts { } // @api - function createNamedExports(elements: readonly ExportSpecifier[]) { - const node = createBaseNode(SyntaxKind.NamedExports); + function createNamedExports(elements: readonly ts.ExportSpecifier[]) { + const node = createBaseNode(ts.SyntaxKind.NamedExports); node.elements = createNodeArray(elements); node.transformFlags |= propagateChildrenFlags(node.elements); - node.transformFlags &= ~TransformFlags.ContainsPossibleTopLevelAwait; // always parsed in an Await context + node.transformFlags &= ~ts.TransformFlags.ContainsPossibleTopLevelAwait; // always parsed in an Await context return node; } // @api - function updateNamedExports(node: NamedExports, elements: readonly ExportSpecifier[]) { + function updateNamedExports(node: ts.NamedExports, elements: readonly ts.ExportSpecifier[]) { return node.elements !== elements ? update(createNamedExports(elements), node) : node; } // @api - function createExportSpecifier(isTypeOnly: boolean, propertyName: string | Identifier | undefined, name: string | Identifier) { - const node = createBaseNode(SyntaxKind.ExportSpecifier); + function createExportSpecifier(isTypeOnly: boolean, propertyName: string | ts.Identifier | undefined, name: string | ts.Identifier) { + const node = createBaseNode(ts.SyntaxKind.ExportSpecifier); node.isTypeOnly = isTypeOnly; node.propertyName = asName(propertyName); node.name = asName(name); node.transformFlags |= propagateChildFlags(node.propertyName) | propagateChildFlags(node.name); - node.transformFlags &= ~TransformFlags.ContainsPossibleTopLevelAwait; // always parsed in an Await context + node.transformFlags &= ~ts.TransformFlags.ContainsPossibleTopLevelAwait; // always parsed in an Await context return node; } // @api - function updateExportSpecifier(node: ExportSpecifier, isTypeOnly: boolean, propertyName: Identifier | undefined, name: Identifier) { + function updateExportSpecifier(node: ts.ExportSpecifier, isTypeOnly: boolean, propertyName: ts.Identifier | undefined, name: ts.Identifier) { return node.isTypeOnly !== isTypeOnly || node.propertyName !== propertyName || node.name !== name @@ -4326,11 +3689,9 @@ namespace ts { // @api function createMissingDeclaration() { - const node = createBaseDeclaration( - SyntaxKind.MissingDeclaration, + const node = createBaseDeclaration(ts.SyntaxKind.MissingDeclaration, /*decorators*/ undefined, - /*modifiers*/ undefined - ); + /*modifiers*/ undefined); return node; } @@ -4339,16 +3700,16 @@ namespace ts { // // @api - function createExternalModuleReference(expression: Expression) { - const node = createBaseNode(SyntaxKind.ExternalModuleReference); + function createExternalModuleReference(expression: ts.Expression) { + const node = createBaseNode(ts.SyntaxKind.ExternalModuleReference); node.expression = expression; node.transformFlags |= propagateChildFlags(node.expression); - node.transformFlags &= ~TransformFlags.ContainsPossibleTopLevelAwait; // always parsed in an Await context + node.transformFlags &= ~ts.TransformFlags.ContainsPossibleTopLevelAwait; // always parsed in an Await context return node; } // @api - function updateExternalModuleReference(node: ExternalModuleReference, expression: Expression) { + function updateExternalModuleReference(node: ts.ExternalModuleReference, expression: ts.Expression) { return node.expression !== expression ? update(createExternalModuleReference(expression), node) : node; @@ -4361,18 +3722,18 @@ namespace ts { // @api // createJSDocAllType // createJSDocUnknownType - function createJSDocPrimaryTypeWorker(kind: T["kind"]) { + function createJSDocPrimaryTypeWorker(kind: T["kind"]) { return createBaseNode(kind); } // @api // createJSDocNullableType // createJSDocNonNullableType - function createJSDocPrePostfixUnaryTypeWorker(kind: T["kind"], type: T["type"], postfix = false): T { - const node = createJSDocUnaryTypeWorker( - kind, - postfix ? type && parenthesizerRules().parenthesizeNonArrayTypeOfPostfixType(type) : type - ) as Mutable; + function createJSDocPrePostfixUnaryTypeWorker(kind: T["kind"], type: T["type"], postfix = false): T { + const node = createJSDocUnaryTypeWorker(kind, postfix ? type && parenthesizerRules().parenthesizeNonArrayTypeOfPostfixType(type) : type) as ts.Mutable; node.postfix = postfix; return node; } @@ -4381,7 +3742,9 @@ namespace ts { // createJSDocOptionalType // createJSDocVariadicType // createJSDocNamepathType - function createJSDocUnaryTypeWorker(kind: T["kind"], type: T["type"]): T { + function createJSDocUnaryTypeWorker(kind: T["kind"], type: T["type"]): T { const node = createBaseNode(kind); node.type = type; return node; @@ -4390,7 +3753,10 @@ namespace ts { // @api // updateJSDocNonNullableType // updateJSDocNullableType - function updateJSDocPrePostfixUnaryTypeWorker(kind: T["kind"], node: T, type: T["type"]): T { + function updateJSDocPrePostfixUnaryTypeWorker(kind: T["kind"], node: T, type: T["type"]): T { return node.type !== type ? update(createJSDocPrePostfixUnaryTypeWorker(kind, type, node.postfix), node) : node; @@ -4400,28 +3766,26 @@ namespace ts { // updateJSDocOptionalType // updateJSDocVariadicType // updateJSDocNamepathType - function updateJSDocUnaryTypeWorker(kind: T["kind"], node: T, type: T["type"]): T { + function updateJSDocUnaryTypeWorker(kind: T["kind"], node: T, type: T["type"]): T { return node.type !== type ? update(createJSDocUnaryTypeWorker(kind, type), node) : node; } // @api - function createJSDocFunctionType(parameters: readonly ParameterDeclaration[], type: TypeNode | undefined): JSDocFunctionType { - const node = createBaseSignatureDeclaration( - SyntaxKind.JSDocFunctionType, + function createJSDocFunctionType(parameters: readonly ts.ParameterDeclaration[], type: ts.TypeNode | undefined): ts.JSDocFunctionType { + const node = createBaseSignatureDeclaration(ts.SyntaxKind.JSDocFunctionType, /*decorators*/ undefined, /*modifiers*/ undefined, /*name*/ undefined, - /*typeParameters*/ undefined, - parameters, - type - ); + /*typeParameters*/ undefined, parameters, type); return node; } // @api - function updateJSDocFunctionType(node: JSDocFunctionType, parameters: readonly ParameterDeclaration[], type: TypeNode | undefined): JSDocFunctionType { + function updateJSDocFunctionType(node: ts.JSDocFunctionType, parameters: readonly ts.ParameterDeclaration[], type: ts.TypeNode | undefined): ts.JSDocFunctionType { return node.parameters !== parameters || node.type !== type ? update(createJSDocFunctionType(parameters, type), node) @@ -4429,15 +3793,15 @@ namespace ts { } // @api - function createJSDocTypeLiteral(propertyTags?: readonly JSDocPropertyLikeTag[], isArrayType = false): JSDocTypeLiteral { - const node = createBaseNode(SyntaxKind.JSDocTypeLiteral); + function createJSDocTypeLiteral(propertyTags?: readonly ts.JSDocPropertyLikeTag[], isArrayType = false): ts.JSDocTypeLiteral { + const node = createBaseNode(ts.SyntaxKind.JSDocTypeLiteral); node.jsDocPropertyTags = asNodeArray(propertyTags); node.isArrayType = isArrayType; return node; } // @api - function updateJSDocTypeLiteral(node: JSDocTypeLiteral, propertyTags: readonly JSDocPropertyLikeTag[] | undefined, isArrayType: boolean): JSDocTypeLiteral { + function updateJSDocTypeLiteral(node: ts.JSDocTypeLiteral, propertyTags: readonly ts.JSDocPropertyLikeTag[] | undefined, isArrayType: boolean): ts.JSDocTypeLiteral { return node.jsDocPropertyTags !== propertyTags || node.isArrayType !== isArrayType ? update(createJSDocTypeLiteral(propertyTags, isArrayType), node) @@ -4445,22 +3809,22 @@ namespace ts { } // @api - function createJSDocTypeExpression(type: TypeNode): JSDocTypeExpression { - const node = createBaseNode(SyntaxKind.JSDocTypeExpression); + function createJSDocTypeExpression(type: ts.TypeNode): ts.JSDocTypeExpression { + const node = createBaseNode(ts.SyntaxKind.JSDocTypeExpression); node.type = type; return node; } // @api - function updateJSDocTypeExpression(node: JSDocTypeExpression, type: TypeNode): JSDocTypeExpression { + function updateJSDocTypeExpression(node: ts.JSDocTypeExpression, type: ts.TypeNode): ts.JSDocTypeExpression { return node.type !== type ? update(createJSDocTypeExpression(type), node) : node; } // @api - function createJSDocSignature(typeParameters: readonly JSDocTemplateTag[] | undefined, parameters: readonly JSDocParameterTag[], type?: JSDocReturnTag): JSDocSignature { - const node = createBaseNode(SyntaxKind.JSDocSignature); + function createJSDocSignature(typeParameters: readonly ts.JSDocTemplateTag[] | undefined, parameters: readonly ts.JSDocParameterTag[], type?: ts.JSDocReturnTag): ts.JSDocSignature { + const node = createBaseNode(ts.SyntaxKind.JSDocSignature); node.typeParameters = asNodeArray(typeParameters); node.parameters = createNodeArray(parameters); node.type = type; @@ -4468,7 +3832,7 @@ namespace ts { } // @api - function updateJSDocSignature(node: JSDocSignature, typeParameters: readonly JSDocTemplateTag[] | undefined, parameters: readonly JSDocParameterTag[], type: JSDocReturnTag | undefined): JSDocSignature { + function updateJSDocSignature(node: ts.JSDocSignature, typeParameters: readonly ts.JSDocTemplateTag[] | undefined, parameters: readonly ts.JSDocParameterTag[], type: ts.JSDocReturnTag | undefined): ts.JSDocSignature { return node.typeParameters !== typeParameters || node.parameters !== parameters || node.type !== type @@ -4476,15 +3840,15 @@ namespace ts { : node; } - function getDefaultTagName(node: JSDocTag) { + function getDefaultTagName(node: ts.JSDocTag) { const defaultTagName = getDefaultTagNameForKind(node.kind); - return node.tagName.escapedText === escapeLeadingUnderscores(defaultTagName) + return node.tagName.escapedText === ts.escapeLeadingUnderscores(defaultTagName) ? node.tagName : createIdentifier(defaultTagName); } // @api - function createBaseJSDocTag(kind: T["kind"], tagName: Identifier, comment: string | NodeArray | undefined) { + function createBaseJSDocTag(kind: T["kind"], tagName: ts.Identifier, comment: string | ts.NodeArray | undefined) { const node = createBaseNode(kind); node.tagName = tagName; node.comment = comment; @@ -4492,15 +3856,15 @@ namespace ts { } // @api - function createJSDocTemplateTag(tagName: Identifier | undefined, constraint: JSDocTypeExpression | undefined, typeParameters: readonly TypeParameterDeclaration[], comment?: string | NodeArray): JSDocTemplateTag { - const node = createBaseJSDocTag(SyntaxKind.JSDocTemplateTag, tagName ?? createIdentifier("template"), comment); + function createJSDocTemplateTag(tagName: ts.Identifier | undefined, constraint: ts.JSDocTypeExpression | undefined, typeParameters: readonly ts.TypeParameterDeclaration[], comment?: string | ts.NodeArray): ts.JSDocTemplateTag { + const node = createBaseJSDocTag(ts.SyntaxKind.JSDocTemplateTag, tagName ?? createIdentifier("template"), comment); node.constraint = constraint; node.typeParameters = createNodeArray(typeParameters); return node; } // @api - function updateJSDocTemplateTag(node: JSDocTemplateTag, tagName: Identifier = getDefaultTagName(node), constraint: JSDocTypeExpression | undefined, typeParameters: readonly TypeParameterDeclaration[], comment: string | NodeArray | undefined): JSDocTemplateTag { + function updateJSDocTemplateTag(node: ts.JSDocTemplateTag, tagName: ts.Identifier = getDefaultTagName(node), constraint: ts.JSDocTypeExpression | undefined, typeParameters: readonly ts.TypeParameterDeclaration[], comment: string | ts.NodeArray | undefined): ts.JSDocTemplateTag { return node.tagName !== tagName || node.constraint !== constraint || node.typeParameters !== typeParameters @@ -4510,16 +3874,16 @@ namespace ts { } // @api - function createJSDocTypedefTag(tagName: Identifier | undefined, typeExpression?: JSDocTypeExpression, fullName?: Identifier | JSDocNamespaceDeclaration, comment?: string | NodeArray): JSDocTypedefTag { - const node = createBaseJSDocTag(SyntaxKind.JSDocTypedefTag, tagName ?? createIdentifier("typedef"), comment); + function createJSDocTypedefTag(tagName: ts.Identifier | undefined, typeExpression?: ts.JSDocTypeExpression, fullName?: ts.Identifier | ts.JSDocNamespaceDeclaration, comment?: string | ts.NodeArray): ts.JSDocTypedefTag { + const node = createBaseJSDocTag(ts.SyntaxKind.JSDocTypedefTag, tagName ?? createIdentifier("typedef"), comment); node.typeExpression = typeExpression; node.fullName = fullName; - node.name = getJSDocTypeAliasName(fullName); + node.name = ts.getJSDocTypeAliasName(fullName); return node; } // @api - function updateJSDocTypedefTag(node: JSDocTypedefTag, tagName: Identifier = getDefaultTagName(node), typeExpression: JSDocTypeExpression | undefined, fullName: Identifier | JSDocNamespaceDeclaration | undefined, comment: string | NodeArray | undefined): JSDocTypedefTag { + function updateJSDocTypedefTag(node: ts.JSDocTypedefTag, tagName: ts.Identifier = getDefaultTagName(node), typeExpression: ts.JSDocTypeExpression | undefined, fullName: ts.Identifier | ts.JSDocNamespaceDeclaration | undefined, comment: string | ts.NodeArray | undefined): ts.JSDocTypedefTag { return node.tagName !== tagName || node.typeExpression !== typeExpression || node.fullName !== fullName @@ -4529,8 +3893,8 @@ namespace ts { } // @api - function createJSDocParameterTag(tagName: Identifier | undefined, name: EntityName, isBracketed: boolean, typeExpression?: JSDocTypeExpression, isNameFirst?: boolean, comment?: string | NodeArray): JSDocParameterTag { - const node = createBaseJSDocTag(SyntaxKind.JSDocParameterTag, tagName ?? createIdentifier("param"), comment); + function createJSDocParameterTag(tagName: ts.Identifier | undefined, name: ts.EntityName, isBracketed: boolean, typeExpression?: ts.JSDocTypeExpression, isNameFirst?: boolean, comment?: string | ts.NodeArray): ts.JSDocParameterTag { + const node = createBaseJSDocTag(ts.SyntaxKind.JSDocParameterTag, tagName ?? createIdentifier("param"), comment); node.typeExpression = typeExpression; node.name = name; node.isNameFirst = !!isNameFirst; @@ -4539,7 +3903,7 @@ namespace ts { } // @api - function updateJSDocParameterTag(node: JSDocParameterTag, tagName: Identifier = getDefaultTagName(node), name: EntityName, isBracketed: boolean, typeExpression: JSDocTypeExpression | undefined, isNameFirst: boolean, comment: string | NodeArray | undefined): JSDocParameterTag { + function updateJSDocParameterTag(node: ts.JSDocParameterTag, tagName: ts.Identifier = getDefaultTagName(node), name: ts.EntityName, isBracketed: boolean, typeExpression: ts.JSDocTypeExpression | undefined, isNameFirst: boolean, comment: string | ts.NodeArray | undefined): ts.JSDocParameterTag { return node.tagName !== tagName || node.name !== name || node.isBracketed !== isBracketed @@ -4551,8 +3915,8 @@ namespace ts { } // @api - function createJSDocPropertyTag(tagName: Identifier | undefined, name: EntityName, isBracketed: boolean, typeExpression?: JSDocTypeExpression, isNameFirst?: boolean, comment?: string | NodeArray): JSDocPropertyTag { - const node = createBaseJSDocTag(SyntaxKind.JSDocPropertyTag, tagName ?? createIdentifier("prop"), comment); + function createJSDocPropertyTag(tagName: ts.Identifier | undefined, name: ts.EntityName, isBracketed: boolean, typeExpression?: ts.JSDocTypeExpression, isNameFirst?: boolean, comment?: string | ts.NodeArray): ts.JSDocPropertyTag { + const node = createBaseJSDocTag(ts.SyntaxKind.JSDocPropertyTag, tagName ?? createIdentifier("prop"), comment); node.typeExpression = typeExpression; node.name = name; node.isNameFirst = !!isNameFirst; @@ -4561,7 +3925,7 @@ namespace ts { } // @api - function updateJSDocPropertyTag(node: JSDocPropertyTag, tagName: Identifier = getDefaultTagName(node), name: EntityName, isBracketed: boolean, typeExpression: JSDocTypeExpression | undefined, isNameFirst: boolean, comment: string | NodeArray | undefined): JSDocPropertyTag { + function updateJSDocPropertyTag(node: ts.JSDocPropertyTag, tagName: ts.Identifier = getDefaultTagName(node), name: ts.EntityName, isBracketed: boolean, typeExpression: ts.JSDocTypeExpression | undefined, isNameFirst: boolean, comment: string | ts.NodeArray | undefined): ts.JSDocPropertyTag { return node.tagName !== tagName || node.name !== name || node.isBracketed !== isBracketed @@ -4573,16 +3937,16 @@ namespace ts { } // @api - function createJSDocCallbackTag(tagName: Identifier | undefined, typeExpression: JSDocSignature, fullName?: Identifier | JSDocNamespaceDeclaration, comment?: string | NodeArray): JSDocCallbackTag { - const node = createBaseJSDocTag(SyntaxKind.JSDocCallbackTag, tagName ?? createIdentifier("callback"), comment); + function createJSDocCallbackTag(tagName: ts.Identifier | undefined, typeExpression: ts.JSDocSignature, fullName?: ts.Identifier | ts.JSDocNamespaceDeclaration, comment?: string | ts.NodeArray): ts.JSDocCallbackTag { + const node = createBaseJSDocTag(ts.SyntaxKind.JSDocCallbackTag, tagName ?? createIdentifier("callback"), comment); node.typeExpression = typeExpression; node.fullName = fullName; - node.name = getJSDocTypeAliasName(fullName); + node.name = ts.getJSDocTypeAliasName(fullName); return node; } // @api - function updateJSDocCallbackTag(node: JSDocCallbackTag, tagName: Identifier = getDefaultTagName(node), typeExpression: JSDocSignature, fullName: Identifier | JSDocNamespaceDeclaration | undefined, comment: string | NodeArray | undefined): JSDocCallbackTag { + function updateJSDocCallbackTag(node: ts.JSDocCallbackTag, tagName: ts.Identifier = getDefaultTagName(node), typeExpression: ts.JSDocSignature, fullName: ts.Identifier | ts.JSDocNamespaceDeclaration | undefined, comment: string | ts.NodeArray | undefined): ts.JSDocCallbackTag { return node.tagName !== tagName || node.typeExpression !== typeExpression || node.fullName !== fullName @@ -4592,14 +3956,14 @@ namespace ts { } // @api - function createJSDocAugmentsTag(tagName: Identifier | undefined, className: JSDocAugmentsTag["class"], comment?: string | NodeArray): JSDocAugmentsTag { - const node = createBaseJSDocTag(SyntaxKind.JSDocAugmentsTag, tagName ?? createIdentifier("augments"), comment); + function createJSDocAugmentsTag(tagName: ts.Identifier | undefined, className: ts.JSDocAugmentsTag["class"], comment?: string | ts.NodeArray): ts.JSDocAugmentsTag { + const node = createBaseJSDocTag(ts.SyntaxKind.JSDocAugmentsTag, tagName ?? createIdentifier("augments"), comment); node.class = className; return node; } // @api - function updateJSDocAugmentsTag(node: JSDocAugmentsTag, tagName: Identifier = getDefaultTagName(node), className: JSDocAugmentsTag["class"], comment: string | NodeArray | undefined): JSDocAugmentsTag { + function updateJSDocAugmentsTag(node: ts.JSDocAugmentsTag, tagName: ts.Identifier = getDefaultTagName(node), className: ts.JSDocAugmentsTag["class"], comment: string | ts.NodeArray | undefined): ts.JSDocAugmentsTag { return node.tagName !== tagName || node.class !== className || node.comment !== comment @@ -4608,21 +3972,21 @@ namespace ts { } // @api - function createJSDocImplementsTag(tagName: Identifier | undefined, className: JSDocImplementsTag["class"], comment?: string | NodeArray): JSDocImplementsTag { - const node = createBaseJSDocTag(SyntaxKind.JSDocImplementsTag, tagName ?? createIdentifier("implements"), comment); + function createJSDocImplementsTag(tagName: ts.Identifier | undefined, className: ts.JSDocImplementsTag["class"], comment?: string | ts.NodeArray): ts.JSDocImplementsTag { + const node = createBaseJSDocTag(ts.SyntaxKind.JSDocImplementsTag, tagName ?? createIdentifier("implements"), comment); node.class = className; return node; } // @api - function createJSDocSeeTag(tagName: Identifier | undefined, name: JSDocNameReference | undefined, comment?: string | NodeArray): JSDocSeeTag { - const node = createBaseJSDocTag(SyntaxKind.JSDocSeeTag, tagName ?? createIdentifier("see"), comment); + function createJSDocSeeTag(tagName: ts.Identifier | undefined, name: ts.JSDocNameReference | undefined, comment?: string | ts.NodeArray): ts.JSDocSeeTag { + const node = createBaseJSDocTag(ts.SyntaxKind.JSDocSeeTag, tagName ?? createIdentifier("see"), comment); node.name = name; return node; } // @api - function updateJSDocSeeTag(node: JSDocSeeTag, tagName: Identifier | undefined, name: JSDocNameReference | undefined, comment?: string | NodeArray): JSDocSeeTag { + function updateJSDocSeeTag(node: ts.JSDocSeeTag, tagName: ts.Identifier | undefined, name: ts.JSDocNameReference | undefined, comment?: string | ts.NodeArray): ts.JSDocSeeTag { return node.tagName !== tagName || node.name !== name || node.comment !== comment @@ -4631,22 +3995,22 @@ namespace ts { } // @api - function createJSDocNameReference(name: EntityName | JSDocMemberName): JSDocNameReference { - const node = createBaseNode(SyntaxKind.JSDocNameReference); + function createJSDocNameReference(name: ts.EntityName | ts.JSDocMemberName): ts.JSDocNameReference { + const node = createBaseNode(ts.SyntaxKind.JSDocNameReference); node.name = name; return node; } // @api - function updateJSDocNameReference(node: JSDocNameReference, name: EntityName | JSDocMemberName): JSDocNameReference { + function updateJSDocNameReference(node: ts.JSDocNameReference, name: ts.EntityName | ts.JSDocMemberName): ts.JSDocNameReference { return node.name !== name ? update(createJSDocNameReference(name), node) : node; } // @api - function createJSDocMemberName(left: EntityName | JSDocMemberName, right: Identifier) { - const node = createBaseNode(SyntaxKind.JSDocMemberName); + function createJSDocMemberName(left: ts.EntityName | ts.JSDocMemberName, right: ts.Identifier) { + const node = createBaseNode(ts.SyntaxKind.JSDocMemberName); node.left = left; node.right = right; node.transformFlags |= @@ -4656,7 +4020,7 @@ namespace ts { } // @api - function updateJSDocMemberName(node: JSDocMemberName, left: EntityName | JSDocMemberName, right: Identifier) { + function updateJSDocMemberName(node: ts.JSDocMemberName, left: ts.EntityName | ts.JSDocMemberName, right: ts.Identifier) { return node.left !== left || node.right !== right ? update(createJSDocMemberName(left, right), node) @@ -4664,52 +4028,52 @@ namespace ts { } // @api - function createJSDocLink(name: EntityName | JSDocMemberName | undefined, text: string): JSDocLink { - const node = createBaseNode(SyntaxKind.JSDocLink); + function createJSDocLink(name: ts.EntityName | ts.JSDocMemberName | undefined, text: string): ts.JSDocLink { + const node = createBaseNode(ts.SyntaxKind.JSDocLink); node.name = name; node.text = text; return node; } // @api - function updateJSDocLink(node: JSDocLink, name: EntityName | JSDocMemberName | undefined, text: string): JSDocLink { + function updateJSDocLink(node: ts.JSDocLink, name: ts.EntityName | ts.JSDocMemberName | undefined, text: string): ts.JSDocLink { return node.name !== name ? update(createJSDocLink(name, text), node) : node; } // @api - function createJSDocLinkCode(name: EntityName | JSDocMemberName | undefined, text: string): JSDocLinkCode { - const node = createBaseNode(SyntaxKind.JSDocLinkCode); + function createJSDocLinkCode(name: ts.EntityName | ts.JSDocMemberName | undefined, text: string): ts.JSDocLinkCode { + const node = createBaseNode(ts.SyntaxKind.JSDocLinkCode); node.name = name; node.text = text; return node; } // @api - function updateJSDocLinkCode(node: JSDocLinkCode, name: EntityName | JSDocMemberName | undefined, text: string): JSDocLinkCode { + function updateJSDocLinkCode(node: ts.JSDocLinkCode, name: ts.EntityName | ts.JSDocMemberName | undefined, text: string): ts.JSDocLinkCode { return node.name !== name ? update(createJSDocLinkCode(name, text), node) : node; } // @api - function createJSDocLinkPlain(name: EntityName | JSDocMemberName | undefined, text: string): JSDocLinkPlain { - const node = createBaseNode(SyntaxKind.JSDocLinkPlain); + function createJSDocLinkPlain(name: ts.EntityName | ts.JSDocMemberName | undefined, text: string): ts.JSDocLinkPlain { + const node = createBaseNode(ts.SyntaxKind.JSDocLinkPlain); node.name = name; node.text = text; return node; } // @api - function updateJSDocLinkPlain(node: JSDocLinkPlain, name: EntityName | JSDocMemberName | undefined, text: string): JSDocLinkPlain { + function updateJSDocLinkPlain(node: ts.JSDocLinkPlain, name: ts.EntityName | ts.JSDocMemberName | undefined, text: string): ts.JSDocLinkPlain { return node.name !== name ? update(createJSDocLinkPlain(name, text), node) : node; } // @api - function updateJSDocImplementsTag(node: JSDocImplementsTag, tagName: Identifier = getDefaultTagName(node), className: JSDocImplementsTag["class"], comment: string | NodeArray | undefined): JSDocImplementsTag { + function updateJSDocImplementsTag(node: ts.JSDocImplementsTag, tagName: ts.Identifier = getDefaultTagName(node), className: ts.JSDocImplementsTag["class"], comment: string | ts.NodeArray | undefined): ts.JSDocImplementsTag { return node.tagName !== tagName || node.class !== className || node.comment !== comment @@ -4725,7 +4089,7 @@ namespace ts { // createJSDocProtectedTag // createJSDocReadonlyTag // createJSDocDeprecatedTag - function createJSDocSimpleTagWorker(kind: T["kind"], tagName: Identifier | undefined, comment?: string | NodeArray) { + function createJSDocSimpleTagWorker(kind: T["kind"], tagName: ts.Identifier | undefined, comment?: string | ts.NodeArray) { const node = createBaseJSDocTag(kind, tagName ?? createIdentifier(getDefaultTagNameForKind(kind)), comment); return node; } @@ -4738,7 +4102,7 @@ namespace ts { // updateJSDocProtectedTag // updateJSDocReadonlyTag // updateJSDocDeprecatedTag - function updateJSDocSimpleTagWorker(kind: T["kind"], node: T, tagName: Identifier = getDefaultTagName(node), comment: string | NodeArray | undefined) { + function updateJSDocSimpleTagWorker(kind: T["kind"], node: T, tagName: ts.Identifier = getDefaultTagName(node), comment: string | ts.NodeArray | undefined) { return node.tagName !== tagName || node.comment !== comment ? update(createJSDocSimpleTagWorker(kind, tagName, comment), node) : @@ -4750,7 +4114,9 @@ namespace ts { // createJSDocReturnTag // createJSDocThisTag // createJSDocEnumTag - function createJSDocTypeLikeTagWorker(kind: T["kind"], tagName: Identifier | undefined, typeExpression?: JSDocTypeExpression, comment?: string | NodeArray) { + function createJSDocTypeLikeTagWorker(kind: T["kind"], tagName: ts.Identifier | undefined, typeExpression?: ts.JSDocTypeExpression, comment?: string | ts.NodeArray) { const node = createBaseJSDocTag(kind, tagName ?? createIdentifier(getDefaultTagNameForKind(kind)), comment); node.typeExpression = typeExpression; return node; @@ -4761,7 +4127,9 @@ namespace ts { // updateJSDocReturnTag // updateJSDocThisTag // updateJSDocEnumTag - function updateJSDocTypeLikeTagWorker(kind: T["kind"], node: T, tagName: Identifier = getDefaultTagName(node), typeExpression: JSDocTypeExpression | undefined, comment: string | NodeArray | undefined) { + function updateJSDocTypeLikeTagWorker(kind: T["kind"], node: T, tagName: ts.Identifier = getDefaultTagName(node), typeExpression: ts.JSDocTypeExpression | undefined, comment: string | ts.NodeArray | undefined) { return node.tagName !== tagName || node.typeExpression !== typeExpression || node.comment !== comment @@ -4770,13 +4138,13 @@ namespace ts { } // @api - function createJSDocUnknownTag(tagName: Identifier, comment?: string | NodeArray): JSDocUnknownTag { - const node = createBaseJSDocTag(SyntaxKind.JSDocTag, tagName, comment); + function createJSDocUnknownTag(tagName: ts.Identifier, comment?: string | ts.NodeArray): ts.JSDocUnknownTag { + const node = createBaseJSDocTag(ts.SyntaxKind.JSDocTag, tagName, comment); return node; } // @api - function updateJSDocUnknownTag(node: JSDocUnknownTag, tagName: Identifier, comment: string | NodeArray | undefined): JSDocUnknownTag { + function updateJSDocUnknownTag(node: ts.JSDocUnknownTag, tagName: ts.Identifier, comment: string | ts.NodeArray | undefined): ts.JSDocUnknownTag { return node.tagName !== tagName || node.comment !== comment ? update(createJSDocUnknownTag(tagName, comment), node) @@ -4784,29 +4152,29 @@ namespace ts { } // @api - function createJSDocText(text: string): JSDocText { - const node = createBaseNode(SyntaxKind.JSDocText); + function createJSDocText(text: string): ts.JSDocText { + const node = createBaseNode(ts.SyntaxKind.JSDocText); node.text = text; return node; } // @api - function updateJSDocText(node: JSDocText, text: string): JSDocText { + function updateJSDocText(node: ts.JSDocText, text: string): ts.JSDocText { return node.text !== text ? update(createJSDocText(text), node) : node; } // @api - function createJSDocComment(comment?: string | NodeArray | undefined, tags?: readonly JSDocTag[] | undefined) { - const node = createBaseNode(SyntaxKind.JSDoc); + function createJSDocComment(comment?: string | ts.NodeArray | undefined, tags?: readonly ts.JSDocTag[] | undefined) { + const node = createBaseNode(ts.SyntaxKind.JSDoc); node.comment = comment; node.tags = asNodeArray(tags); return node; } // @api - function updateJSDocComment(node: JSDoc, comment: string | NodeArray | undefined, tags: readonly JSDocTag[] | undefined) { + function updateJSDocComment(node: ts.JSDoc, comment: string | ts.NodeArray | undefined, tags: readonly ts.JSDocTag[] | undefined) { return node.comment !== comment || node.tags !== tags ? update(createJSDocComment(comment, tags), node) @@ -4818,8 +4186,8 @@ namespace ts { // // @api - function createJsxElement(openingElement: JsxOpeningElement, children: readonly JsxChild[], closingElement: JsxClosingElement) { - const node = createBaseNode(SyntaxKind.JsxElement); + function createJsxElement(openingElement: ts.JsxOpeningElement, children: readonly ts.JsxChild[], closingElement: ts.JsxClosingElement) { + const node = createBaseNode(ts.SyntaxKind.JsxElement); node.openingElement = openingElement; node.children = createNodeArray(children); node.closingElement = closingElement; @@ -4827,12 +4195,12 @@ namespace ts { propagateChildFlags(node.openingElement) | propagateChildrenFlags(node.children) | propagateChildFlags(node.closingElement) | - TransformFlags.ContainsJsx; + ts.TransformFlags.ContainsJsx; return node; } // @api - function updateJsxElement(node: JsxElement, openingElement: JsxOpeningElement, children: readonly JsxChild[], closingElement: JsxClosingElement) { + function updateJsxElement(node: ts.JsxElement, openingElement: ts.JsxOpeningElement, children: readonly ts.JsxChild[], closingElement: ts.JsxClosingElement) { return node.openingElement !== openingElement || node.children !== children || node.closingElement !== closingElement @@ -4841,8 +4209,8 @@ namespace ts { } // @api - function createJsxSelfClosingElement(tagName: JsxTagNameExpression, typeArguments: readonly TypeNode[] | undefined, attributes: JsxAttributes) { - const node = createBaseNode(SyntaxKind.JsxSelfClosingElement); + function createJsxSelfClosingElement(tagName: ts.JsxTagNameExpression, typeArguments: readonly ts.TypeNode[] | undefined, attributes: ts.JsxAttributes) { + const node = createBaseNode(ts.SyntaxKind.JsxSelfClosingElement); node.tagName = tagName; node.typeArguments = asNodeArray(typeArguments); node.attributes = attributes; @@ -4850,15 +4218,15 @@ namespace ts { propagateChildFlags(node.tagName) | propagateChildrenFlags(node.typeArguments) | propagateChildFlags(node.attributes) | - TransformFlags.ContainsJsx; + ts.TransformFlags.ContainsJsx; if (node.typeArguments) { - node.transformFlags |= TransformFlags.ContainsTypeScript; + node.transformFlags |= ts.TransformFlags.ContainsTypeScript; } return node; } // @api - function updateJsxSelfClosingElement(node: JsxSelfClosingElement, tagName: JsxTagNameExpression, typeArguments: readonly TypeNode[] | undefined, attributes: JsxAttributes) { + function updateJsxSelfClosingElement(node: ts.JsxSelfClosingElement, tagName: ts.JsxTagNameExpression, typeArguments: readonly ts.TypeNode[] | undefined, attributes: ts.JsxAttributes) { return node.tagName !== tagName || node.typeArguments !== typeArguments || node.attributes !== attributes @@ -4867,8 +4235,8 @@ namespace ts { } // @api - function createJsxOpeningElement(tagName: JsxTagNameExpression, typeArguments: readonly TypeNode[] | undefined, attributes: JsxAttributes) { - const node = createBaseNode(SyntaxKind.JsxOpeningElement); + function createJsxOpeningElement(tagName: ts.JsxTagNameExpression, typeArguments: readonly ts.TypeNode[] | undefined, attributes: ts.JsxAttributes) { + const node = createBaseNode(ts.SyntaxKind.JsxOpeningElement); node.tagName = tagName; node.typeArguments = asNodeArray(typeArguments); node.attributes = attributes; @@ -4876,15 +4244,15 @@ namespace ts { propagateChildFlags(node.tagName) | propagateChildrenFlags(node.typeArguments) | propagateChildFlags(node.attributes) | - TransformFlags.ContainsJsx; + ts.TransformFlags.ContainsJsx; if (typeArguments) { - node.transformFlags |= TransformFlags.ContainsTypeScript; + node.transformFlags |= ts.TransformFlags.ContainsTypeScript; } return node; } // @api - function updateJsxOpeningElement(node: JsxOpeningElement, tagName: JsxTagNameExpression, typeArguments: readonly TypeNode[] | undefined, attributes: JsxAttributes) { + function updateJsxOpeningElement(node: ts.JsxOpeningElement, tagName: ts.JsxTagNameExpression, typeArguments: readonly ts.TypeNode[] | undefined, attributes: ts.JsxAttributes) { return node.tagName !== tagName || node.typeArguments !== typeArguments || node.attributes !== attributes @@ -4893,25 +4261,25 @@ namespace ts { } // @api - function createJsxClosingElement(tagName: JsxTagNameExpression) { - const node = createBaseNode(SyntaxKind.JsxClosingElement); + function createJsxClosingElement(tagName: ts.JsxTagNameExpression) { + const node = createBaseNode(ts.SyntaxKind.JsxClosingElement); node.tagName = tagName; node.transformFlags |= propagateChildFlags(node.tagName) | - TransformFlags.ContainsJsx; + ts.TransformFlags.ContainsJsx; return node; } // @api - function updateJsxClosingElement(node: JsxClosingElement, tagName: JsxTagNameExpression) { + function updateJsxClosingElement(node: ts.JsxClosingElement, tagName: ts.JsxTagNameExpression) { return node.tagName !== tagName ? update(createJsxClosingElement(tagName), node) : node; } // @api - function createJsxFragment(openingFragment: JsxOpeningFragment, children: readonly JsxChild[], closingFragment: JsxClosingFragment) { - const node = createBaseNode(SyntaxKind.JsxFragment); + function createJsxFragment(openingFragment: ts.JsxOpeningFragment, children: readonly ts.JsxChild[], closingFragment: ts.JsxClosingFragment) { + const node = createBaseNode(ts.SyntaxKind.JsxFragment); node.openingFragment = openingFragment; node.children = createNodeArray(children); node.closingFragment = closingFragment; @@ -4919,12 +4287,12 @@ namespace ts { propagateChildFlags(node.openingFragment) | propagateChildrenFlags(node.children) | propagateChildFlags(node.closingFragment) | - TransformFlags.ContainsJsx; + ts.TransformFlags.ContainsJsx; return node; } // @api - function updateJsxFragment(node: JsxFragment, openingFragment: JsxOpeningFragment, children: readonly JsxChild[], closingFragment: JsxClosingFragment) { + function updateJsxFragment(node: ts.JsxFragment, openingFragment: ts.JsxOpeningFragment, children: readonly ts.JsxChild[], closingFragment: ts.JsxClosingFragment) { return node.openingFragment !== openingFragment || node.children !== children || node.closingFragment !== closingFragment @@ -4934,15 +4302,15 @@ namespace ts { // @api function createJsxText(text: string, containsOnlyTriviaWhiteSpaces?: boolean) { - const node = createBaseNode(SyntaxKind.JsxText); + const node = createBaseNode(ts.SyntaxKind.JsxText); node.text = text; node.containsOnlyTriviaWhiteSpaces = !!containsOnlyTriviaWhiteSpaces; - node.transformFlags |= TransformFlags.ContainsJsx; + node.transformFlags |= ts.TransformFlags.ContainsJsx; return node; } // @api - function updateJsxText(node: JsxText, text: string, containsOnlyTriviaWhiteSpaces?: boolean) { + function updateJsxText(node: ts.JsxText, text: string, containsOnlyTriviaWhiteSpaces?: boolean) { return node.text !== text || node.containsOnlyTriviaWhiteSpaces !== containsOnlyTriviaWhiteSpaces ? update(createJsxText(text, containsOnlyTriviaWhiteSpaces), node) @@ -4951,32 +4319,32 @@ namespace ts { // @api function createJsxOpeningFragment() { - const node = createBaseNode(SyntaxKind.JsxOpeningFragment); - node.transformFlags |= TransformFlags.ContainsJsx; + const node = createBaseNode(ts.SyntaxKind.JsxOpeningFragment); + node.transformFlags |= ts.TransformFlags.ContainsJsx; return node; } // @api function createJsxJsxClosingFragment() { - const node = createBaseNode(SyntaxKind.JsxClosingFragment); - node.transformFlags |= TransformFlags.ContainsJsx; + const node = createBaseNode(ts.SyntaxKind.JsxClosingFragment); + node.transformFlags |= ts.TransformFlags.ContainsJsx; return node; } // @api - function createJsxAttribute(name: Identifier, initializer: JsxAttributeValue | undefined) { - const node = createBaseNode(SyntaxKind.JsxAttribute); + function createJsxAttribute(name: ts.Identifier, initializer: ts.JsxAttributeValue | undefined) { + const node = createBaseNode(ts.SyntaxKind.JsxAttribute); node.name = name; node.initializer = initializer; node.transformFlags |= propagateChildFlags(node.name) | propagateChildFlags(node.initializer) | - TransformFlags.ContainsJsx; + ts.TransformFlags.ContainsJsx; return node; } // @api - function updateJsxAttribute(node: JsxAttribute, name: Identifier, initializer: JsxAttributeValue | undefined) { + function updateJsxAttribute(node: ts.JsxAttribute, name: ts.Identifier, initializer: ts.JsxAttributeValue | undefined) { return node.name !== name || node.initializer !== initializer ? update(createJsxAttribute(name, initializer), node) @@ -4984,53 +4352,53 @@ namespace ts { } // @api - function createJsxAttributes(properties: readonly JsxAttributeLike[]) { - const node = createBaseNode(SyntaxKind.JsxAttributes); + function createJsxAttributes(properties: readonly ts.JsxAttributeLike[]) { + const node = createBaseNode(ts.SyntaxKind.JsxAttributes); node.properties = createNodeArray(properties); node.transformFlags |= propagateChildrenFlags(node.properties) | - TransformFlags.ContainsJsx; + ts.TransformFlags.ContainsJsx; return node; } // @api - function updateJsxAttributes(node: JsxAttributes, properties: readonly JsxAttributeLike[]) { + function updateJsxAttributes(node: ts.JsxAttributes, properties: readonly ts.JsxAttributeLike[]) { return node.properties !== properties ? update(createJsxAttributes(properties), node) : node; } // @api - function createJsxSpreadAttribute(expression: Expression) { - const node = createBaseNode(SyntaxKind.JsxSpreadAttribute); + function createJsxSpreadAttribute(expression: ts.Expression) { + const node = createBaseNode(ts.SyntaxKind.JsxSpreadAttribute); node.expression = expression; node.transformFlags |= propagateChildFlags(node.expression) | - TransformFlags.ContainsJsx; + ts.TransformFlags.ContainsJsx; return node; } // @api - function updateJsxSpreadAttribute(node: JsxSpreadAttribute, expression: Expression) { + function updateJsxSpreadAttribute(node: ts.JsxSpreadAttribute, expression: ts.Expression) { return node.expression !== expression ? update(createJsxSpreadAttribute(expression), node) : node; } // @api - function createJsxExpression(dotDotDotToken: DotDotDotToken | undefined, expression: Expression | undefined) { - const node = createBaseNode(SyntaxKind.JsxExpression); + function createJsxExpression(dotDotDotToken: ts.DotDotDotToken | undefined, expression: ts.Expression | undefined) { + const node = createBaseNode(ts.SyntaxKind.JsxExpression); node.dotDotDotToken = dotDotDotToken; node.expression = expression; node.transformFlags |= propagateChildFlags(node.dotDotDotToken) | propagateChildFlags(node.expression) | - TransformFlags.ContainsJsx; + ts.TransformFlags.ContainsJsx; return node; } // @api - function updateJsxExpression(node: JsxExpression, expression: Expression | undefined) { + function updateJsxExpression(node: ts.JsxExpression, expression: ts.Expression | undefined) { return node.expression !== expression ? update(createJsxExpression(node.dotDotDotToken, expression), node) : node; @@ -5041,8 +4409,8 @@ namespace ts { // // @api - function createCaseClause(expression: Expression, statements: readonly Statement[]) { - const node = createBaseNode(SyntaxKind.CaseClause); + function createCaseClause(expression: ts.Expression, statements: readonly ts.Statement[]) { + const node = createBaseNode(ts.SyntaxKind.CaseClause); node.expression = parenthesizerRules().parenthesizeExpressionForDisallowedComma(expression); node.statements = createNodeArray(statements); node.transformFlags |= @@ -5052,7 +4420,7 @@ namespace ts { } // @api - function updateCaseClause(node: CaseClause, expression: Expression, statements: readonly Statement[]) { + function updateCaseClause(node: ts.CaseClause, expression: ts.Expression, statements: readonly ts.Statement[]) { return node.expression !== expression || node.statements !== statements ? update(createCaseClause(expression, statements), node) @@ -5060,68 +4428,67 @@ namespace ts { } // @api - function createDefaultClause(statements: readonly Statement[]) { - const node = createBaseNode(SyntaxKind.DefaultClause); + function createDefaultClause(statements: readonly ts.Statement[]) { + const node = createBaseNode(ts.SyntaxKind.DefaultClause); node.statements = createNodeArray(statements); node.transformFlags = propagateChildrenFlags(node.statements); return node; } // @api - function updateDefaultClause(node: DefaultClause, statements: readonly Statement[]) { + function updateDefaultClause(node: ts.DefaultClause, statements: readonly ts.Statement[]) { return node.statements !== statements ? update(createDefaultClause(statements), node) : node; } // @api - function createHeritageClause(token: HeritageClause["token"], types: readonly ExpressionWithTypeArguments[]) { - const node = createBaseNode(SyntaxKind.HeritageClause); + function createHeritageClause(token: ts.HeritageClause["token"], types: readonly ts.ExpressionWithTypeArguments[]) { + const node = createBaseNode(ts.SyntaxKind.HeritageClause); node.token = token; node.types = createNodeArray(types); node.transformFlags |= propagateChildrenFlags(node.types); switch (token) { - case SyntaxKind.ExtendsKeyword: - node.transformFlags |= TransformFlags.ContainsES2015; + case ts.SyntaxKind.ExtendsKeyword: + node.transformFlags |= ts.TransformFlags.ContainsES2015; break; - case SyntaxKind.ImplementsKeyword: - node.transformFlags |= TransformFlags.ContainsTypeScript; + case ts.SyntaxKind.ImplementsKeyword: + node.transformFlags |= ts.TransformFlags.ContainsTypeScript; break; default: - return Debug.assertNever(token); + return ts.Debug.assertNever(token); } return node; } // @api - function updateHeritageClause(node: HeritageClause, types: readonly ExpressionWithTypeArguments[]) { + function updateHeritageClause(node: ts.HeritageClause, types: readonly ts.ExpressionWithTypeArguments[]) { return node.types !== types ? update(createHeritageClause(node.token, types), node) : node; } // @api - function createCatchClause(variableDeclaration: string | BindingName | VariableDeclaration | undefined, block: Block) { - const node = createBaseNode(SyntaxKind.CatchClause); - if (typeof variableDeclaration === "string" || variableDeclaration && !isVariableDeclaration(variableDeclaration)) { - variableDeclaration = createVariableDeclaration( - variableDeclaration, + function createCatchClause(variableDeclaration: string | ts.BindingName | ts.VariableDeclaration | undefined, block: ts.Block) { + const node = createBaseNode(ts.SyntaxKind.CatchClause); + if (typeof variableDeclaration === "string" || variableDeclaration && !ts.isVariableDeclaration(variableDeclaration)) { + variableDeclaration = createVariableDeclaration(variableDeclaration, /*exclamationToken*/ undefined, /*type*/ undefined, - /*initializer*/ undefined - ); + /*initializer*/ undefined); } node.variableDeclaration = variableDeclaration; node.block = block; node.transformFlags |= propagateChildFlags(node.variableDeclaration) | propagateChildFlags(node.block); - if (!variableDeclaration) node.transformFlags |= TransformFlags.ContainsES2019; + if (!variableDeclaration) + node.transformFlags |= ts.TransformFlags.ContainsES2019; return node; } // @api - function updateCatchClause(node: CatchClause, variableDeclaration: VariableDeclaration | undefined, block: Block) { + function updateCatchClause(node: ts.CatchClause, variableDeclaration: ts.VariableDeclaration | undefined, block: ts.Block) { return node.variableDeclaration !== variableDeclaration || node.block !== block ? update(createCatchClause(variableDeclaration, block), node) @@ -5133,13 +4500,10 @@ namespace ts { // // @api - function createPropertyAssignment(name: string | PropertyName, initializer: Expression) { - const node = createBaseNamedDeclaration( - SyntaxKind.PropertyAssignment, + function createPropertyAssignment(name: string | ts.PropertyName, initializer: ts.Expression) { + const node = createBaseNamedDeclaration(ts.SyntaxKind.PropertyAssignment, /*decorators*/ undefined, - /*modifiers*/ undefined, - name - ); + /*modifiers*/ undefined, name); node.initializer = parenthesizerRules().parenthesizeExpressionForDisallowedComma(initializer); node.transformFlags |= propagateChildFlags(node.name) | @@ -5147,17 +4511,21 @@ namespace ts { return node; } - function finishUpdatePropertyAssignment(updated: Mutable, original: PropertyAssignment) { + function finishUpdatePropertyAssignment(updated: ts.Mutable, original: ts.PropertyAssignment) { // copy children used only for error reporting - if (original.decorators) updated.decorators = original.decorators; - if (original.modifiers) updated.modifiers = original.modifiers; - if (original.questionToken) updated.questionToken = original.questionToken; - if (original.exclamationToken) updated.exclamationToken = original.exclamationToken; + if (original.decorators) + updated.decorators = original.decorators; + if (original.modifiers) + updated.modifiers = original.modifiers; + if (original.questionToken) + updated.questionToken = original.questionToken; + if (original.exclamationToken) + updated.exclamationToken = original.exclamationToken; return update(updated, original); } // @api - function updatePropertyAssignment(node: PropertyAssignment, name: PropertyName, initializer: Expression) { + function updatePropertyAssignment(node: ts.PropertyAssignment, name: ts.PropertyName, initializer: ts.Expression) { return node.name !== name || node.initializer !== initializer ? finishUpdatePropertyAssignment(createPropertyAssignment(name, initializer), node) @@ -5165,32 +4533,34 @@ namespace ts { } // @api - function createShorthandPropertyAssignment(name: string | Identifier, objectAssignmentInitializer?: Expression) { - const node = createBaseNamedDeclaration( - SyntaxKind.ShorthandPropertyAssignment, + function createShorthandPropertyAssignment(name: string | ts.Identifier, objectAssignmentInitializer?: ts.Expression) { + const node = createBaseNamedDeclaration(ts.SyntaxKind.ShorthandPropertyAssignment, /*decorators*/ undefined, - /*modifiers*/ undefined, - name - ); + /*modifiers*/ undefined, name); node.objectAssignmentInitializer = objectAssignmentInitializer && parenthesizerRules().parenthesizeExpressionForDisallowedComma(objectAssignmentInitializer); node.transformFlags |= propagateChildFlags(node.objectAssignmentInitializer) | - TransformFlags.ContainsES2015; + ts.TransformFlags.ContainsES2015; return node; } - function finishUpdateShorthandPropertyAssignment(updated: Mutable, original: ShorthandPropertyAssignment) { + function finishUpdateShorthandPropertyAssignment(updated: ts.Mutable, original: ts.ShorthandPropertyAssignment) { // copy children used only for error reporting - if (original.decorators) updated.decorators = original.decorators; - if (original.modifiers) updated.modifiers = original.modifiers; - if (original.equalsToken) updated.equalsToken = original.equalsToken; - if (original.questionToken) updated.questionToken = original.questionToken; - if (original.exclamationToken) updated.exclamationToken = original.exclamationToken; + if (original.decorators) + updated.decorators = original.decorators; + if (original.modifiers) + updated.modifiers = original.modifiers; + if (original.equalsToken) + updated.equalsToken = original.equalsToken; + if (original.questionToken) + updated.questionToken = original.questionToken; + if (original.exclamationToken) + updated.exclamationToken = original.exclamationToken; return update(updated, original); } // @api - function updateShorthandPropertyAssignment(node: ShorthandPropertyAssignment, name: Identifier, objectAssignmentInitializer: Expression | undefined) { + function updateShorthandPropertyAssignment(node: ts.ShorthandPropertyAssignment, name: ts.Identifier, objectAssignmentInitializer: ts.Expression | undefined) { return node.name !== name || node.objectAssignmentInitializer !== objectAssignmentInitializer ? finishUpdateShorthandPropertyAssignment(createShorthandPropertyAssignment(name, objectAssignmentInitializer), node) @@ -5198,18 +4568,18 @@ namespace ts { } // @api - function createSpreadAssignment(expression: Expression) { - const node = createBaseNode(SyntaxKind.SpreadAssignment); + function createSpreadAssignment(expression: ts.Expression) { + const node = createBaseNode(ts.SyntaxKind.SpreadAssignment); node.expression = parenthesizerRules().parenthesizeExpressionForDisallowedComma(expression); node.transformFlags |= propagateChildFlags(node.expression) | - TransformFlags.ContainsES2018 | - TransformFlags.ContainsObjectRestOrSpread; + ts.TransformFlags.ContainsES2018 | + ts.TransformFlags.ContainsObjectRestOrSpread; return node; } // @api - function updateSpreadAssignment(node: SpreadAssignment, expression: Expression) { + function updateSpreadAssignment(node: ts.SpreadAssignment, expression: ts.Expression) { return node.expression !== expression ? update(createSpreadAssignment(expression), node) : node; @@ -5220,19 +4590,19 @@ namespace ts { // // @api - function createEnumMember(name: string | PropertyName, initializer?: Expression) { - const node = createBaseNode(SyntaxKind.EnumMember); + function createEnumMember(name: string | ts.PropertyName, initializer?: ts.Expression) { + const node = createBaseNode(ts.SyntaxKind.EnumMember); node.name = asName(name); node.initializer = initializer && parenthesizerRules().parenthesizeExpressionForDisallowedComma(initializer); node.transformFlags |= propagateChildFlags(node.name) | propagateChildFlags(node.initializer) | - TransformFlags.ContainsTypeScript; + ts.TransformFlags.ContainsTypeScript; return node; } // @api - function updateEnumMember(node: EnumMember, name: PropertyName, initializer: Expression | undefined) { + function updateEnumMember(node: ts.EnumMember, name: ts.PropertyName, initializer: ts.Expression | undefined) { return node.name !== name || node.initializer !== initializer ? update(createEnumMember(name, initializer), node) @@ -5244,12 +4614,8 @@ namespace ts { // // @api - function createSourceFile( - statements: readonly Statement[], - endOfFileToken: EndOfFileToken, - flags: NodeFlags - ) { - const node = baseFactory.createBaseSourceFileNode(SyntaxKind.SourceFile) as Mutable; + function createSourceFile(statements: readonly ts.Statement[], endOfFileToken: ts.EndOfFileToken, flags: ts.NodeFlags) { + const node = baseFactory.createBaseSourceFileNode(ts.SyntaxKind.SourceFile) as ts.Mutable; node.statements = createNodeArray(statements); node.endOfFileToken = endOfFileToken; node.flags |= flags; @@ -5266,18 +4632,11 @@ namespace ts { return node; } - function cloneSourceFileWithChanges( - source: SourceFile, - statements: readonly Statement[], - isDeclarationFile: boolean, - referencedFiles: readonly FileReference[], - typeReferences: readonly FileReference[], - hasNoDefaultLib: boolean, - libReferences: readonly FileReference[] - ) { - const node = (source.redirectInfo ? Object.create(source.redirectInfo.redirectTarget) : baseFactory.createBaseSourceFileNode(SyntaxKind.SourceFile)) as Mutable; + function cloneSourceFileWithChanges(source: ts.SourceFile, statements: readonly ts.Statement[], isDeclarationFile: boolean, referencedFiles: readonly ts.FileReference[], typeReferences: readonly ts.FileReference[], hasNoDefaultLib: boolean, libReferences: readonly ts.FileReference[]) { + const node = (source.redirectInfo ? Object.create(source.redirectInfo.redirectTarget) : baseFactory.createBaseSourceFileNode(ts.SyntaxKind.SourceFile)) as ts.Mutable; for (const p in source) { - if (p === "emitNode" || hasProperty(node, p) || !hasProperty(source, p)) continue; + if (p === "emitNode" || ts.hasProperty(node, p) || !ts.hasProperty(source, p)) + continue; (node as any)[p] = (source as any)[p]; } node.flags |= source.flags; @@ -5296,15 +4655,7 @@ namespace ts { } // @api - function updateSourceFile( - node: SourceFile, - statements: readonly Statement[], - isDeclarationFile = node.isDeclarationFile, - referencedFiles = node.referencedFiles, - typeReferenceDirectives = node.typeReferenceDirectives, - hasNoDefaultLib = node.hasNoDefaultLib, - libReferenceDirectives = node.libReferenceDirectives - ) { + function updateSourceFile(node: ts.SourceFile, statements: readonly ts.Statement[], isDeclarationFile = node.isDeclarationFile, referencedFiles = node.referencedFiles, typeReferenceDirectives = node.typeReferenceDirectives, hasNoDefaultLib = node.hasNoDefaultLib, libReferenceDirectives = node.libReferenceDirectives) { return node.statements !== statements || node.isDeclarationFile !== isDeclarationFile || node.referencedFiles !== referencedFiles @@ -5316,15 +4667,15 @@ namespace ts { } // @api - function createBundle(sourceFiles: readonly SourceFile[], prepends: readonly (UnparsedSource | InputFiles)[] = emptyArray) { - const node = createBaseNode(SyntaxKind.Bundle); + function createBundle(sourceFiles: readonly ts.SourceFile[], prepends: readonly (ts.UnparsedSource | ts.InputFiles)[] = ts.emptyArray) { + const node = createBaseNode(ts.SyntaxKind.Bundle); node.prepends = prepends; node.sourceFiles = sourceFiles; return node; } // @api - function updateBundle(node: Bundle, sourceFiles: readonly SourceFile[], prepends: readonly (UnparsedSource | InputFiles)[] = emptyArray) { + function updateBundle(node: ts.Bundle, sourceFiles: readonly ts.SourceFile[], prepends: readonly (ts.UnparsedSource | ts.InputFiles)[] = ts.emptyArray) { return node.sourceFiles !== sourceFiles || node.prepends !== prepends ? update(createBundle(sourceFiles, prepends), node) @@ -5332,53 +4683,53 @@ namespace ts { } // @api - function createUnparsedSource(prologues: readonly UnparsedPrologue[], syntheticReferences: readonly UnparsedSyntheticReference[] | undefined, texts: readonly UnparsedSourceText[]) { - const node = createBaseNode(SyntaxKind.UnparsedSource); + function createUnparsedSource(prologues: readonly ts.UnparsedPrologue[], syntheticReferences: readonly ts.UnparsedSyntheticReference[] | undefined, texts: readonly ts.UnparsedSourceText[]) { + const node = createBaseNode(ts.SyntaxKind.UnparsedSource); node.prologues = prologues; node.syntheticReferences = syntheticReferences; node.texts = texts; node.fileName = ""; node.text = ""; - node.referencedFiles = emptyArray; - node.libReferenceDirectives = emptyArray; - node.getLineAndCharacterOfPosition = pos => getLineAndCharacterOfPosition(node, pos); + node.referencedFiles = ts.emptyArray; + node.libReferenceDirectives = ts.emptyArray; + node.getLineAndCharacterOfPosition = pos => ts.getLineAndCharacterOfPosition(node, pos); return node; } - function createBaseUnparsedNode(kind: T["kind"], data?: string) { + function createBaseUnparsedNode(kind: T["kind"], data?: string) { const node = createBaseNode(kind); node.data = data; return node; } // @api - function createUnparsedPrologue(data?: string): UnparsedPrologue { - return createBaseUnparsedNode(SyntaxKind.UnparsedPrologue, data); + function createUnparsedPrologue(data?: string): ts.UnparsedPrologue { + return createBaseUnparsedNode(ts.SyntaxKind.UnparsedPrologue, data); } // @api - function createUnparsedPrepend(data: string | undefined, texts: readonly UnparsedTextLike[]): UnparsedPrepend { - const node = createBaseUnparsedNode(SyntaxKind.UnparsedPrepend, data); + function createUnparsedPrepend(data: string | undefined, texts: readonly ts.UnparsedTextLike[]): ts.UnparsedPrepend { + const node = createBaseUnparsedNode(ts.SyntaxKind.UnparsedPrepend, data); node.texts = texts; return node; } // @api - function createUnparsedTextLike(data: string | undefined, internal: boolean): UnparsedTextLike { - return createBaseUnparsedNode(internal ? SyntaxKind.UnparsedInternalText : SyntaxKind.UnparsedText, data); + function createUnparsedTextLike(data: string | undefined, internal: boolean): ts.UnparsedTextLike { + return createBaseUnparsedNode(internal ? ts.SyntaxKind.UnparsedInternalText : ts.SyntaxKind.UnparsedText, data); } // @api - function createUnparsedSyntheticReference(section: BundleFileHasNoDefaultLib | BundleFileReference): UnparsedSyntheticReference { - const node = createBaseNode(SyntaxKind.UnparsedSyntheticReference); + function createUnparsedSyntheticReference(section: ts.BundleFileHasNoDefaultLib | ts.BundleFileReference): ts.UnparsedSyntheticReference { + const node = createBaseNode(ts.SyntaxKind.UnparsedSyntheticReference); node.data = section.data; node.section = section; return node; } // @api - function createInputFiles(): InputFiles { - const node = createBaseNode(SyntaxKind.InputFiles); + function createInputFiles(): ts.InputFiles { + const node = createBaseNode(ts.SyntaxKind.InputFiles); node.javascriptText = ""; node.declarationText = ""; return node; @@ -5389,8 +4740,8 @@ namespace ts { // // @api - function createSyntheticExpression(type: Type, isSpread = false, tupleNameSource?: ParameterDeclaration | NamedTupleMember) { - const node = createBaseNode(SyntaxKind.SyntheticExpression); + function createSyntheticExpression(type: ts.Type, isSpread = false, tupleNameSource?: ts.ParameterDeclaration | ts.NamedTupleMember) { + const node = createBaseNode(ts.SyntaxKind.SyntheticExpression); node.type = type; node.isSpread = isSpread; node.tupleNameSource = tupleNameSource; @@ -5398,8 +4749,8 @@ namespace ts { } // @api - function createSyntaxList(children: Node[]) { - const node = createBaseNode(SyntaxKind.SyntaxList); + function createSyntaxList(children: ts.Node[]) { + const node = createBaseNode(ts.SyntaxKind.SyntaxList); node._children = children; return node; } @@ -5415,10 +4766,10 @@ namespace ts { * @param original The original statement. */ // @api - function createNotEmittedStatement(original: Node) { - const node = createBaseNode(SyntaxKind.NotEmittedStatement); + function createNotEmittedStatement(original: ts.Node) { + const node = createBaseNode(ts.SyntaxKind.NotEmittedStatement); node.original = original; - setTextRange(node, original); + ts.setTextRange(node, original); return node; } @@ -5430,30 +4781,30 @@ namespace ts { * @param original The original outer expression. */ // @api - function createPartiallyEmittedExpression(expression: Expression, original?: Node) { - const node = createBaseNode(SyntaxKind.PartiallyEmittedExpression); + function createPartiallyEmittedExpression(expression: ts.Expression, original?: ts.Node) { + const node = createBaseNode(ts.SyntaxKind.PartiallyEmittedExpression); node.expression = expression; node.original = original; node.transformFlags |= propagateChildFlags(node.expression) | - TransformFlags.ContainsTypeScript; - setTextRange(node, original); + ts.TransformFlags.ContainsTypeScript; + ts.setTextRange(node, original); return node; } // @api - function updatePartiallyEmittedExpression(node: PartiallyEmittedExpression, expression: Expression) { + function updatePartiallyEmittedExpression(node: ts.PartiallyEmittedExpression, expression: ts.Expression) { return node.expression !== expression ? update(createPartiallyEmittedExpression(expression, node.original), node) : node; } - function flattenCommaElements(node: Expression): Expression | readonly Expression[] { - if (nodeIsSynthesized(node) && !isParseTreeNode(node) && !node.original && !node.emitNode && !node.id) { - if (isCommaListExpression(node)) { + function flattenCommaElements(node: ts.Expression): ts.Expression | readonly ts.Expression[] { + if (ts.nodeIsSynthesized(node) && !ts.isParseTreeNode(node) && !node.original && !node.emitNode && !node.id) { + if (ts.isCommaListExpression(node)) { return node.elements; } - if (isBinaryExpression(node) && isCommaToken(node.operatorToken)) { + if (ts.isBinaryExpression(node) && ts.isCommaToken(node.operatorToken)) { return [node.left, node.right]; } } @@ -5461,15 +4812,15 @@ namespace ts { } // @api - function createCommaListExpression(elements: readonly Expression[]) { - const node = createBaseNode(SyntaxKind.CommaListExpression); - node.elements = createNodeArray(sameFlatMap(elements, flattenCommaElements)); + function createCommaListExpression(elements: readonly ts.Expression[]) { + const node = createBaseNode(ts.SyntaxKind.CommaListExpression); + node.elements = createNodeArray(ts.sameFlatMap(elements, flattenCommaElements)); node.transformFlags |= propagateChildrenFlags(node.elements); return node; } // @api - function updateCommaListExpression(node: CommaListExpression, elements: readonly Expression[]) { + function updateCommaListExpression(node: ts.CommaListExpression, elements: readonly ts.Expression[]) { return node.elements !== elements ? update(createCommaListExpression(elements), node) : node; @@ -5480,9 +4831,9 @@ namespace ts { * order to properly emit exports. */ // @api - function createEndOfDeclarationMarker(original: Node) { - const node = createBaseNode(SyntaxKind.EndOfDeclarationMarker); - node.emitNode = {} as EmitNode; + function createEndOfDeclarationMarker(original: ts.Node) { + const node = createBaseNode(ts.SyntaxKind.EndOfDeclarationMarker); + node.emitNode = {} as ts.EmitNode; node.original = original; return node; } @@ -5492,16 +4843,16 @@ namespace ts { * order to properly emit exports. */ // @api - function createMergeDeclarationMarker(original: Node) { - const node = createBaseNode(SyntaxKind.MergeDeclarationMarker); - node.emitNode = {} as EmitNode; + function createMergeDeclarationMarker(original: ts.Node) { + const node = createBaseNode(ts.SyntaxKind.MergeDeclarationMarker); + node.emitNode = {} as ts.EmitNode; node.original = original; return node; } // @api - function createSyntheticReferenceExpression(expression: Expression, thisArg: Expression) { - const node = createBaseNode(SyntaxKind.SyntheticReferenceExpression); + function createSyntheticReferenceExpression(expression: ts.Expression, thisArg: ts.Expression) { + const node = createBaseNode(ts.SyntaxKind.SyntheticReferenceExpression); node.expression = expression; node.thisArg = thisArg; node.transformFlags |= @@ -5511,7 +4862,7 @@ namespace ts { } // @api - function updateSyntheticReferenceExpression(node: SyntheticReferenceExpression, expression: Expression, thisArg: Expression) { + function updateSyntheticReferenceExpression(node: ts.SyntheticReferenceExpression, expression: ts.Expression, thisArg: ts.Expression) { return node.expression !== expression || node.thisArg !== thisArg ? update(createSyntheticReferenceExpression(expression, thisArg), node) @@ -5519,8 +4870,8 @@ namespace ts { } // @api - function cloneNode(node: T): T; - function cloneNode(node: T) { + function cloneNode(node: T): T; + function cloneNode(node: T) { // We don't use "clone" from core.ts here, as we need to preserve the prototype chain of // the original node. We also need to exclude specific properties and only include own- // properties (to skip members already defined on the shared prototype). @@ -5528,15 +4879,14 @@ namespace ts { return node; } - const clone = - isSourceFile(node) ? baseFactory.createBaseSourceFileNode(SyntaxKind.SourceFile) as T : - isIdentifier(node) ? baseFactory.createBaseIdentifierNode(SyntaxKind.Identifier) as T : - isPrivateIdentifier(node) ? baseFactory.createBasePrivateIdentifierNode(SyntaxKind.PrivateIdentifier) as T : - !isNodeKind(node.kind) ? baseFactory.createBaseTokenNode(node.kind) as T : + const clone = ts.isSourceFile(node) ? baseFactory.createBaseSourceFileNode(ts.SyntaxKind.SourceFile) as T : + ts.isIdentifier(node) ? baseFactory.createBaseIdentifierNode(ts.SyntaxKind.Identifier) as T : + ts.isPrivateIdentifier(node) ? baseFactory.createBasePrivateIdentifierNode(ts.SyntaxKind.PrivateIdentifier) as T : + !ts.isNodeKind(node.kind) ? baseFactory.createBaseTokenNode(node.kind) as T : baseFactory.createBaseNode(node.kind) as T; - (clone as Mutable).flags |= (node.flags & ~NodeFlags.Synthesized); - (clone as Mutable).transformFlags = node.transformFlags; + (clone as ts.Mutable).flags |= (node.flags & ~ts.NodeFlags.Synthesized); + (clone as ts.Mutable).transformFlags = node.transformFlags; setOriginalNode(clone, node); for (const key in node) { @@ -5551,128 +4901,110 @@ namespace ts { } // compound nodes - function createImmediatelyInvokedFunctionExpression(statements: readonly Statement[]): CallExpression; - function createImmediatelyInvokedFunctionExpression(statements: readonly Statement[], param: ParameterDeclaration, paramValue: Expression): CallExpression; - function createImmediatelyInvokedFunctionExpression(statements: readonly Statement[], param?: ParameterDeclaration, paramValue?: Expression) { - return createCallExpression( - createFunctionExpression( + function createImmediatelyInvokedFunctionExpression(statements: readonly ts.Statement[]): ts.CallExpression; + function createImmediatelyInvokedFunctionExpression(statements: readonly ts.Statement[], param: ts.ParameterDeclaration, paramValue: ts.Expression): ts.CallExpression; + function createImmediatelyInvokedFunctionExpression(statements: readonly ts.Statement[], param?: ts.ParameterDeclaration, paramValue?: ts.Expression) { + return createCallExpression(createFunctionExpression( /*modifiers*/ undefined, /*asteriskToken*/ undefined, /*name*/ undefined, /*typeParameters*/ undefined, /*parameters*/ param ? [param] : [], - /*type*/ undefined, - createBlock(statements, /*multiLine*/ true) - ), + /*type*/ undefined, createBlock(statements, /*multiLine*/ true)), /*typeArguments*/ undefined, - /*argumentsArray*/ paramValue ? [paramValue] : [] - ); + /*argumentsArray*/ paramValue ? [paramValue] : []); } - - function createImmediatelyInvokedArrowFunction(statements: readonly Statement[]): CallExpression; - function createImmediatelyInvokedArrowFunction(statements: readonly Statement[], param: ParameterDeclaration, paramValue: Expression): CallExpression; - function createImmediatelyInvokedArrowFunction(statements: readonly Statement[], param?: ParameterDeclaration, paramValue?: Expression) { - return createCallExpression( - createArrowFunction( + function createImmediatelyInvokedArrowFunction(statements: readonly ts.Statement[]): ts.CallExpression; + function createImmediatelyInvokedArrowFunction(statements: readonly ts.Statement[], param: ts.ParameterDeclaration, paramValue: ts.Expression): ts.CallExpression; + function createImmediatelyInvokedArrowFunction(statements: readonly ts.Statement[], param?: ts.ParameterDeclaration, paramValue?: ts.Expression) { + return createCallExpression(createArrowFunction( /*modifiers*/ undefined, /*typeParameters*/ undefined, /*parameters*/ param ? [param] : [], /*type*/ undefined, - /*equalsGreaterThanToken*/ undefined, - createBlock(statements, /*multiLine*/ true) - ), + /*equalsGreaterThanToken*/ undefined, createBlock(statements, /*multiLine*/ true)), /*typeArguments*/ undefined, - /*argumentsArray*/ paramValue ? [paramValue] : [] - ); + /*argumentsArray*/ paramValue ? [paramValue] : []); } function createVoidZero() { return createVoidExpression(createNumericLiteral("0")); } - function createExportDefault(expression: Expression) { + function createExportDefault(expression: ts.Expression) { return createExportAssignment( /*decorators*/ undefined, /*modifiers*/ undefined, - /*isExportEquals*/ false, - expression); + /*isExportEquals*/ false, expression); } - function createExternalModuleExport(exportName: Identifier) { + function createExternalModuleExport(exportName: ts.Identifier) { return createExportDeclaration( /*decorators*/ undefined, /*modifiers*/ undefined, - /*isTypeOnly*/ false, - createNamedExports([ + /*isTypeOnly*/ false, createNamedExports([ createExportSpecifier(/*isTypeOnly*/ false, /*propertyName*/ undefined, exportName) - ]) - ); + ])); } // // Utilities // - function createTypeCheck(value: Expression, tag: TypeOfTag) { + function createTypeCheck(value: ts.Expression, tag: ts.TypeOfTag) { return tag === "undefined" ? factory.createStrictEquality(value, createVoidZero()) : factory.createStrictEquality(createTypeOfExpression(value), createStringLiteral(tag)); } - function createMethodCall(object: Expression, methodName: string | Identifier, argumentsList: readonly Expression[]) { + function createMethodCall(object: ts.Expression, methodName: string | ts.Identifier, argumentsList: readonly ts.Expression[]) { // Preserve the optionality of `object`. - if (isCallChain(object)) { - return createCallChain( - createPropertyAccessChain(object, /*questionDotToken*/ undefined, methodName), + if (ts.isCallChain(object)) { + return createCallChain(createPropertyAccessChain(object, /*questionDotToken*/ undefined, methodName), /*questionDotToken*/ undefined, - /*typeArguments*/ undefined, - argumentsList - ); + /*typeArguments*/ undefined, argumentsList); } - return createCallExpression( - createPropertyAccessExpression(object, methodName), - /*typeArguments*/ undefined, - argumentsList - ); + return createCallExpression(createPropertyAccessExpression(object, methodName), + /*typeArguments*/ undefined, argumentsList); } - function createFunctionBindCall(target: Expression, thisArg: Expression, argumentsList: readonly Expression[]) { + function createFunctionBindCall(target: ts.Expression, thisArg: ts.Expression, argumentsList: readonly ts.Expression[]) { return createMethodCall(target, "bind", [thisArg, ...argumentsList]); } - function createFunctionCallCall(target: Expression, thisArg: Expression, argumentsList: readonly Expression[]) { + function createFunctionCallCall(target: ts.Expression, thisArg: ts.Expression, argumentsList: readonly ts.Expression[]) { return createMethodCall(target, "call", [thisArg, ...argumentsList]); } - function createFunctionApplyCall(target: Expression, thisArg: Expression, argumentsExpression: Expression) { + function createFunctionApplyCall(target: ts.Expression, thisArg: ts.Expression, argumentsExpression: ts.Expression) { return createMethodCall(target, "apply", [thisArg, argumentsExpression]); } - function createGlobalMethodCall(globalObjectName: string, methodName: string, argumentsList: readonly Expression[]) { + function createGlobalMethodCall(globalObjectName: string, methodName: string, argumentsList: readonly ts.Expression[]) { return createMethodCall(createIdentifier(globalObjectName), methodName, argumentsList); } - function createArraySliceCall(array: Expression, start?: number | Expression) { + function createArraySliceCall(array: ts.Expression, start?: number | ts.Expression) { return createMethodCall(array, "slice", start === undefined ? [] : [asExpression(start)]); } - function createArrayConcatCall(array: Expression, argumentsList: readonly Expression[]) { + function createArrayConcatCall(array: ts.Expression, argumentsList: readonly ts.Expression[]) { return createMethodCall(array, "concat", argumentsList); } - function createObjectDefinePropertyCall(target: Expression, propertyName: string | Expression, attributes: Expression) { + function createObjectDefinePropertyCall(target: ts.Expression, propertyName: string | ts.Expression, attributes: ts.Expression) { return createGlobalMethodCall("Object", "defineProperty", [target, asExpression(propertyName), attributes]); } - function createReflectGetCall(target: Expression, propertyKey: Expression, receiver?: Expression): CallExpression { + function createReflectGetCall(target: ts.Expression, propertyKey: ts.Expression, receiver?: ts.Expression): ts.CallExpression { return createGlobalMethodCall("Reflect", "get", receiver ? [target, propertyKey, receiver] : [target, propertyKey]); } - function createReflectSetCall(target: Expression, propertyKey: Expression, value: Expression, receiver?: Expression): CallExpression { + function createReflectSetCall(target: ts.Expression, propertyKey: ts.Expression, value: ts.Expression, receiver?: ts.Expression): ts.CallExpression { return createGlobalMethodCall("Reflect", "set", receiver ? [target, propertyKey, value, receiver] : [target, propertyKey, value]); } - function tryAddPropertyAssignment(properties: Push, propertyName: string, expression: Expression | undefined) { + function tryAddPropertyAssignment(properties: ts.Push, propertyName: string, expression: ts.Expression | undefined) { if (expression) { properties.push(createPropertyAssignment(propertyName, expression)); return true; @@ -5680,8 +5012,8 @@ namespace ts { return false; } - function createPropertyDescriptor(attributes: PropertyDescriptorAttributes, singleLine?: boolean) { - const properties: PropertyAssignment[] = []; + function createPropertyDescriptor(attributes: ts.PropertyDescriptorAttributes, singleLine?: boolean) { + const properties: ts.PropertyAssignment[] = []; tryAddPropertyAssignment(properties, "enumerable", asExpression(attributes.enumerable)); tryAddPropertyAssignment(properties, "configurable", asExpression(attributes.configurable)); @@ -5691,17 +5023,17 @@ namespace ts { let isAccessor = tryAddPropertyAssignment(properties, "get", attributes.get); isAccessor = tryAddPropertyAssignment(properties, "set", attributes.set) || isAccessor; - Debug.assert(!(isData && isAccessor), "A PropertyDescriptor may not be both an accessor descriptor and a data descriptor."); + ts.Debug.assert(!(isData && isAccessor), "A PropertyDescriptor may not be both an accessor descriptor and a data descriptor."); return createObjectLiteralExpression(properties, !singleLine); } - function updateOuterExpression(outerExpression: OuterExpression, expression: Expression) { + function updateOuterExpression(outerExpression: ts.OuterExpression, expression: ts.Expression) { switch (outerExpression.kind) { - case SyntaxKind.ParenthesizedExpression: return updateParenthesizedExpression(outerExpression, expression); - case SyntaxKind.TypeAssertionExpression: return updateTypeAssertion(outerExpression, outerExpression.type, expression); - case SyntaxKind.AsExpression: return updateAsExpression(outerExpression, expression, outerExpression.type); - case SyntaxKind.NonNullExpression: return updateNonNullExpression(outerExpression, expression); - case SyntaxKind.PartiallyEmittedExpression: return updatePartiallyEmittedExpression(outerExpression, expression); + case ts.SyntaxKind.ParenthesizedExpression: return updateParenthesizedExpression(outerExpression, expression); + case ts.SyntaxKind.TypeAssertionExpression: return updateTypeAssertion(outerExpression, outerExpression.type, expression); + case ts.SyntaxKind.AsExpression: return updateAsExpression(outerExpression, expression, outerExpression.type); + case ts.SyntaxKind.NonNullExpression: return updateNonNullExpression(outerExpression, expression); + case ts.SyntaxKind.PartiallyEmittedExpression: return updatePartiallyEmittedExpression(outerExpression, expression); } } @@ -5719,119 +5051,93 @@ namespace ts { * the expression to maintain precedence, a new parenthesized expression should be created automatically when * the containing expression is created/updated. */ - function isIgnorableParen(node: Expression) { - return isParenthesizedExpression(node) - && nodeIsSynthesized(node) - && nodeIsSynthesized(getSourceMapRange(node)) - && nodeIsSynthesized(getCommentRange(node)) - && !some(getSyntheticLeadingComments(node)) - && !some(getSyntheticTrailingComments(node)); - } - - function restoreOuterExpressions(outerExpression: Expression | undefined, innerExpression: Expression, kinds = OuterExpressionKinds.All): Expression { - if (outerExpression && isOuterExpression(outerExpression, kinds) && !isIgnorableParen(outerExpression)) { - return updateOuterExpression( - outerExpression, - restoreOuterExpressions(outerExpression.expression, innerExpression) - ); + function isIgnorableParen(node: ts.Expression) { + return ts.isParenthesizedExpression(node) + && ts.nodeIsSynthesized(node) + && ts.nodeIsSynthesized(ts.getSourceMapRange(node)) + && ts.nodeIsSynthesized(ts.getCommentRange(node)) + && !ts.some(ts.getSyntheticLeadingComments(node)) + && !ts.some(ts.getSyntheticTrailingComments(node)); + } + function restoreOuterExpressions(outerExpression: ts.Expression | undefined, innerExpression: ts.Expression, kinds = ts.OuterExpressionKinds.All): ts.Expression { + if (outerExpression && ts.isOuterExpression(outerExpression, kinds) && !isIgnorableParen(outerExpression)) { + return updateOuterExpression(outerExpression, restoreOuterExpressions(outerExpression.expression, innerExpression)); } return innerExpression; } - function restoreEnclosingLabel(node: Statement, outermostLabeledStatement: LabeledStatement | undefined, afterRestoreLabelCallback?: (node: LabeledStatement) => void): Statement { + function restoreEnclosingLabel(node: ts.Statement, outermostLabeledStatement: ts.LabeledStatement | undefined, afterRestoreLabelCallback?: (node: ts.LabeledStatement) => void): ts.Statement { if (!outermostLabeledStatement) { return node; } - const updated = updateLabeledStatement( - outermostLabeledStatement, - outermostLabeledStatement.label, - isLabeledStatement(outermostLabeledStatement.statement) + const updated = updateLabeledStatement(outermostLabeledStatement, outermostLabeledStatement.label, ts.isLabeledStatement(outermostLabeledStatement.statement) ? restoreEnclosingLabel(node, outermostLabeledStatement.statement) - : node - ); + : node); if (afterRestoreLabelCallback) { afterRestoreLabelCallback(outermostLabeledStatement); } return updated; } - function shouldBeCapturedInTempVariable(node: Expression, cacheIdentifiers: boolean): boolean { - const target = skipParentheses(node); + function shouldBeCapturedInTempVariable(node: ts.Expression, cacheIdentifiers: boolean): boolean { + const target = ts.skipParentheses(node); switch (target.kind) { - case SyntaxKind.Identifier: + case ts.SyntaxKind.Identifier: return cacheIdentifiers; - case SyntaxKind.ThisKeyword: - case SyntaxKind.NumericLiteral: - case SyntaxKind.BigIntLiteral: - case SyntaxKind.StringLiteral: + case ts.SyntaxKind.ThisKeyword: + case ts.SyntaxKind.NumericLiteral: + case ts.SyntaxKind.BigIntLiteral: + case ts.SyntaxKind.StringLiteral: return false; - case SyntaxKind.ArrayLiteralExpression: - const elements = (target as ArrayLiteralExpression).elements; + case ts.SyntaxKind.ArrayLiteralExpression: + const elements = (target as ts.ArrayLiteralExpression).elements; if (elements.length === 0) { return false; } return true; - case SyntaxKind.ObjectLiteralExpression: - return (target as ObjectLiteralExpression).properties.length > 0; + case ts.SyntaxKind.ObjectLiteralExpression: + return (target as ts.ObjectLiteralExpression).properties.length > 0; default: return true; } } - function createCallBinding(expression: Expression, recordTempVariable: (temp: Identifier) => void, languageVersion?: ScriptTarget, cacheIdentifiers = false): CallBinding { - const callee = skipOuterExpressions(expression, OuterExpressionKinds.All); - let thisArg: Expression; - let target: LeftHandSideExpression; - if (isSuperProperty(callee)) { + function createCallBinding(expression: ts.Expression, recordTempVariable: (temp: ts.Identifier) => void, languageVersion?: ts.ScriptTarget, cacheIdentifiers = false): ts.CallBinding { + const callee = ts.skipOuterExpressions(expression, ts.OuterExpressionKinds.All); + let thisArg: ts.Expression; + let target: ts.LeftHandSideExpression; + if (ts.isSuperProperty(callee)) { thisArg = createThis(); target = callee; } - else if (isSuperKeyword(callee)) { + else if (ts.isSuperKeyword(callee)) { thisArg = createThis(); - target = languageVersion !== undefined && languageVersion < ScriptTarget.ES2015 - ? setTextRange(createIdentifier("_super"), callee) - : callee as PrimaryExpression; + target = languageVersion !== undefined && languageVersion < ts.ScriptTarget.ES2015 + ? ts.setTextRange(createIdentifier("_super"), callee) + : callee as ts.PrimaryExpression; } - else if (getEmitFlags(callee) & EmitFlags.HelperName) { + else if (ts.getEmitFlags(callee) & ts.EmitFlags.HelperName) { thisArg = createVoidZero(); target = parenthesizerRules().parenthesizeLeftSideOfAccess(callee); } - else if (isPropertyAccessExpression(callee)) { + else if (ts.isPropertyAccessExpression(callee)) { if (shouldBeCapturedInTempVariable(callee.expression, cacheIdentifiers)) { // for `a.b()` target is `(_a = a).b` and thisArg is `_a` thisArg = createTempVariable(recordTempVariable); - target = createPropertyAccessExpression( - setTextRange( - factory.createAssignment( - thisArg, - callee.expression - ), - callee.expression - ), - callee.name - ); - setTextRange(target, callee); + target = createPropertyAccessExpression(ts.setTextRange(factory.createAssignment(thisArg, callee.expression), callee.expression), callee.name); + ts.setTextRange(target, callee); } else { thisArg = callee.expression; target = callee; } } - else if (isElementAccessExpression(callee)) { + else if (ts.isElementAccessExpression(callee)) { if (shouldBeCapturedInTempVariable(callee.expression, cacheIdentifiers)) { // for `a[b]()` target is `(_a = a)[b]` and thisArg is `_a` thisArg = createTempVariable(recordTempVariable); - target = createElementAccessExpression( - setTextRange( - factory.createAssignment( - thisArg, - callee.expression - ), - callee.expression - ), - callee.argumentExpression - ); - setTextRange(target, callee); + target = createElementAccessExpression(ts.setTextRange(factory.createAssignment(thisArg, callee.expression), callee.expression), callee.argumentExpression); + ts.setTextRange(target, callee); } else { thisArg = callee.expression; @@ -5847,51 +5153,43 @@ namespace ts { return { target, thisArg }; } - function createAssignmentTargetWrapper(paramName: Identifier, expression: Expression): LeftHandSideExpression { + function createAssignmentTargetWrapper(paramName: ts.Identifier, expression: ts.Expression): ts.LeftHandSideExpression { return createPropertyAccessExpression( // Explicit parens required because of v8 regression (https://bugs.chromium.org/p/v8/issues/detail?id=9560) - createParenthesizedExpression( - createObjectLiteralExpression([ + createParenthesizedExpression(createObjectLiteralExpression([ createSetAccessorDeclaration( /*decorators*/ undefined, - /*modifiers*/ undefined, - "value", - [createParameterDeclaration( + /*modifiers*/ undefined, "value", [createParameterDeclaration( /*decorators*/ undefined, /*modifiers*/ undefined, - /*dotDotDotToken*/ undefined, - paramName, + /*dotDotDotToken*/ undefined, paramName, /*questionToken*/ undefined, /*type*/ undefined, - /*initializer*/ undefined - )], - createBlock([ + /*initializer*/ undefined)], createBlock([ createExpressionStatement(expression) - ]) - ) - ]) - ), - "value" - ); + ])) + ])), "value"); } - - function inlineExpressions(expressions: readonly Expression[]) { + function inlineExpressions(expressions: readonly ts.Expression[]) { // Avoid deeply nested comma expressions as traversing them during emit can result in "Maximum call // stack size exceeded" errors. return expressions.length > 10 ? createCommaListExpression(expressions) - : reduceLeft(expressions, factory.createComma)!; + : ts.reduceLeft(expressions, factory.createComma)!; } - function getName(node: Declaration | undefined, allowComments?: boolean, allowSourceMaps?: boolean, emitFlags: EmitFlags = 0) { - const nodeName = getNameOfDeclaration(node); - if (nodeName && isIdentifier(nodeName) && !isGeneratedIdentifier(nodeName)) { + function getName(node: ts.Declaration | undefined, allowComments?: boolean, allowSourceMaps?: boolean, emitFlags: ts.EmitFlags = 0) { + const nodeName = ts.getNameOfDeclaration(node); + if (nodeName && ts.isIdentifier(nodeName) && !ts.isGeneratedIdentifier(nodeName)) { // TODO(rbuckton): Does this need to be parented? - const name = setParent(setTextRange(cloneNode(nodeName), nodeName), nodeName.parent); - emitFlags |= getEmitFlags(nodeName); - if (!allowSourceMaps) emitFlags |= EmitFlags.NoSourceMap; - if (!allowComments) emitFlags |= EmitFlags.NoComments; - if (emitFlags) setEmitFlags(name, emitFlags); + const name = ts.setParent(ts.setTextRange(cloneNode(nodeName), nodeName), nodeName.parent); + emitFlags |= ts.getEmitFlags(nodeName); + if (!allowSourceMaps) + emitFlags |= ts.EmitFlags.NoSourceMap; + if (!allowComments) + emitFlags |= ts.EmitFlags.NoComments; + if (emitFlags) + ts.setEmitFlags(name, emitFlags); return name; } return getGeneratedNameForNode(node); @@ -5908,8 +5206,8 @@ namespace ts { * @param allowComments A value indicating whether comments may be emitted for the name. * @param allowSourceMaps A value indicating whether source maps may be emitted for the name. */ - function getInternalName(node: Declaration, allowComments?: boolean, allowSourceMaps?: boolean) { - return getName(node, allowComments, allowSourceMaps, EmitFlags.LocalName | EmitFlags.InternalName); + function getInternalName(node: ts.Declaration, allowComments?: boolean, allowSourceMaps?: boolean) { + return getName(node, allowComments, allowSourceMaps, ts.EmitFlags.LocalName | ts.EmitFlags.InternalName); } /** @@ -5922,8 +5220,8 @@ namespace ts { * @param allowComments A value indicating whether comments may be emitted for the name. * @param allowSourceMaps A value indicating whether source maps may be emitted for the name. */ - function getLocalName(node: Declaration, allowComments?: boolean, allowSourceMaps?: boolean) { - return getName(node, allowComments, allowSourceMaps, EmitFlags.LocalName); + function getLocalName(node: ts.Declaration, allowComments?: boolean, allowSourceMaps?: boolean) { + return getName(node, allowComments, allowSourceMaps, ts.EmitFlags.LocalName); } /** @@ -5936,8 +5234,8 @@ namespace ts { * @param allowComments A value indicating whether comments may be emitted for the name. * @param allowSourceMaps A value indicating whether source maps may be emitted for the name. */ - function getExportName(node: Declaration, allowComments?: boolean, allowSourceMaps?: boolean): Identifier { - return getName(node, allowComments, allowSourceMaps, EmitFlags.ExportName); + function getExportName(node: ts.Declaration, allowComments?: boolean, allowSourceMaps?: boolean): ts.Identifier { + return getName(node, allowComments, allowSourceMaps, ts.EmitFlags.ExportName); } /** @@ -5947,7 +5245,7 @@ namespace ts { * @param allowComments A value indicating whether comments may be emitted for the name. * @param allowSourceMaps A value indicating whether source maps may be emitted for the name. */ - function getDeclarationName(node: Declaration | undefined, allowComments?: boolean, allowSourceMaps?: boolean) { + function getDeclarationName(node: ts.Declaration | undefined, allowComments?: boolean, allowSourceMaps?: boolean) { return getName(node, allowComments, allowSourceMaps); } @@ -5959,13 +5257,16 @@ namespace ts { * @param allowComments A value indicating whether comments may be emitted for the name. * @param allowSourceMaps A value indicating whether source maps may be emitted for the name. */ - function getNamespaceMemberName(ns: Identifier, name: Identifier, allowComments?: boolean, allowSourceMaps?: boolean): PropertyAccessExpression { - const qualifiedName = createPropertyAccessExpression(ns, nodeIsSynthesized(name) ? name : cloneNode(name)); - setTextRange(qualifiedName, name); - let emitFlags: EmitFlags = 0; - if (!allowSourceMaps) emitFlags |= EmitFlags.NoSourceMap; - if (!allowComments) emitFlags |= EmitFlags.NoComments; - if (emitFlags) setEmitFlags(qualifiedName, emitFlags); + function getNamespaceMemberName(ns: ts.Identifier, name: ts.Identifier, allowComments?: boolean, allowSourceMaps?: boolean): ts.PropertyAccessExpression { + const qualifiedName = createPropertyAccessExpression(ns, ts.nodeIsSynthesized(name) ? name : cloneNode(name)); + ts.setTextRange(qualifiedName, name); + let emitFlags: ts.EmitFlags = 0; + if (!allowSourceMaps) + emitFlags |= ts.EmitFlags.NoSourceMap; + if (!allowComments) + emitFlags |= ts.EmitFlags.NoComments; + if (emitFlags) + ts.setEmitFlags(qualifiedName, emitFlags); return qualifiedName; } @@ -5980,8 +5281,8 @@ namespace ts { * @param allowComments A value indicating whether comments may be emitted for the name. * @param allowSourceMaps A value indicating whether source maps may be emitted for the name. */ - function getExternalModuleOrNamespaceExportName(ns: Identifier | undefined, node: Declaration, allowComments?: boolean, allowSourceMaps?: boolean): Identifier | PropertyAccessExpression { - if (ns && hasSyntacticModifier(node, ModifierFlags.Export)) { + function getExternalModuleOrNamespaceExportName(ns: ts.Identifier | undefined, node: ts.Declaration, allowComments?: boolean, allowSourceMaps?: boolean): ts.Identifier | ts.PropertyAccessExpression { + if (ns && ts.hasSyntacticModifier(node, ts.ModifierFlags.Export)) { return getNamespaceMemberName(ns, getName(node), allowComments, allowSourceMaps); } return getExportName(node, allowComments, allowSourceMaps); @@ -5994,17 +5295,17 @@ namespace ts { * @param ensureUseStrict boolean determining whether the function need to add prologue-directives * @param visitor Optional callback used to visit any custom prologue directives. */ - function copyPrologue(source: readonly Statement[], target: Push, ensureUseStrict?: boolean, visitor?: (node: Node) => VisitResult): number { + function copyPrologue(source: readonly ts.Statement[], target: ts.Push, ensureUseStrict?: boolean, visitor?: (node: ts.Node) => ts.VisitResult): number { const offset = copyStandardPrologue(source, target, 0, ensureUseStrict); return copyCustomPrologue(source, target, offset, visitor); } - function isUseStrictPrologue(node: ExpressionStatement): boolean { - return isStringLiteral(node.expression) && node.expression.text === "use strict"; + function isUseStrictPrologue(node: ts.ExpressionStatement): boolean { + return ts.isStringLiteral(node.expression) && node.expression.text === "use strict"; } function createUseStrictPrologue() { - return startOnNewLine(createExpressionStatement(createStringLiteral("use strict"))) as PrologueDirective; + return ts.startOnNewLine(createExpressionStatement(createStringLiteral("use strict"))) as ts.PrologueDirective; } /** @@ -6015,13 +5316,13 @@ namespace ts { * @param ensureUseStrict boolean determining whether the function need to add prologue-directives * @returns Count of how many directive statements were copied. */ - function copyStandardPrologue(source: readonly Statement[], target: Push, statementOffset = 0, ensureUseStrict?: boolean): number { - Debug.assert(target.length === 0, "Prologue directives should be at the first statement in the target statements array"); + function copyStandardPrologue(source: readonly ts.Statement[], target: ts.Push, statementOffset = 0, ensureUseStrict?: boolean): number { + ts.Debug.assert(target.length === 0, "Prologue directives should be at the first statement in the target statements array"); let foundUseStrict = false; const numStatements = source.length; while (statementOffset < numStatements) { const statement = source[statementOffset]; - if (isPrologueDirective(statement)) { + if (ts.isPrologueDirective(statement)) { if (isUseStrictPrologue(statement)) { foundUseStrict = true; } @@ -6045,14 +5346,14 @@ namespace ts { * @param statementOffset The offset at which to begin the copy. * @param visitor Optional callback used to visit any custom prologue directives. */ - function copyCustomPrologue(source: readonly Statement[], target: Push, statementOffset: number, visitor?: (node: Node) => VisitResult, filter?: (node: Node) => boolean): number; - function copyCustomPrologue(source: readonly Statement[], target: Push, statementOffset: number | undefined, visitor?: (node: Node) => VisitResult, filter?: (node: Node) => boolean): number | undefined; - function copyCustomPrologue(source: readonly Statement[], target: Push, statementOffset: number | undefined, visitor?: (node: Node) => VisitResult, filter: (node: Node) => boolean = returnTrue): number | undefined { + function copyCustomPrologue(source: readonly ts.Statement[], target: ts.Push, statementOffset: number, visitor?: (node: ts.Node) => ts.VisitResult, filter?: (node: ts.Node) => boolean): number; + function copyCustomPrologue(source: readonly ts.Statement[], target: ts.Push, statementOffset: number | undefined, visitor?: (node: ts.Node) => ts.VisitResult, filter?: (node: ts.Node) => boolean): number | undefined; + function copyCustomPrologue(source: readonly ts.Statement[], target: ts.Push, statementOffset: number | undefined, visitor?: (node: ts.Node) => ts.VisitResult, filter: (node: ts.Node) => boolean = ts.returnTrue): number | undefined { const numStatements = source.length; while (statementOffset !== undefined && statementOffset < numStatements) { const statement = source[statementOffset]; - if (getEmitFlags(statement) & EmitFlags.CustomPrologue && filter(statement)) { - append(target, visitor ? visitNode(statement, visitor, isStatement) : statement); + if (ts.getEmitFlags(statement) & ts.EmitFlags.CustomPrologue && filter(statement)) { + ts.append(target, visitor ? ts.visitNode(statement, visitor, ts.isStatement) : statement); } else { break; @@ -6067,11 +5368,11 @@ namespace ts { * * @param statements An array of statements */ - function ensureUseStrict(statements: NodeArray): NodeArray { - const foundUseStrict = findUseStrictPrologue(statements); + function ensureUseStrict(statements: ts.NodeArray): ts.NodeArray { + const foundUseStrict = ts.findUseStrictPrologue(statements); if (!foundUseStrict) { - return setTextRange(createNodeArray([createUseStrictPrologue(), ...statements]), statements); + return ts.setTextRange(createNodeArray([createUseStrictPrologue(), ...statements]), statements); } return statements; @@ -6082,9 +5383,9 @@ namespace ts { * * @param nodes The NodeArray. */ - function liftToBlock(nodes: readonly Node[]): Statement { - Debug.assert(every(nodes, isStatementOrBlock), "Cannot lift nodes to a Block."); - return singleOrUndefined(nodes) as Statement || createBlock(nodes as readonly Statement[]); + function liftToBlock(nodes: readonly ts.Node[]): ts.Statement { + ts.Debug.assert(ts.every(nodes, ts.isStatementOrBlock), "Cannot lift nodes to a Block."); + return ts.singleOrUndefined(nodes) as ts.Statement || createBlock(nodes as readonly ts.Statement[]); } function findSpanEnd(array: readonly T[], test: (value: T) => boolean, start: number) { @@ -6095,10 +5396,10 @@ namespace ts { return i; } - function mergeLexicalEnvironment(statements: NodeArray, declarations: readonly Statement[] | undefined): NodeArray; - function mergeLexicalEnvironment(statements: Statement[], declarations: readonly Statement[] | undefined): Statement[]; - function mergeLexicalEnvironment(statements: Statement[] | NodeArray, declarations: readonly Statement[] | undefined) { - if (!some(declarations)) { + function mergeLexicalEnvironment(statements: ts.NodeArray, declarations: readonly ts.Statement[] | undefined): ts.NodeArray; + function mergeLexicalEnvironment(statements: ts.Statement[], declarations: readonly ts.Statement[] | undefined): ts.Statement[]; + function mergeLexicalEnvironment(statements: ts.Statement[] | ts.NodeArray, declarations: readonly ts.Statement[] | undefined) { + if (!ts.some(declarations)) { return statements; } @@ -6132,20 +5433,20 @@ namespace ts { // as the prior transformation may depend on the evaluation of the lexical init statements to be in the correct state. // find standard prologues on left in the following order: standard directives, hoisted functions, hoisted variables, other custom - const leftStandardPrologueEnd = findSpanEnd(statements, isPrologueDirective, 0); - const leftHoistedFunctionsEnd = findSpanEnd(statements, isHoistedFunction, leftStandardPrologueEnd); - const leftHoistedVariablesEnd = findSpanEnd(statements, isHoistedVariableStatement, leftHoistedFunctionsEnd); + const leftStandardPrologueEnd = findSpanEnd(statements, ts.isPrologueDirective, 0); + const leftHoistedFunctionsEnd = findSpanEnd(statements, ts.isHoistedFunction, leftStandardPrologueEnd); + const leftHoistedVariablesEnd = findSpanEnd(statements, ts.isHoistedVariableStatement, leftHoistedFunctionsEnd); // find standard prologues on right in the following order: standard directives, hoisted functions, hoisted variables, other custom - const rightStandardPrologueEnd = findSpanEnd(declarations, isPrologueDirective, 0); - const rightHoistedFunctionsEnd = findSpanEnd(declarations, isHoistedFunction, rightStandardPrologueEnd); - const rightHoistedVariablesEnd = findSpanEnd(declarations, isHoistedVariableStatement, rightHoistedFunctionsEnd); - const rightCustomPrologueEnd = findSpanEnd(declarations, isCustomPrologue, rightHoistedVariablesEnd); - Debug.assert(rightCustomPrologueEnd === declarations.length, "Expected declarations to be valid standard or custom prologues"); + const rightStandardPrologueEnd = findSpanEnd(declarations, ts.isPrologueDirective, 0); + const rightHoistedFunctionsEnd = findSpanEnd(declarations, ts.isHoistedFunction, rightStandardPrologueEnd); + const rightHoistedVariablesEnd = findSpanEnd(declarations, ts.isHoistedVariableStatement, rightHoistedFunctionsEnd); + const rightCustomPrologueEnd = findSpanEnd(declarations, ts.isCustomPrologue, rightHoistedVariablesEnd); + ts.Debug.assert(rightCustomPrologueEnd === declarations.length, "Expected declarations to be valid standard or custom prologues"); // splice prologues from the right into the left. We do this in reverse order // so that we don't need to recompute the index on the left when we insert items. - const left = isNodeArray(statements) ? statements.slice() : statements; + const left = ts.isNodeArray(statements) ? statements.slice() : statements; // splice other custom prologues from right into left if (rightCustomPrologueEnd > rightHoistedVariablesEnd) { @@ -6168,13 +5469,13 @@ namespace ts { left.splice(0, 0, ...declarations.slice(0, rightStandardPrologueEnd)); } else { - const leftPrologues = new Map(); + const leftPrologues = new ts.Map(); for (let i = 0; i < leftStandardPrologueEnd; i++) { - const leftPrologue = statements[i] as PrologueDirective; + const leftPrologue = statements[i] as ts.PrologueDirective; leftPrologues.set(leftPrologue.expression.text, true); } for (let i = rightStandardPrologueEnd - 1; i >= 0; i--) { - const rightPrologue = declarations[i] as PrologueDirective; + const rightPrologue = declarations[i] as ts.PrologueDirective; if (!leftPrologues.has(rightPrologue.expression.text)) { left.unshift(rightPrologue); } @@ -6182,15 +5483,15 @@ namespace ts { } } - if (isNodeArray(statements)) { - return setTextRange(createNodeArray(left, statements.hasTrailingComma), statements); + if (ts.isNodeArray(statements)) { + return ts.setTextRange(createNodeArray(left, statements.hasTrailingComma), statements); } return statements; } - function updateModifiers(node: T, modifiers: readonly Modifier[] | ModifierFlags): T; - function updateModifiers(node: HasModifiers, modifiers: readonly Modifier[] | ModifierFlags) { + function updateModifiers(node: T, modifiers: readonly ts.Modifier[] | ts.ModifierFlags): T; + function updateModifiers(node: ts.HasModifiers, modifiers: readonly ts.Modifier[] | ts.ModifierFlags) { let modifierArray; if (typeof modifiers === "number") { modifierArray = createModifiersFromModifierFlags(modifiers); @@ -6198,127 +5499,126 @@ namespace ts { else { modifierArray = modifiers; } - return isParameter(node) ? updateParameterDeclaration(node, node.decorators, modifierArray, node.dotDotDotToken, node.name, node.questionToken, node.type, node.initializer) : - isPropertySignature(node) ? updatePropertySignature(node, modifierArray, node.name, node.questionToken, node.type) : - isPropertyDeclaration(node) ? updatePropertyDeclaration(node, node.decorators, modifierArray, node.name, node.questionToken ?? node.exclamationToken, node.type, node.initializer) : - isMethodSignature(node) ? updateMethodSignature(node, modifierArray, node.name, node.questionToken, node.typeParameters, node.parameters, node.type) : - isMethodDeclaration(node) ? updateMethodDeclaration(node, node.decorators, modifierArray, node.asteriskToken, node.name, node.questionToken, node.typeParameters, node.parameters, node.type, node.body) : - isConstructorDeclaration(node) ? updateConstructorDeclaration(node, node.decorators, modifierArray, node.parameters, node.body) : - isGetAccessorDeclaration(node) ? updateGetAccessorDeclaration(node, node.decorators, modifierArray, node.name, node.parameters, node.type, node.body) : - isSetAccessorDeclaration(node) ? updateSetAccessorDeclaration(node, node.decorators, modifierArray, node.name, node.parameters, node.body) : - isIndexSignatureDeclaration(node) ? updateIndexSignature(node, node.decorators, modifierArray, node.parameters, node.type) : - isFunctionExpression(node) ? updateFunctionExpression(node, modifierArray, node.asteriskToken, node.name, node.typeParameters, node.parameters, node.type, node.body) : - isArrowFunction(node) ? updateArrowFunction(node, modifierArray, node.typeParameters, node.parameters, node.type, node.equalsGreaterThanToken, node.body) : - isClassExpression(node) ? updateClassExpression(node, node.decorators, modifierArray, node.name, node.typeParameters, node.heritageClauses, node.members) : - isVariableStatement(node) ? updateVariableStatement(node, modifierArray, node.declarationList) : - isFunctionDeclaration(node) ? updateFunctionDeclaration(node, node.decorators, modifierArray, node.asteriskToken, node.name, node.typeParameters, node.parameters, node.type, node.body) : - isClassDeclaration(node) ? updateClassDeclaration(node, node.decorators, modifierArray, node.name, node.typeParameters, node.heritageClauses, node.members) : - isInterfaceDeclaration(node) ? updateInterfaceDeclaration(node, node.decorators, modifierArray, node.name, node.typeParameters, node.heritageClauses, node.members) : - isTypeAliasDeclaration(node) ? updateTypeAliasDeclaration(node, node.decorators, modifierArray, node.name, node.typeParameters, node.type) : - isEnumDeclaration(node) ? updateEnumDeclaration(node, node.decorators, modifierArray, node.name, node.members) : - isModuleDeclaration(node) ? updateModuleDeclaration(node, node.decorators, modifierArray, node.name, node.body) : - isImportEqualsDeclaration(node) ? updateImportEqualsDeclaration(node, node.decorators, modifierArray, node.isTypeOnly, node.name, node.moduleReference) : - isImportDeclaration(node) ? updateImportDeclaration(node, node.decorators, modifierArray, node.importClause, node.moduleSpecifier, node.assertClause) : - isExportAssignment(node) ? updateExportAssignment(node, node.decorators, modifierArray, node.expression) : - isExportDeclaration(node) ? updateExportDeclaration(node, node.decorators, modifierArray, node.isTypeOnly, node.exportClause, node.moduleSpecifier, node.assertClause) : - Debug.assertNever(node); - } - - function asNodeArray(array: readonly T[]): NodeArray; - function asNodeArray(array: readonly T[] | undefined): NodeArray | undefined; - function asNodeArray(array: readonly T[] | undefined): NodeArray | undefined { + return ts.isParameter(node) ? updateParameterDeclaration(node, node.decorators, modifierArray, node.dotDotDotToken, node.name, node.questionToken, node.type, node.initializer) : + ts.isPropertySignature(node) ? updatePropertySignature(node, modifierArray, node.name, node.questionToken, node.type) : + ts.isPropertyDeclaration(node) ? updatePropertyDeclaration(node, node.decorators, modifierArray, node.name, node.questionToken ?? node.exclamationToken, node.type, node.initializer) : + ts.isMethodSignature(node) ? updateMethodSignature(node, modifierArray, node.name, node.questionToken, node.typeParameters, node.parameters, node.type) : + ts.isMethodDeclaration(node) ? updateMethodDeclaration(node, node.decorators, modifierArray, node.asteriskToken, node.name, node.questionToken, node.typeParameters, node.parameters, node.type, node.body) : + ts.isConstructorDeclaration(node) ? updateConstructorDeclaration(node, node.decorators, modifierArray, node.parameters, node.body) : + ts.isGetAccessorDeclaration(node) ? updateGetAccessorDeclaration(node, node.decorators, modifierArray, node.name, node.parameters, node.type, node.body) : + ts.isSetAccessorDeclaration(node) ? updateSetAccessorDeclaration(node, node.decorators, modifierArray, node.name, node.parameters, node.body) : + ts.isIndexSignatureDeclaration(node) ? updateIndexSignature(node, node.decorators, modifierArray, node.parameters, node.type) : + ts.isFunctionExpression(node) ? updateFunctionExpression(node, modifierArray, node.asteriskToken, node.name, node.typeParameters, node.parameters, node.type, node.body) : + ts.isArrowFunction(node) ? updateArrowFunction(node, modifierArray, node.typeParameters, node.parameters, node.type, node.equalsGreaterThanToken, node.body) : + ts.isClassExpression(node) ? updateClassExpression(node, node.decorators, modifierArray, node.name, node.typeParameters, node.heritageClauses, node.members) : + ts.isVariableStatement(node) ? updateVariableStatement(node, modifierArray, node.declarationList) : + ts.isFunctionDeclaration(node) ? updateFunctionDeclaration(node, node.decorators, modifierArray, node.asteriskToken, node.name, node.typeParameters, node.parameters, node.type, node.body) : + ts.isClassDeclaration(node) ? updateClassDeclaration(node, node.decorators, modifierArray, node.name, node.typeParameters, node.heritageClauses, node.members) : + ts.isInterfaceDeclaration(node) ? updateInterfaceDeclaration(node, node.decorators, modifierArray, node.name, node.typeParameters, node.heritageClauses, node.members) : + ts.isTypeAliasDeclaration(node) ? updateTypeAliasDeclaration(node, node.decorators, modifierArray, node.name, node.typeParameters, node.type) : + ts.isEnumDeclaration(node) ? updateEnumDeclaration(node, node.decorators, modifierArray, node.name, node.members) : + ts.isModuleDeclaration(node) ? updateModuleDeclaration(node, node.decorators, modifierArray, node.name, node.body) : + ts.isImportEqualsDeclaration(node) ? updateImportEqualsDeclaration(node, node.decorators, modifierArray, node.isTypeOnly, node.name, node.moduleReference) : + ts.isImportDeclaration(node) ? updateImportDeclaration(node, node.decorators, modifierArray, node.importClause, node.moduleSpecifier, node.assertClause) : + ts.isExportAssignment(node) ? updateExportAssignment(node, node.decorators, modifierArray, node.expression) : + ts.isExportDeclaration(node) ? updateExportDeclaration(node, node.decorators, modifierArray, node.isTypeOnly, node.exportClause, node.moduleSpecifier, node.assertClause) : + ts.Debug.assertNever(node); + } + function asNodeArray(array: readonly T[]): ts.NodeArray; + function asNodeArray(array: readonly T[] | undefined): ts.NodeArray | undefined; + function asNodeArray(array: readonly T[] | undefined): ts.NodeArray | undefined { return array ? createNodeArray(array) : undefined; } - function asName(name: string | T): T | Identifier { + function asName(name: string | T): T | ts.Identifier { return typeof name === "string" ? createIdentifier(name) : name; } - function asExpression(value: string | number | boolean | T): T | StringLiteral | NumericLiteral | BooleanLiteral { + function asExpression(value: string | number | boolean | T): T | ts.StringLiteral | ts.NumericLiteral | ts.BooleanLiteral { return typeof value === "string" ? createStringLiteral(value) : typeof value === "number" ? createNumericLiteral(value) : typeof value === "boolean" ? value ? createTrue() : createFalse() : value; } - function asToken(value: TKind | Token): Token { + function asToken(value: TKind | ts.Token): ts.Token { return typeof value === "number" ? createToken(value) : value; } - function asEmbeddedStatement(statement: T): T | EmptyStatement; - function asEmbeddedStatement(statement: T | undefined): T | EmptyStatement | undefined; - function asEmbeddedStatement(statement: T | undefined): T | EmptyStatement | undefined { - return statement && isNotEmittedStatement(statement) ? setTextRange(setOriginalNode(createEmptyStatement(), statement), statement) : statement; + function asEmbeddedStatement(statement: T): T | ts.EmptyStatement; + function asEmbeddedStatement(statement: T | undefined): T | ts.EmptyStatement | undefined; + function asEmbeddedStatement(statement: T | undefined): T | ts.EmptyStatement | undefined { + return statement && ts.isNotEmittedStatement(statement) ? ts.setTextRange(setOriginalNode(createEmptyStatement(), statement), statement) : statement; } } - function updateWithoutOriginal(updated: T, original: T): T { + function updateWithoutOriginal(updated: T, original: T): T { if (updated !== original) { - setTextRange(updated, original); + ts.setTextRange(updated, original); } return updated; } - function updateWithOriginal(updated: T, original: T): T { + function updateWithOriginal(updated: T, original: T): T { if (updated !== original) { setOriginalNode(updated, original); - setTextRange(updated, original); + ts.setTextRange(updated, original); } return updated; } - function getDefaultTagNameForKind(kind: JSDocTag["kind"]): string { + function getDefaultTagNameForKind(kind: ts.JSDocTag["kind"]): string { switch (kind) { - case SyntaxKind.JSDocTypeTag: return "type"; - case SyntaxKind.JSDocReturnTag: return "returns"; - case SyntaxKind.JSDocThisTag: return "this"; - case SyntaxKind.JSDocEnumTag: return "enum"; - case SyntaxKind.JSDocAuthorTag: return "author"; - case SyntaxKind.JSDocClassTag: return "class"; - case SyntaxKind.JSDocPublicTag: return "public"; - case SyntaxKind.JSDocPrivateTag: return "private"; - case SyntaxKind.JSDocProtectedTag: return "protected"; - case SyntaxKind.JSDocReadonlyTag: return "readonly"; - case SyntaxKind.JSDocOverrideTag: return "override"; - case SyntaxKind.JSDocTemplateTag: return "template"; - case SyntaxKind.JSDocTypedefTag: return "typedef"; - case SyntaxKind.JSDocParameterTag: return "param"; - case SyntaxKind.JSDocPropertyTag: return "prop"; - case SyntaxKind.JSDocCallbackTag: return "callback"; - case SyntaxKind.JSDocAugmentsTag: return "augments"; - case SyntaxKind.JSDocImplementsTag: return "implements"; + case ts.SyntaxKind.JSDocTypeTag: return "type"; + case ts.SyntaxKind.JSDocReturnTag: return "returns"; + case ts.SyntaxKind.JSDocThisTag: return "this"; + case ts.SyntaxKind.JSDocEnumTag: return "enum"; + case ts.SyntaxKind.JSDocAuthorTag: return "author"; + case ts.SyntaxKind.JSDocClassTag: return "class"; + case ts.SyntaxKind.JSDocPublicTag: return "public"; + case ts.SyntaxKind.JSDocPrivateTag: return "private"; + case ts.SyntaxKind.JSDocProtectedTag: return "protected"; + case ts.SyntaxKind.JSDocReadonlyTag: return "readonly"; + case ts.SyntaxKind.JSDocOverrideTag: return "override"; + case ts.SyntaxKind.JSDocTemplateTag: return "template"; + case ts.SyntaxKind.JSDocTypedefTag: return "typedef"; + case ts.SyntaxKind.JSDocParameterTag: return "param"; + case ts.SyntaxKind.JSDocPropertyTag: return "prop"; + case ts.SyntaxKind.JSDocCallbackTag: return "callback"; + case ts.SyntaxKind.JSDocAugmentsTag: return "augments"; + case ts.SyntaxKind.JSDocImplementsTag: return "implements"; default: - return Debug.fail(`Unsupported kind: ${Debug.formatSyntaxKind(kind)}`); + return ts.Debug.fail(`Unsupported kind: ${ts.Debug.formatSyntaxKind(kind)}`); } } - let rawTextScanner: Scanner | undefined; + let rawTextScanner: ts.Scanner | undefined; const invalidValueSentinel: object = { }; - function getCookedText(kind: TemplateLiteralToken["kind"], rawText: string) { + function getCookedText(kind: ts.TemplateLiteralToken["kind"], rawText: string) { if (!rawTextScanner) { - rawTextScanner = createScanner(ScriptTarget.Latest, /*skipTrivia*/ false, LanguageVariant.Standard); + rawTextScanner = ts.createScanner(ts.ScriptTarget.Latest, /*skipTrivia*/ false, ts.LanguageVariant.Standard); } switch (kind) { - case SyntaxKind.NoSubstitutionTemplateLiteral: + case ts.SyntaxKind.NoSubstitutionTemplateLiteral: rawTextScanner.setText("`" + rawText + "`"); break; - case SyntaxKind.TemplateHead: + case ts.SyntaxKind.TemplateHead: // tslint:disable-next-line no-invalid-template-strings rawTextScanner.setText("`" + rawText + "${"); break; - case SyntaxKind.TemplateMiddle: + case ts.SyntaxKind.TemplateMiddle: // tslint:disable-next-line no-invalid-template-strings rawTextScanner.setText("}" + rawText + "${"); break; - case SyntaxKind.TemplateTail: + case ts.SyntaxKind.TemplateTail: rawTextScanner.setText("}" + rawText + "`"); break; } let token = rawTextScanner.scan(); - if (token === SyntaxKind.CloseBraceToken) { + if (token === ts.SyntaxKind.CloseBraceToken) { token = rawTextScanner.reScanTemplateToken(/*isTaggedTemplate*/ false); } @@ -6329,15 +5629,15 @@ namespace ts { let tokenValue: string | undefined; switch (token) { - case SyntaxKind.NoSubstitutionTemplateLiteral: - case SyntaxKind.TemplateHead: - case SyntaxKind.TemplateMiddle: - case SyntaxKind.TemplateTail: + case ts.SyntaxKind.NoSubstitutionTemplateLiteral: + case ts.SyntaxKind.TemplateHead: + case ts.SyntaxKind.TemplateMiddle: + case ts.SyntaxKind.TemplateTail: tokenValue = rawTextScanner.getTokenValue(); break; } - if (tokenValue === undefined || rawTextScanner.scan() !== SyntaxKind.EndOfFileToken) { + if (tokenValue === undefined || rawTextScanner.scan() !== ts.SyntaxKind.EndOfFileToken) { rawTextScanner.setText(undefined); return invalidValueSentinel; } @@ -6346,27 +5646,28 @@ namespace ts { return tokenValue; } - function propagateIdentifierNameFlags(node: Identifier) { + function propagateIdentifierNameFlags(node: ts.Identifier) { // An IdentifierName is allowed to be `await` - return propagateChildFlags(node) & ~TransformFlags.ContainsPossibleTopLevelAwait; + return propagateChildFlags(node) & ~ts.TransformFlags.ContainsPossibleTopLevelAwait; } - function propagatePropertyNameFlagsOfChild(node: PropertyName, transformFlags: TransformFlags) { - return transformFlags | (node.transformFlags & TransformFlags.PropertyNamePropagatingFlags); + function propagatePropertyNameFlagsOfChild(node: ts.PropertyName, transformFlags: ts.TransformFlags) { + return transformFlags | (node.transformFlags & ts.TransformFlags.PropertyNamePropagatingFlags); } - function propagateChildFlags(child: Node | undefined): TransformFlags { - if (!child) return TransformFlags.None; + function propagateChildFlags(child: ts.Node | undefined): ts.TransformFlags { + if (!child) + return ts.TransformFlags.None; const childFlags = child.transformFlags & ~getTransformFlagsSubtreeExclusions(child.kind); - return isNamedDeclaration(child) && isPropertyName(child.name) ? propagatePropertyNameFlagsOfChild(child.name, childFlags) : childFlags; + return ts.isNamedDeclaration(child) && ts.isPropertyName(child.name) ? propagatePropertyNameFlagsOfChild(child.name, childFlags) : childFlags; } - function propagateChildrenFlags(children: NodeArray | undefined): TransformFlags { - return children ? children.transformFlags : TransformFlags.None; + function propagateChildrenFlags(children: ts.NodeArray | undefined): ts.TransformFlags { + return children ? children.transformFlags : ts.TransformFlags.None; } - function aggregateChildrenFlags(children: MutableNodeArray) { - let subtreeFlags = TransformFlags.None; + function aggregateChildrenFlags(children: ts.MutableNodeArray) { + let subtreeFlags = ts.TransformFlags.None; for (const child of children) { subtreeFlags |= propagateChildFlags(child); } @@ -6377,85 +5678,84 @@ namespace ts { * Gets the transform flags to exclude when unioning the transform flags of a subtree. */ /* @internal */ - export function getTransformFlagsSubtreeExclusions(kind: SyntaxKind) { - if (kind >= SyntaxKind.FirstTypeNode && kind <= SyntaxKind.LastTypeNode) { - return TransformFlags.TypeExcludes; + export function getTransformFlagsSubtreeExclusions(kind: ts.SyntaxKind) { + if (kind >= ts.SyntaxKind.FirstTypeNode && kind <= ts.SyntaxKind.LastTypeNode) { + return ts.TransformFlags.TypeExcludes; } switch (kind) { - case SyntaxKind.CallExpression: - case SyntaxKind.NewExpression: - case SyntaxKind.ArrayLiteralExpression: - return TransformFlags.ArrayLiteralOrCallOrNewExcludes; - case SyntaxKind.ModuleDeclaration: - return TransformFlags.ModuleExcludes; - case SyntaxKind.Parameter: - return TransformFlags.ParameterExcludes; - case SyntaxKind.ArrowFunction: - return TransformFlags.ArrowFunctionExcludes; - case SyntaxKind.FunctionExpression: - case SyntaxKind.FunctionDeclaration: - return TransformFlags.FunctionExcludes; - case SyntaxKind.VariableDeclarationList: - return TransformFlags.VariableDeclarationListExcludes; - case SyntaxKind.ClassDeclaration: - case SyntaxKind.ClassExpression: - return TransformFlags.ClassExcludes; - case SyntaxKind.Constructor: - return TransformFlags.ConstructorExcludes; - case SyntaxKind.PropertyDeclaration: - return TransformFlags.PropertyExcludes; - case SyntaxKind.MethodDeclaration: - case SyntaxKind.GetAccessor: - case SyntaxKind.SetAccessor: - return TransformFlags.MethodOrAccessorExcludes; - case SyntaxKind.AnyKeyword: - case SyntaxKind.NumberKeyword: - case SyntaxKind.BigIntKeyword: - case SyntaxKind.NeverKeyword: - case SyntaxKind.StringKeyword: - case SyntaxKind.ObjectKeyword: - case SyntaxKind.BooleanKeyword: - case SyntaxKind.SymbolKeyword: - case SyntaxKind.VoidKeyword: - case SyntaxKind.TypeParameter: - case SyntaxKind.PropertySignature: - case SyntaxKind.MethodSignature: - case SyntaxKind.CallSignature: - case SyntaxKind.ConstructSignature: - case SyntaxKind.IndexSignature: - case SyntaxKind.InterfaceDeclaration: - case SyntaxKind.TypeAliasDeclaration: - return TransformFlags.TypeExcludes; - case SyntaxKind.ObjectLiteralExpression: - return TransformFlags.ObjectLiteralExcludes; - case SyntaxKind.CatchClause: - return TransformFlags.CatchClauseExcludes; - case SyntaxKind.ObjectBindingPattern: - case SyntaxKind.ArrayBindingPattern: - return TransformFlags.BindingPatternExcludes; - case SyntaxKind.TypeAssertionExpression: - case SyntaxKind.AsExpression: - case SyntaxKind.PartiallyEmittedExpression: - case SyntaxKind.ParenthesizedExpression: - case SyntaxKind.SuperKeyword: - return TransformFlags.OuterExpressionExcludes; - case SyntaxKind.PropertyAccessExpression: - case SyntaxKind.ElementAccessExpression: - return TransformFlags.PropertyAccessExcludes; + case ts.SyntaxKind.CallExpression: + case ts.SyntaxKind.NewExpression: + case ts.SyntaxKind.ArrayLiteralExpression: + return ts.TransformFlags.ArrayLiteralOrCallOrNewExcludes; + case ts.SyntaxKind.ModuleDeclaration: + return ts.TransformFlags.ModuleExcludes; + case ts.SyntaxKind.Parameter: + return ts.TransformFlags.ParameterExcludes; + case ts.SyntaxKind.ArrowFunction: + return ts.TransformFlags.ArrowFunctionExcludes; + case ts.SyntaxKind.FunctionExpression: + case ts.SyntaxKind.FunctionDeclaration: + return ts.TransformFlags.FunctionExcludes; + case ts.SyntaxKind.VariableDeclarationList: + return ts.TransformFlags.VariableDeclarationListExcludes; + case ts.SyntaxKind.ClassDeclaration: + case ts.SyntaxKind.ClassExpression: + return ts.TransformFlags.ClassExcludes; + case ts.SyntaxKind.Constructor: + return ts.TransformFlags.ConstructorExcludes; + case ts.SyntaxKind.PropertyDeclaration: + return ts.TransformFlags.PropertyExcludes; + case ts.SyntaxKind.MethodDeclaration: + case ts.SyntaxKind.GetAccessor: + case ts.SyntaxKind.SetAccessor: + return ts.TransformFlags.MethodOrAccessorExcludes; + case ts.SyntaxKind.AnyKeyword: + case ts.SyntaxKind.NumberKeyword: + case ts.SyntaxKind.BigIntKeyword: + case ts.SyntaxKind.NeverKeyword: + case ts.SyntaxKind.StringKeyword: + case ts.SyntaxKind.ObjectKeyword: + case ts.SyntaxKind.BooleanKeyword: + case ts.SyntaxKind.SymbolKeyword: + case ts.SyntaxKind.VoidKeyword: + case ts.SyntaxKind.TypeParameter: + case ts.SyntaxKind.PropertySignature: + case ts.SyntaxKind.MethodSignature: + case ts.SyntaxKind.CallSignature: + case ts.SyntaxKind.ConstructSignature: + case ts.SyntaxKind.IndexSignature: + case ts.SyntaxKind.InterfaceDeclaration: + case ts.SyntaxKind.TypeAliasDeclaration: + return ts.TransformFlags.TypeExcludes; + case ts.SyntaxKind.ObjectLiteralExpression: + return ts.TransformFlags.ObjectLiteralExcludes; + case ts.SyntaxKind.CatchClause: + return ts.TransformFlags.CatchClauseExcludes; + case ts.SyntaxKind.ObjectBindingPattern: + case ts.SyntaxKind.ArrayBindingPattern: + return ts.TransformFlags.BindingPatternExcludes; + case ts.SyntaxKind.TypeAssertionExpression: + case ts.SyntaxKind.AsExpression: + case ts.SyntaxKind.PartiallyEmittedExpression: + case ts.SyntaxKind.ParenthesizedExpression: + case ts.SyntaxKind.SuperKeyword: + return ts.TransformFlags.OuterExpressionExcludes; + case ts.SyntaxKind.PropertyAccessExpression: + case ts.SyntaxKind.ElementAccessExpression: + return ts.TransformFlags.PropertyAccessExcludes; default: - return TransformFlags.NodeExcludes; + return ts.TransformFlags.NodeExcludes; } } - const baseFactory = createBaseNodeFactory(); - - function makeSynthetic(node: Node) { - (node as Mutable).flags |= NodeFlags.Synthesized; + const baseFactory = ts.createBaseNodeFactory(); + function makeSynthetic(node: ts.Node) { + (node as ts.Mutable).flags |= ts.NodeFlags.Synthesized; return node; } - const syntheticFactory: BaseNodeFactory = { + const syntheticFactory: ts.BaseNodeFactory = { createBaseSourceFileNode: kind => makeSynthetic(baseFactory.createBaseSourceFileNode(kind)), createBaseIdentifierNode: kind => makeSynthetic(baseFactory.createBaseIdentifierNode(kind)), createBasePrivateIdentifierNode: kind => makeSynthetic(baseFactory.createBasePrivateIdentifierNode(kind)), @@ -6465,12 +5765,12 @@ namespace ts { export const factory = createNodeFactory(NodeFactoryFlags.NoIndentationOnFreshPropertyAccess, syntheticFactory); - export function createUnparsedSourceFile(text: string): UnparsedSource; - export function createUnparsedSourceFile(inputFile: InputFiles, type: "js" | "dts", stripInternal?: boolean): UnparsedSource; - export function createUnparsedSourceFile(text: string, mapPath: string | undefined, map: string | undefined): UnparsedSource; - export function createUnparsedSourceFile(textOrInputFiles: string | InputFiles, mapPathOrType?: string, mapTextOrStripInternal?: string | boolean): UnparsedSource { + export function createUnparsedSourceFile(text: string): ts.UnparsedSource; + export function createUnparsedSourceFile(inputFile: ts.InputFiles, type: "js" | "dts", stripInternal?: boolean): ts.UnparsedSource; + export function createUnparsedSourceFile(text: string, mapPath: string | undefined, map: string | undefined): ts.UnparsedSource; + export function createUnparsedSourceFile(textOrInputFiles: string | ts.InputFiles, mapPathOrType?: string, mapTextOrStripInternal?: string | boolean): ts.UnparsedSource { let stripInternal: boolean | undefined; - let bundleFileInfo: BundleFileInfo | undefined; + let bundleFileInfo: ts.BundleFileInfo | undefined; let fileName: string; let text: string | undefined; let length: number | (() => number); @@ -6480,15 +5780,15 @@ namespace ts { let getSourceMapText: (() => string | undefined) | undefined; let oldFileOfCurrentEmit: boolean | undefined; - if (!isString(textOrInputFiles)) { - Debug.assert(mapPathOrType === "js" || mapPathOrType === "dts"); + if (!ts.isString(textOrInputFiles)) { + ts.Debug.assert(mapPathOrType === "js" || mapPathOrType === "dts"); fileName = (mapPathOrType === "js" ? textOrInputFiles.javascriptPath : textOrInputFiles.declarationPath) || ""; sourceMapPath = mapPathOrType === "js" ? textOrInputFiles.javascriptMapPath : textOrInputFiles.declarationMapPath; getText = () => mapPathOrType === "js" ? textOrInputFiles.javascriptText : textOrInputFiles.declarationText; getSourceMapText = () => mapPathOrType === "js" ? textOrInputFiles.javascriptMapText : textOrInputFiles.declarationMapText; length = () => getText!().length; if (textOrInputFiles.buildInfo && textOrInputFiles.buildInfo.bundle) { - Debug.assert(mapTextOrStripInternal === undefined || typeof mapTextOrStripInternal === "boolean"); + ts.Debug.assert(mapTextOrStripInternal === undefined || typeof mapTextOrStripInternal === "boolean"); stripInternal = mapTextOrStripInternal; bundleFileInfo = mapPathOrType === "js" ? textOrInputFiles.buildInfo.bundle.js : textOrInputFiles.buildInfo.bundle.dts; oldFileOfCurrentEmit = textOrInputFiles.oldFileOfCurrentEmit; @@ -6502,7 +5802,7 @@ namespace ts { sourceMapText = mapTextOrStripInternal as string; } const node = oldFileOfCurrentEmit ? - parseOldFileOfCurrentEmit(Debug.checkDefined(bundleFileInfo)) : + parseOldFileOfCurrentEmit(ts.Debug.checkDefined(bundleFileInfo)) : parseUnparsedSourceFile(bundleFileInfo, stripInternal, length); node.fileName = fileName; node.sourceMapPath = sourceMapPath; @@ -6512,7 +5812,7 @@ namespace ts { Object.defineProperty(node, "sourceMapText", { get: getSourceMapText }); } else { - Debug.assert(!oldFileOfCurrentEmit); + ts.Debug.assert(!oldFileOfCurrentEmit); node.text = text ?? ""; node.sourceMapText = sourceMapText; } @@ -6520,175 +5820,136 @@ namespace ts { return node; } - function parseUnparsedSourceFile(bundleFileInfo: BundleFileInfo | undefined, stripInternal: boolean | undefined, length: number | (() => number)) { - let prologues: UnparsedPrologue[] | undefined; - let helpers: UnscopedEmitHelper[] | undefined; - let referencedFiles: FileReference[] | undefined; - let typeReferenceDirectives: FileReference[] | undefined; - let libReferenceDirectives: FileReference[] | undefined; - let prependChildren: UnparsedTextLike[] | undefined; - let texts: UnparsedSourceText[] | undefined; + function parseUnparsedSourceFile(bundleFileInfo: ts.BundleFileInfo | undefined, stripInternal: boolean | undefined, length: number | (() => number)) { + let prologues: ts.UnparsedPrologue[] | undefined; + let helpers: ts.UnscopedEmitHelper[] | undefined; + let referencedFiles: ts.FileReference[] | undefined; + let typeReferenceDirectives: ts.FileReference[] | undefined; + let libReferenceDirectives: ts.FileReference[] | undefined; + let prependChildren: ts.UnparsedTextLike[] | undefined; + let texts: ts.UnparsedSourceText[] | undefined; let hasNoDefaultLib: boolean | undefined; - for (const section of bundleFileInfo ? bundleFileInfo.sections : emptyArray) { + for (const section of bundleFileInfo ? bundleFileInfo.sections : ts.emptyArray) { switch (section.kind) { - case BundleFileSectionKind.Prologue: - prologues = append(prologues, setTextRange(factory.createUnparsedPrologue(section.data), section)); + case ts.BundleFileSectionKind.Prologue: + prologues = ts.append(prologues, ts.setTextRange(factory.createUnparsedPrologue(section.data), section)); break; - case BundleFileSectionKind.EmitHelpers: - helpers = append(helpers, getAllUnscopedEmitHelpers().get(section.data)!); + case ts.BundleFileSectionKind.EmitHelpers: + helpers = ts.append(helpers, ts.getAllUnscopedEmitHelpers().get(section.data)!); break; - case BundleFileSectionKind.NoDefaultLib: + case ts.BundleFileSectionKind.NoDefaultLib: hasNoDefaultLib = true; break; - case BundleFileSectionKind.Reference: - referencedFiles = append(referencedFiles, { pos: -1, end: -1, fileName: section.data }); + case ts.BundleFileSectionKind.Reference: + referencedFiles = ts.append(referencedFiles, { pos: -1, end: -1, fileName: section.data }); break; - case BundleFileSectionKind.Type: - typeReferenceDirectives = append(typeReferenceDirectives, { pos: -1, end: -1, fileName: section.data }); + case ts.BundleFileSectionKind.Type: + typeReferenceDirectives = ts.append(typeReferenceDirectives, { pos: -1, end: -1, fileName: section.data }); break; - case BundleFileSectionKind.TypeResolutionModeImport: - typeReferenceDirectives = append(typeReferenceDirectives, { pos: -1, end: -1, fileName: section.data, resolutionMode: ModuleKind.ESNext }); + case ts.BundleFileSectionKind.TypeResolutionModeImport: + typeReferenceDirectives = ts.append(typeReferenceDirectives, { pos: -1, end: -1, fileName: section.data, resolutionMode: ts.ModuleKind.ESNext }); break; - case BundleFileSectionKind.TypeResolutionModeRequire: - typeReferenceDirectives = append(typeReferenceDirectives, { pos: -1, end: -1, fileName: section.data, resolutionMode: ModuleKind.CommonJS }); + case ts.BundleFileSectionKind.TypeResolutionModeRequire: + typeReferenceDirectives = ts.append(typeReferenceDirectives, { pos: -1, end: -1, fileName: section.data, resolutionMode: ts.ModuleKind.CommonJS }); break; - case BundleFileSectionKind.Lib: - libReferenceDirectives = append(libReferenceDirectives, { pos: -1, end: -1, fileName: section.data }); + case ts.BundleFileSectionKind.Lib: + libReferenceDirectives = ts.append(libReferenceDirectives, { pos: -1, end: -1, fileName: section.data }); break; - case BundleFileSectionKind.Prepend: - let prependTexts: UnparsedTextLike[] | undefined; + case ts.BundleFileSectionKind.Prepend: + let prependTexts: ts.UnparsedTextLike[] | undefined; for (const text of section.texts) { - if (!stripInternal || text.kind !== BundleFileSectionKind.Internal) { - prependTexts = append(prependTexts, setTextRange(factory.createUnparsedTextLike(text.data, text.kind === BundleFileSectionKind.Internal), text)); + if (!stripInternal || text.kind !== ts.BundleFileSectionKind.Internal) { + prependTexts = ts.append(prependTexts, ts.setTextRange(factory.createUnparsedTextLike(text.data, text.kind === ts.BundleFileSectionKind.Internal), text)); } } - prependChildren = addRange(prependChildren, prependTexts); - texts = append(texts, factory.createUnparsedPrepend(section.data, prependTexts ?? emptyArray)); + prependChildren = ts.addRange(prependChildren, prependTexts); + texts = ts.append(texts, factory.createUnparsedPrepend(section.data, prependTexts ?? ts.emptyArray)); break; - case BundleFileSectionKind.Internal: + case ts.BundleFileSectionKind.Internal: if (stripInternal) { - if (!texts) texts = []; + if (!texts) + texts = []; break; } // falls through - case BundleFileSectionKind.Text: - texts = append(texts, setTextRange(factory.createUnparsedTextLike(section.data, section.kind === BundleFileSectionKind.Internal), section)); + case ts.BundleFileSectionKind.Text: + texts = ts.append(texts, ts.setTextRange(factory.createUnparsedTextLike(section.data, section.kind === ts.BundleFileSectionKind.Internal), section)); break; default: - Debug.assertNever(section); + ts.Debug.assertNever(section); } } if (!texts) { const textNode = factory.createUnparsedTextLike(/*data*/ undefined, /*internal*/ false); - setTextRangePosWidth(textNode, 0, typeof length === "function" ? length() : length); + ts.setTextRangePosWidth(textNode, 0, typeof length === "function" ? length() : length); texts = [textNode]; } - const node = parseNodeFactory.createUnparsedSource(prologues ?? emptyArray, /*syntheticReferences*/ undefined, texts); - setEachParent(prologues, node); - setEachParent(texts, node); - setEachParent(prependChildren, node); + const node = ts.parseNodeFactory.createUnparsedSource(prologues ?? ts.emptyArray, /*syntheticReferences*/ undefined, texts); + ts.setEachParent(prologues, node); + ts.setEachParent(texts, node); + ts.setEachParent(prependChildren, node); node.hasNoDefaultLib = hasNoDefaultLib; node.helpers = helpers; - node.referencedFiles = referencedFiles || emptyArray; + node.referencedFiles = referencedFiles || ts.emptyArray; node.typeReferenceDirectives = typeReferenceDirectives; - node.libReferenceDirectives = libReferenceDirectives || emptyArray; + node.libReferenceDirectives = libReferenceDirectives || ts.emptyArray; return node; } - function parseOldFileOfCurrentEmit(bundleFileInfo: BundleFileInfo) { - let texts: UnparsedTextLike[] | undefined; - let syntheticReferences: UnparsedSyntheticReference[] | undefined; + function parseOldFileOfCurrentEmit(bundleFileInfo: ts.BundleFileInfo) { + let texts: ts.UnparsedTextLike[] | undefined; + let syntheticReferences: ts.UnparsedSyntheticReference[] | undefined; for (const section of bundleFileInfo.sections) { switch (section.kind) { - case BundleFileSectionKind.Internal: - case BundleFileSectionKind.Text: - texts = append(texts, setTextRange(factory.createUnparsedTextLike(section.data, section.kind === BundleFileSectionKind.Internal), section)); + case ts.BundleFileSectionKind.Internal: + case ts.BundleFileSectionKind.Text: + texts = ts.append(texts, ts.setTextRange(factory.createUnparsedTextLike(section.data, section.kind === ts.BundleFileSectionKind.Internal), section)); break; - case BundleFileSectionKind.NoDefaultLib: - case BundleFileSectionKind.Reference: - case BundleFileSectionKind.Type: - case BundleFileSectionKind.TypeResolutionModeImport: - case BundleFileSectionKind.TypeResolutionModeRequire: - case BundleFileSectionKind.Lib: - syntheticReferences = append(syntheticReferences, setTextRange(factory.createUnparsedSyntheticReference(section), section)); + case ts.BundleFileSectionKind.NoDefaultLib: + case ts.BundleFileSectionKind.Reference: + case ts.BundleFileSectionKind.Type: + case ts.BundleFileSectionKind.TypeResolutionModeImport: + case ts.BundleFileSectionKind.TypeResolutionModeRequire: + case ts.BundleFileSectionKind.Lib: + syntheticReferences = ts.append(syntheticReferences, ts.setTextRange(factory.createUnparsedSyntheticReference(section), section)); break; // Ignore - case BundleFileSectionKind.Prologue: - case BundleFileSectionKind.EmitHelpers: - case BundleFileSectionKind.Prepend: + case ts.BundleFileSectionKind.Prologue: + case ts.BundleFileSectionKind.EmitHelpers: + case ts.BundleFileSectionKind.Prepend: break; default: - Debug.assertNever(section); + ts.Debug.assertNever(section); } } - const node = factory.createUnparsedSource(emptyArray, syntheticReferences, texts ?? emptyArray); - setEachParent(syntheticReferences, node); - setEachParent(texts, node); - node.helpers = map(bundleFileInfo.sources && bundleFileInfo.sources.helpers, name => getAllUnscopedEmitHelpers().get(name)!); + const node = factory.createUnparsedSource(ts.emptyArray, syntheticReferences, texts ?? ts.emptyArray); + ts.setEachParent(syntheticReferences, node); + ts.setEachParent(texts, node); + node.helpers = ts.map(bundleFileInfo.sources && bundleFileInfo.sources.helpers, name => ts.getAllUnscopedEmitHelpers().get(name)!); return node; } // TODO(rbuckton): Move part of this to factory - export function createInputFiles( - javascriptText: string, - declarationText: string - ): InputFiles; - export function createInputFiles( - readFileText: (path: string) => string | undefined, - javascriptPath: string, - javascriptMapPath: string | undefined, - declarationPath: string, - declarationMapPath: string | undefined, - buildInfoPath: string | undefined - ): InputFiles; - export function createInputFiles( - javascriptText: string, - declarationText: string, - javascriptMapPath: string | undefined, - javascriptMapText: string | undefined, - declarationMapPath: string | undefined, - declarationMapText: string | undefined - ): InputFiles; + export function createInputFiles(javascriptText: string, declarationText: string): ts.InputFiles; + export function createInputFiles(readFileText: (path: string) => string | undefined, javascriptPath: string, javascriptMapPath: string | undefined, declarationPath: string, declarationMapPath: string | undefined, buildInfoPath: string | undefined): ts.InputFiles; + export function createInputFiles(javascriptText: string, declarationText: string, javascriptMapPath: string | undefined, javascriptMapText: string | undefined, declarationMapPath: string | undefined, declarationMapText: string | undefined): ts.InputFiles; /*@internal*/ - export function createInputFiles( - javascriptText: string, - declarationText: string, - javascriptMapPath: string | undefined, - javascriptMapText: string | undefined, - declarationMapPath: string | undefined, - declarationMapText: string | undefined, - javascriptPath: string | undefined, - declarationPath: string | undefined, - buildInfoPath?: string | undefined, - buildInfo?: BuildInfo, - oldFileOfCurrentEmit?: boolean - ): InputFiles; - export function createInputFiles( - javascriptTextOrReadFileText: string | ((path: string) => string | undefined), - declarationTextOrJavascriptPath: string, - javascriptMapPath?: string, - javascriptMapTextOrDeclarationPath?: string, - declarationMapPath?: string, - declarationMapTextOrBuildInfoPath?: string, - javascriptPath?: string | undefined, - declarationPath?: string | undefined, - buildInfoPath?: string | undefined, - buildInfo?: BuildInfo, - oldFileOfCurrentEmit?: boolean - ): InputFiles { - const node = parseNodeFactory.createInputFiles(); - if (!isString(javascriptTextOrReadFileText)) { - const cache = new Map(); + export function createInputFiles(javascriptText: string, declarationText: string, javascriptMapPath: string | undefined, javascriptMapText: string | undefined, declarationMapPath: string | undefined, declarationMapText: string | undefined, javascriptPath: string | undefined, declarationPath: string | undefined, buildInfoPath?: string | undefined, buildInfo?: ts.BuildInfo, oldFileOfCurrentEmit?: boolean): ts.InputFiles; + export function createInputFiles(javascriptTextOrReadFileText: string | ((path: string) => string | undefined), declarationTextOrJavascriptPath: string, javascriptMapPath?: string, javascriptMapTextOrDeclarationPath?: string, declarationMapPath?: string, declarationMapTextOrBuildInfoPath?: string, javascriptPath?: string | undefined, declarationPath?: string | undefined, buildInfoPath?: string | undefined, buildInfo?: ts.BuildInfo, oldFileOfCurrentEmit?: boolean): ts.InputFiles { + const node = ts.parseNodeFactory.createInputFiles(); + if (!ts.isString(javascriptTextOrReadFileText)) { + const cache = new ts.Map(); const textGetter = (path: string | undefined) => { - if (path === undefined) return undefined; + if (path === undefined) + return undefined; let value = cache.get(path); if (value === undefined) { value = javascriptTextOrReadFileText(path); @@ -6700,24 +5961,24 @@ namespace ts { const result = textGetter(path); return result !== undefined ? result : `/* Input file ${path} was missing */\r\n`; }; - let buildInfo: BuildInfo | false; + let buildInfo: ts.BuildInfo | false; const getAndCacheBuildInfo = (getText: () => string | undefined) => { if (buildInfo === undefined) { const result = getText(); - buildInfo = result !== undefined ? getBuildInfo(result) : false; + buildInfo = result !== undefined ? ts.getBuildInfo(result) : false; } return buildInfo || undefined; }; node.javascriptPath = declarationTextOrJavascriptPath; node.javascriptMapPath = javascriptMapPath; - node.declarationPath = Debug.checkDefined(javascriptMapTextOrDeclarationPath); + node.declarationPath = ts.Debug.checkDefined(javascriptMapTextOrDeclarationPath); node.declarationMapPath = declarationMapPath; node.buildInfoPath = declarationMapTextOrBuildInfoPath; Object.defineProperties(node, { javascriptText: { get() { return definedTextGetter(declarationTextOrJavascriptPath); } }, - javascriptMapText: { get() { return textGetter(javascriptMapPath); } }, // TODO:: if there is inline sourceMap in jsFile, use that - declarationText: { get() { return definedTextGetter(Debug.checkDefined(javascriptMapTextOrDeclarationPath)); } }, - declarationMapText: { get() { return textGetter(declarationMapPath); } }, // TODO:: if there is inline sourceMap in dtsFile, use that + javascriptMapText: { get() { return textGetter(javascriptMapPath); } }, + declarationText: { get() { return definedTextGetter(ts.Debug.checkDefined(javascriptMapTextOrDeclarationPath)); } }, + declarationMapText: { get() { return textGetter(declarationMapPath); } }, buildInfo: { get() { return getAndCacheBuildInfo(() => textGetter(declarationMapTextOrBuildInfoPath)); } } }); } @@ -6738,58 +5999,59 @@ namespace ts { } // tslint:disable-next-line variable-name - let SourceMapSource: new (fileName: string, text: string, skipTrivia?: (pos: number) => number) => SourceMapSource; + let SourceMapSource: new (fileName: string, text: string, skipTrivia?: (pos: number) => number) => ts.SourceMapSource; /** * Create an external source map source file reference */ - export function createSourceMapSource(fileName: string, text: string, skipTrivia?: (pos: number) => number): SourceMapSource { - return new (SourceMapSource || (SourceMapSource = objectAllocator.getSourceMapSourceConstructor()))(fileName, text, skipTrivia); + export function createSourceMapSource(fileName: string, text: string, skipTrivia?: (pos: number) => number): ts.SourceMapSource { + return new (SourceMapSource || (SourceMapSource = ts.objectAllocator.getSourceMapSourceConstructor()))(fileName, text, skipTrivia); } // Utilities - export function setOriginalNode(node: T, original: Node | undefined): T { + export function setOriginalNode(node: T, original: ts.Node | undefined): T { node.original = original; if (original) { const emitNode = original.emitNode; - if (emitNode) node.emitNode = mergeEmitNode(emitNode, node.emitNode); + if (emitNode) + node.emitNode = mergeEmitNode(emitNode, node.emitNode); } return node; } - function mergeEmitNode(sourceEmitNode: EmitNode, destEmitNode: EmitNode | undefined) { - const { - flags, - leadingComments, - trailingComments, - commentRange, - sourceMapRange, - tokenSourceMapRanges, - constantValue, - helpers, - startsOnNewLine, - } = sourceEmitNode; - if (!destEmitNode) destEmitNode = {} as EmitNode; + function mergeEmitNode(sourceEmitNode: ts.EmitNode, destEmitNode: ts.EmitNode | undefined) { + const { flags, leadingComments, trailingComments, commentRange, sourceMapRange, tokenSourceMapRanges, constantValue, helpers, startsOnNewLine, } = sourceEmitNode; + if (!destEmitNode) + destEmitNode = {} as ts.EmitNode; // We are using `.slice()` here in case `destEmitNode.leadingComments` is pushed to later. - if (leadingComments) destEmitNode.leadingComments = addRange(leadingComments.slice(), destEmitNode.leadingComments); - if (trailingComments) destEmitNode.trailingComments = addRange(trailingComments.slice(), destEmitNode.trailingComments); - if (flags) destEmitNode.flags = flags & ~EmitFlags.Immutable; - if (commentRange) destEmitNode.commentRange = commentRange; - if (sourceMapRange) destEmitNode.sourceMapRange = sourceMapRange; - if (tokenSourceMapRanges) destEmitNode.tokenSourceMapRanges = mergeTokenSourceMapRanges(tokenSourceMapRanges, destEmitNode.tokenSourceMapRanges!); - if (constantValue !== undefined) destEmitNode.constantValue = constantValue; + if (leadingComments) + destEmitNode.leadingComments = ts.addRange(leadingComments.slice(), destEmitNode.leadingComments); + if (trailingComments) + destEmitNode.trailingComments = ts.addRange(trailingComments.slice(), destEmitNode.trailingComments); + if (flags) + destEmitNode.flags = flags & ~ts.EmitFlags.Immutable; + if (commentRange) + destEmitNode.commentRange = commentRange; + if (sourceMapRange) + destEmitNode.sourceMapRange = sourceMapRange; + if (tokenSourceMapRanges) + destEmitNode.tokenSourceMapRanges = mergeTokenSourceMapRanges(tokenSourceMapRanges, destEmitNode.tokenSourceMapRanges!); + if (constantValue !== undefined) + destEmitNode.constantValue = constantValue; if (helpers) { for (const helper of helpers) { - destEmitNode.helpers = appendIfUnique(destEmitNode.helpers, helper); + destEmitNode.helpers = ts.appendIfUnique(destEmitNode.helpers, helper); } } - if (startsOnNewLine !== undefined) destEmitNode.startsOnNewLine = startsOnNewLine; + if (startsOnNewLine !== undefined) + destEmitNode.startsOnNewLine = startsOnNewLine; return destEmitNode; } - function mergeTokenSourceMapRanges(sourceRanges: (TextRange | undefined)[], destRanges: (TextRange | undefined)[]) { - if (!destRanges) destRanges = []; + function mergeTokenSourceMapRanges(sourceRanges: (ts.TextRange | undefined)[], destRanges: (ts.TextRange | undefined)[]) { + if (!destRanges) + destRanges = []; for (const key in sourceRanges) { destRanges[key] = sourceRanges[key]; } diff --git a/src/compiler/factory/nodeTests.ts b/src/compiler/factory/nodeTests.ts index cf473caf65bf7..8fe19d157441e 100644 --- a/src/compiler/factory/nodeTests.ts +++ b/src/compiler/factory/nodeTests.ts @@ -1,761 +1,761 @@ namespace ts { // Literals - export function isNumericLiteral(node: Node): node is NumericLiteral { - return node.kind === SyntaxKind.NumericLiteral; + export function isNumericLiteral(node: ts.Node): node is ts.NumericLiteral { + return node.kind === ts.SyntaxKind.NumericLiteral; } - export function isBigIntLiteral(node: Node): node is BigIntLiteral { - return node.kind === SyntaxKind.BigIntLiteral; + export function isBigIntLiteral(node: ts.Node): node is ts.BigIntLiteral { + return node.kind === ts.SyntaxKind.BigIntLiteral; } - export function isStringLiteral(node: Node): node is StringLiteral { - return node.kind === SyntaxKind.StringLiteral; + export function isStringLiteral(node: ts.Node): node is ts.StringLiteral { + return node.kind === ts.SyntaxKind.StringLiteral; } - export function isJsxText(node: Node): node is JsxText { - return node.kind === SyntaxKind.JsxText; + export function isJsxText(node: ts.Node): node is ts.JsxText { + return node.kind === ts.SyntaxKind.JsxText; } - export function isRegularExpressionLiteral(node: Node): node is RegularExpressionLiteral { - return node.kind === SyntaxKind.RegularExpressionLiteral; + export function isRegularExpressionLiteral(node: ts.Node): node is ts.RegularExpressionLiteral { + return node.kind === ts.SyntaxKind.RegularExpressionLiteral; } - export function isNoSubstitutionTemplateLiteral(node: Node): node is NoSubstitutionTemplateLiteral { - return node.kind === SyntaxKind.NoSubstitutionTemplateLiteral; + export function isNoSubstitutionTemplateLiteral(node: ts.Node): node is ts.NoSubstitutionTemplateLiteral { + return node.kind === ts.SyntaxKind.NoSubstitutionTemplateLiteral; } // Pseudo-literals - export function isTemplateHead(node: Node): node is TemplateHead { - return node.kind === SyntaxKind.TemplateHead; + export function isTemplateHead(node: ts.Node): node is ts.TemplateHead { + return node.kind === ts.SyntaxKind.TemplateHead; } - export function isTemplateMiddle(node: Node): node is TemplateMiddle { - return node.kind === SyntaxKind.TemplateMiddle; + export function isTemplateMiddle(node: ts.Node): node is ts.TemplateMiddle { + return node.kind === ts.SyntaxKind.TemplateMiddle; } - export function isTemplateTail(node: Node): node is TemplateTail { - return node.kind === SyntaxKind.TemplateTail; + export function isTemplateTail(node: ts.Node): node is ts.TemplateTail { + return node.kind === ts.SyntaxKind.TemplateTail; } // Punctuation - export function isDotDotDotToken(node: Node): node is DotDotDotToken { - return node.kind === SyntaxKind.DotDotDotToken; + export function isDotDotDotToken(node: ts.Node): node is ts.DotDotDotToken { + return node.kind === ts.SyntaxKind.DotDotDotToken; } /*@internal*/ - export function isCommaToken(node: Node): node is Token { - return node.kind === SyntaxKind.CommaToken; + export function isCommaToken(node: ts.Node): node is ts.Token { + return node.kind === ts.SyntaxKind.CommaToken; } - export function isPlusToken(node: Node): node is PlusToken { - return node.kind === SyntaxKind.PlusToken; + export function isPlusToken(node: ts.Node): node is ts.PlusToken { + return node.kind === ts.SyntaxKind.PlusToken; } - export function isMinusToken(node: Node): node is MinusToken { - return node.kind === SyntaxKind.MinusToken; + export function isMinusToken(node: ts.Node): node is ts.MinusToken { + return node.kind === ts.SyntaxKind.MinusToken; } - export function isAsteriskToken(node: Node): node is AsteriskToken { - return node.kind === SyntaxKind.AsteriskToken; + export function isAsteriskToken(node: ts.Node): node is ts.AsteriskToken { + return node.kind === ts.SyntaxKind.AsteriskToken; } /*@internal*/ - export function isExclamationToken(node: Node): node is ExclamationToken { - return node.kind === SyntaxKind.ExclamationToken; + export function isExclamationToken(node: ts.Node): node is ts.ExclamationToken { + return node.kind === ts.SyntaxKind.ExclamationToken; } /*@internal*/ - export function isQuestionToken(node: Node): node is QuestionToken { - return node.kind === SyntaxKind.QuestionToken; + export function isQuestionToken(node: ts.Node): node is ts.QuestionToken { + return node.kind === ts.SyntaxKind.QuestionToken; } /*@internal*/ - export function isColonToken(node: Node): node is ColonToken { - return node.kind === SyntaxKind.ColonToken; + export function isColonToken(node: ts.Node): node is ts.ColonToken { + return node.kind === ts.SyntaxKind.ColonToken; } /*@internal*/ - export function isQuestionDotToken(node: Node): node is QuestionDotToken { - return node.kind === SyntaxKind.QuestionDotToken; + export function isQuestionDotToken(node: ts.Node): node is ts.QuestionDotToken { + return node.kind === ts.SyntaxKind.QuestionDotToken; } /*@internal*/ - export function isEqualsGreaterThanToken(node: Node): node is EqualsGreaterThanToken { - return node.kind === SyntaxKind.EqualsGreaterThanToken; + export function isEqualsGreaterThanToken(node: ts.Node): node is ts.EqualsGreaterThanToken { + return node.kind === ts.SyntaxKind.EqualsGreaterThanToken; } // Identifiers - export function isIdentifier(node: Node): node is Identifier { - return node.kind === SyntaxKind.Identifier; + export function isIdentifier(node: ts.Node): node is ts.Identifier { + return node.kind === ts.SyntaxKind.Identifier; } - export function isPrivateIdentifier(node: Node): node is PrivateIdentifier { - return node.kind === SyntaxKind.PrivateIdentifier; + export function isPrivateIdentifier(node: ts.Node): node is ts.PrivateIdentifier { + return node.kind === ts.SyntaxKind.PrivateIdentifier; } // Reserved Words /* @internal */ - export function isExportModifier(node: Node): node is ExportKeyword { - return node.kind === SyntaxKind.ExportKeyword; + export function isExportModifier(node: ts.Node): node is ts.ExportKeyword { + return node.kind === ts.SyntaxKind.ExportKeyword; } /* @internal */ - export function isAsyncModifier(node: Node): node is AsyncKeyword { - return node.kind === SyntaxKind.AsyncKeyword; + export function isAsyncModifier(node: ts.Node): node is ts.AsyncKeyword { + return node.kind === ts.SyntaxKind.AsyncKeyword; } /* @internal */ - export function isAssertsKeyword(node: Node): node is AssertsKeyword { - return node.kind === SyntaxKind.AssertsKeyword; + export function isAssertsKeyword(node: ts.Node): node is ts.AssertsKeyword { + return node.kind === ts.SyntaxKind.AssertsKeyword; } /* @internal */ - export function isAwaitKeyword(node: Node): node is AwaitKeyword { - return node.kind === SyntaxKind.AwaitKeyword; + export function isAwaitKeyword(node: ts.Node): node is ts.AwaitKeyword { + return node.kind === ts.SyntaxKind.AwaitKeyword; } /* @internal */ - export function isReadonlyKeyword(node: Node): node is ReadonlyKeyword { - return node.kind === SyntaxKind.ReadonlyKeyword; + export function isReadonlyKeyword(node: ts.Node): node is ts.ReadonlyKeyword { + return node.kind === ts.SyntaxKind.ReadonlyKeyword; } /* @internal */ - export function isStaticModifier(node: Node): node is StaticKeyword { - return node.kind === SyntaxKind.StaticKeyword; + export function isStaticModifier(node: ts.Node): node is ts.StaticKeyword { + return node.kind === ts.SyntaxKind.StaticKeyword; } /* @internal */ - export function isAbstractModifier(node: Node): node is AbstractKeyword { - return node.kind === SyntaxKind.AbstractKeyword; + export function isAbstractModifier(node: ts.Node): node is ts.AbstractKeyword { + return node.kind === ts.SyntaxKind.AbstractKeyword; } /*@internal*/ - export function isSuperKeyword(node: Node): node is SuperExpression { - return node.kind === SyntaxKind.SuperKeyword; + export function isSuperKeyword(node: ts.Node): node is ts.SuperExpression { + return node.kind === ts.SyntaxKind.SuperKeyword; } /*@internal*/ - export function isImportKeyword(node: Node): node is ImportExpression { - return node.kind === SyntaxKind.ImportKeyword; + export function isImportKeyword(node: ts.Node): node is ts.ImportExpression { + return node.kind === ts.SyntaxKind.ImportKeyword; } // Names - export function isQualifiedName(node: Node): node is QualifiedName { - return node.kind === SyntaxKind.QualifiedName; + export function isQualifiedName(node: ts.Node): node is ts.QualifiedName { + return node.kind === ts.SyntaxKind.QualifiedName; } - export function isComputedPropertyName(node: Node): node is ComputedPropertyName { - return node.kind === SyntaxKind.ComputedPropertyName; + export function isComputedPropertyName(node: ts.Node): node is ts.ComputedPropertyName { + return node.kind === ts.SyntaxKind.ComputedPropertyName; } // Signature elements - export function isTypeParameterDeclaration(node: Node): node is TypeParameterDeclaration { - return node.kind === SyntaxKind.TypeParameter; + export function isTypeParameterDeclaration(node: ts.Node): node is ts.TypeParameterDeclaration { + return node.kind === ts.SyntaxKind.TypeParameter; } // TODO(rbuckton): Rename to 'isParameterDeclaration' - export function isParameter(node: Node): node is ParameterDeclaration { - return node.kind === SyntaxKind.Parameter; + export function isParameter(node: ts.Node): node is ts.ParameterDeclaration { + return node.kind === ts.SyntaxKind.Parameter; } - export function isDecorator(node: Node): node is Decorator { - return node.kind === SyntaxKind.Decorator; + export function isDecorator(node: ts.Node): node is ts.Decorator { + return node.kind === ts.SyntaxKind.Decorator; } // TypeMember - export function isPropertySignature(node: Node): node is PropertySignature { - return node.kind === SyntaxKind.PropertySignature; + export function isPropertySignature(node: ts.Node): node is ts.PropertySignature { + return node.kind === ts.SyntaxKind.PropertySignature; } - export function isPropertyDeclaration(node: Node): node is PropertyDeclaration { - return node.kind === SyntaxKind.PropertyDeclaration; + export function isPropertyDeclaration(node: ts.Node): node is ts.PropertyDeclaration { + return node.kind === ts.SyntaxKind.PropertyDeclaration; } - export function isMethodSignature(node: Node): node is MethodSignature { - return node.kind === SyntaxKind.MethodSignature; + export function isMethodSignature(node: ts.Node): node is ts.MethodSignature { + return node.kind === ts.SyntaxKind.MethodSignature; } - export function isMethodDeclaration(node: Node): node is MethodDeclaration { - return node.kind === SyntaxKind.MethodDeclaration; + export function isMethodDeclaration(node: ts.Node): node is ts.MethodDeclaration { + return node.kind === ts.SyntaxKind.MethodDeclaration; } - export function isClassStaticBlockDeclaration(node: Node): node is ClassStaticBlockDeclaration { - return node.kind === SyntaxKind.ClassStaticBlockDeclaration; + export function isClassStaticBlockDeclaration(node: ts.Node): node is ts.ClassStaticBlockDeclaration { + return node.kind === ts.SyntaxKind.ClassStaticBlockDeclaration; } - export function isConstructorDeclaration(node: Node): node is ConstructorDeclaration { - return node.kind === SyntaxKind.Constructor; + export function isConstructorDeclaration(node: ts.Node): node is ts.ConstructorDeclaration { + return node.kind === ts.SyntaxKind.Constructor; } - export function isGetAccessorDeclaration(node: Node): node is GetAccessorDeclaration { - return node.kind === SyntaxKind.GetAccessor; + export function isGetAccessorDeclaration(node: ts.Node): node is ts.GetAccessorDeclaration { + return node.kind === ts.SyntaxKind.GetAccessor; } - export function isSetAccessorDeclaration(node: Node): node is SetAccessorDeclaration { - return node.kind === SyntaxKind.SetAccessor; + export function isSetAccessorDeclaration(node: ts.Node): node is ts.SetAccessorDeclaration { + return node.kind === ts.SyntaxKind.SetAccessor; } - export function isCallSignatureDeclaration(node: Node): node is CallSignatureDeclaration { - return node.kind === SyntaxKind.CallSignature; + export function isCallSignatureDeclaration(node: ts.Node): node is ts.CallSignatureDeclaration { + return node.kind === ts.SyntaxKind.CallSignature; } - export function isConstructSignatureDeclaration(node: Node): node is ConstructSignatureDeclaration { - return node.kind === SyntaxKind.ConstructSignature; + export function isConstructSignatureDeclaration(node: ts.Node): node is ts.ConstructSignatureDeclaration { + return node.kind === ts.SyntaxKind.ConstructSignature; } - export function isIndexSignatureDeclaration(node: Node): node is IndexSignatureDeclaration { - return node.kind === SyntaxKind.IndexSignature; + export function isIndexSignatureDeclaration(node: ts.Node): node is ts.IndexSignatureDeclaration { + return node.kind === ts.SyntaxKind.IndexSignature; } // Type - export function isTypePredicateNode(node: Node): node is TypePredicateNode { - return node.kind === SyntaxKind.TypePredicate; + export function isTypePredicateNode(node: ts.Node): node is ts.TypePredicateNode { + return node.kind === ts.SyntaxKind.TypePredicate; } - export function isTypeReferenceNode(node: Node): node is TypeReferenceNode { - return node.kind === SyntaxKind.TypeReference; + export function isTypeReferenceNode(node: ts.Node): node is ts.TypeReferenceNode { + return node.kind === ts.SyntaxKind.TypeReference; } - export function isFunctionTypeNode(node: Node): node is FunctionTypeNode { - return node.kind === SyntaxKind.FunctionType; + export function isFunctionTypeNode(node: ts.Node): node is ts.FunctionTypeNode { + return node.kind === ts.SyntaxKind.FunctionType; } - export function isConstructorTypeNode(node: Node): node is ConstructorTypeNode { - return node.kind === SyntaxKind.ConstructorType; + export function isConstructorTypeNode(node: ts.Node): node is ts.ConstructorTypeNode { + return node.kind === ts.SyntaxKind.ConstructorType; } - export function isTypeQueryNode(node: Node): node is TypeQueryNode { - return node.kind === SyntaxKind.TypeQuery; + export function isTypeQueryNode(node: ts.Node): node is ts.TypeQueryNode { + return node.kind === ts.SyntaxKind.TypeQuery; } - export function isTypeLiteralNode(node: Node): node is TypeLiteralNode { - return node.kind === SyntaxKind.TypeLiteral; + export function isTypeLiteralNode(node: ts.Node): node is ts.TypeLiteralNode { + return node.kind === ts.SyntaxKind.TypeLiteral; } - export function isArrayTypeNode(node: Node): node is ArrayTypeNode { - return node.kind === SyntaxKind.ArrayType; + export function isArrayTypeNode(node: ts.Node): node is ts.ArrayTypeNode { + return node.kind === ts.SyntaxKind.ArrayType; } - export function isTupleTypeNode(node: Node): node is TupleTypeNode { - return node.kind === SyntaxKind.TupleType; + export function isTupleTypeNode(node: ts.Node): node is ts.TupleTypeNode { + return node.kind === ts.SyntaxKind.TupleType; } - export function isNamedTupleMember(node: Node): node is NamedTupleMember { - return node.kind === SyntaxKind.NamedTupleMember; + export function isNamedTupleMember(node: ts.Node): node is ts.NamedTupleMember { + return node.kind === ts.SyntaxKind.NamedTupleMember; } - export function isOptionalTypeNode(node: Node): node is OptionalTypeNode { - return node.kind === SyntaxKind.OptionalType; + export function isOptionalTypeNode(node: ts.Node): node is ts.OptionalTypeNode { + return node.kind === ts.SyntaxKind.OptionalType; } - export function isRestTypeNode(node: Node): node is RestTypeNode { - return node.kind === SyntaxKind.RestType; + export function isRestTypeNode(node: ts.Node): node is ts.RestTypeNode { + return node.kind === ts.SyntaxKind.RestType; } - export function isUnionTypeNode(node: Node): node is UnionTypeNode { - return node.kind === SyntaxKind.UnionType; + export function isUnionTypeNode(node: ts.Node): node is ts.UnionTypeNode { + return node.kind === ts.SyntaxKind.UnionType; } - export function isIntersectionTypeNode(node: Node): node is IntersectionTypeNode { - return node.kind === SyntaxKind.IntersectionType; + export function isIntersectionTypeNode(node: ts.Node): node is ts.IntersectionTypeNode { + return node.kind === ts.SyntaxKind.IntersectionType; } - export function isConditionalTypeNode(node: Node): node is ConditionalTypeNode { - return node.kind === SyntaxKind.ConditionalType; + export function isConditionalTypeNode(node: ts.Node): node is ts.ConditionalTypeNode { + return node.kind === ts.SyntaxKind.ConditionalType; } - export function isInferTypeNode(node: Node): node is InferTypeNode { - return node.kind === SyntaxKind.InferType; + export function isInferTypeNode(node: ts.Node): node is ts.InferTypeNode { + return node.kind === ts.SyntaxKind.InferType; } - export function isParenthesizedTypeNode(node: Node): node is ParenthesizedTypeNode { - return node.kind === SyntaxKind.ParenthesizedType; + export function isParenthesizedTypeNode(node: ts.Node): node is ts.ParenthesizedTypeNode { + return node.kind === ts.SyntaxKind.ParenthesizedType; } - export function isThisTypeNode(node: Node): node is ThisTypeNode { - return node.kind === SyntaxKind.ThisType; + export function isThisTypeNode(node: ts.Node): node is ts.ThisTypeNode { + return node.kind === ts.SyntaxKind.ThisType; } - export function isTypeOperatorNode(node: Node): node is TypeOperatorNode { - return node.kind === SyntaxKind.TypeOperator; + export function isTypeOperatorNode(node: ts.Node): node is ts.TypeOperatorNode { + return node.kind === ts.SyntaxKind.TypeOperator; } - export function isIndexedAccessTypeNode(node: Node): node is IndexedAccessTypeNode { - return node.kind === SyntaxKind.IndexedAccessType; + export function isIndexedAccessTypeNode(node: ts.Node): node is ts.IndexedAccessTypeNode { + return node.kind === ts.SyntaxKind.IndexedAccessType; } - export function isMappedTypeNode(node: Node): node is MappedTypeNode { - return node.kind === SyntaxKind.MappedType; + export function isMappedTypeNode(node: ts.Node): node is ts.MappedTypeNode { + return node.kind === ts.SyntaxKind.MappedType; } - export function isLiteralTypeNode(node: Node): node is LiteralTypeNode { - return node.kind === SyntaxKind.LiteralType; + export function isLiteralTypeNode(node: ts.Node): node is ts.LiteralTypeNode { + return node.kind === ts.SyntaxKind.LiteralType; } - export function isImportTypeNode(node: Node): node is ImportTypeNode { - return node.kind === SyntaxKind.ImportType; + export function isImportTypeNode(node: ts.Node): node is ts.ImportTypeNode { + return node.kind === ts.SyntaxKind.ImportType; } - export function isTemplateLiteralTypeSpan(node: Node): node is TemplateLiteralTypeSpan { - return node.kind === SyntaxKind.TemplateLiteralTypeSpan; + export function isTemplateLiteralTypeSpan(node: ts.Node): node is ts.TemplateLiteralTypeSpan { + return node.kind === ts.SyntaxKind.TemplateLiteralTypeSpan; } - export function isTemplateLiteralTypeNode(node: Node): node is TemplateLiteralTypeNode { - return node.kind === SyntaxKind.TemplateLiteralType; + export function isTemplateLiteralTypeNode(node: ts.Node): node is ts.TemplateLiteralTypeNode { + return node.kind === ts.SyntaxKind.TemplateLiteralType; } // Binding patterns - export function isObjectBindingPattern(node: Node): node is ObjectBindingPattern { - return node.kind === SyntaxKind.ObjectBindingPattern; + export function isObjectBindingPattern(node: ts.Node): node is ts.ObjectBindingPattern { + return node.kind === ts.SyntaxKind.ObjectBindingPattern; } - export function isArrayBindingPattern(node: Node): node is ArrayBindingPattern { - return node.kind === SyntaxKind.ArrayBindingPattern; + export function isArrayBindingPattern(node: ts.Node): node is ts.ArrayBindingPattern { + return node.kind === ts.SyntaxKind.ArrayBindingPattern; } - export function isBindingElement(node: Node): node is BindingElement { - return node.kind === SyntaxKind.BindingElement; + export function isBindingElement(node: ts.Node): node is ts.BindingElement { + return node.kind === ts.SyntaxKind.BindingElement; } // Expression - export function isArrayLiteralExpression(node: Node): node is ArrayLiteralExpression { - return node.kind === SyntaxKind.ArrayLiteralExpression; + export function isArrayLiteralExpression(node: ts.Node): node is ts.ArrayLiteralExpression { + return node.kind === ts.SyntaxKind.ArrayLiteralExpression; } - export function isObjectLiteralExpression(node: Node): node is ObjectLiteralExpression { - return node.kind === SyntaxKind.ObjectLiteralExpression; + export function isObjectLiteralExpression(node: ts.Node): node is ts.ObjectLiteralExpression { + return node.kind === ts.SyntaxKind.ObjectLiteralExpression; } - export function isPropertyAccessExpression(node: Node): node is PropertyAccessExpression { - return node.kind === SyntaxKind.PropertyAccessExpression; + export function isPropertyAccessExpression(node: ts.Node): node is ts.PropertyAccessExpression { + return node.kind === ts.SyntaxKind.PropertyAccessExpression; } - export function isElementAccessExpression(node: Node): node is ElementAccessExpression { - return node.kind === SyntaxKind.ElementAccessExpression; + export function isElementAccessExpression(node: ts.Node): node is ts.ElementAccessExpression { + return node.kind === ts.SyntaxKind.ElementAccessExpression; } - export function isCallExpression(node: Node): node is CallExpression { - return node.kind === SyntaxKind.CallExpression; + export function isCallExpression(node: ts.Node): node is ts.CallExpression { + return node.kind === ts.SyntaxKind.CallExpression; } - export function isNewExpression(node: Node): node is NewExpression { - return node.kind === SyntaxKind.NewExpression; + export function isNewExpression(node: ts.Node): node is ts.NewExpression { + return node.kind === ts.SyntaxKind.NewExpression; } - export function isTaggedTemplateExpression(node: Node): node is TaggedTemplateExpression { - return node.kind === SyntaxKind.TaggedTemplateExpression; + export function isTaggedTemplateExpression(node: ts.Node): node is ts.TaggedTemplateExpression { + return node.kind === ts.SyntaxKind.TaggedTemplateExpression; } - export function isTypeAssertionExpression(node: Node): node is TypeAssertion { - return node.kind === SyntaxKind.TypeAssertionExpression; + export function isTypeAssertionExpression(node: ts.Node): node is ts.TypeAssertion { + return node.kind === ts.SyntaxKind.TypeAssertionExpression; } - export function isParenthesizedExpression(node: Node): node is ParenthesizedExpression { - return node.kind === SyntaxKind.ParenthesizedExpression; + export function isParenthesizedExpression(node: ts.Node): node is ts.ParenthesizedExpression { + return node.kind === ts.SyntaxKind.ParenthesizedExpression; } - export function isFunctionExpression(node: Node): node is FunctionExpression { - return node.kind === SyntaxKind.FunctionExpression; + export function isFunctionExpression(node: ts.Node): node is ts.FunctionExpression { + return node.kind === ts.SyntaxKind.FunctionExpression; } - export function isArrowFunction(node: Node): node is ArrowFunction { - return node.kind === SyntaxKind.ArrowFunction; + export function isArrowFunction(node: ts.Node): node is ts.ArrowFunction { + return node.kind === ts.SyntaxKind.ArrowFunction; } - export function isDeleteExpression(node: Node): node is DeleteExpression { - return node.kind === SyntaxKind.DeleteExpression; + export function isDeleteExpression(node: ts.Node): node is ts.DeleteExpression { + return node.kind === ts.SyntaxKind.DeleteExpression; } - export function isTypeOfExpression(node: Node): node is TypeOfExpression { - return node.kind === SyntaxKind.TypeOfExpression; + export function isTypeOfExpression(node: ts.Node): node is ts.TypeOfExpression { + return node.kind === ts.SyntaxKind.TypeOfExpression; } - export function isVoidExpression(node: Node): node is VoidExpression { - return node.kind === SyntaxKind.VoidExpression; + export function isVoidExpression(node: ts.Node): node is ts.VoidExpression { + return node.kind === ts.SyntaxKind.VoidExpression; } - export function isAwaitExpression(node: Node): node is AwaitExpression { - return node.kind === SyntaxKind.AwaitExpression; + export function isAwaitExpression(node: ts.Node): node is ts.AwaitExpression { + return node.kind === ts.SyntaxKind.AwaitExpression; } - export function isPrefixUnaryExpression(node: Node): node is PrefixUnaryExpression { - return node.kind === SyntaxKind.PrefixUnaryExpression; + export function isPrefixUnaryExpression(node: ts.Node): node is ts.PrefixUnaryExpression { + return node.kind === ts.SyntaxKind.PrefixUnaryExpression; } - export function isPostfixUnaryExpression(node: Node): node is PostfixUnaryExpression { - return node.kind === SyntaxKind.PostfixUnaryExpression; + export function isPostfixUnaryExpression(node: ts.Node): node is ts.PostfixUnaryExpression { + return node.kind === ts.SyntaxKind.PostfixUnaryExpression; } - export function isBinaryExpression(node: Node): node is BinaryExpression { - return node.kind === SyntaxKind.BinaryExpression; + export function isBinaryExpression(node: ts.Node): node is ts.BinaryExpression { + return node.kind === ts.SyntaxKind.BinaryExpression; } - export function isConditionalExpression(node: Node): node is ConditionalExpression { - return node.kind === SyntaxKind.ConditionalExpression; + export function isConditionalExpression(node: ts.Node): node is ts.ConditionalExpression { + return node.kind === ts.SyntaxKind.ConditionalExpression; } - export function isTemplateExpression(node: Node): node is TemplateExpression { - return node.kind === SyntaxKind.TemplateExpression; + export function isTemplateExpression(node: ts.Node): node is ts.TemplateExpression { + return node.kind === ts.SyntaxKind.TemplateExpression; } - export function isYieldExpression(node: Node): node is YieldExpression { - return node.kind === SyntaxKind.YieldExpression; + export function isYieldExpression(node: ts.Node): node is ts.YieldExpression { + return node.kind === ts.SyntaxKind.YieldExpression; } - export function isSpreadElement(node: Node): node is SpreadElement { - return node.kind === SyntaxKind.SpreadElement; + export function isSpreadElement(node: ts.Node): node is ts.SpreadElement { + return node.kind === ts.SyntaxKind.SpreadElement; } - export function isClassExpression(node: Node): node is ClassExpression { - return node.kind === SyntaxKind.ClassExpression; + export function isClassExpression(node: ts.Node): node is ts.ClassExpression { + return node.kind === ts.SyntaxKind.ClassExpression; } - export function isOmittedExpression(node: Node): node is OmittedExpression { - return node.kind === SyntaxKind.OmittedExpression; + export function isOmittedExpression(node: ts.Node): node is ts.OmittedExpression { + return node.kind === ts.SyntaxKind.OmittedExpression; } - export function isExpressionWithTypeArguments(node: Node): node is ExpressionWithTypeArguments { - return node.kind === SyntaxKind.ExpressionWithTypeArguments; + export function isExpressionWithTypeArguments(node: ts.Node): node is ts.ExpressionWithTypeArguments { + return node.kind === ts.SyntaxKind.ExpressionWithTypeArguments; } - export function isAsExpression(node: Node): node is AsExpression { - return node.kind === SyntaxKind.AsExpression; + export function isAsExpression(node: ts.Node): node is ts.AsExpression { + return node.kind === ts.SyntaxKind.AsExpression; } - export function isNonNullExpression(node: Node): node is NonNullExpression { - return node.kind === SyntaxKind.NonNullExpression; + export function isNonNullExpression(node: ts.Node): node is ts.NonNullExpression { + return node.kind === ts.SyntaxKind.NonNullExpression; } - export function isMetaProperty(node: Node): node is MetaProperty { - return node.kind === SyntaxKind.MetaProperty; + export function isMetaProperty(node: ts.Node): node is ts.MetaProperty { + return node.kind === ts.SyntaxKind.MetaProperty; } - export function isSyntheticExpression(node: Node): node is SyntheticExpression { - return node.kind === SyntaxKind.SyntheticExpression; + export function isSyntheticExpression(node: ts.Node): node is ts.SyntheticExpression { + return node.kind === ts.SyntaxKind.SyntheticExpression; } - export function isPartiallyEmittedExpression(node: Node): node is PartiallyEmittedExpression { - return node.kind === SyntaxKind.PartiallyEmittedExpression; + export function isPartiallyEmittedExpression(node: ts.Node): node is ts.PartiallyEmittedExpression { + return node.kind === ts.SyntaxKind.PartiallyEmittedExpression; } - export function isCommaListExpression(node: Node): node is CommaListExpression { - return node.kind === SyntaxKind.CommaListExpression; + export function isCommaListExpression(node: ts.Node): node is ts.CommaListExpression { + return node.kind === ts.SyntaxKind.CommaListExpression; } // Misc - export function isTemplateSpan(node: Node): node is TemplateSpan { - return node.kind === SyntaxKind.TemplateSpan; + export function isTemplateSpan(node: ts.Node): node is ts.TemplateSpan { + return node.kind === ts.SyntaxKind.TemplateSpan; } - export function isSemicolonClassElement(node: Node): node is SemicolonClassElement { - return node.kind === SyntaxKind.SemicolonClassElement; + export function isSemicolonClassElement(node: ts.Node): node is ts.SemicolonClassElement { + return node.kind === ts.SyntaxKind.SemicolonClassElement; } // Elements - export function isBlock(node: Node): node is Block { - return node.kind === SyntaxKind.Block; + export function isBlock(node: ts.Node): node is ts.Block { + return node.kind === ts.SyntaxKind.Block; } - export function isVariableStatement(node: Node): node is VariableStatement { - return node.kind === SyntaxKind.VariableStatement; + export function isVariableStatement(node: ts.Node): node is ts.VariableStatement { + return node.kind === ts.SyntaxKind.VariableStatement; } - export function isEmptyStatement(node: Node): node is EmptyStatement { - return node.kind === SyntaxKind.EmptyStatement; + export function isEmptyStatement(node: ts.Node): node is ts.EmptyStatement { + return node.kind === ts.SyntaxKind.EmptyStatement; } - export function isExpressionStatement(node: Node): node is ExpressionStatement { - return node.kind === SyntaxKind.ExpressionStatement; + export function isExpressionStatement(node: ts.Node): node is ts.ExpressionStatement { + return node.kind === ts.SyntaxKind.ExpressionStatement; } - export function isIfStatement(node: Node): node is IfStatement { - return node.kind === SyntaxKind.IfStatement; + export function isIfStatement(node: ts.Node): node is ts.IfStatement { + return node.kind === ts.SyntaxKind.IfStatement; } - export function isDoStatement(node: Node): node is DoStatement { - return node.kind === SyntaxKind.DoStatement; + export function isDoStatement(node: ts.Node): node is ts.DoStatement { + return node.kind === ts.SyntaxKind.DoStatement; } - export function isWhileStatement(node: Node): node is WhileStatement { - return node.kind === SyntaxKind.WhileStatement; + export function isWhileStatement(node: ts.Node): node is ts.WhileStatement { + return node.kind === ts.SyntaxKind.WhileStatement; } - export function isForStatement(node: Node): node is ForStatement { - return node.kind === SyntaxKind.ForStatement; + export function isForStatement(node: ts.Node): node is ts.ForStatement { + return node.kind === ts.SyntaxKind.ForStatement; } - export function isForInStatement(node: Node): node is ForInStatement { - return node.kind === SyntaxKind.ForInStatement; + export function isForInStatement(node: ts.Node): node is ts.ForInStatement { + return node.kind === ts.SyntaxKind.ForInStatement; } - export function isForOfStatement(node: Node): node is ForOfStatement { - return node.kind === SyntaxKind.ForOfStatement; + export function isForOfStatement(node: ts.Node): node is ts.ForOfStatement { + return node.kind === ts.SyntaxKind.ForOfStatement; } - export function isContinueStatement(node: Node): node is ContinueStatement { - return node.kind === SyntaxKind.ContinueStatement; + export function isContinueStatement(node: ts.Node): node is ts.ContinueStatement { + return node.kind === ts.SyntaxKind.ContinueStatement; } - export function isBreakStatement(node: Node): node is BreakStatement { - return node.kind === SyntaxKind.BreakStatement; + export function isBreakStatement(node: ts.Node): node is ts.BreakStatement { + return node.kind === ts.SyntaxKind.BreakStatement; } - export function isReturnStatement(node: Node): node is ReturnStatement { - return node.kind === SyntaxKind.ReturnStatement; + export function isReturnStatement(node: ts.Node): node is ts.ReturnStatement { + return node.kind === ts.SyntaxKind.ReturnStatement; } - export function isWithStatement(node: Node): node is WithStatement { - return node.kind === SyntaxKind.WithStatement; + export function isWithStatement(node: ts.Node): node is ts.WithStatement { + return node.kind === ts.SyntaxKind.WithStatement; } - export function isSwitchStatement(node: Node): node is SwitchStatement { - return node.kind === SyntaxKind.SwitchStatement; + export function isSwitchStatement(node: ts.Node): node is ts.SwitchStatement { + return node.kind === ts.SyntaxKind.SwitchStatement; } - export function isLabeledStatement(node: Node): node is LabeledStatement { - return node.kind === SyntaxKind.LabeledStatement; + export function isLabeledStatement(node: ts.Node): node is ts.LabeledStatement { + return node.kind === ts.SyntaxKind.LabeledStatement; } - export function isThrowStatement(node: Node): node is ThrowStatement { - return node.kind === SyntaxKind.ThrowStatement; + export function isThrowStatement(node: ts.Node): node is ts.ThrowStatement { + return node.kind === ts.SyntaxKind.ThrowStatement; } - export function isTryStatement(node: Node): node is TryStatement { - return node.kind === SyntaxKind.TryStatement; + export function isTryStatement(node: ts.Node): node is ts.TryStatement { + return node.kind === ts.SyntaxKind.TryStatement; } - export function isDebuggerStatement(node: Node): node is DebuggerStatement { - return node.kind === SyntaxKind.DebuggerStatement; + export function isDebuggerStatement(node: ts.Node): node is ts.DebuggerStatement { + return node.kind === ts.SyntaxKind.DebuggerStatement; } - export function isVariableDeclaration(node: Node): node is VariableDeclaration { - return node.kind === SyntaxKind.VariableDeclaration; + export function isVariableDeclaration(node: ts.Node): node is ts.VariableDeclaration { + return node.kind === ts.SyntaxKind.VariableDeclaration; } - export function isVariableDeclarationList(node: Node): node is VariableDeclarationList { - return node.kind === SyntaxKind.VariableDeclarationList; + export function isVariableDeclarationList(node: ts.Node): node is ts.VariableDeclarationList { + return node.kind === ts.SyntaxKind.VariableDeclarationList; } - export function isFunctionDeclaration(node: Node): node is FunctionDeclaration { - return node.kind === SyntaxKind.FunctionDeclaration; + export function isFunctionDeclaration(node: ts.Node): node is ts.FunctionDeclaration { + return node.kind === ts.SyntaxKind.FunctionDeclaration; } - export function isClassDeclaration(node: Node): node is ClassDeclaration { - return node.kind === SyntaxKind.ClassDeclaration; + export function isClassDeclaration(node: ts.Node): node is ts.ClassDeclaration { + return node.kind === ts.SyntaxKind.ClassDeclaration; } - export function isInterfaceDeclaration(node: Node): node is InterfaceDeclaration { - return node.kind === SyntaxKind.InterfaceDeclaration; + export function isInterfaceDeclaration(node: ts.Node): node is ts.InterfaceDeclaration { + return node.kind === ts.SyntaxKind.InterfaceDeclaration; } - export function isTypeAliasDeclaration(node: Node): node is TypeAliasDeclaration { - return node.kind === SyntaxKind.TypeAliasDeclaration; + export function isTypeAliasDeclaration(node: ts.Node): node is ts.TypeAliasDeclaration { + return node.kind === ts.SyntaxKind.TypeAliasDeclaration; } - export function isEnumDeclaration(node: Node): node is EnumDeclaration { - return node.kind === SyntaxKind.EnumDeclaration; + export function isEnumDeclaration(node: ts.Node): node is ts.EnumDeclaration { + return node.kind === ts.SyntaxKind.EnumDeclaration; } - export function isModuleDeclaration(node: Node): node is ModuleDeclaration { - return node.kind === SyntaxKind.ModuleDeclaration; + export function isModuleDeclaration(node: ts.Node): node is ts.ModuleDeclaration { + return node.kind === ts.SyntaxKind.ModuleDeclaration; } - export function isModuleBlock(node: Node): node is ModuleBlock { - return node.kind === SyntaxKind.ModuleBlock; + export function isModuleBlock(node: ts.Node): node is ts.ModuleBlock { + return node.kind === ts.SyntaxKind.ModuleBlock; } - export function isCaseBlock(node: Node): node is CaseBlock { - return node.kind === SyntaxKind.CaseBlock; + export function isCaseBlock(node: ts.Node): node is ts.CaseBlock { + return node.kind === ts.SyntaxKind.CaseBlock; } - export function isNamespaceExportDeclaration(node: Node): node is NamespaceExportDeclaration { - return node.kind === SyntaxKind.NamespaceExportDeclaration; + export function isNamespaceExportDeclaration(node: ts.Node): node is ts.NamespaceExportDeclaration { + return node.kind === ts.SyntaxKind.NamespaceExportDeclaration; } - export function isImportEqualsDeclaration(node: Node): node is ImportEqualsDeclaration { - return node.kind === SyntaxKind.ImportEqualsDeclaration; + export function isImportEqualsDeclaration(node: ts.Node): node is ts.ImportEqualsDeclaration { + return node.kind === ts.SyntaxKind.ImportEqualsDeclaration; } - export function isImportDeclaration(node: Node): node is ImportDeclaration { - return node.kind === SyntaxKind.ImportDeclaration; + export function isImportDeclaration(node: ts.Node): node is ts.ImportDeclaration { + return node.kind === ts.SyntaxKind.ImportDeclaration; } - export function isImportClause(node: Node): node is ImportClause { - return node.kind === SyntaxKind.ImportClause; + export function isImportClause(node: ts.Node): node is ts.ImportClause { + return node.kind === ts.SyntaxKind.ImportClause; } - export function isAssertClause(node: Node): node is AssertClause { - return node.kind === SyntaxKind.AssertClause; + export function isAssertClause(node: ts.Node): node is ts.AssertClause { + return node.kind === ts.SyntaxKind.AssertClause; } - export function isAssertEntry(node: Node): node is AssertEntry { - return node.kind === SyntaxKind.AssertEntry; + export function isAssertEntry(node: ts.Node): node is ts.AssertEntry { + return node.kind === ts.SyntaxKind.AssertEntry; } - export function isNamespaceImport(node: Node): node is NamespaceImport { - return node.kind === SyntaxKind.NamespaceImport; + export function isNamespaceImport(node: ts.Node): node is ts.NamespaceImport { + return node.kind === ts.SyntaxKind.NamespaceImport; } - export function isNamespaceExport(node: Node): node is NamespaceExport { - return node.kind === SyntaxKind.NamespaceExport; + export function isNamespaceExport(node: ts.Node): node is ts.NamespaceExport { + return node.kind === ts.SyntaxKind.NamespaceExport; } - export function isNamedImports(node: Node): node is NamedImports { - return node.kind === SyntaxKind.NamedImports; + export function isNamedImports(node: ts.Node): node is ts.NamedImports { + return node.kind === ts.SyntaxKind.NamedImports; } - export function isImportSpecifier(node: Node): node is ImportSpecifier { - return node.kind === SyntaxKind.ImportSpecifier; + export function isImportSpecifier(node: ts.Node): node is ts.ImportSpecifier { + return node.kind === ts.SyntaxKind.ImportSpecifier; } - export function isExportAssignment(node: Node): node is ExportAssignment { - return node.kind === SyntaxKind.ExportAssignment; + export function isExportAssignment(node: ts.Node): node is ts.ExportAssignment { + return node.kind === ts.SyntaxKind.ExportAssignment; } - export function isExportDeclaration(node: Node): node is ExportDeclaration { - return node.kind === SyntaxKind.ExportDeclaration; + export function isExportDeclaration(node: ts.Node): node is ts.ExportDeclaration { + return node.kind === ts.SyntaxKind.ExportDeclaration; } - export function isNamedExports(node: Node): node is NamedExports { - return node.kind === SyntaxKind.NamedExports; + export function isNamedExports(node: ts.Node): node is ts.NamedExports { + return node.kind === ts.SyntaxKind.NamedExports; } - export function isExportSpecifier(node: Node): node is ExportSpecifier { - return node.kind === SyntaxKind.ExportSpecifier; + export function isExportSpecifier(node: ts.Node): node is ts.ExportSpecifier { + return node.kind === ts.SyntaxKind.ExportSpecifier; } - export function isMissingDeclaration(node: Node): node is MissingDeclaration { - return node.kind === SyntaxKind.MissingDeclaration; + export function isMissingDeclaration(node: ts.Node): node is ts.MissingDeclaration { + return node.kind === ts.SyntaxKind.MissingDeclaration; } - export function isNotEmittedStatement(node: Node): node is NotEmittedStatement { - return node.kind === SyntaxKind.NotEmittedStatement; + export function isNotEmittedStatement(node: ts.Node): node is ts.NotEmittedStatement { + return node.kind === ts.SyntaxKind.NotEmittedStatement; } /* @internal */ - export function isSyntheticReference(node: Node): node is SyntheticReferenceExpression { - return node.kind === SyntaxKind.SyntheticReferenceExpression; + export function isSyntheticReference(node: ts.Node): node is ts.SyntheticReferenceExpression { + return node.kind === ts.SyntaxKind.SyntheticReferenceExpression; } /* @internal */ - export function isMergeDeclarationMarker(node: Node): node is MergeDeclarationMarker { - return node.kind === SyntaxKind.MergeDeclarationMarker; + export function isMergeDeclarationMarker(node: ts.Node): node is ts.MergeDeclarationMarker { + return node.kind === ts.SyntaxKind.MergeDeclarationMarker; } /* @internal */ - export function isEndOfDeclarationMarker(node: Node): node is EndOfDeclarationMarker { - return node.kind === SyntaxKind.EndOfDeclarationMarker; + export function isEndOfDeclarationMarker(node: ts.Node): node is ts.EndOfDeclarationMarker { + return node.kind === ts.SyntaxKind.EndOfDeclarationMarker; } // Module References - export function isExternalModuleReference(node: Node): node is ExternalModuleReference { - return node.kind === SyntaxKind.ExternalModuleReference; + export function isExternalModuleReference(node: ts.Node): node is ts.ExternalModuleReference { + return node.kind === ts.SyntaxKind.ExternalModuleReference; } // JSX - export function isJsxElement(node: Node): node is JsxElement { - return node.kind === SyntaxKind.JsxElement; + export function isJsxElement(node: ts.Node): node is ts.JsxElement { + return node.kind === ts.SyntaxKind.JsxElement; } - export function isJsxSelfClosingElement(node: Node): node is JsxSelfClosingElement { - return node.kind === SyntaxKind.JsxSelfClosingElement; + export function isJsxSelfClosingElement(node: ts.Node): node is ts.JsxSelfClosingElement { + return node.kind === ts.SyntaxKind.JsxSelfClosingElement; } - export function isJsxOpeningElement(node: Node): node is JsxOpeningElement { - return node.kind === SyntaxKind.JsxOpeningElement; + export function isJsxOpeningElement(node: ts.Node): node is ts.JsxOpeningElement { + return node.kind === ts.SyntaxKind.JsxOpeningElement; } - export function isJsxClosingElement(node: Node): node is JsxClosingElement { - return node.kind === SyntaxKind.JsxClosingElement; + export function isJsxClosingElement(node: ts.Node): node is ts.JsxClosingElement { + return node.kind === ts.SyntaxKind.JsxClosingElement; } - export function isJsxFragment(node: Node): node is JsxFragment { - return node.kind === SyntaxKind.JsxFragment; + export function isJsxFragment(node: ts.Node): node is ts.JsxFragment { + return node.kind === ts.SyntaxKind.JsxFragment; } - export function isJsxOpeningFragment(node: Node): node is JsxOpeningFragment { - return node.kind === SyntaxKind.JsxOpeningFragment; + export function isJsxOpeningFragment(node: ts.Node): node is ts.JsxOpeningFragment { + return node.kind === ts.SyntaxKind.JsxOpeningFragment; } - export function isJsxClosingFragment(node: Node): node is JsxClosingFragment { - return node.kind === SyntaxKind.JsxClosingFragment; + export function isJsxClosingFragment(node: ts.Node): node is ts.JsxClosingFragment { + return node.kind === ts.SyntaxKind.JsxClosingFragment; } - export function isJsxAttribute(node: Node): node is JsxAttribute { - return node.kind === SyntaxKind.JsxAttribute; + export function isJsxAttribute(node: ts.Node): node is ts.JsxAttribute { + return node.kind === ts.SyntaxKind.JsxAttribute; } - export function isJsxAttributes(node: Node): node is JsxAttributes { - return node.kind === SyntaxKind.JsxAttributes; + export function isJsxAttributes(node: ts.Node): node is ts.JsxAttributes { + return node.kind === ts.SyntaxKind.JsxAttributes; } - export function isJsxSpreadAttribute(node: Node): node is JsxSpreadAttribute { - return node.kind === SyntaxKind.JsxSpreadAttribute; + export function isJsxSpreadAttribute(node: ts.Node): node is ts.JsxSpreadAttribute { + return node.kind === ts.SyntaxKind.JsxSpreadAttribute; } - export function isJsxExpression(node: Node): node is JsxExpression { - return node.kind === SyntaxKind.JsxExpression; + export function isJsxExpression(node: ts.Node): node is ts.JsxExpression { + return node.kind === ts.SyntaxKind.JsxExpression; } // Clauses - export function isCaseClause(node: Node): node is CaseClause { - return node.kind === SyntaxKind.CaseClause; + export function isCaseClause(node: ts.Node): node is ts.CaseClause { + return node.kind === ts.SyntaxKind.CaseClause; } - export function isDefaultClause(node: Node): node is DefaultClause { - return node.kind === SyntaxKind.DefaultClause; + export function isDefaultClause(node: ts.Node): node is ts.DefaultClause { + return node.kind === ts.SyntaxKind.DefaultClause; } - export function isHeritageClause(node: Node): node is HeritageClause { - return node.kind === SyntaxKind.HeritageClause; + export function isHeritageClause(node: ts.Node): node is ts.HeritageClause { + return node.kind === ts.SyntaxKind.HeritageClause; } - export function isCatchClause(node: Node): node is CatchClause { - return node.kind === SyntaxKind.CatchClause; + export function isCatchClause(node: ts.Node): node is ts.CatchClause { + return node.kind === ts.SyntaxKind.CatchClause; } // Property assignments - export function isPropertyAssignment(node: Node): node is PropertyAssignment { - return node.kind === SyntaxKind.PropertyAssignment; + export function isPropertyAssignment(node: ts.Node): node is ts.PropertyAssignment { + return node.kind === ts.SyntaxKind.PropertyAssignment; } - export function isShorthandPropertyAssignment(node: Node): node is ShorthandPropertyAssignment { - return node.kind === SyntaxKind.ShorthandPropertyAssignment; + export function isShorthandPropertyAssignment(node: ts.Node): node is ts.ShorthandPropertyAssignment { + return node.kind === ts.SyntaxKind.ShorthandPropertyAssignment; } - export function isSpreadAssignment(node: Node): node is SpreadAssignment { - return node.kind === SyntaxKind.SpreadAssignment; + export function isSpreadAssignment(node: ts.Node): node is ts.SpreadAssignment { + return node.kind === ts.SyntaxKind.SpreadAssignment; } // Enum - export function isEnumMember(node: Node): node is EnumMember { - return node.kind === SyntaxKind.EnumMember; + export function isEnumMember(node: ts.Node): node is ts.EnumMember { + return node.kind === ts.SyntaxKind.EnumMember; } // Unparsed // TODO(rbuckton): isUnparsedPrologue - export function isUnparsedPrepend(node: Node): node is UnparsedPrepend { - return node.kind === SyntaxKind.UnparsedPrepend; + export function isUnparsedPrepend(node: ts.Node): node is ts.UnparsedPrepend { + return node.kind === ts.SyntaxKind.UnparsedPrepend; } // TODO(rbuckton): isUnparsedText @@ -763,180 +763,180 @@ namespace ts { // TODO(rbuckton): isUnparsedSyntheticReference // Top-level nodes - export function isSourceFile(node: Node): node is SourceFile { - return node.kind === SyntaxKind.SourceFile; + export function isSourceFile(node: ts.Node): node is ts.SourceFile { + return node.kind === ts.SyntaxKind.SourceFile; } - export function isBundle(node: Node): node is Bundle { - return node.kind === SyntaxKind.Bundle; + export function isBundle(node: ts.Node): node is ts.Bundle { + return node.kind === ts.SyntaxKind.Bundle; } - export function isUnparsedSource(node: Node): node is UnparsedSource { - return node.kind === SyntaxKind.UnparsedSource; + export function isUnparsedSource(node: ts.Node): node is ts.UnparsedSource { + return node.kind === ts.SyntaxKind.UnparsedSource; } // TODO(rbuckton): isInputFiles // JSDoc Elements - export function isJSDocTypeExpression(node: Node): node is JSDocTypeExpression { - return node.kind === SyntaxKind.JSDocTypeExpression; + export function isJSDocTypeExpression(node: ts.Node): node is ts.JSDocTypeExpression { + return node.kind === ts.SyntaxKind.JSDocTypeExpression; } - export function isJSDocNameReference(node: Node): node is JSDocNameReference { - return node.kind === SyntaxKind.JSDocNameReference; + export function isJSDocNameReference(node: ts.Node): node is ts.JSDocNameReference { + return node.kind === ts.SyntaxKind.JSDocNameReference; } - export function isJSDocMemberName(node: Node): node is JSDocMemberName { - return node.kind === SyntaxKind.JSDocMemberName; + export function isJSDocMemberName(node: ts.Node): node is ts.JSDocMemberName { + return node.kind === ts.SyntaxKind.JSDocMemberName; } - export function isJSDocLink(node: Node): node is JSDocLink { - return node.kind === SyntaxKind.JSDocLink; + export function isJSDocLink(node: ts.Node): node is ts.JSDocLink { + return node.kind === ts.SyntaxKind.JSDocLink; } - export function isJSDocLinkCode(node: Node): node is JSDocLinkCode { - return node.kind === SyntaxKind.JSDocLinkCode; + export function isJSDocLinkCode(node: ts.Node): node is ts.JSDocLinkCode { + return node.kind === ts.SyntaxKind.JSDocLinkCode; } - export function isJSDocLinkPlain(node: Node): node is JSDocLinkPlain { - return node.kind === SyntaxKind.JSDocLinkPlain; + export function isJSDocLinkPlain(node: ts.Node): node is ts.JSDocLinkPlain { + return node.kind === ts.SyntaxKind.JSDocLinkPlain; } - export function isJSDocAllType(node: Node): node is JSDocAllType { - return node.kind === SyntaxKind.JSDocAllType; + export function isJSDocAllType(node: ts.Node): node is ts.JSDocAllType { + return node.kind === ts.SyntaxKind.JSDocAllType; } - export function isJSDocUnknownType(node: Node): node is JSDocUnknownType { - return node.kind === SyntaxKind.JSDocUnknownType; + export function isJSDocUnknownType(node: ts.Node): node is ts.JSDocUnknownType { + return node.kind === ts.SyntaxKind.JSDocUnknownType; } - export function isJSDocNullableType(node: Node): node is JSDocNullableType { - return node.kind === SyntaxKind.JSDocNullableType; + export function isJSDocNullableType(node: ts.Node): node is ts.JSDocNullableType { + return node.kind === ts.SyntaxKind.JSDocNullableType; } - export function isJSDocNonNullableType(node: Node): node is JSDocNonNullableType { - return node.kind === SyntaxKind.JSDocNonNullableType; + export function isJSDocNonNullableType(node: ts.Node): node is ts.JSDocNonNullableType { + return node.kind === ts.SyntaxKind.JSDocNonNullableType; } - export function isJSDocOptionalType(node: Node): node is JSDocOptionalType { - return node.kind === SyntaxKind.JSDocOptionalType; + export function isJSDocOptionalType(node: ts.Node): node is ts.JSDocOptionalType { + return node.kind === ts.SyntaxKind.JSDocOptionalType; } - export function isJSDocFunctionType(node: Node): node is JSDocFunctionType { - return node.kind === SyntaxKind.JSDocFunctionType; + export function isJSDocFunctionType(node: ts.Node): node is ts.JSDocFunctionType { + return node.kind === ts.SyntaxKind.JSDocFunctionType; } - export function isJSDocVariadicType(node: Node): node is JSDocVariadicType { - return node.kind === SyntaxKind.JSDocVariadicType; + export function isJSDocVariadicType(node: ts.Node): node is ts.JSDocVariadicType { + return node.kind === ts.SyntaxKind.JSDocVariadicType; } - export function isJSDocNamepathType(node: Node): node is JSDocNamepathType { - return node.kind === SyntaxKind.JSDocNamepathType; + export function isJSDocNamepathType(node: ts.Node): node is ts.JSDocNamepathType { + return node.kind === ts.SyntaxKind.JSDocNamepathType; } - export function isJSDoc(node: Node): node is JSDoc { - return node.kind === SyntaxKind.JSDoc; + export function isJSDoc(node: ts.Node): node is ts.JSDoc { + return node.kind === ts.SyntaxKind.JSDoc; } - export function isJSDocTypeLiteral(node: Node): node is JSDocTypeLiteral { - return node.kind === SyntaxKind.JSDocTypeLiteral; + export function isJSDocTypeLiteral(node: ts.Node): node is ts.JSDocTypeLiteral { + return node.kind === ts.SyntaxKind.JSDocTypeLiteral; } - export function isJSDocSignature(node: Node): node is JSDocSignature { - return node.kind === SyntaxKind.JSDocSignature; + export function isJSDocSignature(node: ts.Node): node is ts.JSDocSignature { + return node.kind === ts.SyntaxKind.JSDocSignature; } // JSDoc Tags - export function isJSDocAugmentsTag(node: Node): node is JSDocAugmentsTag { - return node.kind === SyntaxKind.JSDocAugmentsTag; + export function isJSDocAugmentsTag(node: ts.Node): node is ts.JSDocAugmentsTag { + return node.kind === ts.SyntaxKind.JSDocAugmentsTag; } - export function isJSDocAuthorTag(node: Node): node is JSDocAuthorTag { - return node.kind === SyntaxKind.JSDocAuthorTag; + export function isJSDocAuthorTag(node: ts.Node): node is ts.JSDocAuthorTag { + return node.kind === ts.SyntaxKind.JSDocAuthorTag; } - export function isJSDocClassTag(node: Node): node is JSDocClassTag { - return node.kind === SyntaxKind.JSDocClassTag; + export function isJSDocClassTag(node: ts.Node): node is ts.JSDocClassTag { + return node.kind === ts.SyntaxKind.JSDocClassTag; } - export function isJSDocCallbackTag(node: Node): node is JSDocCallbackTag { - return node.kind === SyntaxKind.JSDocCallbackTag; + export function isJSDocCallbackTag(node: ts.Node): node is ts.JSDocCallbackTag { + return node.kind === ts.SyntaxKind.JSDocCallbackTag; } - export function isJSDocPublicTag(node: Node): node is JSDocPublicTag { - return node.kind === SyntaxKind.JSDocPublicTag; + export function isJSDocPublicTag(node: ts.Node): node is ts.JSDocPublicTag { + return node.kind === ts.SyntaxKind.JSDocPublicTag; } - export function isJSDocPrivateTag(node: Node): node is JSDocPrivateTag { - return node.kind === SyntaxKind.JSDocPrivateTag; + export function isJSDocPrivateTag(node: ts.Node): node is ts.JSDocPrivateTag { + return node.kind === ts.SyntaxKind.JSDocPrivateTag; } - export function isJSDocProtectedTag(node: Node): node is JSDocProtectedTag { - return node.kind === SyntaxKind.JSDocProtectedTag; + export function isJSDocProtectedTag(node: ts.Node): node is ts.JSDocProtectedTag { + return node.kind === ts.SyntaxKind.JSDocProtectedTag; } - export function isJSDocReadonlyTag(node: Node): node is JSDocReadonlyTag { - return node.kind === SyntaxKind.JSDocReadonlyTag; + export function isJSDocReadonlyTag(node: ts.Node): node is ts.JSDocReadonlyTag { + return node.kind === ts.SyntaxKind.JSDocReadonlyTag; } - export function isJSDocOverrideTag(node: Node): node is JSDocOverrideTag { - return node.kind === SyntaxKind.JSDocOverrideTag; + export function isJSDocOverrideTag(node: ts.Node): node is ts.JSDocOverrideTag { + return node.kind === ts.SyntaxKind.JSDocOverrideTag; } - export function isJSDocDeprecatedTag(node: Node): node is JSDocDeprecatedTag { - return node.kind === SyntaxKind.JSDocDeprecatedTag; + export function isJSDocDeprecatedTag(node: ts.Node): node is ts.JSDocDeprecatedTag { + return node.kind === ts.SyntaxKind.JSDocDeprecatedTag; } - export function isJSDocSeeTag(node: Node): node is JSDocSeeTag { - return node.kind === SyntaxKind.JSDocSeeTag; + export function isJSDocSeeTag(node: ts.Node): node is ts.JSDocSeeTag { + return node.kind === ts.SyntaxKind.JSDocSeeTag; } - export function isJSDocEnumTag(node: Node): node is JSDocEnumTag { - return node.kind === SyntaxKind.JSDocEnumTag; + export function isJSDocEnumTag(node: ts.Node): node is ts.JSDocEnumTag { + return node.kind === ts.SyntaxKind.JSDocEnumTag; } - export function isJSDocParameterTag(node: Node): node is JSDocParameterTag { - return node.kind === SyntaxKind.JSDocParameterTag; + export function isJSDocParameterTag(node: ts.Node): node is ts.JSDocParameterTag { + return node.kind === ts.SyntaxKind.JSDocParameterTag; } - export function isJSDocReturnTag(node: Node): node is JSDocReturnTag { - return node.kind === SyntaxKind.JSDocReturnTag; + export function isJSDocReturnTag(node: ts.Node): node is ts.JSDocReturnTag { + return node.kind === ts.SyntaxKind.JSDocReturnTag; } - export function isJSDocThisTag(node: Node): node is JSDocThisTag { - return node.kind === SyntaxKind.JSDocThisTag; + export function isJSDocThisTag(node: ts.Node): node is ts.JSDocThisTag { + return node.kind === ts.SyntaxKind.JSDocThisTag; } - export function isJSDocTypeTag(node: Node): node is JSDocTypeTag { - return node.kind === SyntaxKind.JSDocTypeTag; + export function isJSDocTypeTag(node: ts.Node): node is ts.JSDocTypeTag { + return node.kind === ts.SyntaxKind.JSDocTypeTag; } - export function isJSDocTemplateTag(node: Node): node is JSDocTemplateTag { - return node.kind === SyntaxKind.JSDocTemplateTag; + export function isJSDocTemplateTag(node: ts.Node): node is ts.JSDocTemplateTag { + return node.kind === ts.SyntaxKind.JSDocTemplateTag; } - export function isJSDocTypedefTag(node: Node): node is JSDocTypedefTag { - return node.kind === SyntaxKind.JSDocTypedefTag; + export function isJSDocTypedefTag(node: ts.Node): node is ts.JSDocTypedefTag { + return node.kind === ts.SyntaxKind.JSDocTypedefTag; } - export function isJSDocUnknownTag(node: Node): node is JSDocUnknownTag { - return node.kind === SyntaxKind.JSDocTag; + export function isJSDocUnknownTag(node: ts.Node): node is ts.JSDocUnknownTag { + return node.kind === ts.SyntaxKind.JSDocTag; } - export function isJSDocPropertyTag(node: Node): node is JSDocPropertyTag { - return node.kind === SyntaxKind.JSDocPropertyTag; + export function isJSDocPropertyTag(node: ts.Node): node is ts.JSDocPropertyTag { + return node.kind === ts.SyntaxKind.JSDocPropertyTag; } - export function isJSDocImplementsTag(node: Node): node is JSDocImplementsTag { - return node.kind === SyntaxKind.JSDocImplementsTag; + export function isJSDocImplementsTag(node: ts.Node): node is ts.JSDocImplementsTag { + return node.kind === ts.SyntaxKind.JSDocImplementsTag; } // Synthesized list /* @internal */ - export function isSyntaxList(n: Node): n is SyntaxList { - return n.kind === SyntaxKind.SyntaxList; + export function isSyntaxList(n: ts.Node): n is ts.SyntaxList { + return n.kind === ts.SyntaxKind.SyntaxList; } } diff --git a/src/compiler/factory/parenthesizerRules.ts b/src/compiler/factory/parenthesizerRules.ts index c824c13fd1629..8f04537161906 100644 --- a/src/compiler/factory/parenthesizerRules.ts +++ b/src/compiler/factory/parenthesizerRules.ts @@ -1,12 +1,11 @@ /* @internal */ namespace ts { - export function createParenthesizerRules(factory: NodeFactory): ParenthesizerRules { - interface BinaryPlusExpression extends BinaryExpression { - cachedLiteralKind: SyntaxKind; + export function createParenthesizerRules(factory: ts.NodeFactory): ts.ParenthesizerRules { + interface BinaryPlusExpression extends ts.BinaryExpression { + cachedLiteralKind: ts.SyntaxKind; } - - let binaryLeftOperandParenthesizerCache: ESMap Expression> | undefined; - let binaryRightOperandParenthesizerCache: ESMap Expression> | undefined; + let binaryLeftOperandParenthesizerCache: ts.ESMap ts.Expression> | undefined; + let binaryRightOperandParenthesizerCache: ts.ESMap ts.Expression> | undefined; return { getParenthesizeLeftSideOfBinaryForOperator, @@ -41,8 +40,8 @@ namespace ts { parenthesizeLeadingTypeArgument, }; - function getParenthesizeLeftSideOfBinaryForOperator(operatorKind: BinaryOperator) { - binaryLeftOperandParenthesizerCache ||= new Map(); + function getParenthesizeLeftSideOfBinaryForOperator(operatorKind: ts.BinaryOperator) { + binaryLeftOperandParenthesizerCache ||= new ts.Map(); let parenthesizerRule = binaryLeftOperandParenthesizerCache.get(operatorKind); if (!parenthesizerRule) { parenthesizerRule = node => parenthesizeLeftSideOfBinary(operatorKind, node); @@ -51,8 +50,8 @@ namespace ts { return parenthesizerRule; } - function getParenthesizeRightSideOfBinaryForOperator(operatorKind: BinaryOperator) { - binaryRightOperandParenthesizerCache ||= new Map(); + function getParenthesizeRightSideOfBinaryForOperator(operatorKind: ts.BinaryOperator) { + binaryRightOperandParenthesizerCache ||= new ts.Map(); let parenthesizerRule = binaryRightOperandParenthesizerCache.get(operatorKind); if (!parenthesizerRule) { parenthesizerRule = node => parenthesizeRightSideOfBinary(operatorKind, /*leftSide*/ undefined, node); @@ -69,7 +68,7 @@ namespace ts { * @param isLeftSideOfBinary A value indicating whether the operand is the left side of the * BinaryExpression. */ - function binaryOperandNeedsParentheses(binaryOperator: SyntaxKind, operand: Expression, isLeftSideOfBinary: boolean, leftOperand: Expression | undefined) { + function binaryOperandNeedsParentheses(binaryOperator: ts.SyntaxKind, operand: ts.Expression, isLeftSideOfBinary: boolean, leftOperand: ts.Expression | undefined) { // If the operand has lower precedence, then it needs to be parenthesized to preserve the // intent of the expression. For example, if the operand is `a + b` and the operator is // `*`, then we need to parenthesize the operand to preserve the intended order of @@ -87,31 +86,31 @@ namespace ts { // // If `a ** d` is on the left of operator `**`, we need to parenthesize to preserve // the intended order of operations: `(a ** b) ** c` - const binaryOperatorPrecedence = getOperatorPrecedence(SyntaxKind.BinaryExpression, binaryOperator); - const binaryOperatorAssociativity = getOperatorAssociativity(SyntaxKind.BinaryExpression, binaryOperator); - const emittedOperand = skipPartiallyEmittedExpressions(operand); - if (!isLeftSideOfBinary && operand.kind === SyntaxKind.ArrowFunction && binaryOperatorPrecedence > OperatorPrecedence.Assignment) { + const binaryOperatorPrecedence = ts.getOperatorPrecedence(ts.SyntaxKind.BinaryExpression, binaryOperator); + const binaryOperatorAssociativity = ts.getOperatorAssociativity(ts.SyntaxKind.BinaryExpression, binaryOperator); + const emittedOperand = ts.skipPartiallyEmittedExpressions(operand); + if (!isLeftSideOfBinary && operand.kind === ts.SyntaxKind.ArrowFunction && binaryOperatorPrecedence > ts.OperatorPrecedence.Assignment) { // We need to parenthesize arrow functions on the right side to avoid it being // parsed as parenthesized expression: `a && (() => {})` return true; } - const operandPrecedence = getExpressionPrecedence(emittedOperand); - switch (compareValues(operandPrecedence, binaryOperatorPrecedence)) { - case Comparison.LessThan: + const operandPrecedence = ts.getExpressionPrecedence(emittedOperand); + switch (ts.compareValues(operandPrecedence, binaryOperatorPrecedence)) { + case ts.Comparison.LessThan: // If the operand is the right side of a right-associative binary operation // and is a yield expression, then we do not need parentheses. if (!isLeftSideOfBinary - && binaryOperatorAssociativity === Associativity.Right - && operand.kind === SyntaxKind.YieldExpression) { + && binaryOperatorAssociativity === ts.Associativity.Right + && operand.kind === ts.SyntaxKind.YieldExpression) { return false; } return true; - case Comparison.GreaterThan: + case ts.Comparison.GreaterThan: return false; - case Comparison.EqualTo: + case ts.Comparison.EqualTo: if (isLeftSideOfBinary) { // No need to parenthesize the left operand when the binary operator is // left associative: @@ -122,10 +121,10 @@ namespace ts { // right associative: // (a/b)**x -> (a/b)**x // (a**b)**x -> (a**b)**x - return binaryOperatorAssociativity === Associativity.Right; + return binaryOperatorAssociativity === ts.Associativity.Right; } else { - if (isBinaryExpression(emittedOperand) + if (ts.isBinaryExpression(emittedOperand) && emittedOperand.operatorToken.kind === binaryOperator) { // No need to parenthesize the right operand when the binary operator and // operand are the same and one of the following: @@ -143,9 +142,9 @@ namespace ts { // the same kind (recursively). // "a"+(1+2) => "a"+(1+2) // "a"+("b"+"c") => "a"+"b"+"c" - if (binaryOperator === SyntaxKind.PlusToken) { - const leftKind = leftOperand ? getLiteralKindOfBinaryPlusOperand(leftOperand) : SyntaxKind.Unknown; - if (isLiteralKind(leftKind) && leftKind === getLiteralKindOfBinaryPlusOperand(emittedOperand)) { + if (binaryOperator === ts.SyntaxKind.PlusToken) { + const leftKind = leftOperand ? getLiteralKindOfBinaryPlusOperand(leftOperand) : ts.SyntaxKind.Unknown; + if (ts.isLiteralKind(leftKind) && leftKind === getLiteralKindOfBinaryPlusOperand(emittedOperand)) { return false; } } @@ -160,8 +159,8 @@ namespace ts { // associative: // x/(a*b) -> x/(a*b) // x**(a/b) -> x**(a/b) - const operandAssociativity = getExpressionAssociativity(emittedOperand); - return operandAssociativity === Associativity.Left; + const operandAssociativity = ts.getExpressionAssociativity(emittedOperand); + return operandAssociativity === ts.Associativity.Left; } } } @@ -171,7 +170,7 @@ namespace ts { * * @param binaryOperator The binary operator. */ - function operatorHasAssociativeProperty(binaryOperator: SyntaxKind) { + function operatorHasAssociativeProperty(binaryOperator: ts.SyntaxKind) { // The following operators are associative in JavaScript: // (a*b)*c -> a*(b*c) -> a*b*c // (a|b)|c -> a|(b|c) -> a|b|c @@ -180,10 +179,10 @@ namespace ts { // // While addition is associative in mathematics, JavaScript's `+` is not // guaranteed to be associative as it is overloaded with string concatenation. - return binaryOperator === SyntaxKind.AsteriskToken - || binaryOperator === SyntaxKind.BarToken - || binaryOperator === SyntaxKind.AmpersandToken - || binaryOperator === SyntaxKind.CaretToken; + return binaryOperator === ts.SyntaxKind.AsteriskToken + || binaryOperator === ts.SyntaxKind.BarToken + || binaryOperator === ts.SyntaxKind.AmpersandToken + || binaryOperator === ts.SyntaxKind.CaretToken; } /** @@ -192,29 +191,28 @@ namespace ts { * It is used to determine whether the right-hand operand of a binary plus expression can be * emitted without parentheses. */ - function getLiteralKindOfBinaryPlusOperand(node: Expression): SyntaxKind { - node = skipPartiallyEmittedExpressions(node); - - if (isLiteralKind(node.kind)) { + function getLiteralKindOfBinaryPlusOperand(node: ts.Expression): ts.SyntaxKind { + node = ts.skipPartiallyEmittedExpressions(node); + if (ts.isLiteralKind(node.kind)) { return node.kind; } - if (node.kind === SyntaxKind.BinaryExpression && (node as BinaryExpression).operatorToken.kind === SyntaxKind.PlusToken) { + if (node.kind === ts.SyntaxKind.BinaryExpression && (node as ts.BinaryExpression).operatorToken.kind === ts.SyntaxKind.PlusToken) { if ((node as BinaryPlusExpression).cachedLiteralKind !== undefined) { return (node as BinaryPlusExpression).cachedLiteralKind; } - const leftKind = getLiteralKindOfBinaryPlusOperand((node as BinaryExpression).left); - const literalKind = isLiteralKind(leftKind) - && leftKind === getLiteralKindOfBinaryPlusOperand((node as BinaryExpression).right) + const leftKind = getLiteralKindOfBinaryPlusOperand((node as ts.BinaryExpression).left); + const literalKind = ts.isLiteralKind(leftKind) + && leftKind === getLiteralKindOfBinaryPlusOperand((node as ts.BinaryExpression).right) ? leftKind - : SyntaxKind.Unknown; + : ts.SyntaxKind.Unknown; (node as BinaryPlusExpression).cachedLiteralKind = literalKind; return literalKind; } - return SyntaxKind.Unknown; + return ts.SyntaxKind.Unknown; } /** @@ -226,11 +224,11 @@ namespace ts { * @param isLeftSideOfBinary A value indicating whether the operand is the left side of the * BinaryExpression. */ - function parenthesizeBinaryOperand(binaryOperator: SyntaxKind, operand: Expression, isLeftSideOfBinary: boolean, leftOperand?: Expression) { - const skipped = skipPartiallyEmittedExpressions(operand); + function parenthesizeBinaryOperand(binaryOperator: ts.SyntaxKind, operand: ts.Expression, isLeftSideOfBinary: boolean, leftOperand?: ts.Expression) { + const skipped = ts.skipPartiallyEmittedExpressions(operand); // If the resulting expression is already parenthesized, we do not need to do any further processing. - if (skipped.kind === SyntaxKind.ParenthesizedExpression) { + if (skipped.kind === ts.SyntaxKind.ParenthesizedExpression) { return operand; } @@ -240,34 +238,34 @@ namespace ts { } - function parenthesizeLeftSideOfBinary(binaryOperator: SyntaxKind, leftSide: Expression): Expression { + function parenthesizeLeftSideOfBinary(binaryOperator: ts.SyntaxKind, leftSide: ts.Expression): ts.Expression { return parenthesizeBinaryOperand(binaryOperator, leftSide, /*isLeftSideOfBinary*/ true); } - function parenthesizeRightSideOfBinary(binaryOperator: SyntaxKind, leftSide: Expression | undefined, rightSide: Expression): Expression { + function parenthesizeRightSideOfBinary(binaryOperator: ts.SyntaxKind, leftSide: ts.Expression | undefined, rightSide: ts.Expression): ts.Expression { return parenthesizeBinaryOperand(binaryOperator, rightSide, /*isLeftSideOfBinary*/ false, leftSide); } - function parenthesizeExpressionOfComputedPropertyName(expression: Expression): Expression { - return isCommaSequence(expression) ? factory.createParenthesizedExpression(expression) : expression; + function parenthesizeExpressionOfComputedPropertyName(expression: ts.Expression): ts.Expression { + return ts.isCommaSequence(expression) ? factory.createParenthesizedExpression(expression) : expression; } - function parenthesizeConditionOfConditionalExpression(condition: Expression): Expression { - const conditionalPrecedence = getOperatorPrecedence(SyntaxKind.ConditionalExpression, SyntaxKind.QuestionToken); - const emittedCondition = skipPartiallyEmittedExpressions(condition); - const conditionPrecedence = getExpressionPrecedence(emittedCondition); - if (compareValues(conditionPrecedence, conditionalPrecedence) !== Comparison.GreaterThan) { + function parenthesizeConditionOfConditionalExpression(condition: ts.Expression): ts.Expression { + const conditionalPrecedence = ts.getOperatorPrecedence(ts.SyntaxKind.ConditionalExpression, ts.SyntaxKind.QuestionToken); + const emittedCondition = ts.skipPartiallyEmittedExpressions(condition); + const conditionPrecedence = ts.getExpressionPrecedence(emittedCondition); + if (ts.compareValues(conditionPrecedence, conditionalPrecedence) !== ts.Comparison.GreaterThan) { return factory.createParenthesizedExpression(condition); } return condition; } - function parenthesizeBranchOfConditionalExpression(branch: Expression): Expression { + function parenthesizeBranchOfConditionalExpression(branch: ts.Expression): ts.Expression { // per ES grammar both 'whenTrue' and 'whenFalse' parts of conditional expression are assignment expressions // so in case when comma expression is introduced as a part of previous transformations // if should be wrapped in parens since comma operator has the lowest precedence - const emittedExpression = skipPartiallyEmittedExpressions(branch); - return isCommaSequence(emittedExpression) + const emittedExpression = ts.skipPartiallyEmittedExpressions(branch); + return ts.isCommaSequence(emittedExpression) ? factory.createParenthesizedExpression(branch) : branch; } @@ -283,13 +281,13 @@ namespace ts { * - FunctionExpression * - ClassExpression */ - function parenthesizeExpressionOfExportDefault(expression: Expression): Expression { - const check = skipPartiallyEmittedExpressions(expression); - let needsParens = isCommaSequence(check); + function parenthesizeExpressionOfExportDefault(expression: ts.Expression): ts.Expression { + const check = ts.skipPartiallyEmittedExpressions(expression); + let needsParens = ts.isCommaSequence(check); if (!needsParens) { - switch (getLeftmostExpression(check, /*stopAtCallExpression*/ false).kind) { - case SyntaxKind.ClassExpression: - case SyntaxKind.FunctionExpression: + switch (ts.getLeftmostExpression(check, /*stopAtCallExpression*/ false).kind) { + case ts.SyntaxKind.ClassExpression: + case ts.SyntaxKind.FunctionExpression: needsParens = true; } } @@ -300,16 +298,16 @@ namespace ts { * Wraps an expression in parentheses if it is needed in order to use the expression * as the expression of a `NewExpression` node. */ - function parenthesizeExpressionOfNew(expression: Expression): LeftHandSideExpression { - const leftmostExpr = getLeftmostExpression(expression, /*stopAtCallExpressions*/ true); + function parenthesizeExpressionOfNew(expression: ts.Expression): ts.LeftHandSideExpression { + const leftmostExpr = ts.getLeftmostExpression(expression, /*stopAtCallExpressions*/ true); switch (leftmostExpr.kind) { - case SyntaxKind.CallExpression: + case ts.SyntaxKind.CallExpression: return factory.createParenthesizedExpression(expression); - case SyntaxKind.NewExpression: - return !(leftmostExpr as NewExpression).arguments + case ts.SyntaxKind.NewExpression: + return !(leftmostExpr as ts.NewExpression).arguments ? factory.createParenthesizedExpression(expression) - : expression as LeftHandSideExpression; // TODO(rbuckton): Verify this assertion holds + : expression as ts.LeftHandSideExpression; // TODO(rbuckton): Verify this assertion holds } return parenthesizeLeftSideOfAccess(expression); @@ -319,79 +317,71 @@ namespace ts { * Wraps an expression in parentheses if it is needed in order to use the expression for * property or element access. */ - function parenthesizeLeftSideOfAccess(expression: Expression): LeftHandSideExpression { + function parenthesizeLeftSideOfAccess(expression: ts.Expression): ts.LeftHandSideExpression { // isLeftHandSideExpression is almost the correct criterion for when it is not necessary // to parenthesize the expression before a dot. The known exception is: // // NewExpression: // new C.x -> not the same as (new C).x // - const emittedExpression = skipPartiallyEmittedExpressions(expression); - if (isLeftHandSideExpression(emittedExpression) - && (emittedExpression.kind !== SyntaxKind.NewExpression || (emittedExpression as NewExpression).arguments)) { + const emittedExpression = ts.skipPartiallyEmittedExpressions(expression); + if (ts.isLeftHandSideExpression(emittedExpression) + && (emittedExpression.kind !== ts.SyntaxKind.NewExpression || (emittedExpression as ts.NewExpression).arguments)) { // TODO(rbuckton): Verify whether this assertion holds. - return expression as LeftHandSideExpression; + return expression as ts.LeftHandSideExpression; } // TODO(rbuckton): Verifiy whether `setTextRange` is needed. - return setTextRange(factory.createParenthesizedExpression(expression), expression); + return ts.setTextRange(factory.createParenthesizedExpression(expression), expression); } - function parenthesizeOperandOfPostfixUnary(operand: Expression): LeftHandSideExpression { + function parenthesizeOperandOfPostfixUnary(operand: ts.Expression): ts.LeftHandSideExpression { // TODO(rbuckton): Verifiy whether `setTextRange` is needed. - return isLeftHandSideExpression(operand) ? operand : setTextRange(factory.createParenthesizedExpression(operand), operand); + return ts.isLeftHandSideExpression(operand) ? operand : ts.setTextRange(factory.createParenthesizedExpression(operand), operand); } - function parenthesizeOperandOfPrefixUnary(operand: Expression): UnaryExpression { + function parenthesizeOperandOfPrefixUnary(operand: ts.Expression): ts.UnaryExpression { // TODO(rbuckton): Verifiy whether `setTextRange` is needed. - return isUnaryExpression(operand) ? operand : setTextRange(factory.createParenthesizedExpression(operand), operand); + return ts.isUnaryExpression(operand) ? operand : ts.setTextRange(factory.createParenthesizedExpression(operand), operand); } - - function parenthesizeExpressionsOfCommaDelimitedList(elements: NodeArray): NodeArray { - const result = sameMap(elements, parenthesizeExpressionForDisallowedComma); - return setTextRange(factory.createNodeArray(result, elements.hasTrailingComma), elements); + function parenthesizeExpressionsOfCommaDelimitedList(elements: ts.NodeArray): ts.NodeArray { + const result = ts.sameMap(elements, parenthesizeExpressionForDisallowedComma); + return ts.setTextRange(factory.createNodeArray(result, elements.hasTrailingComma), elements); } - - function parenthesizeExpressionForDisallowedComma(expression: Expression): Expression { - const emittedExpression = skipPartiallyEmittedExpressions(expression); - const expressionPrecedence = getExpressionPrecedence(emittedExpression); - const commaPrecedence = getOperatorPrecedence(SyntaxKind.BinaryExpression, SyntaxKind.CommaToken); + function parenthesizeExpressionForDisallowedComma(expression: ts.Expression): ts.Expression { + const emittedExpression = ts.skipPartiallyEmittedExpressions(expression); + const expressionPrecedence = ts.getExpressionPrecedence(emittedExpression); + const commaPrecedence = ts.getOperatorPrecedence(ts.SyntaxKind.BinaryExpression, ts.SyntaxKind.CommaToken); // TODO(rbuckton): Verifiy whether `setTextRange` is needed. - return expressionPrecedence > commaPrecedence ? expression : setTextRange(factory.createParenthesizedExpression(expression), expression); + return expressionPrecedence > commaPrecedence ? expression : ts.setTextRange(factory.createParenthesizedExpression(expression), expression); } - function parenthesizeExpressionOfExpressionStatement(expression: Expression): Expression { - const emittedExpression = skipPartiallyEmittedExpressions(expression); - if (isCallExpression(emittedExpression)) { + function parenthesizeExpressionOfExpressionStatement(expression: ts.Expression): ts.Expression { + const emittedExpression = ts.skipPartiallyEmittedExpressions(expression); + if (ts.isCallExpression(emittedExpression)) { const callee = emittedExpression.expression; - const kind = skipPartiallyEmittedExpressions(callee).kind; - if (kind === SyntaxKind.FunctionExpression || kind === SyntaxKind.ArrowFunction) { + const kind = ts.skipPartiallyEmittedExpressions(callee).kind; + if (kind === ts.SyntaxKind.FunctionExpression || kind === ts.SyntaxKind.ArrowFunction) { // TODO(rbuckton): Verifiy whether `setTextRange` is needed. - const updated = factory.updateCallExpression( - emittedExpression, - setTextRange(factory.createParenthesizedExpression(callee), callee), - emittedExpression.typeArguments, - emittedExpression.arguments - ); - return factory.restoreOuterExpressions(expression, updated, OuterExpressionKinds.PartiallyEmittedExpressions); + const updated = factory.updateCallExpression(emittedExpression, ts.setTextRange(factory.createParenthesizedExpression(callee), callee), emittedExpression.typeArguments, emittedExpression.arguments); + return factory.restoreOuterExpressions(expression, updated, ts.OuterExpressionKinds.PartiallyEmittedExpressions); } } - - const leftmostExpressionKind = getLeftmostExpression(emittedExpression, /*stopAtCallExpressions*/ false).kind; - if (leftmostExpressionKind === SyntaxKind.ObjectLiteralExpression || leftmostExpressionKind === SyntaxKind.FunctionExpression) { + const leftmostExpressionKind = ts.getLeftmostExpression(emittedExpression, /*stopAtCallExpressions*/ false).kind; + if (leftmostExpressionKind === ts.SyntaxKind.ObjectLiteralExpression || leftmostExpressionKind === ts.SyntaxKind.FunctionExpression) { // TODO(rbuckton): Verifiy whether `setTextRange` is needed. - return setTextRange(factory.createParenthesizedExpression(expression), expression); + return ts.setTextRange(factory.createParenthesizedExpression(expression), expression); } return expression; } - function parenthesizeConciseBodyOfArrowFunction(body: Expression): Expression; - function parenthesizeConciseBodyOfArrowFunction(body: ConciseBody): ConciseBody; - function parenthesizeConciseBodyOfArrowFunction(body: ConciseBody): ConciseBody { - if (!isBlock(body) && (isCommaSequence(body) || getLeftmostExpression(body, /*stopAtCallExpressions*/ false).kind === SyntaxKind.ObjectLiteralExpression)) { + function parenthesizeConciseBodyOfArrowFunction(body: ts.Expression): ts.Expression; + function parenthesizeConciseBodyOfArrowFunction(body: ts.ConciseBody): ts.ConciseBody; + function parenthesizeConciseBodyOfArrowFunction(body: ts.ConciseBody): ts.ConciseBody { + if (!ts.isBlock(body) && (ts.isCommaSequence(body) || ts.getLeftmostExpression(body, /*stopAtCallExpressions*/ false).kind === ts.SyntaxKind.ObjectLiteralExpression)) { // TODO(rbuckton): Verifiy whether `setTextRange` is needed. - return setTextRange(factory.createParenthesizedExpression(body), body); + return ts.setTextRange(factory.createParenthesizedExpression(body), body); } return body; @@ -408,19 +398,19 @@ namespace ts { // - The check type (the `UnionType`, above) does not allow function, constructor, or conditional types (they must be parenthesized) // - The extends type (the first `Type`, above) does not allow conditional types (they must be parenthesized). Function and constructor types are fine. // - The true and false branch types (the second and third `Type` non-terminals, above) allow any type - function parenthesizeCheckTypeOfConditionalType(checkType: TypeNode): TypeNode { + function parenthesizeCheckTypeOfConditionalType(checkType: ts.TypeNode): ts.TypeNode { switch (checkType.kind) { - case SyntaxKind.FunctionType: - case SyntaxKind.ConstructorType: - case SyntaxKind.ConditionalType: + case ts.SyntaxKind.FunctionType: + case ts.SyntaxKind.ConstructorType: + case ts.SyntaxKind.ConditionalType: return factory.createParenthesizedType(checkType); } return checkType; } - function parenthesizeExtendsTypeOfConditionalType(extendsType: TypeNode): TypeNode { + function parenthesizeExtendsTypeOfConditionalType(extendsType: ts.TypeNode): ts.TypeNode { switch (extendsType.kind) { - case SyntaxKind.ConditionalType: + case ts.SyntaxKind.ConditionalType: return factory.createParenthesizedType(extendsType); } return extendsType; @@ -431,17 +421,17 @@ namespace ts { // UnionType[?Extends] `|` IntersectionType[?Extends] // // - A union type constituent has the same precedence as the check type of a conditional type - function parenthesizeConstituentTypeOfUnionType(type: TypeNode) { + function parenthesizeConstituentTypeOfUnionType(type: ts.TypeNode) { switch (type.kind) { - case SyntaxKind.UnionType: // Not strictly necessary, but a union containing a union should have been flattened - case SyntaxKind.IntersectionType: // Not strictly necessary, but makes generated output more readable and avoids breaks in DT tests + case ts.SyntaxKind.UnionType: // Not strictly necessary, but a union containing a union should have been flattened + case ts.SyntaxKind.IntersectionType: // Not strictly necessary, but makes generated output more readable and avoids breaks in DT tests return factory.createParenthesizedType(type); } return parenthesizeCheckTypeOfConditionalType(type); } - function parenthesizeConstituentTypesOfUnionType(members: readonly TypeNode[]): NodeArray { - return factory.createNodeArray(sameMap(members, parenthesizeConstituentTypeOfUnionType)); + function parenthesizeConstituentTypesOfUnionType(members: readonly ts.TypeNode[]): ts.NodeArray { + return factory.createNodeArray(ts.sameMap(members, parenthesizeConstituentTypeOfUnionType)); } // IntersectionType[Extends] : @@ -449,17 +439,17 @@ namespace ts { // IntersectionType[?Extends] `&` TypeOperator[?Extends] // // - An intersection type constituent does not allow function, constructor, conditional, or union types (they must be parenthesized) - function parenthesizeConstituentTypeOfIntersectionType(type: TypeNode) { + function parenthesizeConstituentTypeOfIntersectionType(type: ts.TypeNode) { switch (type.kind) { - case SyntaxKind.UnionType: - case SyntaxKind.IntersectionType: // Not strictly necessary, but an intersection containing an intersection should have been flattened + case ts.SyntaxKind.UnionType: + case ts.SyntaxKind.IntersectionType: // Not strictly necessary, but an intersection containing an intersection should have been flattened return factory.createParenthesizedType(type); } return parenthesizeConstituentTypeOfUnionType(type); } - function parenthesizeConstituentTypesOfIntersectionType(members: readonly TypeNode[]): NodeArray { - return factory.createNodeArray(sameMap(members, parenthesizeConstituentTypeOfIntersectionType)); + function parenthesizeConstituentTypesOfIntersectionType(members: readonly ts.TypeNode[]): ts.NodeArray { + return factory.createNodeArray(ts.sameMap(members, parenthesizeConstituentTypeOfIntersectionType)); } // TypeOperator[Extends] : @@ -469,17 +459,17 @@ namespace ts { // `unique` TypeOperator[?Extends] // `readonly` TypeOperator[?Extends] // - function parenthesizeOperandOfTypeOperator(type: TypeNode) { + function parenthesizeOperandOfTypeOperator(type: ts.TypeNode) { switch (type.kind) { - case SyntaxKind.IntersectionType: + case ts.SyntaxKind.IntersectionType: return factory.createParenthesizedType(type); } return parenthesizeConstituentTypeOfIntersectionType(type); } - function parenthesizeOperandOfReadonlyTypeOperator(type: TypeNode) { + function parenthesizeOperandOfReadonlyTypeOperator(type: ts.TypeNode) { switch (type.kind) { - case SyntaxKind.TypeOperator: + case ts.SyntaxKind.TypeOperator: return factory.createParenthesizedType(type); } return parenthesizeOperandOfTypeOperator(type); @@ -498,11 +488,11 @@ namespace ts { // ArrayType : // NonArrayType `[` `]` // - function parenthesizeNonArrayTypeOfPostfixType(type: TypeNode) { + function parenthesizeNonArrayTypeOfPostfixType(type: ts.TypeNode) { switch (type.kind) { - case SyntaxKind.InferType: - case SyntaxKind.TypeOperator: - case SyntaxKind.TypeQuery: // Not strictly necessary, but makes generated output more readable and avoids breaks in DT tests + case ts.SyntaxKind.InferType: + case ts.SyntaxKind.TypeOperator: + case ts.SyntaxKind.TypeQuery: // Not strictly necessary, but makes generated output more readable and avoids breaks in DT tests return factory.createParenthesizedType(type); } return parenthesizeOperandOfTypeOperator(type); @@ -538,28 +528,37 @@ namespace ts { // RestType : // `...` Type[~Extends] // - function parenthesizeElementTypesOfTupleType(types: readonly (TypeNode | NamedTupleMember)[]): NodeArray { - return factory.createNodeArray(sameMap(types, parenthesizeElementTypeOfTupleType)); + function parenthesizeElementTypesOfTupleType(types: readonly (ts.TypeNode | ts.NamedTupleMember)[]): ts.NodeArray { + return factory.createNodeArray(ts.sameMap(types, parenthesizeElementTypeOfTupleType)); } - function parenthesizeElementTypeOfTupleType(type: TypeNode | NamedTupleMember): TypeNode { - if (hasJSDocPostfixQuestion(type)) return factory.createParenthesizedType(type); + function parenthesizeElementTypeOfTupleType(type: ts.TypeNode | ts.NamedTupleMember): ts.TypeNode { + if (hasJSDocPostfixQuestion(type)) + return factory.createParenthesizedType(type); return type; } - function hasJSDocPostfixQuestion(type: TypeNode | NamedTupleMember): boolean { - if (isJSDocNullableType(type)) return type.postfix; - if (isNamedTupleMember(type)) return hasJSDocPostfixQuestion(type.type); - if (isFunctionTypeNode(type) || isConstructorTypeNode(type) || isTypeOperatorNode(type)) return hasJSDocPostfixQuestion(type.type); - if (isConditionalTypeNode(type)) return hasJSDocPostfixQuestion(type.falseType); - if (isUnionTypeNode(type)) return hasJSDocPostfixQuestion(last(type.types)); - if (isIntersectionTypeNode(type)) return hasJSDocPostfixQuestion(last(type.types)); - if (isInferTypeNode(type)) return !!type.typeParameter.constraint && hasJSDocPostfixQuestion(type.typeParameter.constraint); + function hasJSDocPostfixQuestion(type: ts.TypeNode | ts.NamedTupleMember): boolean { + if (ts.isJSDocNullableType(type)) + return type.postfix; + if (ts.isNamedTupleMember(type)) + return hasJSDocPostfixQuestion(type.type); + if (ts.isFunctionTypeNode(type) || ts.isConstructorTypeNode(type) || ts.isTypeOperatorNode(type)) + return hasJSDocPostfixQuestion(type.type); + if (ts.isConditionalTypeNode(type)) + return hasJSDocPostfixQuestion(type.falseType); + if (ts.isUnionTypeNode(type)) + return hasJSDocPostfixQuestion(ts.last(type.types)); + if (ts.isIntersectionTypeNode(type)) + return hasJSDocPostfixQuestion(ts.last(type.types)); + if (ts.isInferTypeNode(type)) + return !!type.typeParameter.constraint && hasJSDocPostfixQuestion(type.typeParameter.constraint); return false; } - function parenthesizeTypeOfOptionalType(type: TypeNode): TypeNode { - if (hasJSDocPostfixQuestion(type)) return factory.createParenthesizedType(type); + function parenthesizeTypeOfOptionalType(type: ts.TypeNode): ts.TypeNode { + if (hasJSDocPostfixQuestion(type)) + return factory.createParenthesizedType(type); return parenthesizeNonArrayTypeOfPostfixType(type); } @@ -584,51 +583,51 @@ namespace ts { // return parenthesizeMemberOfElementType(member); // } - function parenthesizeLeadingTypeArgument(node: TypeNode) { - return isFunctionOrConstructorTypeNode(node) && node.typeParameters ? factory.createParenthesizedType(node) : node; + function parenthesizeLeadingTypeArgument(node: ts.TypeNode) { + return ts.isFunctionOrConstructorTypeNode(node) && node.typeParameters ? factory.createParenthesizedType(node) : node; } - function parenthesizeOrdinalTypeArgument(node: TypeNode, i: number) { + function parenthesizeOrdinalTypeArgument(node: ts.TypeNode, i: number) { return i === 0 ? parenthesizeLeadingTypeArgument(node) : node; } - function parenthesizeTypeArguments(typeArguments: NodeArray | undefined): NodeArray | undefined { - if (some(typeArguments)) { - return factory.createNodeArray(sameMap(typeArguments, parenthesizeOrdinalTypeArgument)); + function parenthesizeTypeArguments(typeArguments: ts.NodeArray | undefined): ts.NodeArray | undefined { + if (ts.some(typeArguments)) { + return factory.createNodeArray(ts.sameMap(typeArguments, parenthesizeOrdinalTypeArgument)); } } } - export const nullParenthesizerRules: ParenthesizerRules = { - getParenthesizeLeftSideOfBinaryForOperator: _ => identity, - getParenthesizeRightSideOfBinaryForOperator: _ => identity, + export const nullParenthesizerRules: ts.ParenthesizerRules = { + getParenthesizeLeftSideOfBinaryForOperator: _ => ts.identity, + getParenthesizeRightSideOfBinaryForOperator: _ => ts.identity, parenthesizeLeftSideOfBinary: (_binaryOperator, leftSide) => leftSide, parenthesizeRightSideOfBinary: (_binaryOperator, _leftSide, rightSide) => rightSide, - parenthesizeExpressionOfComputedPropertyName: identity, - parenthesizeConditionOfConditionalExpression: identity, - parenthesizeBranchOfConditionalExpression: identity, - parenthesizeExpressionOfExportDefault: identity, - parenthesizeExpressionOfNew: expression => cast(expression, isLeftHandSideExpression), - parenthesizeLeftSideOfAccess: expression => cast(expression, isLeftHandSideExpression), - parenthesizeOperandOfPostfixUnary: operand => cast(operand, isLeftHandSideExpression), - parenthesizeOperandOfPrefixUnary: operand => cast(operand, isUnaryExpression), - parenthesizeExpressionsOfCommaDelimitedList: nodes => cast(nodes, isNodeArray), - parenthesizeExpressionForDisallowedComma: identity, - parenthesizeExpressionOfExpressionStatement: identity, - parenthesizeConciseBodyOfArrowFunction: identity, - parenthesizeCheckTypeOfConditionalType: identity, - parenthesizeExtendsTypeOfConditionalType: identity, - parenthesizeConstituentTypesOfUnionType: nodes => cast(nodes, isNodeArray), - parenthesizeConstituentTypeOfUnionType: identity, - parenthesizeConstituentTypesOfIntersectionType: nodes => cast(nodes, isNodeArray), - parenthesizeConstituentTypeOfIntersectionType: identity, - parenthesizeOperandOfTypeOperator: identity, - parenthesizeOperandOfReadonlyTypeOperator: identity, - parenthesizeNonArrayTypeOfPostfixType: identity, - parenthesizeElementTypesOfTupleType: nodes => cast(nodes, isNodeArray), - parenthesizeElementTypeOfTupleType: identity, - parenthesizeTypeOfOptionalType: identity, - parenthesizeTypeArguments: nodes => nodes && cast(nodes, isNodeArray), - parenthesizeLeadingTypeArgument: identity, + parenthesizeExpressionOfComputedPropertyName: ts.identity, + parenthesizeConditionOfConditionalExpression: ts.identity, + parenthesizeBranchOfConditionalExpression: ts.identity, + parenthesizeExpressionOfExportDefault: ts.identity, + parenthesizeExpressionOfNew: expression => ts.cast(expression, ts.isLeftHandSideExpression), + parenthesizeLeftSideOfAccess: expression => ts.cast(expression, ts.isLeftHandSideExpression), + parenthesizeOperandOfPostfixUnary: operand => ts.cast(operand, ts.isLeftHandSideExpression), + parenthesizeOperandOfPrefixUnary: operand => ts.cast(operand, ts.isUnaryExpression), + parenthesizeExpressionsOfCommaDelimitedList: nodes => ts.cast(nodes, ts.isNodeArray), + parenthesizeExpressionForDisallowedComma: ts.identity, + parenthesizeExpressionOfExpressionStatement: ts.identity, + parenthesizeConciseBodyOfArrowFunction: ts.identity, + parenthesizeCheckTypeOfConditionalType: ts.identity, + parenthesizeExtendsTypeOfConditionalType: ts.identity, + parenthesizeConstituentTypesOfUnionType: nodes => ts.cast(nodes, ts.isNodeArray), + parenthesizeConstituentTypeOfUnionType: ts.identity, + parenthesizeConstituentTypesOfIntersectionType: nodes => ts.cast(nodes, ts.isNodeArray), + parenthesizeConstituentTypeOfIntersectionType: ts.identity, + parenthesizeOperandOfTypeOperator: ts.identity, + parenthesizeOperandOfReadonlyTypeOperator: ts.identity, + parenthesizeNonArrayTypeOfPostfixType: ts.identity, + parenthesizeElementTypesOfTupleType: nodes => ts.cast(nodes, ts.isNodeArray), + parenthesizeElementTypeOfTupleType: ts.identity, + parenthesizeTypeOfOptionalType: ts.identity, + parenthesizeTypeArguments: nodes => nodes && ts.cast(nodes, ts.isNodeArray), + parenthesizeLeadingTypeArgument: ts.identity, }; } diff --git a/src/compiler/factory/utilities.ts b/src/compiler/factory/utilities.ts index 7daa31c522732..0ce268602704d 100644 --- a/src/compiler/factory/utilities.ts +++ b/src/compiler/factory/utilities.ts @@ -3,68 +3,59 @@ namespace ts { // Compound nodes - export function createEmptyExports(factory: NodeFactory) { + export function createEmptyExports(factory: ts.NodeFactory) { return factory.createExportDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, /*isTypeOnly*/ false, factory.createNamedExports([]), /*moduleSpecifier*/ undefined); } - export function createMemberAccessForPropertyName(factory: NodeFactory, target: Expression, memberName: PropertyName, location?: TextRange): MemberExpression { - if (isComputedPropertyName(memberName)) { - return setTextRange(factory.createElementAccessExpression(target, memberName.expression), location); + export function createMemberAccessForPropertyName(factory: ts.NodeFactory, target: ts.Expression, memberName: ts.PropertyName, location?: ts.TextRange): ts.MemberExpression { + if (ts.isComputedPropertyName(memberName)) { + return ts.setTextRange(factory.createElementAccessExpression(target, memberName.expression), location); } else { - const expression = setTextRange( - isMemberName(memberName) + const expression = ts.setTextRange(ts.isMemberName(memberName) ? factory.createPropertyAccessExpression(target, memberName) - : factory.createElementAccessExpression(target, memberName), - memberName - ); - getOrCreateEmitNode(expression).flags |= EmitFlags.NoNestedSourceMaps; + : factory.createElementAccessExpression(target, memberName), memberName); + ts.getOrCreateEmitNode(expression).flags |= ts.EmitFlags.NoNestedSourceMaps; return expression; } } - function createReactNamespace(reactNamespace: string, parent: JsxOpeningLikeElement | JsxOpeningFragment) { + function createReactNamespace(reactNamespace: string, parent: ts.JsxOpeningLikeElement | ts.JsxOpeningFragment) { // To ensure the emit resolver can properly resolve the namespace, we need to // treat this identifier as if it were a source tree node by clearing the `Synthesized` // flag and setting a parent node. - const react = parseNodeFactory.createIdentifier(reactNamespace || "React"); + const react = ts.parseNodeFactory.createIdentifier(reactNamespace || "React"); // Set the parent that is in parse tree // this makes sure that parent chain is intact for checker to traverse complete scope tree - setParent(react, getParseTreeNode(parent)); + ts.setParent(react, ts.getParseTreeNode(parent)); return react; } - function createJsxFactoryExpressionFromEntityName(factory: NodeFactory, jsxFactory: EntityName, parent: JsxOpeningLikeElement | JsxOpeningFragment): Expression { - if (isQualifiedName(jsxFactory)) { + function createJsxFactoryExpressionFromEntityName(factory: ts.NodeFactory, jsxFactory: ts.EntityName, parent: ts.JsxOpeningLikeElement | ts.JsxOpeningFragment): ts.Expression { + if (ts.isQualifiedName(jsxFactory)) { const left = createJsxFactoryExpressionFromEntityName(factory, jsxFactory.left, parent); - const right = factory.createIdentifier(idText(jsxFactory.right)) as Mutable; + const right = factory.createIdentifier(ts.idText(jsxFactory.right)) as ts.Mutable; right.escapedText = jsxFactory.right.escapedText; return factory.createPropertyAccessExpression(left, right); } else { - return createReactNamespace(idText(jsxFactory), parent); + return createReactNamespace(ts.idText(jsxFactory), parent); } } - export function createJsxFactoryExpression(factory: NodeFactory, jsxFactoryEntity: EntityName | undefined, reactNamespace: string, parent: JsxOpeningLikeElement | JsxOpeningFragment): Expression { + export function createJsxFactoryExpression(factory: ts.NodeFactory, jsxFactoryEntity: ts.EntityName | undefined, reactNamespace: string, parent: ts.JsxOpeningLikeElement | ts.JsxOpeningFragment): ts.Expression { return jsxFactoryEntity ? createJsxFactoryExpressionFromEntityName(factory, jsxFactoryEntity, parent) : - factory.createPropertyAccessExpression( - createReactNamespace(reactNamespace, parent), - "createElement" - ); + factory.createPropertyAccessExpression(createReactNamespace(reactNamespace, parent), "createElement"); } - function createJsxFragmentFactoryExpression(factory: NodeFactory, jsxFragmentFactoryEntity: EntityName | undefined, reactNamespace: string, parent: JsxOpeningLikeElement | JsxOpeningFragment): Expression { + function createJsxFragmentFactoryExpression(factory: ts.NodeFactory, jsxFragmentFactoryEntity: ts.EntityName | undefined, reactNamespace: string, parent: ts.JsxOpeningLikeElement | ts.JsxOpeningFragment): ts.Expression { return jsxFragmentFactoryEntity ? createJsxFactoryExpressionFromEntityName(factory, jsxFragmentFactoryEntity, parent) : - factory.createPropertyAccessExpression( - createReactNamespace(reactNamespace, parent), - "Fragment" - ); + factory.createPropertyAccessExpression(createReactNamespace(reactNamespace, parent), "Fragment"); } - export function createExpressionForJsxElement(factory: NodeFactory, callee: Expression, tagName: Expression, props: Expression | undefined, children: readonly Expression[] | undefined, location: TextRange): LeftHandSideExpression { + export function createExpressionForJsxElement(factory: ts.NodeFactory, callee: ts.Expression, tagName: ts.Expression, props: ts.Expression | undefined, children: readonly ts.Expression[] | undefined, location: ts.TextRange): ts.LeftHandSideExpression { const argumentsList = [tagName]; if (props) { argumentsList.push(props); @@ -86,17 +77,11 @@ namespace ts { } } - return setTextRange( - factory.createCallExpression( - callee, - /*typeArguments*/ undefined, - argumentsList - ), - location - ); + return ts.setTextRange(factory.createCallExpression(callee, + /*typeArguments*/ undefined, argumentsList), location); } - export function createExpressionForJsxFragment(factory: NodeFactory, jsxFactoryEntity: EntityName | undefined, jsxFragmentFactoryEntity: EntityName | undefined, reactNamespace: string, children: readonly Expression[], parentElement: JsxOpeningFragment, location: TextRange): LeftHandSideExpression { + export function createExpressionForJsxFragment(factory: ts.NodeFactory, jsxFactoryEntity: ts.EntityName | undefined, jsxFragmentFactoryEntity: ts.EntityName | undefined, reactNamespace: string, children: readonly ts.Expression[], parentElement: ts.JsxOpeningFragment, location: ts.TextRange): ts.LeftHandSideExpression { const tagName = createJsxFragmentFactoryExpression(factory, jsxFragmentFactoryEntity, reactNamespace, parentElement); const argumentsList = [tagName, factory.createNull()]; @@ -112,193 +97,125 @@ namespace ts { } } - return setTextRange( - factory.createCallExpression( - createJsxFactoryExpression(factory, jsxFactoryEntity, reactNamespace, parentElement), - /*typeArguments*/ undefined, - argumentsList - ), - location - ); + return ts.setTextRange(factory.createCallExpression(createJsxFactoryExpression(factory, jsxFactoryEntity, reactNamespace, parentElement), + /*typeArguments*/ undefined, argumentsList), location); } // Utilities - export function createForOfBindingStatement(factory: NodeFactory, node: ForInitializer, boundValue: Expression): Statement { - if (isVariableDeclarationList(node)) { - const firstDeclaration = first(node.declarations); - const updatedDeclaration = factory.updateVariableDeclaration( - firstDeclaration, - firstDeclaration.name, + export function createForOfBindingStatement(factory: ts.NodeFactory, node: ts.ForInitializer, boundValue: ts.Expression): ts.Statement { + if (ts.isVariableDeclarationList(node)) { + const firstDeclaration = ts.first(node.declarations); + const updatedDeclaration = factory.updateVariableDeclaration(firstDeclaration, firstDeclaration.name, /*exclamationToken*/ undefined, - /*type*/ undefined, - boundValue - ); - return setTextRange( - factory.createVariableStatement( - /*modifiers*/ undefined, - factory.updateVariableDeclarationList(node, [updatedDeclaration]) - ), - /*location*/ node - ); + /*type*/ undefined, boundValue); + return ts.setTextRange(factory.createVariableStatement( + /*modifiers*/ undefined, factory.updateVariableDeclarationList(node, [updatedDeclaration])), + /*location*/ node); } else { - const updatedExpression = setTextRange(factory.createAssignment(node, boundValue), /*location*/ node); - return setTextRange(factory.createExpressionStatement(updatedExpression), /*location*/ node); + const updatedExpression = ts.setTextRange(factory.createAssignment(node, boundValue), /*location*/ node); + return ts.setTextRange(factory.createExpressionStatement(updatedExpression), /*location*/ node); } } - export function insertLeadingStatement(factory: NodeFactory, dest: Statement, source: Statement) { - if (isBlock(dest)) { - return factory.updateBlock(dest, setTextRange(factory.createNodeArray([source, ...dest.statements]), dest.statements)); + export function insertLeadingStatement(factory: ts.NodeFactory, dest: ts.Statement, source: ts.Statement) { + if (ts.isBlock(dest)) { + return factory.updateBlock(dest, ts.setTextRange(factory.createNodeArray([source, ...dest.statements]), dest.statements)); } else { return factory.createBlock(factory.createNodeArray([dest, source]), /*multiLine*/ true); } } - export function createExpressionFromEntityName(factory: NodeFactory, node: EntityName | Expression): Expression { - if (isQualifiedName(node)) { + export function createExpressionFromEntityName(factory: ts.NodeFactory, node: ts.EntityName | ts.Expression): ts.Expression { + if (ts.isQualifiedName(node)) { const left = createExpressionFromEntityName(factory, node.left); // TODO(rbuckton): Does this need to be parented? - const right = setParent(setTextRange(factory.cloneNode(node.right), node.right), node.right.parent); - return setTextRange(factory.createPropertyAccessExpression(left, right), node); + const right = ts.setParent(ts.setTextRange(factory.cloneNode(node.right), node.right), node.right.parent); + return ts.setTextRange(factory.createPropertyAccessExpression(left, right), node); } else { // TODO(rbuckton): Does this need to be parented? - return setParent(setTextRange(factory.cloneNode(node), node), node.parent); + return ts.setParent(ts.setTextRange(factory.cloneNode(node), node), node.parent); } } - export function createExpressionForPropertyName(factory: NodeFactory, memberName: Exclude): Expression { - if (isIdentifier(memberName)) { + export function createExpressionForPropertyName(factory: ts.NodeFactory, memberName: Exclude): ts.Expression { + if (ts.isIdentifier(memberName)) { return factory.createStringLiteralFromNode(memberName); } - else if (isComputedPropertyName(memberName)) { + else if (ts.isComputedPropertyName(memberName)) { // TODO(rbuckton): Does this need to be parented? - return setParent(setTextRange(factory.cloneNode(memberName.expression), memberName.expression), memberName.expression.parent); + return ts.setParent(ts.setTextRange(factory.cloneNode(memberName.expression), memberName.expression), memberName.expression.parent); } else { // TODO(rbuckton): Does this need to be parented? - return setParent(setTextRange(factory.cloneNode(memberName), memberName), memberName.parent); + return ts.setParent(ts.setTextRange(factory.cloneNode(memberName), memberName), memberName.parent); } } - function createExpressionForAccessorDeclaration(factory: NodeFactory, properties: NodeArray, property: AccessorDeclaration & { readonly name: Exclude; }, receiver: Expression, multiLine: boolean) { - const { firstAccessor, getAccessor, setAccessor } = getAllAccessorDeclarations(properties, property); + function createExpressionForAccessorDeclaration(factory: ts.NodeFactory, properties: ts.NodeArray, property: ts.AccessorDeclaration & { + readonly name: Exclude; + }, receiver: ts.Expression, multiLine: boolean) { + const { firstAccessor, getAccessor, setAccessor } = ts.getAllAccessorDeclarations(properties, property); if (property === firstAccessor) { - return setTextRange( - factory.createObjectDefinePropertyCall( - receiver, - createExpressionForPropertyName(factory, property.name), - factory.createPropertyDescriptor({ + return ts.setTextRange(factory.createObjectDefinePropertyCall(receiver, createExpressionForPropertyName(factory, property.name), factory.createPropertyDescriptor({ enumerable: factory.createFalse(), configurable: true, - get: getAccessor && setTextRange( - setOriginalNode( - factory.createFunctionExpression( - getAccessor.modifiers, + get: getAccessor && ts.setTextRange(ts.setOriginalNode(factory.createFunctionExpression(getAccessor.modifiers, /*asteriskToken*/ undefined, /*name*/ undefined, - /*typeParameters*/ undefined, - getAccessor.parameters, - /*type*/ undefined, - getAccessor.body! // TODO: GH#18217 - ), - getAccessor - ), - getAccessor - ), - set: setAccessor && setTextRange( - setOriginalNode( - factory.createFunctionExpression( - setAccessor.modifiers, + /*typeParameters*/ undefined, getAccessor.parameters, + /*type*/ undefined, getAccessor.body! // TODO: GH#18217 + ), getAccessor), getAccessor), + set: setAccessor && ts.setTextRange(ts.setOriginalNode(factory.createFunctionExpression(setAccessor.modifiers, /*asteriskToken*/ undefined, /*name*/ undefined, - /*typeParameters*/ undefined, - setAccessor.parameters, - /*type*/ undefined, - setAccessor.body! // TODO: GH#18217 - ), - setAccessor - ), - setAccessor - ) - }, !multiLine) - ), - firstAccessor - ); + /*typeParameters*/ undefined, setAccessor.parameters, + /*type*/ undefined, setAccessor.body! // TODO: GH#18217 + ), setAccessor), setAccessor) + }, !multiLine)), firstAccessor); } return undefined; } - function createExpressionForPropertyAssignment(factory: NodeFactory, property: PropertyAssignment, receiver: Expression) { - return setOriginalNode( - setTextRange( - factory.createAssignment( - createMemberAccessForPropertyName(factory, receiver, property.name, /*location*/ property.name), - property.initializer - ), - property - ), - property - ); - } - - function createExpressionForShorthandPropertyAssignment(factory: NodeFactory, property: ShorthandPropertyAssignment, receiver: Expression) { - return setOriginalNode( - setTextRange( - factory.createAssignment( - createMemberAccessForPropertyName(factory, receiver, property.name, /*location*/ property.name), - factory.cloneNode(property.name) - ), - /*location*/ property - ), - /*original*/ property - ); - } - - function createExpressionForMethodDeclaration(factory: NodeFactory, method: MethodDeclaration, receiver: Expression) { - return setOriginalNode( - setTextRange( - factory.createAssignment( - createMemberAccessForPropertyName(factory, receiver, method.name, /*location*/ method.name), - setOriginalNode( - setTextRange( - factory.createFunctionExpression( - method.modifiers, - method.asteriskToken, + function createExpressionForPropertyAssignment(factory: ts.NodeFactory, property: ts.PropertyAssignment, receiver: ts.Expression) { + return ts.setOriginalNode(ts.setTextRange(factory.createAssignment(createMemberAccessForPropertyName(factory, receiver, property.name, /*location*/ property.name), property.initializer), property), property); + } + function createExpressionForShorthandPropertyAssignment(factory: ts.NodeFactory, property: ts.ShorthandPropertyAssignment, receiver: ts.Expression) { + return ts.setOriginalNode(ts.setTextRange(factory.createAssignment(createMemberAccessForPropertyName(factory, receiver, property.name, /*location*/ property.name), factory.cloneNode(property.name)), + /*location*/ property), + /*original*/ property); + } + function createExpressionForMethodDeclaration(factory: ts.NodeFactory, method: ts.MethodDeclaration, receiver: ts.Expression) { + return ts.setOriginalNode(ts.setTextRange(factory.createAssignment(createMemberAccessForPropertyName(factory, receiver, method.name, /*location*/ method.name), ts.setOriginalNode(ts.setTextRange(factory.createFunctionExpression(method.modifiers, method.asteriskToken, /*name*/ undefined, - /*typeParameters*/ undefined, - method.parameters, - /*type*/ undefined, - method.body! // TODO: GH#18217 - ), - /*location*/ method - ), - /*original*/ method - ) - ), - /*location*/ method + /*typeParameters*/ undefined, method.parameters, + /*type*/ undefined, method.body! // TODO: GH#18217 ), - /*original*/ method - ); + /*location*/ method), + /*original*/ method)), + /*location*/ method), + /*original*/ method); } - export function createExpressionForObjectLiteralElementLike(factory: NodeFactory, node: ObjectLiteralExpression, property: ObjectLiteralElementLike, receiver: Expression): Expression | undefined { - if (property.name && isPrivateIdentifier(property.name)) { - Debug.failBadSyntaxKind(property.name, "Private identifiers are not allowed in object literals."); + export function createExpressionForObjectLiteralElementLike(factory: ts.NodeFactory, node: ts.ObjectLiteralExpression, property: ts.ObjectLiteralElementLike, receiver: ts.Expression): ts.Expression | undefined { + if (property.name && ts.isPrivateIdentifier(property.name)) { + ts.Debug.failBadSyntaxKind(property.name, "Private identifiers are not allowed in object literals."); } switch (property.kind) { - case SyntaxKind.GetAccessor: - case SyntaxKind.SetAccessor: - return createExpressionForAccessorDeclaration(factory, node.properties, property as typeof property & { readonly name: Exclude }, receiver, !!node.multiLine); - case SyntaxKind.PropertyAssignment: + case ts.SyntaxKind.GetAccessor: + case ts.SyntaxKind.SetAccessor: + return createExpressionForAccessorDeclaration(factory, node.properties, property as typeof property & { + readonly name: Exclude; + }, receiver, !!node.multiLine); + case ts.SyntaxKind.PropertyAssignment: return createExpressionForPropertyAssignment(factory, property, receiver); - case SyntaxKind.ShorthandPropertyAssignment: + case ts.SyntaxKind.ShorthandPropertyAssignment: return createExpressionForShorthandPropertyAssignment(factory, property, receiver); - case SyntaxKind.MethodDeclaration: + case ts.SyntaxKind.MethodDeclaration: return createExpressionForMethodDeclaration(factory, property, receiver); } } @@ -335,30 +252,28 @@ namespace ts { * @param expression The expression to use as the value to increment or decrement * @param resultVariable A temporary variable in which to store the result. Pass `undefined` if the result is discarded, or if the value of `` is the expected result. */ - export function expandPreOrPostfixIncrementOrDecrementExpression(factory: NodeFactory, node: PrefixUnaryExpression | PostfixUnaryExpression, expression: Expression, recordTempVariable: (node: Identifier) => void, resultVariable: Identifier | undefined) { + export function expandPreOrPostfixIncrementOrDecrementExpression(factory: ts.NodeFactory, node: ts.PrefixUnaryExpression | ts.PostfixUnaryExpression, expression: ts.Expression, recordTempVariable: (node: ts.Identifier) => void, resultVariable: ts.Identifier | undefined) { const operator = node.operator; - Debug.assert(operator === SyntaxKind.PlusPlusToken || operator === SyntaxKind.MinusMinusToken, "Expected 'node' to be a pre- or post-increment or pre- or post-decrement expression"); + ts.Debug.assert(operator === ts.SyntaxKind.PlusPlusToken || operator === ts.SyntaxKind.MinusMinusToken, "Expected 'node' to be a pre- or post-increment or pre- or post-decrement expression"); const temp = factory.createTempVariable(recordTempVariable); expression = factory.createAssignment(temp, expression); - setTextRange(expression, node.operand); - - let operation: Expression = isPrefixUnaryExpression(node) ? + ts.setTextRange(expression, node.operand); + let operation: ts.Expression = ts.isPrefixUnaryExpression(node) ? factory.createPrefixUnaryExpression(operator, temp) : factory.createPostfixUnaryExpression(temp, operator); - setTextRange(operation, node); + ts.setTextRange(operation, node); if (resultVariable) { operation = factory.createAssignment(resultVariable, operation); - setTextRange(operation, node); + ts.setTextRange(operation, node); } expression = factory.createComma(expression, operation); - setTextRange(expression, node); - - if (isPostfixUnaryExpression(node)) { + ts.setTextRange(expression, node); + if (ts.isPostfixUnaryExpression(node)) { expression = factory.createComma(expression, temp); - setTextRange(expression, node); + ts.setTextRange(expression, node); } return expression; @@ -367,32 +282,32 @@ namespace ts { /** * Gets whether an identifier should only be referred to by its internal name. */ - export function isInternalName(node: Identifier) { - return (getEmitFlags(node) & EmitFlags.InternalName) !== 0; + export function isInternalName(node: ts.Identifier) { + return (ts.getEmitFlags(node) & ts.EmitFlags.InternalName) !== 0; } /** * Gets whether an identifier should only be referred to by its local name. */ - export function isLocalName(node: Identifier) { - return (getEmitFlags(node) & EmitFlags.LocalName) !== 0; + export function isLocalName(node: ts.Identifier) { + return (ts.getEmitFlags(node) & ts.EmitFlags.LocalName) !== 0; } /** * Gets whether an identifier should only be referred to by its export representation if the * name points to an exported symbol. */ - export function isExportName(node: Identifier) { - return (getEmitFlags(node) & EmitFlags.ExportName) !== 0; + export function isExportName(node: ts.Identifier) { + return (ts.getEmitFlags(node) & ts.EmitFlags.ExportName) !== 0; } - function isUseStrictPrologue(node: ExpressionStatement): boolean { - return isStringLiteral(node.expression) && node.expression.text === "use strict"; + function isUseStrictPrologue(node: ts.ExpressionStatement): boolean { + return ts.isStringLiteral(node.expression) && node.expression.text === "use strict"; } - export function findUseStrictPrologue(statements: readonly Statement[]): Statement | undefined { + export function findUseStrictPrologue(statements: readonly ts.Statement[]): ts.Statement | undefined { for (const statement of statements) { - if (isPrologueDirective(statement)) { + if (ts.isPrologueDirective(statement)) { if (isUseStrictPrologue(statement)) { return statement; } @@ -404,108 +319,105 @@ namespace ts { return undefined; } - export function startsWithUseStrict(statements: readonly Statement[]) { - const firstStatement = firstOrUndefined(statements); + export function startsWithUseStrict(statements: readonly ts.Statement[]) { + const firstStatement = ts.firstOrUndefined(statements); return firstStatement !== undefined - && isPrologueDirective(firstStatement) + && ts.isPrologueDirective(firstStatement) && isUseStrictPrologue(firstStatement); } - export function isCommaSequence(node: Expression): node is BinaryExpression & {operatorToken: Token} | CommaListExpression { - return node.kind === SyntaxKind.BinaryExpression && (node as BinaryExpression).operatorToken.kind === SyntaxKind.CommaToken || - node.kind === SyntaxKind.CommaListExpression; + export function isCommaSequence(node: ts.Expression): node is (ts.BinaryExpression & { + operatorToken: ts.Token; + }) | ts.CommaListExpression { + return node.kind === ts.SyntaxKind.BinaryExpression && (node as ts.BinaryExpression).operatorToken.kind === ts.SyntaxKind.CommaToken || + node.kind === ts.SyntaxKind.CommaListExpression; } - - export function isJSDocTypeAssertion(node: Node): node is JSDocTypeAssertion { - return isParenthesizedExpression(node) - && isInJSFile(node) - && !!getJSDocTypeTag(node); + export function isJSDocTypeAssertion(node: ts.Node): node is ts.JSDocTypeAssertion { + return ts.isParenthesizedExpression(node) + && ts.isInJSFile(node) + && !!ts.getJSDocTypeTag(node); } - - export function getJSDocTypeAssertionType(node: JSDocTypeAssertion) { - const type = getJSDocType(node); - Debug.assertIsDefined(type); + export function getJSDocTypeAssertionType(node: ts.JSDocTypeAssertion) { + const type = ts.getJSDocType(node); + ts.Debug.assertIsDefined(type); return type; } - export function isOuterExpression(node: Node, kinds = OuterExpressionKinds.All): node is OuterExpression { + export function isOuterExpression(node: ts.Node, kinds = ts.OuterExpressionKinds.All): node is ts.OuterExpression { switch (node.kind) { - case SyntaxKind.ParenthesizedExpression: - if (kinds & OuterExpressionKinds.ExcludeJSDocTypeAssertion && isJSDocTypeAssertion(node)) { + case ts.SyntaxKind.ParenthesizedExpression: + if (kinds & ts.OuterExpressionKinds.ExcludeJSDocTypeAssertion && isJSDocTypeAssertion(node)) { return false; } - return (kinds & OuterExpressionKinds.Parentheses) !== 0; - case SyntaxKind.TypeAssertionExpression: - case SyntaxKind.AsExpression: - return (kinds & OuterExpressionKinds.TypeAssertions) !== 0; - case SyntaxKind.NonNullExpression: - return (kinds & OuterExpressionKinds.NonNullAssertions) !== 0; - case SyntaxKind.PartiallyEmittedExpression: - return (kinds & OuterExpressionKinds.PartiallyEmittedExpressions) !== 0; + return (kinds & ts.OuterExpressionKinds.Parentheses) !== 0; + case ts.SyntaxKind.TypeAssertionExpression: + case ts.SyntaxKind.AsExpression: + return (kinds & ts.OuterExpressionKinds.TypeAssertions) !== 0; + case ts.SyntaxKind.NonNullExpression: + return (kinds & ts.OuterExpressionKinds.NonNullAssertions) !== 0; + case ts.SyntaxKind.PartiallyEmittedExpression: + return (kinds & ts.OuterExpressionKinds.PartiallyEmittedExpressions) !== 0; } return false; } - export function skipOuterExpressions(node: Expression, kinds?: OuterExpressionKinds): Expression; - export function skipOuterExpressions(node: Node, kinds?: OuterExpressionKinds): Node; - export function skipOuterExpressions(node: Node, kinds = OuterExpressionKinds.All) { + export function skipOuterExpressions(node: ts.Expression, kinds?: ts.OuterExpressionKinds): ts.Expression; + export function skipOuterExpressions(node: ts.Node, kinds?: ts.OuterExpressionKinds): ts.Node; + export function skipOuterExpressions(node: ts.Node, kinds = ts.OuterExpressionKinds.All) { while (isOuterExpression(node, kinds)) { node = node.expression; } return node; } - export function skipAssertions(node: Expression): Expression; - export function skipAssertions(node: Node): Node; - export function skipAssertions(node: Node): Node { - return skipOuterExpressions(node, OuterExpressionKinds.Assertions); + export function skipAssertions(node: ts.Expression): ts.Expression; + export function skipAssertions(node: ts.Node): ts.Node; + export function skipAssertions(node: ts.Node): ts.Node { + return skipOuterExpressions(node, ts.OuterExpressionKinds.Assertions); } - export function startOnNewLine(node: T): T { - return setStartsOnNewLine(node, /*newLine*/ true); + export function startOnNewLine(node: T): T { + return ts.setStartsOnNewLine(node, /*newLine*/ true); } - export function getExternalHelpersModuleName(node: SourceFile) { - const parseNode = getOriginalNode(node, isSourceFile); + export function getExternalHelpersModuleName(node: ts.SourceFile) { + const parseNode = ts.getOriginalNode(node, ts.isSourceFile); const emitNode = parseNode && parseNode.emitNode; return emitNode && emitNode.externalHelpersModuleName; } - export function hasRecordedExternalHelpers(sourceFile: SourceFile) { - const parseNode = getOriginalNode(sourceFile, isSourceFile); + export function hasRecordedExternalHelpers(sourceFile: ts.SourceFile) { + const parseNode = ts.getOriginalNode(sourceFile, ts.isSourceFile); const emitNode = parseNode && parseNode.emitNode; return !!emitNode && (!!emitNode.externalHelpersModuleName || !!emitNode.externalHelpers); } - export function createExternalHelpersImportDeclarationIfNeeded(nodeFactory: NodeFactory, helperFactory: EmitHelperFactory, sourceFile: SourceFile, compilerOptions: CompilerOptions, hasExportStarsToExportValues?: boolean, hasImportStar?: boolean, hasImportDefault?: boolean) { - if (compilerOptions.importHelpers && isEffectiveExternalModule(sourceFile, compilerOptions)) { - let namedBindings: NamedImportBindings | undefined; - const moduleKind = getEmitModuleKind(compilerOptions); - if ((moduleKind >= ModuleKind.ES2015 && moduleKind <= ModuleKind.ESNext) || sourceFile.impliedNodeFormat === ModuleKind.ESNext) { + export function createExternalHelpersImportDeclarationIfNeeded(nodeFactory: ts.NodeFactory, helperFactory: ts.EmitHelperFactory, sourceFile: ts.SourceFile, compilerOptions: ts.CompilerOptions, hasExportStarsToExportValues?: boolean, hasImportStar?: boolean, hasImportDefault?: boolean) { + if (compilerOptions.importHelpers && ts.isEffectiveExternalModule(sourceFile, compilerOptions)) { + let namedBindings: ts.NamedImportBindings | undefined; + const moduleKind = ts.getEmitModuleKind(compilerOptions); + if ((moduleKind >= ts.ModuleKind.ES2015 && moduleKind <= ts.ModuleKind.ESNext) || sourceFile.impliedNodeFormat === ts.ModuleKind.ESNext) { // use named imports - const helpers = getEmitHelpers(sourceFile); + const helpers = ts.getEmitHelpers(sourceFile); if (helpers) { const helperNames: string[] = []; for (const helper of helpers) { if (!helper.scoped) { const importName = helper.importName; if (importName) { - pushIfUnique(helperNames, importName); + ts.pushIfUnique(helperNames, importName); } } } - if (some(helperNames)) { - helperNames.sort(compareStringsCaseSensitive); + if (ts.some(helperNames)) { + helperNames.sort(ts.compareStringsCaseSensitive); // Alias the imports if the names are used somewhere in the file. // NOTE: We don't need to care about global import collisions as this is a module. - namedBindings = nodeFactory.createNamedImports( - map(helperNames, name => isFileLevelUniqueName(sourceFile, name) + namedBindings = nodeFactory.createNamedImports(ts.map(helperNames, name => ts.isFileLevelUniqueName(sourceFile, name) ? nodeFactory.createImportSpecifier(/*isTypeOnly*/ false, /*propertyName*/ undefined, nodeFactory.createIdentifier(name)) - : nodeFactory.createImportSpecifier(/*isTypeOnly*/ false, nodeFactory.createIdentifier(name), helperFactory.getUnscopedHelperName(name)) - ) - ); - const parseNode = getOriginalNode(sourceFile, isSourceFile); - const emitNode = getOrCreateEmitNode(parseNode); + : nodeFactory.createImportSpecifier(/*isTypeOnly*/ false, nodeFactory.createIdentifier(name), helperFactory.getUnscopedHelperName(name)))); + const parseNode = ts.getOriginalNode(sourceFile, ts.isSourceFile); + const emitNode = ts.getOrCreateEmitNode(parseNode); emitNode.externalHelpers = true; } } @@ -520,30 +432,27 @@ namespace ts { if (namedBindings) { const externalHelpersImportDeclaration = nodeFactory.createImportDeclaration( /*decorators*/ undefined, - /*modifiers*/ undefined, - nodeFactory.createImportClause(/*isTypeOnly*/ false, /*name*/ undefined, namedBindings), - nodeFactory.createStringLiteral(externalHelpersModuleNameText), - /*assertClause*/ undefined - ); - addEmitFlags(externalHelpersImportDeclaration, EmitFlags.NeverApplyImportHelper); + /*modifiers*/ undefined, nodeFactory.createImportClause(/*isTypeOnly*/ false, /*name*/ undefined, namedBindings), nodeFactory.createStringLiteral(ts.externalHelpersModuleNameText), + /*assertClause*/ undefined); + ts.addEmitFlags(externalHelpersImportDeclaration, ts.EmitFlags.NeverApplyImportHelper); return externalHelpersImportDeclaration; } } } - export function getOrCreateExternalHelpersModuleNameIfNeeded(factory: NodeFactory, node: SourceFile, compilerOptions: CompilerOptions, hasExportStarsToExportValues?: boolean, hasImportStarOrImportDefault?: boolean) { - if (compilerOptions.importHelpers && isEffectiveExternalModule(node, compilerOptions)) { + export function getOrCreateExternalHelpersModuleNameIfNeeded(factory: ts.NodeFactory, node: ts.SourceFile, compilerOptions: ts.CompilerOptions, hasExportStarsToExportValues?: boolean, hasImportStarOrImportDefault?: boolean) { + if (compilerOptions.importHelpers && ts.isEffectiveExternalModule(node, compilerOptions)) { const externalHelpersModuleName = getExternalHelpersModuleName(node); if (externalHelpersModuleName) { return externalHelpersModuleName; } - const moduleKind = getEmitModuleKind(compilerOptions); - let create = (hasExportStarsToExportValues || (getESModuleInterop(compilerOptions) && hasImportStarOrImportDefault)) - && moduleKind !== ModuleKind.System - && (moduleKind < ModuleKind.ES2015 || node.impliedNodeFormat === ModuleKind.CommonJS); + const moduleKind = ts.getEmitModuleKind(compilerOptions); + let create = (hasExportStarsToExportValues || (ts.getESModuleInterop(compilerOptions) && hasImportStarOrImportDefault)) + && moduleKind !== ts.ModuleKind.System + && (moduleKind < ts.ModuleKind.ES2015 || node.impliedNodeFormat === ts.ModuleKind.CommonJS); if (!create) { - const helpers = getEmitHelpers(node); + const helpers = ts.getEmitHelpers(node); if (helpers) { for (const helper of helpers) { if (!helper.scoped) { @@ -555,9 +464,9 @@ namespace ts { } if (create) { - const parseNode = getOriginalNode(node, isSourceFile); - const emitNode = getOrCreateEmitNode(parseNode); - return emitNode.externalHelpersModuleName || (emitNode.externalHelpersModuleName = factory.createUniqueName(externalHelpersModuleNameText)); + const parseNode = ts.getOriginalNode(node, ts.isSourceFile); + const emitNode = ts.getOrCreateEmitNode(parseNode); + return emitNode.externalHelpersModuleName || (emitNode.externalHelpersModuleName = factory.createUniqueName(ts.externalHelpersModuleNameText)); } } } @@ -565,16 +474,16 @@ namespace ts { /** * Get the name of that target module from an import or export declaration */ - export function getLocalNameForExternalImport(factory: NodeFactory, node: ImportDeclaration | ExportDeclaration | ImportEqualsDeclaration, sourceFile: SourceFile): Identifier | undefined { - const namespaceDeclaration = getNamespaceDeclarationNode(node); - if (namespaceDeclaration && !isDefaultImport(node) && !isExportNamespaceAsDefaultDeclaration(node)) { + export function getLocalNameForExternalImport(factory: ts.NodeFactory, node: ts.ImportDeclaration | ts.ExportDeclaration | ts.ImportEqualsDeclaration, sourceFile: ts.SourceFile): ts.Identifier | undefined { + const namespaceDeclaration = ts.getNamespaceDeclarationNode(node); + if (namespaceDeclaration && !ts.isDefaultImport(node) && !ts.isExportNamespaceAsDefaultDeclaration(node)) { const name = namespaceDeclaration.name; - return isGeneratedIdentifier(name) ? name : factory.createIdentifier(getSourceTextOfNodeFromSourceFile(sourceFile, name) || idText(name)); + return ts.isGeneratedIdentifier(name) ? name : factory.createIdentifier(ts.getSourceTextOfNodeFromSourceFile(sourceFile, name) || ts.idText(name)); } - if (node.kind === SyntaxKind.ImportDeclaration && node.importClause) { + if (node.kind === ts.SyntaxKind.ImportDeclaration && node.importClause) { return factory.getGeneratedNameForNode(node); } - if (node.kind === SyntaxKind.ExportDeclaration && node.moduleSpecifier) { + if (node.kind === ts.SyntaxKind.ExportDeclaration && node.moduleSpecifier) { return factory.getGeneratedNameForNode(node); } return undefined; @@ -588,9 +497,9 @@ namespace ts { * 3- The containing SourceFile has an entry in renamedDependencies for the import as requested by some module loaders (e.g. System). * Otherwise, a new StringLiteral node representing the module name will be returned. */ - export function getExternalModuleNameLiteral(factory: NodeFactory, importNode: ImportDeclaration | ExportDeclaration | ImportEqualsDeclaration | ImportCall, sourceFile: SourceFile, host: EmitHost, resolver: EmitResolver, compilerOptions: CompilerOptions) { - const moduleName = getExternalModuleName(importNode); - if (moduleName && isStringLiteral(moduleName)) { + export function getExternalModuleNameLiteral(factory: ts.NodeFactory, importNode: ts.ImportDeclaration | ts.ExportDeclaration | ts.ImportEqualsDeclaration | ts.ImportCall, sourceFile: ts.SourceFile, host: ts.EmitHost, resolver: ts.EmitResolver, compilerOptions: ts.CompilerOptions) { + const moduleName = ts.getExternalModuleName(importNode); + if (moduleName && ts.isStringLiteral(moduleName)) { return tryGetModuleNameFromDeclaration(importNode, host, factory, resolver, compilerOptions) || tryRenameExternalModule(factory, moduleName, sourceFile) || factory.cloneNode(moduleName); @@ -603,7 +512,7 @@ namespace ts { * Some bundlers (SystemJS builder) sometimes want to rename dependencies. * Here we check if alternative name was provided for a given moduleName and return it if possible. */ - function tryRenameExternalModule(factory: NodeFactory, moduleName: LiteralExpression, sourceFile: SourceFile) { + function tryRenameExternalModule(factory: ts.NodeFactory, moduleName: ts.LiteralExpression, sourceFile: ts.SourceFile) { const rename = sourceFile.renamedDependencies && sourceFile.renamedDependencies.get(moduleName.text); return rename ? factory.createStringLiteral(rename) : undefined; } @@ -615,28 +524,28 @@ namespace ts { * 2. --out or --outFile is used, making the name relative to the rootDir * Otherwise, a new StringLiteral node representing the module name will be returned. */ - export function tryGetModuleNameFromFile(factory: NodeFactory, file: SourceFile | undefined, host: EmitHost, options: CompilerOptions): StringLiteral | undefined { + export function tryGetModuleNameFromFile(factory: ts.NodeFactory, file: ts.SourceFile | undefined, host: ts.EmitHost, options: ts.CompilerOptions): ts.StringLiteral | undefined { if (!file) { return undefined; } if (file.moduleName) { return factory.createStringLiteral(file.moduleName); } - if (!file.isDeclarationFile && outFile(options)) { - return factory.createStringLiteral(getExternalModuleNameFromPath(host, file.fileName)); + if (!file.isDeclarationFile && ts.outFile(options)) { + return factory.createStringLiteral(ts.getExternalModuleNameFromPath(host, file.fileName)); } return undefined; } - function tryGetModuleNameFromDeclaration(declaration: ImportEqualsDeclaration | ImportDeclaration | ExportDeclaration | ImportCall, host: EmitHost, factory: NodeFactory, resolver: EmitResolver, compilerOptions: CompilerOptions) { + function tryGetModuleNameFromDeclaration(declaration: ts.ImportEqualsDeclaration | ts.ImportDeclaration | ts.ExportDeclaration | ts.ImportCall, host: ts.EmitHost, factory: ts.NodeFactory, resolver: ts.EmitResolver, compilerOptions: ts.CompilerOptions) { return tryGetModuleNameFromFile(factory, resolver.getExternalModuleFileFromDeclaration(declaration), host, compilerOptions); } /** * Gets the initializer of an BindingOrAssignmentElement. */ - export function getInitializerOfBindingOrAssignmentElement(bindingElement: BindingOrAssignmentElement): Expression | undefined { - if (isDeclarationBindingElement(bindingElement)) { + export function getInitializerOfBindingOrAssignmentElement(bindingElement: ts.BindingOrAssignmentElement): ts.Expression | undefined { + if (ts.isDeclarationBindingElement(bindingElement)) { // `1` in `let { a = 1 } = ...` // `1` in `let { a: b = 1 } = ...` // `1` in `let { a: {b} = 1 } = ...` @@ -647,39 +556,39 @@ namespace ts { return bindingElement.initializer; } - if (isPropertyAssignment(bindingElement)) { + if (ts.isPropertyAssignment(bindingElement)) { // `1` in `({ a: b = 1 } = ...)` // `1` in `({ a: {b} = 1 } = ...)` // `1` in `({ a: [b] = 1 } = ...)` const initializer = bindingElement.initializer; - return isAssignmentExpression(initializer, /*excludeCompoundAssignment*/ true) + return ts.isAssignmentExpression(initializer, /*excludeCompoundAssignment*/ true) ? initializer.right : undefined; } - if (isShorthandPropertyAssignment(bindingElement)) { + if (ts.isShorthandPropertyAssignment(bindingElement)) { // `1` in `({ a = 1 } = ...)` return bindingElement.objectAssignmentInitializer; } - if (isAssignmentExpression(bindingElement, /*excludeCompoundAssignment*/ true)) { + if (ts.isAssignmentExpression(bindingElement, /*excludeCompoundAssignment*/ true)) { // `1` in `[a = 1] = ...` // `1` in `[{a} = 1] = ...` // `1` in `[[a] = 1] = ...` return bindingElement.right; } - if (isSpreadElement(bindingElement)) { + if (ts.isSpreadElement(bindingElement)) { // Recovery consistent with existing emit. - return getInitializerOfBindingOrAssignmentElement(bindingElement.expression as BindingOrAssignmentElement); + return getInitializerOfBindingOrAssignmentElement(bindingElement.expression as ts.BindingOrAssignmentElement); } } /** * Gets the name of an BindingOrAssignmentElement. */ - export function getTargetOfBindingOrAssignmentElement(bindingElement: BindingOrAssignmentElement): BindingOrAssignmentElementTarget | undefined { - if (isDeclarationBindingElement(bindingElement)) { + export function getTargetOfBindingOrAssignmentElement(bindingElement: ts.BindingOrAssignmentElement): ts.BindingOrAssignmentElementTarget | undefined { + if (ts.isDeclarationBindingElement(bindingElement)) { // `a` in `let { a } = ...` // `a` in `let { a = 1 } = ...` // `b` in `let { a: b } = ...` @@ -699,9 +608,9 @@ namespace ts { return bindingElement.name; } - if (isObjectLiteralElementLike(bindingElement)) { + if (ts.isObjectLiteralElementLike(bindingElement)) { switch (bindingElement.kind) { - case SyntaxKind.PropertyAssignment: + case ts.SyntaxKind.PropertyAssignment: // `b` in `({ a: b } = ...)` // `b` in `({ a: b = 1 } = ...)` // `{b}` in `({ a: {b} } = ...)` @@ -712,34 +621,33 @@ namespace ts { // `b.c` in `({ a: b.c = 1 } = ...)` // `b[0]` in `({ a: b[0] } = ...)` // `b[0]` in `({ a: b[0] = 1 } = ...)` - return getTargetOfBindingOrAssignmentElement(bindingElement.initializer as BindingOrAssignmentElement); - - case SyntaxKind.ShorthandPropertyAssignment: + return getTargetOfBindingOrAssignmentElement(bindingElement.initializer as ts.BindingOrAssignmentElement); + case ts.SyntaxKind.ShorthandPropertyAssignment: // `a` in `({ a } = ...)` // `a` in `({ a = 1 } = ...)` return bindingElement.name; - case SyntaxKind.SpreadAssignment: + case ts.SyntaxKind.SpreadAssignment: // `a` in `({ ...a } = ...)` - return getTargetOfBindingOrAssignmentElement(bindingElement.expression as BindingOrAssignmentElement); + return getTargetOfBindingOrAssignmentElement(bindingElement.expression as ts.BindingOrAssignmentElement); } // no target return undefined; } - if (isAssignmentExpression(bindingElement, /*excludeCompoundAssignment*/ true)) { + if (ts.isAssignmentExpression(bindingElement, /*excludeCompoundAssignment*/ true)) { // `a` in `[a = 1] = ...` // `{a}` in `[{a} = 1] = ...` // `[a]` in `[[a] = 1] = ...` // `a.b` in `[a.b = 1] = ...` // `a[0]` in `[a[0] = 1] = ...` - return getTargetOfBindingOrAssignmentElement(bindingElement.left as BindingOrAssignmentElement); + return getTargetOfBindingOrAssignmentElement(bindingElement.left as ts.BindingOrAssignmentElement); } - if (isSpreadElement(bindingElement)) { + if (ts.isSpreadElement(bindingElement)) { // `a` in `[...a] = ...` - return getTargetOfBindingOrAssignmentElement(bindingElement.expression as BindingOrAssignmentElement); + return getTargetOfBindingOrAssignmentElement(bindingElement.expression as ts.BindingOrAssignmentElement); } // `a` in `[a] = ...` @@ -753,15 +661,15 @@ namespace ts { /** * Determines whether an BindingOrAssignmentElement is a rest element. */ - export function getRestIndicatorOfBindingOrAssignmentElement(bindingElement: BindingOrAssignmentElement): BindingOrAssignmentElementRestIndicator | undefined { + export function getRestIndicatorOfBindingOrAssignmentElement(bindingElement: ts.BindingOrAssignmentElement): ts.BindingOrAssignmentElementRestIndicator | undefined { switch (bindingElement.kind) { - case SyntaxKind.Parameter: - case SyntaxKind.BindingElement: + case ts.SyntaxKind.Parameter: + case ts.SyntaxKind.BindingElement: // `...` in `let [...a] = ...` return bindingElement.dotDotDotToken; - case SyntaxKind.SpreadElement: - case SyntaxKind.SpreadAssignment: + case ts.SyntaxKind.SpreadElement: + case ts.SyntaxKind.SpreadAssignment: // `...` in `[...a] = ...` return bindingElement; } @@ -772,242 +680,237 @@ namespace ts { /** * Gets the property name of a BindingOrAssignmentElement */ - export function getPropertyNameOfBindingOrAssignmentElement(bindingElement: BindingOrAssignmentElement): Exclude | undefined { + export function getPropertyNameOfBindingOrAssignmentElement(bindingElement: ts.BindingOrAssignmentElement): Exclude | undefined { const propertyName = tryGetPropertyNameOfBindingOrAssignmentElement(bindingElement); - Debug.assert(!!propertyName || isSpreadAssignment(bindingElement), "Invalid property name for binding element."); + ts.Debug.assert(!!propertyName || ts.isSpreadAssignment(bindingElement), "Invalid property name for binding element."); return propertyName; } - export function tryGetPropertyNameOfBindingOrAssignmentElement(bindingElement: BindingOrAssignmentElement): Exclude | undefined { + export function tryGetPropertyNameOfBindingOrAssignmentElement(bindingElement: ts.BindingOrAssignmentElement): Exclude | undefined { switch (bindingElement.kind) { - case SyntaxKind.BindingElement: + case ts.SyntaxKind.BindingElement: // `a` in `let { a: b } = ...` // `[a]` in `let { [a]: b } = ...` // `"a"` in `let { "a": b } = ...` // `1` in `let { 1: b } = ...` if (bindingElement.propertyName) { const propertyName = bindingElement.propertyName; - if (isPrivateIdentifier(propertyName)) { - return Debug.failBadSyntaxKind(propertyName); + if (ts.isPrivateIdentifier(propertyName)) { + return ts.Debug.failBadSyntaxKind(propertyName); } - return isComputedPropertyName(propertyName) && isStringOrNumericLiteral(propertyName.expression) + return ts.isComputedPropertyName(propertyName) && isStringOrNumericLiteral(propertyName.expression) ? propertyName.expression : propertyName; } break; - case SyntaxKind.PropertyAssignment: + case ts.SyntaxKind.PropertyAssignment: // `a` in `({ a: b } = ...)` // `[a]` in `({ [a]: b } = ...)` // `"a"` in `({ "a": b } = ...)` // `1` in `({ 1: b } = ...)` if (bindingElement.name) { const propertyName = bindingElement.name; - if (isPrivateIdentifier(propertyName)) { - return Debug.failBadSyntaxKind(propertyName); + if (ts.isPrivateIdentifier(propertyName)) { + return ts.Debug.failBadSyntaxKind(propertyName); } - return isComputedPropertyName(propertyName) && isStringOrNumericLiteral(propertyName.expression) + return ts.isComputedPropertyName(propertyName) && isStringOrNumericLiteral(propertyName.expression) ? propertyName.expression : propertyName; } break; - case SyntaxKind.SpreadAssignment: + case ts.SyntaxKind.SpreadAssignment: // `a` in `({ ...a } = ...)` - if (bindingElement.name && isPrivateIdentifier(bindingElement.name)) { - return Debug.failBadSyntaxKind(bindingElement.name); + if (bindingElement.name && ts.isPrivateIdentifier(bindingElement.name)) { + return ts.Debug.failBadSyntaxKind(bindingElement.name); } return bindingElement.name; } const target = getTargetOfBindingOrAssignmentElement(bindingElement); - if (target && isPropertyName(target)) { + if (target && ts.isPropertyName(target)) { return target; } } - function isStringOrNumericLiteral(node: Node): node is StringLiteral | NumericLiteral { + function isStringOrNumericLiteral(node: ts.Node): node is ts.StringLiteral | ts.NumericLiteral { const kind = node.kind; - return kind === SyntaxKind.StringLiteral - || kind === SyntaxKind.NumericLiteral; + return kind === ts.SyntaxKind.StringLiteral + || kind === ts.SyntaxKind.NumericLiteral; } /** * Gets the elements of a BindingOrAssignmentPattern */ - export function getElementsOfBindingOrAssignmentPattern(name: BindingOrAssignmentPattern): readonly BindingOrAssignmentElement[] { + export function getElementsOfBindingOrAssignmentPattern(name: ts.BindingOrAssignmentPattern): readonly ts.BindingOrAssignmentElement[] { switch (name.kind) { - case SyntaxKind.ObjectBindingPattern: - case SyntaxKind.ArrayBindingPattern: - case SyntaxKind.ArrayLiteralExpression: + case ts.SyntaxKind.ObjectBindingPattern: + case ts.SyntaxKind.ArrayBindingPattern: + case ts.SyntaxKind.ArrayLiteralExpression: // `a` in `{a}` // `a` in `[a]` - return name.elements as readonly BindingOrAssignmentElement[]; - - case SyntaxKind.ObjectLiteralExpression: + return name.elements as readonly ts.BindingOrAssignmentElement[]; + case ts.SyntaxKind.ObjectLiteralExpression: // `a` in `{a}` - return name.properties as readonly BindingOrAssignmentElement[]; + return name.properties as readonly ts.BindingOrAssignmentElement[]; } } /* @internal */ - export function getJSDocTypeAliasName(fullName: JSDocNamespaceBody | undefined) { + export function getJSDocTypeAliasName(fullName: ts.JSDocNamespaceBody | undefined) { if (fullName) { let rightNode = fullName; while (true) { - if (isIdentifier(rightNode) || !rightNode.body) { - return isIdentifier(rightNode) ? rightNode : rightNode.name; + if (ts.isIdentifier(rightNode) || !rightNode.body) { + return ts.isIdentifier(rightNode) ? rightNode : rightNode.name; } rightNode = rightNode.body; } } } - export function canHaveModifiers(node: Node): node is HasModifiers { + export function canHaveModifiers(node: ts.Node): node is ts.HasModifiers { const kind = node.kind; - return kind === SyntaxKind.Parameter - || kind === SyntaxKind.PropertySignature - || kind === SyntaxKind.PropertyDeclaration - || kind === SyntaxKind.MethodSignature - || kind === SyntaxKind.MethodDeclaration - || kind === SyntaxKind.Constructor - || kind === SyntaxKind.GetAccessor - || kind === SyntaxKind.SetAccessor - || kind === SyntaxKind.IndexSignature - || kind === SyntaxKind.FunctionExpression - || kind === SyntaxKind.ArrowFunction - || kind === SyntaxKind.ClassExpression - || kind === SyntaxKind.VariableStatement - || kind === SyntaxKind.FunctionDeclaration - || kind === SyntaxKind.ClassDeclaration - || kind === SyntaxKind.InterfaceDeclaration - || kind === SyntaxKind.TypeAliasDeclaration - || kind === SyntaxKind.EnumDeclaration - || kind === SyntaxKind.ModuleDeclaration - || kind === SyntaxKind.ImportEqualsDeclaration - || kind === SyntaxKind.ImportDeclaration - || kind === SyntaxKind.ExportAssignment - || kind === SyntaxKind.ExportDeclaration; - } - - export const isTypeNodeOrTypeParameterDeclaration = or(isTypeNode, isTypeParameterDeclaration) as (node: Node) => node is TypeNode | TypeParameterDeclaration; - export const isQuestionOrExclamationToken = or(isQuestionToken, isExclamationToken) as (node: Node) => node is QuestionToken | ExclamationToken; - export const isIdentifierOrThisTypeNode = or(isIdentifier, isThisTypeNode) as (node: Node) => node is Identifier | ThisTypeNode; - export const isReadonlyKeywordOrPlusOrMinusToken = or(isReadonlyKeyword, isPlusToken, isMinusToken) as (node: Node) => node is ReadonlyKeyword | PlusToken | MinusToken; - export const isQuestionOrPlusOrMinusToken = or(isQuestionToken, isPlusToken, isMinusToken) as (node: Node) => node is QuestionToken | PlusToken | MinusToken; - export const isModuleName = or(isIdentifier, isStringLiteral) as (node: Node) => node is ModuleName; - - export function isLiteralTypeLikeExpression(node: Node): node is NullLiteral | BooleanLiteral | LiteralExpression | PrefixUnaryExpression { + return kind === ts.SyntaxKind.Parameter + || kind === ts.SyntaxKind.PropertySignature + || kind === ts.SyntaxKind.PropertyDeclaration + || kind === ts.SyntaxKind.MethodSignature + || kind === ts.SyntaxKind.MethodDeclaration + || kind === ts.SyntaxKind.Constructor + || kind === ts.SyntaxKind.GetAccessor + || kind === ts.SyntaxKind.SetAccessor + || kind === ts.SyntaxKind.IndexSignature + || kind === ts.SyntaxKind.FunctionExpression + || kind === ts.SyntaxKind.ArrowFunction + || kind === ts.SyntaxKind.ClassExpression + || kind === ts.SyntaxKind.VariableStatement + || kind === ts.SyntaxKind.FunctionDeclaration + || kind === ts.SyntaxKind.ClassDeclaration + || kind === ts.SyntaxKind.InterfaceDeclaration + || kind === ts.SyntaxKind.TypeAliasDeclaration + || kind === ts.SyntaxKind.EnumDeclaration + || kind === ts.SyntaxKind.ModuleDeclaration + || kind === ts.SyntaxKind.ImportEqualsDeclaration + || kind === ts.SyntaxKind.ImportDeclaration + || kind === ts.SyntaxKind.ExportAssignment + || kind === ts.SyntaxKind.ExportDeclaration; + } + export const isTypeNodeOrTypeParameterDeclaration = ts.or(ts.isTypeNode, ts.isTypeParameterDeclaration) as (node: ts.Node) => node is ts.TypeNode | ts.TypeParameterDeclaration; + export const isQuestionOrExclamationToken = ts.or(ts.isQuestionToken, ts.isExclamationToken) as (node: ts.Node) => node is ts.QuestionToken | ts.ExclamationToken; + export const isIdentifierOrThisTypeNode = ts.or(ts.isIdentifier, ts.isThisTypeNode) as (node: ts.Node) => node is ts.Identifier | ts.ThisTypeNode; + export const isReadonlyKeywordOrPlusOrMinusToken = ts.or(ts.isReadonlyKeyword, ts.isPlusToken, ts.isMinusToken) as (node: ts.Node) => node is ts.ReadonlyKeyword | ts.PlusToken | ts.MinusToken; + export const isQuestionOrPlusOrMinusToken = ts.or(ts.isQuestionToken, ts.isPlusToken, ts.isMinusToken) as (node: ts.Node) => node is ts.QuestionToken | ts.PlusToken | ts.MinusToken; + export const isModuleName = ts.or(ts.isIdentifier, ts.isStringLiteral) as (node: ts.Node) => node is ts.ModuleName; + export function isLiteralTypeLikeExpression(node: ts.Node): node is ts.NullLiteral | ts.BooleanLiteral | ts.LiteralExpression | ts.PrefixUnaryExpression { const kind = node.kind; - return kind === SyntaxKind.NullKeyword - || kind === SyntaxKind.TrueKeyword - || kind === SyntaxKind.FalseKeyword - || isLiteralExpression(node) - || isPrefixUnaryExpression(node); + return kind === ts.SyntaxKind.NullKeyword + || kind === ts.SyntaxKind.TrueKeyword + || kind === ts.SyntaxKind.FalseKeyword + || ts.isLiteralExpression(node) + || ts.isPrefixUnaryExpression(node); } - - function isExponentiationOperator(kind: SyntaxKind): kind is ExponentiationOperator { - return kind === SyntaxKind.AsteriskAsteriskToken; + function isExponentiationOperator(kind: ts.SyntaxKind): kind is ts.ExponentiationOperator { + return kind === ts.SyntaxKind.AsteriskAsteriskToken; } - - function isMultiplicativeOperator(kind: SyntaxKind): kind is MultiplicativeOperator { - return kind === SyntaxKind.AsteriskToken - || kind === SyntaxKind.SlashToken - || kind === SyntaxKind.PercentToken; + function isMultiplicativeOperator(kind: ts.SyntaxKind): kind is ts.MultiplicativeOperator { + return kind === ts.SyntaxKind.AsteriskToken + || kind === ts.SyntaxKind.SlashToken + || kind === ts.SyntaxKind.PercentToken; } - - function isMultiplicativeOperatorOrHigher(kind: SyntaxKind): kind is MultiplicativeOperatorOrHigher { + function isMultiplicativeOperatorOrHigher(kind: ts.SyntaxKind): kind is ts.MultiplicativeOperatorOrHigher { return isExponentiationOperator(kind) || isMultiplicativeOperator(kind); } - function isAdditiveOperator(kind: SyntaxKind): kind is AdditiveOperator { - return kind === SyntaxKind.PlusToken - || kind === SyntaxKind.MinusToken; + function isAdditiveOperator(kind: ts.SyntaxKind): kind is ts.AdditiveOperator { + return kind === ts.SyntaxKind.PlusToken + || kind === ts.SyntaxKind.MinusToken; } - function isAdditiveOperatorOrHigher(kind: SyntaxKind): kind is AdditiveOperatorOrHigher { + function isAdditiveOperatorOrHigher(kind: ts.SyntaxKind): kind is ts.AdditiveOperatorOrHigher { return isAdditiveOperator(kind) || isMultiplicativeOperatorOrHigher(kind); } - function isShiftOperator(kind: SyntaxKind): kind is ShiftOperator { - return kind === SyntaxKind.LessThanLessThanToken - || kind === SyntaxKind.GreaterThanGreaterThanToken - || kind === SyntaxKind.GreaterThanGreaterThanGreaterThanToken; + function isShiftOperator(kind: ts.SyntaxKind): kind is ts.ShiftOperator { + return kind === ts.SyntaxKind.LessThanLessThanToken + || kind === ts.SyntaxKind.GreaterThanGreaterThanToken + || kind === ts.SyntaxKind.GreaterThanGreaterThanGreaterThanToken; } - function isShiftOperatorOrHigher(kind: SyntaxKind): kind is ShiftOperatorOrHigher { + function isShiftOperatorOrHigher(kind: ts.SyntaxKind): kind is ts.ShiftOperatorOrHigher { return isShiftOperator(kind) || isAdditiveOperatorOrHigher(kind); } - function isRelationalOperator(kind: SyntaxKind): kind is RelationalOperator { - return kind === SyntaxKind.LessThanToken - || kind === SyntaxKind.LessThanEqualsToken - || kind === SyntaxKind.GreaterThanToken - || kind === SyntaxKind.GreaterThanEqualsToken - || kind === SyntaxKind.InstanceOfKeyword - || kind === SyntaxKind.InKeyword; + function isRelationalOperator(kind: ts.SyntaxKind): kind is ts.RelationalOperator { + return kind === ts.SyntaxKind.LessThanToken + || kind === ts.SyntaxKind.LessThanEqualsToken + || kind === ts.SyntaxKind.GreaterThanToken + || kind === ts.SyntaxKind.GreaterThanEqualsToken + || kind === ts.SyntaxKind.InstanceOfKeyword + || kind === ts.SyntaxKind.InKeyword; } - - function isRelationalOperatorOrHigher(kind: SyntaxKind): kind is RelationalOperatorOrHigher { + function isRelationalOperatorOrHigher(kind: ts.SyntaxKind): kind is ts.RelationalOperatorOrHigher { return isRelationalOperator(kind) || isShiftOperatorOrHigher(kind); } - function isEqualityOperator(kind: SyntaxKind): kind is EqualityOperator { - return kind === SyntaxKind.EqualsEqualsToken - || kind === SyntaxKind.EqualsEqualsEqualsToken - || kind === SyntaxKind.ExclamationEqualsToken - || kind === SyntaxKind.ExclamationEqualsEqualsToken; + function isEqualityOperator(kind: ts.SyntaxKind): kind is ts.EqualityOperator { + return kind === ts.SyntaxKind.EqualsEqualsToken + || kind === ts.SyntaxKind.EqualsEqualsEqualsToken + || kind === ts.SyntaxKind.ExclamationEqualsToken + || kind === ts.SyntaxKind.ExclamationEqualsEqualsToken; } - function isEqualityOperatorOrHigher(kind: SyntaxKind): kind is EqualityOperatorOrHigher { + function isEqualityOperatorOrHigher(kind: ts.SyntaxKind): kind is ts.EqualityOperatorOrHigher { return isEqualityOperator(kind) || isRelationalOperatorOrHigher(kind); } - function isBitwiseOperator(kind: SyntaxKind): kind is BitwiseOperator { - return kind === SyntaxKind.AmpersandToken - || kind === SyntaxKind.BarToken - || kind === SyntaxKind.CaretToken; + function isBitwiseOperator(kind: ts.SyntaxKind): kind is ts.BitwiseOperator { + return kind === ts.SyntaxKind.AmpersandToken + || kind === ts.SyntaxKind.BarToken + || kind === ts.SyntaxKind.CaretToken; } - function isBitwiseOperatorOrHigher(kind: SyntaxKind): kind is BitwiseOperatorOrHigher { + function isBitwiseOperatorOrHigher(kind: ts.SyntaxKind): kind is ts.BitwiseOperatorOrHigher { return isBitwiseOperator(kind) || isEqualityOperatorOrHigher(kind); } // NOTE: The version in utilities includes ExclamationToken, which is not a binary operator. - function isLogicalOperator(kind: SyntaxKind): kind is LogicalOperator { - return kind === SyntaxKind.AmpersandAmpersandToken - || kind === SyntaxKind.BarBarToken; + function isLogicalOperator(kind: ts.SyntaxKind): kind is ts.LogicalOperator { + return kind === ts.SyntaxKind.AmpersandAmpersandToken + || kind === ts.SyntaxKind.BarBarToken; } - function isLogicalOperatorOrHigher(kind: SyntaxKind): kind is LogicalOperatorOrHigher { + function isLogicalOperatorOrHigher(kind: ts.SyntaxKind): kind is ts.LogicalOperatorOrHigher { return isLogicalOperator(kind) || isBitwiseOperatorOrHigher(kind); } - function isAssignmentOperatorOrHigher(kind: SyntaxKind): kind is AssignmentOperatorOrHigher { - return kind === SyntaxKind.QuestionQuestionToken + function isAssignmentOperatorOrHigher(kind: ts.SyntaxKind): kind is ts.AssignmentOperatorOrHigher { + return kind === ts.SyntaxKind.QuestionQuestionToken || isLogicalOperatorOrHigher(kind) - || isAssignmentOperator(kind); + || ts.isAssignmentOperator(kind); } - function isBinaryOperator(kind: SyntaxKind): kind is BinaryOperator { + function isBinaryOperator(kind: ts.SyntaxKind): kind is ts.BinaryOperator { return isAssignmentOperatorOrHigher(kind) - || kind === SyntaxKind.CommaToken; + || kind === ts.SyntaxKind.CommaToken; } - export function isBinaryOperatorToken(node: Node): node is BinaryOperatorToken { + export function isBinaryOperatorToken(node: ts.Node): node is ts.BinaryOperatorToken { return isBinaryOperator(node.kind); } - type BinaryExpressionState = (machine: BinaryExpressionStateMachine, stackIndex: number, stateStack: BinaryExpressionState[], nodeStack: BinaryExpression[], userStateStack: TState[], resultHolder: { value: TResult }, outerState: TOuterState) => number; + type BinaryExpressionState = (machine: BinaryExpressionStateMachine, stackIndex: number, stateStack: BinaryExpressionState[], nodeStack: ts.BinaryExpression[], userStateStack: TState[], resultHolder: { + value: TResult; + }, outerState: TOuterState) => number; namespace BinaryExpressionState { /** @@ -1016,9 +919,11 @@ namespace ts { * @param frame The current frame * @returns The new frame */ - export function enter(machine: BinaryExpressionStateMachine, stackIndex: number, stateStack: BinaryExpressionState[], nodeStack: BinaryExpression[], userStateStack: TState[], _resultHolder: { value: TResult }, outerState: TOuterState): number { + export function enter(machine: BinaryExpressionStateMachine, stackIndex: number, stateStack: BinaryExpressionState[], nodeStack: ts.BinaryExpression[], userStateStack: TState[], _resultHolder: { + value: TResult; + }, outerState: TOuterState): number { const prevUserState = stackIndex > 0 ? userStateStack[stackIndex - 1] : undefined; - Debug.assertEqual(stateStack[stackIndex], enter); + ts.Debug.assertEqual(stateStack[stackIndex], enter); userStateStack[stackIndex] = machine.onEnter(nodeStack[stackIndex], prevUserState, outerState); stateStack[stackIndex] = nextState(machine, enter); return stackIndex; @@ -1030,9 +935,11 @@ namespace ts { * @param frame The current frame * @returns The new frame */ - export function left(machine: BinaryExpressionStateMachine, stackIndex: number, stateStack: BinaryExpressionState[], nodeStack: BinaryExpression[], userStateStack: TState[], _resultHolder: { value: TResult }, _outerState: TOuterState): number { - Debug.assertEqual(stateStack[stackIndex], left); - Debug.assertIsDefined(machine.onLeft); + export function left(machine: BinaryExpressionStateMachine, stackIndex: number, stateStack: BinaryExpressionState[], nodeStack: ts.BinaryExpression[], userStateStack: TState[], _resultHolder: { + value: TResult; + }, _outerState: TOuterState): number { + ts.Debug.assertEqual(stateStack[stackIndex], left); + ts.Debug.assertIsDefined(machine.onLeft); stateStack[stackIndex] = nextState(machine, left); const nextNode = machine.onLeft(nodeStack[stackIndex].left, userStateStack[stackIndex], nodeStack[stackIndex]); if (nextNode) { @@ -1048,9 +955,11 @@ namespace ts { * @param frame The current frame * @returns The new frame */ - export function operator(machine: BinaryExpressionStateMachine, stackIndex: number, stateStack: BinaryExpressionState[], nodeStack: BinaryExpression[], userStateStack: TState[], _resultHolder: { value: TResult }, _outerState: TOuterState): number { - Debug.assertEqual(stateStack[stackIndex], operator); - Debug.assertIsDefined(machine.onOperator); + export function operator(machine: BinaryExpressionStateMachine, stackIndex: number, stateStack: BinaryExpressionState[], nodeStack: ts.BinaryExpression[], userStateStack: TState[], _resultHolder: { + value: TResult; + }, _outerState: TOuterState): number { + ts.Debug.assertEqual(stateStack[stackIndex], operator); + ts.Debug.assertIsDefined(machine.onOperator); stateStack[stackIndex] = nextState(machine, operator); machine.onOperator(nodeStack[stackIndex].operatorToken, userStateStack[stackIndex], nodeStack[stackIndex]); return stackIndex; @@ -1062,9 +971,11 @@ namespace ts { * @param frame The current frame * @returns The new frame */ - export function right(machine: BinaryExpressionStateMachine, stackIndex: number, stateStack: BinaryExpressionState[], nodeStack: BinaryExpression[], userStateStack: TState[], _resultHolder: { value: TResult }, _outerState: TOuterState): number { - Debug.assertEqual(stateStack[stackIndex], right); - Debug.assertIsDefined(machine.onRight); + export function right(machine: BinaryExpressionStateMachine, stackIndex: number, stateStack: BinaryExpressionState[], nodeStack: ts.BinaryExpression[], userStateStack: TState[], _resultHolder: { + value: TResult; + }, _outerState: TOuterState): number { + ts.Debug.assertEqual(stateStack[stackIndex], right); + ts.Debug.assertIsDefined(machine.onRight); stateStack[stackIndex] = nextState(machine, right); const nextNode = machine.onRight(nodeStack[stackIndex].right, userStateStack[stackIndex], nodeStack[stackIndex]); if (nextNode) { @@ -1080,8 +991,10 @@ namespace ts { * @param frame The current frame * @returns The new frame */ - export function exit(machine: BinaryExpressionStateMachine, stackIndex: number, stateStack: BinaryExpressionState[], nodeStack: BinaryExpression[], userStateStack: TState[], resultHolder: { value: TResult }, _outerState: TOuterState): number { - Debug.assertEqual(stateStack[stackIndex], exit); + export function exit(machine: BinaryExpressionStateMachine, stackIndex: number, stateStack: BinaryExpressionState[], nodeStack: ts.BinaryExpression[], userStateStack: TState[], resultHolder: { + value: TResult; + }, _outerState: TOuterState): number { + ts.Debug.assertEqual(stateStack[stackIndex], exit); stateStack[stackIndex] = nextState(machine, exit); const result = machine.onExit(nodeStack[stackIndex], userStateStack[stackIndex]); if (stackIndex > 0) { @@ -1101,30 +1014,35 @@ namespace ts { * Handles a frame that is already done. * @returns The `done` state. */ - export function done(_machine: BinaryExpressionStateMachine, stackIndex: number, stateStack: BinaryExpressionState[], _nodeStack: BinaryExpression[], _userStateStack: TState[], _resultHolder: { value: TResult }, _outerState: TOuterState): number { - Debug.assertEqual(stateStack[stackIndex], done); + export function done(_machine: BinaryExpressionStateMachine, stackIndex: number, stateStack: BinaryExpressionState[], _nodeStack: ts.BinaryExpression[], _userStateStack: TState[], _resultHolder: { + value: TResult; + }, _outerState: TOuterState): number { + ts.Debug.assertEqual(stateStack[stackIndex], done); return stackIndex; } export function nextState(machine: BinaryExpressionStateMachine, currentState: BinaryExpressionState) { switch (currentState) { case enter: - if (machine.onLeft) return left; + if (machine.onLeft) + return left; // falls through case left: - if (machine.onOperator) return operator; + if (machine.onOperator) + return operator; // falls through case operator: - if (machine.onRight) return right; + if (machine.onRight) + return right; // falls through case right: return exit; case exit: return done; case done: return done; - default: Debug.fail("Invalid state"); + default: ts.Debug.fail("Invalid state"); } } - function pushStack(stackIndex: number, stateStack: BinaryExpressionState[], nodeStack: BinaryExpression[], userStateStack: TState[], node: BinaryExpression) { + function pushStack(stackIndex: number, stateStack: BinaryExpressionState[], nodeStack: ts.BinaryExpression[], userStateStack: TState[], node: ts.BinaryExpression) { stackIndex++; stateStack[stackIndex] = enter; nodeStack[stackIndex] = node; @@ -1132,10 +1050,10 @@ namespace ts { return stackIndex; } - function checkCircularity(stackIndex: number, nodeStack: BinaryExpression[], node: BinaryExpression) { - if (Debug.shouldAssert(AssertionLevel.Aggressive)) { + function checkCircularity(stackIndex: number, nodeStack: ts.BinaryExpression[], node: ts.BinaryExpression) { + if (ts.Debug.shouldAssert(ts.AssertionLevel.Aggressive)) { while (stackIndex >= 0) { - Debug.assert(nodeStack[stackIndex] !== node, "Circular traversal detected."); + ts.Debug.assert(nodeStack[stackIndex] !== node, "Circular traversal detected."); stackIndex--; } } @@ -1146,14 +1064,7 @@ namespace ts { * Holds state machine handler functions */ class BinaryExpressionStateMachine { - constructor( - readonly onEnter: (node: BinaryExpression, prev: TState | undefined, outerState: TOuterState) => TState, - readonly onLeft: ((left: Expression, userState: TState, node: BinaryExpression) => BinaryExpression | void) | undefined, - readonly onOperator: ((operatorToken: BinaryOperatorToken, userState: TState, node: BinaryExpression) => void) | undefined, - readonly onRight: ((right: Expression, userState: TState, node: BinaryExpression) => BinaryExpression | void) | undefined, - readonly onExit: (node: BinaryExpression, userState: TState) => TResult, - readonly foldState: ((userState: TState, result: TResult, side: "left" | "right") => TState) | undefined, - ) { + constructor(readonly onEnter: (node: ts.BinaryExpression, prev: TState | undefined, outerState: TOuterState) => TState, readonly onLeft: ((left: ts.Expression, userState: TState, node: ts.BinaryExpression) => ts.BinaryExpression | void) | undefined, readonly onOperator: ((operatorToken: ts.BinaryOperatorToken, userState: TState, node: ts.BinaryExpression) => void) | undefined, readonly onRight: ((right: ts.Expression, userState: TState, node: ts.BinaryExpression) => ts.BinaryExpression | void) | undefined, readonly onExit: (node: ts.BinaryExpression, userState: TState) => TResult, readonly foldState: ((userState: TState, result: TResult, side: "left" | "right") => TState) | undefined) { } } @@ -1166,14 +1077,7 @@ namespace ts { * @param foldState Callback evaluated when the result from a nested `onExit` should be folded into the state of that node's parent. * @returns A function that walks a `BinaryExpression` node using the above callbacks, returning the result of the call to `onExit` from the outermost `BinaryExpression` node. */ - export function createBinaryExpressionTrampoline( - onEnter: (node: BinaryExpression, prev: TState | undefined) => TState, - onLeft: ((left: Expression, userState: TState, node: BinaryExpression) => BinaryExpression | void) | undefined, - onOperator: ((operatorToken: BinaryOperatorToken, userState: TState, node: BinaryExpression) => void) | undefined, - onRight: ((right: Expression, userState: TState, node: BinaryExpression) => BinaryExpression | void) | undefined, - onExit: (node: BinaryExpression, userState: TState) => TResult, - foldState: ((userState: TState, result: TResult, side: "left" | "right") => TState) | undefined, - ): (node: BinaryExpression) => TResult; + export function createBinaryExpressionTrampoline(onEnter: (node: ts.BinaryExpression, prev: TState | undefined) => TState, onLeft: ((left: ts.Expression, userState: TState, node: ts.BinaryExpression) => ts.BinaryExpression | void) | undefined, onOperator: ((operatorToken: ts.BinaryOperatorToken, userState: TState, node: ts.BinaryExpression) => void) | undefined, onRight: ((right: ts.Expression, userState: TState, node: ts.BinaryExpression) => ts.BinaryExpression | void) | undefined, onExit: (node: ts.BinaryExpression, userState: TState) => TResult, foldState: ((userState: TState, result: TResult, side: "left" | "right") => TState) | undefined): (node: ts.BinaryExpression) => TResult; /** * Creates a state machine that walks a `BinaryExpression` using the heap to reduce call-stack depth on a large tree. * @param onEnter Callback evaluated when entering a `BinaryExpression`. Returns new user-defined state to associate with the node while walking. @@ -1183,35 +1087,23 @@ namespace ts { * @param foldState Callback evaluated when the result from a nested `onExit` should be folded into the state of that node's parent. * @returns A function that walks a `BinaryExpression` node using the above callbacks, returning the result of the call to `onExit` from the outermost `BinaryExpression` node. */ - export function createBinaryExpressionTrampoline( - onEnter: (node: BinaryExpression, prev: TState | undefined, outerState: TOuterState) => TState, - onLeft: ((left: Expression, userState: TState, node: BinaryExpression) => BinaryExpression | void) | undefined, - onOperator: ((operatorToken: BinaryOperatorToken, userState: TState, node: BinaryExpression) => void) | undefined, - onRight: ((right: Expression, userState: TState, node: BinaryExpression) => BinaryExpression | void) | undefined, - onExit: (node: BinaryExpression, userState: TState) => TResult, - foldState: ((userState: TState, result: TResult, side: "left" | "right") => TState) | undefined, - ): (node: BinaryExpression, outerState: TOuterState) => TResult; - export function createBinaryExpressionTrampoline( - onEnter: (node: BinaryExpression, prev: TState | undefined, outerState: TOuterState) => TState, - onLeft: ((left: Expression, userState: TState, node: BinaryExpression) => BinaryExpression | void) | undefined, - onOperator: ((operatorToken: BinaryOperatorToken, userState: TState, node: BinaryExpression) => void) | undefined, - onRight: ((right: Expression, userState: TState, node: BinaryExpression) => BinaryExpression | void) | undefined, - onExit: (node: BinaryExpression, userState: TState) => TResult, - foldState: ((userState: TState, result: TResult, side: "left" | "right") => TState) | undefined, - ) { + export function createBinaryExpressionTrampoline(onEnter: (node: ts.BinaryExpression, prev: TState | undefined, outerState: TOuterState) => TState, onLeft: ((left: ts.Expression, userState: TState, node: ts.BinaryExpression) => ts.BinaryExpression | void) | undefined, onOperator: ((operatorToken: ts.BinaryOperatorToken, userState: TState, node: ts.BinaryExpression) => void) | undefined, onRight: ((right: ts.Expression, userState: TState, node: ts.BinaryExpression) => ts.BinaryExpression | void) | undefined, onExit: (node: ts.BinaryExpression, userState: TState) => TResult, foldState: ((userState: TState, result: TResult, side: "left" | "right") => TState) | undefined): (node: ts.BinaryExpression, outerState: TOuterState) => TResult; + export function createBinaryExpressionTrampoline(onEnter: (node: ts.BinaryExpression, prev: TState | undefined, outerState: TOuterState) => TState, onLeft: ((left: ts.Expression, userState: TState, node: ts.BinaryExpression) => ts.BinaryExpression | void) | undefined, onOperator: ((operatorToken: ts.BinaryOperatorToken, userState: TState, node: ts.BinaryExpression) => void) | undefined, onRight: ((right: ts.Expression, userState: TState, node: ts.BinaryExpression) => ts.BinaryExpression | void) | undefined, onExit: (node: ts.BinaryExpression, userState: TState) => TResult, foldState: ((userState: TState, result: TResult, side: "left" | "right") => TState) | undefined) { const machine = new BinaryExpressionStateMachine(onEnter, onLeft, onOperator, onRight, onExit, foldState); return trampoline; - function trampoline(node: BinaryExpression, outerState?: TOuterState) { - const resultHolder: { value: TResult } = { value: undefined! }; + function trampoline(node: ts.BinaryExpression, outerState?: TOuterState) { + const resultHolder: { + value: TResult; + } = { value: undefined! }; const stateStack: BinaryExpressionState[] = [BinaryExpressionState.enter]; - const nodeStack: BinaryExpression[] = [node]; + const nodeStack: ts.BinaryExpression[] = [node]; const userStateStack: TState[] = [undefined!]; let stackIndex = 0; while (stateStack[stackIndex] !== BinaryExpressionState.done) { stackIndex = stateStack[stackIndex](machine, stackIndex, stateStack, nodeStack, userStateStack, resultHolder, outerState); } - Debug.assertEqual(stackIndex, 0); + ts.Debug.assertEqual(stackIndex, 0); return resultHolder.value; } } diff --git a/src/compiler/factory/utilitiesPublic.ts b/src/compiler/factory/utilitiesPublic.ts index 9dd28667eb0e1..9e87cbfa68dff 100644 --- a/src/compiler/factory/utilitiesPublic.ts +++ b/src/compiler/factory/utilitiesPublic.ts @@ -1,5 +1,5 @@ namespace ts { - export function setTextRange(range: T, location: TextRange | undefined): T { - return location ? setTextRangePosEnd(range, location.pos, location.end) : range; + export function setTextRange(range: T, location: ts.TextRange | undefined): T { + return location ? ts.setTextRangePosEnd(range, location.pos, location.end) : range; } } \ No newline at end of file diff --git a/src/compiler/moduleNameResolver.ts b/src/compiler/moduleNameResolver.ts index 8f466c0495aee..3f4053701f336 100644 --- a/src/compiler/moduleNameResolver.ts +++ b/src/compiler/moduleNameResolver.ts @@ -1,23 +1,23 @@ namespace ts { /* @internal */ - export function trace(host: ModuleResolutionHost, message: DiagnosticMessage, ...args: any[]): void; - export function trace(host: ModuleResolutionHost): void { - host.trace!(formatMessage.apply(undefined, arguments)); + export function trace(host: ts.ModuleResolutionHost, message: ts.DiagnosticMessage, ...args: any[]): void; + export function trace(host: ts.ModuleResolutionHost): void { + host.trace!(ts.formatMessage.apply(undefined, arguments)); } /* @internal */ - export function isTraceEnabled(compilerOptions: CompilerOptions, host: ModuleResolutionHost): boolean { + export function isTraceEnabled(compilerOptions: ts.CompilerOptions, host: ts.ModuleResolutionHost): boolean { return !!compilerOptions.traceResolution && host.trace !== undefined; } function withPackageId(packageInfo: PackageJsonInfo | undefined, r: PathAndExtension | undefined): Resolved | undefined { - let packageId: PackageId | undefined; + let packageId: ts.PackageId | undefined; if (r && packageInfo) { const packageJsonContent = packageInfo.packageJsonContent as PackageJson; if (typeof packageJsonContent.name === "string" && typeof packageJsonContent.version === "string") { packageId = { name: packageJsonContent.name, - subModuleName: r.path.slice(packageInfo.packageDirectory.length + directorySeparator.length), + subModuleName: r.path.slice(packageInfo.packageDirectory.length + ts.directorySeparator.length), version: packageJsonContent.version }; } @@ -31,7 +31,7 @@ namespace ts { function removeIgnoredPackageId(r: Resolved | undefined): PathAndExtension | undefined { if (r) { - Debug.assert(r.packageId === undefined); + ts.Debug.assert(r.packageId === undefined); return { path: r.path, ext: r.extension }; } } @@ -39,8 +39,8 @@ namespace ts { /** Result of trying to resolve a module. */ interface Resolved { path: string; - extension: Extension; - packageId: PackageId | undefined; + extension: ts.Extension; + packageId: ts.PackageId | undefined; /** * When the resolved is not created from cache, the value is * - string if it is symbolic link to the resolved `path` @@ -57,7 +57,7 @@ namespace ts { interface PathAndExtension { path: string; // (Use a different name than `extension` to make sure Resolved isn't assignable to PathAndExtension.) - ext: Extension; + ext: ts.Extension; } /** @@ -65,28 +65,28 @@ namespace ts { * Typically there is one pass with Extensions.TypeScript, then a second pass with Extensions.JavaScript. */ enum Extensions { - TypeScript, /** '.ts', '.tsx', or '.d.ts' */ - JavaScript, /** '.js' or '.jsx' */ - Json, /** '.json' */ - TSConfig, /** '.json' with `tsconfig` used instead of `index` */ - DtsOnly, /** Only '.d.ts' */ - TsOnly, /** '.[cm]tsx?' but not .d.ts variants */ + TypeScript, + JavaScript, + Json, + TSConfig, + DtsOnly, + TsOnly } interface PathAndPackageId { readonly fileName: string; - readonly packageId: PackageId | undefined; + readonly packageId: ts.PackageId | undefined; } /** Used with `Extensions.DtsOnly` to extract the path from TypeScript results. */ function resolvedTypeScriptOnly(resolved: Resolved | undefined): PathAndPackageId | undefined { if (!resolved) { return undefined; } - Debug.assert(extensionIsTS(resolved.extension)); + ts.Debug.assert(ts.extensionIsTS(resolved.extension)); return { fileName: resolved.path, packageId: resolved.packageId }; } - function createResolvedModuleWithFailedLookupLocations(resolved: Resolved | undefined, isExternalLibraryImport: boolean | undefined, failedLookupLocations: string[], diagnostics: Diagnostic[], resultFromCache: ResolvedModuleWithFailedLookupLocations | undefined): ResolvedModuleWithFailedLookupLocations { + function createResolvedModuleWithFailedLookupLocations(resolved: Resolved | undefined, isExternalLibraryImport: boolean | undefined, failedLookupLocations: string[], diagnostics: ts.Diagnostic[], resultFromCache: ts.ResolvedModuleWithFailedLookupLocations | undefined): ts.ResolvedModuleWithFailedLookupLocations { if (resultFromCache) { resultFromCache.failedLookupLocations.push(...failedLookupLocations); return resultFromCache; @@ -100,16 +100,16 @@ namespace ts { /*@internal*/ interface ModuleResolutionState { - host: ModuleResolutionHost; - compilerOptions: CompilerOptions; + host: ts.ModuleResolutionHost; + compilerOptions: ts.CompilerOptions; traceEnabled: boolean; - failedLookupLocations: Push; - resultFromCache?: ResolvedModuleWithFailedLookupLocations; + failedLookupLocations: ts.Push; + resultFromCache?: ts.ResolvedModuleWithFailedLookupLocations; packageJsonInfoCache: PackageJsonInfoCache | undefined; features: NodeResolutionFeatures; conditions: string[]; requestContainingDirectory: string | undefined; - reportDiagnostic: DiagnosticReporter; + reportDiagnostic: ts.DiagnosticReporter; } /** Just the fields that we use for module resolution. */ @@ -117,7 +117,7 @@ namespace ts { interface PackageJsonPathFields { typings?: string; types?: string; - typesVersions?: MapLike>; + typesVersions?: ts.MapLike>; main?: string; tsconfig?: string; type?: string; @@ -131,12 +131,12 @@ namespace ts { version?: string; } - function readPackageJsonField>(jsonContent: PackageJson, fieldName: K, typeOfTag: "string", state: ModuleResolutionState): PackageJson[K] | undefined; - function readPackageJsonField>(jsonContent: PackageJson, fieldName: K, typeOfTag: "object", state: ModuleResolutionState): PackageJson[K] | undefined; + function readPackageJsonField>(jsonContent: PackageJson, fieldName: K, typeOfTag: "string", state: ModuleResolutionState): PackageJson[K] | undefined; + function readPackageJsonField>(jsonContent: PackageJson, fieldName: K, typeOfTag: "object", state: ModuleResolutionState): PackageJson[K] | undefined; function readPackageJsonField(jsonContent: PackageJson, fieldName: K, typeOfTag: "string" | "object", state: ModuleResolutionState): PackageJson[K] | undefined { - if (!hasProperty(jsonContent, fieldName)) { + if (!ts.hasProperty(jsonContent, fieldName)) { if (state.traceEnabled) { - trace(state.host, Diagnostics.package_json_does_not_have_a_0_field, fieldName); + trace(state.host, ts.Diagnostics.package_json_does_not_have_a_0_field, fieldName); } return; } @@ -144,7 +144,7 @@ namespace ts { if (typeof value !== typeOfTag || value === null) { // eslint-disable-line no-null/no-null if (state.traceEnabled) { // eslint-disable-next-line no-null/no-null - trace(state.host, Diagnostics.Expected_type_of_0_field_in_package_json_to_be_1_got_2, fieldName, typeOfTag, value === null ? "null" : typeof value); + trace(state.host, ts.Diagnostics.Expected_type_of_0_field_in_package_json_to_be_1_got_2, fieldName, typeOfTag, value === null ? "null" : typeof value); } return; } @@ -158,13 +158,13 @@ namespace ts { } if (!fileName) { if (state.traceEnabled) { - trace(state.host, Diagnostics.package_json_had_a_falsy_0_field, fieldName); + trace(state.host, ts.Diagnostics.package_json_had_a_falsy_0_field, fieldName); } return; } - const path = normalizePath(combinePaths(baseDirectory, fileName)); + const path = ts.normalizePath(ts.combinePaths(baseDirectory, fileName)); if (state.traceEnabled) { - trace(state.host, Diagnostics.package_json_has_0_field_1_that_references_2, fieldName, fileName, path); + trace(state.host, ts.Diagnostics.package_json_has_0_field_1_that_references_2, fieldName, fileName, path); } return path; } @@ -184,10 +184,11 @@ namespace ts { function readPackageJsonTypesVersionsField(jsonContent: PackageJson, state: ModuleResolutionState) { const typesVersions = readPackageJsonField(jsonContent, "typesVersions", "object", state); - if (typesVersions === undefined) return; + if (typesVersions === undefined) + return; if (state.traceEnabled) { - trace(state.host, Diagnostics.package_json_has_a_typesVersions_field_with_version_specific_path_mappings); + trace(state.host, ts.Diagnostics.package_json_has_a_typesVersions_field_with_version_specific_path_mappings); } return typesVersions; @@ -196,17 +197,18 @@ namespace ts { /*@internal*/ interface VersionPaths { version: string; - paths: MapLike; + paths: ts.MapLike; } function readPackageJsonTypesVersionPaths(jsonContent: PackageJson, state: ModuleResolutionState): VersionPaths | undefined { const typesVersions = readPackageJsonTypesVersionsField(jsonContent, state); - if (typesVersions === undefined) return; + if (typesVersions === undefined) + return; if (state.traceEnabled) { for (const key in typesVersions) { - if (hasProperty(typesVersions, key) && !VersionRange.tryParse(key)) { - trace(state.host, Diagnostics.package_json_has_a_typesVersions_entry_0_that_is_not_a_valid_semver_range, key); + if (ts.hasProperty(typesVersions, key) && !ts.VersionRange.tryParse(key)) { + trace(state.host, ts.Diagnostics.package_json_has_a_typesVersions_entry_0_that_is_not_a_valid_semver_range, key); } } } @@ -214,7 +216,7 @@ namespace ts { const result = getPackageJsonTypesVersionsPaths(typesVersions); if (!result) { if (state.traceEnabled) { - trace(state.host, Diagnostics.package_json_does_not_have_a_typesVersions_entry_that_matches_version_0, versionMajorMinor); + trace(state.host, ts.Diagnostics.package_json_does_not_have_a_typesVersions_entry_that_matches_version_0, ts.versionMajorMinor); } return; } @@ -222,7 +224,7 @@ namespace ts { const { version: bestVersionKey, paths: bestVersionPaths } = result; if (typeof bestVersionPaths !== "object") { if (state.traceEnabled) { - trace(state.host, Diagnostics.Expected_type_of_0_field_in_package_json_to_be_1_got_2, `typesVersions['${bestVersionKey}']`, "object", typeof bestVersionPaths); + trace(state.host, ts.Diagnostics.Expected_type_of_0_field_in_package_json_to_be_1_got_2, `typesVersions['${bestVersionKey}']`, "object", typeof bestVersionPaths); } return; } @@ -230,16 +232,17 @@ namespace ts { return result; } - let typeScriptVersion: Version | undefined; + let typeScriptVersion: ts.Version | undefined; /* @internal */ - export function getPackageJsonTypesVersionsPaths(typesVersions: MapLike>) { - if (!typeScriptVersion) typeScriptVersion = new Version(version); + export function getPackageJsonTypesVersionsPaths(typesVersions: ts.MapLike>) { + if (!typeScriptVersion) + typeScriptVersion = new ts.Version(ts.version); for (const key in typesVersions) { - if (!hasProperty(typesVersions, key)) continue; - - const keyRange = VersionRange.tryParse(key); + if (!ts.hasProperty(typesVersions, key)) + continue; + const keyRange = ts.VersionRange.tryParse(key); if (keyRange === undefined) { continue; } @@ -251,14 +254,14 @@ namespace ts { } } - export function getEffectiveTypeRoots(options: CompilerOptions, host: GetEffectiveTypeRootsHost): string[] | undefined { + export function getEffectiveTypeRoots(options: ts.CompilerOptions, host: ts.GetEffectiveTypeRootsHost): string[] | undefined { if (options.typeRoots) { return options.typeRoots; } let currentDirectory: string | undefined; if (options.configFilePath) { - currentDirectory = getDirectoryPath(options.configFilePath); + currentDirectory = ts.getDirectoryPath(options.configFilePath); } else if (host.getCurrentDirectory) { currentDirectory = host.getCurrentDirectory(); @@ -273,15 +276,17 @@ namespace ts { * Returns the path to every node_modules/@types directory from some ancestor directory. * Returns undefined if there are none. */ - function getDefaultTypeRoots(currentDirectory: string, host: { directoryExists?: (directoryName: string) => boolean }): string[] | undefined { + function getDefaultTypeRoots(currentDirectory: string, host: { + directoryExists?: (directoryName: string) => boolean; + }): string[] | undefined { if (!host.directoryExists) { - return [combinePaths(currentDirectory, nodeModulesAtTypes)]; + return [ts.combinePaths(currentDirectory, nodeModulesAtTypes)]; // And if it doesn't exist, tough. } let typeRoots: string[] | undefined; - forEachAncestorDirectory(normalizePath(currentDirectory), directory => { - const atTypes = combinePaths(directory, nodeModulesAtTypes); + ts.forEachAncestorDirectory(ts.normalizePath(currentDirectory), directory => { + const atTypes = ts.combinePaths(directory, nodeModulesAtTypes); if (host.directoryExists!(atTypes)) { (typeRoots || (typeRoots = [])).push(atTypes); } @@ -289,11 +294,10 @@ namespace ts { }); return typeRoots; } - const nodeModulesAtTypes = combinePaths("node_modules", "@types"); - - function arePathsEqual(path1: string, path2: string, host: ModuleResolutionHost): boolean { + const nodeModulesAtTypes = ts.combinePaths("node_modules", "@types"); + function arePathsEqual(path1: string, path2: string, host: ts.ModuleResolutionHost): boolean { const useCaseSensitiveFileNames = typeof host.useCaseSensitiveFileNames === "function" ? host.useCaseSensitiveFileNames() : host.useCaseSensitiveFileNames; - return comparePaths(path1, path2, !useCaseSensitiveFileNames) === Comparison.EqualTo; + return ts.comparePaths(path1, path2, !useCaseSensitiveFileNames) === ts.Comparison.EqualTo; } /** @@ -301,21 +305,22 @@ namespace ts { * This is possible in case if resolution is performed for directives specified via 'types' parameter. In this case initial path for secondary lookups * is assumed to be the same as root directory of the project. */ - export function resolveTypeReferenceDirective(typeReferenceDirectiveName: string, containingFile: string | undefined, options: CompilerOptions, host: ModuleResolutionHost, redirectedReference?: ResolvedProjectReference, cache?: TypeReferenceDirectiveResolutionCache, resolutionMode?: SourceFile["impliedNodeFormat"]): ResolvedTypeReferenceDirectiveWithFailedLookupLocations { - Debug.assert(typeof typeReferenceDirectiveName === "string", "Non-string value passed to `ts.resolveTypeReferenceDirective`, likely by a wrapping package working with an outdated `resolveTypeReferenceDirectives` signature. This is probably not a problem in TS itself."); + export function resolveTypeReferenceDirective(typeReferenceDirectiveName: string, containingFile: string | undefined, options: ts.CompilerOptions, host: ts.ModuleResolutionHost, redirectedReference?: ts.ResolvedProjectReference, cache?: TypeReferenceDirectiveResolutionCache, resolutionMode?: ts.SourceFile["impliedNodeFormat"]): ts.ResolvedTypeReferenceDirectiveWithFailedLookupLocations { + ts.Debug.assert(typeof typeReferenceDirectiveName === "string", "Non-string value passed to `ts.resolveTypeReferenceDirective`, likely by a wrapping package working with an outdated `resolveTypeReferenceDirectives` signature. This is probably not a problem in TS itself."); const traceEnabled = isTraceEnabled(options, host); if (redirectedReference) { options = redirectedReference.commandLine.options; } - const containingDirectory = containingFile ? getDirectoryPath(containingFile) : undefined; + const containingDirectory = containingFile ? ts.getDirectoryPath(containingFile) : undefined; const perFolderCache = containingDirectory ? cache && cache.getOrCreateCacheForDirectory(containingDirectory, redirectedReference) : undefined; let result = perFolderCache && perFolderCache.get(typeReferenceDirectiveName, /*mode*/ resolutionMode); if (result) { if (traceEnabled) { - trace(host, Diagnostics.Resolving_type_reference_directive_0_containing_file_1, typeReferenceDirectiveName, containingFile); - if (redirectedReference) trace(host, Diagnostics.Using_compiler_options_of_project_reference_redirect_0, redirectedReference.sourceFile.fileName); - trace(host, Diagnostics.Resolution_for_type_reference_directive_0_was_found_in_cache_from_location_1, typeReferenceDirectiveName, containingDirectory); + trace(host, ts.Diagnostics.Resolving_type_reference_directive_0_containing_file_1, typeReferenceDirectiveName, containingFile); + if (redirectedReference) + trace(host, ts.Diagnostics.Using_compiler_options_of_project_reference_redirect_0, redirectedReference.sourceFile.fileName); + trace(host, ts.Diagnostics.Resolution_for_type_reference_directive_0_was_found_in_cache_from_location_1, typeReferenceDirectiveName, containingDirectory); traceResult(result); } return result; @@ -325,22 +330,22 @@ namespace ts { if (traceEnabled) { if (containingFile === undefined) { if (typeRoots === undefined) { - trace(host, Diagnostics.Resolving_type_reference_directive_0_containing_file_not_set_root_directory_not_set, typeReferenceDirectiveName); + trace(host, ts.Diagnostics.Resolving_type_reference_directive_0_containing_file_not_set_root_directory_not_set, typeReferenceDirectiveName); } else { - trace(host, Diagnostics.Resolving_type_reference_directive_0_containing_file_not_set_root_directory_1, typeReferenceDirectiveName, typeRoots); + trace(host, ts.Diagnostics.Resolving_type_reference_directive_0_containing_file_not_set_root_directory_1, typeReferenceDirectiveName, typeRoots); } } else { if (typeRoots === undefined) { - trace(host, Diagnostics.Resolving_type_reference_directive_0_containing_file_1_root_directory_not_set, typeReferenceDirectiveName, containingFile); + trace(host, ts.Diagnostics.Resolving_type_reference_directive_0_containing_file_1_root_directory_not_set, typeReferenceDirectiveName, containingFile); } else { - trace(host, Diagnostics.Resolving_type_reference_directive_0_containing_file_1_root_directory_2, typeReferenceDirectiveName, containingFile, typeRoots); + trace(host, ts.Diagnostics.Resolving_type_reference_directive_0_containing_file_1_root_directory_2, typeReferenceDirectiveName, containingFile, typeRoots); } } if (redirectedReference) { - trace(host, Diagnostics.Using_compiler_options_of_project_reference_redirect_0, redirectedReference.sourceFile.fileName); + trace(host, ts.Diagnostics.Using_compiler_options_of_project_reference_redirect_0, redirectedReference.sourceFile.fileName); } } @@ -353,11 +358,11 @@ namespace ts { // in practice, not every cache has the options available to intelligently make the choice to ignore the mode request, and it's unclear how modern "faithful modern // resolution" should be (`node16`? `nodenext`?). As such, witnessing a mode-overriding triple-slash reference in a non-modal module resolution // context should _probably_ be an error - and that should likely be handled by the `Program` (which is what we do). - if (resolutionMode === ModuleKind.ESNext && (getEmitModuleResolutionKind(options) === ModuleResolutionKind.Node16 || getEmitModuleResolutionKind(options) === ModuleResolutionKind.NodeNext)) { + if (resolutionMode === ts.ModuleKind.ESNext && (ts.getEmitModuleResolutionKind(options) === ts.ModuleResolutionKind.Node16 || ts.getEmitModuleResolutionKind(options) === ts.ModuleResolutionKind.NodeNext)) { features |= NodeResolutionFeatures.EsmMode; } const conditions = features & NodeResolutionFeatures.Exports ? features & NodeResolutionFeatures.EsmMode ? ["node", "import", "types"] : ["node", "require", "types"] : []; - const diagnostics: Diagnostic[] = []; + const diagnostics: ts.Diagnostic[] = []; const moduleResolutionState: ModuleResolutionState = { compilerOptions: options, host, @@ -376,7 +381,7 @@ namespace ts { primary = false; } - let resolvedTypeReferenceDirective: ResolvedTypeReferenceDirective | undefined; + let resolvedTypeReferenceDirective: ts.ResolvedTypeReferenceDirective | undefined; if (resolved) { const { fileName, packageId } = resolved; const resolvedFileName = options.preserveSymlinks ? fileName : realPath(fileName, host, traceEnabled); @@ -390,18 +395,19 @@ namespace ts { } result = { resolvedTypeReferenceDirective, failedLookupLocations, resolutionDiagnostics: diagnostics }; perFolderCache?.set(typeReferenceDirectiveName, /*mode*/ resolutionMode, result); - if (traceEnabled) traceResult(result); + if (traceEnabled) + traceResult(result); return result; - function traceResult(result: ResolvedTypeReferenceDirectiveWithFailedLookupLocations) { + function traceResult(result: ts.ResolvedTypeReferenceDirectiveWithFailedLookupLocations) { if (!result.resolvedTypeReferenceDirective?.resolvedFileName) { - trace(host, Diagnostics.Type_reference_directive_0_was_not_resolved, typeReferenceDirectiveName); + trace(host, ts.Diagnostics.Type_reference_directive_0_was_not_resolved, typeReferenceDirectiveName); } else if (result.resolvedTypeReferenceDirective.packageId) { - trace(host, Diagnostics.Type_reference_directive_0_was_successfully_resolved_to_1_with_Package_ID_2_primary_Colon_3, typeReferenceDirectiveName, result.resolvedTypeReferenceDirective.resolvedFileName, packageIdToString(result.resolvedTypeReferenceDirective.packageId), result.resolvedTypeReferenceDirective.primary); + trace(host, ts.Diagnostics.Type_reference_directive_0_was_successfully_resolved_to_1_with_Package_ID_2_primary_Colon_3, typeReferenceDirectiveName, result.resolvedTypeReferenceDirective.resolvedFileName, ts.packageIdToString(result.resolvedTypeReferenceDirective.packageId), result.resolvedTypeReferenceDirective.primary); } else { - trace(host, Diagnostics.Type_reference_directive_0_was_successfully_resolved_to_1_primary_Colon_2, typeReferenceDirectiveName, result.resolvedTypeReferenceDirective.resolvedFileName, result.resolvedTypeReferenceDirective.primary); + trace(host, ts.Diagnostics.Type_reference_directive_0_was_successfully_resolved_to_1_primary_Colon_2, typeReferenceDirectiveName, result.resolvedTypeReferenceDirective.resolvedFileName, result.resolvedTypeReferenceDirective.primary); } } @@ -409,37 +415,35 @@ namespace ts { // Check primary library paths if (typeRoots && typeRoots.length) { if (traceEnabled) { - trace(host, Diagnostics.Resolving_with_primary_search_path_0, typeRoots.join(", ")); + trace(host, ts.Diagnostics.Resolving_with_primary_search_path_0, typeRoots.join(", ")); } - return firstDefined(typeRoots, typeRoot => { - const candidate = combinePaths(typeRoot, typeReferenceDirectiveName); - const candidateDirectory = getDirectoryPath(candidate); - const directoryExists = directoryProbablyExists(candidateDirectory, host); + return ts.firstDefined(typeRoots, typeRoot => { + const candidate = ts.combinePaths(typeRoot, typeReferenceDirectiveName); + const candidateDirectory = ts.getDirectoryPath(candidate); + const directoryExists = ts.directoryProbablyExists(candidateDirectory, host); if (!directoryExists && traceEnabled) { - trace(host, Diagnostics.Directory_0_does_not_exist_skipping_all_lookups_in_it, candidateDirectory); + trace(host, ts.Diagnostics.Directory_0_does_not_exist_skipping_all_lookups_in_it, candidateDirectory); } - return resolvedTypeScriptOnly( - loadNodeModuleFromDirectory(Extensions.DtsOnly, candidate, - !directoryExists, moduleResolutionState)); + return resolvedTypeScriptOnly(loadNodeModuleFromDirectory(Extensions.DtsOnly, candidate, !directoryExists, moduleResolutionState)); }); } else { if (traceEnabled) { - trace(host, Diagnostics.Root_directory_cannot_be_determined_skipping_primary_search_paths); + trace(host, ts.Diagnostics.Root_directory_cannot_be_determined_skipping_primary_search_paths); } } } function secondaryLookup(): PathAndPackageId | undefined { - const initialLocationForSecondaryLookup = containingFile && getDirectoryPath(containingFile); + const initialLocationForSecondaryLookup = containingFile && ts.getDirectoryPath(containingFile); if (initialLocationForSecondaryLookup !== undefined) { // check secondary locations if (traceEnabled) { - trace(host, Diagnostics.Looking_up_in_node_modules_folder_initial_location_0, initialLocationForSecondaryLookup); + trace(host, ts.Diagnostics.Looking_up_in_node_modules_folder_initial_location_0, initialLocationForSecondaryLookup); } let result: Resolved | undefined; - if (!isExternalModuleNameRelative(typeReferenceDirectiveName)) { + if (!ts.isExternalModuleNameRelative(typeReferenceDirectiveName)) { const searchResult = loadModuleFromNearestNodeModulesDirectory(Extensions.DtsOnly, typeReferenceDirectiveName, initialLocationForSecondaryLookup, moduleResolutionState, /*cache*/ undefined, /*redirectedReference*/ undefined); result = searchResult && searchResult.value; } @@ -451,15 +455,15 @@ namespace ts { } else { if (traceEnabled) { - trace(host, Diagnostics.Containing_file_is_not_specified_and_root_directory_cannot_be_determined_skipping_lookup_in_node_modules_folder); + trace(host, ts.Diagnostics.Containing_file_is_not_specified_and_root_directory_cannot_be_determined_skipping_lookup_in_node_modules_folder); } } } } - function getDefaultNodeResolutionFeatures(options: CompilerOptions) { - return getEmitModuleResolutionKind(options) === ModuleResolutionKind.Node16 ? NodeResolutionFeatures.Node16Default : - getEmitModuleResolutionKind(options) === ModuleResolutionKind.NodeNext ? NodeResolutionFeatures.NodeNextDefault : + function getDefaultNodeResolutionFeatures(options: ts.CompilerOptions) { + return ts.getEmitModuleResolutionKind(options) === ts.ModuleResolutionKind.Node16 ? NodeResolutionFeatures.Node16Default : + ts.getEmitModuleResolutionKind(options) === ts.ModuleResolutionKind.NodeNext ? NodeResolutionFeatures.NodeNextDefault : NodeResolutionFeatures.None; } @@ -467,29 +471,23 @@ namespace ts { * @internal * Does not try `@types/${packageName}` - use a second pass if needed. */ - export function resolvePackageNameToPackageJson( - packageName: string, - containingDirectory: string, - options: CompilerOptions, - host: ModuleResolutionHost, - cache: ModuleResolutionCache | undefined, - ): PackageJsonInfo | undefined { + export function resolvePackageNameToPackageJson(packageName: string, containingDirectory: string, options: ts.CompilerOptions, host: ts.ModuleResolutionHost, cache: ModuleResolutionCache | undefined): PackageJsonInfo | undefined { const moduleResolutionState: ModuleResolutionState = { compilerOptions: options, host, traceEnabled: isTraceEnabled(options, host), failedLookupLocations: [], packageJsonInfoCache: cache?.getPackageJsonInfoCache(), - conditions: emptyArray, + conditions: ts.emptyArray, features: NodeResolutionFeatures.None, requestContainingDirectory: containingDirectory, - reportDiagnostic: noop + reportDiagnostic: ts.noop }; - return forEachAncestorDirectory(containingDirectory, ancestorDirectory => { - if (getBaseFileName(ancestorDirectory) !== "node_modules") { - const nodeModulesFolder = combinePaths(ancestorDirectory, "node_modules"); - const candidate = combinePaths(nodeModulesFolder, packageName); + return ts.forEachAncestorDirectory(containingDirectory, ancestorDirectory => { + if (ts.getBaseFileName(ancestorDirectory) !== "node_modules") { + const nodeModulesFolder = ts.combinePaths(ancestorDirectory, "node_modules"); + const candidate = ts.combinePaths(nodeModulesFolder, packageName); return getPackageJsonInfo(candidate, /*onlyRecordFailures*/ false, moduleResolutionState); } }); @@ -503,7 +501,7 @@ namespace ts { * More type directives might appear in the program later as a result of loading actual source files; * this list is only the set of defaults that are implicitly included. */ - export function getAutomaticTypeDirectiveNames(options: CompilerOptions, host: ModuleResolutionHost): string[] { + export function getAutomaticTypeDirectiveNames(options: ts.CompilerOptions, host: ts.ModuleResolutionHost): string[] { // Use explicit type list from tsconfig.json if (options.types) { return options.types; @@ -517,17 +515,17 @@ namespace ts { for (const root of typeRoots) { if (host.directoryExists(root)) { for (const typeDirectivePath of host.getDirectories(root)) { - const normalized = normalizePath(typeDirectivePath); - const packageJsonPath = combinePaths(root, normalized, "package.json"); + const normalized = ts.normalizePath(typeDirectivePath); + const packageJsonPath = ts.combinePaths(root, normalized, "package.json"); // `types-publisher` sometimes creates packages with `"typings": null` for packages that don't provide their own types. // See `createNotNeededPackageJSON` in the types-publisher` repo. // eslint-disable-next-line no-null/no-null - const isNotNeededPackage = host.fileExists(packageJsonPath) && (readJson(packageJsonPath, host) as PackageJson).typings === null; + const isNotNeededPackage = host.fileExists(packageJsonPath) && (ts.readJson(packageJsonPath, host) as PackageJson).typings === null; if (!isNotNeededPackage) { - const baseFileName = getBaseFileName(normalized); + const baseFileName = ts.getBaseFileName(normalized); // At this stage, skip results with leading dot. - if (baseFileName.charCodeAt(0) !== CharacterCodes.dot) { + if (baseFileName.charCodeAt(0) !== ts.CharacterCodes.dot) { // Return just the type directive names result.push(baseFileName); } @@ -540,15 +538,15 @@ namespace ts { return result; } - export interface TypeReferenceDirectiveResolutionCache extends PerDirectoryResolutionCache, PackageJsonInfoCache { + export interface TypeReferenceDirectiveResolutionCache extends PerDirectoryResolutionCache, PackageJsonInfoCache { } export interface ModeAwareCache { - get(key: string, mode: ModuleKind.CommonJS | ModuleKind.ESNext | undefined): T | undefined; - set(key: string, mode: ModuleKind.CommonJS | ModuleKind.ESNext | undefined, value: T): this; - delete(key: string, mode: ModuleKind.CommonJS | ModuleKind.ESNext | undefined): this; - has(key: string, mode: ModuleKind.CommonJS | ModuleKind.ESNext | undefined): boolean; - forEach(cb: (elem: T, key: string, mode: ModuleKind.CommonJS | ModuleKind.ESNext | undefined) => void): void; + get(key: string, mode: ts.ModuleKind.CommonJS | ts.ModuleKind.ESNext | undefined): T | undefined; + set(key: string, mode: ts.ModuleKind.CommonJS | ts.ModuleKind.ESNext | undefined, value: T): this; + delete(key: string, mode: ts.ModuleKind.CommonJS | ts.ModuleKind.ESNext | undefined): this; + has(key: string, mode: ts.ModuleKind.CommonJS | ts.ModuleKind.ESNext | undefined): boolean; + forEach(cb: (elem: T, key: string, mode: ts.ModuleKind.CommonJS | ts.ModuleKind.ESNext | undefined) => void): void; size(): number; } @@ -557,16 +555,16 @@ namespace ts { * This assumes that any module id will have the same resolution for sibling files located in the same folder. */ export interface PerDirectoryResolutionCache { - getOrCreateCacheForDirectory(directoryName: string, redirectedReference?: ResolvedProjectReference): ModeAwareCache; + getOrCreateCacheForDirectory(directoryName: string, redirectedReference?: ts.ResolvedProjectReference): ModeAwareCache; clear(): void; /** * Updates with the current compilerOptions the cache will operate with. * This updates the redirects map as well if needed so module resolutions are cached if they can across the projects */ - update(options: CompilerOptions): void; + update(options: ts.CompilerOptions): void; } - export interface ModuleResolutionCache extends PerDirectoryResolutionCache, NonRelativeModuleNameResolutionCache, PackageJsonInfoCache { + export interface ModuleResolutionCache extends PerDirectoryResolutionCache, NonRelativeModuleNameResolutionCache, PackageJsonInfoCache { getPackageJsonInfoCache(): PackageJsonInfoCache; } @@ -575,35 +573,38 @@ namespace ts { * We support only non-relative module names because resolution of relative module names is usually more deterministic and thus less expensive. */ export interface NonRelativeModuleNameResolutionCache extends PackageJsonInfoCache { - getOrCreateCacheForModuleName(nonRelativeModuleName: string, mode: ModuleKind.CommonJS | ModuleKind.ESNext | undefined, redirectedReference?: ResolvedProjectReference): PerModuleNameCache; + getOrCreateCacheForModuleName(nonRelativeModuleName: string, mode: ts.ModuleKind.CommonJS | ts.ModuleKind.ESNext | undefined, redirectedReference?: ts.ResolvedProjectReference): PerModuleNameCache; } export interface PackageJsonInfoCache { /*@internal*/ getPackageJsonInfo(packageJsonPath: string): PackageJsonInfo | boolean | undefined; /*@internal*/ setPackageJsonInfo(packageJsonPath: string, info: PackageJsonInfo | boolean): void; - /*@internal*/ entries(): [Path, PackageJsonInfo | boolean][]; + /*@internal*/ entries(): [ + ts.Path, + PackageJsonInfo | boolean + ][]; clear(): void; } export interface PerModuleNameCache { - get(directory: string): ResolvedModuleWithFailedLookupLocations | undefined; - set(directory: string, result: ResolvedModuleWithFailedLookupLocations): void; + get(directory: string): ts.ResolvedModuleWithFailedLookupLocations | undefined; + set(directory: string, result: ts.ResolvedModuleWithFailedLookupLocations): void; } /*@internal*/ export interface CacheWithRedirects { - getOwnMap: () => ESMap; - redirectsMap: ESMap>; - getOrCreateMapOfCacheRedirects(redirectedReference: ResolvedProjectReference | undefined): ESMap; + getOwnMap: () => ts.ESMap; + redirectsMap: ts.ESMap>; + getOrCreateMapOfCacheRedirects(redirectedReference: ts.ResolvedProjectReference | undefined): ts.ESMap; clear(): void; - setOwnOptions(newOptions: CompilerOptions): void; - setOwnMap(newOwnMap: ESMap): void; + setOwnOptions(newOptions: ts.CompilerOptions): void; + setOwnMap(newOwnMap: ts.ESMap): void; } /*@internal*/ - export function createCacheWithRedirects(options?: CompilerOptions): CacheWithRedirects { - let ownMap: ESMap = new Map(); - const redirectsMap = new Map>(); + export function createCacheWithRedirects(options?: ts.CompilerOptions): CacheWithRedirects { + let ownMap: ts.ESMap = new ts.Map(); + const redirectsMap = new ts.Map>(); return { getOwnMap, redirectsMap, @@ -617,15 +618,15 @@ namespace ts { return ownMap; } - function setOwnOptions(newOptions: CompilerOptions) { + function setOwnOptions(newOptions: ts.CompilerOptions) { options = newOptions; } - function setOwnMap(newOwnMap: ESMap) { + function setOwnMap(newOwnMap: ts.ESMap) { ownMap = newOwnMap; } - function getOrCreateMapOfCacheRedirects(redirectedReference: ResolvedProjectReference | undefined) { + function getOrCreateMapOfCacheRedirects(redirectedReference: ts.ResolvedProjectReference | undefined) { if (!redirectedReference) { return ownMap; } @@ -633,7 +634,7 @@ namespace ts { let redirects = redirectsMap.get(path); if (!redirects) { // Reuse map if redirected reference map uses same resolution - redirects = !options || optionsHaveModuleResolutionChanges(options, redirectedReference.commandLine.options) ? new Map() : ownMap; + redirects = !options || ts.optionsHaveModuleResolutionChanges(options, redirectedReference.commandLine.options) ? new ts.Map() : ownMap; redirectsMap.set(path, redirects); } return redirects; @@ -646,24 +647,24 @@ namespace ts { } function createPackageJsonInfoCache(currentDirectory: string, getCanonicalFileName: (s: string) => string): PackageJsonInfoCache { - let cache: ESMap | undefined; + let cache: ts.ESMap | undefined; return { getPackageJsonInfo, setPackageJsonInfo, clear, entries }; function getPackageJsonInfo(packageJsonPath: string) { - return cache?.get(toPath(packageJsonPath, currentDirectory, getCanonicalFileName)); + return cache?.get(ts.toPath(packageJsonPath, currentDirectory, getCanonicalFileName)); } function setPackageJsonInfo(packageJsonPath: string, info: PackageJsonInfo | boolean) { - (cache ||= new Map()).set(toPath(packageJsonPath, currentDirectory, getCanonicalFileName), info); + (cache ||= new ts.Map()).set(ts.toPath(packageJsonPath, currentDirectory, getCanonicalFileName), info); } function clear() { cache = undefined; } function entries() { const iter = cache?.entries(); - return iter ? arrayFrom(iter) : []; + return iter ? ts.arrayFrom(iter) : []; } } - function getOrCreateCache(cacheWithRedirects: CacheWithRedirects, redirectedReference: ResolvedProjectReference | undefined, key: string, create: () => T): T { + function getOrCreateCache(cacheWithRedirects: CacheWithRedirects, redirectedReference: ts.ResolvedProjectReference | undefined, key: string, create: () => T): T { const cache = cacheWithRedirects.getOrCreateMapOfCacheRedirects(redirectedReference); let result = cache.get(key); if (!result) { @@ -673,26 +674,23 @@ namespace ts { return result; } - function updateRedirectsMap( - options: CompilerOptions, - directoryToModuleNameMap: CacheWithRedirects>, - moduleNameToDirectoryMap?: CacheWithRedirects - ) { - if (!options.configFile) return; + function updateRedirectsMap(options: ts.CompilerOptions, directoryToModuleNameMap: CacheWithRedirects>, moduleNameToDirectoryMap?: CacheWithRedirects) { + if (!options.configFile) + return; if (directoryToModuleNameMap.redirectsMap.size === 0) { // The own map will be for projectCompilerOptions - Debug.assert(!moduleNameToDirectoryMap || moduleNameToDirectoryMap.redirectsMap.size === 0); - Debug.assert(directoryToModuleNameMap.getOwnMap().size === 0); - Debug.assert(!moduleNameToDirectoryMap || moduleNameToDirectoryMap.getOwnMap().size === 0); + ts.Debug.assert(!moduleNameToDirectoryMap || moduleNameToDirectoryMap.redirectsMap.size === 0); + ts.Debug.assert(directoryToModuleNameMap.getOwnMap().size === 0); + ts.Debug.assert(!moduleNameToDirectoryMap || moduleNameToDirectoryMap.getOwnMap().size === 0); directoryToModuleNameMap.redirectsMap.set(options.configFile.path, directoryToModuleNameMap.getOwnMap()); moduleNameToDirectoryMap?.redirectsMap.set(options.configFile.path, moduleNameToDirectoryMap.getOwnMap()); } else { // Set correct own map - Debug.assert(!moduleNameToDirectoryMap || moduleNameToDirectoryMap.redirectsMap.size > 0); - const ref: ResolvedProjectReference = { + ts.Debug.assert(!moduleNameToDirectoryMap || moduleNameToDirectoryMap.redirectsMap.size > 0); + const ref: ts.ResolvedProjectReference = { sourceFile: options.configFile, - commandLine: { options } as ParsedCommandLine + commandLine: { options } as ts.ParsedCommandLine }; directoryToModuleNameMap.setOwnMap(directoryToModuleNameMap.getOrCreateMapOfCacheRedirects(ref)); moduleNameToDirectoryMap?.setOwnMap(moduleNameToDirectoryMap.getOrCreateMapOfCacheRedirects(ref)); @@ -701,7 +699,7 @@ namespace ts { moduleNameToDirectoryMap?.setOwnOptions(options); } - function createPerDirectoryResolutionCache(currentDirectory: string, getCanonicalFileName: GetCanonicalFileName, directoryToModuleNameMap: CacheWithRedirects>): PerDirectoryResolutionCache { + function createPerDirectoryResolutionCache(currentDirectory: string, getCanonicalFileName: ts.GetCanonicalFileName, directoryToModuleNameMap: CacheWithRedirects>): PerDirectoryResolutionCache { return { getOrCreateCacheForDirectory, clear, @@ -712,20 +710,23 @@ namespace ts { directoryToModuleNameMap.clear(); } - function update(options: CompilerOptions) { + function update(options: ts.CompilerOptions) { updateRedirectsMap(options, directoryToModuleNameMap); } - function getOrCreateCacheForDirectory(directoryName: string, redirectedReference?: ResolvedProjectReference) { - const path = toPath(directoryName, currentDirectory, getCanonicalFileName); + function getOrCreateCacheForDirectory(directoryName: string, redirectedReference?: ts.ResolvedProjectReference) { + const path = ts.toPath(directoryName, currentDirectory, getCanonicalFileName); return getOrCreateCache>(directoryToModuleNameMap, redirectedReference, path, () => createModeAwareCache()); } } /* @internal */ export function createModeAwareCache(): ModeAwareCache { - const underlying = new Map(); - const memoizedReverseKeys = new Map(); + const underlying = new ts.Map(); + const memoizedReverseKeys = new ts.Map(); const cache: ModeAwareCache = { get(specifier, mode) { @@ -754,7 +755,7 @@ namespace ts { }; return cache; - function getUnderlyingCacheKey(specifier: string, mode: ModuleKind.CommonJS | ModuleKind.ESNext | undefined) { + function getUnderlyingCacheKey(specifier: string, mode: ts.ModuleKind.CommonJS | ts.ModuleKind.ESNext | undefined) { const result = mode === undefined ? specifier : `${mode}|${specifier}`; memoizedReverseKeys.set(result, [specifier, mode]); return result; @@ -762,39 +763,23 @@ namespace ts { } /* @internal */ - export function zipToModeAwareCache(file: SourceFile, keys: readonly string[] | readonly FileReference[], values: readonly V[]): ModeAwareCache { - Debug.assert(keys.length === values.length); + export function zipToModeAwareCache(file: ts.SourceFile, keys: readonly string[] | readonly ts.FileReference[], values: readonly V[]): ModeAwareCache { + ts.Debug.assert(keys.length === values.length); const map = createModeAwareCache(); for (let i = 0; i < keys.length; ++i) { const entry = keys[i]; // We lower-case all type references because npm automatically lowercases all packages. See GH#9824. - const name = !isString(entry) ? entry.fileName.toLowerCase() : entry; - const mode = !isString(entry) ? entry.resolutionMode || file.impliedNodeFormat : getModeForResolutionAtIndex(file, i); + const name = !ts.isString(entry) ? entry.fileName.toLowerCase() : entry; + const mode = !ts.isString(entry) ? entry.resolutionMode || file.impliedNodeFormat : ts.getModeForResolutionAtIndex(file, i); map.set(name, mode, values[i]); } return map; } - export function createModuleResolutionCache( - currentDirectory: string, - getCanonicalFileName: (s: string) => string, - options?: CompilerOptions - ): ModuleResolutionCache; + export function createModuleResolutionCache(currentDirectory: string, getCanonicalFileName: (s: string) => string, options?: ts.CompilerOptions): ModuleResolutionCache; /*@internal*/ - export function createModuleResolutionCache( - currentDirectory: string, - getCanonicalFileName: GetCanonicalFileName, - options: undefined, - directoryToModuleNameMap: CacheWithRedirects>, - moduleNameToDirectoryMap: CacheWithRedirects, - ): ModuleResolutionCache; - export function createModuleResolutionCache( - currentDirectory: string, - getCanonicalFileName: GetCanonicalFileName, - options?: CompilerOptions, - directoryToModuleNameMap?: CacheWithRedirects>, - moduleNameToDirectoryMap?: CacheWithRedirects, - ): ModuleResolutionCache { + export function createModuleResolutionCache(currentDirectory: string, getCanonicalFileName: ts.GetCanonicalFileName, options: undefined, directoryToModuleNameMap: CacheWithRedirects>, moduleNameToDirectoryMap: CacheWithRedirects): ModuleResolutionCache; + export function createModuleResolutionCache(currentDirectory: string, getCanonicalFileName: ts.GetCanonicalFileName, options?: ts.CompilerOptions, directoryToModuleNameMap?: CacheWithRedirects>, moduleNameToDirectoryMap?: CacheWithRedirects): ModuleResolutionCache { const preDirectoryResolutionCache = createPerDirectoryResolutionCache(currentDirectory, getCanonicalFileName, directoryToModuleNameMap ||= createCacheWithRedirects(options)); moduleNameToDirectoryMap ||= createCacheWithRedirects(options); const packageJsonInfoCache = createPackageJsonInfoCache(currentDirectory, getCanonicalFileName); @@ -814,22 +799,22 @@ namespace ts { packageJsonInfoCache.clear(); } - function update(options: CompilerOptions) { + function update(options: ts.CompilerOptions) { updateRedirectsMap(options, directoryToModuleNameMap!, moduleNameToDirectoryMap); } - function getOrCreateCacheForModuleName(nonRelativeModuleName: string, mode: ModuleKind.CommonJS | ModuleKind.ESNext | undefined, redirectedReference?: ResolvedProjectReference): PerModuleNameCache { - Debug.assert(!isExternalModuleNameRelative(nonRelativeModuleName)); + function getOrCreateCacheForModuleName(nonRelativeModuleName: string, mode: ts.ModuleKind.CommonJS | ts.ModuleKind.ESNext | undefined, redirectedReference?: ts.ResolvedProjectReference): PerModuleNameCache { + ts.Debug.assert(!ts.isExternalModuleNameRelative(nonRelativeModuleName)); return getOrCreateCache(moduleNameToDirectoryMap!, redirectedReference, mode === undefined ? nonRelativeModuleName : `${mode}|${nonRelativeModuleName}`, createPerModuleNameCache); } function createPerModuleNameCache(): PerModuleNameCache { - const directoryPathMap = new Map(); + const directoryPathMap = new ts.Map(); return { get, set }; - function get(directory: string): ResolvedModuleWithFailedLookupLocations | undefined { - return directoryPathMap.get(toPath(directory, currentDirectory, getCanonicalFileName)); + function get(directory: string): ts.ResolvedModuleWithFailedLookupLocations | undefined { + return directoryPathMap.get(ts.toPath(directory, currentDirectory, getCanonicalFileName)); } /** @@ -843,8 +828,8 @@ namespace ts { * ] * this means that request for module resolution from file in any of these folder will be immediately found in cache. */ - function set(directory: string, result: ResolvedModuleWithFailedLookupLocations): void { - const path = toPath(directory, currentDirectory, getCanonicalFileName); + function set(directory: string, result: ts.ResolvedModuleWithFailedLookupLocations): void { + const path = ts.toPath(directory, currentDirectory, getCanonicalFileName); // if entry is already in cache do nothing if (directoryPathMap.has(path)) { return; @@ -862,7 +847,7 @@ namespace ts { const commonPrefix = resolvedFileName && getCommonPrefix(path, resolvedFileName); let current = path; while (current !== commonPrefix) { - const parent = getDirectoryPath(current); + const parent = ts.getDirectoryPath(current); if (parent === current || directoryPathMap.has(parent)) { break; } @@ -871,8 +856,8 @@ namespace ts { } } - function getCommonPrefix(directory: Path, resolution: string) { - const resolutionDirectory = toPath(getDirectoryPath(resolution), currentDirectory, getCanonicalFileName); + function getCommonPrefix(directory: ts.Path, resolution: string) { + const resolutionDirectory = ts.toPath(ts.getDirectoryPath(resolution), currentDirectory, getCanonicalFileName); // find first position where directory and resolution differs let i = 0; @@ -880,14 +865,14 @@ namespace ts { while (i < limit && directory.charCodeAt(i) === resolutionDirectory.charCodeAt(i)) { i++; } - if (i === directory.length && (resolutionDirectory.length === i || resolutionDirectory[i] === directorySeparator)) { + if (i === directory.length && (resolutionDirectory.length === i || resolutionDirectory[i] === ts.directorySeparator)) { return directory; } - const rootLength = getRootLength(directory); + const rootLength = ts.getRootLength(directory); if (i < rootLength) { return undefined; } - const sep = directory.lastIndexOf(directorySeparator, i - 1); + const sep = directory.lastIndexOf(ts.directorySeparator, i - 1); if (sep === -1) { return undefined; } @@ -896,27 +881,10 @@ namespace ts { } } - export function createTypeReferenceDirectiveResolutionCache( - currentDirectory: string, - getCanonicalFileName: (s: string) => string, - options?: CompilerOptions, - packageJsonInfoCache?: PackageJsonInfoCache, - ): TypeReferenceDirectiveResolutionCache; + export function createTypeReferenceDirectiveResolutionCache(currentDirectory: string, getCanonicalFileName: (s: string) => string, options?: ts.CompilerOptions, packageJsonInfoCache?: PackageJsonInfoCache): TypeReferenceDirectiveResolutionCache; /*@internal*/ - export function createTypeReferenceDirectiveResolutionCache( - currentDirectory: string, - getCanonicalFileName: GetCanonicalFileName, - options: undefined, - packageJsonInfoCache: PackageJsonInfoCache | undefined, - directoryToModuleNameMap: CacheWithRedirects>, - ): TypeReferenceDirectiveResolutionCache; - export function createTypeReferenceDirectiveResolutionCache( - currentDirectory: string, - getCanonicalFileName: GetCanonicalFileName, - options?: CompilerOptions, - packageJsonInfoCache?: PackageJsonInfoCache | undefined, - directoryToModuleNameMap?: CacheWithRedirects>, - ): TypeReferenceDirectiveResolutionCache { + export function createTypeReferenceDirectiveResolutionCache(currentDirectory: string, getCanonicalFileName: ts.GetCanonicalFileName, options: undefined, packageJsonInfoCache: PackageJsonInfoCache | undefined, directoryToModuleNameMap: CacheWithRedirects>): TypeReferenceDirectiveResolutionCache; + export function createTypeReferenceDirectiveResolutionCache(currentDirectory: string, getCanonicalFileName: ts.GetCanonicalFileName, options?: ts.CompilerOptions, packageJsonInfoCache?: PackageJsonInfoCache | undefined, directoryToModuleNameMap?: CacheWithRedirects>): TypeReferenceDirectiveResolutionCache { const preDirectoryResolutionCache = createPerDirectoryResolutionCache(currentDirectory, getCanonicalFileName, directoryToModuleNameMap ||= createCacheWithRedirects(options)); packageJsonInfoCache ||= createPackageJsonInfoCache(currentDirectory, getCanonicalFileName); @@ -932,83 +900,85 @@ namespace ts { } } - export function resolveModuleNameFromCache(moduleName: string, containingFile: string, cache: ModuleResolutionCache, mode?: ModuleKind.CommonJS | ModuleKind.ESNext): ResolvedModuleWithFailedLookupLocations | undefined { - const containingDirectory = getDirectoryPath(containingFile); + export function resolveModuleNameFromCache(moduleName: string, containingFile: string, cache: ModuleResolutionCache, mode?: ts.ModuleKind.CommonJS | ts.ModuleKind.ESNext): ts.ResolvedModuleWithFailedLookupLocations | undefined { + const containingDirectory = ts.getDirectoryPath(containingFile); const perFolderCache = cache && cache.getOrCreateCacheForDirectory(containingDirectory); - if (!perFolderCache) return undefined; + if (!perFolderCache) + return undefined; return perFolderCache.get(moduleName, mode); } - export function resolveModuleName(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost, cache?: ModuleResolutionCache, redirectedReference?: ResolvedProjectReference, resolutionMode?: ModuleKind.CommonJS | ModuleKind.ESNext): ResolvedModuleWithFailedLookupLocations { + export function resolveModuleName(moduleName: string, containingFile: string, compilerOptions: ts.CompilerOptions, host: ts.ModuleResolutionHost, cache?: ModuleResolutionCache, redirectedReference?: ts.ResolvedProjectReference, resolutionMode?: ts.ModuleKind.CommonJS | ts.ModuleKind.ESNext): ts.ResolvedModuleWithFailedLookupLocations { const traceEnabled = isTraceEnabled(compilerOptions, host); if (redirectedReference) { compilerOptions = redirectedReference.commandLine.options; } if (traceEnabled) { - trace(host, Diagnostics.Resolving_module_0_from_1, moduleName, containingFile); + trace(host, ts.Diagnostics.Resolving_module_0_from_1, moduleName, containingFile); if (redirectedReference) { - trace(host, Diagnostics.Using_compiler_options_of_project_reference_redirect_0, redirectedReference.sourceFile.fileName); + trace(host, ts.Diagnostics.Using_compiler_options_of_project_reference_redirect_0, redirectedReference.sourceFile.fileName); } } - const containingDirectory = getDirectoryPath(containingFile); + const containingDirectory = ts.getDirectoryPath(containingFile); const perFolderCache = cache && cache.getOrCreateCacheForDirectory(containingDirectory, redirectedReference); let result = perFolderCache && perFolderCache.get(moduleName, resolutionMode); if (result) { if (traceEnabled) { - trace(host, Diagnostics.Resolution_for_module_0_was_found_in_cache_from_location_1, moduleName, containingDirectory); + trace(host, ts.Diagnostics.Resolution_for_module_0_was_found_in_cache_from_location_1, moduleName, containingDirectory); } } else { let moduleResolution = compilerOptions.moduleResolution; if (moduleResolution === undefined) { - switch (getEmitModuleKind(compilerOptions)) { - case ModuleKind.CommonJS: - moduleResolution = ModuleResolutionKind.NodeJs; + switch (ts.getEmitModuleKind(compilerOptions)) { + case ts.ModuleKind.CommonJS: + moduleResolution = ts.ModuleResolutionKind.NodeJs; break; - case ModuleKind.Node16: - moduleResolution = ModuleResolutionKind.Node16; + case ts.ModuleKind.Node16: + moduleResolution = ts.ModuleResolutionKind.Node16; break; - case ModuleKind.NodeNext: - moduleResolution = ModuleResolutionKind.NodeNext; + case ts.ModuleKind.NodeNext: + moduleResolution = ts.ModuleResolutionKind.NodeNext; break; default: - moduleResolution = ModuleResolutionKind.Classic; + moduleResolution = ts.ModuleResolutionKind.Classic; break; } if (traceEnabled) { - trace(host, Diagnostics.Module_resolution_kind_is_not_specified_using_0, ModuleResolutionKind[moduleResolution]); + trace(host, ts.Diagnostics.Module_resolution_kind_is_not_specified_using_0, ts.ModuleResolutionKind[moduleResolution]); } } else { if (traceEnabled) { - trace(host, Diagnostics.Explicitly_specified_module_resolution_kind_Colon_0, ModuleResolutionKind[moduleResolution]); + trace(host, ts.Diagnostics.Explicitly_specified_module_resolution_kind_Colon_0, ts.ModuleResolutionKind[moduleResolution]); } } - perfLogger.logStartResolveModule(moduleName /* , containingFile, ModuleResolutionKind[moduleResolution]*/); + ts.perfLogger.logStartResolveModule(moduleName /* , containingFile, ModuleResolutionKind[moduleResolution]*/); switch (moduleResolution) { - case ModuleResolutionKind.Node16: + case ts.ModuleResolutionKind.Node16: result = node16ModuleNameResolver(moduleName, containingFile, compilerOptions, host, cache, redirectedReference, resolutionMode); break; - case ModuleResolutionKind.NodeNext: + case ts.ModuleResolutionKind.NodeNext: result = nodeNextModuleNameResolver(moduleName, containingFile, compilerOptions, host, cache, redirectedReference, resolutionMode); break; - case ModuleResolutionKind.NodeJs: + case ts.ModuleResolutionKind.NodeJs: result = nodeModuleNameResolver(moduleName, containingFile, compilerOptions, host, cache, redirectedReference); break; - case ModuleResolutionKind.Classic: + case ts.ModuleResolutionKind.Classic: result = classicNameResolver(moduleName, containingFile, compilerOptions, host, cache, redirectedReference); break; default: - return Debug.fail(`Unexpected moduleResolution: ${moduleResolution}`); + return ts.Debug.fail(`Unexpected moduleResolution: ${moduleResolution}`); } - if (result && result.resolvedModule) perfLogger.logInfoEvent(`Module "${moduleName}" resolved to "${result.resolvedModule.resolvedFileName}"`); - perfLogger.logStopResolveModule((result && result.resolvedModule) ? "" + result.resolvedModule.resolvedFileName : "null"); + if (result && result.resolvedModule) + ts.perfLogger.logInfoEvent(`Module "${moduleName}" resolved to "${result.resolvedModule.resolvedFileName}"`); + ts.perfLogger.logStopResolveModule((result && result.resolvedModule) ? "" + result.resolvedModule.resolvedFileName : "null"); if (perFolderCache) { perFolderCache.set(moduleName, resolutionMode, result); - if (!isExternalModuleNameRelative(moduleName)) { + if (!ts.isExternalModuleNameRelative(moduleName)) { // put result in per-module name cache cache.getOrCreateCacheForModuleName(moduleName, resolutionMode, redirectedReference).set(containingDirectory, result); } @@ -1018,14 +988,14 @@ namespace ts { if (traceEnabled) { if (result.resolvedModule) { if (result.resolvedModule.packageId) { - trace(host, Diagnostics.Module_name_0_was_successfully_resolved_to_1_with_Package_ID_2, moduleName, result.resolvedModule.resolvedFileName, packageIdToString(result.resolvedModule.packageId)); + trace(host, ts.Diagnostics.Module_name_0_was_successfully_resolved_to_1_with_Package_ID_2, moduleName, result.resolvedModule.resolvedFileName, ts.packageIdToString(result.resolvedModule.packageId)); } else { - trace(host, Diagnostics.Module_name_0_was_successfully_resolved_to_1, moduleName, result.resolvedModule.resolvedFileName); + trace(host, ts.Diagnostics.Module_name_0_was_successfully_resolved_to_1, moduleName, result.resolvedModule.resolvedFileName); } } else { - trace(host, Diagnostics.Module_name_0_was_not_resolved, moduleName); + trace(host, ts.Diagnostics.Module_name_0_was_not_resolved, moduleName); } } @@ -1102,13 +1072,12 @@ namespace ts { * be converted to a path relative to found rootDir entry './content/protocols/file2' (*). As a last step compiler will check all remaining * entries in 'rootDirs', use them to build absolute path out of (*) and try to resolve module from this location. */ - function tryLoadModuleUsingOptionalResolutionSettings(extensions: Extensions, moduleName: string, containingDirectory: string, loader: ResolutionKindSpecificLoader, - state: ModuleResolutionState): Resolved | undefined { + function tryLoadModuleUsingOptionalResolutionSettings(extensions: Extensions, moduleName: string, containingDirectory: string, loader: ResolutionKindSpecificLoader, state: ModuleResolutionState): Resolved | undefined { const resolved = tryLoadModuleUsingPathsIfEligible(extensions, moduleName, loader, state); - if (resolved) return resolved.value; - - if (!isExternalModuleNameRelative(moduleName)) { + if (resolved) + return resolved.value; + if (!ts.isExternalModuleNameRelative(moduleName)) { return tryLoadModuleUsingBaseUrl(extensions, moduleName, loader, state); } else { @@ -1118,31 +1087,30 @@ namespace ts { function tryLoadModuleUsingPathsIfEligible(extensions: Extensions, moduleName: string, loader: ResolutionKindSpecificLoader, state: ModuleResolutionState) { const { baseUrl, paths, configFile } = state.compilerOptions; - if (paths && !pathIsRelative(moduleName)) { + if (paths && !ts.pathIsRelative(moduleName)) { if (state.traceEnabled) { if (baseUrl) { - trace(state.host, Diagnostics.baseUrl_option_is_set_to_0_using_this_value_to_resolve_non_relative_module_name_1, baseUrl, moduleName); + trace(state.host, ts.Diagnostics.baseUrl_option_is_set_to_0_using_this_value_to_resolve_non_relative_module_name_1, baseUrl, moduleName); } - trace(state.host, Diagnostics.paths_option_is_specified_looking_for_a_pattern_to_match_module_name_0, moduleName); + trace(state.host, ts.Diagnostics.paths_option_is_specified_looking_for_a_pattern_to_match_module_name_0, moduleName); } - const baseDirectory = getPathsBasePath(state.compilerOptions, state.host)!; // Always defined when 'paths' is defined - const pathPatterns = configFile?.configFileSpecs ? configFile.configFileSpecs.pathPatterns ||= tryParsePatterns(paths) : undefined; + const baseDirectory = ts.getPathsBasePath(state.compilerOptions, state.host)!; // Always defined when 'paths' is defined + const pathPatterns = configFile?.configFileSpecs ? configFile.configFileSpecs.pathPatterns ||= ts.tryParsePatterns(paths) : undefined; return tryLoadModuleUsingPaths(extensions, moduleName, baseDirectory, paths, pathPatterns, loader, /*onlyRecordFailures*/ false, state); } } - function tryLoadModuleUsingRootDirs(extensions: Extensions, moduleName: string, containingDirectory: string, loader: ResolutionKindSpecificLoader, - state: ModuleResolutionState): Resolved | undefined { + function tryLoadModuleUsingRootDirs(extensions: Extensions, moduleName: string, containingDirectory: string, loader: ResolutionKindSpecificLoader, state: ModuleResolutionState): Resolved | undefined { if (!state.compilerOptions.rootDirs) { return undefined; } if (state.traceEnabled) { - trace(state.host, Diagnostics.rootDirs_option_is_set_using_it_to_resolve_relative_module_name_0, moduleName); + trace(state.host, ts.Diagnostics.rootDirs_option_is_set_using_it_to_resolve_relative_module_name_0, moduleName); } - const candidate = normalizePath(combinePaths(containingDirectory, moduleName)); + const candidate = ts.normalizePath(ts.combinePaths(containingDirectory, moduleName)); let matchedRootDir: string | undefined; let matchedNormalizedPrefix: string | undefined; @@ -1150,16 +1118,15 @@ namespace ts { // rootDirs are expected to be absolute // in case of tsconfig.json this will happen automatically - compiler will expand relative names // using location of tsconfig.json as base location - let normalizedRoot = normalizePath(rootDir); - if (!endsWith(normalizedRoot, directorySeparator)) { - normalizedRoot += directorySeparator; + let normalizedRoot = ts.normalizePath(rootDir); + if (!ts.endsWith(normalizedRoot, ts.directorySeparator)) { + normalizedRoot += ts.directorySeparator; } - const isLongestMatchingPrefix = - startsWith(candidate, normalizedRoot) && + const isLongestMatchingPrefix = ts.startsWith(candidate, normalizedRoot) && (matchedNormalizedPrefix === undefined || matchedNormalizedPrefix.length < normalizedRoot.length); if (state.traceEnabled) { - trace(state.host, Diagnostics.Checking_if_0_is_the_longest_matching_prefix_for_1_2, normalizedRoot, candidate, isLongestMatchingPrefix); + trace(state.host, ts.Diagnostics.Checking_if_0_is_the_longest_matching_prefix_for_1_2, normalizedRoot, candidate, isLongestMatchingPrefix); } if (isLongestMatchingPrefix) { @@ -1169,21 +1136,21 @@ namespace ts { } if (matchedNormalizedPrefix) { if (state.traceEnabled) { - trace(state.host, Diagnostics.Longest_matching_prefix_for_0_is_1, candidate, matchedNormalizedPrefix); + trace(state.host, ts.Diagnostics.Longest_matching_prefix_for_0_is_1, candidate, matchedNormalizedPrefix); } const suffix = candidate.substr(matchedNormalizedPrefix.length); // first - try to load from a initial location if (state.traceEnabled) { - trace(state.host, Diagnostics.Loading_0_from_the_root_dir_1_candidate_location_2, suffix, matchedNormalizedPrefix, candidate); + trace(state.host, ts.Diagnostics.Loading_0_from_the_root_dir_1_candidate_location_2, suffix, matchedNormalizedPrefix, candidate); } - const resolvedFileName = loader(extensions, candidate, !directoryProbablyExists(containingDirectory, state.host), state); + const resolvedFileName = loader(extensions, candidate, !ts.directoryProbablyExists(containingDirectory, state.host), state); if (resolvedFileName) { return resolvedFileName; } if (state.traceEnabled) { - trace(state.host, Diagnostics.Trying_other_entries_in_rootDirs); + trace(state.host, ts.Diagnostics.Trying_other_entries_in_rootDirs); } // then try to resolve using remaining entries in rootDirs for (const rootDir of state.compilerOptions.rootDirs) { @@ -1191,18 +1158,18 @@ namespace ts { // skip the initially matched entry continue; } - const candidate = combinePaths(normalizePath(rootDir), suffix); + const candidate = ts.combinePaths(ts.normalizePath(rootDir), suffix); if (state.traceEnabled) { - trace(state.host, Diagnostics.Loading_0_from_the_root_dir_1_candidate_location_2, suffix, rootDir, candidate); + trace(state.host, ts.Diagnostics.Loading_0_from_the_root_dir_1_candidate_location_2, suffix, rootDir, candidate); } - const baseDirectory = getDirectoryPath(candidate); - const resolvedFileName = loader(extensions, candidate, !directoryProbablyExists(baseDirectory, state.host), state); + const baseDirectory = ts.getDirectoryPath(candidate); + const resolvedFileName = loader(extensions, candidate, !ts.directoryProbablyExists(baseDirectory, state.host), state); if (resolvedFileName) { return resolvedFileName; } } if (state.traceEnabled) { - trace(state.host, Diagnostics.Module_resolution_using_rootDirs_has_failed); + trace(state.host, ts.Diagnostics.Module_resolution_using_rootDirs_has_failed); } } return undefined; @@ -1214,13 +1181,13 @@ namespace ts { return undefined; } if (state.traceEnabled) { - trace(state.host, Diagnostics.baseUrl_option_is_set_to_0_using_this_value_to_resolve_non_relative_module_name_1, baseUrl, moduleName); + trace(state.host, ts.Diagnostics.baseUrl_option_is_set_to_0_using_this_value_to_resolve_non_relative_module_name_1, baseUrl, moduleName); } - const candidate = normalizePath(combinePaths(baseUrl, moduleName)); + const candidate = ts.normalizePath(ts.combinePaths(baseUrl, moduleName)); if (state.traceEnabled) { - trace(state.host, Diagnostics.Resolving_module_name_0_relative_to_base_url_1_2, moduleName, baseUrl, candidate); + trace(state.host, ts.Diagnostics.Resolving_module_name_0_relative_to_base_url_1_2, moduleName, baseUrl, candidate); } - return loader(extensions, candidate, !directoryProbablyExists(getDirectoryPath(candidate), state.host), state); + return loader(extensions, candidate, !ts.directoryProbablyExists(ts.getDirectoryPath(candidate), state.host), state); } /** @@ -1229,7 +1196,7 @@ namespace ts { * Throws an error if the module can't be resolved. */ /* @internal */ - export function resolveJSModule(moduleName: string, initialDir: string, host: ModuleResolutionHost): string { + export function resolveJSModule(moduleName: string, initialDir: string, host: ts.ModuleResolutionHost): string { const { resolvedModule, failedLookupLocations } = tryResolveJSModuleWorker(moduleName, initialDir, host); if (!resolvedModule) { throw new Error(`Could not resolve JS module '${moduleName}' starting at '${initialDir}'. Looked in: ${failedLookupLocations.join(", ")}`); @@ -1255,44 +1222,19 @@ namespace ts { NodeNextDefault = AllFeatures, - EsmMode = 1 << 5, + EsmMode = 1 << 5 } - - function node16ModuleNameResolver(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, - host: ModuleResolutionHost, cache?: ModuleResolutionCache, redirectedReference?: ResolvedProjectReference, - resolutionMode?: ModuleKind.CommonJS | ModuleKind.ESNext): ResolvedModuleWithFailedLookupLocations { - return nodeNextModuleNameResolverWorker( - NodeResolutionFeatures.Node16Default, - moduleName, - containingFile, - compilerOptions, - host, - cache, - redirectedReference, - resolutionMode - ); - } - - function nodeNextModuleNameResolver(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, - host: ModuleResolutionHost, cache?: ModuleResolutionCache, redirectedReference?: ResolvedProjectReference, - resolutionMode?: ModuleKind.CommonJS | ModuleKind.ESNext): ResolvedModuleWithFailedLookupLocations { - return nodeNextModuleNameResolverWorker( - NodeResolutionFeatures.NodeNextDefault, - moduleName, - containingFile, - compilerOptions, - host, - cache, - redirectedReference, - resolutionMode - ); + function node16ModuleNameResolver(moduleName: string, containingFile: string, compilerOptions: ts.CompilerOptions, host: ts.ModuleResolutionHost, cache?: ModuleResolutionCache, redirectedReference?: ts.ResolvedProjectReference, resolutionMode?: ts.ModuleKind.CommonJS | ts.ModuleKind.ESNext): ts.ResolvedModuleWithFailedLookupLocations { + return nodeNextModuleNameResolverWorker(NodeResolutionFeatures.Node16Default, moduleName, containingFile, compilerOptions, host, cache, redirectedReference, resolutionMode); } - - function nodeNextModuleNameResolverWorker(features: NodeResolutionFeatures, moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost, cache?: ModuleResolutionCache, redirectedReference?: ResolvedProjectReference, resolutionMode?: ModuleKind.CommonJS | ModuleKind.ESNext): ResolvedModuleWithFailedLookupLocations { - const containingDirectory = getDirectoryPath(containingFile); + function nodeNextModuleNameResolver(moduleName: string, containingFile: string, compilerOptions: ts.CompilerOptions, host: ts.ModuleResolutionHost, cache?: ModuleResolutionCache, redirectedReference?: ts.ResolvedProjectReference, resolutionMode?: ts.ModuleKind.CommonJS | ts.ModuleKind.ESNext): ts.ResolvedModuleWithFailedLookupLocations { + return nodeNextModuleNameResolverWorker(NodeResolutionFeatures.NodeNextDefault, moduleName, containingFile, compilerOptions, host, cache, redirectedReference, resolutionMode); + } + function nodeNextModuleNameResolverWorker(features: NodeResolutionFeatures, moduleName: string, containingFile: string, compilerOptions: ts.CompilerOptions, host: ts.ModuleResolutionHost, cache?: ModuleResolutionCache, redirectedReference?: ts.ResolvedProjectReference, resolutionMode?: ts.ModuleKind.CommonJS | ts.ModuleKind.ESNext): ts.ResolvedModuleWithFailedLookupLocations { + const containingDirectory = ts.getDirectoryPath(containingFile); // es module file or cjs-like input file, use a variant of the legacy cjs resolver that supports the selected modern features - const esmMode = resolutionMode === ModuleKind.ESNext ? NodeResolutionFeatures.EsmMode : 0; + const esmMode = resolutionMode === ts.ModuleKind.ESNext ? NodeResolutionFeatures.EsmMode : 0; return nodeModuleNameResolverWorker(features | esmMode, moduleName, containingDirectory, compilerOptions, host, cache, compilerOptions.resolveJsonModule ? tsPlusJsonExtensions : tsExtensions, redirectedReference); } @@ -1300,29 +1242,31 @@ namespace ts { const tsExtensions = [Extensions.TypeScript, Extensions.JavaScript]; const tsPlusJsonExtensions = [...tsExtensions, Extensions.Json]; const tsconfigExtensions = [Extensions.TSConfig]; - function tryResolveJSModuleWorker(moduleName: string, initialDir: string, host: ModuleResolutionHost): ResolvedModuleWithFailedLookupLocations { - return nodeModuleNameResolverWorker(NodeResolutionFeatures.None, moduleName, initialDir, { moduleResolution: ModuleResolutionKind.NodeJs, allowJs: true }, host, /*cache*/ undefined, jsOnlyExtensions, /*redirectedReferences*/ undefined); + function tryResolveJSModuleWorker(moduleName: string, initialDir: string, host: ts.ModuleResolutionHost): ts.ResolvedModuleWithFailedLookupLocations { + return nodeModuleNameResolverWorker(NodeResolutionFeatures.None, moduleName, initialDir, { moduleResolution: ts.ModuleResolutionKind.NodeJs, allowJs: true }, host, /*cache*/ undefined, jsOnlyExtensions, /*redirectedReferences*/ undefined); } - export function nodeModuleNameResolver(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost, cache?: ModuleResolutionCache, redirectedReference?: ResolvedProjectReference): ResolvedModuleWithFailedLookupLocations; - /* @internal */ export function nodeModuleNameResolver(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost, cache?: ModuleResolutionCache, redirectedReference?: ResolvedProjectReference, lookupConfig?: boolean): ResolvedModuleWithFailedLookupLocations; // eslint-disable-line @typescript-eslint/unified-signatures - export function nodeModuleNameResolver(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost, cache?: ModuleResolutionCache, redirectedReference?: ResolvedProjectReference, lookupConfig?: boolean): ResolvedModuleWithFailedLookupLocations { + export function nodeModuleNameResolver(moduleName: string, containingFile: string, compilerOptions: ts.CompilerOptions, host: ts.ModuleResolutionHost, cache?: ModuleResolutionCache, redirectedReference?: ts.ResolvedProjectReference): ts.ResolvedModuleWithFailedLookupLocations; + /* @internal */ export function nodeModuleNameResolver(moduleName: string, containingFile: string, compilerOptions: ts.CompilerOptions, host: ts.ModuleResolutionHost, cache?: ModuleResolutionCache, redirectedReference?: ts.ResolvedProjectReference, lookupConfig?: boolean): ts.ResolvedModuleWithFailedLookupLocations; // eslint-disable-line @typescript-eslint/unified-signatures + export function nodeModuleNameResolver(moduleName: string, containingFile: string, compilerOptions: ts.CompilerOptions, host: ts.ModuleResolutionHost, cache?: ModuleResolutionCache, redirectedReference?: ts.ResolvedProjectReference, lookupConfig?: boolean): ts.ResolvedModuleWithFailedLookupLocations { let extensions; if (lookupConfig) { extensions = tsconfigExtensions; } else if (compilerOptions.noDtsResolution) { extensions = [Extensions.TsOnly]; - if (compilerOptions.allowJs) extensions.push(Extensions.JavaScript); - if (compilerOptions.resolveJsonModule) extensions.push(Extensions.Json); + if (compilerOptions.allowJs) + extensions.push(Extensions.JavaScript); + if (compilerOptions.resolveJsonModule) + extensions.push(Extensions.Json); } else { extensions = compilerOptions.resolveJsonModule ? tsPlusJsonExtensions : tsExtensions; } - return nodeModuleNameResolverWorker(NodeResolutionFeatures.None, moduleName, getDirectoryPath(containingFile), compilerOptions, host, cache, extensions, redirectedReference); + return nodeModuleNameResolverWorker(NodeResolutionFeatures.None, moduleName, ts.getDirectoryPath(containingFile), compilerOptions, host, cache, extensions, redirectedReference); } - function nodeModuleNameResolverWorker(features: NodeResolutionFeatures, moduleName: string, containingDirectory: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost, cache: ModuleResolutionCache | undefined, extensions: Extensions[], redirectedReference: ResolvedProjectReference | undefined): ResolvedModuleWithFailedLookupLocations { + function nodeModuleNameResolverWorker(features: NodeResolutionFeatures, moduleName: string, containingDirectory: string, compilerOptions: ts.CompilerOptions, host: ts.ModuleResolutionHost, cache: ModuleResolutionCache | undefined, extensions: Extensions[], redirectedReference: ts.ResolvedProjectReference | undefined): ts.ResolvedModuleWithFailedLookupLocations { const traceEnabled = isTraceEnabled(compilerOptions, host); const failedLookupLocations: string[] = []; @@ -1333,7 +1277,7 @@ namespace ts { conditions.pop(); } - const diagnostics: Diagnostic[] = []; + const diagnostics: ts.Diagnostic[] = []; const state: ModuleResolutionState = { compilerOptions, host, @@ -1346,19 +1290,22 @@ namespace ts { reportDiagnostic: diag => void diagnostics.push(diag), }; - const result = forEach(extensions, ext => tryResolve(ext)); + const result = ts.forEach(extensions, ext => tryResolve(ext)); return createResolvedModuleWithFailedLookupLocations(result?.value?.resolved, result?.value?.isExternalLibraryImport, failedLookupLocations, diagnostics, state.resultFromCache); - function tryResolve(extensions: Extensions): SearchResult<{ resolved: Resolved, isExternalLibraryImport: boolean }> { + function tryResolve(extensions: Extensions): SearchResult<{ + resolved: Resolved; + isExternalLibraryImport: boolean; + }> { const loader: ResolutionKindSpecificLoader = (extensions, candidate, onlyRecordFailures, state) => nodeLoadModuleByRelativeName(extensions, candidate, onlyRecordFailures, state, /*considerPackageJson*/ true); const resolved = tryLoadModuleUsingOptionalResolutionSettings(extensions, moduleName, containingDirectory, loader, state); if (resolved) { return toSearchResult({ resolved, isExternalLibraryImport: pathContainsNodeModules(resolved.path) }); } - if (!isExternalModuleNameRelative(moduleName)) { + if (!ts.isExternalModuleNameRelative(moduleName)) { let resolved: SearchResult | undefined; - if (features & NodeResolutionFeatures.Imports && startsWith(moduleName, "#")) { + if (features & NodeResolutionFeatures.Imports && ts.startsWith(moduleName, "#")) { resolved = loadModuleFromImports(extensions, moduleName, containingDirectory, state, cache, redirectedReference); } if (!resolved && features & NodeResolutionFeatures.SelfName) { @@ -1366,11 +1313,12 @@ namespace ts { } if (!resolved) { if (traceEnabled) { - trace(host, Diagnostics.Loading_module_0_from_node_modules_folder_target_file_type_1, moduleName, Extensions[extensions]); + trace(host, ts.Diagnostics.Loading_module_0_from_node_modules_folder_target_file_type_1, moduleName, Extensions[extensions]); } resolved = loadModuleFromNearestNodeModulesDirectory(extensions, moduleName, containingDirectory, state, cache, redirectedReference); } - if (!resolved) return undefined; + if (!resolved) + return undefined; let resolvedValue = resolved.value; if (!compilerOptions.preserveSymlinks && resolvedValue && !resolvedValue.originalPath) { @@ -1385,7 +1333,7 @@ namespace ts { const { path: candidate, parts } = normalizePathForCJSResolution(containingDirectory, moduleName); const resolved = nodeLoadModuleByRelativeName(extensions, candidate, /*onlyRecordFailures*/ false, state, /*considerPackageJson*/ true); // Treat explicit "node_modules" import as an external library import. - return resolved && toSearchResult({ resolved, isExternalLibraryImport: contains(parts, "node_modules") }); + return resolved && toSearchResult({ resolved, isExternalLibraryImport: ts.contains(parts, "node_modules") }); } } @@ -1397,36 +1345,36 @@ namespace ts { // (https://nodejs.org/api/modules.html#all-together), but it seems that module paths ending // in `.` are actually normalized to `./` before proceeding with the resolution algorithm. function normalizePathForCJSResolution(containingDirectory: string, moduleName: string) { - const combined = combinePaths(containingDirectory, moduleName); - const parts = getPathComponents(combined); - const lastPart = lastOrUndefined(parts); - const path = lastPart === "." || lastPart === ".." ? ensureTrailingDirectorySeparator(normalizePath(combined)) : normalizePath(combined); + const combined = ts.combinePaths(containingDirectory, moduleName); + const parts = ts.getPathComponents(combined); + const lastPart = ts.lastOrUndefined(parts); + const path = lastPart === "." || lastPart === ".." ? ts.ensureTrailingDirectorySeparator(ts.normalizePath(combined)) : ts.normalizePath(combined); return { path, parts }; } - function realPath(path: string, host: ModuleResolutionHost, traceEnabled: boolean): string { + function realPath(path: string, host: ts.ModuleResolutionHost, traceEnabled: boolean): string { if (!host.realpath) { return path; } - const real = normalizePath(host.realpath(path)); + const real = ts.normalizePath(host.realpath(path)); if (traceEnabled) { - trace(host, Diagnostics.Resolving_real_path_for_0_result_1, path, real); + trace(host, ts.Diagnostics.Resolving_real_path_for_0_result_1, path, real); } - Debug.assert(host.fileExists(real), `${path} linked to nonexistent file ${real}`); + ts.Debug.assert(host.fileExists(real), `${path} linked to nonexistent file ${real}`); return real; } function nodeLoadModuleByRelativeName(extensions: Extensions, candidate: string, onlyRecordFailures: boolean, state: ModuleResolutionState, considerPackageJson: boolean): Resolved | undefined { if (state.traceEnabled) { - trace(state.host, Diagnostics.Loading_module_as_file_Slash_folder_candidate_module_location_0_target_file_type_1, candidate, Extensions[extensions]); + trace(state.host, ts.Diagnostics.Loading_module_as_file_Slash_folder_candidate_module_location_0_target_file_type_1, candidate, Extensions[extensions]); } - if (!hasTrailingDirectorySeparator(candidate)) { + if (!ts.hasTrailingDirectorySeparator(candidate)) { if (!onlyRecordFailures) { - const parentOfCandidate = getDirectoryPath(candidate); - if (!directoryProbablyExists(parentOfCandidate, state.host)) { + const parentOfCandidate = ts.getDirectoryPath(candidate); + if (!ts.directoryProbablyExists(parentOfCandidate, state.host)) { if (state.traceEnabled) { - trace(state.host, Diagnostics.Directory_0_does_not_exist_skipping_all_lookups_in_it, parentOfCandidate); + trace(state.host, ts.Diagnostics.Directory_0_does_not_exist_skipping_all_lookups_in_it, parentOfCandidate); } onlyRecordFailures = true; } @@ -1439,10 +1387,10 @@ namespace ts { } } if (!onlyRecordFailures) { - const candidateExists = directoryProbablyExists(candidate, state.host); + const candidateExists = ts.directoryProbablyExists(candidate, state.host); if (!candidateExists) { if (state.traceEnabled) { - trace(state.host, Diagnostics.Directory_0_does_not_exist_skipping_all_lookups_in_it, candidate); + trace(state.host, ts.Diagnostics.Directory_0_does_not_exist_skipping_all_lookups_in_it, candidate); } onlyRecordFailures = true; } @@ -1460,7 +1408,7 @@ namespace ts { export const nodeModulesPathPart = "/node_modules/"; /*@internal*/ export function pathContainsNodeModules(path: string): boolean { - return stringContains(path, nodeModulesPathPart); + return ts.stringContains(path, nodeModulesPathPart); } /** @@ -1475,7 +1423,7 @@ namespace ts { */ /* @internal */ export function parseNodeModuleFromPath(resolved: string): string | undefined { - const path = normalizePath(resolved); + const path = ts.normalizePath(resolved); const idx = path.lastIndexOf(nodeModulesPathPart); if (idx === -1) { return undefined; @@ -1483,14 +1431,14 @@ namespace ts { const indexAfterNodeModules = idx + nodeModulesPathPart.length; let indexAfterPackageName = moveToNextDirectorySeparatorIfAvailable(path, indexAfterNodeModules); - if (path.charCodeAt(indexAfterNodeModules) === CharacterCodes.at) { + if (path.charCodeAt(indexAfterNodeModules) === ts.CharacterCodes.at) { indexAfterPackageName = moveToNextDirectorySeparatorIfAvailable(path, indexAfterPackageName); } return path.slice(0, indexAfterPackageName); } function moveToNextDirectorySeparatorIfAvailable(path: string, prevSeparatorIndex: number): number { - const nextSeparatorIndex = path.indexOf(directorySeparator, prevSeparatorIndex + 1); + const nextSeparatorIndex = path.indexOf(ts.directorySeparator, prevSeparatorIndex + 1); return nextSeparatorIndex === -1 ? prevSeparatorIndex : nextSeparatorIndex; } @@ -1504,7 +1452,7 @@ namespace ts { */ function loadModuleFromFile(extensions: Extensions, candidate: string, onlyRecordFailures: boolean, state: ModuleResolutionState): PathAndExtension | undefined { if (extensions === Extensions.Json || extensions === Extensions.TSConfig) { - const extensionLess = tryRemoveExtension(candidate, Extension.Json); + const extensionLess = ts.tryRemoveExtension(candidate, ts.Extension.Json); const extension = extensionLess ? candidate.substring(extensionLess.length) : ""; return (extensionLess === undefined && extensions === Extensions.Json) ? undefined : tryAddingExtensions(extensionLess || candidate, extensions, extension, onlyRecordFailures, state); } @@ -1524,20 +1472,20 @@ namespace ts { function loadModuleFromFileNoImplicitExtensions(extensions: Extensions, candidate: string, onlyRecordFailures: boolean, state: ModuleResolutionState): PathAndExtension | undefined { // If that didn't work, try stripping a ".js" or ".jsx" extension and replacing it with a TypeScript one; // e.g. "./foo.js" can be matched by "./foo.ts" or "./foo.d.ts" - if (hasJSFileExtension(candidate) || (fileExtensionIs(candidate, Extension.Json) && state.compilerOptions.resolveJsonModule)) { - const extensionless = removeFileExtension(candidate); + if (ts.hasJSFileExtension(candidate) || (ts.fileExtensionIs(candidate, ts.Extension.Json) && state.compilerOptions.resolveJsonModule)) { + const extensionless = ts.removeFileExtension(candidate); const extension = candidate.substring(extensionless.length); if (state.traceEnabled) { - trace(state.host, Diagnostics.File_name_0_has_a_1_extension_stripping_it, candidate, extension); + trace(state.host, ts.Diagnostics.File_name_0_has_a_1_extension_stripping_it, candidate, extension); } return tryAddingExtensions(extensionless, extensions, extension, onlyRecordFailures, state); } } function loadJSOrExactTSFileName(extensions: Extensions, candidate: string, onlyRecordFailures: boolean, state: ModuleResolutionState): PathAndExtension | undefined { - if ((extensions === Extensions.TypeScript || extensions === Extensions.DtsOnly) && fileExtensionIsOneOf(candidate, supportedTSExtensionsFlat)) { + if ((extensions === Extensions.TypeScript || extensions === Extensions.DtsOnly) && ts.fileExtensionIsOneOf(candidate, ts.supportedTSExtensionsFlat)) { const result = tryFile(candidate, onlyRecordFailures, state); - return result !== undefined ? { path: candidate, ext: tryExtractTSExtension(candidate) as Extension } : undefined; + return result !== undefined ? { path: candidate, ext: ts.tryExtractTSExtension(candidate) as ts.Extension } : undefined; } return loadModuleFromFileNoImplicitExtensions(extensions, candidate, onlyRecordFailures, state); @@ -1547,67 +1495,67 @@ namespace ts { function tryAddingExtensions(candidate: string, extensions: Extensions, originalExtension: string, onlyRecordFailures: boolean, state: ModuleResolutionState): PathAndExtension | undefined { if (!onlyRecordFailures) { // check if containing folder exists - if it doesn't then just record failures for all supported extensions without disk probing - const directory = getDirectoryPath(candidate); + const directory = ts.getDirectoryPath(candidate); if (directory) { - onlyRecordFailures = !directoryProbablyExists(directory, state.host); + onlyRecordFailures = !ts.directoryProbablyExists(directory, state.host); } } switch (extensions) { case Extensions.DtsOnly: switch (originalExtension) { - case Extension.Mjs: - case Extension.Mts: - case Extension.Dmts: - return tryExtension(Extension.Dmts); - case Extension.Cjs: - case Extension.Cts: - case Extension.Dcts: - return tryExtension(Extension.Dcts); - case Extension.Json: - candidate += Extension.Json; - return tryExtension(Extension.Dts); - default: return tryExtension(Extension.Dts); + case ts.Extension.Mjs: + case ts.Extension.Mts: + case ts.Extension.Dmts: + return tryExtension(ts.Extension.Dmts); + case ts.Extension.Cjs: + case ts.Extension.Cts: + case ts.Extension.Dcts: + return tryExtension(ts.Extension.Dcts); + case ts.Extension.Json: + candidate += ts.Extension.Json; + return tryExtension(ts.Extension.Dts); + default: return tryExtension(ts.Extension.Dts); } case Extensions.TypeScript: case Extensions.TsOnly: const useDts = extensions === Extensions.TypeScript; switch (originalExtension) { - case Extension.Mjs: - case Extension.Mts: - case Extension.Dmts: - return tryExtension(Extension.Mts) || (useDts ? tryExtension(Extension.Dmts) : undefined); - case Extension.Cjs: - case Extension.Cts: - case Extension.Dcts: - return tryExtension(Extension.Cts) || (useDts ? tryExtension(Extension.Dcts) : undefined); - case Extension.Json: - candidate += Extension.Json; - return useDts ? tryExtension(Extension.Dts) : undefined; + case ts.Extension.Mjs: + case ts.Extension.Mts: + case ts.Extension.Dmts: + return tryExtension(ts.Extension.Mts) || (useDts ? tryExtension(ts.Extension.Dmts) : undefined); + case ts.Extension.Cjs: + case ts.Extension.Cts: + case ts.Extension.Dcts: + return tryExtension(ts.Extension.Cts) || (useDts ? tryExtension(ts.Extension.Dcts) : undefined); + case ts.Extension.Json: + candidate += ts.Extension.Json; + return useDts ? tryExtension(ts.Extension.Dts) : undefined; default: - return tryExtension(Extension.Ts) || tryExtension(Extension.Tsx) || (useDts ? tryExtension(Extension.Dts) : undefined); + return tryExtension(ts.Extension.Ts) || tryExtension(ts.Extension.Tsx) || (useDts ? tryExtension(ts.Extension.Dts) : undefined); } case Extensions.JavaScript: switch (originalExtension) { - case Extension.Mjs: - case Extension.Mts: - case Extension.Dmts: - return tryExtension(Extension.Mjs); - case Extension.Cjs: - case Extension.Cts: - case Extension.Dcts: - return tryExtension(Extension.Cjs); - case Extension.Json: - return tryExtension(Extension.Json); + case ts.Extension.Mjs: + case ts.Extension.Mts: + case ts.Extension.Dmts: + return tryExtension(ts.Extension.Mjs); + case ts.Extension.Cjs: + case ts.Extension.Cts: + case ts.Extension.Dcts: + return tryExtension(ts.Extension.Cjs); + case ts.Extension.Json: + return tryExtension(ts.Extension.Json); default: - return tryExtension(Extension.Js) || tryExtension(Extension.Jsx); + return tryExtension(ts.Extension.Js) || tryExtension(ts.Extension.Jsx); } case Extensions.TSConfig: case Extensions.Json: - return tryExtension(Extension.Json); + return tryExtension(ts.Extension.Json); } - function tryExtension(ext: Extension): PathAndExtension | undefined { + function tryExtension(ext: ts.Extension): PathAndExtension | undefined { const path = tryFile(candidate + ext, onlyRecordFailures, state); return path === undefined ? undefined : { path, ext }; } @@ -1619,22 +1567,22 @@ namespace ts { return tryFileLookup(fileName, onlyRecordFailures, state); } - const ext = tryGetExtensionFromPath(fileName) ?? ""; - const fileNameNoExtension = ext ? removeExtension(fileName, ext) : fileName; - return forEach(state.compilerOptions.moduleSuffixes, suffix => tryFileLookup(fileNameNoExtension + suffix + ext, onlyRecordFailures, state)); + const ext = ts.tryGetExtensionFromPath(fileName) ?? ""; + const fileNameNoExtension = ext ? ts.removeExtension(fileName, ext) : fileName; + return ts.forEach(state.compilerOptions.moduleSuffixes, suffix => tryFileLookup(fileNameNoExtension + suffix + ext, onlyRecordFailures, state)); } function tryFileLookup(fileName: string, onlyRecordFailures: boolean, state: ModuleResolutionState): string | undefined { if (!onlyRecordFailures) { if (state.host.fileExists(fileName)) { if (state.traceEnabled) { - trace(state.host, Diagnostics.File_0_exist_use_it_as_a_name_resolution_result, fileName); + trace(state.host, ts.Diagnostics.File_0_exist_use_it_as_a_name_resolution_result, fileName); } return fileName; } else { if (state.traceEnabled) { - trace(state.host, Diagnostics.File_0_does_not_exist, fileName); + trace(state.host, ts.Diagnostics.File_0_does_not_exist, fileName); } } } @@ -1650,13 +1598,7 @@ namespace ts { } /* @internal */ - export function getEntrypointsFromPackageJsonInfo( - packageJsonInfo: PackageJsonInfo, - options: CompilerOptions, - host: ModuleResolutionHost, - cache: ModuleResolutionCache | undefined, - resolveJs?: boolean, - ): string[] | false { + export function getEntrypointsFromPackageJsonInfo(packageJsonInfo: PackageJsonInfo, options: ts.CompilerOptions, host: ts.ModuleResolutionHost, cache: ModuleResolutionCache | undefined, resolveJs?: boolean): string[] | false { if (!resolveJs && packageJsonInfo.resolvedEntrypoints !== undefined) { // Cached value excludes resolutions to JS files - those could be // cached separately, but they're used rarely. @@ -1675,28 +1617,19 @@ namespace ts { conditions: ["node", "require", "types"], features, requestContainingDirectory: packageJsonInfo.packageDirectory, - reportDiagnostic: noop + reportDiagnostic: ts.noop }; - const requireResolution = loadNodeModuleFromDirectoryWorker( - extensions, - packageJsonInfo.packageDirectory, - /*onlyRecordFailures*/ false, - requireState, - packageJsonInfo.packageJsonContent, - packageJsonInfo.versionPaths); - entrypoints = append(entrypoints, requireResolution?.path); + const requireResolution = loadNodeModuleFromDirectoryWorker(extensions, packageJsonInfo.packageDirectory, + /*onlyRecordFailures*/ false, requireState, packageJsonInfo.packageJsonContent, packageJsonInfo.versionPaths); + entrypoints = ts.append(entrypoints, requireResolution?.path); if (features & NodeResolutionFeatures.Exports && packageJsonInfo.packageJsonContent.exports) { for (const conditions of [["node", "import", "types"], ["node", "require", "types"]]) { const exportState = { ...requireState, failedLookupLocations: [], conditions }; - const exportResolutions = loadEntrypointsFromExportMap( - packageJsonInfo, - packageJsonInfo.packageJsonContent.exports, - exportState, - extensions); + const exportResolutions = loadEntrypointsFromExportMap(packageJsonInfo, packageJsonInfo.packageJsonContent.exports, exportState, extensions); if (exportResolutions) { for (const resolution of exportResolutions) { - entrypoints = appendIfUnique(entrypoints, resolution.path); + entrypoints = ts.appendIfUnique(entrypoints, resolution.path); } } } @@ -1705,22 +1638,17 @@ namespace ts { return packageJsonInfo.resolvedEntrypoints = entrypoints || false; } - function loadEntrypointsFromExportMap( - scope: PackageJsonInfo, - exports: object, - state: ModuleResolutionState, - extensions: Extensions, - ): PathAndExtension[] | undefined { + function loadEntrypointsFromExportMap(scope: PackageJsonInfo, exports: object, state: ModuleResolutionState, extensions: Extensions): PathAndExtension[] | undefined { let entrypoints: PathAndExtension[] | undefined; - if (isArray(exports)) { + if (ts.isArray(exports)) { for (const target of exports) { loadEntrypointsFromTargetExports(target); } } // eslint-disable-next-line no-null/no-null - else if (typeof exports === "object" && exports !== null && allKeysStartWithDot(exports as MapLike)) { + else if (typeof exports === "object" && exports !== null && allKeysStartWithDot(exports as ts.MapLike)) { for (const key in exports) { - loadEntrypointsFromTargetExports((exports as MapLike)[key]); + loadEntrypointsFromTargetExports((exports as ts.MapLike)[key]); } } else { @@ -1729,16 +1657,16 @@ namespace ts { return entrypoints; function loadEntrypointsFromTargetExports(target: unknown): boolean | undefined { - if (typeof target === "string" && startsWith(target, "./") && target.indexOf("*") === -1) { - const partsAfterFirst = getPathComponents(target).slice(2); + if (typeof target === "string" && ts.startsWith(target, "./") && target.indexOf("*") === -1) { + const partsAfterFirst = ts.getPathComponents(target).slice(2); if (partsAfterFirst.indexOf("..") >= 0 || partsAfterFirst.indexOf(".") >= 0 || partsAfterFirst.indexOf("node_modules") >= 0) { return false; } - const resolvedTarget = combinePaths(scope.packageDirectory, target); - const finalPath = getNormalizedAbsolutePath(resolvedTarget, state.host.getCurrentDirectory?.()); + const resolvedTarget = ts.combinePaths(scope.packageDirectory, target); + const finalPath = ts.getNormalizedAbsolutePath(resolvedTarget, state.host.getCurrentDirectory?.()); const result = loadJSOrExactTSFileName(extensions, finalPath, /*recordOnlyFailures*/ false, state); if (result) { - entrypoints = appendIfUnique(entrypoints, result, (a, b) => a.path === b.path); + entrypoints = ts.appendIfUnique(entrypoints, result, (a, b) => a.path === b.path); return true; } } @@ -1752,9 +1680,9 @@ namespace ts { } // eslint-disable-next-line no-null/no-null else if (typeof target === "object" && target !== null) { - return forEach(getOwnKeys(target as MapLike), key => { - if (key === "default" || contains(state.conditions, key) || isApplicableVersionedTypesKey(state.conditions, key)) { - loadEntrypointsFromTargetExports((target as MapLike)[key]); + return ts.forEach(ts.getOwnKeys(target as ts.MapLike), key => { + if (key === "default" || ts.contains(state.conditions, key) || isApplicableVersionedTypesKey(state.conditions, key)) { + loadEntrypointsFromTargetExports((target as ts.MapLike)[key]); return true; } }); @@ -1775,18 +1703,18 @@ namespace ts { * A function for locating the package.json scope for a given path */ /*@internal*/ - export function getPackageScopeForPath(fileName: Path, packageJsonInfoCache: PackageJsonInfoCache | undefined, host: ModuleResolutionHost, options: CompilerOptions): PackageJsonInfo | undefined { + export function getPackageScopeForPath(fileName: ts.Path, packageJsonInfoCache: PackageJsonInfoCache | undefined, host: ts.ModuleResolutionHost, options: ts.CompilerOptions): PackageJsonInfo | undefined { const state: { - host: ModuleResolutionHost; - compilerOptions: CompilerOptions; + host: ts.ModuleResolutionHost; + compilerOptions: ts.CompilerOptions; traceEnabled: boolean; - failedLookupLocations: Push; - resultFromCache?: ResolvedModuleWithFailedLookupLocations; + failedLookupLocations: ts.Push; + resultFromCache?: ts.ResolvedModuleWithFailedLookupLocations; packageJsonInfoCache: PackageJsonInfoCache | undefined; features: number; conditions: never[]; requestContainingDirectory: string | undefined; - reportDiagnostic: DiagnosticReporter + reportDiagnostic: ts.DiagnosticReporter; } = { host, compilerOptions: options, @@ -1796,12 +1724,12 @@ namespace ts { features: 0, conditions: [], requestContainingDirectory: undefined, - reportDiagnostic: noop + reportDiagnostic: ts.noop }; - const parts = getPathComponents(fileName); + const parts = ts.getPathComponents(fileName); parts.pop(); while (parts.length > 0) { - const pkg = getPackageJsonInfo(getPathFromPathComponents(parts), /*onlyRecordFailures*/ false, state); + const pkg = getPackageJsonInfo(ts.getPathFromPathComponents(parts), /*onlyRecordFailures*/ false, state); if (pkg) { return pkg; } @@ -1813,7 +1741,7 @@ namespace ts { /*@internal*/ export function getPackageJsonInfo(packageDirectory: string, onlyRecordFailures: boolean, state: ModuleResolutionState): PackageJsonInfo | undefined { const { host, traceEnabled } = state; - const packageJsonPath = combinePaths(packageDirectory, "package.json"); + const packageJsonPath = ts.combinePaths(packageDirectory, "package.json"); if (onlyRecordFailures) { state.failedLookupLocations.push(packageJsonPath); return undefined; @@ -1822,20 +1750,22 @@ namespace ts { const existing = state.packageJsonInfoCache?.getPackageJsonInfo(packageJsonPath); if (existing !== undefined) { if (typeof existing !== "boolean") { - if (traceEnabled) trace(host, Diagnostics.File_0_exists_according_to_earlier_cached_lookups, packageJsonPath); + if (traceEnabled) + trace(host, ts.Diagnostics.File_0_exists_according_to_earlier_cached_lookups, packageJsonPath); return existing; } else { - if (existing && traceEnabled) trace(host, Diagnostics.File_0_does_not_exist_according_to_earlier_cached_lookups, packageJsonPath); + if (existing && traceEnabled) + trace(host, ts.Diagnostics.File_0_does_not_exist_according_to_earlier_cached_lookups, packageJsonPath); state.failedLookupLocations.push(packageJsonPath); return undefined; } } - const directoryExists = directoryProbablyExists(packageDirectory, host); + const directoryExists = ts.directoryProbablyExists(packageDirectory, host); if (directoryExists && host.fileExists(packageJsonPath)) { - const packageJsonContent = readJson(packageJsonPath, host) as PackageJson; + const packageJsonContent = ts.readJson(packageJsonPath, host) as PackageJson; if (traceEnabled) { - trace(host, Diagnostics.Found_package_json_at_0, packageJsonPath); + trace(host, ts.Diagnostics.Found_package_json_at_0, packageJsonPath); } const versionPaths = readPackageJsonTypesVersionPaths(packageJsonContent, state); const result = { packageDirectory, packageJsonContent, versionPaths, resolvedEntrypoints: undefined }; @@ -1844,7 +1774,7 @@ namespace ts { } else { if (directoryExists && traceEnabled) { - trace(host, Diagnostics.File_0_does_not_exist, packageJsonPath); + trace(host, ts.Diagnostics.File_0_does_not_exist, packageJsonPath); } state.packageJsonInfoCache?.setPackageJsonInfo(packageJsonPath, directoryExists); // record package json as one of failed lookup locations - in the future if this file will appear it will invalidate resolution results @@ -1872,7 +1802,7 @@ namespace ts { packageFile = readPackageJsonTSConfigField(jsonContent, candidate, state); break; default: - return Debug.assertNever(extensions); + return ts.Debug.assertNever(extensions); } } @@ -1884,7 +1814,7 @@ namespace ts { return noPackageId(resolved); } if (state.traceEnabled) { - trace(state.host, Diagnostics.File_0_has_an_unsupported_extension_so_skipping_it, fromFile); + trace(state.host, ts.Diagnostics.File_0_has_an_unsupported_extension_so_skipping_it, fromFile); } } @@ -1904,14 +1834,13 @@ namespace ts { return result; }; - const onlyRecordFailuresForPackageFile = packageFile ? !directoryProbablyExists(getDirectoryPath(packageFile), state.host) : undefined; - const onlyRecordFailuresForIndex = onlyRecordFailures || !directoryProbablyExists(candidate, state.host); - const indexPath = combinePaths(candidate, extensions === Extensions.TSConfig ? "tsconfig" : "index"); - - if (versionPaths && (!packageFile || containsPath(candidate, packageFile))) { - const moduleName = getRelativePathFromDirectory(candidate, packageFile || indexPath, /*ignoreCase*/ false); + const onlyRecordFailuresForPackageFile = packageFile ? !ts.directoryProbablyExists(ts.getDirectoryPath(packageFile), state.host) : undefined; + const onlyRecordFailuresForIndex = onlyRecordFailures || !ts.directoryProbablyExists(candidate, state.host); + const indexPath = ts.combinePaths(candidate, extensions === Extensions.TSConfig ? "tsconfig" : "index"); + if (versionPaths && (!packageFile || ts.containsPath(candidate, packageFile))) { + const moduleName = ts.getRelativePathFromDirectory(candidate, packageFile || indexPath, /*ignoreCase*/ false); if (state.traceEnabled) { - trace(state.host, Diagnostics.package_json_has_a_typesVersions_entry_0_that_matches_compiler_version_1_looking_for_a_pattern_to_match_module_name_2, versionPaths.version, version, moduleName); + trace(state.host, ts.Diagnostics.package_json_has_a_typesVersions_entry_0_that_matches_compiler_version_1_looking_for_a_pattern_to_match_module_name_2, versionPaths.version, ts.version, moduleName); } const result = tryLoadModuleUsingPaths(extensions, moduleName, candidate, versionPaths.paths, /*pathPatterns*/ undefined, loader, onlyRecordFailuresForPackageFile || onlyRecordFailuresForIndex, state); if (result) { @@ -1921,7 +1850,8 @@ namespace ts { // It won't have a `packageId` set, because we disabled `considerPackageJson`. const packageFileResult = packageFile && removeIgnoredPackageId(loader(extensions, packageFile, onlyRecordFailuresForPackageFile!, state)); - if (packageFileResult) return packageFileResult; + if (packageFileResult) + return packageFileResult; // esm mode resolutions don't do package `index` lookups if (!(state.features & NodeResolutionFeatures.EsmMode)) { @@ -1931,48 +1861,51 @@ namespace ts { /** Resolve from an arbitrarily specified file. Return `undefined` if it has an unsupported extension. */ function resolvedIfExtensionMatches(extensions: Extensions, path: string): PathAndExtension | undefined { - const ext = tryGetExtensionFromPath(path); + const ext = ts.tryGetExtensionFromPath(path); return ext !== undefined && extensionIsOk(extensions, ext) ? { path, ext } : undefined; } /** True if `extension` is one of the supported `extensions`. */ - function extensionIsOk(extensions: Extensions, extension: Extension): boolean { + function extensionIsOk(extensions: Extensions, extension: ts.Extension): boolean { switch (extensions) { case Extensions.JavaScript: - return extension === Extension.Js || extension === Extension.Jsx || extension === Extension.Mjs || extension === Extension.Cjs; + return extension === ts.Extension.Js || extension === ts.Extension.Jsx || extension === ts.Extension.Mjs || extension === ts.Extension.Cjs; case Extensions.TSConfig: case Extensions.Json: - return extension === Extension.Json; + return extension === ts.Extension.Json; case Extensions.TypeScript: - return extension === Extension.Ts || extension === Extension.Tsx || extension === Extension.Mts || extension === Extension.Cts || extension === Extension.Dts || extension === Extension.Dmts || extension === Extension.Dcts; + return extension === ts.Extension.Ts || extension === ts.Extension.Tsx || extension === ts.Extension.Mts || extension === ts.Extension.Cts || extension === ts.Extension.Dts || extension === ts.Extension.Dmts || extension === ts.Extension.Dcts; case Extensions.TsOnly: - return extension === Extension.Ts || extension === Extension.Tsx || extension === Extension.Mts || extension === Extension.Cts; + return extension === ts.Extension.Ts || extension === ts.Extension.Tsx || extension === ts.Extension.Mts || extension === ts.Extension.Cts; case Extensions.DtsOnly: - return extension === Extension.Dts || extension === Extension.Dmts || extension === Extension.Dcts; + return extension === ts.Extension.Dts || extension === ts.Extension.Dmts || extension === ts.Extension.Dcts; } } /* @internal */ - export function parsePackageName(moduleName: string): { packageName: string, rest: string } { - let idx = moduleName.indexOf(directorySeparator); + export function parsePackageName(moduleName: string): { + packageName: string; + rest: string; + } { + let idx = moduleName.indexOf(ts.directorySeparator); if (moduleName[0] === "@") { - idx = moduleName.indexOf(directorySeparator, idx + 1); + idx = moduleName.indexOf(ts.directorySeparator, idx + 1); } return idx === -1 ? { packageName: moduleName, rest: "" } : { packageName: moduleName.slice(0, idx), rest: moduleName.slice(idx + 1) }; } /* @internal */ - export function allKeysStartWithDot(obj: MapLike) { - return every(getOwnKeys(obj), k => startsWith(k, ".")); + export function allKeysStartWithDot(obj: ts.MapLike) { + return ts.every(ts.getOwnKeys(obj), k => ts.startsWith(k, ".")); } - function noKeyStartsWithDot(obj: MapLike) { - return !some(getOwnKeys(obj), k => startsWith(k, ".")); + function noKeyStartsWithDot(obj: ts.MapLike) { + return !ts.some(ts.getOwnKeys(obj), k => ts.startsWith(k, ".")); } - function loadModuleFromSelfNameReference(extensions: Extensions, moduleName: string, directory: string, state: ModuleResolutionState, cache: ModuleResolutionCache | undefined, redirectedReference: ResolvedProjectReference | undefined): SearchResult { + function loadModuleFromSelfNameReference(extensions: Extensions, moduleName: string, directory: string, state: ModuleResolutionState, cache: ModuleResolutionCache | undefined, redirectedReference: ts.ResolvedProjectReference | undefined): SearchResult { const useCaseSensitiveFileNames = typeof state.host.useCaseSensitiveFileNames === "function" ? state.host.useCaseSensitiveFileNames() : state.host.useCaseSensitiveFileNames; - const directoryPath = toPath(combinePaths(directory, "dummy"), state.host.getCurrentDirectory?.(), createGetCanonicalFileName(useCaseSensitiveFileNames === undefined ? true : useCaseSensitiveFileNames)); + const directoryPath = ts.toPath(ts.combinePaths(directory, "dummy"), state.host.getCurrentDirectory?.(), ts.createGetCanonicalFileName(useCaseSensitiveFileNames === undefined ? true : useCaseSensitiveFileNames)); const scope = getPackageScopeForPath(directoryPath, state.packageJsonInfoCache, state.host, state.compilerOptions); if (!scope || !scope.packageJsonContent.exports) { return undefined; @@ -1980,37 +1913,37 @@ namespace ts { if (typeof scope.packageJsonContent.name !== "string") { return undefined; } - const parts = getPathComponents(moduleName); // unrooted paths should have `""` as their 0th entry - const nameParts = getPathComponents(scope.packageJsonContent.name); - if (!every(nameParts, (p, i) => parts[i] === p)) { + const parts = ts.getPathComponents(moduleName); // unrooted paths should have `""` as their 0th entry + const nameParts = ts.getPathComponents(scope.packageJsonContent.name); + if (!ts.every(nameParts, (p, i) => parts[i] === p)) { return undefined; } const trailingParts = parts.slice(nameParts.length); - return loadModuleFromExports(scope, extensions, !length(trailingParts) ? "." : `.${directorySeparator}${trailingParts.join(directorySeparator)}`, state, cache, redirectedReference); + return loadModuleFromExports(scope, extensions, !ts.length(trailingParts) ? "." : `.${ts.directorySeparator}${trailingParts.join(ts.directorySeparator)}`, state, cache, redirectedReference); } - function loadModuleFromExports(scope: PackageJsonInfo, extensions: Extensions, subpath: string, state: ModuleResolutionState, cache: ModuleResolutionCache | undefined, redirectedReference: ResolvedProjectReference | undefined): SearchResult { + function loadModuleFromExports(scope: PackageJsonInfo, extensions: Extensions, subpath: string, state: ModuleResolutionState, cache: ModuleResolutionCache | undefined, redirectedReference: ts.ResolvedProjectReference | undefined): SearchResult { if (!scope.packageJsonContent.exports) { return undefined; } if (subpath === ".") { let mainExport; - if (typeof scope.packageJsonContent.exports === "string" || Array.isArray(scope.packageJsonContent.exports) || (typeof scope.packageJsonContent.exports === "object" && noKeyStartsWithDot(scope.packageJsonContent.exports as MapLike))) { + if (typeof scope.packageJsonContent.exports === "string" || Array.isArray(scope.packageJsonContent.exports) || (typeof scope.packageJsonContent.exports === "object" && noKeyStartsWithDot(scope.packageJsonContent.exports as ts.MapLike))) { mainExport = scope.packageJsonContent.exports; } - else if (hasProperty(scope.packageJsonContent.exports as MapLike, ".")) { - mainExport = (scope.packageJsonContent.exports as MapLike)["."]; + else if (ts.hasProperty(scope.packageJsonContent.exports as ts.MapLike, ".")) { + mainExport = (scope.packageJsonContent.exports as ts.MapLike)["."]; } if (mainExport) { const loadModuleFromTargetImportOrExport = getLoadModuleFromTargetImportOrExport(extensions, state, cache, redirectedReference, subpath, scope, /*isImports*/ false); return loadModuleFromTargetImportOrExport(mainExport, "", /*pattern*/ false); } } - else if (allKeysStartWithDot(scope.packageJsonContent.exports as MapLike)) { + else if (allKeysStartWithDot(scope.packageJsonContent.exports as ts.MapLike)) { if (typeof scope.packageJsonContent.exports !== "object") { if (state.traceEnabled) { - trace(state.host, Diagnostics.Export_specifier_0_does_not_exist_in_package_json_scope_at_path_1, subpath, scope.packageDirectory); + trace(state.host, ts.Diagnostics.Export_specifier_0_does_not_exist_in_package_json_scope_at_path_1, subpath, scope.packageDirectory); } return toSearchResult(/*value*/ undefined); } @@ -2021,30 +1954,30 @@ namespace ts { } if (state.traceEnabled) { - trace(state.host, Diagnostics.Export_specifier_0_does_not_exist_in_package_json_scope_at_path_1, subpath, scope.packageDirectory); + trace(state.host, ts.Diagnostics.Export_specifier_0_does_not_exist_in_package_json_scope_at_path_1, subpath, scope.packageDirectory); } return toSearchResult(/*value*/ undefined); } - function loadModuleFromImports(extensions: Extensions, moduleName: string, directory: string, state: ModuleResolutionState, cache: ModuleResolutionCache | undefined, redirectedReference: ResolvedProjectReference | undefined): SearchResult { - if (moduleName === "#" || startsWith(moduleName, "#/")) { + function loadModuleFromImports(extensions: Extensions, moduleName: string, directory: string, state: ModuleResolutionState, cache: ModuleResolutionCache | undefined, redirectedReference: ts.ResolvedProjectReference | undefined): SearchResult { + if (moduleName === "#" || ts.startsWith(moduleName, "#/")) { if (state.traceEnabled) { - trace(state.host, Diagnostics.Invalid_import_specifier_0_has_no_possible_resolutions, moduleName); + trace(state.host, ts.Diagnostics.Invalid_import_specifier_0_has_no_possible_resolutions, moduleName); } return toSearchResult(/*value*/ undefined); } const useCaseSensitiveFileNames = typeof state.host.useCaseSensitiveFileNames === "function" ? state.host.useCaseSensitiveFileNames() : state.host.useCaseSensitiveFileNames; - const directoryPath = toPath(combinePaths(directory, "dummy"), state.host.getCurrentDirectory?.(), createGetCanonicalFileName(useCaseSensitiveFileNames === undefined ? true : useCaseSensitiveFileNames)); + const directoryPath = ts.toPath(ts.combinePaths(directory, "dummy"), state.host.getCurrentDirectory?.(), ts.createGetCanonicalFileName(useCaseSensitiveFileNames === undefined ? true : useCaseSensitiveFileNames)); const scope = getPackageScopeForPath(directoryPath, state.packageJsonInfoCache, state.host, state.compilerOptions); if (!scope) { if (state.traceEnabled) { - trace(state.host, Diagnostics.Directory_0_has_no_containing_package_json_scope_Imports_will_not_resolve, directoryPath); + trace(state.host, ts.Diagnostics.Directory_0_has_no_containing_package_json_scope_Imports_will_not_resolve, directoryPath); } return toSearchResult(/*value*/ undefined); } if (!scope.packageJsonContent.imports) { if (state.traceEnabled) { - trace(state.host, Diagnostics.package_json_scope_0_has_no_imports_defined, scope.packageDirectory); + trace(state.host, ts.Diagnostics.package_json_scope_0_has_no_imports_defined, scope.packageDirectory); } return toSearchResult(/*value*/ undefined); } @@ -2055,98 +1988,109 @@ namespace ts { } if (state.traceEnabled) { - trace(state.host, Diagnostics.Import_specifier_0_does_not_exist_in_package_json_scope_at_path_1, moduleName, scope.packageDirectory); + trace(state.host, ts.Diagnostics.Import_specifier_0_does_not_exist_in_package_json_scope_at_path_1, moduleName, scope.packageDirectory); } return toSearchResult(/*value*/ undefined); } - function loadModuleFromImportsOrExports(extensions: Extensions, state: ModuleResolutionState, cache: ModuleResolutionCache | undefined, redirectedReference: ResolvedProjectReference | undefined, moduleName: string, lookupTable: object, scope: PackageJsonInfo, isImports: boolean): SearchResult | undefined { + function loadModuleFromImportsOrExports(extensions: Extensions, state: ModuleResolutionState, cache: ModuleResolutionCache | undefined, redirectedReference: ts.ResolvedProjectReference | undefined, moduleName: string, lookupTable: object, scope: PackageJsonInfo, isImports: boolean): SearchResult | undefined { const loadModuleFromTargetImportOrExport = getLoadModuleFromTargetImportOrExport(extensions, state, cache, redirectedReference, moduleName, scope, isImports); - if (!endsWith(moduleName, directorySeparator) && moduleName.indexOf("*") === -1 && hasProperty(lookupTable, moduleName)) { - const target = (lookupTable as {[idx: string]: unknown})[moduleName]; + if (!ts.endsWith(moduleName, ts.directorySeparator) && moduleName.indexOf("*") === -1 && ts.hasProperty(lookupTable, moduleName)) { + const target = (lookupTable as { + [idx: string]: unknown; + })[moduleName]; return loadModuleFromTargetImportOrExport(target, /*subpath*/ "", /*pattern*/ false); } - const expandingKeys = sort(filter(getOwnKeys(lookupTable as MapLike), k => k.indexOf("*") !== -1 || endsWith(k, "/")), (a, b) => a.length - b.length); + const expandingKeys = ts.sort(ts.filter(ts.getOwnKeys(lookupTable as ts.MapLike), k => k.indexOf("*") !== -1 || ts.endsWith(k, "/")), (a, b) => a.length - b.length); for (const potentialTarget of expandingKeys) { if (state.features & NodeResolutionFeatures.ExportsPatternTrailers && matchesPatternWithTrailer(potentialTarget, moduleName)) { - const target = (lookupTable as {[idx: string]: unknown})[potentialTarget]; + const target = (lookupTable as { + [idx: string]: unknown; + })[potentialTarget]; const starPos = potentialTarget.indexOf("*"); const subpath = moduleName.substring(potentialTarget.substring(0, starPos).length, moduleName.length - (potentialTarget.length - 1 - starPos)); return loadModuleFromTargetImportOrExport(target, subpath, /*pattern*/ true); } - else if (endsWith(potentialTarget, "*") && startsWith(moduleName, potentialTarget.substring(0, potentialTarget.length - 1))) { - const target = (lookupTable as {[idx: string]: unknown})[potentialTarget]; + else if (ts.endsWith(potentialTarget, "*") && ts.startsWith(moduleName, potentialTarget.substring(0, potentialTarget.length - 1))) { + const target = (lookupTable as { + [idx: string]: unknown; + })[potentialTarget]; const subpath = moduleName.substring(potentialTarget.length - 1); return loadModuleFromTargetImportOrExport(target, subpath, /*pattern*/ true); } - else if (startsWith(moduleName, potentialTarget)) { - const target = (lookupTable as {[idx: string]: unknown})[potentialTarget]; + else if (ts.startsWith(moduleName, potentialTarget)) { + const target = (lookupTable as { + [idx: string]: unknown; + })[potentialTarget]; const subpath = moduleName.substring(potentialTarget.length); return loadModuleFromTargetImportOrExport(target, subpath, /*pattern*/ false); } } function matchesPatternWithTrailer(target: string, name: string) { - if (endsWith(target, "*")) return false; // handled by next case in loop + if (ts.endsWith(target, "*")) + return false; // handled by next case in loop const starPos = target.indexOf("*"); - if (starPos === -1) return false; // handled by last case in loop - return startsWith(name, target.substring(0, starPos)) && endsWith(name, target.substring(starPos + 1)); + if (starPos === -1) + return false; // handled by last case in loop + return ts.startsWith(name, target.substring(0, starPos)) && ts.endsWith(name, target.substring(starPos + 1)); } } /** * Gets the self-recursive function specialized to retrieving the targeted import/export element for the given resolution configuration */ - function getLoadModuleFromTargetImportOrExport(extensions: Extensions, state: ModuleResolutionState, cache: ModuleResolutionCache | undefined, redirectedReference: ResolvedProjectReference | undefined, moduleName: string, scope: PackageJsonInfo, isImports: boolean) { + function getLoadModuleFromTargetImportOrExport(extensions: Extensions, state: ModuleResolutionState, cache: ModuleResolutionCache | undefined, redirectedReference: ts.ResolvedProjectReference | undefined, moduleName: string, scope: PackageJsonInfo, isImports: boolean) { return loadModuleFromTargetImportOrExport; function loadModuleFromTargetImportOrExport(target: unknown, subpath: string, pattern: boolean): SearchResult | undefined { if (typeof target === "string") { - if (!pattern && subpath.length > 0 && !endsWith(target, "/")) { + if (!pattern && subpath.length > 0 && !ts.endsWith(target, "/")) { if (state.traceEnabled) { - trace(state.host, Diagnostics.package_json_scope_0_has_invalid_type_for_target_of_specifier_1, scope.packageDirectory, moduleName); + trace(state.host, ts.Diagnostics.package_json_scope_0_has_invalid_type_for_target_of_specifier_1, scope.packageDirectory, moduleName); } return toSearchResult(/*value*/ undefined); } - if (!startsWith(target, "./")) { - if (isImports && !startsWith(target, "../") && !startsWith(target, "/") && !isRootedDiskPath(target)) { + if (!ts.startsWith(target, "./")) { + if (isImports && !ts.startsWith(target, "../") && !ts.startsWith(target, "/") && !ts.isRootedDiskPath(target)) { const combinedLookup = pattern ? target.replace(/\*/g, subpath) : target + subpath; const result = nodeModuleNameResolverWorker(state.features, combinedLookup, scope.packageDirectory + "/", state.compilerOptions, state.host, cache, [extensions], redirectedReference); return toSearchResult(result.resolvedModule ? { path: result.resolvedModule.resolvedFileName, extension: result.resolvedModule.extension, packageId: result.resolvedModule.packageId, originalPath: result.resolvedModule.originalPath } : undefined); } if (state.traceEnabled) { - trace(state.host, Diagnostics.package_json_scope_0_has_invalid_type_for_target_of_specifier_1, scope.packageDirectory, moduleName); + trace(state.host, ts.Diagnostics.package_json_scope_0_has_invalid_type_for_target_of_specifier_1, scope.packageDirectory, moduleName); } return toSearchResult(/*value*/ undefined); } - const parts = pathIsRelative(target) ? getPathComponents(target).slice(1) : getPathComponents(target); + const parts = ts.pathIsRelative(target) ? ts.getPathComponents(target).slice(1) : ts.getPathComponents(target); const partsAfterFirst = parts.slice(1); if (partsAfterFirst.indexOf("..") >= 0 || partsAfterFirst.indexOf(".") >= 0 || partsAfterFirst.indexOf("node_modules") >= 0) { if (state.traceEnabled) { - trace(state.host, Diagnostics.package_json_scope_0_has_invalid_type_for_target_of_specifier_1, scope.packageDirectory, moduleName); + trace(state.host, ts.Diagnostics.package_json_scope_0_has_invalid_type_for_target_of_specifier_1, scope.packageDirectory, moduleName); } return toSearchResult(/*value*/ undefined); } - const resolvedTarget = combinePaths(scope.packageDirectory, target); + const resolvedTarget = ts.combinePaths(scope.packageDirectory, target); // TODO: Assert that `resolvedTarget` is actually within the package directory? That's what the spec says.... but I'm not sure we need // to be in the business of validating everyone's import and export map correctness. - const subpathParts = getPathComponents(subpath); + const subpathParts = ts.getPathComponents(subpath); if (subpathParts.indexOf("..") >= 0 || subpathParts.indexOf(".") >= 0 || subpathParts.indexOf("node_modules") >= 0) { if (state.traceEnabled) { - trace(state.host, Diagnostics.package_json_scope_0_has_invalid_type_for_target_of_specifier_1, scope.packageDirectory, moduleName); + trace(state.host, ts.Diagnostics.package_json_scope_0_has_invalid_type_for_target_of_specifier_1, scope.packageDirectory, moduleName); } return toSearchResult(/*value*/ undefined); } const finalPath = toAbsolutePath(pattern ? resolvedTarget.replace(/\*/g, subpath) : resolvedTarget + subpath); - const inputLink = tryLoadInputFileForPath(finalPath, subpath, combinePaths(scope.packageDirectory, "package.json"), isImports); - if (inputLink) return inputLink; + const inputLink = tryLoadInputFileForPath(finalPath, subpath, ts.combinePaths(scope.packageDirectory, "package.json"), isImports); + if (inputLink) + return inputLink; return toSearchResult(withPackageId(scope, loadJSOrExactTSFileName(extensions, finalPath, /*onlyRecordFailures*/ false, state))); } else if (typeof target === "object" && target !== null) { // eslint-disable-line no-null/no-null if (!Array.isArray(target)) { - for (const key of getOwnKeys(target as MapLike)) { + for (const key of ts.getOwnKeys(target as ts.MapLike)) { if (key === "default" || state.conditions.indexOf(key) >= 0 || isApplicableVersionedTypesKey(state.conditions, key)) { - const subTarget = (target as MapLike)[key]; + const subTarget = (target as ts.MapLike)[key]; const result = loadModuleFromTargetImportOrExport(subTarget, subpath, pattern); if (result) { return result; @@ -2156,9 +2100,9 @@ namespace ts { return undefined; } else { - if (!length(target)) { + if (!ts.length(target)) { if (state.traceEnabled) { - trace(state.host, Diagnostics.package_json_scope_0_has_invalid_type_for_target_of_specifier_1, scope.packageDirectory, moduleName); + trace(state.host, ts.Diagnostics.package_json_scope_0_has_invalid_type_for_target_of_specifier_1, scope.packageDirectory, moduleName); } return toSearchResult(/*value*/ undefined); } @@ -2172,24 +2116,25 @@ namespace ts { } else if (target === null) { // eslint-disable-line no-null/no-null if (state.traceEnabled) { - trace(state.host, Diagnostics.package_json_scope_0_explicitly_maps_specifier_1_to_null, scope.packageDirectory, moduleName); + trace(state.host, ts.Diagnostics.package_json_scope_0_explicitly_maps_specifier_1_to_null, scope.packageDirectory, moduleName); } return toSearchResult(/*value*/ undefined); } if (state.traceEnabled) { - trace(state.host, Diagnostics.package_json_scope_0_has_invalid_type_for_target_of_specifier_1, scope.packageDirectory, moduleName); + trace(state.host, ts.Diagnostics.package_json_scope_0_has_invalid_type_for_target_of_specifier_1, scope.packageDirectory, moduleName); } return toSearchResult(/*value*/ undefined); function toAbsolutePath(path: string): string; function toAbsolutePath(path: string | undefined): string | undefined; function toAbsolutePath(path: string | undefined): string | undefined { - if (path === undefined) return path; - return hostGetCanonicalFileName({ useCaseSensitiveFileNames })(getNormalizedAbsolutePath(path, state.host.getCurrentDirectory?.())); + if (path === undefined) + return path; + return ts.hostGetCanonicalFileName({ useCaseSensitiveFileNames })(ts.getNormalizedAbsolutePath(path, state.host.getCurrentDirectory?.())); } function combineDirectoryPath(root: string, dir: string) { - return ensureTrailingDirectorySeparator(combinePaths(root, dir)); + return ts.ensureTrailingDirectorySeparator(ts.combinePaths(root, dir)); } function useCaseSensitiveFileNames() { @@ -2207,18 +2152,17 @@ namespace ts { if ((extensions === Extensions.TypeScript || extensions === Extensions.JavaScript || extensions === Extensions.Json) && (state.compilerOptions.declarationDir || state.compilerOptions.outDir) && finalPath.indexOf("/node_modules/") === -1 - && (state.compilerOptions.configFile ? startsWith(toAbsolutePath(state.compilerOptions.configFile.fileName), scope.packageDirectory) : true) - ) { + && (state.compilerOptions.configFile ? ts.startsWith(toAbsolutePath(state.compilerOptions.configFile.fileName), scope.packageDirectory) : true)) { // So that all means we'll only try these guesses for files outside `node_modules` in a directory where the `package.json` and `tsconfig.json` are siblings. // Even with all that, we still don't know if the root of the output file structure will be (relative to the package file) // `.`, `./src` or any other deeper directory structure. (If project references are used, it's definitely `.` by fiat, so that should be pretty common.) - const getCanonicalFileName = hostGetCanonicalFileName({ useCaseSensitiveFileNames }); + const getCanonicalFileName = ts.hostGetCanonicalFileName({ useCaseSensitiveFileNames }); const commonSourceDirGuesses: string[] = []; // A `rootDir` compiler option strongly indicates the root location // A `composite` project is using project references and has it's common src dir set to `.`, so it shouldn't need to check any other locations if (state.compilerOptions.rootDir || (state.compilerOptions.composite && state.compilerOptions.configFilePath)) { - const commonDir = toAbsolutePath(getCommonSourceDirectory(state.compilerOptions, () => [], state.host.getCurrentDirectory?.() || "", getCanonicalFileName)); + const commonDir = toAbsolutePath(ts.getCommonSourceDirectory(state.compilerOptions, () => [], state.host.getCurrentDirectory?.() || "", getCanonicalFileName)); commonSourceDirGuesses.push(commonDir); } else if (state.requestContainingDirectory) { @@ -2236,7 +2180,7 @@ namespace ts { // But we do have more context! Just a tiny bit more! We're resolving an import _for some other input file_! And that input file, too // must be inside the common source directory! So we propagate that tidbit of info all the way to here via state.requestContainingDirectory - const requestingFile = toAbsolutePath(combinePaths(state.requestContainingDirectory, "index.ts")); + const requestingFile = toAbsolutePath(ts.combinePaths(state.requestContainingDirectory, "index.ts")); // And we can try every folder above the common folder for the request folder and the config/package base directory // This technically can be wrong - we may load ./src/index.ts when ./src/sub/index.ts was right because we don't // know if only `./src/sub` files were loaded by the program; but this has the best chance to be right of just about anything @@ -2244,42 +2188,39 @@ namespace ts { // be a file outside of `./src/sub` in the program (the file we resolved to), making us de-facto right. So this fallback lookup // logic may influence what files are pulled in by self-names, which in turn influences the output path shape, but it's all // internally consistent so the paths should be stable so long as we prefer the "most general" (meaning: top-most-level directory) possible results first. - const commonDir = toAbsolutePath(getCommonSourceDirectory(state.compilerOptions, () => [requestingFile, toAbsolutePath(packagePath)], state.host.getCurrentDirectory?.() || "", getCanonicalFileName)); + const commonDir = toAbsolutePath(ts.getCommonSourceDirectory(state.compilerOptions, () => [requestingFile, toAbsolutePath(packagePath)], state.host.getCurrentDirectory?.() || "", getCanonicalFileName)); commonSourceDirGuesses.push(commonDir); - let fragment = ensureTrailingDirectorySeparator(commonDir); + let fragment = ts.ensureTrailingDirectorySeparator(commonDir); while (fragment && fragment.length > 1) { - const parts = getPathComponents(fragment); + const parts = ts.getPathComponents(fragment); parts.pop(); // remove a directory - const commonDir = getPathFromPathComponents(parts); + const commonDir = ts.getPathFromPathComponents(parts); commonSourceDirGuesses.unshift(commonDir); - fragment = ensureTrailingDirectorySeparator(commonDir); + fragment = ts.ensureTrailingDirectorySeparator(commonDir); } } if (commonSourceDirGuesses.length > 1) { - state.reportDiagnostic(createCompilerDiagnostic( - isImports - ? Diagnostics.The_project_root_is_ambiguous_but_is_required_to_resolve_import_map_entry_0_in_file_1_Supply_the_rootDir_compiler_option_to_disambiguate - : Diagnostics.The_project_root_is_ambiguous_but_is_required_to_resolve_export_map_entry_0_in_file_1_Supply_the_rootDir_compiler_option_to_disambiguate, - entry === "" ? "." : entry, // replace empty string with `.` - the reverse of the operation done when entries are built - so main entrypoint errors don't look weird - packagePath - )); + state.reportDiagnostic(ts.createCompilerDiagnostic(isImports + ? ts.Diagnostics.The_project_root_is_ambiguous_but_is_required_to_resolve_import_map_entry_0_in_file_1_Supply_the_rootDir_compiler_option_to_disambiguate + : ts.Diagnostics.The_project_root_is_ambiguous_but_is_required_to_resolve_export_map_entry_0_in_file_1_Supply_the_rootDir_compiler_option_to_disambiguate, entry === "" ? "." : entry, // replace empty string with `.` - the reverse of the operation done when entries are built - so main entrypoint errors don't look weird + packagePath)); } for (const commonSourceDirGuess of commonSourceDirGuesses) { const candidateDirectories = getOutputDirectoriesForBaseDirectory(commonSourceDirGuess); for (const candidateDir of candidateDirectories) { - if (startsWith(finalPath, candidateDir)) { + if (ts.startsWith(finalPath, candidateDir)) { // The matched export is looking up something in either the out declaration or js dir, now map the written path back into the source dir and source extension const pathFragment = finalPath.slice(candidateDir.length + 1); // +1 to also remove directory seperator - const possibleInputBase = combinePaths(commonSourceDirGuess, pathFragment); - const jsAndDtsExtensions = [Extension.Mjs, Extension.Cjs, Extension.Js, Extension.Json, Extension.Dmts, Extension.Dcts, Extension.Dts]; + const possibleInputBase = ts.combinePaths(commonSourceDirGuess, pathFragment); + const jsAndDtsExtensions = [ts.Extension.Mjs, ts.Extension.Cjs, ts.Extension.Js, ts.Extension.Json, ts.Extension.Dmts, ts.Extension.Dcts, ts.Extension.Dts]; for (const ext of jsAndDtsExtensions) { - if (fileExtensionIs(possibleInputBase, ext)) { - const inputExts = getPossibleOriginalInputExtensionForExtension(possibleInputBase); + if (ts.fileExtensionIs(possibleInputBase, ext)) { + const inputExts = ts.getPossibleOriginalInputExtensionForExtension(possibleInputBase); for (const possibleExt of inputExts) { - const possibleInputWithInputExtension = changeAnyExtension(possibleInputBase, possibleExt, ext, !useCaseSensitiveFileNames()); - if ((extensions === Extensions.TypeScript && hasJSFileExtension(possibleInputWithInputExtension)) || - (extensions === Extensions.JavaScript && hasTSFileExtension(possibleInputWithInputExtension))) { + const possibleInputWithInputExtension = ts.changeAnyExtension(possibleInputBase, possibleExt, ext, !useCaseSensitiveFileNames()); + if ((extensions === Extensions.TypeScript && ts.hasJSFileExtension(possibleInputWithInputExtension)) || + (extensions === Extensions.JavaScript && ts.hasTSFileExtension(possibleInputWithInputExtension))) { continue; } if (state.host.fileExists(possibleInputWithInputExtension)) { @@ -2313,14 +2254,16 @@ namespace ts { /* @internal */ export function isApplicableVersionedTypesKey(conditions: string[], key: string) { - if (conditions.indexOf("types") === -1) return false; // only apply versioned types conditions if the types condition is applied - if (!startsWith(key, "types@")) return false; - const range = VersionRange.tryParse(key.substring("types@".length)); - if (!range) return false; - return range.test(version); - } - - function loadModuleFromNearestNodeModulesDirectory(extensions: Extensions, moduleName: string, directory: string, state: ModuleResolutionState, cache: ModuleResolutionCache | undefined, redirectedReference: ResolvedProjectReference | undefined): SearchResult { + if (conditions.indexOf("types") === -1) + return false; // only apply versioned types conditions if the types condition is applied + if (!ts.startsWith(key, "types@")) + return false; + const range = ts.VersionRange.tryParse(key.substring("types@".length)); + if (!range) + return false; + return range.test(ts.version); + } + function loadModuleFromNearestNodeModulesDirectory(extensions: Extensions, moduleName: string, directory: string, state: ModuleResolutionState, cache: ModuleResolutionCache | undefined, redirectedReference: ts.ResolvedProjectReference | undefined): SearchResult { return loadModuleFromNearestNodeModulesDirectoryWorker(extensions, moduleName, directory, state, /*typesScopeOnly*/ false, cache, redirectedReference); } @@ -2329,10 +2272,10 @@ namespace ts { return loadModuleFromNearestNodeModulesDirectoryWorker(Extensions.DtsOnly, moduleName, directory, state, /*typesScopeOnly*/ true, /*cache*/ undefined, /*redirectedReference*/ undefined); } - function loadModuleFromNearestNodeModulesDirectoryWorker(extensions: Extensions, moduleName: string, directory: string, state: ModuleResolutionState, typesScopeOnly: boolean, cache: ModuleResolutionCache | undefined, redirectedReference: ResolvedProjectReference | undefined): SearchResult { - const perModuleNameCache = cache && cache.getOrCreateCacheForModuleName(moduleName, state.features === 0 ? undefined : state.features & NodeResolutionFeatures.EsmMode ? ModuleKind.ESNext : ModuleKind.CommonJS, redirectedReference); - return forEachAncestorDirectory(normalizeSlashes(directory), ancestorDirectory => { - if (getBaseFileName(ancestorDirectory) !== "node_modules") { + function loadModuleFromNearestNodeModulesDirectoryWorker(extensions: Extensions, moduleName: string, directory: string, state: ModuleResolutionState, typesScopeOnly: boolean, cache: ModuleResolutionCache | undefined, redirectedReference: ts.ResolvedProjectReference | undefined): SearchResult { + const perModuleNameCache = cache && cache.getOrCreateCacheForModuleName(moduleName, state.features === 0 ? undefined : state.features & NodeResolutionFeatures.EsmMode ? ts.ModuleKind.ESNext : ts.ModuleKind.CommonJS, redirectedReference); + return ts.forEachAncestorDirectory(ts.normalizeSlashes(directory), ancestorDirectory => { + if (ts.getBaseFileName(ancestorDirectory) !== "node_modules") { const resolutionFromCache = tryFindNonRelativeModuleNameInCache(perModuleNameCache, moduleName, ancestorDirectory, state); if (resolutionFromCache) { return resolutionFromCache; @@ -2342,11 +2285,11 @@ namespace ts { }); } - function loadModuleFromImmediateNodeModulesDirectory(extensions: Extensions, moduleName: string, directory: string, state: ModuleResolutionState, typesScopeOnly: boolean, cache: ModuleResolutionCache | undefined, redirectedReference: ResolvedProjectReference | undefined): Resolved | undefined { - const nodeModulesFolder = combinePaths(directory, "node_modules"); - const nodeModulesFolderExists = directoryProbablyExists(nodeModulesFolder, state.host); + function loadModuleFromImmediateNodeModulesDirectory(extensions: Extensions, moduleName: string, directory: string, state: ModuleResolutionState, typesScopeOnly: boolean, cache: ModuleResolutionCache | undefined, redirectedReference: ts.ResolvedProjectReference | undefined): Resolved | undefined { + const nodeModulesFolder = ts.combinePaths(directory, "node_modules"); + const nodeModulesFolderExists = ts.directoryProbablyExists(nodeModulesFolder, state.host); if (!nodeModulesFolderExists && state.traceEnabled) { - trace(state.host, Diagnostics.Directory_0_does_not_exist_skipping_all_lookups_in_it, nodeModulesFolder); + trace(state.host, ts.Diagnostics.Directory_0_does_not_exist_skipping_all_lookups_in_it, nodeModulesFolder); } const packageResult = typesScopeOnly ? undefined : loadModuleFromSpecificNodeModulesDirectory(extensions, moduleName, nodeModulesFolder, nodeModulesFolderExists, state, cache, redirectedReference); @@ -2354,11 +2297,11 @@ namespace ts { return packageResult; } if (extensions === Extensions.TypeScript || extensions === Extensions.DtsOnly) { - const nodeModulesAtTypes = combinePaths(nodeModulesFolder, "@types"); + const nodeModulesAtTypes = ts.combinePaths(nodeModulesFolder, "@types"); let nodeModulesAtTypesExists = nodeModulesFolderExists; - if (nodeModulesFolderExists && !directoryProbablyExists(nodeModulesAtTypes, state.host)) { + if (nodeModulesFolderExists && !ts.directoryProbablyExists(nodeModulesAtTypes, state.host)) { if (state.traceEnabled) { - trace(state.host, Diagnostics.Directory_0_does_not_exist_skipping_all_lookups_in_it, nodeModulesAtTypes); + trace(state.host, ts.Diagnostics.Directory_0_does_not_exist_skipping_all_lookups_in_it, nodeModulesAtTypes); } nodeModulesAtTypesExists = false; } @@ -2366,8 +2309,8 @@ namespace ts { } } - function loadModuleFromSpecificNodeModulesDirectory(extensions: Extensions, moduleName: string, nodeModulesDirectory: string, nodeModulesDirectoryExists: boolean, state: ModuleResolutionState, cache: ModuleResolutionCache | undefined, redirectedReference: ResolvedProjectReference | undefined): Resolved | undefined { - const candidate = normalizePath(combinePaths(nodeModulesDirectory, moduleName)); + function loadModuleFromSpecificNodeModulesDirectory(extensions: Extensions, moduleName: string, nodeModulesDirectory: string, nodeModulesDirectoryExists: boolean, state: ModuleResolutionState, cache: ModuleResolutionCache | undefined, redirectedReference: ts.ResolvedProjectReference | undefined): Resolved | undefined { + const candidate = ts.normalizePath(ts.combinePaths(nodeModulesDirectory, moduleName)); // First look for a nested package.json, as in `node_modules/foo/bar/package.json`. let packageInfo = getPackageJsonInfo(candidate, !nodeModulesDirectoryExists, state); @@ -2379,14 +2322,7 @@ namespace ts { return noPackageId(fromFile); } - const fromDirectory = loadNodeModuleFromDirectoryWorker( - extensions, - candidate, - !nodeModulesDirectoryExists, - state, - packageInfo.packageJsonContent, - packageInfo.versionPaths - ); + const fromDirectory = loadNodeModuleFromDirectoryWorker(extensions, candidate, !nodeModulesDirectoryExists, state, packageInfo.packageJsonContent, packageInfo.versionPaths); return withPackageId(packageInfo, fromDirectory); } } @@ -2395,41 +2331,31 @@ namespace ts { const loader: ResolutionKindSpecificLoader = (extensions, candidate, onlyRecordFailures, state) => { // package exports are higher priority than file/directory lookups (and, if there's exports present, blocks them) if (packageInfo && packageInfo.packageJsonContent.exports && state.features & NodeResolutionFeatures.Exports) { - return loadModuleFromExports(packageInfo, extensions, combinePaths(".", rest), state, cache, redirectedReference)?.value; - } - let pathAndExtension = - loadModuleFromFile(extensions, candidate, onlyRecordFailures, state) || - loadNodeModuleFromDirectoryWorker( - extensions, - candidate, - onlyRecordFailures, - state, - packageInfo && packageInfo.packageJsonContent, - packageInfo && packageInfo.versionPaths - ); - if ( - !pathAndExtension && packageInfo + return loadModuleFromExports(packageInfo, extensions, ts.combinePaths(".", rest), state, cache, redirectedReference)?.value; + } + let pathAndExtension = loadModuleFromFile(extensions, candidate, onlyRecordFailures, state) || + loadNodeModuleFromDirectoryWorker(extensions, candidate, onlyRecordFailures, state, packageInfo && packageInfo.packageJsonContent, packageInfo && packageInfo.versionPaths); + if (!pathAndExtension && packageInfo && packageInfo.packageJsonContent.exports === undefined && packageInfo.packageJsonContent.main === undefined - && state.features & NodeResolutionFeatures.EsmMode - ) { + && state.features & NodeResolutionFeatures.EsmMode) { // EsmMode disables index lookup in `loadNodeModuleFromDirectoryWorker` generally, however non-relative package resolutions still assume // a default `index.js` entrypoint if no `main` or `exports` are present - pathAndExtension = loadModuleFromFile(extensions, combinePaths(candidate, "index.js"), onlyRecordFailures, state); + pathAndExtension = loadModuleFromFile(extensions, ts.combinePaths(candidate, "index.js"), onlyRecordFailures, state); } return withPackageId(packageInfo, pathAndExtension); }; if (rest !== "") { // If "rest" is empty, we just did this search above. - const packageDirectory = combinePaths(nodeModulesDirectory, packageName); + const packageDirectory = ts.combinePaths(nodeModulesDirectory, packageName); // Don't use a "types" or "main" from here because we're not loading the root, but a subdirectory -- just here for the packageId and path mappings. packageInfo = getPackageJsonInfo(packageDirectory, !nodeModulesDirectoryExists, state); if (packageInfo && packageInfo.versionPaths) { if (state.traceEnabled) { - trace(state.host, Diagnostics.package_json_has_a_typesVersions_entry_0_that_matches_compiler_version_1_looking_for_a_pattern_to_match_module_name_2, packageInfo.versionPaths.version, version, rest); + trace(state.host, ts.Diagnostics.package_json_has_a_typesVersions_entry_0_that_matches_compiler_version_1_looking_for_a_pattern_to_match_module_name_2, packageInfo.versionPaths.version, ts.version, rest); } - const packageDirectoryExists = nodeModulesDirectoryExists && directoryProbablyExists(packageDirectory, state.host); + const packageDirectoryExists = nodeModulesDirectoryExists && ts.directoryProbablyExists(packageDirectory, state.host); const fromPaths = tryLoadModuleUsingPaths(extensions, rest, packageDirectory, packageInfo.versionPaths.paths, /*pathPatterns*/ undefined, loader, !packageDirectoryExists, state); if (fromPaths) { return fromPaths.value; @@ -2440,31 +2366,31 @@ namespace ts { return loader(extensions, candidate, !nodeModulesDirectoryExists, state); } - function tryLoadModuleUsingPaths(extensions: Extensions, moduleName: string, baseDirectory: string, paths: MapLike, pathPatterns: readonly (string | Pattern)[] | undefined, loader: ResolutionKindSpecificLoader, onlyRecordFailures: boolean, state: ModuleResolutionState): SearchResult { - pathPatterns ||= tryParsePatterns(paths); - const matchedPattern = matchPatternOrExact(pathPatterns, moduleName); + function tryLoadModuleUsingPaths(extensions: Extensions, moduleName: string, baseDirectory: string, paths: ts.MapLike, pathPatterns: readonly (string | ts.Pattern)[] | undefined, loader: ResolutionKindSpecificLoader, onlyRecordFailures: boolean, state: ModuleResolutionState): SearchResult { + pathPatterns ||= ts.tryParsePatterns(paths); + const matchedPattern = ts.matchPatternOrExact(pathPatterns, moduleName); if (matchedPattern) { - const matchedStar = isString(matchedPattern) ? undefined : matchedText(matchedPattern, moduleName); - const matchedPatternText = isString(matchedPattern) ? matchedPattern : patternText(matchedPattern); + const matchedStar = ts.isString(matchedPattern) ? undefined : ts.matchedText(matchedPattern, moduleName); + const matchedPatternText = ts.isString(matchedPattern) ? matchedPattern : ts.patternText(matchedPattern); if (state.traceEnabled) { - trace(state.host, Diagnostics.Module_name_0_matched_pattern_1, moduleName, matchedPatternText); + trace(state.host, ts.Diagnostics.Module_name_0_matched_pattern_1, moduleName, matchedPatternText); } - const resolved = forEach(paths[matchedPatternText], subst => { + const resolved = ts.forEach(paths[matchedPatternText], subst => { const path = matchedStar ? subst.replace("*", matchedStar) : subst; // When baseUrl is not specified, the command line parser resolves relative paths to the config file location. - const candidate = normalizePath(combinePaths(baseDirectory, path)); + const candidate = ts.normalizePath(ts.combinePaths(baseDirectory, path)); if (state.traceEnabled) { - trace(state.host, Diagnostics.Trying_substitution_0_candidate_module_location_Colon_1, subst, path); + trace(state.host, ts.Diagnostics.Trying_substitution_0_candidate_module_location_Colon_1, subst, path); } // A path mapping may have an extension, in contrast to an import, which should omit it. - const extension = tryGetExtensionFromPath(subst); + const extension = ts.tryGetExtensionFromPath(subst); if (extension !== undefined) { const path = tryFile(candidate, onlyRecordFailures, state); if (path !== undefined) { return noPackageId({ path, ext: extension }); } } - return loader(extensions, candidate, onlyRecordFailures || !directoryProbablyExists(getDirectoryPath(candidate), state.host), state); + return loader(extensions, candidate, onlyRecordFailures || !ts.directoryProbablyExists(ts.getDirectoryPath(candidate), state.host), state); }); return { value: resolved }; } @@ -2477,7 +2403,7 @@ namespace ts { function mangleScopedPackageNameWithTrace(packageName: string, state: ModuleResolutionState): string { const mangled = mangleScopedPackageName(packageName); if (state.traceEnabled && mangled !== packageName) { - trace(state.host, Diagnostics.Scoped_package_detected_looking_in_0, mangled); + trace(state.host, ts.Diagnostics.Scoped_package_detected_looking_in_0, mangled); } return mangled; } @@ -2489,8 +2415,8 @@ namespace ts { /* @internal */ export function mangleScopedPackageName(packageName: string): string { - if (startsWith(packageName, "@")) { - const replaceSlash = packageName.replace(directorySeparator, mangledScopedPackageSeparator); + if (ts.startsWith(packageName, "@")) { + const replaceSlash = packageName.replace(ts.directorySeparator, mangledScopedPackageSeparator); if (replaceSlash !== packageName) { return replaceSlash.slice(1); // Take off the "@" } @@ -2500,7 +2426,7 @@ namespace ts { /* @internal */ export function getPackageNameFromTypesPackageName(mangledName: string): string { - const withoutAtTypePrefix = removePrefix(mangledName, "@types/"); + const withoutAtTypePrefix = ts.removePrefix(mangledName, "@types/"); if (withoutAtTypePrefix !== mangledName) { return unmangleScopedPackageName(withoutAtTypePrefix); } @@ -2509,8 +2435,8 @@ namespace ts { /* @internal */ export function unmangleScopedPackageName(typesPackageName: string): string { - return stringContains(typesPackageName, mangledScopedPackageSeparator) ? - "@" + typesPackageName.replace(mangledScopedPackageSeparator, directorySeparator) : + return ts.stringContains(typesPackageName, mangledScopedPackageSeparator) ? + "@" + typesPackageName.replace(mangledScopedPackageSeparator, ts.directorySeparator) : typesPackageName; } @@ -2518,18 +2444,18 @@ namespace ts { const result = cache && cache.get(containingDirectory); if (result) { if (state.traceEnabled) { - trace(state.host, Diagnostics.Resolution_for_module_0_was_found_in_cache_from_location_1, moduleName, containingDirectory); + trace(state.host, ts.Diagnostics.Resolution_for_module_0_was_found_in_cache_from_location_1, moduleName, containingDirectory); } state.resultFromCache = result; return { value: result.resolvedModule && { path: result.resolvedModule.resolvedFileName, originalPath: result.resolvedModule.originalPath || true, extension: result.resolvedModule.extension, packageId: result.resolvedModule.packageId } }; } } - export function classicNameResolver(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost, cache?: NonRelativeModuleNameResolutionCache, redirectedReference?: ResolvedProjectReference): ResolvedModuleWithFailedLookupLocations { + export function classicNameResolver(moduleName: string, containingFile: string, compilerOptions: ts.CompilerOptions, host: ts.ModuleResolutionHost, cache?: NonRelativeModuleNameResolutionCache, redirectedReference?: ts.ResolvedProjectReference): ts.ResolvedModuleWithFailedLookupLocations { const traceEnabled = isTraceEnabled(compilerOptions, host); const failedLookupLocations: string[] = []; - const containingDirectory = getDirectoryPath(containingFile); - const diagnostics: Diagnostic[] = []; + const containingDirectory = ts.getDirectoryPath(containingFile); + const diagnostics: ts.Diagnostic[] = []; const state: ModuleResolutionState = { compilerOptions, host, traceEnabled, failedLookupLocations, packageJsonInfoCache: cache, features: NodeResolutionFeatures.None, conditions: [], requestContainingDirectory: containingDirectory, reportDiagnostic: diag => void diagnostics.push(diag) }; const resolved = tryResolve(Extensions.TypeScript) || tryResolve(Extensions.JavaScript); @@ -2542,15 +2468,15 @@ namespace ts { return { value: resolvedUsingSettings }; } - if (!isExternalModuleNameRelative(moduleName)) { + if (!ts.isExternalModuleNameRelative(moduleName)) { const perModuleNameCache = cache && cache.getOrCreateCacheForModuleName(moduleName, /*mode*/ undefined, redirectedReference); // Climb up parent directories looking for a module. - const resolved = forEachAncestorDirectory(containingDirectory, directory => { + const resolved = ts.forEachAncestorDirectory(containingDirectory, directory => { const resolutionFromCache = tryFindNonRelativeModuleNameInCache(perModuleNameCache, moduleName, directory, state); if (resolutionFromCache) { return resolutionFromCache; } - const searchName = normalizePath(combinePaths(directory, moduleName)); + const searchName = ts.normalizePath(ts.combinePaths(directory, moduleName)); return toSearchResult(loadModuleFromFileNoPackageId(extensions, searchName, /*onlyRecordFailures*/ false, state)); }); if (resolved) { @@ -2562,7 +2488,7 @@ namespace ts { } } else { - const candidate = normalizePath(combinePaths(containingDirectory, moduleName)); + const candidate = ts.normalizePath(ts.combinePaths(containingDirectory, moduleName)); return toSearchResult(loadModuleFromFileNoPackageId(extensions, candidate, /*onlyRecordFailures*/ false, state)); } } @@ -2573,13 +2499,13 @@ namespace ts { * This is the minumum code needed to expose that functionality; the rest is in the host. */ /* @internal */ - export function loadModuleFromGlobalCache(moduleName: string, projectName: string | undefined, compilerOptions: CompilerOptions, host: ModuleResolutionHost, globalCache: string, packageJsonInfoCache: PackageJsonInfoCache): ResolvedModuleWithFailedLookupLocations { + export function loadModuleFromGlobalCache(moduleName: string, projectName: string | undefined, compilerOptions: ts.CompilerOptions, host: ts.ModuleResolutionHost, globalCache: string, packageJsonInfoCache: PackageJsonInfoCache): ts.ResolvedModuleWithFailedLookupLocations { const traceEnabled = isTraceEnabled(compilerOptions, host); if (traceEnabled) { - trace(host, Diagnostics.Auto_discovery_for_typings_is_enabled_in_project_0_Running_extra_resolution_pass_for_module_1_using_cache_location_2, projectName, moduleName, globalCache); + trace(host, ts.Diagnostics.Auto_discovery_for_typings_is_enabled_in_project_0_Running_extra_resolution_pass_for_module_1_using_cache_location_2, projectName, moduleName, globalCache); } const failedLookupLocations: string[] = []; - const diagnostics: Diagnostic[] = []; + const diagnostics: ts.Diagnostic[] = []; const state: ModuleResolutionState = { compilerOptions, host, traceEnabled, failedLookupLocations, packageJsonInfoCache, features: NodeResolutionFeatures.None, conditions: [], requestContainingDirectory: undefined, reportDiagnostic: diag => void diagnostics.push(diag) }; const resolved = loadModuleFromImmediateNodeModulesDirectory(Extensions.DtsOnly, moduleName, globalCache, state, /*typesScopeOnly*/ false, /*cache*/ undefined, /*redirectedReference*/ undefined); return createResolvedModuleWithFailedLookupLocations(resolved, /*isExternalLibraryImport*/ true, failedLookupLocations, diagnostics, state.resultFromCache); @@ -2594,7 +2520,9 @@ namespace ts { * - { value: undefined } - not found - stop searching * - { value: } - found - stop searching */ - type SearchResult = { value: T | undefined } | undefined; + type SearchResult = { + value: T | undefined; + } | undefined; /** * Wraps value to SearchResult. diff --git a/src/compiler/moduleSpecifiers.ts b/src/compiler/moduleSpecifiers.ts index 44d20c9ff59ef..40451fd75313a 100644 --- a/src/compiler/moduleSpecifiers.ts +++ b/src/compiler/moduleSpecifiers.ts @@ -1,9 +1,18 @@ // Used by importFixes, getEditsForFileRename, and declaration emit to synthesize import module specifiers. /* @internal */ namespace ts.moduleSpecifiers { - const enum RelativePreference { Relative, NonRelative, Shortest, ExternalNonRelative } + const enum RelativePreference { + Relative, + NonRelative, + Shortest, + ExternalNonRelative + } // See UserPreferences#importPathEnding - const enum Ending { Minimal, Index, JsExtension } + const enum Ending { + Minimal, + Index, + JsExtension + } // Processed preferences interface Preferences { @@ -11,10 +20,9 @@ namespace ts.moduleSpecifiers { readonly ending: Ending; } - function getPreferences(host: ModuleSpecifierResolutionHost, { importModuleSpecifierPreference, importModuleSpecifierEnding }: UserPreferences, compilerOptions: CompilerOptions, importingSourceFile: SourceFile): Preferences { + function getPreferences(host: ts.ModuleSpecifierResolutionHost, { importModuleSpecifierPreference, importModuleSpecifierEnding }: ts.UserPreferences, compilerOptions: ts.CompilerOptions, importingSourceFile: ts.SourceFile): Preferences { return { - relativePreference: - importModuleSpecifierPreference === "relative" ? RelativePreference.Relative : + relativePreference: importModuleSpecifierPreference === "relative" ? RelativePreference.Relative : importModuleSpecifierPreference === "non-relative" ? RelativePreference.NonRelative : importModuleSpecifierPreference === "project-relative" ? RelativePreference.ExternalNonRelative : RelativePreference.Shortest, @@ -26,32 +34,32 @@ namespace ts.moduleSpecifiers { case "index": return Ending.Index; case "js": return Ending.JsExtension; default: return usesJsExtensionOnImports(importingSourceFile) || isFormatRequiringExtensions(compilerOptions, importingSourceFile.path, host) ? Ending.JsExtension - : getEmitModuleResolutionKind(compilerOptions) !== ModuleResolutionKind.NodeJs ? Ending.Index : Ending.Minimal; + : ts.getEmitModuleResolutionKind(compilerOptions) !== ts.ModuleResolutionKind.NodeJs ? Ending.Index : Ending.Minimal; } } } - function getPreferencesForUpdate(compilerOptions: CompilerOptions, oldImportSpecifier: string, importingSourceFileName: Path, host: ModuleSpecifierResolutionHost): Preferences { + function getPreferencesForUpdate(compilerOptions: ts.CompilerOptions, oldImportSpecifier: string, importingSourceFileName: ts.Path, host: ts.ModuleSpecifierResolutionHost): Preferences { return { - relativePreference: isExternalModuleNameRelative(oldImportSpecifier) ? RelativePreference.Relative : RelativePreference.NonRelative, - ending: hasJSFileExtension(oldImportSpecifier) || isFormatRequiringExtensions(compilerOptions, importingSourceFileName, host) ? + relativePreference: ts.isExternalModuleNameRelative(oldImportSpecifier) ? RelativePreference.Relative : RelativePreference.NonRelative, + ending: ts.hasJSFileExtension(oldImportSpecifier) || isFormatRequiringExtensions(compilerOptions, importingSourceFileName, host) ? Ending.JsExtension : - getEmitModuleResolutionKind(compilerOptions) !== ModuleResolutionKind.NodeJs || endsWith(oldImportSpecifier, "index") ? Ending.Index : Ending.Minimal, + ts.getEmitModuleResolutionKind(compilerOptions) !== ts.ModuleResolutionKind.NodeJs || ts.endsWith(oldImportSpecifier, "index") ? Ending.Index : Ending.Minimal, }; } - function isFormatRequiringExtensions(compilerOptions: CompilerOptions, importingSourceFileName: Path, host: ModuleSpecifierResolutionHost) { - if (getEmitModuleResolutionKind(compilerOptions) !== ModuleResolutionKind.Node16 - && getEmitModuleResolutionKind(compilerOptions) !== ModuleResolutionKind.NodeNext) { + function isFormatRequiringExtensions(compilerOptions: ts.CompilerOptions, importingSourceFileName: ts.Path, host: ts.ModuleSpecifierResolutionHost) { + if (ts.getEmitModuleResolutionKind(compilerOptions) !== ts.ModuleResolutionKind.Node16 + && ts.getEmitModuleResolutionKind(compilerOptions) !== ts.ModuleResolutionKind.NodeNext) { return false; } - return getImpliedNodeFormatForFile(importingSourceFileName, host.getPackageJsonInfoCache?.(), getModuleResolutionHost(host), compilerOptions) !== ModuleKind.CommonJS; + return ts.getImpliedNodeFormatForFile(importingSourceFileName, host.getPackageJsonInfoCache?.(), getModuleResolutionHost(host), compilerOptions) !== ts.ModuleKind.CommonJS; } - function getModuleResolutionHost(host: ModuleSpecifierResolutionHost): ModuleResolutionHost { + function getModuleResolutionHost(host: ts.ModuleSpecifierResolutionHost): ts.ModuleResolutionHost { return { fileExists: host.fileExists, - readFile: Debug.checkDefined(host.readFile), + readFile: ts.Debug.checkDefined(host.readFile), directoryExists: host.directoryExists, getCurrentDirectory: host.getCurrentDirectory, realpath: host.realpath, @@ -63,17 +71,10 @@ namespace ts.moduleSpecifiers { // Because when this is called by the file renamer, `importingSourceFile` is the file being renamed, // while `importingSourceFileName` its *new* name. We need a source file just to get its // `impliedNodeFormat` and to detect certain preferences from existing import module specifiers. - export function updateModuleSpecifier( - compilerOptions: CompilerOptions, - importingSourceFile: SourceFile, - importingSourceFileName: Path, - toFileName: string, - host: ModuleSpecifierResolutionHost, - oldImportSpecifier: string, - options: ModuleSpecifierOptions = {}, - ): string | undefined { + export function updateModuleSpecifier(compilerOptions: ts.CompilerOptions, importingSourceFile: ts.SourceFile, importingSourceFileName: ts.Path, toFileName: string, host: ts.ModuleSpecifierResolutionHost, oldImportSpecifier: string, options: ts.ModuleSpecifierOptions = {}): string | undefined { const res = getModuleSpecifierWorker(compilerOptions, importingSourceFile, importingSourceFileName, toFileName, host, getPreferencesForUpdate(compilerOptions, oldImportSpecifier, importingSourceFileName, host), {}, options); - if (res === oldImportSpecifier) return undefined; + if (res === oldImportSpecifier) + return undefined; return res; } @@ -83,72 +84,35 @@ namespace ts.moduleSpecifiers { // one currently being produced; the latter to the one being imported). We need an implementation file // just to get its `impliedNodeFormat` and to detect certain preferences from existing import module // specifiers. - export function getModuleSpecifier( - compilerOptions: CompilerOptions, - importingSourceFile: SourceFile, - importingSourceFileName: Path, - toFileName: string, - host: ModuleSpecifierResolutionHost, - options: ModuleSpecifierOptions = {}, - ): string { + export function getModuleSpecifier(compilerOptions: ts.CompilerOptions, importingSourceFile: ts.SourceFile, importingSourceFileName: ts.Path, toFileName: string, host: ts.ModuleSpecifierResolutionHost, options: ts.ModuleSpecifierOptions = {}): string { return getModuleSpecifierWorker(compilerOptions, importingSourceFile, importingSourceFileName, toFileName, host, getPreferences(host, {}, compilerOptions, importingSourceFile), {}, options); } - export function getNodeModulesPackageName( - compilerOptions: CompilerOptions, - importingSourceFile: SourceFile, - nodeModulesFileName: string, - host: ModuleSpecifierResolutionHost, - preferences: UserPreferences, - options: ModuleSpecifierOptions = {}, - ): string | undefined { + export function getNodeModulesPackageName(compilerOptions: ts.CompilerOptions, importingSourceFile: ts.SourceFile, nodeModulesFileName: string, host: ts.ModuleSpecifierResolutionHost, preferences: ts.UserPreferences, options: ts.ModuleSpecifierOptions = {}): string | undefined { const info = getInfo(importingSourceFile.path, host); const modulePaths = getAllModulePaths(importingSourceFile.path, nodeModulesFileName, host, preferences, options); - return firstDefined(modulePaths, - modulePath => tryGetModuleNameAsNodeModule(modulePath, info, importingSourceFile, host, compilerOptions, preferences, /*packageNameOnly*/ true, options.overrideImportMode)); - } - - function getModuleSpecifierWorker( - compilerOptions: CompilerOptions, - importingSourceFile: SourceFile, - importingSourceFileName: Path, - toFileName: string, - host: ModuleSpecifierResolutionHost, - preferences: Preferences, - userPreferences: UserPreferences, - options: ModuleSpecifierOptions = {} - ): string { + return ts.firstDefined(modulePaths, modulePath => tryGetModuleNameAsNodeModule(modulePath, info, importingSourceFile, host, compilerOptions, preferences, /*packageNameOnly*/ true, options.overrideImportMode)); + } + function getModuleSpecifierWorker(compilerOptions: ts.CompilerOptions, importingSourceFile: ts.SourceFile, importingSourceFileName: ts.Path, toFileName: string, host: ts.ModuleSpecifierResolutionHost, preferences: Preferences, userPreferences: ts.UserPreferences, options: ts.ModuleSpecifierOptions = {}): string { const info = getInfo(importingSourceFileName, host); const modulePaths = getAllModulePaths(importingSourceFileName, toFileName, host, userPreferences, options); - return firstDefined(modulePaths, modulePath => tryGetModuleNameAsNodeModule(modulePath, info, importingSourceFile, host, compilerOptions, userPreferences, /*packageNameOnly*/ undefined, options.overrideImportMode)) || + return ts.firstDefined(modulePaths, modulePath => tryGetModuleNameAsNodeModule(modulePath, info, importingSourceFile, host, compilerOptions, userPreferences, /*packageNameOnly*/ undefined, options.overrideImportMode)) || getLocalModuleSpecifier(toFileName, info, compilerOptions, host, preferences); } - export function tryGetModuleSpecifiersFromCache( - moduleSymbol: Symbol, - importingSourceFile: SourceFile, - host: ModuleSpecifierResolutionHost, - userPreferences: UserPreferences, - options: ModuleSpecifierOptions = {}, - ): readonly string[] | undefined { - return tryGetModuleSpecifiersFromCacheWorker( - moduleSymbol, - importingSourceFile, - host, - userPreferences, - options)[0]; - } - - function tryGetModuleSpecifiersFromCacheWorker( - moduleSymbol: Symbol, - importingSourceFile: SourceFile, - host: ModuleSpecifierResolutionHost, - userPreferences: UserPreferences, - options: ModuleSpecifierOptions = {}, - ): readonly [specifiers?: readonly string[], moduleFile?: SourceFile, modulePaths?: readonly ModulePath[], cache?: ModuleSpecifierCache] { - const moduleSourceFile = getSourceFileOfModule(moduleSymbol); + export function tryGetModuleSpecifiersFromCache(moduleSymbol: ts.Symbol, importingSourceFile: ts.SourceFile, host: ts.ModuleSpecifierResolutionHost, userPreferences: ts.UserPreferences, options: ts.ModuleSpecifierOptions = {}): readonly string[] | undefined { + return tryGetModuleSpecifiersFromCacheWorker(moduleSymbol, importingSourceFile, host, userPreferences, options)[0]; + } + function tryGetModuleSpecifiersFromCacheWorker(moduleSymbol: ts.Symbol, importingSourceFile: ts.SourceFile, host: ts.ModuleSpecifierResolutionHost, userPreferences: ts.UserPreferences, options: ts.ModuleSpecifierOptions = {}): readonly [ + specifiers?: readonly string[], + moduleFile?: ts.SourceFile, + modulePaths?: readonly ts.ModulePath[], + cache?: ts.ModuleSpecifierCache + ] { + const moduleSourceFile = ts.getSourceFileOfModule(moduleSymbol); if (!moduleSourceFile) { - return emptyArray as []; + return ts.emptyArray as [ + ]; } const cache = host.getModuleSpecifierCache?.(); @@ -157,49 +121,24 @@ namespace ts.moduleSpecifiers { } /** Returns an import for each symlink and for the realpath. */ - export function getModuleSpecifiers( - moduleSymbol: Symbol, - checker: TypeChecker, - compilerOptions: CompilerOptions, - importingSourceFile: SourceFile, - host: ModuleSpecifierResolutionHost, - userPreferences: UserPreferences, - options: ModuleSpecifierOptions = {}, - ): readonly string[] { - return getModuleSpecifiersWithCacheInfo( - moduleSymbol, - checker, - compilerOptions, - importingSourceFile, - host, - userPreferences, - options - ).moduleSpecifiers; - } - - export function getModuleSpecifiersWithCacheInfo( - moduleSymbol: Symbol, - checker: TypeChecker, - compilerOptions: CompilerOptions, - importingSourceFile: SourceFile, - host: ModuleSpecifierResolutionHost, - userPreferences: UserPreferences, - options: ModuleSpecifierOptions = {}, - ): { moduleSpecifiers: readonly string[], computedWithoutCache: boolean } { + export function getModuleSpecifiers(moduleSymbol: ts.Symbol, checker: ts.TypeChecker, compilerOptions: ts.CompilerOptions, importingSourceFile: ts.SourceFile, host: ts.ModuleSpecifierResolutionHost, userPreferences: ts.UserPreferences, options: ts.ModuleSpecifierOptions = {}): readonly string[] { + return getModuleSpecifiersWithCacheInfo(moduleSymbol, checker, compilerOptions, importingSourceFile, host, userPreferences, options).moduleSpecifiers; + } + export function getModuleSpecifiersWithCacheInfo(moduleSymbol: ts.Symbol, checker: ts.TypeChecker, compilerOptions: ts.CompilerOptions, importingSourceFile: ts.SourceFile, host: ts.ModuleSpecifierResolutionHost, userPreferences: ts.UserPreferences, options: ts.ModuleSpecifierOptions = {}): { + moduleSpecifiers: readonly string[]; + computedWithoutCache: boolean; + } { let computedWithoutCache = false; const ambient = tryGetModuleNameFromAmbientModule(moduleSymbol, checker); - if (ambient) return { moduleSpecifiers: [ambient], computedWithoutCache }; + if (ambient) + return { moduleSpecifiers: [ambient], computedWithoutCache }; // eslint-disable-next-line prefer-const - let [specifiers, moduleSourceFile, modulePaths, cache] = tryGetModuleSpecifiersFromCacheWorker( - moduleSymbol, - importingSourceFile, - host, - userPreferences, - options - ); - if (specifiers) return { moduleSpecifiers: specifiers, computedWithoutCache }; - if (!moduleSourceFile) return { moduleSpecifiers: emptyArray, computedWithoutCache }; + let [specifiers, moduleSourceFile, modulePaths, cache] = tryGetModuleSpecifiersFromCacheWorker(moduleSymbol, importingSourceFile, host, userPreferences, options); + if (specifiers) + return { moduleSpecifiers: specifiers, computedWithoutCache }; + if (!moduleSourceFile) + return { moduleSpecifiers: ts.emptyArray, computedWithoutCache }; computedWithoutCache = true; modulePaths ||= getAllModulePathsWorker(importingSourceFile.path, moduleSourceFile.originalFileName, host); @@ -208,36 +147,28 @@ namespace ts.moduleSpecifiers { return { moduleSpecifiers: result, computedWithoutCache }; } - function computeModuleSpecifiers( - modulePaths: readonly ModulePath[], - compilerOptions: CompilerOptions, - importingSourceFile: SourceFile, - host: ModuleSpecifierResolutionHost, - userPreferences: UserPreferences, - options: ModuleSpecifierOptions = {}, - ): readonly string[] { + function computeModuleSpecifiers(modulePaths: readonly ts.ModulePath[], compilerOptions: ts.CompilerOptions, importingSourceFile: ts.SourceFile, host: ts.ModuleSpecifierResolutionHost, userPreferences: ts.UserPreferences, options: ts.ModuleSpecifierOptions = {}): readonly string[] { const info = getInfo(importingSourceFile.path, host); const preferences = getPreferences(host, userPreferences, compilerOptions, importingSourceFile); - const existingSpecifier = forEach(modulePaths, modulePath => forEach( - host.getFileIncludeReasons().get(toPath(modulePath.path, host.getCurrentDirectory(), info.getCanonicalFileName)), - reason => { - if (reason.kind !== FileIncludeKind.Import || reason.file !== importingSourceFile.path) return undefined; + const existingSpecifier = ts.forEach(modulePaths, modulePath => ts.forEach(host.getFileIncludeReasons().get(ts.toPath(modulePath.path, host.getCurrentDirectory(), info.getCanonicalFileName)), reason => { + if (reason.kind !== ts.FileIncludeKind.Import || reason.file !== importingSourceFile.path) + return undefined; // If the candidate import mode doesn't match the mode we're generating for, don't consider it // TODO: maybe useful to keep around as an alternative option for certain contexts where the mode is overridable - if (importingSourceFile.impliedNodeFormat && importingSourceFile.impliedNodeFormat !== getModeForResolutionAtIndex(importingSourceFile, reason.index)) return undefined; - const specifier = getModuleNameStringLiteralAt(importingSourceFile, reason.index).text; + if (importingSourceFile.impliedNodeFormat && importingSourceFile.impliedNodeFormat !== ts.getModeForResolutionAtIndex(importingSourceFile, reason.index)) + return undefined; + const specifier = ts.getModuleNameStringLiteralAt(importingSourceFile, reason.index).text; // If the preference is for non relative and the module specifier is relative, ignore it - return preferences.relativePreference !== RelativePreference.NonRelative || !pathIsRelative(specifier) ? + return preferences.relativePreference !== RelativePreference.NonRelative || !ts.pathIsRelative(specifier) ? specifier : undefined; - } - )); + })); if (existingSpecifier) { const moduleSpecifiers = [existingSpecifier]; return moduleSpecifiers; } - const importedFileIsInNodeModules = some(modulePaths, p => p.isInNodeModules); + const importedFileIsInNodeModules = ts.some(modulePaths, p => p.isInNodeModules); // Module specifier priority: // 1. "Bare package specifiers" (e.g. "@foo/bar") resulting from a path through node_modules to a package.json's "types" entry @@ -249,7 +180,7 @@ namespace ts.moduleSpecifiers { let relativeSpecifiers: string[] | undefined; for (const modulePath of modulePaths) { const specifier = tryGetModuleNameAsNodeModule(modulePath, info, importingSourceFile, host, compilerOptions, userPreferences, /*packageNameOnly*/ undefined, options.overrideImportMode); - nodeModulesSpecifiers = append(nodeModulesSpecifiers, specifier); + nodeModulesSpecifiers = ts.append(nodeModulesSpecifiers, specifier); if (specifier && modulePath.isRedirect) { // If we got a specifier for a redirect, it was a bare package specifier (e.g. "@foo/bar", // not "@foo/bar/path/to/file"). No other specifier will be this good, so stop looking. @@ -258,8 +189,8 @@ namespace ts.moduleSpecifiers { if (!specifier && !modulePath.isRedirect) { const local = getLocalModuleSpecifier(modulePath.path, info, compilerOptions, host, preferences); - if (pathIsBareSpecifier(local)) { - pathsSpecifiers = append(pathsSpecifiers, local); + if (ts.pathIsBareSpecifier(local)) { + pathsSpecifiers = ts.append(pathsSpecifiers, local); } else if (!importedFileIsInNodeModules || modulePath.isInNodeModules) { // Why this extra conditional, not just an `else`? If some path to the file contained @@ -271,45 +202,45 @@ namespace ts.moduleSpecifiers { // in a monorepo is probably not portable. So, the module specifier we actually go with will be // the relative path through node_modules, so that the declaration emitter can produce a // portability error. (See declarationEmitReexportedSymlinkReference3) - relativeSpecifiers = append(relativeSpecifiers, local); + relativeSpecifiers = ts.append(relativeSpecifiers, local); } } } return pathsSpecifiers?.length ? pathsSpecifiers : nodeModulesSpecifiers?.length ? nodeModulesSpecifiers : - Debug.checkDefined(relativeSpecifiers); + ts.Debug.checkDefined(relativeSpecifiers); } interface Info { - readonly getCanonicalFileName: GetCanonicalFileName; - readonly importingSourceFileName: Path - readonly sourceDirectory: Path; + readonly getCanonicalFileName: ts.GetCanonicalFileName; + readonly importingSourceFileName: ts.Path; + readonly sourceDirectory: ts.Path; } // importingSourceFileName is separate because getEditsForFileRename may need to specify an updated path - function getInfo(importingSourceFileName: Path, host: ModuleSpecifierResolutionHost): Info { - const getCanonicalFileName = createGetCanonicalFileName(host.useCaseSensitiveFileNames ? host.useCaseSensitiveFileNames() : true); - const sourceDirectory = getDirectoryPath(importingSourceFileName); + function getInfo(importingSourceFileName: ts.Path, host: ts.ModuleSpecifierResolutionHost): Info { + const getCanonicalFileName = ts.createGetCanonicalFileName(host.useCaseSensitiveFileNames ? host.useCaseSensitiveFileNames() : true); + const sourceDirectory = ts.getDirectoryPath(importingSourceFileName); return { getCanonicalFileName, importingSourceFileName, sourceDirectory }; } - function getLocalModuleSpecifier(moduleFileName: string, info: Info, compilerOptions: CompilerOptions, host: ModuleSpecifierResolutionHost, { ending, relativePreference }: Preferences): string { + function getLocalModuleSpecifier(moduleFileName: string, info: Info, compilerOptions: ts.CompilerOptions, host: ts.ModuleSpecifierResolutionHost, { ending, relativePreference }: Preferences): string { const { baseUrl, paths, rootDirs } = compilerOptions; const { sourceDirectory, getCanonicalFileName } = info; const relativePath = rootDirs && tryGetModuleNameFromRootDirs(rootDirs, moduleFileName, sourceDirectory, getCanonicalFileName, ending, compilerOptions) || - removeExtensionAndIndexPostFix(ensurePathIsNonModuleName(getRelativePathFromDirectory(sourceDirectory, moduleFileName, getCanonicalFileName)), ending, compilerOptions); + removeExtensionAndIndexPostFix(ts.ensurePathIsNonModuleName(ts.getRelativePathFromDirectory(sourceDirectory, moduleFileName, getCanonicalFileName)), ending, compilerOptions); if (!baseUrl && !paths || relativePreference === RelativePreference.Relative) { return relativePath; } - const baseDirectory = getNormalizedAbsolutePath(getPathsBasePath(compilerOptions, host) || baseUrl!, host.getCurrentDirectory()); + const baseDirectory = ts.getNormalizedAbsolutePath(ts.getPathsBasePath(compilerOptions, host) || baseUrl!, host.getCurrentDirectory()); const relativeToBaseUrl = getRelativePathIfInDirectory(moduleFileName, baseDirectory, getCanonicalFileName); if (!relativeToBaseUrl) { return relativePath; } const importRelativeToBaseUrl = removeExtensionAndIndexPostFix(relativeToBaseUrl, ending, compilerOptions); - const fromPaths = paths && tryGetModuleNameFromPaths(removeFileExtension(relativeToBaseUrl), importRelativeToBaseUrl, paths); + const fromPaths = paths && tryGetModuleNameFromPaths(ts.removeFileExtension(relativeToBaseUrl), importRelativeToBaseUrl, paths); const nonRelative = fromPaths === undefined && baseUrl !== undefined ? importRelativeToBaseUrl : fromPaths; if (!nonRelative) { return relativePath; @@ -321,11 +252,11 @@ namespace ts.moduleSpecifiers { if (relativePreference === RelativePreference.ExternalNonRelative) { const projectDirectory = compilerOptions.configFilePath ? - toPath(getDirectoryPath(compilerOptions.configFilePath), host.getCurrentDirectory(), info.getCanonicalFileName) : + ts.toPath(ts.getDirectoryPath(compilerOptions.configFilePath), host.getCurrentDirectory(), info.getCanonicalFileName) : info.getCanonicalFileName(host.getCurrentDirectory()); - const modulePath = toPath(moduleFileName, projectDirectory, getCanonicalFileName); - const sourceIsInternal = startsWith(sourceDirectory, projectDirectory); - const targetIsInternal = startsWith(modulePath, projectDirectory); + const modulePath = ts.toPath(moduleFileName, projectDirectory, getCanonicalFileName); + const sourceIsInternal = ts.startsWith(sourceDirectory, projectDirectory); + const targetIsInternal = ts.startsWith(modulePath, projectDirectory); if (sourceIsInternal && !targetIsInternal || !sourceIsInternal && targetIsInternal) { // 1. The import path crosses the boundary of the tsconfig.json-containing directory. // @@ -338,7 +269,7 @@ namespace ts.moduleSpecifiers { return nonRelative; } - const nearestTargetPackageJson = getNearestAncestorDirectoryWithPackageJson(host, getDirectoryPath(modulePath)); + const nearestTargetPackageJson = getNearestAncestorDirectoryWithPackageJson(host, ts.getDirectoryPath(modulePath)); const nearestSourcePackageJson = getNearestAncestorDirectoryWithPackageJson(host, sourceDirectory); if (nearestSourcePackageJson !== nearestTargetPackageJson) { // 2. The importing and imported files are part of different packages. @@ -356,7 +287,8 @@ namespace ts.moduleSpecifiers { return relativePath; } - if (relativePreference !== RelativePreference.Shortest) Debug.assertNever(relativePreference); + if (relativePreference !== RelativePreference.Shortest) + ts.Debug.assertNever(relativePreference); // Prefer a relative import over a baseUrl import if it has fewer components. return isPathRelativeToParent(nonRelative) || countPathComponents(relativePath) < countPathComponents(nonRelative) ? relativePath : nonRelative; @@ -364,79 +296,77 @@ namespace ts.moduleSpecifiers { export function countPathComponents(path: string): number { let count = 0; - for (let i = startsWith(path, "./") ? 2 : 0; i < path.length; i++) { - if (path.charCodeAt(i) === CharacterCodes.slash) count++; + for (let i = ts.startsWith(path, "./") ? 2 : 0; i < path.length; i++) { + if (path.charCodeAt(i) === ts.CharacterCodes.slash) + count++; } return count; } - function usesJsExtensionOnImports({ imports }: SourceFile): boolean { - return firstDefined(imports, ({ text }) => pathIsRelative(text) ? hasJSFileExtension(text) : undefined) || false; + function usesJsExtensionOnImports({ imports }: ts.SourceFile): boolean { + return ts.firstDefined(imports, ({ text }) => ts.pathIsRelative(text) ? ts.hasJSFileExtension(text) : undefined) || false; } - function comparePathsByRedirectAndNumberOfDirectorySeparators(a: ModulePath, b: ModulePath) { - return compareBooleans(b.isRedirect, a.isRedirect) || compareNumberOfDirectorySeparators(a.path, b.path); + function comparePathsByRedirectAndNumberOfDirectorySeparators(a: ts.ModulePath, b: ts.ModulePath) { + return ts.compareBooleans(b.isRedirect, a.isRedirect) || ts.compareNumberOfDirectorySeparators(a.path, b.path); } - function getNearestAncestorDirectoryWithPackageJson(host: ModuleSpecifierResolutionHost, fileName: string) { + function getNearestAncestorDirectoryWithPackageJson(host: ts.ModuleSpecifierResolutionHost, fileName: string) { if (host.getNearestAncestorDirectoryWithPackageJson) { return host.getNearestAncestorDirectoryWithPackageJson(fileName); } - return !!forEachAncestorDirectory(fileName, directory => { - return host.fileExists(combinePaths(directory, "package.json")) ? true : undefined; + return !!ts.forEachAncestorDirectory(fileName, directory => { + return host.fileExists(ts.combinePaths(directory, "package.json")) ? true : undefined; }); } - export function forEachFileNameOfModule( - importingFileName: string, - importedFileName: string, - host: ModuleSpecifierResolutionHost, - preferSymlinks: boolean, - cb: (fileName: string, isRedirect: boolean) => T | undefined - ): T | undefined { - const getCanonicalFileName = hostGetCanonicalFileName(host); + export function forEachFileNameOfModule(importingFileName: string, importedFileName: string, host: ts.ModuleSpecifierResolutionHost, preferSymlinks: boolean, cb: (fileName: string, isRedirect: boolean) => T | undefined): T | undefined { + const getCanonicalFileName = ts.hostGetCanonicalFileName(host); const cwd = host.getCurrentDirectory(); const referenceRedirect = host.isSourceOfProjectReferenceRedirect(importedFileName) ? host.getProjectReferenceRedirect(importedFileName) : undefined; - const importedPath = toPath(importedFileName, cwd, getCanonicalFileName); - const redirects = host.redirectTargetsMap.get(importedPath) || emptyArray; - const importedFileNames = [...(referenceRedirect ? [referenceRedirect] : emptyArray), importedFileName, ...redirects]; - const targets = importedFileNames.map(f => getNormalizedAbsolutePath(f, cwd)); - let shouldFilterIgnoredPaths = !every(targets, containsIgnoredPath); + const importedPath = ts.toPath(importedFileName, cwd, getCanonicalFileName); + const redirects = host.redirectTargetsMap.get(importedPath) || ts.emptyArray; + const importedFileNames = [...(referenceRedirect ? [referenceRedirect] : ts.emptyArray), importedFileName, ...redirects]; + const targets = importedFileNames.map(f => ts.getNormalizedAbsolutePath(f, cwd)); + let shouldFilterIgnoredPaths = !ts.every(targets, ts.containsIgnoredPath); if (!preferSymlinks) { // Symlinks inside ignored paths are already filtered out of the symlink cache, // so we only need to remove them from the realpath filenames. - const result = forEach(targets, p => !(shouldFilterIgnoredPaths && containsIgnoredPath(p)) && cb(p, referenceRedirect === p)); - if (result) return result; + const result = ts.forEach(targets, p => !(shouldFilterIgnoredPaths && ts.containsIgnoredPath(p)) && cb(p, referenceRedirect === p)); + if (result) + return result; } const symlinkedDirectories = host.getSymlinkCache?.().getSymlinkedDirectoriesByRealpath(); - const fullImportedFileName = getNormalizedAbsolutePath(importedFileName, cwd); - const result = symlinkedDirectories && forEachAncestorDirectory(getDirectoryPath(fullImportedFileName), realPathDirectory => { - const symlinkDirectories = symlinkedDirectories.get(ensureTrailingDirectorySeparator(toPath(realPathDirectory, cwd, getCanonicalFileName))); - if (!symlinkDirectories) return undefined; // Continue to ancestor directory + const fullImportedFileName = ts.getNormalizedAbsolutePath(importedFileName, cwd); + const result = symlinkedDirectories && ts.forEachAncestorDirectory(ts.getDirectoryPath(fullImportedFileName), realPathDirectory => { + const symlinkDirectories = symlinkedDirectories.get(ts.ensureTrailingDirectorySeparator(ts.toPath(realPathDirectory, cwd, getCanonicalFileName))); + if (!symlinkDirectories) + return undefined; // Continue to ancestor directory // Don't want to a package to globally import from itself (importNameCodeFix_symlink_own_package.ts) - if (startsWithDirectory(importingFileName, realPathDirectory, getCanonicalFileName)) { + if (ts.startsWithDirectory(importingFileName, realPathDirectory, getCanonicalFileName)) { return false; // Stop search, each ancestor directory will also hit this condition } - return forEach(targets, target => { - if (!startsWithDirectory(target, realPathDirectory, getCanonicalFileName)) { + return ts.forEach(targets, target => { + if (!ts.startsWithDirectory(target, realPathDirectory, getCanonicalFileName)) { return; } - const relative = getRelativePathFromDirectory(realPathDirectory, target, getCanonicalFileName); + const relative = ts.getRelativePathFromDirectory(realPathDirectory, target, getCanonicalFileName); for (const symlinkDirectory of symlinkDirectories) { - const option = resolvePath(symlinkDirectory, relative); + const option = ts.resolvePath(symlinkDirectory, relative); const result = cb(option, target === referenceRedirect); shouldFilterIgnoredPaths = true; // We found a non-ignored path in symlinks, so we can reject ignored-path realpaths - if (result) return result; + if (result) + return result; } }); }); return result || (preferSymlinks - ? forEach(targets, p => shouldFilterIgnoredPaths && containsIgnoredPath(p) ? undefined : cb(p, p === referenceRedirect)) + ? ts.forEach(targets, p => shouldFilterIgnoredPaths && ts.containsIgnoredPath(p) ? undefined : cb(p, p === referenceRedirect)) : undefined); } @@ -444,18 +374,13 @@ namespace ts.moduleSpecifiers { * Looks for existing imports that use symlinks to this module. * Symlinks will be returned first so they are preferred over the real path. */ - function getAllModulePaths( - importingFilePath: Path, - importedFileName: string, - host: ModuleSpecifierResolutionHost, - preferences: UserPreferences, - options: ModuleSpecifierOptions = {}, - ) { - const importedFilePath = toPath(importedFileName, host.getCurrentDirectory(), hostGetCanonicalFileName(host)); + function getAllModulePaths(importingFilePath: ts.Path, importedFileName: string, host: ts.ModuleSpecifierResolutionHost, preferences: ts.UserPreferences, options: ts.ModuleSpecifierOptions = {}) { + const importedFilePath = ts.toPath(importedFileName, host.getCurrentDirectory(), ts.hostGetCanonicalFileName(host)); const cache = host.getModuleSpecifierCache?.(); if (cache) { const cached = cache.get(importingFilePath, importedFilePath, preferences, options); - if (cached?.modulePaths) return cached.modulePaths; + if (cached?.modulePaths) + return cached.modulePaths; } const modulePaths = getAllModulePathsWorker(importingFilePath, importedFileName, host); if (cache) { @@ -464,33 +389,29 @@ namespace ts.moduleSpecifiers { return modulePaths; } - function getAllModulePathsWorker(importingFileName: Path, importedFileName: string, host: ModuleSpecifierResolutionHost): readonly ModulePath[] { - const getCanonicalFileName = hostGetCanonicalFileName(host); - const allFileNames = new Map(); + function getAllModulePathsWorker(importingFileName: ts.Path, importedFileName: string, host: ts.ModuleSpecifierResolutionHost): readonly ts.ModulePath[] { + const getCanonicalFileName = ts.hostGetCanonicalFileName(host); + const allFileNames = new ts.Map(); let importedFileFromNodeModules = false; - forEachFileNameOfModule( - importingFileName, - importedFileName, - host, - /*preferSymlinks*/ true, - (path, isRedirect) => { - const isInNodeModules = pathContainsNodeModules(path); + forEachFileNameOfModule(importingFileName, importedFileName, host, + /*preferSymlinks*/ true, (path, isRedirect) => { + const isInNodeModules = ts.pathContainsNodeModules(path); allFileNames.set(path, { path: getCanonicalFileName(path), isRedirect, isInNodeModules }); importedFileFromNodeModules = importedFileFromNodeModules || isInNodeModules; // don't return value, so we collect everything - } - ); + }); // Sort by paths closest to importing file Name directory - const sortedPaths: ModulePath[] = []; - for ( - let directory = getDirectoryPath(importingFileName); - allFileNames.size !== 0; - ) { - const directoryStart = ensureTrailingDirectorySeparator(directory); - let pathsInDirectory: ModulePath[] | undefined; + const sortedPaths: ts.ModulePath[] = []; + for (let directory = ts.getDirectoryPath(importingFileName); allFileNames.size !== 0;) { + const directoryStart = ts.ensureTrailingDirectorySeparator(directory); + let pathsInDirectory: ts.ModulePath[] | undefined; allFileNames.forEach(({ path, isRedirect, isInNodeModules }, fileName) => { - if (startsWith(path, directoryStart)) { + if (ts.startsWith(path, directoryStart)) { (pathsInDirectory ||= []).push({ path: fileName, isRedirect, isInNodeModules }); allFileNames.delete(fileName); } @@ -501,23 +422,25 @@ namespace ts.moduleSpecifiers { } sortedPaths.push(...pathsInDirectory); } - const newDirectory = getDirectoryPath(directory); - if (newDirectory === directory) break; + const newDirectory = ts.getDirectoryPath(directory); + if (newDirectory === directory) + break; directory = newDirectory; } if (allFileNames.size) { - const remainingPaths = arrayFrom(allFileNames.values()); - if (remainingPaths.length > 1) remainingPaths.sort(comparePathsByRedirectAndNumberOfDirectorySeparators); + const remainingPaths = ts.arrayFrom(allFileNames.values()); + if (remainingPaths.length > 1) + remainingPaths.sort(comparePathsByRedirectAndNumberOfDirectorySeparators); sortedPaths.push(...remainingPaths); } return sortedPaths; } - function tryGetModuleNameFromAmbientModule(moduleSymbol: Symbol, checker: TypeChecker): string | undefined { - const decl = moduleSymbol.declarations?.find( - d => isNonGlobalAmbientModule(d) && (!isExternalModuleAugmentation(d) || !isExternalModuleNameRelative(getTextOfIdentifierOrLiteral(d.name))) - ) as (ModuleDeclaration & { name: StringLiteral }) | undefined; + function tryGetModuleNameFromAmbientModule(moduleSymbol: ts.Symbol, checker: ts.TypeChecker): string | undefined { + const decl = moduleSymbol.declarations?.find(d => ts.isNonGlobalAmbientModule(d) && (!ts.isExternalModuleAugmentation(d) || !ts.isExternalModuleNameRelative(ts.getTextOfIdentifierOrLiteral(d.name)))) as (ts.ModuleDeclaration & { + name: ts.StringLiteral; + }) | undefined; if (decl) { return decl.name.text; } @@ -532,45 +455,49 @@ namespace ts.moduleSpecifiers { * } */ // `import {c} from "m";` is valid, in which case, `moduleSymbol` is "ns", but the module name should be "m" - const ambientModuleDeclareCandidates = mapDefined(moduleSymbol.declarations, - d => { - if (!isModuleDeclaration(d)) return; + const ambientModuleDeclareCandidates = ts.mapDefined(moduleSymbol.declarations, d => { + if (!ts.isModuleDeclaration(d)) + return; const topNamespace = getTopNamespace(d); if (!(topNamespace?.parent?.parent - && isModuleBlock(topNamespace.parent) && isAmbientModule(topNamespace.parent.parent) && isSourceFile(topNamespace.parent.parent.parent))) return; - const exportAssignment = ((topNamespace.parent.parent.symbol.exports?.get("export=" as __String)?.valueDeclaration as ExportAssignment)?.expression as PropertyAccessExpression | Identifier); - if (!exportAssignment) return; + && ts.isModuleBlock(topNamespace.parent) && ts.isAmbientModule(topNamespace.parent.parent) && ts.isSourceFile(topNamespace.parent.parent.parent))) + return; + const exportAssignment = ((topNamespace.parent.parent.symbol.exports?.get("export=" as ts.__String)?.valueDeclaration as ts.ExportAssignment)?.expression as ts.PropertyAccessExpression | ts.Identifier); + if (!exportAssignment) + return; const exportSymbol = checker.getSymbolAtLocation(exportAssignment); - if (!exportSymbol) return; - const originalExportSymbol = exportSymbol?.flags & SymbolFlags.Alias ? checker.getAliasedSymbol(exportSymbol) : exportSymbol; - if (originalExportSymbol === d.symbol) return topNamespace.parent.parent; - - function getTopNamespace(namespaceDeclaration: ModuleDeclaration) { - while (namespaceDeclaration.flags & NodeFlags.NestedNamespace) { - namespaceDeclaration = namespaceDeclaration.parent as ModuleDeclaration; + if (!exportSymbol) + return; + const originalExportSymbol = exportSymbol?.flags & ts.SymbolFlags.Alias ? checker.getAliasedSymbol(exportSymbol) : exportSymbol; + if (originalExportSymbol === d.symbol) + return topNamespace.parent.parent; + function getTopNamespace(namespaceDeclaration: ts.ModuleDeclaration) { + while (namespaceDeclaration.flags & ts.NodeFlags.NestedNamespace) { + namespaceDeclaration = namespaceDeclaration.parent as ts.ModuleDeclaration; } return namespaceDeclaration; } - } - ); - const ambientModuleDeclare = ambientModuleDeclareCandidates[0] as (AmbientModuleDeclaration & { name: StringLiteral }) | undefined; + }); + const ambientModuleDeclare = ambientModuleDeclareCandidates[0] as (ts.AmbientModuleDeclaration & { + name: ts.StringLiteral; + }) | undefined; if (ambientModuleDeclare) { return ambientModuleDeclare.name.text; } } - function tryGetModuleNameFromPaths(relativeToBaseUrlWithIndex: string, relativeToBaseUrl: string, paths: MapLike): string | undefined { + function tryGetModuleNameFromPaths(relativeToBaseUrlWithIndex: string, relativeToBaseUrl: string, paths: ts.MapLike): string | undefined { for (const key in paths) { for (const patternText of paths[key]) { - const pattern = removeFileExtension(normalizePath(patternText)); + const pattern = ts.removeFileExtension(ts.normalizePath(patternText)); const indexOfStar = pattern.indexOf("*"); if (indexOfStar !== -1) { const prefix = pattern.substr(0, indexOfStar); const suffix = pattern.substr(indexOfStar + 1); if (relativeToBaseUrl.length >= prefix.length + suffix.length && - startsWith(relativeToBaseUrl, prefix) && - endsWith(relativeToBaseUrl, suffix) || - !suffix && relativeToBaseUrl === removeTrailingDirectorySeparator(prefix)) { + ts.startsWith(relativeToBaseUrl, prefix) && + ts.endsWith(relativeToBaseUrl, suffix) || + !suffix && relativeToBaseUrl === ts.removeTrailingDirectorySeparator(prefix)) { const matchedStar = relativeToBaseUrl.substr(prefix.length, relativeToBaseUrl.length - suffix.length - prefix.length); return key.replace("*", matchedStar); } @@ -588,31 +515,33 @@ namespace ts.moduleSpecifiers { Pattern } - function tryGetModuleNameFromExports(options: CompilerOptions, targetFilePath: string, packageDirectory: string, packageName: string, exports: unknown, conditions: string[], mode = MatchingMode.Exact): { moduleFileToTry: string } | undefined { + function tryGetModuleNameFromExports(options: ts.CompilerOptions, targetFilePath: string, packageDirectory: string, packageName: string, exports: unknown, conditions: string[], mode = MatchingMode.Exact): { + moduleFileToTry: string; + } | undefined { if (typeof exports === "string") { - const pathOrPattern = getNormalizedAbsolutePath(combinePaths(packageDirectory, exports), /*currentDirectory*/ undefined); - const extensionSwappedTarget = hasTSFileExtension(targetFilePath) ? removeFileExtension(targetFilePath) + tryGetJSExtensionForFile(targetFilePath, options) : undefined; + const pathOrPattern = ts.getNormalizedAbsolutePath(ts.combinePaths(packageDirectory, exports), /*currentDirectory*/ undefined); + const extensionSwappedTarget = ts.hasTSFileExtension(targetFilePath) ? ts.removeFileExtension(targetFilePath) + tryGetJSExtensionForFile(targetFilePath, options) : undefined; switch (mode) { case MatchingMode.Exact: - if (comparePaths(targetFilePath, pathOrPattern) === Comparison.EqualTo || (extensionSwappedTarget && comparePaths(extensionSwappedTarget, pathOrPattern) === Comparison.EqualTo)) { + if (ts.comparePaths(targetFilePath, pathOrPattern) === ts.Comparison.EqualTo || (extensionSwappedTarget && ts.comparePaths(extensionSwappedTarget, pathOrPattern) === ts.Comparison.EqualTo)) { return { moduleFileToTry: packageName }; } break; case MatchingMode.Directory: - if (containsPath(pathOrPattern, targetFilePath)) { - const fragment = getRelativePathFromDirectory(pathOrPattern, targetFilePath, /*ignoreCase*/ false); - return { moduleFileToTry: getNormalizedAbsolutePath(combinePaths(combinePaths(packageName, exports), fragment), /*currentDirectory*/ undefined) }; + if (ts.containsPath(pathOrPattern, targetFilePath)) { + const fragment = ts.getRelativePathFromDirectory(pathOrPattern, targetFilePath, /*ignoreCase*/ false); + return { moduleFileToTry: ts.getNormalizedAbsolutePath(ts.combinePaths(ts.combinePaths(packageName, exports), fragment), /*currentDirectory*/ undefined) }; } break; case MatchingMode.Pattern: const starPos = pathOrPattern.indexOf("*"); const leadingSlice = pathOrPattern.slice(0, starPos); const trailingSlice = pathOrPattern.slice(starPos + 1); - if (startsWith(targetFilePath, leadingSlice) && endsWith(targetFilePath, trailingSlice)) { + if (ts.startsWith(targetFilePath, leadingSlice) && ts.endsWith(targetFilePath, trailingSlice)) { const starReplacement = targetFilePath.slice(leadingSlice.length, targetFilePath.length - trailingSlice.length); return { moduleFileToTry: packageName.replace("*", starReplacement) }; } - if (extensionSwappedTarget && startsWith(extensionSwappedTarget, leadingSlice) && endsWith(extensionSwappedTarget, trailingSlice)) { + if (extensionSwappedTarget && ts.startsWith(extensionSwappedTarget, leadingSlice) && ts.endsWith(extensionSwappedTarget, trailingSlice)) { const starReplacement = extensionSwappedTarget.slice(leadingSlice.length, extensionSwappedTarget.length - trailingSlice.length); return { moduleFileToTry: packageName.replace("*", starReplacement) }; } @@ -620,28 +549,28 @@ namespace ts.moduleSpecifiers { } } else if (Array.isArray(exports)) { - return forEach(exports, e => tryGetModuleNameFromExports(options, targetFilePath, packageDirectory, packageName, e, conditions)); + return ts.forEach(exports, e => tryGetModuleNameFromExports(options, targetFilePath, packageDirectory, packageName, e, conditions)); } else if (typeof exports === "object" && exports !== null) { // eslint-disable-line no-null/no-null - if (allKeysStartWithDot(exports as MapLike)) { + if (ts.allKeysStartWithDot(exports as ts.MapLike)) { // sub-mappings // 3 cases: // * directory mappings (legacyish, key ends with / (technically allows index/extension resolution under cjs mode)) // * pattern mappings (contains a *) // * exact mappings (no *, does not end with /) - return forEach(getOwnKeys(exports as MapLike), k => { - const subPackageName = getNormalizedAbsolutePath(combinePaths(packageName, k), /*currentDirectory*/ undefined); - const mode = endsWith(k, "/") ? MatchingMode.Directory - : stringContains(k, "*") ? MatchingMode.Pattern + return ts.forEach(ts.getOwnKeys(exports as ts.MapLike), k => { + const subPackageName = ts.getNormalizedAbsolutePath(ts.combinePaths(packageName, k), /*currentDirectory*/ undefined); + const mode = ts.endsWith(k, "/") ? MatchingMode.Directory + : ts.stringContains(k, "*") ? MatchingMode.Pattern : MatchingMode.Exact; - return tryGetModuleNameFromExports(options, targetFilePath, packageDirectory, subPackageName, (exports as MapLike)[k], conditions, mode); + return tryGetModuleNameFromExports(options, targetFilePath, packageDirectory, subPackageName, (exports as ts.MapLike)[k], conditions, mode); }); } else { // conditional mapping - for (const key of getOwnKeys(exports as MapLike)) { - if (key === "default" || conditions.indexOf(key) >= 0 || isApplicableVersionedTypesKey(conditions, key)) { - const subTarget = (exports as MapLike)[key]; + for (const key of ts.getOwnKeys(exports as ts.MapLike)) { + if (key === "default" || conditions.indexOf(key) >= 0 || ts.isApplicableVersionedTypesKey(conditions, key)) { + const subTarget = (exports as ts.MapLike)[key]; const result = tryGetModuleNameFromExports(options, targetFilePath, packageDirectory, packageName, subTarget, conditions); if (result) { return result; @@ -653,24 +582,24 @@ namespace ts.moduleSpecifiers { return undefined; } - function tryGetModuleNameFromRootDirs(rootDirs: readonly string[], moduleFileName: string, sourceDirectory: string, getCanonicalFileName: (file: string) => string, ending: Ending, compilerOptions: CompilerOptions): string | undefined { + function tryGetModuleNameFromRootDirs(rootDirs: readonly string[], moduleFileName: string, sourceDirectory: string, getCanonicalFileName: (file: string) => string, ending: Ending, compilerOptions: ts.CompilerOptions): string | undefined { const normalizedTargetPath = getPathRelativeToRootDirs(moduleFileName, rootDirs, getCanonicalFileName); if (normalizedTargetPath === undefined) { return undefined; } const normalizedSourcePath = getPathRelativeToRootDirs(sourceDirectory, rootDirs, getCanonicalFileName); - const relativePath = normalizedSourcePath !== undefined ? ensurePathIsNonModuleName(getRelativePathFromDirectory(normalizedSourcePath, normalizedTargetPath, getCanonicalFileName)) : normalizedTargetPath; - return getEmitModuleResolutionKind(compilerOptions) === ModuleResolutionKind.NodeJs + const relativePath = normalizedSourcePath !== undefined ? ts.ensurePathIsNonModuleName(ts.getRelativePathFromDirectory(normalizedSourcePath, normalizedTargetPath, getCanonicalFileName)) : normalizedTargetPath; + return ts.getEmitModuleResolutionKind(compilerOptions) === ts.ModuleResolutionKind.NodeJs ? removeExtensionAndIndexPostFix(relativePath, ending, compilerOptions) - : removeFileExtension(relativePath); + : ts.removeFileExtension(relativePath); } - function tryGetModuleNameAsNodeModule({ path, isRedirect }: ModulePath, { getCanonicalFileName, sourceDirectory }: Info, importingSourceFile: SourceFile , host: ModuleSpecifierResolutionHost, options: CompilerOptions, userPreferences: UserPreferences, packageNameOnly?: boolean, overrideMode?: ModuleKind.ESNext | ModuleKind.CommonJS): string | undefined { + function tryGetModuleNameAsNodeModule({ path, isRedirect }: ts.ModulePath, { getCanonicalFileName, sourceDirectory }: Info, importingSourceFile: ts.SourceFile, host: ts.ModuleSpecifierResolutionHost, options: ts.CompilerOptions, userPreferences: ts.UserPreferences, packageNameOnly?: boolean, overrideMode?: ts.ModuleKind.ESNext | ts.ModuleKind.CommonJS): string | undefined { if (!host.fileExists || !host.readFile) { return undefined; } - const parts: NodeModulePathParts = getNodeModulePathParts(path)!; + const parts: ts.NodeModulePathParts = ts.getNodeModulePathParts(path)!; if (!parts) { return undefined; } @@ -686,7 +615,7 @@ namespace ts.moduleSpecifiers { while (true) { // If the module could be imported by a directory name, use that directory's name const { moduleFileToTry, packageRootPath, blockedByExports, verbatimFromExports } = tryDirectoryWithPackageJson(packageRootIndex); - if (getEmitModuleResolutionKind(options) !== ModuleResolutionKind.Classic) { + if (ts.getEmitModuleResolutionKind(options) !== ts.ModuleResolutionKind.Classic) { if (blockedByExports) { return undefined; // File is under this package.json, but is not publicly exported - there's no way to name it via `node_modules` resolution } @@ -699,10 +628,11 @@ namespace ts.moduleSpecifiers { isPackageRootPath = true; break; } - if (!moduleFileName) moduleFileName = moduleFileToTry; + if (!moduleFileName) + moduleFileName = moduleFileToTry; // try with next level of directory - packageRootIndex = path.indexOf(directorySeparator, packageRootIndex + 1); + packageRootIndex = path.indexOf(ts.directorySeparator, packageRootIndex + 1); if (packageRootIndex === -1) { moduleSpecifier = removeExtensionAndIndexPostFix(moduleFileName, preferences.ending, options, host); break; @@ -718,36 +648,40 @@ namespace ts.moduleSpecifiers { // Get a path that's relative to node_modules or the importing file's path // if node_modules folder is in this folder or any of its parent folders, no need to keep it. const pathToTopLevelNodeModules = getCanonicalFileName(moduleSpecifier.substring(0, parts.topLevelNodeModulesIndex)); - if (!(startsWith(sourceDirectory, pathToTopLevelNodeModules) || globalTypingsCacheLocation && startsWith(getCanonicalFileName(globalTypingsCacheLocation), pathToTopLevelNodeModules))) { + if (!(ts.startsWith(sourceDirectory, pathToTopLevelNodeModules) || globalTypingsCacheLocation && ts.startsWith(getCanonicalFileName(globalTypingsCacheLocation), pathToTopLevelNodeModules))) { return undefined; } // If the module was found in @types, get the actual Node package name const nodeModulesDirectoryName = moduleSpecifier.substring(parts.topLevelPackageNameIndex + 1); - const packageName = getPackageNameFromTypesPackageName(nodeModulesDirectoryName); + const packageName = ts.getPackageNameFromTypesPackageName(nodeModulesDirectoryName); // For classic resolution, only allow importing from node_modules/@types, not other node_modules - return getEmitModuleResolutionKind(options) === ModuleResolutionKind.Classic && packageName === nodeModulesDirectoryName ? undefined : packageName; - - function tryDirectoryWithPackageJson(packageRootIndex: number): { moduleFileToTry: string, packageRootPath?: string, blockedByExports?: true, verbatimFromExports?: true } { + return ts.getEmitModuleResolutionKind(options) === ts.ModuleResolutionKind.Classic && packageName === nodeModulesDirectoryName ? undefined : packageName; + function tryDirectoryWithPackageJson(packageRootIndex: number): { + moduleFileToTry: string; + packageRootPath?: string; + blockedByExports?: true; + verbatimFromExports?: true; + } { const packageRootPath = path.substring(0, packageRootIndex); - const packageJsonPath = combinePaths(packageRootPath, "package.json"); + const packageJsonPath = ts.combinePaths(packageRootPath, "package.json"); let moduleFileToTry = path; const cachedPackageJson = host.getPackageJsonInfoCache?.()?.getPackageJsonInfo(packageJsonPath); if (typeof cachedPackageJson === "object" || cachedPackageJson === undefined && host.fileExists(packageJsonPath)) { const packageJsonContent = cachedPackageJson?.packageJsonContent || JSON.parse(host.readFile!(packageJsonPath)!); - if (getEmitModuleResolutionKind(options) === ModuleResolutionKind.Node16 || getEmitModuleResolutionKind(options) === ModuleResolutionKind.NodeNext) { + if (ts.getEmitModuleResolutionKind(options) === ts.ModuleResolutionKind.Node16 || ts.getEmitModuleResolutionKind(options) === ts.ModuleResolutionKind.NodeNext) { // `conditions` *could* be made to go against `importingSourceFile.impliedNodeFormat` if something wanted to generate // an ImportEqualsDeclaration in an ESM-implied file or an ImportCall in a CJS-implied file. But since this function is // usually called to conjure an import out of thin air, we don't have an existing usage to call `getModeForUsageAtIndex` // with, so for now we just stick with the mode of the file. - const conditions = ["node", overrideMode || importingSourceFile.impliedNodeFormat === ModuleKind.ESNext ? "import" : "require", "types"]; + const conditions = ["node", overrideMode || importingSourceFile.impliedNodeFormat === ts.ModuleKind.ESNext ? "import" : "require", "types"]; const fromExports = packageJsonContent.exports && typeof packageJsonContent.name === "string" - ? tryGetModuleNameFromExports(options, path, packageRootPath, getPackageNameFromTypesPackageName(packageJsonContent.name), packageJsonContent.exports, conditions) + ? tryGetModuleNameFromExports(options, path, packageRootPath, ts.getPackageNameFromTypesPackageName(packageJsonContent.name), packageJsonContent.exports, conditions) : undefined; if (fromExports) { - const withJsExtension = !hasTSFileExtension(fromExports.moduleFileToTry) + const withJsExtension = !ts.hasTSFileExtension(fromExports.moduleFileToTry) ? fromExports - : { moduleFileToTry: removeFileExtension(fromExports.moduleFileToTry) + tryGetJSExtensionForFile(fromExports.moduleFileToTry, options) }; + : { moduleFileToTry: ts.removeFileExtension(fromExports.moduleFileToTry) + tryGetJSExtensionForFile(fromExports.moduleFileToTry, options) }; return { ...withJsExtension, verbatimFromExports: true }; } if (packageJsonContent.exports) { @@ -755,24 +689,20 @@ namespace ts.moduleSpecifiers { } } const versionPaths = packageJsonContent.typesVersions - ? getPackageJsonTypesVersionsPaths(packageJsonContent.typesVersions) + ? ts.getPackageJsonTypesVersionsPaths(packageJsonContent.typesVersions) : undefined; if (versionPaths) { const subModuleName = path.slice(packageRootPath.length + 1); - const fromPaths = tryGetModuleNameFromPaths( - removeFileExtension(subModuleName), - removeExtensionAndIndexPostFix(subModuleName, Ending.Minimal, options), - versionPaths.paths - ); + const fromPaths = tryGetModuleNameFromPaths(ts.removeFileExtension(subModuleName), removeExtensionAndIndexPostFix(subModuleName, Ending.Minimal, options), versionPaths.paths); if (fromPaths !== undefined) { - moduleFileToTry = combinePaths(packageRootPath, fromPaths); + moduleFileToTry = ts.combinePaths(packageRootPath, fromPaths); } } // If the file is the main module, it can be imported by the package name const mainFileRelative = packageJsonContent.typings || packageJsonContent.types || packageJsonContent.main || "index.js"; - if (isString(mainFileRelative)) { - const mainExportFile = toPath(mainFileRelative, packageRootPath, getCanonicalFileName); - if (removeFileExtension(mainExportFile) === removeFileExtension(getCanonicalFileName(moduleFileToTry))) { + if (ts.isString(mainFileRelative)) { + const mainExportFile = ts.toPath(mainFileRelative, packageRootPath, getCanonicalFileName); + if (ts.removeFileExtension(mainExportFile) === ts.removeFileExtension(getCanonicalFileName(moduleFileToTry))) { return { packageRootPath, moduleFileToTry }; } } @@ -788,10 +718,11 @@ namespace ts.moduleSpecifiers { } } - function tryGetAnyFileFromPath(host: ModuleSpecifierResolutionHost, path: string) { - if (!host.fileExists) return; + function tryGetAnyFileFromPath(host: ts.ModuleSpecifierResolutionHost, path: string) { + if (!host.fileExists) + return; // We check all js, `node` and `json` extensions in addition to TS, since node module resolution would also choose those over the directory - const extensions = flatten(getSupportedExtensions({ allowJs: true }, [{ extension: "node", isMixedContent: false }, { extension: "json", isMixedContent: false, scriptKind: ScriptKind.JSON }])); + const extensions = ts.flatten(ts.getSupportedExtensions({ allowJs: true }, [{ extension: "node", isMixedContent: false }, { extension: "json", isMixedContent: false, scriptKind: ts.ScriptKind.JSON }])); for (const e of extensions) { const fullPath = path + e; if (host.fileExists(fullPath)) { @@ -800,21 +731,24 @@ namespace ts.moduleSpecifiers { } } - function getPathRelativeToRootDirs(path: string, rootDirs: readonly string[], getCanonicalFileName: GetCanonicalFileName): string | undefined { - return firstDefined(rootDirs, rootDir => { + function getPathRelativeToRootDirs(path: string, rootDirs: readonly string[], getCanonicalFileName: ts.GetCanonicalFileName): string | undefined { + return ts.firstDefined(rootDirs, rootDir => { const relativePath = getRelativePathIfInDirectory(path, rootDir, getCanonicalFileName); return relativePath !== undefined && isPathRelativeToParent(relativePath) ? undefined : relativePath; }); } - function removeExtensionAndIndexPostFix(fileName: string, ending: Ending, options: CompilerOptions, host?: ModuleSpecifierResolutionHost): string { - if (fileExtensionIsOneOf(fileName, [Extension.Json, Extension.Mjs, Extension.Cjs])) return fileName; - const noExtension = removeFileExtension(fileName); - if (fileName === noExtension) return fileName; - if (fileExtensionIsOneOf(fileName, [Extension.Dmts, Extension.Mts, Extension.Dcts, Extension.Cts])) return noExtension + getJSExtensionForFile(fileName, options); + function removeExtensionAndIndexPostFix(fileName: string, ending: Ending, options: ts.CompilerOptions, host?: ts.ModuleSpecifierResolutionHost): string { + if (ts.fileExtensionIsOneOf(fileName, [ts.Extension.Json, ts.Extension.Mjs, ts.Extension.Cjs])) + return fileName; + const noExtension = ts.removeFileExtension(fileName); + if (fileName === noExtension) + return fileName; + if (ts.fileExtensionIsOneOf(fileName, [ts.Extension.Dmts, ts.Extension.Mts, ts.Extension.Dcts, ts.Extension.Cts])) + return noExtension + getJSExtensionForFile(fileName, options); switch (ending) { case Ending.Minimal: - const withoutIndex = removeSuffix(noExtension, "/index"); + const withoutIndex = ts.removeSuffix(noExtension, "/index"); if (host && withoutIndex !== noExtension && tryGetAnyFileFromPath(host, withoutIndex)) { // Can't remove index if there's a file by the same name as the directory. // Probably more callers should pass `host` so we can determine this? @@ -826,45 +760,45 @@ namespace ts.moduleSpecifiers { case Ending.JsExtension: return noExtension + getJSExtensionForFile(fileName, options); default: - return Debug.assertNever(ending); + return ts.Debug.assertNever(ending); } } - function getJSExtensionForFile(fileName: string, options: CompilerOptions): Extension { - return tryGetJSExtensionForFile(fileName, options) ?? Debug.fail(`Extension ${extensionFromPath(fileName)} is unsupported:: FileName:: ${fileName}`); + function getJSExtensionForFile(fileName: string, options: ts.CompilerOptions): ts.Extension { + return tryGetJSExtensionForFile(fileName, options) ?? ts.Debug.fail(`Extension ${ts.extensionFromPath(fileName)} is unsupported:: FileName:: ${fileName}`); } - export function tryGetJSExtensionForFile(fileName: string, options: CompilerOptions): Extension | undefined { - const ext = tryGetExtensionFromPath(fileName); + export function tryGetJSExtensionForFile(fileName: string, options: ts.CompilerOptions): ts.Extension | undefined { + const ext = ts.tryGetExtensionFromPath(fileName); switch (ext) { - case Extension.Ts: - case Extension.Dts: - return Extension.Js; - case Extension.Tsx: - return options.jsx === JsxEmit.Preserve ? Extension.Jsx : Extension.Js; - case Extension.Js: - case Extension.Jsx: - case Extension.Json: + case ts.Extension.Ts: + case ts.Extension.Dts: + return ts.Extension.Js; + case ts.Extension.Tsx: + return options.jsx === ts.JsxEmit.Preserve ? ts.Extension.Jsx : ts.Extension.Js; + case ts.Extension.Js: + case ts.Extension.Jsx: + case ts.Extension.Json: return ext; - case Extension.Dmts: - case Extension.Mts: - case Extension.Mjs: - return Extension.Mjs; - case Extension.Dcts: - case Extension.Cts: - case Extension.Cjs: - return Extension.Cjs; + case ts.Extension.Dmts: + case ts.Extension.Mts: + case ts.Extension.Mjs: + return ts.Extension.Mjs; + case ts.Extension.Dcts: + case ts.Extension.Cts: + case ts.Extension.Cjs: + return ts.Extension.Cjs; default: return undefined; } } - function getRelativePathIfInDirectory(path: string, directoryPath: string, getCanonicalFileName: GetCanonicalFileName): string | undefined { - const relativePath = getRelativePathToDirectoryOrUrl(directoryPath, path, directoryPath, getCanonicalFileName, /*isAbsolutePathAnUrl*/ false); - return isRootedDiskPath(relativePath) ? undefined : relativePath; + function getRelativePathIfInDirectory(path: string, directoryPath: string, getCanonicalFileName: ts.GetCanonicalFileName): string | undefined { + const relativePath = ts.getRelativePathToDirectoryOrUrl(directoryPath, path, directoryPath, getCanonicalFileName, /*isAbsolutePathAnUrl*/ false); + return ts.isRootedDiskPath(relativePath) ? undefined : relativePath; } function isPathRelativeToParent(path: string): boolean { - return startsWith(path, ".."); + return ts.startsWith(path, ".."); } } diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 1b502dfc22f78..4d7f7b80d95f9 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -5,7 +5,7 @@ namespace ts { Await = 1 << 1, Type = 1 << 2, IgnoreMissingOpenBrace = 1 << 4, - JSDoc = 1 << 5, + JSDoc = 1 << 5 } const enum SpeculationKind { @@ -14,32 +14,31 @@ namespace ts { Reparse } - let NodeConstructor: new (kind: SyntaxKind, pos?: number, end?: number) => Node; - let TokenConstructor: new (kind: SyntaxKind, pos?: number, end?: number) => Node; - let IdentifierConstructor: new (kind: SyntaxKind, pos?: number, end?: number) => Node; - let PrivateIdentifierConstructor: new (kind: SyntaxKind, pos?: number, end?: number) => Node; - let SourceFileConstructor: new (kind: SyntaxKind, pos?: number, end?: number) => Node; + let NodeConstructor: new (kind: ts.SyntaxKind, pos?: number, end?: number) => ts.Node; + let TokenConstructor: new (kind: ts.SyntaxKind, pos?: number, end?: number) => ts.Node; + let IdentifierConstructor: new (kind: ts.SyntaxKind, pos?: number, end?: number) => ts.Node; + let PrivateIdentifierConstructor: new (kind: ts.SyntaxKind, pos?: number, end?: number) => ts.Node; + let SourceFileConstructor: new (kind: ts.SyntaxKind, pos?: number, end?: number) => ts.Node; /** * NOTE: You should not use this, it is only exported to support `createNode` in `~/src/deprecatedCompat/deprecations.ts`. */ /* @internal */ - export const parseBaseNodeFactory: BaseNodeFactory = { - createBaseSourceFileNode: kind => new (SourceFileConstructor || (SourceFileConstructor = objectAllocator.getSourceFileConstructor()))(kind, -1, -1), - createBaseIdentifierNode: kind => new (IdentifierConstructor || (IdentifierConstructor = objectAllocator.getIdentifierConstructor()))(kind, -1, -1), - createBasePrivateIdentifierNode: kind => new (PrivateIdentifierConstructor || (PrivateIdentifierConstructor = objectAllocator.getPrivateIdentifierConstructor()))(kind, -1, -1), - createBaseTokenNode: kind => new (TokenConstructor || (TokenConstructor = objectAllocator.getTokenConstructor()))(kind, -1, -1), - createBaseNode: kind => new (NodeConstructor || (NodeConstructor = objectAllocator.getNodeConstructor()))(kind, -1, -1), + export const parseBaseNodeFactory: ts.BaseNodeFactory = { + createBaseSourceFileNode: kind => new (SourceFileConstructor || (SourceFileConstructor = ts.objectAllocator.getSourceFileConstructor()))(kind, -1, -1), + createBaseIdentifierNode: kind => new (IdentifierConstructor || (IdentifierConstructor = ts.objectAllocator.getIdentifierConstructor()))(kind, -1, -1), + createBasePrivateIdentifierNode: kind => new (PrivateIdentifierConstructor || (PrivateIdentifierConstructor = ts.objectAllocator.getPrivateIdentifierConstructor()))(kind, -1, -1), + createBaseTokenNode: kind => new (TokenConstructor || (TokenConstructor = ts.objectAllocator.getTokenConstructor()))(kind, -1, -1), + createBaseNode: kind => new (NodeConstructor || (NodeConstructor = ts.objectAllocator.getNodeConstructor()))(kind, -1, -1), }; /* @internal */ - export const parseNodeFactory = createNodeFactory(NodeFactoryFlags.NoParenthesizerRules, parseBaseNodeFactory); - - function visitNode(cbNode: (node: Node) => T, node: Node | undefined): T | undefined { + export const parseNodeFactory = ts.createNodeFactory(ts.NodeFactoryFlags.NoParenthesizerRules, parseBaseNodeFactory); + function visitNode(cbNode: (node: ts.Node) => T, node: ts.Node | undefined): T | undefined { return node && cbNode(node); } - function visitNodes(cbNode: (node: Node) => T, cbNodes: ((node: NodeArray) => T | undefined) | undefined, nodes: NodeArray | undefined): T | undefined { + function visitNodes(cbNode: (node: ts.Node) => T, cbNodes: ((node: ts.NodeArray) => T | undefined) | undefined, nodes: ts.NodeArray | undefined): T | undefined { if (nodes) { if (cbNodes) { return cbNodes(nodes); @@ -55,44 +54,43 @@ namespace ts { /*@internal*/ export function isJSDocLikeText(text: string, start: number) { - return text.charCodeAt(start + 1) === CharacterCodes.asterisk && - text.charCodeAt(start + 2) === CharacterCodes.asterisk && - text.charCodeAt(start + 3) !== CharacterCodes.slash; + return text.charCodeAt(start + 1) === ts.CharacterCodes.asterisk && + text.charCodeAt(start + 2) === ts.CharacterCodes.asterisk && + text.charCodeAt(start + 3) !== ts.CharacterCodes.slash; } /*@internal*/ - export function isFileProbablyExternalModule(sourceFile: SourceFile) { + export function isFileProbablyExternalModule(sourceFile: ts.SourceFile) { // Try to use the first top-level import/export when available, then // fall back to looking for an 'import.meta' somewhere in the tree if necessary. - return forEach(sourceFile.statements, isAnExternalModuleIndicatorNode) || + return ts.forEach(sourceFile.statements, isAnExternalModuleIndicatorNode) || getImportMetaIfNecessary(sourceFile); } - function isAnExternalModuleIndicatorNode(node: Node) { - return hasModifierOfKind(node, SyntaxKind.ExportKeyword) - || isImportEqualsDeclaration(node) && isExternalModuleReference(node.moduleReference) - || isImportDeclaration(node) - || isExportAssignment(node) - || isExportDeclaration(node) ? node : undefined; + function isAnExternalModuleIndicatorNode(node: ts.Node) { + return hasModifierOfKind(node, ts.SyntaxKind.ExportKeyword) + || ts.isImportEqualsDeclaration(node) && ts.isExternalModuleReference(node.moduleReference) + || ts.isImportDeclaration(node) + || ts.isExportAssignment(node) + || ts.isExportDeclaration(node) ? node : undefined; } - - function getImportMetaIfNecessary(sourceFile: SourceFile) { - return sourceFile.flags & NodeFlags.PossiblyContainsImportMeta ? + function getImportMetaIfNecessary(sourceFile: ts.SourceFile) { + return sourceFile.flags & ts.NodeFlags.PossiblyContainsImportMeta ? walkTreeForImportMeta(sourceFile) : undefined; } - function walkTreeForImportMeta(node: Node): Node | undefined { + function walkTreeForImportMeta(node: ts.Node): ts.Node | undefined { return isImportMeta(node) ? node : forEachChild(node, walkTreeForImportMeta); } /** Do not use hasModifier inside the parser; it relies on parent pointers. Use this instead. */ - function hasModifierOfKind(node: Node, kind: SyntaxKind) { - return some(node.modifiers, m => m.kind === kind); + function hasModifierOfKind(node: ts.Node, kind: ts.SyntaxKind) { + return ts.some(node.modifiers, m => m.kind === kind); } - function isImportMeta(node: Node): boolean { - return isMetaProperty(node) && node.keywordToken === SyntaxKind.ImportKeyword && node.name.escapedText === "meta"; + function isImportMeta(node: ts.Node): boolean { + return ts.isMetaProperty(node) && node.keywordToken === ts.SyntaxKind.ImportKeyword && node.name.escapedText === "meta"; } /** @@ -108,510 +106,508 @@ namespace ts { * @remarks `forEachChild` must visit the children of a node in the order * that they appear in the source code. The language service depends on this property to locate nodes by position. */ - export function forEachChild(node: Node, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { - if (!node || node.kind <= SyntaxKind.LastToken) { + export function forEachChild(node: ts.Node, cbNode: (node: ts.Node) => T | undefined, cbNodes?: (nodes: ts.NodeArray) => T | undefined): T | undefined { + if (!node || node.kind <= ts.SyntaxKind.LastToken) { return; } switch (node.kind) { - case SyntaxKind.QualifiedName: - return visitNode(cbNode, (node as QualifiedName).left) || - visitNode(cbNode, (node as QualifiedName).right); - case SyntaxKind.TypeParameter: + case ts.SyntaxKind.QualifiedName: + return visitNode(cbNode, (node as ts.QualifiedName).left) || + visitNode(cbNode, (node as ts.QualifiedName).right); + case ts.SyntaxKind.TypeParameter: return visitNodes(cbNode, cbNodes, node.modifiers) || - visitNode(cbNode, (node as TypeParameterDeclaration).name) || - visitNode(cbNode, (node as TypeParameterDeclaration).constraint) || - visitNode(cbNode, (node as TypeParameterDeclaration).default) || - visitNode(cbNode, (node as TypeParameterDeclaration).expression); - case SyntaxKind.ShorthandPropertyAssignment: + visitNode(cbNode, (node as ts.TypeParameterDeclaration).name) || + visitNode(cbNode, (node as ts.TypeParameterDeclaration).constraint) || + visitNode(cbNode, (node as ts.TypeParameterDeclaration).default) || + visitNode(cbNode, (node as ts.TypeParameterDeclaration).expression); + case ts.SyntaxKind.ShorthandPropertyAssignment: return visitNodes(cbNode, cbNodes, node.decorators) || visitNodes(cbNode, cbNodes, node.modifiers) || - visitNode(cbNode, (node as ShorthandPropertyAssignment).name) || - visitNode(cbNode, (node as ShorthandPropertyAssignment).questionToken) || - visitNode(cbNode, (node as ShorthandPropertyAssignment).exclamationToken) || - visitNode(cbNode, (node as ShorthandPropertyAssignment).equalsToken) || - visitNode(cbNode, (node as ShorthandPropertyAssignment).objectAssignmentInitializer); - case SyntaxKind.SpreadAssignment: - return visitNode(cbNode, (node as SpreadAssignment).expression); - case SyntaxKind.Parameter: + visitNode(cbNode, (node as ts.ShorthandPropertyAssignment).name) || + visitNode(cbNode, (node as ts.ShorthandPropertyAssignment).questionToken) || + visitNode(cbNode, (node as ts.ShorthandPropertyAssignment).exclamationToken) || + visitNode(cbNode, (node as ts.ShorthandPropertyAssignment).equalsToken) || + visitNode(cbNode, (node as ts.ShorthandPropertyAssignment).objectAssignmentInitializer); + case ts.SyntaxKind.SpreadAssignment: + return visitNode(cbNode, (node as ts.SpreadAssignment).expression); + case ts.SyntaxKind.Parameter: return visitNodes(cbNode, cbNodes, node.decorators) || visitNodes(cbNode, cbNodes, node.modifiers) || - visitNode(cbNode, (node as ParameterDeclaration).dotDotDotToken) || - visitNode(cbNode, (node as ParameterDeclaration).name) || - visitNode(cbNode, (node as ParameterDeclaration).questionToken) || - visitNode(cbNode, (node as ParameterDeclaration).type) || - visitNode(cbNode, (node as ParameterDeclaration).initializer); - case SyntaxKind.PropertyDeclaration: + visitNode(cbNode, (node as ts.ParameterDeclaration).dotDotDotToken) || + visitNode(cbNode, (node as ts.ParameterDeclaration).name) || + visitNode(cbNode, (node as ts.ParameterDeclaration).questionToken) || + visitNode(cbNode, (node as ts.ParameterDeclaration).type) || + visitNode(cbNode, (node as ts.ParameterDeclaration).initializer); + case ts.SyntaxKind.PropertyDeclaration: return visitNodes(cbNode, cbNodes, node.decorators) || visitNodes(cbNode, cbNodes, node.modifiers) || - visitNode(cbNode, (node as PropertyDeclaration).name) || - visitNode(cbNode, (node as PropertyDeclaration).questionToken) || - visitNode(cbNode, (node as PropertyDeclaration).exclamationToken) || - visitNode(cbNode, (node as PropertyDeclaration).type) || - visitNode(cbNode, (node as PropertyDeclaration).initializer); - case SyntaxKind.PropertySignature: + visitNode(cbNode, (node as ts.PropertyDeclaration).name) || + visitNode(cbNode, (node as ts.PropertyDeclaration).questionToken) || + visitNode(cbNode, (node as ts.PropertyDeclaration).exclamationToken) || + visitNode(cbNode, (node as ts.PropertyDeclaration).type) || + visitNode(cbNode, (node as ts.PropertyDeclaration).initializer); + case ts.SyntaxKind.PropertySignature: return visitNodes(cbNode, cbNodes, node.decorators) || visitNodes(cbNode, cbNodes, node.modifiers) || - visitNode(cbNode, (node as PropertySignature).name) || - visitNode(cbNode, (node as PropertySignature).questionToken) || - visitNode(cbNode, (node as PropertySignature).type) || - visitNode(cbNode, (node as PropertySignature).initializer); - case SyntaxKind.PropertyAssignment: + visitNode(cbNode, (node as ts.PropertySignature).name) || + visitNode(cbNode, (node as ts.PropertySignature).questionToken) || + visitNode(cbNode, (node as ts.PropertySignature).type) || + visitNode(cbNode, (node as ts.PropertySignature).initializer); + case ts.SyntaxKind.PropertyAssignment: return visitNodes(cbNode, cbNodes, node.decorators) || visitNodes(cbNode, cbNodes, node.modifiers) || - visitNode(cbNode, (node as PropertyAssignment).name) || - visitNode(cbNode, (node as PropertyAssignment).questionToken) || - visitNode(cbNode, (node as PropertyAssignment).initializer); - case SyntaxKind.VariableDeclaration: + visitNode(cbNode, (node as ts.PropertyAssignment).name) || + visitNode(cbNode, (node as ts.PropertyAssignment).questionToken) || + visitNode(cbNode, (node as ts.PropertyAssignment).initializer); + case ts.SyntaxKind.VariableDeclaration: return visitNodes(cbNode, cbNodes, node.decorators) || visitNodes(cbNode, cbNodes, node.modifiers) || - visitNode(cbNode, (node as VariableDeclaration).name) || - visitNode(cbNode, (node as VariableDeclaration).exclamationToken) || - visitNode(cbNode, (node as VariableDeclaration).type) || - visitNode(cbNode, (node as VariableDeclaration).initializer); - case SyntaxKind.BindingElement: + visitNode(cbNode, (node as ts.VariableDeclaration).name) || + visitNode(cbNode, (node as ts.VariableDeclaration).exclamationToken) || + visitNode(cbNode, (node as ts.VariableDeclaration).type) || + visitNode(cbNode, (node as ts.VariableDeclaration).initializer); + case ts.SyntaxKind.BindingElement: return visitNodes(cbNode, cbNodes, node.decorators) || visitNodes(cbNode, cbNodes, node.modifiers) || - visitNode(cbNode, (node as BindingElement).dotDotDotToken) || - visitNode(cbNode, (node as BindingElement).propertyName) || - visitNode(cbNode, (node as BindingElement).name) || - visitNode(cbNode, (node as BindingElement).initializer); - case SyntaxKind.FunctionType: - case SyntaxKind.ConstructorType: - case SyntaxKind.CallSignature: - case SyntaxKind.ConstructSignature: - case SyntaxKind.IndexSignature: + visitNode(cbNode, (node as ts.BindingElement).dotDotDotToken) || + visitNode(cbNode, (node as ts.BindingElement).propertyName) || + visitNode(cbNode, (node as ts.BindingElement).name) || + visitNode(cbNode, (node as ts.BindingElement).initializer); + case ts.SyntaxKind.FunctionType: + case ts.SyntaxKind.ConstructorType: + case ts.SyntaxKind.CallSignature: + case ts.SyntaxKind.ConstructSignature: + case ts.SyntaxKind.IndexSignature: return visitNodes(cbNode, cbNodes, node.decorators) || visitNodes(cbNode, cbNodes, node.modifiers) || - visitNodes(cbNode, cbNodes, (node as SignatureDeclaration).typeParameters) || - visitNodes(cbNode, cbNodes, (node as SignatureDeclaration).parameters) || - visitNode(cbNode, (node as SignatureDeclaration).type); - case SyntaxKind.MethodDeclaration: - case SyntaxKind.MethodSignature: - case SyntaxKind.Constructor: - case SyntaxKind.GetAccessor: - case SyntaxKind.SetAccessor: - case SyntaxKind.FunctionExpression: - case SyntaxKind.FunctionDeclaration: - case SyntaxKind.ArrowFunction: + visitNodes(cbNode, cbNodes, (node as ts.SignatureDeclaration).typeParameters) || + visitNodes(cbNode, cbNodes, (node as ts.SignatureDeclaration).parameters) || + visitNode(cbNode, (node as ts.SignatureDeclaration).type); + case ts.SyntaxKind.MethodDeclaration: + case ts.SyntaxKind.MethodSignature: + case ts.SyntaxKind.Constructor: + case ts.SyntaxKind.GetAccessor: + case ts.SyntaxKind.SetAccessor: + case ts.SyntaxKind.FunctionExpression: + case ts.SyntaxKind.FunctionDeclaration: + case ts.SyntaxKind.ArrowFunction: return visitNodes(cbNode, cbNodes, node.decorators) || visitNodes(cbNode, cbNodes, node.modifiers) || - visitNode(cbNode, (node as FunctionLikeDeclaration).asteriskToken) || - visitNode(cbNode, (node as FunctionLikeDeclaration).name) || - visitNode(cbNode, (node as FunctionLikeDeclaration).questionToken) || - visitNode(cbNode, (node as FunctionLikeDeclaration).exclamationToken) || - visitNodes(cbNode, cbNodes, (node as FunctionLikeDeclaration).typeParameters) || - visitNodes(cbNode, cbNodes, (node as FunctionLikeDeclaration).parameters) || - visitNode(cbNode, (node as FunctionLikeDeclaration).type) || - visitNode(cbNode, (node as ArrowFunction).equalsGreaterThanToken) || - visitNode(cbNode, (node as FunctionLikeDeclaration).body); - case SyntaxKind.ClassStaticBlockDeclaration: + visitNode(cbNode, (node as ts.FunctionLikeDeclaration).asteriskToken) || + visitNode(cbNode, (node as ts.FunctionLikeDeclaration).name) || + visitNode(cbNode, (node as ts.FunctionLikeDeclaration).questionToken) || + visitNode(cbNode, (node as ts.FunctionLikeDeclaration).exclamationToken) || + visitNodes(cbNode, cbNodes, (node as ts.FunctionLikeDeclaration).typeParameters) || + visitNodes(cbNode, cbNodes, (node as ts.FunctionLikeDeclaration).parameters) || + visitNode(cbNode, (node as ts.FunctionLikeDeclaration).type) || + visitNode(cbNode, (node as ts.ArrowFunction).equalsGreaterThanToken) || + visitNode(cbNode, (node as ts.FunctionLikeDeclaration).body); + case ts.SyntaxKind.ClassStaticBlockDeclaration: return visitNodes(cbNode, cbNodes, node.decorators) || visitNodes(cbNode, cbNodes, node.modifiers) || - visitNode(cbNode, (node as ClassStaticBlockDeclaration).body); - case SyntaxKind.TypeReference: - return visitNode(cbNode, (node as TypeReferenceNode).typeName) || - visitNodes(cbNode, cbNodes, (node as TypeReferenceNode).typeArguments); - case SyntaxKind.TypePredicate: - return visitNode(cbNode, (node as TypePredicateNode).assertsModifier) || - visitNode(cbNode, (node as TypePredicateNode).parameterName) || - visitNode(cbNode, (node as TypePredicateNode).type); - case SyntaxKind.TypeQuery: - return visitNode(cbNode, (node as TypeQueryNode).exprName) || - visitNodes(cbNode, cbNodes, (node as TypeQueryNode).typeArguments); - case SyntaxKind.TypeLiteral: - return visitNodes(cbNode, cbNodes, (node as TypeLiteralNode).members); - case SyntaxKind.ArrayType: - return visitNode(cbNode, (node as ArrayTypeNode).elementType); - case SyntaxKind.TupleType: - return visitNodes(cbNode, cbNodes, (node as TupleTypeNode).elements); - case SyntaxKind.UnionType: - case SyntaxKind.IntersectionType: - return visitNodes(cbNode, cbNodes, (node as UnionOrIntersectionTypeNode).types); - case SyntaxKind.ConditionalType: - return visitNode(cbNode, (node as ConditionalTypeNode).checkType) || - visitNode(cbNode, (node as ConditionalTypeNode).extendsType) || - visitNode(cbNode, (node as ConditionalTypeNode).trueType) || - visitNode(cbNode, (node as ConditionalTypeNode).falseType); - case SyntaxKind.InferType: - return visitNode(cbNode, (node as InferTypeNode).typeParameter); - case SyntaxKind.ImportType: - return visitNode(cbNode, (node as ImportTypeNode).argument) || - visitNode(cbNode, (node as ImportTypeNode).assertions) || - visitNode(cbNode, (node as ImportTypeNode).qualifier) || - visitNodes(cbNode, cbNodes, (node as ImportTypeNode).typeArguments); - case SyntaxKind.ImportTypeAssertionContainer: - return visitNode(cbNode, (node as ImportTypeAssertionContainer).assertClause); - case SyntaxKind.ParenthesizedType: - case SyntaxKind.TypeOperator: - return visitNode(cbNode, (node as ParenthesizedTypeNode | TypeOperatorNode).type); - case SyntaxKind.IndexedAccessType: - return visitNode(cbNode, (node as IndexedAccessTypeNode).objectType) || - visitNode(cbNode, (node as IndexedAccessTypeNode).indexType); - case SyntaxKind.MappedType: - return visitNode(cbNode, (node as MappedTypeNode).readonlyToken) || - visitNode(cbNode, (node as MappedTypeNode).typeParameter) || - visitNode(cbNode, (node as MappedTypeNode).nameType) || - visitNode(cbNode, (node as MappedTypeNode).questionToken) || - visitNode(cbNode, (node as MappedTypeNode).type) || - visitNodes(cbNode, cbNodes, (node as MappedTypeNode).members); - case SyntaxKind.LiteralType: - return visitNode(cbNode, (node as LiteralTypeNode).literal); - case SyntaxKind.NamedTupleMember: - return visitNode(cbNode, (node as NamedTupleMember).dotDotDotToken) || - visitNode(cbNode, (node as NamedTupleMember).name) || - visitNode(cbNode, (node as NamedTupleMember).questionToken) || - visitNode(cbNode, (node as NamedTupleMember).type); - case SyntaxKind.ObjectBindingPattern: - case SyntaxKind.ArrayBindingPattern: - return visitNodes(cbNode, cbNodes, (node as BindingPattern).elements); - case SyntaxKind.ArrayLiteralExpression: - return visitNodes(cbNode, cbNodes, (node as ArrayLiteralExpression).elements); - case SyntaxKind.ObjectLiteralExpression: - return visitNodes(cbNode, cbNodes, (node as ObjectLiteralExpression).properties); - case SyntaxKind.PropertyAccessExpression: - return visitNode(cbNode, (node as PropertyAccessExpression).expression) || - visitNode(cbNode, (node as PropertyAccessExpression).questionDotToken) || - visitNode(cbNode, (node as PropertyAccessExpression).name); - case SyntaxKind.ElementAccessExpression: - return visitNode(cbNode, (node as ElementAccessExpression).expression) || - visitNode(cbNode, (node as ElementAccessExpression).questionDotToken) || - visitNode(cbNode, (node as ElementAccessExpression).argumentExpression); - case SyntaxKind.CallExpression: - case SyntaxKind.NewExpression: - return visitNode(cbNode, (node as CallExpression).expression) || - visitNode(cbNode, (node as CallExpression).questionDotToken) || - visitNodes(cbNode, cbNodes, (node as CallExpression).typeArguments) || - visitNodes(cbNode, cbNodes, (node as CallExpression).arguments); - case SyntaxKind.TaggedTemplateExpression: - return visitNode(cbNode, (node as TaggedTemplateExpression).tag) || - visitNode(cbNode, (node as TaggedTemplateExpression).questionDotToken) || - visitNodes(cbNode, cbNodes, (node as TaggedTemplateExpression).typeArguments) || - visitNode(cbNode, (node as TaggedTemplateExpression).template); - case SyntaxKind.TypeAssertionExpression: - return visitNode(cbNode, (node as TypeAssertion).type) || - visitNode(cbNode, (node as TypeAssertion).expression); - case SyntaxKind.ParenthesizedExpression: - return visitNode(cbNode, (node as ParenthesizedExpression).expression); - case SyntaxKind.DeleteExpression: - return visitNode(cbNode, (node as DeleteExpression).expression); - case SyntaxKind.TypeOfExpression: - return visitNode(cbNode, (node as TypeOfExpression).expression); - case SyntaxKind.VoidExpression: - return visitNode(cbNode, (node as VoidExpression).expression); - case SyntaxKind.PrefixUnaryExpression: - return visitNode(cbNode, (node as PrefixUnaryExpression).operand); - case SyntaxKind.YieldExpression: - return visitNode(cbNode, (node as YieldExpression).asteriskToken) || - visitNode(cbNode, (node as YieldExpression).expression); - case SyntaxKind.AwaitExpression: - return visitNode(cbNode, (node as AwaitExpression).expression); - case SyntaxKind.PostfixUnaryExpression: - return visitNode(cbNode, (node as PostfixUnaryExpression).operand); - case SyntaxKind.BinaryExpression: - return visitNode(cbNode, (node as BinaryExpression).left) || - visitNode(cbNode, (node as BinaryExpression).operatorToken) || - visitNode(cbNode, (node as BinaryExpression).right); - case SyntaxKind.AsExpression: - return visitNode(cbNode, (node as AsExpression).expression) || - visitNode(cbNode, (node as AsExpression).type); - case SyntaxKind.NonNullExpression: - return visitNode(cbNode, (node as NonNullExpression).expression); - case SyntaxKind.MetaProperty: - return visitNode(cbNode, (node as MetaProperty).name); - case SyntaxKind.ConditionalExpression: - return visitNode(cbNode, (node as ConditionalExpression).condition) || - visitNode(cbNode, (node as ConditionalExpression).questionToken) || - visitNode(cbNode, (node as ConditionalExpression).whenTrue) || - visitNode(cbNode, (node as ConditionalExpression).colonToken) || - visitNode(cbNode, (node as ConditionalExpression).whenFalse); - case SyntaxKind.SpreadElement: - return visitNode(cbNode, (node as SpreadElement).expression); - case SyntaxKind.Block: - case SyntaxKind.ModuleBlock: - return visitNodes(cbNode, cbNodes, (node as Block).statements); - case SyntaxKind.SourceFile: - return visitNodes(cbNode, cbNodes, (node as SourceFile).statements) || - visitNode(cbNode, (node as SourceFile).endOfFileToken); - case SyntaxKind.VariableStatement: + visitNode(cbNode, (node as ts.ClassStaticBlockDeclaration).body); + case ts.SyntaxKind.TypeReference: + return visitNode(cbNode, (node as ts.TypeReferenceNode).typeName) || + visitNodes(cbNode, cbNodes, (node as ts.TypeReferenceNode).typeArguments); + case ts.SyntaxKind.TypePredicate: + return visitNode(cbNode, (node as ts.TypePredicateNode).assertsModifier) || + visitNode(cbNode, (node as ts.TypePredicateNode).parameterName) || + visitNode(cbNode, (node as ts.TypePredicateNode).type); + case ts.SyntaxKind.TypeQuery: + return visitNode(cbNode, (node as ts.TypeQueryNode).exprName) || + visitNodes(cbNode, cbNodes, (node as ts.TypeQueryNode).typeArguments); + case ts.SyntaxKind.TypeLiteral: + return visitNodes(cbNode, cbNodes, (node as ts.TypeLiteralNode).members); + case ts.SyntaxKind.ArrayType: + return visitNode(cbNode, (node as ts.ArrayTypeNode).elementType); + case ts.SyntaxKind.TupleType: + return visitNodes(cbNode, cbNodes, (node as ts.TupleTypeNode).elements); + case ts.SyntaxKind.UnionType: + case ts.SyntaxKind.IntersectionType: + return visitNodes(cbNode, cbNodes, (node as ts.UnionOrIntersectionTypeNode).types); + case ts.SyntaxKind.ConditionalType: + return visitNode(cbNode, (node as ts.ConditionalTypeNode).checkType) || + visitNode(cbNode, (node as ts.ConditionalTypeNode).extendsType) || + visitNode(cbNode, (node as ts.ConditionalTypeNode).trueType) || + visitNode(cbNode, (node as ts.ConditionalTypeNode).falseType); + case ts.SyntaxKind.InferType: + return visitNode(cbNode, (node as ts.InferTypeNode).typeParameter); + case ts.SyntaxKind.ImportType: + return visitNode(cbNode, (node as ts.ImportTypeNode).argument) || + visitNode(cbNode, (node as ts.ImportTypeNode).assertions) || + visitNode(cbNode, (node as ts.ImportTypeNode).qualifier) || + visitNodes(cbNode, cbNodes, (node as ts.ImportTypeNode).typeArguments); + case ts.SyntaxKind.ImportTypeAssertionContainer: + return visitNode(cbNode, (node as ts.ImportTypeAssertionContainer).assertClause); + case ts.SyntaxKind.ParenthesizedType: + case ts.SyntaxKind.TypeOperator: + return visitNode(cbNode, (node as ts.ParenthesizedTypeNode | ts.TypeOperatorNode).type); + case ts.SyntaxKind.IndexedAccessType: + return visitNode(cbNode, (node as ts.IndexedAccessTypeNode).objectType) || + visitNode(cbNode, (node as ts.IndexedAccessTypeNode).indexType); + case ts.SyntaxKind.MappedType: + return visitNode(cbNode, (node as ts.MappedTypeNode).readonlyToken) || + visitNode(cbNode, (node as ts.MappedTypeNode).typeParameter) || + visitNode(cbNode, (node as ts.MappedTypeNode).nameType) || + visitNode(cbNode, (node as ts.MappedTypeNode).questionToken) || + visitNode(cbNode, (node as ts.MappedTypeNode).type) || + visitNodes(cbNode, cbNodes, (node as ts.MappedTypeNode).members); + case ts.SyntaxKind.LiteralType: + return visitNode(cbNode, (node as ts.LiteralTypeNode).literal); + case ts.SyntaxKind.NamedTupleMember: + return visitNode(cbNode, (node as ts.NamedTupleMember).dotDotDotToken) || + visitNode(cbNode, (node as ts.NamedTupleMember).name) || + visitNode(cbNode, (node as ts.NamedTupleMember).questionToken) || + visitNode(cbNode, (node as ts.NamedTupleMember).type); + case ts.SyntaxKind.ObjectBindingPattern: + case ts.SyntaxKind.ArrayBindingPattern: + return visitNodes(cbNode, cbNodes, (node as ts.BindingPattern).elements); + case ts.SyntaxKind.ArrayLiteralExpression: + return visitNodes(cbNode, cbNodes, (node as ts.ArrayLiteralExpression).elements); + case ts.SyntaxKind.ObjectLiteralExpression: + return visitNodes(cbNode, cbNodes, (node as ts.ObjectLiteralExpression).properties); + case ts.SyntaxKind.PropertyAccessExpression: + return visitNode(cbNode, (node as ts.PropertyAccessExpression).expression) || + visitNode(cbNode, (node as ts.PropertyAccessExpression).questionDotToken) || + visitNode(cbNode, (node as ts.PropertyAccessExpression).name); + case ts.SyntaxKind.ElementAccessExpression: + return visitNode(cbNode, (node as ts.ElementAccessExpression).expression) || + visitNode(cbNode, (node as ts.ElementAccessExpression).questionDotToken) || + visitNode(cbNode, (node as ts.ElementAccessExpression).argumentExpression); + case ts.SyntaxKind.CallExpression: + case ts.SyntaxKind.NewExpression: + return visitNode(cbNode, (node as ts.CallExpression).expression) || + visitNode(cbNode, (node as ts.CallExpression).questionDotToken) || + visitNodes(cbNode, cbNodes, (node as ts.CallExpression).typeArguments) || + visitNodes(cbNode, cbNodes, (node as ts.CallExpression).arguments); + case ts.SyntaxKind.TaggedTemplateExpression: + return visitNode(cbNode, (node as ts.TaggedTemplateExpression).tag) || + visitNode(cbNode, (node as ts.TaggedTemplateExpression).questionDotToken) || + visitNodes(cbNode, cbNodes, (node as ts.TaggedTemplateExpression).typeArguments) || + visitNode(cbNode, (node as ts.TaggedTemplateExpression).template); + case ts.SyntaxKind.TypeAssertionExpression: + return visitNode(cbNode, (node as ts.TypeAssertion).type) || + visitNode(cbNode, (node as ts.TypeAssertion).expression); + case ts.SyntaxKind.ParenthesizedExpression: + return visitNode(cbNode, (node as ts.ParenthesizedExpression).expression); + case ts.SyntaxKind.DeleteExpression: + return visitNode(cbNode, (node as ts.DeleteExpression).expression); + case ts.SyntaxKind.TypeOfExpression: + return visitNode(cbNode, (node as ts.TypeOfExpression).expression); + case ts.SyntaxKind.VoidExpression: + return visitNode(cbNode, (node as ts.VoidExpression).expression); + case ts.SyntaxKind.PrefixUnaryExpression: + return visitNode(cbNode, (node as ts.PrefixUnaryExpression).operand); + case ts.SyntaxKind.YieldExpression: + return visitNode(cbNode, (node as ts.YieldExpression).asteriskToken) || + visitNode(cbNode, (node as ts.YieldExpression).expression); + case ts.SyntaxKind.AwaitExpression: + return visitNode(cbNode, (node as ts.AwaitExpression).expression); + case ts.SyntaxKind.PostfixUnaryExpression: + return visitNode(cbNode, (node as ts.PostfixUnaryExpression).operand); + case ts.SyntaxKind.BinaryExpression: + return visitNode(cbNode, (node as ts.BinaryExpression).left) || + visitNode(cbNode, (node as ts.BinaryExpression).operatorToken) || + visitNode(cbNode, (node as ts.BinaryExpression).right); + case ts.SyntaxKind.AsExpression: + return visitNode(cbNode, (node as ts.AsExpression).expression) || + visitNode(cbNode, (node as ts.AsExpression).type); + case ts.SyntaxKind.NonNullExpression: + return visitNode(cbNode, (node as ts.NonNullExpression).expression); + case ts.SyntaxKind.MetaProperty: + return visitNode(cbNode, (node as ts.MetaProperty).name); + case ts.SyntaxKind.ConditionalExpression: + return visitNode(cbNode, (node as ts.ConditionalExpression).condition) || + visitNode(cbNode, (node as ts.ConditionalExpression).questionToken) || + visitNode(cbNode, (node as ts.ConditionalExpression).whenTrue) || + visitNode(cbNode, (node as ts.ConditionalExpression).colonToken) || + visitNode(cbNode, (node as ts.ConditionalExpression).whenFalse); + case ts.SyntaxKind.SpreadElement: + return visitNode(cbNode, (node as ts.SpreadElement).expression); + case ts.SyntaxKind.Block: + case ts.SyntaxKind.ModuleBlock: + return visitNodes(cbNode, cbNodes, (node as ts.Block).statements); + case ts.SyntaxKind.SourceFile: + return visitNodes(cbNode, cbNodes, (node as ts.SourceFile).statements) || + visitNode(cbNode, (node as ts.SourceFile).endOfFileToken); + case ts.SyntaxKind.VariableStatement: return visitNodes(cbNode, cbNodes, node.decorators) || visitNodes(cbNode, cbNodes, node.modifiers) || - visitNode(cbNode, (node as VariableStatement).declarationList); - case SyntaxKind.VariableDeclarationList: - return visitNodes(cbNode, cbNodes, (node as VariableDeclarationList).declarations); - case SyntaxKind.ExpressionStatement: - return visitNode(cbNode, (node as ExpressionStatement).expression); - case SyntaxKind.IfStatement: - return visitNode(cbNode, (node as IfStatement).expression) || - visitNode(cbNode, (node as IfStatement).thenStatement) || - visitNode(cbNode, (node as IfStatement).elseStatement); - case SyntaxKind.DoStatement: - return visitNode(cbNode, (node as DoStatement).statement) || - visitNode(cbNode, (node as DoStatement).expression); - case SyntaxKind.WhileStatement: - return visitNode(cbNode, (node as WhileStatement).expression) || - visitNode(cbNode, (node as WhileStatement).statement); - case SyntaxKind.ForStatement: - return visitNode(cbNode, (node as ForStatement).initializer) || - visitNode(cbNode, (node as ForStatement).condition) || - visitNode(cbNode, (node as ForStatement).incrementor) || - visitNode(cbNode, (node as ForStatement).statement); - case SyntaxKind.ForInStatement: - return visitNode(cbNode, (node as ForInStatement).initializer) || - visitNode(cbNode, (node as ForInStatement).expression) || - visitNode(cbNode, (node as ForInStatement).statement); - case SyntaxKind.ForOfStatement: - return visitNode(cbNode, (node as ForOfStatement).awaitModifier) || - visitNode(cbNode, (node as ForOfStatement).initializer) || - visitNode(cbNode, (node as ForOfStatement).expression) || - visitNode(cbNode, (node as ForOfStatement).statement); - case SyntaxKind.ContinueStatement: - case SyntaxKind.BreakStatement: - return visitNode(cbNode, (node as BreakOrContinueStatement).label); - case SyntaxKind.ReturnStatement: - return visitNode(cbNode, (node as ReturnStatement).expression); - case SyntaxKind.WithStatement: - return visitNode(cbNode, (node as WithStatement).expression) || - visitNode(cbNode, (node as WithStatement).statement); - case SyntaxKind.SwitchStatement: - return visitNode(cbNode, (node as SwitchStatement).expression) || - visitNode(cbNode, (node as SwitchStatement).caseBlock); - case SyntaxKind.CaseBlock: - return visitNodes(cbNode, cbNodes, (node as CaseBlock).clauses); - case SyntaxKind.CaseClause: - return visitNode(cbNode, (node as CaseClause).expression) || - visitNodes(cbNode, cbNodes, (node as CaseClause).statements); - case SyntaxKind.DefaultClause: - return visitNodes(cbNode, cbNodes, (node as DefaultClause).statements); - case SyntaxKind.LabeledStatement: - return visitNode(cbNode, (node as LabeledStatement).label) || - visitNode(cbNode, (node as LabeledStatement).statement); - case SyntaxKind.ThrowStatement: - return visitNode(cbNode, (node as ThrowStatement).expression); - case SyntaxKind.TryStatement: - return visitNode(cbNode, (node as TryStatement).tryBlock) || - visitNode(cbNode, (node as TryStatement).catchClause) || - visitNode(cbNode, (node as TryStatement).finallyBlock); - case SyntaxKind.CatchClause: - return visitNode(cbNode, (node as CatchClause).variableDeclaration) || - visitNode(cbNode, (node as CatchClause).block); - case SyntaxKind.Decorator: - return visitNode(cbNode, (node as Decorator).expression); - case SyntaxKind.ClassDeclaration: - case SyntaxKind.ClassExpression: + visitNode(cbNode, (node as ts.VariableStatement).declarationList); + case ts.SyntaxKind.VariableDeclarationList: + return visitNodes(cbNode, cbNodes, (node as ts.VariableDeclarationList).declarations); + case ts.SyntaxKind.ExpressionStatement: + return visitNode(cbNode, (node as ts.ExpressionStatement).expression); + case ts.SyntaxKind.IfStatement: + return visitNode(cbNode, (node as ts.IfStatement).expression) || + visitNode(cbNode, (node as ts.IfStatement).thenStatement) || + visitNode(cbNode, (node as ts.IfStatement).elseStatement); + case ts.SyntaxKind.DoStatement: + return visitNode(cbNode, (node as ts.DoStatement).statement) || + visitNode(cbNode, (node as ts.DoStatement).expression); + case ts.SyntaxKind.WhileStatement: + return visitNode(cbNode, (node as ts.WhileStatement).expression) || + visitNode(cbNode, (node as ts.WhileStatement).statement); + case ts.SyntaxKind.ForStatement: + return visitNode(cbNode, (node as ts.ForStatement).initializer) || + visitNode(cbNode, (node as ts.ForStatement).condition) || + visitNode(cbNode, (node as ts.ForStatement).incrementor) || + visitNode(cbNode, (node as ts.ForStatement).statement); + case ts.SyntaxKind.ForInStatement: + return visitNode(cbNode, (node as ts.ForInStatement).initializer) || + visitNode(cbNode, (node as ts.ForInStatement).expression) || + visitNode(cbNode, (node as ts.ForInStatement).statement); + case ts.SyntaxKind.ForOfStatement: + return visitNode(cbNode, (node as ts.ForOfStatement).awaitModifier) || + visitNode(cbNode, (node as ts.ForOfStatement).initializer) || + visitNode(cbNode, (node as ts.ForOfStatement).expression) || + visitNode(cbNode, (node as ts.ForOfStatement).statement); + case ts.SyntaxKind.ContinueStatement: + case ts.SyntaxKind.BreakStatement: + return visitNode(cbNode, (node as ts.BreakOrContinueStatement).label); + case ts.SyntaxKind.ReturnStatement: + return visitNode(cbNode, (node as ts.ReturnStatement).expression); + case ts.SyntaxKind.WithStatement: + return visitNode(cbNode, (node as ts.WithStatement).expression) || + visitNode(cbNode, (node as ts.WithStatement).statement); + case ts.SyntaxKind.SwitchStatement: + return visitNode(cbNode, (node as ts.SwitchStatement).expression) || + visitNode(cbNode, (node as ts.SwitchStatement).caseBlock); + case ts.SyntaxKind.CaseBlock: + return visitNodes(cbNode, cbNodes, (node as ts.CaseBlock).clauses); + case ts.SyntaxKind.CaseClause: + return visitNode(cbNode, (node as ts.CaseClause).expression) || + visitNodes(cbNode, cbNodes, (node as ts.CaseClause).statements); + case ts.SyntaxKind.DefaultClause: + return visitNodes(cbNode, cbNodes, (node as ts.DefaultClause).statements); + case ts.SyntaxKind.LabeledStatement: + return visitNode(cbNode, (node as ts.LabeledStatement).label) || + visitNode(cbNode, (node as ts.LabeledStatement).statement); + case ts.SyntaxKind.ThrowStatement: + return visitNode(cbNode, (node as ts.ThrowStatement).expression); + case ts.SyntaxKind.TryStatement: + return visitNode(cbNode, (node as ts.TryStatement).tryBlock) || + visitNode(cbNode, (node as ts.TryStatement).catchClause) || + visitNode(cbNode, (node as ts.TryStatement).finallyBlock); + case ts.SyntaxKind.CatchClause: + return visitNode(cbNode, (node as ts.CatchClause).variableDeclaration) || + visitNode(cbNode, (node as ts.CatchClause).block); + case ts.SyntaxKind.Decorator: + return visitNode(cbNode, (node as ts.Decorator).expression); + case ts.SyntaxKind.ClassDeclaration: + case ts.SyntaxKind.ClassExpression: return visitNodes(cbNode, cbNodes, node.decorators) || visitNodes(cbNode, cbNodes, node.modifiers) || - visitNode(cbNode, (node as ClassLikeDeclaration).name) || - visitNodes(cbNode, cbNodes, (node as ClassLikeDeclaration).typeParameters) || - visitNodes(cbNode, cbNodes, (node as ClassLikeDeclaration).heritageClauses) || - visitNodes(cbNode, cbNodes, (node as ClassLikeDeclaration).members); - case SyntaxKind.InterfaceDeclaration: + visitNode(cbNode, (node as ts.ClassLikeDeclaration).name) || + visitNodes(cbNode, cbNodes, (node as ts.ClassLikeDeclaration).typeParameters) || + visitNodes(cbNode, cbNodes, (node as ts.ClassLikeDeclaration).heritageClauses) || + visitNodes(cbNode, cbNodes, (node as ts.ClassLikeDeclaration).members); + case ts.SyntaxKind.InterfaceDeclaration: return visitNodes(cbNode, cbNodes, node.decorators) || visitNodes(cbNode, cbNodes, node.modifiers) || - visitNode(cbNode, (node as InterfaceDeclaration).name) || - visitNodes(cbNode, cbNodes, (node as InterfaceDeclaration).typeParameters) || - visitNodes(cbNode, cbNodes, (node as ClassDeclaration).heritageClauses) || - visitNodes(cbNode, cbNodes, (node as InterfaceDeclaration).members); - case SyntaxKind.TypeAliasDeclaration: + visitNode(cbNode, (node as ts.InterfaceDeclaration).name) || + visitNodes(cbNode, cbNodes, (node as ts.InterfaceDeclaration).typeParameters) || + visitNodes(cbNode, cbNodes, (node as ts.ClassDeclaration).heritageClauses) || + visitNodes(cbNode, cbNodes, (node as ts.InterfaceDeclaration).members); + case ts.SyntaxKind.TypeAliasDeclaration: return visitNodes(cbNode, cbNodes, node.decorators) || visitNodes(cbNode, cbNodes, node.modifiers) || - visitNode(cbNode, (node as TypeAliasDeclaration).name) || - visitNodes(cbNode, cbNodes, (node as TypeAliasDeclaration).typeParameters) || - visitNode(cbNode, (node as TypeAliasDeclaration).type); - case SyntaxKind.EnumDeclaration: + visitNode(cbNode, (node as ts.TypeAliasDeclaration).name) || + visitNodes(cbNode, cbNodes, (node as ts.TypeAliasDeclaration).typeParameters) || + visitNode(cbNode, (node as ts.TypeAliasDeclaration).type); + case ts.SyntaxKind.EnumDeclaration: return visitNodes(cbNode, cbNodes, node.decorators) || visitNodes(cbNode, cbNodes, node.modifiers) || - visitNode(cbNode, (node as EnumDeclaration).name) || - visitNodes(cbNode, cbNodes, (node as EnumDeclaration).members); - case SyntaxKind.EnumMember: - return visitNode(cbNode, (node as EnumMember).name) || - visitNode(cbNode, (node as EnumMember).initializer); - case SyntaxKind.ModuleDeclaration: + visitNode(cbNode, (node as ts.EnumDeclaration).name) || + visitNodes(cbNode, cbNodes, (node as ts.EnumDeclaration).members); + case ts.SyntaxKind.EnumMember: + return visitNode(cbNode, (node as ts.EnumMember).name) || + visitNode(cbNode, (node as ts.EnumMember).initializer); + case ts.SyntaxKind.ModuleDeclaration: return visitNodes(cbNode, cbNodes, node.decorators) || visitNodes(cbNode, cbNodes, node.modifiers) || - visitNode(cbNode, (node as ModuleDeclaration).name) || - visitNode(cbNode, (node as ModuleDeclaration).body); - case SyntaxKind.ImportEqualsDeclaration: + visitNode(cbNode, (node as ts.ModuleDeclaration).name) || + visitNode(cbNode, (node as ts.ModuleDeclaration).body); + case ts.SyntaxKind.ImportEqualsDeclaration: return visitNodes(cbNode, cbNodes, node.decorators) || visitNodes(cbNode, cbNodes, node.modifiers) || - visitNode(cbNode, (node as ImportEqualsDeclaration).name) || - visitNode(cbNode, (node as ImportEqualsDeclaration).moduleReference); - case SyntaxKind.ImportDeclaration: + visitNode(cbNode, (node as ts.ImportEqualsDeclaration).name) || + visitNode(cbNode, (node as ts.ImportEqualsDeclaration).moduleReference); + case ts.SyntaxKind.ImportDeclaration: return visitNodes(cbNode, cbNodes, node.decorators) || visitNodes(cbNode, cbNodes, node.modifiers) || - visitNode(cbNode, (node as ImportDeclaration).importClause) || - visitNode(cbNode, (node as ImportDeclaration).moduleSpecifier) || - visitNode(cbNode, (node as ImportDeclaration).assertClause); - case SyntaxKind.ImportClause: - return visitNode(cbNode, (node as ImportClause).name) || - visitNode(cbNode, (node as ImportClause).namedBindings); - case SyntaxKind.AssertClause: - return visitNodes(cbNode, cbNodes, (node as AssertClause).elements); - case SyntaxKind.AssertEntry: - return visitNode(cbNode, (node as AssertEntry).name) || - visitNode(cbNode, (node as AssertEntry).value); - case SyntaxKind.NamespaceExportDeclaration: - return visitNode(cbNode, (node as NamespaceExportDeclaration).name); - case SyntaxKind.NamespaceImport: - return visitNode(cbNode, (node as NamespaceImport).name); - case SyntaxKind.NamespaceExport: - return visitNode(cbNode, (node as NamespaceExport).name); - case SyntaxKind.NamedImports: - case SyntaxKind.NamedExports: - return visitNodes(cbNode, cbNodes, (node as NamedImportsOrExports).elements); - case SyntaxKind.ExportDeclaration: + visitNode(cbNode, (node as ts.ImportDeclaration).importClause) || + visitNode(cbNode, (node as ts.ImportDeclaration).moduleSpecifier) || + visitNode(cbNode, (node as ts.ImportDeclaration).assertClause); + case ts.SyntaxKind.ImportClause: + return visitNode(cbNode, (node as ts.ImportClause).name) || + visitNode(cbNode, (node as ts.ImportClause).namedBindings); + case ts.SyntaxKind.AssertClause: + return visitNodes(cbNode, cbNodes, (node as ts.AssertClause).elements); + case ts.SyntaxKind.AssertEntry: + return visitNode(cbNode, (node as ts.AssertEntry).name) || + visitNode(cbNode, (node as ts.AssertEntry).value); + case ts.SyntaxKind.NamespaceExportDeclaration: + return visitNode(cbNode, (node as ts.NamespaceExportDeclaration).name); + case ts.SyntaxKind.NamespaceImport: + return visitNode(cbNode, (node as ts.NamespaceImport).name); + case ts.SyntaxKind.NamespaceExport: + return visitNode(cbNode, (node as ts.NamespaceExport).name); + case ts.SyntaxKind.NamedImports: + case ts.SyntaxKind.NamedExports: + return visitNodes(cbNode, cbNodes, (node as ts.NamedImportsOrExports).elements); + case ts.SyntaxKind.ExportDeclaration: return visitNodes(cbNode, cbNodes, node.decorators) || visitNodes(cbNode, cbNodes, node.modifiers) || - visitNode(cbNode, (node as ExportDeclaration).exportClause) || - visitNode(cbNode, (node as ExportDeclaration).moduleSpecifier) || - visitNode(cbNode, (node as ExportDeclaration).assertClause); - case SyntaxKind.ImportSpecifier: - case SyntaxKind.ExportSpecifier: - return visitNode(cbNode, (node as ImportOrExportSpecifier).propertyName) || - visitNode(cbNode, (node as ImportOrExportSpecifier).name); - case SyntaxKind.ExportAssignment: + visitNode(cbNode, (node as ts.ExportDeclaration).exportClause) || + visitNode(cbNode, (node as ts.ExportDeclaration).moduleSpecifier) || + visitNode(cbNode, (node as ts.ExportDeclaration).assertClause); + case ts.SyntaxKind.ImportSpecifier: + case ts.SyntaxKind.ExportSpecifier: + return visitNode(cbNode, (node as ts.ImportOrExportSpecifier).propertyName) || + visitNode(cbNode, (node as ts.ImportOrExportSpecifier).name); + case ts.SyntaxKind.ExportAssignment: return visitNodes(cbNode, cbNodes, node.decorators) || visitNodes(cbNode, cbNodes, node.modifiers) || - visitNode(cbNode, (node as ExportAssignment).expression); - case SyntaxKind.TemplateExpression: - return visitNode(cbNode, (node as TemplateExpression).head) || visitNodes(cbNode, cbNodes, (node as TemplateExpression).templateSpans); - case SyntaxKind.TemplateSpan: - return visitNode(cbNode, (node as TemplateSpan).expression) || visitNode(cbNode, (node as TemplateSpan).literal); - case SyntaxKind.TemplateLiteralType: - return visitNode(cbNode, (node as TemplateLiteralTypeNode).head) || visitNodes(cbNode, cbNodes, (node as TemplateLiteralTypeNode).templateSpans); - case SyntaxKind.TemplateLiteralTypeSpan: - return visitNode(cbNode, (node as TemplateLiteralTypeSpan).type) || visitNode(cbNode, (node as TemplateLiteralTypeSpan).literal); - case SyntaxKind.ComputedPropertyName: - return visitNode(cbNode, (node as ComputedPropertyName).expression); - case SyntaxKind.HeritageClause: - return visitNodes(cbNode, cbNodes, (node as HeritageClause).types); - case SyntaxKind.ExpressionWithTypeArguments: - return visitNode(cbNode, (node as ExpressionWithTypeArguments).expression) || - visitNodes(cbNode, cbNodes, (node as ExpressionWithTypeArguments).typeArguments); - case SyntaxKind.ExternalModuleReference: - return visitNode(cbNode, (node as ExternalModuleReference).expression); - case SyntaxKind.MissingDeclaration: + visitNode(cbNode, (node as ts.ExportAssignment).expression); + case ts.SyntaxKind.TemplateExpression: + return visitNode(cbNode, (node as ts.TemplateExpression).head) || visitNodes(cbNode, cbNodes, (node as ts.TemplateExpression).templateSpans); + case ts.SyntaxKind.TemplateSpan: + return visitNode(cbNode, (node as ts.TemplateSpan).expression) || visitNode(cbNode, (node as ts.TemplateSpan).literal); + case ts.SyntaxKind.TemplateLiteralType: + return visitNode(cbNode, (node as ts.TemplateLiteralTypeNode).head) || visitNodes(cbNode, cbNodes, (node as ts.TemplateLiteralTypeNode).templateSpans); + case ts.SyntaxKind.TemplateLiteralTypeSpan: + return visitNode(cbNode, (node as ts.TemplateLiteralTypeSpan).type) || visitNode(cbNode, (node as ts.TemplateLiteralTypeSpan).literal); + case ts.SyntaxKind.ComputedPropertyName: + return visitNode(cbNode, (node as ts.ComputedPropertyName).expression); + case ts.SyntaxKind.HeritageClause: + return visitNodes(cbNode, cbNodes, (node as ts.HeritageClause).types); + case ts.SyntaxKind.ExpressionWithTypeArguments: + return visitNode(cbNode, (node as ts.ExpressionWithTypeArguments).expression) || + visitNodes(cbNode, cbNodes, (node as ts.ExpressionWithTypeArguments).typeArguments); + case ts.SyntaxKind.ExternalModuleReference: + return visitNode(cbNode, (node as ts.ExternalModuleReference).expression); + case ts.SyntaxKind.MissingDeclaration: return visitNodes(cbNode, cbNodes, node.decorators); - case SyntaxKind.CommaListExpression: - return visitNodes(cbNode, cbNodes, (node as CommaListExpression).elements); - - case SyntaxKind.JsxElement: - return visitNode(cbNode, (node as JsxElement).openingElement) || - visitNodes(cbNode, cbNodes, (node as JsxElement).children) || - visitNode(cbNode, (node as JsxElement).closingElement); - case SyntaxKind.JsxFragment: - return visitNode(cbNode, (node as JsxFragment).openingFragment) || - visitNodes(cbNode, cbNodes, (node as JsxFragment).children) || - visitNode(cbNode, (node as JsxFragment).closingFragment); - case SyntaxKind.JsxSelfClosingElement: - case SyntaxKind.JsxOpeningElement: - return visitNode(cbNode, (node as JsxOpeningLikeElement).tagName) || - visitNodes(cbNode, cbNodes, (node as JsxOpeningLikeElement).typeArguments) || - visitNode(cbNode, (node as JsxOpeningLikeElement).attributes); - case SyntaxKind.JsxAttributes: - return visitNodes(cbNode, cbNodes, (node as JsxAttributes).properties); - case SyntaxKind.JsxAttribute: - return visitNode(cbNode, (node as JsxAttribute).name) || - visitNode(cbNode, (node as JsxAttribute).initializer); - case SyntaxKind.JsxSpreadAttribute: - return visitNode(cbNode, (node as JsxSpreadAttribute).expression); - case SyntaxKind.JsxExpression: - return visitNode(cbNode, (node as JsxExpression).dotDotDotToken) || - visitNode(cbNode, (node as JsxExpression).expression); - case SyntaxKind.JsxClosingElement: - return visitNode(cbNode, (node as JsxClosingElement).tagName); - - case SyntaxKind.OptionalType: - case SyntaxKind.RestType: - case SyntaxKind.JSDocTypeExpression: - case SyntaxKind.JSDocNonNullableType: - case SyntaxKind.JSDocNullableType: - case SyntaxKind.JSDocOptionalType: - case SyntaxKind.JSDocVariadicType: - return visitNode(cbNode, (node as OptionalTypeNode | RestTypeNode | JSDocTypeExpression | JSDocTypeReferencingNode).type); - case SyntaxKind.JSDocFunctionType: - return visitNodes(cbNode, cbNodes, (node as JSDocFunctionType).parameters) || - visitNode(cbNode, (node as JSDocFunctionType).type); - case SyntaxKind.JSDoc: - return (typeof (node as JSDoc).comment === "string" ? undefined : visitNodes(cbNode, cbNodes, (node as JSDoc).comment as NodeArray | undefined)) - || visitNodes(cbNode, cbNodes, (node as JSDoc).tags); - case SyntaxKind.JSDocSeeTag: - return visitNode(cbNode, (node as JSDocSeeTag).tagName) || - visitNode(cbNode, (node as JSDocSeeTag).name) || - (typeof (node as JSDoc).comment === "string" ? undefined : visitNodes(cbNode, cbNodes, (node as JSDoc).comment as NodeArray | undefined)); - case SyntaxKind.JSDocNameReference: - return visitNode(cbNode, (node as JSDocNameReference).name); - case SyntaxKind.JSDocMemberName: - return visitNode(cbNode, (node as JSDocMemberName).left) || - visitNode(cbNode, (node as JSDocMemberName).right); - case SyntaxKind.JSDocParameterTag: - case SyntaxKind.JSDocPropertyTag: - return visitNode(cbNode, (node as JSDocTag).tagName) || - ((node as JSDocPropertyLikeTag).isNameFirst - ? visitNode(cbNode, (node as JSDocPropertyLikeTag).name) || - visitNode(cbNode, (node as JSDocPropertyLikeTag).typeExpression) || - (typeof (node as JSDoc).comment === "string" ? undefined : visitNodes(cbNode, cbNodes, (node as JSDoc).comment as NodeArray | undefined)) - : visitNode(cbNode, (node as JSDocPropertyLikeTag).typeExpression) || - visitNode(cbNode, (node as JSDocPropertyLikeTag).name) || - (typeof (node as JSDoc).comment === "string" ? undefined : visitNodes(cbNode, cbNodes, (node as JSDoc).comment as NodeArray | undefined))); - case SyntaxKind.JSDocAuthorTag: - return visitNode(cbNode, (node as JSDocTag).tagName) || - (typeof (node as JSDoc).comment === "string" ? undefined : visitNodes(cbNode, cbNodes, (node as JSDoc).comment as NodeArray | undefined)); - case SyntaxKind.JSDocImplementsTag: - return visitNode(cbNode, (node as JSDocTag).tagName) || - visitNode(cbNode, (node as JSDocImplementsTag).class) || - (typeof (node as JSDoc).comment === "string" ? undefined : visitNodes(cbNode, cbNodes, (node as JSDoc).comment as NodeArray | undefined)); - case SyntaxKind.JSDocAugmentsTag: - return visitNode(cbNode, (node as JSDocTag).tagName) || - visitNode(cbNode, (node as JSDocAugmentsTag).class) || - (typeof (node as JSDoc).comment === "string" ? undefined : visitNodes(cbNode, cbNodes, (node as JSDoc).comment as NodeArray | undefined)); - case SyntaxKind.JSDocTemplateTag: - return visitNode(cbNode, (node as JSDocTag).tagName) || - visitNode(cbNode, (node as JSDocTemplateTag).constraint) || - visitNodes(cbNode, cbNodes, (node as JSDocTemplateTag).typeParameters) || - (typeof (node as JSDoc).comment === "string" ? undefined : visitNodes(cbNode, cbNodes, (node as JSDoc).comment as NodeArray | undefined)); - case SyntaxKind.JSDocTypedefTag: - return visitNode(cbNode, (node as JSDocTag).tagName) || - ((node as JSDocTypedefTag).typeExpression && - (node as JSDocTypedefTag).typeExpression!.kind === SyntaxKind.JSDocTypeExpression - ? visitNode(cbNode, (node as JSDocTypedefTag).typeExpression) || - visitNode(cbNode, (node as JSDocTypedefTag).fullName) || - (typeof (node as JSDoc).comment === "string" ? undefined : visitNodes(cbNode, cbNodes, (node as JSDoc).comment as NodeArray | undefined)) - : visitNode(cbNode, (node as JSDocTypedefTag).fullName) || - visitNode(cbNode, (node as JSDocTypedefTag).typeExpression) || - (typeof (node as JSDoc).comment === "string" ? undefined : visitNodes(cbNode, cbNodes, (node as JSDoc).comment as NodeArray | undefined))); - case SyntaxKind.JSDocCallbackTag: - return visitNode(cbNode, (node as JSDocTag).tagName) || - visitNode(cbNode, (node as JSDocCallbackTag).fullName) || - visitNode(cbNode, (node as JSDocCallbackTag).typeExpression) || - (typeof (node as JSDoc).comment === "string" ? undefined : visitNodes(cbNode, cbNodes, (node as JSDoc).comment as NodeArray | undefined)); - case SyntaxKind.JSDocReturnTag: - case SyntaxKind.JSDocTypeTag: - case SyntaxKind.JSDocThisTag: - case SyntaxKind.JSDocEnumTag: - return visitNode(cbNode, (node as JSDocTag).tagName) || - visitNode(cbNode, (node as JSDocReturnTag | JSDocTypeTag | JSDocThisTag | JSDocEnumTag).typeExpression) || - (typeof (node as JSDoc).comment === "string" ? undefined : visitNodes(cbNode, cbNodes, (node as JSDoc).comment as NodeArray | undefined)); - case SyntaxKind.JSDocSignature: - return forEach((node as JSDocSignature).typeParameters, cbNode) || - forEach((node as JSDocSignature).parameters, cbNode) || - visitNode(cbNode, (node as JSDocSignature).type); - case SyntaxKind.JSDocLink: - case SyntaxKind.JSDocLinkCode: - case SyntaxKind.JSDocLinkPlain: - return visitNode(cbNode, (node as JSDocLink | JSDocLinkCode | JSDocLinkPlain).name); - case SyntaxKind.JSDocTypeLiteral: - return forEach((node as JSDocTypeLiteral).jsDocPropertyTags, cbNode); - case SyntaxKind.JSDocTag: - case SyntaxKind.JSDocClassTag: - case SyntaxKind.JSDocPublicTag: - case SyntaxKind.JSDocPrivateTag: - case SyntaxKind.JSDocProtectedTag: - case SyntaxKind.JSDocReadonlyTag: - case SyntaxKind.JSDocDeprecatedTag: - return visitNode(cbNode, (node as JSDocTag).tagName) - || (typeof (node as JSDoc).comment === "string" ? undefined : visitNodes(cbNode, cbNodes, (node as JSDoc).comment as NodeArray | undefined)); - case SyntaxKind.PartiallyEmittedExpression: - return visitNode(cbNode, (node as PartiallyEmittedExpression).expression); + case ts.SyntaxKind.CommaListExpression: + return visitNodes(cbNode, cbNodes, (node as ts.CommaListExpression).elements); + case ts.SyntaxKind.JsxElement: + return visitNode(cbNode, (node as ts.JsxElement).openingElement) || + visitNodes(cbNode, cbNodes, (node as ts.JsxElement).children) || + visitNode(cbNode, (node as ts.JsxElement).closingElement); + case ts.SyntaxKind.JsxFragment: + return visitNode(cbNode, (node as ts.JsxFragment).openingFragment) || + visitNodes(cbNode, cbNodes, (node as ts.JsxFragment).children) || + visitNode(cbNode, (node as ts.JsxFragment).closingFragment); + case ts.SyntaxKind.JsxSelfClosingElement: + case ts.SyntaxKind.JsxOpeningElement: + return visitNode(cbNode, (node as ts.JsxOpeningLikeElement).tagName) || + visitNodes(cbNode, cbNodes, (node as ts.JsxOpeningLikeElement).typeArguments) || + visitNode(cbNode, (node as ts.JsxOpeningLikeElement).attributes); + case ts.SyntaxKind.JsxAttributes: + return visitNodes(cbNode, cbNodes, (node as ts.JsxAttributes).properties); + case ts.SyntaxKind.JsxAttribute: + return visitNode(cbNode, (node as ts.JsxAttribute).name) || + visitNode(cbNode, (node as ts.JsxAttribute).initializer); + case ts.SyntaxKind.JsxSpreadAttribute: + return visitNode(cbNode, (node as ts.JsxSpreadAttribute).expression); + case ts.SyntaxKind.JsxExpression: + return visitNode(cbNode, (node as ts.JsxExpression).dotDotDotToken) || + visitNode(cbNode, (node as ts.JsxExpression).expression); + case ts.SyntaxKind.JsxClosingElement: + return visitNode(cbNode, (node as ts.JsxClosingElement).tagName); + case ts.SyntaxKind.OptionalType: + case ts.SyntaxKind.RestType: + case ts.SyntaxKind.JSDocTypeExpression: + case ts.SyntaxKind.JSDocNonNullableType: + case ts.SyntaxKind.JSDocNullableType: + case ts.SyntaxKind.JSDocOptionalType: + case ts.SyntaxKind.JSDocVariadicType: + return visitNode(cbNode, (node as ts.OptionalTypeNode | ts.RestTypeNode | ts.JSDocTypeExpression | ts.JSDocTypeReferencingNode).type); + case ts.SyntaxKind.JSDocFunctionType: + return visitNodes(cbNode, cbNodes, (node as ts.JSDocFunctionType).parameters) || + visitNode(cbNode, (node as ts.JSDocFunctionType).type); + case ts.SyntaxKind.JSDoc: + return (typeof (node as ts.JSDoc).comment === "string" ? undefined : visitNodes(cbNode, cbNodes, (node as ts.JSDoc).comment as ts.NodeArray | undefined)) + || visitNodes(cbNode, cbNodes, (node as ts.JSDoc).tags); + case ts.SyntaxKind.JSDocSeeTag: + return visitNode(cbNode, (node as ts.JSDocSeeTag).tagName) || + visitNode(cbNode, (node as ts.JSDocSeeTag).name) || + (typeof (node as ts.JSDoc).comment === "string" ? undefined : visitNodes(cbNode, cbNodes, (node as ts.JSDoc).comment as ts.NodeArray | undefined)); + case ts.SyntaxKind.JSDocNameReference: + return visitNode(cbNode, (node as ts.JSDocNameReference).name); + case ts.SyntaxKind.JSDocMemberName: + return visitNode(cbNode, (node as ts.JSDocMemberName).left) || + visitNode(cbNode, (node as ts.JSDocMemberName).right); + case ts.SyntaxKind.JSDocParameterTag: + case ts.SyntaxKind.JSDocPropertyTag: + return visitNode(cbNode, (node as ts.JSDocTag).tagName) || + ((node as ts.JSDocPropertyLikeTag).isNameFirst + ? visitNode(cbNode, (node as ts.JSDocPropertyLikeTag).name) || + visitNode(cbNode, (node as ts.JSDocPropertyLikeTag).typeExpression) || + (typeof (node as ts.JSDoc).comment === "string" ? undefined : visitNodes(cbNode, cbNodes, (node as ts.JSDoc).comment as ts.NodeArray | undefined)) + : visitNode(cbNode, (node as ts.JSDocPropertyLikeTag).typeExpression) || + visitNode(cbNode, (node as ts.JSDocPropertyLikeTag).name) || + (typeof (node as ts.JSDoc).comment === "string" ? undefined : visitNodes(cbNode, cbNodes, (node as ts.JSDoc).comment as ts.NodeArray | undefined))); + case ts.SyntaxKind.JSDocAuthorTag: + return visitNode(cbNode, (node as ts.JSDocTag).tagName) || + (typeof (node as ts.JSDoc).comment === "string" ? undefined : visitNodes(cbNode, cbNodes, (node as ts.JSDoc).comment as ts.NodeArray | undefined)); + case ts.SyntaxKind.JSDocImplementsTag: + return visitNode(cbNode, (node as ts.JSDocTag).tagName) || + visitNode(cbNode, (node as ts.JSDocImplementsTag).class) || + (typeof (node as ts.JSDoc).comment === "string" ? undefined : visitNodes(cbNode, cbNodes, (node as ts.JSDoc).comment as ts.NodeArray | undefined)); + case ts.SyntaxKind.JSDocAugmentsTag: + return visitNode(cbNode, (node as ts.JSDocTag).tagName) || + visitNode(cbNode, (node as ts.JSDocAugmentsTag).class) || + (typeof (node as ts.JSDoc).comment === "string" ? undefined : visitNodes(cbNode, cbNodes, (node as ts.JSDoc).comment as ts.NodeArray | undefined)); + case ts.SyntaxKind.JSDocTemplateTag: + return visitNode(cbNode, (node as ts.JSDocTag).tagName) || + visitNode(cbNode, (node as ts.JSDocTemplateTag).constraint) || + visitNodes(cbNode, cbNodes, (node as ts.JSDocTemplateTag).typeParameters) || + (typeof (node as ts.JSDoc).comment === "string" ? undefined : visitNodes(cbNode, cbNodes, (node as ts.JSDoc).comment as ts.NodeArray | undefined)); + case ts.SyntaxKind.JSDocTypedefTag: + return visitNode(cbNode, (node as ts.JSDocTag).tagName) || + ((node as ts.JSDocTypedefTag).typeExpression && + (node as ts.JSDocTypedefTag).typeExpression!.kind === ts.SyntaxKind.JSDocTypeExpression + ? visitNode(cbNode, (node as ts.JSDocTypedefTag).typeExpression) || + visitNode(cbNode, (node as ts.JSDocTypedefTag).fullName) || + (typeof (node as ts.JSDoc).comment === "string" ? undefined : visitNodes(cbNode, cbNodes, (node as ts.JSDoc).comment as ts.NodeArray | undefined)) + : visitNode(cbNode, (node as ts.JSDocTypedefTag).fullName) || + visitNode(cbNode, (node as ts.JSDocTypedefTag).typeExpression) || + (typeof (node as ts.JSDoc).comment === "string" ? undefined : visitNodes(cbNode, cbNodes, (node as ts.JSDoc).comment as ts.NodeArray | undefined))); + case ts.SyntaxKind.JSDocCallbackTag: + return visitNode(cbNode, (node as ts.JSDocTag).tagName) || + visitNode(cbNode, (node as ts.JSDocCallbackTag).fullName) || + visitNode(cbNode, (node as ts.JSDocCallbackTag).typeExpression) || + (typeof (node as ts.JSDoc).comment === "string" ? undefined : visitNodes(cbNode, cbNodes, (node as ts.JSDoc).comment as ts.NodeArray | undefined)); + case ts.SyntaxKind.JSDocReturnTag: + case ts.SyntaxKind.JSDocTypeTag: + case ts.SyntaxKind.JSDocThisTag: + case ts.SyntaxKind.JSDocEnumTag: + return visitNode(cbNode, (node as ts.JSDocTag).tagName) || + visitNode(cbNode, (node as ts.JSDocReturnTag | ts.JSDocTypeTag | ts.JSDocThisTag | ts.JSDocEnumTag).typeExpression) || + (typeof (node as ts.JSDoc).comment === "string" ? undefined : visitNodes(cbNode, cbNodes, (node as ts.JSDoc).comment as ts.NodeArray | undefined)); + case ts.SyntaxKind.JSDocSignature: + return ts.forEach((node as ts.JSDocSignature).typeParameters, cbNode) || + ts.forEach((node as ts.JSDocSignature).parameters, cbNode) || + visitNode(cbNode, (node as ts.JSDocSignature).type); + case ts.SyntaxKind.JSDocLink: + case ts.SyntaxKind.JSDocLinkCode: + case ts.SyntaxKind.JSDocLinkPlain: + return visitNode(cbNode, (node as ts.JSDocLink | ts.JSDocLinkCode | ts.JSDocLinkPlain).name); + case ts.SyntaxKind.JSDocTypeLiteral: + return ts.forEach((node as ts.JSDocTypeLiteral).jsDocPropertyTags, cbNode); + case ts.SyntaxKind.JSDocTag: + case ts.SyntaxKind.JSDocClassTag: + case ts.SyntaxKind.JSDocPublicTag: + case ts.SyntaxKind.JSDocPrivateTag: + case ts.SyntaxKind.JSDocProtectedTag: + case ts.SyntaxKind.JSDocReadonlyTag: + case ts.SyntaxKind.JSDocDeprecatedTag: + return visitNode(cbNode, (node as ts.JSDocTag).tagName) + || (typeof (node as ts.JSDoc).comment === "string" ? undefined : visitNodes(cbNode, cbNodes, (node as ts.JSDoc).comment as ts.NodeArray | undefined)); + case ts.SyntaxKind.PartiallyEmittedExpression: + return visitNode(cbNode, (node as ts.PartiallyEmittedExpression).expression); } } @@ -629,20 +625,21 @@ namespace ts { * @remarks Unlike `forEachChild`, `forEachChildRecursively` handles recursively invoking the traversal on each child node found, * and while doing so, handles traversing the structure without relying on the callstack to encode the tree structure. */ - export function forEachChildRecursively(rootNode: Node, cbNode: (node: Node, parent: Node) => T | "skip" | undefined, cbNodes?: (nodes: NodeArray, parent: Node) => T | "skip" | undefined): T | undefined { - const queue: (Node | NodeArray)[] = gatherPossibleChildren(rootNode); - const parents: Node[] = []; // tracks parent references for elements in queue + export function forEachChildRecursively(rootNode: ts.Node, cbNode: (node: ts.Node, parent: ts.Node) => T | "skip" | undefined, cbNodes?: (nodes: ts.NodeArray, parent: ts.Node) => T | "skip" | undefined): T | undefined { + const queue: (ts.Node | ts.NodeArray)[] = gatherPossibleChildren(rootNode); + const parents: ts.Node[] = []; // tracks parent references for elements in queue while (parents.length < queue.length) { parents.push(rootNode); } while (queue.length !== 0) { const current = queue.pop()!; const parent = parents.pop()!; - if (isArray(current)) { + if (ts.isArray(current)) { if (cbNodes) { const res = cbNodes(current, parent); if (res) { - if (res === "skip") continue; + if (res === "skip") + continue; return res; } } @@ -654,10 +651,11 @@ namespace ts { else { const res = cbNode(current, parent); if (res) { - if (res === "skip") continue; + if (res === "skip") + continue; return res; } - if (current.kind >= SyntaxKind.FirstNode) { + if (current.kind >= ts.SyntaxKind.FirstNode) { // add children in reverse order to the queue, so popping gives the first child for (const child of gatherPossibleChildren(current)) { queue.push(child); @@ -668,66 +666,60 @@ namespace ts { } } - function gatherPossibleChildren(node: Node) { - const children: (Node | NodeArray)[] = []; + function gatherPossibleChildren(node: ts.Node) { + const children: (ts.Node | ts.NodeArray)[] = []; forEachChild(node, addWorkItem, addWorkItem); // By using a stack above and `unshift` here, we emulate a depth-first preorder traversal return children; - function addWorkItem(n: Node | NodeArray) { + function addWorkItem(n: ts.Node | ts.NodeArray) { children.unshift(n); } } export interface CreateSourceFileOptions { - languageVersion: ScriptTarget; + languageVersion: ts.ScriptTarget; /** * Controls the format the file is detected as - this can be derived from only the path * and files on disk, but needs to be done with a module resolution cache in scope to be performant. * This is usually `undefined` for compilations that do not have `moduleResolution` values of `node16` or `nodenext`. */ - impliedNodeFormat?: ModuleKind.ESNext | ModuleKind.CommonJS; + impliedNodeFormat?: ts.ModuleKind.ESNext | ts.ModuleKind.CommonJS; /** * Controls how module-y-ness is set for the given file. Usually the result of calling * `getSetExternalModuleIndicator` on a valid `CompilerOptions` object. If not present, the default * check specified by `isFileProbablyExternalModule` will be used to set the field. */ - setExternalModuleIndicator?: (file: SourceFile) => void; + setExternalModuleIndicator?: (file: ts.SourceFile) => void; } - function setExternalModuleIndicator(sourceFile: SourceFile) { + function setExternalModuleIndicator(sourceFile: ts.SourceFile) { sourceFile.externalModuleIndicator = isFileProbablyExternalModule(sourceFile); } - export function createSourceFile(fileName: string, sourceText: string, languageVersionOrOptions: ScriptTarget | CreateSourceFileOptions, setParentNodes = false, scriptKind?: ScriptKind): SourceFile { - tracing?.push(tracing.Phase.Parse, "createSourceFile", { path: fileName }, /*separateBeginAndEnd*/ true); - performance.mark("beforeParse"); - let result: SourceFile; - - perfLogger.logStartParseSourceFile(fileName); - const { - languageVersion, - setExternalModuleIndicator: overrideSetExternalModuleIndicator, - impliedNodeFormat: format - } = typeof languageVersionOrOptions === "object" ? languageVersionOrOptions : ({ languageVersion: languageVersionOrOptions } as CreateSourceFileOptions); - if (languageVersion === ScriptTarget.JSON) { - result = Parser.parseSourceFile(fileName, sourceText, languageVersion, /*syntaxCursor*/ undefined, setParentNodes, ScriptKind.JSON, noop); + export function createSourceFile(fileName: string, sourceText: string, languageVersionOrOptions: ts.ScriptTarget | CreateSourceFileOptions, setParentNodes = false, scriptKind?: ts.ScriptKind): ts.SourceFile { + ts.tracing?.push(ts.tracing.Phase.Parse, "createSourceFile", { path: fileName }, /*separateBeginAndEnd*/ true); + ts.performance.mark("beforeParse"); + let result: ts.SourceFile; + ts.perfLogger.logStartParseSourceFile(fileName); + const { languageVersion, setExternalModuleIndicator: overrideSetExternalModuleIndicator, impliedNodeFormat: format } = typeof languageVersionOrOptions === "object" ? languageVersionOrOptions : ({ languageVersion: languageVersionOrOptions } as CreateSourceFileOptions); + if (languageVersion === ts.ScriptTarget.JSON) { + result = Parser.parseSourceFile(fileName, sourceText, languageVersion, /*syntaxCursor*/ undefined, setParentNodes, ts.ScriptKind.JSON, ts.noop); } else { - const setIndicator = format === undefined ? overrideSetExternalModuleIndicator : (file: SourceFile) => { + const setIndicator = format === undefined ? overrideSetExternalModuleIndicator : (file: ts.SourceFile) => { file.impliedNodeFormat = format; return (overrideSetExternalModuleIndicator || setExternalModuleIndicator)(file); }; result = Parser.parseSourceFile(fileName, sourceText, languageVersion, /*syntaxCursor*/ undefined, setParentNodes, scriptKind, setIndicator); } - perfLogger.logStopParseSourceFile(); - - performance.mark("afterParse"); - performance.measure("Parse", "beforeParse", "afterParse"); - tracing?.pop(); + ts.perfLogger.logStopParseSourceFile(); + ts.performance.mark("afterParse"); + ts.performance.measure("Parse", "beforeParse", "afterParse"); + ts.tracing?.pop(); return result; } - export function parseIsolatedEntityName(text: string, languageVersion: ScriptTarget): EntityName | undefined { + export function parseIsolatedEntityName(text: string, languageVersion: ts.ScriptTarget): ts.EntityName | undefined { return Parser.parseIsolatedEntityName(text, languageVersion); } @@ -736,12 +728,12 @@ namespace ts { * @param fileName * @param sourceText */ - export function parseJsonText(fileName: string, sourceText: string): JsonSourceFile { + export function parseJsonText(fileName: string, sourceText: string): ts.JsonSourceFile { return Parser.parseJsonText(fileName, sourceText); } // See also `isExternalOrCommonJsModule` in utilities.ts - export function isExternalModule(file: SourceFile): boolean { + export function isExternalModule(file: ts.SourceFile): boolean { return file.externalModuleIndicator !== undefined; } @@ -754,11 +746,11 @@ namespace ts { // from this SourceFile that are being held onto may change as a result (including // becoming detached from any SourceFile). It is recommended that this SourceFile not // be used once 'update' is called on it. - export function updateSourceFile(sourceFile: SourceFile, newText: string, textChangeRange: TextChangeRange, aggressiveChecks = false): SourceFile { + export function updateSourceFile(sourceFile: ts.SourceFile, newText: string, textChangeRange: ts.TextChangeRange, aggressiveChecks = false): ts.SourceFile { const newSourceFile = IncrementalParser.updateSourceFile(sourceFile, newText, textChangeRange, aggressiveChecks); // Because new source file node is created, it may not have the flag PossiblyContainDynamicImport. This is the case if there is no new edit to add dynamic import. // We will manually port the flag to the new source file. - (newSourceFile as Mutable).flags |= (sourceFile.flags & NodeFlags.PermanentlySetIncrementalFlags); + (newSourceFile as ts.Mutable).flags |= (sourceFile.flags & ts.NodeFlags.PermanentlySetIncrementalFlags); return newSourceFile; } @@ -786,27 +778,26 @@ namespace ts { namespace Parser { // Share a single scanner across all calls to parse a source file. This helps speed things // up by avoiding the cost of creating/compiling scanners over and over again. - const scanner = createScanner(ScriptTarget.Latest, /*skipTrivia*/ true); - - const disallowInAndDecoratorContext = NodeFlags.DisallowInContext | NodeFlags.DecoratorContext; + const scanner = ts.createScanner(ts.ScriptTarget.Latest, /*skipTrivia*/ true); + const disallowInAndDecoratorContext = ts.NodeFlags.DisallowInContext | ts.NodeFlags.DecoratorContext; // capture constructors in 'initializeState' to avoid null checks // tslint:disable variable-name - let NodeConstructor: new (kind: SyntaxKind, pos: number, end: number) => Node; - let TokenConstructor: new (kind: SyntaxKind, pos: number, end: number) => Node; - let IdentifierConstructor: new (kind: SyntaxKind, pos: number, end: number) => Node; - let PrivateIdentifierConstructor: new (kind: SyntaxKind, pos: number, end: number) => Node; - let SourceFileConstructor: new (kind: SyntaxKind, pos: number, end: number) => Node; + let NodeConstructor: new (kind: ts.SyntaxKind, pos: number, end: number) => ts.Node; + let TokenConstructor: new (kind: ts.SyntaxKind, pos: number, end: number) => ts.Node; + let IdentifierConstructor: new (kind: ts.SyntaxKind, pos: number, end: number) => ts.Node; + let PrivateIdentifierConstructor: new (kind: ts.SyntaxKind, pos: number, end: number) => ts.Node; + let SourceFileConstructor: new (kind: ts.SyntaxKind, pos: number, end: number) => ts.Node; // tslint:enable variable-name - function countNode(node: Node) { + function countNode(node: ts.Node) { nodeCount++; return node; } // Rather than using `createBaseNodeFactory` here, we establish a `BaseNodeFactory` that closes over the // constructors above, which are reset each time `initializeState` is called. - const baseNodeFactory: BaseNodeFactory = { + const baseNodeFactory: ts.BaseNodeFactory = { createBaseSourceFileNode: kind => countNode(new SourceFileConstructor(kind, /*pos*/ 0, /*end*/ 0)), createBaseIdentifierNode: kind => countNode(new IdentifierConstructor(kind, /*pos*/ 0, /*end*/ 0)), createBasePrivateIdentifierNode: kind => countNode(new PrivateIdentifierConstructor(kind, /*pos*/ 0, /*end*/ 0)), @@ -814,27 +805,27 @@ namespace ts { createBaseNode: kind => countNode(new NodeConstructor(kind, /*pos*/ 0, /*end*/ 0)) }; - const factory = createNodeFactory(NodeFactoryFlags.NoParenthesizerRules | NodeFactoryFlags.NoNodeConverters | NodeFactoryFlags.NoOriginalNode, baseNodeFactory); + const factory = ts.createNodeFactory(ts.NodeFactoryFlags.NoParenthesizerRules | ts.NodeFactoryFlags.NoNodeConverters | ts.NodeFactoryFlags.NoOriginalNode, baseNodeFactory); let fileName: string; - let sourceFlags: NodeFlags; + let sourceFlags: ts.NodeFlags; let sourceText: string; - let languageVersion: ScriptTarget; - let scriptKind: ScriptKind; - let languageVariant: LanguageVariant; - let parseDiagnostics: DiagnosticWithDetachedLocation[]; - let jsDocDiagnostics: DiagnosticWithDetachedLocation[]; + let languageVersion: ts.ScriptTarget; + let scriptKind: ts.ScriptKind; + let languageVariant: ts.LanguageVariant; + let parseDiagnostics: ts.DiagnosticWithDetachedLocation[]; + let jsDocDiagnostics: ts.DiagnosticWithDetachedLocation[]; let syntaxCursor: IncrementalParser.SyntaxCursor | undefined; - let currentToken: SyntaxKind; + let currentToken: ts.SyntaxKind; let nodeCount: number; - let identifiers: ESMap; - let privateIdentifiers: ESMap; + let identifiers: ts.ESMap; + let privateIdentifiers: ts.ESMap; let identifierCount: number; let parsingContext: ParsingContext; - let notParenthesizedArrow: Set | undefined; + let notParenthesizedArrow: ts.Set | undefined; // Flags that dictate what parsing context we're in. For example: // Whether or not we are in strict parsing mode. All that changes in strict parsing mode is @@ -882,7 +873,7 @@ namespace ts { // Note: it should not be necessary to save/restore these flags during speculative/lookahead // parsing. These context flags are naturally stored and restored through normal recursive // descent parsing and unwinding. - let contextFlags: NodeFlags; + let contextFlags: ts.NodeFlags; // Indicates whether we are currently parsing top-level statements. let topLevel = true; @@ -916,17 +907,17 @@ namespace ts { // attached to the EOF token. let parseErrorBeforeNextFinishedNode = false; - export function parseSourceFile(fileName: string, sourceText: string, languageVersion: ScriptTarget, syntaxCursor: IncrementalParser.SyntaxCursor | undefined, setParentNodes = false, scriptKind?: ScriptKind, setExternalModuleIndicatorOverride?: (file: SourceFile) => void): SourceFile { - scriptKind = ensureScriptKind(fileName, scriptKind); - if (scriptKind === ScriptKind.JSON) { + export function parseSourceFile(fileName: string, sourceText: string, languageVersion: ts.ScriptTarget, syntaxCursor: IncrementalParser.SyntaxCursor | undefined, setParentNodes = false, scriptKind?: ts.ScriptKind, setExternalModuleIndicatorOverride?: (file: ts.SourceFile) => void): ts.SourceFile { + scriptKind = ts.ensureScriptKind(fileName, scriptKind); + if (scriptKind === ts.ScriptKind.JSON) { const result = parseJsonText(fileName, sourceText, languageVersion, syntaxCursor, setParentNodes); - convertToObjectWorker(result, result.statements[0]?.expression, result.parseDiagnostics, /*returnValue*/ false, /*knownRootOptions*/ undefined, /*jsonConversionNotifier*/ undefined); - result.referencedFiles = emptyArray; - result.typeReferenceDirectives = emptyArray; - result.libReferenceDirectives = emptyArray; - result.amdDependencies = emptyArray; + ts.convertToObjectWorker(result, result.statements[0]?.expression, result.parseDiagnostics, /*returnValue*/ false, /*knownRootOptions*/ undefined, /*jsonConversionNotifier*/ undefined); + result.referencedFiles = ts.emptyArray; + result.typeReferenceDirectives = ts.emptyArray; + result.libReferenceDirectives = ts.emptyArray; + result.amdDependencies = ts.emptyArray; result.hasNoDefaultLib = false; - result.pragmas = emptyMap as ReadonlyPragmaMap; + result.pragmas = ts.emptyMap as ts.ReadonlyPragmaMap; return result; } @@ -939,56 +930,56 @@ namespace ts { return result; } - export function parseIsolatedEntityName(content: string, languageVersion: ScriptTarget): EntityName | undefined { + export function parseIsolatedEntityName(content: string, languageVersion: ts.ScriptTarget): ts.EntityName | undefined { // Choice of `isDeclarationFile` should be arbitrary - initializeState("", content, languageVersion, /*syntaxCursor*/ undefined, ScriptKind.JS); + initializeState("", content, languageVersion, /*syntaxCursor*/ undefined, ts.ScriptKind.JS); // Prime the scanner. nextToken(); const entityName = parseEntityName(/*allowReservedWords*/ true); - const isInvalid = token() === SyntaxKind.EndOfFileToken && !parseDiagnostics.length; + const isInvalid = token() === ts.SyntaxKind.EndOfFileToken && !parseDiagnostics.length; clearState(); return isInvalid ? entityName : undefined; } - export function parseJsonText(fileName: string, sourceText: string, languageVersion: ScriptTarget = ScriptTarget.ES2015, syntaxCursor?: IncrementalParser.SyntaxCursor, setParentNodes = false): JsonSourceFile { - initializeState(fileName, sourceText, languageVersion, syntaxCursor, ScriptKind.JSON); + export function parseJsonText(fileName: string, sourceText: string, languageVersion: ts.ScriptTarget = ts.ScriptTarget.ES2015, syntaxCursor?: IncrementalParser.SyntaxCursor, setParentNodes = false): ts.JsonSourceFile { + initializeState(fileName, sourceText, languageVersion, syntaxCursor, ts.ScriptKind.JSON); sourceFlags = contextFlags; // Prime the scanner. nextToken(); const pos = getNodePos(); let statements, endOfFileToken; - if (token() === SyntaxKind.EndOfFileToken) { + if (token() === ts.SyntaxKind.EndOfFileToken) { statements = createNodeArray([], pos, pos); - endOfFileToken = parseTokenNode(); + endOfFileToken = parseTokenNode(); } else { // Loop and synthesize an ArrayLiteralExpression if there are more than // one top-level expressions to ensure all input text is consumed. - let expressions: Expression[] | Expression | undefined; - while (token() !== SyntaxKind.EndOfFileToken) { + let expressions: ts.Expression[] | ts.Expression | undefined; + while (token() !== ts.SyntaxKind.EndOfFileToken) { let expression; switch (token()) { - case SyntaxKind.OpenBracketToken: + case ts.SyntaxKind.OpenBracketToken: expression = parseArrayLiteralExpression(); break; - case SyntaxKind.TrueKeyword: - case SyntaxKind.FalseKeyword: - case SyntaxKind.NullKeyword: - expression = parseTokenNode(); + case ts.SyntaxKind.TrueKeyword: + case ts.SyntaxKind.FalseKeyword: + case ts.SyntaxKind.NullKeyword: + expression = parseTokenNode(); break; - case SyntaxKind.MinusToken: - if (lookAhead(() => nextToken() === SyntaxKind.NumericLiteral && nextToken() !== SyntaxKind.ColonToken)) { - expression = parsePrefixUnaryExpression() as JsonMinusNumericLiteral; + case ts.SyntaxKind.MinusToken: + if (lookAhead(() => nextToken() === ts.SyntaxKind.NumericLiteral && nextToken() !== ts.SyntaxKind.ColonToken)) { + expression = parsePrefixUnaryExpression() as ts.JsonMinusNumericLiteral; } else { expression = parseObjectLiteralExpression(); } break; - case SyntaxKind.NumericLiteral: - case SyntaxKind.StringLiteral: - if (lookAhead(() => nextToken() !== SyntaxKind.ColonToken)) { - expression = parseLiteralNode() as StringLiteral | NumericLiteral; + case ts.SyntaxKind.NumericLiteral: + case ts.SyntaxKind.StringLiteral: + if (lookAhead(() => nextToken() !== ts.SyntaxKind.ColonToken)) { + expression = parseLiteralNode() as ts.StringLiteral | ts.NumericLiteral; break; } // falls through @@ -998,7 +989,7 @@ namespace ts { } // Error recovery: collect multiple top-level expressions - if (expressions && isArray(expressions)) { + if (expressions && ts.isArray(expressions)) { expressions.push(expression); } else if (expressions) { @@ -1006,21 +997,21 @@ namespace ts { } else { expressions = expression; - if (token() !== SyntaxKind.EndOfFileToken) { - parseErrorAtCurrentToken(Diagnostics.Unexpected_token); + if (token() !== ts.SyntaxKind.EndOfFileToken) { + parseErrorAtCurrentToken(ts.Diagnostics.Unexpected_token); } } } - const expression = isArray(expressions) ? finishNode(factory.createArrayLiteralExpression(expressions), pos) : Debug.checkDefined(expressions); - const statement = factory.createExpressionStatement(expression) as JsonObjectExpressionStatement; + const expression = ts.isArray(expressions) ? finishNode(factory.createArrayLiteralExpression(expressions), pos) : ts.Debug.checkDefined(expressions); + const statement = factory.createExpressionStatement(expression) as ts.JsonObjectExpressionStatement; finishNode(statement, pos); statements = createNodeArray([statement], pos); - endOfFileToken = parseExpectedToken(SyntaxKind.EndOfFileToken, Diagnostics.Unexpected_token); + endOfFileToken = parseExpectedToken(ts.SyntaxKind.EndOfFileToken, ts.Diagnostics.Unexpected_token); } // Set source file so that errors will be reported with this file name - const sourceFile = createSourceFile(fileName, ScriptTarget.ES2015, ScriptKind.JSON, /*isDeclaration*/ false, statements, endOfFileToken, sourceFlags, noop); + const sourceFile = createSourceFile(fileName, ts.ScriptTarget.ES2015, ts.ScriptKind.JSON, /*isDeclaration*/ false, statements, endOfFileToken, sourceFlags, ts.noop); if (setParentNodes) { fixupParentReferences(sourceFile); @@ -1029,49 +1020,48 @@ namespace ts { sourceFile.nodeCount = nodeCount; sourceFile.identifierCount = identifierCount; sourceFile.identifiers = identifiers; - sourceFile.parseDiagnostics = attachFileToDiagnostics(parseDiagnostics, sourceFile); + sourceFile.parseDiagnostics = ts.attachFileToDiagnostics(parseDiagnostics, sourceFile); if (jsDocDiagnostics) { - sourceFile.jsDocDiagnostics = attachFileToDiagnostics(jsDocDiagnostics, sourceFile); + sourceFile.jsDocDiagnostics = ts.attachFileToDiagnostics(jsDocDiagnostics, sourceFile); } - const result = sourceFile as JsonSourceFile; + const result = sourceFile as ts.JsonSourceFile; clearState(); return result; } - function initializeState(_fileName: string, _sourceText: string, _languageVersion: ScriptTarget, _syntaxCursor: IncrementalParser.SyntaxCursor | undefined, _scriptKind: ScriptKind) { - NodeConstructor = objectAllocator.getNodeConstructor(); - TokenConstructor = objectAllocator.getTokenConstructor(); - IdentifierConstructor = objectAllocator.getIdentifierConstructor(); - PrivateIdentifierConstructor = objectAllocator.getPrivateIdentifierConstructor(); - SourceFileConstructor = objectAllocator.getSourceFileConstructor(); - - fileName = normalizePath(_fileName); + function initializeState(_fileName: string, _sourceText: string, _languageVersion: ts.ScriptTarget, _syntaxCursor: IncrementalParser.SyntaxCursor | undefined, _scriptKind: ts.ScriptKind) { + NodeConstructor = ts.objectAllocator.getNodeConstructor(); + TokenConstructor = ts.objectAllocator.getTokenConstructor(); + IdentifierConstructor = ts.objectAllocator.getIdentifierConstructor(); + PrivateIdentifierConstructor = ts.objectAllocator.getPrivateIdentifierConstructor(); + SourceFileConstructor = ts.objectAllocator.getSourceFileConstructor(); + fileName = ts.normalizePath(_fileName); sourceText = _sourceText; languageVersion = _languageVersion; syntaxCursor = _syntaxCursor; scriptKind = _scriptKind; - languageVariant = getLanguageVariant(_scriptKind); + languageVariant = ts.getLanguageVariant(_scriptKind); parseDiagnostics = []; parsingContext = 0; - identifiers = new Map(); - privateIdentifiers = new Map(); + identifiers = new ts.Map(); + privateIdentifiers = new ts.Map(); identifierCount = 0; nodeCount = 0; sourceFlags = 0; topLevel = true; switch (scriptKind) { - case ScriptKind.JS: - case ScriptKind.JSX: - contextFlags = NodeFlags.JavaScriptFile; + case ts.ScriptKind.JS: + case ts.ScriptKind.JSX: + contextFlags = ts.NodeFlags.JavaScriptFile; break; - case ScriptKind.JSON: - contextFlags = NodeFlags.JavaScriptFile | NodeFlags.JsonFile; + case ts.ScriptKind.JSON: + contextFlags = ts.NodeFlags.JavaScriptFile | ts.NodeFlags.JsonFile; break; default: - contextFlags = NodeFlags.None; + contextFlags = ts.NodeFlags.None; break; } parseErrorBeforeNextFinishedNode = false; @@ -1104,10 +1094,10 @@ namespace ts { topLevel = true; } - function parseSourceFileWorker(languageVersion: ScriptTarget, setParentNodes: boolean, scriptKind: ScriptKind, setExternalModuleIndicator: (file: SourceFile) => void): SourceFile { + function parseSourceFileWorker(languageVersion: ts.ScriptTarget, setParentNodes: boolean, scriptKind: ts.ScriptKind, setExternalModuleIndicator: (file: ts.SourceFile) => void): ts.SourceFile { const isDeclarationFile = isDeclarationFileName(fileName); if (isDeclarationFile) { - contextFlags |= NodeFlags.Ambient; + contextFlags |= ts.NodeFlags.Ambient; } sourceFlags = contextFlags; @@ -1116,8 +1106,8 @@ namespace ts { nextToken(); const statements = parseList(ParsingContext.SourceElements, parseStatement); - Debug.assert(token() === SyntaxKind.EndOfFileToken); - const endOfFileToken = addJSDocComment(parseTokenNode()); + ts.Debug.assert(token() === ts.SyntaxKind.EndOfFileToken); + const endOfFileToken = addJSDocComment(parseTokenNode()); const sourceFile = createSourceFile(fileName, languageVersion, scriptKind, isDeclarationFile, statements, endOfFileToken, sourceFlags, setExternalModuleIndicator); @@ -1129,9 +1119,9 @@ namespace ts { sourceFile.nodeCount = nodeCount; sourceFile.identifierCount = identifierCount; sourceFile.identifiers = identifiers; - sourceFile.parseDiagnostics = attachFileToDiagnostics(parseDiagnostics, sourceFile); + sourceFile.parseDiagnostics = ts.attachFileToDiagnostics(parseDiagnostics, sourceFile); if (jsDocDiagnostics) { - sourceFile.jsDocDiagnostics = attachFileToDiagnostics(jsDocDiagnostics, sourceFile); + sourceFile.jsDocDiagnostics = ts.attachFileToDiagnostics(jsDocDiagnostics, sourceFile); } if (setParentNodes) { @@ -1140,33 +1130,34 @@ namespace ts { return sourceFile; - function reportPragmaDiagnostic(pos: number, end: number, diagnostic: DiagnosticMessage) { - parseDiagnostics.push(createDetachedDiagnostic(fileName, pos, end, diagnostic)); + function reportPragmaDiagnostic(pos: number, end: number, diagnostic: ts.DiagnosticMessage) { + parseDiagnostics.push(ts.createDetachedDiagnostic(fileName, pos, end, diagnostic)); } } - function withJSDoc(node: T, hasJSDoc: boolean): T { + function withJSDoc(node: T, hasJSDoc: boolean): T { return hasJSDoc ? addJSDocComment(node) : node; } let hasDeprecatedTag = false; - function addJSDocComment(node: T): T { - Debug.assert(!node.jsDoc); // Should only be called once per node - const jsDoc = mapDefined(getJSDocCommentRanges(node, sourceText), comment => JSDocParser.parseJSDocComment(node, comment.pos, comment.end - comment.pos)); - if (jsDoc.length) node.jsDoc = jsDoc; + function addJSDocComment(node: T): T { + ts.Debug.assert(!node.jsDoc); // Should only be called once per node + const jsDoc = ts.mapDefined(ts.getJSDocCommentRanges(node, sourceText), comment => JSDocParser.parseJSDocComment(node, comment.pos, comment.end - comment.pos)); + if (jsDoc.length) + node.jsDoc = jsDoc; if (hasDeprecatedTag) { hasDeprecatedTag = false; - (node as Mutable).flags |= NodeFlags.Deprecated; + (node as ts.Mutable).flags |= ts.NodeFlags.Deprecated; } return node; } - function reparseTopLevelAwait(sourceFile: SourceFile) { + function reparseTopLevelAwait(sourceFile: ts.SourceFile) { const savedSyntaxCursor = syntaxCursor; const baseSyntaxCursor = IncrementalParser.createSyntaxCursor(sourceFile); syntaxCursor = { currentNode }; - const statements: Statement[] = []; + const statements: ts.Statement[] = []; const savedParseDiagnostics = parseDiagnostics; parseDiagnostics = []; @@ -1177,24 +1168,24 @@ namespace ts { // append all statements between pos and start const prevStatement = sourceFile.statements[pos]; const nextStatement = sourceFile.statements[start]; - addRange(statements, sourceFile.statements, pos, start); + ts.addRange(statements, sourceFile.statements, pos, start); pos = findNextStatementWithoutAwait(sourceFile.statements, start); // append all diagnostics associated with the copied range - const diagnosticStart = findIndex(savedParseDiagnostics, diagnostic => diagnostic.start >= prevStatement.pos); - const diagnosticEnd = diagnosticStart >= 0 ? findIndex(savedParseDiagnostics, diagnostic => diagnostic.start >= nextStatement.pos, diagnosticStart) : -1; + const diagnosticStart = ts.findIndex(savedParseDiagnostics, diagnostic => diagnostic.start >= prevStatement.pos); + const diagnosticEnd = diagnosticStart >= 0 ? ts.findIndex(savedParseDiagnostics, diagnostic => diagnostic.start >= nextStatement.pos, diagnosticStart) : -1; if (diagnosticStart >= 0) { - addRange(parseDiagnostics, savedParseDiagnostics, diagnosticStart, diagnosticEnd >= 0 ? diagnosticEnd : undefined); + ts.addRange(parseDiagnostics, savedParseDiagnostics, diagnosticStart, diagnosticEnd >= 0 ? diagnosticEnd : undefined); } // reparse all statements between start and pos. We skip existing diagnostics for the same range and allow the parser to generate new ones. speculationHelper(() => { const savedContextFlags = contextFlags; - contextFlags |= NodeFlags.AwaitContext; + contextFlags |= ts.NodeFlags.AwaitContext; scanner.setTextPos(nextStatement.pos); nextToken(); - while (token() !== SyntaxKind.EndOfFileToken) { + while (token() !== ts.SyntaxKind.EndOfFileToken) { const startPos = scanner.getStartPos(); const statement = parseListElement(ParsingContext.SourceElements, parseStatement); statements.push(statement); @@ -1225,24 +1216,22 @@ namespace ts { // append all statements between pos and the end of the list if (pos >= 0) { const prevStatement = sourceFile.statements[pos]; - addRange(statements, sourceFile.statements, pos); + ts.addRange(statements, sourceFile.statements, pos); // append all diagnostics associated with the copied range - const diagnosticStart = findIndex(savedParseDiagnostics, diagnostic => diagnostic.start >= prevStatement.pos); + const diagnosticStart = ts.findIndex(savedParseDiagnostics, diagnostic => diagnostic.start >= prevStatement.pos); if (diagnosticStart >= 0) { - addRange(parseDiagnostics, savedParseDiagnostics, diagnosticStart); + ts.addRange(parseDiagnostics, savedParseDiagnostics, diagnosticStart); } } syntaxCursor = savedSyntaxCursor; - return factory.updateSourceFile(sourceFile, setTextRange(factory.createNodeArray(statements), sourceFile.statements)); - - function containsPossibleTopLevelAwait(node: Node) { - return !(node.flags & NodeFlags.AwaitContext) - && !!(node.transformFlags & TransformFlags.ContainsPossibleTopLevelAwait); + return factory.updateSourceFile(sourceFile, ts.setTextRange(factory.createNodeArray(statements), sourceFile.statements)); + function containsPossibleTopLevelAwait(node: ts.Node) { + return !(node.flags & ts.NodeFlags.AwaitContext) + && !!(node.transformFlags & ts.TransformFlags.ContainsPossibleTopLevelAwait); } - - function findNextStatementWithAwait(statements: NodeArray, start: number) { + function findNextStatementWithAwait(statements: ts.NodeArray, start: number) { for (let i = start; i < statements.length; i++) { if (containsPossibleTopLevelAwait(statements[i])) { return i; @@ -1251,7 +1240,7 @@ namespace ts { return -1; } - function findNextStatementWithoutAwait(statements: NodeArray, start: number) { + function findNextStatementWithoutAwait(statements: ts.NodeArray, start: number) { for (let i = start; i < statements.length; i++) { if (!containsPossibleTopLevelAwait(statements[i])) { return i; @@ -1270,44 +1259,35 @@ namespace ts { } - export function fixupParentReferences(rootNode: Node) { + export function fixupParentReferences(rootNode: ts.Node) { // normally parent references are set during binding. However, for clients that only need // a syntax tree, and no semantic features, then the binding process is an unnecessary // overhead. This functions allows us to set all the parents, without all the expense of // binding. - setParentRecursive(rootNode, /*incremental*/ true); - } - - function createSourceFile( - fileName: string, - languageVersion: ScriptTarget, - scriptKind: ScriptKind, - isDeclarationFile: boolean, - statements: readonly Statement[], - endOfFileToken: EndOfFileToken, - flags: NodeFlags, - setExternalModuleIndicator: (sourceFile: SourceFile) => void): SourceFile { + ts.setParentRecursive(rootNode, /*incremental*/ true); + } + function createSourceFile(fileName: string, languageVersion: ts.ScriptTarget, scriptKind: ts.ScriptKind, isDeclarationFile: boolean, statements: readonly ts.Statement[], endOfFileToken: ts.EndOfFileToken, flags: ts.NodeFlags, setExternalModuleIndicator: (sourceFile: ts.SourceFile) => void): ts.SourceFile { // code from createNode is inlined here so createNode won't have to deal with special case of creating source files // this is quite rare comparing to other nodes and createNode should be as fast as possible let sourceFile = factory.createSourceFile(statements, endOfFileToken, flags); - setTextRangePosWidth(sourceFile, 0, sourceText.length); + ts.setTextRangePosWidth(sourceFile, 0, sourceText.length); setFields(sourceFile); // If we parsed this as an external module, it may contain top-level await - if (!isDeclarationFile && isExternalModule(sourceFile) && sourceFile.transformFlags & TransformFlags.ContainsPossibleTopLevelAwait) { + if (!isDeclarationFile && isExternalModule(sourceFile) && sourceFile.transformFlags & ts.TransformFlags.ContainsPossibleTopLevelAwait) { sourceFile = reparseTopLevelAwait(sourceFile); setFields(sourceFile); } return sourceFile; - function setFields(sourceFile: SourceFile) { + function setFields(sourceFile: ts.SourceFile) { sourceFile.text = sourceText; sourceFile.bindDiagnostics = []; sourceFile.bindSuggestionDiagnostics = undefined; sourceFile.languageVersion = languageVersion; sourceFile.fileName = fileName; - sourceFile.languageVariant = getLanguageVariant(scriptKind); + sourceFile.languageVariant = ts.getLanguageVariant(scriptKind); sourceFile.isDeclarationFile = isDeclarationFile; sourceFile.scriptKind = scriptKind; @@ -1316,7 +1296,7 @@ namespace ts { } } - function setContextFlag(val: boolean, flag: NodeFlags) { + function setContextFlag(val: boolean, flag: ts.NodeFlags) { if (val) { contextFlags |= flag; } @@ -1326,22 +1306,22 @@ namespace ts { } function setDisallowInContext(val: boolean) { - setContextFlag(val, NodeFlags.DisallowInContext); + setContextFlag(val, ts.NodeFlags.DisallowInContext); } function setYieldContext(val: boolean) { - setContextFlag(val, NodeFlags.YieldContext); + setContextFlag(val, ts.NodeFlags.YieldContext); } function setDecoratorContext(val: boolean) { - setContextFlag(val, NodeFlags.DecoratorContext); + setContextFlag(val, ts.NodeFlags.DecoratorContext); } function setAwaitContext(val: boolean) { - setContextFlag(val, NodeFlags.AwaitContext); + setContextFlag(val, ts.NodeFlags.AwaitContext); } - function doOutsideOfContext(context: NodeFlags, func: () => T): T { + function doOutsideOfContext(context: ts.NodeFlags, func: () => T): T { // contextFlagsToClear will contain only the context flags that are // currently set that we need to temporarily clear // We don't just blindly reset to the previous flags to ensure @@ -1362,7 +1342,7 @@ namespace ts { return func(); } - function doInsideOfContext(context: NodeFlags, func: () => T): T { + function doInsideOfContext(context: ts.NodeFlags, func: () => T): T { // contextFlagsToSet will contain only the context flags that // are not currently set that we need to temporarily enable. // We don't just blindly reset to the previous flags to ensure @@ -1384,79 +1364,79 @@ namespace ts { } function allowInAnd(func: () => T): T { - return doOutsideOfContext(NodeFlags.DisallowInContext, func); + return doOutsideOfContext(ts.NodeFlags.DisallowInContext, func); } function disallowInAnd(func: () => T): T { - return doInsideOfContext(NodeFlags.DisallowInContext, func); + return doInsideOfContext(ts.NodeFlags.DisallowInContext, func); } function allowConditionalTypesAnd(func: () => T): T { - return doOutsideOfContext(NodeFlags.DisallowConditionalTypesContext, func); + return doOutsideOfContext(ts.NodeFlags.DisallowConditionalTypesContext, func); } function disallowConditionalTypesAnd(func: () => T): T { - return doInsideOfContext(NodeFlags.DisallowConditionalTypesContext, func); + return doInsideOfContext(ts.NodeFlags.DisallowConditionalTypesContext, func); } function doInYieldContext(func: () => T): T { - return doInsideOfContext(NodeFlags.YieldContext, func); + return doInsideOfContext(ts.NodeFlags.YieldContext, func); } function doInDecoratorContext(func: () => T): T { - return doInsideOfContext(NodeFlags.DecoratorContext, func); + return doInsideOfContext(ts.NodeFlags.DecoratorContext, func); } function doInAwaitContext(func: () => T): T { - return doInsideOfContext(NodeFlags.AwaitContext, func); + return doInsideOfContext(ts.NodeFlags.AwaitContext, func); } function doOutsideOfAwaitContext(func: () => T): T { - return doOutsideOfContext(NodeFlags.AwaitContext, func); + return doOutsideOfContext(ts.NodeFlags.AwaitContext, func); } function doInYieldAndAwaitContext(func: () => T): T { - return doInsideOfContext(NodeFlags.YieldContext | NodeFlags.AwaitContext, func); + return doInsideOfContext(ts.NodeFlags.YieldContext | ts.NodeFlags.AwaitContext, func); } function doOutsideOfYieldAndAwaitContext(func: () => T): T { - return doOutsideOfContext(NodeFlags.YieldContext | NodeFlags.AwaitContext, func); + return doOutsideOfContext(ts.NodeFlags.YieldContext | ts.NodeFlags.AwaitContext, func); } - function inContext(flags: NodeFlags) { + function inContext(flags: ts.NodeFlags) { return (contextFlags & flags) !== 0; } function inYieldContext() { - return inContext(NodeFlags.YieldContext); + return inContext(ts.NodeFlags.YieldContext); } function inDisallowInContext() { - return inContext(NodeFlags.DisallowInContext); + return inContext(ts.NodeFlags.DisallowInContext); } function inDisallowConditionalTypesContext() { - return inContext(NodeFlags.DisallowConditionalTypesContext); + return inContext(ts.NodeFlags.DisallowConditionalTypesContext); } function inDecoratorContext() { - return inContext(NodeFlags.DecoratorContext); + return inContext(ts.NodeFlags.DecoratorContext); } function inAwaitContext() { - return inContext(NodeFlags.AwaitContext); + return inContext(ts.NodeFlags.AwaitContext); } - function parseErrorAtCurrentToken(message: DiagnosticMessage, arg0?: any): DiagnosticWithDetachedLocation | undefined { + function parseErrorAtCurrentToken(message: ts.DiagnosticMessage, arg0?: any): ts.DiagnosticWithDetachedLocation | undefined { return parseErrorAt(scanner.getTokenPos(), scanner.getTextPos(), message, arg0); } - function parseErrorAtPosition(start: number, length: number, message: DiagnosticMessage, arg0?: any): DiagnosticWithDetachedLocation | undefined { + function parseErrorAtPosition(start: number, length: number, message: ts.DiagnosticMessage, arg0?: any): ts.DiagnosticWithDetachedLocation | undefined { // Don't report another error if it would just be at the same position as the last error. - const lastError = lastOrUndefined(parseDiagnostics); - let result: DiagnosticWithDetachedLocation | undefined; + const lastError = ts.lastOrUndefined(parseDiagnostics); + let result: ts.DiagnosticWithDetachedLocation | undefined; if (!lastError || start !== lastError.start) { - result = createDetachedDiagnostic(fileName, start, length, message, arg0); + result = ts.createDetachedDiagnostic(fileName, start, length, message, arg0); parseDiagnostics.push(result); } @@ -1466,15 +1446,15 @@ namespace ts { return result; } - function parseErrorAt(start: number, end: number, message: DiagnosticMessage, arg0?: any): DiagnosticWithDetachedLocation | undefined { + function parseErrorAt(start: number, end: number, message: ts.DiagnosticMessage, arg0?: any): ts.DiagnosticWithDetachedLocation | undefined { return parseErrorAtPosition(start, end - start, message, arg0); } - function parseErrorAtRange(range: TextRange, message: DiagnosticMessage, arg0?: any): void { + function parseErrorAtRange(range: ts.TextRange, message: ts.DiagnosticMessage, arg0?: any): void { parseErrorAt(range.pos, range.end, message, arg0); } - function scanError(message: DiagnosticMessage, length: number): void { + function scanError(message: ts.DiagnosticMessage, length: number): void { parseErrorAtPosition(scanner.getTextPos(), length, message); } @@ -1492,7 +1472,7 @@ namespace ts { // token (e.g. a call to nextToken() changes the current token but the checker doesn't // reason about this side effect). Mainstream VMs inline simple functions like this, so // there is no performance penalty. - function token(): SyntaxKind { + function token(): ts.SyntaxKind { return currentToken; } @@ -1505,52 +1485,52 @@ namespace ts { return func(); } - function nextToken(): SyntaxKind { + function nextToken(): ts.SyntaxKind { // if the keyword had an escape - if (isKeyword(currentToken) && (scanner.hasUnicodeEscape() || scanner.hasExtendedUnicodeEscape())) { + if (ts.isKeyword(currentToken) && (scanner.hasUnicodeEscape() || scanner.hasExtendedUnicodeEscape())) { // issue a parse error for the escape - parseErrorAt(scanner.getTokenPos(), scanner.getTextPos(), Diagnostics.Keywords_cannot_contain_escape_characters); + parseErrorAt(scanner.getTokenPos(), scanner.getTextPos(), ts.Diagnostics.Keywords_cannot_contain_escape_characters); } return nextTokenWithoutCheck(); } - function nextTokenJSDoc(): JSDocSyntaxKind { + function nextTokenJSDoc(): ts.JSDocSyntaxKind { return currentToken = scanner.scanJsDocToken(); } - function reScanGreaterToken(): SyntaxKind { + function reScanGreaterToken(): ts.SyntaxKind { return currentToken = scanner.reScanGreaterToken(); } - function reScanSlashToken(): SyntaxKind { + function reScanSlashToken(): ts.SyntaxKind { return currentToken = scanner.reScanSlashToken(); } - function reScanTemplateToken(isTaggedTemplate: boolean): SyntaxKind { + function reScanTemplateToken(isTaggedTemplate: boolean): ts.SyntaxKind { return currentToken = scanner.reScanTemplateToken(isTaggedTemplate); } - function reScanTemplateHeadOrNoSubstitutionTemplate(): SyntaxKind { + function reScanTemplateHeadOrNoSubstitutionTemplate(): ts.SyntaxKind { return currentToken = scanner.reScanTemplateHeadOrNoSubstitutionTemplate(); } - function reScanLessThanToken(): SyntaxKind { + function reScanLessThanToken(): ts.SyntaxKind { return currentToken = scanner.reScanLessThanToken(); } - function reScanHashToken(): SyntaxKind { + function reScanHashToken(): ts.SyntaxKind { return currentToken = scanner.reScanHashToken(); } - function scanJsxIdentifier(): SyntaxKind { + function scanJsxIdentifier(): ts.SyntaxKind { return currentToken = scanner.scanJsxIdentifier(); } - function scanJsxText(): SyntaxKind { + function scanJsxText(): ts.SyntaxKind { return currentToken = scanner.scanJsxToken(); } - function scanJsxAttributeValue(): SyntaxKind { + function scanJsxAttributeValue(): ts.SyntaxKind { return currentToken = scanner.scanJsxAttributeValue(); } @@ -1574,7 +1554,7 @@ namespace ts { ? scanner.lookAhead(callback) : scanner.tryScan(callback); - Debug.assert(saveContextFlags === contextFlags); + ts.Debug.assert(saveContextFlags === contextFlags); // If our callback returned something 'falsy' or we're just looking ahead, // then unconditionally restore us to where we were. @@ -1607,36 +1587,36 @@ namespace ts { } function isBindingIdentifier(): boolean { - if (token() === SyntaxKind.Identifier) { + if (token() === ts.SyntaxKind.Identifier) { return true; } // `let await`/`let yield` in [Yield] or [Await] are allowed here and disallowed in the binder. - return token() > SyntaxKind.LastReservedWord; + return token() > ts.SyntaxKind.LastReservedWord; } // Ignore strict mode flag because we will report an error in type checker instead. function isIdentifier(): boolean { - if (token() === SyntaxKind.Identifier) { + if (token() === ts.SyntaxKind.Identifier) { return true; } // If we have a 'yield' keyword, and we're in the [yield] context, then 'yield' is // considered a keyword and is not an identifier. - if (token() === SyntaxKind.YieldKeyword && inYieldContext()) { + if (token() === ts.SyntaxKind.YieldKeyword && inYieldContext()) { return false; } // If we have a 'await' keyword, and we're in the [Await] context, then 'await' is // considered a keyword and is not an identifier. - if (token() === SyntaxKind.AwaitKeyword && inAwaitContext()) { + if (token() === ts.SyntaxKind.AwaitKeyword && inAwaitContext()) { return false; } - return token() > SyntaxKind.LastReservedWord; + return token() > ts.SyntaxKind.LastReservedWord; } - function parseExpected(kind: SyntaxKind, diagnosticMessage?: DiagnosticMessage, shouldAdvance = true): boolean { + function parseExpected(kind: ts.SyntaxKind, diagnosticMessage?: ts.DiagnosticMessage, shouldAdvance = true): boolean { if (token() === kind) { if (shouldAdvance) { nextToken(); @@ -1649,12 +1629,12 @@ namespace ts { parseErrorAtCurrentToken(diagnosticMessage); } else { - parseErrorAtCurrentToken(Diagnostics._0_expected, tokenToString(kind)); + parseErrorAtCurrentToken(ts.Diagnostics._0_expected, ts.tokenToString(kind)); } return false; } - const viableKeywordSuggestions = Object.keys(textToKeywordObj).filter(keyword => keyword.length > 2); + const viableKeywordSuggestions = Object.keys(ts.textToKeywordObj).filter(keyword => keyword.length > 2); /** * Provides a better error message than the generic "';' expected" if possible for @@ -1662,30 +1642,30 @@ namespace ts { * * @param node Node preceding the expected semicolon location. */ - function parseErrorForMissingSemicolonAfter(node: Expression | PropertyName): void { + function parseErrorForMissingSemicolonAfter(node: ts.Expression | ts.PropertyName): void { // Tagged template literals are sometimes used in places where only simple strings are allowed, i.e.: // module `M1` { // ^^^^^^^^^^^ This block is parsed as a template literal like module`M1`. - if (isTaggedTemplateExpression(node)) { - parseErrorAt(skipTrivia(sourceText, node.template.pos), node.template.end, Diagnostics.Module_declaration_names_may_only_use_or_quoted_strings); + if (ts.isTaggedTemplateExpression(node)) { + parseErrorAt(ts.skipTrivia(sourceText, node.template.pos), node.template.end, ts.Diagnostics.Module_declaration_names_may_only_use_or_quoted_strings); return; } // Otherwise, if this isn't a well-known keyword-like identifier, give the generic fallback message. - const expressionText = ts.isIdentifier(node) ? idText(node) : undefined; - if (!expressionText || !isIdentifierText(expressionText, languageVersion)) { - parseErrorAtCurrentToken(Diagnostics._0_expected, tokenToString(SyntaxKind.SemicolonToken)); + const expressionText = ts.isIdentifier(node) ? ts.idText(node) : undefined; + if (!expressionText || !ts.isIdentifierText(expressionText, languageVersion)) { + parseErrorAtCurrentToken(ts.Diagnostics._0_expected, ts.tokenToString(ts.SyntaxKind.SemicolonToken)); return; } - const pos = skipTrivia(sourceText, node.pos); + const pos = ts.skipTrivia(sourceText, node.pos); // Some known keywords are likely signs of syntax being used improperly. switch (expressionText) { case "const": case "let": case "var": - parseErrorAt(pos, node.end, Diagnostics.Variable_declaration_not_allowed_at_this_location); + parseErrorAt(pos, node.end, ts.Diagnostics.Variable_declaration_not_allowed_at_this_location); return; case "declare": @@ -1693,37 +1673,37 @@ namespace ts { return; case "interface": - parseErrorForInvalidName(Diagnostics.Interface_name_cannot_be_0, Diagnostics.Interface_must_be_given_a_name, SyntaxKind.OpenBraceToken); + parseErrorForInvalidName(ts.Diagnostics.Interface_name_cannot_be_0, ts.Diagnostics.Interface_must_be_given_a_name, ts.SyntaxKind.OpenBraceToken); return; case "is": - parseErrorAt(pos, scanner.getTextPos(), Diagnostics.A_type_predicate_is_only_allowed_in_return_type_position_for_functions_and_methods); + parseErrorAt(pos, scanner.getTextPos(), ts.Diagnostics.A_type_predicate_is_only_allowed_in_return_type_position_for_functions_and_methods); return; case "module": case "namespace": - parseErrorForInvalidName(Diagnostics.Namespace_name_cannot_be_0, Diagnostics.Namespace_must_be_given_a_name, SyntaxKind.OpenBraceToken); + parseErrorForInvalidName(ts.Diagnostics.Namespace_name_cannot_be_0, ts.Diagnostics.Namespace_must_be_given_a_name, ts.SyntaxKind.OpenBraceToken); return; case "type": - parseErrorForInvalidName(Diagnostics.Type_alias_name_cannot_be_0, Diagnostics.Type_alias_must_be_given_a_name, SyntaxKind.EqualsToken); + parseErrorForInvalidName(ts.Diagnostics.Type_alias_name_cannot_be_0, ts.Diagnostics.Type_alias_must_be_given_a_name, ts.SyntaxKind.EqualsToken); return; } // The user alternatively might have misspelled or forgotten to add a space after a common keyword. - const suggestion = getSpellingSuggestion(expressionText, viableKeywordSuggestions, n => n) ?? getSpaceSuggestion(expressionText); + const suggestion = ts.getSpellingSuggestion(expressionText, viableKeywordSuggestions, n => n) ?? getSpaceSuggestion(expressionText); if (suggestion) { - parseErrorAt(pos, node.end, Diagnostics.Unknown_keyword_or_identifier_Did_you_mean_0, suggestion); + parseErrorAt(pos, node.end, ts.Diagnostics.Unknown_keyword_or_identifier_Did_you_mean_0, suggestion); return; } // Unknown tokens are handled with their own errors in the scanner - if (token() === SyntaxKind.Unknown) { + if (token() === ts.SyntaxKind.Unknown) { return; } // Otherwise, we know this some kind of unknown word, not just a missing expected semicolon. - parseErrorAt(pos, node.end, Diagnostics.Unexpected_keyword_or_identifier); + parseErrorAt(pos, node.end, ts.Diagnostics.Unexpected_keyword_or_identifier); } /** @@ -1733,7 +1713,7 @@ namespace ts { * @param nameDiagnostic Diagnostic to report for all other cases. * @param tokenIfBlankName Current token if the name was invalid for being blank (not provided / skipped). */ - function parseErrorForInvalidName(nameDiagnostic: DiagnosticMessage, blankDiagnostic: DiagnosticMessage, tokenIfBlankName: SyntaxKind) { + function parseErrorForInvalidName(nameDiagnostic: ts.DiagnosticMessage, blankDiagnostic: ts.DiagnosticMessage, tokenIfBlankName: ts.SyntaxKind) { if (token() === tokenIfBlankName) { parseErrorAtCurrentToken(blankDiagnostic); } @@ -1744,7 +1724,7 @@ namespace ts { function getSpaceSuggestion(expressionText: string) { for (const keyword of viableKeywordSuggestions) { - if (expressionText.length > keyword.length + 2 && startsWith(expressionText, keyword)) { + if (expressionText.length > keyword.length + 2 && ts.startsWith(expressionText, keyword)) { return `${keyword} ${expressionText.slice(keyword.length)}`; } } @@ -1752,24 +1732,24 @@ namespace ts { return undefined; } - function parseSemicolonAfterPropertyName(name: PropertyName, type: TypeNode | undefined, initializer: Expression | undefined) { - if (token() === SyntaxKind.AtToken && !scanner.hasPrecedingLineBreak()) { - parseErrorAtCurrentToken(Diagnostics.Decorators_must_precede_the_name_and_all_keywords_of_property_declarations); + function parseSemicolonAfterPropertyName(name: ts.PropertyName, type: ts.TypeNode | undefined, initializer: ts.Expression | undefined) { + if (token() === ts.SyntaxKind.AtToken && !scanner.hasPrecedingLineBreak()) { + parseErrorAtCurrentToken(ts.Diagnostics.Decorators_must_precede_the_name_and_all_keywords_of_property_declarations); return; } - if (token() === SyntaxKind.OpenParenToken) { - parseErrorAtCurrentToken(Diagnostics.Cannot_start_a_function_call_in_a_type_annotation); + if (token() === ts.SyntaxKind.OpenParenToken) { + parseErrorAtCurrentToken(ts.Diagnostics.Cannot_start_a_function_call_in_a_type_annotation); nextToken(); return; } if (type && !canParseSemicolon()) { if (initializer) { - parseErrorAtCurrentToken(Diagnostics._0_expected, tokenToString(SyntaxKind.SemicolonToken)); + parseErrorAtCurrentToken(ts.Diagnostics._0_expected, ts.tokenToString(ts.SyntaxKind.SemicolonToken)); } else { - parseErrorAtCurrentToken(Diagnostics.Expected_for_property_initializer); + parseErrorAtCurrentToken(ts.Diagnostics.Expected_for_property_initializer); } return; } @@ -1779,40 +1759,37 @@ namespace ts { } if (initializer) { - parseErrorAtCurrentToken(Diagnostics._0_expected, tokenToString(SyntaxKind.SemicolonToken)); + parseErrorAtCurrentToken(ts.Diagnostics._0_expected, ts.tokenToString(ts.SyntaxKind.SemicolonToken)); return; } parseErrorForMissingSemicolonAfter(name); } - function parseExpectedJSDoc(kind: JSDocSyntaxKind) { + function parseExpectedJSDoc(kind: ts.JSDocSyntaxKind) { if (token() === kind) { nextTokenJSDoc(); return true; } - parseErrorAtCurrentToken(Diagnostics._0_expected, tokenToString(kind)); + parseErrorAtCurrentToken(ts.Diagnostics._0_expected, ts.tokenToString(kind)); return false; } - function parseExpectedMatchingBrackets(openKind: SyntaxKind, closeKind: SyntaxKind, openParsed: boolean, openPosition: number) { + function parseExpectedMatchingBrackets(openKind: ts.SyntaxKind, closeKind: ts.SyntaxKind, openParsed: boolean, openPosition: number) { if (token() === closeKind) { nextToken(); return; } - const lastError = parseErrorAtCurrentToken(Diagnostics._0_expected, tokenToString(closeKind)); + const lastError = parseErrorAtCurrentToken(ts.Diagnostics._0_expected, ts.tokenToString(closeKind)); if (!openParsed) { return; } if (lastError) { - addRelatedInfo( - lastError, - createDetachedDiagnostic(fileName, openPosition, 1, Diagnostics.The_parser_expected_to_find_a_1_to_match_the_0_token_here, tokenToString(openKind), tokenToString(closeKind)) - ); + ts.addRelatedInfo(lastError, ts.createDetachedDiagnostic(fileName, openPosition, 1, ts.Diagnostics.The_parser_expected_to_find_a_1_to_match_the_0_token_here, ts.tokenToString(openKind), ts.tokenToString(closeKind))); } } - function parseOptional(t: SyntaxKind): boolean { + function parseOptional(t: ts.SyntaxKind): boolean { if (token() === t) { nextToken(); return true; @@ -1820,42 +1797,42 @@ namespace ts { return false; } - function parseOptionalToken(t: TKind): Token; - function parseOptionalToken(t: SyntaxKind): Node | undefined { + function parseOptionalToken(t: TKind): ts.Token; + function parseOptionalToken(t: ts.SyntaxKind): ts.Node | undefined { if (token() === t) { return parseTokenNode(); } return undefined; } - function parseOptionalTokenJSDoc(t: TKind): Token; - function parseOptionalTokenJSDoc(t: JSDocSyntaxKind): Node | undefined { + function parseOptionalTokenJSDoc(t: TKind): ts.Token; + function parseOptionalTokenJSDoc(t: ts.JSDocSyntaxKind): ts.Node | undefined { if (token() === t) { return parseTokenNodeJSDoc(); } return undefined; } - function parseExpectedToken(t: TKind, diagnosticMessage?: DiagnosticMessage, arg0?: any): Token; - function parseExpectedToken(t: SyntaxKind, diagnosticMessage?: DiagnosticMessage, arg0?: any): Node { + function parseExpectedToken(t: TKind, diagnosticMessage?: ts.DiagnosticMessage, arg0?: any): ts.Token; + function parseExpectedToken(t: ts.SyntaxKind, diagnosticMessage?: ts.DiagnosticMessage, arg0?: any): ts.Node { return parseOptionalToken(t) || - createMissingNode(t, /*reportAtCurrentPosition*/ false, diagnosticMessage || Diagnostics._0_expected, arg0 || tokenToString(t)); + createMissingNode(t, /*reportAtCurrentPosition*/ false, diagnosticMessage || ts.Diagnostics._0_expected, arg0 || ts.tokenToString(t)); } - function parseExpectedTokenJSDoc(t: TKind): Token; - function parseExpectedTokenJSDoc(t: JSDocSyntaxKind): Node { + function parseExpectedTokenJSDoc(t: TKind): ts.Token; + function parseExpectedTokenJSDoc(t: ts.JSDocSyntaxKind): ts.Node { return parseOptionalTokenJSDoc(t) || - createMissingNode(t, /*reportAtCurrentPosition*/ false, Diagnostics._0_expected, tokenToString(t)); + createMissingNode(t, /*reportAtCurrentPosition*/ false, ts.Diagnostics._0_expected, ts.tokenToString(t)); } - function parseTokenNode(): T { + function parseTokenNode(): T { const pos = getNodePos(); const kind = token(); nextToken(); return finishNode(factory.createToken(kind), pos) as T; } - function parseTokenNodeJSDoc(): T { + function parseTokenNodeJSDoc(): T { const pos = getNodePos(); const kind = token(); nextTokenJSDoc(); @@ -1864,12 +1841,12 @@ namespace ts { function canParseSemicolon() { // If there's a real semicolon, then we can always parse it out. - if (token() === SyntaxKind.SemicolonToken) { + if (token() === ts.SyntaxKind.SemicolonToken) { return true; } // We can parse out an optional semicolon in ASI cases in the following cases. - return token() === SyntaxKind.CloseBraceToken || token() === SyntaxKind.EndOfFileToken || scanner.hasPrecedingLineBreak(); + return token() === ts.SyntaxKind.CloseBraceToken || token() === ts.SyntaxKind.EndOfFileToken || scanner.hasPrecedingLineBreak(); } function tryParseSemicolon() { @@ -1877,7 +1854,7 @@ namespace ts { return false; } - if (token() === SyntaxKind.SemicolonToken) { + if (token() === ts.SyntaxKind.SemicolonToken) { // consume the semicolon if it was explicitly provided. nextToken(); } @@ -1886,19 +1863,19 @@ namespace ts { } function parseSemicolon(): boolean { - return tryParseSemicolon() || parseExpected(SyntaxKind.SemicolonToken); + return tryParseSemicolon() || parseExpected(ts.SyntaxKind.SemicolonToken); } - function createNodeArray(elements: T[], pos: number, end?: number, hasTrailingComma?: boolean): NodeArray { + function createNodeArray(elements: T[], pos: number, end?: number, hasTrailingComma?: boolean): ts.NodeArray { const array = factory.createNodeArray(elements, hasTrailingComma); - setTextRangePosEnd(array, pos, end ?? scanner.getStartPos()); + ts.setTextRangePosEnd(array, pos, end ?? scanner.getStartPos()); return array; } - function finishNode(node: T, pos: number, end?: number): T { - setTextRangePosEnd(node, pos, end ?? scanner.getStartPos()); + function finishNode(node: T, pos: number, end?: number): T { + ts.setTextRangePosEnd(node, pos, end ?? scanner.getStartPos()); if (contextFlags) { - (node as Mutable).flags |= contextFlags; + (node as ts.Mutable).flags |= contextFlags; } // Keep track on the node if we encountered an error while parsing it. If we did, then @@ -1906,15 +1883,15 @@ namespace ts { // flag so that we don't mark any subsequent nodes. if (parseErrorBeforeNextFinishedNode) { parseErrorBeforeNextFinishedNode = false; - (node as Mutable).flags |= NodeFlags.ThisNodeHasError; + (node as ts.Mutable).flags |= ts.NodeFlags.ThisNodeHasError; } return node; } - function createMissingNode(kind: T["kind"], reportAtCurrentPosition: false, diagnosticMessage?: DiagnosticMessage, arg0?: any): T; - function createMissingNode(kind: T["kind"], reportAtCurrentPosition: boolean, diagnosticMessage: DiagnosticMessage, arg0?: any): T; - function createMissingNode(kind: T["kind"], reportAtCurrentPosition: boolean, diagnosticMessage: DiagnosticMessage, arg0?: any): T { + function createMissingNode(kind: T["kind"], reportAtCurrentPosition: false, diagnosticMessage?: ts.DiagnosticMessage, arg0?: any): T; + function createMissingNode(kind: T["kind"], reportAtCurrentPosition: boolean, diagnosticMessage: ts.DiagnosticMessage, arg0?: any): T; + function createMissingNode(kind: T["kind"], reportAtCurrentPosition: boolean, diagnosticMessage: ts.DiagnosticMessage, arg0?: any): T { if (reportAtCurrentPosition) { parseErrorAtPosition(scanner.getStartPos(), 0, diagnosticMessage, arg0); } @@ -1923,12 +1900,11 @@ namespace ts { } const pos = getNodePos(); - const result = - kind === SyntaxKind.Identifier ? factory.createIdentifier("", /*typeArguments*/ undefined, /*originalKeywordKind*/ undefined) : - isTemplateLiteralKind(kind) ? factory.createTemplateLiteralLikeNode(kind, "", "", /*templateFlags*/ undefined) : - kind === SyntaxKind.NumericLiteral ? factory.createNumericLiteral("", /*numericLiteralFlags*/ undefined) : - kind === SyntaxKind.StringLiteral ? factory.createStringLiteral("", /*isSingleQuote*/ undefined) : - kind === SyntaxKind.MissingDeclaration ? factory.createMissingDeclaration() : + const result = kind === ts.SyntaxKind.Identifier ? factory.createIdentifier("", /*typeArguments*/ undefined, /*originalKeywordKind*/ undefined) : + ts.isTemplateLiteralKind(kind) ? factory.createTemplateLiteralLikeNode(kind, "", "", /*templateFlags*/ undefined) : + kind === ts.SyntaxKind.NumericLiteral ? factory.createNumericLiteral("", /*numericLiteralFlags*/ undefined) : + kind === ts.SyntaxKind.StringLiteral ? factory.createStringLiteral("", /*isSingleQuote*/ undefined) : + kind === ts.SyntaxKind.MissingDeclaration ? factory.createMissingDeclaration() : factory.createToken(kind); return finishNode(result, pos) as T; } @@ -1944,7 +1920,7 @@ namespace ts { // An identifier that starts with two underscores has an extra underscore character prepended to it to avoid issues // with magic property names like '__proto__'. The 'identifiers' object is used to share a single string instance for // each identifier in order to reduce memory consumption. - function createIdentifier(isIdentifier: boolean, diagnosticMessage?: DiagnosticMessage, privateIdentifierDiagnosticMessage?: DiagnosticMessage): Identifier { + function createIdentifier(isIdentifier: boolean, diagnosticMessage?: ts.DiagnosticMessage, privateIdentifierDiagnosticMessage?: ts.DiagnosticMessage): ts.Identifier { if (isIdentifier) { identifierCount++; const pos = getNodePos(); @@ -1955,83 +1931,82 @@ namespace ts { return finishNode(factory.createIdentifier(text, /*typeArguments*/ undefined, originalKeywordKind), pos); } - if (token() === SyntaxKind.PrivateIdentifier) { - parseErrorAtCurrentToken(privateIdentifierDiagnosticMessage || Diagnostics.Private_identifiers_are_not_allowed_outside_class_bodies); + if (token() === ts.SyntaxKind.PrivateIdentifier) { + parseErrorAtCurrentToken(privateIdentifierDiagnosticMessage || ts.Diagnostics.Private_identifiers_are_not_allowed_outside_class_bodies); return createIdentifier(/*isIdentifier*/ true); } - if (token() === SyntaxKind.Unknown && scanner.tryScan(() => scanner.reScanInvalidIdentifier() === SyntaxKind.Identifier)) { + if (token() === ts.SyntaxKind.Unknown && scanner.tryScan(() => scanner.reScanInvalidIdentifier() === ts.SyntaxKind.Identifier)) { // Scanner has already recorded an 'Invalid character' error, so no need to add another from the parser. return createIdentifier(/*isIdentifier*/ true); } identifierCount++; // Only for end of file because the error gets reported incorrectly on embedded script tags. - const reportAtCurrentPosition = token() === SyntaxKind.EndOfFileToken; + const reportAtCurrentPosition = token() === ts.SyntaxKind.EndOfFileToken; const isReservedWord = scanner.isReservedWord(); const msgArg = scanner.getTokenText(); const defaultMessage = isReservedWord ? - Diagnostics.Identifier_expected_0_is_a_reserved_word_that_cannot_be_used_here : - Diagnostics.Identifier_expected; - - return createMissingNode(SyntaxKind.Identifier, reportAtCurrentPosition, diagnosticMessage || defaultMessage, msgArg); + ts.Diagnostics.Identifier_expected_0_is_a_reserved_word_that_cannot_be_used_here : + ts.Diagnostics.Identifier_expected; + return createMissingNode(ts.SyntaxKind.Identifier, reportAtCurrentPosition, diagnosticMessage || defaultMessage, msgArg); } - function parseBindingIdentifier(privateIdentifierDiagnosticMessage?: DiagnosticMessage) { + function parseBindingIdentifier(privateIdentifierDiagnosticMessage?: ts.DiagnosticMessage) { return createIdentifier(isBindingIdentifier(), /*diagnosticMessage*/ undefined, privateIdentifierDiagnosticMessage); } - function parseIdentifier(diagnosticMessage?: DiagnosticMessage, privateIdentifierDiagnosticMessage?: DiagnosticMessage): Identifier { + function parseIdentifier(diagnosticMessage?: ts.DiagnosticMessage, privateIdentifierDiagnosticMessage?: ts.DiagnosticMessage): ts.Identifier { return createIdentifier(isIdentifier(), diagnosticMessage, privateIdentifierDiagnosticMessage); } - function parseIdentifierName(diagnosticMessage?: DiagnosticMessage): Identifier { - return createIdentifier(tokenIsIdentifierOrKeyword(token()), diagnosticMessage); + function parseIdentifierName(diagnosticMessage?: ts.DiagnosticMessage): ts.Identifier { + return createIdentifier(ts.tokenIsIdentifierOrKeyword(token()), diagnosticMessage); } function isLiteralPropertyName(): boolean { - return tokenIsIdentifierOrKeyword(token()) || - token() === SyntaxKind.StringLiteral || - token() === SyntaxKind.NumericLiteral; + return ts.tokenIsIdentifierOrKeyword(token()) || + token() === ts.SyntaxKind.StringLiteral || + token() === ts.SyntaxKind.NumericLiteral; } function isAssertionKey(): boolean { - return tokenIsIdentifierOrKeyword(token()) || - token() === SyntaxKind.StringLiteral; + return ts.tokenIsIdentifierOrKeyword(token()) || + token() === ts.SyntaxKind.StringLiteral; } - function parsePropertyNameWorker(allowComputedPropertyNames: boolean): PropertyName { - if (token() === SyntaxKind.StringLiteral || token() === SyntaxKind.NumericLiteral) { - const node = parseLiteralNode() as StringLiteral | NumericLiteral; + function parsePropertyNameWorker(allowComputedPropertyNames: boolean): ts.PropertyName { + if (token() === ts.SyntaxKind.StringLiteral || token() === ts.SyntaxKind.NumericLiteral) { + const node = parseLiteralNode() as ts.StringLiteral | ts.NumericLiteral; node.text = internIdentifier(node.text); return node; } - if (allowComputedPropertyNames && token() === SyntaxKind.OpenBracketToken) { + if (allowComputedPropertyNames && token() === ts.SyntaxKind.OpenBracketToken) { return parseComputedPropertyName(); } - if (token() === SyntaxKind.PrivateIdentifier) { + if (token() === ts.SyntaxKind.PrivateIdentifier) { return parsePrivateIdentifier(); } return parseIdentifierName(); } - function parsePropertyName(): PropertyName { + function parsePropertyName(): ts.PropertyName { return parsePropertyNameWorker(/*allowComputedPropertyNames*/ true); } - function parseComputedPropertyName(): ComputedPropertyName { + function parseComputedPropertyName(): ts.ComputedPropertyName { // PropertyName [Yield]: // LiteralPropertyName // ComputedPropertyName[?Yield] const pos = getNodePos(); - parseExpected(SyntaxKind.OpenBracketToken); + parseExpected(ts.SyntaxKind.OpenBracketToken); // We parse any expression (including a comma expression). But the grammar // says that only an assignment expression is allowed, so the grammar checker // will error if it sees a comma expression. const expression = allowInAnd(parseExpression); - parseExpected(SyntaxKind.CloseBracketToken); + parseExpected(ts.SyntaxKind.CloseBracketToken); return finishNode(factory.createComputedPropertyName(expression), pos); } @@ -2043,14 +2018,14 @@ namespace ts { return privateIdentifier; } - function parsePrivateIdentifier(): PrivateIdentifier { + function parsePrivateIdentifier(): ts.PrivateIdentifier { const pos = getNodePos(); const node = factory.createPrivateIdentifier(internPrivateIdentifier(scanner.getTokenText())); nextToken(); return finishNode(node, pos); } - function parseContextualModifier(t: SyntaxKind): boolean { + function parseContextualModifier(t: ts.SyntaxKind): boolean { return token() === t && tryParse(nextTokenCanFollowModifier); } @@ -2064,23 +2039,23 @@ namespace ts { function nextTokenCanFollowModifier() { switch (token()) { - case SyntaxKind.ConstKeyword: + case ts.SyntaxKind.ConstKeyword: // 'const' is only a modifier if followed by 'enum'. - return nextToken() === SyntaxKind.EnumKeyword; - case SyntaxKind.ExportKeyword: + return nextToken() === ts.SyntaxKind.EnumKeyword; + case ts.SyntaxKind.ExportKeyword: nextToken(); - if (token() === SyntaxKind.DefaultKeyword) { + if (token() === ts.SyntaxKind.DefaultKeyword) { return lookAhead(nextTokenCanFollowDefaultKeyword); } - if (token() === SyntaxKind.TypeKeyword) { + if (token() === ts.SyntaxKind.TypeKeyword) { return lookAhead(nextTokenCanFollowExportModifier); } return canFollowExportModifier(); - case SyntaxKind.DefaultKeyword: + case ts.SyntaxKind.DefaultKeyword: return nextTokenCanFollowDefaultKeyword(); - case SyntaxKind.StaticKeyword: - case SyntaxKind.GetKeyword: - case SyntaxKind.SetKeyword: + case ts.SyntaxKind.StaticKeyword: + case ts.SyntaxKind.GetKeyword: + case ts.SyntaxKind.SetKeyword: nextToken(); return canFollowModifier(); default: @@ -2089,9 +2064,9 @@ namespace ts { } function canFollowExportModifier(): boolean { - return token() !== SyntaxKind.AsteriskToken - && token() !== SyntaxKind.AsKeyword - && token() !== SyntaxKind.OpenBraceToken + return token() !== ts.SyntaxKind.AsteriskToken + && token() !== ts.SyntaxKind.AsKeyword + && token() !== ts.SyntaxKind.OpenBraceToken && canFollowModifier(); } @@ -2101,23 +2076,23 @@ namespace ts { } function parseAnyContextualModifier(): boolean { - return isModifierKind(token()) && tryParse(nextTokenCanFollowModifier); + return ts.isModifierKind(token()) && tryParse(nextTokenCanFollowModifier); } function canFollowModifier(): boolean { - return token() === SyntaxKind.OpenBracketToken - || token() === SyntaxKind.OpenBraceToken - || token() === SyntaxKind.AsteriskToken - || token() === SyntaxKind.DotDotDotToken + return token() === ts.SyntaxKind.OpenBracketToken + || token() === ts.SyntaxKind.OpenBraceToken + || token() === ts.SyntaxKind.AsteriskToken + || token() === ts.SyntaxKind.DotDotDotToken || isLiteralPropertyName(); } function nextTokenCanFollowDefaultKeyword(): boolean { nextToken(); - return token() === SyntaxKind.ClassKeyword || token() === SyntaxKind.FunctionKeyword || - token() === SyntaxKind.InterfaceKeyword || - (token() === SyntaxKind.AbstractKeyword && lookAhead(nextTokenIsClassKeywordOnSameLine)) || - (token() === SyntaxKind.AsyncKeyword && lookAhead(nextTokenIsFunctionKeywordOnSameLine)); + return token() === ts.SyntaxKind.ClassKeyword || token() === ts.SyntaxKind.FunctionKeyword || + token() === ts.SyntaxKind.InterfaceKeyword || + (token() === ts.SyntaxKind.AbstractKeyword && lookAhead(nextTokenIsClassKeywordOnSameLine)) || + (token() === ts.SyntaxKind.AsyncKeyword && lookAhead(nextTokenIsFunctionKeywordOnSameLine)); } // True if positioned at the start of a list element @@ -2137,9 +2112,9 @@ namespace ts { // we're parsing. For example, if we have a semicolon in the middle of a class, then // we really don't want to assume the class is over and we're on a statement in the // outer module. We just want to consume and move on. - return !(token() === SyntaxKind.SemicolonToken && inErrorRecovery) && isStartOfStatement(); + return !(token() === ts.SyntaxKind.SemicolonToken && inErrorRecovery) && isStartOfStatement(); case ParsingContext.SwitchClauses: - return token() === SyntaxKind.CaseKeyword || token() === SyntaxKind.DefaultKeyword; + return token() === ts.SyntaxKind.CaseKeyword || token() === ts.SyntaxKind.DefaultKeyword; case ParsingContext.TypeMembers: return lookAhead(isTypeMemberStart); case ParsingContext.ClassMembers: @@ -2147,17 +2122,17 @@ namespace ts { // not in error recovery. If we're in error recovery, we don't want an errant // semicolon to be treated as a class member (since they're almost always used // for statements. - return lookAhead(isClassMemberStart) || (token() === SyntaxKind.SemicolonToken && !inErrorRecovery); + return lookAhead(isClassMemberStart) || (token() === ts.SyntaxKind.SemicolonToken && !inErrorRecovery); case ParsingContext.EnumMembers: // Include open bracket computed properties. This technically also lets in indexers, // which would be a candidate for improved error reporting. - return token() === SyntaxKind.OpenBracketToken || isLiteralPropertyName(); + return token() === ts.SyntaxKind.OpenBracketToken || isLiteralPropertyName(); case ParsingContext.ObjectLiteralMembers: switch (token()) { - case SyntaxKind.OpenBracketToken: - case SyntaxKind.AsteriskToken: - case SyntaxKind.DotDotDotToken: - case SyntaxKind.DotToken: // Not an object literal member, but don't want to close the object (see `tests/cases/fourslash/completionsDotInObjectLiteral.ts`) + case ts.SyntaxKind.OpenBracketToken: + case ts.SyntaxKind.AsteriskToken: + case ts.SyntaxKind.DotDotDotToken: + case ts.SyntaxKind.DotToken: // Not an object literal member, but don't want to close the object (see `tests/cases/fourslash/completionsDotInObjectLiteral.ts`) return true; default: return isLiteralPropertyName(); @@ -2165,13 +2140,13 @@ namespace ts { case ParsingContext.RestProperties: return isLiteralPropertyName(); case ParsingContext.ObjectBindingElements: - return token() === SyntaxKind.OpenBracketToken || token() === SyntaxKind.DotDotDotToken || isLiteralPropertyName(); + return token() === ts.SyntaxKind.OpenBracketToken || token() === ts.SyntaxKind.DotDotDotToken || isLiteralPropertyName(); case ParsingContext.AssertEntries: return isAssertionKey(); case ParsingContext.HeritageClauseElement: // If we see `{ ... }` then only consume it as an expression if it is followed by `,` or `{` // That way we won't consume the body of a class in its heritage clause. - if (token() === SyntaxKind.OpenBraceToken) { + if (token() === ts.SyntaxKind.OpenBraceToken) { return lookAhead(isValidHeritageClauseObjectLiteral); } @@ -2187,41 +2162,41 @@ namespace ts { case ParsingContext.VariableDeclarations: return isBindingIdentifierOrPrivateIdentifierOrPattern(); case ParsingContext.ArrayBindingElements: - return token() === SyntaxKind.CommaToken || token() === SyntaxKind.DotDotDotToken || isBindingIdentifierOrPrivateIdentifierOrPattern(); + return token() === ts.SyntaxKind.CommaToken || token() === ts.SyntaxKind.DotDotDotToken || isBindingIdentifierOrPrivateIdentifierOrPattern(); case ParsingContext.TypeParameters: - return token() === SyntaxKind.InKeyword || isIdentifier(); + return token() === ts.SyntaxKind.InKeyword || isIdentifier(); case ParsingContext.ArrayLiteralMembers: switch (token()) { - case SyntaxKind.CommaToken: - case SyntaxKind.DotToken: // Not an array literal member, but don't want to close the array (see `tests/cases/fourslash/completionsDotInArrayLiteralInObjectLiteral.ts`) + case ts.SyntaxKind.CommaToken: + case ts.SyntaxKind.DotToken: // Not an array literal member, but don't want to close the array (see `tests/cases/fourslash/completionsDotInArrayLiteralInObjectLiteral.ts`) return true; } // falls through case ParsingContext.ArgumentExpressions: - return token() === SyntaxKind.DotDotDotToken || isStartOfExpression(); + return token() === ts.SyntaxKind.DotDotDotToken || isStartOfExpression(); case ParsingContext.Parameters: return isStartOfParameter(/*isJSDocParameter*/ false); case ParsingContext.JSDocParameters: return isStartOfParameter(/*isJSDocParameter*/ true); case ParsingContext.TypeArguments: case ParsingContext.TupleElementTypes: - return token() === SyntaxKind.CommaToken || isStartOfType(); + return token() === ts.SyntaxKind.CommaToken || isStartOfType(); case ParsingContext.HeritageClauses: return isHeritageClause(); case ParsingContext.ImportOrExportSpecifiers: - return tokenIsIdentifierOrKeyword(token()); + return ts.tokenIsIdentifierOrKeyword(token()); case ParsingContext.JsxAttributes: - return tokenIsIdentifierOrKeyword(token()) || token() === SyntaxKind.OpenBraceToken; + return ts.tokenIsIdentifierOrKeyword(token()) || token() === ts.SyntaxKind.OpenBraceToken; case ParsingContext.JsxChildren: return true; } - return Debug.fail("Non-exhaustive case in 'isListElement'."); + return ts.Debug.fail("Non-exhaustive case in 'isListElement'."); } function isValidHeritageClauseObjectLiteral() { - Debug.assert(token() === SyntaxKind.OpenBraceToken); - if (nextToken() === SyntaxKind.CloseBraceToken) { + ts.Debug.assert(token() === ts.SyntaxKind.OpenBraceToken); + if (nextToken() === ts.SyntaxKind.CloseBraceToken) { // if we see "extends {}" then only treat the {} as what we're extending (and not // the class body) if we have: // @@ -2231,7 +2206,7 @@ namespace ts { // extends {} implements const next = nextToken(); - return next === SyntaxKind.CommaToken || next === SyntaxKind.OpenBraceToken || next === SyntaxKind.ExtendsKeyword || next === SyntaxKind.ImplementsKeyword; + return next === ts.SyntaxKind.CommaToken || next === ts.SyntaxKind.OpenBraceToken || next === ts.SyntaxKind.ExtendsKeyword || next === ts.SyntaxKind.ImplementsKeyword; } return true; @@ -2244,17 +2219,17 @@ namespace ts { function nextTokenIsIdentifierOrKeyword() { nextToken(); - return tokenIsIdentifierOrKeyword(token()); + return ts.tokenIsIdentifierOrKeyword(token()); } function nextTokenIsIdentifierOrKeywordOrGreaterThan() { nextToken(); - return tokenIsIdentifierOrKeywordOrGreaterThan(token()); + return ts.tokenIsIdentifierOrKeywordOrGreaterThan(token()); } function isHeritageClauseExtendsOrImplementsKeyword(): boolean { - if (token() === SyntaxKind.ImplementsKeyword || - token() === SyntaxKind.ExtendsKeyword) { + if (token() === ts.SyntaxKind.ImplementsKeyword || + token() === ts.SyntaxKind.ExtendsKeyword) { return lookAhead(nextTokenIsStartOfExpression); } @@ -2274,7 +2249,7 @@ namespace ts { // True if positioned at a list terminator function isListTerminator(kind: ParsingContext): boolean { - if (token() === SyntaxKind.EndOfFileToken) { + if (token() === ts.SyntaxKind.EndOfFileToken) { // Being at the end of the file ends all lists. return true; } @@ -2289,37 +2264,37 @@ namespace ts { case ParsingContext.ObjectBindingElements: case ParsingContext.ImportOrExportSpecifiers: case ParsingContext.AssertEntries: - return token() === SyntaxKind.CloseBraceToken; + return token() === ts.SyntaxKind.CloseBraceToken; case ParsingContext.SwitchClauseStatements: - return token() === SyntaxKind.CloseBraceToken || token() === SyntaxKind.CaseKeyword || token() === SyntaxKind.DefaultKeyword; + return token() === ts.SyntaxKind.CloseBraceToken || token() === ts.SyntaxKind.CaseKeyword || token() === ts.SyntaxKind.DefaultKeyword; case ParsingContext.HeritageClauseElement: - return token() === SyntaxKind.OpenBraceToken || token() === SyntaxKind.ExtendsKeyword || token() === SyntaxKind.ImplementsKeyword; + return token() === ts.SyntaxKind.OpenBraceToken || token() === ts.SyntaxKind.ExtendsKeyword || token() === ts.SyntaxKind.ImplementsKeyword; case ParsingContext.VariableDeclarations: return isVariableDeclaratorListTerminator(); case ParsingContext.TypeParameters: // Tokens other than '>' are here for better error recovery - return token() === SyntaxKind.GreaterThanToken || token() === SyntaxKind.OpenParenToken || token() === SyntaxKind.OpenBraceToken || token() === SyntaxKind.ExtendsKeyword || token() === SyntaxKind.ImplementsKeyword; + return token() === ts.SyntaxKind.GreaterThanToken || token() === ts.SyntaxKind.OpenParenToken || token() === ts.SyntaxKind.OpenBraceToken || token() === ts.SyntaxKind.ExtendsKeyword || token() === ts.SyntaxKind.ImplementsKeyword; case ParsingContext.ArgumentExpressions: // Tokens other than ')' are here for better error recovery - return token() === SyntaxKind.CloseParenToken || token() === SyntaxKind.SemicolonToken; + return token() === ts.SyntaxKind.CloseParenToken || token() === ts.SyntaxKind.SemicolonToken; case ParsingContext.ArrayLiteralMembers: case ParsingContext.TupleElementTypes: case ParsingContext.ArrayBindingElements: - return token() === SyntaxKind.CloseBracketToken; + return token() === ts.SyntaxKind.CloseBracketToken; case ParsingContext.JSDocParameters: case ParsingContext.Parameters: case ParsingContext.RestProperties: // Tokens other than ')' and ']' (the latter for index signatures) are here for better error recovery - return token() === SyntaxKind.CloseParenToken || token() === SyntaxKind.CloseBracketToken /*|| token === SyntaxKind.OpenBraceToken*/; + return token() === ts.SyntaxKind.CloseParenToken || token() === ts.SyntaxKind.CloseBracketToken /*|| token === SyntaxKind.OpenBraceToken*/; case ParsingContext.TypeArguments: // All other tokens should cause the type-argument to terminate except comma token - return token() !== SyntaxKind.CommaToken; + return token() !== ts.SyntaxKind.CommaToken; case ParsingContext.HeritageClauses: - return token() === SyntaxKind.OpenBraceToken || token() === SyntaxKind.CloseBraceToken; + return token() === ts.SyntaxKind.OpenBraceToken || token() === ts.SyntaxKind.CloseBraceToken; case ParsingContext.JsxAttributes: - return token() === SyntaxKind.GreaterThanToken || token() === SyntaxKind.SlashToken; + return token() === ts.SyntaxKind.GreaterThanToken || token() === ts.SyntaxKind.SlashToken; case ParsingContext.JsxChildren: - return token() === SyntaxKind.LessThanToken && lookAhead(nextTokenIsSlash); + return token() === ts.SyntaxKind.LessThanToken && lookAhead(nextTokenIsSlash); default: return false; } @@ -2342,7 +2317,7 @@ namespace ts { // For better error recovery, if we see an '=>' then we just stop immediately. We've got an // arrow function here and it's going to be very unlikely that we'll resynchronize and get // another variable declaration. - if (token() === SyntaxKind.EqualsGreaterThanToken) { + if (token() === ts.SyntaxKind.EqualsGreaterThanToken) { return true; } @@ -2364,7 +2339,7 @@ namespace ts { } // Parses a list of elements - function parseList(kind: ParsingContext, parseElement: () => T): NodeArray { + function parseList(kind: ParsingContext, parseElement: () => T): ts.NodeArray { const saveParsingContext = parsingContext; parsingContext |= 1 << kind; const list = []; @@ -2386,7 +2361,7 @@ namespace ts { return createNodeArray(list, listPos); } - function parseListElement(parsingContext: ParsingContext, parseElement: () => T): T { + function parseListElement(parsingContext: ParsingContext, parseElement: () => T): T { const node = currentNode(parsingContext); if (node) { return consumeNode(node) as T; @@ -2395,7 +2370,7 @@ namespace ts { return parseElement(); } - function currentNode(parsingContext: ParsingContext): Node | undefined { + function currentNode(parsingContext: ParsingContext): ts.Node | undefined { // If we don't have a cursor or the parsing context isn't reusable, there's nothing to reuse. // // If there is an outstanding parse error that we've encountered, but not attached to @@ -2415,7 +2390,7 @@ namespace ts { // Can't reuse a node that intersected the change range. // Can't reuse a node that contains a parse error. This is necessary so that we // produce the same set of errors again. - if (nodeIsMissing(node) || node.intersectsChange || containsParseError(node)) { + if (ts.nodeIsMissing(node) || node.intersectsChange || ts.containsParseError(node)) { return undefined; } @@ -2430,7 +2405,7 @@ namespace ts { // differently depending on what mode it is in. // // This also applies to all our other context flags as well. - const nodeContextFlags = node.flags & NodeFlags.ContextFlags; + const nodeContextFlags = node.flags & ts.NodeFlags.ContextFlags; if (nodeContextFlags !== contextFlags) { return undefined; } @@ -2441,15 +2416,15 @@ namespace ts { return undefined; } - if ((node as JSDocContainer).jsDocCache) { + if ((node as ts.JSDocContainer).jsDocCache) { // jsDocCache may include tags from parent nodes, which might have been modified. - (node as JSDocContainer).jsDocCache = undefined; + (node as ts.JSDocContainer).jsDocCache = undefined; } return node; } - function consumeNode(node: Node) { + function consumeNode(node: ts.Node) { // Move the scanner so it is after the node we just consumed. scanner.setTextPos(node.end); nextToken(); @@ -2473,7 +2448,7 @@ namespace ts { return false; } - function canReuseNode(node: Node, parsingContext: ParsingContext): boolean { + function canReuseNode(node: ts.Node, parsingContext: ParsingContext): boolean { switch (parsingContext) { case ParsingContext.ClassMembers: return isReusableClassMember(node); @@ -2552,23 +2527,23 @@ namespace ts { return false; } - function isReusableClassMember(node: Node) { + function isReusableClassMember(node: ts.Node) { if (node) { switch (node.kind) { - case SyntaxKind.Constructor: - case SyntaxKind.IndexSignature: - case SyntaxKind.GetAccessor: - case SyntaxKind.SetAccessor: - case SyntaxKind.PropertyDeclaration: - case SyntaxKind.SemicolonClassElement: + case ts.SyntaxKind.Constructor: + case ts.SyntaxKind.IndexSignature: + case ts.SyntaxKind.GetAccessor: + case ts.SyntaxKind.SetAccessor: + case ts.SyntaxKind.PropertyDeclaration: + case ts.SyntaxKind.SemicolonClassElement: return true; - case SyntaxKind.MethodDeclaration: + case ts.SyntaxKind.MethodDeclaration: // Method declarations are not necessarily reusable. An object-literal // may have a method calls "constructor(...)" and we must reparse that // into an actual .ConstructorDeclaration. - const methodDeclaration = node as MethodDeclaration; - const nameIsConstructor = methodDeclaration.name.kind === SyntaxKind.Identifier && - methodDeclaration.name.originalKeywordKind === SyntaxKind.ConstructorKeyword; + const methodDeclaration = node as ts.MethodDeclaration; + const nameIsConstructor = methodDeclaration.name.kind === ts.SyntaxKind.Identifier && + methodDeclaration.name.originalKeywordKind === ts.SyntaxKind.ConstructorKeyword; return !nameIsConstructor; } @@ -2577,11 +2552,11 @@ namespace ts { return false; } - function isReusableSwitchClause(node: Node) { + function isReusableSwitchClause(node: ts.Node) { if (node) { switch (node.kind) { - case SyntaxKind.CaseClause: - case SyntaxKind.DefaultClause: + case ts.SyntaxKind.CaseClause: + case ts.SyntaxKind.DefaultClause: return true; } } @@ -2589,38 +2564,38 @@ namespace ts { return false; } - function isReusableStatement(node: Node) { + function isReusableStatement(node: ts.Node) { if (node) { switch (node.kind) { - case SyntaxKind.FunctionDeclaration: - case SyntaxKind.VariableStatement: - case SyntaxKind.Block: - case SyntaxKind.IfStatement: - case SyntaxKind.ExpressionStatement: - case SyntaxKind.ThrowStatement: - case SyntaxKind.ReturnStatement: - case SyntaxKind.SwitchStatement: - case SyntaxKind.BreakStatement: - case SyntaxKind.ContinueStatement: - case SyntaxKind.ForInStatement: - case SyntaxKind.ForOfStatement: - case SyntaxKind.ForStatement: - case SyntaxKind.WhileStatement: - case SyntaxKind.WithStatement: - case SyntaxKind.EmptyStatement: - case SyntaxKind.TryStatement: - case SyntaxKind.LabeledStatement: - case SyntaxKind.DoStatement: - case SyntaxKind.DebuggerStatement: - case SyntaxKind.ImportDeclaration: - case SyntaxKind.ImportEqualsDeclaration: - case SyntaxKind.ExportDeclaration: - case SyntaxKind.ExportAssignment: - case SyntaxKind.ModuleDeclaration: - case SyntaxKind.ClassDeclaration: - case SyntaxKind.InterfaceDeclaration: - case SyntaxKind.EnumDeclaration: - case SyntaxKind.TypeAliasDeclaration: + case ts.SyntaxKind.FunctionDeclaration: + case ts.SyntaxKind.VariableStatement: + case ts.SyntaxKind.Block: + case ts.SyntaxKind.IfStatement: + case ts.SyntaxKind.ExpressionStatement: + case ts.SyntaxKind.ThrowStatement: + case ts.SyntaxKind.ReturnStatement: + case ts.SyntaxKind.SwitchStatement: + case ts.SyntaxKind.BreakStatement: + case ts.SyntaxKind.ContinueStatement: + case ts.SyntaxKind.ForInStatement: + case ts.SyntaxKind.ForOfStatement: + case ts.SyntaxKind.ForStatement: + case ts.SyntaxKind.WhileStatement: + case ts.SyntaxKind.WithStatement: + case ts.SyntaxKind.EmptyStatement: + case ts.SyntaxKind.TryStatement: + case ts.SyntaxKind.LabeledStatement: + case ts.SyntaxKind.DoStatement: + case ts.SyntaxKind.DebuggerStatement: + case ts.SyntaxKind.ImportDeclaration: + case ts.SyntaxKind.ImportEqualsDeclaration: + case ts.SyntaxKind.ExportDeclaration: + case ts.SyntaxKind.ExportAssignment: + case ts.SyntaxKind.ModuleDeclaration: + case ts.SyntaxKind.ClassDeclaration: + case ts.SyntaxKind.InterfaceDeclaration: + case ts.SyntaxKind.EnumDeclaration: + case ts.SyntaxKind.TypeAliasDeclaration: return true; } } @@ -2628,18 +2603,18 @@ namespace ts { return false; } - function isReusableEnumMember(node: Node) { - return node.kind === SyntaxKind.EnumMember; + function isReusableEnumMember(node: ts.Node) { + return node.kind === ts.SyntaxKind.EnumMember; } - function isReusableTypeMember(node: Node) { + function isReusableTypeMember(node: ts.Node) { if (node) { switch (node.kind) { - case SyntaxKind.ConstructSignature: - case SyntaxKind.MethodSignature: - case SyntaxKind.IndexSignature: - case SyntaxKind.PropertySignature: - case SyntaxKind.CallSignature: + case ts.SyntaxKind.ConstructSignature: + case ts.SyntaxKind.MethodSignature: + case ts.SyntaxKind.IndexSignature: + case ts.SyntaxKind.PropertySignature: + case ts.SyntaxKind.CallSignature: return true; } } @@ -2647,8 +2622,8 @@ namespace ts { return false; } - function isReusableVariableDeclaration(node: Node) { - if (node.kind !== SyntaxKind.VariableDeclaration) { + function isReusableVariableDeclaration(node: ts.Node) { + if (node.kind !== ts.SyntaxKind.VariableDeclaration) { return false; } @@ -2666,17 +2641,17 @@ namespace ts { // // In order to prevent this, we do not allow a variable declarator to be reused if it // has an initializer. - const variableDeclarator = node as VariableDeclaration; + const variableDeclarator = node as ts.VariableDeclaration; return variableDeclarator.initializer === undefined; } - function isReusableParameter(node: Node) { - if (node.kind !== SyntaxKind.Parameter) { + function isReusableParameter(node: ts.Node) { + if (node.kind !== ts.SyntaxKind.Parameter) { return false; } // See the comment in isReusableVariableDeclaration for why we do this. - const parameter = node as ParameterDeclaration; + const parameter = node as ts.ParameterDeclaration; return parameter.initializer === undefined; } @@ -2694,46 +2669,46 @@ namespace ts { function parsingContextErrors(context: ParsingContext) { switch (context) { case ParsingContext.SourceElements: - return token() === SyntaxKind.DefaultKeyword - ? parseErrorAtCurrentToken(Diagnostics._0_expected, tokenToString(SyntaxKind.ExportKeyword)) - : parseErrorAtCurrentToken(Diagnostics.Declaration_or_statement_expected); - case ParsingContext.BlockStatements: return parseErrorAtCurrentToken(Diagnostics.Declaration_or_statement_expected); - case ParsingContext.SwitchClauses: return parseErrorAtCurrentToken(Diagnostics.case_or_default_expected); - case ParsingContext.SwitchClauseStatements: return parseErrorAtCurrentToken(Diagnostics.Statement_expected); + return token() === ts.SyntaxKind.DefaultKeyword + ? parseErrorAtCurrentToken(ts.Diagnostics._0_expected, ts.tokenToString(ts.SyntaxKind.ExportKeyword)) + : parseErrorAtCurrentToken(ts.Diagnostics.Declaration_or_statement_expected); + case ParsingContext.BlockStatements: return parseErrorAtCurrentToken(ts.Diagnostics.Declaration_or_statement_expected); + case ParsingContext.SwitchClauses: return parseErrorAtCurrentToken(ts.Diagnostics.case_or_default_expected); + case ParsingContext.SwitchClauseStatements: return parseErrorAtCurrentToken(ts.Diagnostics.Statement_expected); case ParsingContext.RestProperties: // fallthrough - case ParsingContext.TypeMembers: return parseErrorAtCurrentToken(Diagnostics.Property_or_signature_expected); - case ParsingContext.ClassMembers: return parseErrorAtCurrentToken(Diagnostics.Unexpected_token_A_constructor_method_accessor_or_property_was_expected); - case ParsingContext.EnumMembers: return parseErrorAtCurrentToken(Diagnostics.Enum_member_expected); - case ParsingContext.HeritageClauseElement: return parseErrorAtCurrentToken(Diagnostics.Expression_expected); + case ParsingContext.TypeMembers: return parseErrorAtCurrentToken(ts.Diagnostics.Property_or_signature_expected); + case ParsingContext.ClassMembers: return parseErrorAtCurrentToken(ts.Diagnostics.Unexpected_token_A_constructor_method_accessor_or_property_was_expected); + case ParsingContext.EnumMembers: return parseErrorAtCurrentToken(ts.Diagnostics.Enum_member_expected); + case ParsingContext.HeritageClauseElement: return parseErrorAtCurrentToken(ts.Diagnostics.Expression_expected); case ParsingContext.VariableDeclarations: - return isKeyword(token()) - ? parseErrorAtCurrentToken(Diagnostics._0_is_not_allowed_as_a_variable_declaration_name, tokenToString(token())) - : parseErrorAtCurrentToken(Diagnostics.Variable_declaration_expected); - case ParsingContext.ObjectBindingElements: return parseErrorAtCurrentToken(Diagnostics.Property_destructuring_pattern_expected); - case ParsingContext.ArrayBindingElements: return parseErrorAtCurrentToken(Diagnostics.Array_element_destructuring_pattern_expected); - case ParsingContext.ArgumentExpressions: return parseErrorAtCurrentToken(Diagnostics.Argument_expression_expected); - case ParsingContext.ObjectLiteralMembers: return parseErrorAtCurrentToken(Diagnostics.Property_assignment_expected); - case ParsingContext.ArrayLiteralMembers: return parseErrorAtCurrentToken(Diagnostics.Expression_or_comma_expected); - case ParsingContext.JSDocParameters: return parseErrorAtCurrentToken(Diagnostics.Parameter_declaration_expected); + return ts.isKeyword(token()) + ? parseErrorAtCurrentToken(ts.Diagnostics._0_is_not_allowed_as_a_variable_declaration_name, ts.tokenToString(token())) + : parseErrorAtCurrentToken(ts.Diagnostics.Variable_declaration_expected); + case ParsingContext.ObjectBindingElements: return parseErrorAtCurrentToken(ts.Diagnostics.Property_destructuring_pattern_expected); + case ParsingContext.ArrayBindingElements: return parseErrorAtCurrentToken(ts.Diagnostics.Array_element_destructuring_pattern_expected); + case ParsingContext.ArgumentExpressions: return parseErrorAtCurrentToken(ts.Diagnostics.Argument_expression_expected); + case ParsingContext.ObjectLiteralMembers: return parseErrorAtCurrentToken(ts.Diagnostics.Property_assignment_expected); + case ParsingContext.ArrayLiteralMembers: return parseErrorAtCurrentToken(ts.Diagnostics.Expression_or_comma_expected); + case ParsingContext.JSDocParameters: return parseErrorAtCurrentToken(ts.Diagnostics.Parameter_declaration_expected); case ParsingContext.Parameters: - return isKeyword(token()) - ? parseErrorAtCurrentToken(Diagnostics._0_is_not_allowed_as_a_parameter_name, tokenToString(token())) - : parseErrorAtCurrentToken(Diagnostics.Parameter_declaration_expected); - case ParsingContext.TypeParameters: return parseErrorAtCurrentToken(Diagnostics.Type_parameter_declaration_expected); - case ParsingContext.TypeArguments: return parseErrorAtCurrentToken(Diagnostics.Type_argument_expected); - case ParsingContext.TupleElementTypes: return parseErrorAtCurrentToken(Diagnostics.Type_expected); - case ParsingContext.HeritageClauses: return parseErrorAtCurrentToken(Diagnostics.Unexpected_token_expected); - case ParsingContext.ImportOrExportSpecifiers: return parseErrorAtCurrentToken(Diagnostics.Identifier_expected); - case ParsingContext.JsxAttributes: return parseErrorAtCurrentToken(Diagnostics.Identifier_expected); - case ParsingContext.JsxChildren: return parseErrorAtCurrentToken(Diagnostics.Identifier_expected); + return ts.isKeyword(token()) + ? parseErrorAtCurrentToken(ts.Diagnostics._0_is_not_allowed_as_a_parameter_name, ts.tokenToString(token())) + : parseErrorAtCurrentToken(ts.Diagnostics.Parameter_declaration_expected); + case ParsingContext.TypeParameters: return parseErrorAtCurrentToken(ts.Diagnostics.Type_parameter_declaration_expected); + case ParsingContext.TypeArguments: return parseErrorAtCurrentToken(ts.Diagnostics.Type_argument_expected); + case ParsingContext.TupleElementTypes: return parseErrorAtCurrentToken(ts.Diagnostics.Type_expected); + case ParsingContext.HeritageClauses: return parseErrorAtCurrentToken(ts.Diagnostics.Unexpected_token_expected); + case ParsingContext.ImportOrExportSpecifiers: return parseErrorAtCurrentToken(ts.Diagnostics.Identifier_expected); + case ParsingContext.JsxAttributes: return parseErrorAtCurrentToken(ts.Diagnostics.Identifier_expected); + case ParsingContext.JsxChildren: return parseErrorAtCurrentToken(ts.Diagnostics.Identifier_expected); default: return [undefined!]; // TODO: GH#18217 `default: Debug.assertNever(context);` } } // Parses a comma-delimited list of elements - function parseDelimitedList(kind: ParsingContext, parseElement: () => T, considerSemicolonAsDelimiter?: boolean): NodeArray; - function parseDelimitedList(kind: ParsingContext, parseElement: () => T, considerSemicolonAsDelimiter?: boolean): NodeArray> | undefined; - function parseDelimitedList(kind: ParsingContext, parseElement: () => T, considerSemicolonAsDelimiter?: boolean): NodeArray> | undefined { + function parseDelimitedList(kind: ParsingContext, parseElement: () => T, considerSemicolonAsDelimiter?: boolean): ts.NodeArray; + function parseDelimitedList(kind: ParsingContext, parseElement: () => T, considerSemicolonAsDelimiter?: boolean): ts.NodeArray> | undefined; + function parseDelimitedList(kind: ParsingContext, parseElement: () => T, considerSemicolonAsDelimiter?: boolean): ts.NodeArray> | undefined { const saveParsingContext = parsingContext; parsingContext |= 1 << kind; const list = []; @@ -2751,7 +2726,7 @@ namespace ts { list.push(result as NonNullable); commaStart = scanner.getTokenPos(); - if (parseOptional(SyntaxKind.CommaToken)) { + if (parseOptional(ts.SyntaxKind.CommaToken)) { // No need to check for a zero length node since we know we parsed a comma continue; } @@ -2763,14 +2738,14 @@ namespace ts { // We didn't get a comma, and the list wasn't terminated, explicitly parse // out a comma so we give a good error message. - parseExpected(SyntaxKind.CommaToken, getExpectedCommaDiagnostic(kind)); + parseExpected(ts.SyntaxKind.CommaToken, getExpectedCommaDiagnostic(kind)); // If the token was a semicolon, and the caller allows that, then skip it and // continue. This ensures we get back on track and don't result in tons of // parse errors. For example, this can happen when people do things like use // a semicolon to delimit object literal members. Note: we'll have already // reported an error when we called parseExpected above. - if (considerSemicolonAsDelimiter && token() === SyntaxKind.SemicolonToken && !scanner.hasPrecedingLineBreak()) { + if (considerSemicolonAsDelimiter && token() === ts.SyntaxKind.SemicolonToken && !scanner.hasPrecedingLineBreak()) { nextToken(); } if (startPos === scanner.getStartPos()) { @@ -2803,24 +2778,24 @@ namespace ts { } function getExpectedCommaDiagnostic(kind: ParsingContext) { - return kind === ParsingContext.EnumMembers ? Diagnostics.An_enum_member_name_must_be_followed_by_a_or : undefined; + return kind === ParsingContext.EnumMembers ? ts.Diagnostics.An_enum_member_name_must_be_followed_by_a_or : undefined; } - interface MissingList extends NodeArray { + interface MissingList extends ts.NodeArray { isMissingList: true; } - function createMissingList(): MissingList { + function createMissingList(): MissingList { const list = createNodeArray([], getNodePos()) as MissingList; list.isMissingList = true; return list; } - function isMissingList(arr: NodeArray): boolean { - return !!(arr as MissingList).isMissingList; + function isMissingList(arr: ts.NodeArray): boolean { + return !!(arr as MissingList).isMissingList; } - function parseBracketedList(kind: ParsingContext, parseElement: () => T, open: SyntaxKind, close: SyntaxKind): NodeArray { + function parseBracketedList(kind: ParsingContext, parseElement: () => T, open: ts.SyntaxKind, close: ts.SyntaxKind): ts.NodeArray { if (parseExpected(open)) { const result = parseDelimitedList(kind, parseElement); parseExpected(close); @@ -2830,33 +2805,27 @@ namespace ts { return createMissingList(); } - function parseEntityName(allowReservedWords: boolean, diagnosticMessage?: DiagnosticMessage): EntityName { + function parseEntityName(allowReservedWords: boolean, diagnosticMessage?: ts.DiagnosticMessage): ts.EntityName { const pos = getNodePos(); - let entity: EntityName = allowReservedWords ? parseIdentifierName(diagnosticMessage) : parseIdentifier(diagnosticMessage); + let entity: ts.EntityName = allowReservedWords ? parseIdentifierName(diagnosticMessage) : parseIdentifier(diagnosticMessage); let dotPos = getNodePos(); - while (parseOptional(SyntaxKind.DotToken)) { - if (token() === SyntaxKind.LessThanToken) { + while (parseOptional(ts.SyntaxKind.DotToken)) { + if (token() === ts.SyntaxKind.LessThanToken) { // the entity is part of a JSDoc-style generic, so record the trailing dot for later error reporting entity.jsdocDotPos = dotPos; break; } dotPos = getNodePos(); - entity = finishNode( - factory.createQualifiedName( - entity, - parseRightSideOfDot(allowReservedWords, /* allowPrivateIdentifiers */ false) as Identifier - ), - pos - ); + entity = finishNode(factory.createQualifiedName(entity, parseRightSideOfDot(allowReservedWords, /* allowPrivateIdentifiers */ false) as ts.Identifier), pos); } return entity; } - function createQualifiedName(entity: EntityName, name: Identifier): QualifiedName { + function createQualifiedName(entity: ts.EntityName, name: ts.Identifier): ts.QualifiedName { return finishNode(factory.createQualifiedName(entity, name), entity.pos); } - function parseRightSideOfDot(allowIdentifierNames: boolean, allowPrivateIdentifiers: boolean): Identifier | PrivateIdentifier { + function parseRightSideOfDot(allowIdentifierNames: boolean, allowPrivateIdentifiers: boolean): ts.Identifier | ts.PrivateIdentifier { // Technically a keyword is valid here as all identifiers and keywords are identifier names. // However, often we'll encounter this in error situations when the identifier or keyword // is actually starting another valid construct. @@ -2876,20 +2845,20 @@ namespace ts { // the code would be implicitly: "name.identifierOrKeyword; identifierNameOrKeyword". // In the first case though, ASI will not take effect because there is not a // line terminator after the identifier or keyword. - if (scanner.hasPrecedingLineBreak() && tokenIsIdentifierOrKeyword(token())) { + if (scanner.hasPrecedingLineBreak() && ts.tokenIsIdentifierOrKeyword(token())) { const matchesPattern = lookAhead(nextTokenIsIdentifierOrKeywordOnSameLine); if (matchesPattern) { // Report that we need an identifier. However, report it right after the dot, // and not on the next token. This is because the next token might actually // be an identifier and the error would be quite confusing. - return createMissingNode(SyntaxKind.Identifier, /*reportAtCurrentPosition*/ true, Diagnostics.Identifier_expected); + return createMissingNode(ts.SyntaxKind.Identifier, /*reportAtCurrentPosition*/ true, ts.Diagnostics.Identifier_expected); } } - if (token() === SyntaxKind.PrivateIdentifier) { + if (token() === ts.SyntaxKind.PrivateIdentifier) { const node = parsePrivateIdentifier(); - return allowPrivateIdentifiers ? node : createMissingNode(SyntaxKind.Identifier, /*reportAtCurrentPosition*/ true, Diagnostics.Identifier_expected); + return allowPrivateIdentifiers ? node : createMissingNode(ts.SyntaxKind.Identifier, /*reportAtCurrentPosition*/ true, ts.Diagnostics.Identifier_expected); } return allowIdentifierNames ? parseIdentifierName() : parseIdentifier(); @@ -2898,121 +2867,93 @@ namespace ts { function parseTemplateSpans(isTaggedTemplate: boolean) { const pos = getNodePos(); const list = []; - let node: TemplateSpan; + let node: ts.TemplateSpan; do { node = parseTemplateSpan(isTaggedTemplate); list.push(node); - } - while (node.literal.kind === SyntaxKind.TemplateMiddle); + } while (node.literal.kind === ts.SyntaxKind.TemplateMiddle); return createNodeArray(list, pos); } - function parseTemplateExpression(isTaggedTemplate: boolean): TemplateExpression { + function parseTemplateExpression(isTaggedTemplate: boolean): ts.TemplateExpression { const pos = getNodePos(); - return finishNode( - factory.createTemplateExpression( - parseTemplateHead(isTaggedTemplate), - parseTemplateSpans(isTaggedTemplate) - ), - pos - ); + return finishNode(factory.createTemplateExpression(parseTemplateHead(isTaggedTemplate), parseTemplateSpans(isTaggedTemplate)), pos); } - - function parseTemplateType(): TemplateLiteralTypeNode { + function parseTemplateType(): ts.TemplateLiteralTypeNode { const pos = getNodePos(); - return finishNode( - factory.createTemplateLiteralType( - parseTemplateHead(/*isTaggedTemplate*/ false), - parseTemplateTypeSpans() - ), - pos - ); + return finishNode(factory.createTemplateLiteralType(parseTemplateHead(/*isTaggedTemplate*/ false), parseTemplateTypeSpans()), pos); } function parseTemplateTypeSpans() { const pos = getNodePos(); const list = []; - let node: TemplateLiteralTypeSpan; + let node: ts.TemplateLiteralTypeSpan; do { node = parseTemplateTypeSpan(); list.push(node); - } - while (node.literal.kind === SyntaxKind.TemplateMiddle); + } while (node.literal.kind === ts.SyntaxKind.TemplateMiddle); return createNodeArray(list, pos); } - function parseTemplateTypeSpan(): TemplateLiteralTypeSpan { + function parseTemplateTypeSpan(): ts.TemplateLiteralTypeSpan { const pos = getNodePos(); - return finishNode( - factory.createTemplateLiteralTypeSpan( - parseType(), - parseLiteralOfTemplateSpan(/*isTaggedTemplate*/ false) - ), - pos - ); + return finishNode(factory.createTemplateLiteralTypeSpan(parseType(), parseLiteralOfTemplateSpan(/*isTaggedTemplate*/ false)), pos); } function parseLiteralOfTemplateSpan(isTaggedTemplate: boolean) { - if (token() === SyntaxKind.CloseBraceToken) { + if (token() === ts.SyntaxKind.CloseBraceToken) { reScanTemplateToken(isTaggedTemplate); return parseTemplateMiddleOrTemplateTail(); } else { // TODO(rbuckton): Do we need to call `parseExpectedToken` or can we just call `createMissingNode` directly? - return parseExpectedToken(SyntaxKind.TemplateTail, Diagnostics._0_expected, tokenToString(SyntaxKind.CloseBraceToken)) as TemplateTail; + return parseExpectedToken(ts.SyntaxKind.TemplateTail, ts.Diagnostics._0_expected, ts.tokenToString(ts.SyntaxKind.CloseBraceToken)) as ts.TemplateTail; } } - function parseTemplateSpan(isTaggedTemplate: boolean): TemplateSpan { + function parseTemplateSpan(isTaggedTemplate: boolean): ts.TemplateSpan { const pos = getNodePos(); - return finishNode( - factory.createTemplateSpan( - allowInAnd(parseExpression), - parseLiteralOfTemplateSpan(isTaggedTemplate) - ), - pos - ); + return finishNode(factory.createTemplateSpan(allowInAnd(parseExpression), parseLiteralOfTemplateSpan(isTaggedTemplate)), pos); } - function parseLiteralNode(): LiteralExpression { - return parseLiteralLikeNode(token()) as LiteralExpression; + function parseLiteralNode(): ts.LiteralExpression { + return parseLiteralLikeNode(token()) as ts.LiteralExpression; } - function parseTemplateHead(isTaggedTemplate: boolean): TemplateHead { + function parseTemplateHead(isTaggedTemplate: boolean): ts.TemplateHead { if (isTaggedTemplate) { reScanTemplateHeadOrNoSubstitutionTemplate(); } const fragment = parseLiteralLikeNode(token()); - Debug.assert(fragment.kind === SyntaxKind.TemplateHead, "Template head has wrong token kind"); - return fragment as TemplateHead; + ts.Debug.assert(fragment.kind === ts.SyntaxKind.TemplateHead, "Template head has wrong token kind"); + return fragment as ts.TemplateHead; } - function parseTemplateMiddleOrTemplateTail(): TemplateMiddle | TemplateTail { + function parseTemplateMiddleOrTemplateTail(): ts.TemplateMiddle | ts.TemplateTail { const fragment = parseLiteralLikeNode(token()); - Debug.assert(fragment.kind === SyntaxKind.TemplateMiddle || fragment.kind === SyntaxKind.TemplateTail, "Template fragment has wrong token kind"); - return fragment as TemplateMiddle | TemplateTail; + ts.Debug.assert(fragment.kind === ts.SyntaxKind.TemplateMiddle || fragment.kind === ts.SyntaxKind.TemplateTail, "Template fragment has wrong token kind"); + return fragment as ts.TemplateMiddle | ts.TemplateTail; } - function getTemplateLiteralRawText(kind: TemplateLiteralToken["kind"]) { - const isLast = kind === SyntaxKind.NoSubstitutionTemplateLiteral || kind === SyntaxKind.TemplateTail; + function getTemplateLiteralRawText(kind: ts.TemplateLiteralToken["kind"]) { + const isLast = kind === ts.SyntaxKind.NoSubstitutionTemplateLiteral || kind === ts.SyntaxKind.TemplateTail; const tokenText = scanner.getTokenText(); return tokenText.substring(1, tokenText.length - (scanner.isUnterminated() ? 0 : isLast ? 1 : 2)); } - function parseLiteralLikeNode(kind: SyntaxKind): LiteralLikeNode { + function parseLiteralLikeNode(kind: ts.SyntaxKind): ts.LiteralLikeNode { const pos = getNodePos(); - const node = - isTemplateLiteralKind(kind) ? factory.createTemplateLiteralLikeNode(kind, scanner.getTokenValue(), getTemplateLiteralRawText(kind), scanner.getTokenFlags() & TokenFlags.TemplateLiteralLikeFlags) : + const node = ts.isTemplateLiteralKind(kind) ? factory.createTemplateLiteralLikeNode(kind, scanner.getTokenValue(), getTemplateLiteralRawText(kind), scanner.getTokenFlags() & ts.TokenFlags.TemplateLiteralLikeFlags) : // Octal literals are not allowed in strict mode or ES5 // Note that theoretically the following condition would hold true literals like 009, // which is not octal. But because of how the scanner separates the tokens, we would // never get a token like this. Instead, we would get 00 and 9 as two separate tokens. // We also do not need to check for negatives because any prefix operator would be part of a // parent unary expression. - kind === SyntaxKind.NumericLiteral ? factory.createNumericLiteral(scanner.getTokenValue(), scanner.getNumericLiteralFlags()) : - kind === SyntaxKind.StringLiteral ? factory.createStringLiteral(scanner.getTokenValue(), /*isSingleQuote*/ undefined, scanner.hasExtendedUnicodeEscape()) : - isLiteralKind(kind) ? factory.createLiteralLikeNode(kind, scanner.getTokenValue()) : - Debug.fail(); + kind === ts.SyntaxKind.NumericLiteral ? factory.createNumericLiteral(scanner.getTokenValue(), scanner.getNumericLiteralFlags()) : + kind === ts.SyntaxKind.StringLiteral ? factory.createStringLiteral(scanner.getTokenValue(), /*isSingleQuote*/ undefined, scanner.hasExtendedUnicodeEscape()) : + ts.isLiteralKind(kind) ? factory.createLiteralLikeNode(kind, scanner.getTokenValue()) : + ts.Debug.fail(); if (scanner.hasExtendedUnicodeEscape()) { node.hasExtendedUnicodeEscape = true; @@ -3029,67 +2970,61 @@ namespace ts { // TYPES function parseEntityNameOfTypeReference() { - return parseEntityName(/*allowReservedWords*/ true, Diagnostics.Type_expected); + return parseEntityName(/*allowReservedWords*/ true, ts.Diagnostics.Type_expected); } function parseTypeArgumentsOfTypeReference() { - if (!scanner.hasPrecedingLineBreak() && reScanLessThanToken() === SyntaxKind.LessThanToken) { - return parseBracketedList(ParsingContext.TypeArguments, parseType, SyntaxKind.LessThanToken, SyntaxKind.GreaterThanToken); + if (!scanner.hasPrecedingLineBreak() && reScanLessThanToken() === ts.SyntaxKind.LessThanToken) { + return parseBracketedList(ParsingContext.TypeArguments, parseType, ts.SyntaxKind.LessThanToken, ts.SyntaxKind.GreaterThanToken); } } - function parseTypeReference(): TypeReferenceNode { + function parseTypeReference(): ts.TypeReferenceNode { const pos = getNodePos(); - return finishNode( - factory.createTypeReferenceNode( - parseEntityNameOfTypeReference(), - parseTypeArgumentsOfTypeReference() - ), - pos - ); + return finishNode(factory.createTypeReferenceNode(parseEntityNameOfTypeReference(), parseTypeArgumentsOfTypeReference()), pos); } // If true, we should abort parsing an error function. - function typeHasArrowFunctionBlockingParseError(node: TypeNode): boolean { + function typeHasArrowFunctionBlockingParseError(node: ts.TypeNode): boolean { switch (node.kind) { - case SyntaxKind.TypeReference: - return nodeIsMissing((node as TypeReferenceNode).typeName); - case SyntaxKind.FunctionType: - case SyntaxKind.ConstructorType: { - const { parameters, type } = node as FunctionOrConstructorTypeNode; + case ts.SyntaxKind.TypeReference: + return ts.nodeIsMissing((node as ts.TypeReferenceNode).typeName); + case ts.SyntaxKind.FunctionType: + case ts.SyntaxKind.ConstructorType: { + const { parameters, type } = node as ts.FunctionOrConstructorTypeNode; return isMissingList(parameters) || typeHasArrowFunctionBlockingParseError(type); } - case SyntaxKind.ParenthesizedType: - return typeHasArrowFunctionBlockingParseError((node as ParenthesizedTypeNode).type); + case ts.SyntaxKind.ParenthesizedType: + return typeHasArrowFunctionBlockingParseError((node as ts.ParenthesizedTypeNode).type); default: return false; } } - function parseThisTypePredicate(lhs: ThisTypeNode): TypePredicateNode { + function parseThisTypePredicate(lhs: ts.ThisTypeNode): ts.TypePredicateNode { nextToken(); return finishNode(factory.createTypePredicateNode(/*assertsModifier*/ undefined, lhs, parseType()), lhs.pos); } - function parseThisTypeNode(): ThisTypeNode { + function parseThisTypeNode(): ts.ThisTypeNode { const pos = getNodePos(); nextToken(); return finishNode(factory.createThisTypeNode(), pos); } - function parseJSDocAllType(): JSDocAllType | JSDocOptionalType { + function parseJSDocAllType(): ts.JSDocAllType | ts.JSDocOptionalType { const pos = getNodePos(); nextToken(); return finishNode(factory.createJSDocAllType(), pos); } - function parseJSDocNonNullableType(): TypeNode { + function parseJSDocNonNullableType(): ts.TypeNode { const pos = getNodePos(); nextToken(); return finishNode(factory.createJSDocNonNullableType(parseNonArrayType(), /*postfix*/ false), pos); } - function parseJSDocUnknownOrNullableType(): JSDocUnknownType | JSDocNullableType { + function parseJSDocUnknownOrNullableType(): ts.JSDocUnknownType | ts.JSDocNullableType { const pos = getNodePos(); // skip the ? nextToken(); @@ -3104,12 +3039,12 @@ namespace ts { // Foo // Foo(?= // (?| - if (token() === SyntaxKind.CommaToken || - token() === SyntaxKind.CloseBraceToken || - token() === SyntaxKind.CloseParenToken || - token() === SyntaxKind.GreaterThanToken || - token() === SyntaxKind.EqualsToken || - token() === SyntaxKind.BarToken) { + if (token() === ts.SyntaxKind.CommaToken || + token() === ts.SyntaxKind.CloseBraceToken || + token() === ts.SyntaxKind.CloseParenToken || + token() === ts.SyntaxKind.GreaterThanToken || + token() === ts.SyntaxKind.EqualsToken || + token() === ts.SyntaxKind.BarToken) { return finishNode(factory.createJSDocUnknownType(), pos); } else { @@ -3117,52 +3052,46 @@ namespace ts { } } - function parseJSDocFunctionType(): JSDocFunctionType | TypeReferenceNode { + function parseJSDocFunctionType(): ts.JSDocFunctionType | ts.TypeReferenceNode { const pos = getNodePos(); const hasJSDoc = hasPrecedingJSDocComment(); if (lookAhead(nextTokenIsOpenParen)) { nextToken(); const parameters = parseParameters(SignatureFlags.Type | SignatureFlags.JSDoc); - const type = parseReturnType(SyntaxKind.ColonToken, /*isType*/ false); + const type = parseReturnType(ts.SyntaxKind.ColonToken, /*isType*/ false); return withJSDoc(finishNode(factory.createJSDocFunctionType(parameters, type), pos), hasJSDoc); } return finishNode(factory.createTypeReferenceNode(parseIdentifierName(), /*typeArguments*/ undefined), pos); } - function parseJSDocParameter(): ParameterDeclaration { + function parseJSDocParameter(): ts.ParameterDeclaration { const pos = getNodePos(); - let name: Identifier | undefined; - if (token() === SyntaxKind.ThisKeyword || token() === SyntaxKind.NewKeyword) { + let name: ts.Identifier | undefined; + if (token() === ts.SyntaxKind.ThisKeyword || token() === ts.SyntaxKind.NewKeyword) { name = parseIdentifierName(); - parseExpected(SyntaxKind.ColonToken); + parseExpected(ts.SyntaxKind.ColonToken); } - return finishNode( - factory.createParameterDeclaration( + return finishNode(factory.createParameterDeclaration( /*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, // TODO(rbuckton): JSDoc parameters don't have names (except `this`/`new`), should we manufacture an empty identifier? name!, - /*questionToken*/ undefined, - parseJSDocType(), - /*initializer*/ undefined - ), - pos - ); + /*questionToken*/ undefined, parseJSDocType(), + /*initializer*/ undefined), pos); } - - function parseJSDocType(): TypeNode { + function parseJSDocType(): ts.TypeNode { scanner.setInJSDocType(true); const pos = getNodePos(); - if (parseOptional(SyntaxKind.ModuleKeyword)) { + if (parseOptional(ts.SyntaxKind.ModuleKeyword)) { // TODO(rbuckton): We never set the type for a JSDocNamepathType. What should we put here? const moduleTag = factory.createJSDocNamepathType(/*type*/ undefined!); terminate: while (true) { switch (token()) { - case SyntaxKind.CloseBraceToken: - case SyntaxKind.EndOfFileToken: - case SyntaxKind.CommaToken: - case SyntaxKind.WhitespaceTrivia: + case ts.SyntaxKind.CloseBraceToken: + case ts.SyntaxKind.EndOfFileToken: + case ts.SyntaxKind.CommaToken: + case ts.SyntaxKind.WhitespaceTrivia: break terminate; default: nextTokenJSDoc(); @@ -3173,35 +3102,35 @@ namespace ts { return finishNode(moduleTag, pos); } - const hasDotDotDot = parseOptional(SyntaxKind.DotDotDotToken); + const hasDotDotDot = parseOptional(ts.SyntaxKind.DotDotDotToken); let type = parseTypeOrTypePredicate(); scanner.setInJSDocType(false); if (hasDotDotDot) { type = finishNode(factory.createJSDocVariadicType(type), pos); } - if (token() === SyntaxKind.EqualsToken) { + if (token() === ts.SyntaxKind.EqualsToken) { nextToken(); return finishNode(factory.createJSDocOptionalType(type), pos); } return type; } - function parseTypeQuery(): TypeQueryNode { + function parseTypeQuery(): ts.TypeQueryNode { const pos = getNodePos(); - parseExpected(SyntaxKind.TypeOfKeyword); + parseExpected(ts.SyntaxKind.TypeOfKeyword); const entityName = parseEntityName(/*allowReservedWords*/ true); // Make sure we perform ASI to prevent parsing the next line's type arguments as part of an instantiation expression. const typeArguments = !scanner.hasPrecedingLineBreak() ? tryParseTypeArguments() : undefined; return finishNode(factory.createTypeQueryNode(entityName, typeArguments), pos); } - function parseTypeParameter(): TypeParameterDeclaration { + function parseTypeParameter(): ts.TypeParameterDeclaration { const pos = getNodePos(); const modifiers = parseModifiers(); const name = parseIdentifier(); - let constraint: TypeNode | undefined; - let expression: Expression | undefined; - if (parseOptional(SyntaxKind.ExtendsKeyword)) { + let constraint: ts.TypeNode | undefined; + let expression: ts.Expression | undefined; + if (parseOptional(ts.SyntaxKind.ExtendsKeyword)) { // It's not uncommon for people to write improper constraints to a generic. If the // user writes a constraint that is an expression and not an actual type, then parse // it out as an expression (so we can recover well), but report that a type is needed @@ -3221,31 +3150,31 @@ namespace ts { } } - const defaultType = parseOptional(SyntaxKind.EqualsToken) ? parseType() : undefined; + const defaultType = parseOptional(ts.SyntaxKind.EqualsToken) ? parseType() : undefined; const node = factory.createTypeParameterDeclaration(modifiers, name, constraint, defaultType); node.expression = expression; return finishNode(node, pos); } - function parseTypeParameters(): NodeArray | undefined { - if (token() === SyntaxKind.LessThanToken) { - return parseBracketedList(ParsingContext.TypeParameters, parseTypeParameter, SyntaxKind.LessThanToken, SyntaxKind.GreaterThanToken); + function parseTypeParameters(): ts.NodeArray | undefined { + if (token() === ts.SyntaxKind.LessThanToken) { + return parseBracketedList(ParsingContext.TypeParameters, parseTypeParameter, ts.SyntaxKind.LessThanToken, ts.SyntaxKind.GreaterThanToken); } } function isStartOfParameter(isJSDocParameter: boolean): boolean { - return token() === SyntaxKind.DotDotDotToken || + return token() === ts.SyntaxKind.DotDotDotToken || isBindingIdentifierOrPrivateIdentifierOrPattern() || - isModifierKind(token()) || - token() === SyntaxKind.AtToken || + ts.isModifierKind(token()) || + token() === ts.SyntaxKind.AtToken || isStartOfType(/*inStartOfParameter*/ !isJSDocParameter); } - function parseNameOfParameter(modifiers: ModifiersArray | undefined) { + function parseNameOfParameter(modifiers: ts.ModifiersArray | undefined) { // FormalParameter [Yield,Await]: // BindingElement[?Yield,?Await] - const name = parseIdentifierOrPattern(Diagnostics.Private_identifiers_cannot_be_used_as_parameters); - if (getFullWidth(name) === 0 && !some(modifiers) && isModifierKind(token())) { + const name = parseIdentifierOrPattern(ts.Diagnostics.Private_identifiers_cannot_be_used_as_parameters); + if (ts.getFullWidth(name) === 0 && !ts.some(modifiers) && ts.isModifierKind(token())) { // in cases like // 'use strict' // function foo(static) @@ -3263,20 +3192,20 @@ namespace ts { // Be permissive about await and yield by calling isBindingIdentifier instead of isIdentifier; disallowing // them during a speculative parse leads to many more follow-on errors than allowing the function to parse then later // complaining about the use of the keywords. - return isBindingIdentifier() || token() === SyntaxKind.OpenBracketToken || token() === SyntaxKind.OpenBraceToken; + return isBindingIdentifier() || token() === ts.SyntaxKind.OpenBracketToken || token() === ts.SyntaxKind.OpenBraceToken; } - function parseParameter(inOuterAwaitContext: boolean): ParameterDeclaration { + function parseParameter(inOuterAwaitContext: boolean): ts.ParameterDeclaration { return parseParameterWorker(inOuterAwaitContext); } - function parseParameterForSpeculation(inOuterAwaitContext: boolean): ParameterDeclaration | undefined { + function parseParameterForSpeculation(inOuterAwaitContext: boolean): ts.ParameterDeclaration | undefined { return parseParameterWorker(inOuterAwaitContext, /*allowAmbiguity*/ false); } - function parseParameterWorker(inOuterAwaitContext: boolean): ParameterDeclaration; - function parseParameterWorker(inOuterAwaitContext: boolean, allowAmbiguity: false): ParameterDeclaration | undefined; - function parseParameterWorker(inOuterAwaitContext: boolean, allowAmbiguity = true): ParameterDeclaration | undefined { + function parseParameterWorker(inOuterAwaitContext: boolean): ts.ParameterDeclaration; + function parseParameterWorker(inOuterAwaitContext: boolean, allowAmbiguity: false): ts.ParameterDeclaration | undefined; + function parseParameterWorker(inOuterAwaitContext: boolean, allowAmbiguity = true): ts.ParameterDeclaration | undefined { const pos = getNodePos(); const hasJSDoc = hasPrecedingJSDocComment(); @@ -3286,19 +3215,15 @@ namespace ts { // Decorators are parsed in the outer [Await] context, the rest of the parameter is parsed in the function's [Await] context. const decorators = inOuterAwaitContext ? doInAwaitContext(parseDecorators) : parseDecorators(); - if (token() === SyntaxKind.ThisKeyword) { - const node = factory.createParameterDeclaration( - decorators, + if (token() === ts.SyntaxKind.ThisKeyword) { + const node = factory.createParameterDeclaration(decorators, /*modifiers*/ undefined, - /*dotDotDotToken*/ undefined, - createIdentifier(/*isIdentifier*/ true), - /*questionToken*/ undefined, - parseTypeAnnotation(), - /*initializer*/ undefined - ); + /*dotDotDotToken*/ undefined, createIdentifier(/*isIdentifier*/ true), + /*questionToken*/ undefined, parseTypeAnnotation(), + /*initializer*/ undefined); if (decorators) { - parseErrorAtRange(decorators[0], Diagnostics.Decorators_may_not_be_applied_to_this_parameters); + parseErrorAtRange(decorators[0], ts.Diagnostics.Decorators_may_not_be_applied_to_this_parameters); } return withJSDoc(finishNode(node, pos), hasJSDoc); @@ -3308,59 +3233,45 @@ namespace ts { topLevel = false; const modifiers = parseModifiers(); - const dotDotDotToken = parseOptionalToken(SyntaxKind.DotDotDotToken); + const dotDotDotToken = parseOptionalToken(ts.SyntaxKind.DotDotDotToken); if (!allowAmbiguity && !isParameterNameStart()) { return undefined; } - const node = withJSDoc( - finishNode( - factory.createParameterDeclaration( - decorators, - modifiers, - dotDotDotToken, - parseNameOfParameter(modifiers), - parseOptionalToken(SyntaxKind.QuestionToken), - parseTypeAnnotation(), - parseInitializer() - ), - pos - ), - hasJSDoc - ); + const node = withJSDoc(finishNode(factory.createParameterDeclaration(decorators, modifiers, dotDotDotToken, parseNameOfParameter(modifiers), parseOptionalToken(ts.SyntaxKind.QuestionToken), parseTypeAnnotation(), parseInitializer()), pos), hasJSDoc); topLevel = savedTopLevel; return node; } - function parseReturnType(returnToken: SyntaxKind.EqualsGreaterThanToken, isType: boolean): TypeNode; - function parseReturnType(returnToken: SyntaxKind.ColonToken | SyntaxKind.EqualsGreaterThanToken, isType: boolean): TypeNode | undefined; - function parseReturnType(returnToken: SyntaxKind.ColonToken | SyntaxKind.EqualsGreaterThanToken, isType: boolean) { + function parseReturnType(returnToken: ts.SyntaxKind.EqualsGreaterThanToken, isType: boolean): ts.TypeNode; + function parseReturnType(returnToken: ts.SyntaxKind.ColonToken | ts.SyntaxKind.EqualsGreaterThanToken, isType: boolean): ts.TypeNode | undefined; + function parseReturnType(returnToken: ts.SyntaxKind.ColonToken | ts.SyntaxKind.EqualsGreaterThanToken, isType: boolean) { if (shouldParseReturnType(returnToken, isType)) { return allowConditionalTypesAnd(parseTypeOrTypePredicate); } } - function shouldParseReturnType(returnToken: SyntaxKind.ColonToken | SyntaxKind.EqualsGreaterThanToken, isType: boolean): boolean { - if (returnToken === SyntaxKind.EqualsGreaterThanToken) { + function shouldParseReturnType(returnToken: ts.SyntaxKind.ColonToken | ts.SyntaxKind.EqualsGreaterThanToken, isType: boolean): boolean { + if (returnToken === ts.SyntaxKind.EqualsGreaterThanToken) { parseExpected(returnToken); return true; } - else if (parseOptional(SyntaxKind.ColonToken)) { + else if (parseOptional(ts.SyntaxKind.ColonToken)) { return true; } - else if (isType && token() === SyntaxKind.EqualsGreaterThanToken) { + else if (isType && token() === ts.SyntaxKind.EqualsGreaterThanToken) { // This is easy to get backward, especially in type contexts, so parse the type anyway - parseErrorAtCurrentToken(Diagnostics._0_expected, tokenToString(SyntaxKind.ColonToken)); + parseErrorAtCurrentToken(ts.Diagnostics._0_expected, ts.tokenToString(ts.SyntaxKind.ColonToken)); nextToken(); return true; } return false; } - function parseParametersWorker(flags: SignatureFlags, allowAmbiguity: true): NodeArray; - function parseParametersWorker(flags: SignatureFlags, allowAmbiguity: false): NodeArray | undefined; - function parseParametersWorker(flags: SignatureFlags, allowAmbiguity: boolean): NodeArray | undefined { + function parseParametersWorker(flags: SignatureFlags, allowAmbiguity: true): ts.NodeArray; + function parseParametersWorker(flags: SignatureFlags, allowAmbiguity: false): ts.NodeArray | undefined; + function parseParametersWorker(flags: SignatureFlags, allowAmbiguity: boolean): ts.NodeArray | undefined { // FormalParameters [Yield,Await]: (modified) // [empty] // FormalParameterList[?Yield,Await] @@ -3390,7 +3301,7 @@ namespace ts { return parameters; } - function parseParameters(flags: SignatureFlags): NodeArray { + function parseParameters(flags: SignatureFlags): ts.NodeArray { // FormalParameters [Yield,Await]: (modified) // [empty] // FormalParameterList[?Yield,Await] @@ -3404,19 +3315,19 @@ namespace ts { // // SingleNameBinding [Yield,Await]: // BindingIdentifier[?Yield,?Await]Initializer [In, ?Yield,?Await] opt - if (!parseExpected(SyntaxKind.OpenParenToken)) { - return createMissingList(); + if (!parseExpected(ts.SyntaxKind.OpenParenToken)) { + return createMissingList(); } const parameters = parseParametersWorker(flags, /*allowAmbiguity*/ true); - parseExpected(SyntaxKind.CloseParenToken); + parseExpected(ts.SyntaxKind.CloseParenToken); return parameters; } function parseTypeMemberSemicolon() { // We allow type members to be separated by commas or (possibly ASI) semicolons. // First check if it was a comma. If so, we're done with the member. - if (parseOptional(SyntaxKind.CommaToken)) { + if (parseOptional(ts.SyntaxKind.CommaToken)) { return; } @@ -3424,25 +3335,25 @@ namespace ts { parseSemicolon(); } - function parseSignatureMember(kind: SyntaxKind.CallSignature | SyntaxKind.ConstructSignature): CallSignatureDeclaration | ConstructSignatureDeclaration { + function parseSignatureMember(kind: ts.SyntaxKind.CallSignature | ts.SyntaxKind.ConstructSignature): ts.CallSignatureDeclaration | ts.ConstructSignatureDeclaration { const pos = getNodePos(); const hasJSDoc = hasPrecedingJSDocComment(); - if (kind === SyntaxKind.ConstructSignature) { - parseExpected(SyntaxKind.NewKeyword); + if (kind === ts.SyntaxKind.ConstructSignature) { + parseExpected(ts.SyntaxKind.NewKeyword); } const typeParameters = parseTypeParameters(); const parameters = parseParameters(SignatureFlags.Type); - const type = parseReturnType(SyntaxKind.ColonToken, /*isType*/ true); + const type = parseReturnType(ts.SyntaxKind.ColonToken, /*isType*/ true); parseTypeMemberSemicolon(); - const node = kind === SyntaxKind.CallSignature + const node = kind === ts.SyntaxKind.CallSignature ? factory.createCallSignature(typeParameters, parameters, type) : factory.createConstructSignature(typeParameters, parameters, type); return withJSDoc(finishNode(node, pos), hasJSDoc); } function isIndexSignature(): boolean { - return token() === SyntaxKind.OpenBracketToken && lookAhead(isUnambiguouslyIndexSignature); + return token() === ts.SyntaxKind.OpenBracketToken && lookAhead(isUnambiguouslyIndexSignature); } function isUnambiguouslyIndexSignature() { @@ -3463,11 +3374,11 @@ namespace ts { // [] // nextToken(); - if (token() === SyntaxKind.DotDotDotToken || token() === SyntaxKind.CloseBracketToken) { + if (token() === ts.SyntaxKind.DotDotDotToken || token() === ts.SyntaxKind.CloseBracketToken) { return true; } - if (isModifierKind(token())) { + if (ts.isModifierKind(token())) { nextToken(); if (isIdentifier()) { return true; @@ -3484,40 +3395,40 @@ namespace ts { // A colon signifies a well formed indexer // A comma should be a badly formed indexer because comma expressions are not allowed // in computed properties. - if (token() === SyntaxKind.ColonToken || token() === SyntaxKind.CommaToken) { + if (token() === ts.SyntaxKind.ColonToken || token() === ts.SyntaxKind.CommaToken) { return true; } // Question mark could be an indexer with an optional property, // or it could be a conditional expression in a computed property. - if (token() !== SyntaxKind.QuestionToken) { + if (token() !== ts.SyntaxKind.QuestionToken) { return false; } // If any of the following tokens are after the question mark, it cannot // be a conditional expression, so treat it as an indexer. nextToken(); - return token() === SyntaxKind.ColonToken || token() === SyntaxKind.CommaToken || token() === SyntaxKind.CloseBracketToken; + return token() === ts.SyntaxKind.ColonToken || token() === ts.SyntaxKind.CommaToken || token() === ts.SyntaxKind.CloseBracketToken; } - function parseIndexSignatureDeclaration(pos: number, hasJSDoc: boolean, decorators: NodeArray | undefined, modifiers: NodeArray | undefined): IndexSignatureDeclaration { - const parameters = parseBracketedList(ParsingContext.Parameters, () => parseParameter(/*inOuterAwaitContext*/ false), SyntaxKind.OpenBracketToken, SyntaxKind.CloseBracketToken); + function parseIndexSignatureDeclaration(pos: number, hasJSDoc: boolean, decorators: ts.NodeArray | undefined, modifiers: ts.NodeArray | undefined): ts.IndexSignatureDeclaration { + const parameters = parseBracketedList(ParsingContext.Parameters, () => parseParameter(/*inOuterAwaitContext*/ false), ts.SyntaxKind.OpenBracketToken, ts.SyntaxKind.CloseBracketToken); const type = parseTypeAnnotation(); parseTypeMemberSemicolon(); const node = factory.createIndexSignature(decorators, modifiers, parameters, type); return withJSDoc(finishNode(node, pos), hasJSDoc); } - function parsePropertyOrMethodSignature(pos: number, hasJSDoc: boolean, modifiers: NodeArray | undefined): PropertySignature | MethodSignature { + function parsePropertyOrMethodSignature(pos: number, hasJSDoc: boolean, modifiers: ts.NodeArray | undefined): ts.PropertySignature | ts.MethodSignature { const name = parsePropertyName(); - const questionToken = parseOptionalToken(SyntaxKind.QuestionToken); - let node: PropertySignature | MethodSignature; - if (token() === SyntaxKind.OpenParenToken || token() === SyntaxKind.LessThanToken) { + const questionToken = parseOptionalToken(ts.SyntaxKind.QuestionToken); + let node: ts.PropertySignature | ts.MethodSignature; + if (token() === ts.SyntaxKind.OpenParenToken || token() === ts.SyntaxKind.LessThanToken) { // Method signatures don't exist in expression contexts. So they have neither // [Yield] nor [Await] const typeParameters = parseTypeParameters(); const parameters = parseParameters(SignatureFlags.Type); - const type = parseReturnType(SyntaxKind.ColonToken, /*isType*/ true); + const type = parseReturnType(ts.SyntaxKind.ColonToken, /*isType*/ true); node = factory.createMethodSignature(modifiers, name, questionToken, typeParameters, parameters, type); } else { @@ -3526,7 +3437,8 @@ namespace ts { // Although type literal properties cannot not have initializers, we attempt // to parse an initializer so we can report in the checker that an interface // property or type literal property cannot have an initializer. - if (token() === SyntaxKind.EqualsToken) node.initializer = parseInitializer(); + if (token() === ts.SyntaxKind.EqualsToken) + node.initializer = parseInitializer(); } parseTypeMemberSemicolon(); return withJSDoc(finishNode(node, pos), hasJSDoc); @@ -3534,20 +3446,20 @@ namespace ts { function isTypeMemberStart(): boolean { // Return true if we have the start of a signature member - if (token() === SyntaxKind.OpenParenToken || - token() === SyntaxKind.LessThanToken || - token() === SyntaxKind.GetKeyword || - token() === SyntaxKind.SetKeyword) { + if (token() === ts.SyntaxKind.OpenParenToken || + token() === ts.SyntaxKind.LessThanToken || + token() === ts.SyntaxKind.GetKeyword || + token() === ts.SyntaxKind.SetKeyword) { return true; } let idToken = false; // Eat up all modifiers, but hold on to the last one in case it is actually an identifier - while (isModifierKind(token())) { + while (ts.isModifierKind(token())) { idToken = true; nextToken(); } // Index signatures and computed property names are type members - if (token() === SyntaxKind.OpenBracketToken) { + if (token() === ts.SyntaxKind.OpenBracketToken) { return true; } // Try to get the first property-like token following all modifiers @@ -3558,32 +3470,32 @@ namespace ts { // If we were able to get any potential identifier, check that it is // the start of a member declaration if (idToken) { - return token() === SyntaxKind.OpenParenToken || - token() === SyntaxKind.LessThanToken || - token() === SyntaxKind.QuestionToken || - token() === SyntaxKind.ColonToken || - token() === SyntaxKind.CommaToken || + return token() === ts.SyntaxKind.OpenParenToken || + token() === ts.SyntaxKind.LessThanToken || + token() === ts.SyntaxKind.QuestionToken || + token() === ts.SyntaxKind.ColonToken || + token() === ts.SyntaxKind.CommaToken || canParseSemicolon(); } return false; } - function parseTypeMember(): TypeElement { - if (token() === SyntaxKind.OpenParenToken || token() === SyntaxKind.LessThanToken) { - return parseSignatureMember(SyntaxKind.CallSignature); + function parseTypeMember(): ts.TypeElement { + if (token() === ts.SyntaxKind.OpenParenToken || token() === ts.SyntaxKind.LessThanToken) { + return parseSignatureMember(ts.SyntaxKind.CallSignature); } - if (token() === SyntaxKind.NewKeyword && lookAhead(nextTokenIsOpenParenOrLessThan)) { - return parseSignatureMember(SyntaxKind.ConstructSignature); + if (token() === ts.SyntaxKind.NewKeyword && lookAhead(nextTokenIsOpenParenOrLessThan)) { + return parseSignatureMember(ts.SyntaxKind.ConstructSignature); } const pos = getNodePos(); const hasJSDoc = hasPrecedingJSDocComment(); const modifiers = parseModifiers(); - if (parseContextualModifier(SyntaxKind.GetKeyword)) { - return parseAccessorDeclaration(pos, hasJSDoc, /*decorators*/ undefined, modifiers, SyntaxKind.GetAccessor); + if (parseContextualModifier(ts.SyntaxKind.GetKeyword)) { + return parseAccessorDeclaration(pos, hasJSDoc, /*decorators*/ undefined, modifiers, ts.SyntaxKind.GetAccessor); } - if (parseContextualModifier(SyntaxKind.SetKeyword)) { - return parseAccessorDeclaration(pos, hasJSDoc, /*decorators*/ undefined, modifiers, SyntaxKind.SetAccessor); + if (parseContextualModifier(ts.SyntaxKind.SetKeyword)) { + return parseAccessorDeclaration(pos, hasJSDoc, /*decorators*/ undefined, modifiers, ts.SyntaxKind.SetAccessor); } if (isIndexSignature()) { @@ -3594,36 +3506,36 @@ namespace ts { function nextTokenIsOpenParenOrLessThan() { nextToken(); - return token() === SyntaxKind.OpenParenToken || token() === SyntaxKind.LessThanToken; + return token() === ts.SyntaxKind.OpenParenToken || token() === ts.SyntaxKind.LessThanToken; } function nextTokenIsDot() { - return nextToken() === SyntaxKind.DotToken; + return nextToken() === ts.SyntaxKind.DotToken; } function nextTokenIsOpenParenOrLessThanOrDot() { switch (nextToken()) { - case SyntaxKind.OpenParenToken: - case SyntaxKind.LessThanToken: - case SyntaxKind.DotToken: + case ts.SyntaxKind.OpenParenToken: + case ts.SyntaxKind.LessThanToken: + case ts.SyntaxKind.DotToken: return true; } return false; } - function parseTypeLiteral(): TypeLiteralNode { + function parseTypeLiteral(): ts.TypeLiteralNode { const pos = getNodePos(); return finishNode(factory.createTypeLiteralNode(parseObjectTypeMembers()), pos); } - function parseObjectTypeMembers(): NodeArray { - let members: NodeArray; - if (parseExpected(SyntaxKind.OpenBraceToken)) { + function parseObjectTypeMembers(): ts.NodeArray { + let members: ts.NodeArray; + if (parseExpected(ts.SyntaxKind.OpenBraceToken)) { members = parseList(ParsingContext.TypeMembers, parseTypeMember); - parseExpected(SyntaxKind.CloseBraceToken); + parseExpected(ts.SyntaxKind.CloseBraceToken); } else { - members = createMissingList(); + members = createMissingList(); } return members; @@ -3631,85 +3543,85 @@ namespace ts { function isStartOfMappedType() { nextToken(); - if (token() === SyntaxKind.PlusToken || token() === SyntaxKind.MinusToken) { - return nextToken() === SyntaxKind.ReadonlyKeyword; + if (token() === ts.SyntaxKind.PlusToken || token() === ts.SyntaxKind.MinusToken) { + return nextToken() === ts.SyntaxKind.ReadonlyKeyword; } - if (token() === SyntaxKind.ReadonlyKeyword) { + if (token() === ts.SyntaxKind.ReadonlyKeyword) { nextToken(); } - return token() === SyntaxKind.OpenBracketToken && nextTokenIsIdentifier() && nextToken() === SyntaxKind.InKeyword; + return token() === ts.SyntaxKind.OpenBracketToken && nextTokenIsIdentifier() && nextToken() === ts.SyntaxKind.InKeyword; } function parseMappedTypeParameter() { const pos = getNodePos(); const name = parseIdentifierName(); - parseExpected(SyntaxKind.InKeyword); + parseExpected(ts.SyntaxKind.InKeyword); const type = parseType(); return finishNode(factory.createTypeParameterDeclaration(/*modifiers*/ undefined, name, type, /*defaultType*/ undefined), pos); } function parseMappedType() { const pos = getNodePos(); - parseExpected(SyntaxKind.OpenBraceToken); - let readonlyToken: ReadonlyKeyword | PlusToken | MinusToken | undefined; - if (token() === SyntaxKind.ReadonlyKeyword || token() === SyntaxKind.PlusToken || token() === SyntaxKind.MinusToken) { - readonlyToken = parseTokenNode(); - if (readonlyToken.kind !== SyntaxKind.ReadonlyKeyword) { - parseExpected(SyntaxKind.ReadonlyKeyword); + parseExpected(ts.SyntaxKind.OpenBraceToken); + let readonlyToken: ts.ReadonlyKeyword | ts.PlusToken | ts.MinusToken | undefined; + if (token() === ts.SyntaxKind.ReadonlyKeyword || token() === ts.SyntaxKind.PlusToken || token() === ts.SyntaxKind.MinusToken) { + readonlyToken = parseTokenNode(); + if (readonlyToken.kind !== ts.SyntaxKind.ReadonlyKeyword) { + parseExpected(ts.SyntaxKind.ReadonlyKeyword); } } - parseExpected(SyntaxKind.OpenBracketToken); + parseExpected(ts.SyntaxKind.OpenBracketToken); const typeParameter = parseMappedTypeParameter(); - const nameType = parseOptional(SyntaxKind.AsKeyword) ? parseType() : undefined; - parseExpected(SyntaxKind.CloseBracketToken); - let questionToken: QuestionToken | PlusToken | MinusToken | undefined; - if (token() === SyntaxKind.QuestionToken || token() === SyntaxKind.PlusToken || token() === SyntaxKind.MinusToken) { - questionToken = parseTokenNode(); - if (questionToken.kind !== SyntaxKind.QuestionToken) { - parseExpected(SyntaxKind.QuestionToken); + const nameType = parseOptional(ts.SyntaxKind.AsKeyword) ? parseType() : undefined; + parseExpected(ts.SyntaxKind.CloseBracketToken); + let questionToken: ts.QuestionToken | ts.PlusToken | ts.MinusToken | undefined; + if (token() === ts.SyntaxKind.QuestionToken || token() === ts.SyntaxKind.PlusToken || token() === ts.SyntaxKind.MinusToken) { + questionToken = parseTokenNode(); + if (questionToken.kind !== ts.SyntaxKind.QuestionToken) { + parseExpected(ts.SyntaxKind.QuestionToken); } } const type = parseTypeAnnotation(); parseSemicolon(); const members = parseList(ParsingContext.TypeMembers, parseTypeMember); - parseExpected(SyntaxKind.CloseBraceToken); + parseExpected(ts.SyntaxKind.CloseBraceToken); return finishNode(factory.createMappedTypeNode(readonlyToken, typeParameter, nameType, questionToken, type, members), pos); } function parseTupleElementType() { const pos = getNodePos(); - if (parseOptional(SyntaxKind.DotDotDotToken)) { + if (parseOptional(ts.SyntaxKind.DotDotDotToken)) { return finishNode(factory.createRestTypeNode(parseType()), pos); } const type = parseType(); - if (isJSDocNullableType(type) && type.pos === type.type.pos) { + if (ts.isJSDocNullableType(type) && type.pos === type.type.pos) { const node = factory.createOptionalTypeNode(type.type); - setTextRange(node, type); - (node as Mutable).flags = type.flags; + ts.setTextRange(node, type); + (node as ts.Mutable).flags = type.flags; return node; } return type; } function isNextTokenColonOrQuestionColon() { - return nextToken() === SyntaxKind.ColonToken || (token() === SyntaxKind.QuestionToken && nextToken() === SyntaxKind.ColonToken); + return nextToken() === ts.SyntaxKind.ColonToken || (token() === ts.SyntaxKind.QuestionToken && nextToken() === ts.SyntaxKind.ColonToken); } function isTupleElementName() { - if (token() === SyntaxKind.DotDotDotToken) { - return tokenIsIdentifierOrKeyword(nextToken()) && isNextTokenColonOrQuestionColon(); + if (token() === ts.SyntaxKind.DotDotDotToken) { + return ts.tokenIsIdentifierOrKeyword(nextToken()) && isNextTokenColonOrQuestionColon(); } - return tokenIsIdentifierOrKeyword(token()) && isNextTokenColonOrQuestionColon(); + return ts.tokenIsIdentifierOrKeyword(token()) && isNextTokenColonOrQuestionColon(); } function parseTupleElementNameOrTupleElementType() { if (lookAhead(isTupleElementName)) { const pos = getNodePos(); const hasJSDoc = hasPrecedingJSDocComment(); - const dotDotDotToken = parseOptionalToken(SyntaxKind.DotDotDotToken); + const dotDotDotToken = parseOptionalToken(ts.SyntaxKind.DotDotDotToken); const name = parseIdentifierName(); - const questionToken = parseOptionalToken(SyntaxKind.QuestionToken); - parseExpected(SyntaxKind.ColonToken); + const questionToken = parseOptionalToken(ts.SyntaxKind.QuestionToken); + parseExpected(ts.SyntaxKind.ColonToken); const type = parseTupleElementType(); const node = factory.createNamedTupleMember(dotDotDotToken, name, questionToken, type); return withJSDoc(finishNode(node, pos), hasJSDoc); @@ -3717,181 +3629,173 @@ namespace ts { return parseTupleElementType(); } - function parseTupleType(): TupleTypeNode { + function parseTupleType(): ts.TupleTypeNode { const pos = getNodePos(); - return finishNode( - factory.createTupleTypeNode( - parseBracketedList(ParsingContext.TupleElementTypes, parseTupleElementNameOrTupleElementType, SyntaxKind.OpenBracketToken, SyntaxKind.CloseBracketToken) - ), - pos - ); + return finishNode(factory.createTupleTypeNode(parseBracketedList(ParsingContext.TupleElementTypes, parseTupleElementNameOrTupleElementType, ts.SyntaxKind.OpenBracketToken, ts.SyntaxKind.CloseBracketToken)), pos); } - function parseParenthesizedType(): TypeNode { + function parseParenthesizedType(): ts.TypeNode { const pos = getNodePos(); - parseExpected(SyntaxKind.OpenParenToken); + parseExpected(ts.SyntaxKind.OpenParenToken); const type = parseType(); - parseExpected(SyntaxKind.CloseParenToken); + parseExpected(ts.SyntaxKind.CloseParenToken); return finishNode(factory.createParenthesizedType(type), pos); } - function parseModifiersForConstructorType(): NodeArray | undefined { - let modifiers: NodeArray | undefined; - if (token() === SyntaxKind.AbstractKeyword) { + function parseModifiersForConstructorType(): ts.NodeArray | undefined { + let modifiers: ts.NodeArray | undefined; + if (token() === ts.SyntaxKind.AbstractKeyword) { const pos = getNodePos(); nextToken(); - const modifier = finishNode(factory.createToken(SyntaxKind.AbstractKeyword), pos); - modifiers = createNodeArray([modifier], pos); + const modifier = finishNode(factory.createToken(ts.SyntaxKind.AbstractKeyword), pos); + modifiers = createNodeArray([modifier], pos); } return modifiers; } - function parseFunctionOrConstructorType(): TypeNode { + function parseFunctionOrConstructorType(): ts.TypeNode { const pos = getNodePos(); const hasJSDoc = hasPrecedingJSDocComment(); const modifiers = parseModifiersForConstructorType(); - const isConstructorType = parseOptional(SyntaxKind.NewKeyword); + const isConstructorType = parseOptional(ts.SyntaxKind.NewKeyword); const typeParameters = parseTypeParameters(); const parameters = parseParameters(SignatureFlags.Type); - const type = parseReturnType(SyntaxKind.EqualsGreaterThanToken, /*isType*/ false); + const type = parseReturnType(ts.SyntaxKind.EqualsGreaterThanToken, /*isType*/ false); const node = isConstructorType ? factory.createConstructorTypeNode(modifiers, typeParameters, parameters, type) : factory.createFunctionTypeNode(typeParameters, parameters, type); - if (!isConstructorType) (node as Mutable).modifiers = modifiers; + if (!isConstructorType) + (node as ts.Mutable).modifiers = modifiers; return withJSDoc(finishNode(node, pos), hasJSDoc); } - function parseKeywordAndNoDot(): TypeNode | undefined { - const node = parseTokenNode(); - return token() === SyntaxKind.DotToken ? undefined : node; + function parseKeywordAndNoDot(): ts.TypeNode | undefined { + const node = parseTokenNode(); + return token() === ts.SyntaxKind.DotToken ? undefined : node; } - function parseLiteralTypeNode(negative?: boolean): LiteralTypeNode { + function parseLiteralTypeNode(negative?: boolean): ts.LiteralTypeNode { const pos = getNodePos(); if (negative) { nextToken(); } - let expression: BooleanLiteral | NullLiteral | LiteralExpression | PrefixUnaryExpression = - token() === SyntaxKind.TrueKeyword || token() === SyntaxKind.FalseKeyword || token() === SyntaxKind.NullKeyword ? - parseTokenNode() : - parseLiteralLikeNode(token()) as LiteralExpression; + let expression: ts.BooleanLiteral | ts.NullLiteral | ts.LiteralExpression | ts.PrefixUnaryExpression = token() === ts.SyntaxKind.TrueKeyword || token() === ts.SyntaxKind.FalseKeyword || token() === ts.SyntaxKind.NullKeyword ? + parseTokenNode() : + parseLiteralLikeNode(token()) as ts.LiteralExpression; if (negative) { - expression = finishNode(factory.createPrefixUnaryExpression(SyntaxKind.MinusToken, expression), pos); + expression = finishNode(factory.createPrefixUnaryExpression(ts.SyntaxKind.MinusToken, expression), pos); } return finishNode(factory.createLiteralTypeNode(expression), pos); } function isStartOfTypeOfImportType() { nextToken(); - return token() === SyntaxKind.ImportKeyword; + return token() === ts.SyntaxKind.ImportKeyword; } - function parseImportTypeAssertions(): ImportTypeAssertionContainer { + function parseImportTypeAssertions(): ts.ImportTypeAssertionContainer { const pos = getNodePos(); const openBracePosition = scanner.getTokenPos(); - parseExpected(SyntaxKind.OpenBraceToken); + parseExpected(ts.SyntaxKind.OpenBraceToken); const multiLine = scanner.hasPrecedingLineBreak(); - parseExpected(SyntaxKind.AssertKeyword); - parseExpected(SyntaxKind.ColonToken); + parseExpected(ts.SyntaxKind.AssertKeyword); + parseExpected(ts.SyntaxKind.ColonToken); const clause = parseAssertClause(/*skipAssertKeyword*/ true); - if (!parseExpected(SyntaxKind.CloseBraceToken)) { - const lastError = lastOrUndefined(parseDiagnostics); - if (lastError && lastError.code === Diagnostics._0_expected.code) { - addRelatedInfo( - lastError, - createDetachedDiagnostic(fileName, openBracePosition, 1, Diagnostics.The_parser_expected_to_find_a_1_to_match_the_0_token_here, "{", "}") - ); + if (!parseExpected(ts.SyntaxKind.CloseBraceToken)) { + const lastError = ts.lastOrUndefined(parseDiagnostics); + if (lastError && lastError.code === ts.Diagnostics._0_expected.code) { + ts.addRelatedInfo(lastError, ts.createDetachedDiagnostic(fileName, openBracePosition, 1, ts.Diagnostics.The_parser_expected_to_find_a_1_to_match_the_0_token_here, "{", "}")); } } return finishNode(factory.createImportTypeAssertionContainer(clause, multiLine), pos); } - function parseImportType(): ImportTypeNode { - sourceFlags |= NodeFlags.PossiblyContainsDynamicImport; + function parseImportType(): ts.ImportTypeNode { + sourceFlags |= ts.NodeFlags.PossiblyContainsDynamicImport; const pos = getNodePos(); - const isTypeOf = parseOptional(SyntaxKind.TypeOfKeyword); - parseExpected(SyntaxKind.ImportKeyword); - parseExpected(SyntaxKind.OpenParenToken); + const isTypeOf = parseOptional(ts.SyntaxKind.TypeOfKeyword); + parseExpected(ts.SyntaxKind.ImportKeyword); + parseExpected(ts.SyntaxKind.OpenParenToken); const type = parseType(); - let assertions: ImportTypeAssertionContainer | undefined; - if (parseOptional(SyntaxKind.CommaToken)) { + let assertions: ts.ImportTypeAssertionContainer | undefined; + if (parseOptional(ts.SyntaxKind.CommaToken)) { assertions = parseImportTypeAssertions(); } - parseExpected(SyntaxKind.CloseParenToken); - const qualifier = parseOptional(SyntaxKind.DotToken) ? parseEntityNameOfTypeReference() : undefined; + parseExpected(ts.SyntaxKind.CloseParenToken); + const qualifier = parseOptional(ts.SyntaxKind.DotToken) ? parseEntityNameOfTypeReference() : undefined; const typeArguments = parseTypeArgumentsOfTypeReference(); return finishNode(factory.createImportTypeNode(type, assertions, qualifier, typeArguments, isTypeOf), pos); } function nextTokenIsNumericOrBigIntLiteral() { nextToken(); - return token() === SyntaxKind.NumericLiteral || token() === SyntaxKind.BigIntLiteral; + return token() === ts.SyntaxKind.NumericLiteral || token() === ts.SyntaxKind.BigIntLiteral; } - function parseNonArrayType(): TypeNode { + function parseNonArrayType(): ts.TypeNode { switch (token()) { - case SyntaxKind.AnyKeyword: - case SyntaxKind.UnknownKeyword: - case SyntaxKind.StringKeyword: - case SyntaxKind.NumberKeyword: - case SyntaxKind.BigIntKeyword: - case SyntaxKind.SymbolKeyword: - case SyntaxKind.BooleanKeyword: - case SyntaxKind.UndefinedKeyword: - case SyntaxKind.NeverKeyword: - case SyntaxKind.ObjectKeyword: + case ts.SyntaxKind.AnyKeyword: + case ts.SyntaxKind.UnknownKeyword: + case ts.SyntaxKind.StringKeyword: + case ts.SyntaxKind.NumberKeyword: + case ts.SyntaxKind.BigIntKeyword: + case ts.SyntaxKind.SymbolKeyword: + case ts.SyntaxKind.BooleanKeyword: + case ts.SyntaxKind.UndefinedKeyword: + case ts.SyntaxKind.NeverKeyword: + case ts.SyntaxKind.ObjectKeyword: // If these are followed by a dot, then parse these out as a dotted type reference instead. return tryParse(parseKeywordAndNoDot) || parseTypeReference(); - case SyntaxKind.AsteriskEqualsToken: + case ts.SyntaxKind.AsteriskEqualsToken: // If there is '*=', treat it as * followed by postfix = scanner.reScanAsteriskEqualsToken(); // falls through - case SyntaxKind.AsteriskToken: + case ts.SyntaxKind.AsteriskToken: return parseJSDocAllType(); - case SyntaxKind.QuestionQuestionToken: + case ts.SyntaxKind.QuestionQuestionToken: // If there is '??', treat it as prefix-'?' in JSDoc type. scanner.reScanQuestionToken(); // falls through - case SyntaxKind.QuestionToken: + case ts.SyntaxKind.QuestionToken: return parseJSDocUnknownOrNullableType(); - case SyntaxKind.FunctionKeyword: + case ts.SyntaxKind.FunctionKeyword: return parseJSDocFunctionType(); - case SyntaxKind.ExclamationToken: + case ts.SyntaxKind.ExclamationToken: return parseJSDocNonNullableType(); - case SyntaxKind.NoSubstitutionTemplateLiteral: - case SyntaxKind.StringLiteral: - case SyntaxKind.NumericLiteral: - case SyntaxKind.BigIntLiteral: - case SyntaxKind.TrueKeyword: - case SyntaxKind.FalseKeyword: - case SyntaxKind.NullKeyword: + case ts.SyntaxKind.NoSubstitutionTemplateLiteral: + case ts.SyntaxKind.StringLiteral: + case ts.SyntaxKind.NumericLiteral: + case ts.SyntaxKind.BigIntLiteral: + case ts.SyntaxKind.TrueKeyword: + case ts.SyntaxKind.FalseKeyword: + case ts.SyntaxKind.NullKeyword: return parseLiteralTypeNode(); - case SyntaxKind.MinusToken: + case ts.SyntaxKind.MinusToken: return lookAhead(nextTokenIsNumericOrBigIntLiteral) ? parseLiteralTypeNode(/*negative*/ true) : parseTypeReference(); - case SyntaxKind.VoidKeyword: - return parseTokenNode(); - case SyntaxKind.ThisKeyword: { + case ts.SyntaxKind.VoidKeyword: + return parseTokenNode(); + case ts.SyntaxKind.ThisKeyword: { const thisKeyword = parseThisTypeNode(); - if (token() === SyntaxKind.IsKeyword && !scanner.hasPrecedingLineBreak()) { + if (token() === ts.SyntaxKind.IsKeyword && !scanner.hasPrecedingLineBreak()) { return parseThisTypePredicate(thisKeyword); } else { return thisKeyword; } } - case SyntaxKind.TypeOfKeyword: + case ts.SyntaxKind.TypeOfKeyword: return lookAhead(isStartOfTypeOfImportType) ? parseImportType() : parseTypeQuery(); - case SyntaxKind.OpenBraceToken: + case ts.SyntaxKind.OpenBraceToken: return lookAhead(isStartOfMappedType) ? parseMappedType() : parseTypeLiteral(); - case SyntaxKind.OpenBracketToken: + case ts.SyntaxKind.OpenBracketToken: return parseTupleType(); - case SyntaxKind.OpenParenToken: + case ts.SyntaxKind.OpenParenToken: return parseParenthesizedType(); - case SyntaxKind.ImportKeyword: + case ts.SyntaxKind.ImportKeyword: return parseImportType(); - case SyntaxKind.AssertsKeyword: + case ts.SyntaxKind.AssertsKeyword: return lookAhead(nextTokenIsIdentifierOrKeywordOnSameLine) ? parseAssertsTypePredicate() : parseTypeReference(); - case SyntaxKind.TemplateHead: + case ts.SyntaxKind.TemplateHead: return parseTemplateType(); default: return parseTypeReference(); @@ -3900,48 +3804,48 @@ namespace ts { function isStartOfType(inStartOfParameter?: boolean): boolean { switch (token()) { - case SyntaxKind.AnyKeyword: - case SyntaxKind.UnknownKeyword: - case SyntaxKind.StringKeyword: - case SyntaxKind.NumberKeyword: - case SyntaxKind.BigIntKeyword: - case SyntaxKind.BooleanKeyword: - case SyntaxKind.ReadonlyKeyword: - case SyntaxKind.SymbolKeyword: - case SyntaxKind.UniqueKeyword: - case SyntaxKind.VoidKeyword: - case SyntaxKind.UndefinedKeyword: - case SyntaxKind.NullKeyword: - case SyntaxKind.ThisKeyword: - case SyntaxKind.TypeOfKeyword: - case SyntaxKind.NeverKeyword: - case SyntaxKind.OpenBraceToken: - case SyntaxKind.OpenBracketToken: - case SyntaxKind.LessThanToken: - case SyntaxKind.BarToken: - case SyntaxKind.AmpersandToken: - case SyntaxKind.NewKeyword: - case SyntaxKind.StringLiteral: - case SyntaxKind.NumericLiteral: - case SyntaxKind.BigIntLiteral: - case SyntaxKind.TrueKeyword: - case SyntaxKind.FalseKeyword: - case SyntaxKind.ObjectKeyword: - case SyntaxKind.AsteriskToken: - case SyntaxKind.QuestionToken: - case SyntaxKind.ExclamationToken: - case SyntaxKind.DotDotDotToken: - case SyntaxKind.InferKeyword: - case SyntaxKind.ImportKeyword: - case SyntaxKind.AssertsKeyword: - case SyntaxKind.NoSubstitutionTemplateLiteral: - case SyntaxKind.TemplateHead: + case ts.SyntaxKind.AnyKeyword: + case ts.SyntaxKind.UnknownKeyword: + case ts.SyntaxKind.StringKeyword: + case ts.SyntaxKind.NumberKeyword: + case ts.SyntaxKind.BigIntKeyword: + case ts.SyntaxKind.BooleanKeyword: + case ts.SyntaxKind.ReadonlyKeyword: + case ts.SyntaxKind.SymbolKeyword: + case ts.SyntaxKind.UniqueKeyword: + case ts.SyntaxKind.VoidKeyword: + case ts.SyntaxKind.UndefinedKeyword: + case ts.SyntaxKind.NullKeyword: + case ts.SyntaxKind.ThisKeyword: + case ts.SyntaxKind.TypeOfKeyword: + case ts.SyntaxKind.NeverKeyword: + case ts.SyntaxKind.OpenBraceToken: + case ts.SyntaxKind.OpenBracketToken: + case ts.SyntaxKind.LessThanToken: + case ts.SyntaxKind.BarToken: + case ts.SyntaxKind.AmpersandToken: + case ts.SyntaxKind.NewKeyword: + case ts.SyntaxKind.StringLiteral: + case ts.SyntaxKind.NumericLiteral: + case ts.SyntaxKind.BigIntLiteral: + case ts.SyntaxKind.TrueKeyword: + case ts.SyntaxKind.FalseKeyword: + case ts.SyntaxKind.ObjectKeyword: + case ts.SyntaxKind.AsteriskToken: + case ts.SyntaxKind.QuestionToken: + case ts.SyntaxKind.ExclamationToken: + case ts.SyntaxKind.DotDotDotToken: + case ts.SyntaxKind.InferKeyword: + case ts.SyntaxKind.ImportKeyword: + case ts.SyntaxKind.AssertsKeyword: + case ts.SyntaxKind.NoSubstitutionTemplateLiteral: + case ts.SyntaxKind.TemplateHead: return true; - case SyntaxKind.FunctionKeyword: + case ts.SyntaxKind.FunctionKeyword: return !inStartOfParameter; - case SyntaxKind.MinusToken: + case ts.SyntaxKind.MinusToken: return !inStartOfParameter && lookAhead(nextTokenIsNumericOrBigIntLiteral); - case SyntaxKind.OpenParenToken: + case ts.SyntaxKind.OpenParenToken: // Only consider '(' the start of a type if followed by ')', '...', an identifier, a modifier, // or something that starts a type. We don't want to consider things like '(1)' a type. return !inStartOfParameter && lookAhead(isStartOfParenthesizedOrFunctionType); @@ -3952,19 +3856,19 @@ namespace ts { function isStartOfParenthesizedOrFunctionType() { nextToken(); - return token() === SyntaxKind.CloseParenToken || isStartOfParameter(/*isJSDocParameter*/ false) || isStartOfType(); + return token() === ts.SyntaxKind.CloseParenToken || isStartOfParameter(/*isJSDocParameter*/ false) || isStartOfType(); } - function parsePostfixTypeOrHigher(): TypeNode { + function parsePostfixTypeOrHigher(): ts.TypeNode { const pos = getNodePos(); let type = parseNonArrayType(); while (!scanner.hasPrecedingLineBreak()) { switch (token()) { - case SyntaxKind.ExclamationToken: + case ts.SyntaxKind.ExclamationToken: nextToken(); type = finishNode(factory.createJSDocNonNullableType(type, /*postfix*/ true), pos); break; - case SyntaxKind.QuestionToken: + case ts.SyntaxKind.QuestionToken: // If next token is start of a type we have a conditional type if (lookAhead(nextTokenIsStartOfType)) { return type; @@ -3972,15 +3876,15 @@ namespace ts { nextToken(); type = finishNode(factory.createJSDocNullableType(type, /*postfix*/ true), pos); break; - case SyntaxKind.OpenBracketToken: - parseExpected(SyntaxKind.OpenBracketToken); + case ts.SyntaxKind.OpenBracketToken: + parseExpected(ts.SyntaxKind.OpenBracketToken); if (isStartOfType()) { const indexType = parseType(); - parseExpected(SyntaxKind.CloseBracketToken); + parseExpected(ts.SyntaxKind.CloseBracketToken); type = finishNode(factory.createIndexedAccessTypeNode(type, indexType), pos); } else { - parseExpected(SyntaxKind.CloseBracketToken); + parseExpected(ts.SyntaxKind.CloseBracketToken); type = finishNode(factory.createArrayTypeNode(type), pos); } break; @@ -3991,22 +3895,22 @@ namespace ts { return type; } - function parseTypeOperator(operator: SyntaxKind.KeyOfKeyword | SyntaxKind.UniqueKeyword | SyntaxKind.ReadonlyKeyword) { + function parseTypeOperator(operator: ts.SyntaxKind.KeyOfKeyword | ts.SyntaxKind.UniqueKeyword | ts.SyntaxKind.ReadonlyKeyword) { const pos = getNodePos(); parseExpected(operator); return finishNode(factory.createTypeOperatorNode(operator, parseTypeOperatorOrHigher()), pos); } function tryParseConstraintOfInferType() { - if (parseOptional(SyntaxKind.ExtendsKeyword)) { + if (parseOptional(ts.SyntaxKind.ExtendsKeyword)) { const constraint = disallowConditionalTypesAnd(parseType); - if (inDisallowConditionalTypesContext() || token() !== SyntaxKind.QuestionToken) { + if (inDisallowConditionalTypesContext() || token() !== ts.SyntaxKind.QuestionToken) { return constraint; } } } - function parseTypeParameterOfInferType(): TypeParameterDeclaration { + function parseTypeParameterOfInferType(): ts.TypeParameterDeclaration { const pos = getNodePos(); const name = parseIdentifier(); const constraint = tryParse(tryParseConstraintOfInferType); @@ -4014,43 +3918,41 @@ namespace ts { return finishNode(node, pos); } - function parseInferType(): InferTypeNode { + function parseInferType(): ts.InferTypeNode { const pos = getNodePos(); - parseExpected(SyntaxKind.InferKeyword); + parseExpected(ts.SyntaxKind.InferKeyword); return finishNode(factory.createInferTypeNode(parseTypeParameterOfInferType()), pos); } - function parseTypeOperatorOrHigher(): TypeNode { + function parseTypeOperatorOrHigher(): ts.TypeNode { const operator = token(); switch (operator) { - case SyntaxKind.KeyOfKeyword: - case SyntaxKind.UniqueKeyword: - case SyntaxKind.ReadonlyKeyword: + case ts.SyntaxKind.KeyOfKeyword: + case ts.SyntaxKind.UniqueKeyword: + case ts.SyntaxKind.ReadonlyKeyword: return parseTypeOperator(operator); - case SyntaxKind.InferKeyword: + case ts.SyntaxKind.InferKeyword: return parseInferType(); } return allowConditionalTypesAnd(parsePostfixTypeOrHigher); } - function parseFunctionOrConstructorTypeToError( - isInUnionType: boolean - ): TypeNode | undefined { + function parseFunctionOrConstructorTypeToError(isInUnionType: boolean): ts.TypeNode | undefined { // the function type and constructor type shorthand notation // are not allowed directly in unions and intersections, but we'll // try to parse them gracefully and issue a helpful message. if (isStartOfFunctionTypeOrConstructorType()) { const type = parseFunctionOrConstructorType(); - let diagnostic: DiagnosticMessage; - if (isFunctionTypeNode(type)) { + let diagnostic: ts.DiagnosticMessage; + if (ts.isFunctionTypeNode(type)) { diagnostic = isInUnionType - ? Diagnostics.Function_type_notation_must_be_parenthesized_when_used_in_a_union_type - : Diagnostics.Function_type_notation_must_be_parenthesized_when_used_in_an_intersection_type; + ? ts.Diagnostics.Function_type_notation_must_be_parenthesized_when_used_in_a_union_type + : ts.Diagnostics.Function_type_notation_must_be_parenthesized_when_used_in_an_intersection_type; } else { diagnostic = isInUnionType - ? Diagnostics.Constructor_type_notation_must_be_parenthesized_when_used_in_a_union_type - : Diagnostics.Constructor_type_notation_must_be_parenthesized_when_used_in_an_intersection_type; + ? ts.Diagnostics.Constructor_type_notation_must_be_parenthesized_when_used_in_a_union_type + : ts.Diagnostics.Constructor_type_notation_must_be_parenthesized_when_used_in_an_intersection_type; } parseErrorAtRange(type, diagnostic); @@ -4059,13 +3961,9 @@ namespace ts { return undefined; } - function parseUnionOrIntersectionType( - operator: SyntaxKind.BarToken | SyntaxKind.AmpersandToken, - parseConstituentType: () => TypeNode, - createTypeNode: (types: NodeArray) => UnionOrIntersectionTypeNode - ): TypeNode { + function parseUnionOrIntersectionType(operator: ts.SyntaxKind.BarToken | ts.SyntaxKind.AmpersandToken, parseConstituentType: () => ts.TypeNode, createTypeNode: (types: ts.NodeArray) => ts.UnionOrIntersectionTypeNode): ts.TypeNode { const pos = getNodePos(); - const isUnionType = operator === SyntaxKind.BarToken; + const isUnionType = operator === ts.SyntaxKind.BarToken; const hasLeadingOperator = parseOptional(operator); let type = hasLeadingOperator && parseFunctionOrConstructorTypeToError(isUnionType) || parseConstituentType(); @@ -4079,40 +3977,40 @@ namespace ts { return type; } - function parseIntersectionTypeOrHigher(): TypeNode { - return parseUnionOrIntersectionType(SyntaxKind.AmpersandToken, parseTypeOperatorOrHigher, factory.createIntersectionTypeNode); + function parseIntersectionTypeOrHigher(): ts.TypeNode { + return parseUnionOrIntersectionType(ts.SyntaxKind.AmpersandToken, parseTypeOperatorOrHigher, factory.createIntersectionTypeNode); } - function parseUnionTypeOrHigher(): TypeNode { - return parseUnionOrIntersectionType(SyntaxKind.BarToken, parseIntersectionTypeOrHigher, factory.createUnionTypeNode); + function parseUnionTypeOrHigher(): ts.TypeNode { + return parseUnionOrIntersectionType(ts.SyntaxKind.BarToken, parseIntersectionTypeOrHigher, factory.createUnionTypeNode); } function nextTokenIsNewKeyword(): boolean { nextToken(); - return token() === SyntaxKind.NewKeyword; + return token() === ts.SyntaxKind.NewKeyword; } function isStartOfFunctionTypeOrConstructorType(): boolean { - if (token() === SyntaxKind.LessThanToken) { + if (token() === ts.SyntaxKind.LessThanToken) { return true; } - if (token() === SyntaxKind.OpenParenToken && lookAhead(isUnambiguouslyStartOfFunctionType)) { + if (token() === ts.SyntaxKind.OpenParenToken && lookAhead(isUnambiguouslyStartOfFunctionType)) { return true; } - return token() === SyntaxKind.NewKeyword || - token() === SyntaxKind.AbstractKeyword && lookAhead(nextTokenIsNewKeyword); + return token() === ts.SyntaxKind.NewKeyword || + token() === ts.SyntaxKind.AbstractKeyword && lookAhead(nextTokenIsNewKeyword); } function skipParameterStart(): boolean { - if (isModifierKind(token())) { + if (ts.isModifierKind(token())) { // Skip modifiers parseModifiers(); } - if (isIdentifier() || token() === SyntaxKind.ThisKeyword) { + if (isIdentifier() || token() === ts.SyntaxKind.ThisKeyword) { nextToken(); return true; } - if (token() === SyntaxKind.OpenBracketToken || token() === SyntaxKind.OpenBraceToken) { + if (token() === ts.SyntaxKind.OpenBracketToken || token() === ts.SyntaxKind.OpenBraceToken) { // Return true if we can parse an array or object binding pattern with no errors const previousErrorCount = parseDiagnostics.length; parseIdentifierOrPattern(); @@ -4123,7 +4021,7 @@ namespace ts { function isUnambiguouslyStartOfFunctionType() { nextToken(); - if (token() === SyntaxKind.CloseParenToken || token() === SyntaxKind.DotDotDotToken) { + if (token() === ts.SyntaxKind.CloseParenToken || token() === ts.SyntaxKind.DotDotDotToken) { // ( ) // ( ... return true; @@ -4131,17 +4029,17 @@ namespace ts { if (skipParameterStart()) { // We successfully skipped modifiers (if any) and an identifier or binding pattern, // now see if we have something that indicates a parameter declaration - if (token() === SyntaxKind.ColonToken || token() === SyntaxKind.CommaToken || - token() === SyntaxKind.QuestionToken || token() === SyntaxKind.EqualsToken) { + if (token() === ts.SyntaxKind.ColonToken || token() === ts.SyntaxKind.CommaToken || + token() === ts.SyntaxKind.QuestionToken || token() === ts.SyntaxKind.EqualsToken) { // ( xxx : // ( xxx , // ( xxx ? // ( xxx = return true; } - if (token() === SyntaxKind.CloseParenToken) { + if (token() === ts.SyntaxKind.CloseParenToken) { nextToken(); - if (token() === SyntaxKind.EqualsGreaterThanToken) { + if (token() === ts.SyntaxKind.EqualsGreaterThanToken) { // ( xxx ) => return true; } @@ -4150,7 +4048,7 @@ namespace ts { return false; } - function parseTypeOrTypePredicate(): TypeNode { + function parseTypeOrTypePredicate(): ts.TypeNode { const pos = getNodePos(); const typePredicateVariable = isIdentifier() && tryParse(parseTypePredicatePrefix); const type = parseType(); @@ -4164,23 +4062,23 @@ namespace ts { function parseTypePredicatePrefix() { const id = parseIdentifier(); - if (token() === SyntaxKind.IsKeyword && !scanner.hasPrecedingLineBreak()) { + if (token() === ts.SyntaxKind.IsKeyword && !scanner.hasPrecedingLineBreak()) { nextToken(); return id; } } - function parseAssertsTypePredicate(): TypeNode { + function parseAssertsTypePredicate(): ts.TypeNode { const pos = getNodePos(); - const assertsModifier = parseExpectedToken(SyntaxKind.AssertsKeyword); - const parameterName = token() === SyntaxKind.ThisKeyword ? parseThisTypeNode() : parseIdentifier(); - const type = parseOptional(SyntaxKind.IsKeyword) ? parseType() : undefined; + const assertsModifier = parseExpectedToken(ts.SyntaxKind.AssertsKeyword); + const parameterName = token() === ts.SyntaxKind.ThisKeyword ? parseThisTypeNode() : parseIdentifier(); + const type = parseOptional(ts.SyntaxKind.IsKeyword) ? parseType() : undefined; return finishNode(factory.createTypePredicateNode(assertsModifier, parameterName, type), pos); } - function parseType(): TypeNode { - if (contextFlags & NodeFlags.TypeExcludesFlags) { - return doOutsideOfContext(NodeFlags.TypeExcludesFlags, parseType); + function parseType(): ts.TypeNode { + if (contextFlags & ts.NodeFlags.TypeExcludesFlags) { + return doOutsideOfContext(ts.NodeFlags.TypeExcludesFlags, parseType); } if (isStartOfFunctionTypeOrConstructorType()) { @@ -4188,46 +4086,46 @@ namespace ts { } const pos = getNodePos(); const type = parseUnionTypeOrHigher(); - if (!inDisallowConditionalTypesContext() && !scanner.hasPrecedingLineBreak() && parseOptional(SyntaxKind.ExtendsKeyword)) { + if (!inDisallowConditionalTypesContext() && !scanner.hasPrecedingLineBreak() && parseOptional(ts.SyntaxKind.ExtendsKeyword)) { // The type following 'extends' is not permitted to be another conditional type const extendsType = disallowConditionalTypesAnd(parseType); - parseExpected(SyntaxKind.QuestionToken); + parseExpected(ts.SyntaxKind.QuestionToken); const trueType = allowConditionalTypesAnd(parseType); - parseExpected(SyntaxKind.ColonToken); + parseExpected(ts.SyntaxKind.ColonToken); const falseType = allowConditionalTypesAnd(parseType); return finishNode(factory.createConditionalTypeNode(type, extendsType, trueType, falseType), pos); } return type; } - function parseTypeAnnotation(): TypeNode | undefined { - return parseOptional(SyntaxKind.ColonToken) ? parseType() : undefined; + function parseTypeAnnotation(): ts.TypeNode | undefined { + return parseOptional(ts.SyntaxKind.ColonToken) ? parseType() : undefined; } // EXPRESSIONS function isStartOfLeftHandSideExpression(): boolean { switch (token()) { - case SyntaxKind.ThisKeyword: - case SyntaxKind.SuperKeyword: - case SyntaxKind.NullKeyword: - case SyntaxKind.TrueKeyword: - case SyntaxKind.FalseKeyword: - case SyntaxKind.NumericLiteral: - case SyntaxKind.BigIntLiteral: - case SyntaxKind.StringLiteral: - case SyntaxKind.NoSubstitutionTemplateLiteral: - case SyntaxKind.TemplateHead: - case SyntaxKind.OpenParenToken: - case SyntaxKind.OpenBracketToken: - case SyntaxKind.OpenBraceToken: - case SyntaxKind.FunctionKeyword: - case SyntaxKind.ClassKeyword: - case SyntaxKind.NewKeyword: - case SyntaxKind.SlashToken: - case SyntaxKind.SlashEqualsToken: - case SyntaxKind.Identifier: + case ts.SyntaxKind.ThisKeyword: + case ts.SyntaxKind.SuperKeyword: + case ts.SyntaxKind.NullKeyword: + case ts.SyntaxKind.TrueKeyword: + case ts.SyntaxKind.FalseKeyword: + case ts.SyntaxKind.NumericLiteral: + case ts.SyntaxKind.BigIntLiteral: + case ts.SyntaxKind.StringLiteral: + case ts.SyntaxKind.NoSubstitutionTemplateLiteral: + case ts.SyntaxKind.TemplateHead: + case ts.SyntaxKind.OpenParenToken: + case ts.SyntaxKind.OpenBracketToken: + case ts.SyntaxKind.OpenBraceToken: + case ts.SyntaxKind.FunctionKeyword: + case ts.SyntaxKind.ClassKeyword: + case ts.SyntaxKind.NewKeyword: + case ts.SyntaxKind.SlashToken: + case ts.SyntaxKind.SlashEqualsToken: + case ts.SyntaxKind.Identifier: return true; - case SyntaxKind.ImportKeyword: + case ts.SyntaxKind.ImportKeyword: return lookAhead(nextTokenIsOpenParenOrLessThanOrDot); default: return isIdentifier(); @@ -4240,19 +4138,19 @@ namespace ts { } switch (token()) { - case SyntaxKind.PlusToken: - case SyntaxKind.MinusToken: - case SyntaxKind.TildeToken: - case SyntaxKind.ExclamationToken: - case SyntaxKind.DeleteKeyword: - case SyntaxKind.TypeOfKeyword: - case SyntaxKind.VoidKeyword: - case SyntaxKind.PlusPlusToken: - case SyntaxKind.MinusMinusToken: - case SyntaxKind.LessThanToken: - case SyntaxKind.AwaitKeyword: - case SyntaxKind.YieldKeyword: - case SyntaxKind.PrivateIdentifier: + case ts.SyntaxKind.PlusToken: + case ts.SyntaxKind.MinusToken: + case ts.SyntaxKind.TildeToken: + case ts.SyntaxKind.ExclamationToken: + case ts.SyntaxKind.DeleteKeyword: + case ts.SyntaxKind.TypeOfKeyword: + case ts.SyntaxKind.VoidKeyword: + case ts.SyntaxKind.PlusPlusToken: + case ts.SyntaxKind.MinusMinusToken: + case ts.SyntaxKind.LessThanToken: + case ts.SyntaxKind.AwaitKeyword: + case ts.SyntaxKind.YieldKeyword: + case ts.SyntaxKind.PrivateIdentifier: // Yield/await always starts an expression. Either it is an identifier (in which case // it is definitely an expression). Or it's a keyword (either because we're in // a generator or async function, or in strict mode (or both)) and it started a yield or await expression. @@ -4272,14 +4170,14 @@ namespace ts { function isStartOfExpressionStatement(): boolean { // As per the grammar, none of '{' or 'function' or 'class' can start an expression statement. - return token() !== SyntaxKind.OpenBraceToken && - token() !== SyntaxKind.FunctionKeyword && - token() !== SyntaxKind.ClassKeyword && - token() !== SyntaxKind.AtToken && + return token() !== ts.SyntaxKind.OpenBraceToken && + token() !== ts.SyntaxKind.FunctionKeyword && + token() !== ts.SyntaxKind.ClassKeyword && + token() !== ts.SyntaxKind.AtToken && isStartOfExpression(); } - function parseExpression(): Expression { + function parseExpression(): ts.Expression { // Expression[in]: // AssignmentExpression[in] // Expression[in] , AssignmentExpression[in] @@ -4292,8 +4190,8 @@ namespace ts { const pos = getNodePos(); let expr = parseAssignmentExpressionOrHigher(); - let operatorToken: BinaryOperatorToken; - while ((operatorToken = parseOptionalToken(SyntaxKind.CommaToken))) { + let operatorToken: ts.BinaryOperatorToken; + while ((operatorToken = parseOptionalToken(ts.SyntaxKind.CommaToken))) { expr = makeBinaryExpression(expr, operatorToken, parseAssignmentExpressionOrHigher(), pos); } @@ -4303,11 +4201,11 @@ namespace ts { return expr; } - function parseInitializer(): Expression | undefined { - return parseOptional(SyntaxKind.EqualsToken) ? parseAssignmentExpressionOrHigher() : undefined; + function parseInitializer(): ts.Expression | undefined { + return parseOptional(ts.SyntaxKind.EqualsToken) ? parseAssignmentExpressionOrHigher() : undefined; } - function parseAssignmentExpressionOrHigher(): Expression { + function parseAssignmentExpressionOrHigher(): ts.Expression { // AssignmentExpression[in,yield]: // 1) ConditionalExpression[?in,?yield] // 2) LeftHandSideExpression = AssignmentExpression[?in,?yield] @@ -4350,13 +4248,13 @@ namespace ts { // binary expression here, so we pass in the 'lowest' precedence here so that it matches // and consumes anything. const pos = getNodePos(); - const expr = parseBinaryExpressionOrHigher(OperatorPrecedence.Lowest); + const expr = parseBinaryExpressionOrHigher(ts.OperatorPrecedence.Lowest); // To avoid a look-ahead, we did not handle the case of an arrow function with a single un-parenthesized // parameter ('x => ...') above. We handle it here by checking if the parsed expression was a single // identifier and the current token is an arrow. - if (expr.kind === SyntaxKind.Identifier && token() === SyntaxKind.EqualsGreaterThanToken) { - return parseSimpleArrowFunctionExpression(pos, expr as Identifier, /*asyncModifier*/ undefined); + if (expr.kind === ts.SyntaxKind.Identifier && token() === ts.SyntaxKind.EqualsGreaterThanToken) { + return parseSimpleArrowFunctionExpression(pos, expr as ts.Identifier, /*asyncModifier*/ undefined); } // Now see if we might be in cases '2' or '3'. @@ -4365,7 +4263,7 @@ namespace ts { // // Note: we call reScanGreaterToken so that we get an appropriately merged token // for cases like `> > =` becoming `>>=` - if (isLeftHandSideExpression(expr) && isAssignmentOperator(reScanGreaterToken())) { + if (ts.isLeftHandSideExpression(expr) && ts.isAssignmentOperator(reScanGreaterToken())) { return makeBinaryExpression(expr, parseTokenNode(), parseAssignmentExpressionOrHigher(), pos); } @@ -4374,7 +4272,7 @@ namespace ts { } function isYieldExpression(): boolean { - if (token() === SyntaxKind.YieldKeyword) { + if (token() === ts.SyntaxKind.YieldKeyword) { // If we have a 'yield' keyword, and this is a context where yield expressions are // allowed, then definitely parse out a yield expression. if (inYieldContext()) { @@ -4406,7 +4304,7 @@ namespace ts { return !scanner.hasPrecedingLineBreak() && isIdentifier(); } - function parseYieldExpression(): YieldExpression { + function parseYieldExpression(): ts.YieldExpression { const pos = getNodePos(); // YieldExpression[In] : @@ -4416,14 +4314,8 @@ namespace ts { nextToken(); if (!scanner.hasPrecedingLineBreak() && - (token() === SyntaxKind.AsteriskToken || isStartOfExpression())) { - return finishNode( - factory.createYieldExpression( - parseOptionalToken(SyntaxKind.AsteriskToken), - parseAssignmentExpressionOrHigher() - ), - pos - ); + (token() === ts.SyntaxKind.AsteriskToken || isStartOfExpression())) { + return finishNode(factory.createYieldExpression(parseOptionalToken(ts.SyntaxKind.AsteriskToken), parseAssignmentExpressionOrHigher()), pos); } else { // if the next token is not on the same line as yield. or we don't have an '*' or @@ -4432,27 +4324,25 @@ namespace ts { } } - function parseSimpleArrowFunctionExpression(pos: number, identifier: Identifier, asyncModifier?: NodeArray | undefined): ArrowFunction { - Debug.assert(token() === SyntaxKind.EqualsGreaterThanToken, "parseSimpleArrowFunctionExpression should only have been called if we had a =>"); + function parseSimpleArrowFunctionExpression(pos: number, identifier: ts.Identifier, asyncModifier?: ts.NodeArray | undefined): ts.ArrowFunction { + ts.Debug.assert(token() === ts.SyntaxKind.EqualsGreaterThanToken, "parseSimpleArrowFunctionExpression should only have been called if we had a =>"); const parameter = factory.createParameterDeclaration( /*decorators*/ undefined, /*modifiers*/ undefined, - /*dotDotDotToken*/ undefined, - identifier, + /*dotDotDotToken*/ undefined, identifier, /*questionToken*/ undefined, /*type*/ undefined, - /*initializer*/ undefined - ); + /*initializer*/ undefined); finishNode(parameter, identifier.pos); - const parameters = createNodeArray([parameter], parameter.pos, parameter.end); - const equalsGreaterThanToken = parseExpectedToken(SyntaxKind.EqualsGreaterThanToken); + const parameters = createNodeArray([parameter], parameter.pos, parameter.end); + const equalsGreaterThanToken = parseExpectedToken(ts.SyntaxKind.EqualsGreaterThanToken); const body = parseArrowFunctionExpressionBody(/*isAsync*/ !!asyncModifier); const node = factory.createArrowFunction(asyncModifier, /*typeParameters*/ undefined, parameters, /*type*/ undefined, equalsGreaterThanToken, body); return addJSDocComment(finishNode(node, pos)); } - function tryParseParenthesizedArrowFunctionExpression(): Expression | undefined { + function tryParseParenthesizedArrowFunctionExpression(): ts.Expression | undefined { const triState = isParenthesizedArrowFunctionExpression(); if (triState === Tristate.False) { // It's definitely not a parenthesized arrow function expression. @@ -4473,11 +4363,11 @@ namespace ts { // Unknown -> There *might* be a parenthesized arrow function here. // Speculatively look ahead to be sure, and rollback if not. function isParenthesizedArrowFunctionExpression(): Tristate { - if (token() === SyntaxKind.OpenParenToken || token() === SyntaxKind.LessThanToken || token() === SyntaxKind.AsyncKeyword) { + if (token() === ts.SyntaxKind.OpenParenToken || token() === ts.SyntaxKind.LessThanToken || token() === ts.SyntaxKind.AsyncKeyword) { return lookAhead(isParenthesizedArrowFunctionExpressionWorker); } - if (token() === SyntaxKind.EqualsGreaterThanToken) { + if (token() === ts.SyntaxKind.EqualsGreaterThanToken) { // ERROR RECOVERY TWEAK: // If we see a standalone => try to parse it as an arrow function expression as that's // likely what the user intended to write. @@ -4488,12 +4378,12 @@ namespace ts { } function isParenthesizedArrowFunctionExpressionWorker() { - if (token() === SyntaxKind.AsyncKeyword) { + if (token() === ts.SyntaxKind.AsyncKeyword) { nextToken(); if (scanner.hasPrecedingLineBreak()) { return Tristate.False; } - if (token() !== SyntaxKind.OpenParenToken && token() !== SyntaxKind.LessThanToken) { + if (token() !== ts.SyntaxKind.OpenParenToken && token() !== ts.SyntaxKind.LessThanToken) { return Tristate.False; } } @@ -4501,17 +4391,17 @@ namespace ts { const first = token(); const second = nextToken(); - if (first === SyntaxKind.OpenParenToken) { - if (second === SyntaxKind.CloseParenToken) { + if (first === ts.SyntaxKind.OpenParenToken) { + if (second === ts.SyntaxKind.CloseParenToken) { // Simple cases: "() =>", "(): ", and "() {". // This is an arrow function with no parameters. // The last one is not actually an arrow function, // but this is probably what the user intended. const third = nextToken(); switch (third) { - case SyntaxKind.EqualsGreaterThanToken: - case SyntaxKind.ColonToken: - case SyntaxKind.OpenBraceToken: + case ts.SyntaxKind.EqualsGreaterThanToken: + case ts.SyntaxKind.ColonToken: + case ts.SyntaxKind.OpenBraceToken: return Tristate.True; default: return Tristate.False; @@ -4524,21 +4414,21 @@ namespace ts { // ({ x }) => { } // ([ x ]) // ({ x }) - if (second === SyntaxKind.OpenBracketToken || second === SyntaxKind.OpenBraceToken) { + if (second === ts.SyntaxKind.OpenBracketToken || second === ts.SyntaxKind.OpenBraceToken) { return Tristate.Unknown; } // Simple case: "(..." // This is an arrow function with a rest parameter. - if (second === SyntaxKind.DotDotDotToken) { + if (second === ts.SyntaxKind.DotDotDotToken) { return Tristate.True; } // Check for "(xxx yyy", where xxx is a modifier and yyy is an identifier. This // isn't actually allowed, but we want to treat it as a lambda so we can provide // a good error message. - if (isModifierKind(second) && second !== SyntaxKind.AsyncKeyword && lookAhead(nextTokenIsIdentifier)) { - if (nextToken() === SyntaxKind.AsKeyword) { + if (ts.isModifierKind(second) && second !== ts.SyntaxKind.AsyncKeyword && lookAhead(nextTokenIsIdentifier)) { + if (nextToken() === ts.SyntaxKind.AsKeyword) { // https://github.com/microsoft/TypeScript/issues/44466 return Tristate.False; } @@ -4548,26 +4438,26 @@ namespace ts { // If we had "(" followed by something that's not an identifier, // then this definitely doesn't look like a lambda. "this" is not // valid, but we want to parse it and then give a semantic error. - if (!isIdentifier() && second !== SyntaxKind.ThisKeyword) { + if (!isIdentifier() && second !== ts.SyntaxKind.ThisKeyword) { return Tristate.False; } switch (nextToken()) { - case SyntaxKind.ColonToken: + case ts.SyntaxKind.ColonToken: // If we have something like "(a:", then we must have a // type-annotated parameter in an arrow function expression. return Tristate.True; - case SyntaxKind.QuestionToken: + case ts.SyntaxKind.QuestionToken: nextToken(); // If we have "(a?:" or "(a?," or "(a?=" or "(a?)" then it is definitely a lambda. - if (token() === SyntaxKind.ColonToken || token() === SyntaxKind.CommaToken || token() === SyntaxKind.EqualsToken || token() === SyntaxKind.CloseParenToken) { + if (token() === ts.SyntaxKind.ColonToken || token() === ts.SyntaxKind.CommaToken || token() === ts.SyntaxKind.EqualsToken || token() === ts.SyntaxKind.CloseParenToken) { return Tristate.True; } // Otherwise it is definitely not a lambda. return Tristate.False; - case SyntaxKind.CommaToken: - case SyntaxKind.EqualsToken: - case SyntaxKind.CloseParenToken: + case ts.SyntaxKind.CommaToken: + case ts.SyntaxKind.EqualsToken: + case ts.SyntaxKind.CloseParenToken: // If we have "(a," or "(a=" or "(a)" this *could* be an arrow function return Tristate.Unknown; } @@ -4575,7 +4465,7 @@ namespace ts { return Tristate.False; } else { - Debug.assert(first === SyntaxKind.LessThanToken); + ts.Debug.assert(first === ts.SyntaxKind.LessThanToken); // If we have "<" not followed by an identifier, // then this definitely is not an arrow function. @@ -4584,20 +4474,20 @@ namespace ts { } // JSX overrides - if (languageVariant === LanguageVariant.JSX) { + if (languageVariant === ts.LanguageVariant.JSX) { const isArrowFunctionInJsx = lookAhead(() => { const third = nextToken(); - if (third === SyntaxKind.ExtendsKeyword) { + if (third === ts.SyntaxKind.ExtendsKeyword) { const fourth = nextToken(); switch (fourth) { - case SyntaxKind.EqualsToken: - case SyntaxKind.GreaterThanToken: + case ts.SyntaxKind.EqualsToken: + case ts.SyntaxKind.GreaterThanToken: return false; default: return true; } } - else if (third === SyntaxKind.CommaToken || third === SyntaxKind.EqualsToken) { + else if (third === ts.SyntaxKind.CommaToken || third === ts.SyntaxKind.EqualsToken) { return true; } return false; @@ -4615,7 +4505,7 @@ namespace ts { } } - function parsePossibleParenthesizedArrowFunctionExpression(): ArrowFunction | undefined { + function parsePossibleParenthesizedArrowFunctionExpression(): ts.ArrowFunction | undefined { const tokenPos = scanner.getTokenPos(); if (notParenthesizedArrow?.has(tokenPos)) { return undefined; @@ -4623,20 +4513,20 @@ namespace ts { const result = parseParenthesizedArrowFunctionExpression(/*allowAmbiguity*/ false); if (!result) { - (notParenthesizedArrow || (notParenthesizedArrow = new Set())).add(tokenPos); + (notParenthesizedArrow || (notParenthesizedArrow = new ts.Set())).add(tokenPos); } return result; } - function tryParseAsyncSimpleArrowFunctionExpression(): ArrowFunction | undefined { + function tryParseAsyncSimpleArrowFunctionExpression(): ts.ArrowFunction | undefined { // We do a check here so that we won't be doing unnecessarily call to "lookAhead" - if (token() === SyntaxKind.AsyncKeyword) { + if (token() === ts.SyntaxKind.AsyncKeyword) { if (lookAhead(isUnParenthesizedAsyncArrowFunctionWorker) === Tristate.True) { const pos = getNodePos(); const asyncModifier = parseModifiersForArrowFunction(); - const expr = parseBinaryExpressionOrHigher(OperatorPrecedence.Lowest); - return parseSimpleArrowFunctionExpression(pos, expr as Identifier, asyncModifier); + const expr = parseBinaryExpressionOrHigher(ts.OperatorPrecedence.Lowest); + return parseSimpleArrowFunctionExpression(pos, expr as ts.Identifier, asyncModifier); } } return undefined; @@ -4646,16 +4536,16 @@ namespace ts { // AsyncArrowFunctionExpression: // 1) async[no LineTerminator here]AsyncArrowBindingIdentifier[?Yield][no LineTerminator here]=>AsyncConciseBody[?In] // 2) CoverCallExpressionAndAsyncArrowHead[?Yield, ?Await][no LineTerminator here]=>AsyncConciseBody[?In] - if (token() === SyntaxKind.AsyncKeyword) { + if (token() === ts.SyntaxKind.AsyncKeyword) { nextToken(); // If the "async" is followed by "=>" token then it is not a beginning of an async arrow-function // but instead a simple arrow-function which will be parsed inside "parseAssignmentExpressionOrHigher" - if (scanner.hasPrecedingLineBreak() || token() === SyntaxKind.EqualsGreaterThanToken) { + if (scanner.hasPrecedingLineBreak() || token() === ts.SyntaxKind.EqualsGreaterThanToken) { return Tristate.False; } // Check for un-parenthesized AsyncArrowFunction - const expr = parseBinaryExpressionOrHigher(OperatorPrecedence.Lowest); - if (!scanner.hasPrecedingLineBreak() && expr.kind === SyntaxKind.Identifier && token() === SyntaxKind.EqualsGreaterThanToken) { + const expr = parseBinaryExpressionOrHigher(ts.OperatorPrecedence.Lowest); + if (!scanner.hasPrecedingLineBreak() && expr.kind === ts.SyntaxKind.Identifier && token() === ts.SyntaxKind.EqualsGreaterThanToken) { return Tristate.True; } } @@ -4663,11 +4553,11 @@ namespace ts { return Tristate.False; } - function parseParenthesizedArrowFunctionExpression(allowAmbiguity: boolean): ArrowFunction | undefined { + function parseParenthesizedArrowFunctionExpression(allowAmbiguity: boolean): ts.ArrowFunction | undefined { const pos = getNodePos(); const hasJSDoc = hasPrecedingJSDocComment(); const modifiers = parseModifiersForArrowFunction(); - const isAsync = some(modifiers, isAsyncModifier) ? SignatureFlags.Await : SignatureFlags.None; + const isAsync = ts.some(modifiers, ts.isAsyncModifier) ? SignatureFlags.Await : SignatureFlags.None; // Arrow functions are never generators. // // If we're speculatively parsing a signature for a parenthesized arrow function, then @@ -4677,12 +4567,12 @@ namespace ts { // close paren. const typeParameters = parseTypeParameters(); - let parameters: NodeArray; - if (!parseExpected(SyntaxKind.OpenParenToken)) { + let parameters: ts.NodeArray; + if (!parseExpected(ts.SyntaxKind.OpenParenToken)) { if (!allowAmbiguity) { return undefined; } - parameters = createMissingList(); + parameters = createMissingList(); } else { if (!allowAmbiguity) { @@ -4695,12 +4585,12 @@ namespace ts { else { parameters = parseParametersWorker(isAsync, allowAmbiguity); } - if (!parseExpected(SyntaxKind.CloseParenToken) && !allowAmbiguity) { + if (!parseExpected(ts.SyntaxKind.CloseParenToken) && !allowAmbiguity) { return undefined; } } - const type = parseReturnType(SyntaxKind.ColonToken, /*isType*/ false); + const type = parseReturnType(ts.SyntaxKind.ColonToken, /*isType*/ false); if (type && !allowAmbiguity && typeHasArrowFunctionBlockingParseError(type)) { return undefined; } @@ -4717,12 +4607,12 @@ namespace ts { // So we need just a bit of lookahead to ensure that it can only be a signature. let unwrappedType = type; - while (unwrappedType?.kind === SyntaxKind.ParenthesizedType) { - unwrappedType = (unwrappedType as ParenthesizedTypeNode).type; // Skip parens if need be + while (unwrappedType?.kind === ts.SyntaxKind.ParenthesizedType) { + unwrappedType = (unwrappedType as ts.ParenthesizedTypeNode).type; // Skip parens if need be } - const hasJSDocFunctionType = unwrappedType && isJSDocFunctionType(unwrappedType); - if (!allowAmbiguity && token() !== SyntaxKind.EqualsGreaterThanToken && (hasJSDocFunctionType || token() !== SyntaxKind.OpenBraceToken)) { + const hasJSDocFunctionType = unwrappedType && ts.isJSDocFunctionType(unwrappedType); + if (!allowAmbiguity && token() !== ts.SyntaxKind.EqualsGreaterThanToken && (hasJSDocFunctionType || token() !== ts.SyntaxKind.OpenBraceToken)) { // Returning undefined here will cause our caller to rewind to where we started from. return undefined; } @@ -4730,23 +4620,23 @@ namespace ts { // If we have an arrow, then try to parse the body. Even if not, try to parse if we // have an opening brace, just in case we're in an error state. const lastToken = token(); - const equalsGreaterThanToken = parseExpectedToken(SyntaxKind.EqualsGreaterThanToken); - const body = (lastToken === SyntaxKind.EqualsGreaterThanToken || lastToken === SyntaxKind.OpenBraceToken) - ? parseArrowFunctionExpressionBody(some(modifiers, isAsyncModifier)) + const equalsGreaterThanToken = parseExpectedToken(ts.SyntaxKind.EqualsGreaterThanToken); + const body = (lastToken === ts.SyntaxKind.EqualsGreaterThanToken || lastToken === ts.SyntaxKind.OpenBraceToken) + ? parseArrowFunctionExpressionBody(ts.some(modifiers, ts.isAsyncModifier)) : parseIdentifier(); const node = factory.createArrowFunction(modifiers, typeParameters, parameters, type, equalsGreaterThanToken, body); return withJSDoc(finishNode(node, pos), hasJSDoc); } - function parseArrowFunctionExpressionBody(isAsync: boolean): Block | Expression { - if (token() === SyntaxKind.OpenBraceToken) { + function parseArrowFunctionExpressionBody(isAsync: boolean): ts.Block | ts.Expression { + if (token() === ts.SyntaxKind.OpenBraceToken) { return parseFunctionBlock(isAsync ? SignatureFlags.Await : SignatureFlags.None); } - if (token() !== SyntaxKind.SemicolonToken && - token() !== SyntaxKind.FunctionKeyword && - token() !== SyntaxKind.ClassKeyword && + if (token() !== ts.SyntaxKind.SemicolonToken && + token() !== ts.SyntaxKind.FunctionKeyword && + token() !== ts.SyntaxKind.ClassKeyword && isStartOfStatement() && !isStartOfExpressionStatement()) { // Check if we got a plain statement (i.e. no expression-statements, no function/class expressions/declarations) @@ -4775,9 +4665,9 @@ namespace ts { return node; } - function parseConditionalExpressionRest(leftOperand: Expression, pos: number): Expression { + function parseConditionalExpressionRest(leftOperand: ts.Expression, pos: number): ts.Expression { // Note: we are passed in an expression which was produced from parseBinaryExpressionOrHigher. - const questionToken = parseOptionalToken(SyntaxKind.QuestionToken); + const questionToken = parseOptionalToken(ts.SyntaxKind.QuestionToken); if (!questionToken) { return leftOperand; } @@ -4785,37 +4675,28 @@ namespace ts { // Note: we explicitly 'allowIn' in the whenTrue part of the condition expression, and // we do not that for the 'whenFalse' part. let colonToken; - return finishNode( - factory.createConditionalExpression( - leftOperand, - questionToken, - doOutsideOfContext(disallowInAndDecoratorContext, parseAssignmentExpressionOrHigher), - colonToken = parseExpectedToken(SyntaxKind.ColonToken), - nodeIsPresent(colonToken) + return finishNode(factory.createConditionalExpression(leftOperand, questionToken, doOutsideOfContext(disallowInAndDecoratorContext, parseAssignmentExpressionOrHigher), colonToken = parseExpectedToken(ts.SyntaxKind.ColonToken), ts.nodeIsPresent(colonToken) ? parseAssignmentExpressionOrHigher() - : createMissingNode(SyntaxKind.Identifier, /*reportAtCurrentPosition*/ false, Diagnostics._0_expected, tokenToString(SyntaxKind.ColonToken)) - ), - pos - ); + : createMissingNode(ts.SyntaxKind.Identifier, /*reportAtCurrentPosition*/ false, ts.Diagnostics._0_expected, ts.tokenToString(ts.SyntaxKind.ColonToken))), pos); } - function parseBinaryExpressionOrHigher(precedence: OperatorPrecedence): Expression { + function parseBinaryExpressionOrHigher(precedence: ts.OperatorPrecedence): ts.Expression { const pos = getNodePos(); const leftOperand = parseUnaryExpressionOrHigher(); return parseBinaryExpressionRest(precedence, leftOperand, pos); } - function isInOrOfKeyword(t: SyntaxKind) { - return t === SyntaxKind.InKeyword || t === SyntaxKind.OfKeyword; + function isInOrOfKeyword(t: ts.SyntaxKind) { + return t === ts.SyntaxKind.InKeyword || t === ts.SyntaxKind.OfKeyword; } - function parseBinaryExpressionRest(precedence: OperatorPrecedence, leftOperand: Expression, pos: number): Expression { + function parseBinaryExpressionRest(precedence: ts.OperatorPrecedence, leftOperand: ts.Expression, pos: number): ts.Expression { while (true) { // We either have a binary operator here, or we're finished. We call // reScanGreaterToken so that we merge token sequences like > and = into >= reScanGreaterToken(); - const newPrecedence = getBinaryOperatorPrecedence(token()); + const newPrecedence = ts.getBinaryOperatorPrecedence(token()); // Check the precedence to see if we should "take" this operator // - For left associative operator (all operator but **), consume the operator, @@ -4838,7 +4719,7 @@ namespace ts { // ^^token; leftOperand = b. Return b ** c to the caller as a rightOperand // a ** b - c // ^token; leftOperand = b. Return b to the caller as a rightOperand - const consumeCurrentOperator = token() === SyntaxKind.AsteriskAsteriskToken ? + const consumeCurrentOperator = token() === ts.SyntaxKind.AsteriskAsteriskToken ? newPrecedence >= precedence : newPrecedence > precedence; @@ -4846,11 +4727,11 @@ namespace ts { break; } - if (token() === SyntaxKind.InKeyword && inDisallowInContext()) { + if (token() === ts.SyntaxKind.InKeyword && inDisallowInContext()) { break; } - if (token() === SyntaxKind.AsKeyword) { + if (token() === ts.SyntaxKind.AsKeyword) { // Make sure we *do* perform ASI for constructs like this: // var x = foo // as (Bar) @@ -4873,24 +4754,24 @@ namespace ts { } function isBinaryOperator() { - if (inDisallowInContext() && token() === SyntaxKind.InKeyword) { + if (inDisallowInContext() && token() === ts.SyntaxKind.InKeyword) { return false; } - return getBinaryOperatorPrecedence(token()) > 0; + return ts.getBinaryOperatorPrecedence(token()) > 0; } - function makeBinaryExpression(left: Expression, operatorToken: BinaryOperatorToken, right: Expression, pos: number): BinaryExpression { + function makeBinaryExpression(left: ts.Expression, operatorToken: ts.BinaryOperatorToken, right: ts.Expression, pos: number): ts.BinaryExpression { return finishNode(factory.createBinaryExpression(left, operatorToken, right), pos); } - function makeAsExpression(left: Expression, right: TypeNode): AsExpression { + function makeAsExpression(left: ts.Expression, right: ts.TypeNode): ts.AsExpression { return finishNode(factory.createAsExpression(left, right), left.pos); } function parsePrefixUnaryExpression() { const pos = getNodePos(); - return finishNode(factory.createPrefixUnaryExpression(token() as PrefixUnaryOperator, nextTokenAnd(parseSimpleUnaryExpression)), pos); + return finishNode(factory.createPrefixUnaryExpression(token() as ts.PrefixUnaryOperator, nextTokenAnd(parseSimpleUnaryExpression)), pos); } function parseDeleteExpression() { @@ -4909,7 +4790,7 @@ namespace ts { } function isAwaitExpression(): boolean { - if (token() === SyntaxKind.AwaitKeyword) { + if (token() === ts.SyntaxKind.AwaitKeyword) { if (inAwaitContext()) { return true; } @@ -4934,7 +4815,7 @@ namespace ts { * 2) UpdateExpression[?Yield] ** ExponentiationExpression[?Yield] * */ - function parseUnaryExpressionOrHigher(): UnaryExpression | BinaryExpression { + function parseUnaryExpressionOrHigher(): ts.UnaryExpression | ts.BinaryExpression { /** * ES7 UpdateExpression: * 1) LeftHandSideExpression[?Yield] @@ -4946,8 +4827,8 @@ namespace ts { if (isUpdateExpression()) { const pos = getNodePos(); const updateExpression = parseUpdateExpression(); - return token() === SyntaxKind.AsteriskAsteriskToken ? - parseBinaryExpressionRest(getBinaryOperatorPrecedence(token()), updateExpression, pos) as BinaryExpression : + return token() === ts.SyntaxKind.AsteriskAsteriskToken ? + parseBinaryExpressionRest(ts.getBinaryOperatorPrecedence(token()), updateExpression, pos) as ts.BinaryExpression : updateExpression; } @@ -4964,14 +4845,14 @@ namespace ts { */ const unaryOperator = token(); const simpleUnaryExpression = parseSimpleUnaryExpression(); - if (token() === SyntaxKind.AsteriskAsteriskToken) { - const pos = skipTrivia(sourceText, simpleUnaryExpression.pos); + if (token() === ts.SyntaxKind.AsteriskAsteriskToken) { + const pos = ts.skipTrivia(sourceText, simpleUnaryExpression.pos); const { end } = simpleUnaryExpression; - if (simpleUnaryExpression.kind === SyntaxKind.TypeAssertionExpression) { - parseErrorAt(pos, end, Diagnostics.A_type_assertion_expression_is_not_allowed_in_the_left_hand_side_of_an_exponentiation_expression_Consider_enclosing_the_expression_in_parentheses); + if (simpleUnaryExpression.kind === ts.SyntaxKind.TypeAssertionExpression) { + parseErrorAt(pos, end, ts.Diagnostics.A_type_assertion_expression_is_not_allowed_in_the_left_hand_side_of_an_exponentiation_expression_Consider_enclosing_the_expression_in_parentheses); } else { - parseErrorAt(pos, end, Diagnostics.An_unary_expression_with_the_0_operator_is_not_allowed_in_the_left_hand_side_of_an_exponentiation_expression_Consider_enclosing_the_expression_in_parentheses, tokenToString(unaryOperator)); + parseErrorAt(pos, end, ts.Diagnostics.An_unary_expression_with_the_0_operator_is_not_allowed_in_the_left_hand_side_of_an_exponentiation_expression_Consider_enclosing_the_expression_in_parentheses, ts.tokenToString(unaryOperator)); } } return simpleUnaryExpression; @@ -4991,25 +4872,25 @@ namespace ts { * 8) ! UnaryExpression[?yield] * 9) [+Await] await UnaryExpression[?yield] */ - function parseSimpleUnaryExpression(): UnaryExpression { + function parseSimpleUnaryExpression(): ts.UnaryExpression { switch (token()) { - case SyntaxKind.PlusToken: - case SyntaxKind.MinusToken: - case SyntaxKind.TildeToken: - case SyntaxKind.ExclamationToken: + case ts.SyntaxKind.PlusToken: + case ts.SyntaxKind.MinusToken: + case ts.SyntaxKind.TildeToken: + case ts.SyntaxKind.ExclamationToken: return parsePrefixUnaryExpression(); - case SyntaxKind.DeleteKeyword: + case ts.SyntaxKind.DeleteKeyword: return parseDeleteExpression(); - case SyntaxKind.TypeOfKeyword: + case ts.SyntaxKind.TypeOfKeyword: return parseTypeOfExpression(); - case SyntaxKind.VoidKeyword: + case ts.SyntaxKind.VoidKeyword: return parseVoidExpression(); - case SyntaxKind.LessThanToken: + case ts.SyntaxKind.LessThanToken: // This is modified UnaryExpression grammar in TypeScript // UnaryExpression (modified): // < type > UnaryExpression return parseTypeAssertion(); - case SyntaxKind.AwaitKeyword: + case ts.SyntaxKind.AwaitKeyword: if (isAwaitExpression()) { return parseAwaitExpression(); } @@ -5033,18 +4914,18 @@ namespace ts { // This function is called inside parseUnaryExpression to decide // whether to call parseSimpleUnaryExpression or call parseUpdateExpression directly switch (token()) { - case SyntaxKind.PlusToken: - case SyntaxKind.MinusToken: - case SyntaxKind.TildeToken: - case SyntaxKind.ExclamationToken: - case SyntaxKind.DeleteKeyword: - case SyntaxKind.TypeOfKeyword: - case SyntaxKind.VoidKeyword: - case SyntaxKind.AwaitKeyword: + case ts.SyntaxKind.PlusToken: + case ts.SyntaxKind.MinusToken: + case ts.SyntaxKind.TildeToken: + case ts.SyntaxKind.ExclamationToken: + case ts.SyntaxKind.DeleteKeyword: + case ts.SyntaxKind.TypeOfKeyword: + case ts.SyntaxKind.VoidKeyword: + case ts.SyntaxKind.AwaitKeyword: return false; - case SyntaxKind.LessThanToken: + case ts.SyntaxKind.LessThanToken: // If we are not in JSX context, we are parsing TypeAssertion which is an UnaryExpression - if (languageVariant !== LanguageVariant.JSX) { + if (languageVariant !== ts.LanguageVariant.JSX) { return false; } // We are in JSX context and the token is part of JSXElement. @@ -5065,21 +4946,21 @@ namespace ts { * 5) --LeftHandSideExpression[?yield] * In TypeScript (2), (3) are parsed as PostfixUnaryExpression. (4), (5) are parsed as PrefixUnaryExpression */ - function parseUpdateExpression(): UpdateExpression { - if (token() === SyntaxKind.PlusPlusToken || token() === SyntaxKind.MinusMinusToken) { + function parseUpdateExpression(): ts.UpdateExpression { + if (token() === ts.SyntaxKind.PlusPlusToken || token() === ts.SyntaxKind.MinusMinusToken) { const pos = getNodePos(); - return finishNode(factory.createPrefixUnaryExpression(token() as PrefixUnaryOperator, nextTokenAnd(parseLeftHandSideExpressionOrHigher)), pos); + return finishNode(factory.createPrefixUnaryExpression(token() as ts.PrefixUnaryOperator, nextTokenAnd(parseLeftHandSideExpressionOrHigher)), pos); } - else if (languageVariant === LanguageVariant.JSX && token() === SyntaxKind.LessThanToken && lookAhead(nextTokenIsIdentifierOrKeywordOrGreaterThan)) { + else if (languageVariant === ts.LanguageVariant.JSX && token() === ts.SyntaxKind.LessThanToken && lookAhead(nextTokenIsIdentifierOrKeywordOrGreaterThan)) { // JSXElement is part of primaryExpression return parseJsxElementOrSelfClosingElementOrFragment(/*inExpressionContext*/ true); } const expression = parseLeftHandSideExpressionOrHigher(); - Debug.assert(isLeftHandSideExpression(expression)); - if ((token() === SyntaxKind.PlusPlusToken || token() === SyntaxKind.MinusMinusToken) && !scanner.hasPrecedingLineBreak()) { - const operator = token() as PostfixUnaryOperator; + ts.Debug.assert(ts.isLeftHandSideExpression(expression)); + if ((token() === ts.SyntaxKind.PlusPlusToken || token() === ts.SyntaxKind.MinusMinusToken) && !scanner.hasPrecedingLineBreak()) { + const operator = token() as ts.PostfixUnaryOperator; nextToken(); return finishNode(factory.createPostfixUnaryExpression(expression, operator), expression.pos); } @@ -5087,7 +4968,7 @@ namespace ts { return expression; } - function parseLeftHandSideExpressionOrHigher(): LeftHandSideExpression { + function parseLeftHandSideExpressionOrHigher(): ts.LeftHandSideExpression { // Original Ecma: // LeftHandSideExpression: See 11.2 // NewExpression @@ -5120,30 +5001,30 @@ namespace ts { // 3)we have a MemberExpression which either completes the LeftHandSideExpression, // or starts the beginning of the first four CallExpression productions. const pos = getNodePos(); - let expression: MemberExpression; - if (token() === SyntaxKind.ImportKeyword) { + let expression: ts.MemberExpression; + if (token() === ts.SyntaxKind.ImportKeyword) { if (lookAhead(nextTokenIsOpenParenOrLessThan)) { // We don't want to eagerly consume all import keyword as import call expression so we look ahead to find "(" // For example: // var foo3 = require("subfolder // import * as foo1 from "module-from-node // We want this import to be a statement rather than import call expression - sourceFlags |= NodeFlags.PossiblyContainsDynamicImport; - expression = parseTokenNode(); + sourceFlags |= ts.NodeFlags.PossiblyContainsDynamicImport; + expression = parseTokenNode(); } else if (lookAhead(nextTokenIsDot)) { // This is an 'import.*' metaproperty (i.e. 'import.meta') nextToken(); // advance past the 'import' nextToken(); // advance past the dot - expression = finishNode(factory.createMetaProperty(SyntaxKind.ImportKeyword, parseIdentifierName()), pos); - sourceFlags |= NodeFlags.PossiblyContainsImportMeta; + expression = finishNode(factory.createMetaProperty(ts.SyntaxKind.ImportKeyword, parseIdentifierName()), pos); + sourceFlags |= ts.NodeFlags.PossiblyContainsImportMeta; } else { expression = parseMemberExpressionOrHigher(); } } else { - expression = token() === SyntaxKind.SuperKeyword ? parseSuperExpression() : parseMemberExpressionOrHigher(); + expression = token() === ts.SyntaxKind.SuperKeyword ? parseSuperExpression() : parseMemberExpressionOrHigher(); } // Now, we *may* be complete. However, we might have consumed the start of a @@ -5152,7 +5033,7 @@ namespace ts { return parseCallExpressionRest(pos, expression); } - function parseMemberExpressionOrHigher(): MemberExpression { + function parseMemberExpressionOrHigher(): ts.MemberExpression { // Note: to make our lives simpler, we decompose the NewExpression productions and // place ObjectCreationExpression and FunctionExpression into PrimaryExpression. // like so: @@ -5205,50 +5086,44 @@ namespace ts { return parseMemberExpressionRest(pos, expression, /*allowOptionalChain*/ true); } - function parseSuperExpression(): MemberExpression { + function parseSuperExpression(): ts.MemberExpression { const pos = getNodePos(); - const expression = parseTokenNode(); - if (token() === SyntaxKind.LessThanToken) { + const expression = parseTokenNode(); + if (token() === ts.SyntaxKind.LessThanToken) { const startPos = getNodePos(); const typeArguments = tryParse(parseTypeArgumentsInExpression); if (typeArguments !== undefined) { - parseErrorAt(startPos, getNodePos(), Diagnostics.super_may_not_use_type_arguments); + parseErrorAt(startPos, getNodePos(), ts.Diagnostics.super_may_not_use_type_arguments); } } - if (token() === SyntaxKind.OpenParenToken || token() === SyntaxKind.DotToken || token() === SyntaxKind.OpenBracketToken) { + if (token() === ts.SyntaxKind.OpenParenToken || token() === ts.SyntaxKind.DotToken || token() === ts.SyntaxKind.OpenBracketToken) { return expression; } // If we have seen "super" it must be followed by '(' or '.'. // If it wasn't then just try to parse out a '.' and report an error. - parseExpectedToken(SyntaxKind.DotToken, Diagnostics.super_must_be_followed_by_an_argument_list_or_member_access); + parseExpectedToken(ts.SyntaxKind.DotToken, ts.Diagnostics.super_must_be_followed_by_an_argument_list_or_member_access); // private names will never work with `super` (`super.#foo`), but that's a semantic error, not syntactic return finishNode(factory.createPropertyAccessExpression(expression, parseRightSideOfDot(/*allowIdentifierNames*/ true, /*allowPrivateIdentifiers*/ true)), pos); } - function parseJsxElementOrSelfClosingElementOrFragment(inExpressionContext: boolean, topInvalidNodePosition?: number, openingTag?: JsxOpeningElement | JsxOpeningFragment): JsxElement | JsxSelfClosingElement | JsxFragment { + function parseJsxElementOrSelfClosingElementOrFragment(inExpressionContext: boolean, topInvalidNodePosition?: number, openingTag?: ts.JsxOpeningElement | ts.JsxOpeningFragment): ts.JsxElement | ts.JsxSelfClosingElement | ts.JsxFragment { const pos = getNodePos(); const opening = parseJsxOpeningOrSelfClosingElementOrOpeningFragment(inExpressionContext); - let result: JsxElement | JsxSelfClosingElement | JsxFragment; - if (opening.kind === SyntaxKind.JsxOpeningElement) { + let result: ts.JsxElement | ts.JsxSelfClosingElement | ts.JsxFragment; + if (opening.kind === ts.SyntaxKind.JsxOpeningElement) { let children = parseJsxChildren(opening); - let closingElement: JsxClosingElement; - - const lastChild: JsxChild | undefined = children[children.length - 1]; - if (lastChild?.kind === SyntaxKind.JsxElement + let closingElement: ts.JsxClosingElement; + const lastChild: ts.JsxChild | undefined = children[children.length - 1]; + if (lastChild?.kind === ts.SyntaxKind.JsxElement && !tagNamesAreEquivalent(lastChild.openingElement.tagName, lastChild.closingElement.tagName) && tagNamesAreEquivalent(opening.tagName, lastChild.closingElement.tagName)) { // when an unclosed JsxOpeningElement incorrectly parses its parent's JsxClosingElement, // restructure (
(......
)) --> (
(......)
) // (no need to error; the parent will error) const end = lastChild.children.end; - const newLast = finishNode(factory.createJsxElement( - lastChild.openingElement, - lastChild.children, - finishNode(factory.createJsxClosingElement(finishNode(factory.createIdentifier(""), end, end)), end, end)), - lastChild.openingElement.pos, - end); + const newLast = finishNode(factory.createJsxElement(lastChild.openingElement, lastChild.children, finishNode(factory.createJsxClosingElement(finishNode(factory.createIdentifier(""), end, end)), end, end)), lastChild.openingElement.pos, end); children = createNodeArray([...children.slice(0, children.length - 1), newLast], children.pos, end); closingElement = lastChild.closingElement; @@ -5256,23 +5131,23 @@ namespace ts { else { closingElement = parseJsxClosingElement(opening, inExpressionContext); if (!tagNamesAreEquivalent(opening.tagName, closingElement.tagName)) { - if (openingTag && isJsxOpeningElement(openingTag) && tagNamesAreEquivalent(closingElement.tagName, openingTag.tagName)) { + if (openingTag && ts.isJsxOpeningElement(openingTag) && tagNamesAreEquivalent(closingElement.tagName, openingTag.tagName)) { // opening incorrectly matched with its parent's closing -- put error on opening - parseErrorAtRange(opening.tagName, Diagnostics.JSX_element_0_has_no_corresponding_closing_tag, getTextOfNodeFromSourceText(sourceText, opening.tagName)); + parseErrorAtRange(opening.tagName, ts.Diagnostics.JSX_element_0_has_no_corresponding_closing_tag, ts.getTextOfNodeFromSourceText(sourceText, opening.tagName)); } else { // other opening/closing mismatches -- put error on closing - parseErrorAtRange(closingElement.tagName, Diagnostics.Expected_corresponding_JSX_closing_tag_for_0, getTextOfNodeFromSourceText(sourceText, opening.tagName)); + parseErrorAtRange(closingElement.tagName, ts.Diagnostics.Expected_corresponding_JSX_closing_tag_for_0, ts.getTextOfNodeFromSourceText(sourceText, opening.tagName)); } } } result = finishNode(factory.createJsxElement(opening, children, closingElement), pos); } - else if (opening.kind === SyntaxKind.JsxOpeningFragment) { + else if (opening.kind === ts.SyntaxKind.JsxOpeningFragment) { result = finishNode(factory.createJsxFragment(opening, parseJsxChildren(opening), parseJsxClosingFragment(inExpressionContext)), pos); } else { - Debug.assert(opening.kind === SyntaxKind.JsxSelfClosingElement); + ts.Debug.assert(opening.kind === ts.SyntaxKind.JsxSelfClosingElement); // Nothing else to do for self-closing elements result = opening; } @@ -5284,59 +5159,59 @@ namespace ts { // does less damage and we can report a better error. // Since JSX elements are invalid < operands anyway, this lookahead parse will only occur in error scenarios // of one sort or another. - if (inExpressionContext && token() === SyntaxKind.LessThanToken) { + if (inExpressionContext && token() === ts.SyntaxKind.LessThanToken) { const topBadPos = typeof topInvalidNodePosition === "undefined" ? result.pos : topInvalidNodePosition; const invalidElement = tryParse(() => parseJsxElementOrSelfClosingElementOrFragment(/*inExpressionContext*/ true, topBadPos)); if (invalidElement) { - const operatorToken = createMissingNode(SyntaxKind.CommaToken, /*reportAtCurrentPosition*/ false); - setTextRangePosWidth(operatorToken, invalidElement.pos, 0); - parseErrorAt(skipTrivia(sourceText, topBadPos), invalidElement.end, Diagnostics.JSX_expressions_must_have_one_parent_element); - return finishNode(factory.createBinaryExpression(result, operatorToken as Token, invalidElement), pos) as Node as JsxElement; + const operatorToken = createMissingNode(ts.SyntaxKind.CommaToken, /*reportAtCurrentPosition*/ false); + ts.setTextRangePosWidth(operatorToken, invalidElement.pos, 0); + parseErrorAt(ts.skipTrivia(sourceText, topBadPos), invalidElement.end, ts.Diagnostics.JSX_expressions_must_have_one_parent_element); + return finishNode(factory.createBinaryExpression(result, operatorToken as ts.Token, invalidElement), pos) as ts.Node as ts.JsxElement; } } return result; } - function parseJsxText(): JsxText { + function parseJsxText(): ts.JsxText { const pos = getNodePos(); - const node = factory.createJsxText(scanner.getTokenValue(), currentToken === SyntaxKind.JsxTextAllWhiteSpaces); + const node = factory.createJsxText(scanner.getTokenValue(), currentToken === ts.SyntaxKind.JsxTextAllWhiteSpaces); currentToken = scanner.scanJsxToken(); return finishNode(node, pos); } - function parseJsxChild(openingTag: JsxOpeningElement | JsxOpeningFragment, token: JsxTokenSyntaxKind): JsxChild | undefined { + function parseJsxChild(openingTag: ts.JsxOpeningElement | ts.JsxOpeningFragment, token: ts.JsxTokenSyntaxKind): ts.JsxChild | undefined { switch (token) { - case SyntaxKind.EndOfFileToken: + case ts.SyntaxKind.EndOfFileToken: // If we hit EOF, issue the error at the tag that lacks the closing element // rather than at the end of the file (which is useless) - if (isJsxOpeningFragment(openingTag)) { - parseErrorAtRange(openingTag, Diagnostics.JSX_fragment_has_no_corresponding_closing_tag); + if (ts.isJsxOpeningFragment(openingTag)) { + parseErrorAtRange(openingTag, ts.Diagnostics.JSX_fragment_has_no_corresponding_closing_tag); } else { // We want the error span to cover only 'Foo.Bar' in < Foo.Bar > // or to cover only 'Foo' in < Foo > const tag = openingTag.tagName; - const start = skipTrivia(sourceText, tag.pos); - parseErrorAt(start, tag.end, Diagnostics.JSX_element_0_has_no_corresponding_closing_tag, getTextOfNodeFromSourceText(sourceText, openingTag.tagName)); + const start = ts.skipTrivia(sourceText, tag.pos); + parseErrorAt(start, tag.end, ts.Diagnostics.JSX_element_0_has_no_corresponding_closing_tag, ts.getTextOfNodeFromSourceText(sourceText, openingTag.tagName)); } return undefined; - case SyntaxKind.LessThanSlashToken: - case SyntaxKind.ConflictMarkerTrivia: + case ts.SyntaxKind.LessThanSlashToken: + case ts.SyntaxKind.ConflictMarkerTrivia: return undefined; - case SyntaxKind.JsxText: - case SyntaxKind.JsxTextAllWhiteSpaces: + case ts.SyntaxKind.JsxText: + case ts.SyntaxKind.JsxTextAllWhiteSpaces: return parseJsxText(); - case SyntaxKind.OpenBraceToken: + case ts.SyntaxKind.OpenBraceToken: return parseJsxExpression(/*inExpressionContext*/ false); - case SyntaxKind.LessThanToken: + case ts.SyntaxKind.LessThanToken: return parseJsxElementOrSelfClosingElementOrFragment(/*inExpressionContext*/ false, /*topInvalidNodePosition*/ undefined, openingTag); default: - return Debug.assertNever(token); + return ts.Debug.assertNever(token); } } - function parseJsxChildren(openingTag: JsxOpeningElement | JsxOpeningFragment): NodeArray { + function parseJsxChildren(openingTag: ts.JsxOpeningElement | ts.JsxOpeningFragment): ts.NodeArray { const list = []; const listPos = getNodePos(); const saveParsingContext = parsingContext; @@ -5344,10 +5219,11 @@ namespace ts { while (true) { const child = parseJsxChild(openingTag, currentToken = scanner.reScanJsxToken()); - if (!child) break; + if (!child) + break; list.push(child); - if (isJsxOpeningElement(openingTag) - && child?.kind === SyntaxKind.JsxElement + if (ts.isJsxOpeningElement(openingTag) + && child?.kind === ts.SyntaxKind.JsxElement && !tagNamesAreEquivalent(child.openingElement.tagName, child.closingElement.tagName) && tagNamesAreEquivalent(openingTag.tagName, child.closingElement.tagName)) { // stop after parsing a mismatched child like
...(
) in order to reattach the
higher @@ -5359,28 +5235,26 @@ namespace ts { return createNodeArray(list, listPos); } - function parseJsxAttributes(): JsxAttributes { + function parseJsxAttributes(): ts.JsxAttributes { const pos = getNodePos(); return finishNode(factory.createJsxAttributes(parseList(ParsingContext.JsxAttributes, parseJsxAttribute)), pos); } - function parseJsxOpeningOrSelfClosingElementOrOpeningFragment(inExpressionContext: boolean): JsxOpeningElement | JsxSelfClosingElement | JsxOpeningFragment { + function parseJsxOpeningOrSelfClosingElementOrOpeningFragment(inExpressionContext: boolean): ts.JsxOpeningElement | ts.JsxSelfClosingElement | ts.JsxOpeningFragment { const pos = getNodePos(); - parseExpected(SyntaxKind.LessThanToken); - - if (token() === SyntaxKind.GreaterThanToken) { + parseExpected(ts.SyntaxKind.LessThanToken); + if (token() === ts.SyntaxKind.GreaterThanToken) { // See below for explanation of scanJsxText scanJsxText(); return finishNode(factory.createJsxOpeningFragment(), pos); } const tagName = parseJsxElementName(); - const typeArguments = (contextFlags & NodeFlags.JavaScriptFile) === 0 ? tryParseTypeArguments() : undefined; + const typeArguments = (contextFlags & ts.NodeFlags.JavaScriptFile) === 0 ? tryParseTypeArguments() : undefined; const attributes = parseJsxAttributes(); - let node: JsxOpeningLikeElement; - - if (token() === SyntaxKind.GreaterThanToken) { + let node: ts.JsxOpeningLikeElement; + if (token() === ts.SyntaxKind.GreaterThanToken) { // Closing tag, so scan the immediately-following text with the JSX scanning instead // of regular scanning to avoid treating illegal characters (e.g. '#') as immediate // scanning errors @@ -5388,8 +5262,8 @@ namespace ts { node = factory.createJsxOpeningElement(tagName, typeArguments, attributes); } else { - parseExpected(SyntaxKind.SlashToken); - if (parseExpected(SyntaxKind.GreaterThanToken, /*diagnostic*/ undefined, /*shouldAdvance*/ false)) { + parseExpected(ts.SyntaxKind.SlashToken); + if (parseExpected(ts.SyntaxKind.GreaterThanToken, /*diagnostic*/ undefined, /*shouldAdvance*/ false)) { // manually advance the scanner in order to look for jsx text inside jsx if (inExpressionContext) { nextToken(); @@ -5404,7 +5278,7 @@ namespace ts { return finishNode(node, pos); } - function parseJsxElementName(): JsxTagNameExpression { + function parseJsxElementName(): ts.JsxTagNameExpression { const pos = getNodePos(); scanJsxIdentifier(); // JsxElement can have name in the form of @@ -5412,34 +5286,34 @@ namespace ts { // primaryExpression in the form of an identifier and "this" keyword // We can't just simply use parseLeftHandSideExpressionOrHigher because then we will start consider class,function etc as a keyword // We only want to consider "this" as a primaryExpression - let expression: JsxTagNameExpression = token() === SyntaxKind.ThisKeyword ? - parseTokenNode() : parseIdentifierName(); - while (parseOptional(SyntaxKind.DotToken)) { - expression = finishNode(factory.createPropertyAccessExpression(expression, parseRightSideOfDot(/*allowIdentifierNames*/ true, /*allowPrivateIdentifiers*/ false)), pos) as JsxTagNamePropertyAccess; + let expression: ts.JsxTagNameExpression = token() === ts.SyntaxKind.ThisKeyword ? + parseTokenNode() : parseIdentifierName(); + while (parseOptional(ts.SyntaxKind.DotToken)) { + expression = finishNode(factory.createPropertyAccessExpression(expression, parseRightSideOfDot(/*allowIdentifierNames*/ true, /*allowPrivateIdentifiers*/ false)), pos) as ts.JsxTagNamePropertyAccess; } return expression; } - function parseJsxExpression(inExpressionContext: boolean): JsxExpression | undefined { + function parseJsxExpression(inExpressionContext: boolean): ts.JsxExpression | undefined { const pos = getNodePos(); - if (!parseExpected(SyntaxKind.OpenBraceToken)) { + if (!parseExpected(ts.SyntaxKind.OpenBraceToken)) { return undefined; } - let dotDotDotToken: DotDotDotToken | undefined; - let expression: Expression | undefined; - if (token() !== SyntaxKind.CloseBraceToken) { - dotDotDotToken = parseOptionalToken(SyntaxKind.DotDotDotToken); + let dotDotDotToken: ts.DotDotDotToken | undefined; + let expression: ts.Expression | undefined; + if (token() !== ts.SyntaxKind.CloseBraceToken) { + dotDotDotToken = parseOptionalToken(ts.SyntaxKind.DotDotDotToken); // Only an AssignmentExpression is valid here per the JSX spec, // but we can unambiguously parse a comma sequence and provide // a better error message in grammar checking. expression = parseExpression(); } if (inExpressionContext) { - parseExpected(SyntaxKind.CloseBraceToken); + parseExpected(ts.SyntaxKind.CloseBraceToken); } else { - if (parseExpected(SyntaxKind.CloseBraceToken, /*message*/ undefined, /*shouldAdvance*/ false)) { + if (parseExpected(ts.SyntaxKind.CloseBraceToken, /*message*/ undefined, /*shouldAdvance*/ false)) { scanJsxText(); } } @@ -5447,8 +5321,8 @@ namespace ts { return finishNode(factory.createJsxExpression(dotDotDotToken, expression), pos); } - function parseJsxAttribute(): JsxAttribute | JsxSpreadAttribute { - if (token() === SyntaxKind.OpenBraceToken) { + function parseJsxAttribute(): ts.JsxAttribute | ts.JsxSpreadAttribute { + if (token() === ts.SyntaxKind.OpenBraceToken) { return parseJsxSpreadAttribute(); } @@ -5457,36 +5331,36 @@ namespace ts { return finishNode(factory.createJsxAttribute(parseIdentifierName(), parseJsxAttributeValue()), pos); } - function parseJsxAttributeValue(): JsxAttributeValue | undefined { - if (token() === SyntaxKind.EqualsToken) { - if (scanJsxAttributeValue() === SyntaxKind.StringLiteral) { - return parseLiteralNode() as StringLiteral; + function parseJsxAttributeValue(): ts.JsxAttributeValue | undefined { + if (token() === ts.SyntaxKind.EqualsToken) { + if (scanJsxAttributeValue() === ts.SyntaxKind.StringLiteral) { + return parseLiteralNode() as ts.StringLiteral; } - if (token() === SyntaxKind.OpenBraceToken) { + if (token() === ts.SyntaxKind.OpenBraceToken) { return parseJsxExpression(/*inExpressionContext*/ true); } - if (token() === SyntaxKind.LessThanToken) { + if (token() === ts.SyntaxKind.LessThanToken) { return parseJsxElementOrSelfClosingElementOrFragment(/*inExpressionContext*/ true); } - parseErrorAtCurrentToken(Diagnostics.or_JSX_element_expected); + parseErrorAtCurrentToken(ts.Diagnostics.or_JSX_element_expected); } return undefined; } - function parseJsxSpreadAttribute(): JsxSpreadAttribute { + function parseJsxSpreadAttribute(): ts.JsxSpreadAttribute { const pos = getNodePos(); - parseExpected(SyntaxKind.OpenBraceToken); - parseExpected(SyntaxKind.DotDotDotToken); + parseExpected(ts.SyntaxKind.OpenBraceToken); + parseExpected(ts.SyntaxKind.DotDotDotToken); const expression = parseExpression(); - parseExpected(SyntaxKind.CloseBraceToken); + parseExpected(ts.SyntaxKind.CloseBraceToken); return finishNode(factory.createJsxSpreadAttribute(expression), pos); } - function parseJsxClosingElement(open: JsxOpeningElement, inExpressionContext: boolean): JsxClosingElement { + function parseJsxClosingElement(open: ts.JsxOpeningElement, inExpressionContext: boolean): ts.JsxClosingElement { const pos = getNodePos(); - parseExpected(SyntaxKind.LessThanSlashToken); + parseExpected(ts.SyntaxKind.LessThanSlashToken); const tagName = parseJsxElementName(); - if (parseExpected(SyntaxKind.GreaterThanToken, /*diagnostic*/ undefined, /*shouldAdvance*/ false)) { + if (parseExpected(ts.SyntaxKind.GreaterThanToken, /*diagnostic*/ undefined, /*shouldAdvance*/ false)) { // manually advance the scanner in order to look for jsx text inside jsx if (inExpressionContext || !tagNamesAreEquivalent(open.tagName, tagName)) { nextToken(); @@ -5498,13 +5372,13 @@ namespace ts { return finishNode(factory.createJsxClosingElement(tagName), pos); } - function parseJsxClosingFragment(inExpressionContext: boolean): JsxClosingFragment { + function parseJsxClosingFragment(inExpressionContext: boolean): ts.JsxClosingFragment { const pos = getNodePos(); - parseExpected(SyntaxKind.LessThanSlashToken); - if (tokenIsIdentifierOrKeyword(token())) { - parseErrorAtRange(parseJsxElementName(), Diagnostics.Expected_corresponding_closing_tag_for_JSX_fragment); + parseExpected(ts.SyntaxKind.LessThanSlashToken); + if (ts.tokenIsIdentifierOrKeyword(token())) { + parseErrorAtRange(parseJsxElementName(), ts.Diagnostics.Expected_corresponding_closing_tag_for_JSX_fragment); } - if (parseExpected(SyntaxKind.GreaterThanToken, /*diagnostic*/ undefined, /*shouldAdvance*/ false)) { + if (parseExpected(ts.SyntaxKind.GreaterThanToken, /*diagnostic*/ undefined, /*shouldAdvance*/ false)) { // manually advance the scanner in order to look for jsx text inside jsx if (inExpressionContext) { nextToken(); @@ -5516,41 +5390,41 @@ namespace ts { return finishNode(factory.createJsxJsxClosingFragment(), pos); } - function parseTypeAssertion(): TypeAssertion { + function parseTypeAssertion(): ts.TypeAssertion { const pos = getNodePos(); - parseExpected(SyntaxKind.LessThanToken); + parseExpected(ts.SyntaxKind.LessThanToken); const type = parseType(); - parseExpected(SyntaxKind.GreaterThanToken); + parseExpected(ts.SyntaxKind.GreaterThanToken); const expression = parseSimpleUnaryExpression(); return finishNode(factory.createTypeAssertion(type, expression), pos); } function nextTokenIsIdentifierOrKeywordOrOpenBracketOrTemplate() { nextToken(); - return tokenIsIdentifierOrKeyword(token()) - || token() === SyntaxKind.OpenBracketToken + return ts.tokenIsIdentifierOrKeyword(token()) + || token() === ts.SyntaxKind.OpenBracketToken || isTemplateStartOfTaggedTemplate(); } function isStartOfOptionalPropertyOrElementAccessChain() { - return token() === SyntaxKind.QuestionDotToken + return token() === ts.SyntaxKind.QuestionDotToken && lookAhead(nextTokenIsIdentifierOrKeywordOrOpenBracketOrTemplate); } - function tryReparseOptionalChain(node: Expression) { - if (node.flags & NodeFlags.OptionalChain) { + function tryReparseOptionalChain(node: ts.Expression) { + if (node.flags & ts.NodeFlags.OptionalChain) { return true; } // check for an optional chain in a non-null expression - if (isNonNullExpression(node)) { + if (ts.isNonNullExpression(node)) { let expr = node.expression; - while (isNonNullExpression(expr) && !(expr.flags & NodeFlags.OptionalChain)) { + while (ts.isNonNullExpression(expr) && !(expr.flags & ts.NodeFlags.OptionalChain)) { expr = expr.expression; } - if (expr.flags & NodeFlags.OptionalChain) { + if (expr.flags & ts.NodeFlags.OptionalChain) { // this is part of an optional chain. Walk down from `node` to `expression` and set the flag. - while (isNonNullExpression(node)) { - (node as Mutable).flags |= NodeFlags.OptionalChain; + while (ts.isNonNullExpression(node)) { + (node as ts.Mutable).flags |= ts.NodeFlags.OptionalChain; node = node.expression; } return true; @@ -5559,32 +5433,32 @@ namespace ts { return false; } - function parsePropertyAccessExpressionRest(pos: number, expression: LeftHandSideExpression, questionDotToken: QuestionDotToken | undefined) { + function parsePropertyAccessExpressionRest(pos: number, expression: ts.LeftHandSideExpression, questionDotToken: ts.QuestionDotToken | undefined) { const name = parseRightSideOfDot(/*allowIdentifierNames*/ true, /*allowPrivateIdentifiers*/ true); const isOptionalChain = questionDotToken || tryReparseOptionalChain(expression); const propertyAccess = isOptionalChain ? factory.createPropertyAccessChain(expression, questionDotToken, name) : factory.createPropertyAccessExpression(expression, name); - if (isOptionalChain && isPrivateIdentifier(propertyAccess.name)) { - parseErrorAtRange(propertyAccess.name, Diagnostics.An_optional_chain_cannot_contain_private_identifiers); + if (isOptionalChain && ts.isPrivateIdentifier(propertyAccess.name)) { + parseErrorAtRange(propertyAccess.name, ts.Diagnostics.An_optional_chain_cannot_contain_private_identifiers); } return finishNode(propertyAccess, pos); } - function parseElementAccessExpressionRest(pos: number, expression: LeftHandSideExpression, questionDotToken: QuestionDotToken | undefined) { - let argumentExpression: Expression; - if (token() === SyntaxKind.CloseBracketToken) { - argumentExpression = createMissingNode(SyntaxKind.Identifier, /*reportAtCurrentPosition*/ true, Diagnostics.An_element_access_expression_should_take_an_argument); + function parseElementAccessExpressionRest(pos: number, expression: ts.LeftHandSideExpression, questionDotToken: ts.QuestionDotToken | undefined) { + let argumentExpression: ts.Expression; + if (token() === ts.SyntaxKind.CloseBracketToken) { + argumentExpression = createMissingNode(ts.SyntaxKind.Identifier, /*reportAtCurrentPosition*/ true, ts.Diagnostics.An_element_access_expression_should_take_an_argument); } else { const argument = allowInAnd(parseExpression); - if (isStringOrNumericLiteralLike(argument)) { + if (ts.isStringOrNumericLiteralLike(argument)) { argument.text = internIdentifier(argument.text); } argumentExpression = argument; } - parseExpected(SyntaxKind.CloseBracketToken); + parseExpected(ts.SyntaxKind.CloseBracketToken); const indexedAccess = questionDotToken || tryReparseOptionalChain(expression) ? factory.createElementAccessChain(expression, questionDotToken, argumentExpression) : @@ -5592,16 +5466,16 @@ namespace ts { return finishNode(indexedAccess, pos); } - function parseMemberExpressionRest(pos: number, expression: LeftHandSideExpression, allowOptionalChain: boolean): MemberExpression { + function parseMemberExpressionRest(pos: number, expression: ts.LeftHandSideExpression, allowOptionalChain: boolean): ts.MemberExpression { while (true) { - let questionDotToken: QuestionDotToken | undefined; + let questionDotToken: ts.QuestionDotToken | undefined; let isPropertyAccess = false; if (allowOptionalChain && isStartOfOptionalPropertyOrElementAccessChain()) { - questionDotToken = parseExpectedToken(SyntaxKind.QuestionDotToken); - isPropertyAccess = tokenIsIdentifierOrKeyword(token()); + questionDotToken = parseExpectedToken(ts.SyntaxKind.QuestionDotToken); + isPropertyAccess = ts.tokenIsIdentifierOrKeyword(token()); } else { - isPropertyAccess = parseOptional(SyntaxKind.DotToken); + isPropertyAccess = parseOptional(ts.SyntaxKind.DotToken); } if (isPropertyAccess) { @@ -5610,21 +5484,21 @@ namespace ts { } // when in the [Decorator] context, we do not parse ElementAccess as it could be part of a ComputedPropertyName - if ((questionDotToken || !inDecoratorContext()) && parseOptional(SyntaxKind.OpenBracketToken)) { + if ((questionDotToken || !inDecoratorContext()) && parseOptional(ts.SyntaxKind.OpenBracketToken)) { expression = parseElementAccessExpressionRest(pos, expression, questionDotToken); continue; } if (isTemplateStartOfTaggedTemplate()) { // Absorb type arguments into TemplateExpression when preceding expression is ExpressionWithTypeArguments - expression = !questionDotToken && expression.kind === SyntaxKind.ExpressionWithTypeArguments ? - parseTaggedTemplateRest(pos, (expression as ExpressionWithTypeArguments).expression, questionDotToken, (expression as ExpressionWithTypeArguments).typeArguments) : + expression = !questionDotToken && expression.kind === ts.SyntaxKind.ExpressionWithTypeArguments ? + parseTaggedTemplateRest(pos, (expression as ts.ExpressionWithTypeArguments).expression, questionDotToken, (expression as ts.ExpressionWithTypeArguments).typeArguments) : parseTaggedTemplateRest(pos, expression, questionDotToken, /*typeArguments*/ undefined); continue; } if (!questionDotToken) { - if (token() === SyntaxKind.ExclamationToken && !scanner.hasPrecedingLineBreak()) { + if (token() === ts.SyntaxKind.ExclamationToken && !scanner.hasPrecedingLineBreak()) { nextToken(); expression = finishNode(factory.createNonNullExpression(expression), pos); continue; @@ -5636,34 +5510,29 @@ namespace ts { } } - return expression as MemberExpression; + return expression as ts.MemberExpression; } } function isTemplateStartOfTaggedTemplate() { - return token() === SyntaxKind.NoSubstitutionTemplateLiteral || token() === SyntaxKind.TemplateHead; + return token() === ts.SyntaxKind.NoSubstitutionTemplateLiteral || token() === ts.SyntaxKind.TemplateHead; } - - function parseTaggedTemplateRest(pos: number, tag: LeftHandSideExpression, questionDotToken: QuestionDotToken | undefined, typeArguments: NodeArray | undefined) { - const tagExpression = factory.createTaggedTemplateExpression( - tag, - typeArguments, - token() === SyntaxKind.NoSubstitutionTemplateLiteral ? - (reScanTemplateHeadOrNoSubstitutionTemplate(), parseLiteralNode() as NoSubstitutionTemplateLiteral) : - parseTemplateExpression(/*isTaggedTemplate*/ true) - ); - if (questionDotToken || tag.flags & NodeFlags.OptionalChain) { - (tagExpression as Mutable).flags |= NodeFlags.OptionalChain; + function parseTaggedTemplateRest(pos: number, tag: ts.LeftHandSideExpression, questionDotToken: ts.QuestionDotToken | undefined, typeArguments: ts.NodeArray | undefined) { + const tagExpression = factory.createTaggedTemplateExpression(tag, typeArguments, token() === ts.SyntaxKind.NoSubstitutionTemplateLiteral ? + (reScanTemplateHeadOrNoSubstitutionTemplate(), parseLiteralNode() as ts.NoSubstitutionTemplateLiteral) : + parseTemplateExpression(/*isTaggedTemplate*/ true)); + if (questionDotToken || tag.flags & ts.NodeFlags.OptionalChain) { + (tagExpression as ts.Mutable).flags |= ts.NodeFlags.OptionalChain; } tagExpression.questionDotToken = questionDotToken; return finishNode(tagExpression, pos); } - function parseCallExpressionRest(pos: number, expression: LeftHandSideExpression): LeftHandSideExpression { + function parseCallExpressionRest(pos: number, expression: ts.LeftHandSideExpression): ts.LeftHandSideExpression { while (true) { expression = parseMemberExpressionRest(pos, expression, /*allowOptionalChain*/ true); - let typeArguments: NodeArray | undefined; - const questionDotToken = parseOptionalToken(SyntaxKind.QuestionDotToken); + let typeArguments: ts.NodeArray | undefined; + const questionDotToken = parseOptionalToken(ts.SyntaxKind.QuestionDotToken); if (questionDotToken) { typeArguments = tryParse(parseTypeArgumentsInExpression); if (isTemplateStartOfTaggedTemplate()) { @@ -5671,11 +5540,11 @@ namespace ts { continue; } } - if (typeArguments || token() === SyntaxKind.OpenParenToken) { + if (typeArguments || token() === ts.SyntaxKind.OpenParenToken) { // Absorb type arguments into CallExpression when preceding expression is ExpressionWithTypeArguments - if (!questionDotToken && expression.kind === SyntaxKind.ExpressionWithTypeArguments) { - typeArguments = (expression as ExpressionWithTypeArguments).typeArguments; - expression = (expression as ExpressionWithTypeArguments).expression; + if (!questionDotToken && expression.kind === ts.SyntaxKind.ExpressionWithTypeArguments) { + typeArguments = (expression as ts.ExpressionWithTypeArguments).typeArguments; + expression = (expression as ts.ExpressionWithTypeArguments).expression; } const argumentList = parseArgumentList(); const callExpr = questionDotToken || tryReparseOptionalChain(expression) ? @@ -5686,7 +5555,7 @@ namespace ts { } if (questionDotToken) { // We parsed `?.` but then failed to parse anything, so report a missing identifier here. - const name = createMissingNode(SyntaxKind.Identifier, /*reportAtCurrentPosition*/ false, Diagnostics.Identifier_expected); + const name = createMissingNode(ts.SyntaxKind.Identifier, /*reportAtCurrentPosition*/ false, ts.Diagnostics.Identifier_expected); expression = finishNode(factory.createPropertyAccessChain(expression, questionDotToken, name), pos); } break; @@ -5695,25 +5564,25 @@ namespace ts { } function parseArgumentList() { - parseExpected(SyntaxKind.OpenParenToken); + parseExpected(ts.SyntaxKind.OpenParenToken); const result = parseDelimitedList(ParsingContext.ArgumentExpressions, parseArgumentExpression); - parseExpected(SyntaxKind.CloseParenToken); + parseExpected(ts.SyntaxKind.CloseParenToken); return result; } function parseTypeArgumentsInExpression() { - if ((contextFlags & NodeFlags.JavaScriptFile) !== 0) { + if ((contextFlags & ts.NodeFlags.JavaScriptFile) !== 0) { // TypeArguments must not be parsed in JavaScript files to avoid ambiguity with binary operators. return undefined; } - if (reScanLessThanToken() !== SyntaxKind.LessThanToken) { + if (reScanLessThanToken() !== ts.SyntaxKind.LessThanToken) { return undefined; } nextToken(); const typeArguments = parseDelimitedList(ParsingContext.TypeArguments, parseType); - if (!parseExpected(SyntaxKind.GreaterThanToken)) { + if (!parseExpected(ts.SyntaxKind.GreaterThanToken)) { // If it doesn't have the closing `>` then it's definitely not an type argument list. return undefined; } @@ -5728,35 +5597,35 @@ namespace ts { function canFollowTypeArgumentsInExpression(): boolean { switch (token()) { // These tokens can follow a type argument list in a call expression. - case SyntaxKind.OpenParenToken: // foo( - case SyntaxKind.NoSubstitutionTemplateLiteral: // foo `...` - case SyntaxKind.TemplateHead: // foo `...${100}...` + case ts.SyntaxKind.OpenParenToken: // foo( + case ts.SyntaxKind.NoSubstitutionTemplateLiteral: // foo `...` + case ts.SyntaxKind.TemplateHead: // foo `...${100}...` return true; } // Consider something a type argument list only if the following token can't start an expression. return !isStartOfExpression(); } - function parsePrimaryExpression(): PrimaryExpression { + function parsePrimaryExpression(): ts.PrimaryExpression { switch (token()) { - case SyntaxKind.NumericLiteral: - case SyntaxKind.BigIntLiteral: - case SyntaxKind.StringLiteral: - case SyntaxKind.NoSubstitutionTemplateLiteral: + case ts.SyntaxKind.NumericLiteral: + case ts.SyntaxKind.BigIntLiteral: + case ts.SyntaxKind.StringLiteral: + case ts.SyntaxKind.NoSubstitutionTemplateLiteral: return parseLiteralNode(); - case SyntaxKind.ThisKeyword: - case SyntaxKind.SuperKeyword: - case SyntaxKind.NullKeyword: - case SyntaxKind.TrueKeyword: - case SyntaxKind.FalseKeyword: - return parseTokenNode(); - case SyntaxKind.OpenParenToken: + case ts.SyntaxKind.ThisKeyword: + case ts.SyntaxKind.SuperKeyword: + case ts.SyntaxKind.NullKeyword: + case ts.SyntaxKind.TrueKeyword: + case ts.SyntaxKind.FalseKeyword: + return parseTokenNode(); + case ts.SyntaxKind.OpenParenToken: return parseParenthesizedExpression(); - case SyntaxKind.OpenBracketToken: + case ts.SyntaxKind.OpenBracketToken: return parseArrayLiteralExpression(); - case SyntaxKind.OpenBraceToken: + case ts.SyntaxKind.OpenBraceToken: return parseObjectLiteralExpression(); - case SyntaxKind.AsyncKeyword: + case ts.SyntaxKind.AsyncKeyword: // Async arrow functions are parsed earlier in parseAssignmentExpressionOrHigher. // If we encounter `async [no LineTerminator here] function` then this is an async // function; otherwise, its an identifier. @@ -5765,68 +5634,68 @@ namespace ts { } return parseFunctionExpression(); - case SyntaxKind.ClassKeyword: + case ts.SyntaxKind.ClassKeyword: return parseClassExpression(); - case SyntaxKind.FunctionKeyword: + case ts.SyntaxKind.FunctionKeyword: return parseFunctionExpression(); - case SyntaxKind.NewKeyword: + case ts.SyntaxKind.NewKeyword: return parseNewExpressionOrNewDotTarget(); - case SyntaxKind.SlashToken: - case SyntaxKind.SlashEqualsToken: - if (reScanSlashToken() === SyntaxKind.RegularExpressionLiteral) { + case ts.SyntaxKind.SlashToken: + case ts.SyntaxKind.SlashEqualsToken: + if (reScanSlashToken() === ts.SyntaxKind.RegularExpressionLiteral) { return parseLiteralNode(); } break; - case SyntaxKind.TemplateHead: + case ts.SyntaxKind.TemplateHead: return parseTemplateExpression(/* isTaggedTemplate */ false); - case SyntaxKind.PrivateIdentifier: + case ts.SyntaxKind.PrivateIdentifier: return parsePrivateIdentifier(); } - return parseIdentifier(Diagnostics.Expression_expected); + return parseIdentifier(ts.Diagnostics.Expression_expected); } - function parseParenthesizedExpression(): ParenthesizedExpression { + function parseParenthesizedExpression(): ts.ParenthesizedExpression { const pos = getNodePos(); const hasJSDoc = hasPrecedingJSDocComment(); - parseExpected(SyntaxKind.OpenParenToken); + parseExpected(ts.SyntaxKind.OpenParenToken); const expression = allowInAnd(parseExpression); - parseExpected(SyntaxKind.CloseParenToken); + parseExpected(ts.SyntaxKind.CloseParenToken); return withJSDoc(finishNode(factory.createParenthesizedExpression(expression), pos), hasJSDoc); } - function parseSpreadElement(): Expression { + function parseSpreadElement(): ts.Expression { const pos = getNodePos(); - parseExpected(SyntaxKind.DotDotDotToken); + parseExpected(ts.SyntaxKind.DotDotDotToken); const expression = parseAssignmentExpressionOrHigher(); return finishNode(factory.createSpreadElement(expression), pos); } - function parseArgumentOrArrayLiteralElement(): Expression { - return token() === SyntaxKind.DotDotDotToken ? parseSpreadElement() : - token() === SyntaxKind.CommaToken ? finishNode(factory.createOmittedExpression(), getNodePos()) : + function parseArgumentOrArrayLiteralElement(): ts.Expression { + return token() === ts.SyntaxKind.DotDotDotToken ? parseSpreadElement() : + token() === ts.SyntaxKind.CommaToken ? finishNode(factory.createOmittedExpression(), getNodePos()) : parseAssignmentExpressionOrHigher(); } - function parseArgumentExpression(): Expression { + function parseArgumentExpression(): ts.Expression { return doOutsideOfContext(disallowInAndDecoratorContext, parseArgumentOrArrayLiteralElement); } - function parseArrayLiteralExpression(): ArrayLiteralExpression { + function parseArrayLiteralExpression(): ts.ArrayLiteralExpression { const pos = getNodePos(); const openBracketPosition = scanner.getTokenPos(); - const openBracketParsed = parseExpected(SyntaxKind.OpenBracketToken); + const openBracketParsed = parseExpected(ts.SyntaxKind.OpenBracketToken); const multiLine = scanner.hasPrecedingLineBreak(); const elements = parseDelimitedList(ParsingContext.ArrayLiteralMembers, parseArgumentOrArrayLiteralElement); - parseExpectedMatchingBrackets(SyntaxKind.OpenBracketToken, SyntaxKind.CloseBracketToken, openBracketParsed, openBracketPosition); + parseExpectedMatchingBrackets(ts.SyntaxKind.OpenBracketToken, ts.SyntaxKind.CloseBracketToken, openBracketParsed, openBracketPosition); return finishNode(factory.createArrayLiteralExpression(elements, multiLine), pos); } - function parseObjectLiteralElement(): ObjectLiteralElementLike { + function parseObjectLiteralElement(): ts.ObjectLiteralElementLike { const pos = getNodePos(); const hasJSDoc = hasPrecedingJSDocComment(); - if (parseOptionalToken(SyntaxKind.DotDotDotToken)) { + if (parseOptionalToken(ts.SyntaxKind.DotDotDotToken)) { const expression = parseAssignmentExpressionOrHigher(); return withJSDoc(finishNode(factory.createSpreadAssignment(expression), pos), hasJSDoc); } @@ -5834,22 +5703,21 @@ namespace ts { const decorators = parseDecorators(); const modifiers = parseModifiers(); - if (parseContextualModifier(SyntaxKind.GetKeyword)) { - return parseAccessorDeclaration(pos, hasJSDoc, decorators, modifiers, SyntaxKind.GetAccessor); + if (parseContextualModifier(ts.SyntaxKind.GetKeyword)) { + return parseAccessorDeclaration(pos, hasJSDoc, decorators, modifiers, ts.SyntaxKind.GetAccessor); } - if (parseContextualModifier(SyntaxKind.SetKeyword)) { - return parseAccessorDeclaration(pos, hasJSDoc, decorators, modifiers, SyntaxKind.SetAccessor); + if (parseContextualModifier(ts.SyntaxKind.SetKeyword)) { + return parseAccessorDeclaration(pos, hasJSDoc, decorators, modifiers, ts.SyntaxKind.SetAccessor); } - const asteriskToken = parseOptionalToken(SyntaxKind.AsteriskToken); + const asteriskToken = parseOptionalToken(ts.SyntaxKind.AsteriskToken); const tokenIsIdentifier = isIdentifier(); const name = parsePropertyName(); // Disallowing of optional property assignments and definite assignment assertion happens in the grammar checker. - const questionToken = parseOptionalToken(SyntaxKind.QuestionToken); - const exclamationToken = parseOptionalToken(SyntaxKind.ExclamationToken); - - if (asteriskToken || token() === SyntaxKind.OpenParenToken || token() === SyntaxKind.LessThanToken) { + const questionToken = parseOptionalToken(ts.SyntaxKind.QuestionToken); + const exclamationToken = parseOptionalToken(ts.SyntaxKind.ExclamationToken); + if (asteriskToken || token() === ts.SyntaxKind.OpenParenToken || token() === ts.SyntaxKind.LessThanToken) { return parseMethodDeclaration(pos, hasJSDoc, decorators, modifiers, asteriskToken, name, questionToken, exclamationToken); } @@ -5858,18 +5726,18 @@ namespace ts { // CoverInitializedName[Yield] : // IdentifierReference[?Yield] Initializer[In, ?Yield] // this is necessary because ObjectLiteral productions are also used to cover grammar for ObjectAssignmentPattern - let node: Mutable; - const isShorthandPropertyAssignment = tokenIsIdentifier && (token() !== SyntaxKind.ColonToken); + let node: ts.Mutable; + const isShorthandPropertyAssignment = tokenIsIdentifier && (token() !== ts.SyntaxKind.ColonToken); if (isShorthandPropertyAssignment) { - const equalsToken = parseOptionalToken(SyntaxKind.EqualsToken); + const equalsToken = parseOptionalToken(ts.SyntaxKind.EqualsToken); const objectAssignmentInitializer = equalsToken ? allowInAnd(parseAssignmentExpressionOrHigher) : undefined; - node = factory.createShorthandPropertyAssignment(name as Identifier, objectAssignmentInitializer); + node = factory.createShorthandPropertyAssignment(name as ts.Identifier, objectAssignmentInitializer); // Save equals token for error reporting. // TODO(rbuckton): Consider manufacturing this when we need to report an error as it is otherwise not useful. node.equalsToken = equalsToken; } else { - parseExpected(SyntaxKind.ColonToken); + parseExpected(ts.SyntaxKind.ColonToken); const initializer = allowInAnd(parseAssignmentExpressionOrHigher); node = factory.createPropertyAssignment(name, initializer); } @@ -5881,17 +5749,17 @@ namespace ts { return withJSDoc(finishNode(node, pos), hasJSDoc); } - function parseObjectLiteralExpression(): ObjectLiteralExpression { + function parseObjectLiteralExpression(): ts.ObjectLiteralExpression { const pos = getNodePos(); const openBracePosition = scanner.getTokenPos(); - const openBraceParsed = parseExpected(SyntaxKind.OpenBraceToken); + const openBraceParsed = parseExpected(ts.SyntaxKind.OpenBraceToken); const multiLine = scanner.hasPrecedingLineBreak(); const properties = parseDelimitedList(ParsingContext.ObjectLiteralMembers, parseObjectLiteralElement, /*considerSemicolonAsDelimiter*/ true); - parseExpectedMatchingBrackets(SyntaxKind.OpenBraceToken, SyntaxKind.CloseBraceToken, openBraceParsed, openBracePosition); + parseExpectedMatchingBrackets(ts.SyntaxKind.OpenBraceToken, ts.SyntaxKind.CloseBraceToken, openBraceParsed, openBracePosition); return finishNode(factory.createObjectLiteralExpression(properties, multiLine), pos); } - function parseFunctionExpression(): FunctionExpression { + function parseFunctionExpression(): ts.FunctionExpression { // GeneratorExpression: // function* BindingIdentifier [Yield][opt](FormalParameters[Yield]){ GeneratorBody } // @@ -5903,10 +5771,10 @@ namespace ts { const pos = getNodePos(); const hasJSDoc = hasPrecedingJSDocComment(); const modifiers = parseModifiers(); - parseExpected(SyntaxKind.FunctionKeyword); - const asteriskToken = parseOptionalToken(SyntaxKind.AsteriskToken); + parseExpected(ts.SyntaxKind.FunctionKeyword); + const asteriskToken = parseOptionalToken(ts.SyntaxKind.AsteriskToken); const isGenerator = asteriskToken ? SignatureFlags.Yield : SignatureFlags.None; - const isAsync = some(modifiers, isAsyncModifier) ? SignatureFlags.Await : SignatureFlags.None; + const isAsync = ts.some(modifiers, ts.isAsyncModifier) ? SignatureFlags.Await : SignatureFlags.None; const name = isGenerator && isAsync ? doInYieldAndAwaitContext(parseOptionalBindingIdentifier) : isGenerator ? doInYieldContext(parseOptionalBindingIdentifier) : isAsync ? doInAwaitContext(parseOptionalBindingIdentifier) : @@ -5914,7 +5782,7 @@ namespace ts { const typeParameters = parseTypeParameters(); const parameters = parseParameters(isGenerator | isAsync); - const type = parseReturnType(SyntaxKind.ColonToken, /*isType*/ false); + const type = parseReturnType(ts.SyntaxKind.ColonToken, /*isType*/ false); const body = parseFunctionBlock(isGenerator | isAsync); setDecoratorContext(savedDecoratorContext); @@ -5923,54 +5791,54 @@ namespace ts { return withJSDoc(finishNode(node, pos), hasJSDoc); } - function parseOptionalBindingIdentifier(): Identifier | undefined { + function parseOptionalBindingIdentifier(): ts.Identifier | undefined { return isBindingIdentifier() ? parseBindingIdentifier() : undefined; } - function parseNewExpressionOrNewDotTarget(): NewExpression | MetaProperty { + function parseNewExpressionOrNewDotTarget(): ts.NewExpression | ts.MetaProperty { const pos = getNodePos(); - parseExpected(SyntaxKind.NewKeyword); - if (parseOptional(SyntaxKind.DotToken)) { + parseExpected(ts.SyntaxKind.NewKeyword); + if (parseOptional(ts.SyntaxKind.DotToken)) { const name = parseIdentifierName(); - return finishNode(factory.createMetaProperty(SyntaxKind.NewKeyword, name), pos); + return finishNode(factory.createMetaProperty(ts.SyntaxKind.NewKeyword, name), pos); } const expressionPos = getNodePos(); - let expression: LeftHandSideExpression = parseMemberExpressionRest(expressionPos, parsePrimaryExpression(), /*allowOptionalChain*/ false); - let typeArguments: NodeArray | undefined; + let expression: ts.LeftHandSideExpression = parseMemberExpressionRest(expressionPos, parsePrimaryExpression(), /*allowOptionalChain*/ false); + let typeArguments: ts.NodeArray | undefined; // Absorb type arguments into NewExpression when preceding expression is ExpressionWithTypeArguments - if (expression.kind === SyntaxKind.ExpressionWithTypeArguments) { - typeArguments = (expression as ExpressionWithTypeArguments).typeArguments; - expression = (expression as ExpressionWithTypeArguments).expression; + if (expression.kind === ts.SyntaxKind.ExpressionWithTypeArguments) { + typeArguments = (expression as ts.ExpressionWithTypeArguments).typeArguments; + expression = (expression as ts.ExpressionWithTypeArguments).expression; } - const argumentList = token() === SyntaxKind.OpenParenToken ? parseArgumentList() : undefined; + const argumentList = token() === ts.SyntaxKind.OpenParenToken ? parseArgumentList() : undefined; return finishNode(factory.createNewExpression(expression, typeArguments, argumentList), pos); } // STATEMENTS - function parseBlock(ignoreMissingOpenBrace: boolean, diagnosticMessage?: DiagnosticMessage): Block { + function parseBlock(ignoreMissingOpenBrace: boolean, diagnosticMessage?: ts.DiagnosticMessage): ts.Block { const pos = getNodePos(); const hasJSDoc = hasPrecedingJSDocComment(); const openBracePosition = scanner.getTokenPos(); - const openBraceParsed = parseExpected(SyntaxKind.OpenBraceToken, diagnosticMessage); + const openBraceParsed = parseExpected(ts.SyntaxKind.OpenBraceToken, diagnosticMessage); if (openBraceParsed || ignoreMissingOpenBrace) { const multiLine = scanner.hasPrecedingLineBreak(); const statements = parseList(ParsingContext.BlockStatements, parseStatement); - parseExpectedMatchingBrackets(SyntaxKind.OpenBraceToken, SyntaxKind.CloseBraceToken, openBraceParsed, openBracePosition); + parseExpectedMatchingBrackets(ts.SyntaxKind.OpenBraceToken, ts.SyntaxKind.CloseBraceToken, openBraceParsed, openBracePosition); const result = withJSDoc(finishNode(factory.createBlock(statements, multiLine), pos), hasJSDoc); - if (token() === SyntaxKind.EqualsToken) { - parseErrorAtCurrentToken(Diagnostics.Declaration_or_statement_expected_This_follows_a_block_of_statements_so_if_you_intended_to_write_a_destructuring_assignment_you_might_need_to_wrap_the_the_whole_assignment_in_parentheses); + if (token() === ts.SyntaxKind.EqualsToken) { + parseErrorAtCurrentToken(ts.Diagnostics.Declaration_or_statement_expected_This_follows_a_block_of_statements_so_if_you_intended_to_write_a_destructuring_assignment_you_might_need_to_wrap_the_the_whole_assignment_in_parentheses); nextToken(); } return result; } else { - const statements = createMissingList(); + const statements = createMissingList(); return withJSDoc(finishNode(factory.createBlock(statements, /*multiLine*/ undefined), pos), hasJSDoc); } } - function parseFunctionBlock(flags: SignatureFlags, diagnosticMessage?: DiagnosticMessage): Block { + function parseFunctionBlock(flags: SignatureFlags, diagnosticMessage?: ts.DiagnosticMessage): ts.Block { const savedYieldContext = inYieldContext(); setYieldContext(!!(flags & SignatureFlags.Yield)); @@ -6000,67 +5868,66 @@ namespace ts { return block; } - function parseEmptyStatement(): Statement { + function parseEmptyStatement(): ts.Statement { const pos = getNodePos(); const hasJSDoc = hasPrecedingJSDocComment(); - parseExpected(SyntaxKind.SemicolonToken); + parseExpected(ts.SyntaxKind.SemicolonToken); return withJSDoc(finishNode(factory.createEmptyStatement(), pos), hasJSDoc); } - function parseIfStatement(): IfStatement { + function parseIfStatement(): ts.IfStatement { const pos = getNodePos(); const hasJSDoc = hasPrecedingJSDocComment(); - parseExpected(SyntaxKind.IfKeyword); + parseExpected(ts.SyntaxKind.IfKeyword); const openParenPosition = scanner.getTokenPos(); - const openParenParsed = parseExpected(SyntaxKind.OpenParenToken); + const openParenParsed = parseExpected(ts.SyntaxKind.OpenParenToken); const expression = allowInAnd(parseExpression); - parseExpectedMatchingBrackets(SyntaxKind.OpenParenToken, SyntaxKind.CloseParenToken, openParenParsed, openParenPosition); + parseExpectedMatchingBrackets(ts.SyntaxKind.OpenParenToken, ts.SyntaxKind.CloseParenToken, openParenParsed, openParenPosition); const thenStatement = parseStatement(); - const elseStatement = parseOptional(SyntaxKind.ElseKeyword) ? parseStatement() : undefined; + const elseStatement = parseOptional(ts.SyntaxKind.ElseKeyword) ? parseStatement() : undefined; return withJSDoc(finishNode(factory.createIfStatement(expression, thenStatement, elseStatement), pos), hasJSDoc); } - function parseDoStatement(): DoStatement { + function parseDoStatement(): ts.DoStatement { const pos = getNodePos(); const hasJSDoc = hasPrecedingJSDocComment(); - parseExpected(SyntaxKind.DoKeyword); + parseExpected(ts.SyntaxKind.DoKeyword); const statement = parseStatement(); - parseExpected(SyntaxKind.WhileKeyword); + parseExpected(ts.SyntaxKind.WhileKeyword); const openParenPosition = scanner.getTokenPos(); - const openParenParsed = parseExpected(SyntaxKind.OpenParenToken); + const openParenParsed = parseExpected(ts.SyntaxKind.OpenParenToken); const expression = allowInAnd(parseExpression); - parseExpectedMatchingBrackets(SyntaxKind.OpenParenToken, SyntaxKind.CloseParenToken, openParenParsed, openParenPosition); + parseExpectedMatchingBrackets(ts.SyntaxKind.OpenParenToken, ts.SyntaxKind.CloseParenToken, openParenParsed, openParenPosition); // From: https://mail.mozilla.org/pipermail/es-discuss/2011-August/016188.html // 157 min --- All allen at wirfs-brock.com CONF --- "do{;}while(false)false" prohibited in // spec but allowed in consensus reality. Approved -- this is the de-facto standard whereby // do;while(0)x will have a semicolon inserted before x. - parseOptional(SyntaxKind.SemicolonToken); + parseOptional(ts.SyntaxKind.SemicolonToken); return withJSDoc(finishNode(factory.createDoStatement(statement, expression), pos), hasJSDoc); } - function parseWhileStatement(): WhileStatement { + function parseWhileStatement(): ts.WhileStatement { const pos = getNodePos(); const hasJSDoc = hasPrecedingJSDocComment(); - parseExpected(SyntaxKind.WhileKeyword); + parseExpected(ts.SyntaxKind.WhileKeyword); const openParenPosition = scanner.getTokenPos(); - const openParenParsed = parseExpected(SyntaxKind.OpenParenToken); + const openParenParsed = parseExpected(ts.SyntaxKind.OpenParenToken); const expression = allowInAnd(parseExpression); - parseExpectedMatchingBrackets(SyntaxKind.OpenParenToken, SyntaxKind.CloseParenToken, openParenParsed, openParenPosition); + parseExpectedMatchingBrackets(ts.SyntaxKind.OpenParenToken, ts.SyntaxKind.CloseParenToken, openParenParsed, openParenPosition); const statement = parseStatement(); return withJSDoc(finishNode(factory.createWhileStatement(expression, statement), pos), hasJSDoc); } - function parseForOrForInOrForOfStatement(): Statement { + function parseForOrForInOrForOfStatement(): ts.Statement { const pos = getNodePos(); const hasJSDoc = hasPrecedingJSDocComment(); - parseExpected(SyntaxKind.ForKeyword); - const awaitToken = parseOptionalToken(SyntaxKind.AwaitKeyword); - parseExpected(SyntaxKind.OpenParenToken); - - let initializer!: VariableDeclarationList | Expression; - if (token() !== SyntaxKind.SemicolonToken) { - if (token() === SyntaxKind.VarKeyword || token() === SyntaxKind.LetKeyword || token() === SyntaxKind.ConstKeyword) { + parseExpected(ts.SyntaxKind.ForKeyword); + const awaitToken = parseOptionalToken(ts.SyntaxKind.AwaitKeyword); + parseExpected(ts.SyntaxKind.OpenParenToken); + let initializer!: ts.VariableDeclarationList | ts.Expression; + if (token() !== ts.SyntaxKind.SemicolonToken) { + if (token() === ts.SyntaxKind.VarKeyword || token() === ts.SyntaxKind.LetKeyword || token() === ts.SyntaxKind.ConstKeyword) { initializer = parseVariableDeclarationList(/*inForStatementInitializer*/ true); } else { @@ -6068,116 +5935,116 @@ namespace ts { } } - let node: IterationStatement; - if (awaitToken ? parseExpected(SyntaxKind.OfKeyword) : parseOptional(SyntaxKind.OfKeyword)) { + let node: ts.IterationStatement; + if (awaitToken ? parseExpected(ts.SyntaxKind.OfKeyword) : parseOptional(ts.SyntaxKind.OfKeyword)) { const expression = allowInAnd(parseAssignmentExpressionOrHigher); - parseExpected(SyntaxKind.CloseParenToken); + parseExpected(ts.SyntaxKind.CloseParenToken); node = factory.createForOfStatement(awaitToken, initializer, expression, parseStatement()); } - else if (parseOptional(SyntaxKind.InKeyword)) { + else if (parseOptional(ts.SyntaxKind.InKeyword)) { const expression = allowInAnd(parseExpression); - parseExpected(SyntaxKind.CloseParenToken); + parseExpected(ts.SyntaxKind.CloseParenToken); node = factory.createForInStatement(initializer, expression, parseStatement()); } else { - parseExpected(SyntaxKind.SemicolonToken); - const condition = token() !== SyntaxKind.SemicolonToken && token() !== SyntaxKind.CloseParenToken + parseExpected(ts.SyntaxKind.SemicolonToken); + const condition = token() !== ts.SyntaxKind.SemicolonToken && token() !== ts.SyntaxKind.CloseParenToken ? allowInAnd(parseExpression) : undefined; - parseExpected(SyntaxKind.SemicolonToken); - const incrementor = token() !== SyntaxKind.CloseParenToken + parseExpected(ts.SyntaxKind.SemicolonToken); + const incrementor = token() !== ts.SyntaxKind.CloseParenToken ? allowInAnd(parseExpression) : undefined; - parseExpected(SyntaxKind.CloseParenToken); + parseExpected(ts.SyntaxKind.CloseParenToken); node = factory.createForStatement(initializer, condition, incrementor, parseStatement()); } - return withJSDoc(finishNode(node, pos) as ForStatement | ForInOrOfStatement, hasJSDoc); + return withJSDoc(finishNode(node, pos) as ts.ForStatement | ts.ForInOrOfStatement, hasJSDoc); } - function parseBreakOrContinueStatement(kind: SyntaxKind): BreakOrContinueStatement { + function parseBreakOrContinueStatement(kind: ts.SyntaxKind): ts.BreakOrContinueStatement { const pos = getNodePos(); const hasJSDoc = hasPrecedingJSDocComment(); - parseExpected(kind === SyntaxKind.BreakStatement ? SyntaxKind.BreakKeyword : SyntaxKind.ContinueKeyword); + parseExpected(kind === ts.SyntaxKind.BreakStatement ? ts.SyntaxKind.BreakKeyword : ts.SyntaxKind.ContinueKeyword); const label = canParseSemicolon() ? undefined : parseIdentifier(); parseSemicolon(); - const node = kind === SyntaxKind.BreakStatement + const node = kind === ts.SyntaxKind.BreakStatement ? factory.createBreakStatement(label) : factory.createContinueStatement(label); return withJSDoc(finishNode(node, pos), hasJSDoc); } - function parseReturnStatement(): ReturnStatement { + function parseReturnStatement(): ts.ReturnStatement { const pos = getNodePos(); const hasJSDoc = hasPrecedingJSDocComment(); - parseExpected(SyntaxKind.ReturnKeyword); + parseExpected(ts.SyntaxKind.ReturnKeyword); const expression = canParseSemicolon() ? undefined : allowInAnd(parseExpression); parseSemicolon(); return withJSDoc(finishNode(factory.createReturnStatement(expression), pos), hasJSDoc); } - function parseWithStatement(): WithStatement { + function parseWithStatement(): ts.WithStatement { const pos = getNodePos(); const hasJSDoc = hasPrecedingJSDocComment(); - parseExpected(SyntaxKind.WithKeyword); + parseExpected(ts.SyntaxKind.WithKeyword); const openParenPosition = scanner.getTokenPos(); - const openParenParsed = parseExpected(SyntaxKind.OpenParenToken); + const openParenParsed = parseExpected(ts.SyntaxKind.OpenParenToken); const expression = allowInAnd(parseExpression); - parseExpectedMatchingBrackets(SyntaxKind.OpenParenToken, SyntaxKind.CloseParenToken, openParenParsed, openParenPosition); - const statement = doInsideOfContext(NodeFlags.InWithStatement, parseStatement); + parseExpectedMatchingBrackets(ts.SyntaxKind.OpenParenToken, ts.SyntaxKind.CloseParenToken, openParenParsed, openParenPosition); + const statement = doInsideOfContext(ts.NodeFlags.InWithStatement, parseStatement); return withJSDoc(finishNode(factory.createWithStatement(expression, statement), pos), hasJSDoc); } - function parseCaseClause(): CaseClause { + function parseCaseClause(): ts.CaseClause { const pos = getNodePos(); const hasJSDoc = hasPrecedingJSDocComment(); - parseExpected(SyntaxKind.CaseKeyword); + parseExpected(ts.SyntaxKind.CaseKeyword); const expression = allowInAnd(parseExpression); - parseExpected(SyntaxKind.ColonToken); + parseExpected(ts.SyntaxKind.ColonToken); const statements = parseList(ParsingContext.SwitchClauseStatements, parseStatement); return withJSDoc(finishNode(factory.createCaseClause(expression, statements), pos), hasJSDoc); } - function parseDefaultClause(): DefaultClause { + function parseDefaultClause(): ts.DefaultClause { const pos = getNodePos(); - parseExpected(SyntaxKind.DefaultKeyword); - parseExpected(SyntaxKind.ColonToken); + parseExpected(ts.SyntaxKind.DefaultKeyword); + parseExpected(ts.SyntaxKind.ColonToken); const statements = parseList(ParsingContext.SwitchClauseStatements, parseStatement); return finishNode(factory.createDefaultClause(statements), pos); } - function parseCaseOrDefaultClause(): CaseOrDefaultClause { - return token() === SyntaxKind.CaseKeyword ? parseCaseClause() : parseDefaultClause(); + function parseCaseOrDefaultClause(): ts.CaseOrDefaultClause { + return token() === ts.SyntaxKind.CaseKeyword ? parseCaseClause() : parseDefaultClause(); } - function parseCaseBlock(): CaseBlock { + function parseCaseBlock(): ts.CaseBlock { const pos = getNodePos(); - parseExpected(SyntaxKind.OpenBraceToken); + parseExpected(ts.SyntaxKind.OpenBraceToken); const clauses = parseList(ParsingContext.SwitchClauses, parseCaseOrDefaultClause); - parseExpected(SyntaxKind.CloseBraceToken); + parseExpected(ts.SyntaxKind.CloseBraceToken); return finishNode(factory.createCaseBlock(clauses), pos); } - function parseSwitchStatement(): SwitchStatement { + function parseSwitchStatement(): ts.SwitchStatement { const pos = getNodePos(); const hasJSDoc = hasPrecedingJSDocComment(); - parseExpected(SyntaxKind.SwitchKeyword); - parseExpected(SyntaxKind.OpenParenToken); + parseExpected(ts.SyntaxKind.SwitchKeyword); + parseExpected(ts.SyntaxKind.OpenParenToken); const expression = allowInAnd(parseExpression); - parseExpected(SyntaxKind.CloseParenToken); + parseExpected(ts.SyntaxKind.CloseParenToken); const caseBlock = parseCaseBlock(); return withJSDoc(finishNode(factory.createSwitchStatement(expression, caseBlock), pos), hasJSDoc); } - function parseThrowStatement(): ThrowStatement { + function parseThrowStatement(): ts.ThrowStatement { // ThrowStatement[Yield] : // throw [no LineTerminator here]Expression[In, ?Yield]; const pos = getNodePos(); const hasJSDoc = hasPrecedingJSDocComment(); - parseExpected(SyntaxKind.ThrowKeyword); + parseExpected(ts.SyntaxKind.ThrowKeyword); // Because of automatic semicolon insertion, we need to report error if this // throw could be terminated with a semicolon. Note: we can't call 'parseExpression' @@ -6196,33 +6063,33 @@ namespace ts { } // TODO: Review for error recovery - function parseTryStatement(): TryStatement { + function parseTryStatement(): ts.TryStatement { const pos = getNodePos(); const hasJSDoc = hasPrecedingJSDocComment(); - parseExpected(SyntaxKind.TryKeyword); + parseExpected(ts.SyntaxKind.TryKeyword); const tryBlock = parseBlock(/*ignoreMissingOpenBrace*/ false); - const catchClause = token() === SyntaxKind.CatchKeyword ? parseCatchClause() : undefined; + const catchClause = token() === ts.SyntaxKind.CatchKeyword ? parseCatchClause() : undefined; // If we don't have a catch clause, then we must have a finally clause. Try to parse // one out no matter what. - let finallyBlock: Block | undefined; - if (!catchClause || token() === SyntaxKind.FinallyKeyword) { - parseExpected(SyntaxKind.FinallyKeyword, Diagnostics.catch_or_finally_expected); + let finallyBlock: ts.Block | undefined; + if (!catchClause || token() === ts.SyntaxKind.FinallyKeyword) { + parseExpected(ts.SyntaxKind.FinallyKeyword, ts.Diagnostics.catch_or_finally_expected); finallyBlock = parseBlock(/*ignoreMissingOpenBrace*/ false); } return withJSDoc(finishNode(factory.createTryStatement(tryBlock, catchClause, finallyBlock), pos), hasJSDoc); } - function parseCatchClause(): CatchClause { + function parseCatchClause(): ts.CatchClause { const pos = getNodePos(); - parseExpected(SyntaxKind.CatchKeyword); + parseExpected(ts.SyntaxKind.CatchKeyword); let variableDeclaration; - if (parseOptional(SyntaxKind.OpenParenToken)) { + if (parseOptional(ts.SyntaxKind.OpenParenToken)) { variableDeclaration = parseVariableDeclaration(); - parseExpected(SyntaxKind.CloseParenToken); + parseExpected(ts.SyntaxKind.CloseParenToken); } else { // Keep shape of node to avoid degrading performance. @@ -6233,24 +6100,24 @@ namespace ts { return finishNode(factory.createCatchClause(variableDeclaration, block), pos); } - function parseDebuggerStatement(): Statement { + function parseDebuggerStatement(): ts.Statement { const pos = getNodePos(); const hasJSDoc = hasPrecedingJSDocComment(); - parseExpected(SyntaxKind.DebuggerKeyword); + parseExpected(ts.SyntaxKind.DebuggerKeyword); parseSemicolon(); return withJSDoc(finishNode(factory.createDebuggerStatement(), pos), hasJSDoc); } - function parseExpressionOrLabeledStatement(): ExpressionStatement | LabeledStatement { + function parseExpressionOrLabeledStatement(): ts.ExpressionStatement | ts.LabeledStatement { // Avoiding having to do the lookahead for a labeled statement by just trying to parse // out an expression, seeing if it is identifier and then seeing if it is followed by // a colon. const pos = getNodePos(); let hasJSDoc = hasPrecedingJSDocComment(); - let node: ExpressionStatement | LabeledStatement; - const hasParen = token() === SyntaxKind.OpenParenToken; + let node: ts.ExpressionStatement | ts.LabeledStatement; + const hasParen = token() === ts.SyntaxKind.OpenParenToken; const expression = allowInAnd(parseExpression); - if (ts.isIdentifier(expression) && parseOptional(SyntaxKind.ColonToken)) { + if (ts.isIdentifier(expression) && parseOptional(ts.SyntaxKind.ColonToken)) { node = factory.createLabeledStatement(expression, parseStatement()); } else { @@ -6268,33 +6135,33 @@ namespace ts { function nextTokenIsIdentifierOrKeywordOnSameLine() { nextToken(); - return tokenIsIdentifierOrKeyword(token()) && !scanner.hasPrecedingLineBreak(); + return ts.tokenIsIdentifierOrKeyword(token()) && !scanner.hasPrecedingLineBreak(); } function nextTokenIsClassKeywordOnSameLine() { nextToken(); - return token() === SyntaxKind.ClassKeyword && !scanner.hasPrecedingLineBreak(); + return token() === ts.SyntaxKind.ClassKeyword && !scanner.hasPrecedingLineBreak(); } function nextTokenIsFunctionKeywordOnSameLine() { nextToken(); - return token() === SyntaxKind.FunctionKeyword && !scanner.hasPrecedingLineBreak(); + return token() === ts.SyntaxKind.FunctionKeyword && !scanner.hasPrecedingLineBreak(); } function nextTokenIsIdentifierOrKeywordOrLiteralOnSameLine() { nextToken(); - return (tokenIsIdentifierOrKeyword(token()) || token() === SyntaxKind.NumericLiteral || token() === SyntaxKind.BigIntLiteral || token() === SyntaxKind.StringLiteral) && !scanner.hasPrecedingLineBreak(); + return (ts.tokenIsIdentifierOrKeyword(token()) || token() === ts.SyntaxKind.NumericLiteral || token() === ts.SyntaxKind.BigIntLiteral || token() === ts.SyntaxKind.StringLiteral) && !scanner.hasPrecedingLineBreak(); } function isDeclaration(): boolean { while (true) { switch (token()) { - case SyntaxKind.VarKeyword: - case SyntaxKind.LetKeyword: - case SyntaxKind.ConstKeyword: - case SyntaxKind.FunctionKeyword: - case SyntaxKind.ClassKeyword: - case SyntaxKind.EnumKeyword: + case ts.SyntaxKind.VarKeyword: + case ts.SyntaxKind.LetKeyword: + case ts.SyntaxKind.ConstKeyword: + case ts.SyntaxKind.FunctionKeyword: + case ts.SyntaxKind.ClassKeyword: + case ts.SyntaxKind.EnumKeyword: return true; // 'declare', 'module', 'namespace', 'interface'* and 'type' are all legal JavaScript identifiers; @@ -6318,19 +6185,19 @@ namespace ts { // I {} // // could be legal, it would add complexity for very little gain. - case SyntaxKind.InterfaceKeyword: - case SyntaxKind.TypeKeyword: + case ts.SyntaxKind.InterfaceKeyword: + case ts.SyntaxKind.TypeKeyword: return nextTokenIsIdentifierOnSameLine(); - case SyntaxKind.ModuleKeyword: - case SyntaxKind.NamespaceKeyword: + case ts.SyntaxKind.ModuleKeyword: + case ts.SyntaxKind.NamespaceKeyword: return nextTokenIsIdentifierOrStringLiteralOnSameLine(); - case SyntaxKind.AbstractKeyword: - case SyntaxKind.AsyncKeyword: - case SyntaxKind.DeclareKeyword: - case SyntaxKind.PrivateKeyword: - case SyntaxKind.ProtectedKeyword: - case SyntaxKind.PublicKeyword: - case SyntaxKind.ReadonlyKeyword: + case ts.SyntaxKind.AbstractKeyword: + case ts.SyntaxKind.AsyncKeyword: + case ts.SyntaxKind.DeclareKeyword: + case ts.SyntaxKind.PrivateKeyword: + case ts.SyntaxKind.ProtectedKeyword: + case ts.SyntaxKind.PublicKeyword: + case ts.SyntaxKind.ReadonlyKeyword: nextToken(); // ASI takes effect for this modifier. if (scanner.hasPrecedingLineBreak()) { @@ -6338,27 +6205,26 @@ namespace ts { } continue; - case SyntaxKind.GlobalKeyword: + case ts.SyntaxKind.GlobalKeyword: nextToken(); - return token() === SyntaxKind.OpenBraceToken || token() === SyntaxKind.Identifier || token() === SyntaxKind.ExportKeyword; - - case SyntaxKind.ImportKeyword: + return token() === ts.SyntaxKind.OpenBraceToken || token() === ts.SyntaxKind.Identifier || token() === ts.SyntaxKind.ExportKeyword; + case ts.SyntaxKind.ImportKeyword: nextToken(); - return token() === SyntaxKind.StringLiteral || token() === SyntaxKind.AsteriskToken || - token() === SyntaxKind.OpenBraceToken || tokenIsIdentifierOrKeyword(token()); - case SyntaxKind.ExportKeyword: + return token() === ts.SyntaxKind.StringLiteral || token() === ts.SyntaxKind.AsteriskToken || + token() === ts.SyntaxKind.OpenBraceToken || ts.tokenIsIdentifierOrKeyword(token()); + case ts.SyntaxKind.ExportKeyword: let currentToken = nextToken(); - if (currentToken === SyntaxKind.TypeKeyword) { + if (currentToken === ts.SyntaxKind.TypeKeyword) { currentToken = lookAhead(nextToken); } - if (currentToken === SyntaxKind.EqualsToken || currentToken === SyntaxKind.AsteriskToken || - currentToken === SyntaxKind.OpenBraceToken || currentToken === SyntaxKind.DefaultKeyword || - currentToken === SyntaxKind.AsKeyword) { + if (currentToken === ts.SyntaxKind.EqualsToken || currentToken === ts.SyntaxKind.AsteriskToken || + currentToken === ts.SyntaxKind.OpenBraceToken || currentToken === ts.SyntaxKind.DefaultKeyword || + currentToken === ts.SyntaxKind.AsKeyword) { return true; } continue; - case SyntaxKind.StaticKeyword: + case ts.SyntaxKind.StaticKeyword: nextToken(); continue; default: @@ -6373,55 +6239,55 @@ namespace ts { function isStartOfStatement(): boolean { switch (token()) { - case SyntaxKind.AtToken: - case SyntaxKind.SemicolonToken: - case SyntaxKind.OpenBraceToken: - case SyntaxKind.VarKeyword: - case SyntaxKind.LetKeyword: - case SyntaxKind.FunctionKeyword: - case SyntaxKind.ClassKeyword: - case SyntaxKind.EnumKeyword: - case SyntaxKind.IfKeyword: - case SyntaxKind.DoKeyword: - case SyntaxKind.WhileKeyword: - case SyntaxKind.ForKeyword: - case SyntaxKind.ContinueKeyword: - case SyntaxKind.BreakKeyword: - case SyntaxKind.ReturnKeyword: - case SyntaxKind.WithKeyword: - case SyntaxKind.SwitchKeyword: - case SyntaxKind.ThrowKeyword: - case SyntaxKind.TryKeyword: - case SyntaxKind.DebuggerKeyword: + case ts.SyntaxKind.AtToken: + case ts.SyntaxKind.SemicolonToken: + case ts.SyntaxKind.OpenBraceToken: + case ts.SyntaxKind.VarKeyword: + case ts.SyntaxKind.LetKeyword: + case ts.SyntaxKind.FunctionKeyword: + case ts.SyntaxKind.ClassKeyword: + case ts.SyntaxKind.EnumKeyword: + case ts.SyntaxKind.IfKeyword: + case ts.SyntaxKind.DoKeyword: + case ts.SyntaxKind.WhileKeyword: + case ts.SyntaxKind.ForKeyword: + case ts.SyntaxKind.ContinueKeyword: + case ts.SyntaxKind.BreakKeyword: + case ts.SyntaxKind.ReturnKeyword: + case ts.SyntaxKind.WithKeyword: + case ts.SyntaxKind.SwitchKeyword: + case ts.SyntaxKind.ThrowKeyword: + case ts.SyntaxKind.TryKeyword: + case ts.SyntaxKind.DebuggerKeyword: // 'catch' and 'finally' do not actually indicate that the code is part of a statement, // however, we say they are here so that we may gracefully parse them and error later. // falls through - case SyntaxKind.CatchKeyword: - case SyntaxKind.FinallyKeyword: + case ts.SyntaxKind.CatchKeyword: + case ts.SyntaxKind.FinallyKeyword: return true; - case SyntaxKind.ImportKeyword: + case ts.SyntaxKind.ImportKeyword: return isStartOfDeclaration() || lookAhead(nextTokenIsOpenParenOrLessThanOrDot); - case SyntaxKind.ConstKeyword: - case SyntaxKind.ExportKeyword: + case ts.SyntaxKind.ConstKeyword: + case ts.SyntaxKind.ExportKeyword: return isStartOfDeclaration(); - case SyntaxKind.AsyncKeyword: - case SyntaxKind.DeclareKeyword: - case SyntaxKind.InterfaceKeyword: - case SyntaxKind.ModuleKeyword: - case SyntaxKind.NamespaceKeyword: - case SyntaxKind.TypeKeyword: - case SyntaxKind.GlobalKeyword: + case ts.SyntaxKind.AsyncKeyword: + case ts.SyntaxKind.DeclareKeyword: + case ts.SyntaxKind.InterfaceKeyword: + case ts.SyntaxKind.ModuleKeyword: + case ts.SyntaxKind.NamespaceKeyword: + case ts.SyntaxKind.TypeKeyword: + case ts.SyntaxKind.GlobalKeyword: // When these don't start a declaration, they're an identifier in an expression statement return true; - case SyntaxKind.PublicKeyword: - case SyntaxKind.PrivateKeyword: - case SyntaxKind.ProtectedKeyword: - case SyntaxKind.StaticKeyword: - case SyntaxKind.ReadonlyKeyword: + case ts.SyntaxKind.PublicKeyword: + case ts.SyntaxKind.PrivateKeyword: + case ts.SyntaxKind.ProtectedKeyword: + case ts.SyntaxKind.StaticKeyword: + case ts.SyntaxKind.ReadonlyKeyword: // When these don't start a declaration, they may be the start of a class member if an identifier // immediately follows. Otherwise they're an identifier in an expression statement. return isStartOfDeclaration() || !lookAhead(nextTokenIsIdentifierOrKeywordOnSameLine); @@ -6433,7 +6299,7 @@ namespace ts { function nextTokenIsBindingIdentifierOrStartOfDestructuring() { nextToken(); - return isBindingIdentifier() || token() === SyntaxKind.OpenBraceToken || token() === SyntaxKind.OpenBracketToken; + return isBindingIdentifier() || token() === ts.SyntaxKind.OpenBraceToken || token() === ts.SyntaxKind.OpenBracketToken; } function isLetDeclaration() { @@ -6442,70 +6308,70 @@ namespace ts { return lookAhead(nextTokenIsBindingIdentifierOrStartOfDestructuring); } - function parseStatement(): Statement { + function parseStatement(): ts.Statement { switch (token()) { - case SyntaxKind.SemicolonToken: + case ts.SyntaxKind.SemicolonToken: return parseEmptyStatement(); - case SyntaxKind.OpenBraceToken: + case ts.SyntaxKind.OpenBraceToken: return parseBlock(/*ignoreMissingOpenBrace*/ false); - case SyntaxKind.VarKeyword: + case ts.SyntaxKind.VarKeyword: return parseVariableStatement(getNodePos(), hasPrecedingJSDocComment(), /*decorators*/ undefined, /*modifiers*/ undefined); - case SyntaxKind.LetKeyword: + case ts.SyntaxKind.LetKeyword: if (isLetDeclaration()) { return parseVariableStatement(getNodePos(), hasPrecedingJSDocComment(), /*decorators*/ undefined, /*modifiers*/ undefined); } break; - case SyntaxKind.FunctionKeyword: + case ts.SyntaxKind.FunctionKeyword: return parseFunctionDeclaration(getNodePos(), hasPrecedingJSDocComment(), /*decorators*/ undefined, /*modifiers*/ undefined); - case SyntaxKind.ClassKeyword: + case ts.SyntaxKind.ClassKeyword: return parseClassDeclaration(getNodePos(), hasPrecedingJSDocComment(), /*decorators*/ undefined, /*modifiers*/ undefined); - case SyntaxKind.IfKeyword: + case ts.SyntaxKind.IfKeyword: return parseIfStatement(); - case SyntaxKind.DoKeyword: + case ts.SyntaxKind.DoKeyword: return parseDoStatement(); - case SyntaxKind.WhileKeyword: + case ts.SyntaxKind.WhileKeyword: return parseWhileStatement(); - case SyntaxKind.ForKeyword: + case ts.SyntaxKind.ForKeyword: return parseForOrForInOrForOfStatement(); - case SyntaxKind.ContinueKeyword: - return parseBreakOrContinueStatement(SyntaxKind.ContinueStatement); - case SyntaxKind.BreakKeyword: - return parseBreakOrContinueStatement(SyntaxKind.BreakStatement); - case SyntaxKind.ReturnKeyword: + case ts.SyntaxKind.ContinueKeyword: + return parseBreakOrContinueStatement(ts.SyntaxKind.ContinueStatement); + case ts.SyntaxKind.BreakKeyword: + return parseBreakOrContinueStatement(ts.SyntaxKind.BreakStatement); + case ts.SyntaxKind.ReturnKeyword: return parseReturnStatement(); - case SyntaxKind.WithKeyword: + case ts.SyntaxKind.WithKeyword: return parseWithStatement(); - case SyntaxKind.SwitchKeyword: + case ts.SyntaxKind.SwitchKeyword: return parseSwitchStatement(); - case SyntaxKind.ThrowKeyword: + case ts.SyntaxKind.ThrowKeyword: return parseThrowStatement(); - case SyntaxKind.TryKeyword: + case ts.SyntaxKind.TryKeyword: // Include 'catch' and 'finally' for error recovery. // falls through - case SyntaxKind.CatchKeyword: - case SyntaxKind.FinallyKeyword: + case ts.SyntaxKind.CatchKeyword: + case ts.SyntaxKind.FinallyKeyword: return parseTryStatement(); - case SyntaxKind.DebuggerKeyword: + case ts.SyntaxKind.DebuggerKeyword: return parseDebuggerStatement(); - case SyntaxKind.AtToken: + case ts.SyntaxKind.AtToken: return parseDeclaration(); - case SyntaxKind.AsyncKeyword: - case SyntaxKind.InterfaceKeyword: - case SyntaxKind.TypeKeyword: - case SyntaxKind.ModuleKeyword: - case SyntaxKind.NamespaceKeyword: - case SyntaxKind.DeclareKeyword: - case SyntaxKind.ConstKeyword: - case SyntaxKind.EnumKeyword: - case SyntaxKind.ExportKeyword: - case SyntaxKind.ImportKeyword: - case SyntaxKind.PrivateKeyword: - case SyntaxKind.ProtectedKeyword: - case SyntaxKind.PublicKeyword: - case SyntaxKind.AbstractKeyword: - case SyntaxKind.StaticKeyword: - case SyntaxKind.ReadonlyKeyword: - case SyntaxKind.GlobalKeyword: + case ts.SyntaxKind.AsyncKeyword: + case ts.SyntaxKind.InterfaceKeyword: + case ts.SyntaxKind.TypeKeyword: + case ts.SyntaxKind.ModuleKeyword: + case ts.SyntaxKind.NamespaceKeyword: + case ts.SyntaxKind.DeclareKeyword: + case ts.SyntaxKind.ConstKeyword: + case ts.SyntaxKind.EnumKeyword: + case ts.SyntaxKind.ExportKeyword: + case ts.SyntaxKind.ImportKeyword: + case ts.SyntaxKind.PrivateKeyword: + case ts.SyntaxKind.ProtectedKeyword: + case ts.SyntaxKind.PublicKeyword: + case ts.SyntaxKind.AbstractKeyword: + case ts.SyntaxKind.StaticKeyword: + case ts.SyntaxKind.ReadonlyKeyword: + case ts.SyntaxKind.GlobalKeyword: if (isStartOfDeclaration()) { return parseDeclaration(); } @@ -6514,18 +6380,18 @@ namespace ts { return parseExpressionOrLabeledStatement(); } - function isDeclareModifier(modifier: Modifier) { - return modifier.kind === SyntaxKind.DeclareKeyword; + function isDeclareModifier(modifier: ts.Modifier) { + return modifier.kind === ts.SyntaxKind.DeclareKeyword; } - function parseDeclaration(): Statement { + function parseDeclaration(): ts.Statement { // TODO: Can we hold onto the parsed decorators/modifiers and advance the scanner // if we can't reuse the declaration, so that we don't do this work twice? // // `parseListElement` attempted to get the reused node at this position, // but the ambient context flag was not yet set, so the node appeared // not reusable in that context. - const isAmbient = some(lookAhead(() => (parseDecorators(), parseModifiers())), isDeclareModifier); + const isAmbient = ts.some(lookAhead(() => (parseDecorators(), parseModifiers())), isDeclareModifier); if (isAmbient) { const node = tryReuseAmbientDeclaration(); if (node) { @@ -6539,53 +6405,53 @@ namespace ts { const modifiers = parseModifiers(); if (isAmbient) { for (const m of modifiers!) { - (m as Mutable).flags |= NodeFlags.Ambient; + (m as ts.Mutable).flags |= ts.NodeFlags.Ambient; } - return doInsideOfContext(NodeFlags.Ambient, () => parseDeclarationWorker(pos, hasJSDoc, decorators, modifiers)); + return doInsideOfContext(ts.NodeFlags.Ambient, () => parseDeclarationWorker(pos, hasJSDoc, decorators, modifiers)); } else { return parseDeclarationWorker(pos, hasJSDoc, decorators, modifiers); } } - function tryReuseAmbientDeclaration(): Statement | undefined { - return doInsideOfContext(NodeFlags.Ambient, () => { + function tryReuseAmbientDeclaration(): ts.Statement | undefined { + return doInsideOfContext(ts.NodeFlags.Ambient, () => { const node = currentNode(parsingContext); if (node) { - return consumeNode(node) as Statement; + return consumeNode(node) as ts.Statement; } }); } - function parseDeclarationWorker(pos: number, hasJSDoc: boolean, decorators: NodeArray | undefined, modifiers: NodeArray | undefined): Statement { + function parseDeclarationWorker(pos: number, hasJSDoc: boolean, decorators: ts.NodeArray | undefined, modifiers: ts.NodeArray | undefined): ts.Statement { switch (token()) { - case SyntaxKind.VarKeyword: - case SyntaxKind.LetKeyword: - case SyntaxKind.ConstKeyword: + case ts.SyntaxKind.VarKeyword: + case ts.SyntaxKind.LetKeyword: + case ts.SyntaxKind.ConstKeyword: return parseVariableStatement(pos, hasJSDoc, decorators, modifiers); - case SyntaxKind.FunctionKeyword: + case ts.SyntaxKind.FunctionKeyword: return parseFunctionDeclaration(pos, hasJSDoc, decorators, modifiers); - case SyntaxKind.ClassKeyword: + case ts.SyntaxKind.ClassKeyword: return parseClassDeclaration(pos, hasJSDoc, decorators, modifiers); - case SyntaxKind.InterfaceKeyword: + case ts.SyntaxKind.InterfaceKeyword: return parseInterfaceDeclaration(pos, hasJSDoc, decorators, modifiers); - case SyntaxKind.TypeKeyword: + case ts.SyntaxKind.TypeKeyword: return parseTypeAliasDeclaration(pos, hasJSDoc, decorators, modifiers); - case SyntaxKind.EnumKeyword: + case ts.SyntaxKind.EnumKeyword: return parseEnumDeclaration(pos, hasJSDoc, decorators, modifiers); - case SyntaxKind.GlobalKeyword: - case SyntaxKind.ModuleKeyword: - case SyntaxKind.NamespaceKeyword: + case ts.SyntaxKind.GlobalKeyword: + case ts.SyntaxKind.ModuleKeyword: + case ts.SyntaxKind.NamespaceKeyword: return parseModuleDeclaration(pos, hasJSDoc, decorators, modifiers); - case SyntaxKind.ImportKeyword: + case ts.SyntaxKind.ImportKeyword: return parseImportDeclarationOrImportEqualsDeclaration(pos, hasJSDoc, decorators, modifiers); - case SyntaxKind.ExportKeyword: + case ts.SyntaxKind.ExportKeyword: nextToken(); switch (token()) { - case SyntaxKind.DefaultKeyword: - case SyntaxKind.EqualsToken: + case ts.SyntaxKind.DefaultKeyword: + case ts.SyntaxKind.EqualsToken: return parseExportAssignment(pos, hasJSDoc, decorators, modifiers); - case SyntaxKind.AsKeyword: + case ts.SyntaxKind.AsKeyword: return parseNamespaceExportDeclaration(pos, hasJSDoc, decorators, modifiers); default: return parseExportDeclaration(pos, hasJSDoc, decorators, modifiers); @@ -6594,8 +6460,8 @@ namespace ts { if (decorators || modifiers) { // We reached this point because we encountered decorators and/or modifiers and assumed a declaration // would follow. For recovery and error reporting purposes, return an incomplete declaration. - const missing = createMissingNode(SyntaxKind.MissingDeclaration, /*reportAtCurrentPosition*/ true, Diagnostics.Declaration_expected); - setTextRangePos(missing, pos); + const missing = createMissingNode(ts.SyntaxKind.MissingDeclaration, /*reportAtCurrentPosition*/ true, ts.Diagnostics.Declaration_expected); + ts.setTextRangePos(missing, pos); missing.decorators = decorators; missing.modifiers = modifiers; return missing; @@ -6606,11 +6472,11 @@ namespace ts { function nextTokenIsIdentifierOrStringLiteralOnSameLine() { nextToken(); - return !scanner.hasPrecedingLineBreak() && (isIdentifier() || token() === SyntaxKind.StringLiteral); + return !scanner.hasPrecedingLineBreak() && (isIdentifier() || token() === ts.SyntaxKind.StringLiteral); } - function parseFunctionBlockOrSemicolon(flags: SignatureFlags, diagnosticMessage?: DiagnosticMessage): Block | undefined { - if (token() !== SyntaxKind.OpenBraceToken && canParseSemicolon()) { + function parseFunctionBlockOrSemicolon(flags: SignatureFlags, diagnosticMessage?: ts.DiagnosticMessage): ts.Block | undefined { + if (token() !== ts.SyntaxKind.OpenBraceToken && canParseSemicolon()) { parseSemicolon(); return; } @@ -6620,63 +6486,63 @@ namespace ts { // DECLARATIONS - function parseArrayBindingElement(): ArrayBindingElement { + function parseArrayBindingElement(): ts.ArrayBindingElement { const pos = getNodePos(); - if (token() === SyntaxKind.CommaToken) { + if (token() === ts.SyntaxKind.CommaToken) { return finishNode(factory.createOmittedExpression(), pos); } - const dotDotDotToken = parseOptionalToken(SyntaxKind.DotDotDotToken); + const dotDotDotToken = parseOptionalToken(ts.SyntaxKind.DotDotDotToken); const name = parseIdentifierOrPattern(); const initializer = parseInitializer(); return finishNode(factory.createBindingElement(dotDotDotToken, /*propertyName*/ undefined, name, initializer), pos); } - function parseObjectBindingElement(): BindingElement { + function parseObjectBindingElement(): ts.BindingElement { const pos = getNodePos(); - const dotDotDotToken = parseOptionalToken(SyntaxKind.DotDotDotToken); + const dotDotDotToken = parseOptionalToken(ts.SyntaxKind.DotDotDotToken); const tokenIsIdentifier = isBindingIdentifier(); - let propertyName: PropertyName | undefined = parsePropertyName(); - let name: BindingName; - if (tokenIsIdentifier && token() !== SyntaxKind.ColonToken) { - name = propertyName as Identifier; + let propertyName: ts.PropertyName | undefined = parsePropertyName(); + let name: ts.BindingName; + if (tokenIsIdentifier && token() !== ts.SyntaxKind.ColonToken) { + name = propertyName as ts.Identifier; propertyName = undefined; } else { - parseExpected(SyntaxKind.ColonToken); + parseExpected(ts.SyntaxKind.ColonToken); name = parseIdentifierOrPattern(); } const initializer = parseInitializer(); return finishNode(factory.createBindingElement(dotDotDotToken, propertyName, name, initializer), pos); } - function parseObjectBindingPattern(): ObjectBindingPattern { + function parseObjectBindingPattern(): ts.ObjectBindingPattern { const pos = getNodePos(); - parseExpected(SyntaxKind.OpenBraceToken); + parseExpected(ts.SyntaxKind.OpenBraceToken); const elements = parseDelimitedList(ParsingContext.ObjectBindingElements, parseObjectBindingElement); - parseExpected(SyntaxKind.CloseBraceToken); + parseExpected(ts.SyntaxKind.CloseBraceToken); return finishNode(factory.createObjectBindingPattern(elements), pos); } - function parseArrayBindingPattern(): ArrayBindingPattern { + function parseArrayBindingPattern(): ts.ArrayBindingPattern { const pos = getNodePos(); - parseExpected(SyntaxKind.OpenBracketToken); + parseExpected(ts.SyntaxKind.OpenBracketToken); const elements = parseDelimitedList(ParsingContext.ArrayBindingElements, parseArrayBindingElement); - parseExpected(SyntaxKind.CloseBracketToken); + parseExpected(ts.SyntaxKind.CloseBracketToken); return finishNode(factory.createArrayBindingPattern(elements), pos); } function isBindingIdentifierOrPrivateIdentifierOrPattern() { - return token() === SyntaxKind.OpenBraceToken - || token() === SyntaxKind.OpenBracketToken - || token() === SyntaxKind.PrivateIdentifier + return token() === ts.SyntaxKind.OpenBraceToken + || token() === ts.SyntaxKind.OpenBracketToken + || token() === ts.SyntaxKind.PrivateIdentifier || isBindingIdentifier(); } - function parseIdentifierOrPattern(privateIdentifierDiagnosticMessage?: DiagnosticMessage): Identifier | BindingPattern { - if (token() === SyntaxKind.OpenBracketToken) { + function parseIdentifierOrPattern(privateIdentifierDiagnosticMessage?: ts.DiagnosticMessage): ts.Identifier | ts.BindingPattern { + if (token() === ts.SyntaxKind.OpenBracketToken) { return parseArrayBindingPattern(); } - if (token() === SyntaxKind.OpenBraceToken) { + if (token() === ts.SyntaxKind.OpenBraceToken) { return parseObjectBindingPattern(); } return parseBindingIdentifier(privateIdentifierDiagnosticMessage); @@ -6686,14 +6552,14 @@ namespace ts { return parseVariableDeclaration(/*allowExclamation*/ true); } - function parseVariableDeclaration(allowExclamation?: boolean): VariableDeclaration { + function parseVariableDeclaration(allowExclamation?: boolean): ts.VariableDeclaration { const pos = getNodePos(); const hasJSDoc = hasPrecedingJSDocComment(); - const name = parseIdentifierOrPattern(Diagnostics.Private_identifiers_are_not_allowed_in_variable_declarations); - let exclamationToken: ExclamationToken | undefined; - if (allowExclamation && name.kind === SyntaxKind.Identifier && - token() === SyntaxKind.ExclamationToken && !scanner.hasPrecedingLineBreak()) { - exclamationToken = parseTokenNode>(); + const name = parseIdentifierOrPattern(ts.Diagnostics.Private_identifiers_are_not_allowed_in_variable_declarations); + let exclamationToken: ts.ExclamationToken | undefined; + if (allowExclamation && name.kind === ts.SyntaxKind.Identifier && + token() === ts.SyntaxKind.ExclamationToken && !scanner.hasPrecedingLineBreak()) { + exclamationToken = parseTokenNode>(); } const type = parseTypeAnnotation(); const initializer = isInOrOfKeyword(token()) ? undefined : parseInitializer(); @@ -6701,21 +6567,21 @@ namespace ts { return withJSDoc(finishNode(node, pos), hasJSDoc); } - function parseVariableDeclarationList(inForStatementInitializer: boolean): VariableDeclarationList { + function parseVariableDeclarationList(inForStatementInitializer: boolean): ts.VariableDeclarationList { const pos = getNodePos(); - let flags: NodeFlags = 0; + let flags: ts.NodeFlags = 0; switch (token()) { - case SyntaxKind.VarKeyword: + case ts.SyntaxKind.VarKeyword: break; - case SyntaxKind.LetKeyword: - flags |= NodeFlags.Let; + case ts.SyntaxKind.LetKeyword: + flags |= ts.NodeFlags.Let; break; - case SyntaxKind.ConstKeyword: - flags |= NodeFlags.Const; + case ts.SyntaxKind.ConstKeyword: + flags |= ts.NodeFlags.Const; break; default: - Debug.fail(); + ts.Debug.fail(); } nextToken(); @@ -6729,16 +6595,15 @@ namespace ts { // So we need to look ahead to determine if 'of' should be treated as a keyword in // this context. // The checker will then give an error that there is an empty declaration list. - let declarations: readonly VariableDeclaration[]; - if (token() === SyntaxKind.OfKeyword && lookAhead(canFollowContextualOfKeyword)) { - declarations = createMissingList(); + let declarations: readonly ts.VariableDeclaration[]; + if (token() === ts.SyntaxKind.OfKeyword && lookAhead(canFollowContextualOfKeyword)) { + declarations = createMissingList(); } else { const savedDisallowIn = inDisallowInContext(); setDisallowInContext(inForStatementInitializer); - declarations = parseDelimitedList(ParsingContext.VariableDeclarations, - inForStatementInitializer ? parseVariableDeclaration : parseVariableDeclarationAllowExclamation); + declarations = parseDelimitedList(ParsingContext.VariableDeclarations, inForStatementInitializer ? parseVariableDeclaration : parseVariableDeclarationAllowExclamation); setDisallowInContext(savedDisallowIn); } @@ -6747,10 +6612,10 @@ namespace ts { } function canFollowContextualOfKeyword(): boolean { - return nextTokenIsIdentifier() && nextToken() === SyntaxKind.CloseParenToken; + return nextTokenIsIdentifier() && nextToken() === ts.SyntaxKind.CloseParenToken; } - function parseVariableStatement(pos: number, hasJSDoc: boolean, decorators: NodeArray | undefined, modifiers: NodeArray | undefined): VariableStatement { + function parseVariableStatement(pos: number, hasJSDoc: boolean, decorators: ts.NodeArray | undefined, modifiers: ts.NodeArray | undefined): ts.VariableStatement { const declarationList = parseVariableDeclarationList(/*inForStatementInitializer*/ false); parseSemicolon(); const node = factory.createVariableStatement(modifiers, declarationList); @@ -6759,31 +6624,32 @@ namespace ts { return withJSDoc(finishNode(node, pos), hasJSDoc); } - function parseFunctionDeclaration(pos: number, hasJSDoc: boolean, decorators: NodeArray | undefined, modifiers: NodeArray | undefined): FunctionDeclaration { + function parseFunctionDeclaration(pos: number, hasJSDoc: boolean, decorators: ts.NodeArray | undefined, modifiers: ts.NodeArray | undefined): ts.FunctionDeclaration { const savedAwaitContext = inAwaitContext(); - const modifierFlags = modifiersToFlags(modifiers); - parseExpected(SyntaxKind.FunctionKeyword); - const asteriskToken = parseOptionalToken(SyntaxKind.AsteriskToken); + const modifierFlags = ts.modifiersToFlags(modifiers); + parseExpected(ts.SyntaxKind.FunctionKeyword); + const asteriskToken = parseOptionalToken(ts.SyntaxKind.AsteriskToken); // We don't parse the name here in await context, instead we will report a grammar error in the checker. - const name = modifierFlags & ModifierFlags.Default ? parseOptionalBindingIdentifier() : parseBindingIdentifier(); + const name = modifierFlags & ts.ModifierFlags.Default ? parseOptionalBindingIdentifier() : parseBindingIdentifier(); const isGenerator = asteriskToken ? SignatureFlags.Yield : SignatureFlags.None; - const isAsync = modifierFlags & ModifierFlags.Async ? SignatureFlags.Await : SignatureFlags.None; + const isAsync = modifierFlags & ts.ModifierFlags.Async ? SignatureFlags.Await : SignatureFlags.None; const typeParameters = parseTypeParameters(); - if (modifierFlags & ModifierFlags.Export) setAwaitContext(/*value*/ true); + if (modifierFlags & ts.ModifierFlags.Export) + setAwaitContext(/*value*/ true); const parameters = parseParameters(isGenerator | isAsync); - const type = parseReturnType(SyntaxKind.ColonToken, /*isType*/ false); - const body = parseFunctionBlockOrSemicolon(isGenerator | isAsync, Diagnostics.or_expected); + const type = parseReturnType(ts.SyntaxKind.ColonToken, /*isType*/ false); + const body = parseFunctionBlockOrSemicolon(isGenerator | isAsync, ts.Diagnostics.or_expected); setAwaitContext(savedAwaitContext); const node = factory.createFunctionDeclaration(decorators, modifiers, asteriskToken, name, typeParameters, parameters, type, body); return withJSDoc(finishNode(node, pos), hasJSDoc); } function parseConstructorName() { - if (token() === SyntaxKind.ConstructorKeyword) { - return parseExpected(SyntaxKind.ConstructorKeyword); + if (token() === ts.SyntaxKind.ConstructorKeyword) { + return parseExpected(ts.SyntaxKind.ConstructorKeyword); } - if (token() === SyntaxKind.StringLiteral && lookAhead(nextToken) === SyntaxKind.OpenParenToken) { + if (token() === ts.SyntaxKind.StringLiteral && lookAhead(nextToken) === ts.SyntaxKind.OpenParenToken) { return tryParse(() => { const literalNode = parseLiteralNode(); return literalNode.text === "constructor" ? literalNode : undefined; @@ -6791,13 +6657,13 @@ namespace ts { } } - function tryParseConstructorDeclaration(pos: number, hasJSDoc: boolean, decorators: NodeArray | undefined, modifiers: NodeArray | undefined): ConstructorDeclaration | undefined { + function tryParseConstructorDeclaration(pos: number, hasJSDoc: boolean, decorators: ts.NodeArray | undefined, modifiers: ts.NodeArray | undefined): ts.ConstructorDeclaration | undefined { return tryParse(() => { if (parseConstructorName()) { const typeParameters = parseTypeParameters(); const parameters = parseParameters(SignatureFlags.None); - const type = parseReturnType(SyntaxKind.ColonToken, /*isType*/ false); - const body = parseFunctionBlockOrSemicolon(SignatureFlags.None, Diagnostics.or_expected); + const type = parseReturnType(ts.SyntaxKind.ColonToken, /*isType*/ false); + const body = parseFunctionBlockOrSemicolon(SignatureFlags.None, ts.Diagnostics.or_expected); const node = factory.createConstructorDeclaration(decorators, modifiers, parameters, body); // Attach `typeParameters` and `type` if they exist so that we can report them in the grammar checker. node.typeParameters = typeParameters; @@ -6807,96 +6673,64 @@ namespace ts { }); } - function parseMethodDeclaration( - pos: number, - hasJSDoc: boolean, - decorators: NodeArray | undefined, - modifiers: NodeArray | undefined, - asteriskToken: AsteriskToken | undefined, - name: PropertyName, - questionToken: QuestionToken | undefined, - exclamationToken: ExclamationToken | undefined, - diagnosticMessage?: DiagnosticMessage - ): MethodDeclaration { + function parseMethodDeclaration(pos: number, hasJSDoc: boolean, decorators: ts.NodeArray | undefined, modifiers: ts.NodeArray | undefined, asteriskToken: ts.AsteriskToken | undefined, name: ts.PropertyName, questionToken: ts.QuestionToken | undefined, exclamationToken: ts.ExclamationToken | undefined, diagnosticMessage?: ts.DiagnosticMessage): ts.MethodDeclaration { const isGenerator = asteriskToken ? SignatureFlags.Yield : SignatureFlags.None; - const isAsync = some(modifiers, isAsyncModifier) ? SignatureFlags.Await : SignatureFlags.None; + const isAsync = ts.some(modifiers, ts.isAsyncModifier) ? SignatureFlags.Await : SignatureFlags.None; const typeParameters = parseTypeParameters(); const parameters = parseParameters(isGenerator | isAsync); - const type = parseReturnType(SyntaxKind.ColonToken, /*isType*/ false); + const type = parseReturnType(ts.SyntaxKind.ColonToken, /*isType*/ false); const body = parseFunctionBlockOrSemicolon(isGenerator | isAsync, diagnosticMessage); - const node = factory.createMethodDeclaration( - decorators, - modifiers, - asteriskToken, - name, - questionToken, - typeParameters, - parameters, - type, - body - ); + const node = factory.createMethodDeclaration(decorators, modifiers, asteriskToken, name, questionToken, typeParameters, parameters, type, body); // An exclamation token on a method is invalid syntax and will be handled by the grammar checker node.exclamationToken = exclamationToken; return withJSDoc(finishNode(node, pos), hasJSDoc); } - function parsePropertyDeclaration( - pos: number, - hasJSDoc: boolean, - decorators: NodeArray | undefined, - modifiers: NodeArray | undefined, - name: PropertyName, - questionToken: QuestionToken | undefined - ): PropertyDeclaration { - const exclamationToken = !questionToken && !scanner.hasPrecedingLineBreak() ? parseOptionalToken(SyntaxKind.ExclamationToken) : undefined; + function parsePropertyDeclaration(pos: number, hasJSDoc: boolean, decorators: ts.NodeArray | undefined, modifiers: ts.NodeArray | undefined, name: ts.PropertyName, questionToken: ts.QuestionToken | undefined): ts.PropertyDeclaration { + const exclamationToken = !questionToken && !scanner.hasPrecedingLineBreak() ? parseOptionalToken(ts.SyntaxKind.ExclamationToken) : undefined; const type = parseTypeAnnotation(); - const initializer = doOutsideOfContext(NodeFlags.YieldContext | NodeFlags.AwaitContext | NodeFlags.DisallowInContext, parseInitializer); + const initializer = doOutsideOfContext(ts.NodeFlags.YieldContext | ts.NodeFlags.AwaitContext | ts.NodeFlags.DisallowInContext, parseInitializer); parseSemicolonAfterPropertyName(name, type, initializer); const node = factory.createPropertyDeclaration(decorators, modifiers, name, questionToken || exclamationToken, type, initializer); return withJSDoc(finishNode(node, pos), hasJSDoc); } - function parsePropertyOrMethodDeclaration( - pos: number, - hasJSDoc: boolean, - decorators: NodeArray | undefined, - modifiers: NodeArray | undefined - ): PropertyDeclaration | MethodDeclaration { - const asteriskToken = parseOptionalToken(SyntaxKind.AsteriskToken); + function parsePropertyOrMethodDeclaration(pos: number, hasJSDoc: boolean, decorators: ts.NodeArray | undefined, modifiers: ts.NodeArray | undefined): ts.PropertyDeclaration | ts.MethodDeclaration { + const asteriskToken = parseOptionalToken(ts.SyntaxKind.AsteriskToken); const name = parsePropertyName(); // Note: this is not legal as per the grammar. But we allow it in the parser and // report an error in the grammar checker. - const questionToken = parseOptionalToken(SyntaxKind.QuestionToken); - if (asteriskToken || token() === SyntaxKind.OpenParenToken || token() === SyntaxKind.LessThanToken) { - return parseMethodDeclaration(pos, hasJSDoc, decorators, modifiers, asteriskToken, name, questionToken, /*exclamationToken*/ undefined, Diagnostics.or_expected); + const questionToken = parseOptionalToken(ts.SyntaxKind.QuestionToken); + if (asteriskToken || token() === ts.SyntaxKind.OpenParenToken || token() === ts.SyntaxKind.LessThanToken) { + return parseMethodDeclaration(pos, hasJSDoc, decorators, modifiers, asteriskToken, name, questionToken, /*exclamationToken*/ undefined, ts.Diagnostics.or_expected); } return parsePropertyDeclaration(pos, hasJSDoc, decorators, modifiers, name, questionToken); } - function parseAccessorDeclaration(pos: number, hasJSDoc: boolean, decorators: NodeArray | undefined, modifiers: NodeArray | undefined, kind: AccessorDeclaration["kind"]): AccessorDeclaration { + function parseAccessorDeclaration(pos: number, hasJSDoc: boolean, decorators: ts.NodeArray | undefined, modifiers: ts.NodeArray | undefined, kind: ts.AccessorDeclaration["kind"]): ts.AccessorDeclaration { const name = parsePropertyName(); const typeParameters = parseTypeParameters(); const parameters = parseParameters(SignatureFlags.None); - const type = parseReturnType(SyntaxKind.ColonToken, /*isType*/ false); + const type = parseReturnType(ts.SyntaxKind.ColonToken, /*isType*/ false); const body = parseFunctionBlockOrSemicolon(SignatureFlags.None); - const node = kind === SyntaxKind.GetAccessor + const node = kind === ts.SyntaxKind.GetAccessor ? factory.createGetAccessorDeclaration(decorators, modifiers, name, parameters, type, body) : factory.createSetAccessorDeclaration(decorators, modifiers, name, parameters, body); // Keep track of `typeParameters` (for both) and `type` (for setters) if they were parsed those indicate grammar errors node.typeParameters = typeParameters; - if (type && node.kind === SyntaxKind.SetAccessor) (node as Mutable).type = type; + if (type && node.kind === ts.SyntaxKind.SetAccessor) + (node as ts.Mutable).type = type; return withJSDoc(finishNode(node, pos), hasJSDoc); } function isClassMemberStart(): boolean { - let idToken: SyntaxKind | undefined; - - if (token() === SyntaxKind.AtToken) { + let idToken: ts.SyntaxKind | undefined; + if (token() === ts.SyntaxKind.AtToken) { return true; } // Eat up all modifiers, but hold on to the last one in case it is actually an identifier. - while (isModifierKind(token())) { + while (ts.isModifierKind(token())) { idToken = token(); // If the idToken is a class modifier (protected, private, public, and static), it is // certain that we are starting to parse class member. This allows better error recovery @@ -6904,14 +6738,14 @@ namespace ts { // public foo() ... // true // public @dec blah ... // true; we will then report an error later // export public ... // true; we will then report an error later - if (isClassMemberModifier(idToken)) { + if (ts.isClassMemberModifier(idToken)) { return true; } nextToken(); } - if (token() === SyntaxKind.AsteriskToken) { + if (token() === ts.SyntaxKind.AsteriskToken) { return true; } @@ -6923,26 +6757,26 @@ namespace ts { } // Index signatures and computed properties are class members; we can parse. - if (token() === SyntaxKind.OpenBracketToken) { + if (token() === ts.SyntaxKind.OpenBracketToken) { return true; } // If we were able to get any potential identifier... if (idToken !== undefined) { // If we have a non-keyword identifier, or if we have an accessor, then it's safe to parse. - if (!isKeyword(idToken) || idToken === SyntaxKind.SetKeyword || idToken === SyntaxKind.GetKeyword) { + if (!ts.isKeyword(idToken) || idToken === ts.SyntaxKind.SetKeyword || idToken === ts.SyntaxKind.GetKeyword) { return true; } // If it *is* a keyword, but not an accessor, check a little farther along // to see if it should actually be parsed as a class member. switch (token()) { - case SyntaxKind.OpenParenToken: // Method declaration - case SyntaxKind.LessThanToken: // Generic Method declaration - case SyntaxKind.ExclamationToken: // Non-null assertion on property name - case SyntaxKind.ColonToken: // Type Annotation for declaration - case SyntaxKind.EqualsToken: // Initializer for declaration - case SyntaxKind.QuestionToken: // Not valid, but permitted so that it gets caught later on. + case ts.SyntaxKind.OpenParenToken: // Method declaration + case ts.SyntaxKind.LessThanToken: // Generic Method declaration + case ts.SyntaxKind.ExclamationToken: // Non-null assertion on property name + case ts.SyntaxKind.ColonToken: // Type Annotation for declaration + case ts.SyntaxKind.EqualsToken: // Initializer for declaration + case ts.SyntaxKind.QuestionToken: // Not valid, but permitted so that it gets caught later on. return true; default: // Covers @@ -6957,8 +6791,8 @@ namespace ts { return false; } - function parseClassStaticBlockDeclaration(pos: number, hasJSDoc: boolean, decorators: NodeArray | undefined, modifiers: ModifiersArray | undefined): ClassStaticBlockDeclaration { - parseExpectedToken(SyntaxKind.StaticKeyword); + function parseClassStaticBlockDeclaration(pos: number, hasJSDoc: boolean, decorators: ts.NodeArray | undefined, modifiers: ts.ModifiersArray | undefined): ts.ClassStaticBlockDeclaration { + parseExpectedToken(ts.SyntaxKind.StaticKeyword); const body = parseClassStaticBlockBody(); return withJSDoc(finishNode(factory.createClassStaticBlockDeclaration(decorators, modifiers, body), pos), hasJSDoc); } @@ -6979,11 +6813,11 @@ namespace ts { } function parseDecoratorExpression() { - if (inAwaitContext() && token() === SyntaxKind.AwaitKeyword) { + if (inAwaitContext() && token() === ts.SyntaxKind.AwaitKeyword) { // `@await` is is disallowed in an [Await] context, but can cause parsing to go off the rails // This simply parses the missing identifier and moves on. const pos = getNodePos(); - const awaitExpression = parseIdentifier(Diagnostics.Expression_expected); + const awaitExpression = parseIdentifier(ts.Diagnostics.Expression_expected); nextToken(); const memberExpression = parseMemberExpressionRest(pos, awaitExpression, /*allowOptionalChain*/ true); return parseCallExpressionRest(pos, memberExpression); @@ -6991,39 +6825,39 @@ namespace ts { return parseLeftHandSideExpressionOrHigher(); } - function tryParseDecorator(): Decorator | undefined { + function tryParseDecorator(): ts.Decorator | undefined { const pos = getNodePos(); - if (!parseOptional(SyntaxKind.AtToken)) { + if (!parseOptional(ts.SyntaxKind.AtToken)) { return undefined; } const expression = doInDecoratorContext(parseDecoratorExpression); return finishNode(factory.createDecorator(expression), pos); } - function parseDecorators(): NodeArray | undefined { + function parseDecorators(): ts.NodeArray | undefined { const pos = getNodePos(); let list, decorator; while (decorator = tryParseDecorator()) { - list = append(list, decorator); + list = ts.append(list, decorator); } return list && createNodeArray(list, pos); } - function tryParseModifier(permitInvalidConstAsModifier?: boolean, stopOnStartOfClassStaticBlock?: boolean, hasSeenStaticModifier?: boolean): Modifier | undefined { + function tryParseModifier(permitInvalidConstAsModifier?: boolean, stopOnStartOfClassStaticBlock?: boolean, hasSeenStaticModifier?: boolean): ts.Modifier | undefined { const pos = getNodePos(); const kind = token(); - if (token() === SyntaxKind.ConstKeyword && permitInvalidConstAsModifier) { + if (token() === ts.SyntaxKind.ConstKeyword && permitInvalidConstAsModifier) { // We need to ensure that any subsequent modifiers appear on the same line // so that when 'const' is a standalone declaration, we don't issue an error. if (!tryParse(nextTokenIsOnSameLineAndCanFollowModifier)) { return undefined; } } - else if (stopOnStartOfClassStaticBlock && token() === SyntaxKind.StaticKeyword && lookAhead(nextTokenIsOpenBrace)) { + else if (stopOnStartOfClassStaticBlock && token() === ts.SyntaxKind.StaticKeyword && lookAhead(nextTokenIsOpenBrace)) { return undefined; } - else if (hasSeenStaticModifier && token() === SyntaxKind.StaticKeyword) { + else if (hasSeenStaticModifier && token() === ts.SyntaxKind.StaticKeyword) { return undefined; } else { @@ -7032,7 +6866,7 @@ namespace ts { } } - return finishNode(factory.createToken(kind as Modifier["kind"]), pos); + return finishNode(factory.createToken(kind as ts.Modifier["kind"]), pos); } /* @@ -7042,30 +6876,31 @@ namespace ts { * * In such situations, 'permitInvalidConstAsModifier' should be set to true. */ - function parseModifiers(permitInvalidConstAsModifier?: boolean, stopOnStartOfClassStaticBlock?: boolean): NodeArray | undefined { + function parseModifiers(permitInvalidConstAsModifier?: boolean, stopOnStartOfClassStaticBlock?: boolean): ts.NodeArray | undefined { const pos = getNodePos(); let list, modifier, hasSeenStatic = false; while (modifier = tryParseModifier(permitInvalidConstAsModifier, stopOnStartOfClassStaticBlock, hasSeenStatic)) { - if (modifier.kind === SyntaxKind.StaticKeyword) hasSeenStatic = true; - list = append(list, modifier); + if (modifier.kind === ts.SyntaxKind.StaticKeyword) + hasSeenStatic = true; + list = ts.append(list, modifier); } return list && createNodeArray(list, pos); } - function parseModifiersForArrowFunction(): NodeArray | undefined { - let modifiers: NodeArray | undefined; - if (token() === SyntaxKind.AsyncKeyword) { + function parseModifiersForArrowFunction(): ts.NodeArray | undefined { + let modifiers: ts.NodeArray | undefined; + if (token() === ts.SyntaxKind.AsyncKeyword) { const pos = getNodePos(); nextToken(); - const modifier = finishNode(factory.createToken(SyntaxKind.AsyncKeyword), pos); - modifiers = createNodeArray([modifier], pos); + const modifier = finishNode(factory.createToken(ts.SyntaxKind.AsyncKeyword), pos); + modifiers = createNodeArray([modifier], pos); } return modifiers; } - function parseClassElement(): ClassElement { + function parseClassElement(): ts.ClassElement { const pos = getNodePos(); - if (token() === SyntaxKind.SemicolonToken) { + if (token() === ts.SyntaxKind.SemicolonToken) { nextToken(); return finishNode(factory.createSemicolonClassElement(), pos); } @@ -7073,19 +6908,19 @@ namespace ts { const hasJSDoc = hasPrecedingJSDocComment(); const decorators = parseDecorators(); const modifiers = parseModifiers(/*permitInvalidConstAsModifier*/ true, /*stopOnStartOfClassStaticBlock*/ true); - if (token() === SyntaxKind.StaticKeyword && lookAhead(nextTokenIsOpenBrace)) { + if (token() === ts.SyntaxKind.StaticKeyword && lookAhead(nextTokenIsOpenBrace)) { return parseClassStaticBlockDeclaration(pos, hasJSDoc, decorators, modifiers); } - if (parseContextualModifier(SyntaxKind.GetKeyword)) { - return parseAccessorDeclaration(pos, hasJSDoc, decorators, modifiers, SyntaxKind.GetAccessor); + if (parseContextualModifier(ts.SyntaxKind.GetKeyword)) { + return parseAccessorDeclaration(pos, hasJSDoc, decorators, modifiers, ts.SyntaxKind.GetAccessor); } - if (parseContextualModifier(SyntaxKind.SetKeyword)) { - return parseAccessorDeclaration(pos, hasJSDoc, decorators, modifiers, SyntaxKind.SetAccessor); + if (parseContextualModifier(ts.SyntaxKind.SetKeyword)) { + return parseAccessorDeclaration(pos, hasJSDoc, decorators, modifiers, ts.SyntaxKind.SetAccessor); } - if (token() === SyntaxKind.ConstructorKeyword || token() === SyntaxKind.StringLiteral) { + if (token() === ts.SyntaxKind.ConstructorKeyword || token() === ts.SyntaxKind.StringLiteral) { const constructorDeclaration = tryParseConstructorDeclaration(pos, hasJSDoc, decorators, modifiers); if (constructorDeclaration) { return constructorDeclaration; @@ -7098,17 +6933,17 @@ namespace ts { // It is very important that we check this *after* checking indexers because // the [ token can start an index signature or a computed property name - if (tokenIsIdentifierOrKeyword(token()) || - token() === SyntaxKind.StringLiteral || - token() === SyntaxKind.NumericLiteral || - token() === SyntaxKind.AsteriskToken || - token() === SyntaxKind.OpenBracketToken) { - const isAmbient = some(modifiers, isDeclareModifier); + if (ts.tokenIsIdentifierOrKeyword(token()) || + token() === ts.SyntaxKind.StringLiteral || + token() === ts.SyntaxKind.NumericLiteral || + token() === ts.SyntaxKind.AsteriskToken || + token() === ts.SyntaxKind.OpenBracketToken) { + const isAmbient = ts.some(modifiers, isDeclareModifier); if (isAmbient) { for (const m of modifiers!) { - (m as Mutable).flags |= NodeFlags.Ambient; + (m as ts.Mutable).flags |= ts.NodeFlags.Ambient; } - return doInsideOfContext(NodeFlags.Ambient, () => parsePropertyOrMethodDeclaration(pos, hasJSDoc, decorators, modifiers)); + return doInsideOfContext(ts.NodeFlags.Ambient, () => parsePropertyOrMethodDeclaration(pos, hasJSDoc, decorators, modifiers)); } else { return parsePropertyOrMethodDeclaration(pos, hasJSDoc, decorators, modifiers); @@ -7117,50 +6952,51 @@ namespace ts { if (decorators || modifiers) { // treat this as a property declaration with a missing name. - const name = createMissingNode(SyntaxKind.Identifier, /*reportAtCurrentPosition*/ true, Diagnostics.Declaration_expected); + const name = createMissingNode(ts.SyntaxKind.Identifier, /*reportAtCurrentPosition*/ true, ts.Diagnostics.Declaration_expected); return parsePropertyDeclaration(pos, hasJSDoc, decorators, modifiers, name, /*questionToken*/ undefined); } // 'isClassMemberStart' should have hinted not to attempt parsing. - return Debug.fail("Should not have attempted to parse class member declaration."); + return ts.Debug.fail("Should not have attempted to parse class member declaration."); } - function parseClassExpression(): ClassExpression { - return parseClassDeclarationOrExpression(getNodePos(), hasPrecedingJSDocComment(), /*decorators*/ undefined, /*modifiers*/ undefined, SyntaxKind.ClassExpression) as ClassExpression; + function parseClassExpression(): ts.ClassExpression { + return parseClassDeclarationOrExpression(getNodePos(), hasPrecedingJSDocComment(), /*decorators*/ undefined, /*modifiers*/ undefined, ts.SyntaxKind.ClassExpression) as ts.ClassExpression; } - function parseClassDeclaration(pos: number, hasJSDoc: boolean, decorators: NodeArray | undefined, modifiers: NodeArray | undefined): ClassDeclaration { - return parseClassDeclarationOrExpression(pos, hasJSDoc, decorators, modifiers, SyntaxKind.ClassDeclaration) as ClassDeclaration; + function parseClassDeclaration(pos: number, hasJSDoc: boolean, decorators: ts.NodeArray | undefined, modifiers: ts.NodeArray | undefined): ts.ClassDeclaration { + return parseClassDeclarationOrExpression(pos, hasJSDoc, decorators, modifiers, ts.SyntaxKind.ClassDeclaration) as ts.ClassDeclaration; } - function parseClassDeclarationOrExpression(pos: number, hasJSDoc: boolean, decorators: NodeArray | undefined, modifiers: NodeArray | undefined, kind: ClassLikeDeclaration["kind"]): ClassLikeDeclaration { + function parseClassDeclarationOrExpression(pos: number, hasJSDoc: boolean, decorators: ts.NodeArray | undefined, modifiers: ts.NodeArray | undefined, kind: ts.ClassLikeDeclaration["kind"]): ts.ClassLikeDeclaration { const savedAwaitContext = inAwaitContext(); - parseExpected(SyntaxKind.ClassKeyword); + parseExpected(ts.SyntaxKind.ClassKeyword); // We don't parse the name here in await context, instead we will report a grammar error in the checker. const name = parseNameOfClassDeclarationOrExpression(); const typeParameters = parseTypeParameters(); - if (some(modifiers, isExportModifier)) setAwaitContext(/*value*/ true); + if (ts.some(modifiers, ts.isExportModifier)) + setAwaitContext(/*value*/ true); const heritageClauses = parseHeritageClauses(); let members; - if (parseExpected(SyntaxKind.OpenBraceToken)) { + if (parseExpected(ts.SyntaxKind.OpenBraceToken)) { // ClassTail[Yield,Await] : (Modified) See 14.5 // ClassHeritage[?Yield,?Await]opt { ClassBody[?Yield,?Await]opt } members = parseClassMembers(); - parseExpected(SyntaxKind.CloseBraceToken); + parseExpected(ts.SyntaxKind.CloseBraceToken); } else { - members = createMissingList(); + members = createMissingList(); } setAwaitContext(savedAwaitContext); - const node = kind === SyntaxKind.ClassDeclaration + const node = kind === ts.SyntaxKind.ClassDeclaration ? factory.createClassDeclaration(decorators, modifiers, name, typeParameters, heritageClauses, members) : factory.createClassExpression(decorators, modifiers, name, typeParameters, heritageClauses, members); return withJSDoc(finishNode(node, pos), hasJSDoc); } - function parseNameOfClassDeclarationOrExpression(): Identifier | undefined { + function parseNameOfClassDeclarationOrExpression(): ts.Identifier | undefined { // implements is a future reserved word so // 'class implements' might mean either // - class expression with omitted name, 'implements' starts heritage clause @@ -7172,10 +7008,10 @@ namespace ts { } function isImplementsClause() { - return token() === SyntaxKind.ImplementsKeyword && lookAhead(nextTokenIsIdentifierOrKeyword); + return token() === ts.SyntaxKind.ImplementsKeyword && lookAhead(nextTokenIsIdentifierOrKeyword); } - function parseHeritageClauses(): NodeArray | undefined { + function parseHeritageClauses(): ts.NodeArray | undefined { // ClassTail[Yield,Await] : (Modified) See 14.5 // ClassHeritage[?Yield,?Await]opt { ClassBody[?Yield,?Await]opt } @@ -7186,40 +7022,40 @@ namespace ts { return undefined; } - function parseHeritageClause(): HeritageClause { + function parseHeritageClause(): ts.HeritageClause { const pos = getNodePos(); const tok = token(); - Debug.assert(tok === SyntaxKind.ExtendsKeyword || tok === SyntaxKind.ImplementsKeyword); // isListElement() should ensure this. + ts.Debug.assert(tok === ts.SyntaxKind.ExtendsKeyword || tok === ts.SyntaxKind.ImplementsKeyword); // isListElement() should ensure this. nextToken(); const types = parseDelimitedList(ParsingContext.HeritageClauseElement, parseExpressionWithTypeArguments); return finishNode(factory.createHeritageClause(tok, types), pos); } - function parseExpressionWithTypeArguments(): ExpressionWithTypeArguments { + function parseExpressionWithTypeArguments(): ts.ExpressionWithTypeArguments { const pos = getNodePos(); const expression = parseLeftHandSideExpressionOrHigher(); - if (expression.kind === SyntaxKind.ExpressionWithTypeArguments) { - return expression as ExpressionWithTypeArguments; + if (expression.kind === ts.SyntaxKind.ExpressionWithTypeArguments) { + return expression as ts.ExpressionWithTypeArguments; } const typeArguments = tryParseTypeArguments(); return finishNode(factory.createExpressionWithTypeArguments(expression, typeArguments), pos); } - function tryParseTypeArguments(): NodeArray | undefined { - return token() === SyntaxKind.LessThanToken ? - parseBracketedList(ParsingContext.TypeArguments, parseType, SyntaxKind.LessThanToken, SyntaxKind.GreaterThanToken) : undefined; + function tryParseTypeArguments(): ts.NodeArray | undefined { + return token() === ts.SyntaxKind.LessThanToken ? + parseBracketedList(ParsingContext.TypeArguments, parseType, ts.SyntaxKind.LessThanToken, ts.SyntaxKind.GreaterThanToken) : undefined; } function isHeritageClause(): boolean { - return token() === SyntaxKind.ExtendsKeyword || token() === SyntaxKind.ImplementsKeyword; + return token() === ts.SyntaxKind.ExtendsKeyword || token() === ts.SyntaxKind.ImplementsKeyword; } - function parseClassMembers(): NodeArray { + function parseClassMembers(): ts.NodeArray { return parseList(ParsingContext.ClassMembers, parseClassElement); } - function parseInterfaceDeclaration(pos: number, hasJSDoc: boolean, decorators: NodeArray | undefined, modifiers: NodeArray | undefined): InterfaceDeclaration { - parseExpected(SyntaxKind.InterfaceKeyword); + function parseInterfaceDeclaration(pos: number, hasJSDoc: boolean, decorators: ts.NodeArray | undefined, modifiers: ts.NodeArray | undefined): ts.InterfaceDeclaration { + parseExpected(ts.SyntaxKind.InterfaceKeyword); const name = parseIdentifier(); const typeParameters = parseTypeParameters(); const heritageClauses = parseHeritageClauses(); @@ -7228,12 +7064,12 @@ namespace ts { return withJSDoc(finishNode(node, pos), hasJSDoc); } - function parseTypeAliasDeclaration(pos: number, hasJSDoc: boolean, decorators: NodeArray | undefined, modifiers: NodeArray | undefined): TypeAliasDeclaration { - parseExpected(SyntaxKind.TypeKeyword); + function parseTypeAliasDeclaration(pos: number, hasJSDoc: boolean, decorators: ts.NodeArray | undefined, modifiers: ts.NodeArray | undefined): ts.TypeAliasDeclaration { + parseExpected(ts.SyntaxKind.TypeKeyword); const name = parseIdentifier(); const typeParameters = parseTypeParameters(); - parseExpected(SyntaxKind.EqualsToken); - const type = token() === SyntaxKind.IntrinsicKeyword && tryParse(parseKeywordAndNoDot) || parseType(); + parseExpected(ts.SyntaxKind.EqualsToken); + const type = token() === ts.SyntaxKind.IntrinsicKeyword && tryParse(parseKeywordAndNoDot) || parseType(); parseSemicolon(); const node = factory.createTypeAliasDeclaration(decorators, modifiers, name, typeParameters, type); return withJSDoc(finishNode(node, pos), hasJSDoc); @@ -7243,7 +7079,7 @@ namespace ts { // In a non-ambient declaration, the grammar allows uninitialized members only in a // ConstantEnumMemberSection, which starts at the beginning of an enum declaration // or any time an integer literal initializer is encountered. - function parseEnumMember(): EnumMember { + function parseEnumMember(): ts.EnumMember { const pos = getNodePos(); const hasJSDoc = hasPrecedingJSDocComment(); const name = parsePropertyName(); @@ -7251,60 +7087,60 @@ namespace ts { return withJSDoc(finishNode(factory.createEnumMember(name, initializer), pos), hasJSDoc); } - function parseEnumDeclaration(pos: number, hasJSDoc: boolean, decorators: NodeArray | undefined, modifiers: NodeArray | undefined): EnumDeclaration { - parseExpected(SyntaxKind.EnumKeyword); + function parseEnumDeclaration(pos: number, hasJSDoc: boolean, decorators: ts.NodeArray | undefined, modifiers: ts.NodeArray | undefined): ts.EnumDeclaration { + parseExpected(ts.SyntaxKind.EnumKeyword); const name = parseIdentifier(); let members; - if (parseExpected(SyntaxKind.OpenBraceToken)) { + if (parseExpected(ts.SyntaxKind.OpenBraceToken)) { members = doOutsideOfYieldAndAwaitContext(() => parseDelimitedList(ParsingContext.EnumMembers, parseEnumMember)); - parseExpected(SyntaxKind.CloseBraceToken); + parseExpected(ts.SyntaxKind.CloseBraceToken); } else { - members = createMissingList(); + members = createMissingList(); } const node = factory.createEnumDeclaration(decorators, modifiers, name, members); return withJSDoc(finishNode(node, pos), hasJSDoc); } - function parseModuleBlock(): ModuleBlock { + function parseModuleBlock(): ts.ModuleBlock { const pos = getNodePos(); let statements; - if (parseExpected(SyntaxKind.OpenBraceToken)) { + if (parseExpected(ts.SyntaxKind.OpenBraceToken)) { statements = parseList(ParsingContext.BlockStatements, parseStatement); - parseExpected(SyntaxKind.CloseBraceToken); + parseExpected(ts.SyntaxKind.CloseBraceToken); } else { - statements = createMissingList(); + statements = createMissingList(); } return finishNode(factory.createModuleBlock(statements), pos); } - function parseModuleOrNamespaceDeclaration(pos: number, hasJSDoc: boolean, decorators: NodeArray | undefined, modifiers: NodeArray | undefined, flags: NodeFlags): ModuleDeclaration { + function parseModuleOrNamespaceDeclaration(pos: number, hasJSDoc: boolean, decorators: ts.NodeArray | undefined, modifiers: ts.NodeArray | undefined, flags: ts.NodeFlags): ts.ModuleDeclaration { // If we are parsing a dotted namespace name, we want to // propagate the 'Namespace' flag across the names if set. - const namespaceFlag = flags & NodeFlags.Namespace; + const namespaceFlag = flags & ts.NodeFlags.Namespace; const name = parseIdentifier(); - const body = parseOptional(SyntaxKind.DotToken) - ? parseModuleOrNamespaceDeclaration(getNodePos(), /*hasJSDoc*/ false, /*decorators*/ undefined, /*modifiers*/ undefined, NodeFlags.NestedNamespace | namespaceFlag) as NamespaceDeclaration + const body = parseOptional(ts.SyntaxKind.DotToken) + ? parseModuleOrNamespaceDeclaration(getNodePos(), /*hasJSDoc*/ false, /*decorators*/ undefined, /*modifiers*/ undefined, ts.NodeFlags.NestedNamespace | namespaceFlag) as ts.NamespaceDeclaration : parseModuleBlock(); const node = factory.createModuleDeclaration(decorators, modifiers, name, body, flags); return withJSDoc(finishNode(node, pos), hasJSDoc); } - function parseAmbientExternalModuleDeclaration(pos: number, hasJSDoc: boolean, decorators: NodeArray | undefined, modifiers: NodeArray | undefined): ModuleDeclaration { - let flags: NodeFlags = 0; + function parseAmbientExternalModuleDeclaration(pos: number, hasJSDoc: boolean, decorators: ts.NodeArray | undefined, modifiers: ts.NodeArray | undefined): ts.ModuleDeclaration { + let flags: ts.NodeFlags = 0; let name; - if (token() === SyntaxKind.GlobalKeyword) { + if (token() === ts.SyntaxKind.GlobalKeyword) { // parse 'global' as name of global scope augmentation name = parseIdentifier(); - flags |= NodeFlags.GlobalAugmentation; + flags |= ts.NodeFlags.GlobalAugmentation; } else { - name = parseLiteralNode() as StringLiteral; + name = parseLiteralNode() as ts.StringLiteral; name.text = internIdentifier(name.text); } - let body: ModuleBlock | undefined; - if (token() === SyntaxKind.OpenBraceToken) { + let body: ts.ModuleBlock | undefined; + if (token() === ts.SyntaxKind.OpenBraceToken) { body = parseModuleBlock(); } else { @@ -7314,18 +7150,18 @@ namespace ts { return withJSDoc(finishNode(node, pos), hasJSDoc); } - function parseModuleDeclaration(pos: number, hasJSDoc: boolean, decorators: NodeArray | undefined, modifiers: NodeArray | undefined): ModuleDeclaration { - let flags: NodeFlags = 0; - if (token() === SyntaxKind.GlobalKeyword) { + function parseModuleDeclaration(pos: number, hasJSDoc: boolean, decorators: ts.NodeArray | undefined, modifiers: ts.NodeArray | undefined): ts.ModuleDeclaration { + let flags: ts.NodeFlags = 0; + if (token() === ts.SyntaxKind.GlobalKeyword) { // global augmentation return parseAmbientExternalModuleDeclaration(pos, hasJSDoc, decorators, modifiers); } - else if (parseOptional(SyntaxKind.NamespaceKeyword)) { - flags |= NodeFlags.Namespace; + else if (parseOptional(ts.SyntaxKind.NamespaceKeyword)) { + flags |= ts.NodeFlags.Namespace; } else { - parseExpected(SyntaxKind.ModuleKeyword); - if (token() === SyntaxKind.StringLiteral) { + parseExpected(ts.SyntaxKind.ModuleKeyword); + if (token() === ts.SyntaxKind.StringLiteral) { return parseAmbientExternalModuleDeclaration(pos, hasJSDoc, decorators, modifiers); } } @@ -7333,25 +7169,25 @@ namespace ts { } function isExternalModuleReference() { - return token() === SyntaxKind.RequireKeyword && + return token() === ts.SyntaxKind.RequireKeyword && lookAhead(nextTokenIsOpenParen); } function nextTokenIsOpenParen() { - return nextToken() === SyntaxKind.OpenParenToken; + return nextToken() === ts.SyntaxKind.OpenParenToken; } function nextTokenIsOpenBrace() { - return nextToken() === SyntaxKind.OpenBraceToken; + return nextToken() === ts.SyntaxKind.OpenBraceToken; } function nextTokenIsSlash() { - return nextToken() === SyntaxKind.SlashToken; + return nextToken() === ts.SyntaxKind.SlashToken; } - function parseNamespaceExportDeclaration(pos: number, hasJSDoc: boolean, decorators: NodeArray | undefined, modifiers: NodeArray | undefined): NamespaceExportDeclaration { - parseExpected(SyntaxKind.AsKeyword); - parseExpected(SyntaxKind.NamespaceKeyword); + function parseNamespaceExportDeclaration(pos: number, hasJSDoc: boolean, decorators: ts.NodeArray | undefined, modifiers: ts.NodeArray | undefined): ts.NamespaceExportDeclaration { + parseExpected(ts.SyntaxKind.AsKeyword); + parseExpected(ts.SyntaxKind.NamespaceKeyword); const name = parseIdentifier(); parseSemicolon(); const node = factory.createNamespaceExportDeclaration(name); @@ -7361,22 +7197,21 @@ namespace ts { return withJSDoc(finishNode(node, pos), hasJSDoc); } - function parseImportDeclarationOrImportEqualsDeclaration(pos: number, hasJSDoc: boolean, decorators: NodeArray | undefined, modifiers: NodeArray | undefined): ImportEqualsDeclaration | ImportDeclaration { - parseExpected(SyntaxKind.ImportKeyword); + function parseImportDeclarationOrImportEqualsDeclaration(pos: number, hasJSDoc: boolean, decorators: ts.NodeArray | undefined, modifiers: ts.NodeArray | undefined): ts.ImportEqualsDeclaration | ts.ImportDeclaration { + parseExpected(ts.SyntaxKind.ImportKeyword); const afterImportPos = scanner.getStartPos(); // We don't parse the identifier here in await context, instead we will report a grammar error in the checker. - let identifier: Identifier | undefined; + let identifier: ts.Identifier | undefined; if (isIdentifier()) { identifier = parseIdentifier(); } let isTypeOnly = false; - if (token() !== SyntaxKind.FromKeyword && + if (token() !== ts.SyntaxKind.FromKeyword && identifier?.escapedText === "type" && - (isIdentifier() || tokenAfterImportDefinitelyProducesImportDeclaration()) - ) { + (isIdentifier() || tokenAfterImportDefinitelyProducesImportDeclaration())) { isTypeOnly = true; identifier = isIdentifier() ? parseIdentifier() : undefined; } @@ -7388,18 +7223,18 @@ namespace ts { // ImportDeclaration: // import ImportClause from ModuleSpecifier ; // import ModuleSpecifier; - let importClause: ImportClause | undefined; + let importClause: ts.ImportClause | undefined; if (identifier || // import id - token() === SyntaxKind.AsteriskToken || // import * - token() === SyntaxKind.OpenBraceToken // import { + token() === ts.SyntaxKind.AsteriskToken || // import * + token() === ts.SyntaxKind.OpenBraceToken // import { ) { importClause = parseImportClause(identifier, afterImportPos, isTypeOnly); - parseExpected(SyntaxKind.FromKeyword); + parseExpected(ts.SyntaxKind.FromKeyword); } const moduleSpecifier = parseModuleSpecifier(); - let assertClause: AssertClause | undefined; - if (token() === SyntaxKind.AssertKeyword && !scanner.hasPrecedingLineBreak()) { + let assertClause: ts.AssertClause | undefined; + if (token() === ts.SyntaxKind.AssertKeyword && !scanner.hasPrecedingLineBreak()) { assertClause = parseAssertClause(); } @@ -7410,8 +7245,8 @@ namespace ts { function parseAssertEntry() { const pos = getNodePos(); - const name = tokenIsIdentifierOrKeyword(token()) ? parseIdentifierName() : parseLiteralLikeNode(SyntaxKind.StringLiteral) as StringLiteral; - parseExpected(SyntaxKind.ColonToken); + const name = ts.tokenIsIdentifierOrKeyword(token()) ? parseIdentifierName() : parseLiteralLikeNode(ts.SyntaxKind.StringLiteral) as ts.StringLiteral; + parseExpected(ts.SyntaxKind.ColonToken); const value = parseAssignmentExpressionOrHigher(); return finishNode(factory.createAssertEntry(name, value), pos); } @@ -7419,19 +7254,16 @@ namespace ts { function parseAssertClause(skipAssertKeyword?: true) { const pos = getNodePos(); if (!skipAssertKeyword) { - parseExpected(SyntaxKind.AssertKeyword); + parseExpected(ts.SyntaxKind.AssertKeyword); } const openBracePosition = scanner.getTokenPos(); - if (parseExpected(SyntaxKind.OpenBraceToken)) { + if (parseExpected(ts.SyntaxKind.OpenBraceToken)) { const multiLine = scanner.hasPrecedingLineBreak(); const elements = parseDelimitedList(ParsingContext.AssertEntries, parseAssertEntry, /*considerSemicolonAsDelimiter*/ true); - if (!parseExpected(SyntaxKind.CloseBraceToken)) { - const lastError = lastOrUndefined(parseDiagnostics); - if (lastError && lastError.code === Diagnostics._0_expected.code) { - addRelatedInfo( - lastError, - createDetachedDiagnostic(fileName, openBracePosition, 1, Diagnostics.The_parser_expected_to_find_a_1_to_match_the_0_token_here, "{", "}") - ); + if (!parseExpected(ts.SyntaxKind.CloseBraceToken)) { + const lastError = ts.lastOrUndefined(parseDiagnostics); + if (lastError && lastError.code === ts.Diagnostics._0_expected.code) { + ts.addRelatedInfo(lastError, ts.createDetachedDiagnostic(fileName, openBracePosition, 1, ts.Diagnostics.The_parser_expected_to_find_a_1_to_match_the_0_token_here, "{", "}")); } } return finishNode(factory.createAssertClause(elements, multiLine), pos); @@ -7443,17 +7275,17 @@ namespace ts { } function tokenAfterImportDefinitelyProducesImportDeclaration() { - return token() === SyntaxKind.AsteriskToken || token() === SyntaxKind.OpenBraceToken; + return token() === ts.SyntaxKind.AsteriskToken || token() === ts.SyntaxKind.OpenBraceToken; } function tokenAfterImportedIdentifierDefinitelyProducesImportDeclaration() { // In `import id ___`, the current token decides whether to produce // an ImportDeclaration or ImportEqualsDeclaration. - return token() === SyntaxKind.CommaToken || token() === SyntaxKind.FromKeyword; + return token() === ts.SyntaxKind.CommaToken || token() === ts.SyntaxKind.FromKeyword; } - function parseImportEqualsDeclaration(pos: number, hasJSDoc: boolean, decorators: NodeArray | undefined, modifiers: NodeArray | undefined, identifier: Identifier, isTypeOnly: boolean): ImportEqualsDeclaration { - parseExpected(SyntaxKind.EqualsToken); + function parseImportEqualsDeclaration(pos: number, hasJSDoc: boolean, decorators: ts.NodeArray | undefined, modifiers: ts.NodeArray | undefined, identifier: ts.Identifier, isTypeOnly: boolean): ts.ImportEqualsDeclaration { + parseExpected(ts.SyntaxKind.EqualsToken); const moduleReference = parseModuleReference(); parseSemicolon(); const node = factory.createImportEqualsDeclaration(decorators, modifiers, isTypeOnly, identifier, moduleReference); @@ -7461,7 +7293,7 @@ namespace ts { return finished; } - function parseImportClause(identifier: Identifier | undefined, pos: number, isTypeOnly: boolean) { + function parseImportClause(identifier: ts.Identifier | undefined, pos: number, isTypeOnly: boolean) { // ImportClause: // ImportedDefaultBinding // NameSpaceImport @@ -7471,10 +7303,10 @@ namespace ts { // If there was no default import or if there is comma token after default import // parse namespace or named imports - let namedBindings: NamespaceImport | NamedImports | undefined; + let namedBindings: ts.NamespaceImport | ts.NamedImports | undefined; if (!identifier || - parseOptional(SyntaxKind.CommaToken)) { - namedBindings = token() === SyntaxKind.AsteriskToken ? parseNamespaceImport() : parseNamedImportsOrExports(SyntaxKind.NamedImports); + parseOptional(ts.SyntaxKind.CommaToken)) { + namedBindings = token() === ts.SyntaxKind.AsteriskToken ? parseNamespaceImport() : parseNamedImportsOrExports(ts.SyntaxKind.NamedImports); } return finishNode(factory.createImportClause(isTypeOnly, identifier, namedBindings), pos); @@ -7488,15 +7320,15 @@ namespace ts { function parseExternalModuleReference() { const pos = getNodePos(); - parseExpected(SyntaxKind.RequireKeyword); - parseExpected(SyntaxKind.OpenParenToken); + parseExpected(ts.SyntaxKind.RequireKeyword); + parseExpected(ts.SyntaxKind.OpenParenToken); const expression = parseModuleSpecifier(); - parseExpected(SyntaxKind.CloseParenToken); + parseExpected(ts.SyntaxKind.CloseParenToken); return finishNode(factory.createExternalModuleReference(expression), pos); } - function parseModuleSpecifier(): Expression { - if (token() === SyntaxKind.StringLiteral) { + function parseModuleSpecifier(): ts.Expression { + if (token() === ts.SyntaxKind.StringLiteral) { const result = parseLiteralNode(); result.text = internIdentifier(result.text); return result; @@ -7509,19 +7341,19 @@ namespace ts { } } - function parseNamespaceImport(): NamespaceImport { + function parseNamespaceImport(): ts.NamespaceImport { // NameSpaceImport: // * as ImportedBinding const pos = getNodePos(); - parseExpected(SyntaxKind.AsteriskToken); - parseExpected(SyntaxKind.AsKeyword); + parseExpected(ts.SyntaxKind.AsteriskToken); + parseExpected(ts.SyntaxKind.AsKeyword); const name = parseIdentifier(); return finishNode(factory.createNamespaceImport(name), pos); } - function parseNamedImportsOrExports(kind: SyntaxKind.NamedImports): NamedImports; - function parseNamedImportsOrExports(kind: SyntaxKind.NamedExports): NamedExports; - function parseNamedImportsOrExports(kind: SyntaxKind): NamedImportsOrExports { + function parseNamedImportsOrExports(kind: ts.SyntaxKind.NamedImports): ts.NamedImports; + function parseNamedImportsOrExports(kind: ts.SyntaxKind.NamedExports): ts.NamedExports; + function parseNamedImportsOrExports(kind: ts.SyntaxKind): ts.NamedImportsOrExports { const pos = getNodePos(); // NamedImports: @@ -7532,22 +7364,22 @@ namespace ts { // ImportsList: // ImportSpecifier // ImportsList, ImportSpecifier - const node = kind === SyntaxKind.NamedImports - ? factory.createNamedImports(parseBracketedList(ParsingContext.ImportOrExportSpecifiers, parseImportSpecifier, SyntaxKind.OpenBraceToken, SyntaxKind.CloseBraceToken)) - : factory.createNamedExports(parseBracketedList(ParsingContext.ImportOrExportSpecifiers, parseExportSpecifier, SyntaxKind.OpenBraceToken, SyntaxKind.CloseBraceToken)); + const node = kind === ts.SyntaxKind.NamedImports + ? factory.createNamedImports(parseBracketedList(ParsingContext.ImportOrExportSpecifiers, parseImportSpecifier, ts.SyntaxKind.OpenBraceToken, ts.SyntaxKind.CloseBraceToken)) + : factory.createNamedExports(parseBracketedList(ParsingContext.ImportOrExportSpecifiers, parseExportSpecifier, ts.SyntaxKind.OpenBraceToken, ts.SyntaxKind.CloseBraceToken)); return finishNode(node, pos); } function parseExportSpecifier() { const hasJSDoc = hasPrecedingJSDocComment(); - return withJSDoc(parseImportOrExportSpecifier(SyntaxKind.ExportSpecifier) as ExportSpecifier, hasJSDoc); + return withJSDoc(parseImportOrExportSpecifier(ts.SyntaxKind.ExportSpecifier) as ts.ExportSpecifier, hasJSDoc); } function parseImportSpecifier() { - return parseImportOrExportSpecifier(SyntaxKind.ImportSpecifier) as ImportSpecifier; + return parseImportOrExportSpecifier(ts.SyntaxKind.ImportSpecifier) as ts.ImportSpecifier; } - function parseImportOrExportSpecifier(kind: SyntaxKind): ImportOrExportSpecifier { + function parseImportOrExportSpecifier(kind: ts.SyntaxKind): ts.ImportOrExportSpecifier { const pos = getNodePos(); // ImportSpecifier: // BindingIdentifier @@ -7555,11 +7387,11 @@ namespace ts { // ExportSpecifier: // IdentifierName // IdentifierName as IdentifierName - let checkIdentifierIsKeyword = isKeyword(token()) && !isIdentifier(); + let checkIdentifierIsKeyword = ts.isKeyword(token()) && !isIdentifier(); let checkIdentifierStart = scanner.getTokenPos(); let checkIdentifierEnd = scanner.getTextPos(); let isTypeOnly = false; - let propertyName: Identifier | undefined; + let propertyName: ts.Identifier | undefined; let canParseAsKeyword = true; let name = parseIdentifierName(); if (name.escapedText === "type") { @@ -7570,13 +7402,13 @@ namespace ts { // import { type as } from "mod"; - isTypeOnly: true, name: as // import { type as as } from "mod"; - isTypeOnly: false, name: as, propertyName: type // import { type as as as } from "mod"; - isTypeOnly: true, name: as, propertyName: as - if (token() === SyntaxKind.AsKeyword) { + if (token() === ts.SyntaxKind.AsKeyword) { // { type as ...? } const firstAs = parseIdentifierName(); - if (token() === SyntaxKind.AsKeyword) { + if (token() === ts.SyntaxKind.AsKeyword) { // { type as as ...? } const secondAs = parseIdentifierName(); - if (tokenIsIdentifierOrKeyword(token())) { + if (ts.tokenIsIdentifierOrKeyword(token())) { // { type as as something } isTypeOnly = true; propertyName = firstAs; @@ -7590,7 +7422,7 @@ namespace ts { canParseAsKeyword = false; } } - else if (tokenIsIdentifierOrKeyword(token())) { + else if (ts.tokenIsIdentifierOrKeyword(token())) { // { type as something } propertyName = name; canParseAsKeyword = false; @@ -7602,64 +7434,64 @@ namespace ts { name = firstAs; } } - else if (tokenIsIdentifierOrKeyword(token())) { + else if (ts.tokenIsIdentifierOrKeyword(token())) { // { type something ...? } isTypeOnly = true; name = parseNameWithKeywordCheck(); } } - if (canParseAsKeyword && token() === SyntaxKind.AsKeyword) { + if (canParseAsKeyword && token() === ts.SyntaxKind.AsKeyword) { propertyName = name; - parseExpected(SyntaxKind.AsKeyword); + parseExpected(ts.SyntaxKind.AsKeyword); name = parseNameWithKeywordCheck(); } - if (kind === SyntaxKind.ImportSpecifier && checkIdentifierIsKeyword) { - parseErrorAt(checkIdentifierStart, checkIdentifierEnd, Diagnostics.Identifier_expected); + if (kind === ts.SyntaxKind.ImportSpecifier && checkIdentifierIsKeyword) { + parseErrorAt(checkIdentifierStart, checkIdentifierEnd, ts.Diagnostics.Identifier_expected); } - const node = kind === SyntaxKind.ImportSpecifier + const node = kind === ts.SyntaxKind.ImportSpecifier ? factory.createImportSpecifier(isTypeOnly, propertyName, name) : factory.createExportSpecifier(isTypeOnly, propertyName, name); return finishNode(node, pos); function parseNameWithKeywordCheck() { - checkIdentifierIsKeyword = isKeyword(token()) && !isIdentifier(); + checkIdentifierIsKeyword = ts.isKeyword(token()) && !isIdentifier(); checkIdentifierStart = scanner.getTokenPos(); checkIdentifierEnd = scanner.getTextPos(); return parseIdentifierName(); } } - function parseNamespaceExport(pos: number): NamespaceExport { + function parseNamespaceExport(pos: number): ts.NamespaceExport { return finishNode(factory.createNamespaceExport(parseIdentifierName()), pos); } - function parseExportDeclaration(pos: number, hasJSDoc: boolean, decorators: NodeArray | undefined, modifiers: NodeArray | undefined): ExportDeclaration { + function parseExportDeclaration(pos: number, hasJSDoc: boolean, decorators: ts.NodeArray | undefined, modifiers: ts.NodeArray | undefined): ts.ExportDeclaration { const savedAwaitContext = inAwaitContext(); setAwaitContext(/*value*/ true); - let exportClause: NamedExportBindings | undefined; - let moduleSpecifier: Expression | undefined; - let assertClause: AssertClause | undefined; - const isTypeOnly = parseOptional(SyntaxKind.TypeKeyword); + let exportClause: ts.NamedExportBindings | undefined; + let moduleSpecifier: ts.Expression | undefined; + let assertClause: ts.AssertClause | undefined; + const isTypeOnly = parseOptional(ts.SyntaxKind.TypeKeyword); const namespaceExportPos = getNodePos(); - if (parseOptional(SyntaxKind.AsteriskToken)) { - if (parseOptional(SyntaxKind.AsKeyword)) { + if (parseOptional(ts.SyntaxKind.AsteriskToken)) { + if (parseOptional(ts.SyntaxKind.AsKeyword)) { exportClause = parseNamespaceExport(namespaceExportPos); } - parseExpected(SyntaxKind.FromKeyword); + parseExpected(ts.SyntaxKind.FromKeyword); moduleSpecifier = parseModuleSpecifier(); } else { - exportClause = parseNamedImportsOrExports(SyntaxKind.NamedExports); + exportClause = parseNamedImportsOrExports(ts.SyntaxKind.NamedExports); // It is not uncommon to accidentally omit the 'from' keyword. Additionally, in editing scenarios, // the 'from' keyword can be parsed as a named export when the export clause is unterminated (i.e. `export { from "moduleName";`) // If we don't have a 'from' keyword, see if we have a string literal such that ASI won't take effect. - if (token() === SyntaxKind.FromKeyword || (token() === SyntaxKind.StringLiteral && !scanner.hasPrecedingLineBreak())) { - parseExpected(SyntaxKind.FromKeyword); + if (token() === ts.SyntaxKind.FromKeyword || (token() === ts.SyntaxKind.StringLiteral && !scanner.hasPrecedingLineBreak())) { + parseExpected(ts.SyntaxKind.FromKeyword); moduleSpecifier = parseModuleSpecifier(); } } - if (moduleSpecifier && token() === SyntaxKind.AssertKeyword && !scanner.hasPrecedingLineBreak()) { + if (moduleSpecifier && token() === ts.SyntaxKind.AssertKeyword && !scanner.hasPrecedingLineBreak()) { assertClause = parseAssertClause(); } parseSemicolon(); @@ -7668,15 +7500,15 @@ namespace ts { return withJSDoc(finishNode(node, pos), hasJSDoc); } - function parseExportAssignment(pos: number, hasJSDoc: boolean, decorators: NodeArray | undefined, modifiers: NodeArray | undefined): ExportAssignment { + function parseExportAssignment(pos: number, hasJSDoc: boolean, decorators: ts.NodeArray | undefined, modifiers: ts.NodeArray | undefined): ts.ExportAssignment { const savedAwaitContext = inAwaitContext(); setAwaitContext(/*value*/ true); let isExportEquals: boolean | undefined; - if (parseOptional(SyntaxKind.EqualsToken)) { + if (parseOptional(ts.SyntaxKind.EqualsToken)) { isExportEquals = true; } else { - parseExpected(SyntaxKind.DefaultKeyword); + parseExpected(ts.SyntaxKind.DefaultKeyword); } const expression = parseAssignmentExpressionOrHigher(); parseSemicolon(); @@ -7686,31 +7518,31 @@ namespace ts { } const enum ParsingContext { - SourceElements, // Elements in source file - BlockStatements, // Statements in block - SwitchClauses, // Clauses in switch statement - SwitchClauseStatements, // Statements in switch clause - TypeMembers, // Members in interface or type literal - ClassMembers, // Members in class declaration - EnumMembers, // Members in enum declaration - HeritageClauseElement, // Elements in a heritage clause - VariableDeclarations, // Variable declarations in variable statement - ObjectBindingElements, // Binding elements in object binding list - ArrayBindingElements, // Binding elements in array binding list - ArgumentExpressions, // Expressions in argument list - ObjectLiteralMembers, // Members in object literal - JsxAttributes, // Attributes in jsx element - JsxChildren, // Things between opening and closing JSX tags - ArrayLiteralMembers, // Members in array literal - Parameters, // Parameters in parameter list - JSDocParameters, // JSDoc parameters in parameter list of JSDoc function type - RestProperties, // Property names in a rest type list - TypeParameters, // Type parameters in type parameter list - TypeArguments, // Type arguments in type argument list - TupleElementTypes, // Element types in tuple element type list - HeritageClauses, // Heritage clauses for a class or interface declaration. - ImportOrExportSpecifiers, // Named import clause's import specifier list, - AssertEntries, // Import entries list. + SourceElements, + BlockStatements, + SwitchClauses, + SwitchClauseStatements, + TypeMembers, + ClassMembers, + EnumMembers, + HeritageClauseElement, + VariableDeclarations, + ObjectBindingElements, + ArrayBindingElements, + ArgumentExpressions, + ObjectLiteralMembers, + JsxAttributes, + JsxChildren, + ArrayLiteralMembers, + Parameters, + JSDocParameters, + RestProperties, + TypeParameters, + TypeArguments, + TupleElementTypes, + HeritageClauses, + ImportOrExportSpecifiers, + AssertEntries, Count // Number of parsing contexts } @@ -7721,16 +7553,19 @@ namespace ts { } export namespace JSDocParser { - export function parseJSDocTypeExpressionForTests(content: string, start: number | undefined, length: number | undefined): { jsDocTypeExpression: JSDocTypeExpression, diagnostics: Diagnostic[] } | undefined { - initializeState("file.js", content, ScriptTarget.Latest, /*_syntaxCursor:*/ undefined, ScriptKind.JS); + export function parseJSDocTypeExpressionForTests(content: string, start: number | undefined, length: number | undefined): { + jsDocTypeExpression: ts.JSDocTypeExpression; + diagnostics: ts.Diagnostic[]; + } | undefined { + initializeState("file.js", content, ts.ScriptTarget.Latest, /*_syntaxCursor:*/ undefined, ts.ScriptKind.JS); scanner.setText(content, start, length); currentToken = scanner.scan(); const jsDocTypeExpression = parseJSDocTypeExpression(); - const sourceFile = createSourceFile("file.js", ScriptTarget.Latest, ScriptKind.JS, /*isDeclarationFile*/ false, [], factory.createToken(SyntaxKind.EndOfFileToken), NodeFlags.None, noop); - const diagnostics = attachFileToDiagnostics(parseDiagnostics, sourceFile); + const sourceFile = createSourceFile("file.js", ts.ScriptTarget.Latest, ts.ScriptKind.JS, /*isDeclarationFile*/ false, [], factory.createToken(ts.SyntaxKind.EndOfFileToken), ts.NodeFlags.None, ts.noop); + const diagnostics = ts.attachFileToDiagnostics(parseDiagnostics, sourceFile); if (jsDocDiagnostics) { - sourceFile.jsDocDiagnostics = attachFileToDiagnostics(jsDocDiagnostics, sourceFile); + sourceFile.jsDocDiagnostics = ts.attachFileToDiagnostics(jsDocDiagnostics, sourceFile); } clearState(); @@ -7739,12 +7574,12 @@ namespace ts { } // Parses out a JSDoc type expression. - export function parseJSDocTypeExpression(mayOmitBraces?: boolean): JSDocTypeExpression { + export function parseJSDocTypeExpression(mayOmitBraces?: boolean): ts.JSDocTypeExpression { const pos = getNodePos(); - const hasBrace = (mayOmitBraces ? parseOptional : parseExpected)(SyntaxKind.OpenBraceToken); - const type = doInsideOfContext(NodeFlags.JSDoc, parseJSDocType); + const hasBrace = (mayOmitBraces ? parseOptional : parseExpected)(ts.SyntaxKind.OpenBraceToken); + const type = doInsideOfContext(ts.NodeFlags.JSDoc, parseJSDocType); if (!mayOmitBraces || hasBrace) { - parseExpectedJSDoc(SyntaxKind.CloseBraceToken); + parseExpectedJSDoc(ts.SyntaxKind.CloseBraceToken); } const result = factory.createJSDocTypeExpression(type); @@ -7752,18 +7587,18 @@ namespace ts { return finishNode(result, pos); } - export function parseJSDocNameReference(): JSDocNameReference { + export function parseJSDocNameReference(): ts.JSDocNameReference { const pos = getNodePos(); - const hasBrace = parseOptional(SyntaxKind.OpenBraceToken); + const hasBrace = parseOptional(ts.SyntaxKind.OpenBraceToken); const p2 = getNodePos(); - let entityName: EntityName | JSDocMemberName = parseEntityName(/* allowReservedWords*/ false); - while (token() === SyntaxKind.PrivateIdentifier) { + let entityName: ts.EntityName | ts.JSDocMemberName = parseEntityName(/* allowReservedWords*/ false); + while (token() === ts.SyntaxKind.PrivateIdentifier) { reScanHashToken(); // rescan #id as # id nextTokenJSDoc(); // then skip the # entityName = finishNode(factory.createJSDocMemberName(entityName, parseIdentifier()), p2); } if (hasBrace) { - parseExpectedJSDoc(SyntaxKind.CloseBraceToken); + parseExpectedJSDoc(ts.SyntaxKind.CloseBraceToken); } const result = factory.createJSDocNameReference(entityName); @@ -7771,26 +7606,27 @@ namespace ts { return finishNode(result, pos); } - export function parseIsolatedJSDocComment(content: string, start: number | undefined, length: number | undefined): { jsDoc: JSDoc, diagnostics: Diagnostic[] } | undefined { - initializeState("", content, ScriptTarget.Latest, /*_syntaxCursor:*/ undefined, ScriptKind.JS); - const jsDoc = doInsideOfContext(NodeFlags.JSDoc, () => parseJSDocCommentWorker(start, length)); - - const sourceFile = { languageVariant: LanguageVariant.Standard, text: content } as SourceFile; - const diagnostics = attachFileToDiagnostics(parseDiagnostics, sourceFile); + export function parseIsolatedJSDocComment(content: string, start: number | undefined, length: number | undefined): { + jsDoc: ts.JSDoc; + diagnostics: ts.Diagnostic[]; + } | undefined { + initializeState("", content, ts.ScriptTarget.Latest, /*_syntaxCursor:*/ undefined, ts.ScriptKind.JS); + const jsDoc = doInsideOfContext(ts.NodeFlags.JSDoc, () => parseJSDocCommentWorker(start, length)); + const sourceFile = { languageVariant: ts.LanguageVariant.Standard, text: content } as ts.SourceFile; + const diagnostics = ts.attachFileToDiagnostics(parseDiagnostics, sourceFile); clearState(); return jsDoc ? { jsDoc, diagnostics } : undefined; } - export function parseJSDocComment(parent: HasJSDoc, start: number, length: number): JSDoc | undefined { + export function parseJSDocComment(parent: ts.HasJSDoc, start: number, length: number): ts.JSDoc | undefined { const saveToken = currentToken; const saveParseDiagnosticsLength = parseDiagnostics.length; const saveParseErrorBeforeNextFinishedNode = parseErrorBeforeNextFinishedNode; - const comment = doInsideOfContext(NodeFlags.JSDoc, () => parseJSDocCommentWorker(start, length)); - setParent(comment, parent); - - if (contextFlags & NodeFlags.JavaScriptFile) { + const comment = doInsideOfContext(ts.NodeFlags.JSDoc, () => parseJSDocCommentWorker(start, length)); + ts.setParent(comment, parent); + if (contextFlags & ts.NodeFlags.JavaScriptFile) { if (!jsDocDiagnostics) { jsDocDiagnostics = []; } @@ -7806,36 +7642,36 @@ namespace ts { BeginningOfLine, SawAsterisk, SavingComments, - SavingBackticks, // NOTE: Only used when parsing tag comments + SavingBackticks } const enum PropertyLikeParse { Property = 1 << 0, Parameter = 1 << 1, - CallbackParameter = 1 << 2, + CallbackParameter = 1 << 2 } - function parseJSDocCommentWorker(start = 0, length: number | undefined): JSDoc | undefined { + function parseJSDocCommentWorker(start = 0, length: number | undefined): ts.JSDoc | undefined { const content = sourceText; const end = length === undefined ? content.length : start + length; length = end - start; - Debug.assert(start >= 0); - Debug.assert(start <= end); - Debug.assert(end <= content.length); + ts.Debug.assert(start >= 0); + ts.Debug.assert(start <= end); + ts.Debug.assert(end <= content.length); // Check for /** (JSDoc opening part) if (!isJSDocLikeText(content, start)) { return undefined; } - let tags: JSDocTag[]; + let tags: ts.JSDocTag[]; let tagsPos: number; let tagsEnd: number; let linkEnd: number; let commentsPos: number | undefined; let comments: string[] = []; - const parts: JSDocComment[] = []; + const parts: ts.JSDocComment[] = []; // + 3 for leading /**, - 5 in total for /** */ return scanner.scanRange(start + 3, length - 5, () => { @@ -7855,17 +7691,19 @@ namespace ts { } nextTokenJSDoc(); - while (parseOptionalJsdoc(SyntaxKind.WhitespaceTrivia)); - if (parseOptionalJsdoc(SyntaxKind.NewLineTrivia)) { + while (parseOptionalJsdoc(ts.SyntaxKind.WhitespaceTrivia)) + ; + if (parseOptionalJsdoc(ts.SyntaxKind.NewLineTrivia)) { state = JSDocState.BeginningOfLine; indent = 0; } loop: while (true) { switch (token()) { - case SyntaxKind.AtToken: + case ts.SyntaxKind.AtToken: if (state === JSDocState.BeginningOfLine || state === JSDocState.SawAsterisk) { removeTrailingWhitespace(comments); - if (!commentsPos) commentsPos = getNodePos(); + if (!commentsPos) + commentsPos = getNodePos(); addTag(parseTag(indent)); // NOTE: According to usejsdoc.org, a tag goes to end of line, except the last tag. // Real-world comments may break this rule, so "BeginningOfLine" will not be a real line beginning @@ -7877,12 +7715,12 @@ namespace ts { pushComment(scanner.getTokenText()); } break; - case SyntaxKind.NewLineTrivia: + case ts.SyntaxKind.NewLineTrivia: comments.push(scanner.getTokenText()); state = JSDocState.BeginningOfLine; indent = 0; break; - case SyntaxKind.AsteriskToken: + case ts.SyntaxKind.AsteriskToken: const asterisk = scanner.getTokenText(); if (state === JSDocState.SawAsterisk || state === JSDocState.SavingComments) { // If we've already seen an asterisk, then we can no longer parse a tag on this line @@ -7895,7 +7733,7 @@ namespace ts { indent += asterisk.length; } break; - case SyntaxKind.WhitespaceTrivia: + case ts.SyntaxKind.WhitespaceTrivia: // only collect whitespace if we're already saving comments or have just crossed the comment indent margin const whitespace = scanner.getTokenText(); if (state === JSDocState.SavingComments) { @@ -7906,9 +7744,9 @@ namespace ts { } indent += whitespace.length; break; - case SyntaxKind.EndOfFileToken: + case ts.SyntaxKind.EndOfFileToken: break loop; - case SyntaxKind.OpenBraceToken: + case ts.SyntaxKind.OpenBraceToken: state = JSDocState.SavingComments; const commentEnd = scanner.getStartPos(); const linkStart = scanner.getTextPos() - 1; @@ -7938,7 +7776,8 @@ namespace ts { if (parts.length && comments.length) { parts.push(finishNode(factory.createJSDocText(comments.join("")), linkEnd ?? start, commentsPos)); } - if (parts.length && tags) Debug.assertIsDefined(commentsPos, "having parsed tags implies that the end of the comment span should be set"); + if (parts.length && tags) + ts.Debug.assertIsDefined(commentsPos, "having parsed tags implies that the end of the comment span should be set"); const tagsArray = tags && createNodeArray(tags, tagsPos, tagsEnd); return finishNode(factory.createJSDocComment(parts.length ? createNodeArray(parts, start, commentsPos) : comments.length ? comments.join("") : undefined, tagsArray), start, end); }); @@ -7959,28 +7798,28 @@ namespace ts { // We must use infinite lookahead, as there could be any number of newlines :( while (true) { nextTokenJSDoc(); - if (token() === SyntaxKind.EndOfFileToken) { + if (token() === ts.SyntaxKind.EndOfFileToken) { return true; } - if (!(token() === SyntaxKind.WhitespaceTrivia || token() === SyntaxKind.NewLineTrivia)) { + if (!(token() === ts.SyntaxKind.WhitespaceTrivia || token() === ts.SyntaxKind.NewLineTrivia)) { return false; } } } function skipWhitespace(): void { - if (token() === SyntaxKind.WhitespaceTrivia || token() === SyntaxKind.NewLineTrivia) { + if (token() === ts.SyntaxKind.WhitespaceTrivia || token() === ts.SyntaxKind.NewLineTrivia) { if (lookAhead(isNextNonwhitespaceTokenEndOfFile)) { return; // Don't skip whitespace prior to EoF (or end of comment) - that shouldn't be included in any node's range } } - while (token() === SyntaxKind.WhitespaceTrivia || token() === SyntaxKind.NewLineTrivia) { + while (token() === ts.SyntaxKind.WhitespaceTrivia || token() === ts.SyntaxKind.NewLineTrivia) { nextTokenJSDoc(); } } function skipWhitespaceOrAsterisk(): string { - if (token() === SyntaxKind.WhitespaceTrivia || token() === SyntaxKind.NewLineTrivia) { + if (token() === ts.SyntaxKind.WhitespaceTrivia || token() === ts.SyntaxKind.NewLineTrivia) { if (lookAhead(isNextNonwhitespaceTokenEndOfFile)) { return ""; // Don't skip whitespace prior to EoF (or end of comment) - that shouldn't be included in any node's range } @@ -7989,14 +7828,14 @@ namespace ts { let precedingLineBreak = scanner.hasPrecedingLineBreak(); let seenLineBreak = false; let indentText = ""; - while ((precedingLineBreak && token() === SyntaxKind.AsteriskToken) || token() === SyntaxKind.WhitespaceTrivia || token() === SyntaxKind.NewLineTrivia) { + while ((precedingLineBreak && token() === ts.SyntaxKind.AsteriskToken) || token() === ts.SyntaxKind.WhitespaceTrivia || token() === ts.SyntaxKind.NewLineTrivia) { indentText += scanner.getTokenText(); - if (token() === SyntaxKind.NewLineTrivia) { + if (token() === ts.SyntaxKind.NewLineTrivia) { precedingLineBreak = true; seenLineBreak = true; indentText = ""; } - else if (token() === SyntaxKind.AsteriskToken) { + else if (token() === ts.SyntaxKind.AsteriskToken) { precedingLineBreak = false; } nextTokenJSDoc(); @@ -8005,14 +7844,14 @@ namespace ts { } function parseTag(margin: number) { - Debug.assert(token() === SyntaxKind.AtToken); + ts.Debug.assert(token() === ts.SyntaxKind.AtToken); const start = scanner.getTokenPos(); nextTokenJSDoc(); const tagName = parseJSDocIdentifierName(/*message*/ undefined); const indentText = skipWhitespaceOrAsterisk(); - let tag: JSDocTag | undefined; + let tag: ts.JSDocTag | undefined; switch (tagName.escapedText) { case "author": tag = parseAuthorTag(start, tagName, margin, indentText); @@ -8091,10 +7930,10 @@ namespace ts { return parseTagComments(margin, indentText.slice(margin)); } - function parseTagComments(indent: number, initialMargin?: string): string | NodeArray | undefined { + function parseTagComments(indent: number, initialMargin?: string): string | ts.NodeArray | undefined { const commentsPos = getNodePos(); let comments: string[] = []; - const parts: JSDocComment[] = []; + const parts: ts.JSDocComment[] = []; let linkEnd; let state = JSDocState.BeginningOfLine; let previousWhitespace = true; @@ -8113,16 +7952,16 @@ namespace ts { } state = JSDocState.SawAsterisk; } - let tok = token() as JSDocSyntaxKind; + let tok = token() as ts.JSDocSyntaxKind; loop: while (true) { switch (tok) { - case SyntaxKind.NewLineTrivia: + case ts.SyntaxKind.NewLineTrivia: state = JSDocState.BeginningOfLine; // don't use pushComment here because we want to keep the margin unchanged comments.push(scanner.getTokenText()); indent = 0; break; - case SyntaxKind.AtToken: + case ts.SyntaxKind.AtToken: if (state === JSDocState.SavingBackticks || state === JSDocState.SavingComments && (!previousWhitespace || lookAhead(isNextJSDocTokenWhitespace))) { // @ doesn't start a new tag inside ``, and inside a comment, only after whitespace or not before whitespace @@ -8131,10 +7970,10 @@ namespace ts { } scanner.setTextPos(scanner.getTextPos() - 1); // falls through - case SyntaxKind.EndOfFileToken: + case ts.SyntaxKind.EndOfFileToken: // Done break loop; - case SyntaxKind.WhitespaceTrivia: + case ts.SyntaxKind.WhitespaceTrivia: if (state === JSDocState.SavingComments || state === JSDocState.SavingBackticks) { pushComment(scanner.getTokenText()); } @@ -8147,7 +7986,7 @@ namespace ts { indent += whitespace.length; } break; - case SyntaxKind.OpenBraceToken: + case ts.SyntaxKind.OpenBraceToken: state = JSDocState.SavingComments; const commentEnd = scanner.getStartPos(); const linkStart = scanner.getTextPos() - 1; @@ -8162,7 +8001,7 @@ namespace ts { pushComment(scanner.getTokenText()); } break; - case SyntaxKind.BacktickToken: + case ts.SyntaxKind.BacktickToken: if (state === JSDocState.SavingBackticks) { state = JSDocState.SavingComments; } @@ -8171,7 +8010,7 @@ namespace ts { } pushComment(scanner.getTokenText()); break; - case SyntaxKind.AsteriskToken: + case ts.SyntaxKind.AsteriskToken: if (state === JSDocState.BeginningOfLine) { // leading asterisks start recording on the *next* (non-whitespace) token state = JSDocState.SawAsterisk; @@ -8187,7 +8026,7 @@ namespace ts { pushComment(scanner.getTokenText()); break; } - previousWhitespace = token() === SyntaxKind.WhitespaceTrivia; + previousWhitespace = token() === ts.SyntaxKind.WhitespaceTrivia; tok = nextTokenJSDoc(); } @@ -8206,7 +8045,7 @@ namespace ts { function isNextJSDocTokenWhitespace() { const next = nextTokenJSDoc(); - return next === SyntaxKind.WhitespaceTrivia || next === SyntaxKind.NewLineTrivia; + return next === ts.SyntaxKind.WhitespaceTrivia || next === ts.SyntaxKind.NewLineTrivia; } function parseJSDocLink(start: number) { @@ -8218,18 +8057,18 @@ namespace ts { skipWhitespace(); // parseEntityName logs an error for non-identifier, so create a MissingNode ourselves to avoid the error const p2 = getNodePos(); - let name: EntityName | JSDocMemberName | undefined = tokenIsIdentifierOrKeyword(token()) + let name: ts.EntityName | ts.JSDocMemberName | undefined = ts.tokenIsIdentifierOrKeyword(token()) ? parseEntityName(/*allowReservedWords*/ true) : undefined; if (name) { - while (token() === SyntaxKind.PrivateIdentifier) { + while (token() === ts.SyntaxKind.PrivateIdentifier) { reScanHashToken(); // rescan #id as # id nextTokenJSDoc(); // then skip the # name = finishNode(factory.createJSDocMemberName(name, parseIdentifier()), p2); } } const text = []; - while (token() !== SyntaxKind.CloseBraceToken && token() !== SyntaxKind.NewLineTrivia && token() !== SyntaxKind.EndOfFileToken) { + while (token() !== ts.SyntaxKind.CloseBraceToken && token() !== ts.SyntaxKind.NewLineTrivia && token() !== ts.SyntaxKind.EndOfFileToken) { text.push(scanner.getTokenText()); nextTokenJSDoc(); } @@ -8241,11 +8080,12 @@ namespace ts { function parseJSDocLinkPrefix() { skipWhitespaceOrAsterisk(); - if (token() === SyntaxKind.OpenBraceToken - && nextTokenJSDoc() === SyntaxKind.AtToken - && tokenIsIdentifierOrKeyword(nextTokenJSDoc())) { + if (token() === ts.SyntaxKind.OpenBraceToken + && nextTokenJSDoc() === ts.SyntaxKind.AtToken + && ts.tokenIsIdentifierOrKeyword(nextTokenJSDoc())) { const kind = scanner.getTokenValue(); - if (isJSDocLinkTag(kind)) return kind; + if (isJSDocLinkTag(kind)) + return kind; } } @@ -8253,11 +8093,11 @@ namespace ts { return kind === "link" || kind === "linkcode" || kind === "linkplain"; } - function parseUnknownTag(start: number, tagName: Identifier, indent: number, indentText: string) { + function parseUnknownTag(start: number, tagName: ts.Identifier, indent: number, indentText: string) { return finishNode(factory.createJSDocUnknownTag(tagName, parseTrailingTagComments(start, getNodePos(), indent, indentText)), start); } - function addTag(tag: JSDocTag | undefined): void { + function addTag(tag: ts.JSDocTag | undefined): void { if (!tag) { return; } @@ -8271,48 +8111,51 @@ namespace ts { tagsEnd = tag.end; } - function tryParseTypeExpression(): JSDocTypeExpression | undefined { + function tryParseTypeExpression(): ts.JSDocTypeExpression | undefined { skipWhitespaceOrAsterisk(); - return token() === SyntaxKind.OpenBraceToken ? parseJSDocTypeExpression() : undefined; + return token() === ts.SyntaxKind.OpenBraceToken ? parseJSDocTypeExpression() : undefined; } - function parseBracketNameInPropertyAndParamTag(): { name: EntityName, isBracketed: boolean } { + function parseBracketNameInPropertyAndParamTag(): { + name: ts.EntityName; + isBracketed: boolean; + } { // Looking for something like '[foo]', 'foo', '[foo.bar]' or 'foo.bar' - const isBracketed = parseOptionalJsdoc(SyntaxKind.OpenBracketToken); + const isBracketed = parseOptionalJsdoc(ts.SyntaxKind.OpenBracketToken); if (isBracketed) { skipWhitespace(); } // a markdown-quoted name: `arg` is not legal jsdoc, but occurs in the wild - const isBackquoted = parseOptionalJsdoc(SyntaxKind.BacktickToken); + const isBackquoted = parseOptionalJsdoc(ts.SyntaxKind.BacktickToken); const name = parseJSDocEntityName(); if (isBackquoted) { - parseExpectedTokenJSDoc(SyntaxKind.BacktickToken); + parseExpectedTokenJSDoc(ts.SyntaxKind.BacktickToken); } if (isBracketed) { skipWhitespace(); // May have an optional default, e.g. '[foo = 42]' - if (parseOptionalToken(SyntaxKind.EqualsToken)) { + if (parseOptionalToken(ts.SyntaxKind.EqualsToken)) { parseExpression(); } - parseExpected(SyntaxKind.CloseBracketToken); + parseExpected(ts.SyntaxKind.CloseBracketToken); } return { name, isBracketed }; } - function isObjectOrObjectArrayTypeReference(node: TypeNode): boolean { + function isObjectOrObjectArrayTypeReference(node: ts.TypeNode): boolean { switch (node.kind) { - case SyntaxKind.ObjectKeyword: + case ts.SyntaxKind.ObjectKeyword: return true; - case SyntaxKind.ArrayType: - return isObjectOrObjectArrayTypeReference((node as ArrayTypeNode).elementType); + case ts.SyntaxKind.ArrayType: + return isObjectOrObjectArrayTypeReference((node as ts.ArrayTypeNode).elementType); default: - return isTypeReferenceNode(node) && ts.isIdentifier(node.typeName) && node.typeName.escapedText === "Object" && !node.typeArguments; + return ts.isTypeReferenceNode(node) && ts.isIdentifier(node.typeName) && node.typeName.escapedText === "Object" && !node.typeArguments; } } - function parseParameterOrPropertyTag(start: number, tagName: Identifier, target: PropertyLikeParse, indent: number): JSDocParameterTag | JSDocPropertyTag { + function parseParameterOrPropertyTag(start: number, tagName: ts.Identifier, target: PropertyLikeParse, indent: number): ts.JSDocParameterTag | ts.JSDocPropertyTag { let typeExpression = tryParseTypeExpression(); let isNameFirst = !typeExpression; skipWhitespaceOrAsterisk(); @@ -8337,35 +8180,35 @@ namespace ts { return finishNode(result, start); } - function parseNestedTypeLiteral(typeExpression: JSDocTypeExpression | undefined, name: EntityName, target: PropertyLikeParse, indent: number) { + function parseNestedTypeLiteral(typeExpression: ts.JSDocTypeExpression | undefined, name: ts.EntityName, target: PropertyLikeParse, indent: number) { if (typeExpression && isObjectOrObjectArrayTypeReference(typeExpression.type)) { const pos = getNodePos(); - let child: JSDocPropertyLikeTag | JSDocTypeTag | false; - let children: JSDocPropertyLikeTag[] | undefined; + let child: ts.JSDocPropertyLikeTag | ts.JSDocTypeTag | false; + let children: ts.JSDocPropertyLikeTag[] | undefined; while (child = tryParse(() => parseChildParameterOrPropertyTag(target, indent, name))) { - if (child.kind === SyntaxKind.JSDocParameterTag || child.kind === SyntaxKind.JSDocPropertyTag) { - children = append(children, child); + if (child.kind === ts.SyntaxKind.JSDocParameterTag || child.kind === ts.SyntaxKind.JSDocPropertyTag) { + children = ts.append(children, child); } } if (children) { - const literal = finishNode(factory.createJSDocTypeLiteral(children, typeExpression.type.kind === SyntaxKind.ArrayType), pos); + const literal = finishNode(factory.createJSDocTypeLiteral(children, typeExpression.type.kind === ts.SyntaxKind.ArrayType), pos); return finishNode(factory.createJSDocTypeExpression(literal), pos); } } } - function parseReturnTag(start: number, tagName: Identifier, indent: number, indentText: string): JSDocReturnTag { - if (some(tags, isJSDocReturnTag)) { - parseErrorAt(tagName.pos, scanner.getTokenPos(), Diagnostics._0_tag_already_specified, tagName.escapedText); + function parseReturnTag(start: number, tagName: ts.Identifier, indent: number, indentText: string): ts.JSDocReturnTag { + if (ts.some(tags, ts.isJSDocReturnTag)) { + parseErrorAt(tagName.pos, scanner.getTokenPos(), ts.Diagnostics._0_tag_already_specified, tagName.escapedText); } const typeExpression = tryParseTypeExpression(); return finishNode(factory.createJSDocReturnTag(tagName, typeExpression, parseTrailingTagComments(start, getNodePos(), indent, indentText)), start); } - function parseTypeTag(start: number, tagName: Identifier, indent?: number, indentText?: string): JSDocTypeTag { - if (some(tags, isJSDocTypeTag)) { - parseErrorAt(tagName.pos, scanner.getTokenPos(), Diagnostics._0_tag_already_specified, tagName.escapedText); + function parseTypeTag(start: number, tagName: ts.Identifier, indent?: number, indentText?: string): ts.JSDocTypeTag { + if (ts.some(tags, ts.isJSDocTypeTag)) { + parseErrorAt(tagName.pos, scanner.getTokenPos(), ts.Diagnostics._0_tag_already_specified, tagName.escapedText); } const typeExpression = parseJSDocTypeExpression(/*mayOmitBraces*/ true); @@ -8373,15 +8216,15 @@ namespace ts { return finishNode(factory.createJSDocTypeTag(tagName, typeExpression, comments), start); } - function parseSeeTag(start: number, tagName: Identifier, indent?: number, indentText?: string): JSDocSeeTag { - const isMarkdownOrJSDocLink = token() === SyntaxKind.OpenBracketToken - || lookAhead(() => nextTokenJSDoc() === SyntaxKind.AtToken && tokenIsIdentifierOrKeyword(nextTokenJSDoc()) && isJSDocLinkTag(scanner.getTokenValue())); + function parseSeeTag(start: number, tagName: ts.Identifier, indent?: number, indentText?: string): ts.JSDocSeeTag { + const isMarkdownOrJSDocLink = token() === ts.SyntaxKind.OpenBracketToken + || lookAhead(() => nextTokenJSDoc() === ts.SyntaxKind.AtToken && ts.tokenIsIdentifierOrKeyword(nextTokenJSDoc()) && isJSDocLinkTag(scanner.getTokenValue())); const nameExpression = isMarkdownOrJSDocLink ? undefined : parseJSDocNameReference(); const comments = indent !== undefined && indentText !== undefined ? parseTrailingTagComments(start, getNodePos(), indent, indentText) : undefined; return finishNode(factory.createJSDocSeeTag(tagName, nameExpression, comments), start); } - function parseAuthorTag(start: number, tagName: Identifier, indent: number, indentText: string): JSDocAuthorTag { + function parseAuthorTag(start: number, tagName: ts.Identifier, indent: number, indentText: string): ts.JSDocAuthorTag { const commentStart = getNodePos(); const textOnly = parseAuthorNameAndEmail(); let commentEnd = scanner.getStartPos(); @@ -8390,23 +8233,23 @@ namespace ts { commentEnd = scanner.getStartPos(); } const allParts = typeof comments !== "string" - ? createNodeArray(concatenate([finishNode(textOnly, commentStart, commentEnd)], comments) as JSDocComment[], commentStart) // cast away readonly + ? createNodeArray(ts.concatenate([finishNode(textOnly, commentStart, commentEnd)], comments) as ts.JSDocComment[], commentStart) // cast away readonly : textOnly.text + comments; return finishNode(factory.createJSDocAuthorTag(tagName, allParts), start); } - function parseAuthorNameAndEmail(): JSDocText { + function parseAuthorNameAndEmail(): ts.JSDocText { const comments: string[] = []; let inEmail = false; let token = scanner.getToken(); - while (token !== SyntaxKind.EndOfFileToken && token !== SyntaxKind.NewLineTrivia) { - if (token === SyntaxKind.LessThanToken) { + while (token !== ts.SyntaxKind.EndOfFileToken && token !== ts.SyntaxKind.NewLineTrivia) { + if (token === ts.SyntaxKind.LessThanToken) { inEmail = true; } - else if (token === SyntaxKind.AtToken && !inEmail) { + else if (token === ts.SyntaxKind.AtToken && !inEmail) { break; } - else if (token === SyntaxKind.GreaterThanToken && inEmail) { + else if (token === ts.SyntaxKind.GreaterThanToken && inEmail) { comments.push(scanner.getTokenText()); scanner.setTextPos(scanner.getTokenPos() + 1); break; @@ -8418,57 +8261,61 @@ namespace ts { return factory.createJSDocText(comments.join("")); } - function parseImplementsTag(start: number, tagName: Identifier, margin: number, indentText: string): JSDocImplementsTag { + function parseImplementsTag(start: number, tagName: ts.Identifier, margin: number, indentText: string): ts.JSDocImplementsTag { const className = parseExpressionWithTypeArgumentsForAugments(); return finishNode(factory.createJSDocImplementsTag(tagName, className, parseTrailingTagComments(start, getNodePos(), margin, indentText)), start); } - function parseAugmentsTag(start: number, tagName: Identifier, margin: number, indentText: string): JSDocAugmentsTag { + function parseAugmentsTag(start: number, tagName: ts.Identifier, margin: number, indentText: string): ts.JSDocAugmentsTag { const className = parseExpressionWithTypeArgumentsForAugments(); return finishNode(factory.createJSDocAugmentsTag(tagName, className, parseTrailingTagComments(start, getNodePos(), margin, indentText)), start); } - function parseExpressionWithTypeArgumentsForAugments(): ExpressionWithTypeArguments & { expression: Identifier | PropertyAccessEntityNameExpression } { - const usedBrace = parseOptional(SyntaxKind.OpenBraceToken); + function parseExpressionWithTypeArgumentsForAugments(): ts.ExpressionWithTypeArguments & { + expression: ts.Identifier | ts.PropertyAccessEntityNameExpression; + } { + const usedBrace = parseOptional(ts.SyntaxKind.OpenBraceToken); const pos = getNodePos(); const expression = parsePropertyAccessEntityNameExpression(); const typeArguments = tryParseTypeArguments(); - const node = factory.createExpressionWithTypeArguments(expression, typeArguments) as ExpressionWithTypeArguments & { expression: Identifier | PropertyAccessEntityNameExpression }; + const node = factory.createExpressionWithTypeArguments(expression, typeArguments) as ts.ExpressionWithTypeArguments & { + expression: ts.Identifier | ts.PropertyAccessEntityNameExpression; + }; const res = finishNode(node, pos); if (usedBrace) { - parseExpected(SyntaxKind.CloseBraceToken); + parseExpected(ts.SyntaxKind.CloseBraceToken); } return res; } function parsePropertyAccessEntityNameExpression() { const pos = getNodePos(); - let node: Identifier | PropertyAccessEntityNameExpression = parseJSDocIdentifierName(); - while (parseOptional(SyntaxKind.DotToken)) { + let node: ts.Identifier | ts.PropertyAccessEntityNameExpression = parseJSDocIdentifierName(); + while (parseOptional(ts.SyntaxKind.DotToken)) { const name = parseJSDocIdentifierName(); - node = finishNode(factory.createPropertyAccessExpression(node, name), pos) as PropertyAccessEntityNameExpression; + node = finishNode(factory.createPropertyAccessExpression(node, name), pos) as ts.PropertyAccessEntityNameExpression; } return node; } - function parseSimpleTag(start: number, createTag: (tagName: Identifier | undefined, comment?: string | NodeArray) => JSDocTag, tagName: Identifier, margin: number, indentText: string): JSDocTag { + function parseSimpleTag(start: number, createTag: (tagName: ts.Identifier | undefined, comment?: string | ts.NodeArray) => ts.JSDocTag, tagName: ts.Identifier, margin: number, indentText: string): ts.JSDocTag { return finishNode(createTag(tagName, parseTrailingTagComments(start, getNodePos(), margin, indentText)), start); } - function parseThisTag(start: number, tagName: Identifier, margin: number, indentText: string): JSDocThisTag { + function parseThisTag(start: number, tagName: ts.Identifier, margin: number, indentText: string): ts.JSDocThisTag { const typeExpression = parseJSDocTypeExpression(/*mayOmitBraces*/ true); skipWhitespace(); return finishNode(factory.createJSDocThisTag(tagName, typeExpression, parseTrailingTagComments(start, getNodePos(), margin, indentText)), start); } - function parseEnumTag(start: number, tagName: Identifier, margin: number, indentText: string): JSDocEnumTag { + function parseEnumTag(start: number, tagName: ts.Identifier, margin: number, indentText: string): ts.JSDocEnumTag { const typeExpression = parseJSDocTypeExpression(/*mayOmitBraces*/ true); skipWhitespace(); return finishNode(factory.createJSDocEnumTag(tagName, typeExpression, parseTrailingTagComments(start, getNodePos(), margin, indentText)), start); } - function parseTypedefTag(start: number, tagName: Identifier, indent: number, indentText: string): JSDocTypedefTag { - let typeExpression: JSDocTypeExpression | JSDocTypeLiteral | undefined = tryParseTypeExpression(); + function parseTypedefTag(start: number, tagName: ts.Identifier, indent: number, indentText: string): ts.JSDocTypedefTag { + let typeExpression: ts.JSDocTypeExpression | ts.JSDocTypeLiteral | undefined = tryParseTypeExpression(); skipWhitespaceOrAsterisk(); const fullName = parseJSDocTypeNameWithNamespace(); @@ -8477,17 +8324,17 @@ namespace ts { let end: number | undefined; if (!typeExpression || isObjectOrObjectArrayTypeReference(typeExpression.type)) { - let child: JSDocTypeTag | JSDocPropertyTag | false; - let childTypeTag: JSDocTypeTag | undefined; - let jsDocPropertyTags: JSDocPropertyTag[] | undefined; + let child: ts.JSDocTypeTag | ts.JSDocPropertyTag | false; + let childTypeTag: ts.JSDocTypeTag | undefined; + let jsDocPropertyTags: ts.JSDocPropertyTag[] | undefined; let hasChildren = false; while (child = tryParse(() => parseChildPropertyTag(indent))) { hasChildren = true; - if (child.kind === SyntaxKind.JSDocTypeTag) { + if (child.kind === ts.SyntaxKind.JSDocTypeTag) { if (childTypeTag) { - const lastError = parseErrorAtCurrentToken(Diagnostics.A_JSDoc_typedef_comment_may_not_contain_multiple_type_tags); + const lastError = parseErrorAtCurrentToken(ts.Diagnostics.A_JSDoc_typedef_comment_may_not_contain_multiple_type_tags); if (lastError) { - addRelatedInfo(lastError, createDetachedDiagnostic(fileName, 0, 0, Diagnostics.The_tag_was_first_specified_here)); + ts.addRelatedInfo(lastError, ts.createDetachedDiagnostic(fileName, 0, 0, ts.Diagnostics.The_tag_was_first_specified_here)); } break; } @@ -8496,11 +8343,11 @@ namespace ts { } } else { - jsDocPropertyTags = append(jsDocPropertyTags, child); + jsDocPropertyTags = ts.append(jsDocPropertyTags, child); } } if (hasChildren) { - const isArrayType = typeExpression && typeExpression.type.kind === SyntaxKind.ArrayType; + const isArrayType = typeExpression && typeExpression.type.kind === ts.SyntaxKind.ArrayType; const jsdocTypeLiteral = factory.createJSDocTypeLiteral(jsDocPropertyTags, isArrayType); typeExpression = childTypeTag && childTypeTag.typeExpression && !isObjectOrObjectArrayTypeReference(childTypeTag.typeExpression.type) ? childTypeTag.typeExpression : @@ -8524,19 +8371,15 @@ namespace ts { function parseJSDocTypeNameWithNamespace(nested?: boolean) { const pos = scanner.getTokenPos(); - if (!tokenIsIdentifierOrKeyword(token())) { + if (!ts.tokenIsIdentifierOrKeyword(token())) { return undefined; } const typeNameOrNamespaceName = parseJSDocIdentifierName(); - if (parseOptional(SyntaxKind.DotToken)) { + if (parseOptional(ts.SyntaxKind.DotToken)) { const body = parseJSDocTypeNameWithNamespace(/*nested*/ true); const jsDocNamespaceNode = factory.createModuleDeclaration( /*decorators*/ undefined, - /*modifiers*/ undefined, - typeNameOrNamespaceName, - body, - nested ? NodeFlags.NestedNamespace : undefined - ) as JSDocNamespaceDeclaration; + /*modifiers*/ undefined, typeNameOrNamespaceName, body, nested ? ts.NodeFlags.NestedNamespace : undefined) as ts.JSDocNamespaceDeclaration; return finishNode(jsDocNamespaceNode, pos); } @@ -8549,24 +8392,24 @@ namespace ts { function parseCallbackTagParameters(indent: number) { const pos = getNodePos(); - let child: JSDocParameterTag | false; + let child: ts.JSDocParameterTag | false; let parameters; - while (child = tryParse(() => parseChildParameterOrPropertyTag(PropertyLikeParse.CallbackParameter, indent) as JSDocParameterTag)) { - parameters = append(parameters, child); + while (child = tryParse(() => parseChildParameterOrPropertyTag(PropertyLikeParse.CallbackParameter, indent) as ts.JSDocParameterTag)) { + parameters = ts.append(parameters, child); } return createNodeArray(parameters || [], pos); } - function parseCallbackTag(start: number, tagName: Identifier, indent: number, indentText: string): JSDocCallbackTag { + function parseCallbackTag(start: number, tagName: ts.Identifier, indent: number, indentText: string): ts.JSDocCallbackTag { const fullName = parseJSDocTypeNameWithNamespace(); skipWhitespace(); let comment = parseTagComments(indent); const parameters = parseCallbackTagParameters(indent); const returnTag = tryParse(() => { - if (parseOptionalJsdoc(SyntaxKind.AtToken)) { + if (parseOptionalJsdoc(ts.SyntaxKind.AtToken)) { const tag = parseTag(indent); - if (tag && tag.kind === SyntaxKind.JSDocReturnTag) { - return tag as JSDocReturnTag; + if (tag && tag.kind === ts.SyntaxKind.JSDocReturnTag) { + return tag as ts.JSDocReturnTag; } } }); @@ -8578,7 +8421,7 @@ namespace ts { return finishNode(factory.createJSDocCallbackTag(tagName, typeExpression, fullName, comment), start, end); } - function escapedTextsEqual(a: EntityName, b: EntityName): boolean { + function escapedTextsEqual(a: ts.EntityName, b: ts.EntityName): boolean { while (!ts.isIdentifier(a) || !ts.isIdentifier(b)) { if (!ts.isIdentifier(a) && !ts.isIdentifier(b) && a.right.escapedText === b.right.escapedText) { a = a.left; @@ -8592,18 +8435,18 @@ namespace ts { } function parseChildPropertyTag(indent: number) { - return parseChildParameterOrPropertyTag(PropertyLikeParse.Property, indent) as JSDocTypeTag | JSDocPropertyTag | false; + return parseChildParameterOrPropertyTag(PropertyLikeParse.Property, indent) as ts.JSDocTypeTag | ts.JSDocPropertyTag | false; } - function parseChildParameterOrPropertyTag(target: PropertyLikeParse, indent: number, name?: EntityName): JSDocTypeTag | JSDocPropertyTag | JSDocParameterTag | false { + function parseChildParameterOrPropertyTag(target: PropertyLikeParse, indent: number, name?: ts.EntityName): ts.JSDocTypeTag | ts.JSDocPropertyTag | ts.JSDocParameterTag | false { let canParseTag = true; let seenAsterisk = false; while (true) { switch (nextTokenJSDoc()) { - case SyntaxKind.AtToken: + case ts.SyntaxKind.AtToken: if (canParseTag) { const child = tryParseChildTag(target, indent); - if (child && (child.kind === SyntaxKind.JSDocParameterTag || child.kind === SyntaxKind.JSDocPropertyTag) && + if (child && (child.kind === ts.SyntaxKind.JSDocParameterTag || child.kind === ts.SyntaxKind.JSDocPropertyTag) && target !== PropertyLikeParse.CallbackParameter && name && (ts.isIdentifier(child.name) || !escapedTextsEqual(name, child.name.left))) { return false; @@ -8612,27 +8455,27 @@ namespace ts { } seenAsterisk = false; break; - case SyntaxKind.NewLineTrivia: + case ts.SyntaxKind.NewLineTrivia: canParseTag = true; seenAsterisk = false; break; - case SyntaxKind.AsteriskToken: + case ts.SyntaxKind.AsteriskToken: if (seenAsterisk) { canParseTag = false; } seenAsterisk = true; break; - case SyntaxKind.Identifier: + case ts.SyntaxKind.Identifier: canParseTag = false; break; - case SyntaxKind.EndOfFileToken: + case ts.SyntaxKind.EndOfFileToken: return false; } } } - function tryParseChildTag(target: PropertyLikeParse, indent: number): JSDocTypeTag | JSDocPropertyTag | JSDocParameterTag | false { - Debug.assert(token() === SyntaxKind.AtToken); + function tryParseChildTag(target: PropertyLikeParse, indent: number): ts.JSDocTypeTag | ts.JSDocPropertyTag | ts.JSDocParameterTag | false { + ts.Debug.assert(token() === ts.SyntaxKind.AtToken); const start = scanner.getStartPos(); nextTokenJSDoc(); @@ -8662,21 +8505,20 @@ namespace ts { function parseTemplateTagTypeParameter() { const typeParameterPos = getNodePos(); - const isBracketed = parseOptionalJsdoc(SyntaxKind.OpenBracketToken); + const isBracketed = parseOptionalJsdoc(ts.SyntaxKind.OpenBracketToken); if (isBracketed) { skipWhitespace(); } - const name = parseJSDocIdentifierName(Diagnostics.Unexpected_token_A_type_parameter_name_was_expected_without_curly_braces); - - let defaultType: TypeNode | undefined; + const name = parseJSDocIdentifierName(ts.Diagnostics.Unexpected_token_A_type_parameter_name_was_expected_without_curly_braces); + let defaultType: ts.TypeNode | undefined; if (isBracketed) { skipWhitespace(); - parseExpected(SyntaxKind.EqualsToken); - defaultType = doInsideOfContext(NodeFlags.JSDoc, parseJSDocType); - parseExpected(SyntaxKind.CloseBracketToken); + parseExpected(ts.SyntaxKind.EqualsToken); + defaultType = doInsideOfContext(ts.NodeFlags.JSDoc, parseJSDocType); + parseExpected(ts.SyntaxKind.CloseBracketToken); } - if (nodeIsMissing(name)) { + if (ts.nodeIsMissing(name)) { return undefined; } return finishNode(factory.createTypeParameterDeclaration(/*modifiers*/ undefined, name, /*constraint*/ undefined, defaultType), typeParameterPos); @@ -8692,11 +8534,11 @@ namespace ts { typeParameters.push(node); } skipWhitespaceOrAsterisk(); - } while (parseOptionalJsdoc(SyntaxKind.CommaToken)); + } while (parseOptionalJsdoc(ts.SyntaxKind.CommaToken)); return createNodeArray(typeParameters, pos); } - function parseTemplateTag(start: number, tagName: Identifier, indent: number, indentText: string): JSDocTemplateTag { + function parseTemplateTag(start: number, tagName: ts.Identifier, indent: number, indentText: string): ts.JSDocTemplateTag { // The template tag looks like one of the following: // @template T,U,V // @template {Constraint} T @@ -8708,12 +8550,12 @@ namespace ts { // TODO: Determine whether we should enforce this in the checker. // TODO: Consider moving the `constraint` to the first type parameter as we could then remove `getEffectiveConstraintOfTypeParameter`. // TODO: Consider only parsing a single type parameter if there is a constraint. - const constraint = token() === SyntaxKind.OpenBraceToken ? parseJSDocTypeExpression() : undefined; + const constraint = token() === ts.SyntaxKind.OpenBraceToken ? parseJSDocTypeExpression() : undefined; const typeParameters = parseTemplateTagTypeParameters(); return finishNode(factory.createJSDocTemplateTag(tagName, constraint, typeParameters, parseTrailingTagComments(start, getNodePos(), indent, indentText)), start); } - function parseOptionalJsdoc(t: JSDocSyntaxKind): boolean { + function parseOptionalJsdoc(t: ts.JSDocSyntaxKind): boolean { if (token() === t) { nextTokenJSDoc(); return true; @@ -8721,27 +8563,27 @@ namespace ts { return false; } - function parseJSDocEntityName(): EntityName { - let entity: EntityName = parseJSDocIdentifierName(); - if (parseOptional(SyntaxKind.OpenBracketToken)) { - parseExpected(SyntaxKind.CloseBracketToken); + function parseJSDocEntityName(): ts.EntityName { + let entity: ts.EntityName = parseJSDocIdentifierName(); + if (parseOptional(ts.SyntaxKind.OpenBracketToken)) { + parseExpected(ts.SyntaxKind.CloseBracketToken); // Note that y[] is accepted as an entity name, but the postfix brackets are not saved for checking. // Technically usejsdoc.org requires them for specifying a property of a type equivalent to Array<{ x: ...}> // but it's not worth it to enforce that restriction. } - while (parseOptional(SyntaxKind.DotToken)) { + while (parseOptional(ts.SyntaxKind.DotToken)) { const name = parseJSDocIdentifierName(); - if (parseOptional(SyntaxKind.OpenBracketToken)) { - parseExpected(SyntaxKind.CloseBracketToken); + if (parseOptional(ts.SyntaxKind.OpenBracketToken)) { + parseExpected(ts.SyntaxKind.CloseBracketToken); } entity = createQualifiedName(entity, name); } return entity; } - function parseJSDocIdentifierName(message?: DiagnosticMessage): Identifier { - if (!tokenIsIdentifierOrKeyword(token())) { - return createMissingNode(SyntaxKind.Identifier, /*reportAtCurrentPosition*/ !message, message || Diagnostics.Identifier_expected); + function parseJSDocIdentifierName(message?: ts.DiagnosticMessage): ts.Identifier { + if (!ts.tokenIsIdentifierOrKeyword(token())) { + return createMissingNode(ts.SyntaxKind.Identifier, /*reportAtCurrentPosition*/ !message, message || ts.Diagnostics.Identifier_expected); } identifierCount++; @@ -8758,11 +8600,11 @@ namespace ts { } namespace IncrementalParser { - export function updateSourceFile(sourceFile: SourceFile, newText: string, textChangeRange: TextChangeRange, aggressiveChecks: boolean): SourceFile { - aggressiveChecks = aggressiveChecks || Debug.shouldAssert(AssertionLevel.Aggressive); + export function updateSourceFile(sourceFile: ts.SourceFile, newText: string, textChangeRange: ts.TextChangeRange, aggressiveChecks: boolean): ts.SourceFile { + aggressiveChecks = aggressiveChecks || ts.Debug.shouldAssert(ts.AssertionLevel.Aggressive); checkChangeRange(sourceFile, newText, textChangeRange, aggressiveChecks); - if (textChangeRangeIsUnchanged(textChangeRange)) { + if (ts.textChangeRangeIsUnchanged(textChangeRange)) { // if the text didn't change, then we can just return our current source file as-is. return sourceFile; } @@ -8779,8 +8621,8 @@ namespace ts { // This is because we do incremental parsing in-place. i.e. we take nodes from the old // tree and give them new positions and parents. From that point on, trusting the old // tree at all is not possible as far too much of it may violate invariants. - const incrementalSourceFile = sourceFile as Node as IncrementalNode; - Debug.assert(!incrementalSourceFile.hasBeenIncrementallyParsed); + const incrementalSourceFile = sourceFile as ts.Node as IncrementalNode; + ts.Debug.assert(!incrementalSourceFile.hasBeenIncrementallyParsed); incrementalSourceFile.hasBeenIncrementallyParsed = true; Parser.fixupParentReferences(incrementalSourceFile); const oldText = sourceFile.text; @@ -8793,14 +8635,14 @@ namespace ts { // Ensure that extending the affected range only moved the start of the change range // earlier in the file. - Debug.assert(changeRange.span.start <= textChangeRange.span.start); - Debug.assert(textSpanEnd(changeRange.span) === textSpanEnd(textChangeRange.span)); - Debug.assert(textSpanEnd(textChangeRangeNewSpan(changeRange)) === textSpanEnd(textChangeRangeNewSpan(textChangeRange))); + ts.Debug.assert(changeRange.span.start <= textChangeRange.span.start); + ts.Debug.assert(ts.textSpanEnd(changeRange.span) === ts.textSpanEnd(textChangeRange.span)); + ts.Debug.assert(ts.textSpanEnd(ts.textChangeRangeNewSpan(changeRange)) === ts.textSpanEnd(ts.textChangeRangeNewSpan(textChangeRange))); // The is the amount the nodes after the edit range need to be adjusted. It can be // positive (if the edit added characters), negative (if the edit deleted characters) // or zero (if this was a pure overwrite with nothing added/removed). - const delta = textChangeRangeNewSpan(changeRange).length - changeRange.span.length; + const delta = ts.textChangeRangeNewSpan(changeRange).length - changeRange.span.length; // If we added or removed characters during the edit, then we need to go and adjust all // the nodes after the edit. Those nodes may move forward (if we inserted chars) or they @@ -8821,8 +8663,7 @@ namespace ts { // // Also, mark any syntax elements that intersect the changed span. We know, up front, // that we cannot reuse these elements. - updateTokenPositionsAndMarkElements(incrementalSourceFile, - changeRange.span.start, textSpanEnd(changeRange.span), textSpanEnd(textChangeRangeNewSpan(changeRange)), delta, oldText, newText, aggressiveChecks); + updateTokenPositionsAndMarkElements(incrementalSourceFile, changeRange.span.start, ts.textSpanEnd(changeRange.span), ts.textSpanEnd(ts.textChangeRangeNewSpan(changeRange)), delta, oldText, newText, aggressiveChecks); // Now that we've set up our internal incremental state just proceed and parse the // source file in the normal fashion. When possible the parser will retrieve and @@ -8835,50 +8676,33 @@ namespace ts { // will immediately bail out of walking any subtrees when we can see that their parents // are already correct. const result = Parser.parseSourceFile(sourceFile.fileName, newText, sourceFile.languageVersion, syntaxCursor, /*setParentNodes*/ true, sourceFile.scriptKind, sourceFile.setExternalModuleIndicator); - result.commentDirectives = getNewCommentDirectives( - sourceFile.commentDirectives, - result.commentDirectives, - changeRange.span.start, - textSpanEnd(changeRange.span), - delta, - oldText, - newText, - aggressiveChecks - ); + result.commentDirectives = getNewCommentDirectives(sourceFile.commentDirectives, result.commentDirectives, changeRange.span.start, ts.textSpanEnd(changeRange.span), delta, oldText, newText, aggressiveChecks); result.impliedNodeFormat = sourceFile.impliedNodeFormat; return result; } - function getNewCommentDirectives( - oldDirectives: CommentDirective[] | undefined, - newDirectives: CommentDirective[] | undefined, - changeStart: number, - changeRangeOldEnd: number, - delta: number, - oldText: string, - newText: string, - aggressiveChecks: boolean - ): CommentDirective[] | undefined { - if (!oldDirectives) return newDirectives; - let commentDirectives: CommentDirective[] | undefined; + function getNewCommentDirectives(oldDirectives: ts.CommentDirective[] | undefined, newDirectives: ts.CommentDirective[] | undefined, changeStart: number, changeRangeOldEnd: number, delta: number, oldText: string, newText: string, aggressiveChecks: boolean): ts.CommentDirective[] | undefined { + if (!oldDirectives) + return newDirectives; + let commentDirectives: ts.CommentDirective[] | undefined; let addedNewlyScannedDirectives = false; for (const directive of oldDirectives) { const { range, type } = directive; // Range before the change if (range.end < changeStart) { - commentDirectives = append(commentDirectives, directive); + commentDirectives = ts.append(commentDirectives, directive); } else if (range.pos > changeRangeOldEnd) { addNewlyScannedDirectives(); // Node is entirely past the change range. We need to move both its pos and // end, forward or backward appropriately. - const updatedDirective: CommentDirective = { + const updatedDirective: ts.CommentDirective = { range: { pos: range.pos + delta, end: range.end + delta }, type }; - commentDirectives = append(commentDirectives, updatedDirective); + commentDirectives = ts.append(commentDirectives, updatedDirective); if (aggressiveChecks) { - Debug.assert(oldText.substring(range.pos, range.end) === newText.substring(updatedDirective.range.pos, updatedDirective.range.end)); + ts.Debug.assert(oldText.substring(range.pos, range.end) === newText.substring(updatedDirective.range.pos, updatedDirective.range.end)); } } // Ignore ranges that fall in change range @@ -8887,7 +8711,8 @@ namespace ts { return commentDirectives; function addNewlyScannedDirectives() { - if (addedNewlyScannedDirectives) return; + if (addedNewlyScannedDirectives) + return; addedNewlyScannedDirectives = true; if (!commentDirectives) { commentDirectives = newDirectives; @@ -8919,16 +8744,16 @@ namespace ts { node._children = undefined; } - setTextRangePosEnd(node, node.pos + delta, node.end + delta); + ts.setTextRangePosEnd(node, node.pos + delta, node.end + delta); if (aggressiveChecks && shouldCheckNode(node)) { - Debug.assert(text === newText.substring(node.pos, node.end)); + ts.Debug.assert(text === newText.substring(node.pos, node.end)); } forEachChild(node, visitNode, visitArray); - if (hasJSDocNodes(node)) { + if (ts.hasJSDocNodes(node)) { for (const jsDocComment of node.jsDoc!) { - visitNode(jsDocComment as Node as IncrementalNode); + visitNode(jsDocComment as ts.Node as IncrementalNode); } } checkNodePositions(node, aggressiveChecks); @@ -8936,7 +8761,7 @@ namespace ts { function visitArray(array: IncrementalNodeArray) { array._children = undefined; - setTextRangePosEnd(array, array.pos + delta, array.end + delta); + ts.setTextRangePosEnd(array, array.pos + delta, array.end + delta); for (const node of array) { visitNode(node); @@ -8944,11 +8769,11 @@ namespace ts { } } - function shouldCheckNode(node: Node) { + function shouldCheckNode(node: ts.Node) { switch (node.kind) { - case SyntaxKind.StringLiteral: - case SyntaxKind.NumericLiteral: - case SyntaxKind.Identifier: + case ts.SyntaxKind.StringLiteral: + case ts.SyntaxKind.NumericLiteral: + case ts.SyntaxKind.Identifier: return true; } @@ -8956,9 +8781,9 @@ namespace ts { } function adjustIntersectingElement(element: IncrementalElement, changeStart: number, changeRangeOldEnd: number, changeRangeNewEnd: number, delta: number) { - Debug.assert(element.end >= changeStart, "Adjusting an element that was entirely before the change range"); - Debug.assert(element.pos <= changeRangeOldEnd, "Adjusting an element that was entirely after the change range"); - Debug.assert(element.pos <= element.end); + ts.Debug.assert(element.end >= changeStart, "Adjusting an element that was entirely before the change range"); + ts.Debug.assert(element.pos <= changeRangeOldEnd, "Adjusting an element that was entirely after the change range"); + ts.Debug.assert(element.pos <= element.end); // We have an element that intersects the change range in some way. It may have its // start, or its end (or both) in the changed range. We want to adjust any part @@ -9020,47 +8845,38 @@ namespace ts { // possible. Or Move backward to the new-end if it's in the 'Y' range. Math.min(element.end, changeRangeNewEnd); - Debug.assert(pos <= end); + ts.Debug.assert(pos <= end); if (element.parent) { - Debug.assertGreaterThanOrEqual(pos, element.parent.pos); - Debug.assertLessThanOrEqual(end, element.parent.end); + ts.Debug.assertGreaterThanOrEqual(pos, element.parent.pos); + ts.Debug.assertLessThanOrEqual(end, element.parent.end); } - setTextRangePosEnd(element, pos, end); + ts.setTextRangePosEnd(element, pos, end); } - function checkNodePositions(node: Node, aggressiveChecks: boolean) { + function checkNodePositions(node: ts.Node, aggressiveChecks: boolean) { if (aggressiveChecks) { let pos = node.pos; - const visitNode = (child: Node) => { - Debug.assert(child.pos >= pos); + const visitNode = (child: ts.Node) => { + ts.Debug.assert(child.pos >= pos); pos = child.end; }; - if (hasJSDocNodes(node)) { + if (ts.hasJSDocNodes(node)) { for (const jsDocComment of node.jsDoc!) { visitNode(jsDocComment); } } forEachChild(node, visitNode); - Debug.assert(pos <= node.end); + ts.Debug.assert(pos <= node.end); } } - - function updateTokenPositionsAndMarkElements( - sourceFile: IncrementalNode, - changeStart: number, - changeRangeOldEnd: number, - changeRangeNewEnd: number, - delta: number, - oldText: string, - newText: string, - aggressiveChecks: boolean): void { + function updateTokenPositionsAndMarkElements(sourceFile: IncrementalNode, changeStart: number, changeRangeOldEnd: number, changeRangeNewEnd: number, delta: number, oldText: string, newText: string, aggressiveChecks: boolean): void { visitNode(sourceFile); return; function visitNode(child: IncrementalNode) { - Debug.assert(child.pos <= child.end); + ts.Debug.assert(child.pos <= child.end); if (child.pos > changeRangeOldEnd) { // Node is entirely past the change range. We need to move both its pos and // end, forward or backward appropriately. @@ -9079,9 +8895,9 @@ namespace ts { // Adjust the pos or end (or both) of the intersecting element accordingly. adjustIntersectingElement(child, changeStart, changeRangeOldEnd, changeRangeNewEnd, delta); forEachChild(child, visitNode, visitArray); - if (hasJSDocNodes(child)) { + if (ts.hasJSDocNodes(child)) { for (const jsDocComment of child.jsDoc!) { - visitNode(jsDocComment as Node as IncrementalNode); + visitNode(jsDocComment as ts.Node as IncrementalNode); } } checkNodePositions(child, aggressiveChecks); @@ -9089,11 +8905,11 @@ namespace ts { } // Otherwise, the node is entirely before the change range. No need to do anything with it. - Debug.assert(fullEnd < changeStart); + ts.Debug.assert(fullEnd < changeStart); } function visitArray(array: IncrementalNodeArray) { - Debug.assert(array.pos <= array.end); + ts.Debug.assert(array.pos <= array.end); if (array.pos > changeRangeOldEnd) { // Array is entirely after the change range. We need to move it, and move any of // its children. @@ -9118,11 +8934,11 @@ namespace ts { } // Otherwise, the array is entirely before the change range. No need to do anything with it. - Debug.assert(fullEnd < changeStart); + ts.Debug.assert(fullEnd < changeStart); } } - function extendToAffectedRange(sourceFile: SourceFile, changeRange: TextChangeRange): TextChangeRange { + function extendToAffectedRange(sourceFile: ts.SourceFile, changeRange: ts.TextChangeRange): ts.TextChangeRange { // Consider the following code: // void foo() { /; } // @@ -9142,21 +8958,20 @@ namespace ts { // start of the tree. for (let i = 0; start > 0 && i <= maxLookahead; i++) { const nearestNode = findNearestNodeStartingBeforeOrAtPosition(sourceFile, start); - Debug.assert(nearestNode.pos <= start); + ts.Debug.assert(nearestNode.pos <= start); const position = nearestNode.pos; start = Math.max(0, position - 1); } - const finalSpan = createTextSpanFromBounds(start, textSpanEnd(changeRange.span)); + const finalSpan = ts.createTextSpanFromBounds(start, ts.textSpanEnd(changeRange.span)); const finalLength = changeRange.newLength + (changeRange.span.start - start); - return createTextChangeRange(finalSpan, finalLength); + return ts.createTextChangeRange(finalSpan, finalLength); } - - function findNearestNodeStartingBeforeOrAtPosition(sourceFile: SourceFile, position: number): Node { - let bestResult: Node = sourceFile; - let lastNodeEntirelyBeforePosition: Node | undefined; + function findNearestNodeStartingBeforeOrAtPosition(sourceFile: ts.SourceFile, position: number): ts.Node { + let bestResult: ts.Node = sourceFile; + let lastNodeEntirelyBeforePosition: ts.Node | undefined; forEachChild(sourceFile, visit); @@ -9169,9 +8984,9 @@ namespace ts { return bestResult; - function getLastDescendant(node: Node): Node { + function getLastDescendant(node: ts.Node): ts.Node { while (true) { - const lastChild = getLastChild(node); + const lastChild = ts.getLastChild(node); if (lastChild) { node = lastChild; } @@ -9181,8 +8996,8 @@ namespace ts { } } - function visit(child: Node) { - if (nodeIsMissing(child)) { + function visit(child: ts.Node) { + if (ts.nodeIsMissing(child)) { // Missing nodes are effectively invisible to us. We never even consider them // When trying to find the nearest node before us. return; @@ -9212,7 +9027,7 @@ namespace ts { return true; } else { - Debug.assert(child.end <= position); + ts.Debug.assert(child.end <= position); // The child ends entirely before this position. Say you have the following // (where $ is the position) // @@ -9230,7 +9045,7 @@ namespace ts { } } else { - Debug.assert(child.pos > position); + ts.Debug.assert(child.pos > position); // We're now at a node that is entirely past the position we're searching for. // This node (and all following nodes) could never contribute to the result, // so just skip them by returning 'true' here. @@ -9239,35 +9054,33 @@ namespace ts { } } - function checkChangeRange(sourceFile: SourceFile, newText: string, textChangeRange: TextChangeRange, aggressiveChecks: boolean) { + function checkChangeRange(sourceFile: ts.SourceFile, newText: string, textChangeRange: ts.TextChangeRange, aggressiveChecks: boolean) { const oldText = sourceFile.text; if (textChangeRange) { - Debug.assert((oldText.length - textChangeRange.span.length + textChangeRange.newLength) === newText.length); - - if (aggressiveChecks || Debug.shouldAssert(AssertionLevel.VeryAggressive)) { + ts.Debug.assert((oldText.length - textChangeRange.span.length + textChangeRange.newLength) === newText.length); + if (aggressiveChecks || ts.Debug.shouldAssert(ts.AssertionLevel.VeryAggressive)) { const oldTextPrefix = oldText.substr(0, textChangeRange.span.start); const newTextPrefix = newText.substr(0, textChangeRange.span.start); - Debug.assert(oldTextPrefix === newTextPrefix); - - const oldTextSuffix = oldText.substring(textSpanEnd(textChangeRange.span), oldText.length); - const newTextSuffix = newText.substring(textSpanEnd(textChangeRangeNewSpan(textChangeRange)), newText.length); - Debug.assert(oldTextSuffix === newTextSuffix); + ts.Debug.assert(oldTextPrefix === newTextPrefix); + const oldTextSuffix = oldText.substring(ts.textSpanEnd(textChangeRange.span), oldText.length); + const newTextSuffix = newText.substring(ts.textSpanEnd(ts.textChangeRangeNewSpan(textChangeRange)), newText.length); + ts.Debug.assert(oldTextSuffix === newTextSuffix); } } } - interface IncrementalElement extends ReadonlyTextRange { - readonly parent: Node; + interface IncrementalElement extends ts.ReadonlyTextRange { + readonly parent: ts.Node; intersectsChange: boolean; length?: number; - _children: Node[] | undefined; + _children: ts.Node[] | undefined; } - export interface IncrementalNode extends Node, IncrementalElement { + export interface IncrementalNode extends ts.Node, IncrementalElement { hasBeenIncrementallyParsed: boolean; } - interface IncrementalNodeArray extends NodeArray, IncrementalElement { + interface IncrementalNodeArray extends ts.NodeArray, IncrementalElement { length: number; } @@ -9278,11 +9091,11 @@ namespace ts { currentNode(position: number): IncrementalNode; } - export function createSyntaxCursor(sourceFile: SourceFile): SyntaxCursor { - let currentArray: NodeArray = sourceFile.statements; + export function createSyntaxCursor(sourceFile: ts.SourceFile): SyntaxCursor { + let currentArray: ts.NodeArray = sourceFile.statements; let currentArrayIndex = 0; - Debug.assert(currentArrayIndex < currentArray.length); + ts.Debug.assert(currentArrayIndex < currentArray.length); let current = currentArray[currentArrayIndex]; let lastQueriedPosition = InvalidPosition.Value; @@ -9316,7 +9129,7 @@ namespace ts { lastQueriedPosition = position; // Either we don'd have a node, or we have a node at the position being asked for. - Debug.assert(!current || current.pos === position); + ts.Debug.assert(!current || current.pos === position); return current as IncrementalNode; } }; @@ -9334,7 +9147,7 @@ namespace ts { forEachChild(sourceFile, visitNode, visitArray); return; - function visitNode(node: Node) { + function visitNode(node: ts.Node) { if (position >= node.pos && position < node.end) { // Position was within this node. Keep searching deeper to find the node. forEachChild(node, visitNode, visitArray); @@ -9347,7 +9160,7 @@ namespace ts { return false; } - function visitArray(array: NodeArray) { + function visitArray(array: ts.NodeArray) { if (position >= array.pos && position < array.end) { // position was in this array. Search through this array to see if we find a // viable element. @@ -9386,46 +9199,45 @@ namespace ts { /** @internal */ export function isDeclarationFileName(fileName: string): boolean { - return fileExtensionIsOneOf(fileName, supportedDeclarationExtensions); + return ts.fileExtensionIsOneOf(fileName, ts.supportedDeclarationExtensions); } /*@internal*/ export interface PragmaContext { - languageVersion: ScriptTarget; - pragmas?: PragmaMap; - checkJsDirective?: CheckJsDirective; - referencedFiles: FileReference[]; - typeReferenceDirectives: FileReference[]; - libReferenceDirectives: FileReference[]; - amdDependencies: AmdDependency[]; + languageVersion: ts.ScriptTarget; + pragmas?: ts.PragmaMap; + checkJsDirective?: ts.CheckJsDirective; + referencedFiles: ts.FileReference[]; + typeReferenceDirectives: ts.FileReference[]; + libReferenceDirectives: ts.FileReference[]; + amdDependencies: ts.AmdDependency[]; hasNoDefaultLib?: boolean; moduleName?: string; } - function parseResolutionMode(mode: string | undefined, pos: number, end: number, reportDiagnostic: PragmaDiagnosticReporter): ModuleKind.ESNext | ModuleKind.CommonJS | undefined { + function parseResolutionMode(mode: string | undefined, pos: number, end: number, reportDiagnostic: PragmaDiagnosticReporter): ts.ModuleKind.ESNext | ts.ModuleKind.CommonJS | undefined { if (!mode) { return undefined; } if (mode === "import") { - return ModuleKind.ESNext; + return ts.ModuleKind.ESNext; } if (mode === "require") { - return ModuleKind.CommonJS; + return ts.ModuleKind.CommonJS; } - reportDiagnostic(pos, end - pos, Diagnostics.resolution_mode_should_be_either_require_or_import); + reportDiagnostic(pos, end - pos, ts.Diagnostics.resolution_mode_should_be_either_require_or_import); return undefined; } /*@internal*/ export function processCommentPragmas(context: PragmaContext, sourceText: string): void { - const pragmas: PragmaPseudoMapEntry[] = []; - - for (const range of getLeadingCommentRanges(sourceText, 0) || emptyArray) { + const pragmas: ts.PragmaPseudoMapEntry[] = []; + for (const range of ts.getLeadingCommentRanges(sourceText, 0) || ts.emptyArray) { const comment = sourceText.substring(range.pos, range.end); extractPragmas(pragmas, range, comment); } - context.pragmas = new Map() as PragmaMap; + context.pragmas = new ts.Map() as ts.PragmaMap; for (const pragma of pragmas) { if (context.pragmas.has(pragma.name)) { const currentValue = context.pragmas.get(pragma.name); @@ -9442,7 +9254,7 @@ namespace ts { } /*@internal*/ - type PragmaDiagnosticReporter = (pos: number, length: number, message: DiagnosticMessage) => void; + type PragmaDiagnosticReporter = (pos: number, length: number, message: ts.DiagnosticMessage) => void; /*@internal*/ export function processPragmasIntoFields(context: PragmaContext, reportDiagnostic: PragmaDiagnosticReporter): void { @@ -9452,7 +9264,7 @@ namespace ts { context.libReferenceDirectives = []; context.amdDependencies = []; context.hasNoDefaultLib = false; - context.pragmas!.forEach((entryOrList, key) => { // TODO: GH#18217 + context.pragmas!.forEach((entryOrList, key) => { // TODO: The below should be strongly type-guarded and not need casts/explicit annotations, since entryOrList is related to // key and key is constrained to a union; but it's not (see GH#21483 for at least partial fix) :( switch (key) { @@ -9460,7 +9272,7 @@ namespace ts { const referencedFiles = context.referencedFiles; const typeReferenceDirectives = context.typeReferenceDirectives; const libReferenceDirectives = context.libReferenceDirectives; - forEach(toArray(entryOrList) as PragmaPseudoMap["reference"][], arg => { + ts.forEach(ts.toArray(entryOrList) as ts.PragmaPseudoMap["reference"][], arg => { const { types, lib, path, ["resolution-mode"]: res } = arg.arguments; if (arg.arguments["no-default-lib"]) { context.hasNoDefaultLib = true; @@ -9476,15 +9288,13 @@ namespace ts { referencedFiles.push({ pos: path.pos, end: path.end, fileName: path.value }); } else { - reportDiagnostic(arg.range.pos, arg.range.end - arg.range.pos, Diagnostics.Invalid_reference_directive_syntax); + reportDiagnostic(arg.range.pos, arg.range.end - arg.range.pos, ts.Diagnostics.Invalid_reference_directive_syntax); } }); break; } case "amd-dependency": { - context.amdDependencies = map( - toArray(entryOrList) as PragmaPseudoMap["amd-dependency"][], - x => ({ name: x.arguments.name, path: x.arguments.path })); + context.amdDependencies = ts.map(ts.toArray(entryOrList) as ts.PragmaPseudoMap["amd-dependency"][], x => ({ name: x.arguments.name, path: x.arguments.path })); break; } case "amd-module": { @@ -9492,20 +9302,20 @@ namespace ts { for (const entry of entryOrList) { if (context.moduleName) { // TODO: It's probably fine to issue this diagnostic on all instances of the pragma - reportDiagnostic(entry.range.pos, entry.range.end - entry.range.pos, Diagnostics.An_AMD_module_cannot_have_multiple_name_assignments); + reportDiagnostic(entry.range.pos, entry.range.end - entry.range.pos, ts.Diagnostics.An_AMD_module_cannot_have_multiple_name_assignments); } - context.moduleName = (entry as PragmaPseudoMap["amd-module"]).arguments.name; + context.moduleName = (entry as ts.PragmaPseudoMap["amd-module"]).arguments.name; } } else { - context.moduleName = (entryOrList as PragmaPseudoMap["amd-module"]).arguments.name; + context.moduleName = (entryOrList as ts.PragmaPseudoMap["amd-module"]).arguments.name; } break; } case "ts-nocheck": case "ts-check": { // _last_ of either nocheck or check in a file is the "winner" - forEach(toArray(entryOrList), entry => { + ts.forEach(ts.toArray(entryOrList), entry => { if (!context.checkJsDirective || entry.range.pos > context.checkJsDirective.pos) { context.checkJsDirective = { enabled: key === "ts-check", @@ -9521,12 +9331,12 @@ namespace ts { case "jsximportsource": case "jsxruntime": return; // Accessed directly - default: Debug.fail("Unhandled pragma kind"); // Can this be made into an assertNever in the future? + default: ts.Debug.fail("Unhandled pragma kind"); // Can this be made into an assertNever in the future? } }); } - const namedArgRegExCache = new Map(); + const namedArgRegExCache = new ts.Map(); function getNamedArgRegEx(name: string): RegExp { if (namedArgRegExCache.has(name)) { return namedArgRegExCache.get(name)!; @@ -9538,16 +9348,22 @@ namespace ts { const tripleSlashXMLCommentStartRegEx = /^\/\/\/\s*<(\S+)\s.*?\/>/im; const singleLinePragmaRegEx = /^\/\/\/?\s*@(\S+)\s*(.*)\s*$/im; - function extractPragmas(pragmas: PragmaPseudoMapEntry[], range: CommentRange, text: string) { - const tripleSlash = range.kind === SyntaxKind.SingleLineCommentTrivia && tripleSlashXMLCommentStartRegEx.exec(text); + function extractPragmas(pragmas: ts.PragmaPseudoMapEntry[], range: ts.CommentRange, text: string) { + const tripleSlash = range.kind === ts.SyntaxKind.SingleLineCommentTrivia && tripleSlashXMLCommentStartRegEx.exec(text); if (tripleSlash) { - const name = tripleSlash[1].toLowerCase() as keyof PragmaPseudoMap; // Technically unsafe cast, but we do it so the below check to make it safe typechecks - const pragma = commentPragmas[name] as PragmaDefinition; - if (!pragma || !(pragma.kind! & PragmaKindFlags.TripleSlashXML)) { + const name = tripleSlash[1].toLowerCase() as keyof ts.PragmaPseudoMap; // Technically unsafe cast, but we do it so the below check to make it safe typechecks + const pragma = ts.commentPragmas[name] as ts.PragmaDefinition; + if (!pragma || !(pragma.kind! & ts.PragmaKindFlags.TripleSlashXML)) { return; } if (pragma.args) { - const argument: {[index: string]: string | {value: string, pos: number, end: number}} = {}; + const argument: { + [index: string]: string | { + value: string; + pos: number; + end: number; + }; + } = {}; for (const arg of pragma.args) { const matcher = getNamedArgRegEx(arg.name); const matchResult = matcher.exec(text); @@ -9569,54 +9385,62 @@ namespace ts { } } } - pragmas.push({ name, args: { arguments: argument, range } } as PragmaPseudoMapEntry); + pragmas.push({ name, args: { arguments: argument, range } } as ts.PragmaPseudoMapEntry); } else { - pragmas.push({ name, args: { arguments: {}, range } } as PragmaPseudoMapEntry); + pragmas.push({ name, args: { arguments: {}, range } } as ts.PragmaPseudoMapEntry); } return; } - const singleLine = range.kind === SyntaxKind.SingleLineCommentTrivia && singleLinePragmaRegEx.exec(text); + const singleLine = range.kind === ts.SyntaxKind.SingleLineCommentTrivia && singleLinePragmaRegEx.exec(text); if (singleLine) { - return addPragmaForMatch(pragmas, range, PragmaKindFlags.SingleLine, singleLine); + return addPragmaForMatch(pragmas, range, ts.PragmaKindFlags.SingleLine, singleLine); } - if (range.kind === SyntaxKind.MultiLineCommentTrivia) { + if (range.kind === ts.SyntaxKind.MultiLineCommentTrivia) { const multiLinePragmaRegEx = /@(\S+)(\s+.*)?$/gim; // Defined inline since it uses the "g" flag, which keeps a persistent index (for iterating) let multiLineMatch: RegExpExecArray | null; while (multiLineMatch = multiLinePragmaRegEx.exec(text)) { - addPragmaForMatch(pragmas, range, PragmaKindFlags.MultiLine, multiLineMatch); + addPragmaForMatch(pragmas, range, ts.PragmaKindFlags.MultiLine, multiLineMatch); } } } - function addPragmaForMatch(pragmas: PragmaPseudoMapEntry[], range: CommentRange, kind: PragmaKindFlags, match: RegExpExecArray) { - if (!match) return; - const name = match[1].toLowerCase() as keyof PragmaPseudoMap; // Technically unsafe cast, but we do it so they below check to make it safe typechecks - const pragma = commentPragmas[name] as PragmaDefinition; + function addPragmaForMatch(pragmas: ts.PragmaPseudoMapEntry[], range: ts.CommentRange, kind: ts.PragmaKindFlags, match: RegExpExecArray) { + if (!match) + return; + const name = match[1].toLowerCase() as keyof ts.PragmaPseudoMap; // Technically unsafe cast, but we do it so they below check to make it safe typechecks + const pragma = ts.commentPragmas[name] as ts.PragmaDefinition; if (!pragma || !(pragma.kind! & kind)) { return; } const args = match[2]; // Split on spaces and match up positionally with definition const argument = getNamedPragmaArguments(pragma, args); - if (argument === "fail") return; // Missing required argument, fail to parse it - pragmas.push({ name, args: { arguments: argument, range } } as PragmaPseudoMapEntry); + if (argument === "fail") + return; // Missing required argument, fail to parse it + pragmas.push({ name, args: { arguments: argument, range } } as ts.PragmaPseudoMapEntry); return; } - function getNamedPragmaArguments(pragma: PragmaDefinition, text: string | undefined): {[index: string]: string} | "fail" { - if (!text) return {}; - if (!pragma.args) return {}; - const args = trimString(text).split(/\s+/); - const argMap: {[index: string]: string} = {}; + function getNamedPragmaArguments(pragma: ts.PragmaDefinition, text: string | undefined): { + [index: string]: string; + } | "fail" { + if (!text) + return {}; + if (!pragma.args) + return {}; + const args = ts.trimString(text).split(/\s+/); + const argMap: { + [index: string]: string; + } = {}; for (let i = 0; i < pragma.args.length; i++) { const argument = pragma.args[i]; if (!args[i] && !argument.optional) { return "fail"; } if (argument.captureSpan) { - return Debug.fail("Capture spans not yet implemented for non-xml pragmas"); + return ts.Debug.fail("Capture spans not yet implemented for non-xml pragmas"); } argMap[argument.name] = args[i]; } @@ -9624,23 +9448,23 @@ namespace ts { } /** @internal */ - export function tagNamesAreEquivalent(lhs: JsxTagNameExpression, rhs: JsxTagNameExpression): boolean { + export function tagNamesAreEquivalent(lhs: ts.JsxTagNameExpression, rhs: ts.JsxTagNameExpression): boolean { if (lhs.kind !== rhs.kind) { return false; } - if (lhs.kind === SyntaxKind.Identifier) { - return lhs.escapedText === (rhs as Identifier).escapedText; + if (lhs.kind === ts.SyntaxKind.Identifier) { + return lhs.escapedText === (rhs as ts.Identifier).escapedText; } - if (lhs.kind === SyntaxKind.ThisKeyword) { + if (lhs.kind === ts.SyntaxKind.ThisKeyword) { return true; } // If we are at this statement then we must have PropertyAccessExpression and because tag name in Jsx element can only // take forms of JsxTagNameExpression which includes an identifier, "this" expression, or another propertyAccessExpression // it is safe to case the expression property as such. See parseJsxElementName for how we parse tag name in Jsx element - return (lhs as PropertyAccessExpression).name.escapedText === (rhs as PropertyAccessExpression).name.escapedText && - tagNamesAreEquivalent((lhs as PropertyAccessExpression).expression as JsxTagNameExpression, (rhs as PropertyAccessExpression).expression as JsxTagNameExpression); + return (lhs as ts.PropertyAccessExpression).name.escapedText === (rhs as ts.PropertyAccessExpression).name.escapedText && + tagNamesAreEquivalent((lhs as ts.PropertyAccessExpression).expression as ts.JsxTagNameExpression, (rhs as ts.PropertyAccessExpression).expression as ts.JsxTagNameExpression); } } diff --git a/src/compiler/path.ts b/src/compiler/path.ts index ebc837feb33a3..ea63b81c93f41 100644 --- a/src/compiler/path.ts +++ b/src/compiler/path.ts @@ -16,7 +16,7 @@ namespace ts { * Determines whether a charCode corresponds to `/` or `\`. */ export function isAnyDirectorySeparator(charCode: number): boolean { - return charCode === CharacterCodes.slash || charCode === CharacterCodes.backslash; + return charCode === ts.CharacterCodes.slash || charCode === ts.CharacterCodes.backslash; } /** @@ -77,11 +77,11 @@ namespace ts { } export function hasExtension(fileName: string): boolean { - return stringContains(getBaseFileName(fileName), "."); + return ts.stringContains(getBaseFileName(fileName), "."); } export function fileExtensionIs(path: string, extension: string): boolean { - return path.length > extension.length && endsWith(path, extension); + return path.length > extension.length && ts.endsWith(path, extension); } export function fileExtensionIsOneOf(path: string, extensions: readonly string[]): boolean { @@ -104,16 +104,18 @@ namespace ts { //// Path Parsing function isVolumeCharacter(charCode: number) { - return (charCode >= CharacterCodes.a && charCode <= CharacterCodes.z) || - (charCode >= CharacterCodes.A && charCode <= CharacterCodes.Z); + return (charCode >= ts.CharacterCodes.a && charCode <= ts.CharacterCodes.z) || + (charCode >= ts.CharacterCodes.A && charCode <= ts.CharacterCodes.Z); } function getFileUrlVolumeSeparatorEnd(url: string, start: number) { const ch0 = url.charCodeAt(start); - if (ch0 === CharacterCodes.colon) return start + 1; - if (ch0 === CharacterCodes.percent && url.charCodeAt(start + 1) === CharacterCodes._3) { + if (ch0 === ts.CharacterCodes.colon) + return start + 1; + if (ch0 === ts.CharacterCodes.percent && url.charCodeAt(start + 1) === ts.CharacterCodes._3) { const ch2 = url.charCodeAt(start + 2); - if (ch2 === CharacterCodes.a || ch2 === CharacterCodes.A) return start + 3; + if (ch2 === ts.CharacterCodes.a || ch2 === ts.CharacterCodes.A) + return start + 3; } return -1; } @@ -123,24 +125,28 @@ namespace ts { * If the root is part of a URL, the twos-complement of the root length is returned. */ function getEncodedRootLength(path: string): number { - if (!path) return 0; + if (!path) + return 0; const ch0 = path.charCodeAt(0); // POSIX or UNC - if (ch0 === CharacterCodes.slash || ch0 === CharacterCodes.backslash) { - if (path.charCodeAt(1) !== ch0) return 1; // POSIX: "/" (or non-normalized "\") - - const p1 = path.indexOf(ch0 === CharacterCodes.slash ? directorySeparator : altDirectorySeparator, 2); - if (p1 < 0) return path.length; // UNC: "//server" or "\\server" + if (ch0 === ts.CharacterCodes.slash || ch0 === ts.CharacterCodes.backslash) { + if (path.charCodeAt(1) !== ch0) + return 1; // POSIX: "/" (or non-normalized "\") + const p1 = path.indexOf(ch0 === ts.CharacterCodes.slash ? directorySeparator : altDirectorySeparator, 2); + if (p1 < 0) + return path.length; // UNC: "//server" or "\\server" return p1 + 1; // UNC: "//server/" or "\\server\" } // DOS - if (isVolumeCharacter(ch0) && path.charCodeAt(1) === CharacterCodes.colon) { + if (isVolumeCharacter(ch0) && path.charCodeAt(1) === ts.CharacterCodes.colon) { const ch2 = path.charCodeAt(2); - if (ch2 === CharacterCodes.slash || ch2 === CharacterCodes.backslash) return 3; // DOS: "c:/" or "c:\" - if (path.length === 2) return 2; // DOS: "c:" (but not "c:d") + if (ch2 === ts.CharacterCodes.slash || ch2 === ts.CharacterCodes.backslash) + return 3; // DOS: "c:/" or "c:\" + if (path.length === 2) + return 2; // DOS: "c:" (but not "c:d") } // URL @@ -158,7 +164,7 @@ namespace ts { isVolumeCharacter(path.charCodeAt(authorityEnd + 1))) { const volumeSeparatorEnd = getFileUrlVolumeSeparatorEnd(path, authorityEnd + 2); if (volumeSeparatorEnd !== -1) { - if (path.charCodeAt(volumeSeparatorEnd) === CharacterCodes.slash) { + if (path.charCodeAt(volumeSeparatorEnd) === ts.CharacterCodes.slash) { // URL: "file:///c:/", "file://localhost/c:/", "file:///c%3a/", "file://localhost/c%3a/" return ~(volumeSeparatorEnd + 1); } @@ -229,7 +235,7 @@ namespace ts { * getDirectoryPath("http://typescriptlang.org") === "http://typescriptlang.org" * ``` */ - export function getDirectoryPath(path: Path): Path; + export function getDirectoryPath(path: ts.Path): ts.Path; /** * Returns the path except for its basename. Semantics align with NodeJS's `path.dirname` * except that we support URLs as well. @@ -265,7 +271,8 @@ namespace ts { // If the path provided is itself the root, then return it. const rootLength = getRootLength(path); - if (rootLength === path.length) return path; + if (rootLength === path.length) + return path; // return the leading portion of the path up to the last (non-terminal) directory separator // but not including any trailing directory separator. @@ -321,7 +328,8 @@ namespace ts { // if the path provided is itself the root, then it has not file name. const rootLength = getRootLength(path); - if (rootLength === path.length) return ""; + if (rootLength === path.length) + return ""; // return the trailing portion of the path starting after the last (non-terminal) directory // separator but not including any trailing directory separator. @@ -332,8 +340,9 @@ namespace ts { } function tryGetExtensionFromPath(path: string, extension: string, stringEqualityComparer: (a: string, b: string) => boolean) { - if (!startsWith(extension, ".")) extension = "." + extension; - if (path.length >= extension.length && path.charCodeAt(path.length - extension.length) === CharacterCodes.dot) { + if (!ts.startsWith(extension, ".")) + extension = "." + extension; + if (path.length >= extension.length && path.charCodeAt(path.length - extension.length) === ts.CharacterCodes.dot) { const pathExtension = path.slice(path.length - extension.length); if (stringEqualityComparer(pathExtension, extension)) { return pathExtension; @@ -347,7 +356,8 @@ namespace ts { } for (const extension of extensions) { const result = tryGetExtensionFromPath(path, extension, stringEqualityComparer); - if (result) return result; + if (result) + return result; } return ""; } @@ -377,7 +387,7 @@ namespace ts { // Retrieves any string from the final "." onwards from a base file name. // Unlike extensionFromPath, which throws an exception on unrecognized extensions. if (extensions) { - return getAnyExtensionFromPathWorker(removeTrailingDirectorySeparator(path), extensions, ignoreCase ? equateStringsCaseInsensitive : equateStringsCaseSensitive); + return getAnyExtensionFromPathWorker(removeTrailingDirectorySeparator(path), extensions, ignoreCase ? ts.equateStringsCaseInsensitive : ts.equateStringsCaseSensitive); } const baseFileName = getBaseFileName(path); const extensionIndex = baseFileName.lastIndexOf("."); @@ -390,7 +400,8 @@ namespace ts { function pathComponents(path: string, rootLength: number) { const root = path.substring(0, rootLength); const rest = path.substring(rootLength).split(directorySeparator); - if (rest.length && !lastOrUndefined(rest)) rest.pop(); + if (rest.length && !ts.lastOrUndefined(rest)) + rest.pop(); return [root, ...rest]; } @@ -440,7 +451,8 @@ namespace ts { * ``` */ export function getPathFromPathComponents(pathComponents: readonly string[]) { - if (pathComponents.length === 0) return ""; + if (pathComponents.length === 0) + return ""; const root = pathComponents[0] && ensureTrailingDirectorySeparator(pathComponents[0]); return root + pathComponents.slice(1).join(directorySeparator); @@ -465,12 +477,15 @@ namespace ts { * `"."` or `".."` entries in the path. */ export function reducePathComponents(components: readonly string[]) { - if (!some(components)) return []; + if (!ts.some(components)) + return []; const reduced = [components[0]]; for (let i = 1; i < components.length; i++) { const component = components[i]; - if (!component) continue; - if (component === ".") continue; + if (!component) + continue; + if (component === ".") + continue; if (component === "..") { if (reduced.length > 1) { if (reduced[reduced.length - 1] !== "..") { @@ -478,7 +493,8 @@ namespace ts { continue; } } - else if (reduced[0]) continue; + else if (reduced[0]) + continue; } reduced.push(component); } @@ -504,9 +520,11 @@ namespace ts { * ``` */ export function combinePaths(path: string, ...paths: (string | undefined)[]): string { - if (path) path = normalizeSlashes(path); + if (path) + path = normalizeSlashes(path); for (let relativePath of paths) { - if (!relativePath) continue; + if (!relativePath) + continue; relativePath = normalizeSlashes(relativePath); if (!path || getRootLength(relativePath) !== 0) { path = relativePath; @@ -529,7 +547,7 @@ namespace ts { * ``` */ export function resolvePath(path: string, ...paths: (string | undefined)[]): string { - return normalizePath(some(paths) ? combinePaths(path, ...paths) : normalizeSlashes(path)); + return normalizePath(ts.some(paths) ? combinePaths(path, ...paths) : normalizeSlashes(path)); } /** @@ -570,7 +588,8 @@ namespace ts { } function getPathWithoutRoot(pathComponents: readonly string[]) { - if (pathComponents.length === 0) return ""; + if (pathComponents.length === 0) + return ""; return pathComponents.slice(1).join(directorySeparator); } @@ -578,11 +597,11 @@ namespace ts { return getPathWithoutRoot(getNormalizedPathComponents(fileName, currentDirectory)); } - export function toPath(fileName: string, basePath: string | undefined, getCanonicalFileName: (path: string) => string): Path { + export function toPath(fileName: string, basePath: string | undefined, getCanonicalFileName: (path: string) => string): ts.Path { const nonCanonicalizedPath = isRootedDiskPath(fileName) ? normalizePath(fileName) : getNormalizedAbsolutePath(fileName, basePath); - return getCanonicalFileName(nonCanonicalizedPath) as Path; + return getCanonicalFileName(nonCanonicalizedPath) as ts.Path; } //// Path Mutation @@ -595,7 +614,7 @@ namespace ts { * removeTrailingDirectorySeparator("/path/to/file.ext/") === "/path/to/file.ext" * ``` */ - export function removeTrailingDirectorySeparator(path: Path): Path; + export function removeTrailingDirectorySeparator(path: ts.Path): ts.Path; export function removeTrailingDirectorySeparator(path: string): string; export function removeTrailingDirectorySeparator(path: string) { if (hasTrailingDirectorySeparator(path)) { @@ -613,7 +632,7 @@ namespace ts { * ensureTrailingDirectorySeparator("/path/to/file.ext/") === "/path/to/file.ext/" * ``` */ - export function ensureTrailingDirectorySeparator(path: Path): Path; + export function ensureTrailingDirectorySeparator(path: ts.Path): ts.Path; export function ensureTrailingDirectorySeparator(path: string): string; export function ensureTrailingDirectorySeparator(path: string) { if (!hasTrailingDirectorySeparator(path)) { @@ -658,7 +677,7 @@ namespace ts { export function changeAnyExtension(path: string, ext: string, extensions: string | readonly string[], ignoreCase: boolean): string; export function changeAnyExtension(path: string, ext: string, extensions?: string | readonly string[], ignoreCase?: boolean) { const pathext = extensions !== undefined && ignoreCase !== undefined ? getAnyExtensionFromPath(path, extensions, ignoreCase) : getAnyExtensionFromPath(path); - return pathext ? path.slice(0, path.length - pathext.length) + (startsWith(ext, ".") ? ext : "." + ext) : path; + return pathext ? path.slice(0, path.length - pathext.length) + (ts.startsWith(ext, ".") ? ext : "." + ext) : path; } //// Path Comparisons @@ -666,17 +685,20 @@ namespace ts { // check path for these segments: '', '.'. '..' const relativePathSegmentRegExp = /(?:\/\/)|(?:^|\/)\.\.?(?:$|\/)/; - function comparePathsWorker(a: string, b: string, componentComparer: (a: string, b: string) => Comparison) { - if (a === b) return Comparison.EqualTo; - if (a === undefined) return Comparison.LessThan; - if (b === undefined) return Comparison.GreaterThan; + function comparePathsWorker(a: string, b: string, componentComparer: (a: string, b: string) => ts.Comparison) { + if (a === b) + return ts.Comparison.EqualTo; + if (a === undefined) + return ts.Comparison.LessThan; + if (b === undefined) + return ts.Comparison.GreaterThan; // NOTE: Performance optimization - shortcut if the root segments differ as there would be no // need to perform path reduction. const aRoot = a.substring(0, getRootLength(a)); const bRoot = b.substring(0, getRootLength(b)); - const result = compareStringsCaseInsensitive(aRoot, bRoot); - if (result !== Comparison.EqualTo) { + const result = ts.compareStringsCaseInsensitive(aRoot, bRoot); + if (result !== ts.Comparison.EqualTo) { return result; } @@ -695,32 +717,32 @@ namespace ts { const sharedLength = Math.min(aComponents.length, bComponents.length); for (let i = 1; i < sharedLength; i++) { const result = componentComparer(aComponents[i], bComponents[i]); - if (result !== Comparison.EqualTo) { + if (result !== ts.Comparison.EqualTo) { return result; } } - return compareValues(aComponents.length, bComponents.length); + return ts.compareValues(aComponents.length, bComponents.length); } /** * Performs a case-sensitive comparison of two paths. Path roots are always compared case-insensitively. */ export function comparePathsCaseSensitive(a: string, b: string) { - return comparePathsWorker(a, b, compareStringsCaseSensitive); + return comparePathsWorker(a, b, ts.compareStringsCaseSensitive); } /** * Performs a case-insensitive comparison of two paths. */ export function comparePathsCaseInsensitive(a: string, b: string) { - return comparePathsWorker(a, b, compareStringsCaseInsensitive); + return comparePathsWorker(a, b, ts.compareStringsCaseInsensitive); } /** * Compare two paths using the provided case sensitivity. */ - export function comparePaths(a: string, b: string, ignoreCase?: boolean): Comparison; - export function comparePaths(a: string, b: string, currentDirectory: string, ignoreCase?: boolean): Comparison; + export function comparePaths(a: string, b: string, ignoreCase?: boolean): ts.Comparison; + export function comparePaths(a: string, b: string, currentDirectory: string, ignoreCase?: boolean): ts.Comparison; export function comparePaths(a: string, b: string, currentDirectory?: string | boolean, ignoreCase?: boolean) { if (typeof currentDirectory === "string") { a = combinePaths(currentDirectory, a); @@ -729,7 +751,7 @@ namespace ts { else if (typeof currentDirectory === "boolean") { ignoreCase = currentDirectory; } - return comparePathsWorker(a, b, getStringComparer(ignoreCase)); + return comparePathsWorker(a, b, ts.getStringComparer(ignoreCase)); } /** @@ -745,17 +767,19 @@ namespace ts { else if (typeof currentDirectory === "boolean") { ignoreCase = currentDirectory; } - if (parent === undefined || child === undefined) return false; - if (parent === child) return true; + if (parent === undefined || child === undefined) + return false; + if (parent === child) + return true; const parentComponents = reducePathComponents(getPathComponents(parent)); const childComponents = reducePathComponents(getPathComponents(child)); if (childComponents.length < parentComponents.length) { return false; } - const componentEqualityComparer = ignoreCase ? equateStringsCaseInsensitive : equateStringsCaseSensitive; + const componentEqualityComparer = ignoreCase ? ts.equateStringsCaseInsensitive : ts.equateStringsCaseSensitive; for (let i = 0; i < parentComponents.length; i++) { - const equalityComparer = i === 0 ? equateStringsCaseInsensitive : componentEqualityComparer; + const equalityComparer = i === 0 ? ts.equateStringsCaseInsensitive : componentEqualityComparer; if (!equalityComparer(parentComponents[i], childComponents[i])) { return false; } @@ -770,15 +794,15 @@ namespace ts { * * Use `containsPath` if file names are not already reduced and absolute. */ - export function startsWithDirectory(fileName: string, directoryName: string, getCanonicalFileName: GetCanonicalFileName): boolean { + export function startsWithDirectory(fileName: string, directoryName: string, getCanonicalFileName: ts.GetCanonicalFileName): boolean { const canonicalFileName = getCanonicalFileName(fileName); const canonicalDirectoryName = getCanonicalFileName(directoryName); - return startsWith(canonicalFileName, canonicalDirectoryName + "/") || startsWith(canonicalFileName, canonicalDirectoryName + "\\"); + return ts.startsWith(canonicalFileName, canonicalDirectoryName + "/") || ts.startsWith(canonicalFileName, canonicalDirectoryName + "\\"); } //// Relative Paths - export function getPathComponentsRelativeTo(from: string, to: string, stringEqualityComparer: (a: string, b: string) => boolean, getCanonicalFileName: GetCanonicalFileName) { + export function getPathComponentsRelativeTo(from: string, to: string, stringEqualityComparer: (a: string, b: string) => boolean, getCanonicalFileName: ts.GetCanonicalFileName) { const fromComponents = reducePathComponents(getPathComponents(from)); const toComponents = reducePathComponents(getPathComponents(to)); @@ -786,8 +810,9 @@ namespace ts { for (start = 0; start < fromComponents.length && start < toComponents.length; start++) { const fromComponent = getCanonicalFileName(fromComponents[start]); const toComponent = getCanonicalFileName(toComponents[start]); - const comparer = start === 0 ? equateStringsCaseInsensitive : stringEqualityComparer; - if (!comparer(fromComponent, toComponent)) break; + const comparer = start === 0 ? ts.equateStringsCaseInsensitive : stringEqualityComparer; + if (!comparer(fromComponent, toComponent)) + break; } if (start === 0) { @@ -809,12 +834,12 @@ namespace ts { /** * Gets a relative path that can be used to traverse between `from` and `to`. */ - export function getRelativePathFromDirectory(fromDirectory: string, to: string, getCanonicalFileName: GetCanonicalFileName): string; // eslint-disable-line @typescript-eslint/unified-signatures - export function getRelativePathFromDirectory(fromDirectory: string, to: string, getCanonicalFileNameOrIgnoreCase: GetCanonicalFileName | boolean) { - Debug.assert((getRootLength(fromDirectory) > 0) === (getRootLength(to) > 0), "Paths must either both be absolute or both be relative"); - const getCanonicalFileName = typeof getCanonicalFileNameOrIgnoreCase === "function" ? getCanonicalFileNameOrIgnoreCase : identity; + export function getRelativePathFromDirectory(fromDirectory: string, to: string, getCanonicalFileName: ts.GetCanonicalFileName): string; // eslint-disable-line @typescript-eslint/unified-signatures + export function getRelativePathFromDirectory(fromDirectory: string, to: string, getCanonicalFileNameOrIgnoreCase: ts.GetCanonicalFileName | boolean) { + ts.Debug.assert((getRootLength(fromDirectory) > 0) === (getRootLength(to) > 0), "Paths must either both be absolute or both be relative"); + const getCanonicalFileName = typeof getCanonicalFileNameOrIgnoreCase === "function" ? getCanonicalFileNameOrIgnoreCase : ts.identity; const ignoreCase = typeof getCanonicalFileNameOrIgnoreCase === "boolean" ? getCanonicalFileNameOrIgnoreCase : false; - const pathComponents = getPathComponentsRelativeTo(fromDirectory, to, ignoreCase ? equateStringsCaseInsensitive : equateStringsCaseSensitive, getCanonicalFileName); + const pathComponents = getPathComponentsRelativeTo(fromDirectory, to, ignoreCase ? ts.equateStringsCaseInsensitive : ts.equateStringsCaseSensitive, getCanonicalFileName); return getPathFromPathComponents(pathComponents); } @@ -824,17 +849,12 @@ namespace ts { : getRelativePathToDirectoryOrUrl(basePath, absoluteOrRelativePath, basePath, getCanonicalFileName, /*isAbsolutePathAnUrl*/ false); } - export function getRelativePathFromFile(from: string, to: string, getCanonicalFileName: GetCanonicalFileName) { + export function getRelativePathFromFile(from: string, to: string, getCanonicalFileName: ts.GetCanonicalFileName) { return ensurePathIsNonModuleName(getRelativePathFromDirectory(getDirectoryPath(from), to, getCanonicalFileName)); } - export function getRelativePathToDirectoryOrUrl(directoryPathOrUrl: string, relativeOrAbsolutePath: string, currentDirectory: string, getCanonicalFileName: GetCanonicalFileName, isAbsolutePathAnUrl: boolean) { - const pathComponents = getPathComponentsRelativeTo( - resolvePath(currentDirectory, directoryPathOrUrl), - resolvePath(currentDirectory, relativeOrAbsolutePath), - equateStringsCaseSensitive, - getCanonicalFileName - ); + export function getRelativePathToDirectoryOrUrl(directoryPathOrUrl: string, relativeOrAbsolutePath: string, currentDirectory: string, getCanonicalFileName: ts.GetCanonicalFileName, isAbsolutePathAnUrl: boolean) { + const pathComponents = getPathComponentsRelativeTo(resolvePath(currentDirectory, directoryPathOrUrl), resolvePath(currentDirectory, relativeOrAbsolutePath), ts.equateStringsCaseSensitive, getCanonicalFileName); const firstComponent = pathComponents[0]; if (isAbsolutePathAnUrl && isRootedDiskPath(firstComponent)) { @@ -850,9 +870,9 @@ namespace ts { /** * Calls `callback` on `directory` and every ancestor directory it has, returning the first defined result. */ - export function forEachAncestorDirectory(directory: Path, callback: (directory: Path) => T | undefined): T | undefined; + export function forEachAncestorDirectory(directory: ts.Path, callback: (directory: ts.Path) => T | undefined): T | undefined; export function forEachAncestorDirectory(directory: string, callback: (directory: string) => T | undefined): T | undefined; - export function forEachAncestorDirectory(directory: Path, callback: (directory: Path) => T | undefined): T | undefined { + export function forEachAncestorDirectory(directory: ts.Path, callback: (directory: ts.Path) => T | undefined): T | undefined { while (true) { const result = callback(directory); if (result !== undefined) { @@ -868,7 +888,7 @@ namespace ts { } } - export function isNodeModulesDirectory(dirPath: Path) { - return endsWith(dirPath, "/node_modules"); + export function isNodeModulesDirectory(dirPath: ts.Path) { + return ts.endsWith(dirPath, "/node_modules"); } } diff --git a/src/compiler/perfLogger.ts b/src/compiler/perfLogger.ts index f05e8a3bd1053..f6efab44b8b23 100644 --- a/src/compiler/perfLogger.ts +++ b/src/compiler/perfLogger.ts @@ -2,26 +2,26 @@ namespace ts { type PerfLogger = typeof import("@microsoft/typescript-etw"); const nullLogger: PerfLogger = { - logEvent: noop, - logErrEvent: noop, - logPerfEvent: noop, - logInfoEvent: noop, - logStartCommand: noop, - logStopCommand: noop, - logStartUpdateProgram: noop, - logStopUpdateProgram: noop, - logStartUpdateGraph: noop, - logStopUpdateGraph: noop, - logStartResolveModule: noop, - logStopResolveModule: noop, - logStartParseSourceFile: noop, - logStopParseSourceFile: noop, - logStartReadFile: noop, - logStopReadFile: noop, - logStartBindFile: noop, - logStopBindFile: noop, - logStartScheduledOperation: noop, - logStopScheduledOperation: noop, + logEvent: ts.noop, + logErrEvent: ts.noop, + logPerfEvent: ts.noop, + logInfoEvent: ts.noop, + logStartCommand: ts.noop, + logStopCommand: ts.noop, + logStartUpdateProgram: ts.noop, + logStopUpdateProgram: ts.noop, + logStartUpdateGraph: ts.noop, + logStopUpdateGraph: ts.noop, + logStartResolveModule: ts.noop, + logStopResolveModule: ts.noop, + logStartParseSourceFile: ts.noop, + logStopParseSourceFile: ts.noop, + logStartReadFile: ts.noop, + logStopReadFile: ts.noop, + logStartBindFile: ts.noop, + logStopBindFile: ts.noop, + logStartScheduledOperation: ts.noop, + logStopScheduledOperation: ts.noop, }; // Load optional module to enable Event Tracing for Windows diff --git a/src/compiler/performance.ts b/src/compiler/performance.ts index 3f6c23f2b0735..7a450f1899da1 100644 --- a/src/compiler/performance.ts +++ b/src/compiler/performance.ts @@ -1,10 +1,10 @@ /*@internal*/ /** Performance measurements for the compiler. */ namespace ts.performance { - let perfHooks: PerformanceHooks | undefined; + let perfHooks: ts.PerformanceHooks | undefined; // when set, indicates the implementation of `Performance` to use for user timing. // when unset, indicates user timing is unavailable or disabled. - let performanceImpl: Performance | undefined; + let performanceImpl: ts.Performance | undefined; export interface Timer { enter(): void; @@ -34,18 +34,18 @@ namespace ts.performance { measure(measureName, startMarkName, endMarkName); } else if (enterCount < 0) { - Debug.fail("enter/exit count does not match."); + ts.Debug.fail("enter/exit count does not match."); } } } - export const nullTimer: Timer = { enter: noop, exit: noop }; + export const nullTimer: Timer = { enter: ts.noop, exit: ts.noop }; let enabled = false; - let timeorigin = timestamp(); - const marks = new Map(); - const counts = new Map(); - const durations = new Map(); + let timeorigin = ts.timestamp(); + const marks = new ts.Map(); + const counts = new ts.Map(); + const durations = new ts.Map(); /** * Marks a performance event. @@ -56,7 +56,7 @@ namespace ts.performance { if (enabled) { const count = counts.get(markName) ?? 0; counts.set(markName, count + 1); - marks.set(markName, timestamp()); + marks.set(markName, ts.timestamp()); performanceImpl?.mark(markName); } } @@ -72,7 +72,7 @@ namespace ts.performance { */ export function measure(measureName: string, startMarkName?: string, endMarkName?: string) { if (enabled) { - const end = (endMarkName !== undefined ? marks.get(endMarkName) : undefined) ?? timestamp(); + const end = (endMarkName !== undefined ? marks.get(endMarkName) : undefined) ?? ts.timestamp(); const start = (startMarkName !== undefined ? marks.get(startMarkName) : undefined) ?? timeorigin; const previousDuration = durations.get(measureName) || 0; durations.set(measureName, previousDuration + (end - start)); @@ -115,10 +115,10 @@ namespace ts.performance { } /** Enables (and resets) performance measurements for the compiler. */ - export function enable(system: System = sys) { + export function enable(system: ts.System = ts.sys) { if (!enabled) { enabled = true; - perfHooks ||= tryGetNativePerformanceHooks(); + perfHooks ||= ts.tryGetNativePerformanceHooks(); if (perfHooks) { timeorigin = perfHooks.performance.timeOrigin; // NodeJS's Web Performance API is currently slower than expected, but we'd still like diff --git a/src/compiler/performanceCore.ts b/src/compiler/performanceCore.ts index ac40726ebb273..301bfd67a2aa6 100644 --- a/src/compiler/performanceCore.ts +++ b/src/compiler/performanceCore.ts @@ -32,7 +32,9 @@ namespace ts { export interface PerformanceObserver { disconnect(): void; - observe(options: { entryTypes: readonly ("mark" | "measure")[] }): void; + observe(options: { + entryTypes: readonly ("mark" | "measure")[]; + }): void; } export type PerformanceObserverConstructor = new (callback: (list: PerformanceObserverEntryList, observer: PerformanceObserver) => void) => PerformanceObserver; @@ -79,8 +81,8 @@ namespace ts { // match the Web Performance API specification. Node's implementation did not allow // optional `start` and `end` arguments for `performance.measure`. // See https://github.com/nodejs/node/pull/32651 for more information. - const version = new Version(process.versions.node); - const range = new VersionRange("<12.16.3 || 13 <13.13"); + const version = new ts.Version(process.versions.node); + const range = new ts.VersionRange("<12.16.3 || 13 <13.13"); if (range.test(version)) { performance = { get timeOrigin() { return nodePerformance.timeOrigin; }, @@ -122,8 +124,7 @@ namespace ts { } /** Gets a timestamp with (at least) ms resolution */ - export const timestamp = - nativePerformance ? () => nativePerformance.now() : + export const timestamp = nativePerformance ? () => nativePerformance.now() : Date.now ? Date.now : () => +(new Date()); } \ No newline at end of file diff --git a/src/compiler/program.ts b/src/compiler/program.ts index 8ab1cd7d1ca7e..476c605c58c40 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -1,23 +1,23 @@ namespace ts { export function findConfigFile(searchPath: string, fileExists: (fileName: string) => boolean, configName = "tsconfig.json"): string | undefined { - return forEachAncestorDirectory(searchPath, ancestor => { - const fileName = combinePaths(ancestor, configName); + return ts.forEachAncestorDirectory(searchPath, ancestor => { + const fileName = ts.combinePaths(ancestor, configName); return fileExists(fileName) ? fileName : undefined; }); } export function resolveTripleslashReference(moduleName: string, containingFile: string): string { - const basePath = getDirectoryPath(containingFile); - const referencedFileName = isRootedDiskPath(moduleName) ? moduleName : combinePaths(basePath, moduleName); - return normalizePath(referencedFileName); + const basePath = ts.getDirectoryPath(containingFile); + const referencedFileName = ts.isRootedDiskPath(moduleName) ? moduleName : ts.combinePaths(basePath, moduleName); + return ts.normalizePath(referencedFileName); } /* @internal */ - export function computeCommonSourceDirectoryOfFilenames(fileNames: readonly string[], currentDirectory: string, getCanonicalFileName: GetCanonicalFileName): string { + export function computeCommonSourceDirectoryOfFilenames(fileNames: readonly string[], currentDirectory: string, getCanonicalFileName: ts.GetCanonicalFileName): string { let commonPathComponents: string[] | undefined; - const failed = forEach(fileNames, sourceFile => { + const failed = ts.forEach(fileNames, sourceFile => { // Each file contributes into common source file path - const sourcePathComponents = getNormalizedPathComponents(sourceFile, currentDirectory); + const sourcePathComponents = ts.getNormalizedPathComponents(sourceFile, currentDirectory); sourcePathComponents.pop(); // The base file name is not part of the common directory path if (!commonPathComponents) { @@ -55,7 +55,7 @@ namespace ts { return currentDirectory; } - return getPathFromPathComponents(commonPathComponents); + return ts.getPathFromPathComponents(commonPathComponents); } interface OutputFingerprint { @@ -64,23 +64,23 @@ namespace ts { mtime: Date; } - export function createCompilerHost(options: CompilerOptions, setParentNodes?: boolean): CompilerHost { + export function createCompilerHost(options: ts.CompilerOptions, setParentNodes?: boolean): ts.CompilerHost { return createCompilerHostWorker(options, setParentNodes); } /*@internal*/ // TODO(shkamat): update this after reworking ts build API - export function createCompilerHostWorker(options: CompilerOptions, setParentNodes?: boolean, system = sys): CompilerHost { - const existingDirectories = new Map(); - const getCanonicalFileName = createGetCanonicalFileName(system.useCaseSensitiveFileNames); - const computeHash = maybeBind(system, system.createHash) || generateDjb2Hash; - function getSourceFile(fileName: string, languageVersionOrOptions: ScriptTarget | CreateSourceFileOptions, onError?: (message: string) => void): SourceFile | undefined { + export function createCompilerHostWorker(options: ts.CompilerOptions, setParentNodes?: boolean, system = ts.sys): ts.CompilerHost { + const existingDirectories = new ts.Map(); + const getCanonicalFileName = ts.createGetCanonicalFileName(system.useCaseSensitiveFileNames); + const computeHash = ts.maybeBind(system, system.createHash) || ts.generateDjb2Hash; + function getSourceFile(fileName: string, languageVersionOrOptions: ts.ScriptTarget | ts.CreateSourceFileOptions, onError?: (message: string) => void): ts.SourceFile | undefined { let text: string | undefined; try { - performance.mark("beforeIORead"); + ts.performance.mark("beforeIORead"); text = compilerHost.readFile(fileName); - performance.mark("afterIORead"); - performance.measure("I/O Read", "beforeIORead", "afterIORead"); + ts.performance.mark("afterIORead"); + ts.performance.measure("I/O Read", "beforeIORead", "afterIORead"); } catch (e) { if (onError) { @@ -88,7 +88,7 @@ namespace ts { } text = ""; } - return text !== undefined ? createSourceFile(fileName, text, languageVersionOrOptions, setParentNodes) : undefined; + return text !== undefined ? ts.createSourceFile(fileName, text, languageVersionOrOptions, setParentNodes) : undefined; } function directoryExists(directoryPath: string): boolean { @@ -104,21 +104,14 @@ namespace ts { function writeFile(fileName: string, data: string, writeByteOrderMark: boolean, onError?: (message: string) => void) { try { - performance.mark("beforeIOWrite"); + ts.performance.mark("beforeIOWrite"); // NOTE: If patchWriteFileEnsuringDirectory has been called, // the system.writeFile will do its own directory creation and // the ensureDirectoriesExist call will always be redundant. - writeFileEnsuringDirectories( - fileName, - data, - writeByteOrderMark, - (path, data, writeByteOrderMark) => writeFileWorker(path, data, writeByteOrderMark), - path => (compilerHost.createDirectory || system.createDirectory)(path), - path => directoryExists(path)); - - performance.mark("afterIOWrite"); - performance.measure("I/O Write", "beforeIOWrite", "afterIOWrite"); + ts.writeFileEnsuringDirectories(fileName, data, writeByteOrderMark, (path, data, writeByteOrderMark) => writeFileWorker(path, data, writeByteOrderMark), path => (compilerHost.createDirectory || system.createDirectory)(path), path => directoryExists(path)); + ts.performance.mark("afterIOWrite"); + ts.performance.measure("I/O Write", "beforeIOWrite", "afterIOWrite"); } catch (e) { if (onError) { @@ -127,15 +120,15 @@ namespace ts { } } - let outputFingerprints: ESMap; + let outputFingerprints: ts.ESMap; function writeFileWorker(fileName: string, data: string, writeByteOrderMark: boolean) { - if (!isWatchSet(options) || !system.getModifiedTime) { + if (!ts.isWatchSet(options) || !system.getModifiedTime) { system.writeFile(fileName, data, writeByteOrderMark); return; } if (!outputFingerprints) { - outputFingerprints = new Map(); + outputFingerprints = new ts.Map(); } const hash = computeHash(data); @@ -154,7 +147,7 @@ namespace ts { system.writeFile(fileName, data, writeByteOrderMark); - const mtimeAfter = system.getModifiedTime(fileName) || missingFileModifiedTime; + const mtimeAfter = system.getModifiedTime(fileName) || ts.missingFileModifiedTime; outputFingerprints.set(fileName, { hash, @@ -164,17 +157,17 @@ namespace ts { } function getDefaultLibLocation(): string { - return getDirectoryPath(normalizePath(system.getExecutingFilePath())); + return ts.getDirectoryPath(ts.normalizePath(system.getExecutingFilePath())); } - const newLine = getNewLineCharacter(options, () => system.newLine); + const newLine = ts.getNewLineCharacter(options, () => system.newLine); const realpath = system.realpath && ((path: string) => system.realpath!(path)); - const compilerHost: CompilerHost = { + const compilerHost: ts.CompilerHost = { getSourceFile, getDefaultLibLocation, - getDefaultLibFileName: options => combinePaths(getDefaultLibLocation(), getDefaultLibFileName(options)), + getDefaultLibFileName: options => ts.combinePaths(getDefaultLibLocation(), ts.getDefaultLibFileName(options)), writeFile, - getCurrentDirectory: memoize(() => system.getCurrentDirectory()), + getCurrentDirectory: ts.memoize(() => system.getCurrentDirectory()), useCaseSensitiveFileNames: () => system.useCaseSensitiveFileNames, getCanonicalFileName, getNewLine: () => newLine, @@ -187,7 +180,7 @@ namespace ts { realpath, readDirectory: (path, extensions, include, exclude, depth) => system.readDirectory(path, extensions, include, exclude, depth), createDirectory: d => system.createDirectory(d), - createHash: maybeBind(system, system.createHash) + createHash: ts.maybeBind(system, system.createHash) }; return compilerHost; } @@ -198,32 +191,29 @@ namespace ts { readFile(fileName: string, encoding?: string): string | undefined; directoryExists?(directory: string): boolean; createDirectory?(directory: string): void; - writeFile?: WriteFileCallback; + writeFile?: ts.WriteFileCallback; } /*@internal*/ - export function changeCompilerHostLikeToUseCache( - host: CompilerHostLikeForCache, - toPath: (fileName: string) => Path, - getSourceFile?: CompilerHost["getSourceFile"] - ) { + export function changeCompilerHostLikeToUseCache(host: CompilerHostLikeForCache, toPath: (fileName: string) => ts.Path, getSourceFile?: ts.CompilerHost["getSourceFile"]) { const originalReadFile = host.readFile; const originalFileExists = host.fileExists; const originalDirectoryExists = host.directoryExists; const originalCreateDirectory = host.createDirectory; const originalWriteFile = host.writeFile; - const readFileCache = new Map(); - const fileExistsCache = new Map(); - const directoryExistsCache = new Map(); - const sourceFileCache = new Map(); + const readFileCache = new ts.Map(); + const fileExistsCache = new ts.Map(); + const directoryExistsCache = new ts.Map(); + const sourceFileCache = new ts.Map(); const readFileWithCache = (fileName: string): string | undefined => { const key = toPath(fileName); const value = readFileCache.get(key); - if (value !== undefined) return value !== false ? value : undefined; + if (value !== undefined) + return value !== false ? value : undefined; return setReadFileCache(key, fileName); }; - const setReadFileCache = (key: Path, fileName: string) => { + const setReadFileCache = (key: ts.Path, fileName: string) => { const newValue = originalReadFile.call(host, fileName); readFileCache.set(key, newValue !== undefined ? newValue : false); return newValue; @@ -231,22 +221,24 @@ namespace ts { host.readFile = fileName => { const key = toPath(fileName); const value = readFileCache.get(key); - if (value !== undefined) return value !== false ? value : undefined; // could be .d.ts from output + if (value !== undefined) + return value !== false ? value : undefined; // could be .d.ts from output // Cache json or buildInfo - if (!fileExtensionIs(fileName, Extension.Json) && !isBuildInfoFile(fileName)) { + if (!ts.fileExtensionIs(fileName, ts.Extension.Json) && !ts.isBuildInfoFile(fileName)) { return originalReadFile.call(host, fileName); } return setReadFileCache(key, fileName); }; - const getSourceFileWithCache: CompilerHost["getSourceFile"] | undefined = getSourceFile ? (fileName, languageVersion, onError, shouldCreateNewSourceFile) => { + const getSourceFileWithCache: ts.CompilerHost["getSourceFile"] | undefined = getSourceFile ? (fileName, languageVersion, onError, shouldCreateNewSourceFile) => { const key = toPath(fileName); const value = sourceFileCache.get(key); - if (value) return value; + if (value) + return value; const sourceFile = getSourceFile(fileName, languageVersion, onError, shouldCreateNewSourceFile); - if (sourceFile && (isDeclarationFileName(fileName) || fileExtensionIs(fileName, Extension.Json))) { + if (sourceFile && (ts.isDeclarationFileName(fileName) || ts.fileExtensionIs(fileName, ts.Extension.Json))) { sourceFileCache.set(key, sourceFile); } return sourceFile; @@ -256,7 +248,8 @@ namespace ts { host.fileExists = fileName => { const key = toPath(fileName); const value = fileExistsCache.get(key); - if (value !== undefined) return value; + if (value !== undefined) + return value; const newValue = originalFileExists.call(host, fileName); fileExistsCache.set(key, !!newValue); return newValue; @@ -286,7 +279,8 @@ namespace ts { host.directoryExists = directory => { const key = toPath(directory); const value = directoryExistsCache.get(key); - if (value !== undefined) return value; + if (value !== undefined) + return value; const newValue = originalDirectoryExists.call(host, directory); directoryExistsCache.set(key, !!newValue); return newValue; @@ -309,21 +303,19 @@ namespace ts { }; } - export function getPreEmitDiagnostics(program: Program, sourceFile?: SourceFile, cancellationToken?: CancellationToken): readonly Diagnostic[]; - /*@internal*/ export function getPreEmitDiagnostics(program: BuilderProgram, sourceFile?: SourceFile, cancellationToken?: CancellationToken): readonly Diagnostic[]; // eslint-disable-line @typescript-eslint/unified-signatures - export function getPreEmitDiagnostics(program: Program | BuilderProgram, sourceFile?: SourceFile, cancellationToken?: CancellationToken): readonly Diagnostic[] { - let diagnostics: Diagnostic[] | undefined; - diagnostics = addRange(diagnostics, program.getConfigFileParsingDiagnostics()); - diagnostics = addRange(diagnostics, program.getOptionsDiagnostics(cancellationToken)); - diagnostics = addRange(diagnostics, program.getSyntacticDiagnostics(sourceFile, cancellationToken)); - diagnostics = addRange(diagnostics, program.getGlobalDiagnostics(cancellationToken)); - diagnostics = addRange(diagnostics, program.getSemanticDiagnostics(sourceFile, cancellationToken)); - - if (getEmitDeclarations(program.getCompilerOptions())) { - diagnostics = addRange(diagnostics, program.getDeclarationDiagnostics(sourceFile, cancellationToken)); - } - - return sortAndDeduplicateDiagnostics(diagnostics || emptyArray); + export function getPreEmitDiagnostics(program: ts.Program, sourceFile?: ts.SourceFile, cancellationToken?: ts.CancellationToken): readonly ts.Diagnostic[]; + /*@internal*/ export function getPreEmitDiagnostics(program: ts.BuilderProgram, sourceFile?: ts.SourceFile, cancellationToken?: ts.CancellationToken): readonly ts.Diagnostic[]; // eslint-disable-line @typescript-eslint/unified-signatures + export function getPreEmitDiagnostics(program: ts.Program | ts.BuilderProgram, sourceFile?: ts.SourceFile, cancellationToken?: ts.CancellationToken): readonly ts.Diagnostic[] { + let diagnostics: ts.Diagnostic[] | undefined; + diagnostics = ts.addRange(diagnostics, program.getConfigFileParsingDiagnostics()); + diagnostics = ts.addRange(diagnostics, program.getOptionsDiagnostics(cancellationToken)); + diagnostics = ts.addRange(diagnostics, program.getSyntacticDiagnostics(sourceFile, cancellationToken)); + diagnostics = ts.addRange(diagnostics, program.getGlobalDiagnostics(cancellationToken)); + diagnostics = ts.addRange(diagnostics, program.getSemanticDiagnostics(sourceFile, cancellationToken)); + if (ts.getEmitDeclarations(program.getCompilerOptions())) { + diagnostics = ts.addRange(diagnostics, program.getDeclarationDiagnostics(sourceFile, cancellationToken)); + } + return ts.sortAndDeduplicateDiagnostics(diagnostics || ts.emptyArray); } export interface FormatDiagnosticsHost { @@ -332,7 +324,7 @@ namespace ts { getNewLine(): string; } - export function formatDiagnostics(diagnostics: readonly Diagnostic[], host: FormatDiagnosticsHost): string { + export function formatDiagnostics(diagnostics: readonly ts.Diagnostic[], host: FormatDiagnosticsHost): string { let output = ""; for (const diagnostic of diagnostics) { @@ -341,13 +333,13 @@ namespace ts { return output; } - export function formatDiagnostic(diagnostic: Diagnostic, host: FormatDiagnosticsHost): string { - const errorMessage = `${diagnosticCategoryName(diagnostic)} TS${diagnostic.code}: ${flattenDiagnosticMessageText(diagnostic.messageText, host.getNewLine())}${host.getNewLine()}`; + export function formatDiagnostic(diagnostic: ts.Diagnostic, host: FormatDiagnosticsHost): string { + const errorMessage = `${ts.diagnosticCategoryName(diagnostic)} TS${diagnostic.code}: ${flattenDiagnosticMessageText(diagnostic.messageText, host.getNewLine())}${host.getNewLine()}`; if (diagnostic.file) { - const { line, character } = getLineAndCharacterOfPosition(diagnostic.file, diagnostic.start!); // TODO: GH#18217 + const { line, character } = ts.getLineAndCharacterOfPosition(diagnostic.file, diagnostic.start!); // TODO: GH#18217 const fileName = diagnostic.file.fileName; - const relativeFileName = convertToRelativePath(fileName, host.getCurrentDirectory(), fileName => host.getCanonicalFileName(fileName)); + const relativeFileName = ts.convertToRelativePath(fileName, host.getCurrentDirectory(), fileName => host.getCanonicalFileName(fileName)); return `${relativeFileName}(${line + 1},${character + 1}): ` + errorMessage; } @@ -368,12 +360,12 @@ namespace ts { const ellipsis = "..."; const halfIndent = " "; const indent = " "; - function getCategoryFormat(category: DiagnosticCategory): ForegroundColorEscapeSequences { + function getCategoryFormat(category: ts.DiagnosticCategory): ForegroundColorEscapeSequences { switch (category) { - case DiagnosticCategory.Error: return ForegroundColorEscapeSequences.Red; - case DiagnosticCategory.Warning: return ForegroundColorEscapeSequences.Yellow; - case DiagnosticCategory.Suggestion: return Debug.fail("Should never get an Info diagnostic on the command line."); - case DiagnosticCategory.Message: return ForegroundColorEscapeSequences.Blue; + case ts.DiagnosticCategory.Error: return ForegroundColorEscapeSequences.Red; + case ts.DiagnosticCategory.Warning: return ForegroundColorEscapeSequences.Yellow; + case ts.DiagnosticCategory.Suggestion: return ts.Debug.fail("Should never get an Info diagnostic on the command line."); + case ts.DiagnosticCategory.Message: return ForegroundColorEscapeSequences.Blue; } } @@ -382,10 +374,10 @@ namespace ts { return formatStyle + text + resetEscapeSequence; } - function formatCodeSpan(file: SourceFile, start: number, length: number, indent: string, squiggleColor: ForegroundColorEscapeSequences, host: FormatDiagnosticsHost) { - const { line: firstLine, character: firstLineChar } = getLineAndCharacterOfPosition(file, start); - const { line: lastLine, character: lastLineChar } = getLineAndCharacterOfPosition(file, start + length); - const lastLineInFile = getLineAndCharacterOfPosition(file, file.text.length).line; + function formatCodeSpan(file: ts.SourceFile, start: number, length: number, indent: string, squiggleColor: ForegroundColorEscapeSequences, host: FormatDiagnosticsHost) { + const { line: firstLine, character: firstLineChar } = ts.getLineAndCharacterOfPosition(file, start); + const { line: lastLine, character: lastLineChar } = ts.getLineAndCharacterOfPosition(file, start + length); + const lastLineInFile = ts.getLineAndCharacterOfPosition(file, file.text.length).line; const hasMoreThanFiveLines = (lastLine - firstLine) >= 4; let gutterWidth = (lastLine + 1 + "").length; @@ -399,22 +391,22 @@ namespace ts { // If the error spans over 5 lines, we'll only show the first 2 and last 2 lines, // so we'll skip ahead to the second-to-last line. if (hasMoreThanFiveLines && firstLine + 1 < i && i < lastLine - 1) { - context += indent + formatColorAndReset(padLeft(ellipsis, gutterWidth), gutterStyleSequence) + gutterSeparator + host.getNewLine(); + context += indent + formatColorAndReset(ts.padLeft(ellipsis, gutterWidth), gutterStyleSequence) + gutterSeparator + host.getNewLine(); i = lastLine - 1; } - const lineStart = getPositionOfLineAndCharacter(file, i, 0); - const lineEnd = i < lastLineInFile ? getPositionOfLineAndCharacter(file, i + 1, 0) : file.text.length; + const lineStart = ts.getPositionOfLineAndCharacter(file, i, 0); + const lineEnd = i < lastLineInFile ? ts.getPositionOfLineAndCharacter(file, i + 1, 0) : file.text.length; let lineContent = file.text.slice(lineStart, lineEnd); - lineContent = trimStringEnd(lineContent); // trim from end + lineContent = ts.trimStringEnd(lineContent); // trim from end lineContent = lineContent.replace(/\t/g, " "); // convert tabs to single spaces // Output the gutter and the actual contents of the line. - context += indent + formatColorAndReset(padLeft(i + 1 + "", gutterWidth), gutterStyleSequence) + gutterSeparator; + context += indent + formatColorAndReset(ts.padLeft(i + 1 + "", gutterWidth), gutterStyleSequence) + gutterSeparator; context += lineContent + host.getNewLine(); // Output the gutter and the error span for the line using tildes. - context += indent + formatColorAndReset(padLeft("", gutterWidth), gutterStyleSequence) + gutterSeparator; + context += indent + formatColorAndReset(ts.padLeft("", gutterWidth), gutterStyleSequence) + gutterSeparator; context += squiggleColor; if (i === firstLine) { // If we're on the last line, then limit it to the last character of the last line. @@ -437,9 +429,9 @@ namespace ts { } /* @internal */ - export function formatLocation(file: SourceFile, start: number, host: FormatDiagnosticsHost, color = formatColorAndReset) { - const { line: firstLine, character: firstLineChar } = getLineAndCharacterOfPosition(file, start); // TODO: GH#18217 - const relativeFileName = host ? convertToRelativePath(file.fileName, host.getCurrentDirectory(), fileName => host.getCanonicalFileName(fileName)) : file.fileName; + export function formatLocation(file: ts.SourceFile, start: number, host: FormatDiagnosticsHost, color = formatColorAndReset) { + const { line: firstLine, character: firstLineChar } = ts.getLineAndCharacterOfPosition(file, start); // TODO: GH#18217 + const relativeFileName = host ? ts.convertToRelativePath(file.fileName, host.getCurrentDirectory(), fileName => host.getCanonicalFileName(fileName)) : file.fileName; let output = ""; output += color(relativeFileName, ForegroundColorEscapeSequences.Cyan); @@ -450,7 +442,7 @@ namespace ts { return output; } - export function formatDiagnosticsWithColorAndContext(diagnostics: readonly Diagnostic[], host: FormatDiagnosticsHost): string { + export function formatDiagnosticsWithColorAndContext(diagnostics: readonly ts.Diagnostic[], host: FormatDiagnosticsHost): string { let output = ""; for (const diagnostic of diagnostics) { if (diagnostic.file) { @@ -459,7 +451,7 @@ namespace ts { output += " - "; } - output += formatColorAndReset(diagnosticCategoryName(diagnostic), getCategoryFormat(diagnostic.category)); + output += formatColorAndReset(ts.diagnosticCategoryName(diagnostic), getCategoryFormat(diagnostic.category)); output += formatColorAndReset(` TS${diagnostic.code}: `, ForegroundColorEscapeSequences.Grey); output += flattenDiagnosticMessageText(diagnostic.messageText, host.getNewLine()); @@ -484,8 +476,8 @@ namespace ts { return output; } - export function flattenDiagnosticMessageText(diag: string | DiagnosticMessageChain | undefined, newLine: string, indent = 0): string { - if (isString(diag)) { + export function flattenDiagnosticMessageText(diag: string | ts.DiagnosticMessageChain | undefined, newLine: string, indent = 0): string { + if (ts.isString(diag)) { return diag; } else if (diag === undefined) { @@ -510,17 +502,17 @@ namespace ts { } /* @internal */ - export function loadWithTypeDirectiveCache(names: string[] | readonly FileReference[], containingFile: string, redirectedReference: ResolvedProjectReference | undefined, containingFileMode: SourceFile["impliedNodeFormat"], loader: (name: string, containingFile: string, redirectedReference: ResolvedProjectReference | undefined, resolutionMode: SourceFile["impliedNodeFormat"]) => T): T[] { + export function loadWithTypeDirectiveCache(names: string[] | readonly ts.FileReference[], containingFile: string, redirectedReference: ts.ResolvedProjectReference | undefined, containingFileMode: ts.SourceFile["impliedNodeFormat"], loader: (name: string, containingFile: string, redirectedReference: ts.ResolvedProjectReference | undefined, resolutionMode: ts.SourceFile["impliedNodeFormat"]) => T): T[] { if (names.length === 0) { return []; } const resolutions: T[] = []; - const cache = new Map(); + const cache = new ts.Map(); for (const name of names) { let result: T; const mode = getModeForFileReference(name, containingFileMode); // We lower-case all type references because npm automatically lowercases all packages. See GH#9824. - const strName = isString(name) ? name : name.fileName.toLowerCase(); + const strName = ts.isString(name) ? name : name.fileName.toLowerCase(); const cacheKey = mode !== undefined ? `${mode}|${strName}` : strName; if (cache.has(cacheKey)) { result = cache.get(cacheKey)!; @@ -535,27 +527,29 @@ namespace ts { /* @internal */ interface SourceFileImportsList { - imports: SourceFile["imports"]; - moduleAugmentations: SourceFile["moduleAugmentations"]; - impliedNodeFormat?: SourceFile["impliedNodeFormat"]; - }; + imports: ts.SourceFile["imports"]; + moduleAugmentations: ts.SourceFile["moduleAugmentations"]; + impliedNodeFormat?: ts.SourceFile["impliedNodeFormat"]; + } + ; /* @internal */ - export function getModeForFileReference(ref: FileReference | string, containingFileMode: SourceFile["impliedNodeFormat"]) { - return (isString(ref) ? containingFileMode : ref.resolutionMode) || containingFileMode; + export function getModeForFileReference(ref: ts.FileReference | string, containingFileMode: ts.SourceFile["impliedNodeFormat"]) { + return (ts.isString(ref) ? containingFileMode : ref.resolutionMode) || containingFileMode; } /* @internal */ export function getModeForResolutionAtIndex(file: SourceFileImportsList, index: number) { - if (file.impliedNodeFormat === undefined) return undefined; + if (file.impliedNodeFormat === undefined) + return undefined; // we ensure all elements of file.imports and file.moduleAugmentations have the relevant parent pointers set during program setup, // so it's safe to use them even pre-bind return getModeForUsageLocation(file, getModuleNameStringLiteralAt(file, index)); } /* @internal */ - export function isExclusivelyTypeOnlyImportOrExport(decl: ImportDeclaration | ExportDeclaration) { - if (isExportDeclaration(decl)) { + export function isExclusivelyTypeOnlyImportOrExport(decl: ts.ImportDeclaration | ts.ExportDeclaration) { + if (ts.isExportDeclaration(decl)) { return decl.isTypeOnly; } if (decl.importClause?.isTypeOnly) { @@ -565,9 +559,12 @@ namespace ts { } /* @internal */ - export function getModeForUsageLocation(file: {impliedNodeFormat?: SourceFile["impliedNodeFormat"]}, usage: StringLiteralLike) { - if (file.impliedNodeFormat === undefined) return undefined; - if ((isImportDeclaration(usage.parent) || isExportDeclaration(usage.parent))) { + export function getModeForUsageLocation(file: { + impliedNodeFormat?: ts.SourceFile["impliedNodeFormat"]; + }, usage: ts.StringLiteralLike) { + if (file.impliedNodeFormat === undefined) + return undefined; + if ((ts.isImportDeclaration(usage.parent) || ts.isExportDeclaration(usage.parent))) { const isTypeOnly = isExclusivelyTypeOnlyImportOrExport(usage.parent); if (isTypeOnly) { const override = getResolutionModeOverrideForClause(usage.parent.assertClause); @@ -576,50 +573,53 @@ namespace ts { } } } - if (usage.parent.parent && isImportTypeNode(usage.parent.parent)) { + if (usage.parent.parent && ts.isImportTypeNode(usage.parent.parent)) { const override = getResolutionModeOverrideForClause(usage.parent.parent.assertions?.assertClause); if (override) { return override; } } - if (file.impliedNodeFormat !== ModuleKind.ESNext) { + if (file.impliedNodeFormat !== ts.ModuleKind.ESNext) { // in cjs files, import call expressions are esm format, otherwise everything is cjs - return isImportCall(walkUpParenthesizedExpressions(usage.parent)) ? ModuleKind.ESNext : ModuleKind.CommonJS; + return ts.isImportCall(ts.walkUpParenthesizedExpressions(usage.parent)) ? ts.ModuleKind.ESNext : ts.ModuleKind.CommonJS; } // in esm files, import=require statements are cjs format, otherwise everything is esm // imports are only parent'd up to their containing declaration/expression, so access farther parents with care - const exprParentParent = walkUpParenthesizedExpressions(usage.parent)?.parent; - return exprParentParent && isImportEqualsDeclaration(exprParentParent) ? ModuleKind.CommonJS : ModuleKind.ESNext; + const exprParentParent = ts.walkUpParenthesizedExpressions(usage.parent)?.parent; + return exprParentParent && ts.isImportEqualsDeclaration(exprParentParent) ? ts.ModuleKind.CommonJS : ts.ModuleKind.ESNext; } /* @internal */ - export function getResolutionModeOverrideForClause(clause: AssertClause | undefined, grammarErrorOnNode?: (node: Node, diagnostic: DiagnosticMessage) => void) { - if (!clause) return undefined; - if (length(clause.elements) !== 1) { - grammarErrorOnNode?.(clause, Diagnostics.Type_import_assertions_should_have_exactly_one_key_resolution_mode_with_value_import_or_require); + export function getResolutionModeOverrideForClause(clause: ts.AssertClause | undefined, grammarErrorOnNode?: (node: ts.Node, diagnostic: ts.DiagnosticMessage) => void) { + if (!clause) + return undefined; + if (ts.length(clause.elements) !== 1) { + grammarErrorOnNode?.(clause, ts.Diagnostics.Type_import_assertions_should_have_exactly_one_key_resolution_mode_with_value_import_or_require); return undefined; } const elem = clause.elements[0]; - if (!isStringLiteralLike(elem.name)) return undefined; + if (!ts.isStringLiteralLike(elem.name)) + return undefined; if (elem.name.text !== "resolution-mode") { - grammarErrorOnNode?.(elem.name, Diagnostics.resolution_mode_is_the_only_valid_key_for_type_import_assertions); + grammarErrorOnNode?.(elem.name, ts.Diagnostics.resolution_mode_is_the_only_valid_key_for_type_import_assertions); return undefined; } - if (!isStringLiteralLike(elem.value)) return undefined; + if (!ts.isStringLiteralLike(elem.value)) + return undefined; if (elem.value.text !== "import" && elem.value.text !== "require") { - grammarErrorOnNode?.(elem.value, Diagnostics.resolution_mode_should_be_either_require_or_import); + grammarErrorOnNode?.(elem.value, ts.Diagnostics.resolution_mode_should_be_either_require_or_import); return undefined; } - return elem.value.text === "import" ? ModuleKind.ESNext : ModuleKind.CommonJS; + return elem.value.text === "import" ? ts.ModuleKind.ESNext : ts.ModuleKind.CommonJS; } /* @internal */ - export function loadWithModeAwareCache(names: string[], containingFile: SourceFile, containingFileName: string, redirectedReference: ResolvedProjectReference | undefined, loader: (name: string, resolverMode: ModuleKind.CommonJS | ModuleKind.ESNext | undefined, containingFileName: string, redirectedReference: ResolvedProjectReference | undefined) => T): T[] { + export function loadWithModeAwareCache(names: string[], containingFile: ts.SourceFile, containingFileName: string, redirectedReference: ts.ResolvedProjectReference | undefined, loader: (name: string, resolverMode: ts.ModuleKind.CommonJS | ts.ModuleKind.ESNext | undefined, containingFileName: string, redirectedReference: ts.ResolvedProjectReference | undefined) => T): T[] { if (names.length === 0) { return []; } const resolutions: T[] = []; - const cache = new Map(); + const cache = new ts.Map(); let i = 0; for (const name of names) { let result: T; @@ -638,45 +638,34 @@ namespace ts { } /* @internal */ - export function forEachResolvedProjectReference( - resolvedProjectReferences: readonly (ResolvedProjectReference | undefined)[] | undefined, - cb: (resolvedProjectReference: ResolvedProjectReference, parent: ResolvedProjectReference | undefined) => T | undefined - ): T | undefined { + export function forEachResolvedProjectReference(resolvedProjectReferences: readonly (ts.ResolvedProjectReference | undefined)[] | undefined, cb: (resolvedProjectReference: ts.ResolvedProjectReference, parent: ts.ResolvedProjectReference | undefined) => T | undefined): T | undefined { return forEachProjectReference(/*projectReferences*/ undefined, resolvedProjectReferences, (resolvedRef, parent) => resolvedRef && cb(resolvedRef, parent)); } - function forEachProjectReference( - projectReferences: readonly ProjectReference[] | undefined, - resolvedProjectReferences: readonly (ResolvedProjectReference | undefined)[] | undefined, - cbResolvedRef: (resolvedRef: ResolvedProjectReference | undefined, parent: ResolvedProjectReference | undefined, index: number) => T | undefined, - cbRef?: (projectReferences: readonly ProjectReference[] | undefined, parent: ResolvedProjectReference | undefined) => T | undefined - ): T | undefined { - let seenResolvedRefs: Set | undefined; + function forEachProjectReference(projectReferences: readonly ts.ProjectReference[] | undefined, resolvedProjectReferences: readonly (ts.ResolvedProjectReference | undefined)[] | undefined, cbResolvedRef: (resolvedRef: ts.ResolvedProjectReference | undefined, parent: ts.ResolvedProjectReference | undefined, index: number) => T | undefined, cbRef?: (projectReferences: readonly ts.ProjectReference[] | undefined, parent: ts.ResolvedProjectReference | undefined) => T | undefined): T | undefined { + let seenResolvedRefs: ts.Set | undefined; return worker(projectReferences, resolvedProjectReferences, /*parent*/ undefined); - function worker( - projectReferences: readonly ProjectReference[] | undefined, - resolvedProjectReferences: readonly (ResolvedProjectReference | undefined)[] | undefined, - parent: ResolvedProjectReference | undefined, - ): T | undefined { + function worker(projectReferences: readonly ts.ProjectReference[] | undefined, resolvedProjectReferences: readonly (ts.ResolvedProjectReference | undefined)[] | undefined, parent: ts.ResolvedProjectReference | undefined): T | undefined { // Visit project references first if (cbRef) { const result = cbRef(projectReferences, parent); - if (result) return result; + if (result) + return result; } - return forEach(resolvedProjectReferences, (resolvedRef, index) => { + return ts.forEach(resolvedProjectReferences, (resolvedRef, index) => { if (resolvedRef && seenResolvedRefs?.has(resolvedRef.sourceFile.path)) { // ignore recursives return undefined; } const result = cbResolvedRef(resolvedRef, parent, index); - if (result || !resolvedRef) return result; - - (seenResolvedRefs ||= new Set()).add(resolvedRef.sourceFile.path); + if (result || !resolvedRef) + return result; + (seenResolvedRefs ||= new ts.Set()).add(resolvedRef.sourceFile.path); return worker(resolvedRef.commandLine.projectReferences, resolvedRef.references, resolvedRef); }); } @@ -685,18 +674,18 @@ namespace ts { /* @internal */ export const inferredTypesContainingFile = "__inferred type names__.ts"; - interface DiagnosticCache { - perFile?: ESMap; + interface DiagnosticCache { + perFile?: ts.ESMap; allDiagnostics?: readonly T[]; } /*@internal*/ - export function isReferencedFile(reason: FileIncludeReason | undefined): reason is ReferencedFile { + export function isReferencedFile(reason: ts.FileIncludeReason | undefined): reason is ts.ReferencedFile { switch (reason?.kind) { - case FileIncludeKind.Import: - case FileIncludeKind.ReferenceFile: - case FileIncludeKind.TypeReferenceDirective: - case FileIncludeKind.LibReferenceDirective: + case ts.FileIncludeKind.Import: + case ts.FileIncludeKind.ReferenceFile: + case ts.FileIncludeKind.TypeReferenceDirective: + case ts.FileIncludeKind.LibReferenceDirective: return true; default: return false; @@ -705,16 +694,16 @@ namespace ts { /*@internal*/ export interface ReferenceFileLocation { - file: SourceFile; + file: ts.SourceFile; pos: number; end: number; - packageId: PackageId | undefined; + packageId: ts.PackageId | undefined; } /*@internal*/ export interface SyntheticReferenceFileLocation { - file: SourceFile; - packageId: PackageId | undefined; + file: ts.SourceFile; + packageId: ts.PackageId | undefined; text: string; } @@ -724,30 +713,31 @@ namespace ts { } /*@internal*/ - export function getReferencedFileLocation(getSourceFileByPath: (path: Path) => SourceFile | undefined, ref: ReferencedFile): ReferenceFileLocation | SyntheticReferenceFileLocation { - const file = Debug.checkDefined(getSourceFileByPath(ref.file)); + export function getReferencedFileLocation(getSourceFileByPath: (path: ts.Path) => ts.SourceFile | undefined, ref: ts.ReferencedFile): ReferenceFileLocation | SyntheticReferenceFileLocation { + const file = ts.Debug.checkDefined(getSourceFileByPath(ref.file)); const { kind, index } = ref; - let pos: number | undefined, end: number | undefined, packageId: PackageId | undefined, resolutionMode: FileReference["resolutionMode"] | undefined; + let pos: number | undefined, end: number | undefined, packageId: ts.PackageId | undefined, resolutionMode: ts.FileReference["resolutionMode"] | undefined; switch (kind) { - case FileIncludeKind.Import: + case ts.FileIncludeKind.Import: const importLiteral = getModuleNameStringLiteralAt(file, index); packageId = file.resolvedModules?.get(importLiteral.text, getModeForResolutionAtIndex(file, index))?.packageId; - if (importLiteral.pos === -1) return { file, packageId, text: importLiteral.text }; - pos = skipTrivia(file.text, importLiteral.pos); + if (importLiteral.pos === -1) + return { file, packageId, text: importLiteral.text }; + pos = ts.skipTrivia(file.text, importLiteral.pos); end = importLiteral.end; break; - case FileIncludeKind.ReferenceFile: + case ts.FileIncludeKind.ReferenceFile: ({ pos, end } = file.referencedFiles[index]); break; - case FileIncludeKind.TypeReferenceDirective: + case ts.FileIncludeKind.TypeReferenceDirective: ({ pos, end, resolutionMode } = file.typeReferenceDirectives[index]); - packageId = file.resolvedTypeReferenceDirectiveNames?.get(toFileNameLowerCase(file.typeReferenceDirectives[index].fileName), resolutionMode || file.impliedNodeFormat)?.packageId; + packageId = file.resolvedTypeReferenceDirectiveNames?.get(ts.toFileNameLowerCase(file.typeReferenceDirectives[index].fileName), resolutionMode || file.impliedNodeFormat)?.packageId; break; - case FileIncludeKind.LibReferenceDirective: + case ts.FileIncludeKind.LibReferenceDirective: ({ pos, end } = file.libReferenceDirectives[index]); break; default: - return Debug.assertNever(kind); + return ts.Debug.assertNever(kind); } return { file, pos, end, packageId }; } @@ -756,81 +746,80 @@ namespace ts { * Determines if program structure is upto date or needs to be recreated */ /* @internal */ - export function isProgramUptoDate( - program: Program | undefined, - rootFileNames: string[], - newOptions: CompilerOptions, - getSourceVersion: (path: Path, fileName: string) => string | undefined, - fileExists: (fileName: string) => boolean, - hasInvalidatedResolution: HasInvalidatedResolution, - hasChangedAutomaticTypeDirectiveNames: HasChangedAutomaticTypeDirectiveNames | undefined, - getParsedCommandLine: (fileName: string) => ParsedCommandLine | undefined, - projectReferences: readonly ProjectReference[] | undefined - ): boolean { + export function isProgramUptoDate(program: ts.Program | undefined, rootFileNames: string[], newOptions: ts.CompilerOptions, getSourceVersion: (path: ts.Path, fileName: string) => string | undefined, fileExists: (fileName: string) => boolean, hasInvalidatedResolution: ts.HasInvalidatedResolution, hasChangedAutomaticTypeDirectiveNames: ts.HasChangedAutomaticTypeDirectiveNames | undefined, getParsedCommandLine: (fileName: string) => ts.ParsedCommandLine | undefined, projectReferences: readonly ts.ProjectReference[] | undefined): boolean { // If we haven't created a program yet or have changed automatic type directives, then it is not up-to-date - if (!program || hasChangedAutomaticTypeDirectiveNames?.()) return false; + if (!program || hasChangedAutomaticTypeDirectiveNames?.()) + return false; // If root file names don't match - if (!arrayIsEqualTo(program.getRootFileNames(), rootFileNames)) return false; - - let seenResolvedRefs: ResolvedProjectReference[] | undefined; + if (!ts.arrayIsEqualTo(program.getRootFileNames(), rootFileNames)) + return false; + let seenResolvedRefs: ts.ResolvedProjectReference[] | undefined; // If project references don't match - if (!arrayIsEqualTo(program.getProjectReferences(), projectReferences, projectReferenceUptoDate)) return false; + if (!ts.arrayIsEqualTo(program.getProjectReferences(), projectReferences, projectReferenceUptoDate)) + return false; // If any file is not up-to-date, then the whole program is not up-to-date - if (program.getSourceFiles().some(sourceFileNotUptoDate)) return false; + if (program.getSourceFiles().some(sourceFileNotUptoDate)) + return false; // If any of the missing file paths are now created - if (program.getMissingFilePaths().some(fileExists)) return false; + if (program.getMissingFilePaths().some(fileExists)) + return false; const currentOptions = program.getCompilerOptions(); // If the compilation settings do no match, then the program is not up-to-date - if (!compareDataObjects(currentOptions, newOptions)) return false; + if (!ts.compareDataObjects(currentOptions, newOptions)) + return false; // If everything matches but the text of config file is changed, // error locations can change for program options, so update the program - if (currentOptions.configFile && newOptions.configFile) return currentOptions.configFile.text === newOptions.configFile.text; + if (currentOptions.configFile && newOptions.configFile) + return currentOptions.configFile.text === newOptions.configFile.text; return true; - function sourceFileNotUptoDate(sourceFile: SourceFile) { + function sourceFileNotUptoDate(sourceFile: ts.SourceFile) { return !sourceFileVersionUptoDate(sourceFile) || hasInvalidatedResolution(sourceFile.path); } - function sourceFileVersionUptoDate(sourceFile: SourceFile) { + function sourceFileVersionUptoDate(sourceFile: ts.SourceFile) { return sourceFile.version === getSourceVersion(sourceFile.resolvedPath, sourceFile.fileName); } - function projectReferenceUptoDate(oldRef: ProjectReference, newRef: ProjectReference, index: number) { - return projectReferenceIsEqualTo(oldRef, newRef) && + function projectReferenceUptoDate(oldRef: ts.ProjectReference, newRef: ts.ProjectReference, index: number) { + return ts.projectReferenceIsEqualTo(oldRef, newRef) && resolvedProjectReferenceUptoDate(program!.getResolvedProjectReferences()![index], oldRef); } - function resolvedProjectReferenceUptoDate(oldResolvedRef: ResolvedProjectReference | undefined, oldRef: ProjectReference): boolean { + function resolvedProjectReferenceUptoDate(oldResolvedRef: ts.ResolvedProjectReference | undefined, oldRef: ts.ProjectReference): boolean { if (oldResolvedRef) { // Assume true - if (contains(seenResolvedRefs, oldResolvedRef)) return true; + if (ts.contains(seenResolvedRefs, oldResolvedRef)) + return true; const refPath = resolveProjectReferencePath(oldRef); const newParsedCommandLine = getParsedCommandLine(refPath); // Check if config file exists - if (!newParsedCommandLine) return false; + if (!newParsedCommandLine) + return false; // If change in source file - if (oldResolvedRef.commandLine.options.configFile !== newParsedCommandLine.options.configFile) return false; + if (oldResolvedRef.commandLine.options.configFile !== newParsedCommandLine.options.configFile) + return false; // check file names - if (!arrayIsEqualTo(oldResolvedRef.commandLine.fileNames, newParsedCommandLine.fileNames)) return false; + if (!ts.arrayIsEqualTo(oldResolvedRef.commandLine.fileNames, newParsedCommandLine.fileNames)) + return false; // Add to seen before checking the referenced paths of this config file (seenResolvedRefs || (seenResolvedRefs = [])).push(oldResolvedRef); // If child project references are upto date, this project reference is uptodate - return !forEach(oldResolvedRef.references, (childResolvedRef, index) => - !resolvedProjectReferenceUptoDate(childResolvedRef, oldResolvedRef.commandLine.projectReferences![index])); + return !ts.forEach(oldResolvedRef.references, (childResolvedRef, index) => !resolvedProjectReferenceUptoDate(childResolvedRef, oldResolvedRef.commandLine.projectReferences![index])); } // In old program, not able to resolve project reference path, @@ -840,7 +829,7 @@ namespace ts { } } - export function getConfigFileParsingDiagnostics(configFileParseResult: ParsedCommandLine): readonly Diagnostic[] { + export function getConfigFileParsingDiagnostics(configFileParseResult: ts.ParsedCommandLine): readonly ts.Diagnostic[] { return configFileParseResult.options.configFile ? [...configFileParseResult.options.configFile.parseDiagnostics, ...configFileParseResult.errors] : configFileParseResult.errors; @@ -856,129 +845,130 @@ namespace ts { * @param options The compiler options to perform the analysis under - relevant options are `moduleResolution` and `traceResolution` * @returns `undefined` if the path has no relevant implied format, `ModuleKind.ESNext` for esm format, and `ModuleKind.CommonJS` for cjs format */ - export function getImpliedNodeFormatForFile(fileName: Path, packageJsonInfoCache: PackageJsonInfoCache | undefined, host: ModuleResolutionHost, options: CompilerOptions): ModuleKind.ESNext | ModuleKind.CommonJS | undefined { - switch (getEmitModuleResolutionKind(options)) { - case ModuleResolutionKind.Node16: - case ModuleResolutionKind.NodeNext: - return fileExtensionIsOneOf(fileName, [Extension.Dmts, Extension.Mts, Extension.Mjs]) ? ModuleKind.ESNext : - fileExtensionIsOneOf(fileName, [Extension.Dcts, Extension.Cts, Extension.Cjs]) ? ModuleKind.CommonJS : - fileExtensionIsOneOf(fileName, [Extension.Dts, Extension.Ts, Extension.Tsx, Extension.Js, Extension.Jsx]) ? lookupFromPackageJson() : + export function getImpliedNodeFormatForFile(fileName: ts.Path, packageJsonInfoCache: ts.PackageJsonInfoCache | undefined, host: ts.ModuleResolutionHost, options: ts.CompilerOptions): ts.ModuleKind.ESNext | ts.ModuleKind.CommonJS | undefined { + switch (ts.getEmitModuleResolutionKind(options)) { + case ts.ModuleResolutionKind.Node16: + case ts.ModuleResolutionKind.NodeNext: + return ts.fileExtensionIsOneOf(fileName, [ts.Extension.Dmts, ts.Extension.Mts, ts.Extension.Mjs]) ? ts.ModuleKind.ESNext : + ts.fileExtensionIsOneOf(fileName, [ts.Extension.Dcts, ts.Extension.Cts, ts.Extension.Cjs]) ? ts.ModuleKind.CommonJS : + ts.fileExtensionIsOneOf(fileName, [ts.Extension.Dts, ts.Extension.Ts, ts.Extension.Tsx, ts.Extension.Js, ts.Extension.Jsx]) ? lookupFromPackageJson() : undefined; // other extensions, like `json` or `tsbuildinfo`, are set as `undefined` here but they should never be fed through the transformer pipeline default: return undefined; } - function lookupFromPackageJson(): ModuleKind.ESNext | ModuleKind.CommonJS { - const scope = getPackageScopeForPath(fileName, packageJsonInfoCache, host, options); - return scope?.packageJsonContent.type === "module" ? ModuleKind.ESNext : ModuleKind.CommonJS; + function lookupFromPackageJson(): ts.ModuleKind.ESNext | ts.ModuleKind.CommonJS { + const scope = ts.getPackageScopeForPath(fileName, packageJsonInfoCache, host, options); + return scope?.packageJsonContent.type === "module" ? ts.ModuleKind.ESNext : ts.ModuleKind.CommonJS; } } /** @internal */ - export const plainJSErrors: Set = new Set([ + export const plainJSErrors: ts.Set = new ts.Set([ // binder errors - Diagnostics.Cannot_redeclare_block_scoped_variable_0.code, - Diagnostics.A_module_cannot_have_multiple_default_exports.code, - Diagnostics.Another_export_default_is_here.code, - Diagnostics.The_first_export_default_is_here.code, - Diagnostics.Identifier_expected_0_is_a_reserved_word_at_the_top_level_of_a_module.code, - Diagnostics.Identifier_expected_0_is_a_reserved_word_in_strict_mode_Modules_are_automatically_in_strict_mode.code, - Diagnostics.Identifier_expected_0_is_a_reserved_word_that_cannot_be_used_here.code, - Diagnostics.constructor_is_a_reserved_word.code, - Diagnostics.delete_cannot_be_called_on_an_identifier_in_strict_mode.code, - Diagnostics.Code_contained_in_a_class_is_evaluated_in_JavaScript_s_strict_mode_which_does_not_allow_this_use_of_0_For_more_information_see_https_Colon_Slash_Slashdeveloper_mozilla_org_Slashen_US_Slashdocs_SlashWeb_SlashJavaScript_SlashReference_SlashStrict_mode.code, - Diagnostics.Invalid_use_of_0_Modules_are_automatically_in_strict_mode.code, - Diagnostics.Invalid_use_of_0_in_strict_mode.code, - Diagnostics.A_label_is_not_allowed_here.code, - Diagnostics.Octal_literals_are_not_allowed_in_strict_mode.code, - Diagnostics.with_statements_are_not_allowed_in_strict_mode.code, + ts.Diagnostics.Cannot_redeclare_block_scoped_variable_0.code, + ts.Diagnostics.A_module_cannot_have_multiple_default_exports.code, + ts.Diagnostics.Another_export_default_is_here.code, + ts.Diagnostics.The_first_export_default_is_here.code, + ts.Diagnostics.Identifier_expected_0_is_a_reserved_word_at_the_top_level_of_a_module.code, + ts.Diagnostics.Identifier_expected_0_is_a_reserved_word_in_strict_mode_Modules_are_automatically_in_strict_mode.code, + ts.Diagnostics.Identifier_expected_0_is_a_reserved_word_that_cannot_be_used_here.code, + ts.Diagnostics.constructor_is_a_reserved_word.code, + ts.Diagnostics.delete_cannot_be_called_on_an_identifier_in_strict_mode.code, + ts.Diagnostics.Code_contained_in_a_class_is_evaluated_in_JavaScript_s_strict_mode_which_does_not_allow_this_use_of_0_For_more_information_see_https_Colon_Slash_Slashdeveloper_mozilla_org_Slashen_US_Slashdocs_SlashWeb_SlashJavaScript_SlashReference_SlashStrict_mode.code, + ts.Diagnostics.Invalid_use_of_0_Modules_are_automatically_in_strict_mode.code, + ts.Diagnostics.Invalid_use_of_0_in_strict_mode.code, + ts.Diagnostics.A_label_is_not_allowed_here.code, + ts.Diagnostics.Octal_literals_are_not_allowed_in_strict_mode.code, + ts.Diagnostics.with_statements_are_not_allowed_in_strict_mode.code, // grammar errors - Diagnostics.A_break_statement_can_only_be_used_within_an_enclosing_iteration_or_switch_statement.code, - Diagnostics.A_break_statement_can_only_jump_to_a_label_of_an_enclosing_statement.code, - Diagnostics.A_class_declaration_without_the_default_modifier_must_have_a_name.code, - Diagnostics.A_class_member_cannot_have_the_0_keyword.code, - Diagnostics.A_comma_expression_is_not_allowed_in_a_computed_property_name.code, - Diagnostics.A_continue_statement_can_only_be_used_within_an_enclosing_iteration_statement.code, - Diagnostics.A_continue_statement_can_only_jump_to_a_label_of_an_enclosing_iteration_statement.code, - Diagnostics.A_continue_statement_can_only_jump_to_a_label_of_an_enclosing_iteration_statement.code, - Diagnostics.A_default_clause_cannot_appear_more_than_once_in_a_switch_statement.code, - Diagnostics.A_default_export_must_be_at_the_top_level_of_a_file_or_module_declaration.code, - Diagnostics.A_definite_assignment_assertion_is_not_permitted_in_this_context.code, - Diagnostics.A_destructuring_declaration_must_have_an_initializer.code, - Diagnostics.A_get_accessor_cannot_have_parameters.code, - Diagnostics.A_rest_element_cannot_contain_a_binding_pattern.code, - Diagnostics.A_rest_element_cannot_have_a_property_name.code, - Diagnostics.A_rest_element_cannot_have_an_initializer.code, - Diagnostics.A_rest_element_must_be_last_in_a_destructuring_pattern.code, - Diagnostics.A_rest_parameter_cannot_have_an_initializer.code, - Diagnostics.A_rest_parameter_must_be_last_in_a_parameter_list.code, - Diagnostics.A_rest_parameter_or_binding_pattern_may_not_have_a_trailing_comma.code, - Diagnostics.A_return_statement_cannot_be_used_inside_a_class_static_block.code, - Diagnostics.A_set_accessor_cannot_have_rest_parameter.code, - Diagnostics.A_set_accessor_must_have_exactly_one_parameter.code, - Diagnostics.An_export_declaration_can_only_be_used_at_the_top_level_of_a_module.code, - Diagnostics.An_export_declaration_cannot_have_modifiers.code, - Diagnostics.An_import_declaration_can_only_be_used_at_the_top_level_of_a_module.code, - Diagnostics.An_import_declaration_cannot_have_modifiers.code, - Diagnostics.An_object_member_cannot_be_declared_optional.code, - Diagnostics.Argument_of_dynamic_import_cannot_be_spread_element.code, - Diagnostics.Cannot_assign_to_private_method_0_Private_methods_are_not_writable.code, - Diagnostics.Cannot_redeclare_identifier_0_in_catch_clause.code, - Diagnostics.Catch_clause_variable_cannot_have_an_initializer.code, - Diagnostics.Class_decorators_can_t_be_used_with_static_private_identifier_Consider_removing_the_experimental_decorator.code, - Diagnostics.Classes_can_only_extend_a_single_class.code, - Diagnostics.Classes_may_not_have_a_field_named_constructor.code, - Diagnostics.Did_you_mean_to_use_a_Colon_An_can_only_follow_a_property_name_when_the_containing_object_literal_is_part_of_a_destructuring_pattern.code, - Diagnostics.Duplicate_label_0.code, - Diagnostics.Dynamic_imports_can_only_accept_a_module_specifier_and_an_optional_assertion_as_arguments.code, - Diagnostics.For_await_loops_cannot_be_used_inside_a_class_static_block.code, - Diagnostics.JSX_attributes_must_only_be_assigned_a_non_empty_expression.code, - Diagnostics.JSX_elements_cannot_have_multiple_attributes_with_the_same_name.code, - Diagnostics.JSX_expressions_may_not_use_the_comma_operator_Did_you_mean_to_write_an_array.code, - Diagnostics.JSX_property_access_expressions_cannot_include_JSX_namespace_names.code, - Diagnostics.Jump_target_cannot_cross_function_boundary.code, - Diagnostics.Line_terminator_not_permitted_before_arrow.code, - Diagnostics.Modifiers_cannot_appear_here.code, - Diagnostics.Only_a_single_variable_declaration_is_allowed_in_a_for_in_statement.code, - Diagnostics.Only_a_single_variable_declaration_is_allowed_in_a_for_of_statement.code, - Diagnostics.Private_identifiers_are_not_allowed_outside_class_bodies.code, - Diagnostics.Private_identifiers_are_only_allowed_in_class_bodies_and_may_only_be_used_as_part_of_a_class_member_declaration_property_access_or_on_the_left_hand_side_of_an_in_expression.code, - Diagnostics.Property_0_is_not_accessible_outside_class_1_because_it_has_a_private_identifier.code, - Diagnostics.Tagged_template_expressions_are_not_permitted_in_an_optional_chain.code, - Diagnostics.The_left_hand_side_of_a_for_of_statement_may_not_be_async.code, - Diagnostics.The_variable_declaration_of_a_for_in_statement_cannot_have_an_initializer.code, - Diagnostics.The_variable_declaration_of_a_for_of_statement_cannot_have_an_initializer.code, - Diagnostics.Trailing_comma_not_allowed.code, - Diagnostics.Variable_declaration_list_cannot_be_empty.code, - Diagnostics._0_and_1_operations_cannot_be_mixed_without_parentheses.code, - Diagnostics._0_expected.code, - Diagnostics._0_is_not_a_valid_meta_property_for_keyword_1_Did_you_mean_2.code, - Diagnostics._0_list_cannot_be_empty.code, - Diagnostics._0_modifier_already_seen.code, - Diagnostics._0_modifier_cannot_appear_on_a_constructor_declaration.code, - Diagnostics._0_modifier_cannot_appear_on_a_module_or_namespace_element.code, - Diagnostics._0_modifier_cannot_appear_on_a_parameter.code, - Diagnostics._0_modifier_cannot_appear_on_class_elements_of_this_kind.code, - Diagnostics._0_modifier_cannot_be_used_here.code, - Diagnostics._0_modifier_must_precede_1_modifier.code, - Diagnostics.const_declarations_can_only_be_declared_inside_a_block.code, - Diagnostics.const_declarations_must_be_initialized.code, - Diagnostics.extends_clause_already_seen.code, - Diagnostics.let_declarations_can_only_be_declared_inside_a_block.code, - Diagnostics.let_is_not_allowed_to_be_used_as_a_name_in_let_or_const_declarations.code, + ts.Diagnostics.A_break_statement_can_only_be_used_within_an_enclosing_iteration_or_switch_statement.code, + ts.Diagnostics.A_break_statement_can_only_jump_to_a_label_of_an_enclosing_statement.code, + ts.Diagnostics.A_class_declaration_without_the_default_modifier_must_have_a_name.code, + ts.Diagnostics.A_class_member_cannot_have_the_0_keyword.code, + ts.Diagnostics.A_comma_expression_is_not_allowed_in_a_computed_property_name.code, + ts.Diagnostics.A_continue_statement_can_only_be_used_within_an_enclosing_iteration_statement.code, + ts.Diagnostics.A_continue_statement_can_only_jump_to_a_label_of_an_enclosing_iteration_statement.code, + ts.Diagnostics.A_continue_statement_can_only_jump_to_a_label_of_an_enclosing_iteration_statement.code, + ts.Diagnostics.A_default_clause_cannot_appear_more_than_once_in_a_switch_statement.code, + ts.Diagnostics.A_default_export_must_be_at_the_top_level_of_a_file_or_module_declaration.code, + ts.Diagnostics.A_definite_assignment_assertion_is_not_permitted_in_this_context.code, + ts.Diagnostics.A_destructuring_declaration_must_have_an_initializer.code, + ts.Diagnostics.A_get_accessor_cannot_have_parameters.code, + ts.Diagnostics.A_rest_element_cannot_contain_a_binding_pattern.code, + ts.Diagnostics.A_rest_element_cannot_have_a_property_name.code, + ts.Diagnostics.A_rest_element_cannot_have_an_initializer.code, + ts.Diagnostics.A_rest_element_must_be_last_in_a_destructuring_pattern.code, + ts.Diagnostics.A_rest_parameter_cannot_have_an_initializer.code, + ts.Diagnostics.A_rest_parameter_must_be_last_in_a_parameter_list.code, + ts.Diagnostics.A_rest_parameter_or_binding_pattern_may_not_have_a_trailing_comma.code, + ts.Diagnostics.A_return_statement_cannot_be_used_inside_a_class_static_block.code, + ts.Diagnostics.A_set_accessor_cannot_have_rest_parameter.code, + ts.Diagnostics.A_set_accessor_must_have_exactly_one_parameter.code, + ts.Diagnostics.An_export_declaration_can_only_be_used_at_the_top_level_of_a_module.code, + ts.Diagnostics.An_export_declaration_cannot_have_modifiers.code, + ts.Diagnostics.An_import_declaration_can_only_be_used_at_the_top_level_of_a_module.code, + ts.Diagnostics.An_import_declaration_cannot_have_modifiers.code, + ts.Diagnostics.An_object_member_cannot_be_declared_optional.code, + ts.Diagnostics.Argument_of_dynamic_import_cannot_be_spread_element.code, + ts.Diagnostics.Cannot_assign_to_private_method_0_Private_methods_are_not_writable.code, + ts.Diagnostics.Cannot_redeclare_identifier_0_in_catch_clause.code, + ts.Diagnostics.Catch_clause_variable_cannot_have_an_initializer.code, + ts.Diagnostics.Class_decorators_can_t_be_used_with_static_private_identifier_Consider_removing_the_experimental_decorator.code, + ts.Diagnostics.Classes_can_only_extend_a_single_class.code, + ts.Diagnostics.Classes_may_not_have_a_field_named_constructor.code, + ts.Diagnostics.Did_you_mean_to_use_a_Colon_An_can_only_follow_a_property_name_when_the_containing_object_literal_is_part_of_a_destructuring_pattern.code, + ts.Diagnostics.Duplicate_label_0.code, + ts.Diagnostics.Dynamic_imports_can_only_accept_a_module_specifier_and_an_optional_assertion_as_arguments.code, + ts.Diagnostics.For_await_loops_cannot_be_used_inside_a_class_static_block.code, + ts.Diagnostics.JSX_attributes_must_only_be_assigned_a_non_empty_expression.code, + ts.Diagnostics.JSX_elements_cannot_have_multiple_attributes_with_the_same_name.code, + ts.Diagnostics.JSX_expressions_may_not_use_the_comma_operator_Did_you_mean_to_write_an_array.code, + ts.Diagnostics.JSX_property_access_expressions_cannot_include_JSX_namespace_names.code, + ts.Diagnostics.Jump_target_cannot_cross_function_boundary.code, + ts.Diagnostics.Line_terminator_not_permitted_before_arrow.code, + ts.Diagnostics.Modifiers_cannot_appear_here.code, + ts.Diagnostics.Only_a_single_variable_declaration_is_allowed_in_a_for_in_statement.code, + ts.Diagnostics.Only_a_single_variable_declaration_is_allowed_in_a_for_of_statement.code, + ts.Diagnostics.Private_identifiers_are_not_allowed_outside_class_bodies.code, + ts.Diagnostics.Private_identifiers_are_only_allowed_in_class_bodies_and_may_only_be_used_as_part_of_a_class_member_declaration_property_access_or_on_the_left_hand_side_of_an_in_expression.code, + ts.Diagnostics.Property_0_is_not_accessible_outside_class_1_because_it_has_a_private_identifier.code, + ts.Diagnostics.Tagged_template_expressions_are_not_permitted_in_an_optional_chain.code, + ts.Diagnostics.The_left_hand_side_of_a_for_of_statement_may_not_be_async.code, + ts.Diagnostics.The_variable_declaration_of_a_for_in_statement_cannot_have_an_initializer.code, + ts.Diagnostics.The_variable_declaration_of_a_for_of_statement_cannot_have_an_initializer.code, + ts.Diagnostics.Trailing_comma_not_allowed.code, + ts.Diagnostics.Variable_declaration_list_cannot_be_empty.code, + ts.Diagnostics._0_and_1_operations_cannot_be_mixed_without_parentheses.code, + ts.Diagnostics._0_expected.code, + ts.Diagnostics._0_is_not_a_valid_meta_property_for_keyword_1_Did_you_mean_2.code, + ts.Diagnostics._0_list_cannot_be_empty.code, + ts.Diagnostics._0_modifier_already_seen.code, + ts.Diagnostics._0_modifier_cannot_appear_on_a_constructor_declaration.code, + ts.Diagnostics._0_modifier_cannot_appear_on_a_module_or_namespace_element.code, + ts.Diagnostics._0_modifier_cannot_appear_on_a_parameter.code, + ts.Diagnostics._0_modifier_cannot_appear_on_class_elements_of_this_kind.code, + ts.Diagnostics._0_modifier_cannot_be_used_here.code, + ts.Diagnostics._0_modifier_must_precede_1_modifier.code, + ts.Diagnostics.const_declarations_can_only_be_declared_inside_a_block.code, + ts.Diagnostics.const_declarations_must_be_initialized.code, + ts.Diagnostics.extends_clause_already_seen.code, + ts.Diagnostics.let_declarations_can_only_be_declared_inside_a_block.code, + ts.Diagnostics.let_is_not_allowed_to_be_used_as_a_name_in_let_or_const_declarations.code, ]); /** * Determine if source file needs to be re-created even if its text hasn't changed */ - function shouldProgramCreateNewSourceFiles(program: Program | undefined, newOptions: CompilerOptions): boolean { - if (!program) return false; + function shouldProgramCreateNewSourceFiles(program: ts.Program | undefined, newOptions: ts.CompilerOptions): boolean { + if (!program) + return false; // If any compiler options change, we can't reuse old source file even if version match // The change in options like these could result in change in syntax tree or `sourceFile.bindDiagnostics`. - return optionsHaveChanges(program.getCompilerOptions(), newOptions, sourceFileAffectingCompilerOptions); + return ts.optionsHaveChanges(program.getCompilerOptions(), newOptions, ts.sourceFileAffectingCompilerOptions); } - function createCreateProgramOptions(rootNames: readonly string[], options: CompilerOptions, host?: CompilerHost, oldProgram?: Program, configFileParsingDiagnostics?: readonly Diagnostic[]): CreateProgramOptions { + function createCreateProgramOptions(rootNames: readonly string[], options: ts.CompilerOptions, host?: ts.CompilerHost, oldProgram?: ts.Program, configFileParsingDiagnostics?: readonly ts.Diagnostic[]): ts.CreateProgramOptions { return { rootNames, options, @@ -998,7 +988,7 @@ namespace ts { * @param createProgramOptions - The options for creating a program. * @returns A 'Program' object. */ - export function createProgram(createProgramOptions: CreateProgramOptions): Program; + export function createProgram(createProgramOptions: ts.CreateProgramOptions): ts.Program; /** * Create a new 'Program' instance. A Program is an immutable collection of 'SourceFile's and a 'CompilerOptions' * that represent a compilation unit. @@ -1013,26 +1003,25 @@ namespace ts { * @param configFileParsingDiagnostics - error during config file parsing * @returns A 'Program' object. */ - export function createProgram(rootNames: readonly string[], options: CompilerOptions, host?: CompilerHost, oldProgram?: Program, configFileParsingDiagnostics?: readonly Diagnostic[]): Program; - export function createProgram(rootNamesOrOptions: readonly string[] | CreateProgramOptions, _options?: CompilerOptions, _host?: CompilerHost, _oldProgram?: Program, _configFileParsingDiagnostics?: readonly Diagnostic[]): Program { - const createProgramOptions = isArray(rootNamesOrOptions) ? createCreateProgramOptions(rootNamesOrOptions, _options!, _host, _oldProgram, _configFileParsingDiagnostics) : rootNamesOrOptions; // TODO: GH#18217 + export function createProgram(rootNames: readonly string[], options: ts.CompilerOptions, host?: ts.CompilerHost, oldProgram?: ts.Program, configFileParsingDiagnostics?: readonly ts.Diagnostic[]): ts.Program; + export function createProgram(rootNamesOrOptions: readonly string[] | ts.CreateProgramOptions, _options?: ts.CompilerOptions, _host?: ts.CompilerHost, _oldProgram?: ts.Program, _configFileParsingDiagnostics?: readonly ts.Diagnostic[]): ts.Program { + const createProgramOptions = ts.isArray(rootNamesOrOptions) ? createCreateProgramOptions(rootNamesOrOptions, _options!, _host, _oldProgram, _configFileParsingDiagnostics) : rootNamesOrOptions; // TODO: GH#18217 const { rootNames, options, configFileParsingDiagnostics, projectReferences } = createProgramOptions; let { oldProgram } = createProgramOptions; - let processingDefaultLibFiles: SourceFile[] | undefined; - let processingOtherFiles: SourceFile[] | undefined; - let files: SourceFile[]; - let symlinks: SymlinkCache | undefined; + let processingDefaultLibFiles: ts.SourceFile[] | undefined; + let processingOtherFiles: ts.SourceFile[] | undefined; + let files: ts.SourceFile[]; + let symlinks: ts.SymlinkCache | undefined; let commonSourceDirectory: string; - let typeChecker: TypeChecker; - let classifiableNames: Set<__String>; - const ambientModuleNameToUnmodifiedFileName = new Map(); - let fileReasons = createMultiMap(); - const cachedBindAndCheckDiagnosticsForFile: DiagnosticCache = {}; - const cachedDeclarationDiagnosticsForFile: DiagnosticCache = {}; - - let resolvedTypeReferenceDirectives = createModeAwareCache(); - let fileProcessingDiagnostics: FilePreprocessingDiagnostics[] | undefined; + let typeChecker: ts.TypeChecker; + let classifiableNames: ts.Set; + const ambientModuleNameToUnmodifiedFileName = new ts.Map(); + let fileReasons = ts.createMultiMap(); + const cachedBindAndCheckDiagnosticsForFile: DiagnosticCache = {}; + const cachedDeclarationDiagnosticsForFile: DiagnosticCache = {}; + let resolvedTypeReferenceDirectives = ts.createModeAwareCache(); + let fileProcessingDiagnostics: ts.FilePreprocessingDiagnostics[] | undefined; // The below settings are to track if a .js file should be add to the program if loaded via searching under node_modules. // This works as imported modules are discovered recursively in a depth first manner, specifically: @@ -1046,77 +1035,67 @@ namespace ts { // If a module has some of its imports skipped due to being at the depth limit under node_modules, then track // this, as it may be imported at a shallower depth later, and then it will need its skipped imports processed. - const modulesWithElidedImports = new Map(); + const modulesWithElidedImports = new ts.Map(); // Track source files that are source files found by searching under node_modules, as these shouldn't be compiled. - const sourceFilesFoundSearchingNodeModules = new Map(); - - tracing?.push(tracing.Phase.Program, "createProgram", { configFilePath: options.configFilePath, rootDir: options.rootDir }, /*separateBeginAndEnd*/ true); - performance.mark("beforeProgram"); + const sourceFilesFoundSearchingNodeModules = new ts.Map(); + ts.tracing?.push(ts.tracing.Phase.Program, "createProgram", { configFilePath: options.configFilePath, rootDir: options.rootDir }, /*separateBeginAndEnd*/ true); + ts.performance.mark("beforeProgram"); const host = createProgramOptions.host || createCompilerHost(options); const configParsingHost = parseConfigHostFromCompilerHostLike(host); let skipDefaultLib = options.noLib; - const getDefaultLibraryFileName = memoize(() => host.getDefaultLibFileName(options)); - const defaultLibraryPath = host.getDefaultLibLocation ? host.getDefaultLibLocation() : getDirectoryPath(getDefaultLibraryFileName()); - const programDiagnostics = createDiagnosticCollection(); + const getDefaultLibraryFileName = ts.memoize(() => host.getDefaultLibFileName(options)); + const defaultLibraryPath = host.getDefaultLibLocation ? host.getDefaultLibLocation() : ts.getDirectoryPath(getDefaultLibraryFileName()); + const programDiagnostics = ts.createDiagnosticCollection(); const currentDirectory = host.getCurrentDirectory(); - const supportedExtensions = getSupportedExtensions(options); - const supportedExtensionsWithJsonIfResolveJsonModule = getSupportedExtensionsWithJsonIfResolveJsonModule(options, supportedExtensions); + const supportedExtensions = ts.getSupportedExtensions(options); + const supportedExtensionsWithJsonIfResolveJsonModule = ts.getSupportedExtensionsWithJsonIfResolveJsonModule(options, supportedExtensions); // Map storing if there is emit blocking diagnostics for given input - const hasEmitBlockingDiagnostics = new Map(); - let _compilerOptionsObjectLiteralSyntax: ObjectLiteralExpression | false | undefined; - - let moduleResolutionCache: ModuleResolutionCache | undefined; - let typeReferenceDirectiveResolutionCache: TypeReferenceDirectiveResolutionCache | undefined; - let actualResolveModuleNamesWorker: (moduleNames: string[], containingFile: SourceFile, containingFileName: string, reusedNames?: string[], redirectedReference?: ResolvedProjectReference) => ResolvedModuleFull[]; - const hasInvalidatedResolution = host.hasInvalidatedResolution || returnFalse; + const hasEmitBlockingDiagnostics = new ts.Map(); + let _compilerOptionsObjectLiteralSyntax: ts.ObjectLiteralExpression | false | undefined; + let moduleResolutionCache: ts.ModuleResolutionCache | undefined; + let typeReferenceDirectiveResolutionCache: ts.TypeReferenceDirectiveResolutionCache | undefined; + let actualResolveModuleNamesWorker: (moduleNames: string[], containingFile: ts.SourceFile, containingFileName: string, reusedNames?: string[], redirectedReference?: ts.ResolvedProjectReference) => ts.ResolvedModuleFull[]; + const hasInvalidatedResolution = host.hasInvalidatedResolution || ts.returnFalse; if (host.resolveModuleNames) { - actualResolveModuleNamesWorker = (moduleNames, containingFile, containingFileName, reusedNames, redirectedReference) => host.resolveModuleNames!(Debug.checkEachDefined(moduleNames), containingFileName, reusedNames, redirectedReference, options, containingFile).map(resolved => { + actualResolveModuleNamesWorker = (moduleNames, containingFile, containingFileName, reusedNames, redirectedReference) => host.resolveModuleNames!(ts.Debug.checkEachDefined(moduleNames), containingFileName, reusedNames, redirectedReference, options, containingFile).map(resolved => { // An older host may have omitted extension, in which case we should infer it from the file extension of resolvedFileName. - if (!resolved || (resolved as ResolvedModuleFull).extension !== undefined) { - return resolved as ResolvedModuleFull; + if (!resolved || (resolved as ts.ResolvedModuleFull).extension !== undefined) { + return resolved as ts.ResolvedModuleFull; } - const withExtension = clone(resolved) as ResolvedModuleFull; - withExtension.extension = extensionFromPath(resolved.resolvedFileName); + const withExtension = ts.clone(resolved) as ts.ResolvedModuleFull; + withExtension.extension = ts.extensionFromPath(resolved.resolvedFileName); return withExtension; }); moduleResolutionCache = host.getModuleResolutionCache?.(); } else { - moduleResolutionCache = createModuleResolutionCache(currentDirectory, getCanonicalFileName, options); - const loader = (moduleName: string, resolverMode: ModuleKind.CommonJS | ModuleKind.ESNext | undefined, containingFileName: string, redirectedReference: ResolvedProjectReference | undefined) => resolveModuleName(moduleName, containingFileName, options, host, moduleResolutionCache, redirectedReference, resolverMode).resolvedModule!; // TODO: GH#18217 - actualResolveModuleNamesWorker = (moduleNames, containingFile, containingFileName, _reusedNames, redirectedReference) => loadWithModeAwareCache(Debug.checkEachDefined(moduleNames), containingFile, containingFileName, redirectedReference, loader); + moduleResolutionCache = ts.createModuleResolutionCache(currentDirectory, getCanonicalFileName, options); + const loader = (moduleName: string, resolverMode: ts.ModuleKind.CommonJS | ts.ModuleKind.ESNext | undefined, containingFileName: string, redirectedReference: ts.ResolvedProjectReference | undefined) => ts.resolveModuleName(moduleName, containingFileName, options, host, moduleResolutionCache, redirectedReference, resolverMode).resolvedModule!; // TODO: GH#18217 + actualResolveModuleNamesWorker = (moduleNames, containingFile, containingFileName, _reusedNames, redirectedReference) => loadWithModeAwareCache(ts.Debug.checkEachDefined(moduleNames), containingFile, containingFileName, redirectedReference, loader); } - let actualResolveTypeReferenceDirectiveNamesWorker: (typeDirectiveNames: string[] | readonly FileReference[], containingFile: string, redirectedReference?: ResolvedProjectReference, containingFileMode?: SourceFile["impliedNodeFormat"] | undefined) => (ResolvedTypeReferenceDirective | undefined)[]; + let actualResolveTypeReferenceDirectiveNamesWorker: (typeDirectiveNames: string[] | readonly ts.FileReference[], containingFile: string, redirectedReference?: ts.ResolvedProjectReference, containingFileMode?: ts.SourceFile["impliedNodeFormat"] | undefined) => (ts.ResolvedTypeReferenceDirective | undefined)[]; if (host.resolveTypeReferenceDirectives) { - actualResolveTypeReferenceDirectiveNamesWorker = (typeDirectiveNames, containingFile, redirectedReference, containingFileMode) => host.resolveTypeReferenceDirectives!(Debug.checkEachDefined(typeDirectiveNames), containingFile, redirectedReference, options, containingFileMode); + actualResolveTypeReferenceDirectiveNamesWorker = (typeDirectiveNames, containingFile, redirectedReference, containingFileMode) => host.resolveTypeReferenceDirectives!(ts.Debug.checkEachDefined(typeDirectiveNames), containingFile, redirectedReference, options, containingFileMode); } else { - typeReferenceDirectiveResolutionCache = createTypeReferenceDirectiveResolutionCache(currentDirectory, getCanonicalFileName, /*options*/ undefined, moduleResolutionCache?.getPackageJsonInfoCache()); - const loader = (typesRef: string, containingFile: string, redirectedReference: ResolvedProjectReference | undefined, resolutionMode: SourceFile["impliedNodeFormat"] | undefined) => resolveTypeReferenceDirective( - typesRef, - containingFile, - options, - host, - redirectedReference, - typeReferenceDirectiveResolutionCache, - resolutionMode, - ).resolvedTypeReferenceDirective!; // TODO: GH#18217 - actualResolveTypeReferenceDirectiveNamesWorker = (typeReferenceDirectiveNames, containingFile, redirectedReference, containingFileMode) => loadWithTypeDirectiveCache(Debug.checkEachDefined(typeReferenceDirectiveNames), containingFile, redirectedReference, containingFileMode, loader); + typeReferenceDirectiveResolutionCache = ts.createTypeReferenceDirectiveResolutionCache(currentDirectory, getCanonicalFileName, /*options*/ undefined, moduleResolutionCache?.getPackageJsonInfoCache()); + const loader = (typesRef: string, containingFile: string, redirectedReference: ts.ResolvedProjectReference | undefined, resolutionMode: ts.SourceFile["impliedNodeFormat"] | undefined) => ts.resolveTypeReferenceDirective(typesRef, containingFile, options, host, redirectedReference, typeReferenceDirectiveResolutionCache, resolutionMode).resolvedTypeReferenceDirective!; // TODO: GH#18217 + actualResolveTypeReferenceDirectiveNamesWorker = (typeReferenceDirectiveNames, containingFile, redirectedReference, containingFileMode) => loadWithTypeDirectiveCache(ts.Debug.checkEachDefined(typeReferenceDirectiveNames), containingFile, redirectedReference, containingFileMode, loader); } // Map from a stringified PackageId to the source file with that id. // Only one source file may have a given packageId. Others become redirects (see createRedirectSourceFile). // `packageIdToSourceFile` is only used while building the program, while `sourceFileToPackageName` and `isSourceFileTargetOfRedirect` are kept around. - const packageIdToSourceFile = new Map(); + const packageIdToSourceFile = new ts.Map(); // Maps from a SourceFile's `.path` to the name of the package it was imported with. - let sourceFileToPackageName = new Map(); + let sourceFileToPackageName = new ts.Map(); // Key is a file name. Value is the (non-empty, or undefined) list of files that redirect to it. - let redirectTargetsMap = createMultiMap(); + let redirectTargetsMap = ts.createMultiMap(); let usesUriStyleNodeCoreModules = false; /** @@ -1125,17 +1104,17 @@ namespace ts { * - false if sourceFile missing for source of project reference redirect * - undefined otherwise */ - const filesByName = new Map(); - let missingFilePaths: readonly Path[] | undefined; + const filesByName = new ts.Map(); + let missingFilePaths: readonly ts.Path[] | undefined; // stores 'filename -> file association' ignoring case // used to track cases when two file names differ only in casing - const filesByNameIgnoreCase = host.useCaseSensitiveFileNames() ? new Map() : undefined; + const filesByNameIgnoreCase = host.useCaseSensitiveFileNames() ? new ts.Map() : undefined; // A parallel array to projectReferences storing the results of reading in the referenced tsconfig files - let resolvedProjectReferences: readonly (ResolvedProjectReference | undefined)[] | undefined; - let projectReferenceRedirects: ESMap | undefined; - let mapFromFileToProjectReferenceRedirects: ESMap | undefined; - let mapFromToProjectReferenceRedirectSource: ESMap | undefined; + let resolvedProjectReferences: readonly (ts.ResolvedProjectReference | undefined)[] | undefined; + let projectReferenceRedirects: ts.ESMap | undefined; + let mapFromFileToProjectReferenceRedirects: ts.ESMap | undefined; + let mapFromToProjectReferenceRedirectSource: ts.ESMap | undefined; const useSourceOfProjectReferenceRedirect = !!host.useSourceOfProjectReferenceRedirect?.() && !options.disableSourceOfProjectReferenceRedirect; @@ -1150,16 +1129,16 @@ namespace ts { }); const readFile = host.readFile.bind(host) as typeof host.readFile; - tracing?.push(tracing.Phase.Program, "shouldProgramCreateNewSourceFiles", { hasOldProgram: !!oldProgram }); + ts.tracing?.push(ts.tracing.Phase.Program, "shouldProgramCreateNewSourceFiles", { hasOldProgram: !!oldProgram }); const shouldCreateNewSourceFile = shouldProgramCreateNewSourceFiles(oldProgram, options); - tracing?.pop(); + ts.tracing?.pop(); // We set `structuralIsReused` to `undefined` because `tryReuseStructureFromOldProgram` calls `tryReuseStructureFromOldProgram` which checks // `structuralIsReused`, which would be a TDZ violation if it was not set in advance to `undefined`. - let structureIsReused: StructureIsReused; - tracing?.push(tracing.Phase.Program, "tryReuseStructureFromOldProgram", {}); + let structureIsReused: ts.StructureIsReused; + ts.tracing?.push(ts.tracing.Phase.Program, "tryReuseStructureFromOldProgram", {}); structureIsReused = tryReuseStructureFromOldProgram(); // eslint-disable-line prefer-const - tracing?.pop(); - if (structureIsReused !== StructureIsReused.Completely) { + ts.tracing?.pop(); + if (structureIsReused !== ts.StructureIsReused.Completely) { processingDefaultLibFiles = []; processingOtherFiles = []; @@ -1169,24 +1148,25 @@ namespace ts { } if (rootNames.length) { resolvedProjectReferences?.forEach((parsedRef, index) => { - if (!parsedRef) return; - const out = outFile(parsedRef.commandLine.options); + if (!parsedRef) + return; + const out = ts.outFile(parsedRef.commandLine.options); if (useSourceOfProjectReferenceRedirect) { - if (out || getEmitModuleKind(parsedRef.commandLine.options) === ModuleKind.None) { + if (out || ts.getEmitModuleKind(parsedRef.commandLine.options) === ts.ModuleKind.None) { for (const fileName of parsedRef.commandLine.fileNames) { - processProjectReferenceFile(fileName, { kind: FileIncludeKind.SourceFromProjectReference, index }); + processProjectReferenceFile(fileName, { kind: ts.FileIncludeKind.SourceFromProjectReference, index }); } } } else { if (out) { - processProjectReferenceFile(changeExtension(out, ".d.ts"), { kind: FileIncludeKind.OutputFromProjectReference, index }); + processProjectReferenceFile(ts.changeExtension(out, ".d.ts"), { kind: ts.FileIncludeKind.OutputFromProjectReference, index }); } - else if (getEmitModuleKind(parsedRef.commandLine.options) === ModuleKind.None) { - const getCommonSourceDirectory = memoize(() => getCommonSourceDirectoryOfConfig(parsedRef.commandLine, !host.useCaseSensitiveFileNames())); + else if (ts.getEmitModuleKind(parsedRef.commandLine.options) === ts.ModuleKind.None) { + const getCommonSourceDirectory = ts.memoize(() => ts.getCommonSourceDirectoryOfConfig(parsedRef.commandLine, !host.useCaseSensitiveFileNames())); for (const fileName of parsedRef.commandLine.fileNames) { - if (!isDeclarationFileName(fileName) && !fileExtensionIs(fileName, Extension.Json)) { - processProjectReferenceFile(getOutputDeclarationFileName(fileName, parsedRef.commandLine, !host.useCaseSensitiveFileNames(), getCommonSourceDirectory), { kind: FileIncludeKind.OutputFromProjectReference, index }); + if (!ts.isDeclarationFileName(fileName) && !ts.fileExtensionIs(fileName, ts.Extension.Json)) { + processProjectReferenceFile(ts.getOutputDeclarationFileName(fileName, parsedRef.commandLine, !host.useCaseSensitiveFileNames(), getCommonSourceDirectory), { kind: ts.FileIncludeKind.OutputFromProjectReference, index }); } } } @@ -1195,24 +1175,24 @@ namespace ts { } } - tracing?.push(tracing.Phase.Program, "processRootFiles", { count: rootNames.length }); - forEach(rootNames, (name, index) => processRootFile(name, /*isDefaultLib*/ false, /*ignoreNoDefaultLib*/ false, { kind: FileIncludeKind.RootFile, index })); - tracing?.pop(); + ts.tracing?.push(ts.tracing.Phase.Program, "processRootFiles", { count: rootNames.length }); + ts.forEach(rootNames, (name, index) => processRootFile(name, /*isDefaultLib*/ false, /*ignoreNoDefaultLib*/ false, { kind: ts.FileIncludeKind.RootFile, index })); + ts.tracing?.pop(); // load type declarations specified via 'types' argument or implicitly from types/ and node_modules/@types folders - const typeReferences: string[] = rootNames.length ? getAutomaticTypeDirectiveNames(options, host) : emptyArray; + const typeReferences: string[] = rootNames.length ? ts.getAutomaticTypeDirectiveNames(options, host) : ts.emptyArray; if (typeReferences.length) { - tracing?.push(tracing.Phase.Program, "processTypeReferences", { count: typeReferences.length }); + ts.tracing?.push(ts.tracing.Phase.Program, "processTypeReferences", { count: typeReferences.length }); // This containingFilename needs to match with the one used in managed-side - const containingDirectory = options.configFilePath ? getDirectoryPath(options.configFilePath) : host.getCurrentDirectory(); - const containingFilename = combinePaths(containingDirectory, inferredTypesContainingFile); + const containingDirectory = options.configFilePath ? ts.getDirectoryPath(options.configFilePath) : host.getCurrentDirectory(); + const containingFilename = ts.combinePaths(containingDirectory, inferredTypesContainingFile); const resolutions = resolveTypeReferenceDirectiveNamesWorker(typeReferences, containingFilename); for (let i = 0; i < typeReferences.length; i++) { // under node16/nodenext module resolution, load `types`/ata include names as cjs resolution results by passing an `undefined` mode - processTypeReferenceDirective(typeReferences[i], /*mode*/ undefined, resolutions[i], { kind: FileIncludeKind.AutomaticTypeDirectiveFile, typeReference: typeReferences[i], packageId: resolutions[i]?.packageId }); + processTypeReferenceDirective(typeReferences[i], /*mode*/ undefined, resolutions[i], { kind: ts.FileIncludeKind.AutomaticTypeDirectiveFile, typeReference: typeReferences[i], packageId: resolutions[i]?.packageId }); } - tracing?.pop(); + ts.tracing?.pop(); } // Do not process the default library if: @@ -1224,22 +1204,22 @@ namespace ts { // otherwise, using options specified in '--lib' instead of '--target' default library file const defaultLibraryFileName = getDefaultLibraryFileName(); if (!options.lib && defaultLibraryFileName) { - processRootFile(defaultLibraryFileName, /*isDefaultLib*/ true, /*ignoreNoDefaultLib*/ false, { kind: FileIncludeKind.LibFile }); + processRootFile(defaultLibraryFileName, /*isDefaultLib*/ true, /*ignoreNoDefaultLib*/ false, { kind: ts.FileIncludeKind.LibFile }); } else { - forEach(options.lib, (libFileName, index) => { - processRootFile(pathForLibFile(libFileName), /*isDefaultLib*/ true, /*ignoreNoDefaultLib*/ false, { kind: FileIncludeKind.LibFile, index }); + ts.forEach(options.lib, (libFileName, index) => { + processRootFile(pathForLibFile(libFileName), /*isDefaultLib*/ true, /*ignoreNoDefaultLib*/ false, { kind: ts.FileIncludeKind.LibFile, index }); }); } } - missingFilePaths = arrayFrom(mapDefinedIterator(filesByName.entries(), ([path, file]) => file === undefined ? path as Path : undefined)); - files = stableSort(processingDefaultLibFiles, compareDefaultLibFiles).concat(processingOtherFiles); + missingFilePaths = ts.arrayFrom(ts.mapDefinedIterator(filesByName.entries(), ([path, file]) => file === undefined ? path as ts.Path : undefined)); + files = ts.stableSort(processingDefaultLibFiles, compareDefaultLibFiles).concat(processingOtherFiles); processingDefaultLibFiles = undefined; processingOtherFiles = undefined; } - Debug.assert(!!missingFilePaths); + ts.Debug.assert(!!missingFilePaths); // Release any files we have acquired in the old program but are // not part of the new program. @@ -1264,30 +1244,26 @@ namespace ts { // Release commandlines that new program does not use if (oldProgram && host.onReleaseParsedCommandLine) { - forEachProjectReference( - oldProgram.getProjectReferences(), - oldProgram.getResolvedProjectReferences(), - (oldResolvedRef, parent, index) => { + forEachProjectReference(oldProgram.getProjectReferences(), oldProgram.getResolvedProjectReferences(), (oldResolvedRef, parent, index) => { const oldReference = parent?.commandLine.projectReferences![index] || oldProgram!.getProjectReferences()![index]; const oldRefPath = resolveProjectReferencePath(oldReference); if (!projectReferenceRedirects?.has(toPath(oldRefPath))) { host.onReleaseParsedCommandLine!(oldRefPath, oldResolvedRef, oldProgram!.getCompilerOptions()); } + }); } - ); - } typeReferenceDirectiveResolutionCache = undefined; // unconditionally set oldProgram to undefined to prevent it from being captured in closure oldProgram = undefined; - const program: Program = { + const program: ts.Program = { getRootFileNames: () => rootNames, getSourceFile, getSourceFileByPath, getSourceFiles: () => files, - getMissingFilePaths: () => missingFilePaths!, // TODO: GH#18217 + getMissingFilePaths: () => missingFilePaths!, getModuleResolutionCache: () => moduleResolutionCache, getFilesByNameMap: () => filesByName, getCompilerOptions: () => options, @@ -1347,35 +1323,37 @@ namespace ts { // Add file processingDiagnostics fileProcessingDiagnostics?.forEach(diagnostic => { switch (diagnostic.kind) { - case FilePreprocessingDiagnosticsKind.FilePreprocessingFileExplainingDiagnostic: - return programDiagnostics.add(createDiagnosticExplainingFile(diagnostic.file && getSourceFileByPath(diagnostic.file), diagnostic.fileProcessingReason, diagnostic.diagnostic, diagnostic.args || emptyArray)); - case FilePreprocessingDiagnosticsKind.FilePreprocessingReferencedDiagnostic: + case ts.FilePreprocessingDiagnosticsKind.FilePreprocessingFileExplainingDiagnostic: + return programDiagnostics.add(createDiagnosticExplainingFile(diagnostic.file && getSourceFileByPath(diagnostic.file), diagnostic.fileProcessingReason, diagnostic.diagnostic, diagnostic.args || ts.emptyArray)); + case ts.FilePreprocessingDiagnosticsKind.FilePreprocessingReferencedDiagnostic: const { file, pos, end } = getReferencedFileLocation(getSourceFileByPath, diagnostic.reason) as ReferenceFileLocation; - return programDiagnostics.add(createFileDiagnostic(file, Debug.checkDefined(pos), Debug.checkDefined(end) - pos, diagnostic.diagnostic, ...diagnostic.args || emptyArray)); + return programDiagnostics.add(ts.createFileDiagnostic(file, ts.Debug.checkDefined(pos), ts.Debug.checkDefined(end) - pos, diagnostic.diagnostic, ...diagnostic.args || ts.emptyArray)); default: - Debug.assertNever(diagnostic); + ts.Debug.assertNever(diagnostic); } }); verifyCompilerOptions(); - performance.mark("afterProgram"); - performance.measure("Program", "beforeProgram", "afterProgram"); - tracing?.pop(); + ts.performance.mark("afterProgram"); + ts.performance.measure("Program", "beforeProgram", "afterProgram"); + ts.tracing?.pop(); return program; - function addResolutionDiagnostics(list: Diagnostic[] | undefined) { - if (!list) return; + function addResolutionDiagnostics(list: ts.Diagnostic[] | undefined) { + if (!list) + return; for (const elem of list) { programDiagnostics.add(elem); } } - function pullDiagnosticsFromCache(names: string[] | readonly FileReference[], containingFile: SourceFile) { - if (!moduleResolutionCache) return; - const containingFileName = getNormalizedAbsolutePath(containingFile.originalFileName, currentDirectory); - const containingFileMode = !isString(containingFile) ? containingFile.impliedNodeFormat : undefined; - const containingDir = getDirectoryPath(containingFileName); + function pullDiagnosticsFromCache(names: string[] | readonly ts.FileReference[], containingFile: ts.SourceFile) { + if (!moduleResolutionCache) + return; + const containingFileName = ts.getNormalizedAbsolutePath(containingFile.originalFileName, currentDirectory); + const containingFileMode = !ts.isString(containingFile) ? containingFile.impliedNodeFormat : undefined; + const containingDir = ts.getDirectoryPath(containingFileName); const redirectedReference = getRedirectReferenceForResolution(containingFile); let i = 0; for (const n of names) { @@ -1388,103 +1366,108 @@ namespace ts { // This may totally change if/when the issue of output paths not mapping to input files is fixed in a broader context // When it is, how we extract diagnostics from the module name resolver will have the be refined - the current cache // APIs wrapping the underlying resolver make it almost impossible to smuggle the diagnostics out in a generalized way - if (isExternalModuleNameRelative(name)) continue; + if (ts.isExternalModuleNameRelative(name)) + continue; const diags = moduleResolutionCache.getOrCreateCacheForModuleName(name, mode, redirectedReference).get(containingDir)?.resolutionDiagnostics; addResolutionDiagnostics(diags); } } - function resolveModuleNamesWorker(moduleNames: string[], containingFile: SourceFile, reusedNames: string[] | undefined): readonly ResolvedModuleFull[] { - if (!moduleNames.length) return emptyArray; - const containingFileName = getNormalizedAbsolutePath(containingFile.originalFileName, currentDirectory); + function resolveModuleNamesWorker(moduleNames: string[], containingFile: ts.SourceFile, reusedNames: string[] | undefined): readonly ts.ResolvedModuleFull[] { + if (!moduleNames.length) + return ts.emptyArray; + const containingFileName = ts.getNormalizedAbsolutePath(containingFile.originalFileName, currentDirectory); const redirectedReference = getRedirectReferenceForResolution(containingFile); - tracing?.push(tracing.Phase.Program, "resolveModuleNamesWorker", { containingFileName }); - performance.mark("beforeResolveModule"); + ts.tracing?.push(ts.tracing.Phase.Program, "resolveModuleNamesWorker", { containingFileName }); + ts.performance.mark("beforeResolveModule"); const result = actualResolveModuleNamesWorker(moduleNames, containingFile, containingFileName, reusedNames, redirectedReference); - performance.mark("afterResolveModule"); - performance.measure("ResolveModule", "beforeResolveModule", "afterResolveModule"); - tracing?.pop(); + ts.performance.mark("afterResolveModule"); + ts.performance.measure("ResolveModule", "beforeResolveModule", "afterResolveModule"); + ts.tracing?.pop(); pullDiagnosticsFromCache(moduleNames, containingFile); return result; } - function resolveTypeReferenceDirectiveNamesWorker(typeDirectiveNames: string[] | readonly FileReference[], containingFile: string | SourceFile): readonly (ResolvedTypeReferenceDirective | undefined)[] { - if (!typeDirectiveNames.length) return []; - const containingFileName = !isString(containingFile) ? getNormalizedAbsolutePath(containingFile.originalFileName, currentDirectory) : containingFile; - const redirectedReference = !isString(containingFile) ? getRedirectReferenceForResolution(containingFile) : undefined; - const containingFileMode = !isString(containingFile) ? containingFile.impliedNodeFormat : undefined; - tracing?.push(tracing.Phase.Program, "resolveTypeReferenceDirectiveNamesWorker", { containingFileName }); - performance.mark("beforeResolveTypeReference"); + function resolveTypeReferenceDirectiveNamesWorker(typeDirectiveNames: string[] | readonly ts.FileReference[], containingFile: string | ts.SourceFile): readonly (ts.ResolvedTypeReferenceDirective | undefined)[] { + if (!typeDirectiveNames.length) + return []; + const containingFileName = !ts.isString(containingFile) ? ts.getNormalizedAbsolutePath(containingFile.originalFileName, currentDirectory) : containingFile; + const redirectedReference = !ts.isString(containingFile) ? getRedirectReferenceForResolution(containingFile) : undefined; + const containingFileMode = !ts.isString(containingFile) ? containingFile.impliedNodeFormat : undefined; + ts.tracing?.push(ts.tracing.Phase.Program, "resolveTypeReferenceDirectiveNamesWorker", { containingFileName }); + ts.performance.mark("beforeResolveTypeReference"); const result = actualResolveTypeReferenceDirectiveNamesWorker(typeDirectiveNames, containingFileName, redirectedReference, containingFileMode); - performance.mark("afterResolveTypeReference"); - performance.measure("ResolveTypeReference", "beforeResolveTypeReference", "afterResolveTypeReference"); - tracing?.pop(); + ts.performance.mark("afterResolveTypeReference"); + ts.performance.measure("ResolveTypeReference", "beforeResolveTypeReference", "afterResolveTypeReference"); + ts.tracing?.pop(); return result; } - function getRedirectReferenceForResolution(file: SourceFile) { + function getRedirectReferenceForResolution(file: ts.SourceFile) { const redirect = getResolvedProjectReferenceToRedirect(file.originalFileName); - if (redirect || !isDeclarationFileName(file.originalFileName)) return redirect; + if (redirect || !ts.isDeclarationFileName(file.originalFileName)) + return redirect; // The originalFileName could not be actual source file name if file found was d.ts from referecned project // So in this case try to look up if this is output from referenced project, if it is use the redirected project in that case const resultFromDts = getRedirectReferenceForResolutionFromSourceOfProject(file.path); - if (resultFromDts) return resultFromDts; + if (resultFromDts) + return resultFromDts; // If preserveSymlinks is true, module resolution wont jump the symlink // but the resolved real path may be the .d.ts from project reference // Note:: Currently we try the real path only if the // file is from node_modules to avoid having to run real path on all file paths - if (!host.realpath || !options.preserveSymlinks || !stringContains(file.originalFileName, nodeModulesPathPart)) return undefined; + if (!host.realpath || !options.preserveSymlinks || !ts.stringContains(file.originalFileName, ts.nodeModulesPathPart)) + return undefined; const realDeclarationPath = toPath(host.realpath(file.originalFileName)); return realDeclarationPath === file.path ? undefined : getRedirectReferenceForResolutionFromSourceOfProject(realDeclarationPath); } - function getRedirectReferenceForResolutionFromSourceOfProject(filePath: Path) { + function getRedirectReferenceForResolutionFromSourceOfProject(filePath: ts.Path) { const source = getSourceOfProjectReferenceRedirect(filePath); - if (isString(source)) return getResolvedProjectReferenceToRedirect(source); - if (!source) return undefined; + if (ts.isString(source)) + return getResolvedProjectReferenceToRedirect(source); + if (!source) + return undefined; // Output of .d.ts file so return resolved ref that matches the out file name return forEachResolvedProjectReference(resolvedRef => { - const out = outFile(resolvedRef.commandLine.options); - if (!out) return undefined; + const out = ts.outFile(resolvedRef.commandLine.options); + if (!out) + return undefined; return toPath(out) === filePath ? resolvedRef : undefined; }); } - function compareDefaultLibFiles(a: SourceFile, b: SourceFile) { - return compareValues(getDefaultLibFilePriority(a), getDefaultLibFilePriority(b)); + function compareDefaultLibFiles(a: ts.SourceFile, b: ts.SourceFile) { + return ts.compareValues(getDefaultLibFilePriority(a), getDefaultLibFilePriority(b)); } - function getDefaultLibFilePriority(a: SourceFile) { - if (containsPath(defaultLibraryPath, a.fileName, /*ignoreCase*/ false)) { - const basename = getBaseFileName(a.fileName); - if (basename === "lib.d.ts" || basename === "lib.es6.d.ts") return 0; - const name = removeSuffix(removePrefix(basename, "lib."), ".d.ts"); - const index = libs.indexOf(name); - if (index !== -1) return index + 1; + function getDefaultLibFilePriority(a: ts.SourceFile) { + if (ts.containsPath(defaultLibraryPath, a.fileName, /*ignoreCase*/ false)) { + const basename = ts.getBaseFileName(a.fileName); + if (basename === "lib.d.ts" || basename === "lib.es6.d.ts") + return 0; + const name = ts.removeSuffix(ts.removePrefix(basename, "lib."), ".d.ts"); + const index = ts.libs.indexOf(name); + if (index !== -1) + return index + 1; } - return libs.length + 2; + return ts.libs.length + 2; } - function getResolvedModuleWithFailedLookupLocationsFromCache(moduleName: string, containingFile: string, mode?: ModuleKind.CommonJS | ModuleKind.ESNext): ResolvedModuleWithFailedLookupLocations | undefined { - return moduleResolutionCache && resolveModuleNameFromCache(moduleName, containingFile, moduleResolutionCache, mode); + function getResolvedModuleWithFailedLookupLocationsFromCache(moduleName: string, containingFile: string, mode?: ts.ModuleKind.CommonJS | ts.ModuleKind.ESNext): ts.ResolvedModuleWithFailedLookupLocations | undefined { + return moduleResolutionCache && ts.resolveModuleNameFromCache(moduleName, containingFile, moduleResolutionCache, mode); } - function toPath(fileName: string): Path { + function toPath(fileName: string): ts.Path { return ts.toPath(fileName, currentDirectory, getCanonicalFileName); } function getCommonSourceDirectory() { if (commonSourceDirectory === undefined) { - const emittedFiles = filter(files, file => sourceFileMayBeEmitted(file, program)); - commonSourceDirectory = ts.getCommonSourceDirectory( - options, - () => mapDefined(emittedFiles, file => file.isDeclarationFile ? undefined : file.fileName), - currentDirectory, - getCanonicalFileName, - commonSourceDirectory => checkSourceFilesBelongToPath(emittedFiles, commonSourceDirectory) - ); + const emittedFiles = ts.filter(files, file => ts.sourceFileMayBeEmitted(file, program)); + commonSourceDirectory = ts.getCommonSourceDirectory(options, () => ts.mapDefined(emittedFiles, file => file.isDeclarationFile ? undefined : file.fileName), currentDirectory, getCanonicalFileName, commonSourceDirectory => checkSourceFilesBelongToPath(emittedFiles, commonSourceDirectory)); } return commonSourceDirectory; } @@ -1493,7 +1476,7 @@ namespace ts { if (!classifiableNames) { // Initialize a checker so that all our files are bound. getTypeChecker(); - classifiableNames = new Set(); + classifiableNames = new ts.Set(); for (const sourceFile of files) { sourceFile.classifiableNames?.forEach(value => classifiableNames.add(value)); @@ -1503,8 +1486,8 @@ namespace ts { return classifiableNames; } - function resolveModuleNamesReusingOldState(moduleNames: string[], file: SourceFile): readonly ResolvedModuleFull[] { - if (structureIsReused === StructureIsReused.Not && !file.ambientModuleNames.length) { + function resolveModuleNamesReusingOldState(moduleNames: string[], file: ts.SourceFile): readonly ts.ResolvedModuleFull[] { + if (structureIsReused === ts.StructureIsReused.Not && !file.ambientModuleNames.length) { // If the old program state does not permit reusing resolutions and `file` does not contain locally defined ambient modules, // the best we can do is fallback to the default logic. return resolveModuleNamesWorker(moduleNames, file, /*reusedNames*/ undefined); @@ -1520,7 +1503,7 @@ namespace ts { // which per above occurred during the current program creation. // Since we assume the filesystem does not change during program creation, // it is safe to reuse resolutions from the earlier call. - const result: ResolvedModuleFull[] = []; + const result: ts.ResolvedModuleFull[] = []; let i = 0; for (const moduleName of moduleNames) { const resolvedModule = file.resolvedModules.get(moduleName, getModeForResolutionAtIndex(file, i))!; @@ -1545,27 +1528,21 @@ namespace ts { * Needs to be reset to undefined before returning, * * ResolvedModuleFull instance: can be reused. */ - let result: ResolvedModuleFull[] | undefined; + let result: ts.ResolvedModuleFull[] | undefined; let reusedNames: string[] | undefined; /** A transient placeholder used to mark predicted resolution in the result list. */ - const predictedToResolveToAmbientModuleMarker: ResolvedModuleFull = {} as any; + const predictedToResolveToAmbientModuleMarker: ts.ResolvedModuleFull = {} as any; for (let i = 0; i < moduleNames.length; i++) { const moduleName = moduleNames[i]; // If the source file is unchanged and doesnt have invalidated resolution, reuse the module resolutions if (file === oldSourceFile && !hasInvalidatedResolution(oldSourceFile.path)) { - const oldResolvedModule = getResolvedModule(oldSourceFile, moduleName, getModeForResolutionAtIndex(oldSourceFile, i)); + const oldResolvedModule = ts.getResolvedModule(oldSourceFile, moduleName, getModeForResolutionAtIndex(oldSourceFile, i)); if (oldResolvedModule) { - if (isTraceEnabled(options, host)) { - trace(host, - oldResolvedModule.packageId ? - Diagnostics.Reusing_resolution_of_module_0_from_1_of_old_program_it_was_successfully_resolved_to_2_with_Package_ID_3 : - Diagnostics.Reusing_resolution_of_module_0_from_1_of_old_program_it_was_successfully_resolved_to_2, - moduleName, - getNormalizedAbsolutePath(file.originalFileName, currentDirectory), - oldResolvedModule.resolvedFileName, - oldResolvedModule.packageId && packageIdToString(oldResolvedModule.packageId) - ); + if (ts.isTraceEnabled(options, host)) { + ts.trace(host, oldResolvedModule.packageId ? + ts.Diagnostics.Reusing_resolution_of_module_0_from_1_of_old_program_it_was_successfully_resolved_to_2_with_Package_ID_3 : + ts.Diagnostics.Reusing_resolution_of_module_0_from_1_of_old_program_it_was_successfully_resolved_to_2, moduleName, ts.getNormalizedAbsolutePath(file.originalFileName, currentDirectory), oldResolvedModule.resolvedFileName, oldResolvedModule.packageId && ts.packageIdToString(oldResolvedModule.packageId)); } (result || (result = new Array(moduleNames.length)))[i] = oldResolvedModule; (reusedNames || (reusedNames = [])).push(moduleName); @@ -1577,10 +1554,10 @@ namespace ts { // - resolved to an ambient module in the old program whose declaration is in an unmodified file // (so the same module declaration will land in the new program) let resolvesToAmbientModuleInNonModifiedFile = false; - if (contains(file.ambientModuleNames, moduleName)) { + if (ts.contains(file.ambientModuleNames, moduleName)) { resolvesToAmbientModuleInNonModifiedFile = true; - if (isTraceEnabled(options, host)) { - trace(host, Diagnostics.Module_0_was_resolved_as_locally_declared_ambient_module_in_file_1, moduleName, getNormalizedAbsolutePath(file.originalFileName, currentDirectory)); + if (ts.isTraceEnabled(options, host)) { + ts.trace(host, ts.Diagnostics.Module_0_was_resolved_as_locally_declared_ambient_module_in_file_1, moduleName, ts.getNormalizedAbsolutePath(file.originalFileName, currentDirectory)); } } else { @@ -1598,12 +1575,12 @@ namespace ts { const resolutions = unknownModuleNames && unknownModuleNames.length ? resolveModuleNamesWorker(unknownModuleNames, file, reusedNames) - : emptyArray; + : ts.emptyArray; // Combine results of resolutions and predicted results if (!result) { // There were no unresolved/ambient resolutions. - Debug.assert(resolutions.length === moduleNames.length); + ts.Debug.assert(resolutions.length === moduleNames.length); return resolutions; } @@ -1621,15 +1598,16 @@ namespace ts { j++; } } - Debug.assert(j === resolutions.length); + ts.Debug.assert(j === resolutions.length); return result; // If we change our policy of rechecking failed lookups on each program create, // we should adjust the value returned here. function moduleNameResolvesToAmbientModuleInNonModifiedFile(moduleName: string, index: number): boolean { - if (index >= length(oldSourceFile?.imports) + length(oldSourceFile?.moduleAugmentations)) return false; // mode index out of bounds, don't reuse resolution - const resolutionToFile = getResolvedModule(oldSourceFile, moduleName, oldSourceFile && getModeForResolutionAtIndex(oldSourceFile, index)); + if (index >= ts.length(oldSourceFile?.imports) + ts.length(oldSourceFile?.moduleAugmentations)) + return false; // mode index out of bounds, don't reuse resolution + const resolutionToFile = ts.getResolvedModule(oldSourceFile, moduleName, oldSourceFile && getModeForResolutionAtIndex(oldSourceFile, index)); const resolvedFile = resolutionToFile && oldProgram!.getSourceFile(resolutionToFile.resolvedFileName); if (resolutionToFile && resolvedFile) { // In the old program, we resolved to an ambient module that was in the same @@ -1646,80 +1624,81 @@ namespace ts { return false; } - if (isTraceEnabled(options, host)) { - trace(host, Diagnostics.Module_0_was_resolved_as_ambient_module_declared_in_1_since_this_file_was_not_modified, moduleName, unmodifiedFile); + if (ts.isTraceEnabled(options, host)) { + ts.trace(host, ts.Diagnostics.Module_0_was_resolved_as_ambient_module_declared_in_1_since_this_file_was_not_modified, moduleName, unmodifiedFile); } return true; } } function canReuseProjectReferences(): boolean { - return !forEachProjectReference( - oldProgram!.getProjectReferences(), - oldProgram!.getResolvedProjectReferences(), - (oldResolvedRef, parent, index) => { + return !forEachProjectReference(oldProgram!.getProjectReferences(), oldProgram!.getResolvedProjectReferences(), (oldResolvedRef, parent, index) => { const newRef = (parent ? parent.commandLine.projectReferences : projectReferences)![index]; const newResolvedRef = parseProjectReferenceConfigFile(newRef); if (oldResolvedRef) { // Resolved project reference has gone missing or changed return !newResolvedRef || newResolvedRef.sourceFile !== oldResolvedRef.sourceFile || - !arrayIsEqualTo(oldResolvedRef.commandLine.fileNames, newResolvedRef.commandLine.fileNames); + !ts.arrayIsEqualTo(oldResolvedRef.commandLine.fileNames, newResolvedRef.commandLine.fileNames); } else { // A previously-unresolved reference may be resolved now return newResolvedRef !== undefined; } - }, - (oldProjectReferences, parent) => { + }, (oldProjectReferences, parent) => { // If array of references is changed, we cant resue old program const newReferences = parent ? getResolvedProjectReferenceByPath(parent.sourceFile.path)!.commandLine.projectReferences : projectReferences; - return !arrayIsEqualTo(oldProjectReferences, newReferences, projectReferenceIsEqualTo); - } - ); + return !ts.arrayIsEqualTo(oldProjectReferences, newReferences, ts.projectReferenceIsEqualTo); + }); } - function tryReuseStructureFromOldProgram(): StructureIsReused { + function tryReuseStructureFromOldProgram(): ts.StructureIsReused { if (!oldProgram) { - return StructureIsReused.Not; + return ts.StructureIsReused.Not; } // check properties that can affect structure of the program or module resolution strategy // if any of these properties has changed - structure cannot be reused const oldOptions = oldProgram.getCompilerOptions(); - if (changesAffectModuleResolution(oldOptions, options)) { - return StructureIsReused.Not; + if (ts.changesAffectModuleResolution(oldOptions, options)) { + return ts.StructureIsReused.Not; } // there is an old program, check if we can reuse its structure const oldRootNames = oldProgram.getRootFileNames(); - if (!arrayIsEqualTo(oldRootNames, rootNames)) { - return StructureIsReused.Not; + if (!ts.arrayIsEqualTo(oldRootNames, rootNames)) { + return ts.StructureIsReused.Not; } // Check if any referenced project tsconfig files are different if (!canReuseProjectReferences()) { - return StructureIsReused.Not; + return ts.StructureIsReused.Not; } if (projectReferences) { resolvedProjectReferences = projectReferences.map(parseProjectReferenceConfigFile); } // check if program source files has changed in the way that can affect structure of the program - const newSourceFiles: SourceFile[] = []; - const modifiedSourceFiles: { oldFile: SourceFile, newFile: SourceFile }[] = []; - structureIsReused = StructureIsReused.Completely; + const newSourceFiles: ts.SourceFile[] = []; + const modifiedSourceFiles: { + oldFile: ts.SourceFile; + newFile: ts.SourceFile; + }[] = []; + structureIsReused = ts.StructureIsReused.Completely; // If the missing file paths are now present, it can change the progam structure, // and hence cant reuse the structure. // This is same as how we dont reuse the structure if one of the file from old program is now missing if (oldProgram.getMissingFilePaths().some(missingFilePath => host.fileExists(missingFilePath))) { - return StructureIsReused.Not; + return ts.StructureIsReused.Not; } const oldSourceFiles = oldProgram.getSourceFiles(); - const enum SeenPackageName { Exists, Modified } - const seenPackageNames = new Map(); + const enum SeenPackageName { + Exists, + Modified + } + const seenPackageNames = new ts.Map(); for (const oldSourceFile of oldSourceFiles) { let newSourceFile = host.getSourceFileByPath @@ -1727,10 +1706,10 @@ namespace ts { : host.getSourceFile(oldSourceFile.fileName, getCreateSourceFileOptions(oldSourceFile.fileName, moduleResolutionCache, host, options), /*onError*/ undefined, shouldCreateNewSourceFile); // TODO: GH#18217 if (!newSourceFile) { - return StructureIsReused.Not; + return ts.StructureIsReused.Not; } - Debug.assert(!newSourceFile.redirectInfo, "Host should not return a redirect source file from `getSourceFile`"); + ts.Debug.assert(!newSourceFile.redirectInfo, "Host should not return a redirect source file from `getSourceFile`"); let fileChanged: boolean; if (oldSourceFile.redirectInfo) { @@ -1738,7 +1717,7 @@ namespace ts { // This lets us know if the unredirected file has changed. If it has we should break the redirect. if (newSourceFile !== oldSourceFile.redirectInfo.unredirected) { // Underlying file has changed. Might not redirect anymore. Must rebuild program. - return StructureIsReused.Not; + return ts.StructureIsReused.Not; } fileChanged = false; newSourceFile = oldSourceFile; // Use the redirect. @@ -1746,7 +1725,7 @@ namespace ts { else if (oldProgram.redirectTargetsMap.has(oldSourceFile.path)) { // If a redirected-to source file changes, the redirect may be broken. if (newSourceFile !== oldSourceFile) { - return StructureIsReused.Not; + return ts.StructureIsReused.Not; } fileChanged = false; } @@ -1767,7 +1746,7 @@ namespace ts { const prevKind = seenPackageNames.get(packageName); const newKind = fileChanged ? SeenPackageName.Modified : SeenPackageName.Exists; if ((prevKind !== undefined && newKind === SeenPackageName.Modified) || prevKind === SeenPackageName.Modified) { - return StructureIsReused.Not; + return ts.StructureIsReused.Not; } seenPackageNames.set(packageName, newKind); } @@ -1775,41 +1754,41 @@ namespace ts { if (fileChanged) { // The `newSourceFile` object was created for the new program. - if (!arrayIsEqualTo(oldSourceFile.libReferenceDirectives, newSourceFile.libReferenceDirectives, fileReferenceIsEqualTo)) { + if (!ts.arrayIsEqualTo(oldSourceFile.libReferenceDirectives, newSourceFile.libReferenceDirectives, fileReferenceIsEqualTo)) { // 'lib' references has changed. Matches behavior in changesAffectModuleResolution - structureIsReused = StructureIsReused.SafeModules; + structureIsReused = ts.StructureIsReused.SafeModules; } if (oldSourceFile.hasNoDefaultLib !== newSourceFile.hasNoDefaultLib) { // value of no-default-lib has changed // this will affect if default library is injected into the list of files - structureIsReused = StructureIsReused.SafeModules; + structureIsReused = ts.StructureIsReused.SafeModules; } // check tripleslash references - if (!arrayIsEqualTo(oldSourceFile.referencedFiles, newSourceFile.referencedFiles, fileReferenceIsEqualTo)) { + if (!ts.arrayIsEqualTo(oldSourceFile.referencedFiles, newSourceFile.referencedFiles, fileReferenceIsEqualTo)) { // tripleslash references has changed - structureIsReused = StructureIsReused.SafeModules; + structureIsReused = ts.StructureIsReused.SafeModules; } // check imports and module augmentations collectExternalModuleReferences(newSourceFile); - if (!arrayIsEqualTo(oldSourceFile.imports, newSourceFile.imports, moduleNameIsEqualTo)) { + if (!ts.arrayIsEqualTo(oldSourceFile.imports, newSourceFile.imports, moduleNameIsEqualTo)) { // imports has changed - structureIsReused = StructureIsReused.SafeModules; + structureIsReused = ts.StructureIsReused.SafeModules; } - if (!arrayIsEqualTo(oldSourceFile.moduleAugmentations, newSourceFile.moduleAugmentations, moduleNameIsEqualTo)) { + if (!ts.arrayIsEqualTo(oldSourceFile.moduleAugmentations, newSourceFile.moduleAugmentations, moduleNameIsEqualTo)) { // moduleAugmentations has changed - structureIsReused = StructureIsReused.SafeModules; + structureIsReused = ts.StructureIsReused.SafeModules; } - if ((oldSourceFile.flags & NodeFlags.PermanentlySetIncrementalFlags) !== (newSourceFile.flags & NodeFlags.PermanentlySetIncrementalFlags)) { + if ((oldSourceFile.flags & ts.NodeFlags.PermanentlySetIncrementalFlags) !== (newSourceFile.flags & ts.NodeFlags.PermanentlySetIncrementalFlags)) { // dynamicImport has changed - structureIsReused = StructureIsReused.SafeModules; + structureIsReused = ts.StructureIsReused.SafeModules; } - if (!arrayIsEqualTo(oldSourceFile.typeReferenceDirectives, newSourceFile.typeReferenceDirectives, fileReferenceIsEqualTo)) { + if (!ts.arrayIsEqualTo(oldSourceFile.typeReferenceDirectives, newSourceFile.typeReferenceDirectives, fileReferenceIsEqualTo)) { // 'types' references has changed - structureIsReused = StructureIsReused.SafeModules; + structureIsReused = ts.StructureIsReused.SafeModules; } // tentatively approve the file @@ -1817,7 +1796,7 @@ namespace ts { } else if (hasInvalidatedResolution(oldSourceFile.path)) { // 'module/types' references could have changed - structureIsReused = StructureIsReused.SafeModules; + structureIsReused = ts.StructureIsReused.SafeModules; // add file to the modified list so that we will resolve it later modifiedSourceFiles.push({ oldFile: oldSourceFile, newFile: newSourceFile }); @@ -1827,13 +1806,13 @@ namespace ts { newSourceFiles.push(newSourceFile); } - if (structureIsReused !== StructureIsReused.Completely) { + if (structureIsReused !== ts.StructureIsReused.Completely) { return structureIsReused; } const modifiedFiles = modifiedSourceFiles.map(f => f.oldFile); for (const oldFile of oldSourceFiles) { - if (!contains(modifiedFiles, oldFile)) { + if (!ts.contains(modifiedFiles, oldFile)) { for (const moduleName of oldFile.ambientModuleNames) { ambientModuleNameToUnmodifiedFileName.set(moduleName, oldFile.fileName); } @@ -1844,10 +1823,10 @@ namespace ts { const moduleNames = getModuleNames(newSourceFile); const resolutions = resolveModuleNamesReusingOldState(moduleNames, newSourceFile); // ensure that module resolution results are still correct - const resolutionsChanged = hasChangesInResolutions(moduleNames, resolutions, oldSourceFile.resolvedModules, oldSourceFile, moduleResolutionIsEqualTo); + const resolutionsChanged = ts.hasChangesInResolutions(moduleNames, resolutions, oldSourceFile.resolvedModules, oldSourceFile, ts.moduleResolutionIsEqualTo); if (resolutionsChanged) { - structureIsReused = StructureIsReused.SafeModules; - newSourceFile.resolvedModules = zipToModeAwareCache(newSourceFile, moduleNames, resolutions); + structureIsReused = ts.StructureIsReused.SafeModules; + newSourceFile.resolvedModules = ts.zipToModeAwareCache(newSourceFile, moduleNames, resolutions); } else { newSourceFile.resolvedModules = oldSourceFile.resolvedModules; @@ -1855,28 +1834,28 @@ namespace ts { const typesReferenceDirectives = newSourceFile.typeReferenceDirectives; const typeReferenceResolutions = resolveTypeReferenceDirectiveNamesWorker(typesReferenceDirectives, newSourceFile); // ensure that types resolutions are still correct - const typeReferenceResolutionsChanged = hasChangesInResolutions(typesReferenceDirectives, typeReferenceResolutions, oldSourceFile.resolvedTypeReferenceDirectiveNames, oldSourceFile, typeDirectiveIsEqualTo); + const typeReferenceResolutionsChanged = ts.hasChangesInResolutions(typesReferenceDirectives, typeReferenceResolutions, oldSourceFile.resolvedTypeReferenceDirectiveNames, oldSourceFile, ts.typeDirectiveIsEqualTo); if (typeReferenceResolutionsChanged) { - structureIsReused = StructureIsReused.SafeModules; - newSourceFile.resolvedTypeReferenceDirectiveNames = zipToModeAwareCache(newSourceFile, typesReferenceDirectives, typeReferenceResolutions); + structureIsReused = ts.StructureIsReused.SafeModules; + newSourceFile.resolvedTypeReferenceDirectiveNames = ts.zipToModeAwareCache(newSourceFile, typesReferenceDirectives, typeReferenceResolutions); } else { newSourceFile.resolvedTypeReferenceDirectiveNames = oldSourceFile.resolvedTypeReferenceDirectiveNames; } } - if (structureIsReused !== StructureIsReused.Completely) { + if (structureIsReused !== ts.StructureIsReused.Completely) { return structureIsReused; } - if (changesAffectingProgramStructure(oldOptions, options) || host.hasChangedAutomaticTypeDirectiveNames?.()) { - return StructureIsReused.SafeModules; + if (ts.changesAffectingProgramStructure(oldOptions, options) || host.hasChangedAutomaticTypeDirectiveNames?.()) { + return ts.StructureIsReused.SafeModules; } missingFilePaths = oldProgram.getMissingFilePaths(); // update fileName -> file mapping - Debug.assert(newSourceFiles.length === oldProgram.getSourceFiles().length); + ts.Debug.assert(newSourceFiles.length === oldProgram.getSourceFiles().length); for (const newSourceFile of newSourceFiles) { filesByName.set(newSourceFile.path, newSourceFile); } @@ -1905,10 +1884,10 @@ namespace ts { redirectTargetsMap = oldProgram.redirectTargetsMap; usesUriStyleNodeCoreModules = oldProgram.usesUriStyleNodeCoreModules; - return StructureIsReused.Completely; + return ts.StructureIsReused.Completely; } - function getEmitHost(writeFileCallback?: WriteFileCallback): EmitHost { + function getEmitHost(writeFileCallback?: ts.WriteFileCallback): ts.EmitHost { return { getPrependNodes, getCanonicalFileName, @@ -1931,8 +1910,10 @@ namespace ts { fileExists: f => { // Use local caches const path = toPath(f); - if (getSourceFileByPath(path)) return true; - if (contains(missingFilePaths, path)) return false; + if (getSourceFileByPath(path)) + return true; + if (ts.contains(missingFilePaths, path)) + return false; // Before falling back to the host return host.fileExists(f); }, @@ -1944,33 +1925,21 @@ namespace ts { }; } - function writeFile( - fileName: string, - text: string, - writeByteOrderMark: boolean, - onError?: (message: string) => void, - sourceFiles?: readonly SourceFile[], - data?: WriteFileCallbackData - ) { + function writeFile(fileName: string, text: string, writeByteOrderMark: boolean, onError?: (message: string) => void, sourceFiles?: readonly ts.SourceFile[], data?: ts.WriteFileCallbackData) { host.writeFile(fileName, text, writeByteOrderMark, onError, sourceFiles, data); } - function emitBuildInfo(writeFileCallback?: WriteFileCallback): EmitResult { - Debug.assert(!outFile(options)); - tracing?.push(tracing.Phase.Emit, "emitBuildInfo", {}, /*separateBeginAndEnd*/ true); - performance.mark("beforeEmit"); - const emitResult = emitFiles( - notImplementedResolver, - getEmitHost(writeFileCallback), - /*targetSourceFile*/ undefined, - /*transformers*/ noTransformers, + function emitBuildInfo(writeFileCallback?: ts.WriteFileCallback): ts.EmitResult { + ts.Debug.assert(!ts.outFile(options)); + ts.tracing?.push(ts.tracing.Phase.Emit, "emitBuildInfo", {}, /*separateBeginAndEnd*/ true); + ts.performance.mark("beforeEmit"); + const emitResult = ts.emitFiles(ts.notImplementedResolver, getEmitHost(writeFileCallback), + /*targetSourceFile*/ undefined, ts.noTransformers, /*emitOnlyDtsFiles*/ false, - /*onlyBuildInfo*/ true - ); - - performance.mark("afterEmit"); - performance.measure("Emit", "beforeEmit", "afterEmit"); - tracing?.pop(); + /*onlyBuildInfo*/ true); + ts.performance.mark("afterEmit"); + ts.performance.measure("Emit", "beforeEmit", "afterEmit"); + ts.tracing?.pop(); return emitResult; } @@ -1983,22 +1952,17 @@ namespace ts { } function getPrependNodes() { - return createPrependNodes( - projectReferences, - (_ref, index) => resolvedProjectReferences![index]?.commandLine, - fileName => { + return createPrependNodes(projectReferences, (_ref, index) => resolvedProjectReferences![index]?.commandLine, fileName => { const path = toPath(fileName); const sourceFile = getSourceFileByPath(path); return sourceFile ? sourceFile.text : filesByName.has(path) ? undefined : host.readFile(path); + }); } - ); - } - - function isSourceFileFromExternalLibrary(file: SourceFile): boolean { + function isSourceFileFromExternalLibrary(file: ts.SourceFile): boolean { return !!sourceFilesFoundSearchingNodeModules.get(file.path); } - function isSourceFileDefaultLibrary(file: SourceFile): boolean { + function isSourceFileDefaultLibrary(file: ts.SourceFile): boolean { if (!file.isDeclarationFile) { return false; } @@ -2013,23 +1977,23 @@ namespace ts { // If '--lib' is not specified, include default library file according to '--target' // otherwise, using options specified in '--lib' instead of '--target' default library file - const equalityComparer = host.useCaseSensitiveFileNames() ? equateStringsCaseSensitive : equateStringsCaseInsensitive; + const equalityComparer = host.useCaseSensitiveFileNames() ? ts.equateStringsCaseSensitive : ts.equateStringsCaseInsensitive; if (!options.lib) { return equalityComparer(file.fileName, getDefaultLibraryFileName()); } else { - return some(options.lib, libFileName => equalityComparer(file.fileName, pathForLibFile(libFileName))); + return ts.some(options.lib, libFileName => equalityComparer(file.fileName, pathForLibFile(libFileName))); } } function getTypeChecker() { - return typeChecker || (typeChecker = createTypeChecker(program)); + return typeChecker || (typeChecker = ts.createTypeChecker(program)); } - function emit(sourceFile?: SourceFile, writeFileCallback?: WriteFileCallback, cancellationToken?: CancellationToken, emitOnlyDtsFiles?: boolean, transformers?: CustomTransformers, forceDtsEmit?: boolean): EmitResult { - tracing?.push(tracing.Phase.Emit, "emit", { path: sourceFile?.path }, /*separateBeginAndEnd*/ true); + function emit(sourceFile?: ts.SourceFile, writeFileCallback?: ts.WriteFileCallback, cancellationToken?: ts.CancellationToken, emitOnlyDtsFiles?: boolean, transformers?: ts.CustomTransformers, forceDtsEmit?: boolean): ts.EmitResult { + ts.tracing?.push(ts.tracing.Phase.Emit, "emit", { path: sourceFile?.path }, /*separateBeginAndEnd*/ true); const result = runWithCancellationToken(() => emitWorker(program, sourceFile, writeFileCallback, cancellationToken, emitOnlyDtsFiles, transformers, forceDtsEmit)); - tracing?.pop(); + ts.tracing?.pop(); return result; } @@ -2037,10 +2001,11 @@ namespace ts { return hasEmitBlockingDiagnostics.has(toPath(emitFileName)); } - function emitWorker(program: Program, sourceFile: SourceFile | undefined, writeFileCallback: WriteFileCallback | undefined, cancellationToken: CancellationToken | undefined, emitOnlyDtsFiles?: boolean, customTransformers?: CustomTransformers, forceDtsEmit?: boolean): EmitResult { + function emitWorker(program: ts.Program, sourceFile: ts.SourceFile | undefined, writeFileCallback: ts.WriteFileCallback | undefined, cancellationToken: ts.CancellationToken | undefined, emitOnlyDtsFiles?: boolean, customTransformers?: ts.CustomTransformers, forceDtsEmit?: boolean): ts.EmitResult { if (!forceDtsEmit) { const result = handleNoEmitOptions(program, sourceFile, writeFileCallback, cancellationToken); - if (result) return result; + if (result) + return result; } // Create the emit resolver outside of the "emitTime" tracking code below. That way @@ -2051,41 +2016,28 @@ namespace ts { // This is because in the -out scenario all files need to be emitted, and therefore all // files need to be type checked. And the way to specify that all files need to be type // checked is to not pass the file to getEmitResolver. - const emitResolver = getTypeChecker().getEmitResolver(outFile(options) ? undefined : sourceFile, cancellationToken); - - performance.mark("beforeEmit"); - - const emitResult = emitFiles( - emitResolver, - getEmitHost(writeFileCallback), - sourceFile, - getTransformers(options, customTransformers, emitOnlyDtsFiles), - emitOnlyDtsFiles, - /*onlyBuildInfo*/ false, - forceDtsEmit - ); - - performance.mark("afterEmit"); - performance.measure("Emit", "beforeEmit", "afterEmit"); + const emitResolver = getTypeChecker().getEmitResolver(ts.outFile(options) ? undefined : sourceFile, cancellationToken); + ts.performance.mark("beforeEmit"); + const emitResult = ts.emitFiles(emitResolver, getEmitHost(writeFileCallback), sourceFile, ts.getTransformers(options, customTransformers, emitOnlyDtsFiles), emitOnlyDtsFiles, + /*onlyBuildInfo*/ false, forceDtsEmit); + ts.performance.mark("afterEmit"); + ts.performance.measure("Emit", "beforeEmit", "afterEmit"); return emitResult; } - function getSourceFile(fileName: string): SourceFile | undefined { + function getSourceFile(fileName: string): ts.SourceFile | undefined { return getSourceFileByPath(toPath(fileName)); } - function getSourceFileByPath(path: Path): SourceFile | undefined { + function getSourceFileByPath(path: ts.Path): ts.SourceFile | undefined { return filesByName.get(path) || undefined; } - function getDiagnosticsHelper( - sourceFile: SourceFile | undefined, - getDiagnostics: (sourceFile: SourceFile, cancellationToken: CancellationToken | undefined) => readonly T[], - cancellationToken: CancellationToken | undefined): readonly T[] { + function getDiagnosticsHelper(sourceFile: ts.SourceFile | undefined, getDiagnostics: (sourceFile: ts.SourceFile, cancellationToken: ts.CancellationToken | undefined) => readonly T[], cancellationToken: ts.CancellationToken | undefined): readonly T[] { if (sourceFile) { return getDiagnostics(sourceFile, cancellationToken); } - return sortAndDeduplicateDiagnostics(flatMap(program.getSourceFiles(), sourceFile => { + return ts.sortAndDeduplicateDiagnostics(ts.flatMap(program.getSourceFiles(), sourceFile => { if (cancellationToken) { cancellationToken.throwIfCancellationRequested(); } @@ -2093,27 +2045,27 @@ namespace ts { })); } - function getSyntacticDiagnostics(sourceFile?: SourceFile, cancellationToken?: CancellationToken): readonly DiagnosticWithLocation[] { + function getSyntacticDiagnostics(sourceFile?: ts.SourceFile, cancellationToken?: ts.CancellationToken): readonly ts.DiagnosticWithLocation[] { return getDiagnosticsHelper(sourceFile, getSyntacticDiagnosticsForFile, cancellationToken); } - function getSemanticDiagnostics(sourceFile?: SourceFile, cancellationToken?: CancellationToken): readonly Diagnostic[] { + function getSemanticDiagnostics(sourceFile?: ts.SourceFile, cancellationToken?: ts.CancellationToken): readonly ts.Diagnostic[] { return getDiagnosticsHelper(sourceFile, getSemanticDiagnosticsForFile, cancellationToken); } - function getCachedSemanticDiagnostics(sourceFile?: SourceFile): readonly Diagnostic[] | undefined { + function getCachedSemanticDiagnostics(sourceFile?: ts.SourceFile): readonly ts.Diagnostic[] | undefined { return sourceFile ? cachedBindAndCheckDiagnosticsForFile.perFile?.get(sourceFile.path) : cachedBindAndCheckDiagnosticsForFile.allDiagnostics; } - function getBindAndCheckDiagnostics(sourceFile: SourceFile, cancellationToken?: CancellationToken): readonly Diagnostic[] { + function getBindAndCheckDiagnostics(sourceFile: ts.SourceFile, cancellationToken?: ts.CancellationToken): readonly ts.Diagnostic[] { return getBindAndCheckDiagnosticsForFile(sourceFile, cancellationToken); } - function getProgramDiagnostics(sourceFile: SourceFile): readonly Diagnostic[] { - if (skipTypeChecking(sourceFile, options, program)) { - return emptyArray; + function getProgramDiagnostics(sourceFile: ts.SourceFile): readonly ts.Diagnostic[] { + if (ts.skipTypeChecking(sourceFile, options, program)) { + return ts.emptyArray; } const programDiagnosticsInFile = programDiagnostics.getDiagnostics(sourceFile.fileName); @@ -2124,10 +2076,10 @@ namespace ts { return getDiagnosticsWithPrecedingDirectives(sourceFile, sourceFile.commentDirectives, programDiagnosticsInFile).diagnostics; } - function getDeclarationDiagnostics(sourceFile?: SourceFile, cancellationToken?: CancellationToken): readonly DiagnosticWithLocation[] { + function getDeclarationDiagnostics(sourceFile?: ts.SourceFile, cancellationToken?: ts.CancellationToken): readonly ts.DiagnosticWithLocation[] { const options = program.getCompilerOptions(); // collect diagnostics from the program only once if either no source file was specified or out/outFile is set (bundled emit) - if (!sourceFile || outFile(options)) { + if (!sourceFile || ts.outFile(options)) { return getDeclarationDiagnosticsWorker(sourceFile, cancellationToken); } else { @@ -2135,14 +2087,14 @@ namespace ts { } } - function getSyntacticDiagnosticsForFile(sourceFile: SourceFile): readonly DiagnosticWithLocation[] { + function getSyntacticDiagnosticsForFile(sourceFile: ts.SourceFile): readonly ts.DiagnosticWithLocation[] { // For JavaScript files, we report semantic errors for using TypeScript-only // constructs from within a JavaScript file as syntactic errors. - if (isSourceFileJS(sourceFile)) { + if (ts.isSourceFileJS(sourceFile)) { if (!sourceFile.additionalSyntacticDiagnostics) { sourceFile.additionalSyntacticDiagnostics = getJSSyntacticDiagnosticsForFile(sourceFile); } - return concatenate(sourceFile.additionalSyntacticDiagnostics, sourceFile.parseDiagnostics); + return ts.concatenate(sourceFile.additionalSyntacticDiagnostics, sourceFile.parseDiagnostics); } return sourceFile.parseDiagnostics; } @@ -2152,7 +2104,7 @@ namespace ts { return func(); } catch (e) { - if (e instanceof OperationCanceledException) { + if (e instanceof ts.OperationCanceledException) { // We were canceled while performing the operation. Because our type checker // might be a bad state, we need to throw it away. typeChecker = undefined!; @@ -2162,51 +2114,47 @@ namespace ts { } } - function getSemanticDiagnosticsForFile(sourceFile: SourceFile, cancellationToken: CancellationToken | undefined): readonly Diagnostic[] { - return concatenate( - filterSemanticDiagnostics(getBindAndCheckDiagnosticsForFile(sourceFile, cancellationToken), options), - getProgramDiagnostics(sourceFile) - ); + function getSemanticDiagnosticsForFile(sourceFile: ts.SourceFile, cancellationToken: ts.CancellationToken | undefined): readonly ts.Diagnostic[] { + return ts.concatenate(filterSemanticDiagnostics(getBindAndCheckDiagnosticsForFile(sourceFile, cancellationToken), options), getProgramDiagnostics(sourceFile)); } - function getBindAndCheckDiagnosticsForFile(sourceFile: SourceFile, cancellationToken: CancellationToken | undefined): readonly Diagnostic[] { + function getBindAndCheckDiagnosticsForFile(sourceFile: ts.SourceFile, cancellationToken: ts.CancellationToken | undefined): readonly ts.Diagnostic[] { return getAndCacheDiagnostics(sourceFile, cancellationToken, cachedBindAndCheckDiagnosticsForFile, getBindAndCheckDiagnosticsForFileNoCache); } - function getBindAndCheckDiagnosticsForFileNoCache(sourceFile: SourceFile, cancellationToken: CancellationToken | undefined): readonly Diagnostic[] { + function getBindAndCheckDiagnosticsForFileNoCache(sourceFile: ts.SourceFile, cancellationToken: ts.CancellationToken | undefined): readonly ts.Diagnostic[] { return runWithCancellationToken(() => { - if (skipTypeChecking(sourceFile, options, program)) { - return emptyArray; + if (ts.skipTypeChecking(sourceFile, options, program)) { + return ts.emptyArray; } const typeChecker = getTypeChecker(); - Debug.assert(!!sourceFile.bindDiagnostics); - - const isJs = sourceFile.scriptKind === ScriptKind.JS || sourceFile.scriptKind === ScriptKind.JSX; - const isCheckJs = isJs && isCheckJsEnabledForFile(sourceFile, options); - const isPlainJs = isPlainJsFile(sourceFile, options.checkJs); + ts.Debug.assert(!!sourceFile.bindDiagnostics); + const isJs = sourceFile.scriptKind === ts.ScriptKind.JS || sourceFile.scriptKind === ts.ScriptKind.JSX; + const isCheckJs = isJs && ts.isCheckJsEnabledForFile(sourceFile, options); + const isPlainJs = ts.isPlainJsFile(sourceFile, options.checkJs); const isTsNoCheck = !!sourceFile.checkJsDirective && sourceFile.checkJsDirective.enabled === false; // By default, only type-check .ts, .tsx, Deferred, plain JS, checked JS and External // - plain JS: .js files with no // ts-check and checkJs: undefined // - check JS: .js files with either // ts-check or checkJs: true // - external: files that are added by plugins - const includeBindAndCheckDiagnostics = !isTsNoCheck && (sourceFile.scriptKind === ScriptKind.TS || sourceFile.scriptKind === ScriptKind.TSX - || sourceFile.scriptKind === ScriptKind.External || isPlainJs || isCheckJs || sourceFile.scriptKind === ScriptKind.Deferred); - let bindDiagnostics: readonly Diagnostic[] = includeBindAndCheckDiagnostics ? sourceFile.bindDiagnostics : emptyArray; - let checkDiagnostics = includeBindAndCheckDiagnostics ? typeChecker.getDiagnostics(sourceFile, cancellationToken) : emptyArray; + const includeBindAndCheckDiagnostics = !isTsNoCheck && (sourceFile.scriptKind === ts.ScriptKind.TS || sourceFile.scriptKind === ts.ScriptKind.TSX + || sourceFile.scriptKind === ts.ScriptKind.External || isPlainJs || isCheckJs || sourceFile.scriptKind === ts.ScriptKind.Deferred); + let bindDiagnostics: readonly ts.Diagnostic[] = includeBindAndCheckDiagnostics ? sourceFile.bindDiagnostics : ts.emptyArray; + let checkDiagnostics = includeBindAndCheckDiagnostics ? typeChecker.getDiagnostics(sourceFile, cancellationToken) : ts.emptyArray; if (isPlainJs) { - bindDiagnostics = filter(bindDiagnostics, d => plainJSErrors.has(d.code)); - checkDiagnostics = filter(checkDiagnostics, d => plainJSErrors.has(d.code)); + bindDiagnostics = ts.filter(bindDiagnostics, d => plainJSErrors.has(d.code)); + checkDiagnostics = ts.filter(checkDiagnostics, d => plainJSErrors.has(d.code)); } // skip ts-expect-error errors in plain JS files, and skip JSDoc errors except in checked JS return getMergedBindAndCheckDiagnostics(sourceFile, includeBindAndCheckDiagnostics && !isPlainJs, bindDiagnostics, checkDiagnostics, isCheckJs ? sourceFile.jsDocDiagnostics : undefined); }); } - function getMergedBindAndCheckDiagnostics(sourceFile: SourceFile, includeBindAndCheckDiagnostics: boolean, ...allDiagnostics: (readonly Diagnostic[] | undefined)[]) { - const flatDiagnostics = flatten(allDiagnostics); + function getMergedBindAndCheckDiagnostics(sourceFile: ts.SourceFile, includeBindAndCheckDiagnostics: boolean, ...allDiagnostics: (readonly ts.Diagnostic[] | undefined)[]) { + const flatDiagnostics = ts.flatten(allDiagnostics); if (!includeBindAndCheckDiagnostics || !sourceFile.commentDirectives?.length) { return flatDiagnostics; } @@ -2214,7 +2162,7 @@ namespace ts { const { diagnostics, directives } = getDiagnosticsWithPrecedingDirectives(sourceFile, sourceFile.commentDirectives, flatDiagnostics); for (const errorExpectation of directives.getUnusedExpectations()) { - diagnostics.push(createDiagnosticForRange(sourceFile, errorExpectation.range, Diagnostics.Unused_ts_expect_error_directive)); + diagnostics.push(ts.createDiagnosticForRange(sourceFile, errorExpectation.range, ts.Diagnostics.Unused_ts_expect_error_directive)); } return diagnostics; @@ -2224,16 +2172,16 @@ namespace ts { * Creates a map of comment directives along with the diagnostics immediately preceded by one of them. * Comments that match to any of those diagnostics are marked as used. */ - function getDiagnosticsWithPrecedingDirectives(sourceFile: SourceFile, commentDirectives: CommentDirective[], flatDiagnostics: Diagnostic[]) { + function getDiagnosticsWithPrecedingDirectives(sourceFile: ts.SourceFile, commentDirectives: ts.CommentDirective[], flatDiagnostics: ts.Diagnostic[]) { // Diagnostics are only reported if there is no comment directive preceding them // This will modify the directives map by marking "used" ones with a corresponding diagnostic - const directives = createCommentDirectivesMap(sourceFile, commentDirectives); + const directives = ts.createCommentDirectivesMap(sourceFile, commentDirectives); const diagnostics = flatDiagnostics.filter(diagnostic => markPrecedingCommentDirectiveLine(diagnostic, directives) === -1); return { diagnostics, directives }; } - function getSuggestionDiagnostics(sourceFile: SourceFile, cancellationToken: CancellationToken): readonly DiagnosticWithLocation[] { + function getSuggestionDiagnostics(sourceFile: ts.SourceFile, cancellationToken: ts.CancellationToken): readonly ts.DiagnosticWithLocation[] { return runWithCancellationToken(() => { return getTypeChecker().getSuggestionDiagnostics(sourceFile, cancellationToken); }); @@ -2242,15 +2190,15 @@ namespace ts { /** * @returns The line index marked as preceding the diagnostic, or -1 if none was. */ - function markPrecedingCommentDirectiveLine(diagnostic: Diagnostic, directives: CommentDirectivesMap) { + function markPrecedingCommentDirectiveLine(diagnostic: ts.Diagnostic, directives: ts.CommentDirectivesMap) { const { file, start } = diagnostic; if (!file) { return -1; } // Start out with the line just before the text - const lineStarts = getLineStarts(file); - let line = computeLineAndCharacterOfPosition(lineStarts, start!).line - 1; // TODO: GH#18217 + const lineStarts = ts.getLineStarts(file); + let line = ts.computeLineAndCharacterOfPosition(lineStarts, start!).line - 1; // TODO: GH#18217 while (line >= 0) { // As soon as that line is known to have a comment directive, use that if (directives.markUsed(line)) { @@ -2269,228 +2217,223 @@ namespace ts { return -1; } - function getJSSyntacticDiagnosticsForFile(sourceFile: SourceFile): DiagnosticWithLocation[] { + function getJSSyntacticDiagnosticsForFile(sourceFile: ts.SourceFile): ts.DiagnosticWithLocation[] { return runWithCancellationToken(() => { - const diagnostics: DiagnosticWithLocation[] = []; + const diagnostics: ts.DiagnosticWithLocation[] = []; walk(sourceFile, sourceFile); - forEachChildRecursively(sourceFile, walk, walkArray); + ts.forEachChildRecursively(sourceFile, walk, walkArray); return diagnostics; - function walk(node: Node, parent: Node) { + function walk(node: ts.Node, parent: ts.Node) { // Return directly from the case if the given node doesnt want to visit each child // Otherwise break to visit each child switch (parent.kind) { - case SyntaxKind.Parameter: - case SyntaxKind.PropertyDeclaration: - case SyntaxKind.MethodDeclaration: - if ((parent as ParameterDeclaration | PropertyDeclaration | MethodDeclaration).questionToken === node) { - diagnostics.push(createDiagnosticForNode(node, Diagnostics.The_0_modifier_can_only_be_used_in_TypeScript_files, "?")); + case ts.SyntaxKind.Parameter: + case ts.SyntaxKind.PropertyDeclaration: + case ts.SyntaxKind.MethodDeclaration: + if ((parent as ts.ParameterDeclaration | ts.PropertyDeclaration | ts.MethodDeclaration).questionToken === node) { + diagnostics.push(createDiagnosticForNode(node, ts.Diagnostics.The_0_modifier_can_only_be_used_in_TypeScript_files, "?")); return "skip"; } // falls through - case SyntaxKind.MethodSignature: - case SyntaxKind.Constructor: - case SyntaxKind.GetAccessor: - case SyntaxKind.SetAccessor: - case SyntaxKind.FunctionExpression: - case SyntaxKind.FunctionDeclaration: - case SyntaxKind.ArrowFunction: - case SyntaxKind.VariableDeclaration: + case ts.SyntaxKind.MethodSignature: + case ts.SyntaxKind.Constructor: + case ts.SyntaxKind.GetAccessor: + case ts.SyntaxKind.SetAccessor: + case ts.SyntaxKind.FunctionExpression: + case ts.SyntaxKind.FunctionDeclaration: + case ts.SyntaxKind.ArrowFunction: + case ts.SyntaxKind.VariableDeclaration: // type annotation - if ((parent as FunctionLikeDeclaration | VariableDeclaration | ParameterDeclaration | PropertyDeclaration).type === node) { - diagnostics.push(createDiagnosticForNode(node, Diagnostics.Type_annotations_can_only_be_used_in_TypeScript_files)); + if ((parent as ts.FunctionLikeDeclaration | ts.VariableDeclaration | ts.ParameterDeclaration | ts.PropertyDeclaration).type === node) { + diagnostics.push(createDiagnosticForNode(node, ts.Diagnostics.Type_annotations_can_only_be_used_in_TypeScript_files)); return "skip"; } } switch (node.kind) { - case SyntaxKind.ImportClause: - if ((node as ImportClause).isTypeOnly) { - diagnostics.push(createDiagnosticForNode(parent, Diagnostics._0_declarations_can_only_be_used_in_TypeScript_files, "import type")); + case ts.SyntaxKind.ImportClause: + if ((node as ts.ImportClause).isTypeOnly) { + diagnostics.push(createDiagnosticForNode(parent, ts.Diagnostics._0_declarations_can_only_be_used_in_TypeScript_files, "import type")); return "skip"; } break; - case SyntaxKind.ExportDeclaration: - if ((node as ExportDeclaration).isTypeOnly) { - diagnostics.push(createDiagnosticForNode(node, Diagnostics._0_declarations_can_only_be_used_in_TypeScript_files, "export type")); + case ts.SyntaxKind.ExportDeclaration: + if ((node as ts.ExportDeclaration).isTypeOnly) { + diagnostics.push(createDiagnosticForNode(node, ts.Diagnostics._0_declarations_can_only_be_used_in_TypeScript_files, "export type")); return "skip"; } break; - case SyntaxKind.ImportSpecifier: - case SyntaxKind.ExportSpecifier: - if ((node as ImportOrExportSpecifier).isTypeOnly) { - diagnostics.push(createDiagnosticForNode(node, Diagnostics._0_declarations_can_only_be_used_in_TypeScript_files, isImportSpecifier(node) ? "import...type" : "export...type")); + case ts.SyntaxKind.ImportSpecifier: + case ts.SyntaxKind.ExportSpecifier: + if ((node as ts.ImportOrExportSpecifier).isTypeOnly) { + diagnostics.push(createDiagnosticForNode(node, ts.Diagnostics._0_declarations_can_only_be_used_in_TypeScript_files, ts.isImportSpecifier(node) ? "import...type" : "export...type")); return "skip"; } break; - case SyntaxKind.ImportEqualsDeclaration: - diagnostics.push(createDiagnosticForNode(node, Diagnostics.import_can_only_be_used_in_TypeScript_files)); + case ts.SyntaxKind.ImportEqualsDeclaration: + diagnostics.push(createDiagnosticForNode(node, ts.Diagnostics.import_can_only_be_used_in_TypeScript_files)); return "skip"; - case SyntaxKind.ExportAssignment: - if ((node as ExportAssignment).isExportEquals) { - diagnostics.push(createDiagnosticForNode(node, Diagnostics.export_can_only_be_used_in_TypeScript_files)); + case ts.SyntaxKind.ExportAssignment: + if ((node as ts.ExportAssignment).isExportEquals) { + diagnostics.push(createDiagnosticForNode(node, ts.Diagnostics.export_can_only_be_used_in_TypeScript_files)); return "skip"; } break; - case SyntaxKind.HeritageClause: - const heritageClause = node as HeritageClause; - if (heritageClause.token === SyntaxKind.ImplementsKeyword) { - diagnostics.push(createDiagnosticForNode(node, Diagnostics.implements_clauses_can_only_be_used_in_TypeScript_files)); + case ts.SyntaxKind.HeritageClause: + const heritageClause = node as ts.HeritageClause; + if (heritageClause.token === ts.SyntaxKind.ImplementsKeyword) { + diagnostics.push(createDiagnosticForNode(node, ts.Diagnostics.implements_clauses_can_only_be_used_in_TypeScript_files)); return "skip"; } break; - case SyntaxKind.InterfaceDeclaration: - const interfaceKeyword = tokenToString(SyntaxKind.InterfaceKeyword); - Debug.assertIsDefined(interfaceKeyword); - diagnostics.push(createDiagnosticForNode(node, Diagnostics._0_declarations_can_only_be_used_in_TypeScript_files, interfaceKeyword)); + case ts.SyntaxKind.InterfaceDeclaration: + const interfaceKeyword = ts.tokenToString(ts.SyntaxKind.InterfaceKeyword); + ts.Debug.assertIsDefined(interfaceKeyword); + diagnostics.push(createDiagnosticForNode(node, ts.Diagnostics._0_declarations_can_only_be_used_in_TypeScript_files, interfaceKeyword)); return "skip"; - case SyntaxKind.ModuleDeclaration: - const moduleKeyword = node.flags & NodeFlags.Namespace ? tokenToString(SyntaxKind.NamespaceKeyword) : tokenToString(SyntaxKind.ModuleKeyword); - Debug.assertIsDefined(moduleKeyword); - diagnostics.push(createDiagnosticForNode(node, Diagnostics._0_declarations_can_only_be_used_in_TypeScript_files, moduleKeyword)); + case ts.SyntaxKind.ModuleDeclaration: + const moduleKeyword = node.flags & ts.NodeFlags.Namespace ? ts.tokenToString(ts.SyntaxKind.NamespaceKeyword) : ts.tokenToString(ts.SyntaxKind.ModuleKeyword); + ts.Debug.assertIsDefined(moduleKeyword); + diagnostics.push(createDiagnosticForNode(node, ts.Diagnostics._0_declarations_can_only_be_used_in_TypeScript_files, moduleKeyword)); return "skip"; - case SyntaxKind.TypeAliasDeclaration: - diagnostics.push(createDiagnosticForNode(node, Diagnostics.Type_aliases_can_only_be_used_in_TypeScript_files)); + case ts.SyntaxKind.TypeAliasDeclaration: + diagnostics.push(createDiagnosticForNode(node, ts.Diagnostics.Type_aliases_can_only_be_used_in_TypeScript_files)); return "skip"; - case SyntaxKind.EnumDeclaration: - const enumKeyword = Debug.checkDefined(tokenToString(SyntaxKind.EnumKeyword)); - diagnostics.push(createDiagnosticForNode(node, Diagnostics._0_declarations_can_only_be_used_in_TypeScript_files, enumKeyword)); + case ts.SyntaxKind.EnumDeclaration: + const enumKeyword = ts.Debug.checkDefined(ts.tokenToString(ts.SyntaxKind.EnumKeyword)); + diagnostics.push(createDiagnosticForNode(node, ts.Diagnostics._0_declarations_can_only_be_used_in_TypeScript_files, enumKeyword)); return "skip"; - case SyntaxKind.NonNullExpression: - diagnostics.push(createDiagnosticForNode(node, Diagnostics.Non_null_assertions_can_only_be_used_in_TypeScript_files)); + case ts.SyntaxKind.NonNullExpression: + diagnostics.push(createDiagnosticForNode(node, ts.Diagnostics.Non_null_assertions_can_only_be_used_in_TypeScript_files)); return "skip"; - case SyntaxKind.AsExpression: - diagnostics.push(createDiagnosticForNode((node as AsExpression).type, Diagnostics.Type_assertion_expressions_can_only_be_used_in_TypeScript_files)); + case ts.SyntaxKind.AsExpression: + diagnostics.push(createDiagnosticForNode((node as ts.AsExpression).type, ts.Diagnostics.Type_assertion_expressions_can_only_be_used_in_TypeScript_files)); return "skip"; - case SyntaxKind.TypeAssertionExpression: - Debug.fail(); // Won't parse these in a JS file anyway, as they are interpreted as JSX. + case ts.SyntaxKind.TypeAssertionExpression: + ts.Debug.fail(); // Won't parse these in a JS file anyway, as they are interpreted as JSX. } } - function walkArray(nodes: NodeArray, parent: Node) { + function walkArray(nodes: ts.NodeArray, parent: ts.Node) { if (parent.decorators === nodes && !options.experimentalDecorators) { - diagnostics.push(createDiagnosticForNode(parent, Diagnostics.Experimental_support_for_decorators_is_a_feature_that_is_subject_to_change_in_a_future_release_Set_the_experimentalDecorators_option_in_your_tsconfig_or_jsconfig_to_remove_this_warning)); + diagnostics.push(createDiagnosticForNode(parent, ts.Diagnostics.Experimental_support_for_decorators_is_a_feature_that_is_subject_to_change_in_a_future_release_Set_the_experimentalDecorators_option_in_your_tsconfig_or_jsconfig_to_remove_this_warning)); } switch (parent.kind) { - case SyntaxKind.ClassDeclaration: - case SyntaxKind.ClassExpression: - case SyntaxKind.MethodDeclaration: - case SyntaxKind.Constructor: - case SyntaxKind.GetAccessor: - case SyntaxKind.SetAccessor: - case SyntaxKind.FunctionExpression: - case SyntaxKind.FunctionDeclaration: - case SyntaxKind.ArrowFunction: + case ts.SyntaxKind.ClassDeclaration: + case ts.SyntaxKind.ClassExpression: + case ts.SyntaxKind.MethodDeclaration: + case ts.SyntaxKind.Constructor: + case ts.SyntaxKind.GetAccessor: + case ts.SyntaxKind.SetAccessor: + case ts.SyntaxKind.FunctionExpression: + case ts.SyntaxKind.FunctionDeclaration: + case ts.SyntaxKind.ArrowFunction: // Check type parameters - if (nodes === (parent as DeclarationWithTypeParameterChildren).typeParameters) { - diagnostics.push(createDiagnosticForNodeArray(nodes, Diagnostics.Type_parameter_declarations_can_only_be_used_in_TypeScript_files)); + if (nodes === (parent as ts.DeclarationWithTypeParameterChildren).typeParameters) { + diagnostics.push(createDiagnosticForNodeArray(nodes, ts.Diagnostics.Type_parameter_declarations_can_only_be_used_in_TypeScript_files)); return "skip"; } // falls through - case SyntaxKind.VariableStatement: + case ts.SyntaxKind.VariableStatement: // Check modifiers if (nodes === parent.modifiers) { - checkModifiers(parent.modifiers, parent.kind === SyntaxKind.VariableStatement); + checkModifiers(parent.modifiers, parent.kind === ts.SyntaxKind.VariableStatement); return "skip"; } break; - case SyntaxKind.PropertyDeclaration: + case ts.SyntaxKind.PropertyDeclaration: // Check modifiers of property declaration - if (nodes === (parent as PropertyDeclaration).modifiers) { - for (const modifier of nodes as NodeArray) { - if (modifier.kind !== SyntaxKind.StaticKeyword) { - diagnostics.push(createDiagnosticForNode(modifier, Diagnostics.The_0_modifier_can_only_be_used_in_TypeScript_files, tokenToString(modifier.kind))); + if (nodes === (parent as ts.PropertyDeclaration).modifiers) { + for (const modifier of nodes as ts.NodeArray) { + if (modifier.kind !== ts.SyntaxKind.StaticKeyword) { + diagnostics.push(createDiagnosticForNode(modifier, ts.Diagnostics.The_0_modifier_can_only_be_used_in_TypeScript_files, ts.tokenToString(modifier.kind))); } } return "skip"; } break; - case SyntaxKind.Parameter: + case ts.SyntaxKind.Parameter: // Check modifiers of parameter declaration - if (nodes === (parent as ParameterDeclaration).modifiers) { - diagnostics.push(createDiagnosticForNodeArray(nodes, Diagnostics.Parameter_modifiers_can_only_be_used_in_TypeScript_files)); + if (nodes === (parent as ts.ParameterDeclaration).modifiers) { + diagnostics.push(createDiagnosticForNodeArray(nodes, ts.Diagnostics.Parameter_modifiers_can_only_be_used_in_TypeScript_files)); return "skip"; } break; - case SyntaxKind.CallExpression: - case SyntaxKind.NewExpression: - case SyntaxKind.ExpressionWithTypeArguments: - case SyntaxKind.JsxSelfClosingElement: - case SyntaxKind.JsxOpeningElement: - case SyntaxKind.TaggedTemplateExpression: + case ts.SyntaxKind.CallExpression: + case ts.SyntaxKind.NewExpression: + case ts.SyntaxKind.ExpressionWithTypeArguments: + case ts.SyntaxKind.JsxSelfClosingElement: + case ts.SyntaxKind.JsxOpeningElement: + case ts.SyntaxKind.TaggedTemplateExpression: // Check type arguments - if (nodes === (parent as NodeWithTypeArguments).typeArguments) { - diagnostics.push(createDiagnosticForNodeArray(nodes, Diagnostics.Type_arguments_can_only_be_used_in_TypeScript_files)); + if (nodes === (parent as ts.NodeWithTypeArguments).typeArguments) { + diagnostics.push(createDiagnosticForNodeArray(nodes, ts.Diagnostics.Type_arguments_can_only_be_used_in_TypeScript_files)); return "skip"; } break; } } - function checkModifiers(modifiers: NodeArray, isConstValid: boolean) { + function checkModifiers(modifiers: ts.NodeArray, isConstValid: boolean) { for (const modifier of modifiers) { switch (modifier.kind) { - case SyntaxKind.ConstKeyword: + case ts.SyntaxKind.ConstKeyword: if (isConstValid) { continue; } // to report error, // falls through - case SyntaxKind.PublicKeyword: - case SyntaxKind.PrivateKeyword: - case SyntaxKind.ProtectedKeyword: - case SyntaxKind.ReadonlyKeyword: - case SyntaxKind.DeclareKeyword: - case SyntaxKind.AbstractKeyword: - case SyntaxKind.OverrideKeyword: - case SyntaxKind.InKeyword: - case SyntaxKind.OutKeyword: - diagnostics.push(createDiagnosticForNode(modifier, Diagnostics.The_0_modifier_can_only_be_used_in_TypeScript_files, tokenToString(modifier.kind))); + case ts.SyntaxKind.PublicKeyword: + case ts.SyntaxKind.PrivateKeyword: + case ts.SyntaxKind.ProtectedKeyword: + case ts.SyntaxKind.ReadonlyKeyword: + case ts.SyntaxKind.DeclareKeyword: + case ts.SyntaxKind.AbstractKeyword: + case ts.SyntaxKind.OverrideKeyword: + case ts.SyntaxKind.InKeyword: + case ts.SyntaxKind.OutKeyword: + diagnostics.push(createDiagnosticForNode(modifier, ts.Diagnostics.The_0_modifier_can_only_be_used_in_TypeScript_files, ts.tokenToString(modifier.kind))); break; // These are all legal modifiers. - case SyntaxKind.StaticKeyword: - case SyntaxKind.ExportKeyword: - case SyntaxKind.DefaultKeyword: + case ts.SyntaxKind.StaticKeyword: + case ts.SyntaxKind.ExportKeyword: + case ts.SyntaxKind.DefaultKeyword: } } } - function createDiagnosticForNodeArray(nodes: NodeArray, message: DiagnosticMessage, arg0?: string | number, arg1?: string | number, arg2?: string | number): DiagnosticWithLocation { + function createDiagnosticForNodeArray(nodes: ts.NodeArray, message: ts.DiagnosticMessage, arg0?: string | number, arg1?: string | number, arg2?: string | number): ts.DiagnosticWithLocation { const start = nodes.pos; - return createFileDiagnostic(sourceFile, start, nodes.end - start, message, arg0, arg1, arg2); + return ts.createFileDiagnostic(sourceFile, start, nodes.end - start, message, arg0, arg1, arg2); } // Since these are syntactic diagnostics, parent might not have been set // this means the sourceFile cannot be infered from the node - function createDiagnosticForNode(node: Node, message: DiagnosticMessage, arg0?: string | number, arg1?: string | number, arg2?: string | number): DiagnosticWithLocation { - return createDiagnosticForNodeInSourceFile(sourceFile, node, message, arg0, arg1, arg2); + function createDiagnosticForNode(node: ts.Node, message: ts.DiagnosticMessage, arg0?: string | number, arg1?: string | number, arg2?: string | number): ts.DiagnosticWithLocation { + return ts.createDiagnosticForNodeInSourceFile(sourceFile, node, message, arg0, arg1, arg2); } }); } - function getDeclarationDiagnosticsWorker(sourceFile: SourceFile | undefined, cancellationToken: CancellationToken | undefined): readonly DiagnosticWithLocation[] { + function getDeclarationDiagnosticsWorker(sourceFile: ts.SourceFile | undefined, cancellationToken: ts.CancellationToken | undefined): readonly ts.DiagnosticWithLocation[] { return getAndCacheDiagnostics(sourceFile, cancellationToken, cachedDeclarationDiagnosticsForFile, getDeclarationDiagnosticsForFileNoCache); } - function getDeclarationDiagnosticsForFileNoCache(sourceFile: SourceFile | undefined, cancellationToken: CancellationToken | undefined): readonly DiagnosticWithLocation[] { + function getDeclarationDiagnosticsForFileNoCache(sourceFile: ts.SourceFile | undefined, cancellationToken: ts.CancellationToken | undefined): readonly ts.DiagnosticWithLocation[] { return runWithCancellationToken(() => { const resolver = getTypeChecker().getEmitResolver(sourceFile, cancellationToken); // Don't actually write any files since we're just getting diagnostics. - return ts.getDeclarationDiagnostics(getEmitHost(noop), resolver, sourceFile) || emptyArray; + return ts.getDeclarationDiagnostics(getEmitHost(ts.noop), resolver, sourceFile) || ts.emptyArray; }); } - function getAndCacheDiagnostics( - sourceFile: T, - cancellationToken: CancellationToken | undefined, - cache: DiagnosticCache, - getDiagnostics: (sourceFile: T, cancellationToken: CancellationToken | undefined) => readonly U[], - ): readonly U[] { + function getAndCacheDiagnostics(sourceFile: T, cancellationToken: ts.CancellationToken | undefined, cache: DiagnosticCache, getDiagnostics: (sourceFile: T, cancellationToken: ts.CancellationToken | undefined) => readonly U[]): readonly U[] { const cachedResult = sourceFile ? cache.perFile?.get(sourceFile.path) @@ -2501,7 +2444,7 @@ namespace ts { } const result = getDiagnostics(sourceFile, cancellationToken); if (sourceFile) { - (cache.perFile || (cache.perFile = new Map())).set(sourceFile.path, result); + (cache.perFile || (cache.perFile = new ts.Map())).set(sourceFile.path, result); } else { cache.allDiagnostics = result; @@ -2509,72 +2452,69 @@ namespace ts { return result; } - function getDeclarationDiagnosticsForFile(sourceFile: SourceFile, cancellationToken: CancellationToken): readonly DiagnosticWithLocation[] { + function getDeclarationDiagnosticsForFile(sourceFile: ts.SourceFile, cancellationToken: ts.CancellationToken): readonly ts.DiagnosticWithLocation[] { return sourceFile.isDeclarationFile ? [] : getDeclarationDiagnosticsWorker(sourceFile, cancellationToken); } - function getOptionsDiagnostics(): SortedReadonlyArray { - return sortAndDeduplicateDiagnostics(concatenate( - programDiagnostics.getGlobalDiagnostics(), - getOptionsDiagnosticsOfConfigFile() - )); + function getOptionsDiagnostics(): ts.SortedReadonlyArray { + return ts.sortAndDeduplicateDiagnostics(ts.concatenate(programDiagnostics.getGlobalDiagnostics(), getOptionsDiagnosticsOfConfigFile())); } function getOptionsDiagnosticsOfConfigFile() { - if (!options.configFile) return emptyArray; + if (!options.configFile) + return ts.emptyArray; let diagnostics = programDiagnostics.getDiagnostics(options.configFile.fileName); forEachResolvedProjectReference(resolvedRef => { - diagnostics = concatenate(diagnostics, programDiagnostics.getDiagnostics(resolvedRef.sourceFile.fileName)); + diagnostics = ts.concatenate(diagnostics, programDiagnostics.getDiagnostics(resolvedRef.sourceFile.fileName)); }); return diagnostics; } - function getGlobalDiagnostics(): SortedReadonlyArray { - return rootNames.length ? sortAndDeduplicateDiagnostics(getTypeChecker().getGlobalDiagnostics().slice()) : emptyArray as any as SortedReadonlyArray; + function getGlobalDiagnostics(): ts.SortedReadonlyArray { + return rootNames.length ? ts.sortAndDeduplicateDiagnostics(getTypeChecker().getGlobalDiagnostics().slice()) : ts.emptyArray as any as ts.SortedReadonlyArray; } - function getConfigFileParsingDiagnostics(): readonly Diagnostic[] { - return configFileParsingDiagnostics || emptyArray; + function getConfigFileParsingDiagnostics(): readonly ts.Diagnostic[] { + return configFileParsingDiagnostics || ts.emptyArray; } - function processRootFile(fileName: string, isDefaultLib: boolean, ignoreNoDefaultLib: boolean, reason: FileIncludeReason) { - processSourceFile(normalizePath(fileName), isDefaultLib, ignoreNoDefaultLib, /*packageId*/ undefined, reason); + function processRootFile(fileName: string, isDefaultLib: boolean, ignoreNoDefaultLib: boolean, reason: ts.FileIncludeReason) { + processSourceFile(ts.normalizePath(fileName), isDefaultLib, ignoreNoDefaultLib, /*packageId*/ undefined, reason); } - function fileReferenceIsEqualTo(a: FileReference, b: FileReference): boolean { + function fileReferenceIsEqualTo(a: ts.FileReference, b: ts.FileReference): boolean { return a.fileName === b.fileName; } - function moduleNameIsEqualTo(a: StringLiteralLike | Identifier, b: StringLiteralLike | Identifier): boolean { - return a.kind === SyntaxKind.Identifier - ? b.kind === SyntaxKind.Identifier && a.escapedText === b.escapedText - : b.kind === SyntaxKind.StringLiteral && a.text === b.text; + function moduleNameIsEqualTo(a: ts.StringLiteralLike | ts.Identifier, b: ts.StringLiteralLike | ts.Identifier): boolean { + return a.kind === ts.SyntaxKind.Identifier + ? b.kind === ts.SyntaxKind.Identifier && a.escapedText === b.escapedText + : b.kind === ts.SyntaxKind.StringLiteral && a.text === b.text; } - - function createSyntheticImport(text: string, file: SourceFile) { - const externalHelpersModuleReference = factory.createStringLiteral(text); - const importDecl = factory.createImportDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, /*importClause*/ undefined, externalHelpersModuleReference, /*assertClause*/ undefined); - addEmitFlags(importDecl, EmitFlags.NeverApplyImportHelper); - setParent(externalHelpersModuleReference, importDecl); - setParent(importDecl, file); + function createSyntheticImport(text: string, file: ts.SourceFile) { + const externalHelpersModuleReference = ts.factory.createStringLiteral(text); + const importDecl = ts.factory.createImportDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, /*importClause*/ undefined, externalHelpersModuleReference, /*assertClause*/ undefined); + ts.addEmitFlags(importDecl, ts.EmitFlags.NeverApplyImportHelper); + ts.setParent(externalHelpersModuleReference, importDecl); + ts.setParent(importDecl, file); // explicitly unset the synthesized flag on these declarations so the checker API will answer questions about them // (which is required to build the dependency graph for incremental emit) - (externalHelpersModuleReference as Mutable).flags &= ~NodeFlags.Synthesized; - (importDecl as Mutable).flags &= ~NodeFlags.Synthesized; + (externalHelpersModuleReference as ts.Mutable).flags &= ~ts.NodeFlags.Synthesized; + (importDecl as ts.Mutable).flags &= ~ts.NodeFlags.Synthesized; return externalHelpersModuleReference; } - function collectExternalModuleReferences(file: SourceFile): void { + function collectExternalModuleReferences(file: ts.SourceFile): void { if (file.imports) { return; } - const isJavaScriptFile = isSourceFileJS(file); - const isExternalModuleFile = isExternalModule(file); + const isJavaScriptFile = ts.isSourceFileJS(file); + const isExternalModuleFile = ts.isExternalModule(file); // file.imports may not be undefined if there exists dynamic import - let imports: StringLiteralLike[] | undefined; - let moduleAugmentations: (StringLiteral | Identifier)[] | undefined; + let imports: ts.StringLiteralLike[] | undefined; + let moduleAugmentations: (ts.StringLiteral | ts.Identifier)[] | undefined; let ambientModules: string[] | undefined; // If we are importing helpers, we need to add a synthetic reference to resolve the @@ -2583,9 +2523,9 @@ namespace ts { && !file.isDeclarationFile) { if (options.importHelpers) { // synthesize 'import "tslib"' declaration - imports = [createSyntheticImport(externalHelpersModuleNameText, file)]; + imports = [createSyntheticImport(ts.externalHelpersModuleNameText, file)]; } - const jsxImport = getJSXRuntimeImport(getJSXImplicitImportBase(options, file), options); + const jsxImport = ts.getJSXRuntimeImport(ts.getJSXImplicitImportBase(options, file), options); if (jsxImport) { // synthesize `import "base/jsx-runtime"` declaration (imports ||= []).push(createSyntheticImport(jsxImport, file)); @@ -2595,40 +2535,40 @@ namespace ts { for (const node of file.statements) { collectModuleReferences(node, /*inAmbientModule*/ false); } - if ((file.flags & NodeFlags.PossiblyContainsDynamicImport) || isJavaScriptFile) { + if ((file.flags & ts.NodeFlags.PossiblyContainsDynamicImport) || isJavaScriptFile) { collectDynamicImportOrRequireCalls(file); } - file.imports = imports || emptyArray; - file.moduleAugmentations = moduleAugmentations || emptyArray; - file.ambientModuleNames = ambientModules || emptyArray; + file.imports = imports || ts.emptyArray; + file.moduleAugmentations = moduleAugmentations || ts.emptyArray; + file.ambientModuleNames = ambientModules || ts.emptyArray; return; - function collectModuleReferences(node: Statement, inAmbientModule: boolean): void { - if (isAnyImportOrReExport(node)) { - const moduleNameExpr = getExternalModuleName(node); + function collectModuleReferences(node: ts.Statement, inAmbientModule: boolean): void { + if (ts.isAnyImportOrReExport(node)) { + const moduleNameExpr = ts.getExternalModuleName(node); // TypeScript 1.0 spec (April 2014): 12.1.6 // An ExternalImportDeclaration in an AmbientExternalModuleDeclaration may reference other external modules // only through top - level external module names. Relative external module names are not permitted. - if (moduleNameExpr && isStringLiteral(moduleNameExpr) && moduleNameExpr.text && (!inAmbientModule || !isExternalModuleNameRelative(moduleNameExpr.text))) { - setParentRecursive(node, /*incremental*/ false); // we need parent data on imports before the program is fully bound, so we ensure it's set here - imports = append(imports, moduleNameExpr); + if (moduleNameExpr && ts.isStringLiteral(moduleNameExpr) && moduleNameExpr.text && (!inAmbientModule || !ts.isExternalModuleNameRelative(moduleNameExpr.text))) { + ts.setParentRecursive(node, /*incremental*/ false); // we need parent data on imports before the program is fully bound, so we ensure it's set here + imports = ts.append(imports, moduleNameExpr); if (!usesUriStyleNodeCoreModules && currentNodeModulesDepth === 0 && !file.isDeclarationFile) { - usesUriStyleNodeCoreModules = startsWith(moduleNameExpr.text, "node:"); + usesUriStyleNodeCoreModules = ts.startsWith(moduleNameExpr.text, "node:"); } } } - else if (isModuleDeclaration(node)) { - if (isAmbientModule(node) && (inAmbientModule || hasSyntacticModifier(node, ModifierFlags.Ambient) || file.isDeclarationFile)) { - (node.name as Mutable).parent = node; - const nameText = getTextOfIdentifierOrLiteral(node.name); + else if (ts.isModuleDeclaration(node)) { + if (ts.isAmbientModule(node) && (inAmbientModule || ts.hasSyntacticModifier(node, ts.ModifierFlags.Ambient) || file.isDeclarationFile)) { + (node.name as ts.Mutable).parent = node; + const nameText = ts.getTextOfIdentifierOrLiteral(node.name); // Ambient module declarations can be interpreted as augmentations for some existing external modules. // This will happen in two cases: // - if current file is external module then module augmentation is a ambient module declaration defined in the top level scope // - if current file is not external module then module augmentation is an ambient module declaration with non-relative module name // immediately nested in top level ambient module declaration . - if (isExternalModuleFile || (inAmbientModule && !isExternalModuleNameRelative(nameText))) { + if (isExternalModuleFile || (inAmbientModule && !ts.isExternalModuleNameRelative(nameText))) { (moduleAugmentations || (moduleAugmentations = [])).push(node.name); } else if (!inAmbientModule) { @@ -2642,7 +2582,7 @@ namespace ts { // Relative external module names are not permitted // NOTE: body of ambient module is always a module block, if it exists - const body = (node as ModuleDeclaration).body as ModuleBlock; + const body = (node as ts.ModuleDeclaration).body as ts.ModuleBlock; if (body) { for (const statement of body.statements) { collectModuleReferences(statement, /*inAmbientModule*/ true); @@ -2653,36 +2593,36 @@ namespace ts { } } - function collectDynamicImportOrRequireCalls(file: SourceFile) { + function collectDynamicImportOrRequireCalls(file: ts.SourceFile) { const r = /import|require/g; while (r.exec(file.text) !== null) { // eslint-disable-line no-null/no-null const node = getNodeAtPosition(file, r.lastIndex); - if (isJavaScriptFile && isRequireCall(node, /*checkArgumentIsStringLiteralLike*/ true)) { - setParentRecursive(node, /*incremental*/ false); // we need parent data on imports before the program is fully bound, so we ensure it's set here - imports = append(imports, node.arguments[0]); + if (isJavaScriptFile && ts.isRequireCall(node, /*checkArgumentIsStringLiteralLike*/ true)) { + ts.setParentRecursive(node, /*incremental*/ false); // we need parent data on imports before the program is fully bound, so we ensure it's set here + imports = ts.append(imports, node.arguments[0]); } // we have to check the argument list has length of at least 1. We will still have to process these even though we have parsing error. - else if (isImportCall(node) && node.arguments.length >= 1 && isStringLiteralLike(node.arguments[0])) { - setParentRecursive(node, /*incremental*/ false); // we need parent data on imports before the program is fully bound, so we ensure it's set here - imports = append(imports, node.arguments[0]); + else if (ts.isImportCall(node) && node.arguments.length >= 1 && ts.isStringLiteralLike(node.arguments[0])) { + ts.setParentRecursive(node, /*incremental*/ false); // we need parent data on imports before the program is fully bound, so we ensure it's set here + imports = ts.append(imports, node.arguments[0]); } - else if (isLiteralImportTypeNode(node)) { - setParentRecursive(node, /*incremental*/ false); // we need parent data on imports before the program is fully bound, so we ensure it's set here - imports = append(imports, node.argument.literal); + else if (ts.isLiteralImportTypeNode(node)) { + ts.setParentRecursive(node, /*incremental*/ false); // we need parent data on imports before the program is fully bound, so we ensure it's set here + imports = ts.append(imports, node.argument.literal); } } } /** Returns a token if position is in [start-of-leading-trivia, end), includes JSDoc only in JS files */ - function getNodeAtPosition(sourceFile: SourceFile, position: number): Node { - let current: Node = sourceFile; - const getContainingChild = (child: Node) => { - if (child.pos <= position && (position < child.end || (position === child.end && (child.kind === SyntaxKind.EndOfFileToken)))) { + function getNodeAtPosition(sourceFile: ts.SourceFile, position: number): ts.Node { + let current: ts.Node = sourceFile; + const getContainingChild = (child: ts.Node) => { + if (child.pos <= position && (position < child.end || (position === child.end && (child.kind === ts.SyntaxKind.EndOfFileToken)))) { return child; } }; while (true) { - const child = isJavaScriptFile && hasJSDocNodes(current) && forEach(current.jsDoc, getContainingChild) || forEachChild(current, getContainingChild); + const child = isJavaScriptFile && ts.hasJSDocNodes(current) && ts.forEach(current.jsDoc, getContainingChild) || ts.forEachChild(current, getContainingChild); if (!child) { return current; } @@ -2691,34 +2631,29 @@ namespace ts { } } - function getLibFileFromReference(ref: FileReference) { - const libName = toFileNameLowerCase(ref.fileName); - const libFileName = libMap.get(libName); + function getLibFileFromReference(ref: ts.FileReference) { + const libName = ts.toFileNameLowerCase(ref.fileName); + const libFileName = ts.libMap.get(libName); if (libFileName) { return getSourceFile(pathForLibFile(libFileName)); } } /** This should have similar behavior to 'processSourceFile' without diagnostics or mutation. */ - function getSourceFileFromReference(referencingFile: SourceFile | UnparsedSource, ref: FileReference): SourceFile | undefined { + function getSourceFileFromReference(referencingFile: ts.SourceFile | ts.UnparsedSource, ref: ts.FileReference): ts.SourceFile | undefined { return getSourceFileFromReferenceWorker(resolveTripleslashReference(ref.fileName, referencingFile.fileName), getSourceFile); } - function getSourceFileFromReferenceWorker( - fileName: string, - getSourceFile: (fileName: string) => SourceFile | undefined, - fail?: (diagnostic: DiagnosticMessage, ...argument: string[]) => void, - reason?: FileIncludeReason): SourceFile | undefined { - - if (hasExtension(fileName)) { + function getSourceFileFromReferenceWorker(fileName: string, getSourceFile: (fileName: string) => ts.SourceFile | undefined, fail?: (diagnostic: ts.DiagnosticMessage, ...argument: string[]) => void, reason?: ts.FileIncludeReason): ts.SourceFile | undefined { + if (ts.hasExtension(fileName)) { const canonicalFileName = host.getCanonicalFileName(fileName); - if (!options.allowNonTsExtensions && !forEach(flatten(supportedExtensionsWithJsonIfResolveJsonModule), extension => fileExtensionIs(canonicalFileName, extension))) { + if (!options.allowNonTsExtensions && !ts.forEach(ts.flatten(supportedExtensionsWithJsonIfResolveJsonModule), extension => ts.fileExtensionIs(canonicalFileName, extension))) { if (fail) { - if (hasJSFileExtension(canonicalFileName)) { - fail(Diagnostics.File_0_is_a_JavaScript_file_Did_you_mean_to_enable_the_allowJs_option, fileName); + if (ts.hasJSFileExtension(canonicalFileName)) { + fail(ts.Diagnostics.File_0_is_a_JavaScript_file_Did_you_mean_to_enable_the_allowJs_option, fileName); } else { - fail(Diagnostics.File_0_has_an_unsupported_extension_The_only_supported_extensions_are_1, fileName, "'" + flatten(supportedExtensions).join("', '") + "'"); + fail(ts.Diagnostics.File_0_has_an_unsupported_extension_The_only_supported_extensions_are_1, fileName, "'" + ts.flatten(supportedExtensions).join("', '") + "'"); } } return undefined; @@ -2729,60 +2664,58 @@ namespace ts { if (!sourceFile) { const redirect = getProjectReferenceRedirect(fileName); if (redirect) { - fail(Diagnostics.Output_file_0_has_not_been_built_from_source_file_1, redirect, fileName); + fail(ts.Diagnostics.Output_file_0_has_not_been_built_from_source_file_1, redirect, fileName); } else { - fail(Diagnostics.File_0_not_found, fileName); + fail(ts.Diagnostics.File_0_not_found, fileName); } } else if (isReferencedFile(reason) && canonicalFileName === host.getCanonicalFileName(getSourceFileByPath(reason.file)!.fileName)) { - fail(Diagnostics.A_file_cannot_have_a_reference_to_itself); + fail(ts.Diagnostics.A_file_cannot_have_a_reference_to_itself); } } return sourceFile; } else { const sourceFileNoExtension = options.allowNonTsExtensions && getSourceFile(fileName); - if (sourceFileNoExtension) return sourceFileNoExtension; + if (sourceFileNoExtension) + return sourceFileNoExtension; if (fail && options.allowNonTsExtensions) { - fail(Diagnostics.File_0_not_found, fileName); + fail(ts.Diagnostics.File_0_not_found, fileName); return undefined; } // Only try adding extensions from the first supported group (which should be .ts/.tsx/.d.ts) - const sourceFileWithAddedExtension = forEach(supportedExtensions[0], extension => getSourceFile(fileName + extension)); - if (fail && !sourceFileWithAddedExtension) fail(Diagnostics.Could_not_resolve_the_path_0_with_the_extensions_Colon_1, fileName, "'" + flatten(supportedExtensions).join("', '") + "'"); + const sourceFileWithAddedExtension = ts.forEach(supportedExtensions[0], extension => getSourceFile(fileName + extension)); + if (fail && !sourceFileWithAddedExtension) + fail(ts.Diagnostics.Could_not_resolve_the_path_0_with_the_extensions_Colon_1, fileName, "'" + ts.flatten(supportedExtensions).join("', '") + "'"); return sourceFileWithAddedExtension; } } /** This has side effects through `findSourceFile`. */ - function processSourceFile(fileName: string, isDefaultLib: boolean, ignoreNoDefaultLib: boolean, packageId: PackageId | undefined, reason: FileIncludeReason): void { - getSourceFileFromReferenceWorker( - fileName, - fileName => findSourceFile(fileName, isDefaultLib, ignoreNoDefaultLib, reason, packageId), // TODO: GH#18217 - (diagnostic, ...args) => addFilePreprocessingFileExplainingDiagnostic(/*file*/ undefined, reason, diagnostic, args), - reason - ); + function processSourceFile(fileName: string, isDefaultLib: boolean, ignoreNoDefaultLib: boolean, packageId: ts.PackageId | undefined, reason: ts.FileIncludeReason): void { + getSourceFileFromReferenceWorker(fileName, fileName => findSourceFile(fileName, isDefaultLib, ignoreNoDefaultLib, reason, packageId), // TODO: GH#18217 + (diagnostic, ...args) => addFilePreprocessingFileExplainingDiagnostic(/*file*/ undefined, reason, diagnostic, args), reason); } - function processProjectReferenceFile(fileName: string, reason: ProjectReferenceFile) { + function processProjectReferenceFile(fileName: string, reason: ts.ProjectReferenceFile) { return processSourceFile(fileName, /*isDefaultLib*/ false, /*ignoreNoDefaultLib*/ false, /*packageId*/ undefined, reason); } - function reportFileNamesDifferOnlyInCasingError(fileName: string, existingFile: SourceFile, reason: FileIncludeReason): void { - const hasExistingReasonToReportErrorOn = !isReferencedFile(reason) && some(fileReasons.get(existingFile.path), isReferencedFile); + function reportFileNamesDifferOnlyInCasingError(fileName: string, existingFile: ts.SourceFile, reason: ts.FileIncludeReason): void { + const hasExistingReasonToReportErrorOn = !isReferencedFile(reason) && ts.some(fileReasons.get(existingFile.path), isReferencedFile); if (hasExistingReasonToReportErrorOn) { - addFilePreprocessingFileExplainingDiagnostic(existingFile, reason, Diagnostics.Already_included_file_name_0_differs_from_file_name_1_only_in_casing, [existingFile.fileName, fileName]); + addFilePreprocessingFileExplainingDiagnostic(existingFile, reason, ts.Diagnostics.Already_included_file_name_0_differs_from_file_name_1_only_in_casing, [existingFile.fileName, fileName]); } else { - addFilePreprocessingFileExplainingDiagnostic(existingFile, reason, Diagnostics.File_name_0_differs_from_already_included_file_name_1_only_in_casing, [fileName, existingFile.fileName]); + addFilePreprocessingFileExplainingDiagnostic(existingFile, reason, ts.Diagnostics.File_name_0_differs_from_already_included_file_name_1_only_in_casing, [fileName, existingFile.fileName]); } } - function createRedirectSourceFile(redirectTarget: SourceFile, unredirected: SourceFile, fileName: string, path: Path, resolvedPath: Path, originalFileName: string): SourceFile { - const redirect: SourceFile = Object.create(redirectTarget); + function createRedirectSourceFile(redirectTarget: ts.SourceFile, unredirected: ts.SourceFile, fileName: string, path: ts.Path, resolvedPath: ts.Path, originalFileName: string): ts.SourceFile { + const redirect: ts.SourceFile = Object.create(redirectTarget); redirect.fileName = fileName; redirect.path = path; redirect.resolvedPath = resolvedPath; @@ -2791,42 +2724,42 @@ namespace ts { sourceFilesFoundSearchingNodeModules.set(path, currentNodeModulesDepth > 0); Object.defineProperties(redirect, { id: { - get(this: SourceFile) { return this.redirectInfo!.redirectTarget.id; }, - set(this: SourceFile, value: SourceFile["id"]) { this.redirectInfo!.redirectTarget.id = value; }, + get(this: ts.SourceFile) { return this.redirectInfo!.redirectTarget.id; }, + set(this: ts.SourceFile, value: ts.SourceFile["id"]) { this.redirectInfo!.redirectTarget.id = value; }, }, symbol: { - get(this: SourceFile) { return this.redirectInfo!.redirectTarget.symbol; }, - set(this: SourceFile, value: SourceFile["symbol"]) { this.redirectInfo!.redirectTarget.symbol = value; }, + get(this: ts.SourceFile) { return this.redirectInfo!.redirectTarget.symbol; }, + set(this: ts.SourceFile, value: ts.SourceFile["symbol"]) { this.redirectInfo!.redirectTarget.symbol = value; }, }, }); return redirect; } // Get source file from normalized fileName - function findSourceFile(fileName: string, isDefaultLib: boolean, ignoreNoDefaultLib: boolean, reason: FileIncludeReason, packageId: PackageId | undefined): SourceFile | undefined { - tracing?.push(tracing.Phase.Program, "findSourceFile", { + function findSourceFile(fileName: string, isDefaultLib: boolean, ignoreNoDefaultLib: boolean, reason: ts.FileIncludeReason, packageId: ts.PackageId | undefined): ts.SourceFile | undefined { + ts.tracing?.push(ts.tracing.Phase.Program, "findSourceFile", { fileName, isDefaultLib: isDefaultLib || undefined, - fileIncludeKind: (FileIncludeKind as any)[reason.kind], + fileIncludeKind: (ts.FileIncludeKind as any)[reason.kind], }); const result = findSourceFileWorker(fileName, isDefaultLib, ignoreNoDefaultLib, reason, packageId); - tracing?.pop(); + ts.tracing?.pop(); return result; } - function getCreateSourceFileOptions(fileName: string, moduleResolutionCache: ModuleResolutionCache | undefined, host: CompilerHost, options: CompilerOptions) { + function getCreateSourceFileOptions(fileName: string, moduleResolutionCache: ts.ModuleResolutionCache | undefined, host: ts.CompilerHost, options: ts.CompilerOptions) { // It's a _little odd_ that we can't set `impliedNodeFormat` until the program step - but it's the first and only time we have a resolution cache // and a freshly made source file node on hand at the same time, and we need both to set the field. Persisting the resolution cache all the way // to the check and emit steps would be bad - so we much prefer detecting and storing the format information on the source file node upfront. const impliedNodeFormat = getImpliedNodeFormatForFile(toPath(fileName), moduleResolutionCache?.getPackageJsonInfoCache(), host, options); return { - languageVersion: getEmitScriptTarget(options), + languageVersion: ts.getEmitScriptTarget(options), impliedNodeFormat, - setExternalModuleIndicator: getSetExternalModuleIndicator(options) + setExternalModuleIndicator: ts.getSetExternalModuleIndicator(options) }; } - function findSourceFileWorker(fileName: string, isDefaultLib: boolean, ignoreNoDefaultLib: boolean, reason: FileIncludeReason, packageId: PackageId | undefined): SourceFile | undefined { + function findSourceFileWorker(fileName: string, isDefaultLib: boolean, ignoreNoDefaultLib: boolean, reason: ts.FileIncludeReason, packageId: ts.PackageId | undefined): ts.SourceFile | undefined { const path = toPath(fileName); if (useSourceOfProjectReferenceRedirect) { let source = getSourceOfProjectReferenceRedirect(path); @@ -2837,16 +2770,18 @@ namespace ts { if (!source && host.realpath && options.preserveSymlinks && - isDeclarationFileName(fileName) && - stringContains(fileName, nodeModulesPathPart)) { + ts.isDeclarationFileName(fileName) && + ts.stringContains(fileName, ts.nodeModulesPathPart)) { const realPath = toPath(host.realpath(fileName)); - if (realPath !== path) source = getSourceOfProjectReferenceRedirect(realPath); + if (realPath !== path) + source = getSourceOfProjectReferenceRedirect(realPath); } if (source) { - const file = isString(source) ? + const file = ts.isString(source) ? findSourceFile(source, isDefaultLib, ignoreNoDefaultLib, reason, packageId) : undefined; - if (file) addFileToFilesByName(file, path, /*redirectedPath*/ undefined); + if (file) + addFileToFilesByName(file, path, /*redirectedPath*/ undefined); return file; } } @@ -2863,8 +2798,8 @@ namespace ts { fileName = getProjectReferenceRedirect(fileName) || fileName; } // Check if it differs only in drive letters its ok to ignore that error: - const checkedAbsolutePath = getNormalizedAbsolutePathWithoutRoot(checkedName, currentDirectory); - const inputAbsolutePath = getNormalizedAbsolutePathWithoutRoot(fileName, currentDirectory); + const checkedAbsolutePath = ts.getNormalizedAbsolutePathWithoutRoot(checkedName, currentDirectory); + const inputAbsolutePath = ts.getNormalizedAbsolutePathWithoutRoot(fileName, currentDirectory); if (checkedAbsolutePath !== inputAbsolutePath) { reportFileNamesDifferOnlyInCasingError(fileName, file, reason); } @@ -2896,11 +2831,11 @@ namespace ts { return file || undefined; } - let redirectedPath: Path | undefined; + let redirectedPath: ts.Path | undefined; if (isReferencedFile(reason) && !useSourceOfProjectReferenceRedirect) { const redirectProject = getProjectReferenceRedirectProject(fileName); if (redirectProject) { - if (outFile(redirectProject.commandLine.options)) { + if (ts.outFile(redirectProject.commandLine.options)) { // Shouldnt create many to 1 mapping file in --out scenario return undefined; } @@ -2916,15 +2851,10 @@ namespace ts { } // We haven't looked for this file, do so now and cache result - const file = host.getSourceFile( - fileName, - getCreateSourceFileOptions(fileName, moduleResolutionCache, host, options), - hostErrorMessage => addFilePreprocessingFileExplainingDiagnostic(/*file*/ undefined, reason, Diagnostics.Cannot_read_file_0_Colon_1, [fileName, hostErrorMessage]), - shouldCreateNewSourceFile - ); + const file = host.getSourceFile(fileName, getCreateSourceFileOptions(fileName, moduleResolutionCache, host, options), hostErrorMessage => addFilePreprocessingFileExplainingDiagnostic(/*file*/ undefined, reason, ts.Diagnostics.Cannot_read_file_0_Colon_1, [fileName, hostErrorMessage]), shouldCreateNewSourceFile); if (packageId) { - const packageIdKey = packageIdToString(packageId); + const packageIdKey = ts.packageIdToString(packageId); const fileFromPackageId = packageIdToSourceFile.get(packageIdKey); if (fileFromPackageId) { // Some other SourceFile already exists with this package name and version. @@ -2933,14 +2863,14 @@ namespace ts { redirectTargetsMap.add(fileFromPackageId.path, fileName); addFileToFilesByName(dupFile, path, redirectedPath); addFileIncludeReason(dupFile, reason); - sourceFileToPackageName.set(path, packageIdToPackageName(packageId)); + sourceFileToPackageName.set(path, ts.packageIdToPackageName(packageId)); processingOtherFiles!.push(dupFile); return dupFile; } else if (file) { // This is the first source file to have this packageId. packageIdToSourceFile.set(packageIdKey, file); - sourceFileToPackageName.set(path, packageIdToPackageName(packageId)); + sourceFileToPackageName.set(path, ts.packageIdToPackageName(packageId)); } } addFileToFilesByName(file, path, redirectedPath); @@ -2954,7 +2884,7 @@ namespace ts { addFileIncludeReason(file, reason); if (host.useCaseSensitiveFileNames()) { - const pathLowerCase = toFileNameLowerCase(path); + const pathLowerCase = ts.toFileNameLowerCase(path); // for case-sensitive file systems check if we've already seen some file with similar filename ignoring case const existingFile = filesByNameIgnoreCase!.get(pathLowerCase); if (existingFile) { @@ -2989,11 +2919,12 @@ namespace ts { return file; } - function addFileIncludeReason(file: SourceFile | undefined, reason: FileIncludeReason) { - if (file) fileReasons.add(file.path, reason); + function addFileIncludeReason(file: ts.SourceFile | undefined, reason: ts.FileIncludeReason) { + if (file) + fileReasons.add(file.path, reason); } - function addFileToFilesByName(file: SourceFile | undefined, path: Path, redirectedPath: Path | undefined) { + function addFileToFilesByName(file: ts.SourceFile | undefined, path: ts.Path, redirectedPath: ts.Path | undefined) { if (redirectedPath) { filesByName.set(redirectedPath, file); filesByName.set(path, file || false); @@ -3010,7 +2941,7 @@ namespace ts { function getProjectReferenceRedirectProject(fileName: string) { // Ignore dts or any json files - if (!resolvedProjectReferences || !resolvedProjectReferences.length || isDeclarationFileName(fileName) || fileExtensionIs(fileName, Extension.Json)) { + if (!resolvedProjectReferences || !resolvedProjectReferences.length || ts.isDeclarationFileName(fileName) || ts.fileExtensionIs(fileName, ts.Extension.Json)) { return undefined; } @@ -3020,11 +2951,11 @@ namespace ts { } - function getProjectReferenceOutputName(referencedProject: ResolvedProjectReference, fileName: string) { - const out = outFile(referencedProject.commandLine.options); + function getProjectReferenceOutputName(referencedProject: ts.ResolvedProjectReference, fileName: string) { + const out = ts.outFile(referencedProject.commandLine.options); return out ? - changeExtension(out, Extension.Dts) : - getOutputDeclarationFileName(fileName, referencedProject.commandLine, !host.useCaseSensitiveFileNames()); + ts.changeExtension(out, ts.Extension.Dts) : + ts.getOutputDeclarationFileName(fileName, referencedProject.commandLine, !host.useCaseSensitiveFileNames()); } /** @@ -3032,12 +2963,11 @@ namespace ts { */ function getResolvedProjectReferenceToRedirect(fileName: string) { if (mapFromFileToProjectReferenceRedirects === undefined) { - mapFromFileToProjectReferenceRedirects = new Map(); + mapFromFileToProjectReferenceRedirects = new ts.Map(); forEachResolvedProjectReference(referencedProject => { // not input file from the referenced project, ignore if (toPath(options.configFilePath!) !== referencedProject.sourceFile.path) { - referencedProject.commandLine.fileNames.forEach(f => - mapFromFileToProjectReferenceRedirects!.set(toPath(f), referencedProject.sourceFile.path)); + referencedProject.commandLine.fileNames.forEach(f => mapFromFileToProjectReferenceRedirects!.set(toPath(f), referencedProject.sourceFile.path)); } }); } @@ -3046,28 +2976,27 @@ namespace ts { return referencedProjectPath && getResolvedProjectReferenceByPath(referencedProjectPath); } - function forEachResolvedProjectReference( - cb: (resolvedProjectReference: ResolvedProjectReference) => T | undefined - ): T | undefined { + function forEachResolvedProjectReference(cb: (resolvedProjectReference: ts.ResolvedProjectReference) => T | undefined): T | undefined { return ts.forEachResolvedProjectReference(resolvedProjectReferences, cb); } - function getSourceOfProjectReferenceRedirect(path: Path) { - if (!isDeclarationFileName(path)) return undefined; + function getSourceOfProjectReferenceRedirect(path: ts.Path) { + if (!ts.isDeclarationFileName(path)) + return undefined; if (mapFromToProjectReferenceRedirectSource === undefined) { - mapFromToProjectReferenceRedirectSource = new Map(); + mapFromToProjectReferenceRedirectSource = new ts.Map(); forEachResolvedProjectReference(resolvedRef => { - const out = outFile(resolvedRef.commandLine.options); + const out = ts.outFile(resolvedRef.commandLine.options); if (out) { // Dont know which source file it means so return true? - const outputDts = changeExtension(out, Extension.Dts); + const outputDts = ts.changeExtension(out, ts.Extension.Dts); mapFromToProjectReferenceRedirectSource!.set(toPath(outputDts), true); } else { - const getCommonSourceDirectory = memoize(() => getCommonSourceDirectoryOfConfig(resolvedRef.commandLine, !host.useCaseSensitiveFileNames())); - forEach(resolvedRef.commandLine.fileNames, fileName => { - if (!isDeclarationFileName(fileName) && !fileExtensionIs(fileName, Extension.Json)) { - const outputDts = getOutputDeclarationFileName(fileName, resolvedRef.commandLine, !host.useCaseSensitiveFileNames(), getCommonSourceDirectory); + const getCommonSourceDirectory = ts.memoize(() => ts.getCommonSourceDirectoryOfConfig(resolvedRef.commandLine, !host.useCaseSensitiveFileNames())); + ts.forEach(resolvedRef.commandLine.fileNames, fileName => { + if (!ts.isDeclarationFileName(fileName) && !ts.fileExtensionIs(fileName, ts.Extension.Json)) { + const outputDts = ts.getOutputDeclarationFileName(fileName, resolvedRef.commandLine, !host.useCaseSensitiveFileNames(), getCommonSourceDirectory); mapFromToProjectReferenceRedirectSource!.set(toPath(outputDts), fileName); } }); @@ -3081,7 +3010,7 @@ namespace ts { return useSourceOfProjectReferenceRedirect && !!getResolvedProjectReferenceToRedirect(fileName); } - function getResolvedProjectReferenceByPath(projectReferencePath: Path): ResolvedProjectReference | undefined { + function getResolvedProjectReferenceByPath(projectReferencePath: ts.Path): ts.ResolvedProjectReference | undefined { if (!projectReferenceRedirects) { return undefined; } @@ -3089,19 +3018,15 @@ namespace ts { return projectReferenceRedirects.get(projectReferencePath) || undefined; } - function processReferencedFiles(file: SourceFile, isDefaultLib: boolean) { - forEach(file.referencedFiles, (ref, index) => { - processSourceFile( - resolveTripleslashReference(ref.fileName, file.fileName), - isDefaultLib, + function processReferencedFiles(file: ts.SourceFile, isDefaultLib: boolean) { + ts.forEach(file.referencedFiles, (ref, index) => { + processSourceFile(resolveTripleslashReference(ref.fileName, file.fileName), isDefaultLib, /*ignoreNoDefaultLib*/ false, - /*packageId*/ undefined, - { kind: FileIncludeKind.ReferenceFile, file: file.path, index, } - ); + /*packageId*/ undefined, { kind: ts.FileIncludeKind.ReferenceFile, file: file.path, index, }); }); } - function processTypeReferenceDirectives(file: SourceFile) { + function processTypeReferenceDirectives(file: ts.SourceFile) { const typeDirectives = file.typeReferenceDirectives; if (!typeDirectives) { return; @@ -3112,33 +3037,22 @@ namespace ts { const ref = file.typeReferenceDirectives[index]; const resolvedTypeReferenceDirective = resolutions[index]; // store resolved type directive on the file - const fileName = toFileNameLowerCase(ref.fileName); - setResolvedTypeReferenceDirective(file, fileName, resolvedTypeReferenceDirective); + const fileName = ts.toFileNameLowerCase(ref.fileName); + ts.setResolvedTypeReferenceDirective(file, fileName, resolvedTypeReferenceDirective); const mode = ref.resolutionMode || file.impliedNodeFormat; - if (mode && getEmitModuleResolutionKind(options) !== ModuleResolutionKind.Node16 && getEmitModuleResolutionKind(options) !== ModuleResolutionKind.NodeNext) { - programDiagnostics.add(createDiagnosticForRange(file, ref, Diagnostics.Resolution_modes_are_only_supported_when_moduleResolution_is_node16_or_nodenext)); + if (mode && ts.getEmitModuleResolutionKind(options) !== ts.ModuleResolutionKind.Node16 && ts.getEmitModuleResolutionKind(options) !== ts.ModuleResolutionKind.NodeNext) { + programDiagnostics.add(ts.createDiagnosticForRange(file, ref, ts.Diagnostics.Resolution_modes_are_only_supported_when_moduleResolution_is_node16_or_nodenext)); } - processTypeReferenceDirective(fileName, mode, resolvedTypeReferenceDirective, { kind: FileIncludeKind.TypeReferenceDirective, file: file.path, index, }); + processTypeReferenceDirective(fileName, mode, resolvedTypeReferenceDirective, { kind: ts.FileIncludeKind.TypeReferenceDirective, file: file.path, index, }); } } - function processTypeReferenceDirective( - typeReferenceDirective: string, - mode: SourceFile["impliedNodeFormat"] | undefined, - resolvedTypeReferenceDirective: ResolvedTypeReferenceDirective | undefined, - reason: FileIncludeReason - ): void { - tracing?.push(tracing.Phase.Program, "processTypeReferenceDirective", { directive: typeReferenceDirective, hasResolved: !!resolveModuleNamesReusingOldState, refKind: reason.kind, refPath: isReferencedFile(reason) ? reason.file : undefined }); + function processTypeReferenceDirective(typeReferenceDirective: string, mode: ts.SourceFile["impliedNodeFormat"] | undefined, resolvedTypeReferenceDirective: ts.ResolvedTypeReferenceDirective | undefined, reason: ts.FileIncludeReason): void { + ts.tracing?.push(ts.tracing.Phase.Program, "processTypeReferenceDirective", { directive: typeReferenceDirective, hasResolved: !!resolveModuleNamesReusingOldState, refKind: reason.kind, refPath: isReferencedFile(reason) ? reason.file : undefined }); processTypeReferenceDirectiveWorker(typeReferenceDirective, mode, resolvedTypeReferenceDirective, reason); - tracing?.pop(); + ts.tracing?.pop(); } - - function processTypeReferenceDirectiveWorker( - typeReferenceDirective: string, - mode: SourceFile["impliedNodeFormat"] | undefined, - resolvedTypeReferenceDirective: ResolvedTypeReferenceDirective | undefined, - reason: FileIncludeReason - ): void { + function processTypeReferenceDirectiveWorker(typeReferenceDirective: string, mode: ts.SourceFile["impliedNodeFormat"] | undefined, resolvedTypeReferenceDirective: ts.ResolvedTypeReferenceDirective | undefined, reason: ts.FileIncludeReason): void { // If we already found this library as a primary reference - nothing to do const previousResolution = resolvedTypeReferenceDirectives.get(typeReferenceDirective, mode); @@ -3147,7 +3061,8 @@ namespace ts { } let saveResolution = true; if (resolvedTypeReferenceDirective) { - if (resolvedTypeReferenceDirective.isExternalLibraryImport) currentNodeModulesDepth++; + if (resolvedTypeReferenceDirective.isExternalLibraryImport) + currentNodeModulesDepth++; if (resolvedTypeReferenceDirective.primary) { // resolved from the primary path @@ -3162,12 +3077,7 @@ namespace ts { const otherFileText = host.readFile(resolvedTypeReferenceDirective.resolvedFileName!); const existingFile = getSourceFile(previousResolution.resolvedFileName!)!; if (otherFileText !== existingFile.text) { - addFilePreprocessingFileExplainingDiagnostic( - existingFile, - reason, - Diagnostics.Conflicting_definitions_for_0_found_at_1_and_2_Consider_installing_a_specific_version_of_this_library_to_resolve_the_conflict, - [typeReferenceDirective, resolvedTypeReferenceDirective.resolvedFileName, previousResolution.resolvedFileName] - ); + addFilePreprocessingFileExplainingDiagnostic(existingFile, reason, ts.Diagnostics.Conflicting_definitions_for_0_found_at_1_and_2_Consider_installing_a_specific_version_of_this_library_to_resolve_the_conflict, [typeReferenceDirective, resolvedTypeReferenceDirective.resolvedFileName, previousResolution.resolvedFileName]); } } // don't overwrite previous resolution result @@ -3179,10 +3089,11 @@ namespace ts { } } - if (resolvedTypeReferenceDirective.isExternalLibraryImport) currentNodeModulesDepth--; + if (resolvedTypeReferenceDirective.isExternalLibraryImport) + currentNodeModulesDepth--; } else { - addFilePreprocessingFileExplainingDiagnostic(/*file*/ undefined, reason, Diagnostics.Cannot_find_type_definition_file_for_0, [typeReferenceDirective]); + addFilePreprocessingFileExplainingDiagnostic(/*file*/ undefined, reason, ts.Diagnostics.Cannot_find_type_definition_file_for_0, [typeReferenceDirective]); } if (saveResolution) { @@ -3201,29 +3112,29 @@ namespace ts { path += (i === 2 ? "/" : "-") + components[i]; i++; } - const resolveFrom = combinePaths(currentDirectory, `__lib_node_modules_lookup_${libFileName}__.ts`); - const localOverrideModuleResult = resolveModuleName("@typescript/lib-" + path, resolveFrom, { moduleResolution: ModuleResolutionKind.NodeJs }, host, moduleResolutionCache); + const resolveFrom = ts.combinePaths(currentDirectory, `__lib_node_modules_lookup_${libFileName}__.ts`); + const localOverrideModuleResult = ts.resolveModuleName("@typescript/lib-" + path, resolveFrom, { moduleResolution: ts.ModuleResolutionKind.NodeJs }, host, moduleResolutionCache); if (localOverrideModuleResult?.resolvedModule) { return localOverrideModuleResult.resolvedModule.resolvedFileName; } - return combinePaths(defaultLibraryPath, libFileName); + return ts.combinePaths(defaultLibraryPath, libFileName); } - function processLibReferenceDirectives(file: SourceFile) { - forEach(file.libReferenceDirectives, (libReference, index) => { - const libName = toFileNameLowerCase(libReference.fileName); - const libFileName = libMap.get(libName); + function processLibReferenceDirectives(file: ts.SourceFile) { + ts.forEach(file.libReferenceDirectives, (libReference, index) => { + const libName = ts.toFileNameLowerCase(libReference.fileName); + const libFileName = ts.libMap.get(libName); if (libFileName) { // we ignore any 'no-default-lib' reference set on this file. - processRootFile(pathForLibFile(libFileName), /*isDefaultLib*/ true, /*ignoreNoDefaultLib*/ true, { kind: FileIncludeKind.LibReferenceDirective, file: file.path, index, }); + processRootFile(pathForLibFile(libFileName), /*isDefaultLib*/ true, /*ignoreNoDefaultLib*/ true, { kind: ts.FileIncludeKind.LibReferenceDirective, file: file.path, index, }); } else { - const unqualifiedLibName = removeSuffix(removePrefix(libName, "lib."), ".d.ts"); - const suggestion = getSpellingSuggestion(unqualifiedLibName, libs, identity); - const diagnostic = suggestion ? Diagnostics.Cannot_find_lib_definition_for_0_Did_you_mean_1 : Diagnostics.Cannot_find_lib_definition_for_0; + const unqualifiedLibName = ts.removeSuffix(ts.removePrefix(libName, "lib."), ".d.ts"); + const suggestion = ts.getSpellingSuggestion(unqualifiedLibName, ts.libs, ts.identity); + const diagnostic = suggestion ? ts.Diagnostics.Cannot_find_lib_definition_for_0_Did_you_mean_1 : ts.Diagnostics.Cannot_find_lib_definition_for_0; (fileProcessingDiagnostics ||= []).push({ - kind: FilePreprocessingDiagnosticsKind.FilePreprocessingReferencedDiagnostic, - reason: { kind: FileIncludeKind.LibReferenceDirective, file: file.path, index, }, + kind: ts.FilePreprocessingDiagnosticsKind.FilePreprocessingReferencedDiagnostic, + reason: { kind: ts.FileIncludeKind.LibReferenceDirective, file: file.path, index, }, diagnostic, args: [libName, suggestion] }); @@ -3235,24 +3146,24 @@ namespace ts { return host.getCanonicalFileName(fileName); } - function processImportedModules(file: SourceFile) { + function processImportedModules(file: ts.SourceFile) { collectExternalModuleReferences(file); if (file.imports.length || file.moduleAugmentations.length) { // Because global augmentation doesn't have string literal name, we can check for global augmentation as such. const moduleNames = getModuleNames(file); const resolutions = resolveModuleNamesReusingOldState(moduleNames, file); - Debug.assert(resolutions.length === moduleNames.length); + ts.Debug.assert(resolutions.length === moduleNames.length); const optionsForFile = (useSourceOfProjectReferenceRedirect ? getRedirectReferenceForResolution(file)?.commandLine.options : undefined) || options; for (let index = 0; index < moduleNames.length; index++) { const resolution = resolutions[index]; - setResolvedModule(file, moduleNames[index], resolution, getModeForResolutionAtIndex(file, index)); + ts.setResolvedModule(file, moduleNames[index], resolution, getModeForResolutionAtIndex(file, index)); if (!resolution) { continue; } const isFromNodeModulesSearch = resolution.isExternalLibraryImport; - const isJsFile = !resolutionExtensionIsTSOrJson(resolution.extension); + const isJsFile = !ts.resolutionExtensionIsTSOrJson(resolution.extension); const isJsFileFromNodeModules = isFromNodeModulesSearch && isJsFile; const resolvedFileName = resolution.resolvedFileName; @@ -3273,20 +3184,16 @@ namespace ts { && !optionsForFile.noResolve && index < file.imports.length && !elideImport - && !(isJsFile && !getAllowJSCompilerOption(optionsForFile)) - && (isInJSFile(file.imports[index]) || !(file.imports[index].flags & NodeFlags.JSDoc)); + && !(isJsFile && !ts.getAllowJSCompilerOption(optionsForFile)) + && (ts.isInJSFile(file.imports[index]) || !(file.imports[index].flags & ts.NodeFlags.JSDoc)); if (elideImport) { modulesWithElidedImports.set(file.path, true); } else if (shouldAddFile) { - findSourceFile( - resolvedFileName, + findSourceFile(resolvedFileName, /*isDefaultLib*/ false, - /*ignoreNoDefaultLib*/ false, - { kind: FileIncludeKind.Import, file: file.path, index, }, - resolution.packageId, - ); + /*ignoreNoDefaultLib*/ false, { kind: ts.FileIncludeKind.Import, file: file.path, index, }, resolution.packageId); } if (isFromNodeModulesSearch) { @@ -3300,18 +3207,14 @@ namespace ts { } } - function checkSourceFilesBelongToPath(sourceFiles: readonly SourceFile[], rootDirectory: string): boolean { + function checkSourceFilesBelongToPath(sourceFiles: readonly ts.SourceFile[], rootDirectory: string): boolean { let allFilesBelongToPath = true; - const absoluteRootDirectoryPath = host.getCanonicalFileName(getNormalizedAbsolutePath(rootDirectory, currentDirectory)); + const absoluteRootDirectoryPath = host.getCanonicalFileName(ts.getNormalizedAbsolutePath(rootDirectory, currentDirectory)); for (const sourceFile of sourceFiles) { if (!sourceFile.isDeclarationFile) { - const absoluteSourceFilePath = host.getCanonicalFileName(getNormalizedAbsolutePath(sourceFile.fileName, currentDirectory)); + const absoluteSourceFilePath = host.getCanonicalFileName(ts.getNormalizedAbsolutePath(sourceFile.fileName, currentDirectory)); if (absoluteSourceFilePath.indexOf(absoluteRootDirectoryPath) !== 0) { - addProgramDiagnosticExplainingFile( - sourceFile, - Diagnostics.File_0_is_not_under_rootDir_1_rootDir_is_expected_to_contain_all_source_files, - [sourceFile.fileName, rootDirectory] - ); + addProgramDiagnosticExplainingFile(sourceFile, ts.Diagnostics.File_0_is_not_under_rootDir_1_rootDir_is_expected_to_contain_all_source_files, [sourceFile.fileName, rootDirectory]); allFilesBelongToPath = false; } } @@ -3320,9 +3223,9 @@ namespace ts { return allFilesBelongToPath; } - function parseProjectReferenceConfigFile(ref: ProjectReference): ResolvedProjectReference | undefined { + function parseProjectReferenceConfigFile(ref: ts.ProjectReference): ts.ResolvedProjectReference | undefined { if (!projectReferenceRedirects) { - projectReferenceRedirects = new Map(); + projectReferenceRedirects = new ts.Map(); } // The actual filename (i.e. add "/tsconfig.json" if necessary) @@ -3333,8 +3236,8 @@ namespace ts { return fromCache || undefined; } - let commandLine: ParsedCommandLine | undefined; - let sourceFile: JsonSourceFile | undefined; + let commandLine: ts.ParsedCommandLine | undefined; + let sourceFile: ts.JsonSourceFile | undefined; if (host.getParsedCommandLine) { commandLine = host.getParsedCommandLine(refPath); if (!commandLine) { @@ -3342,27 +3245,27 @@ namespace ts { projectReferenceRedirects.set(sourceFilePath, false); return undefined; } - sourceFile = Debug.checkDefined(commandLine.options.configFile); - Debug.assert(!sourceFile.path || sourceFile.path === sourceFilePath); + sourceFile = ts.Debug.checkDefined(commandLine.options.configFile); + ts.Debug.assert(!sourceFile.path || sourceFile.path === sourceFilePath); addFileToFilesByName(sourceFile, sourceFilePath, /*redirectedPath*/ undefined); } else { // An absolute path pointing to the containing directory of the config file - const basePath = getNormalizedAbsolutePath(getDirectoryPath(refPath), host.getCurrentDirectory()); - sourceFile = host.getSourceFile(refPath, ScriptTarget.JSON) as JsonSourceFile | undefined; + const basePath = ts.getNormalizedAbsolutePath(ts.getDirectoryPath(refPath), host.getCurrentDirectory()); + sourceFile = host.getSourceFile(refPath, ts.ScriptTarget.JSON) as ts.JsonSourceFile | undefined; addFileToFilesByName(sourceFile, sourceFilePath, /*redirectedPath*/ undefined); if (sourceFile === undefined) { projectReferenceRedirects.set(sourceFilePath, false); return undefined; } - commandLine = parseJsonSourceFileConfigFileContent(sourceFile, configParsingHost, basePath, /*existingOptions*/ undefined, refPath); + commandLine = ts.parseJsonSourceFileConfigFileContent(sourceFile, configParsingHost, basePath, /*existingOptions*/ undefined, refPath); } sourceFile.fileName = refPath; sourceFile.path = sourceFilePath; sourceFile.resolvedPath = sourceFilePath; sourceFile.originalFileName = refPath; - const resolvedRef: ResolvedProjectReference = { commandLine, sourceFile }; + const resolvedRef: ts.ResolvedProjectReference = { commandLine, sourceFile }; projectReferenceRedirects.set(sourceFilePath, resolvedRef); if (commandLine.projectReferences) { resolvedRef.references = commandLine.projectReferences.map(parseProjectReferenceConfigFile); @@ -3371,187 +3274,181 @@ namespace ts { } function verifyCompilerOptions() { - if (options.strictPropertyInitialization && !getStrictOptionValue(options, "strictNullChecks")) { - createDiagnosticForOptionName(Diagnostics.Option_0_cannot_be_specified_without_specifying_option_1, "strictPropertyInitialization", "strictNullChecks"); + if (options.strictPropertyInitialization && !ts.getStrictOptionValue(options, "strictNullChecks")) { + createDiagnosticForOptionName(ts.Diagnostics.Option_0_cannot_be_specified_without_specifying_option_1, "strictPropertyInitialization", "strictNullChecks"); } - if (options.exactOptionalPropertyTypes && !getStrictOptionValue(options, "strictNullChecks")) { - createDiagnosticForOptionName(Diagnostics.Option_0_cannot_be_specified_without_specifying_option_1, "exactOptionalPropertyTypes", "strictNullChecks"); + if (options.exactOptionalPropertyTypes && !ts.getStrictOptionValue(options, "strictNullChecks")) { + createDiagnosticForOptionName(ts.Diagnostics.Option_0_cannot_be_specified_without_specifying_option_1, "exactOptionalPropertyTypes", "strictNullChecks"); } if (options.isolatedModules) { if (options.out) { - createDiagnosticForOptionName(Diagnostics.Option_0_cannot_be_specified_with_option_1, "out", "isolatedModules"); + createDiagnosticForOptionName(ts.Diagnostics.Option_0_cannot_be_specified_with_option_1, "out", "isolatedModules"); } if (options.outFile) { - createDiagnosticForOptionName(Diagnostics.Option_0_cannot_be_specified_with_option_1, "outFile", "isolatedModules"); + createDiagnosticForOptionName(ts.Diagnostics.Option_0_cannot_be_specified_with_option_1, "outFile", "isolatedModules"); } } if (options.inlineSourceMap) { if (options.sourceMap) { - createDiagnosticForOptionName(Diagnostics.Option_0_cannot_be_specified_with_option_1, "sourceMap", "inlineSourceMap"); + createDiagnosticForOptionName(ts.Diagnostics.Option_0_cannot_be_specified_with_option_1, "sourceMap", "inlineSourceMap"); } if (options.mapRoot) { - createDiagnosticForOptionName(Diagnostics.Option_0_cannot_be_specified_with_option_1, "mapRoot", "inlineSourceMap"); + createDiagnosticForOptionName(ts.Diagnostics.Option_0_cannot_be_specified_with_option_1, "mapRoot", "inlineSourceMap"); } } if (options.composite) { if (options.declaration === false) { - createDiagnosticForOptionName(Diagnostics.Composite_projects_may_not_disable_declaration_emit, "declaration"); + createDiagnosticForOptionName(ts.Diagnostics.Composite_projects_may_not_disable_declaration_emit, "declaration"); } if (options.incremental === false) { - createDiagnosticForOptionName(Diagnostics.Composite_projects_may_not_disable_incremental_compilation, "declaration"); + createDiagnosticForOptionName(ts.Diagnostics.Composite_projects_may_not_disable_incremental_compilation, "declaration"); } } - const outputFile = outFile(options); + const outputFile = ts.outFile(options); if (options.tsBuildInfoFile) { - if (!isIncrementalCompilation(options)) { - createDiagnosticForOptionName(Diagnostics.Option_0_cannot_be_specified_without_specifying_option_1_or_option_2, "tsBuildInfoFile", "incremental", "composite"); + if (!ts.isIncrementalCompilation(options)) { + createDiagnosticForOptionName(ts.Diagnostics.Option_0_cannot_be_specified_without_specifying_option_1_or_option_2, "tsBuildInfoFile", "incremental", "composite"); } } else if (options.incremental && !outputFile && !options.configFilePath) { - programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Option_incremental_can_only_be_specified_using_tsconfig_emitting_to_single_file_or_when_option_tsBuildInfoFile_is_specified)); + programDiagnostics.add(ts.createCompilerDiagnostic(ts.Diagnostics.Option_incremental_can_only_be_specified_using_tsconfig_emitting_to_single_file_or_when_option_tsBuildInfoFile_is_specified)); } verifyProjectReferences(); // List of collected files is complete; validate exhautiveness if this is a project with a file list if (options.composite) { - const rootPaths = new Set(rootNames.map(toPath)); + const rootPaths = new ts.Set(rootNames.map(toPath)); for (const file of files) { // Ignore file that is not emitted - if (sourceFileMayBeEmitted(file, program) && !rootPaths.has(file.path)) { - addProgramDiagnosticExplainingFile( - file, - Diagnostics.File_0_is_not_listed_within_the_file_list_of_project_1_Projects_must_list_all_files_or_use_an_include_pattern, - [file.fileName, options.configFilePath || ""] - ); + if (ts.sourceFileMayBeEmitted(file, program) && !rootPaths.has(file.path)) { + addProgramDiagnosticExplainingFile(file, ts.Diagnostics.File_0_is_not_listed_within_the_file_list_of_project_1_Projects_must_list_all_files_or_use_an_include_pattern, [file.fileName, options.configFilePath || ""]); } } } if (options.paths) { for (const key in options.paths) { - if (!hasProperty(options.paths, key)) { + if (!ts.hasProperty(options.paths, key)) { continue; } - if (!hasZeroOrOneAsteriskCharacter(key)) { - createDiagnosticForOptionPaths(/*onKey*/ true, key, Diagnostics.Pattern_0_can_have_at_most_one_Asterisk_character, key); + if (!ts.hasZeroOrOneAsteriskCharacter(key)) { + createDiagnosticForOptionPaths(/*onKey*/ true, key, ts.Diagnostics.Pattern_0_can_have_at_most_one_Asterisk_character, key); } - if (isArray(options.paths[key])) { + if (ts.isArray(options.paths[key])) { const len = options.paths[key].length; if (len === 0) { - createDiagnosticForOptionPaths(/*onKey*/ false, key, Diagnostics.Substitutions_for_pattern_0_shouldn_t_be_an_empty_array, key); + createDiagnosticForOptionPaths(/*onKey*/ false, key, ts.Diagnostics.Substitutions_for_pattern_0_shouldn_t_be_an_empty_array, key); } for (let i = 0; i < len; i++) { const subst = options.paths[key][i]; const typeOfSubst = typeof subst; if (typeOfSubst === "string") { - if (!hasZeroOrOneAsteriskCharacter(subst)) { - createDiagnosticForOptionPathKeyValue(key, i, Diagnostics.Substitution_0_in_pattern_1_can_have_at_most_one_Asterisk_character, subst, key); + if (!ts.hasZeroOrOneAsteriskCharacter(subst)) { + createDiagnosticForOptionPathKeyValue(key, i, ts.Diagnostics.Substitution_0_in_pattern_1_can_have_at_most_one_Asterisk_character, subst, key); } - if (!options.baseUrl && !pathIsRelative(subst) && !pathIsAbsolute(subst)) { - createDiagnosticForOptionPathKeyValue(key, i, Diagnostics.Non_relative_paths_are_not_allowed_when_baseUrl_is_not_set_Did_you_forget_a_leading_Slash); + if (!options.baseUrl && !ts.pathIsRelative(subst) && !ts.pathIsAbsolute(subst)) { + createDiagnosticForOptionPathKeyValue(key, i, ts.Diagnostics.Non_relative_paths_are_not_allowed_when_baseUrl_is_not_set_Did_you_forget_a_leading_Slash); } } else { - createDiagnosticForOptionPathKeyValue(key, i, Diagnostics.Substitution_0_for_pattern_1_has_incorrect_type_expected_string_got_2, subst, key, typeOfSubst); + createDiagnosticForOptionPathKeyValue(key, i, ts.Diagnostics.Substitution_0_for_pattern_1_has_incorrect_type_expected_string_got_2, subst, key, typeOfSubst); } } } else { - createDiagnosticForOptionPaths(/*onKey*/ false, key, Diagnostics.Substitutions_for_pattern_0_should_be_an_array, key); + createDiagnosticForOptionPaths(/*onKey*/ false, key, ts.Diagnostics.Substitutions_for_pattern_0_should_be_an_array, key); } } } if (!options.sourceMap && !options.inlineSourceMap) { if (options.inlineSources) { - createDiagnosticForOptionName(Diagnostics.Option_0_can_only_be_used_when_either_option_inlineSourceMap_or_option_sourceMap_is_provided, "inlineSources"); + createDiagnosticForOptionName(ts.Diagnostics.Option_0_can_only_be_used_when_either_option_inlineSourceMap_or_option_sourceMap_is_provided, "inlineSources"); } if (options.sourceRoot) { - createDiagnosticForOptionName(Diagnostics.Option_0_can_only_be_used_when_either_option_inlineSourceMap_or_option_sourceMap_is_provided, "sourceRoot"); + createDiagnosticForOptionName(ts.Diagnostics.Option_0_can_only_be_used_when_either_option_inlineSourceMap_or_option_sourceMap_is_provided, "sourceRoot"); } } if (options.out && options.outFile) { - createDiagnosticForOptionName(Diagnostics.Option_0_cannot_be_specified_with_option_1, "out", "outFile"); + createDiagnosticForOptionName(ts.Diagnostics.Option_0_cannot_be_specified_with_option_1, "out", "outFile"); } if (options.mapRoot && !(options.sourceMap || options.declarationMap)) { // Error to specify --mapRoot without --sourcemap - createDiagnosticForOptionName(Diagnostics.Option_0_cannot_be_specified_without_specifying_option_1_or_option_2, "mapRoot", "sourceMap", "declarationMap"); + createDiagnosticForOptionName(ts.Diagnostics.Option_0_cannot_be_specified_without_specifying_option_1_or_option_2, "mapRoot", "sourceMap", "declarationMap"); } if (options.declarationDir) { - if (!getEmitDeclarations(options)) { - createDiagnosticForOptionName(Diagnostics.Option_0_cannot_be_specified_without_specifying_option_1_or_option_2, "declarationDir", "declaration", "composite"); + if (!ts.getEmitDeclarations(options)) { + createDiagnosticForOptionName(ts.Diagnostics.Option_0_cannot_be_specified_without_specifying_option_1_or_option_2, "declarationDir", "declaration", "composite"); } if (outputFile) { - createDiagnosticForOptionName(Diagnostics.Option_0_cannot_be_specified_with_option_1, "declarationDir", options.out ? "out" : "outFile"); + createDiagnosticForOptionName(ts.Diagnostics.Option_0_cannot_be_specified_with_option_1, "declarationDir", options.out ? "out" : "outFile"); } } - if (options.declarationMap && !getEmitDeclarations(options)) { - createDiagnosticForOptionName(Diagnostics.Option_0_cannot_be_specified_without_specifying_option_1_or_option_2, "declarationMap", "declaration", "composite"); + if (options.declarationMap && !ts.getEmitDeclarations(options)) { + createDiagnosticForOptionName(ts.Diagnostics.Option_0_cannot_be_specified_without_specifying_option_1_or_option_2, "declarationMap", "declaration", "composite"); } if (options.lib && options.noLib) { - createDiagnosticForOptionName(Diagnostics.Option_0_cannot_be_specified_with_option_1, "lib", "noLib"); + createDiagnosticForOptionName(ts.Diagnostics.Option_0_cannot_be_specified_with_option_1, "lib", "noLib"); } - if (options.noImplicitUseStrict && getStrictOptionValue(options, "alwaysStrict")) { - createDiagnosticForOptionName(Diagnostics.Option_0_cannot_be_specified_with_option_1, "noImplicitUseStrict", "alwaysStrict"); + if (options.noImplicitUseStrict && ts.getStrictOptionValue(options, "alwaysStrict")) { + createDiagnosticForOptionName(ts.Diagnostics.Option_0_cannot_be_specified_with_option_1, "noImplicitUseStrict", "alwaysStrict"); } - const languageVersion = getEmitScriptTarget(options); - - const firstNonAmbientExternalModuleSourceFile = find(files, f => isExternalModule(f) && !f.isDeclarationFile); + const languageVersion = ts.getEmitScriptTarget(options); + const firstNonAmbientExternalModuleSourceFile = ts.find(files, f => ts.isExternalModule(f) && !f.isDeclarationFile); if (options.isolatedModules) { - if (options.module === ModuleKind.None && languageVersion < ScriptTarget.ES2015) { - createDiagnosticForOptionName(Diagnostics.Option_isolatedModules_can_only_be_used_when_either_option_module_is_provided_or_option_target_is_ES2015_or_higher, "isolatedModules", "target"); + if (options.module === ts.ModuleKind.None && languageVersion < ts.ScriptTarget.ES2015) { + createDiagnosticForOptionName(ts.Diagnostics.Option_isolatedModules_can_only_be_used_when_either_option_module_is_provided_or_option_target_is_ES2015_or_higher, "isolatedModules", "target"); } if (options.preserveConstEnums === false) { - createDiagnosticForOptionName(Diagnostics.Option_preserveConstEnums_cannot_be_disabled_when_isolatedModules_is_enabled, "preserveConstEnums", "isolatedModules"); + createDiagnosticForOptionName(ts.Diagnostics.Option_preserveConstEnums_cannot_be_disabled_when_isolatedModules_is_enabled, "preserveConstEnums", "isolatedModules"); } - const firstNonExternalModuleSourceFile = find(files, f => !isExternalModule(f) && !isSourceFileJS(f) && !f.isDeclarationFile && f.scriptKind !== ScriptKind.JSON); + const firstNonExternalModuleSourceFile = ts.find(files, f => !ts.isExternalModule(f) && !ts.isSourceFileJS(f) && !f.isDeclarationFile && f.scriptKind !== ts.ScriptKind.JSON); if (firstNonExternalModuleSourceFile) { - const span = getErrorSpanForNode(firstNonExternalModuleSourceFile, firstNonExternalModuleSourceFile); - programDiagnostics.add(createFileDiagnostic(firstNonExternalModuleSourceFile, span.start, span.length, - Diagnostics._0_cannot_be_compiled_under_isolatedModules_because_it_is_considered_a_global_script_file_Add_an_import_export_or_an_empty_export_statement_to_make_it_a_module, getBaseFileName(firstNonExternalModuleSourceFile.fileName))); + const span = ts.getErrorSpanForNode(firstNonExternalModuleSourceFile, firstNonExternalModuleSourceFile); + programDiagnostics.add(ts.createFileDiagnostic(firstNonExternalModuleSourceFile, span.start, span.length, ts.Diagnostics._0_cannot_be_compiled_under_isolatedModules_because_it_is_considered_a_global_script_file_Add_an_import_export_or_an_empty_export_statement_to_make_it_a_module, ts.getBaseFileName(firstNonExternalModuleSourceFile.fileName))); } } - else if (firstNonAmbientExternalModuleSourceFile && languageVersion < ScriptTarget.ES2015 && options.module === ModuleKind.None) { + else if (firstNonAmbientExternalModuleSourceFile && languageVersion < ts.ScriptTarget.ES2015 && options.module === ts.ModuleKind.None) { // We cannot use createDiagnosticFromNode because nodes do not have parents yet - const span = getErrorSpanForNode(firstNonAmbientExternalModuleSourceFile, typeof firstNonAmbientExternalModuleSourceFile.externalModuleIndicator === "boolean" ? firstNonAmbientExternalModuleSourceFile : firstNonAmbientExternalModuleSourceFile.externalModuleIndicator!); - programDiagnostics.add(createFileDiagnostic(firstNonAmbientExternalModuleSourceFile, span.start, span.length, Diagnostics.Cannot_use_imports_exports_or_module_augmentations_when_module_is_none)); + const span = ts.getErrorSpanForNode(firstNonAmbientExternalModuleSourceFile, typeof firstNonAmbientExternalModuleSourceFile.externalModuleIndicator === "boolean" ? firstNonAmbientExternalModuleSourceFile : firstNonAmbientExternalModuleSourceFile.externalModuleIndicator!); + programDiagnostics.add(ts.createFileDiagnostic(firstNonAmbientExternalModuleSourceFile, span.start, span.length, ts.Diagnostics.Cannot_use_imports_exports_or_module_augmentations_when_module_is_none)); } // Cannot specify module gen that isn't amd or system with --out if (outputFile && !options.emitDeclarationOnly) { - if (options.module && !(options.module === ModuleKind.AMD || options.module === ModuleKind.System)) { - createDiagnosticForOptionName(Diagnostics.Only_amd_and_system_modules_are_supported_alongside_0, options.out ? "out" : "outFile", "module"); + if (options.module && !(options.module === ts.ModuleKind.AMD || options.module === ts.ModuleKind.System)) { + createDiagnosticForOptionName(ts.Diagnostics.Only_amd_and_system_modules_are_supported_alongside_0, options.out ? "out" : "outFile", "module"); } else if (options.module === undefined && firstNonAmbientExternalModuleSourceFile) { - const span = getErrorSpanForNode(firstNonAmbientExternalModuleSourceFile, typeof firstNonAmbientExternalModuleSourceFile.externalModuleIndicator === "boolean" ? firstNonAmbientExternalModuleSourceFile : firstNonAmbientExternalModuleSourceFile.externalModuleIndicator!); - programDiagnostics.add(createFileDiagnostic(firstNonAmbientExternalModuleSourceFile, span.start, span.length, Diagnostics.Cannot_compile_modules_using_option_0_unless_the_module_flag_is_amd_or_system, options.out ? "out" : "outFile")); + const span = ts.getErrorSpanForNode(firstNonAmbientExternalModuleSourceFile, typeof firstNonAmbientExternalModuleSourceFile.externalModuleIndicator === "boolean" ? firstNonAmbientExternalModuleSourceFile : firstNonAmbientExternalModuleSourceFile.externalModuleIndicator!); + programDiagnostics.add(ts.createFileDiagnostic(firstNonAmbientExternalModuleSourceFile, span.start, span.length, ts.Diagnostics.Cannot_compile_modules_using_option_0_unless_the_module_flag_is_amd_or_system, options.out ? "out" : "outFile")); } } if (options.resolveJsonModule) { - if (getEmitModuleResolutionKind(options) !== ModuleResolutionKind.NodeJs && - getEmitModuleResolutionKind(options) !== ModuleResolutionKind.Node16 && - getEmitModuleResolutionKind(options) !== ModuleResolutionKind.NodeNext) { - createDiagnosticForOptionName(Diagnostics.Option_resolveJsonModule_cannot_be_specified_without_node_module_resolution_strategy, "resolveJsonModule"); + if (ts.getEmitModuleResolutionKind(options) !== ts.ModuleResolutionKind.NodeJs && + ts.getEmitModuleResolutionKind(options) !== ts.ModuleResolutionKind.Node16 && + ts.getEmitModuleResolutionKind(options) !== ts.ModuleResolutionKind.NodeNext) { + createDiagnosticForOptionName(ts.Diagnostics.Option_resolveJsonModule_cannot_be_specified_without_node_module_resolution_strategy, "resolveJsonModule"); } // Any emit other than common js, amd, es2015 or esnext is error - else if (!hasJsonModuleEmitEnabled(options)) { - createDiagnosticForOptionName(Diagnostics.Option_resolveJsonModule_can_only_be_specified_when_module_code_generation_is_commonjs_amd_es2015_or_esNext, "resolveJsonModule", "module"); + else if (!ts.hasJsonModuleEmitEnabled(options)) { + createDiagnosticForOptionName(ts.Diagnostics.Option_resolveJsonModule_can_only_be_specified_when_module_code_generation_is_commonjs_amd_es2015_or_esNext, "resolveJsonModule", "module"); } } @@ -3566,82 +3463,82 @@ namespace ts { const dir = getCommonSourceDirectory(); // If we failed to find a good common directory, but outDir is specified and at least one of our files is on a windows drive/URL/other resource, add a failure - if (options.outDir && dir === "" && files.some(file => getRootLength(file.fileName) > 1)) { - createDiagnosticForOptionName(Diagnostics.Cannot_find_the_common_subdirectory_path_for_the_input_files, "outDir"); + if (options.outDir && dir === "" && files.some(file => ts.getRootLength(file.fileName) > 1)) { + createDiagnosticForOptionName(ts.Diagnostics.Cannot_find_the_common_subdirectory_path_for_the_input_files, "outDir"); } } - if (options.useDefineForClassFields && languageVersion === ScriptTarget.ES3) { - createDiagnosticForOptionName(Diagnostics.Option_0_cannot_be_specified_when_option_target_is_ES3, "useDefineForClassFields"); + if (options.useDefineForClassFields && languageVersion === ts.ScriptTarget.ES3) { + createDiagnosticForOptionName(ts.Diagnostics.Option_0_cannot_be_specified_when_option_target_is_ES3, "useDefineForClassFields"); } - if (options.checkJs && !getAllowJSCompilerOption(options)) { - programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Option_0_cannot_be_specified_without_specifying_option_1, "checkJs", "allowJs")); + if (options.checkJs && !ts.getAllowJSCompilerOption(options)) { + programDiagnostics.add(ts.createCompilerDiagnostic(ts.Diagnostics.Option_0_cannot_be_specified_without_specifying_option_1, "checkJs", "allowJs")); } if (options.emitDeclarationOnly) { - if (!getEmitDeclarations(options)) { - createDiagnosticForOptionName(Diagnostics.Option_0_cannot_be_specified_without_specifying_option_1_or_option_2, "emitDeclarationOnly", "declaration", "composite"); + if (!ts.getEmitDeclarations(options)) { + createDiagnosticForOptionName(ts.Diagnostics.Option_0_cannot_be_specified_without_specifying_option_1_or_option_2, "emitDeclarationOnly", "declaration", "composite"); } if (options.noEmit) { - createDiagnosticForOptionName(Diagnostics.Option_0_cannot_be_specified_with_option_1, "emitDeclarationOnly", "noEmit"); + createDiagnosticForOptionName(ts.Diagnostics.Option_0_cannot_be_specified_with_option_1, "emitDeclarationOnly", "noEmit"); } } if (options.emitDecoratorMetadata && !options.experimentalDecorators) { - createDiagnosticForOptionName(Diagnostics.Option_0_cannot_be_specified_without_specifying_option_1, "emitDecoratorMetadata", "experimentalDecorators"); + createDiagnosticForOptionName(ts.Diagnostics.Option_0_cannot_be_specified_without_specifying_option_1, "emitDecoratorMetadata", "experimentalDecorators"); } if (options.jsxFactory) { if (options.reactNamespace) { - createDiagnosticForOptionName(Diagnostics.Option_0_cannot_be_specified_with_option_1, "reactNamespace", "jsxFactory"); + createDiagnosticForOptionName(ts.Diagnostics.Option_0_cannot_be_specified_with_option_1, "reactNamespace", "jsxFactory"); } - if (options.jsx === JsxEmit.ReactJSX || options.jsx === JsxEmit.ReactJSXDev) { - createDiagnosticForOptionName(Diagnostics.Option_0_cannot_be_specified_when_option_jsx_is_1, "jsxFactory", inverseJsxOptionMap.get("" + options.jsx)); + if (options.jsx === ts.JsxEmit.ReactJSX || options.jsx === ts.JsxEmit.ReactJSXDev) { + createDiagnosticForOptionName(ts.Diagnostics.Option_0_cannot_be_specified_when_option_jsx_is_1, "jsxFactory", ts.inverseJsxOptionMap.get("" + options.jsx)); } - if (!parseIsolatedEntityName(options.jsxFactory, languageVersion)) { - createOptionValueDiagnostic("jsxFactory", Diagnostics.Invalid_value_for_jsxFactory_0_is_not_a_valid_identifier_or_qualified_name, options.jsxFactory); + if (!ts.parseIsolatedEntityName(options.jsxFactory, languageVersion)) { + createOptionValueDiagnostic("jsxFactory", ts.Diagnostics.Invalid_value_for_jsxFactory_0_is_not_a_valid_identifier_or_qualified_name, options.jsxFactory); } } - else if (options.reactNamespace && !isIdentifierText(options.reactNamespace, languageVersion)) { - createOptionValueDiagnostic("reactNamespace", Diagnostics.Invalid_value_for_reactNamespace_0_is_not_a_valid_identifier, options.reactNamespace); + else if (options.reactNamespace && !ts.isIdentifierText(options.reactNamespace, languageVersion)) { + createOptionValueDiagnostic("reactNamespace", ts.Diagnostics.Invalid_value_for_reactNamespace_0_is_not_a_valid_identifier, options.reactNamespace); } if (options.jsxFragmentFactory) { if (!options.jsxFactory) { - createDiagnosticForOptionName(Diagnostics.Option_0_cannot_be_specified_without_specifying_option_1, "jsxFragmentFactory", "jsxFactory"); + createDiagnosticForOptionName(ts.Diagnostics.Option_0_cannot_be_specified_without_specifying_option_1, "jsxFragmentFactory", "jsxFactory"); } - if (options.jsx === JsxEmit.ReactJSX || options.jsx === JsxEmit.ReactJSXDev) { - createDiagnosticForOptionName(Diagnostics.Option_0_cannot_be_specified_when_option_jsx_is_1, "jsxFragmentFactory", inverseJsxOptionMap.get("" + options.jsx)); + if (options.jsx === ts.JsxEmit.ReactJSX || options.jsx === ts.JsxEmit.ReactJSXDev) { + createDiagnosticForOptionName(ts.Diagnostics.Option_0_cannot_be_specified_when_option_jsx_is_1, "jsxFragmentFactory", ts.inverseJsxOptionMap.get("" + options.jsx)); } - if (!parseIsolatedEntityName(options.jsxFragmentFactory, languageVersion)) { - createOptionValueDiagnostic("jsxFragmentFactory", Diagnostics.Invalid_value_for_jsxFragmentFactory_0_is_not_a_valid_identifier_or_qualified_name, options.jsxFragmentFactory); + if (!ts.parseIsolatedEntityName(options.jsxFragmentFactory, languageVersion)) { + createOptionValueDiagnostic("jsxFragmentFactory", ts.Diagnostics.Invalid_value_for_jsxFragmentFactory_0_is_not_a_valid_identifier_or_qualified_name, options.jsxFragmentFactory); } } if (options.reactNamespace) { - if (options.jsx === JsxEmit.ReactJSX || options.jsx === JsxEmit.ReactJSXDev) { - createDiagnosticForOptionName(Diagnostics.Option_0_cannot_be_specified_when_option_jsx_is_1, "reactNamespace", inverseJsxOptionMap.get("" + options.jsx)); + if (options.jsx === ts.JsxEmit.ReactJSX || options.jsx === ts.JsxEmit.ReactJSXDev) { + createDiagnosticForOptionName(ts.Diagnostics.Option_0_cannot_be_specified_when_option_jsx_is_1, "reactNamespace", ts.inverseJsxOptionMap.get("" + options.jsx)); } } if (options.jsxImportSource) { - if (options.jsx === JsxEmit.React) { - createDiagnosticForOptionName(Diagnostics.Option_0_cannot_be_specified_when_option_jsx_is_1, "jsxImportSource", inverseJsxOptionMap.get("" + options.jsx)); + if (options.jsx === ts.JsxEmit.React) { + createDiagnosticForOptionName(ts.Diagnostics.Option_0_cannot_be_specified_when_option_jsx_is_1, "jsxImportSource", ts.inverseJsxOptionMap.get("" + options.jsx)); } } - if (options.preserveValueImports && getEmitModuleKind(options) < ModuleKind.ES2015) { - createOptionValueDiagnostic("importsNotUsedAsValues", Diagnostics.Option_preserveValueImports_can_only_be_used_when_module_is_set_to_es2015_or_later); + if (options.preserveValueImports && ts.getEmitModuleKind(options) < ts.ModuleKind.ES2015) { + createOptionValueDiagnostic("importsNotUsedAsValues", ts.Diagnostics.Option_preserveValueImports_can_only_be_used_when_module_is_set_to_es2015_or_later); } // If the emit is enabled make sure that every output file is unique and not overwriting any of the input files if (!options.noEmit && !options.suppressOutputPathCheck) { const emitHost = getEmitHost(); - const emitFilesSeen = new Set(); - forEachEmittedFile(emitHost, (emitFileNames) => { + const emitFilesSeen = new ts.Set(); + ts.forEachEmittedFile(emitHost, (emitFileNames) => { if (!options.emitDeclarationOnly) { verifyEmitFilePath(emitFileNames.jsFilePath, emitFilesSeen); } @@ -3650,25 +3547,25 @@ namespace ts { } // Verify that all the emit files are unique and don't overwrite input files - function verifyEmitFilePath(emitFileName: string | undefined, emitFilesSeen: Set) { + function verifyEmitFilePath(emitFileName: string | undefined, emitFilesSeen: ts.Set) { if (emitFileName) { const emitFilePath = toPath(emitFileName); // Report error if the output overwrites input file if (filesByName.has(emitFilePath)) { - let chain: DiagnosticMessageChain | undefined; + let chain: ts.DiagnosticMessageChain | undefined; if (!options.configFilePath) { // The program is from either an inferred project or an external project - chain = chainDiagnosticMessages(/*details*/ undefined, Diagnostics.Adding_a_tsconfig_json_file_will_help_organize_projects_that_contain_both_TypeScript_and_JavaScript_files_Learn_more_at_https_Colon_Slash_Slashaka_ms_Slashtsconfig); + chain = ts.chainDiagnosticMessages(/*details*/ undefined, ts.Diagnostics.Adding_a_tsconfig_json_file_will_help_organize_projects_that_contain_both_TypeScript_and_JavaScript_files_Learn_more_at_https_Colon_Slash_Slashaka_ms_Slashtsconfig); } - chain = chainDiagnosticMessages(chain, Diagnostics.Cannot_write_file_0_because_it_would_overwrite_input_file, emitFileName); - blockEmittingOfFile(emitFileName, createCompilerDiagnosticFromMessageChain(chain)); + chain = ts.chainDiagnosticMessages(chain, ts.Diagnostics.Cannot_write_file_0_because_it_would_overwrite_input_file, emitFileName); + blockEmittingOfFile(emitFileName, ts.createCompilerDiagnosticFromMessageChain(chain)); } - const emitFileKey = !host.useCaseSensitiveFileNames() ? toFileNameLowerCase(emitFilePath) : emitFilePath; + const emitFileKey = !host.useCaseSensitiveFileNames() ? ts.toFileNameLowerCase(emitFilePath) : emitFilePath; // Report error if multiple files write into same file if (emitFilesSeen.has(emitFileKey)) { // Already seen the same emit file - report error - blockEmittingOfFile(emitFileName, createCompilerDiagnostic(Diagnostics.Cannot_write_file_0_because_it_would_be_overwritten_by_multiple_input_files, emitFileName)); + blockEmittingOfFile(emitFileName, ts.createCompilerDiagnostic(ts.Diagnostics.Cannot_write_file_0_because_it_would_be_overwritten_by_multiple_input_files, emitFileName)); } else { emitFilesSeen.add(emitFileKey); @@ -3677,39 +3574,42 @@ namespace ts { } } - function createDiagnosticExplainingFile(file: SourceFile | undefined, fileProcessingReason: FileIncludeReason | undefined, diagnostic: DiagnosticMessage, args: (string | number | undefined)[] | undefined): Diagnostic { - let fileIncludeReasons: DiagnosticMessageChain[] | undefined; - let relatedInfo: Diagnostic[] | undefined; + function createDiagnosticExplainingFile(file: ts.SourceFile | undefined, fileProcessingReason: ts.FileIncludeReason | undefined, diagnostic: ts.DiagnosticMessage, args: (string | number | undefined)[] | undefined): ts.Diagnostic { + let fileIncludeReasons: ts.DiagnosticMessageChain[] | undefined; + let relatedInfo: ts.Diagnostic[] | undefined; let locationReason = isReferencedFile(fileProcessingReason) ? fileProcessingReason : undefined; - if (file) fileReasons.get(file.path)?.forEach(processReason); - if (fileProcessingReason) processReason(fileProcessingReason); + if (file) + fileReasons.get(file.path)?.forEach(processReason); + if (fileProcessingReason) + processReason(fileProcessingReason); // If we have location and there is only one reason file is in which is the location, dont add details for file include - if (locationReason && fileIncludeReasons?.length === 1) fileIncludeReasons = undefined; + if (locationReason && fileIncludeReasons?.length === 1) + fileIncludeReasons = undefined; const location = locationReason && getReferencedFileLocation(getSourceFileByPath, locationReason); - const fileIncludeReasonDetails = fileIncludeReasons && chainDiagnosticMessages(fileIncludeReasons, Diagnostics.The_file_is_in_the_program_because_Colon); - const redirectInfo = file && explainIfFileIsRedirect(file); - const chain = chainDiagnosticMessages(redirectInfo ? fileIncludeReasonDetails ? [fileIncludeReasonDetails, ...redirectInfo] : redirectInfo : fileIncludeReasonDetails, diagnostic, ...args || emptyArray); + const fileIncludeReasonDetails = fileIncludeReasons && ts.chainDiagnosticMessages(fileIncludeReasons, ts.Diagnostics.The_file_is_in_the_program_because_Colon); + const redirectInfo = file && ts.explainIfFileIsRedirect(file); + const chain = ts.chainDiagnosticMessages(redirectInfo ? fileIncludeReasonDetails ? [fileIncludeReasonDetails, ...redirectInfo] : redirectInfo : fileIncludeReasonDetails, diagnostic, ...args || ts.emptyArray); return location && isReferenceFileLocation(location) ? - createFileDiagnosticFromMessageChain(location.file, location.pos, location.end - location.pos, chain, relatedInfo) : - createCompilerDiagnosticFromMessageChain(chain, relatedInfo); - - function processReason(reason: FileIncludeReason) { - (fileIncludeReasons ||= []).push(fileIncludeReasonToDiagnostics(program, reason)); + ts.createFileDiagnosticFromMessageChain(location.file, location.pos, location.end - location.pos, chain, relatedInfo) : + ts.createCompilerDiagnosticFromMessageChain(chain, relatedInfo); + function processReason(reason: ts.FileIncludeReason) { + (fileIncludeReasons ||= []).push(ts.fileIncludeReasonToDiagnostics(program, reason)); if (!locationReason && isReferencedFile(reason)) { // Report error at first reference file or file currently in processing and dont report in related information locationReason = reason; } else if (locationReason !== reason) { - relatedInfo = append(relatedInfo, fileIncludeReasonToRelatedInformation(reason)); + relatedInfo = ts.append(relatedInfo, fileIncludeReasonToRelatedInformation(reason)); } // Remove fileProcessingReason if its already included in fileReasons of the program - if (reason === fileProcessingReason) fileProcessingReason = undefined; + if (reason === fileProcessingReason) + fileProcessingReason = undefined; } } - function addFilePreprocessingFileExplainingDiagnostic(file: SourceFile | undefined, fileProcessingReason: FileIncludeReason, diagnostic: DiagnosticMessage, args?: (string | number | undefined)[]) { + function addFilePreprocessingFileExplainingDiagnostic(file: ts.SourceFile | undefined, fileProcessingReason: ts.FileIncludeReason, diagnostic: ts.DiagnosticMessage, args?: (string | number | undefined)[]) { (fileProcessingDiagnostics ||= []).push({ - kind: FilePreprocessingDiagnosticsKind.FilePreprocessingFileExplainingDiagnostic, + kind: ts.FilePreprocessingDiagnosticsKind.FilePreprocessingFileExplainingDiagnostic, file: file && file.path, fileProcessingReason, diagnostic, @@ -3717,108 +3617,96 @@ namespace ts { }); } - function addProgramDiagnosticExplainingFile(file: SourceFile, diagnostic: DiagnosticMessage, args?: (string | number | undefined)[]) { + function addProgramDiagnosticExplainingFile(file: ts.SourceFile, diagnostic: ts.DiagnosticMessage, args?: (string | number | undefined)[]) { programDiagnostics.add(createDiagnosticExplainingFile(file, /*fileProcessingReason*/ undefined, diagnostic, args)); } - function fileIncludeReasonToRelatedInformation(reason: FileIncludeReason): DiagnosticWithLocation | undefined { + function fileIncludeReasonToRelatedInformation(reason: ts.FileIncludeReason): ts.DiagnosticWithLocation | undefined { if (isReferencedFile(reason)) { const referenceLocation = getReferencedFileLocation(getSourceFileByPath, reason); - let message: DiagnosticMessage; + let message: ts.DiagnosticMessage; switch (reason.kind) { - case FileIncludeKind.Import: - message = Diagnostics.File_is_included_via_import_here; + case ts.FileIncludeKind.Import: + message = ts.Diagnostics.File_is_included_via_import_here; break; - case FileIncludeKind.ReferenceFile: - message = Diagnostics.File_is_included_via_reference_here; + case ts.FileIncludeKind.ReferenceFile: + message = ts.Diagnostics.File_is_included_via_reference_here; break; - case FileIncludeKind.TypeReferenceDirective: - message = Diagnostics.File_is_included_via_type_library_reference_here; + case ts.FileIncludeKind.TypeReferenceDirective: + message = ts.Diagnostics.File_is_included_via_type_library_reference_here; break; - case FileIncludeKind.LibReferenceDirective: - message = Diagnostics.File_is_included_via_library_reference_here; + case ts.FileIncludeKind.LibReferenceDirective: + message = ts.Diagnostics.File_is_included_via_library_reference_here; break; default: - Debug.assertNever(reason); + ts.Debug.assertNever(reason); } - return isReferenceFileLocation(referenceLocation) ? createFileDiagnostic( - referenceLocation.file, - referenceLocation.pos, - referenceLocation.end - referenceLocation.pos, - message, - ) : undefined; + return isReferenceFileLocation(referenceLocation) ? ts.createFileDiagnostic(referenceLocation.file, referenceLocation.pos, referenceLocation.end - referenceLocation.pos, message) : undefined; } - - if (!options.configFile) return undefined; - let configFileNode: Node | undefined; - let message: DiagnosticMessage; + if (!options.configFile) + return undefined; + let configFileNode: ts.Node | undefined; + let message: ts.DiagnosticMessage; switch (reason.kind) { - case FileIncludeKind.RootFile: - if (!options.configFile.configFileSpecs) return undefined; - const fileName = getNormalizedAbsolutePath(rootNames[reason.index], currentDirectory); - const matchedByFiles = getMatchedFileSpec(program, fileName); + case ts.FileIncludeKind.RootFile: + if (!options.configFile.configFileSpecs) + return undefined; + const fileName = ts.getNormalizedAbsolutePath(rootNames[reason.index], currentDirectory); + const matchedByFiles = ts.getMatchedFileSpec(program, fileName); if (matchedByFiles) { - configFileNode = getTsConfigPropArrayElementValue(options.configFile, "files", matchedByFiles); - message = Diagnostics.File_is_matched_by_files_list_specified_here; + configFileNode = ts.getTsConfigPropArrayElementValue(options.configFile, "files", matchedByFiles); + message = ts.Diagnostics.File_is_matched_by_files_list_specified_here; break; } - const matchedByInclude = getMatchedIncludeSpec(program, fileName); + const matchedByInclude = ts.getMatchedIncludeSpec(program, fileName); // Could be additional files specified as roots - if (!matchedByInclude || !isString(matchedByInclude)) return undefined; - configFileNode = getTsConfigPropArrayElementValue(options.configFile, "include", matchedByInclude); - message = Diagnostics.File_is_matched_by_include_pattern_specified_here; + if (!matchedByInclude || !ts.isString(matchedByInclude)) + return undefined; + configFileNode = ts.getTsConfigPropArrayElementValue(options.configFile, "include", matchedByInclude); + message = ts.Diagnostics.File_is_matched_by_include_pattern_specified_here; break; - case FileIncludeKind.SourceFromProjectReference: - case FileIncludeKind.OutputFromProjectReference: - const referencedResolvedRef = Debug.checkDefined(resolvedProjectReferences?.[reason.index]); - const referenceInfo = forEachProjectReference(projectReferences, resolvedProjectReferences, (resolvedRef, parent, index) => - resolvedRef === referencedResolvedRef ? { sourceFile: parent?.sourceFile || options.configFile!, index } : undefined - ); - if (!referenceInfo) return undefined; + case ts.FileIncludeKind.SourceFromProjectReference: + case ts.FileIncludeKind.OutputFromProjectReference: + const referencedResolvedRef = ts.Debug.checkDefined(resolvedProjectReferences?.[reason.index]); + const referenceInfo = forEachProjectReference(projectReferences, resolvedProjectReferences, (resolvedRef, parent, index) => resolvedRef === referencedResolvedRef ? { sourceFile: parent?.sourceFile || options.configFile!, index } : undefined); + if (!referenceInfo) + return undefined; const { sourceFile, index } = referenceInfo; - const referencesSyntax = firstDefined(getTsConfigPropArray(sourceFile as TsConfigSourceFile, "references"), - property => isArrayLiteralExpression(property.initializer) ? property.initializer : undefined); + const referencesSyntax = ts.firstDefined(ts.getTsConfigPropArray(sourceFile as ts.TsConfigSourceFile, "references"), property => ts.isArrayLiteralExpression(property.initializer) ? property.initializer : undefined); return referencesSyntax && referencesSyntax.elements.length > index ? - createDiagnosticForNodeInSourceFile( - sourceFile, - referencesSyntax.elements[index], - reason.kind === FileIncludeKind.OutputFromProjectReference ? - Diagnostics.File_is_output_from_referenced_project_specified_here : - Diagnostics.File_is_source_from_referenced_project_specified_here, - ) : + ts.createDiagnosticForNodeInSourceFile(sourceFile, referencesSyntax.elements[index], reason.kind === ts.FileIncludeKind.OutputFromProjectReference ? + ts.Diagnostics.File_is_output_from_referenced_project_specified_here : + ts.Diagnostics.File_is_source_from_referenced_project_specified_here) : undefined; - case FileIncludeKind.AutomaticTypeDirectiveFile: - if (!options.types) return undefined; + case ts.FileIncludeKind.AutomaticTypeDirectiveFile: + if (!options.types) + return undefined; configFileNode = getOptionsSyntaxByArrayElementValue("types", reason.typeReference); - message = Diagnostics.File_is_entry_point_of_type_library_specified_here; + message = ts.Diagnostics.File_is_entry_point_of_type_library_specified_here; break; - case FileIncludeKind.LibFile: + case ts.FileIncludeKind.LibFile: if (reason.index !== undefined) { configFileNode = getOptionsSyntaxByArrayElementValue("lib", options.lib![reason.index]); - message = Diagnostics.File_is_library_specified_here; + message = ts.Diagnostics.File_is_library_specified_here; break; } - const target = forEachEntry(targetOptionDeclaration.type, (value, key) => value === getEmitScriptTarget(options) ? key : undefined); + const target = ts.forEachEntry(ts.targetOptionDeclaration.type, (value, key) => value === ts.getEmitScriptTarget(options) ? key : undefined); configFileNode = target ? getOptionsSyntaxByValue("target", target) : undefined; - message = Diagnostics.File_is_default_library_for_target_specified_here; + message = ts.Diagnostics.File_is_default_library_for_target_specified_here; break; default: - Debug.assertNever(reason); + ts.Debug.assertNever(reason); } - return configFileNode && createDiagnosticForNodeInSourceFile( - options.configFile, - configFileNode, - message, - ); + return configFileNode && ts.createDiagnosticForNodeInSourceFile(options.configFile, configFileNode, message); } function verifyProjectReferences() { - const buildInfoPath = !options.suppressOutputPathCheck ? getTsBuildInfoEmitOutputFilePath(options) : undefined; + const buildInfoPath = !options.suppressOutputPathCheck ? ts.getTsBuildInfoEmitOutputFilePath(options) : undefined; forEachProjectReference(projectReferences, resolvedProjectReferences, (resolvedRef, parent, index) => { const ref = (parent ? parent.commandLine.projectReferences : projectReferences)![index]; - const parentFile = parent && parent.sourceFile as JsonSourceFile; + const parentFile = parent && parent.sourceFile as ts.JsonSourceFile; if (!resolvedRef) { - createDiagnosticForReference(parentFile, index, Diagnostics.File_0_not_found, ref.path); + createDiagnosticForReference(parentFile, index, ts.Diagnostics.File_0_not_found, ref.path); return; } const options = resolvedRef.commandLine.options; @@ -3826,37 +3714,39 @@ namespace ts { // ok to not have composite if the current program is container only const inputs = parent ? parent.commandLine.fileNames : rootNames; if (inputs.length) { - if (!options.composite) createDiagnosticForReference(parentFile, index, Diagnostics.Referenced_project_0_must_have_setting_composite_Colon_true, ref.path); - if (options.noEmit) createDiagnosticForReference(parentFile, index, Diagnostics.Referenced_project_0_may_not_disable_emit, ref.path); + if (!options.composite) + createDiagnosticForReference(parentFile, index, ts.Diagnostics.Referenced_project_0_must_have_setting_composite_Colon_true, ref.path); + if (options.noEmit) + createDiagnosticForReference(parentFile, index, ts.Diagnostics.Referenced_project_0_may_not_disable_emit, ref.path); } } if (ref.prepend) { - const out = outFile(options); + const out = ts.outFile(options); if (out) { if (!host.fileExists(out)) { - createDiagnosticForReference(parentFile, index, Diagnostics.Output_file_0_from_project_1_does_not_exist, out, ref.path); + createDiagnosticForReference(parentFile, index, ts.Diagnostics.Output_file_0_from_project_1_does_not_exist, out, ref.path); } } else { - createDiagnosticForReference(parentFile, index, Diagnostics.Cannot_prepend_project_0_because_it_does_not_have_outFile_set, ref.path); + createDiagnosticForReference(parentFile, index, ts.Diagnostics.Cannot_prepend_project_0_because_it_does_not_have_outFile_set, ref.path); } } - if (!parent && buildInfoPath && buildInfoPath === getTsBuildInfoEmitOutputFilePath(options)) { - createDiagnosticForReference(parentFile, index, Diagnostics.Cannot_write_file_0_because_it_will_overwrite_tsbuildinfo_file_generated_by_referenced_project_1, buildInfoPath, ref.path); + if (!parent && buildInfoPath && buildInfoPath === ts.getTsBuildInfoEmitOutputFilePath(options)) { + createDiagnosticForReference(parentFile, index, ts.Diagnostics.Cannot_write_file_0_because_it_will_overwrite_tsbuildinfo_file_generated_by_referenced_project_1, buildInfoPath, ref.path); hasEmitBlockingDiagnostics.set(toPath(buildInfoPath), true); } }); } - function createDiagnosticForOptionPathKeyValue(key: string, valueIndex: number, message: DiagnosticMessage, arg0?: string | number, arg1?: string | number, arg2?: string | number) { + function createDiagnosticForOptionPathKeyValue(key: string, valueIndex: number, message: ts.DiagnosticMessage, arg0?: string | number, arg1?: string | number, arg2?: string | number) { let needCompilerDiagnostic = true; const pathsSyntax = getOptionPathsSyntax(); for (const pathProp of pathsSyntax) { - if (isObjectLiteralExpression(pathProp.initializer)) { - for (const keyProps of getPropertyAssignment(pathProp.initializer, key)) { + if (ts.isObjectLiteralExpression(pathProp.initializer)) { + for (const keyProps of ts.getPropertyAssignment(pathProp.initializer, key)) { const initializer = keyProps.initializer; - if (isArrayLiteralExpression(initializer) && initializer.elements.length > valueIndex) { - programDiagnostics.add(createDiagnosticForNodeInSourceFile(options.configFile!, initializer.elements[valueIndex], message, arg0, arg1, arg2)); + if (ts.isArrayLiteralExpression(initializer) && initializer.elements.length > valueIndex) { + programDiagnostics.add(ts.createDiagnosticForNodeInSourceFile(options.configFile!, initializer.elements[valueIndex], message, arg0, arg1, arg2)); needCompilerDiagnostic = false; } } @@ -3864,81 +3754,78 @@ namespace ts { } if (needCompilerDiagnostic) { - programDiagnostics.add(createCompilerDiagnostic(message, arg0, arg1, arg2)); + programDiagnostics.add(ts.createCompilerDiagnostic(message, arg0, arg1, arg2)); } } - function createDiagnosticForOptionPaths(onKey: boolean, key: string, message: DiagnosticMessage, arg0: string | number) { + function createDiagnosticForOptionPaths(onKey: boolean, key: string, message: ts.DiagnosticMessage, arg0: string | number) { let needCompilerDiagnostic = true; const pathsSyntax = getOptionPathsSyntax(); for (const pathProp of pathsSyntax) { - if (isObjectLiteralExpression(pathProp.initializer) && - createOptionDiagnosticInObjectLiteralSyntax( - pathProp.initializer, onKey, key, /*key2*/ undefined, - message, arg0)) { + if (ts.isObjectLiteralExpression(pathProp.initializer) && + createOptionDiagnosticInObjectLiteralSyntax(pathProp.initializer, onKey, key, /*key2*/ undefined, message, arg0)) { needCompilerDiagnostic = false; } } if (needCompilerDiagnostic) { - programDiagnostics.add(createCompilerDiagnostic(message, arg0)); + programDiagnostics.add(ts.createCompilerDiagnostic(message, arg0)); } } function getOptionsSyntaxByName(name: string) { const compilerOptionsObjectLiteralSyntax = getCompilerOptionsObjectLiteralSyntax(); - return compilerOptionsObjectLiteralSyntax && getPropertyAssignment(compilerOptionsObjectLiteralSyntax, name); + return compilerOptionsObjectLiteralSyntax && ts.getPropertyAssignment(compilerOptionsObjectLiteralSyntax, name); } function getOptionPathsSyntax() { - return getOptionsSyntaxByName("paths") || emptyArray; + return getOptionsSyntaxByName("paths") || ts.emptyArray; } function getOptionsSyntaxByValue(name: string, value: string) { const syntaxByName = getOptionsSyntaxByName(name); - return syntaxByName && firstDefined(syntaxByName, property => isStringLiteral(property.initializer) && property.initializer.text === value ? property.initializer : undefined); + return syntaxByName && ts.firstDefined(syntaxByName, property => ts.isStringLiteral(property.initializer) && property.initializer.text === value ? property.initializer : undefined); } function getOptionsSyntaxByArrayElementValue(name: string, value: string) { const compilerOptionsObjectLiteralSyntax = getCompilerOptionsObjectLiteralSyntax(); - return compilerOptionsObjectLiteralSyntax && getPropertyArrayElementValue(compilerOptionsObjectLiteralSyntax, name, value); + return compilerOptionsObjectLiteralSyntax && ts.getPropertyArrayElementValue(compilerOptionsObjectLiteralSyntax, name, value); } - function createDiagnosticForOptionName(message: DiagnosticMessage, option1: string, option2?: string, option3?: string) { + function createDiagnosticForOptionName(message: ts.DiagnosticMessage, option1: string, option2?: string, option3?: string) { createDiagnosticForOption(/*onKey*/ true, option1, option2, message, option1, option2, option3); } - function createOptionValueDiagnostic(option1: string, message: DiagnosticMessage, arg0?: string, arg1?: string) { + function createOptionValueDiagnostic(option1: string, message: ts.DiagnosticMessage, arg0?: string, arg1?: string) { createDiagnosticForOption(/*onKey*/ false, option1, /*option2*/ undefined, message, arg0, arg1); } - function createDiagnosticForReference(sourceFile: JsonSourceFile | undefined, index: number, message: DiagnosticMessage, arg0?: string | number, arg1?: string | number) { - const referencesSyntax = firstDefined(getTsConfigPropArray(sourceFile || options.configFile, "references"), - property => isArrayLiteralExpression(property.initializer) ? property.initializer : undefined); + function createDiagnosticForReference(sourceFile: ts.JsonSourceFile | undefined, index: number, message: ts.DiagnosticMessage, arg0?: string | number, arg1?: string | number) { + const referencesSyntax = ts.firstDefined(ts.getTsConfigPropArray(sourceFile || options.configFile, "references"), property => ts.isArrayLiteralExpression(property.initializer) ? property.initializer : undefined); if (referencesSyntax && referencesSyntax.elements.length > index) { - programDiagnostics.add(createDiagnosticForNodeInSourceFile(sourceFile || options.configFile!, referencesSyntax.elements[index], message, arg0, arg1)); + programDiagnostics.add(ts.createDiagnosticForNodeInSourceFile(sourceFile || options.configFile!, referencesSyntax.elements[index], message, arg0, arg1)); } else { - programDiagnostics.add(createCompilerDiagnostic(message, arg0, arg1)); + programDiagnostics.add(ts.createCompilerDiagnostic(message, arg0, arg1)); } } - function createDiagnosticForOption(onKey: boolean, option1: string, option2: string | undefined, message: DiagnosticMessage, arg0?: string | number, arg1?: string | number, arg2?: string | number) { + function createDiagnosticForOption(onKey: boolean, option1: string, option2: string | undefined, message: ts.DiagnosticMessage, arg0?: string | number, arg1?: string | number, arg2?: string | number) { const compilerOptionsObjectLiteralSyntax = getCompilerOptionsObjectLiteralSyntax(); const needCompilerDiagnostic = !compilerOptionsObjectLiteralSyntax || !createOptionDiagnosticInObjectLiteralSyntax(compilerOptionsObjectLiteralSyntax, onKey, option1, option2, message, arg0, arg1, arg2); if (needCompilerDiagnostic) { - programDiagnostics.add(createCompilerDiagnostic(message, arg0, arg1, arg2)); + programDiagnostics.add(ts.createCompilerDiagnostic(message, arg0, arg1, arg2)); } } function getCompilerOptionsObjectLiteralSyntax() { if (_compilerOptionsObjectLiteralSyntax === undefined) { _compilerOptionsObjectLiteralSyntax = false; - const jsonObjectLiteral = getTsConfigObjectLiteralExpression(options.configFile); + const jsonObjectLiteral = ts.getTsConfigObjectLiteralExpression(options.configFile); if (jsonObjectLiteral) { - for (const prop of getPropertyAssignment(jsonObjectLiteral, "compilerOptions")) { - if (isObjectLiteralExpression(prop.initializer)) { + for (const prop of ts.getPropertyAssignment(jsonObjectLiteral, "compilerOptions")) { + if (ts.isObjectLiteralExpression(prop.initializer)) { _compilerOptionsObjectLiteralSyntax = prop.initializer; break; } @@ -3948,15 +3835,15 @@ namespace ts { return _compilerOptionsObjectLiteralSyntax || undefined; } - function createOptionDiagnosticInObjectLiteralSyntax(objectLiteral: ObjectLiteralExpression, onKey: boolean, key1: string, key2: string | undefined, message: DiagnosticMessage, arg0?: string | number, arg1?: string | number, arg2?: string | number): boolean { - const props = getPropertyAssignment(objectLiteral, key1, key2); + function createOptionDiagnosticInObjectLiteralSyntax(objectLiteral: ts.ObjectLiteralExpression, onKey: boolean, key1: string, key2: string | undefined, message: ts.DiagnosticMessage, arg0?: string | number, arg1?: string | number, arg2?: string | number): boolean { + const props = ts.getPropertyAssignment(objectLiteral, key1, key2); for (const prop of props) { - programDiagnostics.add(createDiagnosticForNodeInSourceFile(options.configFile!, onKey ? prop.name : prop.initializer, message, arg0, arg1, arg2)); + programDiagnostics.add(ts.createDiagnosticForNodeInSourceFile(options.configFile!, onKey ? prop.name : prop.initializer, message, arg0, arg1, arg2)); } return !!props.length; } - function blockEmittingOfFile(emitFileName: string, diag: Diagnostic) { + function blockEmittingOfFile(emitFileName: string, diag: ts.Diagnostic) { hasEmitBlockingDiagnostics.set(toPath(emitFileName), true); programDiagnostics.add(diag); } @@ -3973,40 +3860,40 @@ namespace ts { } // If options have --outFile or --out just check that - const out = outFile(options); + const out = ts.outFile(options); if (out) { - return isSameFile(filePath, out) || isSameFile(filePath, removeFileExtension(out) + Extension.Dts); + return isSameFile(filePath, out) || isSameFile(filePath, ts.removeFileExtension(out) + ts.Extension.Dts); } // If declarationDir is specified, return if its a file in that directory - if (options.declarationDir && containsPath(options.declarationDir, filePath, currentDirectory, !host.useCaseSensitiveFileNames())) { + if (options.declarationDir && ts.containsPath(options.declarationDir, filePath, currentDirectory, !host.useCaseSensitiveFileNames())) { return true; } // If --outDir, check if file is in that directory if (options.outDir) { - return containsPath(options.outDir, filePath, currentDirectory, !host.useCaseSensitiveFileNames()); + return ts.containsPath(options.outDir, filePath, currentDirectory, !host.useCaseSensitiveFileNames()); } - if (fileExtensionIsOneOf(filePath, supportedJSExtensionsFlat) || isDeclarationFileName(filePath)) { + if (ts.fileExtensionIsOneOf(filePath, ts.supportedJSExtensionsFlat) || ts.isDeclarationFileName(filePath)) { // Otherwise just check if sourceFile with the name exists - const filePathWithoutExtension = removeFileExtension(filePath); - return !!getSourceFileByPath((filePathWithoutExtension + Extension.Ts) as Path) || - !!getSourceFileByPath((filePathWithoutExtension + Extension.Tsx) as Path); + const filePathWithoutExtension = ts.removeFileExtension(filePath); + return !!getSourceFileByPath((filePathWithoutExtension + ts.Extension.Ts) as ts.Path) || + !!getSourceFileByPath((filePathWithoutExtension + ts.Extension.Tsx) as ts.Path); } return false; } function isSameFile(file1: string, file2: string) { - return comparePaths(file1, file2, currentDirectory, !host.useCaseSensitiveFileNames()) === Comparison.EqualTo; + return ts.comparePaths(file1, file2, currentDirectory, !host.useCaseSensitiveFileNames()) === ts.Comparison.EqualTo; } - function getSymlinkCache(): SymlinkCache { + function getSymlinkCache(): ts.SymlinkCache { if (host.getSymlinkCache) { return host.getSymlinkCache(); } if (!symlinks) { - symlinks = createSymlinkCache(currentDirectory, getCanonicalFileName); + symlinks = ts.createSymlinkCache(currentDirectory, getCanonicalFileName); } if (files && resolvedTypeReferenceDirectives && !symlinks.hasProcessedResolutions()) { symlinks.setSymlinksFromResolutions(files, resolvedTypeReferenceDirectives); @@ -4016,23 +3903,24 @@ namespace ts { } interface HostForUseSourceOfProjectReferenceRedirect { - compilerHost: CompilerHost; - getSymlinkCache: () => SymlinkCache; + compilerHost: ts.CompilerHost; + getSymlinkCache: () => ts.SymlinkCache; useSourceOfProjectReferenceRedirect: boolean; - toPath(fileName: string): Path; - getResolvedProjectReferences(): readonly (ResolvedProjectReference | undefined)[] | undefined; - getSourceOfProjectReferenceRedirect(path: Path): SourceOfProjectReferenceRedirect | undefined; - forEachResolvedProjectReference(cb: (resolvedProjectReference: ResolvedProjectReference) => T | undefined): T | undefined; + toPath(fileName: string): ts.Path; + getResolvedProjectReferences(): readonly (ts.ResolvedProjectReference | undefined)[] | undefined; + getSourceOfProjectReferenceRedirect(path: ts.Path): ts.SourceOfProjectReferenceRedirect | undefined; + forEachResolvedProjectReference(cb: (resolvedProjectReference: ts.ResolvedProjectReference) => T | undefined): T | undefined; } function updateHostForUseSourceOfProjectReferenceRedirect(host: HostForUseSourceOfProjectReferenceRedirect) { - let setOfDeclarationDirectories: Set | undefined; + let setOfDeclarationDirectories: ts.Set | undefined; const originalFileExists = host.compilerHost.fileExists; const originalDirectoryExists = host.compilerHost.directoryExists; const originalGetDirectories = host.compilerHost.getDirectories; const originalRealpath = host.compilerHost.realpath; - if (!host.useSourceOfProjectReferenceRedirect) return { onProgramCreateComplete: noop, fileExists }; + if (!host.useSourceOfProjectReferenceRedirect) + return { onProgramCreateComplete: ts.noop, fileExists }; host.compilerHost.fileExists = fileExists; @@ -4047,14 +3935,15 @@ namespace ts { return true; } - if (!host.getResolvedProjectReferences()) return false; + if (!host.getResolvedProjectReferences()) + return false; if (!setOfDeclarationDirectories) { - setOfDeclarationDirectories = new Set(); + setOfDeclarationDirectories = new ts.Set(); host.forEachResolvedProjectReference(ref => { - const out = outFile(ref.commandLine.options); + const out = ts.outFile(ref.commandLine.options); if (out) { - setOfDeclarationDirectories!.add(getDirectoryPath(host.toPath(out))); + setOfDeclarationDirectories!.add(ts.getDirectoryPath(host.toPath(out))); } else { // Set declaration's in different locations only, if they are next to source the directory present doesnt change @@ -4073,16 +3962,14 @@ namespace ts { if (originalGetDirectories) { // Call getDirectories only if directory actually present on the host // This is needed to ensure that we arent getting directories that we fake about presence for - host.compilerHost.getDirectories = path => - !host.getResolvedProjectReferences() || (originalDirectoryExists && originalDirectoryExists.call(host.compilerHost, path)) ? + host.compilerHost.getDirectories = path => !host.getResolvedProjectReferences() || (originalDirectoryExists && originalDirectoryExists.call(host.compilerHost, path)) ? originalGetDirectories.call(host.compilerHost, path) : []; } // This is something we keep for life time of the host if (originalRealpath) { - host.compilerHost.realpath = s => - host.getSymlinkCache().getSymlinkedFiles()?.get(host.toPath(s)) || + host.compilerHost.realpath = s => host.getSymlinkCache().getSymlinkedFiles()?.get(host.toPath(s)) || originalRealpath.call(host.compilerHost, s); } @@ -4099,9 +3986,12 @@ namespace ts { // .d.ts file for the referenced Project. // If it is it returns true irrespective of whether that file exists on host function fileExists(file: string) { - if (originalFileExists.call(host.compilerHost, file)) return true; - if (!host.getResolvedProjectReferences()) return false; - if (!isDeclarationFileName(file)) return false; + if (originalFileExists.call(host.compilerHost, file)) + return true; + if (!host.getResolvedProjectReferences()) + return false; + if (!ts.isDeclarationFileName(file)) + return false; // Project references go to source file instead of .d.ts file return fileOrDirectoryExistsUsingSource(file, /*isFile*/ true); @@ -4110,43 +4000,42 @@ namespace ts { function fileExistsIfProjectReferenceDts(file: string) { const source = host.getSourceOfProjectReferenceRedirect(host.toPath(file)); return source !== undefined ? - isString(source) ? originalFileExists.call(host.compilerHost, source) as boolean : true : + ts.isString(source) ? originalFileExists.call(host.compilerHost, source) as boolean : true : undefined; } function directoryExistsIfProjectReferenceDeclDir(dir: string) { const dirPath = host.toPath(dir); - const dirPathWithTrailingDirectorySeparator = `${dirPath}${directorySeparator}`; - return forEachKey( - setOfDeclarationDirectories!, - declDirPath => dirPath === declDirPath || + const dirPathWithTrailingDirectorySeparator = `${dirPath}${ts.directorySeparator}`; + return ts.forEachKey(setOfDeclarationDirectories!, declDirPath => dirPath === declDirPath || // Any parent directory of declaration dir - startsWith(declDirPath, dirPathWithTrailingDirectorySeparator) || + ts.startsWith(declDirPath, dirPathWithTrailingDirectorySeparator) || // Any directory inside declaration dir - startsWith(dirPath, `${declDirPath}/`) - ); + ts.startsWith(dirPath, `${declDirPath}/`)); } function handleDirectoryCouldBeSymlink(directory: string) { - if (!host.getResolvedProjectReferences() || containsIgnoredPath(directory)) return; + if (!host.getResolvedProjectReferences() || ts.containsIgnoredPath(directory)) + return; // Because we already watch node_modules, handle symlinks in there - if (!originalRealpath || !stringContains(directory, nodeModulesPathPart)) return; + if (!originalRealpath || !ts.stringContains(directory, ts.nodeModulesPathPart)) + return; const symlinkCache = host.getSymlinkCache(); - const directoryPath = ensureTrailingDirectorySeparator(host.toPath(directory)); - if (symlinkCache.getSymlinkedDirectories()?.has(directoryPath)) return; - - const real = normalizePath(originalRealpath.call(host.compilerHost, directory)); - let realPath: Path; + const directoryPath = ts.ensureTrailingDirectorySeparator(host.toPath(directory)); + if (symlinkCache.getSymlinkedDirectories()?.has(directoryPath)) + return; + const real = ts.normalizePath(originalRealpath.call(host.compilerHost, directory)); + let realPath: ts.Path; if (real === directory || - (realPath = ensureTrailingDirectorySeparator(host.toPath(real))) === directoryPath) { + (realPath = ts.ensureTrailingDirectorySeparator(host.toPath(real))) === directoryPath) { // not symlinked symlinkCache.setSymlinkedDirectory(directoryPath, false); return; } symlinkCache.setSymlinkedDirectory(directory, { - real: ensureTrailingDirectorySeparator(real), + real: ts.ensureTrailingDirectorySeparator(real), realPath }); } @@ -4157,50 +4046,44 @@ namespace ts { (dir: string) => directoryExistsIfProjectReferenceDeclDir(dir); // Check current directory or file const result = fileOrDirectoryExistsUsingSource(fileOrDirectory); - if (result !== undefined) return result; + if (result !== undefined) + return result; const symlinkCache = host.getSymlinkCache(); const symlinkedDirectories = symlinkCache.getSymlinkedDirectories(); - if (!symlinkedDirectories) return false; + if (!symlinkedDirectories) + return false; const fileOrDirectoryPath = host.toPath(fileOrDirectory); - if (!stringContains(fileOrDirectoryPath, nodeModulesPathPart)) return false; - if (isFile && symlinkCache.getSymlinkedFiles()?.has(fileOrDirectoryPath)) return true; + if (!ts.stringContains(fileOrDirectoryPath, ts.nodeModulesPathPart)) + return false; + if (isFile && symlinkCache.getSymlinkedFiles()?.has(fileOrDirectoryPath)) + return true; // If it contains node_modules check if its one of the symlinked path we know of - return firstDefinedIterator( - symlinkedDirectories.entries(), - ([directoryPath, symlinkedDirectory]) => { - if (!symlinkedDirectory || !startsWith(fileOrDirectoryPath, directoryPath)) return undefined; + return ts.firstDefinedIterator(symlinkedDirectories.entries(), ([directoryPath, symlinkedDirectory]) => { + if (!symlinkedDirectory || !ts.startsWith(fileOrDirectoryPath, directoryPath)) + return undefined; const result = fileOrDirectoryExistsUsingSource(fileOrDirectoryPath.replace(directoryPath, symlinkedDirectory.realPath)); if (isFile && result) { // Store the real path for the file' - const absolutePath = getNormalizedAbsolutePath(fileOrDirectory, host.compilerHost.getCurrentDirectory()); - symlinkCache.setSymlinkedFile( - fileOrDirectoryPath, - `${symlinkedDirectory.real}${absolutePath.replace(new RegExp(directoryPath, "i"), "")}` - ); + const absolutePath = ts.getNormalizedAbsolutePath(fileOrDirectory, host.compilerHost.getCurrentDirectory()); + symlinkCache.setSymlinkedFile(fileOrDirectoryPath, `${symlinkedDirectory.real}${absolutePath.replace(new RegExp(directoryPath, "i"), "")}`); } return result; + }) || false; } - ) || false; } - } /*@internal*/ - export const emitSkippedWithNoDiagnostics: EmitResult = { diagnostics: emptyArray, sourceMaps: undefined, emittedFiles: undefined, emitSkipped: true }; + export const emitSkippedWithNoDiagnostics: ts.EmitResult = { diagnostics: ts.emptyArray, sourceMaps: undefined, emittedFiles: undefined, emitSkipped: true }; /*@internal*/ - export function handleNoEmitOptions( - program: Program | T, - sourceFile: SourceFile | undefined, - writeFile: WriteFileCallback | undefined, - cancellationToken: CancellationToken | undefined - ): EmitResult | undefined { + export function handleNoEmitOptions(program: ts.Program | T, sourceFile: ts.SourceFile | undefined, writeFile: ts.WriteFileCallback | undefined, cancellationToken: ts.CancellationToken | undefined): ts.EmitResult | undefined { const options = program.getCompilerOptions(); if (options.noEmit) { // Cache the semantic diagnostics program.getSemanticDiagnostics(sourceFile, cancellationToken); - return sourceFile || outFile(options) ? + return sourceFile || ts.outFile(options) ? emitSkippedWithNoDiagnostics : program.emitBuildInfo(writeFile, cancellationToken); } @@ -4208,31 +4091,34 @@ namespace ts { // If the noEmitOnError flag is set, then check if we have any errors so far. If so, // immediately bail out. Note that we pass 'undefined' for 'sourceFile' so that we // get any preEmit diagnostics, not just the ones - if (!options.noEmitOnError) return undefined; - let diagnostics: readonly Diagnostic[] = [ + if (!options.noEmitOnError) + return undefined; + let diagnostics: readonly ts.Diagnostic[] = [ ...program.getOptionsDiagnostics(cancellationToken), ...program.getSyntacticDiagnostics(sourceFile, cancellationToken), ...program.getGlobalDiagnostics(cancellationToken), ...program.getSemanticDiagnostics(sourceFile, cancellationToken) ]; - if (diagnostics.length === 0 && getEmitDeclarations(program.getCompilerOptions())) { + if (diagnostics.length === 0 && ts.getEmitDeclarations(program.getCompilerOptions())) { diagnostics = program.getDeclarationDiagnostics(/*sourceFile*/ undefined, cancellationToken); } - if (!diagnostics.length) return undefined; + if (!diagnostics.length) + return undefined; let emittedFiles: string[] | undefined; - if (!sourceFile && !outFile(options)) { + if (!sourceFile && !ts.outFile(options)) { const emitResult = program.emitBuildInfo(writeFile, cancellationToken); - if (emitResult.diagnostics) diagnostics = [...diagnostics, ...emitResult.diagnostics]; + if (emitResult.diagnostics) + diagnostics = [...diagnostics, ...emitResult.diagnostics]; emittedFiles = emitResult.emittedFiles; } return { diagnostics, sourceMaps: undefined, emittedFiles, emitSkipped: true }; } /*@internal*/ - export function filterSemanticDiagnostics(diagnostic: readonly Diagnostic[], option: CompilerOptions): readonly Diagnostic[] { - return filter(diagnostic, d => !d.skippedOn || !option[d.skippedOn]); + export function filterSemanticDiagnostics(diagnostic: readonly ts.Diagnostic[], option: ts.CompilerOptions): readonly ts.Diagnostic[] { + return ts.filter(diagnostic, d => !d.skippedOn || !option[d.skippedOn]); } /*@internal*/ @@ -4243,21 +4129,21 @@ namespace ts { readFile(fileName: string): string | undefined; readDirectory?(rootDir: string, extensions: readonly string[], excludes: readonly string[] | undefined, includes: readonly string[], depth?: number): string[]; trace?(s: string): void; - onUnRecoverableConfigFileDiagnostic?: DiagnosticReporter; + onUnRecoverableConfigFileDiagnostic?: ts.DiagnosticReporter; } /* @internal */ - export function parseConfigHostFromCompilerHostLike(host: CompilerHostLike, directoryStructureHost: DirectoryStructureHost = host): ParseConfigFileHost { + export function parseConfigHostFromCompilerHostLike(host: CompilerHostLike, directoryStructureHost: ts.DirectoryStructureHost = host): ts.ParseConfigFileHost { return { fileExists: f => directoryStructureHost.fileExists(f), readDirectory(root, extensions, excludes, includes, depth) { - Debug.assertIsDefined(directoryStructureHost.readDirectory, "'CompilerHost.readDirectory' must be implemented to correctly process 'projectReferences'"); + ts.Debug.assertIsDefined(directoryStructureHost.readDirectory, "'CompilerHost.readDirectory' must be implemented to correctly process 'projectReferences'"); return directoryStructureHost.readDirectory(root, extensions, excludes, includes, depth); }, readFile: f => directoryStructureHost.readFile(f), useCaseSensitiveFileNames: host.useCaseSensitiveFileNames(), getCurrentDirectory: () => host.getCurrentDirectory(), - onUnRecoverableConfigFileDiagnostic: host.onUnRecoverableConfigFileDiagnostic || returnUndefined, + onUnRecoverableConfigFileDiagnostic: host.onUnRecoverableConfigFileDiagnostic || ts.returnUndefined, trace: host.trace ? (s) => host.trace!(s) : undefined }; } @@ -4268,33 +4154,34 @@ namespace ts { } /* @internal */ - export function createPrependNodes(projectReferences: readonly ProjectReference[] | undefined, getCommandLine: (ref: ProjectReference, index: number) => ParsedCommandLine | undefined, readFile: (path: string) => string | undefined) { - if (!projectReferences) return emptyArray; - let nodes: InputFiles[] | undefined; + export function createPrependNodes(projectReferences: readonly ts.ProjectReference[] | undefined, getCommandLine: (ref: ts.ProjectReference, index: number) => ts.ParsedCommandLine | undefined, readFile: (path: string) => string | undefined) { + if (!projectReferences) + return ts.emptyArray; + let nodes: ts.InputFiles[] | undefined; for (let i = 0; i < projectReferences.length; i++) { const ref = projectReferences[i]; const resolvedRefOpts = getCommandLine(ref, i); if (ref.prepend && resolvedRefOpts && resolvedRefOpts.options) { - const out = outFile(resolvedRefOpts.options); + const out = ts.outFile(resolvedRefOpts.options); // Upstream project didn't have outFile set -- skip (error will have been issued earlier) - if (!out) continue; - - const { jsFilePath, sourceMapFilePath, declarationFilePath, declarationMapPath, buildInfoPath } = getOutputPathsForBundle(resolvedRefOpts.options, /*forceDtsPaths*/ true); - const node = createInputFiles(readFile, jsFilePath!, sourceMapFilePath, declarationFilePath!, declarationMapPath, buildInfoPath); + if (!out) + continue; + const { jsFilePath, sourceMapFilePath, declarationFilePath, declarationMapPath, buildInfoPath } = ts.getOutputPathsForBundle(resolvedRefOpts.options, /*forceDtsPaths*/ true); + const node = ts.createInputFiles(readFile, jsFilePath!, sourceMapFilePath, declarationFilePath!, declarationMapPath, buildInfoPath); (nodes || (nodes = [])).push(node); } } - return nodes || emptyArray; + return nodes || ts.emptyArray; } /** * Returns the target config filename of a project reference. * Note: The file might not exist. */ - export function resolveProjectReferencePath(ref: ProjectReference): ResolvedConfigFileName; - /** @deprecated */ export function resolveProjectReferencePath(host: ResolveProjectReferencePathHost, ref: ProjectReference): ResolvedConfigFileName; - export function resolveProjectReferencePath(hostOrRef: ResolveProjectReferencePathHost | ProjectReference, ref?: ProjectReference): ResolvedConfigFileName { - const passedInRef = ref ? ref : hostOrRef as ProjectReference; - return resolveConfigFileProjectName(passedInRef.path); + export function resolveProjectReferencePath(ref: ts.ProjectReference): ts.ResolvedConfigFileName; + /** @deprecated */ export function resolveProjectReferencePath(host: ResolveProjectReferencePathHost, ref: ts.ProjectReference): ts.ResolvedConfigFileName; + export function resolveProjectReferencePath(hostOrRef: ResolveProjectReferencePathHost | ts.ProjectReference, ref?: ts.ProjectReference): ts.ResolvedConfigFileName { + const passedInRef = ref ? ref : hostOrRef as ts.ProjectReference; + return ts.resolveConfigFileProjectName(passedInRef.path); } /* @internal */ @@ -4303,37 +4190,37 @@ namespace ts { * The DiagnosticMessage's parameters are the imported module name, and the filename it resolved to. * This returns a diagnostic even if the module will be an untyped module. */ - export function getResolutionDiagnostic(options: CompilerOptions, { extension }: ResolvedModuleFull): DiagnosticMessage | undefined { + export function getResolutionDiagnostic(options: ts.CompilerOptions, { extension }: ts.ResolvedModuleFull): ts.DiagnosticMessage | undefined { switch (extension) { - case Extension.Ts: - case Extension.Dts: + case ts.Extension.Ts: + case ts.Extension.Dts: // These are always allowed. return undefined; - case Extension.Tsx: + case ts.Extension.Tsx: return needJsx(); - case Extension.Jsx: + case ts.Extension.Jsx: return needJsx() || needAllowJs(); - case Extension.Js: + case ts.Extension.Js: return needAllowJs(); - case Extension.Json: + case ts.Extension.Json: return needResolveJsonModule(); } function needJsx() { - return options.jsx ? undefined : Diagnostics.Module_0_was_resolved_to_1_but_jsx_is_not_set; + return options.jsx ? undefined : ts.Diagnostics.Module_0_was_resolved_to_1_but_jsx_is_not_set; } function needAllowJs() { - return getAllowJSCompilerOption(options) || !getStrictOptionValue(options, "noImplicitAny") ? undefined : Diagnostics.Could_not_find_a_declaration_file_for_module_0_1_implicitly_has_an_any_type; + return ts.getAllowJSCompilerOption(options) || !ts.getStrictOptionValue(options, "noImplicitAny") ? undefined : ts.Diagnostics.Could_not_find_a_declaration_file_for_module_0_1_implicitly_has_an_any_type; } function needResolveJsonModule() { - return options.resolveJsonModule ? undefined : Diagnostics.Module_0_was_resolved_to_1_but_resolveJsonModule_is_not_used; + return options.resolveJsonModule ? undefined : ts.Diagnostics.Module_0_was_resolved_to_1_but_resolveJsonModule_is_not_used; } } - function getModuleNames({ imports, moduleAugmentations }: SourceFile): string[] { + function getModuleNames({ imports, moduleAugmentations }: ts.SourceFile): string[] { const res = imports.map(i => i.text); for (const aug of moduleAugmentations) { - if (aug.kind === SyntaxKind.StringLiteral) { + if (aug.kind === ts.SyntaxKind.StringLiteral) { res.push(aug.text); } // Do nothing if it's an Identifier; we don't need to do module resolution for `declare global`. @@ -4342,16 +4229,18 @@ namespace ts { } /* @internal */ - export function getModuleNameStringLiteralAt({ imports, moduleAugmentations }: SourceFileImportsList, index: number): StringLiteralLike { - if (index < imports.length) return imports[index]; + export function getModuleNameStringLiteralAt({ imports, moduleAugmentations }: SourceFileImportsList, index: number): ts.StringLiteralLike { + if (index < imports.length) + return imports[index]; let augIndex = imports.length; for (const aug of moduleAugmentations) { - if (aug.kind === SyntaxKind.StringLiteral) { - if (index === augIndex) return aug; + if (aug.kind === ts.SyntaxKind.StringLiteral) { + if (index === augIndex) + return aug; augIndex++; } // Do nothing if it's an Identifier; we don't need to do module resolution for `declare global`. } - Debug.fail("should never ask for module name at index higher than possible module name"); + ts.Debug.fail("should never ask for module name at index higher than possible module name"); } } diff --git a/src/compiler/resolutionCache.ts b/src/compiler/resolutionCache.ts index d6127fdc1c488..881d4dcf9b000 100644 --- a/src/compiler/resolutionCache.ts +++ b/src/compiler/resolutionCache.ts @@ -3,20 +3,19 @@ namespace ts { /** This is the cache of module/typedirectives resolution that can be retained across program */ export interface ResolutionCache { startRecordingFilesWithChangedResolutions(): void; - finishRecordingFilesWithChangedResolutions(): Path[] | undefined; - - resolveModuleNames(moduleNames: string[], containingFile: string, reusedNames: string[] | undefined, redirectedReference?: ResolvedProjectReference, containingSourceFile?: SourceFile): (ResolvedModuleFull | undefined)[]; - getResolvedModuleWithFailedLookupLocationsFromCache(moduleName: string, containingFile: string, resolutionMode?: ModuleKind.CommonJS | ModuleKind.ESNext): CachedResolvedModuleWithFailedLookupLocations | undefined; - resolveTypeReferenceDirectives(typeDirectiveNames: string[] | readonly FileReference[], containingFile: string, redirectedReference?: ResolvedProjectReference, containingFileMode?: SourceFile["impliedNodeFormat"]): (ResolvedTypeReferenceDirective | undefined)[]; + finishRecordingFilesWithChangedResolutions(): ts.Path[] | undefined; + resolveModuleNames(moduleNames: string[], containingFile: string, reusedNames: string[] | undefined, redirectedReference?: ts.ResolvedProjectReference, containingSourceFile?: ts.SourceFile): (ts.ResolvedModuleFull | undefined)[]; + getResolvedModuleWithFailedLookupLocationsFromCache(moduleName: string, containingFile: string, resolutionMode?: ts.ModuleKind.CommonJS | ts.ModuleKind.ESNext): CachedResolvedModuleWithFailedLookupLocations | undefined; + resolveTypeReferenceDirectives(typeDirectiveNames: string[] | readonly ts.FileReference[], containingFile: string, redirectedReference?: ts.ResolvedProjectReference, containingFileMode?: ts.SourceFile["impliedNodeFormat"]): (ts.ResolvedTypeReferenceDirective | undefined)[]; invalidateResolutionsOfFailedLookupLocations(): boolean; - invalidateResolutionOfFile(filePath: Path): void; - removeResolutionsOfFile(filePath: Path): void; - removeResolutionsFromProjectReferenceRedirects(filePath: Path): void; - setFilesWithInvalidatedNonRelativeUnresolvedImports(filesWithUnresolvedImports: ESMap): void; - createHasInvalidatedResolution(forceAllFilesAsInvalidated?: boolean): HasInvalidatedResolution; + invalidateResolutionOfFile(filePath: ts.Path): void; + removeResolutionsOfFile(filePath: ts.Path): void; + removeResolutionsFromProjectReferenceRedirects(filePath: ts.Path): void; + setFilesWithInvalidatedNonRelativeUnresolvedImports(filesWithUnresolvedImports: ts.ESMap): void; + createHasInvalidatedResolution(forceAllFilesAsInvalidated?: boolean): ts.HasInvalidatedResolution; hasChangedAutomaticTypeDirectiveNames(): boolean; - isFileWithInvalidatedNonRelativeUnresolvedImports(path: Path): boolean; + isFileWithInvalidatedNonRelativeUnresolvedImports(path: ts.Path): boolean; startCachingPerDirectoryResolution(): void; @@ -25,7 +24,7 @@ namespace ts { updateTypeRootsWatch(): void; closeTypeRootsWatch(): void; - getModuleResolutionCache(): ModuleResolutionCache; + getModuleResolutionCache(): ts.ModuleResolutionCache; clear(): void; } @@ -35,42 +34,42 @@ namespace ts { isInvalidated?: boolean; refCount?: number; // Files that have this resolution using - files?: Path[]; + files?: ts.Path[]; } interface ResolutionWithResolvedFileName { resolvedFileName: string | undefined; - packagetId?: PackageId; + packagetId?: ts.PackageId; } - interface CachedResolvedModuleWithFailedLookupLocations extends ResolvedModuleWithFailedLookupLocations, ResolutionWithFailedLookupLocations { + interface CachedResolvedModuleWithFailedLookupLocations extends ts.ResolvedModuleWithFailedLookupLocations, ResolutionWithFailedLookupLocations { } - interface CachedResolvedTypeReferenceDirectiveWithFailedLookupLocations extends ResolvedTypeReferenceDirectiveWithFailedLookupLocations, ResolutionWithFailedLookupLocations { + interface CachedResolvedTypeReferenceDirectiveWithFailedLookupLocations extends ts.ResolvedTypeReferenceDirectiveWithFailedLookupLocations, ResolutionWithFailedLookupLocations { } - export interface ResolutionCacheHost extends MinimalResolutionCacheHost { - toPath(fileName: string): Path; - getCanonicalFileName: GetCanonicalFileName; - getCompilationSettings(): CompilerOptions; - watchDirectoryOfFailedLookupLocation(directory: string, cb: DirectoryWatcherCallback, flags: WatchDirectoryFlags): FileWatcher; + export interface ResolutionCacheHost extends ts.MinimalResolutionCacheHost { + toPath(fileName: string): ts.Path; + getCanonicalFileName: ts.GetCanonicalFileName; + getCompilationSettings(): ts.CompilerOptions; + watchDirectoryOfFailedLookupLocation(directory: string, cb: ts.DirectoryWatcherCallback, flags: ts.WatchDirectoryFlags): ts.FileWatcher; onInvalidatedResolution(): void; - watchTypeRootsDirectory(directory: string, cb: DirectoryWatcherCallback, flags: WatchDirectoryFlags): FileWatcher; + watchTypeRootsDirectory(directory: string, cb: ts.DirectoryWatcherCallback, flags: ts.WatchDirectoryFlags): ts.FileWatcher; onChangedAutomaticTypeDirectiveNames(): void; scheduleInvalidateResolutionsOfFailedLookupLocations(): void; - getCachedDirectoryStructureHost(): CachedDirectoryStructureHost | undefined; + getCachedDirectoryStructureHost(): ts.CachedDirectoryStructureHost | undefined; projectName?: string; getGlobalCache?(): string | undefined; globalCacheResolutionModuleName?(externalModuleName: string): string; writeLog(s: string): void; - getCurrentProgram(): Program | undefined; - fileIsOpen(filePath: Path): boolean; + getCurrentProgram(): ts.Program | undefined; + fileIsOpen(filePath: ts.Path): boolean; onDiscoveredSymlink?(): void; } interface DirectoryWatchesOfFailedLookup { /** watcher for the directory of failed lookup */ - watcher: FileWatcher; + watcher: ts.FileWatcher; /** ref count keeping this directory watch alive */ refCount: number; /** is the directory watched being non recursive */ @@ -79,17 +78,17 @@ namespace ts { interface DirectoryOfFailedLookupWatch { dir: string; - dirPath: Path; + dirPath: ts.Path; nonRecursive?: boolean; } - export function removeIgnoredPath(path: Path): Path | undefined { + export function removeIgnoredPath(path: ts.Path): ts.Path | undefined { // Consider whole staging folder as if node_modules changed. - if (endsWith(path, "/node_modules/.staging")) { - return removeSuffix(path, "/.staging") as Path; + if (ts.endsWith(path, "/node_modules/.staging")) { + return ts.removeSuffix(path, "/.staging") as ts.Path; } - return some(ignoredPaths, searchPath => stringContains(path, searchPath)) ? + return ts.some(ts.ignoredPaths, searchPath => ts.stringContains(path, searchPath)) ? undefined : path; } @@ -100,25 +99,25 @@ namespace ts { * "c:/", "c:/users", "c:/users/username", "c:/users/username/folderAtRoot", "c:/folderAtRoot" * @param dirPath */ - export function canWatchDirectory(dirPath: Path) { - const rootLength = getRootLength(dirPath); + export function canWatchDirectory(dirPath: ts.Path) { + const rootLength = ts.getRootLength(dirPath); if (dirPath.length === rootLength) { // Ignore "/", "c:/" return false; } - let nextDirectorySeparator = dirPath.indexOf(directorySeparator, rootLength); + let nextDirectorySeparator = dirPath.indexOf(ts.directorySeparator, rootLength); if (nextDirectorySeparator === -1) { // ignore "/user", "c:/users" or "c:/folderAtRoot" return false; } let pathPartForUserCheck = dirPath.substring(rootLength, nextDirectorySeparator + 1); - const isNonDirectorySeparatorRoot = rootLength > 1 || dirPath.charCodeAt(0) !== CharacterCodes.slash; + const isNonDirectorySeparatorRoot = rootLength > 1 || dirPath.charCodeAt(0) !== ts.CharacterCodes.slash; if (isNonDirectorySeparatorRoot && dirPath.search(/[a-zA-Z]:/) !== 0 && // Non dos style paths pathPartForUserCheck.search(/[a-zA-z]\$\//) === 0) { // Dos style nextPart - nextDirectorySeparator = dirPath.indexOf(directorySeparator, nextDirectorySeparator + 1); + nextDirectorySeparator = dirPath.indexOf(ts.directorySeparator, nextDirectorySeparator + 1); if (nextDirectorySeparator === -1) { // ignore "//vda1cs4850/c$/folderAtRoot" return false; @@ -134,7 +133,7 @@ namespace ts { } for (let searchIndex = nextDirectorySeparator + 1, searchLevels = 2; searchLevels > 0; searchLevels--) { - searchIndex = dirPath.indexOf(directorySeparator, searchIndex) + 1; + searchIndex = dirPath.indexOf(ts.directorySeparator, searchIndex) + 1; if (searchIndex === 0) { // Folder isnt at expected minimum levels return false; @@ -143,49 +142,36 @@ namespace ts { return true; } - type GetResolutionWithResolvedFileName = - (resolution: T) => R | undefined; + type GetResolutionWithResolvedFileName = (resolution: T) => R | undefined; export function createResolutionCache(resolutionHost: ResolutionCacheHost, rootDirForResolution: string | undefined, logChangesWhenResolvingModule: boolean): ResolutionCache { - let filesWithChangedSetOfUnresolvedImports: Path[] | undefined; - let filesWithInvalidatedResolutions: Set | undefined; - let filesWithInvalidatedNonRelativeUnresolvedImports: ReadonlyESMap | undefined; - const nonRelativeExternalModuleResolutions = createMultiMap(); + let filesWithChangedSetOfUnresolvedImports: ts.Path[] | undefined; + let filesWithInvalidatedResolutions: ts.Set | undefined; + let filesWithInvalidatedNonRelativeUnresolvedImports: ts.ReadonlyESMap | undefined; + const nonRelativeExternalModuleResolutions = ts.createMultiMap(); const resolutionsWithFailedLookups: ResolutionWithFailedLookupLocations[] = []; - const resolvedFileToResolution = createMultiMap(); + const resolvedFileToResolution = ts.createMultiMap(); let hasChangedAutomaticTypeDirectiveNames = false; - let failedLookupChecks: Path[] | undefined; - let startsWithPathChecks: Set | undefined; - let isInDirectoryChecks: Path[] | undefined; - - const getCurrentDirectory = memoize(() => resolutionHost.getCurrentDirectory!()); // TODO: GH#18217 + let failedLookupChecks: ts.Path[] | undefined; + let startsWithPathChecks: ts.Set | undefined; + let isInDirectoryChecks: ts.Path[] | undefined; + const getCurrentDirectory = ts.memoize(() => resolutionHost.getCurrentDirectory!()); // TODO: GH#18217 const cachedDirectoryStructureHost = resolutionHost.getCachedDirectoryStructureHost(); // The resolvedModuleNames and resolvedTypeReferenceDirectives are the cache of resolutions per file. // The key in the map is source file's path. // The values are Map of resolutions with key being name lookedup. - const resolvedModuleNames = new Map>(); - const perDirectoryResolvedModuleNames: CacheWithRedirects> = createCacheWithRedirects(); - const nonRelativeModuleNameCache: CacheWithRedirects = createCacheWithRedirects(); - const moduleResolutionCache = createModuleResolutionCache( - getCurrentDirectory(), - resolutionHost.getCanonicalFileName, - /*options*/ undefined, - perDirectoryResolvedModuleNames, - nonRelativeModuleNameCache, - ); - - const resolvedTypeReferenceDirectives = new Map>(); - const perDirectoryResolvedTypeReferenceDirectives: CacheWithRedirects> = createCacheWithRedirects(); - const typeReferenceDirectiveResolutionCache = createTypeReferenceDirectiveResolutionCache( - getCurrentDirectory(), - resolutionHost.getCanonicalFileName, - /*options*/ undefined, - moduleResolutionCache.getPackageJsonInfoCache(), - perDirectoryResolvedTypeReferenceDirectives - ); + const resolvedModuleNames = new ts.Map>(); + const perDirectoryResolvedModuleNames: ts.CacheWithRedirects> = ts.createCacheWithRedirects(); + const nonRelativeModuleNameCache: ts.CacheWithRedirects = ts.createCacheWithRedirects(); + const moduleResolutionCache = ts.createModuleResolutionCache(getCurrentDirectory(), resolutionHost.getCanonicalFileName, + /*options*/ undefined, perDirectoryResolvedModuleNames, nonRelativeModuleNameCache); + const resolvedTypeReferenceDirectives = new ts.Map>(); + const perDirectoryResolvedTypeReferenceDirectives: ts.CacheWithRedirects> = ts.createCacheWithRedirects(); + const typeReferenceDirectiveResolutionCache = ts.createTypeReferenceDirectiveResolutionCache(getCurrentDirectory(), resolutionHost.getCanonicalFileName, + /*options*/ undefined, moduleResolutionCache.getPackageJsonInfoCache(), perDirectoryResolvedTypeReferenceDirectives); /** * These are the extensions that failed lookup files will have by default, @@ -193,16 +179,15 @@ namespace ts { * This helps in not having to comb through all resolutions when files are added/removed * Note that .d.ts file also has .d.ts extension hence will be part of default extensions */ - const failedLookupDefaultExtensions = [Extension.Ts, Extension.Tsx, Extension.Js, Extension.Jsx, Extension.Json]; - const customFailedLookupPaths = new Map(); - - const directoryWatchesOfFailedLookups = new Map(); - const rootDir = rootDirForResolution && removeTrailingDirectorySeparator(getNormalizedAbsolutePath(rootDirForResolution, getCurrentDirectory())); - const rootPath = (rootDir && resolutionHost.toPath(rootDir)) as Path; // TODO: GH#18217 - const rootSplitLength = rootPath !== undefined ? rootPath.split(directorySeparator).length : 0; + const failedLookupDefaultExtensions = [ts.Extension.Ts, ts.Extension.Tsx, ts.Extension.Js, ts.Extension.Jsx, ts.Extension.Json]; + const customFailedLookupPaths = new ts.Map(); + const directoryWatchesOfFailedLookups = new ts.Map(); + const rootDir = rootDirForResolution && ts.removeTrailingDirectorySeparator(ts.getNormalizedAbsolutePath(rootDirForResolution, getCurrentDirectory())); + const rootPath = (rootDir && resolutionHost.toPath(rootDir)) as ts.Path; // TODO: GH#18217 + const rootSplitLength = rootPath !== undefined ? rootPath.split(ts.directorySeparator).length : 0; // TypeRoot watches for the types that get added as part of getAutomaticTypeDirectiveNames - const typeRootsWatches = new Map(); + const typeRootsWatches = new ts.Map(); return { getModuleResolutionCache: () => moduleResolutionCache, @@ -236,15 +221,15 @@ namespace ts { return resolution.resolvedTypeReferenceDirective; } - function isInDirectoryPath(dir: Path | undefined, file: Path) { + function isInDirectoryPath(dir: ts.Path | undefined, file: ts.Path) { if (dir === undefined || file.length <= dir.length) { return false; } - return startsWith(file, dir) && file[dir.length] === directorySeparator; + return ts.startsWith(file, dir) && file[dir.length] === ts.directorySeparator; } function clear() { - clearMap(directoryWatchesOfFailedLookups, closeFileWatcherOf); + ts.clearMap(directoryWatchesOfFailedLookups, ts.closeFileWatcherOf); customFailedLookupPaths.clear(); nonRelativeExternalModuleResolutions.clear(); closeTypeRootsWatch(); @@ -271,7 +256,7 @@ namespace ts { return collected; } - function isFileWithInvalidatedNonRelativeUnresolvedImports(path: Path): boolean { + function isFileWithInvalidatedNonRelativeUnresolvedImports(path: ts.Path): boolean { if (!filesWithInvalidatedNonRelativeUnresolvedImports) { return false; } @@ -281,13 +266,13 @@ namespace ts { return !!value && !!value.length; } - function createHasInvalidatedResolution(forceAllFilesAsInvalidated?: boolean): HasInvalidatedResolution { + function createHasInvalidatedResolution(forceAllFilesAsInvalidated?: boolean): ts.HasInvalidatedResolution { // Ensure pending resolutions are applied invalidateResolutionsOfFailedLookupLocations(); if (forceAllFilesAsInvalidated) { // Any file asked would have invalidated resolution filesWithInvalidatedResolutions = undefined; - return returnTrue; + return ts.returnTrue; } const collected = filesWithInvalidatedResolutions; filesWithInvalidatedResolutions = undefined; @@ -314,7 +299,7 @@ namespace ts { hasChangedAutomaticTypeDirectiveNames = false; } - function resolveModuleName(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost, redirectedReference?: ResolvedProjectReference, _containingSourceFile?: never, mode?: ModuleKind.CommonJS | ModuleKind.ESNext | undefined): CachedResolvedModuleWithFailedLookupLocations { + function resolveModuleName(moduleName: string, containingFile: string, compilerOptions: ts.CompilerOptions, host: ts.ModuleResolutionHost, redirectedReference?: ts.ResolvedProjectReference, _containingSourceFile?: never, mode?: ts.ModuleKind.CommonJS | ts.ModuleKind.ESNext | undefined): CachedResolvedModuleWithFailedLookupLocations { const primaryResult = ts.resolveModuleName(moduleName, containingFile, compilerOptions, host, moduleResolutionCache, redirectedReference, mode); // return result immediately only if global cache support is not enabled or if it is .ts, .tsx or .d.ts if (!resolutionHost.getGlobalCache) { @@ -323,17 +308,10 @@ namespace ts { // otherwise try to load typings from @types const globalCache = resolutionHost.getGlobalCache(); - if (globalCache !== undefined && !isExternalModuleNameRelative(moduleName) && !(primaryResult.resolvedModule && extensionIsTS(primaryResult.resolvedModule.extension))) { + if (globalCache !== undefined && !ts.isExternalModuleNameRelative(moduleName) && !(primaryResult.resolvedModule && ts.extensionIsTS(primaryResult.resolvedModule.extension))) { // create different collection of failed lookup locations for second pass // if it will fail and we've already found something during the first pass - we don't want to pollute its results - const { resolvedModule, failedLookupLocations } = loadModuleFromGlobalCache( - Debug.checkDefined(resolutionHost.globalCacheResolutionModuleName)(moduleName), - resolutionHost.projectName, - compilerOptions, - host, - globalCache, - moduleResolutionCache, - ); + const { resolvedModule, failedLookupLocations } = ts.loadModuleFromGlobalCache(ts.Debug.checkDefined(resolutionHost.globalCacheResolutionModuleName)(moduleName), resolutionHost.projectName, compilerOptions, host, globalCache, moduleResolutionCache); if (resolvedModule) { // Modify existing resolution so its saved in the directory cache as well (primaryResult.resolvedModule as any) = resolvedModule; @@ -346,37 +324,32 @@ namespace ts { return primaryResult; } - function resolveTypeReferenceDirective(typeReferenceDirectiveName: string, containingFile: string | undefined, options: CompilerOptions, host: ModuleResolutionHost, redirectedReference?: ResolvedProjectReference, _containingSourceFile?: SourceFile, resolutionMode?: SourceFile["impliedNodeFormat"] | undefined): CachedResolvedTypeReferenceDirectiveWithFailedLookupLocations { + function resolveTypeReferenceDirective(typeReferenceDirectiveName: string, containingFile: string | undefined, options: ts.CompilerOptions, host: ts.ModuleResolutionHost, redirectedReference?: ts.ResolvedProjectReference, _containingSourceFile?: ts.SourceFile, resolutionMode?: ts.SourceFile["impliedNodeFormat"] | undefined): CachedResolvedTypeReferenceDirectiveWithFailedLookupLocations { return ts.resolveTypeReferenceDirective(typeReferenceDirectiveName, containingFile, options, host, redirectedReference, typeReferenceDirectiveResolutionCache, resolutionMode); } interface ResolveNamesWithLocalCacheInput { - names: readonly string[] | readonly FileReference[]; + names: readonly string[] | readonly ts.FileReference[]; containingFile: string; - redirectedReference: ResolvedProjectReference | undefined; - cache: ESMap>; - perDirectoryCacheWithRedirects: CacheWithRedirects>; - loader: (name: string, containingFile: string, options: CompilerOptions, host: ModuleResolutionHost, redirectedReference?: ResolvedProjectReference, containingSourceFile?: SourceFile, resolutionMode?: ModuleKind.CommonJS | ModuleKind.ESNext | undefined) => T; + redirectedReference: ts.ResolvedProjectReference | undefined; + cache: ts.ESMap>; + perDirectoryCacheWithRedirects: ts.CacheWithRedirects>; + loader: (name: string, containingFile: string, options: ts.CompilerOptions, host: ts.ModuleResolutionHost, redirectedReference?: ts.ResolvedProjectReference, containingSourceFile?: ts.SourceFile, resolutionMode?: ts.ModuleKind.CommonJS | ts.ModuleKind.ESNext | undefined) => T; getResolutionWithResolvedFileName: GetResolutionWithResolvedFileName; shouldRetryResolution: (t: T) => boolean; reusedNames?: readonly string[]; logChanges?: boolean; - containingSourceFile?: SourceFile; - containingSourceFileMode?: SourceFile["impliedNodeFormat"]; - } - function resolveNamesWithLocalCache({ - names, containingFile, redirectedReference, - cache, perDirectoryCacheWithRedirects, - loader, getResolutionWithResolvedFileName, - shouldRetryResolution, reusedNames, logChanges, containingSourceFile, containingSourceFileMode - }: ResolveNamesWithLocalCacheInput): (R | undefined)[] { + containingSourceFile?: ts.SourceFile; + containingSourceFileMode?: ts.SourceFile["impliedNodeFormat"]; + } + function resolveNamesWithLocalCache({ names, containingFile, redirectedReference, cache, perDirectoryCacheWithRedirects, loader, getResolutionWithResolvedFileName, shouldRetryResolution, reusedNames, logChanges, containingSourceFile, containingSourceFileMode }: ResolveNamesWithLocalCacheInput): (R | undefined)[] { const path = resolutionHost.toPath(containingFile); - const resolutionsInFile = cache.get(path) || cache.set(path, createModeAwareCache()).get(path)!; - const dirPath = getDirectoryPath(path); + const resolutionsInFile = cache.get(path) || cache.set(path, ts.createModeAwareCache()).get(path)!; + const dirPath = ts.getDirectoryPath(path); const perDirectoryCache = perDirectoryCacheWithRedirects.getOrCreateMapOfCacheRedirects(redirectedReference); let perDirectoryResolution = perDirectoryCache.get(dirPath); if (!perDirectoryResolution) { - perDirectoryResolution = createModeAwareCache(); + perDirectoryResolution = ts.createModeAwareCache(); perDirectoryCache.set(dirPath, perDirectoryResolution); } const resolvedModules: (R | undefined)[] = []; @@ -390,50 +363,42 @@ namespace ts { !redirectedReference || redirectedReference.sourceFile.path !== oldRedirect.sourceFile.path : !!redirectedReference; - const seenNamesInFile = createModeAwareCache(); + const seenNamesInFile = ts.createModeAwareCache(); let i = 0; for (const entry of names) { - const name = isString(entry) ? entry : entry.fileName.toLowerCase(); + const name = ts.isString(entry) ? entry : entry.fileName.toLowerCase(); // Imports supply a `containingSourceFile` but no `containingSourceFileMode` - it would be redundant // they require calculating the mode for a given import from it's position in the resolution table, since a given // import's syntax may override the file's default mode. // Type references instead supply a `containingSourceFileMode` and a non-string entry which contains // a default file mode override if applicable. - const mode = !isString(entry) ? getModeForFileReference(entry, containingSourceFileMode) : - containingSourceFile ? getModeForResolutionAtIndex(containingSourceFile, i) : undefined; + const mode = !ts.isString(entry) ? ts.getModeForFileReference(entry, containingSourceFileMode) : + containingSourceFile ? ts.getModeForResolutionAtIndex(containingSourceFile, i) : undefined; i++; let resolution = resolutionsInFile.get(name, mode); // Resolution is valid if it is present and not invalidated if (!seenNamesInFile.has(name, mode) && unmatchedRedirects || !resolution || resolution.isInvalidated || // If the name is unresolved import that was invalidated, recalculate - (hasInvalidatedNonRelativeUnresolvedImport && !isExternalModuleNameRelative(name) && shouldRetryResolution(resolution))) { + (hasInvalidatedNonRelativeUnresolvedImport && !ts.isExternalModuleNameRelative(name) && shouldRetryResolution(resolution))) { const existingResolution = resolution; const resolutionInDirectory = perDirectoryResolution.get(name, mode); if (resolutionInDirectory) { resolution = resolutionInDirectory; const host = resolutionHost.getCompilerHost?.() || resolutionHost; - if (isTraceEnabled(compilerOptions, host)) { + if (ts.isTraceEnabled(compilerOptions, host)) { const resolved = getResolutionWithResolvedFileName(resolution); - trace( - host, - loader === resolveModuleName as unknown ? + ts.trace(host, loader === resolveModuleName as unknown ? resolved?.resolvedFileName ? resolved.packagetId ? - Diagnostics.Reusing_resolution_of_module_0_from_1_found_in_cache_from_location_2_it_was_successfully_resolved_to_3_with_Package_ID_4: - Diagnostics.Reusing_resolution_of_module_0_from_1_found_in_cache_from_location_2_it_was_successfully_resolved_to_3: - Diagnostics.Reusing_resolution_of_module_0_from_1_found_in_cache_from_location_2_it_was_not_resolved : + ts.Diagnostics.Reusing_resolution_of_module_0_from_1_found_in_cache_from_location_2_it_was_successfully_resolved_to_3_with_Package_ID_4 : + ts.Diagnostics.Reusing_resolution_of_module_0_from_1_found_in_cache_from_location_2_it_was_successfully_resolved_to_3 : + ts.Diagnostics.Reusing_resolution_of_module_0_from_1_found_in_cache_from_location_2_it_was_not_resolved : resolved?.resolvedFileName ? resolved.packagetId ? - Diagnostics.Reusing_resolution_of_type_reference_directive_0_from_1_found_in_cache_from_location_2_it_was_successfully_resolved_to_3_with_Package_ID_4 : - Diagnostics.Reusing_resolution_of_type_reference_directive_0_from_1_found_in_cache_from_location_2_it_was_successfully_resolved_to_3 : - Diagnostics.Reusing_resolution_of_type_reference_directive_0_from_1_found_in_cache_from_location_2_it_was_not_resolved, - name, - containingFile, - getDirectoryPath(containingFile), - resolved?.resolvedFileName, - resolved?.packagetId && packageIdToString(resolved.packagetId) - ); + ts.Diagnostics.Reusing_resolution_of_type_reference_directive_0_from_1_found_in_cache_from_location_2_it_was_successfully_resolved_to_3_with_Package_ID_4 : + ts.Diagnostics.Reusing_resolution_of_type_reference_directive_0_from_1_found_in_cache_from_location_2_it_was_successfully_resolved_to_3 : + ts.Diagnostics.Reusing_resolution_of_type_reference_directive_0_from_1_found_in_cache_from_location_2_it_was_not_resolved, name, containingFile, ts.getDirectoryPath(containingFile), resolved?.resolvedFileName, resolved?.packagetId && ts.packageIdToString(resolved.packagetId)); } } else { @@ -457,36 +422,29 @@ namespace ts { } else { const host = resolutionHost.getCompilerHost?.() || resolutionHost; - if (isTraceEnabled(compilerOptions, host) && !seenNamesInFile.has(name, mode)) { + if (ts.isTraceEnabled(compilerOptions, host) && !seenNamesInFile.has(name, mode)) { const resolved = getResolutionWithResolvedFileName(resolution); - trace( - host, - loader === resolveModuleName as unknown ? + ts.trace(host, loader === resolveModuleName as unknown ? resolved?.resolvedFileName ? resolved.packagetId ? - Diagnostics.Reusing_resolution_of_module_0_from_1_of_old_program_it_was_successfully_resolved_to_2_with_Package_ID_3 : - Diagnostics.Reusing_resolution_of_module_0_from_1_of_old_program_it_was_successfully_resolved_to_2 : - Diagnostics.Reusing_resolution_of_module_0_from_1_of_old_program_it_was_not_resolved : + ts.Diagnostics.Reusing_resolution_of_module_0_from_1_of_old_program_it_was_successfully_resolved_to_2_with_Package_ID_3 : + ts.Diagnostics.Reusing_resolution_of_module_0_from_1_of_old_program_it_was_successfully_resolved_to_2 : + ts.Diagnostics.Reusing_resolution_of_module_0_from_1_of_old_program_it_was_not_resolved : resolved?.resolvedFileName ? resolved.packagetId ? - Diagnostics.Reusing_resolution_of_type_reference_directive_0_from_1_of_old_program_it_was_successfully_resolved_to_2_with_Package_ID_3 : - Diagnostics.Reusing_resolution_of_type_reference_directive_0_from_1_of_old_program_it_was_successfully_resolved_to_2 : - Diagnostics.Reusing_resolution_of_type_reference_directive_0_from_1_of_old_program_it_was_not_resolved, - name, - containingFile, - resolved?.resolvedFileName, - resolved?.packagetId && packageIdToString(resolved.packagetId) - ); + ts.Diagnostics.Reusing_resolution_of_type_reference_directive_0_from_1_of_old_program_it_was_successfully_resolved_to_2_with_Package_ID_3 : + ts.Diagnostics.Reusing_resolution_of_type_reference_directive_0_from_1_of_old_program_it_was_successfully_resolved_to_2 : + ts.Diagnostics.Reusing_resolution_of_type_reference_directive_0_from_1_of_old_program_it_was_not_resolved, name, containingFile, resolved?.resolvedFileName, resolved?.packagetId && ts.packageIdToString(resolved.packagetId)); } } - Debug.assert(resolution !== undefined && !resolution.isInvalidated); + ts.Debug.assert(resolution !== undefined && !resolution.isInvalidated); seenNamesInFile.set(name, mode, true); resolvedModules.push(getResolutionWithResolvedFileName(resolution)); } // Stop watching and remove the unused name resolutionsInFile.forEach((resolution, name, mode) => { - if (!seenNamesInFile.has(name, mode) && !contains(reusedNames, name)) { + if (!seenNamesInFile.has(name, mode) && !ts.contains(reusedNames, name)) { stopWatchFailedLookupLocationOfResolution(resolution, path, getResolutionWithResolvedFileName); resolutionsInFile.delete(name, mode); } @@ -513,8 +471,8 @@ namespace ts { } } - function resolveTypeReferenceDirectives(typeDirectiveNames: string[] | readonly FileReference[], containingFile: string, redirectedReference?: ResolvedProjectReference, containingFileMode?: SourceFile["impliedNodeFormat"]): (ResolvedTypeReferenceDirective | undefined)[] { - return resolveNamesWithLocalCache({ + function resolveTypeReferenceDirectives(typeDirectiveNames: string[] | readonly ts.FileReference[], containingFile: string, redirectedReference?: ts.ResolvedProjectReference, containingFileMode?: ts.SourceFile["impliedNodeFormat"]): (ts.ResolvedTypeReferenceDirective | undefined)[] { + return resolveNamesWithLocalCache({ names: typeDirectiveNames, containingFile, redirectedReference, @@ -527,8 +485,8 @@ namespace ts { }); } - function resolveModuleNames(moduleNames: string[], containingFile: string, reusedNames: string[] | undefined, redirectedReference?: ResolvedProjectReference, containingSourceFile?: SourceFile): (ResolvedModuleFull | undefined)[] { - return resolveNamesWithLocalCache({ + function resolveModuleNames(moduleNames: string[], containingFile: string, reusedNames: string[] | undefined, redirectedReference?: ts.ResolvedProjectReference, containingSourceFile?: ts.SourceFile): (ts.ResolvedModuleFull | undefined)[] { + return resolveNamesWithLocalCache({ names: moduleNames, containingFile, redirectedReference, @@ -536,35 +494,36 @@ namespace ts { perDirectoryCacheWithRedirects: perDirectoryResolvedModuleNames, loader: resolveModuleName, getResolutionWithResolvedFileName: getResolvedModule, - shouldRetryResolution: resolution => !resolution.resolvedModule || !resolutionExtensionIsTSOrJson(resolution.resolvedModule.extension), + shouldRetryResolution: resolution => !resolution.resolvedModule || !ts.resolutionExtensionIsTSOrJson(resolution.resolvedModule.extension), reusedNames, logChanges: logChangesWhenResolvingModule, containingSourceFile, }); } - function getResolvedModuleWithFailedLookupLocationsFromCache(moduleName: string, containingFile: string, resolutionMode?: ModuleKind.CommonJS | ModuleKind.ESNext): CachedResolvedModuleWithFailedLookupLocations | undefined { + function getResolvedModuleWithFailedLookupLocationsFromCache(moduleName: string, containingFile: string, resolutionMode?: ts.ModuleKind.CommonJS | ts.ModuleKind.ESNext): CachedResolvedModuleWithFailedLookupLocations | undefined { const cache = resolvedModuleNames.get(resolutionHost.toPath(containingFile)); - if (!cache) return undefined; + if (!cache) + return undefined; return cache.get(moduleName, resolutionMode); } - function isNodeModulesAtTypesDirectory(dirPath: Path) { - return endsWith(dirPath, "/node_modules/@types"); + function isNodeModulesAtTypesDirectory(dirPath: ts.Path) { + return ts.endsWith(dirPath, "/node_modules/@types"); } - function getDirectoryToWatchFailedLookupLocation(failedLookupLocation: string, failedLookupLocationPath: Path): DirectoryOfFailedLookupWatch | undefined { + function getDirectoryToWatchFailedLookupLocation(failedLookupLocation: string, failedLookupLocationPath: ts.Path): DirectoryOfFailedLookupWatch | undefined { if (isInDirectoryPath(rootPath, failedLookupLocationPath)) { // Ensure failed look up is normalized path - failedLookupLocation = isRootedDiskPath(failedLookupLocation) ? normalizePath(failedLookupLocation) : getNormalizedAbsolutePath(failedLookupLocation, getCurrentDirectory()); - const failedLookupPathSplit = failedLookupLocationPath.split(directorySeparator); - const failedLookupSplit = failedLookupLocation.split(directorySeparator); - Debug.assert(failedLookupSplit.length === failedLookupPathSplit.length, `FailedLookup: ${failedLookupLocation} failedLookupLocationPath: ${failedLookupLocationPath}`); + failedLookupLocation = ts.isRootedDiskPath(failedLookupLocation) ? ts.normalizePath(failedLookupLocation) : ts.getNormalizedAbsolutePath(failedLookupLocation, getCurrentDirectory()); + const failedLookupPathSplit = failedLookupLocationPath.split(ts.directorySeparator); + const failedLookupSplit = failedLookupLocation.split(ts.directorySeparator); + ts.Debug.assert(failedLookupSplit.length === failedLookupPathSplit.length, `FailedLookup: ${failedLookupLocation} failedLookupLocationPath: ${failedLookupLocationPath}`); if (failedLookupPathSplit.length > rootSplitLength + 1) { // Instead of watching root, watch directory in root to avoid watching excluded directories not needed for module resolution return { - dir: failedLookupSplit.slice(0, rootSplitLength + 1).join(directorySeparator), - dirPath: failedLookupPathSplit.slice(0, rootSplitLength + 1).join(directorySeparator) as Path + dir: failedLookupSplit.slice(0, rootSplitLength + 1).join(ts.directorySeparator), + dirPath: failedLookupPathSplit.slice(0, rootSplitLength + 1).join(ts.directorySeparator) as ts.Path }; } else { @@ -577,30 +536,27 @@ namespace ts { } } - return getDirectoryToWatchFromFailedLookupLocationDirectory( - getDirectoryPath(getNormalizedAbsolutePath(failedLookupLocation, getCurrentDirectory())), - getDirectoryPath(failedLookupLocationPath) - ); + return getDirectoryToWatchFromFailedLookupLocationDirectory(ts.getDirectoryPath(ts.getNormalizedAbsolutePath(failedLookupLocation, getCurrentDirectory())), ts.getDirectoryPath(failedLookupLocationPath)); } - function getDirectoryToWatchFromFailedLookupLocationDirectory(dir: string, dirPath: Path): DirectoryOfFailedLookupWatch | undefined { + function getDirectoryToWatchFromFailedLookupLocationDirectory(dir: string, dirPath: ts.Path): DirectoryOfFailedLookupWatch | undefined { // If directory path contains node module, get the most parent node_modules directory for watching - while (pathContainsNodeModules(dirPath)) { - dir = getDirectoryPath(dir); - dirPath = getDirectoryPath(dirPath); + while (ts.pathContainsNodeModules(dirPath)) { + dir = ts.getDirectoryPath(dir); + dirPath = ts.getDirectoryPath(dirPath); } // If the directory is node_modules use it to watch, always watch it recursively - if (isNodeModulesDirectory(dirPath)) { - return canWatchDirectory(getDirectoryPath(dirPath)) ? { dir, dirPath } : undefined; + if (ts.isNodeModulesDirectory(dirPath)) { + return canWatchDirectory(ts.getDirectoryPath(dirPath)) ? { dir, dirPath } : undefined; } let nonRecursive = true; // Use some ancestor of the root directory - let subDirectoryPath: Path | undefined, subDirectory: string | undefined; + let subDirectoryPath: ts.Path | undefined, subDirectory: string | undefined; if (rootPath !== undefined) { while (!isInDirectoryPath(dirPath, rootPath)) { - const parentPath = getDirectoryPath(dirPath); + const parentPath = ts.getDirectoryPath(dirPath); if (parentPath === dirPath) { break; } @@ -608,31 +564,25 @@ namespace ts { subDirectoryPath = dirPath; subDirectory = dir; dirPath = parentPath; - dir = getDirectoryPath(dir); + dir = ts.getDirectoryPath(dir); } } return canWatchDirectory(dirPath) ? { dir: subDirectory || dir, dirPath: subDirectoryPath || dirPath, nonRecursive } : undefined; } - function isPathWithDefaultFailedLookupExtension(path: Path) { - return fileExtensionIsOneOf(path, failedLookupDefaultExtensions); + function isPathWithDefaultFailedLookupExtension(path: ts.Path) { + return ts.fileExtensionIsOneOf(path, failedLookupDefaultExtensions); } - - function watchFailedLookupLocationsOfExternalModuleResolutions( - name: string, - resolution: T, - filePath: Path, - getResolutionWithResolvedFileName: GetResolutionWithResolvedFileName, - ) { + function watchFailedLookupLocationsOfExternalModuleResolutions(name: string, resolution: T, filePath: ts.Path, getResolutionWithResolvedFileName: GetResolutionWithResolvedFileName) { if (resolution.refCount) { resolution.refCount++; - Debug.assertIsDefined(resolution.files); + ts.Debug.assertIsDefined(resolution.files); } else { resolution.refCount = 1; - Debug.assert(length(resolution.files) === 0); // This resolution shouldnt be referenced by any file yet - if (isExternalModuleNameRelative(name)) { + ts.Debug.assert(ts.length(resolution.files) === 0); // This resolution shouldnt be referenced by any file yet + if (ts.isExternalModuleNameRelative(name)) { watchFailedLookupLocationOfResolution(resolution); } else { @@ -647,10 +597,11 @@ namespace ts { } function watchFailedLookupLocationOfResolution(resolution: ResolutionWithFailedLookupLocations) { - Debug.assert(!!resolution.refCount); + ts.Debug.assert(!!resolution.refCount); const { failedLookupLocations } = resolution; - if (!failedLookupLocations.length) return; + if (!failedLookupLocations.length) + return; resolutionsWithFailedLookups.push(resolution); let setAtRoot = false; @@ -666,7 +617,7 @@ namespace ts { customFailedLookupPaths.set(failedLookupLocationPath, refCount + 1); } if (dirPath === rootPath) { - Debug.assert(!nonRecursive); + ts.Debug.assert(!nonRecursive); setAtRoot = true; } else { @@ -688,10 +639,10 @@ namespace ts { } } - function setDirectoryWatcher(dir: string, dirPath: Path, nonRecursive?: boolean) { + function setDirectoryWatcher(dir: string, dirPath: ts.Path, nonRecursive?: boolean) { const dirWatcher = directoryWatchesOfFailedLookups.get(dirPath); if (dirWatcher) { - Debug.assert(!!nonRecursive === !!dirWatcher.nonRecursive); + ts.Debug.assert(!!nonRecursive === !!dirWatcher.nonRecursive); dirWatcher.refCount++; } else { @@ -699,12 +650,8 @@ namespace ts { } } - function stopWatchFailedLookupLocationOfResolution( - resolution: T, - filePath: Path, - getResolutionWithResolvedFileName: GetResolutionWithResolvedFileName, - ) { - unorderedRemoveItem(Debug.checkDefined(resolution.files), filePath); + function stopWatchFailedLookupLocationOfResolution(resolution: T, filePath: ts.Path, getResolutionWithResolvedFileName: GetResolutionWithResolvedFileName) { + ts.unorderedRemoveItem(ts.Debug.checkDefined(resolution.files), filePath); resolution.refCount!--; if (resolution.refCount) { return; @@ -714,7 +661,7 @@ namespace ts { resolvedFileToResolution.remove(resolutionHost.toPath(resolved.resolvedFileName), resolution); } - if (!unorderedRemoveItem(resolutionsWithFailedLookups, resolution)) { + if (!ts.unorderedRemoveItem(resolutionsWithFailedLookups, resolution)) { // If not watching failed lookups, it wont be there in resolutionsWithFailedLookups return; } @@ -732,7 +679,7 @@ namespace ts { customFailedLookupPaths.delete(failedLookupLocationPath); } else { - Debug.assert(refCount > 1); + ts.Debug.assert(refCount > 1); customFailedLookupPaths.set(failedLookupLocationPath, refCount - 1); } } @@ -756,7 +703,7 @@ namespace ts { dirWatcher.refCount--; } - function createDirectoryWatcher(directory: string, dirPath: Path, nonRecursive: boolean | undefined) { + function createDirectoryWatcher(directory: string, dirPath: ts.Path, nonRecursive: boolean | undefined) { return resolutionHost.watchDirectoryOfFailedLookupLocation(directory, fileOrDirectory => { const fileOrDirectoryPath = resolutionHost.toPath(fileOrDirectory); if (cachedDirectoryStructureHost) { @@ -765,14 +712,9 @@ namespace ts { } scheduleInvalidateResolutionOfFailedLookupLocation(fileOrDirectoryPath, dirPath === fileOrDirectoryPath); - }, nonRecursive ? WatchDirectoryFlags.None : WatchDirectoryFlags.Recursive); + }, nonRecursive ? ts.WatchDirectoryFlags.None : ts.WatchDirectoryFlags.Recursive); } - - function removeResolutionsOfFileFromCache( - cache: ESMap>, - filePath: Path, - getResolutionWithResolvedFileName: GetResolutionWithResolvedFileName, - ) { + function removeResolutionsOfFileFromCache(cache: ts.ESMap>, filePath: ts.Path, getResolutionWithResolvedFileName: GetResolutionWithResolvedFileName) { // Deleted file, stop watching failed lookups for all the resolutions in the file const resolutions = cache.get(filePath); if (resolutions) { @@ -781,57 +723,62 @@ namespace ts { } } - function removeResolutionsFromProjectReferenceRedirects(filePath: Path) { - if (!fileExtensionIs(filePath, Extension.Json)) return; + function removeResolutionsFromProjectReferenceRedirects(filePath: ts.Path) { + if (!ts.fileExtensionIs(filePath, ts.Extension.Json)) + return; const program = resolutionHost.getCurrentProgram(); - if (!program) return; + if (!program) + return; // If this file is input file for the referenced project, get it const resolvedProjectReference = program.getResolvedProjectReferenceByPath(filePath); - if (!resolvedProjectReference) return; + if (!resolvedProjectReference) + return; // filePath is for the projectReference and the containing file is from this project reference, invalidate the resolution resolvedProjectReference.commandLine.fileNames.forEach(f => removeResolutionsOfFile(resolutionHost.toPath(f))); } - function removeResolutionsOfFile(filePath: Path) { + function removeResolutionsOfFile(filePath: ts.Path) { removeResolutionsOfFileFromCache(resolvedModuleNames, filePath, getResolvedModule); removeResolutionsOfFileFromCache(resolvedTypeReferenceDirectives, filePath, getResolvedTypeReferenceDirective); } function invalidateResolutions(resolutions: ResolutionWithFailedLookupLocations[] | undefined, canInvalidate: (resolution: ResolutionWithFailedLookupLocations) => boolean) { - if (!resolutions) return false; + if (!resolutions) + return false; let invalidated = false; for (const resolution of resolutions) { - if (resolution.isInvalidated || !canInvalidate(resolution)) continue; + if (resolution.isInvalidated || !canInvalidate(resolution)) + continue; resolution.isInvalidated = invalidated = true; - for (const containingFilePath of Debug.checkDefined(resolution.files)) { - (filesWithInvalidatedResolutions || (filesWithInvalidatedResolutions = new Set())).add(containingFilePath); + for (const containingFilePath of ts.Debug.checkDefined(resolution.files)) { + (filesWithInvalidatedResolutions || (filesWithInvalidatedResolutions = new ts.Set())).add(containingFilePath); // When its a file with inferred types resolution, invalidate type reference directive resolution - hasChangedAutomaticTypeDirectiveNames = hasChangedAutomaticTypeDirectiveNames || endsWith(containingFilePath, inferredTypesContainingFile); + hasChangedAutomaticTypeDirectiveNames = hasChangedAutomaticTypeDirectiveNames || ts.endsWith(containingFilePath, ts.inferredTypesContainingFile); } } return invalidated; } - function invalidateResolutionOfFile(filePath: Path) { + function invalidateResolutionOfFile(filePath: ts.Path) { removeResolutionsOfFile(filePath); // Resolution is invalidated if the resulting file name is same as the deleted file path const prevHasChangedAutomaticTypeDirectiveNames = hasChangedAutomaticTypeDirectiveNames; - if (invalidateResolutions(resolvedFileToResolution.get(filePath), returnTrue) && + if (invalidateResolutions(resolvedFileToResolution.get(filePath), ts.returnTrue) && hasChangedAutomaticTypeDirectiveNames && !prevHasChangedAutomaticTypeDirectiveNames) { resolutionHost.onChangedAutomaticTypeDirectiveNames(); } } - function setFilesWithInvalidatedNonRelativeUnresolvedImports(filesMap: ReadonlyESMap) { - Debug.assert(filesWithInvalidatedNonRelativeUnresolvedImports === filesMap || filesWithInvalidatedNonRelativeUnresolvedImports === undefined); + function setFilesWithInvalidatedNonRelativeUnresolvedImports(filesMap: ts.ReadonlyESMap) { + ts.Debug.assert(filesWithInvalidatedNonRelativeUnresolvedImports === filesMap || filesWithInvalidatedNonRelativeUnresolvedImports === undefined); filesWithInvalidatedNonRelativeUnresolvedImports = filesMap; } - function scheduleInvalidateResolutionOfFailedLookupLocation(fileOrDirectoryPath: Path, isCreatingWatchedDirectory: boolean) { + function scheduleInvalidateResolutionOfFailedLookupLocation(fileOrDirectoryPath: ts.Path, isCreatingWatchedDirectory: boolean) { if (isCreatingWatchedDirectory) { // Watching directory is created // Invalidate any resolution has failed lookup in this directory @@ -840,7 +787,8 @@ namespace ts { else { // If something to do with folder/file starting with "." in node_modules folder, skip it const updatedPath = removeIgnoredPath(fileOrDirectoryPath); - if (!updatedPath) return false; + if (!updatedPath) + return false; fileOrDirectoryPath = updatedPath; // prevent saving an open file from over-eagerly triggering invalidation @@ -850,19 +798,19 @@ namespace ts { // Some file or directory in the watching directory is created // Return early if it does not have any of the watching extension or not the custom failed lookup path - const dirOfFileOrDirectory = getDirectoryPath(fileOrDirectoryPath); - if (isNodeModulesAtTypesDirectory(fileOrDirectoryPath) || isNodeModulesDirectory(fileOrDirectoryPath) || - isNodeModulesAtTypesDirectory(dirOfFileOrDirectory) || isNodeModulesDirectory(dirOfFileOrDirectory)) { + const dirOfFileOrDirectory = ts.getDirectoryPath(fileOrDirectoryPath); + if (isNodeModulesAtTypesDirectory(fileOrDirectoryPath) || ts.isNodeModulesDirectory(fileOrDirectoryPath) || + isNodeModulesAtTypesDirectory(dirOfFileOrDirectory) || ts.isNodeModulesDirectory(dirOfFileOrDirectory)) { // Invalidate any resolution from this directory (failedLookupChecks ||= []).push(fileOrDirectoryPath); - (startsWithPathChecks ||= new Set()).add(fileOrDirectoryPath); + (startsWithPathChecks ||= new ts.Set()).add(fileOrDirectoryPath); } else { if (!isPathWithDefaultFailedLookupExtension(fileOrDirectoryPath) && !customFailedLookupPaths.has(fileOrDirectoryPath)) { return false; } // Ignore emits from the program - if (isEmittedFileOfProgram(resolutionHost.getCurrentProgram(), fileOrDirectoryPath)) { + if (ts.isEmittedFileOfProgram(resolutionHost.getCurrentProgram(), fileOrDirectoryPath)) { return false; } // Resolution need to be invalidated if failed lookup location is same as the file or directory getting created @@ -871,8 +819,9 @@ namespace ts { // If the invalidated file is from a node_modules package, invalidate everything else // in the package since we might not get notifications for other files in the package. // This hardens our logic against unreliable file watchers. - const packagePath = parseNodeModuleFromPath(fileOrDirectoryPath); - if (packagePath) (startsWithPathChecks ||= new Set()).add(packagePath as Path); + const packagePath = ts.parseNodeModuleFromPath(fileOrDirectoryPath); + if (packagePath) + (startsWithPathChecks ||= new ts.Set()).add(packagePath as ts.Path); } } resolutionHost.scheduleInvalidateResolutionsOfFailedLookupLocations(); @@ -893,17 +842,17 @@ namespace ts { function canInvalidateFailedLookupResolution(resolution: ResolutionWithFailedLookupLocations) { return resolution.failedLookupLocations.some(location => { const locationPath = resolutionHost.toPath(location); - return contains(failedLookupChecks, locationPath) || - firstDefinedIterator(startsWithPathChecks?.keys() || emptyIterator, fileOrDirectoryPath => startsWith(locationPath, fileOrDirectoryPath) ? true : undefined) || + return ts.contains(failedLookupChecks, locationPath) || + ts.firstDefinedIterator(startsWithPathChecks?.keys() || ts.emptyIterator, fileOrDirectoryPath => ts.startsWith(locationPath, fileOrDirectoryPath) ? true : undefined) || isInDirectoryChecks?.some(fileOrDirectoryPath => isInDirectoryPath(fileOrDirectoryPath, locationPath)); }); } function closeTypeRootsWatch() { - clearMap(typeRootsWatches, closeFileWatcher); + ts.clearMap(typeRootsWatches, ts.closeFileWatcher); } - function getDirectoryToWatchFailedLookupLocationFromTypeRoot(typeRoot: string, typeRootPath: Path): Path | undefined { + function getDirectoryToWatchFailedLookupLocationFromTypeRoot(typeRoot: string, typeRootPath: ts.Path): ts.Path | undefined { if (isInDirectoryPath(rootPath, typeRootPath)) { return rootPath; } @@ -911,7 +860,7 @@ namespace ts { return toWatch && directoryWatchesOfFailedLookups.has(toWatch.dirPath) ? toWatch.dirPath : undefined; } - function createTypeRootsWatch(typeRootPath: Path, typeRoot: string): FileWatcher { + function createTypeRootsWatch(typeRootPath: ts.Path, typeRoot: string): ts.FileWatcher { // Create new watch and recursive info return resolutionHost.watchTypeRootsDirectory(typeRoot, fileOrDirectory => { const fileOrDirectoryPath = resolutionHost.toPath(fileOrDirectory); @@ -932,7 +881,7 @@ namespace ts { if (dirPath) { scheduleInvalidateResolutionOfFailedLookupLocation(fileOrDirectoryPath, dirPath === fileOrDirectoryPath); } - }, WatchDirectoryFlags.Recursive); + }, ts.WatchDirectoryFlags.Recursive); } /** @@ -950,16 +899,12 @@ namespace ts { // we need to assume the directories exist to ensure that we can get all the type root directories that get included // But filter directories that are at root level to say directory doesnt exist, so that we arent watching them - const typeRoots = getEffectiveTypeRoots(options, { directoryExists: directoryExistsForTypeRootWatch, getCurrentDirectory }); + const typeRoots = ts.getEffectiveTypeRoots(options, { directoryExists: directoryExistsForTypeRootWatch, getCurrentDirectory }); if (typeRoots) { - mutateMap( - typeRootsWatches, - arrayToMap(typeRoots, tr => resolutionHost.toPath(tr)), - { + ts.mutateMap(typeRootsWatches, ts.arrayToMap(typeRoots, tr => resolutionHost.toPath(tr)), { createNewValue: createTypeRootsWatch, - onDeleteValue: closeFileWatcher - } - ); + onDeleteValue: ts.closeFileWatcher + }); } else { closeTypeRootsWatch(); @@ -972,16 +917,14 @@ namespace ts { * Hence return true for all directories except root directories which are filtered from watching */ function directoryExistsForTypeRootWatch(nodeTypesDirectory: string) { - const dir = getDirectoryPath(getDirectoryPath(nodeTypesDirectory)); + const dir = ts.getDirectoryPath(ts.getDirectoryPath(nodeTypesDirectory)); const dirPath = resolutionHost.toPath(dir); return dirPath === rootPath || canWatchDirectory(dirPath); } } function resolutionIsSymlink(resolution: ResolutionWithFailedLookupLocations) { - return !!( - (resolution as ResolvedModuleWithFailedLookupLocations).resolvedModule?.originalPath || - (resolution as ResolvedTypeReferenceDirectiveWithFailedLookupLocations).resolvedTypeReferenceDirective?.originalPath - ); + return !!((resolution as ts.ResolvedModuleWithFailedLookupLocations).resolvedModule?.originalPath || + (resolution as ts.ResolvedTypeReferenceDirectiveWithFailedLookupLocations).resolvedTypeReferenceDirective?.originalPath); } } diff --git a/src/compiler/scanner.ts b/src/compiler/scanner.ts index 107ff3a143efa..ea468b4b489c2 100644 --- a/src/compiler/scanner.ts +++ b/src/compiler/scanner.ts @@ -1,19 +1,19 @@ namespace ts { - export type ErrorCallback = (message: DiagnosticMessage, length: number) => void; + export type ErrorCallback = (message: ts.DiagnosticMessage, length: number) => void; /* @internal */ - export function tokenIsIdentifierOrKeyword(token: SyntaxKind): boolean { - return token >= SyntaxKind.Identifier; + export function tokenIsIdentifierOrKeyword(token: ts.SyntaxKind): boolean { + return token >= ts.SyntaxKind.Identifier; } /* @internal */ - export function tokenIsIdentifierOrKeywordOrGreaterThan(token: SyntaxKind): boolean { - return token === SyntaxKind.GreaterThanToken || tokenIsIdentifierOrKeyword(token); + export function tokenIsIdentifierOrKeywordOrGreaterThan(token: ts.SyntaxKind): boolean { + return token === ts.SyntaxKind.GreaterThanToken || tokenIsIdentifierOrKeyword(token); } export interface Scanner { getStartPos(): number; - getToken(): SyntaxKind; + getToken(): ts.SyntaxKind; getTextPos(): number; getTokenPos(): number; getTokenText(): string; @@ -27,27 +27,27 @@ namespace ts { isReservedWord(): boolean; isUnterminated(): boolean; /* @internal */ - getNumericLiteralFlags(): TokenFlags; + getNumericLiteralFlags(): ts.TokenFlags; /* @internal */ - getCommentDirectives(): CommentDirective[] | undefined; + getCommentDirectives(): ts.CommentDirective[] | undefined; /* @internal */ - getTokenFlags(): TokenFlags; - reScanGreaterToken(): SyntaxKind; - reScanSlashToken(): SyntaxKind; - reScanAsteriskEqualsToken(): SyntaxKind; - reScanTemplateToken(isTaggedTemplate: boolean): SyntaxKind; - reScanTemplateHeadOrNoSubstitutionTemplate(): SyntaxKind; - scanJsxIdentifier(): SyntaxKind; - scanJsxAttributeValue(): SyntaxKind; - reScanJsxAttributeValue(): SyntaxKind; - reScanJsxToken(allowMultilineJsxText?: boolean): JsxTokenSyntaxKind; - reScanLessThanToken(): SyntaxKind; - reScanHashToken(): SyntaxKind; - reScanQuestionToken(): SyntaxKind; - reScanInvalidIdentifier(): SyntaxKind; - scanJsxToken(): JsxTokenSyntaxKind; - scanJsDocToken(): JSDocSyntaxKind; - scan(): SyntaxKind; + getTokenFlags(): ts.TokenFlags; + reScanGreaterToken(): ts.SyntaxKind; + reScanSlashToken(): ts.SyntaxKind; + reScanAsteriskEqualsToken(): ts.SyntaxKind; + reScanTemplateToken(isTaggedTemplate: boolean): ts.SyntaxKind; + reScanTemplateHeadOrNoSubstitutionTemplate(): ts.SyntaxKind; + scanJsxIdentifier(): ts.SyntaxKind; + scanJsxAttributeValue(): ts.SyntaxKind; + reScanJsxAttributeValue(): ts.SyntaxKind; + reScanJsxToken(allowMultilineJsxText?: boolean): ts.JsxTokenSyntaxKind; + reScanLessThanToken(): ts.SyntaxKind; + reScanHashToken(): ts.SyntaxKind; + reScanQuestionToken(): ts.SyntaxKind; + reScanInvalidIdentifier(): ts.SyntaxKind; + scanJsxToken(): ts.JsxTokenSyntaxKind; + scanJsDocToken(): ts.JSDocSyntaxKind; + scan(): ts.SyntaxKind; getText(): string; /* @internal */ @@ -56,8 +56,8 @@ namespace ts { // can be provided to have the scanner only scan a portion of the text. setText(text: string | undefined, start?: number, length?: number): void; setOnError(onError: ErrorCallback | undefined): void; - setScriptTarget(scriptTarget: ScriptTarget): void; - setLanguageVariant(variant: LanguageVariant): void; + setScriptTarget(scriptTarget: ts.ScriptTarget): void; + setLanguageVariant(variant: ts.LanguageVariant): void; setTextPos(textPos: number): void; /* @internal */ setInJSDocType(inType: boolean): void; @@ -78,154 +78,153 @@ namespace ts { } /** @internal */ - export const textToKeywordObj: MapLike = { - abstract: SyntaxKind.AbstractKeyword, - any: SyntaxKind.AnyKeyword, - as: SyntaxKind.AsKeyword, - asserts: SyntaxKind.AssertsKeyword, - assert: SyntaxKind.AssertKeyword, - bigint: SyntaxKind.BigIntKeyword, - boolean: SyntaxKind.BooleanKeyword, - break: SyntaxKind.BreakKeyword, - case: SyntaxKind.CaseKeyword, - catch: SyntaxKind.CatchKeyword, - class: SyntaxKind.ClassKeyword, - continue: SyntaxKind.ContinueKeyword, - const: SyntaxKind.ConstKeyword, - ["" + "constructor"]: SyntaxKind.ConstructorKeyword, - debugger: SyntaxKind.DebuggerKeyword, - declare: SyntaxKind.DeclareKeyword, - default: SyntaxKind.DefaultKeyword, - delete: SyntaxKind.DeleteKeyword, - do: SyntaxKind.DoKeyword, - else: SyntaxKind.ElseKeyword, - enum: SyntaxKind.EnumKeyword, - export: SyntaxKind.ExportKeyword, - extends: SyntaxKind.ExtendsKeyword, - false: SyntaxKind.FalseKeyword, - finally: SyntaxKind.FinallyKeyword, - for: SyntaxKind.ForKeyword, - from: SyntaxKind.FromKeyword, - function: SyntaxKind.FunctionKeyword, - get: SyntaxKind.GetKeyword, - if: SyntaxKind.IfKeyword, - implements: SyntaxKind.ImplementsKeyword, - import: SyntaxKind.ImportKeyword, - in: SyntaxKind.InKeyword, - infer: SyntaxKind.InferKeyword, - instanceof: SyntaxKind.InstanceOfKeyword, - interface: SyntaxKind.InterfaceKeyword, - intrinsic: SyntaxKind.IntrinsicKeyword, - is: SyntaxKind.IsKeyword, - keyof: SyntaxKind.KeyOfKeyword, - let: SyntaxKind.LetKeyword, - module: SyntaxKind.ModuleKeyword, - namespace: SyntaxKind.NamespaceKeyword, - never: SyntaxKind.NeverKeyword, - new: SyntaxKind.NewKeyword, - null: SyntaxKind.NullKeyword, - number: SyntaxKind.NumberKeyword, - object: SyntaxKind.ObjectKeyword, - package: SyntaxKind.PackageKeyword, - private: SyntaxKind.PrivateKeyword, - protected: SyntaxKind.ProtectedKeyword, - public: SyntaxKind.PublicKeyword, - override: SyntaxKind.OverrideKeyword, - out: SyntaxKind.OutKeyword, - readonly: SyntaxKind.ReadonlyKeyword, - require: SyntaxKind.RequireKeyword, - global: SyntaxKind.GlobalKeyword, - return: SyntaxKind.ReturnKeyword, - set: SyntaxKind.SetKeyword, - static: SyntaxKind.StaticKeyword, - string: SyntaxKind.StringKeyword, - super: SyntaxKind.SuperKeyword, - switch: SyntaxKind.SwitchKeyword, - symbol: SyntaxKind.SymbolKeyword, - this: SyntaxKind.ThisKeyword, - throw: SyntaxKind.ThrowKeyword, - true: SyntaxKind.TrueKeyword, - try: SyntaxKind.TryKeyword, - type: SyntaxKind.TypeKeyword, - typeof: SyntaxKind.TypeOfKeyword, - undefined: SyntaxKind.UndefinedKeyword, - unique: SyntaxKind.UniqueKeyword, - unknown: SyntaxKind.UnknownKeyword, - var: SyntaxKind.VarKeyword, - void: SyntaxKind.VoidKeyword, - while: SyntaxKind.WhileKeyword, - with: SyntaxKind.WithKeyword, - yield: SyntaxKind.YieldKeyword, - async: SyntaxKind.AsyncKeyword, - await: SyntaxKind.AwaitKeyword, - of: SyntaxKind.OfKeyword, + export const textToKeywordObj: ts.MapLike = { + abstract: ts.SyntaxKind.AbstractKeyword, + any: ts.SyntaxKind.AnyKeyword, + as: ts.SyntaxKind.AsKeyword, + asserts: ts.SyntaxKind.AssertsKeyword, + assert: ts.SyntaxKind.AssertKeyword, + bigint: ts.SyntaxKind.BigIntKeyword, + boolean: ts.SyntaxKind.BooleanKeyword, + break: ts.SyntaxKind.BreakKeyword, + case: ts.SyntaxKind.CaseKeyword, + catch: ts.SyntaxKind.CatchKeyword, + class: ts.SyntaxKind.ClassKeyword, + continue: ts.SyntaxKind.ContinueKeyword, + const: ts.SyntaxKind.ConstKeyword, + ["" + "constructor"]: ts.SyntaxKind.ConstructorKeyword, + debugger: ts.SyntaxKind.DebuggerKeyword, + declare: ts.SyntaxKind.DeclareKeyword, + default: ts.SyntaxKind.DefaultKeyword, + delete: ts.SyntaxKind.DeleteKeyword, + do: ts.SyntaxKind.DoKeyword, + else: ts.SyntaxKind.ElseKeyword, + enum: ts.SyntaxKind.EnumKeyword, + export: ts.SyntaxKind.ExportKeyword, + extends: ts.SyntaxKind.ExtendsKeyword, + false: ts.SyntaxKind.FalseKeyword, + finally: ts.SyntaxKind.FinallyKeyword, + for: ts.SyntaxKind.ForKeyword, + from: ts.SyntaxKind.FromKeyword, + function: ts.SyntaxKind.FunctionKeyword, + get: ts.SyntaxKind.GetKeyword, + if: ts.SyntaxKind.IfKeyword, + implements: ts.SyntaxKind.ImplementsKeyword, + import: ts.SyntaxKind.ImportKeyword, + in: ts.SyntaxKind.InKeyword, + infer: ts.SyntaxKind.InferKeyword, + instanceof: ts.SyntaxKind.InstanceOfKeyword, + interface: ts.SyntaxKind.InterfaceKeyword, + intrinsic: ts.SyntaxKind.IntrinsicKeyword, + is: ts.SyntaxKind.IsKeyword, + keyof: ts.SyntaxKind.KeyOfKeyword, + let: ts.SyntaxKind.LetKeyword, + module: ts.SyntaxKind.ModuleKeyword, + namespace: ts.SyntaxKind.NamespaceKeyword, + never: ts.SyntaxKind.NeverKeyword, + new: ts.SyntaxKind.NewKeyword, + null: ts.SyntaxKind.NullKeyword, + number: ts.SyntaxKind.NumberKeyword, + object: ts.SyntaxKind.ObjectKeyword, + package: ts.SyntaxKind.PackageKeyword, + private: ts.SyntaxKind.PrivateKeyword, + protected: ts.SyntaxKind.ProtectedKeyword, + public: ts.SyntaxKind.PublicKeyword, + override: ts.SyntaxKind.OverrideKeyword, + out: ts.SyntaxKind.OutKeyword, + readonly: ts.SyntaxKind.ReadonlyKeyword, + require: ts.SyntaxKind.RequireKeyword, + global: ts.SyntaxKind.GlobalKeyword, + return: ts.SyntaxKind.ReturnKeyword, + set: ts.SyntaxKind.SetKeyword, + static: ts.SyntaxKind.StaticKeyword, + string: ts.SyntaxKind.StringKeyword, + super: ts.SyntaxKind.SuperKeyword, + switch: ts.SyntaxKind.SwitchKeyword, + symbol: ts.SyntaxKind.SymbolKeyword, + this: ts.SyntaxKind.ThisKeyword, + throw: ts.SyntaxKind.ThrowKeyword, + true: ts.SyntaxKind.TrueKeyword, + try: ts.SyntaxKind.TryKeyword, + type: ts.SyntaxKind.TypeKeyword, + typeof: ts.SyntaxKind.TypeOfKeyword, + undefined: ts.SyntaxKind.UndefinedKeyword, + unique: ts.SyntaxKind.UniqueKeyword, + unknown: ts.SyntaxKind.UnknownKeyword, + var: ts.SyntaxKind.VarKeyword, + void: ts.SyntaxKind.VoidKeyword, + while: ts.SyntaxKind.WhileKeyword, + with: ts.SyntaxKind.WithKeyword, + yield: ts.SyntaxKind.YieldKeyword, + async: ts.SyntaxKind.AsyncKeyword, + await: ts.SyntaxKind.AwaitKeyword, + of: ts.SyntaxKind.OfKeyword, }; - const textToKeyword = new Map(getEntries(textToKeywordObj)); - - const textToToken = new Map(getEntries({ + const textToKeyword = new ts.Map(ts.getEntries(textToKeywordObj)); + const textToToken = new ts.Map(ts.getEntries({ ...textToKeywordObj, - "{": SyntaxKind.OpenBraceToken, - "}": SyntaxKind.CloseBraceToken, - "(": SyntaxKind.OpenParenToken, - ")": SyntaxKind.CloseParenToken, - "[": SyntaxKind.OpenBracketToken, - "]": SyntaxKind.CloseBracketToken, - ".": SyntaxKind.DotToken, - "...": SyntaxKind.DotDotDotToken, - ";": SyntaxKind.SemicolonToken, - ",": SyntaxKind.CommaToken, - "<": SyntaxKind.LessThanToken, - ">": SyntaxKind.GreaterThanToken, - "<=": SyntaxKind.LessThanEqualsToken, - ">=": SyntaxKind.GreaterThanEqualsToken, - "==": SyntaxKind.EqualsEqualsToken, - "!=": SyntaxKind.ExclamationEqualsToken, - "===": SyntaxKind.EqualsEqualsEqualsToken, - "!==": SyntaxKind.ExclamationEqualsEqualsToken, - "=>": SyntaxKind.EqualsGreaterThanToken, - "+": SyntaxKind.PlusToken, - "-": SyntaxKind.MinusToken, - "**": SyntaxKind.AsteriskAsteriskToken, - "*": SyntaxKind.AsteriskToken, - "/": SyntaxKind.SlashToken, - "%": SyntaxKind.PercentToken, - "++": SyntaxKind.PlusPlusToken, - "--": SyntaxKind.MinusMinusToken, - "<<": SyntaxKind.LessThanLessThanToken, - ">": SyntaxKind.GreaterThanGreaterThanToken, - ">>>": SyntaxKind.GreaterThanGreaterThanGreaterThanToken, - "&": SyntaxKind.AmpersandToken, - "|": SyntaxKind.BarToken, - "^": SyntaxKind.CaretToken, - "!": SyntaxKind.ExclamationToken, - "~": SyntaxKind.TildeToken, - "&&": SyntaxKind.AmpersandAmpersandToken, - "||": SyntaxKind.BarBarToken, - "?": SyntaxKind.QuestionToken, - "??": SyntaxKind.QuestionQuestionToken, - "?.": SyntaxKind.QuestionDotToken, - ":": SyntaxKind.ColonToken, - "=": SyntaxKind.EqualsToken, - "+=": SyntaxKind.PlusEqualsToken, - "-=": SyntaxKind.MinusEqualsToken, - "*=": SyntaxKind.AsteriskEqualsToken, - "**=": SyntaxKind.AsteriskAsteriskEqualsToken, - "/=": SyntaxKind.SlashEqualsToken, - "%=": SyntaxKind.PercentEqualsToken, - "<<=": SyntaxKind.LessThanLessThanEqualsToken, - ">>=": SyntaxKind.GreaterThanGreaterThanEqualsToken, - ">>>=": SyntaxKind.GreaterThanGreaterThanGreaterThanEqualsToken, - "&=": SyntaxKind.AmpersandEqualsToken, - "|=": SyntaxKind.BarEqualsToken, - "^=": SyntaxKind.CaretEqualsToken, - "||=": SyntaxKind.BarBarEqualsToken, - "&&=": SyntaxKind.AmpersandAmpersandEqualsToken, - "??=": SyntaxKind.QuestionQuestionEqualsToken, - "@": SyntaxKind.AtToken, - "#": SyntaxKind.HashToken, - "`": SyntaxKind.BacktickToken, + "{": ts.SyntaxKind.OpenBraceToken, + "}": ts.SyntaxKind.CloseBraceToken, + "(": ts.SyntaxKind.OpenParenToken, + ")": ts.SyntaxKind.CloseParenToken, + "[": ts.SyntaxKind.OpenBracketToken, + "]": ts.SyntaxKind.CloseBracketToken, + ".": ts.SyntaxKind.DotToken, + "...": ts.SyntaxKind.DotDotDotToken, + ";": ts.SyntaxKind.SemicolonToken, + ",": ts.SyntaxKind.CommaToken, + "<": ts.SyntaxKind.LessThanToken, + ">": ts.SyntaxKind.GreaterThanToken, + "<=": ts.SyntaxKind.LessThanEqualsToken, + ">=": ts.SyntaxKind.GreaterThanEqualsToken, + "==": ts.SyntaxKind.EqualsEqualsToken, + "!=": ts.SyntaxKind.ExclamationEqualsToken, + "===": ts.SyntaxKind.EqualsEqualsEqualsToken, + "!==": ts.SyntaxKind.ExclamationEqualsEqualsToken, + "=>": ts.SyntaxKind.EqualsGreaterThanToken, + "+": ts.SyntaxKind.PlusToken, + "-": ts.SyntaxKind.MinusToken, + "**": ts.SyntaxKind.AsteriskAsteriskToken, + "*": ts.SyntaxKind.AsteriskToken, + "/": ts.SyntaxKind.SlashToken, + "%": ts.SyntaxKind.PercentToken, + "++": ts.SyntaxKind.PlusPlusToken, + "--": ts.SyntaxKind.MinusMinusToken, + "<<": ts.SyntaxKind.LessThanLessThanToken, + ">": ts.SyntaxKind.GreaterThanGreaterThanToken, + ">>>": ts.SyntaxKind.GreaterThanGreaterThanGreaterThanToken, + "&": ts.SyntaxKind.AmpersandToken, + "|": ts.SyntaxKind.BarToken, + "^": ts.SyntaxKind.CaretToken, + "!": ts.SyntaxKind.ExclamationToken, + "~": ts.SyntaxKind.TildeToken, + "&&": ts.SyntaxKind.AmpersandAmpersandToken, + "||": ts.SyntaxKind.BarBarToken, + "?": ts.SyntaxKind.QuestionToken, + "??": ts.SyntaxKind.QuestionQuestionToken, + "?.": ts.SyntaxKind.QuestionDotToken, + ":": ts.SyntaxKind.ColonToken, + "=": ts.SyntaxKind.EqualsToken, + "+=": ts.SyntaxKind.PlusEqualsToken, + "-=": ts.SyntaxKind.MinusEqualsToken, + "*=": ts.SyntaxKind.AsteriskEqualsToken, + "**=": ts.SyntaxKind.AsteriskAsteriskEqualsToken, + "/=": ts.SyntaxKind.SlashEqualsToken, + "%=": ts.SyntaxKind.PercentEqualsToken, + "<<=": ts.SyntaxKind.LessThanLessThanEqualsToken, + ">>=": ts.SyntaxKind.GreaterThanGreaterThanEqualsToken, + ">>>=": ts.SyntaxKind.GreaterThanGreaterThanGreaterThanEqualsToken, + "&=": ts.SyntaxKind.AmpersandEqualsToken, + "|=": ts.SyntaxKind.BarEqualsToken, + "^=": ts.SyntaxKind.CaretEqualsToken, + "||=": ts.SyntaxKind.BarBarEqualsToken, + "&&=": ts.SyntaxKind.AmpersandAmpersandEqualsToken, + "??=": ts.SyntaxKind.QuestionQuestionEqualsToken, + "@": ts.SyntaxKind.AtToken, + "#": ts.SyntaxKind.HashToken, + "`": ts.SyntaxKind.BacktickToken, })); /* @@ -325,21 +324,21 @@ namespace ts { return false; } - /* @internal */ export function isUnicodeIdentifierStart(code: number, languageVersion: ScriptTarget | undefined) { - return languageVersion! >= ScriptTarget.ES2015 ? + /* @internal */ export function isUnicodeIdentifierStart(code: number, languageVersion: ts.ScriptTarget | undefined) { + return languageVersion! >= ts.ScriptTarget.ES2015 ? lookupInUnicodeMap(code, unicodeESNextIdentifierStart) : - languageVersion === ScriptTarget.ES5 ? lookupInUnicodeMap(code, unicodeES5IdentifierStart) : + languageVersion === ts.ScriptTarget.ES5 ? lookupInUnicodeMap(code, unicodeES5IdentifierStart) : lookupInUnicodeMap(code, unicodeES3IdentifierStart); } - function isUnicodeIdentifierPart(code: number, languageVersion: ScriptTarget | undefined) { - return languageVersion! >= ScriptTarget.ES2015 ? + function isUnicodeIdentifierPart(code: number, languageVersion: ts.ScriptTarget | undefined) { + return languageVersion! >= ts.ScriptTarget.ES2015 ? lookupInUnicodeMap(code, unicodeESNextIdentifierPart) : - languageVersion === ScriptTarget.ES5 ? lookupInUnicodeMap(code, unicodeES5IdentifierPart) : + languageVersion === ts.ScriptTarget.ES5 ? lookupInUnicodeMap(code, unicodeES5IdentifierPart) : lookupInUnicodeMap(code, unicodeES3IdentifierPart); } - function makeReverseMap(source: ESMap): string[] { + function makeReverseMap(source: ts.ESMap): string[] { const result: string[] = []; source.forEach((value, name) => { result[value] = name; @@ -348,12 +347,12 @@ namespace ts { } const tokenStrings = makeReverseMap(textToToken); - export function tokenToString(t: SyntaxKind): string | undefined { + export function tokenToString(t: ts.SyntaxKind): string | undefined { return tokenStrings[t]; } /* @internal */ - export function stringToToken(s: string): SyntaxKind | undefined { + export function stringToToken(s: string): ts.SyntaxKind | undefined { return textToToken.get(s); } @@ -366,17 +365,17 @@ namespace ts { const ch = text.charCodeAt(pos); pos++; switch (ch) { - case CharacterCodes.carriageReturn: - if (text.charCodeAt(pos) === CharacterCodes.lineFeed) { + case ts.CharacterCodes.carriageReturn: + if (text.charCodeAt(pos) === ts.CharacterCodes.lineFeed) { pos++; } // falls through - case CharacterCodes.lineFeed: + case ts.CharacterCodes.lineFeed: result.push(lineStart); lineStart = pos; break; default: - if (ch > CharacterCodes.maxAsciiCharacter && isLineBreak(ch)) { + if (ch > ts.CharacterCodes.maxAsciiCharacter && isLineBreak(ch)) { result.push(lineStart); lineStart = pos; } @@ -387,10 +386,10 @@ namespace ts { return result; } - export function getPositionOfLineAndCharacter(sourceFile: SourceFileLike, line: number, character: number): number; + export function getPositionOfLineAndCharacter(sourceFile: ts.SourceFileLike, line: number, character: number): number; /* @internal */ - export function getPositionOfLineAndCharacter(sourceFile: SourceFileLike, line: number, character: number, allowEdits?: true): number; // eslint-disable-line @typescript-eslint/unified-signatures - export function getPositionOfLineAndCharacter(sourceFile: SourceFileLike, line: number, character: number, allowEdits?: true): number { + export function getPositionOfLineAndCharacter(sourceFile: ts.SourceFileLike, line: number, character: number, allowEdits?: true): number; // eslint-disable-line @typescript-eslint/unified-signatures + export function getPositionOfLineAndCharacter(sourceFile: ts.SourceFileLike, line: number, character: number, allowEdits?: true): number { return sourceFile.getPositionOfLineAndCharacter ? sourceFile.getPositionOfLineAndCharacter(line, character, allowEdits) : computePositionOfLineAndCharacter(getLineStarts(sourceFile), line, character, sourceFile.text, allowEdits); @@ -404,7 +403,7 @@ namespace ts { line = line < 0 ? 0 : line >= lineStarts.length ? lineStarts.length - 1 : line; } else { - Debug.fail(`Bad line number. Line: ${line}, lineStarts.length: ${lineStarts.length} , line map is correct? ${debugText !== undefined ? arraysEqual(lineStarts, computeLineStarts(debugText)) : "unknown"}`); + ts.Debug.fail(`Bad line number. Line: ${line}, lineStarts.length: ${lineStarts.length} , line map is correct? ${debugText !== undefined ? ts.arraysEqual(lineStarts, computeLineStarts(debugText)) : "unknown"}`); } } @@ -416,21 +415,21 @@ namespace ts { return res > lineStarts[line + 1] ? lineStarts[line + 1] : typeof debugText === "string" && res > debugText.length ? debugText.length : res; } if (line < lineStarts.length - 1) { - Debug.assert(res < lineStarts[line + 1]); + ts.Debug.assert(res < lineStarts[line + 1]); } else if (debugText !== undefined) { - Debug.assert(res <= debugText.length); // Allow single character overflow for trailing newline + ts.Debug.assert(res <= debugText.length); // Allow single character overflow for trailing newline } return res; } /* @internal */ - export function getLineStarts(sourceFile: SourceFileLike): readonly number[] { + export function getLineStarts(sourceFile: ts.SourceFileLike): readonly number[] { return sourceFile.lineMap || (sourceFile.lineMap = computeLineStarts(sourceFile.text)); } /* @internal */ - export function computeLineAndCharacterOfPosition(lineStarts: readonly number[], position: number): LineAndCharacter { + export function computeLineAndCharacterOfPosition(lineStarts: readonly number[], position: number): ts.LineAndCharacter { const lineNumber = computeLineOfPosition(lineStarts, position); return { line: lineNumber, @@ -443,7 +442,7 @@ namespace ts { * We assume the first line starts at position 0 and 'position' is non-negative. */ export function computeLineOfPosition(lineStarts: readonly number[], position: number, lowerBound?: number) { - let lineNumber = binarySearch(lineStarts, position, identity, compareValues, lowerBound); + let lineNumber = ts.binarySearch(lineStarts, position, ts.identity, ts.compareValues, lowerBound); if (lineNumber < 0) { // If the actual position was not found, // the binary search returns the 2's-complement of the next line start @@ -453,14 +452,15 @@ namespace ts { // We want the index of the previous line start, so we subtract 1. // Review 2's-complement if this is confusing. lineNumber = ~lineNumber - 1; - Debug.assert(lineNumber !== -1, "position cannot precede the beginning of the file"); + ts.Debug.assert(lineNumber !== -1, "position cannot precede the beginning of the file"); } return lineNumber; } /** @internal */ - export function getLinesBetweenPositions(sourceFile: SourceFileLike, pos1: number, pos2: number) { - if (pos1 === pos2) return 0; + export function getLinesBetweenPositions(sourceFile: ts.SourceFileLike, pos1: number, pos2: number) { + if (pos1 === pos2) + return 0; const lineStarts = getLineStarts(sourceFile); const lower = Math.min(pos1, pos2); const isNegative = lower === pos2; @@ -470,7 +470,7 @@ namespace ts { return isNegative ? lowerLine - upperLine : upperLine - lowerLine; } - export function getLineAndCharacterOfPosition(sourceFile: SourceFileLike, position: number): LineAndCharacter { + export function getLineAndCharacterOfPosition(sourceFile: ts.SourceFileLike, position: number): ts.LineAndCharacter { return computeLineAndCharacterOfPosition(getLineStarts(sourceFile), position); } @@ -482,18 +482,18 @@ namespace ts { export function isWhiteSpaceSingleLine(ch: number): boolean { // Note: nextLine is in the Zs space, and should be considered to be a whitespace. // It is explicitly not a line-break as it isn't in the exact set specified by EcmaScript. - return ch === CharacterCodes.space || - ch === CharacterCodes.tab || - ch === CharacterCodes.verticalTab || - ch === CharacterCodes.formFeed || - ch === CharacterCodes.nonBreakingSpace || - ch === CharacterCodes.nextLine || - ch === CharacterCodes.ogham || - ch >= CharacterCodes.enQuad && ch <= CharacterCodes.zeroWidthSpace || - ch === CharacterCodes.narrowNoBreakSpace || - ch === CharacterCodes.mathematicalSpace || - ch === CharacterCodes.ideographicSpace || - ch === CharacterCodes.byteOrderMark; + return ch === ts.CharacterCodes.space || + ch === ts.CharacterCodes.tab || + ch === ts.CharacterCodes.verticalTab || + ch === ts.CharacterCodes.formFeed || + ch === ts.CharacterCodes.nonBreakingSpace || + ch === ts.CharacterCodes.nextLine || + ch === ts.CharacterCodes.ogham || + ch >= ts.CharacterCodes.enQuad && ch <= ts.CharacterCodes.zeroWidthSpace || + ch === ts.CharacterCodes.narrowNoBreakSpace || + ch === ts.CharacterCodes.mathematicalSpace || + ch === ts.CharacterCodes.ideographicSpace || + ch === ts.CharacterCodes.byteOrderMark; } export function isLineBreak(ch: number): boolean { @@ -508,18 +508,18 @@ namespace ts { // Only the characters in Table 3 are treated as line terminators. Other new line or line // breaking characters are treated as white space but not as line terminators. - return ch === CharacterCodes.lineFeed || - ch === CharacterCodes.carriageReturn || - ch === CharacterCodes.lineSeparator || - ch === CharacterCodes.paragraphSeparator; + return ch === ts.CharacterCodes.lineFeed || + ch === ts.CharacterCodes.carriageReturn || + ch === ts.CharacterCodes.lineSeparator || + ch === ts.CharacterCodes.paragraphSeparator; } function isDigit(ch: number): boolean { - return ch >= CharacterCodes._0 && ch <= CharacterCodes._9; + return ch >= ts.CharacterCodes._0 && ch <= ts.CharacterCodes._9; } function isHexDigit(ch: number): boolean { - return isDigit(ch) || ch >= CharacterCodes.A && ch <= CharacterCodes.F || ch >= CharacterCodes.a && ch <= CharacterCodes.f; + return isDigit(ch) || ch >= ts.CharacterCodes.A && ch <= ts.CharacterCodes.F || ch >= ts.CharacterCodes.a && ch <= ts.CharacterCodes.f; } function isCodePoint(code: number): boolean { @@ -528,39 +528,39 @@ namespace ts { /* @internal */ export function isOctalDigit(ch: number): boolean { - return ch >= CharacterCodes._0 && ch <= CharacterCodes._7; + return ch >= ts.CharacterCodes._0 && ch <= ts.CharacterCodes._7; } export function couldStartTrivia(text: string, pos: number): boolean { // Keep in sync with skipTrivia const ch = text.charCodeAt(pos); switch (ch) { - case CharacterCodes.carriageReturn: - case CharacterCodes.lineFeed: - case CharacterCodes.tab: - case CharacterCodes.verticalTab: - case CharacterCodes.formFeed: - case CharacterCodes.space: - case CharacterCodes.slash: + case ts.CharacterCodes.carriageReturn: + case ts.CharacterCodes.lineFeed: + case ts.CharacterCodes.tab: + case ts.CharacterCodes.verticalTab: + case ts.CharacterCodes.formFeed: + case ts.CharacterCodes.space: + case ts.CharacterCodes.slash: // starts of normal trivia // falls through - case CharacterCodes.lessThan: - case CharacterCodes.bar: - case CharacterCodes.equals: - case CharacterCodes.greaterThan: + case ts.CharacterCodes.lessThan: + case ts.CharacterCodes.bar: + case ts.CharacterCodes.equals: + case ts.CharacterCodes.greaterThan: // Starts of conflict marker trivia return true; - case CharacterCodes.hash: + case ts.CharacterCodes.hash: // Only if its the beginning can we have #! trivia return pos === 0; default: - return ch > CharacterCodes.maxAsciiCharacter; + return ch > ts.CharacterCodes.maxAsciiCharacter; } } /* @internal */ export function skipTrivia(text: string, pos: number, stopAfterLineBreak?: boolean, stopAtComments?: boolean, inJSDoc?: boolean): number { - if (positionIsSynthesized(pos)) { + if (ts.positionIsSynthesized(pos)) { return pos; } @@ -569,29 +569,29 @@ namespace ts { while (true) { const ch = text.charCodeAt(pos); switch (ch) { - case CharacterCodes.carriageReturn: - if (text.charCodeAt(pos + 1) === CharacterCodes.lineFeed) { + case ts.CharacterCodes.carriageReturn: + if (text.charCodeAt(pos + 1) === ts.CharacterCodes.lineFeed) { pos++; } // falls through - case CharacterCodes.lineFeed: + case ts.CharacterCodes.lineFeed: pos++; if (stopAfterLineBreak) { return pos; } canConsumeStar = !!inJSDoc; continue; - case CharacterCodes.tab: - case CharacterCodes.verticalTab: - case CharacterCodes.formFeed: - case CharacterCodes.space: + case ts.CharacterCodes.tab: + case ts.CharacterCodes.verticalTab: + case ts.CharacterCodes.formFeed: + case ts.CharacterCodes.space: pos++; continue; - case CharacterCodes.slash: + case ts.CharacterCodes.slash: if (stopAtComments) { break; } - if (text.charCodeAt(pos + 1) === CharacterCodes.slash) { + if (text.charCodeAt(pos + 1) === ts.CharacterCodes.slash) { pos += 2; while (pos < text.length) { if (isLineBreak(text.charCodeAt(pos))) { @@ -602,10 +602,10 @@ namespace ts { canConsumeStar = false; continue; } - if (text.charCodeAt(pos + 1) === CharacterCodes.asterisk) { + if (text.charCodeAt(pos + 1) === ts.CharacterCodes.asterisk) { pos += 2; while (pos < text.length) { - if (text.charCodeAt(pos) === CharacterCodes.asterisk && text.charCodeAt(pos + 1) === CharacterCodes.slash) { + if (text.charCodeAt(pos) === ts.CharacterCodes.asterisk && text.charCodeAt(pos + 1) === ts.CharacterCodes.slash) { pos += 2; break; } @@ -616,10 +616,10 @@ namespace ts { } break; - case CharacterCodes.lessThan: - case CharacterCodes.bar: - case CharacterCodes.equals: - case CharacterCodes.greaterThan: + case ts.CharacterCodes.lessThan: + case ts.CharacterCodes.bar: + case ts.CharacterCodes.equals: + case ts.CharacterCodes.greaterThan: if (isConflictMarkerTrivia(text, pos)) { pos = scanConflictMarkerTrivia(text, pos); canConsumeStar = false; @@ -627,7 +627,7 @@ namespace ts { } break; - case CharacterCodes.hash: + case ts.CharacterCodes.hash: if (pos === 0 && isShebangTrivia(text, pos)) { pos = scanShebangTrivia(text, pos); canConsumeStar = false; @@ -635,7 +635,7 @@ namespace ts { } break; - case CharacterCodes.asterisk: + case ts.CharacterCodes.asterisk: if (canConsumeStar) { pos++; canConsumeStar = false; @@ -644,7 +644,7 @@ namespace ts { break; default: - if (ch > CharacterCodes.maxAsciiCharacter && (isWhiteSpaceLike(ch))) { + if (ch > ts.CharacterCodes.maxAsciiCharacter && (isWhiteSpaceLike(ch))) { pos++; continue; } @@ -659,7 +659,7 @@ namespace ts { const mergeConflictMarkerLength = "<<<<<<<".length; function isConflictMarkerTrivia(text: string, pos: number) { - Debug.assert(pos >= 0); + ts.Debug.assert(pos >= 0); // Conflict markers must be at the start of a line. if (pos === 0 || isLineBreak(text.charCodeAt(pos - 1))) { @@ -672,34 +672,34 @@ namespace ts { } } - return ch === CharacterCodes.equals || - text.charCodeAt(pos + mergeConflictMarkerLength) === CharacterCodes.space; + return ch === ts.CharacterCodes.equals || + text.charCodeAt(pos + mergeConflictMarkerLength) === ts.CharacterCodes.space; } } return false; } - function scanConflictMarkerTrivia(text: string, pos: number, error?: (diag: DiagnosticMessage, pos?: number, len?: number) => void) { + function scanConflictMarkerTrivia(text: string, pos: number, error?: (diag: ts.DiagnosticMessage, pos?: number, len?: number) => void) { if (error) { - error(Diagnostics.Merge_conflict_marker_encountered, pos, mergeConflictMarkerLength); + error(ts.Diagnostics.Merge_conflict_marker_encountered, pos, mergeConflictMarkerLength); } const ch = text.charCodeAt(pos); const len = text.length; - if (ch === CharacterCodes.lessThan || ch === CharacterCodes.greaterThan) { + if (ch === ts.CharacterCodes.lessThan || ch === ts.CharacterCodes.greaterThan) { while (pos < len && !isLineBreak(text.charCodeAt(pos))) { pos++; } } else { - Debug.assert(ch === CharacterCodes.bar || ch === CharacterCodes.equals); + ts.Debug.assert(ch === ts.CharacterCodes.bar || ch === ts.CharacterCodes.equals); // Consume everything from the start of a ||||||| or ======= marker to the start // of the next ======= or >>>>>>> marker. while (pos < len) { const currentChar = text.charCodeAt(pos); - if ((currentChar === CharacterCodes.equals || currentChar === CharacterCodes.greaterThan) && currentChar !== ch && isConflictMarkerTrivia(text, pos)) { + if ((currentChar === ts.CharacterCodes.equals || currentChar === ts.CharacterCodes.greaterThan) && currentChar !== ch && isConflictMarkerTrivia(text, pos)) { break; } @@ -715,7 +715,7 @@ namespace ts { /*@internal*/ export function isShebangTrivia(text: string, pos: number) { // Shebangs check must only be done at the start of the file - Debug.assert(pos === 0); + ts.Debug.assert(pos === 0); return shebangTriviaRegex.test(text); } @@ -746,10 +746,10 @@ namespace ts { * @returns If "reduce" is true, the accumulated value. If "reduce" is false, the first truthy * return value of the callback. */ - function iterateCommentRanges(reduce: boolean, text: string, pos: number, trailing: boolean, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean, state: T, memo: U | undefined) => U, state: T, initial?: U): U | undefined { + function iterateCommentRanges(reduce: boolean, text: string, pos: number, trailing: boolean, cb: (pos: number, end: number, kind: ts.CommentKind, hasTrailingNewLine: boolean, state: T, memo: U | undefined) => U, state: T, initial?: U): U | undefined { let pendingPos!: number; let pendingEnd!: number; - let pendingKind!: CommentKind; + let pendingKind!: ts.CommentKind; let pendingHasTrailingNewLine!: boolean; let hasPendingCommentRange = false; let collecting = trailing; @@ -764,12 +764,12 @@ namespace ts { scan: while (pos >= 0 && pos < text.length) { const ch = text.charCodeAt(pos); switch (ch) { - case CharacterCodes.carriageReturn: - if (text.charCodeAt(pos + 1) === CharacterCodes.lineFeed) { + case ts.CharacterCodes.carriageReturn: + if (text.charCodeAt(pos + 1) === ts.CharacterCodes.lineFeed) { pos++; } // falls through - case CharacterCodes.lineFeed: + case ts.CharacterCodes.lineFeed: pos++; if (trailing) { break scan; @@ -781,20 +781,20 @@ namespace ts { } continue; - case CharacterCodes.tab: - case CharacterCodes.verticalTab: - case CharacterCodes.formFeed: - case CharacterCodes.space: + case ts.CharacterCodes.tab: + case ts.CharacterCodes.verticalTab: + case ts.CharacterCodes.formFeed: + case ts.CharacterCodes.space: pos++; continue; - case CharacterCodes.slash: + case ts.CharacterCodes.slash: const nextChar = text.charCodeAt(pos + 1); let hasTrailingNewLine = false; - if (nextChar === CharacterCodes.slash || nextChar === CharacterCodes.asterisk) { - const kind = nextChar === CharacterCodes.slash ? SyntaxKind.SingleLineCommentTrivia : SyntaxKind.MultiLineCommentTrivia; + if (nextChar === ts.CharacterCodes.slash || nextChar === ts.CharacterCodes.asterisk) { + const kind = nextChar === ts.CharacterCodes.slash ? ts.SyntaxKind.SingleLineCommentTrivia : ts.SyntaxKind.MultiLineCommentTrivia; const startPos = pos; pos += 2; - if (nextChar === CharacterCodes.slash) { + if (nextChar === ts.CharacterCodes.slash) { while (pos < text.length) { if (isLineBreak(text.charCodeAt(pos))) { hasTrailingNewLine = true; @@ -805,7 +805,7 @@ namespace ts { } else { while (pos < text.length) { - if (text.charCodeAt(pos) === CharacterCodes.asterisk && text.charCodeAt(pos + 1) === CharacterCodes.slash) { + if (text.charCodeAt(pos) === ts.CharacterCodes.asterisk && text.charCodeAt(pos + 1) === ts.CharacterCodes.slash) { pos += 2; break; } @@ -833,7 +833,7 @@ namespace ts { } break scan; default: - if (ch > CharacterCodes.maxAsciiCharacter && (isWhiteSpaceLike(ch))) { + if (ch > ts.CharacterCodes.maxAsciiCharacter && (isWhiteSpaceLike(ch))) { if (hasPendingCommentRange && isLineBreak(ch)) { pendingHasTrailingNewLine = true; } @@ -851,27 +851,27 @@ namespace ts { return accumulator; } - export function forEachLeadingCommentRange(text: string, pos: number, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean) => U): U | undefined; - export function forEachLeadingCommentRange(text: string, pos: number, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean, state: T) => U, state: T): U | undefined; - export function forEachLeadingCommentRange(text: string, pos: number, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean, state: T) => U, state?: T): U | undefined { + export function forEachLeadingCommentRange(text: string, pos: number, cb: (pos: number, end: number, kind: ts.CommentKind, hasTrailingNewLine: boolean) => U): U | undefined; + export function forEachLeadingCommentRange(text: string, pos: number, cb: (pos: number, end: number, kind: ts.CommentKind, hasTrailingNewLine: boolean, state: T) => U, state: T): U | undefined; + export function forEachLeadingCommentRange(text: string, pos: number, cb: (pos: number, end: number, kind: ts.CommentKind, hasTrailingNewLine: boolean, state: T) => U, state?: T): U | undefined { return iterateCommentRanges(/*reduce*/ false, text, pos, /*trailing*/ false, cb, state); } - export function forEachTrailingCommentRange(text: string, pos: number, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean) => U): U | undefined; - export function forEachTrailingCommentRange(text: string, pos: number, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean, state: T) => U, state: T): U | undefined; - export function forEachTrailingCommentRange(text: string, pos: number, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean, state: T) => U, state?: T): U | undefined { + export function forEachTrailingCommentRange(text: string, pos: number, cb: (pos: number, end: number, kind: ts.CommentKind, hasTrailingNewLine: boolean) => U): U | undefined; + export function forEachTrailingCommentRange(text: string, pos: number, cb: (pos: number, end: number, kind: ts.CommentKind, hasTrailingNewLine: boolean, state: T) => U, state: T): U | undefined; + export function forEachTrailingCommentRange(text: string, pos: number, cb: (pos: number, end: number, kind: ts.CommentKind, hasTrailingNewLine: boolean, state: T) => U, state?: T): U | undefined { return iterateCommentRanges(/*reduce*/ false, text, pos, /*trailing*/ true, cb, state); } - export function reduceEachLeadingCommentRange(text: string, pos: number, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean, state: T, memo: U) => U, state: T, initial: U) { + export function reduceEachLeadingCommentRange(text: string, pos: number, cb: (pos: number, end: number, kind: ts.CommentKind, hasTrailingNewLine: boolean, state: T, memo: U) => U, state: T, initial: U) { return iterateCommentRanges(/*reduce*/ true, text, pos, /*trailing*/ false, cb, state, initial); } - export function reduceEachTrailingCommentRange(text: string, pos: number, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean, state: T, memo: U) => U, state: T, initial: U) { + export function reduceEachTrailingCommentRange(text: string, pos: number, cb: (pos: number, end: number, kind: ts.CommentKind, hasTrailingNewLine: boolean, state: T, memo: U) => U, state: T, initial: U) { return iterateCommentRanges(/*reduce*/ true, text, pos, /*trailing*/ true, cb, state, initial); } - function appendCommentRange(pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean, _state: any, comments: CommentRange[]) { + function appendCommentRange(pos: number, end: number, kind: ts.CommentKind, hasTrailingNewLine: boolean, _state: any, comments: ts.CommentRange[]) { if (!comments) { comments = []; } @@ -880,11 +880,11 @@ namespace ts { return comments; } - export function getLeadingCommentRanges(text: string, pos: number): CommentRange[] | undefined { + export function getLeadingCommentRanges(text: string, pos: number): ts.CommentRange[] | undefined { return reduceEachLeadingCommentRange(text, pos, appendCommentRange, /*state*/ undefined, /*initial*/ undefined); } - export function getTrailingCommentRanges(text: string, pos: number): CommentRange[] | undefined { + export function getTrailingCommentRanges(text: string, pos: number): ts.CommentRange[] | undefined { return reduceEachTrailingCommentRange(text, pos, appendCommentRange, /*state*/ undefined, /*initial*/ undefined); } @@ -896,22 +896,22 @@ namespace ts { } } - export function isIdentifierStart(ch: number, languageVersion: ScriptTarget | undefined): boolean { - return ch >= CharacterCodes.A && ch <= CharacterCodes.Z || ch >= CharacterCodes.a && ch <= CharacterCodes.z || - ch === CharacterCodes.$ || ch === CharacterCodes._ || - ch > CharacterCodes.maxAsciiCharacter && isUnicodeIdentifierStart(ch, languageVersion); + export function isIdentifierStart(ch: number, languageVersion: ts.ScriptTarget | undefined): boolean { + return ch >= ts.CharacterCodes.A && ch <= ts.CharacterCodes.Z || ch >= ts.CharacterCodes.a && ch <= ts.CharacterCodes.z || + ch === ts.CharacterCodes.$ || ch === ts.CharacterCodes._ || + ch > ts.CharacterCodes.maxAsciiCharacter && isUnicodeIdentifierStart(ch, languageVersion); } - export function isIdentifierPart(ch: number, languageVersion: ScriptTarget | undefined, identifierVariant?: LanguageVariant): boolean { - return ch >= CharacterCodes.A && ch <= CharacterCodes.Z || ch >= CharacterCodes.a && ch <= CharacterCodes.z || - ch >= CharacterCodes._0 && ch <= CharacterCodes._9 || ch === CharacterCodes.$ || ch === CharacterCodes._ || + export function isIdentifierPart(ch: number, languageVersion: ts.ScriptTarget | undefined, identifierVariant?: ts.LanguageVariant): boolean { + return ch >= ts.CharacterCodes.A && ch <= ts.CharacterCodes.Z || ch >= ts.CharacterCodes.a && ch <= ts.CharacterCodes.z || + ch >= ts.CharacterCodes._0 && ch <= ts.CharacterCodes._9 || ch === ts.CharacterCodes.$ || ch === ts.CharacterCodes._ || // "-" and ":" are valid in JSX Identifiers - (identifierVariant === LanguageVariant.JSX ? (ch === CharacterCodes.minus || ch === CharacterCodes.colon) : false) || - ch > CharacterCodes.maxAsciiCharacter && isUnicodeIdentifierPart(ch, languageVersion); + (identifierVariant === ts.LanguageVariant.JSX ? (ch === ts.CharacterCodes.minus || ch === ts.CharacterCodes.colon) : false) || + ch > ts.CharacterCodes.maxAsciiCharacter && isUnicodeIdentifierPart(ch, languageVersion); } /* @internal */ - export function isIdentifierText(name: string, languageVersion: ScriptTarget | undefined, identifierVariant?: LanguageVariant): boolean { + export function isIdentifierText(name: string, languageVersion: ts.ScriptTarget | undefined, identifierVariant?: ts.LanguageVariant): boolean { let ch = codePointAt(name, 0); if (!isIdentifierStart(ch, languageVersion)) { return false; @@ -927,13 +927,7 @@ namespace ts { } // Creates a scanner over a (possibly unspecified) range of a piece of text. - export function createScanner(languageVersion: ScriptTarget, - skipTrivia: boolean, - languageVariant = LanguageVariant.Standard, - textInitial?: string, - onError?: ErrorCallback, - start?: number, - length?: number): Scanner { + export function createScanner(languageVersion: ts.ScriptTarget, skipTrivia: boolean, languageVariant = ts.LanguageVariant.Standard, textInitial?: string, onError?: ErrorCallback, start?: number, length?: number): Scanner { let text = textInitial!; @@ -950,11 +944,10 @@ namespace ts { // Start position of text of current token let tokenPos: number; - let token: SyntaxKind; + let token: ts.SyntaxKind; let tokenValue!: string; - let tokenFlags: TokenFlags; - - let commentDirectives: CommentDirective[] | undefined; + let tokenFlags: ts.TokenFlags; + let commentDirectives: ts.CommentDirective[] | undefined; let inJSDocType = 0; setText(text, start, length); @@ -966,15 +959,15 @@ namespace ts { getTokenPos: () => tokenPos, getTokenText: () => text.substring(tokenPos, pos), getTokenValue: () => tokenValue, - hasUnicodeEscape: () => (tokenFlags & TokenFlags.UnicodeEscape) !== 0, - hasExtendedUnicodeEscape: () => (tokenFlags & TokenFlags.ExtendedUnicodeEscape) !== 0, - hasPrecedingLineBreak: () => (tokenFlags & TokenFlags.PrecedingLineBreak) !== 0, - hasPrecedingJSDocComment: () => (tokenFlags & TokenFlags.PrecedingJSDocComment) !== 0, - isIdentifier: () => token === SyntaxKind.Identifier || token > SyntaxKind.LastReservedWord, - isReservedWord: () => token >= SyntaxKind.FirstReservedWord && token <= SyntaxKind.LastReservedWord, - isUnterminated: () => (tokenFlags & TokenFlags.Unterminated) !== 0, + hasUnicodeEscape: () => (tokenFlags & ts.TokenFlags.UnicodeEscape) !== 0, + hasExtendedUnicodeEscape: () => (tokenFlags & ts.TokenFlags.ExtendedUnicodeEscape) !== 0, + hasPrecedingLineBreak: () => (tokenFlags & ts.TokenFlags.PrecedingLineBreak) !== 0, + hasPrecedingJSDocComment: () => (tokenFlags & ts.TokenFlags.PrecedingJSDocComment) !== 0, + isIdentifier: () => token === ts.SyntaxKind.Identifier || token > ts.SyntaxKind.LastReservedWord, + isReservedWord: () => token >= ts.SyntaxKind.FirstReservedWord && token <= ts.SyntaxKind.LastReservedWord, + isUnterminated: () => (tokenFlags & ts.TokenFlags.Unterminated) !== 0, getCommentDirectives: () => commentDirectives, - getNumericLiteralFlags: () => tokenFlags & TokenFlags.NumericLiteralFlags, + getNumericLiteralFlags: () => tokenFlags & ts.TokenFlags.NumericLiteralFlags, getTokenFlags: () => tokenFlags, reScanGreaterToken, reScanAsteriskEqualsToken, @@ -1005,7 +998,7 @@ namespace ts { scanRange, }; - if (Debug.isDebugging) { + if (ts.Debug.isDebugging) { Object.defineProperty(scanner, "__debugShowCurrentPositionInText", { get: () => { const text = scanner.getText(); @@ -1016,9 +1009,9 @@ namespace ts { return scanner; - function error(message: DiagnosticMessage): void; - function error(message: DiagnosticMessage, errPos: number, length: number): void; - function error(message: DiagnosticMessage, errPos: number = pos, length?: number): void { + function error(message: ts.DiagnosticMessage): void; + function error(message: ts.DiagnosticMessage, errPos: number, length: number): void; + function error(message: ts.DiagnosticMessage, errPos: number = pos, length?: number): void { if (onError) { const oldPos = pos; pos = errPos; @@ -1034,18 +1027,18 @@ namespace ts { let result = ""; while (true) { const ch = text.charCodeAt(pos); - if (ch === CharacterCodes._) { - tokenFlags |= TokenFlags.ContainsSeparator; + if (ch === ts.CharacterCodes._) { + tokenFlags |= ts.TokenFlags.ContainsSeparator; if (allowSeparator) { allowSeparator = false; isPreviousTokenSeparator = true; result += text.substring(start, pos); } else if (isPreviousTokenSeparator) { - error(Diagnostics.Multiple_consecutive_numeric_separators_are_not_permitted, pos, 1); + error(ts.Diagnostics.Multiple_consecutive_numeric_separators_are_not_permitted, pos, 1); } else { - error(Diagnostics.Numeric_separators_are_not_allowed_here, pos, 1); + error(ts.Diagnostics.Numeric_separators_are_not_allowed_here, pos, 1); } pos++; start = pos; @@ -1059,30 +1052,34 @@ namespace ts { } break; } - if (text.charCodeAt(pos - 1) === CharacterCodes._) { - error(Diagnostics.Numeric_separators_are_not_allowed_here, pos - 1, 1); + if (text.charCodeAt(pos - 1) === ts.CharacterCodes._) { + error(ts.Diagnostics.Numeric_separators_are_not_allowed_here, pos - 1, 1); } return result + text.substring(start, pos); } - function scanNumber(): { type: SyntaxKind, value: string } { + function scanNumber(): { + type: ts.SyntaxKind; + value: string; + } { const start = pos; const mainFragment = scanNumberFragment(); let decimalFragment: string | undefined; let scientificFragment: string | undefined; - if (text.charCodeAt(pos) === CharacterCodes.dot) { + if (text.charCodeAt(pos) === ts.CharacterCodes.dot) { pos++; decimalFragment = scanNumberFragment(); } let end = pos; - if (text.charCodeAt(pos) === CharacterCodes.E || text.charCodeAt(pos) === CharacterCodes.e) { + if (text.charCodeAt(pos) === ts.CharacterCodes.E || text.charCodeAt(pos) === ts.CharacterCodes.e) { + pos++; + tokenFlags |= ts.TokenFlags.Scientific; + if (text.charCodeAt(pos) === ts.CharacterCodes.plus || text.charCodeAt(pos) === ts.CharacterCodes.minus) pos++; - tokenFlags |= TokenFlags.Scientific; - if (text.charCodeAt(pos) === CharacterCodes.plus || text.charCodeAt(pos) === CharacterCodes.minus) pos++; const preNumericPart = pos; const finalFragment = scanNumberFragment(); if (!finalFragment) { - error(Diagnostics.Digit_expected); + error(ts.Diagnostics.Digit_expected); } else { scientificFragment = text.substring(end, preNumericPart) + finalFragment; @@ -1090,7 +1087,7 @@ namespace ts { } } let result: string; - if (tokenFlags & TokenFlags.ContainsSeparator) { + if (tokenFlags & ts.TokenFlags.ContainsSeparator) { result = mainFragment; if (decimalFragment) { result += "." + decimalFragment; @@ -1103,10 +1100,10 @@ namespace ts { result = text.substring(start, end); // No need to use all the fragments; no _ removal needed } - if (decimalFragment !== undefined || tokenFlags & TokenFlags.Scientific) { - checkForIdentifierStartAfterNumericLiteral(start, decimalFragment === undefined && !!(tokenFlags & TokenFlags.Scientific)); + if (decimalFragment !== undefined || tokenFlags & ts.TokenFlags.Scientific) { + checkForIdentifierStartAfterNumericLiteral(start, decimalFragment === undefined && !!(tokenFlags & ts.TokenFlags.Scientific)); return { - type: SyntaxKind.NumericLiteral, + type: ts.SyntaxKind.NumericLiteral, value: "" + +result // if value is not an integer, it can be safely coerced to a number }; } @@ -1128,14 +1125,14 @@ namespace ts { if (length === 1 && text[identifierStart] === "n") { if (isScientific) { - error(Diagnostics.A_bigint_literal_cannot_use_exponential_notation, numericStart, identifierStart - numericStart + 1); + error(ts.Diagnostics.A_bigint_literal_cannot_use_exponential_notation, numericStart, identifierStart - numericStart + 1); } else { - error(Diagnostics.A_bigint_literal_must_be_an_integer, numericStart, identifierStart - numericStart + 1); + error(ts.Diagnostics.A_bigint_literal_must_be_an_integer, numericStart, identifierStart - numericStart + 1); } } else { - error(Diagnostics.An_identifier_or_keyword_cannot_immediately_follow_a_numeric_literal, identifierStart, length); + error(ts.Diagnostics.An_identifier_or_keyword_cannot_immediately_follow_a_numeric_literal, identifierStart, length); pos = identifierStart; } } @@ -1171,28 +1168,27 @@ namespace ts { let isPreviousTokenSeparator = false; while (valueChars.length < minCount || scanAsManyAsPossible) { let ch = text.charCodeAt(pos); - if (canHaveSeparators && ch === CharacterCodes._) { - tokenFlags |= TokenFlags.ContainsSeparator; + if (canHaveSeparators && ch === ts.CharacterCodes._) { + tokenFlags |= ts.TokenFlags.ContainsSeparator; if (allowSeparator) { allowSeparator = false; isPreviousTokenSeparator = true; } else if (isPreviousTokenSeparator) { - error(Diagnostics.Multiple_consecutive_numeric_separators_are_not_permitted, pos, 1); + error(ts.Diagnostics.Multiple_consecutive_numeric_separators_are_not_permitted, pos, 1); } else { - error(Diagnostics.Numeric_separators_are_not_allowed_here, pos, 1); + error(ts.Diagnostics.Numeric_separators_are_not_allowed_here, pos, 1); } pos++; continue; } allowSeparator = canHaveSeparators; - if (ch >= CharacterCodes.A && ch <= CharacterCodes.F) { - ch += CharacterCodes.a - CharacterCodes.A; // standardize hex literals to lowercase + if (ch >= ts.CharacterCodes.A && ch <= ts.CharacterCodes.F) { + ch += ts.CharacterCodes.a - ts.CharacterCodes.A; // standardize hex literals to lowercase } - else if (!((ch >= CharacterCodes._0 && ch <= CharacterCodes._9) || - (ch >= CharacterCodes.a && ch <= CharacterCodes.f) - )) { + else if (!((ch >= ts.CharacterCodes._0 && ch <= ts.CharacterCodes._9) || + (ch >= ts.CharacterCodes.a && ch <= ts.CharacterCodes.f))) { break; } valueChars.push(ch); @@ -1202,8 +1198,8 @@ namespace ts { if (valueChars.length < minCount) { valueChars = []; } - if (text.charCodeAt(pos - 1) === CharacterCodes._) { - error(Diagnostics.Numeric_separators_are_not_allowed_here, pos - 1, 1); + if (text.charCodeAt(pos - 1) === ts.CharacterCodes._) { + error(ts.Diagnostics.Numeric_separators_are_not_allowed_here, pos - 1, 1); } return String.fromCharCode(...valueChars); } @@ -1216,8 +1212,8 @@ namespace ts { while (true) { if (pos >= end) { result += text.substring(start, pos); - tokenFlags |= TokenFlags.Unterminated; - error(Diagnostics.Unterminated_string_literal); + tokenFlags |= ts.TokenFlags.Unterminated; + error(ts.Diagnostics.Unterminated_string_literal); break; } const ch = text.charCodeAt(pos); @@ -1226,7 +1222,7 @@ namespace ts { pos++; break; } - if (ch === CharacterCodes.backslash && !jsxAttributeString) { + if (ch === ts.CharacterCodes.backslash && !jsxAttributeString) { result += text.substring(start, pos); result += scanEscapeSequence(); start = pos; @@ -1234,8 +1230,8 @@ namespace ts { } if (isLineBreak(ch) && !jsxAttributeString) { result += text.substring(start, pos); - tokenFlags |= TokenFlags.Unterminated; - error(Diagnostics.Unterminated_string_literal); + tokenFlags |= ts.TokenFlags.Unterminated; + error(ts.Diagnostics.Unterminated_string_literal); break; } pos++; @@ -1247,43 +1243,43 @@ namespace ts { * Sets the current 'tokenValue' and returns a NoSubstitutionTemplateLiteral or * a literal component of a TemplateExpression. */ - function scanTemplateAndSetTokenValue(isTaggedTemplate: boolean): SyntaxKind { - const startedWithBacktick = text.charCodeAt(pos) === CharacterCodes.backtick; + function scanTemplateAndSetTokenValue(isTaggedTemplate: boolean): ts.SyntaxKind { + const startedWithBacktick = text.charCodeAt(pos) === ts.CharacterCodes.backtick; pos++; let start = pos; let contents = ""; - let resultingToken: SyntaxKind; + let resultingToken: ts.SyntaxKind; while (true) { if (pos >= end) { contents += text.substring(start, pos); - tokenFlags |= TokenFlags.Unterminated; - error(Diagnostics.Unterminated_template_literal); - resultingToken = startedWithBacktick ? SyntaxKind.NoSubstitutionTemplateLiteral : SyntaxKind.TemplateTail; + tokenFlags |= ts.TokenFlags.Unterminated; + error(ts.Diagnostics.Unterminated_template_literal); + resultingToken = startedWithBacktick ? ts.SyntaxKind.NoSubstitutionTemplateLiteral : ts.SyntaxKind.TemplateTail; break; } const currChar = text.charCodeAt(pos); // '`' - if (currChar === CharacterCodes.backtick) { + if (currChar === ts.CharacterCodes.backtick) { contents += text.substring(start, pos); pos++; - resultingToken = startedWithBacktick ? SyntaxKind.NoSubstitutionTemplateLiteral : SyntaxKind.TemplateTail; + resultingToken = startedWithBacktick ? ts.SyntaxKind.NoSubstitutionTemplateLiteral : ts.SyntaxKind.TemplateTail; break; } // '${' - if (currChar === CharacterCodes.$ && pos + 1 < end && text.charCodeAt(pos + 1) === CharacterCodes.openBrace) { + if (currChar === ts.CharacterCodes.$ && pos + 1 < end && text.charCodeAt(pos + 1) === ts.CharacterCodes.openBrace) { contents += text.substring(start, pos); pos += 2; - resultingToken = startedWithBacktick ? SyntaxKind.TemplateHead : SyntaxKind.TemplateMiddle; + resultingToken = startedWithBacktick ? ts.SyntaxKind.TemplateHead : ts.SyntaxKind.TemplateMiddle; break; } // Escape character - if (currChar === CharacterCodes.backslash) { + if (currChar === ts.CharacterCodes.backslash) { contents += text.substring(start, pos); contents += scanEscapeSequence(isTaggedTemplate); start = pos; @@ -1292,11 +1288,11 @@ namespace ts { // Speculated ECMAScript 6 Spec 11.8.6.1: // and LineTerminatorSequences are normalized to for Template Values - if (currChar === CharacterCodes.carriageReturn) { + if (currChar === ts.CharacterCodes.carriageReturn) { contents += text.substring(start, pos); pos++; - if (pos < end && text.charCodeAt(pos) === CharacterCodes.lineFeed) { + if (pos < end && text.charCodeAt(pos) === ts.CharacterCodes.lineFeed) { pos++; } @@ -1308,7 +1304,7 @@ namespace ts { pos++; } - Debug.assert(resultingToken !== undefined); + ts.Debug.assert(resultingToken !== undefined); tokenValue = contents; return resultingToken; @@ -1318,54 +1314,54 @@ namespace ts { const start = pos; pos++; if (pos >= end) { - error(Diagnostics.Unexpected_end_of_text); + error(ts.Diagnostics.Unexpected_end_of_text); return ""; } const ch = text.charCodeAt(pos); pos++; switch (ch) { - case CharacterCodes._0: + case ts.CharacterCodes._0: // '\01' if (isTaggedTemplate && pos < end && isDigit(text.charCodeAt(pos))) { pos++; - tokenFlags |= TokenFlags.ContainsInvalidEscape; + tokenFlags |= ts.TokenFlags.ContainsInvalidEscape; return text.substring(start, pos); } return "\0"; - case CharacterCodes.b: + case ts.CharacterCodes.b: return "\b"; - case CharacterCodes.t: + case ts.CharacterCodes.t: return "\t"; - case CharacterCodes.n: + case ts.CharacterCodes.n: return "\n"; - case CharacterCodes.v: + case ts.CharacterCodes.v: return "\v"; - case CharacterCodes.f: + case ts.CharacterCodes.f: return "\f"; - case CharacterCodes.r: + case ts.CharacterCodes.r: return "\r"; - case CharacterCodes.singleQuote: + case ts.CharacterCodes.singleQuote: return "\'"; - case CharacterCodes.doubleQuote: + case ts.CharacterCodes.doubleQuote: return "\""; - case CharacterCodes.u: + case ts.CharacterCodes.u: if (isTaggedTemplate) { // '\u' or '\u0' or '\u00' or '\u000' for (let escapePos = pos; escapePos < pos + 4; escapePos++) { - if (escapePos < end && !isHexDigit(text.charCodeAt(escapePos)) && text.charCodeAt(escapePos) !== CharacterCodes.openBrace) { + if (escapePos < end && !isHexDigit(text.charCodeAt(escapePos)) && text.charCodeAt(escapePos) !== ts.CharacterCodes.openBrace) { pos = escapePos; - tokenFlags |= TokenFlags.ContainsInvalidEscape; + tokenFlags |= ts.TokenFlags.ContainsInvalidEscape; return text.substring(start, pos); } } } // '\u{DDDDDDDD}' - if (pos < end && text.charCodeAt(pos) === CharacterCodes.openBrace) { + if (pos < end && text.charCodeAt(pos) === ts.CharacterCodes.openBrace) { pos++; // '\u{' if (isTaggedTemplate && !isHexDigit(text.charCodeAt(pos))) { - tokenFlags |= TokenFlags.ContainsInvalidEscape; + tokenFlags |= ts.TokenFlags.ContainsInvalidEscape; return text.substring(start, pos); } @@ -1375,31 +1371,31 @@ namespace ts { const escapedValue = escapedValueString ? parseInt(escapedValueString, 16) : -1; // '\u{Not Code Point' or '\u{CodePoint' - if (!isCodePoint(escapedValue) || text.charCodeAt(pos) !== CharacterCodes.closeBrace) { - tokenFlags |= TokenFlags.ContainsInvalidEscape; + if (!isCodePoint(escapedValue) || text.charCodeAt(pos) !== ts.CharacterCodes.closeBrace) { + tokenFlags |= ts.TokenFlags.ContainsInvalidEscape; return text.substring(start, pos); } else { pos = savePos; } } - tokenFlags |= TokenFlags.ExtendedUnicodeEscape; + tokenFlags |= ts.TokenFlags.ExtendedUnicodeEscape; return scanExtendedUnicodeEscape(); } - tokenFlags |= TokenFlags.UnicodeEscape; + tokenFlags |= ts.TokenFlags.UnicodeEscape; // '\uDDDD' return scanHexadecimalEscape(/*numDigits*/ 4); - case CharacterCodes.x: + case ts.CharacterCodes.x: if (isTaggedTemplate) { if (!isHexDigit(text.charCodeAt(pos))) { - tokenFlags |= TokenFlags.ContainsInvalidEscape; + tokenFlags |= ts.TokenFlags.ContainsInvalidEscape; return text.substring(start, pos); } else if (!isHexDigit(text.charCodeAt(pos + 1))) { pos++; - tokenFlags |= TokenFlags.ContainsInvalidEscape; + tokenFlags |= ts.TokenFlags.ContainsInvalidEscape; return text.substring(start, pos); } } @@ -1408,14 +1404,14 @@ namespace ts { // when encountering a LineContinuation (i.e. a backslash and a line terminator sequence), // the line terminator is interpreted to be "the empty code unit sequence". - case CharacterCodes.carriageReturn: - if (pos < end && text.charCodeAt(pos) === CharacterCodes.lineFeed) { + case ts.CharacterCodes.carriageReturn: + if (pos < end && text.charCodeAt(pos) === ts.CharacterCodes.lineFeed) { pos++; } // falls through - case CharacterCodes.lineFeed: - case CharacterCodes.lineSeparator: - case CharacterCodes.paragraphSeparator: + case ts.CharacterCodes.lineFeed: + case ts.CharacterCodes.lineSeparator: + case ts.CharacterCodes.paragraphSeparator: return ""; default: return String.fromCharCode(ch); @@ -1429,7 +1425,7 @@ namespace ts { return String.fromCharCode(escapedValue); } else { - error(Diagnostics.Hexadecimal_digit_expected); + error(ts.Diagnostics.Hexadecimal_digit_expected); return ""; } } @@ -1441,24 +1437,24 @@ namespace ts { // Validate the value of the digit if (escapedValue < 0) { - error(Diagnostics.Hexadecimal_digit_expected); + error(ts.Diagnostics.Hexadecimal_digit_expected); isInvalidExtendedEscape = true; } else if (escapedValue > 0x10FFFF) { - error(Diagnostics.An_extended_Unicode_escape_value_must_be_between_0x0_and_0x10FFFF_inclusive); + error(ts.Diagnostics.An_extended_Unicode_escape_value_must_be_between_0x0_and_0x10FFFF_inclusive); isInvalidExtendedEscape = true; } if (pos >= end) { - error(Diagnostics.Unexpected_end_of_text); + error(ts.Diagnostics.Unexpected_end_of_text); isInvalidExtendedEscape = true; } - else if (text.charCodeAt(pos) === CharacterCodes.closeBrace) { + else if (text.charCodeAt(pos) === ts.CharacterCodes.closeBrace) { // Only swallow the following character up if it's a '}'. pos++; } else { - error(Diagnostics.Unterminated_Unicode_escape_sequence); + error(ts.Diagnostics.Unterminated_Unicode_escape_sequence); isInvalidExtendedEscape = true; } @@ -1472,7 +1468,7 @@ namespace ts { // Current character is known to be a backslash. Check for Unicode escape of the form '\uXXXX' // and return code point value if valid Unicode escape is found. Otherwise return -1. function peekUnicodeEscape(): number { - if (pos + 5 < end && text.charCodeAt(pos + 1) === CharacterCodes.u) { + if (pos + 5 < end && text.charCodeAt(pos + 1) === ts.CharacterCodes.u) { const start = pos; pos += 2; const value = scanExactNumberOfHexDigits(4, /*canHaveSeparators*/ false); @@ -1484,7 +1480,7 @@ namespace ts { function peekExtendedUnicodeEscape(): number { - if (languageVersion >= ScriptTarget.ES2015 && codePointAt(text, pos + 1) === CharacterCodes.u && codePointAt(text, pos + 2) === CharacterCodes.openBrace) { + if (languageVersion >= ts.ScriptTarget.ES2015 && codePointAt(text, pos + 1) === ts.CharacterCodes.u && codePointAt(text, pos + 2) === ts.CharacterCodes.openBrace) { const start = pos; pos += 3; const escapedValueString = scanMinimumNumberOfHexDigits(1, /*canHaveSeparators*/ false); @@ -1503,11 +1499,11 @@ namespace ts { if (isIdentifierPart(ch, languageVersion)) { pos += charSize(ch); } - else if (ch === CharacterCodes.backslash) { + else if (ch === ts.CharacterCodes.backslash) { ch = peekExtendedUnicodeEscape(); if (ch >= 0 && isIdentifierPart(ch, languageVersion)) { pos += 3; - tokenFlags |= TokenFlags.ExtendedUnicodeEscape; + tokenFlags |= ts.TokenFlags.ExtendedUnicodeEscape; result += scanExtendedUnicodeEscape(); start = pos; continue; @@ -1516,7 +1512,7 @@ namespace ts { if (!(ch >= 0 && isIdentifierPart(ch, languageVersion))) { break; } - tokenFlags |= TokenFlags.UnicodeEscape; + tokenFlags |= ts.TokenFlags.UnicodeEscape; result += text.substring(start, pos); result += utf16EncodeAsString(ch); // Valid Unicode escape is always six characters @@ -1531,19 +1527,19 @@ namespace ts { return result; } - function getIdentifierToken(): SyntaxKind.Identifier | KeywordSyntaxKind { + function getIdentifierToken(): ts.SyntaxKind.Identifier | ts.KeywordSyntaxKind { // Reserved words are between 2 and 12 characters long and start with a lowercase letter const len = tokenValue.length; if (len >= 2 && len <= 12) { const ch = tokenValue.charCodeAt(0); - if (ch >= CharacterCodes.a && ch <= CharacterCodes.z) { + if (ch >= ts.CharacterCodes.a && ch <= ts.CharacterCodes.z) { const keyword = textToKeyword.get(tokenValue); if (keyword !== undefined) { return token = keyword; } } } - return token = SyntaxKind.Identifier; + return token = ts.SyntaxKind.Identifier; } function scanBinaryOrOctalDigits(base: 2 | 8): string { @@ -1555,120 +1551,120 @@ namespace ts { while (true) { const ch = text.charCodeAt(pos); // Numeric separators are allowed anywhere within a numeric literal, except not at the beginning, or following another separator - if (ch === CharacterCodes._) { - tokenFlags |= TokenFlags.ContainsSeparator; + if (ch === ts.CharacterCodes._) { + tokenFlags |= ts.TokenFlags.ContainsSeparator; if (separatorAllowed) { separatorAllowed = false; isPreviousTokenSeparator = true; } else if (isPreviousTokenSeparator) { - error(Diagnostics.Multiple_consecutive_numeric_separators_are_not_permitted, pos, 1); + error(ts.Diagnostics.Multiple_consecutive_numeric_separators_are_not_permitted, pos, 1); } else { - error(Diagnostics.Numeric_separators_are_not_allowed_here, pos, 1); + error(ts.Diagnostics.Numeric_separators_are_not_allowed_here, pos, 1); } pos++; continue; } separatorAllowed = true; - if (!isDigit(ch) || ch - CharacterCodes._0 >= base) { + if (!isDigit(ch) || ch - ts.CharacterCodes._0 >= base) { break; } value += text[pos]; pos++; isPreviousTokenSeparator = false; } - if (text.charCodeAt(pos - 1) === CharacterCodes._) { + if (text.charCodeAt(pos - 1) === ts.CharacterCodes._) { // Literal ends with underscore - not allowed - error(Diagnostics.Numeric_separators_are_not_allowed_here, pos - 1, 1); + error(ts.Diagnostics.Numeric_separators_are_not_allowed_here, pos - 1, 1); } return value; } - function checkBigIntSuffix(): SyntaxKind { - if (text.charCodeAt(pos) === CharacterCodes.n) { + function checkBigIntSuffix(): ts.SyntaxKind { + if (text.charCodeAt(pos) === ts.CharacterCodes.n) { tokenValue += "n"; // Use base 10 instead of base 2 or base 8 for shorter literals - if (tokenFlags & TokenFlags.BinaryOrOctalSpecifier) { - tokenValue = parsePseudoBigInt(tokenValue) + "n"; + if (tokenFlags & ts.TokenFlags.BinaryOrOctalSpecifier) { + tokenValue = ts.parsePseudoBigInt(tokenValue) + "n"; } pos++; - return SyntaxKind.BigIntLiteral; + return ts.SyntaxKind.BigIntLiteral; } else { // not a bigint, so can convert to number in simplified form // Number() may not support 0b or 0o, so use parseInt() instead - const numericValue = tokenFlags & TokenFlags.BinarySpecifier + const numericValue = tokenFlags & ts.TokenFlags.BinarySpecifier ? parseInt(tokenValue.slice(2), 2) // skip "0b" - : tokenFlags & TokenFlags.OctalSpecifier + : tokenFlags & ts.TokenFlags.OctalSpecifier ? parseInt(tokenValue.slice(2), 8) // skip "0o" : +tokenValue; tokenValue = "" + numericValue; - return SyntaxKind.NumericLiteral; + return ts.SyntaxKind.NumericLiteral; } } - function scan(): SyntaxKind { + function scan(): ts.SyntaxKind { startPos = pos; - tokenFlags = TokenFlags.None; + tokenFlags = ts.TokenFlags.None; let asteriskSeen = false; while (true) { tokenPos = pos; if (pos >= end) { - return token = SyntaxKind.EndOfFileToken; + return token = ts.SyntaxKind.EndOfFileToken; } const ch = codePointAt(text, pos); // Special handling for shebang - if (ch === CharacterCodes.hash && pos === 0 && isShebangTrivia(text, pos)) { + if (ch === ts.CharacterCodes.hash && pos === 0 && isShebangTrivia(text, pos)) { pos = scanShebangTrivia(text, pos); if (skipTrivia) { continue; } else { - return token = SyntaxKind.ShebangTrivia; + return token = ts.SyntaxKind.ShebangTrivia; } } switch (ch) { - case CharacterCodes.lineFeed: - case CharacterCodes.carriageReturn: - tokenFlags |= TokenFlags.PrecedingLineBreak; + case ts.CharacterCodes.lineFeed: + case ts.CharacterCodes.carriageReturn: + tokenFlags |= ts.TokenFlags.PrecedingLineBreak; if (skipTrivia) { pos++; continue; } else { - if (ch === CharacterCodes.carriageReturn && pos + 1 < end && text.charCodeAt(pos + 1) === CharacterCodes.lineFeed) { + if (ch === ts.CharacterCodes.carriageReturn && pos + 1 < end && text.charCodeAt(pos + 1) === ts.CharacterCodes.lineFeed) { // consume both CR and LF pos += 2; } else { pos++; } - return token = SyntaxKind.NewLineTrivia; + return token = ts.SyntaxKind.NewLineTrivia; } - case CharacterCodes.tab: - case CharacterCodes.verticalTab: - case CharacterCodes.formFeed: - case CharacterCodes.space: - case CharacterCodes.nonBreakingSpace: - case CharacterCodes.ogham: - case CharacterCodes.enQuad: - case CharacterCodes.emQuad: - case CharacterCodes.enSpace: - case CharacterCodes.emSpace: - case CharacterCodes.threePerEmSpace: - case CharacterCodes.fourPerEmSpace: - case CharacterCodes.sixPerEmSpace: - case CharacterCodes.figureSpace: - case CharacterCodes.punctuationSpace: - case CharacterCodes.thinSpace: - case CharacterCodes.hairSpace: - case CharacterCodes.zeroWidthSpace: - case CharacterCodes.narrowNoBreakSpace: - case CharacterCodes.mathematicalSpace: - case CharacterCodes.ideographicSpace: - case CharacterCodes.byteOrderMark: + case ts.CharacterCodes.tab: + case ts.CharacterCodes.verticalTab: + case ts.CharacterCodes.formFeed: + case ts.CharacterCodes.space: + case ts.CharacterCodes.nonBreakingSpace: + case ts.CharacterCodes.ogham: + case ts.CharacterCodes.enQuad: + case ts.CharacterCodes.emQuad: + case ts.CharacterCodes.enSpace: + case ts.CharacterCodes.emSpace: + case ts.CharacterCodes.threePerEmSpace: + case ts.CharacterCodes.fourPerEmSpace: + case ts.CharacterCodes.sixPerEmSpace: + case ts.CharacterCodes.figureSpace: + case ts.CharacterCodes.punctuationSpace: + case ts.CharacterCodes.thinSpace: + case ts.CharacterCodes.hairSpace: + case ts.CharacterCodes.zeroWidthSpace: + case ts.CharacterCodes.narrowNoBreakSpace: + case ts.CharacterCodes.mathematicalSpace: + case ts.CharacterCodes.ideographicSpace: + case ts.CharacterCodes.byteOrderMark: if (skipTrivia) { pos++; continue; @@ -1677,98 +1673,98 @@ namespace ts { while (pos < end && isWhiteSpaceSingleLine(text.charCodeAt(pos))) { pos++; } - return token = SyntaxKind.WhitespaceTrivia; + return token = ts.SyntaxKind.WhitespaceTrivia; } - case CharacterCodes.exclamation: - if (text.charCodeAt(pos + 1) === CharacterCodes.equals) { - if (text.charCodeAt(pos + 2) === CharacterCodes.equals) { - return pos += 3, token = SyntaxKind.ExclamationEqualsEqualsToken; + case ts.CharacterCodes.exclamation: + if (text.charCodeAt(pos + 1) === ts.CharacterCodes.equals) { + if (text.charCodeAt(pos + 2) === ts.CharacterCodes.equals) { + return pos += 3, token = ts.SyntaxKind.ExclamationEqualsEqualsToken; } - return pos += 2, token = SyntaxKind.ExclamationEqualsToken; + return pos += 2, token = ts.SyntaxKind.ExclamationEqualsToken; } pos++; - return token = SyntaxKind.ExclamationToken; - case CharacterCodes.doubleQuote: - case CharacterCodes.singleQuote: + return token = ts.SyntaxKind.ExclamationToken; + case ts.CharacterCodes.doubleQuote: + case ts.CharacterCodes.singleQuote: tokenValue = scanString(); - return token = SyntaxKind.StringLiteral; - case CharacterCodes.backtick: + return token = ts.SyntaxKind.StringLiteral; + case ts.CharacterCodes.backtick: return token = scanTemplateAndSetTokenValue(/* isTaggedTemplate */ false); - case CharacterCodes.percent: - if (text.charCodeAt(pos + 1) === CharacterCodes.equals) { - return pos += 2, token = SyntaxKind.PercentEqualsToken; + case ts.CharacterCodes.percent: + if (text.charCodeAt(pos + 1) === ts.CharacterCodes.equals) { + return pos += 2, token = ts.SyntaxKind.PercentEqualsToken; } pos++; - return token = SyntaxKind.PercentToken; - case CharacterCodes.ampersand: - if (text.charCodeAt(pos + 1) === CharacterCodes.ampersand) { - if (text.charCodeAt(pos + 2) === CharacterCodes.equals) { - return pos += 3, token = SyntaxKind.AmpersandAmpersandEqualsToken; + return token = ts.SyntaxKind.PercentToken; + case ts.CharacterCodes.ampersand: + if (text.charCodeAt(pos + 1) === ts.CharacterCodes.ampersand) { + if (text.charCodeAt(pos + 2) === ts.CharacterCodes.equals) { + return pos += 3, token = ts.SyntaxKind.AmpersandAmpersandEqualsToken; } - return pos += 2, token = SyntaxKind.AmpersandAmpersandToken; + return pos += 2, token = ts.SyntaxKind.AmpersandAmpersandToken; } - if (text.charCodeAt(pos + 1) === CharacterCodes.equals) { - return pos += 2, token = SyntaxKind.AmpersandEqualsToken; + if (text.charCodeAt(pos + 1) === ts.CharacterCodes.equals) { + return pos += 2, token = ts.SyntaxKind.AmpersandEqualsToken; } pos++; - return token = SyntaxKind.AmpersandToken; - case CharacterCodes.openParen: + return token = ts.SyntaxKind.AmpersandToken; + case ts.CharacterCodes.openParen: pos++; - return token = SyntaxKind.OpenParenToken; - case CharacterCodes.closeParen: + return token = ts.SyntaxKind.OpenParenToken; + case ts.CharacterCodes.closeParen: pos++; - return token = SyntaxKind.CloseParenToken; - case CharacterCodes.asterisk: - if (text.charCodeAt(pos + 1) === CharacterCodes.equals) { - return pos += 2, token = SyntaxKind.AsteriskEqualsToken; + return token = ts.SyntaxKind.CloseParenToken; + case ts.CharacterCodes.asterisk: + if (text.charCodeAt(pos + 1) === ts.CharacterCodes.equals) { + return pos += 2, token = ts.SyntaxKind.AsteriskEqualsToken; } - if (text.charCodeAt(pos + 1) === CharacterCodes.asterisk) { - if (text.charCodeAt(pos + 2) === CharacterCodes.equals) { - return pos += 3, token = SyntaxKind.AsteriskAsteriskEqualsToken; + if (text.charCodeAt(pos + 1) === ts.CharacterCodes.asterisk) { + if (text.charCodeAt(pos + 2) === ts.CharacterCodes.equals) { + return pos += 3, token = ts.SyntaxKind.AsteriskAsteriskEqualsToken; } - return pos += 2, token = SyntaxKind.AsteriskAsteriskToken; + return pos += 2, token = ts.SyntaxKind.AsteriskAsteriskToken; } pos++; - if (inJSDocType && !asteriskSeen && (tokenFlags & TokenFlags.PrecedingLineBreak)) { + if (inJSDocType && !asteriskSeen && (tokenFlags & ts.TokenFlags.PrecedingLineBreak)) { // decoration at the start of a JSDoc comment line asteriskSeen = true; continue; } - return token = SyntaxKind.AsteriskToken; - case CharacterCodes.plus: - if (text.charCodeAt(pos + 1) === CharacterCodes.plus) { - return pos += 2, token = SyntaxKind.PlusPlusToken; + return token = ts.SyntaxKind.AsteriskToken; + case ts.CharacterCodes.plus: + if (text.charCodeAt(pos + 1) === ts.CharacterCodes.plus) { + return pos += 2, token = ts.SyntaxKind.PlusPlusToken; } - if (text.charCodeAt(pos + 1) === CharacterCodes.equals) { - return pos += 2, token = SyntaxKind.PlusEqualsToken; + if (text.charCodeAt(pos + 1) === ts.CharacterCodes.equals) { + return pos += 2, token = ts.SyntaxKind.PlusEqualsToken; } pos++; - return token = SyntaxKind.PlusToken; - case CharacterCodes.comma: + return token = ts.SyntaxKind.PlusToken; + case ts.CharacterCodes.comma: pos++; - return token = SyntaxKind.CommaToken; - case CharacterCodes.minus: - if (text.charCodeAt(pos + 1) === CharacterCodes.minus) { - return pos += 2, token = SyntaxKind.MinusMinusToken; + return token = ts.SyntaxKind.CommaToken; + case ts.CharacterCodes.minus: + if (text.charCodeAt(pos + 1) === ts.CharacterCodes.minus) { + return pos += 2, token = ts.SyntaxKind.MinusMinusToken; } - if (text.charCodeAt(pos + 1) === CharacterCodes.equals) { - return pos += 2, token = SyntaxKind.MinusEqualsToken; + if (text.charCodeAt(pos + 1) === ts.CharacterCodes.equals) { + return pos += 2, token = ts.SyntaxKind.MinusEqualsToken; } pos++; - return token = SyntaxKind.MinusToken; - case CharacterCodes.dot: + return token = ts.SyntaxKind.MinusToken; + case ts.CharacterCodes.dot: if (isDigit(text.charCodeAt(pos + 1))) { tokenValue = scanNumber().value; - return token = SyntaxKind.NumericLiteral; + return token = ts.SyntaxKind.NumericLiteral; } - if (text.charCodeAt(pos + 1) === CharacterCodes.dot && text.charCodeAt(pos + 2) === CharacterCodes.dot) { - return pos += 3, token = SyntaxKind.DotDotDotToken; + if (text.charCodeAt(pos + 1) === ts.CharacterCodes.dot && text.charCodeAt(pos + 2) === ts.CharacterCodes.dot) { + return pos += 3, token = ts.SyntaxKind.DotDotDotToken; } pos++; - return token = SyntaxKind.DotToken; - case CharacterCodes.slash: + return token = ts.SyntaxKind.DotToken; + case ts.CharacterCodes.slash: // Single-line comment - if (text.charCodeAt(pos + 1) === CharacterCodes.slash) { + if (text.charCodeAt(pos + 1) === ts.CharacterCodes.slash) { pos += 2; while (pos < end) { @@ -1778,25 +1774,20 @@ namespace ts { pos++; } - commentDirectives = appendIfCommentDirective( - commentDirectives, - text.slice(tokenPos, pos), - commentDirectiveRegExSingleLine, - tokenPos, - ); + commentDirectives = appendIfCommentDirective(commentDirectives, text.slice(tokenPos, pos), commentDirectiveRegExSingleLine, tokenPos); if (skipTrivia) { continue; } else { - return token = SyntaxKind.SingleLineCommentTrivia; + return token = ts.SyntaxKind.SingleLineCommentTrivia; } } // Multi-line comment - if (text.charCodeAt(pos + 1) === CharacterCodes.asterisk) { + if (text.charCodeAt(pos + 1) === ts.CharacterCodes.asterisk) { pos += 2; - if (text.charCodeAt(pos) === CharacterCodes.asterisk && text.charCodeAt(pos + 1) !== CharacterCodes.slash) { - tokenFlags |= TokenFlags.PrecedingJSDocComment; + if (text.charCodeAt(pos) === ts.CharacterCodes.asterisk && text.charCodeAt(pos + 1) !== ts.CharacterCodes.slash) { + tokenFlags |= ts.TokenFlags.PrecedingJSDocComment; } let commentClosed = false; @@ -1804,7 +1795,7 @@ namespace ts { while (pos < end) { const ch = text.charCodeAt(pos); - if (ch === CharacterCodes.asterisk && text.charCodeAt(pos + 1) === CharacterCodes.slash) { + if (ch === ts.CharacterCodes.asterisk && text.charCodeAt(pos + 1) === ts.CharacterCodes.slash) { pos += 2; commentClosed = true; break; @@ -1814,14 +1805,14 @@ namespace ts { if (isLineBreak(ch)) { lastLineStart = pos; - tokenFlags |= TokenFlags.PrecedingLineBreak; + tokenFlags |= ts.TokenFlags.PrecedingLineBreak; } } commentDirectives = appendIfCommentDirective(commentDirectives, text.slice(lastLineStart, pos), commentDirectiveRegExMultiLine, lastLineStart); if (!commentClosed) { - error(Diagnostics.Asterisk_Slash_expected); + error(ts.Diagnostics.Asterisk_Slash_expected); } if (skipTrivia) { @@ -1829,205 +1820,204 @@ namespace ts { } else { if (!commentClosed) { - tokenFlags |= TokenFlags.Unterminated; + tokenFlags |= ts.TokenFlags.Unterminated; } - return token = SyntaxKind.MultiLineCommentTrivia; + return token = ts.SyntaxKind.MultiLineCommentTrivia; } } - if (text.charCodeAt(pos + 1) === CharacterCodes.equals) { - return pos += 2, token = SyntaxKind.SlashEqualsToken; + if (text.charCodeAt(pos + 1) === ts.CharacterCodes.equals) { + return pos += 2, token = ts.SyntaxKind.SlashEqualsToken; } pos++; - return token = SyntaxKind.SlashToken; - - case CharacterCodes._0: - if (pos + 2 < end && (text.charCodeAt(pos + 1) === CharacterCodes.X || text.charCodeAt(pos + 1) === CharacterCodes.x)) { + return token = ts.SyntaxKind.SlashToken; + case ts.CharacterCodes._0: + if (pos + 2 < end && (text.charCodeAt(pos + 1) === ts.CharacterCodes.X || text.charCodeAt(pos + 1) === ts.CharacterCodes.x)) { pos += 2; tokenValue = scanMinimumNumberOfHexDigits(1, /*canHaveSeparators*/ true); if (!tokenValue) { - error(Diagnostics.Hexadecimal_digit_expected); + error(ts.Diagnostics.Hexadecimal_digit_expected); tokenValue = "0"; } tokenValue = "0x" + tokenValue; - tokenFlags |= TokenFlags.HexSpecifier; + tokenFlags |= ts.TokenFlags.HexSpecifier; return token = checkBigIntSuffix(); } - else if (pos + 2 < end && (text.charCodeAt(pos + 1) === CharacterCodes.B || text.charCodeAt(pos + 1) === CharacterCodes.b)) { + else if (pos + 2 < end && (text.charCodeAt(pos + 1) === ts.CharacterCodes.B || text.charCodeAt(pos + 1) === ts.CharacterCodes.b)) { pos += 2; tokenValue = scanBinaryOrOctalDigits(/* base */ 2); if (!tokenValue) { - error(Diagnostics.Binary_digit_expected); + error(ts.Diagnostics.Binary_digit_expected); tokenValue = "0"; } tokenValue = "0b" + tokenValue; - tokenFlags |= TokenFlags.BinarySpecifier; + tokenFlags |= ts.TokenFlags.BinarySpecifier; return token = checkBigIntSuffix(); } - else if (pos + 2 < end && (text.charCodeAt(pos + 1) === CharacterCodes.O || text.charCodeAt(pos + 1) === CharacterCodes.o)) { + else if (pos + 2 < end && (text.charCodeAt(pos + 1) === ts.CharacterCodes.O || text.charCodeAt(pos + 1) === ts.CharacterCodes.o)) { pos += 2; tokenValue = scanBinaryOrOctalDigits(/* base */ 8); if (!tokenValue) { - error(Diagnostics.Octal_digit_expected); + error(ts.Diagnostics.Octal_digit_expected); tokenValue = "0"; } tokenValue = "0o" + tokenValue; - tokenFlags |= TokenFlags.OctalSpecifier; + tokenFlags |= ts.TokenFlags.OctalSpecifier; return token = checkBigIntSuffix(); } // Try to parse as an octal if (pos + 1 < end && isOctalDigit(text.charCodeAt(pos + 1))) { tokenValue = "" + scanOctalDigits(); - tokenFlags |= TokenFlags.Octal; - return token = SyntaxKind.NumericLiteral; + tokenFlags |= ts.TokenFlags.Octal; + return token = ts.SyntaxKind.NumericLiteral; } // This fall-through is a deviation from the EcmaScript grammar. The grammar says that a leading zero // can only be followed by an octal digit, a dot, or the end of the number literal. However, we are being // permissive and allowing decimal digits of the form 08* and 09* (which many browsers also do). // falls through - case CharacterCodes._1: - case CharacterCodes._2: - case CharacterCodes._3: - case CharacterCodes._4: - case CharacterCodes._5: - case CharacterCodes._6: - case CharacterCodes._7: - case CharacterCodes._8: - case CharacterCodes._9: + case ts.CharacterCodes._1: + case ts.CharacterCodes._2: + case ts.CharacterCodes._3: + case ts.CharacterCodes._4: + case ts.CharacterCodes._5: + case ts.CharacterCodes._6: + case ts.CharacterCodes._7: + case ts.CharacterCodes._8: + case ts.CharacterCodes._9: ({ type: token, value: tokenValue } = scanNumber()); return token; - case CharacterCodes.colon: + case ts.CharacterCodes.colon: pos++; - return token = SyntaxKind.ColonToken; - case CharacterCodes.semicolon: + return token = ts.SyntaxKind.ColonToken; + case ts.CharacterCodes.semicolon: pos++; - return token = SyntaxKind.SemicolonToken; - case CharacterCodes.lessThan: + return token = ts.SyntaxKind.SemicolonToken; + case ts.CharacterCodes.lessThan: if (isConflictMarkerTrivia(text, pos)) { pos = scanConflictMarkerTrivia(text, pos, error); if (skipTrivia) { continue; } else { - return token = SyntaxKind.ConflictMarkerTrivia; + return token = ts.SyntaxKind.ConflictMarkerTrivia; } } - if (text.charCodeAt(pos + 1) === CharacterCodes.lessThan) { - if (text.charCodeAt(pos + 2) === CharacterCodes.equals) { - return pos += 3, token = SyntaxKind.LessThanLessThanEqualsToken; + if (text.charCodeAt(pos + 1) === ts.CharacterCodes.lessThan) { + if (text.charCodeAt(pos + 2) === ts.CharacterCodes.equals) { + return pos += 3, token = ts.SyntaxKind.LessThanLessThanEqualsToken; } - return pos += 2, token = SyntaxKind.LessThanLessThanToken; + return pos += 2, token = ts.SyntaxKind.LessThanLessThanToken; } - if (text.charCodeAt(pos + 1) === CharacterCodes.equals) { - return pos += 2, token = SyntaxKind.LessThanEqualsToken; + if (text.charCodeAt(pos + 1) === ts.CharacterCodes.equals) { + return pos += 2, token = ts.SyntaxKind.LessThanEqualsToken; } - if (languageVariant === LanguageVariant.JSX && - text.charCodeAt(pos + 1) === CharacterCodes.slash && - text.charCodeAt(pos + 2) !== CharacterCodes.asterisk) { - return pos += 2, token = SyntaxKind.LessThanSlashToken; + if (languageVariant === ts.LanguageVariant.JSX && + text.charCodeAt(pos + 1) === ts.CharacterCodes.slash && + text.charCodeAt(pos + 2) !== ts.CharacterCodes.asterisk) { + return pos += 2, token = ts.SyntaxKind.LessThanSlashToken; } pos++; - return token = SyntaxKind.LessThanToken; - case CharacterCodes.equals: + return token = ts.SyntaxKind.LessThanToken; + case ts.CharacterCodes.equals: if (isConflictMarkerTrivia(text, pos)) { pos = scanConflictMarkerTrivia(text, pos, error); if (skipTrivia) { continue; } else { - return token = SyntaxKind.ConflictMarkerTrivia; + return token = ts.SyntaxKind.ConflictMarkerTrivia; } } - if (text.charCodeAt(pos + 1) === CharacterCodes.equals) { - if (text.charCodeAt(pos + 2) === CharacterCodes.equals) { - return pos += 3, token = SyntaxKind.EqualsEqualsEqualsToken; + if (text.charCodeAt(pos + 1) === ts.CharacterCodes.equals) { + if (text.charCodeAt(pos + 2) === ts.CharacterCodes.equals) { + return pos += 3, token = ts.SyntaxKind.EqualsEqualsEqualsToken; } - return pos += 2, token = SyntaxKind.EqualsEqualsToken; + return pos += 2, token = ts.SyntaxKind.EqualsEqualsToken; } - if (text.charCodeAt(pos + 1) === CharacterCodes.greaterThan) { - return pos += 2, token = SyntaxKind.EqualsGreaterThanToken; + if (text.charCodeAt(pos + 1) === ts.CharacterCodes.greaterThan) { + return pos += 2, token = ts.SyntaxKind.EqualsGreaterThanToken; } pos++; - return token = SyntaxKind.EqualsToken; - case CharacterCodes.greaterThan: + return token = ts.SyntaxKind.EqualsToken; + case ts.CharacterCodes.greaterThan: if (isConflictMarkerTrivia(text, pos)) { pos = scanConflictMarkerTrivia(text, pos, error); if (skipTrivia) { continue; } else { - return token = SyntaxKind.ConflictMarkerTrivia; + return token = ts.SyntaxKind.ConflictMarkerTrivia; } } pos++; - return token = SyntaxKind.GreaterThanToken; - case CharacterCodes.question: - if (text.charCodeAt(pos + 1) === CharacterCodes.dot && !isDigit(text.charCodeAt(pos + 2))) { - return pos += 2, token = SyntaxKind.QuestionDotToken; + return token = ts.SyntaxKind.GreaterThanToken; + case ts.CharacterCodes.question: + if (text.charCodeAt(pos + 1) === ts.CharacterCodes.dot && !isDigit(text.charCodeAt(pos + 2))) { + return pos += 2, token = ts.SyntaxKind.QuestionDotToken; } - if (text.charCodeAt(pos + 1) === CharacterCodes.question) { - if (text.charCodeAt(pos + 2) === CharacterCodes.equals) { - return pos += 3, token = SyntaxKind.QuestionQuestionEqualsToken; + if (text.charCodeAt(pos + 1) === ts.CharacterCodes.question) { + if (text.charCodeAt(pos + 2) === ts.CharacterCodes.equals) { + return pos += 3, token = ts.SyntaxKind.QuestionQuestionEqualsToken; } - return pos += 2, token = SyntaxKind.QuestionQuestionToken; + return pos += 2, token = ts.SyntaxKind.QuestionQuestionToken; } pos++; - return token = SyntaxKind.QuestionToken; - case CharacterCodes.openBracket: + return token = ts.SyntaxKind.QuestionToken; + case ts.CharacterCodes.openBracket: pos++; - return token = SyntaxKind.OpenBracketToken; - case CharacterCodes.closeBracket: + return token = ts.SyntaxKind.OpenBracketToken; + case ts.CharacterCodes.closeBracket: pos++; - return token = SyntaxKind.CloseBracketToken; - case CharacterCodes.caret: - if (text.charCodeAt(pos + 1) === CharacterCodes.equals) { - return pos += 2, token = SyntaxKind.CaretEqualsToken; + return token = ts.SyntaxKind.CloseBracketToken; + case ts.CharacterCodes.caret: + if (text.charCodeAt(pos + 1) === ts.CharacterCodes.equals) { + return pos += 2, token = ts.SyntaxKind.CaretEqualsToken; } pos++; - return token = SyntaxKind.CaretToken; - case CharacterCodes.openBrace: + return token = ts.SyntaxKind.CaretToken; + case ts.CharacterCodes.openBrace: pos++; - return token = SyntaxKind.OpenBraceToken; - case CharacterCodes.bar: + return token = ts.SyntaxKind.OpenBraceToken; + case ts.CharacterCodes.bar: if (isConflictMarkerTrivia(text, pos)) { pos = scanConflictMarkerTrivia(text, pos, error); if (skipTrivia) { continue; } else { - return token = SyntaxKind.ConflictMarkerTrivia; + return token = ts.SyntaxKind.ConflictMarkerTrivia; } } - if (text.charCodeAt(pos + 1) === CharacterCodes.bar) { - if (text.charCodeAt(pos + 2) === CharacterCodes.equals) { - return pos += 3, token = SyntaxKind.BarBarEqualsToken; + if (text.charCodeAt(pos + 1) === ts.CharacterCodes.bar) { + if (text.charCodeAt(pos + 2) === ts.CharacterCodes.equals) { + return pos += 3, token = ts.SyntaxKind.BarBarEqualsToken; } - return pos += 2, token = SyntaxKind.BarBarToken; + return pos += 2, token = ts.SyntaxKind.BarBarToken; } - if (text.charCodeAt(pos + 1) === CharacterCodes.equals) { - return pos += 2, token = SyntaxKind.BarEqualsToken; + if (text.charCodeAt(pos + 1) === ts.CharacterCodes.equals) { + return pos += 2, token = ts.SyntaxKind.BarEqualsToken; } pos++; - return token = SyntaxKind.BarToken; - case CharacterCodes.closeBrace: + return token = ts.SyntaxKind.BarToken; + case ts.CharacterCodes.closeBrace: pos++; - return token = SyntaxKind.CloseBraceToken; - case CharacterCodes.tilde: + return token = ts.SyntaxKind.CloseBraceToken; + case ts.CharacterCodes.tilde: pos++; - return token = SyntaxKind.TildeToken; - case CharacterCodes.at: + return token = ts.SyntaxKind.TildeToken; + case ts.CharacterCodes.at: pos++; - return token = SyntaxKind.AtToken; - case CharacterCodes.backslash: + return token = ts.SyntaxKind.AtToken; + case ts.CharacterCodes.backslash: const extendedCookedChar = peekExtendedUnicodeEscape(); if (extendedCookedChar >= 0 && isIdentifierStart(extendedCookedChar, languageVersion)) { pos += 3; - tokenFlags |= TokenFlags.ExtendedUnicodeEscape; + tokenFlags |= ts.TokenFlags.ExtendedUnicodeEscape; tokenValue = scanExtendedUnicodeEscape() + scanIdentifierParts(); return token = getIdentifierToken(); } @@ -2035,19 +2025,19 @@ namespace ts { const cookedChar = peekUnicodeEscape(); if (cookedChar >= 0 && isIdentifierStart(cookedChar, languageVersion)) { pos += 6; - tokenFlags |= TokenFlags.UnicodeEscape; + tokenFlags |= ts.TokenFlags.UnicodeEscape; tokenValue = String.fromCharCode(cookedChar) + scanIdentifierParts(); return token = getIdentifierToken(); } - error(Diagnostics.Invalid_character); + error(ts.Diagnostics.Invalid_character); pos++; - return token = SyntaxKind.Unknown; - case CharacterCodes.hash: + return token = ts.SyntaxKind.Unknown; + case ts.CharacterCodes.hash: if (pos !== 0 && text[pos + 1] === "!") { - error(Diagnostics.can_only_be_used_at_the_start_of_a_file); + error(ts.Diagnostics.can_only_be_used_at_the_start_of_a_file); pos++; - return token = SyntaxKind.Unknown; + return token = ts.SyntaxKind.Unknown; } if (isIdentifierStart(codePointAt(text, pos + 1), languageVersion)) { @@ -2056,9 +2046,9 @@ namespace ts { } else { tokenValue = String.fromCharCode(codePointAt(text, pos)); - error(Diagnostics.Invalid_character, pos++, charSize(ch)); + error(ts.Diagnostics.Invalid_character, pos++, charSize(ch)); } - return token = SyntaxKind.PrivateIdentifier; + return token = ts.SyntaxKind.PrivateIdentifier; default: const identifierKind = scanIdentifier(ch, languageVersion); if (identifierKind) { @@ -2069,24 +2059,24 @@ namespace ts { continue; } else if (isLineBreak(ch)) { - tokenFlags |= TokenFlags.PrecedingLineBreak; + tokenFlags |= ts.TokenFlags.PrecedingLineBreak; pos += charSize(ch); continue; } const size = charSize(ch); - error(Diagnostics.Invalid_character, pos, size); + error(ts.Diagnostics.Invalid_character, pos, size); pos += size; - return token = SyntaxKind.Unknown; + return token = ts.SyntaxKind.Unknown; } } } - function reScanInvalidIdentifier(): SyntaxKind { - Debug.assert(token === SyntaxKind.Unknown, "'reScanInvalidIdentifier' should only be called when the current token is 'SyntaxKind.Unknown'."); + function reScanInvalidIdentifier(): ts.SyntaxKind { + ts.Debug.assert(token === ts.SyntaxKind.Unknown, "'reScanInvalidIdentifier' should only be called when the current token is 'SyntaxKind.Unknown'."); pos = tokenPos = startPos; tokenFlags = 0; const ch = codePointAt(text, pos); - const identifierKind = scanIdentifier(ch, ScriptTarget.ESNext); + const identifierKind = scanIdentifier(ch, ts.ScriptTarget.ESNext); if (identifierKind) { return token = identifierKind; } @@ -2094,50 +2084,51 @@ namespace ts { return token; // Still `SyntaKind.Unknown` } - function scanIdentifier(startCharacter: number, languageVersion: ScriptTarget) { + function scanIdentifier(startCharacter: number, languageVersion: ts.ScriptTarget) { let ch = startCharacter; if (isIdentifierStart(ch, languageVersion)) { pos += charSize(ch); - while (pos < end && isIdentifierPart(ch = codePointAt(text, pos), languageVersion)) pos += charSize(ch); + while (pos < end && isIdentifierPart(ch = codePointAt(text, pos), languageVersion)) + pos += charSize(ch); tokenValue = text.substring(tokenPos, pos); - if (ch === CharacterCodes.backslash) { + if (ch === ts.CharacterCodes.backslash) { tokenValue += scanIdentifierParts(); } return getIdentifierToken(); } } - function reScanGreaterToken(): SyntaxKind { - if (token === SyntaxKind.GreaterThanToken) { - if (text.charCodeAt(pos) === CharacterCodes.greaterThan) { - if (text.charCodeAt(pos + 1) === CharacterCodes.greaterThan) { - if (text.charCodeAt(pos + 2) === CharacterCodes.equals) { - return pos += 3, token = SyntaxKind.GreaterThanGreaterThanGreaterThanEqualsToken; + function reScanGreaterToken(): ts.SyntaxKind { + if (token === ts.SyntaxKind.GreaterThanToken) { + if (text.charCodeAt(pos) === ts.CharacterCodes.greaterThan) { + if (text.charCodeAt(pos + 1) === ts.CharacterCodes.greaterThan) { + if (text.charCodeAt(pos + 2) === ts.CharacterCodes.equals) { + return pos += 3, token = ts.SyntaxKind.GreaterThanGreaterThanGreaterThanEqualsToken; } - return pos += 2, token = SyntaxKind.GreaterThanGreaterThanGreaterThanToken; + return pos += 2, token = ts.SyntaxKind.GreaterThanGreaterThanGreaterThanToken; } - if (text.charCodeAt(pos + 1) === CharacterCodes.equals) { - return pos += 2, token = SyntaxKind.GreaterThanGreaterThanEqualsToken; + if (text.charCodeAt(pos + 1) === ts.CharacterCodes.equals) { + return pos += 2, token = ts.SyntaxKind.GreaterThanGreaterThanEqualsToken; } pos++; - return token = SyntaxKind.GreaterThanGreaterThanToken; + return token = ts.SyntaxKind.GreaterThanGreaterThanToken; } - if (text.charCodeAt(pos) === CharacterCodes.equals) { + if (text.charCodeAt(pos) === ts.CharacterCodes.equals) { pos++; - return token = SyntaxKind.GreaterThanEqualsToken; + return token = ts.SyntaxKind.GreaterThanEqualsToken; } } return token; } - function reScanAsteriskEqualsToken(): SyntaxKind { - Debug.assert(token === SyntaxKind.AsteriskEqualsToken, "'reScanAsteriskEqualsToken' should only be called on a '*='"); + function reScanAsteriskEqualsToken(): ts.SyntaxKind { + ts.Debug.assert(token === ts.SyntaxKind.AsteriskEqualsToken, "'reScanAsteriskEqualsToken' should only be called on a '*='"); pos = tokenPos + 1; - return token = SyntaxKind.EqualsToken; + return token = ts.SyntaxKind.EqualsToken; } - function reScanSlashToken(): SyntaxKind { - if (token === SyntaxKind.SlashToken || token === SyntaxKind.SlashEqualsToken) { + function reScanSlashToken(): ts.SyntaxKind { + if (token === ts.SyntaxKind.SlashToken || token === ts.SyntaxKind.SlashEqualsToken) { let p = tokenPos + 1; let inEscape = false; let inCharacterClass = false; @@ -2145,15 +2136,15 @@ namespace ts { // If we reach the end of a file, or hit a newline, then this is an unterminated // regex. Report error and return what we have so far. if (p >= end) { - tokenFlags |= TokenFlags.Unterminated; - error(Diagnostics.Unterminated_regular_expression_literal); + tokenFlags |= ts.TokenFlags.Unterminated; + error(ts.Diagnostics.Unterminated_regular_expression_literal); break; } const ch = text.charCodeAt(p); if (isLineBreak(ch)) { - tokenFlags |= TokenFlags.Unterminated; - error(Diagnostics.Unterminated_regular_expression_literal); + tokenFlags |= ts.TokenFlags.Unterminated; + error(ts.Diagnostics.Unterminated_regular_expression_literal); break; } @@ -2162,19 +2153,19 @@ namespace ts { // reset the flag and just advance to the next char. inEscape = false; } - else if (ch === CharacterCodes.slash && !inCharacterClass) { + else if (ch === ts.CharacterCodes.slash && !inCharacterClass) { // A slash within a character class is permissible, // but in general it signals the end of the regexp literal. p++; break; } - else if (ch === CharacterCodes.openBracket) { + else if (ch === ts.CharacterCodes.openBracket) { inCharacterClass = true; } - else if (ch === CharacterCodes.backslash) { + else if (ch === ts.CharacterCodes.backslash) { inEscape = true; } - else if (ch === CharacterCodes.closeBracket) { + else if (ch === ts.CharacterCodes.closeBracket) { inCharacterClass = false; } p++; @@ -2185,29 +2176,21 @@ namespace ts { } pos = p; tokenValue = text.substring(tokenPos, pos); - token = SyntaxKind.RegularExpressionLiteral; + token = ts.SyntaxKind.RegularExpressionLiteral; } return token; } - function appendIfCommentDirective( - commentDirectives: CommentDirective[] | undefined, - text: string, - commentDirectiveRegEx: RegExp, - lineStart: number, - ) { - const type = getDirectiveFromComment(trimStringStart(text), commentDirectiveRegEx); + function appendIfCommentDirective(commentDirectives: ts.CommentDirective[] | undefined, text: string, commentDirectiveRegEx: RegExp, lineStart: number) { + const type = getDirectiveFromComment(ts.trimStringStart(text), commentDirectiveRegEx); if (type === undefined) { return commentDirectives; } - return append( - commentDirectives, - { + return ts.append(commentDirectives, { range: { pos: lineStart, end: pos }, type, - }, - ); + }); } function getDirectiveFromComment(text: string, commentDirectiveRegEx: RegExp) { @@ -2218,10 +2201,10 @@ namespace ts { switch (match[1]) { case "ts-expect-error": - return CommentDirectiveType.ExpectError; + return ts.CommentDirectiveType.ExpectError; case "ts-ignore": - return CommentDirectiveType.Ignore; + return ts.CommentDirectiveType.Ignore; } return undefined; @@ -2230,64 +2213,64 @@ namespace ts { /** * Unconditionally back up and scan a template expression portion. */ - function reScanTemplateToken(isTaggedTemplate: boolean): SyntaxKind { - Debug.assert(token === SyntaxKind.CloseBraceToken, "'reScanTemplateToken' should only be called on a '}'"); + function reScanTemplateToken(isTaggedTemplate: boolean): ts.SyntaxKind { + ts.Debug.assert(token === ts.SyntaxKind.CloseBraceToken, "'reScanTemplateToken' should only be called on a '}'"); pos = tokenPos; return token = scanTemplateAndSetTokenValue(isTaggedTemplate); } - function reScanTemplateHeadOrNoSubstitutionTemplate(): SyntaxKind { + function reScanTemplateHeadOrNoSubstitutionTemplate(): ts.SyntaxKind { pos = tokenPos; return token = scanTemplateAndSetTokenValue(/* isTaggedTemplate */ true); } - function reScanJsxToken(allowMultilineJsxText = true): JsxTokenSyntaxKind { + function reScanJsxToken(allowMultilineJsxText = true): ts.JsxTokenSyntaxKind { pos = tokenPos = startPos; return token = scanJsxToken(allowMultilineJsxText); } - function reScanLessThanToken(): SyntaxKind { - if (token === SyntaxKind.LessThanLessThanToken) { + function reScanLessThanToken(): ts.SyntaxKind { + if (token === ts.SyntaxKind.LessThanLessThanToken) { pos = tokenPos + 1; - return token = SyntaxKind.LessThanToken; + return token = ts.SyntaxKind.LessThanToken; } return token; } - function reScanHashToken(): SyntaxKind { - if (token === SyntaxKind.PrivateIdentifier) { + function reScanHashToken(): ts.SyntaxKind { + if (token === ts.SyntaxKind.PrivateIdentifier) { pos = tokenPos + 1; - return token = SyntaxKind.HashToken; + return token = ts.SyntaxKind.HashToken; } return token; } - function reScanQuestionToken(): SyntaxKind { - Debug.assert(token === SyntaxKind.QuestionQuestionToken, "'reScanQuestionToken' should only be called on a '??'"); + function reScanQuestionToken(): ts.SyntaxKind { + ts.Debug.assert(token === ts.SyntaxKind.QuestionQuestionToken, "'reScanQuestionToken' should only be called on a '??'"); pos = tokenPos + 1; - return token = SyntaxKind.QuestionToken; + return token = ts.SyntaxKind.QuestionToken; } - function scanJsxToken(allowMultilineJsxText = true): JsxTokenSyntaxKind { + function scanJsxToken(allowMultilineJsxText = true): ts.JsxTokenSyntaxKind { startPos = tokenPos = pos; if (pos >= end) { - return token = SyntaxKind.EndOfFileToken; + return token = ts.SyntaxKind.EndOfFileToken; } let char = text.charCodeAt(pos); - if (char === CharacterCodes.lessThan) { - if (text.charCodeAt(pos + 1) === CharacterCodes.slash) { + if (char === ts.CharacterCodes.lessThan) { + if (text.charCodeAt(pos + 1) === ts.CharacterCodes.slash) { pos += 2; - return token = SyntaxKind.LessThanSlashToken; + return token = ts.SyntaxKind.LessThanSlashToken; } pos++; - return token = SyntaxKind.LessThanToken; + return token = ts.SyntaxKind.LessThanToken; } - if (char === CharacterCodes.openBrace) { + if (char === ts.CharacterCodes.openBrace) { pos++; - return token = SyntaxKind.OpenBraceToken; + return token = ts.SyntaxKind.OpenBraceToken; } // First non-whitespace character on this line. @@ -2298,21 +2281,21 @@ namespace ts { while (pos < end) { char = text.charCodeAt(pos); - if (char === CharacterCodes.openBrace) { + if (char === ts.CharacterCodes.openBrace) { break; } - if (char === CharacterCodes.lessThan) { + if (char === ts.CharacterCodes.lessThan) { if (isConflictMarkerTrivia(text, pos)) { pos = scanConflictMarkerTrivia(text, pos, error); - return token = SyntaxKind.ConflictMarkerTrivia; + return token = ts.SyntaxKind.ConflictMarkerTrivia; } break; } - if (char === CharacterCodes.greaterThan) { - error(Diagnostics.Unexpected_token_Did_you_mean_or_gt, pos, 1); + if (char === ts.CharacterCodes.greaterThan) { + error(ts.Diagnostics.Unexpected_token_Did_you_mean_or_gt, pos, 1); } - if (char === CharacterCodes.closeBrace) { - error(Diagnostics.Unexpected_token_Did_you_mean_or_rbrace, pos, 1); + if (char === ts.CharacterCodes.closeBrace) { + error(ts.Diagnostics.Unexpected_token_Did_you_mean_or_rbrace, pos, 1); } // FirstNonWhitespace is 0, then we only see whitespaces so far. If we see a linebreak, we want to ignore that whitespaces. @@ -2338,12 +2321,12 @@ namespace ts { tokenValue = text.substring(startPos, pos); - return firstNonWhitespace === -1 ? SyntaxKind.JsxTextAllWhiteSpaces : SyntaxKind.JsxText; + return firstNonWhitespace === -1 ? ts.SyntaxKind.JsxTextAllWhiteSpaces : ts.SyntaxKind.JsxText; } // Scans a JSX identifier; these differ from normal identifiers in that // they allow dashes - function scanJsxIdentifier(): SyntaxKind { + function scanJsxIdentifier(): ts.SyntaxKind { if (tokenIsIdentifierOrKeyword(token)) { // An identifier or keyword has already been parsed - check for a `-` or a single instance of `:` and then append it and // everything after it to the token @@ -2352,16 +2335,16 @@ namespace ts { let namespaceSeparator = false; while (pos < end) { const ch = text.charCodeAt(pos); - if (ch === CharacterCodes.minus) { + if (ch === ts.CharacterCodes.minus) { tokenValue += "-"; pos++; continue; } - else if (ch === CharacterCodes.colon && !namespaceSeparator) { + else if (ch === ts.CharacterCodes.colon && !namespaceSeparator) { tokenValue += ":"; pos++; namespaceSeparator = true; - token = SyntaxKind.Identifier; // swap from keyword kind to identifier kind + token = ts.SyntaxKind.Identifier; // swap from keyword kind to identifier kind continue; } const oldPos = pos; @@ -2380,83 +2363,83 @@ namespace ts { return token; } - function scanJsxAttributeValue(): SyntaxKind { + function scanJsxAttributeValue(): ts.SyntaxKind { startPos = pos; switch (text.charCodeAt(pos)) { - case CharacterCodes.doubleQuote: - case CharacterCodes.singleQuote: + case ts.CharacterCodes.doubleQuote: + case ts.CharacterCodes.singleQuote: tokenValue = scanString(/*jsxAttributeString*/ true); - return token = SyntaxKind.StringLiteral; + return token = ts.SyntaxKind.StringLiteral; default: // If this scans anything other than `{`, it's a parse error. return scan(); } } - function reScanJsxAttributeValue(): SyntaxKind { + function reScanJsxAttributeValue(): ts.SyntaxKind { pos = tokenPos = startPos; return scanJsxAttributeValue(); } - function scanJsDocToken(): JSDocSyntaxKind { + function scanJsDocToken(): ts.JSDocSyntaxKind { startPos = tokenPos = pos; - tokenFlags = TokenFlags.None; + tokenFlags = ts.TokenFlags.None; if (pos >= end) { - return token = SyntaxKind.EndOfFileToken; + return token = ts.SyntaxKind.EndOfFileToken; } const ch = codePointAt(text, pos); pos += charSize(ch); switch (ch) { - case CharacterCodes.tab: - case CharacterCodes.verticalTab: - case CharacterCodes.formFeed: - case CharacterCodes.space: + case ts.CharacterCodes.tab: + case ts.CharacterCodes.verticalTab: + case ts.CharacterCodes.formFeed: + case ts.CharacterCodes.space: while (pos < end && isWhiteSpaceSingleLine(text.charCodeAt(pos))) { pos++; } - return token = SyntaxKind.WhitespaceTrivia; - case CharacterCodes.at: - return token = SyntaxKind.AtToken; - case CharacterCodes.carriageReturn: - if (text.charCodeAt(pos) === CharacterCodes.lineFeed) { + return token = ts.SyntaxKind.WhitespaceTrivia; + case ts.CharacterCodes.at: + return token = ts.SyntaxKind.AtToken; + case ts.CharacterCodes.carriageReturn: + if (text.charCodeAt(pos) === ts.CharacterCodes.lineFeed) { pos++; } // falls through - case CharacterCodes.lineFeed: - tokenFlags |= TokenFlags.PrecedingLineBreak; - return token = SyntaxKind.NewLineTrivia; - case CharacterCodes.asterisk: - return token = SyntaxKind.AsteriskToken; - case CharacterCodes.openBrace: - return token = SyntaxKind.OpenBraceToken; - case CharacterCodes.closeBrace: - return token = SyntaxKind.CloseBraceToken; - case CharacterCodes.openBracket: - return token = SyntaxKind.OpenBracketToken; - case CharacterCodes.closeBracket: - return token = SyntaxKind.CloseBracketToken; - case CharacterCodes.lessThan: - return token = SyntaxKind.LessThanToken; - case CharacterCodes.greaterThan: - return token = SyntaxKind.GreaterThanToken; - case CharacterCodes.equals: - return token = SyntaxKind.EqualsToken; - case CharacterCodes.comma: - return token = SyntaxKind.CommaToken; - case CharacterCodes.dot: - return token = SyntaxKind.DotToken; - case CharacterCodes.backtick: - return token = SyntaxKind.BacktickToken; - case CharacterCodes.hash: - return token = SyntaxKind.HashToken; - case CharacterCodes.backslash: + case ts.CharacterCodes.lineFeed: + tokenFlags |= ts.TokenFlags.PrecedingLineBreak; + return token = ts.SyntaxKind.NewLineTrivia; + case ts.CharacterCodes.asterisk: + return token = ts.SyntaxKind.AsteriskToken; + case ts.CharacterCodes.openBrace: + return token = ts.SyntaxKind.OpenBraceToken; + case ts.CharacterCodes.closeBrace: + return token = ts.SyntaxKind.CloseBraceToken; + case ts.CharacterCodes.openBracket: + return token = ts.SyntaxKind.OpenBracketToken; + case ts.CharacterCodes.closeBracket: + return token = ts.SyntaxKind.CloseBracketToken; + case ts.CharacterCodes.lessThan: + return token = ts.SyntaxKind.LessThanToken; + case ts.CharacterCodes.greaterThan: + return token = ts.SyntaxKind.GreaterThanToken; + case ts.CharacterCodes.equals: + return token = ts.SyntaxKind.EqualsToken; + case ts.CharacterCodes.comma: + return token = ts.SyntaxKind.CommaToken; + case ts.CharacterCodes.dot: + return token = ts.SyntaxKind.DotToken; + case ts.CharacterCodes.backtick: + return token = ts.SyntaxKind.BacktickToken; + case ts.CharacterCodes.hash: + return token = ts.SyntaxKind.HashToken; + case ts.CharacterCodes.backslash: pos--; const extendedCookedChar = peekExtendedUnicodeEscape(); if (extendedCookedChar >= 0 && isIdentifierStart(extendedCookedChar, languageVersion)) { pos += 3; - tokenFlags |= TokenFlags.ExtendedUnicodeEscape; + tokenFlags |= ts.TokenFlags.ExtendedUnicodeEscape; tokenValue = scanExtendedUnicodeEscape() + scanIdentifierParts(); return token = getIdentifierToken(); } @@ -2464,25 +2447,26 @@ namespace ts { const cookedChar = peekUnicodeEscape(); if (cookedChar >= 0 && isIdentifierStart(cookedChar, languageVersion)) { pos += 6; - tokenFlags |= TokenFlags.UnicodeEscape; + tokenFlags |= ts.TokenFlags.UnicodeEscape; tokenValue = String.fromCharCode(cookedChar) + scanIdentifierParts(); return token = getIdentifierToken(); } pos++; - return token = SyntaxKind.Unknown; + return token = ts.SyntaxKind.Unknown; } if (isIdentifierStart(ch, languageVersion)) { let char = ch; - while (pos < end && isIdentifierPart(char = codePointAt(text, pos), languageVersion) || text.charCodeAt(pos) === CharacterCodes.minus) pos += charSize(char); + while (pos < end && isIdentifierPart(char = codePointAt(text, pos), languageVersion) || text.charCodeAt(pos) === ts.CharacterCodes.minus) + pos += charSize(char); tokenValue = text.substring(tokenPos, pos); - if (char === CharacterCodes.backslash) { + if (char === ts.CharacterCodes.backslash) { tokenValue += scanIdentifierParts(); } return token = getIdentifierToken(); } else { - return token = SyntaxKind.Unknown; + return token = ts.SyntaxKind.Unknown; } } @@ -2559,22 +2543,22 @@ namespace ts { onError = errorCallback; } - function setScriptTarget(scriptTarget: ScriptTarget) { + function setScriptTarget(scriptTarget: ts.ScriptTarget) { languageVersion = scriptTarget; } - function setLanguageVariant(variant: LanguageVariant) { + function setLanguageVariant(variant: ts.LanguageVariant) { languageVariant = variant; } function setTextPos(textPos: number) { - Debug.assert(textPos >= 0); + ts.Debug.assert(textPos >= 0); pos = textPos; startPos = textPos; tokenPos = textPos; - token = SyntaxKind.Unknown; + token = ts.SyntaxKind.Unknown; tokenValue = undefined!; - tokenFlags = TokenFlags.None; + tokenFlags = ts.TokenFlags.None; } function setInJSDocType(inType: boolean) { @@ -2613,7 +2597,7 @@ namespace ts { // Derived from the 10.1.1 UTF16Encoding of the ES6 Spec. function utf16EncodeAsStringFallback(codePoint: number) { - Debug.assert(0x0 <= codePoint && codePoint <= 0x10FFFF); + ts.Debug.assert(0x0 <= codePoint && codePoint <= 0x10FFFF); if (codePoint <= 65535) { return String.fromCharCode(codePoint); diff --git a/src/compiler/semver.ts b/src/compiler/semver.ts index 76d4cf2d65e7a..f3d18dcc24426 100644 --- a/src/compiler/semver.ts +++ b/src/compiler/semver.ts @@ -42,25 +42,26 @@ namespace ts { constructor(major: number, minor?: number, patch?: number, prerelease?: string, build?: string); constructor(major: number | string, minor = 0, patch = 0, prerelease = "", build = "") { if (typeof major === "string") { - const result = Debug.checkDefined(tryParseComponents(major), "Invalid version"); + const result = ts.Debug.checkDefined(tryParseComponents(major), "Invalid version"); ({ major, minor, patch, prerelease, build } = result); } - Debug.assert(major >= 0, "Invalid argument: major"); - Debug.assert(minor >= 0, "Invalid argument: minor"); - Debug.assert(patch >= 0, "Invalid argument: patch"); - Debug.assert(!prerelease || prereleaseRegExp.test(prerelease), "Invalid argument: prerelease"); - Debug.assert(!build || buildRegExp.test(build), "Invalid argument: build"); + ts.Debug.assert(major >= 0, "Invalid argument: major"); + ts.Debug.assert(minor >= 0, "Invalid argument: minor"); + ts.Debug.assert(patch >= 0, "Invalid argument: patch"); + ts.Debug.assert(!prerelease || prereleaseRegExp.test(prerelease), "Invalid argument: prerelease"); + ts.Debug.assert(!build || buildRegExp.test(build), "Invalid argument: build"); this.major = major; this.minor = minor; this.patch = patch; - this.prerelease = prerelease ? prerelease.split(".") : emptyArray; - this.build = build ? build.split(".") : emptyArray; + this.prerelease = prerelease ? prerelease.split(".") : ts.emptyArray; + this.build = build ? build.split(".") : ts.emptyArray; } static tryParse(text: string) { const result = tryParseComponents(text); - if (!result) return undefined; + if (!result) + return undefined; const { major, minor, patch, prerelease, build } = result; return new Version(major, minor, patch, prerelease, build); @@ -79,11 +80,13 @@ namespace ts { // // https://semver.org/#spec-item-11 // > Build metadata does not figure into precedence - if (this === other) return Comparison.EqualTo; - if (other === undefined) return Comparison.GreaterThan; - return compareValues(this.major, other.major) - || compareValues(this.minor, other.minor) - || compareValues(this.patch, other.patch) + if (this === other) + return ts.Comparison.EqualTo; + if (other === undefined) + return ts.Comparison.GreaterThan; + return ts.compareValues(this.major, other.major) + || ts.compareValues(this.minor, other.minor) + || ts.compareValues(this.patch, other.patch) || comparePrereleaseIdentifiers(this.prerelease, other.prerelease); } @@ -92,25 +95,30 @@ namespace ts { case "major": return new Version(this.major + 1, 0, 0); case "minor": return new Version(this.major, this.minor + 1, 0); case "patch": return new Version(this.major, this.minor, this.patch + 1); - default: return Debug.assertNever(field); + default: return ts.Debug.assertNever(field); } } toString() { let result = `${this.major}.${this.minor}.${this.patch}`; - if (some(this.prerelease)) result += `-${this.prerelease.join(".")}`; - if (some(this.build)) result += `+${this.build.join(".")}`; + if (ts.some(this.prerelease)) + result += `-${this.prerelease.join(".")}`; + if (ts.some(this.build)) + result += `+${this.build.join(".")}`; return result; } } function tryParseComponents(text: string) { const match = versionRegExp.exec(text); - if (!match) return undefined; + if (!match) + return undefined; const [, major, minor = "0", patch = "0", prerelease = "", build = ""] = match; - if (prerelease && !prereleaseRegExp.test(prerelease)) return undefined; - if (build && !buildRegExp.test(build)) return undefined; + if (prerelease && !prereleaseRegExp.test(prerelease)) + return undefined; + if (build && !buildRegExp.test(build)) + return undefined; return { major: parseInt(major, 10), minor: parseInt(minor, 10), @@ -124,9 +132,12 @@ namespace ts { // https://semver.org/#spec-item-11 // > When major, minor, and patch are equal, a pre-release version has lower precedence // > than a normal version. - if (left === right) return Comparison.EqualTo; - if (left.length === 0) return right.length === 0 ? Comparison.EqualTo : Comparison.GreaterThan; - if (right.length === 0) return Comparison.LessThan; + if (left === right) + return ts.Comparison.EqualTo; + if (left.length === 0) + return right.length === 0 ? ts.Comparison.EqualTo : ts.Comparison.GreaterThan; + if (right.length === 0) + return ts.Comparison.LessThan; // https://semver.org/#spec-item-11 // > Precedence for two pre-release versions with the same major, minor, and patch version @@ -136,32 +147,36 @@ namespace ts { for (let i = 0; i < length; i++) { const leftIdentifier = left[i]; const rightIdentifier = right[i]; - if (leftIdentifier === rightIdentifier) continue; + if (leftIdentifier === rightIdentifier) + continue; const leftIsNumeric = numericIdentifierRegExp.test(leftIdentifier); const rightIsNumeric = numericIdentifierRegExp.test(rightIdentifier); if (leftIsNumeric || rightIsNumeric) { // https://semver.org/#spec-item-11 // > Numeric identifiers always have lower precedence than non-numeric identifiers. - if (leftIsNumeric !== rightIsNumeric) return leftIsNumeric ? Comparison.LessThan : Comparison.GreaterThan; + if (leftIsNumeric !== rightIsNumeric) + return leftIsNumeric ? ts.Comparison.LessThan : ts.Comparison.GreaterThan; // https://semver.org/#spec-item-11 // > identifiers consisting of only digits are compared numerically - const result = compareValues(+leftIdentifier, +rightIdentifier); - if (result) return result; + const result = ts.compareValues(+leftIdentifier, +rightIdentifier); + if (result) + return result; } else { // https://semver.org/#spec-item-11 // > identifiers with letters or hyphens are compared lexically in ASCII sort order. - const result = compareStringsCaseSensitive(leftIdentifier, rightIdentifier); - if (result) return result; + const result = ts.compareStringsCaseSensitive(leftIdentifier, rightIdentifier); + if (result) + return result; } } // https://semver.org/#spec-item-11 // > A larger set of pre-release fields has a higher precedence than a smaller set, if all // > of the preceding identifiers are equal. - return compareValues(left.length, right.length); + return ts.compareValues(left.length, right.length); } /** @@ -171,7 +186,7 @@ namespace ts { private _alternatives: readonly (readonly Comparator[])[]; constructor(spec: string) { - this._alternatives = spec ? Debug.checkDefined(parseRange(spec), "Invalid range spec.") : emptyArray; + this._alternatives = spec ? ts.Debug.checkDefined(parseRange(spec), "Invalid range spec.") : ts.emptyArray; } static tryParse(text: string) { @@ -185,7 +200,8 @@ namespace ts { } test(version: Version | string) { - if (typeof version === "string") version = new Version(version); + if (typeof version === "string") + version = new Version(version); return testDisjunction(version, this._alternatives); } @@ -234,18 +250,21 @@ namespace ts { function parseRange(text: string) { const alternatives: Comparator[][] = []; - for (let range of trimString(text).split(logicalOrRegExp)) { - if (!range) continue; + for (let range of ts.trimString(text).split(logicalOrRegExp)) { + if (!range) + continue; const comparators: Comparator[] = []; - range = trimString(range); + range = ts.trimString(range); const match = hyphenRegExp.exec(range); if (match) { - if (!parseHyphen(match[1], match[2], comparators)) return undefined; + if (!parseHyphen(match[1], match[2], comparators)) + return undefined; } else { for (const simple of range.split(whitespaceRegExp)) { - const match = rangeRegExp.exec(trimString(simple)); - if (!match || !parseComparator(match[1], match[2], comparators)) return undefined; + const match = rangeRegExp.exec(ts.trimString(simple)); + if (!match || !parseComparator(match[1], match[2], comparators)) + return undefined; } } alternatives.push(comparators); @@ -255,33 +274,30 @@ namespace ts { function parsePartial(text: string) { const match = partialRegExp.exec(text); - if (!match) return undefined; + if (!match) + return undefined; const [, major, minor = "*", patch = "*", prerelease, build] = match; - const version = new Version( - isWildcard(major) ? 0 : parseInt(major, 10), - isWildcard(major) || isWildcard(minor) ? 0 : parseInt(minor, 10), - isWildcard(major) || isWildcard(minor) || isWildcard(patch) ? 0 : parseInt(patch, 10), - prerelease, - build); + const version = new Version(isWildcard(major) ? 0 : parseInt(major, 10), isWildcard(major) || isWildcard(minor) ? 0 : parseInt(minor, 10), isWildcard(major) || isWildcard(minor) || isWildcard(patch) ? 0 : parseInt(patch, 10), prerelease, build); return { version, major, minor, patch }; } function parseHyphen(left: string, right: string, comparators: Comparator[]) { const leftResult = parsePartial(left); - if (!leftResult) return false; + if (!leftResult) + return false; const rightResult = parsePartial(right); - if (!rightResult) return false; + if (!rightResult) + return false; if (!isWildcard(leftResult.major)) { comparators.push(createComparator(">=", leftResult.version)); } if (!isWildcard(rightResult.major)) { - comparators.push( - isWildcard(rightResult.minor) ? createComparator("<", rightResult.version.increment("major")) : + comparators.push(isWildcard(rightResult.minor) ? createComparator("<", rightResult.version.increment("major")) : isWildcard(rightResult.patch) ? createComparator("<", rightResult.version.increment("minor")) : createComparator("<=", rightResult.version)); } @@ -291,21 +307,20 @@ namespace ts { function parseComparator(operator: string, text: string, comparators: Comparator[]) { const result = parsePartial(text); - if (!result) return false; + if (!result) + return false; const { version, major, minor, patch } = result; if (!isWildcard(major)) { switch (operator) { case "~": comparators.push(createComparator(">=", version)); - comparators.push(createComparator("<", version.increment( - isWildcard(minor) ? "major" : + comparators.push(createComparator("<", version.increment(isWildcard(minor) ? "major" : "minor"))); break; case "^": comparators.push(createComparator(">=", version)); - comparators.push(createComparator("<", version.increment( - version.major > 0 || isWildcard(minor) ? "major" : + comparators.push(createComparator("<", version.increment(version.major > 0 || isWildcard(minor) ? "major" : version.minor > 0 || isWildcard(patch) ? "minor" : "patch"))); break; @@ -315,8 +330,7 @@ namespace ts { break; case "<=": case ">": - comparators.push( - isWildcard(minor) ? createComparator(operator === "<=" ? "<" : ">=", version.increment("major")) : + comparators.push(isWildcard(minor) ? createComparator(operator === "<=" ? "<" : ">=", version.increment("major")) : isWildcard(patch) ? createComparator(operator === "<=" ? "<" : ">=", version.increment("minor")) : createComparator(operator, version)); break; @@ -352,16 +366,19 @@ namespace ts { function testDisjunction(version: Version, alternatives: readonly (readonly Comparator[])[]) { // an empty disjunction is treated as "*" (all versions) - if (alternatives.length === 0) return true; + if (alternatives.length === 0) + return true; for (const alternative of alternatives) { - if (testAlternative(version, alternative)) return true; + if (testAlternative(version, alternative)) + return true; } return false; } function testAlternative(version: Version, comparators: readonly Comparator[]) { for (const comparator of comparators) { - if (!testComparator(version, comparator.operator, comparator.operand)) return false; + if (!testComparator(version, comparator.operator, comparator.operand)) + return false; } return true; } @@ -374,16 +391,16 @@ namespace ts { case ">": return cmp > 0; case ">=": return cmp >= 0; case "=": return cmp === 0; - default: return Debug.assertNever(operator); + default: return ts.Debug.assertNever(operator); } } function formatDisjunction(alternatives: readonly (readonly Comparator[])[]) { - return map(alternatives, formatAlternative).join(" || ") || "*"; + return ts.map(alternatives, formatAlternative).join(" || ") || "*"; } function formatAlternative(comparators: readonly Comparator[]) { - return map(comparators, formatComparator).join(" "); + return ts.map(comparators, formatComparator).join(" "); } function formatComparator(comparator: Comparator) { diff --git a/src/compiler/sourcemap.ts b/src/compiler/sourcemap.ts index e3aebc849b6a3..21168a764acfc 100644 --- a/src/compiler/sourcemap.ts +++ b/src/compiler/sourcemap.ts @@ -4,19 +4,19 @@ namespace ts { extendedDiagnostics?: boolean; } - export function createSourceMapGenerator(host: EmitHost, file: string, sourceRoot: string, sourcesDirectoryPath: string, generatorOptions: SourceMapGeneratorOptions): SourceMapGenerator { + export function createSourceMapGenerator(host: ts.EmitHost, file: string, sourceRoot: string, sourcesDirectoryPath: string, generatorOptions: SourceMapGeneratorOptions): ts.SourceMapGenerator { const { enter, exit } = generatorOptions.extendedDiagnostics - ? performance.createTimer("Source Map", "beforeSourcemap", "afterSourcemap") - : performance.nullTimer; + ? ts.performance.createTimer("Source Map", "beforeSourcemap", "afterSourcemap") + : ts.performance.nullTimer; // Current source map file and its index in the sources list const rawSources: string[] = []; const sources: string[] = []; - const sourceToSourceIndexMap = new Map(); + const sourceToSourceIndexMap = new ts.Map(); let sourcesContent: (string | null)[] | undefined; const names: string[] = []; - let nameToNameIndexMap: ESMap | undefined; + let nameToNameIndexMap: ts.ESMap | undefined; const mappingCharCodes: number[] = []; let mappings = ""; @@ -52,10 +52,7 @@ namespace ts { function addSource(fileName: string) { enter(); - const source = getRelativePathToDirectoryOrUrl(sourcesDirectoryPath, - fileName, - host.getCurrentDirectory(), - host.getCanonicalFileName, + const source = ts.getRelativePathToDirectoryOrUrl(sourcesDirectoryPath, fileName, host.getCurrentDirectory(), host.getCanonicalFileName, /*isAbsolutePathAnUrl*/ true); let sourceIndex = sourceToSourceIndexMap.get(source); @@ -73,7 +70,8 @@ namespace ts { function setSourceContent(sourceIndex: number, content: string | null) { enter(); if (content !== null) { - if (!sourcesContent) sourcesContent = []; + if (!sourcesContent) + sourcesContent = []; while (sourcesContent.length < sourceIndex) { sourcesContent.push(null); } @@ -85,7 +83,8 @@ namespace ts { function addName(name: string) { enter(); - if (!nameToNameIndexMap) nameToNameIndexMap = new Map(); + if (!nameToNameIndexMap) + nameToNameIndexMap = new ts.Map(); let nameIndex = nameToNameIndexMap.get(name); if (nameIndex === undefined) { nameIndex = names.length; @@ -112,11 +111,11 @@ namespace ts { } function addMapping(generatedLine: number, generatedCharacter: number, sourceIndex?: number, sourceLine?: number, sourceCharacter?: number, nameIndex?: number) { - Debug.assert(generatedLine >= pendingGeneratedLine, "generatedLine cannot backtrack"); - Debug.assert(generatedCharacter >= 0, "generatedCharacter cannot be negative"); - Debug.assert(sourceIndex === undefined || sourceIndex >= 0, "sourceIndex cannot be negative"); - Debug.assert(sourceLine === undefined || sourceLine >= 0, "sourceLine cannot be negative"); - Debug.assert(sourceCharacter === undefined || sourceCharacter >= 0, "sourceCharacter cannot be negative"); + ts.Debug.assert(generatedLine >= pendingGeneratedLine, "generatedLine cannot backtrack"); + ts.Debug.assert(generatedCharacter >= 0, "generatedCharacter cannot be negative"); + ts.Debug.assert(sourceIndex === undefined || sourceIndex >= 0, "sourceIndex cannot be negative"); + ts.Debug.assert(sourceLine === undefined || sourceLine >= 0, "sourceLine cannot be negative"); + ts.Debug.assert(sourceCharacter === undefined || sourceCharacter >= 0, "sourceCharacter cannot be negative"); enter(); // If this location wasn't recorded or the location in source is going backwards, record the mapping if (isNewGeneratedPosition(generatedLine, generatedCharacter) || @@ -142,9 +141,9 @@ namespace ts { exit(); } - function appendSourceMap(generatedLine: number, generatedCharacter: number, map: RawSourceMap, sourceMapPath: string, start?: LineAndCharacter, end?: LineAndCharacter) { - Debug.assert(generatedLine >= pendingGeneratedLine, "generatedLine cannot backtrack"); - Debug.assert(generatedCharacter >= 0, "generatedCharacter cannot be negative"); + function appendSourceMap(generatedLine: number, generatedCharacter: number, map: ts.RawSourceMap, sourceMapPath: string, start?: ts.LineAndCharacter, end?: ts.LineAndCharacter) { + ts.Debug.assert(generatedLine >= pendingGeneratedLine, "generatedLine cannot backtrack"); + ts.Debug.assert(generatedCharacter >= 0, "generatedCharacter cannot be negative"); enter(); // First, decode the old component sourcemap const sourceIndexToNewSourceIndexMap: number[] = []; @@ -152,14 +151,12 @@ namespace ts { const mappingIterator = decodeMappings(map.mappings); for (let iterResult = mappingIterator.next(); !iterResult.done; iterResult = mappingIterator.next()) { const raw = iterResult.value; - if (end && ( - raw.generatedLine > end.line || + if (end && (raw.generatedLine > end.line || (raw.generatedLine === end.line && raw.generatedCharacter > end.character))) { break; } - if (start && ( - raw.generatedLine < start.line || + if (start && (raw.generatedLine < start.line || (start.line === raw.generatedLine && raw.generatedCharacter < start.character))) { continue; } @@ -173,8 +170,8 @@ namespace ts { if (newSourceIndex === undefined) { // Apply offsets to each position and fixup source entries const rawPath = map.sources[raw.sourceIndex]; - const relativePath = map.sourceRoot ? combinePaths(map.sourceRoot, rawPath) : rawPath; - const combinedPath = combinePaths(getDirectoryPath(sourceMapPath), relativePath); + const relativePath = map.sourceRoot ? ts.combinePaths(map.sourceRoot, rawPath) : rawPath; + const combinedPath = ts.combinePaths(ts.getDirectoryPath(sourceMapPath), relativePath); sourceIndexToNewSourceIndexMap[raw.sourceIndex] = newSourceIndex = addSource(combinedPath); if (map.sourcesContent && typeof map.sourcesContent[raw.sourceIndex] === "string") { setSourceContent(newSourceIndex, map.sourcesContent[raw.sourceIndex]); @@ -184,7 +181,8 @@ namespace ts { newSourceLine = raw.sourceLine; newSourceCharacter = raw.sourceCharacter; if (map.names && raw.nameIndex !== undefined) { - if (!nameIndexToNewNameIndexMap) nameIndexToNewNameIndexMap = []; + if (!nameIndexToNewNameIndexMap) + nameIndexToNewNameIndexMap = []; newNameIndex = nameIndexToNewNameIndexMap[raw.nameIndex]; if (newNameIndex === undefined) { nameIndexToNewNameIndexMap[raw.nameIndex] = newNameIndex = addName(map.names[raw.nameIndex]); @@ -231,18 +229,17 @@ namespace ts { if (lastGeneratedLine < pendingGeneratedLine) { // Emit line delimiters do { - appendMappingCharCode(CharacterCodes.semicolon); + appendMappingCharCode(ts.CharacterCodes.semicolon); lastGeneratedLine++; - } - while (lastGeneratedLine < pendingGeneratedLine); + } while (lastGeneratedLine < pendingGeneratedLine); // Only need to set this once lastGeneratedCharacter = 0; } else { - Debug.assertEqual(lastGeneratedLine, pendingGeneratedLine, "generatedLine cannot backtrack"); + ts.Debug.assertEqual(lastGeneratedLine, pendingGeneratedLine, "generatedLine cannot backtrack"); // Emit comma to separate the entry if (hasLast) { - appendMappingCharCode(CharacterCodes.comma); + appendMappingCharCode(ts.CharacterCodes.comma); } } @@ -281,7 +278,7 @@ namespace ts { } } - function toJSON(): RawSourceMap { + function toJSON(): ts.RawSourceMap { commitPendingMapping(); flushMappingBuffer(); return { @@ -346,7 +343,7 @@ namespace ts { const line = lineInfo.getLineText(index); const comment = sourceMapCommentRegExp.exec(line); if (comment) { - return trimStringEnd(comment[1]); + return ts.trimStringEnd(comment[1]); } // If we see a non-whitespace/map comment-like line, break, to avoid scanning up the entire file else if (!line.match(whitespaceOrMapCommentRegExp)) { @@ -360,16 +357,16 @@ namespace ts { return typeof x === "string" || x === null; } - export function isRawSourceMap(x: any): x is RawSourceMap { + export function isRawSourceMap(x: any): x is ts.RawSourceMap { return x !== null && typeof x === "object" && x.version === 3 && typeof x.file === "string" && typeof x.mappings === "string" - && isArray(x.sources) && every(x.sources, isString) + && ts.isArray(x.sources) && ts.every(x.sources, ts.isString) && (x.sourceRoot === undefined || x.sourceRoot === null || typeof x.sourceRoot === "string") - && (x.sourcesContent === undefined || x.sourcesContent === null || isArray(x.sourcesContent) && every(x.sourcesContent, isStringOrNull)) - && (x.names === undefined || x.names === null || isArray(x.names) && every(x.names, isString)); + && (x.sourcesContent === undefined || x.sourcesContent === null || ts.isArray(x.sourcesContent) && ts.every(x.sourcesContent, isStringOrNull)) + && (x.names === undefined || x.names === null || ts.isArray(x.names) && ts.every(x.names, ts.isString)); } /* eslint-enable no-null/no-null */ @@ -387,7 +384,7 @@ namespace ts { return undefined; } - export interface MappingsDecoder extends Iterator { + export interface MappingsDecoder extends ts.Iterator { readonly pos: number; readonly error: string | undefined; readonly state: Required; @@ -426,7 +423,7 @@ namespace ts { next() { while (!done && pos < mappings.length) { const ch = mappings.charCodeAt(pos); - if (ch === CharacterCodes.semicolon) { + if (ch === ts.CharacterCodes.semicolon) { // new line generatedLine++; generatedCharacter = 0; @@ -434,7 +431,7 @@ namespace ts { continue; } - if (ch === CharacterCodes.comma) { + if (ch === ts.CharacterCodes.comma) { // Next entry is on same line - no action needed pos++; continue; @@ -444,33 +441,45 @@ namespace ts { let hasName = false; generatedCharacter += base64VLQFormatDecode(); - if (hasReportedError()) return stopIterating(); - if (generatedCharacter < 0) return setErrorAndStopIterating("Invalid generatedCharacter found"); + if (hasReportedError()) + return stopIterating(); + if (generatedCharacter < 0) + return setErrorAndStopIterating("Invalid generatedCharacter found"); if (!isSourceMappingSegmentEnd()) { hasSource = true; sourceIndex += base64VLQFormatDecode(); - if (hasReportedError()) return stopIterating(); - if (sourceIndex < 0) return setErrorAndStopIterating("Invalid sourceIndex found"); - if (isSourceMappingSegmentEnd()) return setErrorAndStopIterating("Unsupported Format: No entries after sourceIndex"); + if (hasReportedError()) + return stopIterating(); + if (sourceIndex < 0) + return setErrorAndStopIterating("Invalid sourceIndex found"); + if (isSourceMappingSegmentEnd()) + return setErrorAndStopIterating("Unsupported Format: No entries after sourceIndex"); sourceLine += base64VLQFormatDecode(); - if (hasReportedError()) return stopIterating(); - if (sourceLine < 0) return setErrorAndStopIterating("Invalid sourceLine found"); - if (isSourceMappingSegmentEnd()) return setErrorAndStopIterating("Unsupported Format: No entries after sourceLine"); + if (hasReportedError()) + return stopIterating(); + if (sourceLine < 0) + return setErrorAndStopIterating("Invalid sourceLine found"); + if (isSourceMappingSegmentEnd()) + return setErrorAndStopIterating("Unsupported Format: No entries after sourceLine"); sourceCharacter += base64VLQFormatDecode(); - if (hasReportedError()) return stopIterating(); - if (sourceCharacter < 0) return setErrorAndStopIterating("Invalid sourceCharacter found"); + if (hasReportedError()) + return stopIterating(); + if (sourceCharacter < 0) + return setErrorAndStopIterating("Invalid sourceCharacter found"); if (!isSourceMappingSegmentEnd()) { hasName = true; nameIndex += base64VLQFormatDecode(); - if (hasReportedError()) return stopIterating(); - if (nameIndex < 0) return setErrorAndStopIterating("Invalid nameIndex found"); - - if (!isSourceMappingSegmentEnd()) return setErrorAndStopIterating("Unsupported Error Format: Entries after nameIndex"); + if (hasReportedError()) + return stopIterating(); + if (nameIndex < 0) + return setErrorAndStopIterating("Invalid nameIndex found"); + if (!isSourceMappingSegmentEnd()) + return setErrorAndStopIterating("Unsupported Error Format: Entries after nameIndex"); } } @@ -494,7 +503,10 @@ namespace ts { }; } - function stopIterating(): { value: never, done: true } { + function stopIterating(): { + value: never; + done: true; + } { done = true; return { value: undefined!, done: true }; } @@ -516,8 +528,8 @@ namespace ts { function isSourceMappingSegmentEnd() { return (pos === mappings.length || - mappings.charCodeAt(pos) === CharacterCodes.comma || - mappings.charCodeAt(pos) === CharacterCodes.semicolon); + mappings.charCodeAt(pos) === ts.CharacterCodes.comma || + mappings.charCodeAt(pos) === ts.CharacterCodes.semicolon); } function base64VLQFormatDecode(): number { @@ -526,11 +538,13 @@ namespace ts { let value = 0; for (; moreDigits; pos++) { - if (pos >= mappings.length) return setError("Error in decoding base64VLQFormatDecode, past the mapping string"), -1; + if (pos >= mappings.length) + return setError("Error in decoding base64VLQFormatDecode, past the mapping string"), -1; // 6 digit number const currentByte = base64FormatDecode(mappings.charCodeAt(pos)); - if (currentByte === -1) return setError("Invalid character in VLQ"), -1; + if (currentByte === -1) + return setError("Invalid character in VLQ"), -1; // If msb is set, we still have more bits to continue moreDigits = (currentByte & 32) !== 0; @@ -572,20 +586,20 @@ namespace ts { } function base64FormatEncode(value: number) { - return value >= 0 && value < 26 ? CharacterCodes.A + value : - value >= 26 && value < 52 ? CharacterCodes.a + value - 26 : - value >= 52 && value < 62 ? CharacterCodes._0 + value - 52 : - value === 62 ? CharacterCodes.plus : - value === 63 ? CharacterCodes.slash : - Debug.fail(`${value}: not a base64 value`); + return value >= 0 && value < 26 ? ts.CharacterCodes.A + value : + value >= 26 && value < 52 ? ts.CharacterCodes.a + value - 26 : + value >= 52 && value < 62 ? ts.CharacterCodes._0 + value - 52 : + value === 62 ? ts.CharacterCodes.plus : + value === 63 ? ts.CharacterCodes.slash : + ts.Debug.fail(`${value}: not a base64 value`); } function base64FormatDecode(ch: number) { - return ch >= CharacterCodes.A && ch <= CharacterCodes.Z ? ch - CharacterCodes.A : - ch >= CharacterCodes.a && ch <= CharacterCodes.z ? ch - CharacterCodes.a + 26 : - ch >= CharacterCodes._0 && ch <= CharacterCodes._9 ? ch - CharacterCodes._0 + 52 : - ch === CharacterCodes.plus ? 62 : - ch === CharacterCodes.slash ? 63 : + return ch >= ts.CharacterCodes.A && ch <= ts.CharacterCodes.Z ? ch - ts.CharacterCodes.A : + ch >= ts.CharacterCodes.a && ch <= ts.CharacterCodes.z ? ch - ts.CharacterCodes.a + 26 : + ch >= ts.CharacterCodes._0 && ch <= ts.CharacterCodes._9 ? ch - ts.CharacterCodes._0 + 52 : + ch === ts.CharacterCodes.plus ? 62 : + ch === ts.CharacterCodes.slash ? 63 : -1; } @@ -617,12 +631,12 @@ namespace ts { function compareSourcePositions(left: SourceMappedPosition, right: SourceMappedPosition) { // Compares sourcePosition without comparing sourceIndex // since the mappings are grouped by sourceIndex - Debug.assert(left.sourceIndex === right.sourceIndex); - return compareValues(left.sourcePosition, right.sourcePosition); + ts.Debug.assert(left.sourceIndex === right.sourceIndex); + return ts.compareValues(left.sourcePosition, right.sourcePosition); } function compareGeneratedPositions(left: MappedPosition, right: MappedPosition) { - return compareValues(left.generatedPosition, right.generatedPosition); + return ts.compareValues(left.generatedPosition, right.generatedPosition); } function getSourcePositionOfMapping(value: SourceMappedPosition) { @@ -633,16 +647,16 @@ namespace ts { return value.generatedPosition; } - export function createDocumentPositionMapper(host: DocumentPositionMapperHost, map: RawSourceMap, mapPath: string): DocumentPositionMapper { - const mapDirectory = getDirectoryPath(mapPath); - const sourceRoot = map.sourceRoot ? getNormalizedAbsolutePath(map.sourceRoot, mapDirectory) : mapDirectory; - const generatedAbsoluteFilePath = getNormalizedAbsolutePath(map.file, mapDirectory); + export function createDocumentPositionMapper(host: ts.DocumentPositionMapperHost, map: ts.RawSourceMap, mapPath: string): ts.DocumentPositionMapper { + const mapDirectory = ts.getDirectoryPath(mapPath); + const sourceRoot = map.sourceRoot ? ts.getNormalizedAbsolutePath(map.sourceRoot, mapDirectory) : mapDirectory; + const generatedAbsoluteFilePath = ts.getNormalizedAbsolutePath(map.file, mapDirectory); const generatedFile = host.getSourceFileLike(generatedAbsoluteFilePath); - const sourceFileAbsolutePaths = map.sources.map(source => getNormalizedAbsolutePath(source, sourceRoot)); - const sourceToSourceIndexMap = new Map(sourceFileAbsolutePaths.map((source, i) => [host.getCanonicalFileName(source), i])); + const sourceFileAbsolutePaths = map.sources.map(source => ts.getNormalizedAbsolutePath(source, sourceRoot)); + const sourceToSourceIndexMap = new ts.Map(sourceFileAbsolutePaths.map((source, i) => [host.getCanonicalFileName(source), i])); let decodedMappings: readonly MappedPosition[] | undefined; - let generatedMappings: SortedReadonlyArray | undefined; - let sourceMappings: readonly SortedReadonlyArray[] | undefined; + let generatedMappings: ts.SortedReadonlyArray | undefined; + let sourceMappings: readonly ts.SortedReadonlyArray[] | undefined; return { getSourcePosition, @@ -651,7 +665,7 @@ namespace ts { function processMapping(mapping: Mapping): MappedPosition { const generatedPosition = generatedFile !== undefined - ? getPositionOfLineAndCharacter(generatedFile, mapping.generatedLine, mapping.generatedCharacter, /*allowEdits*/ true) + ? ts.getPositionOfLineAndCharacter(generatedFile, mapping.generatedLine, mapping.generatedCharacter, /*allowEdits*/ true) : -1; let source: string | undefined; let sourcePosition: number | undefined; @@ -659,7 +673,7 @@ namespace ts { const sourceFile = host.getSourceFileLike(sourceFileAbsolutePaths[mapping.sourceIndex]); source = map.sources[mapping.sourceIndex]; sourcePosition = sourceFile !== undefined - ? getPositionOfLineAndCharacter(sourceFile, mapping.sourceLine, mapping.sourceCharacter, /*allowEdits*/ true) + ? ts.getPositionOfLineAndCharacter(sourceFile, mapping.sourceLine, mapping.sourceCharacter, /*allowEdits*/ true) : -1; } return { @@ -674,12 +688,12 @@ namespace ts { function getDecodedMappings() { if (decodedMappings === undefined) { const decoder = decodeMappings(map.mappings); - const mappings = arrayFrom(decoder, processMapping); + const mappings = ts.arrayFrom(decoder, processMapping); if (decoder.error !== undefined) { if (host.log) { host.log(`Encountered error while decoding sourcemap: ${decoder.error}`); } - decodedMappings = emptyArray; + decodedMappings = ts.emptyArray; } else { decodedMappings = mappings; @@ -692,12 +706,14 @@ namespace ts { if (sourceMappings === undefined) { const lists: SourceMappedPosition[][] = []; for (const mapping of getDecodedMappings()) { - if (!isSourceMappedPosition(mapping)) continue; + if (!isSourceMappedPosition(mapping)) + continue; let list = lists[mapping.sourceIndex]; - if (!list) lists[mapping.sourceIndex] = list = []; + if (!list) + lists[mapping.sourceIndex] = list = []; list.push(mapping); } - sourceMappings = lists.map(list => sortAndDeduplicate(list, compareSourcePositions, sameMappedPosition)); + sourceMappings = lists.map(list => ts.sortAndDeduplicate(list, compareSourcePositions, sameMappedPosition)); } return sourceMappings[sourceIndex]; } @@ -708,19 +724,20 @@ namespace ts { for (const mapping of getDecodedMappings()) { list.push(mapping); } - generatedMappings = sortAndDeduplicate(list, compareGeneratedPositions, sameMappedPosition); + generatedMappings = ts.sortAndDeduplicate(list, compareGeneratedPositions, sameMappedPosition); } return generatedMappings; } - function getGeneratedPosition(loc: DocumentPosition): DocumentPosition { + function getGeneratedPosition(loc: ts.DocumentPosition): ts.DocumentPosition { const sourceIndex = sourceToSourceIndexMap.get(host.getCanonicalFileName(loc.fileName)); - if (sourceIndex === undefined) return loc; + if (sourceIndex === undefined) + return loc; const sourceMappings = getSourceMappings(sourceIndex); - if (!some(sourceMappings)) return loc; - - let targetIndex = binarySearchKey(sourceMappings, loc.pos, getSourcePositionOfMapping, compareValues); + if (!ts.some(sourceMappings)) + return loc; + let targetIndex = ts.binarySearchKey(sourceMappings, loc.pos, getSourcePositionOfMapping, ts.compareValues); if (targetIndex < 0) { // if no exact match, closest is 2's complement of result targetIndex = ~targetIndex; @@ -734,11 +751,11 @@ namespace ts { return { fileName: generatedAbsoluteFilePath, pos: mapping.generatedPosition }; // Closest pos } - function getSourcePosition(loc: DocumentPosition): DocumentPosition { + function getSourcePosition(loc: ts.DocumentPosition): ts.DocumentPosition { const generatedMappings = getGeneratedMappings(); - if (!some(generatedMappings)) return loc; - - let targetIndex = binarySearchKey(generatedMappings, loc.pos, getGeneratedPositionOfMapping, compareValues); + if (!ts.some(generatedMappings)) + return loc; + let targetIndex = ts.binarySearchKey(generatedMappings, loc.pos, getGeneratedPositionOfMapping, ts.compareValues); if (targetIndex < 0) { // if no exact match, closest is 2's complement of result targetIndex = ~targetIndex; @@ -753,8 +770,8 @@ namespace ts { } } - export const identitySourceMapConsumer: DocumentPositionMapper = { - getSourcePosition: identity, - getGeneratedPosition: identity + export const identitySourceMapConsumer: ts.DocumentPositionMapper = { + getSourcePosition: ts.identity, + getGeneratedPosition: ts.identity }; } diff --git a/src/compiler/symbolWalker.ts b/src/compiler/symbolWalker.ts index 4130d7fc84f9e..af933f038e7f8 100644 --- a/src/compiler/symbolWalker.ts +++ b/src/compiler/symbolWalker.ts @@ -1,47 +1,37 @@ /** @internal */ namespace ts { - export function createGetSymbolWalker( - getRestTypeOfSignature: (sig: Signature) => Type, - getTypePredicateOfSignature: (sig: Signature) => TypePredicate | undefined, - getReturnTypeOfSignature: (sig: Signature) => Type, - getBaseTypes: (type: Type) => Type[], - resolveStructuredTypeMembers: (type: ObjectType) => ResolvedType, - getTypeOfSymbol: (sym: Symbol) => Type, - getResolvedSymbol: (node: Node) => Symbol, - getConstraintOfTypeParameter: (typeParameter: TypeParameter) => Type | undefined, - getFirstIdentifier: (node: EntityNameOrEntityNameExpression) => Identifier, - getTypeArguments: (type: TypeReference) => readonly Type[]) { + export function createGetSymbolWalker(getRestTypeOfSignature: (sig: ts.Signature) => ts.Type, getTypePredicateOfSignature: (sig: ts.Signature) => ts.TypePredicate | undefined, getReturnTypeOfSignature: (sig: ts.Signature) => ts.Type, getBaseTypes: (type: ts.Type) => ts.Type[], resolveStructuredTypeMembers: (type: ts.ObjectType) => ts.ResolvedType, getTypeOfSymbol: (sym: ts.Symbol) => ts.Type, getResolvedSymbol: (node: ts.Node) => ts.Symbol, getConstraintOfTypeParameter: (typeParameter: ts.TypeParameter) => ts.Type | undefined, getFirstIdentifier: (node: ts.EntityNameOrEntityNameExpression) => ts.Identifier, getTypeArguments: (type: ts.TypeReference) => readonly ts.Type[]) { return getSymbolWalker; - function getSymbolWalker(accept: (symbol: Symbol) => boolean = () => true): SymbolWalker { - const visitedTypes: Type[] = []; // Sparse array from id to type - const visitedSymbols: Symbol[] = []; // Sparse array from id to symbol + function getSymbolWalker(accept: (symbol: ts.Symbol) => boolean = () => true): ts.SymbolWalker { + const visitedTypes: ts.Type[] = []; // Sparse array from id to type + const visitedSymbols: ts.Symbol[] = []; // Sparse array from id to symbol return { walkType: type => { try { visitType(type); - return { visitedTypes: getOwnValues(visitedTypes), visitedSymbols: getOwnValues(visitedSymbols) }; + return { visitedTypes: ts.getOwnValues(visitedTypes), visitedSymbols: ts.getOwnValues(visitedSymbols) }; } finally { - clear(visitedTypes); - clear(visitedSymbols); + ts.clear(visitedTypes); + ts.clear(visitedSymbols); } }, walkSymbol: symbol => { try { visitSymbol(symbol); - return { visitedTypes: getOwnValues(visitedTypes), visitedSymbols: getOwnValues(visitedSymbols) }; + return { visitedTypes: ts.getOwnValues(visitedTypes), visitedSymbols: ts.getOwnValues(visitedSymbols) }; } finally { - clear(visitedTypes); - clear(visitedSymbols); + ts.clear(visitedTypes); + ts.clear(visitedSymbols); } }, }; - function visitType(type: Type | undefined): void { + function visitType(type: ts.Type | undefined): void { if (!type) { return; } @@ -54,75 +44,76 @@ namespace ts { // Reuse visitSymbol to visit the type's symbol, // but be sure to bail on recuring into the type if accept declines the symbol. const shouldBail = visitSymbol(type.symbol); - if (shouldBail) return; + if (shouldBail) + return; // Visit the type's related types, if any - if (type.flags & TypeFlags.Object) { - const objectType = type as ObjectType; + if (type.flags & ts.TypeFlags.Object) { + const objectType = type as ts.ObjectType; const objectFlags = objectType.objectFlags; - if (objectFlags & ObjectFlags.Reference) { - visitTypeReference(type as TypeReference); + if (objectFlags & ts.ObjectFlags.Reference) { + visitTypeReference(type as ts.TypeReference); } - if (objectFlags & ObjectFlags.Mapped) { - visitMappedType(type as MappedType); + if (objectFlags & ts.ObjectFlags.Mapped) { + visitMappedType(type as ts.MappedType); } - if (objectFlags & (ObjectFlags.Class | ObjectFlags.Interface)) { - visitInterfaceType(type as InterfaceType); + if (objectFlags & (ts.ObjectFlags.Class | ts.ObjectFlags.Interface)) { + visitInterfaceType(type as ts.InterfaceType); } - if (objectFlags & (ObjectFlags.Tuple | ObjectFlags.Anonymous)) { + if (objectFlags & (ts.ObjectFlags.Tuple | ts.ObjectFlags.Anonymous)) { visitObjectType(objectType); } } - if (type.flags & TypeFlags.TypeParameter) { - visitTypeParameter(type as TypeParameter); + if (type.flags & ts.TypeFlags.TypeParameter) { + visitTypeParameter(type as ts.TypeParameter); } - if (type.flags & TypeFlags.UnionOrIntersection) { - visitUnionOrIntersectionType(type as UnionOrIntersectionType); + if (type.flags & ts.TypeFlags.UnionOrIntersection) { + visitUnionOrIntersectionType(type as ts.UnionOrIntersectionType); } - if (type.flags & TypeFlags.Index) { - visitIndexType(type as IndexType); + if (type.flags & ts.TypeFlags.Index) { + visitIndexType(type as ts.IndexType); } - if (type.flags & TypeFlags.IndexedAccess) { - visitIndexedAccessType(type as IndexedAccessType); + if (type.flags & ts.TypeFlags.IndexedAccess) { + visitIndexedAccessType(type as ts.IndexedAccessType); } } - function visitTypeReference(type: TypeReference): void { + function visitTypeReference(type: ts.TypeReference): void { visitType(type.target); - forEach(getTypeArguments(type), visitType); + ts.forEach(getTypeArguments(type), visitType); } - function visitTypeParameter(type: TypeParameter): void { + function visitTypeParameter(type: ts.TypeParameter): void { visitType(getConstraintOfTypeParameter(type)); } - function visitUnionOrIntersectionType(type: UnionOrIntersectionType): void { - forEach(type.types, visitType); + function visitUnionOrIntersectionType(type: ts.UnionOrIntersectionType): void { + ts.forEach(type.types, visitType); } - function visitIndexType(type: IndexType): void { + function visitIndexType(type: ts.IndexType): void { visitType(type.type); } - function visitIndexedAccessType(type: IndexedAccessType): void { + function visitIndexedAccessType(type: ts.IndexedAccessType): void { visitType(type.objectType); visitType(type.indexType); visitType(type.constraint); } - function visitMappedType(type: MappedType): void { + function visitMappedType(type: ts.MappedType): void { visitType(type.typeParameter); visitType(type.constraintType); visitType(type.templateType); visitType(type.modifiersType); } - function visitSignature(signature: Signature): void { + function visitSignature(signature: ts.Signature): void { const typePredicate = getTypePredicateOfSignature(signature); if (typePredicate) { visitType(typePredicate.type); } - forEach(signature.typeParameters, visitType); + ts.forEach(signature.typeParameters, visitType); for (const parameter of signature.parameters) { visitSymbol(parameter); @@ -131,14 +122,14 @@ namespace ts { visitType(getReturnTypeOfSignature(signature)); } - function visitInterfaceType(interfaceT: InterfaceType): void { + function visitInterfaceType(interfaceT: ts.InterfaceType): void { visitObjectType(interfaceT); - forEach(interfaceT.typeParameters, visitType); - forEach(getBaseTypes(interfaceT), visitType); + ts.forEach(interfaceT.typeParameters, visitType); + ts.forEach(getBaseTypes(interfaceT), visitType); visitType(interfaceT.thisType); } - function visitObjectType(type: ObjectType): void { + function visitObjectType(type: ts.ObjectType): void { const resolved = resolveStructuredTypeMembers(type); for (const info of resolved.indexInfos) { visitType(info.keyType); @@ -155,11 +146,11 @@ namespace ts { } } - function visitSymbol(symbol: Symbol | undefined): boolean { + function visitSymbol(symbol: ts.Symbol | undefined): boolean { if (!symbol) { return false; } - const symbolId = getSymbolId(symbol); + const symbolId = ts.getSymbolId(symbol); if (visitedSymbols[symbolId]) { return false; } @@ -172,13 +163,13 @@ namespace ts { if (symbol.exports) { symbol.exports.forEach(visitSymbol); } - forEach(symbol.declarations, d => { + ts.forEach(symbol.declarations, d => { // Type queries are too far resolved when we just visit the symbol's type // (their type resolved directly to the member deeply referenced) // So to get the intervening symbols, we need to check if there's a type // query node on any of the symbol's declarations and get symbols there - if ((d as any).type && (d as any).type.kind === SyntaxKind.TypeQuery) { - const query = (d as any).type as TypeQueryNode; + if ((d as any).type && (d as any).type.kind === ts.SyntaxKind.TypeQuery) { + const query = (d as any).type as ts.TypeQueryNode; const entity = getResolvedSymbol(getFirstIdentifier(query.exprName)); visitSymbol(entity); } diff --git a/src/compiler/sys.ts b/src/compiler/sys.ts index 6cdcc6a26b9e4..ffaf2e92b50bb 100644 --- a/src/compiler/sys.ts +++ b/src/compiler/sys.ts @@ -50,15 +50,17 @@ namespace ts { } /* @internal */ - export type HostWatchFile = (fileName: string, callback: FileWatcherCallback, pollingInterval: PollingInterval, options: WatchOptions | undefined) => FileWatcher; + export type HostWatchFile = (fileName: string, callback: FileWatcherCallback, pollingInterval: PollingInterval, options: ts.WatchOptions | undefined) => FileWatcher; /* @internal */ - export type HostWatchDirectory = (fileName: string, callback: DirectoryWatcherCallback, recursive: boolean, options: WatchOptions | undefined) => FileWatcher; + export type HostWatchDirectory = (fileName: string, callback: DirectoryWatcherCallback, recursive: boolean, options: ts.WatchOptions | undefined) => FileWatcher; /* @internal */ export const missingFileModifiedTime = new Date(0); // Any subsequent modification will occur after this time /* @internal */ - export function getModifiedTime(host: { getModifiedTime: NonNullable; }, fileName: string) { + export function getModifiedTime(host: { + getModifiedTime: NonNullable; + }, fileName: string) { return host.getModifiedTime(fileName) || missingFileModifiedTime; } @@ -134,12 +136,9 @@ namespace ts { interface WatchedFileWithIsClosed extends WatchedFile { isClosed?: boolean; } - function pollWatchedFileQueue( - host: { getModifiedTime: NonNullable; }, - queue: (T | undefined)[], - pollIndex: number, chunkSize: number, - callbackOnWatchFileStat?: (watchedFile: T, pollIndex: number, fileChanged: boolean) => void - ) { + function pollWatchedFileQueue(host: { + getModifiedTime: NonNullable; + }, queue: (T | undefined)[], pollIndex: number, chunkSize: number, callbackOnWatchFileStat?: (watchedFile: T, pollIndex: number, fileChanged: boolean) => void) { let definedValueCopyToIndex = pollIndex; // Max visit would be all elements of the queue for (let canVisit = queue.length; chunkSize && canVisit; nextPollIndex(), canVisit--) { @@ -226,7 +225,7 @@ namespace ts { close: () => { file.isClosed = true; // Remove from watchedFiles - unorderedRemoveItem(watchedFiles, file); + ts.unorderedRemoveItem(watchedFiles, file); // Do not update polling interval queue since that will happen as part of polling } }; @@ -247,7 +246,7 @@ namespace ts { scheduleNextPoll(queue.pollingInterval); } else { - Debug.assert(queue.pollIndex === 0); + ts.Debug.assert(queue.pollIndex === 0); queue.pollScheduled = false; } } @@ -266,13 +265,7 @@ namespace ts { } function pollQueue(queue: (WatchedFile | undefined)[], pollingInterval: PollingInterval, pollIndex: number, chunkSize: number) { - return pollWatchedFileQueue( - host, - queue, - pollIndex, - chunkSize, - onWatchFileStat - ); + return pollWatchedFileQueue(host, queue, pollIndex, chunkSize, onWatchFileStat); function onWatchFileStat(watchedFile: WatchedFile, pollIndex: number, fileChanged: boolean) { if (fileChanged) { @@ -334,17 +327,17 @@ namespace ts { function createUseFsEventsOnParentDirectoryWatchFile(fsWatch: FsWatch, useCaseSensitiveFileNames: boolean): HostWatchFile { // One file can have multiple watchers - const fileWatcherCallbacks = createMultiMap(); - const dirWatchers = new Map(); - const toCanonicalName = createGetCanonicalFileName(useCaseSensitiveFileNames); + const fileWatcherCallbacks = ts.createMultiMap(); + const dirWatchers = new ts.Map(); + const toCanonicalName = ts.createGetCanonicalFileName(useCaseSensitiveFileNames); return nonPollingWatchFile; - function nonPollingWatchFile(fileName: string, callback: FileWatcherCallback, _pollingInterval: PollingInterval, fallbackOptions: WatchOptions | undefined): FileWatcher { + function nonPollingWatchFile(fileName: string, callback: FileWatcherCallback, _pollingInterval: PollingInterval, fallbackOptions: ts.WatchOptions | undefined): FileWatcher { const filePath = toCanonicalName(fileName); fileWatcherCallbacks.add(filePath, callback); - const dirPath = getDirectoryPath(filePath) || "."; + const dirPath = ts.getDirectoryPath(filePath) || "."; const watcher = dirWatchers.get(dirPath) || - createDirectoryWatcher(getDirectoryPath(fileName) || ".", dirPath, fallbackOptions); + createDirectoryWatcher(ts.getDirectoryPath(fileName) || ".", dirPath, fallbackOptions); watcher.referenceCount++; return { close: () => { @@ -360,14 +353,12 @@ namespace ts { }; } - function createDirectoryWatcher(dirName: string, dirPath: string, fallbackOptions: WatchOptions | undefined) { - const watcher = fsWatch( - dirName, - FileSystemEntryKind.Directory, - (_eventName: string, relativeFileName) => { + function createDirectoryWatcher(dirName: string, dirPath: string, fallbackOptions: ts.WatchOptions | undefined) { + const watcher = fsWatch(dirName, FileSystemEntryKind.Directory, (_eventName: string, relativeFileName) => { // When files are deleted from disk, the triggered "rename" event would have a relativefileName of "undefined" - if (!isString(relativeFileName)) return; - const fileName = getNormalizedAbsolutePath(relativeFileName, dirName); + if (!ts.isString(relativeFileName)) + return; + const fileName = ts.getNormalizedAbsolutePath(relativeFileName, dirName); // Some applications save a working file via rename operations const callbacks = fileName && fileWatcherCallbacks.get(toCanonicalName(fileName)); if (callbacks) { @@ -376,10 +367,7 @@ namespace ts { } } }, - /*recursive*/ false, - PollingInterval.Medium, - fallbackOptions - ) as DirectoryWatcher; + /*recursive*/ false, PollingInterval.Medium, fallbackOptions) as DirectoryWatcher; watcher.referenceCount = 0; dirWatchers.set(dirPath, watcher); return watcher; @@ -406,7 +394,7 @@ namespace ts { return { close: () => { file.isClosed = true; - unorderedRemoveItem(watchedFiles, file); + ts.unorderedRemoveItem(watchedFiles, file); } }; } @@ -418,23 +406,21 @@ namespace ts { } function scheduleNextPoll() { - if (!watchedFiles.length || pollScheduled) return; + if (!watchedFiles.length || pollScheduled) + return; pollScheduled = host.setTimeout(pollQueue, PollingInterval.High); } } /* @internal */ - export function createSingleFileWatcherPerName( - watchFile: HostWatchFile, - useCaseSensitiveFileNames: boolean - ): HostWatchFile { + export function createSingleFileWatcherPerName(watchFile: HostWatchFile, useCaseSensitiveFileNames: boolean): HostWatchFile { interface SingleFileWatcher { watcher: FileWatcher; refCount: number; } - const cache = new Map(); - const callbacksCache = createMultiMap(); - const toCanonicalFileName = createGetCanonicalFileName(useCaseSensitiveFileNames); + const cache = new ts.Map(); + const callbacksCache = ts.createMultiMap(); + const toCanonicalFileName = ts.createGetCanonicalFileName(useCaseSensitiveFileNames); return (fileName, callback, pollingInterval, options) => { const path = toCanonicalFileName(fileName); @@ -444,15 +430,7 @@ namespace ts { } else { cache.set(path, { - watcher: watchFile( - fileName, - (fileName, eventKind) => forEach( - callbacksCache.get(path), - cb => cb(fileName, eventKind) - ), - pollingInterval, - options - ), + watcher: watchFile(fileName, (fileName, eventKind) => ts.forEach(callbacksCache.get(path), cb => cb(fileName, eventKind)), pollingInterval, options), refCount: 1 }); } @@ -460,12 +438,13 @@ namespace ts { return { close: () => { - const watcher = Debug.checkDefined(cache.get(path)); + const watcher = ts.Debug.checkDefined(cache.get(path)); callbacksCache.remove(path, callback); watcher.refCount--; - if (watcher.refCount) return; + if (watcher.refCount) + return; cache.delete(path); - closeFileWatcherOf(watcher); + ts.closeFileWatcherOf(watcher); } }; }; @@ -499,7 +478,7 @@ namespace ts { /*@internal*/ export const ignoredPaths = ["/node_modules/.", "/.git", "/.#"]; - let curSysLog: (s: string) => void = noop; // eslint-disable-line prefer-const + let curSysLog: (s: string) => void = ts.noop; // eslint-disable-line prefer-const /*@internal*/ export function sysLog(s: string) { @@ -529,16 +508,7 @@ namespace ts { * (eg on OS that dont support recursive watch using fs.watch use fs.watchFile) */ /*@internal*/ - export function createDirectoryWatcherSupportingRecursive({ - watchDirectory, - useCaseSensitiveFileNames, - getCurrentDirectory, - getAccessibleSortedChildDirectories, - directoryExists, - realpath, - setTimeout, - clearTimeout - }: RecursiveDirectoryWatcherHost): HostWatchDirectory { + export function createDirectoryWatcherSupportingRecursive({ watchDirectory, useCaseSensitiveFileNames, getCurrentDirectory, getAccessibleSortedChildDirectories, directoryExists, realpath, setTimeout, clearTimeout }: RecursiveDirectoryWatcherHost): HostWatchDirectory { interface ChildDirectoryWatcher extends FileWatcher { dirName: string; } @@ -549,13 +519,20 @@ namespace ts { refCount: number; } - const cache = new Map(); - const callbackCache = createMultiMap(); - const cacheToUpdateChildWatches = new Map(); + const cache = new ts.Map(); + const callbackCache = ts.createMultiMap(); + const cacheToUpdateChildWatches = new ts.Map(); let timerToUpdateChildWatches: any; - const filePathComparer = getStringComparer(!useCaseSensitiveFileNames); - const toCanonicalFilePath = createGetCanonicalFileName(useCaseSensitiveFileNames); + const filePathComparer = ts.getStringComparer(!useCaseSensitiveFileNames); + const toCanonicalFilePath = ts.createGetCanonicalFileName(useCaseSensitiveFileNames); return (dirName, callback, recursive, options) => recursive ? createDirectoryWatcher(dirName, options, callback) : @@ -564,8 +541,8 @@ namespace ts { /** * Create the directory watcher for the dirPath. */ - function createDirectoryWatcher(dirName: string, options: WatchOptions | undefined, callback?: DirectoryWatcherCallback): ChildDirectoryWatcher { - const dirPath = toCanonicalFilePath(dirName) as Path; + function createDirectoryWatcher(dirName: string, options: ts.WatchOptions | undefined, callback?: DirectoryWatcherCallback): ChildDirectoryWatcher { + const dirPath = toCanonicalFilePath(dirName) as ts.Path; let directoryWatcher = cache.get(dirPath); if (directoryWatcher) { directoryWatcher.refCount++; @@ -573,7 +550,8 @@ namespace ts { else { directoryWatcher = { watcher: watchDirectory(dirName, fileName => { - if (isIgnoredPath(fileName, options)) return; + if (isIgnoredPath(fileName, options)) + return; if (options?.synchronousWatchDirectory) { // Call the actual callback @@ -587,7 +565,7 @@ namespace ts { } }, /*recursive*/ false, options), refCount: 1, - childWatches: emptyArray + childWatches: ts.emptyArray }; cache.set(dirPath, directoryWatcher); updateChildWatches(dirName, dirPath, options); @@ -601,26 +579,28 @@ namespace ts { return { dirName, close: () => { - const directoryWatcher = Debug.checkDefined(cache.get(dirPath)); - if (callbackToAdd) callbackCache.remove(dirPath, callbackToAdd); + const directoryWatcher = ts.Debug.checkDefined(cache.get(dirPath)); + if (callbackToAdd) + callbackCache.remove(dirPath, callbackToAdd); directoryWatcher.refCount--; - if (directoryWatcher.refCount) return; + if (directoryWatcher.refCount) + return; cache.delete(dirPath); - closeFileWatcherOf(directoryWatcher); - directoryWatcher.childWatches.forEach(closeFileWatcher); + ts.closeFileWatcherOf(directoryWatcher); + directoryWatcher.childWatches.forEach(ts.closeFileWatcher); } }; } - type InvokeMap = ESMap; - function invokeCallbacks(dirPath: Path, fileName: string): void; - function invokeCallbacks(dirPath: Path, invokeMap: InvokeMap, fileNames: string[] | undefined): void; - function invokeCallbacks(dirPath: Path, fileNameOrInvokeMap: string | InvokeMap, fileNames?: string[]) { + type InvokeMap = ts.ESMap; + function invokeCallbacks(dirPath: ts.Path, fileName: string): void; + function invokeCallbacks(dirPath: ts.Path, invokeMap: InvokeMap, fileNames: string[] | undefined): void; + function invokeCallbacks(dirPath: ts.Path, fileNameOrInvokeMap: string | InvokeMap, fileNames?: string[]) { let fileName: string | undefined; let invokeMap: InvokeMap | undefined; - if (isString(fileNameOrInvokeMap)) { + if (ts.isString(fileNameOrInvokeMap)) { fileName = fileNameOrInvokeMap; } else { @@ -628,8 +608,9 @@ namespace ts { } // Call the actual callback callbackCache.forEach((callbacks, rootDirName) => { - if (invokeMap && invokeMap.get(rootDirName) === true) return; - if (rootDirName === dirPath || (startsWith(dirPath, rootDirName) && dirPath[rootDirName.length] === directorySeparator)) { + if (invokeMap && invokeMap.get(rootDirName) === true) + return; + if (rootDirName === dirPath || (ts.startsWith(dirPath, rootDirName) && dirPath[rootDirName.length] === ts.directorySeparator)) { if (invokeMap) { if (fileNames) { const existing = invokeMap.get(rootDirName); @@ -651,7 +632,7 @@ namespace ts { }); } - function nonSyncUpdateChildWatches(dirName: string, dirPath: Path, fileName: string, options: WatchOptions | undefined) { + function nonSyncUpdateChildWatches(dirName: string, dirPath: ts.Path, fileName: string, options: ts.WatchOptions | undefined) { // Iterate through existing children and update the watches if needed const parentWatcher = cache.get(dirPath); if (parentWatcher && directoryExists(dirName)) { @@ -665,7 +646,7 @@ namespace ts { removeChildWatches(parentWatcher); } - function scheduleUpdateChildWatches(dirName: string, dirPath: Path, fileName: string, options: WatchOptions | undefined) { + function scheduleUpdateChildWatches(dirName: string, dirPath: ts.Path, fileName: string, options: ts.WatchOptions | undefined) { const existing = cacheToUpdateChildWatches.get(dirPath); if (existing) { existing.fileNames.push(fileName); @@ -683,12 +664,12 @@ namespace ts { function onTimerToUpdateChildWatches() { timerToUpdateChildWatches = undefined; sysLog(`sysLog:: onTimerToUpdateChildWatches:: ${cacheToUpdateChildWatches.size}`); - const start = timestamp(); - const invokeMap = new Map(); + const start = ts.timestamp(); + const invokeMap = new ts.Map(); while (!timerToUpdateChildWatches && cacheToUpdateChildWatches.size) { const result = cacheToUpdateChildWatches.entries().next(); - Debug.assert(!result.done); + ts.Debug.assert(!result.done); const { value: [dirPath, { dirName, options, fileNames }] } = result; cacheToUpdateChildWatches.delete(dirPath); // Because the child refresh is fresh, we would need to invalidate whole root directory being watched @@ -697,12 +678,12 @@ namespace ts { invokeCallbacks(dirPath, invokeMap, hasChanges ? undefined : fileNames); } - sysLog(`sysLog:: invokingWatchers:: Elapsed:: ${timestamp() - start}ms:: ${cacheToUpdateChildWatches.size}`); + sysLog(`sysLog:: invokingWatchers:: Elapsed:: ${ts.timestamp() - start}ms:: ${cacheToUpdateChildWatches.size}`); callbackCache.forEach((callbacks, rootDirName) => { const existing = invokeMap.get(rootDirName); if (existing) { callbacks.forEach(({ callback, dirName }) => { - if (isArray(existing)) { + if (ts.isArray(existing)) { existing.forEach(callback); } else { @@ -712,39 +693,34 @@ namespace ts { } }); - const elapsed = timestamp() - start; + const elapsed = ts.timestamp() - start; sysLog(`sysLog:: Elapsed:: ${elapsed}ms:: onTimerToUpdateChildWatches:: ${cacheToUpdateChildWatches.size} ${timerToUpdateChildWatches}`); } function removeChildWatches(parentWatcher: HostDirectoryWatcher | undefined) { - if (!parentWatcher) return; + if (!parentWatcher) + return; const existingChildWatches = parentWatcher.childWatches; - parentWatcher.childWatches = emptyArray; + parentWatcher.childWatches = ts.emptyArray; for (const childWatcher of existingChildWatches) { childWatcher.close(); removeChildWatches(cache.get(toCanonicalFilePath(childWatcher.dirName))); } } - function updateChildWatches(parentDir: string, parentDirPath: Path, options: WatchOptions | undefined) { + function updateChildWatches(parentDir: string, parentDirPath: ts.Path, options: ts.WatchOptions | undefined) { // Iterate through existing children and update the watches if needed const parentWatcher = cache.get(parentDirPath); - if (!parentWatcher) return false; + if (!parentWatcher) + return false; let newChildWatches: ChildDirectoryWatcher[] | undefined; - const hasChanges = enumerateInsertsAndDeletes( - directoryExists(parentDir) ? mapDefined(getAccessibleSortedChildDirectories(parentDir), child => { - const childFullName = getNormalizedAbsolutePath(child, parentDir); + const hasChanges = ts.enumerateInsertsAndDeletes(directoryExists(parentDir) ? ts.mapDefined(getAccessibleSortedChildDirectories(parentDir), child => { + const childFullName = ts.getNormalizedAbsolutePath(child, parentDir); // Filter our the symbolic link directories since those arent included in recursive watch // which is same behaviour when recursive: true is passed to fs.watch - return !isIgnoredPath(childFullName, options) && filePathComparer(childFullName, normalizePath(realpath(childFullName))) === Comparison.EqualTo ? childFullName : undefined; - }) : emptyArray, - parentWatcher.childWatches, - (child, childWatcher) => filePathComparer(child, childWatcher.dirName), - createAndAddChildDirectoryWatcher, - closeFileWatcher, - addChildDirectoryWatcher - ); - parentWatcher.childWatches = newChildWatches || emptyArray; + return !isIgnoredPath(childFullName, options) && filePathComparer(childFullName, ts.normalizePath(realpath(childFullName))) === ts.Comparison.EqualTo ? childFullName : undefined; + }) : ts.emptyArray, parentWatcher.childWatches, (child, childWatcher) => filePathComparer(child, childWatcher.dirName), createAndAddChildDirectoryWatcher, ts.closeFileWatcher, addChildDirectoryWatcher); + parentWatcher.childWatches = newChildWatches || ts.emptyArray; return hasChanges; /** @@ -763,27 +739,29 @@ namespace ts { } } - function isIgnoredPath(path: string, options: WatchOptions | undefined) { - return some(ignoredPaths, searchPath => isInPath(path, searchPath)) || + function isIgnoredPath(path: string, options: ts.WatchOptions | undefined) { + return ts.some(ignoredPaths, searchPath => isInPath(path, searchPath)) || isIgnoredByWatchOptions(path, options, useCaseSensitiveFileNames, getCurrentDirectory); } function isInPath(path: string, searchPath: string) { - if (stringContains(path, searchPath)) return true; - if (useCaseSensitiveFileNames) return false; - return stringContains(toCanonicalFilePath(path), searchPath); + if (ts.stringContains(path, searchPath)) + return true; + if (useCaseSensitiveFileNames) + return false; + return ts.stringContains(toCanonicalFilePath(path), searchPath); } } /*@internal*/ export type FsWatchCallback = (eventName: "rename" | "change", relativeFileName: string | undefined) => void; /*@internal*/ - export type FsWatch = (fileOrDirectory: string, entryKind: FileSystemEntryKind, callback: FsWatchCallback, recursive: boolean, fallbackPollingInterval: PollingInterval, fallbackOptions: WatchOptions | undefined) => FileWatcher; + export type FsWatch = (fileOrDirectory: string, entryKind: FileSystemEntryKind, callback: FsWatchCallback, recursive: boolean, fallbackPollingInterval: PollingInterval, fallbackOptions: ts.WatchOptions | undefined) => FileWatcher; /*@internal*/ export const enum FileSystemEntryKind { File, - Directory, + Directory } /*@internal*/ @@ -791,11 +769,7 @@ namespace ts { return (_fileName, eventKind) => callback(eventKind === FileWatcherEventKind.Changed ? "change" : "rename", ""); } - function createFsWatchCallbackForFileWatcherCallback( - fileName: string, - callback: FileWatcherCallback, - fileExists: System["fileExists"] - ): FsWatchCallback { + function createFsWatchCallbackForFileWatcherCallback(fileName: string, callback: FileWatcherCallback, fileExists: System["fileExists"]): FsWatchCallback { return eventName => { if (eventName === "rename") { callback(fileName, fileExists(fileName) ? FileWatcherEventKind.Created : FileWatcherEventKind.Deleted); @@ -807,32 +781,18 @@ namespace ts { }; } - function isIgnoredByWatchOptions( - pathToCheck: string, - options: WatchOptions | undefined, - useCaseSensitiveFileNames: boolean, - getCurrentDirectory: System["getCurrentDirectory"], - ) { - return (options?.excludeDirectories || options?.excludeFiles) && ( - matchesExclude(pathToCheck, options?.excludeFiles, useCaseSensitiveFileNames, getCurrentDirectory()) || - matchesExclude(pathToCheck, options?.excludeDirectories, useCaseSensitiveFileNames, getCurrentDirectory()) - ); + function isIgnoredByWatchOptions(pathToCheck: string, options: ts.WatchOptions | undefined, useCaseSensitiveFileNames: boolean, getCurrentDirectory: System["getCurrentDirectory"]) { + return (options?.excludeDirectories || options?.excludeFiles) && (ts.matchesExclude(pathToCheck, options?.excludeFiles, useCaseSensitiveFileNames, getCurrentDirectory()) || + ts.matchesExclude(pathToCheck, options?.excludeDirectories, useCaseSensitiveFileNames, getCurrentDirectory())); } - - function createFsWatchCallbackForDirectoryWatcherCallback( - directoryName: string, - callback: DirectoryWatcherCallback, - options: WatchOptions | undefined, - useCaseSensitiveFileNames: boolean, - getCurrentDirectory: System["getCurrentDirectory"], - ): FsWatchCallback { + function createFsWatchCallbackForDirectoryWatcherCallback(directoryName: string, callback: DirectoryWatcherCallback, options: ts.WatchOptions | undefined, useCaseSensitiveFileNames: boolean, getCurrentDirectory: System["getCurrentDirectory"]): FsWatchCallback { return (eventName, relativeFileName) => { // In watchDirectory we only care about adding and removing files (when event name is // "rename"); changes made within files are handled by corresponding fileWatchers (when // event name is "change") if (eventName === "rename") { // When deleting a file, the passed baseFileName is null - const fileName = !relativeFileName ? directoryName : normalizePath(combinePaths(directoryName, relativeFileName)); + const fileName = !relativeFileName ? directoryName : ts.normalizePath(ts.combinePaths(directoryName, relativeFileName)); if (!relativeFileName || !isIgnoredByWatchOptions(fileName, options, useCaseSensitiveFileNames, getCurrentDirectory)) { callback(fileName); } @@ -865,24 +825,10 @@ namespace ts { } /*@internal*/ - export function createSystemWatchFunctions({ - pollingWatchFile, - getModifiedTime, - setTimeout, - clearTimeout, - fsWatch, - fileExists, - useCaseSensitiveFileNames, - getCurrentDirectory, - fsSupportsRecursiveFsWatch, - directoryExists, - getAccessibleSortedChildDirectories, - realpath, - tscWatchFile, - useNonPollingWatchers, - tscWatchDirectory, - defaultWatchFileKind, - }: CreateSystemWatchFunctions): { watchFile: HostWatchFile; watchDirectory: HostWatchDirectory; } { + export function createSystemWatchFunctions({ pollingWatchFile, getModifiedTime, setTimeout, clearTimeout, fsWatch, fileExists, useCaseSensitiveFileNames, getCurrentDirectory, fsSupportsRecursiveFsWatch, directoryExists, getAccessibleSortedChildDirectories, realpath, tscWatchFile, useNonPollingWatchers, tscWatchDirectory, defaultWatchFileKind, }: CreateSystemWatchFunctions): { + watchFile: HostWatchFile; + watchDirectory: HostWatchDirectory; + } { let dynamicPollingWatchFile: HostWatchFile | undefined; let fixedChunkSizePollingWatchFile: HostWatchFile | undefined; let nonPollingWatchFile: HostWatchFile | undefined; @@ -892,34 +838,28 @@ namespace ts { watchDirectory }; - function watchFile(fileName: string, callback: FileWatcherCallback, pollingInterval: PollingInterval, options: WatchOptions | undefined): FileWatcher { + function watchFile(fileName: string, callback: FileWatcherCallback, pollingInterval: PollingInterval, options: ts.WatchOptions | undefined): FileWatcher { options = updateOptionsForWatchFile(options, useNonPollingWatchers); - const watchFileKind = Debug.checkDefined(options.watchFile); + const watchFileKind = ts.Debug.checkDefined(options.watchFile); switch (watchFileKind) { - case WatchFileKind.FixedPollingInterval: + case ts.WatchFileKind.FixedPollingInterval: return pollingWatchFile(fileName, callback, PollingInterval.Low, /*options*/ undefined); - case WatchFileKind.PriorityPollingInterval: + case ts.WatchFileKind.PriorityPollingInterval: return pollingWatchFile(fileName, callback, pollingInterval, /*options*/ undefined); - case WatchFileKind.DynamicPriorityPolling: + case ts.WatchFileKind.DynamicPriorityPolling: return ensureDynamicPollingWatchFile()(fileName, callback, pollingInterval, /*options*/ undefined); - case WatchFileKind.FixedChunkSizePolling: + case ts.WatchFileKind.FixedChunkSizePolling: return ensureFixedChunkSizePollingWatchFile()(fileName, callback, /* pollingInterval */ undefined!, /*options*/ undefined); - case WatchFileKind.UseFsEvents: - return fsWatch( - fileName, - FileSystemEntryKind.File, - createFsWatchCallbackForFileWatcherCallback(fileName, callback, fileExists), - /*recursive*/ false, - pollingInterval, - getFallbackOptions(options) - ); - case WatchFileKind.UseFsEventsOnParentDirectory: + case ts.WatchFileKind.UseFsEvents: + return fsWatch(fileName, FileSystemEntryKind.File, createFsWatchCallbackForFileWatcherCallback(fileName, callback, fileExists), + /*recursive*/ false, pollingInterval, ts.getFallbackOptions(options)); + case ts.WatchFileKind.UseFsEventsOnParentDirectory: if (!nonPollingWatchFile) { nonPollingWatchFile = createUseFsEventsOnParentDirectoryWatchFile(fsWatch, useCaseSensitiveFileNames); } - return nonPollingWatchFile(fileName, callback, pollingInterval, getFallbackOptions(options)); + return nonPollingWatchFile(fileName, callback, pollingInterval, ts.getFallbackOptions(options)); default: - Debug.assertNever(watchFileKind); + ts.Debug.assertNever(watchFileKind); } } @@ -931,38 +871,35 @@ namespace ts { return fixedChunkSizePollingWatchFile ||= createFixedChunkSizePollingWatchFile({ getModifiedTime, setTimeout }); } - function updateOptionsForWatchFile(options: WatchOptions | undefined, useNonPollingWatchers?: boolean): WatchOptions { - if (options && options.watchFile !== undefined) return options; + function updateOptionsForWatchFile(options: ts.WatchOptions | undefined, useNonPollingWatchers?: boolean): ts.WatchOptions { + if (options && options.watchFile !== undefined) + return options; switch (tscWatchFile) { case "PriorityPollingInterval": // Use polling interval based on priority when create watch using host.watchFile - return { watchFile: WatchFileKind.PriorityPollingInterval }; + return { watchFile: ts.WatchFileKind.PriorityPollingInterval }; case "DynamicPriorityPolling": // Use polling interval but change the interval depending on file changes and their default polling interval - return { watchFile: WatchFileKind.DynamicPriorityPolling }; + return { watchFile: ts.WatchFileKind.DynamicPriorityPolling }; case "UseFsEvents": // Use notifications from FS to watch with falling back to fs.watchFile - return generateWatchFileOptions(WatchFileKind.UseFsEvents, PollingWatchKind.PriorityInterval, options); + return generateWatchFileOptions(ts.WatchFileKind.UseFsEvents, ts.PollingWatchKind.PriorityInterval, options); case "UseFsEventsWithFallbackDynamicPolling": // Use notifications from FS to watch with falling back to dynamic watch file - return generateWatchFileOptions(WatchFileKind.UseFsEvents, PollingWatchKind.DynamicPriority, options); + return generateWatchFileOptions(ts.WatchFileKind.UseFsEvents, ts.PollingWatchKind.DynamicPriority, options); case "UseFsEventsOnParentDirectory": useNonPollingWatchers = true; // fall through default: return useNonPollingWatchers ? // Use notifications from FS to watch with falling back to fs.watchFile - generateWatchFileOptions(WatchFileKind.UseFsEventsOnParentDirectory, PollingWatchKind.PriorityInterval, options) : + generateWatchFileOptions(ts.WatchFileKind.UseFsEventsOnParentDirectory, ts.PollingWatchKind.PriorityInterval, options) : // Default to do not use fixed polling interval - { watchFile: defaultWatchFileKind?.() || WatchFileKind.FixedPollingInterval }; + { watchFile: defaultWatchFileKind?.() || ts.WatchFileKind.FixedPollingInterval }; } } - function generateWatchFileOptions( - watchFile: WatchFileKind, - fallbackPolling: PollingWatchKind, - options: WatchOptions | undefined - ): WatchOptions { + function generateWatchFileOptions(watchFile: ts.WatchFileKind, fallbackPolling: ts.PollingWatchKind, options: ts.WatchOptions | undefined): ts.WatchOptions { const defaultFallbackPolling = options?.fallbackPolling; return { watchFile, @@ -972,16 +909,9 @@ namespace ts { }; } - function watchDirectory(directoryName: string, callback: DirectoryWatcherCallback, recursive: boolean, options: WatchOptions | undefined): FileWatcher { + function watchDirectory(directoryName: string, callback: DirectoryWatcherCallback, recursive: boolean, options: ts.WatchOptions | undefined): FileWatcher { if (fsSupportsRecursiveFsWatch) { - return fsWatch( - directoryName, - FileSystemEntryKind.Directory, - createFsWatchCallbackForDirectoryWatcherCallback(directoryName, callback, options, useCaseSensitiveFileNames, getCurrentDirectory), - recursive, - PollingInterval.Medium, - getFallbackOptions(options) - ); + return fsWatch(directoryName, FileSystemEntryKind.Directory, createFsWatchCallbackForDirectoryWatcherCallback(directoryName, callback, options, useCaseSensitiveFileNames, getCurrentDirectory), recursive, PollingInterval.Medium, ts.getFallbackOptions(options)); } if (!hostRecursiveDirectoryWatcher) { @@ -999,59 +929,42 @@ namespace ts { return hostRecursiveDirectoryWatcher(directoryName, callback, recursive, options); } - function nonRecursiveWatchDirectory(directoryName: string, callback: DirectoryWatcherCallback, recursive: boolean, options: WatchOptions | undefined): FileWatcher { - Debug.assert(!recursive); + function nonRecursiveWatchDirectory(directoryName: string, callback: DirectoryWatcherCallback, recursive: boolean, options: ts.WatchOptions | undefined): FileWatcher { + ts.Debug.assert(!recursive); const watchDirectoryOptions = updateOptionsForWatchDirectory(options); - const watchDirectoryKind = Debug.checkDefined(watchDirectoryOptions.watchDirectory); + const watchDirectoryKind = ts.Debug.checkDefined(watchDirectoryOptions.watchDirectory); switch (watchDirectoryKind) { - case WatchDirectoryKind.FixedPollingInterval: - return pollingWatchFile( - directoryName, - () => callback(directoryName), - PollingInterval.Medium, - /*options*/ undefined - ); - case WatchDirectoryKind.DynamicPriorityPolling: - return ensureDynamicPollingWatchFile()( - directoryName, - () => callback(directoryName), - PollingInterval.Medium, - /*options*/ undefined - ); - case WatchDirectoryKind.FixedChunkSizePolling: - return ensureFixedChunkSizePollingWatchFile()( - directoryName, - () => callback(directoryName), + case ts.WatchDirectoryKind.FixedPollingInterval: + return pollingWatchFile(directoryName, () => callback(directoryName), PollingInterval.Medium, + /*options*/ undefined); + case ts.WatchDirectoryKind.DynamicPriorityPolling: + return ensureDynamicPollingWatchFile()(directoryName, () => callback(directoryName), PollingInterval.Medium, + /*options*/ undefined); + case ts.WatchDirectoryKind.FixedChunkSizePolling: + return ensureFixedChunkSizePollingWatchFile()(directoryName, () => callback(directoryName), /* pollingInterval */ undefined!, - /*options*/ undefined - ); - case WatchDirectoryKind.UseFsEvents: - return fsWatch( - directoryName, - FileSystemEntryKind.Directory, - createFsWatchCallbackForDirectoryWatcherCallback(directoryName, callback, options, useCaseSensitiveFileNames, getCurrentDirectory), - recursive, - PollingInterval.Medium, - getFallbackOptions(watchDirectoryOptions) - ); + /*options*/ undefined); + case ts.WatchDirectoryKind.UseFsEvents: + return fsWatch(directoryName, FileSystemEntryKind.Directory, createFsWatchCallbackForDirectoryWatcherCallback(directoryName, callback, options, useCaseSensitiveFileNames, getCurrentDirectory), recursive, PollingInterval.Medium, ts.getFallbackOptions(watchDirectoryOptions)); default: - Debug.assertNever(watchDirectoryKind); + ts.Debug.assertNever(watchDirectoryKind); } } - function updateOptionsForWatchDirectory(options: WatchOptions | undefined): WatchOptions { - if (options && options.watchDirectory !== undefined) return options; + function updateOptionsForWatchDirectory(options: ts.WatchOptions | undefined): ts.WatchOptions { + if (options && options.watchDirectory !== undefined) + return options; switch (tscWatchDirectory) { case "RecursiveDirectoryUsingFsWatchFile": // Use polling interval based on priority when create watch using host.watchFile - return { watchDirectory: WatchDirectoryKind.FixedPollingInterval }; + return { watchDirectory: ts.WatchDirectoryKind.FixedPollingInterval }; case "RecursiveDirectoryUsingDynamicPriorityPolling": // Use polling interval but change the interval depending on file changes and their default polling interval - return { watchDirectory: WatchDirectoryKind.DynamicPriorityPolling }; + return { watchDirectory: ts.WatchDirectoryKind.DynamicPriorityPolling }; default: const defaultFallbackPolling = options?.fallbackPolling; return { - watchDirectory: WatchDirectoryKind.UseFsEvents, + watchDirectory: ts.WatchDirectoryKind.UseFsEvents, fallbackPolling: defaultFallbackPolling !== undefined ? defaultFallbackPolling : undefined @@ -1067,14 +980,7 @@ namespace ts { export function patchWriteFileEnsuringDirectory(sys: System) { // patch writefile to create folder before writing the file const originalWriteFile = sys.writeFile; - sys.writeFile = (path, data, writeBom) => - writeFileEnsuringDirectories( - path, - data, - !!writeBom, - (path, data, writeByteOrderMark) => originalWriteFile.call(sys, path, data, writeByteOrderMark), - path => sys.createDirectory(path), - path => sys.directoryExists(path)); + sys.writeFile = (path, data, writeBom) => ts.writeFileEnsuringDirectories(path, data, !!writeBom, (path, data, writeByteOrderMark) => originalWriteFile.call(sys, path, data, writeByteOrderMark), path => sys.createDirectory(path), path => sys.directoryExists(path)); } /*@internal*/ @@ -1087,15 +993,12 @@ namespace ts { write(str: string, offset: number, encoding?: BufferEncoding): number; write(str: string, offset: number, length: number, encoding?: BufferEncoding): number; toString(encoding?: string, start?: number, end?: number): string; - toJSON(): { type: "Buffer"; data: number[] }; + toJSON(): { + type: "Buffer"; + data: number[]; + }; equals(otherBuffer: Uint8Array): boolean; - compare( - otherBuffer: Uint8Array, - targetStart?: number, - targetEnd?: number, - sourceStart?: number, - sourceEnd?: number - ): number; + compare(otherBuffer: Uint8Array, targetStart?: number, targetEnd?: number, sourceStart?: number, sourceEnd?: number): number; copy(targetBuffer: Uint8Array, targetStart?: number, sourceStart?: number, sourceEnd?: number): number; slice(begin?: number, end?: number): Buffer; subarray(begin?: number, end?: number): Buffer; @@ -1150,14 +1053,18 @@ namespace ts { fill(value: string | Uint8Array | number, offset?: number, end?: number, encoding?: BufferEncoding): this; indexOf(value: string | number | Uint8Array, byteOffset?: number, encoding?: BufferEncoding): number; lastIndexOf(value: string | number | Uint8Array, byteOffset?: number, encoding?: BufferEncoding): number; - entries(): IterableIterator<[number, number]>; + entries(): IterableIterator<[ + number, + number + ]>; includes(value: string | number | Buffer, byteOffset?: number, encoding?: BufferEncoding): boolean; keys(): IterableIterator; values(): IterableIterator; } /*@internal*/ - interface Buffer extends NodeBuffer { } + interface Buffer extends NodeBuffer { + } // TODO: GH#18217 Methods on System are often used as if they are certainly defined export interface System { @@ -1175,8 +1082,8 @@ namespace ts { * @pollingInterval - this parameter is used in polling-based watchers and ignored in watchers that * use native OS file watching */ - watchFile?(path: string, callback: FileWatcherCallback, pollingInterval?: number, options?: WatchOptions): FileWatcher; - watchDirectory?(path: string, callback: DirectoryWatcherCallback, recursive?: boolean, options?: WatchOptions): FileWatcher; + watchFile?(path: string, callback: FileWatcherCallback, pollingInterval?: number, options?: ts.WatchOptions): FileWatcher; + watchDirectory?(path: string, callback: DirectoryWatcherCallback, recursive?: boolean, options?: ts.WatchOptions): FileWatcher; resolvePath(path: string): string; fileExists(path: string): boolean; directoryExists(path: string): boolean; @@ -1210,8 +1117,8 @@ namespace ts { base64decode?(input: string): string; base64encode?(input: string): string; /*@internal*/ bufferFrom?(input: string, encoding?: string): Buffer; - /*@internal*/ require?(baseDir: string, moduleName: string): RequireResult; - /*@internal*/ defaultWatchFileKind?(): WatchFileKind | undefined; + /*@internal*/ require?(baseDir: string, moduleName: string): ts.RequireResult; + /*@internal*/ defaultWatchFileKind?(): ts.WatchFileKind | undefined; // For testing /*@internal*/ now?(): Date; @@ -1288,7 +1195,7 @@ namespace ts { const realpathSync = _fs.realpathSync.native ?? _fs.realpathSync; const fsSupportsRecursiveFsWatch = isNode4OrLater && (process.platform === "win32" || process.platform === "darwin"); - const getCurrentDirectory = memoize(() => process.cwd()); + const getCurrentDirectory = ts.memoize(() => process.cwd()); const { watchFile, watchDirectory } = createSystemWatchFunctions({ pollingWatchFile: createSingleFileWatcherPerName(fsWatchFileWorker, useCaseSensitiveFileNames), getModifiedTime, @@ -1379,9 +1286,9 @@ namespace ts { }, enableCPUProfiler, disableCPUProfiler, - cpuProfilingEnabled: () => !!activeSession || contains(process.execArgv, "--cpu-prof") || contains(process.execArgv, "--prof"), + cpuProfilingEnabled: () => !!activeSession || ts.contains(process.execArgv, "--cpu-prof") || ts.contains(process.execArgv, "--prof"), realpath, - debugMode: !!process.env.NODE_INSPECTOR_IPC || !!process.env.VSCODE_INSPECTOR_OPTIONS || some(process.execArgv as string[], arg => /^--(inspect|debug)(-brk)?(=\d+)?$/i.test(arg)), + debugMode: !!process.env.NODE_INSPECTOR_IPC || !!process.env.VSCODE_INSPECTOR_OPTIONS || ts.some(process.execArgv as string[], arg => /^--(inspect|debug)(-brk)?(=\d+)?$/i.test(arg)), tryEnableSourceMapsForHost() { try { require("source-map-support").install(); @@ -1405,7 +1312,7 @@ namespace ts { base64encode: input => bufferFrom(input).toString("base64"), require: (baseDir, moduleName) => { try { - const modulePath = resolveJSModule(moduleName, baseDir, nodeSystem); + const modulePath = ts.resolveJSModule(moduleName, baseDir, nodeSystem); return { module: require(modulePath), modulePath, error: undefined }; } catch (error) { @@ -1458,15 +1365,15 @@ namespace ts { */ function cleanupPaths(profile: import("inspector").Profiler.Profile) { let externalFileCounter = 0; - const remappedPaths = new Map(); - const normalizedDir = normalizeSlashes(__dirname); + const remappedPaths = new ts.Map(); + const normalizedDir = ts.normalizeSlashes(__dirname); // Windows rooted dir names need an extra `/` prepended to be valid file:/// urls - const fileUrlRoot = `file://${getRootLength(normalizedDir) === 1 ? "" : "/"}${normalizedDir}`; + const fileUrlRoot = `file://${ts.getRootLength(normalizedDir) === 1 ? "" : "/"}${normalizedDir}`; for (const node of profile.nodes) { if (node.callFrame.url) { - const url = normalizeSlashes(node.callFrame.url); - if (containsPath(fileUrlRoot, url, useCaseSensitiveFileNames)) { - node.callFrame.url = getRelativePathToDirectoryOrUrl(fileUrlRoot, url, fileUrlRoot, createGetCanonicalFileName(useCaseSensitiveFileNames), /*isAbsolutePathAnUrl*/ true); + const url = ts.normalizeSlashes(node.callFrame.url); + if (ts.containsPath(fileUrlRoot, url, useCaseSensitiveFileNames)) { + node.callFrame.url = ts.getRelativePathToDirectoryOrUrl(fileUrlRoot, url, fileUrlRoot, ts.createGetCanonicalFileName(useCaseSensitiveFileNames), /*isAbsolutePathAnUrl*/ true); } else if (!nativePattern.test(url)) { node.callFrame.url = (remappedPaths.has(url) ? remappedPaths : remappedPaths.set(url, `external${externalFileCounter}.js`)).get(url)!; @@ -1568,20 +1475,13 @@ namespace ts { } } - function fsWatch( - fileOrDirectory: string, - entryKind: FileSystemEntryKind, - callback: FsWatchCallback, - recursive: boolean, - fallbackPollingInterval: PollingInterval, - fallbackOptions: WatchOptions | undefined - ): FileWatcher { + function fsWatch(fileOrDirectory: string, entryKind: FileSystemEntryKind, callback: FsWatchCallback, recursive: boolean, fallbackPollingInterval: PollingInterval, fallbackOptions: ts.WatchOptions | undefined): FileWatcher { let options: any; let lastDirectoryPartWithDirectorySeparator: string | undefined; let lastDirectoryPart: string | undefined; if (isLinuxOrMacOs) { - lastDirectoryPartWithDirectorySeparator = fileOrDirectory.substr(fileOrDirectory.lastIndexOf(directorySeparator)); - lastDirectoryPart = lastDirectoryPartWithDirectorySeparator.slice(directorySeparator.length); + lastDirectoryPartWithDirectorySeparator = fileOrDirectory.substr(fileOrDirectory.lastIndexOf(ts.directorySeparator)); + lastDirectoryPart = lastDirectoryPartWithDirectorySeparator.slice(ts.directorySeparator.length); } /** Watcher for the file system entry depending on whether it is missing or present */ let watcher = !fileSystemEntryExists(fileOrDirectory, entryKind) ? @@ -1632,13 +1532,9 @@ namespace ts { return watchPresentFileSystemEntryWithFsWatchFile(); } try { - const presentWatcher = _fs.watch( - fileOrDirectory, - options, - isLinuxOrMacOs ? + const presentWatcher = _fs.watch(fileOrDirectory, options, isLinuxOrMacOs ? callbackChangingToMissingFileSystemEntry : - callback - ); + callback); // Watch the missing file or directory or error presentWatcher.on("error", () => invokeCallbackAndUpdateWatcher(watchMissingFileSystemEntry)); return presentWatcher; @@ -1670,12 +1566,7 @@ namespace ts { * Eg. on linux the number of watches are limited and one could easily exhaust watches and the exception ENOSPC is thrown when creating watcher at that point */ function watchPresentFileSystemEntryWithFsWatchFile(): FileWatcher { - return watchFile( - fileOrDirectory, - createFileWatcherCallback(callback), - fallbackPollingInterval, - fallbackOptions - ); + return watchFile(fileOrDirectory, createFileWatcherCallback(callback), fallbackPollingInterval, fallbackOptions); } /** @@ -1683,19 +1574,14 @@ namespace ts { * and switch to existing file or directory when the missing filesystem entry is created */ function watchMissingFileSystemEntry(): FileWatcher { - return watchFile( - fileOrDirectory, - (_fileName, eventKind) => { + return watchFile(fileOrDirectory, (_fileName, eventKind) => { if (eventKind === FileWatcherEventKind.Created && fileSystemEntryExists(fileOrDirectory, entryKind)) { // Call the callback for current file or directory // For now it could be callback for the inner directory creation, // but just return current directory, better than current no-op invokeCallbackAndUpdateWatcher(watchPresentFileSystemEntry); } - }, - fallbackPollingInterval, - fallbackOptions - ); + }, fallbackPollingInterval, fallbackOptions); } } @@ -1732,14 +1618,14 @@ namespace ts { } function readFile(fileName: string, _encoding?: string): string | undefined { - perfLogger.logStartReadFile(fileName); + ts.perfLogger.logStartReadFile(fileName); const file = readFileWorker(fileName, _encoding); - perfLogger.logStopReadFile(); + ts.perfLogger.logStopReadFile(); return file; } function writeFile(fileName: string, data: string, writeByteOrderMark?: boolean): void { - perfLogger.logEvent("WriteFile: " + fileName); + ts.perfLogger.logEvent("WriteFile: " + fileName); // If a BOM is required, emit one if (writeByteOrderMark) { data = byteOrderMarkIndicator + data; @@ -1758,8 +1644,8 @@ namespace ts { } } - function getAccessibleFileSystemEntries(path: string): FileSystemEntries { - perfLogger.logEvent("ReadDir: " + (path || ".")); + function getAccessibleFileSystemEntries(path: string): ts.FileSystemEntries { + ts.perfLogger.logEvent("ReadDir: " + (path || ".")); try { const entries = _fs.readdirSync(path || ".", { withFileTypes: true }); const files: string[] = []; @@ -1776,7 +1662,7 @@ namespace ts { let stat: any; if (typeof dirent === "string" || dirent.isSymbolicLink()) { - const name = combinePaths(path, entry); + const name = ts.combinePaths(path, entry); try { stat = statSync(name); @@ -1804,12 +1690,12 @@ namespace ts { return { files, directories }; } catch (e) { - return emptyFileSystemEntries; + return ts.emptyFileSystemEntries; } } function readDirectory(path: string, extensions?: readonly string[], excludes?: readonly string[], includes?: readonly string[], depth?: number): string[] { - return matchFiles(path, extensions, excludes, includes, useCaseSensitiveFileNames, process.cwd(), depth, getAccessibleFileSystemEntries, realpath); + return ts.matchFiles(path, extensions, excludes, includes, useCaseSensitiveFileNames, process.cwd(), depth, getAccessibleFileSystemEntries, realpath); } function fileSystemEntryExists(path: string, entryKind: FileSystemEntryKind): boolean { @@ -1912,11 +1798,11 @@ namespace ts { if (sys && sys.getEnvironmentVariable) { setCustomPollingValues(sys); - Debug.setAssertionLevel(/^development$/i.test(sys.getEnvironmentVariable("NODE_ENV")) - ? AssertionLevel.Normal - : AssertionLevel.None); + ts.Debug.setAssertionLevel(/^development$/i.test(sys.getEnvironmentVariable("NODE_ENV")) + ? ts.AssertionLevel.Normal + : ts.AssertionLevel.None); } if (sys && sys.debugMode) { - Debug.isDebugging = true; + ts.Debug.isDebugging = true; } } diff --git a/src/compiler/tracing.ts b/src/compiler/tracing.ts index 4757ac72e1b7b..e507ec8978c1d 100644 --- a/src/compiler/tracing.ts +++ b/src/compiler/tracing.ts @@ -17,7 +17,7 @@ namespace ts { // eslint-disable-line one-namespace-per-file let mode: Mode; - const typeCatalog: Type[] = []; // NB: id is index + 1 + const typeCatalog: ts.Type[] = []; // NB: id is index + 1 let legendPath: string | undefined; const legend: TraceRecord[] = []; @@ -25,11 +25,12 @@ namespace ts { // eslint-disable-line one-namespace-per-file // The actual constraint is that JSON.stringify be able to serialize it without throwing. interface Args { [key: string]: string | number | boolean | null | undefined | Args | readonly (string | number | boolean | null | undefined | Args)[]; - }; + } + ; /** Starts tracing for the given project. */ export function startTracing(tracingMode: Mode, traceDir: string, configFilePath?: string) { - Debug.assert(!tracing, "Tracing already started"); + ts.Debug.assert(!tracing, "Tracing already started"); if (fs === undefined) { try { @@ -44,7 +45,7 @@ namespace ts { // eslint-disable-line one-namespace-per-file typeCatalog.length = 0; if (legendPath === undefined) { - legendPath = combinePaths(traceDir, "legend.json"); + legendPath = ts.combinePaths(traceDir, "legend.json"); } // Note that writing will fail later on if it exists and is not a directory @@ -52,12 +53,11 @@ namespace ts { // eslint-disable-line one-namespace-per-file fs.mkdirSync(traceDir, { recursive: true }); } - const countPart = - mode === "build" ? `.${process.pid}-${++traceCount}` + const countPart = mode === "build" ? `.${process.pid}-${++traceCount}` : mode === "server" ? `.${process.pid}` : ``; - const tracePath = combinePaths(traceDir, `trace${countPart}.json`); - const typesPath = combinePaths(traceDir, `types${countPart}.json`); + const tracePath = ts.combinePaths(traceDir, `trace${countPart}.json`); + const typesPath = ts.combinePaths(traceDir, `types${countPart}.json`); legend.push({ configFilePath, @@ -69,9 +69,8 @@ namespace ts { // eslint-disable-line one-namespace-per-file tracing = tracingEnabled; // only when traceFd is properly set // Start with a prefix that contains some metadata that the devtools profiler expects (also avoids a warning on import) - const meta = { cat: "__metadata", ph: "M", ts: 1000 * timestamp(), pid: 1, tid: 1 }; - fs.writeSync(traceFd, - "[\n" + const meta = { cat: "__metadata", ph: "M", ts: 1000 * ts.timestamp(), pid: 1, tid: 1 }; + fs.writeSync(traceFd, "[\n" + [{ name: "process_name", args: { name: "tsc" }, ...meta }, { name: "thread_name", args: { name: "Main" }, ...meta }, { name: "TracingStartedInBrowser", ...meta, cat: "disabled-by-default-devtools.timeline" }] @@ -80,8 +79,8 @@ namespace ts { // eslint-disable-line one-namespace-per-file /** Stops tracing for the in-progress project and dumps the type catalog. */ export function stopTracing() { - Debug.assert(tracing, "Tracing is not in progress"); - Debug.assert(!!typeCatalog.length === (mode !== "server")); // Have a type catalog iff not in server mode + ts.Debug.assert(tracing, "Tracing is not in progress"); + ts.Debug.assert(!!typeCatalog.length === (mode !== "server")); // Have a type catalog iff not in server mode fs.writeSync(traceFd, `\n]\n`); fs.closeSync(traceFd); @@ -97,7 +96,7 @@ namespace ts { // eslint-disable-line one-namespace-per-file } } - export function recordType(type: Type): void { + export function recordType(type: ts.Type): void { if (mode !== "server") { typeCatalog.push(type); } @@ -107,17 +106,23 @@ namespace ts { // eslint-disable-line one-namespace-per-file Parse = "parse", Program = "program", Bind = "bind", - Check = "check", // Before we get into checking types (e.g. checkSourceFile) + Check = "check", CheckTypes = "checkTypes", Emit = "emit", - Session = "session", + Session = "session" } export function instant(phase: Phase, name: string, args?: Args) { writeEvent("I", phase, name, args, `"s":"g"`); } - const eventStack: { phase: Phase, name: string, args?: Args, time: number, separateBeginAndEnd: boolean }[] = []; + const eventStack: { + phase: Phase; + name: string; + args?: Args; + time: number; + separateBeginAndEnd: boolean; + }[] = []; /** * @param separateBeginAndEnd - used for special cases where we need the trace point even if the event @@ -129,15 +134,15 @@ namespace ts { // eslint-disable-line one-namespace-per-file if (separateBeginAndEnd) { writeEvent("B", phase, name, args); } - eventStack.push({ phase, name, args, time: 1000 * timestamp(), separateBeginAndEnd }); + eventStack.push({ phase, name, args, time: 1000 * ts.timestamp(), separateBeginAndEnd }); } export function pop() { - Debug.assert(eventStack.length > 0); - writeStackEvent(eventStack.length - 1, 1000 * timestamp()); + ts.Debug.assert(eventStack.length > 0); + writeStackEvent(eventStack.length - 1, 1000 * ts.timestamp()); eventStack.length--; } export function popAll() { - const endTime = 1000 * timestamp(); + const endTime = 1000 * ts.timestamp(); for (let i = eventStack.length - 1; i >= 0; i--) { writeStackEvent(i, endTime); } @@ -156,32 +161,33 @@ namespace ts { // eslint-disable-line one-namespace-per-file } } - function writeEvent(eventType: string, phase: Phase, name: string, args: Args | undefined, extras?: string, - time: number = 1000 * timestamp()) { + function writeEvent(eventType: string, phase: Phase, name: string, args: Args | undefined, extras?: string, time: number = 1000 * ts.timestamp()) { // In server mode, there's no easy way to dump type information, so we drop events that would require it. - if (mode === "server" && phase === Phase.CheckTypes) return; - - performance.mark("beginTracing"); + if (mode === "server" && phase === Phase.CheckTypes) + return; + ts.performance.mark("beginTracing"); fs.writeSync(traceFd, `,\n{"pid":1,"tid":1,"ph":"${eventType}","cat":"${phase}","ts":${time},"name":"${name}"`); - if (extras) fs.writeSync(traceFd, `,${extras}`); - if (args) fs.writeSync(traceFd, `,"args":${JSON.stringify(args)}`); + if (extras) + fs.writeSync(traceFd, `,${extras}`); + if (args) + fs.writeSync(traceFd, `,"args":${JSON.stringify(args)}`); fs.writeSync(traceFd, `}`); - performance.mark("endTracing"); - performance.measure("Tracing", "beginTracing", "endTracing"); + ts.performance.mark("endTracing"); + ts.performance.measure("Tracing", "beginTracing", "endTracing"); } - function getLocation(node: Node | undefined) { - const file = getSourceFileOfNode(node); + function getLocation(node: ts.Node | undefined) { + const file = ts.getSourceFileOfNode(node); return !file ? undefined : { path: file.path, - start: indexFromOne(getLineAndCharacterOfPosition(file, node!.pos)), - end: indexFromOne(getLineAndCharacterOfPosition(file, node!.end)), + start: indexFromOne(ts.getLineAndCharacterOfPosition(file, node!.pos)), + end: indexFromOne(ts.getLineAndCharacterOfPosition(file, node!.end)), }; - function indexFromOne(lc: LineAndCharacter): LineAndCharacter { + function indexFromOne(lc: ts.LineAndCharacter): ts.LineAndCharacter { return { line: lc.line + 1, character: lc.character + 1, @@ -189,13 +195,13 @@ namespace ts { // eslint-disable-line one-namespace-per-file } } - function dumpTypes(types: readonly Type[]) { - performance.mark("beginDumpTypes"); + function dumpTypes(types: readonly ts.Type[]) { + ts.performance.mark("beginDumpTypes"); const typesPath = legend[legend.length - 1].typesPath!; const typesFd = fs.openSync(typesPath, "w"); - const recursionIdentityMap = new Map(); + const recursionIdentityMap = new ts.Map(); // Cleverness: no line break here so that the type ID will match the line number fs.writeSync(typesFd, "["); @@ -208,7 +214,7 @@ namespace ts { // eslint-disable-line one-namespace-per-file // It's slow to compute the display text, so skip it unless it's really valuable (or cheap) let display: string | undefined; - if ((objectFlags & ObjectFlags.Anonymous) | (type.flags & TypeFlags.Literal)) { + if ((objectFlags & ts.ObjectFlags.Anonymous) | (type.flags & ts.TypeFlags.Literal)) { try { display = type.checker?.typeToString(type); } @@ -218,8 +224,8 @@ namespace ts { // eslint-disable-line one-namespace-per-file } let indexedAccessProperties: object = {}; - if (type.flags & TypeFlags.IndexedAccess) { - const indexedAccessType = type as IndexedAccessType; + if (type.flags & ts.TypeFlags.IndexedAccess) { + const indexedAccessType = type as ts.IndexedAccessType; indexedAccessProperties = { indexedAccessObjectType: indexedAccessType.objectType?.id, indexedAccessIndexType: indexedAccessType.indexType?.id, @@ -227,8 +233,8 @@ namespace ts { // eslint-disable-line one-namespace-per-file } let referenceProperties: object = {}; - if (objectFlags & ObjectFlags.Reference) { - const referenceType = type as TypeReference; + if (objectFlags & ts.ObjectFlags.Reference) { + const referenceType = type as ts.TypeReference; referenceProperties = { instantiatedType: referenceType.target?.id, typeArguments: referenceType.resolvedTypeArguments?.map(t => t.id), @@ -237,8 +243,8 @@ namespace ts { // eslint-disable-line one-namespace-per-file } let conditionalProperties: object = {}; - if (type.flags & TypeFlags.Conditional) { - const conditionalType = type as ConditionalType; + if (type.flags & ts.TypeFlags.Conditional) { + const conditionalType = type as ts.ConditionalType; conditionalProperties = { conditionalCheckType: conditionalType.checkType?.id, conditionalExtendsType: conditionalType.extendsType?.id, @@ -248,8 +254,8 @@ namespace ts { // eslint-disable-line one-namespace-per-file } let substitutionProperties: object = {}; - if (type.flags & TypeFlags.Substitution) { - const substitutionType = type as SubstitutionType; + if (type.flags & ts.TypeFlags.Substitution) { + const substitutionType = type as ts.SubstitutionType; substitutionProperties = { substitutionBaseType: substitutionType.baseType?.id, substituteType: substitutionType.substitute?.id, @@ -257,8 +263,8 @@ namespace ts { // eslint-disable-line one-namespace-per-file } let reverseMappedProperties: object = {}; - if (objectFlags & ObjectFlags.ReverseMapped) { - const reverseMappedType = type as ReverseMappedType; + if (objectFlags & ts.ObjectFlags.ReverseMapped) { + const reverseMappedType = type as ts.ReverseMappedType; reverseMappedProperties = { reverseMappedSourceType: reverseMappedType.source?.id, reverseMappedMappedType: reverseMappedType.mappedType?.id, @@ -267,8 +273,8 @@ namespace ts { // eslint-disable-line one-namespace-per-file } let evolvingArrayProperties: object = {}; - if (objectFlags & ObjectFlags.EvolvingArray) { - const evolvingArrayType = type as EvolvingArrayType; + if (objectFlags & ts.ObjectFlags.EvolvingArray) { + const evolvingArrayType = type as ts.EvolvingArrayType; evolvingArrayProperties = { evolvingArrayElementType: evolvingArrayType.elementType.id, evolvingArrayFinalType: evolvingArrayType.finalArrayType?.id, @@ -290,13 +296,13 @@ namespace ts { // eslint-disable-line one-namespace-per-file const descriptor = { id: type.id, intrinsicName: (type as any).intrinsicName, - symbolName: symbol?.escapedName && unescapeLeadingUnderscores(symbol.escapedName), + symbolName: symbol?.escapedName && ts.unescapeLeadingUnderscores(symbol.escapedName), recursionId: recursionToken, - isTuple: objectFlags & ObjectFlags.Tuple ? true : undefined, - unionTypes: (type.flags & TypeFlags.Union) ? (type as UnionType).types?.map(t => t.id) : undefined, - intersectionTypes: (type.flags & TypeFlags.Intersection) ? (type as IntersectionType).types.map(t => t.id) : undefined, + isTuple: objectFlags & ts.ObjectFlags.Tuple ? true : undefined, + unionTypes: (type.flags & ts.TypeFlags.Union) ? (type as ts.UnionType).types?.map(t => t.id) : undefined, + intersectionTypes: (type.flags & ts.TypeFlags.Intersection) ? (type as ts.IntersectionType).types.map(t => t.id) : undefined, aliasTypeArguments: type.aliasTypeArguments?.map(t => t.id), - keyofType: (type.flags & TypeFlags.Index) ? (type as IndexType).type?.id : undefined, + keyofType: (type.flags & ts.TypeFlags.Index) ? (type as ts.IndexType).type?.id : undefined, ...indexedAccessProperties, ...referenceProperties, ...conditionalProperties, @@ -305,7 +311,7 @@ namespace ts { // eslint-disable-line one-namespace-per-file ...evolvingArrayProperties, destructuringPattern: getLocation(type.pattern), firstDeclaration: getLocation(symbol?.declarations?.[0]), - flags: Debug.formatTypeFlags(type.flags).split("|"), + flags: ts.Debug.formatTypeFlags(type.flags).split("|"), display, }; @@ -319,8 +325,8 @@ namespace ts { // eslint-disable-line one-namespace-per-file fs.closeSync(typesFd); - performance.mark("endDumpTypes"); - performance.measure("Dump types", "beginDumpTypes", "endDumpTypes"); + ts.performance.mark("endDumpTypes"); + ts.performance.measure("Dump types", "beginDumpTypes", "endDumpTypes"); } export function dumpLegend() { @@ -343,6 +349,6 @@ namespace ts { // eslint-disable-line one-namespace-per-file export const dumpTracingLegend = tracingEnabled.dumpLegend; export interface TracingNode { - tracingPath?: Path; + tracingPath?: ts.Path; } } diff --git a/src/compiler/transformer.ts b/src/compiler/transformer.ts index bfe7017150406..1b456f7fec165 100644 --- a/src/compiler/transformer.ts +++ b/src/compiler/transformer.ts @@ -1,19 +1,19 @@ /* @internal */ namespace ts { - function getModuleTransformer(moduleKind: ModuleKind): TransformerFactory { + function getModuleTransformer(moduleKind: ts.ModuleKind): ts.TransformerFactory { switch (moduleKind) { - case ModuleKind.ESNext: - case ModuleKind.ES2022: - case ModuleKind.ES2020: - case ModuleKind.ES2015: - return transformECMAScriptModule; - case ModuleKind.System: - return transformSystemModule; - case ModuleKind.Node16: - case ModuleKind.NodeNext: - return transformNodeModule; + case ts.ModuleKind.ESNext: + case ts.ModuleKind.ES2022: + case ts.ModuleKind.ES2020: + case ts.ModuleKind.ES2015: + return ts.transformECMAScriptModule; + case ts.ModuleKind.System: + return ts.transformSystemModule; + case ts.ModuleKind.Node16: + case ts.ModuleKind.NodeNext: + return ts.transformNodeModule; default: - return transformModule; + return ts.transformModule; } } @@ -26,97 +26,85 @@ namespace ts { const enum SyntaxKindFeatureFlags { Substitution = 1 << 0, - EmitNotifications = 1 << 1, + EmitNotifications = 1 << 1 } - export const noTransformers: EmitTransformers = { scriptTransformers: emptyArray, declarationTransformers: emptyArray }; - - export function getTransformers(compilerOptions: CompilerOptions, customTransformers?: CustomTransformers, emitOnlyDtsFiles?: boolean): EmitTransformers { + export const noTransformers: ts.EmitTransformers = { scriptTransformers: ts.emptyArray, declarationTransformers: ts.emptyArray }; + export function getTransformers(compilerOptions: ts.CompilerOptions, customTransformers?: ts.CustomTransformers, emitOnlyDtsFiles?: boolean): ts.EmitTransformers { return { scriptTransformers: getScriptTransformers(compilerOptions, customTransformers, emitOnlyDtsFiles), declarationTransformers: getDeclarationTransformers(customTransformers), }; } - function getScriptTransformers(compilerOptions: CompilerOptions, customTransformers?: CustomTransformers, emitOnlyDtsFiles?: boolean) { - if (emitOnlyDtsFiles) return emptyArray; - - const languageVersion = getEmitScriptTarget(compilerOptions); - const moduleKind = getEmitModuleKind(compilerOptions); - const transformers: TransformerFactory[] = []; - - addRange(transformers, customTransformers && map(customTransformers.before, wrapScriptTransformerFactory)); - - transformers.push(transformTypeScript); - transformers.push(transformClassFields); - - if (getJSXTransformEnabled(compilerOptions)) { - transformers.push(transformJsx); + function getScriptTransformers(compilerOptions: ts.CompilerOptions, customTransformers?: ts.CustomTransformers, emitOnlyDtsFiles?: boolean) { + if (emitOnlyDtsFiles) + return ts.emptyArray; + const languageVersion = ts.getEmitScriptTarget(compilerOptions); + const moduleKind = ts.getEmitModuleKind(compilerOptions); + const transformers: ts.TransformerFactory[] = []; + ts.addRange(transformers, customTransformers && ts.map(customTransformers.before, wrapScriptTransformerFactory)); + transformers.push(ts.transformTypeScript); + transformers.push(ts.transformClassFields); + if (ts.getJSXTransformEnabled(compilerOptions)) { + transformers.push(ts.transformJsx); } - - if (languageVersion < ScriptTarget.ESNext) { - transformers.push(transformESNext); + if (languageVersion < ts.ScriptTarget.ESNext) { + transformers.push(ts.transformESNext); } - - if (languageVersion < ScriptTarget.ES2021) { - transformers.push(transformES2021); + if (languageVersion < ts.ScriptTarget.ES2021) { + transformers.push(ts.transformES2021); } - - if (languageVersion < ScriptTarget.ES2020) { - transformers.push(transformES2020); + if (languageVersion < ts.ScriptTarget.ES2020) { + transformers.push(ts.transformES2020); } - - if (languageVersion < ScriptTarget.ES2019) { - transformers.push(transformES2019); + if (languageVersion < ts.ScriptTarget.ES2019) { + transformers.push(ts.transformES2019); } - - if (languageVersion < ScriptTarget.ES2018) { - transformers.push(transformES2018); + if (languageVersion < ts.ScriptTarget.ES2018) { + transformers.push(ts.transformES2018); } - - if (languageVersion < ScriptTarget.ES2017) { - transformers.push(transformES2017); + if (languageVersion < ts.ScriptTarget.ES2017) { + transformers.push(ts.transformES2017); } - - if (languageVersion < ScriptTarget.ES2016) { - transformers.push(transformES2016); + if (languageVersion < ts.ScriptTarget.ES2016) { + transformers.push(ts.transformES2016); } - - if (languageVersion < ScriptTarget.ES2015) { - transformers.push(transformES2015); - transformers.push(transformGenerators); + if (languageVersion < ts.ScriptTarget.ES2015) { + transformers.push(ts.transformES2015); + transformers.push(ts.transformGenerators); } transformers.push(getModuleTransformer(moduleKind)); // The ES5 transformer is last so that it can substitute expressions like `exports.default` // for ES3. - if (languageVersion < ScriptTarget.ES5) { - transformers.push(transformES5); + if (languageVersion < ts.ScriptTarget.ES5) { + transformers.push(ts.transformES5); } - addRange(transformers, customTransformers && map(customTransformers.after, wrapScriptTransformerFactory)); + ts.addRange(transformers, customTransformers && ts.map(customTransformers.after, wrapScriptTransformerFactory)); return transformers; } - function getDeclarationTransformers(customTransformers?: CustomTransformers) { - const transformers: TransformerFactory[] = []; - transformers.push(transformDeclarations); - addRange(transformers, customTransformers && map(customTransformers.afterDeclarations, wrapDeclarationTransformerFactory)); + function getDeclarationTransformers(customTransformers?: ts.CustomTransformers) { + const transformers: ts.TransformerFactory[] = []; + transformers.push(ts.transformDeclarations); + ts.addRange(transformers, customTransformers && ts.map(customTransformers.afterDeclarations, wrapDeclarationTransformerFactory)); return transformers; } /** * Wrap a custom script or declaration transformer object in a `Transformer` callback with fallback support for transforming bundles. */ - function wrapCustomTransformer(transformer: CustomTransformer): Transformer { - return node => isBundle(node) ? transformer.transformBundle(node) : transformer.transformSourceFile(node); + function wrapCustomTransformer(transformer: ts.CustomTransformer): ts.Transformer { + return node => ts.isBundle(node) ? transformer.transformBundle(node) : transformer.transformSourceFile(node); } /** * Wrap a transformer factory that may return a custom script or declaration transformer object. */ - function wrapCustomTransformerFactory(transformer: TransformerFactory | CustomTransformerFactory, handleDefault: (context: TransformationContext, tx: Transformer) => Transformer): TransformerFactory { + function wrapCustomTransformerFactory(transformer: ts.TransformerFactory | ts.CustomTransformerFactory, handleDefault: (context: ts.TransformationContext, tx: ts.Transformer) => ts.Transformer): ts.TransformerFactory { return context => { const customTransformer = transformer(context); return typeof customTransformer === "function" @@ -125,19 +113,19 @@ namespace ts { }; } - function wrapScriptTransformerFactory(transformer: TransformerFactory | CustomTransformerFactory): TransformerFactory { - return wrapCustomTransformerFactory(transformer, chainBundle); + function wrapScriptTransformerFactory(transformer: ts.TransformerFactory | ts.CustomTransformerFactory): ts.TransformerFactory { + return wrapCustomTransformerFactory(transformer, ts.chainBundle); } - function wrapDeclarationTransformerFactory(transformer: TransformerFactory | CustomTransformerFactory): TransformerFactory { + function wrapDeclarationTransformerFactory(transformer: ts.TransformerFactory | ts.CustomTransformerFactory): ts.TransformerFactory { return wrapCustomTransformerFactory(transformer, (_, node) => node); } - export function noEmitSubstitution(_hint: EmitHint, node: Node) { + export function noEmitSubstitution(_hint: ts.EmitHint, node: ts.Node) { return node; } - export function noEmitNotification(hint: EmitHint, node: Node, callback: (hint: EmitHint, node: Node) => void) { + export function noEmitNotification(hint: ts.EmitHint, node: ts.Node, callback: (hint: ts.EmitHint, node: ts.Node) => void) { callback(hint, node); } @@ -151,35 +139,35 @@ namespace ts { * @param transforms An array of `TransformerFactory` callbacks. * @param allowDtsFiles A value indicating whether to allow the transformation of .d.ts files. */ - export function transformNodes(resolver: EmitResolver | undefined, host: EmitHost | undefined, factory: NodeFactory, options: CompilerOptions, nodes: readonly T[], transformers: readonly TransformerFactory[], allowDtsFiles: boolean): TransformationResult { - const enabledSyntaxKindFeatures = new Array(SyntaxKind.Count); - let lexicalEnvironmentVariableDeclarations: VariableDeclaration[]; - let lexicalEnvironmentFunctionDeclarations: FunctionDeclaration[]; - let lexicalEnvironmentStatements: Statement[]; - let lexicalEnvironmentFlags = LexicalEnvironmentFlags.None; - let lexicalEnvironmentVariableDeclarationsStack: VariableDeclaration[][] = []; - let lexicalEnvironmentFunctionDeclarationsStack: FunctionDeclaration[][] = []; - let lexicalEnvironmentStatementsStack: Statement[][] = []; - let lexicalEnvironmentFlagsStack: LexicalEnvironmentFlags[] = []; + export function transformNodes(resolver: ts.EmitResolver | undefined, host: ts.EmitHost | undefined, factory: ts.NodeFactory, options: ts.CompilerOptions, nodes: readonly T[], transformers: readonly ts.TransformerFactory[], allowDtsFiles: boolean): ts.TransformationResult { + const enabledSyntaxKindFeatures = new Array(ts.SyntaxKind.Count); + let lexicalEnvironmentVariableDeclarations: ts.VariableDeclaration[]; + let lexicalEnvironmentFunctionDeclarations: ts.FunctionDeclaration[]; + let lexicalEnvironmentStatements: ts.Statement[]; + let lexicalEnvironmentFlags = ts.LexicalEnvironmentFlags.None; + let lexicalEnvironmentVariableDeclarationsStack: ts.VariableDeclaration[][] = []; + let lexicalEnvironmentFunctionDeclarationsStack: ts.FunctionDeclaration[][] = []; + let lexicalEnvironmentStatementsStack: ts.Statement[][] = []; + let lexicalEnvironmentFlagsStack: ts.LexicalEnvironmentFlags[] = []; let lexicalEnvironmentStackOffset = 0; let lexicalEnvironmentSuspended = false; - let blockScopedVariableDeclarationsStack: Identifier[][] = []; + let blockScopedVariableDeclarationsStack: ts.Identifier[][] = []; let blockScopeStackOffset = 0; - let blockScopedVariableDeclarations: Identifier[]; - let emitHelpers: EmitHelper[] | undefined; - let onSubstituteNode: TransformationContext["onSubstituteNode"] = noEmitSubstitution; - let onEmitNode: TransformationContext["onEmitNode"] = noEmitNotification; + let blockScopedVariableDeclarations: ts.Identifier[]; + let emitHelpers: ts.EmitHelper[] | undefined; + let onSubstituteNode: ts.TransformationContext["onSubstituteNode"] = noEmitSubstitution; + let onEmitNode: ts.TransformationContext["onEmitNode"] = noEmitNotification; let state = TransformationState.Uninitialized; - const diagnostics: DiagnosticWithLocation[] = []; + const diagnostics: ts.DiagnosticWithLocation[] = []; // The transformation context is provided to each transformer as part of transformer // initialization. - const context: TransformationContext = { + const context: ts.TransformationContext = { factory, getCompilerOptions: () => options, - getEmitResolver: () => resolver!, // TODO: GH#18217 - getEmitHost: () => host!, // TODO: GH#18217 - getEmitHelperFactory: memoize(() => createEmitHelperFactory(context)), + getEmitResolver: () => resolver!, + getEmitHost: () => host!, + getEmitHelperFactory: ts.memoize(() => ts.createEmitHelperFactory(context)), startLexicalEnvironment, suspendLexicalEnvironment, resumeLexicalEnvironment, @@ -200,14 +188,14 @@ namespace ts { isEmitNotificationEnabled, get onSubstituteNode() { return onSubstituteNode; }, set onSubstituteNode(value) { - Debug.assert(state < TransformationState.Initialized, "Cannot modify transformation hooks after initialization has completed."); - Debug.assert(value !== undefined, "Value must not be 'undefined'"); + ts.Debug.assert(state < TransformationState.Initialized, "Cannot modify transformation hooks after initialization has completed."); + ts.Debug.assert(value !== undefined, "Value must not be 'undefined'"); onSubstituteNode = value; }, get onEmitNode() { return onEmitNode; }, set onEmitNode(value) { - Debug.assert(state < TransformationState.Initialized, "Cannot modify transformation hooks after initialization has completed."); - Debug.assert(value !== undefined, "Value must not be 'undefined'"); + ts.Debug.assert(state < TransformationState.Initialized, "Cannot modify transformation hooks after initialization has completed."); + ts.Debug.assert(value !== undefined, "Value must not be 'undefined'"); onEmitNode = value; }, addDiagnostic(diag) { @@ -217,10 +205,10 @@ namespace ts { // Ensure the parse tree is clean before applying transformations for (const node of nodes) { - disposeEmitNodes(getSourceFileOfNode(getParseTreeNode(node))); + ts.disposeEmitNodes(ts.getSourceFileOfNode(ts.getParseTreeNode(node))); } - performance.mark("beforeTransform"); + ts.performance.mark("beforeTransform"); // Chain together and initialize each transformer. const transformersWithContext = transformers.map(t => t(context)); @@ -237,16 +225,16 @@ namespace ts { // Transform each node. const transformed: T[] = []; for (const node of nodes) { - tracing?.push(tracing.Phase.Emit, "transformNodes", node.kind === SyntaxKind.SourceFile ? { path: (node as any as SourceFile).path } : { kind: node.kind, pos: node.pos, end: node.end }); + ts.tracing?.push(ts.tracing.Phase.Emit, "transformNodes", node.kind === ts.SyntaxKind.SourceFile ? { path: (node as any as ts.SourceFile).path } : { kind: node.kind, pos: node.pos, end: node.end }); transformed.push((allowDtsFiles ? transformation : transformRoot)(node)); - tracing?.pop(); + ts.tracing?.pop(); } // prevent modification of the lexical environment. state = TransformationState.Completed; - performance.mark("afterTransform"); - performance.measure("transformTime", "beforeTransform", "afterTransform"); + ts.performance.mark("afterTransform"); + ts.performance.measure("transformTime", "beforeTransform", "afterTransform"); return { transformed, @@ -258,23 +246,23 @@ namespace ts { }; function transformRoot(node: T) { - return node && (!isSourceFile(node) || !node.isDeclarationFile) ? transformation(node) : node; + return node && (!ts.isSourceFile(node) || !node.isDeclarationFile) ? transformation(node) : node; } /** * Enables expression substitutions in the pretty printer for the provided SyntaxKind. */ - function enableSubstitution(kind: SyntaxKind) { - Debug.assert(state < TransformationState.Completed, "Cannot modify the transformation context after transformation has completed."); + function enableSubstitution(kind: ts.SyntaxKind) { + ts.Debug.assert(state < TransformationState.Completed, "Cannot modify the transformation context after transformation has completed."); enabledSyntaxKindFeatures[kind] |= SyntaxKindFeatureFlags.Substitution; } /** * Determines whether expression substitutions are enabled for the provided node. */ - function isSubstitutionEnabled(node: Node) { + function isSubstitutionEnabled(node: ts.Node) { return (enabledSyntaxKindFeatures[node.kind] & SyntaxKindFeatureFlags.Substitution) !== 0 - && (getEmitFlags(node) & EmitFlags.NoSubstitution) === 0; + && (ts.getEmitFlags(node) & ts.EmitFlags.NoSubstitution) === 0; } /** @@ -284,16 +272,16 @@ namespace ts { * @param node The node to emit. * @param emitCallback The callback used to emit the node or its substitute. */ - function substituteNode(hint: EmitHint, node: Node) { - Debug.assert(state < TransformationState.Disposed, "Cannot substitute a node after the result is disposed."); + function substituteNode(hint: ts.EmitHint, node: ts.Node) { + ts.Debug.assert(state < TransformationState.Disposed, "Cannot substitute a node after the result is disposed."); return node && isSubstitutionEnabled(node) && onSubstituteNode(hint, node) || node; } /** * Enables before/after emit notifications in the pretty printer for the provided SyntaxKind. */ - function enableEmitNotification(kind: SyntaxKind) { - Debug.assert(state < TransformationState.Completed, "Cannot modify the transformation context after transformation has completed."); + function enableEmitNotification(kind: ts.SyntaxKind) { + ts.Debug.assert(state < TransformationState.Completed, "Cannot modify the transformation context after transformation has completed."); enabledSyntaxKindFeatures[kind] |= SyntaxKindFeatureFlags.EmitNotifications; } @@ -301,9 +289,9 @@ namespace ts { * Determines whether before/after emit notifications should be raised in the pretty * printer when it emits a node. */ - function isEmitNotificationEnabled(node: Node) { + function isEmitNotificationEnabled(node: ts.Node) { return (enabledSyntaxKindFeatures[node.kind] & SyntaxKindFeatureFlags.EmitNotifications) !== 0 - || (getEmitFlags(node) & EmitFlags.AdviseOnEmitNode) !== 0; + || (ts.getEmitFlags(node) & ts.EmitFlags.AdviseOnEmitNode) !== 0; } /** @@ -313,8 +301,8 @@ namespace ts { * @param node The node to emit. * @param emitCallback The callback used to emit the node. */ - function emitNodeWithNotification(hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) => void) { - Debug.assert(state < TransformationState.Disposed, "Cannot invoke TransformationResult callbacks after the result is disposed."); + function emitNodeWithNotification(hint: ts.EmitHint, node: ts.Node, emitCallback: (hint: ts.EmitHint, node: ts.Node) => void) { + ts.Debug.assert(state < TransformationState.Disposed, "Cannot invoke TransformationResult callbacks after the result is disposed."); if (node) { // TODO: Remove check and unconditionally use onEmitNode when API is breakingly changed // (see https://github.com/microsoft/TypeScript/pull/36248/files/5062623f39120171b98870c71344b3242eb03d23#r369766739) @@ -330,28 +318,28 @@ namespace ts { /** * Records a hoisted variable declaration for the provided name within a lexical environment. */ - function hoistVariableDeclaration(name: Identifier): void { - Debug.assert(state > TransformationState.Uninitialized, "Cannot modify the lexical environment during initialization."); - Debug.assert(state < TransformationState.Completed, "Cannot modify the lexical environment after transformation has completed."); - const decl = setEmitFlags(factory.createVariableDeclaration(name), EmitFlags.NoNestedSourceMaps); + function hoistVariableDeclaration(name: ts.Identifier): void { + ts.Debug.assert(state > TransformationState.Uninitialized, "Cannot modify the lexical environment during initialization."); + ts.Debug.assert(state < TransformationState.Completed, "Cannot modify the lexical environment after transformation has completed."); + const decl = ts.setEmitFlags(factory.createVariableDeclaration(name), ts.EmitFlags.NoNestedSourceMaps); if (!lexicalEnvironmentVariableDeclarations) { lexicalEnvironmentVariableDeclarations = [decl]; } else { lexicalEnvironmentVariableDeclarations.push(decl); } - if (lexicalEnvironmentFlags & LexicalEnvironmentFlags.InParameters) { - lexicalEnvironmentFlags |= LexicalEnvironmentFlags.VariablesHoistedInParameters; + if (lexicalEnvironmentFlags & ts.LexicalEnvironmentFlags.InParameters) { + lexicalEnvironmentFlags |= ts.LexicalEnvironmentFlags.VariablesHoistedInParameters; } } /** * Records a hoisted function declaration within a lexical environment. */ - function hoistFunctionDeclaration(func: FunctionDeclaration): void { - Debug.assert(state > TransformationState.Uninitialized, "Cannot modify the lexical environment during initialization."); - Debug.assert(state < TransformationState.Completed, "Cannot modify the lexical environment after transformation has completed."); - setEmitFlags(func, EmitFlags.CustomPrologue); + function hoistFunctionDeclaration(func: ts.FunctionDeclaration): void { + ts.Debug.assert(state > TransformationState.Uninitialized, "Cannot modify the lexical environment during initialization."); + ts.Debug.assert(state < TransformationState.Completed, "Cannot modify the lexical environment after transformation has completed."); + ts.setEmitFlags(func, ts.EmitFlags.CustomPrologue); if (!lexicalEnvironmentFunctionDeclarations) { lexicalEnvironmentFunctionDeclarations = [func]; } @@ -363,10 +351,10 @@ namespace ts { /** * Adds an initialization statement to the top of the lexical environment. */ - function addInitializationStatement(node: Statement): void { - Debug.assert(state > TransformationState.Uninitialized, "Cannot modify the lexical environment during initialization."); - Debug.assert(state < TransformationState.Completed, "Cannot modify the lexical environment after transformation has completed."); - setEmitFlags(node, EmitFlags.CustomPrologue); + function addInitializationStatement(node: ts.Statement): void { + ts.Debug.assert(state > TransformationState.Uninitialized, "Cannot modify the lexical environment during initialization."); + ts.Debug.assert(state < TransformationState.Completed, "Cannot modify the lexical environment after transformation has completed."); + ts.setEmitFlags(node, ts.EmitFlags.CustomPrologue); if (!lexicalEnvironmentStatements) { lexicalEnvironmentStatements = [node]; } @@ -380,9 +368,9 @@ namespace ts { * are pushed onto a stack, and the related storage variables are reset. */ function startLexicalEnvironment(): void { - Debug.assert(state > TransformationState.Uninitialized, "Cannot modify the lexical environment during initialization."); - Debug.assert(state < TransformationState.Completed, "Cannot modify the lexical environment after transformation has completed."); - Debug.assert(!lexicalEnvironmentSuspended, "Lexical environment is suspended."); + ts.Debug.assert(state > TransformationState.Uninitialized, "Cannot modify the lexical environment during initialization."); + ts.Debug.assert(state < TransformationState.Completed, "Cannot modify the lexical environment after transformation has completed."); + ts.Debug.assert(!lexicalEnvironmentSuspended, "Lexical environment is suspended."); // Save the current lexical environment. Rather than resizing the array we adjust the // stack size variable. This allows us to reuse existing array slots we've @@ -396,22 +384,22 @@ namespace ts { lexicalEnvironmentVariableDeclarations = undefined!; lexicalEnvironmentFunctionDeclarations = undefined!; lexicalEnvironmentStatements = undefined!; - lexicalEnvironmentFlags = LexicalEnvironmentFlags.None; + lexicalEnvironmentFlags = ts.LexicalEnvironmentFlags.None; } /** Suspends the current lexical environment, usually after visiting a parameter list. */ function suspendLexicalEnvironment(): void { - Debug.assert(state > TransformationState.Uninitialized, "Cannot modify the lexical environment during initialization."); - Debug.assert(state < TransformationState.Completed, "Cannot modify the lexical environment after transformation has completed."); - Debug.assert(!lexicalEnvironmentSuspended, "Lexical environment is already suspended."); + ts.Debug.assert(state > TransformationState.Uninitialized, "Cannot modify the lexical environment during initialization."); + ts.Debug.assert(state < TransformationState.Completed, "Cannot modify the lexical environment after transformation has completed."); + ts.Debug.assert(!lexicalEnvironmentSuspended, "Lexical environment is already suspended."); lexicalEnvironmentSuspended = true; } /** Resumes a suspended lexical environment, usually before visiting a function body. */ function resumeLexicalEnvironment(): void { - Debug.assert(state > TransformationState.Uninitialized, "Cannot modify the lexical environment during initialization."); - Debug.assert(state < TransformationState.Completed, "Cannot modify the lexical environment after transformation has completed."); - Debug.assert(lexicalEnvironmentSuspended, "Lexical environment is not suspended."); + ts.Debug.assert(state > TransformationState.Uninitialized, "Cannot modify the lexical environment during initialization."); + ts.Debug.assert(state < TransformationState.Completed, "Cannot modify the lexical environment after transformation has completed."); + ts.Debug.assert(lexicalEnvironmentSuspended, "Lexical environment is not suspended."); lexicalEnvironmentSuspended = false; } @@ -419,12 +407,11 @@ namespace ts { * Ends a lexical environment. The previous set of hoisted declarations are restored and * any hoisted declarations added in this environment are returned. */ - function endLexicalEnvironment(): Statement[] | undefined { - Debug.assert(state > TransformationState.Uninitialized, "Cannot modify the lexical environment during initialization."); - Debug.assert(state < TransformationState.Completed, "Cannot modify the lexical environment after transformation has completed."); - Debug.assert(!lexicalEnvironmentSuspended, "Lexical environment is suspended."); - - let statements: Statement[] | undefined; + function endLexicalEnvironment(): ts.Statement[] | undefined { + ts.Debug.assert(state > TransformationState.Uninitialized, "Cannot modify the lexical environment during initialization."); + ts.Debug.assert(state < TransformationState.Completed, "Cannot modify the lexical environment after transformation has completed."); + ts.Debug.assert(!lexicalEnvironmentSuspended, "Lexical environment is suspended."); + let statements: ts.Statement[] | undefined; if (lexicalEnvironmentVariableDeclarations || lexicalEnvironmentFunctionDeclarations || lexicalEnvironmentStatements) { @@ -434,11 +421,8 @@ namespace ts { if (lexicalEnvironmentVariableDeclarations) { const statement = factory.createVariableStatement( - /*modifiers*/ undefined, - factory.createVariableDeclarationList(lexicalEnvironmentVariableDeclarations) - ); - - setEmitFlags(statement, EmitFlags.CustomPrologue); + /*modifiers*/ undefined, factory.createVariableDeclarationList(lexicalEnvironmentVariableDeclarations)); + ts.setEmitFlags(statement, ts.EmitFlags.CustomPrologue); if (!statements) { statements = [statement]; @@ -473,13 +457,13 @@ namespace ts { return statements; } - function setLexicalEnvironmentFlags(flags: LexicalEnvironmentFlags, value: boolean): void { + function setLexicalEnvironmentFlags(flags: ts.LexicalEnvironmentFlags, value: boolean): void { lexicalEnvironmentFlags = value ? lexicalEnvironmentFlags | flags : lexicalEnvironmentFlags & ~flags; } - function getLexicalEnvironmentFlags(): LexicalEnvironmentFlags { + function getLexicalEnvironmentFlags(): ts.LexicalEnvironmentFlags { return lexicalEnvironmentFlags; } @@ -487,8 +471,8 @@ namespace ts { * Starts a block scope. Any existing block hoisted variables are pushed onto the stack and the related storage variables are reset. */ function startBlockScope() { - Debug.assert(state > TransformationState.Uninitialized, "Cannot start a block scope during initialization."); - Debug.assert(state < TransformationState.Completed, "Cannot start a block scope after transformation has completed."); + ts.Debug.assert(state > TransformationState.Uninitialized, "Cannot start a block scope during initialization."); + ts.Debug.assert(state < TransformationState.Completed, "Cannot start a block scope after transformation has completed."); blockScopedVariableDeclarationsStack[blockScopeStackOffset] = blockScopedVariableDeclarations; blockScopeStackOffset++; blockScopedVariableDeclarations = undefined!; @@ -498,17 +482,12 @@ namespace ts { * Ends a block scope. The previous set of block hoisted variables are restored. Any hoisted declarations are returned. */ function endBlockScope() { - Debug.assert(state > TransformationState.Uninitialized, "Cannot end a block scope during initialization."); - Debug.assert(state < TransformationState.Completed, "Cannot end a block scope after transformation has completed."); - const statements: Statement[] | undefined = some(blockScopedVariableDeclarations) ? + ts.Debug.assert(state > TransformationState.Uninitialized, "Cannot end a block scope during initialization."); + ts.Debug.assert(state < TransformationState.Completed, "Cannot end a block scope after transformation has completed."); + const statements: ts.Statement[] | undefined = ts.some(blockScopedVariableDeclarations) ? [ factory.createVariableStatement( - /*modifiers*/ undefined, - factory.createVariableDeclarationList( - blockScopedVariableDeclarations.map(identifier => factory.createVariableDeclaration(identifier)), - NodeFlags.Let - ) - ) + /*modifiers*/ undefined, factory.createVariableDeclarationList(blockScopedVariableDeclarations.map(identifier => factory.createVariableDeclaration(identifier)), ts.NodeFlags.Let)) ] : undefined; blockScopeStackOffset--; blockScopedVariableDeclarations = blockScopedVariableDeclarationsStack[blockScopeStackOffset]; @@ -518,26 +497,26 @@ namespace ts { return statements; } - function addBlockScopedVariable(name: Identifier): void { - Debug.assert(blockScopeStackOffset > 0, "Cannot add a block scoped variable outside of an iteration body."); + function addBlockScopedVariable(name: ts.Identifier): void { + ts.Debug.assert(blockScopeStackOffset > 0, "Cannot add a block scoped variable outside of an iteration body."); (blockScopedVariableDeclarations || (blockScopedVariableDeclarations = [])).push(name); } - function requestEmitHelper(helper: EmitHelper): void { - Debug.assert(state > TransformationState.Uninitialized, "Cannot modify the transformation context during initialization."); - Debug.assert(state < TransformationState.Completed, "Cannot modify the transformation context after transformation has completed."); - Debug.assert(!helper.scoped, "Cannot request a scoped emit helper."); + function requestEmitHelper(helper: ts.EmitHelper): void { + ts.Debug.assert(state > TransformationState.Uninitialized, "Cannot modify the transformation context during initialization."); + ts.Debug.assert(state < TransformationState.Completed, "Cannot modify the transformation context after transformation has completed."); + ts.Debug.assert(!helper.scoped, "Cannot request a scoped emit helper."); if (helper.dependencies) { for (const h of helper.dependencies) { requestEmitHelper(h); } } - emitHelpers = append(emitHelpers, helper); + emitHelpers = ts.append(emitHelpers, helper); } - function readEmitHelpers(): EmitHelper[] | undefined { - Debug.assert(state > TransformationState.Uninitialized, "Cannot modify the transformation context during initialization."); - Debug.assert(state < TransformationState.Completed, "Cannot modify the transformation context after transformation has completed."); + function readEmitHelpers(): ts.EmitHelper[] | undefined { + ts.Debug.assert(state > TransformationState.Uninitialized, "Cannot modify the transformation context during initialization."); + ts.Debug.assert(state < TransformationState.Completed, "Cannot modify the transformation context after transformation has completed."); const helpers = emitHelpers; emitHelpers = undefined; return helpers; @@ -547,7 +526,7 @@ namespace ts { if (state < TransformationState.Disposed) { // Clean up emit nodes on parse tree for (const node of nodes) { - disposeEmitNodes(getSourceFileOfNode(getParseTreeNode(node))); + ts.disposeEmitNodes(ts.getSourceFileOfNode(ts.getParseTreeNode(node))); } // Release references to external entries for GC purposes. @@ -565,32 +544,32 @@ namespace ts { } } - export const nullTransformationContext: TransformationContext = { - factory: factory, // eslint-disable-line object-shorthand + export const nullTransformationContext: ts.TransformationContext = { + factory: ts.factory, getCompilerOptions: () => ({}), - getEmitResolver: notImplemented, - getEmitHost: notImplemented, - getEmitHelperFactory: notImplemented, - startLexicalEnvironment: noop, - resumeLexicalEnvironment: noop, - suspendLexicalEnvironment: noop, - endLexicalEnvironment: returnUndefined, - setLexicalEnvironmentFlags: noop, + getEmitResolver: ts.notImplemented, + getEmitHost: ts.notImplemented, + getEmitHelperFactory: ts.notImplemented, + startLexicalEnvironment: ts.noop, + resumeLexicalEnvironment: ts.noop, + suspendLexicalEnvironment: ts.noop, + endLexicalEnvironment: ts.returnUndefined, + setLexicalEnvironmentFlags: ts.noop, getLexicalEnvironmentFlags: () => 0, - hoistVariableDeclaration: noop, - hoistFunctionDeclaration: noop, - addInitializationStatement: noop, - startBlockScope: noop, - endBlockScope: returnUndefined, - addBlockScopedVariable: noop, - requestEmitHelper: noop, - readEmitHelpers: notImplemented, - enableSubstitution: noop, - enableEmitNotification: noop, - isSubstitutionEnabled: notImplemented, - isEmitNotificationEnabled: notImplemented, + hoistVariableDeclaration: ts.noop, + hoistFunctionDeclaration: ts.noop, + addInitializationStatement: ts.noop, + startBlockScope: ts.noop, + endBlockScope: ts.returnUndefined, + addBlockScopedVariable: ts.noop, + requestEmitHelper: ts.noop, + readEmitHelpers: ts.notImplemented, + enableSubstitution: ts.noop, + enableEmitNotification: ts.noop, + isSubstitutionEnabled: ts.notImplemented, + isEmitNotificationEnabled: ts.notImplemented, onSubstituteNode: noEmitSubstitution, onEmitNode: noEmitNotification, - addDiagnostic: noop, + addDiagnostic: ts.noop, }; } diff --git a/src/compiler/transformers/classFields.ts b/src/compiler/transformers/classFields.ts index cff2be7fb78b8..6e606463e28c3 100644 --- a/src/compiler/transformers/classFields.ts +++ b/src/compiler/transformers/classFields.ts @@ -10,7 +10,7 @@ namespace ts { * Enables substitutions for class expressions with static fields * which have initializers that reference the 'this' or 'super'. */ - ClassStaticThisOrSuperReference = 1 << 1, + ClassStaticThisOrSuperReference = 1 << 1 } export const enum PrivateIdentifierKind { Field = "f", @@ -24,7 +24,7 @@ namespace ts { * - For instance methods or accessors: The WeakSet that will be used for brand checking. * - For static members: The constructor that will be used for brand checking. */ - brandCheckIdentifier: Identifier; + brandCheckIdentifier: ts.Identifier; /** * Stores if the identifier is static or not */ @@ -40,18 +40,18 @@ namespace ts { /** * Identifier for a variable that will contain the private get accessor implementation, if any. */ - getterName?: Identifier; + getterName?: ts.Identifier; /** * Identifier for a variable that will contain the private set accessor implementation, if any. */ - setterName?: Identifier; + setterName?: ts.Identifier; } interface PrivateIdentifierMethodInfo extends PrivateIdentifierInfoBase { kind: PrivateIdentifierKind.Method; /** * Identifier for a variable that will contain the private method implementation. */ - methodName: Identifier; + methodName: ts.Identifier; } interface PrivateIdentifierInstanceFieldInfo extends PrivateIdentifierInfoBase { kind: PrivateIdentifierKind.Field; @@ -67,14 +67,9 @@ namespace ts { /** * Contains the variable that will server as the storage for the field. */ - variableName: Identifier; + variableName: ts.Identifier; } - - type PrivateIdentifierInfo = - | PrivateIdentifierMethodInfo - | PrivateIdentifierInstanceFieldInfo - | PrivateIdentifierStaticFieldInfo - | PrivateIdentifierAccessorInfo; + type PrivateIdentifierInfo = PrivateIdentifierMethodInfo | PrivateIdentifierInstanceFieldInfo | PrivateIdentifierStaticFieldInfo | PrivateIdentifierAccessorInfo; interface PrivateIdentifierEnvironment { /** @@ -84,11 +79,11 @@ namespace ts { /** * Used for brand check on private methods. */ - weakSetName?: Identifier; + weakSetName?: ts.Identifier; /** * A mapping of private names to information needed for transformation. */ - identifiers: UnderscoreEscapedMap + identifiers: ts.UnderscoreEscapedMap; } interface ClassLexicalEnvironment { @@ -96,11 +91,11 @@ namespace ts { /** * Used for brand checks on static members, and `this` references in static initializers */ - classConstructor: Identifier | undefined; + classConstructor: ts.Identifier | undefined; /** * Used for `super` references in static initializers. */ - superClassReference: Identifier | undefined; + superClassReference: ts.Identifier | undefined; privateIdentifierEnvironment: PrivateIdentifierEnvironment | undefined; } @@ -109,7 +104,7 @@ namespace ts { ClassWasDecorated = 1 << 0, NeedsClassConstructorReference = 1 << 1, NeedsClassSuperReference = 1 << 2, - NeedsSubstitutionForThisInClassStaticField = 1 << 3, + NeedsSubstitutionForThisInClassStaticField = 1 << 3 } /** @@ -119,29 +114,21 @@ namespace ts { * where declarations are elided and initializers are transformed as assignments in the constructor. * When --useDefineForClassFields is on, this transforms to ECMAScript semantics, with Object.defineProperty. */ - export function transformClassFields(context: TransformationContext) { - const { - factory, - hoistVariableDeclaration, - endLexicalEnvironment, - startLexicalEnvironment, - resumeLexicalEnvironment, - addBlockScopedVariable - } = context; + export function transformClassFields(context: ts.TransformationContext) { + const { factory, hoistVariableDeclaration, endLexicalEnvironment, startLexicalEnvironment, resumeLexicalEnvironment, addBlockScopedVariable } = context; const resolver = context.getEmitResolver(); const compilerOptions = context.getCompilerOptions(); - const languageVersion = getEmitScriptTarget(compilerOptions); - const useDefineForClassFields = getUseDefineForClassFields(compilerOptions); - - const shouldTransformPrivateElementsOrClassStaticBlocks = languageVersion < ScriptTarget.ES2022; + const languageVersion = ts.getEmitScriptTarget(compilerOptions); + const useDefineForClassFields = ts.getUseDefineForClassFields(compilerOptions); + const shouldTransformPrivateElementsOrClassStaticBlocks = languageVersion < ts.ScriptTarget.ES2022; // We need to transform `this` in a static initializer into a reference to the class // when targeting < ES2022 since the assignment will be moved outside of the class body. - const shouldTransformThisInStaticInitializers = languageVersion < ScriptTarget.ES2022; + const shouldTransformThisInStaticInitializers = languageVersion < ts.ScriptTarget.ES2022; // We don't need to transform `super` property access when targeting ES5, ES3 because // the es2015 transformation handles those. - const shouldTransformSuperInStaticInitializers = shouldTransformThisInStaticInitializers && languageVersion >= ScriptTarget.ES2015; + const shouldTransformSuperInStaticInitializers = shouldTransformThisInStaticInitializers && languageVersion >= ts.ScriptTarget.ES2015; const previousOnSubstituteNode = context.onSubstituteNode; context.onSubstituteNode = onSubstituteNode; @@ -150,118 +137,116 @@ namespace ts { let enabledSubstitutions: ClassPropertySubstitutionFlags; - let classAliases: Identifier[]; + let classAliases: ts.Identifier[]; /** * Tracks what computed name expressions originating from elided names must be inlined * at the next execution site, in document order */ - let pendingExpressions: Expression[] | undefined; + let pendingExpressions: ts.Expression[] | undefined; /** * Tracks what computed name expression statements and static property initializers must be * emitted at the next execution site, in document order (for decorated classes). */ - let pendingStatements: Statement[] | undefined; + let pendingStatements: ts.Statement[] | undefined; const classLexicalEnvironmentStack: (ClassLexicalEnvironment | undefined)[] = []; - const classLexicalEnvironmentMap = new Map(); + const classLexicalEnvironmentMap = new ts.Map(); let currentClassLexicalEnvironment: ClassLexicalEnvironment | undefined; let currentComputedPropertyNameClassLexicalEnvironment: ClassLexicalEnvironment | undefined; - let currentStaticPropertyDeclarationOrStaticBlock: PropertyDeclaration | ClassStaticBlockDeclaration | undefined; - - return chainBundle(context, transformSourceFile); - - function transformSourceFile(node: SourceFile) { + let currentStaticPropertyDeclarationOrStaticBlock: ts.PropertyDeclaration | ts.ClassStaticBlockDeclaration | undefined; + return ts.chainBundle(context, transformSourceFile); + function transformSourceFile(node: ts.SourceFile) { const options = context.getCompilerOptions(); if (node.isDeclarationFile - || useDefineForClassFields && getEmitScriptTarget(options) >= ScriptTarget.ES2022) { + || useDefineForClassFields && ts.getEmitScriptTarget(options) >= ts.ScriptTarget.ES2022) { return node; } - const visited = visitEachChild(node, visitor, context); - addEmitHelpers(visited, context.readEmitHelpers()); + const visited = ts.visitEachChild(node, visitor, context); + ts.addEmitHelpers(visited, context.readEmitHelpers()); return visited; } - function visitorWorker(node: Node, valueIsDiscarded: boolean): VisitResult { - if (node.transformFlags & TransformFlags.ContainsClassFields) { + function visitorWorker(node: ts.Node, valueIsDiscarded: boolean): ts.VisitResult { + if (node.transformFlags & ts.TransformFlags.ContainsClassFields) { switch (node.kind) { - case SyntaxKind.ClassExpression: - case SyntaxKind.ClassDeclaration: - return visitClassLike(node as ClassLikeDeclaration); - case SyntaxKind.PropertyDeclaration: - return visitPropertyDeclaration(node as PropertyDeclaration); - case SyntaxKind.VariableStatement: - return visitVariableStatement(node as VariableStatement); - case SyntaxKind.PrivateIdentifier: - return visitPrivateIdentifier(node as PrivateIdentifier); - case SyntaxKind.ClassStaticBlockDeclaration: - return visitClassStaticBlockDeclaration(node as ClassStaticBlockDeclaration); + case ts.SyntaxKind.ClassExpression: + case ts.SyntaxKind.ClassDeclaration: + return visitClassLike(node as ts.ClassLikeDeclaration); + case ts.SyntaxKind.PropertyDeclaration: + return visitPropertyDeclaration(node as ts.PropertyDeclaration); + case ts.SyntaxKind.VariableStatement: + return visitVariableStatement(node as ts.VariableStatement); + case ts.SyntaxKind.PrivateIdentifier: + return visitPrivateIdentifier(node as ts.PrivateIdentifier); + case ts.SyntaxKind.ClassStaticBlockDeclaration: + return visitClassStaticBlockDeclaration(node as ts.ClassStaticBlockDeclaration); } } - if (node.transformFlags & TransformFlags.ContainsClassFields || - node.transformFlags & TransformFlags.ContainsLexicalSuper && + if (node.transformFlags & ts.TransformFlags.ContainsClassFields || + node.transformFlags & ts.TransformFlags.ContainsLexicalSuper && shouldTransformSuperInStaticInitializers && currentStaticPropertyDeclarationOrStaticBlock && currentClassLexicalEnvironment) { switch (node.kind) { - case SyntaxKind.PrefixUnaryExpression: - case SyntaxKind.PostfixUnaryExpression: - return visitPreOrPostfixUnaryExpression(node as PrefixUnaryExpression | PostfixUnaryExpression, valueIsDiscarded); - case SyntaxKind.BinaryExpression: - return visitBinaryExpression(node as BinaryExpression, valueIsDiscarded); - case SyntaxKind.CallExpression: - return visitCallExpression(node as CallExpression); - case SyntaxKind.TaggedTemplateExpression: - return visitTaggedTemplateExpression(node as TaggedTemplateExpression); - case SyntaxKind.PropertyAccessExpression: - return visitPropertyAccessExpression(node as PropertyAccessExpression); - case SyntaxKind.ElementAccessExpression: - return visitElementAccessExpression(node as ElementAccessExpression); - case SyntaxKind.ExpressionStatement: - return visitExpressionStatement(node as ExpressionStatement); - case SyntaxKind.ForStatement: - return visitForStatement(node as ForStatement); - case SyntaxKind.FunctionDeclaration: - case SyntaxKind.FunctionExpression: - case SyntaxKind.Constructor: - case SyntaxKind.MethodDeclaration: - case SyntaxKind.GetAccessor: - case SyntaxKind.SetAccessor: { + case ts.SyntaxKind.PrefixUnaryExpression: + case ts.SyntaxKind.PostfixUnaryExpression: + return visitPreOrPostfixUnaryExpression(node as ts.PrefixUnaryExpression | ts.PostfixUnaryExpression, valueIsDiscarded); + case ts.SyntaxKind.BinaryExpression: + return visitBinaryExpression(node as ts.BinaryExpression, valueIsDiscarded); + case ts.SyntaxKind.CallExpression: + return visitCallExpression(node as ts.CallExpression); + case ts.SyntaxKind.TaggedTemplateExpression: + return visitTaggedTemplateExpression(node as ts.TaggedTemplateExpression); + case ts.SyntaxKind.PropertyAccessExpression: + return visitPropertyAccessExpression(node as ts.PropertyAccessExpression); + case ts.SyntaxKind.ElementAccessExpression: + return visitElementAccessExpression(node as ts.ElementAccessExpression); + case ts.SyntaxKind.ExpressionStatement: + return visitExpressionStatement(node as ts.ExpressionStatement); + case ts.SyntaxKind.ForStatement: + return visitForStatement(node as ts.ForStatement); + case ts.SyntaxKind.FunctionDeclaration: + case ts.SyntaxKind.FunctionExpression: + case ts.SyntaxKind.Constructor: + case ts.SyntaxKind.MethodDeclaration: + case ts.SyntaxKind.GetAccessor: + case ts.SyntaxKind.SetAccessor: { const savedCurrentStaticPropertyDeclarationOrStaticBlock = currentStaticPropertyDeclarationOrStaticBlock; currentStaticPropertyDeclarationOrStaticBlock = undefined; - const result = visitEachChild(node, visitor, context); + const result = ts.visitEachChild(node, visitor, context); currentStaticPropertyDeclarationOrStaticBlock = savedCurrentStaticPropertyDeclarationOrStaticBlock; return result; } } } - return visitEachChild(node, visitor, context); + return ts.visitEachChild(node, visitor, context); } - function discardedValueVisitor(node: Node): VisitResult { + function discardedValueVisitor(node: ts.Node): ts.VisitResult { return visitorWorker(node, /*valueIsDiscarded*/ true); } - function visitor(node: Node): VisitResult { + function visitor(node: ts.Node): ts.VisitResult { return visitorWorker(node, /*valueIsDiscarded*/ false); } - function heritageClauseVisitor(node: Node): VisitResult { + function heritageClauseVisitor(node: ts.Node): ts.VisitResult { switch (node.kind) { - case SyntaxKind.HeritageClause: - return visitEachChild(node, heritageClauseVisitor, context); - case SyntaxKind.ExpressionWithTypeArguments: - return visitExpressionWithTypeArguments(node as ExpressionWithTypeArguments); + case ts.SyntaxKind.HeritageClause: + return ts.visitEachChild(node, heritageClauseVisitor, context); + case ts.SyntaxKind.ExpressionWithTypeArguments: + return visitExpressionWithTypeArguments(node as ts.ExpressionWithTypeArguments); } return visitor(node); } - function visitorDestructuringTarget(node: Node): VisitResult { + function visitorDestructuringTarget(node: ts.Node): ts.VisitResult { switch (node.kind) { - case SyntaxKind.ObjectLiteralExpression: - case SyntaxKind.ArrayLiteralExpression: - return visitAssignmentPattern(node as AssignmentPattern); + case ts.SyntaxKind.ObjectLiteralExpression: + case ts.SyntaxKind.ArrayLiteralExpression: + return visitAssignmentPattern(node as ts.AssignmentPattern); default: return visitor(node); } @@ -273,38 +258,34 @@ namespace ts { * unless we are in a statement position - otherwise this will not trigger * a SyntaxError. */ - function visitPrivateIdentifier(node: PrivateIdentifier) { + function visitPrivateIdentifier(node: ts.PrivateIdentifier) { if (!shouldTransformPrivateElementsOrClassStaticBlocks) { return node; } - if (isStatement(node.parent)) { + if (ts.isStatement(node.parent)) { return node; } - return setOriginalNode(factory.createIdentifier(""), node); + return ts.setOriginalNode(factory.createIdentifier(""), node); } /** * Visits `#id in expr` */ - function visitPrivateIdentifierInInExpression(node: BinaryExpression) { + function visitPrivateIdentifierInInExpression(node: ts.BinaryExpression) { if (!shouldTransformPrivateElementsOrClassStaticBlocks) { return node; } const privId = node.left; - Debug.assertNode(privId, isPrivateIdentifier); - Debug.assert(node.operatorToken.kind === SyntaxKind.InKeyword); + ts.Debug.assertNode(privId, ts.isPrivateIdentifier); + ts.Debug.assert(node.operatorToken.kind === ts.SyntaxKind.InKeyword); const info = accessPrivateIdentifier(privId); if (info) { - const receiver = visitNode(node.right, visitor, isExpression); - - return setOriginalNode( - context.getEmitHelperFactory().createClassPrivateFieldInHelper(info.brandCheckIdentifier, receiver), - node - ); + const receiver = ts.visitNode(node.right, visitor, ts.isExpression); + return ts.setOriginalNode(context.getEmitHelperFactory().createClassPrivateFieldInHelper(info.brandCheckIdentifier, receiver), node); } // Private name has not been declared. Subsequent transformers will handle this error - return visitEachChild(node, visitor, context); + return ts.visitEachChild(node, visitor, context); } /** @@ -312,25 +293,22 @@ namespace ts { * * @param node The node to visit. */ - function classElementVisitor(node: Node): VisitResult { + function classElementVisitor(node: ts.Node): ts.VisitResult { switch (node.kind) { - case SyntaxKind.Constructor: + case ts.SyntaxKind.Constructor: // Constructors for classes using class fields are transformed in // `visitClassDeclaration` or `visitClassExpression`. return undefined; - case SyntaxKind.GetAccessor: - case SyntaxKind.SetAccessor: - case SyntaxKind.MethodDeclaration: - return visitMethodOrAccessorDeclaration(node as MethodDeclaration | AccessorDeclaration); - - case SyntaxKind.PropertyDeclaration: - return visitPropertyDeclaration(node as PropertyDeclaration); - - case SyntaxKind.ComputedPropertyName: - return visitComputedPropertyName(node as ComputedPropertyName); - - case SyntaxKind.SemicolonClassElement: + case ts.SyntaxKind.GetAccessor: + case ts.SyntaxKind.SetAccessor: + case ts.SyntaxKind.MethodDeclaration: + return visitMethodOrAccessorDeclaration(node as ts.MethodDeclaration | ts.AccessorDeclaration); + case ts.SyntaxKind.PropertyDeclaration: + return visitPropertyDeclaration(node as ts.PropertyDeclaration); + case ts.SyntaxKind.ComputedPropertyName: + return visitComputedPropertyName(node as ts.ComputedPropertyName); + case ts.SyntaxKind.SemicolonClassElement: return node; default: @@ -338,12 +316,12 @@ namespace ts { } } - function visitVariableStatement(node: VariableStatement) { + function visitVariableStatement(node: ts.VariableStatement) { const savedPendingStatements = pendingStatements; pendingStatements = []; - const visitedNode = visitEachChild(node, visitor, context); - const statement = some(pendingStatements) ? + const visitedNode = ts.visitEachChild(node, visitor, context); + const statement = ts.some(pendingStatements) ? [visitedNode, ...pendingStatements] : visitedNode; @@ -351,100 +329,80 @@ namespace ts { return statement; } - function visitComputedPropertyName(name: ComputedPropertyName) { - let node = visitEachChild(name, visitor, context); - if (some(pendingExpressions)) { + function visitComputedPropertyName(name: ts.ComputedPropertyName) { + let node = ts.visitEachChild(name, visitor, context); + if (ts.some(pendingExpressions)) { const expressions = pendingExpressions; expressions.push(node.expression); pendingExpressions = []; - node = factory.updateComputedPropertyName( - node, - factory.inlineExpressions(expressions) - ); + node = factory.updateComputedPropertyName(node, factory.inlineExpressions(expressions)); } return node; } - function visitMethodOrAccessorDeclaration(node: MethodDeclaration | AccessorDeclaration) { - Debug.assert(!some(node.decorators)); - - if (!shouldTransformPrivateElementsOrClassStaticBlocks || !isPrivateIdentifier(node.name)) { - return visitEachChild(node, classElementVisitor, context); + function visitMethodOrAccessorDeclaration(node: ts.MethodDeclaration | ts.AccessorDeclaration) { + ts.Debug.assert(!ts.some(node.decorators)); + if (!shouldTransformPrivateElementsOrClassStaticBlocks || !ts.isPrivateIdentifier(node.name)) { + return ts.visitEachChild(node, classElementVisitor, context); } // leave invalid code untransformed const info = accessPrivateIdentifier(node.name); - Debug.assert(info, "Undeclared private name for property declaration."); + ts.Debug.assert(info, "Undeclared private name for property declaration."); if (!info.isValid) { return node; } const functionName = getHoistedFunctionName(node); if (functionName) { - getPendingExpressions().push( - factory.createAssignment( - functionName, - factory.createFunctionExpression( - filter(node.modifiers, m => !isStaticModifier(m)), - node.asteriskToken, - functionName, - /* typeParameters */ undefined, - visitParameterList(node.parameters, classElementVisitor, context), - /* type */ undefined, - visitFunctionBody(node.body!, classElementVisitor, context) - ) - ) - ); + getPendingExpressions().push(factory.createAssignment(functionName, factory.createFunctionExpression(ts.filter(node.modifiers, m => !ts.isStaticModifier(m)), node.asteriskToken, functionName, + /* typeParameters */ undefined, ts.visitParameterList(node.parameters, classElementVisitor, context), + /* type */ undefined, ts.visitFunctionBody(node.body!, classElementVisitor, context)))); } // remove method declaration from class return undefined; } - function getHoistedFunctionName(node: MethodDeclaration | AccessorDeclaration) { - Debug.assert(isPrivateIdentifier(node.name)); + function getHoistedFunctionName(node: ts.MethodDeclaration | ts.AccessorDeclaration) { + ts.Debug.assert(ts.isPrivateIdentifier(node.name)); const info = accessPrivateIdentifier(node.name); - Debug.assert(info, "Undeclared private name for property declaration."); + ts.Debug.assert(info, "Undeclared private name for property declaration."); if (info.kind === PrivateIdentifierKind.Method) { return info.methodName; } if (info.kind === PrivateIdentifierKind.Accessor) { - if (isGetAccessor(node)) { + if (ts.isGetAccessor(node)) { return info.getterName; } - if (isSetAccessor(node)) { + if (ts.isSetAccessor(node)) { return info.setterName; } } } - function visitPropertyDeclaration(node: PropertyDeclaration) { - Debug.assert(!some(node.decorators)); - - if (isPrivateIdentifier(node.name)) { + function visitPropertyDeclaration(node: ts.PropertyDeclaration) { + ts.Debug.assert(!ts.some(node.decorators)); + if (ts.isPrivateIdentifier(node.name)) { if (!shouldTransformPrivateElementsOrClassStaticBlocks) { - if (isStatic(node)) { + if (ts.isStatic(node)) { // static fields are left as is - return visitEachChild(node, visitor, context); + return ts.visitEachChild(node, visitor, context); } // Initializer is elided as the field is initialized in transformConstructor. - return factory.updatePropertyDeclaration( - node, - /*decorators*/ undefined, - visitNodes(node.modifiers, visitor, isModifier), - node.name, + return factory.updatePropertyDeclaration(node, + /*decorators*/ undefined, ts.visitNodes(node.modifiers, visitor, ts.isModifier), node.name, /*questionOrExclamationToken*/ undefined, /*type*/ undefined, - /*initializer*/ undefined - ); + /*initializer*/ undefined); } // leave invalid code untransformed const info = accessPrivateIdentifier(node.name); - Debug.assert(info, "Undeclared private name for property declaration."); + ts.Debug.assert(info, "Undeclared private name for property declaration."); if (!info.isValid) { return node; } @@ -453,27 +411,24 @@ namespace ts { // If it's not inlineable, then we emit an expression after the class which assigns // the property name to the temporary variable. const expr = getPropertyNameExpressionIfNeeded(node.name, !!node.initializer || useDefineForClassFields); - if (expr && !isSimpleInlineableExpression(expr)) { + if (expr && !ts.isSimpleInlineableExpression(expr)) { getPendingExpressions().push(expr); } - if (isStatic(node) && !shouldTransformPrivateElementsOrClassStaticBlocks && !useDefineForClassFields) { + if (ts.isStatic(node) && !shouldTransformPrivateElementsOrClassStaticBlocks && !useDefineForClassFields) { const initializerStatement = transformPropertyOrClassStaticBlock(node, factory.createThis()); if (initializerStatement) { const staticBlock = factory.createClassStaticBlockDeclaration( /*decorators*/ undefined, - /*modifiers*/ undefined, - factory.createBlock([initializerStatement]) - ); - - setOriginalNode(staticBlock, node); - setCommentRange(staticBlock, node); + /*modifiers*/ undefined, factory.createBlock([initializerStatement])); + ts.setOriginalNode(staticBlock, node); + ts.setCommentRange(staticBlock, node); // Set the comment range for the statement to an empty synthetic range // and drop synthetic comments from the statement to avoid printing them twice. - setCommentRange(initializerStatement, { pos: -1, end: -1 }); - setSyntheticLeadingComments(initializerStatement, undefined); - setSyntheticTrailingComments(initializerStatement, undefined); + ts.setCommentRange(initializerStatement, { pos: -1, end: -1 }); + ts.setSyntheticLeadingComments(initializerStatement, undefined); + ts.setSyntheticTrailingComments(initializerStatement, undefined); return staticBlock; } } @@ -481,56 +436,35 @@ namespace ts { return undefined; } - function createPrivateIdentifierAccess(info: PrivateIdentifierInfo, receiver: Expression): Expression { - return createPrivateIdentifierAccessHelper(info, visitNode(receiver, visitor, isExpression)); + function createPrivateIdentifierAccess(info: PrivateIdentifierInfo, receiver: ts.Expression): ts.Expression { + return createPrivateIdentifierAccessHelper(info, ts.visitNode(receiver, visitor, ts.isExpression)); } - function createPrivateIdentifierAccessHelper(info: PrivateIdentifierInfo, receiver: Expression): Expression { - setCommentRange(receiver, moveRangePos(receiver, -1)); + function createPrivateIdentifierAccessHelper(info: PrivateIdentifierInfo, receiver: ts.Expression): ts.Expression { + ts.setCommentRange(receiver, ts.moveRangePos(receiver, -1)); switch(info.kind) { case PrivateIdentifierKind.Accessor: - return context.getEmitHelperFactory().createClassPrivateFieldGetHelper( - receiver, - info.brandCheckIdentifier, - info.kind, - info.getterName - ); + return context.getEmitHelperFactory().createClassPrivateFieldGetHelper(receiver, info.brandCheckIdentifier, info.kind, info.getterName); case PrivateIdentifierKind.Method: - return context.getEmitHelperFactory().createClassPrivateFieldGetHelper( - receiver, - info.brandCheckIdentifier, - info.kind, - info.methodName - ); + return context.getEmitHelperFactory().createClassPrivateFieldGetHelper(receiver, info.brandCheckIdentifier, info.kind, info.methodName); case PrivateIdentifierKind.Field: - return context.getEmitHelperFactory().createClassPrivateFieldGetHelper( - receiver, - info.brandCheckIdentifier, - info.kind, - info.variableName - ); + return context.getEmitHelperFactory().createClassPrivateFieldGetHelper(receiver, info.brandCheckIdentifier, info.kind, info.variableName); default: - Debug.assertNever(info, "Unknown private element type"); + ts.Debug.assertNever(info, "Unknown private element type"); } } - function visitPropertyAccessExpression(node: PropertyAccessExpression) { - if (shouldTransformPrivateElementsOrClassStaticBlocks && isPrivateIdentifier(node.name)) { + function visitPropertyAccessExpression(node: ts.PropertyAccessExpression) { + if (shouldTransformPrivateElementsOrClassStaticBlocks && ts.isPrivateIdentifier(node.name)) { const privateIdentifierInfo = accessPrivateIdentifier(node.name); if (privateIdentifierInfo) { - return setTextRange( - setOriginalNode( - createPrivateIdentifierAccess(privateIdentifierInfo, node.expression), - node - ), - node - ); + return ts.setTextRange(ts.setOriginalNode(createPrivateIdentifierAccess(privateIdentifierInfo, node.expression), node), node); } } if (shouldTransformSuperInStaticInitializers && - isSuperProperty(node) && - isIdentifier(node.name) && + ts.isSuperProperty(node) && + ts.isIdentifier(node.name) && currentStaticPropertyDeclarationOrStaticBlock && currentClassLexicalEnvironment) { const { classConstructor, superClassReference, facts } = currentClassLexicalEnvironment; @@ -539,22 +473,18 @@ namespace ts { } if (classConstructor && superClassReference) { // converts `super.x` into `Reflect.get(_baseTemp, "x", _classTemp)` - const superProperty = factory.createReflectGetCall( - superClassReference, - factory.createStringLiteralFromNode(node.name), - classConstructor - ); - setOriginalNode(superProperty, node.expression); - setTextRange(superProperty, node.expression); + const superProperty = factory.createReflectGetCall(superClassReference, factory.createStringLiteralFromNode(node.name), classConstructor); + ts.setOriginalNode(superProperty, node.expression); + ts.setTextRange(superProperty, node.expression); return superProperty; } } - return visitEachChild(node, visitor, context); + return ts.visitEachChild(node, visitor, context); } - function visitElementAccessExpression(node: ElementAccessExpression) { + function visitElementAccessExpression(node: ts.ElementAccessExpression) { if (shouldTransformSuperInStaticInitializers && - isSuperProperty(node) && + ts.isSuperProperty(node) && currentStaticPropertyDeclarationOrStaticBlock && currentClassLexicalEnvironment) { const { classConstructor, superClassReference, facts } = currentClassLexicalEnvironment; @@ -564,47 +494,38 @@ namespace ts { if (classConstructor && superClassReference) { // converts `super[x]` into `Reflect.get(_baseTemp, x, _classTemp)` - const superProperty = factory.createReflectGetCall( - superClassReference, - visitNode(node.argumentExpression, visitor, isExpression), - classConstructor - ); - setOriginalNode(superProperty, node.expression); - setTextRange(superProperty, node.expression); + const superProperty = factory.createReflectGetCall(superClassReference, ts.visitNode(node.argumentExpression, visitor, ts.isExpression), classConstructor); + ts.setOriginalNode(superProperty, node.expression); + ts.setTextRange(superProperty, node.expression); return superProperty; } } - return visitEachChild(node, visitor, context); + return ts.visitEachChild(node, visitor, context); } - function visitPreOrPostfixUnaryExpression(node: PrefixUnaryExpression | PostfixUnaryExpression, valueIsDiscarded: boolean) { - if (node.operator === SyntaxKind.PlusPlusToken || node.operator === SyntaxKind.MinusMinusToken) { - if (shouldTransformPrivateElementsOrClassStaticBlocks && isPrivateIdentifierPropertyAccessExpression(node.operand)) { + function visitPreOrPostfixUnaryExpression(node: ts.PrefixUnaryExpression | ts.PostfixUnaryExpression, valueIsDiscarded: boolean) { + if (node.operator === ts.SyntaxKind.PlusPlusToken || node.operator === ts.SyntaxKind.MinusMinusToken) { + if (shouldTransformPrivateElementsOrClassStaticBlocks && ts.isPrivateIdentifierPropertyAccessExpression(node.operand)) { let info: PrivateIdentifierInfo | undefined; if (info = accessPrivateIdentifier(node.operand.name)) { - const receiver = visitNode(node.operand.expression, visitor, isExpression); + const receiver = ts.visitNode(node.operand.expression, visitor, ts.isExpression); const { readExpression, initializeExpression } = createCopiableReceiverExpr(receiver); - let expression: Expression = createPrivateIdentifierAccess(info, readExpression); - const temp = isPrefixUnaryExpression(node) || valueIsDiscarded ? undefined : factory.createTempVariable(hoistVariableDeclaration); - expression = expandPreOrPostfixIncrementOrDecrementExpression(factory, node, expression, hoistVariableDeclaration, temp); - expression = createPrivateIdentifierAssignment( - info, - initializeExpression || readExpression, - expression, - SyntaxKind.EqualsToken - ); - setOriginalNode(expression, node); - setTextRange(expression, node); + let expression: ts.Expression = createPrivateIdentifierAccess(info, readExpression); + const temp = ts.isPrefixUnaryExpression(node) || valueIsDiscarded ? undefined : factory.createTempVariable(hoistVariableDeclaration); + expression = ts.expandPreOrPostfixIncrementOrDecrementExpression(factory, node, expression, hoistVariableDeclaration, temp); + expression = createPrivateIdentifierAssignment(info, initializeExpression || readExpression, expression, ts.SyntaxKind.EqualsToken); + ts.setOriginalNode(expression, node); + ts.setTextRange(expression, node); if (temp) { expression = factory.createComma(expression, temp); - setTextRange(expression, node); + ts.setTextRange(expression, node); } return expression; } } else if (shouldTransformSuperInStaticInitializers && - isSuperProperty(node.operand) && + ts.isSuperProperty(node.operand) && currentStaticPropertyDeclarationOrStaticBlock && currentClassLexicalEnvironment) { // converts `++super.a` into `(Reflect.set(_baseTemp, "a", (_a = Reflect.get(_baseTemp, "a", _classTemp), _b = ++_a), _classTemp), _b)` @@ -618,68 +539,62 @@ namespace ts { const { classConstructor, superClassReference, facts } = currentClassLexicalEnvironment; if (facts & ClassFacts.ClassWasDecorated) { const operand = visitInvalidSuperProperty(node.operand); - return isPrefixUnaryExpression(node) ? + return ts.isPrefixUnaryExpression(node) ? factory.updatePrefixUnaryExpression(node, operand) : factory.updatePostfixUnaryExpression(node, operand); } if (classConstructor && superClassReference) { - let setterName: Expression | undefined; - let getterName: Expression | undefined; - if (isPropertyAccessExpression(node.operand)) { - if (isIdentifier(node.operand.name)) { + let setterName: ts.Expression | undefined; + let getterName: ts.Expression | undefined; + if (ts.isPropertyAccessExpression(node.operand)) { + if (ts.isIdentifier(node.operand.name)) { getterName = setterName = factory.createStringLiteralFromNode(node.operand.name); } } else { - if (isSimpleInlineableExpression(node.operand.argumentExpression)) { + if (ts.isSimpleInlineableExpression(node.operand.argumentExpression)) { getterName = setterName = node.operand.argumentExpression; } else { getterName = factory.createTempVariable(hoistVariableDeclaration); - setterName = factory.createAssignment(getterName, visitNode(node.operand.argumentExpression, visitor, isExpression)); + setterName = factory.createAssignment(getterName, ts.visitNode(node.operand.argumentExpression, visitor, ts.isExpression)); } } if (setterName && getterName) { - let expression: Expression = factory.createReflectGetCall(superClassReference, getterName, classConstructor); - setTextRange(expression, node.operand); + let expression: ts.Expression = factory.createReflectGetCall(superClassReference, getterName, classConstructor); + ts.setTextRange(expression, node.operand); const temp = valueIsDiscarded ? undefined : factory.createTempVariable(hoistVariableDeclaration); - expression = expandPreOrPostfixIncrementOrDecrementExpression(factory, node, expression, hoistVariableDeclaration, temp); + expression = ts.expandPreOrPostfixIncrementOrDecrementExpression(factory, node, expression, hoistVariableDeclaration, temp); expression = factory.createReflectSetCall(superClassReference, setterName, expression, classConstructor); - setOriginalNode(expression, node); - setTextRange(expression, node); + ts.setOriginalNode(expression, node); + ts.setTextRange(expression, node); if (temp) { expression = factory.createComma(expression, temp); - setTextRange(expression, node); + ts.setTextRange(expression, node); } return expression; } } } } - return visitEachChild(node, visitor, context); + return ts.visitEachChild(node, visitor, context); } - function visitForStatement(node: ForStatement) { - return factory.updateForStatement( - node, - visitNode(node.initializer, discardedValueVisitor, isForInitializer), - visitNode(node.condition, visitor, isExpression), - visitNode(node.incrementor, discardedValueVisitor, isExpression), - visitIterationBody(node.statement, visitor, context) - ); + function visitForStatement(node: ts.ForStatement) { + return factory.updateForStatement(node, ts.visitNode(node.initializer, discardedValueVisitor, ts.isForInitializer), ts.visitNode(node.condition, visitor, ts.isExpression), ts.visitNode(node.incrementor, discardedValueVisitor, ts.isExpression), ts.visitIterationBody(node.statement, visitor, context)); } - function visitExpressionStatement(node: ExpressionStatement) { - return factory.updateExpressionStatement( - node, - visitNode(node.expression, discardedValueVisitor, isExpression) - ); + function visitExpressionStatement(node: ts.ExpressionStatement) { + return factory.updateExpressionStatement(node, ts.visitNode(node.expression, discardedValueVisitor, ts.isExpression)); } - function createCopiableReceiverExpr(receiver: Expression): { readExpression: Expression; initializeExpression: Expression | undefined } { - const clone = nodeIsSynthesized(receiver) ? receiver : factory.cloneNode(receiver); - if (isSimpleInlineableExpression(receiver)) { + function createCopiableReceiverExpr(receiver: ts.Expression): { + readExpression: ts.Expression; + initializeExpression: ts.Expression | undefined; + } { + const clone = ts.nodeIsSynthesized(receiver) ? receiver : factory.cloneNode(receiver); + if (ts.isSimpleInlineableExpression(receiver)) { return { readExpression: clone, initializeExpression: undefined }; } const readExpression = factory.createTempVariable(hoistVariableDeclaration); @@ -687,150 +602,106 @@ namespace ts { return { readExpression, initializeExpression }; } - function visitCallExpression(node: CallExpression) { - if (shouldTransformPrivateElementsOrClassStaticBlocks && isPrivateIdentifierPropertyAccessExpression(node.expression)) { + function visitCallExpression(node: ts.CallExpression) { + if (shouldTransformPrivateElementsOrClassStaticBlocks && ts.isPrivateIdentifierPropertyAccessExpression(node.expression)) { // Transform call expressions of private names to properly bind the `this` parameter. const { thisArg, target } = factory.createCallBinding(node.expression, hoistVariableDeclaration, languageVersion); - if (isCallChain(node)) { - return factory.updateCallChain( - node, - factory.createPropertyAccessChain(visitNode(target, visitor), node.questionDotToken, "call"), + if (ts.isCallChain(node)) { + return factory.updateCallChain(node, factory.createPropertyAccessChain(ts.visitNode(target, visitor), node.questionDotToken, "call"), /*questionDotToken*/ undefined, - /*typeArguments*/ undefined, - [visitNode(thisArg, visitor, isExpression), ...visitNodes(node.arguments, visitor, isExpression)] - ); + /*typeArguments*/ undefined, [ts.visitNode(thisArg, visitor, ts.isExpression), ...ts.visitNodes(node.arguments, visitor, ts.isExpression)]); } - return factory.updateCallExpression( - node, - factory.createPropertyAccessExpression(visitNode(target, visitor), "call"), - /*typeArguments*/ undefined, - [visitNode(thisArg, visitor, isExpression), ...visitNodes(node.arguments, visitor, isExpression)] - ); + return factory.updateCallExpression(node, factory.createPropertyAccessExpression(ts.visitNode(target, visitor), "call"), + /*typeArguments*/ undefined, [ts.visitNode(thisArg, visitor, ts.isExpression), ...ts.visitNodes(node.arguments, visitor, ts.isExpression)]); } if (shouldTransformSuperInStaticInitializers && - isSuperProperty(node.expression) && + ts.isSuperProperty(node.expression) && currentStaticPropertyDeclarationOrStaticBlock && currentClassLexicalEnvironment?.classConstructor) { // converts `super.f(...)` into `Reflect.get(_baseTemp, "f", _classTemp).call(_classTemp, ...)` - const invocation = factory.createFunctionCallCall( - visitNode(node.expression, visitor, isExpression), - currentClassLexicalEnvironment.classConstructor, - visitNodes(node.arguments, visitor, isExpression) - ); - setOriginalNode(invocation, node); - setTextRange(invocation, node); + const invocation = factory.createFunctionCallCall(ts.visitNode(node.expression, visitor, ts.isExpression), currentClassLexicalEnvironment.classConstructor, ts.visitNodes(node.arguments, visitor, ts.isExpression)); + ts.setOriginalNode(invocation, node); + ts.setTextRange(invocation, node); return invocation; } - return visitEachChild(node, visitor, context); + return ts.visitEachChild(node, visitor, context); } - function visitTaggedTemplateExpression(node: TaggedTemplateExpression) { - if (shouldTransformPrivateElementsOrClassStaticBlocks && isPrivateIdentifierPropertyAccessExpression(node.tag)) { + function visitTaggedTemplateExpression(node: ts.TaggedTemplateExpression) { + if (shouldTransformPrivateElementsOrClassStaticBlocks && ts.isPrivateIdentifierPropertyAccessExpression(node.tag)) { // Bind the `this` correctly for tagged template literals when the tag is a private identifier property access. const { thisArg, target } = factory.createCallBinding(node.tag, hoistVariableDeclaration, languageVersion); - return factory.updateTaggedTemplateExpression( - node, - factory.createCallExpression( - factory.createPropertyAccessExpression(visitNode(target, visitor), "bind"), - /*typeArguments*/ undefined, - [visitNode(thisArg, visitor, isExpression)] - ), - /*typeArguments*/ undefined, - visitNode(node.template, visitor, isTemplateLiteral) - ); + return factory.updateTaggedTemplateExpression(node, factory.createCallExpression(factory.createPropertyAccessExpression(ts.visitNode(target, visitor), "bind"), + /*typeArguments*/ undefined, [ts.visitNode(thisArg, visitor, ts.isExpression)]), + /*typeArguments*/ undefined, ts.visitNode(node.template, visitor, ts.isTemplateLiteral)); } if (shouldTransformSuperInStaticInitializers && - isSuperProperty(node.tag) && + ts.isSuperProperty(node.tag) && currentStaticPropertyDeclarationOrStaticBlock && currentClassLexicalEnvironment?.classConstructor) { // converts `` super.f`x` `` into `` Reflect.get(_baseTemp, "f", _classTemp).bind(_classTemp)`x` `` - const invocation = factory.createFunctionBindCall( - visitNode(node.tag, visitor, isExpression), - currentClassLexicalEnvironment.classConstructor, - [] - ); - setOriginalNode(invocation, node); - setTextRange(invocation, node); - return factory.updateTaggedTemplateExpression( - node, - invocation, - /*typeArguments*/ undefined, - visitNode(node.template, visitor, isTemplateLiteral) - ); - } - return visitEachChild(node, visitor, context); - } - - function transformClassStaticBlockDeclaration(node: ClassStaticBlockDeclaration) { + const invocation = factory.createFunctionBindCall(ts.visitNode(node.tag, visitor, ts.isExpression), currentClassLexicalEnvironment.classConstructor, []); + ts.setOriginalNode(invocation, node); + ts.setTextRange(invocation, node); + return factory.updateTaggedTemplateExpression(node, invocation, + /*typeArguments*/ undefined, ts.visitNode(node.template, visitor, ts.isTemplateLiteral)); + } + return ts.visitEachChild(node, visitor, context); + } + function transformClassStaticBlockDeclaration(node: ts.ClassStaticBlockDeclaration) { if (shouldTransformPrivateElementsOrClassStaticBlocks) { if (currentClassLexicalEnvironment) { - classLexicalEnvironmentMap.set(getOriginalNodeId(node), currentClassLexicalEnvironment); + classLexicalEnvironmentMap.set(ts.getOriginalNodeId(node), currentClassLexicalEnvironment); } startLexicalEnvironment(); const savedCurrentStaticPropertyDeclarationOrStaticBlock = currentStaticPropertyDeclarationOrStaticBlock; currentStaticPropertyDeclarationOrStaticBlock = node; - let statements = visitNodes(node.body.statements, visitor, isStatement); + let statements = ts.visitNodes(node.body.statements, visitor, ts.isStatement); statements = factory.mergeLexicalEnvironment(statements, endLexicalEnvironment()); currentStaticPropertyDeclarationOrStaticBlock = savedCurrentStaticPropertyDeclarationOrStaticBlock; const iife = factory.createImmediatelyInvokedArrowFunction(statements); - setOriginalNode(iife, node); - setTextRange(iife, node); - addEmitFlags(iife, EmitFlags.AdviseOnEmitNode); + ts.setOriginalNode(iife, node); + ts.setTextRange(iife, node); + ts.addEmitFlags(iife, ts.EmitFlags.AdviseOnEmitNode); return iife; } } - function visitBinaryExpression(node: BinaryExpression, valueIsDiscarded: boolean) { - if (isDestructuringAssignment(node)) { + function visitBinaryExpression(node: ts.BinaryExpression, valueIsDiscarded: boolean) { + if (ts.isDestructuringAssignment(node)) { const savedPendingExpressions = pendingExpressions; pendingExpressions = undefined; - node = factory.updateBinaryExpression( - node, - visitNode(node.left, visitorDestructuringTarget), - node.operatorToken, - visitNode(node.right, visitor) - ); - const expr = some(pendingExpressions) ? - factory.inlineExpressions(compact([...pendingExpressions, node])) : + node = factory.updateBinaryExpression(node, ts.visitNode(node.left, visitorDestructuringTarget), node.operatorToken, ts.visitNode(node.right, visitor)); + const expr = ts.some(pendingExpressions) ? + factory.inlineExpressions(ts.compact([...pendingExpressions, node])) : node; pendingExpressions = savedPendingExpressions; return expr; } - if (isAssignmentExpression(node)) { - if (shouldTransformPrivateElementsOrClassStaticBlocks && isPrivateIdentifierPropertyAccessExpression(node.left)) { + if (ts.isAssignmentExpression(node)) { + if (shouldTransformPrivateElementsOrClassStaticBlocks && ts.isPrivateIdentifierPropertyAccessExpression(node.left)) { const info = accessPrivateIdentifier(node.left.name); if (info) { - return setTextRange( - setOriginalNode( - createPrivateIdentifierAssignment(info, node.left.expression, node.right, node.operatorToken.kind), - node - ), - node - ); + return ts.setTextRange(ts.setOriginalNode(createPrivateIdentifierAssignment(info, node.left.expression, node.right, node.operatorToken.kind), node), node); } } else if (shouldTransformSuperInStaticInitializers && - isSuperProperty(node.left) && + ts.isSuperProperty(node.left) && currentStaticPropertyDeclarationOrStaticBlock && currentClassLexicalEnvironment) { const { classConstructor, superClassReference, facts } = currentClassLexicalEnvironment; if (facts & ClassFacts.ClassWasDecorated) { - return factory.updateBinaryExpression( - node, - visitInvalidSuperProperty(node.left), - node.operatorToken, - visitNode(node.right, visitor, isExpression)); + return factory.updateBinaryExpression(node, visitInvalidSuperProperty(node.left), node.operatorToken, ts.visitNode(node.right, visitor, ts.isExpression)); } if (classConstructor && superClassReference) { - let setterName = - isElementAccessExpression(node.left) ? visitNode(node.left.argumentExpression, visitor, isExpression) : - isIdentifier(node.left.name) ? factory.createStringLiteralFromNode(node.left.name) : + let setterName = ts.isElementAccessExpression(node.left) ? ts.visitNode(node.left.argumentExpression, visitor, ts.isExpression) : + ts.isIdentifier(node.left.name) ? factory.createStringLiteralFromNode(node.left.name) : undefined; if (setterName) { // converts `super.x = 1` into `(Reflect.set(_baseTemp, "x", _a = 1, _classTemp), _a)` @@ -838,47 +709,33 @@ namespace ts { // converts `super.x += 1` into `(Reflect.set(_baseTemp, "x", _a = Reflect.get(_baseTemp, "x", _classtemp) + 1, _classTemp), _a)` // converts `super[f()] += 1` into `(Reflect.set(_baseTemp, _a = f(), _b = Reflect.get(_baseTemp, _a, _classtemp) + 1, _classTemp), _b)` - let expression = visitNode(node.right, visitor, isExpression); - if (isCompoundAssignment(node.operatorToken.kind)) { + let expression = ts.visitNode(node.right, visitor, ts.isExpression); + if (ts.isCompoundAssignment(node.operatorToken.kind)) { let getterName = setterName; - if (!isSimpleInlineableExpression(setterName)) { + if (!ts.isSimpleInlineableExpression(setterName)) { getterName = factory.createTempVariable(hoistVariableDeclaration); setterName = factory.createAssignment(getterName, setterName); } - const superPropertyGet = factory.createReflectGetCall( - superClassReference, - getterName, - classConstructor - ); - setOriginalNode(superPropertyGet, node.left); - setTextRange(superPropertyGet, node.left); - - expression = factory.createBinaryExpression( - superPropertyGet, - getNonAssignmentOperatorForCompoundAssignment(node.operatorToken.kind), - expression - ); - setTextRange(expression, node); + const superPropertyGet = factory.createReflectGetCall(superClassReference, getterName, classConstructor); + ts.setOriginalNode(superPropertyGet, node.left); + ts.setTextRange(superPropertyGet, node.left); + expression = factory.createBinaryExpression(superPropertyGet, ts.getNonAssignmentOperatorForCompoundAssignment(node.operatorToken.kind), expression); + ts.setTextRange(expression, node); } const temp = valueIsDiscarded ? undefined : factory.createTempVariable(hoistVariableDeclaration); if (temp) { expression = factory.createAssignment(temp, expression); - setTextRange(temp, node); + ts.setTextRange(temp, node); } - expression = factory.createReflectSetCall( - superClassReference, - setterName, - expression, - classConstructor - ); - setOriginalNode(expression, node); - setTextRange(expression, node); + expression = factory.createReflectSetCall(superClassReference, setterName, expression, classConstructor); + ts.setOriginalNode(expression, node); + ts.setTextRange(expression, node); if (temp) { expression = factory.createComma(expression, temp); - setTextRange(expression, node); + ts.setTextRange(expression, node); } return expression; @@ -886,64 +743,41 @@ namespace ts { } } } - if (node.operatorToken.kind === SyntaxKind.InKeyword && isPrivateIdentifier(node.left)) { + if (node.operatorToken.kind === ts.SyntaxKind.InKeyword && ts.isPrivateIdentifier(node.left)) { return visitPrivateIdentifierInInExpression(node); } - return visitEachChild(node, visitor, context); + return ts.visitEachChild(node, visitor, context); } - function createPrivateIdentifierAssignment(info: PrivateIdentifierInfo, receiver: Expression, right: Expression, operator: AssignmentOperator): Expression { - receiver = visitNode(receiver, visitor, isExpression); - right = visitNode(right, visitor, isExpression); - - if (isCompoundAssignment(operator)) { + function createPrivateIdentifierAssignment(info: PrivateIdentifierInfo, receiver: ts.Expression, right: ts.Expression, operator: ts.AssignmentOperator): ts.Expression { + receiver = ts.visitNode(receiver, visitor, ts.isExpression); + right = ts.visitNode(right, visitor, ts.isExpression); + if (ts.isCompoundAssignment(operator)) { const { readExpression, initializeExpression } = createCopiableReceiverExpr(receiver); receiver = initializeExpression || readExpression; - right = factory.createBinaryExpression( - createPrivateIdentifierAccessHelper(info, readExpression), - getNonAssignmentOperatorForCompoundAssignment(operator), - right - ); + right = factory.createBinaryExpression(createPrivateIdentifierAccessHelper(info, readExpression), ts.getNonAssignmentOperatorForCompoundAssignment(operator), right); } - - setCommentRange(receiver, moveRangePos(receiver, -1)); + ts.setCommentRange(receiver, ts.moveRangePos(receiver, -1)); switch(info.kind) { case PrivateIdentifierKind.Accessor: - return context.getEmitHelperFactory().createClassPrivateFieldSetHelper( - receiver, - info.brandCheckIdentifier, - right, - info.kind, - info.setterName - ); + return context.getEmitHelperFactory().createClassPrivateFieldSetHelper(receiver, info.brandCheckIdentifier, right, info.kind, info.setterName); case PrivateIdentifierKind.Method: - return context.getEmitHelperFactory().createClassPrivateFieldSetHelper( - receiver, - info.brandCheckIdentifier, - right, - info.kind, - /* f */ undefined - ); + return context.getEmitHelperFactory().createClassPrivateFieldSetHelper(receiver, info.brandCheckIdentifier, right, info.kind, + /* f */ undefined); case PrivateIdentifierKind.Field: - return context.getEmitHelperFactory().createClassPrivateFieldSetHelper( - receiver, - info.brandCheckIdentifier, - right, - info.kind, - info.variableName - ); + return context.getEmitHelperFactory().createClassPrivateFieldSetHelper(receiver, info.brandCheckIdentifier, right, info.kind, info.variableName); default: - Debug.assertNever(info, "Unknown private element type"); + ts.Debug.assertNever(info, "Unknown private element type"); } } /** * Set up the environment for a class. */ - function visitClassLike(node: ClassLikeDeclaration) { - if (!forEach(node.members, doesClassElementNeedTransform)) { - return visitEachChild(node, visitor, context); + function visitClassLike(node: ts.ClassLikeDeclaration) { + if (!ts.forEach(node.members, doesClassElementNeedTransform)) { + return ts.visitEachChild(node, visitor, context); } const savedPendingExpressions = pendingExpressions; @@ -951,21 +785,18 @@ namespace ts { startClassLexicalEnvironment(); if (shouldTransformPrivateElementsOrClassStaticBlocks) { - const name = getNameOfDeclaration(node); - if (name && isIdentifier(name)) { - getPrivateIdentifierEnvironment().className = idText(name); + const name = ts.getNameOfDeclaration(node); + if (name && ts.isIdentifier(name)) { + getPrivateIdentifierEnvironment().className = ts.idText(name); } const privateInstanceMethodsAndAccessors = getPrivateInstanceMethodsAndAccessors(node); - if (some(privateInstanceMethodsAndAccessors)) { - getPrivateIdentifierEnvironment().weakSetName = createHoistedVariableForClass( - "instances", - privateInstanceMethodsAndAccessors[0].name - ); + if (ts.some(privateInstanceMethodsAndAccessors)) { + getPrivateIdentifierEnvironment().weakSetName = createHoistedVariableForClass("instances", privateInstanceMethodsAndAccessors[0].name); } } - const result = isClassDeclaration(node) ? + const result = ts.isClassDeclaration(node) ? visitClassDeclaration(node) : visitClassExpression(node); @@ -974,33 +805,34 @@ namespace ts { return result; } - function doesClassElementNeedTransform(node: ClassElement) { - return isPropertyDeclaration(node) || isClassStaticBlockDeclaration(node) || (shouldTransformPrivateElementsOrClassStaticBlocks && node.name && isPrivateIdentifier(node.name)); + function doesClassElementNeedTransform(node: ts.ClassElement) { + return ts.isPropertyDeclaration(node) || ts.isClassStaticBlockDeclaration(node) || (shouldTransformPrivateElementsOrClassStaticBlocks && node.name && ts.isPrivateIdentifier(node.name)); } - function getPrivateInstanceMethodsAndAccessors(node: ClassLikeDeclaration) { - return filter(node.members, isNonStaticMethodOrAccessorWithPrivateName); + function getPrivateInstanceMethodsAndAccessors(node: ts.ClassLikeDeclaration) { + return ts.filter(node.members, ts.isNonStaticMethodOrAccessorWithPrivateName); } - function getClassFacts(node: ClassLikeDeclaration) { + function getClassFacts(node: ts.ClassLikeDeclaration) { let facts = ClassFacts.None; - const original = getOriginalNode(node); - if (isClassDeclaration(original) && classOrConstructorParameterIsDecorated(original)) { + const original = ts.getOriginalNode(node); + if (ts.isClassDeclaration(original) && ts.classOrConstructorParameterIsDecorated(original)) { facts |= ClassFacts.ClassWasDecorated; } for (const member of node.members) { - if (!isStatic(member)) continue; - if (member.name && isPrivateIdentifier(member.name) && shouldTransformPrivateElementsOrClassStaticBlocks) { + if (!ts.isStatic(member)) + continue; + if (member.name && ts.isPrivateIdentifier(member.name) && shouldTransformPrivateElementsOrClassStaticBlocks) { facts |= ClassFacts.NeedsClassConstructorReference; } - if (isPropertyDeclaration(member) || isClassStaticBlockDeclaration(member)) { - if (shouldTransformThisInStaticInitializers && member.transformFlags & TransformFlags.ContainsLexicalThis) { + if (ts.isPropertyDeclaration(member) || ts.isClassStaticBlockDeclaration(member)) { + if (shouldTransformThisInStaticInitializers && member.transformFlags & ts.TransformFlags.ContainsLexicalThis) { facts |= ClassFacts.NeedsSubstitutionForThisInClassStaticField; if (!(facts & ClassFacts.ClassWasDecorated)) { facts |= ClassFacts.NeedsClassConstructorReference; } } - if (shouldTransformSuperInStaticInitializers && member.transformFlags & TransformFlags.ContainsLexicalSuper) { + if (shouldTransformSuperInStaticInitializers && member.transformFlags & ts.TransformFlags.ContainsLexicalSuper) { if (!(facts & ClassFacts.ClassWasDecorated)) { facts |= ClassFacts.NeedsClassConstructorReference | ClassFacts.NeedsClassSuperReference; } @@ -1010,24 +842,17 @@ namespace ts { return facts; } - function visitExpressionWithTypeArguments(node: ExpressionWithTypeArguments) { + function visitExpressionWithTypeArguments(node: ts.ExpressionWithTypeArguments) { const facts = currentClassLexicalEnvironment?.facts || ClassFacts.None; if (facts & ClassFacts.NeedsClassSuperReference) { const temp = factory.createTempVariable(hoistVariableDeclaration, /*reserveInNestedScopes*/ true); getClassLexicalEnvironment().superClassReference = temp; - return factory.updateExpressionWithTypeArguments( - node, - factory.createAssignment( - temp, - visitNode(node.expression, visitor, isExpression) - ), - /*typeArguments*/ undefined - ); + return factory.updateExpressionWithTypeArguments(node, factory.createAssignment(temp, ts.visitNode(node.expression, visitor, ts.isExpression)), + /*typeArguments*/ undefined); } - return visitEachChild(node, visitor, context); + return ts.visitEachChild(node, visitor, context); } - - function visitClassDeclaration(node: ClassDeclaration) { + function visitClassDeclaration(node: ts.ClassDeclaration) { const facts = getClassFacts(node); if (facts) { getClassLexicalEnvironment().facts = facts; @@ -1038,26 +863,19 @@ namespace ts { // If a class has private static fields, or a static field has a `this` or `super` reference, // then we need to allocate a temp variable to hold on to that reference. - let pendingClassReferenceAssignment: BinaryExpression | undefined; + let pendingClassReferenceAssignment: ts.BinaryExpression | undefined; if (facts & ClassFacts.NeedsClassConstructorReference) { const temp = factory.createTempVariable(hoistVariableDeclaration, /*reservedInNestedScopes*/ true); getClassLexicalEnvironment().classConstructor = factory.cloneNode(temp); pendingClassReferenceAssignment = factory.createAssignment(temp, factory.getInternalName(node)); } - const extendsClauseElement = getEffectiveBaseTypeNode(node); - const isDerivedClass = !!(extendsClauseElement && skipOuterExpressions(extendsClauseElement.expression).kind !== SyntaxKind.NullKeyword); - - const statements: Statement[] = [ - factory.updateClassDeclaration( - node, - /*decorators*/ undefined, - node.modifiers, - node.name, - /*typeParameters*/ undefined, - visitNodes(node.heritageClauses, heritageClauseVisitor, isHeritageClause), - transformClassMembers(node, isDerivedClass) - ) + const extendsClauseElement = ts.getEffectiveBaseTypeNode(node); + const isDerivedClass = !!(extendsClauseElement && ts.skipOuterExpressions(extendsClauseElement.expression).kind !== ts.SyntaxKind.NullKeyword); + const statements: ts.Statement[] = [ + factory.updateClassDeclaration(node, + /*decorators*/ undefined, node.modifiers, node.name, + /*typeParameters*/ undefined, ts.visitNodes(node.heritageClauses, heritageClauseVisitor, ts.isHeritageClause), transformClassMembers(node, isDerivedClass)) ]; if (pendingClassReferenceAssignment) { @@ -1065,7 +883,7 @@ namespace ts { } // Write any pending expressions from elided or moved computed property names - if (some(pendingExpressions)) { + if (ts.some(pendingExpressions)) { statements.push(factory.createExpressionStatement(factory.inlineExpressions(pendingExpressions))); } @@ -1075,15 +893,15 @@ namespace ts { // HasLexicalDeclaration (N) : Determines if the argument identifier has a binding in this environment record that was created using // a lexical declaration such as a LexicalDeclaration or a ClassDeclaration. - const staticProperties = getStaticPropertiesAndClassStaticBlock(node); - if (some(staticProperties)) { + const staticProperties = ts.getStaticPropertiesAndClassStaticBlock(node); + if (ts.some(staticProperties)) { addPropertyOrClassStaticBlockStatements(statements, staticProperties, factory.getInternalName(node)); } return statements; } - function visitClassExpression(node: ClassExpression): Expression { + function visitClassExpression(node: ts.ClassExpression): ts.Expression { const facts = getClassFacts(node); if (facts) { getClassLexicalEnvironment().facts = facts; @@ -1102,17 +920,15 @@ namespace ts { // these statements after the class expression variable statement. const isDecoratedClassDeclaration = !!(facts & ClassFacts.ClassWasDecorated); - const staticPropertiesOrClassStaticBlocks = getStaticPropertiesAndClassStaticBlock(node); - - const extendsClauseElement = getEffectiveBaseTypeNode(node); - const isDerivedClass = !!(extendsClauseElement && skipOuterExpressions(extendsClauseElement.expression).kind !== SyntaxKind.NullKeyword); - - const isClassWithConstructorReference = resolver.getNodeCheckFlags(node) & NodeCheckFlags.ClassWithConstructorReference; - let temp: Identifier | undefined; + const staticPropertiesOrClassStaticBlocks = ts.getStaticPropertiesAndClassStaticBlock(node); + const extendsClauseElement = ts.getEffectiveBaseTypeNode(node); + const isDerivedClass = !!(extendsClauseElement && ts.skipOuterExpressions(extendsClauseElement.expression).kind !== ts.SyntaxKind.NullKeyword); + const isClassWithConstructorReference = resolver.getNodeCheckFlags(node) & ts.NodeCheckFlags.ClassWithConstructorReference; + let temp: ts.Identifier | undefined; function createClassTempVar() { const classCheckFlags = resolver.getNodeCheckFlags(node); - const isClassWithConstructorReference = classCheckFlags & NodeCheckFlags.ClassWithConstructorReference; - const requiresBlockScopedVar = classCheckFlags & NodeCheckFlags.BlockScopedBindingInLoop; + const isClassWithConstructorReference = classCheckFlags & ts.NodeCheckFlags.ClassWithConstructorReference; + const requiresBlockScopedVar = classCheckFlags & ts.NodeCheckFlags.BlockScopedBindingInLoop; return factory.createTempVariable(requiresBlockScopedVar ? addBlockScopedVariable : hoistVariableDeclaration, !!isClassWithConstructorReference); } @@ -1121,27 +937,19 @@ namespace ts { getClassLexicalEnvironment().classConstructor = factory.cloneNode(temp); } - const classExpression = factory.updateClassExpression( - node, - visitNodes(node.decorators, visitor, isDecorator), - node.modifiers, - node.name, - /*typeParameters*/ undefined, - visitNodes(node.heritageClauses, heritageClauseVisitor, isHeritageClause), - transformClassMembers(node, isDerivedClass) - ); - - const hasTransformableStatics = shouldTransformPrivateElementsOrClassStaticBlocks && some(staticPropertiesOrClassStaticBlocks, p => isClassStaticBlockDeclaration(p) || !!p.initializer || isPrivateIdentifier(p.name)); - if (hasTransformableStatics || some(pendingExpressions)) { + const classExpression = factory.updateClassExpression(node, ts.visitNodes(node.decorators, visitor, ts.isDecorator), node.modifiers, node.name, + /*typeParameters*/ undefined, ts.visitNodes(node.heritageClauses, heritageClauseVisitor, ts.isHeritageClause), transformClassMembers(node, isDerivedClass)); + const hasTransformableStatics = shouldTransformPrivateElementsOrClassStaticBlocks && ts.some(staticPropertiesOrClassStaticBlocks, p => ts.isClassStaticBlockDeclaration(p) || !!p.initializer || ts.isPrivateIdentifier(p.name)); + if (hasTransformableStatics || ts.some(pendingExpressions)) { if (isDecoratedClassDeclaration) { - Debug.assertIsDefined(pendingStatements, "Decorated classes transformed by TypeScript are expected to be within a variable declaration."); + ts.Debug.assertIsDefined(pendingStatements, "Decorated classes transformed by TypeScript are expected to be within a variable declaration."); // Write any pending expressions from elided or moved computed property names - if (pendingStatements && pendingExpressions && some(pendingExpressions)) { + if (pendingStatements && pendingExpressions && ts.some(pendingExpressions)) { pendingStatements.push(factory.createExpressionStatement(factory.inlineExpressions(pendingExpressions))); } - if (pendingStatements && some(staticPropertiesOrClassStaticBlocks)) { + if (pendingStatements && ts.some(staticPropertiesOrClassStaticBlocks)) { addPropertyOrClassStaticBlockStatements(pendingStatements, staticPropertiesOrClassStaticBlocks, factory.getInternalName(node)); } if (temp) { @@ -1150,24 +958,24 @@ namespace ts { return classExpression; } else { - const expressions: Expression[] = []; + const expressions: ts.Expression[] = []; temp ||= createClassTempVar(); if (isClassWithConstructorReference) { // record an alias as the class name is not in scope for statics. enableSubstitutionForClassAliases(); - const alias = factory.cloneNode(temp) as GeneratedIdentifier; - alias.autoGenerateFlags &= ~GeneratedIdentifierFlags.ReservedInNestedScopes; - classAliases[getOriginalNodeId(node)] = alias; + const alias = factory.cloneNode(temp) as ts.GeneratedIdentifier; + alias.autoGenerateFlags &= ~ts.GeneratedIdentifierFlags.ReservedInNestedScopes; + classAliases[ts.getOriginalNodeId(node)] = alias; } // To preserve the behavior of the old emitter, we explicitly indent // the body of a class with static initializers. - setEmitFlags(classExpression, EmitFlags.Indented | getEmitFlags(classExpression)); - expressions.push(startOnNewLine(factory.createAssignment(temp, classExpression))); + ts.setEmitFlags(classExpression, ts.EmitFlags.Indented | ts.getEmitFlags(classExpression)); + expressions.push(ts.startOnNewLine(factory.createAssignment(temp, classExpression))); // Add any pending expressions leftover from elided or relocated computed property names - addRange(expressions, map(pendingExpressions, startOnNewLine)); - addRange(expressions, generateInitializedPropertyExpressionsOrClassStaticBlock(staticPropertiesOrClassStaticBlocks, temp)); - expressions.push(startOnNewLine(temp)); + ts.addRange(expressions, ts.map(pendingExpressions, ts.startOnNewLine)); + ts.addRange(expressions, generateInitializedPropertyExpressionsOrClassStaticBlock(staticPropertiesOrClassStaticBlocks, temp)); + expressions.push(ts.startOnNewLine(temp)); return factory.inlineExpressions(expressions); } @@ -1176,119 +984,94 @@ namespace ts { return classExpression; } - function visitClassStaticBlockDeclaration(node: ClassStaticBlockDeclaration) { + function visitClassStaticBlockDeclaration(node: ts.ClassStaticBlockDeclaration) { if (!shouldTransformPrivateElementsOrClassStaticBlocks) { - return visitEachChild(node, classElementVisitor, context); + return ts.visitEachChild(node, classElementVisitor, context); } // ClassStaticBlockDeclaration for classes are transformed in `visitClassDeclaration` or `visitClassExpression`. return undefined; } - function transformClassMembers(node: ClassDeclaration | ClassExpression, isDerivedClass: boolean) { - const members: ClassElement[] = []; + function transformClassMembers(node: ts.ClassDeclaration | ts.ClassExpression, isDerivedClass: boolean) { + const members: ts.ClassElement[] = []; if (shouldTransformPrivateElementsOrClassStaticBlocks) { // Declare private names. for (const member of node.members) { - if (isPrivateIdentifierClassElementDeclaration(member)) { + if (ts.isPrivateIdentifierClassElementDeclaration(member)) { addPrivateIdentifierToEnvironment(member); } } - if (some(getPrivateInstanceMethodsAndAccessors(node))) { + if (ts.some(getPrivateInstanceMethodsAndAccessors(node))) { createBrandCheckWeakSetForPrivateMethods(); } } const constructor = transformConstructor(node, isDerivedClass); - const visitedMembers = visitNodes(node.members, classElementVisitor, isClassElement); + const visitedMembers = ts.visitNodes(node.members, classElementVisitor, ts.isClassElement); if (constructor) { members.push(constructor); } - if (!shouldTransformPrivateElementsOrClassStaticBlocks && some(pendingExpressions)) { + if (!shouldTransformPrivateElementsOrClassStaticBlocks && ts.some(pendingExpressions)) { members.push(factory.createClassStaticBlockDeclaration( /*decorators*/ undefined, - /*modifiers*/ undefined, - factory.createBlock([ + /*modifiers*/ undefined, factory.createBlock([ factory.createExpressionStatement(factory.inlineExpressions(pendingExpressions)) - ]) - )); + ]))); pendingExpressions = undefined; } - addRange(members, visitedMembers); - - return setTextRange(factory.createNodeArray(members), /*location*/ node.members); + ts.addRange(members, visitedMembers); + return ts.setTextRange(factory.createNodeArray(members), /*location*/ node.members); } function createBrandCheckWeakSetForPrivateMethods() { const { weakSetName } = getPrivateIdentifierEnvironment(); - Debug.assert(weakSetName, "weakSetName should be set in private identifier environment"); - - getPendingExpressions().push( - factory.createAssignment( - weakSetName, - factory.createNewExpression( - factory.createIdentifier("WeakSet"), - /*typeArguments*/ undefined, - [] - ) - ) - ); - } - - function isClassElementThatRequiresConstructorStatement(member: ClassElement) { - if (isStatic(member) || hasSyntacticModifier(getOriginalNode(member), ModifierFlags.Abstract)) { + ts.Debug.assert(weakSetName, "weakSetName should be set in private identifier environment"); + getPendingExpressions().push(factory.createAssignment(weakSetName, factory.createNewExpression(factory.createIdentifier("WeakSet"), + /*typeArguments*/ undefined, []))); + } + function isClassElementThatRequiresConstructorStatement(member: ts.ClassElement) { + if (ts.isStatic(member) || ts.hasSyntacticModifier(ts.getOriginalNode(member), ts.ModifierFlags.Abstract)) { return false; } if (useDefineForClassFields) { // If we are using define semantics and targeting ESNext or higher, // then we don't need to transform any class properties. - return languageVersion < ScriptTarget.ES2022; + return languageVersion < ts.ScriptTarget.ES2022; } - return isInitializedProperty(member) || shouldTransformPrivateElementsOrClassStaticBlocks && isPrivateIdentifierClassElementDeclaration(member); + return ts.isInitializedProperty(member) || shouldTransformPrivateElementsOrClassStaticBlocks && ts.isPrivateIdentifierClassElementDeclaration(member); } - function transformConstructor(node: ClassDeclaration | ClassExpression, isDerivedClass: boolean) { - const constructor = visitNode(getFirstConstructorWithBody(node), visitor, isConstructorDeclaration); + function transformConstructor(node: ts.ClassDeclaration | ts.ClassExpression, isDerivedClass: boolean) { + const constructor = ts.visitNode(ts.getFirstConstructorWithBody(node), visitor, ts.isConstructorDeclaration); const elements = node.members.filter(isClassElementThatRequiresConstructorStatement); - if (!some(elements)) { + if (!ts.some(elements)) { return constructor; } - const parameters = visitParameterList(constructor ? constructor.parameters : undefined, visitor, context); + const parameters = ts.visitParameterList(constructor ? constructor.parameters : undefined, visitor, context); const body = transformConstructorBody(node, constructor, isDerivedClass); if (!body) { return undefined; } - return startOnNewLine( - setOriginalNode( - setTextRange( - factory.createConstructorDeclaration( + return ts.startOnNewLine(ts.setOriginalNode(ts.setTextRange(factory.createConstructorDeclaration( /*decorators*/ undefined, - /*modifiers*/ undefined, - parameters ?? [], - body - ), - constructor || node - ), - constructor - ) - ); - } - - function transformConstructorBody(node: ClassDeclaration | ClassExpression, constructor: ConstructorDeclaration | undefined, isDerivedClass: boolean) { - let properties = getProperties(node, /*requireInitializer*/ false, /*isStatic*/ false); + /*modifiers*/ undefined, parameters ?? [], body), constructor || node), constructor)); + } + function transformConstructorBody(node: ts.ClassDeclaration | ts.ClassExpression, constructor: ts.ConstructorDeclaration | undefined, isDerivedClass: boolean) { + let properties = ts.getProperties(node, /*requireInitializer*/ false, /*isStatic*/ false); if (!useDefineForClassFields) { - properties = filter(properties, property => !!property.initializer || isPrivateIdentifier(property.name)); + properties = ts.filter(properties, property => !!property.initializer || ts.isPrivateIdentifier(property.name)); } const privateMethodsAndAccessors = getPrivateInstanceMethodsAndAccessors(node); - const needsConstructorBody = some(properties) || some(privateMethodsAndAccessors); + const needsConstructorBody = ts.some(properties) || ts.some(privateMethodsAndAccessors); // Only generate synthetic constructor when there are property initializers to move. if (!constructor && !needsConstructorBody) { - return visitFunctionBody(/*node*/ undefined, visitor, context); + return ts.visitFunctionBody(/*node*/ undefined, visitor, context); } resumeLexicalEnvironment(); @@ -1297,18 +1080,18 @@ namespace ts { let indexOfFirstStatementAfterSuperAndPrologue = 0; let prologueStatementCount = 0; let superStatementIndex = -1; - let statements: Statement[] = []; + let statements: ts.Statement[] = []; if (constructor?.body?.statements) { prologueStatementCount = factory.copyPrologue(constructor.body.statements, statements, /*ensureUseStrict*/ false, visitor); - superStatementIndex = findSuperStatementIndex(constructor.body.statements, prologueStatementCount); + superStatementIndex = ts.findSuperStatementIndex(constructor.body.statements, prologueStatementCount); // If there was a super call, visit existing statements up to and including it if (superStatementIndex >= 0) { indexOfFirstStatementAfterSuperAndPrologue = superStatementIndex + 1; statements = [ ...statements.slice(0, prologueStatementCount), - ...visitNodes(constructor.body.statements, visitor, isStatement, prologueStatementCount, indexOfFirstStatementAfterSuperAndPrologue - prologueStatementCount), + ...ts.visitNodes(constructor.body.statements, visitor, ts.isStatement, prologueStatementCount, indexOfFirstStatementAfterSuperAndPrologue - prologueStatementCount), ...statements.slice(prologueStatementCount), ]; } @@ -1322,15 +1105,8 @@ namespace ts { // // super(...arguments); // - statements.push( - factory.createExpressionStatement( - factory.createCallExpression( - factory.createSuper(), - /*typeArguments*/ undefined, - [factory.createSpreadElement(factory.createIdentifier("arguments"))] - ) - ) - ); + statements.push(factory.createExpressionStatement(factory.createCallExpression(factory.createSuper(), + /*typeArguments*/ undefined, [factory.createSpreadElement(factory.createIdentifier("arguments"))]))); } // Add the property initializers. Transforms this: @@ -1348,26 +1124,27 @@ namespace ts { let parameterPropertyDeclarationCount = 0; if (constructor?.body) { if (useDefineForClassFields) { - statements = statements.filter(statement => !isParameterPropertyDeclaration(getOriginalNode(statement), constructor)); + statements = statements.filter(statement => !ts.isParameterPropertyDeclaration(ts.getOriginalNode(statement), constructor)); } else { for (const statement of constructor.body.statements) { - if (isParameterPropertyDeclaration(getOriginalNode(statement), constructor)) { + if (ts.isParameterPropertyDeclaration(ts.getOriginalNode(statement), constructor)) { parameterPropertyDeclarationCount++; } } if (parameterPropertyDeclarationCount > 0) { - const parameterProperties = visitNodes(constructor.body.statements, visitor, isStatement, indexOfFirstStatementAfterSuperAndPrologue, parameterPropertyDeclarationCount); + const parameterProperties = ts.visitNodes(constructor.body.statements, visitor, ts.isStatement, indexOfFirstStatementAfterSuperAndPrologue, parameterPropertyDeclarationCount); // If there was a super() call found, add parameter properties immediately after it if (superStatementIndex >= 0) { - addRange(statements, parameterProperties); + ts.addRange(statements, parameterProperties); } else { // Add add parameter properties to the top of the constructor after the prologue let superAndPrologueStatementCount = prologueStatementCount; // If a synthetic super() call was added, need to account for that - if (needsSyntheticConstructor) superAndPrologueStatementCount++; + if (needsSyntheticConstructor) + superAndPrologueStatementCount++; statements = [ ...statements.slice(0, superAndPrologueStatementCount), ...parameterProperties, @@ -1387,24 +1164,17 @@ namespace ts { // Add existing statements after the initial prologues and super call if (constructor) { - addRange(statements, visitNodes(constructor.body!.statements, visitBodyStatement, isStatement, indexOfFirstStatementAfterSuperAndPrologue)); + ts.addRange(statements, ts.visitNodes(constructor.body!.statements, visitBodyStatement, ts.isStatement, indexOfFirstStatementAfterSuperAndPrologue)); } statements = factory.mergeLexicalEnvironment(statements, endLexicalEnvironment()); - return setTextRange( - factory.createBlock( - setTextRange( - factory.createNodeArray(statements), - /*location*/ constructor ? constructor.body!.statements : node.members - ), - /*multiLine*/ true - ), - /*location*/ constructor ? constructor.body : undefined - ); - - function visitBodyStatement(statement: Node) { - if (useDefineForClassFields && isParameterPropertyDeclaration(getOriginalNode(statement), constructor!)) { + return ts.setTextRange(factory.createBlock(ts.setTextRange(factory.createNodeArray(statements), + /*location*/ constructor ? constructor.body!.statements : node.members), + /*multiLine*/ true), + /*location*/ constructor ? constructor.body : undefined); + function visitBodyStatement(statement: ts.Node) { + if (useDefineForClassFields && ts.isParameterPropertyDeclaration(ts.getOriginalNode(statement), constructor!)) { return undefined; } @@ -1418,9 +1188,9 @@ namespace ts { * @param properties An array of property declarations to transform. * @param receiver The receiver on which each property should be assigned. */ - function addPropertyOrClassStaticBlockStatements(statements: Statement[], properties: readonly (PropertyDeclaration | ClassStaticBlockDeclaration)[], receiver: LeftHandSideExpression) { + function addPropertyOrClassStaticBlockStatements(statements: ts.Statement[], properties: readonly (ts.PropertyDeclaration | ts.ClassStaticBlockDeclaration)[], receiver: ts.LeftHandSideExpression) { for (const property of properties) { - if (isStatic(property) && !shouldTransformPrivateElementsOrClassStaticBlocks && !useDefineForClassFields) { + if (ts.isStatic(property) && !shouldTransformPrivateElementsOrClassStaticBlocks && !useDefineForClassFields) { continue; } @@ -1433,8 +1203,8 @@ namespace ts { } } - function transformPropertyOrClassStaticBlock(property: PropertyDeclaration | ClassStaticBlockDeclaration, receiver: LeftHandSideExpression) { - const expression = isClassStaticBlockDeclaration(property) ? + function transformPropertyOrClassStaticBlock(property: ts.PropertyDeclaration | ts.ClassStaticBlockDeclaration, receiver: ts.LeftHandSideExpression) { + const expression = ts.isClassStaticBlockDeclaration(property) ? transformClassStaticBlockDeclaration(property) : transformProperty(property, receiver); if (!expression) { @@ -1442,15 +1212,15 @@ namespace ts { } const statement = factory.createExpressionStatement(expression); - setSourceMapRange(statement, moveRangePastModifiers(property)); - setCommentRange(statement, property); - setOriginalNode(statement, property); + ts.setSourceMapRange(statement, ts.moveRangePastModifiers(property)); + ts.setCommentRange(statement, property); + ts.setOriginalNode(statement, property); // `setOriginalNode` *copies* the `emitNode` from `property`, so now both // `statement` and `expression` have a copy of the synthesized comments. // Drop the comments from expression to avoid printing them twice. - setSyntheticLeadingComments(expression, undefined); - setSyntheticTrailingComments(expression, undefined); + ts.setSyntheticLeadingComments(expression, undefined); + ts.setSyntheticTrailingComments(expression, undefined); return statement; } @@ -1461,17 +1231,17 @@ namespace ts { * @param propertiesOrClassStaticBlocks An array of property declarations to transform. * @param receiver The receiver on which each property should be assigned. */ - function generateInitializedPropertyExpressionsOrClassStaticBlock(propertiesOrClassStaticBlocks: readonly (PropertyDeclaration | ClassStaticBlockDeclaration)[], receiver: LeftHandSideExpression) { - const expressions: Expression[] = []; + function generateInitializedPropertyExpressionsOrClassStaticBlock(propertiesOrClassStaticBlocks: readonly (ts.PropertyDeclaration | ts.ClassStaticBlockDeclaration)[], receiver: ts.LeftHandSideExpression) { + const expressions: ts.Expression[] = []; for (const property of propertiesOrClassStaticBlocks) { - const expression = isClassStaticBlockDeclaration(property) ? transformClassStaticBlockDeclaration(property) : transformProperty(property, receiver); + const expression = ts.isClassStaticBlockDeclaration(property) ? transformClassStaticBlockDeclaration(property) : transformProperty(property, receiver); if (!expression) { continue; } - startOnNewLine(expression); - setSourceMapRange(expression, moveRangePastModifiers(property)); - setCommentRange(expression, property); - setOriginalNode(expression, property); + ts.startOnNewLine(expression); + ts.setSourceMapRange(expression, ts.moveRangePastModifiers(property)); + ts.setCommentRange(expression, property); + ts.setOriginalNode(expression, property); expressions.push(expression); } @@ -1484,46 +1254,39 @@ namespace ts { * @param property The property declaration. * @param receiver The object receiving the property assignment. */ - function transformProperty(property: PropertyDeclaration, receiver: LeftHandSideExpression) { + function transformProperty(property: ts.PropertyDeclaration, receiver: ts.LeftHandSideExpression) { const savedCurrentStaticPropertyDeclarationOrStaticBlock = currentStaticPropertyDeclarationOrStaticBlock; const transformed = transformPropertyWorker(property, receiver); - if (transformed && hasStaticModifier(property) && currentClassLexicalEnvironment?.facts) { + if (transformed && ts.hasStaticModifier(property) && currentClassLexicalEnvironment?.facts) { // capture the lexical environment for the member - setOriginalNode(transformed, property); - addEmitFlags(transformed, EmitFlags.AdviseOnEmitNode); - classLexicalEnvironmentMap.set(getOriginalNodeId(transformed), currentClassLexicalEnvironment); + ts.setOriginalNode(transformed, property); + ts.addEmitFlags(transformed, ts.EmitFlags.AdviseOnEmitNode); + classLexicalEnvironmentMap.set(ts.getOriginalNodeId(transformed), currentClassLexicalEnvironment); } currentStaticPropertyDeclarationOrStaticBlock = savedCurrentStaticPropertyDeclarationOrStaticBlock; return transformed; } - function transformPropertyWorker(property: PropertyDeclaration, receiver: LeftHandSideExpression) { + function transformPropertyWorker(property: ts.PropertyDeclaration, receiver: ts.LeftHandSideExpression) { // We generate a name here in order to reuse the value cached by the relocated computed name expression (which uses the same generated name) const emitAssignment = !useDefineForClassFields; - const propertyName = isComputedPropertyName(property.name) && !isSimpleInlineableExpression(property.name.expression) + const propertyName = ts.isComputedPropertyName(property.name) && !ts.isSimpleInlineableExpression(property.name.expression) ? factory.updateComputedPropertyName(property.name, factory.getGeneratedNameForNode(property.name)) : property.name; - if (hasStaticModifier(property)) { + if (ts.hasStaticModifier(property)) { currentStaticPropertyDeclarationOrStaticBlock = property; } - if (shouldTransformPrivateElementsOrClassStaticBlocks && isPrivateIdentifier(propertyName)) { + if (shouldTransformPrivateElementsOrClassStaticBlocks && ts.isPrivateIdentifier(propertyName)) { const privateIdentifierInfo = accessPrivateIdentifier(propertyName); if (privateIdentifierInfo) { if (privateIdentifierInfo.kind === PrivateIdentifierKind.Field) { if (!privateIdentifierInfo.isStatic) { - return createPrivateInstanceFieldInitializer( - receiver, - visitNode(property.initializer, visitor, isExpression), - privateIdentifierInfo.brandCheckIdentifier - ); + return createPrivateInstanceFieldInitializer(receiver, ts.visitNode(property.initializer, visitor, ts.isExpression), privateIdentifierInfo.brandCheckIdentifier); } else { - return createPrivateStaticFieldInitializer( - privateIdentifierInfo.variableName, - visitNode(property.initializer, visitor, isExpression) - ); + return createPrivateStaticFieldInitializer(privateIdentifierInfo.variableName, ts.visitNode(property.initializer, visitor, ts.isExpression)); } } else { @@ -1531,29 +1294,29 @@ namespace ts { } } else { - Debug.fail("Undeclared private name for property declaration."); + ts.Debug.fail("Undeclared private name for property declaration."); } } - if ((isPrivateIdentifier(propertyName) || hasStaticModifier(property)) && !property.initializer) { + if ((ts.isPrivateIdentifier(propertyName) || ts.hasStaticModifier(property)) && !property.initializer) { return undefined; } - const propertyOriginalNode = getOriginalNode(property); - if (hasSyntacticModifier(propertyOriginalNode, ModifierFlags.Abstract)) { + const propertyOriginalNode = ts.getOriginalNode(property); + if (ts.hasSyntacticModifier(propertyOriginalNode, ts.ModifierFlags.Abstract)) { return undefined; } - const initializer = property.initializer || emitAssignment ? visitNode(property.initializer, visitor, isExpression) ?? factory.createVoidZero() - : isParameterPropertyDeclaration(propertyOriginalNode, propertyOriginalNode.parent) && isIdentifier(propertyName) ? propertyName + const initializer = property.initializer || emitAssignment ? ts.visitNode(property.initializer, visitor, ts.isExpression) ?? factory.createVoidZero() + : ts.isParameterPropertyDeclaration(propertyOriginalNode, propertyOriginalNode.parent) && ts.isIdentifier(propertyName) ? propertyName : factory.createVoidZero(); - if (emitAssignment || isPrivateIdentifier(propertyName)) { - const memberAccess = createMemberAccessForPropertyName(factory, receiver, propertyName, /*location*/ propertyName); + if (emitAssignment || ts.isPrivateIdentifier(propertyName)) { + const memberAccess = ts.createMemberAccessForPropertyName(factory, receiver, propertyName, /*location*/ propertyName); return factory.createAssignment(memberAccess, initializer); } else { - const name = isComputedPropertyName(propertyName) ? propertyName.expression - : isIdentifier(propertyName) ? factory.createStringLiteral(unescapeLeadingUnderscores(propertyName.escapedText)) + const name = ts.isComputedPropertyName(propertyName) ? propertyName.expression + : ts.isIdentifier(propertyName) ? factory.createStringLiteral(ts.unescapeLeadingUnderscores(propertyName.escapedText)) : propertyName; const descriptor = factory.createPropertyDescriptor({ value: initializer, configurable: true, writable: true, enumerable: true }); return factory.createObjectDefinePropertyCall(receiver, name, descriptor); @@ -1566,7 +1329,7 @@ namespace ts { // We need to enable substitutions for identifiers. This allows us to // substitute class names inside of a class declaration. - context.enableSubstitution(SyntaxKind.Identifier); + context.enableSubstitution(ts.SyntaxKind.Identifier); // Keep track of class aliases. classAliases = []; @@ -1578,22 +1341,22 @@ namespace ts { enabledSubstitutions |= ClassPropertySubstitutionFlags.ClassStaticThisOrSuperReference; // substitute `this` in a static field initializer - context.enableSubstitution(SyntaxKind.ThisKeyword); + context.enableSubstitution(ts.SyntaxKind.ThisKeyword); // these push a new lexical environment that is not the class lexical environment - context.enableEmitNotification(SyntaxKind.FunctionDeclaration); - context.enableEmitNotification(SyntaxKind.FunctionExpression); - context.enableEmitNotification(SyntaxKind.Constructor); + context.enableEmitNotification(ts.SyntaxKind.FunctionDeclaration); + context.enableEmitNotification(ts.SyntaxKind.FunctionExpression); + context.enableEmitNotification(ts.SyntaxKind.Constructor); // these push a new lexical environment that is not the class lexical environment, except // when they have a computed property name - context.enableEmitNotification(SyntaxKind.GetAccessor); - context.enableEmitNotification(SyntaxKind.SetAccessor); - context.enableEmitNotification(SyntaxKind.MethodDeclaration); - context.enableEmitNotification(SyntaxKind.PropertyDeclaration); + context.enableEmitNotification(ts.SyntaxKind.GetAccessor); + context.enableEmitNotification(ts.SyntaxKind.SetAccessor); + context.enableEmitNotification(ts.SyntaxKind.MethodDeclaration); + context.enableEmitNotification(ts.SyntaxKind.PropertyDeclaration); // class lexical environments are restored when entering a computed property name - context.enableEmitNotification(SyntaxKind.ComputedPropertyName); + context.enableEmitNotification(ts.SyntaxKind.ComputedPropertyName); } } @@ -1604,34 +1367,22 @@ namespace ts { * @param methods An array of method declarations. * @param receiver The receiver on which each method should be assigned. */ - function addMethodStatements(statements: Statement[], methods: readonly (MethodDeclaration | AccessorDeclaration)[], receiver: LeftHandSideExpression) { - if (!shouldTransformPrivateElementsOrClassStaticBlocks || !some(methods)) { + function addMethodStatements(statements: ts.Statement[], methods: readonly (ts.MethodDeclaration | ts.AccessorDeclaration)[], receiver: ts.LeftHandSideExpression) { + if (!shouldTransformPrivateElementsOrClassStaticBlocks || !ts.some(methods)) { return; } const { weakSetName } = getPrivateIdentifierEnvironment(); - Debug.assert(weakSetName, "weakSetName should be set in private identifier environment"); - statements.push( - factory.createExpressionStatement( - createPrivateInstanceMethodInitializer(receiver, weakSetName) - ) - ); - } - - function visitInvalidSuperProperty(node: SuperProperty) { - return isPropertyAccessExpression(node) ? - factory.updatePropertyAccessExpression( - node, - factory.createVoidZero(), - node.name) : - factory.updateElementAccessExpression( - node, - factory.createVoidZero(), - visitNode(node.argumentExpression, visitor, isExpression)); - } - - function onEmitNode(hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) => void) { - const original = getOriginalNode(node); + ts.Debug.assert(weakSetName, "weakSetName should be set in private identifier environment"); + statements.push(factory.createExpressionStatement(createPrivateInstanceMethodInitializer(receiver, weakSetName))); + } + function visitInvalidSuperProperty(node: ts.SuperProperty) { + return ts.isPropertyAccessExpression(node) ? + factory.updatePropertyAccessExpression(node, factory.createVoidZero(), node.name) : + factory.updateElementAccessExpression(node, factory.createVoidZero(), ts.visitNode(node.argumentExpression, visitor, ts.isExpression)); + } + function onEmitNode(hint: ts.EmitHint, node: ts.Node, emitCallback: (hint: ts.EmitHint, node: ts.Node) => void) { + const original = ts.getOriginalNode(node); if (original.id) { const classLexicalEnvironment = classLexicalEnvironmentMap.get(original.id); if (classLexicalEnvironment) { @@ -1647,14 +1398,14 @@ namespace ts { } switch (node.kind) { - case SyntaxKind.FunctionExpression: - if (isArrowFunction(original) || getEmitFlags(node) & EmitFlags.AsyncFunctionBody) { + case ts.SyntaxKind.FunctionExpression: + if (ts.isArrowFunction(original) || ts.getEmitFlags(node) & ts.EmitFlags.AsyncFunctionBody) { break; } // falls through - case SyntaxKind.FunctionDeclaration: - case SyntaxKind.Constructor: { + case ts.SyntaxKind.FunctionDeclaration: + case ts.SyntaxKind.Constructor: { const savedClassLexicalEnvironment = currentClassLexicalEnvironment; const savedCurrentComputedPropertyNameClassLexicalEnvironment = currentComputedPropertyNameClassLexicalEnvironment; currentClassLexicalEnvironment = undefined; @@ -1665,10 +1416,10 @@ namespace ts { return; } - case SyntaxKind.GetAccessor: - case SyntaxKind.SetAccessor: - case SyntaxKind.MethodDeclaration: - case SyntaxKind.PropertyDeclaration: { + case ts.SyntaxKind.GetAccessor: + case ts.SyntaxKind.SetAccessor: + case ts.SyntaxKind.MethodDeclaration: + case ts.SyntaxKind.PropertyDeclaration: { const savedClassLexicalEnvironment = currentClassLexicalEnvironment; const savedCurrentComputedPropertyNameClassLexicalEnvironment = currentComputedPropertyNameClassLexicalEnvironment; currentComputedPropertyNameClassLexicalEnvironment = currentClassLexicalEnvironment; @@ -1678,7 +1429,7 @@ namespace ts { currentComputedPropertyNameClassLexicalEnvironment = savedCurrentComputedPropertyNameClassLexicalEnvironment; return; } - case SyntaxKind.ComputedPropertyName: { + case ts.SyntaxKind.ComputedPropertyName: { const savedClassLexicalEnvironment = currentClassLexicalEnvironment; const savedCurrentComputedPropertyNameClassLexicalEnvironment = currentComputedPropertyNameClassLexicalEnvironment; currentClassLexicalEnvironment = currentComputedPropertyNameClassLexicalEnvironment; @@ -1698,50 +1449,44 @@ namespace ts { * @param hint The context for the emitter. * @param node The node to substitute. */ - function onSubstituteNode(hint: EmitHint, node: Node) { + function onSubstituteNode(hint: ts.EmitHint, node: ts.Node) { node = previousOnSubstituteNode(hint, node); - if (hint === EmitHint.Expression) { - return substituteExpression(node as Expression); + if (hint === ts.EmitHint.Expression) { + return substituteExpression(node as ts.Expression); } return node; } - function substituteExpression(node: Expression) { + function substituteExpression(node: ts.Expression) { switch (node.kind) { - case SyntaxKind.Identifier: - return substituteExpressionIdentifier(node as Identifier); - case SyntaxKind.ThisKeyword: - return substituteThisExpression(node as ThisExpression); + case ts.SyntaxKind.Identifier: + return substituteExpressionIdentifier(node as ts.Identifier); + case ts.SyntaxKind.ThisKeyword: + return substituteThisExpression(node as ts.ThisExpression); } return node; } - function substituteThisExpression(node: ThisExpression) { + function substituteThisExpression(node: ts.ThisExpression) { if (enabledSubstitutions & ClassPropertySubstitutionFlags.ClassStaticThisOrSuperReference && currentClassLexicalEnvironment) { const { facts, classConstructor } = currentClassLexicalEnvironment; if (facts & ClassFacts.ClassWasDecorated) { return factory.createParenthesizedExpression(factory.createVoidZero()); } if (classConstructor) { - return setTextRange( - setOriginalNode( - factory.cloneNode(classConstructor), - node, - ), - node - ); + return ts.setTextRange(ts.setOriginalNode(factory.cloneNode(classConstructor), node), node); } } return node; } - function substituteExpressionIdentifier(node: Identifier): Expression { + function substituteExpressionIdentifier(node: ts.Identifier): ts.Expression { return trySubstituteClassAlias(node) || node; } - function trySubstituteClassAlias(node: Identifier): Expression | undefined { + function trySubstituteClassAlias(node: ts.Identifier): ts.Expression | undefined { if (enabledSubstitutions & ClassPropertySubstitutionFlags.ClassAliases) { - if (resolver.getNodeCheckFlags(node) & NodeCheckFlags.ConstructorReferenceInClass) { + if (resolver.getNodeCheckFlags(node) & ts.NodeCheckFlags.ConstructorReferenceInClass) { // Due to the emit for class decorators, any reference to the class from inside of the class body // must instead be rewritten to point to a temporary variable to avoid issues with the double-bind // behavior of class names in ES6. @@ -1752,8 +1497,8 @@ namespace ts { const classAlias = classAliases[declaration.id!]; // TODO: GH#18217 if (classAlias) { const clone = factory.cloneNode(classAlias); - setSourceMapRange(clone, node); - setCommentRange(clone, node); + ts.setSourceMapRange(clone, node); + ts.setCommentRange(clone, node); return clone; } } @@ -1768,15 +1513,15 @@ namespace ts { * value of the result or the expression itself if the value is either unused or safe to inline into multiple locations * @param shouldHoist Does the expression need to be reused? (ie, for an initializer or a decorator) */ - function getPropertyNameExpressionIfNeeded(name: PropertyName, shouldHoist: boolean): Expression | undefined { - if (isComputedPropertyName(name)) { - const expression = visitNode(name.expression, visitor, isExpression); - const innerExpression = skipPartiallyEmittedExpressions(expression); - const inlinable = isSimpleInlineableExpression(innerExpression); - const alreadyTransformed = isAssignmentExpression(innerExpression) && isGeneratedIdentifier(innerExpression.left); + function getPropertyNameExpressionIfNeeded(name: ts.PropertyName, shouldHoist: boolean): ts.Expression | undefined { + if (ts.isComputedPropertyName(name)) { + const expression = ts.visitNode(name.expression, visitor, ts.isExpression); + const innerExpression = ts.skipPartiallyEmittedExpressions(expression); + const inlinable = ts.isSimpleInlineableExpression(innerExpression); + const alreadyTransformed = ts.isAssignmentExpression(innerExpression) && ts.isGeneratedIdentifier(innerExpression.left); if (!alreadyTransformed && !inlinable && shouldHoist) { const generatedName = factory.getGeneratedNameForNode(name); - if (resolver.getNodeCheckFlags(name) & NodeCheckFlags.BlockScopedBindingInLoop) { + if (resolver.getNodeCheckFlags(name) & ts.NodeCheckFlags.BlockScopedBindingInLoop) { addBlockScopedVariable(generatedName); } else { @@ -1784,7 +1529,7 @@ namespace ts { } return factory.createAssignment(generatedName, expression); } - return (inlinable || isIdentifier(innerExpression)) ? undefined : expression; + return (inlinable || ts.isIdentifier(innerExpression)) ? undefined : expression; } } @@ -1810,7 +1555,7 @@ namespace ts { const lex = getClassLexicalEnvironment(); lex.privateIdentifierEnvironment ||= { className: "", - identifiers: new Map() + identifiers: new ts.Map() }; return lex.privateIdentifierEnvironment; } @@ -1819,23 +1564,23 @@ namespace ts { return pendingExpressions || (pendingExpressions = []); } - function addPrivateIdentifierToEnvironment(node: PrivateClassElementDeclaration) { - const text = getTextOfPropertyName(node.name) as string; + function addPrivateIdentifierToEnvironment(node: ts.PrivateClassElementDeclaration) { + const text = ts.getTextOfPropertyName(node.name) as string; const lex = getClassLexicalEnvironment(); const { classConstructor } = lex; const privateEnv = getPrivateIdentifierEnvironment(); const { weakSetName } = privateEnv; - const assignmentExpressions: Expression[] = []; + const assignmentExpressions: ts.Expression[] = []; const privateName = node.name.escapedText; const previousInfo = privateEnv.identifiers.get(privateName); const isValid = !isReservedPrivateName(node.name) && previousInfo === undefined; - if (hasStaticModifier(node)) { - Debug.assert(classConstructor, "weakSetName should be set in private identifier environment"); - if (isPropertyDeclaration(node)) { + if (ts.hasStaticModifier(node)) { + ts.Debug.assert(classConstructor, "weakSetName should be set in private identifier environment"); + if (ts.isPropertyDeclaration(node)) { const variableName = createHoistedVariableForPrivateName(text, node); privateEnv.identifiers.set(privateName, { kind: PrivateIdentifierKind.Field, @@ -1845,7 +1590,7 @@ namespace ts { isValid, }); } - else if (isMethodDeclaration(node)) { + else if (ts.isMethodDeclaration(node)) { const functionName = createHoistedVariableForPrivateName(text, node); privateEnv.identifiers.set(privateName, { kind: PrivateIdentifierKind.Method, @@ -1855,7 +1600,7 @@ namespace ts { isValid, }); } - else if (isGetAccessorDeclaration(node)) { + else if (ts.isGetAccessorDeclaration(node)) { const getterName = createHoistedVariableForPrivateName(text + "_get", node); if (previousInfo?.kind === PrivateIdentifierKind.Accessor && previousInfo.isStatic && !previousInfo.getterName) { previousInfo.getterName = getterName; @@ -1871,7 +1616,7 @@ namespace ts { }); } } - else if (isSetAccessorDeclaration(node)) { + else if (ts.isSetAccessorDeclaration(node)) { const setterName = createHoistedVariableForPrivateName(text + "_set", node); if (previousInfo?.kind === PrivateIdentifierKind.Accessor && previousInfo.isStatic && !previousInfo.setterName) { previousInfo.setterName = setterName; @@ -1888,10 +1633,10 @@ namespace ts { } } else { - Debug.assertNever(node, "Unknown class element type."); + ts.Debug.assertNever(node, "Unknown class element type."); } } - else if (isPropertyDeclaration(node)) { + else if (ts.isPropertyDeclaration(node)) { const weakMapName = createHoistedVariableForPrivateName(text, node); privateEnv.identifiers.set(privateName, { kind: PrivateIdentifierKind.Field, @@ -1901,17 +1646,11 @@ namespace ts { isValid, }); - assignmentExpressions.push(factory.createAssignment( - weakMapName, - factory.createNewExpression( - factory.createIdentifier("WeakMap"), - /*typeArguments*/ undefined, - [] - ) - )); + assignmentExpressions.push(factory.createAssignment(weakMapName, factory.createNewExpression(factory.createIdentifier("WeakMap"), + /*typeArguments*/ undefined, []))); } - else if (isMethodDeclaration(node)) { - Debug.assert(weakSetName, "weakSetName should be set in private identifier environment"); + else if (ts.isMethodDeclaration(node)) { + ts.Debug.assert(weakSetName, "weakSetName should be set in private identifier environment"); privateEnv.identifiers.set(privateName, { kind: PrivateIdentifierKind.Method, @@ -1921,10 +1660,9 @@ namespace ts { isValid, }); } - else if (isAccessor(node)) { - Debug.assert(weakSetName, "weakSetName should be set in private identifier environment"); - - if (isGetAccessor(node)) { + else if (ts.isAccessor(node)) { + ts.Debug.assert(weakSetName, "weakSetName should be set in private identifier environment"); + if (ts.isGetAccessor(node)) { const getterName = createHoistedVariableForPrivateName(text + "_get", node); if (previousInfo?.kind === PrivateIdentifierKind.Accessor && !previousInfo.isStatic && !previousInfo.getterName) { @@ -1960,18 +1698,17 @@ namespace ts { } } else { - Debug.assertNever(node, "Unknown class element type."); + ts.Debug.assertNever(node, "Unknown class element type."); } getPendingExpressions().push(...assignmentExpressions); } - function createHoistedVariableForClass(name: string, node: PrivateIdentifier | ClassStaticBlockDeclaration): Identifier { + function createHoistedVariableForClass(name: string, node: ts.PrivateIdentifier | ts.ClassStaticBlockDeclaration): ts.Identifier { const { className } = getPrivateIdentifierEnvironment(); const prefix = className ? `_${className}` : ""; - const identifier = factory.createUniqueName(`${prefix}_${name}`, GeneratedIdentifierFlags.Optimistic); - - if (resolver.getNodeCheckFlags(node) & NodeCheckFlags.BlockScopedBindingInLoop) { + const identifier = factory.createUniqueName(`${prefix}_${name}`, ts.GeneratedIdentifierFlags.Optimistic); + if (resolver.getNodeCheckFlags(node) & ts.NodeCheckFlags.BlockScopedBindingInLoop) { addBlockScopedVariable(identifier); } else { @@ -1981,11 +1718,11 @@ namespace ts { return identifier; } - function createHoistedVariableForPrivateName(privateName: string, node: PrivateClassElementDeclaration): Identifier { + function createHoistedVariableForPrivateName(privateName: string, node: ts.PrivateClassElementDeclaration): ts.Identifier { return createHoistedVariableForClass(privateName.substring(1), node.name); } - function accessPrivateIdentifier(name: PrivateIdentifier) { + function accessPrivateIdentifier(name: ts.PrivateIdentifier) { if (currentClassLexicalEnvironment?.privateIdentifierEnvironment) { const info = currentClassLexicalEnvironment.privateIdentifierEnvironment.identifiers.get(name.escapedText); if (info) { @@ -2005,39 +1742,30 @@ namespace ts { return undefined; } - function wrapPrivateIdentifierForDestructuringTarget(node: PrivateIdentifierPropertyAccessExpression) { + function wrapPrivateIdentifierForDestructuringTarget(node: ts.PrivateIdentifierPropertyAccessExpression) { const parameter = factory.getGeneratedNameForNode(node); const info = accessPrivateIdentifier(node.name); if (!info) { - return visitEachChild(node, visitor, context); + return ts.visitEachChild(node, visitor, context); } let receiver = node.expression; // We cannot copy `this` or `super` into the function because they will be bound // differently inside the function. - if (isThisProperty(node) || isSuperProperty(node) || !isSimpleCopiableExpression(node.expression)) { + if (ts.isThisProperty(node) || ts.isSuperProperty(node) || !ts.isSimpleCopiableExpression(node.expression)) { receiver = factory.createTempVariable(hoistVariableDeclaration, /*reservedInNestedScopes*/ true); - getPendingExpressions().push(factory.createBinaryExpression(receiver, SyntaxKind.EqualsToken, visitNode(node.expression, visitor, isExpression))); + getPendingExpressions().push(factory.createBinaryExpression(receiver, ts.SyntaxKind.EqualsToken, ts.visitNode(node.expression, visitor, ts.isExpression))); } - return factory.createAssignmentTargetWrapper( - parameter, - createPrivateIdentifierAssignment( - info, - receiver, - parameter, - SyntaxKind.EqualsToken - ) - ); + return factory.createAssignmentTargetWrapper(parameter, createPrivateIdentifierAssignment(info, receiver, parameter, ts.SyntaxKind.EqualsToken)); } - - function visitArrayAssignmentTarget(node: BindingOrAssignmentElement) { - const target = getTargetOfBindingOrAssignmentElement(node); + function visitArrayAssignmentTarget(node: ts.BindingOrAssignmentElement) { + const target = ts.getTargetOfBindingOrAssignmentElement(node); if (target) { - let wrapped: LeftHandSideExpression | undefined; - if (isPrivateIdentifierPropertyAccessExpression(target)) { + let wrapped: ts.LeftHandSideExpression | undefined; + if (ts.isPrivateIdentifierPropertyAccessExpression(target)) { wrapped = wrapPrivateIdentifierForDestructuringTarget(target); } else if (shouldTransformSuperInStaticInitializers && - isSuperProperty(target) && + ts.isSuperProperty(target) && currentStaticPropertyDeclarationOrStaticBlock && currentClassLexicalEnvironment) { const { classConstructor, superClassReference, facts } = currentClassLexicalEnvironment; @@ -2045,34 +1773,20 @@ namespace ts { wrapped = visitInvalidSuperProperty(target); } else if (classConstructor && superClassReference) { - const name = - isElementAccessExpression(target) ? visitNode(target.argumentExpression, visitor, isExpression) : - isIdentifier(target.name) ? factory.createStringLiteralFromNode(target.name) : + const name = ts.isElementAccessExpression(target) ? ts.visitNode(target.argumentExpression, visitor, ts.isExpression) : + ts.isIdentifier(target.name) ? factory.createStringLiteralFromNode(target.name) : undefined; if (name) { const temp = factory.createTempVariable(/*recordTempVariable*/ undefined); - wrapped = factory.createAssignmentTargetWrapper( - temp, - factory.createReflectSetCall( - superClassReference, - name, - temp, - classConstructor, - ) - ); + wrapped = factory.createAssignmentTargetWrapper(temp, factory.createReflectSetCall(superClassReference, name, temp, classConstructor)); } } } if (wrapped) { - if (isAssignmentExpression(node)) { - return factory.updateBinaryExpression( - node, - wrapped, - node.operatorToken, - visitNode(node.right, visitor, isExpression) - ); + if (ts.isAssignmentExpression(node)) { + return factory.updateBinaryExpression(node, wrapped, node.operatorToken, ts.visitNode(node.right, visitor, ts.isExpression)); } - else if (isSpreadElement(node)) { + else if (ts.isSpreadElement(node)) { return factory.updateSpreadElement(node, wrapped); } else { @@ -2080,19 +1794,19 @@ namespace ts { } } } - return visitNode(node, visitorDestructuringTarget); + return ts.visitNode(node, visitorDestructuringTarget); } - function visitObjectAssignmentTarget(node: ObjectLiteralElementLike) { - if (isObjectBindingOrAssignmentElement(node) && !isShorthandPropertyAssignment(node)) { - const target = getTargetOfBindingOrAssignmentElement(node); - let wrapped: LeftHandSideExpression | undefined; + function visitObjectAssignmentTarget(node: ts.ObjectLiteralElementLike) { + if (ts.isObjectBindingOrAssignmentElement(node) && !ts.isShorthandPropertyAssignment(node)) { + const target = ts.getTargetOfBindingOrAssignmentElement(node); + let wrapped: ts.LeftHandSideExpression | undefined; if (target) { - if (isPrivateIdentifierPropertyAccessExpression(target)) { + if (ts.isPrivateIdentifierPropertyAccessExpression(target)) { wrapped = wrapPrivateIdentifierForDestructuringTarget(target); } else if (shouldTransformSuperInStaticInitializers && - isSuperProperty(target) && + ts.isSuperProperty(target) && currentStaticPropertyDeclarationOrStaticBlock && currentClassLexicalEnvironment) { const { classConstructor, superClassReference, facts } = currentClassLexicalEnvironment; @@ -2100,48 +1814,31 @@ namespace ts { wrapped = visitInvalidSuperProperty(target); } else if (classConstructor && superClassReference) { - const name = - isElementAccessExpression(target) ? visitNode(target.argumentExpression, visitor, isExpression) : - isIdentifier(target.name) ? factory.createStringLiteralFromNode(target.name) : + const name = ts.isElementAccessExpression(target) ? ts.visitNode(target.argumentExpression, visitor, ts.isExpression) : + ts.isIdentifier(target.name) ? factory.createStringLiteralFromNode(target.name) : undefined; if (name) { const temp = factory.createTempVariable(/*recordTempVariable*/ undefined); - wrapped = factory.createAssignmentTargetWrapper( - temp, - factory.createReflectSetCall( - superClassReference, - name, - temp, - classConstructor, - ) - ); + wrapped = factory.createAssignmentTargetWrapper(temp, factory.createReflectSetCall(superClassReference, name, temp, classConstructor)); } } } } - if (isPropertyAssignment(node)) { - const initializer = getInitializerOfBindingOrAssignmentElement(node); - return factory.updatePropertyAssignment( - node, - visitNode(node.name, visitor, isPropertyName), - wrapped ? - initializer ? factory.createAssignment(wrapped, visitNode(initializer, visitor)) : wrapped : - visitNode(node.initializer, visitorDestructuringTarget, isExpression) - ); + if (ts.isPropertyAssignment(node)) { + const initializer = ts.getInitializerOfBindingOrAssignmentElement(node); + return factory.updatePropertyAssignment(node, ts.visitNode(node.name, visitor, ts.isPropertyName), wrapped ? + initializer ? factory.createAssignment(wrapped, ts.visitNode(initializer, visitor)) : wrapped : + ts.visitNode(node.initializer, visitorDestructuringTarget, ts.isExpression)); } - if (isSpreadAssignment(node)) { - return factory.updateSpreadAssignment( - node, - wrapped || visitNode(node.expression, visitorDestructuringTarget, isExpression) - ); + if (ts.isSpreadAssignment(node)) { + return factory.updateSpreadAssignment(node, wrapped || ts.visitNode(node.expression, visitorDestructuringTarget, ts.isExpression)); } - Debug.assert(wrapped === undefined, "Should not have generated a wrapped target"); + ts.Debug.assert(wrapped === undefined, "Should not have generated a wrapped target"); } - return visitNode(node, visitor); + return ts.visitNode(node, visitor); } - - function visitAssignmentPattern(node: AssignmentPattern) { - if (isArrayLiteralExpression(node)) { + function visitAssignmentPattern(node: ts.AssignmentPattern) { + if (ts.isArrayLiteralExpression(node)) { // Transforms private names in destructuring assignment array bindings. // Transforms SuperProperty assignments in destructuring assignment array bindings in static initializers. // @@ -2150,10 +1847,7 @@ namespace ts { // // Transformation: // [ { set value(x) { this.#myProp = x; } }.value ] = [ "hello" ]; - return factory.updateArrayLiteralExpression( - node, - visitNodes(node.elements, visitArrayAssignmentTarget, isExpression) - ); + return factory.updateArrayLiteralExpression(node, ts.visitNodes(node.elements, visitArrayAssignmentTarget, ts.isExpression)); } else { // Transforms private names in destructuring assignment object bindings. @@ -2164,40 +1858,25 @@ namespace ts { // // Transformation: // ({ stringProperty: { set value(x) { this.#myProp = x; } }.value }) = { stringProperty: "hello" }; - return factory.updateObjectLiteralExpression( - node, - visitNodes(node.properties, visitObjectAssignmentTarget, isObjectLiteralElementLike) - ); + return factory.updateObjectLiteralExpression(node, ts.visitNodes(node.properties, visitObjectAssignmentTarget, ts.isObjectLiteralElementLike)); } } } - function createPrivateStaticFieldInitializer(variableName: Identifier, initializer: Expression | undefined) { - return factory.createAssignment( - variableName, - factory.createObjectLiteralExpression([ - factory.createPropertyAssignment("value", initializer || factory.createVoidZero()) - ]) - ); + function createPrivateStaticFieldInitializer(variableName: ts.Identifier, initializer: ts.Expression | undefined) { + return ts.factory.createAssignment(variableName, ts.factory.createObjectLiteralExpression([ + ts.factory.createPropertyAssignment("value", initializer || ts.factory.createVoidZero()) + ])); } - - function createPrivateInstanceFieldInitializer(receiver: LeftHandSideExpression, initializer: Expression | undefined, weakMapName: Identifier) { - return factory.createCallExpression( - factory.createPropertyAccessExpression(weakMapName, "set"), - /*typeArguments*/ undefined, - [receiver, initializer || factory.createVoidZero()] - ); + function createPrivateInstanceFieldInitializer(receiver: ts.LeftHandSideExpression, initializer: ts.Expression | undefined, weakMapName: ts.Identifier) { + return ts.factory.createCallExpression(ts.factory.createPropertyAccessExpression(weakMapName, "set"), + /*typeArguments*/ undefined, [receiver, initializer || ts.factory.createVoidZero()]); } - - function createPrivateInstanceMethodInitializer(receiver: LeftHandSideExpression, weakSetName: Identifier) { - return factory.createCallExpression( - factory.createPropertyAccessExpression(weakSetName, "add"), - /*typeArguments*/ undefined, - [receiver] - ); + function createPrivateInstanceMethodInitializer(receiver: ts.LeftHandSideExpression, weakSetName: ts.Identifier) { + return ts.factory.createCallExpression(ts.factory.createPropertyAccessExpression(weakSetName, "add"), + /*typeArguments*/ undefined, [receiver]); } - - function isReservedPrivateName(node: PrivateIdentifier) { + function isReservedPrivateName(node: ts.PrivateIdentifier) { return node.escapedText === "#constructor"; } } diff --git a/src/compiler/transformers/declarations.ts b/src/compiler/transformers/declarations.ts index b855fd4b8dab5..e1385abd802af 100644 --- a/src/compiler/transformers/declarations.ts +++ b/src/compiler/transformers/declarations.ts @@ -1,47 +1,43 @@ /*@internal*/ namespace ts { - export function getDeclarationDiagnostics(host: EmitHost, resolver: EmitResolver, file: SourceFile | undefined): DiagnosticWithLocation[] | undefined { + export function getDeclarationDiagnostics(host: ts.EmitHost, resolver: ts.EmitResolver, file: ts.SourceFile | undefined): ts.DiagnosticWithLocation[] | undefined { const compilerOptions = host.getCompilerOptions(); - const result = transformNodes(resolver, host, factory, compilerOptions, file ? [file] : filter(host.getSourceFiles(), isSourceFileNotJson), [transformDeclarations], /*allowDtsFiles*/ false); + const result = ts.transformNodes(resolver, host, ts.factory, compilerOptions, file ? [file] : ts.filter(host.getSourceFiles(), ts.isSourceFileNotJson), [transformDeclarations], /*allowDtsFiles*/ false); return result.diagnostics; } - function hasInternalAnnotation(range: CommentRange, currentSourceFile: SourceFile) { + function hasInternalAnnotation(range: ts.CommentRange, currentSourceFile: ts.SourceFile) { const comment = currentSourceFile.text.substring(range.pos, range.end); - return stringContains(comment, "@internal"); + return ts.stringContains(comment, "@internal"); } - - export function isInternalDeclaration(node: Node, currentSourceFile: SourceFile) { - const parseTreeNode = getParseTreeNode(node); - if (parseTreeNode && parseTreeNode.kind === SyntaxKind.Parameter) { - const paramIdx = (parseTreeNode.parent as SignatureDeclaration).parameters.indexOf(parseTreeNode as ParameterDeclaration); - const previousSibling = paramIdx > 0 ? (parseTreeNode.parent as SignatureDeclaration).parameters[paramIdx - 1] : undefined; + export function isInternalDeclaration(node: ts.Node, currentSourceFile: ts.SourceFile) { + const parseTreeNode = ts.getParseTreeNode(node); + if (parseTreeNode && parseTreeNode.kind === ts.SyntaxKind.Parameter) { + const paramIdx = (parseTreeNode.parent as ts.SignatureDeclaration).parameters.indexOf(parseTreeNode as ts.ParameterDeclaration); + const previousSibling = paramIdx > 0 ? (parseTreeNode.parent as ts.SignatureDeclaration).parameters[paramIdx - 1] : undefined; const text = currentSourceFile.text; const commentRanges = previousSibling - ? concatenate( + ? ts.concatenate( // to handle // ... parameters, /* @internal */ // public param: string - getTrailingCommentRanges(text, skipTrivia(text, previousSibling.end + 1, /* stopAfterLineBreak */ false, /* stopAtComments */ true)), - getLeadingCommentRanges(text, node.pos) - ) - : getTrailingCommentRanges(text, skipTrivia(text, node.pos, /* stopAfterLineBreak */ false, /* stopAtComments */ true)); - return commentRanges && commentRanges.length && hasInternalAnnotation(last(commentRanges), currentSourceFile); + ts.getTrailingCommentRanges(text, ts.skipTrivia(text, previousSibling.end + 1, /* stopAfterLineBreak */ false, /* stopAtComments */ true)), ts.getLeadingCommentRanges(text, node.pos)) + : ts.getTrailingCommentRanges(text, ts.skipTrivia(text, node.pos, /* stopAfterLineBreak */ false, /* stopAtComments */ true)); + return commentRanges && commentRanges.length && hasInternalAnnotation(ts.last(commentRanges), currentSourceFile); } - const leadingCommentRanges = parseTreeNode && getLeadingCommentRangesOfNode(parseTreeNode, currentSourceFile); - return !!forEach(leadingCommentRanges, range => { + const leadingCommentRanges = parseTreeNode && ts.getLeadingCommentRangesOfNode(parseTreeNode, currentSourceFile); + return !!ts.forEach(leadingCommentRanges, range => { return hasInternalAnnotation(range, currentSourceFile); }); } - const declarationEmitNodeBuilderFlags = - NodeBuilderFlags.MultilineObjectLiterals | - NodeBuilderFlags.WriteClassExpressionAsTypeLiteral | - NodeBuilderFlags.UseTypeOfFunction | - NodeBuilderFlags.UseStructuralFallback | - NodeBuilderFlags.AllowEmptyTuple | - NodeBuilderFlags.GenerateNamesForShadowedTypeParams | - NodeBuilderFlags.NoTruncation; + const declarationEmitNodeBuilderFlags = ts.NodeBuilderFlags.MultilineObjectLiterals | + ts.NodeBuilderFlags.WriteClassExpressionAsTypeLiteral | + ts.NodeBuilderFlags.UseTypeOfFunction | + ts.NodeBuilderFlags.UseStructuralFallback | + ts.NodeBuilderFlags.AllowEmptyTuple | + ts.NodeBuilderFlags.GenerateNamesForShadowedTypeParams | + ts.NodeBuilderFlags.NoTruncation; /** * Transforms a ts file into a .d.ts file @@ -49,24 +45,27 @@ namespace ts { * in many places this transformer assumes it will be operating on parse tree nodes directly. * This means that _no transforms should be allowed to occur before this one_. */ - export function transformDeclarations(context: TransformationContext) { - const throwDiagnostic = () => Debug.fail("Diagnostic emitted without context"); - let getSymbolAccessibilityDiagnostic: GetSymbolAccessibilityDiagnostic = throwDiagnostic; + export function transformDeclarations(context: ts.TransformationContext) { + const throwDiagnostic = () => ts.Debug.fail("Diagnostic emitted without context"); + let getSymbolAccessibilityDiagnostic: ts.GetSymbolAccessibilityDiagnostic = throwDiagnostic; let needsDeclare = true; let isBundledEmit = false; let resultHasExternalModuleIndicator = false; let needsScopeFixMarker = false; let resultHasScopeMarker = false; - let enclosingDeclaration: Node; - let necessaryTypeReferences: Set<[specifier: string, mode: SourceFile["impliedNodeFormat"] | undefined]> | undefined; - let lateMarkedStatements: LateVisibilityPaintedStatement[] | undefined; - let lateStatementReplacementMap: ESMap>; + let enclosingDeclaration: ts.Node; + let necessaryTypeReferences: ts.Set<[ + specifier: string, + mode: ts.SourceFile["impliedNodeFormat"] | undefined + ]> | undefined; + let lateMarkedStatements: ts.LateVisibilityPaintedStatement[] | undefined; + let lateStatementReplacementMap: ts.ESMap>; let suppressNewDiagnosticContexts: boolean; - let exportedModulesFromDeclarationEmit: Symbol[] | undefined; + let exportedModulesFromDeclarationEmit: ts.Symbol[] | undefined; const { factory } = context; const host = context.getEmitHost(); - const symbolTracker: SymbolTracker = { + const symbolTracker: ts.SymbolTracker = { trackSymbol, reportInaccessibleThisError, reportInaccessibleUniqueSymbolError, @@ -80,41 +79,43 @@ namespace ts { reportNonlocalAugmentation, reportNonSerializableProperty }; - let errorNameNode: DeclarationName | undefined; - let errorFallbackNode: Declaration | undefined; - - let currentSourceFile: SourceFile; - let refs: ESMap; - let libs: ESMap; - let emittedImports: readonly AnyImportSyntax[] | undefined; // must be declared in container so it can be `undefined` while transformer's first pass + let errorNameNode: ts.DeclarationName | undefined; + let errorFallbackNode: ts.Declaration | undefined; + let currentSourceFile: ts.SourceFile; + let refs: ts.ESMap; + let libs: ts.ESMap; + let emittedImports: readonly ts.AnyImportSyntax[] | undefined; // must be declared in container so it can be `undefined` while transformer's first pass const resolver = context.getEmitResolver(); const options = context.getCompilerOptions(); const { noResolve, stripInternal } = options; return transformRoot; - function recordTypeReferenceDirectivesIfNecessary(typeReferenceDirectives: readonly [specifier: string, mode: SourceFile["impliedNodeFormat"] | undefined][] | undefined): void { + function recordTypeReferenceDirectivesIfNecessary(typeReferenceDirectives: readonly [ + specifier: string, + mode: ts.SourceFile["impliedNodeFormat"] | undefined + ][] | undefined): void { if (!typeReferenceDirectives) { return; } - necessaryTypeReferences = necessaryTypeReferences || new Set(); + necessaryTypeReferences = necessaryTypeReferences || new ts.Set(); for (const ref of typeReferenceDirectives) { necessaryTypeReferences.add(ref); } } - function trackReferencedAmbientModule(node: ModuleDeclaration, symbol: Symbol) { + function trackReferencedAmbientModule(node: ts.ModuleDeclaration, symbol: ts.Symbol) { // If it is visible via `// `, then we should just use that - const directives = resolver.getTypeReferenceDirectivesForSymbol(symbol, SymbolFlags.All); - if (length(directives)) { + const directives = resolver.getTypeReferenceDirectivesForSymbol(symbol, ts.SymbolFlags.All); + if (ts.length(directives)) { return recordTypeReferenceDirectivesIfNecessary(directives); } // Otherwise we should emit a path-based reference - const container = getSourceFileOfNode(node); - refs.set(getOriginalNodeId(container), container); + const container = ts.getSourceFileOfNode(node); + refs.set(ts.getOriginalNodeId(container), container); } - function handleSymbolAccessibilityError(symbolAccessibilityResult: SymbolAccessibilityResult) { - if (symbolAccessibilityResult.accessibility === SymbolAccessibility.Accessible) { + function handleSymbolAccessibilityError(symbolAccessibilityResult: ts.SymbolAccessibilityResult) { + if (symbolAccessibilityResult.accessibility === ts.SymbolAccessibility.Accessible) { // Add aliases back onto the possible imports list if they're not there so we can try them again with updated visibility info if (symbolAccessibilityResult && symbolAccessibilityResult.aliasesToMakeVisible) { if (!lateMarkedStatements) { @@ -122,7 +123,7 @@ namespace ts { } else { for (const ref of symbolAccessibilityResult.aliasesToMakeVisible) { - pushIfUnique(lateMarkedStatements, ref); + ts.pushIfUnique(lateMarkedStatements, ref); } } } @@ -134,17 +135,10 @@ namespace ts { const errorInfo = getSymbolAccessibilityDiagnostic(symbolAccessibilityResult); if (errorInfo) { if (errorInfo.typeName) { - context.addDiagnostic(createDiagnosticForNode(symbolAccessibilityResult.errorNode || errorInfo.errorNode, - errorInfo.diagnosticMessage, - getTextOfNode(errorInfo.typeName), - symbolAccessibilityResult.errorSymbolName, - symbolAccessibilityResult.errorModuleName)); + context.addDiagnostic(ts.createDiagnosticForNode(symbolAccessibilityResult.errorNode || errorInfo.errorNode, errorInfo.diagnosticMessage, ts.getTextOfNode(errorInfo.typeName), symbolAccessibilityResult.errorSymbolName, symbolAccessibilityResult.errorModuleName)); } else { - context.addDiagnostic(createDiagnosticForNode(symbolAccessibilityResult.errorNode || errorInfo.errorNode, - errorInfo.diagnosticMessage, - symbolAccessibilityResult.errorSymbolName, - symbolAccessibilityResult.errorModuleName)); + context.addDiagnostic(ts.createDiagnosticForNode(symbolAccessibilityResult.errorNode || errorInfo.errorNode, errorInfo.diagnosticMessage, symbolAccessibilityResult.errorSymbolName, symbolAccessibilityResult.errorModuleName)); } return true; } @@ -152,14 +146,15 @@ namespace ts { return false; } - function trackExternalModuleSymbolOfImportTypeNode(symbol: Symbol) { + function trackExternalModuleSymbolOfImportTypeNode(symbol: ts.Symbol) { if (!isBundledEmit) { (exportedModulesFromDeclarationEmit || (exportedModulesFromDeclarationEmit = [])).push(symbol); } } - function trackSymbol(symbol: Symbol, enclosingDeclaration?: Node, meaning?: SymbolFlags) { - if (symbol.flags & SymbolFlags.TypeParameter) return false; + function trackSymbol(symbol: ts.Symbol, enclosingDeclaration?: ts.Node, meaning?: ts.SymbolFlags) { + if (symbol.flags & ts.SymbolFlags.TypeParameter) + return false; const issuedDiagnostic = handleSymbolAccessibilityError(resolver.isSymbolAccessible(symbol, enclosingDeclaration, meaning, /*shouldComputeAliasesToMakeVisible*/ true)); recordTypeReferenceDirectivesIfNecessary(resolver.getTypeReferenceDirectivesForSymbol(symbol, meaning)); return issuedDiagnostic; @@ -167,80 +162,69 @@ namespace ts { function reportPrivateInBaseOfClassExpression(propertyName: string) { if (errorNameNode || errorFallbackNode) { - context.addDiagnostic( - createDiagnosticForNode((errorNameNode || errorFallbackNode)!, Diagnostics.Property_0_of_exported_class_expression_may_not_be_private_or_protected, propertyName)); + context.addDiagnostic(ts.createDiagnosticForNode((errorNameNode || errorFallbackNode)!, ts.Diagnostics.Property_0_of_exported_class_expression_may_not_be_private_or_protected, propertyName)); } } function errorDeclarationNameWithFallback() { - return errorNameNode ? declarationNameToString(errorNameNode) : - errorFallbackNode && getNameOfDeclaration(errorFallbackNode) ? declarationNameToString(getNameOfDeclaration(errorFallbackNode)) : - errorFallbackNode && isExportAssignment(errorFallbackNode) ? errorFallbackNode.isExportEquals ? "export=" : "default" : + return errorNameNode ? ts.declarationNameToString(errorNameNode) : + errorFallbackNode && ts.getNameOfDeclaration(errorFallbackNode) ? ts.declarationNameToString(ts.getNameOfDeclaration(errorFallbackNode)) : + errorFallbackNode && ts.isExportAssignment(errorFallbackNode) ? errorFallbackNode.isExportEquals ? "export=" : "default" : "(Missing)"; // same fallback declarationNameToString uses when node is zero-width (ie, nameless) } function reportInaccessibleUniqueSymbolError() { if (errorNameNode || errorFallbackNode) { - context.addDiagnostic(createDiagnosticForNode((errorNameNode || errorFallbackNode)!, Diagnostics.The_inferred_type_of_0_references_an_inaccessible_1_type_A_type_annotation_is_necessary, - errorDeclarationNameWithFallback(), - "unique symbol")); + context.addDiagnostic(ts.createDiagnosticForNode((errorNameNode || errorFallbackNode)!, ts.Diagnostics.The_inferred_type_of_0_references_an_inaccessible_1_type_A_type_annotation_is_necessary, errorDeclarationNameWithFallback(), "unique symbol")); } } function reportCyclicStructureError() { if (errorNameNode || errorFallbackNode) { - context.addDiagnostic(createDiagnosticForNode((errorNameNode || errorFallbackNode)!, Diagnostics.The_inferred_type_of_0_references_a_type_with_a_cyclic_structure_which_cannot_be_trivially_serialized_A_type_annotation_is_necessary, - errorDeclarationNameWithFallback())); + context.addDiagnostic(ts.createDiagnosticForNode((errorNameNode || errorFallbackNode)!, ts.Diagnostics.The_inferred_type_of_0_references_a_type_with_a_cyclic_structure_which_cannot_be_trivially_serialized_A_type_annotation_is_necessary, errorDeclarationNameWithFallback())); } } function reportInaccessibleThisError() { if (errorNameNode || errorFallbackNode) { - context.addDiagnostic(createDiagnosticForNode((errorNameNode || errorFallbackNode)!, Diagnostics.The_inferred_type_of_0_references_an_inaccessible_1_type_A_type_annotation_is_necessary, - errorDeclarationNameWithFallback(), - "this")); + context.addDiagnostic(ts.createDiagnosticForNode((errorNameNode || errorFallbackNode)!, ts.Diagnostics.The_inferred_type_of_0_references_an_inaccessible_1_type_A_type_annotation_is_necessary, errorDeclarationNameWithFallback(), "this")); } } function reportLikelyUnsafeImportRequiredError(specifier: string) { if (errorNameNode || errorFallbackNode) { - context.addDiagnostic(createDiagnosticForNode((errorNameNode || errorFallbackNode)!, Diagnostics.The_inferred_type_of_0_cannot_be_named_without_a_reference_to_1_This_is_likely_not_portable_A_type_annotation_is_necessary, - errorDeclarationNameWithFallback(), - specifier)); + context.addDiagnostic(ts.createDiagnosticForNode((errorNameNode || errorFallbackNode)!, ts.Diagnostics.The_inferred_type_of_0_cannot_be_named_without_a_reference_to_1_This_is_likely_not_portable_A_type_annotation_is_necessary, errorDeclarationNameWithFallback(), specifier)); } } function reportTruncationError() { if (errorNameNode || errorFallbackNode) { - context.addDiagnostic(createDiagnosticForNode((errorNameNode || errorFallbackNode)!, Diagnostics.The_inferred_type_of_this_node_exceeds_the_maximum_length_the_compiler_will_serialize_An_explicit_type_annotation_is_needed)); + context.addDiagnostic(ts.createDiagnosticForNode((errorNameNode || errorFallbackNode)!, ts.Diagnostics.The_inferred_type_of_this_node_exceeds_the_maximum_length_the_compiler_will_serialize_An_explicit_type_annotation_is_needed)); } } - function reportNonlocalAugmentation(containingFile: SourceFile, parentSymbol: Symbol, symbol: Symbol) { - const primaryDeclaration = parentSymbol.declarations?.find(d => getSourceFileOfNode(d) === containingFile)!; - const augmentingDeclarations = filter(symbol.declarations, d => getSourceFileOfNode(d) !== containingFile); + function reportNonlocalAugmentation(containingFile: ts.SourceFile, parentSymbol: ts.Symbol, symbol: ts.Symbol) { + const primaryDeclaration = parentSymbol.declarations?.find(d => ts.getSourceFileOfNode(d) === containingFile)!; + const augmentingDeclarations = ts.filter(symbol.declarations, d => ts.getSourceFileOfNode(d) !== containingFile); if (augmentingDeclarations) { for (const augmentations of augmentingDeclarations) { - context.addDiagnostic(addRelatedInfo( - createDiagnosticForNode(augmentations, Diagnostics.Declaration_augments_declaration_in_another_file_This_cannot_be_serialized), - createDiagnosticForNode(primaryDeclaration, Diagnostics.This_is_the_declaration_being_augmented_Consider_moving_the_augmenting_declaration_into_the_same_file) - )); + context.addDiagnostic(ts.addRelatedInfo(ts.createDiagnosticForNode(augmentations, ts.Diagnostics.Declaration_augments_declaration_in_another_file_This_cannot_be_serialized), ts.createDiagnosticForNode(primaryDeclaration, ts.Diagnostics.This_is_the_declaration_being_augmented_Consider_moving_the_augmenting_declaration_into_the_same_file))); } } } function reportNonSerializableProperty(propertyName: string) { if (errorNameNode || errorFallbackNode) { - context.addDiagnostic(createDiagnosticForNode((errorNameNode || errorFallbackNode)!, Diagnostics.The_type_of_this_node_cannot_be_serialized_because_its_property_0_cannot_be_serialized, propertyName)); + context.addDiagnostic(ts.createDiagnosticForNode((errorNameNode || errorFallbackNode)!, ts.Diagnostics.The_type_of_this_node_cannot_be_serialized_because_its_property_0_cannot_be_serialized, propertyName)); } } - function transformDeclarationsForJS(sourceFile: SourceFile, bundled?: boolean) { + function transformDeclarationsForJS(sourceFile: ts.SourceFile, bundled?: boolean) { const oldDiag = getSymbolAccessibilityDiagnostic; - getSymbolAccessibilityDiagnostic = (s) => (s.errorNode && canProduceDiagnostics(s.errorNode) ? createGetSymbolAccessibilityDiagnosticForNode(s.errorNode)(s) : ({ + getSymbolAccessibilityDiagnostic = (s) => (s.errorNode && ts.canProduceDiagnostics(s.errorNode) ? ts.createGetSymbolAccessibilityDiagnosticForNode(s.errorNode)(s) : ({ diagnosticMessage: s.errorModuleName - ? Diagnostics.Declaration_emit_for_this_file_requires_using_private_name_0_from_module_1_An_explicit_type_annotation_may_unblock_declaration_emit - : Diagnostics.Declaration_emit_for_this_file_requires_using_private_name_0_An_explicit_type_annotation_may_unblock_declaration_emit, + ? ts.Diagnostics.Declaration_emit_for_this_file_requires_using_private_name_0_from_module_1_An_explicit_type_annotation_may_unblock_declaration_emit + : ts.Diagnostics.Declaration_emit_for_this_file_requires_using_private_name_0_An_explicit_type_annotation_may_unblock_declaration_emit, errorNode: s.errorNode || sourceFile })); const result = resolver.getDeclarationStatementsForSourceFile(sourceFile, declarationEmitNodeBuilderFlags, symbolTracker, bundled); @@ -248,55 +232,49 @@ namespace ts { return result; } - function transformRoot(node: Bundle): Bundle; - function transformRoot(node: SourceFile): SourceFile; - function transformRoot(node: SourceFile | Bundle): SourceFile | Bundle; - function transformRoot(node: SourceFile | Bundle) { - if (node.kind === SyntaxKind.SourceFile && node.isDeclarationFile) { + function transformRoot(node: ts.Bundle): ts.Bundle; + function transformRoot(node: ts.SourceFile): ts.SourceFile; + function transformRoot(node: ts.SourceFile | ts.Bundle): ts.SourceFile | ts.Bundle; + function transformRoot(node: ts.SourceFile | ts.Bundle) { + if (node.kind === ts.SyntaxKind.SourceFile && node.isDeclarationFile) { return node; } - if (node.kind === SyntaxKind.Bundle) { + if (node.kind === ts.SyntaxKind.Bundle) { isBundledEmit = true; - refs = new Map(); - libs = new Map(); + refs = new ts.Map(); + libs = new ts.Map(); let hasNoDefaultLib = false; - const bundle = factory.createBundle(map(node.sourceFiles, - sourceFile => { - if (sourceFile.isDeclarationFile) return undefined!; // Omit declaration files from bundle results, too // TODO: GH#18217 + const bundle = factory.createBundle(ts.map(node.sourceFiles, sourceFile => { + if (sourceFile.isDeclarationFile) + return undefined!; // Omit declaration files from bundle results, too // TODO: GH#18217 hasNoDefaultLib = hasNoDefaultLib || sourceFile.hasNoDefaultLib; currentSourceFile = sourceFile; enclosingDeclaration = sourceFile; lateMarkedStatements = undefined; suppressNewDiagnosticContexts = false; - lateStatementReplacementMap = new Map(); + lateStatementReplacementMap = new ts.Map(); getSymbolAccessibilityDiagnostic = throwDiagnostic; needsScopeFixMarker = false; resultHasScopeMarker = false; collectReferences(sourceFile, refs); collectLibs(sourceFile, libs); - if (isExternalOrCommonJsModule(sourceFile) || isJsonSourceFile(sourceFile)) { + if (ts.isExternalOrCommonJsModule(sourceFile) || ts.isJsonSourceFile(sourceFile)) { resultHasExternalModuleIndicator = false; // unused in external module bundle emit (all external modules are within module blocks, therefore are known to be modules) needsDeclare = false; - const statements = isSourceFileJS(sourceFile) ? factory.createNodeArray(transformDeclarationsForJS(sourceFile, /*bundled*/ true)) : visitNodes(sourceFile.statements, visitDeclarationStatements); - const newFile = factory.updateSourceFile(sourceFile, [factory.createModuleDeclaration( - [], - [factory.createModifier(SyntaxKind.DeclareKeyword)], - factory.createStringLiteral(getResolvedExternalModuleName(context.getEmitHost(), sourceFile)), - factory.createModuleBlock(setTextRange(factory.createNodeArray(transformAndReplaceLatePaintedStatements(statements)), sourceFile.statements)) - )], /*isDeclarationFile*/ true, /*referencedFiles*/ [], /*typeReferences*/ [], /*hasNoDefaultLib*/ false, /*libReferences*/ []); + const statements = ts.isSourceFileJS(sourceFile) ? factory.createNodeArray(transformDeclarationsForJS(sourceFile, /*bundled*/ true)) : ts.visitNodes(sourceFile.statements, visitDeclarationStatements); + const newFile = factory.updateSourceFile(sourceFile, [factory.createModuleDeclaration([], [factory.createModifier(ts.SyntaxKind.DeclareKeyword)], factory.createStringLiteral(ts.getResolvedExternalModuleName(context.getEmitHost(), sourceFile)), factory.createModuleBlock(ts.setTextRange(factory.createNodeArray(transformAndReplaceLatePaintedStatements(statements)), sourceFile.statements)))], /*isDeclarationFile*/ true, /*referencedFiles*/ [], /*typeReferences*/ [], /*hasNoDefaultLib*/ false, /*libReferences*/ []); return newFile; } needsDeclare = true; - const updated = isSourceFileJS(sourceFile) ? factory.createNodeArray(transformDeclarationsForJS(sourceFile)) : visitNodes(sourceFile.statements, visitDeclarationStatements); + const updated = ts.isSourceFileJS(sourceFile) ? factory.createNodeArray(transformDeclarationsForJS(sourceFile)) : ts.visitNodes(sourceFile.statements, visitDeclarationStatements); return factory.updateSourceFile(sourceFile, transformAndReplaceLatePaintedStatements(updated), /*isDeclarationFile*/ true, /*referencedFiles*/ [], /*typeReferences*/ [], /*hasNoDefaultLib*/ false, /*libReferences*/ []); - } - ), mapDefined(node.prepends, prepend => { - if (prepend.kind === SyntaxKind.InputFiles) { - const sourceFile = createUnparsedSourceFile(prepend, "dts", stripInternal); + }), ts.mapDefined(node.prepends, prepend => { + if (prepend.kind === ts.SyntaxKind.InputFiles) { + const sourceFile = ts.createUnparsedSourceFile(prepend, "dts", stripInternal); hasNoDefaultLib = hasNoDefaultLib || !!sourceFile.hasNoDefaultLib; collectReferences(sourceFile, refs); - recordTypeReferenceDirectivesIfNecessary(map(sourceFile.typeReferenceDirectives, ref => [ref.fileName, ref.resolutionMode])); + recordTypeReferenceDirectivesIfNecessary(ts.map(sourceFile.typeReferenceDirectives, ref => [ref.fileName, ref.resolutionMode])); collectLibs(sourceFile, libs); return sourceFile; } @@ -306,8 +284,8 @@ namespace ts { bundle.syntheticTypeReferences = getFileReferencesForUsedTypeReferences(); bundle.syntheticLibReferences = getLibReferences(); bundle.hasNoDefaultLib = hasNoDefaultLib; - const outputFilePath = getDirectoryPath(normalizeSlashes(getOutputPathsFor(node, host, /*forceDtsPaths*/ true).declarationFilePath!)); - const referenceVisitor = mapReferencesIntoArray(bundle.syntheticFileReferences as FileReference[], outputFilePath); + const outputFilePath = ts.getDirectoryPath(ts.normalizeSlashes(ts.getOutputPathsFor(node, host, /*forceDtsPaths*/ true).declarationFilePath!)); + const referenceVisitor = mapReferencesIntoArray(bundle.syntheticFileReferences as ts.FileReference[], outputFilePath); refs.forEach(referenceVisitor); return bundle; } @@ -323,26 +301,26 @@ namespace ts { resultHasExternalModuleIndicator = false; suppressNewDiagnosticContexts = false; lateMarkedStatements = undefined; - lateStatementReplacementMap = new Map(); + lateStatementReplacementMap = new ts.Map(); necessaryTypeReferences = undefined; - refs = collectReferences(currentSourceFile, new Map()); - libs = collectLibs(currentSourceFile, new Map()); - const references: FileReference[] = []; - const outputFilePath = getDirectoryPath(normalizeSlashes(getOutputPathsFor(node, host, /*forceDtsPaths*/ true).declarationFilePath!)); + refs = collectReferences(currentSourceFile, new ts.Map()); + libs = collectLibs(currentSourceFile, new ts.Map()); + const references: ts.FileReference[] = []; + const outputFilePath = ts.getDirectoryPath(ts.normalizeSlashes(ts.getOutputPathsFor(node, host, /*forceDtsPaths*/ true).declarationFilePath!)); const referenceVisitor = mapReferencesIntoArray(references, outputFilePath); - let combinedStatements: NodeArray; - if (isSourceFileJS(currentSourceFile)) { + let combinedStatements: ts.NodeArray; + if (ts.isSourceFileJS(currentSourceFile)) { combinedStatements = factory.createNodeArray(transformDeclarationsForJS(node)); refs.forEach(referenceVisitor); - emittedImports = filter(combinedStatements, isAnyImportSyntax); + emittedImports = ts.filter(combinedStatements, ts.isAnyImportSyntax); } else { - const statements = visitNodes(node.statements, visitDeclarationStatements); - combinedStatements = setTextRange(factory.createNodeArray(transformAndReplaceLatePaintedStatements(statements)), node.statements); + const statements = ts.visitNodes(node.statements, visitDeclarationStatements); + combinedStatements = ts.setTextRange(factory.createNodeArray(transformAndReplaceLatePaintedStatements(statements)), node.statements); refs.forEach(referenceVisitor); - emittedImports = filter(combinedStatements, isAnyImportSyntax); - if (isExternalModule(node) && (!resultHasExternalModuleIndicator || (needsScopeFixMarker && !resultHasScopeMarker))) { - combinedStatements = setTextRange(factory.createNodeArray([...combinedStatements, createEmptyExports(factory)]), combinedStatements); + emittedImports = ts.filter(combinedStatements, ts.isAnyImportSyntax); + if (ts.isExternalModule(node) && (!resultHasExternalModuleIndicator || (needsScopeFixMarker && !resultHasScopeMarker))) { + combinedStatements = ts.setTextRange(factory.createNodeArray([...combinedStatements, ts.createEmptyExports(factory)]), combinedStatements); } } const updated = factory.updateSourceFile(node, combinedStatements, /*isDeclarationFile*/ true, references, getFileReferencesForUsedTypeReferences(), node.hasNoDefaultLib, getLibReferences()); @@ -350,24 +328,27 @@ namespace ts { return updated; function getLibReferences() { - return map(arrayFrom(libs.keys()), lib => ({ fileName: lib, pos: -1, end: -1 })); + return ts.map(ts.arrayFrom(libs.keys()), lib => ({ fileName: lib, pos: -1, end: -1 })); } function getFileReferencesForUsedTypeReferences() { - return necessaryTypeReferences ? mapDefined(arrayFrom(necessaryTypeReferences.keys()), getFileReferenceForSpecifierModeTuple) : []; + return necessaryTypeReferences ? ts.mapDefined(ts.arrayFrom(necessaryTypeReferences.keys()), getFileReferenceForSpecifierModeTuple) : []; } - function getFileReferenceForSpecifierModeTuple([typeName, mode]: [specifier: string, mode: SourceFile["impliedNodeFormat"] | undefined]): FileReference | undefined { + function getFileReferenceForSpecifierModeTuple([typeName, mode]: [ + specifier: string, + mode: ts.SourceFile["impliedNodeFormat"] | undefined + ]): ts.FileReference | undefined { // Elide type references for which we have imports if (emittedImports) { for (const importStatement of emittedImports) { - if (isImportEqualsDeclaration(importStatement) && isExternalModuleReference(importStatement.moduleReference)) { + if (ts.isImportEqualsDeclaration(importStatement) && ts.isExternalModuleReference(importStatement.moduleReference)) { const expr = importStatement.moduleReference.expression; - if (isStringLiteralLike(expr) && expr.text === typeName) { + if (ts.isStringLiteralLike(expr) && expr.text === typeName) { return undefined; } } - else if (isImportDeclaration(importStatement) && isStringLiteral(importStatement.moduleSpecifier) && importStatement.moduleSpecifier.text === typeName) { + else if (ts.isImportDeclaration(importStatement) && ts.isStringLiteral(importStatement.moduleSpecifier) && importStatement.moduleSpecifier.text === typeName) { return undefined; } } @@ -375,27 +356,22 @@ namespace ts { return { fileName: typeName, pos: -1, end: -1, ...(mode ? { resolutionMode: mode } : undefined) }; } - function mapReferencesIntoArray(references: FileReference[], outputFilePath: string): (file: SourceFile) => void { + function mapReferencesIntoArray(references: ts.FileReference[], outputFilePath: string): (file: ts.SourceFile) => void { return file => { let declFileName: string; if (file.isDeclarationFile) { // Neither decl files or js should have their refs changed declFileName = file.fileName; } else { - if (isBundledEmit && contains((node as Bundle).sourceFiles, file)) return; // Omit references to files which are being merged - const paths = getOutputPathsFor(file, host, /*forceDtsPaths*/ true); + if (isBundledEmit && ts.contains((node as ts.Bundle).sourceFiles, file)) + return; // Omit references to files which are being merged + const paths = ts.getOutputPathsFor(file, host, /*forceDtsPaths*/ true); declFileName = paths.declarationFilePath || paths.jsFilePath || file.fileName; } if (declFileName) { - const specifier = moduleSpecifiers.getModuleSpecifier( - options, - currentSourceFile, - toPath(outputFilePath, host.getCurrentDirectory(), host.getCanonicalFileName), - toPath(declFileName, host.getCurrentDirectory(), host.getCanonicalFileName), - host, - ); - if (!pathIsRelative(specifier)) { + const specifier = ts.moduleSpecifiers.getModuleSpecifier(options, currentSourceFile, ts.toPath(outputFilePath, host.getCurrentDirectory(), host.getCanonicalFileName), ts.toPath(declFileName, host.getCurrentDirectory(), host.getCanonicalFileName), host); + if (!ts.pathIsRelative(specifier)) { // If some compiler option/symlink/whatever allows access to the file containing the ambient module declaration // via a non-relative name, emit a type reference directive to that non-relative name, rather than // a relative path to the declaration file @@ -403,20 +379,15 @@ namespace ts { return; } - let fileName = getRelativePathToDirectoryOrUrl( - outputFilePath, - declFileName, - host.getCurrentDirectory(), - host.getCanonicalFileName, - /*isAbsolutePathAnUrl*/ false - ); - if (startsWith(fileName, "./") && hasExtension(fileName)) { + let fileName = ts.getRelativePathToDirectoryOrUrl(outputFilePath, declFileName, host.getCurrentDirectory(), host.getCanonicalFileName, + /*isAbsolutePathAnUrl*/ false); + if (ts.startsWith(fileName, "./") && ts.hasExtension(fileName)) { fileName = fileName.substring(2); } // omit references to files from node_modules (npm may disambiguate module // references when installing this package, making the path is unreliable). - if (startsWith(fileName, "node_modules/") || pathContainsNodeModules(fileName)) { + if (ts.startsWith(fileName, "node_modules/") || ts.pathContainsNodeModules(fileName)) { return; } @@ -426,98 +397,79 @@ namespace ts { } } - function collectReferences(sourceFile: SourceFile | UnparsedSource, ret: ESMap) { - if (noResolve || (!isUnparsedSource(sourceFile) && isSourceFileJS(sourceFile))) return ret; - forEach(sourceFile.referencedFiles, f => { + function collectReferences(sourceFile: ts.SourceFile | ts.UnparsedSource, ret: ts.ESMap) { + if (noResolve || (!ts.isUnparsedSource(sourceFile) && ts.isSourceFileJS(sourceFile))) + return ret; + ts.forEach(sourceFile.referencedFiles, f => { const elem = host.getSourceFileFromReference(sourceFile, f); if (elem) { - ret.set(getOriginalNodeId(elem), elem); + ret.set(ts.getOriginalNodeId(elem), elem); } }); return ret; } - function collectLibs(sourceFile: SourceFile | UnparsedSource, ret: ESMap) { - forEach(sourceFile.libReferenceDirectives, ref => { + function collectLibs(sourceFile: ts.SourceFile | ts.UnparsedSource, ret: ts.ESMap) { + ts.forEach(sourceFile.libReferenceDirectives, ref => { const lib = host.getLibFileFromReference(ref); if (lib) { - ret.set(toFileNameLowerCase(ref.fileName), true); + ret.set(ts.toFileNameLowerCase(ref.fileName), true); } }); return ret; } - function filterBindingPatternInitializers(name: BindingName) { - if (name.kind === SyntaxKind.Identifier) { + function filterBindingPatternInitializers(name: ts.BindingName) { + if (name.kind === ts.SyntaxKind.Identifier) { return name; } else { - if (name.kind === SyntaxKind.ArrayBindingPattern) { - return factory.updateArrayBindingPattern(name, visitNodes(name.elements, visitBindingElement)); + if (name.kind === ts.SyntaxKind.ArrayBindingPattern) { + return factory.updateArrayBindingPattern(name, ts.visitNodes(name.elements, visitBindingElement)); } else { - return factory.updateObjectBindingPattern(name, visitNodes(name.elements, visitBindingElement)); + return factory.updateObjectBindingPattern(name, ts.visitNodes(name.elements, visitBindingElement)); } } - function visitBindingElement(elem: T): T; - function visitBindingElement(elem: ArrayBindingElement): ArrayBindingElement { - if (elem.kind === SyntaxKind.OmittedExpression) { + function visitBindingElement(elem: T): T; + function visitBindingElement(elem: ts.ArrayBindingElement): ts.ArrayBindingElement { + if (elem.kind === ts.SyntaxKind.OmittedExpression) { return elem; } return factory.updateBindingElement(elem, elem.dotDotDotToken, elem.propertyName, filterBindingPatternInitializers(elem.name), shouldPrintWithInitializer(elem) ? elem.initializer : undefined); } } - function ensureParameter(p: ParameterDeclaration, modifierMask?: ModifierFlags, type?: TypeNode): ParameterDeclaration { + function ensureParameter(p: ts.ParameterDeclaration, modifierMask?: ts.ModifierFlags, type?: ts.TypeNode): ts.ParameterDeclaration { let oldDiag: typeof getSymbolAccessibilityDiagnostic | undefined; if (!suppressNewDiagnosticContexts) { oldDiag = getSymbolAccessibilityDiagnostic; - getSymbolAccessibilityDiagnostic = createGetSymbolAccessibilityDiagnosticForNode(p); - } - const newParam = factory.updateParameterDeclaration( - p, - /*decorators*/ undefined, - maskModifiers(p, modifierMask), - p.dotDotDotToken, - filterBindingPatternInitializers(p.name), - resolver.isOptionalParameter(p) ? (p.questionToken || factory.createToken(SyntaxKind.QuestionToken)) : undefined, - ensureType(p, type || p.type, /*ignorePrivate*/ true), // Ignore private param props, since this type is going straight back into a param - ensureNoInitializer(p) - ); + getSymbolAccessibilityDiagnostic = ts.createGetSymbolAccessibilityDiagnosticForNode(p); + } + const newParam = factory.updateParameterDeclaration(p, + /*decorators*/ undefined, maskModifiers(p, modifierMask), p.dotDotDotToken, filterBindingPatternInitializers(p.name), resolver.isOptionalParameter(p) ? (p.questionToken || factory.createToken(ts.SyntaxKind.QuestionToken)) : undefined, ensureType(p, type || p.type, /*ignorePrivate*/ true), // Ignore private param props, since this type is going straight back into a param + ensureNoInitializer(p)); if (!suppressNewDiagnosticContexts) { getSymbolAccessibilityDiagnostic = oldDiag!; } return newParam; } - function shouldPrintWithInitializer(node: Node) { - return canHaveLiteralInitializer(node) && resolver.isLiteralConstDeclaration(getParseTreeNode(node) as CanHaveLiteralInitializer); // TODO: Make safe + function shouldPrintWithInitializer(node: ts.Node) { + return canHaveLiteralInitializer(node) && resolver.isLiteralConstDeclaration(ts.getParseTreeNode(node) as CanHaveLiteralInitializer); // TODO: Make safe } function ensureNoInitializer(node: CanHaveLiteralInitializer) { if (shouldPrintWithInitializer(node)) { - return resolver.createLiteralConstValue(getParseTreeNode(node) as CanHaveLiteralInitializer, symbolTracker); // TODO: Make safe + return resolver.createLiteralConstValue(ts.getParseTreeNode(node) as CanHaveLiteralInitializer, symbolTracker); // TODO: Make safe } return undefined; } - type HasInferredType = - | FunctionDeclaration - | MethodDeclaration - | GetAccessorDeclaration - | SetAccessorDeclaration - | BindingElement - | ConstructSignatureDeclaration - | VariableDeclaration - | MethodSignature - | CallSignatureDeclaration - | ParameterDeclaration - | PropertyDeclaration - | PropertySignature; - - function ensureType(node: HasInferredType, type: TypeNode | undefined, ignorePrivate?: boolean): TypeNode | undefined { - if (!ignorePrivate && hasEffectiveModifier(node, ModifierFlags.Private)) { + type HasInferredType = ts.FunctionDeclaration | ts.MethodDeclaration | ts.GetAccessorDeclaration | ts.SetAccessorDeclaration | ts.BindingElement | ts.ConstructSignatureDeclaration | ts.VariableDeclaration | ts.MethodSignature | ts.CallSignatureDeclaration | ts.ParameterDeclaration | ts.PropertyDeclaration | ts.PropertySignature; + function ensureType(node: HasInferredType, type: ts.TypeNode | undefined, ignorePrivate?: boolean): ts.TypeNode | undefined { + if (!ignorePrivate && ts.hasEffectiveModifier(node, ts.ModifierFlags.Private)) { // Private nodes emit no types (except private parameter properties, whose parameter types are actually visible) return; } @@ -525,116 +477,117 @@ namespace ts { // Literal const declarations will have an initializer ensured rather than a type return; } - const shouldUseResolverType = node.kind === SyntaxKind.Parameter && + const shouldUseResolverType = node.kind === ts.SyntaxKind.Parameter && (resolver.isRequiredInitializedParameter(node) || resolver.isOptionalUninitializedParameterProperty(node)); if (type && !shouldUseResolverType) { - return visitNode(type, visitDeclarationSubtree); + return ts.visitNode(type, visitDeclarationSubtree); } - if (!getParseTreeNode(node)) { - return type ? visitNode(type, visitDeclarationSubtree) : factory.createKeywordTypeNode(SyntaxKind.AnyKeyword); + if (!ts.getParseTreeNode(node)) { + return type ? ts.visitNode(type, visitDeclarationSubtree) : factory.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword); } - if (node.kind === SyntaxKind.SetAccessor) { + if (node.kind === ts.SyntaxKind.SetAccessor) { // Set accessors with no associated type node (from it's param or get accessor return) are `any` since they are never contextually typed right now // (The inferred type here will be void, but the old declaration emitter printed `any`, so this replicates that) - return factory.createKeywordTypeNode(SyntaxKind.AnyKeyword); + return factory.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword); } errorNameNode = node.name; let oldDiag: typeof getSymbolAccessibilityDiagnostic; if (!suppressNewDiagnosticContexts) { oldDiag = getSymbolAccessibilityDiagnostic; - getSymbolAccessibilityDiagnostic = createGetSymbolAccessibilityDiagnosticForNode(node); + getSymbolAccessibilityDiagnostic = ts.createGetSymbolAccessibilityDiagnosticForNode(node); } - if (node.kind === SyntaxKind.VariableDeclaration || node.kind === SyntaxKind.BindingElement) { + if (node.kind === ts.SyntaxKind.VariableDeclaration || node.kind === ts.SyntaxKind.BindingElement) { return cleanup(resolver.createTypeOfDeclaration(node, enclosingDeclaration, declarationEmitNodeBuilderFlags, symbolTracker)); } - if (node.kind === SyntaxKind.Parameter - || node.kind === SyntaxKind.PropertyDeclaration - || node.kind === SyntaxKind.PropertySignature) { - if (!node.initializer) return cleanup(resolver.createTypeOfDeclaration(node, enclosingDeclaration, declarationEmitNodeBuilderFlags, symbolTracker, shouldUseResolverType)); + if (node.kind === ts.SyntaxKind.Parameter + || node.kind === ts.SyntaxKind.PropertyDeclaration + || node.kind === ts.SyntaxKind.PropertySignature) { + if (!node.initializer) + return cleanup(resolver.createTypeOfDeclaration(node, enclosingDeclaration, declarationEmitNodeBuilderFlags, symbolTracker, shouldUseResolverType)); return cleanup(resolver.createTypeOfDeclaration(node, enclosingDeclaration, declarationEmitNodeBuilderFlags, symbolTracker, shouldUseResolverType) || resolver.createTypeOfExpression(node.initializer, enclosingDeclaration, declarationEmitNodeBuilderFlags, symbolTracker)); } return cleanup(resolver.createReturnTypeOfSignatureDeclaration(node, enclosingDeclaration, declarationEmitNodeBuilderFlags, symbolTracker)); - function cleanup(returnValue: TypeNode | undefined) { + function cleanup(returnValue: ts.TypeNode | undefined) { errorNameNode = undefined; if (!suppressNewDiagnosticContexts) { getSymbolAccessibilityDiagnostic = oldDiag; } - return returnValue || factory.createKeywordTypeNode(SyntaxKind.AnyKeyword); + return returnValue || factory.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword); } } - function isDeclarationAndNotVisible(node: NamedDeclaration) { - node = getParseTreeNode(node) as NamedDeclaration; + function isDeclarationAndNotVisible(node: ts.NamedDeclaration) { + node = ts.getParseTreeNode(node) as ts.NamedDeclaration; switch (node.kind) { - case SyntaxKind.FunctionDeclaration: - case SyntaxKind.ModuleDeclaration: - case SyntaxKind.InterfaceDeclaration: - case SyntaxKind.ClassDeclaration: - case SyntaxKind.TypeAliasDeclaration: - case SyntaxKind.EnumDeclaration: + case ts.SyntaxKind.FunctionDeclaration: + case ts.SyntaxKind.ModuleDeclaration: + case ts.SyntaxKind.InterfaceDeclaration: + case ts.SyntaxKind.ClassDeclaration: + case ts.SyntaxKind.TypeAliasDeclaration: + case ts.SyntaxKind.EnumDeclaration: return !resolver.isDeclarationVisible(node); // The following should be doing their own visibility checks based on filtering their members - case SyntaxKind.VariableDeclaration: - return !getBindingNameVisible(node as VariableDeclaration); - case SyntaxKind.ImportEqualsDeclaration: - case SyntaxKind.ImportDeclaration: - case SyntaxKind.ExportDeclaration: - case SyntaxKind.ExportAssignment: + case ts.SyntaxKind.VariableDeclaration: + return !getBindingNameVisible(node as ts.VariableDeclaration); + case ts.SyntaxKind.ImportEqualsDeclaration: + case ts.SyntaxKind.ImportDeclaration: + case ts.SyntaxKind.ExportDeclaration: + case ts.SyntaxKind.ExportAssignment: return false; - case SyntaxKind.ClassStaticBlockDeclaration: + case ts.SyntaxKind.ClassStaticBlockDeclaration: return true; } return false; } // If the ExpandoFunctionDeclaration have multiple overloads, then we only need to emit properties for the last one. - function shouldEmitFunctionProperties(input: FunctionDeclaration) { + function shouldEmitFunctionProperties(input: ts.FunctionDeclaration) { if (input.body) { return true; } - const overloadSignatures = input.symbol.declarations?.filter(decl => isFunctionDeclaration(decl) && !decl.body); + const overloadSignatures = input.symbol.declarations?.filter(decl => ts.isFunctionDeclaration(decl) && !decl.body); return !overloadSignatures || overloadSignatures.indexOf(input) === overloadSignatures.length - 1; } - function getBindingNameVisible(elem: BindingElement | VariableDeclaration | OmittedExpression): boolean { - if (isOmittedExpression(elem)) { + function getBindingNameVisible(elem: ts.BindingElement | ts.VariableDeclaration | ts.OmittedExpression): boolean { + if (ts.isOmittedExpression(elem)) { return false; } - if (isBindingPattern(elem.name)) { + if (ts.isBindingPattern(elem.name)) { // If any child binding pattern element has been marked visible (usually by collect linked aliases), then this is visible - return some(elem.name.elements, getBindingNameVisible); + return ts.some(elem.name.elements, getBindingNameVisible); } else { return resolver.isDeclarationVisible(elem); } } - function updateParamsList(node: Node, params: NodeArray, modifierMask?: ModifierFlags) { - if (hasEffectiveModifier(node, ModifierFlags.Private)) { + function updateParamsList(node: ts.Node, params: ts.NodeArray, modifierMask?: ts.ModifierFlags) { + if (ts.hasEffectiveModifier(node, ts.ModifierFlags.Private)) { return undefined!; // TODO: GH#18217 } - const newParams = map(params, p => ensureParameter(p, modifierMask)); + const newParams = ts.map(params, p => ensureParameter(p, modifierMask)); if (!newParams) { return undefined!; // TODO: GH#18217 } return factory.createNodeArray(newParams, params.hasTrailingComma); } - function updateAccessorParamsList(input: AccessorDeclaration, isPrivate: boolean) { - let newParams: ParameterDeclaration[] | undefined; + function updateAccessorParamsList(input: ts.AccessorDeclaration, isPrivate: boolean) { + let newParams: ts.ParameterDeclaration[] | undefined; if (!isPrivate) { - const thisParameter = getThisParameter(input); + const thisParameter = ts.getThisParameter(input); if (thisParameter) { newParams = [ensureParameter(thisParameter)]; } } - if (isSetAccessorDeclaration(input)) { - let newValueParameter: ParameterDeclaration | undefined; + if (ts.isSetAccessorDeclaration(input)) { + let newValueParameter: ts.ParameterDeclaration | undefined; if (!isPrivate) { - const valueParameter = getSetAccessorValueParameter(input); + const valueParameter = ts.getSetAccessorValueParameter(input); if (valueParameter) { const accessorType = getTypeAnnotationFromAllAccessorDeclarations(input, resolver.getAllAccessorDeclarations(input)); newValueParameter = ensureParameter(valueParameter, /*modifierMask*/ undefined, accessorType); @@ -644,49 +597,45 @@ namespace ts { newValueParameter = factory.createParameterDeclaration( /*decorators*/ undefined, /*modifiers*/ undefined, - /*dotDotDotToken*/ undefined, - "value" - ); + /*dotDotDotToken*/ undefined, "value"); } - newParams = append(newParams, newValueParameter); + newParams = ts.append(newParams, newValueParameter); } - return factory.createNodeArray(newParams || emptyArray); + return factory.createNodeArray(newParams || ts.emptyArray); } - - function ensureTypeParams(node: Node, params: NodeArray | undefined) { - return hasEffectiveModifier(node, ModifierFlags.Private) ? undefined : visitNodes(params, visitDeclarationSubtree); + function ensureTypeParams(node: ts.Node, params: ts.NodeArray | undefined) { + return ts.hasEffectiveModifier(node, ts.ModifierFlags.Private) ? undefined : ts.visitNodes(params, visitDeclarationSubtree); } - - function isEnclosingDeclaration(node: Node) { - return isSourceFile(node) - || isTypeAliasDeclaration(node) - || isModuleDeclaration(node) - || isClassDeclaration(node) - || isInterfaceDeclaration(node) - || isFunctionLike(node) - || isIndexSignatureDeclaration(node) - || isMappedTypeNode(node); + function isEnclosingDeclaration(node: ts.Node) { + return ts.isSourceFile(node) + || ts.isTypeAliasDeclaration(node) + || ts.isModuleDeclaration(node) + || ts.isClassDeclaration(node) + || ts.isInterfaceDeclaration(node) + || ts.isFunctionLike(node) + || ts.isIndexSignatureDeclaration(node) + || ts.isMappedTypeNode(node); } - - function checkEntityNameVisibility(entityName: EntityNameOrEntityNameExpression, enclosingDeclaration: Node) { + function checkEntityNameVisibility(entityName: ts.EntityNameOrEntityNameExpression, enclosingDeclaration: ts.Node) { const visibilityResult = resolver.isEntityNameVisible(entityName, enclosingDeclaration); handleSymbolAccessibilityError(visibilityResult); recordTypeReferenceDirectivesIfNecessary(resolver.getTypeReferenceDirectivesForEntityName(entityName)); } - function preserveJsDoc(updated: T, original: Node): T { - if (hasJSDocNodes(updated) && hasJSDocNodes(original)) { + function preserveJsDoc(updated: T, original: ts.Node): T { + if (ts.hasJSDocNodes(updated) && ts.hasJSDocNodes(original)) { updated.jsDoc = original.jsDoc; } - return setCommentRange(updated, getCommentRange(original)); + return ts.setCommentRange(updated, ts.getCommentRange(original)); } - function rewriteModuleSpecifier(parent: ImportEqualsDeclaration | ImportDeclaration | ExportDeclaration | ModuleDeclaration | ImportTypeNode, input: T | undefined): T | StringLiteral { - if (!input) return undefined!; // TODO: GH#18217 - resultHasExternalModuleIndicator = resultHasExternalModuleIndicator || (parent.kind !== SyntaxKind.ModuleDeclaration && parent.kind !== SyntaxKind.ImportType); - if (isStringLiteralLike(input)) { + function rewriteModuleSpecifier(parent: ts.ImportEqualsDeclaration | ts.ImportDeclaration | ts.ExportDeclaration | ts.ModuleDeclaration | ts.ImportTypeNode, input: T | undefined): T | ts.StringLiteral { + if (!input) + return undefined!; // TODO: GH#18217 + resultHasExternalModuleIndicator = resultHasExternalModuleIndicator || (parent.kind !== ts.SyntaxKind.ModuleDeclaration && parent.kind !== ts.SyntaxKind.ImportType); + if (ts.isStringLiteralLike(input)) { if (isBundledEmit) { - const newName = getExternalModuleNameFromDeclaration(context.getEmitHost(), resolver, parent); + const newName = ts.getExternalModuleNameFromDeclaration(context.getEmitHost(), resolver, parent); if (newName) { return factory.createStringLiteral(newName); } @@ -701,105 +650,69 @@ namespace ts { return input; } - function transformImportEqualsDeclaration(decl: ImportEqualsDeclaration) { - if (!resolver.isDeclarationVisible(decl)) return; - if (decl.moduleReference.kind === SyntaxKind.ExternalModuleReference) { + function transformImportEqualsDeclaration(decl: ts.ImportEqualsDeclaration) { + if (!resolver.isDeclarationVisible(decl)) + return; + if (decl.moduleReference.kind === ts.SyntaxKind.ExternalModuleReference) { // Rewrite external module names if necessary - const specifier = getExternalModuleImportEqualsDeclarationExpression(decl); - return factory.updateImportEqualsDeclaration( - decl, - /*decorators*/ undefined, - decl.modifiers, - decl.isTypeOnly, - decl.name, - factory.updateExternalModuleReference(decl.moduleReference, rewriteModuleSpecifier(decl, specifier)) - ); + const specifier = ts.getExternalModuleImportEqualsDeclarationExpression(decl); + return factory.updateImportEqualsDeclaration(decl, + /*decorators*/ undefined, decl.modifiers, decl.isTypeOnly, decl.name, factory.updateExternalModuleReference(decl.moduleReference, rewriteModuleSpecifier(decl, specifier))); } else { const oldDiag = getSymbolAccessibilityDiagnostic; - getSymbolAccessibilityDiagnostic = createGetSymbolAccessibilityDiagnosticForNode(decl); + getSymbolAccessibilityDiagnostic = ts.createGetSymbolAccessibilityDiagnosticForNode(decl); checkEntityNameVisibility(decl.moduleReference, enclosingDeclaration); getSymbolAccessibilityDiagnostic = oldDiag; return decl; } } - function transformImportDeclaration(decl: ImportDeclaration) { + function transformImportDeclaration(decl: ts.ImportDeclaration) { if (!decl.importClause) { // import "mod" - possibly needed for side effects? (global interface patches, module augmentations, etc) - return factory.updateImportDeclaration( - decl, - /*decorators*/ undefined, - decl.modifiers, - decl.importClause, - rewriteModuleSpecifier(decl, decl.moduleSpecifier), - getResolutionModeOverrideForClauseInNightly(decl.assertClause) - ); + return factory.updateImportDeclaration(decl, + /*decorators*/ undefined, decl.modifiers, decl.importClause, rewriteModuleSpecifier(decl, decl.moduleSpecifier), getResolutionModeOverrideForClauseInNightly(decl.assertClause)); } // The `importClause` visibility corresponds to the default's visibility. const visibleDefaultBinding = decl.importClause && decl.importClause.name && resolver.isDeclarationVisible(decl.importClause) ? decl.importClause.name : undefined; if (!decl.importClause.namedBindings) { // No named bindings (either namespace or list), meaning the import is just default or should be elided - return visibleDefaultBinding && factory.updateImportDeclaration(decl, /*decorators*/ undefined, decl.modifiers, factory.updateImportClause( - decl.importClause, - decl.importClause.isTypeOnly, - visibleDefaultBinding, - /*namedBindings*/ undefined, - ), rewriteModuleSpecifier(decl, decl.moduleSpecifier), getResolutionModeOverrideForClauseInNightly(decl.assertClause)); - } - if (decl.importClause.namedBindings.kind === SyntaxKind.NamespaceImport) { + return visibleDefaultBinding && factory.updateImportDeclaration(decl, /*decorators*/ undefined, decl.modifiers, factory.updateImportClause(decl.importClause, decl.importClause.isTypeOnly, visibleDefaultBinding, + /*namedBindings*/ undefined), rewriteModuleSpecifier(decl, decl.moduleSpecifier), getResolutionModeOverrideForClauseInNightly(decl.assertClause)); + } + if (decl.importClause.namedBindings.kind === ts.SyntaxKind.NamespaceImport) { // Namespace import (optionally with visible default) const namedBindings = resolver.isDeclarationVisible(decl.importClause.namedBindings) ? decl.importClause.namedBindings : /*namedBindings*/ undefined; - return visibleDefaultBinding || namedBindings ? factory.updateImportDeclaration(decl, /*decorators*/ undefined, decl.modifiers, factory.updateImportClause( - decl.importClause, - decl.importClause.isTypeOnly, - visibleDefaultBinding, - namedBindings, - ), rewriteModuleSpecifier(decl, decl.moduleSpecifier), getResolutionModeOverrideForClauseInNightly(decl.assertClause)) : undefined; + return visibleDefaultBinding || namedBindings ? factory.updateImportDeclaration(decl, /*decorators*/ undefined, decl.modifiers, factory.updateImportClause(decl.importClause, decl.importClause.isTypeOnly, visibleDefaultBinding, namedBindings), rewriteModuleSpecifier(decl, decl.moduleSpecifier), getResolutionModeOverrideForClauseInNightly(decl.assertClause)) : undefined; } // Named imports (optionally with visible default) - const bindingList = mapDefined(decl.importClause.namedBindings.elements, b => resolver.isDeclarationVisible(b) ? b : undefined); + const bindingList = ts.mapDefined(decl.importClause.namedBindings.elements, b => resolver.isDeclarationVisible(b) ? b : undefined); if ((bindingList && bindingList.length) || visibleDefaultBinding) { - return factory.updateImportDeclaration( - decl, - /*decorators*/ undefined, - decl.modifiers, - factory.updateImportClause( - decl.importClause, - decl.importClause.isTypeOnly, - visibleDefaultBinding, - bindingList && bindingList.length ? factory.updateNamedImports(decl.importClause.namedBindings, bindingList) : undefined, - ), - rewriteModuleSpecifier(decl, decl.moduleSpecifier), - getResolutionModeOverrideForClauseInNightly(decl.assertClause) - ); + return factory.updateImportDeclaration(decl, + /*decorators*/ undefined, decl.modifiers, factory.updateImportClause(decl.importClause, decl.importClause.isTypeOnly, visibleDefaultBinding, bindingList && bindingList.length ? factory.updateNamedImports(decl.importClause.namedBindings, bindingList) : undefined), rewriteModuleSpecifier(decl, decl.moduleSpecifier), getResolutionModeOverrideForClauseInNightly(decl.assertClause)); } // Augmentation of export depends on import if (resolver.isImportRequiredByAugmentation(decl)) { - return factory.updateImportDeclaration( - decl, - /*decorators*/ undefined, - decl.modifiers, - /*importClause*/ undefined, - rewriteModuleSpecifier(decl, decl.moduleSpecifier), - getResolutionModeOverrideForClauseInNightly(decl.assertClause) - ); + return factory.updateImportDeclaration(decl, + /*decorators*/ undefined, decl.modifiers, + /*importClause*/ undefined, rewriteModuleSpecifier(decl, decl.moduleSpecifier), getResolutionModeOverrideForClauseInNightly(decl.assertClause)); } // Nothing visible } - function getResolutionModeOverrideForClauseInNightly(assertClause: AssertClause | undefined) { - const mode = getResolutionModeOverrideForClause(assertClause); + function getResolutionModeOverrideForClauseInNightly(assertClause: ts.AssertClause | undefined) { + const mode = ts.getResolutionModeOverrideForClause(assertClause); if (mode !== undefined) { - if (!isNightly()) { - context.addDiagnostic(createDiagnosticForNode(assertClause!, Diagnostics.Resolution_mode_assertions_are_unstable_Use_nightly_TypeScript_to_silence_this_error_Try_updating_with_npm_install_D_typescript_next)); + if (!ts.isNightly()) { + context.addDiagnostic(ts.createDiagnosticForNode(assertClause!, ts.Diagnostics.Resolution_mode_assertions_are_unstable_Use_nightly_TypeScript_to_silence_this_error_Try_updating_with_npm_install_D_typescript_next)); } return assertClause; } return undefined; } - function transformAndReplaceLatePaintedStatements(statements: NodeArray): NodeArray { + function transformAndReplaceLatePaintedStatements(statements: ts.NodeArray): ts.NodeArray { // This is a `while` loop because `handleSymbolAccessibilityError` can see additional import aliases marked as visible during // error handling which must now be included in the output and themselves checked for errors. // For example: @@ -814,34 +727,33 @@ namespace ts { // In such a scenario, only Q and D are initially visible, but we don't consider imports as private names - instead we say they if they are referenced they must // be recorded. So while checking D's visibility we mark C as visible, then we must check C which in turn marks B, completing the chain of // dependent imports and allowing a valid declaration file output. Today, this dependent alias marking only happens for internal import aliases. - while (length(lateMarkedStatements)) { + while (ts.length(lateMarkedStatements)) { const i = lateMarkedStatements!.shift()!; - if (!isLateVisibilityPaintedStatement(i)) { - return Debug.fail(`Late replaced statement was found which is not handled by the declaration transformer!: ${(ts as any).SyntaxKind ? (ts as any).SyntaxKind[(i as any).kind] : (i as any).kind}`); + if (!ts.isLateVisibilityPaintedStatement(i)) { + return ts.Debug.fail(`Late replaced statement was found which is not handled by the declaration transformer!: ${(ts as any).SyntaxKind ? (ts as any).SyntaxKind[(i as any).kind] : (i as any).kind}`); } const priorNeedsDeclare = needsDeclare; - needsDeclare = i.parent && isSourceFile(i.parent) && !(isExternalModule(i.parent) && isBundledEmit); + needsDeclare = i.parent && ts.isSourceFile(i.parent) && !(ts.isExternalModule(i.parent) && isBundledEmit); const result = transformTopLevelDeclaration(i); needsDeclare = priorNeedsDeclare; - lateStatementReplacementMap.set(getOriginalNodeId(i), result); + lateStatementReplacementMap.set(ts.getOriginalNodeId(i), result); } // And lastly, we need to get the final form of all those indetermine import declarations from before and add them to the output list // (and remove them from the set to examine for outter declarations) - return visitNodes(statements, visitLateVisibilityMarkedStatements); - - function visitLateVisibilityMarkedStatements(statement: Statement) { - if (isLateVisibilityPaintedStatement(statement)) { - const key = getOriginalNodeId(statement); + return ts.visitNodes(statements, visitLateVisibilityMarkedStatements); + function visitLateVisibilityMarkedStatements(statement: ts.Statement) { + if (ts.isLateVisibilityPaintedStatement(statement)) { + const key = ts.getOriginalNodeId(statement); if (lateStatementReplacementMap.has(key)) { const result = lateStatementReplacementMap.get(key); lateStatementReplacementMap.delete(key); if (result) { - if (isArray(result) ? some(result, needsScopeMarker) : needsScopeMarker(result)) { + if (ts.isArray(result) ? ts.some(result, ts.needsScopeMarker) : ts.needsScopeMarker(result)) { // Top-level declarations in .d.ts files are always considered exported even without a modifier unless there's an export assignment or specifier needsScopeFixMarker = true; } - if (isSourceFile(statement.parent) && (isArray(result) ? some(result, isExternalModuleIndicator) : isExternalModuleIndicator(result))) { + if (ts.isSourceFile(statement.parent) && (ts.isArray(result) ? ts.some(result, ts.isExternalModuleIndicator) : ts.isExternalModuleIndicator(result))) { resultHasExternalModuleIndicator = true; } } @@ -852,47 +764,52 @@ namespace ts { } } - function visitDeclarationSubtree(input: Node): VisitResult { - if (shouldStripInternal(input)) return; - if (isDeclaration(input)) { - if (isDeclarationAndNotVisible(input)) return; - if (hasDynamicName(input) && !resolver.isLateBound(getParseTreeNode(input) as Declaration)) { + function visitDeclarationSubtree(input: ts.Node): ts.VisitResult { + if (shouldStripInternal(input)) + return; + if (ts.isDeclaration(input)) { + if (isDeclarationAndNotVisible(input)) + return; + if (ts.hasDynamicName(input) && !resolver.isLateBound(ts.getParseTreeNode(input) as ts.Declaration)) { return; } } // Elide implementation signatures from overload sets - if (isFunctionLike(input) && resolver.isImplementationOfOverload(input)) return; + if (ts.isFunctionLike(input) && resolver.isImplementationOfOverload(input)) + return; // Elide semicolon class statements - if (isSemicolonClassElement(input)) return; + if (ts.isSemicolonClassElement(input)) + return; let previousEnclosingDeclaration: typeof enclosingDeclaration; if (isEnclosingDeclaration(input)) { previousEnclosingDeclaration = enclosingDeclaration; - enclosingDeclaration = input as Declaration; + enclosingDeclaration = input as ts.Declaration; } const oldDiag = getSymbolAccessibilityDiagnostic; // Setup diagnostic-related flags before first potential `cleanup` call, otherwise // We'd see a TDZ violation at runtime - const canProduceDiagnostic = canProduceDiagnostics(input); + const canProduceDiagnostic = ts.canProduceDiagnostics(input); const oldWithinObjectLiteralType = suppressNewDiagnosticContexts; - let shouldEnterSuppressNewDiagnosticsContextContext = ((input.kind === SyntaxKind.TypeLiteral || input.kind === SyntaxKind.MappedType) && input.parent.kind !== SyntaxKind.TypeAliasDeclaration); + let shouldEnterSuppressNewDiagnosticsContextContext = ((input.kind === ts.SyntaxKind.TypeLiteral || input.kind === ts.SyntaxKind.MappedType) && input.parent.kind !== ts.SyntaxKind.TypeAliasDeclaration); // Emit methods which are private as properties with no type information - if (isMethodDeclaration(input) || isMethodSignature(input)) { - if (hasEffectiveModifier(input, ModifierFlags.Private)) { - if (input.symbol && input.symbol.declarations && input.symbol.declarations[0] !== input) return; // Elide all but the first overload + if (ts.isMethodDeclaration(input) || ts.isMethodSignature(input)) { + if (ts.hasEffectiveModifier(input, ts.ModifierFlags.Private)) { + if (input.symbol && input.symbol.declarations && input.symbol.declarations[0] !== input) + return; // Elide all but the first overload return cleanup(factory.createPropertyDeclaration(/*decorators*/ undefined, ensureModifiers(input), input.name, /*questionToken*/ undefined, /*type*/ undefined, /*initializer*/ undefined)); } } if (canProduceDiagnostic && !suppressNewDiagnosticContexts) { - getSymbolAccessibilityDiagnostic = createGetSymbolAccessibilityDiagnosticForNode(input); + getSymbolAccessibilityDiagnostic = ts.createGetSymbolAccessibilityDiagnosticForNode(input); } - if (isTypeQueryNode(input)) { + if (ts.isTypeQueryNode(input)) { checkEntityNameVisibility(input.exprName, enclosingDeclaration); } @@ -903,188 +820,127 @@ namespace ts { if (isProcessedComponent(input)) { switch (input.kind) { - case SyntaxKind.ExpressionWithTypeArguments: { - if ((isEntityName(input.expression) || isEntityNameExpression(input.expression))) { + case ts.SyntaxKind.ExpressionWithTypeArguments: { + if ((ts.isEntityName(input.expression) || ts.isEntityNameExpression(input.expression))) { checkEntityNameVisibility(input.expression, enclosingDeclaration); } - const node = visitEachChild(input, visitDeclarationSubtree, context); + const node = ts.visitEachChild(input, visitDeclarationSubtree, context); return cleanup(factory.updateExpressionWithTypeArguments(node, node.expression, node.typeArguments)); } - case SyntaxKind.TypeReference: { + case ts.SyntaxKind.TypeReference: { checkEntityNameVisibility(input.typeName, enclosingDeclaration); - const node = visitEachChild(input, visitDeclarationSubtree, context); + const node = ts.visitEachChild(input, visitDeclarationSubtree, context); return cleanup(factory.updateTypeReferenceNode(node, node.typeName, node.typeArguments)); } - case SyntaxKind.ConstructSignature: - return cleanup(factory.updateConstructSignature( - input, - ensureTypeParams(input, input.typeParameters), - updateParamsList(input, input.parameters), - ensureType(input, input.type) - )); - case SyntaxKind.Constructor: { + case ts.SyntaxKind.ConstructSignature: + return cleanup(factory.updateConstructSignature(input, ensureTypeParams(input, input.typeParameters), updateParamsList(input, input.parameters), ensureType(input, input.type))); + case ts.SyntaxKind.Constructor: { // A constructor declaration may not have a type annotation const ctor = factory.createConstructorDeclaration( /*decorators*/ undefined, - /*modifiers*/ ensureModifiers(input), - updateParamsList(input, input.parameters, ModifierFlags.None), - /*body*/ undefined - ); + /*modifiers*/ ensureModifiers(input), updateParamsList(input, input.parameters, ts.ModifierFlags.None), + /*body*/ undefined); return cleanup(ctor); } - case SyntaxKind.MethodDeclaration: { - if (isPrivateIdentifier(input.name)) { + case ts.SyntaxKind.MethodDeclaration: { + if (ts.isPrivateIdentifier(input.name)) { return cleanup(/*returnValue*/ undefined); } const sig = factory.createMethodDeclaration( - /*decorators*/ undefined, - ensureModifiers(input), - /*asteriskToken*/ undefined, - input.name, - input.questionToken, - ensureTypeParams(input, input.typeParameters), - updateParamsList(input, input.parameters), - ensureType(input, input.type), - /*body*/ undefined - ); + /*decorators*/ undefined, ensureModifiers(input), + /*asteriskToken*/ undefined, input.name, input.questionToken, ensureTypeParams(input, input.typeParameters), updateParamsList(input, input.parameters), ensureType(input, input.type), + /*body*/ undefined); return cleanup(sig); } - case SyntaxKind.GetAccessor: { - if (isPrivateIdentifier(input.name)) { + case ts.SyntaxKind.GetAccessor: { + if (ts.isPrivateIdentifier(input.name)) { return cleanup(/*returnValue*/ undefined); } const accessorType = getTypeAnnotationFromAllAccessorDeclarations(input, resolver.getAllAccessorDeclarations(input)); - return cleanup(factory.updateGetAccessorDeclaration( - input, - /*decorators*/ undefined, - ensureModifiers(input), - input.name, - updateAccessorParamsList(input, hasEffectiveModifier(input, ModifierFlags.Private)), - ensureType(input, accessorType), + return cleanup(factory.updateGetAccessorDeclaration(input, + /*decorators*/ undefined, ensureModifiers(input), input.name, updateAccessorParamsList(input, ts.hasEffectiveModifier(input, ts.ModifierFlags.Private)), ensureType(input, accessorType), /*body*/ undefined)); } - case SyntaxKind.SetAccessor: { - if (isPrivateIdentifier(input.name)) { + case ts.SyntaxKind.SetAccessor: { + if (ts.isPrivateIdentifier(input.name)) { return cleanup(/*returnValue*/ undefined); } - return cleanup(factory.updateSetAccessorDeclaration( - input, - /*decorators*/ undefined, - ensureModifiers(input), - input.name, - updateAccessorParamsList(input, hasEffectiveModifier(input, ModifierFlags.Private)), + return cleanup(factory.updateSetAccessorDeclaration(input, + /*decorators*/ undefined, ensureModifiers(input), input.name, updateAccessorParamsList(input, ts.hasEffectiveModifier(input, ts.ModifierFlags.Private)), /*body*/ undefined)); } - case SyntaxKind.PropertyDeclaration: - if (isPrivateIdentifier(input.name)) { + case ts.SyntaxKind.PropertyDeclaration: + if (ts.isPrivateIdentifier(input.name)) { return cleanup(/*returnValue*/ undefined); } - return cleanup(factory.updatePropertyDeclaration( - input, - /*decorators*/ undefined, - ensureModifiers(input), - input.name, - input.questionToken, - ensureType(input, input.type), - ensureNoInitializer(input) - )); - case SyntaxKind.PropertySignature: - if (isPrivateIdentifier(input.name)) { + return cleanup(factory.updatePropertyDeclaration(input, + /*decorators*/ undefined, ensureModifiers(input), input.name, input.questionToken, ensureType(input, input.type), ensureNoInitializer(input))); + case ts.SyntaxKind.PropertySignature: + if (ts.isPrivateIdentifier(input.name)) { return cleanup(/*returnValue*/ undefined); } - return cleanup(factory.updatePropertySignature( - input, - ensureModifiers(input), - input.name, - input.questionToken, - ensureType(input, input.type) - )); - case SyntaxKind.MethodSignature: { - if (isPrivateIdentifier(input.name)) { + return cleanup(factory.updatePropertySignature(input, ensureModifiers(input), input.name, input.questionToken, ensureType(input, input.type))); + case ts.SyntaxKind.MethodSignature: { + if (ts.isPrivateIdentifier(input.name)) { return cleanup(/*returnValue*/ undefined); } - return cleanup(factory.updateMethodSignature( - input, - ensureModifiers(input), - input.name, - input.questionToken, - ensureTypeParams(input, input.typeParameters), - updateParamsList(input, input.parameters), - ensureType(input, input.type) - )); + return cleanup(factory.updateMethodSignature(input, ensureModifiers(input), input.name, input.questionToken, ensureTypeParams(input, input.typeParameters), updateParamsList(input, input.parameters), ensureType(input, input.type))); } - case SyntaxKind.CallSignature: { - return cleanup(factory.updateCallSignature( - input, - ensureTypeParams(input, input.typeParameters), - updateParamsList(input, input.parameters), - ensureType(input, input.type) - )); + case ts.SyntaxKind.CallSignature: { + return cleanup(factory.updateCallSignature(input, ensureTypeParams(input, input.typeParameters), updateParamsList(input, input.parameters), ensureType(input, input.type))); } - case SyntaxKind.IndexSignature: { - return cleanup(factory.updateIndexSignature( - input, - /*decorators*/ undefined, - ensureModifiers(input), - updateParamsList(input, input.parameters), - visitNode(input.type, visitDeclarationSubtree) || factory.createKeywordTypeNode(SyntaxKind.AnyKeyword) - )); + case ts.SyntaxKind.IndexSignature: { + return cleanup(factory.updateIndexSignature(input, + /*decorators*/ undefined, ensureModifiers(input), updateParamsList(input, input.parameters), ts.visitNode(input.type, visitDeclarationSubtree) || factory.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword))); } - case SyntaxKind.VariableDeclaration: { - if (isBindingPattern(input.name)) { + case ts.SyntaxKind.VariableDeclaration: { + if (ts.isBindingPattern(input.name)) { return recreateBindingPattern(input.name); } shouldEnterSuppressNewDiagnosticsContextContext = true; suppressNewDiagnosticContexts = true; // Variable declaration types also suppress new diagnostic contexts, provided the contexts wouldn't be made for binding pattern types return cleanup(factory.updateVariableDeclaration(input, input.name, /*exclamationToken*/ undefined, ensureType(input, input.type), ensureNoInitializer(input))); } - case SyntaxKind.TypeParameter: { + case ts.SyntaxKind.TypeParameter: { if (isPrivateMethodTypeParameter(input) && (input.default || input.constraint)) { return cleanup(factory.updateTypeParameterDeclaration(input, input.modifiers, input.name, /*constraint*/ undefined, /*defaultType*/ undefined)); } - return cleanup(visitEachChild(input, visitDeclarationSubtree, context)); + return cleanup(ts.visitEachChild(input, visitDeclarationSubtree, context)); } - case SyntaxKind.ConditionalType: { + case ts.SyntaxKind.ConditionalType: { // We have to process conditional types in a special way because for visibility purposes we need to push a new enclosingDeclaration // just for the `infer` types in the true branch. It's an implicit declaration scope that only applies to _part_ of the type. - const checkType = visitNode(input.checkType, visitDeclarationSubtree); - const extendsType = visitNode(input.extendsType, visitDeclarationSubtree); + const checkType = ts.visitNode(input.checkType, visitDeclarationSubtree); + const extendsType = ts.visitNode(input.extendsType, visitDeclarationSubtree); const oldEnclosingDecl = enclosingDeclaration; enclosingDeclaration = input.trueType; - const trueType = visitNode(input.trueType, visitDeclarationSubtree); + const trueType = ts.visitNode(input.trueType, visitDeclarationSubtree); enclosingDeclaration = oldEnclosingDecl; - const falseType = visitNode(input.falseType, visitDeclarationSubtree); + const falseType = ts.visitNode(input.falseType, visitDeclarationSubtree); return cleanup(factory.updateConditionalTypeNode(input, checkType, extendsType, trueType, falseType)); } - case SyntaxKind.FunctionType: { - return cleanup(factory.updateFunctionTypeNode(input, visitNodes(input.typeParameters, visitDeclarationSubtree), updateParamsList(input, input.parameters), visitNode(input.type, visitDeclarationSubtree))); + case ts.SyntaxKind.FunctionType: { + return cleanup(factory.updateFunctionTypeNode(input, ts.visitNodes(input.typeParameters, visitDeclarationSubtree), updateParamsList(input, input.parameters), ts.visitNode(input.type, visitDeclarationSubtree))); } - case SyntaxKind.ConstructorType: { - return cleanup(factory.updateConstructorTypeNode(input, ensureModifiers(input), visitNodes(input.typeParameters, visitDeclarationSubtree), updateParamsList(input, input.parameters), visitNode(input.type, visitDeclarationSubtree))); + case ts.SyntaxKind.ConstructorType: { + return cleanup(factory.updateConstructorTypeNode(input, ensureModifiers(input), ts.visitNodes(input.typeParameters, visitDeclarationSubtree), updateParamsList(input, input.parameters), ts.visitNode(input.type, visitDeclarationSubtree))); } - case SyntaxKind.ImportType: { - if (!isLiteralImportTypeNode(input)) return cleanup(input); - return cleanup(factory.updateImportTypeNode( - input, - factory.updateLiteralTypeNode(input.argument, rewriteModuleSpecifier(input, input.argument.literal)), - input.assertions, - input.qualifier, - visitNodes(input.typeArguments, visitDeclarationSubtree, isTypeNode), - input.isTypeOf - )); + case ts.SyntaxKind.ImportType: { + if (!ts.isLiteralImportTypeNode(input)) + return cleanup(input); + return cleanup(factory.updateImportTypeNode(input, factory.updateLiteralTypeNode(input.argument, rewriteModuleSpecifier(input, input.argument.literal)), input.assertions, input.qualifier, ts.visitNodes(input.typeArguments, visitDeclarationSubtree, ts.isTypeNode), input.isTypeOf)); } - default: Debug.assertNever(input, `Attempted to process unhandled node kind: ${(ts as any).SyntaxKind[(input as any).kind]}`); + default: ts.Debug.assertNever(input, `Attempted to process unhandled node kind: ${(ts as any).SyntaxKind[(input as any).kind]}`); } } - if (isTupleTypeNode(input) && (getLineAndCharacterOfPosition(currentSourceFile, input.pos).line === getLineAndCharacterOfPosition(currentSourceFile, input.end).line)) { - setEmitFlags(input, EmitFlags.SingleLine); + if (ts.isTupleTypeNode(input) && (ts.getLineAndCharacterOfPosition(currentSourceFile, input.pos).line === ts.getLineAndCharacterOfPosition(currentSourceFile, input.end).line)) { + ts.setEmitFlags(input, ts.EmitFlags.SingleLine); } - return cleanup(visitEachChild(input, visitDeclarationSubtree, context)); - - function cleanup(returnValue: T | undefined): T | undefined { - if (returnValue && canProduceDiagnostic && hasDynamicName(input as Declaration)) { + return cleanup(ts.visitEachChild(input, visitDeclarationSubtree, context)); + function cleanup(returnValue: T | undefined): T | undefined { + if (returnValue && canProduceDiagnostic && ts.hasDynamicName(input as ts.Declaration)) { checkName(input); } if (isEnclosingDeclaration(input)) { @@ -1099,61 +955,55 @@ namespace ts { if (returnValue === input) { return returnValue; } - return returnValue && setOriginalNode(preserveJsDoc(returnValue, input), input); + return returnValue && ts.setOriginalNode(preserveJsDoc(returnValue, input), input); } } - function isPrivateMethodTypeParameter(node: TypeParameterDeclaration) { - return node.parent.kind === SyntaxKind.MethodDeclaration && hasEffectiveModifier(node.parent, ModifierFlags.Private); + function isPrivateMethodTypeParameter(node: ts.TypeParameterDeclaration) { + return node.parent.kind === ts.SyntaxKind.MethodDeclaration && ts.hasEffectiveModifier(node.parent, ts.ModifierFlags.Private); } - function visitDeclarationStatements(input: Node): VisitResult { + function visitDeclarationStatements(input: ts.Node): ts.VisitResult { if (!isPreservedDeclarationStatement(input)) { // return undefined for unmatched kinds to omit them from the tree return; } - if (shouldStripInternal(input)) return; + if (shouldStripInternal(input)) + return; switch (input.kind) { - case SyntaxKind.ExportDeclaration: { - if (isSourceFile(input.parent)) { + case ts.SyntaxKind.ExportDeclaration: { + if (ts.isSourceFile(input.parent)) { resultHasExternalModuleIndicator = true; } resultHasScopeMarker = true; // Always visible if the parent node isn't dropped for being not visible // Rewrite external module names if necessary - return factory.updateExportDeclaration( - input, - /*decorators*/ undefined, - input.modifiers, - input.isTypeOnly, - input.exportClause, - rewriteModuleSpecifier(input, input.moduleSpecifier), - getResolutionModeOverrideForClause(input.assertClause) ? input.assertClause : undefined - ); + return factory.updateExportDeclaration(input, + /*decorators*/ undefined, input.modifiers, input.isTypeOnly, input.exportClause, rewriteModuleSpecifier(input, input.moduleSpecifier), ts.getResolutionModeOverrideForClause(input.assertClause) ? input.assertClause : undefined); } - case SyntaxKind.ExportAssignment: { + case ts.SyntaxKind.ExportAssignment: { // Always visible if the parent node isn't dropped for being not visible - if (isSourceFile(input.parent)) { + if (ts.isSourceFile(input.parent)) { resultHasExternalModuleIndicator = true; } resultHasScopeMarker = true; - if (input.expression.kind === SyntaxKind.Identifier) { + if (input.expression.kind === ts.SyntaxKind.Identifier) { return input; } else { - const newId = factory.createUniqueName("_default", GeneratedIdentifierFlags.Optimistic); + const newId = factory.createUniqueName("_default", ts.GeneratedIdentifierFlags.Optimistic); getSymbolAccessibilityDiagnostic = () => ({ - diagnosticMessage: Diagnostics.Default_export_of_the_module_has_or_is_using_private_name_0, + diagnosticMessage: ts.Diagnostics.Default_export_of_the_module_has_or_is_using_private_name_0, errorNode: input }); errorFallbackNode = input; const varDecl = factory.createVariableDeclaration(newId, /*exclamationToken*/ undefined, resolver.createTypeOfExpression(input.expression, input, declarationEmitNodeBuilderFlags, symbolTracker), /*initializer*/ undefined); errorFallbackNode = undefined; - const statement = factory.createVariableStatement(needsDeclare ? [factory.createModifier(SyntaxKind.DeclareKeyword)] : [], factory.createVariableDeclarationList([varDecl], NodeFlags.Const)); + const statement = factory.createVariableStatement(needsDeclare ? [factory.createModifier(ts.SyntaxKind.DeclareKeyword)] : [], factory.createVariableDeclarationList([varDecl], ts.NodeFlags.Const)); preserveJsDoc(statement, input); - removeAllComments(input); + ts.removeAllComments(input); return [statement, factory.updateExportAssignment(input, input.decorators, input.modifiers, newId)]; } } @@ -1161,157 +1011,126 @@ namespace ts { const result = transformTopLevelDeclaration(input); // Don't actually transform yet; just leave as original node - will be elided/swapped by late pass - lateStatementReplacementMap.set(getOriginalNodeId(input), result); + lateStatementReplacementMap.set(ts.getOriginalNodeId(input), result); return input; } - function stripExportModifiers(statement: Statement): Statement { - if (isImportEqualsDeclaration(statement) || hasEffectiveModifier(statement, ModifierFlags.Default) || !canHaveModifiers(statement)) { + function stripExportModifiers(statement: ts.Statement): ts.Statement { + if (ts.isImportEqualsDeclaration(statement) || ts.hasEffectiveModifier(statement, ts.ModifierFlags.Default) || !ts.canHaveModifiers(statement)) { // `export import` statements should remain as-is, as imports are _not_ implicitly exported in an ambient namespace // Likewise, `export default` classes and the like and just be `default`, so we preserve their `export` modifiers, too return statement; } - const modifiers = factory.createModifiersFromModifierFlags(getEffectiveModifierFlags(statement) & (ModifierFlags.All ^ ModifierFlags.Export)); + const modifiers = factory.createModifiersFromModifierFlags(ts.getEffectiveModifierFlags(statement) & (ts.ModifierFlags.All ^ ts.ModifierFlags.Export)); return factory.updateModifiers(statement, modifiers); } - function transformTopLevelDeclaration(input: LateVisibilityPaintedStatement) { + function transformTopLevelDeclaration(input: ts.LateVisibilityPaintedStatement) { if (lateMarkedStatements) { - while (orderedRemoveItem(lateMarkedStatements, input)); + while (ts.orderedRemoveItem(lateMarkedStatements, input)) + ; } - if (shouldStripInternal(input)) return; + if (shouldStripInternal(input)) + return; switch (input.kind) { - case SyntaxKind.ImportEqualsDeclaration: { + case ts.SyntaxKind.ImportEqualsDeclaration: { return transformImportEqualsDeclaration(input); } - case SyntaxKind.ImportDeclaration: { + case ts.SyntaxKind.ImportDeclaration: { return transformImportDeclaration(input); } } - if (isDeclaration(input) && isDeclarationAndNotVisible(input)) return; + if (ts.isDeclaration(input) && isDeclarationAndNotVisible(input)) + return; // Elide implementation signatures from overload sets - if (isFunctionLike(input) && resolver.isImplementationOfOverload(input)) return; + if (ts.isFunctionLike(input) && resolver.isImplementationOfOverload(input)) + return; let previousEnclosingDeclaration: typeof enclosingDeclaration; if (isEnclosingDeclaration(input)) { previousEnclosingDeclaration = enclosingDeclaration; - enclosingDeclaration = input as Declaration; + enclosingDeclaration = input as ts.Declaration; } - const canProdiceDiagnostic = canProduceDiagnostics(input); + const canProdiceDiagnostic = ts.canProduceDiagnostics(input); const oldDiag = getSymbolAccessibilityDiagnostic; if (canProdiceDiagnostic) { - getSymbolAccessibilityDiagnostic = createGetSymbolAccessibilityDiagnosticForNode(input as DeclarationDiagnosticProducing); + getSymbolAccessibilityDiagnostic = ts.createGetSymbolAccessibilityDiagnosticForNode(input as ts.DeclarationDiagnosticProducing); } const previousNeedsDeclare = needsDeclare; switch (input.kind) { - case SyntaxKind.TypeAliasDeclaration: // Type aliases get `declare`d if need be (for legacy support), but that's all - return cleanup(factory.updateTypeAliasDeclaration( - input, - /*decorators*/ undefined, - ensureModifiers(input), - input.name, - visitNodes(input.typeParameters, visitDeclarationSubtree, isTypeParameterDeclaration), - visitNode(input.type, visitDeclarationSubtree, isTypeNode) - )); - case SyntaxKind.InterfaceDeclaration: { - return cleanup(factory.updateInterfaceDeclaration( - input, - /*decorators*/ undefined, - ensureModifiers(input), - input.name, - ensureTypeParams(input, input.typeParameters), - transformHeritageClauses(input.heritageClauses), - visitNodes(input.members, visitDeclarationSubtree) - )); + case ts.SyntaxKind.TypeAliasDeclaration: // Type aliases get `declare`d if need be (for legacy support), but that's all + return cleanup(factory.updateTypeAliasDeclaration(input, + /*decorators*/ undefined, ensureModifiers(input), input.name, ts.visitNodes(input.typeParameters, visitDeclarationSubtree, ts.isTypeParameterDeclaration), ts.visitNode(input.type, visitDeclarationSubtree, ts.isTypeNode))); + case ts.SyntaxKind.InterfaceDeclaration: { + return cleanup(factory.updateInterfaceDeclaration(input, + /*decorators*/ undefined, ensureModifiers(input), input.name, ensureTypeParams(input, input.typeParameters), transformHeritageClauses(input.heritageClauses), ts.visitNodes(input.members, visitDeclarationSubtree))); } - case SyntaxKind.FunctionDeclaration: { + case ts.SyntaxKind.FunctionDeclaration: { // Generators lose their generator-ness, excepting their return type - const clean = cleanup(factory.updateFunctionDeclaration( - input, - /*decorators*/ undefined, - ensureModifiers(input), - /*asteriskToken*/ undefined, - input.name, - ensureTypeParams(input, input.typeParameters), - updateParamsList(input, input.parameters), - ensureType(input, input.type), - /*body*/ undefined - )); + const clean = cleanup(factory.updateFunctionDeclaration(input, + /*decorators*/ undefined, ensureModifiers(input), + /*asteriskToken*/ undefined, input.name, ensureTypeParams(input, input.typeParameters), updateParamsList(input, input.parameters), ensureType(input, input.type), + /*body*/ undefined)); if (clean && resolver.isExpandoFunctionDeclaration(input) && shouldEmitFunctionProperties(input)) { const props = resolver.getPropertiesOfContainerFunction(input); // Use parseNodeFactory so it is usable as an enclosing declaration - const fakespace = parseNodeFactory.createModuleDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, clean.name || factory.createIdentifier("_default"), factory.createModuleBlock([]), NodeFlags.Namespace); - setParent(fakespace, enclosingDeclaration as SourceFile | NamespaceDeclaration); - fakespace.locals = createSymbolTable(props); + const fakespace = ts.parseNodeFactory.createModuleDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, clean.name || factory.createIdentifier("_default"), factory.createModuleBlock([]), ts.NodeFlags.Namespace); + ts.setParent(fakespace, enclosingDeclaration as ts.SourceFile | ts.NamespaceDeclaration); + fakespace.locals = ts.createSymbolTable(props); fakespace.symbol = props[0].parent!; - const exportMappings: [Identifier, string][] = []; - let declarations: (VariableStatement | ExportDeclaration)[] = mapDefined(props, p => { - if (!p.valueDeclaration || !isPropertyAccessExpression(p.valueDeclaration)) { + const exportMappings: [ + ts.Identifier, + string + ][] = []; + let declarations: (ts.VariableStatement | ts.ExportDeclaration)[] = ts.mapDefined(props, p => { + if (!p.valueDeclaration || !ts.isPropertyAccessExpression(p.valueDeclaration)) { return undefined; // TODO GH#33569: Handle element access expressions that created late bound names (rather than silently omitting them) } - getSymbolAccessibilityDiagnostic = createGetSymbolAccessibilityDiagnosticForNode(p.valueDeclaration); + getSymbolAccessibilityDiagnostic = ts.createGetSymbolAccessibilityDiagnosticForNode(p.valueDeclaration); const type = resolver.createTypeOfDeclaration(p.valueDeclaration, fakespace, declarationEmitNodeBuilderFlags, symbolTracker); getSymbolAccessibilityDiagnostic = oldDiag; - const nameStr = unescapeLeadingUnderscores(p.escapedName); - const isNonContextualKeywordName = isStringANonContextualKeyword(nameStr); + const nameStr = ts.unescapeLeadingUnderscores(p.escapedName); + const isNonContextualKeywordName = ts.isStringANonContextualKeyword(nameStr); const name = isNonContextualKeywordName ? factory.getGeneratedNameForNode(p.valueDeclaration) : factory.createIdentifier(nameStr); if (isNonContextualKeywordName) { exportMappings.push([name, nameStr]); } const varDecl = factory.createVariableDeclaration(name, /*exclamationToken*/ undefined, type, /*initializer*/ undefined); - return factory.createVariableStatement(isNonContextualKeywordName ? undefined : [factory.createToken(SyntaxKind.ExportKeyword)], factory.createVariableDeclarationList([varDecl])); + return factory.createVariableStatement(isNonContextualKeywordName ? undefined : [factory.createToken(ts.SyntaxKind.ExportKeyword)], factory.createVariableDeclarationList([varDecl])); }); if (!exportMappings.length) { - declarations = mapDefined(declarations, declaration => factory.updateModifiers(declaration, ModifierFlags.None)); + declarations = ts.mapDefined(declarations, declaration => factory.updateModifiers(declaration, ts.ModifierFlags.None)); } else { declarations.push(factory.createExportDeclaration( /*decorators*/ undefined, /*modifiers*/ undefined, - /*isTypeOnly*/ false, - factory.createNamedExports(map(exportMappings, ([gen, exp]) => { + /*isTypeOnly*/ false, factory.createNamedExports(ts.map(exportMappings, ([gen, exp]) => { return factory.createExportSpecifier(/*isTypeOnly*/ false, gen, exp); - })) - )); + })))); } - const namespaceDecl = factory.createModuleDeclaration(/*decorators*/ undefined, ensureModifiers(input), input.name!, factory.createModuleBlock(declarations), NodeFlags.Namespace); - if (!hasEffectiveModifier(clean, ModifierFlags.Default)) { + const namespaceDecl = factory.createModuleDeclaration(/*decorators*/ undefined, ensureModifiers(input), input.name!, factory.createModuleBlock(declarations), ts.NodeFlags.Namespace); + if (!ts.hasEffectiveModifier(clean, ts.ModifierFlags.Default)) { return [clean, namespaceDecl]; } - const modifiers = factory.createModifiersFromModifierFlags((getEffectiveModifierFlags(clean) & ~ModifierFlags.ExportDefault) | ModifierFlags.Ambient); - const cleanDeclaration = factory.updateFunctionDeclaration( - clean, - /*decorators*/ undefined, - modifiers, - /*asteriskToken*/ undefined, - clean.name, - clean.typeParameters, - clean.parameters, - clean.type, - /*body*/ undefined - ); - - const namespaceDeclaration = factory.updateModuleDeclaration( - namespaceDecl, - /*decorators*/ undefined, - modifiers, - namespaceDecl.name, - namespaceDecl.body - ); + const modifiers = factory.createModifiersFromModifierFlags((ts.getEffectiveModifierFlags(clean) & ~ts.ModifierFlags.ExportDefault) | ts.ModifierFlags.Ambient); + const cleanDeclaration = factory.updateFunctionDeclaration(clean, + /*decorators*/ undefined, modifiers, + /*asteriskToken*/ undefined, clean.name, clean.typeParameters, clean.parameters, clean.type, + /*body*/ undefined); + const namespaceDeclaration = factory.updateModuleDeclaration(namespaceDecl, + /*decorators*/ undefined, modifiers, namespaceDecl.name, namespaceDecl.body); const exportDefaultDeclaration = factory.createExportAssignment( /*decorators*/ undefined, /*modifiers*/ undefined, - /*isExportEquals*/ false, - namespaceDecl.name - ); - - if (isSourceFile(input.parent)) { + /*isExportEquals*/ false, namespaceDecl.name); + if (ts.isSourceFile(input.parent)) { resultHasExternalModuleIndicator = true; } resultHasScopeMarker = true; @@ -1322,29 +1141,29 @@ namespace ts { return clean; } } - case SyntaxKind.ModuleDeclaration: { + case ts.SyntaxKind.ModuleDeclaration: { needsDeclare = false; const inner = input.body; - if (inner && inner.kind === SyntaxKind.ModuleBlock) { + if (inner && inner.kind === ts.SyntaxKind.ModuleBlock) { const oldNeedsScopeFix = needsScopeFixMarker; const oldHasScopeFix = resultHasScopeMarker; resultHasScopeMarker = false; needsScopeFixMarker = false; - const statements = visitNodes(inner.statements, visitDeclarationStatements); + const statements = ts.visitNodes(inner.statements, visitDeclarationStatements); let lateStatements = transformAndReplaceLatePaintedStatements(statements); - if (input.flags & NodeFlags.Ambient) { + if (input.flags & ts.NodeFlags.Ambient) { needsScopeFixMarker = false; // If it was `declare`'d everything is implicitly exported already, ignore late printed "privates" } // With the final list of statements, there are 3 possibilities: // 1. There's an export assignment or export declaration in the namespace - do nothing // 2. Everything is exported and there are no export assignments or export declarations - strip all export modifiers // 3. Some things are exported, some are not, and there's no marker - add an empty marker - if (!isGlobalScopeAugmentation(input) && !hasScopeMarker(lateStatements) && !resultHasScopeMarker) { + if (!ts.isGlobalScopeAugmentation(input) && !hasScopeMarker(lateStatements) && !resultHasScopeMarker) { if (needsScopeFixMarker) { - lateStatements = factory.createNodeArray([...lateStatements, createEmptyExports(factory)]); + lateStatements = factory.createNodeArray([...lateStatements, ts.createEmptyExports(factory)]); } else { - lateStatements = visitNodes(lateStatements, stripExportModifiers); + lateStatements = ts.visitNodes(lateStatements, stripExportModifiers); } } const body = factory.updateModuleBlock(inner, lateStatements); @@ -1352,74 +1171,57 @@ namespace ts { needsScopeFixMarker = oldNeedsScopeFix; resultHasScopeMarker = oldHasScopeFix; const mods = ensureModifiers(input); - return cleanup(factory.updateModuleDeclaration( - input, - /*decorators*/ undefined, - mods, - isExternalModuleAugmentation(input) ? rewriteModuleSpecifier(input, input.name) : input.name, - body - )); + return cleanup(factory.updateModuleDeclaration(input, + /*decorators*/ undefined, mods, ts.isExternalModuleAugmentation(input) ? rewriteModuleSpecifier(input, input.name) : input.name, body)); } else { needsDeclare = previousNeedsDeclare; const mods = ensureModifiers(input); needsDeclare = false; - visitNode(inner, visitDeclarationStatements); + ts.visitNode(inner, visitDeclarationStatements); // eagerly transform nested namespaces (the nesting doesn't need any elision or painting done) - const id = getOriginalNodeId(inner!); // TODO: GH#18217 + const id = ts.getOriginalNodeId(inner!); // TODO: GH#18217 const body = lateStatementReplacementMap.get(id); lateStatementReplacementMap.delete(id); - return cleanup(factory.updateModuleDeclaration( - input, - /*decorators*/ undefined, - mods, - input.name, - body as ModuleBody - )); + return cleanup(factory.updateModuleDeclaration(input, + /*decorators*/ undefined, mods, input.name, body as ts.ModuleBody)); } } - case SyntaxKind.ClassDeclaration: { + case ts.SyntaxKind.ClassDeclaration: { errorNameNode = input.name; errorFallbackNode = input; const modifiers = factory.createNodeArray(ensureModifiers(input)); const typeParameters = ensureTypeParams(input, input.typeParameters); - const ctor = getFirstConstructorWithBody(input); - let parameterProperties: readonly PropertyDeclaration[] | undefined; + const ctor = ts.getFirstConstructorWithBody(input); + let parameterProperties: readonly ts.PropertyDeclaration[] | undefined; if (ctor) { const oldDiag = getSymbolAccessibilityDiagnostic; - parameterProperties = compact(flatMap(ctor.parameters, (param) => { - if (!hasSyntacticModifier(param, ModifierFlags.ParameterPropertyModifier) || shouldStripInternal(param)) return; - getSymbolAccessibilityDiagnostic = createGetSymbolAccessibilityDiagnosticForNode(param); - if (param.name.kind === SyntaxKind.Identifier) { + parameterProperties = ts.compact(ts.flatMap(ctor.parameters, (param) => { + if (!ts.hasSyntacticModifier(param, ts.ModifierFlags.ParameterPropertyModifier) || shouldStripInternal(param)) + return; + getSymbolAccessibilityDiagnostic = ts.createGetSymbolAccessibilityDiagnosticForNode(param); + if (param.name.kind === ts.SyntaxKind.Identifier) { return preserveJsDoc(factory.createPropertyDeclaration( - /*decorators*/ undefined, - ensureModifiers(param), - param.name, - param.questionToken, - ensureType(param, param.type), - ensureNoInitializer(param)), param); + /*decorators*/ undefined, ensureModifiers(param), param.name, param.questionToken, ensureType(param, param.type), ensureNoInitializer(param)), param); } else { // Pattern - this is currently an error, but we emit declarations for it somewhat correctly return walkBindingPattern(param.name); } - function walkBindingPattern(pattern: BindingPattern) { - let elems: PropertyDeclaration[] | undefined; + function walkBindingPattern(pattern: ts.BindingPattern) { + let elems: ts.PropertyDeclaration[] | undefined; for (const elem of pattern.elements) { - if (isOmittedExpression(elem)) continue; - if (isBindingPattern(elem.name)) { - elems = concatenate(elems, walkBindingPattern(elem.name)); + if (ts.isOmittedExpression(elem)) + continue; + if (ts.isBindingPattern(elem.name)) { + elems = ts.concatenate(elems, walkBindingPattern(elem.name)); } elems = elems || []; elems.push(factory.createPropertyDeclaration( - /*decorators*/ undefined, - ensureModifiers(param), - elem.name as Identifier, - /*questionToken*/ undefined, - ensureType(elem, /*type*/ undefined), - /*initializer*/ undefined - )); + /*decorators*/ undefined, ensureModifiers(param), elem.name as ts.Identifier, + /*questionToken*/ undefined, ensureType(elem, /*type*/ undefined), + /*initializer*/ undefined)); } return elems; } @@ -1427,74 +1229,59 @@ namespace ts { getSymbolAccessibilityDiagnostic = oldDiag; } - const hasPrivateIdentifier = some(input.members, member => !!member.name && isPrivateIdentifier(member.name)); + const hasPrivateIdentifier = ts.some(input.members, member => !!member.name && ts.isPrivateIdentifier(member.name)); // When the class has at least one private identifier, create a unique constant identifier to retain the nominal typing behavior // Prevents other classes with the same public members from being used in place of the current class const privateIdentifier = hasPrivateIdentifier ? [ factory.createPropertyDeclaration( /*decorators*/ undefined, - /*modifiers*/ undefined, - factory.createPrivateIdentifier("#private"), + /*modifiers*/ undefined, factory.createPrivateIdentifier("#private"), /*questionToken*/ undefined, /*type*/ undefined, - /*initializer*/ undefined - ) + /*initializer*/ undefined) ] : undefined; - const memberNodes = concatenate(concatenate(privateIdentifier, parameterProperties), visitNodes(input.members, visitDeclarationSubtree)); + const memberNodes = ts.concatenate(ts.concatenate(privateIdentifier, parameterProperties), ts.visitNodes(input.members, visitDeclarationSubtree)); const members = factory.createNodeArray(memberNodes); - const extendsClause = getEffectiveBaseTypeNode(input); - if (extendsClause && !isEntityNameExpression(extendsClause.expression) && extendsClause.expression.kind !== SyntaxKind.NullKeyword) { + const extendsClause = ts.getEffectiveBaseTypeNode(input); + if (extendsClause && !ts.isEntityNameExpression(extendsClause.expression) && extendsClause.expression.kind !== ts.SyntaxKind.NullKeyword) { // We must add a temporary declaration for the extends clause expression - const oldId = input.name ? unescapeLeadingUnderscores(input.name.escapedText) : "default"; - const newId = factory.createUniqueName(`${oldId}_base`, GeneratedIdentifierFlags.Optimistic); + const oldId = input.name ? ts.unescapeLeadingUnderscores(input.name.escapedText) : "default"; + const newId = factory.createUniqueName(`${oldId}_base`, ts.GeneratedIdentifierFlags.Optimistic); getSymbolAccessibilityDiagnostic = () => ({ - diagnosticMessage: Diagnostics.extends_clause_of_exported_class_0_has_or_is_using_private_name_1, + diagnosticMessage: ts.Diagnostics.extends_clause_of_exported_class_0_has_or_is_using_private_name_1, errorNode: extendsClause, typeName: input.name }); const varDecl = factory.createVariableDeclaration(newId, /*exclamationToken*/ undefined, resolver.createTypeOfExpression(extendsClause.expression, input, declarationEmitNodeBuilderFlags, symbolTracker), /*initializer*/ undefined); - const statement = factory.createVariableStatement(needsDeclare ? [factory.createModifier(SyntaxKind.DeclareKeyword)] : [], factory.createVariableDeclarationList([varDecl], NodeFlags.Const)); - const heritageClauses = factory.createNodeArray(map(input.heritageClauses, clause => { - if (clause.token === SyntaxKind.ExtendsKeyword) { + const statement = factory.createVariableStatement(needsDeclare ? [factory.createModifier(ts.SyntaxKind.DeclareKeyword)] : [], factory.createVariableDeclarationList([varDecl], ts.NodeFlags.Const)); + const heritageClauses = factory.createNodeArray(ts.map(input.heritageClauses, clause => { + if (clause.token === ts.SyntaxKind.ExtendsKeyword) { const oldDiag = getSymbolAccessibilityDiagnostic; - getSymbolAccessibilityDiagnostic = createGetSymbolAccessibilityDiagnosticForNode(clause.types[0]); - const newClause = factory.updateHeritageClause(clause, map(clause.types, t => factory.updateExpressionWithTypeArguments(t, newId, visitNodes(t.typeArguments, visitDeclarationSubtree)))); + getSymbolAccessibilityDiagnostic = ts.createGetSymbolAccessibilityDiagnosticForNode(clause.types[0]); + const newClause = factory.updateHeritageClause(clause, ts.map(clause.types, t => factory.updateExpressionWithTypeArguments(t, newId, ts.visitNodes(t.typeArguments, visitDeclarationSubtree)))); getSymbolAccessibilityDiagnostic = oldDiag; return newClause; } - return factory.updateHeritageClause(clause, visitNodes(factory.createNodeArray(filter(clause.types, t => isEntityNameExpression(t.expression) || t.expression.kind === SyntaxKind.NullKeyword)), visitDeclarationSubtree)); + return factory.updateHeritageClause(clause, ts.visitNodes(factory.createNodeArray(ts.filter(clause.types, t => ts.isEntityNameExpression(t.expression) || t.expression.kind === ts.SyntaxKind.NullKeyword)), visitDeclarationSubtree)); })); - return [statement, cleanup(factory.updateClassDeclaration( - input, - /*decorators*/ undefined, - modifiers, - input.name, - typeParameters, - heritageClauses, - members - ))!]; // TODO: GH#18217 + return [statement, cleanup(factory.updateClassDeclaration(input, + /*decorators*/ undefined, modifiers, input.name, typeParameters, heritageClauses, members))!]; // TODO: GH#18217 } else { const heritageClauses = transformHeritageClauses(input.heritageClauses); - return cleanup(factory.updateClassDeclaration( - input, - /*decorators*/ undefined, - modifiers, - input.name, - typeParameters, - heritageClauses, - members - )); + return cleanup(factory.updateClassDeclaration(input, + /*decorators*/ undefined, modifiers, input.name, typeParameters, heritageClauses, members)); } } - case SyntaxKind.VariableStatement: { + case ts.SyntaxKind.VariableStatement: { return cleanup(transformVariableStatement(input)); } - case SyntaxKind.EnumDeclaration: { - return cleanup(factory.updateEnumDeclaration(input, /*decorators*/ undefined, factory.createNodeArray(ensureModifiers(input)), input.name, factory.createNodeArray(mapDefined(input.members, m => { - if (shouldStripInternal(m)) return; + case ts.SyntaxKind.EnumDeclaration: { + return cleanup(factory.updateEnumDeclaration(input, /*decorators*/ undefined, factory.createNodeArray(ensureModifiers(input)), input.name, factory.createNodeArray(ts.mapDefined(input.members, m => { + if (shouldStripInternal(m)) + return; // Rewrite enum values to their constants, if available const constValue = resolver.getConstantValue(m); return preserveJsDoc(factory.updateEnumMember(m, m.name, constValue !== undefined ? typeof constValue === "string" ? factory.createStringLiteral(constValue) : factory.createNumericLiteral(constValue) : undefined), m); @@ -1502,45 +1289,47 @@ namespace ts { } } // Anything left unhandled is an error, so this should be unreachable - return Debug.assertNever(input, `Unhandled top-level node in declaration emit: ${(ts as any).SyntaxKind[(input as any).kind]}`); - - function cleanup(node: T | undefined): T | undefined { + return ts.Debug.assertNever(input, `Unhandled top-level node in declaration emit: ${(ts as any).SyntaxKind[(input as any).kind]}`); + function cleanup(node: T | undefined): T | undefined { if (isEnclosingDeclaration(input)) { enclosingDeclaration = previousEnclosingDeclaration; } if (canProdiceDiagnostic) { getSymbolAccessibilityDiagnostic = oldDiag; } - if (input.kind === SyntaxKind.ModuleDeclaration) { + if (input.kind === ts.SyntaxKind.ModuleDeclaration) { needsDeclare = previousNeedsDeclare; } - if (node as Node === input) { + if (node as ts.Node === input) { return node; } errorFallbackNode = undefined; errorNameNode = undefined; - return node && setOriginalNode(preserveJsDoc(node, input), input); + return node && ts.setOriginalNode(preserveJsDoc(node, input), input); } } - function transformVariableStatement(input: VariableStatement) { - if (!forEach(input.declarationList.declarations, getBindingNameVisible)) return; - const nodes = visitNodes(input.declarationList.declarations, visitDeclarationSubtree); - if (!length(nodes)) return; + function transformVariableStatement(input: ts.VariableStatement) { + if (!ts.forEach(input.declarationList.declarations, getBindingNameVisible)) + return; + const nodes = ts.visitNodes(input.declarationList.declarations, visitDeclarationSubtree); + if (!ts.length(nodes)) + return; return factory.updateVariableStatement(input, factory.createNodeArray(ensureModifiers(input)), factory.updateVariableDeclarationList(input.declarationList, nodes)); } - function recreateBindingPattern(d: BindingPattern): VariableDeclaration[] { - return flatten(mapDefined(d.elements, e => recreateBindingElement(e))); + function recreateBindingPattern(d: ts.BindingPattern): ts.VariableDeclaration[] { + return ts.flatten(ts.mapDefined(d.elements, e => recreateBindingElement(e))); } - function recreateBindingElement(e: ArrayBindingElement) { - if (e.kind === SyntaxKind.OmittedExpression) { + function recreateBindingElement(e: ts.ArrayBindingElement) { + if (e.kind === ts.SyntaxKind.OmittedExpression) { return; } if (e.name) { - if (!getBindingNameVisible(e)) return; - if (isBindingPattern(e.name)) { + if (!getBindingNameVisible(e)) + return; + if (ts.isBindingPattern(e.name)) { return recreateBindingPattern(e.name); } else { @@ -1549,15 +1338,15 @@ namespace ts { } } - function checkName(node: DeclarationDiagnosticProducing) { + function checkName(node: ts.DeclarationDiagnosticProducing) { let oldDiag: typeof getSymbolAccessibilityDiagnostic | undefined; if (!suppressNewDiagnosticContexts) { oldDiag = getSymbolAccessibilityDiagnostic; - getSymbolAccessibilityDiagnostic = createGetSymbolAccessibilityDiagnosticForNodeName(node); + getSymbolAccessibilityDiagnostic = ts.createGetSymbolAccessibilityDiagnosticForNodeName(node); } - errorNameNode = (node as NamedDeclaration).name; - Debug.assert(resolver.isLateBound(getParseTreeNode(node) as Declaration)); // Should only be called with dynamic names - const decl = node as NamedDeclaration as LateBoundDeclaration; + errorNameNode = (node as ts.NamedDeclaration).name; + ts.Debug.assert(resolver.isLateBound(ts.getParseTreeNode(node) as ts.Declaration)); // Should only be called with dynamic names + const decl = node as ts.NamedDeclaration as ts.LateBoundDeclaration; const entityName = decl.name.expression; checkEntityNameVisibility(entityName, enclosingDeclaration); if (!suppressNewDiagnosticContexts) { @@ -1566,20 +1355,20 @@ namespace ts { errorNameNode = undefined; } - function shouldStripInternal(node: Node) { + function shouldStripInternal(node: ts.Node) { return !!stripInternal && !!node && isInternalDeclaration(node, currentSourceFile); } - function isScopeMarker(node: Node) { - return isExportAssignment(node) || isExportDeclaration(node); + function isScopeMarker(node: ts.Node) { + return ts.isExportAssignment(node) || ts.isExportDeclaration(node); } - function hasScopeMarker(statements: readonly Statement[]) { - return some(statements, isScopeMarker); + function hasScopeMarker(statements: readonly ts.Statement[]) { + return ts.some(statements, isScopeMarker); } - function ensureModifiers(node: Node): readonly Modifier[] | undefined { - const currentFlags = getEffectiveModifierFlags(node); + function ensureModifiers(node: ts.Node): readonly ts.Modifier[] | undefined { + const currentFlags = ts.getEffectiveModifierFlags(node); const newFlags = ensureModifierFlags(node); if (currentFlags === newFlags) { return node.modifiers; @@ -1587,67 +1376,67 @@ namespace ts { return factory.createModifiersFromModifierFlags(newFlags); } - function ensureModifierFlags(node: Node): ModifierFlags { - let mask = ModifierFlags.All ^ (ModifierFlags.Public | ModifierFlags.Async | ModifierFlags.Override); // No async and override modifiers in declaration files - let additions = (needsDeclare && !isAlwaysType(node)) ? ModifierFlags.Ambient : ModifierFlags.None; - const parentIsFile = node.parent.kind === SyntaxKind.SourceFile; - if (!parentIsFile || (isBundledEmit && parentIsFile && isExternalModule(node.parent as SourceFile))) { - mask ^= ModifierFlags.Ambient; - additions = ModifierFlags.None; + function ensureModifierFlags(node: ts.Node): ts.ModifierFlags { + let mask = ts.ModifierFlags.All ^ (ts.ModifierFlags.Public | ts.ModifierFlags.Async | ts.ModifierFlags.Override); // No async and override modifiers in declaration files + let additions = (needsDeclare && !isAlwaysType(node)) ? ts.ModifierFlags.Ambient : ts.ModifierFlags.None; + const parentIsFile = node.parent.kind === ts.SyntaxKind.SourceFile; + if (!parentIsFile || (isBundledEmit && parentIsFile && ts.isExternalModule(node.parent as ts.SourceFile))) { + mask ^= ts.ModifierFlags.Ambient; + additions = ts.ModifierFlags.None; } return maskModifierFlags(node, mask, additions); } - function getTypeAnnotationFromAllAccessorDeclarations(node: AccessorDeclaration, accessors: AllAccessorDeclarations) { + function getTypeAnnotationFromAllAccessorDeclarations(node: ts.AccessorDeclaration, accessors: ts.AllAccessorDeclarations) { let accessorType = getTypeAnnotationFromAccessor(node); if (!accessorType && node !== accessors.firstAccessor) { accessorType = getTypeAnnotationFromAccessor(accessors.firstAccessor); // If we end up pulling the type from the second accessor, we also need to change the diagnostic context to get the expected error message - getSymbolAccessibilityDiagnostic = createGetSymbolAccessibilityDiagnosticForNode(accessors.firstAccessor); + getSymbolAccessibilityDiagnostic = ts.createGetSymbolAccessibilityDiagnosticForNode(accessors.firstAccessor); } if (!accessorType && accessors.secondAccessor && node !== accessors.secondAccessor) { accessorType = getTypeAnnotationFromAccessor(accessors.secondAccessor); // If we end up pulling the type from the second accessor, we also need to change the diagnostic context to get the expected error message - getSymbolAccessibilityDiagnostic = createGetSymbolAccessibilityDiagnosticForNode(accessors.secondAccessor); + getSymbolAccessibilityDiagnostic = ts.createGetSymbolAccessibilityDiagnosticForNode(accessors.secondAccessor); } return accessorType; } - function transformHeritageClauses(nodes: NodeArray | undefined) { - return factory.createNodeArray(filter(map(nodes, clause => factory.updateHeritageClause(clause, visitNodes(factory.createNodeArray(filter(clause.types, t => { - return isEntityNameExpression(t.expression) || (clause.token === SyntaxKind.ExtendsKeyword && t.expression.kind === SyntaxKind.NullKeyword); + function transformHeritageClauses(nodes: ts.NodeArray | undefined) { + return factory.createNodeArray(ts.filter(ts.map(nodes, clause => factory.updateHeritageClause(clause, ts.visitNodes(factory.createNodeArray(ts.filter(clause.types, t => { + return ts.isEntityNameExpression(t.expression) || (clause.token === ts.SyntaxKind.ExtendsKeyword && t.expression.kind === ts.SyntaxKind.NullKeyword); })), visitDeclarationSubtree))), clause => clause.types && !!clause.types.length)); } } - function isAlwaysType(node: Node) { - if (node.kind === SyntaxKind.InterfaceDeclaration) { + function isAlwaysType(node: ts.Node) { + if (node.kind === ts.SyntaxKind.InterfaceDeclaration) { return true; } return false; } // Elide "public" modifier, as it is the default - function maskModifiers(node: Node, modifierMask?: ModifierFlags, modifierAdditions?: ModifierFlags): Modifier[] | undefined { - return factory.createModifiersFromModifierFlags(maskModifierFlags(node, modifierMask, modifierAdditions)); + function maskModifiers(node: ts.Node, modifierMask?: ts.ModifierFlags, modifierAdditions?: ts.ModifierFlags): ts.Modifier[] | undefined { + return ts.factory.createModifiersFromModifierFlags(maskModifierFlags(node, modifierMask, modifierAdditions)); } - function maskModifierFlags(node: Node, modifierMask: ModifierFlags = ModifierFlags.All ^ ModifierFlags.Public, modifierAdditions: ModifierFlags = ModifierFlags.None): ModifierFlags { - let flags = (getEffectiveModifierFlags(node) & modifierMask) | modifierAdditions; - if (flags & ModifierFlags.Default && !(flags & ModifierFlags.Export)) { + function maskModifierFlags(node: ts.Node, modifierMask: ts.ModifierFlags = ts.ModifierFlags.All ^ ts.ModifierFlags.Public, modifierAdditions: ts.ModifierFlags = ts.ModifierFlags.None): ts.ModifierFlags { + let flags = (ts.getEffectiveModifierFlags(node) & modifierMask) | modifierAdditions; + if (flags & ts.ModifierFlags.Default && !(flags & ts.ModifierFlags.Export)) { // A non-exported default is a nonsequitor - we usually try to remove all export modifiers // from statements in ambient declarations; but a default export must retain its export modifier to be syntactically valid - flags ^= ModifierFlags.Export; + flags ^= ts.ModifierFlags.Export; } - if (flags & ModifierFlags.Default && flags & ModifierFlags.Ambient) { - flags ^= ModifierFlags.Ambient; // `declare` is never required alongside `default` (and would be an error if printed) + if (flags & ts.ModifierFlags.Default && flags & ts.ModifierFlags.Ambient) { + flags ^= ts.ModifierFlags.Ambient; // `declare` is never required alongside `default` (and would be an error if printed) } return flags; } - function getTypeAnnotationFromAccessor(accessor: AccessorDeclaration): TypeNode | undefined { + function getTypeAnnotationFromAccessor(accessor: ts.AccessorDeclaration): ts.TypeNode | undefined { if (accessor) { - return accessor.kind === SyntaxKind.GetAccessor + return accessor.kind === ts.SyntaxKind.GetAccessor ? accessor.type // Getter - return type : accessor.parameters.length > 0 ? accessor.parameters[0].type // Setter parameter type @@ -1655,90 +1444,59 @@ namespace ts { } } - type CanHaveLiteralInitializer = VariableDeclaration | PropertyDeclaration | PropertySignature | ParameterDeclaration; - function canHaveLiteralInitializer(node: Node): boolean { + type CanHaveLiteralInitializer = ts.VariableDeclaration | ts.PropertyDeclaration | ts.PropertySignature | ts.ParameterDeclaration; + function canHaveLiteralInitializer(node: ts.Node): boolean { switch (node.kind) { - case SyntaxKind.PropertyDeclaration: - case SyntaxKind.PropertySignature: - return !hasEffectiveModifier(node, ModifierFlags.Private); - case SyntaxKind.Parameter: - case SyntaxKind.VariableDeclaration: + case ts.SyntaxKind.PropertyDeclaration: + case ts.SyntaxKind.PropertySignature: + return !ts.hasEffectiveModifier(node, ts.ModifierFlags.Private); + case ts.SyntaxKind.Parameter: + case ts.SyntaxKind.VariableDeclaration: return true; } return false; } - type ProcessedDeclarationStatement = - | FunctionDeclaration - | ModuleDeclaration - | ImportEqualsDeclaration - | InterfaceDeclaration - | ClassDeclaration - | TypeAliasDeclaration - | EnumDeclaration - | VariableStatement - | ImportDeclaration - | ExportDeclaration - | ExportAssignment; - - function isPreservedDeclarationStatement(node: Node): node is ProcessedDeclarationStatement { + type ProcessedDeclarationStatement = ts.FunctionDeclaration | ts.ModuleDeclaration | ts.ImportEqualsDeclaration | ts.InterfaceDeclaration | ts.ClassDeclaration | ts.TypeAliasDeclaration | ts.EnumDeclaration | ts.VariableStatement | ts.ImportDeclaration | ts.ExportDeclaration | ts.ExportAssignment; + function isPreservedDeclarationStatement(node: ts.Node): node is ProcessedDeclarationStatement { switch (node.kind) { - case SyntaxKind.FunctionDeclaration: - case SyntaxKind.ModuleDeclaration: - case SyntaxKind.ImportEqualsDeclaration: - case SyntaxKind.InterfaceDeclaration: - case SyntaxKind.ClassDeclaration: - case SyntaxKind.TypeAliasDeclaration: - case SyntaxKind.EnumDeclaration: - case SyntaxKind.VariableStatement: - case SyntaxKind.ImportDeclaration: - case SyntaxKind.ExportDeclaration: - case SyntaxKind.ExportAssignment: + case ts.SyntaxKind.FunctionDeclaration: + case ts.SyntaxKind.ModuleDeclaration: + case ts.SyntaxKind.ImportEqualsDeclaration: + case ts.SyntaxKind.InterfaceDeclaration: + case ts.SyntaxKind.ClassDeclaration: + case ts.SyntaxKind.TypeAliasDeclaration: + case ts.SyntaxKind.EnumDeclaration: + case ts.SyntaxKind.VariableStatement: + case ts.SyntaxKind.ImportDeclaration: + case ts.SyntaxKind.ExportDeclaration: + case ts.SyntaxKind.ExportAssignment: return true; } return false; } - type ProcessedComponent = - | ConstructSignatureDeclaration - | ConstructorDeclaration - | MethodDeclaration - | GetAccessorDeclaration - | SetAccessorDeclaration - | PropertyDeclaration - | PropertySignature - | MethodSignature - | CallSignatureDeclaration - | IndexSignatureDeclaration - | VariableDeclaration - | TypeParameterDeclaration - | ExpressionWithTypeArguments - | TypeReferenceNode - | ConditionalTypeNode - | FunctionTypeNode - | ConstructorTypeNode - | ImportTypeNode; - - function isProcessedComponent(node: Node): node is ProcessedComponent { + type ProcessedComponent = ts.ConstructSignatureDeclaration | ts.ConstructorDeclaration | ts.MethodDeclaration | ts.GetAccessorDeclaration | ts.SetAccessorDeclaration | ts.PropertyDeclaration | ts.PropertySignature | ts.MethodSignature | ts.CallSignatureDeclaration | ts.IndexSignatureDeclaration | ts.VariableDeclaration | ts.TypeParameterDeclaration | ts.ExpressionWithTypeArguments | ts.TypeReferenceNode | ts.ConditionalTypeNode | ts.FunctionTypeNode | ts.ConstructorTypeNode | ts.ImportTypeNode; + function isProcessedComponent(node: ts.Node): node is ProcessedComponent { switch (node.kind) { - case SyntaxKind.ConstructSignature: - case SyntaxKind.Constructor: - case SyntaxKind.MethodDeclaration: - case SyntaxKind.GetAccessor: - case SyntaxKind.SetAccessor: - case SyntaxKind.PropertyDeclaration: - case SyntaxKind.PropertySignature: - case SyntaxKind.MethodSignature: - case SyntaxKind.CallSignature: - case SyntaxKind.IndexSignature: - case SyntaxKind.VariableDeclaration: - case SyntaxKind.TypeParameter: - case SyntaxKind.ExpressionWithTypeArguments: - case SyntaxKind.TypeReference: - case SyntaxKind.ConditionalType: - case SyntaxKind.FunctionType: - case SyntaxKind.ConstructorType: - case SyntaxKind.ImportType: + case ts.SyntaxKind.ConstructSignature: + case ts.SyntaxKind.Constructor: + case ts.SyntaxKind.MethodDeclaration: + case ts.SyntaxKind.GetAccessor: + case ts.SyntaxKind.SetAccessor: + case ts.SyntaxKind.PropertyDeclaration: + case ts.SyntaxKind.PropertySignature: + case ts.SyntaxKind.MethodSignature: + case ts.SyntaxKind.CallSignature: + case ts.SyntaxKind.IndexSignature: + case ts.SyntaxKind.VariableDeclaration: + case ts.SyntaxKind.TypeParameter: + case ts.SyntaxKind.ExpressionWithTypeArguments: + case ts.SyntaxKind.TypeReference: + case ts.SyntaxKind.ConditionalType: + case ts.SyntaxKind.FunctionType: + case ts.SyntaxKind.ConstructorType: + case ts.SyntaxKind.ImportType: return true; } return false; diff --git a/src/compiler/transformers/declarations/diagnostics.ts b/src/compiler/transformers/declarations/diagnostics.ts index 81b00987efdd8..494ab9420f3a5 100644 --- a/src/compiler/transformers/declarations/diagnostics.ts +++ b/src/compiler/transformers/declarations/diagnostics.ts @@ -1,490 +1,462 @@ /* @internal */ namespace ts { - export type GetSymbolAccessibilityDiagnostic = (symbolAccessibilityResult: SymbolAccessibilityResult) => (SymbolAccessibilityDiagnostic | undefined); + export type GetSymbolAccessibilityDiagnostic = (symbolAccessibilityResult: ts.SymbolAccessibilityResult) => (SymbolAccessibilityDiagnostic | undefined); export interface SymbolAccessibilityDiagnostic { - errorNode: Node; - diagnosticMessage: DiagnosticMessage; - typeName?: DeclarationName | QualifiedName; + errorNode: ts.Node; + diagnosticMessage: ts.DiagnosticMessage; + typeName?: ts.DeclarationName | ts.QualifiedName; } - - export type DeclarationDiagnosticProducing = - | VariableDeclaration - | PropertyDeclaration - | PropertySignature - | BindingElement - | SetAccessorDeclaration - | GetAccessorDeclaration - | ConstructSignatureDeclaration - | CallSignatureDeclaration - | MethodDeclaration - | MethodSignature - | FunctionDeclaration - | ParameterDeclaration - | TypeParameterDeclaration - | ExpressionWithTypeArguments - | ImportEqualsDeclaration - | TypeAliasDeclaration - | ConstructorDeclaration - | IndexSignatureDeclaration - | PropertyAccessExpression - | JSDocTypedefTag - | JSDocCallbackTag - | JSDocEnumTag; - - export function canProduceDiagnostics(node: Node): node is DeclarationDiagnosticProducing { - return isVariableDeclaration(node) || - isPropertyDeclaration(node) || - isPropertySignature(node) || - isBindingElement(node) || - isSetAccessor(node) || - isGetAccessor(node) || - isConstructSignatureDeclaration(node) || - isCallSignatureDeclaration(node) || - isMethodDeclaration(node) || - isMethodSignature(node) || - isFunctionDeclaration(node) || - isParameter(node) || - isTypeParameterDeclaration(node) || - isExpressionWithTypeArguments(node) || - isImportEqualsDeclaration(node) || - isTypeAliasDeclaration(node) || - isConstructorDeclaration(node) || - isIndexSignatureDeclaration(node) || - isPropertyAccessExpression(node) || - isJSDocTypeAlias(node); + export type DeclarationDiagnosticProducing = ts.VariableDeclaration | ts.PropertyDeclaration | ts.PropertySignature | ts.BindingElement | ts.SetAccessorDeclaration | ts.GetAccessorDeclaration | ts.ConstructSignatureDeclaration | ts.CallSignatureDeclaration | ts.MethodDeclaration | ts.MethodSignature | ts.FunctionDeclaration | ts.ParameterDeclaration | ts.TypeParameterDeclaration | ts.ExpressionWithTypeArguments | ts.ImportEqualsDeclaration | ts.TypeAliasDeclaration | ts.ConstructorDeclaration | ts.IndexSignatureDeclaration | ts.PropertyAccessExpression | ts.JSDocTypedefTag | ts.JSDocCallbackTag | ts.JSDocEnumTag; + export function canProduceDiagnostics(node: ts.Node): node is DeclarationDiagnosticProducing { + return ts.isVariableDeclaration(node) || + ts.isPropertyDeclaration(node) || + ts.isPropertySignature(node) || + ts.isBindingElement(node) || + ts.isSetAccessor(node) || + ts.isGetAccessor(node) || + ts.isConstructSignatureDeclaration(node) || + ts.isCallSignatureDeclaration(node) || + ts.isMethodDeclaration(node) || + ts.isMethodSignature(node) || + ts.isFunctionDeclaration(node) || + ts.isParameter(node) || + ts.isTypeParameterDeclaration(node) || + ts.isExpressionWithTypeArguments(node) || + ts.isImportEqualsDeclaration(node) || + ts.isTypeAliasDeclaration(node) || + ts.isConstructorDeclaration(node) || + ts.isIndexSignatureDeclaration(node) || + ts.isPropertyAccessExpression(node) || + ts.isJSDocTypeAlias(node); } export function createGetSymbolAccessibilityDiagnosticForNodeName(node: DeclarationDiagnosticProducing) { - if (isSetAccessor(node) || isGetAccessor(node)) { + if (ts.isSetAccessor(node) || ts.isGetAccessor(node)) { return getAccessorNameVisibilityError; } - else if (isMethodSignature(node) || isMethodDeclaration(node)) { + else if (ts.isMethodSignature(node) || ts.isMethodDeclaration(node)) { return getMethodNameVisibilityError; } else { return createGetSymbolAccessibilityDiagnosticForNode(node); } - function getAccessorNameVisibilityError(symbolAccessibilityResult: SymbolAccessibilityResult) { + function getAccessorNameVisibilityError(symbolAccessibilityResult: ts.SymbolAccessibilityResult) { const diagnosticMessage = getAccessorNameVisibilityDiagnosticMessage(symbolAccessibilityResult); return diagnosticMessage !== undefined ? { diagnosticMessage, errorNode: node, - typeName: (node as NamedDeclaration).name + typeName: (node as ts.NamedDeclaration).name } : undefined; } - function getAccessorNameVisibilityDiagnosticMessage(symbolAccessibilityResult: SymbolAccessibilityResult) { - if (isStatic(node)) { + function getAccessorNameVisibilityDiagnosticMessage(symbolAccessibilityResult: ts.SymbolAccessibilityResult) { + if (ts.isStatic(node)) { return symbolAccessibilityResult.errorModuleName ? - symbolAccessibilityResult.accessibility === SymbolAccessibility.CannotBeNamed ? - Diagnostics.Public_static_property_0_of_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named : - Diagnostics.Public_static_property_0_of_exported_class_has_or_is_using_name_1_from_private_module_2 : - Diagnostics.Public_static_property_0_of_exported_class_has_or_is_using_private_name_1; + symbolAccessibilityResult.accessibility === ts.SymbolAccessibility.CannotBeNamed ? + ts.Diagnostics.Public_static_property_0_of_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named : + ts.Diagnostics.Public_static_property_0_of_exported_class_has_or_is_using_name_1_from_private_module_2 : + ts.Diagnostics.Public_static_property_0_of_exported_class_has_or_is_using_private_name_1; } - else if (node.parent.kind === SyntaxKind.ClassDeclaration) { + else if (node.parent.kind === ts.SyntaxKind.ClassDeclaration) { return symbolAccessibilityResult.errorModuleName ? - symbolAccessibilityResult.accessibility === SymbolAccessibility.CannotBeNamed ? - Diagnostics.Public_property_0_of_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named : - Diagnostics.Public_property_0_of_exported_class_has_or_is_using_name_1_from_private_module_2 : - Diagnostics.Public_property_0_of_exported_class_has_or_is_using_private_name_1; + symbolAccessibilityResult.accessibility === ts.SymbolAccessibility.CannotBeNamed ? + ts.Diagnostics.Public_property_0_of_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named : + ts.Diagnostics.Public_property_0_of_exported_class_has_or_is_using_name_1_from_private_module_2 : + ts.Diagnostics.Public_property_0_of_exported_class_has_or_is_using_private_name_1; } else { return symbolAccessibilityResult.errorModuleName ? - Diagnostics.Property_0_of_exported_interface_has_or_is_using_name_1_from_private_module_2 : - Diagnostics.Property_0_of_exported_interface_has_or_is_using_private_name_1; + ts.Diagnostics.Property_0_of_exported_interface_has_or_is_using_name_1_from_private_module_2 : + ts.Diagnostics.Property_0_of_exported_interface_has_or_is_using_private_name_1; } } - function getMethodNameVisibilityError(symbolAccessibilityResult: SymbolAccessibilityResult): SymbolAccessibilityDiagnostic | undefined { + function getMethodNameVisibilityError(symbolAccessibilityResult: ts.SymbolAccessibilityResult): SymbolAccessibilityDiagnostic | undefined { const diagnosticMessage = getMethodNameVisibilityDiagnosticMessage(symbolAccessibilityResult); return diagnosticMessage !== undefined ? { diagnosticMessage, errorNode: node, - typeName: (node as NamedDeclaration).name + typeName: (node as ts.NamedDeclaration).name } : undefined; } - function getMethodNameVisibilityDiagnosticMessage(symbolAccessibilityResult: SymbolAccessibilityResult) { - if (isStatic(node)) { + function getMethodNameVisibilityDiagnosticMessage(symbolAccessibilityResult: ts.SymbolAccessibilityResult) { + if (ts.isStatic(node)) { return symbolAccessibilityResult.errorModuleName ? - symbolAccessibilityResult.accessibility === SymbolAccessibility.CannotBeNamed ? - Diagnostics.Public_static_method_0_of_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named : - Diagnostics.Public_static_method_0_of_exported_class_has_or_is_using_name_1_from_private_module_2 : - Diagnostics.Public_static_method_0_of_exported_class_has_or_is_using_private_name_1; + symbolAccessibilityResult.accessibility === ts.SymbolAccessibility.CannotBeNamed ? + ts.Diagnostics.Public_static_method_0_of_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named : + ts.Diagnostics.Public_static_method_0_of_exported_class_has_or_is_using_name_1_from_private_module_2 : + ts.Diagnostics.Public_static_method_0_of_exported_class_has_or_is_using_private_name_1; } - else if (node.parent.kind === SyntaxKind.ClassDeclaration) { + else if (node.parent.kind === ts.SyntaxKind.ClassDeclaration) { return symbolAccessibilityResult.errorModuleName ? - symbolAccessibilityResult.accessibility === SymbolAccessibility.CannotBeNamed ? - Diagnostics.Public_method_0_of_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named : - Diagnostics.Public_method_0_of_exported_class_has_or_is_using_name_1_from_private_module_2 : - Diagnostics.Public_method_0_of_exported_class_has_or_is_using_private_name_1; + symbolAccessibilityResult.accessibility === ts.SymbolAccessibility.CannotBeNamed ? + ts.Diagnostics.Public_method_0_of_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named : + ts.Diagnostics.Public_method_0_of_exported_class_has_or_is_using_name_1_from_private_module_2 : + ts.Diagnostics.Public_method_0_of_exported_class_has_or_is_using_private_name_1; } else { return symbolAccessibilityResult.errorModuleName ? - Diagnostics.Method_0_of_exported_interface_has_or_is_using_name_1_from_private_module_2 : - Diagnostics.Method_0_of_exported_interface_has_or_is_using_private_name_1; + ts.Diagnostics.Method_0_of_exported_interface_has_or_is_using_name_1_from_private_module_2 : + ts.Diagnostics.Method_0_of_exported_interface_has_or_is_using_private_name_1; } } } export function createGetSymbolAccessibilityDiagnosticForNode(node: DeclarationDiagnosticProducing): GetSymbolAccessibilityDiagnostic { - if (isVariableDeclaration(node) || isPropertyDeclaration(node) || isPropertySignature(node) || isPropertyAccessExpression(node) || isBindingElement(node) || isConstructorDeclaration(node)) { + if (ts.isVariableDeclaration(node) || ts.isPropertyDeclaration(node) || ts.isPropertySignature(node) || ts.isPropertyAccessExpression(node) || ts.isBindingElement(node) || ts.isConstructorDeclaration(node)) { return getVariableDeclarationTypeVisibilityError; } - else if (isSetAccessor(node) || isGetAccessor(node)) { + else if (ts.isSetAccessor(node) || ts.isGetAccessor(node)) { return getAccessorDeclarationTypeVisibilityError; } - else if (isConstructSignatureDeclaration(node) || isCallSignatureDeclaration(node) || isMethodDeclaration(node) || isMethodSignature(node) || isFunctionDeclaration(node) || isIndexSignatureDeclaration(node)) { + else if (ts.isConstructSignatureDeclaration(node) || ts.isCallSignatureDeclaration(node) || ts.isMethodDeclaration(node) || ts.isMethodSignature(node) || ts.isFunctionDeclaration(node) || ts.isIndexSignatureDeclaration(node)) { return getReturnTypeVisibilityError; } - else if (isParameter(node)) { - if (isParameterPropertyDeclaration(node, node.parent) && hasSyntacticModifier(node.parent, ModifierFlags.Private)) { + else if (ts.isParameter(node)) { + if (ts.isParameterPropertyDeclaration(node, node.parent) && ts.hasSyntacticModifier(node.parent, ts.ModifierFlags.Private)) { return getVariableDeclarationTypeVisibilityError; } return getParameterDeclarationTypeVisibilityError; } - else if (isTypeParameterDeclaration(node)) { + else if (ts.isTypeParameterDeclaration(node)) { return getTypeParameterConstraintVisibilityError; } - else if (isExpressionWithTypeArguments(node)) { + else if (ts.isExpressionWithTypeArguments(node)) { return getHeritageClauseVisibilityError; } - else if (isImportEqualsDeclaration(node)) { + else if (ts.isImportEqualsDeclaration(node)) { return getImportEntityNameVisibilityError; } - else if (isTypeAliasDeclaration(node) || isJSDocTypeAlias(node)) { + else if (ts.isTypeAliasDeclaration(node) || ts.isJSDocTypeAlias(node)) { return getTypeAliasDeclarationVisibilityError; } else { - return Debug.assertNever(node, `Attempted to set a declaration diagnostic context for unhandled node kind: ${(ts as any).SyntaxKind[(node as any).kind]}`); + return ts.Debug.assertNever(node, `Attempted to set a declaration diagnostic context for unhandled node kind: ${(ts as any).SyntaxKind[(node as any).kind]}`); } - function getVariableDeclarationTypeVisibilityDiagnosticMessage(symbolAccessibilityResult: SymbolAccessibilityResult) { - if (node.kind === SyntaxKind.VariableDeclaration || node.kind === SyntaxKind.BindingElement) { + function getVariableDeclarationTypeVisibilityDiagnosticMessage(symbolAccessibilityResult: ts.SymbolAccessibilityResult) { + if (node.kind === ts.SyntaxKind.VariableDeclaration || node.kind === ts.SyntaxKind.BindingElement) { return symbolAccessibilityResult.errorModuleName ? - symbolAccessibilityResult.accessibility === SymbolAccessibility.CannotBeNamed ? - Diagnostics.Exported_variable_0_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named : - Diagnostics.Exported_variable_0_has_or_is_using_name_1_from_private_module_2 : - Diagnostics.Exported_variable_0_has_or_is_using_private_name_1; + symbolAccessibilityResult.accessibility === ts.SymbolAccessibility.CannotBeNamed ? + ts.Diagnostics.Exported_variable_0_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named : + ts.Diagnostics.Exported_variable_0_has_or_is_using_name_1_from_private_module_2 : + ts.Diagnostics.Exported_variable_0_has_or_is_using_private_name_1; } // This check is to ensure we don't report error on constructor parameter property as that error would be reported during parameter emit // The only exception here is if the constructor was marked as private. we are not emitting the constructor parameters at all. - else if (node.kind === SyntaxKind.PropertyDeclaration || node.kind === SyntaxKind.PropertyAccessExpression || node.kind === SyntaxKind.PropertySignature || - (node.kind === SyntaxKind.Parameter && hasSyntacticModifier(node.parent, ModifierFlags.Private))) { + else if (node.kind === ts.SyntaxKind.PropertyDeclaration || node.kind === ts.SyntaxKind.PropertyAccessExpression || node.kind === ts.SyntaxKind.PropertySignature || + (node.kind === ts.SyntaxKind.Parameter && ts.hasSyntacticModifier(node.parent, ts.ModifierFlags.Private))) { // TODO(jfreeman): Deal with computed properties in error reporting. - if (isStatic(node)) { + if (ts.isStatic(node)) { return symbolAccessibilityResult.errorModuleName ? - symbolAccessibilityResult.accessibility === SymbolAccessibility.CannotBeNamed ? - Diagnostics.Public_static_property_0_of_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named : - Diagnostics.Public_static_property_0_of_exported_class_has_or_is_using_name_1_from_private_module_2 : - Diagnostics.Public_static_property_0_of_exported_class_has_or_is_using_private_name_1; + symbolAccessibilityResult.accessibility === ts.SymbolAccessibility.CannotBeNamed ? + ts.Diagnostics.Public_static_property_0_of_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named : + ts.Diagnostics.Public_static_property_0_of_exported_class_has_or_is_using_name_1_from_private_module_2 : + ts.Diagnostics.Public_static_property_0_of_exported_class_has_or_is_using_private_name_1; } - else if (node.parent.kind === SyntaxKind.ClassDeclaration || node.kind === SyntaxKind.Parameter) { + else if (node.parent.kind === ts.SyntaxKind.ClassDeclaration || node.kind === ts.SyntaxKind.Parameter) { return symbolAccessibilityResult.errorModuleName ? - symbolAccessibilityResult.accessibility === SymbolAccessibility.CannotBeNamed ? - Diagnostics.Public_property_0_of_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named : - Diagnostics.Public_property_0_of_exported_class_has_or_is_using_name_1_from_private_module_2 : - Diagnostics.Public_property_0_of_exported_class_has_or_is_using_private_name_1; + symbolAccessibilityResult.accessibility === ts.SymbolAccessibility.CannotBeNamed ? + ts.Diagnostics.Public_property_0_of_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named : + ts.Diagnostics.Public_property_0_of_exported_class_has_or_is_using_name_1_from_private_module_2 : + ts.Diagnostics.Public_property_0_of_exported_class_has_or_is_using_private_name_1; } else { // Interfaces cannot have types that cannot be named return symbolAccessibilityResult.errorModuleName ? - Diagnostics.Property_0_of_exported_interface_has_or_is_using_name_1_from_private_module_2 : - Diagnostics.Property_0_of_exported_interface_has_or_is_using_private_name_1; + ts.Diagnostics.Property_0_of_exported_interface_has_or_is_using_name_1_from_private_module_2 : + ts.Diagnostics.Property_0_of_exported_interface_has_or_is_using_private_name_1; } } } - function getVariableDeclarationTypeVisibilityError(symbolAccessibilityResult: SymbolAccessibilityResult): SymbolAccessibilityDiagnostic | undefined { + function getVariableDeclarationTypeVisibilityError(symbolAccessibilityResult: ts.SymbolAccessibilityResult): SymbolAccessibilityDiagnostic | undefined { const diagnosticMessage = getVariableDeclarationTypeVisibilityDiagnosticMessage(symbolAccessibilityResult); return diagnosticMessage !== undefined ? { diagnosticMessage, errorNode: node, - typeName: (node as NamedDeclaration).name + typeName: (node as ts.NamedDeclaration).name } : undefined; } - function getAccessorDeclarationTypeVisibilityError(symbolAccessibilityResult: SymbolAccessibilityResult): SymbolAccessibilityDiagnostic { - let diagnosticMessage: DiagnosticMessage; - if (node.kind === SyntaxKind.SetAccessor) { + function getAccessorDeclarationTypeVisibilityError(symbolAccessibilityResult: ts.SymbolAccessibilityResult): SymbolAccessibilityDiagnostic { + let diagnosticMessage: ts.DiagnosticMessage; + if (node.kind === ts.SyntaxKind.SetAccessor) { // Getters can infer the return type from the returned expression, but setters cannot, so the // "_from_external_module_1_but_cannot_be_named" case cannot occur. - if (isStatic(node)) { + if (ts.isStatic(node)) { diagnosticMessage = symbolAccessibilityResult.errorModuleName ? - Diagnostics.Parameter_type_of_public_static_setter_0_from_exported_class_has_or_is_using_name_1_from_private_module_2 : - Diagnostics.Parameter_type_of_public_static_setter_0_from_exported_class_has_or_is_using_private_name_1; + ts.Diagnostics.Parameter_type_of_public_static_setter_0_from_exported_class_has_or_is_using_name_1_from_private_module_2 : + ts.Diagnostics.Parameter_type_of_public_static_setter_0_from_exported_class_has_or_is_using_private_name_1; } else { diagnosticMessage = symbolAccessibilityResult.errorModuleName ? - Diagnostics.Parameter_type_of_public_setter_0_from_exported_class_has_or_is_using_name_1_from_private_module_2 : - Diagnostics.Parameter_type_of_public_setter_0_from_exported_class_has_or_is_using_private_name_1; + ts.Diagnostics.Parameter_type_of_public_setter_0_from_exported_class_has_or_is_using_name_1_from_private_module_2 : + ts.Diagnostics.Parameter_type_of_public_setter_0_from_exported_class_has_or_is_using_private_name_1; } } else { - if (isStatic(node)) { + if (ts.isStatic(node)) { diagnosticMessage = symbolAccessibilityResult.errorModuleName ? - symbolAccessibilityResult.accessibility === SymbolAccessibility.CannotBeNamed ? - Diagnostics.Return_type_of_public_static_getter_0_from_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named : - Diagnostics.Return_type_of_public_static_getter_0_from_exported_class_has_or_is_using_name_1_from_private_module_2 : - Diagnostics.Return_type_of_public_static_getter_0_from_exported_class_has_or_is_using_private_name_1; + symbolAccessibilityResult.accessibility === ts.SymbolAccessibility.CannotBeNamed ? + ts.Diagnostics.Return_type_of_public_static_getter_0_from_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named : + ts.Diagnostics.Return_type_of_public_static_getter_0_from_exported_class_has_or_is_using_name_1_from_private_module_2 : + ts.Diagnostics.Return_type_of_public_static_getter_0_from_exported_class_has_or_is_using_private_name_1; } else { diagnosticMessage = symbolAccessibilityResult.errorModuleName ? - symbolAccessibilityResult.accessibility === SymbolAccessibility.CannotBeNamed ? - Diagnostics.Return_type_of_public_getter_0_from_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named : - Diagnostics.Return_type_of_public_getter_0_from_exported_class_has_or_is_using_name_1_from_private_module_2 : - Diagnostics.Return_type_of_public_getter_0_from_exported_class_has_or_is_using_private_name_1; + symbolAccessibilityResult.accessibility === ts.SymbolAccessibility.CannotBeNamed ? + ts.Diagnostics.Return_type_of_public_getter_0_from_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named : + ts.Diagnostics.Return_type_of_public_getter_0_from_exported_class_has_or_is_using_name_1_from_private_module_2 : + ts.Diagnostics.Return_type_of_public_getter_0_from_exported_class_has_or_is_using_private_name_1; } } return { diagnosticMessage, - errorNode: (node as NamedDeclaration).name!, - typeName: (node as NamedDeclaration).name + errorNode: (node as ts.NamedDeclaration).name!, + typeName: (node as ts.NamedDeclaration).name }; } - function getReturnTypeVisibilityError(symbolAccessibilityResult: SymbolAccessibilityResult): SymbolAccessibilityDiagnostic { - let diagnosticMessage: DiagnosticMessage; + function getReturnTypeVisibilityError(symbolAccessibilityResult: ts.SymbolAccessibilityResult): SymbolAccessibilityDiagnostic { + let diagnosticMessage: ts.DiagnosticMessage; switch (node.kind) { - case SyntaxKind.ConstructSignature: + case ts.SyntaxKind.ConstructSignature: // Interfaces cannot have return types that cannot be named diagnosticMessage = symbolAccessibilityResult.errorModuleName ? - Diagnostics.Return_type_of_constructor_signature_from_exported_interface_has_or_is_using_name_0_from_private_module_1 : - Diagnostics.Return_type_of_constructor_signature_from_exported_interface_has_or_is_using_private_name_0; + ts.Diagnostics.Return_type_of_constructor_signature_from_exported_interface_has_or_is_using_name_0_from_private_module_1 : + ts.Diagnostics.Return_type_of_constructor_signature_from_exported_interface_has_or_is_using_private_name_0; break; - case SyntaxKind.CallSignature: + case ts.SyntaxKind.CallSignature: // Interfaces cannot have return types that cannot be named diagnosticMessage = symbolAccessibilityResult.errorModuleName ? - Diagnostics.Return_type_of_call_signature_from_exported_interface_has_or_is_using_name_0_from_private_module_1 : - Diagnostics.Return_type_of_call_signature_from_exported_interface_has_or_is_using_private_name_0; + ts.Diagnostics.Return_type_of_call_signature_from_exported_interface_has_or_is_using_name_0_from_private_module_1 : + ts.Diagnostics.Return_type_of_call_signature_from_exported_interface_has_or_is_using_private_name_0; break; - case SyntaxKind.IndexSignature: + case ts.SyntaxKind.IndexSignature: // Interfaces cannot have return types that cannot be named diagnosticMessage = symbolAccessibilityResult.errorModuleName ? - Diagnostics.Return_type_of_index_signature_from_exported_interface_has_or_is_using_name_0_from_private_module_1 : - Diagnostics.Return_type_of_index_signature_from_exported_interface_has_or_is_using_private_name_0; + ts.Diagnostics.Return_type_of_index_signature_from_exported_interface_has_or_is_using_name_0_from_private_module_1 : + ts.Diagnostics.Return_type_of_index_signature_from_exported_interface_has_or_is_using_private_name_0; break; - case SyntaxKind.MethodDeclaration: - case SyntaxKind.MethodSignature: - if (isStatic(node)) { + case ts.SyntaxKind.MethodDeclaration: + case ts.SyntaxKind.MethodSignature: + if (ts.isStatic(node)) { diagnosticMessage = symbolAccessibilityResult.errorModuleName ? - symbolAccessibilityResult.accessibility === SymbolAccessibility.CannotBeNamed ? - Diagnostics.Return_type_of_public_static_method_from_exported_class_has_or_is_using_name_0_from_external_module_1_but_cannot_be_named : - Diagnostics.Return_type_of_public_static_method_from_exported_class_has_or_is_using_name_0_from_private_module_1 : - Diagnostics.Return_type_of_public_static_method_from_exported_class_has_or_is_using_private_name_0; + symbolAccessibilityResult.accessibility === ts.SymbolAccessibility.CannotBeNamed ? + ts.Diagnostics.Return_type_of_public_static_method_from_exported_class_has_or_is_using_name_0_from_external_module_1_but_cannot_be_named : + ts.Diagnostics.Return_type_of_public_static_method_from_exported_class_has_or_is_using_name_0_from_private_module_1 : + ts.Diagnostics.Return_type_of_public_static_method_from_exported_class_has_or_is_using_private_name_0; } - else if (node.parent.kind === SyntaxKind.ClassDeclaration) { + else if (node.parent.kind === ts.SyntaxKind.ClassDeclaration) { diagnosticMessage = symbolAccessibilityResult.errorModuleName ? - symbolAccessibilityResult.accessibility === SymbolAccessibility.CannotBeNamed ? - Diagnostics.Return_type_of_public_method_from_exported_class_has_or_is_using_name_0_from_external_module_1_but_cannot_be_named : - Diagnostics.Return_type_of_public_method_from_exported_class_has_or_is_using_name_0_from_private_module_1 : - Diagnostics.Return_type_of_public_method_from_exported_class_has_or_is_using_private_name_0; + symbolAccessibilityResult.accessibility === ts.SymbolAccessibility.CannotBeNamed ? + ts.Diagnostics.Return_type_of_public_method_from_exported_class_has_or_is_using_name_0_from_external_module_1_but_cannot_be_named : + ts.Diagnostics.Return_type_of_public_method_from_exported_class_has_or_is_using_name_0_from_private_module_1 : + ts.Diagnostics.Return_type_of_public_method_from_exported_class_has_or_is_using_private_name_0; } else { // Interfaces cannot have return types that cannot be named diagnosticMessage = symbolAccessibilityResult.errorModuleName ? - Diagnostics.Return_type_of_method_from_exported_interface_has_or_is_using_name_0_from_private_module_1 : - Diagnostics.Return_type_of_method_from_exported_interface_has_or_is_using_private_name_0; + ts.Diagnostics.Return_type_of_method_from_exported_interface_has_or_is_using_name_0_from_private_module_1 : + ts.Diagnostics.Return_type_of_method_from_exported_interface_has_or_is_using_private_name_0; } break; - case SyntaxKind.FunctionDeclaration: + case ts.SyntaxKind.FunctionDeclaration: diagnosticMessage = symbolAccessibilityResult.errorModuleName ? - symbolAccessibilityResult.accessibility === SymbolAccessibility.CannotBeNamed ? - Diagnostics.Return_type_of_exported_function_has_or_is_using_name_0_from_external_module_1_but_cannot_be_named : - Diagnostics.Return_type_of_exported_function_has_or_is_using_name_0_from_private_module_1 : - Diagnostics.Return_type_of_exported_function_has_or_is_using_private_name_0; + symbolAccessibilityResult.accessibility === ts.SymbolAccessibility.CannotBeNamed ? + ts.Diagnostics.Return_type_of_exported_function_has_or_is_using_name_0_from_external_module_1_but_cannot_be_named : + ts.Diagnostics.Return_type_of_exported_function_has_or_is_using_name_0_from_private_module_1 : + ts.Diagnostics.Return_type_of_exported_function_has_or_is_using_private_name_0; break; default: - return Debug.fail("This is unknown kind for signature: " + node.kind); + return ts.Debug.fail("This is unknown kind for signature: " + node.kind); } return { diagnosticMessage, - errorNode: (node as NamedDeclaration).name || node + errorNode: (node as ts.NamedDeclaration).name || node }; } - function getParameterDeclarationTypeVisibilityError(symbolAccessibilityResult: SymbolAccessibilityResult): SymbolAccessibilityDiagnostic | undefined { - const diagnosticMessage: DiagnosticMessage = getParameterDeclarationTypeVisibilityDiagnosticMessage(symbolAccessibilityResult); + function getParameterDeclarationTypeVisibilityError(symbolAccessibilityResult: ts.SymbolAccessibilityResult): SymbolAccessibilityDiagnostic | undefined { + const diagnosticMessage: ts.DiagnosticMessage = getParameterDeclarationTypeVisibilityDiagnosticMessage(symbolAccessibilityResult); return diagnosticMessage !== undefined ? { diagnosticMessage, errorNode: node, - typeName: (node as NamedDeclaration).name + typeName: (node as ts.NamedDeclaration).name } : undefined; } - function getParameterDeclarationTypeVisibilityDiagnosticMessage(symbolAccessibilityResult: SymbolAccessibilityResult): DiagnosticMessage { + function getParameterDeclarationTypeVisibilityDiagnosticMessage(symbolAccessibilityResult: ts.SymbolAccessibilityResult): ts.DiagnosticMessage { switch (node.parent.kind) { - case SyntaxKind.Constructor: + case ts.SyntaxKind.Constructor: return symbolAccessibilityResult.errorModuleName ? - symbolAccessibilityResult.accessibility === SymbolAccessibility.CannotBeNamed ? - Diagnostics.Parameter_0_of_constructor_from_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named : - Diagnostics.Parameter_0_of_constructor_from_exported_class_has_or_is_using_name_1_from_private_module_2 : - Diagnostics.Parameter_0_of_constructor_from_exported_class_has_or_is_using_private_name_1; - - case SyntaxKind.ConstructSignature: - case SyntaxKind.ConstructorType: + symbolAccessibilityResult.accessibility === ts.SymbolAccessibility.CannotBeNamed ? + ts.Diagnostics.Parameter_0_of_constructor_from_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named : + ts.Diagnostics.Parameter_0_of_constructor_from_exported_class_has_or_is_using_name_1_from_private_module_2 : + ts.Diagnostics.Parameter_0_of_constructor_from_exported_class_has_or_is_using_private_name_1; + case ts.SyntaxKind.ConstructSignature: + case ts.SyntaxKind.ConstructorType: // Interfaces cannot have parameter types that cannot be named return symbolAccessibilityResult.errorModuleName ? - Diagnostics.Parameter_0_of_constructor_signature_from_exported_interface_has_or_is_using_name_1_from_private_module_2 : - Diagnostics.Parameter_0_of_constructor_signature_from_exported_interface_has_or_is_using_private_name_1; - - case SyntaxKind.CallSignature: + ts.Diagnostics.Parameter_0_of_constructor_signature_from_exported_interface_has_or_is_using_name_1_from_private_module_2 : + ts.Diagnostics.Parameter_0_of_constructor_signature_from_exported_interface_has_or_is_using_private_name_1; + case ts.SyntaxKind.CallSignature: // Interfaces cannot have parameter types that cannot be named return symbolAccessibilityResult.errorModuleName ? - Diagnostics.Parameter_0_of_call_signature_from_exported_interface_has_or_is_using_name_1_from_private_module_2 : - Diagnostics.Parameter_0_of_call_signature_from_exported_interface_has_or_is_using_private_name_1; - - case SyntaxKind.IndexSignature: + ts.Diagnostics.Parameter_0_of_call_signature_from_exported_interface_has_or_is_using_name_1_from_private_module_2 : + ts.Diagnostics.Parameter_0_of_call_signature_from_exported_interface_has_or_is_using_private_name_1; + case ts.SyntaxKind.IndexSignature: // Interfaces cannot have parameter types that cannot be named return symbolAccessibilityResult.errorModuleName ? - Diagnostics.Parameter_0_of_index_signature_from_exported_interface_has_or_is_using_name_1_from_private_module_2 : - Diagnostics.Parameter_0_of_index_signature_from_exported_interface_has_or_is_using_private_name_1; - - case SyntaxKind.MethodDeclaration: - case SyntaxKind.MethodSignature: - if (isStatic(node.parent)) { + ts.Diagnostics.Parameter_0_of_index_signature_from_exported_interface_has_or_is_using_name_1_from_private_module_2 : + ts.Diagnostics.Parameter_0_of_index_signature_from_exported_interface_has_or_is_using_private_name_1; + case ts.SyntaxKind.MethodDeclaration: + case ts.SyntaxKind.MethodSignature: + if (ts.isStatic(node.parent)) { return symbolAccessibilityResult.errorModuleName ? - symbolAccessibilityResult.accessibility === SymbolAccessibility.CannotBeNamed ? - Diagnostics.Parameter_0_of_public_static_method_from_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named : - Diagnostics.Parameter_0_of_public_static_method_from_exported_class_has_or_is_using_name_1_from_private_module_2 : - Diagnostics.Parameter_0_of_public_static_method_from_exported_class_has_or_is_using_private_name_1; + symbolAccessibilityResult.accessibility === ts.SymbolAccessibility.CannotBeNamed ? + ts.Diagnostics.Parameter_0_of_public_static_method_from_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named : + ts.Diagnostics.Parameter_0_of_public_static_method_from_exported_class_has_or_is_using_name_1_from_private_module_2 : + ts.Diagnostics.Parameter_0_of_public_static_method_from_exported_class_has_or_is_using_private_name_1; } - else if (node.parent.parent.kind === SyntaxKind.ClassDeclaration) { + else if (node.parent.parent.kind === ts.SyntaxKind.ClassDeclaration) { return symbolAccessibilityResult.errorModuleName ? - symbolAccessibilityResult.accessibility === SymbolAccessibility.CannotBeNamed ? - Diagnostics.Parameter_0_of_public_method_from_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named : - Diagnostics.Parameter_0_of_public_method_from_exported_class_has_or_is_using_name_1_from_private_module_2 : - Diagnostics.Parameter_0_of_public_method_from_exported_class_has_or_is_using_private_name_1; + symbolAccessibilityResult.accessibility === ts.SymbolAccessibility.CannotBeNamed ? + ts.Diagnostics.Parameter_0_of_public_method_from_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named : + ts.Diagnostics.Parameter_0_of_public_method_from_exported_class_has_or_is_using_name_1_from_private_module_2 : + ts.Diagnostics.Parameter_0_of_public_method_from_exported_class_has_or_is_using_private_name_1; } else { // Interfaces cannot have parameter types that cannot be named return symbolAccessibilityResult.errorModuleName ? - Diagnostics.Parameter_0_of_method_from_exported_interface_has_or_is_using_name_1_from_private_module_2 : - Diagnostics.Parameter_0_of_method_from_exported_interface_has_or_is_using_private_name_1; + ts.Diagnostics.Parameter_0_of_method_from_exported_interface_has_or_is_using_name_1_from_private_module_2 : + ts.Diagnostics.Parameter_0_of_method_from_exported_interface_has_or_is_using_private_name_1; } - case SyntaxKind.FunctionDeclaration: - case SyntaxKind.FunctionType: + case ts.SyntaxKind.FunctionDeclaration: + case ts.SyntaxKind.FunctionType: return symbolAccessibilityResult.errorModuleName ? - symbolAccessibilityResult.accessibility === SymbolAccessibility.CannotBeNamed ? - Diagnostics.Parameter_0_of_exported_function_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named : - Diagnostics.Parameter_0_of_exported_function_has_or_is_using_name_1_from_private_module_2 : - Diagnostics.Parameter_0_of_exported_function_has_or_is_using_private_name_1; - case SyntaxKind.SetAccessor: - case SyntaxKind.GetAccessor: + symbolAccessibilityResult.accessibility === ts.SymbolAccessibility.CannotBeNamed ? + ts.Diagnostics.Parameter_0_of_exported_function_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named : + ts.Diagnostics.Parameter_0_of_exported_function_has_or_is_using_name_1_from_private_module_2 : + ts.Diagnostics.Parameter_0_of_exported_function_has_or_is_using_private_name_1; + case ts.SyntaxKind.SetAccessor: + case ts.SyntaxKind.GetAccessor: return symbolAccessibilityResult.errorModuleName ? - symbolAccessibilityResult.accessibility === SymbolAccessibility.CannotBeNamed ? - Diagnostics.Parameter_0_of_accessor_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named : - Diagnostics.Parameter_0_of_accessor_has_or_is_using_name_1_from_private_module_2 : - Diagnostics.Parameter_0_of_accessor_has_or_is_using_private_name_1; + symbolAccessibilityResult.accessibility === ts.SymbolAccessibility.CannotBeNamed ? + ts.Diagnostics.Parameter_0_of_accessor_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named : + ts.Diagnostics.Parameter_0_of_accessor_has_or_is_using_name_1_from_private_module_2 : + ts.Diagnostics.Parameter_0_of_accessor_has_or_is_using_private_name_1; default: - return Debug.fail(`Unknown parent for parameter: ${(ts as any).SyntaxKind[node.parent.kind]}`); + return ts.Debug.fail(`Unknown parent for parameter: ${(ts as any).SyntaxKind[node.parent.kind]}`); } } function getTypeParameterConstraintVisibilityError(): SymbolAccessibilityDiagnostic { // Type parameter constraints are named by user so we should always be able to name it - let diagnosticMessage: DiagnosticMessage; + let diagnosticMessage: ts.DiagnosticMessage; switch (node.parent.kind) { - case SyntaxKind.ClassDeclaration: - diagnosticMessage = Diagnostics.Type_parameter_0_of_exported_class_has_or_is_using_private_name_1; + case ts.SyntaxKind.ClassDeclaration: + diagnosticMessage = ts.Diagnostics.Type_parameter_0_of_exported_class_has_or_is_using_private_name_1; break; - case SyntaxKind.InterfaceDeclaration: - diagnosticMessage = Diagnostics.Type_parameter_0_of_exported_interface_has_or_is_using_private_name_1; + case ts.SyntaxKind.InterfaceDeclaration: + diagnosticMessage = ts.Diagnostics.Type_parameter_0_of_exported_interface_has_or_is_using_private_name_1; break; - case SyntaxKind.MappedType: - diagnosticMessage = Diagnostics.Type_parameter_0_of_exported_mapped_object_type_is_using_private_name_1; + case ts.SyntaxKind.MappedType: + diagnosticMessage = ts.Diagnostics.Type_parameter_0_of_exported_mapped_object_type_is_using_private_name_1; break; - case SyntaxKind.ConstructorType: - case SyntaxKind.ConstructSignature: - diagnosticMessage = Diagnostics.Type_parameter_0_of_constructor_signature_from_exported_interface_has_or_is_using_private_name_1; + case ts.SyntaxKind.ConstructorType: + case ts.SyntaxKind.ConstructSignature: + diagnosticMessage = ts.Diagnostics.Type_parameter_0_of_constructor_signature_from_exported_interface_has_or_is_using_private_name_1; break; - case SyntaxKind.CallSignature: - diagnosticMessage = Diagnostics.Type_parameter_0_of_call_signature_from_exported_interface_has_or_is_using_private_name_1; + case ts.SyntaxKind.CallSignature: + diagnosticMessage = ts.Diagnostics.Type_parameter_0_of_call_signature_from_exported_interface_has_or_is_using_private_name_1; break; - case SyntaxKind.MethodDeclaration: - case SyntaxKind.MethodSignature: - if (isStatic(node.parent)) { - diagnosticMessage = Diagnostics.Type_parameter_0_of_public_static_method_from_exported_class_has_or_is_using_private_name_1; + case ts.SyntaxKind.MethodDeclaration: + case ts.SyntaxKind.MethodSignature: + if (ts.isStatic(node.parent)) { + diagnosticMessage = ts.Diagnostics.Type_parameter_0_of_public_static_method_from_exported_class_has_or_is_using_private_name_1; } - else if (node.parent.parent.kind === SyntaxKind.ClassDeclaration) { - diagnosticMessage = Diagnostics.Type_parameter_0_of_public_method_from_exported_class_has_or_is_using_private_name_1; + else if (node.parent.parent.kind === ts.SyntaxKind.ClassDeclaration) { + diagnosticMessage = ts.Diagnostics.Type_parameter_0_of_public_method_from_exported_class_has_or_is_using_private_name_1; } else { - diagnosticMessage = Diagnostics.Type_parameter_0_of_method_from_exported_interface_has_or_is_using_private_name_1; + diagnosticMessage = ts.Diagnostics.Type_parameter_0_of_method_from_exported_interface_has_or_is_using_private_name_1; } break; - case SyntaxKind.FunctionType: - case SyntaxKind.FunctionDeclaration: - diagnosticMessage = Diagnostics.Type_parameter_0_of_exported_function_has_or_is_using_private_name_1; + case ts.SyntaxKind.FunctionType: + case ts.SyntaxKind.FunctionDeclaration: + diagnosticMessage = ts.Diagnostics.Type_parameter_0_of_exported_function_has_or_is_using_private_name_1; break; - case SyntaxKind.TypeAliasDeclaration: - diagnosticMessage = Diagnostics.Type_parameter_0_of_exported_type_alias_has_or_is_using_private_name_1; + case ts.SyntaxKind.TypeAliasDeclaration: + diagnosticMessage = ts.Diagnostics.Type_parameter_0_of_exported_type_alias_has_or_is_using_private_name_1; break; default: - return Debug.fail("This is unknown parent for type parameter: " + node.parent.kind); + return ts.Debug.fail("This is unknown parent for type parameter: " + node.parent.kind); } return { diagnosticMessage, errorNode: node, - typeName: (node as NamedDeclaration).name + typeName: (node as ts.NamedDeclaration).name }; } function getHeritageClauseVisibilityError(): SymbolAccessibilityDiagnostic { - let diagnosticMessage: DiagnosticMessage; + let diagnosticMessage: ts.DiagnosticMessage; // Heritage clause is written by user so it can always be named - if (isClassDeclaration(node.parent.parent)) { + if (ts.isClassDeclaration(node.parent.parent)) { // Class or Interface implemented/extended is inaccessible - diagnosticMessage = isHeritageClause(node.parent) && node.parent.token === SyntaxKind.ImplementsKeyword ? - Diagnostics.Implements_clause_of_exported_class_0_has_or_is_using_private_name_1 : - node.parent.parent.name ? Diagnostics.extends_clause_of_exported_class_0_has_or_is_using_private_name_1 : - Diagnostics.extends_clause_of_exported_class_has_or_is_using_private_name_0; + diagnosticMessage = ts.isHeritageClause(node.parent) && node.parent.token === ts.SyntaxKind.ImplementsKeyword ? + ts.Diagnostics.Implements_clause_of_exported_class_0_has_or_is_using_private_name_1 : + node.parent.parent.name ? ts.Diagnostics.extends_clause_of_exported_class_0_has_or_is_using_private_name_1 : + ts.Diagnostics.extends_clause_of_exported_class_has_or_is_using_private_name_0; } else { // interface is inaccessible - diagnosticMessage = Diagnostics.extends_clause_of_exported_interface_0_has_or_is_using_private_name_1; + diagnosticMessage = ts.Diagnostics.extends_clause_of_exported_interface_0_has_or_is_using_private_name_1; } return { diagnosticMessage, errorNode: node, - typeName: getNameOfDeclaration(node.parent.parent as Declaration) + typeName: ts.getNameOfDeclaration(node.parent.parent as ts.Declaration) }; } function getImportEntityNameVisibilityError(): SymbolAccessibilityDiagnostic { return { - diagnosticMessage: Diagnostics.Import_declaration_0_is_using_private_name_1, + diagnosticMessage: ts.Diagnostics.Import_declaration_0_is_using_private_name_1, errorNode: node, - typeName: (node as NamedDeclaration).name + typeName: (node as ts.NamedDeclaration).name }; } - function getTypeAliasDeclarationVisibilityError(symbolAccessibilityResult: SymbolAccessibilityResult): SymbolAccessibilityDiagnostic { + function getTypeAliasDeclarationVisibilityError(symbolAccessibilityResult: ts.SymbolAccessibilityResult): SymbolAccessibilityDiagnostic { return { diagnosticMessage: symbolAccessibilityResult.errorModuleName - ? Diagnostics.Exported_type_alias_0_has_or_is_using_private_name_1_from_module_2 - : Diagnostics.Exported_type_alias_0_has_or_is_using_private_name_1, - errorNode: isJSDocTypeAlias(node) ? Debug.checkDefined(node.typeExpression) : (node as TypeAliasDeclaration).type, - typeName: isJSDocTypeAlias(node) ? getNameOfDeclaration(node) : (node as TypeAliasDeclaration).name, + ? ts.Diagnostics.Exported_type_alias_0_has_or_is_using_private_name_1_from_module_2 + : ts.Diagnostics.Exported_type_alias_0_has_or_is_using_private_name_1, + errorNode: ts.isJSDocTypeAlias(node) ? ts.Debug.checkDefined(node.typeExpression) : (node as ts.TypeAliasDeclaration).type, + typeName: ts.isJSDocTypeAlias(node) ? ts.getNameOfDeclaration(node) : (node as ts.TypeAliasDeclaration).name, }; } } diff --git a/src/compiler/transformers/destructuring.ts b/src/compiler/transformers/destructuring.ts index 64900c56a887a..dfeab55e84d16 100644 --- a/src/compiler/transformers/destructuring.ts +++ b/src/compiler/transformers/destructuring.ts @@ -1,22 +1,22 @@ /*@internal*/ namespace ts { interface FlattenContext { - context: TransformationContext; + context: ts.TransformationContext; level: FlattenLevel; downlevelIteration: boolean; hoistTempVariables: boolean; hasTransformedPriorElement?: boolean; // indicates whether we've transformed a prior declaration - emitExpression: (value: Expression) => void; - emitBindingOrAssignment: (target: BindingOrAssignmentElementTarget, value: Expression, location: TextRange, original: Node | undefined) => void; - createArrayBindingOrAssignmentPattern: (elements: BindingOrAssignmentElement[]) => ArrayBindingOrAssignmentPattern; - createObjectBindingOrAssignmentPattern: (elements: BindingOrAssignmentElement[]) => ObjectBindingOrAssignmentPattern; - createArrayBindingOrAssignmentElement: (node: Identifier) => BindingOrAssignmentElement; - visitor?: (node: Node) => VisitResult; + emitExpression: (value: ts.Expression) => void; + emitBindingOrAssignment: (target: ts.BindingOrAssignmentElementTarget, value: ts.Expression, location: ts.TextRange, original: ts.Node | undefined) => void; + createArrayBindingOrAssignmentPattern: (elements: ts.BindingOrAssignmentElement[]) => ts.ArrayBindingOrAssignmentPattern; + createObjectBindingOrAssignmentPattern: (elements: ts.BindingOrAssignmentElement[]) => ts.ObjectBindingOrAssignmentPattern; + createArrayBindingOrAssignmentElement: (node: ts.Identifier) => ts.BindingOrAssignmentElement; + visitor?: (node: ts.Node) => ts.VisitResult; } export const enum FlattenLevel { All, - ObjectRest, + ObjectRest } /** @@ -30,29 +30,23 @@ namespace ts { * the destructuring assignment is needed as part of a larger expression. * @param createAssignmentCallback An optional callback used to create the assignment expression. */ - export function flattenDestructuringAssignment( - node: VariableDeclaration | DestructuringAssignment, - visitor: ((node: Node) => VisitResult) | undefined, - context: TransformationContext, - level: FlattenLevel, - needsValue?: boolean, - createAssignmentCallback?: (name: Identifier, value: Expression, location?: TextRange) => Expression): Expression { - let location: TextRange = node; - let value: Expression | undefined; - if (isDestructuringAssignment(node)) { + export function flattenDestructuringAssignment(node: ts.VariableDeclaration | ts.DestructuringAssignment, visitor: ((node: ts.Node) => ts.VisitResult) | undefined, context: ts.TransformationContext, level: FlattenLevel, needsValue?: boolean, createAssignmentCallback?: (name: ts.Identifier, value: ts.Expression, location?: ts.TextRange) => ts.Expression): ts.Expression { + let location: ts.TextRange = node; + let value: ts.Expression | undefined; + if (ts.isDestructuringAssignment(node)) { value = node.right; - while (isEmptyArrayLiteral(node.left) || isEmptyObjectLiteral(node.left)) { - if (isDestructuringAssignment(value)) { + while (ts.isEmptyArrayLiteral(node.left) || ts.isEmptyObjectLiteral(node.left)) { + if (ts.isDestructuringAssignment(value)) { location = node = value; value = node.right; } else { - return visitNode(value, visitor, isExpression); + return ts.visitNode(value, visitor, ts.isExpression); } } } - let expressions: Expression[] | undefined; + let expressions: ts.Expression[] | undefined; const flattenContext: FlattenContext = { context, level, @@ -67,9 +61,8 @@ namespace ts { }; if (value) { - value = visitNode(value, visitor, isExpression); - - if (isIdentifier(value) && bindingOrAssignmentElementAssignsToName(node, value.escapedText) || + value = ts.visitNode(value, visitor, ts.isExpression); + if (ts.isIdentifier(value) && bindingOrAssignmentElementAssignsToName(node, value.escapedText) || bindingOrAssignmentElementContainsNonLiteralComputedName(node)) { // If the right-hand value of the assignment is also an assignment target then // we need to cache the right-hand value. @@ -84,7 +77,7 @@ namespace ts { // expression. value = ensureIdentifier(flattenContext, value, /*reuseIdentifierExpressions*/ true, location); } - else if (nodeIsSynthesized(node)) { + else if (ts.nodeIsSynthesized(node)) { // Generally, the source map location for a destructuring assignment is the root // expression. // @@ -95,10 +88,10 @@ namespace ts { } } - flattenBindingOrAssignmentElement(flattenContext, node, value, location, /*skipInitializer*/ isDestructuringAssignment(node)); + flattenBindingOrAssignmentElement(flattenContext, node, value, location, /*skipInitializer*/ ts.isDestructuringAssignment(node)); if (value && needsValue) { - if (!some(expressions)) { + if (!ts.some(expressions)) { return value; } @@ -107,36 +100,33 @@ namespace ts { return context.factory.inlineExpressions(expressions!) || context.factory.createOmittedExpression(); - function emitExpression(expression: Expression) { - expressions = append(expressions, expression); + function emitExpression(expression: ts.Expression) { + expressions = ts.append(expressions, expression); } - function emitBindingOrAssignment(target: BindingOrAssignmentElementTarget, value: Expression, location: TextRange, original: Node) { - Debug.assertNode(target, createAssignmentCallback ? isIdentifier : isExpression); + function emitBindingOrAssignment(target: ts.BindingOrAssignmentElementTarget, value: ts.Expression, location: ts.TextRange, original: ts.Node) { + ts.Debug.assertNode(target, createAssignmentCallback ? ts.isIdentifier : ts.isExpression); const expression = createAssignmentCallback - ? createAssignmentCallback(target as Identifier, value, location) - : setTextRange( - context.factory.createAssignment(visitNode(target as Expression, visitor, isExpression), value), - location - ); + ? createAssignmentCallback(target as ts.Identifier, value, location) + : ts.setTextRange(context.factory.createAssignment(ts.visitNode(target as ts.Expression, visitor, ts.isExpression), value), location); expression.original = original; emitExpression(expression); } } - function bindingOrAssignmentElementAssignsToName(element: BindingOrAssignmentElement, escapedName: __String): boolean { - const target = getTargetOfBindingOrAssignmentElement(element)!; // TODO: GH#18217 - if (isBindingOrAssignmentPattern(target)) { + function bindingOrAssignmentElementAssignsToName(element: ts.BindingOrAssignmentElement, escapedName: ts.__String): boolean { + const target = ts.getTargetOfBindingOrAssignmentElement(element)!; // TODO: GH#18217 + if (ts.isBindingOrAssignmentPattern(target)) { return bindingOrAssignmentPatternAssignsToName(target, escapedName); } - else if (isIdentifier(target)) { + else if (ts.isIdentifier(target)) { return target.escapedText === escapedName; } return false; } - function bindingOrAssignmentPatternAssignsToName(pattern: BindingOrAssignmentPattern, escapedName: __String): boolean { - const elements = getElementsOfBindingOrAssignmentPattern(pattern); + function bindingOrAssignmentPatternAssignsToName(pattern: ts.BindingOrAssignmentPattern, escapedName: ts.__String): boolean { + const elements = ts.getElementsOfBindingOrAssignmentPattern(pattern); for (const element of elements) { if (bindingOrAssignmentElementAssignsToName(element, escapedName)) { return true; @@ -145,17 +135,17 @@ namespace ts { return false; } - function bindingOrAssignmentElementContainsNonLiteralComputedName(element: BindingOrAssignmentElement): boolean { - const propertyName = tryGetPropertyNameOfBindingOrAssignmentElement(element); - if (propertyName && isComputedPropertyName(propertyName) && !isLiteralExpression(propertyName.expression)) { + function bindingOrAssignmentElementContainsNonLiteralComputedName(element: ts.BindingOrAssignmentElement): boolean { + const propertyName = ts.tryGetPropertyNameOfBindingOrAssignmentElement(element); + if (propertyName && ts.isComputedPropertyName(propertyName) && !ts.isLiteralExpression(propertyName.expression)) { return true; } - const target = getTargetOfBindingOrAssignmentElement(element); - return !!target && isBindingOrAssignmentPattern(target) && bindingOrAssignmentPatternContainsNonLiteralComputedName(target); + const target = ts.getTargetOfBindingOrAssignmentElement(element); + return !!target && ts.isBindingOrAssignmentPattern(target) && bindingOrAssignmentPatternContainsNonLiteralComputedName(target); } - function bindingOrAssignmentPatternContainsNonLiteralComputedName(pattern: BindingOrAssignmentPattern): boolean { - return !!forEach(getElementsOfBindingOrAssignmentPattern(pattern), bindingOrAssignmentElementContainsNonLiteralComputedName); + function bindingOrAssignmentPatternContainsNonLiteralComputedName(pattern: ts.BindingOrAssignmentPattern): boolean { + return !!ts.forEach(ts.getElementsOfBindingOrAssignmentPattern(pattern), bindingOrAssignmentElementContainsNonLiteralComputedName); } /** @@ -169,17 +159,16 @@ namespace ts { * @param hoistTempVariables Indicates whether temporary variables should not be recorded in-line. * @param level Indicates the extent to which flattening should occur. */ - export function flattenDestructuringBinding( - node: VariableDeclaration | ParameterDeclaration, - visitor: (node: Node) => VisitResult, - context: TransformationContext, - level: FlattenLevel, - rval?: Expression, - hoistTempVariables = false, - skipInitializer?: boolean): VariableDeclaration[] { - let pendingExpressions: Expression[] | undefined; - const pendingDeclarations: { pendingExpressions?: Expression[], name: BindingName, value: Expression, location?: TextRange, original?: Node; }[] = []; - const declarations: VariableDeclaration[] = []; + export function flattenDestructuringBinding(node: ts.VariableDeclaration | ts.ParameterDeclaration, visitor: (node: ts.Node) => ts.VisitResult, context: ts.TransformationContext, level: FlattenLevel, rval?: ts.Expression, hoistTempVariables = false, skipInitializer?: boolean): ts.VariableDeclaration[] { + let pendingExpressions: ts.Expression[] | undefined; + const pendingDeclarations: { + pendingExpressions?: ts.Expression[]; + name: ts.BindingName; + value: ts.Expression; + location?: ts.TextRange; + original?: ts.Node; + }[] = []; + const declarations: ts.VariableDeclaration[] = []; const flattenContext: FlattenContext = { context, level, @@ -193,13 +182,13 @@ namespace ts { visitor }; - if (isVariableDeclaration(node)) { - let initializer = getInitializerOfBindingOrAssignmentElement(node); - if (initializer && (isIdentifier(initializer) && bindingOrAssignmentElementAssignsToName(node, initializer.escapedText) || + if (ts.isVariableDeclaration(node)) { + let initializer = ts.getInitializerOfBindingOrAssignmentElement(node); + if (initializer && (ts.isIdentifier(initializer) && bindingOrAssignmentElementAssignsToName(node, initializer.escapedText) || bindingOrAssignmentElementContainsNonLiteralComputedName(node))) { // If the right-hand value of the assignment is also an assignment target then // we need to cache the right-hand value. - initializer = ensureIdentifier(flattenContext, visitNode(initializer, flattenContext.visitor), /*reuseIdentifierExpressions*/ false, initializer); + initializer = ensureIdentifier(flattenContext, ts.visitNode(initializer, flattenContext.visitor), /*reuseIdentifierExpressions*/ false, initializer); node = context.factory.updateVariableDeclaration(node, node.name, /*exclamationToken*/ undefined, /*type*/ undefined, initializer); } } @@ -214,36 +203,30 @@ namespace ts { } else { context.hoistVariableDeclaration(temp); - const pendingDeclaration = last(pendingDeclarations); - pendingDeclaration.pendingExpressions = append( - pendingDeclaration.pendingExpressions, - context.factory.createAssignment(temp, pendingDeclaration.value) - ); - addRange(pendingDeclaration.pendingExpressions, pendingExpressions); + const pendingDeclaration = ts.last(pendingDeclarations); + pendingDeclaration.pendingExpressions = ts.append(pendingDeclaration.pendingExpressions, context.factory.createAssignment(temp, pendingDeclaration.value)); + ts.addRange(pendingDeclaration.pendingExpressions, pendingExpressions); pendingDeclaration.value = temp; } } for (const { pendingExpressions, name, value, location, original } of pendingDeclarations) { - const variable = context.factory.createVariableDeclaration( - name, + const variable = context.factory.createVariableDeclaration(name, /*exclamationToken*/ undefined, - /*type*/ undefined, - pendingExpressions ? context.factory.inlineExpressions(append(pendingExpressions, value)) : value - ); + /*type*/ undefined, pendingExpressions ? context.factory.inlineExpressions(ts.append(pendingExpressions, value)) : value); variable.original = original; - setTextRange(variable, location); + ts.setTextRange(variable, location); declarations.push(variable); } return declarations; - function emitExpression(value: Expression) { - pendingExpressions = append(pendingExpressions, value); + function emitExpression(value: ts.Expression) { + pendingExpressions = ts.append(pendingExpressions, value); } - function emitBindingOrAssignment(target: BindingOrAssignmentElementTarget, value: Expression, location: TextRange | undefined, original: Node | undefined) { - Debug.assertNode(target, isBindingName); + function emitBindingOrAssignment(target: ts.BindingOrAssignmentElementTarget, value: ts.Expression, location: ts.TextRange | undefined, original: ts.Node | undefined) { + ts.Debug.assertNode(target, ts.isBindingName); if (pendingExpressions) { - value = context.factory.inlineExpressions(append(pendingExpressions, value)); + value = context.factory.inlineExpressions(ts.append(pendingExpressions, value)); pendingExpressions = undefined; } pendingDeclarations.push({ pendingExpressions, name: target, value, location, original }); @@ -260,21 +243,16 @@ namespace ts { * @param skipInitializer An optional value indicating whether to include the initializer * for the element. */ - function flattenBindingOrAssignmentElement( - flattenContext: FlattenContext, - element: BindingOrAssignmentElement, - value: Expression | undefined, - location: TextRange, - skipInitializer?: boolean) { - const bindingTarget = getTargetOfBindingOrAssignmentElement(element)!; // TODO: GH#18217 + function flattenBindingOrAssignmentElement(flattenContext: FlattenContext, element: ts.BindingOrAssignmentElement, value: ts.Expression | undefined, location: ts.TextRange, skipInitializer?: boolean) { + const bindingTarget = ts.getTargetOfBindingOrAssignmentElement(element)!; // TODO: GH#18217 if (!skipInitializer) { - const initializer = visitNode(getInitializerOfBindingOrAssignmentElement(element), flattenContext.visitor, isExpression); + const initializer = ts.visitNode(ts.getInitializerOfBindingOrAssignmentElement(element), flattenContext.visitor, ts.isExpression); if (initializer) { // Combine value and initializer if (value) { value = createDefaultValueCheck(flattenContext, value, initializer, location); // If 'value' is not a simple expression, it could contain side-effecting code that should evaluate before an object or array binding pattern. - if (!isSimpleInlineableExpression(initializer) && isBindingOrAssignmentPattern(bindingTarget)) { + if (!ts.isSimpleInlineableExpression(initializer) && ts.isBindingOrAssignmentPattern(bindingTarget)) { value = ensureIdentifier(flattenContext, value, /*reuseIdentifierExpressions*/ true, location); } } @@ -287,10 +265,10 @@ namespace ts { value = flattenContext.context.factory.createVoidZero(); } } - if (isObjectBindingOrAssignmentPattern(bindingTarget)) { + if (ts.isObjectBindingOrAssignmentPattern(bindingTarget)) { flattenObjectBindingOrAssignmentPattern(flattenContext, element, bindingTarget, value!, location); } - else if (isArrayBindingOrAssignmentPattern(bindingTarget)) { + else if (ts.isArrayBindingOrAssignmentPattern(bindingTarget)) { flattenArrayBindingOrAssignmentPattern(flattenContext, element, bindingTarget, value!, location); } else { @@ -307,28 +285,28 @@ namespace ts { * @param value The current RHS value to assign to the element. * @param location The location to use for source maps and comments. */ - function flattenObjectBindingOrAssignmentPattern(flattenContext: FlattenContext, parent: BindingOrAssignmentElement, pattern: ObjectBindingOrAssignmentPattern, value: Expression, location: TextRange) { - const elements = getElementsOfBindingOrAssignmentPattern(pattern); + function flattenObjectBindingOrAssignmentPattern(flattenContext: FlattenContext, parent: ts.BindingOrAssignmentElement, pattern: ts.ObjectBindingOrAssignmentPattern, value: ts.Expression, location: ts.TextRange) { + const elements = ts.getElementsOfBindingOrAssignmentPattern(pattern); const numElements = elements.length; if (numElements !== 1) { // For anything other than a single-element destructuring we need to generate a temporary // to ensure value is evaluated exactly once. Additionally, if we have zero elements // we need to emit *something* to ensure that in case a 'var' keyword was already emitted, // so in that case, we'll intentionally create that temporary. - const reuseIdentifierExpressions = !isDeclarationBindingElement(parent) || numElements !== 0; + const reuseIdentifierExpressions = !ts.isDeclarationBindingElement(parent) || numElements !== 0; value = ensureIdentifier(flattenContext, value, reuseIdentifierExpressions, location); } - let bindingElements: BindingOrAssignmentElement[] | undefined; - let computedTempVariables: Expression[] | undefined; + let bindingElements: ts.BindingOrAssignmentElement[] | undefined; + let computedTempVariables: ts.Expression[] | undefined; for (let i = 0; i < numElements; i++) { const element = elements[i]; - if (!getRestIndicatorOfBindingOrAssignmentElement(element)) { - const propertyName = getPropertyNameOfBindingOrAssignmentElement(element)!; + if (!ts.getRestIndicatorOfBindingOrAssignmentElement(element)) { + const propertyName = ts.getPropertyNameOfBindingOrAssignmentElement(element)!; if (flattenContext.level >= FlattenLevel.ObjectRest - && !(element.transformFlags & (TransformFlags.ContainsRestOrSpread | TransformFlags.ContainsObjectRestOrSpread)) - && !(getTargetOfBindingOrAssignmentElement(element)!.transformFlags & (TransformFlags.ContainsRestOrSpread | TransformFlags.ContainsObjectRestOrSpread)) - && !isComputedPropertyName(propertyName)) { - bindingElements = append(bindingElements, visitNode(element, flattenContext.visitor)); + && !(element.transformFlags & (ts.TransformFlags.ContainsRestOrSpread | ts.TransformFlags.ContainsObjectRestOrSpread)) + && !(ts.getTargetOfBindingOrAssignmentElement(element)!.transformFlags & (ts.TransformFlags.ContainsRestOrSpread | ts.TransformFlags.ContainsObjectRestOrSpread)) + && !ts.isComputedPropertyName(propertyName)) { + bindingElements = ts.append(bindingElements, ts.visitNode(element, flattenContext.visitor)); } else { if (bindingElements) { @@ -336,8 +314,8 @@ namespace ts { bindingElements = undefined; } const rhsValue = createDestructuringPropertyAccess(flattenContext, value, propertyName); - if (isComputedPropertyName(propertyName)) { - computedTempVariables = append(computedTempVariables, (rhsValue as ElementAccessExpression).argumentExpression); + if (ts.isComputedPropertyName(propertyName)) { + computedTempVariables = ts.append(computedTempVariables, (rhsValue as ts.ElementAccessExpression).argumentExpression); } flattenBindingOrAssignmentElement(flattenContext, element, rhsValue, /*location*/ element); } @@ -365,62 +343,58 @@ namespace ts { * @param value The current RHS value to assign to the element. * @param location The location to use for source maps and comments. */ - function flattenArrayBindingOrAssignmentPattern(flattenContext: FlattenContext, parent: BindingOrAssignmentElement, pattern: ArrayBindingOrAssignmentPattern, value: Expression, location: TextRange) { - const elements = getElementsOfBindingOrAssignmentPattern(pattern); + function flattenArrayBindingOrAssignmentPattern(flattenContext: FlattenContext, parent: ts.BindingOrAssignmentElement, pattern: ts.ArrayBindingOrAssignmentPattern, value: ts.Expression, location: ts.TextRange) { + const elements = ts.getElementsOfBindingOrAssignmentPattern(pattern); const numElements = elements.length; if (flattenContext.level < FlattenLevel.ObjectRest && flattenContext.downlevelIteration) { // Read the elements of the iterable into an array - value = ensureIdentifier( - flattenContext, - setTextRange( - flattenContext.context.getEmitHelperFactory().createReadHelper( - value, - numElements > 0 && getRestIndicatorOfBindingOrAssignmentElement(elements[numElements - 1]) + value = ensureIdentifier(flattenContext, ts.setTextRange(flattenContext.context.getEmitHelperFactory().createReadHelper(value, numElements > 0 && ts.getRestIndicatorOfBindingOrAssignmentElement(elements[numElements - 1]) ? undefined - : numElements - ), - location - ), - /*reuseIdentifierExpressions*/ false, - location - ); + : numElements), location), + /*reuseIdentifierExpressions*/ false, location); } else if (numElements !== 1 && (flattenContext.level < FlattenLevel.ObjectRest || numElements === 0) - || every(elements, isOmittedExpression)) { + || ts.every(elements, ts.isOmittedExpression)) { // For anything other than a single-element destructuring we need to generate a temporary // to ensure value is evaluated exactly once. Additionally, if we have zero elements // we need to emit *something* to ensure that in case a 'var' keyword was already emitted, // so in that case, we'll intentionally create that temporary. // Or all the elements of the binding pattern are omitted expression such as "var [,] = [1,2]", // then we will create temporary variable. - const reuseIdentifierExpressions = !isDeclarationBindingElement(parent) || numElements !== 0; + const reuseIdentifierExpressions = !ts.isDeclarationBindingElement(parent) || numElements !== 0; value = ensureIdentifier(flattenContext, value, reuseIdentifierExpressions, location); } - let bindingElements: BindingOrAssignmentElement[] | undefined; - let restContainingElements: [Identifier, BindingOrAssignmentElement][] | undefined; + let bindingElements: ts.BindingOrAssignmentElement[] | undefined; + let restContainingElements: [ + ts.Identifier, + ts.BindingOrAssignmentElement + ][] | undefined; for (let i = 0; i < numElements; i++) { const element = elements[i]; if (flattenContext.level >= FlattenLevel.ObjectRest) { // If an array pattern contains an ObjectRest, we must cache the result so that we // can perform the ObjectRest destructuring in a different declaration - if (element.transformFlags & TransformFlags.ContainsObjectRestOrSpread || flattenContext.hasTransformedPriorElement && !isSimpleBindingOrAssignmentElement(element)) { + if (element.transformFlags & ts.TransformFlags.ContainsObjectRestOrSpread || flattenContext.hasTransformedPriorElement && !isSimpleBindingOrAssignmentElement(element)) { flattenContext.hasTransformedPriorElement = true; const temp = flattenContext.context.factory.createTempVariable(/*recordTempVariable*/ undefined); if (flattenContext.hoistTempVariables) { flattenContext.context.hoistVariableDeclaration(temp); } - restContainingElements = append(restContainingElements, [temp, element] as [Identifier, BindingOrAssignmentElement]); - bindingElements = append(bindingElements, flattenContext.createArrayBindingOrAssignmentElement(temp)); + restContainingElements = ts.append(restContainingElements, [temp, element] as [ + ts.Identifier, + ts.BindingOrAssignmentElement + ]); + bindingElements = ts.append(bindingElements, flattenContext.createArrayBindingOrAssignmentElement(temp)); } else { - bindingElements = append(bindingElements, element); + bindingElements = ts.append(bindingElements, element); } } - else if (isOmittedExpression(element)) { + else if (ts.isOmittedExpression(element)) { continue; } - else if (!getRestIndicatorOfBindingOrAssignmentElement(element)) { + else if (!ts.getRestIndicatorOfBindingOrAssignmentElement(element)) { const rhsValue = flattenContext.context.factory.createElementAccessExpression(value, i); flattenBindingOrAssignmentElement(flattenContext, element, rhsValue, /*location*/ element); } @@ -439,15 +413,19 @@ namespace ts { } } - function isSimpleBindingOrAssignmentElement(element: BindingOrAssignmentElement): boolean { - const target = getTargetOfBindingOrAssignmentElement(element); - if (!target || isOmittedExpression(target)) return true; - const propertyName = tryGetPropertyNameOfBindingOrAssignmentElement(element); - if (propertyName && !isPropertyNameLiteral(propertyName)) return false; - const initializer = getInitializerOfBindingOrAssignmentElement(element); - if (initializer && !isSimpleInlineableExpression(initializer)) return false; - if (isBindingOrAssignmentPattern(target)) return every(getElementsOfBindingOrAssignmentPattern(target), isSimpleBindingOrAssignmentElement); - return isIdentifier(target); + function isSimpleBindingOrAssignmentElement(element: ts.BindingOrAssignmentElement): boolean { + const target = ts.getTargetOfBindingOrAssignmentElement(element); + if (!target || ts.isOmittedExpression(target)) + return true; + const propertyName = ts.tryGetPropertyNameOfBindingOrAssignmentElement(element); + if (propertyName && !ts.isPropertyNameLiteral(propertyName)) + return false; + const initializer = ts.getInitializerOfBindingOrAssignmentElement(element); + if (initializer && !ts.isSimpleInlineableExpression(initializer)) + return false; + if (ts.isBindingOrAssignmentPattern(target)) + return ts.every(ts.getElementsOfBindingOrAssignmentPattern(target), isSimpleBindingOrAssignmentElement); + return ts.isIdentifier(target); } /** @@ -458,7 +436,7 @@ namespace ts { * @param defaultValue The default value to use if `value` is `undefined` at runtime. * @param location The location to use for source maps and comments. */ - function createDefaultValueCheck(flattenContext: FlattenContext, value: Expression, defaultValue: Expression, location: TextRange): Expression { + function createDefaultValueCheck(flattenContext: FlattenContext, value: ts.Expression, defaultValue: ts.Expression, location: ts.TextRange): ts.Expression { value = ensureIdentifier(flattenContext, value, /*reuseIdentifierExpressions*/ true, location); return flattenContext.context.factory.createConditionalExpression(flattenContext.context.factory.createTypeCheck(value, "undefined"), /*questionToken*/ undefined, defaultValue, /*colonToken*/ undefined, value); } @@ -473,17 +451,17 @@ namespace ts { * @param value The RHS value that is the source of the property. * @param propertyName The destructuring property name. */ - function createDestructuringPropertyAccess(flattenContext: FlattenContext, value: Expression, propertyName: PropertyName): LeftHandSideExpression { - if (isComputedPropertyName(propertyName)) { - const argumentExpression = ensureIdentifier(flattenContext, visitNode(propertyName.expression, flattenContext.visitor), /*reuseIdentifierExpressions*/ false, /*location*/ propertyName); + function createDestructuringPropertyAccess(flattenContext: FlattenContext, value: ts.Expression, propertyName: ts.PropertyName): ts.LeftHandSideExpression { + if (ts.isComputedPropertyName(propertyName)) { + const argumentExpression = ensureIdentifier(flattenContext, ts.visitNode(propertyName.expression, flattenContext.visitor), /*reuseIdentifierExpressions*/ false, /*location*/ propertyName); return flattenContext.context.factory.createElementAccessExpression(value, argumentExpression); } - else if (isStringOrNumericLiteralLike(propertyName)) { - const argumentExpression = factory.cloneNode(propertyName); + else if (ts.isStringOrNumericLiteralLike(propertyName)) { + const argumentExpression = ts.factory.cloneNode(propertyName); return flattenContext.context.factory.createElementAccessExpression(value, argumentExpression); } else { - const name = flattenContext.context.factory.createIdentifier(idText(propertyName)); + const name = flattenContext.context.factory.createIdentifier(ts.idText(propertyName)); return flattenContext.context.factory.createPropertyAccessExpression(value, name); } } @@ -499,15 +477,15 @@ namespace ts { * false if it is necessary to always emit an identifier. * @param location The location to use for source maps and comments. */ - function ensureIdentifier(flattenContext: FlattenContext, value: Expression, reuseIdentifierExpressions: boolean, location: TextRange) { - if (isIdentifier(value) && reuseIdentifierExpressions) { + function ensureIdentifier(flattenContext: FlattenContext, value: ts.Expression, reuseIdentifierExpressions: boolean, location: ts.TextRange) { + if (ts.isIdentifier(value) && reuseIdentifierExpressions) { return value; } else { const temp = flattenContext.context.factory.createTempVariable(/*recordTempVariable*/ undefined); if (flattenContext.hoistTempVariables) { flattenContext.context.hoistVariableDeclaration(temp); - flattenContext.emitExpression(setTextRange(flattenContext.context.factory.createAssignment(temp, value), location)); + flattenContext.emitExpression(ts.setTextRange(flattenContext.context.factory.createAssignment(temp, value), location)); } else { flattenContext.emitBindingOrAssignment(temp, value, location, /*original*/ undefined); @@ -516,29 +494,29 @@ namespace ts { } } - function makeArrayBindingPattern(factory: NodeFactory, elements: BindingOrAssignmentElement[]) { - Debug.assertEachNode(elements, isArrayBindingElement); - return factory.createArrayBindingPattern(elements as ArrayBindingElement[]); + function makeArrayBindingPattern(factory: ts.NodeFactory, elements: ts.BindingOrAssignmentElement[]) { + ts.Debug.assertEachNode(elements, ts.isArrayBindingElement); + return factory.createArrayBindingPattern(elements as ts.ArrayBindingElement[]); } - function makeArrayAssignmentPattern(factory: NodeFactory, elements: BindingOrAssignmentElement[]) { - return factory.createArrayLiteralExpression(map(elements, factory.converters.convertToArrayAssignmentElement)); + function makeArrayAssignmentPattern(factory: ts.NodeFactory, elements: ts.BindingOrAssignmentElement[]) { + return factory.createArrayLiteralExpression(ts.map(elements, factory.converters.convertToArrayAssignmentElement)); } - function makeObjectBindingPattern(factory: NodeFactory, elements: BindingOrAssignmentElement[]) { - Debug.assertEachNode(elements, isBindingElement); - return factory.createObjectBindingPattern(elements as BindingElement[]); + function makeObjectBindingPattern(factory: ts.NodeFactory, elements: ts.BindingOrAssignmentElement[]) { + ts.Debug.assertEachNode(elements, ts.isBindingElement); + return factory.createObjectBindingPattern(elements as ts.BindingElement[]); } - function makeObjectAssignmentPattern(factory: NodeFactory, elements: BindingOrAssignmentElement[]) { - return factory.createObjectLiteralExpression(map(elements, factory.converters.convertToObjectAssignmentElement)); + function makeObjectAssignmentPattern(factory: ts.NodeFactory, elements: ts.BindingOrAssignmentElement[]) { + return factory.createObjectLiteralExpression(ts.map(elements, factory.converters.convertToObjectAssignmentElement)); } - function makeBindingElement(factory: NodeFactory, name: Identifier) { + function makeBindingElement(factory: ts.NodeFactory, name: ts.Identifier) { return factory.createBindingElement(/*dotDotDotToken*/ undefined, /*propertyName*/ undefined, name); } - function makeAssignmentElement(name: Identifier) { + function makeAssignmentElement(name: ts.Identifier) { return name; } } diff --git a/src/compiler/transformers/es2015.ts b/src/compiler/transformers/es2015.ts index 38ad28faacc32..7a4c00621f6c7 100644 --- a/src/compiler/transformers/es2015.ts +++ b/src/compiler/transformers/es2015.ts @@ -4,7 +4,7 @@ namespace ts { /** Enables substitutions for captured `this` */ CapturedThis = 1 << 0, /** Enables substitutions for block-scoped bindings. */ - BlockScopedBindings = 1 << 1, + BlockScopedBindings = 1 << 1 } /** @@ -47,13 +47,13 @@ namespace ts { */ interface LoopOutParameter { flags: LoopOutParameterFlags; - originalName: Identifier; - outParamName: Identifier; + originalName: ts.Identifier; + outParamName: ts.Identifier; } const enum LoopOutParameterFlags { - Body = 1 << 0, // Modified in the body of the iteration statement - Initializer = 1 << 1, // Set in the initializer of a ForStatement + Body = 1 << 0, + Initializer = 1 << 1 } const enum CopyDirection { @@ -72,15 +72,15 @@ namespace ts { * set of labels that occurred inside the converted loop * used to determine if labeled jump can be emitted as is or it should be dispatched to calling code */ - labels?: ESMap; + labels?: ts.ESMap; /* * collection of labeled jumps that transfer control outside the converted loop. * maps store association 'label -> labelMarker' where * - label - value of label as it appear in code * - label marker - return value that should be interpreted by calling code as 'jump to " - const lessThanToken = getTokenAtPosition(sourceFile, pos); + const lessThanToken = ts.getTokenAtPosition(sourceFile, pos); const firstJsxElementOrOpenElement = lessThanToken.parent; let binaryExpr = firstJsxElementOrOpenElement.parent; - if (!isBinaryExpression(binaryExpr)) { + if (!ts.isBinaryExpression(binaryExpr)) { // In case the start element is a JsxSelfClosingElement, it the end. // For JsxOpenElement, find one more parent binaryExpr = binaryExpr.parent; - if (!isBinaryExpression(binaryExpr)) return undefined; + if (!ts.isBinaryExpression(binaryExpr)) + return undefined; } - if (!nodeIsMissing(binaryExpr.operatorToken)) return undefined; + if (!ts.nodeIsMissing(binaryExpr.operatorToken)) + return undefined; return binaryExpr; } - function doChange(changeTracker: textChanges.ChangeTracker, sf: SourceFile, node: Node) { + function doChange(changeTracker: ts.textChanges.ChangeTracker, sf: ts.SourceFile, node: ts.Node) { const jsx = flattenInvalidBinaryExpr(node); - if (jsx) changeTracker.replaceNode(sf, node, factory.createJsxFragment(factory.createJsxOpeningFragment(), jsx, factory.createJsxJsxClosingFragment())); + if (jsx) + changeTracker.replaceNode(sf, node, ts.factory.createJsxFragment(ts.factory.createJsxOpeningFragment(), jsx, ts.factory.createJsxJsxClosingFragment())); } // The invalid syntax is constructed as // InvalidJsxTree :: One of // JsxElement CommaToken InvalidJsxTree // JsxElement CommaToken JsxElement - function flattenInvalidBinaryExpr(node: Node): JsxChild[] | undefined { - const children: JsxChild[] = []; + function flattenInvalidBinaryExpr(node: ts.Node): ts.JsxChild[] | undefined { + const children: ts.JsxChild[] = []; let current = node; while (true) { - if (isBinaryExpression(current) && nodeIsMissing(current.operatorToken) && current.operatorToken.kind === SyntaxKind.CommaToken) { - children.push(current.left as JsxChild); - if (isJsxChild(current.right)) { + if (ts.isBinaryExpression(current) && ts.nodeIsMissing(current.operatorToken) && current.operatorToken.kind === ts.SyntaxKind.CommaToken) { + children.push(current.left as ts.JsxChild); + if (ts.isJsxChild(current.right)) { children.push(current.right); // Indicates the tree has go to the bottom return children; } - else if (isBinaryExpression(current.right)) { + else if (ts.isBinaryExpression(current.right)) { current = current.right; continue; } // Unreachable case - else return undefined; + else + return undefined; } // Unreachable case - else return undefined; + else + return undefined; } } } diff --git a/src/services/completions.ts b/src/services/completions.ts index 27066f7b72e64..102733b45b9c2 100644 --- a/src/services/completions.ts +++ b/src/services/completions.ts @@ -6,7 +6,9 @@ namespace ts.Completions { export type Log = (message: string) => void; - export type SortText = string & { __sortText: any }; + export type SortText = string & { + __sortText: any; + }; export const SortText = { // Presets LocalDeclarationPriority: "10" as SortText, @@ -52,7 +54,7 @@ namespace ts.Completions { /** A type-only import that needs to be promoted in order to be used at the completion location */ TypeOnlyAlias = "TypeOnlyAlias/", /** Auto-import that comes attached to an object literal method snippet */ - ObjectLiteralMethodSnippet = "ObjectLiteralMethodSnippet/", + ObjectLiteralMethodSnippet = "ObjectLiteralMethodSnippet/" } const enum SymbolOriginInfoKind { @@ -66,7 +68,7 @@ namespace ts.Completions { ObjectLiteralMethod = 1 << 7, SymbolMemberNoExport = SymbolMember, - SymbolMemberExport = SymbolMember | Export, + SymbolMemberExport = SymbolMember | Export } interface SymbolOriginInfo { @@ -78,7 +80,7 @@ namespace ts.Completions { interface SymbolOriginInfoExport extends SymbolOriginInfo { symbolName: string; - moduleSymbol: Symbol; + moduleSymbol: ts.Symbol; isDefaultExport: boolean; exportName: string; exportMapKey: string; @@ -86,19 +88,19 @@ namespace ts.Completions { interface SymbolOriginInfoResolvedExport extends SymbolOriginInfo { symbolName: string; - moduleSymbol: Symbol; + moduleSymbol: ts.Symbol; exportName: string; moduleSpecifier: string; } interface SymbolOriginInfoTypeOnlyAlias extends SymbolOriginInfo { - declaration: TypeOnlyAliasDeclaration; + declaration: ts.TypeOnlyAliasDeclaration; } interface SymbolOriginInfoObjectLiteralMethod extends SymbolOriginInfo { - insertText: string, - labelDetails: CompletionEntryLabelDetails, - isSnippet?: true, + insertText: string; + labelDetails: ts.CompletionEntryLabelDetails; + isSnippet?: true; } function originIsThisType(origin: SymbolOriginInfo): boolean { @@ -155,51 +157,45 @@ namespace ts.Completions { type SymbolSortTextMap = (SortText | undefined)[]; const enum KeywordCompletionFilters { - None, // No keywords - All, // Every possible keyword (TODO: This is never appropriate) - ClassElementKeywords, // Keywords inside class body - InterfaceElementKeywords, // Keywords inside interface body - ConstructorParameterKeywords, // Keywords at constructor parameter - FunctionLikeBodyKeywords, // Keywords at function like body + None, + All, + ClassElementKeywords, + InterfaceElementKeywords, + ConstructorParameterKeywords, + FunctionLikeBodyKeywords, TypeAssertionKeywords, TypeKeywords, - TypeKeyword, // Literally just `type` + TypeKeyword, Last = TypeKeyword } - const enum GlobalsSearch { Continue, Success, Fail } + const enum GlobalsSearch { + Continue, + Success, + Fail + } interface ModuleSpecifierResolutioContext { - tryResolve: (exportInfo: readonly SymbolExportInfo[], symbolName: string, isFromAmbientModule: boolean) => ModuleSpecifierResolutionResult; + tryResolve: (exportInfo: readonly ts.SymbolExportInfo[], symbolName: string, isFromAmbientModule: boolean) => ModuleSpecifierResolutionResult; resolvedAny: () => boolean; skippedAny: () => boolean; resolvedBeyondLimit: () => boolean; } type ModuleSpecifierResolutionResult = "skipped" | "failed" | { - exportInfo?: SymbolExportInfo; + exportInfo?: ts.SymbolExportInfo; moduleSpecifier: string; }; - function resolvingModuleSpecifiers( - logPrefix: string, - host: LanguageServiceHost, - program: Program, - sourceFile: SourceFile, - position: number, - preferences: UserPreferences, - isForImportStatementCompletion: boolean, - isValidTypeOnlyUseSite: boolean, - cb: (context: ModuleSpecifierResolutioContext) => TReturn, - ): TReturn { - const start = timestamp(); - const packageJsonImportFilter = createPackageJsonImportFilter(sourceFile, preferences, host); + function resolvingModuleSpecifiers(logPrefix: string, host: ts.LanguageServiceHost, program: ts.Program, sourceFile: ts.SourceFile, position: number, preferences: ts.UserPreferences, isForImportStatementCompletion: boolean, isValidTypeOnlyUseSite: boolean, cb: (context: ModuleSpecifierResolutioContext) => TReturn): TReturn { + const start = ts.timestamp(); + const packageJsonImportFilter = ts.createPackageJsonImportFilter(sourceFile, preferences, host); // Under `--moduleResolution nodenext`, we have to resolve module specifiers up front, because // package.json exports can mean we *can't* resolve a module specifier (that doesn't include a // relative path into node_modules), and we want to filter those completions out entirely. // Import statement completions always need specifier resolution because the module specifier is // part of their `insertText`, not the `codeActions` creating edits away from the cursor. - const needsFullResolution = isForImportStatementCompletion || moduleResolutionRespectsExports(getEmitModuleResolutionKind(program.getCompilerOptions())); + const needsFullResolution = isForImportStatementCompletion || ts.moduleResolutionRespectsExports(ts.getEmitModuleResolutionKind(program.getCompilerOptions())); let skippedAny = false; let ambientCount = 0; let resolvedCount = 0; @@ -216,12 +212,12 @@ namespace ts.Completions { const hitRateMessage = cacheAttemptCount ? ` (${(resolvedFromCacheCount / cacheAttemptCount * 100).toFixed(1)}% hit rate)` : ""; host.log?.(`${logPrefix}: resolved ${resolvedCount} module specifiers, plus ${ambientCount} ambient and ${resolvedFromCacheCount} from cache${hitRateMessage}`); host.log?.(`${logPrefix}: response is ${skippedAny ? "incomplete" : "complete"}`); - host.log?.(`${logPrefix}: ${timestamp() - start}`); + host.log?.(`${logPrefix}: ${ts.timestamp() - start}`); return result; - function tryResolve(exportInfo: readonly SymbolExportInfo[], symbolName: string, isFromAmbientModule: boolean): ModuleSpecifierResolutionResult { + function tryResolve(exportInfo: readonly ts.SymbolExportInfo[], symbolName: string, isFromAmbientModule: boolean): ModuleSpecifierResolutionResult { if (isFromAmbientModule) { - const result = codefix.getModuleSpecifierForBestExportInfo(exportInfo, symbolName, position, isValidTypeOnlyUseSite, sourceFile, program, host, preferences); + const result = ts.codefix.getModuleSpecifierForBestExportInfo(exportInfo, symbolName, position, isValidTypeOnlyUseSite, sourceFile, program, host, preferences); if (result) { ambientCount++; } @@ -230,7 +226,7 @@ namespace ts.Completions { const shouldResolveModuleSpecifier = needsFullResolution || preferences.allowIncompleteCompletions && resolvedCount < moduleSpecifierResolutionLimit; const shouldGetModuleSpecifierFromCache = !shouldResolveModuleSpecifier && preferences.allowIncompleteCompletions && cacheAttemptCount < moduleSpecifierResolutionCacheAttemptLimit; const result = (shouldResolveModuleSpecifier || shouldGetModuleSpecifierFromCache) - ? codefix.getModuleSpecifierForBestExportInfo(exportInfo, symbolName, position, isValidTypeOnlyUseSite, sourceFile, program, host, preferences, packageJsonImportFilter, shouldGetModuleSpecifierFromCache) + ? ts.codefix.getModuleSpecifierForBestExportInfo(exportInfo, symbolName, position, isValidTypeOnlyUseSite, sourceFile, program, host, preferences, packageJsonImportFilter, shouldGetModuleSpecifierFromCache) : undefined; if (!shouldResolveModuleSpecifier && !shouldGetModuleSpecifierFromCache || shouldGetModuleSpecifierFromCache && !result) { @@ -247,20 +243,9 @@ namespace ts.Completions { } } - export function getCompletionsAtPosition( - host: LanguageServiceHost, - program: Program, - log: Log, - sourceFile: SourceFile, - position: number, - preferences: UserPreferences, - triggerCharacter: CompletionsTriggerCharacter | undefined, - completionKind: CompletionTriggerKind | undefined, - cancellationToken: CancellationToken, - formatContext?: formatting.FormatContext, - ): CompletionInfo | undefined { + export function getCompletionsAtPosition(host: ts.LanguageServiceHost, program: ts.Program, log: Log, sourceFile: ts.SourceFile, position: number, preferences: ts.UserPreferences, triggerCharacter: ts.CompletionsTriggerCharacter | undefined, completionKind: ts.CompletionTriggerKind | undefined, cancellationToken: ts.CancellationToken, formatContext?: ts.formatting.FormatContext): ts.CompletionInfo | undefined { const { previousToken } = getRelevantTokens(position, sourceFile); - if (triggerCharacter && !isInString(sourceFile, position, previousToken) && !isValidTrigger(sourceFile, triggerCharacter, previousToken, position)) { + if (triggerCharacter && !ts.isInString(sourceFile, position, previousToken) && !isValidTrigger(sourceFile, triggerCharacter, previousToken, position)) { return undefined; } @@ -277,7 +262,7 @@ namespace ts.Completions { // we can continue it from the cached previous response. const compilerOptions = program.getCompilerOptions(); const incompleteCompletionsCache = preferences.allowIncompleteCompletions ? host.getIncompleteCompletionsCache?.() : undefined; - if (incompleteCompletionsCache && completionKind === CompletionTriggerKind.TriggerForIncompleteCompletions && previousToken && isIdentifier(previousToken)) { + if (incompleteCompletionsCache && completionKind === ts.CompletionTriggerKind.TriggerForIncompleteCompletions && previousToken && ts.isIdentifier(previousToken)) { const incompleteContinuation = continuePreviousIncompleteResponse(incompleteCompletionsCache, sourceFile, previousToken, program, host, preferences, cancellationToken); if (incompleteContinuation) { return incompleteContinuation; @@ -287,13 +272,13 @@ namespace ts.Completions { incompleteCompletionsCache?.clear(); } - const stringCompletions = StringCompletions.getStringLiteralCompletions(sourceFile, position, previousToken, compilerOptions, host, program, log, preferences); + const stringCompletions = ts.Completions.StringCompletions.getStringLiteralCompletions(sourceFile, position, previousToken, compilerOptions, host, program, log, preferences); if (stringCompletions) { return stringCompletions; } - if (previousToken && isBreakOrContinueStatement(previousToken.parent) - && (previousToken.kind === SyntaxKind.BreakKeyword || previousToken.kind === SyntaxKind.ContinueKeyword || previousToken.kind === SyntaxKind.Identifier)) { + if (previousToken && ts.isBreakOrContinueStatement(previousToken.parent) + && (previousToken.kind === ts.SyntaxKind.BreakKeyword || previousToken.kind === ts.SyntaxKind.ContinueKeyword || previousToken.kind === ts.SyntaxKind.Identifier)) { return getLabelCompletionAtPosition(previousToken.parent); } @@ -311,16 +296,16 @@ namespace ts.Completions { return response; case CompletionDataKind.JsDocTagName: // If the current position is a jsDoc tag name, only tag names should be provided for completion - return jsdocCompletionInfo(JsDoc.getJSDocTagNameCompletions()); + return jsdocCompletionInfo(ts.JsDoc.getJSDocTagNameCompletions()); case CompletionDataKind.JsDocTag: // If the current position is a jsDoc tag, only tags should be provided for completion - return jsdocCompletionInfo(JsDoc.getJSDocTagCompletions()); + return jsdocCompletionInfo(ts.JsDoc.getJSDocTagCompletions()); case CompletionDataKind.JsDocParameterName: - return jsdocCompletionInfo(JsDoc.getJSDocParameterNameCompletions(completionData.tag)); + return jsdocCompletionInfo(ts.JsDoc.getJSDocParameterNameCompletions(completionData.tag)); case CompletionDataKind.Keywords: return specificKeywordCompletionInfo(completionData.keywordCompletions, completionData.isNewIdentifierLocation); default: - return Debug.assertNever(completionData); + return ts.Debug.assertNever(completionData); } } @@ -331,54 +316,36 @@ namespace ts.Completions { // by the language service consistent with what TS Server does and what editors typically do. This also makes // completions tests make more sense. We used to sort only alphabetically and only in the server layer, but // this made tests really weird, since most fourslash tests don't use the server. - function compareCompletionEntries(entryInArray: CompletionEntry, entryToInsert: CompletionEntry): Comparison { - let result = compareStringsCaseSensitiveUI(entryInArray.sortText, entryToInsert.sortText); - if (result === Comparison.EqualTo) { - result = compareStringsCaseSensitiveUI(entryInArray.name, entryToInsert.name); + function compareCompletionEntries(entryInArray: ts.CompletionEntry, entryToInsert: ts.CompletionEntry): ts.Comparison { + let result = ts.compareStringsCaseSensitiveUI(entryInArray.sortText, entryToInsert.sortText); + if (result === ts.Comparison.EqualTo) { + result = ts.compareStringsCaseSensitiveUI(entryInArray.name, entryToInsert.name); } - if (result === Comparison.EqualTo && entryInArray.data?.moduleSpecifier && entryToInsert.data?.moduleSpecifier) { + if (result === ts.Comparison.EqualTo && entryInArray.data?.moduleSpecifier && entryToInsert.data?.moduleSpecifier) { // Sort same-named auto-imports by module specifier - result = compareNumberOfDirectorySeparators( - (entryInArray.data as CompletionEntryDataResolved).moduleSpecifier, - (entryToInsert.data as CompletionEntryDataResolved).moduleSpecifier, - ); + result = ts.compareNumberOfDirectorySeparators((entryInArray.data as ts.CompletionEntryDataResolved).moduleSpecifier, (entryToInsert.data as ts.CompletionEntryDataResolved).moduleSpecifier); } - if (result === Comparison.EqualTo) { + if (result === ts.Comparison.EqualTo) { // Fall back to symbol order - if we return `EqualTo`, `insertSorted` will put later symbols first. - return Comparison.LessThan; + return ts.Comparison.LessThan; } return result; } - function completionEntryDataIsResolved(data: CompletionEntryDataAutoImport | undefined): data is CompletionEntryDataResolved { + function completionEntryDataIsResolved(data: ts.CompletionEntryDataAutoImport | undefined): data is ts.CompletionEntryDataResolved { return !!data?.moduleSpecifier; } - function continuePreviousIncompleteResponse( - cache: IncompleteCompletionsCache, - file: SourceFile, - location: Identifier, - program: Program, - host: LanguageServiceHost, - preferences: UserPreferences, - cancellationToken: CancellationToken, - ): CompletionInfo | undefined { + function continuePreviousIncompleteResponse(cache: ts.IncompleteCompletionsCache, file: ts.SourceFile, location: ts.Identifier, program: ts.Program, host: ts.LanguageServiceHost, preferences: ts.UserPreferences, cancellationToken: ts.CancellationToken): ts.CompletionInfo | undefined { const previousResponse = cache.get(); - if (!previousResponse) return undefined; + if (!previousResponse) + return undefined; const lowerCaseTokenText = location.text.toLowerCase(); - const exportMap = getExportInfoMap(file, host, program, cancellationToken); - const newEntries = resolvingModuleSpecifiers( - "continuePreviousIncompleteResponse", - host, - program, - file, - location.getStart(), - preferences, - /*isForImportStatementCompletion*/ false, - isValidTypeOnlyAliasUseSite(location), - context => { - const entries = mapDefined(previousResponse.entries, entry => { + const exportMap = ts.getExportInfoMap(file, host, program, cancellationToken); + const newEntries = resolvingModuleSpecifiers("continuePreviousIncompleteResponse", host, program, file, location.getStart(), preferences, + /*isForImportStatementCompletion*/ false, ts.isValidTypeOnlyAliasUseSite(location), context => { + const entries = ts.mapDefined(previousResponse.entries, entry => { if (!entry.hasAction || !entry.source || !entry.data || completionEntryDataIsResolved(entry.data)) { // Not an auto import or already resolved; keep as is return entry; @@ -388,11 +355,12 @@ namespace ts.Completions { return undefined; } - const { origin } = Debug.checkDefined(getAutoImportSymbolFromCompletionEntryData(entry.name, entry.data, program, host)); + const { origin } = ts.Debug.checkDefined(getAutoImportSymbolFromCompletionEntryData(entry.name, entry.data, program, host)); const info = exportMap.get(file.path, entry.data.exportMapKey); - const result = info && context.tryResolve(info, entry.name, !isExternalModuleNameRelative(stripQuotes(origin.moduleSymbol.name))); - if (result === "skipped") return entry; + const result = info && context.tryResolve(info, entry.name, !ts.isExternalModuleNameRelative(ts.stripQuotes(origin.moduleSymbol.name))); + if (result === "skipped") + return entry; if (!result || result === "failed") { host.log?.(`Unexpected failure resolving auto import for '${entry.name}' from '${entry.source}'`); return undefined; @@ -407,7 +375,7 @@ namespace ts.Completions { // so why bother allocating a bunch of new objects? entry.data = originToCompletionEntryData(newOrigin); entry.source = getSourceFromOrigin(newOrigin); - entry.sourceDisplay = [textPart(newOrigin.moduleSpecifier)]; + entry.sourceDisplay = [ts.textPart(newOrigin.moduleSpecifier)]; return entry; }); @@ -416,28 +384,27 @@ namespace ts.Completions { } return entries; - }, - ); + }); previousResponse.entries = newEntries; - previousResponse.flags = (previousResponse.flags || 0) | CompletionInfoFlags.IsContinuation; + previousResponse.flags = (previousResponse.flags || 0) | ts.CompletionInfoFlags.IsContinuation; return previousResponse; } - function jsdocCompletionInfo(entries: CompletionEntry[]): CompletionInfo { + function jsdocCompletionInfo(entries: ts.CompletionEntry[]): ts.CompletionInfo { return { isGlobalCompletion: false, isMemberCompletion: false, isNewIdentifierLocation: false, entries }; } - function keywordToCompletionEntry(keyword: TokenSyntaxKind) { + function keywordToCompletionEntry(keyword: ts.TokenSyntaxKind) { return { - name: tokenToString(keyword)!, - kind: ScriptElementKind.keyword, - kindModifiers: ScriptElementKindModifier.none, + name: ts.tokenToString(keyword)!, + kind: ts.ScriptElementKind.keyword, + kindModifiers: ts.ScriptElementKindModifier.none, sortText: SortText.GlobalsOrKeywords, }; } - function specificKeywordCompletionInfo(entries: readonly CompletionEntry[], isNewIdentifierLocation: boolean): CompletionInfo { + function specificKeywordCompletionInfo(entries: readonly ts.CompletionEntry[], isNewIdentifierLocation: boolean): ts.CompletionInfo { return { isGlobalCompletion: false, isMemberCompletion: false, @@ -454,141 +421,62 @@ namespace ts.Completions { }; } - function keywordFiltersFromSyntaxKind(keywordCompletion: TokenSyntaxKind): KeywordCompletionFilters { + function keywordFiltersFromSyntaxKind(keywordCompletion: ts.TokenSyntaxKind): KeywordCompletionFilters { switch (keywordCompletion) { - case SyntaxKind.TypeKeyword: return KeywordCompletionFilters.TypeKeyword; - default: Debug.fail("Unknown mapping from SyntaxKind to KeywordCompletionFilters"); + case ts.SyntaxKind.TypeKeyword: return KeywordCompletionFilters.TypeKeyword; + default: ts.Debug.fail("Unknown mapping from SyntaxKind to KeywordCompletionFilters"); } } - function getOptionalReplacementSpan(location: Node | undefined) { + function getOptionalReplacementSpan(location: ts.Node | undefined) { // StringLiteralLike locations are handled separately in stringCompletions.ts - return location?.kind === SyntaxKind.Identifier ? createTextSpanFromNode(location) : undefined; + return location?.kind === ts.SyntaxKind.Identifier ? ts.createTextSpanFromNode(location) : undefined; } - - function completionInfoFromData( - sourceFile: SourceFile, - host: LanguageServiceHost, - program: Program, - compilerOptions: CompilerOptions, - log: Log, - completionData: CompletionData, - preferences: UserPreferences, - formatContext: formatting.FormatContext | undefined, - position: number - ): CompletionInfo | undefined { - const { - symbols, - contextToken, - completionKind, - isInSnippetScope, - isNewIdentifierLocation, - location, - propertyAccessToConvert, - keywordFilters, - literals, - symbolToOriginInfoMap, - recommendedCompletion, - isJsxInitializer, - isTypeOnlyLocation, - isJsxIdentifierExpected, - isRightOfOpenTag, - importCompletionNode, - insideJsDocTagTypeExpression, - symbolToSortTextMap: symbolToSortTextMap, - hasUnresolvedAutoImports, - } = completionData; + function completionInfoFromData(sourceFile: ts.SourceFile, host: ts.LanguageServiceHost, program: ts.Program, compilerOptions: ts.CompilerOptions, log: Log, completionData: CompletionData, preferences: ts.UserPreferences, formatContext: ts.formatting.FormatContext | undefined, position: number): ts.CompletionInfo | undefined { + const { symbols, contextToken, completionKind, isInSnippetScope, isNewIdentifierLocation, location, propertyAccessToConvert, keywordFilters, literals, symbolToOriginInfoMap, recommendedCompletion, isJsxInitializer, isTypeOnlyLocation, isJsxIdentifierExpected, isRightOfOpenTag, importCompletionNode, insideJsDocTagTypeExpression, symbolToSortTextMap: symbolToSortTextMap, hasUnresolvedAutoImports, } = completionData; // Verify if the file is JSX language variant - if (getLanguageVariant(sourceFile.scriptKind) === LanguageVariant.JSX) { + if (ts.getLanguageVariant(sourceFile.scriptKind) === ts.LanguageVariant.JSX) { const completionInfo = getJsxClosingTagCompletion(location, sourceFile); if (completionInfo) { return completionInfo; } } - const entries = createSortedArray(); + const entries = ts.createSortedArray(); if (isUncheckedFile(sourceFile, compilerOptions)) { - const uniqueNames = getCompletionEntriesFromSymbols( - symbols, - entries, - /*replacementToken*/ undefined, - contextToken, - location, - sourceFile, - host, - program, - getEmitScriptTarget(compilerOptions), - log, - completionKind, - preferences, - compilerOptions, - formatContext, - isTypeOnlyLocation, - propertyAccessToConvert, - isJsxIdentifierExpected, - isJsxInitializer, - importCompletionNode, - recommendedCompletion, - symbolToOriginInfoMap, - symbolToSortTextMap, - isJsxIdentifierExpected, - isRightOfOpenTag, - ); - getJSCompletionEntries(sourceFile, location.pos, uniqueNames, getEmitScriptTarget(compilerOptions), entries); + const uniqueNames = getCompletionEntriesFromSymbols(symbols, entries, + /*replacementToken*/ undefined, contextToken, location, sourceFile, host, program, ts.getEmitScriptTarget(compilerOptions), log, completionKind, preferences, compilerOptions, formatContext, isTypeOnlyLocation, propertyAccessToConvert, isJsxIdentifierExpected, isJsxInitializer, importCompletionNode, recommendedCompletion, symbolToOriginInfoMap, symbolToSortTextMap, isJsxIdentifierExpected, isRightOfOpenTag); + getJSCompletionEntries(sourceFile, location.pos, uniqueNames, ts.getEmitScriptTarget(compilerOptions), entries); } else { if (!isNewIdentifierLocation && (!symbols || symbols.length === 0) && keywordFilters === KeywordCompletionFilters.None) { return undefined; } - getCompletionEntriesFromSymbols( - symbols, - entries, - /*replacementToken*/ undefined, - contextToken, - location, - sourceFile, - host, - program, - getEmitScriptTarget(compilerOptions), - log, - completionKind, - preferences, - compilerOptions, - formatContext, - isTypeOnlyLocation, - propertyAccessToConvert, - isJsxIdentifierExpected, - isJsxInitializer, - importCompletionNode, - recommendedCompletion, - symbolToOriginInfoMap, - symbolToSortTextMap, - isJsxIdentifierExpected, - isRightOfOpenTag, - ); + getCompletionEntriesFromSymbols(symbols, entries, + /*replacementToken*/ undefined, contextToken, location, sourceFile, host, program, ts.getEmitScriptTarget(compilerOptions), log, completionKind, preferences, compilerOptions, formatContext, isTypeOnlyLocation, propertyAccessToConvert, isJsxIdentifierExpected, isJsxInitializer, importCompletionNode, recommendedCompletion, symbolToOriginInfoMap, symbolToSortTextMap, isJsxIdentifierExpected, isRightOfOpenTag); } if (keywordFilters !== KeywordCompletionFilters.None) { - const entryNames = new Set(entries.map(e => e.name)); - for (const keywordEntry of getKeywordCompletions(keywordFilters, !insideJsDocTagTypeExpression && isSourceFileJS(sourceFile))) { - if (isTypeOnlyLocation && isTypeKeyword(stringToToken(keywordEntry.name)!) || !entryNames.has(keywordEntry.name)) { - insertSorted(entries, keywordEntry, compareCompletionEntries, /*allowDuplicates*/ true); + const entryNames = new ts.Set(entries.map(e => e.name)); + for (const keywordEntry of getKeywordCompletions(keywordFilters, !insideJsDocTagTypeExpression && ts.isSourceFileJS(sourceFile))) { + if (isTypeOnlyLocation && ts.isTypeKeyword(ts.stringToToken(keywordEntry.name)!) || !entryNames.has(keywordEntry.name)) { + ts.insertSorted(entries, keywordEntry, compareCompletionEntries, /*allowDuplicates*/ true); } } } - const entryNames = new Set(entries.map(e => e.name)); + const entryNames = new ts.Set(entries.map(e => e.name)); for (const keywordEntry of getContextualKeywords(contextToken, position)) { if (!entryNames.has(keywordEntry.name)) { - insertSorted(entries, keywordEntry, compareCompletionEntries, /*allowDuplicates*/ true); + ts.insertSorted(entries, keywordEntry, compareCompletionEntries, /*allowDuplicates*/ true); } } for (const literal of literals) { - insertSorted(entries, createCompletionEntryForLiteral(sourceFile, preferences, literal), compareCompletionEntries, /*allowDuplicates*/ true); + ts.insertSorted(entries, createCompletionEntryForLiteral(sourceFile, preferences, literal), compareCompletionEntries, /*allowDuplicates*/ true); } return { @@ -602,8 +490,8 @@ namespace ts.Completions { }; } - function isUncheckedFile(sourceFile: SourceFile, compilerOptions: CompilerOptions): boolean { - return isSourceFileJS(sourceFile) && !isCheckJsEnabledForFile(sourceFile, compilerOptions); + function isUncheckedFile(sourceFile: ts.SourceFile, compilerOptions: ts.CompilerOptions): boolean { + return ts.isSourceFileJS(sourceFile) && !ts.isCheckJsEnabledForFile(sourceFile, compilerOptions); } function isMemberCompletionKind(kind: CompletionKind): boolean { @@ -617,21 +505,21 @@ namespace ts.Completions { } } - function getJsxClosingTagCompletion(location: Node | undefined, sourceFile: SourceFile): CompletionInfo | undefined { + function getJsxClosingTagCompletion(location: ts.Node | undefined, sourceFile: ts.SourceFile): ts.CompletionInfo | undefined { // We wanna walk up the tree till we find a JSX closing element - const jsxClosingElement = findAncestor(location, node => { + const jsxClosingElement = ts.findAncestor(location, node => { switch (node.kind) { - case SyntaxKind.JsxClosingElement: + case ts.SyntaxKind.JsxClosingElement: return true; - case SyntaxKind.SlashToken: - case SyntaxKind.GreaterThanToken: - case SyntaxKind.Identifier: - case SyntaxKind.PropertyAccessExpression: + case ts.SyntaxKind.SlashToken: + case ts.SyntaxKind.GreaterThanToken: + case ts.SyntaxKind.Identifier: + case ts.SyntaxKind.PropertyAccessExpression: return false; default: return "quit"; } - }) as JsxClosingElement | undefined; + }) as ts.JsxClosingElement | undefined; if (jsxClosingElement) { // In the TypeScript JSX element, if such element is not defined. When users query for completion at closing tag, @@ -646,15 +534,14 @@ namespace ts.Completions { // var x = // var y = // the completion list at "1" and "2" will contain "MainComponent.Child" with a replacement span of closing tag name - const hasClosingAngleBracket = !!findChildOfKind(jsxClosingElement, SyntaxKind.GreaterThanToken, sourceFile); + const hasClosingAngleBracket = !!ts.findChildOfKind(jsxClosingElement, ts.SyntaxKind.GreaterThanToken, sourceFile); const tagName = jsxClosingElement.parent.openingElement.tagName; const closingTag = tagName.getText(sourceFile); const fullClosingTag = closingTag + (hasClosingAngleBracket ? "" : ">"); - const replacementSpan = createTextSpanFromNode(jsxClosingElement.tagName); - - const entry: CompletionEntry = { + const replacementSpan = ts.createTextSpanFromNode(jsxClosingElement.tagName); + const entry: ts.CompletionEntry = { name: fullClosingTag, - kind: ScriptElementKind.classElement, + kind: ts.ScriptElementKind.classElement, kindModifiers: undefined, sortText: SortText.LocationPriority, }; @@ -663,23 +550,18 @@ namespace ts.Completions { return; } - function getJSCompletionEntries( - sourceFile: SourceFile, - position: number, - uniqueNames: UniqueNameSet, - target: ScriptTarget, - entries: SortedArray): void { - getNameTable(sourceFile).forEach((pos, name) => { + function getJSCompletionEntries(sourceFile: ts.SourceFile, position: number, uniqueNames: UniqueNameSet, target: ts.ScriptTarget, entries: ts.SortedArray): void { + ts.getNameTable(sourceFile).forEach((pos, name) => { // Skip identifiers produced only from the current location if (pos === position) { return; } - const realName = unescapeLeadingUnderscores(name); - if (!uniqueNames.has(realName) && isIdentifierText(realName, target)) { + const realName = ts.unescapeLeadingUnderscores(name); + if (!uniqueNames.has(realName) && ts.isIdentifierText(realName, target)) { uniqueNames.add(realName); - insertSorted(entries, { + ts.insertSorted(entries, { name: realName, - kind: ScriptElementKind.warning, + kind: ts.ScriptElementKind.warning, kindModifiers: "", sortText: SortText.JavascriptIdentifiers, isFromUncheckedFile: true @@ -688,42 +570,17 @@ namespace ts.Completions { }); } - function completionNameForLiteral(sourceFile: SourceFile, preferences: UserPreferences, literal: string | number | PseudoBigInt): string { - return typeof literal === "object" ? pseudoBigIntToString(literal) + "n" : - isString(literal) ? quote(sourceFile, preferences, literal) : JSON.stringify(literal); + function completionNameForLiteral(sourceFile: ts.SourceFile, preferences: ts.UserPreferences, literal: string | number | ts.PseudoBigInt): string { + return typeof literal === "object" ? ts.pseudoBigIntToString(literal) + "n" : + ts.isString(literal) ? ts.quote(sourceFile, preferences, literal) : JSON.stringify(literal); } - - function createCompletionEntryForLiteral(sourceFile: SourceFile, preferences: UserPreferences, literal: string | number | PseudoBigInt): CompletionEntry { - return { name: completionNameForLiteral(sourceFile, preferences, literal), kind: ScriptElementKind.string, kindModifiers: ScriptElementKindModifier.none, sortText: SortText.LocationPriority }; + function createCompletionEntryForLiteral(sourceFile: ts.SourceFile, preferences: ts.UserPreferences, literal: string | number | ts.PseudoBigInt): ts.CompletionEntry { + return { name: completionNameForLiteral(sourceFile, preferences, literal), kind: ts.ScriptElementKind.string, kindModifiers: ts.ScriptElementKindModifier.none, sortText: SortText.LocationPriority }; } - - function createCompletionEntry( - symbol: Symbol, - sortText: SortText, - replacementToken: Node | undefined, - contextToken: Node | undefined, - location: Node, - sourceFile: SourceFile, - host: LanguageServiceHost, - program: Program, - name: string, - needsConvertPropertyAccess: boolean, - origin: SymbolOriginInfo | undefined, - recommendedCompletion: Symbol | undefined, - propertyAccessToConvert: PropertyAccessExpression | undefined, - isJsxInitializer: IsJsxInitializer | undefined, - importCompletionNode: Node | undefined, - useSemicolons: boolean, - options: CompilerOptions, - preferences: UserPreferences, - completionKind: CompletionKind, - formatContext: formatting.FormatContext | undefined, - isJsxIdentifierExpected: boolean | undefined, - isRightOfOpenTag: boolean | undefined, - ): CompletionEntry | undefined { + function createCompletionEntry(symbol: ts.Symbol, sortText: SortText, replacementToken: ts.Node | undefined, contextToken: ts.Node | undefined, location: ts.Node, sourceFile: ts.SourceFile, host: ts.LanguageServiceHost, program: ts.Program, name: string, needsConvertPropertyAccess: boolean, origin: SymbolOriginInfo | undefined, recommendedCompletion: ts.Symbol | undefined, propertyAccessToConvert: ts.PropertyAccessExpression | undefined, isJsxInitializer: IsJsxInitializer | undefined, importCompletionNode: ts.Node | undefined, useSemicolons: boolean, options: ts.CompilerOptions, preferences: ts.UserPreferences, completionKind: CompletionKind, formatContext: ts.formatting.FormatContext | undefined, isJsxIdentifierExpected: boolean | undefined, isRightOfOpenTag: boolean | undefined): ts.CompletionEntry | undefined { let insertText: string | undefined; - let replacementSpan = getReplacementSpanForContextToken(replacementToken); - let data: CompletionEntryData | undefined; + let replacementSpan = ts.getReplacementSpanForContextToken(replacementToken); + let data: ts.CompletionEntryData | undefined; let isSnippet: true | undefined; let source = getSourceFromOrigin(origin); let sourceDisplay; @@ -746,38 +603,40 @@ namespace ts.Completions { insertText = `?.${insertText}`; } - const dot = findChildOfKind(propertyAccessToConvert, SyntaxKind.DotToken, sourceFile) || - findChildOfKind(propertyAccessToConvert, SyntaxKind.QuestionDotToken, sourceFile); + const dot = ts.findChildOfKind(propertyAccessToConvert, ts.SyntaxKind.DotToken, sourceFile) || + ts.findChildOfKind(propertyAccessToConvert, ts.SyntaxKind.QuestionDotToken, sourceFile); if (!dot) { return undefined; } // If the text after the '.' starts with this name, write over it. Else, add new text. - const end = startsWith(name, propertyAccessToConvert.name.text) ? propertyAccessToConvert.name.end : dot.end; - replacementSpan = createTextSpanFromBounds(dot.getStart(sourceFile), end); + const end = ts.startsWith(name, propertyAccessToConvert.name.text) ? propertyAccessToConvert.name.end : dot.end; + replacementSpan = ts.createTextSpanFromBounds(dot.getStart(sourceFile), end); } if (isJsxInitializer) { - if (insertText === undefined) insertText = name; + if (insertText === undefined) + insertText = name; insertText = `{${insertText}}`; if (typeof isJsxInitializer !== "boolean") { - replacementSpan = createTextSpanFromNode(isJsxInitializer, sourceFile); + replacementSpan = ts.createTextSpanFromNode(isJsxInitializer, sourceFile); } } if (origin && originIsPromise(origin) && propertyAccessToConvert) { - if (insertText === undefined) insertText = name; - const precedingToken = findPrecedingToken(propertyAccessToConvert.pos, sourceFile); + if (insertText === undefined) + insertText = name; + const precedingToken = ts.findPrecedingToken(propertyAccessToConvert.pos, sourceFile); let awaitText = ""; - if (precedingToken && positionIsASICandidate(precedingToken.end, precedingToken.parent, sourceFile)) { + if (precedingToken && ts.positionIsASICandidate(precedingToken.end, precedingToken.parent, sourceFile)) { awaitText = ";"; } awaitText += `(await ${propertyAccessToConvert.expression.getText()})`; insertText = needsConvertPropertyAccess ? `${awaitText}${insertText}` : `${awaitText}${insertQuestionDot ? "?." : "."}${insertText}`; - replacementSpan = createTextSpanFromBounds(propertyAccessToConvert.getStart(sourceFile), propertyAccessToConvert.end); + replacementSpan = ts.createTextSpanFromBounds(propertyAccessToConvert.getStart(sourceFile), propertyAccessToConvert.end); } if (originIsResolvedExport(origin)) { - sourceDisplay = [textPart(origin.moduleSpecifier)]; + sourceDisplay = [ts.textPart(origin.moduleSpecifier)]; if (importCompletionNode) { ({ insertText, replacementSpan } = getInsertTextAndReplacementSpanForImportCompletion(name, importCompletionNode, contextToken, origin, useSemicolons, options, preferences)); isSnippet = preferences.includeCompletionsWithSnippetText ? true : undefined; @@ -817,12 +676,11 @@ namespace ts.Completions { // If is boolean like or undefined, don't return a snippet we want just to return the completion. if (preferences.jsxAttributeCompletionStyle === "auto" - && !(type.flags & TypeFlags.BooleanLike) - && !(type.flags & TypeFlags.Union && find((type as UnionType).types, type => !!(type.flags & TypeFlags.BooleanLike))) - ) { - if (type.flags & TypeFlags.StringLike || (type.flags & TypeFlags.Union && every((type as UnionType).types, type => !!(type.flags & (TypeFlags.StringLike | TypeFlags.Undefined))))) { + && !(type.flags & ts.TypeFlags.BooleanLike) + && !(type.flags & ts.TypeFlags.Union && ts.find((type as ts.UnionType).types, type => !!(type.flags & ts.TypeFlags.BooleanLike)))) { + if (type.flags & ts.TypeFlags.StringLike || (type.flags & ts.TypeFlags.Union && ts.every((type as ts.UnionType).types, type => !!(type.flags & (ts.TypeFlags.StringLike | ts.TypeFlags.Undefined))))) { // If is string like or undefined use quotes - insertText = `${escapeSnippetText(name)}=${quote(sourceFile, preferences, "$1")}`; + insertText = `${ts.escapeSnippetText(name)}=${ts.quote(sourceFile, preferences, "$1")}`; isSnippet = true; } else { @@ -832,7 +690,7 @@ namespace ts.Completions { } if (useBraces) { - insertText = `${escapeSnippetText(name)}={$1}`; + insertText = `${ts.escapeSnippetText(name)}={$1}`; isSnippet = true; } } @@ -856,8 +714,8 @@ namespace ts.Completions { // entries (like JavaScript identifier entries). return { name, - kind: SymbolDisplay.getSymbolKind(typeChecker, symbol, location), - kindModifiers: SymbolDisplay.getSymbolModifiers(typeChecker, symbol), + kind: ts.SymbolDisplay.getSymbolKind(typeChecker, symbol, location), + kindModifiers: ts.SymbolDisplay.getSymbolModifiers(typeChecker, symbol), sortText, source, hasAction: hasAction ? true : undefined, @@ -873,16 +731,15 @@ namespace ts.Completions { }; } - function isClassLikeMemberCompletion(symbol: Symbol, location: Node): boolean { + function isClassLikeMemberCompletion(symbol: ts.Symbol, location: ts.Node): boolean { // TODO: support JS files. - if (isInJSFile(location)) { + if (ts.isInJSFile(location)) { return false; } // Completion symbol must be for a class member. - const memberFlags = - SymbolFlags.ClassMember - & SymbolFlags.EnumMemberExcludes; + const memberFlags = ts.SymbolFlags.ClassMember + & ts.SymbolFlags.EnumMemberExcludes; /* In `class C { | @@ -904,41 +761,29 @@ namespace ts.Completions { and `location.parent` is a class-like declaration. */ return !!(symbol.flags & memberFlags) && - ( - isClassLike(location) || - ( - location.parent && + (ts.isClassLike(location) || + (location.parent && location.parent.parent && - isClassElement(location.parent) && + ts.isClassElement(location.parent) && location === location.parent.name && - isClassLike(location.parent.parent) - ) || - ( - location.parent && - isSyntaxList(location) && - isClassLike(location.parent) - ) - ); - } - - function getEntryForMemberCompletion( - host: LanguageServiceHost, - program: Program, - options: CompilerOptions, - preferences: UserPreferences, - name: string, - symbol: Symbol, - location: Node, - contextToken: Node | undefined, - formatContext: formatting.FormatContext | undefined, - ): { insertText: string, isSnippet?: true, importAdder?: codefix.ImportAdder, replacementSpan?: TextSpan } { - const classLikeDeclaration = findAncestor(location, isClassLike); + ts.isClassLike(location.parent.parent)) || + (location.parent && + ts.isSyntaxList(location) && + ts.isClassLike(location.parent))); + } + function getEntryForMemberCompletion(host: ts.LanguageServiceHost, program: ts.Program, options: ts.CompilerOptions, preferences: ts.UserPreferences, name: string, symbol: ts.Symbol, location: ts.Node, contextToken: ts.Node | undefined, formatContext: ts.formatting.FormatContext | undefined): { + insertText: string; + isSnippet?: true; + importAdder?: ts.codefix.ImportAdder; + replacementSpan?: ts.TextSpan; + } { + const classLikeDeclaration = ts.findAncestor(location, ts.isClassLike); if (!classLikeDeclaration) { return { insertText: name }; } let isSnippet: true | undefined; - let replacementSpan: TextSpan | undefined; + let replacementSpan: ts.TextSpan | undefined; let insertText: string = name; const checker = program.getTypeChecker(); @@ -948,9 +793,9 @@ namespace ts.Completions { module: options.module, target: options.target, omitTrailingSemicolon: false, - newLine: getNewLineKind(getNewLineCharacter(options, maybeBind(host, host.getNewLine))), + newLine: ts.getNewLineKind(ts.getNewLineCharacter(options, ts.maybeBind(host, host.getNewLine))), }); - const importAdder = codefix.createImportAdder(sourceFile, program, preferences, host); + const importAdder = ts.codefix.createImportAdder(sourceFile, program, preferences, host); // Create empty body for possible method implementation. let body; @@ -959,27 +804,21 @@ namespace ts.Completions { // We are adding a tabstop (i.e. `$0`) in the body of the suggested member, // if it has one, so that the cursor ends up in the body once the completion is inserted. // Note: this assumes we won't have more than one body in the completion nodes, which should be the case. - const emptyStmt = factory.createEmptyStatement(); - body = factory.createBlock([emptyStmt], /* multiline */ true); - setSnippetElement(emptyStmt, { kind: SnippetKind.TabStop, order: 0 }); + const emptyStmt = ts.factory.createEmptyStatement(); + body = ts.factory.createBlock([emptyStmt], /* multiline */ true); + ts.setSnippetElement(emptyStmt, { kind: ts.SnippetKind.TabStop, order: 0 }); } else { - body = factory.createBlock([], /* multiline */ true); + body = ts.factory.createBlock([], /* multiline */ true); } - let modifiers = ModifierFlags.None; + let modifiers = ts.ModifierFlags.None; // Whether the suggested member should be abstract. // e.g. in `abstract class C { abstract | }`, we should offer abstract method signatures at position `|`. const { modifiers: presentModifiers, span: modifiersSpan } = getPresentModifiers(contextToken); - const isAbstract = !!(presentModifiers & ModifierFlags.Abstract); - const completionNodes: Node[] = []; - codefix.addNewNodeForMemberSymbol( - symbol, - classLikeDeclaration, - sourceFile, - { program, host }, - preferences, - importAdder, + const isAbstract = !!(presentModifiers & ts.ModifierFlags.Abstract); + const completionNodes: ts.Node[] = []; + ts.codefix.addNewNodeForMemberSymbol(symbol, classLikeDeclaration, sourceFile, { program, host }, preferences, importAdder, // `addNewNodeForMemberSymbol` calls this callback function for each new member node // it adds for the given member symbol. // We store these member nodes in the `completionNodes` array. @@ -988,13 +827,13 @@ namespace ts.Completions { // - One node; // - More than one node if the member is overloaded (e.g. a method with overload signatures). node => { - let requiredModifiers = ModifierFlags.None; + let requiredModifiers = ts.ModifierFlags.None; if (isAbstract) { - requiredModifiers |= ModifierFlags.Abstract; + requiredModifiers |= ts.ModifierFlags.Abstract; } - if (isClassElement(node) - && checker.getMemberOverrideModifierStatus(classLikeDeclaration, node) === MemberOverrideStatus.NeedsOverride) { - requiredModifiers |= ModifierFlags.Override; + if (ts.isClassElement(node) + && checker.getMemberOverrideModifierStatus(classLikeDeclaration, node) === ts.MemberOverrideStatus.NeedsOverride) { + requiredModifiers |= ts.ModifierFlags.Override; } if (!completionNodes.length) { @@ -1004,41 +843,34 @@ namespace ts.Completions { // and we need to make sure the modifiers are uniform for all nodes/signatures. modifiers = node.modifierFlagsCache | requiredModifiers | presentModifiers; } - node = factory.updateModifiers(node, modifiers); + node = ts.factory.updateModifiers(node, modifiers); completionNodes.push(node); - }, - body, - codefix.PreserveOptionalFlags.Property, - isAbstract); + }, body, ts.codefix.PreserveOptionalFlags.Property, isAbstract); if (completionNodes.length) { - const format = ListFormat.MultiLine | ListFormat.NoTrailingNewLine; + const format = ts.ListFormat.MultiLine | ts.ListFormat.NoTrailingNewLine; replacementSpan = modifiersSpan; // If we have access to formatting settings, we print the nodes using the emitter, // and then format the printed text. if (formatContext) { - insertText = printer.printAndFormatSnippetList( - format, - factory.createNodeArray(completionNodes), - sourceFile, - formatContext); + insertText = printer.printAndFormatSnippetList(format, ts.factory.createNodeArray(completionNodes), sourceFile, formatContext); } else { // Otherwise, just use emitter to print the new nodes. - insertText = printer.printSnippetList( - format, - factory.createNodeArray(completionNodes), - sourceFile); + insertText = printer.printSnippetList(format, ts.factory.createNodeArray(completionNodes), sourceFile); } } return { insertText, isSnippet, importAdder, replacementSpan }; } - function getPresentModifiers(contextToken: Node | undefined): { modifiers: ModifierFlags, span?: TextSpan } { + function getPresentModifiers(contextToken: ts.Node | undefined): { + modifiers: ts.ModifierFlags; + span?: ts.TextSpan; + } { if (!contextToken) { - return { modifiers: ModifierFlags.None }; + return { modifiers: ts.ModifierFlags.None }; } - let modifiers = ModifierFlags.None; + let modifiers = ts.ModifierFlags.None; let span; let contextMod; /* @@ -1061,36 +893,31 @@ namespace ts.Completions { `location.parent.parent` is class declaration ``class C { ... }``. */ if (contextMod = isModifierLike(contextToken)) { - modifiers |= modifierToFlag(contextMod); - span = createTextSpanFromNode(contextToken); + modifiers |= ts.modifierToFlag(contextMod); + span = ts.createTextSpanFromNode(contextToken); } - if (isPropertyDeclaration(contextToken.parent)) { - modifiers |= modifiersToFlags(contextToken.parent.modifiers); - span = createTextSpanFromNode(contextToken.parent); + if (ts.isPropertyDeclaration(contextToken.parent)) { + modifiers |= ts.modifiersToFlags(contextToken.parent.modifiers); + span = ts.createTextSpanFromNode(contextToken.parent); } return { modifiers, span }; } - function isModifierLike(node: Node): ModifierSyntaxKind | undefined { - if (isModifier(node)) { + function isModifierLike(node: ts.Node): ts.ModifierSyntaxKind | undefined { + if (ts.isModifier(node)) { return node.kind; } - if (isIdentifier(node) && node.originalKeywordKind && isModifierKind(node.originalKeywordKind)) { + if (ts.isIdentifier(node) && node.originalKeywordKind && ts.isModifierKind(node.originalKeywordKind)) { return node.originalKeywordKind; } return undefined; } - function getEntryForObjectLiteralMethodCompletion( - symbol: Symbol, - name: string, - enclosingDeclaration: ObjectLiteralExpression, - program: Program, - host: LanguageServiceHost, - options: CompilerOptions, - preferences: UserPreferences, - formatContext: formatting.FormatContext | undefined, - ): { insertText: string, isSnippet?: true, labelDetails: CompletionEntryLabelDetails } | undefined { + function getEntryForObjectLiteralMethodCompletion(symbol: ts.Symbol, name: string, enclosingDeclaration: ts.ObjectLiteralExpression, program: ts.Program, host: ts.LanguageServiceHost, options: ts.CompilerOptions, preferences: ts.UserPreferences, formatContext: ts.formatting.FormatContext | undefined): { + insertText: string; + isSnippet?: true; + labelDetails: ts.CompletionEntryLabelDetails; + } | undefined { const isSnippet = preferences.includeCompletionsWithSnippetText || undefined; let insertText: string = name; @@ -1106,16 +933,16 @@ namespace ts.Completions { module: options.module, target: options.target, omitTrailingSemicolon: false, - newLine: getNewLineKind(getNewLineCharacter(options, maybeBind(host, host.getNewLine))), + newLine: ts.getNewLineKind(ts.getNewLineCharacter(options, ts.maybeBind(host, host.getNewLine))), }); if (formatContext) { - insertText = printer.printAndFormatSnippetList(ListFormat.CommaDelimited | ListFormat.AllowTrailingComma, factory.createNodeArray([method], /*hasTrailingComma*/ true), sourceFile, formatContext); + insertText = printer.printAndFormatSnippetList(ts.ListFormat.CommaDelimited | ts.ListFormat.AllowTrailingComma, ts.factory.createNodeArray([method], /*hasTrailingComma*/ true), sourceFile, formatContext); } else { - insertText = printer.printSnippetList(ListFormat.CommaDelimited | ListFormat.AllowTrailingComma, factory.createNodeArray([method], /*hasTrailingComma*/ true), sourceFile); + insertText = printer.printSnippetList(ts.ListFormat.CommaDelimited | ts.ListFormat.AllowTrailingComma, ts.factory.createNodeArray([method], /*hasTrailingComma*/ true), sourceFile); } - const signaturePrinter = createPrinter({ + const signaturePrinter = ts.createPrinter({ removeComments: true, module: options.module, target: options.target, @@ -1123,49 +950,38 @@ namespace ts.Completions { }); // The `labelDetails.detail` will be displayed right beside the method name, // so we drop the name (and modifiers) from the signature. - const methodSignature = factory.createMethodSignature( + const methodSignature = ts.factory.createMethodSignature( /*modifiers*/ undefined, - /*name*/ "", - method.questionToken, - method.typeParameters, - method.parameters, - method.type); - const labelDetails = { detail: signaturePrinter.printNode(EmitHint.Unspecified, methodSignature, sourceFile) }; + /*name*/ "", method.questionToken, method.typeParameters, method.parameters, method.type); + const labelDetails = { detail: signaturePrinter.printNode(ts.EmitHint.Unspecified, methodSignature, sourceFile) }; return { isSnippet, insertText, labelDetails }; - }; - - function createObjectLiteralMethod( - symbol: Symbol, - enclosingDeclaration: ObjectLiteralExpression, - sourceFile: SourceFile, - program: Program, - host: LanguageServiceHost, - preferences: UserPreferences, - ): MethodDeclaration | undefined { + } + ; + function createObjectLiteralMethod(symbol: ts.Symbol, enclosingDeclaration: ts.ObjectLiteralExpression, sourceFile: ts.SourceFile, program: ts.Program, host: ts.LanguageServiceHost, preferences: ts.UserPreferences): ts.MethodDeclaration | undefined { const declarations = symbol.getDeclarations(); if (!(declarations && declarations.length)) { return undefined; } const checker = program.getTypeChecker(); const declaration = declarations[0]; - const name = getSynthesizedDeepClone(getNameOfDeclaration(declaration), /*includeTrivia*/ false) as PropertyName; + const name = ts.getSynthesizedDeepClone(ts.getNameOfDeclaration(declaration), /*includeTrivia*/ false) as ts.PropertyName; const type = checker.getWidenedType(checker.getTypeOfSymbolAtLocation(symbol, enclosingDeclaration)); - const quotePreference = getQuotePreference(sourceFile, preferences); - const builderFlags = quotePreference === QuotePreference.Single ? NodeBuilderFlags.UseSingleQuotesForStringLiteralType : undefined; + const quotePreference = ts.getQuotePreference(sourceFile, preferences); + const builderFlags = quotePreference === ts.QuotePreference.Single ? ts.NodeBuilderFlags.UseSingleQuotesForStringLiteralType : undefined; switch (declaration.kind) { - case SyntaxKind.PropertySignature: - case SyntaxKind.PropertyDeclaration: - case SyntaxKind.MethodSignature: - case SyntaxKind.MethodDeclaration: { - let effectiveType = type.flags & TypeFlags.Union && (type as UnionType).types.length < 10 - ? checker.getUnionType((type as UnionType).types, UnionReduction.Subtype) + case ts.SyntaxKind.PropertySignature: + case ts.SyntaxKind.PropertyDeclaration: + case ts.SyntaxKind.MethodSignature: + case ts.SyntaxKind.MethodDeclaration: { + let effectiveType = type.flags & ts.TypeFlags.Union && (type as ts.UnionType).types.length < 10 + ? checker.getUnionType((type as ts.UnionType).types, ts.UnionReduction.Subtype) : type; - if (effectiveType.flags & TypeFlags.Union) { + if (effectiveType.flags & ts.TypeFlags.Union) { // Only offer the completion if there's a single function type component. - const functionTypes = filter((effectiveType as UnionType).types, type => checker.getSignaturesOfType(type, SignatureKind.Call).length > 0); + const functionTypes = ts.filter((effectiveType as ts.UnionType).types, type => checker.getSignaturesOfType(type, ts.SignatureKind.Call).length > 0); if (functionTypes.length === 1) { effectiveType = functionTypes[0]; } @@ -1173,59 +989,48 @@ namespace ts.Completions { return undefined; } } - const signatures = checker.getSignaturesOfType(effectiveType, SignatureKind.Call); + const signatures = checker.getSignaturesOfType(effectiveType, ts.SignatureKind.Call); if (signatures.length !== 1) { // We don't support overloads in object literals. return undefined; } - const typeNode = checker.typeToTypeNode(effectiveType, enclosingDeclaration, builderFlags, codefix.getNoopSymbolTrackerWithResolver({ program, host })); - if (!typeNode || !isFunctionTypeNode(typeNode)) { + const typeNode = checker.typeToTypeNode(effectiveType, enclosingDeclaration, builderFlags, ts.codefix.getNoopSymbolTrackerWithResolver({ program, host })); + if (!typeNode || !ts.isFunctionTypeNode(typeNode)) { return undefined; } let body; if (preferences.includeCompletionsWithSnippetText) { - const emptyStmt = factory.createEmptyStatement(); - body = factory.createBlock([emptyStmt], /* multiline */ true); - setSnippetElement(emptyStmt, { kind: SnippetKind.TabStop, order: 0 }); + const emptyStmt = ts.factory.createEmptyStatement(); + body = ts.factory.createBlock([emptyStmt], /* multiline */ true); + ts.setSnippetElement(emptyStmt, { kind: ts.SnippetKind.TabStop, order: 0 }); } else { - body = factory.createBlock([], /* multiline */ true); + body = ts.factory.createBlock([], /* multiline */ true); } - const parameters = typeNode.parameters.map(typedParam => - factory.createParameterDeclaration( + const parameters = typeNode.parameters.map(typedParam => ts.factory.createParameterDeclaration( /*decorators*/ undefined, - /*modifiers*/ undefined, - typedParam.dotDotDotToken, - typedParam.name, - typedParam.questionToken, - /*type*/ undefined, - typedParam.initializer, - )); - return factory.createMethodDeclaration( + /*modifiers*/ undefined, typedParam.dotDotDotToken, typedParam.name, typedParam.questionToken, + /*type*/ undefined, typedParam.initializer)); + return ts.factory.createMethodDeclaration( /*decorators*/ undefined, /*modifiers*/ undefined, - /*asteriskToken*/ undefined, - name, + /*asteriskToken*/ undefined, name, /*questionToken*/ undefined, - /*typeParameters*/ undefined, - parameters, - /*type*/ undefined, - body); + /*typeParameters*/ undefined, parameters, + /*type*/ undefined, body); } default: return undefined; } } - function createSnippetPrinter( - printerOptions: PrinterOptions, - ) { - let escapes: TextChange[] | undefined; - const baseWriter = textChanges.createWriter(getNewLineCharacter(printerOptions)); - const printer = createPrinter(printerOptions, baseWriter); - const writer: EmitTextWriter = { + function createSnippetPrinter(printerOptions: ts.PrinterOptions) { + let escapes: ts.TextChange[] | undefined; + const baseWriter = ts.textChanges.createWriter(ts.getNewLineCharacter(printerOptions)); + const printer = ts.createPrinter(printerOptions, baseWriter); + const writer: ts.EmitTextWriter = { ...baseWriter, write: s => escapingWrite(s, () => baseWriter.write(s)), nonEscapingWrite: baseWriter.write, @@ -1247,12 +1052,12 @@ namespace ts.Completions { // generate a set of changes that can be applied to the unescaped text // to escape it post-formatting. function escapingWrite(s: string, write: () => void) { - const escaped = escapeSnippetText(s); + const escaped = ts.escapeSnippetText(s); if (escaped !== s) { const start = baseWriter.getTextPos(); write(); const end = baseWriter.getTextPos(); - escapes = append(escapes ||= [], { newText: escaped, span: { start, length: end - start } }); + escapes = ts.append(escapes ||= [], { newText: escaped, span: { start, length: end - start } }); } else { write(); @@ -1260,66 +1065,45 @@ namespace ts.Completions { } /* Snippet-escaping version of `printer.printList`. */ - function printSnippetList( - format: ListFormat, - list: NodeArray, - sourceFile: SourceFile | undefined, - ): string { + function printSnippetList(format: ts.ListFormat, list: ts.NodeArray, sourceFile: ts.SourceFile | undefined): string { const unescaped = printUnescapedSnippetList(format, list, sourceFile); - return escapes ? textChanges.applyChanges(unescaped, escapes) : unescaped; + return escapes ? ts.textChanges.applyChanges(unescaped, escapes) : unescaped; } - - function printUnescapedSnippetList( - format: ListFormat, - list: NodeArray, - sourceFile: SourceFile | undefined, - ): string { + function printUnescapedSnippetList(format: ts.ListFormat, list: ts.NodeArray, sourceFile: ts.SourceFile | undefined): string { escapes = undefined; writer.clear(); printer.writeList(format, list, sourceFile, writer); return writer.getText(); } - function printAndFormatSnippetList( - format: ListFormat, - list: NodeArray, - sourceFile: SourceFile, - formatContext: formatting.FormatContext, - ): string { + function printAndFormatSnippetList(format: ts.ListFormat, list: ts.NodeArray, sourceFile: ts.SourceFile, formatContext: ts.formatting.FormatContext): string { const syntheticFile = { - text: printUnescapedSnippetList( - format, - list, - sourceFile), + text: printUnescapedSnippetList(format, list, sourceFile), getLineAndCharacterOfPosition(pos: number) { - return getLineAndCharacterOfPosition(this, pos); + return ts.getLineAndCharacterOfPosition(this, pos); }, }; - const formatOptions = getFormatCodeSettingsForWriting(formatContext, sourceFile); - const changes = flatMap(list, node => { - const nodeWithPos = textChanges.assignPositionsToNode(node); - return formatting.formatNodeGivenIndentation( - nodeWithPos, - syntheticFile, - sourceFile.languageVariant, + const formatOptions = ts.getFormatCodeSettingsForWriting(formatContext, sourceFile); + const changes = ts.flatMap(list, node => { + const nodeWithPos = ts.textChanges.assignPositionsToNode(node); + return ts.formatting.formatNodeGivenIndentation(nodeWithPos, syntheticFile, sourceFile.languageVariant, /* indentation */ 0, - /* delta */ 0, - { ...formatContext, options: formatOptions }); + /* delta */ 0, { ...formatContext, options: formatOptions }); }); const allChanges = escapes - ? stableSort(concatenate(changes, escapes), (a, b) => compareTextSpans(a.span, b.span)) + ? ts.stableSort(ts.concatenate(changes, escapes), (a, b) => ts.compareTextSpans(a.span, b.span)) : changes; - return textChanges.applyChanges(syntheticFile.text, allChanges); + return ts.textChanges.applyChanges(syntheticFile.text, allChanges); } } - function originToCompletionEntryData(origin: SymbolOriginInfoExport | SymbolOriginInfoResolvedExport): CompletionEntryData | undefined { - const ambientModuleName = origin.fileName ? undefined : stripQuotes(origin.moduleSymbol.name); + function originToCompletionEntryData(origin: SymbolOriginInfoExport | SymbolOriginInfoResolvedExport): ts.CompletionEntryData | undefined { + const ambientModuleName = origin.fileName ? undefined : ts.stripQuotes(origin.moduleSymbol.name); const isPackageJsonImport = origin.isFromPackageJson ? true : undefined; if (originIsResolvedExport(origin)) { - const resolvedData: CompletionEntryDataResolved = { + const resolvedData: ts.CompletionEntryDataResolved = { exportName: origin.exportName, moduleSpecifier: origin.moduleSpecifier, ambientModuleName, @@ -1328,18 +1112,18 @@ namespace ts.Completions { }; return resolvedData; } - const unresolvedData: CompletionEntryDataUnresolved = { + const unresolvedData: ts.CompletionEntryDataUnresolved = { exportName: origin.exportName, exportMapKey: origin.exportMapKey, fileName: origin.fileName, - ambientModuleName: origin.fileName ? undefined : stripQuotes(origin.moduleSymbol.name), + ambientModuleName: origin.fileName ? undefined : ts.stripQuotes(origin.moduleSymbol.name), isPackageJsonImport: origin.isFromPackageJson ? true : undefined, }; return unresolvedData; } - function completionEntryDataToSymbolOriginInfo(data: CompletionEntryData, completionName: string, moduleSymbol: Symbol): SymbolOriginInfoExport | SymbolOriginInfoResolvedExport { - const isDefaultExport = data.exportName === InternalSymbolName.Default; + function completionEntryDataToSymbolOriginInfo(data: ts.CompletionEntryData, completionName: string, moduleSymbol: ts.Symbol): SymbolOriginInfoExport | SymbolOriginInfoResolvedExport { + const isDefaultExport = data.exportName === ts.InternalSymbolName.Default; const isFromPackageJson = !!data.isPackageJsonImport; if (completionEntryDataIsResolved(data)) { const resolvedOrigin: SymbolOriginInfoResolvedExport = { @@ -1367,45 +1151,44 @@ namespace ts.Completions { return unresolvedOrigin; } - function getInsertTextAndReplacementSpanForImportCompletion(name: string, importCompletionNode: Node, contextToken: Node | undefined, origin: SymbolOriginInfoResolvedExport, useSemicolons: boolean, options: CompilerOptions, preferences: UserPreferences) { + function getInsertTextAndReplacementSpanForImportCompletion(name: string, importCompletionNode: ts.Node, contextToken: ts.Node | undefined, origin: SymbolOriginInfoResolvedExport, useSemicolons: boolean, options: ts.CompilerOptions, preferences: ts.UserPreferences) { const sourceFile = importCompletionNode.getSourceFile(); - const replacementSpan = createTextSpanFromNode(findAncestor(importCompletionNode, or(isImportDeclaration, isImportEqualsDeclaration)) || importCompletionNode, sourceFile); - const quotedModuleSpecifier = quote(sourceFile, preferences, origin.moduleSpecifier); - const exportKind = - origin.isDefaultExport ? ExportKind.Default : - origin.exportName === InternalSymbolName.ExportEquals ? ExportKind.ExportEquals : - ExportKind.Named; + const replacementSpan = ts.createTextSpanFromNode(ts.findAncestor(importCompletionNode, ts.or(ts.isImportDeclaration, ts.isImportEqualsDeclaration)) || importCompletionNode, sourceFile); + const quotedModuleSpecifier = ts.quote(sourceFile, preferences, origin.moduleSpecifier); + const exportKind = origin.isDefaultExport ? ts.ExportKind.Default : + origin.exportName === ts.InternalSymbolName.ExportEquals ? ts.ExportKind.ExportEquals : + ts.ExportKind.Named; const tabStop = preferences.includeCompletionsWithSnippetText ? "$1" : ""; - const importKind = codefix.getImportKind(sourceFile, exportKind, options, /*forceImportKeyword*/ true); - const isTopLevelTypeOnly = tryCast(importCompletionNode, isImportDeclaration)?.importClause?.isTypeOnly || tryCast(importCompletionNode, isImportEqualsDeclaration)?.isTypeOnly; + const importKind = ts.codefix.getImportKind(sourceFile, exportKind, options, /*forceImportKeyword*/ true); + const isTopLevelTypeOnly = ts.tryCast(importCompletionNode, ts.isImportDeclaration)?.importClause?.isTypeOnly || ts.tryCast(importCompletionNode, ts.isImportEqualsDeclaration)?.isTypeOnly; const isImportSpecifierTypeOnly = couldBeTypeOnlyImportSpecifier(importCompletionNode, contextToken); - const topLevelTypeOnlyText = isTopLevelTypeOnly ? ` ${tokenToString(SyntaxKind.TypeKeyword)} ` : " "; - const importSpecifierTypeOnlyText = isImportSpecifierTypeOnly ? `${tokenToString(SyntaxKind.TypeKeyword)} ` : ""; + const topLevelTypeOnlyText = isTopLevelTypeOnly ? ` ${ts.tokenToString(ts.SyntaxKind.TypeKeyword)} ` : " "; + const importSpecifierTypeOnlyText = isImportSpecifierTypeOnly ? `${ts.tokenToString(ts.SyntaxKind.TypeKeyword)} ` : ""; const suffix = useSemicolons ? ";" : ""; switch (importKind) { - case ImportKind.CommonJS: return { replacementSpan, insertText: `import${topLevelTypeOnlyText}${escapeSnippetText(name)}${tabStop} = require(${quotedModuleSpecifier})${suffix}` }; - case ImportKind.Default: return { replacementSpan, insertText: `import${topLevelTypeOnlyText}${escapeSnippetText(name)}${tabStop} from ${quotedModuleSpecifier}${suffix}` }; - case ImportKind.Namespace: return { replacementSpan, insertText: `import${topLevelTypeOnlyText}* as ${escapeSnippetText(name)} from ${quotedModuleSpecifier}${suffix}` }; - case ImportKind.Named: return { replacementSpan, insertText: `import${topLevelTypeOnlyText}{ ${importSpecifierTypeOnlyText}${escapeSnippetText(name)}${tabStop} } from ${quotedModuleSpecifier}${suffix}` }; + case ts.ImportKind.CommonJS: return { replacementSpan, insertText: `import${topLevelTypeOnlyText}${ts.escapeSnippetText(name)}${tabStop} = require(${quotedModuleSpecifier})${suffix}` }; + case ts.ImportKind.Default: return { replacementSpan, insertText: `import${topLevelTypeOnlyText}${ts.escapeSnippetText(name)}${tabStop} from ${quotedModuleSpecifier}${suffix}` }; + case ts.ImportKind.Namespace: return { replacementSpan, insertText: `import${topLevelTypeOnlyText}* as ${ts.escapeSnippetText(name)} from ${quotedModuleSpecifier}${suffix}` }; + case ts.ImportKind.Named: return { replacementSpan, insertText: `import${topLevelTypeOnlyText}{ ${importSpecifierTypeOnlyText}${ts.escapeSnippetText(name)}${tabStop} } from ${quotedModuleSpecifier}${suffix}` }; } } - function quotePropertyName(sourceFile: SourceFile, preferences: UserPreferences, name: string,): string { + function quotePropertyName(sourceFile: ts.SourceFile, preferences: ts.UserPreferences, name: string): string { if (/^\d+$/.test(name)) { return name; } - return quote(sourceFile, preferences, name); + return ts.quote(sourceFile, preferences, name); } - function isRecommendedCompletionMatch(localSymbol: Symbol, recommendedCompletion: Symbol | undefined, checker: TypeChecker): boolean { + function isRecommendedCompletionMatch(localSymbol: ts.Symbol, recommendedCompletion: ts.Symbol | undefined, checker: ts.TypeChecker): boolean { return localSymbol === recommendedCompletion || - !!(localSymbol.flags & SymbolFlags.ExportValue) && checker.getExportSymbolOfSymbol(localSymbol) === recommendedCompletion; + !!(localSymbol.flags & ts.SymbolFlags.ExportValue) && checker.getExportSymbolOfSymbol(localSymbol) === recommendedCompletion; } function getSourceFromOrigin(origin: SymbolOriginInfo | undefined): string | undefined { if (originIsExport(origin)) { - return stripQuotes(origin.moduleSymbol.name); + return ts.stripQuotes(origin.moduleSymbol.name); } if (originIsResolvedExport(origin)) { return origin.moduleSpecifier; @@ -1418,41 +1201,16 @@ namespace ts.Completions { } } - export function getCompletionEntriesFromSymbols( - symbols: readonly Symbol[], - entries: SortedArray, - replacementToken: Node | undefined, - contextToken: Node | undefined, - location: Node, - sourceFile: SourceFile, - host: LanguageServiceHost, - program: Program, - target: ScriptTarget, - log: Log, - kind: CompletionKind, - preferences: UserPreferences, - compilerOptions: CompilerOptions, - formatContext: formatting.FormatContext | undefined, - isTypeOnlyLocation?: boolean, - propertyAccessToConvert?: PropertyAccessExpression, - jsxIdentifierExpected?: boolean, - isJsxInitializer?: IsJsxInitializer, - importCompletionNode?: Node, - recommendedCompletion?: Symbol, - symbolToOriginInfoMap?: SymbolOriginInfoMap, - symbolToSortTextMap?: SymbolSortTextMap, - isJsxIdentifierExpected?: boolean, - isRightOfOpenTag?: boolean, - ): UniqueNameSet { - const start = timestamp(); + export function getCompletionEntriesFromSymbols(symbols: readonly ts.Symbol[], entries: ts.SortedArray, replacementToken: ts.Node | undefined, contextToken: ts.Node | undefined, location: ts.Node, sourceFile: ts.SourceFile, host: ts.LanguageServiceHost, program: ts.Program, target: ts.ScriptTarget, log: Log, kind: CompletionKind, preferences: ts.UserPreferences, compilerOptions: ts.CompilerOptions, formatContext: ts.formatting.FormatContext | undefined, isTypeOnlyLocation?: boolean, propertyAccessToConvert?: ts.PropertyAccessExpression, jsxIdentifierExpected?: boolean, isJsxInitializer?: IsJsxInitializer, importCompletionNode?: ts.Node, recommendedCompletion?: ts.Symbol, symbolToOriginInfoMap?: SymbolOriginInfoMap, symbolToSortTextMap?: SymbolSortTextMap, isJsxIdentifierExpected?: boolean, isRightOfOpenTag?: boolean): UniqueNameSet { + const start = ts.timestamp(); const variableDeclaration = getVariableDeclaration(location); - const useSemicolons = probablyUsesSemicolons(sourceFile); + const useSemicolons = ts.probablyUsesSemicolons(sourceFile); const typeChecker = program.getTypeChecker(); // Tracks unique names. // Value is set to false for global variables or completions from external module exports, because we can have multiple of those; // true otherwise. Based on the order we add things we will always see locals first, then globals, then module exports. // So adding a completion for a local will prevent us from adding completions for external module exports sharing the same name. - const uniques = new Map(); + const uniques = new ts.Map(); for (let i = 0; i < symbols.length; i++) { const symbol = symbols[i]; const origin = symbolToOriginInfoMap?.[i]; @@ -1462,43 +1220,20 @@ namespace ts.Completions { } const { name, needsConvertPropertyAccess } = info; - const originalSortText = symbolToSortTextMap?.[getSymbolId(symbol)] ?? SortText.LocationPriority; + const originalSortText = symbolToSortTextMap?.[ts.getSymbolId(symbol)] ?? SortText.LocationPriority; const sortText = (isDeprecated(symbol, typeChecker) ? SortText.Deprecated(originalSortText) : originalSortText); - const entry = createCompletionEntry( - symbol, - sortText, - replacementToken, - contextToken, - location, - sourceFile, - host, - program, - name, - needsConvertPropertyAccess, - origin, - recommendedCompletion, - propertyAccessToConvert, - isJsxInitializer, - importCompletionNode, - useSemicolons, - compilerOptions, - preferences, - kind, - formatContext, - isJsxIdentifierExpected, - isRightOfOpenTag, - ); + const entry = createCompletionEntry(symbol, sortText, replacementToken, contextToken, location, sourceFile, host, program, name, needsConvertPropertyAccess, origin, recommendedCompletion, propertyAccessToConvert, isJsxInitializer, importCompletionNode, useSemicolons, compilerOptions, preferences, kind, formatContext, isJsxIdentifierExpected, isRightOfOpenTag); if (!entry) { continue; } /** True for locals; false for globals, module exports from other files, `this.` completions. */ - const shouldShadowLaterSymbols = (!origin || originIsTypeOnlyAlias(origin)) && !(symbol.parent === undefined && !some(symbol.declarations, d => d.getSourceFile() === location.getSourceFile())); + const shouldShadowLaterSymbols = (!origin || originIsTypeOnlyAlias(origin)) && !(symbol.parent === undefined && !ts.some(symbol.declarations, d => d.getSourceFile() === location.getSourceFile())); uniques.set(name, shouldShadowLaterSymbols); - insertSorted(entries, entry, compareCompletionEntries, /*allowDuplicates*/ true); + ts.insertSorted(entries, entry, compareCompletionEntries, /*allowDuplicates*/ true); } - log("getCompletionsAtPosition: getCompletionEntriesFromSymbols: " + (timestamp() - start)); + log("getCompletionsAtPosition: getCompletionEntriesFromSymbols: " + (ts.timestamp() - start)); // Prevent consumers of this map from having to worry about // the boolean value. Externally, it should be seen as the @@ -1508,11 +1243,11 @@ namespace ts.Completions { add: name => uniques.set(name, true), }; - function shouldIncludeSymbol(symbol: Symbol, symbolToSortTextMap: SymbolSortTextMap): boolean { + function shouldIncludeSymbol(symbol: ts.Symbol, symbolToSortTextMap: SymbolSortTextMap): boolean { let allFlags = symbol.flags; - if (!isSourceFile(location)) { + if (!ts.isSourceFile(location)) { // export = /**/ here we want to get all meanings, so any symbol is ok - if (isExportAssignment(location.parent)) { + if (ts.isExportAssignment(location.parent)) { return true; } // Filter out variables from their own initializers @@ -1526,22 +1261,22 @@ namespace ts.Completions { // already has an explicit export and user only wants to user explicit // module imports then the global keywords will be filtered out so auto // import suggestions will win in the completion - const symbolOrigin = skipAlias(symbol, typeChecker); + const symbolOrigin = ts.skipAlias(symbol, typeChecker); // We only want to filter out the global keywords // Auto Imports are not available for scripts so this conditional is always false if (!!sourceFile.externalModuleIndicator && !compilerOptions.allowUmdGlobalAccess - && symbolToSortTextMap[getSymbolId(symbol)] === SortText.GlobalsOrKeywords - && (symbolToSortTextMap[getSymbolId(symbolOrigin)] === SortText.AutoImportSuggestions - || symbolToSortTextMap[getSymbolId(symbolOrigin)] === SortText.LocationPriority)) { + && symbolToSortTextMap[ts.getSymbolId(symbol)] === SortText.GlobalsOrKeywords + && (symbolToSortTextMap[ts.getSymbolId(symbolOrigin)] === SortText.AutoImportSuggestions + || symbolToSortTextMap[ts.getSymbolId(symbolOrigin)] === SortText.LocationPriority)) { return false; } - allFlags |= getCombinedLocalAndExportSymbolFlags(symbolOrigin); + allFlags |= ts.getCombinedLocalAndExportSymbolFlags(symbolOrigin); // import m = /**/ <-- It can only access namespace (if typing import = x. this would get member symbols and not namespace) - if (isInRightSideOfInternalImportEqualsDeclaration(location)) { - return !!(allFlags & SymbolFlags.Namespace); + if (ts.isInRightSideOfInternalImportEqualsDeclaration(location)) { + return !!(allFlags & ts.SymbolFlags.Namespace); } if (isTypeOnlyLocation) { @@ -1551,34 +1286,34 @@ namespace ts.Completions { } // expressions are value space (which includes the value namespaces) - return !!(allFlags & SymbolFlags.Value); + return !!(allFlags & ts.SymbolFlags.Value); } } - function getLabelCompletionAtPosition(node: BreakOrContinueStatement): CompletionInfo | undefined { + function getLabelCompletionAtPosition(node: ts.BreakOrContinueStatement): ts.CompletionInfo | undefined { const entries = getLabelStatementCompletions(node); if (entries.length) { return { isGlobalCompletion: false, isMemberCompletion: false, isNewIdentifierLocation: false, entries }; } } - function getLabelStatementCompletions(node: Node): CompletionEntry[] { - const entries: CompletionEntry[] = []; - const uniques = new Map(); + function getLabelStatementCompletions(node: ts.Node): ts.CompletionEntry[] { + const entries: ts.CompletionEntry[] = []; + const uniques = new ts.Map(); let current = node; while (current) { - if (isFunctionLike(current)) { + if (ts.isFunctionLike(current)) { break; } - if (isLabeledStatement(current)) { + if (ts.isLabeledStatement(current)) { const name = current.label.text; if (!uniques.has(name)) { uniques.set(name, true); entries.push({ name, - kindModifiers: ScriptElementKindModifier.none, - kind: ScriptElementKind.label, + kindModifiers: ts.ScriptElementKindModifier.none, + kind: ts.ScriptElementKind.label, sortText: SortText.LocationPriority }); } @@ -1590,23 +1325,23 @@ namespace ts.Completions { interface SymbolCompletion { type: "symbol"; - symbol: Symbol; - location: Node; + symbol: ts.Symbol; + location: ts.Node; origin: SymbolOriginInfo | SymbolOriginInfoExport | SymbolOriginInfoResolvedExport | undefined; - previousToken: Node | undefined; - contextToken: Node | undefined; + previousToken: ts.Node | undefined; + contextToken: ts.Node | undefined; readonly isJsxInitializer: IsJsxInitializer; readonly isTypeOnlyLocation: boolean; } - function getSymbolCompletionFromEntryId( - program: Program, - log: Log, - sourceFile: SourceFile, - position: number, - entryId: CompletionEntryIdentifier, - host: LanguageServiceHost, - preferences: UserPreferences, - ): SymbolCompletion | { type: "request", request: Request } | { type: "literal", literal: string | number | PseudoBigInt } | { type: "none" } { + function getSymbolCompletionFromEntryId(program: ts.Program, log: Log, sourceFile: ts.SourceFile, position: number, entryId: CompletionEntryIdentifier, host: ts.LanguageServiceHost, preferences: ts.UserPreferences): SymbolCompletion | { + type: "request"; + request: Request; + } | { + type: "literal"; + literal: string | number | ts.PseudoBigInt; + } | { + type: "none"; + } { if (entryId.data) { const autoImport = getAutoImportSymbolFromCompletionEntryData(entryId.name, entryId.data, program, host); if (autoImport) { @@ -1614,7 +1349,7 @@ namespace ts.Completions { return { type: "symbol", symbol: autoImport.symbol, - location: getTouchingPropertyName(sourceFile, position), + location: ts.getTouchingPropertyName(sourceFile, position), previousToken, contextToken, isJsxInitializer: false, @@ -1635,19 +1370,19 @@ namespace ts.Completions { const { symbols, literals, location, completionKind, symbolToOriginInfoMap, contextToken, previousToken, isJsxInitializer, isTypeOnlyLocation } = completionData; - const literal = find(literals, l => completionNameForLiteral(sourceFile, preferences, l) === entryId.name); - if (literal !== undefined) return { type: "literal", literal }; + const literal = ts.find(literals, l => completionNameForLiteral(sourceFile, preferences, l) === entryId.name); + if (literal !== undefined) + return { type: "literal", literal }; // Find the symbol with the matching entry name. // We don't need to perform character checks here because we're only comparing the // name against 'entryName' (which is known to be good), not building a new // completion entry. - return firstDefined(symbols, (symbol, index): SymbolCompletion | undefined => { + return ts.firstDefined(symbols, (symbol, index): SymbolCompletion | undefined => { const origin = symbolToOriginInfoMap[index]; - const info = getCompletionEntryDisplayNameForSymbol(symbol, getEmitScriptTarget(compilerOptions), origin, completionKind, completionData.isJsxIdentifierExpected); - return info && info.name === entryId.name && ( - entryId.source === CompletionSource.ClassMemberSnippet && symbol.flags & SymbolFlags.ClassMember - || entryId.source === CompletionSource.ObjectLiteralMethodSnippet && symbol.flags & (SymbolFlags.Property | SymbolFlags.Method) + const info = getCompletionEntryDisplayNameForSymbol(symbol, ts.getEmitScriptTarget(compilerOptions), origin, completionKind, completionData.isJsxIdentifierExpected); + return info && info.name === entryId.name && (entryId.source === CompletionSource.ClassMemberSnippet && symbol.flags & ts.SymbolFlags.ClassMember + || entryId.source === CompletionSource.ObjectLiteralMethodSnippet && symbol.flags & (ts.SymbolFlags.Property | ts.SymbolFlags.Method) || getSourceFromOrigin(origin) === entryId.source) ? { type: "symbol" as const, symbol, location, origin, contextToken, previousToken, isJsxInitializer, isTypeOnlyLocation } : undefined; @@ -1657,27 +1392,16 @@ namespace ts.Completions { export interface CompletionEntryIdentifier { name: string; source?: string; - data?: CompletionEntryData; + data?: ts.CompletionEntryData; } - - export function getCompletionEntryDetails( - program: Program, - log: Log, - sourceFile: SourceFile, - position: number, - entryId: CompletionEntryIdentifier, - host: LanguageServiceHost, - formatContext: formatting.FormatContext, - preferences: UserPreferences, - cancellationToken: CancellationToken, - ): CompletionEntryDetails | undefined { + export function getCompletionEntryDetails(program: ts.Program, log: Log, sourceFile: ts.SourceFile, position: number, entryId: CompletionEntryIdentifier, host: ts.LanguageServiceHost, formatContext: ts.formatting.FormatContext, preferences: ts.UserPreferences, cancellationToken: ts.CancellationToken): ts.CompletionEntryDetails | undefined { const typeChecker = program.getTypeChecker(); const compilerOptions = program.getCompilerOptions(); const { name, source, data } = entryId; - const contextToken = findPrecedingToken(position, sourceFile); - if (isInString(sourceFile, position, contextToken)) { - return StringCompletions.getStringLiteralCompletionDetails(name, sourceFile, position, contextToken, typeChecker, compilerOptions, host, cancellationToken, preferences); + const contextToken = ts.findPrecedingToken(position, sourceFile); + if (ts.isInString(sourceFile, position, contextToken)) { + return ts.Completions.StringCompletions.getStringLiteralCompletionDetails(name, sourceFile, position, contextToken, typeChecker, compilerOptions, host, cancellationToken, preferences); } // Compute all the completion symbols again. @@ -1687,15 +1411,15 @@ namespace ts.Completions { const { request } = symbolCompletion; switch (request.kind) { case CompletionDataKind.JsDocTagName: - return JsDoc.getJSDocTagNameCompletionDetails(name); + return ts.JsDoc.getJSDocTagNameCompletionDetails(name); case CompletionDataKind.JsDocTag: - return JsDoc.getJSDocTagCompletionDetails(name); + return ts.JsDoc.getJSDocTagCompletionDetails(name); case CompletionDataKind.JsDocParameterName: - return JsDoc.getJSDocParameterNameCompletionDetails(name); + return ts.JsDoc.getJSDocParameterNameCompletionDetails(name); case CompletionDataKind.Keywords: - return some(request.keywordCompletions, c => c.name === name) ? createSimpleDetails(name, ScriptElementKind.keyword, SymbolDisplayPartKind.keyword) : undefined; + return ts.some(request.keywordCompletions, c => c.name === name) ? createSimpleDetails(name, ts.ScriptElementKind.keyword, ts.SymbolDisplayPartKind.keyword) : undefined; default: - return Debug.assertNever(request); + return ts.Debug.assertNever(request); } } case "symbol": { @@ -1705,95 +1429,58 @@ namespace ts.Completions { } case "literal": { const { literal } = symbolCompletion; - return createSimpleDetails(completionNameForLiteral(sourceFile, preferences, literal), ScriptElementKind.string, typeof literal === "string" ? SymbolDisplayPartKind.stringLiteral : SymbolDisplayPartKind.numericLiteral); + return createSimpleDetails(completionNameForLiteral(sourceFile, preferences, literal), ts.ScriptElementKind.string, typeof literal === "string" ? ts.SymbolDisplayPartKind.stringLiteral : ts.SymbolDisplayPartKind.numericLiteral); } case "none": // Didn't find a symbol with this name. See if we can find a keyword instead. - return allKeywordsCompletions().some(c => c.name === name) ? createSimpleDetails(name, ScriptElementKind.keyword, SymbolDisplayPartKind.keyword) : undefined; + return allKeywordsCompletions().some(c => c.name === name) ? createSimpleDetails(name, ts.ScriptElementKind.keyword, ts.SymbolDisplayPartKind.keyword) : undefined; default: - Debug.assertNever(symbolCompletion); + ts.Debug.assertNever(symbolCompletion); } } - function createSimpleDetails(name: string, kind: ScriptElementKind, kind2: SymbolDisplayPartKind): CompletionEntryDetails { - return createCompletionDetails(name, ScriptElementKindModifier.none, kind, [displayPart(name, kind2)]); + function createSimpleDetails(name: string, kind: ts.ScriptElementKind, kind2: ts.SymbolDisplayPartKind): ts.CompletionEntryDetails { + return createCompletionDetails(name, ts.ScriptElementKindModifier.none, kind, [ts.displayPart(name, kind2)]); } - export function createCompletionDetailsForSymbol(symbol: Symbol, checker: TypeChecker, sourceFile: SourceFile, location: Node, cancellationToken: CancellationToken, codeActions?: CodeAction[], sourceDisplay?: SymbolDisplayPart[]): CompletionEntryDetails { - const { displayParts, documentation, symbolKind, tags } = - checker.runWithCancellationToken(cancellationToken, checker => - SymbolDisplay.getSymbolDisplayPartsDocumentationAndSymbolKind(checker, symbol, sourceFile, location, location, SemanticMeaning.All) - ); - return createCompletionDetails(symbol.name, SymbolDisplay.getSymbolModifiers(checker, symbol), symbolKind, displayParts, documentation, tags, codeActions, sourceDisplay); + export function createCompletionDetailsForSymbol(symbol: ts.Symbol, checker: ts.TypeChecker, sourceFile: ts.SourceFile, location: ts.Node, cancellationToken: ts.CancellationToken, codeActions?: ts.CodeAction[], sourceDisplay?: ts.SymbolDisplayPart[]): ts.CompletionEntryDetails { + const { displayParts, documentation, symbolKind, tags } = checker.runWithCancellationToken(cancellationToken, checker => ts.SymbolDisplay.getSymbolDisplayPartsDocumentationAndSymbolKind(checker, symbol, sourceFile, location, location, ts.SemanticMeaning.All)); + return createCompletionDetails(symbol.name, ts.SymbolDisplay.getSymbolModifiers(checker, symbol), symbolKind, displayParts, documentation, tags, codeActions, sourceDisplay); } - export function createCompletionDetails(name: string, kindModifiers: string, kind: ScriptElementKind, displayParts: SymbolDisplayPart[], documentation?: SymbolDisplayPart[], tags?: JSDocTagInfo[], codeActions?: CodeAction[], source?: SymbolDisplayPart[]): CompletionEntryDetails { + export function createCompletionDetails(name: string, kindModifiers: string, kind: ts.ScriptElementKind, displayParts: ts.SymbolDisplayPart[], documentation?: ts.SymbolDisplayPart[], tags?: ts.JSDocTagInfo[], codeActions?: ts.CodeAction[], source?: ts.SymbolDisplayPart[]): ts.CompletionEntryDetails { return { name, kindModifiers, kind, displayParts, documentation, tags, codeActions, source, sourceDisplay: source }; } interface CodeActionsAndSourceDisplay { - readonly codeActions: CodeAction[] | undefined; - readonly sourceDisplay: SymbolDisplayPart[] | undefined; + readonly codeActions: ts.CodeAction[] | undefined; + readonly sourceDisplay: ts.SymbolDisplayPart[] | undefined; } - function getCompletionEntryCodeActionsAndSourceDisplay( - name: string, - location: Node, - contextToken: Node | undefined, - origin: SymbolOriginInfo | SymbolOriginInfoExport | SymbolOriginInfoResolvedExport | undefined, - symbol: Symbol, - program: Program, - host: LanguageServiceHost, - compilerOptions: CompilerOptions, - sourceFile: SourceFile, - position: number, - previousToken: Node | undefined, - formatContext: formatting.FormatContext, - preferences: UserPreferences, - data: CompletionEntryData | undefined, - source: string | undefined, - ): CodeActionsAndSourceDisplay { + function getCompletionEntryCodeActionsAndSourceDisplay(name: string, location: ts.Node, contextToken: ts.Node | undefined, origin: SymbolOriginInfo | SymbolOriginInfoExport | SymbolOriginInfoResolvedExport | undefined, symbol: ts.Symbol, program: ts.Program, host: ts.LanguageServiceHost, compilerOptions: ts.CompilerOptions, sourceFile: ts.SourceFile, position: number, previousToken: ts.Node | undefined, formatContext: ts.formatting.FormatContext, preferences: ts.UserPreferences, data: ts.CompletionEntryData | undefined, source: string | undefined): CodeActionsAndSourceDisplay { if (data?.moduleSpecifier) { if (previousToken && getImportStatementCompletionInfo(contextToken || previousToken).replacementNode) { // Import statement completion: 'import c|' - return { codeActions: undefined, sourceDisplay: [textPart(data.moduleSpecifier)] }; + return { codeActions: undefined, sourceDisplay: [ts.textPart(data.moduleSpecifier)] }; } } if (source === CompletionSource.ClassMemberSnippet) { - const { importAdder } = getEntryForMemberCompletion( - host, - program, - compilerOptions, - preferences, - name, - symbol, - location, - contextToken, - formatContext); + const { importAdder } = getEntryForMemberCompletion(host, program, compilerOptions, preferences, name, symbol, location, contextToken, formatContext); if (importAdder) { - const changes = textChanges.ChangeTracker.with( - { host, formatContext, preferences }, - importAdder.writeFixes); + const changes = ts.textChanges.ChangeTracker.with({ host, formatContext, preferences }, importAdder.writeFixes); return { sourceDisplay: undefined, codeActions: [{ changes, - description: diagnosticToString([Diagnostics.Includes_imports_of_types_referenced_by_0, name]), + description: ts.diagnosticToString([ts.Diagnostics.Includes_imports_of_types_referenced_by_0, name]), }], }; } } if (originIsTypeOnlyAlias(origin)) { - const codeAction = codefix.getPromoteTypeOnlyCompletionAction( - sourceFile, - origin.declaration.name, - program, - host, - formatContext, - preferences); - - Debug.assertIsDefined(codeAction, "Expected to have a code action for promoting type-only alias"); + const codeAction = ts.codefix.getPromoteTypeOnlyCompletionAction(sourceFile, origin.declaration.name, program, host, formatContext, preferences); + ts.Debug.assertIsDefined(codeAction, "Expected to have a code action for promoting type-only alias"); return { codeActions: [codeAction], sourceDisplay: undefined }; } @@ -1803,54 +1490,41 @@ namespace ts.Completions { const checker = origin.isFromPackageJson ? host.getPackageJsonAutoImportProvider!()!.getTypeChecker() : program.getTypeChecker(); const { moduleSymbol } = origin; - const targetSymbol = checker.getMergedSymbol(skipAlias(symbol.exportSymbol || symbol, checker)); - const isJsxOpeningTagName = contextToken?.kind === SyntaxKind.LessThanToken && isJsxOpeningLikeElement(contextToken.parent); - const { moduleSpecifier, codeAction } = codefix.getImportCompletionAction( - targetSymbol, - moduleSymbol, - sourceFile, - getNameForExportedSymbol(symbol, getEmitScriptTarget(compilerOptions), isJsxOpeningTagName), - isJsxOpeningTagName, - host, - program, - formatContext, - previousToken && isIdentifier(previousToken) ? previousToken.getStart(sourceFile) : position, - preferences); - Debug.assert(!data?.moduleSpecifier || moduleSpecifier === data.moduleSpecifier); - return { sourceDisplay: [textPart(moduleSpecifier)], codeActions: [codeAction] }; + const targetSymbol = checker.getMergedSymbol(ts.skipAlias(symbol.exportSymbol || symbol, checker)); + const isJsxOpeningTagName = contextToken?.kind === ts.SyntaxKind.LessThanToken && ts.isJsxOpeningLikeElement(contextToken.parent); + const { moduleSpecifier, codeAction } = ts.codefix.getImportCompletionAction(targetSymbol, moduleSymbol, sourceFile, ts.getNameForExportedSymbol(symbol, ts.getEmitScriptTarget(compilerOptions), isJsxOpeningTagName), isJsxOpeningTagName, host, program, formatContext, previousToken && ts.isIdentifier(previousToken) ? previousToken.getStart(sourceFile) : position, preferences); + ts.Debug.assert(!data?.moduleSpecifier || moduleSpecifier === data.moduleSpecifier); + return { sourceDisplay: [ts.textPart(moduleSpecifier)], codeActions: [codeAction] }; } - - export function getCompletionEntrySymbol( - program: Program, - log: Log, - sourceFile: SourceFile, - position: number, - entryId: CompletionEntryIdentifier, - host: LanguageServiceHost, - preferences: UserPreferences, - ): Symbol | undefined { + export function getCompletionEntrySymbol(program: ts.Program, log: Log, sourceFile: ts.SourceFile, position: number, entryId: CompletionEntryIdentifier, host: ts.LanguageServiceHost, preferences: ts.UserPreferences): ts.Symbol | undefined { const completion = getSymbolCompletionFromEntryId(program, log, sourceFile, position, entryId, host, preferences); return completion.type === "symbol" ? completion.symbol : undefined; } - const enum CompletionDataKind { Data, JsDocTagName, JsDocTag, JsDocParameterName, Keywords } + const enum CompletionDataKind { + Data, + JsDocTagName, + JsDocTag, + JsDocParameterName, + Keywords + } /** true: after the `=` sign but no identifier has been typed yet. Else is the Identifier after the initializer. */ - type IsJsxInitializer = boolean | Identifier; + type IsJsxInitializer = boolean | ts.Identifier; interface CompletionData { readonly kind: CompletionDataKind.Data; - readonly symbols: readonly Symbol[]; + readonly symbols: readonly ts.Symbol[]; readonly completionKind: CompletionKind; readonly isInSnippetScope: boolean; /** Note that the presence of this alone doesn't mean that we need a conversion. Only do that if the completion is not an ordinary identifier. */ - readonly propertyAccessToConvert: PropertyAccessExpression | undefined; + readonly propertyAccessToConvert: ts.PropertyAccessExpression | undefined; readonly isNewIdentifierLocation: boolean; - readonly location: Node; + readonly location: ts.Node; readonly keywordFilters: KeywordCompletionFilters; - readonly literals: readonly (string | number | PseudoBigInt)[]; + readonly literals: readonly (string | number | ts.PseudoBigInt)[]; readonly symbolToOriginInfoMap: SymbolOriginInfoMap; - readonly recommendedCompletion: Symbol | undefined; - readonly previousToken: Node | undefined; - readonly contextToken: Node | undefined; + readonly recommendedCompletion: ts.Symbol | undefined; + readonly previousToken: ts.Node | undefined; + readonly contextToken: ts.Node | undefined; readonly isJsxInitializer: IsJsxInitializer; readonly insideJsDocTagTypeExpression: boolean; readonly symbolToSortTextMap: SymbolSortTextMap; @@ -1858,14 +1532,20 @@ namespace ts.Completions { /** In JSX tag name and attribute names, identifiers like "my-tag" or "aria-name" is valid identifier. */ readonly isJsxIdentifierExpected: boolean; readonly isRightOfOpenTag: boolean; - readonly importCompletionNode?: Node; + readonly importCompletionNode?: ts.Node; readonly hasUnresolvedAutoImports?: boolean; - readonly flags: CompletionInfoFlags; - } - type Request = - | { readonly kind: CompletionDataKind.JsDocTagName | CompletionDataKind.JsDocTag } - | { readonly kind: CompletionDataKind.JsDocParameterName, tag: JSDocParameterTag } - | { readonly kind: CompletionDataKind.Keywords, keywordCompletions: readonly CompletionEntry[], isNewIdentifierLocation: boolean }; + readonly flags: ts.CompletionInfoFlags; + } + type Request = { + readonly kind: CompletionDataKind.JsDocTagName | CompletionDataKind.JsDocTag; + } | { + readonly kind: CompletionDataKind.JsDocParameterName; + tag: ts.JSDocParameterTag; + } | { + readonly kind: CompletionDataKind.Keywords; + keywordCompletions: readonly ts.CompletionEntry[]; + isNewIdentifierLocation: boolean; + }; export const enum CompletionKind { ObjectPropertyDeclaration, @@ -1873,94 +1553,82 @@ namespace ts.Completions { PropertyAccess, MemberLike, String, - None, + None } - function getRecommendedCompletion(previousToken: Node, contextualType: Type, checker: TypeChecker): Symbol | undefined { + function getRecommendedCompletion(previousToken: ts.Node, contextualType: ts.Type, checker: ts.TypeChecker): ts.Symbol | undefined { // For a union, return the first one with a recommended completion. - return firstDefined(contextualType && (contextualType.isUnion() ? contextualType.types : [contextualType]), type => { + return ts.firstDefined(contextualType && (contextualType.isUnion() ? contextualType.types : [contextualType]), type => { const symbol = type && type.symbol; // Don't include make a recommended completion for an abstract class - return symbol && (symbol.flags & (SymbolFlags.EnumMember | SymbolFlags.Enum | SymbolFlags.Class) && !isAbstractConstructorSymbol(symbol)) + return symbol && (symbol.flags & (ts.SymbolFlags.EnumMember | ts.SymbolFlags.Enum | ts.SymbolFlags.Class) && !ts.isAbstractConstructorSymbol(symbol)) ? getFirstSymbolInChain(symbol, previousToken, checker) : undefined; }); } - function getContextualType(previousToken: Node, position: number, sourceFile: SourceFile, checker: TypeChecker): Type | undefined { + function getContextualType(previousToken: ts.Node, position: number, sourceFile: ts.SourceFile, checker: ts.TypeChecker): ts.Type | undefined { const { parent } = previousToken; switch (previousToken.kind) { - case SyntaxKind.Identifier: - return getContextualTypeFromParent(previousToken as Identifier, checker); - case SyntaxKind.EqualsToken: + case ts.SyntaxKind.Identifier: + return ts.getContextualTypeFromParent(previousToken as ts.Identifier, checker); + case ts.SyntaxKind.EqualsToken: switch (parent.kind) { - case SyntaxKind.VariableDeclaration: - return checker.getContextualType((parent as VariableDeclaration).initializer!); // TODO: GH#18217 - case SyntaxKind.BinaryExpression: - return checker.getTypeAtLocation((parent as BinaryExpression).left); - case SyntaxKind.JsxAttribute: - return checker.getContextualTypeForJsxAttribute(parent as JsxAttribute); + case ts.SyntaxKind.VariableDeclaration: + return checker.getContextualType((parent as ts.VariableDeclaration).initializer!); // TODO: GH#18217 + case ts.SyntaxKind.BinaryExpression: + return checker.getTypeAtLocation((parent as ts.BinaryExpression).left); + case ts.SyntaxKind.JsxAttribute: + return checker.getContextualTypeForJsxAttribute(parent as ts.JsxAttribute); default: return undefined; } - case SyntaxKind.NewKeyword: - return checker.getContextualType(parent as Expression); - case SyntaxKind.CaseKeyword: - const caseClause = tryCast(parent, isCaseClause); - return caseClause ? getSwitchedType(caseClause, checker) : undefined; - case SyntaxKind.OpenBraceToken: - return isJsxExpression(parent) && !isJsxElement(parent.parent) && !isJsxFragment(parent.parent) ? checker.getContextualTypeForJsxAttribute(parent.parent) : undefined; + case ts.SyntaxKind.NewKeyword: + return checker.getContextualType(parent as ts.Expression); + case ts.SyntaxKind.CaseKeyword: + const caseClause = ts.tryCast(parent, ts.isCaseClause); + return caseClause ? ts.getSwitchedType(caseClause, checker) : undefined; + case ts.SyntaxKind.OpenBraceToken: + return ts.isJsxExpression(parent) && !ts.isJsxElement(parent.parent) && !ts.isJsxFragment(parent.parent) ? checker.getContextualTypeForJsxAttribute(parent.parent) : undefined; default: - const argInfo = SignatureHelp.getArgumentInfoForCompletions(previousToken, position, sourceFile); + const argInfo = ts.SignatureHelp.getArgumentInfoForCompletions(previousToken, position, sourceFile); return argInfo ? // At `,`, treat this as the next argument after the comma. - checker.getContextualTypeForArgumentAtIndex(argInfo.invocation, argInfo.argumentIndex + (previousToken.kind === SyntaxKind.CommaToken ? 1 : 0)) : - isEqualityOperatorKind(previousToken.kind) && isBinaryExpression(parent) && isEqualityOperatorKind(parent.operatorToken.kind) ? + checker.getContextualTypeForArgumentAtIndex(argInfo.invocation, argInfo.argumentIndex + (previousToken.kind === ts.SyntaxKind.CommaToken ? 1 : 0)) : + ts.isEqualityOperatorKind(previousToken.kind) && ts.isBinaryExpression(parent) && ts.isEqualityOperatorKind(parent.operatorToken.kind) ? // completion at `x ===/**/` should be for the right side checker.getTypeAtLocation(parent.left) : - checker.getContextualType(previousToken as Expression); + checker.getContextualType(previousToken as ts.Expression); } } - function getFirstSymbolInChain(symbol: Symbol, enclosingDeclaration: Node, checker: TypeChecker): Symbol | undefined { - const chain = checker.getAccessibleSymbolChain(symbol, enclosingDeclaration, /*meaning*/ SymbolFlags.All, /*useOnlyExternalAliasing*/ false); - if (chain) return first(chain); + function getFirstSymbolInChain(symbol: ts.Symbol, enclosingDeclaration: ts.Node, checker: ts.TypeChecker): ts.Symbol | undefined { + const chain = checker.getAccessibleSymbolChain(symbol, enclosingDeclaration, /*meaning*/ ts.SymbolFlags.All, /*useOnlyExternalAliasing*/ false); + if (chain) + return ts.first(chain); return symbol.parent && (isModuleSymbol(symbol.parent) ? symbol : getFirstSymbolInChain(symbol.parent, enclosingDeclaration, checker)); } - function isModuleSymbol(symbol: Symbol): boolean { - return !!symbol.declarations?.some(d => d.kind === SyntaxKind.SourceFile); + function isModuleSymbol(symbol: ts.Symbol): boolean { + return !!symbol.declarations?.some(d => d.kind === ts.SyntaxKind.SourceFile); } - - function getCompletionData( - program: Program, - log: (message: string) => void, - sourceFile: SourceFile, - compilerOptions: CompilerOptions, - position: number, - preferences: UserPreferences, - detailsEntryId: CompletionEntryIdentifier | undefined, - host: LanguageServiceHost, - formatContext: formatting.FormatContext | undefined, - cancellationToken?: CancellationToken, - ): CompletionData | Request | undefined { + function getCompletionData(program: ts.Program, log: (message: string) => void, sourceFile: ts.SourceFile, compilerOptions: ts.CompilerOptions, position: number, preferences: ts.UserPreferences, detailsEntryId: CompletionEntryIdentifier | undefined, host: ts.LanguageServiceHost, formatContext: ts.formatting.FormatContext | undefined, cancellationToken?: ts.CancellationToken): CompletionData | Request | undefined { const typeChecker = program.getTypeChecker(); const inUncheckedFile = isUncheckedFile(sourceFile, compilerOptions); - let start = timestamp(); - let currentToken = getTokenAtPosition(sourceFile, position); // TODO: GH#15853 + let start = ts.timestamp(); + let currentToken = ts.getTokenAtPosition(sourceFile, position); // TODO: GH#15853 // We will check for jsdoc comments with insideComment and getJsDocTagAtPosition. (TODO: that seems rather inefficient to check the same thing so many times.) - log("getCompletionData: Get current token: " + (timestamp() - start)); - - start = timestamp(); - const insideComment = isInComment(sourceFile, position, currentToken); - log("getCompletionData: Is inside comment: " + (timestamp() - start)); + log("getCompletionData: Get current token: " + (ts.timestamp() - start)); + start = ts.timestamp(); + const insideComment = ts.isInComment(sourceFile, position, currentToken); + log("getCompletionData: Is inside comment: " + (ts.timestamp() - start)); let insideJsDocTagTypeExpression = false; let isInSnippetScope = false; if (insideComment) { - if (hasDocComment(sourceFile, position)) { - if (sourceFile.text.charCodeAt(position - 1) === CharacterCodes.at) { + if (ts.hasDocComment(sourceFile, position)) { + if (sourceFile.text.charCodeAt(position - 1) === ts.CharacterCodes.at) { // The current position is next to the '@' sign, when no tag name being provided yet. // Provide a full list of tag names return { kind: CompletionDataKind.JsDocTagName }; @@ -1982,7 +1650,7 @@ namespace ts.Completions { // /** // * |c| // */ - const lineStart = getLineStartPositionForPosition(position, sourceFile); + const lineStart = ts.getLineStartPositionForPosition(position, sourceFile); if (!/[^\*|\s(/)]/.test(sourceFile.text.substring(lineStart, position))) { return { kind: CompletionDataKind.JsDocTag }; } @@ -1999,16 +1667,16 @@ namespace ts.Completions { } const typeExpression = tryGetTypeExpressionFromTag(tag); if (typeExpression) { - currentToken = getTokenAtPosition(sourceFile, position); + currentToken = ts.getTokenAtPosition(sourceFile, position); if (!currentToken || - (!isDeclarationName(currentToken) && - (currentToken.parent.kind !== SyntaxKind.JSDocPropertyTag || - (currentToken.parent as JSDocPropertyTag).name !== currentToken))) { + (!ts.isDeclarationName(currentToken) && + (currentToken.parent.kind !== ts.SyntaxKind.JSDocPropertyTag || + (currentToken.parent as ts.JSDocPropertyTag).name !== currentToken))) { // Use as type location if inside tag's type expression insideJsDocTagTypeExpression = isCurrentlyEditingNode(typeExpression); } } - if (!insideJsDocTagTypeExpression && isJSDocParameterTag(tag) && (nodeIsMissing(tag.name) || tag.name.pos <= position && position <= tag.name.end)) { + if (!insideJsDocTagTypeExpression && ts.isJSDocParameterTag(tag) && (ts.nodeIsMissing(tag.name) || tag.name.pos <= position && position <= tag.name.end)) { return { kind: CompletionDataKind.JsDocParameterName, tag }; } } @@ -2021,31 +1689,31 @@ namespace ts.Completions { } } - start = timestamp(); + start = ts.timestamp(); // The decision to provide completion depends on the contextToken, which is determined through the previousToken. // Note: 'previousToken' (and thus 'contextToken') can be undefined if we are the beginning of the file - const isJsOnlyLocation = !insideJsDocTagTypeExpression && isSourceFileJS(sourceFile); + const isJsOnlyLocation = !insideJsDocTagTypeExpression && ts.isSourceFileJS(sourceFile); const tokens = getRelevantTokens(position, sourceFile); const previousToken = tokens.previousToken!; let contextToken = tokens.contextToken!; - log("getCompletionData: Get previous token: " + (timestamp() - start)); + log("getCompletionData: Get previous token: " + (ts.timestamp() - start)); // Find the node where completion is requested on. // Also determine whether we are trying to complete with members of that node // or attributes of a JSX tag. let node = currentToken; - let propertyAccessToConvert: PropertyAccessExpression | undefined; + let propertyAccessToConvert: ts.PropertyAccessExpression | undefined; let isRightOfDot = false; let isRightOfQuestionDot = false; let isRightOfOpenTag = false; let isStartingCloseTag = false; let isJsxInitializer: IsJsxInitializer = false; let isJsxIdentifierExpected = false; - let importCompletionNode: Node | undefined; - let location = getTouchingPropertyName(sourceFile, position); + let importCompletionNode: ts.Node | undefined; + let location = ts.getTouchingPropertyName(sourceFile, position); let keywordFilters = KeywordCompletionFilters.None; let isNewIdentifierLocation = false; - let flags = CompletionInfoFlags.None; + let flags = ts.CompletionInfoFlags.None; if (contextToken) { const importStatementCompletion = getImportStatementCompletionInfo(contextToken); @@ -2066,7 +1734,7 @@ namespace ts.Completions { // is not backward compatible with older clients, the language service defaults to disabling it, allowing newer clients // to opt in with the `includeCompletionsForImportStatements` user preference. importCompletionNode = importStatementCompletion.replacementNode; - flags |= CompletionInfoFlags.IsImportStatementCompletion; + flags |= ts.CompletionInfoFlags.IsImportStatementCompletion; } // Bail out if this is a known invalid completion location if (!importCompletionNode && isCompletionListBlocker(contextToken)) { @@ -2077,19 +1745,19 @@ namespace ts.Completions { } let parent = contextToken.parent; - if (contextToken.kind === SyntaxKind.DotToken || contextToken.kind === SyntaxKind.QuestionDotToken) { - isRightOfDot = contextToken.kind === SyntaxKind.DotToken; - isRightOfQuestionDot = contextToken.kind === SyntaxKind.QuestionDotToken; + if (contextToken.kind === ts.SyntaxKind.DotToken || contextToken.kind === ts.SyntaxKind.QuestionDotToken) { + isRightOfDot = contextToken.kind === ts.SyntaxKind.DotToken; + isRightOfQuestionDot = contextToken.kind === ts.SyntaxKind.QuestionDotToken; switch (parent.kind) { - case SyntaxKind.PropertyAccessExpression: - propertyAccessToConvert = parent as PropertyAccessExpression; + case ts.SyntaxKind.PropertyAccessExpression: + propertyAccessToConvert = parent as ts.PropertyAccessExpression; node = propertyAccessToConvert.expression; - const leftmostAccessExpression = getLeftmostAccessExpression(propertyAccessToConvert); - if (nodeIsMissing(leftmostAccessExpression) || - ((isCallExpression(node) || isFunctionLike(node)) && + const leftmostAccessExpression = ts.getLeftmostAccessExpression(propertyAccessToConvert); + if (ts.nodeIsMissing(leftmostAccessExpression) || + ((ts.isCallExpression(node) || ts.isFunctionLike(node)) && node.end === contextToken.pos && node.getChildCount(sourceFile) && - last(node.getChildren(sourceFile)).kind !== SyntaxKind.CloseParenToken)) { + ts.last(node.getChildren(sourceFile)).kind !== ts.SyntaxKind.CloseParenToken)) { // This is likely dot from incorrectly parsed expression and user is starting to write spread // eg: Math.min(./**/) // const x = function (./**/) {} @@ -2097,18 +1765,18 @@ namespace ts.Completions { return undefined; } break; - case SyntaxKind.QualifiedName: - node = (parent as QualifiedName).left; + case ts.SyntaxKind.QualifiedName: + node = (parent as ts.QualifiedName).left; break; - case SyntaxKind.ModuleDeclaration: - node = (parent as ModuleDeclaration).name; + case ts.SyntaxKind.ModuleDeclaration: + node = (parent as ts.ModuleDeclaration).name; break; - case SyntaxKind.ImportType: + case ts.SyntaxKind.ImportType: node = parent; break; - case SyntaxKind.MetaProperty: + case ts.SyntaxKind.MetaProperty: node = parent.getFirstToken(sourceFile)!; - Debug.assert(node.kind === SyntaxKind.ImportKeyword || node.kind === SyntaxKind.NewKeyword); + ts.Debug.assert(node.kind === ts.SyntaxKind.ImportKeyword || node.kind === ts.SyntaxKind.NewKeyword); break; default: // There is nothing that precedes the dot, so this likely just a stray character @@ -2116,11 +1784,11 @@ namespace ts.Completions { return undefined; } } - else if (!importCompletionNode && sourceFile.languageVariant === LanguageVariant.JSX) { + else if (!importCompletionNode && sourceFile.languageVariant === ts.LanguageVariant.JSX) { // // If the tagname is a property access expression, we will then walk up to the top most of property access expression. // Then, try to get a JSX container and its associated attributes type. - if (parent && parent.kind === SyntaxKind.PropertyAccessExpression) { + if (parent && parent.kind === ts.SyntaxKind.PropertyAccessExpression) { contextToken = parent; parent = parent.parent; } @@ -2128,14 +1796,14 @@ namespace ts.Completions { // Fix location if (currentToken.parent === location) { switch (currentToken.kind) { - case SyntaxKind.GreaterThanToken: - if (currentToken.parent.kind === SyntaxKind.JsxElement || currentToken.parent.kind === SyntaxKind.JsxOpeningElement) { + case ts.SyntaxKind.GreaterThanToken: + if (currentToken.parent.kind === ts.SyntaxKind.JsxElement || currentToken.parent.kind === ts.SyntaxKind.JsxOpeningElement) { location = currentToken; } break; - case SyntaxKind.SlashToken: - if (currentToken.parent.kind === SyntaxKind.JsxSelfClosingElement) { + case ts.SyntaxKind.SlashToken: + if (currentToken.parent.kind === ts.SyntaxKind.JsxSelfClosingElement) { location = currentToken; } break; @@ -2143,56 +1811,56 @@ namespace ts.Completions { } switch (parent.kind) { - case SyntaxKind.JsxClosingElement: - if (contextToken.kind === SyntaxKind.SlashToken) { + case ts.SyntaxKind.JsxClosingElement: + if (contextToken.kind === ts.SyntaxKind.SlashToken) { isStartingCloseTag = true; location = contextToken; } break; - case SyntaxKind.BinaryExpression: - if (!binaryExpressionMayBeOpenTag(parent as BinaryExpression)) { + case ts.SyntaxKind.BinaryExpression: + if (!binaryExpressionMayBeOpenTag(parent as ts.BinaryExpression)) { break; } // falls through - case SyntaxKind.JsxSelfClosingElement: - case SyntaxKind.JsxElement: - case SyntaxKind.JsxOpeningElement: + case ts.SyntaxKind.JsxSelfClosingElement: + case ts.SyntaxKind.JsxElement: + case ts.SyntaxKind.JsxOpeningElement: isJsxIdentifierExpected = true; - if (contextToken.kind === SyntaxKind.LessThanToken) { + if (contextToken.kind === ts.SyntaxKind.LessThanToken) { isRightOfOpenTag = true; location = contextToken; } break; - case SyntaxKind.JsxExpression: - case SyntaxKind.JsxSpreadAttribute: + case ts.SyntaxKind.JsxExpression: + case ts.SyntaxKind.JsxSpreadAttribute: // For `
`, `parent` will be `{true}` and `previousToken` will be `}` - if (previousToken.kind === SyntaxKind.CloseBraceToken && currentToken.kind === SyntaxKind.GreaterThanToken) { + if (previousToken.kind === ts.SyntaxKind.CloseBraceToken && currentToken.kind === ts.SyntaxKind.GreaterThanToken) { isJsxIdentifierExpected = true; } break; - case SyntaxKind.JsxAttribute: + case ts.SyntaxKind.JsxAttribute: // For `
`, `parent` will be JsxAttribute and `previousToken` will be its initializer - if ((parent as JsxAttribute).initializer === previousToken && + if ((parent as ts.JsxAttribute).initializer === previousToken && previousToken.end < position) { isJsxIdentifierExpected = true; break; } switch (previousToken.kind) { - case SyntaxKind.EqualsToken: + case ts.SyntaxKind.EqualsToken: isJsxInitializer = true; break; - case SyntaxKind.Identifier: + case ts.SyntaxKind.Identifier: isJsxIdentifierExpected = true; // For `
` we don't want to treat this as a jsx inializer, instead it's the attribute name. if (parent !== previousToken.parent && - !(parent as JsxAttribute).initializer && - findChildOfKind(parent, SyntaxKind.EqualsToken, sourceFile)) { - isJsxInitializer = previousToken as Identifier; + !(parent as ts.JsxAttribute).initializer && + ts.findChildOfKind(parent, ts.SyntaxKind.EqualsToken, sourceFile)) { + isJsxInitializer = previousToken as ts.Identifier; } } break; @@ -2200,18 +1868,18 @@ namespace ts.Completions { } } - const semanticStart = timestamp(); + const semanticStart = ts.timestamp(); let completionKind = CompletionKind.None; let isNonContextualObjectLiteral = false; let hasUnresolvedAutoImports = false; // This also gets mutated in nested-functions after the return - let symbols: Symbol[] = []; + let symbols: ts.Symbol[] = []; const symbolToOriginInfoMap: SymbolOriginInfoMap = []; const symbolToSortTextMap: SymbolSortTextMap = []; - const seenPropertySymbols = new Map(); + const seenPropertySymbols = new ts.Map(); const isTypeOnlyLocation = isTypeOnlyCompletion(); - const getModuleSpecifierResolutionHost = memoizeOne((isFromPackageJson: boolean) => { - return createModuleSpecifierResolutionHost(isFromPackageJson ? host.getPackageJsonAutoImportProvider!()! : program, host); + const getModuleSpecifierResolutionHost = ts.memoizeOne((isFromPackageJson: boolean) => { + return ts.createModuleSpecifierResolutionHost(isFromPackageJson ? host.getPackageJsonAutoImportProvider!()! : program, host); }); if (isRightOfDot || isRightOfQuestionDot) { @@ -2219,13 +1887,13 @@ namespace ts.Completions { } else if (isRightOfOpenTag) { symbols = typeChecker.getJsxIntrinsicTagNamesAt(location); - Debug.assertEachIsDefined(symbols, "getJsxIntrinsicTagNames() should all be defined"); + ts.Debug.assertEachIsDefined(symbols, "getJsxIntrinsicTagNames() should all be defined"); tryGetGlobalSymbols(); completionKind = CompletionKind.Global; keywordFilters = KeywordCompletionFilters.None; } else if (isStartingCloseTag) { - const tagName = (contextToken.parent.parent as JsxElement).openingElement.tagName; + const tagName = (contextToken.parent.parent as ts.JsxElement).openingElement.tagName; const tagSymbol = typeChecker.getSymbolAtLocation(tagName); if (tagSymbol) { symbols = [tagSymbol]; @@ -2244,12 +1912,10 @@ namespace ts.Completions { } } - log("getCompletionData: Semantic work: " + (timestamp() - semanticStart)); + log("getCompletionData: Semantic work: " + (ts.timestamp() - semanticStart)); const contextualType = previousToken && getContextualType(previousToken, position, sourceFile, typeChecker); - const literals = mapDefined( - contextualType && (contextualType.isUnion() ? contextualType.types : [contextualType]), - t => t.isLiteral() && !(t.flags & TypeFlags.EnumLiteral) ? t.value : undefined); + const literals = ts.mapDefined(contextualType && (contextualType.isUnion() ? contextualType.types : [contextualType]), t => t.isLiteral() && !(t.flags & ts.TypeFlags.EnumLiteral) ? t.value : undefined); const recommendedCompletion = previousToken && contextualType && getRecommendedCompletion(previousToken, contextualType, typeChecker); return { @@ -2277,27 +1943,26 @@ namespace ts.Completions { flags, }; - type JSDocTagWithTypeExpression = JSDocParameterTag | JSDocPropertyTag | JSDocReturnTag | JSDocTypeTag | JSDocTypedefTag | JSDocTemplateTag; - - function isTagWithTypeExpression(tag: JSDocTag): tag is JSDocTagWithTypeExpression { + type JSDocTagWithTypeExpression = ts.JSDocParameterTag | ts.JSDocPropertyTag | ts.JSDocReturnTag | ts.JSDocTypeTag | ts.JSDocTypedefTag | ts.JSDocTemplateTag; + function isTagWithTypeExpression(tag: ts.JSDocTag): tag is JSDocTagWithTypeExpression { switch (tag.kind) { - case SyntaxKind.JSDocParameterTag: - case SyntaxKind.JSDocPropertyTag: - case SyntaxKind.JSDocReturnTag: - case SyntaxKind.JSDocTypeTag: - case SyntaxKind.JSDocTypedefTag: + case ts.SyntaxKind.JSDocParameterTag: + case ts.SyntaxKind.JSDocPropertyTag: + case ts.SyntaxKind.JSDocReturnTag: + case ts.SyntaxKind.JSDocTypeTag: + case ts.SyntaxKind.JSDocTypedefTag: return true; - case SyntaxKind.JSDocTemplateTag: - return !!(tag as JSDocTemplateTag).constraint; + case ts.SyntaxKind.JSDocTemplateTag: + return !!(tag as ts.JSDocTemplateTag).constraint; default: return false; } } - function tryGetTypeExpressionFromTag(tag: JSDocTag): JSDocTypeExpression | undefined { + function tryGetTypeExpressionFromTag(tag: ts.JSDocTag): ts.JSDocTypeExpression | undefined { if (isTagWithTypeExpression(tag)) { - const typeExpression = isJSDocTemplateTag(tag) ? tag.constraint : tag.typeExpression; - return typeExpression && typeExpression.kind === SyntaxKind.JSDocTypeExpression ? typeExpression : undefined; + const typeExpression = ts.isJSDocTemplateTag(tag) ? tag.constraint : tag.typeExpression; + return typeExpression && typeExpression.kind === ts.SyntaxKind.JSDocTypeExpression ? typeExpression : undefined; } return undefined; } @@ -2307,28 +1972,28 @@ namespace ts.Completions { completionKind = CompletionKind.PropertyAccess; // Since this is qualified name check it's a type node location - const isImportType = isLiteralImportTypeNode(node); + const isImportType = ts.isLiteralImportTypeNode(node); const isTypeLocation = insideJsDocTagTypeExpression - || (isImportType && !(node as ImportTypeNode).isTypeOf) - || isPartOfTypeNode(node.parent) - || isPossiblyTypeArgumentPosition(contextToken, sourceFile, typeChecker); - const isRhsOfImportDeclaration = isInRightSideOfInternalImportEqualsDeclaration(node); - if (isEntityName(node) || isImportType || isPropertyAccessExpression(node)) { - const isNamespaceName = isModuleDeclaration(node.parent); - if (isNamespaceName) isNewIdentifierLocation = true; + || (isImportType && !(node as ts.ImportTypeNode).isTypeOf) + || ts.isPartOfTypeNode(node.parent) + || ts.isPossiblyTypeArgumentPosition(contextToken, sourceFile, typeChecker); + const isRhsOfImportDeclaration = ts.isInRightSideOfInternalImportEqualsDeclaration(node); + if (ts.isEntityName(node) || isImportType || ts.isPropertyAccessExpression(node)) { + const isNamespaceName = ts.isModuleDeclaration(node.parent); + if (isNamespaceName) + isNewIdentifierLocation = true; let symbol = typeChecker.getSymbolAtLocation(node); if (symbol) { - symbol = skipAlias(symbol, typeChecker); - if (symbol.flags & (SymbolFlags.Module | SymbolFlags.Enum)) { + symbol = ts.skipAlias(symbol, typeChecker); + if (symbol.flags & (ts.SymbolFlags.Module | ts.SymbolFlags.Enum)) { // Extract module or enum members const exportedSymbols = typeChecker.getExportsOfModule(symbol); - Debug.assertEachIsDefined(exportedSymbols, "getExportsOfModule() should all be defined"); - const isValidValueAccess = (symbol: Symbol) => typeChecker.isValidPropertyAccess(isImportType ? node as ImportTypeNode : (node.parent as PropertyAccessExpression), symbol.name); - const isValidTypeAccess = (symbol: Symbol) => symbolCanBeReferencedAtTypeLocation(symbol, typeChecker); - const isValidAccess: (symbol: Symbol) => boolean = - isNamespaceName + ts.Debug.assertEachIsDefined(exportedSymbols, "getExportsOfModule() should all be defined"); + const isValidValueAccess = (symbol: ts.Symbol) => typeChecker.isValidPropertyAccess(isImportType ? node as ts.ImportTypeNode : (node.parent as ts.PropertyAccessExpression), symbol.name); + const isValidTypeAccess = (symbol: ts.Symbol) => symbolCanBeReferencedAtTypeLocation(symbol, typeChecker); + const isValidAccess: (symbol: ts.Symbol) => boolean = isNamespaceName // At `namespace N.M/**/`, if this is the only declaration of `M`, don't include `M` as a completion. - ? symbol => !!(symbol.flags & SymbolFlags.Namespace) && !symbol.declarations?.every(d => d.parent === node.parent) + ? symbol => !!(symbol.flags & ts.SymbolFlags.Namespace) && !symbol.declarations?.every(d => d.parent === node.parent) : isRhsOfImportDeclaration ? // Any kind is allowed when dotting off namespace in internal import equals declaration symbol => isValidTypeAccess(symbol) || isValidValueAccess(symbol) : @@ -2342,12 +2007,11 @@ namespace ts.Completions { // If the module is merged with a value, we must get the type of the class and add its propertes (for inherited static methods). if (!isTypeLocation && symbol.declarations && - symbol.declarations.some(d => d.kind !== SyntaxKind.SourceFile && d.kind !== SyntaxKind.ModuleDeclaration && d.kind !== SyntaxKind.EnumDeclaration)) { + symbol.declarations.some(d => d.kind !== ts.SyntaxKind.SourceFile && d.kind !== ts.SyntaxKind.ModuleDeclaration && d.kind !== ts.SyntaxKind.EnumDeclaration)) { let type = typeChecker.getTypeOfSymbolAtLocation(symbol, node).getNonOptionalType(); let insertQuestionDot = false; if (type.isNullableType()) { - const canCorrectToQuestionDot = - isRightOfDot && + const canCorrectToQuestionDot = isRightOfDot && !isRightOfQuestionDot && preferences.includeAutomaticOptionalChainCompletions !== false; @@ -2358,7 +2022,7 @@ namespace ts.Completions { } } } - addTypeProperties(type, !!(node.flags & NodeFlags.AwaitContext), insertQuestionDot); + addTypeProperties(type, !!(node.flags & ts.NodeFlags.AwaitContext), insertQuestionDot); } return; @@ -2375,8 +2039,7 @@ namespace ts.Completions { let type = typeChecker.getTypeAtLocation(node).getNonOptionalType(); let insertQuestionDot = false; if (type.isNullableType()) { - const canCorrectToQuestionDot = - isRightOfDot && + const canCorrectToQuestionDot = isRightOfDot && !isRightOfQuestionDot && preferences.includeAutomaticOptionalChainCompletions !== false; @@ -2387,24 +2050,24 @@ namespace ts.Completions { } } } - addTypeProperties(type, !!(node.flags & NodeFlags.AwaitContext), insertQuestionDot); + addTypeProperties(type, !!(node.flags & ts.NodeFlags.AwaitContext), insertQuestionDot); } } - function addTypeProperties(type: Type, insertAwait: boolean, insertQuestionDot: boolean): void { + function addTypeProperties(type: ts.Type, insertAwait: boolean, insertQuestionDot: boolean): void { isNewIdentifierLocation = !!type.getStringIndexType(); - if (isRightOfQuestionDot && some(type.getCallSignatures())) { + if (isRightOfQuestionDot && ts.some(type.getCallSignatures())) { isNewIdentifierLocation = true; } - const propertyAccess = node.kind === SyntaxKind.ImportType ? node as ImportTypeNode : node.parent as PropertyAccessExpression | QualifiedName; + const propertyAccess = node.kind === ts.SyntaxKind.ImportType ? node as ts.ImportTypeNode : node.parent as ts.PropertyAccessExpression | ts.QualifiedName; if (inUncheckedFile) { // In javascript files, for union types, we don't just get the members that // the individual types have in common, we also include all the members that // each individual type has. This is because we're going to add all identifiers // anyways. So we might as well elevate the members that were at least part // of the individual types to a higher status since we know what they are. - symbols.push(...filter(getPropertiesForCompletion(type, typeChecker), s => typeChecker.isValidPropertyAccessForCompletions(propertyAccess, type, s))); + symbols.push(...ts.filter(getPropertiesForCompletion(type, typeChecker), s => typeChecker.isValidPropertyAccessForCompletions(propertyAccess, type, s))); } else { for (const symbol of type.getApparentProperties()) { @@ -2426,36 +2089,35 @@ namespace ts.Completions { } } - function addPropertySymbol(symbol: Symbol, insertAwait: boolean, insertQuestionDot: boolean) { + function addPropertySymbol(symbol: ts.Symbol, insertAwait: boolean, insertQuestionDot: boolean) { // For a computed property with an accessible name like `Symbol.iterator`, // we'll add a completion for the *name* `Symbol` instead of for the property. // If this is e.g. [Symbol.iterator], add a completion for `Symbol`. - const computedPropertyName = firstDefined(symbol.declarations, decl => tryCast(getNameOfDeclaration(decl), isComputedPropertyName)); + const computedPropertyName = ts.firstDefined(symbol.declarations, decl => ts.tryCast(ts.getNameOfDeclaration(decl), ts.isComputedPropertyName)); if (computedPropertyName) { const leftMostName = getLeftMostName(computedPropertyName.expression); // The completion is for `Symbol`, not `iterator`. const nameSymbol = leftMostName && typeChecker.getSymbolAtLocation(leftMostName); // If this is nested like for `namespace N { export const sym = Symbol(); }`, we'll add the completion for `N`. const firstAccessibleSymbol = nameSymbol && getFirstSymbolInChain(nameSymbol, contextToken, typeChecker); - if (firstAccessibleSymbol && addToSeen(seenPropertySymbols, getSymbolId(firstAccessibleSymbol))) { + if (firstAccessibleSymbol && ts.addToSeen(seenPropertySymbols, ts.getSymbolId(firstAccessibleSymbol))) { const index = symbols.length; symbols.push(firstAccessibleSymbol); const moduleSymbol = firstAccessibleSymbol.parent; if (!moduleSymbol || - !isExternalModuleSymbol(moduleSymbol) || - typeChecker.tryGetMemberInModuleExportsAndProperties(firstAccessibleSymbol.name, moduleSymbol) !== firstAccessibleSymbol - ) { + !ts.isExternalModuleSymbol(moduleSymbol) || + typeChecker.tryGetMemberInModuleExportsAndProperties(firstAccessibleSymbol.name, moduleSymbol) !== firstAccessibleSymbol) { symbolToOriginInfoMap[index] = { kind: getNullableSymbolOriginInfoKind(SymbolOriginInfoKind.SymbolMemberNoExport) }; } else { - const fileName = isExternalModuleNameRelative(stripQuotes(moduleSymbol.name)) ? getSourceFileOfModule(moduleSymbol)?.fileName : undefined; - const { moduleSpecifier } = codefix.getModuleSpecifierForBestExportInfo([{ - exportKind: ExportKind.Named, + const fileName = ts.isExternalModuleNameRelative(ts.stripQuotes(moduleSymbol.name)) ? ts.getSourceFileOfModule(moduleSymbol)?.fileName : undefined; + const { moduleSpecifier } = ts.codefix.getModuleSpecifierForBestExportInfo([{ + exportKind: ts.ExportKind.Named, moduleFileName: fileName, isFromPackageJson: false, moduleSymbol, symbol: firstAccessibleSymbol, - targetFlags: skipAlias(firstAccessibleSymbol, typeChecker).flags, - }], firstAccessibleSymbol.name, position, isValidTypeOnlyAliasUseSite(location), sourceFile, program, host, preferences) || {}; + targetFlags: ts.skipAlias(firstAccessibleSymbol, typeChecker).flags, + }], firstAccessibleSymbol.name, position, ts.isValidTypeOnlyAliasUseSite(location), sourceFile, program, host, preferences) || {}; if (moduleSpecifier) { const origin: SymbolOriginInfoResolvedExport = { @@ -2483,15 +2145,15 @@ namespace ts.Completions { symbols.push(symbol); } - function addSymbolSortInfo(symbol: Symbol) { + function addSymbolSortInfo(symbol: ts.Symbol) { if (isStaticProperty(symbol)) { - symbolToSortTextMap[getSymbolId(symbol)] = SortText.LocalDeclarationPriority; + symbolToSortTextMap[ts.getSymbolId(symbol)] = SortText.LocalDeclarationPriority; } } - function addSymbolOriginInfo(symbol: Symbol) { + function addSymbolOriginInfo(symbol: ts.Symbol) { if (preferences.includeCompletionsWithInsertText) { - if (insertAwait && addToSeen(seenPropertySymbols, getSymbolId(symbol))) { + if (insertAwait && ts.addToSeen(seenPropertySymbols, ts.getSymbolId(symbol))) { symbolToOriginInfoMap[symbols.length] = { kind: getNullableSymbolOriginInfoKind(SymbolOriginInfoKind.Promise) }; } else if (insertQuestionDot) { @@ -2506,8 +2168,8 @@ namespace ts.Completions { } /** Given 'a.b.c', returns 'a'. */ - function getLeftMostName(e: Expression): Identifier | undefined { - return isIdentifier(e) ? e : isPropertyAccessExpression(e) ? getLeftMostName(e.expression) : undefined; + function getLeftMostName(e: ts.Expression): ts.Identifier | undefined { + return ts.isIdentifier(e) ? e : ts.isPropertyAccessExpression(e) ? getLeftMostName(e.expression) : undefined; } function tryGetGlobalSymbols(): boolean { @@ -2524,7 +2186,8 @@ namespace ts.Completions { } function tryGetConstructorCompletion(): GlobalsSearch { - if (!tryGetConstructorLikeCompletionContainer(contextToken)) return GlobalsSearch.Continue; + if (!tryGetConstructorLikeCompletionContainer(contextToken)) + return GlobalsSearch.Continue; // no members, only keywords completionKind = CompletionKind.None; // Declaring new property/method/accessor @@ -2538,9 +2201,10 @@ namespace ts.Completions { const jsxContainer = tryGetContainingJsxElement(contextToken); // Cursor is inside a JSX self-closing element or opening element const attrsType = jsxContainer && typeChecker.getContextualType(jsxContainer.attributes); - if (!attrsType) return GlobalsSearch.Continue; - const completionsType = jsxContainer && typeChecker.getContextualType(jsxContainer.attributes, ContextFlags.Completions); - symbols = concatenate(symbols, filterJsxAttributes(getPropertiesForObjectExpression(attrsType, completionsType, jsxContainer.attributes, typeChecker), jsxContainer.attributes.properties)); + if (!attrsType) + return GlobalsSearch.Continue; + const completionsType = jsxContainer && typeChecker.getContextualType(jsxContainer.attributes, ts.ContextFlags.Completions); + symbols = ts.concatenate(symbols, filterJsxAttributes(getPropertiesForObjectExpression(attrsType, completionsType, jsxContainer.attributes, typeChecker), jsxContainer.attributes.properties)); setSortTextToOptionalMember(); completionKind = CompletionKind.MemberLike; isNewIdentifierLocation = false; @@ -2548,7 +2212,8 @@ namespace ts.Completions { } function tryGetImportCompletionSymbols(): GlobalsSearch { - if (!importCompletionNode) return GlobalsSearch.Continue; + if (!importCompletionNode) + return GlobalsSearch.Continue; isNewIdentifierLocation = true; collectAutoImports(); return GlobalsSearch.Success; @@ -2562,7 +2227,7 @@ namespace ts.Completions { isNewIdentifierLocation = isNewIdentifierDefinitionLocation(); if (previousToken !== contextToken) { - Debug.assert(!!previousToken, "Expected 'contextToken' to be defined when different from 'previousToken'."); + ts.Debug.assert(!!previousToken, "Expected 'contextToken' to be defined when different from 'previousToken'."); } // We need to find the node that will give us an appropriate scope to begin // aggregating completion candidates. This is achieved in 'getScopeNode' @@ -2596,19 +2261,18 @@ namespace ts.Completions { const scopeNode = getScopeNode(contextToken, adjustedPosition, sourceFile) || sourceFile; isInSnippetScope = isSnippetScope(scopeNode); - const symbolMeanings = (isTypeOnlyLocation ? SymbolFlags.None : SymbolFlags.Value) | SymbolFlags.Type | SymbolFlags.Namespace | SymbolFlags.Alias; - const typeOnlyAliasNeedsPromotion = previousToken && !isValidTypeOnlyAliasUseSite(previousToken); - - symbols = concatenate(symbols, typeChecker.getSymbolsInScope(scopeNode, symbolMeanings)); - Debug.assertEachIsDefined(symbols, "getSymbolsInScope() should all be defined"); + const symbolMeanings = (isTypeOnlyLocation ? ts.SymbolFlags.None : ts.SymbolFlags.Value) | ts.SymbolFlags.Type | ts.SymbolFlags.Namespace | ts.SymbolFlags.Alias; + const typeOnlyAliasNeedsPromotion = previousToken && !ts.isValidTypeOnlyAliasUseSite(previousToken); + symbols = ts.concatenate(symbols, typeChecker.getSymbolsInScope(scopeNode, symbolMeanings)); + ts.Debug.assertEachIsDefined(symbols, "getSymbolsInScope() should all be defined"); for (let i = 0; i < symbols.length; i++) { const symbol = symbols[i]; if (!typeChecker.isArgumentsSymbol(symbol) && - !some(symbol.declarations, d => d.getSourceFile() === sourceFile)) { - symbolToSortTextMap[getSymbolId(symbol)] = SortText.GlobalsOrKeywords; + !ts.some(symbol.declarations, d => d.getSourceFile() === sourceFile)) { + symbolToSortTextMap[ts.getSymbolId(symbol)] = SortText.GlobalsOrKeywords; } - if (typeOnlyAliasNeedsPromotion && !(symbol.flags & SymbolFlags.Value)) { - const typeOnlyAliasDeclaration = symbol.declarations && find(symbol.declarations, isTypeOnlyImportOrExportDeclaration); + if (typeOnlyAliasNeedsPromotion && !(symbol.flags & ts.SymbolFlags.Value)) { + const typeOnlyAliasDeclaration = symbol.declarations && ts.find(symbol.declarations, ts.isTypeOnlyImportOrExportDeclaration); if (typeOnlyAliasDeclaration) { const origin: SymbolOriginInfoTypeOnlyAlias = { kind: SymbolOriginInfoKind.TypeOnlyAlias, declaration: typeOnlyAliasDeclaration }; symbolToOriginInfoMap[i] = origin; @@ -2617,19 +2281,19 @@ namespace ts.Completions { } // Need to insert 'this.' before properties of `this` type, so only do that if `includeInsertTextCompletions` - if (preferences.includeCompletionsWithInsertText && scopeNode.kind !== SyntaxKind.SourceFile) { + if (preferences.includeCompletionsWithInsertText && scopeNode.kind !== ts.SyntaxKind.SourceFile) { const thisType = typeChecker.tryGetThisTypeAt(scopeNode, /*includeGlobalThis*/ false); if (thisType && !isProbablyGlobalType(thisType, sourceFile, typeChecker)) { for (const symbol of getPropertiesForCompletion(thisType, typeChecker)) { symbolToOriginInfoMap[symbols.length] = { kind: SymbolOriginInfoKind.ThisType }; symbols.push(symbol); - symbolToSortTextMap[getSymbolId(symbol)] = SortText.SuggestedClassMembers; + symbolToSortTextMap[ts.getSymbolId(symbol)] = SortText.SuggestedClassMembers; } } } collectAutoImports(); if (isTypeOnlyLocation) { - keywordFilters = contextToken && isAssertionExpression(contextToken.parent) + keywordFilters = contextToken && ts.isAssertionExpression(contextToken.parent) ? KeywordCompletionFilters.TypeAssertionKeywords : KeywordCompletionFilters.TypeKeywords; } @@ -2637,70 +2301,71 @@ namespace ts.Completions { function shouldOfferImportCompletions(): boolean { // If already typing an import statement, provide completions for it. - if (importCompletionNode) return true; + if (importCompletionNode) + return true; // If current completion is for non-contextual Object literal shortahands, ignore auto-import symbols - if (isNonContextualObjectLiteral) return false; + if (isNonContextualObjectLiteral) + return false; // If not already a module, must have modules enabled. - if (!preferences.includeCompletionsForModuleExports) return false; + if (!preferences.includeCompletionsForModuleExports) + return false; // If already using ES modules, OK to continue using them. - if (sourceFile.externalModuleIndicator || sourceFile.commonJsModuleIndicator) return true; + if (sourceFile.externalModuleIndicator || sourceFile.commonJsModuleIndicator) + return true; // If module transpilation is enabled or we're targeting es6 or above, or not emitting, OK. - if (compilerOptionsIndicateEsModules(program.getCompilerOptions())) return true; + if (ts.compilerOptionsIndicateEsModules(program.getCompilerOptions())) + return true; // If some file is using ES6 modules, assume that it's OK to add more. - return programContainsModules(program); + return ts.programContainsModules(program); } - function isSnippetScope(scopeNode: Node): boolean { + function isSnippetScope(scopeNode: ts.Node): boolean { switch (scopeNode.kind) { - case SyntaxKind.SourceFile: - case SyntaxKind.TemplateExpression: - case SyntaxKind.JsxExpression: - case SyntaxKind.Block: + case ts.SyntaxKind.SourceFile: + case ts.SyntaxKind.TemplateExpression: + case ts.SyntaxKind.JsxExpression: + case ts.SyntaxKind.Block: return true; default: - return isStatement(scopeNode); + return ts.isStatement(scopeNode); } } function isTypeOnlyCompletion(): boolean { return insideJsDocTagTypeExpression - || !!importCompletionNode && isTypeOnlyImportOrExportDeclaration(location.parent) + || !!importCompletionNode && ts.isTypeOnlyImportOrExportDeclaration(location.parent) || !isContextTokenValueLocation(contextToken) && - (isPossiblyTypeArgumentPosition(contextToken, sourceFile, typeChecker) - || isPartOfTypeNode(location) + (ts.isPossiblyTypeArgumentPosition(contextToken, sourceFile, typeChecker) + || ts.isPartOfTypeNode(location) || isContextTokenTypeLocation(contextToken)); } - function isContextTokenValueLocation(contextToken: Node) { + function isContextTokenValueLocation(contextToken: ts.Node) { return contextToken && - ((contextToken.kind === SyntaxKind.TypeOfKeyword && - (contextToken.parent.kind === SyntaxKind.TypeQuery || isTypeOfExpression(contextToken.parent))) || - (contextToken.kind === SyntaxKind.AssertsKeyword && contextToken.parent.kind === SyntaxKind.TypePredicate)); + ((contextToken.kind === ts.SyntaxKind.TypeOfKeyword && + (contextToken.parent.kind === ts.SyntaxKind.TypeQuery || ts.isTypeOfExpression(contextToken.parent))) || + (contextToken.kind === ts.SyntaxKind.AssertsKeyword && contextToken.parent.kind === ts.SyntaxKind.TypePredicate)); } - function isContextTokenTypeLocation(contextToken: Node): boolean { + function isContextTokenTypeLocation(contextToken: ts.Node): boolean { if (contextToken) { const parentKind = contextToken.parent.kind; switch (contextToken.kind) { - case SyntaxKind.ColonToken: - return parentKind === SyntaxKind.PropertyDeclaration || - parentKind === SyntaxKind.PropertySignature || - parentKind === SyntaxKind.Parameter || - parentKind === SyntaxKind.VariableDeclaration || - isFunctionLikeKind(parentKind); - - case SyntaxKind.EqualsToken: - return parentKind === SyntaxKind.TypeAliasDeclaration; - - case SyntaxKind.AsKeyword: - return parentKind === SyntaxKind.AsExpression; - - case SyntaxKind.LessThanToken: - return parentKind === SyntaxKind.TypeReference || - parentKind === SyntaxKind.TypeAssertionExpression; - - case SyntaxKind.ExtendsKeyword: - return parentKind === SyntaxKind.TypeParameter; + case ts.SyntaxKind.ColonToken: + return parentKind === ts.SyntaxKind.PropertyDeclaration || + parentKind === ts.SyntaxKind.PropertySignature || + parentKind === ts.SyntaxKind.Parameter || + parentKind === ts.SyntaxKind.VariableDeclaration || + ts.isFunctionLikeKind(parentKind); + case ts.SyntaxKind.EqualsToken: + return parentKind === ts.SyntaxKind.TypeAliasDeclaration; + case ts.SyntaxKind.AsKeyword: + return parentKind === ts.SyntaxKind.AsExpression; + case ts.SyntaxKind.LessThanToken: + return parentKind === ts.SyntaxKind.TypeReference || + parentKind === ts.SyntaxKind.TypeAssertionExpression; + case ts.SyntaxKind.ExtendsKeyword: + return parentKind === ts.SyntaxKind.TypeParameter; } } return false; @@ -2708,55 +2373,48 @@ namespace ts.Completions { /** Mutates `symbols`, `symbolToOriginInfoMap`, and `symbolToSortTextMap` */ function collectAutoImports() { - if (!shouldOfferImportCompletions()) return; - Debug.assert(!detailsEntryId?.data, "Should not run 'collectAutoImports' when faster path is available via `data`"); + if (!shouldOfferImportCompletions()) + return; + ts.Debug.assert(!detailsEntryId?.data, "Should not run 'collectAutoImports' when faster path is available via `data`"); if (detailsEntryId && !detailsEntryId.source) { // Asking for completion details for an item that is not an auto-import return; } - flags |= CompletionInfoFlags.MayIncludeAutoImports; + flags |= ts.CompletionInfoFlags.MayIncludeAutoImports; // import { type | -> token text should be blank const isAfterTypeOnlyImportSpecifierModifier = previousToken === contextToken && importCompletionNode && couldBeTypeOnlyImportSpecifier(importCompletionNode, contextToken); - const lowerCaseTokenText = - isAfterTypeOnlyImportSpecifierModifier ? "" : - previousToken && isIdentifier(previousToken) ? previousToken.text.toLowerCase() : + const lowerCaseTokenText = isAfterTypeOnlyImportSpecifierModifier ? "" : + previousToken && ts.isIdentifier(previousToken) ? previousToken.text.toLowerCase() : ""; const moduleSpecifierCache = host.getModuleSpecifierCache?.(); - const exportInfo = getExportInfoMap(sourceFile, host, program, cancellationToken); + const exportInfo = ts.getExportInfoMap(sourceFile, host, program, cancellationToken); const packageJsonAutoImportProvider = host.getPackageJsonAutoImportProvider?.(); - const packageJsonFilter = detailsEntryId ? undefined : createPackageJsonImportFilter(sourceFile, preferences, host); - resolvingModuleSpecifiers( - "collectAutoImports", - host, - program, - sourceFile, - position, - preferences, - !!importCompletionNode, - isValidTypeOnlyAliasUseSite(location), - context => { - exportInfo.search( - sourceFile.path, - /*preferCapitalized*/ isRightOfOpenTag, - (symbolName, targetFlags) => { - if (!isIdentifierText(symbolName, getEmitScriptTarget(host.getCompilationSettings()))) return false; - if (!detailsEntryId && isStringANonContextualKeyword(symbolName)) return false; - if (!isTypeOnlyLocation && !importCompletionNode && !(targetFlags & SymbolFlags.Value)) return false; - if (isTypeOnlyLocation && !(targetFlags & (SymbolFlags.Module | SymbolFlags.Type))) return false; + const packageJsonFilter = detailsEntryId ? undefined : ts.createPackageJsonImportFilter(sourceFile, preferences, host); + resolvingModuleSpecifiers("collectAutoImports", host, program, sourceFile, position, preferences, !!importCompletionNode, ts.isValidTypeOnlyAliasUseSite(location), context => { + exportInfo.search(sourceFile.path, + /*preferCapitalized*/ isRightOfOpenTag, (symbolName, targetFlags) => { + if (!ts.isIdentifierText(symbolName, ts.getEmitScriptTarget(host.getCompilationSettings()))) + return false; + if (!detailsEntryId && ts.isStringANonContextualKeyword(symbolName)) + return false; + if (!isTypeOnlyLocation && !importCompletionNode && !(targetFlags & ts.SymbolFlags.Value)) + return false; + if (isTypeOnlyLocation && !(targetFlags & (ts.SymbolFlags.Module | ts.SymbolFlags.Type))) + return false; // Do not try to auto-import something with a lowercase first letter for a JSX tag const firstChar = symbolName.charCodeAt(0); - if (isRightOfOpenTag && (firstChar < CharacterCodes.A || firstChar > CharacterCodes.Z)) return false; - - if (detailsEntryId) return true; + if (isRightOfOpenTag && (firstChar < ts.CharacterCodes.A || firstChar > ts.CharacterCodes.Z)) + return false; + if (detailsEntryId) + return true; return charactersFuzzyMatchInString(symbolName, lowerCaseTokenText); - }, - (info, symbolName, isFromAmbientModule, exportMapKey) => { - if (detailsEntryId && !some(info, i => detailsEntryId.source === stripQuotes(i.moduleSymbol.name))) { + }, (info, symbolName, isFromAmbientModule, exportMapKey) => { + if (detailsEntryId && !ts.some(info, i => detailsEntryId.source === ts.stripQuotes(i.moduleSymbol.name))) { return; } @@ -2765,7 +2423,7 @@ namespace ts.Completions { // module resolution modes, getting past this point guarantees that we'll be // able to generate a suitable module specifier, so we can safely show a completion, // even if we defer computing the module specifier. - const firstImportableExportInfo = find(info, isImportableExportInfo); + const firstImportableExportInfo = ts.find(info, isImportableExportInfo); if (!firstImportableExportInfo) { return; } @@ -2776,7 +2434,8 @@ namespace ts.Completions { // because we have to know now if it's going to fail so we can omit the completion // from the list. const result = context.tryResolve(info, symbolName, isFromAmbientModule) || {}; - if (result === "failed") return; + if (result === "failed") + return; // If we skipped resolving module specifiers, our selection of which ExportInfo // to use here is arbitrary, since the info shown in the completion list derived from @@ -2788,53 +2447,43 @@ namespace ts.Completions { ({ exportInfo = firstImportableExportInfo, moduleSpecifier } = result); } - const isDefaultExport = exportInfo.exportKind === ExportKind.Default; - const symbol = isDefaultExport && getLocalSymbolForExportDefault(exportInfo.symbol) || exportInfo.symbol; + const isDefaultExport = exportInfo.exportKind === ts.ExportKind.Default; + const symbol = isDefaultExport && ts.getLocalSymbolForExportDefault(exportInfo.symbol) || exportInfo.symbol; pushAutoImportSymbol(symbol, { kind: moduleSpecifier ? SymbolOriginInfoKind.ResolvedExport : SymbolOriginInfoKind.Export, moduleSpecifier, symbolName, exportMapKey, - exportName: exportInfo.exportKind === ExportKind.ExportEquals ? InternalSymbolName.ExportEquals : exportInfo.symbol.name, + exportName: exportInfo.exportKind === ts.ExportKind.ExportEquals ? ts.InternalSymbolName.ExportEquals : exportInfo.symbol.name, fileName: exportInfo.moduleFileName, isDefaultExport, moduleSymbol: exportInfo.moduleSymbol, isFromPackageJson: exportInfo.isFromPackageJson, }); - } - ); + }); hasUnresolvedAutoImports = context.skippedAny(); - flags |= context.resolvedAny() ? CompletionInfoFlags.ResolvedModuleSpecifiers : 0; - flags |= context.resolvedBeyondLimit() ? CompletionInfoFlags.ResolvedModuleSpecifiersBeyondLimit : 0; - } - ); - - function isImportableExportInfo(info: SymbolExportInfo) { - const moduleFile = tryCast(info.moduleSymbol.valueDeclaration, isSourceFile); + flags |= context.resolvedAny() ? ts.CompletionInfoFlags.ResolvedModuleSpecifiers : 0; + flags |= context.resolvedBeyondLimit() ? ts.CompletionInfoFlags.ResolvedModuleSpecifiersBeyondLimit : 0; + }); + function isImportableExportInfo(info: ts.SymbolExportInfo) { + const moduleFile = ts.tryCast(info.moduleSymbol.valueDeclaration, ts.isSourceFile); if (!moduleFile) { - const moduleName = stripQuotes(info.moduleSymbol.name); - if (JsTyping.nodeCoreModules.has(moduleName) && startsWith(moduleName, "node:") !== shouldUseUriStyleNodeCoreModules(sourceFile, program)) { + const moduleName = ts.stripQuotes(info.moduleSymbol.name); + if (ts.JsTyping.nodeCoreModules.has(moduleName) && ts.startsWith(moduleName, "node:") !== ts.shouldUseUriStyleNodeCoreModules(sourceFile, program)) { return false; } return packageJsonFilter ? packageJsonFilter.allowsImportingAmbientModule(info.moduleSymbol, getModuleSpecifierResolutionHost(info.isFromPackageJson)) : true; } - return isImportableFile( - info.isFromPackageJson ? packageJsonAutoImportProvider! : program, - sourceFile, - moduleFile, - preferences, - packageJsonFilter, - getModuleSpecifierResolutionHost(info.isFromPackageJson), - moduleSpecifierCache); + return ts.isImportableFile(info.isFromPackageJson ? packageJsonAutoImportProvider! : program, sourceFile, moduleFile, preferences, packageJsonFilter, getModuleSpecifierResolutionHost(info.isFromPackageJson), moduleSpecifierCache); } } - function pushAutoImportSymbol(symbol: Symbol, origin: SymbolOriginInfoResolvedExport | SymbolOriginInfoExport) { - const symbolId = getSymbolId(symbol); + function pushAutoImportSymbol(symbol: ts.Symbol, origin: SymbolOriginInfoResolvedExport | SymbolOriginInfoExport) { + const symbolId = ts.getSymbolId(symbol); if (symbolToSortTextMap[symbolId] === SortText.GlobalsOrKeywords) { // If an auto-importable symbol is available as a global, don't add the auto import return; @@ -2845,45 +2494,34 @@ namespace ts.Completions { } /* Mutates `symbols` and `symbolToOriginInfoMap`. */ - function collectObjectLiteralMethodSymbols(members: Symbol[], enclosingDeclaration: ObjectLiteralExpression): void { + function collectObjectLiteralMethodSymbols(members: ts.Symbol[], enclosingDeclaration: ts.ObjectLiteralExpression): void { // TODO: support JS files. - if (isInJSFile(location)) { + if (ts.isInJSFile(location)) { return; } members.forEach(member => { if (!isObjectLiteralMethodSymbol(member)) { return; } - const displayName = getCompletionEntryDisplayNameForSymbol( - member, - getEmitScriptTarget(compilerOptions), - /*origin*/ undefined, - CompletionKind.ObjectPropertyDeclaration, + const displayName = getCompletionEntryDisplayNameForSymbol(member, ts.getEmitScriptTarget(compilerOptions), + /*origin*/ undefined, CompletionKind.ObjectPropertyDeclaration, /*jsxIdentifierExpected*/ false); if (!displayName) { return; } const { name } = displayName; - const entryProps = getEntryForObjectLiteralMethodCompletion( - member, - name, - enclosingDeclaration, - program, - host, - compilerOptions, - preferences, - formatContext); + const entryProps = getEntryForObjectLiteralMethodCompletion(member, name, enclosingDeclaration, program, host, compilerOptions, preferences, formatContext); if (!entryProps) { return; } const origin: SymbolOriginInfoObjectLiteralMethod = { kind: SymbolOriginInfoKind.ObjectLiteralMethod, ...entryProps }; - flags |= CompletionInfoFlags.MayIncludeMethodSnippets; + flags |= ts.CompletionInfoFlags.MayIncludeMethodSnippets; symbolToOriginInfoMap[symbols.length] = origin; symbols.push(member); }); } - function isObjectLiteralMethodSymbol(symbol: Symbol): boolean { + function isObjectLiteralMethodSymbol(symbol: ts.Symbol): boolean { /* For an object type `type Foo = { @@ -2893,7 +2531,7 @@ namespace ts.Completions { `bar` will have symbol flag `Method`, `foo` will have symbol flag `Property`. */ - if (!(symbol.flags & (SymbolFlags.Property | SymbolFlags.Method))) { + if (!(symbol.flags & (ts.SymbolFlags.Property | ts.SymbolFlags.Method))) { return false; } return true; @@ -2903,50 +2541,50 @@ namespace ts.Completions { * Finds the first node that "embraces" the position, so that one may * accurately aggregate locals from the closest containing scope. */ - function getScopeNode(initialToken: Node | undefined, position: number, sourceFile: SourceFile) { - let scope: Node | undefined = initialToken; - while (scope && !positionBelongsToNode(scope, position, sourceFile)) { + function getScopeNode(initialToken: ts.Node | undefined, position: number, sourceFile: ts.SourceFile) { + let scope: ts.Node | undefined = initialToken; + while (scope && !ts.positionBelongsToNode(scope, position, sourceFile)) { scope = scope.parent; } return scope; } - function isCompletionListBlocker(contextToken: Node): boolean { - const start = timestamp(); + function isCompletionListBlocker(contextToken: ts.Node): boolean { + const start = ts.timestamp(); const result = isInStringOrRegularExpressionOrTemplateLiteral(contextToken) || isSolelyIdentifierDefinitionLocation(contextToken) || isDotOfNumericLiteral(contextToken) || isInJsxText(contextToken) || - isBigIntLiteral(contextToken); - log("getCompletionsAtPosition: isCompletionListBlocker: " + (timestamp() - start)); + ts.isBigIntLiteral(contextToken); + log("getCompletionsAtPosition: isCompletionListBlocker: " + (ts.timestamp() - start)); return result; } - function isInJsxText(contextToken: Node): boolean { - if (contextToken.kind === SyntaxKind.JsxText) { + function isInJsxText(contextToken: ts.Node): boolean { + if (contextToken.kind === ts.SyntaxKind.JsxText) { return true; } - if (contextToken.kind === SyntaxKind.GreaterThanToken && contextToken.parent) { + if (contextToken.kind === ts.SyntaxKind.GreaterThanToken && contextToken.parent) { // /**/ /> // /**/ > // - contextToken: GreaterThanToken (before cursor) // - location: JsxSelfClosingElement or JsxOpeningElement // - contextToken.parent === location - if (location === contextToken.parent && (location.kind === SyntaxKind.JsxOpeningElement || location.kind === SyntaxKind.JsxSelfClosingElement)) { + if (location === contextToken.parent && (location.kind === ts.SyntaxKind.JsxOpeningElement || location.kind === ts.SyntaxKind.JsxSelfClosingElement)) { return false; } - if (contextToken.parent.kind === SyntaxKind.JsxOpeningElement) { + if (contextToken.parent.kind === ts.SyntaxKind.JsxOpeningElement) { //
/**/ // - contextToken: GreaterThanToken (before cursor) // - location: JSXElement // - different parents (JSXOpeningElement, JSXElement) - return location.parent.kind !== SyntaxKind.JsxOpeningElement; + return location.parent.kind !== ts.SyntaxKind.JsxOpeningElement; } - if (contextToken.parent.kind === SyntaxKind.JsxClosingElement || contextToken.parent.kind === SyntaxKind.JsxSelfClosingElement) { - return !!contextToken.parent.parent && contextToken.parent.parent.kind === SyntaxKind.JsxElement; + if (contextToken.parent.kind === ts.SyntaxKind.JsxClosingElement || contextToken.parent.kind === ts.SyntaxKind.JsxSelfClosingElement) { + return !!contextToken.parent.parent && contextToken.parent.parent.kind === ts.SyntaxKind.JsxElement; } } return false; @@ -2958,55 +2596,46 @@ namespace ts.Completions { const tokenKind = keywordForNode(contextToken); // Previous token may have been a keyword that was converted to an identifier. switch (tokenKind) { - case SyntaxKind.CommaToken: - return containingNodeKind === SyntaxKind.CallExpression // func( a, | - || containingNodeKind === SyntaxKind.Constructor // constructor( a, | /* public, protected, private keywords are allowed here, so show completion */ - || containingNodeKind === SyntaxKind.NewExpression // new C(a, | - || containingNodeKind === SyntaxKind.ArrayLiteralExpression // [a, | - || containingNodeKind === SyntaxKind.BinaryExpression // const x = (a, | - || containingNodeKind === SyntaxKind.FunctionType // var x: (s: string, list| - || containingNodeKind === SyntaxKind.ObjectLiteralExpression; // const obj = { x, | - - case SyntaxKind.OpenParenToken: - return containingNodeKind === SyntaxKind.CallExpression // func( | - || containingNodeKind === SyntaxKind.Constructor // constructor( | - || containingNodeKind === SyntaxKind.NewExpression // new C(a| - || containingNodeKind === SyntaxKind.ParenthesizedExpression // const x = (a| - || containingNodeKind === SyntaxKind.ParenthesizedType; // function F(pred: (a| /* this can become an arrow function, where 'a' is the argument */ - - case SyntaxKind.OpenBracketToken: - return containingNodeKind === SyntaxKind.ArrayLiteralExpression // [ | - || containingNodeKind === SyntaxKind.IndexSignature // [ | : string ] - || containingNodeKind === SyntaxKind.ComputedPropertyName; // [ | /* this can become an index signature */ - - case SyntaxKind.ModuleKeyword: // module | - case SyntaxKind.NamespaceKeyword: // namespace | - case SyntaxKind.ImportKeyword: // import | + case ts.SyntaxKind.CommaToken: + return containingNodeKind === ts.SyntaxKind.CallExpression // func( a, | + || containingNodeKind === ts.SyntaxKind.Constructor // constructor( a, | /* public, protected, private keywords are allowed here, so show completion */ + || containingNodeKind === ts.SyntaxKind.NewExpression // new C(a, | + || containingNodeKind === ts.SyntaxKind.ArrayLiteralExpression // [a, | + || containingNodeKind === ts.SyntaxKind.BinaryExpression // const x = (a, | + || containingNodeKind === ts.SyntaxKind.FunctionType // var x: (s: string, list| + || containingNodeKind === ts.SyntaxKind.ObjectLiteralExpression; // const obj = { x, | + case ts.SyntaxKind.OpenParenToken: + return containingNodeKind === ts.SyntaxKind.CallExpression // func( | + || containingNodeKind === ts.SyntaxKind.Constructor // constructor( | + || containingNodeKind === ts.SyntaxKind.NewExpression // new C(a| + || containingNodeKind === ts.SyntaxKind.ParenthesizedExpression // const x = (a| + || containingNodeKind === ts.SyntaxKind.ParenthesizedType; // function F(pred: (a| /* this can become an arrow function, where 'a' is the argument */ + case ts.SyntaxKind.OpenBracketToken: + return containingNodeKind === ts.SyntaxKind.ArrayLiteralExpression // [ | + || containingNodeKind === ts.SyntaxKind.IndexSignature // [ | : string ] + || containingNodeKind === ts.SyntaxKind.ComputedPropertyName; // [ | /* this can become an index signature */ + case ts.SyntaxKind.ModuleKeyword: // module | + case ts.SyntaxKind.NamespaceKeyword: // namespace | + case ts.SyntaxKind.ImportKeyword: // import | return true; - case SyntaxKind.DotToken: - return containingNodeKind === SyntaxKind.ModuleDeclaration; // module A.| - - case SyntaxKind.OpenBraceToken: - return containingNodeKind === SyntaxKind.ClassDeclaration // class A { | - || containingNodeKind === SyntaxKind.ObjectLiteralExpression; // const obj = { | - - case SyntaxKind.EqualsToken: - return containingNodeKind === SyntaxKind.VariableDeclaration // const x = a| - || containingNodeKind === SyntaxKind.BinaryExpression; // x = a| - - case SyntaxKind.TemplateHead: - return containingNodeKind === SyntaxKind.TemplateExpression; // `aa ${| - - case SyntaxKind.TemplateMiddle: - return containingNodeKind === SyntaxKind.TemplateSpan; // `aa ${10} dd ${| - - case SyntaxKind.AsyncKeyword: - return containingNodeKind === SyntaxKind.MethodDeclaration // const obj = { async c|() - || containingNodeKind === SyntaxKind.ShorthandPropertyAssignment; // const obj = { async c| - - case SyntaxKind.AsteriskToken: - return containingNodeKind === SyntaxKind.MethodDeclaration; // const obj = { * c| + case ts.SyntaxKind.DotToken: + return containingNodeKind === ts.SyntaxKind.ModuleDeclaration; // module A.| + case ts.SyntaxKind.OpenBraceToken: + return containingNodeKind === ts.SyntaxKind.ClassDeclaration // class A { | + || containingNodeKind === ts.SyntaxKind.ObjectLiteralExpression; // const obj = { | + case ts.SyntaxKind.EqualsToken: + return containingNodeKind === ts.SyntaxKind.VariableDeclaration // const x = a| + || containingNodeKind === ts.SyntaxKind.BinaryExpression; // x = a| + case ts.SyntaxKind.TemplateHead: + return containingNodeKind === ts.SyntaxKind.TemplateExpression; // `aa ${| + case ts.SyntaxKind.TemplateMiddle: + return containingNodeKind === ts.SyntaxKind.TemplateSpan; // `aa ${10} dd ${| + case ts.SyntaxKind.AsyncKeyword: + return containingNodeKind === ts.SyntaxKind.MethodDeclaration // const obj = { async c|() + || containingNodeKind === ts.SyntaxKind.ShorthandPropertyAssignment; // const obj = { async c| + case ts.SyntaxKind.AsteriskToken: + return containingNodeKind === ts.SyntaxKind.MethodDeclaration; // const obj = { * c| } if (isClassMemberCompletionKeyword(tokenKind)) { @@ -3017,35 +2646,35 @@ namespace ts.Completions { return false; } - function isInStringOrRegularExpressionOrTemplateLiteral(contextToken: Node): boolean { + function isInStringOrRegularExpressionOrTemplateLiteral(contextToken: ts.Node): boolean { // To be "in" one of these literals, the position has to be: // 1. entirely within the token text. // 2. at the end position of an unterminated token. // 3. at the end of a regular expression (due to trailing flags like '/foo/g'). - return (isRegularExpressionLiteral(contextToken) || isStringTextContainingNode(contextToken)) && ( - rangeContainsPositionExclusive(createTextRangeFromSpan(createTextSpanFromNode(contextToken)), position) || - position === contextToken.end && (!!contextToken.isUnterminated || isRegularExpressionLiteral(contextToken))); + return (ts.isRegularExpressionLiteral(contextToken) || ts.isStringTextContainingNode(contextToken)) && (ts.rangeContainsPositionExclusive(ts.createTextRangeFromSpan(ts.createTextSpanFromNode(contextToken)), position) || + position === contextToken.end && (!!contextToken.isUnterminated || ts.isRegularExpressionLiteral(contextToken))); } function tryGetObjectTypeLiteralInTypeArgumentCompletionSymbols(): GlobalsSearch | undefined { const typeLiteralNode = tryGetTypeLiteralNode(contextToken); - if (!typeLiteralNode) return GlobalsSearch.Continue; - - const intersectionTypeNode = isIntersectionTypeNode(typeLiteralNode.parent) ? typeLiteralNode.parent : undefined; + if (!typeLiteralNode) + return GlobalsSearch.Continue; + const intersectionTypeNode = ts.isIntersectionTypeNode(typeLiteralNode.parent) ? typeLiteralNode.parent : undefined; const containerTypeNode = intersectionTypeNode || typeLiteralNode; const containerExpectedType = getConstraintOfTypeArgumentProperty(containerTypeNode, typeChecker); - if (!containerExpectedType) return GlobalsSearch.Continue; + if (!containerExpectedType) + return GlobalsSearch.Continue; const containerActualType = typeChecker.getTypeFromTypeNode(containerTypeNode); const members = getPropertiesForCompletion(containerExpectedType, typeChecker); const existingMembers = getPropertiesForCompletion(containerActualType, typeChecker); - const existingMemberEscapedNames: Set<__String> = new Set(); + const existingMemberEscapedNames: ts.Set = new ts.Set(); existingMembers.forEach(s => existingMemberEscapedNames.add(s.escapedName)); - symbols = concatenate(symbols, filter(members, s => !existingMemberEscapedNames.has(s.escapedName))); + symbols = ts.concatenate(symbols, ts.filter(members, s => !existingMemberEscapedNames.has(s.escapedName))); completionKind = CompletionKind.ObjectPropertyDeclaration; isNewIdentifierLocation = true; @@ -3062,26 +2691,26 @@ namespace ts.Completions { function tryGetObjectLikeCompletionSymbols(): GlobalsSearch | undefined { const symbolsStartIndex = symbols.length; const objectLikeContainer = tryGetObjectLikeCompletionContainer(contextToken); - if (!objectLikeContainer) return GlobalsSearch.Continue; + if (!objectLikeContainer) + return GlobalsSearch.Continue; // We're looking up possible property names from contextual/inferred/declared type. completionKind = CompletionKind.ObjectPropertyDeclaration; - let typeMembers: Symbol[] | undefined; - let existingMembers: readonly Declaration[] | undefined; - - if (objectLikeContainer.kind === SyntaxKind.ObjectLiteralExpression) { + let typeMembers: ts.Symbol[] | undefined; + let existingMembers: readonly ts.Declaration[] | undefined; + if (objectLikeContainer.kind === ts.SyntaxKind.ObjectLiteralExpression) { const instantiatedType = tryGetObjectLiteralContextualType(objectLikeContainer, typeChecker); // Check completions for Object property value shorthand if (instantiatedType === undefined) { - if (objectLikeContainer.flags & NodeFlags.InWithStatement) { + if (objectLikeContainer.flags & ts.NodeFlags.InWithStatement) { return GlobalsSearch.Fail; } isNonContextualObjectLiteral = true; return GlobalsSearch.Continue; } - const completionsType = typeChecker.getContextualType(objectLikeContainer, ContextFlags.Completions); + const completionsType = typeChecker.getContextualType(objectLikeContainer, ts.ContextFlags.Completions); const hasStringIndexType = (completionsType || instantiatedType).getStringIndexType(); const hasNumberIndextype = (completionsType || instantiatedType).getNumberIndexType(); isNewIdentifierLocation = !!hasStringIndexType || !!hasNumberIndextype; @@ -3097,30 +2726,32 @@ namespace ts.Completions { } } else { - Debug.assert(objectLikeContainer.kind === SyntaxKind.ObjectBindingPattern); + ts.Debug.assert(objectLikeContainer.kind === ts.SyntaxKind.ObjectBindingPattern); // We are *only* completing on properties from the type being destructured. isNewIdentifierLocation = false; - const rootDeclaration = getRootDeclaration(objectLikeContainer.parent); - if (!isVariableLike(rootDeclaration)) return Debug.fail("Root declaration is not variable-like."); + const rootDeclaration = ts.getRootDeclaration(objectLikeContainer.parent); + if (!ts.isVariableLike(rootDeclaration)) + return ts.Debug.fail("Root declaration is not variable-like."); // We don't want to complete using the type acquired by the shape // of the binding pattern; we are only interested in types acquired // through type declaration or inference. // Also proceed if rootDeclaration is a parameter and if its containing function expression/arrow function is contextually typed - // type of parameter will flow in from the contextual type of the function - let canGetType = hasInitializer(rootDeclaration) || !!getEffectiveTypeAnnotationNode(rootDeclaration) || rootDeclaration.parent.parent.kind === SyntaxKind.ForOfStatement; - if (!canGetType && rootDeclaration.kind === SyntaxKind.Parameter) { - if (isExpression(rootDeclaration.parent)) { - canGetType = !!typeChecker.getContextualType(rootDeclaration.parent as Expression); + let canGetType = ts.hasInitializer(rootDeclaration) || !!ts.getEffectiveTypeAnnotationNode(rootDeclaration) || rootDeclaration.parent.parent.kind === ts.SyntaxKind.ForOfStatement; + if (!canGetType && rootDeclaration.kind === ts.SyntaxKind.Parameter) { + if (ts.isExpression(rootDeclaration.parent)) { + canGetType = !!typeChecker.getContextualType(rootDeclaration.parent as ts.Expression); } - else if (rootDeclaration.parent.kind === SyntaxKind.MethodDeclaration || rootDeclaration.parent.kind === SyntaxKind.SetAccessor) { - canGetType = isExpression(rootDeclaration.parent.parent) && !!typeChecker.getContextualType(rootDeclaration.parent.parent as Expression); + else if (rootDeclaration.parent.kind === ts.SyntaxKind.MethodDeclaration || rootDeclaration.parent.kind === ts.SyntaxKind.SetAccessor) { + canGetType = ts.isExpression(rootDeclaration.parent.parent) && !!typeChecker.getContextualType(rootDeclaration.parent.parent as ts.Expression); } } if (canGetType) { const typeForObject = typeChecker.getTypeAtLocation(objectLikeContainer); - if (!typeForObject) return GlobalsSearch.Fail; + if (!typeForObject) + return GlobalsSearch.Fail; typeMembers = typeChecker.getPropertiesOfType(typeForObject).filter(propertySymbol => { return typeChecker.isPropertyAccessible(objectLikeContainer, /*isSuper*/ false, /*writing*/ false, typeForObject, propertySymbol); }); @@ -3130,10 +2761,10 @@ namespace ts.Completions { if (typeMembers && typeMembers.length > 0) { // Add filtered items to the completion list - const filteredMembers = filterObjectMembersList(typeMembers, Debug.checkDefined(existingMembers)); - symbols = concatenate(symbols, filteredMembers); + const filteredMembers = filterObjectMembersList(typeMembers, ts.Debug.checkDefined(existingMembers)); + symbols = ts.concatenate(symbols, filteredMembers); setSortTextToOptionalMember(); - if (objectLikeContainer.kind === SyntaxKind.ObjectLiteralExpression + if (objectLikeContainer.kind === ts.SyntaxKind.ObjectLiteralExpression && preferences.includeCompletionsWithObjectLiteralMethodSnippets && preferences.includeCompletionsWithInsertText) { transformObjectLiteralMembersSortText(symbolsStartIndex); @@ -3158,25 +2789,25 @@ namespace ts.Completions { * Relevant symbols are stored in the captured 'symbols' variable. */ function tryGetImportOrExportClauseCompletionSymbols(): GlobalsSearch { - if (!contextToken) return GlobalsSearch.Continue; + if (!contextToken) + return GlobalsSearch.Continue; // `import { |` or `import { a as 0, | }` or `import { type | }` - const namedImportsOrExports = - contextToken.kind === SyntaxKind.OpenBraceToken || contextToken.kind === SyntaxKind.CommaToken ? tryCast(contextToken.parent, isNamedImportsOrExports) : - isTypeKeywordTokenOrIdentifier(contextToken) ? tryCast(contextToken.parent.parent, isNamedImportsOrExports) : undefined; - - if (!namedImportsOrExports) return GlobalsSearch.Continue; + const namedImportsOrExports = contextToken.kind === ts.SyntaxKind.OpenBraceToken || contextToken.kind === ts.SyntaxKind.CommaToken ? ts.tryCast(contextToken.parent, ts.isNamedImportsOrExports) : + ts.isTypeKeywordTokenOrIdentifier(contextToken) ? ts.tryCast(contextToken.parent.parent, ts.isNamedImportsOrExports) : undefined; + if (!namedImportsOrExports) + return GlobalsSearch.Continue; // We can at least offer `type` at `import { |` - if (!isTypeKeywordTokenOrIdentifier(contextToken)) { + if (!ts.isTypeKeywordTokenOrIdentifier(contextToken)) { keywordFilters = KeywordCompletionFilters.TypeKeyword; } // try to show exported member for imported/re-exported module - const { moduleSpecifier } = namedImportsOrExports.kind === SyntaxKind.NamedImports ? namedImportsOrExports.parent.parent : namedImportsOrExports.parent; + const { moduleSpecifier } = namedImportsOrExports.kind === ts.SyntaxKind.NamedImports ? namedImportsOrExports.parent.parent : namedImportsOrExports.parent; if (!moduleSpecifier) { isNewIdentifierLocation = true; - return namedImportsOrExports.kind === SyntaxKind.NamedImports ? GlobalsSearch.Fail : GlobalsSearch.Continue; + return namedImportsOrExports.kind === ts.SyntaxKind.NamedImports ? GlobalsSearch.Fail : GlobalsSearch.Continue; } const moduleSpecifierSymbol = typeChecker.getSymbolAtLocation(moduleSpecifier); // TODO: GH#18217 if (!moduleSpecifierSymbol) { @@ -3187,9 +2818,9 @@ namespace ts.Completions { completionKind = CompletionKind.MemberLike; isNewIdentifierLocation = false; const exports = typeChecker.getExportsAndPropertiesOfModule(moduleSpecifierSymbol); - const existing = new Set((namedImportsOrExports.elements as NodeArray).filter(n => !isCurrentlyEditingNode(n)).map(n => (n.propertyName || n.name).escapedText)); - const uniques = exports.filter(e => e.escapedName !== InternalSymbolName.Default && !existing.has(e.escapedName)); - symbols = concatenate(symbols, uniques); + const existing = new ts.Set((namedImportsOrExports.elements as ts.NodeArray).filter(n => !isCurrentlyEditingNode(n)).map(n => (n.propertyName || n.name).escapedText)); + const uniques = exports.filter(e => e.escapedName !== ts.InternalSymbolName.Default && !existing.has(e.escapedName)); + symbols = ts.concatenate(symbols, uniques); if (!uniques.length) { // If there's nothing else to import, don't offer `type` either keywordFilters = KeywordCompletionFilters.None; @@ -3207,21 +2838,21 @@ namespace ts.Completions { * preventing this function from running. */ function tryGetLocalNamedExportCompletionSymbols(): GlobalsSearch { - const namedExports = contextToken && (contextToken.kind === SyntaxKind.OpenBraceToken || contextToken.kind === SyntaxKind.CommaToken) - ? tryCast(contextToken.parent, isNamedExports) + const namedExports = contextToken && (contextToken.kind === ts.SyntaxKind.OpenBraceToken || contextToken.kind === ts.SyntaxKind.CommaToken) + ? ts.tryCast(contextToken.parent, ts.isNamedExports) : undefined; if (!namedExports) { return GlobalsSearch.Continue; } - const localsContainer = findAncestor(namedExports, or(isSourceFile, isModuleDeclaration))!; + const localsContainer = ts.findAncestor(namedExports, ts.or(ts.isSourceFile, ts.isModuleDeclaration))!; completionKind = CompletionKind.None; isNewIdentifierLocation = false; localsContainer.locals?.forEach((symbol, name) => { symbols.push(symbol); if (localsContainer.symbol?.exports?.has(name)) { - symbolToSortTextMap[getSymbolId(symbol)] = SortText.OptionalMember; + symbolToSortTextMap[ts.getSymbolId(symbol)] = SortText.OptionalMember; } }); return GlobalsSearch.Success; @@ -3233,157 +2864,159 @@ namespace ts.Completions { */ function tryGetClassLikeCompletionSymbols(): GlobalsSearch { const decl = tryGetObjectTypeDeclarationCompletionContainer(sourceFile, contextToken, location, position); - if (!decl) return GlobalsSearch.Continue; + if (!decl) + return GlobalsSearch.Continue; // We're looking up possible property names from parent type. completionKind = CompletionKind.MemberLike; // Declaring new property/method/accessor isNewIdentifierLocation = true; - keywordFilters = contextToken.kind === SyntaxKind.AsteriskToken ? KeywordCompletionFilters.None : - isClassLike(decl) ? KeywordCompletionFilters.ClassElementKeywords : KeywordCompletionFilters.InterfaceElementKeywords; + keywordFilters = contextToken.kind === ts.SyntaxKind.AsteriskToken ? KeywordCompletionFilters.None : + ts.isClassLike(decl) ? KeywordCompletionFilters.ClassElementKeywords : KeywordCompletionFilters.InterfaceElementKeywords; // If you're in an interface you don't want to repeat things from super-interface. So just stop here. - if (!isClassLike(decl)) return GlobalsSearch.Success; - - const classElement = contextToken.kind === SyntaxKind.SemicolonToken ? contextToken.parent.parent : contextToken.parent; - let classElementModifierFlags = isClassElement(classElement) ? getEffectiveModifierFlags(classElement) : ModifierFlags.None; + if (!ts.isClassLike(decl)) + return GlobalsSearch.Success; + const classElement = contextToken.kind === ts.SyntaxKind.SemicolonToken ? contextToken.parent.parent : contextToken.parent; + let classElementModifierFlags = ts.isClassElement(classElement) ? ts.getEffectiveModifierFlags(classElement) : ts.ModifierFlags.None; // If this is context token is not something we are editing now, consider if this would lead to be modifier - if (contextToken.kind === SyntaxKind.Identifier && !isCurrentlyEditingNode(contextToken)) { + if (contextToken.kind === ts.SyntaxKind.Identifier && !isCurrentlyEditingNode(contextToken)) { switch (contextToken.getText()) { case "private": - classElementModifierFlags = classElementModifierFlags | ModifierFlags.Private; + classElementModifierFlags = classElementModifierFlags | ts.ModifierFlags.Private; break; case "static": - classElementModifierFlags = classElementModifierFlags | ModifierFlags.Static; + classElementModifierFlags = classElementModifierFlags | ts.ModifierFlags.Static; break; case "override": - classElementModifierFlags = classElementModifierFlags | ModifierFlags.Override; + classElementModifierFlags = classElementModifierFlags | ts.ModifierFlags.Override; break; } } - if (isClassStaticBlockDeclaration(classElement)) { - classElementModifierFlags |= ModifierFlags.Static; + if (ts.isClassStaticBlockDeclaration(classElement)) { + classElementModifierFlags |= ts.ModifierFlags.Static; } // No member list for private methods - if (!(classElementModifierFlags & ModifierFlags.Private)) { + if (!(classElementModifierFlags & ts.ModifierFlags.Private)) { // List of property symbols of base type that are not private and already implemented - const baseTypeNodes = isClassLike(decl) && classElementModifierFlags & ModifierFlags.Override ? singleElementArray(getEffectiveBaseTypeNode(decl)) : getAllSuperTypeNodes(decl); - const baseSymbols = flatMap(baseTypeNodes, baseTypeNode => { + const baseTypeNodes = ts.isClassLike(decl) && classElementModifierFlags & ts.ModifierFlags.Override ? ts.singleElementArray(ts.getEffectiveBaseTypeNode(decl)) : ts.getAllSuperTypeNodes(decl); + const baseSymbols = ts.flatMap(baseTypeNodes, baseTypeNode => { const type = typeChecker.getTypeAtLocation(baseTypeNode); - return classElementModifierFlags & ModifierFlags.Static ? + return classElementModifierFlags & ts.ModifierFlags.Static ? type?.symbol && typeChecker.getPropertiesOfType(typeChecker.getTypeOfSymbolAtLocation(type.symbol, decl)) : type && typeChecker.getPropertiesOfType(type); }); - symbols = concatenate(symbols, filterClassMembersList(baseSymbols, decl.members, classElementModifierFlags)); + symbols = ts.concatenate(symbols, filterClassMembersList(baseSymbols, decl.members, classElementModifierFlags)); } return GlobalsSearch.Success; } - function isConstructorParameterCompletion(node: Node): boolean { - return !!node.parent && isParameter(node.parent) && isConstructorDeclaration(node.parent.parent) - && (isParameterPropertyModifier(node.kind) || isDeclarationName(node)); + function isConstructorParameterCompletion(node: ts.Node): boolean { + return !!node.parent && ts.isParameter(node.parent) && ts.isConstructorDeclaration(node.parent.parent) + && (ts.isParameterPropertyModifier(node.kind) || ts.isDeclarationName(node)); } /** * Returns the immediate owning class declaration of a context token, * on the condition that one exists and that the context implies completion should be given. */ - function tryGetConstructorLikeCompletionContainer(contextToken: Node): ConstructorDeclaration | undefined { + function tryGetConstructorLikeCompletionContainer(contextToken: ts.Node): ts.ConstructorDeclaration | undefined { if (contextToken) { const parent = contextToken.parent; switch (contextToken.kind) { - case SyntaxKind.OpenParenToken: - case SyntaxKind.CommaToken: - return isConstructorDeclaration(contextToken.parent) ? contextToken.parent : undefined; + case ts.SyntaxKind.OpenParenToken: + case ts.SyntaxKind.CommaToken: + return ts.isConstructorDeclaration(contextToken.parent) ? contextToken.parent : undefined; default: if (isConstructorParameterCompletion(contextToken)) { - return parent.parent as ConstructorDeclaration; + return parent.parent as ts.ConstructorDeclaration; } } } return undefined; } - function tryGetFunctionLikeBodyCompletionContainer(contextToken: Node): FunctionLikeDeclaration | undefined { + function tryGetFunctionLikeBodyCompletionContainer(contextToken: ts.Node): ts.FunctionLikeDeclaration | undefined { if (contextToken) { - let prev: Node; - const container = findAncestor(contextToken.parent, (node: Node) => { - if (isClassLike(node)) { + let prev: ts.Node; + const container = ts.findAncestor(contextToken.parent, (node: ts.Node) => { + if (ts.isClassLike(node)) { return "quit"; } - if (isFunctionLikeDeclaration(node) && prev === node.body) { + if (ts.isFunctionLikeDeclaration(node) && prev === node.body) { return true; } prev = node; return false; }); - return container && container as FunctionLikeDeclaration; + return container && container as ts.FunctionLikeDeclaration; } } - function tryGetContainingJsxElement(contextToken: Node): JsxOpeningLikeElement | undefined { + function tryGetContainingJsxElement(contextToken: ts.Node): ts.JsxOpeningLikeElement | undefined { if (contextToken) { const parent = contextToken.parent; switch (contextToken.kind) { - case SyntaxKind.GreaterThanToken: // End of a type argument list - case SyntaxKind.LessThanSlashToken: - case SyntaxKind.SlashToken: - case SyntaxKind.Identifier: - case SyntaxKind.PropertyAccessExpression: - case SyntaxKind.JsxAttributes: - case SyntaxKind.JsxAttribute: - case SyntaxKind.JsxSpreadAttribute: - if (parent && (parent.kind === SyntaxKind.JsxSelfClosingElement || parent.kind === SyntaxKind.JsxOpeningElement)) { - if (contextToken.kind === SyntaxKind.GreaterThanToken) { - const precedingToken = findPrecedingToken(contextToken.pos, sourceFile, /*startNode*/ undefined); - if (!(parent as JsxOpeningLikeElement).typeArguments || (precedingToken && precedingToken.kind === SyntaxKind.SlashToken)) break; + case ts.SyntaxKind.GreaterThanToken: // End of a type argument list + case ts.SyntaxKind.LessThanSlashToken: + case ts.SyntaxKind.SlashToken: + case ts.SyntaxKind.Identifier: + case ts.SyntaxKind.PropertyAccessExpression: + case ts.SyntaxKind.JsxAttributes: + case ts.SyntaxKind.JsxAttribute: + case ts.SyntaxKind.JsxSpreadAttribute: + if (parent && (parent.kind === ts.SyntaxKind.JsxSelfClosingElement || parent.kind === ts.SyntaxKind.JsxOpeningElement)) { + if (contextToken.kind === ts.SyntaxKind.GreaterThanToken) { + const precedingToken = ts.findPrecedingToken(contextToken.pos, sourceFile, /*startNode*/ undefined); + if (!(parent as ts.JsxOpeningLikeElement).typeArguments || (precedingToken && precedingToken.kind === ts.SyntaxKind.SlashToken)) + break; } - return parent as JsxOpeningLikeElement; + return parent as ts.JsxOpeningLikeElement; } - else if (parent.kind === SyntaxKind.JsxAttribute) { + else if (parent.kind === ts.SyntaxKind.JsxAttribute) { // Currently we parse JsxOpeningLikeElement as: // JsxOpeningLikeElement // attributes: JsxAttributes // properties: NodeArray - return parent.parent.parent as JsxOpeningLikeElement; + return parent.parent.parent as ts.JsxOpeningLikeElement; } break; // The context token is the closing } or " of an attribute, which means // its parent is a JsxExpression, whose parent is a JsxAttribute, // whose parent is a JsxOpeningLikeElement - case SyntaxKind.StringLiteral: - if (parent && ((parent.kind === SyntaxKind.JsxAttribute) || (parent.kind === SyntaxKind.JsxSpreadAttribute))) { + case ts.SyntaxKind.StringLiteral: + if (parent && ((parent.kind === ts.SyntaxKind.JsxAttribute) || (parent.kind === ts.SyntaxKind.JsxSpreadAttribute))) { // Currently we parse JsxOpeningLikeElement as: // JsxOpeningLikeElement // attributes: JsxAttributes // properties: NodeArray - return parent.parent.parent as JsxOpeningLikeElement; + return parent.parent.parent as ts.JsxOpeningLikeElement; } break; - case SyntaxKind.CloseBraceToken: + case ts.SyntaxKind.CloseBraceToken: if (parent && - parent.kind === SyntaxKind.JsxExpression && - parent.parent && parent.parent.kind === SyntaxKind.JsxAttribute) { + parent.kind === ts.SyntaxKind.JsxExpression && + parent.parent && parent.parent.kind === ts.SyntaxKind.JsxAttribute) { // Currently we parse JsxOpeningLikeElement as: // JsxOpeningLikeElement // attributes: JsxAttributes // properties: NodeArray // each JsxAttribute can have initializer as JsxExpression - return parent.parent.parent.parent as JsxOpeningLikeElement; + return parent.parent.parent.parent as ts.JsxOpeningLikeElement; } - if (parent && parent.kind === SyntaxKind.JsxSpreadAttribute) { + if (parent && parent.kind === ts.SyntaxKind.JsxSpreadAttribute) { // Currently we parse JsxOpeningLikeElement as: // JsxOpeningLikeElement // attributes: JsxAttributes // properties: NodeArray - return parent.parent.parent as JsxOpeningLikeElement; + return parent.parent.parent as ts.JsxOpeningLikeElement; } break; @@ -3395,96 +3028,85 @@ namespace ts.Completions { /** * @returns true if we are certain that the currently edited location must define a new location; false otherwise. */ - function isSolelyIdentifierDefinitionLocation(contextToken: Node): boolean { + function isSolelyIdentifierDefinitionLocation(contextToken: ts.Node): boolean { const parent = contextToken.parent; const containingNodeKind = parent.kind; switch (contextToken.kind) { - case SyntaxKind.CommaToken: - return containingNodeKind === SyntaxKind.VariableDeclaration || + case ts.SyntaxKind.CommaToken: + return containingNodeKind === ts.SyntaxKind.VariableDeclaration || isVariableDeclarationListButNotTypeArgument(contextToken) || - containingNodeKind === SyntaxKind.VariableStatement || - containingNodeKind === SyntaxKind.EnumDeclaration || // enum a { foo, | + containingNodeKind === ts.SyntaxKind.VariableStatement || + containingNodeKind === ts.SyntaxKind.EnumDeclaration || // enum a { foo, | isFunctionLikeButNotConstructor(containingNodeKind) || - containingNodeKind === SyntaxKind.InterfaceDeclaration || // interface A= contextToken.pos); - case SyntaxKind.DotToken: - return containingNodeKind === SyntaxKind.ArrayBindingPattern; // var [.| - - case SyntaxKind.ColonToken: - return containingNodeKind === SyntaxKind.BindingElement; // var {x :html| - - case SyntaxKind.OpenBracketToken: - return containingNodeKind === SyntaxKind.ArrayBindingPattern; // var [x| - - case SyntaxKind.OpenParenToken: - return containingNodeKind === SyntaxKind.CatchClause || + case ts.SyntaxKind.DotToken: + return containingNodeKind === ts.SyntaxKind.ArrayBindingPattern; // var [.| + case ts.SyntaxKind.ColonToken: + return containingNodeKind === ts.SyntaxKind.BindingElement; // var {x :html| + case ts.SyntaxKind.OpenBracketToken: + return containingNodeKind === ts.SyntaxKind.ArrayBindingPattern; // var [x| + case ts.SyntaxKind.OpenParenToken: + return containingNodeKind === ts.SyntaxKind.CatchClause || isFunctionLikeButNotConstructor(containingNodeKind); - case SyntaxKind.OpenBraceToken: - return containingNodeKind === SyntaxKind.EnumDeclaration; // enum a { | - - case SyntaxKind.LessThanToken: - return containingNodeKind === SyntaxKind.ClassDeclaration || // class A< | - containingNodeKind === SyntaxKind.ClassExpression || // var C = class D< | - containingNodeKind === SyntaxKind.InterfaceDeclaration || // interface A< | - containingNodeKind === SyntaxKind.TypeAliasDeclaration || // type List< | - isFunctionLikeKind(containingNodeKind); - - case SyntaxKind.StaticKeyword: - return containingNodeKind === SyntaxKind.PropertyDeclaration && !isClassLike(parent.parent); - - case SyntaxKind.DotDotDotToken: - return containingNodeKind === SyntaxKind.Parameter || - (!!parent.parent && parent.parent.kind === SyntaxKind.ArrayBindingPattern); // var [...z| - - case SyntaxKind.PublicKeyword: - case SyntaxKind.PrivateKeyword: - case SyntaxKind.ProtectedKeyword: - return containingNodeKind === SyntaxKind.Parameter && !isConstructorDeclaration(parent.parent); - - case SyntaxKind.AsKeyword: - return containingNodeKind === SyntaxKind.ImportSpecifier || - containingNodeKind === SyntaxKind.ExportSpecifier || - containingNodeKind === SyntaxKind.NamespaceImport; - - case SyntaxKind.GetKeyword: - case SyntaxKind.SetKeyword: + case ts.SyntaxKind.OpenBraceToken: + return containingNodeKind === ts.SyntaxKind.EnumDeclaration; // enum a { | + case ts.SyntaxKind.LessThanToken: + return containingNodeKind === ts.SyntaxKind.ClassDeclaration || // class A< | + containingNodeKind === ts.SyntaxKind.ClassExpression || // var C = class D< | + containingNodeKind === ts.SyntaxKind.InterfaceDeclaration || // interface A< | + containingNodeKind === ts.SyntaxKind.TypeAliasDeclaration || // type List< | + ts.isFunctionLikeKind(containingNodeKind); + case ts.SyntaxKind.StaticKeyword: + return containingNodeKind === ts.SyntaxKind.PropertyDeclaration && !ts.isClassLike(parent.parent); + case ts.SyntaxKind.DotDotDotToken: + return containingNodeKind === ts.SyntaxKind.Parameter || + (!!parent.parent && parent.parent.kind === ts.SyntaxKind.ArrayBindingPattern); // var [...z| + case ts.SyntaxKind.PublicKeyword: + case ts.SyntaxKind.PrivateKeyword: + case ts.SyntaxKind.ProtectedKeyword: + return containingNodeKind === ts.SyntaxKind.Parameter && !ts.isConstructorDeclaration(parent.parent); + case ts.SyntaxKind.AsKeyword: + return containingNodeKind === ts.SyntaxKind.ImportSpecifier || + containingNodeKind === ts.SyntaxKind.ExportSpecifier || + containingNodeKind === ts.SyntaxKind.NamespaceImport; + case ts.SyntaxKind.GetKeyword: + case ts.SyntaxKind.SetKeyword: return !isFromObjectTypeDeclaration(contextToken); - case SyntaxKind.Identifier: - if (containingNodeKind === SyntaxKind.ImportSpecifier && - contextToken === (parent as ImportSpecifier).name && - (contextToken as Identifier).text === "type" - ) { + case ts.SyntaxKind.Identifier: + if (containingNodeKind === ts.SyntaxKind.ImportSpecifier && + contextToken === (parent as ts.ImportSpecifier).name && + (contextToken as ts.Identifier).text === "type") { // import { type | } return false; } break; - case SyntaxKind.ClassKeyword: - case SyntaxKind.EnumKeyword: - case SyntaxKind.InterfaceKeyword: - case SyntaxKind.FunctionKeyword: - case SyntaxKind.VarKeyword: - case SyntaxKind.ImportKeyword: - case SyntaxKind.LetKeyword: - case SyntaxKind.ConstKeyword: - case SyntaxKind.InferKeyword: + case ts.SyntaxKind.ClassKeyword: + case ts.SyntaxKind.EnumKeyword: + case ts.SyntaxKind.InterfaceKeyword: + case ts.SyntaxKind.FunctionKeyword: + case ts.SyntaxKind.VarKeyword: + case ts.SyntaxKind.ImportKeyword: + case ts.SyntaxKind.LetKeyword: + case ts.SyntaxKind.ConstKeyword: + case ts.SyntaxKind.InferKeyword: return true; - case SyntaxKind.TypeKeyword: + case ts.SyntaxKind.TypeKeyword: // import { type foo| } - return containingNodeKind !== SyntaxKind.ImportSpecifier; - - case SyntaxKind.AsteriskToken: - return isFunctionLike(contextToken.parent) && !isMethodDeclaration(contextToken.parent); + return containingNodeKind !== ts.SyntaxKind.ImportSpecifier; + case ts.SyntaxKind.AsteriskToken: + return ts.isFunctionLike(contextToken.parent) && !ts.isMethodDeclaration(contextToken.parent); } // If the previous token is keyword corresponding to class member completion keyword @@ -3498,8 +3120,8 @@ namespace ts.Completions { // - its modifier of the constructor parameter or // - its name of the parameter and not being edited // eg. constructor(a |<- this shouldnt show completion - if (!isIdentifier(contextToken) || - isParameterPropertyModifier(keywordForNode(contextToken)) || + if (!ts.isIdentifier(contextToken) || + ts.isParameterPropertyModifier(keywordForNode(contextToken)) || isCurrentlyEditingNode(contextToken)) { return false; } @@ -3507,71 +3129,71 @@ namespace ts.Completions { // Previous token may have been a keyword that was converted to an identifier. switch (keywordForNode(contextToken)) { - case SyntaxKind.AbstractKeyword: - case SyntaxKind.ClassKeyword: - case SyntaxKind.ConstKeyword: - case SyntaxKind.DeclareKeyword: - case SyntaxKind.EnumKeyword: - case SyntaxKind.FunctionKeyword: - case SyntaxKind.InterfaceKeyword: - case SyntaxKind.LetKeyword: - case SyntaxKind.PrivateKeyword: - case SyntaxKind.ProtectedKeyword: - case SyntaxKind.PublicKeyword: - case SyntaxKind.StaticKeyword: - case SyntaxKind.VarKeyword: + case ts.SyntaxKind.AbstractKeyword: + case ts.SyntaxKind.ClassKeyword: + case ts.SyntaxKind.ConstKeyword: + case ts.SyntaxKind.DeclareKeyword: + case ts.SyntaxKind.EnumKeyword: + case ts.SyntaxKind.FunctionKeyword: + case ts.SyntaxKind.InterfaceKeyword: + case ts.SyntaxKind.LetKeyword: + case ts.SyntaxKind.PrivateKeyword: + case ts.SyntaxKind.ProtectedKeyword: + case ts.SyntaxKind.PublicKeyword: + case ts.SyntaxKind.StaticKeyword: + case ts.SyntaxKind.VarKeyword: return true; - case SyntaxKind.AsyncKeyword: - return isPropertyDeclaration(contextToken.parent); + case ts.SyntaxKind.AsyncKeyword: + return ts.isPropertyDeclaration(contextToken.parent); } // If we are inside a class declaration, and `constructor` is totally not present, // but we request a completion manually at a whitespace... - const ancestorClassLike = findAncestor(contextToken.parent, isClassLike); + const ancestorClassLike = ts.findAncestor(contextToken.parent, ts.isClassLike); if (ancestorClassLike && contextToken === previousToken && isPreviousPropertyDeclarationTerminated(contextToken, position)) { return false; // Don't block completions. } - const ancestorPropertyDeclaraion = getAncestor(contextToken.parent, SyntaxKind.PropertyDeclaration); + const ancestorPropertyDeclaraion = ts.getAncestor(contextToken.parent, ts.SyntaxKind.PropertyDeclaration); // If we are inside a class declaration and typing `constructor` after property declaration... if (ancestorPropertyDeclaraion && contextToken !== previousToken - && isClassLike(previousToken.parent.parent) + && ts.isClassLike(previousToken.parent.parent) // And the cursor is at the token... && position <= previousToken.end) { // If we are sure that the previous property declaration is terminated according to newline or semicolon... if (isPreviousPropertyDeclarationTerminated(contextToken, previousToken.end)) { return false; // Don't block completions. } - else if (contextToken.kind !== SyntaxKind.EqualsToken + else if (contextToken.kind !== ts.SyntaxKind.EqualsToken // Should not block: `class C { blah = c/**/ }` // But should block: `class C { blah = somewhat c/**/ }` and `class C { blah: SomeType c/**/ }` - && (isInitializedProperty(ancestorPropertyDeclaraion as PropertyDeclaration) - || hasType(ancestorPropertyDeclaraion))) { + && (ts.isInitializedProperty(ancestorPropertyDeclaraion as ts.PropertyDeclaration) + || ts.hasType(ancestorPropertyDeclaraion))) { return true; } } - return isDeclarationName(contextToken) - && !isShorthandPropertyAssignment(contextToken.parent) - && !isJsxAttribute(contextToken.parent) + return ts.isDeclarationName(contextToken) + && !ts.isShorthandPropertyAssignment(contextToken.parent) + && !ts.isJsxAttribute(contextToken.parent) // Don't block completions if we're in `class C /**/`, because we're *past* the end of the identifier and might want to complete `extends`. // If `contextToken !== previousToken`, this is `class C ex/**/`. - && !(isClassLike(contextToken.parent) && (contextToken !== previousToken || position > previousToken.end)); + && !(ts.isClassLike(contextToken.parent) && (contextToken !== previousToken || position > previousToken.end)); } - function isPreviousPropertyDeclarationTerminated(contextToken: Node, position: number) { - return contextToken.kind !== SyntaxKind.EqualsToken && - (contextToken.kind === SyntaxKind.SemicolonToken - || !positionsAreOnSameLine(contextToken.end, position, sourceFile)); + function isPreviousPropertyDeclarationTerminated(contextToken: ts.Node, position: number) { + return contextToken.kind !== ts.SyntaxKind.EqualsToken && + (contextToken.kind === ts.SyntaxKind.SemicolonToken + || !ts.positionsAreOnSameLine(contextToken.end, position, sourceFile)); } - function isFunctionLikeButNotConstructor(kind: SyntaxKind) { - return isFunctionLikeKind(kind) && kind !== SyntaxKind.Constructor; + function isFunctionLikeButNotConstructor(kind: ts.SyntaxKind) { + return ts.isFunctionLikeKind(kind) && kind !== ts.SyntaxKind.Constructor; } - function isDotOfNumericLiteral(contextToken: Node): boolean { - if (contextToken.kind === SyntaxKind.NumericLiteral) { + function isDotOfNumericLiteral(contextToken: ts.Node): boolean { + if (contextToken.kind === ts.SyntaxKind.NumericLiteral) { const text = contextToken.getFullText(); return text.charAt(text.length - 1) === "."; } @@ -3579,9 +3201,9 @@ namespace ts.Completions { return false; } - function isVariableDeclarationListButNotTypeArgument(node: Node): boolean { - return node.parent.kind === SyntaxKind.VariableDeclarationList - && !isPossiblyTypeArgumentPosition(node, sourceFile, typeChecker); + function isVariableDeclarationListButNotTypeArgument(node: ts.Node): boolean { + return node.parent.kind === ts.SyntaxKind.VariableDeclarationList + && !ts.isPossiblyTypeArgumentPosition(node, sourceFile, typeChecker); } /** @@ -3590,22 +3212,22 @@ namespace ts.Completions { * @returns Symbols to be suggested in an object binding pattern or object literal expression, barring those whose declarations * do not occur at the current position and have not otherwise been typed. */ - function filterObjectMembersList(contextualMemberSymbols: Symbol[], existingMembers: readonly Declaration[]): Symbol[] { + function filterObjectMembersList(contextualMemberSymbols: ts.Symbol[], existingMembers: readonly ts.Declaration[]): ts.Symbol[] { if (existingMembers.length === 0) { return contextualMemberSymbols; } - const membersDeclaredBySpreadAssignment = new Set(); - const existingMemberNames = new Set<__String>(); + const membersDeclaredBySpreadAssignment = new ts.Set(); + const existingMemberNames = new ts.Set(); for (const m of existingMembers) { // Ignore omitted expressions for missing members - if (m.kind !== SyntaxKind.PropertyAssignment && - m.kind !== SyntaxKind.ShorthandPropertyAssignment && - m.kind !== SyntaxKind.BindingElement && - m.kind !== SyntaxKind.MethodDeclaration && - m.kind !== SyntaxKind.GetAccessor && - m.kind !== SyntaxKind.SetAccessor && - m.kind !== SyntaxKind.SpreadAssignment) { + if (m.kind !== ts.SyntaxKind.PropertyAssignment && + m.kind !== ts.SyntaxKind.ShorthandPropertyAssignment && + m.kind !== ts.SyntaxKind.BindingElement && + m.kind !== ts.SyntaxKind.MethodDeclaration && + m.kind !== ts.SyntaxKind.GetAccessor && + m.kind !== ts.SyntaxKind.SetAccessor && + m.kind !== ts.SyntaxKind.SpreadAssignment) { continue; } @@ -3614,14 +3236,13 @@ namespace ts.Completions { continue; } - let existingName: __String | undefined; - - if (isSpreadAssignment(m)) { + let existingName: ts.__String | undefined; + if (ts.isSpreadAssignment(m)) { setMembersDeclaredBySpreadAssignment(m, membersDeclaredBySpreadAssignment); } - else if (isBindingElement(m) && m.propertyName) { + else if (ts.isBindingElement(m) && m.propertyName) { // include only identifiers in completion list - if (m.propertyName.kind === SyntaxKind.Identifier) { + if (m.propertyName.kind === ts.SyntaxKind.Identifier) { existingName = m.propertyName.escapedText; } } @@ -3629,8 +3250,8 @@ namespace ts.Completions { // TODO: Account for computed property name // NOTE: if one only performs this step when m.name is an identifier, // things like '__proto__' are not filtered out. - const name = getNameOfDeclaration(m); - existingName = name && isPropertyNameLiteral(name) ? getEscapedTextOfIdentifierOrLiteral(name) : undefined; + const name = ts.getNameOfDeclaration(m); + existingName = name && ts.isPropertyNameLiteral(name) ? ts.getEscapedTextOfIdentifierOrLiteral(name) : undefined; } if (existingName !== undefined) { @@ -3644,11 +3265,11 @@ namespace ts.Completions { return filteredSymbols; } - function setMembersDeclaredBySpreadAssignment(declaration: SpreadAssignment | JsxSpreadAttribute, membersDeclaredBySpreadAssignment: Set) { + function setMembersDeclaredBySpreadAssignment(declaration: ts.SpreadAssignment | ts.JsxSpreadAttribute, membersDeclaredBySpreadAssignment: ts.Set) { const expression = declaration.expression; const symbol = typeChecker.getSymbolAtLocation(expression); const type = symbol && typeChecker.getTypeOfSymbolAtLocation(symbol, expression); - const properties = type && (type as ObjectType).properties; + const properties = type && (type as ts.ObjectType).properties; if (properties) { properties.forEach(property => { membersDeclaredBySpreadAssignment.add(property.name); @@ -3659,21 +3280,21 @@ namespace ts.Completions { // Set SortText to OptionalMember if it is an optional member function setSortTextToOptionalMember() { symbols.forEach(m => { - if (m.flags & SymbolFlags.Optional) { - const symbolId = getSymbolId(m); + if (m.flags & ts.SymbolFlags.Optional) { + const symbolId = ts.getSymbolId(m); symbolToSortTextMap[symbolId] = symbolToSortTextMap[symbolId] ?? SortText.OptionalMember; } }); } // Set SortText to MemberDeclaredBySpreadAssignment if it is fulfilled by spread assignment - function setSortTextToMemberDeclaredBySpreadAssignment(membersDeclaredBySpreadAssignment: Set, contextualMemberSymbols: Symbol[]): void { + function setSortTextToMemberDeclaredBySpreadAssignment(membersDeclaredBySpreadAssignment: ts.Set, contextualMemberSymbols: ts.Symbol[]): void { if (membersDeclaredBySpreadAssignment.size === 0) { return; } for (const contextualMemberSymbol of contextualMemberSymbols) { if (membersDeclaredBySpreadAssignment.has(contextualMemberSymbol.name)) { - symbolToSortTextMap[getSymbolId(contextualMemberSymbol)] = SortText.MemberDeclaredBySpreadAssignment; + symbolToSortTextMap[ts.getSymbolId(contextualMemberSymbol)] = SortText.MemberDeclaredBySpreadAssignment; } } } @@ -3681,14 +3302,10 @@ namespace ts.Completions { function transformObjectLiteralMembersSortText(start: number): void { for (let i = start; i < symbols.length; i++) { const symbol = symbols[i]; - const symbolId = getSymbolId(symbol); + const symbolId = ts.getSymbolId(symbol); const origin = symbolToOriginInfoMap?.[i]; - const target = getEmitScriptTarget(compilerOptions); - const displayName = getCompletionEntryDisplayNameForSymbol( - symbol, - target, - origin, - CompletionKind.ObjectPropertyDeclaration, + const target = ts.getEmitScriptTarget(compilerOptions); + const displayName = getCompletionEntryDisplayNameForSymbol(symbol, target, origin, CompletionKind.ObjectPropertyDeclaration, /*jsxIdentifierExpected*/ false); if (displayName) { const originalSortText = symbolToSortTextMap[symbolId] ?? SortText.LocationPriority; @@ -3703,14 +3320,14 @@ namespace ts.Completions { * * @returns Symbols to be suggested in an class element depending on existing memebers and symbol flags */ - function filterClassMembersList(baseSymbols: readonly Symbol[], existingMembers: readonly ClassElement[], currentClassElementModifierFlags: ModifierFlags): Symbol[] { - const existingMemberNames = new Set<__String>(); + function filterClassMembersList(baseSymbols: readonly ts.Symbol[], existingMembers: readonly ts.ClassElement[], currentClassElementModifierFlags: ts.ModifierFlags): ts.Symbol[] { + const existingMemberNames = new ts.Set(); for (const m of existingMembers) { // Ignore omitted expressions for missing members - if (m.kind !== SyntaxKind.PropertyDeclaration && - m.kind !== SyntaxKind.MethodDeclaration && - m.kind !== SyntaxKind.GetAccessor && - m.kind !== SyntaxKind.SetAccessor) { + if (m.kind !== ts.SyntaxKind.PropertyDeclaration && + m.kind !== ts.SyntaxKind.MethodDeclaration && + m.kind !== ts.SyntaxKind.GetAccessor && + m.kind !== ts.SyntaxKind.SetAccessor) { continue; } @@ -3720,26 +3337,25 @@ namespace ts.Completions { } // Dont filter member even if the name matches if it is declared private in the list - if (hasEffectiveModifier(m, ModifierFlags.Private)) { + if (ts.hasEffectiveModifier(m, ts.ModifierFlags.Private)) { continue; } // do not filter it out if the static presence doesnt match - if (isStatic(m) !== !!(currentClassElementModifierFlags & ModifierFlags.Static)) { + if (ts.isStatic(m) !== !!(currentClassElementModifierFlags & ts.ModifierFlags.Static)) { continue; } - const existingName = getPropertyNameForPropertyNameNode(m.name!); + const existingName = ts.getPropertyNameForPropertyNameNode(m.name!); if (existingName) { existingMemberNames.add(existingName); } } - return baseSymbols.filter(propertySymbol => - !existingMemberNames.has(propertySymbol.escapedName) && + return baseSymbols.filter(propertySymbol => !existingMemberNames.has(propertySymbol.escapedName) && !!propertySymbol.declarations && - !(getDeclarationModifierFlagsFromSymbol(propertySymbol) & ModifierFlags.Private) && - !(propertySymbol.valueDeclaration && isPrivateIdentifierClassElementDeclaration(propertySymbol.valueDeclaration))); + !(ts.getDeclarationModifierFlagsFromSymbol(propertySymbol) & ts.ModifierFlags.Private) && + !(propertySymbol.valueDeclaration && ts.isPrivateIdentifierClassElementDeclaration(propertySymbol.valueDeclaration))); } /** @@ -3748,19 +3364,19 @@ namespace ts.Completions { * @returns Symbols to be suggested in a JSX element, barring those whose attributes * do not occur at the current position and have not otherwise been typed. */ - function filterJsxAttributes(symbols: Symbol[], attributes: NodeArray): Symbol[] { - const seenNames = new Set<__String>(); - const membersDeclaredBySpreadAssignment = new Set(); + function filterJsxAttributes(symbols: ts.Symbol[], attributes: ts.NodeArray): ts.Symbol[] { + const seenNames = new ts.Set(); + const membersDeclaredBySpreadAssignment = new ts.Set(); for (const attr of attributes) { // If this is the current item we are editing right now, do not filter it out if (isCurrentlyEditingNode(attr)) { continue; } - if (attr.kind === SyntaxKind.JsxAttribute) { + if (attr.kind === ts.SyntaxKind.JsxAttribute) { seenNames.add(attr.name.escapedText); } - else if (isJsxSpreadAttribute(attr)) { + else if (ts.isJsxSpreadAttribute(attr)) { setMembersDeclaredBySpreadAssignment(attr, membersDeclaredBySpreadAssignment); } } @@ -3771,7 +3387,7 @@ namespace ts.Completions { return filteredSymbols; } - function isCurrentlyEditingNode(node: Node): boolean { + function isCurrentlyEditingNode(node: ts.Node): boolean { return node.getStart(sourceFile) <= position && position <= node.getEnd(); } } @@ -3780,20 +3396,20 @@ namespace ts.Completions { * Returns the immediate owning object literal or binding pattern of a context token, * on the condition that one exists and that the context implies completion should be given. */ - function tryGetObjectLikeCompletionContainer(contextToken: Node | undefined): ObjectLiteralExpression | ObjectBindingPattern | undefined { + function tryGetObjectLikeCompletionContainer(contextToken: ts.Node | undefined): ts.ObjectLiteralExpression | ts.ObjectBindingPattern | undefined { if (contextToken) { const { parent } = contextToken; switch (contextToken.kind) { - case SyntaxKind.OpenBraceToken: // const x = { | - case SyntaxKind.CommaToken: // const x = { a: 0, | - if (isObjectLiteralExpression(parent) || isObjectBindingPattern(parent)) { + case ts.SyntaxKind.OpenBraceToken: // const x = { | + case ts.SyntaxKind.CommaToken: // const x = { a: 0, | + if (ts.isObjectLiteralExpression(parent) || ts.isObjectBindingPattern(parent)) { return parent; } break; - case SyntaxKind.AsteriskToken: - return isMethodDeclaration(parent) ? tryCast(parent.parent, isObjectLiteralExpression) : undefined; - case SyntaxKind.Identifier: - return (contextToken as Identifier).text === "async" && isShorthandPropertyAssignment(contextToken.parent) + case ts.SyntaxKind.AsteriskToken: + return ts.isMethodDeclaration(parent) ? ts.tryCast(parent.parent, ts.isObjectLiteralExpression) : undefined; + case ts.SyntaxKind.Identifier: + return (contextToken as ts.Identifier).text === "async" && ts.isShorthandPropertyAssignment(contextToken.parent) ? contextToken.parent.parent : undefined; } } @@ -3801,30 +3417,40 @@ namespace ts.Completions { return undefined; } - function getRelevantTokens(position: number, sourceFile: SourceFile): { contextToken: Node, previousToken: Node } | { contextToken: undefined, previousToken: undefined } { - const previousToken = findPrecedingToken(position, sourceFile); - if (previousToken && position <= previousToken.end && (isMemberName(previousToken) || isKeyword(previousToken.kind))) { - const contextToken = findPrecedingToken(previousToken.getFullStart(), sourceFile, /*startNode*/ undefined)!; // TODO: GH#18217 + function getRelevantTokens(position: number, sourceFile: ts.SourceFile): { + contextToken: ts.Node; + previousToken: ts.Node; + } | { + contextToken: undefined; + previousToken: undefined; + } { + const previousToken = ts.findPrecedingToken(position, sourceFile); + if (previousToken && position <= previousToken.end && (ts.isMemberName(previousToken) || ts.isKeyword(previousToken.kind))) { + const contextToken = ts.findPrecedingToken(previousToken.getFullStart(), sourceFile, /*startNode*/ undefined)!; // TODO: GH#18217 return { contextToken, previousToken }; } - return { contextToken: previousToken as Node, previousToken: previousToken as Node }; + return { contextToken: previousToken as ts.Node, previousToken: previousToken as ts.Node }; } - function getAutoImportSymbolFromCompletionEntryData(name: string, data: CompletionEntryData, program: Program, host: LanguageServiceHost): { symbol: Symbol, origin: SymbolOriginInfoExport | SymbolOriginInfoResolvedExport } | undefined { + function getAutoImportSymbolFromCompletionEntryData(name: string, data: ts.CompletionEntryData, program: ts.Program, host: ts.LanguageServiceHost): { + symbol: ts.Symbol; + origin: SymbolOriginInfoExport | SymbolOriginInfoResolvedExport; + } | undefined { const containingProgram = data.isPackageJsonImport ? host.getPackageJsonAutoImportProvider!()! : program; const checker = containingProgram.getTypeChecker(); - const moduleSymbol = - data.ambientModuleName ? checker.tryFindAmbientModule(data.ambientModuleName) : - data.fileName ? checker.getMergedSymbol(Debug.checkDefined(containingProgram.getSourceFile(data.fileName)).symbol) : + const moduleSymbol = data.ambientModuleName ? checker.tryFindAmbientModule(data.ambientModuleName) : + data.fileName ? checker.getMergedSymbol(ts.Debug.checkDefined(containingProgram.getSourceFile(data.fileName)).symbol) : undefined; - if (!moduleSymbol) return undefined; - let symbol = data.exportName === InternalSymbolName.ExportEquals + if (!moduleSymbol) + return undefined; + let symbol = data.exportName === ts.InternalSymbolName.ExportEquals ? checker.resolveExternalModuleSymbol(moduleSymbol) : checker.tryGetMemberInModuleExportsAndProperties(data.exportName, moduleSymbol); - if (!symbol) return undefined; - const isDefaultExport = data.exportName === InternalSymbolName.Default; - symbol = isDefaultExport && getLocalSymbolForExportDefault(symbol) || symbol; + if (!symbol) + return undefined; + const isDefaultExport = data.exportName === ts.InternalSymbolName.Default; + symbol = isDefaultExport && ts.getLocalSymbolForExportDefault(symbol) || symbol; return { symbol, origin: completionEntryDataToSymbolOriginInfo(data, name, moduleSymbol) }; } @@ -3832,25 +3458,19 @@ namespace ts.Completions { readonly name: string; readonly needsConvertPropertyAccess: boolean; } - function getCompletionEntryDisplayNameForSymbol( - symbol: Symbol, - target: ScriptTarget, - origin: SymbolOriginInfo | undefined, - kind: CompletionKind, - jsxIdentifierExpected: boolean, - ): CompletionEntryDisplayNameForSymbol | undefined { + function getCompletionEntryDisplayNameForSymbol(symbol: ts.Symbol, target: ts.ScriptTarget, origin: SymbolOriginInfo | undefined, kind: CompletionKind, jsxIdentifierExpected: boolean): CompletionEntryDisplayNameForSymbol | undefined { const name = originIncludesSymbolName(origin) ? origin.symbolName : symbol.name; if (name === undefined // If the symbol is external module, don't show it in the completion list // (i.e declare module "http" { const x; } | // <= request completion here, "http" should not be there) - || symbol.flags & SymbolFlags.Module && isSingleOrDoubleQuote(name.charCodeAt(0)) + || symbol.flags & ts.SymbolFlags.Module && ts.isSingleOrDoubleQuote(name.charCodeAt(0)) // If the symbol is the internal name of an ES symbol, it is not a valid entry. Internal names for ES symbols start with "__@" - || isKnownSymbol(symbol)) { + || ts.isKnownSymbol(symbol)) { return undefined; } const validNameResult: CompletionEntryDisplayNameForSymbol = { name, needsConvertPropertyAccess: false }; - if (isIdentifierText(name, target, jsxIdentifierExpected ? LanguageVariant.JSX : LanguageVariant.Standard) || symbol.valueDeclaration && isPrivateIdentifierClassElementDeclaration(symbol.valueDeclaration)) { + if (ts.isIdentifierText(name, target, jsxIdentifierExpected ? ts.LanguageVariant.JSX : ts.LanguageVariant.Standard) || symbol.valueDeclaration && ts.isPrivateIdentifierClassElementDeclaration(symbol.valueDeclaration)) { return validNameResult; } switch (kind) { @@ -3862,54 +3482,54 @@ namespace ts.Completions { case CompletionKind.PropertyAccess: case CompletionKind.Global: // For a 'this.' completion it will be in a global context, but may have a non-identifier name. // Don't add a completion for a name starting with a space. See https://github.com/Microsoft/TypeScript/pull/20547 - return name.charCodeAt(0) === CharacterCodes.space ? undefined : { name, needsConvertPropertyAccess: true }; + return name.charCodeAt(0) === ts.CharacterCodes.space ? undefined : { name, needsConvertPropertyAccess: true }; case CompletionKind.None: case CompletionKind.String: return validNameResult; default: - Debug.assertNever(kind); + ts.Debug.assertNever(kind); } } // A cache of completion entries for keywords, these do not change between sessions - const _keywordCompletions: CompletionEntry[][] = []; - const allKeywordsCompletions: () => readonly CompletionEntry[] = memoize(() => { - const res: CompletionEntry[] = []; - for (let i = SyntaxKind.FirstKeyword; i <= SyntaxKind.LastKeyword; i++) { + const _keywordCompletions: ts.CompletionEntry[][] = []; + const allKeywordsCompletions: () => readonly ts.CompletionEntry[] = ts.memoize(() => { + const res: ts.CompletionEntry[] = []; + for (let i = ts.SyntaxKind.FirstKeyword; i <= ts.SyntaxKind.LastKeyword; i++) { res.push({ - name: tokenToString(i)!, - kind: ScriptElementKind.keyword, - kindModifiers: ScriptElementKindModifier.none, + name: ts.tokenToString(i)!, + kind: ts.ScriptElementKind.keyword, + kindModifiers: ts.ScriptElementKindModifier.none, sortText: SortText.GlobalsOrKeywords }); } return res; }); - function getKeywordCompletions(keywordFilter: KeywordCompletionFilters, filterOutTsOnlyKeywords: boolean): readonly CompletionEntry[] { - if (!filterOutTsOnlyKeywords) return getTypescriptKeywordCompletions(keywordFilter); + function getKeywordCompletions(keywordFilter: KeywordCompletionFilters, filterOutTsOnlyKeywords: boolean): readonly ts.CompletionEntry[] { + if (!filterOutTsOnlyKeywords) + return getTypescriptKeywordCompletions(keywordFilter); const index = keywordFilter + KeywordCompletionFilters.Last + 1; return _keywordCompletions[index] || (_keywordCompletions[index] = getTypescriptKeywordCompletions(keywordFilter) - .filter(entry => !isTypeScriptOnlyKeyword(stringToToken(entry.name)!)) - ); + .filter(entry => !isTypeScriptOnlyKeyword(ts.stringToToken(entry.name)!))); } - function getTypescriptKeywordCompletions(keywordFilter: KeywordCompletionFilters): readonly CompletionEntry[] { + function getTypescriptKeywordCompletions(keywordFilter: KeywordCompletionFilters): readonly ts.CompletionEntry[] { return _keywordCompletions[keywordFilter] || (_keywordCompletions[keywordFilter] = allKeywordsCompletions().filter(entry => { - const kind = stringToToken(entry.name)!; + const kind = ts.stringToToken(entry.name)!; switch (keywordFilter) { case KeywordCompletionFilters.None: return false; case KeywordCompletionFilters.All: return isFunctionLikeBodyKeyword(kind) - || kind === SyntaxKind.DeclareKeyword - || kind === SyntaxKind.ModuleKeyword - || kind === SyntaxKind.TypeKeyword - || kind === SyntaxKind.NamespaceKeyword - || kind === SyntaxKind.AbstractKeyword - || isTypeKeyword(kind) && kind !== SyntaxKind.UndefinedKeyword; + || kind === ts.SyntaxKind.DeclareKeyword + || kind === ts.SyntaxKind.ModuleKeyword + || kind === ts.SyntaxKind.TypeKeyword + || kind === ts.SyntaxKind.NamespaceKeyword + || kind === ts.SyntaxKind.AbstractKeyword + || ts.isTypeKeyword(kind) && kind !== ts.SyntaxKind.UndefinedKeyword; case KeywordCompletionFilters.FunctionLikeBodyKeywords: return isFunctionLikeBodyKeyword(kind); case KeywordCompletionFilters.ClassElementKeywords: @@ -3917,88 +3537,85 @@ namespace ts.Completions { case KeywordCompletionFilters.InterfaceElementKeywords: return isInterfaceOrTypeLiteralCompletionKeyword(kind); case KeywordCompletionFilters.ConstructorParameterKeywords: - return isParameterPropertyModifier(kind); + return ts.isParameterPropertyModifier(kind); case KeywordCompletionFilters.TypeAssertionKeywords: - return isTypeKeyword(kind) || kind === SyntaxKind.ConstKeyword; + return ts.isTypeKeyword(kind) || kind === ts.SyntaxKind.ConstKeyword; case KeywordCompletionFilters.TypeKeywords: - return isTypeKeyword(kind); + return ts.isTypeKeyword(kind); case KeywordCompletionFilters.TypeKeyword: - return kind === SyntaxKind.TypeKeyword; + return kind === ts.SyntaxKind.TypeKeyword; default: - return Debug.assertNever(keywordFilter); + return ts.Debug.assertNever(keywordFilter); } })); } - function isTypeScriptOnlyKeyword(kind: SyntaxKind) { + function isTypeScriptOnlyKeyword(kind: ts.SyntaxKind) { switch (kind) { - case SyntaxKind.AbstractKeyword: - case SyntaxKind.AnyKeyword: - case SyntaxKind.BigIntKeyword: - case SyntaxKind.BooleanKeyword: - case SyntaxKind.DeclareKeyword: - case SyntaxKind.EnumKeyword: - case SyntaxKind.GlobalKeyword: - case SyntaxKind.ImplementsKeyword: - case SyntaxKind.InferKeyword: - case SyntaxKind.InterfaceKeyword: - case SyntaxKind.IsKeyword: - case SyntaxKind.KeyOfKeyword: - case SyntaxKind.ModuleKeyword: - case SyntaxKind.NamespaceKeyword: - case SyntaxKind.NeverKeyword: - case SyntaxKind.NumberKeyword: - case SyntaxKind.ObjectKeyword: - case SyntaxKind.OverrideKeyword: - case SyntaxKind.PrivateKeyword: - case SyntaxKind.ProtectedKeyword: - case SyntaxKind.PublicKeyword: - case SyntaxKind.ReadonlyKeyword: - case SyntaxKind.StringKeyword: - case SyntaxKind.SymbolKeyword: - case SyntaxKind.TypeKeyword: - case SyntaxKind.UniqueKeyword: - case SyntaxKind.UnknownKeyword: + case ts.SyntaxKind.AbstractKeyword: + case ts.SyntaxKind.AnyKeyword: + case ts.SyntaxKind.BigIntKeyword: + case ts.SyntaxKind.BooleanKeyword: + case ts.SyntaxKind.DeclareKeyword: + case ts.SyntaxKind.EnumKeyword: + case ts.SyntaxKind.GlobalKeyword: + case ts.SyntaxKind.ImplementsKeyword: + case ts.SyntaxKind.InferKeyword: + case ts.SyntaxKind.InterfaceKeyword: + case ts.SyntaxKind.IsKeyword: + case ts.SyntaxKind.KeyOfKeyword: + case ts.SyntaxKind.ModuleKeyword: + case ts.SyntaxKind.NamespaceKeyword: + case ts.SyntaxKind.NeverKeyword: + case ts.SyntaxKind.NumberKeyword: + case ts.SyntaxKind.ObjectKeyword: + case ts.SyntaxKind.OverrideKeyword: + case ts.SyntaxKind.PrivateKeyword: + case ts.SyntaxKind.ProtectedKeyword: + case ts.SyntaxKind.PublicKeyword: + case ts.SyntaxKind.ReadonlyKeyword: + case ts.SyntaxKind.StringKeyword: + case ts.SyntaxKind.SymbolKeyword: + case ts.SyntaxKind.TypeKeyword: + case ts.SyntaxKind.UniqueKeyword: + case ts.SyntaxKind.UnknownKeyword: return true; default: return false; } } - function isInterfaceOrTypeLiteralCompletionKeyword(kind: SyntaxKind): boolean { - return kind === SyntaxKind.ReadonlyKeyword; + function isInterfaceOrTypeLiteralCompletionKeyword(kind: ts.SyntaxKind): boolean { + return kind === ts.SyntaxKind.ReadonlyKeyword; } - function isClassMemberCompletionKeyword(kind: SyntaxKind) { + function isClassMemberCompletionKeyword(kind: ts.SyntaxKind) { switch (kind) { - case SyntaxKind.AbstractKeyword: - case SyntaxKind.ConstructorKeyword: - case SyntaxKind.GetKeyword: - case SyntaxKind.SetKeyword: - case SyntaxKind.AsyncKeyword: - case SyntaxKind.DeclareKeyword: - case SyntaxKind.OverrideKeyword: + case ts.SyntaxKind.AbstractKeyword: + case ts.SyntaxKind.ConstructorKeyword: + case ts.SyntaxKind.GetKeyword: + case ts.SyntaxKind.SetKeyword: + case ts.SyntaxKind.AsyncKeyword: + case ts.SyntaxKind.DeclareKeyword: + case ts.SyntaxKind.OverrideKeyword: return true; default: - return isClassMemberModifier(kind); + return ts.isClassMemberModifier(kind); } } - function isFunctionLikeBodyKeyword(kind: SyntaxKind) { - return kind === SyntaxKind.AsyncKeyword - || kind === SyntaxKind.AwaitKeyword - || kind === SyntaxKind.AsKeyword - || !isContextualKeyword(kind) && !isClassMemberCompletionKeyword(kind); + function isFunctionLikeBodyKeyword(kind: ts.SyntaxKind) { + return kind === ts.SyntaxKind.AsyncKeyword + || kind === ts.SyntaxKind.AwaitKeyword + || kind === ts.SyntaxKind.AsKeyword + || !ts.isContextualKeyword(kind) && !isClassMemberCompletionKeyword(kind); } - function keywordForNode(node: Node): SyntaxKind { - return isIdentifier(node) ? node.originalKeywordKind || SyntaxKind.Unknown : node.kind; + function keywordForNode(node: ts.Node): ts.SyntaxKind { + return ts.isIdentifier(node) ? node.originalKeywordKind || ts.SyntaxKind.Unknown : node.kind; } - function getContextualKeywords( - contextToken: Node | undefined, - position: number, - ): readonly CompletionEntry[] { + function getContextualKeywords(contextToken: ts.Node | undefined, position: number): readonly ts.CompletionEntry[] { const entries = []; /** * An `AssertClause` can come after an import declaration: @@ -4013,13 +3630,13 @@ namespace ts.Completions { const parent = contextToken.parent; const tokenLine = file.getLineAndCharacterOfPosition(contextToken.end).line; const currentLine = file.getLineAndCharacterOfPosition(position).line; - if ((isImportDeclaration(parent) || isExportDeclaration(parent) && parent.moduleSpecifier) + if ((ts.isImportDeclaration(parent) || ts.isExportDeclaration(parent) && parent.moduleSpecifier) && contextToken === parent.moduleSpecifier && tokenLine === currentLine) { entries.push({ - name: tokenToString(SyntaxKind.AssertKeyword)!, - kind: ScriptElementKind.keyword, - kindModifiers: ScriptElementKindModifier.none, + name: ts.tokenToString(ts.SyntaxKind.AssertKeyword)!, + kind: ts.ScriptElementKind.keyword, + kindModifiers: ts.ScriptElementKindModifier.none, sortText: SortText.GlobalsOrKeywords, }); } @@ -4028,135 +3645,137 @@ namespace ts.Completions { } /** Get the corresponding JSDocTag node if the position is in a jsDoc comment */ - function getJsDocTagAtPosition(node: Node, position: number): JSDocTag | undefined { - return findAncestor(node, n => - isJSDocTag(n) && rangeContainsPosition(n, position) ? true : - isJSDoc(n) ? "quit" : false) as JSDocTag | undefined; + function getJsDocTagAtPosition(node: ts.Node, position: number): ts.JSDocTag | undefined { + return ts.findAncestor(node, n => ts.isJSDocTag(n) && ts.rangeContainsPosition(n, position) ? true : + ts.isJSDoc(n) ? "quit" : false) as ts.JSDocTag | undefined; } - export function getPropertiesForObjectExpression(contextualType: Type, completionsType: Type | undefined, obj: ObjectLiteralExpression | JsxAttributes, checker: TypeChecker): Symbol[] { + export function getPropertiesForObjectExpression(contextualType: ts.Type, completionsType: ts.Type | undefined, obj: ts.ObjectLiteralExpression | ts.JsxAttributes, checker: ts.TypeChecker): ts.Symbol[] { const hasCompletionsType = completionsType && completionsType !== contextualType; - const type = hasCompletionsType && !(completionsType.flags & TypeFlags.AnyOrUnknown) + const type = hasCompletionsType && !(completionsType.flags & ts.TypeFlags.AnyOrUnknown) ? checker.getUnionType([contextualType, completionsType]) : contextualType; const properties = getApparentProperties(type, obj, checker); return type.isClass() && containsNonPublicProperties(properties) ? [] : - hasCompletionsType ? filter(properties, hasDeclarationOtherThanSelf) : properties; + hasCompletionsType ? ts.filter(properties, hasDeclarationOtherThanSelf) : properties; // Filter out members whose only declaration is the object literal itself to avoid // self-fulfilling completions like: // // function f(x: T) {} // f({ abc/**/: "" }) // `abc` is a member of `T` but only because it declares itself - function hasDeclarationOtherThanSelf(member: Symbol) { - if (!length(member.declarations)) return true; - return some(member.declarations, decl => decl.parent !== obj); + function hasDeclarationOtherThanSelf(member: ts.Symbol) { + if (!ts.length(member.declarations)) + return true; + return ts.some(member.declarations, decl => decl.parent !== obj); } } - function getApparentProperties(type: Type, node: ObjectLiteralExpression | JsxAttributes, checker: TypeChecker) { - if (!type.isUnion()) return type.getApparentProperties(); - return checker.getAllPossiblePropertiesOfTypes(filter(type.types, memberType => - !(memberType.flags & TypeFlags.Primitive + function getApparentProperties(type: ts.Type, node: ts.ObjectLiteralExpression | ts.JsxAttributes, checker: ts.TypeChecker) { + if (!type.isUnion()) + return type.getApparentProperties(); + return checker.getAllPossiblePropertiesOfTypes(ts.filter(type.types, memberType => !(memberType.flags & ts.TypeFlags.Primitive || checker.isArrayLikeType(memberType) || checker.isTypeInvalidDueToUnionDiscriminant(memberType, node) - || typeHasCallOrConstructSignatures(memberType, checker) + || ts.typeHasCallOrConstructSignatures(memberType, checker) || memberType.isClass() && containsNonPublicProperties(memberType.getApparentProperties())))); } - function containsNonPublicProperties(props: Symbol[]) { - return some(props, p => !!(getDeclarationModifierFlagsFromSymbol(p) & ModifierFlags.NonPublicAccessibilityModifier)); + function containsNonPublicProperties(props: ts.Symbol[]) { + return ts.some(props, p => !!(ts.getDeclarationModifierFlagsFromSymbol(p) & ts.ModifierFlags.NonPublicAccessibilityModifier)); } /** * Gets all properties on a type, but if that type is a union of several types, * excludes array-like types or callable/constructable types. */ - function getPropertiesForCompletion(type: Type, checker: TypeChecker): Symbol[] { + function getPropertiesForCompletion(type: ts.Type, checker: ts.TypeChecker): ts.Symbol[] { return type.isUnion() - ? Debug.checkEachDefined(checker.getAllPossiblePropertiesOfTypes(type.types), "getAllPossiblePropertiesOfTypes() should all be defined") - : Debug.checkEachDefined(type.getApparentProperties(), "getApparentProperties() should all be defined"); + ? ts.Debug.checkEachDefined(checker.getAllPossiblePropertiesOfTypes(type.types), "getAllPossiblePropertiesOfTypes() should all be defined") + : ts.Debug.checkEachDefined(type.getApparentProperties(), "getApparentProperties() should all be defined"); } /** * Returns the immediate owning class declaration of a context token, * on the condition that one exists and that the context implies completion should be given. */ - function tryGetObjectTypeDeclarationCompletionContainer(sourceFile: SourceFile, contextToken: Node | undefined, location: Node, position: number): ObjectTypeDeclaration | undefined { + function tryGetObjectTypeDeclarationCompletionContainer(sourceFile: ts.SourceFile, contextToken: ts.Node | undefined, location: ts.Node, position: number): ts.ObjectTypeDeclaration | undefined { // class c { method() { } | method2() { } } switch (location.kind) { - case SyntaxKind.SyntaxList: - return tryCast(location.parent, isObjectTypeDeclaration); - case SyntaxKind.EndOfFileToken: - const cls = tryCast(lastOrUndefined(cast(location.parent, isSourceFile).statements), isObjectTypeDeclaration); - if (cls && !findChildOfKind(cls, SyntaxKind.CloseBraceToken, sourceFile)) { + case ts.SyntaxKind.SyntaxList: + return ts.tryCast(location.parent, ts.isObjectTypeDeclaration); + case ts.SyntaxKind.EndOfFileToken: + const cls = ts.tryCast(ts.lastOrUndefined(ts.cast(location.parent, ts.isSourceFile).statements), ts.isObjectTypeDeclaration); + if (cls && !ts.findChildOfKind(cls, ts.SyntaxKind.CloseBraceToken, sourceFile)) { return cls; } break; - case SyntaxKind.Identifier: { + case ts.SyntaxKind.Identifier: { // class c { public prop = c| } - if (isPropertyDeclaration(location.parent) && location.parent.initializer === location) { + if (ts.isPropertyDeclaration(location.parent) && location.parent.initializer === location) { return undefined; } // class c extends React.Component { a: () => 1\n compon| } if (isFromObjectTypeDeclaration(location)) { - return findAncestor(location, isObjectTypeDeclaration); + return ts.findAncestor(location, ts.isObjectTypeDeclaration); } } } - if (!contextToken) return undefined; + if (!contextToken) + return undefined; // class C { blah; constructor/**/ } and so on - if (location.kind === SyntaxKind.ConstructorKeyword + if (location.kind === ts.SyntaxKind.ConstructorKeyword // class C { blah \n constructor/**/ } - || (isIdentifier(contextToken) && isPropertyDeclaration(contextToken.parent) && isClassLike(location))) { - return findAncestor(contextToken, isClassLike) as ObjectTypeDeclaration; + || (ts.isIdentifier(contextToken) && ts.isPropertyDeclaration(contextToken.parent) && ts.isClassLike(location))) { + return ts.findAncestor(contextToken, ts.isClassLike) as ts.ObjectTypeDeclaration; } switch (contextToken.kind) { - case SyntaxKind.EqualsToken: // class c { public prop = | /* global completions */ } + case ts.SyntaxKind.EqualsToken: // class c { public prop = | /* global completions */ } return undefined; - case SyntaxKind.SemicolonToken: // class c {getValue(): number; | } - case SyntaxKind.CloseBraceToken: // class c { method() { } | } + case ts.SyntaxKind.SemicolonToken: // class c {getValue(): number; | } + case ts.SyntaxKind.CloseBraceToken: // class c { method() { } | } // class c { method() { } b| } - return isFromObjectTypeDeclaration(location) && (location.parent as ClassElement | TypeElement).name === location - ? location.parent.parent as ObjectTypeDeclaration - : tryCast(location, isObjectTypeDeclaration); - case SyntaxKind.OpenBraceToken: // class c { | - case SyntaxKind.CommaToken: // class c {getValue(): number, | } - return tryCast(contextToken.parent, isObjectTypeDeclaration); + return isFromObjectTypeDeclaration(location) && (location.parent as ts.ClassElement | ts.TypeElement).name === location + ? location.parent.parent as ts.ObjectTypeDeclaration + : ts.tryCast(location, ts.isObjectTypeDeclaration); + case ts.SyntaxKind.OpenBraceToken: // class c { | + case ts.SyntaxKind.CommaToken: // class c {getValue(): number, | } + return ts.tryCast(contextToken.parent, ts.isObjectTypeDeclaration); default: if (!isFromObjectTypeDeclaration(contextToken)) { // class c extends React.Component { a: () => 1\n| } - if (getLineAndCharacterOfPosition(sourceFile, contextToken.getEnd()).line !== getLineAndCharacterOfPosition(sourceFile, position).line && isObjectTypeDeclaration(location)) { + if (ts.getLineAndCharacterOfPosition(sourceFile, contextToken.getEnd()).line !== ts.getLineAndCharacterOfPosition(sourceFile, position).line && ts.isObjectTypeDeclaration(location)) { return location; } return undefined; } - const isValidKeyword = isClassLike(contextToken.parent.parent) ? isClassMemberCompletionKeyword : isInterfaceOrTypeLiteralCompletionKeyword; - return (isValidKeyword(contextToken.kind) || contextToken.kind === SyntaxKind.AsteriskToken || isIdentifier(contextToken) && isValidKeyword(stringToToken(contextToken.text)!)) // TODO: GH#18217 - ? contextToken.parent.parent as ObjectTypeDeclaration : undefined; + const isValidKeyword = ts.isClassLike(contextToken.parent.parent) ? isClassMemberCompletionKeyword : isInterfaceOrTypeLiteralCompletionKeyword; + return (isValidKeyword(contextToken.kind) || contextToken.kind === ts.SyntaxKind.AsteriskToken || ts.isIdentifier(contextToken) && isValidKeyword(ts.stringToToken(contextToken.text)!)) // TODO: GH#18217 + ? contextToken.parent.parent as ts.ObjectTypeDeclaration : undefined; } } - function tryGetTypeLiteralNode(node: Node): TypeLiteralNode | undefined { - if (!node) return undefined; + function tryGetTypeLiteralNode(node: ts.Node): ts.TypeLiteralNode | undefined { + if (!node) + return undefined; const parent = node.parent; switch (node.kind) { - case SyntaxKind.OpenBraceToken: - if (isTypeLiteralNode(parent)) { + case ts.SyntaxKind.OpenBraceToken: + if (ts.isTypeLiteralNode(parent)) { return parent; } break; - case SyntaxKind.SemicolonToken: - case SyntaxKind.CommaToken: - case SyntaxKind.Identifier: - if (parent.kind === SyntaxKind.PropertySignature && isTypeLiteralNode(parent.parent)) { + case ts.SyntaxKind.SemicolonToken: + case ts.SyntaxKind.CommaToken: + case ts.SyntaxKind.Identifier: + if (parent.kind === ts.SyntaxKind.PropertySignature && ts.isTypeLiteralNode(parent.parent)) { return parent.parent; } break; @@ -4165,32 +3784,33 @@ namespace ts.Completions { return undefined; } - function getConstraintOfTypeArgumentProperty(node: Node, checker: TypeChecker): Type | undefined { - if (!node) return undefined; - - if (isTypeNode(node) && isTypeReferenceType(node.parent)) { + function getConstraintOfTypeArgumentProperty(node: ts.Node, checker: ts.TypeChecker): ts.Type | undefined { + if (!node) + return undefined; + if (ts.isTypeNode(node) && ts.isTypeReferenceType(node.parent)) { return checker.getTypeArgumentConstraint(node); } const t = getConstraintOfTypeArgumentProperty(node.parent, checker); - if (!t) return undefined; + if (!t) + return undefined; switch (node.kind) { - case SyntaxKind.PropertySignature: + case ts.SyntaxKind.PropertySignature: return checker.getTypeOfPropertyOfContextualType(t, node.symbol.escapedName); - case SyntaxKind.IntersectionType: - case SyntaxKind.TypeLiteral: - case SyntaxKind.UnionType: + case ts.SyntaxKind.IntersectionType: + case ts.SyntaxKind.TypeLiteral: + case ts.SyntaxKind.UnionType: return t; } } // TODO: GH#19856 Would like to return `node is Node & { parent: (ClassElement | TypeElement) & { parent: ObjectTypeDeclaration } }` but then compilation takes > 10 minutes - function isFromObjectTypeDeclaration(node: Node): boolean { - return node.parent && isClassOrTypeElement(node.parent) && isObjectTypeDeclaration(node.parent.parent); + function isFromObjectTypeDeclaration(node: ts.Node): boolean { + return node.parent && ts.isClassOrTypeElement(node.parent) && ts.isObjectTypeDeclaration(node.parent.parent); } - function isValidTrigger(sourceFile: SourceFile, triggerCharacter: CompletionsTriggerCharacter, contextToken: Node | undefined, position: number): boolean { + function isValidTrigger(sourceFile: ts.SourceFile, triggerCharacter: ts.CompletionsTriggerCharacter, contextToken: ts.Node | undefined, position: number): boolean { switch (triggerCharacter) { case ".": case "@": @@ -4199,61 +3819,61 @@ namespace ts.Completions { case "'": case "`": // Only automatically bring up completions if this is an opening quote. - return !!contextToken && isStringLiteralOrTemplate(contextToken) && position === contextToken.getStart(sourceFile) + 1; + return !!contextToken && ts.isStringLiteralOrTemplate(contextToken) && position === contextToken.getStart(sourceFile) + 1; case "#": - return !!contextToken && isPrivateIdentifier(contextToken) && !!getContainingClass(contextToken); + return !!contextToken && ts.isPrivateIdentifier(contextToken) && !!ts.getContainingClass(contextToken); case "<": // Opening JSX tag - return !!contextToken && contextToken.kind === SyntaxKind.LessThanToken && (!isBinaryExpression(contextToken.parent) || binaryExpressionMayBeOpenTag(contextToken.parent)); + return !!contextToken && contextToken.kind === ts.SyntaxKind.LessThanToken && (!ts.isBinaryExpression(contextToken.parent) || binaryExpressionMayBeOpenTag(contextToken.parent)); case "/": - return !!contextToken && (isStringLiteralLike(contextToken) - ? !!tryGetImportFromModuleSpecifier(contextToken) - : contextToken.kind === SyntaxKind.SlashToken && isJsxClosingElement(contextToken.parent)); + return !!contextToken && (ts.isStringLiteralLike(contextToken) + ? !!ts.tryGetImportFromModuleSpecifier(contextToken) + : contextToken.kind === ts.SyntaxKind.SlashToken && ts.isJsxClosingElement(contextToken.parent)); case " ": - return !!contextToken && isImportKeyword(contextToken) && contextToken.parent.kind === SyntaxKind.SourceFile; + return !!contextToken && ts.isImportKeyword(contextToken) && contextToken.parent.kind === ts.SyntaxKind.SourceFile; default: - return Debug.assertNever(triggerCharacter); + return ts.Debug.assertNever(triggerCharacter); } } - function binaryExpressionMayBeOpenTag({ left }: BinaryExpression): boolean { - return nodeIsMissing(left); + function binaryExpressionMayBeOpenTag({ left }: ts.BinaryExpression): boolean { + return ts.nodeIsMissing(left); } /** Determines if a type is exactly the same type resolved by the global 'self', 'global', or 'globalThis'. */ - function isProbablyGlobalType(type: Type, sourceFile: SourceFile, checker: TypeChecker) { + function isProbablyGlobalType(type: ts.Type, sourceFile: ts.SourceFile, checker: ts.TypeChecker) { // The type of `self` and `window` is the same in lib.dom.d.ts, but `window` does not exist in // lib.webworker.d.ts, so checking against `self` is also a check against `window` when it exists. - const selfSymbol = checker.resolveName("self", /*location*/ undefined, SymbolFlags.Value, /*excludeGlobals*/ false); + const selfSymbol = checker.resolveName("self", /*location*/ undefined, ts.SymbolFlags.Value, /*excludeGlobals*/ false); if (selfSymbol && checker.getTypeOfSymbolAtLocation(selfSymbol, sourceFile) === type) { return true; } - const globalSymbol = checker.resolveName("global", /*location*/ undefined, SymbolFlags.Value, /*excludeGlobals*/ false); + const globalSymbol = checker.resolveName("global", /*location*/ undefined, ts.SymbolFlags.Value, /*excludeGlobals*/ false); if (globalSymbol && checker.getTypeOfSymbolAtLocation(globalSymbol, sourceFile) === type) { return true; } - const globalThisSymbol = checker.resolveName("globalThis", /*location*/ undefined, SymbolFlags.Value, /*excludeGlobals*/ false); + const globalThisSymbol = checker.resolveName("globalThis", /*location*/ undefined, ts.SymbolFlags.Value, /*excludeGlobals*/ false); if (globalThisSymbol && checker.getTypeOfSymbolAtLocation(globalThisSymbol, sourceFile) === type) { return true; } return false; } - function isStaticProperty(symbol: Symbol) { - return !!(symbol.valueDeclaration && getEffectiveModifierFlags(symbol.valueDeclaration) & ModifierFlags.Static && isClassLike(symbol.valueDeclaration.parent)); + function isStaticProperty(symbol: ts.Symbol) { + return !!(symbol.valueDeclaration && ts.getEffectiveModifierFlags(symbol.valueDeclaration) & ts.ModifierFlags.Static && ts.isClassLike(symbol.valueDeclaration.parent)); } - function tryGetObjectLiteralContextualType(node: ObjectLiteralExpression, typeChecker: TypeChecker) { + function tryGetObjectLiteralContextualType(node: ts.ObjectLiteralExpression, typeChecker: ts.TypeChecker) { const type = typeChecker.getContextualType(node); if (type) { return type; } - const parent = walkUpParenthesizedExpressions(node.parent); - if (isBinaryExpression(parent) && parent.operatorToken.kind === SyntaxKind.EqualsToken && node === parent.left) { + const parent = ts.walkUpParenthesizedExpressions(node.parent); + if (ts.isBinaryExpression(parent) && parent.operatorToken.kind === ts.SyntaxKind.EqualsToken && node === parent.left) { // Object literal is assignment pattern: ({ | } = x) return typeChecker.getTypeAtLocation(parent); } - if (isExpression(parent)) { + if (ts.isExpression(parent)) { // f(() => (({ | }))); return typeChecker.getContextualType(parent); } @@ -4262,47 +3882,45 @@ namespace ts.Completions { interface ImportStatementCompletionInfo { isKeywordOnlyCompletion: boolean; - keywordCompletion: TokenSyntaxKind | undefined; + keywordCompletion: ts.TokenSyntaxKind | undefined; isNewIdentifierLocation: boolean; - replacementNode: ImportEqualsDeclaration | ImportDeclaration | ImportSpecifier | Token | undefined; + replacementNode: ts.ImportEqualsDeclaration | ts.ImportDeclaration | ts.ImportSpecifier | ts.Token | undefined; } - function getImportStatementCompletionInfo(contextToken: Node): ImportStatementCompletionInfo { - let keywordCompletion: TokenSyntaxKind | undefined; + function getImportStatementCompletionInfo(contextToken: ts.Node): ImportStatementCompletionInfo { + let keywordCompletion: ts.TokenSyntaxKind | undefined; let isKeywordOnlyCompletion = false; const candidate = getCandidate(); return { isKeywordOnlyCompletion, keywordCompletion, - isNewIdentifierLocation: !!(candidate || keywordCompletion === SyntaxKind.TypeKeyword), - replacementNode: candidate && rangeIsOnSingleLine(candidate, candidate.getSourceFile()) + isNewIdentifierLocation: !!(candidate || keywordCompletion === ts.SyntaxKind.TypeKeyword), + replacementNode: candidate && ts.rangeIsOnSingleLine(candidate, candidate.getSourceFile()) ? candidate : undefined }; function getCandidate() { const parent = contextToken.parent; - if (isImportEqualsDeclaration(parent)) { - keywordCompletion = contextToken.kind === SyntaxKind.TypeKeyword ? undefined : SyntaxKind.TypeKeyword; + if (ts.isImportEqualsDeclaration(parent)) { + keywordCompletion = contextToken.kind === ts.SyntaxKind.TypeKeyword ? undefined : ts.SyntaxKind.TypeKeyword; return isModuleSpecifierMissingOrEmpty(parent.moduleReference) ? parent : undefined; } if (couldBeTypeOnlyImportSpecifier(parent, contextToken) && canCompleteFromNamedBindings(parent.parent)) { return parent; } - if (isNamedImports(parent) || isNamespaceImport(parent)) { - if (!parent.parent.isTypeOnly && ( - contextToken.kind === SyntaxKind.OpenBraceToken || - contextToken.kind === SyntaxKind.ImportKeyword || - contextToken.kind === SyntaxKind.CommaToken - )) { - keywordCompletion = SyntaxKind.TypeKeyword; + if (ts.isNamedImports(parent) || ts.isNamespaceImport(parent)) { + if (!parent.parent.isTypeOnly && (contextToken.kind === ts.SyntaxKind.OpenBraceToken || + contextToken.kind === ts.SyntaxKind.ImportKeyword || + contextToken.kind === ts.SyntaxKind.CommaToken)) { + keywordCompletion = ts.SyntaxKind.TypeKeyword; } if (canCompleteFromNamedBindings(parent)) { // At `import { ... } |` or `import * as Foo |`, the only possible completion is `from` - if (contextToken.kind === SyntaxKind.CloseBraceToken || contextToken.kind === SyntaxKind.Identifier) { + if (contextToken.kind === ts.SyntaxKind.CloseBraceToken || contextToken.kind === ts.SyntaxKind.Identifier) { isKeywordOnlyCompletion = true; - keywordCompletion = SyntaxKind.FromKeyword; + keywordCompletion = ts.SyntaxKind.FromKeyword; } else { return parent.parent.parent; @@ -4310,65 +3928,64 @@ namespace ts.Completions { } return undefined; } - if (isImportKeyword(contextToken) && isSourceFile(parent)) { + if (ts.isImportKeyword(contextToken) && ts.isSourceFile(parent)) { // A lone import keyword with nothing following it does not parse as a statement at all - keywordCompletion = SyntaxKind.TypeKeyword; - return contextToken as Token; + keywordCompletion = ts.SyntaxKind.TypeKeyword; + return contextToken as ts.Token; } - if (isImportKeyword(contextToken) && isImportDeclaration(parent)) { + if (ts.isImportKeyword(contextToken) && ts.isImportDeclaration(parent)) { // `import s| from` - keywordCompletion = SyntaxKind.TypeKeyword; + keywordCompletion = ts.SyntaxKind.TypeKeyword; return isModuleSpecifierMissingOrEmpty(parent.moduleSpecifier) ? parent : undefined; } return undefined; } } - function couldBeTypeOnlyImportSpecifier(importSpecifier: Node, contextToken: Node | undefined): importSpecifier is ImportSpecifier { - return isImportSpecifier(importSpecifier) - && (importSpecifier.isTypeOnly || contextToken === importSpecifier.name && isTypeKeywordTokenOrIdentifier(contextToken)); + function couldBeTypeOnlyImportSpecifier(importSpecifier: ts.Node, contextToken: ts.Node | undefined): importSpecifier is ts.ImportSpecifier { + return ts.isImportSpecifier(importSpecifier) + && (importSpecifier.isTypeOnly || contextToken === importSpecifier.name && ts.isTypeKeywordTokenOrIdentifier(contextToken)); } - function canCompleteFromNamedBindings(namedBindings: NamedImportBindings) { + function canCompleteFromNamedBindings(namedBindings: ts.NamedImportBindings) { return isModuleSpecifierMissingOrEmpty(namedBindings.parent.parent.moduleSpecifier) - && (isNamespaceImport(namedBindings) || namedBindings.elements.length < 2) + && (ts.isNamespaceImport(namedBindings) || namedBindings.elements.length < 2) && !namedBindings.parent.name; } - function isModuleSpecifierMissingOrEmpty(specifier: ModuleReference | Expression) { - if (nodeIsMissing(specifier)) return true; - return !tryCast(isExternalModuleReference(specifier) ? specifier.expression : specifier, isStringLiteralLike)?.text; + function isModuleSpecifierMissingOrEmpty(specifier: ts.ModuleReference | ts.Expression) { + if (ts.nodeIsMissing(specifier)) + return true; + return !ts.tryCast(ts.isExternalModuleReference(specifier) ? specifier.expression : specifier, ts.isStringLiteralLike)?.text; } - function getVariableDeclaration(property: Node): VariableDeclaration | undefined { - const variableDeclaration = findAncestor(property, node => - isFunctionBlock(node) || isArrowFunctionBody(node) || isBindingPattern(node) + function getVariableDeclaration(property: ts.Node): ts.VariableDeclaration | undefined { + const variableDeclaration = ts.findAncestor(property, node => ts.isFunctionBlock(node) || isArrowFunctionBody(node) || ts.isBindingPattern(node) ? "quit" - : isVariableDeclaration(node)); - - return variableDeclaration as VariableDeclaration | undefined; + : ts.isVariableDeclaration(node)); + return variableDeclaration as ts.VariableDeclaration | undefined; } - function isArrowFunctionBody(node: Node) { - return node.parent && isArrowFunction(node.parent) && node.parent.body === node; - }; + function isArrowFunctionBody(node: ts.Node) { + return node.parent && ts.isArrowFunction(node.parent) && node.parent.body === node; + } + ; /** True if symbol is a type or a module containing at least one type. */ - function symbolCanBeReferencedAtTypeLocation(symbol: Symbol, checker: TypeChecker, seenModules = new Map()): boolean { + function symbolCanBeReferencedAtTypeLocation(symbol: ts.Symbol, checker: ts.TypeChecker, seenModules = new ts.Map()): boolean { // Since an alias can be merged with a local declaration, we need to test both the alias and its target. // This code used to just test the result of `skipAlias`, but that would ignore any locally introduced meanings. - return nonAliasCanBeReferencedAtTypeLocation(symbol) || nonAliasCanBeReferencedAtTypeLocation(skipAlias(symbol.exportSymbol || symbol, checker)); - - function nonAliasCanBeReferencedAtTypeLocation(symbol: Symbol): boolean { - return !!(symbol.flags & SymbolFlags.Type) || checker.isUnknownSymbol(symbol) || - !!(symbol.flags & SymbolFlags.Module) && addToSeen(seenModules, getSymbolId(symbol)) && + return nonAliasCanBeReferencedAtTypeLocation(symbol) || nonAliasCanBeReferencedAtTypeLocation(ts.skipAlias(symbol.exportSymbol || symbol, checker)); + function nonAliasCanBeReferencedAtTypeLocation(symbol: ts.Symbol): boolean { + return !!(symbol.flags & ts.SymbolFlags.Type) || checker.isUnknownSymbol(symbol) || + !!(symbol.flags & ts.SymbolFlags.Module) && ts.addToSeen(seenModules, ts.getSymbolId(symbol)) && checker.getExportsOfModule(symbol).some(e => symbolCanBeReferencedAtTypeLocation(e, checker, seenModules)); } } - function isDeprecated(symbol: Symbol, checker: TypeChecker) { - const declarations = skipAlias(symbol, checker).declarations; - return !!length(declarations) && every(declarations, isDeprecatedDeclaration); + function isDeprecated(symbol: ts.Symbol, checker: ts.TypeChecker) { + const declarations = ts.skipAlias(symbol, checker).declarations; + return !!ts.length(declarations) && ts.every(declarations, ts.isDeprecatedDeclaration); } /** @@ -4402,8 +4019,8 @@ namespace ts.Completions { if (strChar === testChar || strChar === toUpperCharCode(testChar)) { matchedFirstCharacter ||= prevChar === undefined || // Beginning of word - CharacterCodes.a <= prevChar && prevChar <= CharacterCodes.z && CharacterCodes.A <= strChar && strChar <= CharacterCodes.Z || // camelCase transition - prevChar === CharacterCodes._ && strChar !== CharacterCodes._; // snake_case transition + ts.CharacterCodes.a <= prevChar && prevChar <= ts.CharacterCodes.z && ts.CharacterCodes.A <= strChar && strChar <= ts.CharacterCodes.Z || // camelCase transition + prevChar === ts.CharacterCodes._ && strChar !== ts.CharacterCodes._; // snake_case transition if (matchedFirstCharacter) { characterIndex++; } @@ -4419,7 +4036,7 @@ namespace ts.Completions { } function toUpperCharCode(charCode: number) { - if (CharacterCodes.a <= charCode && charCode <= CharacterCodes.z) { + if (ts.CharacterCodes.a <= charCode && charCode <= ts.CharacterCodes.z) { return charCode - 32; } return charCode; diff --git a/src/services/documentHighlights.ts b/src/services/documentHighlights.ts index 698f82eda51b4..0ab8c29af6ed4 100644 --- a/src/services/documentHighlights.ts +++ b/src/services/documentHighlights.ts @@ -1,15 +1,14 @@ namespace ts { export interface DocumentHighlights { fileName: string; - highlightSpans: HighlightSpan[]; + highlightSpans: ts.HighlightSpan[]; } /* @internal */ export namespace DocumentHighlights { - export function getDocumentHighlights(program: Program, cancellationToken: CancellationToken, sourceFile: SourceFile, position: number, sourceFilesToSearch: readonly SourceFile[]): DocumentHighlights[] | undefined { - const node = getTouchingPropertyName(sourceFile, position); - - if (node.parent && (isJsxOpeningElement(node.parent) && node.parent.tagName === node || isJsxClosingElement(node.parent))) { + export function getDocumentHighlights(program: ts.Program, cancellationToken: ts.CancellationToken, sourceFile: ts.SourceFile, position: number, sourceFilesToSearch: readonly ts.SourceFile[]): DocumentHighlights[] | undefined { + const node = ts.getTouchingPropertyName(sourceFile, position); + if (node.parent && (ts.isJsxOpeningElement(node.parent) && node.parent.tagName === node || ts.isJsxClosingElement(node.parent))) { // For a JSX element, just highlight the matching tag, not all references. const { openingElement, closingElement } = node.parent.parent; const highlightSpans = [openingElement, closingElement].map(({ tagName }) => getHighlightSpanForNode(tagName, sourceFile)); @@ -19,98 +18,98 @@ namespace ts { return getSemanticDocumentHighlights(position, node, program, cancellationToken, sourceFilesToSearch) || getSyntacticDocumentHighlights(node, sourceFile); } - function getHighlightSpanForNode(node: Node, sourceFile: SourceFile): HighlightSpan { + function getHighlightSpanForNode(node: ts.Node, sourceFile: ts.SourceFile): ts.HighlightSpan { return { fileName: sourceFile.fileName, - textSpan: createTextSpanFromNode(node, sourceFile), - kind: HighlightSpanKind.none + textSpan: ts.createTextSpanFromNode(node, sourceFile), + kind: ts.HighlightSpanKind.none }; } - function getSemanticDocumentHighlights(position: number, node: Node, program: Program, cancellationToken: CancellationToken, sourceFilesToSearch: readonly SourceFile[]): DocumentHighlights[] | undefined { - const sourceFilesSet = new Set(sourceFilesToSearch.map(f => f.fileName)); - const referenceEntries = FindAllReferences.getReferenceEntriesForNode(position, node, program, sourceFilesToSearch, cancellationToken, /*options*/ undefined, sourceFilesSet); - if (!referenceEntries) return undefined; - const map = arrayToMultiMap(referenceEntries.map(FindAllReferences.toHighlightSpan), e => e.fileName, e => e.span); - const getCanonicalFileName = createGetCanonicalFileName(program.useCaseSensitiveFileNames()); - return mapDefined(arrayFrom(map.entries()), ([fileName, highlightSpans]) => { + function getSemanticDocumentHighlights(position: number, node: ts.Node, program: ts.Program, cancellationToken: ts.CancellationToken, sourceFilesToSearch: readonly ts.SourceFile[]): DocumentHighlights[] | undefined { + const sourceFilesSet = new ts.Set(sourceFilesToSearch.map(f => f.fileName)); + const referenceEntries = ts.FindAllReferences.getReferenceEntriesForNode(position, node, program, sourceFilesToSearch, cancellationToken, /*options*/ undefined, sourceFilesSet); + if (!referenceEntries) + return undefined; + const map = ts.arrayToMultiMap(referenceEntries.map(ts.FindAllReferences.toHighlightSpan), e => e.fileName, e => e.span); + const getCanonicalFileName = ts.createGetCanonicalFileName(program.useCaseSensitiveFileNames()); + return ts.mapDefined(ts.arrayFrom(map.entries()), ([fileName, highlightSpans]) => { if (!sourceFilesSet.has(fileName)) { - if (!program.redirectTargetsMap.has(toPath(fileName, program.getCurrentDirectory(), getCanonicalFileName))) { + if (!program.redirectTargetsMap.has(ts.toPath(fileName, program.getCurrentDirectory(), getCanonicalFileName))) { return undefined; } const redirectTarget = program.getSourceFile(fileName); - const redirect = find(sourceFilesToSearch, f => !!f.redirectInfo && f.redirectInfo.redirectTarget === redirectTarget)!; + const redirect = ts.find(sourceFilesToSearch, f => !!f.redirectInfo && f.redirectInfo.redirectTarget === redirectTarget)!; fileName = redirect.fileName; - Debug.assert(sourceFilesSet.has(fileName)); + ts.Debug.assert(sourceFilesSet.has(fileName)); } return { fileName, highlightSpans }; }); } - function getSyntacticDocumentHighlights(node: Node, sourceFile: SourceFile): DocumentHighlights[] | undefined { + function getSyntacticDocumentHighlights(node: ts.Node, sourceFile: ts.SourceFile): DocumentHighlights[] | undefined { const highlightSpans = getHighlightSpans(node, sourceFile); return highlightSpans && [{ fileName: sourceFile.fileName, highlightSpans }]; } - function getHighlightSpans(node: Node, sourceFile: SourceFile): HighlightSpan[] | undefined { + function getHighlightSpans(node: ts.Node, sourceFile: ts.SourceFile): ts.HighlightSpan[] | undefined { switch (node.kind) { - case SyntaxKind.IfKeyword: - case SyntaxKind.ElseKeyword: - return isIfStatement(node.parent) ? getIfElseOccurrences(node.parent, sourceFile) : undefined; - case SyntaxKind.ReturnKeyword: - return useParent(node.parent, isReturnStatement, getReturnOccurrences); - case SyntaxKind.ThrowKeyword: - return useParent(node.parent, isThrowStatement, getThrowOccurrences); - case SyntaxKind.TryKeyword: - case SyntaxKind.CatchKeyword: - case SyntaxKind.FinallyKeyword: - const tryStatement = node.kind === SyntaxKind.CatchKeyword ? node.parent.parent : node.parent; - return useParent(tryStatement, isTryStatement, getTryCatchFinallyOccurrences); - case SyntaxKind.SwitchKeyword: - return useParent(node.parent, isSwitchStatement, getSwitchCaseDefaultOccurrences); - case SyntaxKind.CaseKeyword: - case SyntaxKind.DefaultKeyword: { - if (isDefaultClause(node.parent) || isCaseClause(node.parent)) { - return useParent(node.parent.parent.parent, isSwitchStatement, getSwitchCaseDefaultOccurrences); + case ts.SyntaxKind.IfKeyword: + case ts.SyntaxKind.ElseKeyword: + return ts.isIfStatement(node.parent) ? getIfElseOccurrences(node.parent, sourceFile) : undefined; + case ts.SyntaxKind.ReturnKeyword: + return useParent(node.parent, ts.isReturnStatement, getReturnOccurrences); + case ts.SyntaxKind.ThrowKeyword: + return useParent(node.parent, ts.isThrowStatement, getThrowOccurrences); + case ts.SyntaxKind.TryKeyword: + case ts.SyntaxKind.CatchKeyword: + case ts.SyntaxKind.FinallyKeyword: + const tryStatement = node.kind === ts.SyntaxKind.CatchKeyword ? node.parent.parent : node.parent; + return useParent(tryStatement, ts.isTryStatement, getTryCatchFinallyOccurrences); + case ts.SyntaxKind.SwitchKeyword: + return useParent(node.parent, ts.isSwitchStatement, getSwitchCaseDefaultOccurrences); + case ts.SyntaxKind.CaseKeyword: + case ts.SyntaxKind.DefaultKeyword: { + if (ts.isDefaultClause(node.parent) || ts.isCaseClause(node.parent)) { + return useParent(node.parent.parent.parent, ts.isSwitchStatement, getSwitchCaseDefaultOccurrences); } return undefined; } - case SyntaxKind.BreakKeyword: - case SyntaxKind.ContinueKeyword: - return useParent(node.parent, isBreakOrContinueStatement, getBreakOrContinueStatementOccurrences); - case SyntaxKind.ForKeyword: - case SyntaxKind.WhileKeyword: - case SyntaxKind.DoKeyword: - return useParent(node.parent, (n): n is IterationStatement => isIterationStatement(n, /*lookInLabeledStatements*/ true), getLoopBreakContinueOccurrences); - case SyntaxKind.ConstructorKeyword: - return getFromAllDeclarations(isConstructorDeclaration, [SyntaxKind.ConstructorKeyword]); - case SyntaxKind.GetKeyword: - case SyntaxKind.SetKeyword: - return getFromAllDeclarations(isAccessor, [SyntaxKind.GetKeyword, SyntaxKind.SetKeyword]); - case SyntaxKind.AwaitKeyword: - return useParent(node.parent, isAwaitExpression, getAsyncAndAwaitOccurrences); - case SyntaxKind.AsyncKeyword: + case ts.SyntaxKind.BreakKeyword: + case ts.SyntaxKind.ContinueKeyword: + return useParent(node.parent, ts.isBreakOrContinueStatement, getBreakOrContinueStatementOccurrences); + case ts.SyntaxKind.ForKeyword: + case ts.SyntaxKind.WhileKeyword: + case ts.SyntaxKind.DoKeyword: + return useParent(node.parent, (n): n is ts.IterationStatement => ts.isIterationStatement(n, /*lookInLabeledStatements*/ true), getLoopBreakContinueOccurrences); + case ts.SyntaxKind.ConstructorKeyword: + return getFromAllDeclarations(ts.isConstructorDeclaration, [ts.SyntaxKind.ConstructorKeyword]); + case ts.SyntaxKind.GetKeyword: + case ts.SyntaxKind.SetKeyword: + return getFromAllDeclarations(ts.isAccessor, [ts.SyntaxKind.GetKeyword, ts.SyntaxKind.SetKeyword]); + case ts.SyntaxKind.AwaitKeyword: + return useParent(node.parent, ts.isAwaitExpression, getAsyncAndAwaitOccurrences); + case ts.SyntaxKind.AsyncKeyword: return highlightSpans(getAsyncAndAwaitOccurrences(node)); - case SyntaxKind.YieldKeyword: + case ts.SyntaxKind.YieldKeyword: return highlightSpans(getYieldOccurrences(node)); - case SyntaxKind.InKeyword: + case ts.SyntaxKind.InKeyword: return undefined; default: - return isModifierKind(node.kind) && (isDeclaration(node.parent) || isVariableStatement(node.parent)) + return ts.isModifierKind(node.kind) && (ts.isDeclaration(node.parent) || ts.isVariableStatement(node.parent)) ? highlightSpans(getModifierOccurrences(node.kind, node.parent)) : undefined; } - function getFromAllDeclarations(nodeTest: (node: Node) => node is T, keywords: readonly SyntaxKind[]): HighlightSpan[] | undefined { - return useParent(node.parent, nodeTest, decl => mapDefined(decl.symbol.declarations, d => - nodeTest(d) ? find(d.getChildren(sourceFile), c => contains(keywords, c.kind)) : undefined)); + function getFromAllDeclarations(nodeTest: (node: ts.Node) => node is T, keywords: readonly ts.SyntaxKind[]): ts.HighlightSpan[] | undefined { + return useParent(node.parent, nodeTest, decl => ts.mapDefined(decl.symbol.declarations, d => nodeTest(d) ? ts.find(d.getChildren(sourceFile), c => ts.contains(keywords, c.kind)) : undefined)); } - function useParent(node: Node, nodeTest: (node: Node) => node is T, getNodes: (node: T, sourceFile: SourceFile) => readonly Node[] | undefined): HighlightSpan[] | undefined { + function useParent(node: ts.Node, nodeTest: (node: ts.Node) => node is T, getNodes: (node: T, sourceFile: ts.SourceFile) => readonly ts.Node[] | undefined): ts.HighlightSpan[] | undefined { return nodeTest(node) ? highlightSpans(getNodes(node, sourceFile)) : undefined; } - function highlightSpans(nodes: readonly Node[] | undefined): HighlightSpan[] | undefined { + function highlightSpans(nodes: readonly ts.Node[] | undefined): ts.HighlightSpan[] | undefined { return nodes && nodes.map(node => getHighlightSpanForNode(node, sourceFile)); } } @@ -119,18 +118,16 @@ namespace ts { * Aggregates all throw-statements within this node *without* crossing * into function boundaries and try-blocks with catch-clauses. */ - function aggregateOwnedThrowStatements(node: Node): readonly ThrowStatement[] | undefined { - if (isThrowStatement(node)) { + function aggregateOwnedThrowStatements(node: ts.Node): readonly ts.ThrowStatement[] | undefined { + if (ts.isThrowStatement(node)) { return [node]; } - else if (isTryStatement(node)) { + else if (ts.isTryStatement(node)) { // Exceptions thrown within a try block lacking a catch clause are "owned" in the current context. - return concatenate( - node.catchClause ? aggregateOwnedThrowStatements(node.catchClause) : node.tryBlock && aggregateOwnedThrowStatements(node.tryBlock), - node.finallyBlock && aggregateOwnedThrowStatements(node.finallyBlock)); + return ts.concatenate(node.catchClause ? aggregateOwnedThrowStatements(node.catchClause) : node.tryBlock && aggregateOwnedThrowStatements(node.tryBlock), node.finallyBlock && aggregateOwnedThrowStatements(node.finallyBlock)); } // Do not cross function boundaries. - return isFunctionLike(node) ? undefined : flatMapChildren(node, aggregateOwnedThrowStatements); + return ts.isFunctionLike(node) ? undefined : flatMapChildren(node, aggregateOwnedThrowStatements); } /** @@ -138,19 +135,19 @@ namespace ts { * nearest ancestor that is a try-block (whose try statement has a catch clause), * function-block, or source file. */ - function getThrowStatementOwner(throwStatement: ThrowStatement): Node | undefined { - let child: Node = throwStatement; + function getThrowStatementOwner(throwStatement: ts.ThrowStatement): ts.Node | undefined { + let child: ts.Node = throwStatement; while (child.parent) { const parent = child.parent; - if (isFunctionBlock(parent) || parent.kind === SyntaxKind.SourceFile) { + if (ts.isFunctionBlock(parent) || parent.kind === ts.SyntaxKind.SourceFile) { return parent; } // A throw-statement is only owned by a try-statement if the try-statement has // a catch clause, and if the throw-statement occurs within the try block. - if (isTryStatement(parent) && parent.tryBlock === child && parent.catchClause) { + if (ts.isTryStatement(parent) && parent.tryBlock === child && parent.catchClause) { return child; } @@ -160,103 +157,103 @@ namespace ts { return undefined; } - function aggregateAllBreakAndContinueStatements(node: Node): readonly BreakOrContinueStatement[] | undefined { - return isBreakOrContinueStatement(node) ? [node] : isFunctionLike(node) ? undefined : flatMapChildren(node, aggregateAllBreakAndContinueStatements); + function aggregateAllBreakAndContinueStatements(node: ts.Node): readonly ts.BreakOrContinueStatement[] | undefined { + return ts.isBreakOrContinueStatement(node) ? [node] : ts.isFunctionLike(node) ? undefined : flatMapChildren(node, aggregateAllBreakAndContinueStatements); } - function flatMapChildren(node: Node, cb: (child: Node) => readonly T[] | T | undefined): readonly T[] { + function flatMapChildren(node: ts.Node, cb: (child: ts.Node) => readonly T[] | T | undefined): readonly T[] { const result: T[] = []; node.forEachChild(child => { const value = cb(child); if (value !== undefined) { - result.push(...toArray(value)); + result.push(...ts.toArray(value)); } }); return result; } - function ownsBreakOrContinueStatement(owner: Node, statement: BreakOrContinueStatement): boolean { + function ownsBreakOrContinueStatement(owner: ts.Node, statement: ts.BreakOrContinueStatement): boolean { const actualOwner = getBreakOrContinueOwner(statement); return !!actualOwner && actualOwner === owner; } - function getBreakOrContinueOwner(statement: BreakOrContinueStatement): Node | undefined { - return findAncestor(statement, node => { + function getBreakOrContinueOwner(statement: ts.BreakOrContinueStatement): ts.Node | undefined { + return ts.findAncestor(statement, node => { switch (node.kind) { - case SyntaxKind.SwitchStatement: - if (statement.kind === SyntaxKind.ContinueStatement) { + case ts.SyntaxKind.SwitchStatement: + if (statement.kind === ts.SyntaxKind.ContinueStatement) { return false; } // falls through - case SyntaxKind.ForStatement: - case SyntaxKind.ForInStatement: - case SyntaxKind.ForOfStatement: - case SyntaxKind.WhileStatement: - case SyntaxKind.DoStatement: + case ts.SyntaxKind.ForStatement: + case ts.SyntaxKind.ForInStatement: + case ts.SyntaxKind.ForOfStatement: + case ts.SyntaxKind.WhileStatement: + case ts.SyntaxKind.DoStatement: return !statement.label || isLabeledBy(node, statement.label.escapedText); default: // Don't cross function boundaries. // TODO: GH#20090 - return isFunctionLike(node) && "quit"; + return ts.isFunctionLike(node) && "quit"; } }); } - function getModifierOccurrences(modifier: Modifier["kind"], declaration: Node): Node[] { - return mapDefined(getNodesToSearchForModifier(declaration, modifierToFlag(modifier)), node => findModifier(node, modifier)); + function getModifierOccurrences(modifier: ts.Modifier["kind"], declaration: ts.Node): ts.Node[] { + return ts.mapDefined(getNodesToSearchForModifier(declaration, ts.modifierToFlag(modifier)), node => ts.findModifier(node, modifier)); } - function getNodesToSearchForModifier(declaration: Node, modifierFlag: ModifierFlags): readonly Node[] | undefined { + function getNodesToSearchForModifier(declaration: ts.Node, modifierFlag: ts.ModifierFlags): readonly ts.Node[] | undefined { // Types of node whose children might have modifiers. - const container = declaration.parent as ModuleBlock | SourceFile | Block | CaseClause | DefaultClause | ConstructorDeclaration | MethodDeclaration | FunctionDeclaration | ObjectTypeDeclaration | ObjectLiteralExpression; + const container = declaration.parent as ts.ModuleBlock | ts.SourceFile | ts.Block | ts.CaseClause | ts.DefaultClause | ts.ConstructorDeclaration | ts.MethodDeclaration | ts.FunctionDeclaration | ts.ObjectTypeDeclaration | ts.ObjectLiteralExpression; switch (container.kind) { - case SyntaxKind.ModuleBlock: - case SyntaxKind.SourceFile: - case SyntaxKind.Block: - case SyntaxKind.CaseClause: - case SyntaxKind.DefaultClause: + case ts.SyntaxKind.ModuleBlock: + case ts.SyntaxKind.SourceFile: + case ts.SyntaxKind.Block: + case ts.SyntaxKind.CaseClause: + case ts.SyntaxKind.DefaultClause: // Container is either a class declaration or the declaration is a classDeclaration - if (modifierFlag & ModifierFlags.Abstract && isClassDeclaration(declaration)) { + if (modifierFlag & ts.ModifierFlags.Abstract && ts.isClassDeclaration(declaration)) { return [...declaration.members, declaration]; } else { return container.statements; } - case SyntaxKind.Constructor: - case SyntaxKind.MethodDeclaration: - case SyntaxKind.FunctionDeclaration: - return [...container.parameters, ...(isClassLike(container.parent) ? container.parent.members : [])]; - case SyntaxKind.ClassDeclaration: - case SyntaxKind.ClassExpression: - case SyntaxKind.InterfaceDeclaration: - case SyntaxKind.TypeLiteral: + case ts.SyntaxKind.Constructor: + case ts.SyntaxKind.MethodDeclaration: + case ts.SyntaxKind.FunctionDeclaration: + return [...container.parameters, ...(ts.isClassLike(container.parent) ? container.parent.members : [])]; + case ts.SyntaxKind.ClassDeclaration: + case ts.SyntaxKind.ClassExpression: + case ts.SyntaxKind.InterfaceDeclaration: + case ts.SyntaxKind.TypeLiteral: const nodes = container.members; // If we're an accessibility modifier, we're in an instance member and should search // the constructor's parameter list for instance members as well. - if (modifierFlag & (ModifierFlags.AccessibilityModifier | ModifierFlags.Readonly)) { - const constructor = find(container.members, isConstructorDeclaration); + if (modifierFlag & (ts.ModifierFlags.AccessibilityModifier | ts.ModifierFlags.Readonly)) { + const constructor = ts.find(container.members, ts.isConstructorDeclaration); if (constructor) { return [...nodes, ...constructor.parameters]; } } - else if (modifierFlag & ModifierFlags.Abstract) { + else if (modifierFlag & ts.ModifierFlags.Abstract) { return [...nodes, container]; } return nodes; // Syntactically invalid positions that the parser might produce anyway - case SyntaxKind.ObjectLiteralExpression: + case ts.SyntaxKind.ObjectLiteralExpression: return undefined; default: - Debug.assertNever(container, "Invalid container kind."); + ts.Debug.assertNever(container, "Invalid container kind."); } } - function pushKeywordIf(keywordList: Push, token: Node | undefined, ...expected: SyntaxKind[]): boolean { - if (token && contains(expected, token.kind)) { + function pushKeywordIf(keywordList: ts.Push, token: ts.Node | undefined, ...expected: ts.SyntaxKind[]): boolean { + if (token && ts.contains(expected, token.kind)) { keywordList.push(token); return true; } @@ -264,63 +261,59 @@ namespace ts { return false; } - function getLoopBreakContinueOccurrences(loopNode: IterationStatement): Node[] { - const keywords: Node[] = []; - - if (pushKeywordIf(keywords, loopNode.getFirstToken(), SyntaxKind.ForKeyword, SyntaxKind.WhileKeyword, SyntaxKind.DoKeyword)) { + function getLoopBreakContinueOccurrences(loopNode: ts.IterationStatement): ts.Node[] { + const keywords: ts.Node[] = []; + if (pushKeywordIf(keywords, loopNode.getFirstToken(), ts.SyntaxKind.ForKeyword, ts.SyntaxKind.WhileKeyword, ts.SyntaxKind.DoKeyword)) { // If we succeeded and got a do-while loop, then start looking for a 'while' keyword. - if (loopNode.kind === SyntaxKind.DoStatement) { + if (loopNode.kind === ts.SyntaxKind.DoStatement) { const loopTokens = loopNode.getChildren(); for (let i = loopTokens.length - 1; i >= 0; i--) { - if (pushKeywordIf(keywords, loopTokens[i], SyntaxKind.WhileKeyword)) { + if (pushKeywordIf(keywords, loopTokens[i], ts.SyntaxKind.WhileKeyword)) { break; } } } } - forEach(aggregateAllBreakAndContinueStatements(loopNode.statement), statement => { + ts.forEach(aggregateAllBreakAndContinueStatements(loopNode.statement), statement => { if (ownsBreakOrContinueStatement(loopNode, statement)) { - pushKeywordIf(keywords, statement.getFirstToken(), SyntaxKind.BreakKeyword, SyntaxKind.ContinueKeyword); + pushKeywordIf(keywords, statement.getFirstToken(), ts.SyntaxKind.BreakKeyword, ts.SyntaxKind.ContinueKeyword); } }); return keywords; } - function getBreakOrContinueStatementOccurrences(breakOrContinueStatement: BreakOrContinueStatement): Node[] | undefined { + function getBreakOrContinueStatementOccurrences(breakOrContinueStatement: ts.BreakOrContinueStatement): ts.Node[] | undefined { const owner = getBreakOrContinueOwner(breakOrContinueStatement); if (owner) { switch (owner.kind) { - case SyntaxKind.ForStatement: - case SyntaxKind.ForInStatement: - case SyntaxKind.ForOfStatement: - case SyntaxKind.DoStatement: - case SyntaxKind.WhileStatement: - return getLoopBreakContinueOccurrences(owner as IterationStatement); - case SyntaxKind.SwitchStatement: - return getSwitchCaseDefaultOccurrences(owner as SwitchStatement); - + case ts.SyntaxKind.ForStatement: + case ts.SyntaxKind.ForInStatement: + case ts.SyntaxKind.ForOfStatement: + case ts.SyntaxKind.DoStatement: + case ts.SyntaxKind.WhileStatement: + return getLoopBreakContinueOccurrences(owner as ts.IterationStatement); + case ts.SyntaxKind.SwitchStatement: + return getSwitchCaseDefaultOccurrences(owner as ts.SwitchStatement); } } return undefined; } - function getSwitchCaseDefaultOccurrences(switchStatement: SwitchStatement): Node[] { - const keywords: Node[] = []; - - pushKeywordIf(keywords, switchStatement.getFirstToken(), SyntaxKind.SwitchKeyword); + function getSwitchCaseDefaultOccurrences(switchStatement: ts.SwitchStatement): ts.Node[] { + const keywords: ts.Node[] = []; + pushKeywordIf(keywords, switchStatement.getFirstToken(), ts.SyntaxKind.SwitchKeyword); // Go through each clause in the switch statement, collecting the 'case'/'default' keywords. - forEach(switchStatement.caseBlock.clauses, clause => { - pushKeywordIf(keywords, clause.getFirstToken(), SyntaxKind.CaseKeyword, SyntaxKind.DefaultKeyword); - - forEach(aggregateAllBreakAndContinueStatements(clause), statement => { + ts.forEach(switchStatement.caseBlock.clauses, clause => { + pushKeywordIf(keywords, clause.getFirstToken(), ts.SyntaxKind.CaseKeyword, ts.SyntaxKind.DefaultKeyword); + ts.forEach(aggregateAllBreakAndContinueStatements(clause), statement => { if (ownsBreakOrContinueStatement(switchStatement, statement)) { - pushKeywordIf(keywords, statement.getFirstToken(), SyntaxKind.BreakKeyword); + pushKeywordIf(keywords, statement.getFirstToken(), ts.SyntaxKind.BreakKeyword); } }); }); @@ -328,84 +321,82 @@ namespace ts { return keywords; } - function getTryCatchFinallyOccurrences(tryStatement: TryStatement, sourceFile: SourceFile): Node[] { - const keywords: Node[] = []; - - pushKeywordIf(keywords, tryStatement.getFirstToken(), SyntaxKind.TryKeyword); + function getTryCatchFinallyOccurrences(tryStatement: ts.TryStatement, sourceFile: ts.SourceFile): ts.Node[] { + const keywords: ts.Node[] = []; + pushKeywordIf(keywords, tryStatement.getFirstToken(), ts.SyntaxKind.TryKeyword); if (tryStatement.catchClause) { - pushKeywordIf(keywords, tryStatement.catchClause.getFirstToken(), SyntaxKind.CatchKeyword); + pushKeywordIf(keywords, tryStatement.catchClause.getFirstToken(), ts.SyntaxKind.CatchKeyword); } if (tryStatement.finallyBlock) { - const finallyKeyword = findChildOfKind(tryStatement, SyntaxKind.FinallyKeyword, sourceFile)!; - pushKeywordIf(keywords, finallyKeyword, SyntaxKind.FinallyKeyword); + const finallyKeyword = ts.findChildOfKind(tryStatement, ts.SyntaxKind.FinallyKeyword, sourceFile)!; + pushKeywordIf(keywords, finallyKeyword, ts.SyntaxKind.FinallyKeyword); } return keywords; } - function getThrowOccurrences(throwStatement: ThrowStatement, sourceFile: SourceFile): Node[] | undefined { + function getThrowOccurrences(throwStatement: ts.ThrowStatement, sourceFile: ts.SourceFile): ts.Node[] | undefined { const owner = getThrowStatementOwner(throwStatement); if (!owner) { return undefined; } - const keywords: Node[] = []; - - forEach(aggregateOwnedThrowStatements(owner), throwStatement => { - keywords.push(findChildOfKind(throwStatement, SyntaxKind.ThrowKeyword, sourceFile)!); + const keywords: ts.Node[] = []; + ts.forEach(aggregateOwnedThrowStatements(owner), throwStatement => { + keywords.push(ts.findChildOfKind(throwStatement, ts.SyntaxKind.ThrowKeyword, sourceFile)!); }); // If the "owner" is a function, then we equate 'return' and 'throw' statements in their // ability to "jump out" of the function, and include occurrences for both. - if (isFunctionBlock(owner)) { - forEachReturnStatement(owner as Block, returnStatement => { - keywords.push(findChildOfKind(returnStatement, SyntaxKind.ReturnKeyword, sourceFile)!); + if (ts.isFunctionBlock(owner)) { + ts.forEachReturnStatement(owner as ts.Block, returnStatement => { + keywords.push(ts.findChildOfKind(returnStatement, ts.SyntaxKind.ReturnKeyword, sourceFile)!); }); } return keywords; } - function getReturnOccurrences(returnStatement: ReturnStatement, sourceFile: SourceFile): Node[] | undefined { - const func = getContainingFunction(returnStatement) as FunctionLikeDeclaration; + function getReturnOccurrences(returnStatement: ts.ReturnStatement, sourceFile: ts.SourceFile): ts.Node[] | undefined { + const func = ts.getContainingFunction(returnStatement) as ts.FunctionLikeDeclaration; if (!func) { return undefined; } - const keywords: Node[] = []; - forEachReturnStatement(cast(func.body, isBlock), returnStatement => { - keywords.push(findChildOfKind(returnStatement, SyntaxKind.ReturnKeyword, sourceFile)!); + const keywords: ts.Node[] = []; + ts.forEachReturnStatement(ts.cast(func.body, ts.isBlock), returnStatement => { + keywords.push(ts.findChildOfKind(returnStatement, ts.SyntaxKind.ReturnKeyword, sourceFile)!); }); // Include 'throw' statements that do not occur within a try block. - forEach(aggregateOwnedThrowStatements(func.body!), throwStatement => { - keywords.push(findChildOfKind(throwStatement, SyntaxKind.ThrowKeyword, sourceFile)!); + ts.forEach(aggregateOwnedThrowStatements(func.body!), throwStatement => { + keywords.push(ts.findChildOfKind(throwStatement, ts.SyntaxKind.ThrowKeyword, sourceFile)!); }); return keywords; } - function getAsyncAndAwaitOccurrences(node: Node): Node[] | undefined { - const func = getContainingFunction(node) as FunctionLikeDeclaration; + function getAsyncAndAwaitOccurrences(node: ts.Node): ts.Node[] | undefined { + const func = ts.getContainingFunction(node) as ts.FunctionLikeDeclaration; if (!func) { return undefined; } - const keywords: Node[] = []; + const keywords: ts.Node[] = []; if (func.modifiers) { func.modifiers.forEach(modifier => { - pushKeywordIf(keywords, modifier, SyntaxKind.AsyncKeyword); + pushKeywordIf(keywords, modifier, ts.SyntaxKind.AsyncKeyword); }); } - forEachChild(func, child => { + ts.forEachChild(func, child => { traverseWithoutCrossingFunction(child, node => { - if (isAwaitExpression(node)) { - pushKeywordIf(keywords, node.getFirstToken(), SyntaxKind.AwaitKeyword); + if (ts.isAwaitExpression(node)) { + pushKeywordIf(keywords, node.getFirstToken(), ts.SyntaxKind.AwaitKeyword); } }); }); @@ -414,18 +405,17 @@ namespace ts { return keywords; } - function getYieldOccurrences(node: Node): Node[] | undefined { - const func = getContainingFunction(node) as FunctionDeclaration; + function getYieldOccurrences(node: ts.Node): ts.Node[] | undefined { + const func = ts.getContainingFunction(node) as ts.FunctionDeclaration; if (!func) { return undefined; } - const keywords: Node[] = []; - - forEachChild(func, child => { + const keywords: ts.Node[] = []; + ts.forEachChild(func, child => { traverseWithoutCrossingFunction(child, node => { - if (isYieldExpression(node)) { - pushKeywordIf(keywords, node.getFirstToken(), SyntaxKind.YieldKeyword); + if (ts.isYieldExpression(node)) { + pushKeywordIf(keywords, node.getFirstToken(), ts.SyntaxKind.YieldKeyword); } }); }); @@ -434,21 +424,21 @@ namespace ts { } // Do not cross function/class/interface/module/type boundaries. - function traverseWithoutCrossingFunction(node: Node, cb: (node: Node) => void) { + function traverseWithoutCrossingFunction(node: ts.Node, cb: (node: ts.Node) => void) { cb(node); - if (!isFunctionLike(node) && !isClassLike(node) && !isInterfaceDeclaration(node) && !isModuleDeclaration(node) && !isTypeAliasDeclaration(node) && !isTypeNode(node)) { - forEachChild(node, child => traverseWithoutCrossingFunction(child, cb)); + if (!ts.isFunctionLike(node) && !ts.isClassLike(node) && !ts.isInterfaceDeclaration(node) && !ts.isModuleDeclaration(node) && !ts.isTypeAliasDeclaration(node) && !ts.isTypeNode(node)) { + ts.forEachChild(node, child => traverseWithoutCrossingFunction(child, cb)); } } - function getIfElseOccurrences(ifStatement: IfStatement, sourceFile: SourceFile): HighlightSpan[] { + function getIfElseOccurrences(ifStatement: ts.IfStatement, sourceFile: ts.SourceFile): ts.HighlightSpan[] { const keywords = getIfElseKeywords(ifStatement, sourceFile); - const result: HighlightSpan[] = []; + const result: ts.HighlightSpan[] = []; // We'd like to highlight else/ifs together if they are only separated by whitespace // (i.e. the keywords are separated by no comments, no newlines). for (let i = 0; i < keywords.length; i++) { - if (keywords[i].kind === SyntaxKind.ElseKeyword && i < keywords.length - 1) { + if (keywords[i].kind === ts.SyntaxKind.ElseKeyword && i < keywords.length - 1) { const elseKeyword = keywords[i]; const ifKeyword = keywords[i + 1]; // this *should* always be an 'if' keyword. @@ -456,7 +446,7 @@ namespace ts { // Avoid recalculating getStart() by iterating backwards. for (let j = ifKeyword.getStart(sourceFile) - 1; j >= elseKeyword.end; j--) { - if (!isWhiteSpaceSingleLine(sourceFile.text.charCodeAt(j))) { + if (!ts.isWhiteSpaceSingleLine(sourceFile.text.charCodeAt(j))) { shouldCombineElseAndIf = false; break; } @@ -465,8 +455,8 @@ namespace ts { if (shouldCombineElseAndIf) { result.push({ fileName: sourceFile.fileName, - textSpan: createTextSpanFromBounds(elseKeyword.getStart(), ifKeyword.end), - kind: HighlightSpanKind.reference + textSpan: ts.createTextSpanFromBounds(elseKeyword.getStart(), ifKeyword.end), + kind: ts.HighlightSpanKind.reference }); i++; // skip the next keyword continue; @@ -480,27 +470,27 @@ namespace ts { return result; } - function getIfElseKeywords(ifStatement: IfStatement, sourceFile: SourceFile): Node[] { - const keywords: Node[] = []; + function getIfElseKeywords(ifStatement: ts.IfStatement, sourceFile: ts.SourceFile): ts.Node[] { + const keywords: ts.Node[] = []; // Traverse upwards through all parent if-statements linked by their else-branches. - while (isIfStatement(ifStatement.parent) && ifStatement.parent.elseStatement === ifStatement) { + while (ts.isIfStatement(ifStatement.parent) && ifStatement.parent.elseStatement === ifStatement) { ifStatement = ifStatement.parent; } // Now traverse back down through the else branches, aggregating if/else keywords of if-statements. while (true) { const children = ifStatement.getChildren(sourceFile); - pushKeywordIf(keywords, children[0], SyntaxKind.IfKeyword); + pushKeywordIf(keywords, children[0], ts.SyntaxKind.IfKeyword); // Generally the 'else' keyword is second-to-last, so we traverse backwards. for (let i = children.length - 1; i >= 0; i--) { - if (pushKeywordIf(keywords, children[i], SyntaxKind.ElseKeyword)) { + if (pushKeywordIf(keywords, children[i], ts.SyntaxKind.ElseKeyword)) { break; } } - if (!ifStatement.elseStatement || !isIfStatement(ifStatement.elseStatement)) { + if (!ifStatement.elseStatement || !ts.isIfStatement(ifStatement.elseStatement)) { break; } @@ -514,8 +504,8 @@ namespace ts { * Whether or not a 'node' is preceded by a label of the given string. * Note: 'node' cannot be a SourceFile. */ - function isLabeledBy(node: Node, labelName: __String): boolean { - return !!findAncestor(node.parent, owner => !isLabeledStatement(owner) ? "quit" : owner.label.escapedText === labelName); + function isLabeledBy(node: ts.Node, labelName: ts.__String): boolean { + return !!ts.findAncestor(node.parent, owner => !ts.isLabeledStatement(owner) ? "quit" : owner.label.escapedText === labelName); } } } diff --git a/src/services/documentRegistry.ts b/src/services/documentRegistry.ts index 7141bc12fd7cd..49189dbb47cb3 100644 --- a/src/services/documentRegistry.ts +++ b/src/services/documentRegistry.ts @@ -32,21 +32,8 @@ namespace ts { * @param version Current version of the file. Only used if the file was not found * in the registry and a new one was created. */ - acquireDocument( - fileName: string, - compilationSettingsOrHost: CompilerOptions | MinimalResolutionCacheHost, - scriptSnapshot: IScriptSnapshot, - version: string, - scriptKind?: ScriptKind): SourceFile; - - acquireDocumentWithKey( - fileName: string, - path: Path, - compilationSettingsOrHost: CompilerOptions | MinimalResolutionCacheHost, - key: DocumentRegistryBucketKey, - scriptSnapshot: IScriptSnapshot, - version: string, - scriptKind?: ScriptKind): SourceFile; + acquireDocument(fileName: string, compilationSettingsOrHost: ts.CompilerOptions | ts.MinimalResolutionCacheHost, scriptSnapshot: ts.IScriptSnapshot, version: string, scriptKind?: ts.ScriptKind): ts.SourceFile; + acquireDocumentWithKey(fileName: string, path: ts.Path, compilationSettingsOrHost: ts.CompilerOptions | ts.MinimalResolutionCacheHost, key: DocumentRegistryBucketKey, scriptSnapshot: ts.IScriptSnapshot, version: string, scriptKind?: ts.ScriptKind): ts.SourceFile; /** * Request an updated version of an already existing SourceFile with a given fileName @@ -63,23 +50,9 @@ namespace ts { * @param scriptSnapshot Text of the file. * @param version Current version of the file. */ - updateDocument( - fileName: string, - compilationSettingsOrHost: CompilerOptions | MinimalResolutionCacheHost, - scriptSnapshot: IScriptSnapshot, - version: string, - scriptKind?: ScriptKind): SourceFile; - - updateDocumentWithKey( - fileName: string, - path: Path, - compilationSettingsOrHost: CompilerOptions | MinimalResolutionCacheHost, - key: DocumentRegistryBucketKey, - scriptSnapshot: IScriptSnapshot, - version: string, - scriptKind?: ScriptKind): SourceFile; - - getKeyForCompilationSettings(settings: CompilerOptions): DocumentRegistryBucketKey; + updateDocument(fileName: string, compilationSettingsOrHost: ts.CompilerOptions | ts.MinimalResolutionCacheHost, scriptSnapshot: ts.IScriptSnapshot, version: string, scriptKind?: ts.ScriptKind): ts.SourceFile; + updateDocumentWithKey(fileName: string, path: ts.Path, compilationSettingsOrHost: ts.CompilerOptions | ts.MinimalResolutionCacheHost, key: DocumentRegistryBucketKey, scriptSnapshot: ts.IScriptSnapshot, version: string, scriptKind?: ts.ScriptKind): ts.SourceFile; + getKeyForCompilationSettings(settings: ts.CompilerOptions): DocumentRegistryBucketKey; /** * Informs the DocumentRegistry that a file is not needed any longer. * @@ -90,7 +63,7 @@ namespace ts { * @param compilationSettings The compilation settings used to acquire the file */ /**@deprecated pass scriptKind for correctness */ - releaseDocument(fileName: string, compilationSettings: CompilerOptions): void; + releaseDocument(fileName: string, compilationSettings: ts.CompilerOptions): void; /** * Informs the DocumentRegistry that a file is not needed any longer. * @@ -101,28 +74,33 @@ namespace ts { * @param compilationSettings The compilation settings used to acquire the file * @param scriptKind The script kind of the file to be released */ - releaseDocument(fileName: string, compilationSettings: CompilerOptions, scriptKind: ScriptKind): void; // eslint-disable-line @typescript-eslint/unified-signatures + releaseDocument(fileName: string, compilationSettings: ts.CompilerOptions, scriptKind: ts.ScriptKind): void; // eslint-disable-line @typescript-eslint/unified-signatures /** * @deprecated pass scriptKind for correctness */ - releaseDocumentWithKey(path: Path, key: DocumentRegistryBucketKey): void; - releaseDocumentWithKey(path: Path, key: DocumentRegistryBucketKey, scriptKind: ScriptKind): void; // eslint-disable-line @typescript-eslint/unified-signatures + releaseDocumentWithKey(path: ts.Path, key: DocumentRegistryBucketKey): void; + releaseDocumentWithKey(path: ts.Path, key: DocumentRegistryBucketKey, scriptKind: ts.ScriptKind): void; // eslint-disable-line @typescript-eslint/unified-signatures /*@internal*/ - getLanguageServiceRefCounts(path: Path, scriptKind: ScriptKind): [string, number | undefined][]; + getLanguageServiceRefCounts(path: ts.Path, scriptKind: ts.ScriptKind): [ + string, + number | undefined + ][]; reportStats(): string; } /*@internal*/ export interface ExternalDocumentCache { - setDocument(key: DocumentRegistryBucketKey, path: Path, sourceFile: SourceFile): void; - getDocument(key: DocumentRegistryBucketKey, path: Path): SourceFile | undefined; + setDocument(key: DocumentRegistryBucketKey, path: ts.Path, sourceFile: ts.SourceFile): void; + getDocument(key: DocumentRegistryBucketKey, path: ts.Path): ts.SourceFile | undefined; } - export type DocumentRegistryBucketKey = string & { __bucketKey: any }; + export type DocumentRegistryBucketKey = string & { + __bucketKey: any; + }; interface DocumentRegistryEntry { - sourceFile: SourceFile; + sourceFile: ts.SourceFile; // The number of language services that this source file is referenced in. When no more // language services are referencing the file, then the file can be removed from the @@ -130,7 +108,7 @@ namespace ts { languageServiceRefCount: number; } - type BucketEntry = DocumentRegistryEntry | ESMap; + type BucketEntry = DocumentRegistryEntry | ts.ESMap; function isDocumentRegistryEntry(entry: BucketEntry): entry is DocumentRegistryEntry { return !!(entry as DocumentRegistryEntry).sourceFile; } @@ -143,13 +121,17 @@ namespace ts { export function createDocumentRegistryInternal(useCaseSensitiveFileNames?: boolean, currentDirectory = "", externalCache?: ExternalDocumentCache): DocumentRegistry { // Maps from compiler setting target (ES3, ES5, etc.) to all the cached documents we have // for those settings. - const buckets = new Map>(); - const getCanonicalFileName = createGetCanonicalFileName(!!useCaseSensitiveFileNames); + const buckets = new ts.Map>(); + const getCanonicalFileName = ts.createGetCanonicalFileName(!!useCaseSensitiveFileNames); function reportStats() { - const bucketInfoArray = arrayFrom(buckets.keys()).filter(name => name && name.charAt(0) === "_").map(name => { + const bucketInfoArray = ts.arrayFrom(buckets.keys()).filter(name => name && name.charAt(0) === "_").map(name => { const entries = buckets.get(name)!; - const sourceFiles: { name: string; scriptKind: ScriptKind, refCount: number; }[] = []; + const sourceFiles: { + name: string; + scriptKind: ts.ScriptKind; + refCount: number; + }[] = []; entries.forEach((entry, name) => { if (isDocumentRegistryEntry(entry)) { sourceFiles.push({ @@ -171,75 +153,67 @@ namespace ts { return JSON.stringify(bucketInfoArray, undefined, 2); } - function getCompilationSettings(settingsOrHost: CompilerOptions | MinimalResolutionCacheHost) { + function getCompilationSettings(settingsOrHost: ts.CompilerOptions | ts.MinimalResolutionCacheHost) { if (typeof settingsOrHost.getCompilationSettings === "function") { - return (settingsOrHost as MinimalResolutionCacheHost).getCompilationSettings(); + return (settingsOrHost as ts.MinimalResolutionCacheHost).getCompilationSettings(); } - return settingsOrHost as CompilerOptions; + return settingsOrHost as ts.CompilerOptions; } - function acquireDocument(fileName: string, compilationSettings: CompilerOptions | MinimalResolutionCacheHost, scriptSnapshot: IScriptSnapshot, version: string, scriptKind?: ScriptKind): SourceFile { - const path = toPath(fileName, currentDirectory, getCanonicalFileName); + function acquireDocument(fileName: string, compilationSettings: ts.CompilerOptions | ts.MinimalResolutionCacheHost, scriptSnapshot: ts.IScriptSnapshot, version: string, scriptKind?: ts.ScriptKind): ts.SourceFile { + const path = ts.toPath(fileName, currentDirectory, getCanonicalFileName); const key = getKeyForCompilationSettings(getCompilationSettings(compilationSettings)); return acquireDocumentWithKey(fileName, path, compilationSettings, key, scriptSnapshot, version, scriptKind); } - function acquireDocumentWithKey(fileName: string, path: Path, compilationSettings: CompilerOptions | MinimalResolutionCacheHost, key: DocumentRegistryBucketKey, scriptSnapshot: IScriptSnapshot, version: string, scriptKind?: ScriptKind): SourceFile { + function acquireDocumentWithKey(fileName: string, path: ts.Path, compilationSettings: ts.CompilerOptions | ts.MinimalResolutionCacheHost, key: DocumentRegistryBucketKey, scriptSnapshot: ts.IScriptSnapshot, version: string, scriptKind?: ts.ScriptKind): ts.SourceFile { return acquireOrUpdateDocument(fileName, path, compilationSettings, key, scriptSnapshot, version, /*acquiring*/ true, scriptKind); } - function updateDocument(fileName: string, compilationSettings: CompilerOptions | MinimalResolutionCacheHost, scriptSnapshot: IScriptSnapshot, version: string, scriptKind?: ScriptKind): SourceFile { - const path = toPath(fileName, currentDirectory, getCanonicalFileName); + function updateDocument(fileName: string, compilationSettings: ts.CompilerOptions | ts.MinimalResolutionCacheHost, scriptSnapshot: ts.IScriptSnapshot, version: string, scriptKind?: ts.ScriptKind): ts.SourceFile { + const path = ts.toPath(fileName, currentDirectory, getCanonicalFileName); const key = getKeyForCompilationSettings(getCompilationSettings(compilationSettings)); return updateDocumentWithKey(fileName, path, compilationSettings, key, scriptSnapshot, version, scriptKind); } - function updateDocumentWithKey(fileName: string, path: Path, compilationSettings: CompilerOptions | MinimalResolutionCacheHost, key: DocumentRegistryBucketKey, scriptSnapshot: IScriptSnapshot, version: string, scriptKind?: ScriptKind): SourceFile { + function updateDocumentWithKey(fileName: string, path: ts.Path, compilationSettings: ts.CompilerOptions | ts.MinimalResolutionCacheHost, key: DocumentRegistryBucketKey, scriptSnapshot: ts.IScriptSnapshot, version: string, scriptKind?: ts.ScriptKind): ts.SourceFile { return acquireOrUpdateDocument(fileName, path, getCompilationSettings(compilationSettings), key, scriptSnapshot, version, /*acquiring*/ false, scriptKind); } - function getDocumentRegistryEntry(bucketEntry: BucketEntry, scriptKind: ScriptKind | undefined) { - const entry = isDocumentRegistryEntry(bucketEntry) ? bucketEntry : bucketEntry.get(Debug.checkDefined(scriptKind, "If there are more than one scriptKind's for same document the scriptKind should be provided")); - Debug.assert(scriptKind === undefined || !entry || entry.sourceFile.scriptKind === scriptKind, `Script kind should match provided ScriptKind:${scriptKind} and sourceFile.scriptKind: ${entry?.sourceFile.scriptKind}, !entry: ${!entry}`); + function getDocumentRegistryEntry(bucketEntry: BucketEntry, scriptKind: ts.ScriptKind | undefined) { + const entry = isDocumentRegistryEntry(bucketEntry) ? bucketEntry : bucketEntry.get(ts.Debug.checkDefined(scriptKind, "If there are more than one scriptKind's for same document the scriptKind should be provided")); + ts.Debug.assert(scriptKind === undefined || !entry || entry.sourceFile.scriptKind === scriptKind, `Script kind should match provided ScriptKind:${scriptKind} and sourceFile.scriptKind: ${entry?.sourceFile.scriptKind}, !entry: ${!entry}`); return entry; } - function acquireOrUpdateDocument( - fileName: string, - path: Path, - compilationSettingsOrHost: CompilerOptions | MinimalResolutionCacheHost, - key: DocumentRegistryBucketKey, - scriptSnapshot: IScriptSnapshot, - version: string, - acquiring: boolean, - scriptKind?: ScriptKind): SourceFile { - scriptKind = ensureScriptKind(fileName, scriptKind); + function acquireOrUpdateDocument(fileName: string, path: ts.Path, compilationSettingsOrHost: ts.CompilerOptions | ts.MinimalResolutionCacheHost, key: DocumentRegistryBucketKey, scriptSnapshot: ts.IScriptSnapshot, version: string, acquiring: boolean, scriptKind?: ts.ScriptKind): ts.SourceFile { + scriptKind = ts.ensureScriptKind(fileName, scriptKind); const compilationSettings = getCompilationSettings(compilationSettingsOrHost); - const host: MinimalResolutionCacheHost | undefined = compilationSettingsOrHost === compilationSettings ? undefined : compilationSettingsOrHost as MinimalResolutionCacheHost; - const scriptTarget = scriptKind === ScriptKind.JSON ? ScriptTarget.JSON : getEmitScriptTarget(compilationSettings); - const sourceFileOptions: CreateSourceFileOptions = { + const host: ts.MinimalResolutionCacheHost | undefined = compilationSettingsOrHost === compilationSettings ? undefined : compilationSettingsOrHost as ts.MinimalResolutionCacheHost; + const scriptTarget = scriptKind === ts.ScriptKind.JSON ? ts.ScriptTarget.JSON : ts.getEmitScriptTarget(compilationSettings); + const sourceFileOptions: ts.CreateSourceFileOptions = { languageVersion: scriptTarget, - impliedNodeFormat: host && getImpliedNodeFormatForFile(path, host.getCompilerHost?.()?.getModuleResolutionCache?.()?.getPackageJsonInfoCache(), host, compilationSettings), - setExternalModuleIndicator: getSetExternalModuleIndicator(compilationSettings) + impliedNodeFormat: host && ts.getImpliedNodeFormatForFile(path, host.getCompilerHost?.()?.getModuleResolutionCache?.()?.getPackageJsonInfoCache(), host, compilationSettings), + setExternalModuleIndicator: ts.getSetExternalModuleIndicator(compilationSettings) }; const oldBucketCount = buckets.size; - const bucket = getOrUpdate(buckets, key, () => new Map()); - if (tracing) { + const bucket = ts.getOrUpdate(buckets, key, () => new ts.Map()); + if (ts.tracing) { if (buckets.size > oldBucketCount) { // It is interesting, but not definitively problematic if a build requires multiple document registry buckets - // perhaps they are for two projects that don't have any overlap. // Bonus: these events can help us interpret the more interesting event below. - tracing.instant(tracing.Phase.Session, "createdDocumentRegistryBucket", { configFilePath: compilationSettings.configFilePath, key }); + ts.tracing.instant(ts.tracing.Phase.Session, "createdDocumentRegistryBucket", { configFilePath: compilationSettings.configFilePath, key }); } // It is fairly suspicious to have one path in two buckets - you'd expect dependencies to have similar configurations. // If this occurs unexpectedly, the fix is likely to synchronize the project settings. // Skip .d.ts files to reduce noise (should also cover most of node_modules). - const otherBucketKey = !isDeclarationFileName(path) && - forEachEntry(buckets, (bucket, bucketKey) => bucketKey !== key && bucket.has(path) && bucketKey); + const otherBucketKey = !ts.isDeclarationFileName(path) && + ts.forEachEntry(buckets, (bucket, bucketKey) => bucketKey !== key && bucket.has(path) && bucketKey); if (otherBucketKey) { - tracing.instant(tracing.Phase.Session, "documentRegistryBucketOverlap", { path, key1: otherBucketKey, key2: key }); + ts.tracing.instant(ts.tracing.Phase.Session, "documentRegistryBucketOverlap", { path, key1: otherBucketKey, key2: key }); } } @@ -248,7 +222,7 @@ namespace ts { if (!entry && externalCache) { const sourceFile = externalCache.getDocument(key, path); if (sourceFile) { - Debug.assert(acquiring); + ts.Debug.assert(acquiring); entry = { sourceFile, languageServiceRefCount: 0 @@ -259,7 +233,7 @@ namespace ts { if (!entry) { // Have never seen this file with these settings. Create a new source file for it. - const sourceFile = createLanguageServiceSourceFile(fileName, scriptSnapshot, sourceFileOptions, version, /*setNodeParents*/ false, scriptKind); + const sourceFile = ts.createLanguageServiceSourceFile(fileName, scriptSnapshot, sourceFileOptions, version, /*setNodeParents*/ false, scriptKind); if (externalCache) { externalCache.setDocument(key, path, sourceFile); } @@ -274,8 +248,7 @@ namespace ts { // the script snapshot. If so, update it appropriately. Otherwise, we can just // return it as is. if (entry.sourceFile.version !== version) { - entry.sourceFile = updateLanguageServiceSourceFile(entry.sourceFile, scriptSnapshot, version, - scriptSnapshot.getChangeRange(entry.sourceFile.scriptSnapshot!)); // TODO: GH#18217 + entry.sourceFile = ts.updateLanguageServiceSourceFile(entry.sourceFile, scriptSnapshot, version, scriptSnapshot.getChangeRange(entry.sourceFile.scriptSnapshot!)); // TODO: GH#18217 if (externalCache) { externalCache.setDocument(key, path, entry.sourceFile); } @@ -290,7 +263,7 @@ namespace ts { entry.languageServiceRefCount++; } } - Debug.assert(entry.languageServiceRefCount !== 0); + ts.Debug.assert(entry.languageServiceRefCount !== 0); return entry.sourceFile; @@ -299,7 +272,7 @@ namespace ts { bucket.set(path, entry!); } else if (isDocumentRegistryEntry(bucketEntry)) { - const scriptKindMap = new Map(); + const scriptKindMap = new ts.Map(); scriptKindMap.set(bucketEntry.sourceFile.scriptKind, bucketEntry); scriptKindMap.set(scriptKind!, entry!); bucket.set(path, scriptKindMap); @@ -310,19 +283,19 @@ namespace ts { } } - function releaseDocument(fileName: string, compilationSettings: CompilerOptions, scriptKind?: ScriptKind): void { - const path = toPath(fileName, currentDirectory, getCanonicalFileName); + function releaseDocument(fileName: string, compilationSettings: ts.CompilerOptions, scriptKind?: ts.ScriptKind): void { + const path = ts.toPath(fileName, currentDirectory, getCanonicalFileName); const key = getKeyForCompilationSettings(compilationSettings); return releaseDocumentWithKey(path, key, scriptKind); } - function releaseDocumentWithKey(path: Path, key: DocumentRegistryBucketKey, scriptKind?: ScriptKind): void { - const bucket = Debug.checkDefined(buckets.get(key)); + function releaseDocumentWithKey(path: ts.Path, key: DocumentRegistryBucketKey, scriptKind?: ts.ScriptKind): void { + const bucket = ts.Debug.checkDefined(buckets.get(key)); const bucketEntry = bucket.get(path)!; const entry = getDocumentRegistryEntry(bucketEntry, scriptKind)!; entry.languageServiceRefCount--; - Debug.assert(entry.languageServiceRefCount >= 0); + ts.Debug.assert(entry.languageServiceRefCount >= 0); if (entry.languageServiceRefCount === 0) { if (isDocumentRegistryEntry(bucketEntry)) { bucket.delete(path); @@ -330,14 +303,17 @@ namespace ts { else { bucketEntry.delete(scriptKind!); if (bucketEntry.size === 1) { - bucket.set(path, firstDefinedIterator(bucketEntry.values(), identity)!); + bucket.set(path, ts.firstDefinedIterator(bucketEntry.values(), ts.identity)!); } } } } - function getLanguageServiceRefCounts(path: Path, scriptKind: ScriptKind) { - return arrayFrom(buckets.entries(), ([key, bucket]): [string, number | undefined] => { + function getLanguageServiceRefCounts(path: ts.Path, scriptKind: ts.ScriptKind) { + return ts.arrayFrom(buckets.entries(), ([key, bucket]): [ + string, + number | undefined + ] => { const bucketEntry = bucket.get(path); const entry = bucketEntry && getDocumentRegistryEntry(bucketEntry, scriptKind); return [key, entry && entry.languageServiceRefCount]; @@ -361,8 +337,8 @@ namespace ts { if (value === null || typeof value !== "object") { // eslint-disable-line no-null/no-null return "" + value; } - if (isArray(value)) { - return `[${map(value, e => compilerOptionValueToString(e))?.join(",")}]`; + if (ts.isArray(value)) { + return `[${ts.map(value, e => compilerOptionValueToString(e))?.join(",")}]`; } let str = "{"; for (const key in value) { @@ -373,7 +349,7 @@ namespace ts { return str + "}"; } - function getKeyForCompilationSettings(settings: CompilerOptions): DocumentRegistryBucketKey { - return sourceFileAffectingCompilerOptions.map(option => compilerOptionValueToString(getCompilerOptionValue(settings, option))).join("|") + (settings.pathsBasePath ? `|${settings.pathsBasePath}` : undefined) as DocumentRegistryBucketKey; + function getKeyForCompilationSettings(settings: ts.CompilerOptions): DocumentRegistryBucketKey { + return ts.sourceFileAffectingCompilerOptions.map(option => compilerOptionValueToString(ts.getCompilerOptionValue(settings, option))).join("|") + (settings.pathsBasePath ? `|${settings.pathsBasePath}` : undefined) as DocumentRegistryBucketKey; } } diff --git a/src/services/exportAsModule.ts b/src/services/exportAsModule.ts index 6760e9c38c2d0..7179e64d4fc57 100644 --- a/src/services/exportAsModule.ts +++ b/src/services/exportAsModule.ts @@ -1,7 +1,9 @@ // Here we expose the TypeScript services as an external module // so that it may be consumed easily like a node module. // @ts-ignore -/* @internal */ declare const module: { exports: {} }; +/* @internal */ declare const module: { + exports: {}; +}; if (typeof module !== "undefined" && module.exports) { module.exports = ts; } \ No newline at end of file diff --git a/src/services/exportInfoMap.ts b/src/services/exportInfoMap.ts index e8b52d48122ab..afe9d31056f33 100644 --- a/src/services/exportInfoMap.ts +++ b/src/services/exportInfoMap.ts @@ -4,23 +4,23 @@ namespace ts { Named, Default, Namespace, - CommonJS, + CommonJS } export const enum ExportKind { Named, Default, ExportEquals, - UMD, + UMD } export interface SymbolExportInfo { - readonly symbol: Symbol; - readonly moduleSymbol: Symbol; + readonly symbol: ts.Symbol; + readonly moduleSymbol: ts.Symbol; /** Set if `moduleSymbol` is an external module, not an ambient module */ moduleFileName: string | undefined; exportKind: ExportKind; - targetFlags: SymbolFlags; + targetFlags: ts.SymbolFlags; /** True if export was only found via the package.json AutoImportProvider (for telemetry). */ isFromPackageJson: boolean; } @@ -30,42 +30,45 @@ namespace ts { id: number; symbolName: string; capitalizedSymbolName: string | undefined; - symbolTableKey: __String; + symbolTableKey: ts.__String; moduleName: string; - moduleFile: SourceFile | undefined; + moduleFile: ts.SourceFile | undefined; packageName: string | undefined; // SymbolExportInfo, but optional symbols - readonly symbol: Symbol | undefined; - readonly moduleSymbol: Symbol | undefined; + readonly symbol: ts.Symbol | undefined; + readonly moduleSymbol: ts.Symbol | undefined; moduleFileName: string | undefined; exportKind: ExportKind; - targetFlags: SymbolFlags; + targetFlags: ts.SymbolFlags; isFromPackageJson: boolean; } export interface ExportInfoMap { - isUsableByFile(importingFile: Path): boolean; + isUsableByFile(importingFile: ts.Path): boolean; clear(): void; - add(importingFile: Path, symbol: Symbol, key: __String, moduleSymbol: Symbol, moduleFile: SourceFile | undefined, exportKind: ExportKind, isFromPackageJson: boolean, checker: TypeChecker): void; - get(importingFile: Path, key: string): readonly SymbolExportInfo[] | undefined; - search(importingFile: Path, preferCapitalized: boolean, matches: (name: string, targetFlags: SymbolFlags) => boolean, action: (info: readonly SymbolExportInfo[], symbolName: string, isFromAmbientModule: boolean, key: string) => void): void; + add(importingFile: ts.Path, symbol: ts.Symbol, key: ts.__String, moduleSymbol: ts.Symbol, moduleFile: ts.SourceFile | undefined, exportKind: ExportKind, isFromPackageJson: boolean, checker: ts.TypeChecker): void; + get(importingFile: ts.Path, key: string): readonly SymbolExportInfo[] | undefined; + search(importingFile: ts.Path, preferCapitalized: boolean, matches: (name: string, targetFlags: ts.SymbolFlags) => boolean, action: (info: readonly SymbolExportInfo[], symbolName: string, isFromAmbientModule: boolean, key: string) => void): void; releaseSymbols(): void; isEmpty(): boolean; /** @returns Whether the change resulted in the cache being cleared */ - onFileChanged(oldSourceFile: SourceFile, newSourceFile: SourceFile, typeAcquisitionEnabled: boolean): boolean; + onFileChanged(oldSourceFile: ts.SourceFile, newSourceFile: ts.SourceFile, typeAcquisitionEnabled: boolean): boolean; } export interface CacheableExportInfoMapHost { - getCurrentProgram(): Program | undefined; - getPackageJsonAutoImportProvider(): Program | undefined; + getCurrentProgram(): ts.Program | undefined; + getPackageJsonAutoImportProvider(): ts.Program | undefined; getGlobalTypingsCacheLocation(): string | undefined; } export function createCacheableExportInfoMap(host: CacheableExportInfoMapHost): ExportInfoMap { let exportInfoId = 1; - const exportInfo = createMultiMap(); - const symbols = new Map(); + const exportInfo = ts.createMultiMap(); + const symbols = new ts.Map(); /** * Key: node_modules package name (no @types). * Value: path to deepest node_modules folder seen that is @@ -76,8 +79,8 @@ namespace ts { * node_modules folder by seeing if its path starts with the * value stored here. */ - const packages = new Map(); - let usableByFileName: Path | undefined; + const packages = new ts.Map(); + let usableByFileName: ts.Path | undefined; const cache: ExportInfoMap = { isUsableByFile: importingFile => importingFile === usableByFileName, isEmpty: () => !exportInfo.size, @@ -94,15 +97,15 @@ namespace ts { let packageName; if (moduleFile) { - const nodeModulesPathParts = getNodeModulePathParts(moduleFile.fileName); + const nodeModulesPathParts = ts.getNodeModulePathParts(moduleFile.fileName); if (nodeModulesPathParts) { const { topLevelNodeModulesIndex, topLevelPackageNameIndex, packageRootIndex } = nodeModulesPathParts; - packageName = unmangleScopedPackageName(getPackageNameFromTypesPackageName(moduleFile.fileName.substring(topLevelPackageNameIndex + 1, packageRootIndex))); - if (startsWith(importingFile, moduleFile.path.substring(0, topLevelNodeModulesIndex))) { + packageName = ts.unmangleScopedPackageName(ts.getPackageNameFromTypesPackageName(moduleFile.fileName.substring(topLevelPackageNameIndex + 1, packageRootIndex))); + if (ts.startsWith(importingFile, moduleFile.path.substring(0, topLevelNodeModulesIndex))) { const prevDeepestNodeModulesPath = packages.get(packageName); const nodeModulesPath = moduleFile.fileName.substring(0, topLevelPackageNameIndex + 1); if (prevDeepestNodeModulesPath) { - const prevDeepestNodeModulesIndex = prevDeepestNodeModulesPath.indexOf(nodeModulesPathPart); + const prevDeepestNodeModulesIndex = prevDeepestNodeModulesPath.indexOf(ts.nodeModulesPathPart); if (topLevelNodeModulesIndex > prevDeepestNodeModulesIndex) { packages.set(packageName, nodeModulesPath); } @@ -115,7 +118,7 @@ namespace ts { } const isDefault = exportKind === ExportKind.Default; - const namedSymbol = isDefault && getLocalSymbolForExportDefault(symbol) || symbol; + const namedSymbol = isDefault && ts.getLocalSymbolForExportDefault(symbol) || symbol; // 1. A named export must be imported by its key in `moduleSymbol.exports` or `moduleSymbol.members`. // 2. A re-export merged with an export from a module augmentation can result in `symbol` // being an external module symbol; the name it is re-exported by will be `symbolTableKey` @@ -123,21 +126,21 @@ namespace ts { // 3. Otherwise, we have a default/namespace import that can be imported by any name, and // `symbolTableKey` will be something undesirable like `export=` or `default`, so we try to // get a better name. - const names = exportKind === ExportKind.Named || isExternalModuleSymbol(namedSymbol) - ? unescapeLeadingUnderscores(symbolTableKey) - : getNamesForExportedSymbol(namedSymbol, /*scriptTarget*/ undefined); + const names = exportKind === ExportKind.Named || ts.isExternalModuleSymbol(namedSymbol) + ? ts.unescapeLeadingUnderscores(symbolTableKey) + : ts.getNamesForExportedSymbol(namedSymbol, /*scriptTarget*/ undefined); const symbolName = typeof names === "string" ? names : names[0]; const capitalizedSymbolName = typeof names === "string" ? undefined : names[1]; - const moduleName = stripQuotes(moduleSymbol.name); + const moduleName = ts.stripQuotes(moduleSymbol.name); const id = exportInfoId++; - const target = skipAlias(symbol, checker); - const storedSymbol = symbol.flags & SymbolFlags.Transient ? undefined : symbol; - const storedModuleSymbol = moduleSymbol.flags & SymbolFlags.Transient ? undefined : moduleSymbol; - if (!storedSymbol || !storedModuleSymbol) symbols.set(id, [symbol, moduleSymbol]); - - exportInfo.add(key(symbolName, symbol, isExternalModuleNameRelative(moduleName) ? undefined : moduleName, checker), { + const target = ts.skipAlias(symbol, checker); + const storedSymbol = symbol.flags & ts.SymbolFlags.Transient ? undefined : symbol; + const storedModuleSymbol = moduleSymbol.flags & ts.SymbolFlags.Transient ? undefined : moduleSymbol; + if (!storedSymbol || !storedModuleSymbol) + symbols.set(id, [symbol, moduleSymbol]); + exportInfo.add(key(symbolName, symbol, ts.isExternalModuleNameRelative(moduleName) ? undefined : moduleName, checker), { id, symbolTableKey, symbolName, @@ -154,12 +157,14 @@ namespace ts { }); }, get: (importingFile, key) => { - if (importingFile !== usableByFileName) return; + if (importingFile !== usableByFileName) + return; const result = exportInfo.get(key); return result?.map(rehydrateCachedInfo); }, search: (importingFile, preferCapitalized, matches, action) => { - if (importingFile !== usableByFileName) return; + if (importingFile !== usableByFileName) + return; exportInfo.forEach((info, key) => { const { symbolName, ambientModuleName } = parseKey(key); const name = preferCapitalized && info[0].capitalizedSymbolName || symbolName; @@ -175,22 +180,20 @@ namespace ts { releaseSymbols: () => { symbols.clear(); }, - onFileChanged: (oldSourceFile: SourceFile, newSourceFile: SourceFile, typeAcquisitionEnabled: boolean) => { + onFileChanged: (oldSourceFile: ts.SourceFile, newSourceFile: ts.SourceFile, typeAcquisitionEnabled: boolean) => { if (fileIsGlobalOnly(oldSourceFile) && fileIsGlobalOnly(newSourceFile)) { // File is purely global; doesn't affect export map return false; } - if ( - usableByFileName && usableByFileName !== newSourceFile.path || + if (usableByFileName && usableByFileName !== newSourceFile.path || // If ATA is enabled, auto-imports uses existing imports to guess whether you want auto-imports from node. // Adding or removing imports from node could change the outcome of that guess, so could change the suggestions list. - typeAcquisitionEnabled && consumesNodeCoreModules(oldSourceFile) !== consumesNodeCoreModules(newSourceFile) || + typeAcquisitionEnabled && ts.consumesNodeCoreModules(oldSourceFile) !== ts.consumesNodeCoreModules(newSourceFile) || // Module agumentation and ambient module changes can add or remove exports available to be auto-imported. // Changes elsewhere in the file can change the *type* of an export in a module augmentation, // but type info is gathered in getCompletionEntryDetails, which doesn’t use the cache. - !arrayIsEqualTo(oldSourceFile.moduleAugmentations, newSourceFile.moduleAugmentations) || - !ambientModuleDeclarationsAreEqual(oldSourceFile, newSourceFile) - ) { + !ts.arrayIsEqualTo(oldSourceFile.moduleAugmentations, newSourceFile.moduleAugmentations) || + !ambientModuleDeclarationsAreEqual(oldSourceFile, newSourceFile)) { cache.clear(); return true; } @@ -198,15 +201,16 @@ namespace ts { return false; }, }; - if (Debug.isDebugging) { + if (ts.Debug.isDebugging) { Object.defineProperty(cache, "__cache", { get: () => exportInfo }); } return cache; function rehydrateCachedInfo(info: CachedSymbolExportInfo): SymbolExportInfo { - if (info.symbol && info.moduleSymbol) return info as SymbolExportInfo; + if (info.symbol && info.moduleSymbol) + return info as SymbolExportInfo; const { id, exportKind, targetFlags, isFromPackageJson, moduleFileName } = info; - const [cachedSymbol, cachedModuleSymbol] = symbols.get(id) || emptyArray; + const [cachedSymbol, cachedModuleSymbol] = symbols.get(id) || ts.emptyArray; if (cachedSymbol && cachedModuleSymbol) { return { symbol: cachedSymbol, @@ -220,13 +224,12 @@ namespace ts { const checker = (isFromPackageJson ? host.getPackageJsonAutoImportProvider()! : host.getCurrentProgram()!).getTypeChecker(); - const moduleSymbol = info.moduleSymbol || cachedModuleSymbol || Debug.checkDefined(info.moduleFile + const moduleSymbol = info.moduleSymbol || cachedModuleSymbol || ts.Debug.checkDefined(info.moduleFile ? checker.getMergedSymbol(info.moduleFile.symbol) : checker.tryFindAmbientModule(info.moduleName)); - const symbol = info.symbol || cachedSymbol || Debug.checkDefined(exportKind === ExportKind.ExportEquals + const symbol = info.symbol || cachedSymbol || ts.Debug.checkDefined(exportKind === ExportKind.ExportEquals ? checker.resolveExternalModuleSymbol(moduleSymbol) - : checker.tryGetMemberInModuleExportsAndProperties(unescapeLeadingUnderscores(info.symbolTableKey), moduleSymbol), - `Could not find symbol '${info.symbolName}' by key '${info.symbolTableKey}' in module ${moduleSymbol.name}`); + : checker.tryGetMemberInModuleExportsAndProperties(ts.unescapeLeadingUnderscores(info.symbolTableKey), moduleSymbol), `Could not find symbol '${info.symbolName}' by key '${info.symbolTableKey}' in module ${moduleSymbol.name}`); symbols.set(id, [symbol, moduleSymbol]); return { symbol, @@ -238,9 +241,9 @@ namespace ts { }; } - function key(importedName: string, symbol: Symbol, ambientModuleName: string | undefined, checker: TypeChecker): string { + function key(importedName: string, symbol: ts.Symbol, ambientModuleName: string | undefined, checker: ts.TypeChecker): string { const moduleKey = ambientModuleName || ""; - return `${importedName}|${getSymbolId(skipAlias(symbol, checker))}|${moduleKey}`; + return `${importedName}|${ts.getSymbolId(ts.skipAlias(symbol, checker))}|${moduleKey}`; } function parseKey(key: string) { @@ -250,20 +253,20 @@ namespace ts { return { symbolName, ambientModuleName }; } - function fileIsGlobalOnly(file: SourceFile) { + function fileIsGlobalOnly(file: ts.SourceFile) { return !file.commonJsModuleIndicator && !file.externalModuleIndicator && !file.moduleAugmentations && !file.ambientModuleNames; } - function ambientModuleDeclarationsAreEqual(oldSourceFile: SourceFile, newSourceFile: SourceFile) { - if (!arrayIsEqualTo(oldSourceFile.ambientModuleNames, newSourceFile.ambientModuleNames)) { + function ambientModuleDeclarationsAreEqual(oldSourceFile: ts.SourceFile, newSourceFile: ts.SourceFile) { + if (!ts.arrayIsEqualTo(oldSourceFile.ambientModuleNames, newSourceFile.ambientModuleNames)) { return false; } let oldFileStatementIndex = -1; let newFileStatementIndex = -1; for (const ambientModuleName of newSourceFile.ambientModuleNames) { - const isMatchingModuleDeclaration = (node: Statement) => isNonGlobalAmbientModule(node) && node.name.text === ambientModuleName; - oldFileStatementIndex = findIndex(oldSourceFile.statements, isMatchingModuleDeclaration, oldFileStatementIndex + 1); - newFileStatementIndex = findIndex(newSourceFile.statements, isMatchingModuleDeclaration, newFileStatementIndex + 1); + const isMatchingModuleDeclaration = (node: ts.Statement) => ts.isNonGlobalAmbientModule(node) && node.name.text === ambientModuleName; + oldFileStatementIndex = ts.findIndex(oldSourceFile.statements, isMatchingModuleDeclaration, oldFileStatementIndex + 1); + newFileStatementIndex = ts.findIndex(newSourceFile.statements, isMatchingModuleDeclaration, newFileStatementIndex + 1); if (oldSourceFile.statements[oldFileStatementIndex] !== newSourceFile.statements[newFileStatementIndex]) { return false; } @@ -272,44 +275,33 @@ namespace ts { } function isNotShadowedByDeeperNodeModulesPackage(info: SymbolExportInfo, packageName: string | undefined) { - if (!packageName || !info.moduleFileName) return true; + if (!packageName || !info.moduleFileName) + return true; const typingsCacheLocation = host.getGlobalTypingsCacheLocation(); - if (typingsCacheLocation && startsWith(info.moduleFileName, typingsCacheLocation)) return true; + if (typingsCacheLocation && ts.startsWith(info.moduleFileName, typingsCacheLocation)) + return true; const packageDeepestNodeModulesPath = packages.get(packageName); - return !packageDeepestNodeModulesPath || startsWith(info.moduleFileName, packageDeepestNodeModulesPath); + return !packageDeepestNodeModulesPath || ts.startsWith(info.moduleFileName, packageDeepestNodeModulesPath); } } - - export function isImportableFile( - program: Program, - from: SourceFile, - to: SourceFile, - preferences: UserPreferences, - packageJsonFilter: PackageJsonImportFilter | undefined, - moduleSpecifierResolutionHost: ModuleSpecifierResolutionHost, - moduleSpecifierCache: ModuleSpecifierCache | undefined, - ): boolean { - if (from === to) return false; + export function isImportableFile(program: ts.Program, from: ts.SourceFile, to: ts.SourceFile, preferences: ts.UserPreferences, packageJsonFilter: ts.PackageJsonImportFilter | undefined, moduleSpecifierResolutionHost: ts.ModuleSpecifierResolutionHost, moduleSpecifierCache: ts.ModuleSpecifierCache | undefined): boolean { + if (from === to) + return false; const cachedResult = moduleSpecifierCache?.get(from.path, to.path, preferences, {}); if (cachedResult?.isBlockedByPackageJsonDependencies !== undefined) { return !cachedResult.isBlockedByPackageJsonDependencies; } - const getCanonicalFileName = hostGetCanonicalFileName(moduleSpecifierResolutionHost); + const getCanonicalFileName = ts.hostGetCanonicalFileName(moduleSpecifierResolutionHost); const globalTypingsCache = moduleSpecifierResolutionHost.getGlobalTypingsCacheLocation?.(); - const hasImportablePath = !!moduleSpecifiers.forEachFileNameOfModule( - from.fileName, - to.fileName, - moduleSpecifierResolutionHost, - /*preferSymlinks*/ false, - toPath => { + const hasImportablePath = !!ts.moduleSpecifiers.forEachFileNameOfModule(from.fileName, to.fileName, moduleSpecifierResolutionHost, + /*preferSymlinks*/ false, toPath => { const toFile = program.getSourceFile(toPath); // Determine to import using toPath only if toPath is what we were looking at // or there doesnt exist the file in the program by the symlink return (toFile === to || !toFile) && isImportablePath(from.fileName, toPath, getCanonicalFileName, globalTypingsCache); - } - ); + }); if (packageJsonFilter) { const isAutoImportable = hasImportablePath && packageJsonFilter.allowsImportingSourceFile(to, moduleSpecifierResolutionHost); @@ -324,45 +316,39 @@ namespace ts { * Don't include something from a `node_modules` that isn't actually reachable by a global import. * A relative import to node_modules is usually a bad idea. */ - function isImportablePath(fromPath: string, toPath: string, getCanonicalFileName: GetCanonicalFileName, globalCachePath?: string): boolean { + function isImportablePath(fromPath: string, toPath: string, getCanonicalFileName: ts.GetCanonicalFileName, globalCachePath?: string): boolean { // If it's in a `node_modules` but is not reachable from here via a global import, don't bother. - const toNodeModules = forEachAncestorDirectory(toPath, ancestor => getBaseFileName(ancestor) === "node_modules" ? ancestor : undefined); - const toNodeModulesParent = toNodeModules && getDirectoryPath(getCanonicalFileName(toNodeModules)); + const toNodeModules = ts.forEachAncestorDirectory(toPath, ancestor => ts.getBaseFileName(ancestor) === "node_modules" ? ancestor : undefined); + const toNodeModulesParent = toNodeModules && ts.getDirectoryPath(getCanonicalFileName(toNodeModules)); return toNodeModulesParent === undefined - || startsWith(getCanonicalFileName(fromPath), toNodeModulesParent) - || (!!globalCachePath && startsWith(getCanonicalFileName(globalCachePath), toNodeModulesParent)); + || ts.startsWith(getCanonicalFileName(fromPath), toNodeModulesParent) + || (!!globalCachePath && ts.startsWith(getCanonicalFileName(globalCachePath), toNodeModulesParent)); } - - export function forEachExternalModuleToImportFrom( - program: Program, - host: LanguageServiceHost, - useAutoImportProvider: boolean, - cb: (module: Symbol, moduleFile: SourceFile | undefined, program: Program, isFromPackageJson: boolean) => void, - ) { + export function forEachExternalModuleToImportFrom(program: ts.Program, host: ts.LanguageServiceHost, useAutoImportProvider: boolean, cb: (module: ts.Symbol, moduleFile: ts.SourceFile | undefined, program: ts.Program, isFromPackageJson: boolean) => void) { forEachExternalModule(program.getTypeChecker(), program.getSourceFiles(), (module, file) => cb(module, file, program, /*isFromPackageJson*/ false)); const autoImportProvider = useAutoImportProvider && host.getPackageJsonAutoImportProvider?.(); if (autoImportProvider) { - const start = timestamp(); + const start = ts.timestamp(); forEachExternalModule(autoImportProvider.getTypeChecker(), autoImportProvider.getSourceFiles(), (module, file) => cb(module, file, autoImportProvider, /*isFromPackageJson*/ true)); - host.log?.(`forEachExternalModuleToImportFrom autoImportProvider: ${timestamp() - start}`); + host.log?.(`forEachExternalModuleToImportFrom autoImportProvider: ${ts.timestamp() - start}`); } } - function forEachExternalModule(checker: TypeChecker, allSourceFiles: readonly SourceFile[], cb: (module: Symbol, sourceFile: SourceFile | undefined) => void) { + function forEachExternalModule(checker: ts.TypeChecker, allSourceFiles: readonly ts.SourceFile[], cb: (module: ts.Symbol, sourceFile: ts.SourceFile | undefined) => void) { for (const ambient of checker.getAmbientModules()) { - if (!stringContains(ambient.name, "*")) { + if (!ts.stringContains(ambient.name, "*")) { cb(ambient, /*sourceFile*/ undefined); } } for (const sourceFile of allSourceFiles) { - if (isExternalOrCommonJsModule(sourceFile)) { + if (ts.isExternalOrCommonJsModule(sourceFile)) { cb(checker.getMergedSymbol(sourceFile.symbol), sourceFile); } } } - export function getExportInfoMap(importingFile: SourceFile, host: LanguageServiceHost, program: Program, cancellationToken: CancellationToken | undefined): ExportInfoMap { - const start = timestamp(); + export function getExportInfoMap(importingFile: ts.SourceFile, host: ts.LanguageServiceHost, program: ts.Program, cancellationToken: ts.CancellationToken | undefined): ExportInfoMap { + const start = ts.timestamp(); // Pulling the AutoImportProvider project will trigger its updateGraph if pending, // which will invalidate the export map cache if things change, so pull it before // checking the cache. @@ -383,34 +369,19 @@ namespace ts { let moduleCount = 0; try { forEachExternalModuleToImportFrom(program, host, /*useAutoImportProvider*/ true, (moduleSymbol, moduleFile, program, isFromPackageJson) => { - if (++moduleCount % 100 === 0) cancellationToken?.throwIfCancellationRequested(); - const seenExports = new Map<__String, true>(); + if (++moduleCount % 100 === 0) + cancellationToken?.throwIfCancellationRequested(); + const seenExports = new ts.Map(); const checker = program.getTypeChecker(); const defaultInfo = getDefaultLikeExportInfo(moduleSymbol, checker, compilerOptions); // Note: I think we shouldn't actually see resolved module symbols here, but weird merges // can cause it to happen: see 'completionsImport_mergedReExport.ts' if (defaultInfo && isImportableSymbol(defaultInfo.symbol, checker)) { - cache.add( - importingFile.path, - defaultInfo.symbol, - defaultInfo.exportKind === ExportKind.Default ? InternalSymbolName.Default : InternalSymbolName.ExportEquals, - moduleSymbol, - moduleFile, - defaultInfo.exportKind, - isFromPackageJson, - checker); + cache.add(importingFile.path, defaultInfo.symbol, defaultInfo.exportKind === ExportKind.Default ? ts.InternalSymbolName.Default : ts.InternalSymbolName.ExportEquals, moduleSymbol, moduleFile, defaultInfo.exportKind, isFromPackageJson, checker); } checker.forEachExportAndPropertyOfModule(moduleSymbol, (exported, key) => { - if (exported !== defaultInfo?.symbol && isImportableSymbol(exported, checker) && addToSeen(seenExports, key)) { - cache.add( - importingFile.path, - exported, - key, - moduleSymbol, - moduleFile, - ExportKind.Named, - isFromPackageJson, - checker); + if (exported !== defaultInfo?.symbol && isImportableSymbol(exported, checker) && ts.addToSeen(seenExports, key)) { + cache.add(importingFile.path, exported, key, moduleSymbol, moduleFile, ExportKind.Named, isFromPackageJson, checker); } }); }); @@ -421,37 +392,46 @@ namespace ts { throw err; } - host.log?.(`getExportInfoMap: done in ${timestamp() - start} ms`); + host.log?.(`getExportInfoMap: done in ${ts.timestamp() - start} ms`); return cache; } - export function getDefaultLikeExportInfo(moduleSymbol: Symbol, checker: TypeChecker, compilerOptions: CompilerOptions) { + export function getDefaultLikeExportInfo(moduleSymbol: ts.Symbol, checker: ts.TypeChecker, compilerOptions: ts.CompilerOptions) { const exported = getDefaultLikeExportWorker(moduleSymbol, checker); - if (!exported) return undefined; + if (!exported) + return undefined; const { symbol, exportKind } = exported; const info = getDefaultExportInfoWorker(symbol, checker, compilerOptions); return info && { symbol, exportKind, ...info }; } - function isImportableSymbol(symbol: Symbol, checker: TypeChecker) { - return !checker.isUndefinedSymbol(symbol) && !checker.isUnknownSymbol(symbol) && !isKnownSymbol(symbol) && !isPrivateIdentifierSymbol(symbol); + function isImportableSymbol(symbol: ts.Symbol, checker: ts.TypeChecker) { + return !checker.isUndefinedSymbol(symbol) && !checker.isUnknownSymbol(symbol) && !ts.isKnownSymbol(symbol) && !ts.isPrivateIdentifierSymbol(symbol); } - function getDefaultLikeExportWorker(moduleSymbol: Symbol, checker: TypeChecker): { readonly symbol: Symbol, readonly exportKind: ExportKind } | undefined { + function getDefaultLikeExportWorker(moduleSymbol: ts.Symbol, checker: ts.TypeChecker): { + readonly symbol: ts.Symbol; + readonly exportKind: ExportKind; + } | undefined { const exportEquals = checker.resolveExternalModuleSymbol(moduleSymbol); - if (exportEquals !== moduleSymbol) return { symbol: exportEquals, exportKind: ExportKind.ExportEquals }; - const defaultExport = checker.tryGetMemberInModuleExports(InternalSymbolName.Default, moduleSymbol); - if (defaultExport) return { symbol: defaultExport, exportKind: ExportKind.Default }; + if (exportEquals !== moduleSymbol) + return { symbol: exportEquals, exportKind: ExportKind.ExportEquals }; + const defaultExport = checker.tryGetMemberInModuleExports(ts.InternalSymbolName.Default, moduleSymbol); + if (defaultExport) + return { symbol: defaultExport, exportKind: ExportKind.Default }; } - - function getDefaultExportInfoWorker(defaultExport: Symbol, checker: TypeChecker, compilerOptions: CompilerOptions): { readonly symbolForMeaning: Symbol, readonly name: string } | undefined { - const localSymbol = getLocalSymbolForExportDefault(defaultExport); - if (localSymbol) return { symbolForMeaning: localSymbol, name: localSymbol.name }; + function getDefaultExportInfoWorker(defaultExport: ts.Symbol, checker: ts.TypeChecker, compilerOptions: ts.CompilerOptions): { + readonly symbolForMeaning: ts.Symbol; + readonly name: string; + } | undefined { + const localSymbol = ts.getLocalSymbolForExportDefault(defaultExport); + if (localSymbol) + return { symbolForMeaning: localSymbol, name: localSymbol.name }; const name = getNameForExportDefault(defaultExport); - if (name !== undefined) return { symbolForMeaning: defaultExport, name }; - - if (defaultExport.flags & SymbolFlags.Alias) { + if (name !== undefined) + return { symbolForMeaning: defaultExport, name }; + if (defaultExport.flags & ts.SymbolFlags.Alias) { const aliased = checker.getImmediateAliasedSymbol(defaultExport); if (aliased && aliased.parent) { // - `aliased` will be undefined if the module is exporting an unresolvable name, @@ -462,20 +442,20 @@ namespace ts { } } - if (defaultExport.escapedName !== InternalSymbolName.Default && - defaultExport.escapedName !== InternalSymbolName.ExportEquals) { + if (defaultExport.escapedName !== ts.InternalSymbolName.Default && + defaultExport.escapedName !== ts.InternalSymbolName.ExportEquals) { return { symbolForMeaning: defaultExport, name: defaultExport.getName() }; } - return { symbolForMeaning: defaultExport, name: getNameForExportedSymbol(defaultExport, compilerOptions.target) }; + return { symbolForMeaning: defaultExport, name: ts.getNameForExportedSymbol(defaultExport, compilerOptions.target) }; } - function getNameForExportDefault(symbol: Symbol): string | undefined { - return symbol.declarations && firstDefined(symbol.declarations, declaration => { - if (isExportAssignment(declaration)) { - return tryCast(skipOuterExpressions(declaration.expression), isIdentifier)?.text; + function getNameForExportDefault(symbol: ts.Symbol): string | undefined { + return symbol.declarations && ts.firstDefined(symbol.declarations, declaration => { + if (ts.isExportAssignment(declaration)) { + return ts.tryCast(ts.skipOuterExpressions(declaration.expression), ts.isIdentifier)?.text; } - else if (isExportSpecifier(declaration)) { - Debug.assert(declaration.name.text === InternalSymbolName.Default, "Expected the specifier to be a default export"); + else if (ts.isExportSpecifier(declaration)) { + ts.Debug.assert(declaration.name.text === ts.InternalSymbolName.Default, "Expected the specifier to be a default export"); return declaration.propertyName && declaration.propertyName.text; } }); diff --git a/src/services/findAllReferences.ts b/src/services/findAllReferences.ts index ba46b5d311f46..9fb0b22d8de6f 100644 --- a/src/services/findAllReferences.ts +++ b/src/services/findAllReferences.ts @@ -5,157 +5,176 @@ namespace ts.FindAllReferences { readonly references: readonly Entry[]; } - export const enum DefinitionKind { Symbol, Label, Keyword, This, String, TripleSlashReference } - export type Definition = - | { readonly type: DefinitionKind.Symbol; readonly symbol: Symbol } - | { readonly type: DefinitionKind.Label; readonly node: Identifier } - | { readonly type: DefinitionKind.Keyword; readonly node: Node } - | { readonly type: DefinitionKind.This; readonly node: Node } - | { readonly type: DefinitionKind.String; readonly node: StringLiteralLike } - | { readonly type: DefinitionKind.TripleSlashReference; readonly reference: FileReference, readonly file: SourceFile }; - - export const enum EntryKind { Span, Node, StringLiteral, SearchedLocalFoundProperty, SearchedPropertyFoundLocal } + export const enum DefinitionKind { + Symbol, + Label, + Keyword, + This, + String, + TripleSlashReference + } + export type Definition = { + readonly type: DefinitionKind.Symbol; + readonly symbol: ts.Symbol; + } | { + readonly type: DefinitionKind.Label; + readonly node: ts.Identifier; + } | { + readonly type: DefinitionKind.Keyword; + readonly node: ts.Node; + } | { + readonly type: DefinitionKind.This; + readonly node: ts.Node; + } | { + readonly type: DefinitionKind.String; + readonly node: ts.StringLiteralLike; + } | { + readonly type: DefinitionKind.TripleSlashReference; + readonly reference: ts.FileReference; + readonly file: ts.SourceFile; + }; + export const enum EntryKind { + Span, + Node, + StringLiteral, + SearchedLocalFoundProperty, + SearchedPropertyFoundLocal + } export type NodeEntryKind = EntryKind.Node | EntryKind.StringLiteral | EntryKind.SearchedLocalFoundProperty | EntryKind.SearchedPropertyFoundLocal; export type Entry = NodeEntry | SpanEntry; export interface ContextWithStartAndEndNode { - start: Node; - end: Node; + start: ts.Node; + end: ts.Node; } - export type ContextNode = Node | ContextWithStartAndEndNode; + export type ContextNode = ts.Node | ContextWithStartAndEndNode; export interface NodeEntry { readonly kind: NodeEntryKind; - readonly node: Node; + readonly node: ts.Node; readonly context?: ContextNode; } export interface SpanEntry { readonly kind: EntryKind.Span; readonly fileName: string; - readonly textSpan: TextSpan; + readonly textSpan: ts.TextSpan; } - export function nodeEntry(node: Node, kind: NodeEntryKind = EntryKind.Node): NodeEntry { + export function nodeEntry(node: ts.Node, kind: NodeEntryKind = EntryKind.Node): NodeEntry { return { kind, - node: (node as NamedDeclaration).name || node, + node: (node as ts.NamedDeclaration).name || node, context: getContextNodeForNodeEntry(node) }; } export function isContextWithStartAndEndNode(node: ContextNode): node is ContextWithStartAndEndNode { - return node && (node as Node).kind === undefined; + return node && (node as ts.Node).kind === undefined; } - function getContextNodeForNodeEntry(node: Node): ContextNode | undefined { - if (isDeclaration(node)) { + function getContextNodeForNodeEntry(node: ts.Node): ContextNode | undefined { + if (ts.isDeclaration(node)) { return getContextNode(node); } - if (!node.parent) return undefined; - - if (!isDeclaration(node.parent) && !isExportAssignment(node.parent)) { + if (!node.parent) + return undefined; + if (!ts.isDeclaration(node.parent) && !ts.isExportAssignment(node.parent)) { // Special property assignment in javascript - if (isInJSFile(node)) { - const binaryExpression = isBinaryExpression(node.parent) ? + if (ts.isInJSFile(node)) { + const binaryExpression = ts.isBinaryExpression(node.parent) ? node.parent : - isAccessExpression(node.parent) && - isBinaryExpression(node.parent.parent) && + ts.isAccessExpression(node.parent) && + ts.isBinaryExpression(node.parent.parent) && node.parent.parent.left === node.parent ? node.parent.parent : undefined; - if (binaryExpression && getAssignmentDeclarationKind(binaryExpression) !== AssignmentDeclarationKind.None) { + if (binaryExpression && ts.getAssignmentDeclarationKind(binaryExpression) !== ts.AssignmentDeclarationKind.None) { return getContextNode(binaryExpression); } } // Jsx Tags - if (isJsxOpeningElement(node.parent) || isJsxClosingElement(node.parent)) { + if (ts.isJsxOpeningElement(node.parent) || ts.isJsxClosingElement(node.parent)) { return node.parent.parent; } - else if (isJsxSelfClosingElement(node.parent) || - isLabeledStatement(node.parent) || - isBreakOrContinueStatement(node.parent)) { + else if (ts.isJsxSelfClosingElement(node.parent) || + ts.isLabeledStatement(node.parent) || + ts.isBreakOrContinueStatement(node.parent)) { return node.parent; } - else if (isStringLiteralLike(node)) { - const validImport = tryGetImportFromModuleSpecifier(node); + else if (ts.isStringLiteralLike(node)) { + const validImport = ts.tryGetImportFromModuleSpecifier(node); if (validImport) { - const declOrStatement = findAncestor(validImport, node => - isDeclaration(node) || - isStatement(node) || - isJSDocTag(node) - )! as NamedDeclaration | Statement | JSDocTag; - return isDeclaration(declOrStatement) ? + const declOrStatement = ts.findAncestor(validImport, node => ts.isDeclaration(node) || + ts.isStatement(node) || + ts.isJSDocTag(node))! as ts.NamedDeclaration | ts.Statement | ts.JSDocTag; + return ts.isDeclaration(declOrStatement) ? getContextNode(declOrStatement) : declOrStatement; } } // Handle computed property name - const propertyName = findAncestor(node, isComputedPropertyName); + const propertyName = ts.findAncestor(node, ts.isComputedPropertyName); return propertyName ? getContextNode(propertyName.parent) : undefined; } if (node.parent.name === node || // node is name of declaration, use parent - isConstructorDeclaration(node.parent) || - isExportAssignment(node.parent) || + ts.isConstructorDeclaration(node.parent) || + ts.isExportAssignment(node.parent) || // Property name of the import export specifier or binding pattern, use parent - ((isImportOrExportSpecifier(node.parent) || isBindingElement(node.parent)) + ((ts.isImportOrExportSpecifier(node.parent) || ts.isBindingElement(node.parent)) && node.parent.propertyName === node) || // Is default export - (node.kind === SyntaxKind.DefaultKeyword && hasSyntacticModifier(node.parent, ModifierFlags.ExportDefault))) { + (node.kind === ts.SyntaxKind.DefaultKeyword && ts.hasSyntacticModifier(node.parent, ts.ModifierFlags.ExportDefault))) { return getContextNode(node.parent); } return undefined; } - export function getContextNode(node: NamedDeclaration | BinaryExpression | ForInOrOfStatement | undefined): ContextNode | undefined { - if (!node) return undefined; + export function getContextNode(node: ts.NamedDeclaration | ts.BinaryExpression | ts.ForInOrOfStatement | undefined): ContextNode | undefined { + if (!node) + return undefined; switch (node.kind) { - case SyntaxKind.VariableDeclaration: - return !isVariableDeclarationList(node.parent) || node.parent.declarations.length !== 1 ? + case ts.SyntaxKind.VariableDeclaration: + return !ts.isVariableDeclarationList(node.parent) || node.parent.declarations.length !== 1 ? node : - isVariableStatement(node.parent.parent) ? + ts.isVariableStatement(node.parent.parent) ? node.parent.parent : - isForInOrOfStatement(node.parent.parent) ? + ts.isForInOrOfStatement(node.parent.parent) ? getContextNode(node.parent.parent) : node.parent; - case SyntaxKind.BindingElement: - return getContextNode(node.parent.parent as NamedDeclaration); - - case SyntaxKind.ImportSpecifier: + case ts.SyntaxKind.BindingElement: + return getContextNode(node.parent.parent as ts.NamedDeclaration); + case ts.SyntaxKind.ImportSpecifier: return node.parent.parent.parent; - case SyntaxKind.ExportSpecifier: - case SyntaxKind.NamespaceImport: + case ts.SyntaxKind.ExportSpecifier: + case ts.SyntaxKind.NamespaceImport: return node.parent.parent; - case SyntaxKind.ImportClause: - case SyntaxKind.NamespaceExport: + case ts.SyntaxKind.ImportClause: + case ts.SyntaxKind.NamespaceExport: return node.parent; - case SyntaxKind.BinaryExpression: - return isExpressionStatement(node.parent) ? + case ts.SyntaxKind.BinaryExpression: + return ts.isExpressionStatement(node.parent) ? node.parent : node; - case SyntaxKind.ForOfStatement: - case SyntaxKind.ForInStatement: + case ts.SyntaxKind.ForOfStatement: + case ts.SyntaxKind.ForInStatement: return { - start: (node as ForInOrOfStatement).initializer, - end: (node as ForInOrOfStatement).expression + start: (node as ts.ForInOrOfStatement).initializer, + end: (node as ts.ForInOrOfStatement).expression }; - case SyntaxKind.PropertyAssignment: - case SyntaxKind.ShorthandPropertyAssignment: - return isArrayLiteralOrObjectLiteralDestructuringPattern(node.parent) ? - getContextNode( - findAncestor(node.parent, node => - isBinaryExpression(node) || isForInOrOfStatement(node) - ) as BinaryExpression | ForInOrOfStatement - ) : + case ts.SyntaxKind.PropertyAssignment: + case ts.SyntaxKind.ShorthandPropertyAssignment: + return ts.isArrayLiteralOrObjectLiteralDestructuringPattern(node.parent) ? + getContextNode(ts.findAncestor(node.parent, node => ts.isBinaryExpression(node) || ts.isForInOrOfStatement(node)) as ts.BinaryExpression | ts.ForInOrOfStatement) : node; default: @@ -163,8 +182,11 @@ namespace ts.FindAllReferences { } } - export function toContextSpan(textSpan: TextSpan, sourceFile: SourceFile, context?: ContextNode): { contextSpan: TextSpan } | undefined { - if (!context) return undefined; + export function toContextSpan(textSpan: ts.TextSpan, sourceFile: ts.SourceFile, context?: ContextNode): { + contextSpan: ts.TextSpan; + } | undefined { + if (!context) + return undefined; const contextSpan = isContextWithStartAndEndNode(context) ? getTextSpan(context.start, sourceFile, context.end) : getTextSpan(context, sourceFile); @@ -187,7 +209,7 @@ namespace ts.FindAllReferences { * Unlike `References`, the location will only be adjusted keyword belonged to a declaration with a valid name. * If set, we will find fewer references -- if it is referenced by several different names, we still only find references for the original name. */ - Rename, + Rename } export interface Options { @@ -204,15 +226,15 @@ namespace ts.FindAllReferences { readonly providePrefixAndSuffixTextForRename?: boolean; } - export function findReferencedSymbols(program: Program, cancellationToken: CancellationToken, sourceFiles: readonly SourceFile[], sourceFile: SourceFile, position: number): ReferencedSymbol[] | undefined { - const node = getTouchingPropertyName(sourceFile, position); + export function findReferencedSymbols(program: ts.Program, cancellationToken: ts.CancellationToken, sourceFiles: readonly ts.SourceFile[], sourceFile: ts.SourceFile, position: number): ts.ReferencedSymbol[] | undefined { + const node = ts.getTouchingPropertyName(sourceFile, position); const options = { use: FindReferencesUse.References }; const referencedSymbols = Core.getReferencedSymbolsForNode(position, node, program, sourceFiles, cancellationToken, options); const checker = program.getTypeChecker(); // Unless the starting node is a declaration (vs e.g. JSDoc), don't attempt to compute isDefinition const adjustedNode = Core.getAdjustedNode(node, options); const symbol = isDefinitionForReference(adjustedNode) ? checker.getSymbolAtLocation(adjustedNode) : undefined; - return !referencedSymbols || !referencedSymbols.length ? undefined : mapDefined(referencedSymbols, ({ definition, references }) => + return !referencedSymbols || !referencedSymbols.length ? undefined : ts.mapDefined(referencedSymbols, ({ definition, references }) => // Only include referenced symbols that have a valid definition. definition && { definition: checker.runWithCancellationToken(cancellationToken, checker => definitionToReferencedSymbolDefinitionInfo(definition, checker, node)), @@ -220,35 +242,33 @@ namespace ts.FindAllReferences { }); } - function isDefinitionForReference(node: Node): boolean { - return node.kind === SyntaxKind.DefaultKeyword - || !!getDeclarationFromName(node) - || isLiteralComputedPropertyDeclarationName(node) - || (node.kind === SyntaxKind.ConstructorKeyword && isConstructorDeclaration(node.parent)); + function isDefinitionForReference(node: ts.Node): boolean { + return node.kind === ts.SyntaxKind.DefaultKeyword + || !!ts.getDeclarationFromName(node) + || ts.isLiteralComputedPropertyDeclarationName(node) + || (node.kind === ts.SyntaxKind.ConstructorKeyword && ts.isConstructorDeclaration(node.parent)); } - export function getImplementationsAtPosition(program: Program, cancellationToken: CancellationToken, sourceFiles: readonly SourceFile[], sourceFile: SourceFile, position: number): ImplementationLocation[] | undefined { - const node = getTouchingPropertyName(sourceFile, position); + export function getImplementationsAtPosition(program: ts.Program, cancellationToken: ts.CancellationToken, sourceFiles: readonly ts.SourceFile[], sourceFile: ts.SourceFile, position: number): ts.ImplementationLocation[] | undefined { + const node = ts.getTouchingPropertyName(sourceFile, position); let referenceEntries: Entry[] | undefined; const entries = getImplementationReferenceEntries(program, cancellationToken, sourceFiles, node, position); - if ( - node.parent.kind === SyntaxKind.PropertyAccessExpression - || node.parent.kind === SyntaxKind.BindingElement - || node.parent.kind === SyntaxKind.ElementAccessExpression - || node.kind === SyntaxKind.SuperKeyword - ) { + if (node.parent.kind === ts.SyntaxKind.PropertyAccessExpression + || node.parent.kind === ts.SyntaxKind.BindingElement + || node.parent.kind === ts.SyntaxKind.ElementAccessExpression + || node.kind === ts.SyntaxKind.SuperKeyword) { referenceEntries = entries && [...entries]; } else { const queue = entries && [...entries]; - const seenNodes = new Map(); + const seenNodes = new ts.Map(); while (queue && queue.length) { const entry = queue.shift() as NodeEntry; - if (!addToSeen(seenNodes, getNodeId(entry.node))) { + if (!ts.addToSeen(seenNodes, ts.getNodeId(entry.node))) { continue; } - referenceEntries = append(referenceEntries, entry); + referenceEntries = ts.append(referenceEntries, entry); const entries = getImplementationReferenceEntries(program, cancellationToken, sourceFiles, entry.node, entry.node.pos); if (entries) { queue.push(...entries); @@ -256,23 +276,23 @@ namespace ts.FindAllReferences { } } const checker = program.getTypeChecker(); - return map(referenceEntries, entry => toImplementationLocation(entry, checker)); + return ts.map(referenceEntries, entry => toImplementationLocation(entry, checker)); } - function getImplementationReferenceEntries(program: Program, cancellationToken: CancellationToken, sourceFiles: readonly SourceFile[], node: Node, position: number): readonly Entry[] | undefined { - if (node.kind === SyntaxKind.SourceFile) { + function getImplementationReferenceEntries(program: ts.Program, cancellationToken: ts.CancellationToken, sourceFiles: readonly ts.SourceFile[], node: ts.Node, position: number): readonly Entry[] | undefined { + if (node.kind === ts.SyntaxKind.SourceFile) { return undefined; } const checker = program.getTypeChecker(); // If invoked directly on a shorthand property assignment, then return // the declaration of the symbol being assigned (not the symbol being assigned to). - if (node.parent.kind === SyntaxKind.ShorthandPropertyAssignment) { + if (node.parent.kind === ts.SyntaxKind.ShorthandPropertyAssignment) { const result: NodeEntry[] = []; Core.getReferenceEntriesForShorthandPropertyAssignment(node, checker, node => result.push(nodeEntry(node))); return result; } - else if (node.kind === SyntaxKind.SuperKeyword || isSuperProperty(node.parent)) { + else if (node.kind === ts.SyntaxKind.SuperKeyword || ts.isSuperProperty(node.parent)) { // References to and accesses on the super keyword only have one possible implementation, so no // need to "Find all References" const symbol = checker.getSymbolAtLocation(node)!; @@ -284,40 +304,33 @@ namespace ts.FindAllReferences { } } - export function findReferenceOrRenameEntries( - program: Program, cancellationToken: CancellationToken, sourceFiles: readonly SourceFile[], node: Node, position: number, options: Options | undefined, - convertEntry: ToReferenceOrRenameEntry, - ): T[] | undefined { - return map(flattenEntries(Core.getReferencedSymbolsForNode(position, node, program, sourceFiles, cancellationToken, options)), entry => convertEntry(entry, node, program.getTypeChecker())); + export function findReferenceOrRenameEntries(program: ts.Program, cancellationToken: ts.CancellationToken, sourceFiles: readonly ts.SourceFile[], node: ts.Node, position: number, options: Options | undefined, convertEntry: ToReferenceOrRenameEntry): T[] | undefined { + return ts.map(flattenEntries(Core.getReferencedSymbolsForNode(position, node, program, sourceFiles, cancellationToken, options)), entry => convertEntry(entry, node, program.getTypeChecker())); } - - export type ToReferenceOrRenameEntry = (entry: Entry, originalNode: Node, checker: TypeChecker) => T; - - export function getReferenceEntriesForNode( - position: number, - node: Node, - program: Program, - sourceFiles: readonly SourceFile[], - cancellationToken: CancellationToken, - options: Options = {}, - sourceFilesSet: ReadonlySet = new Set(sourceFiles.map(f => f.fileName)), - ): readonly Entry[] | undefined { + export type ToReferenceOrRenameEntry = (entry: Entry, originalNode: ts.Node, checker: ts.TypeChecker) => T; + export function getReferenceEntriesForNode(position: number, node: ts.Node, program: ts.Program, sourceFiles: readonly ts.SourceFile[], cancellationToken: ts.CancellationToken, options: Options = {}, sourceFilesSet: ts.ReadonlySet = new ts.Set(sourceFiles.map(f => f.fileName))): readonly Entry[] | undefined { return flattenEntries(Core.getReferencedSymbolsForNode(position, node, program, sourceFiles, cancellationToken, options, sourceFilesSet)); } function flattenEntries(referenceSymbols: readonly SymbolAndEntries[] | undefined): readonly Entry[] | undefined { - return referenceSymbols && flatMap(referenceSymbols, r => r.references); + return referenceSymbols && ts.flatMap(referenceSymbols, r => r.references); } - - function definitionToReferencedSymbolDefinitionInfo(def: Definition, checker: TypeChecker, originalNode: Node): ReferencedSymbolDefinitionInfo { - const info = ((): { sourceFile: SourceFile, textSpan: TextSpan, name: string, kind: ScriptElementKind, displayParts: SymbolDisplayPart[], context?: Node | ContextWithStartAndEndNode } => { + function definitionToReferencedSymbolDefinitionInfo(def: Definition, checker: ts.TypeChecker, originalNode: ts.Node): ts.ReferencedSymbolDefinitionInfo { + const info = ((): { + sourceFile: ts.SourceFile; + textSpan: ts.TextSpan; + name: string; + kind: ts.ScriptElementKind; + displayParts: ts.SymbolDisplayPart[]; + context?: ts.Node | ContextWithStartAndEndNode; + } => { switch (def.type) { case DefinitionKind.Symbol: { const { symbol } = def; const { displayParts, kind } = getDefinitionKindAndDisplayParts(symbol, checker, originalNode); const name = displayParts.map(p => p.text).join(""); - const declaration = symbol.declarations && firstOrUndefined(symbol.declarations); - const node = declaration ? (getNameOfDeclaration(declaration) || declaration) : originalNode; + const declaration = symbol.declarations && ts.firstOrUndefined(symbol.declarations); + const node = declaration ? (ts.getNameOfDeclaration(declaration) || declaration) : originalNode; return { ...getFileAndTextSpanFromNode(node), name, @@ -328,46 +341,45 @@ namespace ts.FindAllReferences { } case DefinitionKind.Label: { const { node } = def; - return { ...getFileAndTextSpanFromNode(node), name: node.text, kind: ScriptElementKind.label, displayParts: [displayPart(node.text, SymbolDisplayPartKind.text)] }; + return { ...getFileAndTextSpanFromNode(node), name: node.text, kind: ts.ScriptElementKind.label, displayParts: [ts.displayPart(node.text, ts.SymbolDisplayPartKind.text)] }; } case DefinitionKind.Keyword: { const { node } = def; - const name = tokenToString(node.kind)!; - return { ...getFileAndTextSpanFromNode(node), name, kind: ScriptElementKind.keyword, displayParts: [{ text: name, kind: ScriptElementKind.keyword }] }; + const name = ts.tokenToString(node.kind)!; + return { ...getFileAndTextSpanFromNode(node), name, kind: ts.ScriptElementKind.keyword, displayParts: [{ text: name, kind: ts.ScriptElementKind.keyword }] }; } case DefinitionKind.This: { const { node } = def; const symbol = checker.getSymbolAtLocation(node); - const displayParts = symbol && SymbolDisplay.getSymbolDisplayPartsDocumentationAndSymbolKind( - checker, symbol, node.getSourceFile(), getContainerNode(node), node).displayParts || [textPart("this")]; - return { ...getFileAndTextSpanFromNode(node), name: "this", kind: ScriptElementKind.variableElement, displayParts }; + const displayParts = symbol && ts.SymbolDisplay.getSymbolDisplayPartsDocumentationAndSymbolKind(checker, symbol, node.getSourceFile(), ts.getContainerNode(node), node).displayParts || [ts.textPart("this")]; + return { ...getFileAndTextSpanFromNode(node), name: "this", kind: ts.ScriptElementKind.variableElement, displayParts }; } case DefinitionKind.String: { const { node } = def; return { ...getFileAndTextSpanFromNode(node), name: node.text, - kind: ScriptElementKind.variableElement, - displayParts: [displayPart(getTextOfNode(node), SymbolDisplayPartKind.stringLiteral)] + kind: ts.ScriptElementKind.variableElement, + displayParts: [ts.displayPart(ts.getTextOfNode(node), ts.SymbolDisplayPartKind.stringLiteral)] }; } case DefinitionKind.TripleSlashReference: { return { - textSpan: createTextSpanFromRange(def.reference), + textSpan: ts.createTextSpanFromRange(def.reference), sourceFile: def.file, name: def.reference.fileName, - kind: ScriptElementKind.string, - displayParts: [displayPart(`"${def.reference.fileName}"`, SymbolDisplayPartKind.stringLiteral)] + kind: ts.ScriptElementKind.string, + displayParts: [ts.displayPart(`"${def.reference.fileName}"`, ts.SymbolDisplayPartKind.stringLiteral)] }; } default: - return Debug.assertNever(def); + return ts.Debug.assertNever(def); } })(); const { sourceFile, textSpan, name, kind, displayParts, context } = info; return { - containerKind: ScriptElementKind.unknown, + containerKind: ts.ScriptElementKind.unknown, containerName: "", fileName: sourceFile.fileName, kind, @@ -378,36 +390,39 @@ namespace ts.FindAllReferences { }; } - function getFileAndTextSpanFromNode(node: Node) { + function getFileAndTextSpanFromNode(node: ts.Node) { const sourceFile = node.getSourceFile(); return { sourceFile, - textSpan: getTextSpan(isComputedPropertyName(node) ? node.expression : node, sourceFile) + textSpan: getTextSpan(ts.isComputedPropertyName(node) ? node.expression : node, sourceFile) }; } - function getDefinitionKindAndDisplayParts(symbol: Symbol, checker: TypeChecker, node: Node): { displayParts: SymbolDisplayPart[], kind: ScriptElementKind } { + function getDefinitionKindAndDisplayParts(symbol: ts.Symbol, checker: ts.TypeChecker, node: ts.Node): { + displayParts: ts.SymbolDisplayPart[]; + kind: ts.ScriptElementKind; + } { const meaning = Core.getIntersectingMeaningFromDeclarations(node, symbol); - const enclosingDeclaration = symbol.declarations && firstOrUndefined(symbol.declarations) || node; - const { displayParts, symbolKind } = - SymbolDisplay.getSymbolDisplayPartsDocumentationAndSymbolKind(checker, symbol, enclosingDeclaration.getSourceFile(), enclosingDeclaration, enclosingDeclaration, meaning); + const enclosingDeclaration = symbol.declarations && ts.firstOrUndefined(symbol.declarations) || node; + const { displayParts, symbolKind } = ts.SymbolDisplay.getSymbolDisplayPartsDocumentationAndSymbolKind(checker, symbol, enclosingDeclaration.getSourceFile(), enclosingDeclaration, enclosingDeclaration, meaning); return { displayParts, kind: symbolKind }; } - export function toRenameLocation(entry: Entry, originalNode: Node, checker: TypeChecker, providePrefixAndSuffixText: boolean): RenameLocation { + export function toRenameLocation(entry: Entry, originalNode: ts.Node, checker: ts.TypeChecker, providePrefixAndSuffixText: boolean): ts.RenameLocation { return { ...entryToDocumentSpan(entry), ...(providePrefixAndSuffixText && getPrefixAndSuffixText(entry, originalNode, checker)) }; } - function toReferencedSymbolEntry(entry: Entry, symbol: Symbol | undefined): ReferencedSymbolEntry { + function toReferencedSymbolEntry(entry: Entry, symbol: ts.Symbol | undefined): ts.ReferencedSymbolEntry { const referenceEntry = toReferenceEntry(entry); - if (!symbol) return referenceEntry; + if (!symbol) + return referenceEntry; return { ...referenceEntry, isDefinition: entry.kind !== EntryKind.Span && isDeclarationOfSymbol(entry.node, symbol) }; } - export function toReferenceEntry(entry: Entry): ReferenceEntry { + export function toReferenceEntry(entry: Entry): ts.ReferenceEntry { const documentSpan = entryToDocumentSpan(entry); if (entry.kind === EntryKind.Span) { return { ...documentSpan, isWriteAccess: false }; @@ -420,7 +435,7 @@ namespace ts.FindAllReferences { }; } - function entryToDocumentSpan(entry: Entry): DocumentSpan { + function entryToDocumentSpan(entry: Entry): ts.DocumentSpan { if (entry.kind === EntryKind.Span) { return { textSpan: entry.textSpan, fileName: entry.fileName }; } @@ -435,14 +450,17 @@ namespace ts.FindAllReferences { } } - interface PrefixAndSuffix { readonly prefixText?: string; readonly suffixText?: string; } - function getPrefixAndSuffixText(entry: Entry, originalNode: Node, checker: TypeChecker): PrefixAndSuffix { - if (entry.kind !== EntryKind.Span && isIdentifier(originalNode)) { + interface PrefixAndSuffix { + readonly prefixText?: string; + readonly suffixText?: string; + } + function getPrefixAndSuffixText(entry: Entry, originalNode: ts.Node, checker: ts.TypeChecker): PrefixAndSuffix { + if (entry.kind !== EntryKind.Span && ts.isIdentifier(originalNode)) { const { node, kind } = entry; const parent = node.parent; const name = originalNode.text; - const isShorthandAssignment = isShorthandPropertyAssignment(parent); - if (isShorthandAssignment || (isObjectBindingElementWithoutPropertyName(parent) && parent.name === node && parent.dotDotDotToken === undefined)) { + const isShorthandAssignment = ts.isShorthandPropertyAssignment(parent); + if (isShorthandAssignment || (ts.isObjectBindingElementWithoutPropertyName(parent) && parent.name === node && parent.dotDotDotToken === undefined)) { const prefixColon: PrefixAndSuffix = { prefixText: name + ": " }; const suffixColon: PrefixAndSuffix = { suffixText: ": " + name }; if (kind === EntryKind.SearchedLocalFoundProperty) { @@ -456,9 +474,9 @@ namespace ts.FindAllReferences { // For a binding element `const { x } = o;`, symbolAtLocation at `x` is the property symbol. if (isShorthandAssignment) { const grandParent = parent.parent; - if (isObjectLiteralExpression(grandParent) && - isBinaryExpression(grandParent.parent) && - isModuleExportsAccessExpression(grandParent.parent.left)) { + if (ts.isObjectLiteralExpression(grandParent) && + ts.isBinaryExpression(grandParent.parent) && + ts.isModuleExportsAccessExpression(grandParent.parent.left)) { return prefixColon; } return suffixColon; @@ -467,12 +485,12 @@ namespace ts.FindAllReferences { return prefixColon; } } - else if (isImportSpecifier(parent) && !parent.propertyName) { + else if (ts.isImportSpecifier(parent) && !parent.propertyName) { // If the original symbol was using this alias, just rename the alias. - const originalSymbol = isExportSpecifier(originalNode.parent) ? checker.getExportSpecifierLocalTargetSymbol(originalNode.parent) : checker.getSymbolAtLocation(originalNode); - return contains(originalSymbol!.declarations, parent) ? { prefixText: name + " as " } : emptyOptions; + const originalSymbol = ts.isExportSpecifier(originalNode.parent) ? checker.getExportSpecifierLocalTargetSymbol(originalNode.parent) : checker.getSymbolAtLocation(originalNode); + return ts.contains(originalSymbol!.declarations, parent) ? { prefixText: name + " as " } : ts.emptyOptions; } - else if (isExportSpecifier(parent) && !parent.propertyName) { + else if (ts.isExportSpecifier(parent) && !parent.propertyName) { // If the symbol for the node is same as declared node symbol use prefix text return originalNode === entry.node || checker.getSymbolAtLocation(originalNode) === checker.getSymbolAtLocation(entry.node) ? { prefixText: name + " as " } : @@ -480,10 +498,10 @@ namespace ts.FindAllReferences { } } - return emptyOptions; + return ts.emptyOptions; } - function toImplementationLocation(entry: Entry, checker: TypeChecker): ImplementationLocation { + function toImplementationLocation(entry: Entry, checker: ts.TypeChecker): ts.ImplementationLocation { const documentSpan = entryToDocumentSpan(entry); if (entry.kind !== EntryKind.Span) { const { node } = entry; @@ -493,63 +511,69 @@ namespace ts.FindAllReferences { }; } else { - return { ...documentSpan, kind: ScriptElementKind.unknown, displayParts: [] }; + return { ...documentSpan, kind: ts.ScriptElementKind.unknown, displayParts: [] }; } } - function implementationKindDisplayParts(node: Node, checker: TypeChecker): { kind: ScriptElementKind, displayParts: SymbolDisplayPart[] } { - const symbol = checker.getSymbolAtLocation(isDeclaration(node) && node.name ? node.name : node); + function implementationKindDisplayParts(node: ts.Node, checker: ts.TypeChecker): { + kind: ts.ScriptElementKind; + displayParts: ts.SymbolDisplayPart[]; + } { + const symbol = checker.getSymbolAtLocation(ts.isDeclaration(node) && node.name ? node.name : node); if (symbol) { return getDefinitionKindAndDisplayParts(symbol, checker, node); } - else if (node.kind === SyntaxKind.ObjectLiteralExpression) { + else if (node.kind === ts.SyntaxKind.ObjectLiteralExpression) { return { - kind: ScriptElementKind.interfaceElement, - displayParts: [punctuationPart(SyntaxKind.OpenParenToken), textPart("object literal"), punctuationPart(SyntaxKind.CloseParenToken)] + kind: ts.ScriptElementKind.interfaceElement, + displayParts: [ts.punctuationPart(ts.SyntaxKind.OpenParenToken), ts.textPart("object literal"), ts.punctuationPart(ts.SyntaxKind.CloseParenToken)] }; } - else if (node.kind === SyntaxKind.ClassExpression) { + else if (node.kind === ts.SyntaxKind.ClassExpression) { return { - kind: ScriptElementKind.localClassElement, - displayParts: [punctuationPart(SyntaxKind.OpenParenToken), textPart("anonymous local class"), punctuationPart(SyntaxKind.CloseParenToken)] + kind: ts.ScriptElementKind.localClassElement, + displayParts: [ts.punctuationPart(ts.SyntaxKind.OpenParenToken), ts.textPart("anonymous local class"), ts.punctuationPart(ts.SyntaxKind.CloseParenToken)] }; } else { - return { kind: getNodeKind(node), displayParts: [] }; + return { kind: ts.getNodeKind(node), displayParts: [] }; } } - export function toHighlightSpan(entry: Entry): { fileName: string, span: HighlightSpan } { + export function toHighlightSpan(entry: Entry): { + fileName: string; + span: ts.HighlightSpan; + } { const documentSpan = entryToDocumentSpan(entry); if (entry.kind === EntryKind.Span) { return { fileName: documentSpan.fileName, span: { textSpan: documentSpan.textSpan, - kind: HighlightSpanKind.reference + kind: ts.HighlightSpanKind.reference } }; } const writeAccess = isWriteAccessForReference(entry.node); - const span: HighlightSpan = { + const span: ts.HighlightSpan = { textSpan: documentSpan.textSpan, - kind: writeAccess ? HighlightSpanKind.writtenReference : HighlightSpanKind.reference, + kind: writeAccess ? ts.HighlightSpanKind.writtenReference : ts.HighlightSpanKind.reference, isInString: entry.kind === EntryKind.StringLiteral ? true : undefined, ...documentSpan.contextSpan && { contextSpan: documentSpan.contextSpan } }; return { fileName: documentSpan.fileName, span }; } - function getTextSpan(node: Node, sourceFile: SourceFile, endNode?: Node): TextSpan { + function getTextSpan(node: ts.Node, sourceFile: ts.SourceFile, endNode?: ts.Node): ts.TextSpan { let start = node.getStart(sourceFile); let end = (endNode || node).getEnd(); - if (isStringLiteralLike(node) && (end - start) > 2) { - Debug.assert(endNode === undefined); + if (ts.isStringLiteralLike(node) && (end - start) > 2) { + ts.Debug.assert(endNode === undefined); start += 1; end -= 1; } - return createTextSpanFromBounds(start, end); + return ts.createTextSpanFromBounds(start, end); } export function getTextSpanOfEntry(entry: Entry) { @@ -558,20 +582,21 @@ namespace ts.FindAllReferences { } /** A node is considered a writeAccess iff it is a name of a declaration or a target of an assignment */ - function isWriteAccessForReference(node: Node): boolean { - const decl = getDeclarationFromName(node); - return !!decl && declarationIsWriteAccess(decl) || node.kind === SyntaxKind.DefaultKeyword || isWriteAccess(node); + function isWriteAccessForReference(node: ts.Node): boolean { + const decl = ts.getDeclarationFromName(node); + return !!decl && declarationIsWriteAccess(decl) || node.kind === ts.SyntaxKind.DefaultKeyword || ts.isWriteAccess(node); } /** Whether a reference, `node`, is a definition of the `target` symbol */ - function isDeclarationOfSymbol(node: Node, target: Symbol | undefined): boolean { - if (!target) return false; - const source = getDeclarationFromName(node) || - (node.kind === SyntaxKind.DefaultKeyword ? node.parent - : isLiteralComputedPropertyDeclarationName(node) ? node.parent.parent - : node.kind === SyntaxKind.ConstructorKeyword && isConstructorDeclaration(node.parent) ? node.parent.parent + function isDeclarationOfSymbol(node: ts.Node, target: ts.Symbol | undefined): boolean { + if (!target) + return false; + const source = ts.getDeclarationFromName(node) || + (node.kind === ts.SyntaxKind.DefaultKeyword ? node.parent + : ts.isLiteralComputedPropertyDeclarationName(node) ? node.parent.parent + : node.kind === ts.SyntaxKind.ConstructorKeyword && ts.isConstructorDeclaration(node.parent) ? node.parent.parent : undefined); - const commonjsSource = source && isBinaryExpression(source) ? source.left as unknown as Declaration : undefined; + const commonjsSource = source && ts.isBinaryExpression(source) ? source.left as unknown as ts.Declaration : undefined; return !!(source && target.declarations?.some(d => d === source || d === commonjsSource)); } @@ -579,70 +604,68 @@ namespace ts.FindAllReferences { * True if 'decl' provides a value, as in `function f() {}`; * false if 'decl' is just a location for a future write, as in 'let x;' */ - function declarationIsWriteAccess(decl: Declaration): boolean { + function declarationIsWriteAccess(decl: ts.Declaration): boolean { // Consider anything in an ambient declaration to be a write access since it may be coming from JS. - if (!!(decl.flags & NodeFlags.Ambient)) return true; + if (!!(decl.flags & ts.NodeFlags.Ambient)) + return true; switch (decl.kind) { - case SyntaxKind.BinaryExpression: - case SyntaxKind.BindingElement: - case SyntaxKind.ClassDeclaration: - case SyntaxKind.ClassExpression: - case SyntaxKind.DefaultKeyword: - case SyntaxKind.EnumDeclaration: - case SyntaxKind.EnumMember: - case SyntaxKind.ExportSpecifier: - case SyntaxKind.ImportClause: // default import - case SyntaxKind.ImportEqualsDeclaration: - case SyntaxKind.ImportSpecifier: - case SyntaxKind.InterfaceDeclaration: - case SyntaxKind.JSDocCallbackTag: - case SyntaxKind.JSDocTypedefTag: - case SyntaxKind.JsxAttribute: - case SyntaxKind.ModuleDeclaration: - case SyntaxKind.NamespaceExportDeclaration: - case SyntaxKind.NamespaceImport: - case SyntaxKind.NamespaceExport: - case SyntaxKind.Parameter: - case SyntaxKind.ShorthandPropertyAssignment: - case SyntaxKind.TypeAliasDeclaration: - case SyntaxKind.TypeParameter: + case ts.SyntaxKind.BinaryExpression: + case ts.SyntaxKind.BindingElement: + case ts.SyntaxKind.ClassDeclaration: + case ts.SyntaxKind.ClassExpression: + case ts.SyntaxKind.DefaultKeyword: + case ts.SyntaxKind.EnumDeclaration: + case ts.SyntaxKind.EnumMember: + case ts.SyntaxKind.ExportSpecifier: + case ts.SyntaxKind.ImportClause: // default import + case ts.SyntaxKind.ImportEqualsDeclaration: + case ts.SyntaxKind.ImportSpecifier: + case ts.SyntaxKind.InterfaceDeclaration: + case ts.SyntaxKind.JSDocCallbackTag: + case ts.SyntaxKind.JSDocTypedefTag: + case ts.SyntaxKind.JsxAttribute: + case ts.SyntaxKind.ModuleDeclaration: + case ts.SyntaxKind.NamespaceExportDeclaration: + case ts.SyntaxKind.NamespaceImport: + case ts.SyntaxKind.NamespaceExport: + case ts.SyntaxKind.Parameter: + case ts.SyntaxKind.ShorthandPropertyAssignment: + case ts.SyntaxKind.TypeAliasDeclaration: + case ts.SyntaxKind.TypeParameter: return true; - case SyntaxKind.PropertyAssignment: + case ts.SyntaxKind.PropertyAssignment: // In `({ x: y } = 0);`, `x` is not a write access. (Won't call this function for `y`.) - return !isArrayLiteralOrObjectLiteralDestructuringPattern((decl as PropertyAssignment).parent); - - case SyntaxKind.FunctionDeclaration: - case SyntaxKind.FunctionExpression: - case SyntaxKind.Constructor: - case SyntaxKind.MethodDeclaration: - case SyntaxKind.GetAccessor: - case SyntaxKind.SetAccessor: - return !!(decl as FunctionDeclaration | FunctionExpression | ConstructorDeclaration | MethodDeclaration | GetAccessorDeclaration | SetAccessorDeclaration).body; - - case SyntaxKind.VariableDeclaration: - case SyntaxKind.PropertyDeclaration: - return !!(decl as VariableDeclaration | PropertyDeclaration).initializer || isCatchClause(decl.parent); - - case SyntaxKind.MethodSignature: - case SyntaxKind.PropertySignature: - case SyntaxKind.JSDocPropertyTag: - case SyntaxKind.JSDocParameterTag: + return !ts.isArrayLiteralOrObjectLiteralDestructuringPattern((decl as ts.PropertyAssignment).parent); + case ts.SyntaxKind.FunctionDeclaration: + case ts.SyntaxKind.FunctionExpression: + case ts.SyntaxKind.Constructor: + case ts.SyntaxKind.MethodDeclaration: + case ts.SyntaxKind.GetAccessor: + case ts.SyntaxKind.SetAccessor: + return !!(decl as ts.FunctionDeclaration | ts.FunctionExpression | ts.ConstructorDeclaration | ts.MethodDeclaration | ts.GetAccessorDeclaration | ts.SetAccessorDeclaration).body; + case ts.SyntaxKind.VariableDeclaration: + case ts.SyntaxKind.PropertyDeclaration: + return !!(decl as ts.VariableDeclaration | ts.PropertyDeclaration).initializer || ts.isCatchClause(decl.parent); + case ts.SyntaxKind.MethodSignature: + case ts.SyntaxKind.PropertySignature: + case ts.SyntaxKind.JSDocPropertyTag: + case ts.SyntaxKind.JSDocParameterTag: return false; default: - return Debug.failBadSyntaxKind(decl); + return ts.Debug.failBadSyntaxKind(decl); } } /** Encapsulates the core find-all-references algorithm. */ export namespace Core { /** Core find-all-references algorithm. Handles special cases before delegating to `getReferencedSymbolsForSymbol`. */ - export function getReferencedSymbolsForNode(position: number, node: Node, program: Program, sourceFiles: readonly SourceFile[], cancellationToken: CancellationToken, options: Options = {}, sourceFilesSet: ReadonlySet = new Set(sourceFiles.map(f => f.fileName))): readonly SymbolAndEntries[] | undefined { + export function getReferencedSymbolsForNode(position: number, node: ts.Node, program: ts.Program, sourceFiles: readonly ts.SourceFile[], cancellationToken: ts.CancellationToken, options: Options = {}, sourceFilesSet: ts.ReadonlySet = new ts.Set(sourceFiles.map(f => f.fileName))): readonly SymbolAndEntries[] | undefined { node = getAdjustedNode(node, options); - if (isSourceFile(node)) { - const resolvedRef = GoToDefinition.getReferenceAtPosition(node, position, program); + if (ts.isSourceFile(node)) { + const resolvedRef = ts.GoToDefinition.getReferenceAtPosition(node, position, program); if (!resolvedRef?.file) { return undefined; } @@ -656,7 +679,7 @@ namespace ts.FindAllReferences { } return [{ definition: { type: DefinitionKind.TripleSlashReference, reference: resolvedRef.reference, file: node }, - references: getReferencesForNonModule(resolvedRef.file, fileIncludeReasons, program) || emptyArray + references: getReferencesForNonModule(resolvedRef.file, fileIncludeReasons, program) || ts.emptyArray }]; } @@ -669,18 +692,18 @@ namespace ts.FindAllReferences { const checker = program.getTypeChecker(); // constructors should use the class symbol, detected by name, if present - const symbol = checker.getSymbolAtLocation(isConstructorDeclaration(node) && node.parent.name || node); + const symbol = checker.getSymbolAtLocation(ts.isConstructorDeclaration(node) && node.parent.name || node); // Could not find a symbol e.g. unknown identifier if (!symbol) { // String literal might be a property (and thus have a symbol), so do this here rather than in getReferencedSymbolsSpecial. - if (!options.implementations && isStringLiteralLike(node)) { - if (isModuleSpecifierLike(node)) { + if (!options.implementations && ts.isStringLiteralLike(node)) { + if (ts.isModuleSpecifierLike(node)) { const fileIncludeReasons = program.getFileIncludeReasons(); - const referencedFileName = node.getSourceFile().resolvedModules?.get(node.text, getModeForUsageLocation(node.getSourceFile(), node))?.resolvedFileName; + const referencedFileName = node.getSourceFile().resolvedModules?.get(node.text, ts.getModeForUsageLocation(node.getSourceFile(), node))?.resolvedFileName; const referencedFile = referencedFileName ? program.getSourceFile(referencedFileName) : undefined; if (referencedFile) { - return [{ definition: { type: DefinitionKind.String, node }, references: getReferencesForNonModule(referencedFile, fileIncludeReasons, program) || emptyArray }]; + return [{ definition: { type: DefinitionKind.String, node }, references: getReferencesForNonModule(referencedFile, fileIncludeReasons, program) || ts.emptyArray }]; } // Fall through to string literal references. This is not very likely to return // anything useful, but I guess it's better than nothing, and there's an existing @@ -691,12 +714,12 @@ namespace ts.FindAllReferences { return undefined; } - if (symbol.escapedName === InternalSymbolName.ExportEquals) { + if (symbol.escapedName === ts.InternalSymbolName.ExportEquals) { return getReferencedSymbolsForModule(program, symbol.parent!, /*excludeImportTypeOfExportEquals*/ false, sourceFiles, sourceFilesSet); } const moduleReferences = getReferencedSymbolsForModuleIfDeclaredBySourceFile(symbol, program, sourceFiles, cancellationToken, options, sourceFilesSet); - if (moduleReferences && !(symbol.flags & SymbolFlags.Transient)) { + if (moduleReferences && !(symbol.flags & ts.SymbolFlags.Transient)) { return moduleReferences; } @@ -708,38 +731,38 @@ namespace ts.FindAllReferences { return mergeReferences(program, moduleReferences, references, moduleReferencesOfExportTarget); } - export function getAdjustedNode(node: Node, options: Options) { + export function getAdjustedNode(node: ts.Node, options: Options) { if (options.use === FindReferencesUse.References) { - node = getAdjustedReferenceLocation(node); + node = ts.getAdjustedReferenceLocation(node); } else if (options.use === FindReferencesUse.Rename) { - node = getAdjustedRenameLocation(node); + node = ts.getAdjustedRenameLocation(node); } return node; } - export function getReferencesForFileName(fileName: string, program: Program, sourceFiles: readonly SourceFile[], sourceFilesSet: ReadonlySet = new Set(sourceFiles.map(f => f.fileName))): readonly Entry[] { + export function getReferencesForFileName(fileName: string, program: ts.Program, sourceFiles: readonly ts.SourceFile[], sourceFilesSet: ts.ReadonlySet = new ts.Set(sourceFiles.map(f => f.fileName))): readonly Entry[] { const moduleSymbol = program.getSourceFile(fileName)?.symbol; if (moduleSymbol) { - return getReferencedSymbolsForModule(program, moduleSymbol, /*excludeImportTypeOfExportEquals*/ false, sourceFiles, sourceFilesSet)[0]?.references || emptyArray; + return getReferencedSymbolsForModule(program, moduleSymbol, /*excludeImportTypeOfExportEquals*/ false, sourceFiles, sourceFilesSet)[0]?.references || ts.emptyArray; } const fileIncludeReasons = program.getFileIncludeReasons(); const referencedFile = program.getSourceFile(fileName); - return referencedFile && fileIncludeReasons && getReferencesForNonModule(referencedFile, fileIncludeReasons, program) || emptyArray; + return referencedFile && fileIncludeReasons && getReferencesForNonModule(referencedFile, fileIncludeReasons, program) || ts.emptyArray; } - function getReferencesForNonModule(referencedFile: SourceFile, refFileMap: MultiMap, program: Program): readonly SpanEntry[] | undefined { + function getReferencesForNonModule(referencedFile: ts.SourceFile, refFileMap: ts.MultiMap, program: ts.Program): readonly SpanEntry[] | undefined { let entries: SpanEntry[] | undefined; - const references = refFileMap.get(referencedFile.path) || emptyArray; + const references = refFileMap.get(referencedFile.path) || ts.emptyArray; for (const ref of references) { - if (isReferencedFile(ref)) { + if (ts.isReferencedFile(ref)) { const referencingFile = program.getSourceFileByPath(ref.file)!; - const location = getReferencedFileLocation(program.getSourceFileByPath, ref); - if (isReferenceFileLocation(location)) { - entries = append(entries, { + const location = ts.getReferencedFileLocation(program.getSourceFileByPath, ref); + if (ts.isReferenceFileLocation(location)) { + entries = ts.append(entries, { kind: EntryKind.Span, fileName: referencingFile.fileName, - textSpan: createTextSpanFromRange(location) + textSpan: ts.createTextSpanFromRange(location) }); } } @@ -747,8 +770,8 @@ namespace ts.FindAllReferences { return entries; } - function getMergedAliasedSymbolOfNamespaceExportDeclaration(node: Node, symbol: Symbol, checker: TypeChecker) { - if (node.parent && isNamespaceExportDeclaration(node.parent)) { + function getMergedAliasedSymbolOfNamespaceExportDeclaration(node: ts.Node, symbol: ts.Symbol, checker: ts.TypeChecker) { + if (node.parent && ts.isNamespaceExportDeclaration(node.parent)) { const aliasedSymbol = checker.getAliasedSymbol(symbol); const targetSymbol = checker.getMergedSymbol(aliasedSymbol); if (aliasedSymbol !== targetSymbol) { @@ -758,26 +781,29 @@ namespace ts.FindAllReferences { return undefined; } - function getReferencedSymbolsForModuleIfDeclaredBySourceFile(symbol: Symbol, program: Program, sourceFiles: readonly SourceFile[], cancellationToken: CancellationToken, options: Options, sourceFilesSet: ReadonlySet) { - const moduleSourceFile = (symbol.flags & SymbolFlags.Module) && symbol.declarations && find(symbol.declarations, isSourceFile); - if (!moduleSourceFile) return undefined; - const exportEquals = symbol.exports!.get(InternalSymbolName.ExportEquals); + function getReferencedSymbolsForModuleIfDeclaredBySourceFile(symbol: ts.Symbol, program: ts.Program, sourceFiles: readonly ts.SourceFile[], cancellationToken: ts.CancellationToken, options: Options, sourceFilesSet: ts.ReadonlySet) { + const moduleSourceFile = (symbol.flags & ts.SymbolFlags.Module) && symbol.declarations && ts.find(symbol.declarations, ts.isSourceFile); + if (!moduleSourceFile) + return undefined; + const exportEquals = symbol.exports!.get(ts.InternalSymbolName.ExportEquals); // If !!exportEquals, we're about to add references to `import("mod")` anyway, so don't double-count them. const moduleReferences = getReferencedSymbolsForModule(program, symbol, !!exportEquals, sourceFiles, sourceFilesSet); - if (!exportEquals || !sourceFilesSet.has(moduleSourceFile.fileName)) return moduleReferences; + if (!exportEquals || !sourceFilesSet.has(moduleSourceFile.fileName)) + return moduleReferences; // Continue to get references to 'export ='. const checker = program.getTypeChecker(); - symbol = skipAlias(exportEquals, checker); + symbol = ts.skipAlias(exportEquals, checker); return mergeReferences(program, moduleReferences, getReferencedSymbolsForSymbol(symbol, /*node*/ undefined, sourceFiles, sourceFilesSet, checker, cancellationToken, options)); } /** * Merges the references by sorting them (by file index in sourceFiles and their location in it) that point to same definition symbol */ - function mergeReferences(program: Program, ...referencesToMerge: (SymbolAndEntries[] | undefined)[]): SymbolAndEntries[] | undefined { + function mergeReferences(program: ts.Program, ...referencesToMerge: (SymbolAndEntries[] | undefined)[]): SymbolAndEntries[] | undefined { let result: SymbolAndEntries[] | undefined; for (const references of referencesToMerge) { - if (!references || !references.length) continue; + if (!references || !references.length) + continue; if (!result) { result = references; continue; @@ -788,7 +814,7 @@ namespace ts.FindAllReferences { continue; } const symbol = entry.definition.symbol; - const refIndex = findIndex(result, ref => !!ref.definition && + const refIndex = ts.findIndex(result, ref => !!ref.definition && ref.definition.type === DefinitionKind.Symbol && ref.definition.symbol === symbol); if (refIndex === -1) { @@ -803,14 +829,14 @@ namespace ts.FindAllReferences { const entry1File = getSourceFileIndexOfEntry(program, entry1); const entry2File = getSourceFileIndexOfEntry(program, entry2); if (entry1File !== entry2File) { - return compareValues(entry1File, entry2File); + return ts.compareValues(entry1File, entry2File); } const entry1Span = getTextSpanOfEntry(entry1); const entry2Span = getTextSpanOfEntry(entry2); return entry1Span.start !== entry2Span.start ? - compareValues(entry1Span.start, entry2Span.start) : - compareValues(entry1Span.length, entry2Span.length); + ts.compareValues(entry1Span.start, entry2Span.start) : + ts.compareValues(entry1Span.length, entry2Span.length); }) }; } @@ -818,21 +844,20 @@ namespace ts.FindAllReferences { return result; } - function getSourceFileIndexOfEntry(program: Program, entry: Entry) { + function getSourceFileIndexOfEntry(program: ts.Program, entry: Entry) { const sourceFile = entry.kind === EntryKind.Span ? program.getSourceFile(entry.fileName)! : entry.node.getSourceFile(); return program.getSourceFiles().indexOf(sourceFile); } - function getReferencedSymbolsForModule(program: Program, symbol: Symbol, excludeImportTypeOfExportEquals: boolean, sourceFiles: readonly SourceFile[], sourceFilesSet: ReadonlySet): SymbolAndEntries[] { - Debug.assert(!!symbol.valueDeclaration); - - const references = mapDefined(findModuleReferences(program, sourceFiles, symbol), reference => { + function getReferencedSymbolsForModule(program: ts.Program, symbol: ts.Symbol, excludeImportTypeOfExportEquals: boolean, sourceFiles: readonly ts.SourceFile[], sourceFilesSet: ts.ReadonlySet): SymbolAndEntries[] { + ts.Debug.assert(!!symbol.valueDeclaration); + const references = ts.mapDefined(ts.FindAllReferences.findModuleReferences(program, sourceFiles, symbol), reference => { if (reference.kind === "import") { const parent = reference.literal.parent; - if (isLiteralTypeNode(parent)) { - const importType = cast(parent.parent, isImportTypeNode); + if (ts.isLiteralTypeNode(parent)) { + const importType = ts.cast(parent.parent, ts.isImportTypeNode); if (excludeImportTypeOfExportEquals && !importType.qualifier) { return undefined; } @@ -844,7 +869,7 @@ namespace ts.FindAllReferences { return { kind: EntryKind.Span, fileName: reference.referencingFile.fileName, - textSpan: createTextSpanFromRange(reference.ref), + textSpan: ts.createTextSpanFromRange(reference.ref), }; } }); @@ -852,92 +877,87 @@ namespace ts.FindAllReferences { if (symbol.declarations) { for (const decl of symbol.declarations) { switch (decl.kind) { - case SyntaxKind.SourceFile: + case ts.SyntaxKind.SourceFile: // Don't include the source file itself. (This may not be ideal behavior, but awkward to include an entire file as a reference.) break; - case SyntaxKind.ModuleDeclaration: + case ts.SyntaxKind.ModuleDeclaration: if (sourceFilesSet.has(decl.getSourceFile().fileName)) { - references.push(nodeEntry((decl as ModuleDeclaration).name)); + references.push(nodeEntry((decl as ts.ModuleDeclaration).name)); } break; default: // This may be merged with something. - Debug.assert(!!(symbol.flags & SymbolFlags.Transient), "Expected a module symbol to be declared by a SourceFile or ModuleDeclaration."); + ts.Debug.assert(!!(symbol.flags & ts.SymbolFlags.Transient), "Expected a module symbol to be declared by a SourceFile or ModuleDeclaration."); } } } - const exported = symbol.exports!.get(InternalSymbolName.ExportEquals); + const exported = symbol.exports!.get(ts.InternalSymbolName.ExportEquals); if (exported?.declarations) { for (const decl of exported.declarations) { const sourceFile = decl.getSourceFile(); if (sourceFilesSet.has(sourceFile.fileName)) { // At `module.exports = ...`, reference node is `module` - const node = isBinaryExpression(decl) && isPropertyAccessExpression(decl.left) ? decl.left.expression : - isExportAssignment(decl) ? Debug.checkDefined(findChildOfKind(decl, SyntaxKind.ExportKeyword, sourceFile)) : - getNameOfDeclaration(decl) || decl; + const node = ts.isBinaryExpression(decl) && ts.isPropertyAccessExpression(decl.left) ? decl.left.expression : + ts.isExportAssignment(decl) ? ts.Debug.checkDefined(ts.findChildOfKind(decl, ts.SyntaxKind.ExportKeyword, sourceFile)) : + ts.getNameOfDeclaration(decl) || decl; references.push(nodeEntry(node)); } } } - return references.length ? [{ definition: { type: DefinitionKind.Symbol, symbol }, references }] : emptyArray; + return references.length ? [{ definition: { type: DefinitionKind.Symbol, symbol }, references }] : ts.emptyArray; } /** As in a `readonly prop: any` or `constructor(readonly prop: any)`, not a `readonly any[]`. */ - function isReadonlyTypeOperator(node: Node): boolean { - return node.kind === SyntaxKind.ReadonlyKeyword - && isTypeOperatorNode(node.parent) - && node.parent.operator === SyntaxKind.ReadonlyKeyword; + function isReadonlyTypeOperator(node: ts.Node): boolean { + return node.kind === ts.SyntaxKind.ReadonlyKeyword + && ts.isTypeOperatorNode(node.parent) + && node.parent.operator === ts.SyntaxKind.ReadonlyKeyword; } /** getReferencedSymbols for special node kinds. */ - function getReferencedSymbolsSpecial(node: Node, sourceFiles: readonly SourceFile[], cancellationToken: CancellationToken): SymbolAndEntries[] | undefined { - if (isTypeKeyword(node.kind)) { + function getReferencedSymbolsSpecial(node: ts.Node, sourceFiles: readonly ts.SourceFile[], cancellationToken: ts.CancellationToken): SymbolAndEntries[] | undefined { + if (ts.isTypeKeyword(node.kind)) { // A void expression (i.e., `void foo()`) is not special, but the `void` type is. - if (node.kind === SyntaxKind.VoidKeyword && isVoidExpression(node.parent)) { + if (node.kind === ts.SyntaxKind.VoidKeyword && ts.isVoidExpression(node.parent)) { return undefined; } // A modifier readonly (like on a property declaration) is not special; // a readonly type keyword (like `readonly string[]`) is. - if (node.kind === SyntaxKind.ReadonlyKeyword && !isReadonlyTypeOperator(node)) { + if (node.kind === ts.SyntaxKind.ReadonlyKeyword && !isReadonlyTypeOperator(node)) { return undefined; } // Likewise, when we *are* looking for a special keyword, make sure we // *don’t* include readonly member modifiers. - return getAllReferencesForKeyword( - sourceFiles, - node.kind, - cancellationToken, - node.kind === SyntaxKind.ReadonlyKeyword ? isReadonlyTypeOperator : undefined); + return getAllReferencesForKeyword(sourceFiles, node.kind, cancellationToken, node.kind === ts.SyntaxKind.ReadonlyKeyword ? isReadonlyTypeOperator : undefined); } - - if (isImportMeta(node.parent) && node.parent.name === node) { + if (ts.isImportMeta(node.parent) && node.parent.name === node) { return getAllReferencesForImportMeta(sourceFiles, cancellationToken); } - if (isStaticModifier(node) && isClassStaticBlockDeclaration(node.parent)) { + if (ts.isStaticModifier(node) && ts.isClassStaticBlockDeclaration(node.parent)) { return [{ definition: { type: DefinitionKind.Keyword, node }, references: [nodeEntry(node)] }]; } // Labels - if (isJumpStatementTarget(node)) { - const labelDefinition = getTargetLabel(node.parent, node.text); + if (ts.isJumpStatementTarget(node)) { + const labelDefinition = ts.getTargetLabel(node.parent, node.text); // if we have a label definition, look within its statement for references, if not, then // the label is undefined and we have no results.. return labelDefinition && getLabelReferencesInNode(labelDefinition.parent, labelDefinition); } - else if (isLabelOfLabeledStatement(node)) { + else if (ts.isLabelOfLabeledStatement(node)) { // it is a label definition and not a target, search within the parent labeledStatement return getLabelReferencesInNode(node.parent, node); } - if (isThis(node)) { + if (ts.isThis(node)) { return getReferencesForThisKeyword(node, sourceFiles, cancellationToken); } - if (node.kind === SyntaxKind.SuperKeyword) { + if (node.kind === ts.SyntaxKind.SuperKeyword) { return getReferencesForSuperKeyword(node); } @@ -945,22 +965,22 @@ namespace ts.FindAllReferences { } /** Core find-all-references algorithm for a normal symbol. */ - function getReferencedSymbolsForSymbol(originalSymbol: Symbol, node: Node | undefined, sourceFiles: readonly SourceFile[], sourceFilesSet: ReadonlySet, checker: TypeChecker, cancellationToken: CancellationToken, options: Options): SymbolAndEntries[] { + function getReferencedSymbolsForSymbol(originalSymbol: ts.Symbol, node: ts.Node | undefined, sourceFiles: readonly ts.SourceFile[], sourceFilesSet: ts.ReadonlySet, checker: ts.TypeChecker, cancellationToken: ts.CancellationToken, options: Options): SymbolAndEntries[] { const symbol = node && skipPastExportOrImportSpecifierOrUnion(originalSymbol, node, checker, /*useLocalSymbolForExportSpecifier*/ !isForRenameWithPrefixAndSuffixText(options)) || originalSymbol; // Compute the meaning from the location and the symbol it references - const searchMeaning = node ? getIntersectingMeaningFromDeclarations(node, symbol) : SemanticMeaning.All; + const searchMeaning = node ? getIntersectingMeaningFromDeclarations(node, symbol) : ts.SemanticMeaning.All; const result: SymbolAndEntries[] = []; const state = new State(sourceFiles, sourceFilesSet, node ? getSpecialSearchKind(node) : SpecialSearchKind.None, checker, cancellationToken, searchMeaning, options, result); - const exportSpecifier = !isForRenameWithPrefixAndSuffixText(options) || !symbol.declarations ? undefined : find(symbol.declarations, isExportSpecifier); + const exportSpecifier = !isForRenameWithPrefixAndSuffixText(options) || !symbol.declarations ? undefined : ts.find(symbol.declarations, ts.isExportSpecifier); if (exportSpecifier) { // When renaming at an export specifier, rename the export and not the thing being exported. getReferencesAtExportSpecifier(exportSpecifier.name, symbol, exportSpecifier, state.createSearch(node, originalSymbol, /*comingFrom*/ undefined), state, /*addReferencesHere*/ true, /*alwaysGetReferences*/ true); } - else if (node && node.kind === SyntaxKind.DefaultKeyword && symbol.escapedName === InternalSymbolName.Default && symbol.parent) { + else if (node && node.kind === ts.SyntaxKind.DefaultKeyword && symbol.escapedName === ts.InternalSymbolName.Default && symbol.parent) { addReference(node, symbol, state); - searchForImportsOfExport(node, symbol, { exportingModuleSymbol: symbol.parent, exportKind: ExportKind.Default }, state); + searchForImportsOfExport(node, symbol, { exportingModuleSymbol: symbol.parent, exportKind: ts.FindAllReferences.ExportKind.Default }, state); } else { const search = state.createSearch(node, symbol, /*comingFrom*/ undefined, { allSearchSymbols: node ? populateSearchSymbolSet(symbol, node, checker, options.use === FindReferencesUse.Rename, !!options.providePrefixAndSuffixTextForRename, !!options.implementations) : [symbol] }); @@ -970,12 +990,12 @@ namespace ts.FindAllReferences { return result; } - function getReferencesInContainerOrFiles(symbol: Symbol, state: State, search: Search): void { + function getReferencesInContainerOrFiles(symbol: ts.Symbol, state: State, search: Search): void { // Try to get the smallest valid scope that we can limit our search to; // otherwise we'll need to search globally (i.e. include each file). const scope = getSymbolScope(symbol); if (scope) { - getReferencesInContainer(scope, scope.getSourceFile(), search, state, /*addReferencesHere*/ !(isSourceFile(scope) && !contains(state.sourceFiles, scope))); + getReferencesInContainer(scope, scope.getSourceFile(), search, state, /*addReferencesHere*/ !(ts.isSourceFile(scope) && !ts.contains(state.sourceFiles, scope))); } else { // Global search @@ -986,14 +1006,14 @@ namespace ts.FindAllReferences { } } - function getSpecialSearchKind(node: Node): SpecialSearchKind { + function getSpecialSearchKind(node: ts.Node): SpecialSearchKind { switch (node.kind) { - case SyntaxKind.Constructor: - case SyntaxKind.ConstructorKeyword: + case ts.SyntaxKind.Constructor: + case ts.SyntaxKind.ConstructorKeyword: return SpecialSearchKind.Constructor; - case SyntaxKind.Identifier: - if (isClassLike(node.parent)) { - Debug.assert(node.parent.name === node); + case ts.SyntaxKind.Identifier: + if (ts.isClassLike(node.parent)) { + ts.Debug.assert(node.parent.name === node); return SpecialSearchKind.Class; } // falls through @@ -1003,20 +1023,21 @@ namespace ts.FindAllReferences { } /** Handle a few special cases relating to export/import specifiers. */ - function skipPastExportOrImportSpecifierOrUnion(symbol: Symbol, node: Node, checker: TypeChecker, useLocalSymbolForExportSpecifier: boolean): Symbol | undefined { + function skipPastExportOrImportSpecifierOrUnion(symbol: ts.Symbol, node: ts.Node, checker: ts.TypeChecker, useLocalSymbolForExportSpecifier: boolean): ts.Symbol | undefined { const { parent } = node; - if (isExportSpecifier(parent) && useLocalSymbolForExportSpecifier) { - return getLocalSymbolForExportSpecifier(node as Identifier, symbol, parent, checker); + if (ts.isExportSpecifier(parent) && useLocalSymbolForExportSpecifier) { + return getLocalSymbolForExportSpecifier(node as ts.Identifier, symbol, parent, checker); } // If the symbol is declared as part of a declaration like `{ type: "a" } | { type: "b" }`, use the property on the union type to get more references. - return firstDefined(symbol.declarations, decl => { + return ts.firstDefined(symbol.declarations, decl => { if (!decl.parent) { // Ignore UMD module and global merge - if (symbol.flags & SymbolFlags.Transient) return undefined; + if (symbol.flags & ts.SymbolFlags.Transient) + return undefined; // Assertions for GH#21814. We should be handling SourceFile symbols in `getReferencedSymbolsForModule` instead of getting here. - Debug.fail(`Unexpected symbol at ${Debug.formatSyntaxKind(node.kind)}: ${Debug.formatSymbol(symbol)}`); + ts.Debug.fail(`Unexpected symbol at ${ts.Debug.formatSyntaxKind(node.kind)}: ${ts.Debug.formatSymbol(symbol)}`); } - return isTypeLiteralNode(decl.parent) && isUnionTypeNode(decl.parent.parent) + return ts.isTypeLiteralNode(decl.parent) && ts.isUnionTypeNode(decl.parent.parent) ? checker.getPropertyOfType(checker.getTypeFromTypeNode(decl.parent.parent), symbol.name) : undefined; }); @@ -1028,31 +1049,31 @@ namespace ts.FindAllReferences { */ interface Search { /** If coming from an export, we will not recursively search for the imported symbol (since that's where we came from). */ - readonly comingFrom?: ImportExport; - - readonly symbol: Symbol; + readonly comingFrom?: ts.FindAllReferences.ImportExport; + readonly symbol: ts.Symbol; readonly text: string; - readonly escapedText: __String; + readonly escapedText: ts.__String; /** Only set if `options.implementations` is true. These are the symbols checked to get the implementations of a property access. */ - readonly parents: readonly Symbol[] | undefined; - readonly allSearchSymbols: readonly Symbol[]; + readonly parents: readonly ts.Symbol[] | undefined; + readonly allSearchSymbols: readonly ts.Symbol[]; /** * Whether a symbol is in the search set. * Do not compare directly to `symbol` because there may be related symbols to search for. See `populateSearchSymbolSet`. */ - includes(symbol: Symbol): boolean; + includes(symbol: ts.Symbol): boolean; } const enum SpecialSearchKind { None, Constructor, - Class, + Class } - function getNonModuleSymbolOfMergedModuleSymbol(symbol: Symbol) { - if (!(symbol.flags & (SymbolFlags.Module | SymbolFlags.Transient))) return undefined; - const decl = symbol.declarations && find(symbol.declarations, d => !isSourceFile(d) && !isModuleDeclaration(d)); + function getNonModuleSymbolOfMergedModuleSymbol(symbol: ts.Symbol) { + if (!(symbol.flags & (ts.SymbolFlags.Module | ts.SymbolFlags.Transient))) + return undefined; + const decl = symbol.declarations && ts.find(symbol.declarations, d => !ts.isSourceFile(d) && !ts.isModuleDeclaration(d)); return decl && decl.symbol; } @@ -1062,7 +1083,7 @@ namespace ts.FindAllReferences { */ class State { /** Cache for `explicitlyinheritsFrom`. */ - readonly inheritsFromCache = new Map(); + readonly inheritsFromCache = new ts.Map(); /** * Type nodes can contain multiple references to the same type. For example: @@ -1071,7 +1092,7 @@ namespace ts.FindAllReferences { * duplicate entries would be returned here as each of the type references is part of * the same implementation. For that reason, check before we add a new entry. */ - readonly markSeenContainingTypeReference = nodeSeenTracker(); + readonly markSeenContainingTypeReference = ts.nodeSeenTracker(); /** * It's possible that we will encounter the right side of `export { foo as bar } from "x";` more than once. @@ -1084,43 +1105,34 @@ namespace ts.FindAllReferences { * But another reference to it may appear in the same source file. * See `tests/cases/fourslash/transitiveExportImports3.ts`. */ - readonly markSeenReExportRHS = nodeSeenTracker(); - - constructor( - readonly sourceFiles: readonly SourceFile[], - readonly sourceFilesSet: ReadonlySet, - readonly specialSearchKind: SpecialSearchKind, - readonly checker: TypeChecker, - readonly cancellationToken: CancellationToken, - readonly searchMeaning: SemanticMeaning, - readonly options: Options, - private readonly result: Push) { + readonly markSeenReExportRHS = ts.nodeSeenTracker(); + constructor(readonly sourceFiles: readonly ts.SourceFile[], readonly sourceFilesSet: ts.ReadonlySet, readonly specialSearchKind: SpecialSearchKind, readonly checker: ts.TypeChecker, readonly cancellationToken: ts.CancellationToken, readonly searchMeaning: ts.SemanticMeaning, readonly options: Options, private readonly result: ts.Push) { } - - includesSourceFile(sourceFile: SourceFile): boolean { + includesSourceFile(sourceFile: ts.SourceFile): boolean { return this.sourceFilesSet.has(sourceFile.fileName); } - private importTracker: ImportTracker | undefined; + private importTracker: ts.FindAllReferences.ImportTracker | undefined; /** Gets every place to look for references of an exported symbols. See `ImportsResult` in `importTracker.ts` for more documentation. */ - getImportSearches(exportSymbol: Symbol, exportInfo: ExportInfo): ImportsResult { - if (!this.importTracker) this.importTracker = createImportTracker(this.sourceFiles, this.sourceFilesSet, this.checker, this.cancellationToken); + getImportSearches(exportSymbol: ts.Symbol, exportInfo: ts.FindAllReferences.ExportInfo): ts.FindAllReferences.ImportsResult { + if (!this.importTracker) + this.importTracker = ts.FindAllReferences.createImportTracker(this.sourceFiles, this.sourceFilesSet, this.checker, this.cancellationToken); return this.importTracker(exportSymbol, exportInfo, this.options.use === FindReferencesUse.Rename); } /** @param allSearchSymbols set of additional symbols for use by `includes`. */ - createSearch(location: Node | undefined, symbol: Symbol, comingFrom: ImportExport | undefined, searchOptions: { text?: string, allSearchSymbols?: Symbol[] } = {}): Search { + createSearch(location: ts.Node | undefined, symbol: ts.Symbol, comingFrom: ts.FindAllReferences.ImportExport | undefined, searchOptions: { + text?: string; + allSearchSymbols?: ts.Symbol[]; + } = {}): Search { // Note: if this is an external module symbol, the name doesn't include quotes. // Note: getLocalSymbolForExportDefault handles `export default class C {}`, but not `export default C` or `export { C as default }`. // The other two forms seem to be handled downstream (e.g. in `skipPastExportOrImportSpecifier`), so special-casing the first form // here appears to be intentional). - const { - text = stripQuotes(symbolName(getLocalSymbolForExportDefault(symbol) || getNonModuleSymbolOfMergedModuleSymbol(symbol) || symbol)), - allSearchSymbols = [symbol], - } = searchOptions; - const escapedText = escapeLeadingUnderscores(text); + const { text = ts.stripQuotes(ts.symbolName(ts.getLocalSymbolForExportDefault(symbol) || getNonModuleSymbolOfMergedModuleSymbol(symbol) || symbol)), allSearchSymbols = [symbol], } = searchOptions; + const escapedText = ts.escapeLeadingUnderscores(text); const parents = this.options.implementations && location ? getParentSymbolsOfPropertyAccess(location, symbol, this.checker) : undefined; - return { symbol, comingFrom, text, escapedText, parents, allSearchSymbols, includes: sym => contains(allSearchSymbols, sym) }; + return { symbol, comingFrom, text, escapedText, parents, allSearchSymbols, includes: sym => ts.contains(allSearchSymbols, sym) }; } private readonly symbolIdToReferences: Entry[][] = []; @@ -1128,8 +1140,8 @@ namespace ts.FindAllReferences { * Callback to add references for a particular searched symbol. * This initializes a reference group, so only call this if you will add at least one reference. */ - referenceAdder(searchSymbol: Symbol): (node: Node, kind?: NodeEntryKind) => void { - const symbolId = getSymbolId(searchSymbol); + referenceAdder(searchSymbol: ts.Symbol): (node: ts.Node, kind?: NodeEntryKind) => void { + const symbolId = ts.getSymbolId(searchSymbol); let references = this.symbolIdToReferences[symbolId]; if (!references) { references = this.symbolIdToReferences[symbolId] = []; @@ -1139,7 +1151,7 @@ namespace ts.FindAllReferences { } /** Add a reference with no associated definition. */ - addStringOrCommentReference(fileName: string, textSpan: TextSpan): void { + addStringOrCommentReference(fileName: string, textSpan: ts.TextSpan): void { this.result.push({ definition: undefined, references: [{ kind: EntryKind.Span, fileName, textSpan }] @@ -1147,48 +1159,49 @@ namespace ts.FindAllReferences { } // Source file ID → symbol ID → Whether the symbol has been searched for in the source file. - private readonly sourceFileToSeenSymbols: Set[] = []; + private readonly sourceFileToSeenSymbols: ts.Set[] = []; /** Returns `true` the first time we search for a symbol in a file and `false` afterwards. */ - markSearchedSymbols(sourceFile: SourceFile, symbols: readonly Symbol[]): boolean { - const sourceId = getNodeId(sourceFile); - const seenSymbols = this.sourceFileToSeenSymbols[sourceId] || (this.sourceFileToSeenSymbols[sourceId] = new Set()); + markSearchedSymbols(sourceFile: ts.SourceFile, symbols: readonly ts.Symbol[]): boolean { + const sourceId = ts.getNodeId(sourceFile); + const seenSymbols = this.sourceFileToSeenSymbols[sourceId] || (this.sourceFileToSeenSymbols[sourceId] = new ts.Set()); let anyNewSymbols = false; for (const sym of symbols) { - anyNewSymbols = tryAddToSet(seenSymbols, getSymbolId(sym)) || anyNewSymbols; + anyNewSymbols = ts.tryAddToSet(seenSymbols, ts.getSymbolId(sym)) || anyNewSymbols; } return anyNewSymbols; } } /** Search for all imports of a given exported symbol using `State.getImportSearches`. */ - function searchForImportsOfExport(exportLocation: Node, exportSymbol: Symbol, exportInfo: ExportInfo, state: State): void { + function searchForImportsOfExport(exportLocation: ts.Node, exportSymbol: ts.Symbol, exportInfo: ts.FindAllReferences.ExportInfo, state: State): void { const { importSearches, singleReferences, indirectUsers } = state.getImportSearches(exportSymbol, exportInfo); // For `import { foo as bar }` just add the reference to `foo`, and don't otherwise search in the file. if (singleReferences.length) { const addRef = state.referenceAdder(exportSymbol); for (const singleRef of singleReferences) { - if (shouldAddSingleReference(singleRef, state)) addRef(singleRef); + if (shouldAddSingleReference(singleRef, state)) + addRef(singleRef); } } // For each import, find all references to that import in its source file. for (const [importLocation, importSymbol] of importSearches) { - getReferencesInSourceFile(importLocation.getSourceFile(), state.createSearch(importLocation, importSymbol, ImportExport.Export), state); + getReferencesInSourceFile(importLocation.getSourceFile(), state.createSearch(importLocation, importSymbol, ts.FindAllReferences.ImportExport.Export), state); } if (indirectUsers.length) { let indirectSearch: Search | undefined; switch (exportInfo.exportKind) { - case ExportKind.Named: - indirectSearch = state.createSearch(exportLocation, exportSymbol, ImportExport.Export); + case ts.FindAllReferences.ExportKind.Named: + indirectSearch = state.createSearch(exportLocation, exportSymbol, ts.FindAllReferences.ImportExport.Export); break; - case ExportKind.Default: + case ts.FindAllReferences.ExportKind.Default: // Search for a property access to '.default'. This can't be renamed. - indirectSearch = state.options.use === FindReferencesUse.Rename ? undefined : state.createSearch(exportLocation, exportSymbol, ImportExport.Export, { text: "default" }); + indirectSearch = state.options.use === FindReferencesUse.Rename ? undefined : state.createSearch(exportLocation, exportSymbol, ts.FindAllReferences.ImportExport.Export, { text: "default" }); break; - case ExportKind.ExportEquals: + case ts.FindAllReferences.ExportKind.ExportEquals: break; } if (indirectSearch) { @@ -1199,23 +1212,14 @@ namespace ts.FindAllReferences { } } - export function eachExportReference( - sourceFiles: readonly SourceFile[], - checker: TypeChecker, - cancellationToken: CancellationToken | undefined, - exportSymbol: Symbol, - exportingModuleSymbol: Symbol, - exportName: string, - isDefaultExport: boolean, - cb: (ref: Identifier) => void, - ): void { - const importTracker = createImportTracker(sourceFiles, new Set(sourceFiles.map(f => f.fileName)), checker, cancellationToken); - const { importSearches, indirectUsers, singleReferences } = importTracker(exportSymbol, { exportKind: isDefaultExport ? ExportKind.Default : ExportKind.Named, exportingModuleSymbol }, /*isForRename*/ false); + export function eachExportReference(sourceFiles: readonly ts.SourceFile[], checker: ts.TypeChecker, cancellationToken: ts.CancellationToken | undefined, exportSymbol: ts.Symbol, exportingModuleSymbol: ts.Symbol, exportName: string, isDefaultExport: boolean, cb: (ref: ts.Identifier) => void): void { + const importTracker = ts.FindAllReferences.createImportTracker(sourceFiles, new ts.Set(sourceFiles.map(f => f.fileName)), checker, cancellationToken); + const { importSearches, indirectUsers, singleReferences } = importTracker(exportSymbol, { exportKind: isDefaultExport ? ts.FindAllReferences.ExportKind.Default : ts.FindAllReferences.ExportKind.Named, exportingModuleSymbol }, /*isForRename*/ false); for (const [importLocation] of importSearches) { cb(importLocation); } for (const singleReference of singleReferences) { - if (isIdentifier(singleReference) && isImportTypeNode(singleReference.parent)) { + if (ts.isIdentifier(singleReference) && ts.isImportTypeNode(singleReference.parent)) { cb(singleReference); } } @@ -1223,44 +1227,48 @@ namespace ts.FindAllReferences { for (const node of getPossibleSymbolReferenceNodes(indirectUser, isDefaultExport ? "default" : exportName)) { // Import specifiers should be handled by importSearches const symbol = checker.getSymbolAtLocation(node); - const hasExportAssignmentDeclaration = some(symbol?.declarations, d => tryCast(d, isExportAssignment) ? true : false); - if (isIdentifier(node) && !isImportOrExportSpecifier(node.parent) && (symbol === exportSymbol || hasExportAssignmentDeclaration)) { + const hasExportAssignmentDeclaration = ts.some(symbol?.declarations, d => ts.tryCast(d, ts.isExportAssignment) ? true : false); + if (ts.isIdentifier(node) && !ts.isImportOrExportSpecifier(node.parent) && (symbol === exportSymbol || hasExportAssignmentDeclaration)) { cb(node); } } } } - function shouldAddSingleReference(singleRef: Identifier | StringLiteral, state: State): boolean { - if (!hasMatchingMeaning(singleRef, state)) return false; - if (state.options.use !== FindReferencesUse.Rename) return true; + function shouldAddSingleReference(singleRef: ts.Identifier | ts.StringLiteral, state: State): boolean { + if (!hasMatchingMeaning(singleRef, state)) + return false; + if (state.options.use !== FindReferencesUse.Rename) + return true; // Don't rename an import type `import("./module-name")` when renaming `name` in `export = name;` - if (!isIdentifier(singleRef)) return false; + if (!ts.isIdentifier(singleRef)) + return false; // At `default` in `import { default as x }` or `export { default as x }`, do add a reference, but do not rename. - return !(isImportOrExportSpecifier(singleRef.parent) && singleRef.escapedText === InternalSymbolName.Default); + return !(ts.isImportOrExportSpecifier(singleRef.parent) && singleRef.escapedText === ts.InternalSymbolName.Default); } // Go to the symbol we imported from and find references for it. - function searchForImportedSymbol(symbol: Symbol, state: State): void { - if (!symbol.declarations) return; + function searchForImportedSymbol(symbol: ts.Symbol, state: State): void { + if (!symbol.declarations) + return; for (const declaration of symbol.declarations) { const exportingFile = declaration.getSourceFile(); // Need to search in the file even if it's not in the search-file set, because it might export the symbol. - getReferencesInSourceFile(exportingFile, state.createSearch(declaration, symbol, ImportExport.Import), state, state.includesSourceFile(exportingFile)); + getReferencesInSourceFile(exportingFile, state.createSearch(declaration, symbol, ts.FindAllReferences.ImportExport.Import), state, state.includesSourceFile(exportingFile)); } } /** Search for all occurrences of an identifier in a source file (and filter out the ones that match). */ - function searchForName(sourceFile: SourceFile, search: Search, state: State): void { - if (getNameTable(sourceFile).get(search.escapedText) !== undefined) { + function searchForName(sourceFile: ts.SourceFile, search: Search, state: State): void { + if (ts.getNameTable(sourceFile).get(search.escapedText) !== undefined) { getReferencesInSourceFile(sourceFile, search, state); } } - function getPropertySymbolOfDestructuringAssignment(location: Node, checker: TypeChecker): Symbol | undefined { - return isArrayLiteralOrObjectLiteralDestructuringPattern(location.parent.parent) - ? checker.getPropertySymbolOfDestructuringAssignment(location as Identifier) + function getPropertySymbolOfDestructuringAssignment(location: ts.Node, checker: ts.TypeChecker): ts.Symbol | undefined { + return ts.isArrayLiteralOrObjectLiteralDestructuringPattern(location.parent.parent) + ? checker.getPropertySymbolOfDestructuringAssignment(location as ts.Identifier) : undefined; } @@ -1272,11 +1280,11 @@ namespace ts.FindAllReferences { * @returns undefined if the scope cannot be determined, implying that * a reference to a symbol can occur anywhere. */ - function getSymbolScope(symbol: Symbol): Node | undefined { + function getSymbolScope(symbol: ts.Symbol): ts.Node | undefined { // If this is the symbol of a named function expression or named class expression, // then named references are limited to its own scope. const { declarations, flags, parent, valueDeclaration } = symbol; - if (valueDeclaration && (valueDeclaration.kind === SyntaxKind.FunctionExpression || valueDeclaration.kind === SyntaxKind.ClassExpression)) { + if (valueDeclaration && (valueDeclaration.kind === ts.SyntaxKind.FunctionExpression || valueDeclaration.kind === ts.SyntaxKind.ClassExpression)) { return valueDeclaration; } @@ -1285,10 +1293,10 @@ namespace ts.FindAllReferences { } // If this is private property or method, the scope is the containing class - if (flags & (SymbolFlags.Property | SymbolFlags.Method)) { - const privateDeclaration = find(declarations, d => hasEffectiveModifier(d, ModifierFlags.Private) || isPrivateIdentifierClassElementDeclaration(d)); + if (flags & (ts.SymbolFlags.Property | ts.SymbolFlags.Method)) { + const privateDeclaration = ts.find(declarations, d => ts.hasEffectiveModifier(d, ts.ModifierFlags.Private) || ts.isPrivateIdentifierClassElementDeclaration(d)); if (privateDeclaration) { - return getAncestor(privateDeclaration, SyntaxKind.ClassDeclaration); + return ts.getAncestor(privateDeclaration, ts.SyntaxKind.ClassDeclaration); } // Else this is a public property and could be accessed from anywhere. return undefined; @@ -1296,7 +1304,7 @@ namespace ts.FindAllReferences { // If symbol is of object binding pattern element without property name we would want to // look for property too and that could be anywhere - if (declarations.some(isObjectBindingElementWithoutPropertyName)) { + if (declarations.some(ts.isObjectBindingElementWithoutPropertyName)) { return undefined; } @@ -1307,29 +1315,29 @@ namespace ts.FindAllReferences { - The parent is an external module: then we should only search in the module (and recurse on the export later). - But if the parent has `export as namespace`, the symbol is globally visible through that namespace. */ - const exposedByParent = parent && !(symbol.flags & SymbolFlags.TypeParameter); - if (exposedByParent && !(isExternalModuleSymbol(parent) && !parent.globalExports)) { + const exposedByParent = parent && !(symbol.flags & ts.SymbolFlags.TypeParameter); + if (exposedByParent && !(ts.isExternalModuleSymbol(parent) && !parent.globalExports)) { return undefined; } - let scope: Node | undefined; + let scope: ts.Node | undefined; for (const declaration of declarations) { - const container = getContainerNode(declaration); + const container = ts.getContainerNode(declaration); if (scope && scope !== container) { // Different declarations have different containers, bail out return undefined; } - if (!container || container.kind === SyntaxKind.SourceFile && !isExternalOrCommonJsModule(container as SourceFile)) { + if (!container || container.kind === ts.SyntaxKind.SourceFile && !ts.isExternalOrCommonJsModule(container as ts.SourceFile)) { // This is a global variable and not an external module, any declaration defined // within this scope is visible outside the file return undefined; } scope = container; - if (isFunctionExpression(scope)) { - let next: Node | undefined; - while (next = getNextJSDocCommentLocation(scope)) { + if (ts.isFunctionExpression(scope)) { + let next: ts.Node | undefined; + while (next = ts.getNextJSDocCommentLocation(scope)) { scope = next; } } @@ -1344,32 +1352,35 @@ namespace ts.FindAllReferences { } /** Used as a quick check for whether a symbol is used at all in a file (besides its definition). */ - export function isSymbolReferencedInFile(definition: Identifier, checker: TypeChecker, sourceFile: SourceFile, searchContainer: Node = sourceFile): boolean { + export function isSymbolReferencedInFile(definition: ts.Identifier, checker: ts.TypeChecker, sourceFile: ts.SourceFile, searchContainer: ts.Node = sourceFile): boolean { return eachSymbolReferenceInFile(definition, checker, sourceFile, () => true, searchContainer) || false; } - export function eachSymbolReferenceInFile(definition: Identifier, checker: TypeChecker, sourceFile: SourceFile, cb: (token: Identifier) => T, searchContainer: Node = sourceFile): T | undefined { - const symbol = isParameterPropertyDeclaration(definition.parent, definition.parent.parent) - ? first(checker.getSymbolsOfParameterPropertyDeclaration(definition.parent, definition.text)) + export function eachSymbolReferenceInFile(definition: ts.Identifier, checker: ts.TypeChecker, sourceFile: ts.SourceFile, cb: (token: ts.Identifier) => T, searchContainer: ts.Node = sourceFile): T | undefined { + const symbol = ts.isParameterPropertyDeclaration(definition.parent, definition.parent.parent) + ? ts.first(checker.getSymbolsOfParameterPropertyDeclaration(definition.parent, definition.text)) : checker.getSymbolAtLocation(definition); - if (!symbol) return undefined; + if (!symbol) + return undefined; for (const token of getPossibleSymbolReferenceNodes(sourceFile, symbol.name, searchContainer)) { - if (!isIdentifier(token) || token === definition || token.escapedText !== definition.escapedText) continue; + if (!ts.isIdentifier(token) || token === definition || token.escapedText !== definition.escapedText) + continue; const referenceSymbol = checker.getSymbolAtLocation(token)!; if (referenceSymbol === symbol || checker.getShorthandAssignmentValueSymbol(token.parent) === symbol - || isExportSpecifier(token.parent) && getLocalSymbolForExportSpecifier(token, referenceSymbol, token.parent, checker) === symbol) { + || ts.isExportSpecifier(token.parent) && getLocalSymbolForExportSpecifier(token, referenceSymbol, token.parent, checker) === symbol) { const res = cb(token); - if (res) return res; + if (res) + return res; } } } - export function getTopMostDeclarationNamesInFile(declarationName: string, sourceFile: SourceFile): readonly Node[] { - const candidates = filter(getPossibleSymbolReferenceNodes(sourceFile, declarationName), name => !!getDeclarationFromName(name)); + export function getTopMostDeclarationNamesInFile(declarationName: string, sourceFile: ts.SourceFile): readonly ts.Node[] { + const candidates = ts.filter(getPossibleSymbolReferenceNodes(sourceFile, declarationName), name => !!ts.getDeclarationFromName(name)); return candidates.reduce((topMost, decl) => { const depth = getDepth(decl); - if (!some(topMost.declarationNames) || depth === topMost.depth) { + if (!ts.some(topMost.declarationNames) || depth === topMost.depth) { topMost.declarationNames.push(decl); topMost.depth = depth; } @@ -1378,33 +1389,28 @@ namespace ts.FindAllReferences { topMost.depth = depth; } return topMost; - }, { depth: Infinity, declarationNames: [] as Node[] }).declarationNames; - - function getDepth(declaration: Node | undefined) { + }, { depth: Infinity, declarationNames: [] as ts.Node[] }).declarationNames; + function getDepth(declaration: ts.Node | undefined) { let depth = 0; while (declaration) { - declaration = getContainerNode(declaration); + declaration = ts.getContainerNode(declaration); depth++; } return depth; } } - export function someSignatureUsage( - signature: SignatureDeclaration, - sourceFiles: readonly SourceFile[], - checker: TypeChecker, - cb: (name: Identifier, call?: CallExpression) => boolean - ): boolean { - if (!signature.name || !isIdentifier(signature.name)) return false; - - const symbol = Debug.checkDefined(checker.getSymbolAtLocation(signature.name)); + export function someSignatureUsage(signature: ts.SignatureDeclaration, sourceFiles: readonly ts.SourceFile[], checker: ts.TypeChecker, cb: (name: ts.Identifier, call?: ts.CallExpression) => boolean): boolean { + if (!signature.name || !ts.isIdentifier(signature.name)) + return false; + const symbol = ts.Debug.checkDefined(checker.getSymbolAtLocation(signature.name)); for (const sourceFile of sourceFiles) { for (const name of getPossibleSymbolReferenceNodes(sourceFile, symbol.name)) { - if (!isIdentifier(name) || name === signature.name || name.escapedText !== signature.name.escapedText) continue; - const called = climbPastPropertyAccess(name); - const call = isCallExpression(called.parent) && called.parent.expression === called ? called.parent : undefined; + if (!ts.isIdentifier(name) || name === signature.name || name.escapedText !== signature.name.escapedText) + continue; + const called = ts.climbPastPropertyAccess(name); + const call = ts.isCallExpression(called.parent) && called.parent.expression === called ? called.parent : undefined; const referenceSymbol = checker.getSymbolAtLocation(name); if (referenceSymbol && checker.getRootSymbols(referenceSymbol).some(s => s === symbol)) { if (cb(name, call)) { @@ -1416,11 +1422,11 @@ namespace ts.FindAllReferences { return false; } - function getPossibleSymbolReferenceNodes(sourceFile: SourceFile, symbolName: string, container: Node = sourceFile): readonly Node[] { - return getPossibleSymbolReferencePositions(sourceFile, symbolName, container).map(pos => getTouchingPropertyName(sourceFile, pos)); + function getPossibleSymbolReferenceNodes(sourceFile: ts.SourceFile, symbolName: string, container: ts.Node = sourceFile): readonly ts.Node[] { + return getPossibleSymbolReferencePositions(sourceFile, symbolName, container).map(pos => ts.getTouchingPropertyName(sourceFile, pos)); } - function getPossibleSymbolReferencePositions(sourceFile: SourceFile, symbolName: string, container: Node = sourceFile): readonly number[] { + function getPossibleSymbolReferencePositions(sourceFile: ts.SourceFile, symbolName: string, container: ts.Node = sourceFile): readonly number[] { const positions: number[] = []; /// TODO: Cache symbol existence for files to save text search @@ -1438,14 +1444,15 @@ namespace ts.FindAllReferences { let position = text.indexOf(symbolName, container.pos); while (position >= 0) { // If we are past the end, stop looking - if (position > container.end) break; + if (position > container.end) + break; // We found a match. Make sure it's not part of a larger word (i.e. the char // before and after it have to be a non-identifier char). const endPosition = position + symbolNameLength; - if ((position === 0 || !isIdentifierPart(text.charCodeAt(position - 1), ScriptTarget.Latest)) && - (endPosition === sourceLength || !isIdentifierPart(text.charCodeAt(endPosition), ScriptTarget.Latest))) { + if ((position === 0 || !ts.isIdentifierPart(text.charCodeAt(position - 1), ts.ScriptTarget.Latest)) && + (endPosition === sourceLength || !ts.isIdentifierPart(text.charCodeAt(endPosition), ts.ScriptTarget.Latest))) { // Found a real match. Keep searching. positions.push(position); } @@ -1455,36 +1462,35 @@ namespace ts.FindAllReferences { return positions; } - function getLabelReferencesInNode(container: Node, targetLabel: Identifier): SymbolAndEntries[] { + function getLabelReferencesInNode(container: ts.Node, targetLabel: ts.Identifier): SymbolAndEntries[] { const sourceFile = container.getSourceFile(); const labelName = targetLabel.text; - const references = mapDefined(getPossibleSymbolReferenceNodes(sourceFile, labelName, container), node => + const references = ts.mapDefined(getPossibleSymbolReferenceNodes(sourceFile, labelName, container), node => // Only pick labels that are either the target label, or have a target that is the target label - node === targetLabel || (isJumpStatementTarget(node) && getTargetLabel(node, labelName) === targetLabel) ? nodeEntry(node) : undefined); + node === targetLabel || (ts.isJumpStatementTarget(node) && ts.getTargetLabel(node, labelName) === targetLabel) ? nodeEntry(node) : undefined); return [{ definition: { type: DefinitionKind.Label, node: targetLabel }, references }]; } - function isValidReferencePosition(node: Node, searchSymbolName: string): boolean { + function isValidReferencePosition(node: ts.Node, searchSymbolName: string): boolean { // Compare the length so we filter out strict superstrings of the symbol we are looking for switch (node.kind) { - case SyntaxKind.PrivateIdentifier: - if (isJSDocMemberName(node.parent)) { + case ts.SyntaxKind.PrivateIdentifier: + if (ts.isJSDocMemberName(node.parent)) { return true; } // falls through I guess - case SyntaxKind.Identifier: - return (node as PrivateIdentifier | Identifier).text.length === searchSymbolName.length; - case SyntaxKind.NoSubstitutionTemplateLiteral: - case SyntaxKind.StringLiteral: { - const str = node as StringLiteralLike; - return (isLiteralNameOfPropertyDeclarationOrIndexAccess(str) || isNameOfModuleDeclaration(node) || isExpressionOfExternalModuleImportEqualsDeclaration(node) || (isCallExpression(node.parent) && isBindableObjectDefinePropertyCall(node.parent) && node.parent.arguments[1] === node)) && + case ts.SyntaxKind.Identifier: + return (node as ts.PrivateIdentifier | ts.Identifier).text.length === searchSymbolName.length; + case ts.SyntaxKind.NoSubstitutionTemplateLiteral: + case ts.SyntaxKind.StringLiteral: { + const str = node as ts.StringLiteralLike; + return (ts.isLiteralNameOfPropertyDeclarationOrIndexAccess(str) || ts.isNameOfModuleDeclaration(node) || ts.isExpressionOfExternalModuleImportEqualsDeclaration(node) || (ts.isCallExpression(node.parent) && ts.isBindableObjectDefinePropertyCall(node.parent) && node.parent.arguments[1] === node)) && str.text.length === searchSymbolName.length; } - case SyntaxKind.NumericLiteral: - return isLiteralNameOfPropertyDeclarationOrIndexAccess(node as NumericLiteral) && (node as NumericLiteral).text.length === searchSymbolName.length; - - case SyntaxKind.DefaultKeyword: + case ts.SyntaxKind.NumericLiteral: + return ts.isLiteralNameOfPropertyDeclarationOrIndexAccess(node as ts.NumericLiteral) && (node as ts.NumericLiteral).text.length === searchSymbolName.length; + case ts.SyntaxKind.DefaultKeyword: return "default".length === searchSymbolName.length; default: @@ -1492,12 +1498,12 @@ namespace ts.FindAllReferences { } } - function getAllReferencesForImportMeta(sourceFiles: readonly SourceFile[], cancellationToken: CancellationToken): SymbolAndEntries[] | undefined { - const references = flatMap(sourceFiles, sourceFile => { + function getAllReferencesForImportMeta(sourceFiles: readonly ts.SourceFile[], cancellationToken: ts.CancellationToken): SymbolAndEntries[] | undefined { + const references = ts.flatMap(sourceFiles, sourceFile => { cancellationToken.throwIfCancellationRequested(); - return mapDefined(getPossibleSymbolReferenceNodes(sourceFile, "meta", sourceFile), node => { + return ts.mapDefined(getPossibleSymbolReferenceNodes(sourceFile, "meta", sourceFile), node => { const parent = node.parent; - if (isImportMeta(parent)) { + if (ts.isImportMeta(parent)) { return nodeEntry(parent); } }); @@ -1505,10 +1511,10 @@ namespace ts.FindAllReferences { return references.length ? [{ definition: { type: DefinitionKind.Keyword, node: references[0].node }, references }] : undefined; } - function getAllReferencesForKeyword(sourceFiles: readonly SourceFile[], keywordKind: SyntaxKind, cancellationToken: CancellationToken, filter?: (node: Node) => boolean): SymbolAndEntries[] | undefined { - const references = flatMap(sourceFiles, sourceFile => { + function getAllReferencesForKeyword(sourceFiles: readonly ts.SourceFile[], keywordKind: ts.SyntaxKind, cancellationToken: ts.CancellationToken, filter?: (node: ts.Node) => boolean): SymbolAndEntries[] | undefined { + const references = ts.flatMap(sourceFiles, sourceFile => { cancellationToken.throwIfCancellationRequested(); - return mapDefined(getPossibleSymbolReferenceNodes(sourceFile, tokenToString(keywordKind)!, sourceFile), referenceLocation => { + return ts.mapDefined(getPossibleSymbolReferenceNodes(sourceFile, ts.tokenToString(keywordKind)!, sourceFile), referenceLocation => { if (referenceLocation.kind === keywordKind && (!filter || filter(referenceLocation))) { return nodeEntry(referenceLocation); } @@ -1517,7 +1523,7 @@ namespace ts.FindAllReferences { return references.length ? [{ definition: { type: DefinitionKind.Keyword, node: references[0].node }, references }] : undefined; } - function getReferencesInSourceFile(sourceFile: SourceFile, search: Search, state: State, addReferencesHere = true): void { + function getReferencesInSourceFile(sourceFile: ts.SourceFile, search: Search, state: State, addReferencesHere = true): void { state.cancellationToken.throwIfCancellationRequested(); return getReferencesInContainer(sourceFile, sourceFile, search, state, addReferencesHere); } @@ -1527,7 +1533,7 @@ namespace ts.FindAllReferences { * tuple of(searchSymbol, searchText, searchLocation, and searchMeaning). * searchLocation: a node where the search value */ - function getReferencesInContainer(container: Node, sourceFile: SourceFile, search: Search, state: State, addReferencesHere: boolean): void { + function getReferencesInContainer(container: ts.Node, sourceFile: ts.SourceFile, search: Search, state: State, addReferencesHere: boolean): void { if (!state.markSearchedSymbols(sourceFile, search.allSearchSymbols)) { return; } @@ -1537,29 +1543,30 @@ namespace ts.FindAllReferences { } } - function hasMatchingMeaning(referenceLocation: Node, state: State): boolean { - return !!(getMeaningFromLocation(referenceLocation) & state.searchMeaning); + function hasMatchingMeaning(referenceLocation: ts.Node, state: State): boolean { + return !!(ts.getMeaningFromLocation(referenceLocation) & state.searchMeaning); } - function getReferencesAtLocation(sourceFile: SourceFile, position: number, search: Search, state: State, addReferencesHere: boolean): void { - const referenceLocation = getTouchingPropertyName(sourceFile, position); + function getReferencesAtLocation(sourceFile: ts.SourceFile, position: number, search: Search, state: State, addReferencesHere: boolean): void { + const referenceLocation = ts.getTouchingPropertyName(sourceFile, position); if (!isValidReferencePosition(referenceLocation, search.text)) { // This wasn't the start of a token. Check to see if it might be a // match in a comment or string if that's what the caller is asking // for. - if (!state.options.implementations && (state.options.findInStrings && isInString(sourceFile, position) || state.options.findInComments && isInNonReferenceComment(sourceFile, position))) { + if (!state.options.implementations && (state.options.findInStrings && ts.isInString(sourceFile, position) || state.options.findInComments && ts.isInNonReferenceComment(sourceFile, position))) { // In the case where we're looking inside comments/strings, we don't have // an actual definition. So just use 'undefined' here. Features like // 'Rename' won't care (as they ignore the definitions), and features like // 'FindReferences' will just filter out these results. - state.addStringOrCommentReference(sourceFile.fileName, createTextSpan(position, search.text.length)); + state.addStringOrCommentReference(sourceFile.fileName, ts.createTextSpan(position, search.text.length)); } return; } - if (!hasMatchingMeaning(referenceLocation, state)) return; + if (!hasMatchingMeaning(referenceLocation, state)) + return; let referenceSymbol = state.checker.getSymbolAtLocation(referenceLocation); if (!referenceSymbol) { @@ -1567,14 +1574,14 @@ namespace ts.FindAllReferences { } const parent = referenceLocation.parent; - if (isImportSpecifier(parent) && parent.propertyName === referenceLocation) { + if (ts.isImportSpecifier(parent) && parent.propertyName === referenceLocation) { // This is added through `singleReferences` in ImportsResult. If we happen to see it again, don't add it again. return; } - if (isExportSpecifier(parent)) { - Debug.assert(referenceLocation.kind === SyntaxKind.Identifier); - getReferencesAtExportSpecifier(referenceLocation as Identifier, referenceSymbol, parent, search, state, addReferencesHere); + if (ts.isExportSpecifier(parent)) { + ts.Debug.assert(referenceLocation.kind === ts.SyntaxKind.Identifier); + getReferencesAtExportSpecifier(referenceLocation as ts.Identifier, referenceSymbol, parent, search, state, addReferencesHere); return; } @@ -1586,7 +1593,8 @@ namespace ts.FindAllReferences { switch (state.specialSearchKind) { case SpecialSearchKind.None: - if (addReferencesHere) addReference(referenceLocation, relatedSymbol, state); + if (addReferencesHere) + addReference(referenceLocation, relatedSymbol, state); break; case SpecialSearchKind.Constructor: addConstructorReferences(referenceLocation, sourceFile, search, state); @@ -1595,32 +1603,25 @@ namespace ts.FindAllReferences { addClassStaticThisReferences(referenceLocation, search, state); break; default: - Debug.assertNever(state.specialSearchKind); + ts.Debug.assertNever(state.specialSearchKind); } // Use the parent symbol if the location is commonjs require syntax on javascript files only. - if (isInJSFile(referenceLocation) - && referenceLocation.parent.kind === SyntaxKind.BindingElement - && isVariableDeclarationInitializedToBareOrAccessedRequire(referenceLocation.parent)) { + if (ts.isInJSFile(referenceLocation) + && referenceLocation.parent.kind === ts.SyntaxKind.BindingElement + && ts.isVariableDeclarationInitializedToBareOrAccessedRequire(referenceLocation.parent)) { referenceSymbol = referenceLocation.parent.symbol; // The parent will not have a symbol if it's an ObjectBindingPattern (when destructuring is used). In // this case, just skip it, since the bound identifiers are not an alias of the import. - if (!referenceSymbol) return; + if (!referenceSymbol) + return; } getImportOrExportReferences(referenceLocation, referenceSymbol, search, state); } - function getReferencesAtExportSpecifier( - referenceLocation: Identifier, - referenceSymbol: Symbol, - exportSpecifier: ExportSpecifier, - search: Search, - state: State, - addReferencesHere: boolean, - alwaysGetReferences?: boolean, - ): void { - Debug.assert(!alwaysGetReferences || !!state.options.providePrefixAndSuffixTextForRename, "If alwaysGetReferences is true, then prefix/suffix text must be enabled"); + function getReferencesAtExportSpecifier(referenceLocation: ts.Identifier, referenceSymbol: ts.Symbol, exportSpecifier: ts.ExportSpecifier, search: Search, state: State, addReferencesHere: boolean, alwaysGetReferences?: boolean): void { + ts.Debug.assert(!alwaysGetReferences || !!state.options.providePrefixAndSuffixTextForRename, "If alwaysGetReferences is true, then prefix/suffix text must be enabled"); const { parent, propertyName, name } = exportSpecifier; const exportDeclaration = parent.parent; @@ -1631,7 +1632,7 @@ namespace ts.FindAllReferences { if (!propertyName) { // Don't rename at `export { default } from "m";`. (but do continue to search for imports of the re-export) - if (!(state.options.use === FindReferencesUse.Rename && (name.escapedText === InternalSymbolName.Default))) { + if (!(state.options.use === FindReferencesUse.Rename && (name.escapedText === ts.InternalSymbolName.Default))) { addRef(); } } @@ -1643,7 +1644,7 @@ namespace ts.FindAllReferences { } if (addReferencesHere && state.options.use !== FindReferencesUse.Rename && state.markSeenReExportRHS(name)) { - addReference(name, Debug.checkDefined(exportSpecifier.symbol), state); + addReference(name, ts.Debug.checkDefined(exportSpecifier.symbol), state); } } else { @@ -1654,34 +1655,36 @@ namespace ts.FindAllReferences { // For `export { foo as bar }`, rename `foo`, but not `bar`. if (!isForRenameWithPrefixAndSuffixText(state.options) || alwaysGetReferences) { - const isDefaultExport = referenceLocation.originalKeywordKind === SyntaxKind.DefaultKeyword - || exportSpecifier.name.originalKeywordKind === SyntaxKind.DefaultKeyword; - const exportKind = isDefaultExport ? ExportKind.Default : ExportKind.Named; - const exportSymbol = Debug.checkDefined(exportSpecifier.symbol); - const exportInfo = getExportInfo(exportSymbol, exportKind, state.checker); + const isDefaultExport = referenceLocation.originalKeywordKind === ts.SyntaxKind.DefaultKeyword + || exportSpecifier.name.originalKeywordKind === ts.SyntaxKind.DefaultKeyword; + const exportKind = isDefaultExport ? ts.FindAllReferences.ExportKind.Default : ts.FindAllReferences.ExportKind.Named; + const exportSymbol = ts.Debug.checkDefined(exportSpecifier.symbol); + const exportInfo = ts.FindAllReferences.getExportInfo(exportSymbol, exportKind, state.checker); if (exportInfo) { searchForImportsOfExport(referenceLocation, exportSymbol, exportInfo, state); } } // At `export { x } from "foo"`, also search for the imported symbol `"foo".x`. - if (search.comingFrom !== ImportExport.Export && exportDeclaration.moduleSpecifier && !propertyName && !isForRenameWithPrefixAndSuffixText(state.options)) { + if (search.comingFrom !== ts.FindAllReferences.ImportExport.Export && exportDeclaration.moduleSpecifier && !propertyName && !isForRenameWithPrefixAndSuffixText(state.options)) { const imported = state.checker.getExportSpecifierLocalTargetSymbol(exportSpecifier); - if (imported) searchForImportedSymbol(imported, state); + if (imported) + searchForImportedSymbol(imported, state); } function addRef() { - if (addReferencesHere) addReference(referenceLocation, localSymbol, state); + if (addReferencesHere) + addReference(referenceLocation, localSymbol, state); } } - function getLocalSymbolForExportSpecifier(referenceLocation: Identifier, referenceSymbol: Symbol, exportSpecifier: ExportSpecifier, checker: TypeChecker): Symbol { + function getLocalSymbolForExportSpecifier(referenceLocation: ts.Identifier, referenceSymbol: ts.Symbol, exportSpecifier: ts.ExportSpecifier, checker: ts.TypeChecker): ts.Symbol { return isExportSpecifierAlias(referenceLocation, exportSpecifier) && checker.getExportSpecifierLocalTargetSymbol(exportSpecifier) || referenceSymbol; } - function isExportSpecifierAlias(referenceLocation: Identifier, exportSpecifier: ExportSpecifier): boolean { + function isExportSpecifierAlias(referenceLocation: ts.Identifier, exportSpecifier: ts.ExportSpecifier): boolean { const { parent, propertyName, name } = exportSpecifier; - Debug.assert(propertyName === referenceLocation || name === referenceLocation); + ts.Debug.assert(propertyName === referenceLocation || name === referenceLocation); if (propertyName) { // Given `export { foo as bar } [from "someModule"]`: It's an alias at `foo`, but at `bar` it's a new symbol. return propertyName === referenceLocation; @@ -1693,13 +1696,14 @@ namespace ts.FindAllReferences { } } - function getImportOrExportReferences(referenceLocation: Node, referenceSymbol: Symbol, search: Search, state: State): void { - const importOrExport = getImportOrExportSymbol(referenceLocation, referenceSymbol, state.checker, search.comingFrom === ImportExport.Export); - if (!importOrExport) return; + function getImportOrExportReferences(referenceLocation: ts.Node, referenceSymbol: ts.Symbol, search: Search, state: State): void { + const importOrExport = ts.FindAllReferences.getImportOrExportSymbol(referenceLocation, referenceSymbol, state.checker, search.comingFrom === ts.FindAllReferences.ImportExport.Export); + if (!importOrExport) + return; const { symbol } = importOrExport; - if (importOrExport.kind === ImportExport.Import) { + if (importOrExport.kind === ts.FindAllReferences.ImportExport.Import) { if (!(isForRenameWithPrefixAndSuffixText(state.options))) { searchForImportedSymbol(symbol, state); } @@ -1709,9 +1713,9 @@ namespace ts.FindAllReferences { } } - function getReferenceForShorthandProperty({ flags, valueDeclaration }: Symbol, search: Search, state: State): void { + function getReferenceForShorthandProperty({ flags, valueDeclaration }: ts.Symbol, search: Search, state: State): void { const shorthandValueSymbol = state.checker.getShorthandAssignmentValueSymbol(valueDeclaration)!; - const name = valueDeclaration && getNameOfDeclaration(valueDeclaration); + const name = valueDeclaration && ts.getNameOfDeclaration(valueDeclaration); /* * Because in short-hand property assignment, an identifier which stored as name of the short-hand property assignment * has two meanings: property name and property value. Therefore when we do findAllReference at the position where @@ -1719,16 +1723,16 @@ namespace ts.FindAllReferences { * the position in short-hand property assignment excluding property accessing. However, if we do findAllReference at the * position of property accessing, the referenceEntry of such position will be handled in the first case. */ - if (!(flags & SymbolFlags.Transient) && name && search.includes(shorthandValueSymbol)) { + if (!(flags & ts.SymbolFlags.Transient) && name && search.includes(shorthandValueSymbol)) { addReference(name, shorthandValueSymbol, state); } } - function addReference(referenceLocation: Node, relatedSymbol: Symbol | RelatedSymbol, state: State): void { + function addReference(referenceLocation: ts.Node, relatedSymbol: ts.Symbol | RelatedSymbol, state: State): void { const { kind, symbol } = "kind" in relatedSymbol ? relatedSymbol : { kind: undefined, symbol: relatedSymbol }; // eslint-disable-line no-in-operator // if rename symbol from default export anonymous function, for example `export default function() {}`, we do not need to add reference - if (state.options.use === FindReferencesUse.Rename && referenceLocation.kind === SyntaxKind.DefaultKeyword) { + if (state.options.use === FindReferencesUse.Rename && referenceLocation.kind === ts.SyntaxKind.DefaultKeyword) { return; } @@ -1742,15 +1746,15 @@ namespace ts.FindAllReferences { } /** Adds references when a constructor is used with `new this()` in its own class and `super()` calls in subclasses. */ - function addConstructorReferences(referenceLocation: Node, sourceFile: SourceFile, search: Search, state: State): void { - if (isNewExpressionTarget(referenceLocation)) { + function addConstructorReferences(referenceLocation: ts.Node, sourceFile: ts.SourceFile, search: Search, state: State): void { + if (ts.isNewExpressionTarget(referenceLocation)) { addReference(referenceLocation, search.symbol, state); } const pusher = () => state.referenceAdder(search.symbol); - if (isClassLike(referenceLocation.parent)) { - Debug.assert(referenceLocation.kind === SyntaxKind.DefaultKeyword || referenceLocation.parent.name === referenceLocation); + if (ts.isClassLike(referenceLocation.parent)) { + ts.Debug.assert(referenceLocation.kind === ts.SyntaxKind.DefaultKeyword || referenceLocation.parent.name === referenceLocation); // This is the class declaration containing the constructor. findOwnConstructorReferences(search.symbol, sourceFile, pusher()); } @@ -1764,22 +1768,23 @@ namespace ts.FindAllReferences { } } - function addClassStaticThisReferences(referenceLocation: Node, search: Search, state: State): void { + function addClassStaticThisReferences(referenceLocation: ts.Node, search: Search, state: State): void { addReference(referenceLocation, search.symbol, state); const classLike = referenceLocation.parent; - if (state.options.use === FindReferencesUse.Rename || !isClassLike(classLike)) return; - Debug.assert(classLike.name === referenceLocation); + if (state.options.use === FindReferencesUse.Rename || !ts.isClassLike(classLike)) + return; + ts.Debug.assert(classLike.name === referenceLocation); const addRef = state.referenceAdder(search.symbol); for (const member of classLike.members) { - if (!(isMethodOrAccessor(member) && isStatic(member))) { + if (!(ts.isMethodOrAccessor(member) && ts.isStatic(member))) { continue; } if (member.body) { member.body.forEachChild(function cb(node) { - if (node.kind === SyntaxKind.ThisKeyword) { + if (node.kind === ts.SyntaxKind.ThisKeyword) { addRef(node); } - else if (!isFunctionLike(node) && !isClassLike(node)) { + else if (!ts.isFunctionLike(node) && !ts.isClassLike(node)) { node.forEachChild(cb); } }); @@ -1791,12 +1796,12 @@ namespace ts.FindAllReferences { * `classSymbol` is the class where the constructor was defined. * Reference the constructor and all calls to `new this()`. */ - function findOwnConstructorReferences(classSymbol: Symbol, sourceFile: SourceFile, addNode: (node: Node) => void): void { + function findOwnConstructorReferences(classSymbol: ts.Symbol, sourceFile: ts.SourceFile, addNode: (node: ts.Node) => void): void { const constructorSymbol = getClassConstructorSymbol(classSymbol); if (constructorSymbol && constructorSymbol.declarations) { for (const decl of constructorSymbol.declarations) { - const ctrKeyword = findChildOfKind(decl, SyntaxKind.ConstructorKeyword, sourceFile)!; - Debug.assert(decl.kind === SyntaxKind.Constructor && !!ctrKeyword); + const ctrKeyword = ts.findChildOfKind(decl, ts.SyntaxKind.ConstructorKeyword, sourceFile)!; + ts.Debug.assert(decl.kind === ts.SyntaxKind.Constructor && !!ctrKeyword); addNode(ctrKeyword); } } @@ -1804,11 +1809,11 @@ namespace ts.FindAllReferences { if (classSymbol.exports) { classSymbol.exports.forEach(member => { const decl = member.valueDeclaration; - if (decl && decl.kind === SyntaxKind.MethodDeclaration) { - const body = (decl as MethodDeclaration).body; + if (decl && decl.kind === ts.SyntaxKind.MethodDeclaration) { + const body = (decl as ts.MethodDeclaration).body; if (body) { - forEachDescendantOfKind(body, SyntaxKind.ThisKeyword, thisKeyword => { - if (isNewExpressionTarget(thisKeyword)) { + forEachDescendantOfKind(body, ts.SyntaxKind.ThisKeyword, thisKeyword => { + if (ts.isNewExpressionTarget(thisKeyword)) { addNode(thisKeyword); } }); @@ -1818,23 +1823,23 @@ namespace ts.FindAllReferences { } } - function getClassConstructorSymbol(classSymbol: Symbol): Symbol | undefined { - return classSymbol.members && classSymbol.members.get(InternalSymbolName.Constructor); + function getClassConstructorSymbol(classSymbol: ts.Symbol): ts.Symbol | undefined { + return classSymbol.members && classSymbol.members.get(ts.InternalSymbolName.Constructor); } /** Find references to `super` in the constructor of an extending class. */ - function findSuperConstructorAccesses(classDeclaration: ClassLikeDeclaration, addNode: (node: Node) => void): void { + function findSuperConstructorAccesses(classDeclaration: ts.ClassLikeDeclaration, addNode: (node: ts.Node) => void): void { const constructor = getClassConstructorSymbol(classDeclaration.symbol); if (!(constructor && constructor.declarations)) { return; } for (const decl of constructor.declarations) { - Debug.assert(decl.kind === SyntaxKind.Constructor); - const body = (decl as ConstructorDeclaration).body; + ts.Debug.assert(decl.kind === ts.SyntaxKind.Constructor); + const body = (decl as ts.ConstructorDeclaration).body; if (body) { - forEachDescendantOfKind(body, SyntaxKind.SuperKeyword, node => { - if (isCallExpressionTarget(node)) { + forEachDescendantOfKind(body, ts.SyntaxKind.SuperKeyword, node => { + if (ts.isCallExpressionTarget(node)) { addNode(node); } }); @@ -1842,29 +1847,30 @@ namespace ts.FindAllReferences { } } - function hasOwnConstructor(classDeclaration: ClassLikeDeclaration): boolean { + function hasOwnConstructor(classDeclaration: ts.ClassLikeDeclaration): boolean { return !!getClassConstructorSymbol(classDeclaration.symbol); } - function findInheritedConstructorReferences(classDeclaration: ClassLikeDeclaration, state: State): void { - if (hasOwnConstructor(classDeclaration)) return; + function findInheritedConstructorReferences(classDeclaration: ts.ClassLikeDeclaration, state: State): void { + if (hasOwnConstructor(classDeclaration)) + return; const classSymbol = classDeclaration.symbol; const search = state.createSearch(/*location*/ undefined, classSymbol, /*comingFrom*/ undefined); getReferencesInContainerOrFiles(classSymbol, state, search); } - function addImplementationReferences(refNode: Node, addReference: (node: Node) => void, state: State): void { + function addImplementationReferences(refNode: ts.Node, addReference: (node: ts.Node) => void, state: State): void { // Check if we found a function/propertyAssignment/method with an implementation or initializer - if (isDeclarationName(refNode) && isImplementation(refNode.parent)) { + if (ts.isDeclarationName(refNode) && isImplementation(refNode.parent)) { addReference(refNode); return; } - if (refNode.kind !== SyntaxKind.Identifier) { + if (refNode.kind !== ts.SyntaxKind.Identifier) { return; } - if (refNode.parent.kind === SyntaxKind.ShorthandPropertyAssignment) { + if (refNode.parent.kind === ts.SyntaxKind.ShorthandPropertyAssignment) { // Go ahead and dereference the shorthand assignment by going to its definition getReferenceEntriesForShorthandPropertyAssignment(refNode, state.checker, addReference); } @@ -1878,50 +1884,52 @@ namespace ts.FindAllReferences { // If we got a type reference, try and see if the reference applies to any expressions that can implement an interface // Find the first node whose parent isn't a type node -- i.e., the highest type node. - const typeNode = findAncestor(refNode, a => !isQualifiedName(a.parent) && !isTypeNode(a.parent) && !isTypeElement(a.parent))!; + const typeNode = ts.findAncestor(refNode, a => !ts.isQualifiedName(a.parent) && !ts.isTypeNode(a.parent) && !ts.isTypeElement(a.parent))!; const typeHavingNode = typeNode.parent; - if (hasType(typeHavingNode) && typeHavingNode.type === typeNode && state.markSeenContainingTypeReference(typeHavingNode)) { - if (hasInitializer(typeHavingNode)) { + if (ts.hasType(typeHavingNode) && typeHavingNode.type === typeNode && state.markSeenContainingTypeReference(typeHavingNode)) { + if (ts.hasInitializer(typeHavingNode)) { addIfImplementation(typeHavingNode.initializer!); } - else if (isFunctionLike(typeHavingNode) && (typeHavingNode as FunctionLikeDeclaration).body) { - const body = (typeHavingNode as FunctionLikeDeclaration).body!; - if (body.kind === SyntaxKind.Block) { - forEachReturnStatement(body as Block, returnStatement => { - if (returnStatement.expression) addIfImplementation(returnStatement.expression); + else if (ts.isFunctionLike(typeHavingNode) && (typeHavingNode as ts.FunctionLikeDeclaration).body) { + const body = (typeHavingNode as ts.FunctionLikeDeclaration).body!; + if (body.kind === ts.SyntaxKind.Block) { + ts.forEachReturnStatement(body as ts.Block, returnStatement => { + if (returnStatement.expression) + addIfImplementation(returnStatement.expression); }); } else { addIfImplementation(body); } } - else if (isAssertionExpression(typeHavingNode)) { + else if (ts.isAssertionExpression(typeHavingNode)) { addIfImplementation(typeHavingNode.expression); } } - function addIfImplementation(e: Expression): void { - if (isImplementationExpression(e)) addReference(e); + function addIfImplementation(e: ts.Expression): void { + if (isImplementationExpression(e)) + addReference(e); } } - function getContainingClassIfInHeritageClause(node: Node): ClassLikeDeclaration | InterfaceDeclaration | undefined { - return isIdentifier(node) || isPropertyAccessExpression(node) ? getContainingClassIfInHeritageClause(node.parent) - : isExpressionWithTypeArguments(node) ? tryCast(node.parent.parent, isClassLike) : undefined; + function getContainingClassIfInHeritageClause(node: ts.Node): ts.ClassLikeDeclaration | ts.InterfaceDeclaration | undefined { + return ts.isIdentifier(node) || ts.isPropertyAccessExpression(node) ? getContainingClassIfInHeritageClause(node.parent) + : ts.isExpressionWithTypeArguments(node) ? ts.tryCast(node.parent.parent, ts.isClassLike) : undefined; } /** * Returns true if this is an expression that can be considered an implementation */ - function isImplementationExpression(node: Expression): boolean { + function isImplementationExpression(node: ts.Expression): boolean { switch (node.kind) { - case SyntaxKind.ParenthesizedExpression: - return isImplementationExpression((node as ParenthesizedExpression).expression); - case SyntaxKind.ArrowFunction: - case SyntaxKind.FunctionExpression: - case SyntaxKind.ObjectLiteralExpression: - case SyntaxKind.ClassExpression: - case SyntaxKind.ArrayLiteralExpression: + case ts.SyntaxKind.ParenthesizedExpression: + return isImplementationExpression((node as ts.ParenthesizedExpression).expression); + case ts.SyntaxKind.ArrowFunction: + case ts.SyntaxKind.FunctionExpression: + case ts.SyntaxKind.ObjectLiteralExpression: + case ts.SyntaxKind.ClassExpression: + case ts.SyntaxKind.ArrayLiteralExpression: return true; default: return false; @@ -1947,12 +1955,12 @@ namespace ts.FindAllReferences { * @param parent Another class or interface Symbol * @param cachedResults A map of symbol id pairs (i.e. "child,parent") to booleans indicating previous results */ - function explicitlyInheritsFrom(symbol: Symbol, parent: Symbol, cachedResults: ESMap, checker: TypeChecker): boolean { + function explicitlyInheritsFrom(symbol: ts.Symbol, parent: ts.Symbol, cachedResults: ts.ESMap, checker: ts.TypeChecker): boolean { if (symbol === parent) { return true; } - const key = getSymbolId(symbol) + "," + getSymbolId(parent); + const key = ts.getSymbolId(symbol) + "," + ts.getSymbolId(parent); const cached = cachedResults.get(key); if (cached !== undefined) { return cached; @@ -1961,8 +1969,7 @@ namespace ts.FindAllReferences { // Set the key so that we don't infinitely recurse cachedResults.set(key, false); - const inherits = !!symbol.declarations && symbol.declarations.some(declaration => - getAllSuperTypeNodes(declaration).some(typeReference => { + const inherits = !!symbol.declarations && symbol.declarations.some(declaration => ts.getAllSuperTypeNodes(declaration).some(typeReference => { const type = checker.getTypeAtLocation(typeReference); return !!type && !!type.symbol && explicitlyInheritsFrom(type.symbol, parent, cachedResults, checker); })); @@ -1970,23 +1977,23 @@ namespace ts.FindAllReferences { return inherits; } - function getReferencesForSuperKeyword(superKeyword: Node): SymbolAndEntries[] | undefined { - let searchSpaceNode = getSuperContainer(superKeyword, /*stopOnFunctions*/ false); + function getReferencesForSuperKeyword(superKeyword: ts.Node): SymbolAndEntries[] | undefined { + let searchSpaceNode = ts.getSuperContainer(superKeyword, /*stopOnFunctions*/ false); if (!searchSpaceNode) { return undefined; } // Whether 'super' occurs in a static context within a class. - let staticFlag = ModifierFlags.Static; + let staticFlag = ts.ModifierFlags.Static; switch (searchSpaceNode.kind) { - case SyntaxKind.PropertyDeclaration: - case SyntaxKind.PropertySignature: - case SyntaxKind.MethodDeclaration: - case SyntaxKind.MethodSignature: - case SyntaxKind.Constructor: - case SyntaxKind.GetAccessor: - case SyntaxKind.SetAccessor: - staticFlag &= getSyntacticModifierFlags(searchSpaceNode); + case ts.SyntaxKind.PropertyDeclaration: + case ts.SyntaxKind.PropertySignature: + case ts.SyntaxKind.MethodDeclaration: + case ts.SyntaxKind.MethodSignature: + case ts.SyntaxKind.Constructor: + case ts.SyntaxKind.GetAccessor: + case ts.SyntaxKind.SetAccessor: + staticFlag &= ts.getSyntacticModifierFlags(searchSpaceNode); searchSpaceNode = searchSpaceNode.parent; // re-assign to be the owning class break; default: @@ -1994,56 +2001,56 @@ namespace ts.FindAllReferences { } const sourceFile = searchSpaceNode.getSourceFile(); - const references = mapDefined(getPossibleSymbolReferenceNodes(sourceFile, "super", searchSpaceNode), node => { - if (node.kind !== SyntaxKind.SuperKeyword) { + const references = ts.mapDefined(getPossibleSymbolReferenceNodes(sourceFile, "super", searchSpaceNode), node => { + if (node.kind !== ts.SyntaxKind.SuperKeyword) { return; } - const container = getSuperContainer(node, /*stopOnFunctions*/ false); + const container = ts.getSuperContainer(node, /*stopOnFunctions*/ false); // If we have a 'super' container, we must have an enclosing class. // Now make sure the owning class is the same as the search-space // and has the same static qualifier as the original 'super's owner. - return container && isStatic(container) === !!staticFlag && container.parent.symbol === searchSpaceNode.symbol ? nodeEntry(node) : undefined; + return container && ts.isStatic(container) === !!staticFlag && container.parent.symbol === searchSpaceNode.symbol ? nodeEntry(node) : undefined; }); return [{ definition: { type: DefinitionKind.Symbol, symbol: searchSpaceNode.symbol }, references }]; } - function isParameterName(node: Node) { - return node.kind === SyntaxKind.Identifier && node.parent.kind === SyntaxKind.Parameter && (node.parent as ParameterDeclaration).name === node; + function isParameterName(node: ts.Node) { + return node.kind === ts.SyntaxKind.Identifier && node.parent.kind === ts.SyntaxKind.Parameter && (node.parent as ts.ParameterDeclaration).name === node; } - function getReferencesForThisKeyword(thisOrSuperKeyword: Node, sourceFiles: readonly SourceFile[], cancellationToken: CancellationToken): SymbolAndEntries[] | undefined { - let searchSpaceNode = getThisContainer(thisOrSuperKeyword, /* includeArrowFunctions */ false); + function getReferencesForThisKeyword(thisOrSuperKeyword: ts.Node, sourceFiles: readonly ts.SourceFile[], cancellationToken: ts.CancellationToken): SymbolAndEntries[] | undefined { + let searchSpaceNode = ts.getThisContainer(thisOrSuperKeyword, /* includeArrowFunctions */ false); // Whether 'this' occurs in a static context within a class. - let staticFlag = ModifierFlags.Static; + let staticFlag = ts.ModifierFlags.Static; switch (searchSpaceNode.kind) { - case SyntaxKind.MethodDeclaration: - case SyntaxKind.MethodSignature: - if (isObjectLiteralMethod(searchSpaceNode)) { - staticFlag &= getSyntacticModifierFlags(searchSpaceNode); + case ts.SyntaxKind.MethodDeclaration: + case ts.SyntaxKind.MethodSignature: + if (ts.isObjectLiteralMethod(searchSpaceNode)) { + staticFlag &= ts.getSyntacticModifierFlags(searchSpaceNode); searchSpaceNode = searchSpaceNode.parent; // re-assign to be the owning object literals break; } // falls through - case SyntaxKind.PropertyDeclaration: - case SyntaxKind.PropertySignature: - case SyntaxKind.Constructor: - case SyntaxKind.GetAccessor: - case SyntaxKind.SetAccessor: - staticFlag &= getSyntacticModifierFlags(searchSpaceNode); + case ts.SyntaxKind.PropertyDeclaration: + case ts.SyntaxKind.PropertySignature: + case ts.SyntaxKind.Constructor: + case ts.SyntaxKind.GetAccessor: + case ts.SyntaxKind.SetAccessor: + staticFlag &= ts.getSyntacticModifierFlags(searchSpaceNode); searchSpaceNode = searchSpaceNode.parent; // re-assign to be the owning class break; - case SyntaxKind.SourceFile: - if (isExternalModule(searchSpaceNode as SourceFile) || isParameterName(thisOrSuperKeyword)) { + case ts.SyntaxKind.SourceFile: + if (ts.isExternalModule(searchSpaceNode as ts.SourceFile) || isParameterName(thisOrSuperKeyword)) { return undefined; } // falls through - case SyntaxKind.FunctionDeclaration: - case SyntaxKind.FunctionExpression: + case ts.SyntaxKind.FunctionDeclaration: + case ts.SyntaxKind.FunctionExpression: break; // Computed properties in classes are not handled here because references to this are illegal, // so there is no point finding references to them. @@ -2051,53 +2058,53 @@ namespace ts.FindAllReferences { return undefined; } - const references = flatMap(searchSpaceNode.kind === SyntaxKind.SourceFile ? sourceFiles : [searchSpaceNode.getSourceFile()], sourceFile => { + const references = ts.flatMap(searchSpaceNode.kind === ts.SyntaxKind.SourceFile ? sourceFiles : [searchSpaceNode.getSourceFile()], sourceFile => { cancellationToken.throwIfCancellationRequested(); - return getPossibleSymbolReferenceNodes(sourceFile, "this", isSourceFile(searchSpaceNode) ? sourceFile : searchSpaceNode).filter(node => { - if (!isThis(node)) { + return getPossibleSymbolReferenceNodes(sourceFile, "this", ts.isSourceFile(searchSpaceNode) ? sourceFile : searchSpaceNode).filter(node => { + if (!ts.isThis(node)) { return false; } - const container = getThisContainer(node, /* includeArrowFunctions */ false); + const container = ts.getThisContainer(node, /* includeArrowFunctions */ false); switch (searchSpaceNode.kind) { - case SyntaxKind.FunctionExpression: - case SyntaxKind.FunctionDeclaration: + case ts.SyntaxKind.FunctionExpression: + case ts.SyntaxKind.FunctionDeclaration: return searchSpaceNode.symbol === container.symbol; - case SyntaxKind.MethodDeclaration: - case SyntaxKind.MethodSignature: - return isObjectLiteralMethod(searchSpaceNode) && searchSpaceNode.symbol === container.symbol; - case SyntaxKind.ClassExpression: - case SyntaxKind.ClassDeclaration: - case SyntaxKind.ObjectLiteralExpression: + case ts.SyntaxKind.MethodDeclaration: + case ts.SyntaxKind.MethodSignature: + return ts.isObjectLiteralMethod(searchSpaceNode) && searchSpaceNode.symbol === container.symbol; + case ts.SyntaxKind.ClassExpression: + case ts.SyntaxKind.ClassDeclaration: + case ts.SyntaxKind.ObjectLiteralExpression: // Make sure the container belongs to the same class/object literals // and has the appropriate static modifier from the original container. - return container.parent && searchSpaceNode.symbol === container.parent.symbol && isStatic(container) === !!staticFlag; - case SyntaxKind.SourceFile: - return container.kind === SyntaxKind.SourceFile && !isExternalModule(container as SourceFile) && !isParameterName(node); + return container.parent && searchSpaceNode.symbol === container.parent.symbol && ts.isStatic(container) === !!staticFlag; + case ts.SyntaxKind.SourceFile: + return container.kind === ts.SyntaxKind.SourceFile && !ts.isExternalModule(container as ts.SourceFile) && !isParameterName(node); } }); }).map(n => nodeEntry(n)); - const thisParameter = firstDefined(references, r => isParameter(r.node.parent) ? r.node : undefined); + const thisParameter = ts.firstDefined(references, r => ts.isParameter(r.node.parent) ? r.node : undefined); return [{ definition: { type: DefinitionKind.This, node: thisParameter || thisOrSuperKeyword }, references }]; } - function getReferencesForStringLiteral(node: StringLiteralLike, sourceFiles: readonly SourceFile[], checker: TypeChecker, cancellationToken: CancellationToken): SymbolAndEntries[] { - const type = getContextualTypeFromParentOrAncestorTypeNode(node, checker); - const references = flatMap(sourceFiles, sourceFile => { + function getReferencesForStringLiteral(node: ts.StringLiteralLike, sourceFiles: readonly ts.SourceFile[], checker: ts.TypeChecker, cancellationToken: ts.CancellationToken): SymbolAndEntries[] { + const type = ts.getContextualTypeFromParentOrAncestorTypeNode(node, checker); + const references = ts.flatMap(sourceFiles, sourceFile => { cancellationToken.throwIfCancellationRequested(); - return mapDefined(getPossibleSymbolReferenceNodes(sourceFile, node.text), ref => { - if (isStringLiteralLike(ref) && ref.text === node.text) { + return ts.mapDefined(getPossibleSymbolReferenceNodes(sourceFile, node.text), ref => { + if (ts.isStringLiteralLike(ref) && ref.text === node.text) { if (type) { - const refType = getContextualTypeFromParentOrAncestorTypeNode(ref, checker); + const refType = ts.getContextualTypeFromParentOrAncestorTypeNode(ref, checker); if (type !== checker.getStringType() && type === refType) { return nodeEntry(ref, EntryKind.StringLiteral); } } else { - return isNoSubstitutionTemplateLiteral(ref) && !rangeIsOnSingleLine(ref, sourceFile) ? undefined : + return ts.isNoSubstitutionTemplateLiteral(ref) && !ts.rangeIsOnSingleLine(ref, sourceFile) ? undefined : nodeEntry(ref, EntryKind.StringLiteral); } } @@ -2112,10 +2119,9 @@ namespace ts.FindAllReferences { // For certain symbol kinds, we need to include other symbols in the search set. // This is not needed when searching for re-exports. - function populateSearchSymbolSet(symbol: Symbol, location: Node, checker: TypeChecker, isForRename: boolean, providePrefixAndSuffixText: boolean, implementations: boolean): Symbol[] { - const result: Symbol[] = []; - forEachRelatedSymbol(symbol, location, checker, isForRename, !(isForRename && providePrefixAndSuffixText), - (sym, root, base) => { + function populateSearchSymbolSet(symbol: ts.Symbol, location: ts.Node, checker: ts.TypeChecker, isForRename: boolean, providePrefixAndSuffixText: boolean, implementations: boolean): ts.Symbol[] { + const result: ts.Symbol[] = []; + forEachRelatedSymbol(symbol, location, checker, isForRename, !(isForRename && providePrefixAndSuffixText), (sym, root, base) => { // static method/property and instance method/property might have the same name. Only include static or only include instance. if (base) { if (isStaticSymbol(symbol) !== isStaticSymbol(base)) { @@ -2132,15 +2138,12 @@ namespace ts.FindAllReferences { /** * @param allowBaseTypes return true means it would try to find in base class or interface. */ - function forEachRelatedSymbol( - symbol: Symbol, location: Node, checker: TypeChecker, isForRenamePopulateSearchSymbolSet: boolean, onlyIncludeBindingElementAtReferenceLocation: boolean, + function forEachRelatedSymbol(symbol: ts.Symbol, location: ts.Node, checker: ts.TypeChecker, isForRenamePopulateSearchSymbolSet: boolean, onlyIncludeBindingElementAtReferenceLocation: boolean, /** * @param baseSymbol This symbol means one property/mehtod from base class or interface when it is not null or undefined, */ - cbSymbol: (symbol: Symbol, rootSymbol?: Symbol, baseSymbol?: Symbol, kind?: NodeEntryKind) => T | undefined, - allowBaseTypes: (rootSymbol: Symbol) => boolean, - ): T | undefined { - const containingObjectLiteralElement = getContainingObjectLiteralElement(location); + cbSymbol: (symbol: ts.Symbol, rootSymbol?: ts.Symbol, baseSymbol?: ts.Symbol, kind?: NodeEntryKind) => T | undefined, allowBaseTypes: (rootSymbol: ts.Symbol) => boolean): T | undefined { + const containingObjectLiteralElement = ts.getContainingObjectLiteralElement(location); if (containingObjectLiteralElement) { /* Because in short-hand property assignment, location has two meaning : property name and as value of the property * When we do findAllReference at the position of the short-hand property assignment, we would want to have references to position of @@ -2163,54 +2166,57 @@ namespace ts.FindAllReferences { // to get a contextual type for it, and add the property symbol from the contextual // type to the search set const contextualType = checker.getContextualType(containingObjectLiteralElement.parent); - const res = contextualType && firstDefined( - getPropertySymbolsFromContextualType(containingObjectLiteralElement, checker, contextualType, /*unionSymbolOk*/ true), - sym => fromRoot(sym, EntryKind.SearchedPropertyFoundLocal)); - if (res) return res; + const res = contextualType && ts.firstDefined(ts.getPropertySymbolsFromContextualType(containingObjectLiteralElement, checker, contextualType, /*unionSymbolOk*/ true), sym => fromRoot(sym, EntryKind.SearchedPropertyFoundLocal)); + if (res) + return res; // If the location is name of property symbol from object literal destructuring pattern // Search the property symbol // for ( { property: p2 } of elems) { } const propertySymbol = getPropertySymbolOfDestructuringAssignment(location, checker); const res1 = propertySymbol && cbSymbol(propertySymbol, /*rootSymbol*/ undefined, /*baseSymbol*/ undefined, EntryKind.SearchedPropertyFoundLocal); - if (res1) return res1; + if (res1) + return res1; const res2 = shorthandValueSymbol && cbSymbol(shorthandValueSymbol, /*rootSymbol*/ undefined, /*baseSymbol*/ undefined, EntryKind.SearchedLocalFoundProperty); - if (res2) return res2; + if (res2) + return res2; } const aliasedSymbol = getMergedAliasedSymbolOfNamespaceExportDeclaration(location, symbol, checker); if (aliasedSymbol) { // In case of UMD module and global merging, search for global as well const res = cbSymbol(aliasedSymbol, /*rootSymbol*/ undefined, /*baseSymbol*/ undefined, EntryKind.Node); - if (res) return res; + if (res) + return res; } const res = fromRoot(symbol); - if (res) return res; - - if (symbol.valueDeclaration && isParameterPropertyDeclaration(symbol.valueDeclaration, symbol.valueDeclaration.parent)) { + if (res) + return res; + if (symbol.valueDeclaration && ts.isParameterPropertyDeclaration(symbol.valueDeclaration, symbol.valueDeclaration.parent)) { // For a parameter property, now try on the other symbol (property if this was a parameter, parameter if this was a property). - const paramProps = checker.getSymbolsOfParameterPropertyDeclaration(cast(symbol.valueDeclaration, isParameter), symbol.name); - Debug.assert(paramProps.length === 2 && !!(paramProps[0].flags & SymbolFlags.FunctionScopedVariable) && !!(paramProps[1].flags & SymbolFlags.Property)); // is [parameter, property] - return fromRoot(symbol.flags & SymbolFlags.FunctionScopedVariable ? paramProps[1] : paramProps[0]); + const paramProps = checker.getSymbolsOfParameterPropertyDeclaration(ts.cast(symbol.valueDeclaration, ts.isParameter), symbol.name); + ts.Debug.assert(paramProps.length === 2 && !!(paramProps[0].flags & ts.SymbolFlags.FunctionScopedVariable) && !!(paramProps[1].flags & ts.SymbolFlags.Property)); // is [parameter, property] + return fromRoot(symbol.flags & ts.SymbolFlags.FunctionScopedVariable ? paramProps[1] : paramProps[0]); } - const exportSpecifier = getDeclarationOfKind(symbol, SyntaxKind.ExportSpecifier); + const exportSpecifier = ts.getDeclarationOfKind(symbol, ts.SyntaxKind.ExportSpecifier); if (!isForRenamePopulateSearchSymbolSet || exportSpecifier && !exportSpecifier.propertyName) { const localSymbol = exportSpecifier && checker.getExportSpecifierLocalTargetSymbol(exportSpecifier); if (localSymbol) { const res = cbSymbol(localSymbol, /*rootSymbol*/ undefined, /*baseSymbol*/ undefined, EntryKind.Node); - if (res) return res; + if (res) + return res; } } // symbolAtLocation for a binding element is the local symbol. See if the search symbol is the property. // Don't do this when populating search set for a rename when prefix and suffix text will be provided -- just rename the local. if (!isForRenamePopulateSearchSymbolSet) { - let bindingElementPropertySymbol: Symbol | undefined; + let bindingElementPropertySymbol: ts.Symbol | undefined; if (onlyIncludeBindingElementAtReferenceLocation) { - bindingElementPropertySymbol = isObjectBindingElementWithoutPropertyName(location.parent) ? getPropertySymbolFromBindingElement(checker, location.parent) : undefined; + bindingElementPropertySymbol = ts.isObjectBindingElementWithoutPropertyName(location.parent) ? ts.getPropertySymbolFromBindingElement(checker, location.parent) : undefined; } else { bindingElementPropertySymbol = getPropertySymbolOfObjectBindingPatternWithoutPropertyName(symbol, checker); @@ -2218,7 +2224,7 @@ namespace ts.FindAllReferences { return bindingElementPropertySymbol && fromRoot(bindingElementPropertySymbol, EntryKind.SearchedPropertyFoundLocal); } - Debug.assert(isForRenamePopulateSearchSymbolSet); + ts.Debug.assert(isForRenamePopulateSearchSymbolSet); // due to the above assert and the arguments at the uses of this function, // (onlyIncludeBindingElementAtReferenceLocation <=> !providePrefixAndSuffixTextForRename) holds const includeOriginalSymbolOfBindingElement = onlyIncludeBindingElementAtReferenceLocation; @@ -2228,25 +2234,24 @@ namespace ts.FindAllReferences { return bindingElementPropertySymbol && fromRoot(bindingElementPropertySymbol, EntryKind.SearchedPropertyFoundLocal); } - function fromRoot(sym: Symbol, kind?: NodeEntryKind): T | undefined { + function fromRoot(sym: ts.Symbol, kind?: NodeEntryKind): T | undefined { // If this is a union property: // - In populateSearchSymbolsSet we will add all the symbols from all its source symbols in all unioned types. // - In findRelatedSymbol, we will just use the union symbol if any source symbol is included in the search. // If the symbol is an instantiation from a another symbol (e.g. widened symbol): // - In populateSearchSymbolsSet, add the root the list // - In findRelatedSymbol, return the source symbol if that is in the search. (Do not return the instantiation symbol.) - return firstDefined(checker.getRootSymbols(sym), rootSymbol => - cbSymbol(sym, rootSymbol, /*baseSymbol*/ undefined, kind) + return ts.firstDefined(checker.getRootSymbols(sym), rootSymbol => cbSymbol(sym, rootSymbol, /*baseSymbol*/ undefined, kind) // Add symbol of properties/methods of the same name in base classes and implemented interfaces definitions - || (rootSymbol.parent && rootSymbol.parent.flags & (SymbolFlags.Class | SymbolFlags.Interface) && allowBaseTypes(rootSymbol) + || (rootSymbol.parent && rootSymbol.parent.flags & (ts.SymbolFlags.Class | ts.SymbolFlags.Interface) && allowBaseTypes(rootSymbol) ? getPropertySymbolsFromBaseTypes(rootSymbol.parent, rootSymbol.name, checker, base => cbSymbol(sym, rootSymbol, base, kind)) : undefined)); } - function getPropertySymbolOfObjectBindingPatternWithoutPropertyName(symbol: Symbol, checker: TypeChecker): Symbol | undefined { - const bindingElement = getDeclarationOfKind(symbol, SyntaxKind.BindingElement); - if (bindingElement && isObjectBindingElementWithoutPropertyName(bindingElement)) { - return getPropertySymbolFromBindingElement(checker, bindingElement); + function getPropertySymbolOfObjectBindingPatternWithoutPropertyName(symbol: ts.Symbol, checker: ts.TypeChecker): ts.Symbol | undefined { + const bindingElement = ts.getDeclarationOfKind(symbol, ts.SyntaxKind.BindingElement); + if (bindingElement && ts.isObjectBindingElementWithoutPropertyName(bindingElement)) { + return ts.getPropertySymbolFromBindingElement(checker, bindingElement); } } } @@ -2259,42 +2264,42 @@ namespace ts.FindAllReferences { * @param previousIterationSymbolsCache a cache of symbol from previous iterations of calling this function to prevent infinite revisiting of the same symbol. * The value of previousIterationSymbol is undefined when the function is first called. */ - function getPropertySymbolsFromBaseTypes(symbol: Symbol, propertyName: string, checker: TypeChecker, cb: (symbol: Symbol) => T | undefined): T | undefined { - const seen = new Map(); + function getPropertySymbolsFromBaseTypes(symbol: ts.Symbol, propertyName: string, checker: ts.TypeChecker, cb: (symbol: ts.Symbol) => T | undefined): T | undefined { + const seen = new ts.Map(); return recur(symbol); - function recur(symbol: Symbol): T | undefined { + function recur(symbol: ts.Symbol): T | undefined { // Use `addToSeen` to ensure we don't infinitely recurse in this situation: // interface C extends C { // /*findRef*/propName: string; // } - if (!(symbol.flags & (SymbolFlags.Class | SymbolFlags.Interface)) || !addToSeen(seen, getSymbolId(symbol))) return; - - return firstDefined(symbol.declarations, declaration => firstDefined(getAllSuperTypeNodes(declaration), typeReference => { + if (!(symbol.flags & (ts.SymbolFlags.Class | ts.SymbolFlags.Interface)) || !ts.addToSeen(seen, ts.getSymbolId(symbol))) + return; + return ts.firstDefined(symbol.declarations, declaration => ts.firstDefined(ts.getAllSuperTypeNodes(declaration), typeReference => { const type = checker.getTypeAtLocation(typeReference); const propertySymbol = type && type.symbol && checker.getPropertyOfType(type, propertyName); // Visit the typeReference as well to see if it directly or indirectly uses that property - return type && propertySymbol && (firstDefined(checker.getRootSymbols(propertySymbol), cb) || recur(type.symbol)); + return type && propertySymbol && (ts.firstDefined(checker.getRootSymbols(propertySymbol), cb) || recur(type.symbol)); })); } } interface RelatedSymbol { - readonly symbol: Symbol; + readonly symbol: ts.Symbol; readonly kind: NodeEntryKind | undefined; } - function isStaticSymbol(symbol: Symbol): boolean { - if (!symbol.valueDeclaration) return false; - const modifierFlags = getEffectiveModifierFlags(symbol.valueDeclaration); - return !!(modifierFlags & ModifierFlags.Static); + function isStaticSymbol(symbol: ts.Symbol): boolean { + if (!symbol.valueDeclaration) + return false; + const modifierFlags = ts.getEffectiveModifierFlags(symbol.valueDeclaration); + return !!(modifierFlags & ts.ModifierFlags.Static); } - function getRelatedSymbol(search: Search, referenceSymbol: Symbol, referenceLocation: Node, state: State): RelatedSymbol | undefined { + function getRelatedSymbol(search: Search, referenceSymbol: ts.Symbol, referenceLocation: ts.Node, state: State): RelatedSymbol | undefined { const { checker } = state; return forEachRelatedSymbol(referenceSymbol, referenceLocation, checker, /*isForRenamePopulateSearchSymbolSet*/ false, - /*onlyIncludeBindingElementAtReferenceLocation*/ state.options.use !== FindReferencesUse.Rename || !!state.options.providePrefixAndSuffixTextForRename, - (sym, rootSymbol, baseSymbol, kind): RelatedSymbol | undefined => { + /*onlyIncludeBindingElementAtReferenceLocation*/ state.options.use !== FindReferencesUse.Rename || !!state.options.providePrefixAndSuffixTextForRename, (sym, rootSymbol, baseSymbol, kind): RelatedSymbol | undefined => { // check whether the symbol used to search itself is just the searched one. if (baseSymbol) { // static method/property and instance method/property might have the same name. Only check static or only check instance. @@ -2304,12 +2309,10 @@ namespace ts.FindAllReferences { } return search.includes(baseSymbol || rootSymbol || sym) // For a base type, use the symbol for the derived type. For a synthetic (e.g. union) property, use the union symbol. - ? { symbol: rootSymbol && !(getCheckFlags(sym) & CheckFlags.Synthetic) ? rootSymbol : sym, kind } + ? { symbol: rootSymbol && !(ts.getCheckFlags(sym) & ts.CheckFlags.Synthetic) ? rootSymbol : sym, kind } : undefined; }, - /*allowBaseTypes*/ rootSymbol => - !(search.parents && !search.parents.some(parent => explicitlyInheritsFrom(rootSymbol.parent!, parent, state.inheritsFromCache, checker))) - ); + /*allowBaseTypes*/ rootSymbol => !(search.parents && !search.parents.some(parent => explicitlyInheritsFrom(rootSymbol.parent!, parent, state.inheritsFromCache, checker)))); } /** @@ -2320,11 +2323,11 @@ namespace ts.FindAllReferences { * module, we want to keep the search limited to only types, as the two declarations (interface and uninstantiated module) * do not intersect in any of the three spaces. */ - export function getIntersectingMeaningFromDeclarations(node: Node, symbol: Symbol): SemanticMeaning { - let meaning = getMeaningFromLocation(node); + export function getIntersectingMeaningFromDeclarations(node: ts.Node, symbol: ts.Symbol): ts.SemanticMeaning { + let meaning = ts.getMeaningFromLocation(node); const { declarations } = symbol; if (declarations) { - let lastIterationMeaning: SemanticMeaning; + let lastIterationMeaning: ts.SemanticMeaning; do { // The result is order-sensitive, for instance if initialMeaning === Namespace, and declarations = [class, instantiated module] // we need to consider both as they initialMeaning intersects with the module in the namespace space, and the module @@ -2335,40 +2338,39 @@ namespace ts.FindAllReferences { lastIterationMeaning = meaning; for (const declaration of declarations) { - const declarationMeaning = getMeaningFromDeclaration(declaration); + const declarationMeaning = ts.getMeaningFromDeclaration(declaration); if (declarationMeaning & meaning) { meaning |= declarationMeaning; } } - } - while (meaning !== lastIterationMeaning); + } while (meaning !== lastIterationMeaning); } return meaning; } - function isImplementation(node: Node): boolean { - return !!(node.flags & NodeFlags.Ambient) ? !(isInterfaceDeclaration(node) || isTypeAliasDeclaration(node)) : - (isVariableLike(node) ? hasInitializer(node) : - isFunctionLikeDeclaration(node) ? !!node.body : - isClassLike(node) || isModuleOrEnumDeclaration(node)); + function isImplementation(node: ts.Node): boolean { + return !!(node.flags & ts.NodeFlags.Ambient) ? !(ts.isInterfaceDeclaration(node) || ts.isTypeAliasDeclaration(node)) : + (ts.isVariableLike(node) ? ts.hasInitializer(node) : + ts.isFunctionLikeDeclaration(node) ? !!node.body : + ts.isClassLike(node) || ts.isModuleOrEnumDeclaration(node)); } - export function getReferenceEntriesForShorthandPropertyAssignment(node: Node, checker: TypeChecker, addReference: (node: Node) => void): void { + export function getReferenceEntriesForShorthandPropertyAssignment(node: ts.Node, checker: ts.TypeChecker, addReference: (node: ts.Node) => void): void { const refSymbol = checker.getSymbolAtLocation(node)!; const shorthandSymbol = checker.getShorthandAssignmentValueSymbol(refSymbol.valueDeclaration); if (shorthandSymbol) { for (const declaration of shorthandSymbol.getDeclarations()!) { - if (getMeaningFromDeclaration(declaration) & SemanticMeaning.Value) { + if (ts.getMeaningFromDeclaration(declaration) & ts.SemanticMeaning.Value) { addReference(declaration); } } } } - function forEachDescendantOfKind(node: Node, kind: SyntaxKind, action: (node: Node) => void): void { - forEachChild(node, child => { + function forEachDescendantOfKind(node: ts.Node, kind: ts.SyntaxKind, action: (node: ts.Node) => void): void { + ts.forEachChild(node, child => { if (child.kind === kind) { action(child); } @@ -2377,8 +2379,8 @@ namespace ts.FindAllReferences { } /** Get `C` given `N` if `N` is in the position `class C extends N` or `class C extends foo.N` where `N` is an identifier. */ - function tryGetClassByExtendingIdentifier(node: Node): ClassLikeDeclaration | undefined { - return tryGetClassExtendingExpressionWithTypeArguments(climbPastPropertyAccess(node).parent); + function tryGetClassByExtendingIdentifier(node: ts.Node): ts.ClassLikeDeclaration | undefined { + return ts.tryGetClassExtendingExpressionWithTypeArguments(ts.climbPastPropertyAccess(node).parent); } /** @@ -2387,11 +2389,10 @@ namespace ts.FindAllReferences { * symbol may have a different parent symbol if the local type's symbol does not declare the property * being accessed (i.e. it is declared in some parent class or interface) */ - function getParentSymbolsOfPropertyAccess(location: Node, symbol: Symbol, checker: TypeChecker): readonly Symbol[] | undefined { - const propertyAccessExpression = isRightSideOfPropertyAccess(location) ? location.parent as PropertyAccessExpression : undefined; + function getParentSymbolsOfPropertyAccess(location: ts.Node, symbol: ts.Symbol, checker: ts.TypeChecker): readonly ts.Symbol[] | undefined { + const propertyAccessExpression = ts.isRightSideOfPropertyAccess(location) ? location.parent as ts.PropertyAccessExpression : undefined; const lhsType = propertyAccessExpression && checker.getTypeAtLocation(propertyAccessExpression.expression); - const res = mapDefined(lhsType && (lhsType.isUnionOrIntersection() ? lhsType.types : lhsType.symbol === symbol.parent ? undefined : [lhsType]), t => - t.symbol && t.symbol.flags & (SymbolFlags.Class | SymbolFlags.Interface) ? t.symbol : undefined); + const res = ts.mapDefined(lhsType && (lhsType.isUnionOrIntersection() ? lhsType.types : lhsType.symbol === symbol.parent ? undefined : [lhsType]), t => t.symbol && t.symbol.flags & (ts.SymbolFlags.Class | ts.SymbolFlags.Interface) ? t.symbol : undefined); return res.length === 0 ? undefined : res; } diff --git a/src/services/formatting/formatting.ts b/src/services/formatting/formatting.ts index b3e84023d175a..2f0f8ed401e91 100644 --- a/src/services/formatting/formatting.ts +++ b/src/services/formatting/formatting.ts @@ -1,16 +1,16 @@ /* @internal */ namespace ts.formatting { export interface FormatContext { - readonly options: FormatCodeSettings; - readonly getRules: RulesMap; - readonly host: FormattingHost; + readonly options: ts.FormatCodeSettings; + readonly getRules: ts.formatting.RulesMap; + readonly host: ts.FormattingHost; } - export interface TextRangeWithKind extends TextRange { + export interface TextRangeWithKind extends ts.TextRange { kind: T; } - export type TextRangeWithTriviaKind = TextRangeWithKind; + export type TextRangeWithTriviaKind = TextRangeWithKind; export interface TokenInfo { leadingTrivia: TextRangeWithTriviaKind[] | undefined; @@ -18,11 +18,11 @@ namespace ts.formatting { trailingTrivia: TextRangeWithTriviaKind[] | undefined; } - export function createTextRangeWithKind(pos: number, end: number, kind: T): TextRangeWithKind { + export function createTextRangeWithKind(pos: number, end: number, kind: T): TextRangeWithKind { const textRangeWithKind: TextRangeWithKind = { pos, end, kind }; - if (Debug.isDebugging) { + if (ts.Debug.isDebugging) { Object.defineProperty(textRangeWithKind, "__debugKind", { - get: () => Debug.formatSyntaxKind(kind), + get: () => ts.Debug.formatSyntaxKind(kind), }); } return textRangeWithKind; @@ -43,8 +43,8 @@ namespace ts.formatting { * the first token in line so it should be indented */ interface DynamicIndentation { - getIndentationForToken(tokenLine: number, tokenKind: SyntaxKind, container: Node, suppressDelta: boolean): number; - getIndentationForComment(owningToken: SyntaxKind, tokenIndentation: number, container: Node): number; + getIndentationForToken(tokenLine: number, tokenKind: ts.SyntaxKind, container: ts.Node, suppressDelta: boolean): number; + getIndentationForComment(owningToken: ts.SyntaxKind, tokenIndentation: number, container: ts.Node): number; /** * Indentation for open and close tokens of the node if it is block or another node that needs special indentation * ... { @@ -71,10 +71,10 @@ namespace ts.formatting { * Formatter calls this function when rule adds or deletes new lines from the text * so indentation scope can adjust values of indentation and delta. */ - recomputeIndentation(lineAddedByFormatting: boolean, parent: Node): void; + recomputeIndentation(lineAddedByFormatting: boolean, parent: ts.Node): void; } - export function formatOnEnter(position: number, sourceFile: SourceFile, formatContext: FormatContext): TextChange[] { + export function formatOnEnter(position: number, sourceFile: ts.SourceFile, formatContext: FormatContext): ts.TextChange[] { const line = sourceFile.getLineAndCharacterOfPosition(position).line; if (line === 0) { return []; @@ -84,32 +84,32 @@ namespace ts.formatting { // trailing whitespaces. So the end of the formatting span should be the later one between: // 1. the end of the previous line // 2. the last non-whitespace character in the current line - let endOfFormatSpan = getEndLinePosition(line, sourceFile); - while (isWhiteSpaceSingleLine(sourceFile.text.charCodeAt(endOfFormatSpan))) { + let endOfFormatSpan = ts.getEndLinePosition(line, sourceFile); + while (ts.isWhiteSpaceSingleLine(sourceFile.text.charCodeAt(endOfFormatSpan))) { endOfFormatSpan--; } // if the character at the end of the span is a line break, we shouldn't include it, because it indicates we don't want to // touch the current line at all. Also, on some OSes the line break consists of two characters (\r\n), we should test if the // previous character before the end of format span is line break character as well. - if (isLineBreak(sourceFile.text.charCodeAt(endOfFormatSpan))) { + if (ts.isLineBreak(sourceFile.text.charCodeAt(endOfFormatSpan))) { endOfFormatSpan--; } const span = { // get start position for the previous line - pos: getStartPositionOfLine(line - 1, sourceFile), + pos: ts.getStartPositionOfLine(line - 1, sourceFile), // end value is exclusive so add 1 to the result end: endOfFormatSpan + 1 }; - return formatSpan(span, sourceFile, formatContext, FormattingRequestKind.FormatOnEnter); + return formatSpan(span, sourceFile, formatContext, ts.formatting.FormattingRequestKind.FormatOnEnter); } - export function formatOnSemicolon(position: number, sourceFile: SourceFile, formatContext: FormatContext): TextChange[] { - const semicolon = findImmediatelyPrecedingTokenOfKind(position, SyntaxKind.SemicolonToken, sourceFile); - return formatNodeLines(findOutermostNodeWithinListLevel(semicolon), sourceFile, formatContext, FormattingRequestKind.FormatOnSemicolon); + export function formatOnSemicolon(position: number, sourceFile: ts.SourceFile, formatContext: FormatContext): ts.TextChange[] { + const semicolon = findImmediatelyPrecedingTokenOfKind(position, ts.SyntaxKind.SemicolonToken, sourceFile); + return formatNodeLines(findOutermostNodeWithinListLevel(semicolon), sourceFile, formatContext, ts.formatting.FormattingRequestKind.FormatOnSemicolon); } - export function formatOnOpeningCurly(position: number, sourceFile: SourceFile, formatContext: FormatContext): TextChange[] { - const openingCurly = findImmediatelyPrecedingTokenOfKind(position, SyntaxKind.OpenBraceToken, sourceFile); + export function formatOnOpeningCurly(position: number, sourceFile: ts.SourceFile, formatContext: FormatContext): ts.TextChange[] { + const openingCurly = findImmediatelyPrecedingTokenOfKind(position, ts.SyntaxKind.OpenBraceToken, sourceFile); if (!openingCurly) { return []; } @@ -128,42 +128,42 @@ namespace ts.formatting { * ``` * and we wouldn't want to move the closing brace. */ - const textRange: TextRange = { - pos: getLineStartPositionForPosition(outermostNode!.getStart(sourceFile), sourceFile), // TODO: GH#18217 + const textRange: ts.TextRange = { + pos: ts.getLineStartPositionForPosition(outermostNode!.getStart(sourceFile), sourceFile), end: position }; - return formatSpan(textRange, sourceFile, formatContext, FormattingRequestKind.FormatOnOpeningCurlyBrace); + return formatSpan(textRange, sourceFile, formatContext, ts.formatting.FormattingRequestKind.FormatOnOpeningCurlyBrace); } - export function formatOnClosingCurly(position: number, sourceFile: SourceFile, formatContext: FormatContext): TextChange[] { - const precedingToken = findImmediatelyPrecedingTokenOfKind(position, SyntaxKind.CloseBraceToken, sourceFile); - return formatNodeLines(findOutermostNodeWithinListLevel(precedingToken), sourceFile, formatContext, FormattingRequestKind.FormatOnClosingCurlyBrace); + export function formatOnClosingCurly(position: number, sourceFile: ts.SourceFile, formatContext: FormatContext): ts.TextChange[] { + const precedingToken = findImmediatelyPrecedingTokenOfKind(position, ts.SyntaxKind.CloseBraceToken, sourceFile); + return formatNodeLines(findOutermostNodeWithinListLevel(precedingToken), sourceFile, formatContext, ts.formatting.FormattingRequestKind.FormatOnClosingCurlyBrace); } - export function formatDocument(sourceFile: SourceFile, formatContext: FormatContext): TextChange[] { + export function formatDocument(sourceFile: ts.SourceFile, formatContext: FormatContext): ts.TextChange[] { const span = { pos: 0, end: sourceFile.text.length }; - return formatSpan(span, sourceFile, formatContext, FormattingRequestKind.FormatDocument); + return formatSpan(span, sourceFile, formatContext, ts.formatting.FormattingRequestKind.FormatDocument); } - export function formatSelection(start: number, end: number, sourceFile: SourceFile, formatContext: FormatContext): TextChange[] { + export function formatSelection(start: number, end: number, sourceFile: ts.SourceFile, formatContext: FormatContext): ts.TextChange[] { // format from the beginning of the line const span = { - pos: getLineStartPositionForPosition(start, sourceFile), + pos: ts.getLineStartPositionForPosition(start, sourceFile), end, }; - return formatSpan(span, sourceFile, formatContext, FormattingRequestKind.FormatSelection); + return formatSpan(span, sourceFile, formatContext, ts.formatting.FormattingRequestKind.FormatSelection); } /** * Validating `expectedTokenKind` ensures the token was typed in the context we expect (eg: not a comment). * @param expectedTokenKind The kind of the last token constituting the desired parent node. */ - function findImmediatelyPrecedingTokenOfKind(end: number, expectedTokenKind: SyntaxKind, sourceFile: SourceFile): Node | undefined { - const precedingToken = findPrecedingToken(end, sourceFile); + function findImmediatelyPrecedingTokenOfKind(end: number, expectedTokenKind: ts.SyntaxKind, sourceFile: ts.SourceFile): ts.Node | undefined { + const precedingToken = ts.findPrecedingToken(end, sourceFile); return precedingToken && precedingToken.kind === expectedTokenKind && end === precedingToken.getEnd() ? precedingToken : @@ -183,7 +183,7 @@ namespace ts.formatting { * Upon typing the closing curly, we want to format the entire `while`-statement, but not the preceding * variable declaration. */ - function findOutermostNodeWithinListLevel(node: Node | undefined) { + function findOutermostNodeWithinListLevel(node: ts.Node | undefined) { let current = node; while (current && current.parent && @@ -197,31 +197,31 @@ namespace ts.formatting { // Returns true if node is a element in some list in parent // i.e. parent is class declaration with the list of members and node is one of members. - function isListElement(parent: Node, node: Node): boolean { + function isListElement(parent: ts.Node, node: ts.Node): boolean { switch (parent.kind) { - case SyntaxKind.ClassDeclaration: - case SyntaxKind.InterfaceDeclaration: - return rangeContainsRange((parent as InterfaceDeclaration).members, node); - case SyntaxKind.ModuleDeclaration: - const body = (parent as ModuleDeclaration).body; - return !!body && body.kind === SyntaxKind.ModuleBlock && rangeContainsRange(body.statements, node); - case SyntaxKind.SourceFile: - case SyntaxKind.Block: - case SyntaxKind.ModuleBlock: - return rangeContainsRange((parent as Block).statements, node); - case SyntaxKind.CatchClause: - return rangeContainsRange((parent as CatchClause).block.statements, node); + case ts.SyntaxKind.ClassDeclaration: + case ts.SyntaxKind.InterfaceDeclaration: + return ts.rangeContainsRange((parent as ts.InterfaceDeclaration).members, node); + case ts.SyntaxKind.ModuleDeclaration: + const body = (parent as ts.ModuleDeclaration).body; + return !!body && body.kind === ts.SyntaxKind.ModuleBlock && ts.rangeContainsRange(body.statements, node); + case ts.SyntaxKind.SourceFile: + case ts.SyntaxKind.Block: + case ts.SyntaxKind.ModuleBlock: + return ts.rangeContainsRange((parent as ts.Block).statements, node); + case ts.SyntaxKind.CatchClause: + return ts.rangeContainsRange((parent as ts.CatchClause).block.statements, node); } return false; } /** find node that fully contains given text range */ - function findEnclosingNode(range: TextRange, sourceFile: SourceFile): Node { + function findEnclosingNode(range: ts.TextRange, sourceFile: ts.SourceFile): ts.Node { return find(sourceFile); - function find(n: Node): Node { - const candidate = forEachChild(n, c => startEndContainsRange(c.getStart(sourceFile), c.end, range) && c); + function find(n: ts.Node): ts.Node { + const candidate = ts.forEachChild(n, c => ts.startEndContainsRange(c.getStart(sourceFile), c.end, range) && c); if (candidate) { const result = find(candidate); if (result) { @@ -237,14 +237,14 @@ namespace ts.formatting { * This function will return a predicate that for a given text range will tell * if there are any parse errors that overlap with the range. */ - function prepareRangeContainsErrorFunction(errors: readonly Diagnostic[], originalRange: TextRange): (r: TextRange) => boolean { + function prepareRangeContainsErrorFunction(errors: readonly ts.Diagnostic[], originalRange: ts.TextRange): (r: ts.TextRange) => boolean { if (!errors.length) { return rangeHasNoErrors; } // pick only errors that fall in range const sorted = errors - .filter(d => rangeOverlapsWithStartEnd(originalRange, d.start!, d.start! + d.length!)) // TODO: GH#18217 + .filter(d => ts.rangeOverlapsWithStartEnd(originalRange, d.start!, d.start! + d.length!)) // TODO: GH#18217 .sort((e1, e2) => e1.start! - e2.start!); if (!sorted.length) { @@ -268,7 +268,7 @@ namespace ts.formatting { return false; } - if (startEndOverlapsWithStartEnd(r.pos, r.end, error.start!, error.start! + error.length!)) { + if (ts.startEndOverlapsWithStartEnd(r.pos, r.end, error.start!, error.start! + error.length!)) { // specified range overlaps with error range return true; } @@ -287,13 +287,13 @@ namespace ts.formatting { * This function will look for token that is located before the start of target range * and return its end as start position for the scanner. */ - function getScanStartPosition(enclosingNode: Node, originalRange: TextRange, sourceFile: SourceFile): number { + function getScanStartPosition(enclosingNode: ts.Node, originalRange: ts.TextRange, sourceFile: ts.SourceFile): number { const start = enclosingNode.getStart(sourceFile); if (start === originalRange.pos && enclosingNode.end === originalRange.end) { return start; } - const precedingToken = findPrecedingToken(originalRange.pos, sourceFile); + const precedingToken = ts.findPrecedingToken(originalRange.pos, sourceFile); if (!precedingToken) { // no preceding token found - start from the beginning of enclosing node return enclosingNode.pos; @@ -323,16 +323,16 @@ namespace ts.formatting { * if parent is on the different line - its delta was already contributed * to the initial indentation. */ - function getOwnOrInheritedDelta(n: Node, options: FormatCodeSettings, sourceFile: SourceFile): number { + function getOwnOrInheritedDelta(n: ts.Node, options: ts.FormatCodeSettings, sourceFile: ts.SourceFile): number { let previousLine = Constants.Unknown; - let child: Node | undefined; + let child: ts.Node | undefined; while (n) { const line = sourceFile.getLineAndCharacterOfPosition(n.getStart(sourceFile)).line; if (previousLine !== Constants.Unknown && line !== previousLine) { break; } - if (SmartIndenter.shouldIndentChildNode(options, n, child, sourceFile)) { + if (ts.formatting.SmartIndenter.shouldIndentChildNode(options, n, child, sourceFile)) { return options.indentSize!; } @@ -343,74 +343,42 @@ namespace ts.formatting { return 0; } - export function formatNodeGivenIndentation(node: Node, sourceFileLike: SourceFileLike, languageVariant: LanguageVariant, initialIndentation: number, delta: number, formatContext: FormatContext): TextChange[] { + export function formatNodeGivenIndentation(node: ts.Node, sourceFileLike: ts.SourceFileLike, languageVariant: ts.LanguageVariant, initialIndentation: number, delta: number, formatContext: FormatContext): ts.TextChange[] { const range = { pos: node.pos, end: node.end }; - return getFormattingScanner(sourceFileLike.text, languageVariant, range.pos, range.end, scanner => formatSpanWorker( - range, - node, - initialIndentation, - delta, - scanner, - formatContext, - FormattingRequestKind.FormatSelection, - _ => false, // assume that node does not have any errors + return ts.formatting.getFormattingScanner(sourceFileLike.text, languageVariant, range.pos, range.end, scanner => formatSpanWorker(range, node, initialIndentation, delta, scanner, formatContext, ts.formatting.FormattingRequestKind.FormatSelection, _ => false, // assume that node does not have any errors sourceFileLike)); } - function formatNodeLines(node: Node | undefined, sourceFile: SourceFile, formatContext: FormatContext, requestKind: FormattingRequestKind): TextChange[] { + function formatNodeLines(node: ts.Node | undefined, sourceFile: ts.SourceFile, formatContext: FormatContext, requestKind: ts.formatting.FormattingRequestKind): ts.TextChange[] { if (!node) { return []; } const span = { - pos: getLineStartPositionForPosition(node.getStart(sourceFile), sourceFile), + pos: ts.getLineStartPositionForPosition(node.getStart(sourceFile), sourceFile), end: node.end }; return formatSpan(span, sourceFile, formatContext, requestKind); } - function formatSpan(originalRange: TextRange, sourceFile: SourceFile, formatContext: FormatContext, requestKind: FormattingRequestKind): TextChange[] { + function formatSpan(originalRange: ts.TextRange, sourceFile: ts.SourceFile, formatContext: FormatContext, requestKind: ts.formatting.FormattingRequestKind): ts.TextChange[] { // find the smallest node that fully wraps the range and compute the initial indentation for the node const enclosingNode = findEnclosingNode(originalRange, sourceFile); - return getFormattingScanner( - sourceFile.text, - sourceFile.languageVariant, - getScanStartPosition(enclosingNode, originalRange, sourceFile), - originalRange.end, - scanner => formatSpanWorker( - originalRange, - enclosingNode, - SmartIndenter.getIndentationForNode(enclosingNode, originalRange, sourceFile, formatContext.options), - getOwnOrInheritedDelta(enclosingNode, formatContext.options, sourceFile), - scanner, - formatContext, - requestKind, - prepareRangeContainsErrorFunction(sourceFile.parseDiagnostics, originalRange), - sourceFile)); + return ts.formatting.getFormattingScanner(sourceFile.text, sourceFile.languageVariant, getScanStartPosition(enclosingNode, originalRange, sourceFile), originalRange.end, scanner => formatSpanWorker(originalRange, enclosingNode, ts.formatting.SmartIndenter.getIndentationForNode(enclosingNode, originalRange, sourceFile, formatContext.options), getOwnOrInheritedDelta(enclosingNode, formatContext.options, sourceFile), scanner, formatContext, requestKind, prepareRangeContainsErrorFunction(sourceFile.parseDiagnostics, originalRange), sourceFile)); } - - function formatSpanWorker( - originalRange: TextRange, - enclosingNode: Node, - initialIndentation: number, - delta: number, - formattingScanner: FormattingScanner, - { options, getRules, host }: FormatContext, - requestKind: FormattingRequestKind, - rangeContainsError: (r: TextRange) => boolean, - sourceFile: SourceFileLike): TextChange[] { + function formatSpanWorker(originalRange: ts.TextRange, enclosingNode: ts.Node, initialIndentation: number, delta: number, formattingScanner: ts.formatting.FormattingScanner, { options, getRules, host }: FormatContext, requestKind: ts.formatting.FormattingRequestKind, rangeContainsError: (r: ts.TextRange) => boolean, sourceFile: ts.SourceFileLike): ts.TextChange[] { // formatting context is used by rules provider - const formattingContext = new FormattingContext(sourceFile, requestKind, options); + const formattingContext = new ts.formatting.FormattingContext(sourceFile, requestKind, options); let previousRange: TextRangeWithKind; - let previousParent: Node; + let previousParent: ts.Node; let previousRangeStartLine: number; let lastIndentedLine: number; let indentationOnLastIndentedLine = Constants.Unknown; - const edits: TextChange[] = []; + const edits: ts.TextChange[] = []; formattingScanner.advance(); @@ -418,20 +386,19 @@ namespace ts.formatting { const startLine = sourceFile.getLineAndCharacterOfPosition(enclosingNode.getStart(sourceFile)).line; let undecoratedStartLine = startLine; if (enclosingNode.decorators) { - undecoratedStartLine = sourceFile.getLineAndCharacterOfPosition(getNonDecoratorTokenPosOfNode(enclosingNode, sourceFile)).line; + undecoratedStartLine = sourceFile.getLineAndCharacterOfPosition(ts.getNonDecoratorTokenPosOfNode(enclosingNode, sourceFile)).line; } processNode(enclosingNode, enclosingNode, startLine, undecoratedStartLine, initialIndentation, delta); } if (!formattingScanner.isOnToken()) { - const indentation = SmartIndenter.nodeWillIndentChild(options, enclosingNode, /*child*/ undefined, sourceFile, /*indentByDefault*/ false) + const indentation = ts.formatting.SmartIndenter.nodeWillIndentChild(options, enclosingNode, /*child*/ undefined, sourceFile, /*indentByDefault*/ false) ? initialIndentation + options.indentSize! : initialIndentation; const leadingTrivia = formattingScanner.getCurrentLeadingTrivia(); if (leadingTrivia) { - indentTriviaItems(leadingTrivia, indentation, /*indentNextTokenOrTrivia*/ false, - item => processRange(item, sourceFile.getLineAndCharacterOfPosition(item.pos), enclosingNode, enclosingNode, /*dynamicIndentation*/ undefined!)); + indentTriviaItems(leadingTrivia, indentation, /*indentNextTokenOrTrivia*/ false, item => processRange(item, sourceFile.getLineAndCharacterOfPosition(item.pos), enclosingNode, enclosingNode, /*dynamicIndentation*/ undefined!)); if (options.trimTrailingWhitespace !== false) { trimTrailingWhitespacesForRemainingRange(leadingTrivia); } @@ -439,21 +406,13 @@ namespace ts.formatting { } if (previousRange! && formattingScanner.getStartPos() >= originalRange.end) { - const tokenInfo = - formattingScanner.isOnEOF() ? formattingScanner.readEOFTokenRange() : + const tokenInfo = formattingScanner.isOnEOF() ? formattingScanner.readEOFTokenRange() : formattingScanner.isOnToken() ? formattingScanner.readTokenInfo(enclosingNode).token : undefined; if (tokenInfo) { - const parent = findPrecedingToken(tokenInfo.end, sourceFile, enclosingNode)?.parent || previousParent!; - processPair( - tokenInfo, - sourceFile.getLineAndCharacterOfPosition(tokenInfo.pos).line, - parent, - previousRange, - previousRangeStartLine!, - previousParent!, - parent, + const parent = ts.findPrecedingToken(tokenInfo.end, sourceFile, enclosingNode)?.parent || previousParent!; + processPair(tokenInfo, sourceFile.getLineAndCharacterOfPosition(tokenInfo.pos).line, parent, previousRange, previousRangeStartLine!, previousParent!, parent, /*dynamicIndentation*/ undefined); } } @@ -469,14 +428,9 @@ namespace ts.formatting { * If list element is in the range - its indentation will be equal * to inherited indentation from its predecessors. */ - function tryComputeIndentationForListItem(startPos: number, - endPos: number, - parentStartLine: number, - range: TextRange, - inheritedIndentation: number): number { - - if (rangeOverlapsWithStartEnd(range, startPos, endPos) || - rangeContainsStartEnd(range, startPos, endPos) /* Not to miss zero-range nodes e.g. JsxText */) { + function tryComputeIndentationForListItem(startPos: number, endPos: number, parentStartLine: number, range: ts.TextRange, inheritedIndentation: number): number { + if (ts.rangeOverlapsWithStartEnd(range, startPos, endPos) || + ts.rangeContainsStartEnd(range, startPos, endPos) /* Not to miss zero-range nodes e.g. JsxText */) { if (inheritedIndentation !== Constants.Unknown) { return inheritedIndentation; @@ -484,12 +438,12 @@ namespace ts.formatting { } else { const startLine = sourceFile.getLineAndCharacterOfPosition(startPos).line; - const startLinePosition = getLineStartPositionForPosition(startPos, sourceFile); - const column = SmartIndenter.findFirstNonWhitespaceColumn(startLinePosition, startPos, sourceFile, options); + const startLinePosition = ts.getLineStartPositionForPosition(startPos, sourceFile); + const column = ts.formatting.SmartIndenter.findFirstNonWhitespaceColumn(startLinePosition, startPos, sourceFile, options); if (startLine !== parentStartLine || startPos === column) { // Use the base indent size if it is greater than // the indentation of the inherited predecessor. - const baseIndentSize = SmartIndenter.getBaseIndentation(options); + const baseIndentSize = ts.formatting.SmartIndenter.getBaseIndentation(options); return baseIndentSize > column ? baseIndentSize : column; } } @@ -497,15 +451,11 @@ namespace ts.formatting { return Constants.Unknown; } - function computeIndentation( - node: TextRangeWithKind, - startLine: number, - inheritedIndentation: number, - parent: Node, - parentDynamicIndentation: DynamicIndentation, - effectiveParentStartLine: number - ): { indentation: number, delta: number; } { - const delta = SmartIndenter.shouldIndentChildNode(options, node) ? options.indentSize! : 0; + function computeIndentation(node: TextRangeWithKind, startLine: number, inheritedIndentation: number, parent: ts.Node, parentDynamicIndentation: DynamicIndentation, effectiveParentStartLine: number): { + indentation: number; + delta: number; + } { + const delta = ts.formatting.SmartIndenter.shouldIndentChildNode(options, node) ? options.indentSize! : 0; if (effectiveParentStartLine === startLine) { // if node is located on the same line with the parent @@ -517,16 +467,14 @@ namespace ts.formatting { }; } else if (inheritedIndentation === Constants.Unknown) { - if (node.kind === SyntaxKind.OpenParenToken && startLine === lastIndentedLine) { + if (node.kind === ts.SyntaxKind.OpenParenToken && startLine === lastIndentedLine) { // the is used for chaining methods formatting // - we need to get the indentation on last line and the delta of parent return { indentation: indentationOnLastIndentedLine, delta: parentDynamicIndentation.getDelta(node) }; } - else if ( - SmartIndenter.childStartsOnTheSameLineWithElseInIfStatement(parent, node, startLine, sourceFile) || - SmartIndenter.childIsUnindentedBranchOfConditionalExpression(parent, node, startLine, sourceFile) || - SmartIndenter.argumentStartsOnSameLineAsPreviousArgument(parent, node, startLine, sourceFile) - ) { + else if (ts.formatting.SmartIndenter.childStartsOnTheSameLineWithElseInIfStatement(parent, node, startLine, sourceFile) || + ts.formatting.SmartIndenter.childIsUnindentedBranchOfConditionalExpression(parent, node, startLine, sourceFile) || + ts.formatting.SmartIndenter.argumentStartsOnSameLineAsPreviousArgument(parent, node, startLine, sourceFile)) { return { indentation: parentDynamicIndentation.getIndentation(), delta }; } else { @@ -538,33 +486,33 @@ namespace ts.formatting { } } - function getFirstNonDecoratorTokenOfNode(node: Node) { + function getFirstNonDecoratorTokenOfNode(node: ts.Node) { if (node.modifiers && node.modifiers.length) { return node.modifiers[0].kind; } switch (node.kind) { - case SyntaxKind.ClassDeclaration: return SyntaxKind.ClassKeyword; - case SyntaxKind.InterfaceDeclaration: return SyntaxKind.InterfaceKeyword; - case SyntaxKind.FunctionDeclaration: return SyntaxKind.FunctionKeyword; - case SyntaxKind.EnumDeclaration: return SyntaxKind.EnumDeclaration; - case SyntaxKind.GetAccessor: return SyntaxKind.GetKeyword; - case SyntaxKind.SetAccessor: return SyntaxKind.SetKeyword; - case SyntaxKind.MethodDeclaration: - if ((node as MethodDeclaration).asteriskToken) { - return SyntaxKind.AsteriskToken; + case ts.SyntaxKind.ClassDeclaration: return ts.SyntaxKind.ClassKeyword; + case ts.SyntaxKind.InterfaceDeclaration: return ts.SyntaxKind.InterfaceKeyword; + case ts.SyntaxKind.FunctionDeclaration: return ts.SyntaxKind.FunctionKeyword; + case ts.SyntaxKind.EnumDeclaration: return ts.SyntaxKind.EnumDeclaration; + case ts.SyntaxKind.GetAccessor: return ts.SyntaxKind.GetKeyword; + case ts.SyntaxKind.SetAccessor: return ts.SyntaxKind.SetKeyword; + case ts.SyntaxKind.MethodDeclaration: + if ((node as ts.MethodDeclaration).asteriskToken) { + return ts.SyntaxKind.AsteriskToken; } // falls through - case SyntaxKind.PropertyDeclaration: - case SyntaxKind.Parameter: - const name = getNameOfDeclaration(node as Declaration); + case ts.SyntaxKind.PropertyDeclaration: + case ts.SyntaxKind.Parameter: + const name = ts.getNameOfDeclaration(node as ts.Declaration); if (name) { return name.kind; } } } - function getDynamicIndentation(node: Node, nodeStartLine: number, indentation: number, delta: number): DynamicIndentation { + function getDynamicIndentation(node: ts.Node, nodeStartLine: number, indentation: number, delta: number): DynamicIndentation { return { getIndentationForComment: (kind, tokenIndentation, container) => { switch (kind) { @@ -572,9 +520,9 @@ namespace ts.formatting { // .. { // // comment // } - case SyntaxKind.CloseBraceToken: - case SyntaxKind.CloseBracketToken: - case SyntaxKind.CloseParenToken: + case ts.SyntaxKind.CloseBraceToken: + case ts.SyntaxKind.CloseBracketToken: + case ts.SyntaxKind.CloseParenToken: return indentation + getDelta(container); } return tokenIndentation !== Constants.Unknown ? tokenIndentation : indentation; @@ -589,41 +537,40 @@ namespace ts.formatting { // vs // var a = xValue // > yValue; - getIndentationForToken: (line, kind, container, suppressDelta) => - !suppressDelta && shouldAddDelta(line, kind, container) ? indentation + getDelta(container) : indentation, + getIndentationForToken: (line, kind, container, suppressDelta) => !suppressDelta && shouldAddDelta(line, kind, container) ? indentation + getDelta(container) : indentation, getIndentation: () => indentation, getDelta, recomputeIndentation: (lineAdded, parent) => { - if (SmartIndenter.shouldIndentChildNode(options, parent, node, sourceFile)) { + if (ts.formatting.SmartIndenter.shouldIndentChildNode(options, parent, node, sourceFile)) { indentation += lineAdded ? options.indentSize! : -options.indentSize!; - delta = SmartIndenter.shouldIndentChildNode(options, node) ? options.indentSize! : 0; + delta = ts.formatting.SmartIndenter.shouldIndentChildNode(options, node) ? options.indentSize! : 0; } } }; - function shouldAddDelta(line: number, kind: SyntaxKind, container: Node): boolean { + function shouldAddDelta(line: number, kind: ts.SyntaxKind, container: ts.Node): boolean { switch (kind) { // open and close brace, 'else' and 'while' (in do statement) tokens has indentation of the parent - case SyntaxKind.OpenBraceToken: - case SyntaxKind.CloseBraceToken: - case SyntaxKind.CloseParenToken: - case SyntaxKind.ElseKeyword: - case SyntaxKind.WhileKeyword: - case SyntaxKind.AtToken: + case ts.SyntaxKind.OpenBraceToken: + case ts.SyntaxKind.CloseBraceToken: + case ts.SyntaxKind.CloseParenToken: + case ts.SyntaxKind.ElseKeyword: + case ts.SyntaxKind.WhileKeyword: + case ts.SyntaxKind.AtToken: return false; - case SyntaxKind.SlashToken: - case SyntaxKind.GreaterThanToken: + case ts.SyntaxKind.SlashToken: + case ts.SyntaxKind.GreaterThanToken: switch (container.kind) { - case SyntaxKind.JsxOpeningElement: - case SyntaxKind.JsxClosingElement: - case SyntaxKind.JsxSelfClosingElement: - case SyntaxKind.ExpressionWithTypeArguments: + case ts.SyntaxKind.JsxOpeningElement: + case ts.SyntaxKind.JsxClosingElement: + case ts.SyntaxKind.JsxSelfClosingElement: + case ts.SyntaxKind.ExpressionWithTypeArguments: return false; } break; - case SyntaxKind.OpenBracketToken: - case SyntaxKind.CloseBracketToken: - if (container.kind !== SyntaxKind.MappedType) { + case ts.SyntaxKind.OpenBracketToken: + case ts.SyntaxKind.CloseBracketToken: + if (container.kind !== ts.SyntaxKind.MappedType) { return false; } break; @@ -636,12 +583,12 @@ namespace ts.formatting { function getDelta(child: TextRangeWithKind) { // Delta value should be zero when the node explicitly prevents indentation of the child node - return SmartIndenter.nodeWillIndentChild(options, node, child, sourceFile, /*indentByDefault*/ true) ? delta : 0; + return ts.formatting.SmartIndenter.nodeWillIndentChild(options, node, child, sourceFile, /*indentByDefault*/ true) ? delta : 0; } } - function processNode(node: Node, contextNode: Node, nodeStartLine: number, undecoratedNodeStartLine: number, indentation: number, delta: number) { - if (!rangeOverlapsWithStartEnd(originalRange, node.getStart(sourceFile), node.getEnd())) { + function processNode(node: ts.Node, contextNode: ts.Node, nodeStartLine: number, undecoratedNodeStartLine: number, indentation: number, delta: number) { + if (!ts.rangeOverlapsWithStartEnd(originalRange, node.getStart(sourceFile), node.getEnd())) { return; } @@ -663,12 +610,9 @@ namespace ts.formatting { // if there are any tokens that logically belong to node and interleave child nodes // such tokens will be consumed in processChildNode for the child that follows them - forEachChild( - node, - child => { + ts.forEachChild(node, child => { processChildNode(child, /*inheritedIndentation*/ Constants.Unknown, node, nodeDynamicIndentation, nodeStartLine, undecoratedNodeStartLine, /*isListItem*/ false); - }, - nodes => { + }, nodes => { processChildNodes(nodes, node, nodeStartLine, nodeDynamicIndentation); }); @@ -681,17 +625,8 @@ namespace ts.formatting { consumeTokenAndAdvanceScanner(tokenInfo, node, nodeDynamicIndentation, node); } - function processChildNode( - child: Node, - inheritedIndentation: number, - parent: Node, - parentDynamicIndentation: DynamicIndentation, - parentStartLine: number, - undecoratedParentStartLine: number, - isListItem: boolean, - isFirstListItem?: boolean): number { - - if (nodeIsMissing(child)) { + function processChildNode(child: ts.Node, inheritedIndentation: number, parent: ts.Node, parentDynamicIndentation: DynamicIndentation, parentStartLine: number, undecoratedParentStartLine: number, isListItem: boolean, isFirstListItem?: boolean): number { + if (ts.nodeIsMissing(child)) { return inheritedIndentation; } @@ -701,13 +636,13 @@ namespace ts.formatting { let undecoratedChildStartLine = childStartLine; if (child.decorators) { - undecoratedChildStartLine = sourceFile.getLineAndCharacterOfPosition(getNonDecoratorTokenPosOfNode(child, sourceFile)).line; + undecoratedChildStartLine = sourceFile.getLineAndCharacterOfPosition(ts.getNonDecoratorTokenPosOfNode(child, sourceFile)).line; } // if child is a list item - try to get its indentation, only if parent is within the original range. let childIndentationAmount = Constants.Unknown; - if (isListItem && rangeContainsRange(originalRange, parent)) { + if (isListItem && ts.rangeContainsRange(originalRange, parent)) { childIndentationAmount = tryComputeIndentationForListItem(childStartPos, child.end, parentStartLine, originalRange, inheritedIndentation); if (childIndentationAmount !== Constants.Unknown) { inheritedIndentation = childIndentationAmount; @@ -715,7 +650,7 @@ namespace ts.formatting { } // child node is outside the target range - do not dive inside - if (!rangeOverlapsWithStartEnd(originalRange, child.pos, child.end)) { + if (!ts.rangeOverlapsWithStartEnd(originalRange, child.pos, child.end)) { if (child.end < originalRange.pos) { formattingScanner.skipToEndOf(child); } @@ -747,50 +682,47 @@ namespace ts.formatting { return inheritedIndentation; } - if (isToken(child)) { + if (ts.isToken(child)) { // if child node is a token, it does not impact indentation, proceed it using parent indentation scope rules const tokenInfo = formattingScanner.readTokenInfo(child); // JSX text shouldn't affect indenting - if (child.kind !== SyntaxKind.JsxText) { - Debug.assert(tokenInfo.token.end === child.end, "Token end is child end"); + if (child.kind !== ts.SyntaxKind.JsxText) { + ts.Debug.assert(tokenInfo.token.end === child.end, "Token end is child end"); consumeTokenAndAdvanceScanner(tokenInfo, node, parentDynamicIndentation, child); return inheritedIndentation; } } - const effectiveParentStartLine = child.kind === SyntaxKind.Decorator ? childStartLine : undecoratedParentStartLine; + const effectiveParentStartLine = child.kind === ts.SyntaxKind.Decorator ? childStartLine : undecoratedParentStartLine; const childIndentation = computeIndentation(child, childStartLine, childIndentationAmount, node, parentDynamicIndentation, effectiveParentStartLine); processNode(child, childContextNode, childStartLine, undecoratedChildStartLine, childIndentation.indentation, childIndentation.delta); childContextNode = node; - if (isFirstListItem && parent.kind === SyntaxKind.ArrayLiteralExpression && inheritedIndentation === Constants.Unknown) { + if (isFirstListItem && parent.kind === ts.SyntaxKind.ArrayLiteralExpression && inheritedIndentation === Constants.Unknown) { inheritedIndentation = childIndentation.indentation; } return inheritedIndentation; } - function processChildNodes(nodes: NodeArray, - parent: Node, - parentStartLine: number, - parentDynamicIndentation: DynamicIndentation): void { - Debug.assert(isNodeArray(nodes)); + function processChildNodes(nodes: ts.NodeArray, parent: ts.Node, parentStartLine: number, parentDynamicIndentation: DynamicIndentation): void { + ts.Debug.assert(ts.isNodeArray(nodes)); const listStartToken = getOpenTokenForList(parent, nodes); let listDynamicIndentation = parentDynamicIndentation; let startLine = parentStartLine; // node range is outside the target range - do not dive inside - if (!rangeOverlapsWithStartEnd(originalRange, nodes.pos, nodes.end)) { + if (!ts.rangeOverlapsWithStartEnd(originalRange, nodes.pos, nodes.end)) { if (nodes.end < originalRange.pos) { formattingScanner.skipToEndOf(nodes); } return; } - if (listStartToken !== SyntaxKind.Unknown) { + if (listStartToken !== ts.SyntaxKind.Unknown) { // introduce a new indentation scope for lists (including list start and end tokens) while (formattingScanner.isOnToken() && formattingScanner.getStartPos() < originalRange.end) { const tokenInfo = formattingScanner.readTokenInfo(parent); @@ -813,8 +745,8 @@ namespace ts.formatting { indentationOnListStartToken = indentationOnLastIndentedLine; } else { - const startLinePosition = getLineStartPositionForPosition(tokenInfo.token.pos, sourceFile); - indentationOnListStartToken = SmartIndenter.findFirstNonWhitespaceColumn(startLinePosition, tokenInfo.token.pos, sourceFile, options); + const startLinePosition = ts.getLineStartPositionForPosition(tokenInfo.token.pos, sourceFile); + indentationOnListStartToken = ts.formatting.SmartIndenter.findFirstNonWhitespaceColumn(startLinePosition, tokenInfo.token.pos, sourceFile, options); } listDynamicIndentation = getDynamicIndentation(parent, parentStartLine, indentationOnListStartToken, options.indentSize!); // TODO: GH#18217 @@ -833,9 +765,9 @@ namespace ts.formatting { } const listEndToken = getCloseTokenForOpenToken(listStartToken); - if (listEndToken !== SyntaxKind.Unknown && formattingScanner.isOnToken() && formattingScanner.getStartPos() < originalRange.end) { + if (listEndToken !== ts.SyntaxKind.Unknown && formattingScanner.isOnToken() && formattingScanner.getStartPos() < originalRange.end) { let tokenInfo: TokenInfo | undefined = formattingScanner.readTokenInfo(parent); - if (tokenInfo.token.kind === SyntaxKind.CommaToken && isCallLikeExpression(parent)) { + if (tokenInfo.token.kind === ts.SyntaxKind.CommaToken && ts.isCallLikeExpression(parent)) { const commaTokenLine = sourceFile.getLineAndCharacterOfPosition(tokenInfo.token.pos).line; if (startLine !== commaTokenLine) { formattingScanner.advance(); @@ -847,15 +779,15 @@ namespace ts.formatting { // there might be the case when current token matches end token but does not considered as one // function (x: function) <-- // without this check close paren will be interpreted as list end token for function expression which is wrong - if (tokenInfo && tokenInfo.token.kind === listEndToken && rangeContainsRange(parent, tokenInfo.token)) { + if (tokenInfo && tokenInfo.token.kind === listEndToken && ts.rangeContainsRange(parent, tokenInfo.token)) { // consume list end token consumeTokenAndAdvanceScanner(tokenInfo, parent, listDynamicIndentation, parent, /*isListEndToken*/ true); } } } - function consumeTokenAndAdvanceScanner(currentTokenInfo: TokenInfo, parent: Node, dynamicIndentation: DynamicIndentation, container: Node, isListEndToken?: boolean): void { - Debug.assert(rangeContainsRange(parent, currentTokenInfo.token)); + function consumeTokenAndAdvanceScanner(currentTokenInfo: TokenInfo, parent: ts.Node, dynamicIndentation: DynamicIndentation, container: ts.Node, isListEndToken?: boolean): void { + ts.Debug.assert(ts.rangeContainsRange(parent, currentTokenInfo.token)); const lastTriviaWasNewLine = formattingScanner.lastTrailingTriviaWasNewLine(); let indentToken = false; @@ -865,7 +797,7 @@ namespace ts.formatting { } let lineAction = LineAction.None; - const isTokenInRange = rangeContainsRange(originalRange, currentTokenInfo.token); + const isTokenInRange = ts.rangeContainsRange(originalRange, currentTokenInfo.token); const tokenStart = sourceFile.getLineAndCharacterOfPosition(currentTokenInfo.token.pos); if (isTokenInRange) { @@ -898,8 +830,7 @@ namespace ts.formatting { let indentNextTokenOrTrivia = true; if (currentTokenInfo.leadingTrivia) { const commentIndentation = dynamicIndentation.getIndentationForComment(currentTokenInfo.token.kind, tokenIndentation, container); - indentNextTokenOrTrivia = indentTriviaItems(currentTokenInfo.leadingTrivia, commentIndentation, indentNextTokenOrTrivia, - item => insertIndentation(item.pos, commentIndentation, /*lineAdded*/ false)); + indentNextTokenOrTrivia = indentTriviaItems(currentTokenInfo.leadingTrivia, commentIndentation, indentNextTokenOrTrivia, item => insertIndentation(item.pos, commentIndentation, /*lineAdded*/ false)); } // indent token only if is it is in target range and does not overlap with any error ranges @@ -917,27 +848,23 @@ namespace ts.formatting { } } - function indentTriviaItems( - trivia: TextRangeWithKind[], - commentIndentation: number, - indentNextTokenOrTrivia: boolean, - indentSingleLine: (item: TextRangeWithKind) => void) { + function indentTriviaItems(trivia: TextRangeWithKind[], commentIndentation: number, indentNextTokenOrTrivia: boolean, indentSingleLine: (item: TextRangeWithKind) => void) { for (const triviaItem of trivia) { - const triviaInRange = rangeContainsRange(originalRange, triviaItem); + const triviaInRange = ts.rangeContainsRange(originalRange, triviaItem); switch (triviaItem.kind) { - case SyntaxKind.MultiLineCommentTrivia: + case ts.SyntaxKind.MultiLineCommentTrivia: if (triviaInRange) { indentMultilineComment(triviaItem, commentIndentation, /*firstLineIsIndented*/ !indentNextTokenOrTrivia); } indentNextTokenOrTrivia = false; break; - case SyntaxKind.SingleLineCommentTrivia: + case ts.SyntaxKind.SingleLineCommentTrivia: if (indentNextTokenOrTrivia && triviaInRange) { indentSingleLine(triviaItem); } indentNextTokenOrTrivia = false; break; - case SyntaxKind.NewLineTrivia: + case ts.SyntaxKind.NewLineTrivia: indentNextTokenOrTrivia = true; break; } @@ -945,20 +872,16 @@ namespace ts.formatting { return indentNextTokenOrTrivia; } - function processTrivia(trivia: TextRangeWithKind[], parent: Node, contextNode: Node, dynamicIndentation: DynamicIndentation): void { + function processTrivia(trivia: TextRangeWithKind[], parent: ts.Node, contextNode: ts.Node, dynamicIndentation: DynamicIndentation): void { for (const triviaItem of trivia) { - if (isComment(triviaItem.kind) && rangeContainsRange(originalRange, triviaItem)) { + if (ts.isComment(triviaItem.kind) && ts.rangeContainsRange(originalRange, triviaItem)) { const triviaItemStart = sourceFile.getLineAndCharacterOfPosition(triviaItem.pos); processRange(triviaItem, triviaItemStart, parent, contextNode, dynamicIndentation); } } } - function processRange(range: TextRangeWithKind, - rangeStart: LineAndCharacter, - parent: Node, - contextNode: Node, - dynamicIndentation: DynamicIndentation): LineAction { + function processRange(range: TextRangeWithKind, rangeStart: ts.LineAndCharacter, parent: ts.Node, contextNode: ts.Node, dynamicIndentation: DynamicIndentation): LineAction { const rangeHasError = rangeContainsError(range); let lineAction = LineAction.None; @@ -981,14 +904,7 @@ namespace ts.formatting { return lineAction; } - function processPair(currentItem: TextRangeWithKind, - currentStartLine: number, - currentParent: Node, - previousItem: TextRangeWithKind, - previousStartLine: number, - previousParent: Node, - contextNode: Node, - dynamicIndentation: DynamicIndentation | undefined): LineAction { + function processPair(currentItem: TextRangeWithKind, currentStartLine: number, currentParent: ts.Node, previousItem: TextRangeWithKind, previousStartLine: number, previousParent: ts.Node, contextNode: ts.Node, dynamicIndentation: DynamicIndentation | undefined): LineAction { formattingContext.updateContext(previousItem, previousParent, currentItem, currentParent, contextNode); @@ -999,7 +915,7 @@ namespace ts.formatting { if (rules) { // Apply rules in reverse order so that higher priority rules (which are first in the array) // win in a conflict with lower priority rules. - forEachRight(rules, rule => { + ts.forEachRight(rules, rule => { lineAction = applyRuleEdits(rule, previousItem, previousStartLine, currentItem, currentStartLine); if (dynamicIndentation) { switch (lineAction) { @@ -1019,16 +935,16 @@ namespace ts.formatting { } break; default: - Debug.assert(lineAction === LineAction.None); + ts.Debug.assert(lineAction === LineAction.None); } } // We need to trim trailing whitespace between the tokens if they were on different lines, and no rule was applied to put them on the same line - trimTrailingWhitespaces = trimTrailingWhitespaces && !(rule.action & RuleAction.DeleteSpace) && rule.flags !== RuleFlags.CanDeleteNewLines; + trimTrailingWhitespaces = trimTrailingWhitespaces && !(rule.action & ts.formatting.RuleAction.DeleteSpace) && rule.flags !== ts.formatting.RuleFlags.CanDeleteNewLines; }); } else { - trimTrailingWhitespaces = trimTrailingWhitespaces && currentItem.kind !== SyntaxKind.EndOfFileToken; + trimTrailingWhitespaces = trimTrailingWhitespaces && currentItem.kind !== ts.SyntaxKind.EndOfFileToken; } if (currentStartLine !== previousStartLine && trimTrailingWhitespaces) { @@ -1048,7 +964,7 @@ namespace ts.formatting { } else { const tokenStart = sourceFile.getLineAndCharacterOfPosition(pos); - const startLinePosition = getStartPositionOfLine(tokenStart.line, sourceFile); + const startLinePosition = ts.getStartPositionOfLine(tokenStart.line, sourceFile); if (indentation !== characterToColumn(startLinePosition, tokenStart.character) || indentationIsDifferent(indentationString, startLinePosition)) { recordReplace(startLinePosition, tokenStart.character, indentationString); } @@ -1058,7 +974,7 @@ namespace ts.formatting { function characterToColumn(startLinePosition: number, characterInLine: number): number { let column = 0; for (let i = 0; i < characterInLine; i++) { - if (sourceFile.text.charCodeAt(startLinePosition + i) === CharacterCodes.tab) { + if (sourceFile.text.charCodeAt(startLinePosition + i) === ts.CharacterCodes.tab) { column += options.tabSize! - column % options.tabSize!; } else { @@ -1072,7 +988,7 @@ namespace ts.formatting { return indentationString !== sourceFile.text.substr(startLinePosition, indentationString.length); } - function indentMultilineComment(commentRange: TextRange, indentation: number, firstLineIsIndented: boolean, indentFinalLine = true) { + function indentMultilineComment(commentRange: ts.TextRange, indentation: number, firstLineIsIndented: boolean, indentFinalLine = true) { // split comment in lines let startLine = sourceFile.getLineAndCharacterOfPosition(commentRange.pos).line; const endLine = sourceFile.getLineAndCharacterOfPosition(commentRange.end).line; @@ -1084,24 +1000,22 @@ namespace ts.formatting { return; } - const parts: TextRange[] = []; + const parts: ts.TextRange[] = []; let startPos = commentRange.pos; for (let line = startLine; line < endLine; line++) { - const endOfLine = getEndLinePosition(line, sourceFile); + const endOfLine = ts.getEndLinePosition(line, sourceFile); parts.push({ pos: startPos, end: endOfLine }); - startPos = getStartPositionOfLine(line + 1, sourceFile); + startPos = ts.getStartPositionOfLine(line + 1, sourceFile); } if (indentFinalLine) { parts.push({ pos: startPos, end: commentRange.end }); } - if (parts.length === 0) return; - - const startLinePos = getStartPositionOfLine(startLine, sourceFile); - - const nonWhitespaceColumnInFirstPart = - SmartIndenter.findFirstNonWhitespaceCharacterAndColumn(startLinePos, parts[0].pos, sourceFile, options); + if (parts.length === 0) + return; + const startLinePos = ts.getStartPositionOfLine(startLine, sourceFile); + const nonWhitespaceColumnInFirstPart = ts.formatting.SmartIndenter.findFirstNonWhitespaceCharacterAndColumn(startLinePos, parts[0].pos, sourceFile, options); let startIndex = 0; if (firstLineIsIndented) { @@ -1112,11 +1026,10 @@ namespace ts.formatting { // shift all parts on the delta size const delta = indentation - nonWhitespaceColumnInFirstPart.column; for (let i = startIndex; i < parts.length; i++ , startLine++) { - const startLinePos = getStartPositionOfLine(startLine, sourceFile); - const nonWhitespaceCharacterAndColumn = - i === 0 + const startLinePos = ts.getStartPositionOfLine(startLine, sourceFile); + const nonWhitespaceCharacterAndColumn = i === 0 ? nonWhitespaceColumnInFirstPart - : SmartIndenter.findFirstNonWhitespaceCharacterAndColumn(parts[i].pos, parts[i].end, sourceFile, options); + : ts.formatting.SmartIndenter.findFirstNonWhitespaceCharacterAndColumn(parts[i].pos, parts[i].end, sourceFile, options); const newIndentation = nonWhitespaceCharacterAndColumn.column + delta; if (newIndentation > 0) { const indentationString = getIndentationString(newIndentation, options); @@ -1130,17 +1043,17 @@ namespace ts.formatting { function trimTrailingWhitespacesForLines(line1: number, line2: number, range?: TextRangeWithKind) { for (let line = line1; line < line2; line++) { - const lineStartPosition = getStartPositionOfLine(line, sourceFile); - const lineEndPosition = getEndLinePosition(line, sourceFile); + const lineStartPosition = ts.getStartPositionOfLine(line, sourceFile); + const lineEndPosition = ts.getEndLinePosition(line, sourceFile); // do not trim whitespaces in comments or template expression - if (range && (isComment(range.kind) || isStringOrRegularExpressionOrTemplateLiteral(range.kind)) && range.pos <= lineEndPosition && range.end > lineEndPosition) { + if (range && (ts.isComment(range.kind) || ts.isStringOrRegularExpressionOrTemplateLiteral(range.kind)) && range.pos <= lineEndPosition && range.end > lineEndPosition) { continue; } const whitespaceStart = getTrailingWhitespaceStartPosition(lineStartPosition, lineEndPosition); if (whitespaceStart !== -1) { - Debug.assert(whitespaceStart === lineStartPosition || !isWhiteSpaceSingleLine(sourceFile.text.charCodeAt(whitespaceStart - 1))); + ts.Debug.assert(whitespaceStart === lineStartPosition || !ts.isWhiteSpaceSingleLine(sourceFile.text.charCodeAt(whitespaceStart - 1))); recordDelete(whitespaceStart, lineEndPosition + 1 - whitespaceStart); } } @@ -1152,7 +1065,7 @@ namespace ts.formatting { */ function getTrailingWhitespaceStartPosition(start: number, end: number) { let pos = end; - while (pos >= start && isWhiteSpaceSingleLine(sourceFile.text.charCodeAt(pos))) { + while (pos >= start && ts.isWhiteSpaceSingleLine(sourceFile.text.charCodeAt(pos))) { pos--; } if (pos !== end) { @@ -1165,10 +1078,10 @@ namespace ts.formatting { * Trimming will be done for lines after the previous range. * Exclude comments as they had been previously processed. */ - function trimTrailingWhitespacesForRemainingRange(trivias: TextRangeWithKind[]) { + function trimTrailingWhitespacesForRemainingRange(trivias: TextRangeWithKind[]) { let startPos = previousRange ? previousRange.end : originalRange.pos; for (const trivia of trivias) { - if (isComment(trivia.kind)) { + if (ts.isComment(trivia.kind)) { if (startPos < trivia.pos) { trimTrailingWitespacesForPositions(startPos, trivia.pos - 1, previousRange); } @@ -1191,104 +1104,99 @@ namespace ts.formatting { function recordDelete(start: number, len: number) { if (len) { - edits.push(createTextChangeFromStartLength(start, len, "")); + edits.push(ts.createTextChangeFromStartLength(start, len, "")); } } function recordReplace(start: number, len: number, newText: string) { if (len || newText) { - edits.push(createTextChangeFromStartLength(start, len, newText)); + edits.push(ts.createTextChangeFromStartLength(start, len, newText)); } } function recordInsert(start: number, text: string) { if (text) { - edits.push(createTextChangeFromStartLength(start, 0, text)); + edits.push(ts.createTextChangeFromStartLength(start, 0, text)); } } - function applyRuleEdits(rule: Rule, - previousRange: TextRangeWithKind, - previousStartLine: number, - currentRange: TextRangeWithKind, - currentStartLine: number - ): LineAction { + function applyRuleEdits(rule: ts.formatting.Rule, previousRange: TextRangeWithKind, previousStartLine: number, currentRange: TextRangeWithKind, currentStartLine: number): LineAction { const onLaterLine = currentStartLine !== previousStartLine; switch (rule.action) { - case RuleAction.StopProcessingSpaceActions: + case ts.formatting.RuleAction.StopProcessingSpaceActions: // no action required return LineAction.None; - case RuleAction.DeleteSpace: + case ts.formatting.RuleAction.DeleteSpace: if (previousRange.end !== currentRange.pos) { // delete characters starting from t1.end up to t2.pos exclusive recordDelete(previousRange.end, currentRange.pos - previousRange.end); return onLaterLine ? LineAction.LineRemoved : LineAction.None; } break; - case RuleAction.DeleteToken: + case ts.formatting.RuleAction.DeleteToken: recordDelete(previousRange.pos, previousRange.end - previousRange.pos); break; - case RuleAction.InsertNewLine: + case ts.formatting.RuleAction.InsertNewLine: // exit early if we on different lines and rule cannot change number of newlines // if line1 and line2 are on subsequent lines then no edits are required - ok to exit // if line1 and line2 are separated with more than one newline - ok to exit since we cannot delete extra new lines - if (rule.flags !== RuleFlags.CanDeleteNewLines && previousStartLine !== currentStartLine) { + if (rule.flags !== ts.formatting.RuleFlags.CanDeleteNewLines && previousStartLine !== currentStartLine) { return LineAction.None; } // edit should not be applied if we have one line feed between elements const lineDelta = currentStartLine - previousStartLine; if (lineDelta !== 1) { - recordReplace(previousRange.end, currentRange.pos - previousRange.end, getNewLineOrDefaultFromHost(host, options)); + recordReplace(previousRange.end, currentRange.pos - previousRange.end, ts.getNewLineOrDefaultFromHost(host, options)); return onLaterLine ? LineAction.None : LineAction.LineAdded; } break; - case RuleAction.InsertSpace: + case ts.formatting.RuleAction.InsertSpace: // exit early if we on different lines and rule cannot change number of newlines - if (rule.flags !== RuleFlags.CanDeleteNewLines && previousStartLine !== currentStartLine) { + if (rule.flags !== ts.formatting.RuleFlags.CanDeleteNewLines && previousStartLine !== currentStartLine) { return LineAction.None; } const posDelta = currentRange.pos - previousRange.end; - if (posDelta !== 1 || sourceFile.text.charCodeAt(previousRange.end) !== CharacterCodes.space) { + if (posDelta !== 1 || sourceFile.text.charCodeAt(previousRange.end) !== ts.CharacterCodes.space) { recordReplace(previousRange.end, currentRange.pos - previousRange.end, " "); return onLaterLine ? LineAction.LineRemoved : LineAction.None; } break; - case RuleAction.InsertTrailingSemicolon: + case ts.formatting.RuleAction.InsertTrailingSemicolon: recordInsert(previousRange.end, ";"); } return LineAction.None; } } - const enum LineAction { None, LineAdded, LineRemoved } + const enum LineAction { + None, + LineAdded, + LineRemoved + } /** * @param precedingToken pass `null` if preceding token was already computed and result was `undefined`. */ - export function getRangeOfEnclosingComment( - sourceFile: SourceFile, - position: number, - precedingToken?: Node | null, - tokenAtPosition = getTokenAtPosition(sourceFile, position), - ): CommentRange | undefined { - const jsdoc = findAncestor(tokenAtPosition, isJSDoc); - if (jsdoc) tokenAtPosition = jsdoc.parent; + export function getRangeOfEnclosingComment(sourceFile: ts.SourceFile, position: number, precedingToken?: ts.Node | null, tokenAtPosition = ts.getTokenAtPosition(sourceFile, position)): ts.CommentRange | undefined { + const jsdoc = ts.findAncestor(tokenAtPosition, ts.isJSDoc); + if (jsdoc) + tokenAtPosition = jsdoc.parent; const tokenStart = tokenAtPosition.getStart(sourceFile); if (tokenStart <= position && position < tokenAtPosition.getEnd()) { return undefined; } // eslint-disable-next-line no-null/no-null - precedingToken = precedingToken === null ? undefined : precedingToken === undefined ? findPrecedingToken(position, sourceFile) : precedingToken; + precedingToken = precedingToken === null ? undefined : precedingToken === undefined ? ts.findPrecedingToken(position, sourceFile) : precedingToken; // Between two consecutive tokens, all comments are either trailing on the former // or leading on the latter (and none are in both lists). - const trailingRangesOfPreviousToken = precedingToken && getTrailingCommentRanges(sourceFile.text, precedingToken.end); - const leadingCommentRangesOfNextToken = getLeadingCommentRangesOfNode(tokenAtPosition, sourceFile); - const commentRanges = concatenate(trailingRangesOfPreviousToken, leadingCommentRangesOfNextToken); - return commentRanges && find(commentRanges, range => rangeContainsPositionExclusive(range, position) || + const trailingRangesOfPreviousToken = precedingToken && ts.getTrailingCommentRanges(sourceFile.text, precedingToken.end); + const leadingCommentRangesOfNextToken = ts.getLeadingCommentRangesOfNode(tokenAtPosition, sourceFile); + const commentRanges = ts.concatenate(trailingRangesOfPreviousToken, leadingCommentRangesOfNextToken); + return commentRanges && ts.find(commentRanges, range => ts.rangeContainsPositionExclusive(range, position) || // The end marker of a single-line comment does not include the newline character. // With caret at `^`, in the following case, we are inside a comment (^ denotes the cursor position): // @@ -1302,66 +1210,66 @@ namespace ts.formatting { // // Internally, we represent the end of the comment at the newline and closing '/', respectively. // - position === range.end && (range.kind === SyntaxKind.SingleLineCommentTrivia || position === sourceFile.getFullWidth())); + position === range.end && (range.kind === ts.SyntaxKind.SingleLineCommentTrivia || position === sourceFile.getFullWidth())); } - function getOpenTokenForList(node: Node, list: readonly Node[]) { + function getOpenTokenForList(node: ts.Node, list: readonly ts.Node[]) { switch (node.kind) { - case SyntaxKind.Constructor: - case SyntaxKind.FunctionDeclaration: - case SyntaxKind.FunctionExpression: - case SyntaxKind.MethodDeclaration: - case SyntaxKind.MethodSignature: - case SyntaxKind.ArrowFunction: - if ((node as FunctionDeclaration).typeParameters === list) { - return SyntaxKind.LessThanToken; + case ts.SyntaxKind.Constructor: + case ts.SyntaxKind.FunctionDeclaration: + case ts.SyntaxKind.FunctionExpression: + case ts.SyntaxKind.MethodDeclaration: + case ts.SyntaxKind.MethodSignature: + case ts.SyntaxKind.ArrowFunction: + if ((node as ts.FunctionDeclaration).typeParameters === list) { + return ts.SyntaxKind.LessThanToken; } - else if ((node as FunctionDeclaration).parameters === list) { - return SyntaxKind.OpenParenToken; + else if ((node as ts.FunctionDeclaration).parameters === list) { + return ts.SyntaxKind.OpenParenToken; } break; - case SyntaxKind.CallExpression: - case SyntaxKind.NewExpression: - if ((node as CallExpression).typeArguments === list) { - return SyntaxKind.LessThanToken; + case ts.SyntaxKind.CallExpression: + case ts.SyntaxKind.NewExpression: + if ((node as ts.CallExpression).typeArguments === list) { + return ts.SyntaxKind.LessThanToken; } - else if ((node as CallExpression).arguments === list) { - return SyntaxKind.OpenParenToken; + else if ((node as ts.CallExpression).arguments === list) { + return ts.SyntaxKind.OpenParenToken; } break; - case SyntaxKind.TypeReference: - if ((node as TypeReferenceNode).typeArguments === list) { - return SyntaxKind.LessThanToken; + case ts.SyntaxKind.TypeReference: + if ((node as ts.TypeReferenceNode).typeArguments === list) { + return ts.SyntaxKind.LessThanToken; } break; - case SyntaxKind.TypeLiteral: - return SyntaxKind.OpenBraceToken; + case ts.SyntaxKind.TypeLiteral: + return ts.SyntaxKind.OpenBraceToken; } - return SyntaxKind.Unknown; + return ts.SyntaxKind.Unknown; } - function getCloseTokenForOpenToken(kind: SyntaxKind) { + function getCloseTokenForOpenToken(kind: ts.SyntaxKind) { switch (kind) { - case SyntaxKind.OpenParenToken: - return SyntaxKind.CloseParenToken; - case SyntaxKind.LessThanToken: - return SyntaxKind.GreaterThanToken; - case SyntaxKind.OpenBraceToken: - return SyntaxKind.CloseBraceToken; + case ts.SyntaxKind.OpenParenToken: + return ts.SyntaxKind.CloseParenToken; + case ts.SyntaxKind.LessThanToken: + return ts.SyntaxKind.GreaterThanToken; + case ts.SyntaxKind.OpenBraceToken: + return ts.SyntaxKind.CloseBraceToken; } - - return SyntaxKind.Unknown; + return ts.SyntaxKind.Unknown; } - - let internedSizes: { tabSize: number; indentSize: number; }; + let internedSizes: { + tabSize: number; + indentSize: number; + }; let internedTabsIndentation: string[] | undefined; let internedSpacesIndentation: string[] | undefined; - export function getIndentationString(indentation: number, options: EditorSettings): string { + export function getIndentationString(indentation: number, options: ts.EditorSettings): string { // reset interned strings if FormatCodeOptions were changed - const resetInternedStrings = - !internedSizes || (internedSizes.tabSize !== options.tabSize || internedSizes.indentSize !== options.indentSize); + const resetInternedStrings = !internedSizes || (internedSizes.tabSize !== options.tabSize || internedSizes.indentSize !== options.indentSize); if (resetInternedStrings) { internedSizes = { tabSize: options.tabSize!, indentSize: options.indentSize! }; @@ -1378,13 +1286,13 @@ namespace ts.formatting { } if (internedTabsIndentation[tabs] === undefined) { - internedTabsIndentation[tabs] = tabString = repeatString("\t", tabs); + internedTabsIndentation[tabs] = tabString = ts.repeatString("\t", tabs); } else { tabString = internedTabsIndentation[tabs]; } - return spaces ? tabString + repeatString(" ", spaces) : tabString; + return spaces ? tabString + ts.repeatString(" ", spaces) : tabString; } else { let spacesString: string; @@ -1395,14 +1303,14 @@ namespace ts.formatting { } if (internedSpacesIndentation[quotient] === undefined) { - spacesString = repeatString(" ", options.indentSize! * quotient); + spacesString = ts.repeatString(" ", options.indentSize! * quotient); internedSpacesIndentation[quotient] = spacesString; } else { spacesString = internedSpacesIndentation[quotient]; } - return remainder ? spacesString + repeatString(" ", remainder) : spacesString; + return remainder ? spacesString + ts.repeatString(" ", remainder) : spacesString; } } } diff --git a/src/services/formatting/formattingContext.ts b/src/services/formatting/formattingContext.ts index 5701f0cd0ad0e..01bb9f6694b4e 100644 --- a/src/services/formatting/formattingContext.ts +++ b/src/services/formatting/formattingContext.ts @@ -10,11 +10,11 @@ namespace ts.formatting { } export class FormattingContext { - public currentTokenSpan!: TextRangeWithKind; - public nextTokenSpan!: TextRangeWithKind; - public contextNode!: Node; - public currentTokenParent!: Node; - public nextTokenParent!: Node; + public currentTokenSpan!: ts.formatting.TextRangeWithKind; + public nextTokenSpan!: ts.formatting.TextRangeWithKind; + public contextNode!: ts.Node; + public currentTokenParent!: ts.Node; + public nextTokenParent!: ts.Node; private contextNodeAllOnSameLine: boolean | undefined; private nextNodeAllOnSameLine: boolean | undefined; @@ -22,15 +22,14 @@ namespace ts.formatting { private contextNodeBlockIsOnOneLine: boolean | undefined; private nextNodeBlockIsOnOneLine: boolean | undefined; - constructor(public readonly sourceFile: SourceFileLike, public formattingRequestKind: FormattingRequestKind, public options: FormatCodeSettings) { + constructor(public readonly sourceFile: ts.SourceFileLike, public formattingRequestKind: FormattingRequestKind, public options: ts.FormatCodeSettings) { } - - public updateContext(currentRange: TextRangeWithKind, currentTokenParent: Node, nextRange: TextRangeWithKind, nextTokenParent: Node, commonParent: Node) { - this.currentTokenSpan = Debug.checkDefined(currentRange); - this.currentTokenParent = Debug.checkDefined(currentTokenParent); - this.nextTokenSpan = Debug.checkDefined(nextRange); - this.nextTokenParent = Debug.checkDefined(nextTokenParent); - this.contextNode = Debug.checkDefined(commonParent); + public updateContext(currentRange: ts.formatting.TextRangeWithKind, currentTokenParent: ts.Node, nextRange: ts.formatting.TextRangeWithKind, nextTokenParent: ts.Node, commonParent: ts.Node) { + this.currentTokenSpan = ts.Debug.checkDefined(currentRange); + this.currentTokenParent = ts.Debug.checkDefined(currentTokenParent); + this.nextTokenSpan = ts.Debug.checkDefined(nextRange); + this.nextTokenParent = ts.Debug.checkDefined(nextTokenParent); + this.contextNode = ts.Debug.checkDefined(commonParent); // drop cached results this.contextNodeAllOnSameLine = undefined; @@ -82,15 +81,15 @@ namespace ts.formatting { return this.nextNodeBlockIsOnOneLine; } - private NodeIsOnOneLine(node: Node): boolean { + private NodeIsOnOneLine(node: ts.Node): boolean { const startLine = this.sourceFile.getLineAndCharacterOfPosition(node.getStart(this.sourceFile)).line; const endLine = this.sourceFile.getLineAndCharacterOfPosition(node.getEnd()).line; return startLine === endLine; } - private BlockIsOnOneLine(node: Node): boolean { - const openBrace = findChildOfKind(node, SyntaxKind.OpenBraceToken, this.sourceFile); - const closeBrace = findChildOfKind(node, SyntaxKind.CloseBraceToken, this.sourceFile); + private BlockIsOnOneLine(node: ts.Node): boolean { + const openBrace = ts.findChildOfKind(node, ts.SyntaxKind.OpenBraceToken, this.sourceFile); + const closeBrace = ts.findChildOfKind(node, ts.SyntaxKind.CloseBraceToken, this.sourceFile); if (openBrace && closeBrace) { const startLine = this.sourceFile.getLineAndCharacterOfPosition(openBrace.getEnd()).line; const endLine = this.sourceFile.getLineAndCharacterOfPosition(closeBrace.getStart(this.sourceFile)).line; diff --git a/src/services/formatting/formattingScanner.ts b/src/services/formatting/formattingScanner.ts index 56ad87770ba7b..17adacd7e07b1 100644 --- a/src/services/formatting/formattingScanner.ts +++ b/src/services/formatting/formattingScanner.ts @@ -1,19 +1,19 @@ /* @internal */ namespace ts.formatting { - const standardScanner = createScanner(ScriptTarget.Latest, /*skipTrivia*/ false, LanguageVariant.Standard); - const jsxScanner = createScanner(ScriptTarget.Latest, /*skipTrivia*/ false, LanguageVariant.JSX); + const standardScanner = ts.createScanner(ts.ScriptTarget.Latest, /*skipTrivia*/ false, ts.LanguageVariant.Standard); + const jsxScanner = ts.createScanner(ts.ScriptTarget.Latest, /*skipTrivia*/ false, ts.LanguageVariant.JSX); export interface FormattingScanner { advance(): void; getStartPos(): number; isOnToken(): boolean; isOnEOF(): boolean; - readTokenInfo(n: Node): TokenInfo; - readEOFTokenRange(): TextRangeWithKind; - getCurrentLeadingTrivia(): TextRangeWithKind[] | undefined; + readTokenInfo(n: ts.Node): ts.formatting.TokenInfo; + readEOFTokenRange(): ts.formatting.TextRangeWithKind; + getCurrentLeadingTrivia(): ts.formatting.TextRangeWithKind[] | undefined; lastTrailingTriviaWasNewLine(): boolean; - skipToEndOf(node: Node | NodeArray): void; - skipToStartOf(node: Node): void; + skipToEndOf(node: ts.Node | ts.NodeArray): void; + skipToStartOf(node: ts.Node): void; } const enum ScanAction { @@ -23,22 +23,22 @@ namespace ts.formatting { RescanTemplateToken, RescanJsxIdentifier, RescanJsxText, - RescanJsxAttributeValue, + RescanJsxAttributeValue } - export function getFormattingScanner(text: string, languageVariant: LanguageVariant, startPos: number, endPos: number, cb: (scanner: FormattingScanner) => T): T { - const scanner = languageVariant === LanguageVariant.JSX ? jsxScanner : standardScanner; + export function getFormattingScanner(text: string, languageVariant: ts.LanguageVariant, startPos: number, endPos: number, cb: (scanner: FormattingScanner) => T): T { + const scanner = languageVariant === ts.LanguageVariant.JSX ? jsxScanner : standardScanner; scanner.setText(text); scanner.setTextPos(startPos); let wasNewLine = true; - let leadingTrivia: TextRangeWithTriviaKind[] | undefined; - let trailingTrivia: TextRangeWithTriviaKind[] | undefined; + let leadingTrivia: ts.formatting.TextRangeWithTriviaKind[] | undefined; + let trailingTrivia: ts.formatting.TextRangeWithTriviaKind[] | undefined; let savedPos: number; let lastScanAction: ScanAction | undefined; - let lastTokenInfo: TokenInfo | undefined; + let lastTokenInfo: ts.formatting.TokenInfo | undefined; const res = cb({ advance, @@ -63,7 +63,7 @@ namespace ts.formatting { const isStarted = scanner.getStartPos() !== startPos; if (isStarted) { - wasNewLine = !!trailingTrivia && last(trailingTrivia).kind === SyntaxKind.NewLineTrivia; + wasNewLine = !!trailingTrivia && ts.last(trailingTrivia).kind === ts.SyntaxKind.NewLineTrivia; } else { scanner.scan(); @@ -77,13 +77,13 @@ namespace ts.formatting { // Read leading trivia and token while (pos < endPos) { const t = scanner.getToken(); - if (!isTrivia(t)) { + if (!ts.isTrivia(t)) { break; } // consume leading trivia scanner.scan(); - const item: TextRangeWithTriviaKind = { + const item: ts.formatting.TextRangeWithTriviaKind = { pos, end: scanner.getStartPos(), kind: t @@ -91,63 +91,63 @@ namespace ts.formatting { pos = scanner.getStartPos(); - leadingTrivia = append(leadingTrivia, item); + leadingTrivia = ts.append(leadingTrivia, item); } savedPos = scanner.getStartPos(); } - function shouldRescanGreaterThanToken(node: Node): boolean { + function shouldRescanGreaterThanToken(node: ts.Node): boolean { switch (node.kind) { - case SyntaxKind.GreaterThanEqualsToken: - case SyntaxKind.GreaterThanGreaterThanEqualsToken: - case SyntaxKind.GreaterThanGreaterThanGreaterThanEqualsToken: - case SyntaxKind.GreaterThanGreaterThanGreaterThanToken: - case SyntaxKind.GreaterThanGreaterThanToken: + case ts.SyntaxKind.GreaterThanEqualsToken: + case ts.SyntaxKind.GreaterThanGreaterThanEqualsToken: + case ts.SyntaxKind.GreaterThanGreaterThanGreaterThanEqualsToken: + case ts.SyntaxKind.GreaterThanGreaterThanGreaterThanToken: + case ts.SyntaxKind.GreaterThanGreaterThanToken: return true; } return false; } - function shouldRescanJsxIdentifier(node: Node): boolean { + function shouldRescanJsxIdentifier(node: ts.Node): boolean { if (node.parent) { switch (node.parent.kind) { - case SyntaxKind.JsxAttribute: - case SyntaxKind.JsxOpeningElement: - case SyntaxKind.JsxClosingElement: - case SyntaxKind.JsxSelfClosingElement: + case ts.SyntaxKind.JsxAttribute: + case ts.SyntaxKind.JsxOpeningElement: + case ts.SyntaxKind.JsxClosingElement: + case ts.SyntaxKind.JsxSelfClosingElement: // May parse an identifier like `module-layout`; that will be scanned as a keyword at first, but we should parse the whole thing to get an identifier. - return isKeyword(node.kind) || node.kind === SyntaxKind.Identifier; + return ts.isKeyword(node.kind) || node.kind === ts.SyntaxKind.Identifier; } } return false; } - function shouldRescanJsxText(node: Node): boolean { - return isJsxText(node); + function shouldRescanJsxText(node: ts.Node): boolean { + return ts.isJsxText(node); } - function shouldRescanSlashToken(container: Node): boolean { - return container.kind === SyntaxKind.RegularExpressionLiteral; + function shouldRescanSlashToken(container: ts.Node): boolean { + return container.kind === ts.SyntaxKind.RegularExpressionLiteral; } - function shouldRescanTemplateToken(container: Node): boolean { - return container.kind === SyntaxKind.TemplateMiddle || - container.kind === SyntaxKind.TemplateTail; + function shouldRescanTemplateToken(container: ts.Node): boolean { + return container.kind === ts.SyntaxKind.TemplateMiddle || + container.kind === ts.SyntaxKind.TemplateTail; } - function shouldRescanJsxAttributeValue(node: Node): boolean { - return node.parent && isJsxAttribute(node.parent) && node.parent.initializer === node; + function shouldRescanJsxAttributeValue(node: ts.Node): boolean { + return node.parent && ts.isJsxAttribute(node.parent) && node.parent.initializer === node; } - function startsWithSlashToken(t: SyntaxKind): boolean { - return t === SyntaxKind.SlashToken || t === SyntaxKind.SlashEqualsToken; + function startsWithSlashToken(t: ts.SyntaxKind): boolean { + return t === ts.SyntaxKind.SlashToken || t === ts.SyntaxKind.SlashEqualsToken; } - function readTokenInfo(n: Node): TokenInfo { - Debug.assert(isOnToken()); + function readTokenInfo(n: ts.Node): ts.formatting.TokenInfo { + ts.Debug.assert(isOnToken()); // normally scanner returns the smallest available token // check the kind of context node to determine if scanner should have more greedy behavior and consume more text. @@ -170,7 +170,7 @@ namespace ts.formatting { } if (scanner.getStartPos() !== savedPos) { - Debug.assert(lastTokenInfo !== undefined); + ts.Debug.assert(lastTokenInfo !== undefined); // readTokenInfo was called before but scan action differs - rescan text scanner.setTextPos(savedPos); scanner.scan(); @@ -178,11 +178,7 @@ namespace ts.formatting { let currentToken = getNextToken(n, expectedScanAction); - const token = createTextRangeWithKind( - scanner.getStartPos(), - scanner.getTextPos(), - currentToken, - ); + const token = ts.formatting.createTextRangeWithKind(scanner.getStartPos(), scanner.getTextPos(), currentToken); // consume trailing trivia if (trailingTrivia) { @@ -190,14 +186,10 @@ namespace ts.formatting { } while (scanner.getStartPos() < endPos) { currentToken = scanner.scan(); - if (!isTrivia(currentToken)) { + if (!ts.isTrivia(currentToken)) { break; } - const trivia = createTextRangeWithKind( - scanner.getStartPos(), - scanner.getTextPos(), - currentToken, - ); + const trivia = ts.formatting.createTextRangeWithKind(scanner.getStartPos(), scanner.getTextPos(), currentToken); if (!trailingTrivia) { trailingTrivia = []; @@ -205,7 +197,7 @@ namespace ts.formatting { trailingTrivia.push(trivia); - if (currentToken === SyntaxKind.NewLineTrivia) { + if (currentToken === ts.SyntaxKind.NewLineTrivia) { // move past new line scanner.scan(); break; @@ -217,15 +209,15 @@ namespace ts.formatting { return fixTokenKind(lastTokenInfo, n); } - function getNextToken(n: Node, expectedScanAction: ScanAction): SyntaxKind { + function getNextToken(n: ts.Node, expectedScanAction: ScanAction): ts.SyntaxKind { const token = scanner.getToken(); lastScanAction = ScanAction.Scan; switch (expectedScanAction) { case ScanAction.RescanGreaterThanToken: - if (token === SyntaxKind.GreaterThanToken) { + if (token === ts.SyntaxKind.GreaterThanToken) { lastScanAction = ScanAction.RescanGreaterThanToken; const newToken = scanner.reScanGreaterToken(); - Debug.assert(n.kind === newToken); + ts.Debug.assert(n.kind === newToken); return newToken; } break; @@ -233,12 +225,12 @@ namespace ts.formatting { if (startsWithSlashToken(token)) { lastScanAction = ScanAction.RescanSlashToken; const newToken = scanner.reScanSlashToken(); - Debug.assert(n.kind === newToken); + ts.Debug.assert(n.kind === newToken); return newToken; } break; case ScanAction.RescanTemplateToken: - if (token === SyntaxKind.CloseBraceToken) { + if (token === ts.SyntaxKind.CloseBraceToken) { lastScanAction = ScanAction.RescanTemplateToken; return scanner.reScanTemplateToken(/* isTaggedTemplate */ false); } @@ -255,38 +247,38 @@ namespace ts.formatting { case ScanAction.Scan: break; default: - Debug.assertNever(expectedScanAction); + ts.Debug.assertNever(expectedScanAction); } return token; } - function readEOFTokenRange(): TextRangeWithKind { - Debug.assert(isOnEOF()); - return createTextRangeWithKind(scanner.getStartPos(), scanner.getTextPos(), SyntaxKind.EndOfFileToken); + function readEOFTokenRange(): ts.formatting.TextRangeWithKind { + ts.Debug.assert(isOnEOF()); + return ts.formatting.createTextRangeWithKind(scanner.getStartPos(), scanner.getTextPos(), ts.SyntaxKind.EndOfFileToken); } function isOnToken(): boolean { const current = lastTokenInfo ? lastTokenInfo.token.kind : scanner.getToken(); - return current !== SyntaxKind.EndOfFileToken && !isTrivia(current); + return current !== ts.SyntaxKind.EndOfFileToken && !ts.isTrivia(current); } function isOnEOF(): boolean { const current = lastTokenInfo ? lastTokenInfo.token.kind : scanner.getToken(); - return current === SyntaxKind.EndOfFileToken; + return current === ts.SyntaxKind.EndOfFileToken; } // when containing node in the tree is token // but its kind differs from the kind that was returned by the scanner, // then kind needs to be fixed. This might happen in cases // when parser interprets token differently, i.e keyword treated as identifier - function fixTokenKind(tokenInfo: TokenInfo, container: Node): TokenInfo { - if (isToken(container) && tokenInfo.token.kind !== container.kind) { + function fixTokenKind(tokenInfo: ts.formatting.TokenInfo, container: ts.Node): ts.formatting.TokenInfo { + if (ts.isToken(container) && tokenInfo.token.kind !== container.kind) { tokenInfo.token.kind = container.kind; } return tokenInfo; } - function skipToEndOf(node: Node | NodeArray): void { + function skipToEndOf(node: ts.Node | ts.NodeArray): void { scanner.setTextPos(node.end); savedPos = scanner.getStartPos(); lastScanAction = undefined; @@ -296,7 +288,7 @@ namespace ts.formatting { trailingTrivia = undefined; } - function skipToStartOf(node: Node): void { + function skipToStartOf(node: ts.Node): void { scanner.setTextPos(node.pos); savedPos = scanner.getStartPos(); lastScanAction = undefined; diff --git a/src/services/formatting/rule.ts b/src/services/formatting/rule.ts index ef98461738891..f0a7730aff5a8 100644 --- a/src/services/formatting/rule.ts +++ b/src/services/formatting/rule.ts @@ -8,8 +8,8 @@ namespace ts.formatting { readonly flags: RuleFlags; } - export type ContextPredicate = (context: FormattingContext) => boolean; - export const anyContext: readonly ContextPredicate[] = emptyArray; + export type ContextPredicate = (context: ts.formatting.FormattingContext) => boolean; + export const anyContext: readonly ContextPredicate[] = ts.emptyArray; export const enum RuleAction { StopProcessingSpaceActions = 1 << 0, @@ -22,16 +22,16 @@ namespace ts.formatting { StopAction = StopProcessingSpaceActions | StopProcessingTokenActions, ModifySpaceAction = InsertSpace | InsertNewLine | DeleteSpace, - ModifyTokenAction = DeleteToken | InsertTrailingSemicolon, + ModifyTokenAction = DeleteToken | InsertTrailingSemicolon } export const enum RuleFlags { None, - CanDeleteNewLines, + CanDeleteNewLines } export interface TokenRange { - readonly tokens: readonly SyntaxKind[]; + readonly tokens: readonly ts.SyntaxKind[]; readonly isSpecific: boolean; } } diff --git a/src/services/formatting/rules.ts b/src/services/formatting/rules.ts index 76a0d34853153..60b1785d25bd9 100644 --- a/src/services/formatting/rules.ts +++ b/src/services/formatting/rules.ts @@ -1,356 +1,317 @@ /* @internal */ namespace ts.formatting { export interface RuleSpec { - readonly leftTokenRange: TokenRange; - readonly rightTokenRange: TokenRange; - readonly rule: Rule; + readonly leftTokenRange: ts.formatting.TokenRange; + readonly rightTokenRange: ts.formatting.TokenRange; + readonly rule: ts.formatting.Rule; } export function getAllRules(): RuleSpec[] { - const allTokens: SyntaxKind[] = []; - for (let token = SyntaxKind.FirstToken; token <= SyntaxKind.LastToken; token++) { - if (token !== SyntaxKind.EndOfFileToken) { + const allTokens: ts.SyntaxKind[] = []; + for (let token = ts.SyntaxKind.FirstToken; token <= ts.SyntaxKind.LastToken; token++) { + if (token !== ts.SyntaxKind.EndOfFileToken) { allTokens.push(token); } } - function anyTokenExcept(...tokens: SyntaxKind[]): TokenRange { + function anyTokenExcept(...tokens: ts.SyntaxKind[]): ts.formatting.TokenRange { return { tokens: allTokens.filter(t => !tokens.some(t2 => t2 === t)), isSpecific: false }; } - const anyToken: TokenRange = { tokens: allTokens, isSpecific: false }; - const anyTokenIncludingMultilineComments = tokenRangeFrom([...allTokens, SyntaxKind.MultiLineCommentTrivia]); - const anyTokenIncludingEOF = tokenRangeFrom([...allTokens, SyntaxKind.EndOfFileToken]); - const keywords = tokenRangeFromRange(SyntaxKind.FirstKeyword, SyntaxKind.LastKeyword); - const binaryOperators = tokenRangeFromRange(SyntaxKind.FirstBinaryOperator, SyntaxKind.LastBinaryOperator); - const binaryKeywordOperators = [SyntaxKind.InKeyword, SyntaxKind.InstanceOfKeyword, SyntaxKind.OfKeyword, SyntaxKind.AsKeyword, SyntaxKind.IsKeyword]; - const unaryPrefixOperators = [SyntaxKind.PlusPlusToken, SyntaxKind.MinusMinusToken, SyntaxKind.TildeToken, SyntaxKind.ExclamationToken]; + const anyToken: ts.formatting.TokenRange = { tokens: allTokens, isSpecific: false }; + const anyTokenIncludingMultilineComments = tokenRangeFrom([...allTokens, ts.SyntaxKind.MultiLineCommentTrivia]); + const anyTokenIncludingEOF = tokenRangeFrom([...allTokens, ts.SyntaxKind.EndOfFileToken]); + const keywords = tokenRangeFromRange(ts.SyntaxKind.FirstKeyword, ts.SyntaxKind.LastKeyword); + const binaryOperators = tokenRangeFromRange(ts.SyntaxKind.FirstBinaryOperator, ts.SyntaxKind.LastBinaryOperator); + const binaryKeywordOperators = [ts.SyntaxKind.InKeyword, ts.SyntaxKind.InstanceOfKeyword, ts.SyntaxKind.OfKeyword, ts.SyntaxKind.AsKeyword, ts.SyntaxKind.IsKeyword]; + const unaryPrefixOperators = [ts.SyntaxKind.PlusPlusToken, ts.SyntaxKind.MinusMinusToken, ts.SyntaxKind.TildeToken, ts.SyntaxKind.ExclamationToken]; const unaryPrefixExpressions = [ - SyntaxKind.NumericLiteral, SyntaxKind.BigIntLiteral, SyntaxKind.Identifier, SyntaxKind.OpenParenToken, - SyntaxKind.OpenBracketToken, SyntaxKind.OpenBraceToken, SyntaxKind.ThisKeyword, SyntaxKind.NewKeyword]; - const unaryPreincrementExpressions = [SyntaxKind.Identifier, SyntaxKind.OpenParenToken, SyntaxKind.ThisKeyword, SyntaxKind.NewKeyword]; - const unaryPostincrementExpressions = [SyntaxKind.Identifier, SyntaxKind.CloseParenToken, SyntaxKind.CloseBracketToken, SyntaxKind.NewKeyword]; - const unaryPredecrementExpressions = [SyntaxKind.Identifier, SyntaxKind.OpenParenToken, SyntaxKind.ThisKeyword, SyntaxKind.NewKeyword]; - const unaryPostdecrementExpressions = [SyntaxKind.Identifier, SyntaxKind.CloseParenToken, SyntaxKind.CloseBracketToken, SyntaxKind.NewKeyword]; - const comments = [SyntaxKind.SingleLineCommentTrivia, SyntaxKind.MultiLineCommentTrivia]; - const typeNames = [SyntaxKind.Identifier, ...typeKeywords]; + ts.SyntaxKind.NumericLiteral, ts.SyntaxKind.BigIntLiteral, ts.SyntaxKind.Identifier, ts.SyntaxKind.OpenParenToken, + ts.SyntaxKind.OpenBracketToken, ts.SyntaxKind.OpenBraceToken, ts.SyntaxKind.ThisKeyword, ts.SyntaxKind.NewKeyword + ]; + const unaryPreincrementExpressions = [ts.SyntaxKind.Identifier, ts.SyntaxKind.OpenParenToken, ts.SyntaxKind.ThisKeyword, ts.SyntaxKind.NewKeyword]; + const unaryPostincrementExpressions = [ts.SyntaxKind.Identifier, ts.SyntaxKind.CloseParenToken, ts.SyntaxKind.CloseBracketToken, ts.SyntaxKind.NewKeyword]; + const unaryPredecrementExpressions = [ts.SyntaxKind.Identifier, ts.SyntaxKind.OpenParenToken, ts.SyntaxKind.ThisKeyword, ts.SyntaxKind.NewKeyword]; + const unaryPostdecrementExpressions = [ts.SyntaxKind.Identifier, ts.SyntaxKind.CloseParenToken, ts.SyntaxKind.CloseBracketToken, ts.SyntaxKind.NewKeyword]; + const comments = [ts.SyntaxKind.SingleLineCommentTrivia, ts.SyntaxKind.MultiLineCommentTrivia]; + const typeNames = [ts.SyntaxKind.Identifier, ...ts.typeKeywords]; // Place a space before open brace in a function declaration // TypeScript: Function can have return types, which can be made of tons of different token kinds const functionOpenBraceLeftTokenRange = anyTokenIncludingMultilineComments; // Place a space before open brace in a TypeScript declaration that has braces as children (class, module, enum, etc) - const typeScriptOpenBraceLeftTokenRange = tokenRangeFrom([SyntaxKind.Identifier, SyntaxKind.MultiLineCommentTrivia, SyntaxKind.ClassKeyword, SyntaxKind.ExportKeyword, SyntaxKind.ImportKeyword]); + const typeScriptOpenBraceLeftTokenRange = tokenRangeFrom([ts.SyntaxKind.Identifier, ts.SyntaxKind.MultiLineCommentTrivia, ts.SyntaxKind.ClassKeyword, ts.SyntaxKind.ExportKeyword, ts.SyntaxKind.ImportKeyword]); // Place a space before open brace in a control flow construct - const controlOpenBraceLeftTokenRange = tokenRangeFrom([SyntaxKind.CloseParenToken, SyntaxKind.MultiLineCommentTrivia, SyntaxKind.DoKeyword, SyntaxKind.TryKeyword, SyntaxKind.FinallyKeyword, SyntaxKind.ElseKeyword]); + const controlOpenBraceLeftTokenRange = tokenRangeFrom([ts.SyntaxKind.CloseParenToken, ts.SyntaxKind.MultiLineCommentTrivia, ts.SyntaxKind.DoKeyword, ts.SyntaxKind.TryKeyword, ts.SyntaxKind.FinallyKeyword, ts.SyntaxKind.ElseKeyword]); // These rules are higher in priority than user-configurable const highPriorityCommonRules = [ // Leave comments alone - rule("IgnoreBeforeComment", anyToken, comments, anyContext, RuleAction.StopProcessingSpaceActions), - rule("IgnoreAfterLineComment", SyntaxKind.SingleLineCommentTrivia, anyToken, anyContext, RuleAction.StopProcessingSpaceActions), - - rule("NotSpaceBeforeColon", anyToken, SyntaxKind.ColonToken, [isNonJsxSameLineTokenContext, isNotBinaryOpContext, isNotTypeAnnotationContext], RuleAction.DeleteSpace), - rule("SpaceAfterColon", SyntaxKind.ColonToken, anyToken, [isNonJsxSameLineTokenContext, isNotBinaryOpContext], RuleAction.InsertSpace), - rule("NoSpaceBeforeQuestionMark", anyToken, SyntaxKind.QuestionToken, [isNonJsxSameLineTokenContext, isNotBinaryOpContext, isNotTypeAnnotationContext], RuleAction.DeleteSpace), + rule("IgnoreBeforeComment", anyToken, comments, ts.formatting.anyContext, ts.formatting.RuleAction.StopProcessingSpaceActions), + rule("IgnoreAfterLineComment", ts.SyntaxKind.SingleLineCommentTrivia, anyToken, ts.formatting.anyContext, ts.formatting.RuleAction.StopProcessingSpaceActions), + rule("NotSpaceBeforeColon", anyToken, ts.SyntaxKind.ColonToken, [isNonJsxSameLineTokenContext, isNotBinaryOpContext, isNotTypeAnnotationContext], ts.formatting.RuleAction.DeleteSpace), + rule("SpaceAfterColon", ts.SyntaxKind.ColonToken, anyToken, [isNonJsxSameLineTokenContext, isNotBinaryOpContext], ts.formatting.RuleAction.InsertSpace), + rule("NoSpaceBeforeQuestionMark", anyToken, ts.SyntaxKind.QuestionToken, [isNonJsxSameLineTokenContext, isNotBinaryOpContext, isNotTypeAnnotationContext], ts.formatting.RuleAction.DeleteSpace), // insert space after '?' only when it is used in conditional operator - rule("SpaceAfterQuestionMarkInConditionalOperator", SyntaxKind.QuestionToken, anyToken, [isNonJsxSameLineTokenContext, isConditionalOperatorContext], RuleAction.InsertSpace), + rule("SpaceAfterQuestionMarkInConditionalOperator", ts.SyntaxKind.QuestionToken, anyToken, [isNonJsxSameLineTokenContext, isConditionalOperatorContext], ts.formatting.RuleAction.InsertSpace), // in other cases there should be no space between '?' and next token - rule("NoSpaceAfterQuestionMark", SyntaxKind.QuestionToken, anyToken, [isNonJsxSameLineTokenContext], RuleAction.DeleteSpace), - - rule("NoSpaceBeforeDot", anyToken, [SyntaxKind.DotToken, SyntaxKind.QuestionDotToken], [isNonJsxSameLineTokenContext], RuleAction.DeleteSpace), - rule("NoSpaceAfterDot", [SyntaxKind.DotToken, SyntaxKind.QuestionDotToken], anyToken, [isNonJsxSameLineTokenContext], RuleAction.DeleteSpace), - - rule("NoSpaceBetweenImportParenInImportType", SyntaxKind.ImportKeyword, SyntaxKind.OpenParenToken, [isNonJsxSameLineTokenContext, isImportTypeContext], RuleAction.DeleteSpace), + rule("NoSpaceAfterQuestionMark", ts.SyntaxKind.QuestionToken, anyToken, [isNonJsxSameLineTokenContext], ts.formatting.RuleAction.DeleteSpace), + rule("NoSpaceBeforeDot", anyToken, [ts.SyntaxKind.DotToken, ts.SyntaxKind.QuestionDotToken], [isNonJsxSameLineTokenContext], ts.formatting.RuleAction.DeleteSpace), + rule("NoSpaceAfterDot", [ts.SyntaxKind.DotToken, ts.SyntaxKind.QuestionDotToken], anyToken, [isNonJsxSameLineTokenContext], ts.formatting.RuleAction.DeleteSpace), + rule("NoSpaceBetweenImportParenInImportType", ts.SyntaxKind.ImportKeyword, ts.SyntaxKind.OpenParenToken, [isNonJsxSameLineTokenContext, isImportTypeContext], ts.formatting.RuleAction.DeleteSpace), // Special handling of unary operators. // Prefix operators generally shouldn't have a space between // them and their target unary expression. - rule("NoSpaceAfterUnaryPrefixOperator", unaryPrefixOperators, unaryPrefixExpressions, [isNonJsxSameLineTokenContext, isNotBinaryOpContext], RuleAction.DeleteSpace), - rule("NoSpaceAfterUnaryPreincrementOperator", SyntaxKind.PlusPlusToken, unaryPreincrementExpressions, [isNonJsxSameLineTokenContext], RuleAction.DeleteSpace), - rule("NoSpaceAfterUnaryPredecrementOperator", SyntaxKind.MinusMinusToken, unaryPredecrementExpressions, [isNonJsxSameLineTokenContext], RuleAction.DeleteSpace), - rule("NoSpaceBeforeUnaryPostincrementOperator", unaryPostincrementExpressions, SyntaxKind.PlusPlusToken, [isNonJsxSameLineTokenContext, isNotStatementConditionContext], RuleAction.DeleteSpace), - rule("NoSpaceBeforeUnaryPostdecrementOperator", unaryPostdecrementExpressions, SyntaxKind.MinusMinusToken, [isNonJsxSameLineTokenContext, isNotStatementConditionContext], RuleAction.DeleteSpace), + rule("NoSpaceAfterUnaryPrefixOperator", unaryPrefixOperators, unaryPrefixExpressions, [isNonJsxSameLineTokenContext, isNotBinaryOpContext], ts.formatting.RuleAction.DeleteSpace), + rule("NoSpaceAfterUnaryPreincrementOperator", ts.SyntaxKind.PlusPlusToken, unaryPreincrementExpressions, [isNonJsxSameLineTokenContext], ts.formatting.RuleAction.DeleteSpace), + rule("NoSpaceAfterUnaryPredecrementOperator", ts.SyntaxKind.MinusMinusToken, unaryPredecrementExpressions, [isNonJsxSameLineTokenContext], ts.formatting.RuleAction.DeleteSpace), + rule("NoSpaceBeforeUnaryPostincrementOperator", unaryPostincrementExpressions, ts.SyntaxKind.PlusPlusToken, [isNonJsxSameLineTokenContext, isNotStatementConditionContext], ts.formatting.RuleAction.DeleteSpace), + rule("NoSpaceBeforeUnaryPostdecrementOperator", unaryPostdecrementExpressions, ts.SyntaxKind.MinusMinusToken, [isNonJsxSameLineTokenContext, isNotStatementConditionContext], ts.formatting.RuleAction.DeleteSpace), // More unary operator special-casing. // DevDiv 181814: Be careful when removing leading whitespace // around unary operators. Examples: // 1 - -2 --X--> 1--2 // a + ++b --X--> a+++b - rule("SpaceAfterPostincrementWhenFollowedByAdd", SyntaxKind.PlusPlusToken, SyntaxKind.PlusToken, [isNonJsxSameLineTokenContext, isBinaryOpContext], RuleAction.InsertSpace), - rule("SpaceAfterAddWhenFollowedByUnaryPlus", SyntaxKind.PlusToken, SyntaxKind.PlusToken, [isNonJsxSameLineTokenContext, isBinaryOpContext], RuleAction.InsertSpace), - rule("SpaceAfterAddWhenFollowedByPreincrement", SyntaxKind.PlusToken, SyntaxKind.PlusPlusToken, [isNonJsxSameLineTokenContext, isBinaryOpContext], RuleAction.InsertSpace), - rule("SpaceAfterPostdecrementWhenFollowedBySubtract", SyntaxKind.MinusMinusToken, SyntaxKind.MinusToken, [isNonJsxSameLineTokenContext, isBinaryOpContext], RuleAction.InsertSpace), - rule("SpaceAfterSubtractWhenFollowedByUnaryMinus", SyntaxKind.MinusToken, SyntaxKind.MinusToken, [isNonJsxSameLineTokenContext, isBinaryOpContext], RuleAction.InsertSpace), - rule("SpaceAfterSubtractWhenFollowedByPredecrement", SyntaxKind.MinusToken, SyntaxKind.MinusMinusToken, [isNonJsxSameLineTokenContext, isBinaryOpContext], RuleAction.InsertSpace), - - rule("NoSpaceAfterCloseBrace", SyntaxKind.CloseBraceToken, [SyntaxKind.CommaToken, SyntaxKind.SemicolonToken], [isNonJsxSameLineTokenContext], RuleAction.DeleteSpace), + rule("SpaceAfterPostincrementWhenFollowedByAdd", ts.SyntaxKind.PlusPlusToken, ts.SyntaxKind.PlusToken, [isNonJsxSameLineTokenContext, isBinaryOpContext], ts.formatting.RuleAction.InsertSpace), + rule("SpaceAfterAddWhenFollowedByUnaryPlus", ts.SyntaxKind.PlusToken, ts.SyntaxKind.PlusToken, [isNonJsxSameLineTokenContext, isBinaryOpContext], ts.formatting.RuleAction.InsertSpace), + rule("SpaceAfterAddWhenFollowedByPreincrement", ts.SyntaxKind.PlusToken, ts.SyntaxKind.PlusPlusToken, [isNonJsxSameLineTokenContext, isBinaryOpContext], ts.formatting.RuleAction.InsertSpace), + rule("SpaceAfterPostdecrementWhenFollowedBySubtract", ts.SyntaxKind.MinusMinusToken, ts.SyntaxKind.MinusToken, [isNonJsxSameLineTokenContext, isBinaryOpContext], ts.formatting.RuleAction.InsertSpace), + rule("SpaceAfterSubtractWhenFollowedByUnaryMinus", ts.SyntaxKind.MinusToken, ts.SyntaxKind.MinusToken, [isNonJsxSameLineTokenContext, isBinaryOpContext], ts.formatting.RuleAction.InsertSpace), + rule("SpaceAfterSubtractWhenFollowedByPredecrement", ts.SyntaxKind.MinusToken, ts.SyntaxKind.MinusMinusToken, [isNonJsxSameLineTokenContext, isBinaryOpContext], ts.formatting.RuleAction.InsertSpace), + rule("NoSpaceAfterCloseBrace", ts.SyntaxKind.CloseBraceToken, [ts.SyntaxKind.CommaToken, ts.SyntaxKind.SemicolonToken], [isNonJsxSameLineTokenContext], ts.formatting.RuleAction.DeleteSpace), // For functions and control block place } on a new line [multi-line rule] - rule("NewLineBeforeCloseBraceInBlockContext", anyTokenIncludingMultilineComments, SyntaxKind.CloseBraceToken, [isMultilineBlockContext], RuleAction.InsertNewLine), + rule("NewLineBeforeCloseBraceInBlockContext", anyTokenIncludingMultilineComments, ts.SyntaxKind.CloseBraceToken, [isMultilineBlockContext], ts.formatting.RuleAction.InsertNewLine), // Space/new line after }. - rule("SpaceAfterCloseBrace", SyntaxKind.CloseBraceToken, anyTokenExcept(SyntaxKind.CloseParenToken), [isNonJsxSameLineTokenContext, isAfterCodeBlockContext], RuleAction.InsertSpace), + rule("SpaceAfterCloseBrace", ts.SyntaxKind.CloseBraceToken, anyTokenExcept(ts.SyntaxKind.CloseParenToken), [isNonJsxSameLineTokenContext, isAfterCodeBlockContext], ts.formatting.RuleAction.InsertSpace), // Special case for (}, else) and (}, while) since else & while tokens are not part of the tree which makes SpaceAfterCloseBrace rule not applied // Also should not apply to }) - rule("SpaceBetweenCloseBraceAndElse", SyntaxKind.CloseBraceToken, SyntaxKind.ElseKeyword, [isNonJsxSameLineTokenContext], RuleAction.InsertSpace), - rule("SpaceBetweenCloseBraceAndWhile", SyntaxKind.CloseBraceToken, SyntaxKind.WhileKeyword, [isNonJsxSameLineTokenContext], RuleAction.InsertSpace), - rule("NoSpaceBetweenEmptyBraceBrackets", SyntaxKind.OpenBraceToken, SyntaxKind.CloseBraceToken, [isNonJsxSameLineTokenContext, isObjectContext], RuleAction.DeleteSpace), + rule("SpaceBetweenCloseBraceAndElse", ts.SyntaxKind.CloseBraceToken, ts.SyntaxKind.ElseKeyword, [isNonJsxSameLineTokenContext], ts.formatting.RuleAction.InsertSpace), + rule("SpaceBetweenCloseBraceAndWhile", ts.SyntaxKind.CloseBraceToken, ts.SyntaxKind.WhileKeyword, [isNonJsxSameLineTokenContext], ts.formatting.RuleAction.InsertSpace), + rule("NoSpaceBetweenEmptyBraceBrackets", ts.SyntaxKind.OpenBraceToken, ts.SyntaxKind.CloseBraceToken, [isNonJsxSameLineTokenContext, isObjectContext], ts.formatting.RuleAction.DeleteSpace), // Add a space after control dec context if the next character is an open bracket ex: 'if (false)[a, b] = [1, 2];' -> 'if (false) [a, b] = [1, 2];' - rule("SpaceAfterConditionalClosingParen", SyntaxKind.CloseParenToken, SyntaxKind.OpenBracketToken, [isControlDeclContext], RuleAction.InsertSpace), - - rule("NoSpaceBetweenFunctionKeywordAndStar", SyntaxKind.FunctionKeyword, SyntaxKind.AsteriskToken, [isFunctionDeclarationOrFunctionExpressionContext], RuleAction.DeleteSpace), - rule("SpaceAfterStarInGeneratorDeclaration", SyntaxKind.AsteriskToken, SyntaxKind.Identifier, [isFunctionDeclarationOrFunctionExpressionContext], RuleAction.InsertSpace), - - rule("SpaceAfterFunctionInFuncDecl", SyntaxKind.FunctionKeyword, anyToken, [isFunctionDeclContext], RuleAction.InsertSpace), + rule("SpaceAfterConditionalClosingParen", ts.SyntaxKind.CloseParenToken, ts.SyntaxKind.OpenBracketToken, [isControlDeclContext], ts.formatting.RuleAction.InsertSpace), + rule("NoSpaceBetweenFunctionKeywordAndStar", ts.SyntaxKind.FunctionKeyword, ts.SyntaxKind.AsteriskToken, [isFunctionDeclarationOrFunctionExpressionContext], ts.formatting.RuleAction.DeleteSpace), + rule("SpaceAfterStarInGeneratorDeclaration", ts.SyntaxKind.AsteriskToken, ts.SyntaxKind.Identifier, [isFunctionDeclarationOrFunctionExpressionContext], ts.formatting.RuleAction.InsertSpace), + rule("SpaceAfterFunctionInFuncDecl", ts.SyntaxKind.FunctionKeyword, anyToken, [isFunctionDeclContext], ts.formatting.RuleAction.InsertSpace), // Insert new line after { and before } in multi-line contexts. - rule("NewLineAfterOpenBraceInBlockContext", SyntaxKind.OpenBraceToken, anyToken, [isMultilineBlockContext], RuleAction.InsertNewLine), + rule("NewLineAfterOpenBraceInBlockContext", ts.SyntaxKind.OpenBraceToken, anyToken, [isMultilineBlockContext], ts.formatting.RuleAction.InsertNewLine), // For get/set members, we check for (identifier,identifier) since get/set don't have tokens and they are represented as just an identifier token. // Though, we do extra check on the context to make sure we are dealing with get/set node. Example: // get x() {} // set x(val) {} - rule("SpaceAfterGetSetInMember", [SyntaxKind.GetKeyword, SyntaxKind.SetKeyword], SyntaxKind.Identifier, [isFunctionDeclContext], RuleAction.InsertSpace), - - rule("NoSpaceBetweenYieldKeywordAndStar", SyntaxKind.YieldKeyword, SyntaxKind.AsteriskToken, [isNonJsxSameLineTokenContext, isYieldOrYieldStarWithOperand], RuleAction.DeleteSpace), - rule("SpaceBetweenYieldOrYieldStarAndOperand", [SyntaxKind.YieldKeyword, SyntaxKind.AsteriskToken], anyToken, [isNonJsxSameLineTokenContext, isYieldOrYieldStarWithOperand], RuleAction.InsertSpace), - - rule("NoSpaceBetweenReturnAndSemicolon", SyntaxKind.ReturnKeyword, SyntaxKind.SemicolonToken, [isNonJsxSameLineTokenContext], RuleAction.DeleteSpace), - rule("SpaceAfterCertainKeywords", [SyntaxKind.VarKeyword, SyntaxKind.ThrowKeyword, SyntaxKind.NewKeyword, SyntaxKind.DeleteKeyword, SyntaxKind.ReturnKeyword, SyntaxKind.TypeOfKeyword, SyntaxKind.AwaitKeyword], anyToken, [isNonJsxSameLineTokenContext], RuleAction.InsertSpace), - rule("SpaceAfterLetConstInVariableDeclaration", [SyntaxKind.LetKeyword, SyntaxKind.ConstKeyword], anyToken, [isNonJsxSameLineTokenContext, isStartOfVariableDeclarationList], RuleAction.InsertSpace), - rule("NoSpaceBeforeOpenParenInFuncCall", anyToken, SyntaxKind.OpenParenToken, [isNonJsxSameLineTokenContext, isFunctionCallOrNewContext, isPreviousTokenNotComma], RuleAction.DeleteSpace), + rule("SpaceAfterGetSetInMember", [ts.SyntaxKind.GetKeyword, ts.SyntaxKind.SetKeyword], ts.SyntaxKind.Identifier, [isFunctionDeclContext], ts.formatting.RuleAction.InsertSpace), + rule("NoSpaceBetweenYieldKeywordAndStar", ts.SyntaxKind.YieldKeyword, ts.SyntaxKind.AsteriskToken, [isNonJsxSameLineTokenContext, isYieldOrYieldStarWithOperand], ts.formatting.RuleAction.DeleteSpace), + rule("SpaceBetweenYieldOrYieldStarAndOperand", [ts.SyntaxKind.YieldKeyword, ts.SyntaxKind.AsteriskToken], anyToken, [isNonJsxSameLineTokenContext, isYieldOrYieldStarWithOperand], ts.formatting.RuleAction.InsertSpace), + rule("NoSpaceBetweenReturnAndSemicolon", ts.SyntaxKind.ReturnKeyword, ts.SyntaxKind.SemicolonToken, [isNonJsxSameLineTokenContext], ts.formatting.RuleAction.DeleteSpace), + rule("SpaceAfterCertainKeywords", [ts.SyntaxKind.VarKeyword, ts.SyntaxKind.ThrowKeyword, ts.SyntaxKind.NewKeyword, ts.SyntaxKind.DeleteKeyword, ts.SyntaxKind.ReturnKeyword, ts.SyntaxKind.TypeOfKeyword, ts.SyntaxKind.AwaitKeyword], anyToken, [isNonJsxSameLineTokenContext], ts.formatting.RuleAction.InsertSpace), + rule("SpaceAfterLetConstInVariableDeclaration", [ts.SyntaxKind.LetKeyword, ts.SyntaxKind.ConstKeyword], anyToken, [isNonJsxSameLineTokenContext, isStartOfVariableDeclarationList], ts.formatting.RuleAction.InsertSpace), + rule("NoSpaceBeforeOpenParenInFuncCall", anyToken, ts.SyntaxKind.OpenParenToken, [isNonJsxSameLineTokenContext, isFunctionCallOrNewContext, isPreviousTokenNotComma], ts.formatting.RuleAction.DeleteSpace), // Special case for binary operators (that are keywords). For these we have to add a space and shouldn't follow any user options. - rule("SpaceBeforeBinaryKeywordOperator", anyToken, binaryKeywordOperators, [isNonJsxSameLineTokenContext, isBinaryOpContext], RuleAction.InsertSpace), - rule("SpaceAfterBinaryKeywordOperator", binaryKeywordOperators, anyToken, [isNonJsxSameLineTokenContext, isBinaryOpContext], RuleAction.InsertSpace), - - rule("SpaceAfterVoidOperator", SyntaxKind.VoidKeyword, anyToken, [isNonJsxSameLineTokenContext, isVoidOpContext], RuleAction.InsertSpace), + rule("SpaceBeforeBinaryKeywordOperator", anyToken, binaryKeywordOperators, [isNonJsxSameLineTokenContext, isBinaryOpContext], ts.formatting.RuleAction.InsertSpace), + rule("SpaceAfterBinaryKeywordOperator", binaryKeywordOperators, anyToken, [isNonJsxSameLineTokenContext, isBinaryOpContext], ts.formatting.RuleAction.InsertSpace), + rule("SpaceAfterVoidOperator", ts.SyntaxKind.VoidKeyword, anyToken, [isNonJsxSameLineTokenContext, isVoidOpContext], ts.formatting.RuleAction.InsertSpace), // Async-await - rule("SpaceBetweenAsyncAndOpenParen", SyntaxKind.AsyncKeyword, SyntaxKind.OpenParenToken, [isArrowFunctionContext, isNonJsxSameLineTokenContext], RuleAction.InsertSpace), - rule("SpaceBetweenAsyncAndFunctionKeyword", SyntaxKind.AsyncKeyword, [SyntaxKind.FunctionKeyword, SyntaxKind.Identifier], [isNonJsxSameLineTokenContext], RuleAction.InsertSpace), + rule("SpaceBetweenAsyncAndOpenParen", ts.SyntaxKind.AsyncKeyword, ts.SyntaxKind.OpenParenToken, [isArrowFunctionContext, isNonJsxSameLineTokenContext], ts.formatting.RuleAction.InsertSpace), + rule("SpaceBetweenAsyncAndFunctionKeyword", ts.SyntaxKind.AsyncKeyword, [ts.SyntaxKind.FunctionKeyword, ts.SyntaxKind.Identifier], [isNonJsxSameLineTokenContext], ts.formatting.RuleAction.InsertSpace), // Template string - rule("NoSpaceBetweenTagAndTemplateString", [SyntaxKind.Identifier, SyntaxKind.CloseParenToken], [SyntaxKind.NoSubstitutionTemplateLiteral, SyntaxKind.TemplateHead], [isNonJsxSameLineTokenContext], RuleAction.DeleteSpace), + rule("NoSpaceBetweenTagAndTemplateString", [ts.SyntaxKind.Identifier, ts.SyntaxKind.CloseParenToken], [ts.SyntaxKind.NoSubstitutionTemplateLiteral, ts.SyntaxKind.TemplateHead], [isNonJsxSameLineTokenContext], ts.formatting.RuleAction.DeleteSpace), // JSX opening elements - rule("SpaceBeforeJsxAttribute", anyToken, SyntaxKind.Identifier, [isNextTokenParentJsxAttribute, isNonJsxSameLineTokenContext], RuleAction.InsertSpace), - rule("SpaceBeforeSlashInJsxOpeningElement", anyToken, SyntaxKind.SlashToken, [isJsxSelfClosingElementContext, isNonJsxSameLineTokenContext], RuleAction.InsertSpace), - rule("NoSpaceBeforeGreaterThanTokenInJsxOpeningElement", SyntaxKind.SlashToken, SyntaxKind.GreaterThanToken, [isJsxSelfClosingElementContext, isNonJsxSameLineTokenContext], RuleAction.DeleteSpace), - rule("NoSpaceBeforeEqualInJsxAttribute", anyToken, SyntaxKind.EqualsToken, [isJsxAttributeContext, isNonJsxSameLineTokenContext], RuleAction.DeleteSpace), - rule("NoSpaceAfterEqualInJsxAttribute", SyntaxKind.EqualsToken, anyToken, [isJsxAttributeContext, isNonJsxSameLineTokenContext], RuleAction.DeleteSpace), + rule("SpaceBeforeJsxAttribute", anyToken, ts.SyntaxKind.Identifier, [isNextTokenParentJsxAttribute, isNonJsxSameLineTokenContext], ts.formatting.RuleAction.InsertSpace), + rule("SpaceBeforeSlashInJsxOpeningElement", anyToken, ts.SyntaxKind.SlashToken, [isJsxSelfClosingElementContext, isNonJsxSameLineTokenContext], ts.formatting.RuleAction.InsertSpace), + rule("NoSpaceBeforeGreaterThanTokenInJsxOpeningElement", ts.SyntaxKind.SlashToken, ts.SyntaxKind.GreaterThanToken, [isJsxSelfClosingElementContext, isNonJsxSameLineTokenContext], ts.formatting.RuleAction.DeleteSpace), + rule("NoSpaceBeforeEqualInJsxAttribute", anyToken, ts.SyntaxKind.EqualsToken, [isJsxAttributeContext, isNonJsxSameLineTokenContext], ts.formatting.RuleAction.DeleteSpace), + rule("NoSpaceAfterEqualInJsxAttribute", ts.SyntaxKind.EqualsToken, anyToken, [isJsxAttributeContext, isNonJsxSameLineTokenContext], ts.formatting.RuleAction.DeleteSpace), // TypeScript-specific rules // Use of module as a function call. e.g.: import m2 = module("m2"); - rule("NoSpaceAfterModuleImport", [SyntaxKind.ModuleKeyword, SyntaxKind.RequireKeyword], SyntaxKind.OpenParenToken, [isNonJsxSameLineTokenContext], RuleAction.DeleteSpace), + rule("NoSpaceAfterModuleImport", [ts.SyntaxKind.ModuleKeyword, ts.SyntaxKind.RequireKeyword], ts.SyntaxKind.OpenParenToken, [isNonJsxSameLineTokenContext], ts.formatting.RuleAction.DeleteSpace), // Add a space around certain TypeScript keywords - rule( - "SpaceAfterCertainTypeScriptKeywords", - [ - SyntaxKind.AbstractKeyword, - SyntaxKind.ClassKeyword, - SyntaxKind.DeclareKeyword, - SyntaxKind.DefaultKeyword, - SyntaxKind.EnumKeyword, - SyntaxKind.ExportKeyword, - SyntaxKind.ExtendsKeyword, - SyntaxKind.GetKeyword, - SyntaxKind.ImplementsKeyword, - SyntaxKind.ImportKeyword, - SyntaxKind.InterfaceKeyword, - SyntaxKind.ModuleKeyword, - SyntaxKind.NamespaceKeyword, - SyntaxKind.PrivateKeyword, - SyntaxKind.PublicKeyword, - SyntaxKind.ProtectedKeyword, - SyntaxKind.ReadonlyKeyword, - SyntaxKind.SetKeyword, - SyntaxKind.StaticKeyword, - SyntaxKind.TypeKeyword, - SyntaxKind.FromKeyword, - SyntaxKind.KeyOfKeyword, - SyntaxKind.InferKeyword, - ], - anyToken, - [isNonJsxSameLineTokenContext], - RuleAction.InsertSpace), - rule( - "SpaceBeforeCertainTypeScriptKeywords", - anyToken, - [SyntaxKind.ExtendsKeyword, SyntaxKind.ImplementsKeyword, SyntaxKind.FromKeyword], - [isNonJsxSameLineTokenContext], - RuleAction.InsertSpace), + rule("SpaceAfterCertainTypeScriptKeywords", [ + ts.SyntaxKind.AbstractKeyword, + ts.SyntaxKind.ClassKeyword, + ts.SyntaxKind.DeclareKeyword, + ts.SyntaxKind.DefaultKeyword, + ts.SyntaxKind.EnumKeyword, + ts.SyntaxKind.ExportKeyword, + ts.SyntaxKind.ExtendsKeyword, + ts.SyntaxKind.GetKeyword, + ts.SyntaxKind.ImplementsKeyword, + ts.SyntaxKind.ImportKeyword, + ts.SyntaxKind.InterfaceKeyword, + ts.SyntaxKind.ModuleKeyword, + ts.SyntaxKind.NamespaceKeyword, + ts.SyntaxKind.PrivateKeyword, + ts.SyntaxKind.PublicKeyword, + ts.SyntaxKind.ProtectedKeyword, + ts.SyntaxKind.ReadonlyKeyword, + ts.SyntaxKind.SetKeyword, + ts.SyntaxKind.StaticKeyword, + ts.SyntaxKind.TypeKeyword, + ts.SyntaxKind.FromKeyword, + ts.SyntaxKind.KeyOfKeyword, + ts.SyntaxKind.InferKeyword, + ], anyToken, [isNonJsxSameLineTokenContext], ts.formatting.RuleAction.InsertSpace), + rule("SpaceBeforeCertainTypeScriptKeywords", anyToken, [ts.SyntaxKind.ExtendsKeyword, ts.SyntaxKind.ImplementsKeyword, ts.SyntaxKind.FromKeyword], [isNonJsxSameLineTokenContext], ts.formatting.RuleAction.InsertSpace), // Treat string literals in module names as identifiers, and add a space between the literal and the opening Brace braces, e.g.: module "m2" { - rule("SpaceAfterModuleName", SyntaxKind.StringLiteral, SyntaxKind.OpenBraceToken, [isModuleDeclContext], RuleAction.InsertSpace), + rule("SpaceAfterModuleName", ts.SyntaxKind.StringLiteral, ts.SyntaxKind.OpenBraceToken, [isModuleDeclContext], ts.formatting.RuleAction.InsertSpace), // Lambda expressions - rule("SpaceBeforeArrow", anyToken, SyntaxKind.EqualsGreaterThanToken, [isNonJsxSameLineTokenContext], RuleAction.InsertSpace), - rule("SpaceAfterArrow", SyntaxKind.EqualsGreaterThanToken, anyToken, [isNonJsxSameLineTokenContext], RuleAction.InsertSpace), + rule("SpaceBeforeArrow", anyToken, ts.SyntaxKind.EqualsGreaterThanToken, [isNonJsxSameLineTokenContext], ts.formatting.RuleAction.InsertSpace), + rule("SpaceAfterArrow", ts.SyntaxKind.EqualsGreaterThanToken, anyToken, [isNonJsxSameLineTokenContext], ts.formatting.RuleAction.InsertSpace), // Optional parameters and let args - rule("NoSpaceAfterEllipsis", SyntaxKind.DotDotDotToken, SyntaxKind.Identifier, [isNonJsxSameLineTokenContext], RuleAction.DeleteSpace), - rule("NoSpaceAfterOptionalParameters", SyntaxKind.QuestionToken, [SyntaxKind.CloseParenToken, SyntaxKind.CommaToken], [isNonJsxSameLineTokenContext, isNotBinaryOpContext], RuleAction.DeleteSpace), + rule("NoSpaceAfterEllipsis", ts.SyntaxKind.DotDotDotToken, ts.SyntaxKind.Identifier, [isNonJsxSameLineTokenContext], ts.formatting.RuleAction.DeleteSpace), + rule("NoSpaceAfterOptionalParameters", ts.SyntaxKind.QuestionToken, [ts.SyntaxKind.CloseParenToken, ts.SyntaxKind.CommaToken], [isNonJsxSameLineTokenContext, isNotBinaryOpContext], ts.formatting.RuleAction.DeleteSpace), // Remove spaces in empty interface literals. e.g.: x: {} - rule("NoSpaceBetweenEmptyInterfaceBraceBrackets", SyntaxKind.OpenBraceToken, SyntaxKind.CloseBraceToken, [isNonJsxSameLineTokenContext, isObjectTypeContext], RuleAction.DeleteSpace), + rule("NoSpaceBetweenEmptyInterfaceBraceBrackets", ts.SyntaxKind.OpenBraceToken, ts.SyntaxKind.CloseBraceToken, [isNonJsxSameLineTokenContext, isObjectTypeContext], ts.formatting.RuleAction.DeleteSpace), // generics and type assertions - rule("NoSpaceBeforeOpenAngularBracket", typeNames, SyntaxKind.LessThanToken, [isNonJsxSameLineTokenContext, isTypeArgumentOrParameterOrAssertionContext], RuleAction.DeleteSpace), - rule("NoSpaceBetweenCloseParenAndAngularBracket", SyntaxKind.CloseParenToken, SyntaxKind.LessThanToken, [isNonJsxSameLineTokenContext, isTypeArgumentOrParameterOrAssertionContext], RuleAction.DeleteSpace), - rule("NoSpaceAfterOpenAngularBracket", SyntaxKind.LessThanToken, anyToken, [isNonJsxSameLineTokenContext, isTypeArgumentOrParameterOrAssertionContext], RuleAction.DeleteSpace), - rule("NoSpaceBeforeCloseAngularBracket", anyToken, SyntaxKind.GreaterThanToken, [isNonJsxSameLineTokenContext, isTypeArgumentOrParameterOrAssertionContext], RuleAction.DeleteSpace), - rule("NoSpaceAfterCloseAngularBracket", - SyntaxKind.GreaterThanToken, - [SyntaxKind.OpenParenToken, SyntaxKind.OpenBracketToken, SyntaxKind.GreaterThanToken, SyntaxKind.CommaToken], - [isNonJsxSameLineTokenContext, isTypeArgumentOrParameterOrAssertionContext, isNotFunctionDeclContext /*To prevent an interference with the SpaceBeforeOpenParenInFuncDecl rule*/], - RuleAction.DeleteSpace), + rule("NoSpaceBeforeOpenAngularBracket", typeNames, ts.SyntaxKind.LessThanToken, [isNonJsxSameLineTokenContext, isTypeArgumentOrParameterOrAssertionContext], ts.formatting.RuleAction.DeleteSpace), + rule("NoSpaceBetweenCloseParenAndAngularBracket", ts.SyntaxKind.CloseParenToken, ts.SyntaxKind.LessThanToken, [isNonJsxSameLineTokenContext, isTypeArgumentOrParameterOrAssertionContext], ts.formatting.RuleAction.DeleteSpace), + rule("NoSpaceAfterOpenAngularBracket", ts.SyntaxKind.LessThanToken, anyToken, [isNonJsxSameLineTokenContext, isTypeArgumentOrParameterOrAssertionContext], ts.formatting.RuleAction.DeleteSpace), + rule("NoSpaceBeforeCloseAngularBracket", anyToken, ts.SyntaxKind.GreaterThanToken, [isNonJsxSameLineTokenContext, isTypeArgumentOrParameterOrAssertionContext], ts.formatting.RuleAction.DeleteSpace), + rule("NoSpaceAfterCloseAngularBracket", ts.SyntaxKind.GreaterThanToken, [ts.SyntaxKind.OpenParenToken, ts.SyntaxKind.OpenBracketToken, ts.SyntaxKind.GreaterThanToken, ts.SyntaxKind.CommaToken], [isNonJsxSameLineTokenContext, isTypeArgumentOrParameterOrAssertionContext, isNotFunctionDeclContext /*To prevent an interference with the SpaceBeforeOpenParenInFuncDecl rule*/], ts.formatting.RuleAction.DeleteSpace), // decorators - rule("SpaceBeforeAt", [SyntaxKind.CloseParenToken, SyntaxKind.Identifier], SyntaxKind.AtToken, [isNonJsxSameLineTokenContext], RuleAction.InsertSpace), - rule("NoSpaceAfterAt", SyntaxKind.AtToken, anyToken, [isNonJsxSameLineTokenContext], RuleAction.DeleteSpace), + rule("SpaceBeforeAt", [ts.SyntaxKind.CloseParenToken, ts.SyntaxKind.Identifier], ts.SyntaxKind.AtToken, [isNonJsxSameLineTokenContext], ts.formatting.RuleAction.InsertSpace), + rule("NoSpaceAfterAt", ts.SyntaxKind.AtToken, anyToken, [isNonJsxSameLineTokenContext], ts.formatting.RuleAction.DeleteSpace), // Insert space after @ in decorator - rule("SpaceAfterDecorator", - anyToken, - [ - SyntaxKind.AbstractKeyword, - SyntaxKind.Identifier, - SyntaxKind.ExportKeyword, - SyntaxKind.DefaultKeyword, - SyntaxKind.ClassKeyword, - SyntaxKind.StaticKeyword, - SyntaxKind.PublicKeyword, - SyntaxKind.PrivateKeyword, - SyntaxKind.ProtectedKeyword, - SyntaxKind.GetKeyword, - SyntaxKind.SetKeyword, - SyntaxKind.OpenBracketToken, - SyntaxKind.AsteriskToken, - ], - [isEndOfDecoratorContextOnSameLine], - RuleAction.InsertSpace), - - rule("NoSpaceBeforeNonNullAssertionOperator", anyToken, SyntaxKind.ExclamationToken, [isNonJsxSameLineTokenContext, isNonNullAssertionContext], RuleAction.DeleteSpace), - rule("NoSpaceAfterNewKeywordOnConstructorSignature", SyntaxKind.NewKeyword, SyntaxKind.OpenParenToken, [isNonJsxSameLineTokenContext, isConstructorSignatureContext], RuleAction.DeleteSpace), - rule("SpaceLessThanAndNonJSXTypeAnnotation", SyntaxKind.LessThanToken, SyntaxKind.LessThanToken, [isNonJsxSameLineTokenContext], RuleAction.InsertSpace), + rule("SpaceAfterDecorator", anyToken, [ + ts.SyntaxKind.AbstractKeyword, + ts.SyntaxKind.Identifier, + ts.SyntaxKind.ExportKeyword, + ts.SyntaxKind.DefaultKeyword, + ts.SyntaxKind.ClassKeyword, + ts.SyntaxKind.StaticKeyword, + ts.SyntaxKind.PublicKeyword, + ts.SyntaxKind.PrivateKeyword, + ts.SyntaxKind.ProtectedKeyword, + ts.SyntaxKind.GetKeyword, + ts.SyntaxKind.SetKeyword, + ts.SyntaxKind.OpenBracketToken, + ts.SyntaxKind.AsteriskToken, + ], [isEndOfDecoratorContextOnSameLine], ts.formatting.RuleAction.InsertSpace), + rule("NoSpaceBeforeNonNullAssertionOperator", anyToken, ts.SyntaxKind.ExclamationToken, [isNonJsxSameLineTokenContext, isNonNullAssertionContext], ts.formatting.RuleAction.DeleteSpace), + rule("NoSpaceAfterNewKeywordOnConstructorSignature", ts.SyntaxKind.NewKeyword, ts.SyntaxKind.OpenParenToken, [isNonJsxSameLineTokenContext, isConstructorSignatureContext], ts.formatting.RuleAction.DeleteSpace), + rule("SpaceLessThanAndNonJSXTypeAnnotation", ts.SyntaxKind.LessThanToken, ts.SyntaxKind.LessThanToken, [isNonJsxSameLineTokenContext], ts.formatting.RuleAction.InsertSpace), ]; // These rules are applied after high priority const userConfigurableRules = [ // Treat constructor as an identifier in a function declaration, and remove spaces between constructor and following left parentheses - rule("SpaceAfterConstructor", SyntaxKind.ConstructorKeyword, SyntaxKind.OpenParenToken, [isOptionEnabled("insertSpaceAfterConstructor"), isNonJsxSameLineTokenContext], RuleAction.InsertSpace), - rule("NoSpaceAfterConstructor", SyntaxKind.ConstructorKeyword, SyntaxKind.OpenParenToken, [isOptionDisabledOrUndefined("insertSpaceAfterConstructor"), isNonJsxSameLineTokenContext], RuleAction.DeleteSpace), - - rule("SpaceAfterComma", SyntaxKind.CommaToken, anyToken, [isOptionEnabled("insertSpaceAfterCommaDelimiter"), isNonJsxSameLineTokenContext, isNonJsxElementOrFragmentContext, isNextTokenNotCloseBracket, isNextTokenNotCloseParen], RuleAction.InsertSpace), - rule("NoSpaceAfterComma", SyntaxKind.CommaToken, anyToken, [isOptionDisabledOrUndefined("insertSpaceAfterCommaDelimiter"), isNonJsxSameLineTokenContext, isNonJsxElementOrFragmentContext], RuleAction.DeleteSpace), + rule("SpaceAfterConstructor", ts.SyntaxKind.ConstructorKeyword, ts.SyntaxKind.OpenParenToken, [isOptionEnabled("insertSpaceAfterConstructor"), isNonJsxSameLineTokenContext], ts.formatting.RuleAction.InsertSpace), + rule("NoSpaceAfterConstructor", ts.SyntaxKind.ConstructorKeyword, ts.SyntaxKind.OpenParenToken, [isOptionDisabledOrUndefined("insertSpaceAfterConstructor"), isNonJsxSameLineTokenContext], ts.formatting.RuleAction.DeleteSpace), + rule("SpaceAfterComma", ts.SyntaxKind.CommaToken, anyToken, [isOptionEnabled("insertSpaceAfterCommaDelimiter"), isNonJsxSameLineTokenContext, isNonJsxElementOrFragmentContext, isNextTokenNotCloseBracket, isNextTokenNotCloseParen], ts.formatting.RuleAction.InsertSpace), + rule("NoSpaceAfterComma", ts.SyntaxKind.CommaToken, anyToken, [isOptionDisabledOrUndefined("insertSpaceAfterCommaDelimiter"), isNonJsxSameLineTokenContext, isNonJsxElementOrFragmentContext], ts.formatting.RuleAction.DeleteSpace), // Insert space after function keyword for anonymous functions - rule("SpaceAfterAnonymousFunctionKeyword", [SyntaxKind.FunctionKeyword, SyntaxKind.AsteriskToken], SyntaxKind.OpenParenToken, [isOptionEnabled("insertSpaceAfterFunctionKeywordForAnonymousFunctions"), isFunctionDeclContext], RuleAction.InsertSpace), - rule("NoSpaceAfterAnonymousFunctionKeyword", [SyntaxKind.FunctionKeyword, SyntaxKind.AsteriskToken], SyntaxKind.OpenParenToken, [isOptionDisabledOrUndefined("insertSpaceAfterFunctionKeywordForAnonymousFunctions"), isFunctionDeclContext], RuleAction.DeleteSpace), + rule("SpaceAfterAnonymousFunctionKeyword", [ts.SyntaxKind.FunctionKeyword, ts.SyntaxKind.AsteriskToken], ts.SyntaxKind.OpenParenToken, [isOptionEnabled("insertSpaceAfterFunctionKeywordForAnonymousFunctions"), isFunctionDeclContext], ts.formatting.RuleAction.InsertSpace), + rule("NoSpaceAfterAnonymousFunctionKeyword", [ts.SyntaxKind.FunctionKeyword, ts.SyntaxKind.AsteriskToken], ts.SyntaxKind.OpenParenToken, [isOptionDisabledOrUndefined("insertSpaceAfterFunctionKeywordForAnonymousFunctions"), isFunctionDeclContext], ts.formatting.RuleAction.DeleteSpace), // Insert space after keywords in control flow statements - rule("SpaceAfterKeywordInControl", keywords, SyntaxKind.OpenParenToken, [isOptionEnabled("insertSpaceAfterKeywordsInControlFlowStatements"), isControlDeclContext], RuleAction.InsertSpace), - rule("NoSpaceAfterKeywordInControl", keywords, SyntaxKind.OpenParenToken, [isOptionDisabledOrUndefined("insertSpaceAfterKeywordsInControlFlowStatements"), isControlDeclContext], RuleAction.DeleteSpace), + rule("SpaceAfterKeywordInControl", keywords, ts.SyntaxKind.OpenParenToken, [isOptionEnabled("insertSpaceAfterKeywordsInControlFlowStatements"), isControlDeclContext], ts.formatting.RuleAction.InsertSpace), + rule("NoSpaceAfterKeywordInControl", keywords, ts.SyntaxKind.OpenParenToken, [isOptionDisabledOrUndefined("insertSpaceAfterKeywordsInControlFlowStatements"), isControlDeclContext], ts.formatting.RuleAction.DeleteSpace), // Insert space after opening and before closing nonempty parenthesis - rule("SpaceAfterOpenParen", SyntaxKind.OpenParenToken, anyToken, [isOptionEnabled("insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis"), isNonJsxSameLineTokenContext], RuleAction.InsertSpace), - rule("SpaceBeforeCloseParen", anyToken, SyntaxKind.CloseParenToken, [isOptionEnabled("insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis"), isNonJsxSameLineTokenContext], RuleAction.InsertSpace), - rule("SpaceBetweenOpenParens", SyntaxKind.OpenParenToken, SyntaxKind.OpenParenToken, [isOptionEnabled("insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis"), isNonJsxSameLineTokenContext], RuleAction.InsertSpace), - rule("NoSpaceBetweenParens", SyntaxKind.OpenParenToken, SyntaxKind.CloseParenToken, [isNonJsxSameLineTokenContext], RuleAction.DeleteSpace), - rule("NoSpaceAfterOpenParen", SyntaxKind.OpenParenToken, anyToken, [isOptionDisabledOrUndefined("insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis"), isNonJsxSameLineTokenContext], RuleAction.DeleteSpace), - rule("NoSpaceBeforeCloseParen", anyToken, SyntaxKind.CloseParenToken, [isOptionDisabledOrUndefined("insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis"), isNonJsxSameLineTokenContext], RuleAction.DeleteSpace), + rule("SpaceAfterOpenParen", ts.SyntaxKind.OpenParenToken, anyToken, [isOptionEnabled("insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis"), isNonJsxSameLineTokenContext], ts.formatting.RuleAction.InsertSpace), + rule("SpaceBeforeCloseParen", anyToken, ts.SyntaxKind.CloseParenToken, [isOptionEnabled("insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis"), isNonJsxSameLineTokenContext], ts.formatting.RuleAction.InsertSpace), + rule("SpaceBetweenOpenParens", ts.SyntaxKind.OpenParenToken, ts.SyntaxKind.OpenParenToken, [isOptionEnabled("insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis"), isNonJsxSameLineTokenContext], ts.formatting.RuleAction.InsertSpace), + rule("NoSpaceBetweenParens", ts.SyntaxKind.OpenParenToken, ts.SyntaxKind.CloseParenToken, [isNonJsxSameLineTokenContext], ts.formatting.RuleAction.DeleteSpace), + rule("NoSpaceAfterOpenParen", ts.SyntaxKind.OpenParenToken, anyToken, [isOptionDisabledOrUndefined("insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis"), isNonJsxSameLineTokenContext], ts.formatting.RuleAction.DeleteSpace), + rule("NoSpaceBeforeCloseParen", anyToken, ts.SyntaxKind.CloseParenToken, [isOptionDisabledOrUndefined("insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis"), isNonJsxSameLineTokenContext], ts.formatting.RuleAction.DeleteSpace), // Insert space after opening and before closing nonempty brackets - rule("SpaceAfterOpenBracket", SyntaxKind.OpenBracketToken, anyToken, [isOptionEnabled("insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets"), isNonJsxSameLineTokenContext], RuleAction.InsertSpace), - rule("SpaceBeforeCloseBracket", anyToken, SyntaxKind.CloseBracketToken, [isOptionEnabled("insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets"), isNonJsxSameLineTokenContext], RuleAction.InsertSpace), - rule("NoSpaceBetweenBrackets", SyntaxKind.OpenBracketToken, SyntaxKind.CloseBracketToken, [isNonJsxSameLineTokenContext], RuleAction.DeleteSpace), - rule("NoSpaceAfterOpenBracket", SyntaxKind.OpenBracketToken, anyToken, [isOptionDisabledOrUndefined("insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets"), isNonJsxSameLineTokenContext], RuleAction.DeleteSpace), - rule("NoSpaceBeforeCloseBracket", anyToken, SyntaxKind.CloseBracketToken, [isOptionDisabledOrUndefined("insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets"), isNonJsxSameLineTokenContext], RuleAction.DeleteSpace), + rule("SpaceAfterOpenBracket", ts.SyntaxKind.OpenBracketToken, anyToken, [isOptionEnabled("insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets"), isNonJsxSameLineTokenContext], ts.formatting.RuleAction.InsertSpace), + rule("SpaceBeforeCloseBracket", anyToken, ts.SyntaxKind.CloseBracketToken, [isOptionEnabled("insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets"), isNonJsxSameLineTokenContext], ts.formatting.RuleAction.InsertSpace), + rule("NoSpaceBetweenBrackets", ts.SyntaxKind.OpenBracketToken, ts.SyntaxKind.CloseBracketToken, [isNonJsxSameLineTokenContext], ts.formatting.RuleAction.DeleteSpace), + rule("NoSpaceAfterOpenBracket", ts.SyntaxKind.OpenBracketToken, anyToken, [isOptionDisabledOrUndefined("insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets"), isNonJsxSameLineTokenContext], ts.formatting.RuleAction.DeleteSpace), + rule("NoSpaceBeforeCloseBracket", anyToken, ts.SyntaxKind.CloseBracketToken, [isOptionDisabledOrUndefined("insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets"), isNonJsxSameLineTokenContext], ts.formatting.RuleAction.DeleteSpace), // Insert a space after { and before } in single-line contexts, but remove space from empty object literals {}. - rule("SpaceAfterOpenBrace", SyntaxKind.OpenBraceToken, anyToken, [isOptionEnabledOrUndefined("insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces"), isBraceWrappedContext], RuleAction.InsertSpace), - rule("SpaceBeforeCloseBrace", anyToken, SyntaxKind.CloseBraceToken, [isOptionEnabledOrUndefined("insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces"), isBraceWrappedContext], RuleAction.InsertSpace), - rule("NoSpaceBetweenEmptyBraceBrackets", SyntaxKind.OpenBraceToken, SyntaxKind.CloseBraceToken, [isNonJsxSameLineTokenContext, isObjectContext], RuleAction.DeleteSpace), - rule("NoSpaceAfterOpenBrace", SyntaxKind.OpenBraceToken, anyToken, [isOptionDisabled("insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces"), isNonJsxSameLineTokenContext], RuleAction.DeleteSpace), - rule("NoSpaceBeforeCloseBrace", anyToken, SyntaxKind.CloseBraceToken, [isOptionDisabled("insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces"), isNonJsxSameLineTokenContext], RuleAction.DeleteSpace), + rule("SpaceAfterOpenBrace", ts.SyntaxKind.OpenBraceToken, anyToken, [isOptionEnabledOrUndefined("insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces"), isBraceWrappedContext], ts.formatting.RuleAction.InsertSpace), + rule("SpaceBeforeCloseBrace", anyToken, ts.SyntaxKind.CloseBraceToken, [isOptionEnabledOrUndefined("insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces"), isBraceWrappedContext], ts.formatting.RuleAction.InsertSpace), + rule("NoSpaceBetweenEmptyBraceBrackets", ts.SyntaxKind.OpenBraceToken, ts.SyntaxKind.CloseBraceToken, [isNonJsxSameLineTokenContext, isObjectContext], ts.formatting.RuleAction.DeleteSpace), + rule("NoSpaceAfterOpenBrace", ts.SyntaxKind.OpenBraceToken, anyToken, [isOptionDisabled("insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces"), isNonJsxSameLineTokenContext], ts.formatting.RuleAction.DeleteSpace), + rule("NoSpaceBeforeCloseBrace", anyToken, ts.SyntaxKind.CloseBraceToken, [isOptionDisabled("insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces"), isNonJsxSameLineTokenContext], ts.formatting.RuleAction.DeleteSpace), // Insert a space after opening and before closing empty brace brackets - rule("SpaceBetweenEmptyBraceBrackets", SyntaxKind.OpenBraceToken, SyntaxKind.CloseBraceToken, [isOptionEnabled("insertSpaceAfterOpeningAndBeforeClosingEmptyBraces")], RuleAction.InsertSpace), - rule("NoSpaceBetweenEmptyBraceBrackets", SyntaxKind.OpenBraceToken, SyntaxKind.CloseBraceToken, [isOptionDisabled("insertSpaceAfterOpeningAndBeforeClosingEmptyBraces"), isNonJsxSameLineTokenContext], RuleAction.DeleteSpace), + rule("SpaceBetweenEmptyBraceBrackets", ts.SyntaxKind.OpenBraceToken, ts.SyntaxKind.CloseBraceToken, [isOptionEnabled("insertSpaceAfterOpeningAndBeforeClosingEmptyBraces")], ts.formatting.RuleAction.InsertSpace), + rule("NoSpaceBetweenEmptyBraceBrackets", ts.SyntaxKind.OpenBraceToken, ts.SyntaxKind.CloseBraceToken, [isOptionDisabled("insertSpaceAfterOpeningAndBeforeClosingEmptyBraces"), isNonJsxSameLineTokenContext], ts.formatting.RuleAction.DeleteSpace), // Insert space after opening and before closing template string braces - rule("SpaceAfterTemplateHeadAndMiddle", [SyntaxKind.TemplateHead, SyntaxKind.TemplateMiddle], anyToken, [isOptionEnabled("insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces"), isNonJsxTextContext], RuleAction.InsertSpace, RuleFlags.CanDeleteNewLines), - rule("SpaceBeforeTemplateMiddleAndTail", anyToken, [SyntaxKind.TemplateMiddle, SyntaxKind.TemplateTail], [isOptionEnabled("insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces"), isNonJsxSameLineTokenContext], RuleAction.InsertSpace), - rule("NoSpaceAfterTemplateHeadAndMiddle", [SyntaxKind.TemplateHead, SyntaxKind.TemplateMiddle], anyToken, [isOptionDisabledOrUndefined("insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces"), isNonJsxTextContext], RuleAction.DeleteSpace, RuleFlags.CanDeleteNewLines), - rule("NoSpaceBeforeTemplateMiddleAndTail", anyToken, [SyntaxKind.TemplateMiddle, SyntaxKind.TemplateTail], [isOptionDisabledOrUndefined("insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces"), isNonJsxSameLineTokenContext], RuleAction.DeleteSpace), + rule("SpaceAfterTemplateHeadAndMiddle", [ts.SyntaxKind.TemplateHead, ts.SyntaxKind.TemplateMiddle], anyToken, [isOptionEnabled("insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces"), isNonJsxTextContext], ts.formatting.RuleAction.InsertSpace, ts.formatting.RuleFlags.CanDeleteNewLines), + rule("SpaceBeforeTemplateMiddleAndTail", anyToken, [ts.SyntaxKind.TemplateMiddle, ts.SyntaxKind.TemplateTail], [isOptionEnabled("insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces"), isNonJsxSameLineTokenContext], ts.formatting.RuleAction.InsertSpace), + rule("NoSpaceAfterTemplateHeadAndMiddle", [ts.SyntaxKind.TemplateHead, ts.SyntaxKind.TemplateMiddle], anyToken, [isOptionDisabledOrUndefined("insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces"), isNonJsxTextContext], ts.formatting.RuleAction.DeleteSpace, ts.formatting.RuleFlags.CanDeleteNewLines), + rule("NoSpaceBeforeTemplateMiddleAndTail", anyToken, [ts.SyntaxKind.TemplateMiddle, ts.SyntaxKind.TemplateTail], [isOptionDisabledOrUndefined("insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces"), isNonJsxSameLineTokenContext], ts.formatting.RuleAction.DeleteSpace), // No space after { and before } in JSX expression - rule("SpaceAfterOpenBraceInJsxExpression", SyntaxKind.OpenBraceToken, anyToken, [isOptionEnabled("insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces"), isNonJsxSameLineTokenContext, isJsxExpressionContext], RuleAction.InsertSpace), - rule("SpaceBeforeCloseBraceInJsxExpression", anyToken, SyntaxKind.CloseBraceToken, [isOptionEnabled("insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces"), isNonJsxSameLineTokenContext, isJsxExpressionContext], RuleAction.InsertSpace), - rule("NoSpaceAfterOpenBraceInJsxExpression", SyntaxKind.OpenBraceToken, anyToken, [isOptionDisabledOrUndefined("insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces"), isNonJsxSameLineTokenContext, isJsxExpressionContext], RuleAction.DeleteSpace), - rule("NoSpaceBeforeCloseBraceInJsxExpression", anyToken, SyntaxKind.CloseBraceToken, [isOptionDisabledOrUndefined("insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces"), isNonJsxSameLineTokenContext, isJsxExpressionContext], RuleAction.DeleteSpace), + rule("SpaceAfterOpenBraceInJsxExpression", ts.SyntaxKind.OpenBraceToken, anyToken, [isOptionEnabled("insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces"), isNonJsxSameLineTokenContext, isJsxExpressionContext], ts.formatting.RuleAction.InsertSpace), + rule("SpaceBeforeCloseBraceInJsxExpression", anyToken, ts.SyntaxKind.CloseBraceToken, [isOptionEnabled("insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces"), isNonJsxSameLineTokenContext, isJsxExpressionContext], ts.formatting.RuleAction.InsertSpace), + rule("NoSpaceAfterOpenBraceInJsxExpression", ts.SyntaxKind.OpenBraceToken, anyToken, [isOptionDisabledOrUndefined("insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces"), isNonJsxSameLineTokenContext, isJsxExpressionContext], ts.formatting.RuleAction.DeleteSpace), + rule("NoSpaceBeforeCloseBraceInJsxExpression", anyToken, ts.SyntaxKind.CloseBraceToken, [isOptionDisabledOrUndefined("insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces"), isNonJsxSameLineTokenContext, isJsxExpressionContext], ts.formatting.RuleAction.DeleteSpace), // Insert space after semicolon in for statement - rule("SpaceAfterSemicolonInFor", SyntaxKind.SemicolonToken, anyToken, [isOptionEnabled("insertSpaceAfterSemicolonInForStatements"), isNonJsxSameLineTokenContext, isForContext], RuleAction.InsertSpace), - rule("NoSpaceAfterSemicolonInFor", SyntaxKind.SemicolonToken, anyToken, [isOptionDisabledOrUndefined("insertSpaceAfterSemicolonInForStatements"), isNonJsxSameLineTokenContext, isForContext], RuleAction.DeleteSpace), + rule("SpaceAfterSemicolonInFor", ts.SyntaxKind.SemicolonToken, anyToken, [isOptionEnabled("insertSpaceAfterSemicolonInForStatements"), isNonJsxSameLineTokenContext, isForContext], ts.formatting.RuleAction.InsertSpace), + rule("NoSpaceAfterSemicolonInFor", ts.SyntaxKind.SemicolonToken, anyToken, [isOptionDisabledOrUndefined("insertSpaceAfterSemicolonInForStatements"), isNonJsxSameLineTokenContext, isForContext], ts.formatting.RuleAction.DeleteSpace), // Insert space before and after binary operators - rule("SpaceBeforeBinaryOperator", anyToken, binaryOperators, [isOptionEnabled("insertSpaceBeforeAndAfterBinaryOperators"), isNonJsxSameLineTokenContext, isBinaryOpContext], RuleAction.InsertSpace), - rule("SpaceAfterBinaryOperator", binaryOperators, anyToken, [isOptionEnabled("insertSpaceBeforeAndAfterBinaryOperators"), isNonJsxSameLineTokenContext, isBinaryOpContext], RuleAction.InsertSpace), - rule("NoSpaceBeforeBinaryOperator", anyToken, binaryOperators, [isOptionDisabledOrUndefined("insertSpaceBeforeAndAfterBinaryOperators"), isNonJsxSameLineTokenContext, isBinaryOpContext], RuleAction.DeleteSpace), - rule("NoSpaceAfterBinaryOperator", binaryOperators, anyToken, [isOptionDisabledOrUndefined("insertSpaceBeforeAndAfterBinaryOperators"), isNonJsxSameLineTokenContext, isBinaryOpContext], RuleAction.DeleteSpace), - - rule("SpaceBeforeOpenParenInFuncDecl", anyToken, SyntaxKind.OpenParenToken, [isOptionEnabled("insertSpaceBeforeFunctionParenthesis"), isNonJsxSameLineTokenContext, isFunctionDeclContext], RuleAction.InsertSpace), - rule("NoSpaceBeforeOpenParenInFuncDecl", anyToken, SyntaxKind.OpenParenToken, [isOptionDisabledOrUndefined("insertSpaceBeforeFunctionParenthesis"), isNonJsxSameLineTokenContext, isFunctionDeclContext], RuleAction.DeleteSpace), + rule("SpaceBeforeBinaryOperator", anyToken, binaryOperators, [isOptionEnabled("insertSpaceBeforeAndAfterBinaryOperators"), isNonJsxSameLineTokenContext, isBinaryOpContext], ts.formatting.RuleAction.InsertSpace), + rule("SpaceAfterBinaryOperator", binaryOperators, anyToken, [isOptionEnabled("insertSpaceBeforeAndAfterBinaryOperators"), isNonJsxSameLineTokenContext, isBinaryOpContext], ts.formatting.RuleAction.InsertSpace), + rule("NoSpaceBeforeBinaryOperator", anyToken, binaryOperators, [isOptionDisabledOrUndefined("insertSpaceBeforeAndAfterBinaryOperators"), isNonJsxSameLineTokenContext, isBinaryOpContext], ts.formatting.RuleAction.DeleteSpace), + rule("NoSpaceAfterBinaryOperator", binaryOperators, anyToken, [isOptionDisabledOrUndefined("insertSpaceBeforeAndAfterBinaryOperators"), isNonJsxSameLineTokenContext, isBinaryOpContext], ts.formatting.RuleAction.DeleteSpace), + rule("SpaceBeforeOpenParenInFuncDecl", anyToken, ts.SyntaxKind.OpenParenToken, [isOptionEnabled("insertSpaceBeforeFunctionParenthesis"), isNonJsxSameLineTokenContext, isFunctionDeclContext], ts.formatting.RuleAction.InsertSpace), + rule("NoSpaceBeforeOpenParenInFuncDecl", anyToken, ts.SyntaxKind.OpenParenToken, [isOptionDisabledOrUndefined("insertSpaceBeforeFunctionParenthesis"), isNonJsxSameLineTokenContext, isFunctionDeclContext], ts.formatting.RuleAction.DeleteSpace), // Open Brace braces after control block - rule("NewLineBeforeOpenBraceInControl", controlOpenBraceLeftTokenRange, SyntaxKind.OpenBraceToken, [isOptionEnabled("placeOpenBraceOnNewLineForControlBlocks"), isControlDeclContext, isBeforeMultilineBlockContext], RuleAction.InsertNewLine, RuleFlags.CanDeleteNewLines), + rule("NewLineBeforeOpenBraceInControl", controlOpenBraceLeftTokenRange, ts.SyntaxKind.OpenBraceToken, [isOptionEnabled("placeOpenBraceOnNewLineForControlBlocks"), isControlDeclContext, isBeforeMultilineBlockContext], ts.formatting.RuleAction.InsertNewLine, ts.formatting.RuleFlags.CanDeleteNewLines), // Open Brace braces after function // TypeScript: Function can have return types, which can be made of tons of different token kinds - rule("NewLineBeforeOpenBraceInFunction", functionOpenBraceLeftTokenRange, SyntaxKind.OpenBraceToken, [isOptionEnabled("placeOpenBraceOnNewLineForFunctions"), isFunctionDeclContext, isBeforeMultilineBlockContext], RuleAction.InsertNewLine, RuleFlags.CanDeleteNewLines), + rule("NewLineBeforeOpenBraceInFunction", functionOpenBraceLeftTokenRange, ts.SyntaxKind.OpenBraceToken, [isOptionEnabled("placeOpenBraceOnNewLineForFunctions"), isFunctionDeclContext, isBeforeMultilineBlockContext], ts.formatting.RuleAction.InsertNewLine, ts.formatting.RuleFlags.CanDeleteNewLines), // Open Brace braces after TypeScript module/class/interface - rule("NewLineBeforeOpenBraceInTypeScriptDeclWithBlock", typeScriptOpenBraceLeftTokenRange, SyntaxKind.OpenBraceToken, [isOptionEnabled("placeOpenBraceOnNewLineForFunctions"), isTypeScriptDeclWithBlockContext, isBeforeMultilineBlockContext], RuleAction.InsertNewLine, RuleFlags.CanDeleteNewLines), - - rule("SpaceAfterTypeAssertion", SyntaxKind.GreaterThanToken, anyToken, [isOptionEnabled("insertSpaceAfterTypeAssertion"), isNonJsxSameLineTokenContext, isTypeAssertionContext], RuleAction.InsertSpace), - rule("NoSpaceAfterTypeAssertion", SyntaxKind.GreaterThanToken, anyToken, [isOptionDisabledOrUndefined("insertSpaceAfterTypeAssertion"), isNonJsxSameLineTokenContext, isTypeAssertionContext], RuleAction.DeleteSpace), - - rule("SpaceBeforeTypeAnnotation", anyToken, [SyntaxKind.QuestionToken, SyntaxKind.ColonToken], [isOptionEnabled("insertSpaceBeforeTypeAnnotation"), isNonJsxSameLineTokenContext, isTypeAnnotationContext], RuleAction.InsertSpace), - rule("NoSpaceBeforeTypeAnnotation", anyToken, [SyntaxKind.QuestionToken, SyntaxKind.ColonToken], [isOptionDisabledOrUndefined("insertSpaceBeforeTypeAnnotation"), isNonJsxSameLineTokenContext, isTypeAnnotationContext], RuleAction.DeleteSpace), - - rule("NoOptionalSemicolon", SyntaxKind.SemicolonToken, anyTokenIncludingEOF, [optionEquals("semicolons", SemicolonPreference.Remove), isSemicolonDeletionContext], RuleAction.DeleteToken), - rule("OptionalSemicolon", anyToken, anyTokenIncludingEOF, [optionEquals("semicolons", SemicolonPreference.Insert), isSemicolonInsertionContext], RuleAction.InsertTrailingSemicolon), + rule("NewLineBeforeOpenBraceInTypeScriptDeclWithBlock", typeScriptOpenBraceLeftTokenRange, ts.SyntaxKind.OpenBraceToken, [isOptionEnabled("placeOpenBraceOnNewLineForFunctions"), isTypeScriptDeclWithBlockContext, isBeforeMultilineBlockContext], ts.formatting.RuleAction.InsertNewLine, ts.formatting.RuleFlags.CanDeleteNewLines), + rule("SpaceAfterTypeAssertion", ts.SyntaxKind.GreaterThanToken, anyToken, [isOptionEnabled("insertSpaceAfterTypeAssertion"), isNonJsxSameLineTokenContext, isTypeAssertionContext], ts.formatting.RuleAction.InsertSpace), + rule("NoSpaceAfterTypeAssertion", ts.SyntaxKind.GreaterThanToken, anyToken, [isOptionDisabledOrUndefined("insertSpaceAfterTypeAssertion"), isNonJsxSameLineTokenContext, isTypeAssertionContext], ts.formatting.RuleAction.DeleteSpace), + rule("SpaceBeforeTypeAnnotation", anyToken, [ts.SyntaxKind.QuestionToken, ts.SyntaxKind.ColonToken], [isOptionEnabled("insertSpaceBeforeTypeAnnotation"), isNonJsxSameLineTokenContext, isTypeAnnotationContext], ts.formatting.RuleAction.InsertSpace), + rule("NoSpaceBeforeTypeAnnotation", anyToken, [ts.SyntaxKind.QuestionToken, ts.SyntaxKind.ColonToken], [isOptionDisabledOrUndefined("insertSpaceBeforeTypeAnnotation"), isNonJsxSameLineTokenContext, isTypeAnnotationContext], ts.formatting.RuleAction.DeleteSpace), + rule("NoOptionalSemicolon", ts.SyntaxKind.SemicolonToken, anyTokenIncludingEOF, [optionEquals("semicolons", ts.SemicolonPreference.Remove), isSemicolonDeletionContext], ts.formatting.RuleAction.DeleteToken), + rule("OptionalSemicolon", anyToken, anyTokenIncludingEOF, [optionEquals("semicolons", ts.SemicolonPreference.Insert), isSemicolonInsertionContext], ts.formatting.RuleAction.InsertTrailingSemicolon), ]; // These rules are lower in priority than user-configurable. Rules earlier in this list have priority over rules later in the list. const lowPriorityCommonRules = [ // Space after keyword but not before ; or : or ? - rule("NoSpaceBeforeSemicolon", anyToken, SyntaxKind.SemicolonToken, [isNonJsxSameLineTokenContext], RuleAction.DeleteSpace), - - rule("SpaceBeforeOpenBraceInControl", controlOpenBraceLeftTokenRange, SyntaxKind.OpenBraceToken, [isOptionDisabledOrUndefinedOrTokensOnSameLine("placeOpenBraceOnNewLineForControlBlocks"), isControlDeclContext, isNotFormatOnEnter, isSameLineTokenOrBeforeBlockContext], RuleAction.InsertSpace, RuleFlags.CanDeleteNewLines), - rule("SpaceBeforeOpenBraceInFunction", functionOpenBraceLeftTokenRange, SyntaxKind.OpenBraceToken, [isOptionDisabledOrUndefinedOrTokensOnSameLine("placeOpenBraceOnNewLineForFunctions"), isFunctionDeclContext, isBeforeBlockContext, isNotFormatOnEnter, isSameLineTokenOrBeforeBlockContext], RuleAction.InsertSpace, RuleFlags.CanDeleteNewLines), - rule("SpaceBeforeOpenBraceInTypeScriptDeclWithBlock", typeScriptOpenBraceLeftTokenRange, SyntaxKind.OpenBraceToken, [isOptionDisabledOrUndefinedOrTokensOnSameLine("placeOpenBraceOnNewLineForFunctions"), isTypeScriptDeclWithBlockContext, isNotFormatOnEnter, isSameLineTokenOrBeforeBlockContext], RuleAction.InsertSpace, RuleFlags.CanDeleteNewLines), - - rule("NoSpaceBeforeComma", anyToken, SyntaxKind.CommaToken, [isNonJsxSameLineTokenContext], RuleAction.DeleteSpace), + rule("NoSpaceBeforeSemicolon", anyToken, ts.SyntaxKind.SemicolonToken, [isNonJsxSameLineTokenContext], ts.formatting.RuleAction.DeleteSpace), + rule("SpaceBeforeOpenBraceInControl", controlOpenBraceLeftTokenRange, ts.SyntaxKind.OpenBraceToken, [isOptionDisabledOrUndefinedOrTokensOnSameLine("placeOpenBraceOnNewLineForControlBlocks"), isControlDeclContext, isNotFormatOnEnter, isSameLineTokenOrBeforeBlockContext], ts.formatting.RuleAction.InsertSpace, ts.formatting.RuleFlags.CanDeleteNewLines), + rule("SpaceBeforeOpenBraceInFunction", functionOpenBraceLeftTokenRange, ts.SyntaxKind.OpenBraceToken, [isOptionDisabledOrUndefinedOrTokensOnSameLine("placeOpenBraceOnNewLineForFunctions"), isFunctionDeclContext, isBeforeBlockContext, isNotFormatOnEnter, isSameLineTokenOrBeforeBlockContext], ts.formatting.RuleAction.InsertSpace, ts.formatting.RuleFlags.CanDeleteNewLines), + rule("SpaceBeforeOpenBraceInTypeScriptDeclWithBlock", typeScriptOpenBraceLeftTokenRange, ts.SyntaxKind.OpenBraceToken, [isOptionDisabledOrUndefinedOrTokensOnSameLine("placeOpenBraceOnNewLineForFunctions"), isTypeScriptDeclWithBlockContext, isNotFormatOnEnter, isSameLineTokenOrBeforeBlockContext], ts.formatting.RuleAction.InsertSpace, ts.formatting.RuleFlags.CanDeleteNewLines), + rule("NoSpaceBeforeComma", anyToken, ts.SyntaxKind.CommaToken, [isNonJsxSameLineTokenContext], ts.formatting.RuleAction.DeleteSpace), // No space before and after indexer `x[]` - rule("NoSpaceBeforeOpenBracket", anyTokenExcept(SyntaxKind.AsyncKeyword, SyntaxKind.CaseKeyword), SyntaxKind.OpenBracketToken, [isNonJsxSameLineTokenContext], RuleAction.DeleteSpace), - rule("NoSpaceAfterCloseBracket", SyntaxKind.CloseBracketToken, anyToken, [isNonJsxSameLineTokenContext, isNotBeforeBlockInFunctionDeclarationContext], RuleAction.DeleteSpace), - rule("SpaceAfterSemicolon", SyntaxKind.SemicolonToken, anyToken, [isNonJsxSameLineTokenContext], RuleAction.InsertSpace), + rule("NoSpaceBeforeOpenBracket", anyTokenExcept(ts.SyntaxKind.AsyncKeyword, ts.SyntaxKind.CaseKeyword), ts.SyntaxKind.OpenBracketToken, [isNonJsxSameLineTokenContext], ts.formatting.RuleAction.DeleteSpace), + rule("NoSpaceAfterCloseBracket", ts.SyntaxKind.CloseBracketToken, anyToken, [isNonJsxSameLineTokenContext, isNotBeforeBlockInFunctionDeclarationContext], ts.formatting.RuleAction.DeleteSpace), + rule("SpaceAfterSemicolon", ts.SyntaxKind.SemicolonToken, anyToken, [isNonJsxSameLineTokenContext], ts.formatting.RuleAction.InsertSpace), // Remove extra space between for and await - rule("SpaceBetweenForAndAwaitKeyword", SyntaxKind.ForKeyword, SyntaxKind.AwaitKeyword, [isNonJsxSameLineTokenContext], RuleAction.InsertSpace), + rule("SpaceBetweenForAndAwaitKeyword", ts.SyntaxKind.ForKeyword, ts.SyntaxKind.AwaitKeyword, [isNonJsxSameLineTokenContext], ts.formatting.RuleAction.InsertSpace), // Add a space between statements. All keywords except (do,else,case) has open/close parens after them. // So, we have a rule to add a space for [),Any], [do,Any], [else,Any], and [case,Any] - rule( - "SpaceBetweenStatements", - [SyntaxKind.CloseParenToken, SyntaxKind.DoKeyword, SyntaxKind.ElseKeyword, SyntaxKind.CaseKeyword], - anyToken, - [isNonJsxSameLineTokenContext, isNonJsxElementOrFragmentContext, isNotForContext], - RuleAction.InsertSpace), + rule("SpaceBetweenStatements", [ts.SyntaxKind.CloseParenToken, ts.SyntaxKind.DoKeyword, ts.SyntaxKind.ElseKeyword, ts.SyntaxKind.CaseKeyword], anyToken, [isNonJsxSameLineTokenContext, isNonJsxElementOrFragmentContext, isNotForContext], ts.formatting.RuleAction.InsertSpace), // This low-pri rule takes care of "try {", "catch {" and "finally {" in case the rule SpaceBeforeOpenBraceInControl didn't execute on FormatOnEnter. - rule("SpaceAfterTryCatchFinally", [SyntaxKind.TryKeyword, SyntaxKind.CatchKeyword, SyntaxKind.FinallyKeyword], SyntaxKind.OpenBraceToken, [isNonJsxSameLineTokenContext], RuleAction.InsertSpace), + rule("SpaceAfterTryCatchFinally", [ts.SyntaxKind.TryKeyword, ts.SyntaxKind.CatchKeyword, ts.SyntaxKind.FinallyKeyword], ts.SyntaxKind.OpenBraceToken, [isNonJsxSameLineTokenContext], ts.formatting.RuleAction.InsertSpace), ]; return [ @@ -372,29 +333,22 @@ namespace ts.formatting { * @param action a declaration of the expected whitespace * @param flags whether the rule deletes a line or not, defaults to no-op */ - function rule( - debugName: string, - left: SyntaxKind | readonly SyntaxKind[] | TokenRange, - right: SyntaxKind | readonly SyntaxKind[] | TokenRange, - context: readonly ContextPredicate[], - action: RuleAction, - flags: RuleFlags = RuleFlags.None, - ): RuleSpec { + function rule(debugName: string, left: ts.SyntaxKind | readonly ts.SyntaxKind[] | ts.formatting.TokenRange, right: ts.SyntaxKind | readonly ts.SyntaxKind[] | ts.formatting.TokenRange, context: readonly ts.formatting.ContextPredicate[], action: ts.formatting.RuleAction, flags: ts.formatting.RuleFlags = ts.formatting.RuleFlags.None): RuleSpec { return { leftTokenRange: toTokenRange(left), rightTokenRange: toTokenRange(right), rule: { debugName, context, action, flags } }; } - function tokenRangeFrom(tokens: readonly SyntaxKind[]): TokenRange { + function tokenRangeFrom(tokens: readonly ts.SyntaxKind[]): ts.formatting.TokenRange { return { tokens, isSpecific: true }; } - function toTokenRange(arg: SyntaxKind | readonly SyntaxKind[] | TokenRange): TokenRange { - return typeof arg === "number" ? tokenRangeFrom([arg]) : isArray(arg) ? tokenRangeFrom(arg) : arg; + function toTokenRange(arg: ts.SyntaxKind | readonly ts.SyntaxKind[] | ts.formatting.TokenRange): ts.formatting.TokenRange { + return typeof arg === "number" ? tokenRangeFrom([arg]) : ts.isArray(arg) ? tokenRangeFrom(arg) : arg; } - function tokenRangeFromRange(from: SyntaxKind, to: SyntaxKind, except: readonly SyntaxKind[] = []): TokenRange { - const tokens: SyntaxKind[] = []; + function tokenRangeFromRange(from: ts.SyntaxKind, to: ts.SyntaxKind, except: readonly ts.SyntaxKind[] = []): ts.formatting.TokenRange { + const tokens: ts.SyntaxKind[] = []; for (let token = from; token <= to; token++) { - if (!contains(except, token)) { + if (!ts.contains(except, token)) { tokens.push(token); } } @@ -405,226 +359,224 @@ namespace ts.formatting { /// Contexts /// - function optionEquals(optionName: K, optionValue: FormatCodeSettings[K]): (context: FormattingContext) => boolean { + function optionEquals(optionName: K, optionValue: ts.FormatCodeSettings[K]): (context: ts.formatting.FormattingContext) => boolean { return (context) => context.options && context.options[optionName] === optionValue; } - function isOptionEnabled(optionName: keyof FormatCodeSettings): (context: FormattingContext) => boolean { + function isOptionEnabled(optionName: keyof ts.FormatCodeSettings): (context: ts.formatting.FormattingContext) => boolean { return (context) => context.options && context.options.hasOwnProperty(optionName) && !!context.options[optionName]; } - function isOptionDisabled(optionName: keyof FormatCodeSettings): (context: FormattingContext) => boolean { + function isOptionDisabled(optionName: keyof ts.FormatCodeSettings): (context: ts.formatting.FormattingContext) => boolean { return (context) => context.options && context.options.hasOwnProperty(optionName) && !context.options[optionName]; } - function isOptionDisabledOrUndefined(optionName: keyof FormatCodeSettings): (context: FormattingContext) => boolean { + function isOptionDisabledOrUndefined(optionName: keyof ts.FormatCodeSettings): (context: ts.formatting.FormattingContext) => boolean { return (context) => !context.options || !context.options.hasOwnProperty(optionName) || !context.options[optionName]; } - function isOptionDisabledOrUndefinedOrTokensOnSameLine(optionName: keyof FormatCodeSettings): (context: FormattingContext) => boolean { + function isOptionDisabledOrUndefinedOrTokensOnSameLine(optionName: keyof ts.FormatCodeSettings): (context: ts.formatting.FormattingContext) => boolean { return (context) => !context.options || !context.options.hasOwnProperty(optionName) || !context.options[optionName] || context.TokensAreOnSameLine(); } - function isOptionEnabledOrUndefined(optionName: keyof FormatCodeSettings): (context: FormattingContext) => boolean { + function isOptionEnabledOrUndefined(optionName: keyof ts.FormatCodeSettings): (context: ts.formatting.FormattingContext) => boolean { return (context) => !context.options || !context.options.hasOwnProperty(optionName) || !!context.options[optionName]; } - function isForContext(context: FormattingContext): boolean { - return context.contextNode.kind === SyntaxKind.ForStatement; + function isForContext(context: ts.formatting.FormattingContext): boolean { + return context.contextNode.kind === ts.SyntaxKind.ForStatement; } - function isNotForContext(context: FormattingContext): boolean { + function isNotForContext(context: ts.formatting.FormattingContext): boolean { return !isForContext(context); } - function isBinaryOpContext(context: FormattingContext): boolean { + function isBinaryOpContext(context: ts.formatting.FormattingContext): boolean { switch (context.contextNode.kind) { - case SyntaxKind.BinaryExpression: - return (context.contextNode as BinaryExpression).operatorToken.kind !== SyntaxKind.CommaToken; - case SyntaxKind.ConditionalExpression: - case SyntaxKind.ConditionalType: - case SyntaxKind.AsExpression: - case SyntaxKind.ExportSpecifier: - case SyntaxKind.ImportSpecifier: - case SyntaxKind.TypePredicate: - case SyntaxKind.UnionType: - case SyntaxKind.IntersectionType: + case ts.SyntaxKind.BinaryExpression: + return (context.contextNode as ts.BinaryExpression).operatorToken.kind !== ts.SyntaxKind.CommaToken; + case ts.SyntaxKind.ConditionalExpression: + case ts.SyntaxKind.ConditionalType: + case ts.SyntaxKind.AsExpression: + case ts.SyntaxKind.ExportSpecifier: + case ts.SyntaxKind.ImportSpecifier: + case ts.SyntaxKind.TypePredicate: + case ts.SyntaxKind.UnionType: + case ts.SyntaxKind.IntersectionType: return true; // equals in binding elements: function foo([[x, y] = [1, 2]]) - case SyntaxKind.BindingElement: + case ts.SyntaxKind.BindingElement: // equals in type X = ... // falls through - case SyntaxKind.TypeAliasDeclaration: + case ts.SyntaxKind.TypeAliasDeclaration: // equal in import a = module('a'); // falls through - case SyntaxKind.ImportEqualsDeclaration: + case ts.SyntaxKind.ImportEqualsDeclaration: // equal in export = 1 // falls through - case SyntaxKind.ExportAssignment: + case ts.SyntaxKind.ExportAssignment: // equal in let a = 0 // falls through - case SyntaxKind.VariableDeclaration: + case ts.SyntaxKind.VariableDeclaration: // equal in p = 0 // falls through - case SyntaxKind.Parameter: - case SyntaxKind.EnumMember: - case SyntaxKind.PropertyDeclaration: - case SyntaxKind.PropertySignature: - return context.currentTokenSpan.kind === SyntaxKind.EqualsToken || context.nextTokenSpan.kind === SyntaxKind.EqualsToken; + case ts.SyntaxKind.Parameter: + case ts.SyntaxKind.EnumMember: + case ts.SyntaxKind.PropertyDeclaration: + case ts.SyntaxKind.PropertySignature: + return context.currentTokenSpan.kind === ts.SyntaxKind.EqualsToken || context.nextTokenSpan.kind === ts.SyntaxKind.EqualsToken; // "in" keyword in for (let x in []) { } - case SyntaxKind.ForInStatement: + case ts.SyntaxKind.ForInStatement: // "in" keyword in [P in keyof T]: T[P] // falls through - case SyntaxKind.TypeParameter: - return context.currentTokenSpan.kind === SyntaxKind.InKeyword || context.nextTokenSpan.kind === SyntaxKind.InKeyword || context.currentTokenSpan.kind === SyntaxKind.EqualsToken || context.nextTokenSpan.kind === SyntaxKind.EqualsToken; + case ts.SyntaxKind.TypeParameter: + return context.currentTokenSpan.kind === ts.SyntaxKind.InKeyword || context.nextTokenSpan.kind === ts.SyntaxKind.InKeyword || context.currentTokenSpan.kind === ts.SyntaxKind.EqualsToken || context.nextTokenSpan.kind === ts.SyntaxKind.EqualsToken; // Technically, "of" is not a binary operator, but format it the same way as "in" - case SyntaxKind.ForOfStatement: - return context.currentTokenSpan.kind === SyntaxKind.OfKeyword || context.nextTokenSpan.kind === SyntaxKind.OfKeyword; + case ts.SyntaxKind.ForOfStatement: + return context.currentTokenSpan.kind === ts.SyntaxKind.OfKeyword || context.nextTokenSpan.kind === ts.SyntaxKind.OfKeyword; } return false; } - function isNotBinaryOpContext(context: FormattingContext): boolean { + function isNotBinaryOpContext(context: ts.formatting.FormattingContext): boolean { return !isBinaryOpContext(context); } - function isNotTypeAnnotationContext(context: FormattingContext): boolean { + function isNotTypeAnnotationContext(context: ts.formatting.FormattingContext): boolean { return !isTypeAnnotationContext(context); } - function isTypeAnnotationContext(context: FormattingContext): boolean { + function isTypeAnnotationContext(context: ts.formatting.FormattingContext): boolean { const contextKind = context.contextNode.kind; - return contextKind === SyntaxKind.PropertyDeclaration || - contextKind === SyntaxKind.PropertySignature || - contextKind === SyntaxKind.Parameter || - contextKind === SyntaxKind.VariableDeclaration || - isFunctionLikeKind(contextKind); + return contextKind === ts.SyntaxKind.PropertyDeclaration || + contextKind === ts.SyntaxKind.PropertySignature || + contextKind === ts.SyntaxKind.Parameter || + contextKind === ts.SyntaxKind.VariableDeclaration || + ts.isFunctionLikeKind(contextKind); } - - function isConditionalOperatorContext(context: FormattingContext): boolean { - return context.contextNode.kind === SyntaxKind.ConditionalExpression || - context.contextNode.kind === SyntaxKind.ConditionalType; + function isConditionalOperatorContext(context: ts.formatting.FormattingContext): boolean { + return context.contextNode.kind === ts.SyntaxKind.ConditionalExpression || + context.contextNode.kind === ts.SyntaxKind.ConditionalType; } - - function isSameLineTokenOrBeforeBlockContext(context: FormattingContext): boolean { + function isSameLineTokenOrBeforeBlockContext(context: ts.formatting.FormattingContext): boolean { return context.TokensAreOnSameLine() || isBeforeBlockContext(context); } - function isBraceWrappedContext(context: FormattingContext): boolean { - return context.contextNode.kind === SyntaxKind.ObjectBindingPattern || - context.contextNode.kind === SyntaxKind.MappedType || + function isBraceWrappedContext(context: ts.formatting.FormattingContext): boolean { + return context.contextNode.kind === ts.SyntaxKind.ObjectBindingPattern || + context.contextNode.kind === ts.SyntaxKind.MappedType || isSingleLineBlockContext(context); } // This check is done before an open brace in a control construct, a function, or a typescript block declaration - function isBeforeMultilineBlockContext(context: FormattingContext): boolean { + function isBeforeMultilineBlockContext(context: ts.formatting.FormattingContext): boolean { return isBeforeBlockContext(context) && !(context.NextNodeAllOnSameLine() || context.NextNodeBlockIsOnOneLine()); } - function isMultilineBlockContext(context: FormattingContext): boolean { + function isMultilineBlockContext(context: ts.formatting.FormattingContext): boolean { return isBlockContext(context) && !(context.ContextNodeAllOnSameLine() || context.ContextNodeBlockIsOnOneLine()); } - function isSingleLineBlockContext(context: FormattingContext): boolean { + function isSingleLineBlockContext(context: ts.formatting.FormattingContext): boolean { return isBlockContext(context) && (context.ContextNodeAllOnSameLine() || context.ContextNodeBlockIsOnOneLine()); } - function isBlockContext(context: FormattingContext): boolean { + function isBlockContext(context: ts.formatting.FormattingContext): boolean { return nodeIsBlockContext(context.contextNode); } - function isBeforeBlockContext(context: FormattingContext): boolean { + function isBeforeBlockContext(context: ts.formatting.FormattingContext): boolean { return nodeIsBlockContext(context.nextTokenParent); } // IMPORTANT!!! This method must return true ONLY for nodes with open and close braces as immediate children - function nodeIsBlockContext(node: Node): boolean { + function nodeIsBlockContext(node: ts.Node): boolean { if (nodeIsTypeScriptDeclWithBlockContext(node)) { // This means we are in a context that looks like a block to the user, but in the grammar is actually not a node (it's a class, module, enum, object type literal, etc). return true; } switch (node.kind) { - case SyntaxKind.Block: - case SyntaxKind.CaseBlock: - case SyntaxKind.ObjectLiteralExpression: - case SyntaxKind.ModuleBlock: + case ts.SyntaxKind.Block: + case ts.SyntaxKind.CaseBlock: + case ts.SyntaxKind.ObjectLiteralExpression: + case ts.SyntaxKind.ModuleBlock: return true; } return false; } - function isFunctionDeclContext(context: FormattingContext): boolean { + function isFunctionDeclContext(context: ts.formatting.FormattingContext): boolean { switch (context.contextNode.kind) { - case SyntaxKind.FunctionDeclaration: - case SyntaxKind.MethodDeclaration: - case SyntaxKind.MethodSignature: + case ts.SyntaxKind.FunctionDeclaration: + case ts.SyntaxKind.MethodDeclaration: + case ts.SyntaxKind.MethodSignature: // case SyntaxKind.MemberFunctionDeclaration: // falls through - case SyntaxKind.GetAccessor: - case SyntaxKind.SetAccessor: + case ts.SyntaxKind.GetAccessor: + case ts.SyntaxKind.SetAccessor: // case SyntaxKind.MethodSignature: // falls through - case SyntaxKind.CallSignature: - case SyntaxKind.FunctionExpression: - case SyntaxKind.Constructor: - case SyntaxKind.ArrowFunction: + case ts.SyntaxKind.CallSignature: + case ts.SyntaxKind.FunctionExpression: + case ts.SyntaxKind.Constructor: + case ts.SyntaxKind.ArrowFunction: // case SyntaxKind.ConstructorDeclaration: // case SyntaxKind.SimpleArrowFunctionExpression: // case SyntaxKind.ParenthesizedArrowFunctionExpression: // falls through - case SyntaxKind.InterfaceDeclaration: // This one is not truly a function, but for formatting purposes, it acts just like one + case ts.SyntaxKind.InterfaceDeclaration: // This one is not truly a function, but for formatting purposes, it acts just like one return true; } return false; } - function isNotFunctionDeclContext(context: FormattingContext): boolean { + function isNotFunctionDeclContext(context: ts.formatting.FormattingContext): boolean { return !isFunctionDeclContext(context); } - function isFunctionDeclarationOrFunctionExpressionContext(context: FormattingContext): boolean { - return context.contextNode.kind === SyntaxKind.FunctionDeclaration || context.contextNode.kind === SyntaxKind.FunctionExpression; + function isFunctionDeclarationOrFunctionExpressionContext(context: ts.formatting.FormattingContext): boolean { + return context.contextNode.kind === ts.SyntaxKind.FunctionDeclaration || context.contextNode.kind === ts.SyntaxKind.FunctionExpression; } - function isTypeScriptDeclWithBlockContext(context: FormattingContext): boolean { + function isTypeScriptDeclWithBlockContext(context: ts.formatting.FormattingContext): boolean { return nodeIsTypeScriptDeclWithBlockContext(context.contextNode); } - function nodeIsTypeScriptDeclWithBlockContext(node: Node): boolean { + function nodeIsTypeScriptDeclWithBlockContext(node: ts.Node): boolean { switch (node.kind) { - case SyntaxKind.ClassDeclaration: - case SyntaxKind.ClassExpression: - case SyntaxKind.InterfaceDeclaration: - case SyntaxKind.EnumDeclaration: - case SyntaxKind.TypeLiteral: - case SyntaxKind.ModuleDeclaration: - case SyntaxKind.ExportDeclaration: - case SyntaxKind.NamedExports: - case SyntaxKind.ImportDeclaration: - case SyntaxKind.NamedImports: + case ts.SyntaxKind.ClassDeclaration: + case ts.SyntaxKind.ClassExpression: + case ts.SyntaxKind.InterfaceDeclaration: + case ts.SyntaxKind.EnumDeclaration: + case ts.SyntaxKind.TypeLiteral: + case ts.SyntaxKind.ModuleDeclaration: + case ts.SyntaxKind.ExportDeclaration: + case ts.SyntaxKind.NamedExports: + case ts.SyntaxKind.ImportDeclaration: + case ts.SyntaxKind.NamedImports: return true; } return false; } - function isAfterCodeBlockContext(context: FormattingContext): boolean { + function isAfterCodeBlockContext(context: ts.formatting.FormattingContext): boolean { switch (context.currentTokenParent.kind) { - case SyntaxKind.ClassDeclaration: - case SyntaxKind.ModuleDeclaration: - case SyntaxKind.EnumDeclaration: - case SyntaxKind.CatchClause: - case SyntaxKind.ModuleBlock: - case SyntaxKind.SwitchStatement: + case ts.SyntaxKind.ClassDeclaration: + case ts.SyntaxKind.ModuleDeclaration: + case ts.SyntaxKind.EnumDeclaration: + case ts.SyntaxKind.CatchClause: + case ts.SyntaxKind.ModuleBlock: + case ts.SyntaxKind.SwitchStatement: return true; - case SyntaxKind.Block: { + case ts.SyntaxKind.Block: { const blockParent = context.currentTokenParent.parent; // In a codefix scenario, we can't rely on parents being set. So just always return true. - if (!blockParent || blockParent.kind !== SyntaxKind.ArrowFunction && blockParent.kind !== SyntaxKind.FunctionExpression) { + if (!blockParent || blockParent.kind !== ts.SyntaxKind.ArrowFunction && blockParent.kind !== ts.SyntaxKind.FunctionExpression) { return true; } } @@ -632,21 +584,21 @@ namespace ts.formatting { return false; } - function isControlDeclContext(context: FormattingContext): boolean { + function isControlDeclContext(context: ts.formatting.FormattingContext): boolean { switch (context.contextNode.kind) { - case SyntaxKind.IfStatement: - case SyntaxKind.SwitchStatement: - case SyntaxKind.ForStatement: - case SyntaxKind.ForInStatement: - case SyntaxKind.ForOfStatement: - case SyntaxKind.WhileStatement: - case SyntaxKind.TryStatement: - case SyntaxKind.DoStatement: - case SyntaxKind.WithStatement: + case ts.SyntaxKind.IfStatement: + case ts.SyntaxKind.SwitchStatement: + case ts.SyntaxKind.ForStatement: + case ts.SyntaxKind.ForInStatement: + case ts.SyntaxKind.ForOfStatement: + case ts.SyntaxKind.WhileStatement: + case ts.SyntaxKind.TryStatement: + case ts.SyntaxKind.DoStatement: + case ts.SyntaxKind.WithStatement: // TODO // case SyntaxKind.ElseClause: // falls through - case SyntaxKind.CatchClause: + case ts.SyntaxKind.CatchClause: return true; default: @@ -654,130 +606,130 @@ namespace ts.formatting { } } - function isObjectContext(context: FormattingContext): boolean { - return context.contextNode.kind === SyntaxKind.ObjectLiteralExpression; + function isObjectContext(context: ts.formatting.FormattingContext): boolean { + return context.contextNode.kind === ts.SyntaxKind.ObjectLiteralExpression; } - function isFunctionCallContext(context: FormattingContext): boolean { - return context.contextNode.kind === SyntaxKind.CallExpression; + function isFunctionCallContext(context: ts.formatting.FormattingContext): boolean { + return context.contextNode.kind === ts.SyntaxKind.CallExpression; } - function isNewContext(context: FormattingContext): boolean { - return context.contextNode.kind === SyntaxKind.NewExpression; + function isNewContext(context: ts.formatting.FormattingContext): boolean { + return context.contextNode.kind === ts.SyntaxKind.NewExpression; } - function isFunctionCallOrNewContext(context: FormattingContext): boolean { + function isFunctionCallOrNewContext(context: ts.formatting.FormattingContext): boolean { return isFunctionCallContext(context) || isNewContext(context); } - function isPreviousTokenNotComma(context: FormattingContext): boolean { - return context.currentTokenSpan.kind !== SyntaxKind.CommaToken; + function isPreviousTokenNotComma(context: ts.formatting.FormattingContext): boolean { + return context.currentTokenSpan.kind !== ts.SyntaxKind.CommaToken; } - function isNextTokenNotCloseBracket(context: FormattingContext): boolean { - return context.nextTokenSpan.kind !== SyntaxKind.CloseBracketToken; + function isNextTokenNotCloseBracket(context: ts.formatting.FormattingContext): boolean { + return context.nextTokenSpan.kind !== ts.SyntaxKind.CloseBracketToken; } - function isNextTokenNotCloseParen(context: FormattingContext): boolean { - return context.nextTokenSpan.kind !== SyntaxKind.CloseParenToken; + function isNextTokenNotCloseParen(context: ts.formatting.FormattingContext): boolean { + return context.nextTokenSpan.kind !== ts.SyntaxKind.CloseParenToken; } - function isArrowFunctionContext(context: FormattingContext): boolean { - return context.contextNode.kind === SyntaxKind.ArrowFunction; + function isArrowFunctionContext(context: ts.formatting.FormattingContext): boolean { + return context.contextNode.kind === ts.SyntaxKind.ArrowFunction; } - function isImportTypeContext(context: FormattingContext): boolean { - return context.contextNode.kind === SyntaxKind.ImportType; + function isImportTypeContext(context: ts.formatting.FormattingContext): boolean { + return context.contextNode.kind === ts.SyntaxKind.ImportType; } - function isNonJsxSameLineTokenContext(context: FormattingContext): boolean { - return context.TokensAreOnSameLine() && context.contextNode.kind !== SyntaxKind.JsxText; + function isNonJsxSameLineTokenContext(context: ts.formatting.FormattingContext): boolean { + return context.TokensAreOnSameLine() && context.contextNode.kind !== ts.SyntaxKind.JsxText; } - function isNonJsxTextContext(context: FormattingContext): boolean { - return context.contextNode.kind !== SyntaxKind.JsxText; + function isNonJsxTextContext(context: ts.formatting.FormattingContext): boolean { + return context.contextNode.kind !== ts.SyntaxKind.JsxText; } - function isNonJsxElementOrFragmentContext(context: FormattingContext): boolean { - return context.contextNode.kind !== SyntaxKind.JsxElement && context.contextNode.kind !== SyntaxKind.JsxFragment; + function isNonJsxElementOrFragmentContext(context: ts.formatting.FormattingContext): boolean { + return context.contextNode.kind !== ts.SyntaxKind.JsxElement && context.contextNode.kind !== ts.SyntaxKind.JsxFragment; } - function isJsxExpressionContext(context: FormattingContext): boolean { - return context.contextNode.kind === SyntaxKind.JsxExpression || context.contextNode.kind === SyntaxKind.JsxSpreadAttribute; + function isJsxExpressionContext(context: ts.formatting.FormattingContext): boolean { + return context.contextNode.kind === ts.SyntaxKind.JsxExpression || context.contextNode.kind === ts.SyntaxKind.JsxSpreadAttribute; } - function isNextTokenParentJsxAttribute(context: FormattingContext): boolean { - return context.nextTokenParent.kind === SyntaxKind.JsxAttribute; + function isNextTokenParentJsxAttribute(context: ts.formatting.FormattingContext): boolean { + return context.nextTokenParent.kind === ts.SyntaxKind.JsxAttribute; } - function isJsxAttributeContext(context: FormattingContext): boolean { - return context.contextNode.kind === SyntaxKind.JsxAttribute; + function isJsxAttributeContext(context: ts.formatting.FormattingContext): boolean { + return context.contextNode.kind === ts.SyntaxKind.JsxAttribute; } - function isJsxSelfClosingElementContext(context: FormattingContext): boolean { - return context.contextNode.kind === SyntaxKind.JsxSelfClosingElement; + function isJsxSelfClosingElementContext(context: ts.formatting.FormattingContext): boolean { + return context.contextNode.kind === ts.SyntaxKind.JsxSelfClosingElement; } - function isNotBeforeBlockInFunctionDeclarationContext(context: FormattingContext): boolean { + function isNotBeforeBlockInFunctionDeclarationContext(context: ts.formatting.FormattingContext): boolean { return !isFunctionDeclContext(context) && !isBeforeBlockContext(context); } - function isEndOfDecoratorContextOnSameLine(context: FormattingContext): boolean { + function isEndOfDecoratorContextOnSameLine(context: ts.formatting.FormattingContext): boolean { return context.TokensAreOnSameLine() && !!context.contextNode.decorators && nodeIsInDecoratorContext(context.currentTokenParent) && !nodeIsInDecoratorContext(context.nextTokenParent); } - function nodeIsInDecoratorContext(node: Node): boolean { - while (isExpressionNode(node)) { + function nodeIsInDecoratorContext(node: ts.Node): boolean { + while (ts.isExpressionNode(node)) { node = node.parent; } - return node.kind === SyntaxKind.Decorator; + return node.kind === ts.SyntaxKind.Decorator; } - function isStartOfVariableDeclarationList(context: FormattingContext): boolean { - return context.currentTokenParent.kind === SyntaxKind.VariableDeclarationList && + function isStartOfVariableDeclarationList(context: ts.formatting.FormattingContext): boolean { + return context.currentTokenParent.kind === ts.SyntaxKind.VariableDeclarationList && context.currentTokenParent.getStart(context.sourceFile) === context.currentTokenSpan.pos; } - function isNotFormatOnEnter(context: FormattingContext): boolean { - return context.formattingRequestKind !== FormattingRequestKind.FormatOnEnter; + function isNotFormatOnEnter(context: ts.formatting.FormattingContext): boolean { + return context.formattingRequestKind !== ts.formatting.FormattingRequestKind.FormatOnEnter; } - function isModuleDeclContext(context: FormattingContext): boolean { - return context.contextNode.kind === SyntaxKind.ModuleDeclaration; + function isModuleDeclContext(context: ts.formatting.FormattingContext): boolean { + return context.contextNode.kind === ts.SyntaxKind.ModuleDeclaration; } - function isObjectTypeContext(context: FormattingContext): boolean { - return context.contextNode.kind === SyntaxKind.TypeLiteral; // && context.contextNode.parent.kind !== SyntaxKind.InterfaceDeclaration; + function isObjectTypeContext(context: ts.formatting.FormattingContext): boolean { + return context.contextNode.kind === ts.SyntaxKind.TypeLiteral; // && context.contextNode.parent.kind !== SyntaxKind.InterfaceDeclaration; } - function isConstructorSignatureContext(context: FormattingContext): boolean { - return context.contextNode.kind === SyntaxKind.ConstructSignature; + function isConstructorSignatureContext(context: ts.formatting.FormattingContext): boolean { + return context.contextNode.kind === ts.SyntaxKind.ConstructSignature; } - function isTypeArgumentOrParameterOrAssertion(token: TextRangeWithKind, parent: Node): boolean { - if (token.kind !== SyntaxKind.LessThanToken && token.kind !== SyntaxKind.GreaterThanToken) { + function isTypeArgumentOrParameterOrAssertion(token: ts.formatting.TextRangeWithKind, parent: ts.Node): boolean { + if (token.kind !== ts.SyntaxKind.LessThanToken && token.kind !== ts.SyntaxKind.GreaterThanToken) { return false; } switch (parent.kind) { - case SyntaxKind.TypeReference: - case SyntaxKind.TypeAssertionExpression: - case SyntaxKind.TypeAliasDeclaration: - case SyntaxKind.ClassDeclaration: - case SyntaxKind.ClassExpression: - case SyntaxKind.InterfaceDeclaration: - case SyntaxKind.FunctionDeclaration: - case SyntaxKind.FunctionExpression: - case SyntaxKind.ArrowFunction: - case SyntaxKind.MethodDeclaration: - case SyntaxKind.MethodSignature: - case SyntaxKind.CallSignature: - case SyntaxKind.ConstructSignature: - case SyntaxKind.CallExpression: - case SyntaxKind.NewExpression: - case SyntaxKind.ExpressionWithTypeArguments: + case ts.SyntaxKind.TypeReference: + case ts.SyntaxKind.TypeAssertionExpression: + case ts.SyntaxKind.TypeAliasDeclaration: + case ts.SyntaxKind.ClassDeclaration: + case ts.SyntaxKind.ClassExpression: + case ts.SyntaxKind.InterfaceDeclaration: + case ts.SyntaxKind.FunctionDeclaration: + case ts.SyntaxKind.FunctionExpression: + case ts.SyntaxKind.ArrowFunction: + case ts.SyntaxKind.MethodDeclaration: + case ts.SyntaxKind.MethodSignature: + case ts.SyntaxKind.CallSignature: + case ts.SyntaxKind.ConstructSignature: + case ts.SyntaxKind.CallExpression: + case ts.SyntaxKind.NewExpression: + case ts.SyntaxKind.ExpressionWithTypeArguments: return true; default: return false; @@ -785,39 +737,39 @@ namespace ts.formatting { } } - function isTypeArgumentOrParameterOrAssertionContext(context: FormattingContext): boolean { + function isTypeArgumentOrParameterOrAssertionContext(context: ts.formatting.FormattingContext): boolean { return isTypeArgumentOrParameterOrAssertion(context.currentTokenSpan, context.currentTokenParent) || isTypeArgumentOrParameterOrAssertion(context.nextTokenSpan, context.nextTokenParent); } - function isTypeAssertionContext(context: FormattingContext): boolean { - return context.contextNode.kind === SyntaxKind.TypeAssertionExpression; + function isTypeAssertionContext(context: ts.formatting.FormattingContext): boolean { + return context.contextNode.kind === ts.SyntaxKind.TypeAssertionExpression; } - function isVoidOpContext(context: FormattingContext): boolean { - return context.currentTokenSpan.kind === SyntaxKind.VoidKeyword && context.currentTokenParent.kind === SyntaxKind.VoidExpression; + function isVoidOpContext(context: ts.formatting.FormattingContext): boolean { + return context.currentTokenSpan.kind === ts.SyntaxKind.VoidKeyword && context.currentTokenParent.kind === ts.SyntaxKind.VoidExpression; } - function isYieldOrYieldStarWithOperand(context: FormattingContext): boolean { - return context.contextNode.kind === SyntaxKind.YieldExpression && (context.contextNode as YieldExpression).expression !== undefined; + function isYieldOrYieldStarWithOperand(context: ts.formatting.FormattingContext): boolean { + return context.contextNode.kind === ts.SyntaxKind.YieldExpression && (context.contextNode as ts.YieldExpression).expression !== undefined; } - function isNonNullAssertionContext(context: FormattingContext): boolean { - return context.contextNode.kind === SyntaxKind.NonNullExpression; + function isNonNullAssertionContext(context: ts.formatting.FormattingContext): boolean { + return context.contextNode.kind === ts.SyntaxKind.NonNullExpression; } - function isNotStatementConditionContext(context: FormattingContext): boolean { + function isNotStatementConditionContext(context: ts.formatting.FormattingContext): boolean { return !isStatementConditionContext(context); } - function isStatementConditionContext(context: FormattingContext): boolean { + function isStatementConditionContext(context: ts.formatting.FormattingContext): boolean { switch (context.contextNode.kind) { - case SyntaxKind.IfStatement: - case SyntaxKind.ForStatement: - case SyntaxKind.ForInStatement: - case SyntaxKind.ForOfStatement: - case SyntaxKind.DoStatement: - case SyntaxKind.WhileStatement: + case ts.SyntaxKind.IfStatement: + case ts.SyntaxKind.ForStatement: + case ts.SyntaxKind.ForInStatement: + case ts.SyntaxKind.ForOfStatement: + case ts.SyntaxKind.DoStatement: + case ts.SyntaxKind.WhileStatement: return true; default: @@ -825,15 +777,12 @@ namespace ts.formatting { } } - function isSemicolonDeletionContext(context: FormattingContext): boolean { + function isSemicolonDeletionContext(context: ts.formatting.FormattingContext): boolean { let nextTokenKind = context.nextTokenSpan.kind; let nextTokenStart = context.nextTokenSpan.pos; - if (isTrivia(nextTokenKind)) { + if (ts.isTrivia(nextTokenKind)) { const nextRealToken = context.nextTokenParent === context.currentTokenParent - ? findNextToken( - context.currentTokenParent, - findAncestor(context.currentTokenParent, a => !a.parent)!, - context.sourceFile) + ? ts.findNextToken(context.currentTokenParent, ts.findAncestor(context.currentTokenParent, a => !a.parent)!, context.sourceFile) : context.nextTokenParent.getFirstToken(context.sourceFile); if (!nextRealToken) { return true; @@ -845,51 +794,48 @@ namespace ts.formatting { const startLine = context.sourceFile.getLineAndCharacterOfPosition(context.currentTokenSpan.pos).line; const endLine = context.sourceFile.getLineAndCharacterOfPosition(nextTokenStart).line; if (startLine === endLine) { - return nextTokenKind === SyntaxKind.CloseBraceToken - || nextTokenKind === SyntaxKind.EndOfFileToken; + return nextTokenKind === ts.SyntaxKind.CloseBraceToken + || nextTokenKind === ts.SyntaxKind.EndOfFileToken; } - if (nextTokenKind === SyntaxKind.SemicolonClassElement || - nextTokenKind === SyntaxKind.SemicolonToken - ) { + if (nextTokenKind === ts.SyntaxKind.SemicolonClassElement || + nextTokenKind === ts.SyntaxKind.SemicolonToken) { return false; } - if (context.contextNode.kind === SyntaxKind.InterfaceDeclaration || - context.contextNode.kind === SyntaxKind.TypeAliasDeclaration - ) { + if (context.contextNode.kind === ts.SyntaxKind.InterfaceDeclaration || + context.contextNode.kind === ts.SyntaxKind.TypeAliasDeclaration) { // Can’t remove semicolon after `foo`; it would parse as a method declaration: // // interface I { // foo; // (): void // } - return !isPropertySignature(context.currentTokenParent) + return !ts.isPropertySignature(context.currentTokenParent) || !!context.currentTokenParent.type - || nextTokenKind !== SyntaxKind.OpenParenToken; + || nextTokenKind !== ts.SyntaxKind.OpenParenToken; } - if (isPropertyDeclaration(context.currentTokenParent)) { + if (ts.isPropertyDeclaration(context.currentTokenParent)) { return !context.currentTokenParent.initializer; } - return context.currentTokenParent.kind !== SyntaxKind.ForStatement - && context.currentTokenParent.kind !== SyntaxKind.EmptyStatement - && context.currentTokenParent.kind !== SyntaxKind.SemicolonClassElement - && nextTokenKind !== SyntaxKind.OpenBracketToken - && nextTokenKind !== SyntaxKind.OpenParenToken - && nextTokenKind !== SyntaxKind.PlusToken - && nextTokenKind !== SyntaxKind.MinusToken - && nextTokenKind !== SyntaxKind.SlashToken - && nextTokenKind !== SyntaxKind.RegularExpressionLiteral - && nextTokenKind !== SyntaxKind.CommaToken - && nextTokenKind !== SyntaxKind.TemplateExpression - && nextTokenKind !== SyntaxKind.TemplateHead - && nextTokenKind !== SyntaxKind.NoSubstitutionTemplateLiteral - && nextTokenKind !== SyntaxKind.DotToken; - } - - function isSemicolonInsertionContext(context: FormattingContext): boolean { - return positionIsASICandidate(context.currentTokenSpan.end, context.currentTokenParent, context.sourceFile); + return context.currentTokenParent.kind !== ts.SyntaxKind.ForStatement + && context.currentTokenParent.kind !== ts.SyntaxKind.EmptyStatement + && context.currentTokenParent.kind !== ts.SyntaxKind.SemicolonClassElement + && nextTokenKind !== ts.SyntaxKind.OpenBracketToken + && nextTokenKind !== ts.SyntaxKind.OpenParenToken + && nextTokenKind !== ts.SyntaxKind.PlusToken + && nextTokenKind !== ts.SyntaxKind.MinusToken + && nextTokenKind !== ts.SyntaxKind.SlashToken + && nextTokenKind !== ts.SyntaxKind.RegularExpressionLiteral + && nextTokenKind !== ts.SyntaxKind.CommaToken + && nextTokenKind !== ts.SyntaxKind.TemplateExpression + && nextTokenKind !== ts.SyntaxKind.TemplateHead + && nextTokenKind !== ts.SyntaxKind.NoSubstitutionTemplateLiteral + && nextTokenKind !== ts.SyntaxKind.DotToken; + } + function isSemicolonInsertionContext(context: ts.formatting.FormattingContext): boolean { + return ts.positionIsASICandidate(context.currentTokenSpan.end, context.currentTokenParent, context.sourceFile); } } diff --git a/src/services/formatting/rulesMap.ts b/src/services/formatting/rulesMap.ts index ccee491040fc6..4540fb19e53d0 100644 --- a/src/services/formatting/rulesMap.ts +++ b/src/services/formatting/rulesMap.ts @@ -1,6 +1,6 @@ /* @internal */ namespace ts.formatting { - export function getFormatContext(options: FormatCodeSettings, host: FormattingHost): FormatContext { + export function getFormatContext(options: ts.FormatCodeSettings, host: ts.FormattingHost): ts.formatting.FormatContext { return { options, getRules: getRulesMap(), host }; } @@ -8,7 +8,7 @@ namespace ts.formatting { function getRulesMap(): RulesMap { if (rulesMapCache === undefined) { - rulesMapCache = createRulesMap(getAllRules()); + rulesMapCache = createRulesMap(ts.formatting.getAllRules()); } return rulesMapCache; } @@ -17,34 +17,34 @@ namespace ts.formatting { * For a given rule action, gets a mask of other rule actions that * cannot be applied at the same position. */ - function getRuleActionExclusion(ruleAction: RuleAction): RuleAction { - let mask: RuleAction = 0; - if (ruleAction & RuleAction.StopProcessingSpaceActions) { - mask |= RuleAction.ModifySpaceAction; + function getRuleActionExclusion(ruleAction: ts.formatting.RuleAction): ts.formatting.RuleAction { + let mask: ts.formatting.RuleAction = 0; + if (ruleAction & ts.formatting.RuleAction.StopProcessingSpaceActions) { + mask |= ts.formatting.RuleAction.ModifySpaceAction; } - if (ruleAction & RuleAction.StopProcessingTokenActions) { - mask |= RuleAction.ModifyTokenAction; + if (ruleAction & ts.formatting.RuleAction.StopProcessingTokenActions) { + mask |= ts.formatting.RuleAction.ModifyTokenAction; } - if (ruleAction & RuleAction.ModifySpaceAction) { - mask |= RuleAction.ModifySpaceAction; + if (ruleAction & ts.formatting.RuleAction.ModifySpaceAction) { + mask |= ts.formatting.RuleAction.ModifySpaceAction; } - if (ruleAction & RuleAction.ModifyTokenAction) { - mask |= RuleAction.ModifyTokenAction; + if (ruleAction & ts.formatting.RuleAction.ModifyTokenAction) { + mask |= ts.formatting.RuleAction.ModifyTokenAction; } return mask; } - export type RulesMap = (context: FormattingContext) => readonly Rule[] | undefined; - function createRulesMap(rules: readonly RuleSpec[]): RulesMap { + export type RulesMap = (context: ts.formatting.FormattingContext) => readonly ts.formatting.Rule[] | undefined; + function createRulesMap(rules: readonly ts.formatting.RuleSpec[]): RulesMap { const map = buildMap(rules); return context => { const bucket = map[getRuleBucketIndex(context.currentTokenSpan.kind, context.nextTokenSpan.kind)]; if (bucket) { - const rules: Rule[] = []; - let ruleActionMask: RuleAction = 0; + const rules: ts.formatting.Rule[] = []; + let ruleActionMask: ts.formatting.RuleAction = 0; for (const rule of bucket) { const acceptRuleActions = ~getRuleActionExclusion(ruleActionMask); - if (rule.action & acceptRuleActions && every(rule.context, c => c(context))) { + if (rule.action & acceptRuleActions && ts.every(rule.context, c => c(context))) { rules.push(rule); ruleActionMask |= rule.action; } @@ -56,9 +56,9 @@ namespace ts.formatting { }; } - function buildMap(rules: readonly RuleSpec[]): readonly (readonly Rule[])[] { + function buildMap(rules: readonly ts.formatting.RuleSpec[]): readonly (readonly ts.formatting.Rule[])[] { // Map from bucket index to array of rules - const map: Rule[][] = new Array(mapRowLength * mapRowLength); + const map: ts.formatting.Rule[][] = new Array(mapRowLength * mapRowLength); // This array is used only during construction of the rulesbucket in the map const rulesBucketConstructionStateList = new Array(map.length); for (const rule of rules) { @@ -79,13 +79,13 @@ namespace ts.formatting { } function getRuleBucketIndex(row: number, column: number): number { - Debug.assert(row <= SyntaxKind.LastKeyword && column <= SyntaxKind.LastKeyword, "Must compute formatting context from tokens"); + ts.Debug.assert(row <= ts.SyntaxKind.LastKeyword && column <= ts.SyntaxKind.LastKeyword, "Must compute formatting context from tokens"); return (row * mapRowLength) + column; } const maskBitSize = 5; const mask = 0b11111; // MaskBitSize bits - const mapRowLength = SyntaxKind.LastToken + 1; + const mapRowLength = ts.SyntaxKind.LastToken + 1; enum RulesPosition { StopRulesSpecific = 0, @@ -111,10 +111,10 @@ namespace ts.formatting { // Example: // In order to insert a rule to the end of sub-bucket (3), we get the index by adding // the values in the bitmap segments 3rd, 2nd, and 1st. - function addRule(rules: Rule[], rule: Rule, specificTokens: boolean, constructionState: number[], rulesBucketIndex: number): void { - const position = rule.action & RuleAction.StopAction ? + function addRule(rules: ts.formatting.Rule[], rule: ts.formatting.Rule, specificTokens: boolean, constructionState: number[], rulesBucketIndex: number): void { + const position = rule.action & ts.formatting.RuleAction.StopAction ? specificTokens ? RulesPosition.StopRulesSpecific : RulesPosition.StopRulesAny : - rule.context !== anyContext ? + rule.context !== ts.formatting.anyContext ? specificTokens ? RulesPosition.ContextRulesSpecific : RulesPosition.ContextRulesAny : specificTokens ? RulesPosition.NoContextRulesSpecific : RulesPosition.NoContextRulesAny; @@ -134,7 +134,7 @@ namespace ts.formatting { function increaseInsertionIndex(indexBitmap: number, maskPosition: RulesPosition): number { const value = ((indexBitmap >> maskPosition) & mask) + 1; - Debug.assert((value & mask) === value, "Adding more rules into the sub-bucket than allowed. Maximum allowed is 32 rules."); + ts.Debug.assert((value & mask) === value, "Adding more rules into the sub-bucket than allowed. Maximum allowed is 32 rules."); return (indexBitmap & ~(mask << maskPosition)) | (value << maskPosition); } } diff --git a/src/services/formatting/smartIndenter.ts b/src/services/formatting/smartIndenter.ts index 78b8a95890e50..6189ae97ba597 100644 --- a/src/services/formatting/smartIndenter.ts +++ b/src/services/formatting/smartIndenter.ts @@ -21,22 +21,22 @@ namespace ts.formatting { * When inserting some text after an open brace, we would like to get indentation as if a newline was already there. * By default indentation at `position` will be 0 so 'assumeNewLineBeforeCloseBrace' overrides this behavior. */ - export function getIndentation(position: number, sourceFile: SourceFile, options: EditorSettings, assumeNewLineBeforeCloseBrace = false): number { + export function getIndentation(position: number, sourceFile: ts.SourceFile, options: ts.EditorSettings, assumeNewLineBeforeCloseBrace = false): number { if (position > sourceFile.text.length) { return getBaseIndentation(options); // past EOF } // no indentation when the indent style is set to none, // so we can return fast - if (options.indentStyle === IndentStyle.None) { + if (options.indentStyle === ts.IndentStyle.None) { return 0; } - const precedingToken = findPrecedingToken(position, sourceFile, /*startNode*/ undefined, /*excludeJsdoc*/ true); + const precedingToken = ts.findPrecedingToken(position, sourceFile, /*startNode*/ undefined, /*excludeJsdoc*/ true); // eslint-disable-next-line no-null/no-null - const enclosingCommentRange = getRangeOfEnclosingComment(sourceFile, position, precedingToken || null); - if (enclosingCommentRange && enclosingCommentRange.kind === SyntaxKind.MultiLineCommentTrivia) { + const enclosingCommentRange = ts.formatting.getRangeOfEnclosingComment(sourceFile, position, precedingToken || null); + if (enclosingCommentRange && enclosingCommentRange.kind === ts.SyntaxKind.MultiLineCommentTrivia) { return getCommentIndent(sourceFile, position, options, enclosingCommentRange); } @@ -45,7 +45,7 @@ namespace ts.formatting { } // no indentation in string \regex\template literals - const precedingTokenIsLiteral = isStringOrRegularExpressionOrTemplateLiteral(precedingToken.kind); + const precedingTokenIsLiteral = ts.isStringOrRegularExpressionOrTemplateLiteral(precedingToken.kind); if (precedingTokenIsLiteral && precedingToken.getStart(sourceFile) <= position && position < precedingToken.end) { return 0; } @@ -55,7 +55,7 @@ namespace ts.formatting { // indentation is first non-whitespace character in a previous line // for block indentation, we should look for a line which contains something that's not // whitespace. - const currentToken = getTokenAtPosition(sourceFile, position); + const currentToken = ts.getTokenAtPosition(sourceFile, position); // For object literals, we want indentation to work just like with blocks. // If the `{` starts in any position (even in the middle of a line), then // the following indentation should treat `{` as the start of that line (including leading whitespace). @@ -76,12 +76,12 @@ namespace ts.formatting { // y: undefined, // } // ``` - const isObjectLiteral = currentToken.kind === SyntaxKind.OpenBraceToken && currentToken.parent.kind === SyntaxKind.ObjectLiteralExpression; - if (options.indentStyle === IndentStyle.Block || isObjectLiteral) { + const isObjectLiteral = currentToken.kind === ts.SyntaxKind.OpenBraceToken && currentToken.parent.kind === ts.SyntaxKind.ObjectLiteralExpression; + if (options.indentStyle === ts.IndentStyle.Block || isObjectLiteral) { return getBlockIndent(sourceFile, position, options); } - if (precedingToken.kind === SyntaxKind.CommaToken && precedingToken.parent.kind !== SyntaxKind.BinaryExpression) { + if (precedingToken.kind === ts.SyntaxKind.CommaToken && precedingToken.parent.kind !== ts.SyntaxKind.BinaryExpression) { // previous token is comma that separates items in list - find the previous item and try to derive indentation from it const actualIndentation = getActualIndentationForListItemBeforeComma(precedingToken, sourceFile, options); if (actualIndentation !== Value.Unknown) { @@ -91,8 +91,8 @@ namespace ts.formatting { const containerList = getListByPosition(position, precedingToken.parent, sourceFile); // use list position if the preceding token is before any list items - if (containerList && !rangeContainsRange(containerList, precedingToken)) { - const useTheSameBaseIndentation = [SyntaxKind.FunctionExpression, SyntaxKind.ArrowFunction].indexOf(currentToken.parent.kind) !== -1; + if (containerList && !ts.rangeContainsRange(containerList, precedingToken)) { + const useTheSameBaseIndentation = [ts.SyntaxKind.FunctionExpression, ts.SyntaxKind.ArrowFunction].indexOf(currentToken.parent.kind) !== -1; const indentSize = useTheSameBaseIndentation ? 0 : options.indentSize!; return getActualIndentationForListStartLine(containerList, sourceFile, options) + indentSize; // TODO: GH#18217 } @@ -100,17 +100,16 @@ namespace ts.formatting { return getSmartIndent(sourceFile, position, precedingToken, lineAtPosition, assumeNewLineBeforeCloseBrace, options); } - function getCommentIndent(sourceFile: SourceFile, position: number, options: EditorSettings, enclosingCommentRange: CommentRange): number { - const previousLine = getLineAndCharacterOfPosition(sourceFile, position).line - 1; - const commentStartLine = getLineAndCharacterOfPosition(sourceFile, enclosingCommentRange.pos).line; - - Debug.assert(commentStartLine >= 0); + function getCommentIndent(sourceFile: ts.SourceFile, position: number, options: ts.EditorSettings, enclosingCommentRange: ts.CommentRange): number { + const previousLine = ts.getLineAndCharacterOfPosition(sourceFile, position).line - 1; + const commentStartLine = ts.getLineAndCharacterOfPosition(sourceFile, enclosingCommentRange.pos).line; + ts.Debug.assert(commentStartLine >= 0); if (previousLine <= commentStartLine) { - return findFirstNonWhitespaceColumn(getStartPositionOfLine(commentStartLine, sourceFile), position, sourceFile, options); + return findFirstNonWhitespaceColumn(ts.getStartPositionOfLine(commentStartLine, sourceFile), position, sourceFile, options); } - const startPositionOfLine = getStartPositionOfLine(previousLine, sourceFile); + const startPositionOfLine = ts.getStartPositionOfLine(previousLine, sourceFile); const { column, character } = findFirstNonWhitespaceCharacterAndColumn(startPositionOfLine, position, sourceFile, options); if (column === 0) { @@ -118,33 +117,33 @@ namespace ts.formatting { } const firstNonWhitespaceCharacterCode = sourceFile.text.charCodeAt(startPositionOfLine + character); - return firstNonWhitespaceCharacterCode === CharacterCodes.asterisk ? column - 1 : column; + return firstNonWhitespaceCharacterCode === ts.CharacterCodes.asterisk ? column - 1 : column; } - function getBlockIndent(sourceFile: SourceFile, position: number, options: EditorSettings): number { + function getBlockIndent(sourceFile: ts.SourceFile, position: number, options: ts.EditorSettings): number { // move backwards until we find a line with a non-whitespace character, // then find the first non-whitespace character for that line. let current = position; while (current > 0) { const char = sourceFile.text.charCodeAt(current); - if (!isWhiteSpaceLike(char)) { + if (!ts.isWhiteSpaceLike(char)) { break; } current--; } - const lineStart = getLineStartPositionForPosition(current, sourceFile); + const lineStart = ts.getLineStartPositionForPosition(current, sourceFile); return findFirstNonWhitespaceColumn(lineStart, current, sourceFile, options); } - function getSmartIndent(sourceFile: SourceFile, position: number, precedingToken: Node, lineAtPosition: number, assumeNewLineBeforeCloseBrace: boolean, options: EditorSettings): number { + function getSmartIndent(sourceFile: ts.SourceFile, position: number, precedingToken: ts.Node, lineAtPosition: number, assumeNewLineBeforeCloseBrace: boolean, options: ts.EditorSettings): number { // try to find node that can contribute to indentation and includes 'position' starting from 'precedingToken' // if such node is found - compute initial indentation for 'position' inside this node - let previous: Node | undefined; + let previous: ts.Node | undefined; let current = precedingToken; while (current) { - if (positionBelongsToNode(current, position, sourceFile) && shouldIndentChildNode(options, current, previous, sourceFile, /*isNextChild*/ true)) { + if (ts.positionBelongsToNode(current, position, sourceFile) && shouldIndentChildNode(options, current, previous, sourceFile, /*isNextChild*/ true)) { const currentStart = getStartLineAndCharacterForNode(current, sourceFile); const nextTokenKind = nextTokenIsCurlyBraceOnSameLineAsCursor(precedingToken, current, lineAtPosition, sourceFile); const indentationDelta = nextTokenKind !== NextTokenKind.Unknown @@ -170,23 +169,16 @@ namespace ts.formatting { return getBaseIndentation(options); } - export function getIndentationForNode(n: Node, ignoreActualIndentationRange: TextRange, sourceFile: SourceFile, options: EditorSettings): number { + export function getIndentationForNode(n: ts.Node, ignoreActualIndentationRange: ts.TextRange, sourceFile: ts.SourceFile, options: ts.EditorSettings): number { const start = sourceFile.getLineAndCharacterOfPosition(n.getStart(sourceFile)); return getIndentationForNodeWorker(n, start, ignoreActualIndentationRange, /*indentationDelta*/ 0, sourceFile, /*isNextChild*/ false, options); } - export function getBaseIndentation(options: EditorSettings) { + export function getBaseIndentation(options: ts.EditorSettings) { return options.baseIndentSize || 0; } - function getIndentationForNodeWorker( - current: Node, - currentStart: LineAndCharacter, - ignoreActualIndentationRange: TextRange | undefined, - indentationDelta: number, - sourceFile: SourceFile, - isNextChild: boolean, - options: EditorSettings): number { + function getIndentationForNodeWorker(current: ts.Node, currentStart: ts.LineAndCharacter, ignoreActualIndentationRange: ts.TextRange | undefined, indentationDelta: number, sourceFile: ts.SourceFile, isNextChild: boolean, options: ts.EditorSettings): number { let parent = current.parent; // Walk up the tree and collect indentation for parent-child node pairs. Indentation is not added if @@ -200,8 +192,7 @@ namespace ts.formatting { } const containingListOrParentStart = getContainingListOrParentStart(parent, current, sourceFile); - const parentAndChildShareLine = - containingListOrParentStart.line === currentStart.line || + const parentAndChildShareLine = containingListOrParentStart.line === currentStart.line || childStartsOnTheSameLineWithElseInIfStatement(parent, current, currentStart.line, sourceFile); if (useActualIndentation) { @@ -250,8 +241,7 @@ namespace ts.formatting { // Instead, when at an argument, we unspoof the starting position of the enclosing call expression // *after* applying indentation for the argument. - const useTrueStart = - isArgumentAndStartLineOverlapsExpressionBeingCalled(parent, current, currentStart.line, sourceFile); + const useTrueStart = isArgumentAndStartLineOverlapsExpressionBeingCalled(parent, current, currentStart.line, sourceFile); current = parent; parent = current.parent; @@ -261,7 +251,7 @@ namespace ts.formatting { return indentationDelta + getBaseIndentation(options); } - function getContainingListOrParentStart(parent: Node, child: Node, sourceFile: SourceFile): LineAndCharacter { + function getContainingListOrParentStart(parent: ts.Node, child: ts.Node, sourceFile: ts.SourceFile): ts.LineAndCharacter { const containingList = getContainingList(child, sourceFile); const startPos = containingList ? containingList.pos : parent.getStart(sourceFile); return sourceFile.getLineAndCharacterOfPosition(startPos); @@ -270,9 +260,9 @@ namespace ts.formatting { /* * Function returns Value.Unknown if indentation cannot be determined */ - function getActualIndentationForListItemBeforeComma(commaToken: Node, sourceFile: SourceFile, options: EditorSettings): number { + function getActualIndentationForListItemBeforeComma(commaToken: ts.Node, sourceFile: ts.SourceFile, options: ts.EditorSettings): number { // previous token is comma that separates items in list - find the previous item and try to derive indentation from it - const commaItemInfo = findListItemInfo(commaToken); + const commaItemInfo = ts.findListItemInfo(commaToken); if (commaItemInfo && commaItemInfo.listItemIndex > 0) { return deriveActualIndentationFromList(commaItemInfo.list.getChildren(), commaItemInfo.listItemIndex - 1, sourceFile, options); } @@ -285,19 +275,13 @@ namespace ts.formatting { /* * Function returns Value.Unknown if actual indentation for node should not be used (i.e because node is nested expression) */ - function getActualIndentationForNode(current: Node, - parent: Node, - currentLineAndChar: LineAndCharacter, - parentAndChildShareLine: boolean, - sourceFile: SourceFile, - options: EditorSettings): number { + function getActualIndentationForNode(current: ts.Node, parent: ts.Node, currentLineAndChar: ts.LineAndCharacter, parentAndChildShareLine: boolean, sourceFile: ts.SourceFile, options: ts.EditorSettings): number { // actual indentation is used for statements\declarations if one of cases below is true: // - parent is SourceFile - by default immediate children of SourceFile are not indented except when user indents them manually // - parent and child are not on the same line - const useActualIndentation = - (isDeclaration(current) || isStatementButNotDeclaration(current)) && - (parent.kind === SyntaxKind.SourceFile || !parentAndChildShareLine); + const useActualIndentation = (ts.isDeclaration(current) || ts.isStatementButNotDeclaration(current)) && + (parent.kind === ts.SyntaxKind.SourceFile || !parentAndChildShareLine); if (!useActualIndentation) { return Value.Unknown; @@ -312,17 +296,17 @@ namespace ts.formatting { CloseBrace } - function nextTokenIsCurlyBraceOnSameLineAsCursor(precedingToken: Node, current: Node, lineAtPosition: number, sourceFile: SourceFile): NextTokenKind { - const nextToken = findNextToken(precedingToken, current, sourceFile); + function nextTokenIsCurlyBraceOnSameLineAsCursor(precedingToken: ts.Node, current: ts.Node, lineAtPosition: number, sourceFile: ts.SourceFile): NextTokenKind { + const nextToken = ts.findNextToken(precedingToken, current, sourceFile); if (!nextToken) { return NextTokenKind.Unknown; } - if (nextToken.kind === SyntaxKind.OpenBraceToken) { + if (nextToken.kind === ts.SyntaxKind.OpenBraceToken) { // open braces are always indented at the parent level return NextTokenKind.OpenBrace; } - else if (nextToken.kind === SyntaxKind.CloseBraceToken) { + else if (nextToken.kind === ts.SyntaxKind.CloseBraceToken) { // close braces are indented at the parent level if they are located on the same line with cursor // this means that if new line will be added at $ position, this case will be indented // class A { @@ -339,24 +323,24 @@ namespace ts.formatting { return NextTokenKind.Unknown; } - function getStartLineAndCharacterForNode(n: Node, sourceFile: SourceFileLike): LineAndCharacter { + function getStartLineAndCharacterForNode(n: ts.Node, sourceFile: ts.SourceFileLike): ts.LineAndCharacter { return sourceFile.getLineAndCharacterOfPosition(n.getStart(sourceFile)); } - export function isArgumentAndStartLineOverlapsExpressionBeingCalled(parent: Node, child: Node, childStartLine: number, sourceFile: SourceFileLike): boolean { - if (!(isCallExpression(parent) && contains(parent.arguments, child))) { + export function isArgumentAndStartLineOverlapsExpressionBeingCalled(parent: ts.Node, child: ts.Node, childStartLine: number, sourceFile: ts.SourceFileLike): boolean { + if (!(ts.isCallExpression(parent) && ts.contains(parent.arguments, child))) { return false; } const expressionOfCallExpressionEnd = parent.expression.getEnd(); - const expressionOfCallExpressionEndLine = getLineAndCharacterOfPosition(sourceFile, expressionOfCallExpressionEnd).line; + const expressionOfCallExpressionEndLine = ts.getLineAndCharacterOfPosition(sourceFile, expressionOfCallExpressionEnd).line; return expressionOfCallExpressionEndLine === childStartLine; } - export function childStartsOnTheSameLineWithElseInIfStatement(parent: Node, child: TextRangeWithKind, childStartLine: number, sourceFile: SourceFileLike): boolean { - if (parent.kind === SyntaxKind.IfStatement && (parent as IfStatement).elseStatement === child) { - const elseKeyword = findChildOfKind(parent, SyntaxKind.ElseKeyword, sourceFile)!; - Debug.assert(elseKeyword !== undefined); + export function childStartsOnTheSameLineWithElseInIfStatement(parent: ts.Node, child: ts.formatting.TextRangeWithKind, childStartLine: number, sourceFile: ts.SourceFileLike): boolean { + if (parent.kind === ts.SyntaxKind.IfStatement && (parent as ts.IfStatement).elseStatement === child) { + const elseKeyword = ts.findChildOfKind(parent, ts.SyntaxKind.ElseKeyword, sourceFile)!; + ts.Debug.assert(elseKeyword !== undefined); const elseKeywordStartLine = getStartLineAndCharacterForNode(elseKeyword, sourceFile).line; return elseKeywordStartLine === childStartLine; @@ -386,9 +370,9 @@ namespace ts.formatting { // whenTrue and whenFalse children to avoid double-indenting their contents. To identify this scenario, // we check for the whenTrue branch beginning on the line that the condition ends, and the whenFalse // branch beginning on the line that the whenTrue branch ends. - export function childIsUnindentedBranchOfConditionalExpression(parent: Node, child: TextRangeWithKind, childStartLine: number, sourceFile: SourceFileLike): boolean { - if (isConditionalExpression(parent) && (child === parent.whenTrue || child === parent.whenFalse)) { - const conditionEndLine = getLineAndCharacterOfPosition(sourceFile, parent.condition.end).line; + export function childIsUnindentedBranchOfConditionalExpression(parent: ts.Node, child: ts.formatting.TextRangeWithKind, childStartLine: number, sourceFile: ts.SourceFileLike): boolean { + if (ts.isConditionalExpression(parent) && (child === parent.whenTrue || child === parent.whenFalse)) { + const conditionEndLine = ts.getLineAndCharacterOfPosition(sourceFile, parent.condition.end).line; if (child === parent.whenTrue) { return childStartLine === conditionEndLine; } @@ -401,24 +385,27 @@ namespace ts.formatting { // 0 L2: indented two stops, one because whenTrue was indented // ); and one because of the parentheses spanning multiple lines const trueStartLine = getStartLineAndCharacterForNode(parent.whenTrue, sourceFile).line; - const trueEndLine = getLineAndCharacterOfPosition(sourceFile, parent.whenTrue.end).line; + const trueEndLine = ts.getLineAndCharacterOfPosition(sourceFile, parent.whenTrue.end).line; return conditionEndLine === trueStartLine && trueEndLine === childStartLine; } } return false; } - export function argumentStartsOnSameLineAsPreviousArgument(parent: Node, child: TextRangeWithKind, childStartLine: number, sourceFile: SourceFileLike): boolean { - if (isCallOrNewExpression(parent)) { - if (!parent.arguments) return false; - const currentNode = find(parent.arguments, arg => arg.pos === child.pos); + export function argumentStartsOnSameLineAsPreviousArgument(parent: ts.Node, child: ts.formatting.TextRangeWithKind, childStartLine: number, sourceFile: ts.SourceFileLike): boolean { + if (ts.isCallOrNewExpression(parent)) { + if (!parent.arguments) + return false; + const currentNode = ts.find(parent.arguments, arg => arg.pos === child.pos); // If it's not one of the arguments, don't look past this - if (!currentNode) return false; + if (!currentNode) + return false; const currentIndex = parent.arguments.indexOf(currentNode); - if (currentIndex === 0) return false; // Can't look at previous node if first + if (currentIndex === 0) + return false; // Can't look at previous node if first const previousNode = parent.arguments[currentIndex - 1]; - const lineOfPreviousNode = getLineAndCharacterOfPosition(sourceFile, previousNode.getEnd()).line; + const lineOfPreviousNode = ts.getLineAndCharacterOfPosition(sourceFile, previousNode.getEnd()).line; if (childStartLine === lineOfPreviousNode) { return true; @@ -428,61 +415,59 @@ namespace ts.formatting { return false; } - export function getContainingList(node: Node, sourceFile: SourceFile): NodeArray | undefined { + export function getContainingList(node: ts.Node, sourceFile: ts.SourceFile): ts.NodeArray | undefined { return node.parent && getListByRange(node.getStart(sourceFile), node.getEnd(), node.parent, sourceFile); } - function getListByPosition(pos: number, node: Node, sourceFile: SourceFile): NodeArray | undefined { + function getListByPosition(pos: number, node: ts.Node, sourceFile: ts.SourceFile): ts.NodeArray | undefined { return node && getListByRange(pos, pos, node, sourceFile); } - function getListByRange(start: number, end: number, node: Node, sourceFile: SourceFile): NodeArray | undefined { + function getListByRange(start: number, end: number, node: ts.Node, sourceFile: ts.SourceFile): ts.NodeArray | undefined { switch (node.kind) { - case SyntaxKind.TypeReference: - return getList((node as TypeReferenceNode).typeArguments); - case SyntaxKind.ObjectLiteralExpression: - return getList((node as ObjectLiteralExpression).properties); - case SyntaxKind.ArrayLiteralExpression: - return getList((node as ArrayLiteralExpression).elements); - case SyntaxKind.TypeLiteral: - return getList((node as TypeLiteralNode).members); - case SyntaxKind.FunctionDeclaration: - case SyntaxKind.FunctionExpression: - case SyntaxKind.ArrowFunction: - case SyntaxKind.MethodDeclaration: - case SyntaxKind.MethodSignature: - case SyntaxKind.CallSignature: - case SyntaxKind.Constructor: - case SyntaxKind.ConstructorType: - case SyntaxKind.ConstructSignature: - return getList((node as SignatureDeclaration).typeParameters) || getList((node as SignatureDeclaration).parameters); - case SyntaxKind.GetAccessor: - return getList((node as GetAccessorDeclaration).parameters); - case SyntaxKind.ClassDeclaration: - case SyntaxKind.ClassExpression: - case SyntaxKind.InterfaceDeclaration: - case SyntaxKind.TypeAliasDeclaration: - case SyntaxKind.JSDocTemplateTag: - return getList((node as ClassDeclaration | ClassExpression | InterfaceDeclaration | TypeAliasDeclaration | JSDocTemplateTag).typeParameters); - case SyntaxKind.NewExpression: - case SyntaxKind.CallExpression: - return getList((node as CallExpression).typeArguments) || getList((node as CallExpression).arguments); - case SyntaxKind.VariableDeclarationList: - return getList((node as VariableDeclarationList).declarations); - case SyntaxKind.NamedImports: - case SyntaxKind.NamedExports: - return getList((node as NamedImportsOrExports).elements); - case SyntaxKind.ObjectBindingPattern: - case SyntaxKind.ArrayBindingPattern: - return getList((node as ObjectBindingPattern | ArrayBindingPattern).elements); - } - - function getList(list: NodeArray | undefined): NodeArray | undefined { - return list && rangeContainsStartEnd(getVisualListRange(node, list, sourceFile), start, end) ? list : undefined; - } - } - - function getVisualListRange(node: Node, list: TextRange, sourceFile: SourceFile): TextRange { + case ts.SyntaxKind.TypeReference: + return getList((node as ts.TypeReferenceNode).typeArguments); + case ts.SyntaxKind.ObjectLiteralExpression: + return getList((node as ts.ObjectLiteralExpression).properties); + case ts.SyntaxKind.ArrayLiteralExpression: + return getList((node as ts.ArrayLiteralExpression).elements); + case ts.SyntaxKind.TypeLiteral: + return getList((node as ts.TypeLiteralNode).members); + case ts.SyntaxKind.FunctionDeclaration: + case ts.SyntaxKind.FunctionExpression: + case ts.SyntaxKind.ArrowFunction: + case ts.SyntaxKind.MethodDeclaration: + case ts.SyntaxKind.MethodSignature: + case ts.SyntaxKind.CallSignature: + case ts.SyntaxKind.Constructor: + case ts.SyntaxKind.ConstructorType: + case ts.SyntaxKind.ConstructSignature: + return getList((node as ts.SignatureDeclaration).typeParameters) || getList((node as ts.SignatureDeclaration).parameters); + case ts.SyntaxKind.GetAccessor: + return getList((node as ts.GetAccessorDeclaration).parameters); + case ts.SyntaxKind.ClassDeclaration: + case ts.SyntaxKind.ClassExpression: + case ts.SyntaxKind.InterfaceDeclaration: + case ts.SyntaxKind.TypeAliasDeclaration: + case ts.SyntaxKind.JSDocTemplateTag: + return getList((node as ts.ClassDeclaration | ts.ClassExpression | ts.InterfaceDeclaration | ts.TypeAliasDeclaration | ts.JSDocTemplateTag).typeParameters); + case ts.SyntaxKind.NewExpression: + case ts.SyntaxKind.CallExpression: + return getList((node as ts.CallExpression).typeArguments) || getList((node as ts.CallExpression).arguments); + case ts.SyntaxKind.VariableDeclarationList: + return getList((node as ts.VariableDeclarationList).declarations); + case ts.SyntaxKind.NamedImports: + case ts.SyntaxKind.NamedExports: + return getList((node as ts.NamedImportsOrExports).elements); + case ts.SyntaxKind.ObjectBindingPattern: + case ts.SyntaxKind.ArrayBindingPattern: + return getList((node as ts.ObjectBindingPattern | ts.ArrayBindingPattern).elements); + } + function getList(list: ts.NodeArray | undefined): ts.NodeArray | undefined { + return list && ts.rangeContainsStartEnd(getVisualListRange(node, list, sourceFile), start, end) ? list : undefined; + } + } + function getVisualListRange(node: ts.Node, list: ts.TextRange, sourceFile: ts.SourceFile): ts.TextRange { const children = node.getChildren(sourceFile); for (let i = 1; i < children.length - 1; i++) { if (children[i].pos === list.pos && children[i].end === list.end) { @@ -492,15 +477,15 @@ namespace ts.formatting { return list; } - function getActualIndentationForListStartLine(list: NodeArray, sourceFile: SourceFile, options: EditorSettings): number { + function getActualIndentationForListStartLine(list: ts.NodeArray, sourceFile: ts.SourceFile, options: ts.EditorSettings): number { if (!list) { return Value.Unknown; } return findColumnForFirstNonWhitespaceCharacterInLine(sourceFile.getLineAndCharacterOfPosition(list.pos), sourceFile, options); } - function getActualIndentationForListItem(node: Node, sourceFile: SourceFile, options: EditorSettings, listIndentsChild: boolean): number { - if (node.parent && node.parent.kind === SyntaxKind.VariableDeclarationList) { + function getActualIndentationForListItem(node: ts.Node, sourceFile: ts.SourceFile, options: ts.EditorSettings, listIndentsChild: boolean): number { + if (node.parent && node.parent.kind === ts.SyntaxKind.VariableDeclarationList) { // VariableDeclarationList has no wrapping tokens return Value.Unknown; } @@ -518,15 +503,15 @@ namespace ts.formatting { return Value.Unknown; } - function deriveActualIndentationFromList(list: readonly Node[], index: number, sourceFile: SourceFile, options: EditorSettings): number { - Debug.assert(index >= 0 && index < list.length); + function deriveActualIndentationFromList(list: readonly ts.Node[], index: number, sourceFile: ts.SourceFile, options: ts.EditorSettings): number { + ts.Debug.assert(index >= 0 && index < list.length); const node = list[index]; // walk toward the start of the list starting from current node and check if the line is the same for all items. // if end line for item [i - 1] differs from the start line for item [i] - find column of the first non-whitespace character on the line of item [i] let lineAndCharacter = getStartLineAndCharacterForNode(node, sourceFile); for (let i = index - 1; i >= 0; i--) { - if (list[i].kind === SyntaxKind.CommaToken) { + if (list[i].kind === ts.SyntaxKind.CommaToken) { continue; } // skip list items that ends on the same line with the current list element @@ -540,7 +525,7 @@ namespace ts.formatting { return Value.Unknown; } - function findColumnForFirstNonWhitespaceCharacterInLine(lineAndCharacter: LineAndCharacter, sourceFile: SourceFile, options: EditorSettings): number { + function findColumnForFirstNonWhitespaceCharacterInLine(lineAndCharacter: ts.LineAndCharacter, sourceFile: ts.SourceFile, options: ts.EditorSettings): number { const lineStart = sourceFile.getPositionOfLineAndCharacter(lineAndCharacter.line, 0); return findFirstNonWhitespaceColumn(lineStart, lineStart + lineAndCharacter.character, sourceFile, options); } @@ -552,16 +537,16 @@ namespace ts.formatting { * value of 'character' for '$' is 3 * value of 'column' for '$' is 6 (assuming that tab size is 4) */ - export function findFirstNonWhitespaceCharacterAndColumn(startPos: number, endPos: number, sourceFile: SourceFileLike, options: EditorSettings) { + export function findFirstNonWhitespaceCharacterAndColumn(startPos: number, endPos: number, sourceFile: ts.SourceFileLike, options: ts.EditorSettings) { let character = 0; let column = 0; for (let pos = startPos; pos < endPos; pos++) { const ch = sourceFile.text.charCodeAt(pos); - if (!isWhiteSpaceSingleLine(ch)) { + if (!ts.isWhiteSpaceSingleLine(ch)) { break; } - if (ch === CharacterCodes.tab) { + if (ch === ts.CharacterCodes.tab) { column += options.tabSize! + (column % options.tabSize!); } else { @@ -573,104 +558,104 @@ namespace ts.formatting { return { column, character }; } - export function findFirstNonWhitespaceColumn(startPos: number, endPos: number, sourceFile: SourceFileLike, options: EditorSettings): number { + export function findFirstNonWhitespaceColumn(startPos: number, endPos: number, sourceFile: ts.SourceFileLike, options: ts.EditorSettings): number { return findFirstNonWhitespaceCharacterAndColumn(startPos, endPos, sourceFile, options).column; } - export function nodeWillIndentChild(settings: FormatCodeSettings, parent: TextRangeWithKind, child: TextRangeWithKind | undefined, sourceFile: SourceFileLike | undefined, indentByDefault: boolean): boolean { - const childKind = child ? child.kind : SyntaxKind.Unknown; + export function nodeWillIndentChild(settings: ts.FormatCodeSettings, parent: ts.formatting.TextRangeWithKind, child: ts.formatting.TextRangeWithKind | undefined, sourceFile: ts.SourceFileLike | undefined, indentByDefault: boolean): boolean { + const childKind = child ? child.kind : ts.SyntaxKind.Unknown; switch (parent.kind) { - case SyntaxKind.ExpressionStatement: - case SyntaxKind.ClassDeclaration: - case SyntaxKind.ClassExpression: - case SyntaxKind.InterfaceDeclaration: - case SyntaxKind.EnumDeclaration: - case SyntaxKind.TypeAliasDeclaration: - case SyntaxKind.ArrayLiteralExpression: - case SyntaxKind.Block: - case SyntaxKind.ModuleBlock: - case SyntaxKind.ObjectLiteralExpression: - case SyntaxKind.TypeLiteral: - case SyntaxKind.MappedType: - case SyntaxKind.TupleType: - case SyntaxKind.CaseBlock: - case SyntaxKind.DefaultClause: - case SyntaxKind.CaseClause: - case SyntaxKind.ParenthesizedExpression: - case SyntaxKind.PropertyAccessExpression: - case SyntaxKind.CallExpression: - case SyntaxKind.NewExpression: - case SyntaxKind.VariableStatement: - case SyntaxKind.ExportAssignment: - case SyntaxKind.ReturnStatement: - case SyntaxKind.ConditionalExpression: - case SyntaxKind.ArrayBindingPattern: - case SyntaxKind.ObjectBindingPattern: - case SyntaxKind.JsxOpeningElement: - case SyntaxKind.JsxOpeningFragment: - case SyntaxKind.JsxSelfClosingElement: - case SyntaxKind.JsxExpression: - case SyntaxKind.MethodSignature: - case SyntaxKind.CallSignature: - case SyntaxKind.ConstructSignature: - case SyntaxKind.Parameter: - case SyntaxKind.FunctionType: - case SyntaxKind.ConstructorType: - case SyntaxKind.ParenthesizedType: - case SyntaxKind.TaggedTemplateExpression: - case SyntaxKind.AwaitExpression: - case SyntaxKind.NamedExports: - case SyntaxKind.NamedImports: - case SyntaxKind.ExportSpecifier: - case SyntaxKind.ImportSpecifier: - case SyntaxKind.PropertyDeclaration: + case ts.SyntaxKind.ExpressionStatement: + case ts.SyntaxKind.ClassDeclaration: + case ts.SyntaxKind.ClassExpression: + case ts.SyntaxKind.InterfaceDeclaration: + case ts.SyntaxKind.EnumDeclaration: + case ts.SyntaxKind.TypeAliasDeclaration: + case ts.SyntaxKind.ArrayLiteralExpression: + case ts.SyntaxKind.Block: + case ts.SyntaxKind.ModuleBlock: + case ts.SyntaxKind.ObjectLiteralExpression: + case ts.SyntaxKind.TypeLiteral: + case ts.SyntaxKind.MappedType: + case ts.SyntaxKind.TupleType: + case ts.SyntaxKind.CaseBlock: + case ts.SyntaxKind.DefaultClause: + case ts.SyntaxKind.CaseClause: + case ts.SyntaxKind.ParenthesizedExpression: + case ts.SyntaxKind.PropertyAccessExpression: + case ts.SyntaxKind.CallExpression: + case ts.SyntaxKind.NewExpression: + case ts.SyntaxKind.VariableStatement: + case ts.SyntaxKind.ExportAssignment: + case ts.SyntaxKind.ReturnStatement: + case ts.SyntaxKind.ConditionalExpression: + case ts.SyntaxKind.ArrayBindingPattern: + case ts.SyntaxKind.ObjectBindingPattern: + case ts.SyntaxKind.JsxOpeningElement: + case ts.SyntaxKind.JsxOpeningFragment: + case ts.SyntaxKind.JsxSelfClosingElement: + case ts.SyntaxKind.JsxExpression: + case ts.SyntaxKind.MethodSignature: + case ts.SyntaxKind.CallSignature: + case ts.SyntaxKind.ConstructSignature: + case ts.SyntaxKind.Parameter: + case ts.SyntaxKind.FunctionType: + case ts.SyntaxKind.ConstructorType: + case ts.SyntaxKind.ParenthesizedType: + case ts.SyntaxKind.TaggedTemplateExpression: + case ts.SyntaxKind.AwaitExpression: + case ts.SyntaxKind.NamedExports: + case ts.SyntaxKind.NamedImports: + case ts.SyntaxKind.ExportSpecifier: + case ts.SyntaxKind.ImportSpecifier: + case ts.SyntaxKind.PropertyDeclaration: return true; - case SyntaxKind.VariableDeclaration: - case SyntaxKind.PropertyAssignment: - case SyntaxKind.BinaryExpression: - if (!settings.indentMultiLineObjectLiteralBeginningOnBlankLine && sourceFile && childKind === SyntaxKind.ObjectLiteralExpression) { // TODO: GH#18217 + case ts.SyntaxKind.VariableDeclaration: + case ts.SyntaxKind.PropertyAssignment: + case ts.SyntaxKind.BinaryExpression: + if (!settings.indentMultiLineObjectLiteralBeginningOnBlankLine && sourceFile && childKind === ts.SyntaxKind.ObjectLiteralExpression) { // TODO: GH#18217 return rangeIsOnOneLine(sourceFile, child!); } - if (parent.kind === SyntaxKind.BinaryExpression && sourceFile && child && childKind === SyntaxKind.JsxElement) { - const parentStartLine = sourceFile.getLineAndCharacterOfPosition(skipTrivia(sourceFile.text, parent.pos)).line; - const childStartLine = sourceFile.getLineAndCharacterOfPosition(skipTrivia(sourceFile.text, child.pos)).line; + if (parent.kind === ts.SyntaxKind.BinaryExpression && sourceFile && child && childKind === ts.SyntaxKind.JsxElement) { + const parentStartLine = sourceFile.getLineAndCharacterOfPosition(ts.skipTrivia(sourceFile.text, parent.pos)).line; + const childStartLine = sourceFile.getLineAndCharacterOfPosition(ts.skipTrivia(sourceFile.text, child.pos)).line; return parentStartLine !== childStartLine; } - if (parent.kind !== SyntaxKind.BinaryExpression) { + if (parent.kind !== ts.SyntaxKind.BinaryExpression) { return true; } break; - case SyntaxKind.DoStatement: - case SyntaxKind.WhileStatement: - case SyntaxKind.ForInStatement: - case SyntaxKind.ForOfStatement: - case SyntaxKind.ForStatement: - case SyntaxKind.IfStatement: - case SyntaxKind.FunctionDeclaration: - case SyntaxKind.FunctionExpression: - case SyntaxKind.MethodDeclaration: - case SyntaxKind.Constructor: - case SyntaxKind.GetAccessor: - case SyntaxKind.SetAccessor: - return childKind !== SyntaxKind.Block; - case SyntaxKind.ArrowFunction: - if (sourceFile && childKind === SyntaxKind.ParenthesizedExpression) { + case ts.SyntaxKind.DoStatement: + case ts.SyntaxKind.WhileStatement: + case ts.SyntaxKind.ForInStatement: + case ts.SyntaxKind.ForOfStatement: + case ts.SyntaxKind.ForStatement: + case ts.SyntaxKind.IfStatement: + case ts.SyntaxKind.FunctionDeclaration: + case ts.SyntaxKind.FunctionExpression: + case ts.SyntaxKind.MethodDeclaration: + case ts.SyntaxKind.Constructor: + case ts.SyntaxKind.GetAccessor: + case ts.SyntaxKind.SetAccessor: + return childKind !== ts.SyntaxKind.Block; + case ts.SyntaxKind.ArrowFunction: + if (sourceFile && childKind === ts.SyntaxKind.ParenthesizedExpression) { return rangeIsOnOneLine(sourceFile, child!); } - return childKind !== SyntaxKind.Block; - case SyntaxKind.ExportDeclaration: - return childKind !== SyntaxKind.NamedExports; - case SyntaxKind.ImportDeclaration: - return childKind !== SyntaxKind.ImportClause || - (!!(child as ImportClause).namedBindings && (child as ImportClause).namedBindings!.kind !== SyntaxKind.NamedImports); - case SyntaxKind.JsxElement: - return childKind !== SyntaxKind.JsxClosingElement; - case SyntaxKind.JsxFragment: - return childKind !== SyntaxKind.JsxClosingFragment; - case SyntaxKind.IntersectionType: - case SyntaxKind.UnionType: - if (childKind === SyntaxKind.TypeLiteral || childKind === SyntaxKind.TupleType) { + return childKind !== ts.SyntaxKind.Block; + case ts.SyntaxKind.ExportDeclaration: + return childKind !== ts.SyntaxKind.NamedExports; + case ts.SyntaxKind.ImportDeclaration: + return childKind !== ts.SyntaxKind.ImportClause || + (!!(child as ts.ImportClause).namedBindings && (child as ts.ImportClause).namedBindings!.kind !== ts.SyntaxKind.NamedImports); + case ts.SyntaxKind.JsxElement: + return childKind !== ts.SyntaxKind.JsxClosingElement; + case ts.SyntaxKind.JsxFragment: + return childKind !== ts.SyntaxKind.JsxClosingFragment; + case ts.SyntaxKind.IntersectionType: + case ts.SyntaxKind.UnionType: + if (childKind === ts.SyntaxKind.TypeLiteral || childKind === ts.SyntaxKind.TupleType) { return false; } break; @@ -679,13 +664,13 @@ namespace ts.formatting { return indentByDefault; } - function isControlFlowEndingStatement(kind: SyntaxKind, parent: TextRangeWithKind): boolean { + function isControlFlowEndingStatement(kind: ts.SyntaxKind, parent: ts.formatting.TextRangeWithKind): boolean { switch (kind) { - case SyntaxKind.ReturnStatement: - case SyntaxKind.ThrowStatement: - case SyntaxKind.ContinueStatement: - case SyntaxKind.BreakStatement: - return parent.kind !== SyntaxKind.Block; + case ts.SyntaxKind.ReturnStatement: + case ts.SyntaxKind.ThrowStatement: + case ts.SyntaxKind.ContinueStatement: + case ts.SyntaxKind.BreakStatement: + return parent.kind !== ts.SyntaxKind.Block; default: return false; } @@ -695,13 +680,13 @@ namespace ts.formatting { * True when the parent node should indent the given child by an explicit rule. * @param isNextChild If true, we are judging indent of a hypothetical child *after* this one, not the current child. */ - export function shouldIndentChildNode(settings: FormatCodeSettings, parent: TextRangeWithKind, child?: Node, sourceFile?: SourceFileLike, isNextChild = false): boolean { + export function shouldIndentChildNode(settings: ts.FormatCodeSettings, parent: ts.formatting.TextRangeWithKind, child?: ts.Node, sourceFile?: ts.SourceFileLike, isNextChild = false): boolean { return nodeWillIndentChild(settings, parent, child, sourceFile, /*indentByDefault*/ false) && !(isNextChild && child && isControlFlowEndingStatement(child.kind, parent)); } - function rangeIsOnOneLine(sourceFile: SourceFileLike, range: TextRangeWithKind) { - const rangeStart = skipTrivia(sourceFile.text, range.pos); + function rangeIsOnOneLine(sourceFile: ts.SourceFileLike, range: ts.formatting.TextRangeWithKind) { + const rangeStart = ts.skipTrivia(sourceFile.text, range.pos); const startLine = sourceFile.getLineAndCharacterOfPosition(rangeStart).line; const endLine = sourceFile.getLineAndCharacterOfPosition(range.end).line; return startLine === endLine; diff --git a/src/services/getEditsForFileRename.ts b/src/services/getEditsForFileRename.ts index 369f8e8e23f07..eeae02d58e67f 100644 --- a/src/services/getEditsForFileRename.ts +++ b/src/services/getEditsForFileRename.ts @@ -1,19 +1,11 @@ /* @internal */ namespace ts { - export function getEditsForFileRename( - program: Program, - oldFileOrDirPath: string, - newFileOrDirPath: string, - host: LanguageServiceHost, - formatContext: formatting.FormatContext, - preferences: UserPreferences, - sourceMapper: SourceMapper, - ): readonly FileTextChanges[] { - const useCaseSensitiveFileNames = hostUsesCaseSensitiveFileNames(host); - const getCanonicalFileName = createGetCanonicalFileName(useCaseSensitiveFileNames); + export function getEditsForFileRename(program: ts.Program, oldFileOrDirPath: string, newFileOrDirPath: string, host: ts.LanguageServiceHost, formatContext: ts.formatting.FormatContext, preferences: ts.UserPreferences, sourceMapper: ts.SourceMapper): readonly ts.FileTextChanges[] { + const useCaseSensitiveFileNames = ts.hostUsesCaseSensitiveFileNames(host); + const getCanonicalFileName = ts.createGetCanonicalFileName(useCaseSensitiveFileNames); const oldToNew = getPathUpdater(oldFileOrDirPath, newFileOrDirPath, getCanonicalFileName, sourceMapper); const newToOld = getPathUpdater(newFileOrDirPath, oldFileOrDirPath, getCanonicalFileName, sourceMapper); - return textChanges.ChangeTracker.with({ host, formatContext, preferences }, changeTracker => { + return ts.textChanges.ChangeTracker.with({ host, formatContext, preferences }, changeTracker => { updateTsconfigFiles(program, changeTracker, oldToNew, oldFileOrDirPath, newFileOrDirPath, host.getCurrentDirectory(), useCaseSensitiveFileNames); updateImports(program, changeTracker, oldToNew, newToOld, host, getCanonicalFileName); }); @@ -22,7 +14,7 @@ namespace ts { /** If 'path' refers to an old directory, returns path in the new directory. */ type PathUpdater = (path: string) => string | undefined; // exported for tests - export function getPathUpdater(oldFileOrDirPath: string, newFileOrDirPath: string, getCanonicalFileName: GetCanonicalFileName, sourceMapper: SourceMapper | undefined): PathUpdater { + export function getPathUpdater(oldFileOrDirPath: string, newFileOrDirPath: string, getCanonicalFileName: ts.GetCanonicalFileName, sourceMapper: ts.SourceMapper | undefined): PathUpdater { const canonicalOldPath = getCanonicalFileName(oldFileOrDirPath); return path => { const originalPath = sourceMapper && sourceMapper.tryGetSourcePosition({ fileName: path, pos: 0 }); @@ -33,25 +25,27 @@ namespace ts { }; function getUpdatedPath(pathToUpdate: string): string | undefined { - if (getCanonicalFileName(pathToUpdate) === canonicalOldPath) return newFileOrDirPath; - const suffix = tryRemoveDirectoryPrefix(pathToUpdate, canonicalOldPath, getCanonicalFileName); + if (getCanonicalFileName(pathToUpdate) === canonicalOldPath) + return newFileOrDirPath; + const suffix = ts.tryRemoveDirectoryPrefix(pathToUpdate, canonicalOldPath, getCanonicalFileName); return suffix === undefined ? undefined : newFileOrDirPath + "/" + suffix; } } // Relative path from a0 to b0 should be same as relative path from a1 to b1. Returns b1. - function makeCorrespondingRelativeChange(a0: string, b0: string, a1: string, getCanonicalFileName: GetCanonicalFileName): string { - const rel = getRelativePathFromFile(a0, b0, getCanonicalFileName); - return combinePathsSafe(getDirectoryPath(a1), rel); + function makeCorrespondingRelativeChange(a0: string, b0: string, a1: string, getCanonicalFileName: ts.GetCanonicalFileName): string { + const rel = ts.getRelativePathFromFile(a0, b0, getCanonicalFileName); + return combinePathsSafe(ts.getDirectoryPath(a1), rel); } - function updateTsconfigFiles(program: Program, changeTracker: textChanges.ChangeTracker, oldToNew: PathUpdater, oldFileOrDirPath: string, newFileOrDirPath: string, currentDirectory: string, useCaseSensitiveFileNames: boolean): void { + function updateTsconfigFiles(program: ts.Program, changeTracker: ts.textChanges.ChangeTracker, oldToNew: PathUpdater, oldFileOrDirPath: string, newFileOrDirPath: string, currentDirectory: string, useCaseSensitiveFileNames: boolean): void { const { configFile } = program.getCompilerOptions(); - if (!configFile) return; - const configDir = getDirectoryPath(configFile.fileName); - - const jsonObjectLiteral = getTsConfigObjectLiteralExpression(configFile); - if (!jsonObjectLiteral) return; + if (!configFile) + return; + const configDir = ts.getDirectoryPath(configFile.fileName); + const jsonObjectLiteral = ts.getTsConfigObjectLiteralExpression(configFile); + if (!jsonObjectLiteral) + return; forEachProperty(jsonObjectLiteral, (property, propertyName) => { switch (propertyName) { @@ -59,26 +53,29 @@ namespace ts { case "include": case "exclude": { const foundExactMatch = updatePaths(property); - if (foundExactMatch || propertyName !== "include" || !isArrayLiteralExpression(property.initializer)) return; - const includes = mapDefined(property.initializer.elements, e => isStringLiteral(e) ? e.text : undefined); - if (includes.length === 0) return; - const matchers = getFileMatcherPatterns(configDir, /*excludes*/ [], includes, useCaseSensitiveFileNames, currentDirectory); + if (foundExactMatch || propertyName !== "include" || !ts.isArrayLiteralExpression(property.initializer)) + return; + const includes = ts.mapDefined(property.initializer.elements, e => ts.isStringLiteral(e) ? e.text : undefined); + if (includes.length === 0) + return; + const matchers = ts.getFileMatcherPatterns(configDir, /*excludes*/ [], includes, useCaseSensitiveFileNames, currentDirectory); // If there isn't some include for this, add a new one. - if (getRegexFromPattern(Debug.checkDefined(matchers.includeFilePattern), useCaseSensitiveFileNames).test(oldFileOrDirPath) && - !getRegexFromPattern(Debug.checkDefined(matchers.includeFilePattern), useCaseSensitiveFileNames).test(newFileOrDirPath)) { - changeTracker.insertNodeAfter(configFile, last(property.initializer.elements), factory.createStringLiteral(relativePath(newFileOrDirPath))); + if (ts.getRegexFromPattern(ts.Debug.checkDefined(matchers.includeFilePattern), useCaseSensitiveFileNames).test(oldFileOrDirPath) && + !ts.getRegexFromPattern(ts.Debug.checkDefined(matchers.includeFilePattern), useCaseSensitiveFileNames).test(newFileOrDirPath)) { + changeTracker.insertNodeAfter(configFile, ts.last(property.initializer.elements), ts.factory.createStringLiteral(relativePath(newFileOrDirPath))); } return; } case "compilerOptions": forEachProperty(property.initializer, (property, propertyName) => { - const option = getOptionFromName(propertyName); + const option = ts.getOptionFromName(propertyName); if (option && (option.isFilePath || option.type === "list" && option.element.isFilePath)) { updatePaths(property); } else if (propertyName === "paths") { forEachProperty(property.initializer, (pathsProperty) => { - if (!isArrayLiteralExpression(pathsProperty.initializer)) return; + if (!ts.isArrayLiteralExpression(pathsProperty.initializer)) + return; for (const e of pathsProperty.initializer.elements) { tryUpdateString(e); } @@ -89,8 +86,8 @@ namespace ts { } }); - function updatePaths(property: PropertyAssignment): boolean { - const elements = isArrayLiteralExpression(property.initializer) ? property.initializer.elements : [property.initializer]; + function updatePaths(property: ts.PropertyAssignment): boolean { + const elements = ts.isArrayLiteralExpression(property.initializer) ? property.initializer.elements : [property.initializer]; let foundExactMatch = false; for (const element of elements) { foundExactMatch = tryUpdateString(element) || foundExactMatch; @@ -98,8 +95,9 @@ namespace ts { return foundExactMatch; } - function tryUpdateString(element: Expression): boolean { - if (!isStringLiteral(element)) return false; + function tryUpdateString(element: ts.Expression): boolean { + if (!ts.isStringLiteral(element)) + return false; const elementFileName = combinePathsSafe(configDir, element.text); const updated = oldToNew(elementFileName); @@ -111,62 +109,53 @@ namespace ts { } function relativePath(path: string): string { - return getRelativePathFromDirectory(configDir, path, /*ignoreCase*/ !useCaseSensitiveFileNames); + return ts.getRelativePathFromDirectory(configDir, path, /*ignoreCase*/ !useCaseSensitiveFileNames); } } - - function updateImports( - program: Program, - changeTracker: textChanges.ChangeTracker, - oldToNew: PathUpdater, - newToOld: PathUpdater, - host: LanguageServiceHost, - getCanonicalFileName: GetCanonicalFileName, - ): void { + function updateImports(program: ts.Program, changeTracker: ts.textChanges.ChangeTracker, oldToNew: PathUpdater, newToOld: PathUpdater, host: ts.LanguageServiceHost, getCanonicalFileName: ts.GetCanonicalFileName): void { const allFiles = program.getSourceFiles(); for (const sourceFile of allFiles) { const newFromOld = oldToNew(sourceFile.fileName); const newImportFromPath = newFromOld ?? sourceFile.fileName; - const newImportFromDirectory = getDirectoryPath(newImportFromPath); + const newImportFromDirectory = ts.getDirectoryPath(newImportFromPath); const oldFromNew: string | undefined = newToOld(sourceFile.fileName); const oldImportFromPath: string = oldFromNew || sourceFile.fileName; - const oldImportFromDirectory = getDirectoryPath(oldImportFromPath); + const oldImportFromDirectory = ts.getDirectoryPath(oldImportFromPath); const importingSourceFileMoved = newFromOld !== undefined || oldFromNew !== undefined; - updateImportsWorker(sourceFile, changeTracker, - referenceText => { - if (!pathIsRelative(referenceText)) return undefined; + updateImportsWorker(sourceFile, changeTracker, referenceText => { + if (!ts.pathIsRelative(referenceText)) + return undefined; const oldAbsolute = combinePathsSafe(oldImportFromDirectory, referenceText); const newAbsolute = oldToNew(oldAbsolute); - return newAbsolute === undefined ? undefined : ensurePathIsNonModuleName(getRelativePathFromDirectory(newImportFromDirectory, newAbsolute, getCanonicalFileName)); - }, - importLiteral => { + return newAbsolute === undefined ? undefined : ts.ensurePathIsNonModuleName(ts.getRelativePathFromDirectory(newImportFromDirectory, newAbsolute, getCanonicalFileName)); + }, importLiteral => { const importedModuleSymbol = program.getTypeChecker().getSymbolAtLocation(importLiteral); // No need to update if it's an ambient module^M - if (importedModuleSymbol?.declarations && importedModuleSymbol.declarations.some(d => isAmbientModule(d))) return undefined; + if (importedModuleSymbol?.declarations && importedModuleSymbol.declarations.some(d => ts.isAmbientModule(d))) + return undefined; const toImport = oldFromNew !== undefined // If we're at the new location (file was already renamed), need to redo module resolution starting from the old location. // TODO:GH#18217 - ? getSourceFileToImportFromResolved(importLiteral, resolveModuleName(importLiteral.text, oldImportFromPath, program.getCompilerOptions(), host as ModuleResolutionHost), - oldToNew, allFiles) + ? getSourceFileToImportFromResolved(importLiteral, ts.resolveModuleName(importLiteral.text, oldImportFromPath, program.getCompilerOptions(), host as ts.ModuleResolutionHost), oldToNew, allFiles) : getSourceFileToImport(importedModuleSymbol, importLiteral, sourceFile, program, host, oldToNew); // Need an update if the imported file moved, or the importing file moved and was using a relative path. - return toImport !== undefined && (toImport.updated || (importingSourceFileMoved && pathIsRelative(importLiteral.text))) - ? moduleSpecifiers.updateModuleSpecifier(program.getCompilerOptions(), sourceFile, getCanonicalFileName(newImportFromPath) as Path, toImport.newFileName, createModuleSpecifierResolutionHost(program, host), importLiteral.text) + return toImport !== undefined && (toImport.updated || (importingSourceFileMoved && ts.pathIsRelative(importLiteral.text))) + ? ts.moduleSpecifiers.updateModuleSpecifier(program.getCompilerOptions(), sourceFile, getCanonicalFileName(newImportFromPath) as ts.Path, toImport.newFileName, ts.createModuleSpecifierResolutionHost(program, host), importLiteral.text) : undefined; }); } } function combineNormal(pathA: string, pathB: string): string { - return normalizePath(combinePaths(pathA, pathB)); + return ts.normalizePath(ts.combinePaths(pathA, pathB)); } function combinePathsSafe(pathA: string, pathB: string): string { - return ensurePathIsNonModuleName(combineNormal(pathA, pathB)); + return ts.ensurePathIsNonModuleName(combineNormal(pathA, pathB)); } interface ToImport { @@ -174,22 +163,15 @@ namespace ts { /** True if the imported file was renamed. */ readonly updated: boolean; } - function getSourceFileToImport( - importedModuleSymbol: Symbol | undefined, - importLiteral: StringLiteralLike, - importingSourceFile: SourceFile, - program: Program, - host: LanguageServiceHost, - oldToNew: PathUpdater, - ): ToImport | undefined { + function getSourceFileToImport(importedModuleSymbol: ts.Symbol | undefined, importLiteral: ts.StringLiteralLike, importingSourceFile: ts.SourceFile, program: ts.Program, host: ts.LanguageServiceHost, oldToNew: PathUpdater): ToImport | undefined { if (importedModuleSymbol) { // `find` should succeed because we checked for ambient modules before calling this function. - const oldFileName = find(importedModuleSymbol.declarations!, isSourceFile)!.fileName; + const oldFileName = ts.find(importedModuleSymbol.declarations!, ts.isSourceFile)!.fileName; const newFileName = oldToNew(oldFileName); return newFileName === undefined ? { newFileName: oldFileName, updated: false } : { newFileName, updated: true }; } else { - const mode = getModeForUsageLocation(importingSourceFile, importLiteral); + const mode = ts.getModeForUsageLocation(importingSourceFile, importLiteral); const resolved = host.resolveModuleNames ? host.getResolvedModuleWithFailedLookupLocationsFromCache && host.getResolvedModuleWithFailedLookupLocationsFromCache(importLiteral.text, importingSourceFile.fileName, mode) : program.getResolvedModuleWithFailedLookupLocationsFromCache(importLiteral.text, importingSourceFile.fileName, mode); @@ -197,35 +179,38 @@ namespace ts { } } - function getSourceFileToImportFromResolved(importLiteral: StringLiteralLike, resolved: ResolvedModuleWithFailedLookupLocations | undefined, oldToNew: PathUpdater, sourceFiles: readonly SourceFile[]): ToImport | undefined { + function getSourceFileToImportFromResolved(importLiteral: ts.StringLiteralLike, resolved: ts.ResolvedModuleWithFailedLookupLocations | undefined, oldToNew: PathUpdater, sourceFiles: readonly ts.SourceFile[]): ToImport | undefined { // Search through all locations looking for a moved file, and only then test already existing files. // This is because if `a.ts` is compiled to `a.js` and `a.ts` is moved, we don't want to resolve anything to `a.js`, but to `a.ts`'s new location. - if (!resolved) return undefined; + if (!resolved) + return undefined; // First try resolved module if (resolved.resolvedModule) { const result = tryChange(resolved.resolvedModule.resolvedFileName); - if (result) return result; + if (result) + return result; } // Then failed lookups that are in the list of sources - const result = forEach(resolved.failedLookupLocations, tryChangeWithIgnoringPackageJsonExisting) + const result = ts.forEach(resolved.failedLookupLocations, tryChangeWithIgnoringPackageJsonExisting) // Then failed lookups except package.json since we dont want to touch them (only included ts/js files). // At this point, the confidence level of this fix being correct is too low to change bare specifiers or absolute paths. - || pathIsRelative(importLiteral.text) && forEach(resolved.failedLookupLocations, tryChangeWithIgnoringPackageJson); - if (result) return result; + || ts.pathIsRelative(importLiteral.text) && ts.forEach(resolved.failedLookupLocations, tryChangeWithIgnoringPackageJson); + if (result) + return result; // If nothing changed, then result is resolved module file thats not updated return resolved.resolvedModule && { newFileName: resolved.resolvedModule.resolvedFileName, updated: false }; function tryChangeWithIgnoringPackageJsonExisting(oldFileName: string) { const newFileName = oldToNew(oldFileName); - return newFileName && find(sourceFiles, src => src.fileName === newFileName) + return newFileName && ts.find(sourceFiles, src => src.fileName === newFileName) ? tryChangeWithIgnoringPackageJson(oldFileName) : undefined; } function tryChangeWithIgnoringPackageJson(oldFileName: string) { - return !endsWith(oldFileName, "/package.json") ? tryChange(oldFileName) : undefined; + return !ts.endsWith(oldFileName, "/package.json") ? tryChange(oldFileName) : undefined; } function tryChange(oldFileName: string) { @@ -234,26 +219,29 @@ namespace ts { } } - function updateImportsWorker(sourceFile: SourceFile, changeTracker: textChanges.ChangeTracker, updateRef: (refText: string) => string | undefined, updateImport: (importLiteral: StringLiteralLike) => string | undefined) { - for (const ref of sourceFile.referencedFiles || emptyArray) { // TODO: GH#26162 + function updateImportsWorker(sourceFile: ts.SourceFile, changeTracker: ts.textChanges.ChangeTracker, updateRef: (refText: string) => string | undefined, updateImport: (importLiteral: ts.StringLiteralLike) => string | undefined) { + for (const ref of sourceFile.referencedFiles || ts.emptyArray) { // TODO: GH#26162 const updated = updateRef(ref.fileName); - if (updated !== undefined && updated !== sourceFile.text.slice(ref.pos, ref.end)) changeTracker.replaceRangeWithText(sourceFile, ref, updated); + if (updated !== undefined && updated !== sourceFile.text.slice(ref.pos, ref.end)) + changeTracker.replaceRangeWithText(sourceFile, ref, updated); } for (const importStringLiteral of sourceFile.imports) { const updated = updateImport(importStringLiteral); - if (updated !== undefined && updated !== importStringLiteral.text) changeTracker.replaceRangeWithText(sourceFile, createStringRange(importStringLiteral, sourceFile), updated); + if (updated !== undefined && updated !== importStringLiteral.text) + changeTracker.replaceRangeWithText(sourceFile, createStringRange(importStringLiteral, sourceFile), updated); } } - function createStringRange(node: StringLiteralLike, sourceFile: SourceFileLike): TextRange { - return createRange(node.getStart(sourceFile) + 1, node.end - 1); + function createStringRange(node: ts.StringLiteralLike, sourceFile: ts.SourceFileLike): ts.TextRange { + return ts.createRange(node.getStart(sourceFile) + 1, node.end - 1); } - function forEachProperty(objectLiteral: Expression, cb: (property: PropertyAssignment, propertyName: string) => void) { - if (!isObjectLiteralExpression(objectLiteral)) return; + function forEachProperty(objectLiteral: ts.Expression, cb: (property: ts.PropertyAssignment, propertyName: string) => void) { + if (!ts.isObjectLiteralExpression(objectLiteral)) + return; for (const property of objectLiteral.properties) { - if (isPropertyAssignment(property) && isStringLiteral(property.name)) { + if (ts.isPropertyAssignment(property) && ts.isStringLiteral(property.name)) { cb(property, property.name.text); } } diff --git a/src/services/globalThisShim.ts b/src/services/globalThisShim.ts index 899bb009895c0..28c009422c4a3 100644 --- a/src/services/globalThisShim.ts +++ b/src/services/globalThisShim.ts @@ -9,7 +9,8 @@ declare var window: {}; /* eslint-enable no-var */ ((() => { - if (typeof globalThis === "object") return; + if (typeof globalThis === "object") + return; try { Object.defineProperty(Object.prototype, "__magic__", { get() { diff --git a/src/services/goToDefinition.ts b/src/services/goToDefinition.ts index f9f742e65a451..0e4819dfb6fe2 100644 --- a/src/services/goToDefinition.ts +++ b/src/services/goToDefinition.ts @@ -1,14 +1,14 @@ /* @internal */ namespace ts.GoToDefinition { - export function getDefinitionAtPosition(program: Program, sourceFile: SourceFile, position: number, searchOtherFilesOnly?: boolean, stopAtAlias?: boolean): readonly DefinitionInfo[] | undefined { + export function getDefinitionAtPosition(program: ts.Program, sourceFile: ts.SourceFile, position: number, searchOtherFilesOnly?: boolean, stopAtAlias?: boolean): readonly ts.DefinitionInfo[] | undefined { const resolvedRef = getReferenceAtPosition(sourceFile, position, program); - const fileReferenceDefinition = resolvedRef && [getDefinitionInfoForFileReference(resolvedRef.reference.fileName, resolvedRef.fileName, resolvedRef.unverified)] || emptyArray; + const fileReferenceDefinition = resolvedRef && [getDefinitionInfoForFileReference(resolvedRef.reference.fileName, resolvedRef.fileName, resolvedRef.unverified)] || ts.emptyArray; if (resolvedRef?.file) { // If `file` is missing, do a symbol-based lookup as well return fileReferenceDefinition; } - const node = getTouchingPropertyName(sourceFile, position); + const node = ts.getTouchingPropertyName(sourceFile, position); if (node === sourceFile) { return undefined; } @@ -16,27 +16,27 @@ namespace ts.GoToDefinition { const { parent } = node; const typeChecker = program.getTypeChecker(); - if (node.kind === SyntaxKind.OverrideKeyword || (isJSDocOverrideTag(node) && rangeContainsPosition(node.tagName, position))) { - return getDefinitionFromOverriddenMember(typeChecker, node) || emptyArray; + if (node.kind === ts.SyntaxKind.OverrideKeyword || (ts.isJSDocOverrideTag(node) && ts.rangeContainsPosition(node.tagName, position))) { + return getDefinitionFromOverriddenMember(typeChecker, node) || ts.emptyArray; } // Labels - if (isJumpStatementTarget(node)) { - const label = getTargetLabel(node.parent, node.text); - return label ? [createDefinitionInfoFromName(typeChecker, label, ScriptElementKind.label, node.text, /*containerName*/ undefined!)] : undefined; // TODO: GH#18217 + if (ts.isJumpStatementTarget(node)) { + const label = ts.getTargetLabel(node.parent, node.text); + return label ? [createDefinitionInfoFromName(typeChecker, label, ts.ScriptElementKind.label, node.text, /*containerName*/ undefined!)] : undefined; // TODO: GH#18217 } - if (isStaticModifier(node) && isClassStaticBlockDeclaration(node.parent)) { + if (ts.isStaticModifier(node) && ts.isClassStaticBlockDeclaration(node.parent)) { const classDecl = node.parent.parent; const { symbol, failedAliasResolution } = getSymbol(classDecl, typeChecker, stopAtAlias); - const staticBlocks = filter(classDecl.members, isClassStaticBlockDeclaration); + const staticBlocks = ts.filter(classDecl.members, ts.isClassStaticBlockDeclaration); const containerName = symbol ? typeChecker.symbolToString(symbol, classDecl) : ""; const sourceFile = node.getSourceFile(); - return map(staticBlocks, staticBlock => { - let { pos } = moveRangePastModifiers(staticBlock); - pos = skipTrivia(sourceFile.text, pos); - return createDefinitionInfoFromName(typeChecker, staticBlock, ScriptElementKind.constructorImplementationElement, "static {}", containerName, /*unverified*/ false, failedAliasResolution, { start: pos, length: "static".length }); + return ts.map(staticBlocks, staticBlock => { + let { pos } = ts.moveRangePastModifiers(staticBlock); + pos = ts.skipTrivia(sourceFile.text, pos); + return createDefinitionInfoFromName(typeChecker, staticBlock, ts.ScriptElementKind.constructorImplementationElement, "static {}", containerName, /*unverified*/ false, failedAliasResolution, { start: pos, length: "static".length }); }); } @@ -45,28 +45,28 @@ namespace ts.GoToDefinition { if (searchOtherFilesOnly && failedAliasResolution) { // We couldn't resolve the specific import, try on the module specifier. - const importDeclaration = forEach([node, ...symbol?.declarations || emptyArray], n => findAncestor(n, isAnyImportOrBareOrAccessedRequire)); - const moduleSpecifier = importDeclaration && tryGetModuleSpecifierFromDeclaration(importDeclaration); + const importDeclaration = ts.forEach([node, ...symbol?.declarations || ts.emptyArray], n => ts.findAncestor(n, ts.isAnyImportOrBareOrAccessedRequire)); + const moduleSpecifier = importDeclaration && ts.tryGetModuleSpecifierFromDeclaration(importDeclaration); if (moduleSpecifier) { ({ symbol, failedAliasResolution } = getSymbol(moduleSpecifier, typeChecker, stopAtAlias)); fallbackNode = moduleSpecifier; } } - if (!symbol && isModuleSpecifierLike(fallbackNode)) { + if (!symbol && ts.isModuleSpecifierLike(fallbackNode)) { // We couldn't resolve the module specifier as an external module, but it could // be that module resolution succeeded but the target was not a module. - const ref = sourceFile.resolvedModules?.get(fallbackNode.text, getModeForUsageLocation(sourceFile, fallbackNode)); + const ref = sourceFile.resolvedModules?.get(fallbackNode.text, ts.getModeForUsageLocation(sourceFile, fallbackNode)); if (ref) { return [{ name: fallbackNode.text, fileName: ref.resolvedFileName, containerName: undefined!, containerKind: undefined!, - kind: ScriptElementKind.scriptElement, - textSpan: createTextSpan(0, 0), + kind: ts.ScriptElementKind.scriptElement, + textSpan: ts.createTextSpan(0, 0), failedAliasResolution, - isAmbient: isDeclarationFileName(ref.resolvedFileName), + isAmbient: ts.isDeclarationFileName(ref.resolvedFileName), unverified: fallbackNode !== node, }]; } @@ -75,14 +75,15 @@ namespace ts.GoToDefinition { // Could not find a symbol e.g. node is string or number keyword, // or the symbol was an internal symbol and does not have a declaration e.g. undefined symbol if (!symbol) { - return concatenate(fileReferenceDefinition, getDefinitionInfoForIndexSignatures(node, typeChecker)); + return ts.concatenate(fileReferenceDefinition, getDefinitionInfoForIndexSignatures(node, typeChecker)); } - if (searchOtherFilesOnly && every(symbol.declarations, d => d.getSourceFile().fileName === sourceFile.fileName)) return undefined; + if (searchOtherFilesOnly && ts.every(symbol.declarations, d => d.getSourceFile().fileName === sourceFile.fileName)) + return undefined; const calledDeclaration = tryGetSignatureDeclaration(typeChecker, node); // Don't go to the component constructor definition for a JSX element, just go to the component definition. - if (calledDeclaration && !(isJsxOpeningLikeElement(node.parent) && isConstructorLike(calledDeclaration))) { + if (calledDeclaration && !(ts.isJsxOpeningLikeElement(node.parent) && isConstructorLike(calledDeclaration))) { const sigInfo = createDefinitionFromSignatureDeclaration(typeChecker, calledDeclaration, failedAliasResolution); // For a function, if this is the original function definition, return just sigInfo. // If this is the original constructor definition, parent is the class. @@ -90,9 +91,9 @@ namespace ts.GoToDefinition { return [sigInfo]; } else { - const defs = getDefinitionFromSymbol(typeChecker, symbol, node, failedAliasResolution, calledDeclaration) || emptyArray; + const defs = getDefinitionFromSymbol(typeChecker, symbol, node, failedAliasResolution, calledDeclaration) || ts.emptyArray; // For a 'super()' call, put the signature first, else put the variable first. - return node.kind === SyntaxKind.SuperKeyword ? [sigInfo, ...defs] : [...defs, sigInfo]; + return node.kind === ts.SyntaxKind.SuperKeyword ? [sigInfo, ...defs] : [...defs, sigInfo]; } } @@ -101,10 +102,10 @@ namespace ts.GoToDefinition { // go to the declaration of the property name (in this case stay at the same position). However, if go-to-definition // is performed at the location of property access, we would like to go to definition of the property in the short-hand // assignment. This case and others are handled by the following code. - if (node.parent.kind === SyntaxKind.ShorthandPropertyAssignment) { + if (node.parent.kind === ts.SyntaxKind.ShorthandPropertyAssignment) { const shorthandSymbol = typeChecker.getShorthandAssignmentValueSymbol(symbol.valueDeclaration); - const definitions = shorthandSymbol?.declarations ? shorthandSymbol.declarations.map(decl => createDefinitionInfo(decl, typeChecker, shorthandSymbol, node, /*unverified*/ false, failedAliasResolution)) : emptyArray; - return concatenate(definitions, getDefinitionFromObjectLiteralElement(typeChecker, node) || emptyArray); + const definitions = shorthandSymbol?.declarations ? shorthandSymbol.declarations.map(decl => createDefinitionInfo(decl, typeChecker, shorthandSymbol, node, /*unverified*/ false, failedAliasResolution)) : ts.emptyArray; + return ts.concatenate(definitions, getDefinitionFromObjectLiteralElement(typeChecker, node) || ts.emptyArray); } // If the node is the name of a BindingElement within an ObjectBindingPattern instead of just returning the @@ -118,17 +119,17 @@ namespace ts.GoToDefinition { // pr/*destination*/op1: number // } // bar(({pr/*goto*/op1})=>{}); - if (isPropertyName(node) && isBindingElement(parent) && isObjectBindingPattern(parent.parent) && + if (ts.isPropertyName(node) && ts.isBindingElement(parent) && ts.isObjectBindingPattern(parent.parent) && (node === (parent.propertyName || parent.name))) { - const name = getNameFromPropertyName(node); + const name = ts.getNameFromPropertyName(node); const type = typeChecker.getTypeAtLocation(parent.parent); - return name === undefined ? emptyArray : flatMap(type.isUnion() ? type.types : [type], t => { + return name === undefined ? ts.emptyArray : ts.flatMap(type.isUnion() ? type.types : [type], t => { const prop = t.getProperty(name); return prop && getDefinitionFromSymbol(typeChecker, prop, node); }); } - return concatenate(fileReferenceDefinition, getDefinitionFromObjectLiteralElement(typeChecker, node) || getDefinitionFromSymbol(typeChecker, symbol, node, failedAliasResolution)); + return ts.concatenate(fileReferenceDefinition, getDefinitionFromObjectLiteralElement(typeChecker, node) || getDefinitionFromSymbol(typeChecker, symbol, node, failedAliasResolution)); } /** @@ -136,11 +137,11 @@ namespace ts.GoToDefinition { * True for `const |f = |() => 0`, false for `function |f() {} const |g = f;`. * Also true for any assignment RHS. */ - function symbolMatchesSignature(s: Symbol, calledDeclaration: SignatureDeclaration) { + function symbolMatchesSignature(s: ts.Symbol, calledDeclaration: ts.SignatureDeclaration) { return s === calledDeclaration.symbol || s === calledDeclaration.symbol.parent - || isAssignmentExpression(calledDeclaration.parent) - || (!isCallLikeExpression(calledDeclaration.parent) && s === calledDeclaration.parent.symbol); + || ts.isAssignmentExpression(calledDeclaration.parent) + || (!ts.isCallLikeExpression(calledDeclaration.parent) && s === calledDeclaration.parent.symbol); } // If the current location we want to find its definition is in an object literal, try to get the contextual type for the @@ -152,38 +153,43 @@ namespace ts.GoToDefinition { // } // function Foo(arg: Props) {} // Foo( { pr/*1*/op1: 10, prop2: true }) - function getDefinitionFromObjectLiteralElement(typeChecker: TypeChecker, node: Node) { - const element = getContainingObjectLiteralElement(node); + function getDefinitionFromObjectLiteralElement(typeChecker: ts.TypeChecker, node: ts.Node) { + const element = ts.getContainingObjectLiteralElement(node); if (element) { const contextualType = element && typeChecker.getContextualType(element.parent); if (contextualType) { - return flatMap(getPropertySymbolsFromContextualType(element, typeChecker, contextualType, /*unionSymbolOk*/ false), propertySymbol => - getDefinitionFromSymbol(typeChecker, propertySymbol, node)); + return ts.flatMap(ts.getPropertySymbolsFromContextualType(element, typeChecker, contextualType, /*unionSymbolOk*/ false), propertySymbol => getDefinitionFromSymbol(typeChecker, propertySymbol, node)); } } } - function getDefinitionFromOverriddenMember(typeChecker: TypeChecker, node: Node) { - const classElement = findAncestor(node, isClassElement); - if (!(classElement && classElement.name)) return; - - const baseDeclaration = findAncestor(classElement, isClassLike); - if (!baseDeclaration) return; - - const baseTypeNode = getEffectiveBaseTypeNode(baseDeclaration); + function getDefinitionFromOverriddenMember(typeChecker: ts.TypeChecker, node: ts.Node) { + const classElement = ts.findAncestor(node, ts.isClassElement); + if (!(classElement && classElement.name)) + return; + const baseDeclaration = ts.findAncestor(classElement, ts.isClassLike); + if (!baseDeclaration) + return; + const baseTypeNode = ts.getEffectiveBaseTypeNode(baseDeclaration); const baseType = baseTypeNode ? typeChecker.getTypeAtLocation(baseTypeNode) : undefined; - if (!baseType) return; - - const name = unescapeLeadingUnderscores(getTextOfPropertyName(classElement.name)); - const symbol = hasStaticModifier(classElement) + if (!baseType) + return; + const name = ts.unescapeLeadingUnderscores(ts.getTextOfPropertyName(classElement.name)); + const symbol = ts.hasStaticModifier(classElement) ? typeChecker.getPropertyOfType(typeChecker.getTypeOfSymbolAtLocation(baseType.symbol, baseDeclaration), name) : typeChecker.getPropertyOfType(baseType, name); - if (!symbol) return; + if (!symbol) + return; return getDefinitionFromSymbol(typeChecker, symbol, node); } - export function getReferenceAtPosition(sourceFile: SourceFile, position: number, program: Program): { reference: FileReference, fileName: string, unverified: boolean, file?: SourceFile } | undefined { + export function getReferenceAtPosition(sourceFile: ts.SourceFile, position: number, program: ts.Program): { + reference: ts.FileReference; + fileName: string; + unverified: boolean; + file?: ts.SourceFile; + } | undefined { const referencePath = findReferenceInPosition(sourceFile.referencedFiles, position); if (referencePath) { const file = program.getSourceFileFromReference(sourceFile, referencePath); @@ -204,10 +210,10 @@ namespace ts.GoToDefinition { } if (sourceFile.resolvedModules?.size()) { - const node = getTouchingToken(sourceFile, position); - if (isModuleSpecifierLike(node) && isExternalModuleNameRelative(node.text) && sourceFile.resolvedModules.has(node.text, getModeForUsageLocation(sourceFile, node))) { - const verifiedFileName = sourceFile.resolvedModules.get(node.text, getModeForUsageLocation(sourceFile, node))?.resolvedFileName; - const fileName = verifiedFileName || resolvePath(getDirectoryPath(sourceFile.fileName), node.text); + const node = ts.getTouchingToken(sourceFile, position); + if (ts.isModuleSpecifierLike(node) && ts.isExternalModuleNameRelative(node.text) && sourceFile.resolvedModules.has(node.text, ts.getModeForUsageLocation(sourceFile, node))) { + const verifiedFileName = sourceFile.resolvedModules.get(node.text, ts.getModeForUsageLocation(sourceFile, node))?.resolvedFileName; + const fileName = verifiedFileName || ts.resolvePath(ts.getDirectoryPath(sourceFile.fileName), node.text); return { file: program.getSourceFile(fileName), fileName, @@ -225,18 +231,19 @@ namespace ts.GoToDefinition { } /// Goto type - export function getTypeDefinitionAtPosition(typeChecker: TypeChecker, sourceFile: SourceFile, position: number): readonly DefinitionInfo[] | undefined { - const node = getTouchingPropertyName(sourceFile, position); + export function getTypeDefinitionAtPosition(typeChecker: ts.TypeChecker, sourceFile: ts.SourceFile, position: number): readonly ts.DefinitionInfo[] | undefined { + const node = ts.getTouchingPropertyName(sourceFile, position); if (node === sourceFile) { return undefined; } - if (isImportMeta(node.parent) && node.parent.name === node) { + if (ts.isImportMeta(node.parent) && node.parent.name === node) { return definitionFromType(typeChecker.getTypeAtLocation(node.parent), typeChecker, node.parent, /*failedAliasResolution*/ false); } const { symbol, failedAliasResolution } = getSymbol(node, typeChecker, /*stopAtAlias*/ false); - if (!symbol) return undefined; + if (!symbol) + return undefined; const typeAtLocation = typeChecker.getTypeOfSymbolAtLocation(symbol, node); const returnType = tryGetReturnTypeOfFunction(symbol, typeAtLocation, typeChecker); @@ -244,28 +251,28 @@ namespace ts.GoToDefinition { // If a function returns 'void' or some other type with no definition, just return the function definition. const typeDefinitions = fromReturnType && fromReturnType.length !== 0 ? fromReturnType : definitionFromType(typeAtLocation, typeChecker, node, failedAliasResolution); return typeDefinitions.length ? typeDefinitions - : !(symbol.flags & SymbolFlags.Value) && symbol.flags & SymbolFlags.Type ? getDefinitionFromSymbol(typeChecker, skipAlias(symbol, typeChecker), node, failedAliasResolution) + : !(symbol.flags & ts.SymbolFlags.Value) && symbol.flags & ts.SymbolFlags.Type ? getDefinitionFromSymbol(typeChecker, ts.skipAlias(symbol, typeChecker), node, failedAliasResolution) : undefined; } - function definitionFromType(type: Type, checker: TypeChecker, node: Node, failedAliasResolution: boolean | undefined): readonly DefinitionInfo[] { - return flatMap(type.isUnion() && !(type.flags & TypeFlags.Enum) ? type.types : [type], t => - t.symbol && getDefinitionFromSymbol(checker, t.symbol, node, failedAliasResolution)); + function definitionFromType(type: ts.Type, checker: ts.TypeChecker, node: ts.Node, failedAliasResolution: boolean | undefined): readonly ts.DefinitionInfo[] { + return ts.flatMap(type.isUnion() && !(type.flags & ts.TypeFlags.Enum) ? type.types : [type], t => t.symbol && getDefinitionFromSymbol(checker, t.symbol, node, failedAliasResolution)); } - function tryGetReturnTypeOfFunction(symbol: Symbol, type: Type, checker: TypeChecker): Type | undefined { + function tryGetReturnTypeOfFunction(symbol: ts.Symbol, type: ts.Type, checker: ts.TypeChecker): ts.Type | undefined { // If the type is just a function's inferred type, // go-to-type should go to the return type instead, since go-to-definition takes you to the function anyway. if (type.symbol === symbol || // At `const f = () => {}`, the symbol is `f` and the type symbol is at `() => {}` - symbol.valueDeclaration && type.symbol && isVariableDeclaration(symbol.valueDeclaration) && symbol.valueDeclaration.initializer === type.symbol.valueDeclaration as Node) { + symbol.valueDeclaration && type.symbol && ts.isVariableDeclaration(symbol.valueDeclaration) && symbol.valueDeclaration.initializer === type.symbol.valueDeclaration as ts.Node) { const sigs = type.getCallSignatures(); - if (sigs.length === 1) return checker.getReturnTypeOfSignature(first(sigs)); + if (sigs.length === 1) + return checker.getReturnTypeOfSignature(ts.first(sigs)); } return undefined; } - export function getDefinitionAndBoundSpan(program: Program, sourceFile: SourceFile, position: number): DefinitionInfoAndBoundSpan | undefined { + export function getDefinitionAndBoundSpan(program: ts.Program, sourceFile: ts.SourceFile, position: number): ts.DefinitionInfoAndBoundSpan | undefined { const definitions = getDefinitionAtPosition(program, sourceFile, position); if (!definitions || definitions.length === 0) { @@ -278,28 +285,28 @@ namespace ts.GoToDefinition { findReferenceInPosition(sourceFile.libReferenceDirectives, position); if (comment) { - return { definitions, textSpan: createTextSpanFromRange(comment) }; + return { definitions, textSpan: ts.createTextSpanFromRange(comment) }; } - const node = getTouchingPropertyName(sourceFile, position); - const textSpan = createTextSpan(node.getStart(), node.getWidth()); + const node = ts.getTouchingPropertyName(sourceFile, position); + const textSpan = ts.createTextSpan(node.getStart(), node.getWidth()); return { definitions, textSpan }; } // At 'x.foo', see if the type of 'x' has an index signature, and if so find its declarations. - function getDefinitionInfoForIndexSignatures(node: Node, checker: TypeChecker): DefinitionInfo[] | undefined { - return mapDefined(checker.getIndexInfosAtLocation(node), info => info.declaration && createDefinitionFromSignatureDeclaration(checker, info.declaration)); + function getDefinitionInfoForIndexSignatures(node: ts.Node, checker: ts.TypeChecker): ts.DefinitionInfo[] | undefined { + return ts.mapDefined(checker.getIndexInfosAtLocation(node), info => info.declaration && createDefinitionFromSignatureDeclaration(checker, info.declaration)); } - function getSymbol(node: Node, checker: TypeChecker, stopAtAlias: boolean | undefined) { + function getSymbol(node: ts.Node, checker: ts.TypeChecker, stopAtAlias: boolean | undefined) { const symbol = checker.getSymbolAtLocation(node); // If this is an alias, and the request came at the declaration location // get the aliased symbol instead. This allows for goto def on an import e.g. // import {A, B} from "mod"; // to jump to the implementation directly. let failedAliasResolution = false; - if (symbol?.declarations && symbol.flags & SymbolFlags.Alias && !stopAtAlias && shouldSkipAlias(node, symbol.declarations[0])) { + if (symbol?.declarations && symbol.flags & ts.SymbolFlags.Alias && !stopAtAlias && shouldSkipAlias(node, symbol.declarations[0])) { const aliased = checker.getAliasedSymbol(symbol); if (aliased.declarations) { return { symbol: aliased }; @@ -316,14 +323,14 @@ namespace ts.GoToDefinition { // (1) when the aliased symbol was declared in the location(parent). // (2) when the aliased symbol is originating from an import. // - function shouldSkipAlias(node: Node, declaration: Node): boolean { - if (node.kind !== SyntaxKind.Identifier) { + function shouldSkipAlias(node: ts.Node, declaration: ts.Node): boolean { + if (node.kind !== ts.SyntaxKind.Identifier) { return false; } if (node.parent === declaration) { return true; } - if (declaration.kind === SyntaxKind.NamespaceImport) { + if (declaration.kind === ts.SyntaxKind.NamespaceImport) { return false; } return true; @@ -346,157 +353,158 @@ namespace ts.GoToDefinition { * calling) covers our tests but feels like a hack, and it would be great if someone could come * up with a more precise definition of what counts as a definition. */ - function isExpandoDeclaration(node: Declaration): boolean { - if (!isAssignmentDeclaration(node)) return false; - const containingAssignment = findAncestor(node, p => { - if (isAssignmentExpression(p)) return true; - if (!isAssignmentDeclaration(p as Declaration)) return "quit"; + function isExpandoDeclaration(node: ts.Declaration): boolean { + if (!ts.isAssignmentDeclaration(node)) return false; - }) as AssignmentExpression | undefined; - return !!containingAssignment && getAssignmentDeclarationKind(containingAssignment) === AssignmentDeclarationKind.Property; + const containingAssignment = ts.findAncestor(node, p => { + if (ts.isAssignmentExpression(p)) + return true; + if (!ts.isAssignmentDeclaration(p as ts.Declaration)) + return "quit"; + return false; + }) as ts.AssignmentExpression | undefined; + return !!containingAssignment && ts.getAssignmentDeclarationKind(containingAssignment) === ts.AssignmentDeclarationKind.Property; } - - function getDefinitionFromSymbol(typeChecker: TypeChecker, symbol: Symbol, node: Node, failedAliasResolution?: boolean, excludeDeclaration?: Node): DefinitionInfo[] | undefined { - const filteredDeclarations = filter(symbol.declarations, d => d !== excludeDeclaration); - const withoutExpandos = filter(filteredDeclarations, d => !isExpandoDeclaration(d)); - const results = some(withoutExpandos) ? withoutExpandos : filteredDeclarations; - return getConstructSignatureDefinition() || getCallSignatureDefinition() || map(results, declaration => createDefinitionInfo(declaration, typeChecker, symbol, node, /*unverified*/ false, failedAliasResolution)); - - function getConstructSignatureDefinition(): DefinitionInfo[] | undefined { + function getDefinitionFromSymbol(typeChecker: ts.TypeChecker, symbol: ts.Symbol, node: ts.Node, failedAliasResolution?: boolean, excludeDeclaration?: ts.Node): ts.DefinitionInfo[] | undefined { + const filteredDeclarations = ts.filter(symbol.declarations, d => d !== excludeDeclaration); + const withoutExpandos = ts.filter(filteredDeclarations, d => !isExpandoDeclaration(d)); + const results = ts.some(withoutExpandos) ? withoutExpandos : filteredDeclarations; + return getConstructSignatureDefinition() || getCallSignatureDefinition() || ts.map(results, declaration => createDefinitionInfo(declaration, typeChecker, symbol, node, /*unverified*/ false, failedAliasResolution)); + function getConstructSignatureDefinition(): ts.DefinitionInfo[] | undefined { // Applicable only if we are in a new expression, or we are on a constructor declaration // and in either case the symbol has a construct signature definition, i.e. class - if (symbol.flags & SymbolFlags.Class && !(symbol.flags & (SymbolFlags.Function | SymbolFlags.Variable)) && (isNewExpressionTarget(node) || node.kind === SyntaxKind.ConstructorKeyword)) { - const cls = find(filteredDeclarations!, isClassLike) || Debug.fail("Expected declaration to have at least one class-like declaration"); + if (symbol.flags & ts.SymbolFlags.Class && !(symbol.flags & (ts.SymbolFlags.Function | ts.SymbolFlags.Variable)) && (ts.isNewExpressionTarget(node) || node.kind === ts.SyntaxKind.ConstructorKeyword)) { + const cls = ts.find(filteredDeclarations!, ts.isClassLike) || ts.Debug.fail("Expected declaration to have at least one class-like declaration"); return getSignatureDefinition(cls.members, /*selectConstructors*/ true); } } - function getCallSignatureDefinition(): DefinitionInfo[] | undefined { - return isCallOrNewExpressionTarget(node) || isNameOfFunctionDeclaration(node) + function getCallSignatureDefinition(): ts.DefinitionInfo[] | undefined { + return ts.isCallOrNewExpressionTarget(node) || ts.isNameOfFunctionDeclaration(node) ? getSignatureDefinition(filteredDeclarations, /*selectConstructors*/ false) : undefined; } - function getSignatureDefinition(signatureDeclarations: readonly Declaration[] | undefined, selectConstructors: boolean): DefinitionInfo[] | undefined { + function getSignatureDefinition(signatureDeclarations: readonly ts.Declaration[] | undefined, selectConstructors: boolean): ts.DefinitionInfo[] | undefined { if (!signatureDeclarations) { return undefined; } - const declarations = signatureDeclarations.filter(selectConstructors ? isConstructorDeclaration : isFunctionLike); - const declarationsWithBody = declarations.filter(d => !!(d as FunctionLikeDeclaration).body); + const declarations = signatureDeclarations.filter(selectConstructors ? ts.isConstructorDeclaration : ts.isFunctionLike); + const declarationsWithBody = declarations.filter(d => !!(d as ts.FunctionLikeDeclaration).body); // declarations defined on the global scope can be defined on multiple files. Get all of them. return declarations.length ? declarationsWithBody.length !== 0 ? declarationsWithBody.map(x => createDefinitionInfo(x, typeChecker, symbol, node)) - : [createDefinitionInfo(last(declarations), typeChecker, symbol, node, /*unverified*/ false, failedAliasResolution)] + : [createDefinitionInfo(ts.last(declarations), typeChecker, symbol, node, /*unverified*/ false, failedAliasResolution)] : undefined; } } /** Creates a DefinitionInfo from a Declaration, using the declaration's name if possible. */ - export function createDefinitionInfo(declaration: Declaration, checker: TypeChecker, symbol: Symbol, node: Node, unverified?: boolean, failedAliasResolution?: boolean): DefinitionInfo { + export function createDefinitionInfo(declaration: ts.Declaration, checker: ts.TypeChecker, symbol: ts.Symbol, node: ts.Node, unverified?: boolean, failedAliasResolution?: boolean): ts.DefinitionInfo { const symbolName = checker.symbolToString(symbol); // Do not get scoped name, just the name of the symbol - const symbolKind = SymbolDisplay.getSymbolKind(checker, symbol, node); + const symbolKind = ts.SymbolDisplay.getSymbolKind(checker, symbol, node); const containerName = symbol.parent ? checker.symbolToString(symbol.parent, node) : ""; return createDefinitionInfoFromName(checker, declaration, symbolKind, symbolName, containerName, unverified, failedAliasResolution); } /** Creates a DefinitionInfo directly from the name of a declaration. */ - function createDefinitionInfoFromName(checker: TypeChecker, declaration: Declaration, symbolKind: ScriptElementKind, symbolName: string, containerName: string, unverified?: boolean, failedAliasResolution?: boolean, textSpan?: TextSpan): DefinitionInfo { + function createDefinitionInfoFromName(checker: ts.TypeChecker, declaration: ts.Declaration, symbolKind: ts.ScriptElementKind, symbolName: string, containerName: string, unverified?: boolean, failedAliasResolution?: boolean, textSpan?: ts.TextSpan): ts.DefinitionInfo { const sourceFile = declaration.getSourceFile(); if (!textSpan) { - const name = getNameOfDeclaration(declaration) || declaration; - textSpan = createTextSpanFromNode(name, sourceFile); + const name = ts.getNameOfDeclaration(declaration) || declaration; + textSpan = ts.createTextSpanFromNode(name, sourceFile); } return { fileName: sourceFile.fileName, textSpan, kind: symbolKind, name: symbolName, - containerKind: undefined!, // TODO: GH#18217 + containerKind: undefined!, containerName, - ...FindAllReferences.toContextSpan( - textSpan, - sourceFile, - FindAllReferences.getContextNode(declaration) - ), + ...ts.FindAllReferences.toContextSpan(textSpan, sourceFile, ts.FindAllReferences.getContextNode(declaration)), isLocal: !isDefinitionVisible(checker, declaration), - isAmbient: !!(declaration.flags & NodeFlags.Ambient), + isAmbient: !!(declaration.flags & ts.NodeFlags.Ambient), unverified, failedAliasResolution, }; } - function isDefinitionVisible(checker: TypeChecker, declaration: Declaration): boolean { - if (checker.isDeclarationVisible(declaration)) return true; - if (!declaration.parent) return false; + function isDefinitionVisible(checker: ts.TypeChecker, declaration: ts.Declaration): boolean { + if (checker.isDeclarationVisible(declaration)) + return true; + if (!declaration.parent) + return false; // Variable initializers are visible if variable is visible - if (hasInitializer(declaration.parent) && declaration.parent.initializer === declaration) return isDefinitionVisible(checker, declaration.parent as Declaration); + if (ts.hasInitializer(declaration.parent) && declaration.parent.initializer === declaration) + return isDefinitionVisible(checker, declaration.parent as ts.Declaration); // Handle some exceptions here like arrow function, members of class and object literal expression which are technically not visible but we want the definition to be determined by its parent switch (declaration.kind) { - case SyntaxKind.PropertyDeclaration: - case SyntaxKind.GetAccessor: - case SyntaxKind.SetAccessor: - case SyntaxKind.MethodDeclaration: + case ts.SyntaxKind.PropertyDeclaration: + case ts.SyntaxKind.GetAccessor: + case ts.SyntaxKind.SetAccessor: + case ts.SyntaxKind.MethodDeclaration: // Private/protected properties/methods are not visible - if (hasEffectiveModifier(declaration, ModifierFlags.Private)) return false; + if (ts.hasEffectiveModifier(declaration, ts.ModifierFlags.Private)) + return false; // Public properties/methods are visible if its parents are visible, so: // falls through - case SyntaxKind.Constructor: - case SyntaxKind.PropertyAssignment: - case SyntaxKind.ShorthandPropertyAssignment: - case SyntaxKind.ObjectLiteralExpression: - case SyntaxKind.ClassExpression: - case SyntaxKind.ArrowFunction: - case SyntaxKind.FunctionExpression: - return isDefinitionVisible(checker, declaration.parent as Declaration); + case ts.SyntaxKind.Constructor: + case ts.SyntaxKind.PropertyAssignment: + case ts.SyntaxKind.ShorthandPropertyAssignment: + case ts.SyntaxKind.ObjectLiteralExpression: + case ts.SyntaxKind.ClassExpression: + case ts.SyntaxKind.ArrowFunction: + case ts.SyntaxKind.FunctionExpression: + return isDefinitionVisible(checker, declaration.parent as ts.Declaration); default: return false; } } - function createDefinitionFromSignatureDeclaration(typeChecker: TypeChecker, decl: SignatureDeclaration, failedAliasResolution?: boolean): DefinitionInfo { + function createDefinitionFromSignatureDeclaration(typeChecker: ts.TypeChecker, decl: ts.SignatureDeclaration, failedAliasResolution?: boolean): ts.DefinitionInfo { return createDefinitionInfo(decl, typeChecker, decl.symbol, decl, /*unverified*/ false, failedAliasResolution); } - export function findReferenceInPosition(refs: readonly FileReference[], pos: number): FileReference | undefined { - return find(refs, ref => textRangeContainsPositionInclusive(ref, pos)); + export function findReferenceInPosition(refs: readonly ts.FileReference[], pos: number): ts.FileReference | undefined { + return ts.find(refs, ref => ts.textRangeContainsPositionInclusive(ref, pos)); } - function getDefinitionInfoForFileReference(name: string, targetFileName: string, unverified: boolean): DefinitionInfo { + function getDefinitionInfoForFileReference(name: string, targetFileName: string, unverified: boolean): ts.DefinitionInfo { return { fileName: targetFileName, - textSpan: createTextSpanFromBounds(0, 0), - kind: ScriptElementKind.scriptElement, + textSpan: ts.createTextSpanFromBounds(0, 0), + kind: ts.ScriptElementKind.scriptElement, name, containerName: undefined!, - containerKind: undefined!, // TODO: GH#18217 + containerKind: undefined!, unverified, }; } /** Returns a CallLikeExpression where `node` is the target being invoked. */ - function getAncestorCallLikeExpression(node: Node): CallLikeExpression | undefined { - const target = findAncestor(node, n => !isRightSideOfPropertyAccess(n)); + function getAncestorCallLikeExpression(node: ts.Node): ts.CallLikeExpression | undefined { + const target = ts.findAncestor(node, n => !ts.isRightSideOfPropertyAccess(n)); const callLike = target?.parent; - return callLike && isCallLikeExpression(callLike) && getInvokedExpression(callLike) === target ? callLike : undefined; + return callLike && ts.isCallLikeExpression(callLike) && ts.getInvokedExpression(callLike) === target ? callLike : undefined; } - function tryGetSignatureDeclaration(typeChecker: TypeChecker, node: Node): SignatureDeclaration | undefined { + function tryGetSignatureDeclaration(typeChecker: ts.TypeChecker, node: ts.Node): ts.SignatureDeclaration | undefined { const callLike = getAncestorCallLikeExpression(node); const signature = callLike && typeChecker.getResolvedSignature(callLike); // Don't go to a function type, go to the value having that type. - return tryCast(signature && signature.declaration, (d): d is SignatureDeclaration => isFunctionLike(d) && !isFunctionTypeNode(d)); + return ts.tryCast(signature && signature.declaration, (d): d is ts.SignatureDeclaration => ts.isFunctionLike(d) && !ts.isFunctionTypeNode(d)); } - function isConstructorLike(node: Node): boolean { + function isConstructorLike(node: ts.Node): boolean { switch (node.kind) { - case SyntaxKind.Constructor: - case SyntaxKind.ConstructorType: - case SyntaxKind.ConstructSignature: + case ts.SyntaxKind.Constructor: + case ts.SyntaxKind.ConstructorType: + case ts.SyntaxKind.ConstructSignature: return true; default: return false; diff --git a/src/services/importTracker.ts b/src/services/importTracker.ts index a3fcfb76680de..2ed6b410ee3a5 100644 --- a/src/services/importTracker.ts +++ b/src/services/importTracker.ts @@ -3,16 +3,19 @@ namespace ts.FindAllReferences { export interface ImportsResult { /** For every import of the symbol, the location and local symbol for the import. */ - importSearches: readonly [Identifier, Symbol][]; + importSearches: readonly [ + ts.Identifier, + ts.Symbol + ][]; /** For rename imports/exports `{ foo as bar }`, `foo` is not a local, so it may be added as a reference immediately without further searching. */ - singleReferences: readonly (Identifier | StringLiteral)[]; + singleReferences: readonly (ts.Identifier | ts.StringLiteral)[]; /** List of source files that may (or may not) use the symbol via a namespace. (For UMD modules this is every file.) */ - indirectUsers: readonly SourceFile[]; + indirectUsers: readonly ts.SourceFile[]; } - export type ImportTracker = (exportSymbol: Symbol, exportInfo: ExportInfo, isForRename: boolean) => ImportsResult; + export type ImportTracker = (exportSymbol: ts.Symbol, exportInfo: ExportInfo, isForRename: boolean) => ImportsResult; /** Creates the imports map and returns an ImportTracker that uses it. Call this lazily to avoid calling `getDirectImportsMap` unnecessarily. */ - export function createImportTracker(sourceFiles: readonly SourceFile[], sourceFilesSet: ReadonlySet, checker: TypeChecker, cancellationToken: CancellationToken | undefined): ImportTracker { + export function createImportTracker(sourceFiles: readonly ts.SourceFile[], sourceFilesSet: ts.ReadonlySet, checker: ts.TypeChecker, cancellationToken: ts.CancellationToken | undefined): ImportTracker { const allDirectImports = getDirectImportsMap(sourceFiles, checker, cancellationToken); return (exportSymbol, exportInfo, isForRename) => { const { directImports, indirectUsers } = getImportersForExport(sourceFiles, sourceFilesSet, allDirectImports, exportInfo, checker, cancellationToken); @@ -22,31 +25,34 @@ namespace ts.FindAllReferences { /** Info about an exported symbol to perform recursive search on. */ export interface ExportInfo { - exportingModuleSymbol: Symbol; + exportingModuleSymbol: ts.Symbol; exportKind: ExportKind; } - export const enum ExportKind { Named, Default, ExportEquals } - - export const enum ImportExport { Import, Export } - - interface AmbientModuleDeclaration extends ModuleDeclaration { body?: ModuleBlock; } - type SourceFileLike = SourceFile | AmbientModuleDeclaration; + export const enum ExportKind { + Named, + Default, + ExportEquals + } + export const enum ImportExport { + Import, + Export + } + interface AmbientModuleDeclaration extends ts.ModuleDeclaration { + body?: ts.ModuleBlock; + } + type SourceFileLike = ts.SourceFile | AmbientModuleDeclaration; // Identifier for the case of `const x = require("y")`. - type Importer = AnyImportOrReExport | ValidImportTypeNode | Identifier; - type ImporterOrCallExpression = Importer | CallExpression; + type Importer = ts.AnyImportOrReExport | ts.ValidImportTypeNode | ts.Identifier; + type ImporterOrCallExpression = Importer | ts.CallExpression; /** Returns import statements that directly reference the exporting module, and a list of files that may access the module through a namespace. */ - function getImportersForExport( - sourceFiles: readonly SourceFile[], - sourceFilesSet: ReadonlySet, - allDirectImports: ESMap, - { exportingModuleSymbol, exportKind }: ExportInfo, - checker: TypeChecker, - cancellationToken: CancellationToken | undefined, - ): { directImports: Importer[], indirectUsers: readonly SourceFile[] } { - const markSeenDirectImport = nodeSeenTracker(); - const markSeenIndirectUser = nodeSeenTracker(); + function getImportersForExport(sourceFiles: readonly ts.SourceFile[], sourceFilesSet: ts.ReadonlySet, allDirectImports: ts.ESMap, { exportingModuleSymbol, exportKind }: ExportInfo, checker: ts.TypeChecker, cancellationToken: ts.CancellationToken | undefined): { + directImports: Importer[]; + indirectUsers: readonly ts.SourceFile[]; + } { + const markSeenDirectImport = ts.nodeSeenTracker(); + const markSeenIndirectUser = ts.nodeSeenTracker(); const directImports: Importer[] = []; const isAvailableThroughGlobal = !!exportingModuleSymbol.globalExports; const indirectUserDeclarations: SourceFileLike[] | undefined = isAvailableThroughGlobal ? undefined : []; @@ -55,7 +61,7 @@ namespace ts.FindAllReferences { return { directImports, indirectUsers: getIndirectUsers() }; - function getIndirectUsers(): readonly SourceFile[] { + function getIndirectUsers(): readonly ts.SourceFile[] { if (isAvailableThroughGlobal) { // It has `export as namespace`, so anything could potentially use it. return sourceFiles; @@ -64,17 +70,17 @@ namespace ts.FindAllReferences { // Module augmentations may use this module's exports without importing it. if (exportingModuleSymbol.declarations) { for (const decl of exportingModuleSymbol.declarations) { - if (isExternalModuleAugmentation(decl) && sourceFilesSet.has(decl.getSourceFile().fileName)) { + if (ts.isExternalModuleAugmentation(decl) && sourceFilesSet.has(decl.getSourceFile().fileName)) { addIndirectUser(decl); } } } // This may return duplicates (if there are multiple module declarations in a single source file, all importing the same thing as a namespace), but `State.markSearchedSymbol` will handle that. - return indirectUserDeclarations!.map(getSourceFileOfNode); + return indirectUserDeclarations!.map(ts.getSourceFileOfNode); } - function handleDirectImports(exportingModuleSymbol: Symbol): void { + function handleDirectImports(exportingModuleSymbol: ts.Symbol): void { const theseDirectImports = getDirectImports(exportingModuleSymbol); if (theseDirectImports) { for (const direct of theseDirectImports) { @@ -82,19 +88,20 @@ namespace ts.FindAllReferences { continue; } - if (cancellationToken) cancellationToken.throwIfCancellationRequested(); + if (cancellationToken) + cancellationToken.throwIfCancellationRequested(); switch (direct.kind) { - case SyntaxKind.CallExpression: - if (isImportCall(direct)) { + case ts.SyntaxKind.CallExpression: + if (ts.isImportCall(direct)) { handleImportCall(direct); break; } if (!isAvailableThroughGlobal) { const parent = direct.parent; - if (exportKind === ExportKind.ExportEquals && parent.kind === SyntaxKind.VariableDeclaration) { - const { name } = parent as VariableDeclaration; - if (name.kind === SyntaxKind.Identifier) { + if (exportKind === ExportKind.ExportEquals && parent.kind === ts.SyntaxKind.VariableDeclaration) { + const { name } = parent as ts.VariableDeclaration; + if (name.kind === ts.SyntaxKind.Identifier) { directImports.push(name); break; } @@ -102,30 +109,30 @@ namespace ts.FindAllReferences { } break; - case SyntaxKind.Identifier: // for 'const x = require("y"); + case ts.SyntaxKind.Identifier: // for 'const x = require("y"); break; // TODO: GH#23879 - case SyntaxKind.ImportEqualsDeclaration: - handleNamespaceImport(direct, direct.name, hasSyntacticModifier(direct, ModifierFlags.Export), /*alreadyAddedDirect*/ false); + case ts.SyntaxKind.ImportEqualsDeclaration: + handleNamespaceImport(direct, direct.name, ts.hasSyntacticModifier(direct, ts.ModifierFlags.Export), /*alreadyAddedDirect*/ false); break; - case SyntaxKind.ImportDeclaration: + case ts.SyntaxKind.ImportDeclaration: directImports.push(direct); const namedBindings = direct.importClause && direct.importClause.namedBindings; - if (namedBindings && namedBindings.kind === SyntaxKind.NamespaceImport) { + if (namedBindings && namedBindings.kind === ts.SyntaxKind.NamespaceImport) { handleNamespaceImport(direct, namedBindings.name, /*isReExport*/ false, /*alreadyAddedDirect*/ true); } - else if (!isAvailableThroughGlobal && isDefaultImport(direct)) { + else if (!isAvailableThroughGlobal && ts.isDefaultImport(direct)) { addIndirectUser(getSourceFileLikeForImportDeclaration(direct)); // Add a check for indirect uses to handle synthetic default imports } break; - case SyntaxKind.ExportDeclaration: + case ts.SyntaxKind.ExportDeclaration: if (!direct.exportClause) { // This is `export * from "foo"`, so imports of this module may import the export too. handleDirectImports(getContainingModuleSymbol(direct, checker)); } - else if (direct.exportClause.kind === SyntaxKind.NamespaceExport) { + else if (direct.exportClause.kind === ts.SyntaxKind.NamespaceExport) { // `export * as foo from "foo"` add to indirect uses addIndirectUser(getSourceFileLikeForImportDeclaration(direct), /** addTransitiveDependencies */ true); } @@ -135,7 +142,7 @@ namespace ts.FindAllReferences { } break; - case SyntaxKind.ImportType: + case ts.SyntaxKind.ImportType: // Only check for typeof import('xyz') if (direct.isTypeOf && !direct.qualifier && isExported(direct)) { addIndirectUser(direct.getSourceFile(), /** addTransitiveDependencies */ true); @@ -144,32 +151,34 @@ namespace ts.FindAllReferences { break; default: - Debug.failBadSyntaxKind(direct, "Unexpected import kind."); + ts.Debug.failBadSyntaxKind(direct, "Unexpected import kind."); } } } } - function handleImportCall(importCall: ImportCall) { - const top = findAncestor(importCall, isAmbientModuleDeclaration) || importCall.getSourceFile(); + function handleImportCall(importCall: ts.ImportCall) { + const top = ts.findAncestor(importCall, isAmbientModuleDeclaration) || importCall.getSourceFile(); addIndirectUser(top, /** addTransitiveDependencies */ !!isExported(importCall, /** stopAtAmbientModule */ true)); } - function isExported(node: Node, stopAtAmbientModule = false) { - return findAncestor(node, node => { - if (stopAtAmbientModule && isAmbientModuleDeclaration(node)) return "quit"; - return some(node.modifiers, mod => mod.kind === SyntaxKind.ExportKeyword); + function isExported(node: ts.Node, stopAtAmbientModule = false) { + return ts.findAncestor(node, node => { + if (stopAtAmbientModule && isAmbientModuleDeclaration(node)) + return "quit"; + return ts.some(node.modifiers, mod => mod.kind === ts.SyntaxKind.ExportKeyword); }); } - function handleNamespaceImport(importDeclaration: ImportEqualsDeclaration | ImportDeclaration, name: Identifier, isReExport: boolean, alreadyAddedDirect: boolean): void { + function handleNamespaceImport(importDeclaration: ts.ImportEqualsDeclaration | ts.ImportDeclaration, name: ts.Identifier, isReExport: boolean, alreadyAddedDirect: boolean): void { if (exportKind === ExportKind.ExportEquals) { // This is a direct import, not import-as-namespace. - if (!alreadyAddedDirect) directImports.push(importDeclaration); + if (!alreadyAddedDirect) + directImports.push(importDeclaration); } else if (!isAvailableThroughGlobal) { const sourceFileLike = getSourceFileLikeForImportDeclaration(importDeclaration); - Debug.assert(sourceFileLike.kind === SyntaxKind.SourceFile || sourceFileLike.kind === SyntaxKind.ModuleDeclaration); + ts.Debug.assert(sourceFileLike.kind === ts.SyntaxKind.SourceFile || sourceFileLike.kind === ts.SyntaxKind.ModuleDeclaration); if (isReExport || findNamespaceReExports(sourceFileLike, name, checker)) { addIndirectUser(sourceFileLike, /** addTransitiveDependencies */ true); } @@ -181,27 +190,30 @@ namespace ts.FindAllReferences { /** Adds a module and all of its transitive dependencies as possible indirect users. */ function addIndirectUser(sourceFileLike: SourceFileLike, addTransitiveDependencies = false): void { - Debug.assert(!isAvailableThroughGlobal); + ts.Debug.assert(!isAvailableThroughGlobal); const isNew = markSeenIndirectUser(sourceFileLike); - if (!isNew) return; + if (!isNew) + return; indirectUserDeclarations!.push(sourceFileLike); // TODO: GH#18217 - if (!addTransitiveDependencies) return; + if (!addTransitiveDependencies) + return; const moduleSymbol = checker.getMergedSymbol(sourceFileLike.symbol); - if (!moduleSymbol) return; - Debug.assert(!!(moduleSymbol.flags & SymbolFlags.Module)); + if (!moduleSymbol) + return; + ts.Debug.assert(!!(moduleSymbol.flags & ts.SymbolFlags.Module)); const directImports = getDirectImports(moduleSymbol); if (directImports) { for (const directImport of directImports) { - if (!isImportTypeNode(directImport)) { + if (!ts.isImportTypeNode(directImport)) { addIndirectUser(getSourceFileLikeForImportDeclaration(directImport), /** addTransitiveDependencies */ true); } } } } - function getDirectImports(moduleSymbol: Symbol): ImporterOrCallExpression[] | undefined { - return allDirectImports.get(getSymbolId(moduleSymbol).toString()); + function getDirectImports(moduleSymbol: ts.Symbol): ImporterOrCallExpression[] | undefined { + return allDirectImports.get(ts.getSymbolId(moduleSymbol).toString()); } } @@ -210,10 +222,13 @@ namespace ts.FindAllReferences { * The returned `importSearches` will result in the entire source file being searched. * But re-exports will be placed in 'singleReferences' since they cannot be locally referenced. */ - function getSearchesFromDirectImports(directImports: Importer[], exportSymbol: Symbol, exportKind: ExportKind, checker: TypeChecker, isForRename: boolean): Pick { - const importSearches: [Identifier, Symbol][] = []; - const singleReferences: (Identifier | StringLiteral)[] = []; - function addSearch(location: Identifier, symbol: Symbol): void { + function getSearchesFromDirectImports(directImports: Importer[], exportSymbol: ts.Symbol, exportKind: ExportKind, checker: ts.TypeChecker, isForRename: boolean): Pick { + const importSearches: [ + ts.Identifier, + ts.Symbol + ][] = []; + const singleReferences: (ts.Identifier | ts.StringLiteral)[] = []; + function addSearch(location: ts.Identifier, symbol: ts.Symbol): void { importSearches.push([location, symbol]); } @@ -226,22 +241,22 @@ namespace ts.FindAllReferences { return { importSearches, singleReferences }; function handleImport(decl: Importer): void { - if (decl.kind === SyntaxKind.ImportEqualsDeclaration) { + if (decl.kind === ts.SyntaxKind.ImportEqualsDeclaration) { if (isExternalModuleImportEquals(decl)) { handleNamespaceImportLike(decl.name); } return; } - if (decl.kind === SyntaxKind.Identifier) { + if (decl.kind === ts.SyntaxKind.Identifier) { handleNamespaceImportLike(decl); return; } - if (decl.kind === SyntaxKind.ImportType) { + if (decl.kind === ts.SyntaxKind.ImportType) { if (decl.qualifier) { - const firstIdentifier = getFirstIdentifier(decl.qualifier); - if (firstIdentifier.escapedText === symbolName(exportSymbol)) { + const firstIdentifier = ts.getFirstIdentifier(decl.qualifier); + if (firstIdentifier.escapedText === ts.symbolName(exportSymbol)) { singleReferences.push(firstIdentifier); } } @@ -252,12 +267,12 @@ namespace ts.FindAllReferences { } // Ignore if there's a grammar error - if (decl.moduleSpecifier!.kind !== SyntaxKind.StringLiteral) { + if (decl.moduleSpecifier!.kind !== ts.SyntaxKind.StringLiteral) { return; } - if (decl.kind === SyntaxKind.ExportDeclaration) { - if (decl.exportClause && isNamedExports(decl.exportClause)) { + if (decl.kind === ts.SyntaxKind.ExportDeclaration) { + if (decl.exportClause && ts.isNamedExports(decl.exportClause)) { searchForNamedImport(decl.exportClause); } return; @@ -267,24 +282,24 @@ namespace ts.FindAllReferences { if (namedBindings) { switch (namedBindings.kind) { - case SyntaxKind.NamespaceImport: + case ts.SyntaxKind.NamespaceImport: handleNamespaceImportLike(namedBindings.name); break; - case SyntaxKind.NamedImports: + case ts.SyntaxKind.NamedImports: // 'default' might be accessed as a named import `{ default as foo }`. if (exportKind === ExportKind.Named || exportKind === ExportKind.Default) { searchForNamedImport(namedBindings); } break; default: - Debug.assertNever(namedBindings); + ts.Debug.assertNever(namedBindings); } } // `export =` might be imported by a default import if `--allowSyntheticDefaultImports` is on, so this handles both ExportKind.Default and ExportKind.ExportEquals. // If a default import has the same name as the default export, allow to rename it. // Given `import f` and `export default function f`, we will rename both, but for `import g` we will rename just that. - if (name && (exportKind === ExportKind.Default || exportKind === ExportKind.ExportEquals) && (!isForRename || name.escapedText === symbolEscapedNameNoDefault(exportSymbol))) { + if (name && (exportKind === ExportKind.Default || exportKind === ExportKind.ExportEquals) && (!isForRename || name.escapedText === ts.symbolEscapedNameNoDefault(exportSymbol))) { const defaultImportAlias = checker.getSymbolAtLocation(name)!; addSearch(name, defaultImportAlias); } @@ -295,14 +310,14 @@ namespace ts.FindAllReferences { * An `export =` may be imported by this syntax, so it may be a direct import. * If it's not a direct import, it will be in `indirectUsers`, so we don't have to do anything here. */ - function handleNamespaceImportLike(importName: Identifier): void { + function handleNamespaceImportLike(importName: ts.Identifier): void { // Don't rename an import that already has a different name than the export. if (exportKind === ExportKind.ExportEquals && (!isForRename || isNameMatch(importName.escapedText))) { addSearch(importName, checker.getSymbolAtLocation(importName)!); } } - function searchForNamedImport(namedBindings: NamedImportsOrExports | undefined): void { + function searchForNamedImport(namedBindings: ts.NamedImportsOrExports | undefined): void { if (!namedBindings) { return; } @@ -324,7 +339,7 @@ namespace ts.FindAllReferences { } } else { - const localSymbol = element.kind === SyntaxKind.ExportSpecifier && element.propertyName + const localSymbol = element.kind === ts.SyntaxKind.ExportSpecifier && element.propertyName ? checker.getExportSpecifierLocalTargetSymbol(element)! // For re-exporting under a different name, we want to get the re-exported symbol. : checker.getSymbolAtLocation(name)!; addSearch(name, localSymbol); @@ -332,35 +347,43 @@ namespace ts.FindAllReferences { } } - function isNameMatch(name: __String): boolean { + function isNameMatch(name: ts.__String): boolean { // Use name of "default" even in `export =` case because we may have allowSyntheticDefaultImports - return name === exportSymbol.escapedName || exportKind !== ExportKind.Named && name === InternalSymbolName.Default; + return name === exportSymbol.escapedName || exportKind !== ExportKind.Named && name === ts.InternalSymbolName.Default; } } /** Returns 'true' is the namespace 'name' is re-exported from this module, and 'false' if it is only used locally. */ - function findNamespaceReExports(sourceFileLike: SourceFileLike, name: Identifier, checker: TypeChecker): boolean { + function findNamespaceReExports(sourceFileLike: SourceFileLike, name: ts.Identifier, checker: ts.TypeChecker): boolean { const namespaceImportSymbol = checker.getSymbolAtLocation(name); return !!forEachPossibleImportOrExportStatement(sourceFileLike, statement => { - if (!isExportDeclaration(statement)) return; + if (!ts.isExportDeclaration(statement)) + return; const { exportClause, moduleSpecifier } = statement; - return !moduleSpecifier && exportClause && isNamedExports(exportClause) && + return !moduleSpecifier && exportClause && ts.isNamedExports(exportClause) && exportClause.elements.some(element => checker.getExportSpecifierLocalTargetSymbol(element) === namespaceImportSymbol); }); } export type ModuleReference = /** "import" also includes require() calls. */ - | { kind: "import", literal: StringLiteralLike } + { + kind: "import"; + literal: ts.StringLiteralLike; + } /** or */ - | { kind: "reference", referencingFile: SourceFile, ref: FileReference }; - export function findModuleReferences(program: Program, sourceFiles: readonly SourceFile[], searchModuleSymbol: Symbol): ModuleReference[] { + | { + kind: "reference"; + referencingFile: ts.SourceFile; + ref: ts.FileReference; + }; + export function findModuleReferences(program: ts.Program, sourceFiles: readonly ts.SourceFile[], searchModuleSymbol: ts.Symbol): ModuleReference[] { const refs: ModuleReference[] = []; const checker = program.getTypeChecker(); for (const referencingFile of sourceFiles) { const searchSourceFile = searchModuleSymbol.valueDeclaration; - if (searchSourceFile?.kind === SyntaxKind.SourceFile) { + if (searchSourceFile?.kind === ts.SyntaxKind.SourceFile) { for (const ref of referencingFile.referencedFiles) { if (program.getSourceFileFromReference(referencingFile, ref) === searchSourceFile) { refs.push({ kind: "reference", referencingFile, ref }); @@ -368,7 +391,7 @@ namespace ts.FindAllReferences { } for (const ref of referencingFile.typeReferenceDirectives) { const referenced = program.getResolvedTypeReferenceDirectives().get(ref.fileName, ref.resolutionMode || referencingFile.impliedNodeFormat); - if (referenced !== undefined && referenced.resolvedFileName === (searchSourceFile as SourceFile).fileName) { + if (referenced !== undefined && referenced.resolvedFileName === (searchSourceFile as ts.SourceFile).fileName) { refs.push({ kind: "reference", referencingFile, ref }); } } @@ -385,15 +408,16 @@ namespace ts.FindAllReferences { } /** Returns a map from a module symbol Id to all import statements that directly reference the module. */ - function getDirectImportsMap(sourceFiles: readonly SourceFile[], checker: TypeChecker, cancellationToken: CancellationToken | undefined): ESMap { - const map = new Map(); + function getDirectImportsMap(sourceFiles: readonly ts.SourceFile[], checker: ts.TypeChecker, cancellationToken: ts.CancellationToken | undefined): ts.ESMap { + const map = new ts.Map(); for (const sourceFile of sourceFiles) { - if (cancellationToken) cancellationToken.throwIfCancellationRequested(); + if (cancellationToken) + cancellationToken.throwIfCancellationRequested(); forEachImport(sourceFile, (importDecl, moduleSpecifier) => { const moduleSymbol = checker.getSymbolAtLocation(moduleSpecifier); if (moduleSymbol) { - const id = getSymbolId(moduleSymbol).toString(); + const id = ts.getSymbolId(moduleSymbol).toString(); let imports = map.get(id); if (!imports) { map.set(id, imports = []); @@ -407,32 +431,32 @@ namespace ts.FindAllReferences { } /** Iterates over all statements at the top level or in module declarations. Returns the first truthy result. */ - function forEachPossibleImportOrExportStatement(sourceFileLike: SourceFileLike, action: (statement: Statement) => T) { - return forEach(sourceFileLike.kind === SyntaxKind.SourceFile ? sourceFileLike.statements : sourceFileLike.body!.statements, statement => // TODO: GH#18217 - action(statement) || (isAmbientModuleDeclaration(statement) && forEach(statement.body && statement.body.statements, action))); + function forEachPossibleImportOrExportStatement(sourceFileLike: SourceFileLike, action: (statement: ts.Statement) => T) { + return ts.forEach(sourceFileLike.kind === ts.SyntaxKind.SourceFile ? sourceFileLike.statements : sourceFileLike.body!.statements, statement => // TODO: GH#18217 + action(statement) || (isAmbientModuleDeclaration(statement) && ts.forEach(statement.body && statement.body.statements, action))); } /** Calls `action` for each import, re-export, or require() in a file. */ - function forEachImport(sourceFile: SourceFile, action: (importStatement: ImporterOrCallExpression, imported: StringLiteralLike) => void): void { + function forEachImport(sourceFile: ts.SourceFile, action: (importStatement: ImporterOrCallExpression, imported: ts.StringLiteralLike) => void): void { if (sourceFile.externalModuleIndicator || sourceFile.imports !== undefined) { for (const i of sourceFile.imports) { - action(importFromModuleSpecifier(i), i); + action(ts.importFromModuleSpecifier(i), i); } } else { forEachPossibleImportOrExportStatement(sourceFile, statement => { switch (statement.kind) { - case SyntaxKind.ExportDeclaration: - case SyntaxKind.ImportDeclaration: { - const decl = statement as ImportDeclaration | ExportDeclaration; - if (decl.moduleSpecifier && isStringLiteral(decl.moduleSpecifier)) { + case ts.SyntaxKind.ExportDeclaration: + case ts.SyntaxKind.ImportDeclaration: { + const decl = statement as ts.ImportDeclaration | ts.ExportDeclaration; + if (decl.moduleSpecifier && ts.isStringLiteral(decl.moduleSpecifier)) { action(decl, decl.moduleSpecifier); } break; } - case SyntaxKind.ImportEqualsDeclaration: { - const decl = statement as ImportEqualsDeclaration; + case ts.SyntaxKind.ImportEqualsDeclaration: { + const decl = statement as ts.ImportEqualsDeclaration; if (isExternalModuleImportEquals(decl)) { action(decl, decl.moduleReference.expression); } @@ -445,11 +469,11 @@ namespace ts.FindAllReferences { export interface ImportedSymbol { kind: ImportExport.Import; - symbol: Symbol; + symbol: ts.Symbol; } export interface ExportedSymbol { kind: ImportExport.Export; - symbol: Symbol; + symbol: ts.Symbol; exportInfo: ExportInfo; } @@ -460,17 +484,17 @@ namespace ts.FindAllReferences { * This doesn't handle export specifiers; that is done in `getReferencesAtExportSpecifier`. * @param comingFromExport If we are doing a search for all exports, don't bother looking backwards for the imported symbol, since that's the reason we're here. */ - export function getImportOrExportSymbol(node: Node, symbol: Symbol, checker: TypeChecker, comingFromExport: boolean): ImportedSymbol | ExportedSymbol | undefined { + export function getImportOrExportSymbol(node: ts.Node, symbol: ts.Symbol, checker: ts.TypeChecker, comingFromExport: boolean): ImportedSymbol | ExportedSymbol | undefined { return comingFromExport ? getExport() : getExport() || getImport(); function getExport(): ExportedSymbol | ImportedSymbol | undefined { const { parent } = node; const grandparent = parent.parent; if (symbol.exportSymbol) { - if (parent.kind === SyntaxKind.PropertyAccessExpression) { + if (parent.kind === ts.SyntaxKind.PropertyAccessExpression) { // When accessing an export of a JS module, there's no alias. The symbol will still be flagged as an export even though we're at the use. // So check that we are at the declaration. - return symbol.declarations?.some(d => d === parent) && isBinaryExpression(grandparent) + return symbol.declarations?.some(d => d === parent) && ts.isBinaryExpression(grandparent) ? getSpecialPropertyExport(grandparent, /*useLhsSymbol*/ false) : undefined; } @@ -480,8 +504,8 @@ namespace ts.FindAllReferences { } else { const exportNode = getExportNode(parent, node); - if (exportNode && hasSyntacticModifier(exportNode, ModifierFlags.Export)) { - if (isImportEqualsDeclaration(exportNode) && exportNode.moduleReference === node) { + if (exportNode && ts.hasSyntacticModifier(exportNode, ts.ModifierFlags.Export)) { + if (ts.isImportEqualsDeclaration(exportNode) && exportNode.moduleReference === node) { // We're at `Y` in `export import X = Y`. This is not the exported symbol, the left-hand-side is. So treat this as an import statement. if (comingFromExport) { return undefined; @@ -494,61 +518,64 @@ namespace ts.FindAllReferences { return exportInfo(symbol, getExportKindForDeclaration(exportNode)); } } - else if (isNamespaceExport(parent)) { + else if (ts.isNamespaceExport(parent)) { return exportInfo(symbol, ExportKind.Named); } // If we are in `export = a;` or `export default a;`, `parent` is the export assignment. - else if (isExportAssignment(parent)) { + else if (ts.isExportAssignment(parent)) { return getExportAssignmentExport(parent); } // If we are in `export = class A {};` (or `export = class A {};`) at `A`, `parent.parent` is the export assignment. - else if (isExportAssignment(grandparent)) { + else if (ts.isExportAssignment(grandparent)) { return getExportAssignmentExport(grandparent); } // Similar for `module.exports =` and `exports.A =`. - else if (isBinaryExpression(parent)) { + else if (ts.isBinaryExpression(parent)) { return getSpecialPropertyExport(parent, /*useLhsSymbol*/ true); } - else if (isBinaryExpression(grandparent)) { + else if (ts.isBinaryExpression(grandparent)) { return getSpecialPropertyExport(grandparent, /*useLhsSymbol*/ true); } - else if (isJSDocTypedefTag(parent)) { + else if (ts.isJSDocTypedefTag(parent)) { return exportInfo(symbol, ExportKind.Named); } } - function getExportAssignmentExport(ex: ExportAssignment): ExportedSymbol | undefined { + function getExportAssignmentExport(ex: ts.ExportAssignment): ExportedSymbol | undefined { // Get the symbol for the `export =` node; its parent is the module it's the export of. - if (!ex.symbol.parent) return undefined; + if (!ex.symbol.parent) + return undefined; const exportKind = ex.isExportEquals ? ExportKind.ExportEquals : ExportKind.Default; return { kind: ImportExport.Export, symbol, exportInfo: { exportingModuleSymbol: ex.symbol.parent, exportKind } }; } - function getSpecialPropertyExport(node: BinaryExpression, useLhsSymbol: boolean): ExportedSymbol | undefined { + function getSpecialPropertyExport(node: ts.BinaryExpression, useLhsSymbol: boolean): ExportedSymbol | undefined { let kind: ExportKind; - switch (getAssignmentDeclarationKind(node)) { - case AssignmentDeclarationKind.ExportsProperty: + switch (ts.getAssignmentDeclarationKind(node)) { + case ts.AssignmentDeclarationKind.ExportsProperty: kind = ExportKind.Named; break; - case AssignmentDeclarationKind.ModuleExports: + case ts.AssignmentDeclarationKind.ModuleExports: kind = ExportKind.ExportEquals; break; default: return undefined; } - const sym = useLhsSymbol ? checker.getSymbolAtLocation(getNameOfAccessExpression(cast(node.left, isAccessExpression))) : symbol; + const sym = useLhsSymbol ? checker.getSymbolAtLocation(ts.getNameOfAccessExpression(ts.cast(node.left, ts.isAccessExpression))) : symbol; return sym && exportInfo(sym, kind); } } function getImport(): ImportedSymbol | undefined { const isImport = isNodeImport(node); - if (!isImport) return undefined; + if (!isImport) + return undefined; // A symbol being imported is always an alias. So get what that aliases to find the local symbol. let importedSymbol = checker.getImmediateAliasedSymbol(symbol); - if (!importedSymbol) return undefined; + if (!importedSymbol) + return undefined; // Search on the local symbol in the exporting module, not the exported symbol. importedSymbol = skipExportSpecifierSymbol(importedSymbol, checker); @@ -560,96 +587,97 @@ namespace ts.FindAllReferences { // If the import has a different name than the export, do not continue searching. // If `importedName` is undefined, do continue searching as the export is anonymous. // (All imports returned from this function will be ignored anyway if we are in rename and this is a not a named export.) - const importedName = symbolEscapedNameNoDefault(importedSymbol); - if (importedName === undefined || importedName === InternalSymbolName.Default || importedName === symbol.escapedName) { + const importedName = ts.symbolEscapedNameNoDefault(importedSymbol); + if (importedName === undefined || importedName === ts.InternalSymbolName.Default || importedName === symbol.escapedName) { return { kind: ImportExport.Import, symbol: importedSymbol }; } } - function exportInfo(symbol: Symbol, kind: ExportKind): ExportedSymbol | undefined { + function exportInfo(symbol: ts.Symbol, kind: ExportKind): ExportedSymbol | undefined { const exportInfo = getExportInfo(symbol, kind, checker); return exportInfo && { kind: ImportExport.Export, symbol, exportInfo }; } // Not meant for use with export specifiers or export assignment. - function getExportKindForDeclaration(node: Node): ExportKind { - return hasSyntacticModifier(node, ModifierFlags.Default) ? ExportKind.Default : ExportKind.Named; + function getExportKindForDeclaration(node: ts.Node): ExportKind { + return ts.hasSyntacticModifier(node, ts.ModifierFlags.Default) ? ExportKind.Default : ExportKind.Named; } } - function getExportEqualsLocalSymbol(importedSymbol: Symbol, checker: TypeChecker): Symbol { - if (importedSymbol.flags & SymbolFlags.Alias) { - return Debug.checkDefined(checker.getImmediateAliasedSymbol(importedSymbol)); + function getExportEqualsLocalSymbol(importedSymbol: ts.Symbol, checker: ts.TypeChecker): ts.Symbol { + if (importedSymbol.flags & ts.SymbolFlags.Alias) { + return ts.Debug.checkDefined(checker.getImmediateAliasedSymbol(importedSymbol)); } - const decl = Debug.checkDefined(importedSymbol.valueDeclaration); - if (isExportAssignment(decl)) { // `export = class {}` - return Debug.checkDefined(decl.expression.symbol); + const decl = ts.Debug.checkDefined(importedSymbol.valueDeclaration); + if (ts.isExportAssignment(decl)) { // `export = class {}` + return ts.Debug.checkDefined(decl.expression.symbol); } - else if (isBinaryExpression(decl)) { // `module.exports = class {}` - return Debug.checkDefined(decl.right.symbol); + else if (ts.isBinaryExpression(decl)) { // `module.exports = class {}` + return ts.Debug.checkDefined(decl.right.symbol); } - else if (isSourceFile(decl)) { // json module - return Debug.checkDefined(decl.symbol); + else if (ts.isSourceFile(decl)) { // json module + return ts.Debug.checkDefined(decl.symbol); } - return Debug.fail(); + return ts.Debug.fail(); } // If a reference is a class expression, the exported node would be its parent. // If a reference is a variable declaration, the exported node would be the variable statement. - function getExportNode(parent: Node, node: Node): Node | undefined { - const declaration = isVariableDeclaration(parent) ? parent : isBindingElement(parent) ? walkUpBindingElementsAndPatterns(parent) : undefined; + function getExportNode(parent: ts.Node, node: ts.Node): ts.Node | undefined { + const declaration = ts.isVariableDeclaration(parent) ? parent : ts.isBindingElement(parent) ? ts.walkUpBindingElementsAndPatterns(parent) : undefined; if (declaration) { - return (parent as VariableDeclaration | BindingElement).name !== node ? undefined : - isCatchClause(declaration.parent) ? undefined : isVariableStatement(declaration.parent.parent) ? declaration.parent.parent : undefined; + return (parent as ts.VariableDeclaration | ts.BindingElement).name !== node ? undefined : + ts.isCatchClause(declaration.parent) ? undefined : ts.isVariableStatement(declaration.parent.parent) ? declaration.parent.parent : undefined; } else { return parent; } } - function isNodeImport(node: Node): boolean { + function isNodeImport(node: ts.Node): boolean { const { parent } = node; switch (parent.kind) { - case SyntaxKind.ImportEqualsDeclaration: - return (parent as ImportEqualsDeclaration).name === node && isExternalModuleImportEquals(parent as ImportEqualsDeclaration); - case SyntaxKind.ImportSpecifier: + case ts.SyntaxKind.ImportEqualsDeclaration: + return (parent as ts.ImportEqualsDeclaration).name === node && isExternalModuleImportEquals(parent as ts.ImportEqualsDeclaration); + case ts.SyntaxKind.ImportSpecifier: // For a rename import `{ foo as bar }`, don't search for the imported symbol. Just find local uses of `bar`. - return !(parent as ImportSpecifier).propertyName; - case SyntaxKind.ImportClause: - case SyntaxKind.NamespaceImport: - Debug.assert((parent as ImportClause | NamespaceImport).name === node); + return !(parent as ts.ImportSpecifier).propertyName; + case ts.SyntaxKind.ImportClause: + case ts.SyntaxKind.NamespaceImport: + ts.Debug.assert((parent as ts.ImportClause | ts.NamespaceImport).name === node); return true; - case SyntaxKind.BindingElement: - return isInJSFile(node) && isVariableDeclarationInitializedToBareOrAccessedRequire(parent); + case ts.SyntaxKind.BindingElement: + return ts.isInJSFile(node) && ts.isVariableDeclarationInitializedToBareOrAccessedRequire(parent); default: return false; } } - export function getExportInfo(exportSymbol: Symbol, exportKind: ExportKind, checker: TypeChecker): ExportInfo | undefined { + export function getExportInfo(exportSymbol: ts.Symbol, exportKind: ExportKind, checker: ts.TypeChecker): ExportInfo | undefined { const moduleSymbol = exportSymbol.parent; - if (!moduleSymbol) return undefined; // This can happen if an `export` is not at the top-level (which is a compile error). + if (!moduleSymbol) + return undefined; // This can happen if an `export` is not at the top-level (which is a compile error). const exportingModuleSymbol = checker.getMergedSymbol(moduleSymbol); // Need to get merged symbol in case there's an augmentation. // `export` may appear in a namespace. In that case, just rely on global search. - return isExternalModuleSymbol(exportingModuleSymbol) ? { exportingModuleSymbol, exportKind } : undefined; + return ts.isExternalModuleSymbol(exportingModuleSymbol) ? { exportingModuleSymbol, exportKind } : undefined; } /** If at an export specifier, go to the symbol it refers to. */ - function skipExportSpecifierSymbol(symbol: Symbol, checker: TypeChecker): Symbol { + function skipExportSpecifierSymbol(symbol: ts.Symbol, checker: ts.TypeChecker): ts.Symbol { // For `export { foo } from './bar", there's nothing to skip, because it does not create a new alias. But `export { foo } does. if (symbol.declarations) { for (const declaration of symbol.declarations) { - if (isExportSpecifier(declaration) && !declaration.propertyName && !declaration.parent.parent.moduleSpecifier) { + if (ts.isExportSpecifier(declaration) && !declaration.propertyName && !declaration.parent.parent.moduleSpecifier) { return checker.getExportSpecifierLocalTargetSymbol(declaration)!; } - else if (isPropertyAccessExpression(declaration) && isModuleExportsAccessExpression(declaration.expression) && !isPrivateIdentifier(declaration.name)) { + else if (ts.isPropertyAccessExpression(declaration) && ts.isModuleExportsAccessExpression(declaration.expression) && !ts.isPrivateIdentifier(declaration.name)) { // Export of form 'module.exports.propName = expr'; return checker.getSymbolAtLocation(declaration)!; } - else if (isShorthandPropertyAssignment(declaration) - && isBinaryExpression(declaration.parent.parent) - && getAssignmentDeclarationKind(declaration.parent.parent) === AssignmentDeclarationKind.ModuleExports) { + else if (ts.isShorthandPropertyAssignment(declaration) + && ts.isBinaryExpression(declaration.parent.parent) + && ts.getAssignmentDeclarationKind(declaration.parent.parent) === ts.AssignmentDeclarationKind.ModuleExports) { return checker.getExportSpecifierLocalTargetSymbol(declaration.name)!; } } @@ -657,28 +685,32 @@ namespace ts.FindAllReferences { return symbol; } - function getContainingModuleSymbol(importer: Importer, checker: TypeChecker): Symbol { + function getContainingModuleSymbol(importer: Importer, checker: ts.TypeChecker): ts.Symbol { return checker.getMergedSymbol(getSourceFileLikeForImportDeclaration(importer).symbol); } function getSourceFileLikeForImportDeclaration(node: ImporterOrCallExpression): SourceFileLike { - if (node.kind === SyntaxKind.CallExpression) { + if (node.kind === ts.SyntaxKind.CallExpression) { return node.getSourceFile(); } const { parent } = node; - if (parent.kind === SyntaxKind.SourceFile) { - return parent as SourceFile; + if (parent.kind === ts.SyntaxKind.SourceFile) { + return parent as ts.SourceFile; } - Debug.assert(parent.kind === SyntaxKind.ModuleBlock); - return cast(parent.parent, isAmbientModuleDeclaration); + ts.Debug.assert(parent.kind === ts.SyntaxKind.ModuleBlock); + return ts.cast(parent.parent, isAmbientModuleDeclaration); } - function isAmbientModuleDeclaration(node: Node): node is AmbientModuleDeclaration { - return node.kind === SyntaxKind.ModuleDeclaration && (node as ModuleDeclaration).name.kind === SyntaxKind.StringLiteral; + function isAmbientModuleDeclaration(node: ts.Node): node is AmbientModuleDeclaration { + return node.kind === ts.SyntaxKind.ModuleDeclaration && (node as ts.ModuleDeclaration).name.kind === ts.SyntaxKind.StringLiteral; } - function isExternalModuleImportEquals(eq: ImportEqualsDeclaration): eq is ImportEqualsDeclaration & { moduleReference: { expression: StringLiteral } } { - return eq.moduleReference.kind === SyntaxKind.ExternalModuleReference && eq.moduleReference.expression.kind === SyntaxKind.StringLiteral; + function isExternalModuleImportEquals(eq: ts.ImportEqualsDeclaration): eq is ts.ImportEqualsDeclaration & { + moduleReference: { + expression: ts.StringLiteral; + }; + } { + return eq.moduleReference.kind === ts.SyntaxKind.ExternalModuleReference && eq.moduleReference.expression.kind === ts.SyntaxKind.StringLiteral; } } diff --git a/src/services/inlayHints.ts b/src/services/inlayHints.ts index 110e9718405cb..b5fd1c9747742 100644 --- a/src/services/inlayHints.ts +++ b/src/services/inlayHints.ts @@ -7,82 +7,82 @@ namespace ts.InlayHints { return new RegExp(`^\\s?/\\*\\*?\\s?${name}\\s?\\*\\/\\s?$`); }; - function shouldShowParameterNameHints(preferences: UserPreferences) { + function shouldShowParameterNameHints(preferences: ts.UserPreferences) { return preferences.includeInlayParameterNameHints === "literals" || preferences.includeInlayParameterNameHints === "all"; } - function shouldShowLiteralParameterNameHintsOnly(preferences: UserPreferences) { + function shouldShowLiteralParameterNameHintsOnly(preferences: ts.UserPreferences) { return preferences.includeInlayParameterNameHints === "literals"; } - export function provideInlayHints(context: InlayHintsContext): InlayHint[] { + export function provideInlayHints(context: ts.InlayHintsContext): ts.InlayHint[] { const { file, program, span, cancellationToken, preferences } = context; const sourceFileText = file.text; const compilerOptions = program.getCompilerOptions(); const checker = program.getTypeChecker(); - const result: InlayHint[] = []; + const result: ts.InlayHint[] = []; visitor(file); return result; - function visitor(node: Node): true | undefined { + function visitor(node: ts.Node): true | undefined { if (!node || node.getFullWidth() === 0) { return; } switch (node.kind) { - case SyntaxKind.ModuleDeclaration: - case SyntaxKind.ClassDeclaration: - case SyntaxKind.InterfaceDeclaration: - case SyntaxKind.FunctionDeclaration: - case SyntaxKind.ClassExpression: - case SyntaxKind.FunctionExpression: - case SyntaxKind.MethodDeclaration: - case SyntaxKind.ArrowFunction: + case ts.SyntaxKind.ModuleDeclaration: + case ts.SyntaxKind.ClassDeclaration: + case ts.SyntaxKind.InterfaceDeclaration: + case ts.SyntaxKind.FunctionDeclaration: + case ts.SyntaxKind.ClassExpression: + case ts.SyntaxKind.FunctionExpression: + case ts.SyntaxKind.MethodDeclaration: + case ts.SyntaxKind.ArrowFunction: cancellationToken.throwIfCancellationRequested(); } - if (!textSpanIntersectsWith(span, node.pos, node.getFullWidth())) { + if (!ts.textSpanIntersectsWith(span, node.pos, node.getFullWidth())) { return; } - if (isTypeNode(node)) { + if (ts.isTypeNode(node)) { return; } - if (preferences.includeInlayVariableTypeHints && isVariableDeclaration(node)) { + if (preferences.includeInlayVariableTypeHints && ts.isVariableDeclaration(node)) { visitVariableLikeDeclaration(node); } - else if (preferences.includeInlayPropertyDeclarationTypeHints && isPropertyDeclaration(node)) { + else if (preferences.includeInlayPropertyDeclarationTypeHints && ts.isPropertyDeclaration(node)) { visitVariableLikeDeclaration(node); } - else if (preferences.includeInlayEnumMemberValueHints && isEnumMember(node)) { + else if (preferences.includeInlayEnumMemberValueHints && ts.isEnumMember(node)) { visitEnumMember(node); } - else if (shouldShowParameterNameHints(preferences) && (isCallExpression(node) || isNewExpression(node))) { + else if (shouldShowParameterNameHints(preferences) && (ts.isCallExpression(node) || ts.isNewExpression(node))) { visitCallOrNewExpression(node); } else { - if (preferences.includeInlayFunctionParameterTypeHints && isFunctionLikeDeclaration(node) && hasContextSensitiveParameters(node)) { + if (preferences.includeInlayFunctionParameterTypeHints && ts.isFunctionLikeDeclaration(node) && ts.hasContextSensitiveParameters(node)) { visitFunctionLikeForParameterType(node); } if (preferences.includeInlayFunctionLikeReturnTypeHints && isSignatureSupportingReturnAnnotation(node)) { visitFunctionDeclarationLikeForReturnType(node); } } - return forEachChild(node, visitor); + return ts.forEachChild(node, visitor); } - function isSignatureSupportingReturnAnnotation(node: Node): node is FunctionDeclaration | ArrowFunction | FunctionExpression | MethodDeclaration | GetAccessorDeclaration { - return isArrowFunction(node) || isFunctionExpression(node) || isFunctionDeclaration(node) || isMethodDeclaration(node) || isGetAccessorDeclaration(node); + function isSignatureSupportingReturnAnnotation(node: ts.Node): node is ts.FunctionDeclaration | ts.ArrowFunction | ts.FunctionExpression | ts.MethodDeclaration | ts.GetAccessorDeclaration { + return ts.isArrowFunction(node) || ts.isFunctionExpression(node) || ts.isFunctionDeclaration(node) || ts.isMethodDeclaration(node) || ts.isGetAccessorDeclaration(node); } function addParameterHints(text: string, position: number, isFirstVariadicArgument: boolean) { result.push({ text: `${isFirstVariadicArgument ? "..." : ""}${truncation(text, maxHintsLength)}:`, position, - kind: InlayHintKind.Parameter, + kind: ts.InlayHintKind.Parameter, whitespaceAfter: true, }); } @@ -91,7 +91,7 @@ namespace ts.InlayHints { result.push({ text: `: ${truncation(text, maxHintsLength)}`, position, - kind: InlayHintKind.Type, + kind: ts.InlayHintKind.Type, whitespaceBefore: true, }); } @@ -100,12 +100,12 @@ namespace ts.InlayHints { result.push({ text: `= ${truncation(text, maxHintsLength)}`, position, - kind: InlayHintKind.Enum, + kind: ts.InlayHintKind.Enum, whitespaceBefore: true, }); } - function visitEnumMember(member: EnumMember) { + function visitEnumMember(member: ts.EnumMember) { if (member.initializer) { return; } @@ -116,16 +116,16 @@ namespace ts.InlayHints { } } - function isModuleReferenceType(type: Type) { - return type.symbol && (type.symbol.flags & SymbolFlags.Module); + function isModuleReferenceType(type: ts.Type) { + return type.symbol && (type.symbol.flags & ts.SymbolFlags.Module); } - function visitVariableLikeDeclaration(decl: VariableDeclaration | PropertyDeclaration) { - if (!decl.initializer || isBindingPattern(decl.name)) { + function visitVariableLikeDeclaration(decl: ts.VariableDeclaration | ts.PropertyDeclaration) { + if (!decl.initializer || ts.isBindingPattern(decl.name)) { return; } - const effectiveTypeAnnotation = getEffectiveTypeAnnotationNode(decl); + const effectiveTypeAnnotation = ts.getEffectiveTypeAnnotationNode(decl); if (effectiveTypeAnnotation) { return; } @@ -141,13 +141,13 @@ namespace ts.InlayHints { } } - function visitCallOrNewExpression(expr: CallExpression | NewExpression) { + function visitCallOrNewExpression(expr: ts.CallExpression | ts.NewExpression) { const args = expr.arguments; if (!args || !args.length) { return; } - const candidates: Signature[] = []; + const candidates: ts.Signature[] = []; const signature = checker.getResolvedSignatureForSignatureHelp(expr, candidates); if (!signature || !candidates.length) { return; @@ -155,7 +155,7 @@ namespace ts.InlayHints { for (let i = 0; i < args.length; ++i) { const originalArg = args[i]; - const arg = skipParentheses(originalArg); + const arg = ts.skipParentheses(originalArg); if (shouldShowLiteralParameterNameHintsOnly(preferences) && !isHintableLiteral(arg)) { continue; } @@ -168,7 +168,7 @@ namespace ts.InlayHints { continue; } - const name = unescapeLeadingUnderscores(parameterName); + const name = ts.unescapeLeadingUnderscores(parameterName); if (leadingCommentsContainsParameterName(arg, name)) { continue; } @@ -178,58 +178,58 @@ namespace ts.InlayHints { } } - function identifierOrAccessExpressionPostfixMatchesParameterName(expr: Expression, parameterName: __String) { - if (isIdentifier(expr)) { + function identifierOrAccessExpressionPostfixMatchesParameterName(expr: ts.Expression, parameterName: ts.__String) { + if (ts.isIdentifier(expr)) { return expr.text === parameterName; } - if (isPropertyAccessExpression(expr)) { + if (ts.isPropertyAccessExpression(expr)) { return expr.name.text === parameterName; } return false; } - function leadingCommentsContainsParameterName(node: Node, name: string) { - if (!isIdentifierText(name, compilerOptions.target, getLanguageVariant(file.scriptKind))) { + function leadingCommentsContainsParameterName(node: ts.Node, name: string) { + if (!ts.isIdentifierText(name, compilerOptions.target, ts.getLanguageVariant(file.scriptKind))) { return false; } - const ranges = getLeadingCommentRanges(sourceFileText, node.pos); + const ranges = ts.getLeadingCommentRanges(sourceFileText, node.pos); if (!ranges?.length) { return false; } const regex = leadingParameterNameCommentRegexFactory(name); - return some(ranges, range => regex.test(sourceFileText.substring(range.pos, range.end))); + return ts.some(ranges, range => regex.test(sourceFileText.substring(range.pos, range.end))); } - function isHintableLiteral(node: Node) { + function isHintableLiteral(node: ts.Node) { switch (node.kind) { - case SyntaxKind.PrefixUnaryExpression: { - const operand = (node as PrefixUnaryExpression).operand; - return isLiteralExpression(operand) || isIdentifier(operand) && isInfinityOrNaNString(operand.escapedText); + case ts.SyntaxKind.PrefixUnaryExpression: { + const operand = (node as ts.PrefixUnaryExpression).operand; + return ts.isLiteralExpression(operand) || ts.isIdentifier(operand) && ts.isInfinityOrNaNString(operand.escapedText); } - case SyntaxKind.TrueKeyword: - case SyntaxKind.FalseKeyword: - case SyntaxKind.NullKeyword: - case SyntaxKind.NoSubstitutionTemplateLiteral: - case SyntaxKind.TemplateExpression: + case ts.SyntaxKind.TrueKeyword: + case ts.SyntaxKind.FalseKeyword: + case ts.SyntaxKind.NullKeyword: + case ts.SyntaxKind.NoSubstitutionTemplateLiteral: + case ts.SyntaxKind.TemplateExpression: return true; - case SyntaxKind.Identifier: { - const name = (node as Identifier).escapedText; - return isUndefined(name) || isInfinityOrNaNString(name); + case ts.SyntaxKind.Identifier: { + const name = (node as ts.Identifier).escapedText; + return isUndefined(name) || ts.isInfinityOrNaNString(name); } } - return isLiteralExpression(node); + return ts.isLiteralExpression(node); } - function visitFunctionDeclarationLikeForReturnType(decl: FunctionDeclaration | ArrowFunction | FunctionExpression | MethodDeclaration | GetAccessorDeclaration) { - if (isArrowFunction(decl)) { - if (!findChildOfKind(decl, SyntaxKind.OpenParenToken, file)) { + function visitFunctionDeclarationLikeForReturnType(decl: ts.FunctionDeclaration | ts.ArrowFunction | ts.FunctionExpression | ts.MethodDeclaration | ts.GetAccessorDeclaration) { + if (ts.isArrowFunction(decl)) { + if (!ts.findChildOfKind(decl, ts.SyntaxKind.OpenParenToken, file)) { return; } } - const effectiveTypeAnnotation = getEffectiveReturnTypeNode(decl); + const effectiveTypeAnnotation = ts.getEffectiveReturnTypeNode(decl); if (effectiveTypeAnnotation || !decl.body) { return; } @@ -252,15 +252,15 @@ namespace ts.InlayHints { addTypeHints(typeDisplayString, getTypeAnnotationPosition(decl)); } - function getTypeAnnotationPosition(decl: FunctionDeclaration | ArrowFunction | FunctionExpression | MethodDeclaration | GetAccessorDeclaration) { - const closeParenToken = findChildOfKind(decl, SyntaxKind.CloseParenToken, file); + function getTypeAnnotationPosition(decl: ts.FunctionDeclaration | ts.ArrowFunction | ts.FunctionExpression | ts.MethodDeclaration | ts.GetAccessorDeclaration) { + const closeParenToken = ts.findChildOfKind(decl, ts.SyntaxKind.CloseParenToken, file); if (closeParenToken) { return closeParenToken.end; } return decl.parameters.end; } - function visitFunctionLikeForParameterType(node: FunctionLikeDeclaration) { + function visitFunctionLikeForParameterType(node: ts.FunctionLikeDeclaration) { const signature = checker.getSignatureFromDeclaration(node); if (!signature) { return; @@ -268,7 +268,7 @@ namespace ts.InlayHints { for (let i = 0; i < node.parameters.length && i < signature.parameters.length; ++i) { const param = node.parameters[i]; - const effectiveTypeAnnotation = getEffectiveTypeAnnotationNode(param); + const effectiveTypeAnnotation = ts.getEffectiveTypeAnnotationNode(param); if (effectiveTypeAnnotation) { continue; @@ -283,9 +283,9 @@ namespace ts.InlayHints { } } - function getParameterDeclarationTypeDisplayString(symbol: Symbol) { + function getParameterDeclarationTypeDisplayString(symbol: ts.Symbol) { const valueDeclaration = symbol.valueDeclaration; - if (!valueDeclaration || !isParameter(valueDeclaration)) { + if (!valueDeclaration || !ts.isParameter(valueDeclaration)) { return undefined; } @@ -304,19 +304,18 @@ namespace ts.InlayHints { return text; } - function printTypeInSingleLine(type: Type) { - const flags = NodeBuilderFlags.IgnoreErrors | TypeFormatFlags.AllowUniqueESSymbolType | TypeFormatFlags.UseAliasDefinedOutsideCurrentScope; - const options: PrinterOptions = { removeComments: true }; - const printer = createPrinter(options); - - return usingSingleLineStringWriter(writer => { + function printTypeInSingleLine(type: ts.Type) { + const flags = ts.NodeBuilderFlags.IgnoreErrors | ts.TypeFormatFlags.AllowUniqueESSymbolType | ts.TypeFormatFlags.UseAliasDefinedOutsideCurrentScope; + const options: ts.PrinterOptions = { removeComments: true }; + const printer = ts.createPrinter(options); + return ts.usingSingleLineStringWriter(writer => { const typeNode = checker.typeToTypeNode(type, /*enclosingDeclaration*/ undefined, flags, writer); - Debug.assertIsDefined(typeNode, "should always get typenode"); - printer.writeNode(EmitHint.Unspecified, typeNode, /*sourceFile*/ file, writer); + ts.Debug.assertIsDefined(typeNode, "should always get typenode"); + printer.writeNode(ts.EmitHint.Unspecified, typeNode, /*sourceFile*/ file, writer); }); } - function isUndefined(name: __String) { + function isUndefined(name: ts.__String) { return name === "undefined"; } } diff --git a/src/services/jsDoc.ts b/src/services/jsDoc.ts index e85246e9eb5b9..cfeae64c8e125 100644 --- a/src/services/jsDoc.ts +++ b/src/services/jsDoc.ts @@ -80,71 +80,70 @@ namespace ts.JsDoc { "virtual", "yields" ]; - let jsDocTagNameCompletionEntries: CompletionEntry[]; - let jsDocTagCompletionEntries: CompletionEntry[]; - - export function getJsDocCommentsFromDeclarations(declarations: readonly Declaration[], checker?: TypeChecker): SymbolDisplayPart[] { + let jsDocTagNameCompletionEntries: ts.CompletionEntry[]; + let jsDocTagCompletionEntries: ts.CompletionEntry[]; + export function getJsDocCommentsFromDeclarations(declarations: readonly ts.Declaration[], checker?: ts.TypeChecker): ts.SymbolDisplayPart[] { // Only collect doc comments from duplicate declarations once: // In case of a union property there might be same declaration multiple times // which only varies in type parameter // Eg. const a: Array | Array; a.length // The property length will have two declarations of property length coming // from Array - Array and Array - const parts: SymbolDisplayPart[][] = []; - forEachUnique(declarations, declaration => { + const parts: ts.SymbolDisplayPart[][] = []; + ts.forEachUnique(declarations, declaration => { for (const jsdoc of getCommentHavingNodes(declaration)) { - const inheritDoc = isJSDoc(jsdoc) && jsdoc.tags && find(jsdoc.tags, t => t.kind === SyntaxKind.JSDocTag && (t.tagName.escapedText === "inheritDoc" || t.tagName.escapedText === "inheritdoc")); + const inheritDoc = ts.isJSDoc(jsdoc) && jsdoc.tags && ts.find(jsdoc.tags, t => t.kind === ts.SyntaxKind.JSDocTag && (t.tagName.escapedText === "inheritDoc" || t.tagName.escapedText === "inheritdoc")); // skip comments containing @typedefs since they're not associated with particular declarations // Exceptions: // - @typedefs are themselves declarations with associated comments // - @param or @return indicate that the author thinks of it as a 'local' @typedef that's part of the function documentation if (jsdoc.comment === undefined && !inheritDoc - || isJSDoc(jsdoc) - && declaration.kind !== SyntaxKind.JSDocTypedefTag && declaration.kind !== SyntaxKind.JSDocCallbackTag + || ts.isJSDoc(jsdoc) + && declaration.kind !== ts.SyntaxKind.JSDocTypedefTag && declaration.kind !== ts.SyntaxKind.JSDocCallbackTag && jsdoc.tags - && jsdoc.tags.some(t => t.kind === SyntaxKind.JSDocTypedefTag || t.kind === SyntaxKind.JSDocCallbackTag) - && !jsdoc.tags.some(t => t.kind === SyntaxKind.JSDocParameterTag || t.kind === SyntaxKind.JSDocReturnTag)) { + && jsdoc.tags.some(t => t.kind === ts.SyntaxKind.JSDocTypedefTag || t.kind === ts.SyntaxKind.JSDocCallbackTag) + && !jsdoc.tags.some(t => t.kind === ts.SyntaxKind.JSDocParameterTag || t.kind === ts.SyntaxKind.JSDocReturnTag)) { continue; } let newparts = jsdoc.comment ? getDisplayPartsFromComment(jsdoc.comment, checker) : []; if (inheritDoc && inheritDoc.comment) { newparts = newparts.concat(getDisplayPartsFromComment(inheritDoc.comment, checker)); } - if (!contains(parts, newparts, isIdenticalListOfDisplayParts)) { + if (!ts.contains(parts, newparts, isIdenticalListOfDisplayParts)) { parts.push(newparts); } } }); - return flatten(intersperse(parts, [lineBreakPart()])); + return ts.flatten(ts.intersperse(parts, [ts.lineBreakPart()])); } - function isIdenticalListOfDisplayParts(parts1: SymbolDisplayPart[], parts2: SymbolDisplayPart[]) { - return arraysEqual(parts1, parts2, (p1, p2) => p1.kind === p2.kind && p1.text === p2.text); + function isIdenticalListOfDisplayParts(parts1: ts.SymbolDisplayPart[], parts2: ts.SymbolDisplayPart[]) { + return ts.arraysEqual(parts1, parts2, (p1, p2) => p1.kind === p2.kind && p1.text === p2.text); } - function getCommentHavingNodes(declaration: Declaration): readonly (JSDoc | JSDocTag)[] { + function getCommentHavingNodes(declaration: ts.Declaration): readonly (ts.JSDoc | ts.JSDocTag)[] { switch (declaration.kind) { - case SyntaxKind.JSDocParameterTag: - case SyntaxKind.JSDocPropertyTag: - return [declaration as JSDocPropertyTag]; - case SyntaxKind.JSDocCallbackTag: - case SyntaxKind.JSDocTypedefTag: - return [(declaration as JSDocTypedefTag), (declaration as JSDocTypedefTag).parent]; + case ts.SyntaxKind.JSDocParameterTag: + case ts.SyntaxKind.JSDocPropertyTag: + return [declaration as ts.JSDocPropertyTag]; + case ts.SyntaxKind.JSDocCallbackTag: + case ts.SyntaxKind.JSDocTypedefTag: + return [(declaration as ts.JSDocTypedefTag), (declaration as ts.JSDocTypedefTag).parent]; default: - return getJSDocCommentsAndTags(declaration); + return ts.getJSDocCommentsAndTags(declaration); } } - export function getJsDocTagsFromDeclarations(declarations?: Declaration[], checker?: TypeChecker): JSDocTagInfo[] { + export function getJsDocTagsFromDeclarations(declarations?: ts.Declaration[], checker?: ts.TypeChecker): ts.JSDocTagInfo[] { // Only collect doc comments from duplicate declarations once. - const infos: JSDocTagInfo[] = []; - forEachUnique(declarations, declaration => { - const tags = getJSDocTags(declaration); + const infos: ts.JSDocTagInfo[] = []; + ts.forEachUnique(declarations, declaration => { + const tags = ts.getJSDocTags(declaration); // skip comments containing @typedefs since they're not associated with particular declarations // Exceptions: // - @param or @return indicate that the author thinks of it as a 'local' @typedef that's part of the function documentation - if (tags.some(t => t.kind === SyntaxKind.JSDocTypedefTag || t.kind === SyntaxKind.JSDocCallbackTag) - && !tags.some(t => t.kind === SyntaxKind.JSDocParameterTag || t.kind === SyntaxKind.JSDocReturnTag)) { + if (tags.some(t => t.kind === ts.SyntaxKind.JSDocTypedefTag || t.kind === ts.SyntaxKind.JSDocCallbackTag) + && !tags.some(t => t.kind === ts.SyntaxKind.JSDocParameterTag || t.kind === ts.SyntaxKind.JSDocReturnTag)) { return; } for (const tag of tags) { @@ -154,54 +153,51 @@ namespace ts.JsDoc { return infos; } - function getDisplayPartsFromComment(comment: string | readonly JSDocComment[], checker: TypeChecker | undefined): SymbolDisplayPart[] { + function getDisplayPartsFromComment(comment: string | readonly ts.JSDocComment[], checker: ts.TypeChecker | undefined): ts.SymbolDisplayPart[] { if (typeof comment === "string") { - return [textPart(comment)]; + return [ts.textPart(comment)]; } - return flatMap( - comment, - node => node.kind === SyntaxKind.JSDocText ? [textPart(node.text)] : buildLinkParts(node, checker) - ) as SymbolDisplayPart[]; + return ts.flatMap(comment, node => node.kind === ts.SyntaxKind.JSDocText ? [ts.textPart(node.text)] : ts.buildLinkParts(node, checker)) as ts.SymbolDisplayPart[]; } - function getCommentDisplayParts(tag: JSDocTag, checker?: TypeChecker): SymbolDisplayPart[] | undefined { + function getCommentDisplayParts(tag: ts.JSDocTag, checker?: ts.TypeChecker): ts.SymbolDisplayPart[] | undefined { const { comment, kind } = tag; const namePart = getTagNameDisplayPart(kind); switch (kind) { - case SyntaxKind.JSDocImplementsTag: - return withNode((tag as JSDocImplementsTag).class); - case SyntaxKind.JSDocAugmentsTag: - return withNode((tag as JSDocAugmentsTag).class); - case SyntaxKind.JSDocTemplateTag: - const templateTag = tag as JSDocTemplateTag; - const displayParts: SymbolDisplayPart[] = []; + case ts.SyntaxKind.JSDocImplementsTag: + return withNode((tag as ts.JSDocImplementsTag).class); + case ts.SyntaxKind.JSDocAugmentsTag: + return withNode((tag as ts.JSDocAugmentsTag).class); + case ts.SyntaxKind.JSDocTemplateTag: + const templateTag = tag as ts.JSDocTemplateTag; + const displayParts: ts.SymbolDisplayPart[] = []; if (templateTag.constraint) { - displayParts.push(textPart(templateTag.constraint.getText())); + displayParts.push(ts.textPart(templateTag.constraint.getText())); } - if (length(templateTag.typeParameters)) { - if (length(displayParts)) { - displayParts.push(spacePart()); + if (ts.length(templateTag.typeParameters)) { + if (ts.length(displayParts)) { + displayParts.push(ts.spacePart()); } const lastTypeParameter = templateTag.typeParameters[templateTag.typeParameters.length - 1]; - forEach(templateTag.typeParameters, tp => { + ts.forEach(templateTag.typeParameters, tp => { displayParts.push(namePart(tp.getText())); if (lastTypeParameter !== tp) { - displayParts.push(...[punctuationPart(SyntaxKind.CommaToken), spacePart()]); + displayParts.push(...[ts.punctuationPart(ts.SyntaxKind.CommaToken), ts.spacePart()]); } }); } if (comment) { - displayParts.push(...[spacePart(), ...getDisplayPartsFromComment(comment, checker)]); + displayParts.push(...[ts.spacePart(), ...getDisplayPartsFromComment(comment, checker)]); } return displayParts; - case SyntaxKind.JSDocTypeTag: - return withNode((tag as JSDocTypeTag).typeExpression); - case SyntaxKind.JSDocTypedefTag: - case SyntaxKind.JSDocCallbackTag: - case SyntaxKind.JSDocPropertyTag: - case SyntaxKind.JSDocParameterTag: - case SyntaxKind.JSDocSeeTag: - const { name } = tag as JSDocTypedefTag | JSDocCallbackTag | JSDocPropertyTag | JSDocParameterTag | JSDocSeeTag; + case ts.SyntaxKind.JSDocTypeTag: + return withNode((tag as ts.JSDocTypeTag).typeExpression); + case ts.SyntaxKind.JSDocTypedefTag: + case ts.SyntaxKind.JSDocCallbackTag: + case ts.SyntaxKind.JSDocPropertyTag: + case ts.SyntaxKind.JSDocParameterTag: + case ts.SyntaxKind.JSDocSeeTag: + const { name } = tag as ts.JSDocTypedefTag | ts.JSDocCallbackTag | ts.JSDocPropertyTag | ts.JSDocParameterTag | ts.JSDocSeeTag; return name ? withNode(name) : comment === undefined ? undefined : getDisplayPartsFromComment(comment, checker); @@ -209,106 +205,107 @@ namespace ts.JsDoc { return comment === undefined ? undefined : getDisplayPartsFromComment(comment, checker); } - function withNode(node: Node) { + function withNode(node: ts.Node) { return addComment(node.getText()); } function addComment(s: string) { if (comment) { if (s.match(/^https?$/)) { - return [textPart(s), ...getDisplayPartsFromComment(comment, checker)]; + return [ts.textPart(s), ...getDisplayPartsFromComment(comment, checker)]; } else { - return [namePart(s), spacePart(), ...getDisplayPartsFromComment(comment, checker)]; + return [namePart(s), ts.spacePart(), ...getDisplayPartsFromComment(comment, checker)]; } } else { - return [textPart(s)]; + return [ts.textPart(s)]; } } } - function getTagNameDisplayPart(kind: SyntaxKind): (text: string) => SymbolDisplayPart { + function getTagNameDisplayPart(kind: ts.SyntaxKind): (text: string) => ts.SymbolDisplayPart { switch (kind) { - case SyntaxKind.JSDocParameterTag: - return parameterNamePart; - case SyntaxKind.JSDocPropertyTag: - return propertyNamePart; - case SyntaxKind.JSDocTemplateTag: - return typeParameterNamePart; - case SyntaxKind.JSDocTypedefTag: - case SyntaxKind.JSDocCallbackTag: - return typeAliasNamePart; + case ts.SyntaxKind.JSDocParameterTag: + return ts.parameterNamePart; + case ts.SyntaxKind.JSDocPropertyTag: + return ts.propertyNamePart; + case ts.SyntaxKind.JSDocTemplateTag: + return ts.typeParameterNamePart; + case ts.SyntaxKind.JSDocTypedefTag: + case ts.SyntaxKind.JSDocCallbackTag: + return ts.typeAliasNamePart; default: - return textPart; + return ts.textPart; } } - export function getJSDocTagNameCompletions(): CompletionEntry[] { - return jsDocTagNameCompletionEntries || (jsDocTagNameCompletionEntries = map(jsDocTagNames, tagName => { + export function getJSDocTagNameCompletions(): ts.CompletionEntry[] { + return jsDocTagNameCompletionEntries || (jsDocTagNameCompletionEntries = ts.map(jsDocTagNames, tagName => { return { name: tagName, - kind: ScriptElementKind.keyword, + kind: ts.ScriptElementKind.keyword, kindModifiers: "", - sortText: Completions.SortText.LocationPriority, + sortText: ts.Completions.SortText.LocationPriority, }; })); } export const getJSDocTagNameCompletionDetails = getJSDocTagCompletionDetails; - export function getJSDocTagCompletions(): CompletionEntry[] { - return jsDocTagCompletionEntries || (jsDocTagCompletionEntries = map(jsDocTagNames, tagName => { + export function getJSDocTagCompletions(): ts.CompletionEntry[] { + return jsDocTagCompletionEntries || (jsDocTagCompletionEntries = ts.map(jsDocTagNames, tagName => { return { name: `@${tagName}`, - kind: ScriptElementKind.keyword, + kind: ts.ScriptElementKind.keyword, kindModifiers: "", - sortText: Completions.SortText.LocationPriority + sortText: ts.Completions.SortText.LocationPriority }; })); } - export function getJSDocTagCompletionDetails(name: string): CompletionEntryDetails { + export function getJSDocTagCompletionDetails(name: string): ts.CompletionEntryDetails { return { name, - kind: ScriptElementKind.unknown, // TODO: should have its own kind? + kind: ts.ScriptElementKind.unknown, kindModifiers: "", - displayParts: [textPart(name)], - documentation: emptyArray, + displayParts: [ts.textPart(name)], + documentation: ts.emptyArray, tags: undefined, codeActions: undefined, }; } - export function getJSDocParameterNameCompletions(tag: JSDocParameterTag): CompletionEntry[] { - if (!isIdentifier(tag.name)) { - return emptyArray; + export function getJSDocParameterNameCompletions(tag: ts.JSDocParameterTag): ts.CompletionEntry[] { + if (!ts.isIdentifier(tag.name)) { + return ts.emptyArray; } const nameThusFar = tag.name.text; const jsdoc = tag.parent; const fn = jsdoc.parent; - if (!isFunctionLike(fn)) return []; - - return mapDefined(fn.parameters, param => { - if (!isIdentifier(param.name)) return undefined; + if (!ts.isFunctionLike(fn)) + return []; + return ts.mapDefined(fn.parameters, param => { + if (!ts.isIdentifier(param.name)) + return undefined; const name = param.name.text; - if (jsdoc.tags!.some(t => t !== tag && isJSDocParameterTag(t) && isIdentifier(t.name) && t.name.escapedText === name) // TODO: GH#18217 - || nameThusFar !== undefined && !startsWith(name, nameThusFar)) { + if (jsdoc.tags!.some(t => t !== tag && ts.isJSDocParameterTag(t) && ts.isIdentifier(t.name) && t.name.escapedText === name) // TODO: GH#18217 + || nameThusFar !== undefined && !ts.startsWith(name, nameThusFar)) { return undefined; } - return { name, kind: ScriptElementKind.parameterElement, kindModifiers: "", sortText: Completions.SortText.LocationPriority }; + return { name, kind: ts.ScriptElementKind.parameterElement, kindModifiers: "", sortText: ts.Completions.SortText.LocationPriority }; }); } - export function getJSDocParameterNameCompletionDetails(name: string): CompletionEntryDetails { + export function getJSDocParameterNameCompletionDetails(name: string): ts.CompletionEntryDetails { return { name, - kind: ScriptElementKind.parameterElement, + kind: ts.ScriptElementKind.parameterElement, kindModifiers: "", - displayParts: [textPart(name)], - documentation: emptyArray, + displayParts: [ts.textPart(name)], + documentation: ts.emptyArray, tags: undefined, codeActions: undefined, }; @@ -337,10 +334,10 @@ namespace ts.JsDoc { * @param position The (character-indexed) position in the file where the check should * be performed. */ - export function getDocCommentTemplateAtPosition(newLine: string, sourceFile: SourceFile, position: number, options?: DocCommentTemplateOptions): TextInsertion | undefined { - const tokenAtPos = getTokenAtPosition(sourceFile, position); - const existingDocComment = findAncestor(tokenAtPos, isJSDoc); - if (existingDocComment && (existingDocComment.comment !== undefined || length(existingDocComment.tags))) { + export function getDocCommentTemplateAtPosition(newLine: string, sourceFile: ts.SourceFile, position: number, options?: ts.DocCommentTemplateOptions): ts.TextInsertion | undefined { + const tokenAtPos = ts.getTokenAtPosition(sourceFile, position); + const existingDocComment = ts.findAncestor(tokenAtPos, ts.isJSDoc); + if (existingDocComment && (existingDocComment.comment !== undefined || ts.length(existingDocComment.tags))) { // Non-empty comment already exists. return undefined; } @@ -357,15 +354,14 @@ namespace ts.JsDoc { } const { commentOwner, parameters, hasReturn } = commentOwnerInfo; - const commentOwnerJSDoc = hasJSDocNodes(commentOwner) && commentOwner.jsDoc ? lastOrUndefined(commentOwner.jsDoc) : undefined; + const commentOwnerJSDoc = ts.hasJSDocNodes(commentOwner) && commentOwner.jsDoc ? ts.lastOrUndefined(commentOwner.jsDoc) : undefined; if (commentOwner.getStart(sourceFile) < position || commentOwnerJSDoc && commentOwnerJSDoc !== existingDocComment) { return undefined; } const indentationStr = getIndentationStringAtPosition(sourceFile, position); - const isJavaScriptFile = hasJSFileExtension(sourceFile.fileName); - const tags = - (parameters ? parameterDocComments(parameters || [], isJavaScriptFile, indentationStr, newLine) : "") + + const isJavaScriptFile = ts.hasJSFileExtension(sourceFile.fileName); + const tags = (parameters ? parameterDocComments(parameters || [], isJavaScriptFile, indentationStr, newLine) : "") + (hasReturn ? returnsDocComment(indentationStr, newLine) : ""); // A doc comment consists of the following @@ -387,17 +383,18 @@ namespace ts.JsDoc { return { newText: openComment + closeComment, caretOffset: 3 }; } - function getIndentationStringAtPosition(sourceFile: SourceFile, position: number): string { + function getIndentationStringAtPosition(sourceFile: ts.SourceFile, position: number): string { const { text } = sourceFile; - const lineStart = getLineStartPositionForPosition(position, sourceFile); + const lineStart = ts.getLineStartPositionForPosition(position, sourceFile); let pos = lineStart; - for (; pos <= position && isWhiteSpaceSingleLine(text.charCodeAt(pos)); pos++); + for (; pos <= position && ts.isWhiteSpaceSingleLine(text.charCodeAt(pos)); pos++) + ; return text.slice(lineStart, pos); } - function parameterDocComments(parameters: readonly ParameterDeclaration[], isJavaScriptFile: boolean, indentationStr: string, newLine: string): string { + function parameterDocComments(parameters: readonly ts.ParameterDeclaration[], isJavaScriptFile: boolean, indentationStr: string, newLine: string): string { return parameters.map(({ name, dotDotDotToken }, i) => { - const paramName = name.kind === SyntaxKind.Identifier ? name.text : "param" + i; + const paramName = name.kind === ts.SyntaxKind.Identifier ? name.text : "param" + i; const type = isJavaScriptFile ? (dotDotDotToken ? "{...any} " : "{any} ") : ""; return `${indentationStr} * @param ${type}${paramName}${newLine}`; }).join(""); @@ -408,37 +405,36 @@ namespace ts.JsDoc { } interface CommentOwnerInfo { - readonly commentOwner: Node; - readonly parameters?: readonly ParameterDeclaration[]; + readonly commentOwner: ts.Node; + readonly parameters?: readonly ts.ParameterDeclaration[]; readonly hasReturn?: boolean; } - function getCommentOwnerInfo(tokenAtPos: Node, options: DocCommentTemplateOptions | undefined): CommentOwnerInfo | undefined { - return forEachAncestor(tokenAtPos, n => getCommentOwnerInfoWorker(n, options)); + function getCommentOwnerInfo(tokenAtPos: ts.Node, options: ts.DocCommentTemplateOptions | undefined): CommentOwnerInfo | undefined { + return ts.forEachAncestor(tokenAtPos, n => getCommentOwnerInfoWorker(n, options)); } - function getCommentOwnerInfoWorker(commentOwner: Node, options: DocCommentTemplateOptions | undefined): CommentOwnerInfo | undefined | "quit" { + function getCommentOwnerInfoWorker(commentOwner: ts.Node, options: ts.DocCommentTemplateOptions | undefined): CommentOwnerInfo | undefined | "quit" { switch (commentOwner.kind) { - case SyntaxKind.FunctionDeclaration: - case SyntaxKind.FunctionExpression: - case SyntaxKind.MethodDeclaration: - case SyntaxKind.Constructor: - case SyntaxKind.MethodSignature: - case SyntaxKind.ArrowFunction: - const host = commentOwner as ArrowFunction | FunctionDeclaration | MethodDeclaration | ConstructorDeclaration | MethodSignature; + case ts.SyntaxKind.FunctionDeclaration: + case ts.SyntaxKind.FunctionExpression: + case ts.SyntaxKind.MethodDeclaration: + case ts.SyntaxKind.Constructor: + case ts.SyntaxKind.MethodSignature: + case ts.SyntaxKind.ArrowFunction: + const host = commentOwner as ts.ArrowFunction | ts.FunctionDeclaration | ts.MethodDeclaration | ts.ConstructorDeclaration | ts.MethodSignature; return { commentOwner, parameters: host.parameters, hasReturn: hasReturn(host, options) }; - case SyntaxKind.PropertyAssignment: - return getCommentOwnerInfoWorker((commentOwner as PropertyAssignment).initializer, options); - - case SyntaxKind.ClassDeclaration: - case SyntaxKind.InterfaceDeclaration: - case SyntaxKind.PropertySignature: - case SyntaxKind.EnumDeclaration: - case SyntaxKind.EnumMember: - case SyntaxKind.TypeAliasDeclaration: + case ts.SyntaxKind.PropertyAssignment: + return getCommentOwnerInfoWorker((commentOwner as ts.PropertyAssignment).initializer, options); + case ts.SyntaxKind.ClassDeclaration: + case ts.SyntaxKind.InterfaceDeclaration: + case ts.SyntaxKind.PropertySignature: + case ts.SyntaxKind.EnumDeclaration: + case ts.SyntaxKind.EnumMember: + case ts.SyntaxKind.TypeAliasDeclaration: return { commentOwner }; - case SyntaxKind.VariableStatement: { - const varStatement = commentOwner as VariableStatement; + case ts.SyntaxKind.VariableStatement: { + const varStatement = commentOwner as ts.VariableStatement; const varDeclarations = varStatement.declarationList.declarations; const host = varDeclarations.length === 1 && varDeclarations[0].initializer ? getRightHandSideOfAssignment(varDeclarations[0].initializer) @@ -448,51 +444,50 @@ namespace ts.JsDoc { : { commentOwner }; } - case SyntaxKind.SourceFile: + case ts.SyntaxKind.SourceFile: return "quit"; - case SyntaxKind.ModuleDeclaration: + case ts.SyntaxKind.ModuleDeclaration: // If in walking up the tree, we hit a a nested namespace declaration, // then we must be somewhere within a dotted namespace name; however we don't // want to give back a JSDoc template for the 'b' or 'c' in 'namespace a.b.c { }'. - return commentOwner.parent.kind === SyntaxKind.ModuleDeclaration ? undefined : { commentOwner }; - - case SyntaxKind.ExpressionStatement: - return getCommentOwnerInfoWorker((commentOwner as ExpressionStatement).expression, options); - case SyntaxKind.BinaryExpression: { - const be = commentOwner as BinaryExpression; - if (getAssignmentDeclarationKind(be) === AssignmentDeclarationKind.None) { + return commentOwner.parent.kind === ts.SyntaxKind.ModuleDeclaration ? undefined : { commentOwner }; + case ts.SyntaxKind.ExpressionStatement: + return getCommentOwnerInfoWorker((commentOwner as ts.ExpressionStatement).expression, options); + case ts.SyntaxKind.BinaryExpression: { + const be = commentOwner as ts.BinaryExpression; + if (ts.getAssignmentDeclarationKind(be) === ts.AssignmentDeclarationKind.None) { return "quit"; } - return isFunctionLike(be.right) + return ts.isFunctionLike(be.right) ? { commentOwner, parameters: be.right.parameters, hasReturn: hasReturn(be.right, options) } : { commentOwner }; } - case SyntaxKind.PropertyDeclaration: - const init = (commentOwner as PropertyDeclaration).initializer; - if (init && (isFunctionExpression(init) || isArrowFunction(init))) { + case ts.SyntaxKind.PropertyDeclaration: + const init = (commentOwner as ts.PropertyDeclaration).initializer; + if (init && (ts.isFunctionExpression(init) || ts.isArrowFunction(init))) { return { commentOwner, parameters: init.parameters, hasReturn: hasReturn(init, options) }; } } } - function hasReturn(node: Node, options: DocCommentTemplateOptions | undefined) { + function hasReturn(node: ts.Node, options: ts.DocCommentTemplateOptions | undefined) { return !!options?.generateReturnInDocTemplate && - (isArrowFunction(node) && isExpression(node.body) - || isFunctionLikeDeclaration(node) && node.body && isBlock(node.body) && !!forEachReturnStatement(node.body, n => n)); + (ts.isArrowFunction(node) && ts.isExpression(node.body) + || ts.isFunctionLikeDeclaration(node) && node.body && ts.isBlock(node.body) && !!ts.forEachReturnStatement(node.body, n => n)); } - function getRightHandSideOfAssignment(rightHandSide: Expression): FunctionExpression | ArrowFunction | ConstructorDeclaration | undefined { - while (rightHandSide.kind === SyntaxKind.ParenthesizedExpression) { - rightHandSide = (rightHandSide as ParenthesizedExpression).expression; + function getRightHandSideOfAssignment(rightHandSide: ts.Expression): ts.FunctionExpression | ts.ArrowFunction | ts.ConstructorDeclaration | undefined { + while (rightHandSide.kind === ts.SyntaxKind.ParenthesizedExpression) { + rightHandSide = (rightHandSide as ts.ParenthesizedExpression).expression; } switch (rightHandSide.kind) { - case SyntaxKind.FunctionExpression: - case SyntaxKind.ArrowFunction: - return (rightHandSide as FunctionExpression); - case SyntaxKind.ClassExpression: - return find((rightHandSide as ClassExpression).members, isConstructorDeclaration); + case ts.SyntaxKind.FunctionExpression: + case ts.SyntaxKind.ArrowFunction: + return (rightHandSide as ts.FunctionExpression); + case ts.SyntaxKind.ClassExpression: + return ts.find((rightHandSide as ts.ClassExpression).members, ts.isConstructorDeclaration); } } } diff --git a/src/services/navigateTo.ts b/src/services/navigateTo.ts index 462d4fd0ac3ef..a49bf6e317223 100644 --- a/src/services/navigateTo.ts +++ b/src/services/navigateTo.ts @@ -3,14 +3,15 @@ namespace ts.NavigateTo { interface RawNavigateToItem { readonly name: string; readonly fileName: string; - readonly matchKind: PatternMatchKind; + readonly matchKind: ts.PatternMatchKind; readonly isCaseSensitive: boolean; - readonly declaration: Declaration; + readonly declaration: ts.Declaration; } - export function getNavigateToItems(sourceFiles: readonly SourceFile[], checker: TypeChecker, cancellationToken: CancellationToken, searchValue: string, maxResultCount: number | undefined, excludeDtsFiles: boolean): NavigateToItem[] { - const patternMatcher = createPatternMatcher(searchValue); - if (!patternMatcher) return emptyArray; + export function getNavigateToItems(sourceFiles: readonly ts.SourceFile[], checker: ts.TypeChecker, cancellationToken: ts.CancellationToken, searchValue: string, maxResultCount: number | undefined, excludeDtsFiles: boolean): ts.NavigateToItem[] { + const patternMatcher = ts.createPatternMatcher(searchValue); + if (!patternMatcher) + return ts.emptyArray; const rawItems: RawNavigateToItem[] = []; // Search the declarations in all files and output matched NavigateToItem into array of NavigateToItem[] @@ -30,7 +31,7 @@ namespace ts.NavigateTo { return (maxResultCount === undefined ? rawItems : rawItems.slice(0, maxResultCount)).map(createNavigateToItem); } - function getItemsFromNamedDeclaration(patternMatcher: PatternMatcher, name: string, declarations: readonly Declaration[], checker: TypeChecker, fileName: string, rawItems: Push): void { + function getItemsFromNamedDeclaration(patternMatcher: ts.PatternMatcher, name: string, declarations: readonly ts.Declaration[], checker: ts.TypeChecker, fileName: string, rawItems: ts.Push): void { // First do a quick check to see if the name of the declaration matches the // last portion of the (possibly) dotted name they're searching for. const match = patternMatcher.getMatchForLastSegmentOfPattern(name); @@ -39,7 +40,8 @@ namespace ts.NavigateTo { } for (const declaration of declarations) { - if (!shouldKeepItem(declaration, checker)) continue; + if (!shouldKeepItem(declaration, checker)) + continue; if (patternMatcher.patternContainsDots) { // If the pattern has dots in it, then also see if the declaration container matches as well. @@ -54,12 +56,12 @@ namespace ts.NavigateTo { } } - function shouldKeepItem(declaration: Declaration, checker: TypeChecker): boolean { + function shouldKeepItem(declaration: ts.Declaration, checker: ts.TypeChecker): boolean { switch (declaration.kind) { - case SyntaxKind.ImportClause: - case SyntaxKind.ImportSpecifier: - case SyntaxKind.ImportEqualsDeclaration: - const importer = checker.getSymbolAtLocation((declaration as ImportClause | ImportSpecifier | ImportEqualsDeclaration).name!)!; // TODO: GH#18217 + case ts.SyntaxKind.ImportClause: + case ts.SyntaxKind.ImportSpecifier: + case ts.SyntaxKind.ImportEqualsDeclaration: + const importer = checker.getSymbolAtLocation((declaration as ts.ImportClause | ts.ImportSpecifier | ts.ImportEqualsDeclaration).name!)!; // TODO: GH#18217 const imported = checker.getAliasedSymbol(importer); return importer.escapedName !== imported.escapedName; default: @@ -67,44 +69,44 @@ namespace ts.NavigateTo { } } - function tryAddSingleDeclarationName(declaration: Declaration, containers: Push): boolean { - const name = getNameOfDeclaration(declaration); - return !!name && (pushLiteral(name, containers) || name.kind === SyntaxKind.ComputedPropertyName && tryAddComputedPropertyName(name.expression, containers)); + function tryAddSingleDeclarationName(declaration: ts.Declaration, containers: ts.Push): boolean { + const name = ts.getNameOfDeclaration(declaration); + return !!name && (pushLiteral(name, containers) || name.kind === ts.SyntaxKind.ComputedPropertyName && tryAddComputedPropertyName(name.expression, containers)); } // Only added the names of computed properties if they're simple dotted expressions, like: // // [X.Y.Z]() { } - function tryAddComputedPropertyName(expression: Expression, containers: Push): boolean { + function tryAddComputedPropertyName(expression: ts.Expression, containers: ts.Push): boolean { return pushLiteral(expression, containers) - || isPropertyAccessExpression(expression) && (containers.push(expression.name.text), true) && tryAddComputedPropertyName(expression.expression, containers); + || ts.isPropertyAccessExpression(expression) && (containers.push(expression.name.text), true) && tryAddComputedPropertyName(expression.expression, containers); } - function pushLiteral(node: Node, containers: Push): boolean { - return isPropertyNameLiteral(node) && (containers.push(getTextOfIdentifierOrLiteral(node)), true); + function pushLiteral(node: ts.Node, containers: ts.Push): boolean { + return ts.isPropertyNameLiteral(node) && (containers.push(ts.getTextOfIdentifierOrLiteral(node)), true); } - function getContainers(declaration: Declaration): readonly string[] { + function getContainers(declaration: ts.Declaration): readonly string[] { const containers: string[] = []; // First, if we started with a computed property name, then add all but the last // portion into the container array. - const name = getNameOfDeclaration(declaration); - if (name && name.kind === SyntaxKind.ComputedPropertyName && !tryAddComputedPropertyName(name.expression, containers)) { - return emptyArray; + const name = ts.getNameOfDeclaration(declaration); + if (name && name.kind === ts.SyntaxKind.ComputedPropertyName && !tryAddComputedPropertyName(name.expression, containers)) { + return ts.emptyArray; } // Don't include the last portion. containers.shift(); // Now, walk up our containers, adding all their names to the container array. - let container = getContainerNode(declaration); + let container = ts.getContainerNode(declaration); while (container) { if (!tryAddSingleDeclarationName(container, containers)) { - return emptyArray; + return ts.emptyArray; } - container = getContainerNode(container); + container = ts.getContainerNode(container); } return containers.reverse(); @@ -112,25 +114,25 @@ namespace ts.NavigateTo { function compareNavigateToItems(i1: RawNavigateToItem, i2: RawNavigateToItem) { // TODO(cyrusn): get the gamut of comparisons that VS already uses here. - return compareValues(i1.matchKind, i2.matchKind) - || compareStringsCaseSensitiveUI(i1.name, i2.name); + return ts.compareValues(i1.matchKind, i2.matchKind) + || ts.compareStringsCaseSensitiveUI(i1.name, i2.name); } - function createNavigateToItem(rawItem: RawNavigateToItem): NavigateToItem { + function createNavigateToItem(rawItem: RawNavigateToItem): ts.NavigateToItem { const declaration = rawItem.declaration; - const container = getContainerNode(declaration); - const containerName = container && getNameOfDeclaration(container); + const container = ts.getContainerNode(declaration); + const containerName = container && ts.getNameOfDeclaration(container); return { name: rawItem.name, - kind: getNodeKind(declaration), - kindModifiers: getNodeModifiers(declaration), - matchKind: PatternMatchKind[rawItem.matchKind] as keyof typeof PatternMatchKind, + kind: ts.getNodeKind(declaration), + kindModifiers: ts.getNodeModifiers(declaration), + matchKind: ts.PatternMatchKind[rawItem.matchKind] as keyof typeof ts.PatternMatchKind, isCaseSensitive: rawItem.isCaseSensitive, fileName: rawItem.fileName, - textSpan: createTextSpanFromNode(declaration), + textSpan: ts.createTextSpanFromNode(declaration), // TODO(jfreeman): What should be the containerName when the container has a computed name? - containerName: containerName ? (containerName as Identifier).text : "", - containerKind: containerName ? getNodeKind(container) : ScriptElementKind.unknown, + containerName: containerName ? (containerName as ts.Identifier).text : "", + containerKind: containerName ? ts.getNodeKind(container) : ts.ScriptElementKind.unknown, }; } } diff --git a/src/services/navigationBar.ts b/src/services/navigationBar.ts index 6b0e4869eb1a1..781dd5e9d409a 100644 --- a/src/services/navigationBar.ts +++ b/src/services/navigationBar.ts @@ -22,8 +22,8 @@ namespace ts.NavigationBar { const maxLength = 150; // Keep sourceFile handy so we don't have to search for it every time we need to call `getText`. - let curCancellationToken: CancellationToken; - let curSourceFile: SourceFile; + let curCancellationToken: ts.CancellationToken; + let curSourceFile: ts.SourceFile; /** * For performance, we keep navigation bar parents on a stack rather than passing them through each recursion. @@ -33,37 +33,37 @@ namespace ts.NavigationBar { let parentsStack: NavigationBarNode[] = []; let parent: NavigationBarNode; - const trackedEs5ClassesStack: (ESMap | undefined)[] = []; - let trackedEs5Classes: ESMap | undefined; + const trackedEs5ClassesStack: (ts.ESMap | undefined)[] = []; + let trackedEs5Classes: ts.ESMap | undefined; // NavigationBarItem requires an array, but will not mutate it, so just give it this for performance. - let emptyChildItemArray: NavigationBarItem[] = []; + let emptyChildItemArray: ts.NavigationBarItem[] = []; /** * Represents a navigation bar item and its children. * The returned NavigationBarItem is more complicated and doesn't include 'parent', so we use these to do work before converting. */ interface NavigationBarNode { - node: Node; - name: DeclarationName | undefined; - additionalNodes: Node[] | undefined; + node: ts.Node; + name: ts.DeclarationName | undefined; + additionalNodes: ts.Node[] | undefined; parent: NavigationBarNode | undefined; // Present for all but root node children: NavigationBarNode[] | undefined; indent: number; // # of parents } - export function getNavigationBarItems(sourceFile: SourceFile, cancellationToken: CancellationToken): NavigationBarItem[] { + export function getNavigationBarItems(sourceFile: ts.SourceFile, cancellationToken: ts.CancellationToken): ts.NavigationBarItem[] { curCancellationToken = cancellationToken; curSourceFile = sourceFile; try { - return map(primaryNavBarMenuItems(rootNavigationBarNode(sourceFile)), convertToPrimaryNavBarMenuItem); + return ts.map(primaryNavBarMenuItems(rootNavigationBarNode(sourceFile)), convertToPrimaryNavBarMenuItem); } finally { reset(); } } - export function getNavigationTree(sourceFile: SourceFile, cancellationToken: CancellationToken): NavigationTree { + export function getNavigationTree(sourceFile: ts.SourceFile, cancellationToken: ts.CancellationToken): ts.NavigationTree { curCancellationToken = cancellationToken; curSourceFile = sourceFile; try { @@ -82,11 +82,11 @@ namespace ts.NavigationBar { emptyChildItemArray = []; } - function nodeText(node: Node): string { + function nodeText(node: ts.Node): string { return cleanText(node.getText(curSourceFile)); } - function navigationBarNodeKind(n: NavigationBarNode): SyntaxKind { + function navigationBarNodeKind(n: NavigationBarNode): ts.SyntaxKind { return n.node.kind; } @@ -99,26 +99,26 @@ namespace ts.NavigationBar { } } - function rootNavigationBarNode(sourceFile: SourceFile): NavigationBarNode { - Debug.assert(!parentsStack.length); + function rootNavigationBarNode(sourceFile: ts.SourceFile): NavigationBarNode { + ts.Debug.assert(!parentsStack.length); const root: NavigationBarNode = { node: sourceFile, name: undefined, additionalNodes: undefined, parent: undefined, children: undefined, indent: 0 }; parent = root; for (const statement of sourceFile.statements) { addChildrenRecursively(statement); } endNode(); - Debug.assert(!parent && !parentsStack.length); + ts.Debug.assert(!parent && !parentsStack.length); return root; } - function addLeafNode(node: Node, name?: DeclarationName): void { + function addLeafNode(node: ts.Node, name?: ts.DeclarationName): void { pushChild(parent, emptyNavigationBarNode(node, name)); } - function emptyNavigationBarNode(node: Node, name?: DeclarationName): NavigationBarNode { + function emptyNavigationBarNode(node: ts.Node, name?: ts.DeclarationName): NavigationBarNode { return { node, - name: name || (isDeclaration(node) || isExpression(node) ? getNameOfDeclaration(node) : undefined), + name: name || (ts.isDeclaration(node) || ts.isExpression(node) ? ts.getNameOfDeclaration(node) : undefined), additionalNodes: undefined, parent, children: undefined, @@ -128,20 +128,22 @@ namespace ts.NavigationBar { function addTrackedEs5Class(name: string) { if (!trackedEs5Classes) { - trackedEs5Classes = new Map(); + trackedEs5Classes = new ts.Map(); } trackedEs5Classes.set(name, true); } function endNestedNodes(depth: number): void { - for (let i = 0; i < depth; i++) endNode(); + for (let i = 0; i < depth; i++) + endNode(); } - function startNestedNodes(targetNode: Node, entityName: BindableStaticNameExpression) { - const names: PropertyNameLiteral[] = []; - while (!isPropertyNameLiteral(entityName)) { - const name = getNameOrArgument(entityName); - const nameText = getElementOrPropertyAccessName(entityName); + function startNestedNodes(targetNode: ts.Node, entityName: ts.BindableStaticNameExpression) { + const names: ts.PropertyNameLiteral[] = []; + while (!ts.isPropertyNameLiteral(entityName)) { + const name = ts.getNameOrArgument(entityName); + const nameText = ts.getElementOrPropertyAccessName(entityName); entityName = entityName.expression; - if (nameText === "prototype" || isPrivateIdentifier(name)) continue; + if (nameText === "prototype" || ts.isPrivateIdentifier(name)) + continue; names.push(name); } names.push(entityName); @@ -156,7 +158,7 @@ namespace ts.NavigationBar { * Add a new level of NavigationBarNodes. * This pushes to the stack, so you must call `endNode` when you are done adding to this node. */ - function startNode(node: Node, name?: DeclarationName): void { + function startNode(node: ts.Node, name?: ts.DeclarationName): void { const navNode: NavigationBarNode = emptyNavigationBarNode(node, name); pushChild(parent, navNode); @@ -177,16 +179,16 @@ namespace ts.NavigationBar { trackedEs5Classes = trackedEs5ClassesStack.pop(); } - function addNodeWithRecursiveChild(node: Node, child: Node | undefined, name?: DeclarationName): void { + function addNodeWithRecursiveChild(node: ts.Node, child: ts.Node | undefined, name?: ts.DeclarationName): void { startNode(node, name); addChildrenRecursively(child); endNode(); } - function addNodeWithRecursiveInitializer(node: VariableDeclaration | PropertyAssignment | BindingElement | PropertyDeclaration): void { + function addNodeWithRecursiveInitializer(node: ts.VariableDeclaration | ts.PropertyAssignment | ts.BindingElement | ts.PropertyDeclaration): void { if (node.initializer && isFunctionOrClassExpression(node.initializer)) { startNode(node); - forEachChild(node.initializer, addChildrenRecursively); + ts.forEachChild(node.initializer, addChildrenRecursively); endNode(); } else { @@ -199,60 +201,58 @@ namespace ts.NavigationBar { * but included certain "well known" symbol names. While we no longer distinguish those well-known * symbols from other unique symbols, we do the below to retain those members in the nav tree. */ - function hasNavigationBarName(node: Declaration) { - return !hasDynamicName(node) || - ( - node.kind !== SyntaxKind.BinaryExpression && - isPropertyAccessExpression(node.name.expression) && - isIdentifier(node.name.expression.expression) && - idText(node.name.expression.expression) === "Symbol" - ); + function hasNavigationBarName(node: ts.Declaration) { + return !ts.hasDynamicName(node) || + (node.kind !== ts.SyntaxKind.BinaryExpression && + ts.isPropertyAccessExpression(node.name.expression) && + ts.isIdentifier(node.name.expression.expression) && + ts.idText(node.name.expression.expression) === "Symbol"); } /** Look for navigation bar items in node's subtree, adding them to the current `parent`. */ - function addChildrenRecursively(node: Node | undefined): void { + function addChildrenRecursively(node: ts.Node | undefined): void { curCancellationToken.throwIfCancellationRequested(); - if (!node || isToken(node)) { + if (!node || ts.isToken(node)) { return; } switch (node.kind) { - case SyntaxKind.Constructor: + case ts.SyntaxKind.Constructor: // Get parameter properties, and treat them as being on the *same* level as the constructor, not under it. - const ctr = node as ConstructorDeclaration; + const ctr = node as ts.ConstructorDeclaration; addNodeWithRecursiveChild(ctr, ctr.body); // Parameter properties are children of the class, not the constructor. for (const param of ctr.parameters) { - if (isParameterPropertyDeclaration(param, ctr)) { + if (ts.isParameterPropertyDeclaration(param, ctr)) { addLeafNode(param); } } break; - case SyntaxKind.MethodDeclaration: - case SyntaxKind.GetAccessor: - case SyntaxKind.SetAccessor: - case SyntaxKind.MethodSignature: - if (hasNavigationBarName(node as ClassElement | TypeElement)) { - addNodeWithRecursiveChild(node, (node as FunctionLikeDeclaration).body); + case ts.SyntaxKind.MethodDeclaration: + case ts.SyntaxKind.GetAccessor: + case ts.SyntaxKind.SetAccessor: + case ts.SyntaxKind.MethodSignature: + if (hasNavigationBarName(node as ts.ClassElement | ts.TypeElement)) { + addNodeWithRecursiveChild(node, (node as ts.FunctionLikeDeclaration).body); } break; - case SyntaxKind.PropertyDeclaration: - if (hasNavigationBarName(node as ClassElement)) { - addNodeWithRecursiveInitializer(node as PropertyDeclaration); + case ts.SyntaxKind.PropertyDeclaration: + if (hasNavigationBarName(node as ts.ClassElement)) { + addNodeWithRecursiveInitializer(node as ts.PropertyDeclaration); } break; - case SyntaxKind.PropertySignature: - if (hasNavigationBarName(node as TypeElement)) { + case ts.SyntaxKind.PropertySignature: + if (hasNavigationBarName(node as ts.TypeElement)) { addLeafNode(node); } break; - case SyntaxKind.ImportClause: - const importClause = node as ImportClause; + case ts.SyntaxKind.ImportClause: + const importClause = node as ts.ImportClause; // Handle default import case e.g.: // import d from "mod"; if (importClause.name) { @@ -264,7 +264,7 @@ namespace ts.NavigationBar { // import {a, b as B} from "mod"; const { namedBindings } = importClause; if (namedBindings) { - if (namedBindings.kind === SyntaxKind.NamespaceImport) { + if (namedBindings.kind === ts.SyntaxKind.NamespaceImport) { addLeafNode(namedBindings); } else { @@ -275,19 +275,19 @@ namespace ts.NavigationBar { } break; - case SyntaxKind.ShorthandPropertyAssignment: - addNodeWithRecursiveChild(node, (node as ShorthandPropertyAssignment).name); + case ts.SyntaxKind.ShorthandPropertyAssignment: + addNodeWithRecursiveChild(node, (node as ts.ShorthandPropertyAssignment).name); break; - case SyntaxKind.SpreadAssignment: - const { expression } = node as SpreadAssignment; + case ts.SyntaxKind.SpreadAssignment: + const { expression } = node as ts.SpreadAssignment; // Use the expression as the name of the SpreadAssignment, otherwise show as . - isIdentifier(expression) ? addLeafNode(node, expression) : addLeafNode(node); + ts.isIdentifier(expression) ? addLeafNode(node, expression) : addLeafNode(node); break; - case SyntaxKind.BindingElement: - case SyntaxKind.PropertyAssignment: - case SyntaxKind.VariableDeclaration: { - const child = node as VariableDeclaration | PropertyAssignment | BindingElement; - if (isBindingPattern(child.name)) { + case ts.SyntaxKind.BindingElement: + case ts.SyntaxKind.PropertyAssignment: + case ts.SyntaxKind.VariableDeclaration: { + const child = node as ts.VariableDeclaration | ts.PropertyAssignment | ts.BindingElement; + if (ts.isBindingPattern(child.name)) { addChildrenRecursively(child.name); } else { @@ -295,22 +295,22 @@ namespace ts.NavigationBar { } break; } - case SyntaxKind.FunctionDeclaration: - const nameNode = (node as FunctionLikeDeclaration).name; + case ts.SyntaxKind.FunctionDeclaration: + const nameNode = (node as ts.FunctionLikeDeclaration).name; // If we see a function declaration track as a possible ES5 class - if (nameNode && isIdentifier(nameNode)) { + if (nameNode && ts.isIdentifier(nameNode)) { addTrackedEs5Class(nameNode.text); } - addNodeWithRecursiveChild(node, (node as FunctionLikeDeclaration).body); + addNodeWithRecursiveChild(node, (node as ts.FunctionLikeDeclaration).body); break; - case SyntaxKind.ArrowFunction: - case SyntaxKind.FunctionExpression: - addNodeWithRecursiveChild(node, (node as FunctionLikeDeclaration).body); + case ts.SyntaxKind.ArrowFunction: + case ts.SyntaxKind.FunctionExpression: + addNodeWithRecursiveChild(node, (node as ts.FunctionLikeDeclaration).body); break; - case SyntaxKind.EnumDeclaration: + case ts.SyntaxKind.EnumDeclaration: startNode(node); - for (const member of (node as EnumDeclaration).members) { + for (const member of (node as ts.EnumDeclaration).members) { if (!isComputedProperty(member)) { addLeafNode(member); } @@ -318,24 +318,24 @@ namespace ts.NavigationBar { endNode(); break; - case SyntaxKind.ClassDeclaration: - case SyntaxKind.ClassExpression: - case SyntaxKind.InterfaceDeclaration: + case ts.SyntaxKind.ClassDeclaration: + case ts.SyntaxKind.ClassExpression: + case ts.SyntaxKind.InterfaceDeclaration: startNode(node); - for (const member of (node as InterfaceDeclaration).members) { + for (const member of (node as ts.InterfaceDeclaration).members) { addChildrenRecursively(member); } endNode(); break; - case SyntaxKind.ModuleDeclaration: - addNodeWithRecursiveChild(node, getInteriorModule(node as ModuleDeclaration).body); + case ts.SyntaxKind.ModuleDeclaration: + addNodeWithRecursiveChild(node, getInteriorModule(node as ts.ModuleDeclaration).body); break; - case SyntaxKind.ExportAssignment: { - const expression = (node as ExportAssignment).expression; - const child = isObjectLiteralExpression(expression) || isCallExpression(expression) ? expression : - isArrowFunction(expression) || isFunctionExpression(expression) ? expression.body : undefined; + case ts.SyntaxKind.ExportAssignment: { + const expression = (node as ts.ExportAssignment).expression; + const child = ts.isObjectLiteralExpression(expression) || ts.isCallExpression(expression) ? expression : + ts.isArrowFunction(expression) || ts.isFunctionExpression(expression) ? expression.body : undefined; if (child) { startNode(node); addChildrenRecursively(child); @@ -346,56 +346,53 @@ namespace ts.NavigationBar { } break; } - case SyntaxKind.ExportSpecifier: - case SyntaxKind.ImportEqualsDeclaration: - case SyntaxKind.IndexSignature: - case SyntaxKind.CallSignature: - case SyntaxKind.ConstructSignature: - case SyntaxKind.TypeAliasDeclaration: + case ts.SyntaxKind.ExportSpecifier: + case ts.SyntaxKind.ImportEqualsDeclaration: + case ts.SyntaxKind.IndexSignature: + case ts.SyntaxKind.CallSignature: + case ts.SyntaxKind.ConstructSignature: + case ts.SyntaxKind.TypeAliasDeclaration: addLeafNode(node); break; - case SyntaxKind.CallExpression: - case SyntaxKind.BinaryExpression: { - const special = getAssignmentDeclarationKind(node as BinaryExpression); + case ts.SyntaxKind.CallExpression: + case ts.SyntaxKind.BinaryExpression: { + const special = ts.getAssignmentDeclarationKind(node as ts.BinaryExpression); switch (special) { - case AssignmentDeclarationKind.ExportsProperty: - case AssignmentDeclarationKind.ModuleExports: - addNodeWithRecursiveChild(node, (node as BinaryExpression).right); + case ts.AssignmentDeclarationKind.ExportsProperty: + case ts.AssignmentDeclarationKind.ModuleExports: + addNodeWithRecursiveChild(node, (node as ts.BinaryExpression).right); return; - case AssignmentDeclarationKind.Prototype: - case AssignmentDeclarationKind.PrototypeProperty: { - const binaryExpression = (node as BinaryExpression); - const assignmentTarget = binaryExpression.left as PropertyAccessExpression; - - const prototypeAccess = special === AssignmentDeclarationKind.PrototypeProperty ? - assignmentTarget.expression as PropertyAccessExpression : + case ts.AssignmentDeclarationKind.Prototype: + case ts.AssignmentDeclarationKind.PrototypeProperty: { + const binaryExpression = (node as ts.BinaryExpression); + const assignmentTarget = binaryExpression.left as ts.PropertyAccessExpression; + const prototypeAccess = special === ts.AssignmentDeclarationKind.PrototypeProperty ? + assignmentTarget.expression as ts.PropertyAccessExpression : assignmentTarget; let depth = 0; - let className: PropertyNameLiteral; + let className: ts.PropertyNameLiteral; // If we see a prototype assignment, start tracking the target as a class // This is only done for simple classes not nested assignments. - if (isIdentifier(prototypeAccess.expression)) { + if (ts.isIdentifier(prototypeAccess.expression)) { addTrackedEs5Class(prototypeAccess.expression.text); className = prototypeAccess.expression; } else { - [depth, className] = startNestedNodes(binaryExpression, prototypeAccess.expression as EntityNameExpression); + [depth, className] = startNestedNodes(binaryExpression, prototypeAccess.expression as ts.EntityNameExpression); } - if (special === AssignmentDeclarationKind.Prototype) { - if (isObjectLiteralExpression(binaryExpression.right)) { + if (special === ts.AssignmentDeclarationKind.Prototype) { + if (ts.isObjectLiteralExpression(binaryExpression.right)) { if (binaryExpression.right.properties.length > 0) { startNode(binaryExpression, className); - forEachChild(binaryExpression.right, addChildrenRecursively); + ts.forEachChild(binaryExpression.right, addChildrenRecursively); endNode(); } } } - else if (isFunctionExpression(binaryExpression.right) || isArrowFunction(binaryExpression.right)) { - addNodeWithRecursiveChild(node, - binaryExpression.right, - className); + else if (ts.isFunctionExpression(binaryExpression.right) || ts.isArrowFunction(binaryExpression.right)) { + addNodeWithRecursiveChild(node, binaryExpression.right, className); } else { startNode(binaryExpression, className); @@ -405,71 +402,71 @@ namespace ts.NavigationBar { endNestedNodes(depth); return; } - case AssignmentDeclarationKind.ObjectDefinePropertyValue: - case AssignmentDeclarationKind.ObjectDefinePrototypeProperty: { - const defineCall = node as BindableObjectDefinePropertyCall; - const className = special === AssignmentDeclarationKind.ObjectDefinePropertyValue ? + case ts.AssignmentDeclarationKind.ObjectDefinePropertyValue: + case ts.AssignmentDeclarationKind.ObjectDefinePrototypeProperty: { + const defineCall = node as ts.BindableObjectDefinePropertyCall; + const className = special === ts.AssignmentDeclarationKind.ObjectDefinePropertyValue ? defineCall.arguments[0] : - (defineCall.arguments[0] as PropertyAccessExpression).expression as EntityNameExpression; + (defineCall.arguments[0] as ts.PropertyAccessExpression).expression as ts.EntityNameExpression; const memberName = defineCall.arguments[1]; const [depth, classNameIdentifier] = startNestedNodes(node, className); startNode(node, classNameIdentifier); - startNode(node, setTextRange(factory.createIdentifier(memberName.text), memberName)); - addChildrenRecursively((node as CallExpression).arguments[2]); + startNode(node, ts.setTextRange(ts.factory.createIdentifier(memberName.text), memberName)); + addChildrenRecursively((node as ts.CallExpression).arguments[2]); endNode(); endNode(); endNestedNodes(depth); return; } - case AssignmentDeclarationKind.Property: { - const binaryExpression = (node as BinaryExpression); - const assignmentTarget = binaryExpression.left as PropertyAccessExpression | BindableElementAccessExpression; + case ts.AssignmentDeclarationKind.Property: { + const binaryExpression = (node as ts.BinaryExpression); + const assignmentTarget = binaryExpression.left as ts.PropertyAccessExpression | ts.BindableElementAccessExpression; const targetFunction = assignmentTarget.expression; - if (isIdentifier(targetFunction) && getElementOrPropertyAccessName(assignmentTarget) !== "prototype" && + if (ts.isIdentifier(targetFunction) && ts.getElementOrPropertyAccessName(assignmentTarget) !== "prototype" && trackedEs5Classes && trackedEs5Classes.has(targetFunction.text)) { - if (isFunctionExpression(binaryExpression.right) || isArrowFunction(binaryExpression.right)) { + if (ts.isFunctionExpression(binaryExpression.right) || ts.isArrowFunction(binaryExpression.right)) { addNodeWithRecursiveChild(node, binaryExpression.right, targetFunction); } - else if (isBindableStaticAccessExpression(assignmentTarget)) { + else if (ts.isBindableStaticAccessExpression(assignmentTarget)) { startNode(binaryExpression, targetFunction); - addNodeWithRecursiveChild(binaryExpression.left, binaryExpression.right, getNameOrArgument(assignmentTarget)); + addNodeWithRecursiveChild(binaryExpression.left, binaryExpression.right, ts.getNameOrArgument(assignmentTarget)); endNode(); } return; } break; } - case AssignmentDeclarationKind.ThisProperty: - case AssignmentDeclarationKind.None: - case AssignmentDeclarationKind.ObjectDefinePropertyExports: + case ts.AssignmentDeclarationKind.ThisProperty: + case ts.AssignmentDeclarationKind.None: + case ts.AssignmentDeclarationKind.ObjectDefinePropertyExports: break; default: - Debug.assertNever(special); + ts.Debug.assertNever(special); } } // falls through default: - if (hasJSDocNodes(node)) { - forEach(node.jsDoc, jsDoc => { - forEach(jsDoc.tags, tag => { - if (isJSDocTypeAlias(tag)) { + if (ts.hasJSDocNodes(node)) { + ts.forEach(node.jsDoc, jsDoc => { + ts.forEach(jsDoc.tags, tag => { + if (ts.isJSDocTypeAlias(tag)) { addLeafNode(tag); } }); }); } - forEachChild(node, addChildrenRecursively); + ts.forEachChild(node, addChildrenRecursively); } } /** Merge declarations of the same kind. */ function mergeChildren(children: NavigationBarNode[], node: NavigationBarNode): void { - const nameToItems = new Map(); - filterMutate(children, (child, index) => { - const declName = child.name || getNameOfDeclaration(child.node as Declaration); + const nameToItems = new ts.Map(); + ts.filterMutate(children, (child, index) => { + const declName = child.name || ts.getNameOfDeclaration(child.node as ts.Declaration); const name = declName && nodeText(declName); if (!name) { // Anonymous items are never merged. @@ -501,43 +498,41 @@ namespace ts.NavigationBar { } }); } - const isEs5ClassMember: Record = { - [AssignmentDeclarationKind.Property]: true, - [AssignmentDeclarationKind.PrototypeProperty]: true, - [AssignmentDeclarationKind.ObjectDefinePropertyValue]: true, - [AssignmentDeclarationKind.ObjectDefinePrototypeProperty]: true, - [AssignmentDeclarationKind.None]: false, - [AssignmentDeclarationKind.ExportsProperty]: false, - [AssignmentDeclarationKind.ModuleExports]: false, - [AssignmentDeclarationKind.ObjectDefinePropertyExports]: false, - [AssignmentDeclarationKind.Prototype]: true, - [AssignmentDeclarationKind.ThisProperty]: false, + const isEs5ClassMember: Record = { + [ts.AssignmentDeclarationKind.Property]: true, + [ts.AssignmentDeclarationKind.PrototypeProperty]: true, + [ts.AssignmentDeclarationKind.ObjectDefinePropertyValue]: true, + [ts.AssignmentDeclarationKind.ObjectDefinePrototypeProperty]: true, + [ts.AssignmentDeclarationKind.None]: false, + [ts.AssignmentDeclarationKind.ExportsProperty]: false, + [ts.AssignmentDeclarationKind.ModuleExports]: false, + [ts.AssignmentDeclarationKind.ObjectDefinePropertyExports]: false, + [ts.AssignmentDeclarationKind.Prototype]: true, + [ts.AssignmentDeclarationKind.ThisProperty]: false, }; function tryMergeEs5Class(a: NavigationBarNode, b: NavigationBarNode, bIndex: number, parent: NavigationBarNode): boolean | undefined { - function isPossibleConstructor(node: Node) { - return isFunctionExpression(node) || isFunctionDeclaration(node) || isVariableDeclaration(node); + function isPossibleConstructor(node: ts.Node) { + return ts.isFunctionExpression(node) || ts.isFunctionDeclaration(node) || ts.isVariableDeclaration(node); } - const bAssignmentDeclarationKind = isBinaryExpression(b.node) || isCallExpression(b.node) ? - getAssignmentDeclarationKind(b.node) : - AssignmentDeclarationKind.None; - - const aAssignmentDeclarationKind = isBinaryExpression(a.node) || isCallExpression(a.node) ? - getAssignmentDeclarationKind(a.node) : - AssignmentDeclarationKind.None; + const bAssignmentDeclarationKind = ts.isBinaryExpression(b.node) || ts.isCallExpression(b.node) ? + ts.getAssignmentDeclarationKind(b.node) : + ts.AssignmentDeclarationKind.None; + const aAssignmentDeclarationKind = ts.isBinaryExpression(a.node) || ts.isCallExpression(a.node) ? + ts.getAssignmentDeclarationKind(a.node) : + ts.AssignmentDeclarationKind.None; // We treat this as an es5 class and merge the nodes in in one of several cases if ((isEs5ClassMember[bAssignmentDeclarationKind] && isEs5ClassMember[aAssignmentDeclarationKind]) // merge two class elements || (isPossibleConstructor(a.node) && isEs5ClassMember[bAssignmentDeclarationKind]) // ctor function & member || (isPossibleConstructor(b.node) && isEs5ClassMember[aAssignmentDeclarationKind]) // member & ctor function - || (isClassDeclaration(a.node) && isSynthesized(a.node) && isEs5ClassMember[bAssignmentDeclarationKind]) // class (generated) & member - || (isClassDeclaration(b.node) && isEs5ClassMember[aAssignmentDeclarationKind]) // member & class (generated) - || (isClassDeclaration(a.node) && isSynthesized(a.node) && isPossibleConstructor(b.node)) // class (generated) & ctor - || (isClassDeclaration(b.node) && isPossibleConstructor(a.node) && isSynthesized(a.node)) // ctor & class (generated) + || (ts.isClassDeclaration(a.node) && isSynthesized(a.node) && isEs5ClassMember[bAssignmentDeclarationKind]) // class (generated) & member + || (ts.isClassDeclaration(b.node) && isEs5ClassMember[aAssignmentDeclarationKind]) // member & class (generated) + || (ts.isClassDeclaration(a.node) && isSynthesized(a.node) && isPossibleConstructor(b.node)) // class (generated) & ctor + || (ts.isClassDeclaration(b.node) && isPossibleConstructor(a.node) && isSynthesized(a.node)) // ctor & class (generated) ) { - let lastANode = a.additionalNodes && lastOrUndefined(a.additionalNodes) || a.node; - - if ((!isClassDeclaration(a.node) && !isClassDeclaration(b.node)) // If neither outline node is a class + let lastANode = a.additionalNodes && ts.lastOrUndefined(a.additionalNodes) || a.node; + if ((!ts.isClassDeclaration(a.node) && !ts.isClassDeclaration(b.node)) // If neither outline node is a class || isPossibleConstructor(a.node) || isPossibleConstructor(b.node) // If either function is a constructor function ) { const ctorFunction = isPossibleConstructor(a.node) ? a.node : @@ -545,17 +540,15 @@ namespace ts.NavigationBar { undefined; if (ctorFunction !== undefined) { - const ctorNode = setTextRange( - factory.createConstructorDeclaration(/* decorators */ undefined, /* modifiers */ undefined, [], /* body */ undefined), - ctorFunction); + const ctorNode = ts.setTextRange(ts.factory.createConstructorDeclaration(/* decorators */ undefined, /* modifiers */ undefined, [], /* body */ undefined), ctorFunction); const ctor = emptyNavigationBarNode(ctorNode); ctor.indent = a.indent + 1; ctor.children = a.node === ctorFunction ? a.children : b.children; - a.children = a.node === ctorFunction ? concatenate([ctor], b.children || [b]) : concatenate(a.children || [{ ...a }], [ctor]); + a.children = a.node === ctorFunction ? ts.concatenate([ctor], b.children || [b]) : ts.concatenate(a.children || [{ ...a }], [ctor]); } else { if (a.children || b.children) { - a.children = concatenate(a.children || [{ ...a }], b.children || [b]); + a.children = ts.concatenate(a.children || [{ ...a }], b.children || [b]); if (a.children) { mergeChildren(a.children, a); sortChildren(a.children); @@ -563,17 +556,14 @@ namespace ts.NavigationBar { } } - lastANode = a.node = setTextRange(factory.createClassDeclaration( + lastANode = a.node = ts.setTextRange(ts.factory.createClassDeclaration( /* decorators */ undefined, - /* modifiers */ undefined, - a.name as Identifier || factory.createIdentifier("__class__"), + /* modifiers */ undefined, a.name as ts.Identifier || ts.factory.createIdentifier("__class__"), /* typeParameters */ undefined, - /* heritageClauses */ undefined, - [] - ), a.node); + /* heritageClauses */ undefined, []), a.node); } else { - a.children = concatenate(a.children, b.children); + a.children = ts.concatenate(a.children, b.children); if (a.children) { mergeChildren(a.children, a); } @@ -587,22 +577,20 @@ namespace ts.NavigationBar { // Ex This will produce 3 outline nodes: C, a, C // function C() {}; let a = 1; C.prototype.m = function () {} if (parent.children![bIndex - 1].node.end === lastANode.end) { - setTextRange(lastANode, { pos: lastANode.pos, end: bNode.end }); + ts.setTextRange(lastANode, { pos: lastANode.pos, end: bNode.end }); } else { - if (!a.additionalNodes) a.additionalNodes = []; - a.additionalNodes.push(setTextRange(factory.createClassDeclaration( + if (!a.additionalNodes) + a.additionalNodes = []; + a.additionalNodes.push(ts.setTextRange(ts.factory.createClassDeclaration( /* decorators */ undefined, - /* modifiers */ undefined, - a.name as Identifier || factory.createIdentifier("__class__"), + /* modifiers */ undefined, a.name as ts.Identifier || ts.factory.createIdentifier("__class__"), /* typeParameters */ undefined, - /* heritageClauses */ undefined, - [] - ), b.node)); + /* heritageClauses */ undefined, []), b.node)); } return true; } - return bAssignmentDeclarationKind === AssignmentDeclarationKind.None ? false : true; + return bAssignmentDeclarationKind === ts.AssignmentDeclarationKind.None ? false : true; } function tryMerge(a: NavigationBarNode, b: NavigationBarNode, bIndex: number, parent: NavigationBarNode): boolean { @@ -618,42 +606,42 @@ namespace ts.NavigationBar { } /** a and b have the same name, but they may not be mergeable. */ - function shouldReallyMerge(a: Node, b: Node, parent: NavigationBarNode): boolean { + function shouldReallyMerge(a: ts.Node, b: ts.Node, parent: NavigationBarNode): boolean { if (a.kind !== b.kind || a.parent !== b.parent && !(isOwnChild(a, parent) && isOwnChild(b, parent))) { return false; } switch (a.kind) { - case SyntaxKind.PropertyDeclaration: - case SyntaxKind.MethodDeclaration: - case SyntaxKind.GetAccessor: - case SyntaxKind.SetAccessor: - return isStatic(a) === isStatic(b); - case SyntaxKind.ModuleDeclaration: - return areSameModule(a as ModuleDeclaration, b as ModuleDeclaration) - && getFullyQualifiedModuleName(a as ModuleDeclaration) === getFullyQualifiedModuleName(b as ModuleDeclaration); + case ts.SyntaxKind.PropertyDeclaration: + case ts.SyntaxKind.MethodDeclaration: + case ts.SyntaxKind.GetAccessor: + case ts.SyntaxKind.SetAccessor: + return ts.isStatic(a) === ts.isStatic(b); + case ts.SyntaxKind.ModuleDeclaration: + return areSameModule(a as ts.ModuleDeclaration, b as ts.ModuleDeclaration) + && getFullyQualifiedModuleName(a as ts.ModuleDeclaration) === getFullyQualifiedModuleName(b as ts.ModuleDeclaration); default: return true; } } - function isSynthesized(node: Node) { - return !!(node.flags & NodeFlags.Synthesized); + function isSynthesized(node: ts.Node) { + return !!(node.flags & ts.NodeFlags.Synthesized); } // We want to merge own children like `I` in in `module A { interface I {} } module A { interface I {} }` // We don't want to merge unrelated children like `m` in `const o = { a: { m() {} }, b: { m() {} } };` - function isOwnChild(n: Node, parent: NavigationBarNode): boolean { - const par = isModuleBlock(n.parent) ? n.parent.parent : n.parent; - return par === parent.node || contains(parent.additionalNodes, par); + function isOwnChild(n: ts.Node, parent: NavigationBarNode): boolean { + const par = ts.isModuleBlock(n.parent) ? n.parent.parent : n.parent; + return par === parent.node || ts.contains(parent.additionalNodes, par); } // We use 1 NavNode to represent 'A.B.C', but there are multiple source nodes. // Only merge module nodes that have the same chain. Don't merge 'A.B.C' with 'A'! - function areSameModule(a: ModuleDeclaration, b: ModuleDeclaration): boolean { + function areSameModule(a: ts.ModuleDeclaration, b: ts.ModuleDeclaration): boolean { if (!a.body || !b.body) { return a.body === b.body; } - return a.body.kind === b.body.kind && (a.body.kind !== SyntaxKind.ModuleDeclaration || areSameModule(a.body as ModuleDeclaration, b.body as ModuleDeclaration)); + return a.body.kind === b.body.kind && (a.body.kind !== ts.SyntaxKind.ModuleDeclaration || areSameModule(a.body as ts.ModuleDeclaration, b.body as ts.ModuleDeclaration)); } /** Merge source into target. Source should be thrown away after this is called. */ @@ -664,7 +652,7 @@ namespace ts.NavigationBar { target.additionalNodes.push(...source.additionalNodes); } - target.children = concatenate(target.children, source.children); + target.children = ts.concatenate(target.children, source.children); if (target.children) { mergeChildren(target.children, target); sortChildren(target.children); @@ -677,8 +665,8 @@ namespace ts.NavigationBar { } function compareChildren(child1: NavigationBarNode, child2: NavigationBarNode) { - return compareStringsCaseSensitiveUI(tryGetName(child1.node)!, tryGetName(child2.node)!) // TODO: GH#18217 - || compareValues(navigationBarNodeKind(child1), navigationBarNodeKind(child2)); + return ts.compareStringsCaseSensitiveUI(tryGetName(child1.node)!, tryGetName(child2.node)!) // TODO: GH#18217 + || ts.compareValues(navigationBarNodeKind(child1), navigationBarNodeKind(child2)); } /** @@ -686,34 +674,34 @@ namespace ts.NavigationBar { * We only sort nodes by name that have a more-or-less "direct" name, as opposed to `new()` and the like. * So `new()` can still come before an `aardvark` method. */ - function tryGetName(node: Node): string | undefined { - if (node.kind === SyntaxKind.ModuleDeclaration) { - return getModuleName(node as ModuleDeclaration); + function tryGetName(node: ts.Node): string | undefined { + if (node.kind === ts.SyntaxKind.ModuleDeclaration) { + return getModuleName(node as ts.ModuleDeclaration); } - const declName = getNameOfDeclaration(node as Declaration); - if (declName && isPropertyName(declName)) { - const propertyName = getPropertyNameForPropertyNameNode(declName); - return propertyName && unescapeLeadingUnderscores(propertyName); + const declName = ts.getNameOfDeclaration(node as ts.Declaration); + if (declName && ts.isPropertyName(declName)) { + const propertyName = ts.getPropertyNameForPropertyNameNode(declName); + return propertyName && ts.unescapeLeadingUnderscores(propertyName); } switch (node.kind) { - case SyntaxKind.FunctionExpression: - case SyntaxKind.ArrowFunction: - case SyntaxKind.ClassExpression: - return getFunctionOrClassName(node as FunctionExpression | ArrowFunction | ClassExpression); + case ts.SyntaxKind.FunctionExpression: + case ts.SyntaxKind.ArrowFunction: + case ts.SyntaxKind.ClassExpression: + return getFunctionOrClassName(node as ts.FunctionExpression | ts.ArrowFunction | ts.ClassExpression); default: return undefined; } } - function getItemName(node: Node, name: Node | undefined): string { - if (node.kind === SyntaxKind.ModuleDeclaration) { - return cleanText(getModuleName(node as ModuleDeclaration)); + function getItemName(node: ts.Node, name: ts.Node | undefined): string { + if (node.kind === ts.SyntaxKind.ModuleDeclaration) { + return cleanText(getModuleName(node as ts.ModuleDeclaration)); } if (name) { - const text = isIdentifier(name) ? name.text - : isElementAccessExpression(name) ? `[${nodeText(name.argumentExpression)}]` + const text = ts.isIdentifier(name) ? name.text + : ts.isElementAccessExpression(name) ? `[${nodeText(name.argumentExpression)}]` : nodeText(name); if (text.length > 0) { return cleanText(text); @@ -721,33 +709,32 @@ namespace ts.NavigationBar { } switch (node.kind) { - case SyntaxKind.SourceFile: - const sourceFile = node as SourceFile; - return isExternalModule(sourceFile) - ? `"${escapeString(getBaseFileName(removeFileExtension(normalizePath(sourceFile.fileName))))}"` + case ts.SyntaxKind.SourceFile: + const sourceFile = node as ts.SourceFile; + return ts.isExternalModule(sourceFile) + ? `"${ts.escapeString(ts.getBaseFileName(ts.removeFileExtension(ts.normalizePath(sourceFile.fileName))))}"` : ""; - case SyntaxKind.ExportAssignment: - return isExportAssignment(node) && node.isExportEquals ? InternalSymbolName.ExportEquals : InternalSymbolName.Default; - - case SyntaxKind.ArrowFunction: - case SyntaxKind.FunctionDeclaration: - case SyntaxKind.FunctionExpression: - case SyntaxKind.ClassDeclaration: - case SyntaxKind.ClassExpression: - if (getSyntacticModifierFlags(node) & ModifierFlags.Default) { + case ts.SyntaxKind.ExportAssignment: + return ts.isExportAssignment(node) && node.isExportEquals ? ts.InternalSymbolName.ExportEquals : ts.InternalSymbolName.Default; + case ts.SyntaxKind.ArrowFunction: + case ts.SyntaxKind.FunctionDeclaration: + case ts.SyntaxKind.FunctionExpression: + case ts.SyntaxKind.ClassDeclaration: + case ts.SyntaxKind.ClassExpression: + if (ts.getSyntacticModifierFlags(node) & ts.ModifierFlags.Default) { return "default"; } // We may get a string with newlines or other whitespace in the case of an object dereference // (eg: "app\n.onactivated"), so we should remove the whitespace for readability in the // navigation bar. - return getFunctionOrClassName(node as ArrowFunction | FunctionExpression | ClassExpression); - case SyntaxKind.Constructor: + return getFunctionOrClassName(node as ts.ArrowFunction | ts.FunctionExpression | ts.ClassExpression); + case ts.SyntaxKind.Constructor: return "constructor"; - case SyntaxKind.ConstructSignature: + case ts.SyntaxKind.ConstructSignature: return "new()"; - case SyntaxKind.CallSignature: + case ts.SyntaxKind.CallSignature: return "()"; - case SyntaxKind.IndexSignature: + case ts.SyntaxKind.IndexSignature: return "[]"; default: return ""; @@ -782,35 +769,35 @@ namespace ts.NavigationBar { // Some nodes are otherwise important enough to always include in the primary navigation menu. switch (navigationBarNodeKind(item)) { - case SyntaxKind.ClassDeclaration: - case SyntaxKind.ClassExpression: - case SyntaxKind.EnumDeclaration: - case SyntaxKind.InterfaceDeclaration: - case SyntaxKind.ModuleDeclaration: - case SyntaxKind.SourceFile: - case SyntaxKind.TypeAliasDeclaration: - case SyntaxKind.JSDocTypedefTag: - case SyntaxKind.JSDocCallbackTag: + case ts.SyntaxKind.ClassDeclaration: + case ts.SyntaxKind.ClassExpression: + case ts.SyntaxKind.EnumDeclaration: + case ts.SyntaxKind.InterfaceDeclaration: + case ts.SyntaxKind.ModuleDeclaration: + case ts.SyntaxKind.SourceFile: + case ts.SyntaxKind.TypeAliasDeclaration: + case ts.SyntaxKind.JSDocTypedefTag: + case ts.SyntaxKind.JSDocCallbackTag: return true; - case SyntaxKind.ArrowFunction: - case SyntaxKind.FunctionDeclaration: - case SyntaxKind.FunctionExpression: + case ts.SyntaxKind.ArrowFunction: + case ts.SyntaxKind.FunctionDeclaration: + case ts.SyntaxKind.FunctionExpression: return isTopLevelFunctionDeclaration(item); default: return false; } function isTopLevelFunctionDeclaration(item: NavigationBarNode): boolean { - if (!(item.node as FunctionDeclaration).body) { + if (!(item.node as ts.FunctionDeclaration).body) { return false; } switch (navigationBarNodeKind(item.parent!)) { - case SyntaxKind.ModuleBlock: - case SyntaxKind.SourceFile: - case SyntaxKind.MethodDeclaration: - case SyntaxKind.Constructor: + case ts.SyntaxKind.ModuleBlock: + case ts.SyntaxKind.SourceFile: + case ts.SyntaxKind.MethodDeclaration: + case ts.SyntaxKind.Constructor: return true; default: return false; @@ -819,34 +806,34 @@ namespace ts.NavigationBar { } } - function convertToTree(n: NavigationBarNode): NavigationTree { + function convertToTree(n: NavigationBarNode): ts.NavigationTree { return { text: getItemName(n.node, n.name), - kind: getNodeKind(n.node), + kind: ts.getNodeKind(n.node), kindModifiers: getModifiers(n.node), spans: getSpans(n), nameSpan: n.name && getNodeSpan(n.name), - childItems: map(n.children, convertToTree) + childItems: ts.map(n.children, convertToTree) }; } - function convertToPrimaryNavBarMenuItem(n: NavigationBarNode): NavigationBarItem { + function convertToPrimaryNavBarMenuItem(n: NavigationBarNode): ts.NavigationBarItem { return { text: getItemName(n.node, n.name), - kind: getNodeKind(n.node), + kind: ts.getNodeKind(n.node), kindModifiers: getModifiers(n.node), spans: getSpans(n), - childItems: map(n.children, convertToSecondaryNavBarMenuItem) || emptyChildItemArray, + childItems: ts.map(n.children, convertToSecondaryNavBarMenuItem) || emptyChildItemArray, indent: n.indent, bolded: false, grayed: false }; - function convertToSecondaryNavBarMenuItem(n: NavigationBarNode): NavigationBarItem { + function convertToSecondaryNavBarMenuItem(n: NavigationBarNode): ts.NavigationBarItem { return { text: getItemName(n.node, n.name), - kind: getNodeKind(n.node), - kindModifiers: getNodeModifiers(n.node), + kind: ts.getNodeKind(n.node), + kindModifiers: ts.getNodeModifiers(n.node), spans: getSpans(n), childItems: emptyChildItemArray, indent: 0, @@ -856,7 +843,7 @@ namespace ts.NavigationBar { } } - function getSpans(n: NavigationBarNode): TextSpan[] { + function getSpans(n: NavigationBarNode): ts.TextSpan[] { const spans = [getNodeSpan(n.node)]; if (n.additionalNodes) { for (const node of n.additionalNodes) { @@ -866,21 +853,21 @@ namespace ts.NavigationBar { return spans; } - function getModuleName(moduleDeclaration: ModuleDeclaration): string { + function getModuleName(moduleDeclaration: ts.ModuleDeclaration): string { // We want to maintain quotation marks. - if (isAmbientModule(moduleDeclaration)) { - return getTextOfNode(moduleDeclaration.name); + if (ts.isAmbientModule(moduleDeclaration)) { + return ts.getTextOfNode(moduleDeclaration.name); } return getFullyQualifiedModuleName(moduleDeclaration); } - function getFullyQualifiedModuleName(moduleDeclaration: ModuleDeclaration): string { + function getFullyQualifiedModuleName(moduleDeclaration: ts.ModuleDeclaration): string { // Otherwise, we need to aggregate each identifier to build up the qualified name. - const result = [getTextOfIdentifierOrLiteral(moduleDeclaration.name)]; - while (moduleDeclaration.body && moduleDeclaration.body.kind === SyntaxKind.ModuleDeclaration) { + const result = [ts.getTextOfIdentifierOrLiteral(moduleDeclaration.name)]; + while (moduleDeclaration.body && moduleDeclaration.body.kind === ts.SyntaxKind.ModuleDeclaration) { moduleDeclaration = moduleDeclaration.body; - result.push(getTextOfIdentifierOrLiteral(moduleDeclaration.name)); + result.push(ts.getTextOfIdentifierOrLiteral(moduleDeclaration.name)); } return result.join("."); } @@ -889,50 +876,50 @@ namespace ts.NavigationBar { * For 'module A.B.C', we want to get the node for 'C'. * We store 'A' as associated with a NavNode, and use getModuleName to traverse down again. */ - function getInteriorModule(decl: ModuleDeclaration): ModuleDeclaration { - return decl.body && isModuleDeclaration(decl.body) ? getInteriorModule(decl.body) : decl; + function getInteriorModule(decl: ts.ModuleDeclaration): ts.ModuleDeclaration { + return decl.body && ts.isModuleDeclaration(decl.body) ? getInteriorModule(decl.body) : decl; } - function isComputedProperty(member: EnumMember): boolean { - return !member.name || member.name.kind === SyntaxKind.ComputedPropertyName; + function isComputedProperty(member: ts.EnumMember): boolean { + return !member.name || member.name.kind === ts.SyntaxKind.ComputedPropertyName; } - function getNodeSpan(node: Node): TextSpan { - return node.kind === SyntaxKind.SourceFile ? createTextSpanFromRange(node) : createTextSpanFromNode(node, curSourceFile); + function getNodeSpan(node: ts.Node): ts.TextSpan { + return node.kind === ts.SyntaxKind.SourceFile ? ts.createTextSpanFromRange(node) : ts.createTextSpanFromNode(node, curSourceFile); } - function getModifiers(node: Node): string { - if (node.parent && node.parent.kind === SyntaxKind.VariableDeclaration) { + function getModifiers(node: ts.Node): string { + if (node.parent && node.parent.kind === ts.SyntaxKind.VariableDeclaration) { node = node.parent; } - return getNodeModifiers(node); + return ts.getNodeModifiers(node); } - function getFunctionOrClassName(node: FunctionExpression | FunctionDeclaration | ArrowFunction | ClassLikeDeclaration): string { + function getFunctionOrClassName(node: ts.FunctionExpression | ts.FunctionDeclaration | ts.ArrowFunction | ts.ClassLikeDeclaration): string { const { parent } = node; - if (node.name && getFullWidth(node.name) > 0) { - return cleanText(declarationNameToString(node.name)); + if (node.name && ts.getFullWidth(node.name) > 0) { + return cleanText(ts.declarationNameToString(node.name)); } // See if it is a var initializer. If so, use the var name. - else if (isVariableDeclaration(parent)) { - return cleanText(declarationNameToString(parent.name)); + else if (ts.isVariableDeclaration(parent)) { + return cleanText(ts.declarationNameToString(parent.name)); } // See if it is of the form " = function(){...}". If so, use the text from the left-hand side. - else if (isBinaryExpression(parent) && parent.operatorToken.kind === SyntaxKind.EqualsToken) { + else if (ts.isBinaryExpression(parent) && parent.operatorToken.kind === ts.SyntaxKind.EqualsToken) { return nodeText(parent.left).replace(whiteSpaceRegex, ""); } // See if it is a property assignment, and if so use the property name - else if (isPropertyAssignment(parent)) { + else if (ts.isPropertyAssignment(parent)) { return nodeText(parent.name); } // Default exports are named "default" - else if (getSyntacticModifierFlags(node) & ModifierFlags.Default) { + else if (ts.getSyntacticModifierFlags(node) & ts.ModifierFlags.Default) { return "default"; } - else if (isClassLike(node)) { + else if (ts.isClassLike(node)) { return ""; } - else if (isCallExpression(parent)) { + else if (ts.isCallExpression(parent)) { let name = getCalledExpressionName(parent.expression); if (name !== undefined) { name = cleanText(name); @@ -941,7 +928,7 @@ namespace ts.NavigationBar { return `${name} callback`; } - const args = cleanText(mapDefined(parent.arguments, a => isStringLiteralLike(a) ? a.getText(curSourceFile) : undefined).join(", ")); + const args = cleanText(ts.mapDefined(parent.arguments, a => ts.isStringLiteralLike(a) ? a.getText(curSourceFile) : undefined).join(", ")); return `${name}(${args}) callback`; } } @@ -949,11 +936,11 @@ namespace ts.NavigationBar { } // See also 'tryGetPropertyAccessOrIdentifierToString' - function getCalledExpressionName(expr: Expression): string | undefined { - if (isIdentifier(expr)) { + function getCalledExpressionName(expr: ts.Expression): string | undefined { + if (ts.isIdentifier(expr)) { return expr.text; } - else if (isPropertyAccessExpression(expr)) { + else if (ts.isPropertyAccessExpression(expr)) { const left = getCalledExpressionName(expr.expression); const right = expr.name.text; return left === undefined ? right : `${left}.${right}`; @@ -963,11 +950,11 @@ namespace ts.NavigationBar { } } - function isFunctionOrClassExpression(node: Node): node is ArrowFunction | FunctionExpression | ClassExpression { + function isFunctionOrClassExpression(node: ts.Node): node is ts.ArrowFunction | ts.FunctionExpression | ts.ClassExpression { switch (node.kind) { - case SyntaxKind.ArrowFunction: - case SyntaxKind.FunctionExpression: - case SyntaxKind.ClassExpression: + case ts.SyntaxKind.ArrowFunction: + case ts.SyntaxKind.FunctionExpression: + case ts.SyntaxKind.ClassExpression: return true; default: return false; diff --git a/src/services/organizeImports.ts b/src/services/organizeImports.ts index 7533a54893397..5740b81ec254a 100644 --- a/src/services/organizeImports.ts +++ b/src/services/organizeImports.ts @@ -7,45 +7,32 @@ namespace ts.OrganizeImports { * 2) Coalescing imports from the same module * 3) Sorting imports */ - export function organizeImports( - sourceFile: SourceFile, - formatContext: formatting.FormatContext, - host: LanguageServiceHost, - program: Program, - preferences: UserPreferences, - skipDestructiveCodeActions?: boolean - ) { - const changeTracker = textChanges.ChangeTracker.fromContext({ host, formatContext, preferences }); - - const coalesceAndOrganizeImports = (importGroup: readonly ImportDeclaration[]) => stableSort( - coalesceImports(removeUnusedImports(importGroup, sourceFile, program, skipDestructiveCodeActions)), - (s1, s2) => compareImportsOrRequireStatements(s1, s2)); + export function organizeImports(sourceFile: ts.SourceFile, formatContext: ts.formatting.FormatContext, host: ts.LanguageServiceHost, program: ts.Program, preferences: ts.UserPreferences, skipDestructiveCodeActions?: boolean) { + const changeTracker = ts.textChanges.ChangeTracker.fromContext({ host, formatContext, preferences }); + const coalesceAndOrganizeImports = (importGroup: readonly ts.ImportDeclaration[]) => ts.stableSort(coalesceImports(removeUnusedImports(importGroup, sourceFile, program, skipDestructiveCodeActions)), (s1, s2) => compareImportsOrRequireStatements(s1, s2)); // All of the old ImportDeclarations in the file, in syntactic order. - const topLevelImportGroupDecls = groupImportsByNewlineContiguous(sourceFile, sourceFile.statements.filter(isImportDeclaration)); + const topLevelImportGroupDecls = groupImportsByNewlineContiguous(sourceFile, sourceFile.statements.filter(ts.isImportDeclaration)); topLevelImportGroupDecls.forEach(importGroupDecl => organizeImportsWorker(importGroupDecl, coalesceAndOrganizeImports)); // All of the old ExportDeclarations in the file, in syntactic order. - const topLevelExportDecls = sourceFile.statements.filter(isExportDeclaration); + const topLevelExportDecls = sourceFile.statements.filter(ts.isExportDeclaration); organizeImportsWorker(topLevelExportDecls, coalesceExports); - for (const ambientModule of sourceFile.statements.filter(isAmbientModule)) { - if (!ambientModule.body) continue; - - const ambientModuleImportGroupDecls = groupImportsByNewlineContiguous(sourceFile, ambientModule.body.statements.filter(isImportDeclaration)); + for (const ambientModule of sourceFile.statements.filter(ts.isAmbientModule)) { + if (!ambientModule.body) + continue; + const ambientModuleImportGroupDecls = groupImportsByNewlineContiguous(sourceFile, ambientModule.body.statements.filter(ts.isImportDeclaration)); ambientModuleImportGroupDecls.forEach(importGroupDecl => organizeImportsWorker(importGroupDecl, coalesceAndOrganizeImports)); - const ambientModuleExportDecls = ambientModule.body.statements.filter(isExportDeclaration); + const ambientModuleExportDecls = ambientModule.body.statements.filter(ts.isExportDeclaration); organizeImportsWorker(ambientModuleExportDecls, coalesceExports); } return changeTracker.getChanges(); - function organizeImportsWorker( - oldImportDecls: readonly T[], - coalesce: (group: readonly T[]) => readonly T[]) { - - if (length(oldImportDecls) === 0) { + function organizeImportsWorker(oldImportDecls: readonly T[], coalesce: (group: readonly T[]) => readonly T[]) { + if (ts.length(oldImportDecls) === 0) { return; } @@ -54,12 +41,10 @@ namespace ts.OrganizeImports { // on the first import because it is probably the header comment for the file. // Consider: we could do a more careful check that this trivia is actually a header, // but the consequences of being wrong are very minor. - suppressLeadingTrivia(oldImportDecls[0]); - - const oldImportGroups = group(oldImportDecls, importDecl => getExternalModuleName(importDecl.moduleSpecifier!)!); - const sortedImportGroups = stableSort(oldImportGroups, (group1, group2) => compareModuleSpecifiers(group1[0].moduleSpecifier, group2[0].moduleSpecifier)); - const newImportDecls = flatMap(sortedImportGroups, importGroup => - getExternalModuleName(importGroup[0].moduleSpecifier!) + ts.suppressLeadingTrivia(oldImportDecls[0]); + const oldImportGroups = ts.group(oldImportDecls, importDecl => getExternalModuleName(importDecl.moduleSpecifier!)!); + const sortedImportGroups = ts.stableSort(oldImportGroups, (group1, group2) => compareModuleSpecifiers(group1[0].moduleSpecifier, group2[0].moduleSpecifier)); + const newImportDecls = ts.flatMap(sortedImportGroups, importGroup => getExternalModuleName(importGroup[0].moduleSpecifier!) ? coalesce(importGroup) : importGroup); @@ -68,28 +53,28 @@ namespace ts.OrganizeImports { // Consider the first node to have trailingTrivia as we want to exclude the // "header" comment. changeTracker.deleteNodes(sourceFile, oldImportDecls, { - trailingTriviaOption: textChanges.TrailingTriviaOption.Include, + trailingTriviaOption: ts.textChanges.TrailingTriviaOption.Include, }, /*hasTrailingComment*/ true); } else { // Note: Delete the surrounding trivia because it will have been retained in newImportDecls. const replaceOptions = { - leadingTriviaOption: textChanges.LeadingTriviaOption.Exclude, // Leave header comment in place - trailingTriviaOption: textChanges.TrailingTriviaOption.Include, - suffix: getNewLineOrDefaultFromHost(host, formatContext.options), + leadingTriviaOption: ts.textChanges.LeadingTriviaOption.Exclude, + trailingTriviaOption: ts.textChanges.TrailingTriviaOption.Include, + suffix: ts.getNewLineOrDefaultFromHost(host, formatContext.options), }; changeTracker.replaceNodeWithNodes(sourceFile, oldImportDecls[0], newImportDecls, replaceOptions); const hasTrailingComment = changeTracker.nodeHasTrailingComment(sourceFile, oldImportDecls[0], replaceOptions); changeTracker.deleteNodes(sourceFile, oldImportDecls.slice(1), { - trailingTriviaOption: textChanges.TrailingTriviaOption.Include, + trailingTriviaOption: ts.textChanges.TrailingTriviaOption.Include, }, hasTrailingComment); } } } - function groupImportsByNewlineContiguous(sourceFile: SourceFile, importDecls: ImportDeclaration[]): ImportDeclaration[][] { - const scanner = createScanner(sourceFile.languageVersion, /*skipTrivia*/ false, sourceFile.languageVariant); - const groupImports: ImportDeclaration[][] = []; + function groupImportsByNewlineContiguous(sourceFile: ts.SourceFile, importDecls: ts.ImportDeclaration[]): ts.ImportDeclaration[][] { + const scanner = ts.createScanner(sourceFile.languageVersion, /*skipTrivia*/ false, sourceFile.languageVariant); + const groupImports: ts.ImportDeclaration[][] = []; let groupIndex = 0; for (const topLevelImportDecl of importDecls) { if (isNewGroup(sourceFile, topLevelImportDecl, scanner)) { @@ -108,7 +93,7 @@ namespace ts.OrganizeImports { // a new group is created if an import includes at least two new line // new line from multi-line comment doesn't count - function isNewGroup(sourceFile: SourceFile, topLevelImportDecl: ImportDeclaration, scanner: Scanner) { + function isNewGroup(sourceFile: ts.SourceFile, topLevelImportDecl: ts.ImportDeclaration, scanner: ts.Scanner) { const startPos = topLevelImportDecl.getFullStart(); const endPos = topLevelImportDecl.getStart(); scanner.setText(sourceFile.text, startPos, endPos - startPos); @@ -117,7 +102,7 @@ namespace ts.OrganizeImports { while (scanner.getTokenPos() < endPos) { const tokenKind = scanner.scan(); - if (tokenKind === SyntaxKind.NewLineTrivia) { + if (tokenKind === ts.SyntaxKind.NewLineTrivia) { numberOfNewLines++; if (numberOfNewLines >= 2) { @@ -129,7 +114,7 @@ namespace ts.OrganizeImports { return false; } - function removeUnusedImports(oldImports: readonly ImportDeclaration[], sourceFile: SourceFile, program: Program, skipDestructiveCodeActions: boolean | undefined) { + function removeUnusedImports(oldImports: readonly ts.ImportDeclaration[], sourceFile: ts.SourceFile, program: ts.Program, skipDestructiveCodeActions: boolean | undefined) { // As a precaution, consider unused import detection to be destructive (GH #43051) if (skipDestructiveCodeActions) { return oldImports; @@ -139,9 +124,8 @@ namespace ts.OrganizeImports { const compilerOptions = program.getCompilerOptions(); const jsxNamespace = typeChecker.getJsxNamespace(sourceFile); const jsxFragmentFactory = typeChecker.getJsxFragmentFactory(sourceFile); - const jsxElementsPresent = !!(sourceFile.transformFlags & TransformFlags.ContainsJsx); - - const usedImports: ImportDeclaration[] = []; + const jsxElementsPresent = !!(sourceFile.transformFlags & ts.TransformFlags.ContainsJsx); + const usedImports: ts.ImportDeclaration[] = []; for (const importDecl of oldImports) { const { importClause, moduleSpecifier } = importDecl; @@ -160,7 +144,7 @@ namespace ts.OrganizeImports { } if (namedBindings) { - if (isNamespaceImport(namedBindings)) { + if (ts.isNamespaceImport(namedBindings)) { // Namespace import if (!isDeclarationUsed(namedBindings.name)) { namedBindings = undefined; @@ -171,7 +155,7 @@ namespace ts.OrganizeImports { const newElements = namedBindings.elements.filter(e => isDeclarationUsed(e.name)); if (newElements.length < namedBindings.elements.length) { namedBindings = newElements.length - ? factory.updateNamedImports(namedBindings, newElements) + ? ts.factory.updateNamedImports(namedBindings, newElements) : undefined; } } @@ -184,11 +168,8 @@ namespace ts.OrganizeImports { else if (hasModuleDeclarationMatchingSpecifier(sourceFile, moduleSpecifier)) { // If we’re in a declaration file, it’s safe to remove the import clause from it if (sourceFile.isDeclarationFile) { - usedImports.push(factory.createImportDeclaration( - importDecl.decorators, - importDecl.modifiers, - /*importClause*/ undefined, - moduleSpecifier, + usedImports.push(ts.factory.createImportDeclaration(importDecl.decorators, importDecl.modifiers, + /*importClause*/ undefined, moduleSpecifier, /*assertClause*/ undefined)); } // If we’re not in a declaration file, we can’t remove the import clause even though @@ -202,22 +183,21 @@ namespace ts.OrganizeImports { return usedImports; - function isDeclarationUsed(identifier: Identifier) { + function isDeclarationUsed(identifier: ts.Identifier) { // The JSX factory symbol is always used if JSX elements are present - even if they are not allowed. - return jsxElementsPresent && (identifier.text === jsxNamespace || jsxFragmentFactory && identifier.text === jsxFragmentFactory) && jsxModeNeedsExplicitImport(compilerOptions.jsx) || - FindAllReferences.Core.isSymbolReferencedInFile(identifier, typeChecker, sourceFile); + return jsxElementsPresent && (identifier.text === jsxNamespace || jsxFragmentFactory && identifier.text === jsxFragmentFactory) && ts.jsxModeNeedsExplicitImport(compilerOptions.jsx) || + ts.FindAllReferences.Core.isSymbolReferencedInFile(identifier, typeChecker, sourceFile); } } - function hasModuleDeclarationMatchingSpecifier(sourceFile: SourceFile, moduleSpecifier: Expression) { - const moduleSpecifierText = isStringLiteral(moduleSpecifier) && moduleSpecifier.text; - return isString(moduleSpecifierText) && some(sourceFile.moduleAugmentations, moduleName => - isStringLiteral(moduleName) + function hasModuleDeclarationMatchingSpecifier(sourceFile: ts.SourceFile, moduleSpecifier: ts.Expression) { + const moduleSpecifierText = ts.isStringLiteral(moduleSpecifier) && moduleSpecifier.text; + return ts.isString(moduleSpecifierText) && ts.some(sourceFile.moduleAugmentations, moduleName => ts.isStringLiteral(moduleName) && moduleName.text === moduleSpecifierText); } - function getExternalModuleName(specifier: Expression) { - return specifier !== undefined && isStringLiteralLike(specifier) + function getExternalModuleName(specifier: ts.Expression) { + return specifier !== undefined && ts.isStringLiteralLike(specifier) ? specifier.text : undefined; } @@ -226,14 +206,14 @@ namespace ts.OrganizeImports { /** * @param importGroup a list of ImportDeclarations, all with the same module name. */ - export function coalesceImports(importGroup: readonly ImportDeclaration[]) { + export function coalesceImports(importGroup: readonly ts.ImportDeclaration[]) { if (importGroup.length === 0) { return importGroup; } const { importWithoutClause, typeOnlyImports, regularImports } = getCategorizedImports(importGroup); - const coalescedImports: ImportDeclaration[] = []; + const coalescedImports: ts.ImportDeclaration[] = []; if (importWithoutClause) { coalescedImports.push(importWithoutClause); @@ -247,34 +227,30 @@ namespace ts.OrganizeImports { if (!isTypeOnly && defaultImports.length === 1 && namespaceImports.length === 1 && namedImports.length === 0) { // Add the namespace import to the existing default ImportDeclaration. const defaultImport = defaultImports[0]; - coalescedImports.push( - updateImportDeclarationAndClause(defaultImport, defaultImport.importClause!.name, namespaceImports[0].importClause!.namedBindings)); // TODO: GH#18217 + coalescedImports.push(updateImportDeclarationAndClause(defaultImport, defaultImport.importClause!.name, namespaceImports[0].importClause!.namedBindings)); // TODO: GH#18217 continue; } - const sortedNamespaceImports = stableSort(namespaceImports, (i1, i2) => - compareIdentifiers((i1.importClause!.namedBindings as NamespaceImport).name, (i2.importClause!.namedBindings as NamespaceImport).name)); // TODO: GH#18217 + const sortedNamespaceImports = ts.stableSort(namespaceImports, (i1, i2) => compareIdentifiers((i1.importClause!.namedBindings as ts.NamespaceImport).name, (i2.importClause!.namedBindings as ts.NamespaceImport).name)); // TODO: GH#18217 for (const namespaceImport of sortedNamespaceImports) { // Drop the name, if any - coalescedImports.push( - updateImportDeclarationAndClause(namespaceImport, /*name*/ undefined, namespaceImport.importClause!.namedBindings)); // TODO: GH#18217 + coalescedImports.push(updateImportDeclarationAndClause(namespaceImport, /*name*/ undefined, namespaceImport.importClause!.namedBindings)); // TODO: GH#18217 } if (defaultImports.length === 0 && namedImports.length === 0) { continue; } - let newDefaultImport: Identifier | undefined; - const newImportSpecifiers: ImportSpecifier[] = []; + let newDefaultImport: ts.Identifier | undefined; + const newImportSpecifiers: ts.ImportSpecifier[] = []; if (defaultImports.length === 1) { newDefaultImport = defaultImports[0].importClause!.name; } else { for (const defaultImport of defaultImports) { - newImportSpecifiers.push( - factory.createImportSpecifier(/*isTypeOnly*/ false, factory.createIdentifier("default"), defaultImport.importClause!.name!)); // TODO: GH#18217 + newImportSpecifiers.push(ts.factory.createImportSpecifier(/*isTypeOnly*/ false, ts.factory.createIdentifier("default"), defaultImport.importClause!.name!)); // TODO: GH#18217 } } @@ -288,23 +264,20 @@ namespace ts.OrganizeImports { const newNamedImports = sortedImportSpecifiers.length === 0 ? newDefaultImport ? undefined - : factory.createNamedImports(emptyArray) + : ts.factory.createNamedImports(ts.emptyArray) : namedImports.length === 0 - ? factory.createNamedImports(sortedImportSpecifiers) - : factory.updateNamedImports(namedImports[0].importClause!.namedBindings as NamedImports, sortedImportSpecifiers); // TODO: GH#18217 + ? ts.factory.createNamedImports(sortedImportSpecifiers) + : ts.factory.updateNamedImports(namedImports[0].importClause!.namedBindings as ts.NamedImports, sortedImportSpecifiers); // TODO: GH#18217 // Type-only imports are not allowed to mix default, namespace, and named imports in any combination. // We could rewrite a default import as a named import (`import { default as name }`), but we currently // choose not to as a stylistic preference. if (isTypeOnly && newDefaultImport && newNamedImports) { - coalescedImports.push( - updateImportDeclarationAndClause(importDecl, newDefaultImport, /*namedBindings*/ undefined)); - coalescedImports.push( - updateImportDeclarationAndClause(namedImports[0] ?? importDecl, /*name*/ undefined, newNamedImports)); + coalescedImports.push(updateImportDeclarationAndClause(importDecl, newDefaultImport, /*namedBindings*/ undefined)); + coalescedImports.push(updateImportDeclarationAndClause(namedImports[0] ?? importDecl, /*name*/ undefined, newNamedImports)); } else { - coalescedImports.push( - updateImportDeclarationAndClause(importDecl, newDefaultImport, newNamedImports)); + coalescedImports.push(updateImportDeclarationAndClause(importDecl, newDefaultImport, newNamedImports)); } } @@ -313,9 +286,9 @@ namespace ts.OrganizeImports { } interface ImportGroup { - defaultImports: ImportDeclaration[]; - namespaceImports: ImportDeclaration[]; - namedImports: ImportDeclaration[]; + defaultImports: ts.ImportDeclaration[]; + namespaceImports: ts.ImportDeclaration[]; + namedImports: ts.ImportDeclaration[]; } /* @@ -325,8 +298,8 @@ namespace ts.OrganizeImports { * * NB: There may be overlap between `defaultImports` and `namespaceImports`/`namedImports`. */ - function getCategorizedImports(importGroup: readonly ImportDeclaration[]) { - let importWithoutClause: ImportDeclaration | undefined; + function getCategorizedImports(importGroup: readonly ts.ImportDeclaration[]) { + let importWithoutClause: ts.ImportDeclaration | undefined; const typeOnlyImports: ImportGroup = { defaultImports: [], namespaceImports: [], namedImports: [] }; const regularImports: ImportGroup = { defaultImports: [], namespaceImports: [], namedImports: [] }; @@ -346,7 +319,7 @@ namespace ts.OrganizeImports { } if (namedBindings) { - if (isNamespaceImport(namedBindings)) { + if (ts.isNamespaceImport(namedBindings)) { group.namespaceImports.push(importDeclaration); } else { @@ -366,14 +339,14 @@ namespace ts.OrganizeImports { /** * @param exportGroup a list of ExportDeclarations, all with the same module name. */ - export function coalesceExports(exportGroup: readonly ExportDeclaration[]) { + export function coalesceExports(exportGroup: readonly ts.ExportDeclaration[]) { if (exportGroup.length === 0) { return exportGroup; } const { exportWithoutClause, namedExports, typeOnlyExports } = getCategorizedExports(exportGroup); - const coalescedExports: ExportDeclaration[] = []; + const coalescedExports: ts.ExportDeclaration[] = []; if (exportWithoutClause) { coalescedExports.push(exportWithoutClause); @@ -383,25 +356,15 @@ namespace ts.OrganizeImports { if (exportGroup.length === 0) { continue; } - const newExportSpecifiers: ExportSpecifier[] = []; - newExportSpecifiers.push(...flatMap(exportGroup, i => i.exportClause && isNamedExports(i.exportClause) ? i.exportClause.elements : emptyArray)); + const newExportSpecifiers: ts.ExportSpecifier[] = []; + newExportSpecifiers.push(...ts.flatMap(exportGroup, i => i.exportClause && ts.isNamedExports(i.exportClause) ? i.exportClause.elements : ts.emptyArray)); const sortedExportSpecifiers = sortSpecifiers(newExportSpecifiers); const exportDecl = exportGroup[0]; - coalescedExports.push( - factory.updateExportDeclaration( - exportDecl, - exportDecl.decorators, - exportDecl.modifiers, - exportDecl.isTypeOnly, - exportDecl.exportClause && ( - isNamedExports(exportDecl.exportClause) ? - factory.updateNamedExports(exportDecl.exportClause, sortedExportSpecifiers) : - factory.updateNamespaceExport(exportDecl.exportClause, exportDecl.exportClause.name) - ), - exportDecl.moduleSpecifier, - exportDecl.assertClause)); + coalescedExports.push(ts.factory.updateExportDeclaration(exportDecl, exportDecl.decorators, exportDecl.modifiers, exportDecl.isTypeOnly, exportDecl.exportClause && (ts.isNamedExports(exportDecl.exportClause) ? + ts.factory.updateNamedExports(exportDecl.exportClause, sortedExportSpecifiers) : + ts.factory.updateNamespaceExport(exportDecl.exportClause, exportDecl.exportClause.name)), exportDecl.moduleSpecifier, exportDecl.assertClause)); } return coalescedExports; @@ -411,10 +374,10 @@ namespace ts.OrganizeImports { * may lack parent pointers. The desired parts can easily be recovered based on the * categorization. */ - function getCategorizedExports(exportGroup: readonly ExportDeclaration[]) { - let exportWithoutClause: ExportDeclaration | undefined; - const namedExports: ExportDeclaration[] = []; - const typeOnlyExports: ExportDeclaration[] = []; + function getCategorizedExports(exportGroup: readonly ts.ExportDeclaration[]) { + let exportWithoutClause: ts.ExportDeclaration | undefined; + const namedExports: ts.ExportDeclaration[] = []; + const typeOnlyExports: ts.ExportDeclaration[] = []; for (const exportDeclaration of exportGroup) { if (exportDeclaration.exportClause === undefined) { @@ -438,78 +401,67 @@ namespace ts.OrganizeImports { } } - function updateImportDeclarationAndClause( - importDeclaration: ImportDeclaration, - name: Identifier | undefined, - namedBindings: NamedImportBindings | undefined) { - - return factory.updateImportDeclaration( - importDeclaration, - importDeclaration.decorators, - importDeclaration.modifiers, - factory.updateImportClause(importDeclaration.importClause!, importDeclaration.importClause!.isTypeOnly, name, namedBindings), // TODO: GH#18217 - importDeclaration.moduleSpecifier, - importDeclaration.assertClause); + function updateImportDeclarationAndClause(importDeclaration: ts.ImportDeclaration, name: ts.Identifier | undefined, namedBindings: ts.NamedImportBindings | undefined) { + return ts.factory.updateImportDeclaration(importDeclaration, importDeclaration.decorators, importDeclaration.modifiers, ts.factory.updateImportClause(importDeclaration.importClause!, importDeclaration.importClause!.isTypeOnly, name, namedBindings), // TODO: GH#18217 + importDeclaration.moduleSpecifier, importDeclaration.assertClause); } - - function sortSpecifiers(specifiers: readonly T[]) { - return stableSort(specifiers, compareImportOrExportSpecifiers); + function sortSpecifiers(specifiers: readonly T[]) { + return ts.stableSort(specifiers, compareImportOrExportSpecifiers); } - - export function compareImportOrExportSpecifiers(s1: T, s2: T) { - return compareBooleans(s1.isTypeOnly, s2.isTypeOnly) + export function compareImportOrExportSpecifiers(s1: T, s2: T) { + return ts.compareBooleans(s1.isTypeOnly, s2.isTypeOnly) || compareIdentifiers(s1.propertyName || s1.name, s2.propertyName || s2.name) || compareIdentifiers(s1.name, s2.name); } /* internal */ // Exported for testing - export function compareModuleSpecifiers(m1: Expression | undefined, m2: Expression | undefined) { + export function compareModuleSpecifiers(m1: ts.Expression | undefined, m2: ts.Expression | undefined) { const name1 = m1 === undefined ? undefined : getExternalModuleName(m1); const name2 = m2 === undefined ? undefined : getExternalModuleName(m2); - return compareBooleans(name1 === undefined, name2 === undefined) || - compareBooleans(isExternalModuleNameRelative(name1!), isExternalModuleNameRelative(name2!)) || - compareStringsCaseInsensitive(name1!, name2!); + return ts.compareBooleans(name1 === undefined, name2 === undefined) || + ts.compareBooleans(ts.isExternalModuleNameRelative(name1!), ts.isExternalModuleNameRelative(name2!)) || + ts.compareStringsCaseInsensitive(name1!, name2!); } - function compareIdentifiers(s1: Identifier, s2: Identifier) { - return compareStringsCaseInsensitive(s1.text, s2.text); + function compareIdentifiers(s1: ts.Identifier, s2: ts.Identifier) { + return ts.compareStringsCaseInsensitive(s1.text, s2.text); } - function getModuleSpecifierExpression(declaration: AnyImportOrRequireStatement): Expression | undefined { + function getModuleSpecifierExpression(declaration: ts.AnyImportOrRequireStatement): ts.Expression | undefined { switch (declaration.kind) { - case SyntaxKind.ImportEqualsDeclaration: - return tryCast(declaration.moduleReference, isExternalModuleReference)?.expression; - case SyntaxKind.ImportDeclaration: + case ts.SyntaxKind.ImportEqualsDeclaration: + return ts.tryCast(declaration.moduleReference, ts.isExternalModuleReference)?.expression; + case ts.SyntaxKind.ImportDeclaration: return declaration.moduleSpecifier; - case SyntaxKind.VariableStatement: + case ts.SyntaxKind.VariableStatement: return declaration.declarationList.declarations[0].initializer.arguments[0]; } } - export function importsAreSorted(imports: readonly AnyImportOrRequireStatement[]): imports is SortedReadonlyArray { - return arrayIsSorted(imports, compareImportsOrRequireStatements); + export function importsAreSorted(imports: readonly ts.AnyImportOrRequireStatement[]): imports is ts.SortedReadonlyArray { + return ts.arrayIsSorted(imports, compareImportsOrRequireStatements); } - export function importSpecifiersAreSorted(imports: readonly ImportSpecifier[]): imports is SortedReadonlyArray { - return arrayIsSorted(imports, compareImportOrExportSpecifiers); + export function importSpecifiersAreSorted(imports: readonly ts.ImportSpecifier[]): imports is ts.SortedReadonlyArray { + return ts.arrayIsSorted(imports, compareImportOrExportSpecifiers); } - export function getImportDeclarationInsertionIndex(sortedImports: SortedReadonlyArray, newImport: AnyImportOrRequireStatement) { - const index = binarySearch(sortedImports, newImport, identity, compareImportsOrRequireStatements); + export function getImportDeclarationInsertionIndex(sortedImports: ts.SortedReadonlyArray, newImport: ts.AnyImportOrRequireStatement) { + const index = ts.binarySearch(sortedImports, newImport, ts.identity, compareImportsOrRequireStatements); return index < 0 ? ~index : index; } - export function getImportSpecifierInsertionIndex(sortedImports: SortedReadonlyArray, newImport: ImportSpecifier) { - const index = binarySearch(sortedImports, newImport, identity, compareImportOrExportSpecifiers); + export function getImportSpecifierInsertionIndex(sortedImports: ts.SortedReadonlyArray, newImport: ts.ImportSpecifier) { + const index = ts.binarySearch(sortedImports, newImport, ts.identity, compareImportOrExportSpecifiers); return index < 0 ? ~index : index; } - export function compareImportsOrRequireStatements(s1: AnyImportOrRequireStatement, s2: AnyImportOrRequireStatement) { + export function compareImportsOrRequireStatements(s1: ts.AnyImportOrRequireStatement, s2: ts.AnyImportOrRequireStatement) { return compareModuleSpecifiers(getModuleSpecifierExpression(s1), getModuleSpecifierExpression(s2)) || compareImportKind(s1, s2); } - function compareImportKind(s1: AnyImportOrRequireStatement, s2: AnyImportOrRequireStatement) { - return compareValues(getImportKindOrder(s1), getImportKindOrder(s2)); + function compareImportKind(s1: ts.AnyImportOrRequireStatement, s2: ts.AnyImportOrRequireStatement) { + return ts.compareValues(getImportKindOrder(s1), getImportKindOrder(s2)); } // 1. Side-effect imports @@ -519,33 +471,33 @@ namespace ts.OrganizeImports { // 5. Named imports // 6. ImportEqualsDeclarations // 7. Require variable statements - function getImportKindOrder(s1: AnyImportOrRequireStatement) { + function getImportKindOrder(s1: ts.AnyImportOrRequireStatement) { switch (s1.kind) { - case SyntaxKind.ImportDeclaration: - if (!s1.importClause) return 0; - if (s1.importClause.isTypeOnly) return 1; - if (s1.importClause.namedBindings?.kind === SyntaxKind.NamespaceImport) return 2; - if (s1.importClause.name) return 3; + case ts.SyntaxKind.ImportDeclaration: + if (!s1.importClause) + return 0; + if (s1.importClause.isTypeOnly) + return 1; + if (s1.importClause.namedBindings?.kind === ts.SyntaxKind.NamespaceImport) + return 2; + if (s1.importClause.name) + return 3; return 4; - case SyntaxKind.ImportEqualsDeclaration: + case ts.SyntaxKind.ImportEqualsDeclaration: return 5; - case SyntaxKind.VariableStatement: + case ts.SyntaxKind.VariableStatement: return 6; } } - function getNewImportSpecifiers(namedImports: ImportDeclaration[]) { - return flatMap(namedImports, namedImport => - map(tryGetNamedBindingElements(namedImport), importSpecifier => - importSpecifier.name && importSpecifier.propertyName && importSpecifier.name.escapedText === importSpecifier.propertyName.escapedText - ? factory.updateImportSpecifier(importSpecifier, importSpecifier.isTypeOnly, /*propertyName*/ undefined, importSpecifier.name) - : importSpecifier - ) - ); + function getNewImportSpecifiers(namedImports: ts.ImportDeclaration[]) { + return ts.flatMap(namedImports, namedImport => ts.map(tryGetNamedBindingElements(namedImport), importSpecifier => importSpecifier.name && importSpecifier.propertyName && importSpecifier.name.escapedText === importSpecifier.propertyName.escapedText + ? ts.factory.updateImportSpecifier(importSpecifier, importSpecifier.isTypeOnly, /*propertyName*/ undefined, importSpecifier.name) + : importSpecifier)); } - function tryGetNamedBindingElements(namedImport: ImportDeclaration) { - return namedImport.importClause?.namedBindings && isNamedImports(namedImport.importClause.namedBindings) + function tryGetNamedBindingElements(namedImport: ts.ImportDeclaration) { + return namedImport.importClause?.namedBindings && ts.isNamedImports(namedImport.importClause.namedBindings) ? namedImport.importClause.namedBindings.elements : undefined; } diff --git a/src/services/outliningElementsCollector.ts b/src/services/outliningElementsCollector.ts index ee06b0c3a6833..b0c468947fe20 100644 --- a/src/services/outliningElementsCollector.ts +++ b/src/services/outliningElementsCollector.ts @@ -1,67 +1,70 @@ /* @internal */ namespace ts.OutliningElementsCollector { - export function collectElements(sourceFile: SourceFile, cancellationToken: CancellationToken): OutliningSpan[] { - const res: OutliningSpan[] = []; + export function collectElements(sourceFile: ts.SourceFile, cancellationToken: ts.CancellationToken): ts.OutliningSpan[] { + const res: ts.OutliningSpan[] = []; addNodeOutliningSpans(sourceFile, cancellationToken, res); addRegionOutliningSpans(sourceFile, res); return res.sort((span1, span2) => span1.textSpan.start - span2.textSpan.start); } - function addNodeOutliningSpans(sourceFile: SourceFile, cancellationToken: CancellationToken, out: Push): void { + function addNodeOutliningSpans(sourceFile: ts.SourceFile, cancellationToken: ts.CancellationToken, out: ts.Push): void { let depthRemaining = 40; let current = 0; // Includes the EOF Token so that comments which aren't attached to statements are included const statements = [...sourceFile.statements, sourceFile.endOfFileToken]; const n = statements.length; while (current < n) { - while (current < n && !isAnyImportSyntax(statements[current])) { + while (current < n && !ts.isAnyImportSyntax(statements[current])) { visitNonImportNode(statements[current]); current++; } - if (current === n) break; + if (current === n) + break; const firstImport = current; - while (current < n && isAnyImportSyntax(statements[current])) { + while (current < n && ts.isAnyImportSyntax(statements[current])) { addOutliningForLeadingCommentsForNode(statements[current], sourceFile, cancellationToken, out); current++; } const lastImport = current - 1; if (lastImport !== firstImport) { - out.push(createOutliningSpanFromBounds(findChildOfKind(statements[firstImport], SyntaxKind.ImportKeyword, sourceFile)!.getStart(sourceFile), statements[lastImport].getEnd(), OutliningSpanKind.Imports)); + out.push(createOutliningSpanFromBounds(ts.findChildOfKind(statements[firstImport], ts.SyntaxKind.ImportKeyword, sourceFile)!.getStart(sourceFile), statements[lastImport].getEnd(), ts.OutliningSpanKind.Imports)); } } - function visitNonImportNode(n: Node) { - if (depthRemaining === 0) return; + function visitNonImportNode(n: ts.Node) { + if (depthRemaining === 0) + return; cancellationToken.throwIfCancellationRequested(); - if (isDeclaration(n) || isVariableStatement(n) || isReturnStatement(n) || isCallOrNewExpression(n) || n.kind === SyntaxKind.EndOfFileToken) { + if (ts.isDeclaration(n) || ts.isVariableStatement(n) || ts.isReturnStatement(n) || ts.isCallOrNewExpression(n) || n.kind === ts.SyntaxKind.EndOfFileToken) { addOutliningForLeadingCommentsForNode(n, sourceFile, cancellationToken, out); } - if (isFunctionLike(n) && isBinaryExpression(n.parent) && isPropertyAccessExpression(n.parent.left)) { + if (ts.isFunctionLike(n) && ts.isBinaryExpression(n.parent) && ts.isPropertyAccessExpression(n.parent.left)) { addOutliningForLeadingCommentsForNode(n.parent.left, sourceFile, cancellationToken, out); } - if (isBlock(n) || isModuleBlock(n)) { + if (ts.isBlock(n) || ts.isModuleBlock(n)) { addOutliningForLeadingCommentsForPos(n.statements.end, sourceFile, cancellationToken, out); } - if (isClassLike(n) || isInterfaceDeclaration(n)) { + if (ts.isClassLike(n) || ts.isInterfaceDeclaration(n)) { addOutliningForLeadingCommentsForPos(n.members.end, sourceFile, cancellationToken, out); } const span = getOutliningSpanForNode(n, sourceFile); - if (span) out.push(span); + if (span) + out.push(span); depthRemaining--; - if (isCallExpression(n)) { + if (ts.isCallExpression(n)) { depthRemaining++; visitNonImportNode(n.expression); depthRemaining--; n.arguments.forEach(visitNonImportNode); n.typeArguments?.forEach(visitNonImportNode); } - else if (isIfStatement(n) && n.elseStatement && isIfStatement(n.elseStatement)) { + else if (ts.isIfStatement(n) && n.elseStatement && ts.isIfStatement(n.elseStatement)) { // Consider an 'else if' to be on the same depth as the 'if'. visitNonImportNode(n.expression); visitNonImportNode(n.thenStatement); @@ -76,20 +79,20 @@ namespace ts.OutliningElementsCollector { } } - function addRegionOutliningSpans(sourceFile: SourceFile, out: Push): void { - const regions: OutliningSpan[] = []; + function addRegionOutliningSpans(sourceFile: ts.SourceFile, out: ts.Push): void { + const regions: ts.OutliningSpan[] = []; const lineStarts = sourceFile.getLineStarts(); for (const currentLineStart of lineStarts) { const lineEnd = sourceFile.getLineEndOfPosition(currentLineStart); const lineText = sourceFile.text.substring(currentLineStart, lineEnd); const result = isRegionDelimiter(lineText); - if (!result || isInComment(sourceFile, currentLineStart)) { + if (!result || ts.isInComment(sourceFile, currentLineStart)) { continue; } if (!result[1]) { - const span = createTextSpanFromBounds(sourceFile.text.indexOf("//", currentLineStart), lineEnd); - regions.push(createOutliningSpan(span, OutliningSpanKind.Region, span, /*autoCollapse*/ false, result[2] || "#region")); + const span = ts.createTextSpanFromBounds(sourceFile.text.indexOf("//", currentLineStart), lineEnd); + regions.push(createOutliningSpan(span, ts.OutliningSpanKind.Region, span, /*autoCollapse*/ false, result[2] || "#region")); } else { const region = regions.pop(); @@ -106,17 +109,18 @@ namespace ts.OutliningElementsCollector { function isRegionDelimiter(lineText: string) { // We trim the leading whitespace and // without the regex since the // multiple potential whitespace matches can make for some gnarly backtracking behavior - lineText = trimStringStart(lineText); - if (!startsWith(lineText, "\/\/")) { + lineText = ts.trimStringStart(lineText); + if (!ts.startsWith(lineText, "\/\/")) { return null; // eslint-disable-line no-null/no-null } - lineText = trimString(lineText.slice(2)); + lineText = ts.trimString(lineText.slice(2)); return regionDelimiterRegExp.exec(lineText); } - function addOutliningForLeadingCommentsForPos(pos: number, sourceFile: SourceFile, cancellationToken: CancellationToken, out: Push): void { - const comments = getLeadingCommentRanges(sourceFile.text, pos); - if (!comments) return; + function addOutliningForLeadingCommentsForPos(pos: number, sourceFile: ts.SourceFile, cancellationToken: ts.CancellationToken, out: ts.Push): void { + const comments = ts.getLeadingCommentRanges(sourceFile.text, pos); + if (!comments) + return; let firstSingleLineCommentStart = -1; let lastSingleLineCommentEnd = -1; @@ -125,7 +129,7 @@ namespace ts.OutliningElementsCollector { for (const { kind, pos, end } of comments) { cancellationToken.throwIfCancellationRequested(); switch (kind) { - case SyntaxKind.SingleLineCommentTrivia: + case ts.SyntaxKind.SingleLineCommentTrivia: // never fold region delimiters into single-line comment regions const commentText = sourceText.slice(pos, end); if (isRegionDelimiter(commentText)) { @@ -142,13 +146,13 @@ namespace ts.OutliningElementsCollector { lastSingleLineCommentEnd = end; singleLineCommentCount++; break; - case SyntaxKind.MultiLineCommentTrivia: + case ts.SyntaxKind.MultiLineCommentTrivia: combineAndAddMultipleSingleLineComments(); - out.push(createOutliningSpanFromBounds(pos, end, OutliningSpanKind.Comment)); + out.push(createOutliningSpanFromBounds(pos, end, ts.OutliningSpanKind.Comment)); singleLineCommentCount = 0; break; default: - Debug.assertNever(kind); + ts.Debug.assertNever(kind); } } combineAndAddMultipleSingleLineComments(); @@ -156,189 +160,191 @@ namespace ts.OutliningElementsCollector { function combineAndAddMultipleSingleLineComments(): void { // Only outline spans of two or more consecutive single line comments if (singleLineCommentCount > 1) { - out.push(createOutliningSpanFromBounds(firstSingleLineCommentStart, lastSingleLineCommentEnd, OutliningSpanKind.Comment)); + out.push(createOutliningSpanFromBounds(firstSingleLineCommentStart, lastSingleLineCommentEnd, ts.OutliningSpanKind.Comment)); } } } - function addOutliningForLeadingCommentsForNode(n: Node, sourceFile: SourceFile, cancellationToken: CancellationToken, out: Push): void { - if (isJsxText(n)) return; + function addOutliningForLeadingCommentsForNode(n: ts.Node, sourceFile: ts.SourceFile, cancellationToken: ts.CancellationToken, out: ts.Push): void { + if (ts.isJsxText(n)) + return; addOutliningForLeadingCommentsForPos(n.pos, sourceFile, cancellationToken, out); } - function createOutliningSpanFromBounds(pos: number, end: number, kind: OutliningSpanKind): OutliningSpan { - return createOutliningSpan(createTextSpanFromBounds(pos, end), kind); + function createOutliningSpanFromBounds(pos: number, end: number, kind: ts.OutliningSpanKind): ts.OutliningSpan { + return createOutliningSpan(ts.createTextSpanFromBounds(pos, end), kind); } - function getOutliningSpanForNode(n: Node, sourceFile: SourceFile): OutliningSpan | undefined { + function getOutliningSpanForNode(n: ts.Node, sourceFile: ts.SourceFile): ts.OutliningSpan | undefined { switch (n.kind) { - case SyntaxKind.Block: - if (isFunctionLike(n.parent)) { - return functionSpan(n.parent, n as Block, sourceFile); + case ts.SyntaxKind.Block: + if (ts.isFunctionLike(n.parent)) { + return functionSpan(n.parent, n as ts.Block, sourceFile); } // Check if the block is standalone, or 'attached' to some parent statement. // If the latter, we want to collapse the block, but consider its hint span // to be the entire span of the parent. switch (n.parent.kind) { - case SyntaxKind.DoStatement: - case SyntaxKind.ForInStatement: - case SyntaxKind.ForOfStatement: - case SyntaxKind.ForStatement: - case SyntaxKind.IfStatement: - case SyntaxKind.WhileStatement: - case SyntaxKind.WithStatement: - case SyntaxKind.CatchClause: + case ts.SyntaxKind.DoStatement: + case ts.SyntaxKind.ForInStatement: + case ts.SyntaxKind.ForOfStatement: + case ts.SyntaxKind.ForStatement: + case ts.SyntaxKind.IfStatement: + case ts.SyntaxKind.WhileStatement: + case ts.SyntaxKind.WithStatement: + case ts.SyntaxKind.CatchClause: return spanForNode(n.parent); - case SyntaxKind.TryStatement: + case ts.SyntaxKind.TryStatement: // Could be the try-block, or the finally-block. - const tryStatement = n.parent as TryStatement; + const tryStatement = n.parent as ts.TryStatement; if (tryStatement.tryBlock === n) { return spanForNode(n.parent); } else if (tryStatement.finallyBlock === n) { - const node = findChildOfKind(tryStatement, SyntaxKind.FinallyKeyword, sourceFile); - if (node) return spanForNode(node); + const node = ts.findChildOfKind(tryStatement, ts.SyntaxKind.FinallyKeyword, sourceFile); + if (node) + return spanForNode(node); } // falls through default: // Block was a standalone block. In this case we want to only collapse // the span of the block, independent of any parent span. - return createOutliningSpan(createTextSpanFromNode(n, sourceFile), OutliningSpanKind.Code); + return createOutliningSpan(ts.createTextSpanFromNode(n, sourceFile), ts.OutliningSpanKind.Code); } - case SyntaxKind.ModuleBlock: + case ts.SyntaxKind.ModuleBlock: return spanForNode(n.parent); - case SyntaxKind.ClassDeclaration: - case SyntaxKind.ClassExpression: - case SyntaxKind.InterfaceDeclaration: - case SyntaxKind.EnumDeclaration: - case SyntaxKind.CaseBlock: - case SyntaxKind.TypeLiteral: - case SyntaxKind.ObjectBindingPattern: + case ts.SyntaxKind.ClassDeclaration: + case ts.SyntaxKind.ClassExpression: + case ts.SyntaxKind.InterfaceDeclaration: + case ts.SyntaxKind.EnumDeclaration: + case ts.SyntaxKind.CaseBlock: + case ts.SyntaxKind.TypeLiteral: + case ts.SyntaxKind.ObjectBindingPattern: return spanForNode(n); - case SyntaxKind.TupleType: - return spanForNode(n, /*autoCollapse*/ false, /*useFullStart*/ !isTupleTypeNode(n.parent), SyntaxKind.OpenBracketToken); - case SyntaxKind.CaseClause: - case SyntaxKind.DefaultClause: - return spanForNodeArray((n as CaseClause | DefaultClause).statements); - case SyntaxKind.ObjectLiteralExpression: + case ts.SyntaxKind.TupleType: + return spanForNode(n, /*autoCollapse*/ false, /*useFullStart*/ !ts.isTupleTypeNode(n.parent), ts.SyntaxKind.OpenBracketToken); + case ts.SyntaxKind.CaseClause: + case ts.SyntaxKind.DefaultClause: + return spanForNodeArray((n as ts.CaseClause | ts.DefaultClause).statements); + case ts.SyntaxKind.ObjectLiteralExpression: return spanForObjectOrArrayLiteral(n); - case SyntaxKind.ArrayLiteralExpression: - return spanForObjectOrArrayLiteral(n, SyntaxKind.OpenBracketToken); - case SyntaxKind.JsxElement: - return spanForJSXElement(n as JsxElement); - case SyntaxKind.JsxFragment: - return spanForJSXFragment(n as JsxFragment); - case SyntaxKind.JsxSelfClosingElement: - case SyntaxKind.JsxOpeningElement: - return spanForJSXAttributes((n as JsxOpeningLikeElement).attributes); - case SyntaxKind.TemplateExpression: - case SyntaxKind.NoSubstitutionTemplateLiteral: - return spanForTemplateLiteral(n as TemplateExpression | NoSubstitutionTemplateLiteral); - case SyntaxKind.ArrayBindingPattern: - return spanForNode(n, /*autoCollapse*/ false, /*useFullStart*/ !isBindingElement(n.parent), SyntaxKind.OpenBracketToken); - case SyntaxKind.ArrowFunction: - return spanForArrowFunction(n as ArrowFunction); - case SyntaxKind.CallExpression: - return spanForCallExpression(n as CallExpression); - case SyntaxKind.ParenthesizedExpression: - return spanForParenthesizedExpression(n as ParenthesizedExpression); + case ts.SyntaxKind.ArrayLiteralExpression: + return spanForObjectOrArrayLiteral(n, ts.SyntaxKind.OpenBracketToken); + case ts.SyntaxKind.JsxElement: + return spanForJSXElement(n as ts.JsxElement); + case ts.SyntaxKind.JsxFragment: + return spanForJSXFragment(n as ts.JsxFragment); + case ts.SyntaxKind.JsxSelfClosingElement: + case ts.SyntaxKind.JsxOpeningElement: + return spanForJSXAttributes((n as ts.JsxOpeningLikeElement).attributes); + case ts.SyntaxKind.TemplateExpression: + case ts.SyntaxKind.NoSubstitutionTemplateLiteral: + return spanForTemplateLiteral(n as ts.TemplateExpression | ts.NoSubstitutionTemplateLiteral); + case ts.SyntaxKind.ArrayBindingPattern: + return spanForNode(n, /*autoCollapse*/ false, /*useFullStart*/ !ts.isBindingElement(n.parent), ts.SyntaxKind.OpenBracketToken); + case ts.SyntaxKind.ArrowFunction: + return spanForArrowFunction(n as ts.ArrowFunction); + case ts.SyntaxKind.CallExpression: + return spanForCallExpression(n as ts.CallExpression); + case ts.SyntaxKind.ParenthesizedExpression: + return spanForParenthesizedExpression(n as ts.ParenthesizedExpression); } - - function spanForCallExpression(node: CallExpression): OutliningSpan | undefined { + function spanForCallExpression(node: ts.CallExpression): ts.OutliningSpan | undefined { if (!node.arguments.length) { return undefined; } - const openToken = findChildOfKind(node, SyntaxKind.OpenParenToken, sourceFile); - const closeToken = findChildOfKind(node, SyntaxKind.CloseParenToken, sourceFile); - if (!openToken || !closeToken || positionsAreOnSameLine(openToken.pos, closeToken.pos, sourceFile)) { + const openToken = ts.findChildOfKind(node, ts.SyntaxKind.OpenParenToken, sourceFile); + const closeToken = ts.findChildOfKind(node, ts.SyntaxKind.CloseParenToken, sourceFile); + if (!openToken || !closeToken || ts.positionsAreOnSameLine(openToken.pos, closeToken.pos, sourceFile)) { return undefined; } return spanBetweenTokens(openToken, closeToken, node, sourceFile, /*autoCollapse*/ false, /*useFullStart*/ true); } - function spanForArrowFunction(node: ArrowFunction): OutliningSpan | undefined { - if (isBlock(node.body) || isParenthesizedExpression(node.body) || positionsAreOnSameLine(node.body.getFullStart(), node.body.getEnd(), sourceFile)) { + function spanForArrowFunction(node: ts.ArrowFunction): ts.OutliningSpan | undefined { + if (ts.isBlock(node.body) || ts.isParenthesizedExpression(node.body) || ts.positionsAreOnSameLine(node.body.getFullStart(), node.body.getEnd(), sourceFile)) { return undefined; } - const textSpan = createTextSpanFromBounds(node.body.getFullStart(), node.body.getEnd()); - return createOutliningSpan(textSpan, OutliningSpanKind.Code, createTextSpanFromNode(node)); + const textSpan = ts.createTextSpanFromBounds(node.body.getFullStart(), node.body.getEnd()); + return createOutliningSpan(textSpan, ts.OutliningSpanKind.Code, ts.createTextSpanFromNode(node)); } - function spanForJSXElement(node: JsxElement): OutliningSpan | undefined { - const textSpan = createTextSpanFromBounds(node.openingElement.getStart(sourceFile), node.closingElement.getEnd()); + function spanForJSXElement(node: ts.JsxElement): ts.OutliningSpan | undefined { + const textSpan = ts.createTextSpanFromBounds(node.openingElement.getStart(sourceFile), node.closingElement.getEnd()); const tagName = node.openingElement.tagName.getText(sourceFile); const bannerText = "<" + tagName + ">..."; - return createOutliningSpan(textSpan, OutliningSpanKind.Code, textSpan, /*autoCollapse*/ false, bannerText); + return createOutliningSpan(textSpan, ts.OutliningSpanKind.Code, textSpan, /*autoCollapse*/ false, bannerText); } - function spanForJSXFragment(node: JsxFragment): OutliningSpan | undefined { - const textSpan = createTextSpanFromBounds(node.openingFragment.getStart(sourceFile), node.closingFragment.getEnd()); + function spanForJSXFragment(node: ts.JsxFragment): ts.OutliningSpan | undefined { + const textSpan = ts.createTextSpanFromBounds(node.openingFragment.getStart(sourceFile), node.closingFragment.getEnd()); const bannerText = "<>..."; - return createOutliningSpan(textSpan, OutliningSpanKind.Code, textSpan, /*autoCollapse*/ false, bannerText); + return createOutliningSpan(textSpan, ts.OutliningSpanKind.Code, textSpan, /*autoCollapse*/ false, bannerText); } - function spanForJSXAttributes(node: JsxAttributes): OutliningSpan | undefined { + function spanForJSXAttributes(node: ts.JsxAttributes): ts.OutliningSpan | undefined { if (node.properties.length === 0) { return undefined; } - return createOutliningSpanFromBounds(node.getStart(sourceFile), node.getEnd(), OutliningSpanKind.Code); + return createOutliningSpanFromBounds(node.getStart(sourceFile), node.getEnd(), ts.OutliningSpanKind.Code); } - function spanForTemplateLiteral(node: TemplateExpression | NoSubstitutionTemplateLiteral) { - if (node.kind === SyntaxKind.NoSubstitutionTemplateLiteral && node.text.length === 0) { + function spanForTemplateLiteral(node: ts.TemplateExpression | ts.NoSubstitutionTemplateLiteral) { + if (node.kind === ts.SyntaxKind.NoSubstitutionTemplateLiteral && node.text.length === 0) { return undefined; } - return createOutliningSpanFromBounds(node.getStart(sourceFile), node.getEnd(), OutliningSpanKind.Code); + return createOutliningSpanFromBounds(node.getStart(sourceFile), node.getEnd(), ts.OutliningSpanKind.Code); } - function spanForObjectOrArrayLiteral(node: Node, open: SyntaxKind.OpenBraceToken | SyntaxKind.OpenBracketToken = SyntaxKind.OpenBraceToken): OutliningSpan | undefined { + function spanForObjectOrArrayLiteral(node: ts.Node, open: ts.SyntaxKind.OpenBraceToken | ts.SyntaxKind.OpenBracketToken = ts.SyntaxKind.OpenBraceToken): ts.OutliningSpan | undefined { // If the block has no leading keywords and is inside an array literal or call expression, // we only want to collapse the span of the block. // Otherwise, the collapsed section will include the end of the previous line. - return spanForNode(node, /*autoCollapse*/ false, /*useFullStart*/ !isArrayLiteralExpression(node.parent) && !isCallExpression(node.parent), open); + return spanForNode(node, /*autoCollapse*/ false, /*useFullStart*/ !ts.isArrayLiteralExpression(node.parent) && !ts.isCallExpression(node.parent), open); } - function spanForNode(hintSpanNode: Node, autoCollapse = false, useFullStart = true, open: SyntaxKind.OpenBraceToken | SyntaxKind.OpenBracketToken = SyntaxKind.OpenBraceToken, close: SyntaxKind = open === SyntaxKind.OpenBraceToken ? SyntaxKind.CloseBraceToken : SyntaxKind.CloseBracketToken): OutliningSpan | undefined { - const openToken = findChildOfKind(n, open, sourceFile); - const closeToken = findChildOfKind(n, close, sourceFile); + function spanForNode(hintSpanNode: ts.Node, autoCollapse = false, useFullStart = true, open: ts.SyntaxKind.OpenBraceToken | ts.SyntaxKind.OpenBracketToken = ts.SyntaxKind.OpenBraceToken, close: ts.SyntaxKind = open === ts.SyntaxKind.OpenBraceToken ? ts.SyntaxKind.CloseBraceToken : ts.SyntaxKind.CloseBracketToken): ts.OutliningSpan | undefined { + const openToken = ts.findChildOfKind(n, open, sourceFile); + const closeToken = ts.findChildOfKind(n, close, sourceFile); return openToken && closeToken && spanBetweenTokens(openToken, closeToken, hintSpanNode, sourceFile, autoCollapse, useFullStart); } - function spanForNodeArray(nodeArray: NodeArray): OutliningSpan | undefined { - return nodeArray.length ? createOutliningSpan(createTextSpanFromRange(nodeArray), OutliningSpanKind.Code) : undefined; + function spanForNodeArray(nodeArray: ts.NodeArray): ts.OutliningSpan | undefined { + return nodeArray.length ? createOutliningSpan(ts.createTextSpanFromRange(nodeArray), ts.OutliningSpanKind.Code) : undefined; } - function spanForParenthesizedExpression(node: ParenthesizedExpression): OutliningSpan | undefined { - if (positionsAreOnSameLine(node.getStart(), node.getEnd(), sourceFile)) return undefined; - const textSpan = createTextSpanFromBounds(node.getStart(), node.getEnd()); - return createOutliningSpan(textSpan, OutliningSpanKind.Code, createTextSpanFromNode(node)); + function spanForParenthesizedExpression(node: ts.ParenthesizedExpression): ts.OutliningSpan | undefined { + if (ts.positionsAreOnSameLine(node.getStart(), node.getEnd(), sourceFile)) + return undefined; + const textSpan = ts.createTextSpanFromBounds(node.getStart(), node.getEnd()); + return createOutliningSpan(textSpan, ts.OutliningSpanKind.Code, ts.createTextSpanFromNode(node)); } } - function functionSpan(node: SignatureDeclaration, body: Block, sourceFile: SourceFile): OutliningSpan | undefined { + function functionSpan(node: ts.SignatureDeclaration, body: ts.Block, sourceFile: ts.SourceFile): ts.OutliningSpan | undefined { const openToken = tryGetFunctionOpenToken(node, body, sourceFile); - const closeToken = findChildOfKind(body, SyntaxKind.CloseBraceToken, sourceFile); - return openToken && closeToken && spanBetweenTokens(openToken, closeToken, node, sourceFile, /*autoCollapse*/ node.kind !== SyntaxKind.ArrowFunction); + const closeToken = ts.findChildOfKind(body, ts.SyntaxKind.CloseBraceToken, sourceFile); + return openToken && closeToken && spanBetweenTokens(openToken, closeToken, node, sourceFile, /*autoCollapse*/ node.kind !== ts.SyntaxKind.ArrowFunction); } - function spanBetweenTokens(openToken: Node, closeToken: Node, hintSpanNode: Node, sourceFile: SourceFile, autoCollapse = false, useFullStart = true): OutliningSpan { - const textSpan = createTextSpanFromBounds(useFullStart ? openToken.getFullStart() : openToken.getStart(sourceFile), closeToken.getEnd()); - return createOutliningSpan(textSpan, OutliningSpanKind.Code, createTextSpanFromNode(hintSpanNode, sourceFile), autoCollapse); + function spanBetweenTokens(openToken: ts.Node, closeToken: ts.Node, hintSpanNode: ts.Node, sourceFile: ts.SourceFile, autoCollapse = false, useFullStart = true): ts.OutliningSpan { + const textSpan = ts.createTextSpanFromBounds(useFullStart ? openToken.getFullStart() : openToken.getStart(sourceFile), closeToken.getEnd()); + return createOutliningSpan(textSpan, ts.OutliningSpanKind.Code, ts.createTextSpanFromNode(hintSpanNode, sourceFile), autoCollapse); } - function createOutliningSpan(textSpan: TextSpan, kind: OutliningSpanKind, hintSpan: TextSpan = textSpan, autoCollapse = false, bannerText = "..."): OutliningSpan { + function createOutliningSpan(textSpan: ts.TextSpan, kind: ts.OutliningSpanKind, hintSpan: ts.TextSpan = textSpan, autoCollapse = false, bannerText = "..."): ts.OutliningSpan { return { textSpan, kind, hintSpan, bannerText, autoCollapse }; } - function tryGetFunctionOpenToken(node: SignatureDeclaration, body: Block, sourceFile: SourceFile): Node | undefined { - if (isNodeArrayMultiLine(node.parameters, sourceFile)) { - const openParenToken = findChildOfKind(node, SyntaxKind.OpenParenToken, sourceFile); + function tryGetFunctionOpenToken(node: ts.SignatureDeclaration, body: ts.Block, sourceFile: ts.SourceFile): ts.Node | undefined { + if (ts.isNodeArrayMultiLine(node.parameters, sourceFile)) { + const openParenToken = ts.findChildOfKind(node, ts.SyntaxKind.OpenParenToken, sourceFile); if (openParenToken) { return openParenToken; } } - return findChildOfKind(body, SyntaxKind.OpenBraceToken, sourceFile); + return ts.findChildOfKind(body, ts.SyntaxKind.OpenBraceToken, sourceFile); } } diff --git a/src/services/patternMatcher.ts b/src/services/patternMatcher.ts index b0071f7124098..8b8e282cb2465 100644 --- a/src/services/patternMatcher.ts +++ b/src/services/patternMatcher.ts @@ -87,7 +87,7 @@ namespace ts { // independently. For example, if the chunk is for "UIElement" the the spans of interest // correspond to "U", "I" and "Element". If "UIElement" isn't found as an exact, prefix. // or substring match, then the character spans will be used to attempt a camel case match. - characterSpans: TextSpan[]; + characterSpans: ts.TextSpan[]; } function createPatternMatch(kind: PatternMatchKind, isCaseSensitive: boolean): PatternMatch { @@ -102,24 +102,25 @@ namespace ts { // we see the name of a module that is used everywhere, or the name of an overload). As // such, we cache the information we compute about the candidate for the life of this // pattern matcher so we don't have to compute it multiple times. - const stringToWordSpans = new Map(); + const stringToWordSpans = new ts.Map(); const dotSeparatedSegments = pattern.trim().split(".").map(p => createSegment(p.trim())); // A segment is considered invalid if we couldn't find any words in it. - if (dotSeparatedSegments.some(segment => !segment.subWordTextChunks.length)) return undefined; + if (dotSeparatedSegments.some(segment => !segment.subWordTextChunks.length)) + return undefined; return { getFullMatch: (containers, candidate) => getFullMatch(containers, candidate, dotSeparatedSegments, stringToWordSpans), - getMatchForLastSegmentOfPattern: candidate => matchSegment(candidate, last(dotSeparatedSegments), stringToWordSpans), + getMatchForLastSegmentOfPattern: candidate => matchSegment(candidate, ts.last(dotSeparatedSegments), stringToWordSpans), patternContainsDots: dotSeparatedSegments.length > 1 }; } - function getFullMatch(candidateContainers: readonly string[], candidate: string, dotSeparatedSegments: readonly Segment[], stringToWordSpans: ESMap): PatternMatch | undefined { + function getFullMatch(candidateContainers: readonly string[], candidate: string, dotSeparatedSegments: readonly Segment[], stringToWordSpans: ts.ESMap): PatternMatch | undefined { // First, check that the last part of the dot separated pattern matches the name of the // candidate. If not, then there's no point in proceeding and doing the more // expensive work. - const candidateMatch = matchSegment(candidate, last(dotSeparatedSegments), stringToWordSpans); + const candidateMatch = matchSegment(candidate, ts.last(dotSeparatedSegments), stringToWordSpans); if (!candidateMatch) { return undefined; } @@ -133,15 +134,13 @@ namespace ts { } let bestMatch: PatternMatch | undefined; - for (let i = dotSeparatedSegments.length - 2, j = candidateContainers.length - 1; - i >= 0; - i -= 1, j -= 1) { + for (let i = dotSeparatedSegments.length - 2, j = candidateContainers.length - 1; i >= 0; i -= 1, j -= 1) { bestMatch = betterMatch(bestMatch, matchSegment(candidateContainers[j], dotSeparatedSegments[i], stringToWordSpans)); } return bestMatch; } - function getWordSpans(word: string, stringToWordSpans: ESMap): TextSpan[] { + function getWordSpans(word: string, stringToWordSpans: ts.ESMap): ts.TextSpan[] { let spans = stringToWordSpans.get(word); if (!spans) { stringToWordSpans.set(word, spans = breakIntoWordSpans(word)); @@ -149,16 +148,17 @@ namespace ts { return spans; } - function matchTextChunk(candidate: string, chunk: TextChunk, stringToWordSpans: ESMap): PatternMatch | undefined { + function matchTextChunk(candidate: string, chunk: TextChunk, stringToWordSpans: ts.ESMap): PatternMatch | undefined { const index = indexOfIgnoringCase(candidate, chunk.textLowerCase); if (index === 0) { // a) Check if the word is a prefix of the candidate, in a case insensitive or // sensitive manner. If it does, return that there was an exact match if the word and candidate are the same length, else a prefix match. - return createPatternMatch(chunk.text.length === candidate.length ? PatternMatchKind.exact : PatternMatchKind.prefix, /*isCaseSensitive:*/ startsWith(candidate, chunk.text)); + return createPatternMatch(chunk.text.length === candidate.length ? PatternMatchKind.exact : PatternMatchKind.prefix, /*isCaseSensitive:*/ ts.startsWith(candidate, chunk.text)); } if (chunk.isLowerCase) { - if (index === -1) return undefined; + if (index === -1) + return undefined; // b) If the part is entirely lowercase, then check if it is contained anywhere in the // candidate in a case insensitive manner. If so, return that there was a substring // match. @@ -201,7 +201,7 @@ namespace ts { } } - function matchSegment(candidate: string, segment: Segment, stringToWordSpans: ESMap): PatternMatch | undefined { + function matchSegment(candidate: string, segment: Segment, stringToWordSpans: ts.ESMap): PatternMatch | undefined { // First check if the segment matches as is. This is also useful if the segment contains // characters we would normally strip when splitting into parts that we also may want to // match in the candidate. For example if the segment is "@int" and the candidate is @@ -209,9 +209,10 @@ namespace ts { // // Note: if the segment contains a space or an asterisk then we must assume that it's a // multi-word segment. - if (every(segment.totalTextChunk.text, ch => ch !== CharacterCodes.space && ch !== CharacterCodes.asterisk)) { + if (every(segment.totalTextChunk.text, ch => ch !== ts.CharacterCodes.space && ch !== ts.CharacterCodes.asterisk)) { const match = matchTextChunk(candidate, segment.totalTextChunk, stringToWordSpans); - if (match) return match; + if (match) + return match; } // The logic for pattern matching is now as follows: @@ -259,14 +260,14 @@ namespace ts { } function betterMatch(a: PatternMatch | undefined, b: PatternMatch | undefined): PatternMatch | undefined { - return min(a, b, compareMatches); + return ts.min(a, b, compareMatches); } - function compareMatches(a: PatternMatch | undefined, b: PatternMatch | undefined): Comparison { - return a === undefined ? Comparison.GreaterThan : b === undefined ? Comparison.LessThan - : compareValues(a.kind, b.kind) || compareBooleans(!a.isCaseSensitive, !b.isCaseSensitive); + function compareMatches(a: PatternMatch | undefined, b: PatternMatch | undefined): ts.Comparison { + return a === undefined ? ts.Comparison.GreaterThan : b === undefined ? ts.Comparison.LessThan + : ts.compareValues(a.kind, b.kind) || ts.compareBooleans(!a.isCaseSensitive, !b.isCaseSensitive); } - function partStartsWith(candidate: string, candidateSpan: TextSpan, pattern: string, ignoreCase: boolean, patternSpan: TextSpan = { start: 0, length: pattern.length }): boolean { + function partStartsWith(candidate: string, candidateSpan: ts.TextSpan, pattern: string, ignoreCase: boolean, patternSpan: ts.TextSpan = { start: 0, length: pattern.length }): boolean { return patternSpan.length <= candidateSpan.length // If pattern part is longer than the candidate part there can never be a match. && everyInRange(0, patternSpan.length, i => equalChars(pattern.charCodeAt(patternSpan.start + i), candidate.charCodeAt(candidateSpan.start + i), ignoreCase)); } @@ -275,7 +276,7 @@ namespace ts { return ignoreCase ? toLowerCase(ch1) === toLowerCase(ch2) : ch1 === ch2; } - function tryCamelCaseMatch(candidate: string, candidateParts: TextSpan[], chunk: TextChunk, ignoreCase: boolean): boolean { + function tryCamelCaseMatch(candidate: string, candidateParts: ts.TextSpan[], chunk: TextChunk, ignoreCase: boolean): boolean { const chunkCharacterSpans = chunk.characterSpans; // Note: we may have more pattern parts than candidate parts. This is because multiple @@ -331,7 +332,7 @@ namespace ts { // obviously contiguous. contiguous = contiguous === undefined ? true : contiguous; - candidatePart = createTextSpan(candidatePart.start + chunkCharacterSpan.length, candidatePart.length - chunkCharacterSpan.length); + candidatePart = ts.createTextSpan(candidatePart.start + chunkCharacterSpan.length, candidatePart.length - chunkCharacterSpan.length); } // Check if we matched anything at all. If we didn't, then we need to unset the @@ -356,11 +357,11 @@ namespace ts { function isUpperCaseLetter(ch: number) { // Fast check for the ascii range. - if (ch >= CharacterCodes.A && ch <= CharacterCodes.Z) { + if (ch >= ts.CharacterCodes.A && ch <= ts.CharacterCodes.Z) { return true; } - if (ch < CharacterCodes.maxAsciiCharacter || !isUnicodeIdentifierStart(ch, ScriptTarget.Latest)) { + if (ch < ts.CharacterCodes.maxAsciiCharacter || !ts.isUnicodeIdentifierStart(ch, ts.ScriptTarget.Latest)) { return false; } @@ -372,11 +373,11 @@ namespace ts { function isLowerCaseLetter(ch: number) { // Fast check for the ascii range. - if (ch >= CharacterCodes.a && ch <= CharacterCodes.z) { + if (ch >= ts.CharacterCodes.a && ch <= ts.CharacterCodes.z) { return true; } - if (ch < CharacterCodes.maxAsciiCharacter || !isUnicodeIdentifierStart(ch, ScriptTarget.Latest)) { + if (ch < ts.CharacterCodes.maxAsciiCharacter || !ts.isUnicodeIdentifierStart(ch, ts.ScriptTarget.Latest)) { return false; } @@ -401,11 +402,11 @@ namespace ts { function toLowerCase(ch: number): number { // Fast convert for the ascii range. - if (ch >= CharacterCodes.A && ch <= CharacterCodes.Z) { - return CharacterCodes.a + (ch - CharacterCodes.A); + if (ch >= ts.CharacterCodes.A && ch <= ts.CharacterCodes.Z) { + return ts.CharacterCodes.a + (ch - ts.CharacterCodes.A); } - if (ch < CharacterCodes.maxAsciiCharacter) { + if (ch < ts.CharacterCodes.maxAsciiCharacter) { return ch; } @@ -416,11 +417,11 @@ namespace ts { function isDigit(ch: number) { // TODO(cyrusn): Find a way to support this for unicode digits. - return ch >= CharacterCodes._0 && ch <= CharacterCodes._9; + return ch >= ts.CharacterCodes._0 && ch <= ts.CharacterCodes._9; } function isWordChar(ch: number) { - return isUpperCaseLetter(ch) || isLowerCaseLetter(ch) || isDigit(ch) || ch === CharacterCodes._ || ch === CharacterCodes.$; + return isUpperCaseLetter(ch) || isLowerCaseLetter(ch) || isDigit(ch) || ch === ts.CharacterCodes._ || ch === ts.CharacterCodes.$; } function breakPatternIntoTextChunks(pattern: string): TextChunk[] { @@ -461,16 +462,16 @@ namespace ts { }; } - export function breakIntoCharacterSpans(identifier: string): TextSpan[] { + export function breakIntoCharacterSpans(identifier: string): ts.TextSpan[] { return breakIntoSpans(identifier, /*word:*/ false); } - export function breakIntoWordSpans(identifier: string): TextSpan[] { + export function breakIntoWordSpans(identifier: string): ts.TextSpan[] { return breakIntoSpans(identifier, /*word:*/ true); } - function breakIntoSpans(identifier: string, word: boolean): TextSpan[] { - const result: TextSpan[] = []; + function breakIntoSpans(identifier: string, word: boolean): ts.TextSpan[] { + const result: ts.TextSpan[] = []; let wordStart = 0; for (let i = 1; i < identifier.length; i++) { @@ -487,7 +488,7 @@ namespace ts { hasTransitionFromUpperToLower) { if (!isAllPunctuation(identifier, wordStart, i)) { - result.push(createTextSpan(wordStart, i - wordStart)); + result.push(ts.createTextSpan(wordStart, i - wordStart)); } wordStart = i; @@ -495,7 +496,7 @@ namespace ts { } if (!isAllPunctuation(identifier, wordStart, identifier.length)) { - result.push(createTextSpan(wordStart, identifier.length - wordStart)); + result.push(ts.createTextSpan(wordStart, identifier.length - wordStart)); } return result; @@ -503,29 +504,29 @@ namespace ts { function charIsPunctuation(ch: number) { switch (ch) { - case CharacterCodes.exclamation: - case CharacterCodes.doubleQuote: - case CharacterCodes.hash: - case CharacterCodes.percent: - case CharacterCodes.ampersand: - case CharacterCodes.singleQuote: - case CharacterCodes.openParen: - case CharacterCodes.closeParen: - case CharacterCodes.asterisk: - case CharacterCodes.comma: - case CharacterCodes.minus: - case CharacterCodes.dot: - case CharacterCodes.slash: - case CharacterCodes.colon: - case CharacterCodes.semicolon: - case CharacterCodes.question: - case CharacterCodes.at: - case CharacterCodes.openBracket: - case CharacterCodes.backslash: - case CharacterCodes.closeBracket: - case CharacterCodes._: - case CharacterCodes.openBrace: - case CharacterCodes.closeBrace: + case ts.CharacterCodes.exclamation: + case ts.CharacterCodes.doubleQuote: + case ts.CharacterCodes.hash: + case ts.CharacterCodes.percent: + case ts.CharacterCodes.ampersand: + case ts.CharacterCodes.singleQuote: + case ts.CharacterCodes.openParen: + case ts.CharacterCodes.closeParen: + case ts.CharacterCodes.asterisk: + case ts.CharacterCodes.comma: + case ts.CharacterCodes.minus: + case ts.CharacterCodes.dot: + case ts.CharacterCodes.slash: + case ts.CharacterCodes.colon: + case ts.CharacterCodes.semicolon: + case ts.CharacterCodes.question: + case ts.CharacterCodes.at: + case ts.CharacterCodes.openBracket: + case ts.CharacterCodes.backslash: + case ts.CharacterCodes.closeBracket: + case ts.CharacterCodes._: + case ts.CharacterCodes.openBrace: + case ts.CharacterCodes.closeBrace: return true; } @@ -533,7 +534,7 @@ namespace ts { } function isAllPunctuation(identifier: string, start: number, end: number): boolean { - return every(identifier, ch => charIsPunctuation(ch) && ch !== CharacterCodes._, start, end); + return every(identifier, ch => charIsPunctuation(ch) && ch !== ts.CharacterCodes._, start, end); } function transitionFromUpperToLower(identifier: string, index: number, wordStart: number): boolean { diff --git a/src/services/preProcess.ts b/src/services/preProcess.ts index d5c384e9161cc..b7b87c43fa423 100644 --- a/src/services/preProcess.ts +++ b/src/services/preProcess.ts @@ -1,7 +1,7 @@ namespace ts { - export function preProcessFile(sourceText: string, readImportFiles = true, detectJavaScriptImports = false): PreProcessedFileInfo { - const pragmaContext: PragmaContext = { - languageVersion: ScriptTarget.ES5, // controls whether the token scanner considers unicode identifiers or not - shouldn't matter, since we're only using it for trivia + export function preProcessFile(sourceText: string, readImportFiles = true, detectJavaScriptImports = false): ts.PreProcessedFileInfo { + const pragmaContext: ts.PragmaContext = { + languageVersion: ts.ScriptTarget.ES5, pragmas: undefined, checkJsDirective: undefined, referencedFiles: [], @@ -11,10 +11,13 @@ namespace ts { hasNoDefaultLib: undefined, moduleName: undefined }; - const importedFiles: FileReference[] = []; - let ambientExternalModules: { ref: FileReference, depth: number }[] | undefined; - let lastToken: SyntaxKind; - let currentToken: SyntaxKind; + const importedFiles: ts.FileReference[] = []; + let ambientExternalModules: { + ref: ts.FileReference; + depth: number; + }[] | undefined; + let lastToken: ts.SyntaxKind; + let currentToken: ts.SyntaxKind; let braceNesting = 0; // assume that text represent an external module if it contains at least one top level import/export // ambient modules that are found inside external modules are interpreted as module augmentations @@ -22,19 +25,19 @@ namespace ts { function nextToken() { lastToken = currentToken; - currentToken = scanner.scan(); - if (currentToken === SyntaxKind.OpenBraceToken) { + currentToken = ts.scanner.scan(); + if (currentToken === ts.SyntaxKind.OpenBraceToken) { braceNesting++; } - else if (currentToken === SyntaxKind.CloseBraceToken) { + else if (currentToken === ts.SyntaxKind.CloseBraceToken) { braceNesting--; } return currentToken; } function getFileReference() { - const fileName = scanner.getTokenValue(); - const pos = scanner.getTokenPos(); + const fileName = ts.scanner.getTokenValue(); + const pos = ts.scanner.getTokenPos(); return { fileName, pos, end: pos + fileName.length }; } @@ -61,13 +64,13 @@ namespace ts { * Returns true if at least one token was consumed from the stream */ function tryConsumeDeclare(): boolean { - let token = scanner.getToken(); - if (token === SyntaxKind.DeclareKeyword) { + let token = ts.scanner.getToken(); + if (token === ts.SyntaxKind.DeclareKeyword) { // declare module "mod" token = nextToken(); - if (token === SyntaxKind.ModuleKeyword) { + if (token === ts.SyntaxKind.ModuleKeyword) { token = nextToken(); - if (token === SyntaxKind.StringLiteral) { + if (token === ts.SyntaxKind.StringLiteral) { recordAmbientExternalModule(); } } @@ -81,57 +84,55 @@ namespace ts { * Returns true if at least one token was consumed from the stream */ function tryConsumeImport(): boolean { - if (lastToken === SyntaxKind.DotToken) { + if (lastToken === ts.SyntaxKind.DotToken) { return false; } - let token = scanner.getToken(); - if (token === SyntaxKind.ImportKeyword) { + let token = ts.scanner.getToken(); + if (token === ts.SyntaxKind.ImportKeyword) { token = nextToken(); - if (token === SyntaxKind.OpenParenToken) { + if (token === ts.SyntaxKind.OpenParenToken) { token = nextToken(); - if (token === SyntaxKind.StringLiteral || token === SyntaxKind.NoSubstitutionTemplateLiteral) { + if (token === ts.SyntaxKind.StringLiteral || token === ts.SyntaxKind.NoSubstitutionTemplateLiteral) { // import("mod"); recordModuleName(); return true; } } - else if (token === SyntaxKind.StringLiteral) { + else if (token === ts.SyntaxKind.StringLiteral) { // import "mod"; recordModuleName(); return true; } else { - if (token === SyntaxKind.TypeKeyword) { - const skipTypeKeyword = scanner.lookAhead(() => { - const token = scanner.scan(); - return token !== SyntaxKind.FromKeyword && ( - token === SyntaxKind.AsteriskToken || - token === SyntaxKind.OpenBraceToken || - token === SyntaxKind.Identifier || - isKeyword(token) - ); + if (token === ts.SyntaxKind.TypeKeyword) { + const skipTypeKeyword = ts.scanner.lookAhead(() => { + const token = ts.scanner.scan(); + return token !== ts.SyntaxKind.FromKeyword && (token === ts.SyntaxKind.AsteriskToken || + token === ts.SyntaxKind.OpenBraceToken || + token === ts.SyntaxKind.Identifier || + ts.isKeyword(token)); }); if (skipTypeKeyword) { token = nextToken(); } } - if (token === SyntaxKind.Identifier || isKeyword(token)) { + if (token === ts.SyntaxKind.Identifier || ts.isKeyword(token)) { token = nextToken(); - if (token === SyntaxKind.FromKeyword) { + if (token === ts.SyntaxKind.FromKeyword) { token = nextToken(); - if (token === SyntaxKind.StringLiteral) { + if (token === ts.SyntaxKind.StringLiteral) { // import d from "mod"; recordModuleName(); return true; } } - else if (token === SyntaxKind.EqualsToken) { + else if (token === ts.SyntaxKind.EqualsToken) { if (tryConsumeRequireCall(/*skipCurrentToken*/ true)) { return true; } } - else if (token === SyntaxKind.CommaToken) { + else if (token === ts.SyntaxKind.CommaToken) { // consume comma and keep going token = nextToken(); } @@ -141,19 +142,19 @@ namespace ts { } } - if (token === SyntaxKind.OpenBraceToken) { + if (token === ts.SyntaxKind.OpenBraceToken) { token = nextToken(); // consume "{ a as B, c, d as D}" clauses // make sure that it stops on EOF - while (token !== SyntaxKind.CloseBraceToken && token !== SyntaxKind.EndOfFileToken) { + while (token !== ts.SyntaxKind.CloseBraceToken && token !== ts.SyntaxKind.EndOfFileToken) { token = nextToken(); } - if (token === SyntaxKind.CloseBraceToken) { + if (token === ts.SyntaxKind.CloseBraceToken) { token = nextToken(); - if (token === SyntaxKind.FromKeyword) { + if (token === ts.SyntaxKind.FromKeyword) { token = nextToken(); - if (token === SyntaxKind.StringLiteral) { + if (token === ts.SyntaxKind.StringLiteral) { // import {a as A} from "mod"; // import d, {a, b as B} from "mod" recordModuleName(); @@ -161,15 +162,15 @@ namespace ts { } } } - else if (token === SyntaxKind.AsteriskToken) { + else if (token === ts.SyntaxKind.AsteriskToken) { token = nextToken(); - if (token === SyntaxKind.AsKeyword) { + if (token === ts.SyntaxKind.AsKeyword) { token = nextToken(); - if (token === SyntaxKind.Identifier || isKeyword(token)) { + if (token === ts.SyntaxKind.Identifier || ts.isKeyword(token)) { token = nextToken(); - if (token === SyntaxKind.FromKeyword) { + if (token === ts.SyntaxKind.FromKeyword) { token = nextToken(); - if (token === SyntaxKind.StringLiteral) { + if (token === ts.SyntaxKind.StringLiteral) { // import * as NS from "mod" // import d, * as NS from "mod" recordModuleName(); @@ -187,33 +188,33 @@ namespace ts { } function tryConsumeExport(): boolean { - let token = scanner.getToken(); - if (token === SyntaxKind.ExportKeyword) { + let token = ts.scanner.getToken(); + if (token === ts.SyntaxKind.ExportKeyword) { markAsExternalModuleIfTopLevel(); token = nextToken(); - if (token === SyntaxKind.TypeKeyword) { - const skipTypeKeyword = scanner.lookAhead(() => { - const token = scanner.scan(); - return token === SyntaxKind.AsteriskToken || - token === SyntaxKind.OpenBraceToken; + if (token === ts.SyntaxKind.TypeKeyword) { + const skipTypeKeyword = ts.scanner.lookAhead(() => { + const token = ts.scanner.scan(); + return token === ts.SyntaxKind.AsteriskToken || + token === ts.SyntaxKind.OpenBraceToken; }); if (skipTypeKeyword) { token = nextToken(); } } - if (token === SyntaxKind.OpenBraceToken) { + if (token === ts.SyntaxKind.OpenBraceToken) { token = nextToken(); // consume "{ a as B, c, d as D}" clauses // make sure it stops on EOF - while (token !== SyntaxKind.CloseBraceToken && token !== SyntaxKind.EndOfFileToken) { + while (token !== ts.SyntaxKind.CloseBraceToken && token !== ts.SyntaxKind.EndOfFileToken) { token = nextToken(); } - if (token === SyntaxKind.CloseBraceToken) { + if (token === ts.SyntaxKind.CloseBraceToken) { token = nextToken(); - if (token === SyntaxKind.FromKeyword) { + if (token === ts.SyntaxKind.FromKeyword) { token = nextToken(); - if (token === SyntaxKind.StringLiteral) { + if (token === ts.SyntaxKind.StringLiteral) { // export {a as A} from "mod"; // export {a, b as B} from "mod" recordModuleName(); @@ -221,31 +222,31 @@ namespace ts { } } } - else if (token === SyntaxKind.AsteriskToken) { + else if (token === ts.SyntaxKind.AsteriskToken) { token = nextToken(); - if (token === SyntaxKind.FromKeyword) { + if (token === ts.SyntaxKind.FromKeyword) { token = nextToken(); - if (token === SyntaxKind.StringLiteral) { + if (token === ts.SyntaxKind.StringLiteral) { // export * from "mod" recordModuleName(); } } } - else if (token === SyntaxKind.ImportKeyword) { + else if (token === ts.SyntaxKind.ImportKeyword) { token = nextToken(); - if (token === SyntaxKind.TypeKeyword) { - const skipTypeKeyword = scanner.lookAhead(() => { - const token = scanner.scan(); - return token === SyntaxKind.Identifier || - isKeyword(token); + if (token === ts.SyntaxKind.TypeKeyword) { + const skipTypeKeyword = ts.scanner.lookAhead(() => { + const token = ts.scanner.scan(); + return token === ts.SyntaxKind.Identifier || + ts.isKeyword(token); }); if (skipTypeKeyword) { token = nextToken(); } } - if (token === SyntaxKind.Identifier || isKeyword(token)) { + if (token === ts.SyntaxKind.Identifier || ts.isKeyword(token)) { token = nextToken(); - if (token === SyntaxKind.EqualsToken) { + if (token === ts.SyntaxKind.EqualsToken) { if (tryConsumeRequireCall(/*skipCurrentToken*/ true)) { return true; } @@ -260,13 +261,13 @@ namespace ts { } function tryConsumeRequireCall(skipCurrentToken: boolean, allowTemplateLiterals = false): boolean { - let token = skipCurrentToken ? nextToken() : scanner.getToken(); - if (token === SyntaxKind.RequireKeyword) { + let token = skipCurrentToken ? nextToken() : ts.scanner.getToken(); + if (token === ts.SyntaxKind.RequireKeyword) { token = nextToken(); - if (token === SyntaxKind.OpenParenToken) { + if (token === ts.SyntaxKind.OpenParenToken) { token = nextToken(); - if (token === SyntaxKind.StringLiteral || - allowTemplateLiterals && token === SyntaxKind.NoSubstitutionTemplateLiteral) { + if (token === ts.SyntaxKind.StringLiteral || + allowTemplateLiterals && token === ts.SyntaxKind.NoSubstitutionTemplateLiteral) { // require("mod"); recordModuleName(); } @@ -277,18 +278,18 @@ namespace ts { } function tryConsumeDefine(): boolean { - let token = scanner.getToken(); - if (token === SyntaxKind.Identifier && scanner.getTokenValue() === "define") { + let token = ts.scanner.getToken(); + if (token === ts.SyntaxKind.Identifier && ts.scanner.getTokenValue() === "define") { token = nextToken(); - if (token !== SyntaxKind.OpenParenToken) { + if (token !== ts.SyntaxKind.OpenParenToken) { return true; } token = nextToken(); - if (token === SyntaxKind.StringLiteral || token === SyntaxKind.NoSubstitutionTemplateLiteral) { + if (token === ts.SyntaxKind.StringLiteral || token === ts.SyntaxKind.NoSubstitutionTemplateLiteral) { // looks like define ("modname", ... - skip string literal and comma token = nextToken(); - if (token === SyntaxKind.CommaToken) { + if (token === ts.SyntaxKind.CommaToken) { token = nextToken(); } else { @@ -298,16 +299,16 @@ namespace ts { } // should be start of dependency list - if (token !== SyntaxKind.OpenBracketToken) { + if (token !== ts.SyntaxKind.OpenBracketToken) { return true; } // skip open bracket token = nextToken(); // scan until ']' or EOF - while (token !== SyntaxKind.CloseBracketToken && token !== SyntaxKind.EndOfFileToken) { + while (token !== ts.SyntaxKind.CloseBracketToken && token !== ts.SyntaxKind.EndOfFileToken) { // record string literals as module names - if (token === SyntaxKind.StringLiteral || token === SyntaxKind.NoSubstitutionTemplateLiteral) { + if (token === ts.SyntaxKind.StringLiteral || token === ts.SyntaxKind.NoSubstitutionTemplateLiteral) { recordModuleName(); } @@ -320,7 +321,7 @@ namespace ts { } function processImports(): void { - scanner.setText(sourceText); + ts.scanner.setText(sourceText); nextToken(); // Look for: // import "mod"; @@ -341,32 +342,32 @@ namespace ts { // AnySymbol.nested.import("mod") while (true) { - if (scanner.getToken() === SyntaxKind.EndOfFileToken) { + if (ts.scanner.getToken() === ts.SyntaxKind.EndOfFileToken) { break; } - if (scanner.getToken() === SyntaxKind.TemplateHead) { - const stack = [scanner.getToken()]; - let token = scanner.scan(); - loop: while (length(stack)) { + if (ts.scanner.getToken() === ts.SyntaxKind.TemplateHead) { + const stack = [ts.scanner.getToken()]; + let token = ts.scanner.scan(); + loop: while (ts.length(stack)) { switch (token) { - case SyntaxKind.EndOfFileToken: + case ts.SyntaxKind.EndOfFileToken: break loop; - case SyntaxKind.ImportKeyword: + case ts.SyntaxKind.ImportKeyword: tryConsumeImport(); break; - case SyntaxKind.TemplateHead: + case ts.SyntaxKind.TemplateHead: stack.push(token); break; - case SyntaxKind.OpenBraceToken: - if (length(stack)) { + case ts.SyntaxKind.OpenBraceToken: + if (ts.length(stack)) { stack.push(token); } break; - case SyntaxKind.CloseBraceToken: - if (length(stack)) { - if (lastOrUndefined(stack) === SyntaxKind.TemplateHead) { - if (scanner.reScanTemplateToken(/* isTaggedTemplate */ false) === SyntaxKind.TemplateTail) { + case ts.SyntaxKind.CloseBraceToken: + if (ts.length(stack)) { + if (ts.lastOrUndefined(stack) === ts.SyntaxKind.TemplateHead) { + if (ts.scanner.reScanTemplateToken(/* isTaggedTemplate */ false) === ts.SyntaxKind.TemplateTail) { stack.pop(); } } @@ -376,7 +377,7 @@ namespace ts { } break; } - token = scanner.scan(); + token = ts.scanner.scan(); } nextToken(); } @@ -385,10 +386,8 @@ namespace ts { if (tryConsumeDeclare() || tryConsumeImport() || tryConsumeExport() || - (detectJavaScriptImports && ( - tryConsumeRequireCall(/*skipCurrentToken*/ false, /*allowTemplateLiterals*/ true) || - tryConsumeDefine() - ))) { + (detectJavaScriptImports && (tryConsumeRequireCall(/*skipCurrentToken*/ false, /*allowTemplateLiterals*/ true) || + tryConsumeDefine()))) { continue; } else { @@ -396,14 +395,14 @@ namespace ts { } } - scanner.setText(undefined); + ts.scanner.setText(undefined); } if (readImportFiles) { processImports(); } - processCommentPragmas(pragmaContext, sourceText); - processPragmasIntoFields(pragmaContext, noop); + ts.processCommentPragmas(pragmaContext, sourceText); + ts.processPragmasIntoFields(pragmaContext, ts.noop); if (externalModule) { // for external modules module all nested ambient modules are augmentations if (ambientExternalModules) { diff --git a/src/services/refactorProvider.ts b/src/services/refactorProvider.ts index ccc6f81d2924d..fcd091ca4d62a 100644 --- a/src/services/refactorProvider.ts +++ b/src/services/refactorProvider.ts @@ -2,21 +2,20 @@ namespace ts.refactor { // A map with the refactor code as key, the refactor itself as value // e.g. nonSuggestableRefactors[refactorCode] -> the refactor you want - const refactors = new Map(); + const refactors = new ts.Map(); /** @param name An unique code associated with each refactor. Does not have to be human-readable. */ - export function registerRefactor(name: string, refactor: Refactor) { + export function registerRefactor(name: string, refactor: ts.Refactor) { refactors.set(name, refactor); } - export function getApplicableRefactors(context: RefactorContext): ApplicableRefactorInfo[] { - return arrayFrom(flatMapIterator(refactors.values(), refactor => - context.cancellationToken && context.cancellationToken.isCancellationRequested() || - !refactor.kinds?.some(kind => refactorKindBeginsWith(kind, context.kind)) ? undefined : + export function getApplicableRefactors(context: ts.RefactorContext): ts.ApplicableRefactorInfo[] { + return ts.arrayFrom(ts.flatMapIterator(refactors.values(), refactor => context.cancellationToken && context.cancellationToken.isCancellationRequested() || + !refactor.kinds?.some(kind => ts.refactor.refactorKindBeginsWith(kind, context.kind)) ? undefined : refactor.getAvailableActions(context))); } - export function getEditsForRefactor(context: RefactorContext, refactorName: string, actionName: string): RefactorEditInfo | undefined { + export function getEditsForRefactor(context: ts.RefactorContext, refactorName: string, actionName: string): ts.RefactorEditInfo | undefined { const refactor = refactors.get(refactorName); return refactor && refactor.getEditsForAction(context, actionName); } diff --git a/src/services/refactors/addOrRemoveBracesToArrowFunction.ts b/src/services/refactors/addOrRemoveBracesToArrowFunction.ts index aba1a33664085..e21f3676f80bc 100644 --- a/src/services/refactors/addOrRemoveBracesToArrowFunction.ts +++ b/src/services/refactors/addOrRemoveBracesToArrowFunction.ts @@ -1,37 +1,37 @@ /* @internal */ namespace ts.refactor.addOrRemoveBracesToArrowFunction { const refactorName = "Add or remove braces in an arrow function"; - const refactorDescription = Diagnostics.Add_or_remove_braces_in_an_arrow_function.message; + const refactorDescription = ts.Diagnostics.Add_or_remove_braces_in_an_arrow_function.message; const addBracesAction = { name: "Add braces to arrow function", - description: Diagnostics.Add_braces_to_arrow_function.message, + description: ts.Diagnostics.Add_braces_to_arrow_function.message, kind: "refactor.rewrite.arrow.braces.add", }; const removeBracesAction = { name: "Remove braces from arrow function", - description: Diagnostics.Remove_braces_from_arrow_function.message, + description: ts.Diagnostics.Remove_braces_from_arrow_function.message, kind: "refactor.rewrite.arrow.braces.remove" }; - registerRefactor(refactorName, { + ts.refactor.registerRefactor(refactorName, { kinds: [removeBracesAction.kind], getEditsForAction: getRefactorEditsToRemoveFunctionBraces, getAvailableActions: getRefactorActionsToRemoveFunctionBraces }); interface FunctionBracesInfo { - func: ArrowFunction; - expression: Expression | undefined; - returnStatement?: ReturnStatement; + func: ts.ArrowFunction; + expression: ts.Expression | undefined; + returnStatement?: ts.ReturnStatement; addBraces: boolean; } - function getRefactorActionsToRemoveFunctionBraces(context: RefactorContext): readonly ApplicableRefactorInfo[] { + function getRefactorActionsToRemoveFunctionBraces(context: ts.RefactorContext): readonly ts.ApplicableRefactorInfo[] { const { file, startPosition, triggerReason } = context; const info = getConvertibleArrowFunctionAtPosition(file, startPosition, triggerReason === "invoked"); - if (!info) return emptyArray; - - if (!isRefactorErrorInfo(info)) { + if (!info) + return ts.emptyArray; + if (!ts.refactor.isRefactorErrorInfo(info)) { return [{ name: refactorName, description: refactorDescription, @@ -52,67 +52,67 @@ namespace ts.refactor.addOrRemoveBracesToArrowFunction { }]; } - return emptyArray; + return ts.emptyArray; } - function getRefactorEditsToRemoveFunctionBraces(context: RefactorContext, actionName: string): RefactorEditInfo | undefined { + function getRefactorEditsToRemoveFunctionBraces(context: ts.RefactorContext, actionName: string): ts.RefactorEditInfo | undefined { const { file, startPosition } = context; const info = getConvertibleArrowFunctionAtPosition(file, startPosition); - Debug.assert(info && !isRefactorErrorInfo(info), "Expected applicable refactor info"); + ts.Debug.assert(info && !ts.refactor.isRefactorErrorInfo(info), "Expected applicable refactor info"); const { expression, returnStatement, func } = info; - let body: ConciseBody; + let body: ts.ConciseBody; if (actionName === addBracesAction.name) { - const returnStatement = factory.createReturnStatement(expression); - body = factory.createBlock([returnStatement], /* multiLine */ true); - copyLeadingComments(expression!, returnStatement, file, SyntaxKind.MultiLineCommentTrivia, /* hasTrailingNewLine */ true); + const returnStatement = ts.factory.createReturnStatement(expression); + body = ts.factory.createBlock([returnStatement], /* multiLine */ true); + ts.copyLeadingComments(expression!, returnStatement, file, ts.SyntaxKind.MultiLineCommentTrivia, /* hasTrailingNewLine */ true); } else if (actionName === removeBracesAction.name && returnStatement) { - const actualExpression = expression || factory.createVoidZero(); - body = needsParentheses(actualExpression) ? factory.createParenthesizedExpression(actualExpression) : actualExpression; - copyTrailingAsLeadingComments(returnStatement, body, file, SyntaxKind.MultiLineCommentTrivia, /* hasTrailingNewLine */ false); - copyLeadingComments(returnStatement, body, file, SyntaxKind.MultiLineCommentTrivia, /* hasTrailingNewLine */ false); - copyTrailingComments(returnStatement, body, file, SyntaxKind.MultiLineCommentTrivia, /* hasTrailingNewLine */ false); + const actualExpression = expression || ts.factory.createVoidZero(); + body = ts.needsParentheses(actualExpression) ? ts.factory.createParenthesizedExpression(actualExpression) : actualExpression; + ts.copyTrailingAsLeadingComments(returnStatement, body, file, ts.SyntaxKind.MultiLineCommentTrivia, /* hasTrailingNewLine */ false); + ts.copyLeadingComments(returnStatement, body, file, ts.SyntaxKind.MultiLineCommentTrivia, /* hasTrailingNewLine */ false); + ts.copyTrailingComments(returnStatement, body, file, ts.SyntaxKind.MultiLineCommentTrivia, /* hasTrailingNewLine */ false); } else { - Debug.fail("invalid action"); + ts.Debug.fail("invalid action"); } - const edits = textChanges.ChangeTracker.with(context, t => { + const edits = ts.textChanges.ChangeTracker.with(context, t => { t.replaceNode(file, func.body, body); }); return { renameFilename: undefined, renameLocation: undefined, edits }; } - function getConvertibleArrowFunctionAtPosition(file: SourceFile, startPosition: number, considerFunctionBodies = true, kind?: string): FunctionBracesInfo | RefactorErrorInfo | undefined { - const node = getTokenAtPosition(file, startPosition); - const func = getContainingFunction(node); + function getConvertibleArrowFunctionAtPosition(file: ts.SourceFile, startPosition: number, considerFunctionBodies = true, kind?: string): FunctionBracesInfo | ts.refactor.RefactorErrorInfo | undefined { + const node = ts.getTokenAtPosition(file, startPosition); + const func = ts.getContainingFunction(node); if (!func) { return { - error: getLocaleSpecificMessage(Diagnostics.Could_not_find_a_containing_arrow_function) + error: ts.getLocaleSpecificMessage(ts.Diagnostics.Could_not_find_a_containing_arrow_function) }; } - if (!isArrowFunction(func)) { + if (!ts.isArrowFunction(func)) { return { - error: getLocaleSpecificMessage(Diagnostics.Containing_function_is_not_an_arrow_function) + error: ts.getLocaleSpecificMessage(ts.Diagnostics.Containing_function_is_not_an_arrow_function) }; } - if ((!rangeContainsRange(func, node) || rangeContainsRange(func.body, node) && !considerFunctionBodies)) { + if ((!ts.rangeContainsRange(func, node) || ts.rangeContainsRange(func.body, node) && !considerFunctionBodies)) { return undefined; } - if (refactorKindBeginsWith(addBracesAction.kind, kind) && isExpression(func.body)) { + if (ts.refactor.refactorKindBeginsWith(addBracesAction.kind, kind) && ts.isExpression(func.body)) { return { func, addBraces: true, expression: func.body }; } - else if (refactorKindBeginsWith(removeBracesAction.kind, kind) && isBlock(func.body) && func.body.statements.length === 1) { - const firstStatement = first(func.body.statements); - if (isReturnStatement(firstStatement)) { + else if (ts.refactor.refactorKindBeginsWith(removeBracesAction.kind, kind) && ts.isBlock(func.body) && func.body.statements.length === 1) { + const firstStatement = ts.first(func.body.statements); + if (ts.isReturnStatement(firstStatement)) { return { func, addBraces: false, expression: firstStatement.expression, returnStatement: firstStatement }; } } diff --git a/src/services/refactors/convertArrowFunctionOrFunctionExpression.ts b/src/services/refactors/convertArrowFunctionOrFunctionExpression.ts index ea0c72a4dd684..5779d4b8694a0 100644 --- a/src/services/refactors/convertArrowFunctionOrFunctionExpression.ts +++ b/src/services/refactors/convertArrowFunctionOrFunctionExpression.ts @@ -1,24 +1,24 @@ /* @internal */ namespace ts.refactor.convertArrowFunctionOrFunctionExpression { const refactorName = "Convert arrow function or function expression"; - const refactorDescription = getLocaleSpecificMessage(Diagnostics.Convert_arrow_function_or_function_expression); + const refactorDescription = ts.getLocaleSpecificMessage(ts.Diagnostics.Convert_arrow_function_or_function_expression); const toAnonymousFunctionAction = { name: "Convert to anonymous function", - description: getLocaleSpecificMessage(Diagnostics.Convert_to_anonymous_function), + description: ts.getLocaleSpecificMessage(ts.Diagnostics.Convert_to_anonymous_function), kind: "refactor.rewrite.function.anonymous", }; const toNamedFunctionAction = { name: "Convert to named function", - description: getLocaleSpecificMessage(Diagnostics.Convert_to_named_function), + description: ts.getLocaleSpecificMessage(ts.Diagnostics.Convert_to_named_function), kind: "refactor.rewrite.function.named", }; const toArrowFunctionAction = { name: "Convert to arrow function", - description: getLocaleSpecificMessage(Diagnostics.Convert_to_arrow_function), + description: ts.getLocaleSpecificMessage(ts.Diagnostics.Convert_to_arrow_function), kind: "refactor.rewrite.function.arrow", }; - registerRefactor(refactorName, { + ts.refactor.registerRefactor(refactorName, { kinds: [ toAnonymousFunctionAction.kind, toNamedFunctionAction.kind, @@ -30,27 +30,28 @@ namespace ts.refactor.convertArrowFunctionOrFunctionExpression { interface FunctionInfo { readonly selectedVariableDeclaration: boolean; - readonly func: FunctionExpression | ArrowFunction; + readonly func: ts.FunctionExpression | ts.ArrowFunction; } interface VariableInfo { - readonly variableDeclaration: VariableDeclaration; - readonly variableDeclarationList: VariableDeclarationList; - readonly statement: VariableStatement; - readonly name: Identifier; + readonly variableDeclaration: ts.VariableDeclaration; + readonly variableDeclarationList: ts.VariableDeclarationList; + readonly statement: ts.VariableStatement; + readonly name: ts.Identifier; } - function getRefactorActionsToConvertFunctionExpressions(context: RefactorContext): readonly ApplicableRefactorInfo[] { + function getRefactorActionsToConvertFunctionExpressions(context: ts.RefactorContext): readonly ts.ApplicableRefactorInfo[] { const { file, startPosition, program, kind } = context; const info = getFunctionInfo(file, startPosition, program); - if (!info) return emptyArray; + if (!info) + return ts.emptyArray; const { selectedVariableDeclaration, func } = info; - const possibleActions: RefactorActionInfo[] = []; - const errors: RefactorActionInfo[] = []; - if (refactorKindBeginsWith(toNamedFunctionAction.kind, kind)) { - const error = selectedVariableDeclaration || (isArrowFunction(func) && isVariableDeclaration(func.parent)) ? - undefined : getLocaleSpecificMessage(Diagnostics.Could_not_convert_to_named_function); + const possibleActions: ts.RefactorActionInfo[] = []; + const errors: ts.RefactorActionInfo[] = []; + if (ts.refactor.refactorKindBeginsWith(toNamedFunctionAction.kind, kind)) { + const error = selectedVariableDeclaration || (ts.isArrowFunction(func) && ts.isVariableDeclaration(func.parent)) ? + undefined : ts.getLocaleSpecificMessage(ts.Diagnostics.Could_not_convert_to_named_function); if (error) { errors.push({ ...toNamedFunctionAction, notApplicableReason: error }); } @@ -59,9 +60,9 @@ namespace ts.refactor.convertArrowFunctionOrFunctionExpression { } } - if (refactorKindBeginsWith(toAnonymousFunctionAction.kind, kind)) { - const error = !selectedVariableDeclaration && isArrowFunction(func) ? - undefined: getLocaleSpecificMessage(Diagnostics.Could_not_convert_to_anonymous_function); + if (ts.refactor.refactorKindBeginsWith(toAnonymousFunctionAction.kind, kind)) { + const error = !selectedVariableDeclaration && ts.isArrowFunction(func) ? + undefined : ts.getLocaleSpecificMessage(ts.Diagnostics.Could_not_convert_to_anonymous_function); if (error) { errors.push({ ...toAnonymousFunctionAction, notApplicableReason: error }); } @@ -70,8 +71,8 @@ namespace ts.refactor.convertArrowFunctionOrFunctionExpression { } } - if (refactorKindBeginsWith(toArrowFunctionAction.kind, kind)) { - const error = isFunctionExpression(func) ? undefined : getLocaleSpecificMessage(Diagnostics.Could_not_convert_to_arrow_function); + if (ts.refactor.refactorKindBeginsWith(toArrowFunctionAction.kind, kind)) { + const error = ts.isFunctionExpression(func) ? undefined : ts.getLocaleSpecificMessage(ts.Diagnostics.Could_not_convert_to_arrow_function); if (error) { errors.push({ ...toArrowFunctionAction, notApplicableReason: error }); } @@ -88,13 +89,14 @@ namespace ts.refactor.convertArrowFunctionOrFunctionExpression { }]; } - function getRefactorEditsToConvertFunctionExpressions(context: RefactorContext, actionName: string): RefactorEditInfo | undefined { + function getRefactorEditsToConvertFunctionExpressions(context: ts.RefactorContext, actionName: string): ts.RefactorEditInfo | undefined { const { file, startPosition, program } = context; const info = getFunctionInfo(file, startPosition, program); - if (!info) return undefined; + if (!info) + return undefined; const { func } = info; - const edits: FileTextChanges[] = []; + const edits: ts.FileTextChanges[] = []; switch (actionName) { case toAnonymousFunctionAction.name: @@ -103,156 +105,158 @@ namespace ts.refactor.convertArrowFunctionOrFunctionExpression { case toNamedFunctionAction.name: const variableInfo = getVariableInfo(func); - if (!variableInfo) return undefined; + if (!variableInfo) + return undefined; edits.push(...getEditInfoForConvertToNamedFunction(context, func, variableInfo)); break; case toArrowFunctionAction.name: - if (!isFunctionExpression(func)) return undefined; + if (!ts.isFunctionExpression(func)) + return undefined; edits.push(...getEditInfoForConvertToArrowFunction(context, func)); break; default: - return Debug.fail("invalid action"); + return ts.Debug.fail("invalid action"); } return { renameFilename: undefined, renameLocation: undefined, edits }; } - function containingThis(node: Node): boolean { + function containingThis(node: ts.Node): boolean { let containsThis = false; node.forEachChild(function checkThis(child) { - if (isThis(child)) { + if (ts.isThis(child)) { containsThis = true; return; } - if (!isClassLike(child) && !isFunctionDeclaration(child) && !isFunctionExpression(child)) { - forEachChild(child, checkThis); + if (!ts.isClassLike(child) && !ts.isFunctionDeclaration(child) && !ts.isFunctionExpression(child)) { + ts.forEachChild(child, checkThis); } }); return containsThis; } - function getFunctionInfo(file: SourceFile, startPosition: number, program: Program): FunctionInfo | undefined { - const token = getTokenAtPosition(file, startPosition); + function getFunctionInfo(file: ts.SourceFile, startPosition: number, program: ts.Program): FunctionInfo | undefined { + const token = ts.getTokenAtPosition(file, startPosition); const typeChecker = program.getTypeChecker(); const func = tryGetFunctionFromVariableDeclaration(file, typeChecker, token.parent); if (func && !containingThis(func.body) && !typeChecker.containsArgumentsReference(func)) { return { selectedVariableDeclaration: true, func }; } - const maybeFunc = getContainingFunction(token); - if ( - maybeFunc && - (isFunctionExpression(maybeFunc) || isArrowFunction(maybeFunc)) && - !rangeContainsRange(maybeFunc.body, token) && + const maybeFunc = ts.getContainingFunction(token); + if (maybeFunc && + (ts.isFunctionExpression(maybeFunc) || ts.isArrowFunction(maybeFunc)) && + !ts.rangeContainsRange(maybeFunc.body, token) && !containingThis(maybeFunc.body) && - !typeChecker.containsArgumentsReference(maybeFunc) - ) { - if (isFunctionExpression(maybeFunc) && isFunctionReferencedInFile(file, typeChecker, maybeFunc)) return undefined; + !typeChecker.containsArgumentsReference(maybeFunc)) { + if (ts.isFunctionExpression(maybeFunc) && isFunctionReferencedInFile(file, typeChecker, maybeFunc)) + return undefined; return { selectedVariableDeclaration: false, func: maybeFunc }; } return undefined; } - function isSingleVariableDeclaration(parent: Node): parent is VariableDeclarationList { - return isVariableDeclaration(parent) || (isVariableDeclarationList(parent) && parent.declarations.length === 1); + function isSingleVariableDeclaration(parent: ts.Node): parent is ts.VariableDeclarationList { + return ts.isVariableDeclaration(parent) || (ts.isVariableDeclarationList(parent) && parent.declarations.length === 1); } - function tryGetFunctionFromVariableDeclaration(sourceFile: SourceFile, typeChecker: TypeChecker, parent: Node): ArrowFunction | FunctionExpression | undefined { + function tryGetFunctionFromVariableDeclaration(sourceFile: ts.SourceFile, typeChecker: ts.TypeChecker, parent: ts.Node): ts.ArrowFunction | ts.FunctionExpression | undefined { if (!isSingleVariableDeclaration(parent)) { return undefined; } - const variableDeclaration = isVariableDeclaration(parent) ? parent : first(parent.declarations); + const variableDeclaration = ts.isVariableDeclaration(parent) ? parent : ts.first(parent.declarations); const initializer = variableDeclaration.initializer; - if (initializer && (isArrowFunction(initializer) || isFunctionExpression(initializer) && !isFunctionReferencedInFile(sourceFile, typeChecker, initializer))) { + if (initializer && (ts.isArrowFunction(initializer) || ts.isFunctionExpression(initializer) && !isFunctionReferencedInFile(sourceFile, typeChecker, initializer))) { return initializer; } return undefined; } - function convertToBlock(body: ConciseBody): Block { - if (isExpression(body)) { - const returnStatement = factory.createReturnStatement(body); + function convertToBlock(body: ts.ConciseBody): ts.Block { + if (ts.isExpression(body)) { + const returnStatement = ts.factory.createReturnStatement(body); const file = body.getSourceFile(); - suppressLeadingAndTrailingTrivia(returnStatement); - copyTrailingAsLeadingComments(body, returnStatement, file, /* commentKind */ undefined, /* hasTrailingNewLine */ true); - return factory.createBlock([returnStatement], /* multiLine */ true); + ts.suppressLeadingAndTrailingTrivia(returnStatement); + ts.copyTrailingAsLeadingComments(body, returnStatement, file, /* commentKind */ undefined, /* hasTrailingNewLine */ true); + return ts.factory.createBlock([returnStatement], /* multiLine */ true); } else { return body; } } - function getVariableInfo(func: FunctionExpression | ArrowFunction): VariableInfo | undefined { + function getVariableInfo(func: ts.FunctionExpression | ts.ArrowFunction): VariableInfo | undefined { const variableDeclaration = func.parent; - if (!isVariableDeclaration(variableDeclaration) || !isVariableDeclarationInVariableStatement(variableDeclaration)) return undefined; + if (!ts.isVariableDeclaration(variableDeclaration) || !ts.isVariableDeclarationInVariableStatement(variableDeclaration)) + return undefined; const variableDeclarationList = variableDeclaration.parent; const statement = variableDeclarationList.parent; - if (!isVariableDeclarationList(variableDeclarationList) || !isVariableStatement(statement) || !isIdentifier(variableDeclaration.name)) return undefined; + if (!ts.isVariableDeclarationList(variableDeclarationList) || !ts.isVariableStatement(statement) || !ts.isIdentifier(variableDeclaration.name)) + return undefined; return { variableDeclaration, variableDeclarationList, statement, name: variableDeclaration.name }; } - function getEditInfoForConvertToAnonymousFunction(context: RefactorContext, func: FunctionExpression | ArrowFunction): FileTextChanges[] { + function getEditInfoForConvertToAnonymousFunction(context: ts.RefactorContext, func: ts.FunctionExpression | ts.ArrowFunction): ts.FileTextChanges[] { const { file } = context; const body = convertToBlock(func.body); - const newNode = factory.createFunctionExpression(func.modifiers, func.asteriskToken, /* name */ undefined, func.typeParameters, func.parameters, func.type, body); - return textChanges.ChangeTracker.with(context, t => t.replaceNode(file, func, newNode)); + const newNode = ts.factory.createFunctionExpression(func.modifiers, func.asteriskToken, /* name */ undefined, func.typeParameters, func.parameters, func.type, body); + return ts.textChanges.ChangeTracker.with(context, t => t.replaceNode(file, func, newNode)); } - function getEditInfoForConvertToNamedFunction(context: RefactorContext, func: FunctionExpression | ArrowFunction, variableInfo: VariableInfo): FileTextChanges[] { + function getEditInfoForConvertToNamedFunction(context: ts.RefactorContext, func: ts.FunctionExpression | ts.ArrowFunction, variableInfo: VariableInfo): ts.FileTextChanges[] { const { file } = context; const body = convertToBlock(func.body); const { variableDeclaration, variableDeclarationList, statement, name } = variableInfo; - suppressLeadingTrivia(statement); - - const modifiersFlags = (getCombinedModifierFlags(variableDeclaration) & ModifierFlags.Export) | getEffectiveModifierFlags(func); - const modifiers = factory.createModifiersFromModifierFlags(modifiersFlags); - const newNode = factory.createFunctionDeclaration(func.decorators, length(modifiers) ? modifiers : undefined, func.asteriskToken, name, func.typeParameters, func.parameters, func.type, body); + ts.suppressLeadingTrivia(statement); + const modifiersFlags = (ts.getCombinedModifierFlags(variableDeclaration) & ts.ModifierFlags.Export) | ts.getEffectiveModifierFlags(func); + const modifiers = ts.factory.createModifiersFromModifierFlags(modifiersFlags); + const newNode = ts.factory.createFunctionDeclaration(func.decorators, ts.length(modifiers) ? modifiers : undefined, func.asteriskToken, name, func.typeParameters, func.parameters, func.type, body); if (variableDeclarationList.declarations.length === 1) { - return textChanges.ChangeTracker.with(context, t => t.replaceNode(file, statement, newNode)); + return ts.textChanges.ChangeTracker.with(context, t => t.replaceNode(file, statement, newNode)); } else { - return textChanges.ChangeTracker.with(context, t => { + return ts.textChanges.ChangeTracker.with(context, t => { t.delete(file, variableDeclaration); t.insertNodeAfter(file, statement, newNode); }); } } - function getEditInfoForConvertToArrowFunction(context: RefactorContext, func: FunctionExpression): FileTextChanges[] { + function getEditInfoForConvertToArrowFunction(context: ts.RefactorContext, func: ts.FunctionExpression): ts.FileTextChanges[] { const { file } = context; const statements = func.body.statements; const head = statements[0]; - let body: ConciseBody; + let body: ts.ConciseBody; if (canBeConvertedToExpression(func.body, head)) { body = head.expression!; - suppressLeadingAndTrailingTrivia(body); - copyComments(head, body); + ts.suppressLeadingAndTrailingTrivia(body); + ts.copyComments(head, body); } else { body = func.body; } - const newNode = factory.createArrowFunction(func.modifiers, func.typeParameters, func.parameters, func.type, factory.createToken(SyntaxKind.EqualsGreaterThanToken), body); - return textChanges.ChangeTracker.with(context, t => t.replaceNode(file, func, newNode)); + const newNode = ts.factory.createArrowFunction(func.modifiers, func.typeParameters, func.parameters, func.type, ts.factory.createToken(ts.SyntaxKind.EqualsGreaterThanToken), body); + return ts.textChanges.ChangeTracker.with(context, t => t.replaceNode(file, func, newNode)); } - function canBeConvertedToExpression(body: Block, head: Statement): head is ReturnStatement { - return body.statements.length === 1 && ((isReturnStatement(head) && !!head.expression)); + function canBeConvertedToExpression(body: ts.Block, head: ts.Statement): head is ts.ReturnStatement { + return body.statements.length === 1 && ((ts.isReturnStatement(head) && !!head.expression)); } - function isFunctionReferencedInFile(sourceFile: SourceFile, typeChecker: TypeChecker, node: FunctionExpression): boolean { - return !!node.name && FindAllReferences.Core.isSymbolReferencedInFile(node.name, typeChecker, sourceFile); + function isFunctionReferencedInFile(sourceFile: ts.SourceFile, typeChecker: ts.TypeChecker, node: ts.FunctionExpression): boolean { + return !!node.name && ts.FindAllReferences.Core.isSymbolReferencedInFile(node.name, typeChecker, sourceFile); } } diff --git a/src/services/refactors/convertExport.ts b/src/services/refactors/convertExport.ts index 738731a5c8aca..a5705a1a45b4b 100644 --- a/src/services/refactors/convertExport.ts +++ b/src/services/refactors/convertExport.ts @@ -4,167 +4,166 @@ namespace ts.refactor { const defaultToNamedAction = { name: "Convert default export to named export", - description: Diagnostics.Convert_default_export_to_named_export.message, + description: ts.Diagnostics.Convert_default_export_to_named_export.message, kind: "refactor.rewrite.export.named" }; const namedToDefaultAction = { name: "Convert named export to default export", - description: Diagnostics.Convert_named_export_to_default_export.message, + description: ts.Diagnostics.Convert_named_export_to_default_export.message, kind: "refactor.rewrite.export.default" }; - registerRefactor(refactorName, { + ts.refactor.registerRefactor(refactorName, { kinds: [ defaultToNamedAction.kind, namedToDefaultAction.kind ], - getAvailableActions: function getRefactorActionsToConvertBetweenNamedAndDefaultExports(context): readonly ApplicableRefactorInfo[] { + getAvailableActions: function getRefactorActionsToConvertBetweenNamedAndDefaultExports(context): readonly ts.ApplicableRefactorInfo[] { const info = getInfo(context, context.triggerReason === "invoked"); - if (!info) return emptyArray; - - if (!isRefactorErrorInfo(info)) { + if (!info) + return ts.emptyArray; + if (!ts.refactor.isRefactorErrorInfo(info)) { const action = info.wasDefault ? defaultToNamedAction : namedToDefaultAction; return [{ name: refactorName, description: action.description, actions: [action] }]; } if (context.preferences.provideRefactorNotApplicableReason) { return [ - { name: refactorName, description: Diagnostics.Convert_default_export_to_named_export.message, actions: [ + { name: refactorName, description: ts.Diagnostics.Convert_default_export_to_named_export.message, actions: [ { ...defaultToNamedAction, notApplicableReason: info.error }, { ...namedToDefaultAction, notApplicableReason: info.error }, ]} ]; } - return emptyArray; + return ts.emptyArray; }, - getEditsForAction: function getRefactorEditsToConvertBetweenNamedAndDefaultExports(context, actionName): RefactorEditInfo { - Debug.assert(actionName === defaultToNamedAction.name || actionName === namedToDefaultAction.name, "Unexpected action name"); + getEditsForAction: function getRefactorEditsToConvertBetweenNamedAndDefaultExports(context, actionName): ts.RefactorEditInfo { + ts.Debug.assert(actionName === defaultToNamedAction.name || actionName === namedToDefaultAction.name, "Unexpected action name"); const info = getInfo(context); - Debug.assert(info && !isRefactorErrorInfo(info), "Expected applicable refactor info"); - const edits = textChanges.ChangeTracker.with(context, t => doChange(context.file, context.program, info, t, context.cancellationToken)); + ts.Debug.assert(info && !ts.refactor.isRefactorErrorInfo(info), "Expected applicable refactor info"); + const edits = ts.textChanges.ChangeTracker.with(context, t => doChange(context.file, context.program, info, t, context.cancellationToken)); return { edits, renameFilename: undefined, renameLocation: undefined }; }, }); // If a VariableStatement, will have exactly one VariableDeclaration, with an Identifier for a name. - type ExportToConvert = FunctionDeclaration | ClassDeclaration | InterfaceDeclaration | EnumDeclaration | NamespaceDeclaration | TypeAliasDeclaration | VariableStatement | ExportAssignment; + type ExportToConvert = ts.FunctionDeclaration | ts.ClassDeclaration | ts.InterfaceDeclaration | ts.EnumDeclaration | ts.NamespaceDeclaration | ts.TypeAliasDeclaration | ts.VariableStatement | ts.ExportAssignment; interface ExportInfo { readonly exportNode: ExportToConvert; - readonly exportName: Identifier; // This is exportNode.name except for VariableStatement_s. + readonly exportName: ts.Identifier; // This is exportNode.name except for VariableStatement_s. readonly wasDefault: boolean; - readonly exportingModuleSymbol: Symbol; - }; - - function getInfo(context: RefactorContext, considerPartialSpans = true): ExportInfo | RefactorErrorInfo | undefined { + readonly exportingModuleSymbol: ts.Symbol; + } + ; + function getInfo(context: ts.RefactorContext, considerPartialSpans = true): ExportInfo | ts.refactor.RefactorErrorInfo | undefined { const { file, program } = context; - const span = getRefactorContextSpan(context); - const token = getTokenAtPosition(file, span.start); - const exportNode = !!(token.parent && getSyntacticModifierFlags(token.parent) & ModifierFlags.Export) && considerPartialSpans ? token.parent : getParentNodeInSpan(token, file, span); - if (!exportNode || (!isSourceFile(exportNode.parent) && !(isModuleBlock(exportNode.parent) && isAmbientModule(exportNode.parent.parent)))) { - return { error: getLocaleSpecificMessage(Diagnostics.Could_not_find_export_statement) }; + const span = ts.getRefactorContextSpan(context); + const token = ts.getTokenAtPosition(file, span.start); + const exportNode = !!(token.parent && ts.getSyntacticModifierFlags(token.parent) & ts.ModifierFlags.Export) && considerPartialSpans ? token.parent : ts.getParentNodeInSpan(token, file, span); + if (!exportNode || (!ts.isSourceFile(exportNode.parent) && !(ts.isModuleBlock(exportNode.parent) && ts.isAmbientModule(exportNode.parent.parent)))) { + return { error: ts.getLocaleSpecificMessage(ts.Diagnostics.Could_not_find_export_statement) }; } - - const exportingModuleSymbol = isSourceFile(exportNode.parent) ? exportNode.parent.symbol : exportNode.parent.parent.symbol; - - const flags = getSyntacticModifierFlags(exportNode) || ((isExportAssignment(exportNode) && !exportNode.isExportEquals) ? ModifierFlags.ExportDefault : ModifierFlags.None); - - const wasDefault = !!(flags & ModifierFlags.Default); + const exportingModuleSymbol = ts.isSourceFile(exportNode.parent) ? exportNode.parent.symbol : exportNode.parent.parent.symbol; + const flags = ts.getSyntacticModifierFlags(exportNode) || ((ts.isExportAssignment(exportNode) && !exportNode.isExportEquals) ? ts.ModifierFlags.ExportDefault : ts.ModifierFlags.None); + const wasDefault = !!(flags & ts.ModifierFlags.Default); // If source file already has a default export, don't offer refactor. - if (!(flags & ModifierFlags.Export) || !wasDefault && exportingModuleSymbol.exports!.has(InternalSymbolName.Default)) { - return { error: getLocaleSpecificMessage(Diagnostics.This_file_already_has_a_default_export) }; + if (!(flags & ts.ModifierFlags.Export) || !wasDefault && exportingModuleSymbol.exports!.has(ts.InternalSymbolName.Default)) { + return { error: ts.getLocaleSpecificMessage(ts.Diagnostics.This_file_already_has_a_default_export) }; } const checker = program.getTypeChecker(); - const noSymbolError = (id: Node) => - (isIdentifier(id) && checker.getSymbolAtLocation(id)) ? undefined - : { error: getLocaleSpecificMessage(Diagnostics.Can_only_convert_named_export) }; + const noSymbolError = (id: ts.Node) => (ts.isIdentifier(id) && checker.getSymbolAtLocation(id)) ? undefined + : { error: ts.getLocaleSpecificMessage(ts.Diagnostics.Can_only_convert_named_export) }; switch (exportNode.kind) { - case SyntaxKind.FunctionDeclaration: - case SyntaxKind.ClassDeclaration: - case SyntaxKind.InterfaceDeclaration: - case SyntaxKind.EnumDeclaration: - case SyntaxKind.TypeAliasDeclaration: - case SyntaxKind.ModuleDeclaration: { - const node = exportNode as FunctionDeclaration | ClassDeclaration | InterfaceDeclaration | EnumDeclaration | TypeAliasDeclaration | NamespaceDeclaration; - if (!node.name) return undefined; + case ts.SyntaxKind.FunctionDeclaration: + case ts.SyntaxKind.ClassDeclaration: + case ts.SyntaxKind.InterfaceDeclaration: + case ts.SyntaxKind.EnumDeclaration: + case ts.SyntaxKind.TypeAliasDeclaration: + case ts.SyntaxKind.ModuleDeclaration: { + const node = exportNode as ts.FunctionDeclaration | ts.ClassDeclaration | ts.InterfaceDeclaration | ts.EnumDeclaration | ts.TypeAliasDeclaration | ts.NamespaceDeclaration; + if (!node.name) + return undefined; return noSymbolError(node.name) || { exportNode: node, exportName: node.name, wasDefault, exportingModuleSymbol }; } - case SyntaxKind.VariableStatement: { - const vs = exportNode as VariableStatement; + case ts.SyntaxKind.VariableStatement: { + const vs = exportNode as ts.VariableStatement; // Must be `export const x = something;`. - if (!(vs.declarationList.flags & NodeFlags.Const) || vs.declarationList.declarations.length !== 1) { + if (!(vs.declarationList.flags & ts.NodeFlags.Const) || vs.declarationList.declarations.length !== 1) { return undefined; } - const decl = first(vs.declarationList.declarations); - if (!decl.initializer) return undefined; - Debug.assert(!wasDefault, "Can't have a default flag here"); + const decl = ts.first(vs.declarationList.declarations); + if (!decl.initializer) + return undefined; + ts.Debug.assert(!wasDefault, "Can't have a default flag here"); return noSymbolError(decl.name) - || { exportNode: vs, exportName: decl.name as Identifier, wasDefault, exportingModuleSymbol }; + || { exportNode: vs, exportName: decl.name as ts.Identifier, wasDefault, exportingModuleSymbol }; } - case SyntaxKind.ExportAssignment: { - const node = exportNode as ExportAssignment; - if (node.isExportEquals) return undefined; + case ts.SyntaxKind.ExportAssignment: { + const node = exportNode as ts.ExportAssignment; + if (node.isExportEquals) + return undefined; return noSymbolError(node.expression) - || { exportNode: node, exportName: node.expression as Identifier, wasDefault, exportingModuleSymbol }; + || { exportNode: node, exportName: node.expression as ts.Identifier, wasDefault, exportingModuleSymbol }; } default: return undefined; } } - function doChange(exportingSourceFile: SourceFile, program: Program, info: ExportInfo, changes: textChanges.ChangeTracker, cancellationToken: CancellationToken | undefined): void { + function doChange(exportingSourceFile: ts.SourceFile, program: ts.Program, info: ExportInfo, changes: ts.textChanges.ChangeTracker, cancellationToken: ts.CancellationToken | undefined): void { changeExport(exportingSourceFile, info, changes, program.getTypeChecker()); changeImports(program, info, changes, cancellationToken); } - function changeExport(exportingSourceFile: SourceFile, { wasDefault, exportNode, exportName }: ExportInfo, changes: textChanges.ChangeTracker, checker: TypeChecker): void { + function changeExport(exportingSourceFile: ts.SourceFile, { wasDefault, exportNode, exportName }: ExportInfo, changes: ts.textChanges.ChangeTracker, checker: ts.TypeChecker): void { if (wasDefault) { - if (isExportAssignment(exportNode) && !exportNode.isExportEquals) { - const exp = exportNode.expression as Identifier; + if (ts.isExportAssignment(exportNode) && !exportNode.isExportEquals) { + const exp = exportNode.expression as ts.Identifier; const spec = makeExportSpecifier(exp.text, exp.text); - changes.replaceNode(exportingSourceFile, exportNode, factory.createExportDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, /*isTypeOnly*/ false, factory.createNamedExports([spec]))); + changes.replaceNode(exportingSourceFile, exportNode, ts.factory.createExportDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, /*isTypeOnly*/ false, ts.factory.createNamedExports([spec]))); } else { - changes.delete(exportingSourceFile, Debug.checkDefined(findModifier(exportNode, SyntaxKind.DefaultKeyword), "Should find a default keyword in modifier list")); + changes.delete(exportingSourceFile, ts.Debug.checkDefined(ts.findModifier(exportNode, ts.SyntaxKind.DefaultKeyword), "Should find a default keyword in modifier list")); } } else { - const exportKeyword = Debug.checkDefined(findModifier(exportNode, SyntaxKind.ExportKeyword), "Should find an export keyword in modifier list"); + const exportKeyword = ts.Debug.checkDefined(ts.findModifier(exportNode, ts.SyntaxKind.ExportKeyword), "Should find an export keyword in modifier list"); switch (exportNode.kind) { - case SyntaxKind.FunctionDeclaration: - case SyntaxKind.ClassDeclaration: - case SyntaxKind.InterfaceDeclaration: - changes.insertNodeAfter(exportingSourceFile, exportKeyword, factory.createToken(SyntaxKind.DefaultKeyword)); + case ts.SyntaxKind.FunctionDeclaration: + case ts.SyntaxKind.ClassDeclaration: + case ts.SyntaxKind.InterfaceDeclaration: + changes.insertNodeAfter(exportingSourceFile, exportKeyword, ts.factory.createToken(ts.SyntaxKind.DefaultKeyword)); break; - case SyntaxKind.VariableStatement: + case ts.SyntaxKind.VariableStatement: // If 'x' isn't used in this file and doesn't have type definition, `export const x = 0;` --> `export default 0;` - const decl = first(exportNode.declarationList.declarations); - if (!FindAllReferences.Core.isSymbolReferencedInFile(exportName, checker, exportingSourceFile) && !decl.type) { + const decl = ts.first(exportNode.declarationList.declarations); + if (!ts.FindAllReferences.Core.isSymbolReferencedInFile(exportName, checker, exportingSourceFile) && !decl.type) { // We checked in `getInfo` that an initializer exists. - changes.replaceNode(exportingSourceFile, exportNode, factory.createExportDefault(Debug.checkDefined(decl.initializer, "Initializer was previously known to be present"))); + changes.replaceNode(exportingSourceFile, exportNode, ts.factory.createExportDefault(ts.Debug.checkDefined(decl.initializer, "Initializer was previously known to be present"))); break; } // falls through - case SyntaxKind.EnumDeclaration: - case SyntaxKind.TypeAliasDeclaration: - case SyntaxKind.ModuleDeclaration: + case ts.SyntaxKind.EnumDeclaration: + case ts.SyntaxKind.TypeAliasDeclaration: + case ts.SyntaxKind.ModuleDeclaration: // `export type T = number;` -> `type T = number; export default T;` changes.deleteModifier(exportingSourceFile, exportKeyword); - changes.insertNodeAfter(exportingSourceFile, exportNode, factory.createExportDefault(factory.createIdentifier(exportName.text))); + changes.insertNodeAfter(exportingSourceFile, exportNode, ts.factory.createExportDefault(ts.factory.createIdentifier(exportName.text))); break; default: - Debug.fail(`Unexpected exportNode kind ${(exportNode as ExportToConvert).kind}`); + ts.Debug.fail(`Unexpected exportNode kind ${(exportNode as ExportToConvert).kind}`); } } } - function changeImports(program: Program, { wasDefault, exportName, exportingModuleSymbol }: ExportInfo, changes: textChanges.ChangeTracker, cancellationToken: CancellationToken | undefined): void { + function changeImports(program: ts.Program, { wasDefault, exportName, exportingModuleSymbol }: ExportInfo, changes: ts.textChanges.ChangeTracker, cancellationToken: ts.CancellationToken | undefined): void { const checker = program.getTypeChecker(); - const exportSymbol = Debug.checkDefined(checker.getSymbolAtLocation(exportName), "Export name should resolve to a symbol"); - FindAllReferences.Core.eachExportReference(program.getSourceFiles(), checker, cancellationToken, exportSymbol, exportingModuleSymbol, exportName.text, wasDefault, ref => { + const exportSymbol = ts.Debug.checkDefined(checker.getSymbolAtLocation(exportName), "Export name should resolve to a symbol"); + ts.FindAllReferences.Core.eachExportReference(program.getSourceFiles(), checker, cancellationToken, exportSymbol, exportingModuleSymbol, exportName.text, wasDefault, ref => { const importingSourceFile = ref.getSourceFile(); if (wasDefault) { changeDefaultToNamedImport(importingSourceFile, ref, changes, exportName.text); @@ -175,34 +174,34 @@ namespace ts.refactor { }); } - function changeDefaultToNamedImport(importingSourceFile: SourceFile, ref: Identifier, changes: textChanges.ChangeTracker, exportName: string): void { + function changeDefaultToNamedImport(importingSourceFile: ts.SourceFile, ref: ts.Identifier, changes: ts.textChanges.ChangeTracker, exportName: string): void { const { parent } = ref; switch (parent.kind) { - case SyntaxKind.PropertyAccessExpression: + case ts.SyntaxKind.PropertyAccessExpression: // `a.default` --> `a.foo` - changes.replaceNode(importingSourceFile, ref, factory.createIdentifier(exportName)); + changes.replaceNode(importingSourceFile, ref, ts.factory.createIdentifier(exportName)); break; - case SyntaxKind.ImportSpecifier: - case SyntaxKind.ExportSpecifier: { - const spec = parent as ImportSpecifier | ExportSpecifier; + case ts.SyntaxKind.ImportSpecifier: + case ts.SyntaxKind.ExportSpecifier: { + const spec = parent as ts.ImportSpecifier | ts.ExportSpecifier; // `default as foo` --> `foo`, `default as bar` --> `foo as bar` changes.replaceNode(importingSourceFile, spec, makeImportSpecifier(exportName, spec.name.text)); break; } - case SyntaxKind.ImportClause: { - const clause = parent as ImportClause; - Debug.assert(clause.name === ref, "Import clause name should match provided ref"); + case ts.SyntaxKind.ImportClause: { + const clause = parent as ts.ImportClause; + ts.Debug.assert(clause.name === ref, "Import clause name should match provided ref"); const spec = makeImportSpecifier(exportName, ref.text); const { namedBindings } = clause; if (!namedBindings) { // `import foo from "./a";` --> `import { foo } from "./a";` - changes.replaceNode(importingSourceFile, ref, factory.createNamedImports([spec])); + changes.replaceNode(importingSourceFile, ref, ts.factory.createNamedImports([spec])); } - else if (namedBindings.kind === SyntaxKind.NamespaceImport) { + else if (namedBindings.kind === ts.SyntaxKind.NamespaceImport) { // `import foo, * as a from "./a";` --> `import * as a from ".a/"; import { foo } from "./a";` changes.deleteRange(importingSourceFile, { pos: ref.getStart(importingSourceFile), end: namedBindings.getStart(importingSourceFile) }); - const quotePreference = isStringLiteral(clause.parent.moduleSpecifier) ? quotePreferenceFromString(clause.parent.moduleSpecifier, importingSourceFile) : QuotePreference.Double; - const newImport = makeImport(/*default*/ undefined, [makeImportSpecifier(exportName, ref.text)], clause.parent.moduleSpecifier, quotePreference); + const quotePreference = ts.isStringLiteral(clause.parent.moduleSpecifier) ? ts.quotePreferenceFromString(clause.parent.moduleSpecifier, importingSourceFile) : ts.QuotePreference.Double; + const newImport = ts.makeImport(/*default*/ undefined, [makeImportSpecifier(exportName, ref.text)], clause.parent.moduleSpecifier, quotePreference); changes.insertNodeAfter(importingSourceFile, clause.parent, newImport); } else { @@ -212,26 +211,26 @@ namespace ts.refactor { } break; } - case SyntaxKind.ImportType: - const importTypeNode = parent as ImportTypeNode; - changes.replaceNode(importingSourceFile, parent, factory.createImportTypeNode(importTypeNode.argument, factory.createIdentifier(exportName), importTypeNode.typeArguments, importTypeNode.isTypeOf)); + case ts.SyntaxKind.ImportType: + const importTypeNode = parent as ts.ImportTypeNode; + changes.replaceNode(importingSourceFile, parent, ts.factory.createImportTypeNode(importTypeNode.argument, ts.factory.createIdentifier(exportName), importTypeNode.typeArguments, importTypeNode.isTypeOf)); break; default: - Debug.failBadSyntaxKind(parent); + ts.Debug.failBadSyntaxKind(parent); } } - function changeNamedToDefaultImport(importingSourceFile: SourceFile, ref: Identifier, changes: textChanges.ChangeTracker): void { - const parent = ref.parent as PropertyAccessExpression | ImportSpecifier | ExportSpecifier; + function changeNamedToDefaultImport(importingSourceFile: ts.SourceFile, ref: ts.Identifier, changes: ts.textChanges.ChangeTracker): void { + const parent = ref.parent as ts.PropertyAccessExpression | ts.ImportSpecifier | ts.ExportSpecifier; switch (parent.kind) { - case SyntaxKind.PropertyAccessExpression: + case ts.SyntaxKind.PropertyAccessExpression: // `a.foo` --> `a.default` - changes.replaceNode(importingSourceFile, ref, factory.createIdentifier("default")); + changes.replaceNode(importingSourceFile, ref, ts.factory.createIdentifier("default")); break; - case SyntaxKind.ImportSpecifier: { + case ts.SyntaxKind.ImportSpecifier: { // `import { foo } from "./a";` --> `import foo from "./a";` // `import { foo as bar } from "./a";` --> `import bar from "./a";` - const defaultImport = factory.createIdentifier(parent.name.text); + const defaultImport = ts.factory.createIdentifier(parent.name.text); if (parent.parent.elements.length === 1) { changes.replaceNode(importingSourceFile, parent.parent, defaultImport); } @@ -241,7 +240,7 @@ namespace ts.refactor { } break; } - case SyntaxKind.ExportSpecifier: { + case ts.SyntaxKind.ExportSpecifier: { // `export { foo } from "./a";` --> `export { default as foo } from "./a";` // `export { foo as bar } from "./a";` --> `export { default as bar } from "./a";` // `export { foo as default } from "./a";` --> `export { default } from "./a";` @@ -250,16 +249,16 @@ namespace ts.refactor { break; } default: - Debug.assertNever(parent, `Unexpected parent kind ${(parent as Node).kind}`); + ts.Debug.assertNever(parent, `Unexpected parent kind ${(parent as ts.Node).kind}`); } } - function makeImportSpecifier(propertyName: string, name: string): ImportSpecifier { - return factory.createImportSpecifier(/*isTypeOnly*/ false, propertyName === name ? undefined : factory.createIdentifier(propertyName), factory.createIdentifier(name)); + function makeImportSpecifier(propertyName: string, name: string): ts.ImportSpecifier { + return ts.factory.createImportSpecifier(/*isTypeOnly*/ false, propertyName === name ? undefined : ts.factory.createIdentifier(propertyName), ts.factory.createIdentifier(name)); } - function makeExportSpecifier(propertyName: string, name: string): ExportSpecifier { - return factory.createExportSpecifier(/*isTypeOnly*/ false, propertyName === name ? undefined : factory.createIdentifier(propertyName), factory.createIdentifier(name)); + function makeExportSpecifier(propertyName: string, name: string): ts.ExportSpecifier { + return ts.factory.createExportSpecifier(/*isTypeOnly*/ false, propertyName === name ? undefined : ts.factory.createIdentifier(propertyName), ts.factory.createIdentifier(name)); } } diff --git a/src/services/refactors/convertImport.ts b/src/services/refactors/convertImport.ts index 01333162abb14..782b7be17d6b3 100644 --- a/src/services/refactors/convertImport.ts +++ b/src/services/refactors/convertImport.ts @@ -3,139 +3,145 @@ namespace ts.refactor { const refactorName = "Convert import"; const actions = { - [ImportKind.Named]: { + [ts.ImportKind.Named]: { name: "Convert namespace import to named imports", - description: Diagnostics.Convert_namespace_import_to_named_imports.message, + description: ts.Diagnostics.Convert_namespace_import_to_named_imports.message, kind: "refactor.rewrite.import.named", }, - [ImportKind.Namespace]: { + [ts.ImportKind.Namespace]: { name: "Convert named imports to namespace import", - description: Diagnostics.Convert_named_imports_to_namespace_import.message, + description: ts.Diagnostics.Convert_named_imports_to_namespace_import.message, kind: "refactor.rewrite.import.namespace", }, - [ImportKind.Default]: { + [ts.ImportKind.Default]: { name: "Convert named imports to default import", - description: Diagnostics.Convert_named_imports_to_default_import.message, + description: ts.Diagnostics.Convert_named_imports_to_default_import.message, kind: "refactor.rewrite.import.default", }, }; - registerRefactor(refactorName, { - kinds: getOwnValues(actions).map(a => a.kind), - getAvailableActions: function getRefactorActionsToConvertBetweenNamedAndNamespacedImports(context): readonly ApplicableRefactorInfo[] { + ts.refactor.registerRefactor(refactorName, { + kinds: ts.getOwnValues(actions).map(a => a.kind), + getAvailableActions: function getRefactorActionsToConvertBetweenNamedAndNamespacedImports(context): readonly ts.ApplicableRefactorInfo[] { const info = getImportConversionInfo(context, context.triggerReason === "invoked"); - if (!info) return emptyArray; - - if (!isRefactorErrorInfo(info)) { + if (!info) + return ts.emptyArray; + if (!ts.refactor.isRefactorErrorInfo(info)) { const action = actions[info.convertTo]; return [{ name: refactorName, description: action.description, actions: [action] }]; } if (context.preferences.provideRefactorNotApplicableReason) { - return getOwnValues(actions).map(action => ({ + return ts.getOwnValues(actions).map(action => ({ name: refactorName, description: action.description, actions: [{ ...action, notApplicableReason: info.error }] })); } - return emptyArray; + return ts.emptyArray; }, - getEditsForAction: function getRefactorEditsToConvertBetweenNamedAndNamespacedImports(context, actionName): RefactorEditInfo { - Debug.assert(some(getOwnValues(actions), action => action.name === actionName), "Unexpected action name"); + getEditsForAction: function getRefactorEditsToConvertBetweenNamedAndNamespacedImports(context, actionName): ts.RefactorEditInfo { + ts.Debug.assert(ts.some(ts.getOwnValues(actions), action => action.name === actionName), "Unexpected action name"); const info = getImportConversionInfo(context); - Debug.assert(info && !isRefactorErrorInfo(info), "Expected applicable refactor info"); - const edits = textChanges.ChangeTracker.with(context, t => doChange(context.file, context.program, t, info)); + ts.Debug.assert(info && !ts.refactor.isRefactorErrorInfo(info), "Expected applicable refactor info"); + const edits = ts.textChanges.ChangeTracker.with(context, t => doChange(context.file, context.program, t, info)); return { edits, renameFilename: undefined, renameLocation: undefined }; } }); // Can convert imports of the form `import * as m from "m";` or `import d, { x, y } from "m";`. - type ImportConversionInfo = - | { convertTo: ImportKind.Default, import: NamedImports } - | { convertTo: ImportKind.Namespace, import: NamedImports } - | { convertTo: ImportKind.Named, import: NamespaceImport }; - - function getImportConversionInfo(context: RefactorContext, considerPartialSpans = true): ImportConversionInfo | RefactorErrorInfo | undefined { + type ImportConversionInfo = { + convertTo: ts.ImportKind.Default; + import: ts.NamedImports; + } | { + convertTo: ts.ImportKind.Namespace; + import: ts.NamedImports; + } | { + convertTo: ts.ImportKind.Named; + import: ts.NamespaceImport; + }; + function getImportConversionInfo(context: ts.RefactorContext, considerPartialSpans = true): ImportConversionInfo | ts.refactor.RefactorErrorInfo | undefined { const { file } = context; - const span = getRefactorContextSpan(context); - const token = getTokenAtPosition(file, span.start); - const importDecl = considerPartialSpans ? findAncestor(token, isImportDeclaration) : getParentNodeInSpan(token, file, span); - if (!importDecl || !isImportDeclaration(importDecl)) return { error: "Selection is not an import declaration." }; + const span = ts.getRefactorContextSpan(context); + const token = ts.getTokenAtPosition(file, span.start); + const importDecl = considerPartialSpans ? ts.findAncestor(token, ts.isImportDeclaration) : ts.getParentNodeInSpan(token, file, span); + if (!importDecl || !ts.isImportDeclaration(importDecl)) + return { error: "Selection is not an import declaration." }; const end = span.start + span.length; - const nextToken = findNextToken(importDecl, importDecl.parent, file); - if (nextToken && end > nextToken.getStart()) return undefined; + const nextToken = ts.findNextToken(importDecl, importDecl.parent, file); + if (nextToken && end > nextToken.getStart()) + return undefined; const { importClause } = importDecl; if (!importClause) { - return { error: getLocaleSpecificMessage(Diagnostics.Could_not_find_import_clause) }; + return { error: ts.getLocaleSpecificMessage(ts.Diagnostics.Could_not_find_import_clause) }; } if (!importClause.namedBindings) { - return { error: getLocaleSpecificMessage(Diagnostics.Could_not_find_namespace_import_or_named_imports) }; + return { error: ts.getLocaleSpecificMessage(ts.Diagnostics.Could_not_find_namespace_import_or_named_imports) }; } - if (importClause.namedBindings.kind === SyntaxKind.NamespaceImport) { - return { convertTo: ImportKind.Named, import: importClause.namedBindings }; + if (importClause.namedBindings.kind === ts.SyntaxKind.NamespaceImport) { + return { convertTo: ts.ImportKind.Named, import: importClause.namedBindings }; } const shouldUseDefault = getShouldUseDefault(context.program, importClause); return shouldUseDefault - ? { convertTo: ImportKind.Default, import: importClause.namedBindings } - : { convertTo: ImportKind.Namespace, import: importClause.namedBindings }; + ? { convertTo: ts.ImportKind.Default, import: importClause.namedBindings } + : { convertTo: ts.ImportKind.Namespace, import: importClause.namedBindings }; } - function getShouldUseDefault(program: Program, importClause: ImportClause) { - return getAllowSyntheticDefaultImports(program.getCompilerOptions()) + function getShouldUseDefault(program: ts.Program, importClause: ts.ImportClause) { + return ts.getAllowSyntheticDefaultImports(program.getCompilerOptions()) && isExportEqualsModule(importClause.parent.moduleSpecifier, program.getTypeChecker()); } - function doChange(sourceFile: SourceFile, program: Program, changes: textChanges.ChangeTracker, info: ImportConversionInfo): void { + function doChange(sourceFile: ts.SourceFile, program: ts.Program, changes: ts.textChanges.ChangeTracker, info: ImportConversionInfo): void { const checker = program.getTypeChecker(); - if (info.convertTo === ImportKind.Named) { - doChangeNamespaceToNamed(sourceFile, checker, changes, info.import, getAllowSyntheticDefaultImports(program.getCompilerOptions())); + if (info.convertTo === ts.ImportKind.Named) { + doChangeNamespaceToNamed(sourceFile, checker, changes, info.import, ts.getAllowSyntheticDefaultImports(program.getCompilerOptions())); } else { - doChangeNamedToNamespaceOrDefault(sourceFile, program, changes, info.import, info.convertTo === ImportKind.Default); + doChangeNamedToNamespaceOrDefault(sourceFile, program, changes, info.import, info.convertTo === ts.ImportKind.Default); } } - function doChangeNamespaceToNamed(sourceFile: SourceFile, checker: TypeChecker, changes: textChanges.ChangeTracker, toConvert: NamespaceImport, allowSyntheticDefaultImports: boolean): void { + function doChangeNamespaceToNamed(sourceFile: ts.SourceFile, checker: ts.TypeChecker, changes: ts.textChanges.ChangeTracker, toConvert: ts.NamespaceImport, allowSyntheticDefaultImports: boolean): void { let usedAsNamespaceOrDefault = false; - const nodesToReplace: (PropertyAccessExpression | QualifiedName)[] = []; - const conflictingNames = new Map(); - - FindAllReferences.Core.eachSymbolReferenceInFile(toConvert.name, checker, sourceFile, id => { - if (!isPropertyAccessOrQualifiedName(id.parent)) { + const nodesToReplace: (ts.PropertyAccessExpression | ts.QualifiedName)[] = []; + const conflictingNames = new ts.Map(); + ts.FindAllReferences.Core.eachSymbolReferenceInFile(toConvert.name, checker, sourceFile, id => { + if (!ts.isPropertyAccessOrQualifiedName(id.parent)) { usedAsNamespaceOrDefault = true; } else { const exportName = getRightOfPropertyAccessOrQualifiedName(id.parent).text; - if (checker.resolveName(exportName, id, SymbolFlags.All, /*excludeGlobals*/ true)) { + if (checker.resolveName(exportName, id, ts.SymbolFlags.All, /*excludeGlobals*/ true)) { conflictingNames.set(exportName, true); } - Debug.assert(getLeftOfPropertyAccessOrQualifiedName(id.parent) === id, "Parent expression should match id"); + ts.Debug.assert(getLeftOfPropertyAccessOrQualifiedName(id.parent) === id, "Parent expression should match id"); nodesToReplace.push(id.parent); } }); // We may need to change `mod.x` to `_x` to avoid a name conflict. - const exportNameToImportName = new Map(); + const exportNameToImportName = new ts.Map(); for (const propertyAccessOrQualifiedName of nodesToReplace) { const exportName = getRightOfPropertyAccessOrQualifiedName(propertyAccessOrQualifiedName).text; let importName = exportNameToImportName.get(exportName); if (importName === undefined) { - exportNameToImportName.set(exportName, importName = conflictingNames.has(exportName) ? getUniqueName(exportName, sourceFile) : exportName); + exportNameToImportName.set(exportName, importName = conflictingNames.has(exportName) ? ts.getUniqueName(exportName, sourceFile) : exportName); } - changes.replaceNode(sourceFile, propertyAccessOrQualifiedName, factory.createIdentifier(importName)); + changes.replaceNode(sourceFile, propertyAccessOrQualifiedName, ts.factory.createIdentifier(importName)); } - const importSpecifiers: ImportSpecifier[] = []; + const importSpecifiers: ts.ImportSpecifier[] = []; exportNameToImportName.forEach((name, propertyName) => { - importSpecifiers.push(factory.createImportSpecifier(/*isTypeOnly*/ false, name === propertyName ? undefined : factory.createIdentifier(propertyName), factory.createIdentifier(name))); + importSpecifiers.push(ts.factory.createImportSpecifier(/*isTypeOnly*/ false, name === propertyName ? undefined : ts.factory.createIdentifier(propertyName), ts.factory.createIdentifier(name))); }); const importDecl = toConvert.parent.parent; @@ -144,41 +150,41 @@ namespace ts.refactor { changes.insertNodeAfter(sourceFile, importDecl, updateImport(importDecl, /*defaultImportName*/ undefined, importSpecifiers)); } else { - changes.replaceNode(sourceFile, importDecl, updateImport(importDecl, usedAsNamespaceOrDefault ? factory.createIdentifier(toConvert.name.text) : undefined, importSpecifiers)); + changes.replaceNode(sourceFile, importDecl, updateImport(importDecl, usedAsNamespaceOrDefault ? ts.factory.createIdentifier(toConvert.name.text) : undefined, importSpecifiers)); } } - function getRightOfPropertyAccessOrQualifiedName(propertyAccessOrQualifiedName: PropertyAccessExpression | QualifiedName) { - return isPropertyAccessExpression(propertyAccessOrQualifiedName) ? propertyAccessOrQualifiedName.name : propertyAccessOrQualifiedName.right; + function getRightOfPropertyAccessOrQualifiedName(propertyAccessOrQualifiedName: ts.PropertyAccessExpression | ts.QualifiedName) { + return ts.isPropertyAccessExpression(propertyAccessOrQualifiedName) ? propertyAccessOrQualifiedName.name : propertyAccessOrQualifiedName.right; } - function getLeftOfPropertyAccessOrQualifiedName(propertyAccessOrQualifiedName: PropertyAccessExpression | QualifiedName) { - return isPropertyAccessExpression(propertyAccessOrQualifiedName) ? propertyAccessOrQualifiedName.expression : propertyAccessOrQualifiedName.left; + function getLeftOfPropertyAccessOrQualifiedName(propertyAccessOrQualifiedName: ts.PropertyAccessExpression | ts.QualifiedName) { + return ts.isPropertyAccessExpression(propertyAccessOrQualifiedName) ? propertyAccessOrQualifiedName.expression : propertyAccessOrQualifiedName.left; } - export function doChangeNamedToNamespaceOrDefault(sourceFile: SourceFile, program: Program, changes: textChanges.ChangeTracker, toConvert: NamedImports, shouldUseDefault = getShouldUseDefault(program, toConvert.parent)): void { + export function doChangeNamedToNamespaceOrDefault(sourceFile: ts.SourceFile, program: ts.Program, changes: ts.textChanges.ChangeTracker, toConvert: ts.NamedImports, shouldUseDefault = getShouldUseDefault(program, toConvert.parent)): void { const checker = program.getTypeChecker(); const importDecl = toConvert.parent.parent; const { moduleSpecifier } = importDecl; - const toConvertSymbols: Set = new Set(); + const toConvertSymbols: ts.Set = new ts.Set(); toConvert.elements.forEach(namedImport => { const symbol = checker.getSymbolAtLocation(namedImport.name); if (symbol) { toConvertSymbols.add(symbol); } }); - const preferredName = moduleSpecifier && isStringLiteral(moduleSpecifier) ? codefix.moduleSpecifierToValidIdentifier(moduleSpecifier.text, ScriptTarget.ESNext) : "module"; - function hasNamespaceNameConflict(namedImport: ImportSpecifier): boolean { + const preferredName = moduleSpecifier && ts.isStringLiteral(moduleSpecifier) ? ts.codefix.moduleSpecifierToValidIdentifier(moduleSpecifier.text, ts.ScriptTarget.ESNext) : "module"; + function hasNamespaceNameConflict(namedImport: ts.ImportSpecifier): boolean { // We need to check if the preferred namespace name (`preferredName`) we'd like to use in the refactored code will present a name conflict. // A name conflict means that, in a scope where we would like to use the preferred namespace name, there already exists a symbol with that name in that scope. // We are going to use the namespace name in the scopes the named imports being refactored are referenced, // so we look for conflicts by looking at every reference to those named imports. - return !!FindAllReferences.Core.eachSymbolReferenceInFile(namedImport.name, checker, sourceFile, id => { - const symbol = checker.resolveName(preferredName, id, SymbolFlags.All, /*excludeGlobals*/ true); + return !!ts.FindAllReferences.Core.eachSymbolReferenceInFile(namedImport.name, checker, sourceFile, id => { + const symbol = checker.resolveName(preferredName, id, ts.SymbolFlags.All, /*excludeGlobals*/ true); if (symbol) { // There already is a symbol with the same name as the preferred namespace name. if (toConvertSymbols.has(symbol)) { // `preferredName` resolves to a symbol for one of the named import references we are going to transform into namespace import references... - return isExportSpecifier(id.parent); // ...but if this reference is an export specifier, it will not be transformed, so it is a conflict; otherwise, it will be renamed and is not a conflict. + return ts.isExportSpecifier(id.parent); // ...but if this reference is an export specifier, it will not be transformed, so it is a conflict; otherwise, it will be renamed and is not a conflict. } return true; // `preferredName` resolves to any other symbol, which will be present in the refactored code and so poses a name conflict. } @@ -186,20 +192,20 @@ namespace ts.refactor { }); } const namespaceNameConflicts = toConvert.elements.some(hasNamespaceNameConflict); - const namespaceImportName = namespaceNameConflicts ? getUniqueName(preferredName, sourceFile) : preferredName; + const namespaceImportName = namespaceNameConflicts ? ts.getUniqueName(preferredName, sourceFile) : preferredName; // Imports that need to be kept as named imports in the refactored code, to avoid changing the semantics. // More specifically, those are named imports that appear in named exports in the original code, e.g. `a` in `import { a } from "m"; export { a }`. - const neededNamedImports: Set = new Set(); + const neededNamedImports: ts.Set = new ts.Set(); for (const element of toConvert.elements) { const propertyName = (element.propertyName || element.name).text; - FindAllReferences.Core.eachSymbolReferenceInFile(element.name, checker, sourceFile, id => { - const access = factory.createPropertyAccessExpression(factory.createIdentifier(namespaceImportName), propertyName); - if (isShorthandPropertyAssignment(id.parent)) { - changes.replaceNode(sourceFile, id.parent, factory.createPropertyAssignment(id.text, access)); + ts.FindAllReferences.Core.eachSymbolReferenceInFile(element.name, checker, sourceFile, id => { + const access = ts.factory.createPropertyAccessExpression(ts.factory.createIdentifier(namespaceImportName), propertyName); + if (ts.isShorthandPropertyAssignment(id.parent)) { + changes.replaceNode(sourceFile, id.parent, ts.factory.createPropertyAssignment(id.text, access)); } - else if (isExportSpecifier(id.parent)) { + else if (ts.isExportSpecifier(id.parent)) { neededNamedImports.add(element); } else { @@ -209,24 +215,23 @@ namespace ts.refactor { } changes.replaceNode(sourceFile, toConvert, shouldUseDefault - ? factory.createIdentifier(namespaceImportName) - : factory.createNamespaceImport(factory.createIdentifier(namespaceImportName))); + ? ts.factory.createIdentifier(namespaceImportName) + : ts.factory.createNamespaceImport(ts.factory.createIdentifier(namespaceImportName))); if (neededNamedImports.size) { - const newNamedImports: ImportSpecifier[] = arrayFrom(neededNamedImports.values()).map(element => - factory.createImportSpecifier(element.isTypeOnly, element.propertyName && factory.createIdentifier(element.propertyName.text), factory.createIdentifier(element.name.text))); + const newNamedImports: ts.ImportSpecifier[] = ts.arrayFrom(neededNamedImports.values()).map(element => ts.factory.createImportSpecifier(element.isTypeOnly, element.propertyName && ts.factory.createIdentifier(element.propertyName.text), ts.factory.createIdentifier(element.name.text))); changes.insertNodeAfter(sourceFile, toConvert.parent.parent, updateImport(importDecl, /*defaultImportName*/ undefined, newNamedImports)); } } - function isExportEqualsModule(moduleSpecifier: Expression, checker: TypeChecker) { + function isExportEqualsModule(moduleSpecifier: ts.Expression, checker: ts.TypeChecker) { const externalModule = checker.resolveExternalModuleName(moduleSpecifier); - if (!externalModule) return false; + if (!externalModule) + return false; const exportEquals = checker.resolveExternalModuleSymbol(externalModule); return externalModule !== exportEquals; } - function updateImport(old: ImportDeclaration, defaultImportName: Identifier | undefined, elements: readonly ImportSpecifier[] | undefined): ImportDeclaration { - return factory.createImportDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, - factory.createImportClause(/*isTypeOnly*/ false, defaultImportName, elements && elements.length ? factory.createNamedImports(elements) : undefined), old.moduleSpecifier, /*assertClause*/ undefined); + function updateImport(old: ts.ImportDeclaration, defaultImportName: ts.Identifier | undefined, elements: readonly ts.ImportSpecifier[] | undefined): ts.ImportDeclaration { + return ts.factory.createImportDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, ts.factory.createImportClause(/*isTypeOnly*/ false, defaultImportName, elements && elements.length ? ts.factory.createNamedImports(elements) : undefined), old.moduleSpecifier, /*assertClause*/ undefined); } } diff --git a/src/services/refactors/convertOverloadListToSingleSignature.ts b/src/services/refactors/convertOverloadListToSingleSignature.ts index 83c071c70ac48..f1ba62b54f598 100644 --- a/src/services/refactors/convertOverloadListToSingleSignature.ts +++ b/src/services/refactors/convertOverloadListToSingleSignature.ts @@ -1,23 +1,24 @@ /* @internal */ namespace ts.refactor.addOrRemoveBracesToArrowFunction { const refactorName = "Convert overload list to single signature"; - const refactorDescription = Diagnostics.Convert_overload_list_to_single_signature.message; + const refactorDescription = ts.Diagnostics.Convert_overload_list_to_single_signature.message; const functionOverloadAction = { name: refactorName, description: refactorDescription, kind: "refactor.rewrite.function.overloadList", }; - registerRefactor(refactorName, { + ts.refactor.registerRefactor(refactorName, { kinds: [functionOverloadAction.kind], getEditsForAction: getRefactorEditsToConvertOverloadsToOneSignature, getAvailableActions: getRefactorActionsToConvertOverloadsToOneSignature }); - function getRefactorActionsToConvertOverloadsToOneSignature(context: RefactorContext): readonly ApplicableRefactorInfo[] { + function getRefactorActionsToConvertOverloadsToOneSignature(context: ts.RefactorContext): readonly ts.ApplicableRefactorInfo[] { const { file, startPosition, program } = context; const info = getConvertableOverloadListAtPosition(file, startPosition, program); - if (!info) return emptyArray; + if (!info) + return ts.emptyArray; return [{ name: refactorName, @@ -26,138 +27,84 @@ namespace ts.refactor.addOrRemoveBracesToArrowFunction { }]; } - function getRefactorEditsToConvertOverloadsToOneSignature(context: RefactorContext): RefactorEditInfo | undefined { + function getRefactorEditsToConvertOverloadsToOneSignature(context: ts.RefactorContext): ts.RefactorEditInfo | undefined { const { file, startPosition, program } = context; const signatureDecls = getConvertableOverloadListAtPosition(file, startPosition, program); - if (!signatureDecls) return undefined; + if (!signatureDecls) + return undefined; const checker = program.getTypeChecker(); const lastDeclaration = signatureDecls[signatureDecls.length - 1]; let updated = lastDeclaration; switch (lastDeclaration.kind) { - case SyntaxKind.MethodSignature: { - updated = factory.updateMethodSignature( - lastDeclaration, - lastDeclaration.modifiers, - lastDeclaration.name, - lastDeclaration.questionToken, - lastDeclaration.typeParameters, - getNewParametersForCombinedSignature(signatureDecls), - lastDeclaration.type, - ); + case ts.SyntaxKind.MethodSignature: { + updated = ts.factory.updateMethodSignature(lastDeclaration, lastDeclaration.modifiers, lastDeclaration.name, lastDeclaration.questionToken, lastDeclaration.typeParameters, getNewParametersForCombinedSignature(signatureDecls), lastDeclaration.type); break; } - case SyntaxKind.MethodDeclaration: { - updated = factory.updateMethodDeclaration( - lastDeclaration, - lastDeclaration.decorators, - lastDeclaration.modifiers, - lastDeclaration.asteriskToken, - lastDeclaration.name, - lastDeclaration.questionToken, - lastDeclaration.typeParameters, - getNewParametersForCombinedSignature(signatureDecls), - lastDeclaration.type, - lastDeclaration.body - ); + case ts.SyntaxKind.MethodDeclaration: { + updated = ts.factory.updateMethodDeclaration(lastDeclaration, lastDeclaration.decorators, lastDeclaration.modifiers, lastDeclaration.asteriskToken, lastDeclaration.name, lastDeclaration.questionToken, lastDeclaration.typeParameters, getNewParametersForCombinedSignature(signatureDecls), lastDeclaration.type, lastDeclaration.body); break; } - case SyntaxKind.CallSignature: { - updated = factory.updateCallSignature( - lastDeclaration, - lastDeclaration.typeParameters, - getNewParametersForCombinedSignature(signatureDecls), - lastDeclaration.type, - ); + case ts.SyntaxKind.CallSignature: { + updated = ts.factory.updateCallSignature(lastDeclaration, lastDeclaration.typeParameters, getNewParametersForCombinedSignature(signatureDecls), lastDeclaration.type); break; } - case SyntaxKind.Constructor: { - updated = factory.updateConstructorDeclaration( - lastDeclaration, - lastDeclaration.decorators, - lastDeclaration.modifiers, - getNewParametersForCombinedSignature(signatureDecls), - lastDeclaration.body - ); + case ts.SyntaxKind.Constructor: { + updated = ts.factory.updateConstructorDeclaration(lastDeclaration, lastDeclaration.decorators, lastDeclaration.modifiers, getNewParametersForCombinedSignature(signatureDecls), lastDeclaration.body); break; } - case SyntaxKind.ConstructSignature: { - updated = factory.updateConstructSignature( - lastDeclaration, - lastDeclaration.typeParameters, - getNewParametersForCombinedSignature(signatureDecls), - lastDeclaration.type, - ); + case ts.SyntaxKind.ConstructSignature: { + updated = ts.factory.updateConstructSignature(lastDeclaration, lastDeclaration.typeParameters, getNewParametersForCombinedSignature(signatureDecls), lastDeclaration.type); break; } - case SyntaxKind.FunctionDeclaration: { - updated = factory.updateFunctionDeclaration( - lastDeclaration, - lastDeclaration.decorators, - lastDeclaration.modifiers, - lastDeclaration.asteriskToken, - lastDeclaration.name, - lastDeclaration.typeParameters, - getNewParametersForCombinedSignature(signatureDecls), - lastDeclaration.type, - lastDeclaration.body - ); + case ts.SyntaxKind.FunctionDeclaration: { + updated = ts.factory.updateFunctionDeclaration(lastDeclaration, lastDeclaration.decorators, lastDeclaration.modifiers, lastDeclaration.asteriskToken, lastDeclaration.name, lastDeclaration.typeParameters, getNewParametersForCombinedSignature(signatureDecls), lastDeclaration.type, lastDeclaration.body); break; } - default: return Debug.failBadSyntaxKind(lastDeclaration, "Unhandled signature kind in overload list conversion refactoring"); + default: return ts.Debug.failBadSyntaxKind(lastDeclaration, "Unhandled signature kind in overload list conversion refactoring"); } if (updated === lastDeclaration) { return; // No edits to apply, do nothing } - const edits = textChanges.ChangeTracker.with(context, t => { + const edits = ts.textChanges.ChangeTracker.with(context, t => { t.replaceNodeRange(file, signatureDecls[0], signatureDecls[signatureDecls.length - 1], updated); }); return { renameFilename: undefined, renameLocation: undefined, edits }; - function getNewParametersForCombinedSignature(signatureDeclarations: (MethodSignature | MethodDeclaration | CallSignatureDeclaration | ConstructorDeclaration | ConstructSignatureDeclaration | FunctionDeclaration)[]): NodeArray { + function getNewParametersForCombinedSignature(signatureDeclarations: (ts.MethodSignature | ts.MethodDeclaration | ts.CallSignatureDeclaration | ts.ConstructorDeclaration | ts.ConstructSignatureDeclaration | ts.FunctionDeclaration)[]): ts.NodeArray { const lastSig = signatureDeclarations[signatureDeclarations.length - 1]; - if (isFunctionLikeDeclaration(lastSig) && lastSig.body) { + if (ts.isFunctionLikeDeclaration(lastSig) && lastSig.body) { // Trim away implementation signature arguments (they should already be compatible with overloads, but are likely less precise to guarantee compatability with the overloads) signatureDeclarations = signatureDeclarations.slice(0, signatureDeclarations.length - 1); } - return factory.createNodeArray([ - factory.createParameterDeclaration( + return ts.factory.createNodeArray([ + ts.factory.createParameterDeclaration( /*decorators*/ undefined, - /*modifiers*/ undefined, - factory.createToken(SyntaxKind.DotDotDotToken), - "args", - /*questionToken*/ undefined, - factory.createUnionTypeNode(map(signatureDeclarations, convertSignatureParametersToTuple)) - ) + /*modifiers*/ undefined, ts.factory.createToken(ts.SyntaxKind.DotDotDotToken), "args", + /*questionToken*/ undefined, ts.factory.createUnionTypeNode(ts.map(signatureDeclarations, convertSignatureParametersToTuple))) ]); } - function convertSignatureParametersToTuple(decl: MethodSignature | MethodDeclaration | CallSignatureDeclaration | ConstructorDeclaration | ConstructSignatureDeclaration | FunctionDeclaration): TupleTypeNode { - const members = map(decl.parameters, convertParameterToNamedTupleMember); - return setEmitFlags(factory.createTupleTypeNode(members), some(members, m => !!length(getSyntheticLeadingComments(m))) ? EmitFlags.None : EmitFlags.SingleLine); + function convertSignatureParametersToTuple(decl: ts.MethodSignature | ts.MethodDeclaration | ts.CallSignatureDeclaration | ts.ConstructorDeclaration | ts.ConstructSignatureDeclaration | ts.FunctionDeclaration): ts.TupleTypeNode { + const members = ts.map(decl.parameters, convertParameterToNamedTupleMember); + return ts.setEmitFlags(ts.factory.createTupleTypeNode(members), ts.some(members, m => !!ts.length(ts.getSyntheticLeadingComments(m))) ? ts.EmitFlags.None : ts.EmitFlags.SingleLine); } - - function convertParameterToNamedTupleMember(p: ParameterDeclaration): NamedTupleMember { - Debug.assert(isIdentifier(p.name)); // This is checked during refactoring applicability checking - const result = setTextRange(factory.createNamedTupleMember( - p.dotDotDotToken, - p.name, - p.questionToken, - p.type || factory.createKeywordTypeNode(SyntaxKind.AnyKeyword) - ), p); + function convertParameterToNamedTupleMember(p: ts.ParameterDeclaration): ts.NamedTupleMember { + ts.Debug.assert(ts.isIdentifier(p.name)); // This is checked during refactoring applicability checking + const result = ts.setTextRange(ts.factory.createNamedTupleMember(p.dotDotDotToken, p.name, p.questionToken, p.type || ts.factory.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword)), p); const parameterDocComment = p.symbol && p.symbol.getDocumentationComment(checker); if (parameterDocComment) { - const newComment = displayPartsToString(parameterDocComment); + const newComment = ts.displayPartsToString(parameterDocComment); if (newComment.length) { - setSyntheticLeadingComments(result, [{ + ts.setSyntheticLeadingComments(result, [{ text: `* ${newComment.split("\n").map(c => ` * ${c}`).join("\n")} `, - kind: SyntaxKind.MultiLineCommentTrivia, + kind: ts.SyntaxKind.MultiLineCommentTrivia, pos: -1, end: -1, hasTrailingNewLine: true, @@ -170,22 +117,22 @@ ${newComment.split("\n").map(c => ` * ${c}`).join("\n")} } - function isConvertableSignatureDeclaration(d: Node): d is MethodSignature | MethodDeclaration | CallSignatureDeclaration | ConstructorDeclaration | ConstructSignatureDeclaration | FunctionDeclaration { + function isConvertableSignatureDeclaration(d: ts.Node): d is ts.MethodSignature | ts.MethodDeclaration | ts.CallSignatureDeclaration | ts.ConstructorDeclaration | ts.ConstructSignatureDeclaration | ts.FunctionDeclaration { switch (d.kind) { - case SyntaxKind.MethodSignature: - case SyntaxKind.MethodDeclaration: - case SyntaxKind.CallSignature: - case SyntaxKind.Constructor: - case SyntaxKind.ConstructSignature: - case SyntaxKind.FunctionDeclaration: + case ts.SyntaxKind.MethodSignature: + case ts.SyntaxKind.MethodDeclaration: + case ts.SyntaxKind.CallSignature: + case ts.SyntaxKind.Constructor: + case ts.SyntaxKind.ConstructSignature: + case ts.SyntaxKind.FunctionDeclaration: return true; } return false; } - function getConvertableOverloadListAtPosition(file: SourceFile, startPosition: number, program: Program) { - const node = getTokenAtPosition(file, startPosition); - const containingDecl = findAncestor(node, isConvertableSignatureDeclaration); + function getConvertableOverloadListAtPosition(file: ts.SourceFile, startPosition: number, program: ts.Program) { + const node = ts.getTokenAtPosition(file, startPosition); + const containingDecl = ts.findAncestor(node, isConvertableSignatureDeclaration); if (!containingDecl) { return; } @@ -195,29 +142,29 @@ ${newComment.split("\n").map(c => ` * ${c}`).join("\n")} return; } const decls = signatureSymbol.declarations; - if (length(decls) <= 1) { + if (ts.length(decls) <= 1) { return; } - if (!every(decls, d => getSourceFileOfNode(d) === file)) { + if (!ts.every(decls, d => ts.getSourceFileOfNode(d) === file)) { return; } if (!isConvertableSignatureDeclaration(decls![0])) { return; } const kindOne = decls![0].kind; - if (!every(decls, d => d.kind === kindOne)) { + if (!ts.every(decls, d => d.kind === kindOne)) { return; } - const signatureDecls = decls as (MethodSignature | MethodDeclaration | CallSignatureDeclaration | ConstructorDeclaration | ConstructSignatureDeclaration | FunctionDeclaration)[]; - if (some(signatureDecls, d => !!d.typeParameters || some(d.parameters, p => !!p.decorators || !!p.modifiers || !isIdentifier(p.name)))) { + const signatureDecls = decls as (ts.MethodSignature | ts.MethodDeclaration | ts.CallSignatureDeclaration | ts.ConstructorDeclaration | ts.ConstructSignatureDeclaration | ts.FunctionDeclaration)[]; + if (ts.some(signatureDecls, d => !!d.typeParameters || ts.some(d.parameters, p => !!p.decorators || !!p.modifiers || !ts.isIdentifier(p.name)))) { return; } - const signatures = mapDefined(signatureDecls, d => checker.getSignatureFromDeclaration(d)); - if (length(signatures) !== length(decls)) { + const signatures = ts.mapDefined(signatureDecls, d => checker.getSignatureFromDeclaration(d)); + if (ts.length(signatures) !== ts.length(decls)) { return; } const returnOne = checker.getReturnTypeOfSignature(signatures[0]); - if (!every(signatures, s => checker.getReturnTypeOfSignature(s) === returnOne)) { + if (!ts.every(signatures, s => checker.getReturnTypeOfSignature(s) === returnOne)) { return; } diff --git a/src/services/refactors/convertParamsToDestructuredObject.ts b/src/services/refactors/convertParamsToDestructuredObject.ts index 5fcd96a801870..8e7db35baacca 100644 --- a/src/services/refactors/convertParamsToDestructuredObject.ts +++ b/src/services/refactors/convertParamsToDestructuredObject.ts @@ -2,25 +2,27 @@ namespace ts.refactor.convertParamsToDestructuredObject { const refactorName = "Convert parameters to destructured object"; const minimumParameterLength = 1; - const refactorDescription = getLocaleSpecificMessage(Diagnostics.Convert_parameters_to_destructured_object); + const refactorDescription = ts.getLocaleSpecificMessage(ts.Diagnostics.Convert_parameters_to_destructured_object); const toDestructuredAction = { name: refactorName, description: refactorDescription, kind: "refactor.rewrite.parameters.toDestructured" }; - registerRefactor(refactorName, { + ts.refactor.registerRefactor(refactorName, { kinds: [toDestructuredAction.kind], getEditsForAction: getRefactorEditsToConvertParametersToDestructuredObject, getAvailableActions: getRefactorActionsToConvertParametersToDestructuredObject }); - function getRefactorActionsToConvertParametersToDestructuredObject(context: RefactorContext): readonly ApplicableRefactorInfo[] { + function getRefactorActionsToConvertParametersToDestructuredObject(context: ts.RefactorContext): readonly ts.ApplicableRefactorInfo[] { const { file, startPosition } = context; - const isJSFile = isSourceFileJS(file); - if (isJSFile) return emptyArray; // TODO: GH#30113 + const isJSFile = ts.isSourceFileJS(file); + if (isJSFile) + return ts.emptyArray; // TODO: GH#30113 const functionDeclaration = getFunctionDeclarationAtPosition(file, startPosition, context.program.getTypeChecker()); - if (!functionDeclaration) return emptyArray; + if (!functionDeclaration) + return ts.emptyArray; return [{ name: refactorName, @@ -29,91 +31,75 @@ namespace ts.refactor.convertParamsToDestructuredObject { }]; } - function getRefactorEditsToConvertParametersToDestructuredObject(context: RefactorContext, actionName: string): RefactorEditInfo | undefined { - Debug.assert(actionName === refactorName, "Unexpected action name"); + function getRefactorEditsToConvertParametersToDestructuredObject(context: ts.RefactorContext, actionName: string): ts.RefactorEditInfo | undefined { + ts.Debug.assert(actionName === refactorName, "Unexpected action name"); const { file, startPosition, program, cancellationToken, host } = context; const functionDeclaration = getFunctionDeclarationAtPosition(file, startPosition, program.getTypeChecker()); - if (!functionDeclaration || !cancellationToken) return undefined; + if (!functionDeclaration || !cancellationToken) + return undefined; const groupedReferences = getGroupedReferences(functionDeclaration, program, cancellationToken); if (groupedReferences.valid) { - const edits = textChanges.ChangeTracker.with(context, t => doChange(file, program, host, t, functionDeclaration, groupedReferences)); + const edits = ts.textChanges.ChangeTracker.with(context, t => doChange(file, program, host, t, functionDeclaration, groupedReferences)); return { renameFilename: undefined, renameLocation: undefined, edits }; } return { edits: [] }; // TODO: GH#30113 } - function doChange( - sourceFile: SourceFile, - program: Program, - host: LanguageServiceHost, - changes: textChanges.ChangeTracker, - functionDeclaration: ValidFunctionDeclaration, - groupedReferences: GroupedReferences): void { + function doChange(sourceFile: ts.SourceFile, program: ts.Program, host: ts.LanguageServiceHost, changes: ts.textChanges.ChangeTracker, functionDeclaration: ValidFunctionDeclaration, groupedReferences: GroupedReferences): void { const signature = groupedReferences.signature; - const newFunctionDeclarationParams = map(createNewParameters(functionDeclaration, program, host), param => getSynthesizedDeepClone(param)); + const newFunctionDeclarationParams = ts.map(createNewParameters(functionDeclaration, program, host), param => ts.getSynthesizedDeepClone(param)); if (signature) { - const newSignatureParams = map(createNewParameters(signature, program, host), param => getSynthesizedDeepClone(param)); + const newSignatureParams = ts.map(createNewParameters(signature, program, host), param => ts.getSynthesizedDeepClone(param)); replaceParameters(signature, newSignatureParams); } replaceParameters(functionDeclaration, newFunctionDeclarationParams); - const functionCalls = sortAndDeduplicate(groupedReferences.functionCalls, /*comparer*/ (a, b) => compareValues(a.pos, b.pos)); + const functionCalls = ts.sortAndDeduplicate(groupedReferences.functionCalls, /*comparer*/ (a, b) => ts.compareValues(a.pos, b.pos)); for (const call of functionCalls) { if (call.arguments && call.arguments.length) { - const newArgument = getSynthesizedDeepClone(createNewArgument(functionDeclaration, call.arguments), /*includeTrivia*/ true); - changes.replaceNodeRange( - getSourceFileOfNode(call), - first(call.arguments), - last(call.arguments), - newArgument, - { leadingTriviaOption: textChanges.LeadingTriviaOption.IncludeAll, trailingTriviaOption: textChanges.TrailingTriviaOption.Include }); + const newArgument = ts.getSynthesizedDeepClone(createNewArgument(functionDeclaration, call.arguments), /*includeTrivia*/ true); + changes.replaceNodeRange(ts.getSourceFileOfNode(call), ts.first(call.arguments), ts.last(call.arguments), newArgument, { leadingTriviaOption: ts.textChanges.LeadingTriviaOption.IncludeAll, trailingTriviaOption: ts.textChanges.TrailingTriviaOption.Include }); } } - - function replaceParameters(declarationOrSignature: ValidFunctionDeclaration | ValidMethodSignature, parameterDeclarations: ParameterDeclaration[]) { - changes.replaceNodeRangeWithNodes( - sourceFile, - first(declarationOrSignature.parameters), - last(declarationOrSignature.parameters), - parameterDeclarations, - { + function replaceParameters(declarationOrSignature: ValidFunctionDeclaration | ValidMethodSignature, parameterDeclarations: ts.ParameterDeclaration[]) { + changes.replaceNodeRangeWithNodes(sourceFile, ts.first(declarationOrSignature.parameters), ts.last(declarationOrSignature.parameters), parameterDeclarations, { joiner: ", ", // indentation is set to 0 because otherwise the object parameter will be indented if there is a `this` parameter indentation: 0, - leadingTriviaOption: textChanges.LeadingTriviaOption.IncludeAll, - trailingTriviaOption: textChanges.TrailingTriviaOption.Include + leadingTriviaOption: ts.textChanges.LeadingTriviaOption.IncludeAll, + trailingTriviaOption: ts.textChanges.TrailingTriviaOption.Include }); } } - function getGroupedReferences(functionDeclaration: ValidFunctionDeclaration, program: Program, cancellationToken: CancellationToken): GroupedReferences { + function getGroupedReferences(functionDeclaration: ValidFunctionDeclaration, program: ts.Program, cancellationToken: ts.CancellationToken): GroupedReferences { const functionNames = getFunctionNames(functionDeclaration); - const classNames = isConstructorDeclaration(functionDeclaration) ? getClassNames(functionDeclaration) : []; - const names = deduplicate([...functionNames, ...classNames], equateValues); + const classNames = ts.isConstructorDeclaration(functionDeclaration) ? getClassNames(functionDeclaration) : []; + const names = ts.deduplicate([...functionNames, ...classNames], ts.equateValues); const checker = program.getTypeChecker(); - const references = flatMap(names, /*mapfn*/ name => FindAllReferences.getReferenceEntriesForNode(-1, name, program, program.getSourceFiles(), cancellationToken)); + const references = ts.flatMap(names, /*mapfn*/ /*mapfn*/ name => ts.FindAllReferences.getReferenceEntriesForNode(-1, name, program, program.getSourceFiles(), cancellationToken)); const groupedReferences = groupReferences(references); - if (!every(groupedReferences.declarations, /*callback*/ decl => contains(names, decl))) { + if (!ts.every(groupedReferences.declarations, /*callback*/ /*callback*/ decl => ts.contains(names, decl))) { groupedReferences.valid = false; } return groupedReferences; - function groupReferences(referenceEntries: readonly FindAllReferences.Entry[]): GroupedReferences { + function groupReferences(referenceEntries: readonly ts.FindAllReferences.Entry[]): GroupedReferences { const classReferences: ClassReferences = { accessExpressions: [], typeUsages: [] }; const groupedReferences: GroupedReferences = { functionCalls: [], declarations: [], classReferences, valid: true }; - const functionSymbols = map(functionNames, getSymbolTargetAtLocation); - const classSymbols = map(classNames, getSymbolTargetAtLocation); - const isConstructor = isConstructorDeclaration(functionDeclaration); - const contextualSymbols = map(functionNames, name => getSymbolForContextualType(name, checker)); + const functionSymbols = ts.map(functionNames, getSymbolTargetAtLocation); + const classSymbols = ts.map(classNames, getSymbolTargetAtLocation); + const isConstructor = ts.isConstructorDeclaration(functionDeclaration); + const contextualSymbols = ts.map(functionNames, name => getSymbolForContextualType(name, checker)); for (const entry of referenceEntries) { - if (entry.kind === FindAllReferences.EntryKind.Span) { + if (entry.kind === ts.FindAllReferences.EntryKind.Span) { groupedReferences.valid = false; continue; } @@ -124,7 +110,7 @@ namespace ts.refactor.convertParamsToDestructuredObject { const foo: IFoo = { m(a: number): void {} } In these cases we get the symbol for the signature from the contextual type. */ - if (contains(contextualSymbols, getSymbolTargetAtLocation(entry.node))) { + if (ts.contains(contextualSymbols, getSymbolTargetAtLocation(entry.node))) { if (isValidMethodSignature(entry.node.parent)) { groupedReferences.signature = entry.node.parent; continue; @@ -137,7 +123,7 @@ namespace ts.refactor.convertParamsToDestructuredObject { } const contextualSymbol = getSymbolForContextualType(entry.node, checker); - if (contextualSymbol && contains(contextualSymbols, contextualSymbol)) { + if (contextualSymbol && ts.contains(contextualSymbols, contextualSymbol)) { const decl = entryToDeclaration(entry); if (decl) { groupedReferences.declarations.push(decl); @@ -156,7 +142,7 @@ namespace ts.refactor.convertParamsToDestructuredObject { So we need to add a special case for this because when calling a constructor of a class through one of its subclasses, the symbols are going to be different. */ - if (contains(functionSymbols, getSymbolTargetAtLocation(entry.node)) || isNewExpressionTarget(entry.node)) { + if (ts.contains(functionSymbols, getSymbolTargetAtLocation(entry.node)) || ts.isNewExpressionTarget(entry.node)) { const importOrExportReference = entryToImportOrExport(entry); if (importOrExportReference) { continue; @@ -174,7 +160,7 @@ namespace ts.refactor.convertParamsToDestructuredObject { } } // if the refactored function is a constructor, we must also check if the references to its class are valid - if (isConstructor && contains(classSymbols, getSymbolTargetAtLocation(entry.node))) { + if (isConstructor && ts.contains(classSymbols, getSymbolTargetAtLocation(entry.node))) { const importOrExportReference = entryToImportOrExport(entry); if (importOrExportReference) { continue; @@ -194,7 +180,7 @@ namespace ts.refactor.convertParamsToDestructuredObject { // Only class declarations are allowed to be used as a type (in a heritage clause), // otherwise `findAllReferences` might not be able to track constructor calls. - if (isClassDeclaration(functionDeclaration.parent)) { + if (ts.isClassDeclaration(functionDeclaration.parent)) { const type = entryToType(entry); if (type) { classReferences.typeUsages.push(type); @@ -208,77 +194,77 @@ namespace ts.refactor.convertParamsToDestructuredObject { return groupedReferences; } - function getSymbolTargetAtLocation(node: Node) { + function getSymbolTargetAtLocation(node: ts.Node) { const symbol = checker.getSymbolAtLocation(node); - return symbol && getSymbolTarget(symbol, checker); + return symbol && ts.getSymbolTarget(symbol, checker); } } /** * Gets the symbol for the contextual type of the node if it is not a union or intersection. */ - function getSymbolForContextualType(node: Node, checker: TypeChecker): Symbol | undefined { - const element = getContainingObjectLiteralElement(node); + function getSymbolForContextualType(node: ts.Node, checker: ts.TypeChecker): ts.Symbol | undefined { + const element = ts.getContainingObjectLiteralElement(node); if (element) { - const contextualType = checker.getContextualTypeForObjectLiteralElement(element as ObjectLiteralElementLike); + const contextualType = checker.getContextualTypeForObjectLiteralElement(element as ts.ObjectLiteralElementLike); const symbol = contextualType?.getSymbol(); - if (symbol && !(getCheckFlags(symbol) & CheckFlags.Synthetic)) { + if (symbol && !(ts.getCheckFlags(symbol) & ts.CheckFlags.Synthetic)) { return symbol; } } } - function entryToImportOrExport(entry: FindAllReferences.NodeEntry): Node | undefined { + function entryToImportOrExport(entry: ts.FindAllReferences.NodeEntry): ts.Node | undefined { const node = entry.node; - if (isImportSpecifier(node.parent) - || isImportClause(node.parent) - || isImportEqualsDeclaration(node.parent) - || isNamespaceImport(node.parent)) { + if (ts.isImportSpecifier(node.parent) + || ts.isImportClause(node.parent) + || ts.isImportEqualsDeclaration(node.parent) + || ts.isNamespaceImport(node.parent)) { return node; } - if (isExportSpecifier(node.parent) || isExportAssignment(node.parent)) { + if (ts.isExportSpecifier(node.parent) || ts.isExportAssignment(node.parent)) { return node; } return undefined; } - function entryToDeclaration(entry: FindAllReferences.NodeEntry): Node | undefined { - if (isDeclaration(entry.node.parent)) { + function entryToDeclaration(entry: ts.FindAllReferences.NodeEntry): ts.Node | undefined { + if (ts.isDeclaration(entry.node.parent)) { return entry.node; } return undefined; } - function entryToFunctionCall(entry: FindAllReferences.NodeEntry): CallExpression | NewExpression | undefined { + function entryToFunctionCall(entry: ts.FindAllReferences.NodeEntry): ts.CallExpression | ts.NewExpression | undefined { if (entry.node.parent) { const functionReference = entry.node; const parent = functionReference.parent; switch (parent.kind) { // foo(...) or super(...) or new Foo(...) - case SyntaxKind.CallExpression: - case SyntaxKind.NewExpression: - const callOrNewExpression = tryCast(parent, isCallOrNewExpression); + case ts.SyntaxKind.CallExpression: + case ts.SyntaxKind.NewExpression: + const callOrNewExpression = ts.tryCast(parent, ts.isCallOrNewExpression); if (callOrNewExpression && callOrNewExpression.expression === functionReference) { return callOrNewExpression; } break; // x.foo(...) - case SyntaxKind.PropertyAccessExpression: - const propertyAccessExpression = tryCast(parent, isPropertyAccessExpression); + case ts.SyntaxKind.PropertyAccessExpression: + const propertyAccessExpression = ts.tryCast(parent, ts.isPropertyAccessExpression); if (propertyAccessExpression && propertyAccessExpression.parent && propertyAccessExpression.name === functionReference) { - const callOrNewExpression = tryCast(propertyAccessExpression.parent, isCallOrNewExpression); + const callOrNewExpression = ts.tryCast(propertyAccessExpression.parent, ts.isCallOrNewExpression); if (callOrNewExpression && callOrNewExpression.expression === propertyAccessExpression) { return callOrNewExpression; } } break; // x["foo"](...) - case SyntaxKind.ElementAccessExpression: - const elementAccessExpression = tryCast(parent, isElementAccessExpression); + case ts.SyntaxKind.ElementAccessExpression: + const elementAccessExpression = ts.tryCast(parent, ts.isElementAccessExpression); if (elementAccessExpression && elementAccessExpression.parent && elementAccessExpression.argumentExpression === functionReference) { - const callOrNewExpression = tryCast(elementAccessExpression.parent, isCallOrNewExpression); + const callOrNewExpression = ts.tryCast(elementAccessExpression.parent, ts.isCallOrNewExpression); if (callOrNewExpression && callOrNewExpression.expression === elementAccessExpression) { return callOrNewExpression; } @@ -289,21 +275,21 @@ namespace ts.refactor.convertParamsToDestructuredObject { return undefined; } - function entryToAccessExpression(entry: FindAllReferences.NodeEntry): ElementAccessExpression | PropertyAccessExpression | undefined { + function entryToAccessExpression(entry: ts.FindAllReferences.NodeEntry): ts.ElementAccessExpression | ts.PropertyAccessExpression | undefined { if (entry.node.parent) { const reference = entry.node; const parent = reference.parent; switch (parent.kind) { // `C.foo` - case SyntaxKind.PropertyAccessExpression: - const propertyAccessExpression = tryCast(parent, isPropertyAccessExpression); + case ts.SyntaxKind.PropertyAccessExpression: + const propertyAccessExpression = ts.tryCast(parent, ts.isPropertyAccessExpression); if (propertyAccessExpression && propertyAccessExpression.expression === reference) { return propertyAccessExpression; } break; // `C["foo"]` - case SyntaxKind.ElementAccessExpression: - const elementAccessExpression = tryCast(parent, isElementAccessExpression); + case ts.SyntaxKind.ElementAccessExpression: + const elementAccessExpression = ts.tryCast(parent, ts.isElementAccessExpression); if (elementAccessExpression && elementAccessExpression.expression === reference) { return elementAccessExpression; } @@ -313,244 +299,229 @@ namespace ts.refactor.convertParamsToDestructuredObject { return undefined; } - function entryToType(entry: FindAllReferences.NodeEntry): Node | undefined { + function entryToType(entry: ts.FindAllReferences.NodeEntry): ts.Node | undefined { const reference = entry.node; - if (getMeaningFromLocation(reference) === SemanticMeaning.Type || isExpressionWithTypeArgumentsInClassExtendsClause(reference.parent)) { + if (ts.getMeaningFromLocation(reference) === ts.SemanticMeaning.Type || ts.isExpressionWithTypeArgumentsInClassExtendsClause(reference.parent)) { return reference; } return undefined; } - function getFunctionDeclarationAtPosition(file: SourceFile, startPosition: number, checker: TypeChecker): ValidFunctionDeclaration | undefined { - const node = getTouchingToken(file, startPosition); - const functionDeclaration = getContainingFunctionDeclaration(node); + function getFunctionDeclarationAtPosition(file: ts.SourceFile, startPosition: number, checker: ts.TypeChecker): ValidFunctionDeclaration | undefined { + const node = ts.getTouchingToken(file, startPosition); + const functionDeclaration = ts.getContainingFunctionDeclaration(node); // don't offer refactor on top-level JSDoc - if (isTopLevelJSDoc(node)) return undefined; + if (isTopLevelJSDoc(node)) + return undefined; if (functionDeclaration && isValidFunctionDeclaration(functionDeclaration, checker) - && rangeContainsRange(functionDeclaration, node) - && !(functionDeclaration.body && rangeContainsRange(functionDeclaration.body, node))) return functionDeclaration; + && ts.rangeContainsRange(functionDeclaration, node) + && !(functionDeclaration.body && ts.rangeContainsRange(functionDeclaration.body, node))) + return functionDeclaration; return undefined; } - function isTopLevelJSDoc(node: Node): boolean { - const containingJSDoc = findAncestor(node, isJSDocNode); + function isTopLevelJSDoc(node: ts.Node): boolean { + const containingJSDoc = ts.findAncestor(node, ts.isJSDocNode); if (containingJSDoc) { - const containingNonJSDoc = findAncestor(containingJSDoc, n => !isJSDocNode(n)); - return !!containingNonJSDoc && isFunctionLikeDeclaration(containingNonJSDoc); + const containingNonJSDoc = ts.findAncestor(containingJSDoc, n => !ts.isJSDocNode(n)); + return !!containingNonJSDoc && ts.isFunctionLikeDeclaration(containingNonJSDoc); } return false; } - function isValidMethodSignature(node: Node): node is ValidMethodSignature { - return isMethodSignature(node) && (isInterfaceDeclaration(node.parent) || isTypeLiteralNode(node.parent)); + function isValidMethodSignature(node: ts.Node): node is ValidMethodSignature { + return ts.isMethodSignature(node) && (ts.isInterfaceDeclaration(node.parent) || ts.isTypeLiteralNode(node.parent)); } - function isValidFunctionDeclaration( - functionDeclaration: FunctionLikeDeclaration, - checker: TypeChecker): functionDeclaration is ValidFunctionDeclaration { - if (!isValidParameterNodeArray(functionDeclaration.parameters, checker)) return false; + function isValidFunctionDeclaration(functionDeclaration: ts.FunctionLikeDeclaration, checker: ts.TypeChecker): functionDeclaration is ValidFunctionDeclaration { + if (!isValidParameterNodeArray(functionDeclaration.parameters, checker)) + return false; switch (functionDeclaration.kind) { - case SyntaxKind.FunctionDeclaration: + case ts.SyntaxKind.FunctionDeclaration: return hasNameOrDefault(functionDeclaration) && isSingleImplementation(functionDeclaration, checker); - case SyntaxKind.MethodDeclaration: - if (isObjectLiteralExpression(functionDeclaration.parent)) { + case ts.SyntaxKind.MethodDeclaration: + if (ts.isObjectLiteralExpression(functionDeclaration.parent)) { const contextualSymbol = getSymbolForContextualType(functionDeclaration.name, checker); // don't offer the refactor when there are multiple signatures since we won't know which ones the user wants to change return contextualSymbol?.declarations?.length === 1 && isSingleImplementation(functionDeclaration, checker); } return isSingleImplementation(functionDeclaration, checker); - case SyntaxKind.Constructor: - if (isClassDeclaration(functionDeclaration.parent)) { + case ts.SyntaxKind.Constructor: + if (ts.isClassDeclaration(functionDeclaration.parent)) { return hasNameOrDefault(functionDeclaration.parent) && isSingleImplementation(functionDeclaration, checker); } else { return isValidVariableDeclaration(functionDeclaration.parent.parent) && isSingleImplementation(functionDeclaration, checker); } - case SyntaxKind.FunctionExpression: - case SyntaxKind.ArrowFunction: + case ts.SyntaxKind.FunctionExpression: + case ts.SyntaxKind.ArrowFunction: return isValidVariableDeclaration(functionDeclaration.parent); } return false; } - function isSingleImplementation(functionDeclaration: FunctionLikeDeclaration, checker: TypeChecker): boolean { + function isSingleImplementation(functionDeclaration: ts.FunctionLikeDeclaration, checker: ts.TypeChecker): boolean { return !!functionDeclaration.body && !checker.isImplementationOfOverload(functionDeclaration); } - function hasNameOrDefault(functionOrClassDeclaration: FunctionDeclaration | ClassDeclaration): boolean { + function hasNameOrDefault(functionOrClassDeclaration: ts.FunctionDeclaration | ts.ClassDeclaration): boolean { if (!functionOrClassDeclaration.name) { - const defaultKeyword = findModifier(functionOrClassDeclaration, SyntaxKind.DefaultKeyword); + const defaultKeyword = ts.findModifier(functionOrClassDeclaration, ts.SyntaxKind.DefaultKeyword); return !!defaultKeyword; } return true; } - function isValidParameterNodeArray( - parameters: NodeArray, - checker: TypeChecker): parameters is ValidParameterNodeArray { + function isValidParameterNodeArray(parameters: ts.NodeArray, checker: ts.TypeChecker): parameters is ValidParameterNodeArray { return getRefactorableParametersLength(parameters) >= minimumParameterLength - && every(parameters, /*callback*/ paramDecl => isValidParameterDeclaration(paramDecl, checker)); + && ts.every(parameters, /*callback*/ /*callback*/ paramDecl => isValidParameterDeclaration(paramDecl, checker)); } - function isValidParameterDeclaration( - parameterDeclaration: ParameterDeclaration, - checker: TypeChecker): parameterDeclaration is ValidParameterDeclaration { - if (isRestParameter(parameterDeclaration)) { + function isValidParameterDeclaration(parameterDeclaration: ts.ParameterDeclaration, checker: ts.TypeChecker): parameterDeclaration is ValidParameterDeclaration { + if (ts.isRestParameter(parameterDeclaration)) { const type = checker.getTypeAtLocation(parameterDeclaration); - if (!checker.isArrayType(type) && !checker.isTupleType(type)) return false; + if (!checker.isArrayType(type) && !checker.isTupleType(type)) + return false; } - return !parameterDeclaration.modifiers && !parameterDeclaration.decorators && isIdentifier(parameterDeclaration.name); + return !parameterDeclaration.modifiers && !parameterDeclaration.decorators && ts.isIdentifier(parameterDeclaration.name); } - function isValidVariableDeclaration(node: Node): node is ValidVariableDeclaration { - return isVariableDeclaration(node) && isVarConst(node) && isIdentifier(node.name) && !node.type; // TODO: GH#30113 + function isValidVariableDeclaration(node: ts.Node): node is ValidVariableDeclaration { + return ts.isVariableDeclaration(node) && ts.isVarConst(node) && ts.isIdentifier(node.name) && !node.type; // TODO: GH#30113 } - function hasThisParameter(parameters: NodeArray): boolean { - return parameters.length > 0 && isThis(parameters[0].name); + function hasThisParameter(parameters: ts.NodeArray): boolean { + return parameters.length > 0 && ts.isThis(parameters[0].name); } - function getRefactorableParametersLength(parameters: NodeArray): number { + function getRefactorableParametersLength(parameters: ts.NodeArray): number { if (hasThisParameter(parameters)) { return parameters.length - 1; } return parameters.length; } - function getRefactorableParameters(parameters: NodeArray): NodeArray { + function getRefactorableParameters(parameters: ts.NodeArray): ts.NodeArray { if (hasThisParameter(parameters)) { - parameters = factory.createNodeArray(parameters.slice(1), parameters.hasTrailingComma); + parameters = ts.factory.createNodeArray(parameters.slice(1), parameters.hasTrailingComma); } return parameters; } - function createPropertyOrShorthandAssignment(name: string, initializer: Expression): PropertyAssignment | ShorthandPropertyAssignment { - if (isIdentifier(initializer) && getTextOfIdentifierOrLiteral(initializer) === name) { - return factory.createShorthandPropertyAssignment(name); + function createPropertyOrShorthandAssignment(name: string, initializer: ts.Expression): ts.PropertyAssignment | ts.ShorthandPropertyAssignment { + if (ts.isIdentifier(initializer) && ts.getTextOfIdentifierOrLiteral(initializer) === name) { + return ts.factory.createShorthandPropertyAssignment(name); } - return factory.createPropertyAssignment(name, initializer); + return ts.factory.createPropertyAssignment(name, initializer); } - function createNewArgument(functionDeclaration: ValidFunctionDeclaration, functionArguments: NodeArray): ObjectLiteralExpression { + function createNewArgument(functionDeclaration: ValidFunctionDeclaration, functionArguments: ts.NodeArray): ts.ObjectLiteralExpression { const parameters = getRefactorableParameters(functionDeclaration.parameters); - const hasRestParameter = isRestParameter(last(parameters)); + const hasRestParameter = ts.isRestParameter(ts.last(parameters)); const nonRestArguments = hasRestParameter ? functionArguments.slice(0, parameters.length - 1) : functionArguments; - const properties = map(nonRestArguments, (arg, i) => { + const properties = ts.map(nonRestArguments, (arg, i) => { const parameterName = getParameterName(parameters[i]); const property = createPropertyOrShorthandAssignment(parameterName, arg); - suppressLeadingAndTrailingTrivia(property.name); - if (isPropertyAssignment(property)) suppressLeadingAndTrailingTrivia(property.initializer); - copyComments(arg, property); + ts.suppressLeadingAndTrailingTrivia(property.name); + if (ts.isPropertyAssignment(property)) + ts.suppressLeadingAndTrailingTrivia(property.initializer); + ts.copyComments(arg, property); return property; }); if (hasRestParameter && functionArguments.length >= parameters.length) { const restArguments = functionArguments.slice(parameters.length - 1); - const restProperty = factory.createPropertyAssignment(getParameterName(last(parameters)), factory.createArrayLiteralExpression(restArguments)); + const restProperty = ts.factory.createPropertyAssignment(getParameterName(ts.last(parameters)), ts.factory.createArrayLiteralExpression(restArguments)); properties.push(restProperty); } - const objectLiteral = factory.createObjectLiteralExpression(properties, /*multiLine*/ false); + const objectLiteral = ts.factory.createObjectLiteralExpression(properties, /*multiLine*/ false); return objectLiteral; } - function createNewParameters(functionDeclaration: ValidFunctionDeclaration | ValidMethodSignature, program: Program, host: LanguageServiceHost): NodeArray { + function createNewParameters(functionDeclaration: ValidFunctionDeclaration | ValidMethodSignature, program: ts.Program, host: ts.LanguageServiceHost): ts.NodeArray { const checker = program.getTypeChecker(); const refactorableParameters = getRefactorableParameters(functionDeclaration.parameters); - const bindingElements = map(refactorableParameters, createBindingElementFromParameterDeclaration); - const objectParameterName = factory.createObjectBindingPattern(bindingElements); + const bindingElements = ts.map(refactorableParameters, createBindingElementFromParameterDeclaration); + const objectParameterName = ts.factory.createObjectBindingPattern(bindingElements); const objectParameterType = createParameterTypeNode(refactorableParameters); - let objectInitializer: Expression | undefined; + let objectInitializer: ts.Expression | undefined; // If every parameter in the original function was optional, add an empty object initializer to the new object parameter - if (every(refactorableParameters, isOptionalParameter)) { - objectInitializer = factory.createObjectLiteralExpression(); + if (ts.every(refactorableParameters, isOptionalParameter)) { + objectInitializer = ts.factory.createObjectLiteralExpression(); } - const objectParameter = factory.createParameterDeclaration( + const objectParameter = ts.factory.createParameterDeclaration( /*decorators*/ undefined, /*modifiers*/ undefined, - /*dotDotDotToken*/ undefined, - objectParameterName, - /*questionToken*/ undefined, - objectParameterType, - objectInitializer); + /*dotDotDotToken*/ undefined, objectParameterName, + /*questionToken*/ undefined, objectParameterType, objectInitializer); if (hasThisParameter(functionDeclaration.parameters)) { const thisParameter = functionDeclaration.parameters[0]; - const newThisParameter = factory.createParameterDeclaration( + const newThisParameter = ts.factory.createParameterDeclaration( /*decorators*/ undefined, /*modifiers*/ undefined, - /*dotDotDotToken*/ undefined, - thisParameter.name, - /*questionToken*/ undefined, - thisParameter.type); - - suppressLeadingAndTrailingTrivia(newThisParameter.name); - copyComments(thisParameter.name, newThisParameter.name); + /*dotDotDotToken*/ undefined, thisParameter.name, + /*questionToken*/ undefined, thisParameter.type); + ts.suppressLeadingAndTrailingTrivia(newThisParameter.name); + ts.copyComments(thisParameter.name, newThisParameter.name); if (thisParameter.type) { - suppressLeadingAndTrailingTrivia(newThisParameter.type!); - copyComments(thisParameter.type, newThisParameter.type!); + ts.suppressLeadingAndTrailingTrivia(newThisParameter.type!); + ts.copyComments(thisParameter.type, newThisParameter.type!); } - return factory.createNodeArray([newThisParameter, objectParameter]); + return ts.factory.createNodeArray([newThisParameter, objectParameter]); } - return factory.createNodeArray([objectParameter]); - - function createBindingElementFromParameterDeclaration(parameterDeclaration: ValidParameterDeclaration): BindingElement { - const element = factory.createBindingElement( + return ts.factory.createNodeArray([objectParameter]); + function createBindingElementFromParameterDeclaration(parameterDeclaration: ValidParameterDeclaration): ts.BindingElement { + const element = ts.factory.createBindingElement( /*dotDotDotToken*/ undefined, - /*propertyName*/ undefined, - getParameterName(parameterDeclaration), - isRestParameter(parameterDeclaration) && isOptionalParameter(parameterDeclaration) ? factory.createArrayLiteralExpression() : parameterDeclaration.initializer); - - suppressLeadingAndTrailingTrivia(element); + /*propertyName*/ undefined, getParameterName(parameterDeclaration), ts.isRestParameter(parameterDeclaration) && isOptionalParameter(parameterDeclaration) ? ts.factory.createArrayLiteralExpression() : parameterDeclaration.initializer); + ts.suppressLeadingAndTrailingTrivia(element); if (parameterDeclaration.initializer && element.initializer) { - copyComments(parameterDeclaration.initializer, element.initializer); + ts.copyComments(parameterDeclaration.initializer, element.initializer); } return element; } - function createParameterTypeNode(parameters: NodeArray): TypeLiteralNode { - const members = map(parameters, createPropertySignatureFromParameterDeclaration); - const typeNode = addEmitFlags(factory.createTypeLiteralNode(members), EmitFlags.SingleLine); + function createParameterTypeNode(parameters: ts.NodeArray): ts.TypeLiteralNode { + const members = ts.map(parameters, createPropertySignatureFromParameterDeclaration); + const typeNode = ts.addEmitFlags(ts.factory.createTypeLiteralNode(members), ts.EmitFlags.SingleLine); return typeNode; } - function createPropertySignatureFromParameterDeclaration(parameterDeclaration: ValidParameterDeclaration): PropertySignature { + function createPropertySignatureFromParameterDeclaration(parameterDeclaration: ValidParameterDeclaration): ts.PropertySignature { let parameterType = parameterDeclaration.type; - if (!parameterType && (parameterDeclaration.initializer || isRestParameter(parameterDeclaration))) { + if (!parameterType && (parameterDeclaration.initializer || ts.isRestParameter(parameterDeclaration))) { parameterType = getTypeNode(parameterDeclaration); } - const propertySignature = factory.createPropertySignature( - /*modifiers*/ undefined, - getParameterName(parameterDeclaration), - isOptionalParameter(parameterDeclaration) ? factory.createToken(SyntaxKind.QuestionToken) : parameterDeclaration.questionToken, - parameterType); - - suppressLeadingAndTrailingTrivia(propertySignature); - copyComments(parameterDeclaration.name, propertySignature.name); + const propertySignature = ts.factory.createPropertySignature( + /*modifiers*/ undefined, getParameterName(parameterDeclaration), isOptionalParameter(parameterDeclaration) ? ts.factory.createToken(ts.SyntaxKind.QuestionToken) : parameterDeclaration.questionToken, parameterType); + ts.suppressLeadingAndTrailingTrivia(propertySignature); + ts.copyComments(parameterDeclaration.name, propertySignature.name); if (parameterDeclaration.type && propertySignature.type) { - copyComments(parameterDeclaration.type, propertySignature.type); + ts.copyComments(parameterDeclaration.type, propertySignature.type); } return propertySignature; } - function getTypeNode(node: Node): TypeNode | undefined { + function getTypeNode(node: ts.Node): ts.TypeNode | undefined { const type = checker.getTypeAtLocation(node); - return getTypeNodeIfAccessible(type, node, program, host); + return ts.getTypeNodeIfAccessible(type, node, program, host); } function isOptionalParameter(parameterDeclaration: ValidParameterDeclaration): boolean { - if (isRestParameter(parameterDeclaration)) { + if (ts.isRestParameter(parameterDeclaration)) { const type = checker.getTypeAtLocation(parameterDeclaration); return !checker.isTupleType(type); } @@ -559,114 +530,113 @@ namespace ts.refactor.convertParamsToDestructuredObject { } function getParameterName(paramDeclaration: ValidParameterDeclaration) { - return getTextOfIdentifierOrLiteral(paramDeclaration.name); + return ts.getTextOfIdentifierOrLiteral(paramDeclaration.name); } - function getClassNames(constructorDeclaration: ValidConstructor): (Identifier | Modifier)[] { + function getClassNames(constructorDeclaration: ValidConstructor): (ts.Identifier | ts.Modifier)[] { switch (constructorDeclaration.parent.kind) { - case SyntaxKind.ClassDeclaration: + case ts.SyntaxKind.ClassDeclaration: const classDeclaration = constructorDeclaration.parent; - if (classDeclaration.name) return [classDeclaration.name]; + if (classDeclaration.name) + return [classDeclaration.name]; // If the class declaration doesn't have a name, it should have a default modifier. // We validated this in `isValidFunctionDeclaration` through `hasNameOrDefault` - const defaultModifier = Debug.checkDefined( - findModifier(classDeclaration, SyntaxKind.DefaultKeyword), - "Nameless class declaration should be a default export"); + const defaultModifier = ts.Debug.checkDefined(ts.findModifier(classDeclaration, ts.SyntaxKind.DefaultKeyword), "Nameless class declaration should be a default export"); return [defaultModifier]; - case SyntaxKind.ClassExpression: + case ts.SyntaxKind.ClassExpression: const classExpression = constructorDeclaration.parent; const variableDeclaration = constructorDeclaration.parent.parent; const className = classExpression.name; - if (className) return [className, variableDeclaration.name]; + if (className) + return [className, variableDeclaration.name]; return [variableDeclaration.name]; } } - function getFunctionNames(functionDeclaration: ValidFunctionDeclaration): Node[] { + function getFunctionNames(functionDeclaration: ValidFunctionDeclaration): ts.Node[] { switch (functionDeclaration.kind) { - case SyntaxKind.FunctionDeclaration: - if (functionDeclaration.name) return [functionDeclaration.name]; + case ts.SyntaxKind.FunctionDeclaration: + if (functionDeclaration.name) + return [functionDeclaration.name]; // If the function declaration doesn't have a name, it should have a default modifier. // We validated this in `isValidFunctionDeclaration` through `hasNameOrDefault` - const defaultModifier = Debug.checkDefined( - findModifier(functionDeclaration, SyntaxKind.DefaultKeyword), - "Nameless function declaration should be a default export"); + const defaultModifier = ts.Debug.checkDefined(ts.findModifier(functionDeclaration, ts.SyntaxKind.DefaultKeyword), "Nameless function declaration should be a default export"); return [defaultModifier]; - case SyntaxKind.MethodDeclaration: + case ts.SyntaxKind.MethodDeclaration: return [functionDeclaration.name]; - case SyntaxKind.Constructor: - const ctrKeyword = Debug.checkDefined( - findChildOfKind(functionDeclaration, SyntaxKind.ConstructorKeyword, functionDeclaration.getSourceFile()), - "Constructor declaration should have constructor keyword"); - if (functionDeclaration.parent.kind === SyntaxKind.ClassExpression) { + case ts.SyntaxKind.Constructor: + const ctrKeyword = ts.Debug.checkDefined(ts.findChildOfKind(functionDeclaration, ts.SyntaxKind.ConstructorKeyword, functionDeclaration.getSourceFile()), "Constructor declaration should have constructor keyword"); + if (functionDeclaration.parent.kind === ts.SyntaxKind.ClassExpression) { const variableDeclaration = functionDeclaration.parent.parent; return [variableDeclaration.name, ctrKeyword]; } return [ctrKeyword]; - case SyntaxKind.ArrowFunction: + case ts.SyntaxKind.ArrowFunction: return [functionDeclaration.parent.name]; - case SyntaxKind.FunctionExpression: - if (functionDeclaration.name) return [functionDeclaration.name, functionDeclaration.parent.name]; + case ts.SyntaxKind.FunctionExpression: + if (functionDeclaration.name) + return [functionDeclaration.name, functionDeclaration.parent.name]; return [functionDeclaration.parent.name]; default: - return Debug.assertNever(functionDeclaration, `Unexpected function declaration kind ${(functionDeclaration as ValidFunctionDeclaration).kind}`); + return ts.Debug.assertNever(functionDeclaration, `Unexpected function declaration kind ${(functionDeclaration as ValidFunctionDeclaration).kind}`); } } - type ValidParameterNodeArray = NodeArray; - - interface ValidVariableDeclaration extends VariableDeclaration { - name: Identifier; + type ValidParameterNodeArray = ts.NodeArray; + interface ValidVariableDeclaration extends ts.VariableDeclaration { + name: ts.Identifier; type: undefined; } - interface ValidConstructor extends ConstructorDeclaration { - parent: ClassDeclaration | (ClassExpression & { parent: ValidVariableDeclaration }); - parameters: NodeArray; - body: FunctionBody; + interface ValidConstructor extends ts.ConstructorDeclaration { + parent: ts.ClassDeclaration | (ts.ClassExpression & { + parent: ValidVariableDeclaration; + }); + parameters: ts.NodeArray; + body: ts.FunctionBody; } - interface ValidFunction extends FunctionDeclaration { - parameters: NodeArray; - body: FunctionBody; + interface ValidFunction extends ts.FunctionDeclaration { + parameters: ts.NodeArray; + body: ts.FunctionBody; } - interface ValidMethod extends MethodDeclaration { - parameters: NodeArray; - body: FunctionBody; + interface ValidMethod extends ts.MethodDeclaration { + parameters: ts.NodeArray; + body: ts.FunctionBody; } - interface ValidFunctionExpression extends FunctionExpression { + interface ValidFunctionExpression extends ts.FunctionExpression { parent: ValidVariableDeclaration; - parameters: NodeArray; + parameters: ts.NodeArray; } - interface ValidArrowFunction extends ArrowFunction { + interface ValidArrowFunction extends ts.ArrowFunction { parent: ValidVariableDeclaration; - parameters: NodeArray; + parameters: ts.NodeArray; } - interface ValidMethodSignature extends MethodSignature { - parameters: NodeArray; + interface ValidMethodSignature extends ts.MethodSignature { + parameters: ts.NodeArray; } type ValidFunctionDeclaration = ValidConstructor | ValidFunction | ValidMethod | ValidArrowFunction | ValidFunctionExpression; - interface ValidParameterDeclaration extends ParameterDeclaration { - name: Identifier; + interface ValidParameterDeclaration extends ts.ParameterDeclaration { + name: ts.Identifier; modifiers: undefined; decorators: undefined; } interface GroupedReferences { - functionCalls: (CallExpression | NewExpression)[]; - declarations: Node[]; + functionCalls: (ts.CallExpression | ts.NewExpression)[]; + declarations: ts.Node[]; signature?: ValidMethodSignature; classReferences?: ClassReferences; valid: boolean; } interface ClassReferences { - accessExpressions: Node[]; - typeUsages: Node[]; + accessExpressions: ts.Node[]; + typeUsages: ts.Node[]; } } diff --git a/src/services/refactors/convertStringOrTemplateLiteral.ts b/src/services/refactors/convertStringOrTemplateLiteral.ts index 82c7452f81923..d4c7bbaec65ee 100644 --- a/src/services/refactors/convertStringOrTemplateLiteral.ts +++ b/src/services/refactors/convertStringOrTemplateLiteral.ts @@ -1,54 +1,51 @@ /* @internal */ namespace ts.refactor.convertStringOrTemplateLiteral { const refactorName = "Convert to template string"; - const refactorDescription = getLocaleSpecificMessage(Diagnostics.Convert_to_template_string); + const refactorDescription = ts.getLocaleSpecificMessage(ts.Diagnostics.Convert_to_template_string); const convertStringAction = { name: refactorName, description: refactorDescription, kind: "refactor.rewrite.string" }; - registerRefactor(refactorName, { + ts.refactor.registerRefactor(refactorName, { kinds: [convertStringAction.kind], getEditsForAction: getRefactorEditsToConvertToTemplateString, getAvailableActions: getRefactorActionsToConvertToTemplateString }); - function getRefactorActionsToConvertToTemplateString(context: RefactorContext): readonly ApplicableRefactorInfo[] { + function getRefactorActionsToConvertToTemplateString(context: ts.RefactorContext): readonly ts.ApplicableRefactorInfo[] { const { file, startPosition } = context; const node = getNodeOrParentOfParentheses(file, startPosition); const maybeBinary = getParentBinaryExpression(node); - const refactorInfo: ApplicableRefactorInfo = { name: refactorName, description: refactorDescription, actions: [] }; - - if (isBinaryExpression(maybeBinary) && treeToArray(maybeBinary).isValidConcatenation) { + const refactorInfo: ts.ApplicableRefactorInfo = { name: refactorName, description: refactorDescription, actions: [] }; + if (ts.isBinaryExpression(maybeBinary) && treeToArray(maybeBinary).isValidConcatenation) { refactorInfo.actions.push(convertStringAction); return [refactorInfo]; } else if (context.preferences.provideRefactorNotApplicableReason) { refactorInfo.actions.push({ ...convertStringAction, - notApplicableReason: getLocaleSpecificMessage(Diagnostics.Can_only_convert_string_concatenation) + notApplicableReason: ts.getLocaleSpecificMessage(ts.Diagnostics.Can_only_convert_string_concatenation) }); return [refactorInfo]; } - return emptyArray; + return ts.emptyArray; } - function getNodeOrParentOfParentheses(file: SourceFile, startPosition: number) { - const node = getTokenAtPosition(file, startPosition); + function getNodeOrParentOfParentheses(file: ts.SourceFile, startPosition: number) { + const node = ts.getTokenAtPosition(file, startPosition); const nestedBinary = getParentBinaryExpression(node); const isNonStringBinary = !treeToArray(nestedBinary).isValidConcatenation; - if ( - isNonStringBinary && - isParenthesizedExpression(nestedBinary.parent) && - isBinaryExpression(nestedBinary.parent.parent) - ) { + if (isNonStringBinary && + ts.isParenthesizedExpression(nestedBinary.parent) && + ts.isBinaryExpression(nestedBinary.parent.parent)) { return nestedBinary.parent.parent; } return node; } - function getRefactorEditsToConvertToTemplateString(context: RefactorContext, actionName: string): RefactorEditInfo | undefined { + function getRefactorEditsToConvertToTemplateString(context: ts.RefactorContext, actionName: string): ts.RefactorEditInfo | undefined { const { file, startPosition } = context; const node = getNodeOrParentOfParentheses(file, startPosition); @@ -56,16 +53,16 @@ namespace ts.refactor.convertStringOrTemplateLiteral { case refactorDescription: return { edits: getEditsForToTemplateLiteral(context, node) }; default: - return Debug.fail("invalid action"); + return ts.Debug.fail("invalid action"); } } - function getEditsForToTemplateLiteral(context: RefactorContext, node: Node) { + function getEditsForToTemplateLiteral(context: ts.RefactorContext, node: ts.Node) { const maybeBinary = getParentBinaryExpression(node); const file = context.file; const templateLiteral = nodesToTemplate(treeToArray(maybeBinary), file); - const trailingCommentRanges = getTrailingCommentRanges(file.text, maybeBinary.end); + const trailingCommentRanges = ts.getTrailingCommentRanges(file.text, maybeBinary.end); if (trailingCommentRanges) { const lastComment = trailingCommentRanges[trailingCommentRanges.length - 1]; @@ -73,50 +70,54 @@ namespace ts.refactor.convertStringOrTemplateLiteral { // since suppressTrailingTrivia(maybeBinary) does not work, the trailing comment is removed manually // otherwise it would have the trailing comment twice - return textChanges.ChangeTracker.with(context, t => { + return ts.textChanges.ChangeTracker.with(context, t => { t.deleteRange(file, trailingRange); t.replaceNode(file, maybeBinary, templateLiteral); }); } else { - return textChanges.ChangeTracker.with(context, t => t.replaceNode(file, maybeBinary, templateLiteral)); + return ts.textChanges.ChangeTracker.with(context, t => t.replaceNode(file, maybeBinary, templateLiteral)); } } - function isNotEqualsOperator(node: BinaryExpression) { - return node.operatorToken.kind !== SyntaxKind.EqualsToken; + function isNotEqualsOperator(node: ts.BinaryExpression) { + return node.operatorToken.kind !== ts.SyntaxKind.EqualsToken; } - function getParentBinaryExpression(expr: Node) { - const container = findAncestor(expr.parent, n => { + function getParentBinaryExpression(expr: ts.Node) { + const container = ts.findAncestor(expr.parent, n => { switch (n.kind) { - case SyntaxKind.PropertyAccessExpression: - case SyntaxKind.ElementAccessExpression: + case ts.SyntaxKind.PropertyAccessExpression: + case ts.SyntaxKind.ElementAccessExpression: return false; - case SyntaxKind.TemplateExpression: - case SyntaxKind.BinaryExpression: - return !(isBinaryExpression(n.parent) && isNotEqualsOperator(n.parent)); + case ts.SyntaxKind.TemplateExpression: + case ts.SyntaxKind.BinaryExpression: + return !(ts.isBinaryExpression(n.parent) && isNotEqualsOperator(n.parent)); default: return "quit"; } }); - return (container || expr) as Expression; + return (container || expr) as ts.Expression; } - - function treeToArray(current: Expression) { - const loop = (current: Node): { nodes: Expression[], operators: Token[], hasString: boolean, validOperators: boolean} => { - if (!isBinaryExpression(current)) { - return { nodes: [current as Expression], operators: [], validOperators: true, - hasString: isStringLiteral(current) || isNoSubstitutionTemplateLiteral(current) }; + function treeToArray(current: ts.Expression) { + const loop = (current: ts.Node): { + nodes: ts.Expression[]; + operators: ts.Token[]; + hasString: boolean; + validOperators: boolean; + } => { + if (!ts.isBinaryExpression(current)) { + return { nodes: [current as ts.Expression], operators: [], validOperators: true, + hasString: ts.isStringLiteral(current) || ts.isNoSubstitutionTemplateLiteral(current) }; } const { nodes, operators, hasString: leftHasString, validOperators: leftOperatorValid } = loop(current.left); - if (!(leftHasString || isStringLiteral(current.right) || isTemplateExpression(current.right))) { + if (!(leftHasString || ts.isStringLiteral(current.right) || ts.isTemplateExpression(current.right))) { return { nodes: [current], operators: [], hasString: false, validOperators: true }; } - const currentOperatorValid = current.operatorToken.kind === SyntaxKind.PlusToken; + const currentOperatorValid = current.operatorToken.kind === ts.SyntaxKind.PlusToken; const validOperators = leftOperatorValid && currentOperatorValid; nodes.push(current.right); @@ -130,19 +131,18 @@ namespace ts.refactor.convertStringOrTemplateLiteral { // to copy comments following the operator // "foo" + /* comment */ "bar" - const copyTrailingOperatorComments = (operators: Token[], file: SourceFile) => (index: number, targetNode: Node) => { + const copyTrailingOperatorComments = (operators: ts.Token[], file: ts.SourceFile) => (index: number, targetNode: ts.Node) => { if (index < operators.length) { - copyTrailingComments(operators[index], targetNode, file, SyntaxKind.MultiLineCommentTrivia, /* hasTrailingNewLine */ false); + ts.copyTrailingComments(operators[index], targetNode, file, ts.SyntaxKind.MultiLineCommentTrivia, /* hasTrailingNewLine */ false); } }; // to copy comments following the string // "foo" /* comment */ + "bar" /* comment */ + "bar2" - const copyCommentFromMultiNode = (nodes: readonly Expression[], file: SourceFile, copyOperatorComments: (index: number, targetNode: Node) => void) => - (indexes: number[], targetNode: Node) => { + const copyCommentFromMultiNode = (nodes: readonly ts.Expression[], file: ts.SourceFile, copyOperatorComments: (index: number, targetNode: ts.Node) => void) => (indexes: number[], targetNode: ts.Node) => { while (indexes.length > 0) { const index = indexes.shift()!; - copyTrailingComments(nodes[index], targetNode, file, SyntaxKind.MultiLineCommentTrivia, /* hasTrailingNewLine */ false); + ts.copyTrailingComments(nodes[index], targetNode, file, ts.SyntaxKind.MultiLineCommentTrivia, /* hasTrailingNewLine */ false); copyOperatorComments(index, targetNode); } }; @@ -157,24 +157,28 @@ namespace ts.refactor.convertStringOrTemplateLiteral { // but `\$${foo}` is likely more clear than the more-confusing-but-still-working `$${foo}`. } - function getRawTextOfTemplate(node: TemplateHead | TemplateMiddle | TemplateTail) { + function getRawTextOfTemplate(node: ts.TemplateHead | ts.TemplateMiddle | ts.TemplateTail) { // in these cases the right side is ${ - const rightShaving = isTemplateHead(node) || isTemplateMiddle(node) ? -2 : -1; - return getTextOfNode(node).slice(1, rightShaving); + const rightShaving = ts.isTemplateHead(node) || ts.isTemplateMiddle(node) ? -2 : -1; + return ts.getTextOfNode(node).slice(1, rightShaving); } - - function concatConsecutiveString(index: number, nodes: readonly Expression[]): [nextIndex: number, text: string, rawText: string, usedIndexes: number[]] { + function concatConsecutiveString(index: number, nodes: readonly ts.Expression[]): [ + nextIndex: number, + text: string, + rawText: string, + usedIndexes: number[] + ] { const indexes = []; let text = "", rawText = ""; while (index < nodes.length) { const node = nodes[index]; - if (isStringLiteralLike(node)) { // includes isNoSubstitutionTemplateLiteral(node) + if (ts.isStringLiteralLike(node)) { // includes isNoSubstitutionTemplateLiteral(node) text += node.text; - rawText += escapeRawStringForTemplate(getTextOfNode(node).slice(1, -1)); + rawText += escapeRawStringForTemplate(ts.getTextOfNode(node).slice(1, -1)); indexes.push(index); index++; } - else if (isTemplateExpression(node)) { + else if (ts.isTemplateExpression(node)) { text += node.head.text; rawText += getRawTextOfTemplate(node.head); break; @@ -186,19 +190,22 @@ namespace ts.refactor.convertStringOrTemplateLiteral { return [index, text, rawText, indexes]; } - function nodesToTemplate({ nodes, operators }: { nodes: readonly Expression[], operators: Token[] }, file: SourceFile) { + function nodesToTemplate({ nodes, operators }: { + nodes: readonly ts.Expression[]; + operators: ts.Token[]; + }, file: ts.SourceFile) { const copyOperatorComments = copyTrailingOperatorComments(operators, file); const copyCommentFromStringLiterals = copyCommentFromMultiNode(nodes, file, copyOperatorComments); const [begin, headText, rawHeadText, headIndexes] = concatConsecutiveString(0, nodes); if (begin === nodes.length) { - const noSubstitutionTemplateLiteral = factory.createNoSubstitutionTemplateLiteral(headText, rawHeadText); + const noSubstitutionTemplateLiteral = ts.factory.createNoSubstitutionTemplateLiteral(headText, rawHeadText); copyCommentFromStringLiterals(headIndexes, noSubstitutionTemplateLiteral); return noSubstitutionTemplateLiteral; } - const templateSpans: TemplateSpan[] = []; - const templateHead = factory.createTemplateHead(headText, rawHeadText); + const templateSpans: ts.TemplateSpan[] = []; + const templateHead = ts.factory.createTemplateHead(headText, rawHeadText); copyCommentFromStringLiterals(headIndexes, templateHead); for (let i = begin; i < nodes.length; i++) { @@ -209,40 +216,40 @@ namespace ts.refactor.convertStringOrTemplateLiteral { i = newIndex - 1; const isLast = i === nodes.length - 1; - if (isTemplateExpression(currentNode)) { - const spans = map(currentNode.templateSpans, (span, index) => { + if (ts.isTemplateExpression(currentNode)) { + const spans = ts.map(currentNode.templateSpans, (span, index) => { copyExpressionComments(span); const isLastSpan = index === currentNode.templateSpans.length - 1; const text = span.literal.text + (isLastSpan ? subsequentText : ""); const rawText = getRawTextOfTemplate(span.literal) + (isLastSpan ? rawSubsequentText : ""); - return factory.createTemplateSpan(span.expression, isLast && isLastSpan - ? factory.createTemplateTail(text, rawText) - : factory.createTemplateMiddle(text, rawText)); + return ts.factory.createTemplateSpan(span.expression, isLast && isLastSpan + ? ts.factory.createTemplateTail(text, rawText) + : ts.factory.createTemplateMiddle(text, rawText)); }); templateSpans.push(...spans); } else { const templatePart = isLast - ? factory.createTemplateTail(subsequentText, rawSubsequentText) - : factory.createTemplateMiddle(subsequentText, rawSubsequentText); + ? ts.factory.createTemplateTail(subsequentText, rawSubsequentText) + : ts.factory.createTemplateMiddle(subsequentText, rawSubsequentText); copyCommentFromStringLiterals(stringIndexes, templatePart); - templateSpans.push(factory.createTemplateSpan(currentNode, templatePart)); + templateSpans.push(ts.factory.createTemplateSpan(currentNode, templatePart)); } } - return factory.createTemplateExpression(templateHead, templateSpans); + return ts.factory.createTemplateExpression(templateHead, templateSpans); } // to copy comments following the opening & closing parentheses // "foo" + ( /* comment */ 5 + 5 ) /* comment */ + "bar" - function copyExpressionComments(node: ParenthesizedExpression | TemplateSpan) { + function copyExpressionComments(node: ts.ParenthesizedExpression | ts.TemplateSpan) { const file = node.getSourceFile(); - copyTrailingComments(node, node.expression, file, SyntaxKind.MultiLineCommentTrivia, /* hasTrailingNewLine */ false); - copyTrailingAsLeadingComments(node.expression, node.expression, file, SyntaxKind.MultiLineCommentTrivia, /* hasTrailingNewLine */ false); + ts.copyTrailingComments(node, node.expression, file, ts.SyntaxKind.MultiLineCommentTrivia, /* hasTrailingNewLine */ false); + ts.copyTrailingAsLeadingComments(node.expression, node.expression, file, ts.SyntaxKind.MultiLineCommentTrivia, /* hasTrailingNewLine */ false); } - function getExpressionFromParenthesesOrExpression(node: Expression) { - if (isParenthesizedExpression(node)) { + function getExpressionFromParenthesesOrExpression(node: ts.Expression) { + if (ts.isParenthesizedExpression(node)) { copyExpressionComments(node); node = node.expression; } diff --git a/src/services/refactors/convertToOptionalChainExpression.ts b/src/services/refactors/convertToOptionalChainExpression.ts index ba40ec6a5e553..1ca419ef96e4f 100644 --- a/src/services/refactors/convertToOptionalChainExpression.ts +++ b/src/services/refactors/convertToOptionalChainExpression.ts @@ -1,24 +1,24 @@ /* @internal */ namespace ts.refactor.convertToOptionalChainExpression { const refactorName = "Convert to optional chain expression"; - const convertToOptionalChainExpressionMessage = getLocaleSpecificMessage(Diagnostics.Convert_to_optional_chain_expression); + const convertToOptionalChainExpressionMessage = ts.getLocaleSpecificMessage(ts.Diagnostics.Convert_to_optional_chain_expression); const toOptionalChainAction = { name: refactorName, description: convertToOptionalChainExpressionMessage, kind: "refactor.rewrite.expression.optionalChain", }; - registerRefactor(refactorName, { + ts.refactor.registerRefactor(refactorName, { kinds: [toOptionalChainAction.kind], getEditsForAction: getRefactorEditsToConvertToOptionalChain, getAvailableActions: getRefactorActionsToConvertToOptionalChain, }); - function getRefactorActionsToConvertToOptionalChain(context: RefactorContext): readonly ApplicableRefactorInfo[] { + function getRefactorActionsToConvertToOptionalChain(context: ts.RefactorContext): readonly ts.ApplicableRefactorInfo[] { const info = getInfo(context, context.triggerReason === "invoked"); - if (!info) return emptyArray; - - if (!isRefactorErrorInfo(info)) { + if (!info) + return ts.emptyArray; + if (!ts.refactor.isRefactorErrorInfo(info)) { return [{ name: refactorName, description: convertToOptionalChainExpressionMessage, @@ -33,109 +33,111 @@ namespace ts.refactor.convertToOptionalChainExpression { actions: [{ ...toOptionalChainAction, notApplicableReason: info.error }], }]; } - return emptyArray; + return ts.emptyArray; } - function getRefactorEditsToConvertToOptionalChain(context: RefactorContext, actionName: string): RefactorEditInfo | undefined { + function getRefactorEditsToConvertToOptionalChain(context: ts.RefactorContext, actionName: string): ts.RefactorEditInfo | undefined { const info = getInfo(context); - Debug.assert(info && !isRefactorErrorInfo(info), "Expected applicable refactor info"); - const edits = textChanges.ChangeTracker.with(context, t => - doChange(context.file, context.program.getTypeChecker(), t, info, actionName) - ); + ts.Debug.assert(info && !ts.refactor.isRefactorErrorInfo(info), "Expected applicable refactor info"); + const edits = ts.textChanges.ChangeTracker.with(context, t => doChange(context.file, context.program.getTypeChecker(), t, info, actionName)); return { edits, renameFilename: undefined, renameLocation: undefined }; } - type Occurrence = PropertyAccessExpression | ElementAccessExpression | Identifier; + type Occurrence = ts.PropertyAccessExpression | ts.ElementAccessExpression | ts.Identifier; interface OptionalChainInfo { - finalExpression: PropertyAccessExpression | ElementAccessExpression | CallExpression, - occurrences: Occurrence[], - expression: ValidExpression, - }; + finalExpression: ts.PropertyAccessExpression | ts.ElementAccessExpression | ts.CallExpression; + occurrences: Occurrence[]; + expression: ValidExpression; + } + ; type ValidExpressionOrStatement = ValidExpression | ValidStatement; /** * Types for which a "Convert to optional chain refactor" are offered. */ - type ValidExpression = BinaryExpression | ConditionalExpression; + type ValidExpression = ts.BinaryExpression | ts.ConditionalExpression; /** * Types of statements which are likely to include a valid expression for extraction. */ - type ValidStatement = ExpressionStatement | ReturnStatement | VariableStatement; - - function isValidExpression(node: Node): node is ValidExpression { - return isBinaryExpression(node) || isConditionalExpression(node); + type ValidStatement = ts.ExpressionStatement | ts.ReturnStatement | ts.VariableStatement; + function isValidExpression(node: ts.Node): node is ValidExpression { + return ts.isBinaryExpression(node) || ts.isConditionalExpression(node); } - function isValidStatement(node: Node): node is ValidStatement { - return isExpressionStatement(node) || isReturnStatement(node) || isVariableStatement(node); + function isValidStatement(node: ts.Node): node is ValidStatement { + return ts.isExpressionStatement(node) || ts.isReturnStatement(node) || ts.isVariableStatement(node); } - function isValidExpressionOrStatement(node: Node): node is ValidExpressionOrStatement { + function isValidExpressionOrStatement(node: ts.Node): node is ValidExpressionOrStatement { return isValidExpression(node) || isValidStatement(node); } - function getInfo(context: RefactorContext, considerEmptySpans = true): OptionalChainInfo | RefactorErrorInfo | undefined { + function getInfo(context: ts.RefactorContext, considerEmptySpans = true): OptionalChainInfo | ts.refactor.RefactorErrorInfo | undefined { const { file, program } = context; - const span = getRefactorContextSpan(context); + const span = ts.getRefactorContextSpan(context); const forEmptySpan = span.length === 0; - if (forEmptySpan && !considerEmptySpans) return undefined; + if (forEmptySpan && !considerEmptySpans) + return undefined; // selecting fo[|o && foo.ba|]r should be valid, so adjust span to fit start and end tokens - const startToken = getTokenAtPosition(file, span.start); - const endToken = findTokenOnLeftOfPosition(file, span.start + span.length); - const adjustedSpan = createTextSpanFromBounds(startToken.pos, endToken && endToken.end >= startToken.pos ? endToken.getEnd() : startToken.getEnd()); + const startToken = ts.getTokenAtPosition(file, span.start); + const endToken = ts.findTokenOnLeftOfPosition(file, span.start + span.length); + const adjustedSpan = ts.createTextSpanFromBounds(startToken.pos, endToken && endToken.end >= startToken.pos ? endToken.getEnd() : startToken.getEnd()); const parent = forEmptySpan ? getValidParentNodeOfEmptySpan(startToken) : getValidParentNodeContainingSpan(startToken, adjustedSpan); const expression = parent && isValidExpressionOrStatement(parent) ? getExpression(parent) : undefined; - if (!expression) return { error: getLocaleSpecificMessage(Diagnostics.Could_not_find_convertible_access_expression) }; + if (!expression) + return { error: ts.getLocaleSpecificMessage(ts.Diagnostics.Could_not_find_convertible_access_expression) }; const checker = program.getTypeChecker(); - return isConditionalExpression(expression) ? getConditionalInfo(expression, checker) : getBinaryInfo(expression); + return ts.isConditionalExpression(expression) ? getConditionalInfo(expression, checker) : getBinaryInfo(expression); } - function getConditionalInfo(expression: ConditionalExpression, checker: TypeChecker): OptionalChainInfo | RefactorErrorInfo | undefined { + function getConditionalInfo(expression: ts.ConditionalExpression, checker: ts.TypeChecker): OptionalChainInfo | ts.refactor.RefactorErrorInfo | undefined { const condition = expression.condition; const finalExpression = getFinalExpressionInChain(expression.whenTrue); if (!finalExpression || checker.isNullableType(checker.getTypeAtLocation(finalExpression))) { - return { error: getLocaleSpecificMessage(Diagnostics.Could_not_find_convertible_access_expression) }; + return { error: ts.getLocaleSpecificMessage(ts.Diagnostics.Could_not_find_convertible_access_expression) }; } - if ((isPropertyAccessExpression(condition) || isIdentifier(condition)) + if ((ts.isPropertyAccessExpression(condition) || ts.isIdentifier(condition)) && getMatchingStart(condition, finalExpression.expression)) { return { finalExpression, occurrences: [condition], expression }; } - else if (isBinaryExpression(condition)) { + else if (ts.isBinaryExpression(condition)) { const occurrences = getOccurrencesInExpression(finalExpression.expression, condition); return occurrences ? { finalExpression, occurrences, expression } : - { error: getLocaleSpecificMessage(Diagnostics.Could_not_find_matching_access_expressions) }; + { error: ts.getLocaleSpecificMessage(ts.Diagnostics.Could_not_find_matching_access_expressions) }; } } - function getBinaryInfo(expression: BinaryExpression): OptionalChainInfo | RefactorErrorInfo | undefined { - if (expression.operatorToken.kind !== SyntaxKind.AmpersandAmpersandToken) { - return { error: getLocaleSpecificMessage(Diagnostics.Can_only_convert_logical_AND_access_chains) }; - }; + function getBinaryInfo(expression: ts.BinaryExpression): OptionalChainInfo | ts.refactor.RefactorErrorInfo | undefined { + if (expression.operatorToken.kind !== ts.SyntaxKind.AmpersandAmpersandToken) { + return { error: ts.getLocaleSpecificMessage(ts.Diagnostics.Can_only_convert_logical_AND_access_chains) }; + } + ; const finalExpression = getFinalExpressionInChain(expression.right); - if (!finalExpression) return { error: getLocaleSpecificMessage(Diagnostics.Could_not_find_convertible_access_expression) }; + if (!finalExpression) + return { error: ts.getLocaleSpecificMessage(ts.Diagnostics.Could_not_find_convertible_access_expression) }; const occurrences = getOccurrencesInExpression(finalExpression.expression, expression.left); return occurrences ? { finalExpression, occurrences, expression } : - { error: getLocaleSpecificMessage(Diagnostics.Could_not_find_matching_access_expressions) }; + { error: ts.getLocaleSpecificMessage(ts.Diagnostics.Could_not_find_matching_access_expressions) }; } /** * Gets a list of property accesses that appear in matchTo and occur in sequence in expression. */ - function getOccurrencesInExpression(matchTo: Expression, expression: Expression): Occurrence[] | undefined { + function getOccurrencesInExpression(matchTo: ts.Expression, expression: ts.Expression): Occurrence[] | undefined { const occurrences: Occurrence[] = []; - while (isBinaryExpression(expression) && expression.operatorToken.kind === SyntaxKind.AmpersandAmpersandToken) { - const match = getMatchingStart(skipParentheses(matchTo), skipParentheses(expression.right)); + while (ts.isBinaryExpression(expression) && expression.operatorToken.kind === ts.SyntaxKind.AmpersandAmpersandToken) { + const match = getMatchingStart(ts.skipParentheses(matchTo), ts.skipParentheses(expression.right)); if (!match) { break; } @@ -153,8 +155,8 @@ namespace ts.refactor.convertToOptionalChainExpression { /** * Returns subchain if chain begins with subchain syntactically. */ - function getMatchingStart(chain: Expression, subchain: Expression): PropertyAccessExpression | ElementAccessExpression | Identifier | undefined { - if (!isIdentifier(subchain) && !isPropertyAccessExpression(subchain) && !isElementAccessExpression(subchain)) { + function getMatchingStart(chain: ts.Expression, subchain: ts.Expression): ts.PropertyAccessExpression | ts.ElementAccessExpression | ts.Identifier | undefined { + if (!ts.isIdentifier(subchain) && !ts.isPropertyAccessExpression(subchain) && !ts.isElementAccessExpression(subchain)) { return undefined; } return chainStartsWith(chain, subchain) ? subchain : undefined; @@ -163,31 +165,33 @@ namespace ts.refactor.convertToOptionalChainExpression { /** * Returns true if chain begins with subchain syntactically. */ - function chainStartsWith(chain: Node, subchain: Node): boolean { + function chainStartsWith(chain: ts.Node, subchain: ts.Node): boolean { // skip until we find a matching identifier. - while (isCallExpression(chain) || isPropertyAccessExpression(chain) || isElementAccessExpression(chain)) { - if (getTextOfChainNode(chain) === getTextOfChainNode(subchain)) break; + while (ts.isCallExpression(chain) || ts.isPropertyAccessExpression(chain) || ts.isElementAccessExpression(chain)) { + if (getTextOfChainNode(chain) === getTextOfChainNode(subchain)) + break; chain = chain.expression; } // check that the chains match at each access. Call chains in subchain are not valid. - while ((isPropertyAccessExpression(chain) && isPropertyAccessExpression(subchain)) || - (isElementAccessExpression(chain) && isElementAccessExpression(subchain))) { - if (getTextOfChainNode(chain) !== getTextOfChainNode(subchain)) return false; + while ((ts.isPropertyAccessExpression(chain) && ts.isPropertyAccessExpression(subchain)) || + (ts.isElementAccessExpression(chain) && ts.isElementAccessExpression(subchain))) { + if (getTextOfChainNode(chain) !== getTextOfChainNode(subchain)) + return false; chain = chain.expression; subchain = subchain.expression; } // check if we have reached a final identifier. - return isIdentifier(chain) && isIdentifier(subchain) && chain.getText() === subchain.getText(); + return ts.isIdentifier(chain) && ts.isIdentifier(subchain) && chain.getText() === subchain.getText(); } - function getTextOfChainNode(node: Node): string | undefined { - if (isIdentifier(node) || isStringOrNumericLiteralLike(node)) { + function getTextOfChainNode(node: ts.Node): string | undefined { + if (ts.isIdentifier(node) || ts.isStringOrNumericLiteralLike(node)) { return node.getText(); } - if (isPropertyAccessExpression(node)) { + if (ts.isPropertyAccessExpression(node)) { return getTextOfChainNode(node.name); } - if (isElementAccessExpression(node)) { + if (ts.isElementAccessExpression(node)) { return getTextOfChainNode(node.argumentExpression); } return undefined; @@ -196,7 +200,7 @@ namespace ts.refactor.convertToOptionalChainExpression { /** * Find the least ancestor of the input node that is a valid type for extraction and contains the input span. */ - function getValidParentNodeContainingSpan(node: Node, span: TextSpan): ValidExpressionOrStatement | undefined { + function getValidParentNodeContainingSpan(node: ts.Node, span: ts.TextSpan): ValidExpressionOrStatement | undefined { while (node.parent) { if (isValidExpressionOrStatement(node) && span.length !== 0 && node.end >= span.start + span.length) { return node; @@ -209,7 +213,7 @@ namespace ts.refactor.convertToOptionalChainExpression { /** * Finds an ancestor of the input node that is a valid type for extraction, skipping subexpressions. */ - function getValidParentNodeOfEmptySpan(node: Node): ValidExpressionOrStatement | undefined { + function getValidParentNodeOfEmptySpan(node: ts.Node): ValidExpressionOrStatement | undefined { while (node.parent) { if (isValidExpressionOrStatement(node) && !isValidExpressionOrStatement(node.parent)) { return node; @@ -226,8 +230,8 @@ namespace ts.refactor.convertToOptionalChainExpression { if (isValidExpression(node)) { return node; } - if (isVariableStatement(node)) { - const variable = getSingleVariableOfVariableStatement(node); + if (ts.isVariableStatement(node)) { + const variable = ts.getSingleVariableOfVariableStatement(node); const initializer = variable?.initializer; return initializer && isValidExpression(initializer) ? initializer : undefined; } @@ -240,15 +244,15 @@ namespace ts.refactor.convertToOptionalChainExpression { * it is followed by a different binary operator. * @param node the right child of a binary expression or a call expression. */ - function getFinalExpressionInChain(node: Expression): CallExpression | PropertyAccessExpression | ElementAccessExpression | undefined { + function getFinalExpressionInChain(node: ts.Expression): ts.CallExpression | ts.PropertyAccessExpression | ts.ElementAccessExpression | undefined { // foo && |foo.bar === 1|; - here the right child of the && binary expression is another binary expression. // the rightmost member of the && chain should be the leftmost child of that expression. - node = skipParentheses(node); - if (isBinaryExpression(node)) { + node = ts.skipParentheses(node); + if (ts.isBinaryExpression(node)) { return getFinalExpressionInChain(node.left); } // foo && |foo.bar()()| - nested calls are treated like further accesses. - else if ((isPropertyAccessExpression(node) || isElementAccessExpression(node) || isCallExpression(node)) && !isOptionalChain(node)) { + else if ((ts.isPropertyAccessExpression(node) || ts.isElementAccessExpression(node) || ts.isCallExpression(node)) && !ts.isOptionalChain(node)) { return node; } return undefined; @@ -257,43 +261,42 @@ namespace ts.refactor.convertToOptionalChainExpression { /** * Creates an access chain from toConvert with '?.' accesses at expressions appearing in occurrences. */ - function convertOccurrences(checker: TypeChecker, toConvert: Expression, occurrences: Occurrence[]): Expression { - if (isPropertyAccessExpression(toConvert) || isElementAccessExpression(toConvert) || isCallExpression(toConvert)) { + function convertOccurrences(checker: ts.TypeChecker, toConvert: ts.Expression, occurrences: Occurrence[]): ts.Expression { + if (ts.isPropertyAccessExpression(toConvert) || ts.isElementAccessExpression(toConvert) || ts.isCallExpression(toConvert)) { const chain = convertOccurrences(checker, toConvert.expression, occurrences); const lastOccurrence = occurrences.length > 0 ? occurrences[occurrences.length - 1] : undefined; const isOccurrence = lastOccurrence?.getText() === toConvert.expression.getText(); - if (isOccurrence) occurrences.pop(); - if (isCallExpression(toConvert)) { + if (isOccurrence) + occurrences.pop(); + if (ts.isCallExpression(toConvert)) { return isOccurrence ? - factory.createCallChain(chain, factory.createToken(SyntaxKind.QuestionDotToken), toConvert.typeArguments, toConvert.arguments) : - factory.createCallChain(chain, toConvert.questionDotToken, toConvert.typeArguments, toConvert.arguments); + ts.factory.createCallChain(chain, ts.factory.createToken(ts.SyntaxKind.QuestionDotToken), toConvert.typeArguments, toConvert.arguments) : + ts.factory.createCallChain(chain, toConvert.questionDotToken, toConvert.typeArguments, toConvert.arguments); } - else if (isPropertyAccessExpression(toConvert)) { + else if (ts.isPropertyAccessExpression(toConvert)) { return isOccurrence ? - factory.createPropertyAccessChain(chain, factory.createToken(SyntaxKind.QuestionDotToken), toConvert.name) : - factory.createPropertyAccessChain(chain, toConvert.questionDotToken, toConvert.name); + ts.factory.createPropertyAccessChain(chain, ts.factory.createToken(ts.SyntaxKind.QuestionDotToken), toConvert.name) : + ts.factory.createPropertyAccessChain(chain, toConvert.questionDotToken, toConvert.name); } - else if (isElementAccessExpression(toConvert)) { + else if (ts.isElementAccessExpression(toConvert)) { return isOccurrence ? - factory.createElementAccessChain(chain, factory.createToken(SyntaxKind.QuestionDotToken), toConvert.argumentExpression) : - factory.createElementAccessChain(chain, toConvert.questionDotToken, toConvert.argumentExpression); + ts.factory.createElementAccessChain(chain, ts.factory.createToken(ts.SyntaxKind.QuestionDotToken), toConvert.argumentExpression) : + ts.factory.createElementAccessChain(chain, toConvert.questionDotToken, toConvert.argumentExpression); } } return toConvert; } - function doChange(sourceFile: SourceFile, checker: TypeChecker, changes: textChanges.ChangeTracker, info: OptionalChainInfo, _actionName: string): void { + function doChange(sourceFile: ts.SourceFile, checker: ts.TypeChecker, changes: ts.textChanges.ChangeTracker, info: OptionalChainInfo, _actionName: string): void { const { finalExpression, occurrences, expression } = info; const firstOccurrence = occurrences[occurrences.length - 1]; const convertedChain = convertOccurrences(checker, finalExpression, occurrences); - if (convertedChain && (isPropertyAccessExpression(convertedChain) || isElementAccessExpression(convertedChain) || isCallExpression(convertedChain))) { - if (isBinaryExpression(expression)) { + if (convertedChain && (ts.isPropertyAccessExpression(convertedChain) || ts.isElementAccessExpression(convertedChain) || ts.isCallExpression(convertedChain))) { + if (ts.isBinaryExpression(expression)) { changes.replaceNodeRange(sourceFile, firstOccurrence, finalExpression, convertedChain); } - else if (isConditionalExpression(expression)) { - changes.replaceNode(sourceFile, expression, - factory.createBinaryExpression(convertedChain, factory.createToken(SyntaxKind.QuestionQuestionToken), expression.whenFalse) - ); + else if (ts.isConditionalExpression(expression)) { + changes.replaceNode(sourceFile, expression, ts.factory.createBinaryExpression(convertedChain, ts.factory.createToken(ts.SyntaxKind.QuestionQuestionToken), expression.whenFalse)); } } } diff --git a/src/services/refactors/extractSymbol.ts b/src/services/refactors/extractSymbol.ts index 6e17babb6fea5..604ec8e9d4bff 100644 --- a/src/services/refactors/extractSymbol.ts +++ b/src/services/refactors/extractSymbol.ts @@ -4,15 +4,15 @@ namespace ts.refactor.extractSymbol { const extractConstantAction = { name: "Extract Constant", - description: getLocaleSpecificMessage(Diagnostics.Extract_constant), + description: ts.getLocaleSpecificMessage(ts.Diagnostics.Extract_constant), kind: "refactor.extract.constant", }; const extractFunctionAction = { name: "Extract Function", - description: getLocaleSpecificMessage(Diagnostics.Extract_function), + description: ts.getLocaleSpecificMessage(ts.Diagnostics.Extract_function), kind: "refactor.extract.function", }; - registerRefactor(refactorName, { + ts.refactor.registerRefactor(refactorName, { kinds: [ extractConstantAction.kind, extractFunctionAction.kind @@ -25,25 +25,25 @@ namespace ts.refactor.extractSymbol { * Compute the associated code actions * Exported for tests. */ - export function getRefactorActionsToExtractSymbol(context: RefactorContext): readonly ApplicableRefactorInfo[] { + export function getRefactorActionsToExtractSymbol(context: ts.RefactorContext): readonly ts.ApplicableRefactorInfo[] { const requestedRefactor = context.kind; - const rangeToExtract = getRangeToExtract(context.file, getRefactorContextSpan(context), context.triggerReason === "invoked"); + const rangeToExtract = getRangeToExtract(context.file, ts.getRefactorContextSpan(context), context.triggerReason === "invoked"); const targetRange = rangeToExtract.targetRange; if (targetRange === undefined) { if (!rangeToExtract.errors || rangeToExtract.errors.length === 0 || !context.preferences.provideRefactorNotApplicableReason) { - return emptyArray; + return ts.emptyArray; } const errors = []; - if (refactorKindBeginsWith(extractFunctionAction.kind, requestedRefactor)) { + if (ts.refactor.refactorKindBeginsWith(extractFunctionAction.kind, requestedRefactor)) { errors.push({ name: refactorName, description: extractFunctionAction.description, actions: [{ ...extractFunctionAction, notApplicableReason: getStringError(rangeToExtract.errors) }] }); } - if (refactorKindBeginsWith(extractConstantAction.kind, requestedRefactor)) { + if (ts.refactor.refactorKindBeginsWith(extractConstantAction.kind, requestedRefactor)) { errors.push({ name: refactorName, description: extractConstantAction.description, @@ -56,21 +56,19 @@ namespace ts.refactor.extractSymbol { const extractions = getPossibleExtractions(targetRange, context); if (extractions === undefined) { // No extractions possible - return emptyArray; + return ts.emptyArray; } - - const functionActions: RefactorActionInfo[] = []; - const usedFunctionNames = new Map(); - let innermostErrorFunctionAction: RefactorActionInfo | undefined; - - const constantActions: RefactorActionInfo[] = []; - const usedConstantNames = new Map(); - let innermostErrorConstantAction: RefactorActionInfo | undefined; + const functionActions: ts.RefactorActionInfo[] = []; + const usedFunctionNames = new ts.Map(); + let innermostErrorFunctionAction: ts.RefactorActionInfo | undefined; + const constantActions: ts.RefactorActionInfo[] = []; + const usedConstantNames = new ts.Map(); + let innermostErrorConstantAction: ts.RefactorActionInfo | undefined; let i = 0; for (const { functionExtraction, constantExtraction } of extractions) { const description = functionExtraction.description; - if (refactorKindBeginsWith(extractFunctionAction.kind, requestedRefactor)) { + if (ts.refactor.refactorKindBeginsWith(extractFunctionAction.kind, requestedRefactor)) { if (functionExtraction.errors.length === 0) { // Don't issue refactorings with duplicated names. // Scopes come back in "innermost first" order, so extractions will @@ -94,7 +92,7 @@ namespace ts.refactor.extractSymbol { } } - if (refactorKindBeginsWith(extractConstantAction.kind, requestedRefactor)) { + if (ts.refactor.refactorKindBeginsWith(extractConstantAction.kind, requestedRefactor)) { if (constantExtraction.errors.length === 0) { // Don't issue refactorings with duplicated names. // Scopes come back in "innermost first" order, so extractions will @@ -124,19 +122,19 @@ namespace ts.refactor.extractSymbol { i++; } - const infos: ApplicableRefactorInfo[] = []; + const infos: ts.ApplicableRefactorInfo[] = []; if (functionActions.length) { infos.push({ name: refactorName, - description: getLocaleSpecificMessage(Diagnostics.Extract_function), + description: ts.getLocaleSpecificMessage(ts.Diagnostics.Extract_function), actions: functionActions, }); } else if (context.preferences.provideRefactorNotApplicableReason && innermostErrorFunctionAction) { infos.push({ name: refactorName, - description: getLocaleSpecificMessage(Diagnostics.Extract_function), + description: ts.getLocaleSpecificMessage(ts.Diagnostics.Extract_function), actions: [ innermostErrorFunctionAction ] }); } @@ -144,21 +142,20 @@ namespace ts.refactor.extractSymbol { if (constantActions.length) { infos.push({ name: refactorName, - description: getLocaleSpecificMessage(Diagnostics.Extract_constant), + description: ts.getLocaleSpecificMessage(ts.Diagnostics.Extract_constant), actions: constantActions }); } else if (context.preferences.provideRefactorNotApplicableReason && innermostErrorConstantAction) { infos.push({ name: refactorName, - description: getLocaleSpecificMessage(Diagnostics.Extract_constant), + description: ts.getLocaleSpecificMessage(ts.Diagnostics.Extract_constant), actions: [ innermostErrorConstantAction ] }); } - return infos.length ? infos : emptyArray; - - function getStringError(errors: readonly Diagnostic[]) { + return infos.length ? infos : ts.emptyArray; + function getStringError(errors: readonly ts.Diagnostic[]) { let error = errors[0].messageText; if (typeof error !== "string") { error = error.messageText; @@ -168,45 +165,44 @@ namespace ts.refactor.extractSymbol { } /* Exported for tests */ - export function getRefactorEditsToExtractSymbol(context: RefactorContext, actionName: string): RefactorEditInfo | undefined { - const rangeToExtract = getRangeToExtract(context.file, getRefactorContextSpan(context)); + export function getRefactorEditsToExtractSymbol(context: ts.RefactorContext, actionName: string): ts.RefactorEditInfo | undefined { + const rangeToExtract = getRangeToExtract(context.file, ts.getRefactorContextSpan(context)); const targetRange = rangeToExtract.targetRange!; // TODO:GH#18217 const parsedFunctionIndexMatch = /^function_scope_(\d+)$/.exec(actionName); if (parsedFunctionIndexMatch) { const index = +parsedFunctionIndexMatch[1]; - Debug.assert(isFinite(index), "Expected to parse a finite number from the function scope index"); + ts.Debug.assert(isFinite(index), "Expected to parse a finite number from the function scope index"); return getFunctionExtractionAtIndex(targetRange, context, index); } const parsedConstantIndexMatch = /^constant_scope_(\d+)$/.exec(actionName); if (parsedConstantIndexMatch) { const index = +parsedConstantIndexMatch[1]; - Debug.assert(isFinite(index), "Expected to parse a finite number from the constant scope index"); + ts.Debug.assert(isFinite(index), "Expected to parse a finite number from the constant scope index"); return getConstantExtractionAtIndex(targetRange, context, index); } - Debug.fail("Unrecognized action name"); + ts.Debug.fail("Unrecognized action name"); } // Move these into diagnostic messages if they become user-facing export namespace Messages { - function createMessage(message: string): DiagnosticMessage { - return { message, code: 0, category: DiagnosticCategory.Message, key: message }; - } - - export const cannotExtractRange: DiagnosticMessage = createMessage("Cannot extract range."); - export const cannotExtractImport: DiagnosticMessage = createMessage("Cannot extract import statement."); - export const cannotExtractSuper: DiagnosticMessage = createMessage("Cannot extract super call."); - export const cannotExtractJSDoc: DiagnosticMessage = createMessage("Cannot extract JSDoc."); - export const cannotExtractEmpty: DiagnosticMessage = createMessage("Cannot extract empty range."); - export const expressionExpected: DiagnosticMessage = createMessage("expression expected."); - export const uselessConstantType: DiagnosticMessage = createMessage("No reason to extract constant of type."); - export const statementOrExpressionExpected: DiagnosticMessage = createMessage("Statement or expression expected."); - export const cannotExtractRangeContainingConditionalBreakOrContinueStatements: DiagnosticMessage = createMessage("Cannot extract range containing conditional break or continue statements."); - export const cannotExtractRangeContainingConditionalReturnStatement: DiagnosticMessage = createMessage("Cannot extract range containing conditional return statement."); - export const cannotExtractRangeContainingLabeledBreakOrContinueStatementWithTargetOutsideOfTheRange: DiagnosticMessage = createMessage("Cannot extract range containing labeled break or continue with target outside of the range."); - export const cannotExtractRangeThatContainsWritesToReferencesLocatedOutsideOfTheTargetRangeInGenerators: DiagnosticMessage = createMessage("Cannot extract range containing writes to references located outside of the target range in generators."); + function createMessage(message: string): ts.DiagnosticMessage { + return { message, code: 0, category: ts.DiagnosticCategory.Message, key: message }; + } + export const cannotExtractRange: ts.DiagnosticMessage = createMessage("Cannot extract range."); + export const cannotExtractImport: ts.DiagnosticMessage = createMessage("Cannot extract import statement."); + export const cannotExtractSuper: ts.DiagnosticMessage = createMessage("Cannot extract super call."); + export const cannotExtractJSDoc: ts.DiagnosticMessage = createMessage("Cannot extract JSDoc."); + export const cannotExtractEmpty: ts.DiagnosticMessage = createMessage("Cannot extract empty range."); + export const expressionExpected: ts.DiagnosticMessage = createMessage("expression expected."); + export const uselessConstantType: ts.DiagnosticMessage = createMessage("No reason to extract constant of type."); + export const statementOrExpressionExpected: ts.DiagnosticMessage = createMessage("Statement or expression expected."); + export const cannotExtractRangeContainingConditionalBreakOrContinueStatements: ts.DiagnosticMessage = createMessage("Cannot extract range containing conditional break or continue statements."); + export const cannotExtractRangeContainingConditionalReturnStatement: ts.DiagnosticMessage = createMessage("Cannot extract range containing conditional return statement."); + export const cannotExtractRangeContainingLabeledBreakOrContinueStatementWithTargetOutsideOfTheRange: ts.DiagnosticMessage = createMessage("Cannot extract range containing labeled break or continue with target outside of the range."); + export const cannotExtractRangeThatContainsWritesToReferencesLocatedOutsideOfTheTargetRangeInGenerators: ts.DiagnosticMessage = createMessage("Cannot extract range containing writes to references located outside of the target range in generators."); export const typeWillNotBeVisibleInTheNewScope = createMessage("Type will not visible in the new scope."); export const functionWillNotBeVisibleInTheNewScope = createMessage("Function will not visible in the new scope."); export const cannotExtractIdentifier = createMessage("Select more than a single identifier."); @@ -230,24 +226,24 @@ namespace ts.refactor.extractSymbol { /** * The range is in a function which needs the 'static' modifier in a class */ - InStaticRegion = 1 << 5, + InStaticRegion = 1 << 5 } /** * Represents an expression or a list of statements that should be extracted with some extra information */ interface TargetRange { - readonly range: Expression | Statement[]; + readonly range: ts.Expression | ts.Statement[]; readonly facts: RangeFacts; /** * A list of symbols that are declared in the selected range which are visible in the containing lexical scope * Used to ensure we don't turn something used outside the range free (or worse, resolve to a different entity). */ - readonly declarations: Symbol[]; + readonly declarations: ts.Symbol[]; /** * If `this` is referring to a function instead of class, we need to retrieve its type. */ - readonly thisNode: Node | undefined; + readonly thisNode: ts.Node | undefined; } /** @@ -255,7 +251,7 @@ namespace ts.refactor.extractSymbol { */ type RangeToExtract = { readonly targetRange?: never; - readonly errors: readonly Diagnostic[]; + readonly errors: readonly ts.Diagnostic[]; } | { readonly targetRange: TargetRange; readonly errors?: never; @@ -264,7 +260,7 @@ namespace ts.refactor.extractSymbol { /* * Scopes that can store newly extracted method */ - type Scope = FunctionLikeDeclaration | SourceFile | ModuleBlock | ClassLikeDeclaration; + type Scope = ts.FunctionLikeDeclaration | ts.SourceFile | ts.ModuleBlock | ts.ClassLikeDeclaration; /** * getRangeToExtract takes a span inside a text file and returns either an expression or an array @@ -273,15 +269,15 @@ namespace ts.refactor.extractSymbol { * users if they have the provideRefactorNotApplicableReason option set. */ // exported only for tests - export function getRangeToExtract(sourceFile: SourceFile, span: TextSpan, invoked = true): RangeToExtract { + export function getRangeToExtract(sourceFile: ts.SourceFile, span: ts.TextSpan, invoked = true): RangeToExtract { const { length } = span; if (length === 0 && !invoked) { - return { errors: [createFileDiagnostic(sourceFile, span.start, length, Messages.cannotExtractEmpty)] }; + return { errors: [ts.createFileDiagnostic(sourceFile, span.start, length, Messages.cannotExtractEmpty)] }; } const cursorRequest = length === 0 && invoked; - const startToken = findFirstNonJsxWhitespaceToken(sourceFile, span.start); - const endToken = findTokenOnLeftOfPosition(sourceFile, textSpanEnd(span)); + const startToken = ts.findFirstNonJsxWhitespaceToken(sourceFile, span.start); + const endToken = ts.findTokenOnLeftOfPosition(sourceFile, ts.textSpanEnd(span)); /* If the refactoring command is invoked through a keyboard action it's safe to assume that the user is actively looking for refactoring actions at the span location. As they may not know the exact range that will trigger a refactoring, we expand the searched span to cover a real node range making it more likely that something useful will show up. */ @@ -289,39 +285,38 @@ namespace ts.refactor.extractSymbol { // Walk up starting from the the start position until we find a non-SourceFile node that subsumes the selected span. // This may fail (e.g. you select two statements in the root of a source file) - const start = cursorRequest ? getExtractableParent(startToken) : getParentNodeInSpan(startToken, sourceFile, adjustedSpan); + const start = cursorRequest ? getExtractableParent(startToken) : ts.getParentNodeInSpan(startToken, sourceFile, adjustedSpan); // Do the same for the ending position - const end = cursorRequest ? start : getParentNodeInSpan(endToken, sourceFile, adjustedSpan); - - const declarations: Symbol[] = []; + const end = cursorRequest ? start : ts.getParentNodeInSpan(endToken, sourceFile, adjustedSpan); + const declarations: ts.Symbol[] = []; // We'll modify these flags as we walk the tree to collect data // about what things need to be done as part of the extraction. let rangeFacts = RangeFacts.None; - let thisNode: Node | undefined; + let thisNode: ts.Node | undefined; if (!start || !end) { // cannot find either start or end node - return { errors: [createFileDiagnostic(sourceFile, span.start, length, Messages.cannotExtractRange)] }; + return { errors: [ts.createFileDiagnostic(sourceFile, span.start, length, Messages.cannotExtractRange)] }; } - if (start.flags & NodeFlags.JSDoc) { - return { errors: [createFileDiagnostic(sourceFile, span.start, length, Messages.cannotExtractJSDoc)] }; + if (start.flags & ts.NodeFlags.JSDoc) { + return { errors: [ts.createFileDiagnostic(sourceFile, span.start, length, Messages.cannotExtractJSDoc)] }; } if (start.parent !== end.parent) { // start and end nodes belong to different subtrees - return { errors: [createFileDiagnostic(sourceFile, span.start, length, Messages.cannotExtractRange)] }; + return { errors: [ts.createFileDiagnostic(sourceFile, span.start, length, Messages.cannotExtractRange)] }; } if (start !== end) { // start and end should be statements and parent should be either block or a source file if (!isBlockLike(start.parent)) { - return { errors: [createFileDiagnostic(sourceFile, span.start, length, Messages.cannotExtractRange)] }; + return { errors: [ts.createFileDiagnostic(sourceFile, span.start, length, Messages.cannotExtractRange)] }; } - const statements: Statement[] = []; + const statements: ts.Statement[] = []; for (const statement of start.parent.statements) { if (statement === start || statements.length) { const errors = checkNode(statement); @@ -341,15 +336,15 @@ namespace ts.refactor.extractSymbol { // they will never find `start` in `start.parent.statements`. // Consider: We could support ranges like [|case 1:|] by refining them to just // the expression. - return { errors: [createFileDiagnostic(sourceFile, span.start, length, Messages.cannotExtractRange)] }; + return { errors: [ts.createFileDiagnostic(sourceFile, span.start, length, Messages.cannotExtractRange)] }; } return { targetRange: { range: statements, facts: rangeFacts, declarations, thisNode } }; } - if (isReturnStatement(start) && !start.expression) { + if (ts.isReturnStatement(start) && !start.expression) { // Makes no sense to extract an expression-less return statement. - return { errors: [createFileDiagnostic(sourceFile, span.start, length, Messages.cannotExtractRange)] }; + return { errors: [ts.createFileDiagnostic(sourceFile, span.start, length, Messages.cannotExtractRange)] }; } // We have a single node (start) @@ -365,16 +360,16 @@ namespace ts.refactor.extractSymbol { * Attempt to refine the extraction node (generally, by shrinking it) to produce better results. * @param node The unrefined extraction node. */ - function refineNode(node: Node): Node { - if (isReturnStatement(node)) { + function refineNode(node: ts.Node): ts.Node { + if (ts.isReturnStatement(node)) { if (node.expression) { return node.expression; } } - else if (isVariableStatement(node) || isVariableDeclarationList(node)) { - const declarations = isVariableStatement(node) ? node.declarationList.declarations : node.declarations; + else if (ts.isVariableStatement(node) || ts.isVariableDeclarationList(node)) { + const declarations = ts.isVariableStatement(node) ? node.declarationList.declarations : node.declarations; let numInitializers = 0; - let lastInitializer: Expression | undefined; + let lastInitializer: ts.Expression | undefined; for (const declaration of declarations) { if (declaration.initializer) { numInitializers++; @@ -386,7 +381,7 @@ namespace ts.refactor.extractSymbol { } // No special handling if there are multiple initializers. } - else if (isVariableDeclaration(node)) { + else if (ts.isVariableDeclaration(node)) { if (node.initializer) { return node.initializer; } @@ -394,31 +389,31 @@ namespace ts.refactor.extractSymbol { return node; } - function checkRootNode(node: Node): Diagnostic[] | undefined { - if (isIdentifier(isExpressionStatement(node) ? node.expression : node)) { - return [createDiagnosticForNode(node, Messages.cannotExtractIdentifier)]; + function checkRootNode(node: ts.Node): ts.Diagnostic[] | undefined { + if (ts.isIdentifier(ts.isExpressionStatement(node) ? node.expression : node)) { + return [ts.createDiagnosticForNode(node, Messages.cannotExtractIdentifier)]; } return undefined; } - function checkForStaticContext(nodeToCheck: Node, containingClass: Node) { - let current: Node = nodeToCheck; + function checkForStaticContext(nodeToCheck: ts.Node, containingClass: ts.Node) { + let current: ts.Node = nodeToCheck; while (current !== containingClass) { - if (current.kind === SyntaxKind.PropertyDeclaration) { - if (isStatic(current)) { + if (current.kind === ts.SyntaxKind.PropertyDeclaration) { + if (ts.isStatic(current)) { rangeFacts |= RangeFacts.InStaticRegion; } break; } - else if (current.kind === SyntaxKind.Parameter) { - const ctorOrMethod = getContainingFunction(current)!; - if (ctorOrMethod.kind === SyntaxKind.Constructor) { + else if (current.kind === ts.SyntaxKind.Parameter) { + const ctorOrMethod = ts.getContainingFunction(current)!; + if (ctorOrMethod.kind === ts.SyntaxKind.Constructor) { rangeFacts |= RangeFacts.InStaticRegion; } break; } - else if (current.kind === SyntaxKind.MethodDeclaration) { - if (isStatic(current)) { + else if (current.kind === ts.SyntaxKind.MethodDeclaration) { + if (ts.isStatic(current)) { rangeFacts |= RangeFacts.InStaticRegion; } } @@ -427,7 +422,7 @@ namespace ts.refactor.extractSymbol { } // Verifies whether we can actually extract this node or not. - function checkNode(nodeToCheck: Node): Diagnostic[] | undefined { + function checkNode(nodeToCheck: ts.Node): ts.Diagnostic[] | undefined { const enum PermittedJumps { None = 0, Break = 1 << 0, @@ -436,57 +431,54 @@ namespace ts.refactor.extractSymbol { } // We believe it's true because the node is from the (unmodified) tree. - Debug.assert(nodeToCheck.pos <= nodeToCheck.end, "This failure could trigger https://github.com/Microsoft/TypeScript/issues/20809 (1)"); + ts.Debug.assert(nodeToCheck.pos <= nodeToCheck.end, "This failure could trigger https://github.com/Microsoft/TypeScript/issues/20809 (1)"); // For understanding how skipTrivia functioned: - Debug.assert(!positionIsSynthesized(nodeToCheck.pos), "This failure could trigger https://github.com/Microsoft/TypeScript/issues/20809 (2)"); - - if (!isStatement(nodeToCheck) && !(isExpressionNode(nodeToCheck) && isExtractableExpression(nodeToCheck)) && !isStringLiteralJsxAttribute(nodeToCheck)) { - return [createDiagnosticForNode(nodeToCheck, Messages.statementOrExpressionExpected)]; + ts.Debug.assert(!ts.positionIsSynthesized(nodeToCheck.pos), "This failure could trigger https://github.com/Microsoft/TypeScript/issues/20809 (2)"); + if (!ts.isStatement(nodeToCheck) && !(ts.isExpressionNode(nodeToCheck) && isExtractableExpression(nodeToCheck)) && !isStringLiteralJsxAttribute(nodeToCheck)) { + return [ts.createDiagnosticForNode(nodeToCheck, Messages.statementOrExpressionExpected)]; } - if (nodeToCheck.flags & NodeFlags.Ambient) { - return [createDiagnosticForNode(nodeToCheck, Messages.cannotExtractAmbientBlock)]; + if (nodeToCheck.flags & ts.NodeFlags.Ambient) { + return [ts.createDiagnosticForNode(nodeToCheck, Messages.cannotExtractAmbientBlock)]; } // If we're in a class, see whether we're in a static region (static property initializer, static method, class constructor parameter default) - const containingClass = getContainingClass(nodeToCheck); + const containingClass = ts.getContainingClass(nodeToCheck); if (containingClass) { checkForStaticContext(nodeToCheck, containingClass); } - let errors: Diagnostic[] | undefined; + let errors: ts.Diagnostic[] | undefined; let permittedJumps = PermittedJumps.Return; - let seenLabels: __String[]; + let seenLabels: ts.__String[]; visit(nodeToCheck); if (rangeFacts & RangeFacts.UsesThis) { - const container = getThisContainer(nodeToCheck, /** includeArrowFunctions */ false); - if ( - container.kind === SyntaxKind.FunctionDeclaration || - (container.kind === SyntaxKind.MethodDeclaration && container.parent.kind === SyntaxKind.ObjectLiteralExpression) || - container.kind === SyntaxKind.FunctionExpression - ) { + const container = ts.getThisContainer(nodeToCheck, /** includeArrowFunctions */ false); + if (container.kind === ts.SyntaxKind.FunctionDeclaration || + (container.kind === ts.SyntaxKind.MethodDeclaration && container.parent.kind === ts.SyntaxKind.ObjectLiteralExpression) || + container.kind === ts.SyntaxKind.FunctionExpression) { rangeFacts |= RangeFacts.UsesThisInFunction; } } return errors; - function visit(node: Node) { + function visit(node: ts.Node) { if (errors) { // already found an error - can stop now return true; } - if (isDeclaration(node)) { - const declaringNode = (node.kind === SyntaxKind.VariableDeclaration) ? node.parent.parent : node; - if (hasSyntacticModifier(declaringNode, ModifierFlags.Export)) { + if (ts.isDeclaration(node)) { + const declaringNode = (node.kind === ts.SyntaxKind.VariableDeclaration) ? node.parent.parent : node; + if (ts.hasSyntacticModifier(declaringNode, ts.ModifierFlags.Export)) { // TODO: GH#18217 Silly to use `errors ||` since it's definitely not defined (see top of `visit`) // Also, if we're only pushing one error, just use `let error: Diagnostic | undefined`! // Also TODO: GH#19956 - (errors ||= []).push(createDiagnosticForNode(node, Messages.cannotExtractExportedEntity)); + (errors ||= []).push(ts.createDiagnosticForNode(node, Messages.cannotExtractExportedEntity)); return true; } declarations.push(node.symbol); @@ -494,20 +486,20 @@ namespace ts.refactor.extractSymbol { // Some things can't be extracted in certain situations switch (node.kind) { - case SyntaxKind.ImportDeclaration: - (errors ||= []).push(createDiagnosticForNode(node, Messages.cannotExtractImport)); + case ts.SyntaxKind.ImportDeclaration: + (errors ||= []).push(ts.createDiagnosticForNode(node, Messages.cannotExtractImport)); return true; - case SyntaxKind.ExportAssignment: - (errors ||= []).push(createDiagnosticForNode(node, Messages.cannotExtractExportedEntity)); + case ts.SyntaxKind.ExportAssignment: + (errors ||= []).push(ts.createDiagnosticForNode(node, Messages.cannotExtractExportedEntity)); return true; - case SyntaxKind.SuperKeyword: + case ts.SyntaxKind.SuperKeyword: // For a super *constructor call*, we have to be extracting the entire class, // but a super *method call* simply implies a 'this' reference - if (node.parent.kind === SyntaxKind.CallExpression) { + if (node.parent.kind === ts.SyntaxKind.CallExpression) { // Super constructor call - const containingClass = getContainingClass(node); + const containingClass = ts.getContainingClass(node); if (containingClass === undefined || containingClass.pos < span.start || containingClass.end >= (span.start + span.length)) { - (errors ||= []).push(createDiagnosticForNode(node, Messages.cannotExtractSuper)); + (errors ||= []).push(ts.createDiagnosticForNode(node, Messages.cannotExtractSuper)); return true; } } @@ -516,60 +508,60 @@ namespace ts.refactor.extractSymbol { thisNode = node; } break; - case SyntaxKind.ArrowFunction: + case ts.SyntaxKind.ArrowFunction: // check if arrow function uses this - forEachChild(node, function check(n) { - if (isThis(n)) { + ts.forEachChild(node, function check(n) { + if (ts.isThis(n)) { rangeFacts |= RangeFacts.UsesThis; thisNode = node; } - else if (isClassLike(n) || (isFunctionLike(n) && !isArrowFunction(n))) { + else if (ts.isClassLike(n) || (ts.isFunctionLike(n) && !ts.isArrowFunction(n))) { return false; } else { - forEachChild(n, check); + ts.forEachChild(n, check); } }); // falls through - case SyntaxKind.ClassDeclaration: - case SyntaxKind.FunctionDeclaration: - if (isSourceFile(node.parent) && node.parent.externalModuleIndicator === undefined) { + case ts.SyntaxKind.ClassDeclaration: + case ts.SyntaxKind.FunctionDeclaration: + if (ts.isSourceFile(node.parent) && node.parent.externalModuleIndicator === undefined) { // You cannot extract global declarations - (errors ||= []).push(createDiagnosticForNode(node, Messages.functionWillNotBeVisibleInTheNewScope)); + (errors ||= []).push(ts.createDiagnosticForNode(node, Messages.functionWillNotBeVisibleInTheNewScope)); } // falls through - case SyntaxKind.ClassExpression: - case SyntaxKind.FunctionExpression: - case SyntaxKind.MethodDeclaration: - case SyntaxKind.Constructor: - case SyntaxKind.GetAccessor: - case SyntaxKind.SetAccessor: + case ts.SyntaxKind.ClassExpression: + case ts.SyntaxKind.FunctionExpression: + case ts.SyntaxKind.MethodDeclaration: + case ts.SyntaxKind.Constructor: + case ts.SyntaxKind.GetAccessor: + case ts.SyntaxKind.SetAccessor: // do not dive into functions or classes return false; } const savedPermittedJumps = permittedJumps; switch (node.kind) { - case SyntaxKind.IfStatement: + case ts.SyntaxKind.IfStatement: permittedJumps = PermittedJumps.None; break; - case SyntaxKind.TryStatement: + case ts.SyntaxKind.TryStatement: // forbid all jumps inside try blocks permittedJumps = PermittedJumps.None; break; - case SyntaxKind.Block: - if (node.parent && node.parent.kind === SyntaxKind.TryStatement && (node.parent as TryStatement).finallyBlock === node) { + case ts.SyntaxKind.Block: + if (node.parent && node.parent.kind === ts.SyntaxKind.TryStatement && (node.parent as ts.TryStatement).finallyBlock === node) { // allow unconditional returns from finally blocks permittedJumps = PermittedJumps.Return; } break; - case SyntaxKind.DefaultClause: - case SyntaxKind.CaseClause: + case ts.SyntaxKind.DefaultClause: + case ts.SyntaxKind.CaseClause: // allow unlabeled break inside case clauses permittedJumps |= PermittedJumps.Break; break; default: - if (isIterationStatement(node, /*lookInLabeledStatements*/ false)) { + if (ts.isIterationStatement(node, /*lookInLabeledStatements*/ false)) { // allow unlabeled break/continue inside loops permittedJumps |= PermittedJumps.Break | PermittedJumps.Continue; } @@ -577,51 +569,51 @@ namespace ts.refactor.extractSymbol { } switch (node.kind) { - case SyntaxKind.ThisType: - case SyntaxKind.ThisKeyword: + case ts.SyntaxKind.ThisType: + case ts.SyntaxKind.ThisKeyword: rangeFacts |= RangeFacts.UsesThis; thisNode = node; break; - case SyntaxKind.LabeledStatement: { - const label = (node as LabeledStatement).label; + case ts.SyntaxKind.LabeledStatement: { + const label = (node as ts.LabeledStatement).label; (seenLabels || (seenLabels = [])).push(label.escapedText); - forEachChild(node, visit); + ts.forEachChild(node, visit); seenLabels.pop(); break; } - case SyntaxKind.BreakStatement: - case SyntaxKind.ContinueStatement: { - const label = (node as BreakStatement | ContinueStatement).label; + case ts.SyntaxKind.BreakStatement: + case ts.SyntaxKind.ContinueStatement: { + const label = (node as ts.BreakStatement | ts.ContinueStatement).label; if (label) { - if (!contains(seenLabels, label.escapedText)) { + if (!ts.contains(seenLabels, label.escapedText)) { // attempts to jump to label that is not in range to be extracted - (errors ||= []).push(createDiagnosticForNode(node, Messages.cannotExtractRangeContainingLabeledBreakOrContinueStatementWithTargetOutsideOfTheRange)); + (errors ||= []).push(ts.createDiagnosticForNode(node, Messages.cannotExtractRangeContainingLabeledBreakOrContinueStatementWithTargetOutsideOfTheRange)); } } else { - if (!(permittedJumps & (node.kind === SyntaxKind.BreakStatement ? PermittedJumps.Break : PermittedJumps.Continue))) { + if (!(permittedJumps & (node.kind === ts.SyntaxKind.BreakStatement ? PermittedJumps.Break : PermittedJumps.Continue))) { // attempt to break or continue in a forbidden context - (errors ||= []).push(createDiagnosticForNode(node, Messages.cannotExtractRangeContainingConditionalBreakOrContinueStatements)); + (errors ||= []).push(ts.createDiagnosticForNode(node, Messages.cannotExtractRangeContainingConditionalBreakOrContinueStatements)); } } break; } - case SyntaxKind.AwaitExpression: + case ts.SyntaxKind.AwaitExpression: rangeFacts |= RangeFacts.IsAsyncFunction; break; - case SyntaxKind.YieldExpression: + case ts.SyntaxKind.YieldExpression: rangeFacts |= RangeFacts.IsGenerator; break; - case SyntaxKind.ReturnStatement: + case ts.SyntaxKind.ReturnStatement: if (permittedJumps & PermittedJumps.Return) { rangeFacts |= RangeFacts.HasReturn; } else { - (errors ||= []).push(createDiagnosticForNode(node, Messages.cannotExtractRangeContainingConditionalReturnStatement)); + (errors ||= []).push(ts.createDiagnosticForNode(node, Messages.cannotExtractRangeContainingConditionalReturnStatement)); } break; default: - forEachChild(node, visit); + ts.forEachChild(node, visit); break; } @@ -634,25 +626,25 @@ namespace ts.refactor.extractSymbol { * Includes the final semicolon so that the span covers statements in cases where it would otherwise * only cover the declaration list. */ - function getAdjustedSpanFromNodes(startNode: Node, endNode: Node, sourceFile: SourceFile): TextSpan { + function getAdjustedSpanFromNodes(startNode: ts.Node, endNode: ts.Node, sourceFile: ts.SourceFile): ts.TextSpan { const start = startNode.getStart(sourceFile); let end = endNode.getEnd(); - if (sourceFile.text.charCodeAt(end) === CharacterCodes.semicolon) { + if (sourceFile.text.charCodeAt(end) === ts.CharacterCodes.semicolon) { end++; } return { start, length: end - start }; } - function getStatementOrExpressionRange(node: Node): Statement[] | Expression | undefined { - if (isStatement(node)) { + function getStatementOrExpressionRange(node: ts.Node): ts.Statement[] | ts.Expression | undefined { + if (ts.isStatement(node)) { return [node]; } - if (isExpressionNode(node)) { + if (ts.isExpressionNode(node)) { // If our selection is the expression in an ExpressionStatement, expand // the selection to include the enclosing Statement (this stops us // from trying to care about the return value of the extracted function // and eliminates double semicolon insertion in certain scenarios) - return isExpressionStatement(node.parent) ? [node.parent] : node as Expression; + return ts.isExpressionStatement(node.parent) ? [node.parent] : node as ts.Expression; } if (isStringLiteralJsxAttribute(node)) { return node; @@ -660,9 +652,9 @@ namespace ts.refactor.extractSymbol { return undefined; } - function isScope(node: Node): node is Scope { - return isArrowFunction(node) ? isFunctionBody(node.body) : - isFunctionLikeDeclaration(node) || isSourceFile(node) || isModuleBlock(node) || isClassLike(node); + function isScope(node: ts.Node): node is Scope { + return ts.isArrowFunction(node) ? ts.isFunctionBody(node.body) : + ts.isFunctionLikeDeclaration(node) || ts.isSourceFile(node) || ts.isModuleBlock(node) || ts.isClassLike(node); } /** @@ -671,12 +663,12 @@ namespace ts.refactor.extractSymbol { * depending on what's in the extracted body. */ function collectEnclosingScopes(range: TargetRange): Scope[] { - let current: Node = isReadonlyArray(range.range) ? first(range.range) : range.range; + let current: ts.Node = isReadonlyArray(range.range) ? ts.first(range.range) : range.range; if (range.facts & RangeFacts.UsesThis && !(range.facts & RangeFacts.UsesThisInFunction)) { // if range uses this as keyword or as type inside the class then it can only be extracted to a method of the containing class - const containingClass = getContainingClass(current); + const containingClass = ts.getContainingClass(current); if (containingClass) { - const containingFunction = findAncestor(current, isFunctionLikeDeclaration); + const containingFunction = ts.findAncestor(current, ts.isFunctionLikeDeclaration); return containingFunction ? [containingFunction, containingClass] : [containingClass]; @@ -687,9 +679,9 @@ namespace ts.refactor.extractSymbol { while (true) { current = current.parent; // A function parameter's initializer is actually in the outer scope, not the function declaration - if (current.kind === SyntaxKind.Parameter) { + if (current.kind === ts.SyntaxKind.Parameter) { // Skip all the way to the outer scope of the function that declared this parameter - current = findAncestor(current, parent => isFunctionLikeDeclaration(parent))!.parent; + current = ts.findAncestor(current, parent => ts.isFunctionLikeDeclaration(parent))!.parent; } // We want to find the nearest parent where we can place an "equivalent" sibling to the node we're extracting out of. @@ -699,34 +691,34 @@ namespace ts.refactor.extractSymbol { // * Module/namespace or source file if (isScope(current)) { scopes.push(current); - if (current.kind === SyntaxKind.SourceFile) { + if (current.kind === ts.SyntaxKind.SourceFile) { return scopes; } } } } - function getFunctionExtractionAtIndex(targetRange: TargetRange, context: RefactorContext, requestedChangesIndex: number): RefactorEditInfo { + function getFunctionExtractionAtIndex(targetRange: TargetRange, context: ts.RefactorContext, requestedChangesIndex: number): ts.RefactorEditInfo { const { scopes, readsAndWrites: { target, usagesPerScope, functionErrorsPerScope, exposedVariableDeclarations } } = getPossibleExtractionsWorker(targetRange, context); - Debug.assert(!functionErrorsPerScope[requestedChangesIndex].length, "The extraction went missing? How?"); + ts.Debug.assert(!functionErrorsPerScope[requestedChangesIndex].length, "The extraction went missing? How?"); context.cancellationToken!.throwIfCancellationRequested(); // TODO: GH#18217 return extractFunctionInScope(target, scopes[requestedChangesIndex], usagesPerScope[requestedChangesIndex], exposedVariableDeclarations, targetRange, context); } - function getConstantExtractionAtIndex(targetRange: TargetRange, context: RefactorContext, requestedChangesIndex: number): RefactorEditInfo { + function getConstantExtractionAtIndex(targetRange: TargetRange, context: ts.RefactorContext, requestedChangesIndex: number): ts.RefactorEditInfo { const { scopes, readsAndWrites: { target, usagesPerScope, constantErrorsPerScope, exposedVariableDeclarations } } = getPossibleExtractionsWorker(targetRange, context); - Debug.assert(!constantErrorsPerScope[requestedChangesIndex].length, "The extraction went missing? How?"); - Debug.assert(exposedVariableDeclarations.length === 0, "Extract constant accepted a range containing a variable declaration?"); + ts.Debug.assert(!constantErrorsPerScope[requestedChangesIndex].length, "The extraction went missing? How?"); + ts.Debug.assert(exposedVariableDeclarations.length === 0, "Extract constant accepted a range containing a variable declaration?"); context.cancellationToken!.throwIfCancellationRequested(); - const expression = isExpression(target) + const expression = ts.isExpression(target) ? target - : (target.statements[0] as ExpressionStatement).expression; + : (target.statements[0] as ts.ExpressionStatement).expression; return extractConstantInScope(expression, scopes[requestedChangesIndex], usagesPerScope[requestedChangesIndex], targetRange.facts, context); } interface Extraction { readonly description: string; - readonly errors: readonly Diagnostic[]; + readonly errors: readonly ts.Diagnostic[]; } interface ScopeExtractions { @@ -739,37 +731,37 @@ namespace ts.refactor.extractSymbol { * Each returned ExtractResultForScope corresponds to a possible target scope and is either a set of changes * or an error explaining why we can't extract into that scope. */ - function getPossibleExtractions(targetRange: TargetRange, context: RefactorContext): readonly ScopeExtractions[] | undefined { + function getPossibleExtractions(targetRange: TargetRange, context: ts.RefactorContext): readonly ScopeExtractions[] | undefined { const { scopes, readsAndWrites: { functionErrorsPerScope, constantErrorsPerScope } } = getPossibleExtractionsWorker(targetRange, context); // Need the inner type annotation to avoid https://github.com/Microsoft/TypeScript/issues/7547 const extractions = scopes.map((scope, i): ScopeExtractions => { const functionDescriptionPart = getDescriptionForFunctionInScope(scope); const constantDescriptionPart = getDescriptionForConstantInScope(scope); - const scopeDescription = isFunctionLikeDeclaration(scope) + const scopeDescription = ts.isFunctionLikeDeclaration(scope) ? getDescriptionForFunctionLikeDeclaration(scope) - : isClassLike(scope) + : ts.isClassLike(scope) ? getDescriptionForClassLikeDeclaration(scope) : getDescriptionForModuleLikeDeclaration(scope); let functionDescription: string; let constantDescription: string; if (scopeDescription === SpecialScope.Global) { - functionDescription = formatStringFromArgs(getLocaleSpecificMessage(Diagnostics.Extract_to_0_in_1_scope), [functionDescriptionPart, "global"]); - constantDescription = formatStringFromArgs(getLocaleSpecificMessage(Diagnostics.Extract_to_0_in_1_scope), [constantDescriptionPart, "global"]); + functionDescription = ts.formatStringFromArgs(ts.getLocaleSpecificMessage(ts.Diagnostics.Extract_to_0_in_1_scope), [functionDescriptionPart, "global"]); + constantDescription = ts.formatStringFromArgs(ts.getLocaleSpecificMessage(ts.Diagnostics.Extract_to_0_in_1_scope), [constantDescriptionPart, "global"]); } else if (scopeDescription === SpecialScope.Module) { - functionDescription = formatStringFromArgs(getLocaleSpecificMessage(Diagnostics.Extract_to_0_in_1_scope), [functionDescriptionPart, "module"]); - constantDescription = formatStringFromArgs(getLocaleSpecificMessage(Diagnostics.Extract_to_0_in_1_scope), [constantDescriptionPart, "module"]); + functionDescription = ts.formatStringFromArgs(ts.getLocaleSpecificMessage(ts.Diagnostics.Extract_to_0_in_1_scope), [functionDescriptionPart, "module"]); + constantDescription = ts.formatStringFromArgs(ts.getLocaleSpecificMessage(ts.Diagnostics.Extract_to_0_in_1_scope), [constantDescriptionPart, "module"]); } else { - functionDescription = formatStringFromArgs(getLocaleSpecificMessage(Diagnostics.Extract_to_0_in_1), [functionDescriptionPart, scopeDescription]); - constantDescription = formatStringFromArgs(getLocaleSpecificMessage(Diagnostics.Extract_to_0_in_1), [constantDescriptionPart, scopeDescription]); + functionDescription = ts.formatStringFromArgs(ts.getLocaleSpecificMessage(ts.Diagnostics.Extract_to_0_in_1), [functionDescriptionPart, scopeDescription]); + constantDescription = ts.formatStringFromArgs(ts.getLocaleSpecificMessage(ts.Diagnostics.Extract_to_0_in_1), [constantDescriptionPart, scopeDescription]); } // Customize the phrasing for the innermost scope to increase clarity. - if (i === 0 && !isClassLike(scope)) { - constantDescription = formatStringFromArgs(getLocaleSpecificMessage(Diagnostics.Extract_to_0_in_enclosing_scope), [constantDescriptionPart]); + if (i === 0 && !ts.isClassLike(scope)) { + constantDescription = ts.formatStringFromArgs(ts.getLocaleSpecificMessage(ts.Diagnostics.Extract_to_0_in_enclosing_scope), [constantDescriptionPart]); } return { @@ -786,201 +778,162 @@ namespace ts.refactor.extractSymbol { return extractions; } - function getPossibleExtractionsWorker(targetRange: TargetRange, context: RefactorContext): { readonly scopes: Scope[], readonly readsAndWrites: ReadsAndWrites } { + function getPossibleExtractionsWorker(targetRange: TargetRange, context: ts.RefactorContext): { + readonly scopes: Scope[]; + readonly readsAndWrites: ReadsAndWrites; + } { const { file: sourceFile } = context; const scopes = collectEnclosingScopes(targetRange); const enclosingTextRange = getEnclosingTextRange(targetRange, sourceFile); - const readsAndWrites = collectReadsAndWrites( - targetRange, - scopes, - enclosingTextRange, - sourceFile, - context.program.getTypeChecker(), - context.cancellationToken!); + const readsAndWrites = collectReadsAndWrites(targetRange, scopes, enclosingTextRange, sourceFile, context.program.getTypeChecker(), context.cancellationToken!); return { scopes, readsAndWrites }; } function getDescriptionForFunctionInScope(scope: Scope): string { - return isFunctionLikeDeclaration(scope) + return ts.isFunctionLikeDeclaration(scope) ? "inner function" - : isClassLike(scope) + : ts.isClassLike(scope) ? "method" : "function"; } function getDescriptionForConstantInScope(scope: Scope): string { - return isClassLike(scope) + return ts.isClassLike(scope) ? "readonly field" : "constant"; } - function getDescriptionForFunctionLikeDeclaration(scope: FunctionLikeDeclaration): string { + function getDescriptionForFunctionLikeDeclaration(scope: ts.FunctionLikeDeclaration): string { switch (scope.kind) { - case SyntaxKind.Constructor: + case ts.SyntaxKind.Constructor: return "constructor"; - case SyntaxKind.FunctionExpression: - case SyntaxKind.FunctionDeclaration: + case ts.SyntaxKind.FunctionExpression: + case ts.SyntaxKind.FunctionDeclaration: return scope.name ? `function '${scope.name.text}'` - : ANONYMOUS; - case SyntaxKind.ArrowFunction: + : ts.ANONYMOUS; + case ts.SyntaxKind.ArrowFunction: return "arrow function"; - case SyntaxKind.MethodDeclaration: + case ts.SyntaxKind.MethodDeclaration: return `method '${scope.name.getText()}'`; - case SyntaxKind.GetAccessor: + case ts.SyntaxKind.GetAccessor: return `'get ${scope.name.getText()}'`; - case SyntaxKind.SetAccessor: + case ts.SyntaxKind.SetAccessor: return `'set ${scope.name.getText()}'`; default: - throw Debug.assertNever(scope, `Unexpected scope kind ${(scope as FunctionLikeDeclaration).kind}`); + throw ts.Debug.assertNever(scope, `Unexpected scope kind ${(scope as ts.FunctionLikeDeclaration).kind}`); } } - function getDescriptionForClassLikeDeclaration(scope: ClassLikeDeclaration): string { - return scope.kind === SyntaxKind.ClassDeclaration + function getDescriptionForClassLikeDeclaration(scope: ts.ClassLikeDeclaration): string { + return scope.kind === ts.SyntaxKind.ClassDeclaration ? scope.name ? `class '${scope.name.text}'` : "anonymous class declaration" : scope.name ? `class expression '${scope.name.text}'` : "anonymous class expression"; } - function getDescriptionForModuleLikeDeclaration(scope: SourceFile | ModuleBlock): string | SpecialScope { - return scope.kind === SyntaxKind.ModuleBlock + function getDescriptionForModuleLikeDeclaration(scope: ts.SourceFile | ts.ModuleBlock): string | SpecialScope { + return scope.kind === ts.SyntaxKind.ModuleBlock ? `namespace '${scope.parent.name.getText()}'` : scope.externalModuleIndicator ? SpecialScope.Module : SpecialScope.Global; } const enum SpecialScope { Module, - Global, + Global } /** * Result of 'extractRange' operation for a specific scope. * Stores either a list of changes that should be applied to extract a range or a list of errors */ - function extractFunctionInScope( - node: Statement | Expression | Block, - scope: Scope, - { usages: usagesInScope, typeParameterUsages, substitutions }: ScopeUsages, - exposedVariableDeclarations: readonly VariableDeclaration[], - range: TargetRange, - context: RefactorContext): RefactorEditInfo { + function extractFunctionInScope(node: ts.Statement | ts.Expression | ts.Block, scope: Scope, { usages: usagesInScope, typeParameterUsages, substitutions }: ScopeUsages, exposedVariableDeclarations: readonly ts.VariableDeclaration[], range: TargetRange, context: ts.RefactorContext): ts.RefactorEditInfo { const checker = context.program.getTypeChecker(); - const scriptTarget = getEmitScriptTarget(context.program.getCompilerOptions()); - const importAdder = codefix.createImportAdder(context.file, context.program, context.preferences, context.host); + const scriptTarget = ts.getEmitScriptTarget(context.program.getCompilerOptions()); + const importAdder = ts.codefix.createImportAdder(context.file, context.program, context.preferences, context.host); // Make a unique name for the extracted function const file = scope.getSourceFile(); - const functionNameText = getUniqueName(isClassLike(scope) ? "newMethod" : "newFunction", file); - const isJS = isInJSFile(scope); - - const functionName = factory.createIdentifier(functionNameText); - - let returnType: TypeNode | undefined; - const parameters: ParameterDeclaration[] = []; - const callArguments: Identifier[] = []; + const functionNameText = ts.getUniqueName(ts.isClassLike(scope) ? "newMethod" : "newFunction", file); + const isJS = ts.isInJSFile(scope); + const functionName = ts.factory.createIdentifier(functionNameText); + let returnType: ts.TypeNode | undefined; + const parameters: ts.ParameterDeclaration[] = []; + const callArguments: ts.Identifier[] = []; let writes: UsageEntry[] | undefined; usagesInScope.forEach((usage, name) => { - let typeNode: TypeNode | undefined; + let typeNode: ts.TypeNode | undefined; if (!isJS) { let type = checker.getTypeOfSymbolAtLocation(usage.symbol, usage.node); // Widen the type so we don't emit nonsense annotations like "function fn(x: 3) {" type = checker.getBaseTypeOfLiteralType(type); - typeNode = codefix.typeToAutoImportableTypeNode(checker, importAdder, type, scope, scriptTarget, NodeBuilderFlags.NoTruncation); + typeNode = ts.codefix.typeToAutoImportableTypeNode(checker, importAdder, type, scope, scriptTarget, ts.NodeBuilderFlags.NoTruncation); } - const paramDecl = factory.createParameterDeclaration( + const paramDecl = ts.factory.createParameterDeclaration( /*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, /*name*/ name, - /*questionToken*/ undefined, - typeNode - ); + /*questionToken*/ undefined, typeNode); parameters.push(paramDecl); if (usage.usage === Usage.Write) { (writes || (writes = [])).push(usage); } - callArguments.push(factory.createIdentifier(name)); + callArguments.push(ts.factory.createIdentifier(name)); }); - const typeParametersAndDeclarations = arrayFrom(typeParameterUsages.values()).map(type => ({ type, declaration: getFirstDeclaration(type) })); + const typeParametersAndDeclarations = ts.arrayFrom(typeParameterUsages.values()).map(type => ({ type, declaration: getFirstDeclaration(type) })); const sortedTypeParametersAndDeclarations = typeParametersAndDeclarations.sort(compareTypesByDeclarationOrder); - const typeParameters: readonly TypeParameterDeclaration[] | undefined = sortedTypeParametersAndDeclarations.length === 0 + const typeParameters: readonly ts.TypeParameterDeclaration[] | undefined = sortedTypeParametersAndDeclarations.length === 0 ? undefined - : sortedTypeParametersAndDeclarations.map(t => t.declaration as TypeParameterDeclaration); + : sortedTypeParametersAndDeclarations.map(t => t.declaration as ts.TypeParameterDeclaration); // Strictly speaking, we should check whether each name actually binds to the appropriate type // parameter. In cases of shadowing, they may not. - const callTypeArguments: readonly TypeNode[] | undefined = typeParameters !== undefined - ? typeParameters.map(decl => factory.createTypeReferenceNode(decl.name, /*typeArguments*/ undefined)) + const callTypeArguments: readonly ts.TypeNode[] | undefined = typeParameters !== undefined + ? typeParameters.map(decl => ts.factory.createTypeReferenceNode(decl.name, /*typeArguments*/ undefined)) : undefined; // Provide explicit return types for contextually-typed functions // to avoid problems when there are literal types present - if (isExpression(node) && !isJS) { + if (ts.isExpression(node) && !isJS) { const contextualType = checker.getContextualType(node); - returnType = checker.typeToTypeNode(contextualType!, scope, NodeBuilderFlags.NoTruncation); // TODO: GH#18217 + returnType = checker.typeToTypeNode(contextualType!, scope, ts.NodeBuilderFlags.NoTruncation); // TODO: GH#18217 } const { body, returnValueProperty } = transformFunctionBody(node, exposedVariableDeclarations, writes, substitutions, !!(range.facts & RangeFacts.HasReturn)); - suppressLeadingAndTrailingTrivia(body); - - let newFunction: MethodDeclaration | FunctionDeclaration; + ts.suppressLeadingAndTrailingTrivia(body); + let newFunction: ts.MethodDeclaration | ts.FunctionDeclaration; const callThis = !!(range.facts & RangeFacts.UsesThisInFunction); - if (isClassLike(scope)) { + if (ts.isClassLike(scope)) { // always create private method in TypeScript files - const modifiers: Modifier[] = isJS ? [] : [factory.createModifier(SyntaxKind.PrivateKeyword)]; + const modifiers: ts.Modifier[] = isJS ? [] : [ts.factory.createModifier(ts.SyntaxKind.PrivateKeyword)]; if (range.facts & RangeFacts.InStaticRegion) { - modifiers.push(factory.createModifier(SyntaxKind.StaticKeyword)); + modifiers.push(ts.factory.createModifier(ts.SyntaxKind.StaticKeyword)); } if (range.facts & RangeFacts.IsAsyncFunction) { - modifiers.push(factory.createModifier(SyntaxKind.AsyncKeyword)); + modifiers.push(ts.factory.createModifier(ts.SyntaxKind.AsyncKeyword)); } - newFunction = factory.createMethodDeclaration( - /*decorators*/ undefined, - modifiers.length ? modifiers : undefined, - range.facts & RangeFacts.IsGenerator ? factory.createToken(SyntaxKind.AsteriskToken) : undefined, - functionName, - /*questionToken*/ undefined, - typeParameters, - parameters, - returnType, - body - ); + newFunction = ts.factory.createMethodDeclaration( + /*decorators*/ undefined, modifiers.length ? modifiers : undefined, range.facts & RangeFacts.IsGenerator ? ts.factory.createToken(ts.SyntaxKind.AsteriskToken) : undefined, functionName, + /*questionToken*/ undefined, typeParameters, parameters, returnType, body); } else { if (callThis) { - parameters.unshift( - factory.createParameterDeclaration( + parameters.unshift(ts.factory.createParameterDeclaration( /*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, /*name*/ "this", - /*questionToken*/ undefined, - checker.typeToTypeNode( - checker.getTypeAtLocation(range.thisNode!), - scope, - NodeBuilderFlags.NoTruncation - ), - /*initializer*/ undefined, - ) - ); - } - newFunction = factory.createFunctionDeclaration( - /*decorators*/ undefined, - range.facts & RangeFacts.IsAsyncFunction ? [factory.createToken(SyntaxKind.AsyncKeyword)] : undefined, - range.facts & RangeFacts.IsGenerator ? factory.createToken(SyntaxKind.AsteriskToken) : undefined, - functionName, - typeParameters, - parameters, - returnType, - body - ); - } - - const changeTracker = textChanges.ChangeTracker.fromContext(context); - const minInsertionPos = (isReadonlyArray(range.range) ? last(range.range) : range.range).end; + /*questionToken*/ undefined, checker.typeToTypeNode(checker.getTypeAtLocation(range.thisNode!), scope, ts.NodeBuilderFlags.NoTruncation), + /*initializer*/ undefined)); + } + newFunction = ts.factory.createFunctionDeclaration( + /*decorators*/ undefined, range.facts & RangeFacts.IsAsyncFunction ? [ts.factory.createToken(ts.SyntaxKind.AsyncKeyword)] : undefined, range.facts & RangeFacts.IsGenerator ? ts.factory.createToken(ts.SyntaxKind.AsteriskToken) : undefined, functionName, typeParameters, parameters, returnType, body); + } + const changeTracker = ts.textChanges.ChangeTracker.fromContext(context); + const minInsertionPos = (isReadonlyArray(range.range) ? ts.last(range.range) : range.range).end; const nodeToInsertBefore = getNodeToInsertFunctionBefore(minInsertionPos, scope); if (nodeToInsertBefore) { changeTracker.insertNodeBefore(context.file, nodeToInsertBefore, newFunction, /*blankLineBetween*/ true); @@ -990,67 +943,55 @@ namespace ts.refactor.extractSymbol { } importAdder.writeFixes(changeTracker); - const newNodes: Node[] = []; + const newNodes: ts.Node[] = []; // replace range with function call const called = getCalledExpression(scope, range, functionNameText); if (callThis) { - callArguments.unshift(factory.createIdentifier("this")); + callArguments.unshift(ts.factory.createIdentifier("this")); } - - let call: Expression = factory.createCallExpression( - callThis ? factory.createPropertyAccessExpression( - called, - "call" - ) : called, - callTypeArguments, // Note that no attempt is made to take advantage of type argument inference + let call: ts.Expression = ts.factory.createCallExpression(callThis ? ts.factory.createPropertyAccessExpression(called, "call") : called, callTypeArguments, // Note that no attempt is made to take advantage of type argument inference callArguments); if (range.facts & RangeFacts.IsGenerator) { - call = factory.createYieldExpression(factory.createToken(SyntaxKind.AsteriskToken), call); + call = ts.factory.createYieldExpression(ts.factory.createToken(ts.SyntaxKind.AsteriskToken), call); } if (range.facts & RangeFacts.IsAsyncFunction) { - call = factory.createAwaitExpression(call); + call = ts.factory.createAwaitExpression(call); } if (isInJSXContent(node)) { - call = factory.createJsxExpression(/*dotDotDotToken*/ undefined, call); + call = ts.factory.createJsxExpression(/*dotDotDotToken*/ undefined, call); } if (exposedVariableDeclarations.length && !writes) { // No need to mix declarations and writes. // How could any variables be exposed if there's a return statement? - Debug.assert(!returnValueProperty, "Expected no returnValueProperty"); - Debug.assert(!(range.facts & RangeFacts.HasReturn), "Expected RangeFacts.HasReturn flag to be unset"); + ts.Debug.assert(!returnValueProperty, "Expected no returnValueProperty"); + ts.Debug.assert(!(range.facts & RangeFacts.HasReturn), "Expected RangeFacts.HasReturn flag to be unset"); if (exposedVariableDeclarations.length === 1) { // Declaring exactly one variable: let x = newFunction(); const variableDeclaration = exposedVariableDeclarations[0]; - newNodes.push(factory.createVariableStatement( - /*modifiers*/ undefined, - factory.createVariableDeclarationList( - [factory.createVariableDeclaration(getSynthesizedDeepClone(variableDeclaration.name), /*exclamationToken*/ undefined, /*type*/ getSynthesizedDeepClone(variableDeclaration.type), /*initializer*/ call)], // TODO (acasey): test binding patterns + newNodes.push(ts.factory.createVariableStatement( + /*modifiers*/ undefined, ts.factory.createVariableDeclarationList([ts.factory.createVariableDeclaration(ts.getSynthesizedDeepClone(variableDeclaration.name), /*exclamationToken*/ undefined, /*type*/ ts.getSynthesizedDeepClone(variableDeclaration.type), /*initializer*/ call)], // TODO (acasey): test binding patterns variableDeclaration.parent.flags))); } else { // Declaring multiple variables / return properties: // let {x, y} = newFunction(); - const bindingElements: BindingElement[] = []; - const typeElements: TypeElement[] = []; + const bindingElements: ts.BindingElement[] = []; + const typeElements: ts.TypeElement[] = []; let commonNodeFlags = exposedVariableDeclarations[0].parent.flags; let sawExplicitType = false; for (const variableDeclaration of exposedVariableDeclarations) { - bindingElements.push(factory.createBindingElement( + bindingElements.push(ts.factory.createBindingElement( /*dotDotDotToken*/ undefined, /*propertyName*/ undefined, - /*name*/ getSynthesizedDeepClone(variableDeclaration.name))); + /*name*/ ts.getSynthesizedDeepClone(variableDeclaration.name))); // Being returned through an object literal will have widened the type. - const variableType: TypeNode | undefined = checker.typeToTypeNode( - checker.getBaseTypeOfLiteralType(checker.getTypeAtLocation(variableDeclaration)), - scope, - NodeBuilderFlags.NoTruncation); - - typeElements.push(factory.createPropertySignature( + const variableType: ts.TypeNode | undefined = checker.typeToTypeNode(checker.getBaseTypeOfLiteralType(checker.getTypeAtLocation(variableDeclaration)), scope, ts.NodeBuilderFlags.NoTruncation); + typeElements.push(ts.factory.createPropertySignature( /*modifiers*/ undefined, /*name*/ variableDeclaration.symbol.name, /*questionToken*/ undefined, @@ -1059,81 +1000,70 @@ namespace ts.refactor.extractSymbol { commonNodeFlags = commonNodeFlags & variableDeclaration.parent.flags; } - const typeLiteral: TypeLiteralNode | undefined = sawExplicitType ? factory.createTypeLiteralNode(typeElements) : undefined; + const typeLiteral: ts.TypeLiteralNode | undefined = sawExplicitType ? ts.factory.createTypeLiteralNode(typeElements) : undefined; if (typeLiteral) { - setEmitFlags(typeLiteral, EmitFlags.SingleLine); + ts.setEmitFlags(typeLiteral, ts.EmitFlags.SingleLine); } - newNodes.push(factory.createVariableStatement( - /*modifiers*/ undefined, - factory.createVariableDeclarationList( - [factory.createVariableDeclaration( - factory.createObjectBindingPattern(bindingElements), + newNodes.push(ts.factory.createVariableStatement( + /*modifiers*/ undefined, ts.factory.createVariableDeclarationList([ts.factory.createVariableDeclaration(ts.factory.createObjectBindingPattern(bindingElements), /*exclamationToken*/ undefined, /*type*/ typeLiteral, - /*initializer*/call)], - commonNodeFlags))); + /*initializer*/ call)], commonNodeFlags))); } } else if (exposedVariableDeclarations.length || writes) { if (exposedVariableDeclarations.length) { // CONSIDER: we're going to create one statement per variable, but we could actually preserve their original grouping. for (const variableDeclaration of exposedVariableDeclarations) { - let flags: NodeFlags = variableDeclaration.parent.flags; - if (flags & NodeFlags.Const) { - flags = (flags & ~NodeFlags.Const) | NodeFlags.Let; + let flags: ts.NodeFlags = variableDeclaration.parent.flags; + if (flags & ts.NodeFlags.Const) { + flags = (flags & ~ts.NodeFlags.Const) | ts.NodeFlags.Let; } - newNodes.push(factory.createVariableStatement( - /*modifiers*/ undefined, - factory.createVariableDeclarationList( - [factory.createVariableDeclaration(variableDeclaration.symbol.name, /*exclamationToken*/ undefined, getTypeDeepCloneUnionUndefined(variableDeclaration.type))], - flags))); + newNodes.push(ts.factory.createVariableStatement( + /*modifiers*/ undefined, ts.factory.createVariableDeclarationList([ts.factory.createVariableDeclaration(variableDeclaration.symbol.name, /*exclamationToken*/ undefined, getTypeDeepCloneUnionUndefined(variableDeclaration.type))], flags))); } } if (returnValueProperty) { // has both writes and return, need to create variable declaration to hold return value; - newNodes.push(factory.createVariableStatement( - /*modifiers*/ undefined, - factory.createVariableDeclarationList( - [factory.createVariableDeclaration(returnValueProperty, /*exclamationToken*/ undefined, getTypeDeepCloneUnionUndefined(returnType))], - NodeFlags.Let))); + newNodes.push(ts.factory.createVariableStatement( + /*modifiers*/ undefined, ts.factory.createVariableDeclarationList([ts.factory.createVariableDeclaration(returnValueProperty, /*exclamationToken*/ undefined, getTypeDeepCloneUnionUndefined(returnType))], ts.NodeFlags.Let))); } const assignments = getPropertyAssignmentsForWritesAndVariableDeclarations(exposedVariableDeclarations, writes); if (returnValueProperty) { - assignments.unshift(factory.createShorthandPropertyAssignment(returnValueProperty)); + assignments.unshift(ts.factory.createShorthandPropertyAssignment(returnValueProperty)); } // propagate writes back if (assignments.length === 1) { // We would only have introduced a return value property if there had been // other assignments to make. - Debug.assert(!returnValueProperty, "Shouldn't have returnValueProperty here"); - - newNodes.push(factory.createExpressionStatement(factory.createAssignment(assignments[0].name, call))); + ts.Debug.assert(!returnValueProperty, "Shouldn't have returnValueProperty here"); + newNodes.push(ts.factory.createExpressionStatement(ts.factory.createAssignment(assignments[0].name, call))); if (range.facts & RangeFacts.HasReturn) { - newNodes.push(factory.createReturnStatement()); + newNodes.push(ts.factory.createReturnStatement()); } } else { // emit e.g. // { a, b, __return } = newFunction(a, b); // return __return; - newNodes.push(factory.createExpressionStatement(factory.createAssignment(factory.createObjectLiteralExpression(assignments), call))); + newNodes.push(ts.factory.createExpressionStatement(ts.factory.createAssignment(ts.factory.createObjectLiteralExpression(assignments), call))); if (returnValueProperty) { - newNodes.push(factory.createReturnStatement(factory.createIdentifier(returnValueProperty))); + newNodes.push(ts.factory.createReturnStatement(ts.factory.createIdentifier(returnValueProperty))); } } } else { if (range.facts & RangeFacts.HasReturn) { - newNodes.push(factory.createReturnStatement(call)); + newNodes.push(ts.factory.createReturnStatement(call)); } else if (isReadonlyArray(range.range)) { - newNodes.push(factory.createExpressionStatement(call)); + newNodes.push(ts.factory.createExpressionStatement(call)); } else { newNodes.push(call); @@ -1141,32 +1071,32 @@ namespace ts.refactor.extractSymbol { } if (isReadonlyArray(range.range)) { - changeTracker.replaceNodeRangeWithNodes(context.file, first(range.range), last(range.range), newNodes); + changeTracker.replaceNodeRangeWithNodes(context.file, ts.first(range.range), ts.last(range.range), newNodes); } else { changeTracker.replaceNodeWithNodes(context.file, range.range, newNodes); } const edits = changeTracker.getChanges(); - const renameRange = isReadonlyArray(range.range) ? first(range.range) : range.range; + const renameRange = isReadonlyArray(range.range) ? ts.first(range.range) : range.range; const renameFilename = renameRange.getSourceFile().fileName; - const renameLocation = getRenameLocation(edits, renameFilename, functionNameText, /*isDeclaredBeforeUse*/ false); + const renameLocation = ts.getRenameLocation(edits, renameFilename, functionNameText, /*isDeclaredBeforeUse*/ false); return { renameFilename, renameLocation, edits }; - function getTypeDeepCloneUnionUndefined(typeNode: TypeNode | undefined): TypeNode | undefined { + function getTypeDeepCloneUnionUndefined(typeNode: ts.TypeNode | undefined): ts.TypeNode | undefined { if (typeNode === undefined) { return undefined; } - const clone = getSynthesizedDeepClone(typeNode); + const clone = ts.getSynthesizedDeepClone(typeNode); let withoutParens = clone; - while (isParenthesizedTypeNode(withoutParens)) { + while (ts.isParenthesizedTypeNode(withoutParens)) { withoutParens = withoutParens.type; } - return isUnionTypeNode(withoutParens) && find(withoutParens.types, t => t.kind === SyntaxKind.UndefinedKeyword) + return ts.isUnionTypeNode(withoutParens) && ts.find(withoutParens.types, t => t.kind === ts.SyntaxKind.UndefinedKeyword) ? clone - : factory.createUnionTypeNode([clone, factory.createKeywordTypeNode(SyntaxKind.UndefinedKeyword)]); + : ts.factory.createUnionTypeNode([clone, ts.factory.createKeywordTypeNode(ts.SyntaxKind.UndefinedKeyword)]); } } @@ -1174,59 +1104,43 @@ namespace ts.refactor.extractSymbol { * Result of 'extractRange' operation for a specific scope. * Stores either a list of changes that should be applied to extract a range or a list of errors */ - function extractConstantInScope( - node: Expression, - scope: Scope, - { substitutions }: ScopeUsages, - rangeFacts: RangeFacts, - context: RefactorContext): RefactorEditInfo { + function extractConstantInScope(node: ts.Expression, scope: Scope, { substitutions }: ScopeUsages, rangeFacts: RangeFacts, context: ts.RefactorContext): ts.RefactorEditInfo { const checker = context.program.getTypeChecker(); // Make a unique name for the extracted variable const file = scope.getSourceFile(); - const localNameText = isPropertyAccessExpression(node) && !isClassLike(scope) && !checker.resolveName(node.name.text, node, SymbolFlags.Value, /*excludeGlobals*/ false) && !isPrivateIdentifier(node.name) && !isKeyword(node.name.originalKeywordKind!) + const localNameText = ts.isPropertyAccessExpression(node) && !ts.isClassLike(scope) && !checker.resolveName(node.name.text, node, ts.SymbolFlags.Value, /*excludeGlobals*/ false) && !ts.isPrivateIdentifier(node.name) && !ts.isKeyword(node.name.originalKeywordKind!) ? node.name.text - : getUniqueName(isClassLike(scope) ? "newProperty" : "newLocal", file); - const isJS = isInJSFile(scope); + : ts.getUniqueName(ts.isClassLike(scope) ? "newProperty" : "newLocal", file); + const isJS = ts.isInJSFile(scope); let variableType = isJS || !checker.isContextSensitive(node) ? undefined - : checker.typeToTypeNode(checker.getContextualType(node)!, scope, NodeBuilderFlags.NoTruncation); // TODO: GH#18217 - - let initializer = transformConstantInitializer(skipParentheses(node), substitutions); + : checker.typeToTypeNode(checker.getContextualType(node)!, scope, ts.NodeBuilderFlags.NoTruncation); // TODO: GH#18217 + let initializer = transformConstantInitializer(ts.skipParentheses(node), substitutions); ({ variableType, initializer } = transformFunctionInitializerAndType(variableType, initializer)); - suppressLeadingAndTrailingTrivia(initializer); - - const changeTracker = textChanges.ChangeTracker.fromContext(context); - - if (isClassLike(scope)) { - Debug.assert(!isJS, "Cannot extract to a JS class"); // See CannotExtractToJSClass - const modifiers: Modifier[] = []; - modifiers.push(factory.createModifier(SyntaxKind.PrivateKeyword)); + ts.suppressLeadingAndTrailingTrivia(initializer); + const changeTracker = ts.textChanges.ChangeTracker.fromContext(context); + if (ts.isClassLike(scope)) { + ts.Debug.assert(!isJS, "Cannot extract to a JS class"); // See CannotExtractToJSClass + const modifiers: ts.Modifier[] = []; + modifiers.push(ts.factory.createModifier(ts.SyntaxKind.PrivateKeyword)); if (rangeFacts & RangeFacts.InStaticRegion) { - modifiers.push(factory.createModifier(SyntaxKind.StaticKeyword)); + modifiers.push(ts.factory.createModifier(ts.SyntaxKind.StaticKeyword)); } - modifiers.push(factory.createModifier(SyntaxKind.ReadonlyKeyword)); - - const newVariable = factory.createPropertyDeclaration( - /*decorators*/ undefined, - modifiers, - localNameText, - /*questionToken*/ undefined, - variableType, - initializer); - - let localReference: Expression = factory.createPropertyAccessExpression( - rangeFacts & RangeFacts.InStaticRegion - ? factory.createIdentifier(scope.name!.getText()) // TODO: GH#18217 - : factory.createThis(), - factory.createIdentifier(localNameText)); + modifiers.push(ts.factory.createModifier(ts.SyntaxKind.ReadonlyKeyword)); + const newVariable = ts.factory.createPropertyDeclaration( + /*decorators*/ undefined, modifiers, localNameText, + /*questionToken*/ undefined, variableType, initializer); + let localReference: ts.Expression = ts.factory.createPropertyAccessExpression(rangeFacts & RangeFacts.InStaticRegion + ? ts.factory.createIdentifier(scope.name!.getText()) // TODO: GH#18217 + : ts.factory.createThis(), ts.factory.createIdentifier(localNameText)); if (isInJSXContent(node)) { - localReference = factory.createJsxExpression(/*dotDotDotToken*/ undefined, localReference); + localReference = ts.factory.createJsxExpression(/*dotDotDotToken*/ undefined, localReference); } // Declare @@ -1238,7 +1152,7 @@ namespace ts.refactor.extractSymbol { changeTracker.replaceNode(context.file, node, localReference); } else { - const newVariableDeclaration = factory.createVariableDeclaration(localNameText, /*exclamationToken*/ undefined, variableType, initializer); + const newVariableDeclaration = ts.factory.createVariableDeclaration(localNameText, /*exclamationToken*/ undefined, variableType, initializer); // If the node is part of an initializer in a list of variable declarations, insert a new // variable declaration into the list (in case it depends on earlier ones). @@ -1251,21 +1165,19 @@ namespace ts.refactor.extractSymbol { changeTracker.insertNodeBefore(context.file, oldVariableDeclaration, newVariableDeclaration); // Consume - const localReference = factory.createIdentifier(localNameText); + const localReference = ts.factory.createIdentifier(localNameText); changeTracker.replaceNode(context.file, node, localReference); } - else if (node.parent.kind === SyntaxKind.ExpressionStatement && scope === findAncestor(node, isScope)) { + else if (node.parent.kind === ts.SyntaxKind.ExpressionStatement && scope === ts.findAncestor(node, isScope)) { // If the parent is an expression statement and the target scope is the immediately enclosing one, // replace the statement with the declaration. - const newVariableStatement = factory.createVariableStatement( - /*modifiers*/ undefined, - factory.createVariableDeclarationList([newVariableDeclaration], NodeFlags.Const)); + const newVariableStatement = ts.factory.createVariableStatement( + /*modifiers*/ undefined, ts.factory.createVariableDeclarationList([newVariableDeclaration], ts.NodeFlags.Const)); changeTracker.replaceNode(context.file, node.parent, newVariableStatement); } else { - const newVariableStatement = factory.createVariableStatement( - /*modifiers*/ undefined, - factory.createVariableDeclarationList([newVariableDeclaration], NodeFlags.Const)); + const newVariableStatement = ts.factory.createVariableStatement( + /*modifiers*/ undefined, ts.factory.createVariableDeclarationList([newVariableDeclaration], ts.NodeFlags.Const)); // Declare const nodeToInsertBefore = getNodeToInsertConstantBefore(node, scope); @@ -1277,16 +1189,16 @@ namespace ts.refactor.extractSymbol { } // Consume - if (node.parent.kind === SyntaxKind.ExpressionStatement) { + if (node.parent.kind === ts.SyntaxKind.ExpressionStatement) { // If the parent is an expression statement, delete it. changeTracker.delete(context.file, node.parent); } else { - let localReference: Expression = factory.createIdentifier(localNameText); + let localReference: ts.Expression = ts.factory.createIdentifier(localNameText); // When extract to a new variable in JSX content, need to wrap a {} out of the new variable // or it will become a plain text if (isInJSXContent(node)) { - localReference = factory.createJsxExpression(/*dotDotDotToken*/ undefined, localReference); + localReference = ts.factory.createJsxExpression(/*dotDotDotToken*/ undefined, localReference); } changeTracker.replaceNode(context.file, node, localReference); } @@ -1296,24 +1208,31 @@ namespace ts.refactor.extractSymbol { const edits = changeTracker.getChanges(); const renameFilename = node.getSourceFile().fileName; - const renameLocation = getRenameLocation(edits, renameFilename, localNameText, /*isDeclaredBeforeUse*/ true); + const renameLocation = ts.getRenameLocation(edits, renameFilename, localNameText, /*isDeclaredBeforeUse*/ true); return { renameFilename, renameLocation, edits }; - function transformFunctionInitializerAndType(variableType: TypeNode | undefined, initializer: Expression): { variableType: TypeNode | undefined, initializer: Expression } { + function transformFunctionInitializerAndType(variableType: ts.TypeNode | undefined, initializer: ts.Expression): { + variableType: ts.TypeNode | undefined; + initializer: ts.Expression; + } { // If no contextual type exists there is nothing to transfer to the function signature - if (variableType === undefined) return { variableType, initializer }; + if (variableType === undefined) + return { variableType, initializer }; // Only do this for function expressions and arrow functions that are not generic - if (!isFunctionExpression(initializer) && !isArrowFunction(initializer) || !!initializer.typeParameters) return { variableType, initializer }; + if (!ts.isFunctionExpression(initializer) && !ts.isArrowFunction(initializer) || !!initializer.typeParameters) + return { variableType, initializer }; const functionType = checker.getTypeAtLocation(node); - const functionSignature = singleOrUndefined(checker.getSignaturesOfType(functionType, SignatureKind.Call)); + const functionSignature = ts.singleOrUndefined(checker.getSignaturesOfType(functionType, ts.SignatureKind.Call)); // If no function signature, maybe there was an error, do nothing - if (!functionSignature) return { variableType, initializer }; + if (!functionSignature) + return { variableType, initializer }; // If the function signature has generic type parameters we don't attempt to move the parameters - if (!!functionSignature.getTypeParameters()) return { variableType, initializer }; + if (!!functionSignature.getTypeParameters()) + return { variableType, initializer }; // We add parameter types if needed - const parameters: ParameterDeclaration[] = []; + const parameters: ts.ParameterDeclaration[] = []; let hasAny = false; for (const p of initializer.parameters) { if (p.type) { @@ -1321,58 +1240,46 @@ namespace ts.refactor.extractSymbol { } else { const paramType = checker.getTypeAtLocation(p); - if (paramType === checker.getAnyType()) hasAny = true; - - parameters.push(factory.updateParameterDeclaration(p, - p.decorators, p.modifiers, p.dotDotDotToken, - p.name, p.questionToken, p.type || checker.typeToTypeNode(paramType, scope, NodeBuilderFlags.NoTruncation), p.initializer)); + if (paramType === checker.getAnyType()) + hasAny = true; + parameters.push(ts.factory.updateParameterDeclaration(p, p.decorators, p.modifiers, p.dotDotDotToken, p.name, p.questionToken, p.type || checker.typeToTypeNode(paramType, scope, ts.NodeBuilderFlags.NoTruncation), p.initializer)); } } // If a parameter was inferred as any we skip adding function parameters at all. // Turning an implicit any (which under common settings is a error) to an explicit // is probably actually a worse refactor outcome. - if (hasAny) return { variableType, initializer }; + if (hasAny) + return { variableType, initializer }; variableType = undefined; - if (isArrowFunction(initializer)) { - initializer = factory.updateArrowFunction(initializer, node.modifiers, initializer.typeParameters, - parameters, - initializer.type || checker.typeToTypeNode(functionSignature.getReturnType(), scope, NodeBuilderFlags.NoTruncation), - initializer.equalsGreaterThanToken, - initializer.body); + if (ts.isArrowFunction(initializer)) { + initializer = ts.factory.updateArrowFunction(initializer, node.modifiers, initializer.typeParameters, parameters, initializer.type || checker.typeToTypeNode(functionSignature.getReturnType(), scope, ts.NodeBuilderFlags.NoTruncation), initializer.equalsGreaterThanToken, initializer.body); } else { if (functionSignature && !!functionSignature.thisParameter) { - const firstParameter = firstOrUndefined(parameters); + const firstParameter = ts.firstOrUndefined(parameters); // If the function signature has a this parameter and if the first defined parameter is not the this parameter, we must add it // Note: If this parameter was already there, it would have been previously updated with the type if not type was present - if ((!firstParameter || (isIdentifier(firstParameter.name) && firstParameter.name.escapedText !== "this"))) { + if ((!firstParameter || (ts.isIdentifier(firstParameter.name) && firstParameter.name.escapedText !== "this"))) { const thisType = checker.getTypeOfSymbolAtLocation(functionSignature.thisParameter, node); - parameters.splice(0, 0, factory.createParameterDeclaration( + parameters.splice(0, 0, ts.factory.createParameterDeclaration( /* decorators */ undefined, /* modifiers */ undefined, - /* dotDotDotToken */ undefined, - "this", - /* questionToken */ undefined, - checker.typeToTypeNode(thisType, scope, NodeBuilderFlags.NoTruncation) - )); + /* dotDotDotToken */ undefined, "this", + /* questionToken */ undefined, checker.typeToTypeNode(thisType, scope, ts.NodeBuilderFlags.NoTruncation))); } } - initializer = factory.updateFunctionExpression(initializer, node.modifiers, initializer.asteriskToken, - initializer.name, initializer.typeParameters, - parameters, - initializer.type || checker.typeToTypeNode(functionSignature.getReturnType(), scope, NodeBuilderFlags.NoTruncation), - initializer.body); + initializer = ts.factory.updateFunctionExpression(initializer, node.modifiers, initializer.asteriskToken, initializer.name, initializer.typeParameters, parameters, initializer.type || checker.typeToTypeNode(functionSignature.getReturnType(), scope, ts.NodeBuilderFlags.NoTruncation), initializer.body); } return { variableType, initializer }; } } - function getContainingVariableDeclarationIfInList(node: Node, scope: Scope) { + function getContainingVariableDeclarationIfInList(node: ts.Node, scope: Scope) { let prevNode; while (node !== undefined && node !== scope) { - if (isVariableDeclaration(node) && + if (ts.isVariableDeclaration(node) && node.initializer === prevNode && - isVariableDeclarationList(node.parent) && + ts.isVariableDeclarationList(node.parent) && node.parent.declarations.length > 1) { return node; @@ -1383,7 +1290,7 @@ namespace ts.refactor.extractSymbol { } } - function getFirstDeclaration(type: Type): Declaration | undefined { + function getFirstDeclaration(type: ts.Type): ts.Declaration | undefined { let firstDeclaration; const symbol = type.symbol; @@ -1398,135 +1305,136 @@ namespace ts.refactor.extractSymbol { return firstDeclaration; } - function compareTypesByDeclarationOrder( - { type: type1, declaration: declaration1 }: { type: Type, declaration?: Declaration }, - { type: type2, declaration: declaration2 }: { type: Type, declaration?: Declaration }) { - - return compareProperties(declaration1, declaration2, "pos", compareValues) - || compareStringsCaseSensitive( - type1.symbol ? type1.symbol.getName() : "", - type2.symbol ? type2.symbol.getName() : "") - || compareValues(type1.id, type2.id); + function compareTypesByDeclarationOrder({ type: type1, declaration: declaration1 }: { + type: ts.Type; + declaration?: ts.Declaration; + }, { type: type2, declaration: declaration2 }: { + type: ts.Type; + declaration?: ts.Declaration; + }) { + return ts.compareProperties(declaration1, declaration2, "pos", ts.compareValues) + || ts.compareStringsCaseSensitive(type1.symbol ? type1.symbol.getName() : "", type2.symbol ? type2.symbol.getName() : "") + || ts.compareValues(type1.id, type2.id); } - - function getCalledExpression(scope: Node, range: TargetRange, functionNameText: string): Expression { - const functionReference = factory.createIdentifier(functionNameText); - if (isClassLike(scope)) { - const lhs = range.facts & RangeFacts.InStaticRegion ? factory.createIdentifier(scope.name!.text) : factory.createThis(); // TODO: GH#18217 - return factory.createPropertyAccessExpression(lhs, functionReference); + function getCalledExpression(scope: ts.Node, range: TargetRange, functionNameText: string): ts.Expression { + const functionReference = ts.factory.createIdentifier(functionNameText); + if (ts.isClassLike(scope)) { + const lhs = range.facts & RangeFacts.InStaticRegion ? ts.factory.createIdentifier(scope.name!.text) : ts.factory.createThis(); // TODO: GH#18217 + return ts.factory.createPropertyAccessExpression(lhs, functionReference); } else { return functionReference; } } - function transformFunctionBody(body: Node, exposedVariableDeclarations: readonly VariableDeclaration[], writes: readonly UsageEntry[] | undefined, substitutions: ReadonlyESMap, hasReturn: boolean): { body: Block, returnValueProperty: string | undefined } { + function transformFunctionBody(body: ts.Node, exposedVariableDeclarations: readonly ts.VariableDeclaration[], writes: readonly UsageEntry[] | undefined, substitutions: ts.ReadonlyESMap, hasReturn: boolean): { + body: ts.Block; + returnValueProperty: string | undefined; + } { const hasWritesOrVariableDeclarations = writes !== undefined || exposedVariableDeclarations.length > 0; - if (isBlock(body) && !hasWritesOrVariableDeclarations && substitutions.size === 0) { + if (ts.isBlock(body) && !hasWritesOrVariableDeclarations && substitutions.size === 0) { // already block, no declarations or writes to propagate back, no substitutions - can use node as is - return { body: factory.createBlock(body.statements, /*multLine*/ true), returnValueProperty: undefined }; + return { body: ts.factory.createBlock(body.statements, /*multLine*/ true), returnValueProperty: undefined }; } let returnValueProperty: string | undefined; let ignoreReturns = false; - const statements = factory.createNodeArray(isBlock(body) ? body.statements.slice(0) : [isStatement(body) ? body : factory.createReturnStatement(skipParentheses(body as Expression))]); + const statements = ts.factory.createNodeArray(ts.isBlock(body) ? body.statements.slice(0) : [ts.isStatement(body) ? body : ts.factory.createReturnStatement(ts.skipParentheses(body as ts.Expression))]); // rewrite body if either there are writes that should be propagated back via return statements or there are substitutions if (hasWritesOrVariableDeclarations || substitutions.size) { - const rewrittenStatements = visitNodes(statements, visitor).slice(); - if (hasWritesOrVariableDeclarations && !hasReturn && isStatement(body)) { + const rewrittenStatements = ts.visitNodes(statements, visitor).slice(); + if (hasWritesOrVariableDeclarations && !hasReturn && ts.isStatement(body)) { // add return at the end to propagate writes back in case if control flow falls out of the function body // it is ok to know that range has at least one return since it we only allow unconditional returns const assignments = getPropertyAssignmentsForWritesAndVariableDeclarations(exposedVariableDeclarations, writes); if (assignments.length === 1) { - rewrittenStatements.push(factory.createReturnStatement(assignments[0].name)); + rewrittenStatements.push(ts.factory.createReturnStatement(assignments[0].name)); } else { - rewrittenStatements.push(factory.createReturnStatement(factory.createObjectLiteralExpression(assignments))); + rewrittenStatements.push(ts.factory.createReturnStatement(ts.factory.createObjectLiteralExpression(assignments))); } } - return { body: factory.createBlock(rewrittenStatements, /*multiLine*/ true), returnValueProperty }; + return { body: ts.factory.createBlock(rewrittenStatements, /*multiLine*/ true), returnValueProperty }; } else { - return { body: factory.createBlock(statements, /*multiLine*/ true), returnValueProperty: undefined }; + return { body: ts.factory.createBlock(statements, /*multiLine*/ true), returnValueProperty: undefined }; } - function visitor(node: Node): VisitResult { - if (!ignoreReturns && isReturnStatement(node) && hasWritesOrVariableDeclarations) { - const assignments: ObjectLiteralElementLike[] = getPropertyAssignmentsForWritesAndVariableDeclarations(exposedVariableDeclarations, writes); + function visitor(node: ts.Node): ts.VisitResult { + if (!ignoreReturns && ts.isReturnStatement(node) && hasWritesOrVariableDeclarations) { + const assignments: ts.ObjectLiteralElementLike[] = getPropertyAssignmentsForWritesAndVariableDeclarations(exposedVariableDeclarations, writes); if (node.expression) { if (!returnValueProperty) { returnValueProperty = "__return"; } - assignments.unshift(factory.createPropertyAssignment(returnValueProperty, visitNode(node.expression, visitor))); + assignments.unshift(ts.factory.createPropertyAssignment(returnValueProperty, ts.visitNode(node.expression, visitor))); } if (assignments.length === 1) { - return factory.createReturnStatement(assignments[0].name as Expression); + return ts.factory.createReturnStatement(assignments[0].name as ts.Expression); } else { - return factory.createReturnStatement(factory.createObjectLiteralExpression(assignments)); + return ts.factory.createReturnStatement(ts.factory.createObjectLiteralExpression(assignments)); } } else { const oldIgnoreReturns = ignoreReturns; - ignoreReturns = ignoreReturns || isFunctionLikeDeclaration(node) || isClassLike(node); - const substitution = substitutions.get(getNodeId(node).toString()); - const result = substitution ? getSynthesizedDeepClone(substitution) : visitEachChild(node, visitor, nullTransformationContext); + ignoreReturns = ignoreReturns || ts.isFunctionLikeDeclaration(node) || ts.isClassLike(node); + const substitution = substitutions.get(ts.getNodeId(node).toString()); + const result = substitution ? ts.getSynthesizedDeepClone(substitution) : ts.visitEachChild(node, visitor, ts.nullTransformationContext); ignoreReturns = oldIgnoreReturns; return result; } } } - function transformConstantInitializer(initializer: Expression, substitutions: ReadonlyESMap): Expression { + function transformConstantInitializer(initializer: ts.Expression, substitutions: ts.ReadonlyESMap): ts.Expression { return substitutions.size - ? visitor(initializer) as Expression + ? visitor(initializer) as ts.Expression : initializer; - function visitor(node: Node): VisitResult { - const substitution = substitutions.get(getNodeId(node).toString()); - return substitution ? getSynthesizedDeepClone(substitution) : visitEachChild(node, visitor, nullTransformationContext); + function visitor(node: ts.Node): ts.VisitResult { + const substitution = substitutions.get(ts.getNodeId(node).toString()); + return substitution ? ts.getSynthesizedDeepClone(substitution) : ts.visitEachChild(node, visitor, ts.nullTransformationContext); } } - function getStatementsOrClassElements(scope: Scope): readonly Statement[] | readonly ClassElement[] { - if (isFunctionLikeDeclaration(scope)) { + function getStatementsOrClassElements(scope: Scope): readonly ts.Statement[] | readonly ts.ClassElement[] { + if (ts.isFunctionLikeDeclaration(scope)) { const body = scope.body!; // TODO: GH#18217 - if (isBlock(body)) { + if (ts.isBlock(body)) { return body.statements; } } - else if (isModuleBlock(scope) || isSourceFile(scope)) { + else if (ts.isModuleBlock(scope) || ts.isSourceFile(scope)) { return scope.statements; } - else if (isClassLike(scope)) { + else if (ts.isClassLike(scope)) { return scope.members; } else { - assertType(scope); + ts.assertType(scope); } - return emptyArray; + return ts.emptyArray; } /** * If `scope` contains a function after `minPos`, then return the first such function. * Otherwise, return `undefined`. */ - function getNodeToInsertFunctionBefore(minPos: number, scope: Scope): Statement | ClassElement | undefined { - return find(getStatementsOrClassElements(scope), child => - child.pos >= minPos && isFunctionLikeDeclaration(child) && !isConstructorDeclaration(child)); + function getNodeToInsertFunctionBefore(minPos: number, scope: Scope): ts.Statement | ts.ClassElement | undefined { + return ts.find(getStatementsOrClassElements(scope), child => child.pos >= minPos && ts.isFunctionLikeDeclaration(child) && !ts.isConstructorDeclaration(child)); } - function getNodeToInsertPropertyBefore(maxPos: number, scope: ClassLikeDeclaration): ClassElement { + function getNodeToInsertPropertyBefore(maxPos: number, scope: ts.ClassLikeDeclaration): ts.ClassElement { const members = scope.members; - Debug.assert(members.length > 0, "Found no members"); // There must be at least one child, since we extracted from one. - - let prevMember: ClassElement | undefined; + ts.Debug.assert(members.length > 0, "Found no members"); // There must be at least one child, since we extracted from one. + let prevMember: ts.ClassElement | undefined; let allProperties = true; for (const member of members) { if (member.pos > maxPos) { return prevMember || members[0]; } - if (allProperties && !isPropertyDeclaration(member)) { + if (allProperties && !ts.isPropertyDeclaration(member)) { // If it is non-vacuously true that all preceding members are properties, // insert before the current member (i.e. at the end of the list of properties). if (prevMember !== undefined) { @@ -1538,12 +1446,13 @@ namespace ts.refactor.extractSymbol { prevMember = member; } - if (prevMember === undefined) return Debug.fail(); // If the loop didn't return, then it did set prevMember. + if (prevMember === undefined) + return ts.Debug.fail(); // If the loop didn't return, then it did set prevMember. return prevMember; } - function getNodeToInsertConstantBefore(node: Node, scope: Scope): Statement { - Debug.assert(!isClassLike(scope)); + function getNodeToInsertConstantBefore(node: ts.Node, scope: Scope): ts.Statement { + ts.Debug.assert(!ts.isClassLike(scope)); let prevScope: Scope | undefined; for (let curr = node; curr !== scope; curr = curr.parent) { @@ -1554,7 +1463,7 @@ namespace ts.refactor.extractSymbol { for (let curr = (prevScope || node).parent; ; curr = curr.parent) { if (isBlockLike(curr)) { - let prevStatement: Statement | undefined; + let prevStatement: ts.Statement | undefined; for (const statement of curr.statements) { if (statement.pos > node.pos) { break; @@ -1562,26 +1471,23 @@ namespace ts.refactor.extractSymbol { prevStatement = statement; } - if (!prevStatement && isCaseClause(curr)) { + if (!prevStatement && ts.isCaseClause(curr)) { // We must have been in the expression of the case clause. - Debug.assert(isSwitchStatement(curr.parent.parent), "Grandparent isn't a switch statement"); + ts.Debug.assert(ts.isSwitchStatement(curr.parent.parent), "Grandparent isn't a switch statement"); return curr.parent.parent; } // There must be at least one statement since we started in one. - return Debug.checkDefined(prevStatement, "prevStatement failed to get set"); + return ts.Debug.checkDefined(prevStatement, "prevStatement failed to get set"); } - Debug.assert(curr !== scope, "Didn't encounter a block-like before encountering scope"); + ts.Debug.assert(curr !== scope, "Didn't encounter a block-like before encountering scope"); } } - function getPropertyAssignmentsForWritesAndVariableDeclarations( - exposedVariableDeclarations: readonly VariableDeclaration[], - writes: readonly UsageEntry[] | undefined - ): ShorthandPropertyAssignment[] { - const variableAssignments = map(exposedVariableDeclarations, v => factory.createShorthandPropertyAssignment(v.symbol.name)); - const writeAssignments = map(writes, w => factory.createShorthandPropertyAssignment(w.symbol.name)); + function getPropertyAssignmentsForWritesAndVariableDeclarations(exposedVariableDeclarations: readonly ts.VariableDeclaration[], writes: readonly UsageEntry[] | undefined): ts.ShorthandPropertyAssignment[] { + const variableAssignments = ts.map(exposedVariableDeclarations, v => ts.factory.createShorthandPropertyAssignment(v.symbol.name)); + const writeAssignments = ts.map(writes, w => ts.factory.createShorthandPropertyAssignment(w.symbol.name)); // TODO: GH#18217 `variableAssignments` not possibly undefined! return variableAssignments === undefined @@ -1592,7 +1498,7 @@ namespace ts.refactor.extractSymbol { } function isReadonlyArray(v: any): v is readonly any[] { - return isArray(v); + return ts.isArray(v); } /** @@ -1604,9 +1510,9 @@ namespace ts.refactor.extractSymbol { * var someThing = foo + bar; * this returns ^-------^ */ - function getEnclosingTextRange(targetRange: TargetRange, sourceFile: SourceFile): TextRange { + function getEnclosingTextRange(targetRange: TargetRange, sourceFile: ts.SourceFile): ts.TextRange { return isReadonlyArray(targetRange.range) - ? { pos: first(targetRange.range).getStart(sourceFile), end: last(targetRange.range).getEnd() } + ? { pos: ts.first(targetRange.range).getStart(sourceFile), end: ts.last(targetRange.range).getEnd() } : targetRange.range; } @@ -1619,62 +1525,55 @@ namespace ts.refactor.extractSymbol { interface UsageEntry { readonly usage: Usage; - readonly symbol: Symbol; - readonly node: Node; + readonly symbol: ts.Symbol; + readonly node: ts.Node; } interface ScopeUsages { - readonly usages: ESMap; - readonly typeParameterUsages: ESMap; // Key is type ID - readonly substitutions: ESMap; + readonly usages: ts.ESMap; + readonly typeParameterUsages: ts.ESMap; // Key is type ID + readonly substitutions: ts.ESMap; } interface ReadsAndWrites { - readonly target: Expression | Block; + readonly target: ts.Expression | ts.Block; readonly usagesPerScope: readonly ScopeUsages[]; - readonly functionErrorsPerScope: readonly (readonly Diagnostic[])[]; - readonly constantErrorsPerScope: readonly (readonly Diagnostic[])[]; - readonly exposedVariableDeclarations: readonly VariableDeclaration[]; + readonly functionErrorsPerScope: readonly (readonly ts.Diagnostic[])[]; + readonly constantErrorsPerScope: readonly (readonly ts.Diagnostic[])[]; + readonly exposedVariableDeclarations: readonly ts.VariableDeclaration[]; } - function collectReadsAndWrites( - targetRange: TargetRange, - scopes: Scope[], - enclosingTextRange: TextRange, - sourceFile: SourceFile, - checker: TypeChecker, - cancellationToken: CancellationToken): ReadsAndWrites { - - const allTypeParameterUsages = new Map(); // Key is type ID + function collectReadsAndWrites(targetRange: TargetRange, scopes: Scope[], enclosingTextRange: ts.TextRange, sourceFile: ts.SourceFile, checker: ts.TypeChecker, cancellationToken: ts.CancellationToken): ReadsAndWrites { + const allTypeParameterUsages = new ts.Map(); // Key is type ID const usagesPerScope: ScopeUsages[] = []; - const substitutionsPerScope: ESMap[] = []; - const functionErrorsPerScope: Diagnostic[][] = []; - const constantErrorsPerScope: Diagnostic[][] = []; - const visibleDeclarationsInExtractedRange: NamedDeclaration[] = []; - const exposedVariableSymbolSet = new Map(); // Key is symbol ID - const exposedVariableDeclarations: VariableDeclaration[] = []; - let firstExposedNonVariableDeclaration: NamedDeclaration | undefined; + const substitutionsPerScope: ts.ESMap[] = []; + const functionErrorsPerScope: ts.Diagnostic[][] = []; + const constantErrorsPerScope: ts.Diagnostic[][] = []; + const visibleDeclarationsInExtractedRange: ts.NamedDeclaration[] = []; + const exposedVariableSymbolSet = new ts.Map(); // Key is symbol ID + const exposedVariableDeclarations: ts.VariableDeclaration[] = []; + let firstExposedNonVariableDeclaration: ts.NamedDeclaration | undefined; const expression = !isReadonlyArray(targetRange.range) ? targetRange.range - : targetRange.range.length === 1 && isExpressionStatement(targetRange.range[0]) + : targetRange.range.length === 1 && ts.isExpressionStatement(targetRange.range[0]) ? targetRange.range[0].expression : undefined; - let expressionDiagnostic: Diagnostic | undefined; + let expressionDiagnostic: ts.Diagnostic | undefined; if (expression === undefined) { - const statements = targetRange.range as readonly Statement[]; - const start = first(statements).getStart(); - const end = last(statements).end; - expressionDiagnostic = createFileDiagnostic(sourceFile, start, end - start, Messages.expressionExpected); + const statements = targetRange.range as readonly ts.Statement[]; + const start = ts.first(statements).getStart(); + const end = ts.last(statements).end; + expressionDiagnostic = ts.createFileDiagnostic(sourceFile, start, end - start, Messages.expressionExpected); } - else if (checker.getTypeAtLocation(expression).flags & (TypeFlags.Void | TypeFlags.Never)) { - expressionDiagnostic = createDiagnosticForNode(expression, Messages.uselessConstantType); + else if (checker.getTypeAtLocation(expression).flags & (ts.TypeFlags.Void | ts.TypeFlags.Never)) { + expressionDiagnostic = ts.createDiagnosticForNode(expression, Messages.uselessConstantType); } // initialize results for (const scope of scopes) { - usagesPerScope.push({ usages: new Map(), typeParameterUsages: new Map(), substitutions: new Map() }); - substitutionsPerScope.push(new Map()); + usagesPerScope.push({ usages: new ts.Map(), typeParameterUsages: new ts.Map(), substitutions: new ts.Map() }); + substitutionsPerScope.push(new ts.Map()); functionErrorsPerScope.push([]); @@ -1682,20 +1581,19 @@ namespace ts.refactor.extractSymbol { if (expressionDiagnostic) { constantErrors.push(expressionDiagnostic); } - if (isClassLike(scope) && isInJSFile(scope)) { - constantErrors.push(createDiagnosticForNode(scope, Messages.cannotExtractToJSClass)); + if (ts.isClassLike(scope) && ts.isInJSFile(scope)) { + constantErrors.push(ts.createDiagnosticForNode(scope, Messages.cannotExtractToJSClass)); } - if (isArrowFunction(scope) && !isBlock(scope.body)) { + if (ts.isArrowFunction(scope) && !ts.isBlock(scope.body)) { // TODO (https://github.com/Microsoft/TypeScript/issues/18924): allow this - constantErrors.push(createDiagnosticForNode(scope, Messages.cannotExtractToExpressionArrowFunction)); + constantErrors.push(ts.createDiagnosticForNode(scope, Messages.cannotExtractToExpressionArrowFunction)); } constantErrorsPerScope.push(constantErrors); } - const seenUsages = new Map(); - const target = isReadonlyArray(targetRange.range) ? factory.createBlock(targetRange.range) : targetRange.range; - - const unmodifiedNode = isReadonlyArray(targetRange.range) ? first(targetRange.range) : targetRange.range; + const seenUsages = new ts.Map(); + const target = isReadonlyArray(targetRange.range) ? ts.factory.createBlock(targetRange.range) : targetRange.range; + const unmodifiedNode = isReadonlyArray(targetRange.range) ? ts.first(targetRange.range) : targetRange.range; const inGenericContext = isInGenericContext(unmodifiedNode); collectUsages(target); @@ -1703,16 +1601,16 @@ namespace ts.refactor.extractSymbol { // Unfortunately, this code takes advantage of the knowledge that the generated method // will use the contextual type of an expression as the return type of the extracted // method (and will therefore "use" all the types involved). - if (inGenericContext && !isReadonlyArray(targetRange.range) && !isJsxAttribute(targetRange.range)) { + if (inGenericContext && !isReadonlyArray(targetRange.range) && !ts.isJsxAttribute(targetRange.range)) { const contextualType = checker.getContextualType(targetRange.range)!; // TODO: GH#18217 recordTypeParameterUsages(contextualType); } if (allTypeParameterUsages.size > 0) { - const seenTypeParameterUsages = new Map(); // Key is type ID + const seenTypeParameterUsages = new ts.Map(); // Key is type ID let i = 0; - for (let curr: Node = unmodifiedNode; curr !== undefined && i < scopes.length; curr = curr.parent) { + for (let curr: ts.Node = unmodifiedNode; curr !== undefined && i < scopes.length; curr = curr.parent) { if (curr === scopes[i]) { // Copy current contents of seenTypeParameterUsages into scope. seenTypeParameterUsages.forEach((typeParameter, id) => { @@ -1723,9 +1621,9 @@ namespace ts.refactor.extractSymbol { } // Note that we add the current node's type parameters *after* updating the corresponding scope. - if (isDeclarationWithTypeParameters(curr)) { - for (const typeParameterDecl of getEffectiveTypeParameterDeclarations(curr)) { - const typeParameter = checker.getTypeAtLocation(typeParameterDecl) as TypeParameter; + if (ts.isDeclarationWithTypeParameters(curr)) { + for (const typeParameterDecl of ts.getEffectiveTypeParameterDeclarations(curr)) { + const typeParameter = checker.getTypeAtLocation(typeParameterDecl) as ts.TypeParameter; if (allTypeParameterUsages.has(typeParameter.id.toString())) { seenTypeParameterUsages.set(typeParameter.id.toString(), typeParameter); } @@ -1736,16 +1634,16 @@ namespace ts.refactor.extractSymbol { // If we didn't get through all the scopes, then there were some that weren't in our // parent chain (impossible at time of writing). A conservative solution would be to // copy allTypeParameterUsages into all remaining scopes. - Debug.assert(i === scopes.length, "Should have iterated all scopes"); + ts.Debug.assert(i === scopes.length, "Should have iterated all scopes"); } // If there are any declarations in the extracted block that are used in the same enclosing // lexical scope, we can't move the extraction "up" as those declarations will become unreachable if (visibleDeclarationsInExtractedRange.length) { - const containingLexicalScopeOfExtraction = isBlockScope(scopes[0], scopes[0].parent) + const containingLexicalScopeOfExtraction = ts.isBlockScope(scopes[0], scopes[0].parent) ? scopes[0] - : getEnclosingBlockScopeContainer(scopes[0]); - forEachChild(containingLexicalScopeOfExtraction, checkForUsedDeclarations); + : ts.getEnclosingBlockScopeContainer(scopes[0]); + ts.forEachChild(containingLexicalScopeOfExtraction, checkForUsedDeclarations); } for (let i = 0; i < scopes.length; i++) { @@ -1755,41 +1653,41 @@ namespace ts.refactor.extractSymbol { // local will actually be declared at the same level as the extracted expression). if (i > 0 && (scopeUsages.usages.size > 0 || scopeUsages.typeParameterUsages.size > 0)) { const errorNode = isReadonlyArray(targetRange.range) ? targetRange.range[0] : targetRange.range; - constantErrorsPerScope[i].push(createDiagnosticForNode(errorNode, Messages.cannotAccessVariablesFromNestedScopes)); + constantErrorsPerScope[i].push(ts.createDiagnosticForNode(errorNode, Messages.cannotAccessVariablesFromNestedScopes)); } - if (targetRange.facts & RangeFacts.UsesThisInFunction && isClassLike(scopes[i])) { - functionErrorsPerScope[i].push(createDiagnosticForNode(targetRange.thisNode!, Messages.cannotExtractFunctionsContainingThisToMethod)); + if (targetRange.facts & RangeFacts.UsesThisInFunction && ts.isClassLike(scopes[i])) { + functionErrorsPerScope[i].push(ts.createDiagnosticForNode(targetRange.thisNode!, Messages.cannotExtractFunctionsContainingThisToMethod)); } let hasWrite = false; - let readonlyClassPropertyWrite: Declaration | undefined; + let readonlyClassPropertyWrite: ts.Declaration | undefined; usagesPerScope[i].usages.forEach(value => { if (value.usage === Usage.Write) { hasWrite = true; - if (value.symbol.flags & SymbolFlags.ClassMember && + if (value.symbol.flags & ts.SymbolFlags.ClassMember && value.symbol.valueDeclaration && - hasEffectiveModifier(value.symbol.valueDeclaration, ModifierFlags.Readonly)) { + ts.hasEffectiveModifier(value.symbol.valueDeclaration, ts.ModifierFlags.Readonly)) { readonlyClassPropertyWrite = value.symbol.valueDeclaration; } } }); // If an expression was extracted, then there shouldn't have been any variable declarations. - Debug.assert(isReadonlyArray(targetRange.range) || exposedVariableDeclarations.length === 0, "No variable declarations expected if something was extracted"); + ts.Debug.assert(isReadonlyArray(targetRange.range) || exposedVariableDeclarations.length === 0, "No variable declarations expected if something was extracted"); if (hasWrite && !isReadonlyArray(targetRange.range)) { - const diag = createDiagnosticForNode(targetRange.range, Messages.cannotWriteInExpression); + const diag = ts.createDiagnosticForNode(targetRange.range, Messages.cannotWriteInExpression); functionErrorsPerScope[i].push(diag); constantErrorsPerScope[i].push(diag); } else if (readonlyClassPropertyWrite && i > 0) { - const diag = createDiagnosticForNode(readonlyClassPropertyWrite, Messages.cannotExtractReadonlyPropertyInitializerOutsideConstructor); + const diag = ts.createDiagnosticForNode(readonlyClassPropertyWrite, Messages.cannotExtractReadonlyPropertyInitializerOutsideConstructor); functionErrorsPerScope[i].push(diag); constantErrorsPerScope[i].push(diag); } else if (firstExposedNonVariableDeclaration) { - const diag = createDiagnosticForNode(firstExposedNonVariableDeclaration, Messages.cannotExtractExportedEntity); + const diag = ts.createDiagnosticForNode(firstExposedNonVariableDeclaration, Messages.cannotExtractExportedEntity); functionErrorsPerScope[i].push(diag); constantErrorsPerScope[i].push(diag); } @@ -1797,11 +1695,11 @@ namespace ts.refactor.extractSymbol { return { target, usagesPerScope, functionErrorsPerScope, constantErrorsPerScope, exposedVariableDeclarations }; - function isInGenericContext(node: Node) { - return !!findAncestor(node, n => isDeclarationWithTypeParameters(n) && getEffectiveTypeParameterDeclarations(n).length !== 0); + function isInGenericContext(node: ts.Node) { + return !!ts.findAncestor(node, n => ts.isDeclarationWithTypeParameters(n) && ts.getEffectiveTypeParameterDeclarations(n).length !== 0); } - function recordTypeParameterUsages(type: Type) { + function recordTypeParameterUsages(type: ts.Type) { // PERF: This is potentially very expensive. `type` could be a library type with // a lot of properties, each of which the walker will visit. Unfortunately, the // solution isn't as trivial as filtering to user types because of (e.g.) Array. @@ -1815,65 +1713,65 @@ namespace ts.refactor.extractSymbol { } } - function collectUsages(node: Node, valueUsage = Usage.Read) { + function collectUsages(node: ts.Node, valueUsage = Usage.Read) { if (inGenericContext) { const type = checker.getTypeAtLocation(node); recordTypeParameterUsages(type); } - if (isDeclaration(node) && node.symbol) { + if (ts.isDeclaration(node) && node.symbol) { visibleDeclarationsInExtractedRange.push(node); } - if (isAssignmentExpression(node)) { + if (ts.isAssignmentExpression(node)) { // use 'write' as default usage for values collectUsages(node.left, Usage.Write); collectUsages(node.right); } - else if (isUnaryExpressionWithWrite(node)) { + else if (ts.isUnaryExpressionWithWrite(node)) { collectUsages(node.operand, Usage.Write); } - else if (isPropertyAccessExpression(node) || isElementAccessExpression(node)) { + else if (ts.isPropertyAccessExpression(node) || ts.isElementAccessExpression(node)) { // use 'write' as default usage for values - forEachChild(node, collectUsages); + ts.forEachChild(node, collectUsages); } - else if (isIdentifier(node)) { + else if (ts.isIdentifier(node)) { if (!node.parent) { return; } - if (isQualifiedName(node.parent) && node !== node.parent.left) { + if (ts.isQualifiedName(node.parent) && node !== node.parent.left) { return; } - if (isPropertyAccessExpression(node.parent) && node !== node.parent.expression) { + if (ts.isPropertyAccessExpression(node.parent) && node !== node.parent.expression) { return; } - recordUsage(node, valueUsage, /*isTypeNode*/ isPartOfTypeNode(node)); + recordUsage(node, valueUsage, /*isTypeNode*/ ts.isPartOfTypeNode(node)); } else { - forEachChild(node, collectUsages); + ts.forEachChild(node, collectUsages); } } - function recordUsage(n: Identifier, usage: Usage, isTypeNode: boolean) { + function recordUsage(n: ts.Identifier, usage: Usage, isTypeNode: boolean) { const symbolId = recordUsagebySymbol(n, usage, isTypeNode); if (symbolId) { for (let i = 0; i < scopes.length; i++) { // push substitution from map to map to simplify rewriting const substitution = substitutionsPerScope[i].get(symbolId); if (substitution) { - usagesPerScope[i].substitutions.set(getNodeId(n).toString(), substitution); + usagesPerScope[i].substitutions.set(ts.getNodeId(n).toString(), substitution); } } } } - function recordUsagebySymbol(identifier: Identifier, usage: Usage, isTypeName: boolean) { + function recordUsagebySymbol(identifier: ts.Identifier, usage: Usage, isTypeName: boolean) { const symbol = getSymbolReferencedByIdentifier(identifier); if (!symbol) { // cannot find symbol - do nothing return undefined; } - const symbolId = getSymbolId(symbol).toString(); + const symbolId = ts.getSymbolId(symbol).toString(); const lastUsage = seenUsages.get(symbolId); // there are two kinds of value usages // - reads - if range contains a read from the value located outside of the range then value should be passed as a parameter @@ -1899,18 +1797,18 @@ namespace ts.refactor.extractSymbol { } // find first declaration in this file const decls = symbol.getDeclarations(); - const declInFile = decls && find(decls, d => d.getSourceFile() === sourceFile); + const declInFile = decls && ts.find(decls, d => d.getSourceFile() === sourceFile); if (!declInFile) { return undefined; } - if (rangeContainsStartEnd(enclosingTextRange, declInFile.getStart(), declInFile.end)) { + if (ts.rangeContainsStartEnd(enclosingTextRange, declInFile.getStart(), declInFile.end)) { // declaration is located in range to be extracted - do nothing return undefined; } if (targetRange.facts & RangeFacts.IsGenerator && usage === Usage.Write) { // this is write to a reference located outside of the target scope and range is extracted into generator // currently this is unsupported scenario - const diag = createDiagnosticForNode(identifier, Messages.cannotExtractRangeThatContainsWritesToReferencesLocatedOutsideOfTheTargetRangeInGenerators); + const diag = ts.createDiagnosticForNode(identifier, Messages.cannotExtractRangeThatContainsWritesToReferencesLocatedOutsideOfTheTargetRangeInGenerators); for (const errors of functionErrorsPerScope) { errors.push(diag); } @@ -1932,8 +1830,8 @@ namespace ts.refactor.extractSymbol { else if (isTypeName) { // If the symbol is a type parameter that won't be in scope, we'll pass it as a type argument // so there's no problem. - if (!(symbol.flags & SymbolFlags.TypeParameter)) { - const diag = createDiagnosticForNode(identifier, Messages.typeWillNotBeVisibleInTheNewScope); + if (!(symbol.flags & ts.SymbolFlags.TypeParameter)) { + const diag = ts.createDiagnosticForNode(identifier, Messages.typeWillNotBeVisibleInTheNewScope); functionErrorsPerScope[i].push(diag); constantErrorsPerScope[i].push(diag); } @@ -1946,20 +1844,20 @@ namespace ts.refactor.extractSymbol { return symbolId; } - function checkForUsedDeclarations(node: Node) { + function checkForUsedDeclarations(node: ts.Node) { // If this node is entirely within the original extraction range, we don't need to do anything. - if (node === targetRange.range || (isReadonlyArray(targetRange.range) && targetRange.range.indexOf(node as Statement) >= 0)) { + if (node === targetRange.range || (isReadonlyArray(targetRange.range) && targetRange.range.indexOf(node as ts.Statement) >= 0)) { return; } // Otherwise check and recurse. - const sym = isIdentifier(node) + const sym = ts.isIdentifier(node) ? getSymbolReferencedByIdentifier(node) : checker.getSymbolAtLocation(node); if (sym) { - const decl = find(visibleDeclarationsInExtractedRange, d => d.symbol === sym); + const decl = ts.find(visibleDeclarationsInExtractedRange, d => d.symbol === sym); if (decl) { - if (isVariableDeclaration(decl)) { + if (ts.isVariableDeclaration(decl)) { const idString = decl.symbol.id!.toString(); if (!exposedVariableSymbolSet.has(idString)) { exposedVariableDeclarations.push(decl); @@ -1974,40 +1872,40 @@ namespace ts.refactor.extractSymbol { } } - forEachChild(node, checkForUsedDeclarations); + ts.forEachChild(node, checkForUsedDeclarations); } /** * Return the symbol referenced by an identifier (even if it declares a different symbol). */ - function getSymbolReferencedByIdentifier(identifier: Identifier) { + function getSymbolReferencedByIdentifier(identifier: ts.Identifier) { // If the identifier is both a property name and its value, we're only interested in its value // (since the name is a declaration and will be included in the extracted range). - return identifier.parent && isShorthandPropertyAssignment(identifier.parent) && identifier.parent.name === identifier + return identifier.parent && ts.isShorthandPropertyAssignment(identifier.parent) && identifier.parent.name === identifier ? checker.getShorthandAssignmentValueSymbol(identifier.parent) : checker.getSymbolAtLocation(identifier); } - function tryReplaceWithQualifiedNameOrPropertyAccess(symbol: Symbol | undefined, scopeDecl: Node, isTypeNode: boolean): PropertyAccessExpression | EntityName | undefined { + function tryReplaceWithQualifiedNameOrPropertyAccess(symbol: ts.Symbol | undefined, scopeDecl: ts.Node, isTypeNode: boolean): ts.PropertyAccessExpression | ts.EntityName | undefined { if (!symbol) { return undefined; } const decls = symbol.getDeclarations(); if (decls && decls.some(d => d.parent === scopeDecl)) { - return factory.createIdentifier(symbol.name); + return ts.factory.createIdentifier(symbol.name); } const prefix = tryReplaceWithQualifiedNameOrPropertyAccess(symbol.parent, scopeDecl, isTypeNode); if (prefix === undefined) { return undefined; } return isTypeNode - ? factory.createQualifiedName(prefix as EntityName, factory.createIdentifier(symbol.name)) - : factory.createPropertyAccessExpression(prefix as Expression, symbol.name); + ? ts.factory.createQualifiedName(prefix as ts.EntityName, ts.factory.createIdentifier(symbol.name)) + : ts.factory.createPropertyAccessExpression(prefix as ts.Expression, symbol.name); } } - function getExtractableParent(node: Node | undefined): Node | undefined { - return findAncestor(node, node => node.parent && isExtractableExpression(node) && !isBinaryExpression(node.parent)); + function getExtractableParent(node: ts.Node | undefined): ts.Node | undefined { + return ts.findAncestor(node, node => node.parent && isExtractableExpression(node) && !ts.isBinaryExpression(node.parent)); } /** @@ -2017,49 +1915,48 @@ namespace ts.refactor.extractSymbol { * such as `import x from 'y'` -- the 'y' is a StringLiteral but is *not* an expression * in the sense of something that you could extract on */ - function isExtractableExpression(node: Node): boolean { + function isExtractableExpression(node: ts.Node): boolean { const { parent } = node; switch (parent.kind) { - case SyntaxKind.EnumMember: + case ts.SyntaxKind.EnumMember: return false; } switch (node.kind) { - case SyntaxKind.StringLiteral: - return parent.kind !== SyntaxKind.ImportDeclaration && - parent.kind !== SyntaxKind.ImportSpecifier; - - case SyntaxKind.SpreadElement: - case SyntaxKind.ObjectBindingPattern: - case SyntaxKind.BindingElement: + case ts.SyntaxKind.StringLiteral: + return parent.kind !== ts.SyntaxKind.ImportDeclaration && + parent.kind !== ts.SyntaxKind.ImportSpecifier; + case ts.SyntaxKind.SpreadElement: + case ts.SyntaxKind.ObjectBindingPattern: + case ts.SyntaxKind.BindingElement: return false; - case SyntaxKind.Identifier: - return parent.kind !== SyntaxKind.BindingElement && - parent.kind !== SyntaxKind.ImportSpecifier && - parent.kind !== SyntaxKind.ExportSpecifier; + case ts.SyntaxKind.Identifier: + return parent.kind !== ts.SyntaxKind.BindingElement && + parent.kind !== ts.SyntaxKind.ImportSpecifier && + parent.kind !== ts.SyntaxKind.ExportSpecifier; } return true; } - function isBlockLike(node: Node): node is BlockLike { + function isBlockLike(node: ts.Node): node is ts.BlockLike { switch (node.kind) { - case SyntaxKind.Block: - case SyntaxKind.SourceFile: - case SyntaxKind.ModuleBlock: - case SyntaxKind.CaseClause: + case ts.SyntaxKind.Block: + case ts.SyntaxKind.SourceFile: + case ts.SyntaxKind.ModuleBlock: + case ts.SyntaxKind.CaseClause: return true; default: return false; } } - function isInJSXContent(node: Node) { + function isInJSXContent(node: ts.Node) { return isStringLiteralJsxAttribute(node) || - (isJsxElement(node) || isJsxSelfClosingElement(node) || isJsxFragment(node)) && (isJsxElement(node.parent) || isJsxFragment(node.parent)); + (ts.isJsxElement(node) || ts.isJsxSelfClosingElement(node) || ts.isJsxFragment(node)) && (ts.isJsxElement(node.parent) || ts.isJsxFragment(node.parent)); } - function isStringLiteralJsxAttribute(node: Node): node is StringLiteral { - return isStringLiteral(node) && node.parent && isJsxAttribute(node.parent); + function isStringLiteralJsxAttribute(node: ts.Node): node is ts.StringLiteral { + return ts.isStringLiteral(node) && node.parent && ts.isJsxAttribute(node.parent); } } diff --git a/src/services/refactors/extractType.ts b/src/services/refactors/extractType.ts index ac6ab73963b31..c94bea810d3ac 100644 --- a/src/services/refactors/extractType.ts +++ b/src/services/refactors/extractType.ts @@ -4,43 +4,43 @@ namespace ts.refactor { const extractToTypeAliasAction = { name: "Extract to type alias", - description: getLocaleSpecificMessage(Diagnostics.Extract_to_type_alias), + description: ts.getLocaleSpecificMessage(ts.Diagnostics.Extract_to_type_alias), kind: "refactor.extract.type", }; const extractToInterfaceAction = { name: "Extract to interface", - description: getLocaleSpecificMessage(Diagnostics.Extract_to_interface), + description: ts.getLocaleSpecificMessage(ts.Diagnostics.Extract_to_interface), kind: "refactor.extract.interface", }; const extractToTypeDefAction = { name: "Extract to typedef", - description: getLocaleSpecificMessage(Diagnostics.Extract_to_typedef), + description: ts.getLocaleSpecificMessage(ts.Diagnostics.Extract_to_typedef), kind: "refactor.extract.typedef" }; - registerRefactor(refactorName, { + ts.refactor.registerRefactor(refactorName, { kinds: [ extractToTypeAliasAction.kind, extractToInterfaceAction.kind, extractToTypeDefAction.kind ], - getAvailableActions: function getRefactorActionsToExtractType(context): readonly ApplicableRefactorInfo[] { + getAvailableActions: function getRefactorActionsToExtractType(context): readonly ts.ApplicableRefactorInfo[] { const info = getRangeToExtract(context, context.triggerReason === "invoked"); - if (!info) return emptyArray; - - if (!isRefactorErrorInfo(info)) { + if (!info) + return ts.emptyArray; + if (!ts.refactor.isRefactorErrorInfo(info)) { return [{ name: refactorName, - description: getLocaleSpecificMessage(Diagnostics.Extract_type), + description: ts.getLocaleSpecificMessage(ts.Diagnostics.Extract_type), actions: info.isJS ? - [extractToTypeDefAction] : append([extractToTypeAliasAction], info.typeElements && extractToInterfaceAction) + [extractToTypeDefAction] : ts.append([extractToTypeAliasAction], info.typeElements && extractToInterfaceAction) }]; } if (context.preferences.provideRefactorNotApplicableReason) { return [{ name: refactorName, - description: getLocaleSpecificMessage(Diagnostics.Extract_type), + description: ts.getLocaleSpecificMessage(ts.Diagnostics.Extract_type), actions: [ { ...extractToTypeDefAction, notApplicableReason: info.error }, { ...extractToTypeAliasAction, notApplicableReason: info.error }, @@ -49,105 +49,115 @@ namespace ts.refactor { }]; } - return emptyArray; + return ts.emptyArray; }, - getEditsForAction: function getRefactorEditsToExtractType(context, actionName): RefactorEditInfo { + getEditsForAction: function getRefactorEditsToExtractType(context, actionName): ts.RefactorEditInfo { const { file, } = context; const info = getRangeToExtract(context); - Debug.assert(info && !isRefactorErrorInfo(info), "Expected to find a range to extract"); - - const name = getUniqueName("NewType", file); - const edits = textChanges.ChangeTracker.with(context, changes => { + ts.Debug.assert(info && !ts.refactor.isRefactorErrorInfo(info), "Expected to find a range to extract"); + const name = ts.getUniqueName("NewType", file); + const edits = ts.textChanges.ChangeTracker.with(context, changes => { switch (actionName) { case extractToTypeAliasAction.name: - Debug.assert(!info.isJS, "Invalid actionName/JS combo"); + ts.Debug.assert(!info.isJS, "Invalid actionName/JS combo"); return doTypeAliasChange(changes, file, name, info); case extractToTypeDefAction.name: - Debug.assert(info.isJS, "Invalid actionName/JS combo"); + ts.Debug.assert(info.isJS, "Invalid actionName/JS combo"); return doTypedefChange(changes, file, name, info); case extractToInterfaceAction.name: - Debug.assert(!info.isJS && !!info.typeElements, "Invalid actionName/JS combo"); + ts.Debug.assert(!info.isJS && !!info.typeElements, "Invalid actionName/JS combo"); return doInterfaceChange(changes, file, name, info as InterfaceInfo); default: - Debug.fail("Unexpected action name"); + ts.Debug.fail("Unexpected action name"); } }); const renameFilename = file.fileName; - const renameLocation = getRenameLocation(edits, renameFilename, name, /*preferLastLocation*/ false); + const renameLocation = ts.getRenameLocation(edits, renameFilename, name, /*preferLastLocation*/ false); return { edits, renameFilename, renameLocation }; } }); interface TypeAliasInfo { - isJS: boolean; selection: TypeNode; firstStatement: Statement; typeParameters: readonly TypeParameterDeclaration[]; typeElements?: readonly TypeElement[]; + isJS: boolean; + selection: ts.TypeNode; + firstStatement: ts.Statement; + typeParameters: readonly ts.TypeParameterDeclaration[]; + typeElements?: readonly ts.TypeElement[]; } interface InterfaceInfo { - isJS: boolean; selection: TypeNode; firstStatement: Statement; typeParameters: readonly TypeParameterDeclaration[]; typeElements: readonly TypeElement[]; + isJS: boolean; + selection: ts.TypeNode; + firstStatement: ts.Statement; + typeParameters: readonly ts.TypeParameterDeclaration[]; + typeElements: readonly ts.TypeElement[]; } type ExtractInfo = TypeAliasInfo | InterfaceInfo; - function getRangeToExtract(context: RefactorContext, considerEmptySpans = true): ExtractInfo | RefactorErrorInfo | undefined { + function getRangeToExtract(context: ts.RefactorContext, considerEmptySpans = true): ExtractInfo | ts.refactor.RefactorErrorInfo | undefined { const { file, startPosition } = context; - const isJS = isSourceFileJS(file); - const current = getTokenAtPosition(file, startPosition); - const range = createTextRangeFromSpan(getRefactorContextSpan(context)); + const isJS = ts.isSourceFileJS(file); + const current = ts.getTokenAtPosition(file, startPosition); + const range = ts.createTextRangeFromSpan(ts.getRefactorContextSpan(context)); const cursorRequest = range.pos === range.end && considerEmptySpans; - const selection = findAncestor(current, (node => node.parent && isTypeNode(node) && !rangeContainsSkipTrivia(range, node.parent, file) && - (cursorRequest || nodeOverlapsWithStartEnd(current, file, range.pos, range.end)))); - if (!selection || !isTypeNode(selection)) return { error: getLocaleSpecificMessage(Diagnostics.Selection_is_not_a_valid_type_node) }; + const selection = ts.findAncestor(current, (node => node.parent && ts.isTypeNode(node) && !rangeContainsSkipTrivia(range, node.parent, file) && + (cursorRequest || ts.nodeOverlapsWithStartEnd(current, file, range.pos, range.end)))); + if (!selection || !ts.isTypeNode(selection)) + return { error: ts.getLocaleSpecificMessage(ts.Diagnostics.Selection_is_not_a_valid_type_node) }; const checker = context.program.getTypeChecker(); - const firstStatement = Debug.checkDefined(findAncestor(selection, isStatement), "Should find a statement"); + const firstStatement = ts.Debug.checkDefined(ts.findAncestor(selection, ts.isStatement), "Should find a statement"); const typeParameters = collectTypeParameters(checker, selection, firstStatement, file); - if (!typeParameters) return { error: getLocaleSpecificMessage(Diagnostics.No_type_could_be_extracted_from_this_type_node) }; + if (!typeParameters) + return { error: ts.getLocaleSpecificMessage(ts.Diagnostics.No_type_could_be_extracted_from_this_type_node) }; const typeElements = flattenTypeLiteralNodeReference(checker, selection); return { isJS, selection, firstStatement, typeParameters, typeElements }; } - function flattenTypeLiteralNodeReference(checker: TypeChecker, node: TypeNode | undefined): readonly TypeElement[] | undefined { - if (!node) return undefined; - if (isIntersectionTypeNode(node)) { - const result: TypeElement[] = []; - const seen = new Map(); + function flattenTypeLiteralNodeReference(checker: ts.TypeChecker, node: ts.TypeNode | undefined): readonly ts.TypeElement[] | undefined { + if (!node) + return undefined; + if (ts.isIntersectionTypeNode(node)) { + const result: ts.TypeElement[] = []; + const seen = new ts.Map(); for (const type of node.types) { const flattenedTypeMembers = flattenTypeLiteralNodeReference(checker, type); - if (!flattenedTypeMembers || !flattenedTypeMembers.every(type => type.name && addToSeen(seen, getNameFromPropertyName(type.name) as string))) { + if (!flattenedTypeMembers || !flattenedTypeMembers.every(type => type.name && ts.addToSeen(seen, ts.getNameFromPropertyName(type.name) as string))) { return undefined; } - addRange(result, flattenedTypeMembers); + ts.addRange(result, flattenedTypeMembers); } return result; } - else if (isParenthesizedTypeNode(node)) { + else if (ts.isParenthesizedTypeNode(node)) { return flattenTypeLiteralNodeReference(checker, node.type); } - else if (isTypeLiteralNode(node)) { + else if (ts.isTypeLiteralNode(node)) { return node.members; } return undefined; } - function rangeContainsSkipTrivia(r1: TextRange, node: Node, file: SourceFile): boolean { - return rangeContainsStartEnd(r1, skipTrivia(file.text, node.pos), node.end); + function rangeContainsSkipTrivia(r1: ts.TextRange, node: ts.Node, file: ts.SourceFile): boolean { + return ts.rangeContainsStartEnd(r1, ts.skipTrivia(file.text, node.pos), node.end); } - function collectTypeParameters(checker: TypeChecker, selection: TypeNode, statement: Statement, file: SourceFile): TypeParameterDeclaration[] | undefined { - const result: TypeParameterDeclaration[] = []; + function collectTypeParameters(checker: ts.TypeChecker, selection: ts.TypeNode, statement: ts.Statement, file: ts.SourceFile): ts.TypeParameterDeclaration[] | undefined { + const result: ts.TypeParameterDeclaration[] = []; return visitor(selection) ? undefined : result; - function visitor(node: Node): true | undefined { - if (isTypeReferenceNode(node)) { - if (isIdentifier(node.typeName)) { + function visitor(node: ts.Node): true | undefined { + if (ts.isTypeReferenceNode(node)) { + if (ts.isIdentifier(node.typeName)) { const typeName = node.typeName; - const symbol = checker.resolveName(typeName.text, typeName, SymbolFlags.TypeParameter, /* excludeGlobals */ true); - for (const decl of symbol?.declarations || emptyArray) { - if (isTypeParameterDeclaration(decl) && decl.getSourceFile() === file) { + const symbol = checker.resolveName(typeName.text, typeName, ts.SymbolFlags.TypeParameter, /* excludeGlobals */ true); + for (const decl of symbol?.declarations || ts.emptyArray) { + if (ts.isTypeParameterDeclaration(decl) && decl.getSourceFile() === file) { // skip extraction if the type node is in the range of the type parameter declaration. // function foo(): void; if (decl.name.escapedText === typeName.escapedText && rangeContainsSkipTrivia(decl, selection, file)) { @@ -155,100 +165,81 @@ namespace ts.refactor { } if (rangeContainsSkipTrivia(statement, decl, file) && !rangeContainsSkipTrivia(selection, decl, file)) { - pushIfUnique(result, decl); + ts.pushIfUnique(result, decl); break; } } } } } - else if (isInferTypeNode(node)) { - const conditionalTypeNode = findAncestor(node, n => isConditionalTypeNode(n) && rangeContainsSkipTrivia(n.extendsType, node, file)); + else if (ts.isInferTypeNode(node)) { + const conditionalTypeNode = ts.findAncestor(node, n => ts.isConditionalTypeNode(n) && rangeContainsSkipTrivia(n.extendsType, node, file)); if (!conditionalTypeNode || !rangeContainsSkipTrivia(selection, conditionalTypeNode, file)) { return true; } } - else if ((isTypePredicateNode(node) || isThisTypeNode(node))) { - const functionLikeNode = findAncestor(node.parent, isFunctionLike); + else if ((ts.isTypePredicateNode(node) || ts.isThisTypeNode(node))) { + const functionLikeNode = ts.findAncestor(node.parent, ts.isFunctionLike); if (functionLikeNode && functionLikeNode.type && rangeContainsSkipTrivia(functionLikeNode.type, node, file) && !rangeContainsSkipTrivia(selection, functionLikeNode, file)) { return true; } } - else if (isTypeQueryNode(node)) { - if (isIdentifier(node.exprName)) { - const symbol = checker.resolveName(node.exprName.text, node.exprName, SymbolFlags.Value, /* excludeGlobals */ false); + else if (ts.isTypeQueryNode(node)) { + if (ts.isIdentifier(node.exprName)) { + const symbol = checker.resolveName(node.exprName.text, node.exprName, ts.SymbolFlags.Value, /* excludeGlobals */ false); if (symbol?.valueDeclaration && rangeContainsSkipTrivia(statement, symbol.valueDeclaration, file) && !rangeContainsSkipTrivia(selection, symbol.valueDeclaration, file)) { return true; } } else { - if (isThisIdentifier(node.exprName.left) && !rangeContainsSkipTrivia(selection, node.parent, file)) { + if (ts.isThisIdentifier(node.exprName.left) && !rangeContainsSkipTrivia(selection, node.parent, file)) { return true; } } } - if (file && isTupleTypeNode(node) && (getLineAndCharacterOfPosition(file, node.pos).line === getLineAndCharacterOfPosition(file, node.end).line)) { - setEmitFlags(node, EmitFlags.SingleLine); + if (file && ts.isTupleTypeNode(node) && (ts.getLineAndCharacterOfPosition(file, node.pos).line === ts.getLineAndCharacterOfPosition(file, node.end).line)) { + ts.setEmitFlags(node, ts.EmitFlags.SingleLine); } - return forEachChild(node, visitor); + return ts.forEachChild(node, visitor); } } - function doTypeAliasChange(changes: textChanges.ChangeTracker, file: SourceFile, name: string, info: TypeAliasInfo) { + function doTypeAliasChange(changes: ts.textChanges.ChangeTracker, file: ts.SourceFile, name: string, info: TypeAliasInfo) { const { firstStatement, selection, typeParameters } = info; - const newTypeNode = factory.createTypeAliasDeclaration( + const newTypeNode = ts.factory.createTypeAliasDeclaration( /* decorators */ undefined, - /* modifiers */ undefined, - name, - typeParameters.map(id => factory.updateTypeParameterDeclaration(id, id.modifiers, id.name, id.constraint, /* defaultType */ undefined)), - selection - ); - changes.insertNodeBefore(file, firstStatement, ignoreSourceNewlines(newTypeNode), /* blankLineBetween */ true); - changes.replaceNode(file, selection, factory.createTypeReferenceNode(name, typeParameters.map(id => factory.createTypeReferenceNode(id.name, /* typeArguments */ undefined))), { leadingTriviaOption: textChanges.LeadingTriviaOption.Exclude, trailingTriviaOption: textChanges.TrailingTriviaOption.ExcludeWhitespace }); + /* modifiers */ undefined, name, typeParameters.map(id => ts.factory.updateTypeParameterDeclaration(id, id.modifiers, id.name, id.constraint, /* defaultType */ undefined)), selection); + changes.insertNodeBefore(file, firstStatement, ts.ignoreSourceNewlines(newTypeNode), /* blankLineBetween */ true); + changes.replaceNode(file, selection, ts.factory.createTypeReferenceNode(name, typeParameters.map(id => ts.factory.createTypeReferenceNode(id.name, /* typeArguments */ undefined))), { leadingTriviaOption: ts.textChanges.LeadingTriviaOption.Exclude, trailingTriviaOption: ts.textChanges.TrailingTriviaOption.ExcludeWhitespace }); } - - function doInterfaceChange(changes: textChanges.ChangeTracker, file: SourceFile, name: string, info: InterfaceInfo) { + function doInterfaceChange(changes: ts.textChanges.ChangeTracker, file: ts.SourceFile, name: string, info: InterfaceInfo) { const { firstStatement, selection, typeParameters, typeElements } = info; - const newTypeNode = factory.createInterfaceDeclaration( + const newTypeNode = ts.factory.createInterfaceDeclaration( /* decorators */ undefined, - /* modifiers */ undefined, - name, - typeParameters, - /* heritageClauses */ undefined, - typeElements - ); - setTextRange(newTypeNode, typeElements[0]?.parent); - changes.insertNodeBefore(file, firstStatement, ignoreSourceNewlines(newTypeNode), /* blankLineBetween */ true); - changes.replaceNode(file, selection, factory.createTypeReferenceNode(name, typeParameters.map(id => factory.createTypeReferenceNode(id.name, /* typeArguments */ undefined))), { leadingTriviaOption: textChanges.LeadingTriviaOption.Exclude, trailingTriviaOption: textChanges.TrailingTriviaOption.ExcludeWhitespace }); + /* modifiers */ undefined, name, typeParameters, + /* heritageClauses */ undefined, typeElements); + ts.setTextRange(newTypeNode, typeElements[0]?.parent); + changes.insertNodeBefore(file, firstStatement, ts.ignoreSourceNewlines(newTypeNode), /* blankLineBetween */ true); + changes.replaceNode(file, selection, ts.factory.createTypeReferenceNode(name, typeParameters.map(id => ts.factory.createTypeReferenceNode(id.name, /* typeArguments */ undefined))), { leadingTriviaOption: ts.textChanges.LeadingTriviaOption.Exclude, trailingTriviaOption: ts.textChanges.TrailingTriviaOption.ExcludeWhitespace }); } - - function doTypedefChange(changes: textChanges.ChangeTracker, file: SourceFile, name: string, info: ExtractInfo) { + function doTypedefChange(changes: ts.textChanges.ChangeTracker, file: ts.SourceFile, name: string, info: ExtractInfo) { const { firstStatement, selection, typeParameters } = info; - setEmitFlags(selection, EmitFlags.NoComments | EmitFlags.NoNestedComments); - - const node = factory.createJSDocTypedefTag( - factory.createIdentifier("typedef"), - factory.createJSDocTypeExpression(selection), - factory.createIdentifier(name)); - - const templates: JSDocTemplateTag[] = []; - forEach(typeParameters, typeParameter => { - const constraint = getEffectiveConstraintOfTypeParameter(typeParameter); - const parameter = factory.createTypeParameterDeclaration(/*modifiers*/ undefined, typeParameter.name); - const template = factory.createJSDocTemplateTag( - factory.createIdentifier("template"), - constraint && cast(constraint, isJSDocTypeExpression), - [parameter] - ); + ts.setEmitFlags(selection, ts.EmitFlags.NoComments | ts.EmitFlags.NoNestedComments); + const node = ts.factory.createJSDocTypedefTag(ts.factory.createIdentifier("typedef"), ts.factory.createJSDocTypeExpression(selection), ts.factory.createIdentifier(name)); + const templates: ts.JSDocTemplateTag[] = []; + ts.forEach(typeParameters, typeParameter => { + const constraint = ts.getEffectiveConstraintOfTypeParameter(typeParameter); + const parameter = ts.factory.createTypeParameterDeclaration(/*modifiers*/ undefined, typeParameter.name); + const template = ts.factory.createJSDocTemplateTag(ts.factory.createIdentifier("template"), constraint && ts.cast(constraint, ts.isJSDocTypeExpression), [parameter]); templates.push(template); }); - changes.insertNodeBefore(file, firstStatement, factory.createJSDocComment(/* comment */ undefined, factory.createNodeArray(concatenate(templates, [node]))), /* blankLineBetween */ true); - changes.replaceNode(file, selection, factory.createTypeReferenceNode(name, typeParameters.map(id => factory.createTypeReferenceNode(id.name, /* typeArguments */ undefined)))); + changes.insertNodeBefore(file, firstStatement, ts.factory.createJSDocComment(/* comment */ undefined, ts.factory.createNodeArray(ts.concatenate(templates, [node]))), /* blankLineBetween */ true); + changes.replaceNode(file, selection, ts.factory.createTypeReferenceNode(name, typeParameters.map(id => ts.factory.createTypeReferenceNode(id.name, /* typeArguments */ undefined)))); } } diff --git a/src/services/refactors/generateGetAccessorAndSetAccessor.ts b/src/services/refactors/generateGetAccessorAndSetAccessor.ts index 70f1da47dfc8e..7c4d4a838cf16 100644 --- a/src/services/refactors/generateGetAccessorAndSetAccessor.ts +++ b/src/services/refactors/generateGetAccessorAndSetAccessor.ts @@ -1,35 +1,38 @@ /* @internal */ namespace ts.refactor.generateGetAccessorAndSetAccessor { const actionName = "Generate 'get' and 'set' accessors"; - const actionDescription = Diagnostics.Generate_get_and_set_accessors.message; + const actionDescription = ts.Diagnostics.Generate_get_and_set_accessors.message; const generateGetSetAction = { name: actionName, description: actionDescription, kind: "refactor.rewrite.property.generateAccessors", }; - registerRefactor(actionName, { + ts.refactor.registerRefactor(actionName, { kinds: [generateGetSetAction.kind], getEditsForAction: function getRefactorActionsToGenerateGetAndSetAccessors(context, actionName) { - if (!context.endPosition) return undefined; - const info = codefix.getAccessorConvertiblePropertyAtPosition(context.file, context.program, context.startPosition, context.endPosition); - Debug.assert(info && !isRefactorErrorInfo(info), "Expected applicable refactor info"); - const edits = codefix.generateAccessorFromProperty(context.file, context.program, context.startPosition, context.endPosition, context, actionName); - if (!edits) return undefined; + if (!context.endPosition) + return undefined; + const info = ts.codefix.getAccessorConvertiblePropertyAtPosition(context.file, context.program, context.startPosition, context.endPosition); + ts.Debug.assert(info && !ts.refactor.isRefactorErrorInfo(info), "Expected applicable refactor info"); + const edits = ts.codefix.generateAccessorFromProperty(context.file, context.program, context.startPosition, context.endPosition, context, actionName); + if (!edits) + return undefined; const renameFilename = context.file.fileName; const nameNeedRename = info.renameAccessor ? info.accessorName : info.fieldName; - const renameLocationOffset = isIdentifier(nameNeedRename) ? 0 : -1; - const renameLocation = renameLocationOffset + getRenameLocation(edits, renameFilename, nameNeedRename.text, /*preferLastLocation*/ isParameter(info.declaration)); + const renameLocationOffset = ts.isIdentifier(nameNeedRename) ? 0 : -1; + const renameLocation = renameLocationOffset + ts.getRenameLocation(edits, renameFilename, nameNeedRename.text, /*preferLastLocation*/ ts.isParameter(info.declaration)); return { renameFilename, renameLocation, edits }; }, - getAvailableActions(context: RefactorContext): readonly ApplicableRefactorInfo[] { - if (!context.endPosition) return emptyArray; - const info = codefix.getAccessorConvertiblePropertyAtPosition(context.file, context.program, context.startPosition, context.endPosition, context.triggerReason === "invoked"); - if (!info) return emptyArray; - - if (!isRefactorErrorInfo(info)) { + getAvailableActions(context: ts.RefactorContext): readonly ts.ApplicableRefactorInfo[] { + if (!context.endPosition) + return ts.emptyArray; + const info = ts.codefix.getAccessorConvertiblePropertyAtPosition(context.file, context.program, context.startPosition, context.endPosition, context.triggerReason === "invoked"); + if (!info) + return ts.emptyArray; + if (!ts.refactor.isRefactorErrorInfo(info)) { return [{ name: actionName, description: actionDescription, @@ -45,7 +48,7 @@ namespace ts.refactor.generateGetAccessorAndSetAccessor { }]; } - return emptyArray; + return ts.emptyArray; } }); } diff --git a/src/services/refactors/helpers.ts b/src/services/refactors/helpers.ts index e86229af915d1..009257fc95bd3 100644 --- a/src/services/refactors/helpers.ts +++ b/src/services/refactors/helpers.ts @@ -5,7 +5,8 @@ namespace ts.refactor { */ export interface RefactorErrorInfo { error: string; - }; + } + ; /** * Checks if some refactor info has refactor error info. @@ -19,7 +20,8 @@ namespace ts.refactor { * Used to match requested kinds with a known kind. */ export function refactorKindBeginsWith(known: string, requested: string | undefined): boolean { - if(!requested) return true; + if (!requested) + return true; return known.substr(0, requested.length) === requested; } } diff --git a/src/services/refactors/inferFunctionReturnType.ts b/src/services/refactors/inferFunctionReturnType.ts index f2e4a8f66edc1..7095bd377f70b 100644 --- a/src/services/refactors/inferFunctionReturnType.ts +++ b/src/services/refactors/inferFunctionReturnType.ts @@ -1,32 +1,33 @@ /* @internal */ namespace ts.refactor.inferFunctionReturnType { const refactorName = "Infer function return type"; - const refactorDescription = Diagnostics.Infer_function_return_type.message; + const refactorDescription = ts.Diagnostics.Infer_function_return_type.message; const inferReturnTypeAction = { name: refactorName, description: refactorDescription, kind: "refactor.rewrite.function.returnType" }; - registerRefactor(refactorName, { + ts.refactor.registerRefactor(refactorName, { kinds: [inferReturnTypeAction.kind], getEditsForAction: getRefactorEditsToInferReturnType, getAvailableActions: getRefactorActionsToInferReturnType }); - function getRefactorEditsToInferReturnType(context: RefactorContext): RefactorEditInfo | undefined { + function getRefactorEditsToInferReturnType(context: ts.RefactorContext): ts.RefactorEditInfo | undefined { const info = getInfo(context); - if (info && !isRefactorErrorInfo(info)) { - const edits = textChanges.ChangeTracker.with(context, t => doChange(context.file, t, info.declaration, info.returnTypeNode)); + if (info && !ts.refactor.isRefactorErrorInfo(info)) { + const edits = ts.textChanges.ChangeTracker.with(context, t => doChange(context.file, t, info.declaration, info.returnTypeNode)); return { renameFilename: undefined, renameLocation: undefined, edits }; } return undefined; } - function getRefactorActionsToInferReturnType(context: RefactorContext): readonly ApplicableRefactorInfo[] { + function getRefactorActionsToInferReturnType(context: ts.RefactorContext): readonly ts.ApplicableRefactorInfo[] { const info = getInfo(context); - if (!info) return emptyArray; - if (!isRefactorErrorInfo(info)) { + if (!info) + return ts.emptyArray; + if (!ts.refactor.isRefactorErrorInfo(info)) { return [{ name: refactorName, description: refactorDescription, @@ -40,73 +41,68 @@ namespace ts.refactor.inferFunctionReturnType { actions: [{ ...inferReturnTypeAction, notApplicableReason: info.error }] }]; } - return emptyArray; + return ts.emptyArray; } - type ConvertibleDeclaration = - | FunctionDeclaration - | FunctionExpression - | ArrowFunction - | MethodDeclaration; + type ConvertibleDeclaration = ts.FunctionDeclaration | ts.FunctionExpression | ts.ArrowFunction | ts.MethodDeclaration; interface FunctionInfo { declaration: ConvertibleDeclaration; - returnTypeNode: TypeNode; + returnTypeNode: ts.TypeNode; } - function doChange(sourceFile: SourceFile, changes: textChanges.ChangeTracker, declaration: ConvertibleDeclaration, typeNode: TypeNode) { - const closeParen = findChildOfKind(declaration, SyntaxKind.CloseParenToken, sourceFile); - const needParens = isArrowFunction(declaration) && closeParen === undefined; - const endNode = needParens ? first(declaration.parameters) : closeParen; + function doChange(sourceFile: ts.SourceFile, changes: ts.textChanges.ChangeTracker, declaration: ConvertibleDeclaration, typeNode: ts.TypeNode) { + const closeParen = ts.findChildOfKind(declaration, ts.SyntaxKind.CloseParenToken, sourceFile); + const needParens = ts.isArrowFunction(declaration) && closeParen === undefined; + const endNode = needParens ? ts.first(declaration.parameters) : closeParen; if (endNode) { if (needParens) { - changes.insertNodeBefore(sourceFile, endNode, factory.createToken(SyntaxKind.OpenParenToken)); - changes.insertNodeAfter(sourceFile, endNode, factory.createToken(SyntaxKind.CloseParenToken)); + changes.insertNodeBefore(sourceFile, endNode, ts.factory.createToken(ts.SyntaxKind.OpenParenToken)); + changes.insertNodeAfter(sourceFile, endNode, ts.factory.createToken(ts.SyntaxKind.CloseParenToken)); } changes.insertNodeAt(sourceFile, endNode.end, typeNode, { prefix: ": " }); } } - function getInfo(context: RefactorContext): FunctionInfo | RefactorErrorInfo | undefined { - if (isInJSFile(context.file) || !refactorKindBeginsWith(inferReturnTypeAction.kind, context.kind)) return; - - const token = getTokenAtPosition(context.file, context.startPosition); - const declaration = findAncestor(token, n => - isBlock(n) || n.parent && isArrowFunction(n.parent) && (n.kind === SyntaxKind.EqualsGreaterThanToken || n.parent.body === n) ? "quit" : + function getInfo(context: ts.RefactorContext): FunctionInfo | ts.refactor.RefactorErrorInfo | undefined { + if (ts.isInJSFile(context.file) || !ts.refactor.refactorKindBeginsWith(inferReturnTypeAction.kind, context.kind)) + return; + const token = ts.getTokenAtPosition(context.file, context.startPosition); + const declaration = ts.findAncestor(token, n => ts.isBlock(n) || n.parent && ts.isArrowFunction(n.parent) && (n.kind === ts.SyntaxKind.EqualsGreaterThanToken || n.parent.body === n) ? "quit" : isConvertibleDeclaration(n)) as ConvertibleDeclaration | undefined; if (!declaration || !declaration.body || declaration.type) { - return { error: getLocaleSpecificMessage(Diagnostics.Return_type_must_be_inferred_from_a_function) }; + return { error: ts.getLocaleSpecificMessage(ts.Diagnostics.Return_type_must_be_inferred_from_a_function) }; } const typeChecker = context.program.getTypeChecker(); const returnType = tryGetReturnType(typeChecker, declaration); if (!returnType) { - return { error: getLocaleSpecificMessage(Diagnostics.Could_not_determine_function_return_type) }; + return { error: ts.getLocaleSpecificMessage(ts.Diagnostics.Could_not_determine_function_return_type) }; } - const returnTypeNode = typeChecker.typeToTypeNode(returnType, declaration, NodeBuilderFlags.NoTruncation); + const returnTypeNode = typeChecker.typeToTypeNode(returnType, declaration, ts.NodeBuilderFlags.NoTruncation); if (returnTypeNode) { return { declaration, returnTypeNode }; } } - function isConvertibleDeclaration(node: Node): node is ConvertibleDeclaration { + function isConvertibleDeclaration(node: ts.Node): node is ConvertibleDeclaration { switch (node.kind) { - case SyntaxKind.FunctionDeclaration: - case SyntaxKind.FunctionExpression: - case SyntaxKind.ArrowFunction: - case SyntaxKind.MethodDeclaration: + case ts.SyntaxKind.FunctionDeclaration: + case ts.SyntaxKind.FunctionExpression: + case ts.SyntaxKind.ArrowFunction: + case ts.SyntaxKind.MethodDeclaration: return true; default: return false; } } - function tryGetReturnType(typeChecker: TypeChecker, node: ConvertibleDeclaration): Type | undefined { + function tryGetReturnType(typeChecker: ts.TypeChecker, node: ConvertibleDeclaration): ts.Type | undefined { if (typeChecker.isImplementationOfOverload(node)) { const signatures = typeChecker.getTypeAtLocation(node).getCallSignatures(); if (signatures.length > 1) { - return typeChecker.getUnionType(mapDefined(signatures, s => s.getReturnType())); + return typeChecker.getUnionType(ts.mapDefined(signatures, s => s.getReturnType())); } } const signature = typeChecker.getSignatureFromDeclaration(node); diff --git a/src/services/refactors/moveToNewFile.ts b/src/services/refactors/moveToNewFile.ts index 2e96d5aa95b4f..9315693067484 100644 --- a/src/services/refactors/moveToNewFile.ts +++ b/src/services/refactors/moveToNewFile.ts @@ -1,54 +1,59 @@ /* @internal */ namespace ts.refactor { const refactorName = "Move to a new file"; - const description = getLocaleSpecificMessage(Diagnostics.Move_to_a_new_file); + const description = ts.getLocaleSpecificMessage(ts.Diagnostics.Move_to_a_new_file); const moveToNewFileAction = { name: refactorName, description, kind: "refactor.move.newFile", }; - registerRefactor(refactorName, { + ts.refactor.registerRefactor(refactorName, { kinds: [moveToNewFileAction.kind], - getAvailableActions: function getRefactorActionsToMoveToNewFile(context): readonly ApplicableRefactorInfo[] { + getAvailableActions: function getRefactorActionsToMoveToNewFile(context): readonly ts.ApplicableRefactorInfo[] { const statements = getStatementsToMove(context); if (context.preferences.allowTextChangesInNewFiles && statements) { return [{ name: refactorName, description, actions: [moveToNewFileAction] }]; } if (context.preferences.provideRefactorNotApplicableReason) { - return [{ name: refactorName, description, actions: - [{ ...moveToNewFileAction, notApplicableReason: getLocaleSpecificMessage(Diagnostics.Selection_is_not_a_valid_statement_or_statements) }] + return [{ name: refactorName, description, actions: [{ ...moveToNewFileAction, notApplicableReason: ts.getLocaleSpecificMessage(ts.Diagnostics.Selection_is_not_a_valid_statement_or_statements) }] }]; } - return emptyArray; + return ts.emptyArray; }, - getEditsForAction: function getRefactorEditsToMoveToNewFile(context, actionName): RefactorEditInfo { - Debug.assert(actionName === refactorName, "Wrong refactor invoked"); - const statements = Debug.checkDefined(getStatementsToMove(context)); - const edits = textChanges.ChangeTracker.with(context, t => doChange(context.file, context.program, statements, t, context.host, context.preferences)); + getEditsForAction: function getRefactorEditsToMoveToNewFile(context, actionName): ts.RefactorEditInfo { + ts.Debug.assert(actionName === refactorName, "Wrong refactor invoked"); + const statements = ts.Debug.checkDefined(getStatementsToMove(context)); + const edits = ts.textChanges.ChangeTracker.with(context, t => doChange(context.file, context.program, statements, t, context.host, context.preferences)); return { edits, renameFilename: undefined, renameLocation: undefined }; } }); - interface RangeToMove { readonly toMove: readonly Statement[]; readonly afterLast: Statement | undefined; } - function getRangeToMove(context: RefactorContext): RangeToMove | undefined { + interface RangeToMove { + readonly toMove: readonly ts.Statement[]; + readonly afterLast: ts.Statement | undefined; + } + function getRangeToMove(context: ts.RefactorContext): RangeToMove | undefined { const { file } = context; - const range = createTextRangeFromSpan(getRefactorContextSpan(context)); + const range = ts.createTextRangeFromSpan(ts.getRefactorContextSpan(context)); const { statements } = file; - const startNodeIndex = findIndex(statements, s => s.end > range.pos); - if (startNodeIndex === -1) return undefined; + const startNodeIndex = ts.findIndex(statements, s => s.end > range.pos); + if (startNodeIndex === -1) + return undefined; const startStatement = statements[startNodeIndex]; - if (isNamedDeclaration(startStatement) && startStatement.name && rangeContainsRange(startStatement.name, range)) { + if (ts.isNamedDeclaration(startStatement) && startStatement.name && ts.rangeContainsRange(startStatement.name, range)) { return { toMove: [statements[startNodeIndex]], afterLast: statements[startNodeIndex + 1] }; } // Can't only partially include the start node or be partially into the next node - if (range.pos > startStatement.getStart(file)) return undefined; - const afterEndNodeIndex = findIndex(statements, s => s.end > range.end, startNodeIndex); + if (range.pos > startStatement.getStart(file)) + return undefined; + const afterEndNodeIndex = ts.findIndex(statements, s => s.end > range.end, startNodeIndex); // Can't be partially into the next node - if (afterEndNodeIndex !== -1 && (afterEndNodeIndex === 0 || statements[afterEndNodeIndex].getStart(file) < range.end)) return undefined; + if (afterEndNodeIndex !== -1 && (afterEndNodeIndex === 0 || statements[afterEndNodeIndex].getStart(file) < range.end)) + return undefined; return { toMove: statements.slice(startNodeIndex, afterEndNodeIndex === -1 ? statements.length : afterEndNodeIndex), @@ -56,93 +61,90 @@ namespace ts.refactor { }; } - function doChange(oldFile: SourceFile, program: Program, toMove: ToMove, changes: textChanges.ChangeTracker, host: LanguageServiceHost, preferences: UserPreferences): void { + function doChange(oldFile: ts.SourceFile, program: ts.Program, toMove: ToMove, changes: ts.textChanges.ChangeTracker, host: ts.LanguageServiceHost, preferences: ts.UserPreferences): void { const checker = program.getTypeChecker(); const usage = getUsageInfo(oldFile, toMove.all, checker); - const currentDirectory = getDirectoryPath(oldFile.fileName); - const extension = extensionFromPath(oldFile.fileName); + const currentDirectory = ts.getDirectoryPath(oldFile.fileName); + const extension = ts.extensionFromPath(oldFile.fileName); const newModuleName = makeUniqueModuleName(getNewModuleName(usage.movedSymbols), extension, currentDirectory, host); const newFileNameWithExtension = newModuleName + extension; // If previous file was global, this is easy. - changes.createNewFile(oldFile, combinePaths(currentDirectory, newFileNameWithExtension), getNewStatementsAndRemoveFromOldFile(oldFile, usage, changes, toMove, program, newModuleName, preferences)); - - addNewFileToTsconfig(program, changes, oldFile.fileName, newFileNameWithExtension, hostGetCanonicalFileName(host)); + changes.createNewFile(oldFile, ts.combinePaths(currentDirectory, newFileNameWithExtension), getNewStatementsAndRemoveFromOldFile(oldFile, usage, changes, toMove, program, newModuleName, preferences)); + addNewFileToTsconfig(program, changes, oldFile.fileName, newFileNameWithExtension, ts.hostGetCanonicalFileName(host)); } interface StatementRange { - readonly first: Statement; - readonly afterLast: Statement | undefined; + readonly first: ts.Statement; + readonly afterLast: ts.Statement | undefined; } interface ToMove { - readonly all: readonly Statement[]; + readonly all: readonly ts.Statement[]; readonly ranges: readonly StatementRange[]; } - function getStatementsToMove(context: RefactorContext): ToMove | undefined { + function getStatementsToMove(context: ts.RefactorContext): ToMove | undefined { const rangeToMove = getRangeToMove(context); - if (rangeToMove === undefined) return undefined; - const all: Statement[] = []; + if (rangeToMove === undefined) + return undefined; + const all: ts.Statement[] = []; const ranges: StatementRange[] = []; const { toMove, afterLast } = rangeToMove; - getRangesWhere(toMove, isAllowedStatementToMove, (start, afterEndIndex) => { - for (let i = start; i < afterEndIndex; i++) all.push(toMove[i]); + ts.getRangesWhere(toMove, isAllowedStatementToMove, (start, afterEndIndex) => { + for (let i = start; i < afterEndIndex; i++) + all.push(toMove[i]); ranges.push({ first: toMove[start], afterLast }); }); return all.length === 0 ? undefined : { all, ranges }; } - function isAllowedStatementToMove(statement: Statement): boolean { + function isAllowedStatementToMove(statement: ts.Statement): boolean { // Filters imports and prologue directives out of the range of statements to move. // Imports will be copied to the new file anyway, and may still be needed in the old file. // Prologue directives will be copied to the new file and should be left in the old file. - return !isPureImport(statement) && !isPrologueDirective(statement);; + return !isPureImport(statement) && !ts.isPrologueDirective(statement); + ; } - function isPureImport(node: Node): boolean { + function isPureImport(node: ts.Node): boolean { switch (node.kind) { - case SyntaxKind.ImportDeclaration: + case ts.SyntaxKind.ImportDeclaration: return true; - case SyntaxKind.ImportEqualsDeclaration: - return !hasSyntacticModifier(node, ModifierFlags.Export); - case SyntaxKind.VariableStatement: - return (node as VariableStatement).declarationList.declarations.every(d => !!d.initializer && isRequireCall(d.initializer, /*checkArgumentIsStringLiteralLike*/ true)); + case ts.SyntaxKind.ImportEqualsDeclaration: + return !ts.hasSyntacticModifier(node, ts.ModifierFlags.Export); + case ts.SyntaxKind.VariableStatement: + return (node as ts.VariableStatement).declarationList.declarations.every(d => !!d.initializer && ts.isRequireCall(d.initializer, /*checkArgumentIsStringLiteralLike*/ true)); default: return false; } } - function addNewFileToTsconfig(program: Program, changes: textChanges.ChangeTracker, oldFileName: string, newFileNameWithExtension: string, getCanonicalFileName: GetCanonicalFileName): void { + function addNewFileToTsconfig(program: ts.Program, changes: ts.textChanges.ChangeTracker, oldFileName: string, newFileNameWithExtension: string, getCanonicalFileName: ts.GetCanonicalFileName): void { const cfg = program.getCompilerOptions().configFile; - if (!cfg) return; - - const newFileAbsolutePath = normalizePath(combinePaths(oldFileName, "..", newFileNameWithExtension)); - const newFilePath = getRelativePathFromFile(cfg.fileName, newFileAbsolutePath, getCanonicalFileName); - - const cfgObject = cfg.statements[0] && tryCast(cfg.statements[0].expression, isObjectLiteralExpression); - const filesProp = cfgObject && find(cfgObject.properties, (prop): prop is PropertyAssignment => - isPropertyAssignment(prop) && isStringLiteral(prop.name) && prop.name.text === "files"); - if (filesProp && isArrayLiteralExpression(filesProp.initializer)) { - changes.insertNodeInListAfter(cfg, last(filesProp.initializer.elements), factory.createStringLiteral(newFilePath), filesProp.initializer.elements); + if (!cfg) + return; + const newFileAbsolutePath = ts.normalizePath(ts.combinePaths(oldFileName, "..", newFileNameWithExtension)); + const newFilePath = ts.getRelativePathFromFile(cfg.fileName, newFileAbsolutePath, getCanonicalFileName); + const cfgObject = cfg.statements[0] && ts.tryCast(cfg.statements[0].expression, ts.isObjectLiteralExpression); + const filesProp = cfgObject && ts.find(cfgObject.properties, (prop): prop is ts.PropertyAssignment => ts.isPropertyAssignment(prop) && ts.isStringLiteral(prop.name) && prop.name.text === "files"); + if (filesProp && ts.isArrayLiteralExpression(filesProp.initializer)) { + changes.insertNodeInListAfter(cfg, ts.last(filesProp.initializer.elements), ts.factory.createStringLiteral(newFilePath), filesProp.initializer.elements); } } - - function getNewStatementsAndRemoveFromOldFile( - oldFile: SourceFile, usage: UsageInfo, changes: textChanges.ChangeTracker, toMove: ToMove, program: Program, newModuleName: string, preferences: UserPreferences, - ) { + function getNewStatementsAndRemoveFromOldFile(oldFile: ts.SourceFile, usage: UsageInfo, changes: ts.textChanges.ChangeTracker, toMove: ToMove, program: ts.Program, newModuleName: string, preferences: ts.UserPreferences) { const checker = program.getTypeChecker(); - const prologueDirectives = takeWhile(oldFile.statements, isPrologueDirective); + const prologueDirectives = ts.takeWhile(oldFile.statements, ts.isPrologueDirective); if (!oldFile.externalModuleIndicator && !oldFile.commonJsModuleIndicator) { deleteMovedStatements(oldFile, toMove.ranges, changes); return [...prologueDirectives, ...toMove.all]; } const useEsModuleSyntax = !!oldFile.externalModuleIndicator; - const quotePreference = getQuotePreference(oldFile, preferences); + const quotePreference = ts.getQuotePreference(oldFile, preferences); const importsFromNewFile = createOldFileImportsFromNewFile(usage.oldFileImportsFromNewFile, newModuleName, useEsModuleSyntax, quotePreference); if (importsFromNewFile) { - insertImports(changes, oldFile, importsFromNewFile, /*blankLineBetween*/ true); + ts.insertImports(changes, oldFile, importsFromNewFile, /*blankLineBetween*/ true); } deleteUnusedOldImports(oldFile, toMove.all, changes, usage.unusedImportsFromOldFile, checker); @@ -155,7 +157,7 @@ namespace ts.refactor { return [ ...prologueDirectives, ...imports, - SyntaxKind.NewLineTrivia as const, + ts.SyntaxKind.NewLineTrivia as const, ...body ]; } @@ -167,147 +169,142 @@ namespace ts.refactor { ]; } - function deleteMovedStatements(sourceFile: SourceFile, moved: readonly StatementRange[], changes: textChanges.ChangeTracker) { + function deleteMovedStatements(sourceFile: ts.SourceFile, moved: readonly StatementRange[], changes: ts.textChanges.ChangeTracker) { for (const { first, afterLast } of moved) { changes.deleteNodeRangeExcludingEnd(sourceFile, first, afterLast); } } - function deleteUnusedOldImports(oldFile: SourceFile, toMove: readonly Statement[], changes: textChanges.ChangeTracker, toDelete: ReadonlySymbolSet, checker: TypeChecker) { + function deleteUnusedOldImports(oldFile: ts.SourceFile, toMove: readonly ts.Statement[], changes: ts.textChanges.ChangeTracker, toDelete: ReadonlySymbolSet, checker: ts.TypeChecker) { for (const statement of oldFile.statements) { - if (contains(toMove, statement)) continue; + if (ts.contains(toMove, statement)) + continue; forEachImportInStatement(statement, i => deleteUnusedImports(oldFile, i, changes, name => toDelete.has(checker.getSymbolAtLocation(name)!))); } } - function updateImportsInOtherFiles(changes: textChanges.ChangeTracker, program: Program, oldFile: SourceFile, movedSymbols: ReadonlySymbolSet, newModuleName: string): void { + function updateImportsInOtherFiles(changes: ts.textChanges.ChangeTracker, program: ts.Program, oldFile: ts.SourceFile, movedSymbols: ReadonlySymbolSet, newModuleName: string): void { const checker = program.getTypeChecker(); for (const sourceFile of program.getSourceFiles()) { - if (sourceFile === oldFile) continue; + if (sourceFile === oldFile) + continue; for (const statement of sourceFile.statements) { forEachImportInStatement(statement, importNode => { - if (checker.getSymbolAtLocation(moduleSpecifierFromImport(importNode)) !== oldFile.symbol) return; - - const shouldMove = (name: Identifier): boolean => { - const symbol = isBindingElement(name.parent) - ? getPropertySymbolFromBindingElement(checker, name.parent as ObjectBindingElementWithoutPropertyName) - : skipAlias(checker.getSymbolAtLocation(name)!, checker); // TODO: GH#18217 + if (checker.getSymbolAtLocation(moduleSpecifierFromImport(importNode)) !== oldFile.symbol) + return; + const shouldMove = (name: ts.Identifier): boolean => { + const symbol = ts.isBindingElement(name.parent) + ? ts.getPropertySymbolFromBindingElement(checker, name.parent as ts.ObjectBindingElementWithoutPropertyName) + : ts.skipAlias(checker.getSymbolAtLocation(name)!, checker); // TODO: GH#18217 return !!symbol && movedSymbols.has(symbol); }; deleteUnusedImports(sourceFile, importNode, changes, shouldMove); // These will be changed to imports from the new file - const newModuleSpecifier = combinePaths(getDirectoryPath(moduleSpecifierFromImport(importNode).text), newModuleName); - const newImportDeclaration = filterImport(importNode, factory.createStringLiteral(newModuleSpecifier), shouldMove); - if (newImportDeclaration) changes.insertNodeAfter(sourceFile, statement, newImportDeclaration); + const newModuleSpecifier = ts.combinePaths(ts.getDirectoryPath(moduleSpecifierFromImport(importNode).text), newModuleName); + const newImportDeclaration = filterImport(importNode, ts.factory.createStringLiteral(newModuleSpecifier), shouldMove); + if (newImportDeclaration) + changes.insertNodeAfter(sourceFile, statement, newImportDeclaration); const ns = getNamespaceLikeImport(importNode); - if (ns) updateNamespaceLikeImport(changes, sourceFile, checker, movedSymbols, newModuleName, newModuleSpecifier, ns, importNode); + if (ns) + updateNamespaceLikeImport(changes, sourceFile, checker, movedSymbols, newModuleName, newModuleSpecifier, ns, importNode); }); } } } - function getNamespaceLikeImport(node: SupportedImport): Identifier | undefined { + function getNamespaceLikeImport(node: SupportedImport): ts.Identifier | undefined { switch (node.kind) { - case SyntaxKind.ImportDeclaration: - return node.importClause && node.importClause.namedBindings && node.importClause.namedBindings.kind === SyntaxKind.NamespaceImport ? + case ts.SyntaxKind.ImportDeclaration: + return node.importClause && node.importClause.namedBindings && node.importClause.namedBindings.kind === ts.SyntaxKind.NamespaceImport ? node.importClause.namedBindings.name : undefined; - case SyntaxKind.ImportEqualsDeclaration: + case ts.SyntaxKind.ImportEqualsDeclaration: return node.name; - case SyntaxKind.VariableDeclaration: - return tryCast(node.name, isIdentifier); + case ts.SyntaxKind.VariableDeclaration: + return ts.tryCast(node.name, ts.isIdentifier); default: - return Debug.assertNever(node, `Unexpected node kind ${(node as SupportedImport).kind}`); + return ts.Debug.assertNever(node, `Unexpected node kind ${(node as SupportedImport).kind}`); } } - - function updateNamespaceLikeImport( - changes: textChanges.ChangeTracker, - sourceFile: SourceFile, - checker: TypeChecker, - movedSymbols: ReadonlySymbolSet, - newModuleName: string, - newModuleSpecifier: string, - oldImportId: Identifier, - oldImportNode: SupportedImport, - ): void { - const preferredNewNamespaceName = codefix.moduleSpecifierToValidIdentifier(newModuleName, ScriptTarget.ESNext); + function updateNamespaceLikeImport(changes: ts.textChanges.ChangeTracker, sourceFile: ts.SourceFile, checker: ts.TypeChecker, movedSymbols: ReadonlySymbolSet, newModuleName: string, newModuleSpecifier: string, oldImportId: ts.Identifier, oldImportNode: SupportedImport): void { + const preferredNewNamespaceName = ts.codefix.moduleSpecifierToValidIdentifier(newModuleName, ts.ScriptTarget.ESNext); let needUniqueName = false; - const toChange: Identifier[] = []; - FindAllReferences.Core.eachSymbolReferenceInFile(oldImportId, checker, sourceFile, ref => { - if (!isPropertyAccessExpression(ref.parent)) return; - needUniqueName = needUniqueName || !!checker.resolveName(preferredNewNamespaceName, ref, SymbolFlags.All, /*excludeGlobals*/ true); + const toChange: ts.Identifier[] = []; + ts.FindAllReferences.Core.eachSymbolReferenceInFile(oldImportId, checker, sourceFile, ref => { + if (!ts.isPropertyAccessExpression(ref.parent)) + return; + needUniqueName = needUniqueName || !!checker.resolveName(preferredNewNamespaceName, ref, ts.SymbolFlags.All, /*excludeGlobals*/ true); if (movedSymbols.has(checker.getSymbolAtLocation(ref.parent.name)!)) { toChange.push(ref); } }); if (toChange.length) { - const newNamespaceName = needUniqueName ? getUniqueName(preferredNewNamespaceName, sourceFile) : preferredNewNamespaceName; + const newNamespaceName = needUniqueName ? ts.getUniqueName(preferredNewNamespaceName, sourceFile) : preferredNewNamespaceName; for (const ref of toChange) { - changes.replaceNode(sourceFile, ref, factory.createIdentifier(newNamespaceName)); + changes.replaceNode(sourceFile, ref, ts.factory.createIdentifier(newNamespaceName)); } changes.insertNodeAfter(sourceFile, oldImportNode, updateNamespaceLikeImportNode(oldImportNode, newModuleName, newModuleSpecifier)); } } - function updateNamespaceLikeImportNode(node: SupportedImport, newNamespaceName: string, newModuleSpecifier: string): Node { - const newNamespaceId = factory.createIdentifier(newNamespaceName); - const newModuleString = factory.createStringLiteral(newModuleSpecifier); + function updateNamespaceLikeImportNode(node: SupportedImport, newNamespaceName: string, newModuleSpecifier: string): ts.Node { + const newNamespaceId = ts.factory.createIdentifier(newNamespaceName); + const newModuleString = ts.factory.createStringLiteral(newModuleSpecifier); switch (node.kind) { - case SyntaxKind.ImportDeclaration: - return factory.createImportDeclaration( - /*decorators*/ undefined, /*modifiers*/ undefined, - factory.createImportClause(/*isTypeOnly*/ false, /*name*/ undefined, factory.createNamespaceImport(newNamespaceId)), - newModuleString, + case ts.SyntaxKind.ImportDeclaration: + return ts.factory.createImportDeclaration( + /*decorators*/ undefined, /*modifiers*/ undefined, ts.factory.createImportClause(/*isTypeOnly*/ false, /*name*/ undefined, ts.factory.createNamespaceImport(newNamespaceId)), newModuleString, /*assertClause*/ undefined); - case SyntaxKind.ImportEqualsDeclaration: - return factory.createImportEqualsDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, /*isTypeOnly*/ false, newNamespaceId, factory.createExternalModuleReference(newModuleString)); - case SyntaxKind.VariableDeclaration: - return factory.createVariableDeclaration(newNamespaceId, /*exclamationToken*/ undefined, /*type*/ undefined, createRequireCall(newModuleString)); + case ts.SyntaxKind.ImportEqualsDeclaration: + return ts.factory.createImportEqualsDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, /*isTypeOnly*/ false, newNamespaceId, ts.factory.createExternalModuleReference(newModuleString)); + case ts.SyntaxKind.VariableDeclaration: + return ts.factory.createVariableDeclaration(newNamespaceId, /*exclamationToken*/ undefined, /*type*/ undefined, createRequireCall(newModuleString)); default: - return Debug.assertNever(node, `Unexpected node kind ${(node as SupportedImport).kind}`); + return ts.Debug.assertNever(node, `Unexpected node kind ${(node as SupportedImport).kind}`); } } - function moduleSpecifierFromImport(i: SupportedImport): StringLiteralLike { - return (i.kind === SyntaxKind.ImportDeclaration ? i.moduleSpecifier - : i.kind === SyntaxKind.ImportEqualsDeclaration ? i.moduleReference.expression + function moduleSpecifierFromImport(i: SupportedImport): ts.StringLiteralLike { + return (i.kind === ts.SyntaxKind.ImportDeclaration ? i.moduleSpecifier + : i.kind === ts.SyntaxKind.ImportEqualsDeclaration ? i.moduleReference.expression : i.initializer.arguments[0]); } - function forEachImportInStatement(statement: Statement, cb: (importNode: SupportedImport) => void): void { - if (isImportDeclaration(statement)) { - if (isStringLiteral(statement.moduleSpecifier)) cb(statement as SupportedImport); + function forEachImportInStatement(statement: ts.Statement, cb: (importNode: SupportedImport) => void): void { + if (ts.isImportDeclaration(statement)) { + if (ts.isStringLiteral(statement.moduleSpecifier)) + cb(statement as SupportedImport); } - else if (isImportEqualsDeclaration(statement)) { - if (isExternalModuleReference(statement.moduleReference) && isStringLiteralLike(statement.moduleReference.expression)) { + else if (ts.isImportEqualsDeclaration(statement)) { + if (ts.isExternalModuleReference(statement.moduleReference) && ts.isStringLiteralLike(statement.moduleReference.expression)) { cb(statement as SupportedImport); } } - else if (isVariableStatement(statement)) { + else if (ts.isVariableStatement(statement)) { for (const decl of statement.declarationList.declarations) { - if (decl.initializer && isRequireCall(decl.initializer, /*checkArgumentIsStringLiteralLike*/ true)) { + if (decl.initializer && ts.isRequireCall(decl.initializer, /*checkArgumentIsStringLiteralLike*/ true)) { cb(decl as SupportedImport); } } } } - type SupportedImport = - | ImportDeclaration & { moduleSpecifier: StringLiteralLike } - | ImportEqualsDeclaration & { moduleReference: ExternalModuleReference & { expression: StringLiteralLike } } - | VariableDeclaration & { initializer: RequireOrImportCall }; - type SupportedImportStatement = - | ImportDeclaration - | ImportEqualsDeclaration - | VariableStatement; - - function createOldFileImportsFromNewFile(newFileNeedExport: ReadonlySymbolSet, newFileNameWithExtension: string, useEs6Imports: boolean, quotePreference: QuotePreference): AnyImportOrRequireStatement | undefined { - let defaultImport: Identifier | undefined; + type SupportedImport = (ts.ImportDeclaration & { + moduleSpecifier: ts.StringLiteralLike; + }) | (ts.ImportEqualsDeclaration & { + moduleReference: ts.ExternalModuleReference & { + expression: ts.StringLiteralLike; + }; + }) | (ts.VariableDeclaration & { + initializer: ts.RequireOrImportCall; + }); + type SupportedImportStatement = ts.ImportDeclaration | ts.ImportEqualsDeclaration | ts.VariableStatement; + function createOldFileImportsFromNewFile(newFileNeedExport: ReadonlySymbolSet, newFileNameWithExtension: string, useEs6Imports: boolean, quotePreference: ts.QuotePreference): ts.AnyImportOrRequireStatement | undefined { + let defaultImport: ts.Identifier | undefined; const imports: string[] = []; newFileNeedExport.forEach(symbol => { - if (symbol.escapedName === InternalSymbolName.Default) { - defaultImport = factory.createIdentifier(symbolNameNoDefault(symbol)!); // TODO: GH#18217 + if (symbol.escapedName === ts.InternalSymbolName.Default) { + defaultImport = ts.factory.createIdentifier(ts.symbolNameNoDefault(symbol)!); // TODO: GH#18217 } else { imports.push(symbol.name); @@ -316,64 +313,66 @@ namespace ts.refactor { return makeImportOrRequire(defaultImport, imports, newFileNameWithExtension, useEs6Imports, quotePreference); } - function makeImportOrRequire(defaultImport: Identifier | undefined, imports: readonly string[], path: string, useEs6Imports: boolean, quotePreference: QuotePreference): AnyImportOrRequireStatement | undefined { - path = ensurePathIsNonModuleName(path); + function makeImportOrRequire(defaultImport: ts.Identifier | undefined, imports: readonly string[], path: string, useEs6Imports: boolean, quotePreference: ts.QuotePreference): ts.AnyImportOrRequireStatement | undefined { + path = ts.ensurePathIsNonModuleName(path); if (useEs6Imports) { - const specifiers = imports.map(i => factory.createImportSpecifier(/*isTypeOnly*/ false, /*propertyName*/ undefined, factory.createIdentifier(i))); - return makeImportIfNecessary(defaultImport, specifiers, path, quotePreference); + const specifiers = imports.map(i => ts.factory.createImportSpecifier(/*isTypeOnly*/ false, /*propertyName*/ undefined, ts.factory.createIdentifier(i))); + return ts.makeImportIfNecessary(defaultImport, specifiers, path, quotePreference); } else { - Debug.assert(!defaultImport, "No default import should exist"); // If there's a default export, it should have been an es6 module. - const bindingElements = imports.map(i => factory.createBindingElement(/*dotDotDotToken*/ undefined, /*propertyName*/ undefined, i)); + ts.Debug.assert(!defaultImport, "No default import should exist"); // If there's a default export, it should have been an es6 module. + const bindingElements = imports.map(i => ts.factory.createBindingElement(/*dotDotDotToken*/ undefined, /*propertyName*/ undefined, i)); return bindingElements.length - ? makeVariableStatement(factory.createObjectBindingPattern(bindingElements), /*type*/ undefined, createRequireCall(factory.createStringLiteral(path))) as RequireVariableStatement + ? makeVariableStatement(ts.factory.createObjectBindingPattern(bindingElements), /*type*/ undefined, createRequireCall(ts.factory.createStringLiteral(path))) as ts.RequireVariableStatement : undefined; } } - function makeVariableStatement(name: BindingName, type: TypeNode | undefined, initializer: Expression | undefined, flags: NodeFlags = NodeFlags.Const) { - return factory.createVariableStatement(/*modifiers*/ undefined, factory.createVariableDeclarationList([factory.createVariableDeclaration(name, /*exclamationToken*/ undefined, type, initializer)], flags)); + function makeVariableStatement(name: ts.BindingName, type: ts.TypeNode | undefined, initializer: ts.Expression | undefined, flags: ts.NodeFlags = ts.NodeFlags.Const) { + return ts.factory.createVariableStatement(/*modifiers*/ undefined, ts.factory.createVariableDeclarationList([ts.factory.createVariableDeclaration(name, /*exclamationToken*/ undefined, type, initializer)], flags)); } - function createRequireCall(moduleSpecifier: StringLiteralLike): CallExpression { - return factory.createCallExpression(factory.createIdentifier("require"), /*typeArguments*/ undefined, [moduleSpecifier]); + function createRequireCall(moduleSpecifier: ts.StringLiteralLike): ts.CallExpression { + return ts.factory.createCallExpression(ts.factory.createIdentifier("require"), /*typeArguments*/ undefined, [moduleSpecifier]); } - function addExports(sourceFile: SourceFile, toMove: readonly Statement[], needExport: ReadonlySymbolSet, useEs6Exports: boolean): readonly Statement[] { - return flatMap(toMove, statement => { + function addExports(sourceFile: ts.SourceFile, toMove: readonly ts.Statement[], needExport: ReadonlySymbolSet, useEs6Exports: boolean): readonly ts.Statement[] { + return ts.flatMap(toMove, statement => { if (isTopLevelDeclarationStatement(statement) && !isExported(sourceFile, statement, useEs6Exports) && - forEachTopLevelDeclaration(statement, d => needExport.has(Debug.checkDefined(d.symbol)))) { + forEachTopLevelDeclaration(statement, d => needExport.has(ts.Debug.checkDefined(d.symbol)))) { const exports = addExport(statement, useEs6Exports); - if (exports) return exports; + if (exports) + return exports; } return statement; }); } - function deleteUnusedImports(sourceFile: SourceFile, importDecl: SupportedImport, changes: textChanges.ChangeTracker, isUnused: (name: Identifier) => boolean): void { + function deleteUnusedImports(sourceFile: ts.SourceFile, importDecl: SupportedImport, changes: ts.textChanges.ChangeTracker, isUnused: (name: ts.Identifier) => boolean): void { switch (importDecl.kind) { - case SyntaxKind.ImportDeclaration: + case ts.SyntaxKind.ImportDeclaration: deleteUnusedImportsInDeclaration(sourceFile, importDecl, changes, isUnused); break; - case SyntaxKind.ImportEqualsDeclaration: + case ts.SyntaxKind.ImportEqualsDeclaration: if (isUnused(importDecl.name)) { changes.delete(sourceFile, importDecl); } break; - case SyntaxKind.VariableDeclaration: + case ts.SyntaxKind.VariableDeclaration: deleteUnusedImportsInVariableDeclaration(sourceFile, importDecl, changes, isUnused); break; default: - Debug.assertNever(importDecl, `Unexpected import decl kind ${(importDecl as SupportedImport).kind}`); + ts.Debug.assertNever(importDecl, `Unexpected import decl kind ${(importDecl as SupportedImport).kind}`); } } - function deleteUnusedImportsInDeclaration(sourceFile: SourceFile, importDecl: ImportDeclaration, changes: textChanges.ChangeTracker, isUnused: (name: Identifier) => boolean): void { - if (!importDecl.importClause) return; + function deleteUnusedImportsInDeclaration(sourceFile: ts.SourceFile, importDecl: ts.ImportDeclaration, changes: ts.textChanges.ChangeTracker, isUnused: (name: ts.Identifier) => boolean): void { + if (!importDecl.importClause) + return; const { name, namedBindings } = importDecl.importClause; const defaultUnused = !name || isUnused(name); const namedBindingsUnused = !namedBindings || - (namedBindings.kind === SyntaxKind.NamespaceImport ? isUnused(namedBindings.name) : namedBindings.elements.length !== 0 && namedBindings.elements.every(e => isUnused(e.name))); + (namedBindings.kind === ts.SyntaxKind.NamespaceImport ? isUnused(namedBindings.name) : namedBindings.elements.length !== 0 && namedBindings.elements.every(e => isUnused(e.name))); if (defaultUnused && namedBindingsUnused) { changes.delete(sourceFile, importDecl); } @@ -383,38 +382,34 @@ namespace ts.refactor { } if (namedBindings) { if (namedBindingsUnused) { - changes.replaceNode( - sourceFile, - importDecl.importClause, - factory.updateImportClause(importDecl.importClause, importDecl.importClause.isTypeOnly, name, /*namedBindings*/ undefined) - ); + changes.replaceNode(sourceFile, importDecl.importClause, ts.factory.updateImportClause(importDecl.importClause, importDecl.importClause.isTypeOnly, name, /*namedBindings*/ undefined)); } - else if (namedBindings.kind === SyntaxKind.NamedImports) { + else if (namedBindings.kind === ts.SyntaxKind.NamedImports) { for (const element of namedBindings.elements) { - if (isUnused(element.name)) changes.delete(sourceFile, element); + if (isUnused(element.name)) + changes.delete(sourceFile, element); } } } } } - function deleteUnusedImportsInVariableDeclaration(sourceFile: SourceFile, varDecl: VariableDeclaration, changes: textChanges.ChangeTracker, isUnused: (name: Identifier) => boolean) { + function deleteUnusedImportsInVariableDeclaration(sourceFile: ts.SourceFile, varDecl: ts.VariableDeclaration, changes: ts.textChanges.ChangeTracker, isUnused: (name: ts.Identifier) => boolean) { const { name } = varDecl; switch (name.kind) { - case SyntaxKind.Identifier: + case ts.SyntaxKind.Identifier: if (isUnused(name)) { changes.delete(sourceFile, name); } break; - case SyntaxKind.ArrayBindingPattern: + case ts.SyntaxKind.ArrayBindingPattern: break; - case SyntaxKind.ObjectBindingPattern: - if (name.elements.every(e => isIdentifier(e.name) && isUnused(e.name))) { - changes.delete(sourceFile, - isVariableDeclarationList(varDecl.parent) && varDecl.parent.declarations.length === 1 ? varDecl.parent.parent : varDecl); + case ts.SyntaxKind.ObjectBindingPattern: + if (name.elements.every(e => ts.isIdentifier(e.name) && isUnused(e.name))) { + changes.delete(sourceFile, ts.isVariableDeclarationList(varDecl.parent) && varDecl.parent.declarations.length === 1 ? varDecl.parent.parent : varDecl); } else { for (const element of name.elements) { - if (isIdentifier(element.name) && isUnused(element.name)) { + if (ts.isIdentifier(element.name) && isUnused(element.name)) { changes.delete(sourceFile, element.name); } } @@ -423,40 +418,34 @@ namespace ts.refactor { } } - function getNewFileImportsAndAddExportInOldFile( - oldFile: SourceFile, - importsToCopy: ReadonlySymbolSet, - newFileImportsFromOldFile: ReadonlySymbolSet, - changes: textChanges.ChangeTracker, - checker: TypeChecker, - useEsModuleSyntax: boolean, - quotePreference: QuotePreference, - ): readonly SupportedImportStatement[] { + function getNewFileImportsAndAddExportInOldFile(oldFile: ts.SourceFile, importsToCopy: ReadonlySymbolSet, newFileImportsFromOldFile: ReadonlySymbolSet, changes: ts.textChanges.ChangeTracker, checker: ts.TypeChecker, useEsModuleSyntax: boolean, quotePreference: ts.QuotePreference): readonly SupportedImportStatement[] { const copiedOldImports: SupportedImportStatement[] = []; for (const oldStatement of oldFile.statements) { forEachImportInStatement(oldStatement, i => { - append(copiedOldImports, filterImport(i, moduleSpecifierFromImport(i), name => importsToCopy.has(checker.getSymbolAtLocation(name)!))); + ts.append(copiedOldImports, filterImport(i, moduleSpecifierFromImport(i), name => importsToCopy.has(checker.getSymbolAtLocation(name)!))); }); } // Also, import things used from the old file, and insert 'export' modifiers as necessary in the old file. - let oldFileDefault: Identifier | undefined; + let oldFileDefault: ts.Identifier | undefined; const oldFileNamedImports: string[] = []; - const markSeenTop = nodeSeenTracker(); // Needed because multiple declarations may appear in `const x = 0, y = 1;`. + const markSeenTop = ts.nodeSeenTracker(); // Needed because multiple declarations may appear in `const x = 0, y = 1;`. newFileImportsFromOldFile.forEach(symbol => { if (!symbol.declarations) { return; } for (const decl of symbol.declarations) { - if (!isTopLevelDeclaration(decl)) continue; + if (!isTopLevelDeclaration(decl)) + continue; const name = nameOfTopLevelDeclaration(decl); - if (!name) continue; + if (!name) + continue; const top = getTopLevelDeclarationStatement(decl); if (markSeenTop(top)) { addExportToChanges(oldFile, top, name, changes, useEsModuleSyntax); } - if (hasSyntacticModifier(decl, ModifierFlags.Default)) { + if (ts.hasSyntacticModifier(decl, ts.ModifierFlags.Default)) { oldFileDefault = name; } else { @@ -465,21 +454,22 @@ namespace ts.refactor { } }); - append(copiedOldImports, makeImportOrRequire(oldFileDefault, oldFileNamedImports, removeFileExtension(getBaseFileName(oldFile.fileName)), useEsModuleSyntax, quotePreference)); + ts.append(copiedOldImports, makeImportOrRequire(oldFileDefault, oldFileNamedImports, ts.removeFileExtension(ts.getBaseFileName(oldFile.fileName)), useEsModuleSyntax, quotePreference)); return copiedOldImports; } - function makeUniqueModuleName(moduleName: string, extension: string, inDirectory: string, host: LanguageServiceHost): string { + function makeUniqueModuleName(moduleName: string, extension: string, inDirectory: string, host: ts.LanguageServiceHost): string { let newModuleName = moduleName; for (let i = 1; ; i++) { - const name = combinePaths(inDirectory, newModuleName + extension); - if (!host.fileExists(name)) return newModuleName; + const name = ts.combinePaths(inDirectory, newModuleName + extension); + if (!host.fileExists(name)) + return newModuleName; newModuleName = `${moduleName}.${i}`; } } function getNewModuleName(movedSymbols: ReadonlySymbolSet): string { - return movedSymbols.forEachEntry(symbolNameNoDefault) || "newFile"; + return movedSymbols.forEachEntry(ts.symbolNameNoDefault) || "newFile"; } interface UsageInfo { @@ -495,12 +485,12 @@ namespace ts.refactor { // Subset of oldImportsNeededByNewFile that are will no longer be used in the old file. readonly unusedImportsFromOldFile: ReadonlySymbolSet; } - function getUsageInfo(oldFile: SourceFile, toMove: readonly Statement[], checker: TypeChecker): UsageInfo { + function getUsageInfo(oldFile: ts.SourceFile, toMove: readonly ts.Statement[], checker: ts.TypeChecker): UsageInfo { const movedSymbols = new SymbolSet(); const oldImportsNeededByNewFile = new SymbolSet(); const newFileImportsFromOldFile = new SymbolSet(); - const containsJsx = find(toMove, statement => !!(statement.transformFlags & TransformFlags.ContainsJsx)); + const containsJsx = ts.find(toMove, statement => !!(statement.transformFlags & ts.TransformFlags.ContainsJsx)); const jsxNamespaceSymbol = getJsxNamespaceSymbol(containsJsx); if (jsxNamespaceSymbol) { // Might not exist (e.g. in non-compiling code) oldImportsNeededByNewFile.add(jsxNamespaceSymbol); @@ -508,12 +498,13 @@ namespace ts.refactor { for (const statement of toMove) { forEachTopLevelDeclaration(statement, decl => { - movedSymbols.add(Debug.checkDefined(isExpressionStatement(decl) ? checker.getSymbolAtLocation(decl.expression.left) : decl.symbol, "Need a symbol here")); + movedSymbols.add(ts.Debug.checkDefined(ts.isExpressionStatement(decl) ? checker.getSymbolAtLocation(decl.expression.left) : decl.symbol, "Need a symbol here")); }); } for (const statement of toMove) { forEachReference(statement, checker, symbol => { - if (!symbol.declarations) return; + if (!symbol.declarations) + return; for (const decl of symbol.declarations) { if (isInImport(decl)) { oldImportsNeededByNewFile.add(symbol); @@ -529,22 +520,24 @@ namespace ts.refactor { const oldFileImportsFromNewFile = new SymbolSet(); for (const statement of oldFile.statements) { - if (contains(toMove, statement)) continue; + if (ts.contains(toMove, statement)) + continue; // jsxNamespaceSymbol will only be set iff it is in oldImportsNeededByNewFile. - if (jsxNamespaceSymbol && !!(statement.transformFlags & TransformFlags.ContainsJsx)) { + if (jsxNamespaceSymbol && !!(statement.transformFlags & ts.TransformFlags.ContainsJsx)) { unusedImportsFromOldFile.delete(jsxNamespaceSymbol); } forEachReference(statement, checker, symbol => { - if (movedSymbols.has(symbol)) oldFileImportsFromNewFile.add(symbol); + if (movedSymbols.has(symbol)) + oldFileImportsFromNewFile.add(symbol); unusedImportsFromOldFile.delete(symbol); }); } return { movedSymbols, newFileImportsFromOldFile, oldFileImportsFromNewFile, oldImportsNeededByNewFile, unusedImportsFromOldFile }; - function getJsxNamespaceSymbol(containsJsx: Node | undefined) { + function getJsxNamespaceSymbol(containsJsx: ts.Node | undefined) { if (containsJsx === undefined) { return undefined; } @@ -554,9 +547,8 @@ namespace ts.refactor { // Strictly speaking, this could resolve to a symbol other than the JSX namespace. // This will produce erroneous output (probably, an incorrectly copied import) but // is expected to be very rare and easily reversible. - const jsxNamespaceSymbol = checker.resolveName(jsxNamespace, containsJsx, SymbolFlags.Namespace, /*excludeGlobals*/ true); - - return !!jsxNamespaceSymbol && some(jsxNamespaceSymbol.declarations, isInImport) + const jsxNamespaceSymbol = checker.resolveName(jsxNamespace, containsJsx, ts.SymbolFlags.Namespace, /*excludeGlobals*/ true); + return !!jsxNamespaceSymbol && ts.some(jsxNamespaceSymbol.declarations, isInImport) ? jsxNamespaceSymbol : undefined; } @@ -564,75 +556,77 @@ namespace ts.refactor { // Below should all be utilities - function isInImport(decl: Declaration) { + function isInImport(decl: ts.Declaration) { switch (decl.kind) { - case SyntaxKind.ImportEqualsDeclaration: - case SyntaxKind.ImportSpecifier: - case SyntaxKind.ImportClause: - case SyntaxKind.NamespaceImport: + case ts.SyntaxKind.ImportEqualsDeclaration: + case ts.SyntaxKind.ImportSpecifier: + case ts.SyntaxKind.ImportClause: + case ts.SyntaxKind.NamespaceImport: return true; - case SyntaxKind.VariableDeclaration: - return isVariableDeclarationInImport(decl as VariableDeclaration); - case SyntaxKind.BindingElement: - return isVariableDeclaration(decl.parent.parent) && isVariableDeclarationInImport(decl.parent.parent); + case ts.SyntaxKind.VariableDeclaration: + return isVariableDeclarationInImport(decl as ts.VariableDeclaration); + case ts.SyntaxKind.BindingElement: + return ts.isVariableDeclaration(decl.parent.parent) && isVariableDeclarationInImport(decl.parent.parent); default: return false; } } - function isVariableDeclarationInImport(decl: VariableDeclaration) { - return isSourceFile(decl.parent.parent.parent) && - !!decl.initializer && isRequireCall(decl.initializer, /*checkArgumentIsStringLiteralLike*/ true); + function isVariableDeclarationInImport(decl: ts.VariableDeclaration) { + return ts.isSourceFile(decl.parent.parent.parent) && + !!decl.initializer && ts.isRequireCall(decl.initializer, /*checkArgumentIsStringLiteralLike*/ true); } - function filterImport(i: SupportedImport, moduleSpecifier: StringLiteralLike, keep: (name: Identifier) => boolean): SupportedImportStatement | undefined { + function filterImport(i: SupportedImport, moduleSpecifier: ts.StringLiteralLike, keep: (name: ts.Identifier) => boolean): SupportedImportStatement | undefined { switch (i.kind) { - case SyntaxKind.ImportDeclaration: { + case ts.SyntaxKind.ImportDeclaration: { const clause = i.importClause; - if (!clause) return undefined; + if (!clause) + return undefined; const defaultImport = clause.name && keep(clause.name) ? clause.name : undefined; const namedBindings = clause.namedBindings && filterNamedBindings(clause.namedBindings, keep); return defaultImport || namedBindings - ? factory.createImportDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, factory.createImportClause(/*isTypeOnly*/ false, defaultImport, namedBindings), moduleSpecifier, /*assertClause*/ undefined) + ? ts.factory.createImportDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, ts.factory.createImportClause(/*isTypeOnly*/ false, defaultImport, namedBindings), moduleSpecifier, /*assertClause*/ undefined) : undefined; } - case SyntaxKind.ImportEqualsDeclaration: + case ts.SyntaxKind.ImportEqualsDeclaration: return keep(i.name) ? i : undefined; - case SyntaxKind.VariableDeclaration: { + case ts.SyntaxKind.VariableDeclaration: { const name = filterBindingName(i.name, keep); return name ? makeVariableStatement(name, i.type, createRequireCall(moduleSpecifier), i.parent.flags) : undefined; } default: - return Debug.assertNever(i, `Unexpected import kind ${(i as SupportedImport).kind}`); + return ts.Debug.assertNever(i, `Unexpected import kind ${(i as SupportedImport).kind}`); } } - function filterNamedBindings(namedBindings: NamedImportBindings, keep: (name: Identifier) => boolean): NamedImportBindings | undefined { - if (namedBindings.kind === SyntaxKind.NamespaceImport) { + function filterNamedBindings(namedBindings: ts.NamedImportBindings, keep: (name: ts.Identifier) => boolean): ts.NamedImportBindings | undefined { + if (namedBindings.kind === ts.SyntaxKind.NamespaceImport) { return keep(namedBindings.name) ? namedBindings : undefined; } else { const newElements = namedBindings.elements.filter(e => keep(e.name)); - return newElements.length ? factory.createNamedImports(newElements) : undefined; + return newElements.length ? ts.factory.createNamedImports(newElements) : undefined; } } - function filterBindingName(name: BindingName, keep: (name: Identifier) => boolean): BindingName | undefined { + function filterBindingName(name: ts.BindingName, keep: (name: ts.Identifier) => boolean): ts.BindingName | undefined { switch (name.kind) { - case SyntaxKind.Identifier: + case ts.SyntaxKind.Identifier: return keep(name) ? name : undefined; - case SyntaxKind.ArrayBindingPattern: + case ts.SyntaxKind.ArrayBindingPattern: return name; - case SyntaxKind.ObjectBindingPattern: { + case ts.SyntaxKind.ObjectBindingPattern: { // We can't handle nested destructurings or property names well here, so just copy them all. - const newElements = name.elements.filter(prop => prop.propertyName || !isIdentifier(prop.name) || keep(prop.name)); - return newElements.length ? factory.createObjectBindingPattern(newElements) : undefined; + const newElements = name.elements.filter(prop => prop.propertyName || !ts.isIdentifier(prop.name) || keep(prop.name)); + return newElements.length ? ts.factory.createObjectBindingPattern(newElements) : undefined; } } } - function forEachReference(node: Node, checker: TypeChecker, onReference: (s: Symbol) => void) { + function forEachReference(node: ts.Node, checker: ts.TypeChecker, onReference: (s: ts.Symbol) => void) { node.forEachChild(function cb(node) { - if (isIdentifier(node) && !isDeclarationName(node)) { + if (ts.isIdentifier(node) && !ts.isDeclarationName(node)) { const sym = checker.getSymbolAtLocation(node); - if (sym) onReference(sym); + if (sym) + onReference(sym); } else { node.forEachChild(cb); @@ -641,200 +635,193 @@ namespace ts.refactor { } interface ReadonlySymbolSet { - has(symbol: Symbol): boolean; - forEach(cb: (symbol: Symbol) => void): void; - forEachEntry(cb: (symbol: Symbol) => T | undefined): T | undefined; + has(symbol: ts.Symbol): boolean; + forEach(cb: (symbol: ts.Symbol) => void): void; + forEachEntry(cb: (symbol: ts.Symbol) => T | undefined): T | undefined; } class SymbolSet implements ReadonlySymbolSet { - private map = new Map(); - add(symbol: Symbol): void { - this.map.set(String(getSymbolId(symbol)), symbol); + private map = new ts.Map(); + add(symbol: ts.Symbol): void { + this.map.set(String(ts.getSymbolId(symbol)), symbol); } - has(symbol: Symbol): boolean { - return this.map.has(String(getSymbolId(symbol))); + has(symbol: ts.Symbol): boolean { + return this.map.has(String(ts.getSymbolId(symbol))); } - delete(symbol: Symbol): void { - this.map.delete(String(getSymbolId(symbol))); + delete(symbol: ts.Symbol): void { + this.map.delete(String(ts.getSymbolId(symbol))); } - forEach(cb: (symbol: Symbol) => void): void { + forEach(cb: (symbol: ts.Symbol) => void): void { this.map.forEach(cb); } - forEachEntry(cb: (symbol: Symbol) => T | undefined): T | undefined { - return forEachEntry(this.map, cb); + forEachEntry(cb: (symbol: ts.Symbol) => T | undefined): T | undefined { + return ts.forEachEntry(this.map, cb); } clone(): SymbolSet { const clone = new SymbolSet(); - copyEntries(this.map, clone.map); + ts.copyEntries(this.map, clone.map); return clone; } } - type TopLevelExpressionStatement = ExpressionStatement & { expression: BinaryExpression & { left: PropertyAccessExpression } }; // 'exports.x = ...' - type NonVariableTopLevelDeclaration = - | FunctionDeclaration - | ClassDeclaration - | EnumDeclaration - | TypeAliasDeclaration - | InterfaceDeclaration - | ModuleDeclaration - | TopLevelExpressionStatement - | ImportEqualsDeclaration; - type TopLevelDeclarationStatement = NonVariableTopLevelDeclaration | VariableStatement; - interface TopLevelVariableDeclaration extends VariableDeclaration { parent: VariableDeclarationList & { parent: VariableStatement; }; } - type TopLevelDeclaration = NonVariableTopLevelDeclaration | TopLevelVariableDeclaration | BindingElement; - function isTopLevelDeclaration(node: Node): node is TopLevelDeclaration { - return isNonVariableTopLevelDeclaration(node) && isSourceFile(node.parent) || isVariableDeclaration(node) && isSourceFile(node.parent.parent.parent); + type TopLevelExpressionStatement = ts.ExpressionStatement & { + expression: ts.BinaryExpression & { + left: ts.PropertyAccessExpression; + }; + }; // 'exports.x = ...' + type NonVariableTopLevelDeclaration = ts.FunctionDeclaration | ts.ClassDeclaration | ts.EnumDeclaration | ts.TypeAliasDeclaration | ts.InterfaceDeclaration | ts.ModuleDeclaration | TopLevelExpressionStatement | ts.ImportEqualsDeclaration; + type TopLevelDeclarationStatement = NonVariableTopLevelDeclaration | ts.VariableStatement; + interface TopLevelVariableDeclaration extends ts.VariableDeclaration { + parent: ts.VariableDeclarationList & { + parent: ts.VariableStatement; + }; } - - function sourceFileOfTopLevelDeclaration(node: TopLevelDeclaration): Node { - return isVariableDeclaration(node) ? node.parent.parent.parent : node.parent; + type TopLevelDeclaration = NonVariableTopLevelDeclaration | TopLevelVariableDeclaration | ts.BindingElement; + function isTopLevelDeclaration(node: ts.Node): node is TopLevelDeclaration { + return isNonVariableTopLevelDeclaration(node) && ts.isSourceFile(node.parent) || ts.isVariableDeclaration(node) && ts.isSourceFile(node.parent.parent.parent); } - - function isTopLevelDeclarationStatement(node: Node): node is TopLevelDeclarationStatement { - Debug.assert(isSourceFile(node.parent), "Node parent should be a SourceFile"); - return isNonVariableTopLevelDeclaration(node) || isVariableStatement(node); + function sourceFileOfTopLevelDeclaration(node: TopLevelDeclaration): ts.Node { + return ts.isVariableDeclaration(node) ? node.parent.parent.parent : node.parent; } - - function isNonVariableTopLevelDeclaration(node: Node): node is NonVariableTopLevelDeclaration { + function isTopLevelDeclarationStatement(node: ts.Node): node is TopLevelDeclarationStatement { + ts.Debug.assert(ts.isSourceFile(node.parent), "Node parent should be a SourceFile"); + return isNonVariableTopLevelDeclaration(node) || ts.isVariableStatement(node); + } + function isNonVariableTopLevelDeclaration(node: ts.Node): node is NonVariableTopLevelDeclaration { switch (node.kind) { - case SyntaxKind.FunctionDeclaration: - case SyntaxKind.ClassDeclaration: - case SyntaxKind.ModuleDeclaration: - case SyntaxKind.EnumDeclaration: - case SyntaxKind.TypeAliasDeclaration: - case SyntaxKind.InterfaceDeclaration: - case SyntaxKind.ImportEqualsDeclaration: + case ts.SyntaxKind.FunctionDeclaration: + case ts.SyntaxKind.ClassDeclaration: + case ts.SyntaxKind.ModuleDeclaration: + case ts.SyntaxKind.EnumDeclaration: + case ts.SyntaxKind.TypeAliasDeclaration: + case ts.SyntaxKind.InterfaceDeclaration: + case ts.SyntaxKind.ImportEqualsDeclaration: return true; default: return false; } } - function forEachTopLevelDeclaration(statement: Statement, cb: (node: TopLevelDeclaration) => T): T | undefined { + function forEachTopLevelDeclaration(statement: ts.Statement, cb: (node: TopLevelDeclaration) => T): T | undefined { switch (statement.kind) { - case SyntaxKind.FunctionDeclaration: - case SyntaxKind.ClassDeclaration: - case SyntaxKind.ModuleDeclaration: - case SyntaxKind.EnumDeclaration: - case SyntaxKind.TypeAliasDeclaration: - case SyntaxKind.InterfaceDeclaration: - case SyntaxKind.ImportEqualsDeclaration: - return cb(statement as FunctionDeclaration | ClassDeclaration | EnumDeclaration | ModuleDeclaration | TypeAliasDeclaration | InterfaceDeclaration | ImportEqualsDeclaration); - - case SyntaxKind.VariableStatement: - return firstDefined((statement as VariableStatement).declarationList.declarations, decl => forEachTopLevelDeclarationInBindingName(decl.name, cb)); - - case SyntaxKind.ExpressionStatement: { - const { expression } = statement as ExpressionStatement; - return isBinaryExpression(expression) && getAssignmentDeclarationKind(expression) === AssignmentDeclarationKind.ExportsProperty + case ts.SyntaxKind.FunctionDeclaration: + case ts.SyntaxKind.ClassDeclaration: + case ts.SyntaxKind.ModuleDeclaration: + case ts.SyntaxKind.EnumDeclaration: + case ts.SyntaxKind.TypeAliasDeclaration: + case ts.SyntaxKind.InterfaceDeclaration: + case ts.SyntaxKind.ImportEqualsDeclaration: + return cb(statement as ts.FunctionDeclaration | ts.ClassDeclaration | ts.EnumDeclaration | ts.ModuleDeclaration | ts.TypeAliasDeclaration | ts.InterfaceDeclaration | ts.ImportEqualsDeclaration); + case ts.SyntaxKind.VariableStatement: + return ts.firstDefined((statement as ts.VariableStatement).declarationList.declarations, decl => forEachTopLevelDeclarationInBindingName(decl.name, cb)); + case ts.SyntaxKind.ExpressionStatement: { + const { expression } = statement as ts.ExpressionStatement; + return ts.isBinaryExpression(expression) && ts.getAssignmentDeclarationKind(expression) === ts.AssignmentDeclarationKind.ExportsProperty ? cb(statement as TopLevelExpressionStatement) : undefined; } } } - function forEachTopLevelDeclarationInBindingName(name: BindingName, cb: (node: TopLevelDeclaration) => T): T | undefined { + function forEachTopLevelDeclarationInBindingName(name: ts.BindingName, cb: (node: TopLevelDeclaration) => T): T | undefined { switch (name.kind) { - case SyntaxKind.Identifier: - return cb(cast(name.parent, (x): x is TopLevelVariableDeclaration | BindingElement => isVariableDeclaration(x) || isBindingElement(x))); - case SyntaxKind.ArrayBindingPattern: - case SyntaxKind.ObjectBindingPattern: - return firstDefined(name.elements, em => isOmittedExpression(em) ? undefined : forEachTopLevelDeclarationInBindingName(em.name, cb)); + case ts.SyntaxKind.Identifier: + return cb(ts.cast(name.parent, (x): x is TopLevelVariableDeclaration | ts.BindingElement => ts.isVariableDeclaration(x) || ts.isBindingElement(x))); + case ts.SyntaxKind.ArrayBindingPattern: + case ts.SyntaxKind.ObjectBindingPattern: + return ts.firstDefined(name.elements, em => ts.isOmittedExpression(em) ? undefined : forEachTopLevelDeclarationInBindingName(em.name, cb)); default: - return Debug.assertNever(name, `Unexpected name kind ${(name as BindingName).kind}`); + return ts.Debug.assertNever(name, `Unexpected name kind ${(name as ts.BindingName).kind}`); } } - function nameOfTopLevelDeclaration(d: TopLevelDeclaration): Identifier | undefined { - return isExpressionStatement(d) ? tryCast(d.expression.left.name, isIdentifier) : tryCast(d.name, isIdentifier); + function nameOfTopLevelDeclaration(d: TopLevelDeclaration): ts.Identifier | undefined { + return ts.isExpressionStatement(d) ? ts.tryCast(d.expression.left.name, ts.isIdentifier) : ts.tryCast(d.name, ts.isIdentifier); } function getTopLevelDeclarationStatement(d: TopLevelDeclaration): TopLevelDeclarationStatement { switch (d.kind) { - case SyntaxKind.VariableDeclaration: + case ts.SyntaxKind.VariableDeclaration: return d.parent.parent; - case SyntaxKind.BindingElement: - return getTopLevelDeclarationStatement( - cast(d.parent.parent, (p): p is TopLevelVariableDeclaration | BindingElement => isVariableDeclaration(p) || isBindingElement(p))); + case ts.SyntaxKind.BindingElement: + return getTopLevelDeclarationStatement(ts.cast(d.parent.parent, (p): p is TopLevelVariableDeclaration | ts.BindingElement => ts.isVariableDeclaration(p) || ts.isBindingElement(p))); default: return d; } } - function addExportToChanges(sourceFile: SourceFile, decl: TopLevelDeclarationStatement, name: Identifier, changes: textChanges.ChangeTracker, useEs6Exports: boolean): void { - if (isExported(sourceFile, decl, useEs6Exports, name)) return; + function addExportToChanges(sourceFile: ts.SourceFile, decl: TopLevelDeclarationStatement, name: ts.Identifier, changes: ts.textChanges.ChangeTracker, useEs6Exports: boolean): void { + if (isExported(sourceFile, decl, useEs6Exports, name)) + return; if (useEs6Exports) { - if (!isExpressionStatement(decl)) changes.insertExportModifier(sourceFile, decl); + if (!ts.isExpressionStatement(decl)) + changes.insertExportModifier(sourceFile, decl); } else { const names = getNamesToExportInCommonJS(decl); - if (names.length !== 0) changes.insertNodesAfter(sourceFile, decl, names.map(createExportAssignment)); + if (names.length !== 0) + changes.insertNodesAfter(sourceFile, decl, names.map(createExportAssignment)); } } - function isExported(sourceFile: SourceFile, decl: TopLevelDeclarationStatement, useEs6Exports: boolean, name?: Identifier): boolean { + function isExported(sourceFile: ts.SourceFile, decl: TopLevelDeclarationStatement, useEs6Exports: boolean, name?: ts.Identifier): boolean { if (useEs6Exports) { - return !isExpressionStatement(decl) && hasSyntacticModifier(decl, ModifierFlags.Export) || !!(name && sourceFile.symbol.exports?.has(name.escapedText)); + return !ts.isExpressionStatement(decl) && ts.hasSyntacticModifier(decl, ts.ModifierFlags.Export) || !!(name && sourceFile.symbol.exports?.has(name.escapedText)); } - return getNamesToExportInCommonJS(decl).some(name => sourceFile.symbol.exports!.has(escapeLeadingUnderscores(name))); + return getNamesToExportInCommonJS(decl).some(name => sourceFile.symbol.exports!.has(ts.escapeLeadingUnderscores(name))); } - function addExport(decl: TopLevelDeclarationStatement, useEs6Exports: boolean): readonly Statement[] | undefined { + function addExport(decl: TopLevelDeclarationStatement, useEs6Exports: boolean): readonly ts.Statement[] | undefined { return useEs6Exports ? [addEs6Export(decl)] : addCommonjsExport(decl); } function addEs6Export(d: TopLevelDeclarationStatement): TopLevelDeclarationStatement { - const modifiers = concatenate([factory.createModifier(SyntaxKind.ExportKeyword)], d.modifiers); + const modifiers = ts.concatenate([ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)], d.modifiers); switch (d.kind) { - case SyntaxKind.FunctionDeclaration: - return factory.updateFunctionDeclaration(d, d.decorators, modifiers, d.asteriskToken, d.name, d.typeParameters, d.parameters, d.type, d.body); - case SyntaxKind.ClassDeclaration: - return factory.updateClassDeclaration(d, d.decorators, modifiers, d.name, d.typeParameters, d.heritageClauses, d.members); - case SyntaxKind.VariableStatement: - return factory.updateVariableStatement(d, modifiers, d.declarationList); - case SyntaxKind.ModuleDeclaration: - return factory.updateModuleDeclaration(d, d.decorators, modifiers, d.name, d.body); - case SyntaxKind.EnumDeclaration: - return factory.updateEnumDeclaration(d, d.decorators, modifiers, d.name, d.members); - case SyntaxKind.TypeAliasDeclaration: - return factory.updateTypeAliasDeclaration(d, d.decorators, modifiers, d.name, d.typeParameters, d.type); - case SyntaxKind.InterfaceDeclaration: - return factory.updateInterfaceDeclaration(d, d.decorators, modifiers, d.name, d.typeParameters, d.heritageClauses, d.members); - case SyntaxKind.ImportEqualsDeclaration: - return factory.updateImportEqualsDeclaration(d, d.decorators, modifiers, d.isTypeOnly, d.name, d.moduleReference); - case SyntaxKind.ExpressionStatement: - return Debug.fail(); // Shouldn't try to add 'export' keyword to `exports.x = ...` + case ts.SyntaxKind.FunctionDeclaration: + return ts.factory.updateFunctionDeclaration(d, d.decorators, modifiers, d.asteriskToken, d.name, d.typeParameters, d.parameters, d.type, d.body); + case ts.SyntaxKind.ClassDeclaration: + return ts.factory.updateClassDeclaration(d, d.decorators, modifiers, d.name, d.typeParameters, d.heritageClauses, d.members); + case ts.SyntaxKind.VariableStatement: + return ts.factory.updateVariableStatement(d, modifiers, d.declarationList); + case ts.SyntaxKind.ModuleDeclaration: + return ts.factory.updateModuleDeclaration(d, d.decorators, modifiers, d.name, d.body); + case ts.SyntaxKind.EnumDeclaration: + return ts.factory.updateEnumDeclaration(d, d.decorators, modifiers, d.name, d.members); + case ts.SyntaxKind.TypeAliasDeclaration: + return ts.factory.updateTypeAliasDeclaration(d, d.decorators, modifiers, d.name, d.typeParameters, d.type); + case ts.SyntaxKind.InterfaceDeclaration: + return ts.factory.updateInterfaceDeclaration(d, d.decorators, modifiers, d.name, d.typeParameters, d.heritageClauses, d.members); + case ts.SyntaxKind.ImportEqualsDeclaration: + return ts.factory.updateImportEqualsDeclaration(d, d.decorators, modifiers, d.isTypeOnly, d.name, d.moduleReference); + case ts.SyntaxKind.ExpressionStatement: + return ts.Debug.fail(); // Shouldn't try to add 'export' keyword to `exports.x = ...` default: - return Debug.assertNever(d, `Unexpected declaration kind ${(d as DeclarationStatement).kind}`); + return ts.Debug.assertNever(d, `Unexpected declaration kind ${(d as ts.DeclarationStatement).kind}`); } } - function addCommonjsExport(decl: TopLevelDeclarationStatement): readonly Statement[] | undefined { + function addCommonjsExport(decl: TopLevelDeclarationStatement): readonly ts.Statement[] | undefined { return [decl, ...getNamesToExportInCommonJS(decl).map(createExportAssignment)]; } function getNamesToExportInCommonJS(decl: TopLevelDeclarationStatement): readonly string[] { switch (decl.kind) { - case SyntaxKind.FunctionDeclaration: - case SyntaxKind.ClassDeclaration: + case ts.SyntaxKind.FunctionDeclaration: + case ts.SyntaxKind.ClassDeclaration: return [decl.name!.text]; // TODO: GH#18217 - case SyntaxKind.VariableStatement: - return mapDefined(decl.declarationList.declarations, d => isIdentifier(d.name) ? d.name.text : undefined); - case SyntaxKind.ModuleDeclaration: - case SyntaxKind.EnumDeclaration: - case SyntaxKind.TypeAliasDeclaration: - case SyntaxKind.InterfaceDeclaration: - case SyntaxKind.ImportEqualsDeclaration: - return emptyArray; - case SyntaxKind.ExpressionStatement: - return Debug.fail("Can't export an ExpressionStatement"); // Shouldn't try to add 'export' keyword to `exports.x = ...` + case ts.SyntaxKind.VariableStatement: + return ts.mapDefined(decl.declarationList.declarations, d => ts.isIdentifier(d.name) ? d.name.text : undefined); + case ts.SyntaxKind.ModuleDeclaration: + case ts.SyntaxKind.EnumDeclaration: + case ts.SyntaxKind.TypeAliasDeclaration: + case ts.SyntaxKind.InterfaceDeclaration: + case ts.SyntaxKind.ImportEqualsDeclaration: + return ts.emptyArray; + case ts.SyntaxKind.ExpressionStatement: + return ts.Debug.fail("Can't export an ExpressionStatement"); // Shouldn't try to add 'export' keyword to `exports.x = ...` default: - return Debug.assertNever(decl, `Unexpected decl kind ${(decl as TopLevelDeclarationStatement).kind}`); + return ts.Debug.assertNever(decl, `Unexpected decl kind ${(decl as TopLevelDeclarationStatement).kind}`); } } /** Creates `exports.x = x;` */ - function createExportAssignment(name: string): Statement { - return factory.createExpressionStatement( - factory.createBinaryExpression( - factory.createPropertyAccessExpression(factory.createIdentifier("exports"), factory.createIdentifier(name)), - SyntaxKind.EqualsToken, - factory.createIdentifier(name))); + function createExportAssignment(name: string): ts.Statement { + return ts.factory.createExpressionStatement(ts.factory.createBinaryExpression(ts.factory.createPropertyAccessExpression(ts.factory.createIdentifier("exports"), ts.factory.createIdentifier(name)), ts.SyntaxKind.EqualsToken, ts.factory.createIdentifier(name))); } } diff --git a/src/services/rename.ts b/src/services/rename.ts index 0d33f1f2152f9..9b2583eebcc3e 100644 --- a/src/services/rename.ts +++ b/src/services/rename.ts @@ -1,90 +1,90 @@ /* @internal */ namespace ts.Rename { - export function getRenameInfo(program: Program, sourceFile: SourceFile, position: number, options?: RenameInfoOptions): RenameInfo { - const node = getAdjustedRenameLocation(getTouchingPropertyName(sourceFile, position)); + export function getRenameInfo(program: ts.Program, sourceFile: ts.SourceFile, position: number, options?: ts.RenameInfoOptions): ts.RenameInfo { + const node = ts.getAdjustedRenameLocation(ts.getTouchingPropertyName(sourceFile, position)); if (nodeIsEligibleForRename(node)) { const renameInfo = getRenameInfoForNode(node, program.getTypeChecker(), sourceFile, program, options); if (renameInfo) { return renameInfo; } } - return getRenameInfoError(Diagnostics.You_cannot_rename_this_element); + return getRenameInfoError(ts.Diagnostics.You_cannot_rename_this_element); } - function getRenameInfoForNode(node: Node, typeChecker: TypeChecker, sourceFile: SourceFile, program: Program, options?: RenameInfoOptions): RenameInfo | undefined { + function getRenameInfoForNode(node: ts.Node, typeChecker: ts.TypeChecker, sourceFile: ts.SourceFile, program: ts.Program, options?: ts.RenameInfoOptions): ts.RenameInfo | undefined { const symbol = typeChecker.getSymbolAtLocation(node); if (!symbol) { - if (isStringLiteralLike(node)) { - const type = getContextualTypeFromParentOrAncestorTypeNode(node, typeChecker); - if (type && ((type.flags & TypeFlags.StringLiteral) || ( - (type.flags & TypeFlags.Union) && every((type as UnionType).types, type => !!(type.flags & TypeFlags.StringLiteral)) - ))) { - return getRenameInfoSuccess(node.text, node.text, ScriptElementKind.string, "", node, sourceFile); + if (ts.isStringLiteralLike(node)) { + const type = ts.getContextualTypeFromParentOrAncestorTypeNode(node, typeChecker); + if (type && ((type.flags & ts.TypeFlags.StringLiteral) || ((type.flags & ts.TypeFlags.Union) && ts.every((type as ts.UnionType).types, type => !!(type.flags & ts.TypeFlags.StringLiteral))))) { + return getRenameInfoSuccess(node.text, node.text, ts.ScriptElementKind.string, "", node, sourceFile); } } - else if (isLabelName(node)) { - const name = getTextOfNode(node); - return getRenameInfoSuccess(name, name, ScriptElementKind.label, ScriptElementKindModifier.none, node, sourceFile); + else if (ts.isLabelName(node)) { + const name = ts.getTextOfNode(node); + return getRenameInfoSuccess(name, name, ts.ScriptElementKind.label, ts.ScriptElementKindModifier.none, node, sourceFile); } return undefined; } // Only allow a symbol to be renamed if it actually has at least one declaration. const { declarations } = symbol; - if (!declarations || declarations.length === 0) return; + if (!declarations || declarations.length === 0) + return; // Disallow rename for elements that are defined in the standard TypeScript library. if (declarations.some(declaration => isDefinedInLibraryFile(program, declaration))) { - return getRenameInfoError(Diagnostics.You_cannot_rename_elements_that_are_defined_in_the_standard_TypeScript_library); + return getRenameInfoError(ts.Diagnostics.You_cannot_rename_elements_that_are_defined_in_the_standard_TypeScript_library); } // Cannot rename `default` as in `import { default as foo } from "./someModule"; - if (isIdentifier(node) && node.originalKeywordKind === SyntaxKind.DefaultKeyword && symbol.parent && symbol.parent.flags & SymbolFlags.Module) { + if (ts.isIdentifier(node) && node.originalKeywordKind === ts.SyntaxKind.DefaultKeyword && symbol.parent && symbol.parent.flags & ts.SymbolFlags.Module) { return undefined; } - if (isStringLiteralLike(node) && tryGetImportFromModuleSpecifier(node)) { + if (ts.isStringLiteralLike(node) && ts.tryGetImportFromModuleSpecifier(node)) { return options && options.allowRenameOfImportPath ? getRenameInfoForModule(node, sourceFile, symbol) : undefined; } - const kind = SymbolDisplay.getSymbolKind(typeChecker, symbol, node); - const specifierName = (isImportOrExportSpecifierName(node) || isStringOrNumericLiteralLike(node) && node.parent.kind === SyntaxKind.ComputedPropertyName) - ? stripQuotes(getTextOfIdentifierOrLiteral(node)) + const kind = ts.SymbolDisplay.getSymbolKind(typeChecker, symbol, node); + const specifierName = (ts.isImportOrExportSpecifierName(node) || ts.isStringOrNumericLiteralLike(node) && node.parent.kind === ts.SyntaxKind.ComputedPropertyName) + ? ts.stripQuotes(ts.getTextOfIdentifierOrLiteral(node)) : undefined; const displayName = specifierName || typeChecker.symbolToString(symbol); const fullDisplayName = specifierName || typeChecker.getFullyQualifiedName(symbol); - return getRenameInfoSuccess(displayName, fullDisplayName, kind, SymbolDisplay.getSymbolModifiers(typeChecker,symbol), node, sourceFile); + return getRenameInfoSuccess(displayName, fullDisplayName, kind, ts.SymbolDisplay.getSymbolModifiers(typeChecker, symbol), node, sourceFile); } - function isDefinedInLibraryFile(program: Program, declaration: Node) { + function isDefinedInLibraryFile(program: ts.Program, declaration: ts.Node) { const sourceFile = declaration.getSourceFile(); - return program.isSourceFileDefaultLibrary(sourceFile) && fileExtensionIs(sourceFile.fileName, Extension.Dts); + return program.isSourceFileDefaultLibrary(sourceFile) && ts.fileExtensionIs(sourceFile.fileName, ts.Extension.Dts); } - function getRenameInfoForModule(node: StringLiteralLike, sourceFile: SourceFile, moduleSymbol: Symbol): RenameInfo | undefined { - if (!isExternalModuleNameRelative(node.text)) { - return getRenameInfoError(Diagnostics.You_cannot_rename_a_module_via_a_global_import); + function getRenameInfoForModule(node: ts.StringLiteralLike, sourceFile: ts.SourceFile, moduleSymbol: ts.Symbol): ts.RenameInfo | undefined { + if (!ts.isExternalModuleNameRelative(node.text)) { + return getRenameInfoError(ts.Diagnostics.You_cannot_rename_a_module_via_a_global_import); } - const moduleSourceFile = moduleSymbol.declarations && find(moduleSymbol.declarations, isSourceFile); - if (!moduleSourceFile) return undefined; - const withoutIndex = endsWith(node.text, "/index") || endsWith(node.text, "/index.js") ? undefined : tryRemoveSuffix(removeFileExtension(moduleSourceFile.fileName), "/index"); + const moduleSourceFile = moduleSymbol.declarations && ts.find(moduleSymbol.declarations, ts.isSourceFile); + if (!moduleSourceFile) + return undefined; + const withoutIndex = ts.endsWith(node.text, "/index") || ts.endsWith(node.text, "/index.js") ? undefined : ts.tryRemoveSuffix(ts.removeFileExtension(moduleSourceFile.fileName), "/index"); const name = withoutIndex === undefined ? moduleSourceFile.fileName : withoutIndex; - const kind = withoutIndex === undefined ? ScriptElementKind.moduleElement : ScriptElementKind.directory; + const kind = withoutIndex === undefined ? ts.ScriptElementKind.moduleElement : ts.ScriptElementKind.directory; const indexAfterLastSlash = node.text.lastIndexOf("/") + 1; // Span should only be the last component of the path. + 1 to account for the quote character. - const triggerSpan = createTextSpan(node.getStart(sourceFile) + 1 + indexAfterLastSlash, node.text.length - indexAfterLastSlash); + const triggerSpan = ts.createTextSpan(node.getStart(sourceFile) + 1 + indexAfterLastSlash, node.text.length - indexAfterLastSlash); return { canRename: true, fileToRename: name, kind, displayName: name, fullDisplayName: name, - kindModifiers: ScriptElementKindModifier.none, + kindModifiers: ts.ScriptElementKindModifier.none, triggerSpan, }; } - function getRenameInfoSuccess(displayName: string, fullDisplayName: string, kind: ScriptElementKind, kindModifiers: string, node: Node, sourceFile: SourceFile): RenameInfoSuccess { + function getRenameInfoSuccess(displayName: string, fullDisplayName: string, kind: ts.ScriptElementKind, kindModifiers: string, node: ts.Node, sourceFile: ts.SourceFile): ts.RenameInfoSuccess { return { canRename: true, fileToRename: undefined, @@ -96,31 +96,31 @@ namespace ts.Rename { }; } - function getRenameInfoError(diagnostic: DiagnosticMessage): RenameInfoFailure { - return { canRename: false, localizedErrorMessage: getLocaleSpecificMessage(diagnostic) }; + function getRenameInfoError(diagnostic: ts.DiagnosticMessage): ts.RenameInfoFailure { + return { canRename: false, localizedErrorMessage: ts.getLocaleSpecificMessage(diagnostic) }; } - function createTriggerSpanForNode(node: Node, sourceFile: SourceFile) { + function createTriggerSpanForNode(node: ts.Node, sourceFile: ts.SourceFile) { let start = node.getStart(sourceFile); let width = node.getWidth(sourceFile); - if (isStringLiteralLike(node)) { + if (ts.isStringLiteralLike(node)) { // Exclude the quotes start += 1; width -= 2; } - return createTextSpan(start, width); + return ts.createTextSpan(start, width); } - export function nodeIsEligibleForRename(node: Node): boolean { + export function nodeIsEligibleForRename(node: ts.Node): boolean { switch (node.kind) { - case SyntaxKind.Identifier: - case SyntaxKind.PrivateIdentifier: - case SyntaxKind.StringLiteral: - case SyntaxKind.NoSubstitutionTemplateLiteral: - case SyntaxKind.ThisKeyword: + case ts.SyntaxKind.Identifier: + case ts.SyntaxKind.PrivateIdentifier: + case ts.SyntaxKind.StringLiteral: + case ts.SyntaxKind.NoSubstitutionTemplateLiteral: + case ts.SyntaxKind.ThisKeyword: return true; - case SyntaxKind.NumericLiteral: - return isLiteralNameOfPropertyDeclarationOrIndexAccess(node as NumericLiteral); + case ts.SyntaxKind.NumericLiteral: + return ts.isLiteralNameOfPropertyDeclarationOrIndexAccess(node as ts.NumericLiteral); default: return false; } diff --git a/src/services/services.ts b/src/services/services.ts index 9ac9cf354002f..d6750aaf9bb24 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -2,51 +2,50 @@ namespace ts { /** The version of the language service API */ export const servicesVersion = "0.8"; - function createNode(kind: TKind, pos: number, end: number, parent: Node): NodeObject | TokenObject | IdentifierObject | PrivateIdentifierObject { - const node = isNodeKind(kind) ? new NodeObject(kind, pos, end) : - kind === SyntaxKind.Identifier ? new IdentifierObject(SyntaxKind.Identifier, pos, end) : - kind === SyntaxKind.PrivateIdentifier ? new PrivateIdentifierObject(SyntaxKind.PrivateIdentifier, pos, end) : + function createNode(kind: TKind, pos: number, end: number, parent: ts.Node): NodeObject | TokenObject | IdentifierObject | PrivateIdentifierObject { + const node = ts.isNodeKind(kind) ? new NodeObject(kind, pos, end) : + kind === ts.SyntaxKind.Identifier ? new IdentifierObject(ts.SyntaxKind.Identifier, pos, end) : + kind === ts.SyntaxKind.PrivateIdentifier ? new PrivateIdentifierObject(ts.SyntaxKind.PrivateIdentifier, pos, end) : new TokenObject(kind, pos, end); node.parent = parent; - node.flags = parent.flags & NodeFlags.ContextFlags; + node.flags = parent.flags & ts.NodeFlags.ContextFlags; return node; } - class NodeObject implements Node { - public kind: SyntaxKind; + class NodeObject implements ts.Node { + public kind: ts.SyntaxKind; public pos: number; public end: number; - public flags: NodeFlags; - public modifierFlagsCache: ModifierFlags; - public transformFlags: TransformFlags; - public parent: Node; - public symbol!: Symbol; // Actually optional, but it was too annoying to access `node.symbol!` everywhere since in many cases we know it must be defined - public jsDoc?: JSDoc[]; - public original?: Node; - private _children: Node[] | undefined; - - constructor(kind: SyntaxKind, pos: number, end: number) { + public flags: ts.NodeFlags; + public modifierFlagsCache: ts.ModifierFlags; + public transformFlags: ts.TransformFlags; + public parent: ts.Node; + public symbol!: ts.Symbol; // Actually optional, but it was too annoying to access `node.symbol!` everywhere since in many cases we know it must be defined + public jsDoc?: ts.JSDoc[]; + public original?: ts.Node; + private _children: ts.Node[] | undefined; + constructor(kind: ts.SyntaxKind, pos: number, end: number) { this.pos = pos; this.end = end; - this.flags = NodeFlags.None; - this.modifierFlagsCache = ModifierFlags.None; - this.transformFlags = TransformFlags.None; + this.flags = ts.NodeFlags.None; + this.modifierFlagsCache = ts.ModifierFlags.None; + this.transformFlags = ts.TransformFlags.None; this.parent = undefined!; this.kind = kind; } private assertHasRealPosition(message?: string) { // eslint-disable-next-line debug-assert - Debug.assert(!positionIsSynthesized(this.pos) && !positionIsSynthesized(this.end), message || "Node must have a real position for this operation"); + ts.Debug.assert(!ts.positionIsSynthesized(this.pos) && !ts.positionIsSynthesized(this.end), message || "Node must have a real position for this operation"); } - public getSourceFile(): SourceFile { - return getSourceFileOfNode(this); + public getSourceFile(): ts.SourceFile { + return ts.getSourceFileOfNode(this); } - public getStart(sourceFile?: SourceFileLike, includeJsDocComment?: boolean): number { + public getStart(sourceFile?: ts.SourceFileLike, includeJsDocComment?: boolean): number { this.assertHasRealPosition(); - return getTokenPosOfNode(this, sourceFile, includeJsDocComment); + return ts.getTokenPosOfNode(this, sourceFile, includeJsDocComment); } public getFullStart(): number { @@ -59,7 +58,7 @@ namespace ts { return this.end; } - public getWidth(sourceFile?: SourceFile): number { + public getWidth(sourceFile?: ts.SourceFile): number { this.assertHasRealPosition(); return this.getEnd() - this.getStart(sourceFile); } @@ -69,17 +68,17 @@ namespace ts { return this.end - this.pos; } - public getLeadingTriviaWidth(sourceFile?: SourceFile): number { + public getLeadingTriviaWidth(sourceFile?: ts.SourceFile): number { this.assertHasRealPosition(); return this.getStart(sourceFile) - this.pos; } - public getFullText(sourceFile?: SourceFile): string { + public getFullText(sourceFile?: ts.SourceFile): string { this.assertHasRealPosition(); return (sourceFile || this.getSourceFile()).text.substring(this.pos, this.end); } - public getText(sourceFile?: SourceFile): string { + public getText(sourceFile?: ts.SourceFile): string { this.assertHasRealPosition(); if (!sourceFile) { sourceFile = this.getSourceFile(); @@ -87,57 +86,56 @@ namespace ts { return sourceFile.text.substring(this.getStart(sourceFile), this.getEnd()); } - public getChildCount(sourceFile?: SourceFile): number { + public getChildCount(sourceFile?: ts.SourceFile): number { return this.getChildren(sourceFile).length; } - public getChildAt(index: number, sourceFile?: SourceFile): Node { + public getChildAt(index: number, sourceFile?: ts.SourceFile): ts.Node { return this.getChildren(sourceFile)[index]; } - public getChildren(sourceFile?: SourceFileLike): Node[] { + public getChildren(sourceFile?: ts.SourceFileLike): ts.Node[] { this.assertHasRealPosition("Node without a real position cannot be scanned and thus has no token nodes - use forEachChild and collect the result if that's fine"); return this._children || (this._children = createChildren(this, sourceFile)); } - public getFirstToken(sourceFile?: SourceFileLike): Node | undefined { + public getFirstToken(sourceFile?: ts.SourceFileLike): ts.Node | undefined { this.assertHasRealPosition(); const children = this.getChildren(sourceFile); if (!children.length) { return undefined; } - const child = find(children, kid => kid.kind < SyntaxKind.FirstJSDocNode || kid.kind > SyntaxKind.LastJSDocNode)!; - return child.kind < SyntaxKind.FirstNode ? + const child = ts.find(children, kid => kid.kind < ts.SyntaxKind.FirstJSDocNode || kid.kind > ts.SyntaxKind.LastJSDocNode)!; + return child.kind < ts.SyntaxKind.FirstNode ? child : child.getFirstToken(sourceFile); } - public getLastToken(sourceFile?: SourceFileLike): Node | undefined { + public getLastToken(sourceFile?: ts.SourceFileLike): ts.Node | undefined { this.assertHasRealPosition(); const children = this.getChildren(sourceFile); - const child = lastOrUndefined(children); + const child = ts.lastOrUndefined(children); if (!child) { return undefined; } - return child.kind < SyntaxKind.FirstNode ? child : child.getLastToken(sourceFile); + return child.kind < ts.SyntaxKind.FirstNode ? child : child.getLastToken(sourceFile); } - public forEachChild(cbNode: (node: Node) => T, cbNodeArray?: (nodes: NodeArray) => T): T | undefined { - return forEachChild(this, cbNode, cbNodeArray); + public forEachChild(cbNode: (node: ts.Node) => T, cbNodeArray?: (nodes: ts.NodeArray) => T): T | undefined { + return ts.forEachChild(this, cbNode, cbNodeArray); } } - function createChildren(node: Node, sourceFile: SourceFileLike | undefined): Node[] { - if (!isNodeKind(node.kind)) { - return emptyArray; + function createChildren(node: ts.Node, sourceFile: ts.SourceFileLike | undefined): ts.Node[] { + if (!ts.isNodeKind(node.kind)) { + return ts.emptyArray; } - const children: Node[] = []; - - if (isJSDocCommentContainingNode(node)) { + const children: ts.Node[] = []; + if (ts.isJSDocCommentContainingNode(node)) { /** Don't add trivia for "tokens" since this is in a comment. */ node.forEachChild(child => { children.push(child); @@ -145,50 +143,50 @@ namespace ts { return children; } - scanner.setText((sourceFile || node.getSourceFile()).text); + ts.scanner.setText((sourceFile || node.getSourceFile()).text); let pos = node.pos; - const processNode = (child: Node) => { + const processNode = (child: ts.Node) => { addSyntheticNodes(children, pos, child.pos, node); children.push(child); pos = child.end; }; - const processNodes = (nodes: NodeArray) => { + const processNodes = (nodes: ts.NodeArray) => { addSyntheticNodes(children, pos, nodes.pos, node); children.push(createSyntaxList(nodes, node)); pos = nodes.end; }; // jsDocComments need to be the first children - forEach((node as JSDocContainer).jsDoc, processNode); + ts.forEach((node as ts.JSDocContainer).jsDoc, processNode); // For syntactic classifications, all trivia are classified together, including jsdoc comments. // For that to work, the jsdoc comments should still be the leading trivia of the first child. // Restoring the scanner position ensures that. pos = node.pos; node.forEachChild(processNode, processNodes); addSyntheticNodes(children, pos, node.end, node); - scanner.setText(undefined); + ts.scanner.setText(undefined); return children; } - function addSyntheticNodes(nodes: Push, pos: number, end: number, parent: Node): void { - scanner.setTextPos(pos); + function addSyntheticNodes(nodes: ts.Push, pos: number, end: number, parent: ts.Node): void { + ts.scanner.setTextPos(pos); while (pos < end) { - const token = scanner.scan(); - const textPos = scanner.getTextPos(); + const token = ts.scanner.scan(); + const textPos = ts.scanner.getTextPos(); if (textPos <= end) { - if (token === SyntaxKind.Identifier) { - Debug.fail(`Did not expect ${Debug.formatSyntaxKind(parent.kind)} to have an Identifier in its trivia`); + if (token === ts.SyntaxKind.Identifier) { + ts.Debug.fail(`Did not expect ${ts.Debug.formatSyntaxKind(parent.kind)} to have an Identifier in its trivia`); } nodes.push(createNode(token, pos, textPos, parent)); } pos = textPos; - if (token === SyntaxKind.EndOfFileToken) { + if (token === ts.SyntaxKind.EndOfFileToken) { break; } } } - function createSyntaxList(nodes: NodeArray, parent: Node): Node { - const list = createNode(SyntaxKind.SyntaxList, nodes.pos, nodes.end, parent) as any as SyntaxList; + function createSyntaxList(nodes: ts.NodeArray, parent: ts.Node): ts.Node { + const list = createNode(ts.SyntaxKind.SyntaxList, nodes.pos, nodes.end, parent) as any as ts.SyntaxList; list._children = []; let pos = nodes.pos; for (const node of nodes) { @@ -200,33 +198,33 @@ namespace ts { return list; } - class TokenOrIdentifierObject implements Node { - public kind!: SyntaxKind; + class TokenOrIdentifierObject implements ts.Node { + public kind!: ts.SyntaxKind; public pos: number; public end: number; - public flags: NodeFlags; - public modifierFlagsCache: ModifierFlags; - public transformFlags: TransformFlags; - public parent: Node; - public symbol!: Symbol; - public jsDocComments?: JSDoc[]; + public flags: ts.NodeFlags; + public modifierFlagsCache: ts.ModifierFlags; + public transformFlags: ts.TransformFlags; + public parent: ts.Node; + public symbol!: ts.Symbol; + public jsDocComments?: ts.JSDoc[]; constructor(pos: number, end: number) { // Set properties in same order as NodeObject this.pos = pos; this.end = end; - this.flags = NodeFlags.None; - this.modifierFlagsCache = ModifierFlags.None; - this.transformFlags = TransformFlags.None; + this.flags = ts.NodeFlags.None; + this.modifierFlagsCache = ts.ModifierFlags.None; + this.transformFlags = ts.TransformFlags.None; this.parent = undefined!; } - public getSourceFile(): SourceFile { - return getSourceFileOfNode(this); + public getSourceFile(): ts.SourceFile { + return ts.getSourceFileOfNode(this); } - public getStart(sourceFile?: SourceFileLike, includeJsDocComment?: boolean): number { - return getTokenPosOfNode(this, sourceFile, includeJsDocComment); + public getStart(sourceFile?: ts.SourceFileLike, includeJsDocComment?: boolean): number { + return ts.getTokenPosOfNode(this, sourceFile, includeJsDocComment); } public getFullStart(): number { @@ -237,7 +235,7 @@ namespace ts { return this.end; } - public getWidth(sourceFile?: SourceFile): number { + public getWidth(sourceFile?: ts.SourceFile): number { return this.getEnd() - this.getStart(sourceFile); } @@ -245,15 +243,15 @@ namespace ts { return this.end - this.pos; } - public getLeadingTriviaWidth(sourceFile?: SourceFile): number { + public getLeadingTriviaWidth(sourceFile?: ts.SourceFile): number { return this.getStart(sourceFile) - this.pos; } - public getFullText(sourceFile?: SourceFile): string { + public getFullText(sourceFile?: ts.SourceFile): string { return (sourceFile || this.getSourceFile()).text.substring(this.pos, this.end); } - public getText(sourceFile?: SourceFile): string { + public getText(sourceFile?: ts.SourceFile): string { if (!sourceFile) { sourceFile = this.getSourceFile(); } @@ -264,19 +262,19 @@ namespace ts { return this.getChildren().length; } - public getChildAt(index: number): Node { + public getChildAt(index: number): ts.Node { return this.getChildren()[index]; } - public getChildren(): Node[] { - return this.kind === SyntaxKind.EndOfFileToken ? (this as EndOfFileToken).jsDoc || emptyArray : emptyArray; + public getChildren(): ts.Node[] { + return this.kind === ts.SyntaxKind.EndOfFileToken ? (this as ts.EndOfFileToken).jsDoc || ts.emptyArray : ts.emptyArray; } - public getFirstToken(): Node | undefined { + public getFirstToken(): ts.Node | undefined { return undefined; } - public getLastToken(): Node | undefined { + public getLastToken(): ts.Node | undefined { return undefined; } @@ -285,37 +283,34 @@ namespace ts { } } - class SymbolObject implements Symbol { - flags: SymbolFlags; - escapedName: __String; - declarations!: Declaration[]; - valueDeclaration!: Declaration; + class SymbolObject implements ts.Symbol { + flags: ts.SymbolFlags; + escapedName: ts.__String; + declarations!: ts.Declaration[]; + valueDeclaration!: ts.Declaration; // Undefined is used to indicate the value has not been computed. If, after computing, the // symbol has no doc comment, then the empty array will be returned. - documentationComment?: SymbolDisplayPart[]; - tags?: JSDocTagInfo[]; // same - - contextualGetAccessorDocumentationComment?: SymbolDisplayPart[]; - contextualSetAccessorDocumentationComment?: SymbolDisplayPart[]; - - contextualGetAccessorTags?: JSDocTagInfo[]; - contextualSetAccessorTags?: JSDocTagInfo[]; - - constructor(flags: SymbolFlags, name: __String) { + documentationComment?: ts.SymbolDisplayPart[]; + tags?: ts.JSDocTagInfo[]; // same + contextualGetAccessorDocumentationComment?: ts.SymbolDisplayPart[]; + contextualSetAccessorDocumentationComment?: ts.SymbolDisplayPart[]; + contextualGetAccessorTags?: ts.JSDocTagInfo[]; + contextualSetAccessorTags?: ts.JSDocTagInfo[]; + constructor(flags: ts.SymbolFlags, name: ts.__String) { this.flags = flags; this.escapedName = name; } - getFlags(): SymbolFlags { + getFlags(): ts.SymbolFlags { return this.flags; } get name(): string { - return symbolName(this); + return ts.symbolName(this); } - getEscapedName(): __String { + getEscapedName(): ts.__String { return this.escapedName; } @@ -323,16 +318,15 @@ namespace ts { return this.name; } - getDeclarations(): Declaration[] | undefined { + getDeclarations(): ts.Declaration[] | undefined { return this.declarations; } - getDocumentationComment(checker: TypeChecker | undefined): SymbolDisplayPart[] { + getDocumentationComment(checker: ts.TypeChecker | undefined): ts.SymbolDisplayPart[] { if (!this.documentationComment) { - this.documentationComment = emptyArray; // Set temporarily to avoid an infinite loop finding inherited docs - - if (!this.declarations && (this as Symbol as TransientSymbol).target && ((this as Symbol as TransientSymbol).target as TransientSymbol).tupleLabelDeclaration) { - const labelDecl = ((this as Symbol as TransientSymbol).target as TransientSymbol).tupleLabelDeclaration!; + this.documentationComment = ts.emptyArray; // Set temporarily to avoid an infinite loop finding inherited docs + if (!this.declarations && (this as ts.Symbol as ts.TransientSymbol).target && ((this as ts.Symbol as ts.TransientSymbol).target as ts.TransientSymbol).tupleLabelDeclaration) { + const labelDecl = ((this as ts.Symbol as ts.TransientSymbol).target as ts.TransientSymbol).tupleLabelDeclaration!; this.documentationComment = getDocumentationComment([labelDecl], checker); } else { @@ -342,16 +336,16 @@ namespace ts { return this.documentationComment; } - getContextualDocumentationComment(context: Node | undefined, checker: TypeChecker | undefined): SymbolDisplayPart[] { + getContextualDocumentationComment(context: ts.Node | undefined, checker: ts.TypeChecker | undefined): ts.SymbolDisplayPart[] { switch (context?.kind) { - case SyntaxKind.GetAccessor: + case ts.SyntaxKind.GetAccessor: if (!this.contextualGetAccessorDocumentationComment) { - this.contextualGetAccessorDocumentationComment = getDocumentationComment(filter(this.declarations, isGetAccessor), checker); + this.contextualGetAccessorDocumentationComment = getDocumentationComment(ts.filter(this.declarations, ts.isGetAccessor), checker); } return this.contextualGetAccessorDocumentationComment; - case SyntaxKind.SetAccessor: + case ts.SyntaxKind.SetAccessor: if (!this.contextualSetAccessorDocumentationComment) { - this.contextualSetAccessorDocumentationComment = getDocumentationComment(filter(this.declarations, isSetAccessor), checker); + this.contextualSetAccessorDocumentationComment = getDocumentationComment(ts.filter(this.declarations, ts.isSetAccessor), checker); } return this.contextualSetAccessorDocumentationComment; default: @@ -359,7 +353,7 @@ namespace ts { } } - getJsDocTags(checker?: TypeChecker): JSDocTagInfo[] { + getJsDocTags(checker?: ts.TypeChecker): ts.JSDocTagInfo[] { if (this.tags === undefined) { this.tags = getJsDocTagsOfDeclarations(this.declarations, checker); } @@ -367,16 +361,16 @@ namespace ts { return this.tags; } - getContextualJsDocTags(context: Node | undefined, checker: TypeChecker | undefined): JSDocTagInfo[] { + getContextualJsDocTags(context: ts.Node | undefined, checker: ts.TypeChecker | undefined): ts.JSDocTagInfo[] { switch (context?.kind) { - case SyntaxKind.GetAccessor: + case ts.SyntaxKind.GetAccessor: if (!this.contextualGetAccessorTags) { - this.contextualGetAccessorTags = getJsDocTagsOfDeclarations(filter(this.declarations, isGetAccessor), checker); + this.contextualGetAccessorTags = getJsDocTagsOfDeclarations(ts.filter(this.declarations, ts.isGetAccessor), checker); } return this.contextualGetAccessorTags; - case SyntaxKind.SetAccessor: + case ts.SyntaxKind.SetAccessor: if (!this.contextualSetAccessorTags) { - this.contextualSetAccessorTags = getJsDocTagsOfDeclarations(filter(this.declarations, isSetAccessor), checker); + this.contextualSetAccessorTags = getJsDocTagsOfDeclarations(ts.filter(this.declarations, ts.isSetAccessor), checker); } return this.contextualSetAccessorTags; default: @@ -385,7 +379,7 @@ namespace ts { } } - class TokenObject extends TokenOrIdentifierObject implements Token { + class TokenObject extends TokenOrIdentifierObject implements ts.Token { public kind: TKind; constructor(kind: TKind, pos: number, end: number) { @@ -394,10 +388,10 @@ namespace ts { } } - class IdentifierObject extends TokenOrIdentifierObject implements Identifier { - public kind: SyntaxKind.Identifier = SyntaxKind.Identifier; - public escapedText!: __String; - public autoGenerateFlags!: GeneratedIdentifierFlags; + class IdentifierObject extends TokenOrIdentifierObject implements ts.Identifier { + public kind: ts.SyntaxKind.Identifier = ts.SyntaxKind.Identifier; + public escapedText!: ts.__String; + public autoGenerateFlags!: ts.GeneratedIdentifierFlags; _primaryExpressionBrand: any; _memberExpressionBrand: any; _leftHandSideExpressionBrand: any; @@ -405,170 +399,168 @@ namespace ts { _unaryExpressionBrand: any; _expressionBrand: any; _declarationBrand: any; - /*@internal*/typeArguments!: NodeArray; - constructor(_kind: SyntaxKind.Identifier, pos: number, end: number) { + /*@internal*/ typeArguments!: ts.NodeArray; + constructor(_kind: ts.SyntaxKind.Identifier, pos: number, end: number) { super(pos, end); } get text(): string { - return idText(this); + return ts.idText(this); } } - IdentifierObject.prototype.kind = SyntaxKind.Identifier; - class PrivateIdentifierObject extends TokenOrIdentifierObject implements PrivateIdentifier { - public kind!: SyntaxKind.PrivateIdentifier; - public escapedText!: __String; - public symbol!: Symbol; + IdentifierObject.prototype.kind = ts.SyntaxKind.Identifier; + class PrivateIdentifierObject extends TokenOrIdentifierObject implements ts.PrivateIdentifier { + public kind!: ts.SyntaxKind.PrivateIdentifier; + public escapedText!: ts.__String; + public symbol!: ts.Symbol; _primaryExpressionBrand: any; _memberExpressionBrand: any; _leftHandSideExpressionBrand: any; _updateExpressionBrand: any; _unaryExpressionBrand: any; _expressionBrand: any; - constructor(_kind: SyntaxKind.PrivateIdentifier, pos: number, end: number) { + constructor(_kind: ts.SyntaxKind.PrivateIdentifier, pos: number, end: number) { super(pos, end); } get text(): string { - return idText(this); + return ts.idText(this); } } - PrivateIdentifierObject.prototype.kind = SyntaxKind.PrivateIdentifier; - - class TypeObject implements Type { - checker: TypeChecker; - flags: TypeFlags; - objectFlags?: ObjectFlags; + PrivateIdentifierObject.prototype.kind = ts.SyntaxKind.PrivateIdentifier; + class TypeObject implements ts.Type { + checker: ts.TypeChecker; + flags: ts.TypeFlags; + objectFlags?: ts.ObjectFlags; id!: number; - symbol!: Symbol; - constructor(checker: TypeChecker, flags: TypeFlags) { + symbol!: ts.Symbol; + constructor(checker: ts.TypeChecker, flags: ts.TypeFlags) { this.checker = checker; this.flags = flags; } - getFlags(): TypeFlags { + getFlags(): ts.TypeFlags { return this.flags; } - getSymbol(): Symbol | undefined { + getSymbol(): ts.Symbol | undefined { return this.symbol; } - getProperties(): Symbol[] { + getProperties(): ts.Symbol[] { return this.checker.getPropertiesOfType(this); } - getProperty(propertyName: string): Symbol | undefined { + getProperty(propertyName: string): ts.Symbol | undefined { return this.checker.getPropertyOfType(this, propertyName); } - getApparentProperties(): Symbol[] { + getApparentProperties(): ts.Symbol[] { return this.checker.getAugmentedPropertiesOfType(this); } - getCallSignatures(): readonly Signature[] { - return this.checker.getSignaturesOfType(this, SignatureKind.Call); + getCallSignatures(): readonly ts.Signature[] { + return this.checker.getSignaturesOfType(this, ts.SignatureKind.Call); } - getConstructSignatures(): readonly Signature[] { - return this.checker.getSignaturesOfType(this, SignatureKind.Construct); + getConstructSignatures(): readonly ts.Signature[] { + return this.checker.getSignaturesOfType(this, ts.SignatureKind.Construct); } - getStringIndexType(): Type | undefined { - return this.checker.getIndexTypeOfType(this, IndexKind.String); + getStringIndexType(): ts.Type | undefined { + return this.checker.getIndexTypeOfType(this, ts.IndexKind.String); } - getNumberIndexType(): Type | undefined { - return this.checker.getIndexTypeOfType(this, IndexKind.Number); + getNumberIndexType(): ts.Type | undefined { + return this.checker.getIndexTypeOfType(this, ts.IndexKind.Number); } - getBaseTypes(): BaseType[] | undefined { + getBaseTypes(): ts.BaseType[] | undefined { return this.isClassOrInterface() ? this.checker.getBaseTypes(this) : undefined; } isNullableType(): boolean { return this.checker.isNullableType(this); } - getNonNullableType(): Type { + getNonNullableType(): ts.Type { return this.checker.getNonNullableType(this); } - getNonOptionalType(): Type { + getNonOptionalType(): ts.Type { return this.checker.getNonOptionalType(this); } - getConstraint(): Type | undefined { + getConstraint(): ts.Type | undefined { return this.checker.getBaseConstraintOfType(this); } - getDefault(): Type | undefined { + getDefault(): ts.Type | undefined { return this.checker.getDefaultFromTypeParameter(this); } - isUnion(): this is UnionType { - return !!(this.flags & TypeFlags.Union); + isUnion(): this is ts.UnionType { + return !!(this.flags & ts.TypeFlags.Union); } - isIntersection(): this is IntersectionType { - return !!(this.flags & TypeFlags.Intersection); + isIntersection(): this is ts.IntersectionType { + return !!(this.flags & ts.TypeFlags.Intersection); } - isUnionOrIntersection(): this is UnionOrIntersectionType { - return !!(this.flags & TypeFlags.UnionOrIntersection); + isUnionOrIntersection(): this is ts.UnionOrIntersectionType { + return !!(this.flags & ts.TypeFlags.UnionOrIntersection); } - isLiteral(): this is LiteralType { - return !!(this.flags & TypeFlags.StringOrNumberLiteral); + isLiteral(): this is ts.LiteralType { + return !!(this.flags & ts.TypeFlags.StringOrNumberLiteral); } - isStringLiteral(): this is StringLiteralType { - return !!(this.flags & TypeFlags.StringLiteral); + isStringLiteral(): this is ts.StringLiteralType { + return !!(this.flags & ts.TypeFlags.StringLiteral); } - isNumberLiteral(): this is NumberLiteralType { - return !!(this.flags & TypeFlags.NumberLiteral); + isNumberLiteral(): this is ts.NumberLiteralType { + return !!(this.flags & ts.TypeFlags.NumberLiteral); } - isTypeParameter(): this is TypeParameter { - return !!(this.flags & TypeFlags.TypeParameter); + isTypeParameter(): this is ts.TypeParameter { + return !!(this.flags & ts.TypeFlags.TypeParameter); } - isClassOrInterface(): this is InterfaceType { - return !!(getObjectFlags(this) & ObjectFlags.ClassOrInterface); + isClassOrInterface(): this is ts.InterfaceType { + return !!(ts.getObjectFlags(this) & ts.ObjectFlags.ClassOrInterface); } - isClass(): this is InterfaceType { - return !!(getObjectFlags(this) & ObjectFlags.Class); + isClass(): this is ts.InterfaceType { + return !!(ts.getObjectFlags(this) & ts.ObjectFlags.Class); } - isIndexType(): this is IndexType { - return !!(this.flags & TypeFlags.Index); + isIndexType(): this is ts.IndexType { + return !!(this.flags & ts.TypeFlags.Index); } /** * This polyfills `referenceType.typeArguments` for API consumers */ get typeArguments() { - if (getObjectFlags(this) & ObjectFlags.Reference) { - return this.checker.getTypeArguments(this as Type as TypeReference); + if (ts.getObjectFlags(this) & ts.ObjectFlags.Reference) { + return this.checker.getTypeArguments(this as ts.Type as ts.TypeReference); } return undefined; } } - class SignatureObject implements Signature { - flags: SignatureFlags; - checker: TypeChecker; - declaration!: SignatureDeclaration; - typeParameters?: TypeParameter[]; - parameters!: Symbol[]; - thisParameter!: Symbol; - resolvedReturnType!: Type; - resolvedTypePredicate: TypePredicate | undefined; + class SignatureObject implements ts.Signature { + flags: ts.SignatureFlags; + checker: ts.TypeChecker; + declaration!: ts.SignatureDeclaration; + typeParameters?: ts.TypeParameter[]; + parameters!: ts.Symbol[]; + thisParameter!: ts.Symbol; + resolvedReturnType!: ts.Type; + resolvedTypePredicate: ts.TypePredicate | undefined; minTypeArgumentCount!: number; minArgumentCount!: number; // Undefined is used to indicate the value has not been computed. If, after computing, the // symbol has no doc comment, then the empty array will be returned. - documentationComment?: SymbolDisplayPart[]; - jsDocTags?: JSDocTagInfo[]; // same - - constructor(checker: TypeChecker, flags: SignatureFlags) { + documentationComment?: ts.SymbolDisplayPart[]; + jsDocTags?: ts.JSDocTagInfo[]; // same + constructor(checker: ts.TypeChecker, flags: ts.SignatureFlags) { this.checker = checker; this.flags = flags; } - getDeclaration(): SignatureDeclaration { + getDeclaration(): ts.SignatureDeclaration { return this.declaration; } - getTypeParameters(): TypeParameter[] | undefined { + getTypeParameters(): ts.TypeParameter[] | undefined { return this.typeParameters; } - getParameters(): Symbol[] { + getParameters(): ts.Symbol[] { return this.parameters; } - getReturnType(): Type { + getReturnType(): ts.Type { return this.checker.getReturnTypeOfSignature(this); } - getTypeParameterAtPosition(pos: number): Type { + getTypeParameterAtPosition(pos: number): ts.Type { const type = this.checker.getParameterType(this, pos); - if (type.isIndexType() && isThisTypeParameter(type.type)) { + if (type.isIndexType() && ts.isThisTypeParameter(type.type)) { const constraint = type.type.getConstraint(); if (constraint) { return this.checker.getIndexType(constraint); @@ -577,12 +569,12 @@ namespace ts { return type; } - getDocumentationComment(): SymbolDisplayPart[] { - return this.documentationComment || (this.documentationComment = getDocumentationComment(singleElementArray(this.declaration), this.checker)); + getDocumentationComment(): ts.SymbolDisplayPart[] { + return this.documentationComment || (this.documentationComment = getDocumentationComment(ts.singleElementArray(this.declaration), this.checker)); } - getJsDocTags(): JSDocTagInfo[] { - return this.jsDocTags || (this.jsDocTags = getJsDocTagsOfDeclarations(singleElementArray(this.declaration), this.checker)); + getJsDocTags(): ts.JSDocTagInfo[] { + return this.jsDocTags || (this.jsDocTags = getJsDocTagsOfDeclarations(ts.singleElementArray(this.declaration), this.checker)); } } @@ -591,21 +583,20 @@ namespace ts { * @param node the Node in question. * @returns `true` if `node` has a JSDoc "inheritDoc" tag on it, otherwise `false`. */ - function hasJSDocInheritDocTag(node: Node) { - return getJSDocTags(node).some(tag => tag.tagName.text === "inheritDoc" || tag.tagName.text === "inheritdoc"); + function hasJSDocInheritDocTag(node: ts.Node) { + return ts.getJSDocTags(node).some(tag => tag.tagName.text === "inheritDoc" || tag.tagName.text === "inheritdoc"); } - - function getJsDocTagsOfDeclarations(declarations: Declaration[] | undefined, checker: TypeChecker | undefined): JSDocTagInfo[] { - if (!declarations) return emptyArray; - - let tags = JsDoc.getJsDocTagsFromDeclarations(declarations, checker); + function getJsDocTagsOfDeclarations(declarations: ts.Declaration[] | undefined, checker: ts.TypeChecker | undefined): ts.JSDocTagInfo[] { + if (!declarations) + return ts.emptyArray; + let tags = ts.JsDoc.getJsDocTagsFromDeclarations(declarations, checker); if (checker && (tags.length === 0 || declarations.some(hasJSDocInheritDocTag))) { - const seenSymbols = new Set(); + const seenSymbols = new ts.Set(); for (const declaration of declarations) { const inheritedTags = findBaseOfDeclaration(checker, declaration, symbol => { if (!seenSymbols.has(symbol)) { seenSymbols.add(symbol); - if (declaration.kind === SyntaxKind.GetAccessor || declaration.kind === SyntaxKind.SetAccessor) { + if (declaration.kind === ts.SyntaxKind.GetAccessor || declaration.kind === ts.SyntaxKind.SetAccessor) { return symbol.getContextualJsDocTags(declaration, checker); } return symbol.declarations?.length === 1 ? symbol.getJsDocTags() : undefined; @@ -619,113 +610,114 @@ namespace ts { return tags; } - function getDocumentationComment(declarations: readonly Declaration[] | undefined, checker: TypeChecker | undefined): SymbolDisplayPart[] { - if (!declarations) return emptyArray; - - let doc = JsDoc.getJsDocCommentsFromDeclarations(declarations, checker); + function getDocumentationComment(declarations: readonly ts.Declaration[] | undefined, checker: ts.TypeChecker | undefined): ts.SymbolDisplayPart[] { + if (!declarations) + return ts.emptyArray; + let doc = ts.JsDoc.getJsDocCommentsFromDeclarations(declarations, checker); if (checker && (doc.length === 0 || declarations.some(hasJSDocInheritDocTag))) { - const seenSymbols = new Set(); + const seenSymbols = new ts.Set(); for (const declaration of declarations) { const inheritedDocs = findBaseOfDeclaration(checker, declaration, symbol => { if (!seenSymbols.has(symbol)) { seenSymbols.add(symbol); - if (declaration.kind === SyntaxKind.GetAccessor || declaration.kind === SyntaxKind.SetAccessor) { + if (declaration.kind === ts.SyntaxKind.GetAccessor || declaration.kind === ts.SyntaxKind.SetAccessor) { return symbol.getContextualDocumentationComment(declaration, checker); } return symbol.getDocumentationComment(checker); } }); // TODO: GH#16312 Return a ReadonlyArray, avoid copying inheritedDocs - if (inheritedDocs) doc = doc.length === 0 ? inheritedDocs.slice() : inheritedDocs.concat(lineBreakPart(), doc); + if (inheritedDocs) + doc = doc.length === 0 ? inheritedDocs.slice() : inheritedDocs.concat(ts.lineBreakPart(), doc); } } return doc; } - function findBaseOfDeclaration(checker: TypeChecker, declaration: Declaration, cb: (symbol: Symbol) => T[] | undefined): T[] | undefined { - const classOrInterfaceDeclaration = declaration.parent?.kind === SyntaxKind.Constructor ? declaration.parent.parent : declaration.parent; - if (!classOrInterfaceDeclaration) return; - - const isStaticMember = hasStaticModifier(declaration); - return firstDefined(getAllSuperTypeNodes(classOrInterfaceDeclaration), superTypeNode => { + function findBaseOfDeclaration(checker: ts.TypeChecker, declaration: ts.Declaration, cb: (symbol: ts.Symbol) => T[] | undefined): T[] | undefined { + const classOrInterfaceDeclaration = declaration.parent?.kind === ts.SyntaxKind.Constructor ? declaration.parent.parent : declaration.parent; + if (!classOrInterfaceDeclaration) + return; + const isStaticMember = ts.hasStaticModifier(declaration); + return ts.firstDefined(ts.getAllSuperTypeNodes(classOrInterfaceDeclaration), superTypeNode => { const baseType = checker.getTypeAtLocation(superTypeNode); const symbol = isStaticMember - ? find(checker.getExportsOfModule(baseType.symbol), s => s.escapedName === declaration.symbol.name) + ? ts.find(checker.getExportsOfModule(baseType.symbol), s => s.escapedName === declaration.symbol.name) : checker.getPropertyOfType(baseType, declaration.symbol.name); return symbol ? cb(symbol) : undefined; }); } - class SourceFileObject extends NodeObject implements SourceFile { - public kind: SyntaxKind.SourceFile = SyntaxKind.SourceFile; + class SourceFileObject extends NodeObject implements ts.SourceFile { + public kind: ts.SyntaxKind.SourceFile = ts.SyntaxKind.SourceFile; public _declarationBrand: any; public fileName!: string; - public path!: Path; - public resolvedPath!: Path; + public path!: ts.Path; + public resolvedPath!: ts.Path; public originalFileName!: string; public text!: string; - public scriptSnapshot!: IScriptSnapshot; + public scriptSnapshot!: ts.IScriptSnapshot; public lineMap!: readonly number[]; - public statements!: NodeArray; - public endOfFileToken!: Token; - - public amdDependencies!: { name: string; path: string }[]; + public statements!: ts.NodeArray; + public endOfFileToken!: ts.Token; + public amdDependencies!: { + name: string; + path: string; + }[]; public moduleName!: string; - public referencedFiles!: FileReference[]; - public typeReferenceDirectives!: FileReference[]; - public libReferenceDirectives!: FileReference[]; - - public syntacticDiagnostics!: DiagnosticWithLocation[]; - public parseDiagnostics!: DiagnosticWithLocation[]; - public bindDiagnostics!: DiagnosticWithLocation[]; - public bindSuggestionDiagnostics?: DiagnosticWithLocation[]; + public referencedFiles!: ts.FileReference[]; + public typeReferenceDirectives!: ts.FileReference[]; + public libReferenceDirectives!: ts.FileReference[]; + public syntacticDiagnostics!: ts.DiagnosticWithLocation[]; + public parseDiagnostics!: ts.DiagnosticWithLocation[]; + public bindDiagnostics!: ts.DiagnosticWithLocation[]; + public bindSuggestionDiagnostics?: ts.DiagnosticWithLocation[]; public isDeclarationFile!: boolean; public isDefaultLib!: boolean; public hasNoDefaultLib!: boolean; - public externalModuleIndicator!: Node; // The first node that causes this file to be an external module - public commonJsModuleIndicator!: Node; // The first node that causes this file to be a CommonJS module + public externalModuleIndicator!: ts.Node; // The first node that causes this file to be an external module + public commonJsModuleIndicator!: ts.Node; // The first node that causes this file to be a CommonJS module public nodeCount!: number; public identifierCount!: number; public symbolCount!: number; public version!: string; - public scriptKind!: ScriptKind; - public languageVersion!: ScriptTarget; - public languageVariant!: LanguageVariant; - public identifiers!: ESMap; - public nameTable: UnderscoreEscapedMap | undefined; - public resolvedModules: ModeAwareCache | undefined; - public resolvedTypeReferenceDirectiveNames!: ModeAwareCache; - public imports!: readonly StringLiteralLike[]; - public moduleAugmentations!: StringLiteral[]; - private namedDeclarations: ESMap | undefined; + public scriptKind!: ts.ScriptKind; + public languageVersion!: ts.ScriptTarget; + public languageVariant!: ts.LanguageVariant; + public identifiers!: ts.ESMap; + public nameTable: ts.UnderscoreEscapedMap | undefined; + public resolvedModules: ts.ModeAwareCache | undefined; + public resolvedTypeReferenceDirectiveNames!: ts.ModeAwareCache; + public imports!: readonly ts.StringLiteralLike[]; + public moduleAugmentations!: ts.StringLiteral[]; + private namedDeclarations: ts.ESMap | undefined; public ambientModuleNames!: string[]; - public checkJsDirective: CheckJsDirective | undefined; - public errorExpectations: TextRange[] | undefined; + public checkJsDirective: ts.CheckJsDirective | undefined; + public errorExpectations: ts.TextRange[] | undefined; public possiblyContainDynamicImport?: boolean; - public pragmas!: PragmaMap; - public localJsxFactory: EntityName | undefined; - public localJsxNamespace: __String | undefined; - - constructor(kind: SyntaxKind, pos: number, end: number) { + public pragmas!: ts.PragmaMap; + public localJsxFactory: ts.EntityName | undefined; + public localJsxNamespace: ts.__String | undefined; + constructor(kind: ts.SyntaxKind, pos: number, end: number) { super(kind, pos, end); } - public update(newText: string, textChangeRange: TextChangeRange): SourceFile { - return updateSourceFile(this, newText, textChangeRange); + public update(newText: string, textChangeRange: ts.TextChangeRange): ts.SourceFile { + return ts.updateSourceFile(this, newText, textChangeRange); } - public getLineAndCharacterOfPosition(position: number): LineAndCharacter { - return getLineAndCharacterOfPosition(this, position); + public getLineAndCharacterOfPosition(position: number): ts.LineAndCharacter { + return ts.getLineAndCharacterOfPosition(this, position); } public getLineStarts(): readonly number[] { - return getLineStarts(this); + return ts.getLineStarts(this); } public getPositionOfLineAndCharacter(line: number, character: number, allowEdits?: true): number { - return computePositionOfLineAndCharacter(getLineStarts(this), line, character, this.text, allowEdits); + return ts.computePositionOfLineAndCharacter(ts.getLineStarts(this), line, character, this.text, allowEdits); } public getLineEndOfPosition(pos: number): number { @@ -745,7 +737,7 @@ namespace ts { return fullText[lastCharPos] === "\n" && fullText[lastCharPos - 1] === "\r" ? lastCharPos - 1 : lastCharPos; } - public getNamedDeclarations(): ESMap { + public getNamedDeclarations(): ts.ESMap { if (!this.namedDeclarations) { this.namedDeclarations = this.computeNamedDeclarations(); } @@ -753,14 +745,14 @@ namespace ts { return this.namedDeclarations; } - private computeNamedDeclarations(): ESMap { - const result = createMultiMap(); + private computeNamedDeclarations(): ts.ESMap { + const result = ts.createMultiMap(); this.forEachChild(visit); return result; - function addDeclaration(declaration: Declaration) { + function addDeclaration(declaration: ts.Declaration) { const name = getDeclarationName(declaration); if (name) { result.add(name, declaration); @@ -775,30 +767,30 @@ namespace ts { return declarations; } - function getDeclarationName(declaration: Declaration) { - const name = getNonAssignedNameOfDeclaration(declaration); - return name && (isComputedPropertyName(name) && isPropertyAccessExpression(name.expression) ? name.expression.name.text - : isPropertyName(name) ? getNameFromPropertyName(name) : undefined); + function getDeclarationName(declaration: ts.Declaration) { + const name = ts.getNonAssignedNameOfDeclaration(declaration); + return name && (ts.isComputedPropertyName(name) && ts.isPropertyAccessExpression(name.expression) ? name.expression.name.text + : ts.isPropertyName(name) ? ts.getNameFromPropertyName(name) : undefined); } - function visit(node: Node): void { + function visit(node: ts.Node): void { switch (node.kind) { - case SyntaxKind.FunctionDeclaration: - case SyntaxKind.FunctionExpression: - case SyntaxKind.MethodDeclaration: - case SyntaxKind.MethodSignature: - const functionDeclaration = node as FunctionLikeDeclaration; + case ts.SyntaxKind.FunctionDeclaration: + case ts.SyntaxKind.FunctionExpression: + case ts.SyntaxKind.MethodDeclaration: + case ts.SyntaxKind.MethodSignature: + const functionDeclaration = node as ts.FunctionLikeDeclaration; const declarationName = getDeclarationName(functionDeclaration); if (declarationName) { const declarations = getDeclarations(declarationName); - const lastDeclaration = lastOrUndefined(declarations); + const lastDeclaration = ts.lastOrUndefined(declarations); // Check whether this declaration belongs to an "overload group". if (lastDeclaration && functionDeclaration.parent === lastDeclaration.parent && functionDeclaration.symbol === lastDeclaration.symbol) { // Overwrite the last declaration if it was an overload // and this one is an implementation. - if (functionDeclaration.body && !(lastDeclaration as FunctionLikeDeclaration).body) { + if (functionDeclaration.body && !(lastDeclaration as ts.FunctionLikeDeclaration).body) { declarations[declarations.length - 1] = functionDeclaration; } } @@ -806,39 +798,39 @@ namespace ts { declarations.push(functionDeclaration); } } - forEachChild(node, visit); + ts.forEachChild(node, visit); break; - case SyntaxKind.ClassDeclaration: - case SyntaxKind.ClassExpression: - case SyntaxKind.InterfaceDeclaration: - case SyntaxKind.TypeAliasDeclaration: - case SyntaxKind.EnumDeclaration: - case SyntaxKind.ModuleDeclaration: - case SyntaxKind.ImportEqualsDeclaration: - case SyntaxKind.ExportSpecifier: - case SyntaxKind.ImportSpecifier: - case SyntaxKind.ImportClause: - case SyntaxKind.NamespaceImport: - case SyntaxKind.GetAccessor: - case SyntaxKind.SetAccessor: - case SyntaxKind.TypeLiteral: - addDeclaration(node as Declaration); - forEachChild(node, visit); + case ts.SyntaxKind.ClassDeclaration: + case ts.SyntaxKind.ClassExpression: + case ts.SyntaxKind.InterfaceDeclaration: + case ts.SyntaxKind.TypeAliasDeclaration: + case ts.SyntaxKind.EnumDeclaration: + case ts.SyntaxKind.ModuleDeclaration: + case ts.SyntaxKind.ImportEqualsDeclaration: + case ts.SyntaxKind.ExportSpecifier: + case ts.SyntaxKind.ImportSpecifier: + case ts.SyntaxKind.ImportClause: + case ts.SyntaxKind.NamespaceImport: + case ts.SyntaxKind.GetAccessor: + case ts.SyntaxKind.SetAccessor: + case ts.SyntaxKind.TypeLiteral: + addDeclaration(node as ts.Declaration); + ts.forEachChild(node, visit); break; - case SyntaxKind.Parameter: + case ts.SyntaxKind.Parameter: // Only consider parameter properties - if (!hasSyntacticModifier(node, ModifierFlags.ParameterPropertyModifier)) { + if (!ts.hasSyntacticModifier(node, ts.ModifierFlags.ParameterPropertyModifier)) { break; } // falls through - case SyntaxKind.VariableDeclaration: - case SyntaxKind.BindingElement: { - const decl = node as VariableDeclaration; - if (isBindingPattern(decl.name)) { - forEachChild(decl.name, visit); + case ts.SyntaxKind.VariableDeclaration: + case ts.SyntaxKind.BindingElement: { + const decl = node as ts.VariableDeclaration; + if (ts.isBindingPattern(decl.name)) { + ts.forEachChild(decl.name, visit); break; } if (decl.initializer) { @@ -846,19 +838,19 @@ namespace ts { } } // falls through - case SyntaxKind.EnumMember: - case SyntaxKind.PropertyDeclaration: - case SyntaxKind.PropertySignature: - addDeclaration(node as Declaration); + case ts.SyntaxKind.EnumMember: + case ts.SyntaxKind.PropertyDeclaration: + case ts.SyntaxKind.PropertySignature: + addDeclaration(node as ts.Declaration); break; - case SyntaxKind.ExportDeclaration: + case ts.SyntaxKind.ExportDeclaration: // Handle named exports case e.g.: // export {a, b as B} from "mod"; - const exportDeclaration = node as ExportDeclaration; + const exportDeclaration = node as ts.ExportDeclaration; if (exportDeclaration.exportClause) { - if (isNamedExports(exportDeclaration.exportClause)) { - forEach(exportDeclaration.exportClause.elements, visit); + if (ts.isNamedExports(exportDeclaration.exportClause)) { + ts.forEach(exportDeclaration.exportClause.elements, visit); } else { visit(exportDeclaration.exportClause.name); @@ -866,8 +858,8 @@ namespace ts { } break; - case SyntaxKind.ImportDeclaration: - const importClause = (node as ImportDeclaration).importClause; + case ts.SyntaxKind.ImportDeclaration: + const importClause = (node as ts.ImportDeclaration).importClause; if (importClause) { // Handle default import case e.g.: // import d from "mod"; @@ -879,39 +871,39 @@ namespace ts { // import * as NS from "mod"; // import {a, b as B} from "mod"; if (importClause.namedBindings) { - if (importClause.namedBindings.kind === SyntaxKind.NamespaceImport) { + if (importClause.namedBindings.kind === ts.SyntaxKind.NamespaceImport) { addDeclaration(importClause.namedBindings); } else { - forEach(importClause.namedBindings.elements, visit); + ts.forEach(importClause.namedBindings.elements, visit); } } } break; - case SyntaxKind.BinaryExpression: - if (getAssignmentDeclarationKind(node as BinaryExpression) !== AssignmentDeclarationKind.None) { - addDeclaration(node as BinaryExpression); + case ts.SyntaxKind.BinaryExpression: + if (ts.getAssignmentDeclarationKind(node as ts.BinaryExpression) !== ts.AssignmentDeclarationKind.None) { + addDeclaration(node as ts.BinaryExpression); } // falls through default: - forEachChild(node, visit); + ts.forEachChild(node, visit); } } } } - class SourceMapSourceObject implements SourceMapSource { + class SourceMapSourceObject implements ts.SourceMapSource { lineMap!: number[]; constructor(public fileName: string, public text: string, public skipTrivia?: (pos: number) => number) { } - public getLineAndCharacterOfPosition(pos: number): LineAndCharacter { - return getLineAndCharacterOfPosition(this, pos); + public getLineAndCharacterOfPosition(pos: number): ts.LineAndCharacter { + return ts.getLineAndCharacterOfPosition(this, pos); } } - function getServicesObjectAllocator(): ObjectAllocator { + function getServicesObjectAllocator(): ts.ObjectAllocator { return { getNodeConstructor: () => NodeObject, getTokenConstructor: () => TokenObject, @@ -932,22 +924,22 @@ namespace ts { interface HostFileInformation { hostFileName: string; version: string; - scriptSnapshot: IScriptSnapshot; - scriptKind: ScriptKind; + scriptSnapshot: ts.IScriptSnapshot; + scriptKind: ts.ScriptKind; } /* @internal */ - export interface DisplayPartsSymbolWriter extends EmitTextWriter { - displayParts(): SymbolDisplayPart[]; + export interface DisplayPartsSymbolWriter extends ts.EmitTextWriter { + displayParts(): ts.SymbolDisplayPart[]; } /* @internal */ - export function toEditorSettings(options: FormatCodeOptions | FormatCodeSettings): FormatCodeSettings; - export function toEditorSettings(options: EditorOptions | EditorSettings): EditorSettings; - export function toEditorSettings(optionsAsMap: MapLike): MapLike { + export function toEditorSettings(options: ts.FormatCodeOptions | ts.FormatCodeSettings): ts.FormatCodeSettings; + export function toEditorSettings(options: ts.EditorOptions | ts.EditorSettings): ts.EditorSettings; + export function toEditorSettings(optionsAsMap: ts.MapLike): ts.MapLike { let allPropertiesAreCamelCased = true; for (const key in optionsAsMap) { - if (hasProperty(optionsAsMap, key) && !isCamelCase(key)) { + if (ts.hasProperty(optionsAsMap, key) && !isCamelCase(key)) { allPropertiesAreCamelCased = false; break; } @@ -955,9 +947,9 @@ namespace ts { if (allPropertiesAreCamelCased) { return optionsAsMap; } - const settings: MapLike = {}; + const settings: ts.MapLike = {}; for (const key in optionsAsMap) { - if (hasProperty(optionsAsMap, key)) { + if (ts.hasProperty(optionsAsMap, key)) { const newKey = isCamelCase(key) ? key : key.charAt(0).toLowerCase() + key.substr(1); settings[newKey] = optionsAsMap[key]; } @@ -969,24 +961,24 @@ namespace ts { return !s.length || s.charAt(0) === s.charAt(0).toLowerCase(); } - export function displayPartsToString(displayParts: SymbolDisplayPart[] | undefined) { + export function displayPartsToString(displayParts: ts.SymbolDisplayPart[] | undefined) { if (displayParts) { - return map(displayParts, displayPart => displayPart.text).join(""); + return ts.map(displayParts, displayPart => displayPart.text).join(""); } return ""; } - export function getDefaultCompilerOptions(): CompilerOptions { + export function getDefaultCompilerOptions(): ts.CompilerOptions { // Always default to "ScriptTarget.ES5" for the language service return { - target: ScriptTarget.ES5, - jsx: JsxEmit.Preserve + target: ts.ScriptTarget.ES5, + jsx: ts.JsxEmit.Preserve }; } export function getSupportedCodeFixes() { - return codefix.getSupportedErrorCodes(); + return ts.codefix.getSupportedErrorCodes(); } // Either it will be file name if host doesnt have file or it will be the host's file information @@ -996,24 +988,24 @@ namespace ts { // at each language service public entry point, since we don't know when // the set of scripts handled by the host changes. class HostCache { - private fileNameToEntry: ESMap; + private fileNameToEntry: ts.ESMap; private currentDirectory: string; - constructor(private host: LanguageServiceHost, getCanonicalFileName: GetCanonicalFileName) { + constructor(private host: ts.LanguageServiceHost, getCanonicalFileName: ts.GetCanonicalFileName) { // script id => script index this.currentDirectory = host.getCurrentDirectory(); - this.fileNameToEntry = new Map(); + this.fileNameToEntry = new ts.Map(); // Initialize the list with the root file names const rootFileNames = host.getScriptFileNames(); - tracing?.push(tracing.Phase.Session, "initializeHostCache", { count: rootFileNames.length }); + ts.tracing?.push(ts.tracing.Phase.Session, "initializeHostCache", { count: rootFileNames.length }); for (const fileName of rootFileNames) { - this.createEntry(fileName, toPath(fileName, this.currentDirectory, getCanonicalFileName)); + this.createEntry(fileName, ts.toPath(fileName, this.currentDirectory, getCanonicalFileName)); } - tracing?.pop(); + ts.tracing?.pop(); } - private createEntry(fileName: string, path: Path) { + private createEntry(fileName: string, path: ts.Path) { let entry: CachedHostFileInformation; const scriptSnapshot = this.host.getScriptSnapshot(fileName); if (scriptSnapshot) { @@ -1021,7 +1013,7 @@ namespace ts { hostFileName: fileName, version: this.host.getScriptVersion(fileName), scriptSnapshot, - scriptKind: getScriptKind(fileName, this.host) + scriptKind: ts.getScriptKind(fileName, this.host) }; } else { @@ -1032,24 +1024,24 @@ namespace ts { return entry; } - public getEntryByPath(path: Path): CachedHostFileInformation | undefined { + public getEntryByPath(path: ts.Path): CachedHostFileInformation | undefined { return this.fileNameToEntry.get(path); } - public getHostFileInformation(path: Path): HostFileInformation | undefined { + public getHostFileInformation(path: ts.Path): HostFileInformation | undefined { const entry = this.fileNameToEntry.get(path); - return !isString(entry) ? entry : undefined; + return !ts.isString(entry) ? entry : undefined; } - public getOrCreateEntryByPath(fileName: string, path: Path): HostFileInformation { + public getOrCreateEntryByPath(fileName: string, path: ts.Path): HostFileInformation { const info = this.getEntryByPath(path) || this.createEntry(fileName, path); - return isString(info) ? undefined! : info; // TODO: GH#18217 + return ts.isString(info) ? undefined! : info; // TODO: GH#18217 } public getRootFileNames(): string[] { const names: string[] = []; this.fileNameToEntry.forEach(entry => { - if (isString(entry)) { + if (ts.isString(entry)) { names.push(entry); } else { @@ -1059,7 +1051,7 @@ namespace ts { return names; } - public getScriptSnapshot(path: Path): IScriptSnapshot { + public getScriptSnapshot(path: ts.Path): ts.IScriptSnapshot { const file = this.getHostFileInformation(path); return (file && file.scriptSnapshot)!; // TODO: GH#18217 } @@ -1070,34 +1062,28 @@ namespace ts { // currently edited file. private currentFileName: string | undefined; private currentFileVersion: string | undefined; - private currentFileScriptSnapshot: IScriptSnapshot | undefined; - private currentSourceFile: SourceFile | undefined; - - constructor(private host: LanguageServiceHost) { + private currentFileScriptSnapshot: ts.IScriptSnapshot | undefined; + private currentSourceFile: ts.SourceFile | undefined; + constructor(private host: ts.LanguageServiceHost) { } - public getCurrentSourceFile(fileName: string): SourceFile { + public getCurrentSourceFile(fileName: string): ts.SourceFile { const scriptSnapshot = this.host.getScriptSnapshot(fileName); if (!scriptSnapshot) { // The host does not know about this file. throw new Error("Could not find file: '" + fileName + "'."); } - const scriptKind = getScriptKind(fileName, this.host); + const scriptKind = ts.getScriptKind(fileName, this.host); const version = this.host.getScriptVersion(fileName); - let sourceFile: SourceFile | undefined; + let sourceFile: ts.SourceFile | undefined; if (this.currentFileName !== fileName) { // This is a new file, just parse it - const options: CreateSourceFileOptions = { - languageVersion: ScriptTarget.Latest, - impliedNodeFormat: getImpliedNodeFormatForFile( - toPath(fileName, this.host.getCurrentDirectory(), this.host.getCompilerHost?.()?.getCanonicalFileName || hostGetCanonicalFileName(this.host)), - this.host.getCompilerHost?.()?.getModuleResolutionCache?.()?.getPackageJsonInfoCache(), - this.host, - this.host.getCompilationSettings() - ), - setExternalModuleIndicator: getSetExternalModuleIndicator(this.host.getCompilationSettings()) + const options: ts.CreateSourceFileOptions = { + languageVersion: ts.ScriptTarget.Latest, + impliedNodeFormat: ts.getImpliedNodeFormatForFile(ts.toPath(fileName, this.host.getCurrentDirectory(), this.host.getCompilerHost?.()?.getCanonicalFileName || ts.hostGetCanonicalFileName(this.host)), this.host.getCompilerHost?.()?.getModuleResolutionCache?.()?.getPackageJsonInfoCache(), this.host, this.host.getCompilationSettings()), + setExternalModuleIndicator: ts.getSetExternalModuleIndicator(this.host.getCompilationSettings()) }; sourceFile = createLanguageServiceSourceFile(fileName, scriptSnapshot, options, version, /*setNodeParents*/ true, scriptKind); } @@ -1119,18 +1105,18 @@ namespace ts { } } - function setSourceFileFields(sourceFile: SourceFile, scriptSnapshot: IScriptSnapshot, version: string) { + function setSourceFileFields(sourceFile: ts.SourceFile, scriptSnapshot: ts.IScriptSnapshot, version: string) { sourceFile.version = version; sourceFile.scriptSnapshot = scriptSnapshot; } - export function createLanguageServiceSourceFile(fileName: string, scriptSnapshot: IScriptSnapshot, scriptTargetOrOptions: ScriptTarget | CreateSourceFileOptions, version: string, setNodeParents: boolean, scriptKind?: ScriptKind): SourceFile { - const sourceFile = createSourceFile(fileName, getSnapshotText(scriptSnapshot), scriptTargetOrOptions, setNodeParents, scriptKind); + export function createLanguageServiceSourceFile(fileName: string, scriptSnapshot: ts.IScriptSnapshot, scriptTargetOrOptions: ts.ScriptTarget | ts.CreateSourceFileOptions, version: string, setNodeParents: boolean, scriptKind?: ts.ScriptKind): ts.SourceFile { + const sourceFile = ts.createSourceFile(fileName, ts.getSnapshotText(scriptSnapshot), scriptTargetOrOptions, setNodeParents, scriptKind); setSourceFileFields(sourceFile, scriptSnapshot, version); return sourceFile; } - export function updateLanguageServiceSourceFile(sourceFile: SourceFile, scriptSnapshot: IScriptSnapshot, version: string, textChangeRange: TextChangeRange | undefined, aggressiveChecks?: boolean): SourceFile { + export function updateLanguageServiceSourceFile(sourceFile: ts.SourceFile, scriptSnapshot: ts.IScriptSnapshot, version: string, textChangeRange: ts.TextChangeRange | undefined, aggressiveChecks?: boolean): ts.SourceFile { // If we were given a text change range, and our version or open-ness changed, then // incrementally parse this file. if (textChangeRange) { @@ -1143,8 +1129,8 @@ namespace ts { : ""; // grab the fragment from the end of the span till the end of the original text - const suffix = textSpanEnd(textChangeRange.span) !== sourceFile.text.length - ? sourceFile.text.substr(textSpanEnd(textChangeRange.span)) + const suffix = ts.textSpanEnd(textChangeRange.span) !== sourceFile.text.length + ? sourceFile.text.substr(ts.textSpanEnd(textChangeRange.span)) : ""; if (textChangeRange.newLength === 0) { @@ -1162,7 +1148,7 @@ namespace ts { : (changedText + suffix); } - const newSourceFile = updateSourceFile(sourceFile, newText, textChangeRange, aggressiveChecks); + const newSourceFile = ts.updateSourceFile(sourceFile, newText, textChangeRange, aggressiveChecks); setSourceFileFields(newSourceFile, scriptSnapshot, version); // after incremental parsing nameTable might not be up-to-date // drop it so it can be lazily recreated later @@ -1181,7 +1167,7 @@ namespace ts { } } - const options: CreateSourceFileOptions = { + const options: ts.CreateSourceFileOptions = { languageVersion: sourceFile.languageVersion, impliedNodeFormat: sourceFile.impliedNodeFormat, setExternalModuleIndicator: sourceFile.setExternalModuleIndicator, @@ -1190,13 +1176,13 @@ namespace ts { return createLanguageServiceSourceFile(sourceFile.fileName, scriptSnapshot, options, version, /*setNodeParents*/ true, sourceFile.scriptKind); } - const NoopCancellationToken: CancellationToken = { - isCancellationRequested: returnFalse, - throwIfCancellationRequested: noop, + const NoopCancellationToken: ts.CancellationToken = { + isCancellationRequested: ts.returnFalse, + throwIfCancellationRequested: ts.noop, }; - class CancellationTokenObject implements CancellationToken { - constructor(private cancellationToken: HostCancellationToken) { + class CancellationTokenObject implements ts.CancellationToken { + constructor(private cancellationToken: ts.HostCancellationToken) { } public isCancellationRequested(): boolean { @@ -1205,25 +1191,25 @@ namespace ts { public throwIfCancellationRequested(): void { if (this.isCancellationRequested()) { - tracing?.instant(tracing.Phase.Session, "cancellationThrown", { kind: "CancellationTokenObject" }); - throw new OperationCanceledException(); + ts.tracing?.instant(ts.tracing.Phase.Session, "cancellationThrown", { kind: "CancellationTokenObject" }); + throw new ts.OperationCanceledException(); } } } /* @internal */ /** A cancellation that throttles calls to the host */ - export class ThrottledCancellationToken implements CancellationToken { + export class ThrottledCancellationToken implements ts.CancellationToken { // Store when we last tried to cancel. Checking cancellation can be expensive (as we have // to marshall over to the host layer). So we only bother actually checking once enough // time has passed. private lastCancellationCheckTime = 0; - constructor(private hostCancellationToken: HostCancellationToken, private readonly throttleWaitMilliseconds = 20) { + constructor(private hostCancellationToken: ts.HostCancellationToken, private readonly throttleWaitMilliseconds = 20) { } public isCancellationRequested(): boolean { - const time = timestamp(); + const time = ts.timestamp(); const duration = Math.abs(time - this.lastCancellationCheckTime); if (duration >= this.throttleWaitMilliseconds) { // Check no more than once every throttle wait milliseconds @@ -1236,13 +1222,13 @@ namespace ts { public throwIfCancellationRequested(): void { if (this.isCancellationRequested()) { - tracing?.instant(tracing.Phase.Session, "cancellationThrown", { kind: "ThrottledCancellationToken" }); - throw new OperationCanceledException(); + ts.tracing?.instant(ts.tracing.Phase.Session, "cancellationThrown", { kind: "ThrottledCancellationToken" }); + throw new ts.OperationCanceledException(); } } } - const invalidOperationsInPartialSemanticMode: readonly (keyof LanguageService)[] = [ + const invalidOperationsInPartialSemanticMode: readonly (keyof ts.LanguageService)[] = [ "getSemanticDiagnostics", "getSuggestionDiagnostics", "getCompilerOptionsDiagnostics", @@ -1262,7 +1248,7 @@ namespace ts { "provideInlayHints" ]; - const invalidOperationsInSyntacticMode: readonly (keyof LanguageService)[] = [ + const invalidOperationsInSyntacticMode: readonly (keyof ts.LanguageService)[] = [ ...invalidOperationsInPartialSemanticMode, "getCompletionsAtPosition", "getCompletionEntryDetails", @@ -1282,25 +1268,21 @@ namespace ts { "findRenameLocations", "getApplicableRefactors", ]; - export function createLanguageService( - host: LanguageServiceHost, - documentRegistry: DocumentRegistry = createDocumentRegistry(host.useCaseSensitiveFileNames && host.useCaseSensitiveFileNames(), host.getCurrentDirectory()), - syntaxOnlyOrLanguageServiceMode?: boolean | LanguageServiceMode, - ): LanguageService { - let languageServiceMode: LanguageServiceMode; + export function createLanguageService(host: ts.LanguageServiceHost, documentRegistry: ts.DocumentRegistry = ts.createDocumentRegistry(host.useCaseSensitiveFileNames && host.useCaseSensitiveFileNames(), host.getCurrentDirectory()), syntaxOnlyOrLanguageServiceMode?: boolean | ts.LanguageServiceMode): ts.LanguageService { + let languageServiceMode: ts.LanguageServiceMode; if (syntaxOnlyOrLanguageServiceMode === undefined) { - languageServiceMode = LanguageServiceMode.Semantic; + languageServiceMode = ts.LanguageServiceMode.Semantic; } else if (typeof syntaxOnlyOrLanguageServiceMode === "boolean") { // languageServiceMode = SyntaxOnly - languageServiceMode = syntaxOnlyOrLanguageServiceMode ? LanguageServiceMode.Syntactic : LanguageServiceMode.Semantic; + languageServiceMode = syntaxOnlyOrLanguageServiceMode ? ts.LanguageServiceMode.Syntactic : ts.LanguageServiceMode.Semantic; } else { languageServiceMode = syntaxOnlyOrLanguageServiceMode; } const syntaxTreeCache: SyntaxTreeCache = new SyntaxTreeCache(host); - let program: Program; + let program: ts.Program; let lastProjectVersion: string; let lastTypesRootVersion = 0; @@ -1311,7 +1293,7 @@ namespace ts { const currentDirectory = host.getCurrentDirectory(); // Checks if the localized messages json is set, and if not, query the host for it - maybeSetLocalizedDiagnosticMessages(host.getLocalizedDiagnosticMessages?.bind(host)); + ts.maybeSetLocalizedDiagnosticMessages(host.getLocalizedDiagnosticMessages?.bind(host)); function log(message: string) { if (host.log) { @@ -1319,24 +1301,23 @@ namespace ts { } } - const useCaseSensitiveFileNames = hostUsesCaseSensitiveFileNames(host); - const getCanonicalFileName = createGetCanonicalFileName(useCaseSensitiveFileNames); - - const sourceMapper = getSourceMapper({ + const useCaseSensitiveFileNames = ts.hostUsesCaseSensitiveFileNames(host); + const getCanonicalFileName = ts.createGetCanonicalFileName(useCaseSensitiveFileNames); + const sourceMapper = ts.getSourceMapper({ useCaseSensitiveFileNames: () => useCaseSensitiveFileNames, getCurrentDirectory: () => currentDirectory, getProgram, - fileExists: maybeBind(host, host.fileExists), - readFile: maybeBind(host, host.readFile), - getDocumentPositionMapper: maybeBind(host, host.getDocumentPositionMapper), - getSourceFileLike: maybeBind(host, host.getSourceFileLike), + fileExists: ts.maybeBind(host, host.fileExists), + readFile: ts.maybeBind(host, host.readFile), + getDocumentPositionMapper: ts.maybeBind(host, host.getDocumentPositionMapper), + getSourceFileLike: ts.maybeBind(host, host.getSourceFileLike), log }); - function getValidSourceFile(fileName: string): SourceFile { + function getValidSourceFile(fileName: string): ts.SourceFile { const sourceFile = program.getSourceFile(fileName); if (!sourceFile) { - const error: Error & PossibleProgramFileInfo = new Error(`Could not find source file: '${fileName}'.`); + const error: Error & ts.PossibleProgramFileInfo = new Error(`Could not find source file: '${fileName}'.`); // We've been having trouble debugging this, so attach sidecar data for the tsserver log. // See https://github.com/microsoft/TypeScript/issues/30180. @@ -1348,7 +1329,7 @@ namespace ts { } function synchronizeHostData(): void { - Debug.assert(languageServiceMode !== LanguageServiceMode.Syntactic); + ts.Debug.assert(languageServiceMode !== ts.LanguageServiceMode.Syntactic); // perform fast check if host supports it if (host.getProjectVersion) { const hostProjectVersion = host.getProjectVersion(); @@ -1372,22 +1353,22 @@ namespace ts { let hostCache: HostCache | undefined = new HostCache(host, getCanonicalFileName); const rootFileNames = hostCache.getRootFileNames(); const newSettings = host.getCompilationSettings() || getDefaultCompilerOptions(); - const hasInvalidatedResolution: HasInvalidatedResolution = host.hasInvalidatedResolution || returnFalse; - const hasChangedAutomaticTypeDirectiveNames = maybeBind(host, host.hasChangedAutomaticTypeDirectiveNames); + const hasInvalidatedResolution: ts.HasInvalidatedResolution = host.hasInvalidatedResolution || ts.returnFalse; + const hasChangedAutomaticTypeDirectiveNames = ts.maybeBind(host, host.hasChangedAutomaticTypeDirectiveNames); const projectReferences = host.getProjectReferences?.(); - let parsedCommandLines: ESMap | undefined; - const parseConfigHost: ParseConfigFileHost = { + let parsedCommandLines: ts.ESMap | undefined; + const parseConfigHost: ts.ParseConfigFileHost = { useCaseSensitiveFileNames, fileExists, readFile, readDirectory, - trace: maybeBind(host, host.trace), + trace: ts.maybeBind(host, host.trace), getCurrentDirectory: () => currentDirectory, - onUnRecoverableConfigFileDiagnostic: noop, + onUnRecoverableConfigFileDiagnostic: ts.noop, }; // If the program is already up-to-date, we can reuse it - if (isProgramUptoDate(program, rootFileNames, newSettings, (_path, fileName) => host.getScriptVersion(fileName), fileExists, hasInvalidatedResolution, hasChangedAutomaticTypeDirectiveNames, getParsedCommandLine, projectReferences)) { + if (ts.isProgramUptoDate(program, rootFileNames, newSettings, (_path, fileName) => host.getScriptVersion(fileName), fileExists, hasInvalidatedResolution, hasChangedAutomaticTypeDirectiveNames, getParsedCommandLine, projectReferences)) { return; } @@ -1398,22 +1379,22 @@ namespace ts { // incremental parsing. // Now create a new compiler - const compilerHost: CompilerHost = { + const compilerHost: ts.CompilerHost = { getSourceFile: getOrCreateSourceFile, getSourceFileByPath: getOrCreateSourceFileByPath, getCancellationToken: () => cancellationToken, getCanonicalFileName, useCaseSensitiveFileNames: () => useCaseSensitiveFileNames, - getNewLine: () => getNewLineCharacter(newSettings, () => getNewLineOrDefaultFromHost(host)), + getNewLine: () => ts.getNewLineCharacter(newSettings, () => ts.getNewLineOrDefaultFromHost(host)), getDefaultLibFileName: options => host.getDefaultLibFileName(options), - writeFile: noop, + writeFile: ts.noop, getCurrentDirectory: () => currentDirectory, fileExists, readFile, - getSymlinkCache: maybeBind(host, host.getSymlinkCache), - realpath: maybeBind(host, host.realpath), + getSymlinkCache: ts.maybeBind(host, host.getSymlinkCache), + realpath: ts.maybeBind(host, host.realpath), directoryExists: directoryName => { - return directoryProbablyExists(directoryName, host); + return ts.directoryProbablyExists(directoryName, host); }, getDirectories: path => { return host.getDirectories ? host.getDirectories(path) : []; @@ -1424,23 +1405,23 @@ namespace ts { hasInvalidatedResolution, hasChangedAutomaticTypeDirectiveNames, trace: parseConfigHost.trace, - resolveModuleNames: maybeBind(host, host.resolveModuleNames), - getModuleResolutionCache: maybeBind(host, host.getModuleResolutionCache), - resolveTypeReferenceDirectives: maybeBind(host, host.resolveTypeReferenceDirectives), - useSourceOfProjectReferenceRedirect: maybeBind(host, host.useSourceOfProjectReferenceRedirect), + resolveModuleNames: ts.maybeBind(host, host.resolveModuleNames), + getModuleResolutionCache: ts.maybeBind(host, host.getModuleResolutionCache), + resolveTypeReferenceDirectives: ts.maybeBind(host, host.resolveTypeReferenceDirectives), + useSourceOfProjectReferenceRedirect: ts.maybeBind(host, host.useSourceOfProjectReferenceRedirect), getParsedCommandLine, }; host.setCompilerHost?.(compilerHost); const documentRegistryBucketKey = documentRegistry.getKeyForCompilationSettings(newSettings); - const options: CreateProgramOptions = { + const options: ts.CreateProgramOptions = { rootNames: rootFileNames, options: newSettings, host: compilerHost, oldProgram: program, projectReferences }; - program = createProgram(options); + program = ts.createProgram(options); // hostCache is captured in the closure for 'getOrCreateSourceFile' but it should not be used past this point. // It needs to be cleared to allow all collected snapshots to be released @@ -1457,34 +1438,30 @@ namespace ts { program.getTypeChecker(); return; - function getParsedCommandLine(fileName: string): ParsedCommandLine | undefined { - const path = toPath(fileName, currentDirectory, getCanonicalFileName); + function getParsedCommandLine(fileName: string): ts.ParsedCommandLine | undefined { + const path = ts.toPath(fileName, currentDirectory, getCanonicalFileName); const existing = parsedCommandLines?.get(path); - if (existing !== undefined) return existing || undefined; + if (existing !== undefined) + return existing || undefined; const result = host.getParsedCommandLine ? host.getParsedCommandLine(fileName) : getParsedCommandLineOfConfigFileUsingSourceFile(fileName); - (parsedCommandLines ||= new Map()).set(path, result || false); + (parsedCommandLines ||= new ts.Map()).set(path, result || false); return result; } - function getParsedCommandLineOfConfigFileUsingSourceFile(configFileName: string): ParsedCommandLine | undefined { - const result = getOrCreateSourceFile(configFileName, ScriptTarget.JSON) as JsonSourceFile | undefined; - if (!result) return undefined; - result.path = toPath(configFileName, currentDirectory, getCanonicalFileName); + function getParsedCommandLineOfConfigFileUsingSourceFile(configFileName: string): ts.ParsedCommandLine | undefined { + const result = getOrCreateSourceFile(configFileName, ts.ScriptTarget.JSON) as ts.JsonSourceFile | undefined; + if (!result) + return undefined; + result.path = ts.toPath(configFileName, currentDirectory, getCanonicalFileName); result.resolvedPath = result.path; result.originalFileName = result.fileName; - return parseJsonSourceFileConfigFileContent( - result, - parseConfigHost, - getNormalizedAbsolutePath(getDirectoryPath(configFileName), currentDirectory), - /*optionsToExtend*/ undefined, - getNormalizedAbsolutePath(configFileName, currentDirectory), - ); + return ts.parseJsonSourceFileConfigFileContent(result, parseConfigHost, ts.getNormalizedAbsolutePath(ts.getDirectoryPath(configFileName), currentDirectory), + /*optionsToExtend*/ undefined, ts.getNormalizedAbsolutePath(configFileName, currentDirectory)); } - - function onReleaseParsedCommandLine(configFileName: string, oldResolvedRef: ResolvedProjectReference | undefined, oldOptions: CompilerOptions) { + function onReleaseParsedCommandLine(configFileName: string, oldResolvedRef: ts.ResolvedProjectReference | undefined, oldOptions: ts.CompilerOptions) { if (host.getParsedCommandLine) { host.onReleaseParsedCommandLine?.(configFileName, oldResolvedRef, oldOptions); } @@ -1494,41 +1471,41 @@ namespace ts { } function fileExists(fileName: string): boolean { - const path = toPath(fileName, currentDirectory, getCanonicalFileName); + const path = ts.toPath(fileName, currentDirectory, getCanonicalFileName); const entry = hostCache && hostCache.getEntryByPath(path); return entry ? - !isString(entry) : + !ts.isString(entry) : (!!host.fileExists && host.fileExists(fileName)); } function readFile(fileName: string) { // stub missing host functionality - const path = toPath(fileName, currentDirectory, getCanonicalFileName); + const path = ts.toPath(fileName, currentDirectory, getCanonicalFileName); const entry = hostCache && hostCache.getEntryByPath(path); if (entry) { - return isString(entry) ? undefined : getSnapshotText(entry.scriptSnapshot); + return ts.isString(entry) ? undefined : ts.getSnapshotText(entry.scriptSnapshot); } return host.readFile && host.readFile(fileName); } function readDirectory(path: string, extensions?: readonly string[], exclude?: readonly string[], include?: readonly string[], depth?: number) { - Debug.checkDefined(host.readDirectory, "'LanguageServiceHost.readDirectory' must be implemented to correctly process 'projectReferences'"); + ts.Debug.checkDefined(host.readDirectory, "'LanguageServiceHost.readDirectory' must be implemented to correctly process 'projectReferences'"); return host.readDirectory!(path, extensions, exclude, include, depth); } // Release any files we have acquired in the old program but are // not part of the new program. - function onReleaseOldSourceFile(oldSourceFile: SourceFile, oldOptions: CompilerOptions) { + function onReleaseOldSourceFile(oldSourceFile: ts.SourceFile, oldOptions: ts.CompilerOptions) { const oldSettingsKey = documentRegistry.getKeyForCompilationSettings(oldOptions); documentRegistry.releaseDocumentWithKey(oldSourceFile.resolvedPath, oldSettingsKey, oldSourceFile.scriptKind); } - function getOrCreateSourceFile(fileName: string, languageVersion: ScriptTarget, onError?: (message: string) => void, shouldCreateNewSourceFile?: boolean): SourceFile | undefined { - return getOrCreateSourceFileByPath(fileName, toPath(fileName, currentDirectory, getCanonicalFileName), languageVersion, onError, shouldCreateNewSourceFile); + function getOrCreateSourceFile(fileName: string, languageVersion: ts.ScriptTarget, onError?: (message: string) => void, shouldCreateNewSourceFile?: boolean): ts.SourceFile | undefined { + return getOrCreateSourceFileByPath(fileName, ts.toPath(fileName, currentDirectory, getCanonicalFileName), languageVersion, onError, shouldCreateNewSourceFile); } - function getOrCreateSourceFileByPath(fileName: string, path: Path, _languageVersion: ScriptTarget, _onError?: (message: string) => void, shouldCreateNewSourceFile?: boolean): SourceFile | undefined { - Debug.assert(hostCache !== undefined, "getOrCreateSourceFileByPath called after typical CompilerHost lifetime, check the callstack something with a reference to an old host."); + function getOrCreateSourceFileByPath(fileName: string, path: ts.Path, _languageVersion: ts.ScriptTarget, _onError?: (message: string) => void, shouldCreateNewSourceFile?: boolean): ts.SourceFile | undefined { + ts.Debug.assert(hostCache !== undefined, "getOrCreateSourceFileByPath called after typical CompilerHost lifetime, check the callstack something with a reference to an old host."); // The program is asking for this file, check first if the host can locate it. // If the host can not locate the file, then it does not exist. return undefined // to the program to allow reporting of errors for missing files. @@ -1587,9 +1564,9 @@ namespace ts { } // TODO: GH#18217 frequently asserted as defined - function getProgram(): Program | undefined { - if (languageServiceMode === LanguageServiceMode.Syntactic) { - Debug.assert(program === undefined); + function getProgram(): ts.Program | undefined { + if (languageServiceMode === ts.LanguageServiceMode.Syntactic) { + ts.Debug.assert(program === undefined); return undefined; } @@ -1598,7 +1575,7 @@ namespace ts { return program; } - function getAutoImportProvider(): Program | undefined { + function getAutoImportProvider(): ts.Program | undefined { return host.getPackageJsonAutoImportProvider?.(); } @@ -1610,15 +1587,14 @@ namespace ts { if (program) { // Use paths to ensure we are using correct key and paths as document registry could be created with different current directory than host const key = documentRegistry.getKeyForCompilationSettings(program.getCompilerOptions()); - forEach(program.getSourceFiles(), f => - documentRegistry.releaseDocumentWithKey(f.resolvedPath, key, f.scriptKind)); + ts.forEach(program.getSourceFiles(), f => documentRegistry.releaseDocumentWithKey(f.resolvedPath, key, f.scriptKind)); program = undefined!; // TODO: GH#18217 } host = undefined!; } /// Diagnostics - function getSyntacticDiagnostics(fileName: string): DiagnosticWithLocation[] { + function getSyntacticDiagnostics(fileName: string): ts.DiagnosticWithLocation[] { synchronizeHostData(); return program.getSyntacticDiagnostics(getValidSourceFile(fileName), cancellationToken).slice(); @@ -1628,7 +1604,7 @@ namespace ts { * getSemanticDiagnostics return array of Diagnostics. If '-d' is not enabled, only report semantic errors * If '-d' enabled, report both semantic and emitter errors */ - function getSemanticDiagnostics(fileName: string): Diagnostic[] { + function getSemanticDiagnostics(fileName: string): ts.Diagnostic[] { synchronizeHostData(); const targetSourceFile = getValidSourceFile(fileName); @@ -1637,7 +1613,7 @@ namespace ts { // Therefore only get diagnostics for given file. const semanticDiagnostics = program.getSemanticDiagnostics(targetSourceFile, cancellationToken); - if (!getEmitDeclarations(program.getCompilerOptions())) { + if (!ts.getEmitDeclarations(program.getCompilerOptions())) { return semanticDiagnostics.slice(); } @@ -1646,9 +1622,9 @@ namespace ts { return [...semanticDiagnostics, ...declarationDiagnostics]; } - function getSuggestionDiagnostics(fileName: string): DiagnosticWithLocation[] { + function getSuggestionDiagnostics(fileName: string): ts.DiagnosticWithLocation[] { synchronizeHostData(); - return computeSuggestionDiagnostics(getValidSourceFile(fileName), program, cancellationToken); + return ts.computeSuggestionDiagnostics(getValidSourceFile(fileName), program, cancellationToken); } function getCompilerOptionsDiagnostics() { @@ -1656,52 +1632,33 @@ namespace ts { return [...program.getOptionsDiagnostics(cancellationToken), ...program.getGlobalDiagnostics(cancellationToken)]; } - function getCompletionsAtPosition(fileName: string, position: number, options: GetCompletionsAtPositionOptions = emptyOptions, formattingSettings?: FormatCodeSettings): CompletionInfo | undefined { + function getCompletionsAtPosition(fileName: string, position: number, options: ts.GetCompletionsAtPositionOptions = ts.emptyOptions, formattingSettings?: ts.FormatCodeSettings): ts.CompletionInfo | undefined { // Convert from deprecated options names to new names - const fullPreferences: UserPreferences = { - ...identity(options), // avoid excess property check + const fullPreferences: ts.UserPreferences = { + ...ts.identity(options), includeCompletionsForModuleExports: options.includeCompletionsForModuleExports || options.includeExternalModuleExports, includeCompletionsWithInsertText: options.includeCompletionsWithInsertText || options.includeInsertTextCompletions, }; synchronizeHostData(); - return Completions.getCompletionsAtPosition( - host, - program, - log, - getValidSourceFile(fileName), - position, - fullPreferences, - options.triggerCharacter, - options.triggerKind, - cancellationToken, - formattingSettings && formatting.getFormatContext(formattingSettings, host)); + return ts.Completions.getCompletionsAtPosition(host, program, log, getValidSourceFile(fileName), position, fullPreferences, options.triggerCharacter, options.triggerKind, cancellationToken, formattingSettings && ts.formatting.getFormatContext(formattingSettings, host)); } - function getCompletionEntryDetails(fileName: string, position: number, name: string, formattingOptions: FormatCodeSettings | undefined, source: string | undefined, preferences: UserPreferences = emptyOptions, data?: CompletionEntryData): CompletionEntryDetails | undefined { + function getCompletionEntryDetails(fileName: string, position: number, name: string, formattingOptions: ts.FormatCodeSettings | undefined, source: string | undefined, preferences: ts.UserPreferences = ts.emptyOptions, data?: ts.CompletionEntryData): ts.CompletionEntryDetails | undefined { synchronizeHostData(); - return Completions.getCompletionEntryDetails( - program, - log, - getValidSourceFile(fileName), - position, - { name, source, data }, - host, - (formattingOptions && formatting.getFormatContext(formattingOptions, host))!, // TODO: GH#18217 - preferences, - cancellationToken, - ); + return ts.Completions.getCompletionEntryDetails(program, log, getValidSourceFile(fileName), position, { name, source, data }, host, (formattingOptions && ts.formatting.getFormatContext(formattingOptions, host))!, // TODO: GH#18217 + preferences, cancellationToken); } - function getCompletionEntrySymbol(fileName: string, position: number, name: string, source?: string, preferences: UserPreferences = emptyOptions): Symbol | undefined { + function getCompletionEntrySymbol(fileName: string, position: number, name: string, source?: string, preferences: ts.UserPreferences = ts.emptyOptions): ts.Symbol | undefined { synchronizeHostData(); - return Completions.getCompletionEntrySymbol(program, log, getValidSourceFile(fileName), position, { name, source }, host, preferences); + return ts.Completions.getCompletionEntrySymbol(program, log, getValidSourceFile(fileName), position, { name, source }, host, preferences); } - function getQuickInfoAtPosition(fileName: string, position: number): QuickInfo | undefined { + function getQuickInfoAtPosition(fileName: string, position: number): ts.QuickInfo | undefined { synchronizeHostData(); const sourceFile = getValidSourceFile(fileName); - const node = getTouchingPropertyName(sourceFile, position); + const node = ts.getTouchingPropertyName(sourceFile, position); if (node === sourceFile) { // Avoid giving quickInfo for the sourceFile as a whole. return undefined; @@ -1714,159 +1671,154 @@ namespace ts { if (!symbol || typeChecker.isUnknownSymbol(symbol)) { const type = shouldGetType(sourceFile, nodeForQuickInfo, position) ? typeChecker.getTypeAtLocation(nodeForQuickInfo) : undefined; return type && { - kind: ScriptElementKind.unknown, - kindModifiers: ScriptElementKindModifier.none, - textSpan: createTextSpanFromNode(nodeForQuickInfo, sourceFile), - displayParts: typeChecker.runWithCancellationToken(cancellationToken, typeChecker => typeToDisplayParts(typeChecker, type, getContainerNode(nodeForQuickInfo))), + kind: ts.ScriptElementKind.unknown, + kindModifiers: ts.ScriptElementKindModifier.none, + textSpan: ts.createTextSpanFromNode(nodeForQuickInfo, sourceFile), + displayParts: typeChecker.runWithCancellationToken(cancellationToken, typeChecker => ts.typeToDisplayParts(typeChecker, type, ts.getContainerNode(nodeForQuickInfo))), documentation: type.symbol ? type.symbol.getDocumentationComment(typeChecker) : undefined, tags: type.symbol ? type.symbol.getJsDocTags(typeChecker) : undefined }; } - const { symbolKind, displayParts, documentation, tags } = typeChecker.runWithCancellationToken(cancellationToken, typeChecker => - SymbolDisplay.getSymbolDisplayPartsDocumentationAndSymbolKind(typeChecker, symbol, sourceFile, getContainerNode(nodeForQuickInfo), nodeForQuickInfo) - ); + const { symbolKind, displayParts, documentation, tags } = typeChecker.runWithCancellationToken(cancellationToken, typeChecker => ts.SymbolDisplay.getSymbolDisplayPartsDocumentationAndSymbolKind(typeChecker, symbol, sourceFile, ts.getContainerNode(nodeForQuickInfo), nodeForQuickInfo)); return { kind: symbolKind, - kindModifiers: SymbolDisplay.getSymbolModifiers(typeChecker, symbol), - textSpan: createTextSpanFromNode(nodeForQuickInfo, sourceFile), + kindModifiers: ts.SymbolDisplay.getSymbolModifiers(typeChecker, symbol), + textSpan: ts.createTextSpanFromNode(nodeForQuickInfo, sourceFile), displayParts, documentation, tags, }; } - function getNodeForQuickInfo(node: Node): Node { - if (isNewExpression(node.parent) && node.pos === node.parent.pos) { + function getNodeForQuickInfo(node: ts.Node): ts.Node { + if (ts.isNewExpression(node.parent) && node.pos === node.parent.pos) { return node.parent.expression; } - if (isNamedTupleMember(node.parent) && node.pos === node.parent.pos) { + if (ts.isNamedTupleMember(node.parent) && node.pos === node.parent.pos) { return node.parent; } - if (isImportMeta(node.parent) && node.parent.name === node) { + if (ts.isImportMeta(node.parent) && node.parent.name === node) { return node.parent; } return node; } - function shouldGetType(sourceFile: SourceFile, node: Node, position: number): boolean { + function shouldGetType(sourceFile: ts.SourceFile, node: ts.Node, position: number): boolean { switch (node.kind) { - case SyntaxKind.Identifier: - return !isLabelName(node) && !isTagName(node) && !isConstTypeReference(node.parent); - case SyntaxKind.PropertyAccessExpression: - case SyntaxKind.QualifiedName: + case ts.SyntaxKind.Identifier: + return !ts.isLabelName(node) && !ts.isTagName(node) && !ts.isConstTypeReference(node.parent); + case ts.SyntaxKind.PropertyAccessExpression: + case ts.SyntaxKind.QualifiedName: // Don't return quickInfo if inside the comment in `a/**/.b` - return !isInComment(sourceFile, position); - case SyntaxKind.ThisKeyword: - case SyntaxKind.ThisType: - case SyntaxKind.SuperKeyword: - case SyntaxKind.NamedTupleMember: + return !ts.isInComment(sourceFile, position); + case ts.SyntaxKind.ThisKeyword: + case ts.SyntaxKind.ThisType: + case ts.SyntaxKind.SuperKeyword: + case ts.SyntaxKind.NamedTupleMember: return true; - case SyntaxKind.MetaProperty: - return isImportMeta(node); + case ts.SyntaxKind.MetaProperty: + return ts.isImportMeta(node); default: return false; } } /// Goto definition - function getDefinitionAtPosition(fileName: string, position: number, searchOtherFilesOnly?: boolean, stopAtAlias?: boolean): readonly DefinitionInfo[] | undefined { + function getDefinitionAtPosition(fileName: string, position: number, searchOtherFilesOnly?: boolean, stopAtAlias?: boolean): readonly ts.DefinitionInfo[] | undefined { synchronizeHostData(); - return GoToDefinition.getDefinitionAtPosition(program, getValidSourceFile(fileName), position, searchOtherFilesOnly, stopAtAlias); + return ts.GoToDefinition.getDefinitionAtPosition(program, getValidSourceFile(fileName), position, searchOtherFilesOnly, stopAtAlias); } - function getDefinitionAndBoundSpan(fileName: string, position: number): DefinitionInfoAndBoundSpan | undefined { + function getDefinitionAndBoundSpan(fileName: string, position: number): ts.DefinitionInfoAndBoundSpan | undefined { synchronizeHostData(); - return GoToDefinition.getDefinitionAndBoundSpan(program, getValidSourceFile(fileName), position); + return ts.GoToDefinition.getDefinitionAndBoundSpan(program, getValidSourceFile(fileName), position); } - function getTypeDefinitionAtPosition(fileName: string, position: number): readonly DefinitionInfo[] | undefined { + function getTypeDefinitionAtPosition(fileName: string, position: number): readonly ts.DefinitionInfo[] | undefined { synchronizeHostData(); - return GoToDefinition.getTypeDefinitionAtPosition(program.getTypeChecker(), getValidSourceFile(fileName), position); + return ts.GoToDefinition.getTypeDefinitionAtPosition(program.getTypeChecker(), getValidSourceFile(fileName), position); } /// Goto implementation - function getImplementationAtPosition(fileName: string, position: number): ImplementationLocation[] | undefined { + function getImplementationAtPosition(fileName: string, position: number): ts.ImplementationLocation[] | undefined { synchronizeHostData(); - return FindAllReferences.getImplementationsAtPosition(program, cancellationToken, program.getSourceFiles(), getValidSourceFile(fileName), position); + return ts.FindAllReferences.getImplementationsAtPosition(program, cancellationToken, program.getSourceFiles(), getValidSourceFile(fileName), position); } /// References and Occurrences - function getOccurrencesAtPosition(fileName: string, position: number): readonly ReferenceEntry[] | undefined { - return flatMap( - getDocumentHighlights(fileName, position, [fileName]), - entry => entry.highlightSpans.map(highlightSpan => ({ + function getOccurrencesAtPosition(fileName: string, position: number): readonly ts.ReferenceEntry[] | undefined { + return ts.flatMap(getDocumentHighlights(fileName, position, [fileName]), entry => entry.highlightSpans.map(highlightSpan => ({ fileName: entry.fileName, textSpan: highlightSpan.textSpan, - isWriteAccess: highlightSpan.kind === HighlightSpanKind.writtenReference, + isWriteAccess: highlightSpan.kind === ts.HighlightSpanKind.writtenReference, ...highlightSpan.isInString && { isInString: true }, ...highlightSpan.contextSpan && { contextSpan: highlightSpan.contextSpan } - })) - ); + }))); } - function getDocumentHighlights(fileName: string, position: number, filesToSearch: readonly string[]): DocumentHighlights[] | undefined { - const normalizedFileName = normalizePath(fileName); - Debug.assert(filesToSearch.some(f => normalizePath(f) === normalizedFileName)); + function getDocumentHighlights(fileName: string, position: number, filesToSearch: readonly string[]): ts.DocumentHighlights[] | undefined { + const normalizedFileName = ts.normalizePath(fileName); + ts.Debug.assert(filesToSearch.some(f => ts.normalizePath(f) === normalizedFileName)); synchronizeHostData(); - const sourceFilesToSearch = mapDefined(filesToSearch, fileName => program.getSourceFile(fileName)); + const sourceFilesToSearch = ts.mapDefined(filesToSearch, fileName => program.getSourceFile(fileName)); const sourceFile = getValidSourceFile(fileName); - return DocumentHighlights.getDocumentHighlights(program, cancellationToken, sourceFile, position, sourceFilesToSearch); + return ts.DocumentHighlights.getDocumentHighlights(program, cancellationToken, sourceFile, position, sourceFilesToSearch); } - function findRenameLocations(fileName: string, position: number, findInStrings: boolean, findInComments: boolean, providePrefixAndSuffixTextForRename?: boolean): RenameLocation[] | undefined { + function findRenameLocations(fileName: string, position: number, findInStrings: boolean, findInComments: boolean, providePrefixAndSuffixTextForRename?: boolean): ts.RenameLocation[] | undefined { synchronizeHostData(); const sourceFile = getValidSourceFile(fileName); - const node = getAdjustedRenameLocation(getTouchingPropertyName(sourceFile, position)); - if (!Rename.nodeIsEligibleForRename(node)) return undefined; - if (isIdentifier(node) && (isJsxOpeningElement(node.parent) || isJsxClosingElement(node.parent)) && isIntrinsicJsxName(node.escapedText)) { + const node = ts.getAdjustedRenameLocation(ts.getTouchingPropertyName(sourceFile, position)); + if (!ts.Rename.nodeIsEligibleForRename(node)) + return undefined; + if (ts.isIdentifier(node) && (ts.isJsxOpeningElement(node.parent) || ts.isJsxClosingElement(node.parent)) && ts.isIntrinsicJsxName(node.escapedText)) { const { openingElement, closingElement } = node.parent.parent; - return [openingElement, closingElement].map((node): RenameLocation => { - const textSpan = createTextSpanFromNode(node.tagName, sourceFile); + return [openingElement, closingElement].map((node): ts.RenameLocation => { + const textSpan = ts.createTextSpanFromNode(node.tagName, sourceFile); return { fileName: sourceFile.fileName, textSpan, - ...FindAllReferences.toContextSpan(textSpan, sourceFile, node.parent) + ...ts.FindAllReferences.toContextSpan(textSpan, sourceFile, node.parent) }; }); } else { - return getReferencesWorker(node, position, { findInStrings, findInComments, providePrefixAndSuffixTextForRename, use: FindAllReferences.FindReferencesUse.Rename }, - (entry, originalNode, checker) => FindAllReferences.toRenameLocation(entry, originalNode, checker, providePrefixAndSuffixTextForRename || false)); + return getReferencesWorker(node, position, { findInStrings, findInComments, providePrefixAndSuffixTextForRename, use: ts.FindAllReferences.FindReferencesUse.Rename }, (entry, originalNode, checker) => ts.FindAllReferences.toRenameLocation(entry, originalNode, checker, providePrefixAndSuffixTextForRename || false)); } } - function getReferencesAtPosition(fileName: string, position: number): ReferenceEntry[] | undefined { + function getReferencesAtPosition(fileName: string, position: number): ts.ReferenceEntry[] | undefined { synchronizeHostData(); - return getReferencesWorker(getTouchingPropertyName(getValidSourceFile(fileName), position), position, { use: FindAllReferences.FindReferencesUse.References }, FindAllReferences.toReferenceEntry); + return getReferencesWorker(ts.getTouchingPropertyName(getValidSourceFile(fileName), position), position, { use: ts.FindAllReferences.FindReferencesUse.References }, ts.FindAllReferences.toReferenceEntry); } - function getReferencesWorker(node: Node, position: number, options: FindAllReferences.Options, cb: FindAllReferences.ToReferenceOrRenameEntry): T[] | undefined { + function getReferencesWorker(node: ts.Node, position: number, options: ts.FindAllReferences.Options, cb: ts.FindAllReferences.ToReferenceOrRenameEntry): T[] | undefined { synchronizeHostData(); // Exclude default library when renaming as commonly user don't want to change that file. - const sourceFiles = options && options.use === FindAllReferences.FindReferencesUse.Rename + const sourceFiles = options && options.use === ts.FindAllReferences.FindReferencesUse.Rename ? program.getSourceFiles().filter(sourceFile => !program.isSourceFileDefaultLibrary(sourceFile)) : program.getSourceFiles(); - return FindAllReferences.findReferenceOrRenameEntries(program, cancellationToken, sourceFiles, node, position, options, cb); + return ts.FindAllReferences.findReferenceOrRenameEntries(program, cancellationToken, sourceFiles, node, position, options, cb); } - function findReferences(fileName: string, position: number): ReferencedSymbol[] | undefined { + function findReferences(fileName: string, position: number): ts.ReferencedSymbol[] | undefined { synchronizeHostData(); - return FindAllReferences.findReferencedSymbols(program, cancellationToken, program.getSourceFiles(), getValidSourceFile(fileName), position); + return ts.FindAllReferences.findReferencedSymbols(program, cancellationToken, program.getSourceFiles(), getValidSourceFile(fileName), position); } - function getFileReferences(fileName: string): ReferenceEntry[] { + function getFileReferences(fileName: string): ts.ReferenceEntry[] { synchronizeHostData(); - return FindAllReferences.Core.getReferencesForFileName(fileName, program, program.getSourceFiles()).map(FindAllReferences.toReferenceEntry); + return ts.FindAllReferences.Core.getReferencesForFileName(fileName, program, program.getSourceFiles()).map(ts.FindAllReferences.toReferenceEntry); } - function getNavigateToItems(searchValue: string, maxResultCount?: number, fileName?: string, excludeDtsFiles = false): NavigateToItem[] { + function getNavigateToItems(searchValue: string, maxResultCount?: number, fileName?: string, excludeDtsFiles = false): ts.NavigateToItem[] { synchronizeHostData(); const sourceFiles = fileName ? [getValidSourceFile(fileName)] : program.getSourceFiles(); - return NavigateTo.getNavigateToItems(sourceFiles, program.getTypeChecker(), cancellationToken, searchValue, maxResultCount, excludeDtsFiles); + return ts.NavigateTo.getNavigateToItems(sourceFiles, program.getTypeChecker(), cancellationToken, searchValue, maxResultCount, excludeDtsFiles); } function getEmitOutput(fileName: string, emitOnlyDtsFiles?: boolean, forceDtsEmit?: boolean) { @@ -1874,47 +1826,47 @@ namespace ts { const sourceFile = getValidSourceFile(fileName); const customTransformers = host.getCustomTransformers && host.getCustomTransformers(); - return getFileEmitOutput(program, sourceFile, !!emitOnlyDtsFiles, cancellationToken, customTransformers, forceDtsEmit); + return ts.getFileEmitOutput(program, sourceFile, !!emitOnlyDtsFiles, cancellationToken, customTransformers, forceDtsEmit); } // Signature help /** * This is a semantic operation. */ - function getSignatureHelpItems(fileName: string, position: number, { triggerReason }: SignatureHelpItemsOptions = emptyOptions): SignatureHelpItems | undefined { + function getSignatureHelpItems(fileName: string, position: number, { triggerReason }: ts.SignatureHelpItemsOptions = ts.emptyOptions): ts.SignatureHelpItems | undefined { synchronizeHostData(); const sourceFile = getValidSourceFile(fileName); - return SignatureHelp.getSignatureHelpItems(program, sourceFile, position, triggerReason, cancellationToken); + return ts.SignatureHelp.getSignatureHelpItems(program, sourceFile, position, triggerReason, cancellationToken); } /// Syntactic features - function getNonBoundSourceFile(fileName: string): SourceFile { + function getNonBoundSourceFile(fileName: string): ts.SourceFile { return syntaxTreeCache.getCurrentSourceFile(fileName); } - function getNameOrDottedNameSpan(fileName: string, startPos: number, _endPos: number): TextSpan | undefined { + function getNameOrDottedNameSpan(fileName: string, startPos: number, _endPos: number): ts.TextSpan | undefined { const sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); // Get node at the location - const node = getTouchingPropertyName(sourceFile, startPos); + const node = ts.getTouchingPropertyName(sourceFile, startPos); if (node === sourceFile) { return undefined; } switch (node.kind) { - case SyntaxKind.PropertyAccessExpression: - case SyntaxKind.QualifiedName: - case SyntaxKind.StringLiteral: - case SyntaxKind.FalseKeyword: - case SyntaxKind.TrueKeyword: - case SyntaxKind.NullKeyword: - case SyntaxKind.SuperKeyword: - case SyntaxKind.ThisKeyword: - case SyntaxKind.ThisType: - case SyntaxKind.Identifier: + case ts.SyntaxKind.PropertyAccessExpression: + case ts.SyntaxKind.QualifiedName: + case ts.SyntaxKind.StringLiteral: + case ts.SyntaxKind.FalseKeyword: + case ts.SyntaxKind.TrueKeyword: + case ts.SyntaxKind.NullKeyword: + case ts.SyntaxKind.SuperKeyword: + case ts.SyntaxKind.ThisKeyword: + case ts.SyntaxKind.ThisType: + case ts.SyntaxKind.Identifier: break; // Cant create the text span @@ -1924,18 +1876,18 @@ namespace ts { let nodeForStartPos = node; while (true) { - if (isRightSideOfPropertyAccess(nodeForStartPos) || isRightSideOfQualifiedName(nodeForStartPos)) { + if (ts.isRightSideOfPropertyAccess(nodeForStartPos) || ts.isRightSideOfQualifiedName(nodeForStartPos)) { // If on the span is in right side of the the property or qualified name, return the span from the qualified name pos to end of this node nodeForStartPos = nodeForStartPos.parent; } - else if (isNameOfModuleDeclaration(nodeForStartPos)) { + else if (ts.isNameOfModuleDeclaration(nodeForStartPos)) { // If this is name of a module declarations, check if this is right side of dotted module name // If parent of the module declaration which is parent of this node is module declaration and its body is the module declaration that this node is name of // Then this name is name from dotted module - if (nodeForStartPos.parent.parent.kind === SyntaxKind.ModuleDeclaration && - (nodeForStartPos.parent.parent as ModuleDeclaration).body === nodeForStartPos.parent) { + if (nodeForStartPos.parent.parent.kind === ts.SyntaxKind.ModuleDeclaration && + (nodeForStartPos.parent.parent as ts.ModuleDeclaration).body === nodeForStartPos.parent) { // Use parent module declarations name for start pos - nodeForStartPos = (nodeForStartPos.parent.parent as ModuleDeclaration).name; + nodeForStartPos = (nodeForStartPos.parent.parent as ts.ModuleDeclaration).name; } else { // We have to use this name for start pos @@ -1948,179 +1900,168 @@ namespace ts { } } - return createTextSpanFromBounds(nodeForStartPos.getStart(), node.getEnd()); + return ts.createTextSpanFromBounds(nodeForStartPos.getStart(), node.getEnd()); } - function getBreakpointStatementAtPosition(fileName: string, position: number): TextSpan | undefined { + function getBreakpointStatementAtPosition(fileName: string, position: number): ts.TextSpan | undefined { // doesn't use compiler - no need to synchronize with host const sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); - return BreakpointResolver.spanInSourceFileAtLocation(sourceFile, position); + return ts.BreakpointResolver.spanInSourceFileAtLocation(sourceFile, position); } - function getNavigationBarItems(fileName: string): NavigationBarItem[] { - return NavigationBar.getNavigationBarItems(syntaxTreeCache.getCurrentSourceFile(fileName), cancellationToken); + function getNavigationBarItems(fileName: string): ts.NavigationBarItem[] { + return ts.NavigationBar.getNavigationBarItems(syntaxTreeCache.getCurrentSourceFile(fileName), cancellationToken); } - function getNavigationTree(fileName: string): NavigationTree { - return NavigationBar.getNavigationTree(syntaxTreeCache.getCurrentSourceFile(fileName), cancellationToken); + function getNavigationTree(fileName: string): ts.NavigationTree { + return ts.NavigationBar.getNavigationTree(syntaxTreeCache.getCurrentSourceFile(fileName), cancellationToken); } - function getSemanticClassifications(fileName: string, span: TextSpan): ClassifiedSpan[]; - function getSemanticClassifications(fileName: string, span: TextSpan, format?: SemanticClassificationFormat): ClassifiedSpan[] | ClassifiedSpan2020[] { + function getSemanticClassifications(fileName: string, span: ts.TextSpan): ts.ClassifiedSpan[]; + function getSemanticClassifications(fileName: string, span: ts.TextSpan, format?: ts.SemanticClassificationFormat): ts.ClassifiedSpan[] | ts.ClassifiedSpan2020[] { synchronizeHostData(); - const responseFormat = format || SemanticClassificationFormat.Original; - if (responseFormat === SemanticClassificationFormat.TwentyTwenty) { - return classifier.v2020.getSemanticClassifications(program, cancellationToken, getValidSourceFile(fileName), span); + const responseFormat = format || ts.SemanticClassificationFormat.Original; + if (responseFormat === ts.SemanticClassificationFormat.TwentyTwenty) { + return ts.classifier.v2020.getSemanticClassifications(program, cancellationToken, getValidSourceFile(fileName), span); } else { return ts.getSemanticClassifications(program.getTypeChecker(), cancellationToken, getValidSourceFile(fileName), program.getClassifiableNames(), span); } } - function getEncodedSemanticClassifications(fileName: string, span: TextSpan, format?: SemanticClassificationFormat): Classifications { + function getEncodedSemanticClassifications(fileName: string, span: ts.TextSpan, format?: ts.SemanticClassificationFormat): ts.Classifications { synchronizeHostData(); - const responseFormat = format || SemanticClassificationFormat.Original; - if (responseFormat === SemanticClassificationFormat.Original) { + const responseFormat = format || ts.SemanticClassificationFormat.Original; + if (responseFormat === ts.SemanticClassificationFormat.Original) { return ts.getEncodedSemanticClassifications(program.getTypeChecker(), cancellationToken, getValidSourceFile(fileName), program.getClassifiableNames(), span); } else { - return classifier.v2020.getEncodedSemanticClassifications(program, cancellationToken, getValidSourceFile(fileName), span); + return ts.classifier.v2020.getEncodedSemanticClassifications(program, cancellationToken, getValidSourceFile(fileName), span); } } - function getSyntacticClassifications(fileName: string, span: TextSpan): ClassifiedSpan[] { + function getSyntacticClassifications(fileName: string, span: ts.TextSpan): ts.ClassifiedSpan[] { // doesn't use compiler - no need to synchronize with host return ts.getSyntacticClassifications(cancellationToken, syntaxTreeCache.getCurrentSourceFile(fileName), span); } - function getEncodedSyntacticClassifications(fileName: string, span: TextSpan): Classifications { + function getEncodedSyntacticClassifications(fileName: string, span: ts.TextSpan): ts.Classifications { // doesn't use compiler - no need to synchronize with host return ts.getEncodedSyntacticClassifications(cancellationToken, syntaxTreeCache.getCurrentSourceFile(fileName), span); } - function getOutliningSpans(fileName: string): OutliningSpan[] { + function getOutliningSpans(fileName: string): ts.OutliningSpan[] { // doesn't use compiler - no need to synchronize with host const sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); - return OutliningElementsCollector.collectElements(sourceFile, cancellationToken); + return ts.OutliningElementsCollector.collectElements(sourceFile, cancellationToken); } - - const braceMatching = new Map(getEntries({ - [SyntaxKind.OpenBraceToken]: SyntaxKind.CloseBraceToken, - [SyntaxKind.OpenParenToken]: SyntaxKind.CloseParenToken, - [SyntaxKind.OpenBracketToken]: SyntaxKind.CloseBracketToken, - [SyntaxKind.GreaterThanToken]: SyntaxKind.LessThanToken, + const braceMatching = new ts.Map(ts.getEntries({ + [ts.SyntaxKind.OpenBraceToken]: ts.SyntaxKind.CloseBraceToken, + [ts.SyntaxKind.OpenParenToken]: ts.SyntaxKind.CloseParenToken, + [ts.SyntaxKind.OpenBracketToken]: ts.SyntaxKind.CloseBracketToken, + [ts.SyntaxKind.GreaterThanToken]: ts.SyntaxKind.LessThanToken, })); - braceMatching.forEach((value, key) => braceMatching.set(value.toString(), Number(key) as SyntaxKind)); - - function getBraceMatchingAtPosition(fileName: string, position: number): TextSpan[] { + braceMatching.forEach((value, key) => braceMatching.set(value.toString(), Number(key) as ts.SyntaxKind)); + function getBraceMatchingAtPosition(fileName: string, position: number): ts.TextSpan[] { const sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); - const token = getTouchingToken(sourceFile, position); + const token = ts.getTouchingToken(sourceFile, position); const matchKind = token.getStart(sourceFile) === position ? braceMatching.get(token.kind.toString()) : undefined; - const match = matchKind && findChildOfKind(token.parent, matchKind, sourceFile); + const match = matchKind && ts.findChildOfKind(token.parent, matchKind, sourceFile); // We want to order the braces when we return the result. - return match ? [createTextSpanFromNode(token, sourceFile), createTextSpanFromNode(match, sourceFile)].sort((a, b) => a.start - b.start) : emptyArray; + return match ? [ts.createTextSpanFromNode(token, sourceFile), ts.createTextSpanFromNode(match, sourceFile)].sort((a, b) => a.start - b.start) : ts.emptyArray; } - function getIndentationAtPosition(fileName: string, position: number, editorOptions: EditorOptions | EditorSettings) { - let start = timestamp(); + function getIndentationAtPosition(fileName: string, position: number, editorOptions: ts.EditorOptions | ts.EditorSettings) { + let start = ts.timestamp(); const settings = toEditorSettings(editorOptions); const sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); - log("getIndentationAtPosition: getCurrentSourceFile: " + (timestamp() - start)); - - start = timestamp(); - - const result = formatting.SmartIndenter.getIndentation(position, sourceFile, settings); - log("getIndentationAtPosition: computeIndentation : " + (timestamp() - start)); + log("getIndentationAtPosition: getCurrentSourceFile: " + (ts.timestamp() - start)); + start = ts.timestamp(); + const result = ts.formatting.SmartIndenter.getIndentation(position, sourceFile, settings); + log("getIndentationAtPosition: computeIndentation : " + (ts.timestamp() - start)); return result; } - function getFormattingEditsForRange(fileName: string, start: number, end: number, options: FormatCodeOptions | FormatCodeSettings): TextChange[] { + function getFormattingEditsForRange(fileName: string, start: number, end: number, options: ts.FormatCodeOptions | ts.FormatCodeSettings): ts.TextChange[] { const sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); - return formatting.formatSelection(start, end, sourceFile, formatting.getFormatContext(toEditorSettings(options), host)); + return ts.formatting.formatSelection(start, end, sourceFile, ts.formatting.getFormatContext(toEditorSettings(options), host)); } - function getFormattingEditsForDocument(fileName: string, options: FormatCodeOptions | FormatCodeSettings): TextChange[] { - return formatting.formatDocument(syntaxTreeCache.getCurrentSourceFile(fileName), formatting.getFormatContext(toEditorSettings(options), host)); + function getFormattingEditsForDocument(fileName: string, options: ts.FormatCodeOptions | ts.FormatCodeSettings): ts.TextChange[] { + return ts.formatting.formatDocument(syntaxTreeCache.getCurrentSourceFile(fileName), ts.formatting.getFormatContext(toEditorSettings(options), host)); } - function getFormattingEditsAfterKeystroke(fileName: string, position: number, key: string, options: FormatCodeOptions | FormatCodeSettings): TextChange[] { + function getFormattingEditsAfterKeystroke(fileName: string, position: number, key: string, options: ts.FormatCodeOptions | ts.FormatCodeSettings): ts.TextChange[] { const sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); - const formatContext = formatting.getFormatContext(toEditorSettings(options), host); - - if (!isInComment(sourceFile, position)) { + const formatContext = ts.formatting.getFormatContext(toEditorSettings(options), host); + if (!ts.isInComment(sourceFile, position)) { switch (key) { case "{": - return formatting.formatOnOpeningCurly(position, sourceFile, formatContext); + return ts.formatting.formatOnOpeningCurly(position, sourceFile, formatContext); case "}": - return formatting.formatOnClosingCurly(position, sourceFile, formatContext); + return ts.formatting.formatOnClosingCurly(position, sourceFile, formatContext); case ";": - return formatting.formatOnSemicolon(position, sourceFile, formatContext); + return ts.formatting.formatOnSemicolon(position, sourceFile, formatContext); case "\n": - return formatting.formatOnEnter(position, sourceFile, formatContext); + return ts.formatting.formatOnEnter(position, sourceFile, formatContext); } } return []; } - function getCodeFixesAtPosition(fileName: string, start: number, end: number, errorCodes: readonly number[], formatOptions: FormatCodeSettings, preferences: UserPreferences = emptyOptions): readonly CodeFixAction[] { + function getCodeFixesAtPosition(fileName: string, start: number, end: number, errorCodes: readonly number[], formatOptions: ts.FormatCodeSettings, preferences: ts.UserPreferences = ts.emptyOptions): readonly ts.CodeFixAction[] { synchronizeHostData(); const sourceFile = getValidSourceFile(fileName); - const span = createTextSpanFromBounds(start, end); - const formatContext = formatting.getFormatContext(formatOptions, host); - - return flatMap(deduplicate(errorCodes, equateValues, compareValues), errorCode => { + const span = ts.createTextSpanFromBounds(start, end); + const formatContext = ts.formatting.getFormatContext(formatOptions, host); + return ts.flatMap(ts.deduplicate(errorCodes, ts.equateValues, ts.compareValues), errorCode => { cancellationToken.throwIfCancellationRequested(); - return codefix.getFixes({ errorCode, sourceFile, span, program, host, cancellationToken, formatContext, preferences }); + return ts.codefix.getFixes({ errorCode, sourceFile, span, program, host, cancellationToken, formatContext, preferences }); }); } - function getCombinedCodeFix(scope: CombinedCodeFixScope, fixId: {}, formatOptions: FormatCodeSettings, preferences: UserPreferences = emptyOptions): CombinedCodeActions { + function getCombinedCodeFix(scope: ts.CombinedCodeFixScope, fixId: {}, formatOptions: ts.FormatCodeSettings, preferences: ts.UserPreferences = ts.emptyOptions): ts.CombinedCodeActions { synchronizeHostData(); - Debug.assert(scope.type === "file"); + ts.Debug.assert(scope.type === "file"); const sourceFile = getValidSourceFile(scope.fileName); - const formatContext = formatting.getFormatContext(formatOptions, host); - - return codefix.getAllFixes({ fixId, sourceFile, program, host, cancellationToken, formatContext, preferences }); + const formatContext = ts.formatting.getFormatContext(formatOptions, host); + return ts.codefix.getAllFixes({ fixId, sourceFile, program, host, cancellationToken, formatContext, preferences }); } - function organizeImports(args: OrganizeImportsArgs, formatOptions: FormatCodeSettings, preferences: UserPreferences = emptyOptions): readonly FileTextChanges[] { + function organizeImports(args: ts.OrganizeImportsArgs, formatOptions: ts.FormatCodeSettings, preferences: ts.UserPreferences = ts.emptyOptions): readonly ts.FileTextChanges[] { synchronizeHostData(); - Debug.assert(args.type === "file"); + ts.Debug.assert(args.type === "file"); const sourceFile = getValidSourceFile(args.fileName); - const formatContext = formatting.getFormatContext(formatOptions, host); - - return OrganizeImports.organizeImports(sourceFile, formatContext, host, program, preferences, args.skipDestructiveCodeActions); - } - - function getEditsForFileRename(oldFilePath: string, newFilePath: string, formatOptions: FormatCodeSettings, preferences: UserPreferences = emptyOptions): readonly FileTextChanges[] { - return ts.getEditsForFileRename(getProgram()!, oldFilePath, newFilePath, host, formatting.getFormatContext(formatOptions, host), preferences, sourceMapper); - } - - function applyCodeActionCommand(action: CodeActionCommand, formatSettings?: FormatCodeSettings): Promise; - function applyCodeActionCommand(action: CodeActionCommand[], formatSettings?: FormatCodeSettings): Promise; - function applyCodeActionCommand(action: CodeActionCommand | CodeActionCommand[], formatSettings?: FormatCodeSettings): Promise; - function applyCodeActionCommand(fileName: Path, action: CodeActionCommand): Promise; - function applyCodeActionCommand(fileName: Path, action: CodeActionCommand[]): Promise; - function applyCodeActionCommand(fileName: Path | CodeActionCommand | CodeActionCommand[], actionOrFormatSettingsOrUndefined?: CodeActionCommand | CodeActionCommand[] | FormatCodeSettings): Promise { - const action = typeof fileName === "string" ? actionOrFormatSettingsOrUndefined as CodeActionCommand | CodeActionCommand[] : fileName as CodeActionCommand[]; - return isArray(action) ? Promise.all(action.map(a => applySingleCodeActionCommand(a))) : applySingleCodeActionCommand(action); - } - - function applySingleCodeActionCommand(action: CodeActionCommand): Promise { - const getPath = (path: string): Path => toPath(path, currentDirectory, getCanonicalFileName); - Debug.assertEqual(action.type, "install package"); + const formatContext = ts.formatting.getFormatContext(formatOptions, host); + return ts.OrganizeImports.organizeImports(sourceFile, formatContext, host, program, preferences, args.skipDestructiveCodeActions); + } + function getEditsForFileRename(oldFilePath: string, newFilePath: string, formatOptions: ts.FormatCodeSettings, preferences: ts.UserPreferences = ts.emptyOptions): readonly ts.FileTextChanges[] { + return ts.getEditsForFileRename(getProgram()!, oldFilePath, newFilePath, host, ts.formatting.getFormatContext(formatOptions, host), preferences, sourceMapper); + } + function applyCodeActionCommand(action: ts.CodeActionCommand, formatSettings?: ts.FormatCodeSettings): Promise; + function applyCodeActionCommand(action: ts.CodeActionCommand[], formatSettings?: ts.FormatCodeSettings): Promise; + function applyCodeActionCommand(action: ts.CodeActionCommand | ts.CodeActionCommand[], formatSettings?: ts.FormatCodeSettings): Promise; + function applyCodeActionCommand(fileName: ts.Path, action: ts.CodeActionCommand): Promise; + function applyCodeActionCommand(fileName: ts.Path, action: ts.CodeActionCommand[]): Promise; + function applyCodeActionCommand(fileName: ts.Path | ts.CodeActionCommand | ts.CodeActionCommand[], actionOrFormatSettingsOrUndefined?: ts.CodeActionCommand | ts.CodeActionCommand[] | ts.FormatCodeSettings): Promise { + const action = typeof fileName === "string" ? actionOrFormatSettingsOrUndefined as ts.CodeActionCommand | ts.CodeActionCommand[] : fileName as ts.CodeActionCommand[]; + return ts.isArray(action) ? Promise.all(action.map(a => applySingleCodeActionCommand(a))) : applySingleCodeActionCommand(action); + } + function applySingleCodeActionCommand(action: ts.CodeActionCommand): Promise { + const getPath = (path: string): ts.Path => ts.toPath(path, currentDirectory, getCanonicalFileName); + ts.Debug.assertEqual(action.type, "install package"); return host.installPackage ? host.installPackage({ fileName: getPath(action.file), packageName: action.packageName }) : Promise.reject("Host does not implement `installPackage`"); } - function getDocCommentTemplateAtPosition(fileName: string, position: number, options?: DocCommentTemplateOptions): TextInsertion | undefined { - return JsDoc.getDocCommentTemplateAtPosition(getNewLineOrDefaultFromHost(host), syntaxTreeCache.getCurrentSourceFile(fileName), position, options); + function getDocCommentTemplateAtPosition(fileName: string, position: number, options?: ts.DocCommentTemplateOptions): ts.TextInsertion | undefined { + return ts.JsDoc.getDocCommentTemplateAtPosition(ts.getNewLineOrDefaultFromHost(host), syntaxTreeCache.getCurrentSourceFile(fileName), position, options); } function isValidBraceCompletionAtPosition(fileName: string, position: number, openingBrace: number): boolean { @@ -2130,52 +2071,53 @@ namespace ts { // var x = new foo<| ( with class foo{} ) // or // var y = 3 <| - if (openingBrace === CharacterCodes.lessThan) { + if (openingBrace === ts.CharacterCodes.lessThan) { return false; } const sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); // Check if in a context where we don't want to perform any insertion - if (isInString(sourceFile, position)) { + if (ts.isInString(sourceFile, position)) { return false; } - if (isInsideJsxElementOrAttribute(sourceFile, position)) { - return openingBrace === CharacterCodes.openBrace; + if (ts.isInsideJsxElementOrAttribute(sourceFile, position)) { + return openingBrace === ts.CharacterCodes.openBrace; } - if (isInTemplateString(sourceFile, position)) { + if (ts.isInTemplateString(sourceFile, position)) { return false; } switch (openingBrace) { - case CharacterCodes.singleQuote: - case CharacterCodes.doubleQuote: - case CharacterCodes.backtick: - return !isInComment(sourceFile, position); + case ts.CharacterCodes.singleQuote: + case ts.CharacterCodes.doubleQuote: + case ts.CharacterCodes.backtick: + return !ts.isInComment(sourceFile, position); } return true; } - function getJsxClosingTagAtPosition(fileName: string, position: number): JsxClosingTagInfo | undefined { + function getJsxClosingTagAtPosition(fileName: string, position: number): ts.JsxClosingTagInfo | undefined { const sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); - const token = findPrecedingToken(position, sourceFile); - if (!token) return undefined; - const element = token.kind === SyntaxKind.GreaterThanToken && isJsxOpeningElement(token.parent) ? token.parent.parent - : isJsxText(token) && isJsxElement(token.parent) ? token.parent : undefined; + const token = ts.findPrecedingToken(position, sourceFile); + if (!token) + return undefined; + const element = token.kind === ts.SyntaxKind.GreaterThanToken && ts.isJsxOpeningElement(token.parent) ? token.parent.parent + : ts.isJsxText(token) && ts.isJsxElement(token.parent) ? token.parent : undefined; if (element && isUnclosedTag(element)) { return { newText: `` }; } - const fragment = token.kind === SyntaxKind.GreaterThanToken && isJsxOpeningFragment(token.parent) ? token.parent.parent - : isJsxText(token) && isJsxFragment(token.parent) ? token.parent : undefined; + const fragment = token.kind === ts.SyntaxKind.GreaterThanToken && ts.isJsxOpeningFragment(token.parent) ? token.parent.parent + : ts.isJsxText(token) && ts.isJsxFragment(token.parent) ? token.parent : undefined; if (fragment && isUnclosedFragment(fragment)) { return { newText: "" }; } } - function getLinesForRange(sourceFile: SourceFile, textRange: TextRange) { + function getLinesForRange(sourceFile: ts.SourceFile, textRange: ts.TextRange) { return { lineStarts: sourceFile.getLineStarts(), firstLine: sourceFile.getLineAndCharacterOfPosition(textRange.pos).line, @@ -2183,16 +2125,16 @@ namespace ts { }; } - function toggleLineComment(fileName: string, textRange: TextRange, insertComment?: boolean): TextChange[] { + function toggleLineComment(fileName: string, textRange: ts.TextRange, insertComment?: boolean): ts.TextChange[] { const sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); - const textChanges: TextChange[] = []; + const textChanges: ts.TextChange[] = []; const { lineStarts, firstLine, lastLine } = getLinesForRange(sourceFile, textRange); let isCommenting = insertComment || false; let leftMostPosition = Number.MAX_VALUE; - const lineTextStarts = new Map(); + const lineTextStarts = new ts.Map(); const firstNonWhitespaceCharacterRegex = new RegExp(/\S/); - const isJsx = isInsideJsxElement(sourceFile, lineStarts[firstLine]); + const isJsx = ts.isInsideJsxElement(sourceFile, lineStarts[firstLine]); const openComment = isJsx ? "{/*" : "//"; // Check each line before any text changes. @@ -2249,17 +2191,17 @@ namespace ts { return textChanges; } - function toggleMultilineComment(fileName: string, textRange: TextRange, insertComment?: boolean, isInsideJsx?: boolean): TextChange[] { + function toggleMultilineComment(fileName: string, textRange: ts.TextRange, insertComment?: boolean, isInsideJsx?: boolean): ts.TextChange[] { const sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); - const textChanges: TextChange[] = []; + const textChanges: ts.TextChange[] = []; const { text } = sourceFile; let hasComment = false; let isCommenting = insertComment || false; - const positions = [] as number[] as SortedArray; + const positions = [] as number[] as ts.SortedArray; let { pos } = textRange; - const isJsx = isInsideJsx !== undefined ? isInsideJsx : isInsideJsxElement(sourceFile, pos); + const isJsx = isInsideJsx !== undefined ? isInsideJsx : ts.isInsideJsxElement(sourceFile, pos); const openMultiline = isJsx ? "{/*" : "/*"; const closeMultiline = isJsx ? "*/}" : "*/"; @@ -2270,7 +2212,7 @@ namespace ts { while (pos <= textRange.end) { // Start of comment is considered inside comment. const offset = text.substr(pos, openMultiline.length) === openMultiline ? openMultiline.length : 0; - const commentRange = isInComment(sourceFile, pos + offset); + const commentRange = ts.isInComment(sourceFile, pos + offset); // If position is in a comment add it to the positions array. if (commentRange) { @@ -2281,7 +2223,7 @@ namespace ts { } positions.push(commentRange.pos); - if (commentRange.kind === SyntaxKind.MultiLineCommentTrivia) { + if (commentRange.kind === ts.SyntaxKind.MultiLineCommentTrivia) { positions.push(commentRange.end); } @@ -2293,7 +2235,7 @@ namespace ts { isCommenting = insertComment !== undefined ? insertComment - : isCommenting || !isTextWhiteSpaceLike(text, pos, newPos === -1 ? textRange.end : pos + newPos); // If isCommenting is already true we don't need to check whitespace again. + : isCommenting || !ts.isTextWhiteSpaceLike(text, pos, newPos === -1 ? textRange.end : pos + newPos); // If isCommenting is already true we don't need to check whitespace again. pos = newPos === -1 ? textRange.end + 1 : pos + newPos + closeMultiline.length; } } @@ -2301,10 +2243,10 @@ namespace ts { // If it didn't found a comment and isCommenting is false means is only empty space. // We want to insert comment in this scenario. if (isCommenting || !hasComment) { - if (isInComment(sourceFile, textRange.pos)?.kind !== SyntaxKind.SingleLineCommentTrivia) { - insertSorted(positions, textRange.pos, compareValues); + if (ts.isInComment(sourceFile, textRange.pos)?.kind !== ts.SyntaxKind.SingleLineCommentTrivia) { + ts.insertSorted(positions, textRange.pos, ts.compareValues); } - insertSorted(positions, textRange.end, compareValues); + ts.insertSorted(positions, textRange.end, ts.compareValues); // Insert open comment if the first position is not a comment already. const firstPos = positions[0]; @@ -2370,7 +2312,7 @@ namespace ts { return textChanges; } - function commentSelection(fileName: string, textRange: TextRange): TextChange[] { + function commentSelection(fileName: string, textRange: ts.TextRange): ts.TextChange[] { const sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); const { firstLine, lastLine } = getLinesForRange(sourceFile, textRange); @@ -2380,26 +2322,26 @@ namespace ts { : toggleLineComment(fileName, textRange, /*insertComment*/ true); } - function uncommentSelection(fileName: string, textRange: TextRange): TextChange[] { + function uncommentSelection(fileName: string, textRange: ts.TextRange): ts.TextChange[] { const sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); - const textChanges: TextChange[] = []; + const textChanges: ts.TextChange[] = []; const { pos } = textRange; let { end } = textRange; // If cursor is not a selection we need to increase the end position // to include the start of the comment. if (pos === end) { - end += isInsideJsxElement(sourceFile, pos) ? 2 : 1; + end += ts.isInsideJsxElement(sourceFile, pos) ? 2 : 1; } for (let i = pos; i <= end; i++) { - const commentRange = isInComment(sourceFile, i); + const commentRange = ts.isInComment(sourceFile, i); if (commentRange) { switch (commentRange.kind) { - case SyntaxKind.SingleLineCommentTrivia: + case ts.SyntaxKind.SingleLineCommentTrivia: textChanges.push.apply(textChanges, toggleLineComment(fileName, { end: commentRange.end, pos: commentRange.pos + 1 }, /*insertComment*/ false)); break; - case SyntaxKind.MultiLineCommentTrivia: + case ts.SyntaxKind.MultiLineCommentTrivia: textChanges.push.apply(textChanges, toggleMultilineComment(fileName, { end: commentRange.end, pos: commentRange.pos + 1 }, /*insertComment*/ false)); } @@ -2410,22 +2352,22 @@ namespace ts { return textChanges; } - function isUnclosedTag({ openingElement, closingElement, parent }: JsxElement): boolean { - return !tagNamesAreEquivalent(openingElement.tagName, closingElement.tagName) || - isJsxElement(parent) && tagNamesAreEquivalent(openingElement.tagName, parent.openingElement.tagName) && isUnclosedTag(parent); + function isUnclosedTag({ openingElement, closingElement, parent }: ts.JsxElement): boolean { + return !ts.tagNamesAreEquivalent(openingElement.tagName, closingElement.tagName) || + ts.isJsxElement(parent) && ts.tagNamesAreEquivalent(openingElement.tagName, parent.openingElement.tagName) && isUnclosedTag(parent); } - function isUnclosedFragment({ closingFragment, parent }: JsxFragment): boolean { - return !!(closingFragment.flags & NodeFlags.ThisNodeHasError) || (isJsxFragment(parent) && isUnclosedFragment(parent)); + function isUnclosedFragment({ closingFragment, parent }: ts.JsxFragment): boolean { + return !!(closingFragment.flags & ts.NodeFlags.ThisNodeHasError) || (ts.isJsxFragment(parent) && isUnclosedFragment(parent)); } - function getSpanOfEnclosingComment(fileName: string, position: number, onlyMultiLine: boolean): TextSpan | undefined { + function getSpanOfEnclosingComment(fileName: string, position: number, onlyMultiLine: boolean): ts.TextSpan | undefined { const sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); - const range = formatting.getRangeOfEnclosingComment(sourceFile, position); - return range && (!onlyMultiLine || range.kind === SyntaxKind.MultiLineCommentTrivia) ? createTextSpanFromRange(range) : undefined; + const range = ts.formatting.getRangeOfEnclosingComment(sourceFile, position); + return range && (!onlyMultiLine || range.kind === ts.SyntaxKind.MultiLineCommentTrivia) ? ts.createTextSpanFromRange(range) : undefined; } - function getTodoComments(fileName: string, descriptors: TodoCommentDescriptor[]): TodoComment[] { + function getTodoComments(fileName: string, descriptors: ts.TodoCommentDescriptor[]): ts.TodoComment[] { // Note: while getting todo comments seems like a syntactic operation, we actually // treat it as a semantic operation here. This is because we expect our host to call // this on every single file. If we treat this syntactically, then that will cause @@ -2439,7 +2381,7 @@ namespace ts { cancellationToken.throwIfCancellationRequested(); const fileContents = sourceFile.text; - const result: TodoComment[] = []; + const result: ts.TodoComment[] = []; // Exclude node_modules files as we don't want to show the todos of external libraries. if (descriptors.length > 0 && !isNodeModulesFile(sourceFile.fileName)) { @@ -2467,24 +2409,25 @@ namespace ts { // i.e. 'undefined' in position 3 above means TODO(jason) didn't match. // "hack" in position 4 means HACK did match. const firstDescriptorCaptureIndex = 3; - Debug.assert(matchArray.length === descriptors.length + firstDescriptorCaptureIndex); + ts.Debug.assert(matchArray.length === descriptors.length + firstDescriptorCaptureIndex); const preamble = matchArray[1]; const matchPosition = matchArray.index + preamble.length; // OK, we have found a match in the file. This is only an acceptable match if // it is contained within a comment. - if (!isInComment(sourceFile, matchPosition)) { + if (!ts.isInComment(sourceFile, matchPosition)) { continue; } - let descriptor: TodoCommentDescriptor | undefined; + let descriptor: ts.TodoCommentDescriptor | undefined; for (let i = 0; i < descriptors.length; i++) { if (matchArray[i + firstDescriptorCaptureIndex]) { descriptor = descriptors[i]; } } - if (descriptor === undefined) return Debug.fail(); + if (descriptor === undefined) + return ts.Debug.fail(); // We don't want to match something like 'TODOBY', so we make sure a non // letter/digit follows the match. @@ -2536,7 +2479,7 @@ namespace ts { // Note that the outermost group is *not* a capture group, but the innermost groups // *are* capture groups. By capturing the inner literals we can determine after // matching which descriptor we are dealing with. - const literals = "(?:" + map(descriptors, d => "(" + escapeRegExp(d.text) + ")").join("|") + ")"; + const literals = "(?:" + ts.map(descriptors, d => "(" + escapeRegExp(d.text) + ")").join("|") + ")"; // After matching a descriptor literal, the following regexp matches the rest of the // text up to the end of the line (or */). @@ -2562,22 +2505,22 @@ namespace ts { } function isLetterOrDigit(char: number): boolean { - return (char >= CharacterCodes.a && char <= CharacterCodes.z) || - (char >= CharacterCodes.A && char <= CharacterCodes.Z) || - (char >= CharacterCodes._0 && char <= CharacterCodes._9); + return (char >= ts.CharacterCodes.a && char <= ts.CharacterCodes.z) || + (char >= ts.CharacterCodes.A && char <= ts.CharacterCodes.Z) || + (char >= ts.CharacterCodes._0 && char <= ts.CharacterCodes._9); } function isNodeModulesFile(path: string): boolean { - return stringContains(path, "/node_modules/"); + return ts.stringContains(path, "/node_modules/"); } } - function getRenameInfo(fileName: string, position: number, options?: RenameInfoOptions): RenameInfo { + function getRenameInfo(fileName: string, position: number, options?: ts.RenameInfoOptions): ts.RenameInfo { synchronizeHostData(); - return Rename.getRenameInfo(program, getValidSourceFile(fileName), position, options); + return ts.Rename.getRenameInfo(program, getValidSourceFile(fileName), position, options); } - function getRefactorContext(file: SourceFile, positionOrRange: number | TextRange, preferences: UserPreferences, formatOptions?: FormatCodeSettings, triggerReason?: RefactorTriggerReason, kind?: string): RefactorContext { + function getRefactorContext(file: ts.SourceFile, positionOrRange: number | ts.TextRange, preferences: ts.UserPreferences, formatOptions?: ts.FormatCodeSettings, triggerReason?: ts.RefactorTriggerReason, kind?: string): ts.RefactorContext { const [startPosition, endPosition] = typeof positionOrRange === "number" ? [positionOrRange, undefined] : [positionOrRange.pos, positionOrRange.end]; return { file, @@ -2585,7 +2528,7 @@ namespace ts { endPosition, program: getProgram()!, host, - formatContext: formatting.getFormatContext(formatOptions!, host), // TODO: GH#18217 + formatContext: ts.formatting.getFormatContext(formatOptions!, host), cancellationToken, preferences, triggerReason, @@ -2593,7 +2536,7 @@ namespace ts { }; } - function getInlayHintsContext(file: SourceFile, span: TextSpan, preferences: UserPreferences): InlayHintsContext { + function getInlayHintsContext(file: ts.SourceFile, span: ts.TextSpan, preferences: ts.UserPreferences): ts.InlayHintsContext { return { file, program: getProgram()!, @@ -2604,30 +2547,22 @@ namespace ts { }; } - function getSmartSelectionRange(fileName: string, position: number): SelectionRange { - return SmartSelectionRange.getSmartSelectionRange(position, syntaxTreeCache.getCurrentSourceFile(fileName)); + function getSmartSelectionRange(fileName: string, position: number): ts.SelectionRange { + return ts.SmartSelectionRange.getSmartSelectionRange(position, syntaxTreeCache.getCurrentSourceFile(fileName)); } - function getApplicableRefactors(fileName: string, positionOrRange: number | TextRange, preferences: UserPreferences = emptyOptions, triggerReason: RefactorTriggerReason, kind: string): ApplicableRefactorInfo[] { + function getApplicableRefactors(fileName: string, positionOrRange: number | ts.TextRange, preferences: ts.UserPreferences = ts.emptyOptions, triggerReason: ts.RefactorTriggerReason, kind: string): ts.ApplicableRefactorInfo[] { synchronizeHostData(); const file = getValidSourceFile(fileName); - return refactor.getApplicableRefactors(getRefactorContext(file, positionOrRange, preferences, emptyOptions, triggerReason, kind)); + return ts.refactor.getApplicableRefactors(getRefactorContext(file, positionOrRange, preferences, ts.emptyOptions, triggerReason, kind)); } - - function getEditsForRefactor( - fileName: string, - formatOptions: FormatCodeSettings, - positionOrRange: number | TextRange, - refactorName: string, - actionName: string, - preferences: UserPreferences = emptyOptions, - ): RefactorEditInfo | undefined { + function getEditsForRefactor(fileName: string, formatOptions: ts.FormatCodeSettings, positionOrRange: number | ts.TextRange, refactorName: string, actionName: string, preferences: ts.UserPreferences = ts.emptyOptions): ts.RefactorEditInfo | undefined { synchronizeHostData(); const file = getValidSourceFile(fileName); - return refactor.getEditsForRefactor(getRefactorContext(file, positionOrRange, preferences, formatOptions), refactorName, actionName); + return ts.refactor.getEditsForRefactor(getRefactorContext(file, positionOrRange, preferences, formatOptions), refactorName, actionName); } - function toLineColumnOffset(fileName: string, position: number): LineAndCharacter { + function toLineColumnOffset(fileName: string, position: number): ts.LineAndCharacter { // Go to Definition supports returning a zero-length span at position 0 for // non-existent files. We need to special-case the conversion of position 0 // to avoid a crash trying to get the text for that file, since this function @@ -2638,33 +2573,33 @@ namespace ts { return sourceMapper.toLineColumnOffset(fileName, position); } - function prepareCallHierarchy(fileName: string, position: number): CallHierarchyItem | CallHierarchyItem[] | undefined { + function prepareCallHierarchy(fileName: string, position: number): ts.CallHierarchyItem | ts.CallHierarchyItem[] | undefined { synchronizeHostData(); - const declarations = CallHierarchy.resolveCallHierarchyDeclaration(program, getTouchingPropertyName(getValidSourceFile(fileName), position)); - return declarations && mapOneOrMany(declarations, declaration => CallHierarchy.createCallHierarchyItem(program, declaration)); + const declarations = ts.CallHierarchy.resolveCallHierarchyDeclaration(program, ts.getTouchingPropertyName(getValidSourceFile(fileName), position)); + return declarations && ts.mapOneOrMany(declarations, declaration => ts.CallHierarchy.createCallHierarchyItem(program, declaration)); } - function provideCallHierarchyIncomingCalls(fileName: string, position: number): CallHierarchyIncomingCall[] { + function provideCallHierarchyIncomingCalls(fileName: string, position: number): ts.CallHierarchyIncomingCall[] { synchronizeHostData(); const sourceFile = getValidSourceFile(fileName); - const declaration = firstOrOnly(CallHierarchy.resolveCallHierarchyDeclaration(program, position === 0 ? sourceFile : getTouchingPropertyName(sourceFile, position))); - return declaration ? CallHierarchy.getIncomingCalls(program, declaration, cancellationToken) : []; + const declaration = ts.firstOrOnly(ts.CallHierarchy.resolveCallHierarchyDeclaration(program, position === 0 ? sourceFile : ts.getTouchingPropertyName(sourceFile, position))); + return declaration ? ts.CallHierarchy.getIncomingCalls(program, declaration, cancellationToken) : []; } - function provideCallHierarchyOutgoingCalls(fileName: string, position: number): CallHierarchyOutgoingCall[] { + function provideCallHierarchyOutgoingCalls(fileName: string, position: number): ts.CallHierarchyOutgoingCall[] { synchronizeHostData(); const sourceFile = getValidSourceFile(fileName); - const declaration = firstOrOnly(CallHierarchy.resolveCallHierarchyDeclaration(program, position === 0 ? sourceFile : getTouchingPropertyName(sourceFile, position))); - return declaration ? CallHierarchy.getOutgoingCalls(program, declaration) : []; + const declaration = ts.firstOrOnly(ts.CallHierarchy.resolveCallHierarchyDeclaration(program, position === 0 ? sourceFile : ts.getTouchingPropertyName(sourceFile, position))); + return declaration ? ts.CallHierarchy.getOutgoingCalls(program, declaration) : []; } - function provideInlayHints(fileName: string, span: TextSpan, preferences: UserPreferences = emptyOptions): InlayHint[] { + function provideInlayHints(fileName: string, span: ts.TextSpan, preferences: ts.UserPreferences = ts.emptyOptions): ts.InlayHint[] { synchronizeHostData(); const sourceFile = getValidSourceFile(fileName); - return InlayHints.provideInlayHints(getInlayHintsContext(sourceFile, span, preferences)); + return ts.InlayHints.provideInlayHints(getInlayHintsContext(sourceFile, span, preferences)); } - const ls: LanguageService = { + const ls: ts.LanguageService = { dispose, cleanupSemanticCache, getSyntacticDiagnostics, @@ -2733,31 +2668,27 @@ namespace ts { }; switch (languageServiceMode) { - case LanguageServiceMode.Semantic: + case ts.LanguageServiceMode.Semantic: break; - case LanguageServiceMode.PartialSemantic: - invalidOperationsInPartialSemanticMode.forEach(key => - ls[key] = () => { + case ts.LanguageServiceMode.PartialSemantic: + invalidOperationsInPartialSemanticMode.forEach(key => ls[key] = () => { throw new Error(`LanguageService Operation: ${key} not allowed in LanguageServiceMode.PartialSemantic`); - } - ); + }); break; - case LanguageServiceMode.Syntactic: - invalidOperationsInSyntacticMode.forEach(key => - ls[key] = () => { + case ts.LanguageServiceMode.Syntactic: + invalidOperationsInSyntacticMode.forEach(key => ls[key] = () => { throw new Error(`LanguageService Operation: ${key} not allowed in LanguageServiceMode.Syntactic`); - } - ); + }); break; default: - Debug.assertNever(languageServiceMode); + ts.Debug.assertNever(languageServiceMode); } return ls; } /* @internal */ /** Names in the name table are escaped, so an identifier `__foo` will have a name table entry `___foo`. */ - export function getNameTable(sourceFile: SourceFile): UnderscoreEscapedMap { + export function getNameTable(sourceFile: ts.SourceFile): ts.UnderscoreEscapedMap { if (!sourceFile.nameTable) { initializeNameTable(sourceFile); } @@ -2765,22 +2696,22 @@ namespace ts { return sourceFile.nameTable!; // TODO: GH#18217 } - function initializeNameTable(sourceFile: SourceFile): void { - const nameTable = sourceFile.nameTable = new Map(); + function initializeNameTable(sourceFile: ts.SourceFile): void { + const nameTable = sourceFile.nameTable = new ts.Map(); sourceFile.forEachChild(function walk(node) { - if (isIdentifier(node) && !isTagName(node) && node.escapedText || isStringOrNumericLiteralLike(node) && literalIsName(node)) { - const text = getEscapedTextOfIdentifierOrLiteral(node); + if (ts.isIdentifier(node) && !ts.isTagName(node) && node.escapedText || ts.isStringOrNumericLiteralLike(node) && literalIsName(node)) { + const text = ts.getEscapedTextOfIdentifierOrLiteral(node); nameTable.set(text, nameTable.get(text) === undefined ? node.pos : -1); } - else if (isPrivateIdentifier(node)) { + else if (ts.isPrivateIdentifier(node)) { const text = node.escapedText; nameTable.set(text, nameTable.get(text) === undefined ? node.pos : -1); } - forEachChild(node, walk); - if (hasJSDocNodes(node)) { + ts.forEachChild(node, walk); + if (ts.hasJSDocNodes(node)) { for (const jsDoc of node.jsDoc!) { - forEachChild(jsDoc, walk); + ts.forEachChild(jsDoc, walk); } } }); @@ -2792,49 +2723,51 @@ namespace ts { * then we want 'something' to be in the name table. Similarly, if we have * "a['propname']" then we want to store "propname" in the name table. */ - function literalIsName(node: StringLiteralLike | NumericLiteral): boolean { - return isDeclarationName(node) || - node.parent.kind === SyntaxKind.ExternalModuleReference || + function literalIsName(node: ts.StringLiteralLike | ts.NumericLiteral): boolean { + return ts.isDeclarationName(node) || + node.parent.kind === ts.SyntaxKind.ExternalModuleReference || isArgumentOfElementAccessExpression(node) || - isLiteralComputedPropertyDeclarationName(node); + ts.isLiteralComputedPropertyDeclarationName(node); } /** * Returns the containing object literal property declaration given a possible name node, e.g. "a" in x = { "a": 1 } */ /* @internal */ - export function getContainingObjectLiteralElement(node: Node): ObjectLiteralElementWithName | undefined { + export function getContainingObjectLiteralElement(node: ts.Node): ObjectLiteralElementWithName | undefined { const element = getContainingObjectLiteralElementWorker(node); - return element && (isObjectLiteralExpression(element.parent) || isJsxAttributes(element.parent)) ? element as ObjectLiteralElementWithName : undefined; + return element && (ts.isObjectLiteralExpression(element.parent) || ts.isJsxAttributes(element.parent)) ? element as ObjectLiteralElementWithName : undefined; } - function getContainingObjectLiteralElementWorker(node: Node): ObjectLiteralElement | undefined { + function getContainingObjectLiteralElementWorker(node: ts.Node): ts.ObjectLiteralElement | undefined { switch (node.kind) { - case SyntaxKind.StringLiteral: - case SyntaxKind.NoSubstitutionTemplateLiteral: - case SyntaxKind.NumericLiteral: - if (node.parent.kind === SyntaxKind.ComputedPropertyName) { - return isObjectLiteralElement(node.parent.parent) ? node.parent.parent : undefined; + case ts.SyntaxKind.StringLiteral: + case ts.SyntaxKind.NoSubstitutionTemplateLiteral: + case ts.SyntaxKind.NumericLiteral: + if (node.parent.kind === ts.SyntaxKind.ComputedPropertyName) { + return ts.isObjectLiteralElement(node.parent.parent) ? node.parent.parent : undefined; } // falls through - case SyntaxKind.Identifier: - return isObjectLiteralElement(node.parent) && - (node.parent.parent.kind === SyntaxKind.ObjectLiteralExpression || node.parent.parent.kind === SyntaxKind.JsxAttributes) && + case ts.SyntaxKind.Identifier: + return ts.isObjectLiteralElement(node.parent) && + (node.parent.parent.kind === ts.SyntaxKind.ObjectLiteralExpression || node.parent.parent.kind === ts.SyntaxKind.JsxAttributes) && node.parent.name === node ? node.parent : undefined; } return undefined; } /* @internal */ - export type ObjectLiteralElementWithName = ObjectLiteralElement & { name: PropertyName; parent: ObjectLiteralExpression | JsxAttributes }; - - function getSymbolAtLocationForQuickInfo(node: Node, checker: TypeChecker): Symbol | undefined { + export type ObjectLiteralElementWithName = ts.ObjectLiteralElement & { + name: ts.PropertyName; + parent: ts.ObjectLiteralExpression | ts.JsxAttributes; + }; + function getSymbolAtLocationForQuickInfo(node: ts.Node, checker: ts.TypeChecker): ts.Symbol | undefined { const object = getContainingObjectLiteralElement(node); if (object) { const contextualType = checker.getContextualType(object.parent); const properties = contextualType && getPropertySymbolsFromContextualType(object, checker, contextualType, /*unionSymbolOk*/ false); if (properties && properties.length === 1) { - return first(properties); + return ts.first(properties); } } return checker.getSymbolAtLocation(node); @@ -2842,31 +2775,33 @@ namespace ts { /** Gets all symbols for one property. Does not get symbols for every property. */ /* @internal */ - export function getPropertySymbolsFromContextualType(node: ObjectLiteralElementWithName, checker: TypeChecker, contextualType: Type, unionSymbolOk: boolean): readonly Symbol[] { - const name = getNameFromPropertyName(node.name); - if (!name) return emptyArray; + export function getPropertySymbolsFromContextualType(node: ObjectLiteralElementWithName, checker: ts.TypeChecker, contextualType: ts.Type, unionSymbolOk: boolean): readonly ts.Symbol[] { + const name = ts.getNameFromPropertyName(node.name); + if (!name) + return ts.emptyArray; if (!contextualType.isUnion()) { const symbol = contextualType.getProperty(name); - return symbol ? [symbol] : emptyArray; + return symbol ? [symbol] : ts.emptyArray; } - const discriminatedPropertySymbols = mapDefined(contextualType.types, t => (isObjectLiteralExpression(node.parent)|| isJsxAttributes(node.parent)) && checker.isTypeInvalidDueToUnionDiscriminant(t, node.parent) ? undefined : t.getProperty(name)); + const discriminatedPropertySymbols = ts.mapDefined(contextualType.types, t => (ts.isObjectLiteralExpression(node.parent) || ts.isJsxAttributes(node.parent)) && checker.isTypeInvalidDueToUnionDiscriminant(t, node.parent) ? undefined : t.getProperty(name)); if (unionSymbolOk && (discriminatedPropertySymbols.length === 0 || discriminatedPropertySymbols.length === contextualType.types.length)) { const symbol = contextualType.getProperty(name); - if (symbol) return [symbol]; + if (symbol) + return [symbol]; } if (discriminatedPropertySymbols.length === 0) { // Bad discriminant -- do again without discriminating - return mapDefined(contextualType.types, t => t.getProperty(name)); + return ts.mapDefined(contextualType.types, t => t.getProperty(name)); } return discriminatedPropertySymbols; } - function isArgumentOfElementAccessExpression(node: Node) { + function isArgumentOfElementAccessExpression(node: ts.Node) { return node && node.parent && - node.parent.kind === SyntaxKind.ElementAccessExpression && - (node.parent as ElementAccessExpression).argumentExpression === node; + node.parent.kind === ts.SyntaxKind.ElementAccessExpression && + (node.parent as ts.ElementAccessExpression).argumentExpression === node; } /// getDefaultLibraryFilePath @@ -2877,14 +2812,14 @@ namespace ts { * node package. * The functionality is not supported if the ts module is consumed outside of a node module. */ - export function getDefaultLibFilePath(options: CompilerOptions): string { + export function getDefaultLibFilePath(options: ts.CompilerOptions): string { // Check __dirname is defined and that we are on a node.js system. if (typeof __dirname !== "undefined") { - return combinePaths(__dirname, getDefaultLibFileName(options)); + return ts.combinePaths(__dirname, ts.getDefaultLibFileName(options)); } throw new Error("getDefaultLibFilePath is only supported when consumed as a node module. "); } - setObjectAllocator(getServicesObjectAllocator()); + ts.setObjectAllocator(getServicesObjectAllocator()); } diff --git a/src/services/shims.ts b/src/services/shims.ts index 5a87dcd6eefa4..858bce7415abd 100644 --- a/src/services/shims.ts +++ b/src/services/shims.ts @@ -14,7 +14,9 @@ // /* @internal */ -let debugObjectHost: { CollectGarbage(): void } = (function (this: any) { // eslint-disable-line prefer-const +let debugObjectHost: { + CollectGarbage(): void; +} = (function (this: any) { return this; })(); @@ -27,11 +29,11 @@ namespace ts { fileNames: string[]; // The file names that belong to the same project. projectRootPath: string; // The path to the project root directory safeListPath: string; // The path used to retrieve the safe list - packageNameToTypingLocation: ESMap; // The map of package names to their cached typing locations and installed versions - typeAcquisition: TypeAcquisition; // Used to customize the type acquisition process - compilerOptions: CompilerOptions; // Used as a source for typing inference + packageNameToTypingLocation: ts.ESMap; // The map of package names to their cached typing locations and installed versions + typeAcquisition: ts.TypeAcquisition; // Used to customize the type acquisition process + compilerOptions: ts.CompilerOptions; // Used as a source for typing inference unresolvedImports: readonly string[]; // List of unresolved module ids from imports - typesRegistry: ReadonlyESMap>; // The map of available typings in npm to maps of TS versions to their latest supported versions + typesRegistry: ts.ReadonlyESMap>; // The map of available typings in npm to maps of TS versions to their latest supported versions } export interface ScriptSnapshotShim { @@ -65,11 +67,11 @@ namespace ts { /** Returns a JSON-encoded value of the type: string[] */ getScriptFileNames(): string; - getScriptKind?(fileName: string): ScriptKind; + getScriptKind?(fileName: string): ts.ScriptKind; getScriptVersion(fileName: string): string; getScriptSnapshot(fileName: string): ScriptSnapshotShim; getLocalizedDiagnosticMessages(): string; - getCancellationToken(): HostCancellationToken; + getCancellationToken(): ts.HostCancellationToken; getCurrentDirectory(): string; getDirectories(path: string): string; getDefaultLibFileName(options: string): string; @@ -133,7 +135,7 @@ namespace ts { } export interface LanguageServiceShim extends Shim { - languageService: LanguageService; + languageService: ts.LanguageService; dispose(_dummy: {}): void; @@ -147,25 +149,24 @@ namespace ts { getCompilerOptionsDiagnostics(): string; getSyntacticClassifications(fileName: string, start: number, length: number): string; - getSemanticClassifications(fileName: string, start: number, length: number, format?: SemanticClassificationFormat): string; + getSemanticClassifications(fileName: string, start: number, length: number, format?: ts.SemanticClassificationFormat): string; getEncodedSyntacticClassifications(fileName: string, start: number, length: number): string; - getEncodedSemanticClassifications(fileName: string, start: number, length: number, format?: SemanticClassificationFormat): string; - - getCompletionsAtPosition(fileName: string, position: number, preferences: UserPreferences | undefined, formattingSettings: FormatCodeSettings | undefined): string; - getCompletionEntryDetails(fileName: string, position: number, entryName: string, formatOptions: string/*Services.FormatCodeOptions*/ | undefined, source: string | undefined, preferences: UserPreferences | undefined, data: CompletionEntryData | undefined): string; + getEncodedSemanticClassifications(fileName: string, start: number, length: number, format?: ts.SemanticClassificationFormat): string; + getCompletionsAtPosition(fileName: string, position: number, preferences: ts.UserPreferences | undefined, formattingSettings: ts.FormatCodeSettings | undefined): string; + getCompletionEntryDetails(fileName: string, position: number, entryName: string, formatOptions: string /*Services.FormatCodeOptions*/ | undefined, source: string | undefined, preferences: ts.UserPreferences | undefined, data: ts.CompletionEntryData | undefined): string; getQuickInfoAtPosition(fileName: string, position: number): string; getNameOrDottedNameSpan(fileName: string, startPos: number, endPos: number): string; getBreakpointStatementAtPosition(fileName: string, position: number): string; - getSignatureHelpItems(fileName: string, position: number, options: SignatureHelpItemsOptions | undefined): string; + getSignatureHelpItems(fileName: string, position: number, options: ts.SignatureHelpItemsOptions | undefined): string; /** * Returns a JSON-encoded value of the type: * { canRename: boolean, localizedErrorMessage: string, displayName: string, fullDisplayName: string, kind: string, kindModifiers: string, triggerSpan: { start; length } } */ - getRenameInfo(fileName: string, position: number, options?: RenameInfoOptions): string; + getRenameInfo(fileName: string, position: number, options?: ts.RenameInfoOptions): string; getSmartSelectionRange(fileName: string, position: number): string; /** @@ -265,7 +266,7 @@ namespace ts { /** * Returns JSON-encoded value of the type TextInsertion. */ - getDocCommentTemplateAtPosition(fileName: string, position: number, options?: DocCommentTemplateOptions): string; + getDocCommentTemplateAtPosition(fileName: string, position: number, options?: ts.DocCommentTemplateOptions): string; /** * Returns JSON-encoded boolean to indicate whether we should support brace location @@ -282,25 +283,24 @@ namespace ts { prepareCallHierarchy(fileName: string, position: number): string; provideCallHierarchyIncomingCalls(fileName: string, position: number): string; provideCallHierarchyOutgoingCalls(fileName: string, position: number): string; - provideInlayHints(fileName: string, span: TextSpan, preference: UserPreferences | undefined): string; + provideInlayHints(fileName: string, span: ts.TextSpan, preference: ts.UserPreferences | undefined): string; getEmitOutput(fileName: string): string; - getEmitOutputObject(fileName: string): EmitOutput; - - toggleLineComment(fileName: string, textChange: TextRange): string; - toggleMultilineComment(fileName: string, textChange: TextRange): string; - commentSelection(fileName: string, textChange: TextRange): string; - uncommentSelection(fileName: string, textChange: TextRange): string; + getEmitOutputObject(fileName: string): ts.EmitOutput; + toggleLineComment(fileName: string, textChange: ts.TextRange): string; + toggleMultilineComment(fileName: string, textChange: ts.TextRange): string; + commentSelection(fileName: string, textChange: ts.TextRange): string; + uncommentSelection(fileName: string, textChange: ts.TextRange): string; } export interface ClassifierShim extends Shim { - getEncodedLexicalClassifications(text: string, lexState: EndOfLineState, syntacticClassifierAbsent?: boolean): string; - getClassificationsForLine(text: string, lexState: EndOfLineState, syntacticClassifierAbsent?: boolean): string; + getEncodedLexicalClassifications(text: string, lexState: ts.EndOfLineState, syntacticClassifierAbsent?: boolean): string; + getClassificationsForLine(text: string, lexState: ts.EndOfLineState, syntacticClassifierAbsent?: boolean): string; } export interface CoreServicesShim extends Shim { getAutomaticTypeDirectiveNames(compilerOptionsJson: string): string; - getPreProcessedFileInfo(fileName: string, sourceText: IScriptSnapshot): string; - getTSConfigFileInfo(fileName: string, sourceText: IScriptSnapshot): string; + getPreProcessedFileInfo(fileName: string, sourceText: ts.IScriptSnapshot): string; + getTSConfigFileInfo(fileName: string, sourceText: ts.IScriptSnapshot): string; getDefaultCompilationSettings(): string; discoverTypings(discoverTypingsJson: string): string; } @@ -311,7 +311,7 @@ namespace ts { } } - class ScriptSnapshotShimAdapter implements IScriptSnapshot { + class ScriptSnapshotShimAdapter implements ts.IScriptSnapshot { constructor(private scriptSnapshotShim: ScriptSnapshotShim) { } @@ -323,7 +323,7 @@ namespace ts { return this.scriptSnapshotShim.getLength(); } - public getChangeRange(oldSnapshot: IScriptSnapshot): TextChangeRange | undefined { + public getChangeRange(oldSnapshot: ts.IScriptSnapshot): ts.TextChangeRange | undefined { const oldSnapshotShim = oldSnapshot as ScriptSnapshotShimAdapter; const encoded = this.scriptSnapshotShim.getChangeRange(oldSnapshotShim.scriptSnapshotShim); /* eslint-disable no-null/no-null */ @@ -332,9 +332,14 @@ namespace ts { } /* eslint-enable no-null/no-null */ - const decoded: { span: { start: number; length: number; }; newLength: number; } = JSON.parse(encoded!); // TODO: GH#18217 - return createTextChangeRange( - createTextSpan(decoded.span.start, decoded.span.length), decoded.newLength); + const decoded: { + span: { + start: number; + length: number; + }; + newLength: number; + } = JSON.parse(encoded!); // TODO: GH#18217 + return ts.createTextChangeRange(ts.createTextSpan(decoded.span.start, decoded.span.length), decoded.newLength); } public dispose(): void { @@ -346,12 +351,12 @@ namespace ts { } } - export class LanguageServiceShimHostAdapter implements LanguageServiceHost { + export class LanguageServiceShimHostAdapter implements ts.LanguageServiceHost { private loggingEnabled = false; private tracingEnabled = false; - public resolveModuleNames: ((moduleName: string[], containingFile: string) => (ResolvedModuleFull | undefined)[]) | undefined; - public resolveTypeReferenceDirectives: ((typeDirectiveNames: string[] | readonly FileReference[], containingFile: string) => (ResolvedTypeReferenceDirective | undefined)[]) | undefined; + public resolveModuleNames: ((moduleName: string[], containingFile: string) => (ts.ResolvedModuleFull | undefined)[]) | undefined; + public resolveTypeReferenceDirectives: ((typeDirectiveNames: string[] | readonly ts.FileReference[], containingFile: string) => (ts.ResolvedTypeReferenceDirective | undefined)[]) | undefined; public directoryExists: ((directoryName: string) => boolean) | undefined; constructor(private shimHost: LanguageServiceShimHost) { @@ -359,10 +364,10 @@ namespace ts { // 'in' does not have this effect. if ("getModuleResolutionsForFile" in this.shimHost) { this.resolveModuleNames = (moduleNames, containingFile) => { - const resolutionsInFile = JSON.parse(this.shimHost.getModuleResolutionsForFile!(containingFile)) as MapLike; // TODO: GH#18217 - return map(moduleNames, name => { - const result = getProperty(resolutionsInFile, name); - return result ? { resolvedFileName: result, extension: extensionFromPath(result), isExternalLibraryImport: false } : undefined; + const resolutionsInFile = JSON.parse(this.shimHost.getModuleResolutionsForFile!(containingFile)) as ts.MapLike; // TODO: GH#18217 + return ts.map(moduleNames, name => { + const result = ts.getProperty(resolutionsInFile, name); + return result ? { resolvedFileName: result, extension: ts.extensionFromPath(result), isExternalLibraryImport: false } : undefined; }); }; } @@ -371,8 +376,8 @@ namespace ts { } if ("getTypeReferenceDirectiveResolutionsForFile" in this.shimHost) { this.resolveTypeReferenceDirectives = (typeDirectiveNames, containingFile) => { - const typeDirectivesForFile = JSON.parse(this.shimHost.getTypeReferenceDirectiveResolutionsForFile!(containingFile)) as MapLike; // TODO: GH#18217 - return map(typeDirectiveNames as (string | FileReference)[], name => getProperty(typeDirectivesForFile, isString(name) ? name : name.fileName.toLowerCase())); + const typeDirectivesForFile = JSON.parse(this.shimHost.getTypeReferenceDirectiveResolutionsForFile!(containingFile)) as ts.MapLike; // TODO: GH#18217 + return ts.map(typeDirectiveNames as (string | ts.FileReference)[], name => ts.getProperty(typeDirectivesForFile, ts.isString(name) ? name : name.fileName.toLowerCase())); }; } } @@ -413,13 +418,13 @@ namespace ts { return this.shimHost.useCaseSensitiveFileNames ? this.shimHost.useCaseSensitiveFileNames() : false; } - public getCompilationSettings(): CompilerOptions { + public getCompilationSettings(): ts.CompilerOptions { const settingsJson = this.shimHost.getCompilationSettings(); // eslint-disable-next-line no-null/no-null if (settingsJson === null || settingsJson === "") { throw Error("LanguageServiceShimHostAdapter.getCompilationSettings: empty compilationSettings"); } - const compilerOptions = JSON.parse(settingsJson) as CompilerOptions; + const compilerOptions = JSON.parse(settingsJson) as ts.CompilerOptions; // permit language service to handle all files (filtering should be performed on the host side) compilerOptions.allowNonTsExtensions = true; return compilerOptions; @@ -430,17 +435,17 @@ namespace ts { return JSON.parse(encoded); } - public getScriptSnapshot(fileName: string): IScriptSnapshot | undefined { + public getScriptSnapshot(fileName: string): ts.IScriptSnapshot | undefined { const scriptSnapshot = this.shimHost.getScriptSnapshot(fileName); return scriptSnapshot && new ScriptSnapshotShimAdapter(scriptSnapshot); } - public getScriptKind(fileName: string): ScriptKind { + public getScriptKind(fileName: string): ts.ScriptKind { if ("getScriptKind" in this.shimHost) { return this.shimHost.getScriptKind!(fileName); // TODO: GH#18217 } else { - return ScriptKind.Unknown; + return ts.ScriptKind.Unknown; } } @@ -465,9 +470,9 @@ namespace ts { /* eslint-enable no-null/no-null */ } - public getCancellationToken(): HostCancellationToken { + public getCancellationToken(): ts.HostCancellationToken { const hostCancellationToken = this.shimHost.getCancellationToken(); - return new ThrottledCancellationToken(hostCancellationToken); + return new ts.ThrottledCancellationToken(hostCancellationToken); } public getCurrentDirectory(): string { @@ -478,22 +483,13 @@ namespace ts { return JSON.parse(this.shimHost.getDirectories(path)); } - public getDefaultLibFileName(options: CompilerOptions): string { + public getDefaultLibFileName(options: ts.CompilerOptions): string { return this.shimHost.getDefaultLibFileName(JSON.stringify(options)); } public readDirectory(path: string, extensions?: readonly string[], exclude?: string[], include?: string[], depth?: number): string[] { - const pattern = getFileMatcherPatterns(path, exclude, include, - this.shimHost.useCaseSensitiveFileNames!(), this.shimHost.getCurrentDirectory()); // TODO: GH#18217 - return JSON.parse(this.shimHost.readDirectory( - path, - JSON.stringify(extensions), - JSON.stringify(pattern.basePaths), - pattern.excludePattern, - pattern.includeFilePattern, - pattern.includeDirectoryPattern, - depth - )); + const pattern = ts.getFileMatcherPatterns(path, exclude, include, this.shimHost.useCaseSensitiveFileNames!(), this.shimHost.getCurrentDirectory()); // TODO: GH#18217 + return JSON.parse(this.shimHost.readDirectory(path, JSON.stringify(extensions), JSON.stringify(pattern.basePaths), pattern.excludePattern, pattern.includeFilePattern, pattern.includeDirectoryPattern, depth)); } public readFile(path: string, encoding?: string): string | undefined { @@ -505,7 +501,7 @@ namespace ts { } } - export class CoreServicesShimHostAdapter implements ParseConfigHost, ModuleResolutionHost, JsTyping.TypingResolutionHost { + export class CoreServicesShimHostAdapter implements ts.ParseConfigHost, ts.ModuleResolutionHost, ts.JsTyping.TypingResolutionHost { public directoryExists: (directoryName: string) => boolean; public realpath: (path: string) => string; @@ -528,17 +524,8 @@ namespace ts { } public readDirectory(rootDir: string, extensions: readonly string[], exclude: readonly string[], include: readonly string[], depth?: number): string[] { - const pattern = getFileMatcherPatterns(rootDir, exclude, include, - this.shimHost.useCaseSensitiveFileNames!(), this.shimHost.getCurrentDirectory()); // TODO: GH#18217 - return JSON.parse(this.shimHost.readDirectory( - rootDir, - JSON.stringify(extensions), - JSON.stringify(pattern.basePaths), - pattern.excludePattern, - pattern.includeFilePattern, - pattern.includeDirectoryPattern, - depth - )); + const pattern = ts.getFileMatcherPatterns(rootDir, exclude, include, this.shimHost.useCaseSensitiveFileNames!(), this.shimHost.getCurrentDirectory()); // TODO: GH#18217 + return JSON.parse(this.shimHost.readDirectory(rootDir, JSON.stringify(extensions), JSON.stringify(pattern.basePaths), pattern.excludePattern, pattern.includeFilePattern, pattern.includeDirectoryPattern, depth)); } public fileExists(fileName: string): boolean { @@ -558,15 +545,15 @@ namespace ts { let start: number | undefined; if (logPerformance) { logger.log(actionDescription); - start = timestamp(); + start = ts.timestamp(); } const result = action(); if (logPerformance) { - const end = timestamp(); + const end = ts.timestamp(); logger.log(`${actionDescription} completed in ${end - start!} msec`); - if (isString(result)) { + if (ts.isString(result)) { let str = result; if (str.length > 128) { str = str.substring(0, 128) + "..."; @@ -588,7 +575,7 @@ namespace ts { return returnJson ? JSON.stringify({ result }) : result as T; } catch (err) { - if (err instanceof OperationCanceledException) { + if (err instanceof ts.OperationCanceledException) { return JSON.stringify({ canceled: true }); } logInternalError(logger, err); @@ -616,16 +603,16 @@ namespace ts { reportsUnnecessary?: {}; reportsDeprecated?: {}; } - export function realizeDiagnostics(diagnostics: readonly Diagnostic[], newLine: string): RealizedDiagnostic[] { + export function realizeDiagnostics(diagnostics: readonly ts.Diagnostic[], newLine: string): RealizedDiagnostic[] { return diagnostics.map(d => realizeDiagnostic(d, newLine)); } - function realizeDiagnostic(diagnostic: Diagnostic, newLine: string): RealizedDiagnostic { + function realizeDiagnostic(diagnostic: ts.Diagnostic, newLine: string): RealizedDiagnostic { return { - message: flattenDiagnosticMessageText(diagnostic.messageText, newLine), - start: diagnostic.start!, // TODO: GH#18217 - length: diagnostic.length!, // TODO: GH#18217 - category: diagnosticCategoryName(diagnostic), + message: ts.flattenDiagnosticMessageText(diagnostic.messageText, newLine), + start: diagnostic.start!, + length: diagnostic.length!, + category: ts.diagnosticCategoryName(diagnostic), code: diagnostic.code, reportsUnnecessary: diagnostic.reportsUnnecessary, reportsDeprecated: diagnostic.reportsDeprecated @@ -636,9 +623,7 @@ namespace ts { private logger: Logger; private logPerformance = false; - constructor(factory: ShimFactory, - private host: LanguageServiceShimHost, - public languageService: LanguageService) { + constructor(factory: ShimFactory, private host: LanguageServiceShimHost, public languageService: ts.LanguageService) { super(factory); this.logger = this.host; } @@ -675,71 +660,58 @@ namespace ts { * Update the list of scripts known to the compiler */ public refresh(throwOnError: boolean): void { - this.forwardJSONCall( - `refresh(${throwOnError})`, - () => null // eslint-disable-line no-null/no-null + this.forwardJSONCall(`refresh(${throwOnError})`, () => null // eslint-disable-line no-null/no-null ); } public cleanupSemanticCache(): void { - this.forwardJSONCall( - "cleanupSemanticCache()", - () => { + this.forwardJSONCall("cleanupSemanticCache()", () => { this.languageService.cleanupSemanticCache(); return null; // eslint-disable-line no-null/no-null }); } - private realizeDiagnostics(diagnostics: readonly Diagnostic[]): { message: string; start: number; length: number; category: string; }[] { - const newLine = getNewLineOrDefaultFromHost(this.host); + private realizeDiagnostics(diagnostics: readonly ts.Diagnostic[]): { + message: string; + start: number; + length: number; + category: string; + }[] { + const newLine = ts.getNewLineOrDefaultFromHost(this.host); return realizeDiagnostics(diagnostics, newLine); } public getSyntacticClassifications(fileName: string, start: number, length: number): string { - return this.forwardJSONCall( - `getSyntacticClassifications('${fileName}', ${start}, ${length})`, - () => this.languageService.getSyntacticClassifications(fileName, createTextSpan(start, length)) - ); + return this.forwardJSONCall(`getSyntacticClassifications('${fileName}', ${start}, ${length})`, () => this.languageService.getSyntacticClassifications(fileName, ts.createTextSpan(start, length))); } public getSemanticClassifications(fileName: string, start: number, length: number): string { - return this.forwardJSONCall( - `getSemanticClassifications('${fileName}', ${start}, ${length})`, - () => this.languageService.getSemanticClassifications(fileName, createTextSpan(start, length)) - ); + return this.forwardJSONCall(`getSemanticClassifications('${fileName}', ${start}, ${length})`, () => this.languageService.getSemanticClassifications(fileName, ts.createTextSpan(start, length))); } public getEncodedSyntacticClassifications(fileName: string, start: number, length: number): string { - return this.forwardJSONCall( - `getEncodedSyntacticClassifications('${fileName}', ${start}, ${length})`, + return this.forwardJSONCall(`getEncodedSyntacticClassifications('${fileName}', ${start}, ${length})`, // directly serialize the spans out to a string. This is much faster to decode // on the managed side versus a full JSON array. - () => convertClassifications(this.languageService.getEncodedSyntacticClassifications(fileName, createTextSpan(start, length))) - ); + () => convertClassifications(this.languageService.getEncodedSyntacticClassifications(fileName, ts.createTextSpan(start, length)))); } public getEncodedSemanticClassifications(fileName: string, start: number, length: number): string { - return this.forwardJSONCall( - `getEncodedSemanticClassifications('${fileName}', ${start}, ${length})`, + return this.forwardJSONCall(`getEncodedSemanticClassifications('${fileName}', ${start}, ${length})`, // directly serialize the spans out to a string. This is much faster to decode // on the managed side versus a full JSON array. - () => convertClassifications(this.languageService.getEncodedSemanticClassifications(fileName, createTextSpan(start, length))) - ); + () => convertClassifications(this.languageService.getEncodedSemanticClassifications(fileName, ts.createTextSpan(start, length)))); } public getSyntacticDiagnostics(fileName: string): string { - return this.forwardJSONCall( - `getSyntacticDiagnostics('${fileName}')`, - () => { + return this.forwardJSONCall(`getSyntacticDiagnostics('${fileName}')`, () => { const diagnostics = this.languageService.getSyntacticDiagnostics(fileName); return this.realizeDiagnostics(diagnostics); }); } public getSemanticDiagnostics(fileName: string): string { - return this.forwardJSONCall( - `getSemanticDiagnostics('${fileName}')`, - () => { + return this.forwardJSONCall(`getSemanticDiagnostics('${fileName}')`, () => { const diagnostics = this.languageService.getSemanticDiagnostics(fileName); return this.realizeDiagnostics(diagnostics); }); @@ -750,9 +722,7 @@ namespace ts { } public getCompilerOptionsDiagnostics(): string { - return this.forwardJSONCall( - "getCompilerOptionsDiagnostics()", - () => { + return this.forwardJSONCall("getCompilerOptionsDiagnostics()", () => { const diagnostics = this.languageService.getCompilerOptionsDiagnostics(); return this.realizeDiagnostics(diagnostics); }); @@ -765,10 +735,7 @@ namespace ts { * in the active file. */ public getQuickInfoAtPosition(fileName: string, position: number): string { - return this.forwardJSONCall( - `getQuickInfoAtPosition('${fileName}', ${position})`, - () => this.languageService.getQuickInfoAtPosition(fileName, position) - ); + return this.forwardJSONCall(`getQuickInfoAtPosition('${fileName}', ${position})`, () => this.languageService.getQuickInfoAtPosition(fileName, position)); } @@ -779,10 +746,7 @@ namespace ts { * in the active file. */ public getNameOrDottedNameSpan(fileName: string, startPos: number, endPos: number): string { - return this.forwardJSONCall( - `getNameOrDottedNameSpan('${fileName}', ${startPos}, ${endPos})`, - () => this.languageService.getNameOrDottedNameSpan(fileName, startPos, endPos) - ); + return this.forwardJSONCall(`getNameOrDottedNameSpan('${fileName}', ${startPos}, ${endPos})`, () => this.languageService.getNameOrDottedNameSpan(fileName, startPos, endPos)); } /** @@ -790,19 +754,13 @@ namespace ts { * Computes span information of statement at the requested position in the active file. */ public getBreakpointStatementAtPosition(fileName: string, position: number): string { - return this.forwardJSONCall( - `getBreakpointStatementAtPosition('${fileName}', ${position})`, - () => this.languageService.getBreakpointStatementAtPosition(fileName, position) - ); + return this.forwardJSONCall(`getBreakpointStatementAtPosition('${fileName}', ${position})`, () => this.languageService.getBreakpointStatementAtPosition(fileName, position)); } /// SIGNATUREHELP - public getSignatureHelpItems(fileName: string, position: number, options: SignatureHelpItemsOptions | undefined): string { - return this.forwardJSONCall( - `getSignatureHelpItems('${fileName}', ${position})`, - () => this.languageService.getSignatureHelpItems(fileName, position, options) - ); + public getSignatureHelpItems(fileName: string, position: number, options: ts.SignatureHelpItemsOptions | undefined): string { + return this.forwardJSONCall(`getSignatureHelpItems('${fileName}', ${position})`, () => this.languageService.getSignatureHelpItems(fileName, position, options)); } /// GOTO DEFINITION @@ -812,10 +770,7 @@ namespace ts { * at the requested position. */ public getDefinitionAtPosition(fileName: string, position: number): string { - return this.forwardJSONCall( - `getDefinitionAtPosition('${fileName}', ${position})`, - () => this.languageService.getDefinitionAtPosition(fileName, position) - ); + return this.forwardJSONCall(`getDefinitionAtPosition('${fileName}', ${position})`, () => this.languageService.getDefinitionAtPosition(fileName, position)); } /** @@ -823,10 +778,7 @@ namespace ts { * at the requested position. */ public getDefinitionAndBoundSpan(fileName: string, position: number): string { - return this.forwardJSONCall( - `getDefinitionAndBoundSpan('${fileName}', ${position})`, - () => this.languageService.getDefinitionAndBoundSpan(fileName, position) - ); + return this.forwardJSONCall(`getDefinitionAndBoundSpan('${fileName}', ${position})`, () => this.languageService.getDefinitionAndBoundSpan(fileName, position)); } /// GOTO Type @@ -836,10 +788,7 @@ namespace ts { * at the requested position. */ public getTypeDefinitionAtPosition(fileName: string, position: number): string { - return this.forwardJSONCall( - `getTypeDefinitionAtPosition('${fileName}', ${position})`, - () => this.languageService.getTypeDefinitionAtPosition(fileName, position) - ); + return this.forwardJSONCall(`getTypeDefinitionAtPosition('${fileName}', ${position})`, () => this.languageService.getTypeDefinitionAtPosition(fileName, position)); } /// GOTO Implementation @@ -849,61 +798,38 @@ namespace ts { * at the requested position. */ public getImplementationAtPosition(fileName: string, position: number): string { - return this.forwardJSONCall( - `getImplementationAtPosition('${fileName}', ${position})`, - () => this.languageService.getImplementationAtPosition(fileName, position) - ); + return this.forwardJSONCall(`getImplementationAtPosition('${fileName}', ${position})`, () => this.languageService.getImplementationAtPosition(fileName, position)); } - public getRenameInfo(fileName: string, position: number, options?: RenameInfoOptions): string { - return this.forwardJSONCall( - `getRenameInfo('${fileName}', ${position})`, - () => this.languageService.getRenameInfo(fileName, position, options) - ); + public getRenameInfo(fileName: string, position: number, options?: ts.RenameInfoOptions): string { + return this.forwardJSONCall(`getRenameInfo('${fileName}', ${position})`, () => this.languageService.getRenameInfo(fileName, position, options)); } public getSmartSelectionRange(fileName: string, position: number): string { - return this.forwardJSONCall( - `getSmartSelectionRange('${fileName}', ${position})`, - () => this.languageService.getSmartSelectionRange(fileName, position) - ); + return this.forwardJSONCall(`getSmartSelectionRange('${fileName}', ${position})`, () => this.languageService.getSmartSelectionRange(fileName, position)); } public findRenameLocations(fileName: string, position: number, findInStrings: boolean, findInComments: boolean, providePrefixAndSuffixTextForRename?: boolean): string { - return this.forwardJSONCall( - `findRenameLocations('${fileName}', ${position}, ${findInStrings}, ${findInComments}, ${providePrefixAndSuffixTextForRename})`, - () => this.languageService.findRenameLocations(fileName, position, findInStrings, findInComments, providePrefixAndSuffixTextForRename) - ); + return this.forwardJSONCall(`findRenameLocations('${fileName}', ${position}, ${findInStrings}, ${findInComments}, ${providePrefixAndSuffixTextForRename})`, () => this.languageService.findRenameLocations(fileName, position, findInStrings, findInComments, providePrefixAndSuffixTextForRename)); } /// GET BRACE MATCHING public getBraceMatchingAtPosition(fileName: string, position: number): string { - return this.forwardJSONCall( - `getBraceMatchingAtPosition('${fileName}', ${position})`, - () => this.languageService.getBraceMatchingAtPosition(fileName, position) - ); + return this.forwardJSONCall(`getBraceMatchingAtPosition('${fileName}', ${position})`, () => this.languageService.getBraceMatchingAtPosition(fileName, position)); } public isValidBraceCompletionAtPosition(fileName: string, position: number, openingBrace: number): string { - return this.forwardJSONCall( - `isValidBraceCompletionAtPosition('${fileName}', ${position}, ${openingBrace})`, - () => this.languageService.isValidBraceCompletionAtPosition(fileName, position, openingBrace) - ); + return this.forwardJSONCall(`isValidBraceCompletionAtPosition('${fileName}', ${position}, ${openingBrace})`, () => this.languageService.isValidBraceCompletionAtPosition(fileName, position, openingBrace)); } public getSpanOfEnclosingComment(fileName: string, position: number, onlyMultiLine: boolean): string { - return this.forwardJSONCall( - `getSpanOfEnclosingComment('${fileName}', ${position})`, - () => this.languageService.getSpanOfEnclosingComment(fileName, position, onlyMultiLine) - ); + return this.forwardJSONCall(`getSpanOfEnclosingComment('${fileName}', ${position})`, () => this.languageService.getSpanOfEnclosingComment(fileName, position, onlyMultiLine)); } /// GET SMART INDENT public getIndentationAtPosition(fileName: string, position: number, options: string /*Services.EditorOptions*/): string { - return this.forwardJSONCall( - `getIndentationAtPosition('${fileName}', ${position})`, - () => { - const localOptions: EditorOptions = JSON.parse(options); + return this.forwardJSONCall(`getIndentationAtPosition('${fileName}', ${position})`, () => { + const localOptions: ts.EditorOptions = JSON.parse(options); return this.languageService.getIndentationAtPosition(fileName, position, localOptions); }); } @@ -911,41 +837,27 @@ namespace ts { /// GET REFERENCES public getReferencesAtPosition(fileName: string, position: number): string { - return this.forwardJSONCall( - `getReferencesAtPosition('${fileName}', ${position})`, - () => this.languageService.getReferencesAtPosition(fileName, position) - ); + return this.forwardJSONCall(`getReferencesAtPosition('${fileName}', ${position})`, () => this.languageService.getReferencesAtPosition(fileName, position)); } public findReferences(fileName: string, position: number): string { - return this.forwardJSONCall( - `findReferences('${fileName}', ${position})`, - () => this.languageService.findReferences(fileName, position) - ); + return this.forwardJSONCall(`findReferences('${fileName}', ${position})`, () => this.languageService.findReferences(fileName, position)); } public getFileReferences(fileName: string) { - return this.forwardJSONCall( - `getFileReferences('${fileName})`, - () => this.languageService.getFileReferences(fileName) - ); + return this.forwardJSONCall(`getFileReferences('${fileName})`, () => this.languageService.getFileReferences(fileName)); } public getOccurrencesAtPosition(fileName: string, position: number): string { - return this.forwardJSONCall( - `getOccurrencesAtPosition('${fileName}', ${position})`, - () => this.languageService.getOccurrencesAtPosition(fileName, position) - ); + return this.forwardJSONCall(`getOccurrencesAtPosition('${fileName}', ${position})`, () => this.languageService.getOccurrencesAtPosition(fileName, position)); } public getDocumentHighlights(fileName: string, position: number, filesToSearch: string): string { - return this.forwardJSONCall( - `getDocumentHighlights('${fileName}', ${position})`, - () => { + return this.forwardJSONCall(`getDocumentHighlights('${fileName}', ${position})`, () => { const results = this.languageService.getDocumentHighlights(fileName, position, JSON.parse(filesToSearch)); // workaround for VS document highlighting issue - keep only items from the initial file - const normalizedName = toFileNameLowerCase(normalizeSlashes(fileName)); - return filter(results, r => toFileNameLowerCase(normalizeSlashes(r.fileName)) === normalizedName); + const normalizedName = ts.toFileNameLowerCase(ts.normalizeSlashes(fileName)); + return ts.filter(results, r => ts.toFileNameLowerCase(ts.normalizeSlashes(r.fileName)) === normalizedName); }); } @@ -956,196 +868,135 @@ namespace ts { * to provide at the given source position and providing a member completion * list if requested. */ - public getCompletionsAtPosition(fileName: string, position: number, preferences: GetCompletionsAtPositionOptions | undefined, formattingSettings: FormatCodeSettings | undefined) { - return this.forwardJSONCall( - `getCompletionsAtPosition('${fileName}', ${position}, ${preferences}, ${formattingSettings})`, - () => this.languageService.getCompletionsAtPosition(fileName, position, preferences, formattingSettings) - ); + public getCompletionsAtPosition(fileName: string, position: number, preferences: ts.GetCompletionsAtPositionOptions | undefined, formattingSettings: ts.FormatCodeSettings | undefined) { + return this.forwardJSONCall(`getCompletionsAtPosition('${fileName}', ${position}, ${preferences}, ${formattingSettings})`, () => this.languageService.getCompletionsAtPosition(fileName, position, preferences, formattingSettings)); } /** Get a string based representation of a completion list entry details */ - public getCompletionEntryDetails(fileName: string, position: number, entryName: string, formatOptions: string/*Services.FormatCodeOptions*/ | undefined, source: string | undefined, preferences: UserPreferences | undefined, data: CompletionEntryData | undefined) { - return this.forwardJSONCall( - `getCompletionEntryDetails('${fileName}', ${position}, '${entryName}')`, - () => { - const localOptions: FormatCodeOptions = formatOptions === undefined ? undefined : JSON.parse(formatOptions); + public getCompletionEntryDetails(fileName: string, position: number, entryName: string, formatOptions: string /*Services.FormatCodeOptions*/ | undefined, source: string | undefined, preferences: ts.UserPreferences | undefined, data: ts.CompletionEntryData | undefined) { + return this.forwardJSONCall(`getCompletionEntryDetails('${fileName}', ${position}, '${entryName}')`, () => { + const localOptions: ts.FormatCodeOptions = formatOptions === undefined ? undefined : JSON.parse(formatOptions); return this.languageService.getCompletionEntryDetails(fileName, position, entryName, localOptions, source, preferences, data); + }); } - ); - } public getFormattingEditsForRange(fileName: string, start: number, end: number, options: string/*Services.FormatCodeOptions*/): string { - return this.forwardJSONCall( - `getFormattingEditsForRange('${fileName}', ${start}, ${end})`, - () => { - const localOptions: FormatCodeOptions = JSON.parse(options); + return this.forwardJSONCall(`getFormattingEditsForRange('${fileName}', ${start}, ${end})`, () => { + const localOptions: ts.FormatCodeOptions = JSON.parse(options); return this.languageService.getFormattingEditsForRange(fileName, start, end, localOptions); }); } public getFormattingEditsForDocument(fileName: string, options: string/*Services.FormatCodeOptions*/): string { - return this.forwardJSONCall( - `getFormattingEditsForDocument('${fileName}')`, - () => { - const localOptions: FormatCodeOptions = JSON.parse(options); + return this.forwardJSONCall(`getFormattingEditsForDocument('${fileName}')`, () => { + const localOptions: ts.FormatCodeOptions = JSON.parse(options); return this.languageService.getFormattingEditsForDocument(fileName, localOptions); }); } public getFormattingEditsAfterKeystroke(fileName: string, position: number, key: string, options: string/*Services.FormatCodeOptions*/): string { - return this.forwardJSONCall( - `getFormattingEditsAfterKeystroke('${fileName}', ${position}, '${key}')`, - () => { - const localOptions: FormatCodeOptions = JSON.parse(options); + return this.forwardJSONCall(`getFormattingEditsAfterKeystroke('${fileName}', ${position}, '${key}')`, () => { + const localOptions: ts.FormatCodeOptions = JSON.parse(options); return this.languageService.getFormattingEditsAfterKeystroke(fileName, position, key, localOptions); }); } - public getDocCommentTemplateAtPosition(fileName: string, position: number, options?: DocCommentTemplateOptions): string { - return this.forwardJSONCall( - `getDocCommentTemplateAtPosition('${fileName}', ${position})`, - () => this.languageService.getDocCommentTemplateAtPosition(fileName, position, options) - ); + public getDocCommentTemplateAtPosition(fileName: string, position: number, options?: ts.DocCommentTemplateOptions): string { + return this.forwardJSONCall(`getDocCommentTemplateAtPosition('${fileName}', ${position})`, () => this.languageService.getDocCommentTemplateAtPosition(fileName, position, options)); } /// NAVIGATE TO /** Return a list of symbols that are interesting to navigate to */ public getNavigateToItems(searchValue: string, maxResultCount?: number, fileName?: string): string { - return this.forwardJSONCall( - `getNavigateToItems('${searchValue}', ${maxResultCount}, ${fileName})`, - () => this.languageService.getNavigateToItems(searchValue, maxResultCount, fileName) - ); + return this.forwardJSONCall(`getNavigateToItems('${searchValue}', ${maxResultCount}, ${fileName})`, () => this.languageService.getNavigateToItems(searchValue, maxResultCount, fileName)); } public getNavigationBarItems(fileName: string): string { - return this.forwardJSONCall( - `getNavigationBarItems('${fileName}')`, - () => this.languageService.getNavigationBarItems(fileName) - ); + return this.forwardJSONCall(`getNavigationBarItems('${fileName}')`, () => this.languageService.getNavigationBarItems(fileName)); } public getNavigationTree(fileName: string): string { - return this.forwardJSONCall( - `getNavigationTree('${fileName}')`, - () => this.languageService.getNavigationTree(fileName) - ); + return this.forwardJSONCall(`getNavigationTree('${fileName}')`, () => this.languageService.getNavigationTree(fileName)); } public getOutliningSpans(fileName: string): string { - return this.forwardJSONCall( - `getOutliningSpans('${fileName}')`, - () => this.languageService.getOutliningSpans(fileName) - ); + return this.forwardJSONCall(`getOutliningSpans('${fileName}')`, () => this.languageService.getOutliningSpans(fileName)); } public getTodoComments(fileName: string, descriptors: string): string { - return this.forwardJSONCall( - `getTodoComments('${fileName}')`, - () => this.languageService.getTodoComments(fileName, JSON.parse(descriptors)) - ); + return this.forwardJSONCall(`getTodoComments('${fileName}')`, () => this.languageService.getTodoComments(fileName, JSON.parse(descriptors))); } /// CALL HIERARCHY public prepareCallHierarchy(fileName: string, position: number): string { - return this.forwardJSONCall( - `prepareCallHierarchy('${fileName}', ${position})`, - () => this.languageService.prepareCallHierarchy(fileName, position) - ); + return this.forwardJSONCall(`prepareCallHierarchy('${fileName}', ${position})`, () => this.languageService.prepareCallHierarchy(fileName, position)); } public provideCallHierarchyIncomingCalls(fileName: string, position: number): string { - return this.forwardJSONCall( - `provideCallHierarchyIncomingCalls('${fileName}', ${position})`, - () => this.languageService.provideCallHierarchyIncomingCalls(fileName, position) - ); + return this.forwardJSONCall(`provideCallHierarchyIncomingCalls('${fileName}', ${position})`, () => this.languageService.provideCallHierarchyIncomingCalls(fileName, position)); } public provideCallHierarchyOutgoingCalls(fileName: string, position: number): string { - return this.forwardJSONCall( - `provideCallHierarchyOutgoingCalls('${fileName}', ${position})`, - () => this.languageService.provideCallHierarchyOutgoingCalls(fileName, position) - ); + return this.forwardJSONCall(`provideCallHierarchyOutgoingCalls('${fileName}', ${position})`, () => this.languageService.provideCallHierarchyOutgoingCalls(fileName, position)); } - public provideInlayHints(fileName: string, span: TextSpan, preference: UserPreferences | undefined): string { - return this.forwardJSONCall( - `provideInlayHints('${fileName}', '${JSON.stringify(span)}', ${JSON.stringify(preference)})`, - () => this.languageService.provideInlayHints(fileName, span, preference) - ); + public provideInlayHints(fileName: string, span: ts.TextSpan, preference: ts.UserPreferences | undefined): string { + return this.forwardJSONCall(`provideInlayHints('${fileName}', '${JSON.stringify(span)}', ${JSON.stringify(preference)})`, () => this.languageService.provideInlayHints(fileName, span, preference)); } /// Emit public getEmitOutput(fileName: string): string { - return this.forwardJSONCall( - `getEmitOutput('${fileName}')`, - () => { + return this.forwardJSONCall(`getEmitOutput('${fileName}')`, () => { const { diagnostics, ...rest } = this.languageService.getEmitOutput(fileName); return { ...rest, diagnostics: this.realizeDiagnostics(diagnostics) }; + }); } - ); - } - - public getEmitOutputObject(fileName: string): EmitOutput { - return forwardCall( - this.logger, - `getEmitOutput('${fileName}')`, - /*returnJson*/ false, - () => this.languageService.getEmitOutput(fileName), - this.logPerformance) as EmitOutput; + public getEmitOutputObject(fileName: string): ts.EmitOutput { + return forwardCall(this.logger, `getEmitOutput('${fileName}')`, + /*returnJson*/ false, () => this.languageService.getEmitOutput(fileName), this.logPerformance) as ts.EmitOutput; } - public toggleLineComment(fileName: string, textRange: TextRange): string { - return this.forwardJSONCall( - `toggleLineComment('${fileName}', '${JSON.stringify(textRange)}')`, - () => this.languageService.toggleLineComment(fileName, textRange) - ); + public toggleLineComment(fileName: string, textRange: ts.TextRange): string { + return this.forwardJSONCall(`toggleLineComment('${fileName}', '${JSON.stringify(textRange)}')`, () => this.languageService.toggleLineComment(fileName, textRange)); } - public toggleMultilineComment(fileName: string, textRange: TextRange): string { - return this.forwardJSONCall( - `toggleMultilineComment('${fileName}', '${JSON.stringify(textRange)}')`, - () => this.languageService.toggleMultilineComment(fileName, textRange) - ); + public toggleMultilineComment(fileName: string, textRange: ts.TextRange): string { + return this.forwardJSONCall(`toggleMultilineComment('${fileName}', '${JSON.stringify(textRange)}')`, () => this.languageService.toggleMultilineComment(fileName, textRange)); } - public commentSelection(fileName: string, textRange: TextRange): string { - return this.forwardJSONCall( - `commentSelection('${fileName}', '${JSON.stringify(textRange)}')`, - () => this.languageService.commentSelection(fileName, textRange) - ); + public commentSelection(fileName: string, textRange: ts.TextRange): string { + return this.forwardJSONCall(`commentSelection('${fileName}', '${JSON.stringify(textRange)}')`, () => this.languageService.commentSelection(fileName, textRange)); } - public uncommentSelection(fileName: string, textRange: TextRange): string { - return this.forwardJSONCall( - `uncommentSelection('${fileName}', '${JSON.stringify(textRange)}')`, - () => this.languageService.uncommentSelection(fileName, textRange) - ); + public uncommentSelection(fileName: string, textRange: ts.TextRange): string { + return this.forwardJSONCall(`uncommentSelection('${fileName}', '${JSON.stringify(textRange)}')`, () => this.languageService.uncommentSelection(fileName, textRange)); } } - function convertClassifications(classifications: Classifications): { spans: string, endOfLineState: EndOfLineState } { + function convertClassifications(classifications: ts.Classifications): { + spans: string; + endOfLineState: ts.EndOfLineState; + } { return { spans: classifications.spans.join(","), endOfLineState: classifications.endOfLineState }; } class ClassifierShimObject extends ShimBase implements ClassifierShim { - public classifier: Classifier; + public classifier: ts.Classifier; private logPerformance = false; constructor(factory: ShimFactory, private logger: Logger) { super(factory); - this.classifier = createClassifier(); + this.classifier = ts.createClassifier(); } - public getEncodedLexicalClassifications(text: string, lexState: EndOfLineState, syntacticClassifierAbsent = false): string { - return forwardJSONCall(this.logger, "getEncodedLexicalClassifications", - () => convertClassifications(this.classifier.getEncodedLexicalClassifications(text, lexState, syntacticClassifierAbsent)), - this.logPerformance); + public getEncodedLexicalClassifications(text: string, lexState: ts.EndOfLineState, syntacticClassifierAbsent = false): string { + return forwardJSONCall(this.logger, "getEncodedLexicalClassifications", () => convertClassifications(this.classifier.getEncodedLexicalClassifications(text, lexState, syntacticClassifierAbsent)), this.logPerformance); } /// COLORIZATION - public getClassificationsForLine(text: string, lexState: EndOfLineState, classifyKeywordsInGenerics = false): string { + public getClassificationsForLine(text: string, lexState: ts.EndOfLineState, classifyKeywordsInGenerics = false): string { const classification = this.classifier.getClassificationsForLine(text, lexState, classifyKeywordsInGenerics); let result = ""; for (const item of classification.entries) { @@ -1159,7 +1010,7 @@ namespace ts { class CoreServicesShimObject extends ShimBase implements CoreServicesShim { private logPerformance = false; - private safeList: JsTyping.SafeList | undefined; + private safeList: ts.JsTyping.SafeList | undefined; constructor(factory: ShimFactory, public readonly logger: Logger, private readonly host: CoreServicesShimHostAdapter) { super(factory); @@ -1171,10 +1022,10 @@ namespace ts { public resolveModuleName(fileName: string, moduleName: string, compilerOptionsJson: string): string { return this.forwardJSONCall(`resolveModuleName('${fileName}')`, () => { - const compilerOptions = JSON.parse(compilerOptionsJson) as CompilerOptions; - const result = resolveModuleName(moduleName, normalizeSlashes(fileName), compilerOptions, this.host); + const compilerOptions = JSON.parse(compilerOptionsJson) as ts.CompilerOptions; + const result = ts.resolveModuleName(moduleName, ts.normalizeSlashes(fileName), compilerOptions, this.host); let resolvedFileName = result.resolvedModule ? result.resolvedModule.resolvedFileName : undefined; - if (result.resolvedModule && result.resolvedModule.extension !== Extension.Ts && result.resolvedModule.extension !== Extension.Tsx && result.resolvedModule.extension !== Extension.Dts) { + if (result.resolvedModule && result.resolvedModule.extension !== ts.Extension.Ts && result.resolvedModule.extension !== ts.Extension.Tsx && result.resolvedModule.extension !== ts.Extension.Dts) { resolvedFileName = undefined; } @@ -1187,8 +1038,8 @@ namespace ts { public resolveTypeReferenceDirective(fileName: string, typeReferenceDirective: string, compilerOptionsJson: string): string { return this.forwardJSONCall(`resolveTypeReferenceDirective(${fileName})`, () => { - const compilerOptions = JSON.parse(compilerOptionsJson) as CompilerOptions; - const result = resolveTypeReferenceDirective(typeReferenceDirective, normalizeSlashes(fileName), compilerOptions, this.host); + const compilerOptions = JSON.parse(compilerOptionsJson) as ts.CompilerOptions; + const result = ts.resolveTypeReferenceDirective(typeReferenceDirective, ts.normalizeSlashes(fileName), compilerOptions, this.host); return { resolvedFileName: result.resolvedTypeReferenceDirective ? result.resolvedTypeReferenceDirective.resolvedFileName : undefined, primary: result.resolvedTypeReferenceDirective ? result.resolvedTypeReferenceDirective.primary : true, @@ -1197,12 +1048,10 @@ namespace ts { }); } - public getPreProcessedFileInfo(fileName: string, sourceTextSnapshot: IScriptSnapshot): string { - return this.forwardJSONCall( - `getPreProcessedFileInfo('${fileName}')`, - () => { + public getPreProcessedFileInfo(fileName: string, sourceTextSnapshot: ts.IScriptSnapshot): string { + return this.forwardJSONCall(`getPreProcessedFileInfo('${fileName}')`, () => { // for now treat files as JavaScript - const result = preProcessFile(getSnapshotText(sourceTextSnapshot), /* readImportFiles */ true, /* detectJavaScriptImports */ true); + const result = ts.preProcessFile(ts.getSnapshotText(sourceTextSnapshot), /* readImportFiles */ true, /* detectJavaScriptImports */ true); return { referencedFiles: this.convertFileReferences(result.referencedFiles), importedFiles: this.convertFileReferences(result.importedFiles), @@ -1215,23 +1064,20 @@ namespace ts { } public getAutomaticTypeDirectiveNames(compilerOptionsJson: string): string { - return this.forwardJSONCall( - `getAutomaticTypeDirectiveNames('${compilerOptionsJson}')`, - () => { - const compilerOptions = JSON.parse(compilerOptionsJson) as CompilerOptions; - return getAutomaticTypeDirectiveNames(compilerOptions, this.host); - } - ); + return this.forwardJSONCall(`getAutomaticTypeDirectiveNames('${compilerOptionsJson}')`, () => { + const compilerOptions = JSON.parse(compilerOptionsJson) as ts.CompilerOptions; + return ts.getAutomaticTypeDirectiveNames(compilerOptions, this.host); + }); } - private convertFileReferences(refs: FileReference[]): ShimsFileReference[] | undefined { + private convertFileReferences(refs: ts.FileReference[]): ShimsFileReference[] | undefined { if (!refs) { return undefined; } const result: ShimsFileReference[] = []; for (const ref of refs) { result.push({ - path: normalizeSlashes(ref.fileName), + path: ts.normalizeSlashes(ref.fileName), position: ref.pos, length: ref.end - ref.pos }); @@ -1239,13 +1085,11 @@ namespace ts { return result; } - public getTSConfigFileInfo(fileName: string, sourceTextSnapshot: IScriptSnapshot): string { - return this.forwardJSONCall( - `getTSConfigFileInfo('${fileName}')`, - () => { - const result = parseJsonText(fileName, getSnapshotText(sourceTextSnapshot)); - const normalizedFileName = normalizeSlashes(fileName); - const configFile = parseJsonSourceFileConfigFileContent(result, this.host, getDirectoryPath(normalizedFileName), /*existingOptions*/ {}, normalizedFileName); + public getTSConfigFileInfo(fileName: string, sourceTextSnapshot: ts.IScriptSnapshot): string { + return this.forwardJSONCall(`getTSConfigFileInfo('${fileName}')`, () => { + const result = ts.parseJsonText(fileName, ts.getSnapshotText(sourceTextSnapshot)); + const normalizedFileName = ts.normalizeSlashes(fileName); + const configFile = ts.parseJsonSourceFileConfigFileContent(result, this.host, ts.getDirectoryPath(normalizedFileName), /*existingOptions*/ {}, normalizedFileName); return { options: configFile.options, @@ -1258,51 +1102,39 @@ namespace ts { } public getDefaultCompilationSettings(): string { - return this.forwardJSONCall( - "getDefaultCompilationSettings()", - () => getDefaultCompilerOptions() - ); + return this.forwardJSONCall("getDefaultCompilationSettings()", () => ts.getDefaultCompilerOptions()); } public discoverTypings(discoverTypingsJson: string): string { - const getCanonicalFileName = createGetCanonicalFileName(/*useCaseSensitivefileNames:*/ false); + const getCanonicalFileName = ts.createGetCanonicalFileName(/*useCaseSensitivefileNames:*/ false); return this.forwardJSONCall("discoverTypings()", () => { const info = JSON.parse(discoverTypingsJson) as DiscoverTypingsInfo; if (this.safeList === undefined) { - this.safeList = JsTyping.loadSafeList(this.host, toPath(info.safeListPath, info.safeListPath, getCanonicalFileName)); + this.safeList = ts.JsTyping.loadSafeList(this.host, ts.toPath(info.safeListPath, info.safeListPath, getCanonicalFileName)); } - return JsTyping.discoverTypings( - this.host, - msg => this.logger.log(msg), - info.fileNames, - toPath(info.projectRootPath, info.projectRootPath, getCanonicalFileName), - this.safeList, - info.packageNameToTypingLocation, - info.typeAcquisition, - info.unresolvedImports, - info.typesRegistry); + return ts.JsTyping.discoverTypings(this.host, msg => this.logger.log(msg), info.fileNames, ts.toPath(info.projectRootPath, info.projectRootPath, getCanonicalFileName), this.safeList, info.packageNameToTypingLocation, info.typeAcquisition, info.unresolvedImports, info.typesRegistry); }); } } export class TypeScriptServicesFactory implements ShimFactory { private _shims: Shim[] = []; - private documentRegistry: DocumentRegistry | undefined; + private documentRegistry: ts.DocumentRegistry | undefined; /* * Returns script API version. */ public getServicesVersion(): string { - return servicesVersion; + return ts.servicesVersion; } public createLanguageServiceShim(host: LanguageServiceShimHost): LanguageServiceShim { try { if (this.documentRegistry === undefined) { - this.documentRegistry = createDocumentRegistry(host.useCaseSensitiveFileNames && host.useCaseSensitiveFileNames(), host.getCurrentDirectory()); + this.documentRegistry = ts.createDocumentRegistry(host.useCaseSensitiveFileNames && host.useCaseSensitiveFileNames(), host.getCurrentDirectory()); } const hostAdapter = new LanguageServiceShimHostAdapter(host); - const languageService = createLanguageService(hostAdapter, this.documentRegistry, /*syntaxOnly*/ false); + const languageService = ts.createLanguageService(hostAdapter, this.documentRegistry, /*syntaxOnly*/ false); return new LanguageServiceShimObject(this, host, languageService); } catch (err) { @@ -1334,7 +1166,7 @@ namespace ts { public close(): void { // Forget all the registered shims - clear(this._shims); + ts.clear(this._shims); this.documentRegistry = undefined; } diff --git a/src/services/signatureHelp.ts b/src/services/signatureHelp.ts index eefc1c44e9c51..a3bd2c22634c9 100644 --- a/src/services/signatureHelp.ts +++ b/src/services/signatureHelp.ts @@ -1,30 +1,40 @@ /* @internal */ namespace ts.SignatureHelp { - const enum InvocationKind { Call, TypeArgs, Contextual } - interface CallInvocation { readonly kind: InvocationKind.Call; readonly node: CallLikeExpression; } - interface TypeArgsInvocation { readonly kind: InvocationKind.TypeArgs; readonly called: Identifier; } + const enum InvocationKind { + Call, + TypeArgs, + Contextual + } + interface CallInvocation { + readonly kind: InvocationKind.Call; + readonly node: ts.CallLikeExpression; + } + interface TypeArgsInvocation { + readonly kind: InvocationKind.TypeArgs; + readonly called: ts.Identifier; + } interface ContextualInvocation { readonly kind: InvocationKind.Contextual; - readonly signature: Signature; - readonly node: Node; // Just for enclosingDeclaration for printing types - readonly symbol: Symbol; + readonly signature: ts.Signature; + readonly node: ts.Node; // Just for enclosingDeclaration for printing types + readonly symbol: ts.Symbol; } type Invocation = CallInvocation | TypeArgsInvocation | ContextualInvocation; interface ArgumentListInfo { readonly isTypeParameterList: boolean; readonly invocation: Invocation; - readonly argumentsSpan: TextSpan; + readonly argumentsSpan: ts.TextSpan; readonly argumentIndex: number; /** argumentCount is the *apparent* number of arguments. */ readonly argumentCount: number; } - export function getSignatureHelpItems(program: Program, sourceFile: SourceFile, position: number, triggerReason: SignatureHelpTriggerReason | undefined, cancellationToken: CancellationToken): SignatureHelpItems | undefined { + export function getSignatureHelpItems(program: ts.Program, sourceFile: ts.SourceFile, position: number, triggerReason: ts.SignatureHelpTriggerReason | undefined, cancellationToken: ts.CancellationToken): ts.SignatureHelpItems | undefined { const typeChecker = program.getTypeChecker(); // Decide whether to show signature help - const startingToken = findTokenOnLeftOfPosition(sourceFile, position); + const startingToken = ts.findTokenOnLeftOfPosition(sourceFile, position); if (!startingToken) { // We are at the beginning of the file return undefined; @@ -34,13 +44,14 @@ namespace ts.SignatureHelp { const onlyUseSyntacticOwners = !!triggerReason && triggerReason.kind === "characterTyped"; // Bail out quickly in the middle of a string or comment, don't provide signature help unless the user explicitly requested it. - if (onlyUseSyntacticOwners && (isInString(sourceFile, position, startingToken) || isInComment(sourceFile, position))) { + if (onlyUseSyntacticOwners && (ts.isInString(sourceFile, position, startingToken) || ts.isInComment(sourceFile, position))) { return undefined; } const isManuallyInvoked = !!triggerReason && triggerReason.kind === "invoked"; const argumentInfo = getContainingArgumentInfo(startingToken, position, sourceFile, typeChecker, isManuallyInvoked); - if (!argumentInfo) return undefined; + if (!argumentInfo) + return undefined; cancellationToken.throwIfCancellationRequested(); @@ -51,43 +62,46 @@ namespace ts.SignatureHelp { if (!candidateInfo) { // We didn't have any sig help items produced by the TS compiler. If this is a JS // file, then see if we can figure out anything better. - return isSourceFileJS(sourceFile) ? createJSSignatureHelpItems(argumentInfo, program, cancellationToken) : undefined; + return ts.isSourceFileJS(sourceFile) ? createJSSignatureHelpItems(argumentInfo, program, cancellationToken) : undefined; } - return typeChecker.runWithCancellationToken(cancellationToken, typeChecker => - candidateInfo.kind === CandidateOrTypeKind.Candidate + return typeChecker.runWithCancellationToken(cancellationToken, typeChecker => candidateInfo.kind === CandidateOrTypeKind.Candidate ? createSignatureHelpItems(candidateInfo.candidates, candidateInfo.resolvedSignature, argumentInfo, sourceFile, typeChecker) : createTypeHelpItems(candidateInfo.symbol, argumentInfo, sourceFile, typeChecker)); } - const enum CandidateOrTypeKind { Candidate, Type } + const enum CandidateOrTypeKind { + Candidate, + Type + } interface CandidateInfo { readonly kind: CandidateOrTypeKind.Candidate; - readonly candidates: readonly Signature[]; - readonly resolvedSignature: Signature; + readonly candidates: readonly ts.Signature[]; + readonly resolvedSignature: ts.Signature; } interface TypeInfo { readonly kind: CandidateOrTypeKind.Type; - readonly symbol: Symbol; + readonly symbol: ts.Symbol; } - function getCandidateOrTypeInfo({ invocation, argumentCount }: ArgumentListInfo, checker: TypeChecker, sourceFile: SourceFile, startingToken: Node, onlyUseSyntacticOwners: boolean): CandidateInfo | TypeInfo | undefined { + function getCandidateOrTypeInfo({ invocation, argumentCount }: ArgumentListInfo, checker: ts.TypeChecker, sourceFile: ts.SourceFile, startingToken: ts.Node, onlyUseSyntacticOwners: boolean): CandidateInfo | TypeInfo | undefined { switch (invocation.kind) { case InvocationKind.Call: { if (onlyUseSyntacticOwners && !isSyntacticOwner(startingToken, invocation.node, sourceFile)) { return undefined; } - const candidates: Signature[] = []; + const candidates: ts.Signature[] = []; const resolvedSignature = checker.getResolvedSignatureForSignatureHelp(invocation.node, candidates, argumentCount)!; // TODO: GH#18217 return candidates.length === 0 ? undefined : { kind: CandidateOrTypeKind.Candidate, candidates, resolvedSignature }; } case InvocationKind.TypeArgs: { const { called } = invocation; - if (onlyUseSyntacticOwners && !containsPrecedingToken(startingToken, sourceFile, isIdentifier(called) ? called.parent : called)) { + if (onlyUseSyntacticOwners && !containsPrecedingToken(startingToken, sourceFile, ts.isIdentifier(called) ? called.parent : called)) { return undefined; } - const candidates = getPossibleGenericSignatures(called, argumentCount, checker); - if (candidates.length !== 0) return { kind: CandidateOrTypeKind.Candidate, candidates, resolvedSignature: first(candidates) }; + const candidates = ts.getPossibleGenericSignatures(called, argumentCount, checker); + if (candidates.length !== 0) + return { kind: CandidateOrTypeKind.Candidate, candidates, resolvedSignature: ts.first(candidates) }; const symbol = checker.getSymbolAtLocation(called); return symbol && { kind: CandidateOrTypeKind.Type, symbol }; @@ -95,94 +109,97 @@ namespace ts.SignatureHelp { case InvocationKind.Contextual: return { kind: CandidateOrTypeKind.Candidate, candidates: [invocation.signature], resolvedSignature: invocation.signature }; default: - return Debug.assertNever(invocation); + return ts.Debug.assertNever(invocation); } } - function isSyntacticOwner(startingToken: Node, node: CallLikeExpression, sourceFile: SourceFile): boolean { - if (!isCallOrNewExpression(node)) return false; + function isSyntacticOwner(startingToken: ts.Node, node: ts.CallLikeExpression, sourceFile: ts.SourceFile): boolean { + if (!ts.isCallOrNewExpression(node)) + return false; const invocationChildren = node.getChildren(sourceFile); switch (startingToken.kind) { - case SyntaxKind.OpenParenToken: - return contains(invocationChildren, startingToken); - case SyntaxKind.CommaToken: { - const containingList = findContainingList(startingToken); - return !!containingList && contains(invocationChildren, containingList); + case ts.SyntaxKind.OpenParenToken: + return ts.contains(invocationChildren, startingToken); + case ts.SyntaxKind.CommaToken: { + const containingList = ts.findContainingList(startingToken); + return !!containingList && ts.contains(invocationChildren, containingList); } - case SyntaxKind.LessThanToken: + case ts.SyntaxKind.LessThanToken: return containsPrecedingToken(startingToken, sourceFile, node.expression); default: return false; } } - function createJSSignatureHelpItems(argumentInfo: ArgumentListInfo, program: Program, cancellationToken: CancellationToken): SignatureHelpItems | undefined { - if (argumentInfo.invocation.kind === InvocationKind.Contextual) return undefined; + function createJSSignatureHelpItems(argumentInfo: ArgumentListInfo, program: ts.Program, cancellationToken: ts.CancellationToken): ts.SignatureHelpItems | undefined { + if (argumentInfo.invocation.kind === InvocationKind.Contextual) + return undefined; // See if we can find some symbol with the call expression name that has call signatures. const expression = getExpressionFromInvocation(argumentInfo.invocation); - const name = isPropertyAccessExpression(expression) ? expression.name.text : undefined; + const name = ts.isPropertyAccessExpression(expression) ? expression.name.text : undefined; const typeChecker = program.getTypeChecker(); - return name === undefined ? undefined : firstDefined(program.getSourceFiles(), sourceFile => - firstDefined(sourceFile.getNamedDeclarations().get(name), declaration => { + return name === undefined ? undefined : ts.firstDefined(program.getSourceFiles(), sourceFile => ts.firstDefined(sourceFile.getNamedDeclarations().get(name), declaration => { const type = declaration.symbol && typeChecker.getTypeOfSymbolAtLocation(declaration.symbol, declaration); const callSignatures = type && type.getCallSignatures(); if (callSignatures && callSignatures.length) { - return typeChecker.runWithCancellationToken( - cancellationToken, - typeChecker => createSignatureHelpItems( - callSignatures, - callSignatures[0], - argumentInfo, - sourceFile, - typeChecker, + return typeChecker.runWithCancellationToken(cancellationToken, typeChecker => createSignatureHelpItems(callSignatures, callSignatures[0], argumentInfo, sourceFile, typeChecker, /*useFullPrefix*/ true)); } })); } - function containsPrecedingToken(startingToken: Node, sourceFile: SourceFile, container: Node) { + function containsPrecedingToken(startingToken: ts.Node, sourceFile: ts.SourceFile, container: ts.Node) { const pos = startingToken.getFullStart(); // There’s a possibility that `startingToken.parent` contains only `startingToken` and // missing nodes, none of which are valid to be returned by `findPrecedingToken`. In that // case, the preceding token we want is actually higher up the tree—almost definitely the // next parent, but theoretically the situation with missing nodes might be happening on // multiple nested levels. - let currentParent: Node | undefined = startingToken.parent; + let currentParent: ts.Node | undefined = startingToken.parent; while (currentParent) { - const precedingToken = findPrecedingToken(pos, sourceFile, currentParent, /*excludeJsdoc*/ true); + const precedingToken = ts.findPrecedingToken(pos, sourceFile, currentParent, /*excludeJsdoc*/ true); if (precedingToken) { - return rangeContainsRange(container, precedingToken); + return ts.rangeContainsRange(container, precedingToken); } currentParent = currentParent.parent; } - return Debug.fail("Could not find preceding token"); + return ts.Debug.fail("Could not find preceding token"); } export interface ArgumentInfoForCompletions { - readonly invocation: CallLikeExpression; + readonly invocation: ts.CallLikeExpression; readonly argumentIndex: number; readonly argumentCount: number; } - export function getArgumentInfoForCompletions(node: Node, position: number, sourceFile: SourceFile): ArgumentInfoForCompletions | undefined { + export function getArgumentInfoForCompletions(node: ts.Node, position: number, sourceFile: ts.SourceFile): ArgumentInfoForCompletions | undefined { const info = getImmediatelyContainingArgumentInfo(node, position, sourceFile); return !info || info.isTypeParameterList || info.invocation.kind !== InvocationKind.Call ? undefined : { invocation: info.invocation.node, argumentCount: info.argumentCount, argumentIndex: info.argumentIndex }; } - function getArgumentOrParameterListInfo(node: Node, position: number, sourceFile: SourceFile): { readonly list: Node, readonly argumentIndex: number, readonly argumentCount: number, readonly argumentsSpan: TextSpan } | undefined { + function getArgumentOrParameterListInfo(node: ts.Node, position: number, sourceFile: ts.SourceFile): { + readonly list: ts.Node; + readonly argumentIndex: number; + readonly argumentCount: number; + readonly argumentsSpan: ts.TextSpan; + } | undefined { const info = getArgumentOrParameterListAndIndex(node, sourceFile); - if (!info) return undefined; + if (!info) + return undefined; const { list, argumentIndex } = info; - const argumentCount = getArgumentCount(list, /*ignoreTrailingComma*/ isInString(sourceFile, position, node)); + const argumentCount = getArgumentCount(list, /*ignoreTrailingComma*/ ts.isInString(sourceFile, position, node)); if (argumentIndex !== 0) { - Debug.assertLessThan(argumentIndex, argumentCount); + ts.Debug.assertLessThan(argumentIndex, argumentCount); } const argumentsSpan = getApplicableSpanForArguments(list, sourceFile); return { list, argumentIndex, argumentCount, argumentsSpan }; } - function getArgumentOrParameterListAndIndex(node: Node, sourceFile: SourceFile): { readonly list: Node, readonly argumentIndex: number } | undefined { - if (node.kind === SyntaxKind.LessThanToken || node.kind === SyntaxKind.OpenParenToken) { + function getArgumentOrParameterListAndIndex(node: ts.Node, sourceFile: ts.SourceFile): { + readonly list: ts.Node; + readonly argumentIndex: number; + } | undefined { + if (node.kind === ts.SyntaxKind.LessThanToken || node.kind === ts.SyntaxKind.OpenParenToken) { // Find the list that starts right *after* the < or ( token. // If the user has just opened a list, consider this item 0. return { list: getChildListThatStartsWithOpenerToken(node.parent, node, sourceFile), argumentIndex: 0 }; @@ -194,7 +211,7 @@ namespace ts.SignatureHelp { // - Between the type arguments and the arguments (greater than token) // - On the target of the call (parent.func) // - On the 'new' keyword in a 'new' expression - const list = findContainingList(node); + const list = ts.findContainingList(node); return list && { list, argumentIndex: getArgumentIndex(list, node) }; } } @@ -203,9 +220,9 @@ namespace ts.SignatureHelp { * Returns relevant information for the argument list and the current argument if we are * in the argument of an invocation; returns undefined otherwise. */ - function getImmediatelyContainingArgumentInfo(node: Node, position: number, sourceFile: SourceFile): ArgumentListInfo | undefined { + function getImmediatelyContainingArgumentInfo(node: ts.Node, position: number, sourceFile: ts.SourceFile): ArgumentListInfo | undefined { const { parent } = node; - if (isCallOrNewExpression(parent)) { + if (ts.isCallOrNewExpression(parent)) { const invocation = parent; // There are 3 cases to handle: @@ -223,34 +240,34 @@ namespace ts.SignatureHelp { // foo(a#, #b#) -> The token is buried inside a list, and should give signature help // Find out if 'node' is an argument, a type argument, or neither const info = getArgumentOrParameterListInfo(node, position, sourceFile); - if (!info) return undefined; + if (!info) + return undefined; const { list, argumentIndex, argumentCount, argumentsSpan } = info; const isTypeParameterList = !!parent.typeArguments && parent.typeArguments.pos === list.pos; return { isTypeParameterList, invocation: { kind: InvocationKind.Call, node: invocation }, argumentsSpan, argumentIndex, argumentCount }; } - else if (isNoSubstitutionTemplateLiteral(node) && isTaggedTemplateExpression(parent)) { + else if (ts.isNoSubstitutionTemplateLiteral(node) && ts.isTaggedTemplateExpression(parent)) { // Check if we're actually inside the template; // otherwise we'll fall out and return undefined. - if (isInsideTemplateLiteral(node, position, sourceFile)) { + if (ts.isInsideTemplateLiteral(node, position, sourceFile)) { return getArgumentListInfoForTemplate(parent, /*argumentIndex*/ 0, sourceFile); } return undefined; } - else if (isTemplateHead(node) && parent.parent.kind === SyntaxKind.TaggedTemplateExpression) { - const templateExpression = parent as TemplateExpression; - const tagExpression = templateExpression.parent as TaggedTemplateExpression; - Debug.assert(templateExpression.kind === SyntaxKind.TemplateExpression); - - const argumentIndex = isInsideTemplateLiteral(node, position, sourceFile) ? 0 : 1; + else if (ts.isTemplateHead(node) && parent.parent.kind === ts.SyntaxKind.TaggedTemplateExpression) { + const templateExpression = parent as ts.TemplateExpression; + const tagExpression = templateExpression.parent as ts.TaggedTemplateExpression; + ts.Debug.assert(templateExpression.kind === ts.SyntaxKind.TemplateExpression); + const argumentIndex = ts.isInsideTemplateLiteral(node, position, sourceFile) ? 0 : 1; return getArgumentListInfoForTemplate(tagExpression, argumentIndex, sourceFile); } - else if (isTemplateSpan(parent) && isTaggedTemplateExpression(parent.parent.parent)) { + else if (ts.isTemplateSpan(parent) && ts.isTaggedTemplateExpression(parent.parent.parent)) { const templateSpan = parent; const tagExpression = parent.parent.parent; // If we're just after a template tail, don't show signature help. - if (isTemplateTail(node) && !isInsideTemplateLiteral(node, position, sourceFile)) { + if (ts.isTemplateTail(node) && !ts.isInsideTemplateLiteral(node, position, sourceFile)) { return undefined; } @@ -259,84 +276,93 @@ namespace ts.SignatureHelp { return getArgumentListInfoForTemplate(tagExpression, argumentIndex, sourceFile); } - else if (isJsxOpeningLikeElement(parent)) { + else if (ts.isJsxOpeningLikeElement(parent)) { // Provide a signature help for JSX opening element or JSX self-closing element. // This is not guarantee that JSX tag-name is resolved into stateless function component. (that is done in "getSignatureHelpItems") // i.e // export function MainButton(props: ButtonProps, context: any): JSX.Element { ... } // isFunctionTypeNode(d) ? d.parent.symbol : undefined) || s + function chooseBetterSymbol(s: ts.Symbol): ts.Symbol { + return s.name === ts.InternalSymbolName.Type + ? ts.firstDefined(s.declarations, d => ts.isFunctionTypeNode(d) ? d.parent.symbol : undefined) || s : s; } - function getArgumentIndex(argumentsList: Node, node: Node) { + function getArgumentIndex(argumentsList: ts.Node, node: ts.Node) { // The list we got back can include commas. In the presence of errors it may // also just have nodes without commas. For example "Foo(a b c)" will have 3 // args without commas. We want to find what index we're at. So we count @@ -367,7 +393,7 @@ namespace ts.SignatureHelp { if (child === node) { break; } - if (child.kind !== SyntaxKind.CommaToken) { + if (child.kind !== ts.SyntaxKind.CommaToken) { argumentIndex++; } } @@ -375,7 +401,7 @@ namespace ts.SignatureHelp { return argumentIndex; } - function getArgumentCount(argumentsList: Node, ignoreTrailingComma: boolean) { + function getArgumentCount(argumentsList: ts.Node, ignoreTrailingComma: boolean) { // The argument count for a list is normally the number of non-comma children it has. // For example, if you have "Foo(a,b)" then there will be three children of the arg // list 'a' '' 'b'. So, in this case the arg count will be 2. However, there @@ -389,8 +415,8 @@ namespace ts.SignatureHelp { // arg count of 3. const listChildren = argumentsList.getChildren(); - let argumentCount = countWhere(listChildren, arg => arg.kind !== SyntaxKind.CommaToken); - if (!ignoreTrailingComma && listChildren.length > 0 && last(listChildren).kind === SyntaxKind.CommaToken) { + let argumentCount = ts.countWhere(listChildren, arg => arg.kind !== ts.SyntaxKind.CommaToken); + if (!ignoreTrailingComma && listChildren.length > 0 && ts.last(listChildren).kind === ts.SyntaxKind.CommaToken) { argumentCount++; } return argumentCount; @@ -398,7 +424,7 @@ namespace ts.SignatureHelp { // spanIndex is either the index for a given template span. // This does not give appropriate results for a NoSubstitutionTemplateLiteral - function getArgumentIndexForTemplatePiece(spanIndex: number, node: Node, position: number, sourceFile: SourceFile): number { + function getArgumentIndexForTemplatePiece(spanIndex: number, node: ts.Node, position: number, sourceFile: ts.SourceFile): number { // Because the TemplateStringsArray is the first argument, we have to offset each substitution expression by 1. // There are three cases we can encounter: // 1. We are precisely in the template literal (argIndex = 0). @@ -412,9 +438,9 @@ namespace ts.SignatureHelp { // ^ ^ ^ ^ ^ ^ ^ ^ ^ // Case: 1 1 3 2 1 3 2 2 1 /* eslint-enable no-double-space */ - Debug.assert(position >= node.getStart(), "Assumed 'position' could not occur before node."); - if (isTemplateLiteralToken(node)) { - if (isInsideTemplateLiteral(node, position, sourceFile)) { + ts.Debug.assert(position >= node.getStart(), "Assumed 'position' could not occur before node."); + if (ts.isTemplateLiteralToken(node)) { + if (ts.isInsideTemplateLiteral(node, position, sourceFile)) { return 0; } return spanIndex + 2; @@ -422,11 +448,11 @@ namespace ts.SignatureHelp { return spanIndex + 1; } - function getArgumentListInfoForTemplate(tagExpression: TaggedTemplateExpression, argumentIndex: number, sourceFile: SourceFile): ArgumentListInfo { + function getArgumentListInfoForTemplate(tagExpression: ts.TaggedTemplateExpression, argumentIndex: number, sourceFile: ts.SourceFile): ArgumentListInfo { // argumentCount is either 1 or (numSpans + 1) to account for the template strings array argument. - const argumentCount = isNoSubstitutionTemplateLiteral(tagExpression.template) ? 1 : tagExpression.template.templateSpans.length + 1; + const argumentCount = ts.isNoSubstitutionTemplateLiteral(tagExpression.template) ? 1 : tagExpression.template.templateSpans.length + 1; if (argumentIndex !== 0) { - Debug.assertLessThan(argumentIndex, argumentCount); + ts.Debug.assertLessThan(argumentIndex, argumentCount); } return { isTypeParameterList: false, @@ -437,7 +463,7 @@ namespace ts.SignatureHelp { }; } - function getApplicableSpanForArguments(argumentsList: Node, sourceFile: SourceFile): TextSpan { + function getApplicableSpanForArguments(argumentsList: ts.Node, sourceFile: ts.SourceFile): ts.TextSpan { // We use full start and skip trivia on the end because we want to include trivia on // both sides. For example, // @@ -447,11 +473,11 @@ namespace ts.SignatureHelp { // The applicable span is from the first bar to the second bar (inclusive, // but not including parentheses) const applicableSpanStart = argumentsList.getFullStart(); - const applicableSpanEnd = skipTrivia(sourceFile.text, argumentsList.getEnd(), /*stopAfterLineBreak*/ false); - return createTextSpan(applicableSpanStart, applicableSpanEnd - applicableSpanStart); + const applicableSpanEnd = ts.skipTrivia(sourceFile.text, argumentsList.getEnd(), /*stopAfterLineBreak*/ false); + return ts.createTextSpan(applicableSpanStart, applicableSpanEnd - applicableSpanStart); } - function getApplicableSpanForTaggedTemplate(taggedTemplate: TaggedTemplateExpression, sourceFile: SourceFile): TextSpan { + function getApplicableSpanForTaggedTemplate(taggedTemplate: ts.TaggedTemplateExpression, sourceFile: ts.SourceFile): ts.TextSpan { const template = taggedTemplate.template; const applicableSpanStart = template.getStart(); let applicableSpanEnd = template.getEnd(); @@ -464,21 +490,21 @@ namespace ts.SignatureHelp { // | | // This is because a Missing node has no width. However, what we actually want is to include trivia // leading up to the next token in case the user is about to type in a TemplateMiddle or TemplateTail. - if (template.kind === SyntaxKind.TemplateExpression) { - const lastSpan = last(template.templateSpans); + if (template.kind === ts.SyntaxKind.TemplateExpression) { + const lastSpan = ts.last(template.templateSpans); if (lastSpan.literal.getFullWidth() === 0) { - applicableSpanEnd = skipTrivia(sourceFile.text, applicableSpanEnd, /*stopAfterLineBreak*/ false); + applicableSpanEnd = ts.skipTrivia(sourceFile.text, applicableSpanEnd, /*stopAfterLineBreak*/ false); } } - return createTextSpan(applicableSpanStart, applicableSpanEnd - applicableSpanStart); + return ts.createTextSpan(applicableSpanStart, applicableSpanEnd - applicableSpanStart); } - function getContainingArgumentInfo(node: Node, position: number, sourceFile: SourceFile, checker: TypeChecker, isManuallyInvoked: boolean): ArgumentListInfo | undefined { - for (let n = node; !isSourceFile(n) && (isManuallyInvoked || !isBlock(n)); n = n.parent) { + function getContainingArgumentInfo(node: ts.Node, position: number, sourceFile: ts.SourceFile, checker: ts.TypeChecker, isManuallyInvoked: boolean): ArgumentListInfo | undefined { + for (let n = node; !ts.isSourceFile(n) && (isManuallyInvoked || !ts.isBlock(n)); n = n.parent) { // If the node is not a subspan of its parent, this is a big problem. // There have been crashes that might be caused by this violation. - Debug.assert(rangeContainsRange(n.parent, n), "Not a subspan", () => `Child: ${Debug.formatSyntaxKind(n.kind)}, parent: ${Debug.formatSyntaxKind(n.parent.kind)}`); + ts.Debug.assert(ts.rangeContainsRange(n.parent, n), "Not a subspan", () => `Child: ${ts.Debug.formatSyntaxKind(n.kind)}, parent: ${ts.Debug.formatSyntaxKind(n.parent.kind)}`); const argumentInfo = getImmediatelyContainingArgumentOrContextualParameterInfo(n, position, sourceFile, checker); if (argumentInfo) { return argumentInfo; @@ -487,37 +513,30 @@ namespace ts.SignatureHelp { return undefined; } - function getChildListThatStartsWithOpenerToken(parent: Node, openerToken: Node, sourceFile: SourceFile): Node { + function getChildListThatStartsWithOpenerToken(parent: ts.Node, openerToken: ts.Node, sourceFile: ts.SourceFile): ts.Node { const children = parent.getChildren(sourceFile); const indexOfOpenerToken = children.indexOf(openerToken); - Debug.assert(indexOfOpenerToken >= 0 && children.length > indexOfOpenerToken + 1); + ts.Debug.assert(indexOfOpenerToken >= 0 && children.length > indexOfOpenerToken + 1); return children[indexOfOpenerToken + 1]; } - function getExpressionFromInvocation(invocation: CallInvocation | TypeArgsInvocation): Expression { - return invocation.kind === InvocationKind.Call ? getInvokedExpression(invocation.node) : invocation.called; + function getExpressionFromInvocation(invocation: CallInvocation | TypeArgsInvocation): ts.Expression { + return invocation.kind === InvocationKind.Call ? ts.getInvokedExpression(invocation.node) : invocation.called; } - function getEnclosingDeclarationFromInvocation(invocation: Invocation): Node { + function getEnclosingDeclarationFromInvocation(invocation: Invocation): ts.Node { return invocation.kind === InvocationKind.Call ? invocation.node : invocation.kind === InvocationKind.TypeArgs ? invocation.called : invocation.node; } - const signatureHelpNodeBuilderFlags = NodeBuilderFlags.OmitParameterModifiers | NodeBuilderFlags.IgnoreErrors | NodeBuilderFlags.UseAliasDefinedOutsideCurrentScope; - function createSignatureHelpItems( - candidates: readonly Signature[], - resolvedSignature: Signature, - { isTypeParameterList, argumentCount, argumentsSpan: applicableSpan, invocation, argumentIndex }: ArgumentListInfo, - sourceFile: SourceFile, - typeChecker: TypeChecker, - useFullPrefix?: boolean, - ): SignatureHelpItems { + const signatureHelpNodeBuilderFlags = ts.NodeBuilderFlags.OmitParameterModifiers | ts.NodeBuilderFlags.IgnoreErrors | ts.NodeBuilderFlags.UseAliasDefinedOutsideCurrentScope; + function createSignatureHelpItems(candidates: readonly ts.Signature[], resolvedSignature: ts.Signature, { isTypeParameterList, argumentCount, argumentsSpan: applicableSpan, invocation, argumentIndex }: ArgumentListInfo, sourceFile: ts.SourceFile, typeChecker: ts.TypeChecker, useFullPrefix?: boolean): ts.SignatureHelpItems { const enclosingDeclaration = getEnclosingDeclarationFromInvocation(invocation); const callTargetSymbol = invocation.kind === InvocationKind.Contextual ? invocation.symbol : (typeChecker.getSymbolAtLocation(getExpressionFromInvocation(invocation)) || useFullPrefix && resolvedSignature.declaration?.symbol); - const callTargetDisplayParts = callTargetSymbol ? symbolToDisplayParts(typeChecker, callTargetSymbol, useFullPrefix ? sourceFile : undefined, /*meaning*/ undefined) : emptyArray; - const items = map(candidates, candidateSignature => getSignatureHelpItem(candidateSignature, callTargetDisplayParts, isTypeParameterList, typeChecker, enclosingDeclaration, sourceFile)); + const callTargetDisplayParts = callTargetSymbol ? ts.symbolToDisplayParts(typeChecker, callTargetSymbol, useFullPrefix ? sourceFile : undefined, /*meaning*/ undefined) : ts.emptyArray; + const items = ts.map(candidates, candidateSignature => getSignatureHelpItem(candidateSignature, callTargetDisplayParts, isTypeParameterList, typeChecker, enclosingDeclaration, sourceFile)); if (argumentIndex !== 0) { - Debug.assertLessThan(argumentIndex, argumentCount); + ts.Debug.assertLessThan(argumentIndex, argumentCount); } let selectedItemIndex = 0; let itemsSeen = 0; @@ -541,11 +560,11 @@ namespace ts.SignatureHelp { itemsSeen += item.length; } - Debug.assert(selectedItemIndex !== -1); // If candidates is non-empty it should always include bestSignature. We check for an empty candidates before calling this function. - const help = { items: flatMapToMutable(items, identity), applicableSpan, selectedItemIndex, argumentIndex, argumentCount }; + ts.Debug.assert(selectedItemIndex !== -1); // If candidates is non-empty it should always include bestSignature. We check for an empty candidates before calling this function. + const help = { items: ts.flatMapToMutable(items, ts.identity), applicableSpan, selectedItemIndex, argumentIndex, argumentCount }; const selected = help.items[selectedItemIndex]; if (selected.isVariadic) { - const firstRest = findIndex(selected.parameters, p => !!p.isRest); + const firstRest = ts.findIndex(selected.parameters, p => !!p.isRest); if (-1 < firstRest && firstRest < selected.parameters.length - 1) { // We don't have any code to get this correct; instead, don't highlight a current parameter AT ALL help.argumentIndex = selected.parameters.length; @@ -557,35 +576,29 @@ namespace ts.SignatureHelp { return help; } - function createTypeHelpItems( - symbol: Symbol, - { argumentCount, argumentsSpan: applicableSpan, invocation, argumentIndex }: ArgumentListInfo, - sourceFile: SourceFile, - checker: TypeChecker - ): SignatureHelpItems | undefined { + function createTypeHelpItems(symbol: ts.Symbol, { argumentCount, argumentsSpan: applicableSpan, invocation, argumentIndex }: ArgumentListInfo, sourceFile: ts.SourceFile, checker: ts.TypeChecker): ts.SignatureHelpItems | undefined { const typeParameters = checker.getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(symbol); - if (!typeParameters) return undefined; + if (!typeParameters) + return undefined; const items = [getTypeHelpItem(symbol, typeParameters, checker, getEnclosingDeclarationFromInvocation(invocation), sourceFile)]; return { items, applicableSpan, selectedItemIndex: 0, argumentIndex, argumentCount }; } - function getTypeHelpItem(symbol: Symbol, typeParameters: readonly TypeParameter[], checker: TypeChecker, enclosingDeclaration: Node, sourceFile: SourceFile): SignatureHelpItem { - const typeSymbolDisplay = symbolToDisplayParts(checker, symbol); - - const printer = createPrinter({ removeComments: true }); + function getTypeHelpItem(symbol: ts.Symbol, typeParameters: readonly ts.TypeParameter[], checker: ts.TypeChecker, enclosingDeclaration: ts.Node, sourceFile: ts.SourceFile): ts.SignatureHelpItem { + const typeSymbolDisplay = ts.symbolToDisplayParts(checker, symbol); + const printer = ts.createPrinter({ removeComments: true }); const parameters = typeParameters.map(t => createSignatureHelpParameterForTypeParameter(t, checker, enclosingDeclaration, sourceFile, printer)); const documentation = symbol.getDocumentationComment(checker); const tags = symbol.getJsDocTags(checker); - const prefixDisplayParts = [...typeSymbolDisplay, punctuationPart(SyntaxKind.LessThanToken)]; - return { isVariadic: false, prefixDisplayParts, suffixDisplayParts: [punctuationPart(SyntaxKind.GreaterThanToken)], separatorDisplayParts, parameters, documentation, tags }; + const prefixDisplayParts = [...typeSymbolDisplay, ts.punctuationPart(ts.SyntaxKind.LessThanToken)]; + return { isVariadic: false, prefixDisplayParts, suffixDisplayParts: [ts.punctuationPart(ts.SyntaxKind.GreaterThanToken)], separatorDisplayParts, parameters, documentation, tags }; } - const separatorDisplayParts: SymbolDisplayPart[] = [punctuationPart(SyntaxKind.CommaToken), spacePart()]; - - function getSignatureHelpItem(candidateSignature: Signature, callTargetDisplayParts: readonly SymbolDisplayPart[], isTypeParameterList: boolean, checker: TypeChecker, enclosingDeclaration: Node, sourceFile: SourceFile): SignatureHelpItem[] { + const separatorDisplayParts: ts.SymbolDisplayPart[] = [ts.punctuationPart(ts.SyntaxKind.CommaToken), ts.spacePart()]; + function getSignatureHelpItem(candidateSignature: ts.Signature, callTargetDisplayParts: readonly ts.SymbolDisplayPart[], isTypeParameterList: boolean, checker: ts.TypeChecker, enclosingDeclaration: ts.Node, sourceFile: ts.SourceFile): ts.SignatureHelpItem[] { const infos = (isTypeParameterList ? itemInfoForTypeParameters : itemInfoForParameters)(candidateSignature, checker, enclosingDeclaration, sourceFile); - return map(infos, ({ isVariadic, parameters, prefix, suffix }) => { + return ts.map(infos, ({ isVariadic, parameters, prefix, suffix }) => { const prefixDisplayParts = [...callTargetDisplayParts, ...prefix]; const suffixDisplayParts = [...suffix, ...returnTypeToDisplayParts(candidateSignature, enclosingDeclaration, checker)]; const documentation = candidateSignature.getDocumentationComment(checker); @@ -594,8 +607,8 @@ namespace ts.SignatureHelp { }); } - function returnTypeToDisplayParts(candidateSignature: Signature, enclosingDeclaration: Node, checker: TypeChecker): readonly SymbolDisplayPart[] { - return mapToDisplayParts(writer => { + function returnTypeToDisplayParts(candidateSignature: ts.Signature, enclosingDeclaration: ts.Node, checker: ts.TypeChecker): readonly ts.SymbolDisplayPart[] { + return ts.mapToDisplayParts(writer => { writer.writePunctuation(":"); writer.writeSpace(" "); const predicate = checker.getTypePredicateOfSignature(candidateSignature); @@ -608,58 +621,61 @@ namespace ts.SignatureHelp { }); } - interface SignatureHelpItemInfo { readonly isVariadic: boolean; readonly parameters: SignatureHelpParameter[]; readonly prefix: readonly SymbolDisplayPart[]; readonly suffix: readonly SymbolDisplayPart[]; } - - function itemInfoForTypeParameters(candidateSignature: Signature, checker: TypeChecker, enclosingDeclaration: Node, sourceFile: SourceFile): SignatureHelpItemInfo[] { + interface SignatureHelpItemInfo { + readonly isVariadic: boolean; + readonly parameters: ts.SignatureHelpParameter[]; + readonly prefix: readonly ts.SymbolDisplayPart[]; + readonly suffix: readonly ts.SymbolDisplayPart[]; + } + function itemInfoForTypeParameters(candidateSignature: ts.Signature, checker: ts.TypeChecker, enclosingDeclaration: ts.Node, sourceFile: ts.SourceFile): SignatureHelpItemInfo[] { const typeParameters = (candidateSignature.target || candidateSignature).typeParameters; - const printer = createPrinter({ removeComments: true }); - const parameters = (typeParameters || emptyArray).map(t => createSignatureHelpParameterForTypeParameter(t, checker, enclosingDeclaration, sourceFile, printer)); + const printer = ts.createPrinter({ removeComments: true }); + const parameters = (typeParameters || ts.emptyArray).map(t => createSignatureHelpParameterForTypeParameter(t, checker, enclosingDeclaration, sourceFile, printer)); const thisParameter = candidateSignature.thisParameter ? [checker.symbolToParameterDeclaration(candidateSignature.thisParameter, enclosingDeclaration, signatureHelpNodeBuilderFlags)!] : []; return checker.getExpandedParameters(candidateSignature).map(paramList => { - const params = factory.createNodeArray([...thisParameter, ...map(paramList, param => checker.symbolToParameterDeclaration(param, enclosingDeclaration, signatureHelpNodeBuilderFlags)!)]); - const parameterParts = mapToDisplayParts(writer => { - printer.writeList(ListFormat.CallExpressionArguments, params, sourceFile, writer); + const params = ts.factory.createNodeArray([...thisParameter, ...ts.map(paramList, param => checker.symbolToParameterDeclaration(param, enclosingDeclaration, signatureHelpNodeBuilderFlags)!)]); + const parameterParts = ts.mapToDisplayParts(writer => { + printer.writeList(ts.ListFormat.CallExpressionArguments, params, sourceFile, writer); }); - return { isVariadic: false, parameters, prefix: [punctuationPart(SyntaxKind.LessThanToken)], suffix: [punctuationPart(SyntaxKind.GreaterThanToken), ...parameterParts] }; + return { isVariadic: false, parameters, prefix: [ts.punctuationPart(ts.SyntaxKind.LessThanToken)], suffix: [ts.punctuationPart(ts.SyntaxKind.GreaterThanToken), ...parameterParts] }; }); } - function itemInfoForParameters(candidateSignature: Signature, checker: TypeChecker, enclosingDeclaration: Node, sourceFile: SourceFile): SignatureHelpItemInfo[] { - const printer = createPrinter({ removeComments: true }); - const typeParameterParts = mapToDisplayParts(writer => { + function itemInfoForParameters(candidateSignature: ts.Signature, checker: ts.TypeChecker, enclosingDeclaration: ts.Node, sourceFile: ts.SourceFile): SignatureHelpItemInfo[] { + const printer = ts.createPrinter({ removeComments: true }); + const typeParameterParts = ts.mapToDisplayParts(writer => { if (candidateSignature.typeParameters && candidateSignature.typeParameters.length) { - const args = factory.createNodeArray(candidateSignature.typeParameters.map(p => checker.typeParameterToDeclaration(p, enclosingDeclaration, signatureHelpNodeBuilderFlags)!)); - printer.writeList(ListFormat.TypeParameters, args, sourceFile, writer); + const args = ts.factory.createNodeArray(candidateSignature.typeParameters.map(p => checker.typeParameterToDeclaration(p, enclosingDeclaration, signatureHelpNodeBuilderFlags)!)); + printer.writeList(ts.ListFormat.TypeParameters, args, sourceFile, writer); } }); const lists = checker.getExpandedParameters(candidateSignature); - const isVariadic: (parameterList: readonly Symbol[]) => boolean = - !checker.hasEffectiveRestParameter(candidateSignature) ? _ => false + const isVariadic: (parameterList: readonly ts.Symbol[]) => boolean = !checker.hasEffectiveRestParameter(candidateSignature) ? _ => false : lists.length === 1 ? _ => true - : pList => !!(pList.length && (pList[pList.length - 1] as TransientSymbol).checkFlags & CheckFlags.RestParameter); + : pList => !!(pList.length && (pList[pList.length - 1] as ts.TransientSymbol).checkFlags & ts.CheckFlags.RestParameter); return lists.map(parameterList => ({ isVariadic: isVariadic(parameterList), parameters: parameterList.map(p => createSignatureHelpParameterForParameter(p, checker, enclosingDeclaration, sourceFile, printer)), - prefix: [...typeParameterParts, punctuationPart(SyntaxKind.OpenParenToken)], - suffix: [punctuationPart(SyntaxKind.CloseParenToken)] + prefix: [...typeParameterParts, ts.punctuationPart(ts.SyntaxKind.OpenParenToken)], + suffix: [ts.punctuationPart(ts.SyntaxKind.CloseParenToken)] })); } - function createSignatureHelpParameterForParameter(parameter: Symbol, checker: TypeChecker, enclosingDeclaration: Node, sourceFile: SourceFile, printer: Printer): SignatureHelpParameter { - const displayParts = mapToDisplayParts(writer => { + function createSignatureHelpParameterForParameter(parameter: ts.Symbol, checker: ts.TypeChecker, enclosingDeclaration: ts.Node, sourceFile: ts.SourceFile, printer: ts.Printer): ts.SignatureHelpParameter { + const displayParts = ts.mapToDisplayParts(writer => { const param = checker.symbolToParameterDeclaration(parameter, enclosingDeclaration, signatureHelpNodeBuilderFlags)!; - printer.writeNode(EmitHint.Unspecified, param, sourceFile, writer); + printer.writeNode(ts.EmitHint.Unspecified, param, sourceFile, writer); }); - const isOptional = checker.isOptionalParameter(parameter.valueDeclaration as ParameterDeclaration); - const isRest = !!((parameter as TransientSymbol).checkFlags & CheckFlags.RestParameter); + const isOptional = checker.isOptionalParameter(parameter.valueDeclaration as ts.ParameterDeclaration); + const isRest = !!((parameter as ts.TransientSymbol).checkFlags & ts.CheckFlags.RestParameter); return { name: parameter.name, documentation: parameter.getDocumentationComment(checker), displayParts, isOptional, isRest }; } - function createSignatureHelpParameterForTypeParameter(typeParameter: TypeParameter, checker: TypeChecker, enclosingDeclaration: Node, sourceFile: SourceFile, printer: Printer): SignatureHelpParameter { - const displayParts = mapToDisplayParts(writer => { + function createSignatureHelpParameterForTypeParameter(typeParameter: ts.TypeParameter, checker: ts.TypeChecker, enclosingDeclaration: ts.Node, sourceFile: ts.SourceFile, printer: ts.Printer): ts.SignatureHelpParameter { + const displayParts = ts.mapToDisplayParts(writer => { const param = checker.typeParameterToDeclaration(typeParameter, enclosingDeclaration, signatureHelpNodeBuilderFlags)!; - printer.writeNode(EmitHint.Unspecified, param, sourceFile, writer); + printer.writeNode(ts.EmitHint.Unspecified, param, sourceFile, writer); }); return { name: typeParameter.symbol.name, documentation: typeParameter.symbol.getDocumentationComment(checker), displayParts, isOptional: false, isRest: false }; } diff --git a/src/services/smartSelection.ts b/src/services/smartSelection.ts index 6cd5c8f94d854..185f8e622e5fb 100644 --- a/src/services/smartSelection.ts +++ b/src/services/smartSelection.ts @@ -1,25 +1,25 @@ /* @internal */ namespace ts.SmartSelectionRange { - export function getSmartSelectionRange(pos: number, sourceFile: SourceFile): SelectionRange { - let selectionRange: SelectionRange = { - textSpan: createTextSpanFromBounds(sourceFile.getFullStart(), sourceFile.getEnd()) + export function getSmartSelectionRange(pos: number, sourceFile: ts.SourceFile): ts.SelectionRange { + let selectionRange: ts.SelectionRange = { + textSpan: ts.createTextSpanFromBounds(sourceFile.getFullStart(), sourceFile.getEnd()) }; - let parentNode: Node = sourceFile; + let parentNode: ts.Node = sourceFile; outer: while (true) { const children = getSelectionChildren(parentNode); - if (!children.length) break; + if (!children.length) + break; for (let i = 0; i < children.length; i++) { - const prevNode: Node | undefined = children[i - 1]; - const node: Node = children[i]; - const nextNode: Node | undefined = children[i + 1]; - - if (getTokenPosOfNode(node, sourceFile, /*includeJsDoc*/ true) > pos) { + const prevNode: ts.Node | undefined = children[i - 1]; + const node: ts.Node = children[i]; + const nextNode: ts.Node | undefined = children[i + 1]; + if (ts.getTokenPosOfNode(node, sourceFile, /*includeJsDoc*/ true) > pos) { break outer; } - const comment = singleOrUndefined(getTrailingCommentRanges(sourceFile.text, node.end)); - if (comment && comment.kind === SyntaxKind.SingleLineCommentTrivia) { + const comment = ts.singleOrUndefined(ts.getTrailingCommentRanges(sourceFile.text, node.end)); + if (comment && comment.kind === ts.SyntaxKind.SingleLineCommentTrivia) { pushSelectionCommentRange(comment.pos, comment.end); } @@ -30,19 +30,19 @@ namespace ts.SmartSelectionRange { // 3. A VariableStatement’s children are just a VaraiableDeclarationList and a semicolon. // 4. A lone VariableDeclaration in a VaraibleDeclaration feels redundant with the VariableStatement. // Dive in without pushing a selection range. - if (isBlock(node) - || isTemplateSpan(node) || isTemplateHead(node) || isTemplateTail(node) - || prevNode && isTemplateHead(prevNode) - || isVariableDeclarationList(node) && isVariableStatement(parentNode) - || isSyntaxList(node) && isVariableDeclarationList(parentNode) - || isVariableDeclaration(node) && isSyntaxList(parentNode) && children.length === 1 - || isJSDocTypeExpression(node) || isJSDocSignature(node) || isJSDocTypeLiteral(node)) { + if (ts.isBlock(node) + || ts.isTemplateSpan(node) || ts.isTemplateHead(node) || ts.isTemplateTail(node) + || prevNode && ts.isTemplateHead(prevNode) + || ts.isVariableDeclarationList(node) && ts.isVariableStatement(parentNode) + || ts.isSyntaxList(node) && ts.isVariableDeclarationList(parentNode) + || ts.isVariableDeclaration(node) && ts.isSyntaxList(parentNode) && children.length === 1 + || ts.isJSDocTypeExpression(node) || ts.isJSDocSignature(node) || ts.isJSDocTypeLiteral(node)) { parentNode = node; break; } // Synthesize a stop for '${ ... }' since '${' and '}' actually belong to siblings. - if (isTemplateSpan(parentNode) && nextNode && isTemplateMiddleOrTemplateTail(nextNode)) { + if (ts.isTemplateSpan(parentNode) && nextNode && ts.isTemplateMiddleOrTemplateTail(nextNode)) { const start = node.getFullStart() - "${".length; const end = nextNode.getStart() + "}".length; pushSelectionRange(start, end); @@ -50,19 +50,19 @@ namespace ts.SmartSelectionRange { // Blocks with braces, brackets, parens, or JSX tags on separate lines should be // selected from open to close, including whitespace but not including the braces/etc. themselves. - const isBetweenMultiLineBookends = isSyntaxList(node) && isListOpener(prevNode) && isListCloser(nextNode) - && !positionsAreOnSameLine(prevNode.getStart(), nextNode.getStart(), sourceFile); + const isBetweenMultiLineBookends = ts.isSyntaxList(node) && isListOpener(prevNode) && isListCloser(nextNode) + && !ts.positionsAreOnSameLine(prevNode.getStart(), nextNode.getStart(), sourceFile); const start = isBetweenMultiLineBookends ? prevNode.getEnd() : node.getStart(); const end = isBetweenMultiLineBookends ? nextNode.getStart() : getEndPos(sourceFile, node); - if (hasJSDocNodes(node) && node.jsDoc?.length) { - pushSelectionRange(first(node.jsDoc).getStart(), end); + if (ts.hasJSDocNodes(node) && node.jsDoc?.length) { + pushSelectionRange(ts.first(node.jsDoc).getStart(), end); } pushSelectionRange(start, end); // String literals should have a stop both inside and outside their quotes. - if (isStringLiteral(node) || isTemplateLiteral(node)) { + if (ts.isStringLiteral(node) || ts.isTemplateLiteral(node)) { pushSelectionRange(start + 1, end - 1); } @@ -84,13 +84,12 @@ namespace ts.SmartSelectionRange { function pushSelectionRange(start: number, end: number): void { // Skip empty ranges if (start !== end) { - const textSpan = createTextSpanFromBounds(start, end); + const textSpan = ts.createTextSpanFromBounds(start, end); if (!selectionRange || ( // Skip ranges that are identical to the parent - !textSpansEqual(textSpan, selectionRange.textSpan) && + !ts.textSpansEqual(textSpan, selectionRange.textSpan) && // Skip ranges that don’t contain the original position - textSpanIntersectsWithPosition(textSpan, pos) - )) { + ts.textSpanIntersectsWithPosition(textSpan, pos))) { selectionRange = { textSpan, ...selectionRange && { parent: selectionRange } }; } } @@ -100,7 +99,7 @@ namespace ts.SmartSelectionRange { pushSelectionRange(start, end); let pos = start; - while (sourceFile.text.charCodeAt(pos) === CharacterCodes.slash) { + while (sourceFile.text.charCodeAt(pos) === ts.CharacterCodes.slash) { pos++; } pushSelectionRange(pos, end); @@ -116,22 +115,22 @@ namespace ts.SmartSelectionRange { * @param pos The position to check. * @param node The candidate node to snap to. */ - function positionShouldSnapToNode(sourceFile: SourceFile, pos: number, node: Node) { + function positionShouldSnapToNode(sourceFile: ts.SourceFile, pos: number, node: ts.Node) { // Can’t use 'ts.positionBelongsToNode()' here because it cleverly accounts // for missing nodes, which can’t really be considered when deciding what // to select. - Debug.assert(node.pos <= pos); + ts.Debug.assert(node.pos <= pos); if (pos < node.end) { return true; } const nodeEnd = node.getEnd(); if (nodeEnd === pos) { - return getTouchingPropertyName(sourceFile, pos).pos < node.end; + return ts.getTouchingPropertyName(sourceFile, pos).pos < node.end; } return false; } - const isImport = or(isImportDeclaration, isImportEqualsDeclaration); + const isImport = ts.or(ts.isImportDeclaration, ts.isImportEqualsDeclaration); /** * Gets the children of a node to be considered for selection ranging, @@ -141,9 +140,9 @@ namespace ts.SmartSelectionRange { * selected all together, even though in the AST they’re just siblings of each * other as well as of other top-level statements and declarations. */ - function getSelectionChildren(node: Node): readonly Node[] { + function getSelectionChildren(node: ts.Node): readonly ts.Node[] { // Group top-level imports - if (isSourceFile(node)) { + if (ts.isSourceFile(node)) { return groupChildren(node.getChildAt(0).getChildren(), isImport); } @@ -157,48 +156,42 @@ namespace ts.SmartSelectionRange { // around the “key/value” pair not because there’s a node there, but // because it allows the mapped type to become an object type with a // few keystrokes. - if (isMappedTypeNode(node)) { + if (ts.isMappedTypeNode(node)) { const [openBraceToken, ...children] = node.getChildren(); - const closeBraceToken = Debug.checkDefined(children.pop()); - Debug.assertEqual(openBraceToken.kind, SyntaxKind.OpenBraceToken); - Debug.assertEqual(closeBraceToken.kind, SyntaxKind.CloseBraceToken); + const closeBraceToken = ts.Debug.checkDefined(children.pop()); + ts.Debug.assertEqual(openBraceToken.kind, ts.SyntaxKind.OpenBraceToken); + ts.Debug.assertEqual(closeBraceToken.kind, ts.SyntaxKind.CloseBraceToken); // Group `-/+readonly` and `-/+?` - const groupedWithPlusMinusTokens = groupChildren(children, child => - child === node.readonlyToken || child.kind === SyntaxKind.ReadonlyKeyword || - child === node.questionToken || child.kind === SyntaxKind.QuestionToken); + const groupedWithPlusMinusTokens = groupChildren(children, child => child === node.readonlyToken || child.kind === ts.SyntaxKind.ReadonlyKeyword || + child === node.questionToken || child.kind === ts.SyntaxKind.QuestionToken); // Group type parameter with surrounding brackets - const groupedWithBrackets = groupChildren(groupedWithPlusMinusTokens, ({ kind }) => - kind === SyntaxKind.OpenBracketToken || - kind === SyntaxKind.TypeParameter || - kind === SyntaxKind.CloseBracketToken - ); + const groupedWithBrackets = groupChildren(groupedWithPlusMinusTokens, ({ kind }) => kind === ts.SyntaxKind.OpenBracketToken || + kind === ts.SyntaxKind.TypeParameter || + kind === ts.SyntaxKind.CloseBracketToken); return [ openBraceToken, // Pivot on `:` - createSyntaxList(splitChildren(groupedWithBrackets, ({ kind }) => kind === SyntaxKind.ColonToken)), + createSyntaxList(splitChildren(groupedWithBrackets, ({ kind }) => kind === ts.SyntaxKind.ColonToken)), closeBraceToken, ]; } // Group modifiers and property name, then pivot on `:`. - if (isPropertySignature(node)) { - const children = groupChildren(node.getChildren(), child => - child === node.name || contains(node.modifiers, child)); - return splitChildren(children, ({ kind }) => kind === SyntaxKind.ColonToken); + if (ts.isPropertySignature(node)) { + const children = groupChildren(node.getChildren(), child => child === node.name || ts.contains(node.modifiers, child)); + return splitChildren(children, ({ kind }) => kind === ts.SyntaxKind.ColonToken); } // Group the parameter name with its `...`, then that group with its `?`, then pivot on `=`. - if (isParameter(node)) { - const groupedDotDotDotAndName = groupChildren(node.getChildren(), child => - child === node.dotDotDotToken || child === node.name); - const groupedWithQuestionToken = groupChildren(groupedDotDotDotAndName, child => - child === groupedDotDotDotAndName[0] || child === node.questionToken); - return splitChildren(groupedWithQuestionToken, ({ kind }) => kind === SyntaxKind.EqualsToken); + if (ts.isParameter(node)) { + const groupedDotDotDotAndName = groupChildren(node.getChildren(), child => child === node.dotDotDotToken || child === node.name); + const groupedWithQuestionToken = groupChildren(groupedDotDotDotAndName, child => child === groupedDotDotDotAndName[0] || child === node.questionToken); + return splitChildren(groupedWithQuestionToken, ({ kind }) => kind === ts.SyntaxKind.EqualsToken); } // Pivot on '=' - if (isBindingElement(node)) { - return splitChildren(node.getChildren(), ({ kind }) => kind === SyntaxKind.EqualsToken); + if (ts.isBindingElement(node)) { + return splitChildren(node.getChildren(), ({ kind }) => kind === ts.SyntaxKind.EqualsToken); } return node.getChildren(); @@ -208,9 +201,9 @@ namespace ts.SmartSelectionRange { * Groups sibling nodes together into their own SyntaxList if they * a) are adjacent, AND b) match a predicate function. */ - function groupChildren(children: Node[], groupOn: (child: Node) => boolean): Node[] { - const result: Node[] = []; - let group: Node[] | undefined; + function groupChildren(children: ts.Node[], groupOn: (child: ts.Node) => boolean): ts.Node[] { + const result: ts.Node[] = []; + let group: ts.Node[] | undefined; for (const child of children) { if (groupOn(child)) { group = group || []; @@ -244,20 +237,20 @@ namespace ts.SmartSelectionRange { * @param separateTrailingSemicolon If the last token is a semicolon, it will be returned as a separate * child rather than be included in the right-hand group. */ - function splitChildren(children: Node[], pivotOn: (child: Node) => boolean, separateTrailingSemicolon = true): Node[] { + function splitChildren(children: ts.Node[], pivotOn: (child: ts.Node) => boolean, separateTrailingSemicolon = true): ts.Node[] { if (children.length < 2) { return children; } - const splitTokenIndex = findIndex(children, pivotOn); + const splitTokenIndex = ts.findIndex(children, pivotOn); if (splitTokenIndex === -1) { return children; } const leftChildren = children.slice(0, splitTokenIndex); const splitToken = children[splitTokenIndex]; - const lastToken = last(children); - const separateLastToken = separateTrailingSemicolon && lastToken.kind === SyntaxKind.SemicolonToken; + const lastToken = ts.last(children); + const separateLastToken = separateTrailingSemicolon && lastToken.kind === ts.SyntaxKind.SemicolonToken; const rightChildren = children.slice(splitTokenIndex + 1, separateLastToken ? children.length - 1 : undefined); - const result = compact([ + const result = ts.compact([ leftChildren.length ? createSyntaxList(leftChildren) : undefined, splitToken, rightChildren.length ? createSyntaxList(rightChildren) : undefined, @@ -265,34 +258,34 @@ namespace ts.SmartSelectionRange { return separateLastToken ? result.concat(lastToken) : result; } - function createSyntaxList(children: Node[]): SyntaxList { - Debug.assertGreaterThanOrEqual(children.length, 1); - return setTextRangePosEnd(parseNodeFactory.createSyntaxList(children), children[0].pos, last(children).end); + function createSyntaxList(children: ts.Node[]): ts.SyntaxList { + ts.Debug.assertGreaterThanOrEqual(children.length, 1); + return ts.setTextRangePosEnd(ts.parseNodeFactory.createSyntaxList(children), children[0].pos, ts.last(children).end); } - function isListOpener(token: Node | undefined): token is Node { + function isListOpener(token: ts.Node | undefined): token is ts.Node { const kind = token && token.kind; - return kind === SyntaxKind.OpenBraceToken - || kind === SyntaxKind.OpenBracketToken - || kind === SyntaxKind.OpenParenToken - || kind === SyntaxKind.JsxOpeningElement; + return kind === ts.SyntaxKind.OpenBraceToken + || kind === ts.SyntaxKind.OpenBracketToken + || kind === ts.SyntaxKind.OpenParenToken + || kind === ts.SyntaxKind.JsxOpeningElement; } - function isListCloser(token: Node | undefined): token is Node { + function isListCloser(token: ts.Node | undefined): token is ts.Node { const kind = token && token.kind; - return kind === SyntaxKind.CloseBraceToken - || kind === SyntaxKind.CloseBracketToken - || kind === SyntaxKind.CloseParenToken - || kind === SyntaxKind.JsxClosingElement; + return kind === ts.SyntaxKind.CloseBraceToken + || kind === ts.SyntaxKind.CloseBracketToken + || kind === ts.SyntaxKind.CloseParenToken + || kind === ts.SyntaxKind.JsxClosingElement; } - function getEndPos(sourceFile: SourceFile, node: Node): number { + function getEndPos(sourceFile: ts.SourceFile, node: ts.Node): number { switch (node.kind) { - case SyntaxKind.JSDocParameterTag: - case SyntaxKind.JSDocCallbackTag: - case SyntaxKind.JSDocPropertyTag: - case SyntaxKind.JSDocTypedefTag: - case SyntaxKind.JSDocThisTag: + case ts.SyntaxKind.JSDocParameterTag: + case ts.SyntaxKind.JSDocCallbackTag: + case ts.SyntaxKind.JSDocPropertyTag: + case ts.SyntaxKind.JSDocTypedefTag: + case ts.SyntaxKind.JSDocThisTag: return sourceFile.getLineEndOfPosition(node.getStart()); default: return node.getEnd(); diff --git a/src/services/sourcemaps.ts b/src/services/sourcemaps.ts index ed4bb7c892822..1a77ee0e344d5 100644 --- a/src/services/sourcemaps.ts +++ b/src/services/sourcemaps.ts @@ -3,28 +3,28 @@ namespace ts { const base64UrlRegExp = /^data:(?:application\/json(?:;charset=[uU][tT][fF]-8);base64,([A-Za-z0-9+\/=]+)$)?/; export interface SourceMapper { - toLineColumnOffset(fileName: string, position: number): LineAndCharacter; - tryGetSourcePosition(info: DocumentPosition): DocumentPosition | undefined; - tryGetGeneratedPosition(info: DocumentPosition): DocumentPosition | undefined; + toLineColumnOffset(fileName: string, position: number): ts.LineAndCharacter; + tryGetSourcePosition(info: ts.DocumentPosition): ts.DocumentPosition | undefined; + tryGetGeneratedPosition(info: ts.DocumentPosition): ts.DocumentPosition | undefined; clearCache(): void; } export interface SourceMapperHost { useCaseSensitiveFileNames(): boolean; getCurrentDirectory(): string; - getProgram(): Program | undefined; + getProgram(): ts.Program | undefined; fileExists?(path: string): boolean; readFile?(path: string, encoding?: string): string | undefined; - getSourceFileLike?(fileName: string): SourceFileLike | undefined; - getDocumentPositionMapper?(generatedFileName: string, sourceFileName?: string): DocumentPositionMapper | undefined; + getSourceFileLike?(fileName: string): ts.SourceFileLike | undefined; + getDocumentPositionMapper?(generatedFileName: string, sourceFileName?: string): ts.DocumentPositionMapper | undefined; log(s: string): void; } export function getSourceMapper(host: SourceMapperHost): SourceMapper { - const getCanonicalFileName = createGetCanonicalFileName(host.useCaseSensitiveFileNames()); + const getCanonicalFileName = ts.createGetCanonicalFileName(host.useCaseSensitiveFileNames()); const currentDirectory = host.getCurrentDirectory(); - const sourceFileLike = new Map(); - const documentPositionMappers = new Map(); + const sourceFileLike = new ts.Map(); + const documentPositionMappers = new ts.Map(); return { tryGetSourcePosition, tryGetGeneratedPosition, toLineColumnOffset, clearCache }; function toPath(fileName: string) { @@ -34,40 +34,38 @@ namespace ts { function getDocumentPositionMapper(generatedFileName: string, sourceFileName?: string) { const path = toPath(generatedFileName); const value = documentPositionMappers.get(path); - if (value) return value; - - let mapper: DocumentPositionMapper | undefined; + if (value) + return value; + let mapper: ts.DocumentPositionMapper | undefined; if (host.getDocumentPositionMapper) { mapper = host.getDocumentPositionMapper(generatedFileName, sourceFileName); } else if (host.readFile) { const file = getSourceFileLike(generatedFileName); - mapper = file && ts.getDocumentPositionMapper( - { getSourceFileLike, getCanonicalFileName, log: s => host.log(s) }, - generatedFileName, - getLineInfo(file.text, getLineStarts(file)), - f => !host.fileExists || host.fileExists(f) ? host.readFile!(f) : undefined - ); + mapper = file && ts.getDocumentPositionMapper({ getSourceFileLike, getCanonicalFileName, log: s => host.log(s) }, generatedFileName, ts.getLineInfo(file.text, ts.getLineStarts(file)), f => !host.fileExists || host.fileExists(f) ? host.readFile!(f) : undefined); } - documentPositionMappers.set(path, mapper || identitySourceMapConsumer); - return mapper || identitySourceMapConsumer; + documentPositionMappers.set(path, mapper || ts.identitySourceMapConsumer); + return mapper || ts.identitySourceMapConsumer; } - - function tryGetSourcePosition(info: DocumentPosition): DocumentPosition | undefined { - if (!isDeclarationFileName(info.fileName)) return undefined; + function tryGetSourcePosition(info: ts.DocumentPosition): ts.DocumentPosition | undefined { + if (!ts.isDeclarationFileName(info.fileName)) + return undefined; const file = getSourceFile(info.fileName); - if (!file) return undefined; + if (!file) + return undefined; const newLoc = getDocumentPositionMapper(info.fileName).getSourcePosition(info); return !newLoc || newLoc === info ? undefined : tryGetSourcePosition(newLoc) || newLoc; } - function tryGetGeneratedPosition(info: DocumentPosition): DocumentPosition | undefined { - if (isDeclarationFileName(info.fileName)) return undefined; + function tryGetGeneratedPosition(info: ts.DocumentPosition): ts.DocumentPosition | undefined { + if (ts.isDeclarationFileName(info.fileName)) + return undefined; const sourceFile = getSourceFile(info.fileName); - if (!sourceFile) return undefined; + if (!sourceFile) + return undefined; const program = host.getProgram()!; // If this is source file of project reference source (instead of redirect) there is no generated position @@ -76,12 +74,13 @@ namespace ts { } const options = program.getCompilerOptions(); - const outPath = outFile(options); + const outPath = ts.outFile(options); const declarationPath = outPath ? - removeFileExtension(outPath) + Extension.Dts : - getDeclarationEmitOutputFilePathWorker(info.fileName, program.getCompilerOptions(), currentDirectory, program.getCommonSourceDirectory(), getCanonicalFileName); - if (declarationPath === undefined) return undefined; + ts.removeFileExtension(outPath) + ts.Extension.Dts : + ts.getDeclarationEmitOutputFilePathWorker(info.fileName, program.getCompilerOptions(), currentDirectory, program.getCommonSourceDirectory(), getCanonicalFileName); + if (declarationPath === undefined) + return undefined; const newLoc = getDocumentPositionMapper(declarationPath, info.fileName).getGeneratedPosition(info); return newLoc === info ? undefined : newLoc; @@ -89,7 +88,8 @@ namespace ts { function getSourceFile(fileName: string) { const program = host.getProgram(); - if (!program) return undefined; + if (!program) + return undefined; const path = toPath(fileName); // file returned here could be .d.ts when asked for .ts file if projectReferences and module resolution created this source file @@ -97,10 +97,11 @@ namespace ts { return file && file.resolvedPath === path ? file : undefined; } - function getOrCreateSourceFileLike(fileName: string): SourceFileLike | undefined { + function getOrCreateSourceFileLike(fileName: string): ts.SourceFileLike | undefined { const path = toPath(fileName); const fileFromCache = sourceFileLike.get(path); - if (fileFromCache !== undefined) return fileFromCache ? fileFromCache : undefined; + if (fileFromCache !== undefined) + return fileFromCache ? fileFromCache : undefined; if (!host.readFile || host.fileExists && !host.fileExists(path)) { sourceFileLike.set(path, false); @@ -121,7 +122,7 @@ namespace ts { host.getSourceFileLike(fileName); } - function toLineColumnOffset(fileName: string, position: number): LineAndCharacter { + function toLineColumnOffset(fileName: string, position: number): ts.LineAndCharacter { const file = getSourceFileLike(fileName)!; // TODO: GH#18217 return file.getLineAndCharacterOfPosition(position); } @@ -136,20 +137,15 @@ namespace ts { * string | undefined to contents of map file to create DocumentPositionMapper from it * DocumentPositionMapper | false to give back cached DocumentPositionMapper */ - export type ReadMapFile = (mapFileName: string, mapFileNameFromDts: string | undefined) => string | undefined | DocumentPositionMapper | false; - - export function getDocumentPositionMapper( - host: DocumentPositionMapperHost, - generatedFileName: string, - generatedFileLineInfo: LineInfo, - readMapFile: ReadMapFile) { - let mapFileName = tryGetSourceMappingURL(generatedFileLineInfo); + export type ReadMapFile = (mapFileName: string, mapFileNameFromDts: string | undefined) => string | undefined | ts.DocumentPositionMapper | false; + export function getDocumentPositionMapper(host: ts.DocumentPositionMapperHost, generatedFileName: string, generatedFileLineInfo: ts.LineInfo, readMapFile: ReadMapFile) { + let mapFileName = ts.tryGetSourceMappingURL(generatedFileLineInfo); if (mapFileName) { const match = base64UrlRegExp.exec(mapFileName); if (match) { if (match[1]) { const base64Object = match[1]; - return convertDocumentToSourceMapper(host, base64decode(sys, base64Object), generatedFileName); + return convertDocumentToSourceMapper(host, ts.base64decode(ts.sys, base64Object), generatedFileName); } // Not a data URL we can parse, skip it mapFileName = undefined; @@ -160,11 +156,11 @@ namespace ts { possibleMapLocations.push(mapFileName); } possibleMapLocations.push(generatedFileName + ".map"); - const originalMapFileName = mapFileName && getNormalizedAbsolutePath(mapFileName, getDirectoryPath(generatedFileName)); + const originalMapFileName = mapFileName && ts.getNormalizedAbsolutePath(mapFileName, ts.getDirectoryPath(generatedFileName)); for (const location of possibleMapLocations) { - const mapFileName = getNormalizedAbsolutePath(location, getDirectoryPath(generatedFileName)); + const mapFileName = ts.getNormalizedAbsolutePath(location, ts.getDirectoryPath(generatedFileName)); const mapFileContents = readMapFile(mapFileName, originalMapFileName); - if (isString(mapFileContents)) { + if (ts.isString(mapFileContents)) { return convertDocumentToSourceMapper(host, mapFileContents, mapFileName); } if (mapFileContents !== undefined) { @@ -174,25 +170,25 @@ namespace ts { return undefined; } - function convertDocumentToSourceMapper(host: DocumentPositionMapperHost, contents: string, mapFileName: string) { - const map = tryParseRawSourceMap(contents); + function convertDocumentToSourceMapper(host: ts.DocumentPositionMapperHost, contents: string, mapFileName: string) { + const map = ts.tryParseRawSourceMap(contents); if (!map || !map.sources || !map.file || !map.mappings) { // obviously invalid map return undefined; } // Dont support sourcemaps that contain inlined sources - if (map.sourcesContent && map.sourcesContent.some(isString)) return undefined; - - return createDocumentPositionMapper(host, map, mapFileName); + if (map.sourcesContent && map.sourcesContent.some(ts.isString)) + return undefined; + return ts.createDocumentPositionMapper(host, map, mapFileName); } - function createSourceFileLike(text: string, lineMap?: SourceFileLike["lineMap"]): SourceFileLike { + function createSourceFileLike(text: string, lineMap?: ts.SourceFileLike["lineMap"]): ts.SourceFileLike { return { text, lineMap, getLineAndCharacterOfPosition(pos: number) { - return computeLineAndCharacterOfPosition(getLineStarts(this), pos); + return ts.computeLineAndCharacterOfPosition(ts.getLineStarts(this), pos); } }; } diff --git a/src/services/stringCompletions.ts b/src/services/stringCompletions.ts index 604a833742649..e99ceddc3a56d 100644 --- a/src/services/stringCompletions.ts +++ b/src/services/stringCompletions.ts @@ -1,183 +1,160 @@ /* @internal */ namespace ts.Completions.StringCompletions { - export function getStringLiteralCompletions( - sourceFile: SourceFile, - position: number, - contextToken: Node | undefined, - options: CompilerOptions, - host: LanguageServiceHost, - program: Program, - log: Log, - preferences: UserPreferences): CompletionInfo | undefined { - if (isInReferenceComment(sourceFile, position)) { + export function getStringLiteralCompletions(sourceFile: ts.SourceFile, position: number, contextToken: ts.Node | undefined, options: ts.CompilerOptions, host: ts.LanguageServiceHost, program: ts.Program, log: ts.Completions.Log, preferences: ts.UserPreferences): ts.CompletionInfo | undefined { + if (ts.isInReferenceComment(sourceFile, position)) { const entries = getTripleSlashReferenceCompletion(sourceFile, position, options, host); return entries && convertPathCompletions(entries); } - if (isInString(sourceFile, position, contextToken)) { - if (!contextToken || !isStringLiteralLike(contextToken)) return undefined; + if (ts.isInString(sourceFile, position, contextToken)) { + if (!contextToken || !ts.isStringLiteralLike(contextToken)) + return undefined; const entries = getStringLiteralCompletionEntries(sourceFile, contextToken, position, program.getTypeChecker(), options, host, preferences); return convertStringLiteralCompletions(entries, contextToken, sourceFile, host, program, log, options, preferences); } } - function convertStringLiteralCompletions( - completion: StringLiteralCompletion | undefined, - contextToken: StringLiteralLike, - sourceFile: SourceFile, - host: LanguageServiceHost, - program: Program, - log: Log, - options: CompilerOptions, - preferences: UserPreferences, - ): CompletionInfo | undefined { + function convertStringLiteralCompletions(completion: StringLiteralCompletion | undefined, contextToken: ts.StringLiteralLike, sourceFile: ts.SourceFile, host: ts.LanguageServiceHost, program: ts.Program, log: ts.Completions.Log, options: ts.CompilerOptions, preferences: ts.UserPreferences): ts.CompletionInfo | undefined { if (completion === undefined) { return undefined; } - const optionalReplacementSpan = createTextSpanFromStringLiteralLikeContent(contextToken); + const optionalReplacementSpan = ts.createTextSpanFromStringLiteralLikeContent(contextToken); switch (completion.kind) { case StringLiteralCompletionKind.Paths: return convertPathCompletions(completion.paths); case StringLiteralCompletionKind.Properties: { - const entries = createSortedArray(); - getCompletionEntriesFromSymbols( - completion.symbols, - entries, - contextToken, - contextToken, - sourceFile, - sourceFile, - host, - program, - ScriptTarget.ESNext, - log, - CompletionKind.String, - preferences, - options, - /*formatContext*/ undefined, - ); // Target will not be used, so arbitrary + const entries = ts.createSortedArray(); + ts.Completions.getCompletionEntriesFromSymbols(completion.symbols, entries, contextToken, contextToken, sourceFile, sourceFile, host, program, ts.ScriptTarget.ESNext, log, ts.Completions.CompletionKind.String, preferences, options, + /*formatContext*/ undefined); // Target will not be used, so arbitrary return { isGlobalCompletion: false, isMemberCompletion: true, isNewIdentifierLocation: completion.hasIndexSignature, optionalReplacementSpan, entries }; } case StringLiteralCompletionKind.Types: { const entries = completion.types.map(type => ({ name: type.value, - kindModifiers: ScriptElementKindModifier.none, - kind: ScriptElementKind.string, - sortText: SortText.LocationPriority, - replacementSpan: getReplacementSpanForContextToken(contextToken) + kindModifiers: ts.ScriptElementKindModifier.none, + kind: ts.ScriptElementKind.string, + sortText: ts.Completions.SortText.LocationPriority, + replacementSpan: ts.getReplacementSpanForContextToken(contextToken) })); return { isGlobalCompletion: false, isMemberCompletion: false, isNewIdentifierLocation: completion.isNewIdentifier, optionalReplacementSpan, entries }; } default: - return Debug.assertNever(completion); + return ts.Debug.assertNever(completion); } } - export function getStringLiteralCompletionDetails(name: string, sourceFile: SourceFile, position: number, contextToken: Node | undefined, checker: TypeChecker, options: CompilerOptions, host: LanguageServiceHost, cancellationToken: CancellationToken, preferences: UserPreferences) { - if (!contextToken || !isStringLiteralLike(contextToken)) return undefined; + export function getStringLiteralCompletionDetails(name: string, sourceFile: ts.SourceFile, position: number, contextToken: ts.Node | undefined, checker: ts.TypeChecker, options: ts.CompilerOptions, host: ts.LanguageServiceHost, cancellationToken: ts.CancellationToken, preferences: ts.UserPreferences) { + if (!contextToken || !ts.isStringLiteralLike(contextToken)) + return undefined; const completions = getStringLiteralCompletionEntries(sourceFile, contextToken, position, checker, options, host, preferences); return completions && stringLiteralCompletionDetails(name, contextToken, completions, sourceFile, checker, cancellationToken); } - function stringLiteralCompletionDetails(name: string, location: Node, completion: StringLiteralCompletion, sourceFile: SourceFile, checker: TypeChecker, cancellationToken: CancellationToken): CompletionEntryDetails | undefined { + function stringLiteralCompletionDetails(name: string, location: ts.Node, completion: StringLiteralCompletion, sourceFile: ts.SourceFile, checker: ts.TypeChecker, cancellationToken: ts.CancellationToken): ts.CompletionEntryDetails | undefined { switch (completion.kind) { case StringLiteralCompletionKind.Paths: { - const match = find(completion.paths, p => p.name === name); - return match && createCompletionDetails(name, kindModifiersFromExtension(match.extension), match.kind, [textPart(name)]); + const match = ts.find(completion.paths, p => p.name === name); + return match && ts.Completions.createCompletionDetails(name, kindModifiersFromExtension(match.extension), match.kind, [ts.textPart(name)]); } case StringLiteralCompletionKind.Properties: { - const match = find(completion.symbols, s => s.name === name); - return match && createCompletionDetailsForSymbol(match, checker, sourceFile, location, cancellationToken); + const match = ts.find(completion.symbols, s => s.name === name); + return match && ts.Completions.createCompletionDetailsForSymbol(match, checker, sourceFile, location, cancellationToken); } case StringLiteralCompletionKind.Types: - return find(completion.types, t => t.value === name) ? createCompletionDetails(name, ScriptElementKindModifier.none, ScriptElementKind.typeElement, [textPart(name)]) : undefined; + return ts.find(completion.types, t => t.value === name) ? ts.Completions.createCompletionDetails(name, ts.ScriptElementKindModifier.none, ts.ScriptElementKind.typeElement, [ts.textPart(name)]) : undefined; default: - return Debug.assertNever(completion); + return ts.Debug.assertNever(completion); } } - function convertPathCompletions(pathCompletions: readonly PathCompletion[]): CompletionInfo { + function convertPathCompletions(pathCompletions: readonly PathCompletion[]): ts.CompletionInfo { const isGlobalCompletion = false; // We don't want the editor to offer any other completions, such as snippets, inside a comment. const isNewIdentifierLocation = true; // The user may type in a path that doesn't yet exist, creating a "new identifier" with respect to the collection of identifiers the server is aware of. - const entries = pathCompletions.map(({ name, kind, span, extension }): CompletionEntry => - ({ name, kind, kindModifiers: kindModifiersFromExtension(extension), sortText: SortText.LocationPriority, replacementSpan: span })); + const entries = pathCompletions.map(({ name, kind, span, extension }): ts.CompletionEntry => ({ name, kind, kindModifiers: kindModifiersFromExtension(extension), sortText: ts.Completions.SortText.LocationPriority, replacementSpan: span })); return { isGlobalCompletion, isMemberCompletion: false, isNewIdentifierLocation, entries }; } - function kindModifiersFromExtension(extension: Extension | undefined): ScriptElementKindModifier { + function kindModifiersFromExtension(extension: ts.Extension | undefined): ts.ScriptElementKindModifier { switch (extension) { - case Extension.Dts: return ScriptElementKindModifier.dtsModifier; - case Extension.Js: return ScriptElementKindModifier.jsModifier; - case Extension.Json: return ScriptElementKindModifier.jsonModifier; - case Extension.Jsx: return ScriptElementKindModifier.jsxModifier; - case Extension.Ts: return ScriptElementKindModifier.tsModifier; - case Extension.Tsx: return ScriptElementKindModifier.tsxModifier; - case Extension.Dmts: return ScriptElementKindModifier.dmtsModifier; - case Extension.Mjs: return ScriptElementKindModifier.mjsModifier; - case Extension.Mts: return ScriptElementKindModifier.mtsModifier; - case Extension.Dcts: return ScriptElementKindModifier.dctsModifier; - case Extension.Cjs: return ScriptElementKindModifier.cjsModifier; - case Extension.Cts: return ScriptElementKindModifier.ctsModifier; - case Extension.TsBuildInfo: return Debug.fail(`Extension ${Extension.TsBuildInfo} is unsupported.`); - case undefined: return ScriptElementKindModifier.none; + case ts.Extension.Dts: return ts.ScriptElementKindModifier.dtsModifier; + case ts.Extension.Js: return ts.ScriptElementKindModifier.jsModifier; + case ts.Extension.Json: return ts.ScriptElementKindModifier.jsonModifier; + case ts.Extension.Jsx: return ts.ScriptElementKindModifier.jsxModifier; + case ts.Extension.Ts: return ts.ScriptElementKindModifier.tsModifier; + case ts.Extension.Tsx: return ts.ScriptElementKindModifier.tsxModifier; + case ts.Extension.Dmts: return ts.ScriptElementKindModifier.dmtsModifier; + case ts.Extension.Mjs: return ts.ScriptElementKindModifier.mjsModifier; + case ts.Extension.Mts: return ts.ScriptElementKindModifier.mtsModifier; + case ts.Extension.Dcts: return ts.ScriptElementKindModifier.dctsModifier; + case ts.Extension.Cjs: return ts.ScriptElementKindModifier.cjsModifier; + case ts.Extension.Cts: return ts.ScriptElementKindModifier.ctsModifier; + case ts.Extension.TsBuildInfo: return ts.Debug.fail(`Extension ${ts.Extension.TsBuildInfo} is unsupported.`); + case undefined: return ts.ScriptElementKindModifier.none; default: - return Debug.assertNever(extension); + return ts.Debug.assertNever(extension); } } - const enum StringLiteralCompletionKind { Paths, Properties, Types } + const enum StringLiteralCompletionKind { + Paths, + Properties, + Types + } interface StringLiteralCompletionsFromProperties { readonly kind: StringLiteralCompletionKind.Properties; - readonly symbols: readonly Symbol[]; + readonly symbols: readonly ts.Symbol[]; readonly hasIndexSignature: boolean; } interface StringLiteralCompletionsFromTypes { readonly kind: StringLiteralCompletionKind.Types; - readonly types: readonly StringLiteralType[]; + readonly types: readonly ts.StringLiteralType[]; readonly isNewIdentifier: boolean; } - type StringLiteralCompletion = { readonly kind: StringLiteralCompletionKind.Paths, readonly paths: readonly PathCompletion[] } | StringLiteralCompletionsFromProperties | StringLiteralCompletionsFromTypes; - function getStringLiteralCompletionEntries(sourceFile: SourceFile, node: StringLiteralLike, position: number, typeChecker: TypeChecker, compilerOptions: CompilerOptions, host: LanguageServiceHost, preferences: UserPreferences): StringLiteralCompletion | undefined { + type StringLiteralCompletion = { + readonly kind: StringLiteralCompletionKind.Paths; + readonly paths: readonly PathCompletion[]; + } | StringLiteralCompletionsFromProperties | StringLiteralCompletionsFromTypes; + function getStringLiteralCompletionEntries(sourceFile: ts.SourceFile, node: ts.StringLiteralLike, position: number, typeChecker: ts.TypeChecker, compilerOptions: ts.CompilerOptions, host: ts.LanguageServiceHost, preferences: ts.UserPreferences): StringLiteralCompletion | undefined { const parent = walkUpParentheses(node.parent); switch (parent.kind) { - case SyntaxKind.LiteralType: { + case ts.SyntaxKind.LiteralType: { const grandParent = walkUpParentheses(parent.parent); switch (grandParent.kind) { - case SyntaxKind.TypeReference: { - const typeReference = grandParent as TypeReferenceNode; - const typeArgument = findAncestor(parent, n => n.parent === typeReference) as LiteralTypeNode; + case ts.SyntaxKind.TypeReference: { + const typeReference = grandParent as ts.TypeReferenceNode; + const typeArgument = ts.findAncestor(parent, n => n.parent === typeReference) as ts.LiteralTypeNode; if (typeArgument) { return { kind: StringLiteralCompletionKind.Types, types: getStringLiteralTypes(typeChecker.getTypeArgumentConstraint(typeArgument)), isNewIdentifier: false }; } return undefined; } - case SyntaxKind.IndexedAccessType: + case ts.SyntaxKind.IndexedAccessType: // Get all apparent property names // i.e. interface Foo { // foo: string; // bar: string; // } // let x: Foo["/*completion position*/"] - const { indexType, objectType } = grandParent as IndexedAccessTypeNode; - if (!rangeContainsPosition(indexType, position)) { + const { indexType, objectType } = grandParent as ts.IndexedAccessTypeNode; + if (!ts.rangeContainsPosition(indexType, position)) { return undefined; } return stringLiteralCompletionsFromProperties(typeChecker.getTypeFromTypeNode(objectType)); - case SyntaxKind.ImportType: + case ts.SyntaxKind.ImportType: return { kind: StringLiteralCompletionKind.Paths, paths: getStringLiteralCompletionsFromModuleNames(sourceFile, node, compilerOptions, host, typeChecker, preferences) }; - case SyntaxKind.UnionType: { - if (!isTypeReferenceNode(grandParent.parent)) { + case ts.SyntaxKind.UnionType: { + if (!ts.isTypeReferenceNode(grandParent.parent)) { return undefined; } - const alreadyUsedTypes = getAlreadyUsedTypesInStringLiteralUnion(grandParent as UnionTypeNode, parent as LiteralTypeNode); - const types = getStringLiteralTypes(typeChecker.getTypeArgumentConstraint(grandParent as UnionTypeNode)).filter(t => !contains(alreadyUsedTypes, t.value)); + const alreadyUsedTypes = getAlreadyUsedTypesInStringLiteralUnion(grandParent as ts.UnionTypeNode, parent as ts.LiteralTypeNode); + const types = getStringLiteralTypes(typeChecker.getTypeArgumentConstraint(grandParent as ts.UnionTypeNode)).filter(t => !ts.contains(alreadyUsedTypes, t.value)); return { kind: StringLiteralCompletionKind.Types, types, isNewIdentifier: false }; } default: return undefined; } } - case SyntaxKind.PropertyAssignment: - if (isObjectLiteralExpression(parent.parent) && (parent as PropertyAssignment).name === node) { + case ts.SyntaxKind.PropertyAssignment: + if (ts.isObjectLiteralExpression(parent.parent) && (parent as ts.PropertyAssignment).name === node) { // Get quoted name of properties of the object literal expression // i.e. interface ConfigFiles { // 'jspm:dev': string @@ -194,9 +171,9 @@ namespace ts.Completions.StringCompletions { } return fromContextualType(); - case SyntaxKind.ElementAccessExpression: { - const { expression, argumentExpression } = parent as ElementAccessExpression; - if (node === skipParentheses(argumentExpression)) { + case ts.SyntaxKind.ElementAccessExpression: { + const { expression, argumentExpression } = parent as ts.ElementAccessExpression; + if (node === ts.skipParentheses(argumentExpression)) { // Get all names of properties on the expression // i.e. interface A { // 'prop1': string @@ -208,11 +185,11 @@ namespace ts.Completions.StringCompletions { return undefined; } - case SyntaxKind.CallExpression: - case SyntaxKind.NewExpression: - case SyntaxKind.JsxAttribute: - if (!isRequireCallArgument(node) && !isImportCall(parent)) { - const argumentInfo = SignatureHelp.getArgumentInfoForCompletions(parent.kind === SyntaxKind.JsxAttribute ? parent.parent : node, position, sourceFile); + case ts.SyntaxKind.CallExpression: + case ts.SyntaxKind.NewExpression: + case ts.SyntaxKind.JsxAttribute: + if (!isRequireCallArgument(node) && !ts.isImportCall(parent)) { + const argumentInfo = ts.SignatureHelp.getArgumentInfoForCompletions(parent.kind === ts.SyntaxKind.JsxAttribute ? parent.parent : node, position, sourceFile); // Get string literal completions from specialized signatures of the target // i.e. declare function f(a: 'A'); // f("/*completion position*/") @@ -220,9 +197,9 @@ namespace ts.Completions.StringCompletions { } // falls through (is `require("")` or `require(""` or `import("")`) - case SyntaxKind.ImportDeclaration: - case SyntaxKind.ExportDeclaration: - case SyntaxKind.ExternalModuleReference: + case ts.SyntaxKind.ImportDeclaration: + case ts.SyntaxKind.ExportDeclaration: + case ts.SyntaxKind.ExternalModuleReference: // Get all known external module names or complete a path to a module // i.e. import * as ns from "/*completion position*/"; // var y = import("/*completion position*/"); @@ -238,158 +215,151 @@ namespace ts.Completions.StringCompletions { function fromContextualType(): StringLiteralCompletion { // Get completion for string literal from string literal type // i.e. var x: "hi" | "hello" = "/*completion position*/" - return { kind: StringLiteralCompletionKind.Types, types: getStringLiteralTypes(getContextualTypeFromParent(node, typeChecker)), isNewIdentifier: false }; + return { kind: StringLiteralCompletionKind.Types, types: getStringLiteralTypes(ts.getContextualTypeFromParent(node, typeChecker)), isNewIdentifier: false }; } } - function walkUpParentheses(node: Node) { + function walkUpParentheses(node: ts.Node) { switch (node.kind) { - case SyntaxKind.ParenthesizedType: - return walkUpParenthesizedTypes(node); - case SyntaxKind.ParenthesizedExpression: - return walkUpParenthesizedExpressions(node); + case ts.SyntaxKind.ParenthesizedType: + return ts.walkUpParenthesizedTypes(node); + case ts.SyntaxKind.ParenthesizedExpression: + return ts.walkUpParenthesizedExpressions(node); default: return node; } } - function getAlreadyUsedTypesInStringLiteralUnion(union: UnionTypeNode, current: LiteralTypeNode): readonly string[] { - return mapDefined(union.types, type => - type !== current && isLiteralTypeNode(type) && isStringLiteral(type.literal) ? type.literal.text : undefined); + function getAlreadyUsedTypesInStringLiteralUnion(union: ts.UnionTypeNode, current: ts.LiteralTypeNode): readonly string[] { + return ts.mapDefined(union.types, type => type !== current && ts.isLiteralTypeNode(type) && ts.isStringLiteral(type.literal) ? type.literal.text : undefined); } - function getStringLiteralCompletionsFromSignature(call: CallLikeExpression, arg: StringLiteralLike, argumentInfo: SignatureHelp.ArgumentInfoForCompletions, checker: TypeChecker): StringLiteralCompletionsFromTypes { + function getStringLiteralCompletionsFromSignature(call: ts.CallLikeExpression, arg: ts.StringLiteralLike, argumentInfo: ts.SignatureHelp.ArgumentInfoForCompletions, checker: ts.TypeChecker): StringLiteralCompletionsFromTypes { let isNewIdentifier = false; - const uniques = new Map(); - const candidates: Signature[] = []; - const editingArgument = isJsxOpeningLikeElement(call) ? Debug.checkDefined(findAncestor(arg.parent, isJsxAttribute)) : arg; + const uniques = new ts.Map(); + const candidates: ts.Signature[] = []; + const editingArgument = ts.isJsxOpeningLikeElement(call) ? ts.Debug.checkDefined(ts.findAncestor(arg.parent, ts.isJsxAttribute)) : arg; checker.getResolvedSignatureForStringLiteralCompletions(call, editingArgument, candidates); - const types = flatMap(candidates, candidate => { - if (!signatureHasRestParameter(candidate) && argumentInfo.argumentCount > candidate.parameters.length) return; + const types = ts.flatMap(candidates, candidate => { + if (!ts.signatureHasRestParameter(candidate) && argumentInfo.argumentCount > candidate.parameters.length) + return; let type = candidate.getTypeParameterAtPosition(argumentInfo.argumentIndex); - if (isJsxOpeningLikeElement(call)) { - const propType = checker.getTypeOfPropertyOfType(type, (editingArgument as JsxAttribute).name.text); + if (ts.isJsxOpeningLikeElement(call)) { + const propType = checker.getTypeOfPropertyOfType(type, (editingArgument as ts.JsxAttribute).name.text); if (propType) { type = propType; } } - isNewIdentifier = isNewIdentifier || !!(type.flags & TypeFlags.String); + isNewIdentifier = isNewIdentifier || !!(type.flags & ts.TypeFlags.String); return getStringLiteralTypes(type, uniques); }); return { kind: StringLiteralCompletionKind.Types, types, isNewIdentifier }; } - function stringLiteralCompletionsFromProperties(type: Type | undefined): StringLiteralCompletionsFromProperties | undefined { + function stringLiteralCompletionsFromProperties(type: ts.Type | undefined): StringLiteralCompletionsFromProperties | undefined { return type && { kind: StringLiteralCompletionKind.Properties, - symbols: filter(type.getApparentProperties(), prop => !(prop.valueDeclaration && isPrivateIdentifierClassElementDeclaration(prop.valueDeclaration))), - hasIndexSignature: hasIndexSignature(type) + symbols: ts.filter(type.getApparentProperties(), prop => !(prop.valueDeclaration && ts.isPrivateIdentifierClassElementDeclaration(prop.valueDeclaration))), + hasIndexSignature: ts.hasIndexSignature(type) }; } - function stringLiteralCompletionsForObjectLiteral(checker: TypeChecker, objectLiteralExpression: ObjectLiteralExpression): StringLiteralCompletionsFromProperties | undefined { + function stringLiteralCompletionsForObjectLiteral(checker: ts.TypeChecker, objectLiteralExpression: ts.ObjectLiteralExpression): StringLiteralCompletionsFromProperties | undefined { const contextualType = checker.getContextualType(objectLiteralExpression); - if (!contextualType) return undefined; - - const completionsType = checker.getContextualType(objectLiteralExpression, ContextFlags.Completions); - const symbols = getPropertiesForObjectExpression( - contextualType, - completionsType, - objectLiteralExpression, - checker - ); + if (!contextualType) + return undefined; + const completionsType = checker.getContextualType(objectLiteralExpression, ts.ContextFlags.Completions); + const symbols = ts.Completions.getPropertiesForObjectExpression(contextualType, completionsType, objectLiteralExpression, checker); return { kind: StringLiteralCompletionKind.Properties, symbols, - hasIndexSignature: hasIndexSignature(contextualType) + hasIndexSignature: ts.hasIndexSignature(contextualType) }; } - function getStringLiteralTypes(type: Type | undefined, uniques = new Map()): readonly StringLiteralType[] { - if (!type) return emptyArray; - type = skipConstraint(type); - return type.isUnion() ? flatMap(type.types, t => getStringLiteralTypes(t, uniques)) : - type.isStringLiteral() && !(type.flags & TypeFlags.EnumLiteral) && addToSeen(uniques, type.value) ? [type] : emptyArray; + function getStringLiteralTypes(type: ts.Type | undefined, uniques = new ts.Map()): readonly ts.StringLiteralType[] { + if (!type) + return ts.emptyArray; + type = ts.skipConstraint(type); + return type.isUnion() ? ts.flatMap(type.types, t => getStringLiteralTypes(t, uniques)) : + type.isStringLiteral() && !(type.flags & ts.TypeFlags.EnumLiteral) && ts.addToSeen(uniques, type.value) ? [type] : ts.emptyArray; } interface NameAndKind { readonly name: string; - readonly kind: ScriptElementKind.scriptElement | ScriptElementKind.directory | ScriptElementKind.externalModuleName; - readonly extension: Extension | undefined; + readonly kind: ts.ScriptElementKind.scriptElement | ts.ScriptElementKind.directory | ts.ScriptElementKind.externalModuleName; + readonly extension: ts.Extension | undefined; } interface PathCompletion extends NameAndKind { - readonly span: TextSpan | undefined; + readonly span: ts.TextSpan | undefined; } - function nameAndKind(name: string, kind: NameAndKind["kind"], extension: Extension | undefined): NameAndKind { + function nameAndKind(name: string, kind: NameAndKind["kind"], extension: ts.Extension | undefined): NameAndKind { return { name, kind, extension }; } function directoryResult(name: string): NameAndKind { - return nameAndKind(name, ScriptElementKind.directory, /*extension*/ undefined); + return nameAndKind(name, ts.ScriptElementKind.directory, /*extension*/ undefined); } function addReplacementSpans(text: string, textStart: number, names: readonly NameAndKind[]): readonly PathCompletion[] { const span = getDirectoryFragmentTextSpan(text, textStart); - const wholeSpan = text.length === 0 ? undefined : createTextSpan(textStart, text.length); - return names.map(({ name, kind, extension }): PathCompletion => - Math.max(name.indexOf(directorySeparator), name.indexOf(altDirectorySeparator)) !== -1 ? { name, kind, extension, span: wholeSpan } : { name, kind, extension, span }); + const wholeSpan = text.length === 0 ? undefined : ts.createTextSpan(textStart, text.length); + return names.map(({ name, kind, extension }): PathCompletion => Math.max(name.indexOf(ts.directorySeparator), name.indexOf(ts.altDirectorySeparator)) !== -1 ? { name, kind, extension, span: wholeSpan } : { name, kind, extension, span }); } - function getStringLiteralCompletionsFromModuleNames(sourceFile: SourceFile, node: LiteralExpression, compilerOptions: CompilerOptions, host: LanguageServiceHost, typeChecker: TypeChecker, preferences: UserPreferences): readonly PathCompletion[] { + function getStringLiteralCompletionsFromModuleNames(sourceFile: ts.SourceFile, node: ts.LiteralExpression, compilerOptions: ts.CompilerOptions, host: ts.LanguageServiceHost, typeChecker: ts.TypeChecker, preferences: ts.UserPreferences): readonly PathCompletion[] { return addReplacementSpans(node.text, node.getStart(sourceFile) + 1, getStringLiteralCompletionsFromModuleNamesWorker(sourceFile, node, compilerOptions, host, typeChecker, preferences)); } - function getStringLiteralCompletionsFromModuleNamesWorker(sourceFile: SourceFile, node: LiteralExpression, compilerOptions: CompilerOptions, host: LanguageServiceHost, typeChecker: TypeChecker, preferences: UserPreferences): readonly NameAndKind[] { - const literalValue = normalizeSlashes(node.text); + function getStringLiteralCompletionsFromModuleNamesWorker(sourceFile: ts.SourceFile, node: ts.LiteralExpression, compilerOptions: ts.CompilerOptions, host: ts.LanguageServiceHost, typeChecker: ts.TypeChecker, preferences: ts.UserPreferences): readonly NameAndKind[] { + const literalValue = ts.normalizeSlashes(node.text); const scriptPath = sourceFile.path; - const scriptDirectory = getDirectoryPath(scriptPath); - - return isPathRelativeToScript(literalValue) || !compilerOptions.baseUrl && (isRootedDiskPath(literalValue) || isUrl(literalValue)) + const scriptDirectory = ts.getDirectoryPath(scriptPath); + return isPathRelativeToScript(literalValue) || !compilerOptions.baseUrl && (ts.isRootedDiskPath(literalValue) || ts.isUrl(literalValue)) ? getCompletionEntriesForRelativeModules(literalValue, scriptDirectory, compilerOptions, host, scriptPath, getIncludeExtensionOption()) : getCompletionEntriesForNonRelativeModules(literalValue, scriptDirectory, compilerOptions, host, typeChecker); function getIncludeExtensionOption() { - const mode = isStringLiteralLike(node) ? getModeForUsageLocation(sourceFile, node) : undefined; - return preferences.importModuleSpecifierEnding === "js" || mode === ModuleKind.ESNext ? IncludeExtensionsOption.ModuleSpecifierCompletion : IncludeExtensionsOption.Exclude; + const mode = ts.isStringLiteralLike(node) ? ts.getModeForUsageLocation(sourceFile, node) : undefined; + return preferences.importModuleSpecifierEnding === "js" || mode === ts.ModuleKind.ESNext ? IncludeExtensionsOption.ModuleSpecifierCompletion : IncludeExtensionsOption.Exclude; } } interface ExtensionOptions { - readonly extensions: readonly Extension[]; + readonly extensions: readonly ts.Extension[]; readonly includeExtensionsOption: IncludeExtensionsOption; } - function getExtensionOptions(compilerOptions: CompilerOptions, includeExtensionsOption = IncludeExtensionsOption.Exclude): ExtensionOptions { - return { extensions: flatten(getSupportedExtensionsForModuleResolution(compilerOptions)), includeExtensionsOption }; + function getExtensionOptions(compilerOptions: ts.CompilerOptions, includeExtensionsOption = IncludeExtensionsOption.Exclude): ExtensionOptions { + return { extensions: ts.flatten(getSupportedExtensionsForModuleResolution(compilerOptions)), includeExtensionsOption }; } - function getCompletionEntriesForRelativeModules(literalValue: string, scriptDirectory: string, compilerOptions: CompilerOptions, host: LanguageServiceHost, scriptPath: Path, includeExtensions: IncludeExtensionsOption) { + function getCompletionEntriesForRelativeModules(literalValue: string, scriptDirectory: string, compilerOptions: ts.CompilerOptions, host: ts.LanguageServiceHost, scriptPath: ts.Path, includeExtensions: IncludeExtensionsOption) { const extensionOptions = getExtensionOptions(compilerOptions, includeExtensions); if (compilerOptions.rootDirs) { - return getCompletionEntriesForDirectoryFragmentWithRootDirs( - compilerOptions.rootDirs, literalValue, scriptDirectory, extensionOptions, compilerOptions, host, scriptPath); + return getCompletionEntriesForDirectoryFragmentWithRootDirs(compilerOptions.rootDirs, literalValue, scriptDirectory, extensionOptions, compilerOptions, host, scriptPath); } else { return getCompletionEntriesForDirectoryFragment(literalValue, scriptDirectory, extensionOptions, host, scriptPath); } } - function isEmitResolutionKindUsingNodeModules(compilerOptions: CompilerOptions): boolean { - return getEmitModuleResolutionKind(compilerOptions) === ModuleResolutionKind.NodeJs || - getEmitModuleResolutionKind(compilerOptions) === ModuleResolutionKind.Node16 || - getEmitModuleResolutionKind(compilerOptions) === ModuleResolutionKind.NodeNext; + function isEmitResolutionKindUsingNodeModules(compilerOptions: ts.CompilerOptions): boolean { + return ts.getEmitModuleResolutionKind(compilerOptions) === ts.ModuleResolutionKind.NodeJs || + ts.getEmitModuleResolutionKind(compilerOptions) === ts.ModuleResolutionKind.Node16 || + ts.getEmitModuleResolutionKind(compilerOptions) === ts.ModuleResolutionKind.NodeNext; } - function isEmitModuleResolutionRespectingExportMaps(compilerOptions: CompilerOptions) { - return getEmitModuleResolutionKind(compilerOptions) === ModuleResolutionKind.Node16 || - getEmitModuleResolutionKind(compilerOptions) === ModuleResolutionKind.NodeNext; + function isEmitModuleResolutionRespectingExportMaps(compilerOptions: ts.CompilerOptions) { + return ts.getEmitModuleResolutionKind(compilerOptions) === ts.ModuleResolutionKind.Node16 || + ts.getEmitModuleResolutionKind(compilerOptions) === ts.ModuleResolutionKind.NodeNext; } - function getSupportedExtensionsForModuleResolution(compilerOptions: CompilerOptions): readonly Extension[][] { - const extensions = getSupportedExtensions(compilerOptions); + function getSupportedExtensionsForModuleResolution(compilerOptions: ts.CompilerOptions): readonly ts.Extension[][] { + const extensions = ts.getSupportedExtensions(compilerOptions); return isEmitResolutionKindUsingNodeModules(compilerOptions) ? - getSupportedExtensionsWithJsonIfResolveJsonModule(compilerOptions, extensions) : + ts.getSupportedExtensionsWithJsonIfResolveJsonModule(compilerOptions, extensions) : extensions; } @@ -399,64 +369,61 @@ namespace ts.Completions.StringCompletions { */ function getBaseDirectoriesFromRootDirs(rootDirs: string[], basePath: string, scriptDirectory: string, ignoreCase: boolean): readonly string[] { // Make all paths absolute/normalized if they are not already - rootDirs = rootDirs.map(rootDirectory => normalizePath(isRootedDiskPath(rootDirectory) ? rootDirectory : combinePaths(basePath, rootDirectory))); + rootDirs = rootDirs.map(rootDirectory => ts.normalizePath(ts.isRootedDiskPath(rootDirectory) ? rootDirectory : ts.combinePaths(basePath, rootDirectory))); // Determine the path to the directory containing the script relative to the root directory it is contained within - const relativeDirectory = firstDefined(rootDirs, rootDirectory => - containsPath(rootDirectory, scriptDirectory, basePath, ignoreCase) ? scriptDirectory.substr(rootDirectory.length) : undefined)!; // TODO: GH#18217 + const relativeDirectory = ts.firstDefined(rootDirs, rootDirectory => ts.containsPath(rootDirectory, scriptDirectory, basePath, ignoreCase) ? scriptDirectory.substr(rootDirectory.length) : undefined)!; // TODO: GH#18217 // Now find a path for each potential directory that is to be merged with the one containing the script - return deduplicate( - [...rootDirs.map(rootDirectory => combinePaths(rootDirectory, relativeDirectory)), scriptDirectory], - equateStringsCaseSensitive, - compareStringsCaseSensitive); + return ts.deduplicate([...rootDirs.map(rootDirectory => ts.combinePaths(rootDirectory, relativeDirectory)), scriptDirectory], ts.equateStringsCaseSensitive, ts.compareStringsCaseSensitive); } - function getCompletionEntriesForDirectoryFragmentWithRootDirs(rootDirs: string[], fragment: string, scriptDirectory: string, extensionOptions: ExtensionOptions, compilerOptions: CompilerOptions, host: LanguageServiceHost, exclude: string): readonly NameAndKind[] { + function getCompletionEntriesForDirectoryFragmentWithRootDirs(rootDirs: string[], fragment: string, scriptDirectory: string, extensionOptions: ExtensionOptions, compilerOptions: ts.CompilerOptions, host: ts.LanguageServiceHost, exclude: string): readonly NameAndKind[] { const basePath = compilerOptions.project || host.getCurrentDirectory(); const ignoreCase = !(host.useCaseSensitiveFileNames && host.useCaseSensitiveFileNames()); const baseDirectories = getBaseDirectoriesFromRootDirs(rootDirs, basePath, scriptDirectory, ignoreCase); - return flatMap(baseDirectories, baseDirectory => getCompletionEntriesForDirectoryFragment(fragment, baseDirectory, extensionOptions, host, exclude)); + return ts.flatMap(baseDirectories, baseDirectory => getCompletionEntriesForDirectoryFragment(fragment, baseDirectory, extensionOptions, host, exclude)); } const enum IncludeExtensionsOption { Exclude, Include, - ModuleSpecifierCompletion, + ModuleSpecifierCompletion } /** * Given a path ending at a directory, gets the completions for the path, and filters for those entries containing the basename. */ - function getCompletionEntriesForDirectoryFragment(fragment: string, scriptPath: string, { extensions, includeExtensionsOption }: ExtensionOptions, host: LanguageServiceHost, exclude?: string, result: NameAndKind[] = []): NameAndKind[] { + function getCompletionEntriesForDirectoryFragment(fragment: string, scriptPath: string, { extensions, includeExtensionsOption }: ExtensionOptions, host: ts.LanguageServiceHost, exclude?: string, result: NameAndKind[] = []): NameAndKind[] { if (fragment === undefined) { fragment = ""; } - fragment = normalizeSlashes(fragment); + fragment = ts.normalizeSlashes(fragment); /** * Remove the basename from the path. Note that we don't use the basename to filter completions; * the client is responsible for refining completions. */ - if (!hasTrailingDirectorySeparator(fragment)) { - fragment = getDirectoryPath(fragment); + if (!ts.hasTrailingDirectorySeparator(fragment)) { + fragment = ts.getDirectoryPath(fragment); } if (fragment === "") { - fragment = "." + directorySeparator; + fragment = "." + ts.directorySeparator; } - fragment = ensureTrailingDirectorySeparator(fragment); + fragment = ts.ensureTrailingDirectorySeparator(fragment); // const absolutePath = normalizeAndPreserveTrailingSlash(isRootedDiskPath(fragment) ? fragment : combinePaths(scriptPath, fragment)); // TODO(rbuckton): should use resolvePaths - const absolutePath = resolvePath(scriptPath, fragment); - const baseDirectory = hasTrailingDirectorySeparator(absolutePath) ? absolutePath : getDirectoryPath(absolutePath); + const absolutePath = ts.resolvePath(scriptPath, fragment); + const baseDirectory = ts.hasTrailingDirectorySeparator(absolutePath) ? absolutePath : ts.getDirectoryPath(absolutePath); const ignoreCase = !(host.useCaseSensitiveFileNames && host.useCaseSensitiveFileNames()); - if (!tryDirectoryExists(host, baseDirectory)) return result; + if (!ts.tryDirectoryExists(host, baseDirectory)) + return result; // Enumerate the available files if possible - const files = tryReadDirectory(host, baseDirectory, extensions, /*exclude*/ undefined, /*include*/ ["./*"]); + const files = ts.tryReadDirectory(host, baseDirectory, extensions, /*exclude*/ undefined, /*include*/ ["./*"]); if (files) { /** @@ -465,40 +432,40 @@ namespace ts.Completions.StringCompletions { * * both foo.ts and foo.tsx become foo */ - const foundFiles = new Map(); // maps file to its extension + const foundFiles = new ts.Map(); // maps file to its extension for (let filePath of files) { - filePath = normalizePath(filePath); - if (exclude && comparePaths(filePath, exclude, scriptPath, ignoreCase) === Comparison.EqualTo) { + filePath = ts.normalizePath(filePath); + if (exclude && ts.comparePaths(filePath, exclude, scriptPath, ignoreCase) === ts.Comparison.EqualTo) { continue; } let foundFileName: string; - const outputExtension = moduleSpecifiers.tryGetJSExtensionForFile(filePath, host.getCompilationSettings()); - if (includeExtensionsOption === IncludeExtensionsOption.Exclude && !fileExtensionIsOneOf(filePath, [Extension.Json, Extension.Mts, Extension.Cts, Extension.Dmts, Extension.Dcts, Extension.Mjs, Extension.Cjs])) { - foundFileName = removeFileExtension(getBaseFileName(filePath)); - foundFiles.set(foundFileName, tryGetExtensionFromPath(filePath)); + const outputExtension = ts.moduleSpecifiers.tryGetJSExtensionForFile(filePath, host.getCompilationSettings()); + if (includeExtensionsOption === IncludeExtensionsOption.Exclude && !ts.fileExtensionIsOneOf(filePath, [ts.Extension.Json, ts.Extension.Mts, ts.Extension.Cts, ts.Extension.Dmts, ts.Extension.Dcts, ts.Extension.Mjs, ts.Extension.Cjs])) { + foundFileName = ts.removeFileExtension(ts.getBaseFileName(filePath)); + foundFiles.set(foundFileName, ts.tryGetExtensionFromPath(filePath)); } - else if ((fileExtensionIsOneOf(filePath, [Extension.Mts, Extension.Cts, Extension.Dmts, Extension.Dcts, Extension.Mjs, Extension.Cjs]) || includeExtensionsOption === IncludeExtensionsOption.ModuleSpecifierCompletion) && outputExtension) { - foundFileName = changeExtension(getBaseFileName(filePath), outputExtension); + else if ((ts.fileExtensionIsOneOf(filePath, [ts.Extension.Mts, ts.Extension.Cts, ts.Extension.Dmts, ts.Extension.Dcts, ts.Extension.Mjs, ts.Extension.Cjs]) || includeExtensionsOption === IncludeExtensionsOption.ModuleSpecifierCompletion) && outputExtension) { + foundFileName = ts.changeExtension(ts.getBaseFileName(filePath), outputExtension); foundFiles.set(foundFileName, outputExtension); } else { - foundFileName = getBaseFileName(filePath); - foundFiles.set(foundFileName, tryGetExtensionFromPath(filePath)); + foundFileName = ts.getBaseFileName(filePath); + foundFiles.set(foundFileName, ts.tryGetExtensionFromPath(filePath)); } } foundFiles.forEach((ext, foundFile) => { - result.push(nameAndKind(foundFile, ScriptElementKind.scriptElement, ext)); + result.push(nameAndKind(foundFile, ts.ScriptElementKind.scriptElement, ext)); }); } // If possible, get folder completion as well - const directories = tryGetDirectories(host, baseDirectory); + const directories = ts.tryGetDirectories(host, baseDirectory); if (directories) { for (const directory of directories) { - const directoryName = getBaseFileName(normalizePath(directory)); + const directoryName = ts.getBaseFileName(ts.normalizePath(directory)); if (directoryName !== "@types") { result.push(directoryResult(directoryName)); } @@ -506,14 +473,16 @@ namespace ts.Completions.StringCompletions { } // check for a version redirect - const packageJsonPath = findPackageJson(baseDirectory, host); + const packageJsonPath = ts.findPackageJson(baseDirectory, host); if (packageJsonPath) { - const packageJson = readJson(packageJsonPath, host as { readFile: (filename: string) => string | undefined }); + const packageJson = ts.readJson(packageJsonPath, host as { + readFile: (filename: string) => string | undefined; + }); const typesVersions = (packageJson as any).typesVersions; if (typeof typesVersions === "object") { - const versionResult = getPackageJsonTypesVersionsPaths(typesVersions); + const versionResult = ts.getPackageJsonTypesVersionsPaths(typesVersions); const versionPaths = versionResult && versionResult.paths; - const rest = absolutePath.slice(ensureTrailingDirectorySeparator(baseDirectory).length); + const rest = absolutePath.slice(ts.ensureTrailingDirectorySeparator(baseDirectory).length); if (versionPaths) { addCompletionEntriesFromPaths(result, rest, baseDirectory, extensions, versionPaths, host); } @@ -523,9 +492,10 @@ namespace ts.Completions.StringCompletions { return result; } - function addCompletionEntriesFromPaths(result: NameAndKind[], fragment: string, baseDirectory: string, fileExtensions: readonly string[], paths: MapLike, host: LanguageServiceHost) { + function addCompletionEntriesFromPaths(result: NameAndKind[], fragment: string, baseDirectory: string, fileExtensions: readonly string[], paths: ts.MapLike, host: ts.LanguageServiceHost) { for (const path in paths) { - if (!hasProperty(paths, path)) continue; + if (!ts.hasProperty(paths, path)) + continue; const patterns = paths[path]; if (patterns) { for (const { name, kind, extension } of getCompletionsForPathMapping(path, patterns, fragment, baseDirectory, fileExtensions, host)) { @@ -545,7 +515,7 @@ namespace ts.Completions.StringCompletions { * Modules from node_modules (i.e. those listed in package.json) * This includes all files that are found in node_modules/moduleName/ with acceptable file extensions */ - function getCompletionEntriesForNonRelativeModules(fragment: string, scriptPath: string, compilerOptions: CompilerOptions, host: LanguageServiceHost, typeChecker: TypeChecker): readonly NameAndKind[] { + function getCompletionEntriesForNonRelativeModules(fragment: string, scriptPath: string, compilerOptions: ts.CompilerOptions, host: ts.LanguageServiceHost, typeChecker: ts.TypeChecker): readonly NameAndKind[] { const { baseUrl, paths } = compilerOptions; const result: NameAndKind[] = []; @@ -553,7 +523,7 @@ namespace ts.Completions.StringCompletions { const extensionOptions = getExtensionOptions(compilerOptions); if (baseUrl) { const projectDir = compilerOptions.project || host.getCurrentDirectory(); - const absolute = normalizePath(combinePaths(projectDir, baseUrl)); + const absolute = ts.normalizePath(ts.combinePaths(projectDir, baseUrl)); getCompletionEntriesForDirectoryFragment(fragment, absolute, extensionOptions, host, /*exclude*/ undefined, result); if (paths) { addCompletionEntriesFromPaths(result, fragment, absolute, extensionOptions.extensions, paths, host); @@ -562,7 +532,7 @@ namespace ts.Completions.StringCompletions { const fragmentDirectory = getFragmentDirectory(fragment); for (const ambientName of getAmbientModuleCompletions(fragment, fragmentDirectory, typeChecker)) { - result.push(nameAndKind(ambientName, ScriptElementKind.externalModuleName, /*extension*/ undefined)); + result.push(nameAndKind(ambientName, ts.ScriptElementKind.externalModuleName, /*extension*/ undefined)); } getCompletionEntriesFromTypings(host, compilerOptions, scriptPath, fragmentDirectory, extensionOptions, result); @@ -575,50 +545,55 @@ namespace ts.Completions.StringCompletions { for (const moduleName of enumerateNodeModulesVisibleToScript(host, scriptPath)) { if (!result.some(entry => entry.name === moduleName)) { foundGlobal = true; - result.push(nameAndKind(moduleName, ScriptElementKind.externalModuleName, /*extension*/ undefined)); + result.push(nameAndKind(moduleName, ts.ScriptElementKind.externalModuleName, /*extension*/ undefined)); } } } if (!foundGlobal) { let ancestorLookup: (directory: string) => void | undefined = ancestor => { - const nodeModules = combinePaths(ancestor, "node_modules"); - if (tryDirectoryExists(host, nodeModules)) { + const nodeModules = ts.combinePaths(ancestor, "node_modules"); + if (ts.tryDirectoryExists(host, nodeModules)) { getCompletionEntriesForDirectoryFragment(fragment, nodeModules, extensionOptions, host, /*exclude*/ undefined, result); } }; if (fragmentDirectory && isEmitModuleResolutionRespectingExportMaps(compilerOptions)) { const nodeModulesDirectoryLookup = ancestorLookup; ancestorLookup = ancestor => { - const components = getPathComponents(fragment); + const components = ts.getPathComponents(fragment); components.shift(); // shift off empty root let packagePath = components.shift(); if (!packagePath) { return nodeModulesDirectoryLookup(ancestor); } - if (startsWith(packagePath, "@")) { + if (ts.startsWith(packagePath, "@")) { const subName = components.shift(); if (!subName) { return nodeModulesDirectoryLookup(ancestor); } - packagePath = combinePaths(packagePath, subName); + packagePath = ts.combinePaths(packagePath, subName); } - const packageFile = combinePaths(ancestor, "node_modules", packagePath, "package.json"); - if (tryFileExists(host, packageFile)) { - const packageJson = readJson(packageFile, host as { readFile: (filename: string) => string | undefined }); + const packageFile = ts.combinePaths(ancestor, "node_modules", packagePath, "package.json"); + if (ts.tryFileExists(host, packageFile)) { + const packageJson = ts.readJson(packageFile, host as { + readFile: (filename: string) => string | undefined; + }); const exports = (packageJson as any).exports; if (exports) { if (typeof exports !== "object" || exports === null) { // eslint-disable-line no-null/no-null return; // null exports or entrypoint only, no sub-modules available } - const keys = getOwnKeys(exports); + const keys = ts.getOwnKeys(exports); const fragmentSubpath = components.join("/"); - const processedKeys = mapDefined(keys, k => { - if (k === ".") return undefined; - if (!startsWith(k, "./")) return undefined; + const processedKeys = ts.mapDefined(keys, k => { + if (k === ".") + return undefined; + if (!ts.startsWith(k, "./")) + return undefined; const subpath = k.substring(2); - if (!startsWith(subpath, fragmentSubpath)) return undefined; + if (!ts.startsWith(subpath, fragmentSubpath)) + return undefined; // subpath is a valid export (barring conditions, which we don't currently check here) - if (!stringContains(subpath, "*")) { + if (!ts.stringContains(subpath, "*")) { return subpath; } // pattern export - only return everything up to the `*`, so the user can autocomplete, then @@ -627,9 +602,9 @@ namespace ts.Completions.StringCompletions { // options for the `*`. return subpath.slice(0, subpath.indexOf("*")); }); - forEach(processedKeys, k => { + ts.forEach(processedKeys, k => { if (k) { - result.push(nameAndKind(k, ScriptElementKind.externalModuleName, /*extension*/ undefined)); + result.push(nameAndKind(k, ts.ScriptElementKind.externalModuleName, /*extension*/ undefined)); } }); return; @@ -638,7 +613,7 @@ namespace ts.Completions.StringCompletions { return nodeModulesDirectoryLookup(ancestor); }; } - forEachAncestorDirectory(scriptPath, ancestorLookup); + ts.forEachAncestorDirectory(scriptPath, ancestorLookup); } } @@ -646,103 +621,99 @@ namespace ts.Completions.StringCompletions { } function getFragmentDirectory(fragment: string): string | undefined { - return containsSlash(fragment) ? hasTrailingDirectorySeparator(fragment) ? fragment : getDirectoryPath(fragment) : undefined; + return containsSlash(fragment) ? ts.hasTrailingDirectorySeparator(fragment) ? fragment : ts.getDirectoryPath(fragment) : undefined; } - function getCompletionsForPathMapping( - path: string, patterns: readonly string[], fragment: string, baseUrl: string, fileExtensions: readonly string[], host: LanguageServiceHost, - ): readonly NameAndKind[] { - if (!endsWith(path, "*")) { + function getCompletionsForPathMapping(path: string, patterns: readonly string[], fragment: string, baseUrl: string, fileExtensions: readonly string[], host: ts.LanguageServiceHost): readonly NameAndKind[] { + if (!ts.endsWith(path, "*")) { // For a path mapping "foo": ["/x/y/z.ts"], add "foo" itself as a completion. - return !stringContains(path, "*") ? justPathMappingName(path) : emptyArray; + return !ts.stringContains(path, "*") ? justPathMappingName(path) : ts.emptyArray; } const pathPrefix = path.slice(0, path.length - 1); - const remainingFragment = tryRemovePrefix(fragment, pathPrefix); - return remainingFragment === undefined ? justPathMappingName(pathPrefix) : flatMap(patterns, pattern => - getModulesForPathsPattern(remainingFragment, baseUrl, pattern, fileExtensions, host)); + const remainingFragment = ts.tryRemovePrefix(fragment, pathPrefix); + return remainingFragment === undefined ? justPathMappingName(pathPrefix) : ts.flatMap(patterns, pattern => getModulesForPathsPattern(remainingFragment, baseUrl, pattern, fileExtensions, host)); function justPathMappingName(name: string): readonly NameAndKind[] { - return startsWith(name, fragment) ? [directoryResult(name)] : emptyArray; + return ts.startsWith(name, fragment) ? [directoryResult(name)] : ts.emptyArray; } } - function getModulesForPathsPattern(fragment: string, baseUrl: string, pattern: string, fileExtensions: readonly string[], host: LanguageServiceHost): readonly NameAndKind[] | undefined { + function getModulesForPathsPattern(fragment: string, baseUrl: string, pattern: string, fileExtensions: readonly string[], host: ts.LanguageServiceHost): readonly NameAndKind[] | undefined { if (!host.readDirectory) { return undefined; } - const parsed = tryParsePattern(pattern); - if (parsed === undefined || isString(parsed)) { + const parsed = ts.tryParsePattern(pattern); + if (parsed === undefined || ts.isString(parsed)) { return undefined; } // The prefix has two effective parts: the directory path and the base component after the filepath that is not a // full directory component. For example: directory/path/of/prefix/base* - const normalizedPrefix = resolvePath(parsed.prefix); - const normalizedPrefixDirectory = hasTrailingDirectorySeparator(parsed.prefix) ? normalizedPrefix : getDirectoryPath(normalizedPrefix); - const normalizedPrefixBase = hasTrailingDirectorySeparator(parsed.prefix) ? "" : getBaseFileName(normalizedPrefix); + const normalizedPrefix = ts.resolvePath(parsed.prefix); + const normalizedPrefixDirectory = ts.hasTrailingDirectorySeparator(parsed.prefix) ? normalizedPrefix : ts.getDirectoryPath(normalizedPrefix); + const normalizedPrefixBase = ts.hasTrailingDirectorySeparator(parsed.prefix) ? "" : ts.getBaseFileName(normalizedPrefix); const fragmentHasPath = containsSlash(fragment); - const fragmentDirectory = fragmentHasPath ? hasTrailingDirectorySeparator(fragment) ? fragment : getDirectoryPath(fragment) : undefined; + const fragmentDirectory = fragmentHasPath ? ts.hasTrailingDirectorySeparator(fragment) ? fragment : ts.getDirectoryPath(fragment) : undefined; // Try and expand the prefix to include any path from the fragment so that we can limit the readDirectory call - const expandedPrefixDirectory = fragmentHasPath ? combinePaths(normalizedPrefixDirectory, normalizedPrefixBase + fragmentDirectory) : normalizedPrefixDirectory; - - const normalizedSuffix = normalizePath(parsed.suffix); + const expandedPrefixDirectory = fragmentHasPath ? ts.combinePaths(normalizedPrefixDirectory, normalizedPrefixBase + fragmentDirectory) : normalizedPrefixDirectory; + const normalizedSuffix = ts.normalizePath(parsed.suffix); // Need to normalize after combining: If we combinePaths("a", "../b"), we want "b" and not "a/../b". - const baseDirectory = normalizePath(combinePaths(baseUrl, expandedPrefixDirectory)); - const completePrefix = fragmentHasPath ? baseDirectory : ensureTrailingDirectorySeparator(baseDirectory) + normalizedPrefixBase; + const baseDirectory = ts.normalizePath(ts.combinePaths(baseUrl, expandedPrefixDirectory)); + const completePrefix = fragmentHasPath ? baseDirectory : ts.ensureTrailingDirectorySeparator(baseDirectory) + normalizedPrefixBase; // If we have a suffix, then we need to read the directory all the way down. We could create a glob // that encodes the suffix, but we would have to escape the character "?" which readDirectory // doesn't support. For now, this is safer but slower const includeGlob = normalizedSuffix ? "**/*" : "./*"; - const matches = mapDefined(tryReadDirectory(host, baseDirectory, fileExtensions, /*exclude*/ undefined, [includeGlob]), match => { - const extension = tryGetExtensionFromPath(match); + const matches = ts.mapDefined(ts.tryReadDirectory(host, baseDirectory, fileExtensions, /*exclude*/ undefined, [includeGlob]), match => { + const extension = ts.tryGetExtensionFromPath(match); const name = trimPrefixAndSuffix(match); - return name === undefined ? undefined : nameAndKind(removeFileExtension(name), ScriptElementKind.scriptElement, extension); + return name === undefined ? undefined : nameAndKind(ts.removeFileExtension(name), ts.ScriptElementKind.scriptElement, extension); }); - const directories = mapDefined(tryGetDirectories(host, baseDirectory).map(d => combinePaths(baseDirectory, d)), dir => { + const directories = ts.mapDefined(ts.tryGetDirectories(host, baseDirectory).map(d => ts.combinePaths(baseDirectory, d)), dir => { const name = trimPrefixAndSuffix(dir); return name === undefined ? undefined : directoryResult(name); }); return [...matches, ...directories]; function trimPrefixAndSuffix(path: string): string | undefined { - const inner = withoutStartAndEnd(normalizePath(path), completePrefix, normalizedSuffix); + const inner = withoutStartAndEnd(ts.normalizePath(path), completePrefix, normalizedSuffix); return inner === undefined ? undefined : removeLeadingDirectorySeparator(inner); } } function withoutStartAndEnd(s: string, start: string, end: string): string | undefined { - return startsWith(s, start) && endsWith(s, end) ? s.slice(start.length, s.length - end.length) : undefined; + return ts.startsWith(s, start) && ts.endsWith(s, end) ? s.slice(start.length, s.length - end.length) : undefined; } function removeLeadingDirectorySeparator(path: string): string { - return path[0] === directorySeparator ? path.slice(1) : path; + return path[0] === ts.directorySeparator ? path.slice(1) : path; } - function getAmbientModuleCompletions(fragment: string, fragmentDirectory: string | undefined, checker: TypeChecker): readonly string[] { + function getAmbientModuleCompletions(fragment: string, fragmentDirectory: string | undefined, checker: ts.TypeChecker): readonly string[] { // Get modules that the type checker picked up - const ambientModules = checker.getAmbientModules().map(sym => stripQuotes(sym.name)); - const nonRelativeModuleNames = ambientModules.filter(moduleName => startsWith(moduleName, fragment)); + const ambientModules = checker.getAmbientModules().map(sym => ts.stripQuotes(sym.name)); + const nonRelativeModuleNames = ambientModules.filter(moduleName => ts.startsWith(moduleName, fragment)); // Nested modules of the form "module-name/sub" need to be adjusted to only return the string // after the last '/' that appears in the fragment because that's where the replacement span // starts if (fragmentDirectory !== undefined) { - const moduleNameWithSeparator = ensureTrailingDirectorySeparator(fragmentDirectory); - return nonRelativeModuleNames.map(nonRelativeModuleName => removePrefix(nonRelativeModuleName, moduleNameWithSeparator)); + const moduleNameWithSeparator = ts.ensureTrailingDirectorySeparator(fragmentDirectory); + return nonRelativeModuleNames.map(nonRelativeModuleName => ts.removePrefix(nonRelativeModuleName, moduleNameWithSeparator)); } return nonRelativeModuleNames; } - function getTripleSlashReferenceCompletion(sourceFile: SourceFile, position: number, compilerOptions: CompilerOptions, host: LanguageServiceHost): readonly PathCompletion[] | undefined { - const token = getTokenAtPosition(sourceFile, position); - const commentRanges = getLeadingCommentRanges(sourceFile.text, token.pos); - const range = commentRanges && find(commentRanges, commentRange => position >= commentRange.pos && position <= commentRange.end); + function getTripleSlashReferenceCompletion(sourceFile: ts.SourceFile, position: number, compilerOptions: ts.CompilerOptions, host: ts.LanguageServiceHost): readonly PathCompletion[] | undefined { + const token = ts.getTokenAtPosition(sourceFile, position); + const commentRanges = ts.getLeadingCommentRanges(sourceFile.text, token.pos); + const range = commentRanges && ts.find(commentRanges, commentRange => position >= commentRange.pos && position <= commentRange.end); if (!range) { return undefined; } @@ -753,47 +724,47 @@ namespace ts.Completions.StringCompletions { } const [, prefix, kind, toComplete] = match; - const scriptPath = getDirectoryPath(sourceFile.path); + const scriptPath = ts.getDirectoryPath(sourceFile.path); const names = kind === "path" ? getCompletionEntriesForDirectoryFragment(toComplete, scriptPath, getExtensionOptions(compilerOptions, IncludeExtensionsOption.Include), host, sourceFile.path) : kind === "types" ? getCompletionEntriesFromTypings(host, compilerOptions, scriptPath, getFragmentDirectory(toComplete), getExtensionOptions(compilerOptions)) - : Debug.fail(); + : ts.Debug.fail(); return addReplacementSpans(toComplete, range.pos + prefix.length, names); } - function getCompletionEntriesFromTypings(host: LanguageServiceHost, options: CompilerOptions, scriptPath: string, fragmentDirectory: string | undefined, extensionOptions: ExtensionOptions, result: NameAndKind[] = []): readonly NameAndKind[] { + function getCompletionEntriesFromTypings(host: ts.LanguageServiceHost, options: ts.CompilerOptions, scriptPath: string, fragmentDirectory: string | undefined, extensionOptions: ExtensionOptions, result: NameAndKind[] = []): readonly NameAndKind[] { // Check for typings specified in compiler options - const seen = new Map(); - - const typeRoots = tryAndIgnoreErrors(() => getEffectiveTypeRoots(options, host)) || emptyArray; + const seen = new ts.Map(); + const typeRoots = ts.tryAndIgnoreErrors(() => ts.getEffectiveTypeRoots(options, host)) || ts.emptyArray; for (const root of typeRoots) { getCompletionEntriesFromDirectories(root); } // Also get all @types typings installed in visible node_modules directories - for (const packageJson of findPackageJsons(scriptPath, host)) { - const typesDir = combinePaths(getDirectoryPath(packageJson), "node_modules/@types"); + for (const packageJson of ts.findPackageJsons(scriptPath, host)) { + const typesDir = ts.combinePaths(ts.getDirectoryPath(packageJson), "node_modules/@types"); getCompletionEntriesFromDirectories(typesDir); } return result; function getCompletionEntriesFromDirectories(directory: string): void { - if (!tryDirectoryExists(host, directory)) return; - - for (const typeDirectoryName of tryGetDirectories(host, directory)) { - const packageName = unmangleScopedPackageName(typeDirectoryName); - if (options.types && !contains(options.types, packageName)) continue; + if (!ts.tryDirectoryExists(host, directory)) + return; + for (const typeDirectoryName of ts.tryGetDirectories(host, directory)) { + const packageName = ts.unmangleScopedPackageName(typeDirectoryName); + if (options.types && !ts.contains(options.types, packageName)) + continue; if (fragmentDirectory === undefined) { if (!seen.has(packageName)) { - result.push(nameAndKind(packageName, ScriptElementKind.externalModuleName, /*extension*/ undefined)); + result.push(nameAndKind(packageName, ts.ScriptElementKind.externalModuleName, /*extension*/ undefined)); seen.set(packageName, true); } } else { - const baseDirectory = combinePaths(directory, typeDirectoryName); - const remainingFragment = tryRemoveDirectoryPrefix(fragmentDirectory, packageName, hostGetCanonicalFileName(host)); + const baseDirectory = ts.combinePaths(directory, typeDirectoryName); + const remainingFragment = ts.tryRemoveDirectoryPrefix(fragmentDirectory, packageName, ts.hostGetCanonicalFileName(host)); if (remainingFragment !== undefined) { getCompletionEntriesForDirectoryFragment(remainingFragment, baseDirectory, extensionOptions, host, /*exclude*/ undefined, result); } @@ -802,18 +773,22 @@ namespace ts.Completions.StringCompletions { } } - function enumerateNodeModulesVisibleToScript(host: LanguageServiceHost, scriptPath: string): readonly string[] { - if (!host.readFile || !host.fileExists) return emptyArray; + function enumerateNodeModulesVisibleToScript(host: ts.LanguageServiceHost, scriptPath: string): readonly string[] { + if (!host.readFile || !host.fileExists) + return ts.emptyArray; const result: string[] = []; - for (const packageJson of findPackageJsons(scriptPath, host)) { - const contents = readJson(packageJson, host as { readFile: (filename: string) => string | undefined }); // Cast to assert that readFile is defined + for (const packageJson of ts.findPackageJsons(scriptPath, host)) { + const contents = ts.readJson(packageJson, host as { + readFile: (filename: string) => string | undefined; + }); // Cast to assert that readFile is defined // Provide completions for all non @types dependencies for (const key of nodeModulesDependencyKeys) { const dependencies: object | undefined = (contents as any)[key]; - if (!dependencies) continue; + if (!dependencies) + continue; for (const dep in dependencies) { - if (dependencies.hasOwnProperty(dep) && !startsWith(dep, "@types/")) { + if (dependencies.hasOwnProperty(dep) && !ts.startsWith(dep, "@types/")) { result.push(dep); } } @@ -823,20 +798,20 @@ namespace ts.Completions.StringCompletions { } // Replace everything after the last directory separator that appears - function getDirectoryFragmentTextSpan(text: string, textStart: number): TextSpan | undefined { - const index = Math.max(text.lastIndexOf(directorySeparator), text.lastIndexOf(altDirectorySeparator)); + function getDirectoryFragmentTextSpan(text: string, textStart: number): ts.TextSpan | undefined { + const index = Math.max(text.lastIndexOf(ts.directorySeparator), text.lastIndexOf(ts.altDirectorySeparator)); const offset = index !== -1 ? index + 1 : 0; // If the range is an identifier, span is unnecessary. const length = text.length - offset; - return length === 0 || isIdentifierText(text.substr(offset, length), ScriptTarget.ESNext) ? undefined : createTextSpan(textStart + offset, length); + return length === 0 || ts.isIdentifierText(text.substr(offset, length), ts.ScriptTarget.ESNext) ? undefined : ts.createTextSpan(textStart + offset, length); } // Returns true if the path is explicitly relative to the script (i.e. relative to . or ..) function isPathRelativeToScript(path: string) { - if (path && path.length >= 2 && path.charCodeAt(0) === CharacterCodes.dot) { - const slashIndex = path.length >= 3 && path.charCodeAt(1) === CharacterCodes.dot ? 2 : 1; + if (path && path.length >= 2 && path.charCodeAt(0) === ts.CharacterCodes.dot) { + const slashIndex = path.length >= 3 && path.charCodeAt(1) === ts.CharacterCodes.dot ? 2 : 1; const slashCharCode = path.charCodeAt(slashIndex); - return slashCharCode === CharacterCodes.slash || slashCharCode === CharacterCodes.backslash; + return slashCharCode === ts.CharacterCodes.slash || slashCharCode === ts.CharacterCodes.backslash; } return false; } @@ -858,7 +833,7 @@ namespace ts.Completions.StringCompletions { const nodeModulesDependencyKeys: readonly string[] = ["dependencies", "devDependencies", "peerDependencies", "optionalDependencies"]; function containsSlash(fragment: string) { - return stringContains(fragment, directorySeparator); + return ts.stringContains(fragment, ts.directorySeparator); } /** @@ -866,8 +841,8 @@ namespace ts.Completions.StringCompletions { * require("" * require("") */ - function isRequireCallArgument(node: Node) { - return isCallExpression(node.parent) && firstOrUndefined(node.parent.arguments) === node - && isIdentifier(node.parent.expression) && node.parent.expression.escapedText === "require"; + function isRequireCallArgument(node: ts.Node) { + return ts.isCallExpression(node.parent) && ts.firstOrUndefined(node.parent.arguments) === node + && ts.isIdentifier(node.parent.expression) && node.parent.expression.escapedText === "require"; } } diff --git a/src/services/suggestionDiagnostics.ts b/src/services/suggestionDiagnostics.ts index 7be5d210b36ea..8207f00f07311 100644 --- a/src/services/suggestionDiagnostics.ts +++ b/src/services/suggestionDiagnostics.ts @@ -1,61 +1,61 @@ /* @internal */ namespace ts { - const visitedNestedConvertibleFunctions = new Map(); - - export function computeSuggestionDiagnostics(sourceFile: SourceFile, program: Program, cancellationToken: CancellationToken): DiagnosticWithLocation[] { + const visitedNestedConvertibleFunctions = new ts.Map(); + export function computeSuggestionDiagnostics(sourceFile: ts.SourceFile, program: ts.Program, cancellationToken: ts.CancellationToken): ts.DiagnosticWithLocation[] { program.getSemanticDiagnostics(sourceFile, cancellationToken); - const diags: DiagnosticWithLocation[] = []; + const diags: ts.DiagnosticWithLocation[] = []; const checker = program.getTypeChecker(); - const isCommonJSFile = sourceFile.impliedNodeFormat === ModuleKind.CommonJS || fileExtensionIsOneOf(sourceFile.fileName, [Extension.Cts, Extension.Cjs]) ; + const isCommonJSFile = sourceFile.impliedNodeFormat === ts.ModuleKind.CommonJS || ts.fileExtensionIsOneOf(sourceFile.fileName, [ts.Extension.Cts, ts.Extension.Cjs]); if (!isCommonJSFile && sourceFile.commonJsModuleIndicator && - (programContainsEsModules(program) || compilerOptionsIndicateEsModules(program.getCompilerOptions())) && + (ts.programContainsEsModules(program) || ts.compilerOptionsIndicateEsModules(program.getCompilerOptions())) && containsTopLevelCommonjs(sourceFile)) { - diags.push(createDiagnosticForNode(getErrorNodeFromCommonJsIndicator(sourceFile.commonJsModuleIndicator), Diagnostics.File_is_a_CommonJS_module_it_may_be_converted_to_an_ES_module)); + diags.push(ts.createDiagnosticForNode(getErrorNodeFromCommonJsIndicator(sourceFile.commonJsModuleIndicator), ts.Diagnostics.File_is_a_CommonJS_module_it_may_be_converted_to_an_ES_module)); } - const isJsFile = isSourceFileJS(sourceFile); + const isJsFile = ts.isSourceFileJS(sourceFile); visitedNestedConvertibleFunctions.clear(); check(sourceFile); - if (getAllowSyntheticDefaultImports(program.getCompilerOptions())) { + if (ts.getAllowSyntheticDefaultImports(program.getCompilerOptions())) { for (const moduleSpecifier of sourceFile.imports) { - const importNode = importFromModuleSpecifier(moduleSpecifier); + const importNode = ts.importFromModuleSpecifier(moduleSpecifier); const name = importNameForConvertToDefaultImport(importNode); - if (!name) continue; - const module = getResolvedModule(sourceFile, moduleSpecifier.text, getModeForUsageLocation(sourceFile, moduleSpecifier)); + if (!name) + continue; + const module = ts.getResolvedModule(sourceFile, moduleSpecifier.text, ts.getModeForUsageLocation(sourceFile, moduleSpecifier)); const resolvedFile = module && program.getSourceFile(module.resolvedFileName); - if (resolvedFile && resolvedFile.externalModuleIndicator && resolvedFile.externalModuleIndicator !== true && isExportAssignment(resolvedFile.externalModuleIndicator) && resolvedFile.externalModuleIndicator.isExportEquals) { - diags.push(createDiagnosticForNode(name, Diagnostics.Import_may_be_converted_to_a_default_import)); + if (resolvedFile && resolvedFile.externalModuleIndicator && resolvedFile.externalModuleIndicator !== true && ts.isExportAssignment(resolvedFile.externalModuleIndicator) && resolvedFile.externalModuleIndicator.isExportEquals) { + diags.push(ts.createDiagnosticForNode(name, ts.Diagnostics.Import_may_be_converted_to_a_default_import)); } } } - addRange(diags, sourceFile.bindSuggestionDiagnostics); - addRange(diags, program.getSuggestionDiagnostics(sourceFile, cancellationToken)); + ts.addRange(diags, sourceFile.bindSuggestionDiagnostics); + ts.addRange(diags, program.getSuggestionDiagnostics(sourceFile, cancellationToken)); return diags.sort((d1, d2) => d1.start - d2.start); - function check(node: Node) { + function check(node: ts.Node) { if (isJsFile) { if (canBeConvertedToClass(node, checker)) { - diags.push(createDiagnosticForNode(isVariableDeclaration(node.parent) ? node.parent.name : node, Diagnostics.This_constructor_function_may_be_converted_to_a_class_declaration)); + diags.push(ts.createDiagnosticForNode(ts.isVariableDeclaration(node.parent) ? node.parent.name : node, ts.Diagnostics.This_constructor_function_may_be_converted_to_a_class_declaration)); } } else { - if (isVariableStatement(node) && + if (ts.isVariableStatement(node) && node.parent === sourceFile && - node.declarationList.flags & NodeFlags.Const && + node.declarationList.flags & ts.NodeFlags.Const && node.declarationList.declarations.length === 1) { const init = node.declarationList.declarations[0].initializer; - if (init && isRequireCall(init, /*checkArgumentIsStringLiteralLike*/ true)) { - diags.push(createDiagnosticForNode(init, Diagnostics.require_call_may_be_converted_to_an_import)); + if (init && ts.isRequireCall(init, /*checkArgumentIsStringLiteralLike*/ true)) { + diags.push(ts.createDiagnosticForNode(init, ts.Diagnostics.require_call_may_be_converted_to_an_import)); } } - if (codefix.parameterShouldGetTypeFromJSDoc(node)) { - diags.push(createDiagnosticForNode(node.name || node, Diagnostics.JSDoc_types_may_be_moved_to_TypeScript_types)); + if (ts.codefix.parameterShouldGetTypeFromJSDoc(node)) { + diags.push(ts.createDiagnosticForNode(node.name || node, ts.Diagnostics.JSDoc_types_may_be_moved_to_TypeScript_types)); } } @@ -67,17 +67,17 @@ namespace ts { } // convertToEsModule only works on top-level, so don't trigger it if commonjs code only appears in nested scopes. - function containsTopLevelCommonjs(sourceFile: SourceFile): boolean { + function containsTopLevelCommonjs(sourceFile: ts.SourceFile): boolean { return sourceFile.statements.some(statement => { switch (statement.kind) { - case SyntaxKind.VariableStatement: - return (statement as VariableStatement).declarationList.declarations.some(decl => - !!decl.initializer && isRequireCall(propertyAccessLeftHandSide(decl.initializer), /*checkArgumentIsStringLiteralLike*/ true)); - case SyntaxKind.ExpressionStatement: { - const { expression } = statement as ExpressionStatement; - if (!isBinaryExpression(expression)) return isRequireCall(expression, /*checkArgumentIsStringLiteralLike*/ true); - const kind = getAssignmentDeclarationKind(expression); - return kind === AssignmentDeclarationKind.ExportsProperty || kind === AssignmentDeclarationKind.ModuleExports; + case ts.SyntaxKind.VariableStatement: + return (statement as ts.VariableStatement).declarationList.declarations.some(decl => !!decl.initializer && ts.isRequireCall(propertyAccessLeftHandSide(decl.initializer), /*checkArgumentIsStringLiteralLike*/ true)); + case ts.SyntaxKind.ExpressionStatement: { + const { expression } = statement as ts.ExpressionStatement; + if (!ts.isBinaryExpression(expression)) + return ts.isRequireCall(expression, /*checkArgumentIsStringLiteralLike*/ true); + const kind = ts.getAssignmentDeclarationKind(expression); + return kind === ts.AssignmentDeclarationKind.ExportsProperty || kind === ts.AssignmentDeclarationKind.ModuleExports; } default: return false; @@ -85,61 +85,61 @@ namespace ts { }); } - function propertyAccessLeftHandSide(node: Expression): Expression { - return isPropertyAccessExpression(node) ? propertyAccessLeftHandSide(node.expression) : node; + function propertyAccessLeftHandSide(node: ts.Expression): ts.Expression { + return ts.isPropertyAccessExpression(node) ? propertyAccessLeftHandSide(node.expression) : node; } - function importNameForConvertToDefaultImport(node: AnyValidImportOrReExport): Identifier | undefined { + function importNameForConvertToDefaultImport(node: ts.AnyValidImportOrReExport): ts.Identifier | undefined { switch (node.kind) { - case SyntaxKind.ImportDeclaration: + case ts.SyntaxKind.ImportDeclaration: const { importClause, moduleSpecifier } = node; - return importClause && !importClause.name && importClause.namedBindings && importClause.namedBindings.kind === SyntaxKind.NamespaceImport && isStringLiteral(moduleSpecifier) + return importClause && !importClause.name && importClause.namedBindings && importClause.namedBindings.kind === ts.SyntaxKind.NamespaceImport && ts.isStringLiteral(moduleSpecifier) ? importClause.namedBindings.name : undefined; - case SyntaxKind.ImportEqualsDeclaration: + case ts.SyntaxKind.ImportEqualsDeclaration: return node.name; default: return undefined; } } - function addConvertToAsyncFunctionDiagnostics(node: FunctionLikeDeclaration, checker: TypeChecker, diags: Push): void { + function addConvertToAsyncFunctionDiagnostics(node: ts.FunctionLikeDeclaration, checker: ts.TypeChecker, diags: ts.Push): void { // need to check function before checking map so that deeper levels of nested callbacks are checked if (isConvertibleFunction(node, checker) && !visitedNestedConvertibleFunctions.has(getKeyFromNode(node))) { - diags.push(createDiagnosticForNode( - !node.name && isVariableDeclaration(node.parent) && isIdentifier(node.parent.name) ? node.parent.name : node, - Diagnostics.This_may_be_converted_to_an_async_function)); + diags.push(ts.createDiagnosticForNode(!node.name && ts.isVariableDeclaration(node.parent) && ts.isIdentifier(node.parent.name) ? node.parent.name : node, ts.Diagnostics.This_may_be_converted_to_an_async_function)); } } - function isConvertibleFunction(node: FunctionLikeDeclaration, checker: TypeChecker) { - return !isAsyncFunction(node) && + function isConvertibleFunction(node: ts.FunctionLikeDeclaration, checker: ts.TypeChecker) { + return !ts.isAsyncFunction(node) && node.body && - isBlock(node.body) && + ts.isBlock(node.body) && hasReturnStatementWithPromiseHandler(node.body, checker) && returnsPromise(node, checker); } - export function returnsPromise(node: FunctionLikeDeclaration, checker: TypeChecker): boolean { + export function returnsPromise(node: ts.FunctionLikeDeclaration, checker: ts.TypeChecker): boolean { const signature = checker.getSignatureFromDeclaration(node); const returnType = signature ? checker.getReturnTypeOfSignature(signature) : undefined; return !!returnType && !!checker.getPromisedTypeOfPromise(returnType); } - function getErrorNodeFromCommonJsIndicator(commonJsModuleIndicator: Node): Node { - return isBinaryExpression(commonJsModuleIndicator) ? commonJsModuleIndicator.left : commonJsModuleIndicator; + function getErrorNodeFromCommonJsIndicator(commonJsModuleIndicator: ts.Node): ts.Node { + return ts.isBinaryExpression(commonJsModuleIndicator) ? commonJsModuleIndicator.left : commonJsModuleIndicator; } - function hasReturnStatementWithPromiseHandler(body: Block, checker: TypeChecker): boolean { - return !!forEachReturnStatement(body, statement => isReturnStatementWithFixablePromiseHandler(statement, checker)); + function hasReturnStatementWithPromiseHandler(body: ts.Block, checker: ts.TypeChecker): boolean { + return !!ts.forEachReturnStatement(body, statement => isReturnStatementWithFixablePromiseHandler(statement, checker)); } - export function isReturnStatementWithFixablePromiseHandler(node: Node, checker: TypeChecker): node is ReturnStatement & { expression: CallExpression } { - return isReturnStatement(node) && !!node.expression && isFixablePromiseHandler(node.expression, checker); + export function isReturnStatementWithFixablePromiseHandler(node: ts.Node, checker: ts.TypeChecker): node is ts.ReturnStatement & { + expression: ts.CallExpression; + } { + return ts.isReturnStatement(node) && !!node.expression && isFixablePromiseHandler(node.expression, checker); } // Should be kept up to date with transformExpression in convertToAsyncFunction.ts - export function isFixablePromiseHandler(node: Node, checker: TypeChecker): boolean { + export function isFixablePromiseHandler(node: ts.Node, checker: ts.TypeChecker): boolean { // ensure outermost call exists and is a promise handler if (!isPromiseHandler(node) || !hasSupportedNumberOfArguments(node) || !node.arguments.every(arg => isFixablePromiseArgument(arg, checker))) { return false; @@ -147,8 +147,8 @@ namespace ts { // ensure all chained calls are valid let currentNode = node.expression.expression; - while (isPromiseHandler(currentNode) || isPropertyAccessExpression(currentNode)) { - if (isCallExpression(currentNode)) { + while (isPromiseHandler(currentNode) || ts.isPropertyAccessExpression(currentNode)) { + if (ts.isCallExpression(currentNode)) { if (!hasSupportedNumberOfArguments(currentNode) || !currentNode.arguments.every(arg => isFixablePromiseArgument(arg, checker))) { return false; } @@ -161,59 +161,64 @@ namespace ts { return true; } - function isPromiseHandler(node: Node): node is CallExpression & { readonly expression: PropertyAccessExpression } { - return isCallExpression(node) && ( - hasPropertyAccessExpressionWithName(node, "then") || - hasPropertyAccessExpressionWithName(node, "catch") || - hasPropertyAccessExpressionWithName(node, "finally")); + function isPromiseHandler(node: ts.Node): node is ts.CallExpression & { + readonly expression: ts.PropertyAccessExpression; + } { + return ts.isCallExpression(node) && (ts.hasPropertyAccessExpressionWithName(node, "then") || + ts.hasPropertyAccessExpressionWithName(node, "catch") || + ts.hasPropertyAccessExpressionWithName(node, "finally")); } - function hasSupportedNumberOfArguments(node: CallExpression & { readonly expression: PropertyAccessExpression }) { + function hasSupportedNumberOfArguments(node: ts.CallExpression & { + readonly expression: ts.PropertyAccessExpression; + }) { const name = node.expression.name.text; const maxArguments = name === "then" ? 2 : name === "catch" ? 1 : name === "finally" ? 1 : 0; - if (node.arguments.length > maxArguments) return false; - if (node.arguments.length < maxArguments) return true; - return maxArguments === 1 || some(node.arguments, arg => { - return arg.kind === SyntaxKind.NullKeyword || isIdentifier(arg) && arg.text === "undefined"; + if (node.arguments.length > maxArguments) + return false; + if (node.arguments.length < maxArguments) + return true; + return maxArguments === 1 || ts.some(node.arguments, arg => { + return arg.kind === ts.SyntaxKind.NullKeyword || ts.isIdentifier(arg) && arg.text === "undefined"; }); } // should be kept up to date with getTransformationBody in convertToAsyncFunction.ts - function isFixablePromiseArgument(arg: Expression, checker: TypeChecker): boolean { + function isFixablePromiseArgument(arg: ts.Expression, checker: ts.TypeChecker): boolean { switch (arg.kind) { - case SyntaxKind.FunctionDeclaration: - case SyntaxKind.FunctionExpression: - const functionFlags = getFunctionFlags(arg as FunctionDeclaration | FunctionExpression); - if (functionFlags & FunctionFlags.Generator) { + case ts.SyntaxKind.FunctionDeclaration: + case ts.SyntaxKind.FunctionExpression: + const functionFlags = ts.getFunctionFlags(arg as ts.FunctionDeclaration | ts.FunctionExpression); + if (functionFlags & ts.FunctionFlags.Generator) { return false; } // falls through - case SyntaxKind.ArrowFunction: - visitedNestedConvertibleFunctions.set(getKeyFromNode(arg as FunctionLikeDeclaration), true); + case ts.SyntaxKind.ArrowFunction: + visitedNestedConvertibleFunctions.set(getKeyFromNode(arg as ts.FunctionLikeDeclaration), true); // falls through - case SyntaxKind.NullKeyword: + case ts.SyntaxKind.NullKeyword: return true; - case SyntaxKind.Identifier: - case SyntaxKind.PropertyAccessExpression: { + case ts.SyntaxKind.Identifier: + case ts.SyntaxKind.PropertyAccessExpression: { const symbol = checker.getSymbolAtLocation(arg); if (!symbol) { return false; } return checker.isUndefinedSymbol(symbol) || - some(skipAlias(symbol, checker).declarations, d => isFunctionLike(d) || hasInitializer(d) && !!d.initializer && isFunctionLike(d.initializer)); + ts.some(ts.skipAlias(symbol, checker).declarations, d => ts.isFunctionLike(d) || ts.hasInitializer(d) && !!d.initializer && ts.isFunctionLike(d.initializer)); } default: return false; } } - function getKeyFromNode(exp: FunctionLikeDeclaration) { + function getKeyFromNode(exp: ts.FunctionLikeDeclaration) { return `${exp.pos.toString()}:${exp.end.toString()}`; } - function canBeConvertedToClass(node: Node, checker: TypeChecker): boolean { - if (node.kind === SyntaxKind.FunctionExpression) { - if (isVariableDeclaration(node.parent) && node.symbol.members?.size) { + function canBeConvertedToClass(node: ts.Node, checker: ts.TypeChecker): boolean { + if (node.kind === ts.SyntaxKind.FunctionExpression) { + if (ts.isVariableDeclaration(node.parent) && node.symbol.members?.size) { return true; } @@ -221,19 +226,19 @@ namespace ts { return !!(symbol && (symbol.exports?.size || symbol.members?.size)); } - if (node.kind === SyntaxKind.FunctionDeclaration) { + if (node.kind === ts.SyntaxKind.FunctionDeclaration) { return !!node.symbol.members?.size; } return false; } - export function canBeConvertedToAsync(node: Node): node is FunctionDeclaration | MethodDeclaration | FunctionExpression | ArrowFunction { + export function canBeConvertedToAsync(node: ts.Node): node is ts.FunctionDeclaration | ts.MethodDeclaration | ts.FunctionExpression | ts.ArrowFunction { switch (node.kind) { - case SyntaxKind.FunctionDeclaration: - case SyntaxKind.MethodDeclaration: - case SyntaxKind.FunctionExpression: - case SyntaxKind.ArrowFunction: + case ts.SyntaxKind.FunctionDeclaration: + case ts.SyntaxKind.MethodDeclaration: + case ts.SyntaxKind.FunctionExpression: + case ts.SyntaxKind.ArrowFunction: return true; default: return false; diff --git a/src/services/symbolDisplay.ts b/src/services/symbolDisplay.ts index 973e28476b6a5..69ad5ee664b08 100644 --- a/src/services/symbolDisplay.ts +++ b/src/services/symbolDisplay.ts @@ -1,77 +1,88 @@ /* @internal */ namespace ts.SymbolDisplay { - const symbolDisplayNodeBuilderFlags = NodeBuilderFlags.OmitParameterModifiers | NodeBuilderFlags.IgnoreErrors | NodeBuilderFlags.UseAliasDefinedOutsideCurrentScope; + const symbolDisplayNodeBuilderFlags = ts.NodeBuilderFlags.OmitParameterModifiers | ts.NodeBuilderFlags.IgnoreErrors | ts.NodeBuilderFlags.UseAliasDefinedOutsideCurrentScope; // TODO(drosen): use contextual SemanticMeaning. - export function getSymbolKind(typeChecker: TypeChecker, symbol: Symbol, location: Node): ScriptElementKind { + export function getSymbolKind(typeChecker: ts.TypeChecker, symbol: ts.Symbol, location: ts.Node): ts.ScriptElementKind { const result = getSymbolKindOfConstructorPropertyMethodAccessorFunctionOrVar(typeChecker, symbol, location); - if (result !== ScriptElementKind.unknown) { + if (result !== ts.ScriptElementKind.unknown) { return result; } - const flags = getCombinedLocalAndExportSymbolFlags(symbol); - if (flags & SymbolFlags.Class) { - return getDeclarationOfKind(symbol, SyntaxKind.ClassExpression) ? - ScriptElementKind.localClassElement : ScriptElementKind.classElement; - } - if (flags & SymbolFlags.Enum) return ScriptElementKind.enumElement; - if (flags & SymbolFlags.TypeAlias) return ScriptElementKind.typeElement; - if (flags & SymbolFlags.Interface) return ScriptElementKind.interfaceElement; - if (flags & SymbolFlags.TypeParameter) return ScriptElementKind.typeParameterElement; - if (flags & SymbolFlags.EnumMember) return ScriptElementKind.enumMemberElement; - if (flags & SymbolFlags.Alias) return ScriptElementKind.alias; - if (flags & SymbolFlags.Module) return ScriptElementKind.moduleElement; + const flags = ts.getCombinedLocalAndExportSymbolFlags(symbol); + if (flags & ts.SymbolFlags.Class) { + return ts.getDeclarationOfKind(symbol, ts.SyntaxKind.ClassExpression) ? + ts.ScriptElementKind.localClassElement : ts.ScriptElementKind.classElement; + } + if (flags & ts.SymbolFlags.Enum) + return ts.ScriptElementKind.enumElement; + if (flags & ts.SymbolFlags.TypeAlias) + return ts.ScriptElementKind.typeElement; + if (flags & ts.SymbolFlags.Interface) + return ts.ScriptElementKind.interfaceElement; + if (flags & ts.SymbolFlags.TypeParameter) + return ts.ScriptElementKind.typeParameterElement; + if (flags & ts.SymbolFlags.EnumMember) + return ts.ScriptElementKind.enumMemberElement; + if (flags & ts.SymbolFlags.Alias) + return ts.ScriptElementKind.alias; + if (flags & ts.SymbolFlags.Module) + return ts.ScriptElementKind.moduleElement; return result; } - function getSymbolKindOfConstructorPropertyMethodAccessorFunctionOrVar(typeChecker: TypeChecker, symbol: Symbol, location: Node): ScriptElementKind { + function getSymbolKindOfConstructorPropertyMethodAccessorFunctionOrVar(typeChecker: ts.TypeChecker, symbol: ts.Symbol, location: ts.Node): ts.ScriptElementKind { const roots = typeChecker.getRootSymbols(symbol); // If this is a method from a mapped type, leave as a method so long as it still has a call signature. if (roots.length === 1 - && first(roots).flags & SymbolFlags.Method + && ts.first(roots).flags & ts.SymbolFlags.Method // Ensure the mapped version is still a method, as opposed to `{ [K in keyof I]: number }`. && typeChecker.getTypeOfSymbolAtLocation(symbol, location).getNonNullableType().getCallSignatures().length !== 0) { - return ScriptElementKind.memberFunctionElement; + return ts.ScriptElementKind.memberFunctionElement; } if (typeChecker.isUndefinedSymbol(symbol)) { - return ScriptElementKind.variableElement; + return ts.ScriptElementKind.variableElement; } if (typeChecker.isArgumentsSymbol(symbol)) { - return ScriptElementKind.localVariableElement; + return ts.ScriptElementKind.localVariableElement; } - if (location.kind === SyntaxKind.ThisKeyword && isExpression(location) || isThisInTypeQuery(location)) { - return ScriptElementKind.parameterElement; + if (location.kind === ts.SyntaxKind.ThisKeyword && ts.isExpression(location) || ts.isThisInTypeQuery(location)) { + return ts.ScriptElementKind.parameterElement; } - const flags = getCombinedLocalAndExportSymbolFlags(symbol); - if (flags & SymbolFlags.Variable) { - if (isFirstDeclarationOfSymbolParameter(symbol)) { - return ScriptElementKind.parameterElement; + const flags = ts.getCombinedLocalAndExportSymbolFlags(symbol); + if (flags & ts.SymbolFlags.Variable) { + if (ts.isFirstDeclarationOfSymbolParameter(symbol)) { + return ts.ScriptElementKind.parameterElement; } - else if (symbol.valueDeclaration && isVarConst(symbol.valueDeclaration as VariableDeclaration)) { - return ScriptElementKind.constElement; + else if (symbol.valueDeclaration && ts.isVarConst(symbol.valueDeclaration as ts.VariableDeclaration)) { + return ts.ScriptElementKind.constElement; } - else if (forEach(symbol.declarations, isLet)) { - return ScriptElementKind.letElement; + else if (ts.forEach(symbol.declarations, ts.isLet)) { + return ts.ScriptElementKind.letElement; } - return isLocalVariableOrFunction(symbol) ? ScriptElementKind.localVariableElement : ScriptElementKind.variableElement; + return isLocalVariableOrFunction(symbol) ? ts.ScriptElementKind.localVariableElement : ts.ScriptElementKind.variableElement; } - if (flags & SymbolFlags.Function) return isLocalVariableOrFunction(symbol) ? ScriptElementKind.localFunctionElement : ScriptElementKind.functionElement; + if (flags & ts.SymbolFlags.Function) + return isLocalVariableOrFunction(symbol) ? ts.ScriptElementKind.localFunctionElement : ts.ScriptElementKind.functionElement; // FIXME: getter and setter use the same symbol. And it is rare to use only setter without getter, so in most cases the symbol always has getter flag. // So, even when the location is just on the declaration of setter, this function returns getter. - if (flags & SymbolFlags.GetAccessor) return ScriptElementKind.memberGetAccessorElement; - if (flags & SymbolFlags.SetAccessor) return ScriptElementKind.memberSetAccessorElement; - if (flags & SymbolFlags.Method) return ScriptElementKind.memberFunctionElement; - if (flags & SymbolFlags.Constructor) return ScriptElementKind.constructorImplementationElement; - - if (flags & SymbolFlags.Property) { - if (flags & SymbolFlags.Transient && (symbol as TransientSymbol).checkFlags & CheckFlags.Synthetic) { + if (flags & ts.SymbolFlags.GetAccessor) + return ts.ScriptElementKind.memberGetAccessorElement; + if (flags & ts.SymbolFlags.SetAccessor) + return ts.ScriptElementKind.memberSetAccessorElement; + if (flags & ts.SymbolFlags.Method) + return ts.ScriptElementKind.memberFunctionElement; + if (flags & ts.SymbolFlags.Constructor) + return ts.ScriptElementKind.constructorImplementationElement; + if (flags & ts.SymbolFlags.Property) { + if (flags & ts.SymbolFlags.Transient && (symbol as ts.TransientSymbol).checkFlags & ts.CheckFlags.Synthetic) { // If union property is result of union of non method (property/accessors/variables), it is labeled as property - const unionPropertyKind = forEach(typeChecker.getRootSymbols(symbol), rootSymbol => { + const unionPropertyKind = ts.forEach(typeChecker.getRootSymbols(symbol), rootSymbol => { const rootSymbolFlags = rootSymbol.getFlags(); - if (rootSymbolFlags & (SymbolFlags.PropertyOrAccessor | SymbolFlags.Variable)) { - return ScriptElementKind.memberVariableElement; + if (rootSymbolFlags & (ts.SymbolFlags.PropertyOrAccessor | ts.SymbolFlags.Variable)) { + return ts.ScriptElementKind.memberVariableElement; } }); if (!unionPropertyKind) { @@ -79,27 +90,27 @@ namespace ts.SymbolDisplay { // make sure it has call signatures before we can label it as method const typeOfUnionProperty = typeChecker.getTypeOfSymbolAtLocation(symbol, location); if (typeOfUnionProperty.getCallSignatures().length) { - return ScriptElementKind.memberFunctionElement; + return ts.ScriptElementKind.memberFunctionElement; } - return ScriptElementKind.memberVariableElement; + return ts.ScriptElementKind.memberVariableElement; } return unionPropertyKind; } - return ScriptElementKind.memberVariableElement; + return ts.ScriptElementKind.memberVariableElement; } - return ScriptElementKind.unknown; + return ts.ScriptElementKind.unknown; } - function getNormalizedSymbolModifiers(symbol: Symbol) { + function getNormalizedSymbolModifiers(symbol: ts.Symbol) { if (symbol.declarations && symbol.declarations.length) { const [declaration, ...declarations] = symbol.declarations; // omit deprecated flag if some declarations are not deprecated - const excludeFlags = length(declarations) && isDeprecatedDeclaration(declaration) && some(declarations, d => !isDeprecatedDeclaration(d)) - ? ModifierFlags.Deprecated - : ModifierFlags.None; - const modifiers = getNodeModifiers(declaration, excludeFlags); + const excludeFlags = ts.length(declarations) && ts.isDeprecatedDeclaration(declaration) && ts.some(declarations, d => !ts.isDeprecatedDeclaration(d)) + ? ts.ModifierFlags.Deprecated + : ts.ModifierFlags.None; + const modifiers = ts.getNodeModifiers(declaration, excludeFlags); if (modifiers) { return modifiers.split(","); } @@ -107,80 +118,79 @@ namespace ts.SymbolDisplay { return []; } - export function getSymbolModifiers(typeChecker: TypeChecker, symbol: Symbol): string { + export function getSymbolModifiers(typeChecker: ts.TypeChecker, symbol: ts.Symbol): string { if (!symbol) { - return ScriptElementKindModifier.none; + return ts.ScriptElementKindModifier.none; } - const modifiers = new Set(getNormalizedSymbolModifiers(symbol)); - if (symbol.flags & SymbolFlags.Alias) { + const modifiers = new ts.Set(getNormalizedSymbolModifiers(symbol)); + if (symbol.flags & ts.SymbolFlags.Alias) { const resolvedSymbol = typeChecker.getAliasedSymbol(symbol); if (resolvedSymbol !== symbol) { - forEach(getNormalizedSymbolModifiers(resolvedSymbol), modifier => { + ts.forEach(getNormalizedSymbolModifiers(resolvedSymbol), modifier => { modifiers.add(modifier); }); } } - if (symbol.flags & SymbolFlags.Optional) { - modifiers.add(ScriptElementKindModifier.optionalModifier); + if (symbol.flags & ts.SymbolFlags.Optional) { + modifiers.add(ts.ScriptElementKindModifier.optionalModifier); } - return modifiers.size > 0 ? arrayFrom(modifiers.values()).join(",") : ScriptElementKindModifier.none; + return modifiers.size > 0 ? ts.arrayFrom(modifiers.values()).join(",") : ts.ScriptElementKindModifier.none; } interface SymbolDisplayPartsDocumentationAndSymbolKind { - displayParts: SymbolDisplayPart[]; - documentation: SymbolDisplayPart[]; - symbolKind: ScriptElementKind; - tags: JSDocTagInfo[] | undefined; + displayParts: ts.SymbolDisplayPart[]; + documentation: ts.SymbolDisplayPart[]; + symbolKind: ts.ScriptElementKind; + tags: ts.JSDocTagInfo[] | undefined; } // TODO(drosen): Currently completion entry details passes the SemanticMeaning.All instead of using semanticMeaning of location - export function getSymbolDisplayPartsDocumentationAndSymbolKind(typeChecker: TypeChecker, symbol: Symbol, sourceFile: SourceFile, enclosingDeclaration: Node | undefined, - location: Node, semanticMeaning = getMeaningFromLocation(location), alias?: Symbol): SymbolDisplayPartsDocumentationAndSymbolKind { - const displayParts: SymbolDisplayPart[] = []; - let documentation: SymbolDisplayPart[] = []; - let tags: JSDocTagInfo[] = []; - const symbolFlags = getCombinedLocalAndExportSymbolFlags(symbol); - let symbolKind = semanticMeaning & SemanticMeaning.Value ? getSymbolKindOfConstructorPropertyMethodAccessorFunctionOrVar(typeChecker, symbol, location) : ScriptElementKind.unknown; + export function getSymbolDisplayPartsDocumentationAndSymbolKind(typeChecker: ts.TypeChecker, symbol: ts.Symbol, sourceFile: ts.SourceFile, enclosingDeclaration: ts.Node | undefined, location: ts.Node, semanticMeaning = ts.getMeaningFromLocation(location), alias?: ts.Symbol): SymbolDisplayPartsDocumentationAndSymbolKind { + const displayParts: ts.SymbolDisplayPart[] = []; + let documentation: ts.SymbolDisplayPart[] = []; + let tags: ts.JSDocTagInfo[] = []; + const symbolFlags = ts.getCombinedLocalAndExportSymbolFlags(symbol); + let symbolKind = semanticMeaning & ts.SemanticMeaning.Value ? getSymbolKindOfConstructorPropertyMethodAccessorFunctionOrVar(typeChecker, symbol, location) : ts.ScriptElementKind.unknown; let hasAddedSymbolInfo = false; - const isThisExpression = location.kind === SyntaxKind.ThisKeyword && isInExpressionContext(location) || isThisInTypeQuery(location); - let type: Type | undefined; - let printer: Printer; - let documentationFromAlias: SymbolDisplayPart[] | undefined; - let tagsFromAlias: JSDocTagInfo[] | undefined; + const isThisExpression = location.kind === ts.SyntaxKind.ThisKeyword && ts.isInExpressionContext(location) || ts.isThisInTypeQuery(location); + let type: ts.Type | undefined; + let printer: ts.Printer; + let documentationFromAlias: ts.SymbolDisplayPart[] | undefined; + let tagsFromAlias: ts.JSDocTagInfo[] | undefined; let hasMultipleSignatures = false; - if (location.kind === SyntaxKind.ThisKeyword && !isThisExpression) { - return { displayParts: [keywordPart(SyntaxKind.ThisKeyword)], documentation: [], symbolKind: ScriptElementKind.primitiveType, tags: undefined }; + if (location.kind === ts.SyntaxKind.ThisKeyword && !isThisExpression) { + return { displayParts: [ts.keywordPart(ts.SyntaxKind.ThisKeyword)], documentation: [], symbolKind: ts.ScriptElementKind.primitiveType, tags: undefined }; } // Class at constructor site need to be shown as constructor apart from property,method, vars - if (symbolKind !== ScriptElementKind.unknown || symbolFlags & SymbolFlags.Class || symbolFlags & SymbolFlags.Alias) { + if (symbolKind !== ts.ScriptElementKind.unknown || symbolFlags & ts.SymbolFlags.Class || symbolFlags & ts.SymbolFlags.Alias) { // If symbol is accessor, they are allowed only if location is at declaration identifier of the accessor - if (symbolKind === ScriptElementKind.memberGetAccessorElement || symbolKind === ScriptElementKind.memberSetAccessorElement) { - const declaration = find(symbol.declarations as ((GetAccessorDeclaration | SetAccessorDeclaration)[]), declaration => declaration.name === location); + if (symbolKind === ts.ScriptElementKind.memberGetAccessorElement || symbolKind === ts.ScriptElementKind.memberSetAccessorElement) { + const declaration = ts.find(symbol.declarations as ((ts.GetAccessorDeclaration | ts.SetAccessorDeclaration)[]), declaration => declaration.name === location); if (declaration) { switch(declaration.kind){ - case SyntaxKind.GetAccessor: - symbolKind = ScriptElementKind.memberGetAccessorElement; + case ts.SyntaxKind.GetAccessor: + symbolKind = ts.ScriptElementKind.memberGetAccessorElement; break; - case SyntaxKind.SetAccessor: - symbolKind = ScriptElementKind.memberSetAccessorElement; + case ts.SyntaxKind.SetAccessor: + symbolKind = ts.ScriptElementKind.memberSetAccessorElement; break; default: - Debug.assertNever(declaration); + ts.Debug.assertNever(declaration); } } else { - symbolKind = ScriptElementKind.memberVariableElement; + symbolKind = ts.ScriptElementKind.memberVariableElement; } } - let signature: Signature | undefined; + let signature: ts.Signature | undefined; type = isThisExpression ? typeChecker.getTypeAtLocation(location) : typeChecker.getTypeOfSymbolAtLocation(symbol, location); - if (location.parent && location.parent.kind === SyntaxKind.PropertyAccessExpression) { - const right = (location.parent as PropertyAccessExpression).name; + if (location.parent && location.parent.kind === ts.SyntaxKind.PropertyAccessExpression) { + const right = (location.parent as ts.PropertyAccessExpression).name; // Either the location is on the right of a property access, or on the left and the right is missing if (right === location || (right && right.getFullWidth() === 0)) { location = location.parent; @@ -188,47 +198,47 @@ namespace ts.SymbolDisplay { } // try get the call/construct signature from the type if it matches - let callExpressionLike: CallExpression | NewExpression | JsxOpeningLikeElement | TaggedTemplateExpression | undefined; - if (isCallOrNewExpression(location)) { + let callExpressionLike: ts.CallExpression | ts.NewExpression | ts.JsxOpeningLikeElement | ts.TaggedTemplateExpression | undefined; + if (ts.isCallOrNewExpression(location)) { callExpressionLike = location; } - else if (isCallExpressionTarget(location) || isNewExpressionTarget(location)) { - callExpressionLike = location.parent as CallExpression | NewExpression; + else if (ts.isCallExpressionTarget(location) || ts.isNewExpressionTarget(location)) { + callExpressionLike = location.parent as ts.CallExpression | ts.NewExpression; } - else if (location.parent && (isJsxOpeningLikeElement(location.parent) || isTaggedTemplateExpression(location.parent)) && isFunctionLike(symbol.valueDeclaration)) { + else if (location.parent && (ts.isJsxOpeningLikeElement(location.parent) || ts.isTaggedTemplateExpression(location.parent)) && ts.isFunctionLike(symbol.valueDeclaration)) { callExpressionLike = location.parent; } if (callExpressionLike) { signature = typeChecker.getResolvedSignature(callExpressionLike); // TODO: GH#18217 - const useConstructSignatures = callExpressionLike.kind === SyntaxKind.NewExpression || (isCallExpression(callExpressionLike) && callExpressionLike.expression.kind === SyntaxKind.SuperKeyword); + const useConstructSignatures = callExpressionLike.kind === ts.SyntaxKind.NewExpression || (ts.isCallExpression(callExpressionLike) && callExpressionLike.expression.kind === ts.SyntaxKind.SuperKeyword); const allSignatures = useConstructSignatures ? type.getConstructSignatures() : type.getCallSignatures(); - if (signature && !contains(allSignatures, signature.target) && !contains(allSignatures, signature)) { + if (signature && !ts.contains(allSignatures, signature.target) && !ts.contains(allSignatures, signature)) { // Get the first signature if there is one -- allSignatures may contain // either the original signature or its target, so check for either signature = allSignatures.length ? allSignatures[0] : undefined; } if (signature) { - if (useConstructSignatures && (symbolFlags & SymbolFlags.Class)) { + if (useConstructSignatures && (symbolFlags & ts.SymbolFlags.Class)) { // Constructor - symbolKind = ScriptElementKind.constructorImplementationElement; + symbolKind = ts.ScriptElementKind.constructorImplementationElement; addPrefixForAnyFunctionOrVar(type.symbol, symbolKind); } - else if (symbolFlags & SymbolFlags.Alias) { - symbolKind = ScriptElementKind.alias; + else if (symbolFlags & ts.SymbolFlags.Alias) { + symbolKind = ts.ScriptElementKind.alias; pushSymbolKind(symbolKind); - displayParts.push(spacePart()); + displayParts.push(ts.spacePart()); if (useConstructSignatures) { - if (signature.flags & SignatureFlags.Abstract) { - displayParts.push(keywordPart(SyntaxKind.AbstractKeyword)); - displayParts.push(spacePart()); + if (signature.flags & ts.SignatureFlags.Abstract) { + displayParts.push(ts.keywordPart(ts.SyntaxKind.AbstractKeyword)); + displayParts.push(ts.spacePart()); } - displayParts.push(keywordPart(SyntaxKind.NewKeyword)); - displayParts.push(spacePart()); + displayParts.push(ts.keywordPart(ts.SyntaxKind.NewKeyword)); + displayParts.push(ts.spacePart()); } addFullSymbolName(symbol); } @@ -237,29 +247,29 @@ namespace ts.SymbolDisplay { } switch (symbolKind) { - case ScriptElementKind.jsxAttribute: - case ScriptElementKind.memberVariableElement: - case ScriptElementKind.variableElement: - case ScriptElementKind.constElement: - case ScriptElementKind.letElement: - case ScriptElementKind.parameterElement: - case ScriptElementKind.localVariableElement: + case ts.ScriptElementKind.jsxAttribute: + case ts.ScriptElementKind.memberVariableElement: + case ts.ScriptElementKind.variableElement: + case ts.ScriptElementKind.constElement: + case ts.ScriptElementKind.letElement: + case ts.ScriptElementKind.parameterElement: + case ts.ScriptElementKind.localVariableElement: // If it is call or construct signature of lambda's write type name - displayParts.push(punctuationPart(SyntaxKind.ColonToken)); - displayParts.push(spacePart()); - if (!(getObjectFlags(type) & ObjectFlags.Anonymous) && type.symbol) { - addRange(displayParts, symbolToDisplayParts(typeChecker, type.symbol, enclosingDeclaration, /*meaning*/ undefined, SymbolFormatFlags.AllowAnyNodeKind | SymbolFormatFlags.WriteTypeParametersOrArguments)); - displayParts.push(lineBreakPart()); + displayParts.push(ts.punctuationPart(ts.SyntaxKind.ColonToken)); + displayParts.push(ts.spacePart()); + if (!(ts.getObjectFlags(type) & ts.ObjectFlags.Anonymous) && type.symbol) { + ts.addRange(displayParts, ts.symbolToDisplayParts(typeChecker, type.symbol, enclosingDeclaration, /*meaning*/ undefined, ts.SymbolFormatFlags.AllowAnyNodeKind | ts.SymbolFormatFlags.WriteTypeParametersOrArguments)); + displayParts.push(ts.lineBreakPart()); } if (useConstructSignatures) { - if (signature.flags & SignatureFlags.Abstract) { - displayParts.push(keywordPart(SyntaxKind.AbstractKeyword)); - displayParts.push(spacePart()); + if (signature.flags & ts.SignatureFlags.Abstract) { + displayParts.push(ts.keywordPart(ts.SyntaxKind.AbstractKeyword)); + displayParts.push(ts.spacePart()); } - displayParts.push(keywordPart(SyntaxKind.NewKeyword)); - displayParts.push(spacePart()); + displayParts.push(ts.keywordPart(ts.SyntaxKind.NewKeyword)); + displayParts.push(ts.spacePart()); } - addSignatureDisplayParts(signature, allSignatures, TypeFormatFlags.WriteArrowStyleSignature); + addSignatureDisplayParts(signature, allSignatures, ts.TypeFormatFlags.WriteArrowStyleSignature); break; default: @@ -270,16 +280,15 @@ namespace ts.SymbolDisplay { hasMultipleSignatures = allSignatures.length > 1; } } - else if ((isNameOfFunctionDeclaration(location) && !(symbolFlags & SymbolFlags.Accessor)) || // name of function declaration - (location.kind === SyntaxKind.ConstructorKeyword && location.parent.kind === SyntaxKind.Constructor)) { // At constructor keyword of constructor declaration + else if ((ts.isNameOfFunctionDeclaration(location) && !(symbolFlags & ts.SymbolFlags.Accessor)) || // name of function declaration + (location.kind === ts.SyntaxKind.ConstructorKeyword && location.parent.kind === ts.SyntaxKind.Constructor)) { // At constructor keyword of constructor declaration // get the signature from the declaration and write it - const functionDeclaration = location.parent as SignatureDeclaration; + const functionDeclaration = location.parent as ts.SignatureDeclaration; // Use function declaration to write the signatures only if the symbol corresponding to this declaration - const locationIsSymbolDeclaration = symbol.declarations && find(symbol.declarations, declaration => - declaration === (location.kind === SyntaxKind.ConstructorKeyword ? functionDeclaration.parent : functionDeclaration)); + const locationIsSymbolDeclaration = symbol.declarations && ts.find(symbol.declarations, declaration => declaration === (location.kind === ts.SyntaxKind.ConstructorKeyword ? functionDeclaration.parent : functionDeclaration)); if (locationIsSymbolDeclaration) { - const allSignatures = functionDeclaration.kind === SyntaxKind.Constructor ? type.getNonNullableType().getConstructSignatures() : type.getNonNullableType().getCallSignatures(); + const allSignatures = functionDeclaration.kind === ts.SyntaxKind.Constructor ? type.getNonNullableType().getConstructSignatures() : type.getNonNullableType().getCallSignatures(); if (!typeChecker.isImplementationOfOverload(functionDeclaration)) { signature = typeChecker.getSignatureFromDeclaration(functionDeclaration); // TODO: GH#18217 } @@ -287,15 +296,15 @@ namespace ts.SymbolDisplay { signature = allSignatures[0]; } - if (functionDeclaration.kind === SyntaxKind.Constructor) { + if (functionDeclaration.kind === ts.SyntaxKind.Constructor) { // show (constructor) Type(...) signature - symbolKind = ScriptElementKind.constructorImplementationElement; + symbolKind = ts.ScriptElementKind.constructorImplementationElement; addPrefixForAnyFunctionOrVar(type.symbol, symbolKind); } else { // (function/method) symbol(..signature) - addPrefixForAnyFunctionOrVar(functionDeclaration.kind === SyntaxKind.CallSignature && - !(type.symbol.flags & SymbolFlags.TypeLiteral || type.symbol.flags & SymbolFlags.ObjectLiteral) ? type.symbol : symbol, symbolKind); + addPrefixForAnyFunctionOrVar(functionDeclaration.kind === ts.SyntaxKind.CallSignature && + !(type.symbol.flags & ts.SymbolFlags.TypeLiteral || type.symbol.flags & ts.SymbolFlags.ObjectLiteral) ? type.symbol : symbol, symbolKind); } if (signature) { addSignatureDisplayParts(signature, allSignatures); @@ -305,64 +314,64 @@ namespace ts.SymbolDisplay { } } } - if (symbolFlags & SymbolFlags.Class && !hasAddedSymbolInfo && !isThisExpression) { + if (symbolFlags & ts.SymbolFlags.Class && !hasAddedSymbolInfo && !isThisExpression) { addAliasPrefixIfNecessary(); - if (getDeclarationOfKind(symbol, SyntaxKind.ClassExpression)) { + if (ts.getDeclarationOfKind(symbol, ts.SyntaxKind.ClassExpression)) { // Special case for class expressions because we would like to indicate that // the class name is local to the class body (similar to function expression) // (local class) class - pushSymbolKind(ScriptElementKind.localClassElement); + pushSymbolKind(ts.ScriptElementKind.localClassElement); } else { // Class declaration has name which is not local. - displayParts.push(keywordPart(SyntaxKind.ClassKeyword)); + displayParts.push(ts.keywordPart(ts.SyntaxKind.ClassKeyword)); } - displayParts.push(spacePart()); + displayParts.push(ts.spacePart()); addFullSymbolName(symbol); writeTypeParametersOfSymbol(symbol, sourceFile); } - if ((symbolFlags & SymbolFlags.Interface) && (semanticMeaning & SemanticMeaning.Type)) { + if ((symbolFlags & ts.SymbolFlags.Interface) && (semanticMeaning & ts.SemanticMeaning.Type)) { prefixNextMeaning(); - displayParts.push(keywordPart(SyntaxKind.InterfaceKeyword)); - displayParts.push(spacePart()); + displayParts.push(ts.keywordPart(ts.SyntaxKind.InterfaceKeyword)); + displayParts.push(ts.spacePart()); addFullSymbolName(symbol); writeTypeParametersOfSymbol(symbol, sourceFile); } - if ((symbolFlags & SymbolFlags.TypeAlias) && (semanticMeaning & SemanticMeaning.Type)) { + if ((symbolFlags & ts.SymbolFlags.TypeAlias) && (semanticMeaning & ts.SemanticMeaning.Type)) { prefixNextMeaning(); - displayParts.push(keywordPart(SyntaxKind.TypeKeyword)); - displayParts.push(spacePart()); + displayParts.push(ts.keywordPart(ts.SyntaxKind.TypeKeyword)); + displayParts.push(ts.spacePart()); addFullSymbolName(symbol); writeTypeParametersOfSymbol(symbol, sourceFile); - displayParts.push(spacePart()); - displayParts.push(operatorPart(SyntaxKind.EqualsToken)); - displayParts.push(spacePart()); - addRange(displayParts, typeToDisplayParts(typeChecker, isConstTypeReference(location.parent) ? typeChecker.getTypeAtLocation(location.parent) : typeChecker.getDeclaredTypeOfSymbol(symbol), enclosingDeclaration, TypeFormatFlags.InTypeAlias)); + displayParts.push(ts.spacePart()); + displayParts.push(ts.operatorPart(ts.SyntaxKind.EqualsToken)); + displayParts.push(ts.spacePart()); + ts.addRange(displayParts, ts.typeToDisplayParts(typeChecker, ts.isConstTypeReference(location.parent) ? typeChecker.getTypeAtLocation(location.parent) : typeChecker.getDeclaredTypeOfSymbol(symbol), enclosingDeclaration, ts.TypeFormatFlags.InTypeAlias)); } - if (symbolFlags & SymbolFlags.Enum) { + if (symbolFlags & ts.SymbolFlags.Enum) { prefixNextMeaning(); - if (some(symbol.declarations, d => isEnumDeclaration(d) && isEnumConst(d))) { - displayParts.push(keywordPart(SyntaxKind.ConstKeyword)); - displayParts.push(spacePart()); + if (ts.some(symbol.declarations, d => ts.isEnumDeclaration(d) && ts.isEnumConst(d))) { + displayParts.push(ts.keywordPart(ts.SyntaxKind.ConstKeyword)); + displayParts.push(ts.spacePart()); } - displayParts.push(keywordPart(SyntaxKind.EnumKeyword)); - displayParts.push(spacePart()); + displayParts.push(ts.keywordPart(ts.SyntaxKind.EnumKeyword)); + displayParts.push(ts.spacePart()); addFullSymbolName(symbol); } - if (symbolFlags & SymbolFlags.Module && !isThisExpression) { + if (symbolFlags & ts.SymbolFlags.Module && !isThisExpression) { prefixNextMeaning(); - const declaration = getDeclarationOfKind(symbol, SyntaxKind.ModuleDeclaration); - const isNamespace = declaration && declaration.name && declaration.name.kind === SyntaxKind.Identifier; - displayParts.push(keywordPart(isNamespace ? SyntaxKind.NamespaceKeyword : SyntaxKind.ModuleKeyword)); - displayParts.push(spacePart()); + const declaration = ts.getDeclarationOfKind(symbol, ts.SyntaxKind.ModuleDeclaration); + const isNamespace = declaration && declaration.name && declaration.name.kind === ts.SyntaxKind.Identifier; + displayParts.push(ts.keywordPart(isNamespace ? ts.SyntaxKind.NamespaceKeyword : ts.SyntaxKind.ModuleKeyword)); + displayParts.push(ts.spacePart()); addFullSymbolName(symbol); } - if ((symbolFlags & SymbolFlags.TypeParameter) && (semanticMeaning & SemanticMeaning.Type)) { + if ((symbolFlags & ts.SymbolFlags.TypeParameter) && (semanticMeaning & ts.SemanticMeaning.Type)) { prefixNextMeaning(); - displayParts.push(punctuationPart(SyntaxKind.OpenParenToken)); - displayParts.push(textPart("type parameter")); - displayParts.push(punctuationPart(SyntaxKind.CloseParenToken)); - displayParts.push(spacePart()); + displayParts.push(ts.punctuationPart(ts.SyntaxKind.OpenParenToken)); + displayParts.push(ts.textPart("type parameter")); + displayParts.push(ts.punctuationPart(ts.SyntaxKind.CloseParenToken)); + displayParts.push(ts.spacePart()); addFullSymbolName(symbol); if (symbol.parent) { // Class/Interface type parameter @@ -372,74 +381,66 @@ namespace ts.SymbolDisplay { } else { // Method/function type parameter - const decl = getDeclarationOfKind(symbol, SyntaxKind.TypeParameter); - if (decl === undefined) return Debug.fail(); + const decl = ts.getDeclarationOfKind(symbol, ts.SyntaxKind.TypeParameter); + if (decl === undefined) + return ts.Debug.fail(); const declaration = decl.parent; if (declaration) { - if (isFunctionLikeKind(declaration.kind)) { + if (ts.isFunctionLikeKind(declaration.kind)) { addInPrefix(); - const signature = typeChecker.getSignatureFromDeclaration(declaration as SignatureDeclaration)!; // TODO: GH#18217 - if (declaration.kind === SyntaxKind.ConstructSignature) { - displayParts.push(keywordPart(SyntaxKind.NewKeyword)); - displayParts.push(spacePart()); + const signature = typeChecker.getSignatureFromDeclaration(declaration as ts.SignatureDeclaration)!; // TODO: GH#18217 + if (declaration.kind === ts.SyntaxKind.ConstructSignature) { + displayParts.push(ts.keywordPart(ts.SyntaxKind.NewKeyword)); + displayParts.push(ts.spacePart()); } - else if (declaration.kind !== SyntaxKind.CallSignature && (declaration as SignatureDeclaration).name) { + else if (declaration.kind !== ts.SyntaxKind.CallSignature && (declaration as ts.SignatureDeclaration).name) { addFullSymbolName(declaration.symbol); } - addRange(displayParts, signatureToDisplayParts(typeChecker, signature, sourceFile, TypeFormatFlags.WriteTypeArgumentsOfSignature)); + ts.addRange(displayParts, ts.signatureToDisplayParts(typeChecker, signature, sourceFile, ts.TypeFormatFlags.WriteTypeArgumentsOfSignature)); } - else if (declaration.kind === SyntaxKind.TypeAliasDeclaration) { + else if (declaration.kind === ts.SyntaxKind.TypeAliasDeclaration) { // Type alias type parameter // For example // type list = T[]; // Both T will go through same code path addInPrefix(); - displayParts.push(keywordPart(SyntaxKind.TypeKeyword)); - displayParts.push(spacePart()); + displayParts.push(ts.keywordPart(ts.SyntaxKind.TypeKeyword)); + displayParts.push(ts.spacePart()); addFullSymbolName(declaration.symbol); writeTypeParametersOfSymbol(declaration.symbol, sourceFile); } } } } - if (symbolFlags & SymbolFlags.EnumMember) { - symbolKind = ScriptElementKind.enumMemberElement; + if (symbolFlags & ts.SymbolFlags.EnumMember) { + symbolKind = ts.ScriptElementKind.enumMemberElement; addPrefixForAnyFunctionOrVar(symbol, "enum member"); const declaration = symbol.declarations?.[0]; - if (declaration?.kind === SyntaxKind.EnumMember) { - const constantValue = typeChecker.getConstantValue(declaration as EnumMember); + if (declaration?.kind === ts.SyntaxKind.EnumMember) { + const constantValue = typeChecker.getConstantValue(declaration as ts.EnumMember); if (constantValue !== undefined) { - displayParts.push(spacePart()); - displayParts.push(operatorPart(SyntaxKind.EqualsToken)); - displayParts.push(spacePart()); - displayParts.push(displayPart(getTextOfConstantValue(constantValue), - typeof constantValue === "number" ? SymbolDisplayPartKind.numericLiteral : SymbolDisplayPartKind.stringLiteral)); + displayParts.push(ts.spacePart()); + displayParts.push(ts.operatorPart(ts.SyntaxKind.EqualsToken)); + displayParts.push(ts.spacePart()); + displayParts.push(ts.displayPart(ts.getTextOfConstantValue(constantValue), typeof constantValue === "number" ? ts.SymbolDisplayPartKind.numericLiteral : ts.SymbolDisplayPartKind.stringLiteral)); } } } // don't use symbolFlags since getAliasedSymbol requires the flag on the symbol itself - if (symbol.flags & SymbolFlags.Alias) { + if (symbol.flags & ts.SymbolFlags.Alias) { prefixNextMeaning(); if (!hasAddedSymbolInfo) { const resolvedSymbol = typeChecker.getAliasedSymbol(symbol); if (resolvedSymbol !== symbol && resolvedSymbol.declarations && resolvedSymbol.declarations.length > 0) { const resolvedNode = resolvedSymbol.declarations[0]; - const declarationName = getNameOfDeclaration(resolvedNode); + const declarationName = ts.getNameOfDeclaration(resolvedNode); if (declarationName) { - const isExternalModuleDeclaration = - isModuleWithStringLiteralName(resolvedNode) && - hasSyntacticModifier(resolvedNode, ModifierFlags.Ambient); + const isExternalModuleDeclaration = ts.isModuleWithStringLiteralName(resolvedNode) && + ts.hasSyntacticModifier(resolvedNode, ts.ModifierFlags.Ambient); const shouldUseAliasName = symbol.name !== "default" && !isExternalModuleDeclaration; - const resolvedInfo = getSymbolDisplayPartsDocumentationAndSymbolKind( - typeChecker, - resolvedSymbol, - getSourceFileOfNode(resolvedNode), - resolvedNode, - declarationName, - semanticMeaning, - shouldUseAliasName ? symbol : resolvedSymbol); + const resolvedInfo = getSymbolDisplayPartsDocumentationAndSymbolKind(typeChecker, resolvedSymbol, ts.getSourceFileOfNode(resolvedNode), resolvedNode, declarationName, semanticMeaning, shouldUseAliasName ? symbol : resolvedSymbol); displayParts.push(...resolvedInfo.displayParts); - displayParts.push(lineBreakPart()); + displayParts.push(ts.lineBreakPart()); documentationFromAlias = resolvedInfo.documentation; tagsFromAlias = resolvedInfo.tags; } @@ -452,43 +453,43 @@ namespace ts.SymbolDisplay { if (symbol.declarations) { switch (symbol.declarations[0].kind) { - case SyntaxKind.NamespaceExportDeclaration: - displayParts.push(keywordPart(SyntaxKind.ExportKeyword)); - displayParts.push(spacePart()); - displayParts.push(keywordPart(SyntaxKind.NamespaceKeyword)); + case ts.SyntaxKind.NamespaceExportDeclaration: + displayParts.push(ts.keywordPart(ts.SyntaxKind.ExportKeyword)); + displayParts.push(ts.spacePart()); + displayParts.push(ts.keywordPart(ts.SyntaxKind.NamespaceKeyword)); break; - case SyntaxKind.ExportAssignment: - displayParts.push(keywordPart(SyntaxKind.ExportKeyword)); - displayParts.push(spacePart()); - displayParts.push(keywordPart((symbol.declarations[0] as ExportAssignment).isExportEquals ? SyntaxKind.EqualsToken : SyntaxKind.DefaultKeyword)); + case ts.SyntaxKind.ExportAssignment: + displayParts.push(ts.keywordPart(ts.SyntaxKind.ExportKeyword)); + displayParts.push(ts.spacePart()); + displayParts.push(ts.keywordPart((symbol.declarations[0] as ts.ExportAssignment).isExportEquals ? ts.SyntaxKind.EqualsToken : ts.SyntaxKind.DefaultKeyword)); break; - case SyntaxKind.ExportSpecifier: - displayParts.push(keywordPart(SyntaxKind.ExportKeyword)); + case ts.SyntaxKind.ExportSpecifier: + displayParts.push(ts.keywordPart(ts.SyntaxKind.ExportKeyword)); break; default: - displayParts.push(keywordPart(SyntaxKind.ImportKeyword)); + displayParts.push(ts.keywordPart(ts.SyntaxKind.ImportKeyword)); } } - displayParts.push(spacePart()); + displayParts.push(ts.spacePart()); addFullSymbolName(symbol); - forEach(symbol.declarations, declaration => { - if (declaration.kind === SyntaxKind.ImportEqualsDeclaration) { - const importEqualsDeclaration = declaration as ImportEqualsDeclaration; - if (isExternalModuleImportEqualsDeclaration(importEqualsDeclaration)) { - displayParts.push(spacePart()); - displayParts.push(operatorPart(SyntaxKind.EqualsToken)); - displayParts.push(spacePart()); - displayParts.push(keywordPart(SyntaxKind.RequireKeyword)); - displayParts.push(punctuationPart(SyntaxKind.OpenParenToken)); - displayParts.push(displayPart(getTextOfNode(getExternalModuleImportEqualsDeclarationExpression(importEqualsDeclaration)), SymbolDisplayPartKind.stringLiteral)); - displayParts.push(punctuationPart(SyntaxKind.CloseParenToken)); + ts.forEach(symbol.declarations, declaration => { + if (declaration.kind === ts.SyntaxKind.ImportEqualsDeclaration) { + const importEqualsDeclaration = declaration as ts.ImportEqualsDeclaration; + if (ts.isExternalModuleImportEqualsDeclaration(importEqualsDeclaration)) { + displayParts.push(ts.spacePart()); + displayParts.push(ts.operatorPart(ts.SyntaxKind.EqualsToken)); + displayParts.push(ts.spacePart()); + displayParts.push(ts.keywordPart(ts.SyntaxKind.RequireKeyword)); + displayParts.push(ts.punctuationPart(ts.SyntaxKind.OpenParenToken)); + displayParts.push(ts.displayPart(ts.getTextOfNode(ts.getExternalModuleImportEqualsDeclarationExpression(importEqualsDeclaration)), ts.SymbolDisplayPartKind.stringLiteral)); + displayParts.push(ts.punctuationPart(ts.SyntaxKind.CloseParenToken)); } else { const internalAliasSymbol = typeChecker.getSymbolAtLocation(importEqualsDeclaration.moduleReference); if (internalAliasSymbol) { - displayParts.push(spacePart()); - displayParts.push(operatorPart(SyntaxKind.EqualsToken)); - displayParts.push(spacePart()); + displayParts.push(ts.spacePart()); + displayParts.push(ts.operatorPart(ts.SyntaxKind.EqualsToken)); + displayParts.push(ts.spacePart()); addFullSymbolName(internalAliasSymbol, enclosingDeclaration); } } @@ -497,52 +498,52 @@ namespace ts.SymbolDisplay { }); } if (!hasAddedSymbolInfo) { - if (symbolKind !== ScriptElementKind.unknown) { + if (symbolKind !== ts.ScriptElementKind.unknown) { if (type) { if (isThisExpression) { prefixNextMeaning(); - displayParts.push(keywordPart(SyntaxKind.ThisKeyword)); + displayParts.push(ts.keywordPart(ts.SyntaxKind.ThisKeyword)); } else { addPrefixForAnyFunctionOrVar(symbol, symbolKind); } // For properties, variables and local vars: show the type - if (symbolKind === ScriptElementKind.memberVariableElement || - symbolKind === ScriptElementKind.memberGetAccessorElement || - symbolKind === ScriptElementKind.memberSetAccessorElement || - symbolKind === ScriptElementKind.jsxAttribute || - symbolFlags & SymbolFlags.Variable || - symbolKind === ScriptElementKind.localVariableElement || + if (symbolKind === ts.ScriptElementKind.memberVariableElement || + symbolKind === ts.ScriptElementKind.memberGetAccessorElement || + symbolKind === ts.ScriptElementKind.memberSetAccessorElement || + symbolKind === ts.ScriptElementKind.jsxAttribute || + symbolFlags & ts.SymbolFlags.Variable || + symbolKind === ts.ScriptElementKind.localVariableElement || isThisExpression) { - displayParts.push(punctuationPart(SyntaxKind.ColonToken)); - displayParts.push(spacePart()); + displayParts.push(ts.punctuationPart(ts.SyntaxKind.ColonToken)); + displayParts.push(ts.spacePart()); // If the type is type parameter, format it specially - if (type.symbol && type.symbol.flags & SymbolFlags.TypeParameter) { - const typeParameterParts = mapToDisplayParts(writer => { - const param = typeChecker.typeParameterToDeclaration(type as TypeParameter, enclosingDeclaration, symbolDisplayNodeBuilderFlags)!; - getPrinter().writeNode(EmitHint.Unspecified, param, getSourceFileOfNode(getParseTreeNode(enclosingDeclaration)), writer); + if (type.symbol && type.symbol.flags & ts.SymbolFlags.TypeParameter) { + const typeParameterParts = ts.mapToDisplayParts(writer => { + const param = typeChecker.typeParameterToDeclaration(type as ts.TypeParameter, enclosingDeclaration, symbolDisplayNodeBuilderFlags)!; + getPrinter().writeNode(ts.EmitHint.Unspecified, param, ts.getSourceFileOfNode(ts.getParseTreeNode(enclosingDeclaration)), writer); }); - addRange(displayParts, typeParameterParts); + ts.addRange(displayParts, typeParameterParts); } else { - addRange(displayParts, typeToDisplayParts(typeChecker, type, enclosingDeclaration)); + ts.addRange(displayParts, ts.typeToDisplayParts(typeChecker, type, enclosingDeclaration)); } - if ((symbol as TransientSymbol).target && ((symbol as TransientSymbol).target as TransientSymbol).tupleLabelDeclaration) { - const labelDecl = ((symbol as TransientSymbol).target as TransientSymbol).tupleLabelDeclaration!; - Debug.assertNode(labelDecl.name, isIdentifier); - displayParts.push(spacePart()); - displayParts.push(punctuationPart(SyntaxKind.OpenParenToken)); - displayParts.push(textPart(idText(labelDecl.name))); - displayParts.push(punctuationPart(SyntaxKind.CloseParenToken)); + if ((symbol as ts.TransientSymbol).target && ((symbol as ts.TransientSymbol).target as ts.TransientSymbol).tupleLabelDeclaration) { + const labelDecl = ((symbol as ts.TransientSymbol).target as ts.TransientSymbol).tupleLabelDeclaration!; + ts.Debug.assertNode(labelDecl.name, ts.isIdentifier); + displayParts.push(ts.spacePart()); + displayParts.push(ts.punctuationPart(ts.SyntaxKind.OpenParenToken)); + displayParts.push(ts.textPart(ts.idText(labelDecl.name))); + displayParts.push(ts.punctuationPart(ts.SyntaxKind.CloseParenToken)); } } - else if (symbolFlags & SymbolFlags.Function || - symbolFlags & SymbolFlags.Method || - symbolFlags & SymbolFlags.Constructor || - symbolFlags & SymbolFlags.Signature || - symbolFlags & SymbolFlags.Accessor || - symbolKind === ScriptElementKind.memberFunctionElement) { + else if (symbolFlags & ts.SymbolFlags.Function || + symbolFlags & ts.SymbolFlags.Method || + symbolFlags & ts.SymbolFlags.Constructor || + symbolFlags & ts.SymbolFlags.Signature || + symbolFlags & ts.SymbolFlags.Accessor || + symbolKind === ts.ScriptElementKind.memberFunctionElement) { const allSignatures = type.getNonNullableType().getCallSignatures(); if (allSignatures.length) { addSignatureDisplayParts(allSignatures[0], allSignatures); @@ -560,17 +561,17 @@ namespace ts.SymbolDisplay { documentation = symbol.getContextualDocumentationComment(enclosingDeclaration, typeChecker); } - if (documentation.length === 0 && symbolFlags & SymbolFlags.Property) { + if (documentation.length === 0 && symbolFlags & ts.SymbolFlags.Property) { // For some special property access expressions like `exports.foo = foo` or `module.exports.foo = foo` // there documentation comments might be attached to the right hand side symbol of their declarations. // The pattern of such special property access is that the parent symbol is the symbol of the file. - if (symbol.parent && symbol.declarations && forEach(symbol.parent.declarations, declaration => declaration.kind === SyntaxKind.SourceFile)) { + if (symbol.parent && symbol.declarations && ts.forEach(symbol.parent.declarations, declaration => declaration.kind === ts.SyntaxKind.SourceFile)) { for (const declaration of symbol.declarations) { - if (!declaration.parent || declaration.parent.kind !== SyntaxKind.BinaryExpression) { + if (!declaration.parent || declaration.parent.kind !== ts.SyntaxKind.BinaryExpression) { continue; } - const rhsSymbol = typeChecker.getSymbolAtLocation((declaration.parent as BinaryExpression).right); + const rhsSymbol = typeChecker.getSymbolAtLocation((declaration.parent as ts.BinaryExpression).right); if (!rhsSymbol) { continue; } @@ -584,16 +585,16 @@ namespace ts.SymbolDisplay { } } - if (documentation.length === 0 && isIdentifier(location) && symbol.valueDeclaration && isBindingElement(symbol.valueDeclaration)) { + if (documentation.length === 0 && ts.isIdentifier(location) && symbol.valueDeclaration && ts.isBindingElement(symbol.valueDeclaration)) { const declaration = symbol.valueDeclaration; const parent = declaration.parent; - if (isIdentifier(declaration.name) && isObjectBindingPattern(parent)) { - const name = getTextOfIdentifierOrLiteral(declaration.name); + if (ts.isIdentifier(declaration.name) && ts.isObjectBindingPattern(parent)) { + const name = ts.getTextOfIdentifierOrLiteral(declaration.name); const objectType = typeChecker.getTypeAtLocation(parent); - documentation = firstDefined(objectType.isUnion() ? objectType.types : [objectType], t => { + documentation = ts.firstDefined(objectType.isUnion() ? objectType.types : [objectType], t => { const prop = t.getProperty(name); return prop ? prop.getDocumentationComment(typeChecker) : undefined; - }) || emptyArray; + }) || ts.emptyArray; } } @@ -613,50 +614,48 @@ namespace ts.SymbolDisplay { function getPrinter() { if (!printer) { - printer = createPrinter({ removeComments: true }); + printer = ts.createPrinter({ removeComments: true }); } return printer; } function prefixNextMeaning() { if (displayParts.length) { - displayParts.push(lineBreakPart()); + displayParts.push(ts.lineBreakPart()); } addAliasPrefixIfNecessary(); } function addAliasPrefixIfNecessary() { if (alias) { - pushSymbolKind(ScriptElementKind.alias); - displayParts.push(spacePart()); + pushSymbolKind(ts.ScriptElementKind.alias); + displayParts.push(ts.spacePart()); } } function addInPrefix() { - displayParts.push(spacePart()); - displayParts.push(keywordPart(SyntaxKind.InKeyword)); - displayParts.push(spacePart()); + displayParts.push(ts.spacePart()); + displayParts.push(ts.keywordPart(ts.SyntaxKind.InKeyword)); + displayParts.push(ts.spacePart()); } - function addFullSymbolName(symbolToDisplay: Symbol, enclosingDeclaration?: Node) { + function addFullSymbolName(symbolToDisplay: ts.Symbol, enclosingDeclaration?: ts.Node) { if (alias && symbolToDisplay === symbol) { symbolToDisplay = alias; } - const fullSymbolDisplayParts = symbolToDisplayParts(typeChecker, symbolToDisplay, enclosingDeclaration || sourceFile, /*meaning*/ undefined, - SymbolFormatFlags.WriteTypeParametersOrArguments | SymbolFormatFlags.UseOnlyExternalAliasing | SymbolFormatFlags.AllowAnyNodeKind); - addRange(displayParts, fullSymbolDisplayParts); - - if (symbol.flags & SymbolFlags.Optional) { - displayParts.push(punctuationPart(SyntaxKind.QuestionToken)); + const fullSymbolDisplayParts = ts.symbolToDisplayParts(typeChecker, symbolToDisplay, enclosingDeclaration || sourceFile, /*meaning*/ undefined, ts.SymbolFormatFlags.WriteTypeParametersOrArguments | ts.SymbolFormatFlags.UseOnlyExternalAliasing | ts.SymbolFormatFlags.AllowAnyNodeKind); + ts.addRange(displayParts, fullSymbolDisplayParts); + if (symbol.flags & ts.SymbolFlags.Optional) { + displayParts.push(ts.punctuationPart(ts.SyntaxKind.QuestionToken)); } } - function addPrefixForAnyFunctionOrVar(symbol: Symbol, symbolKind: string) { + function addPrefixForAnyFunctionOrVar(symbol: ts.Symbol, symbolKind: string) { prefixNextMeaning(); if (symbolKind) { pushSymbolKind(symbolKind); - if (symbol && !some(symbol.declarations, d => isArrowFunction(d) || (isFunctionExpression(d) || isClassExpression(d)) && !d.name)) { - displayParts.push(spacePart()); + if (symbol && !ts.some(symbol.declarations, d => ts.isArrowFunction(d) || (ts.isFunctionExpression(d) || ts.isClassExpression(d)) && !d.name)) { + displayParts.push(ts.spacePart()); addFullSymbolName(symbol); } } @@ -664,31 +663,31 @@ namespace ts.SymbolDisplay { function pushSymbolKind(symbolKind: string) { switch (symbolKind) { - case ScriptElementKind.variableElement: - case ScriptElementKind.functionElement: - case ScriptElementKind.letElement: - case ScriptElementKind.constElement: - case ScriptElementKind.constructorImplementationElement: - displayParts.push(textOrKeywordPart(symbolKind)); + case ts.ScriptElementKind.variableElement: + case ts.ScriptElementKind.functionElement: + case ts.ScriptElementKind.letElement: + case ts.ScriptElementKind.constElement: + case ts.ScriptElementKind.constructorImplementationElement: + displayParts.push(ts.textOrKeywordPart(symbolKind)); return; default: - displayParts.push(punctuationPart(SyntaxKind.OpenParenToken)); - displayParts.push(textOrKeywordPart(symbolKind)); - displayParts.push(punctuationPart(SyntaxKind.CloseParenToken)); + displayParts.push(ts.punctuationPart(ts.SyntaxKind.OpenParenToken)); + displayParts.push(ts.textOrKeywordPart(symbolKind)); + displayParts.push(ts.punctuationPart(ts.SyntaxKind.CloseParenToken)); return; } } - function addSignatureDisplayParts(signature: Signature, allSignatures: readonly Signature[], flags = TypeFormatFlags.None) { - addRange(displayParts, signatureToDisplayParts(typeChecker, signature, enclosingDeclaration, flags | TypeFormatFlags.WriteTypeArgumentsOfSignature)); + function addSignatureDisplayParts(signature: ts.Signature, allSignatures: readonly ts.Signature[], flags = ts.TypeFormatFlags.None) { + ts.addRange(displayParts, ts.signatureToDisplayParts(typeChecker, signature, enclosingDeclaration, flags | ts.TypeFormatFlags.WriteTypeArgumentsOfSignature)); if (allSignatures.length > 1) { - displayParts.push(spacePart()); - displayParts.push(punctuationPart(SyntaxKind.OpenParenToken)); - displayParts.push(operatorPart(SyntaxKind.PlusToken)); - displayParts.push(displayPart((allSignatures.length - 1).toString(), SymbolDisplayPartKind.numericLiteral)); - displayParts.push(spacePart()); - displayParts.push(textPart(allSignatures.length === 2 ? "overload" : "overloads")); - displayParts.push(punctuationPart(SyntaxKind.CloseParenToken)); + displayParts.push(ts.spacePart()); + displayParts.push(ts.punctuationPart(ts.SyntaxKind.OpenParenToken)); + displayParts.push(ts.operatorPart(ts.SyntaxKind.PlusToken)); + displayParts.push(ts.displayPart((allSignatures.length - 1).toString(), ts.SymbolDisplayPartKind.numericLiteral)); + displayParts.push(ts.spacePart()); + displayParts.push(ts.textPart(allSignatures.length === 2 ? "overload" : "overloads")); + displayParts.push(ts.punctuationPart(ts.SyntaxKind.CloseParenToken)); } documentation = signature.getDocumentationComment(typeChecker); tags = signature.getJsDocTags(); @@ -699,34 +698,34 @@ namespace ts.SymbolDisplay { } } - function writeTypeParametersOfSymbol(symbol: Symbol, enclosingDeclaration: Node | undefined) { - const typeParameterParts = mapToDisplayParts(writer => { + function writeTypeParametersOfSymbol(symbol: ts.Symbol, enclosingDeclaration: ts.Node | undefined) { + const typeParameterParts = ts.mapToDisplayParts(writer => { const params = typeChecker.symbolToTypeParameterDeclarations(symbol, enclosingDeclaration, symbolDisplayNodeBuilderFlags); - getPrinter().writeList(ListFormat.TypeParameters, params, getSourceFileOfNode(getParseTreeNode(enclosingDeclaration)), writer); + getPrinter().writeList(ts.ListFormat.TypeParameters, params, ts.getSourceFileOfNode(ts.getParseTreeNode(enclosingDeclaration)), writer); }); - addRange(displayParts, typeParameterParts); + ts.addRange(displayParts, typeParameterParts); } } - function isLocalVariableOrFunction(symbol: Symbol) { + function isLocalVariableOrFunction(symbol: ts.Symbol) { if (symbol.parent) { return false; // This is exported symbol } - return forEach(symbol.declarations, declaration => { + return ts.forEach(symbol.declarations, declaration => { // Function expressions are local - if (declaration.kind === SyntaxKind.FunctionExpression) { + if (declaration.kind === ts.SyntaxKind.FunctionExpression) { return true; } - if (declaration.kind !== SyntaxKind.VariableDeclaration && declaration.kind !== SyntaxKind.FunctionDeclaration) { + if (declaration.kind !== ts.SyntaxKind.VariableDeclaration && declaration.kind !== ts.SyntaxKind.FunctionDeclaration) { return false; } // If the parent is not sourceFile or module block it is local variable - for (let parent = declaration.parent; !isFunctionBlock(parent); parent = parent.parent) { + for (let parent = declaration.parent; !ts.isFunctionBlock(parent); parent = parent.parent) { // Reached source file or module block - if (parent.kind === SyntaxKind.SourceFile || parent.kind === SyntaxKind.ModuleBlock) { + if (parent.kind === ts.SyntaxKind.SourceFile || parent.kind === ts.SyntaxKind.ModuleBlock) { return false; } } diff --git a/src/services/textChanges.ts b/src/services/textChanges.ts index 9765e8a4fdaba..d3e54cd62f134 100644 --- a/src/services/textChanges.ts +++ b/src/services/textChanges.ts @@ -5,25 +5,25 @@ namespace ts.textChanges { * Currently for simplicity we store recovered positions on the node itself. * It can be changed to side-table later if we decide that current design is too invasive. */ - function getPos(n: TextRange): number { + function getPos(n: ts.TextRange): number { const result = (n as any).__pos; - Debug.assert(typeof result === "number"); + ts.Debug.assert(typeof result === "number"); return result; } - function setPos(n: TextRange, pos: number): void { - Debug.assert(typeof pos === "number"); + function setPos(n: ts.TextRange, pos: number): void { + ts.Debug.assert(typeof pos === "number"); (n as any).__pos = pos; } - function getEnd(n: TextRange): number { + function getEnd(n: ts.TextRange): number { const result = (n as any).__end; - Debug.assert(typeof result === "number"); + ts.Debug.assert(typeof result === "number"); return result; } - function setEnd(n: TextRange, end: number): void { - Debug.assert(typeof end === "number"); + function setEnd(n: ts.TextRange, end: number): void { + ts.Debug.assert(typeof end === "number"); (n as any).__end = end; } @@ -50,7 +50,7 @@ namespace ts.textChanges { * Only delete trivia on the same line as getStart(). * Used to avoid deleting leading comments */ - StartLine, + StartLine } export enum TrailingTriviaOption { @@ -59,22 +59,22 @@ namespace ts.textChanges { /** Doesn't include whitespace, but does strip comments */ ExcludeWhitespace, /** Include trailing trivia */ - Include, + Include } function skipWhitespacesAndLineBreaks(text: string, start: number) { - return skipTrivia(text, start, /*stopAfterLineBreak*/ false, /*stopAtComments*/ true); + return ts.skipTrivia(text, start, /*stopAfterLineBreak*/ false, /*stopAtComments*/ true); } function hasCommentsBeforeLineBreak(text: string, start: number) { let i = start; while (i < text.length) { const ch = text.charCodeAt(i); - if (isWhiteSpaceSingleLine(ch)) { + if (ts.isWhiteSpaceSingleLine(ch)) { i++; continue; } - return ch === CharacterCodes.slash; + return ch === ts.CharacterCodes.slash; } return false; } @@ -92,7 +92,8 @@ namespace ts.textChanges { * If pos\end should be interpreted literally (that is, withouth including leading and trailing trivia), `leadingTriviaOption` should be set to `LeadingTriviaOption.Exclude` * and `trailingTriviaOption` to `TrailingTriviaOption.Exclude`. */ - export interface ConfigurableStartEnd extends ConfigurableStart, ConfigurableEnd {} + export interface ConfigurableStartEnd extends ConfigurableStart, ConfigurableEnd { + } const useNonAdjustedPositions: ConfigurableStartEnd = { leadingTriviaOption: LeadingTriviaOption.Exclude, @@ -126,20 +127,21 @@ namespace ts.textChanges { Remove, ReplaceWithSingleNode, ReplaceWithMultipleNodes, - Text, + Text } type Change = ReplaceWithSingleNode | ReplaceWithMultipleNodes | RemoveNode | ChangeText; interface BaseChange { - readonly sourceFile: SourceFile; - readonly range: TextRange; + readonly sourceFile: ts.SourceFile; + readonly range: ts.TextRange; + } + export interface ChangeNodeOptions extends ConfigurableStartEnd, InsertNodeOptions { } - export interface ChangeNodeOptions extends ConfigurableStartEnd, InsertNodeOptions {} interface ReplaceWithSingleNode extends BaseChange { readonly kind: ChangeKind.ReplaceWithSingleNode; - readonly node: Node; + readonly node: ts.Node; readonly options?: InsertNodeOptions; } @@ -151,7 +153,7 @@ namespace ts.textChanges { interface ReplaceWithMultipleNodes extends BaseChange { readonly kind: ChangeKind.ReplaceWithMultipleNodes; - readonly nodes: readonly Node[]; + readonly nodes: readonly ts.Node[]; readonly options?: ReplaceWithMultipleNodesOptions; } @@ -160,24 +162,24 @@ namespace ts.textChanges { readonly text: string; } - function getAdjustedRange(sourceFile: SourceFile, startNode: Node, endNode: Node, options: ConfigurableStartEnd): TextRange { + function getAdjustedRange(sourceFile: ts.SourceFile, startNode: ts.Node, endNode: ts.Node, options: ConfigurableStartEnd): ts.TextRange { return { pos: getAdjustedStartPosition(sourceFile, startNode, options), end: getAdjustedEndPosition(sourceFile, endNode, options) }; } - function getAdjustedStartPosition(sourceFile: SourceFile, node: Node, options: ConfigurableStartEnd, hasTrailingComment = false) { + function getAdjustedStartPosition(sourceFile: ts.SourceFile, node: ts.Node, options: ConfigurableStartEnd, hasTrailingComment = false) { const { leadingTriviaOption } = options; if (leadingTriviaOption === LeadingTriviaOption.Exclude) { return node.getStart(sourceFile); } if (leadingTriviaOption === LeadingTriviaOption.StartLine) { const startPos = node.getStart(sourceFile); - const pos = getLineStartPositionForPosition(startPos, sourceFile); - return rangeContainsPosition(node, pos) ? pos : startPos; + const pos = ts.getLineStartPositionForPosition(startPos, sourceFile); + return ts.rangeContainsPosition(node, pos) ? pos : startPos; } if (leadingTriviaOption === LeadingTriviaOption.JSDoc) { - const JSDocComments = getJSDocCommentRanges(node, sourceFile.text); + const JSDocComments = ts.getJSDocCommentRanges(node, sourceFile.text); if (JSDocComments?.length) { - return getLineStartPositionForPosition(JSDocComments[0].pos, sourceFile); + return ts.getLineStartPositionForPosition(JSDocComments[0].pos, sourceFile); } } const fullStart = node.getFullStart(); @@ -185,8 +187,8 @@ namespace ts.textChanges { if (fullStart === start) { return start; } - const fullStartLine = getLineStartPositionForPosition(fullStart, sourceFile); - const startLine = getLineStartPositionForPosition(start, sourceFile); + const fullStartLine = ts.getLineStartPositionForPosition(fullStart, sourceFile); + const startLine = ts.getLineStartPositionForPosition(start, sourceFile); if (startLine === fullStartLine) { // full start and start of the node are on the same line // a, b; @@ -202,44 +204,44 @@ namespace ts.textChanges { if (hasTrailingComment) { // Check first for leading comments as if the node is the first import, we want to exclude the trivia; // otherwise we get the trailing comments. - const comment = getLeadingCommentRanges(sourceFile.text, fullStart)?.[0] || getTrailingCommentRanges(sourceFile.text, fullStart)?.[0]; + const comment = ts.getLeadingCommentRanges(sourceFile.text, fullStart)?.[0] || ts.getTrailingCommentRanges(sourceFile.text, fullStart)?.[0]; if (comment) { - return skipTrivia(sourceFile.text, comment.end, /*stopAfterLineBreak*/ true, /*stopAtComments*/ true); + return ts.skipTrivia(sourceFile.text, comment.end, /*stopAfterLineBreak*/ true, /*stopAtComments*/ true); } } // get start position of the line following the line that contains fullstart position // (but only if the fullstart isn't the very beginning of the file) const nextLineStart = fullStart > 0 ? 1 : 0; - let adjustedStartPosition = getStartPositionOfLine(getLineOfLocalPosition(sourceFile, fullStartLine) + nextLineStart, sourceFile); + let adjustedStartPosition = ts.getStartPositionOfLine(ts.getLineOfLocalPosition(sourceFile, fullStartLine) + nextLineStart, sourceFile); // skip whitespaces/newlines adjustedStartPosition = skipWhitespacesAndLineBreaks(sourceFile.text, adjustedStartPosition); - return getStartPositionOfLine(getLineOfLocalPosition(sourceFile, adjustedStartPosition), sourceFile); + return ts.getStartPositionOfLine(ts.getLineOfLocalPosition(sourceFile, adjustedStartPosition), sourceFile); } /** Return the end position of a multiline comment of it is on another line; otherwise returns `undefined`; */ - function getEndPositionOfMultilineTrailingComment(sourceFile: SourceFile, node: Node, options: ConfigurableEnd): number | undefined { + function getEndPositionOfMultilineTrailingComment(sourceFile: ts.SourceFile, node: ts.Node, options: ConfigurableEnd): number | undefined { const { end } = node; const { trailingTriviaOption } = options; if (trailingTriviaOption === TrailingTriviaOption.Include) { // If the trailing comment is a multiline comment that extends to the next lines, // return the end of the comment and track it for the next nodes to adjust. - const comments = getTrailingCommentRanges(sourceFile.text, end); + const comments = ts.getTrailingCommentRanges(sourceFile.text, end); if (comments) { - const nodeEndLine = getLineOfLocalPosition(sourceFile, node.end); + const nodeEndLine = ts.getLineOfLocalPosition(sourceFile, node.end); for (const comment of comments) { // Single line can break the loop as trivia will only be this line. // Comments on subsequest lines are also ignored. - if (comment.kind === SyntaxKind.SingleLineCommentTrivia || getLineOfLocalPosition(sourceFile, comment.pos) > nodeEndLine) { + if (comment.kind === ts.SyntaxKind.SingleLineCommentTrivia || ts.getLineOfLocalPosition(sourceFile, comment.pos) > nodeEndLine) { break; } // Get the end line of the comment and compare against the end line of the node. // If the comment end line position and the multiline comment extends to multiple lines, // then is safe to return the end position. - const commentEndLine = getLineOfLocalPosition(sourceFile, comment.end); + const commentEndLine = ts.getLineOfLocalPosition(sourceFile, comment.end); if (commentEndLine > nodeEndLine) { - return skipTrivia(sourceFile.text, comment.end, /*stopAfterLineBreak*/ true, /*stopAtComments*/ true); + return ts.skipTrivia(sourceFile.text, comment.end, /*stopAfterLineBreak*/ true, /*stopAtComments*/ true); } } } @@ -248,14 +250,14 @@ namespace ts.textChanges { return undefined; } - function getAdjustedEndPosition(sourceFile: SourceFile, node: Node, options: ConfigurableEnd): number { + function getAdjustedEndPosition(sourceFile: ts.SourceFile, node: ts.Node, options: ConfigurableEnd): number { const { end } = node; const { trailingTriviaOption } = options; if (trailingTriviaOption === TrailingTriviaOption.Exclude) { return end; } if (trailingTriviaOption === TrailingTriviaOption.ExcludeWhitespace) { - const comments = concatenate(getTrailingCommentRanges(sourceFile.text, end), getLeadingCommentRanges(sourceFile.text, end)); + const comments = ts.concatenate(ts.getTrailingCommentRanges(sourceFile.text, end), ts.getLeadingCommentRanges(sourceFile.text, end)); const realEnd = comments?.[comments.length - 1]?.end; if (realEnd) { return realEnd; @@ -268,9 +270,8 @@ namespace ts.textChanges { return multilineEndPosition; } - const newEnd = skipTrivia(sourceFile.text, end, /*stopAfterLineBreak*/ true); - - return newEnd !== end && (trailingTriviaOption === TrailingTriviaOption.Include || isLineBreak(sourceFile.text.charCodeAt(newEnd - 1))) + const newEnd = ts.skipTrivia(sourceFile.text, end, /*stopAfterLineBreak*/ true); + return newEnd !== end && (trailingTriviaOption === TrailingTriviaOption.Include || ts.isLineBreak(sourceFile.text.charCodeAt(newEnd - 1))) ? newEnd : end; } @@ -278,69 +279,75 @@ namespace ts.textChanges { /** * Checks if 'candidate' argument is a legal separator in the list that contains 'node' as an element */ - function isSeparator(node: Node, candidate: Node | undefined): candidate is Token { - return !!candidate && !!node.parent && (candidate.kind === SyntaxKind.CommaToken || (candidate.kind === SyntaxKind.SemicolonToken && node.parent.kind === SyntaxKind.ObjectLiteralExpression)); + function isSeparator(node: ts.Node, candidate: ts.Node | undefined): candidate is ts.Token { + return !!candidate && !!node.parent && (candidate.kind === ts.SyntaxKind.CommaToken || (candidate.kind === ts.SyntaxKind.SemicolonToken && node.parent.kind === ts.SyntaxKind.ObjectLiteralExpression)); } export interface TextChangesContext { - host: LanguageServiceHost; - formatContext: formatting.FormatContext; - preferences: UserPreferences; + host: ts.LanguageServiceHost; + formatContext: ts.formatting.FormatContext; + preferences: ts.UserPreferences; } - - export type TypeAnnotatable = SignatureDeclaration | VariableDeclaration | ParameterDeclaration | PropertyDeclaration | PropertySignature; - - export type ThisTypeAnnotatable = FunctionDeclaration | FunctionExpression; - - export function isThisTypeAnnotatable(containingFunction: SignatureDeclaration): containingFunction is ThisTypeAnnotatable { - return isFunctionExpression(containingFunction) || isFunctionDeclaration(containingFunction); + export type TypeAnnotatable = ts.SignatureDeclaration | ts.VariableDeclaration | ts.ParameterDeclaration | ts.PropertyDeclaration | ts.PropertySignature; + export type ThisTypeAnnotatable = ts.FunctionDeclaration | ts.FunctionExpression; + export function isThisTypeAnnotatable(containingFunction: ts.SignatureDeclaration): containingFunction is ThisTypeAnnotatable { + return ts.isFunctionExpression(containingFunction) || ts.isFunctionDeclaration(containingFunction); } export class ChangeTracker { private readonly changes: Change[] = []; - private readonly newFiles: { readonly oldFile: SourceFile | undefined, readonly fileName: string, readonly statements: readonly (Statement | SyntaxKind.NewLineTrivia)[] }[] = []; - private readonly classesWithNodesInsertedAtStart = new Map(); // Set implemented as Map - private readonly deletedNodes: { readonly sourceFile: SourceFile, readonly node: Node | NodeArray }[] = []; + private readonly newFiles: { + readonly oldFile: ts.SourceFile | undefined; + readonly fileName: string; + readonly statements: readonly (ts.Statement | ts.SyntaxKind.NewLineTrivia)[]; + }[] = []; + private readonly classesWithNodesInsertedAtStart = new ts.Map(); // Set implemented as Map + private readonly deletedNodes: { + readonly sourceFile: ts.SourceFile; + readonly node: ts.Node | ts.NodeArray; + }[] = []; public static fromContext(context: TextChangesContext): ChangeTracker { - return new ChangeTracker(getNewLineOrDefaultFromHost(context.host, context.formatContext.options), context.formatContext); + return new ChangeTracker(ts.getNewLineOrDefaultFromHost(context.host, context.formatContext.options), context.formatContext); } - public static with(context: TextChangesContext, cb: (tracker: ChangeTracker) => void): FileTextChanges[] { + public static with(context: TextChangesContext, cb: (tracker: ChangeTracker) => void): ts.FileTextChanges[] { const tracker = ChangeTracker.fromContext(context); cb(tracker); return tracker.getChanges(); } /** Public for tests only. Other callers should use `ChangeTracker.with`. */ - constructor(private readonly newLineCharacter: string, private readonly formatContext: formatting.FormatContext) {} - - public pushRaw(sourceFile: SourceFile, change: FileTextChanges) { - Debug.assertEqual(sourceFile.fileName, change.fileName); + constructor(private readonly newLineCharacter: string, private readonly formatContext: ts.formatting.FormatContext) { } + public pushRaw(sourceFile: ts.SourceFile, change: ts.FileTextChanges) { + ts.Debug.assertEqual(sourceFile.fileName, change.fileName); for (const c of change.textChanges) { this.changes.push({ kind: ChangeKind.Text, sourceFile, text: c.newText, - range: createTextRangeFromSpan(c.span), + range: ts.createTextRangeFromSpan(c.span), }); } } - public deleteRange(sourceFile: SourceFile, range: TextRange): void { + public deleteRange(sourceFile: ts.SourceFile, range: ts.TextRange): void { this.changes.push({ kind: ChangeKind.Remove, sourceFile, range }); } - delete(sourceFile: SourceFile, node: Node | NodeArray): void { + delete(sourceFile: ts.SourceFile, node: ts.Node | ts.NodeArray): void { this.deletedNodes.push({ sourceFile, node }); } /** Stop! Consider using `delete` instead, which has logic for deleting nodes from delimited lists. */ - public deleteNode(sourceFile: SourceFile, node: Node, options: ConfigurableStartEnd = { leadingTriviaOption: LeadingTriviaOption.IncludeAll }): void { + public deleteNode(sourceFile: ts.SourceFile, node: ts.Node, options: ConfigurableStartEnd = { leadingTriviaOption: LeadingTriviaOption.IncludeAll }): void { this.deleteRange(sourceFile, getAdjustedRange(sourceFile, node, node, options)); } - public deleteNodes(sourceFile: SourceFile, nodes: readonly Node[], options: ConfigurableStartEnd = { leadingTriviaOption: LeadingTriviaOption.IncludeAll }, hasTrailingComment: boolean): void { + public deleteNodes(sourceFile: ts.SourceFile, nodes: readonly ts.Node[], options: ConfigurableStartEnd = { leadingTriviaOption: LeadingTriviaOption.IncludeAll }, hasTrailingComment: boolean): void { // When deleting multiple nodes we need to track if the end position is including multiline trailing comments. for (const node of nodes) { const pos = getAdjustedStartPosition(sourceFile, node, options, hasTrailingComment); @@ -352,87 +359,87 @@ namespace ts.textChanges { } } - public deleteModifier(sourceFile: SourceFile, modifier: Modifier): void { - this.deleteRange(sourceFile, { pos: modifier.getStart(sourceFile), end: skipTrivia(sourceFile.text, modifier.end, /*stopAfterLineBreak*/ true) }); + public deleteModifier(sourceFile: ts.SourceFile, modifier: ts.Modifier): void { + this.deleteRange(sourceFile, { pos: modifier.getStart(sourceFile), end: ts.skipTrivia(sourceFile.text, modifier.end, /*stopAfterLineBreak*/ true) }); } - public deleteNodeRange(sourceFile: SourceFile, startNode: Node, endNode: Node, options: ConfigurableStartEnd = { leadingTriviaOption: LeadingTriviaOption.IncludeAll }): void { + public deleteNodeRange(sourceFile: ts.SourceFile, startNode: ts.Node, endNode: ts.Node, options: ConfigurableStartEnd = { leadingTriviaOption: LeadingTriviaOption.IncludeAll }): void { const startPosition = getAdjustedStartPosition(sourceFile, startNode, options); const endPosition = getAdjustedEndPosition(sourceFile, endNode, options); this.deleteRange(sourceFile, { pos: startPosition, end: endPosition }); } - public deleteNodeRangeExcludingEnd(sourceFile: SourceFile, startNode: Node, afterEndNode: Node | undefined, options: ConfigurableStartEnd = { leadingTriviaOption: LeadingTriviaOption.IncludeAll }): void { + public deleteNodeRangeExcludingEnd(sourceFile: ts.SourceFile, startNode: ts.Node, afterEndNode: ts.Node | undefined, options: ConfigurableStartEnd = { leadingTriviaOption: LeadingTriviaOption.IncludeAll }): void { const startPosition = getAdjustedStartPosition(sourceFile, startNode, options); const endPosition = afterEndNode === undefined ? sourceFile.text.length : getAdjustedStartPosition(sourceFile, afterEndNode, options); this.deleteRange(sourceFile, { pos: startPosition, end: endPosition }); } - public replaceRange(sourceFile: SourceFile, range: TextRange, newNode: Node, options: InsertNodeOptions = {}): void { + public replaceRange(sourceFile: ts.SourceFile, range: ts.TextRange, newNode: ts.Node, options: InsertNodeOptions = {}): void { this.changes.push({ kind: ChangeKind.ReplaceWithSingleNode, sourceFile, range, options, node: newNode }); } - public replaceNode(sourceFile: SourceFile, oldNode: Node, newNode: Node, options: ChangeNodeOptions = useNonAdjustedPositions): void { + public replaceNode(sourceFile: ts.SourceFile, oldNode: ts.Node, newNode: ts.Node, options: ChangeNodeOptions = useNonAdjustedPositions): void { this.replaceRange(sourceFile, getAdjustedRange(sourceFile, oldNode, oldNode, options), newNode, options); } - public replaceNodeRange(sourceFile: SourceFile, startNode: Node, endNode: Node, newNode: Node, options: ChangeNodeOptions = useNonAdjustedPositions): void { + public replaceNodeRange(sourceFile: ts.SourceFile, startNode: ts.Node, endNode: ts.Node, newNode: ts.Node, options: ChangeNodeOptions = useNonAdjustedPositions): void { this.replaceRange(sourceFile, getAdjustedRange(sourceFile, startNode, endNode, options), newNode, options); } - private replaceRangeWithNodes(sourceFile: SourceFile, range: TextRange, newNodes: readonly Node[], options: ReplaceWithMultipleNodesOptions & ConfigurableStartEnd = {}): void { + private replaceRangeWithNodes(sourceFile: ts.SourceFile, range: ts.TextRange, newNodes: readonly ts.Node[], options: ReplaceWithMultipleNodesOptions & ConfigurableStartEnd = {}): void { this.changes.push({ kind: ChangeKind.ReplaceWithMultipleNodes, sourceFile, range, options, nodes: newNodes }); } - public replaceNodeWithNodes(sourceFile: SourceFile, oldNode: Node, newNodes: readonly Node[], options: ChangeNodeOptions = useNonAdjustedPositions): void { + public replaceNodeWithNodes(sourceFile: ts.SourceFile, oldNode: ts.Node, newNodes: readonly ts.Node[], options: ChangeNodeOptions = useNonAdjustedPositions): void { this.replaceRangeWithNodes(sourceFile, getAdjustedRange(sourceFile, oldNode, oldNode, options), newNodes, options); } - public replaceNodeWithText(sourceFile: SourceFile, oldNode: Node, text: string): void { + public replaceNodeWithText(sourceFile: ts.SourceFile, oldNode: ts.Node, text: string): void { this.replaceRangeWithText(sourceFile, getAdjustedRange(sourceFile, oldNode, oldNode, useNonAdjustedPositions), text); } - public replaceNodeRangeWithNodes(sourceFile: SourceFile, startNode: Node, endNode: Node, newNodes: readonly Node[], options: ReplaceWithMultipleNodesOptions & ConfigurableStartEnd = useNonAdjustedPositions): void { + public replaceNodeRangeWithNodes(sourceFile: ts.SourceFile, startNode: ts.Node, endNode: ts.Node, newNodes: readonly ts.Node[], options: ReplaceWithMultipleNodesOptions & ConfigurableStartEnd = useNonAdjustedPositions): void { this.replaceRangeWithNodes(sourceFile, getAdjustedRange(sourceFile, startNode, endNode, options), newNodes, options); } - public nodeHasTrailingComment(sourceFile: SourceFile, oldNode: Node, configurableEnd: ConfigurableEnd = useNonAdjustedPositions): boolean { + public nodeHasTrailingComment(sourceFile: ts.SourceFile, oldNode: ts.Node, configurableEnd: ConfigurableEnd = useNonAdjustedPositions): boolean { return !!getEndPositionOfMultilineTrailingComment(sourceFile, oldNode, configurableEnd); } - private nextCommaToken(sourceFile: SourceFile, node: Node): Node | undefined { - const next = findNextToken(node, node.parent, sourceFile); - return next && next.kind === SyntaxKind.CommaToken ? next : undefined; + private nextCommaToken(sourceFile: ts.SourceFile, node: ts.Node): ts.Node | undefined { + const next = ts.findNextToken(node, node.parent, sourceFile); + return next && next.kind === ts.SyntaxKind.CommaToken ? next : undefined; } - public replacePropertyAssignment(sourceFile: SourceFile, oldNode: PropertyAssignment, newNode: PropertyAssignment): void { + public replacePropertyAssignment(sourceFile: ts.SourceFile, oldNode: ts.PropertyAssignment, newNode: ts.PropertyAssignment): void { const suffix = this.nextCommaToken(sourceFile, oldNode) ? "" : ("," + this.newLineCharacter); this.replaceNode(sourceFile, oldNode, newNode, { suffix }); } - public insertNodeAt(sourceFile: SourceFile, pos: number, newNode: Node, options: InsertNodeOptions = {}): void { - this.replaceRange(sourceFile, createRange(pos), newNode, options); + public insertNodeAt(sourceFile: ts.SourceFile, pos: number, newNode: ts.Node, options: InsertNodeOptions = {}): void { + this.replaceRange(sourceFile, ts.createRange(pos), newNode, options); } - private insertNodesAt(sourceFile: SourceFile, pos: number, newNodes: readonly Node[], options: ReplaceWithMultipleNodesOptions = {}): void { - this.replaceRangeWithNodes(sourceFile, createRange(pos), newNodes, options); + private insertNodesAt(sourceFile: ts.SourceFile, pos: number, newNodes: readonly ts.Node[], options: ReplaceWithMultipleNodesOptions = {}): void { + this.replaceRangeWithNodes(sourceFile, ts.createRange(pos), newNodes, options); } - public insertNodeAtTopOfFile(sourceFile: SourceFile, newNode: Statement, blankLineBetween: boolean): void { + public insertNodeAtTopOfFile(sourceFile: ts.SourceFile, newNode: ts.Statement, blankLineBetween: boolean): void { this.insertAtTopOfFile(sourceFile, newNode, blankLineBetween); } - public insertNodesAtTopOfFile(sourceFile: SourceFile, newNodes: readonly Statement[], blankLineBetween: boolean): void { + public insertNodesAtTopOfFile(sourceFile: ts.SourceFile, newNodes: readonly ts.Statement[], blankLineBetween: boolean): void { this.insertAtTopOfFile(sourceFile, newNodes, blankLineBetween); } - private insertAtTopOfFile(sourceFile: SourceFile, insert: Statement | readonly Statement[], blankLineBetween: boolean): void { + private insertAtTopOfFile(sourceFile: ts.SourceFile, insert: ts.Statement | readonly ts.Statement[], blankLineBetween: boolean): void { const pos = getInsertionPositionAtSourceFileTop(sourceFile); const options = { prefix: pos === 0 ? undefined : this.newLineCharacter, - suffix: (isLineBreak(sourceFile.text.charCodeAt(pos)) ? "" : this.newLineCharacter) + (blankLineBetween ? this.newLineCharacter : ""), + suffix: (ts.isLineBreak(sourceFile.text.charCodeAt(pos)) ? "" : this.newLineCharacter) + (blankLineBetween ? this.newLineCharacter : ""), }; - if (isArray(insert)) { + if (ts.isArray(insert)) { this.insertNodesAt(sourceFile, pos, insert, options); } else { @@ -440,8 +447,8 @@ namespace ts.textChanges { } } - public insertFirstParameter(sourceFile: SourceFile, parameters: NodeArray, newParam: ParameterDeclaration): void { - const p0 = firstOrUndefined(parameters); + public insertFirstParameter(sourceFile: ts.SourceFile, parameters: ts.NodeArray, newParam: ts.ParameterDeclaration): void { + const p0 = ts.firstOrUndefined(parameters); if (p0) { this.insertNodeBefore(sourceFile, p0, newParam); } @@ -450,134 +457,133 @@ namespace ts.textChanges { } } - public insertNodeBefore(sourceFile: SourceFile, before: Node, newNode: Node, blankLineBetween = false, options: ConfigurableStartEnd = {}): void { + public insertNodeBefore(sourceFile: ts.SourceFile, before: ts.Node, newNode: ts.Node, blankLineBetween = false, options: ConfigurableStartEnd = {}): void { this.insertNodeAt(sourceFile, getAdjustedStartPosition(sourceFile, before, options), newNode, this.getOptionsForInsertNodeBefore(before, newNode, blankLineBetween)); } - public insertModifierAt(sourceFile: SourceFile, pos: number, modifier: SyntaxKind, options: InsertNodeOptions = {}): void { - this.insertNodeAt(sourceFile, pos, factory.createToken(modifier), options); + public insertModifierAt(sourceFile: ts.SourceFile, pos: number, modifier: ts.SyntaxKind, options: InsertNodeOptions = {}): void { + this.insertNodeAt(sourceFile, pos, ts.factory.createToken(modifier), options); } - public insertModifierBefore(sourceFile: SourceFile, modifier: SyntaxKind, before: Node): void { + public insertModifierBefore(sourceFile: ts.SourceFile, modifier: ts.SyntaxKind, before: ts.Node): void { return this.insertModifierAt(sourceFile, before.getStart(sourceFile), modifier, { suffix: " " }); } - public insertCommentBeforeLine(sourceFile: SourceFile, lineNumber: number, position: number, commentText: string): void { - const lineStartPosition = getStartPositionOfLine(lineNumber, sourceFile); - const startPosition = getFirstNonSpaceCharacterPosition(sourceFile.text, lineStartPosition); + public insertCommentBeforeLine(sourceFile: ts.SourceFile, lineNumber: number, position: number, commentText: string): void { + const lineStartPosition = ts.getStartPositionOfLine(lineNumber, sourceFile); + const startPosition = ts.getFirstNonSpaceCharacterPosition(sourceFile.text, lineStartPosition); // First try to see if we can put the comment on the previous line. // We need to make sure that we are not in the middle of a string literal or a comment. // If so, we do not want to separate the node from its comment if we can. // Otherwise, add an extra new line immediately before the error span. const insertAtLineStart = isValidLocationToAddComment(sourceFile, startPosition); - const token = getTouchingToken(sourceFile, insertAtLineStart ? startPosition : position); + const token = ts.getTouchingToken(sourceFile, insertAtLineStart ? startPosition : position); const indent = sourceFile.text.slice(lineStartPosition, startPosition); const text = `${insertAtLineStart ? "" : this.newLineCharacter}//${commentText}${this.newLineCharacter}${indent}`; this.insertText(sourceFile, token.getStart(sourceFile), text); } - public insertJsdocCommentBefore(sourceFile: SourceFile, node: HasJSDoc, tag: JSDoc): void { + public insertJsdocCommentBefore(sourceFile: ts.SourceFile, node: ts.HasJSDoc, tag: ts.JSDoc): void { const fnStart = node.getStart(sourceFile); if (node.jsDoc) { for (const jsdoc of node.jsDoc) { this.deleteRange(sourceFile, { - pos: getLineStartPositionForPosition(jsdoc.getStart(sourceFile), sourceFile), + pos: ts.getLineStartPositionForPosition(jsdoc.getStart(sourceFile), sourceFile), end: getAdjustedEndPosition(sourceFile, jsdoc, /*options*/ {}) }); } } - const startPosition = getPrecedingNonSpaceCharacterPosition(sourceFile.text, fnStart - 1); + const startPosition = ts.getPrecedingNonSpaceCharacterPosition(sourceFile.text, fnStart - 1); const indent = sourceFile.text.slice(startPosition, fnStart); this.insertNodeAt(sourceFile, fnStart, tag, { suffix: this.newLineCharacter + indent }); } - private createJSDocText(sourceFile: SourceFile, node: HasJSDoc) { - const comments = flatMap(node.jsDoc, jsDoc => - isString(jsDoc.comment) ? factory.createJSDocText(jsDoc.comment) : jsDoc.comment) as JSDocComment[]; - const jsDoc = singleOrUndefined(node.jsDoc); - return jsDoc && positionsAreOnSameLine(jsDoc.pos, jsDoc.end, sourceFile) && length(comments) === 0 ? undefined : - factory.createNodeArray(intersperse(comments, factory.createJSDocText("\n"))); + private createJSDocText(sourceFile: ts.SourceFile, node: ts.HasJSDoc) { + const comments = ts.flatMap(node.jsDoc, jsDoc => ts.isString(jsDoc.comment) ? ts.factory.createJSDocText(jsDoc.comment) : jsDoc.comment) as ts.JSDocComment[]; + const jsDoc = ts.singleOrUndefined(node.jsDoc); + return jsDoc && ts.positionsAreOnSameLine(jsDoc.pos, jsDoc.end, sourceFile) && ts.length(comments) === 0 ? undefined : + ts.factory.createNodeArray(ts.intersperse(comments, ts.factory.createJSDocText("\n"))); } - - public replaceJSDocComment(sourceFile: SourceFile, node: HasJSDoc, tags: readonly JSDocTag[]) { - this.insertJsdocCommentBefore(sourceFile, updateJSDocHost(node), factory.createJSDocComment(this.createJSDocText(sourceFile, node), factory.createNodeArray(tags))); + public replaceJSDocComment(sourceFile: ts.SourceFile, node: ts.HasJSDoc, tags: readonly ts.JSDocTag[]) { + this.insertJsdocCommentBefore(sourceFile, updateJSDocHost(node), ts.factory.createJSDocComment(this.createJSDocText(sourceFile, node), ts.factory.createNodeArray(tags))); } - - public addJSDocTags(sourceFile: SourceFile, parent: HasJSDoc, newTags: readonly JSDocTag[]): void { - const oldTags = flatMapToMutable(parent.jsDoc, j => j.tags); + public addJSDocTags(sourceFile: ts.SourceFile, parent: ts.HasJSDoc, newTags: readonly ts.JSDocTag[]): void { + const oldTags = ts.flatMapToMutable(parent.jsDoc, j => j.tags); const unmergedNewTags = newTags.filter(newTag => !oldTags.some((tag, i) => { const merged = tryMergeJsdocTags(tag, newTag); - if (merged) oldTags[i] = merged; + if (merged) + oldTags[i] = merged; return !!merged; })); this.replaceJSDocComment(sourceFile, parent, [...oldTags, ...unmergedNewTags]); } - public filterJSDocTags(sourceFile: SourceFile, parent: HasJSDoc, predicate: (tag: JSDocTag) => boolean): void { - this.replaceJSDocComment(sourceFile, parent, filter(flatMapToMutable(parent.jsDoc, j => j.tags), predicate)); + public filterJSDocTags(sourceFile: ts.SourceFile, parent: ts.HasJSDoc, predicate: (tag: ts.JSDocTag) => boolean): void { + this.replaceJSDocComment(sourceFile, parent, ts.filter(ts.flatMapToMutable(parent.jsDoc, j => j.tags), predicate)); } - public replaceRangeWithText(sourceFile: SourceFile, range: TextRange, text: string): void { + public replaceRangeWithText(sourceFile: ts.SourceFile, range: ts.TextRange, text: string): void { this.changes.push({ kind: ChangeKind.Text, sourceFile, range, text }); } - public insertText(sourceFile: SourceFile, pos: number, text: string): void { - this.replaceRangeWithText(sourceFile, createRange(pos), text); + public insertText(sourceFile: ts.SourceFile, pos: number, text: string): void { + this.replaceRangeWithText(sourceFile, ts.createRange(pos), text); } /** Prefer this over replacing a node with another that has a type annotation, as it avoids reformatting the other parts of the node. */ - public tryInsertTypeAnnotation(sourceFile: SourceFile, node: TypeAnnotatable, type: TypeNode): boolean { - let endNode: Node | undefined; - if (isFunctionLike(node)) { - endNode = findChildOfKind(node, SyntaxKind.CloseParenToken, sourceFile); + public tryInsertTypeAnnotation(sourceFile: ts.SourceFile, node: TypeAnnotatable, type: ts.TypeNode): boolean { + let endNode: ts.Node | undefined; + if (ts.isFunctionLike(node)) { + endNode = ts.findChildOfKind(node, ts.SyntaxKind.CloseParenToken, sourceFile); if (!endNode) { - if (!isArrowFunction(node)) return false; // Function missing parentheses, give up + if (!ts.isArrowFunction(node)) + return false; // Function missing parentheses, give up // If no `)`, is an arrow function `x => x`, so use the end of the first parameter - endNode = first(node.parameters); + endNode = ts.first(node.parameters); } } else { - endNode = (node.kind === SyntaxKind.VariableDeclaration ? node.exclamationToken : node.questionToken) ?? node.name; + endNode = (node.kind === ts.SyntaxKind.VariableDeclaration ? node.exclamationToken : node.questionToken) ?? node.name; } this.insertNodeAt(sourceFile, endNode.end, type, { prefix: ": " }); return true; } - public tryInsertThisTypeAnnotation(sourceFile: SourceFile, node: ThisTypeAnnotatable, type: TypeNode): void { - const start = findChildOfKind(node, SyntaxKind.OpenParenToken, sourceFile)!.getStart(sourceFile) + 1; + public tryInsertThisTypeAnnotation(sourceFile: ts.SourceFile, node: ThisTypeAnnotatable, type: ts.TypeNode): void { + const start = ts.findChildOfKind(node, ts.SyntaxKind.OpenParenToken, sourceFile)!.getStart(sourceFile) + 1; const suffix = node.parameters.length ? ", " : ""; this.insertNodeAt(sourceFile, start, type, { prefix: "this: ", suffix }); } - public insertTypeParameters(sourceFile: SourceFile, node: SignatureDeclaration, typeParameters: readonly TypeParameterDeclaration[]): void { + public insertTypeParameters(sourceFile: ts.SourceFile, node: ts.SignatureDeclaration, typeParameters: readonly ts.TypeParameterDeclaration[]): void { // If no `(`, is an arrow function `x => x`, so use the pos of the first parameter - const start = (findChildOfKind(node, SyntaxKind.OpenParenToken, sourceFile) || first(node.parameters)).getStart(sourceFile); + const start = (ts.findChildOfKind(node, ts.SyntaxKind.OpenParenToken, sourceFile) || ts.first(node.parameters)).getStart(sourceFile); this.insertNodesAt(sourceFile, start, typeParameters, { prefix: "<", suffix: ">", joiner: ", " }); } - private getOptionsForInsertNodeBefore(before: Node, inserted: Node, blankLineBetween: boolean): InsertNodeOptions { - if (isStatement(before) || isClassElement(before)) { + private getOptionsForInsertNodeBefore(before: ts.Node, inserted: ts.Node, blankLineBetween: boolean): InsertNodeOptions { + if (ts.isStatement(before) || ts.isClassElement(before)) { return { suffix: blankLineBetween ? this.newLineCharacter + this.newLineCharacter : this.newLineCharacter }; } - else if (isVariableDeclaration(before)) { // insert `x = 1, ` into `const x = 1, y = 2; + else if (ts.isVariableDeclaration(before)) { // insert `x = 1, ` into `const x = 1, y = 2; return { suffix: ", " }; } - else if (isParameter(before)) { - return isParameter(inserted) ? { suffix: ", " } : {}; + else if (ts.isParameter(before)) { + return ts.isParameter(inserted) ? { suffix: ", " } : {}; } - else if (isStringLiteral(before) && isImportDeclaration(before.parent) || isNamedImports(before)) { + else if (ts.isStringLiteral(before) && ts.isImportDeclaration(before.parent) || ts.isNamedImports(before)) { return { suffix: ", " }; } - else if (isImportSpecifier(before)) { + else if (ts.isImportSpecifier(before)) { return { suffix: "," + (blankLineBetween ? this.newLineCharacter : " ") }; } - return Debug.failBadSyntaxKind(before); // We haven't handled this kind of node yet -- add it + return ts.Debug.failBadSyntaxKind(before); // We haven't handled this kind of node yet -- add it } - public insertNodeAtConstructorStart(sourceFile: SourceFile, ctr: ConstructorDeclaration, newStatement: Statement): void { - const firstStatement = firstOrUndefined(ctr.body!.statements); + public insertNodeAtConstructorStart(sourceFile: ts.SourceFile, ctr: ts.ConstructorDeclaration, newStatement: ts.Statement): void { + const firstStatement = ts.firstOrUndefined(ctr.body!.statements); if (!firstStatement || !ctr.body!.multiLine) { this.replaceConstructorBody(sourceFile, ctr, [newStatement, ...ctr.body!.statements]); } @@ -586,8 +592,8 @@ namespace ts.textChanges { } } - public insertNodeAtConstructorStartAfterSuperCall(sourceFile: SourceFile, ctr: ConstructorDeclaration, newStatement: Statement): void { - const superCallStatement = find(ctr.body!.statements, stmt => isExpressionStatement(stmt) && isSuperCall(stmt.expression)); + public insertNodeAtConstructorStartAfterSuperCall(sourceFile: ts.SourceFile, ctr: ts.ConstructorDeclaration, newStatement: ts.Statement): void { + const superCallStatement = ts.find(ctr.body!.statements, stmt => ts.isExpressionStatement(stmt) && ts.isSuperCall(stmt.expression)); if (!superCallStatement || !ctr.body!.multiLine) { this.replaceConstructorBody(sourceFile, ctr, [...ctr.body!.statements, newStatement]); } @@ -596,8 +602,8 @@ namespace ts.textChanges { } } - public insertNodeAtConstructorEnd(sourceFile: SourceFile, ctr: ConstructorDeclaration, newStatement: Statement): void { - const lastStatement = lastOrUndefined(ctr.body!.statements); + public insertNodeAtConstructorEnd(sourceFile: ts.SourceFile, ctr: ts.ConstructorDeclaration, newStatement: ts.Statement): void { + const lastStatement = ts.lastOrUndefined(ctr.body!.statements); if (!lastStatement || !ctr.body!.multiLine) { this.replaceConstructorBody(sourceFile, ctr, [...ctr.body!.statements, newStatement]); } @@ -606,27 +612,27 @@ namespace ts.textChanges { } } - private replaceConstructorBody(sourceFile: SourceFile, ctr: ConstructorDeclaration, statements: readonly Statement[]): void { - this.replaceNode(sourceFile, ctr.body!, factory.createBlock(statements, /*multiLine*/ true)); + private replaceConstructorBody(sourceFile: ts.SourceFile, ctr: ts.ConstructorDeclaration, statements: readonly ts.Statement[]): void { + this.replaceNode(sourceFile, ctr.body!, ts.factory.createBlock(statements, /*multiLine*/ true)); } - public insertNodeAtEndOfScope(sourceFile: SourceFile, scope: Node, newNode: Node): void { + public insertNodeAtEndOfScope(sourceFile: ts.SourceFile, scope: ts.Node, newNode: ts.Node): void { const pos = getAdjustedStartPosition(sourceFile, scope.getLastToken()!, {}); this.insertNodeAt(sourceFile, pos, newNode, { - prefix: isLineBreak(sourceFile.text.charCodeAt(scope.getLastToken()!.pos)) ? this.newLineCharacter : this.newLineCharacter + this.newLineCharacter, + prefix: ts.isLineBreak(sourceFile.text.charCodeAt(scope.getLastToken()!.pos)) ? this.newLineCharacter : this.newLineCharacter + this.newLineCharacter, suffix: this.newLineCharacter }); } - public insertMemberAtStart(sourceFile: SourceFile, node: ClassLikeDeclaration | InterfaceDeclaration | TypeLiteralNode, newElement: ClassElement | PropertySignature | MethodSignature): void { + public insertMemberAtStart(sourceFile: ts.SourceFile, node: ts.ClassLikeDeclaration | ts.InterfaceDeclaration | ts.TypeLiteralNode, newElement: ts.ClassElement | ts.PropertySignature | ts.MethodSignature): void { this.insertNodeAtStartWorker(sourceFile, node, newElement); } - public insertNodeAtObjectStart(sourceFile: SourceFile, obj: ObjectLiteralExpression, newElement: ObjectLiteralElementLike): void { + public insertNodeAtObjectStart(sourceFile: ts.SourceFile, obj: ts.ObjectLiteralExpression, newElement: ts.ObjectLiteralElementLike): void { this.insertNodeAtStartWorker(sourceFile, obj, newElement); } - private insertNodeAtStartWorker(sourceFile: SourceFile, node: ClassLikeDeclaration | InterfaceDeclaration | ObjectLiteralExpression | TypeLiteralNode, newElement: ClassElement | ObjectLiteralElementLike | PropertySignature | MethodSignature): void { + private insertNodeAtStartWorker(sourceFile: ts.SourceFile, node: ts.ClassLikeDeclaration | ts.InterfaceDeclaration | ts.ObjectLiteralExpression | ts.TypeLiteralNode, newElement: ts.ClassElement | ts.ObjectLiteralElementLike | ts.PropertySignature | ts.MethodSignature): void { const indentation = this.guessIndentationFromExistingMembers(sourceFile, node) ?? this.computeIndentationForNewMember(sourceFile, node); this.insertNodeAt(sourceFile, getMembersOrProperties(node).pos, newElement, this.getInsertNodeAtStartInsertOptions(sourceFile, node, indentation)); } @@ -635,16 +641,16 @@ namespace ts.textChanges { * Tries to guess the indentation from the existing members of a class/interface/object. All members must be on * new lines and must share the same indentation. */ - private guessIndentationFromExistingMembers(sourceFile: SourceFile, node: ClassLikeDeclaration | InterfaceDeclaration | ObjectLiteralExpression | TypeLiteralNode) { + private guessIndentationFromExistingMembers(sourceFile: ts.SourceFile, node: ts.ClassLikeDeclaration | ts.InterfaceDeclaration | ts.ObjectLiteralExpression | ts.TypeLiteralNode) { let indentation: number | undefined; - let lastRange: TextRange = node; + let lastRange: ts.TextRange = node; for (const member of getMembersOrProperties(node)) { - if (rangeStartPositionsAreOnSameLine(lastRange, member, sourceFile)) { + if (ts.rangeStartPositionsAreOnSameLine(lastRange, member, sourceFile)) { // each indented member must be on a new line return undefined; } const memberStart = member.getStart(sourceFile); - const memberIndentation = formatting.SmartIndenter.findFirstNonWhitespaceColumn(getLineStartPositionForPosition(memberStart, sourceFile), memberStart, sourceFile, this.formatContext.options); + const memberIndentation = ts.formatting.SmartIndenter.findFirstNonWhitespaceColumn(ts.getLineStartPositionForPosition(memberStart, sourceFile), memberStart, sourceFile, this.formatContext.options); if (indentation === undefined) { indentation = memberIndentation; } @@ -657,13 +663,13 @@ namespace ts.textChanges { return indentation; } - private computeIndentationForNewMember(sourceFile: SourceFile, node: ClassLikeDeclaration | InterfaceDeclaration | ObjectLiteralExpression | TypeLiteralNode) { + private computeIndentationForNewMember(sourceFile: ts.SourceFile, node: ts.ClassLikeDeclaration | ts.InterfaceDeclaration | ts.ObjectLiteralExpression | ts.TypeLiteralNode) { const nodeStart = node.getStart(sourceFile); - return formatting.SmartIndenter.findFirstNonWhitespaceColumn(getLineStartPositionForPosition(nodeStart, sourceFile), nodeStart, sourceFile, this.formatContext.options) + return ts.formatting.SmartIndenter.findFirstNonWhitespaceColumn(ts.getLineStartPositionForPosition(nodeStart, sourceFile), nodeStart, sourceFile, this.formatContext.options) + (this.formatContext.options.indentSize ?? 4); } - private getInsertNodeAtStartInsertOptions(sourceFile: SourceFile, node: ClassLikeDeclaration | InterfaceDeclaration | ObjectLiteralExpression | TypeLiteralNode, indentation: number): InsertNodeOptions { + private getInsertNodeAtStartInsertOptions(sourceFile: ts.SourceFile, node: ts.ClassLikeDeclaration | ts.InterfaceDeclaration | ts.ObjectLiteralExpression | ts.TypeLiteralNode, indentation: number): InsertNodeOptions { // Rules: // - Always insert leading newline. // - For object literals: @@ -676,9 +682,9 @@ namespace ts.textChanges { const members = getMembersOrProperties(node); const isEmpty = members.length === 0; - const isFirstInsertion = addToSeen(this.classesWithNodesInsertedAtStart, getNodeId(node), { node, sourceFile }); - const insertTrailingComma = isObjectLiteralExpression(node) && (!isJsonSourceFile(sourceFile) || !isEmpty); - const insertLeadingComma = isObjectLiteralExpression(node) && isJsonSourceFile(sourceFile) && isEmpty && !isFirstInsertion; + const isFirstInsertion = ts.addToSeen(this.classesWithNodesInsertedAtStart, ts.getNodeId(node), { node, sourceFile }); + const insertTrailingComma = ts.isObjectLiteralExpression(node) && (!ts.isJsonSourceFile(sourceFile) || !isEmpty); + const insertLeadingComma = ts.isObjectLiteralExpression(node) && ts.isJsonSourceFile(sourceFile) && isEmpty && !isFirstInsertion; return { indentation, prefix: (insertLeadingComma ? "," : "") + this.newLineCharacter, @@ -686,115 +692,111 @@ namespace ts.textChanges { }; } - public insertNodeAfterComma(sourceFile: SourceFile, after: Node, newNode: Node): void { + public insertNodeAfterComma(sourceFile: ts.SourceFile, after: ts.Node, newNode: ts.Node): void { const endPosition = this.insertNodeAfterWorker(sourceFile, this.nextCommaToken(sourceFile, after) || after, newNode); this.insertNodeAt(sourceFile, endPosition, newNode, this.getInsertNodeAfterOptions(sourceFile, after)); } - public insertNodeAfter(sourceFile: SourceFile, after: Node, newNode: Node): void { + public insertNodeAfter(sourceFile: ts.SourceFile, after: ts.Node, newNode: ts.Node): void { const endPosition = this.insertNodeAfterWorker(sourceFile, after, newNode); this.insertNodeAt(sourceFile, endPosition, newNode, this.getInsertNodeAfterOptions(sourceFile, after)); } - public insertNodeAtEndOfList(sourceFile: SourceFile, list: NodeArray, newNode: Node): void { + public insertNodeAtEndOfList(sourceFile: ts.SourceFile, list: ts.NodeArray, newNode: ts.Node): void { this.insertNodeAt(sourceFile, list.end, newNode, { prefix: ", " }); } - public insertNodesAfter(sourceFile: SourceFile, after: Node, newNodes: readonly Node[]): void { - const endPosition = this.insertNodeAfterWorker(sourceFile, after, first(newNodes)); + public insertNodesAfter(sourceFile: ts.SourceFile, after: ts.Node, newNodes: readonly ts.Node[]): void { + const endPosition = this.insertNodeAfterWorker(sourceFile, after, ts.first(newNodes)); this.insertNodesAt(sourceFile, endPosition, newNodes, this.getInsertNodeAfterOptions(sourceFile, after)); } - private insertNodeAfterWorker(sourceFile: SourceFile, after: Node, newNode: Node): number { + private insertNodeAfterWorker(sourceFile: ts.SourceFile, after: ts.Node, newNode: ts.Node): number { if (needSemicolonBetween(after, newNode)) { // check if previous statement ends with semicolon // if not - insert semicolon to preserve the code from changing the meaning due to ASI - if (sourceFile.text.charCodeAt(after.end - 1) !== CharacterCodes.semicolon) { - this.replaceRange(sourceFile, createRange(after.end), factory.createToken(SyntaxKind.SemicolonToken)); + if (sourceFile.text.charCodeAt(after.end - 1) !== ts.CharacterCodes.semicolon) { + this.replaceRange(sourceFile, ts.createRange(after.end), ts.factory.createToken(ts.SyntaxKind.SemicolonToken)); } } const endPosition = getAdjustedEndPosition(sourceFile, after, {}); return endPosition; } - private getInsertNodeAfterOptions(sourceFile: SourceFile, after: Node): InsertNodeOptions { + private getInsertNodeAfterOptions(sourceFile: ts.SourceFile, after: ts.Node): InsertNodeOptions { const options = this.getInsertNodeAfterOptionsWorker(after); return { ...options, - prefix: after.end === sourceFile.end && isStatement(after) ? (options.prefix ? `\n${options.prefix}` : "\n") : options.prefix, + prefix: after.end === sourceFile.end && ts.isStatement(after) ? (options.prefix ? `\n${options.prefix}` : "\n") : options.prefix, }; } - private getInsertNodeAfterOptionsWorker(node: Node): InsertNodeOptions { + private getInsertNodeAfterOptionsWorker(node: ts.Node): InsertNodeOptions { switch (node.kind) { - case SyntaxKind.ClassDeclaration: - case SyntaxKind.ModuleDeclaration: + case ts.SyntaxKind.ClassDeclaration: + case ts.SyntaxKind.ModuleDeclaration: return { prefix: this.newLineCharacter, suffix: this.newLineCharacter }; - case SyntaxKind.VariableDeclaration: - case SyntaxKind.StringLiteral: - case SyntaxKind.Identifier: + case ts.SyntaxKind.VariableDeclaration: + case ts.SyntaxKind.StringLiteral: + case ts.SyntaxKind.Identifier: return { prefix: ", " }; - case SyntaxKind.PropertyAssignment: + case ts.SyntaxKind.PropertyAssignment: return { suffix: "," + this.newLineCharacter }; - case SyntaxKind.ExportKeyword: + case ts.SyntaxKind.ExportKeyword: return { prefix: " " }; - case SyntaxKind.Parameter: + case ts.SyntaxKind.Parameter: return {}; default: - Debug.assert(isStatement(node) || isClassOrTypeElement(node)); // Else we haven't handled this kind of node yet -- add it + ts.Debug.assert(ts.isStatement(node) || ts.isClassOrTypeElement(node)); // Else we haven't handled this kind of node yet -- add it return { suffix: this.newLineCharacter }; } } - public insertName(sourceFile: SourceFile, node: FunctionExpression | ClassExpression | ArrowFunction, name: string): void { - Debug.assert(!node.name); - if (node.kind === SyntaxKind.ArrowFunction) { - const arrow = findChildOfKind(node, SyntaxKind.EqualsGreaterThanToken, sourceFile)!; - const lparen = findChildOfKind(node, SyntaxKind.OpenParenToken, sourceFile); + public insertName(sourceFile: ts.SourceFile, node: ts.FunctionExpression | ts.ClassExpression | ts.ArrowFunction, name: string): void { + ts.Debug.assert(!node.name); + if (node.kind === ts.SyntaxKind.ArrowFunction) { + const arrow = ts.findChildOfKind(node, ts.SyntaxKind.EqualsGreaterThanToken, sourceFile)!; + const lparen = ts.findChildOfKind(node, ts.SyntaxKind.OpenParenToken, sourceFile); if (lparen) { // `() => {}` --> `function f() {}` - this.insertNodesAt(sourceFile, lparen.getStart(sourceFile), [factory.createToken(SyntaxKind.FunctionKeyword), factory.createIdentifier(name)], { joiner: " " }); + this.insertNodesAt(sourceFile, lparen.getStart(sourceFile), [ts.factory.createToken(ts.SyntaxKind.FunctionKeyword), ts.factory.createIdentifier(name)], { joiner: " " }); deleteNode(this, sourceFile, arrow); } else { // `x => {}` -> `function f(x) {}` - this.insertText(sourceFile, first(node.parameters).getStart(sourceFile), `function ${name}(`); + this.insertText(sourceFile, ts.first(node.parameters).getStart(sourceFile), `function ${name}(`); // Replacing full range of arrow to get rid of the leading space -- replace ` =>` with `)` - this.replaceRange(sourceFile, arrow, factory.createToken(SyntaxKind.CloseParenToken)); + this.replaceRange(sourceFile, arrow, ts.factory.createToken(ts.SyntaxKind.CloseParenToken)); } - if (node.body.kind !== SyntaxKind.Block) { + if (node.body.kind !== ts.SyntaxKind.Block) { // `() => 0` => `function f() { return 0; }` - this.insertNodesAt(sourceFile, node.body.getStart(sourceFile), [factory.createToken(SyntaxKind.OpenBraceToken), factory.createToken(SyntaxKind.ReturnKeyword)], { joiner: " ", suffix: " " }); - this.insertNodesAt(sourceFile, node.body.end, [factory.createToken(SyntaxKind.SemicolonToken), factory.createToken(SyntaxKind.CloseBraceToken)], { joiner: " " }); + this.insertNodesAt(sourceFile, node.body.getStart(sourceFile), [ts.factory.createToken(ts.SyntaxKind.OpenBraceToken), ts.factory.createToken(ts.SyntaxKind.ReturnKeyword)], { joiner: " ", suffix: " " }); + this.insertNodesAt(sourceFile, node.body.end, [ts.factory.createToken(ts.SyntaxKind.SemicolonToken), ts.factory.createToken(ts.SyntaxKind.CloseBraceToken)], { joiner: " " }); } } else { - const pos = findChildOfKind(node, node.kind === SyntaxKind.FunctionExpression ? SyntaxKind.FunctionKeyword : SyntaxKind.ClassKeyword, sourceFile)!.end; - this.insertNodeAt(sourceFile, pos, factory.createIdentifier(name), { prefix: " " }); + const pos = ts.findChildOfKind(node, node.kind === ts.SyntaxKind.FunctionExpression ? ts.SyntaxKind.FunctionKeyword : ts.SyntaxKind.ClassKeyword, sourceFile)!.end; + this.insertNodeAt(sourceFile, pos, ts.factory.createIdentifier(name), { prefix: " " }); } } - public insertExportModifier(sourceFile: SourceFile, node: DeclarationStatement | VariableStatement): void { + public insertExportModifier(sourceFile: ts.SourceFile, node: ts.DeclarationStatement | ts.VariableStatement): void { this.insertText(sourceFile, node.getStart(sourceFile), "export "); } - public insertImportSpecifierAtIndex(sourceFile: SourceFile, importSpecifier: ImportSpecifier, namedImports: NamedImports, index: number) { + public insertImportSpecifierAtIndex(sourceFile: ts.SourceFile, importSpecifier: ts.ImportSpecifier, namedImports: ts.NamedImports, index: number) { const prevSpecifier = namedImports.elements[index - 1]; if (prevSpecifier) { this.insertNodeInListAfter(sourceFile, prevSpecifier, importSpecifier); } else { - this.insertNodeBefore( - sourceFile, - namedImports.elements[0], - importSpecifier, - !positionsAreOnSameLine(namedImports.elements[0].getStart(), namedImports.parent.parent.getStart(), sourceFile)); + this.insertNodeBefore(sourceFile, namedImports.elements[0], importSpecifier, !ts.positionsAreOnSameLine(namedImports.elements[0].getStart(), namedImports.parent.parent.getStart(), sourceFile)); } } @@ -803,12 +805,12 @@ namespace ts.textChanges { * i.e. arguments in arguments lists, parameters in parameter lists etc. * Note that separators are part of the node in statements and class elements. */ - public insertNodeInListAfter(sourceFile: SourceFile, after: Node, newNode: Node, containingList = formatting.SmartIndenter.getContainingList(after, sourceFile)): void { + public insertNodeInListAfter(sourceFile: ts.SourceFile, after: ts.Node, newNode: ts.Node, containingList = ts.formatting.SmartIndenter.getContainingList(after, sourceFile)): void { if (!containingList) { - Debug.fail("node is not a list element"); + ts.Debug.fail("node is not a list element"); return; } - const index = indexOfNode(containingList, after); + const index = ts.indexOfNode(containingList, after); if (index < 0) { return; } @@ -816,7 +818,7 @@ namespace ts.textChanges { if (index !== containingList.length - 1) { // any element except the last one // use next sibling as an anchor - const nextToken = getTokenAtPosition(sourceFile, after.end); + const nextToken = ts.getTokenAtPosition(sourceFile, after.end); if (nextToken && isSeparator(after, nextToken)) { // for list // a, b, c @@ -838,15 +840,14 @@ namespace ts.textChanges { const startPos = skipWhitespacesAndLineBreaks(sourceFile.text, nextNode.getFullStart()); // write separator and leading trivia of the next element as suffix - const suffix = `${tokenToString(nextToken.kind)}${sourceFile.text.substring(nextToken.end, startPos)}`; + const suffix = `${ts.tokenToString(nextToken.kind)}${sourceFile.text.substring(nextToken.end, startPos)}`; this.insertNodesAt(sourceFile, startPos, [newNode], { suffix }); } } else { const afterStart = after.getStart(sourceFile); - const afterStartLinePosition = getLineStartPositionForPosition(afterStart, sourceFile); - - let separator: SyntaxKind.CommaToken | SyntaxKind.SemicolonToken | undefined; + const afterStartLinePosition = ts.getLineStartPositionForPosition(afterStart, sourceFile); + let separator: ts.SyntaxKind.CommaToken | ts.SyntaxKind.SemicolonToken | undefined; let multilineList = false; // insert element after the last element in the list that has more than one item @@ -857,14 +858,14 @@ namespace ts.textChanges { // if list has only one element then we'll format is as multiline if node has comment in trailing trivia, or as singleline otherwise // i.e. var x = 1 // this is x // | new element will be inserted at this position - separator = SyntaxKind.CommaToken; + separator = ts.SyntaxKind.CommaToken; } else { // element has more than one element, pick separator from the list - const tokenBeforeInsertPosition = findPrecedingToken(after.pos, sourceFile); - separator = isSeparator(after, tokenBeforeInsertPosition) ? tokenBeforeInsertPosition.kind : SyntaxKind.CommaToken; + const tokenBeforeInsertPosition = ts.findPrecedingToken(after.pos, sourceFile); + separator = isSeparator(after, tokenBeforeInsertPosition) ? tokenBeforeInsertPosition.kind : ts.SyntaxKind.CommaToken; // determine if list is multiline by checking lines of after element and element that precedes it. - const afterMinusOneStartLinePosition = getLineStartPositionForPosition(containingList[index - 1].getStart(sourceFile), sourceFile); + const afterMinusOneStartLinePosition = ts.getLineStartPositionForPosition(containingList[index - 1].getStart(sourceFile), sourceFile); multilineList = afterMinusOneStartLinePosition !== afterStartLinePosition; } if (hasCommentsBeforeLineBreak(sourceFile.text, after.end)) { @@ -873,25 +874,25 @@ namespace ts.textChanges { } if (multilineList) { // insert separator immediately following the 'after' node to preserve comments in trailing trivia - this.replaceRange(sourceFile, createRange(end), factory.createToken(separator)); + this.replaceRange(sourceFile, ts.createRange(end), ts.factory.createToken(separator)); // use the same indentation as 'after' item - const indentation = formatting.SmartIndenter.findFirstNonWhitespaceColumn(afterStartLinePosition, afterStart, sourceFile, this.formatContext.options); + const indentation = ts.formatting.SmartIndenter.findFirstNonWhitespaceColumn(afterStartLinePosition, afterStart, sourceFile, this.formatContext.options); // insert element before the line break on the line that contains 'after' element - let insertPos = skipTrivia(sourceFile.text, end, /*stopAfterLineBreak*/ true, /*stopAtComments*/ false); + let insertPos = ts.skipTrivia(sourceFile.text, end, /*stopAfterLineBreak*/ true, /*stopAtComments*/ false); // find position before "\n" or "\r\n" - while (insertPos !== end && isLineBreak(sourceFile.text.charCodeAt(insertPos - 1))) { + while (insertPos !== end && ts.isLineBreak(sourceFile.text.charCodeAt(insertPos - 1))) { insertPos--; } - this.replaceRange(sourceFile, createRange(insertPos), newNode, { indentation, prefix: this.newLineCharacter }); + this.replaceRange(sourceFile, ts.createRange(insertPos), newNode, { indentation, prefix: this.newLineCharacter }); } else { - this.replaceRange(sourceFile, createRange(end), newNode, { prefix: `${tokenToString(separator)} ` }); + this.replaceRange(sourceFile, ts.createRange(end), newNode, { prefix: `${ts.tokenToString(separator)} ` }); } } } - public parenthesizeExpression(sourceFile: SourceFile, expression: Expression) { - this.replaceRange(sourceFile, rangeOfNode(expression), factory.createParenthesizedExpression(expression)); + public parenthesizeExpression(sourceFile: ts.SourceFile, expression: ts.Expression) { + this.replaceRange(sourceFile, ts.rangeOfNode(expression), ts.factory.createParenthesizedExpression(expression)); } private finishClassesWithNodesInsertedAtStart(): void { @@ -899,10 +900,10 @@ namespace ts.textChanges { const [openBraceEnd, closeBraceEnd] = getClassOrObjectBraceEnds(node, sourceFile); if (openBraceEnd !== undefined && closeBraceEnd !== undefined) { const isEmpty = getMembersOrProperties(node).length === 0; - const isSingleLine = positionsAreOnSameLine(openBraceEnd, closeBraceEnd, sourceFile); + const isSingleLine = ts.positionsAreOnSameLine(openBraceEnd, closeBraceEnd, sourceFile); if (isEmpty && isSingleLine && openBraceEnd !== closeBraceEnd - 1) { // For `class C { }` remove the whitespace inside the braces. - this.deleteRange(sourceFile, createRange(openBraceEnd, closeBraceEnd - 1)); + this.deleteRange(sourceFile, ts.createRange(openBraceEnd, closeBraceEnd - 1)); } if (isSingleLine) { this.insertText(sourceFile, closeBraceEnd - 1, this.newLineCharacter); @@ -912,11 +913,11 @@ namespace ts.textChanges { } private finishDeleteDeclarations(): void { - const deletedNodesInLists = new Set(); // Stores nodes in lists that we already deleted. Used to avoid deleting `, ` twice in `a, b`. + const deletedNodesInLists = new ts.Set(); // Stores nodes in lists that we already deleted. Used to avoid deleting `, ` twice in `a, b`. for (const { sourceFile, node } of this.deletedNodes) { - if (!this.deletedNodes.some(d => d.sourceFile === sourceFile && rangeContainsRangeExclusive(d.node, node))) { - if (isArray(node)) { - this.deleteRange(sourceFile, rangeOfTypeParameters(sourceFile, node)); + if (!this.deletedNodes.some(d => d.sourceFile === sourceFile && ts.rangeContainsRangeExclusive(d.node, node))) { + if (ts.isArray(node)) { + this.deleteRange(sourceFile, ts.rangeOfTypeParameters(sourceFile, node)); } else { deleteDeclaration.deleteDeclaration(this, deletedNodesInLists, sourceFile, node); @@ -926,10 +927,10 @@ namespace ts.textChanges { deletedNodesInLists.forEach(node => { const sourceFile = node.getSourceFile(); - const list = formatting.SmartIndenter.getContainingList(node, sourceFile)!; - if (node !== last(list)) return; - - const lastNonDeletedIndex = findLastIndex(list, n => !deletedNodesInLists.has(n), list.length - 2); + const list = ts.formatting.SmartIndenter.getContainingList(node, sourceFile)!; + if (node !== ts.last(list)) + return; + const lastNonDeletedIndex = ts.findLastIndex(list, n => !deletedNodesInLists.has(n), list.length - 2); if (lastNonDeletedIndex !== -1) { this.deleteRange(sourceFile, { pos: list[lastNonDeletedIndex].end, end: startPositionToDeleteNodeInList(sourceFile, list[lastNonDeletedIndex + 1]) }); } @@ -942,7 +943,7 @@ namespace ts.textChanges { * The reason we must validate as part of this method is that `getNonFormattedText` changes the node's positions, * so we can only call this once and can't get the non-formatted text separately. */ - public getChanges(validate?: ValidateNonFormattedText): FileTextChanges[] { + public getChanges(validate?: ValidateNonFormattedText): ts.FileTextChanges[] { this.finishDeleteDeclarations(); this.finishClassesWithNodesInsertedAtStart(); const changes = changesToText.getTextChangesFromChanges(this.changes, this.newLineCharacter, this.formatContext, validate); @@ -952,105 +953,105 @@ namespace ts.textChanges { return changes; } - public createNewFile(oldFile: SourceFile | undefined, fileName: string, statements: readonly (Statement | SyntaxKind.NewLineTrivia)[]): void { + public createNewFile(oldFile: ts.SourceFile | undefined, fileName: string, statements: readonly (ts.Statement | ts.SyntaxKind.NewLineTrivia)[]): void { this.newFiles.push({ oldFile, fileName, statements }); } } - function updateJSDocHost(parent: HasJSDoc): HasJSDoc { - if (parent.kind !== SyntaxKind.ArrowFunction) { + function updateJSDocHost(parent: ts.HasJSDoc): ts.HasJSDoc { + if (parent.kind !== ts.SyntaxKind.ArrowFunction) { return parent; } - const jsDocNode = parent.parent.kind === SyntaxKind.PropertyDeclaration ? - parent.parent as HasJSDoc : - parent.parent.parent as HasJSDoc; + const jsDocNode = parent.parent.kind === ts.SyntaxKind.PropertyDeclaration ? + parent.parent as ts.HasJSDoc : + parent.parent.parent as ts.HasJSDoc; jsDocNode.jsDoc = parent.jsDoc; jsDocNode.jsDocCache = parent.jsDocCache; return jsDocNode; } - function tryMergeJsdocTags(oldTag: JSDocTag, newTag: JSDocTag): JSDocTag | undefined { + function tryMergeJsdocTags(oldTag: ts.JSDocTag, newTag: ts.JSDocTag): ts.JSDocTag | undefined { if (oldTag.kind !== newTag.kind) { return undefined; } switch (oldTag.kind) { - case SyntaxKind.JSDocParameterTag: { - const oldParam = oldTag as JSDocParameterTag; - const newParam = newTag as JSDocParameterTag; - return isIdentifier(oldParam.name) && isIdentifier(newParam.name) && oldParam.name.escapedText === newParam.name.escapedText - ? factory.createJSDocParameterTag(/*tagName*/ undefined, newParam.name, /*isBracketed*/ false, newParam.typeExpression, newParam.isNameFirst, oldParam.comment) + case ts.SyntaxKind.JSDocParameterTag: { + const oldParam = oldTag as ts.JSDocParameterTag; + const newParam = newTag as ts.JSDocParameterTag; + return ts.isIdentifier(oldParam.name) && ts.isIdentifier(newParam.name) && oldParam.name.escapedText === newParam.name.escapedText + ? ts.factory.createJSDocParameterTag(/*tagName*/ undefined, newParam.name, /*isBracketed*/ false, newParam.typeExpression, newParam.isNameFirst, oldParam.comment) : undefined; } - case SyntaxKind.JSDocReturnTag: - return factory.createJSDocReturnTag(/*tagName*/ undefined, (newTag as JSDocReturnTag).typeExpression, oldTag.comment); - case SyntaxKind.JSDocTypeTag: - return factory.createJSDocTypeTag(/*tagName*/ undefined, (newTag as JSDocTypeTag).typeExpression, oldTag.comment); + case ts.SyntaxKind.JSDocReturnTag: + return ts.factory.createJSDocReturnTag(/*tagName*/ undefined, (newTag as ts.JSDocReturnTag).typeExpression, oldTag.comment); + case ts.SyntaxKind.JSDocTypeTag: + return ts.factory.createJSDocTypeTag(/*tagName*/ undefined, (newTag as ts.JSDocTypeTag).typeExpression, oldTag.comment); } } // find first non-whitespace position in the leading trivia of the node - function startPositionToDeleteNodeInList(sourceFile: SourceFile, node: Node): number { - return skipTrivia(sourceFile.text, getAdjustedStartPosition(sourceFile, node, { leadingTriviaOption: LeadingTriviaOption.IncludeAll }), /*stopAfterLineBreak*/ false, /*stopAtComments*/ true); + function startPositionToDeleteNodeInList(sourceFile: ts.SourceFile, node: ts.Node): number { + return ts.skipTrivia(sourceFile.text, getAdjustedStartPosition(sourceFile, node, { leadingTriviaOption: LeadingTriviaOption.IncludeAll }), /*stopAfterLineBreak*/ false, /*stopAtComments*/ true); } - - function getClassOrObjectBraceEnds(cls: ClassLikeDeclaration | InterfaceDeclaration | ObjectLiteralExpression, sourceFile: SourceFile): [number | undefined, number | undefined] { - const open = findChildOfKind(cls, SyntaxKind.OpenBraceToken, sourceFile); - const close = findChildOfKind(cls, SyntaxKind.CloseBraceToken, sourceFile); + function getClassOrObjectBraceEnds(cls: ts.ClassLikeDeclaration | ts.InterfaceDeclaration | ts.ObjectLiteralExpression, sourceFile: ts.SourceFile): [ + number | undefined, + number | undefined + ] { + const open = ts.findChildOfKind(cls, ts.SyntaxKind.OpenBraceToken, sourceFile); + const close = ts.findChildOfKind(cls, ts.SyntaxKind.CloseBraceToken, sourceFile); return [open?.end, close?.end]; } - function getMembersOrProperties(node: ClassLikeDeclaration | InterfaceDeclaration | ObjectLiteralExpression | TypeLiteralNode): NodeArray { - return isObjectLiteralExpression(node) ? node.properties : node.members; + function getMembersOrProperties(node: ts.ClassLikeDeclaration | ts.InterfaceDeclaration | ts.ObjectLiteralExpression | ts.TypeLiteralNode): ts.NodeArray { + return ts.isObjectLiteralExpression(node) ? node.properties : node.members; } - export type ValidateNonFormattedText = (node: Node, text: string) => void; - - export function getNewFileText(statements: readonly Statement[], scriptKind: ScriptKind, newLineCharacter: string, formatContext: formatting.FormatContext): string { + export type ValidateNonFormattedText = (node: ts.Node, text: string) => void; + export function getNewFileText(statements: readonly ts.Statement[], scriptKind: ts.ScriptKind, newLineCharacter: string, formatContext: ts.formatting.FormatContext): string { return changesToText.newFileChangesWorker(/*oldFile*/ undefined, scriptKind, statements, newLineCharacter, formatContext); } namespace changesToText { - export function getTextChangesFromChanges(changes: readonly Change[], newLineCharacter: string, formatContext: formatting.FormatContext, validate: ValidateNonFormattedText | undefined): FileTextChanges[] { - return mapDefined(group(changes, c => c.sourceFile.path), changesInFile => { + export function getTextChangesFromChanges(changes: readonly Change[], newLineCharacter: string, formatContext: ts.formatting.FormatContext, validate: ValidateNonFormattedText | undefined): ts.FileTextChanges[] { + return ts.mapDefined(ts.group(changes, c => c.sourceFile.path), changesInFile => { const sourceFile = changesInFile[0].sourceFile; // order changes by start position // If the start position is the same, put the shorter range first, since an empty range (x, x) may precede (x, y) but not vice-versa. - const normalized = stableSort(changesInFile, (a, b) => (a.range.pos - b.range.pos) || (a.range.end - b.range.end)); + const normalized = ts.stableSort(changesInFile, (a, b) => (a.range.pos - b.range.pos) || (a.range.end - b.range.end)); // verify that change intervals do not overlap, except possibly at end points. for (let i = 0; i < normalized.length - 1; i++) { - Debug.assert(normalized[i].range.end <= normalized[i + 1].range.pos, "Changes overlap", () => - `${JSON.stringify(normalized[i].range)} and ${JSON.stringify(normalized[i + 1].range)}`); + ts.Debug.assert(normalized[i].range.end <= normalized[i + 1].range.pos, "Changes overlap", () => `${JSON.stringify(normalized[i].range)} and ${JSON.stringify(normalized[i + 1].range)}`); } - const textChanges = mapDefined(normalized, c => { - const span = createTextSpanFromRange(c.range); + const textChanges = ts.mapDefined(normalized, c => { + const span = ts.createTextSpanFromRange(c.range); const newText = computeNewText(c, sourceFile, newLineCharacter, formatContext, validate); // Filter out redundant changes. - if (span.length === newText.length && stringContainsAt(sourceFile.text, newText, span.start)) { + if (span.length === newText.length && ts.stringContainsAt(sourceFile.text, newText, span.start)) { return undefined; } - return createTextChange(span, newText); + return ts.createTextChange(span, newText); }); return textChanges.length > 0 ? { fileName: sourceFile.fileName, textChanges } : undefined; }); } - export function newFileChanges(oldFile: SourceFile | undefined, fileName: string, statements: readonly (Statement | SyntaxKind.NewLineTrivia)[], newLineCharacter: string, formatContext: formatting.FormatContext): FileTextChanges { - const text = newFileChangesWorker(oldFile, getScriptKindFromFileName(fileName), statements, newLineCharacter, formatContext); - return { fileName, textChanges: [createTextChange(createTextSpan(0, 0), text)], isNewFile: true }; + export function newFileChanges(oldFile: ts.SourceFile | undefined, fileName: string, statements: readonly (ts.Statement | ts.SyntaxKind.NewLineTrivia)[], newLineCharacter: string, formatContext: ts.formatting.FormatContext): ts.FileTextChanges { + const text = newFileChangesWorker(oldFile, ts.getScriptKindFromFileName(fileName), statements, newLineCharacter, formatContext); + return { fileName, textChanges: [ts.createTextChange(ts.createTextSpan(0, 0), text)], isNewFile: true }; } - export function newFileChangesWorker(oldFile: SourceFile | undefined, scriptKind: ScriptKind, statements: readonly (Statement | SyntaxKind.NewLineTrivia)[], newLineCharacter: string, formatContext: formatting.FormatContext): string { + export function newFileChangesWorker(oldFile: ts.SourceFile | undefined, scriptKind: ts.ScriptKind, statements: readonly (ts.Statement | ts.SyntaxKind.NewLineTrivia)[], newLineCharacter: string, formatContext: ts.formatting.FormatContext): string { // TODO: this emits the file, parses it back, then formats it that -- may be a less roundabout way to do this - const nonFormattedText = statements.map(s => s === SyntaxKind.NewLineTrivia ? "" : getNonformattedText(s, oldFile, newLineCharacter).text).join(newLineCharacter); - const sourceFile = createSourceFile("any file name", nonFormattedText, ScriptTarget.ESNext, /*setParentNodes*/ true, scriptKind); - const changes = formatting.formatDocument(sourceFile, formatContext); + const nonFormattedText = statements.map(s => s === ts.SyntaxKind.NewLineTrivia ? "" : getNonformattedText(s, oldFile, newLineCharacter).text).join(newLineCharacter); + const sourceFile = ts.createSourceFile("any file name", nonFormattedText, ts.ScriptTarget.ESNext, /*setParentNodes*/ true, scriptKind); + const changes = ts.formatting.formatDocument(sourceFile, formatContext); return applyChanges(nonFormattedText, changes) + newLineCharacter; } - function computeNewText(change: Change, sourceFile: SourceFile, newLineCharacter: string, formatContext: formatting.FormatContext, validate: ValidateNonFormattedText | undefined): string { + function computeNewText(change: Change, sourceFile: ts.SourceFile, newLineCharacter: string, formatContext: ts.formatting.FormatContext, validate: ValidateNonFormattedText | undefined): string { if (change.kind === ChangeKind.Remove) { return ""; } @@ -1059,126 +1060,128 @@ namespace ts.textChanges { } const { options = {}, range: { pos } } = change; - const format = (n: Node) => getFormattedTextOfNode(n, sourceFile, pos, options, newLineCharacter, formatContext, validate); + const format = (n: ts.Node) => getFormattedTextOfNode(n, sourceFile, pos, options, newLineCharacter, formatContext, validate); const text = change.kind === ChangeKind.ReplaceWithMultipleNodes - ? change.nodes.map(n => removeSuffix(format(n), newLineCharacter)).join(change.options?.joiner || newLineCharacter) + ? change.nodes.map(n => ts.removeSuffix(format(n), newLineCharacter)).join(change.options?.joiner || newLineCharacter) : format(change.node); // strip initial indentation (spaces or tabs) if text will be inserted in the middle of the line - const noIndent = (options.indentation !== undefined || getLineStartPositionForPosition(pos, sourceFile) === pos) ? text : text.replace(/^\s+/, ""); + const noIndent = (options.indentation !== undefined || ts.getLineStartPositionForPosition(pos, sourceFile) === pos) ? text : text.replace(/^\s+/, ""); return (options.prefix || "") + noIndent - + ((!options.suffix || endsWith(noIndent, options.suffix)) + + ((!options.suffix || ts.endsWith(noIndent, options.suffix)) ? "" : options.suffix); } /** Note: this may mutate `nodeIn`. */ - function getFormattedTextOfNode(nodeIn: Node, sourceFile: SourceFile, pos: number, { indentation, prefix, delta }: InsertNodeOptions, newLineCharacter: string, formatContext: formatting.FormatContext, validate: ValidateNonFormattedText | undefined): string { + function getFormattedTextOfNode(nodeIn: ts.Node, sourceFile: ts.SourceFile, pos: number, { indentation, prefix, delta }: InsertNodeOptions, newLineCharacter: string, formatContext: ts.formatting.FormatContext, validate: ValidateNonFormattedText | undefined): string { const { node, text } = getNonformattedText(nodeIn, sourceFile, newLineCharacter); - if (validate) validate(node, text); - const formatOptions = getFormatCodeSettingsForWriting(formatContext, sourceFile); - const initialIndentation = - indentation !== undefined + if (validate) + validate(node, text); + const formatOptions = ts.getFormatCodeSettingsForWriting(formatContext, sourceFile); + const initialIndentation = indentation !== undefined ? indentation - : formatting.SmartIndenter.getIndentation(pos, sourceFile, formatOptions, prefix === newLineCharacter || getLineStartPositionForPosition(pos, sourceFile) === pos); + : ts.formatting.SmartIndenter.getIndentation(pos, sourceFile, formatOptions, prefix === newLineCharacter || ts.getLineStartPositionForPosition(pos, sourceFile) === pos); if (delta === undefined) { - delta = formatting.SmartIndenter.shouldIndentChildNode(formatOptions, nodeIn) ? (formatOptions.indentSize || 0) : 0; + delta = ts.formatting.SmartIndenter.shouldIndentChildNode(formatOptions, nodeIn) ? (formatOptions.indentSize || 0) : 0; } - const file: SourceFileLike = { + const file: ts.SourceFileLike = { text, getLineAndCharacterOfPosition(pos) { - return getLineAndCharacterOfPosition(this, pos); + return ts.getLineAndCharacterOfPosition(this, pos); } }; - const changes = formatting.formatNodeGivenIndentation(node, file, sourceFile.languageVariant, initialIndentation, delta, { ...formatContext, options: formatOptions }); + const changes = ts.formatting.formatNodeGivenIndentation(node, file, sourceFile.languageVariant, initialIndentation, delta, { ...formatContext, options: formatOptions }); return applyChanges(text, changes); } /** Note: output node may be mutated input node. */ - export function getNonformattedText(node: Node, sourceFile: SourceFile | undefined, newLineCharacter: string): { text: string, node: Node } { + export function getNonformattedText(node: ts.Node, sourceFile: ts.SourceFile | undefined, newLineCharacter: string): { + text: string; + node: ts.Node; + } { const writer = createWriter(newLineCharacter); - const newLine = getNewLineKind(newLineCharacter); - createPrinter({ + const newLine = ts.getNewLineKind(newLineCharacter); + ts.createPrinter({ newLine, neverAsciiEscape: true, preserveSourceNewlines: true, terminateUnterminatedLiterals: true - }, writer).writeNode(EmitHint.Unspecified, node, sourceFile, writer); + }, writer).writeNode(ts.EmitHint.Unspecified, node, sourceFile, writer); return { text: writer.getText(), node: assignPositionsToNode(node) }; } } - export function applyChanges(text: string, changes: readonly TextChange[]): string { + export function applyChanges(text: string, changes: readonly ts.TextChange[]): string { for (let i = changes.length - 1; i >= 0; i--) { const { span, newText } = changes[i]; - text = `${text.substring(0, span.start)}${newText}${text.substring(textSpanEnd(span))}`; + text = `${text.substring(0, span.start)}${newText}${text.substring(ts.textSpanEnd(span))}`; } return text; } function isTrivia(s: string) { - return skipTrivia(s, 0) === s.length; + return ts.skipTrivia(s, 0) === s.length; } // A transformation context that won't perform parenthesization, as some parenthesization rules // are more aggressive than is strictly necessary. - const textChangesTransformationContext: TransformationContext = { - ...nullTransformationContext, - factory: createNodeFactory( - nullTransformationContext.factory.flags | NodeFactoryFlags.NoParenthesizerRules, - nullTransformationContext.factory.baseFactory), + const textChangesTransformationContext: ts.TransformationContext = { + ...ts.nullTransformationContext, + factory: ts.createNodeFactory(ts.nullTransformationContext.factory.flags | ts.NodeFactoryFlags.NoParenthesizerRules, ts.nullTransformationContext.factory.baseFactory), }; - export function assignPositionsToNode(node: Node): Node { - const visited = visitEachChild(node, assignPositionsToNode, textChangesTransformationContext, assignPositionsToNodeArray, assignPositionsToNode); + export function assignPositionsToNode(node: ts.Node): ts.Node { + const visited = ts.visitEachChild(node, assignPositionsToNode, textChangesTransformationContext, assignPositionsToNodeArray, assignPositionsToNode); // create proxy node for non synthesized nodes - const newNode = nodeIsSynthesized(visited) ? visited : Object.create(visited) as Node; - setTextRangePosEnd(newNode, getPos(node), getEnd(node)); + const newNode = ts.nodeIsSynthesized(visited) ? visited : Object.create(visited) as ts.Node; + ts.setTextRangePosEnd(newNode, getPos(node), getEnd(node)); return newNode; } - function assignPositionsToNodeArray(nodes: NodeArray, visitor: Visitor, test?: (node: Node) => boolean, start?: number, count?: number) { - const visited = visitNodes(nodes, visitor, test, start, count); + function assignPositionsToNodeArray(nodes: ts.NodeArray, visitor: ts.Visitor, test?: (node: ts.Node) => boolean, start?: number, count?: number) { + const visited = ts.visitNodes(nodes, visitor, test, start, count); if (!visited) { return visited; } // clone nodearray if necessary - const nodeArray = visited === nodes ? factory.createNodeArray(visited.slice(0)) : visited; - setTextRangePosEnd(nodeArray, getPos(nodes), getEnd(nodes)); + const nodeArray = visited === nodes ? ts.factory.createNodeArray(visited.slice(0)) : visited; + ts.setTextRangePosEnd(nodeArray, getPos(nodes), getEnd(nodes)); return nodeArray; } - interface TextChangesWriter extends EmitTextWriter, PrintHandlers {} + interface TextChangesWriter extends ts.EmitTextWriter, ts.PrintHandlers { + } export function createWriter(newLine: string): TextChangesWriter { let lastNonTriviaPosition = 0; - const writer = createTextWriter(newLine); - const onBeforeEmitNode: PrintHandlers["onBeforeEmitNode"] = node => { + const writer = ts.createTextWriter(newLine); + const onBeforeEmitNode: ts.PrintHandlers["onBeforeEmitNode"] = node => { if (node) { setPos(node, lastNonTriviaPosition); } }; - const onAfterEmitNode: PrintHandlers["onAfterEmitNode"] = node => { + const onAfterEmitNode: ts.PrintHandlers["onAfterEmitNode"] = node => { if (node) { setEnd(node, lastNonTriviaPosition); } }; - const onBeforeEmitNodeArray: PrintHandlers["onBeforeEmitNodeArray"] = nodes => { + const onBeforeEmitNodeArray: ts.PrintHandlers["onBeforeEmitNodeArray"] = nodes => { if (nodes) { setPos(nodes, lastNonTriviaPosition); } }; - const onAfterEmitNodeArray: PrintHandlers["onAfterEmitNodeArray"] = nodes => { + const onAfterEmitNodeArray: ts.PrintHandlers["onAfterEmitNodeArray"] = nodes => { if (nodes) { setEnd(nodes, lastNonTriviaPosition); } }; - const onBeforeEmitToken: PrintHandlers["onBeforeEmitToken"] = node => { + const onBeforeEmitToken: ts.PrintHandlers["onBeforeEmitToken"] = node => { if (node) { setPos(node, lastNonTriviaPosition); } }; - const onAfterEmitToken: PrintHandlers["onAfterEmitToken"] = node => { + const onAfterEmitToken: ts.PrintHandlers["onAfterEmitToken"] = node => { if (node) { setEnd(node, lastNonTriviaPosition); } @@ -1188,7 +1191,7 @@ namespace ts.textChanges { if (force || !isTrivia(s)) { lastNonTriviaPosition = writer.getTextPos(); let i = 0; - while (isWhiteSpaceLike(s.charCodeAt(s.length - i - 1))) { + while (ts.isWhiteSpaceLike(s.charCodeAt(s.length - i - 1))) { i++; } // trim trailing whitespaces @@ -1235,7 +1238,7 @@ namespace ts.textChanges { writer.writeStringLiteral(s); setLastNonTriviaPosition(s, /*force*/ false); } - function writeSymbol(s: string, sym: Symbol): void { + function writeSymbol(s: string, sym: ts.Symbol): void { writer.writeSymbol(s, sym); setLastNonTriviaPosition(s, /*force*/ false); } @@ -1314,10 +1317,10 @@ namespace ts.textChanges { }; } - function getInsertionPositionAtSourceFileTop(sourceFile: SourceFile): number { - let lastPrologue: PrologueDirective | undefined; + function getInsertionPositionAtSourceFileTop(sourceFile: ts.SourceFile): number { + let lastPrologue: ts.PrologueDirective | undefined; for (const node of sourceFile.statements) { - if (isPrologueDirective(node)) { + if (ts.isPrologueDirective(node)) { lastPrologue = node; } else { @@ -1333,45 +1336,53 @@ namespace ts.textChanges { return position; } - const shebang = getShebang(text); + const shebang = ts.getShebang(text); if (shebang !== undefined) { position = shebang.length; advancePastLineBreak(); } - const ranges = getLeadingCommentRanges(text, position); - if (!ranges) return position; + const ranges = ts.getLeadingCommentRanges(text, position); + if (!ranges) + return position; // Find the first attached comment to the first node and add before it - let lastComment: { range: CommentRange; pinnedOrTripleSlash: boolean; } | undefined; + let lastComment: { + range: ts.CommentRange; + pinnedOrTripleSlash: boolean; + } | undefined; let firstNodeLine: number | undefined; for (const range of ranges) { - if (range.kind === SyntaxKind.MultiLineCommentTrivia) { - if (isPinnedComment(text, range.pos)) { + if (range.kind === ts.SyntaxKind.MultiLineCommentTrivia) { + if (ts.isPinnedComment(text, range.pos)) { lastComment = { range, pinnedOrTripleSlash: true }; continue; } } - else if (isRecognizedTripleSlashComment(text, range.pos, range.end)) { + else if (ts.isRecognizedTripleSlashComment(text, range.pos, range.end)) { lastComment = { range, pinnedOrTripleSlash: true }; continue; } if (lastComment) { // Always insert after pinned or triple slash comments - if (lastComment.pinnedOrTripleSlash) break; + if (lastComment.pinnedOrTripleSlash) + break; // There was a blank line between the last comment and this comment. // This comment is not part of the copyright comments const commentLine = sourceFile.getLineAndCharacterOfPosition(range.pos).line; const lastCommentEndLine = sourceFile.getLineAndCharacterOfPosition(lastComment.range.end).line; - if (commentLine >= lastCommentEndLine + 2) break; + if (commentLine >= lastCommentEndLine + 2) + break; } if (sourceFile.statements.length) { - if (firstNodeLine === undefined) firstNodeLine = sourceFile.getLineAndCharacterOfPosition(sourceFile.statements[0].getStart()).line; + if (firstNodeLine === undefined) + firstNodeLine = sourceFile.getLineAndCharacterOfPosition(sourceFile.statements[0].getStart()).line; const commentEndLine = sourceFile.getLineAndCharacterOfPosition(range.end).line; - if (firstNodeLine < commentEndLine + 2) break; + if (firstNodeLine < commentEndLine + 2) + break; } lastComment = { range, pinnedOrTripleSlash: false }; } @@ -1385,10 +1396,10 @@ namespace ts.textChanges { function advancePastLineBreak() { if (position < text.length) { const charCode = text.charCodeAt(position); - if (isLineBreak(charCode)) { + if (ts.isLineBreak(charCode)) { position++; - if (position < text.length && charCode === CharacterCodes.carriageReturn && text.charCodeAt(position) === CharacterCodes.lineFeed) { + if (position < text.length && charCode === ts.CharacterCodes.carriageReturn && text.charCodeAt(position) === ts.CharacterCodes.lineFeed) { position++; } } @@ -1396,23 +1407,23 @@ namespace ts.textChanges { } } - export function isValidLocationToAddComment(sourceFile: SourceFile, position: number) { - return !isInComment(sourceFile, position) && !isInString(sourceFile, position) && !isInTemplateString(sourceFile, position) && !isInJSXText(sourceFile, position); + export function isValidLocationToAddComment(sourceFile: ts.SourceFile, position: number) { + return !ts.isInComment(sourceFile, position) && !ts.isInString(sourceFile, position) && !ts.isInTemplateString(sourceFile, position) && !ts.isInJSXText(sourceFile, position); } - function needSemicolonBetween(a: Node, b: Node): boolean { - return (isPropertySignature(a) || isPropertyDeclaration(a)) && isClassOrTypeElement(b) && b.name!.kind === SyntaxKind.ComputedPropertyName - || isStatementButNotDeclaration(a) && isStatementButNotDeclaration(b); // TODO: only if b would start with a `(` or `[` + function needSemicolonBetween(a: ts.Node, b: ts.Node): boolean { + return (ts.isPropertySignature(a) || ts.isPropertyDeclaration(a)) && ts.isClassOrTypeElement(b) && b.name!.kind === ts.SyntaxKind.ComputedPropertyName + || ts.isStatementButNotDeclaration(a) && ts.isStatementButNotDeclaration(b); // TODO: only if b would start with a `(` or `[` } namespace deleteDeclaration { - export function deleteDeclaration(changes: ChangeTracker, deletedNodesInLists: Set, sourceFile: SourceFile, node: Node): void { + export function deleteDeclaration(changes: ChangeTracker, deletedNodesInLists: ts.Set, sourceFile: ts.SourceFile, node: ts.Node): void { switch (node.kind) { - case SyntaxKind.Parameter: { + case ts.SyntaxKind.Parameter: { const oldFunction = node.parent; - if (isArrowFunction(oldFunction) && + if (ts.isArrowFunction(oldFunction) && oldFunction.parameters.length === 1 && - !findChildOfKind(oldFunction, SyntaxKind.OpenParenToken, sourceFile)) { + !ts.findChildOfKind(oldFunction, ts.SyntaxKind.OpenParenToken, sourceFile)) { // Lambdas with exactly one parameter are special because, after removal, there // must be an empty parameter list (i.e. `()`) and this won't necessarily be the // case if the parameter is simply removed (e.g. in `x => 1`). @@ -1424,18 +1435,18 @@ namespace ts.textChanges { break; } - case SyntaxKind.ImportDeclaration: - case SyntaxKind.ImportEqualsDeclaration: - const isFirstImport = sourceFile.imports.length && node === first(sourceFile.imports).parent || node === find(sourceFile.statements, isAnyImportSyntax); + case ts.SyntaxKind.ImportDeclaration: + case ts.SyntaxKind.ImportEqualsDeclaration: + const isFirstImport = sourceFile.imports.length && node === ts.first(sourceFile.imports).parent || node === ts.find(sourceFile.statements, ts.isAnyImportSyntax); // For first import, leave header comment in place, otherwise only delete JSDoc comments deleteNode(changes, sourceFile, node, { - leadingTriviaOption: isFirstImport ? LeadingTriviaOption.Exclude : hasJSDocNodes(node) ? LeadingTriviaOption.JSDoc : LeadingTriviaOption.StartLine, + leadingTriviaOption: isFirstImport ? LeadingTriviaOption.Exclude : ts.hasJSDocNodes(node) ? LeadingTriviaOption.JSDoc : LeadingTriviaOption.StartLine, }); break; - case SyntaxKind.BindingElement: - const pattern = (node as BindingElement).parent; - const preserveComma = pattern.kind === SyntaxKind.ArrayBindingPattern && node !== last(pattern.elements); + case ts.SyntaxKind.BindingElement: + const pattern = (node as ts.BindingElement).parent; + const preserveComma = pattern.kind === ts.SyntaxKind.ArrayBindingPattern && node !== ts.last(pattern.elements); if (preserveComma) { deleteNode(changes, sourceFile, node); } @@ -1444,16 +1455,16 @@ namespace ts.textChanges { } break; - case SyntaxKind.VariableDeclaration: - deleteVariableDeclaration(changes, deletedNodesInLists, sourceFile, node as VariableDeclaration); + case ts.SyntaxKind.VariableDeclaration: + deleteVariableDeclaration(changes, deletedNodesInLists, sourceFile, node as ts.VariableDeclaration); break; - case SyntaxKind.TypeParameter: + case ts.SyntaxKind.TypeParameter: deleteNodeInList(changes, deletedNodesInLists, sourceFile, node); break; - case SyntaxKind.ImportSpecifier: - const namedImports = (node as ImportSpecifier).parent; + case ts.SyntaxKind.ImportSpecifier: + const namedImports = (node as ts.ImportSpecifier).parent; if (namedImports.elements.length === 1) { deleteImportBinding(changes, sourceFile, namedImports); } @@ -1462,21 +1473,21 @@ namespace ts.textChanges { } break; - case SyntaxKind.NamespaceImport: - deleteImportBinding(changes, sourceFile, node as NamespaceImport); + case ts.SyntaxKind.NamespaceImport: + deleteImportBinding(changes, sourceFile, node as ts.NamespaceImport); break; - case SyntaxKind.SemicolonToken: + case ts.SyntaxKind.SemicolonToken: deleteNode(changes, sourceFile, node, { trailingTriviaOption: TrailingTriviaOption.Exclude }); break; - case SyntaxKind.FunctionKeyword: + case ts.SyntaxKind.FunctionKeyword: deleteNode(changes, sourceFile, node, { leadingTriviaOption: LeadingTriviaOption.Exclude }); break; - case SyntaxKind.ClassDeclaration: - case SyntaxKind.FunctionDeclaration: - deleteNode(changes, sourceFile, node, { leadingTriviaOption: hasJSDocNodes(node) ? LeadingTriviaOption.JSDoc : LeadingTriviaOption.StartLine }); + case ts.SyntaxKind.ClassDeclaration: + case ts.SyntaxKind.FunctionDeclaration: + deleteNode(changes, sourceFile, node, { leadingTriviaOption: ts.hasJSDocNodes(node) ? LeadingTriviaOption.JSDoc : LeadingTriviaOption.StartLine }); break; default: @@ -1484,10 +1495,10 @@ namespace ts.textChanges { // a misbehaving client can reach here with the SourceFile node deleteNode(changes, sourceFile, node); } - else if (isImportClause(node.parent) && node.parent.name === node) { + else if (ts.isImportClause(node.parent) && node.parent.name === node) { deleteDefaultImport(changes, sourceFile, node.parent); } - else if (isCallExpression(node.parent) && contains(node.parent.arguments, node)) { + else if (ts.isCallExpression(node.parent) && ts.contains(node.parent.arguments, node)) { deleteNodeInList(changes, deletedNodesInLists, sourceFile, node); } else { @@ -1496,7 +1507,7 @@ namespace ts.textChanges { } } - function deleteDefaultImport(changes: ChangeTracker, sourceFile: SourceFile, importClause: ImportClause): void { + function deleteDefaultImport(changes: ChangeTracker, sourceFile: ts.SourceFile, importClause: ts.ImportClause): void { if (!importClause.namedBindings) { // Delete the whole import deleteNode(changes, sourceFile, importClause.parent); @@ -1504,10 +1515,10 @@ namespace ts.textChanges { else { // import |d,| * as ns from './file' const start = importClause.name!.getStart(sourceFile); - const nextToken = getTokenAtPosition(sourceFile, importClause.name!.end); - if (nextToken && nextToken.kind === SyntaxKind.CommaToken) { + const nextToken = ts.getTokenAtPosition(sourceFile, importClause.name!.end); + if (nextToken && nextToken.kind === ts.SyntaxKind.CommaToken) { // shift first non-whitespace position after comma to the start position of the node - const end = skipTrivia(sourceFile.text, nextToken.end, /*stopAfterLineBreaks*/ false, /*stopAtComments*/ true); + const end = ts.skipTrivia(sourceFile.text, nextToken.end, /*stopAfterLineBreaks*/ false, /*stopAtComments*/ true); changes.deleteRange(sourceFile, { pos: start, end }); } else { @@ -1516,29 +1527,29 @@ namespace ts.textChanges { } } - function deleteImportBinding(changes: ChangeTracker, sourceFile: SourceFile, node: NamedImportBindings): void { + function deleteImportBinding(changes: ChangeTracker, sourceFile: ts.SourceFile, node: ts.NamedImportBindings): void { if (node.parent.name) { // Delete named imports while preserving the default import // import d|, * as ns| from './file' // import d|, { a }| from './file' - const previousToken = Debug.checkDefined(getTokenAtPosition(sourceFile, node.pos - 1)); + const previousToken = ts.Debug.checkDefined(ts.getTokenAtPosition(sourceFile, node.pos - 1)); changes.deleteRange(sourceFile, { pos: previousToken.getStart(sourceFile), end: node.end }); } else { // Delete the entire import declaration // |import * as ns from './file'| // |import { a } from './file'| - const importDecl = getAncestor(node, SyntaxKind.ImportDeclaration)!; + const importDecl = ts.getAncestor(node, ts.SyntaxKind.ImportDeclaration)!; deleteNode(changes, sourceFile, importDecl); } } - function deleteVariableDeclaration(changes: ChangeTracker, deletedNodesInLists: Set, sourceFile: SourceFile, node: VariableDeclaration): void { + function deleteVariableDeclaration(changes: ChangeTracker, deletedNodesInLists: ts.Set, sourceFile: ts.SourceFile, node: ts.VariableDeclaration): void { const { parent } = node; - if (parent.kind === SyntaxKind.CatchClause) { + if (parent.kind === ts.SyntaxKind.CatchClause) { // TODO: There's currently no unused diagnostic for this, could be a suggestion - changes.deleteNodeRange(sourceFile, findChildOfKind(parent, SyntaxKind.OpenParenToken, sourceFile)!, findChildOfKind(parent, SyntaxKind.CloseParenToken, sourceFile)!); + changes.deleteNodeRange(sourceFile, ts.findChildOfKind(parent, ts.SyntaxKind.OpenParenToken, sourceFile)!, ts.findChildOfKind(parent, ts.SyntaxKind.CloseParenToken, sourceFile)!); return; } @@ -1549,37 +1560,37 @@ namespace ts.textChanges { const gp = parent.parent; switch (gp.kind) { - case SyntaxKind.ForOfStatement: - case SyntaxKind.ForInStatement: - changes.replaceNode(sourceFile, node, factory.createObjectLiteralExpression()); + case ts.SyntaxKind.ForOfStatement: + case ts.SyntaxKind.ForInStatement: + changes.replaceNode(sourceFile, node, ts.factory.createObjectLiteralExpression()); break; - case SyntaxKind.ForStatement: + case ts.SyntaxKind.ForStatement: deleteNode(changes, sourceFile, parent); break; - case SyntaxKind.VariableStatement: - deleteNode(changes, sourceFile, gp, { leadingTriviaOption: hasJSDocNodes(gp) ? LeadingTriviaOption.JSDoc : LeadingTriviaOption.StartLine }); + case ts.SyntaxKind.VariableStatement: + deleteNode(changes, sourceFile, gp, { leadingTriviaOption: ts.hasJSDocNodes(gp) ? LeadingTriviaOption.JSDoc : LeadingTriviaOption.StartLine }); break; default: - Debug.assertNever(gp); + ts.Debug.assertNever(gp); } } } /** Warning: This deletes comments too. See `copyComments` in `convertFunctionToEs6Class`. */ // Exported for tests only! (TODO: improve tests to not need this) - export function deleteNode(changes: ChangeTracker, sourceFile: SourceFile, node: Node, options: ConfigurableStartEnd = { leadingTriviaOption: LeadingTriviaOption.IncludeAll }): void { + export function deleteNode(changes: ChangeTracker, sourceFile: ts.SourceFile, node: ts.Node, options: ConfigurableStartEnd = { leadingTriviaOption: LeadingTriviaOption.IncludeAll }): void { const startPosition = getAdjustedStartPosition(sourceFile, node, options); const endPosition = getAdjustedEndPosition(sourceFile, node, options); changes.deleteRange(sourceFile, { pos: startPosition, end: endPosition }); } - function deleteNodeInList(changes: ChangeTracker, deletedNodesInLists: Set, sourceFile: SourceFile, node: Node): void { - const containingList = Debug.checkDefined(formatting.SmartIndenter.getContainingList(node, sourceFile)); - const index = indexOfNode(containingList, node); - Debug.assert(index !== -1); + function deleteNodeInList(changes: ChangeTracker, deletedNodesInLists: ts.Set, sourceFile: ts.SourceFile, node: ts.Node): void { + const containingList = ts.Debug.checkDefined(ts.formatting.SmartIndenter.getContainingList(node, sourceFile)); + const index = ts.indexOfNode(containingList, node); + ts.Debug.assert(index !== -1); if (containingList.length === 1) { deleteNode(changes, sourceFile, node); return; @@ -1587,7 +1598,7 @@ namespace ts.textChanges { // Note: We will only delete a comma *after* a node. This will leave a trailing comma if we delete the last node. // That's handled in the end by `finishTrailingCommaAfterDeletingNodesInList`. - Debug.assert(!deletedNodesInLists.has(node), "Deleting a node twice"); + ts.Debug.assert(!deletedNodesInLists.has(node), "Deleting a node twice"); deletedNodesInLists.add(node); changes.deleteRange(sourceFile, { pos: startPositionToDeleteNodeInList(sourceFile, node), diff --git a/src/services/transform.ts b/src/services/transform.ts index c0d87f67b6f1e..8d51cb5d804fc 100644 --- a/src/services/transform.ts +++ b/src/services/transform.ts @@ -5,12 +5,12 @@ namespace ts { * @param transformers An array of `TransformerFactory` callbacks used to process the transformation. * @param compilerOptions Optional compiler options. */ - export function transform(source: T | T[], transformers: TransformerFactory[], compilerOptions?: CompilerOptions) { - const diagnostics: DiagnosticWithLocation[] = []; - compilerOptions = fixupCompilerOptions(compilerOptions!, diagnostics); // TODO: GH#18217 - const nodes = isArray(source) ? source : [source]; - const result = transformNodes(/*resolver*/ undefined, /*emitHost*/ undefined, factory, compilerOptions, nodes, transformers, /*allowDtsFiles*/ true); - result.diagnostics = concatenate(result.diagnostics, diagnostics); + export function transform(source: T | T[], transformers: ts.TransformerFactory[], compilerOptions?: ts.CompilerOptions) { + const diagnostics: ts.DiagnosticWithLocation[] = []; + compilerOptions = ts.fixupCompilerOptions(compilerOptions!, diagnostics); // TODO: GH#18217 + const nodes = ts.isArray(source) ? source : [source]; + const result = ts.transformNodes(/*resolver*/ undefined, /*emitHost*/ undefined, ts.factory, compilerOptions, nodes, transformers, /*allowDtsFiles*/ true); + result.diagnostics = ts.concatenate(result.diagnostics, diagnostics); return result; } } \ No newline at end of file diff --git a/src/services/transpile.ts b/src/services/transpile.ts index b2d8951e43b7e..542b1c67b3a88 100644 --- a/src/services/transpile.ts +++ b/src/services/transpile.ts @@ -1,16 +1,16 @@ namespace ts { export interface TranspileOptions { - compilerOptions?: CompilerOptions; + compilerOptions?: ts.CompilerOptions; fileName?: string; reportDiagnostics?: boolean; moduleName?: string; - renamedDependencies?: MapLike; - transformers?: CustomTransformers; + renamedDependencies?: ts.MapLike; + transformers?: ts.CustomTransformers; } export interface TranspileOutput { outputText: string; - diagnostics?: Diagnostic[]; + diagnostics?: ts.Diagnostic[]; sourceMapText?: string; } @@ -24,19 +24,18 @@ namespace ts { * - noResolve = true */ export function transpileModule(input: string, transpileOptions: TranspileOptions): TranspileOutput { - const diagnostics: Diagnostic[] = []; - - const options: CompilerOptions = transpileOptions.compilerOptions ? fixupCompilerOptions(transpileOptions.compilerOptions, diagnostics) : {}; + const diagnostics: ts.Diagnostic[] = []; + const options: ts.CompilerOptions = transpileOptions.compilerOptions ? fixupCompilerOptions(transpileOptions.compilerOptions, diagnostics) : {}; // mix in default options - const defaultOptions = getDefaultCompilerOptions(); + const defaultOptions = ts.getDefaultCompilerOptions(); for (const key in defaultOptions) { - if (hasProperty(defaultOptions, key) && options[key] === undefined) { + if (ts.hasProperty(defaultOptions, key) && options[key] === undefined) { options[key] = defaultOptions[key]; } } - for (const option of transpileOptionValueCompilerOptions) { + for (const option of ts.transpileOptionValueCompilerOptions) { options[option.name] = option.transpileOptionValue; } @@ -46,17 +45,17 @@ namespace ts { // Filename can be non-ts file. options.allowNonTsExtensions = true; - const newLine = getNewLineCharacter(options); + const newLine = ts.getNewLineCharacter(options); // Create a compilerHost object to allow the compiler to read and write files - const compilerHost: CompilerHost = { - getSourceFile: (fileName) => fileName === normalizePath(inputFileName) ? sourceFile : undefined, + const compilerHost: ts.CompilerHost = { + getSourceFile: (fileName) => fileName === ts.normalizePath(inputFileName) ? sourceFile : undefined, writeFile: (name, text) => { - if (fileExtensionIs(name, ".map")) { - Debug.assertEqual(sourceMapText, undefined, "Unexpected multiple source map outputs, file:", name); + if (ts.fileExtensionIs(name, ".map")) { + ts.Debug.assertEqual(sourceMapText, undefined, "Unexpected multiple source map outputs, file:", name); sourceMapText = text; } else { - Debug.assertEqual(outputText, undefined, "Unexpected multiple outputs, file:", name); + ts.Debug.assertEqual(outputText, undefined, "Unexpected multiple outputs, file:", name); outputText = text; } }, @@ -73,37 +72,34 @@ namespace ts { // if jsx is specified then treat file as .tsx const inputFileName = transpileOptions.fileName || (transpileOptions.compilerOptions && transpileOptions.compilerOptions.jsx ? "module.tsx" : "module.ts"); - const sourceFile = createSourceFile( - inputFileName, - input, - { - languageVersion: getEmitScriptTarget(options), - impliedNodeFormat: getImpliedNodeFormatForFile(toPath(inputFileName, "", compilerHost.getCanonicalFileName), /*cache*/ undefined, compilerHost, options), - setExternalModuleIndicator: getSetExternalModuleIndicator(options) - } - ); + const sourceFile = ts.createSourceFile(inputFileName, input, { + languageVersion: ts.getEmitScriptTarget(options), + impliedNodeFormat: ts.getImpliedNodeFormatForFile(ts.toPath(inputFileName, "", compilerHost.getCanonicalFileName), /*cache*/ undefined, compilerHost, options), + setExternalModuleIndicator: ts.getSetExternalModuleIndicator(options) + }); if (transpileOptions.moduleName) { sourceFile.moduleName = transpileOptions.moduleName; } if (transpileOptions.renamedDependencies) { - sourceFile.renamedDependencies = new Map(getEntries(transpileOptions.renamedDependencies)); + sourceFile.renamedDependencies = new ts.Map(ts.getEntries(transpileOptions.renamedDependencies)); } // Output let outputText: string | undefined; let sourceMapText: string | undefined; - const program = createProgram([inputFileName], options, compilerHost); + const program = ts.createProgram([inputFileName], options, compilerHost); if (transpileOptions.reportDiagnostics) { - addRange(/*to*/ diagnostics, /*from*/ program.getSyntacticDiagnostics(sourceFile)); - addRange(/*to*/ diagnostics, /*from*/ program.getOptionsDiagnostics()); + ts.addRange(/*to*/ diagnostics, /*from*/ program.getSyntacticDiagnostics(sourceFile)); + ts.addRange(/*to*/ diagnostics, /*from*/ program.getOptionsDiagnostics()); } // Emit program.emit(/*targetSourceFile*/ undefined, /*writeFile*/ undefined, /*cancellationToken*/ undefined, /*emitOnlyDtsFiles*/ undefined, transpileOptions.transformers); - if (outputText === undefined) return Debug.fail("Output generation failed"); + if (outputText === undefined) + return ts.Debug.fail("Output generation failed"); return { outputText, diagnostics, sourceMapText }; } @@ -111,39 +107,38 @@ namespace ts { /* * This is a shortcut function for transpileModule - it accepts transpileOptions as parameters and returns only outputText part of the result. */ - export function transpile(input: string, compilerOptions?: CompilerOptions, fileName?: string, diagnostics?: Diagnostic[], moduleName?: string): string { + export function transpile(input: string, compilerOptions?: ts.CompilerOptions, fileName?: string, diagnostics?: ts.Diagnostic[], moduleName?: string): string { const output = transpileModule(input, { compilerOptions, fileName, reportDiagnostics: !!diagnostics, moduleName }); // addRange correctly handles cases when wither 'from' or 'to' argument is missing - addRange(diagnostics, output.diagnostics); + ts.addRange(diagnostics, output.diagnostics); return output.outputText; } - let commandLineOptionsStringToEnum: CommandLineOptionOfCustomType[]; + let commandLineOptionsStringToEnum: ts.CommandLineOptionOfCustomType[]; /** JS users may pass in string values for enum compiler options (such as ModuleKind), so convert. */ /*@internal*/ - export function fixupCompilerOptions(options: CompilerOptions, diagnostics: Diagnostic[]): CompilerOptions { + export function fixupCompilerOptions(options: ts.CompilerOptions, diagnostics: ts.Diagnostic[]): ts.CompilerOptions { // Lazily create this value to fix module loading errors. commandLineOptionsStringToEnum = commandLineOptionsStringToEnum || - filter(optionDeclarations, o => typeof o.type === "object" && !forEachEntry(o.type, v => typeof v !== "number")) as CommandLineOptionOfCustomType[]; - - options = cloneCompilerOptions(options); + ts.filter(ts.optionDeclarations, o => typeof o.type === "object" && !ts.forEachEntry(o.type, v => typeof v !== "number")) as ts.CommandLineOptionOfCustomType[]; + options = ts.cloneCompilerOptions(options); for (const opt of commandLineOptionsStringToEnum) { - if (!hasProperty(options, opt.name)) { + if (!ts.hasProperty(options, opt.name)) { continue; } const value = options[opt.name]; // Value should be a key of opt.type - if (isString(value)) { + if (ts.isString(value)) { // If value is not a string, this will fail - options[opt.name] = parseCustomTypeOption(opt, value, diagnostics); + options[opt.name] = ts.parseCustomTypeOption(opt, value, diagnostics); } else { - if (!forEachEntry(opt.type, v => v === value)) { + if (!ts.forEachEntry(opt.type, v => v === value)) { // Supplied value isn't a valid enum value. - diagnostics.push(createCompilerDiagnosticForInvalidCustomType(opt)); + diagnostics.push(ts.createCompilerDiagnosticForInvalidCustomType(opt)); } } } diff --git a/src/services/types.ts b/src/services/types.ts index 82ed0b9412455..f029b9639f327 100644 --- a/src/services/types.ts +++ b/src/services/types.ts @@ -1,29 +1,29 @@ namespace ts { export interface Node { - getSourceFile(): SourceFile; - getChildCount(sourceFile?: SourceFile): number; - getChildAt(index: number, sourceFile?: SourceFile): Node; - getChildren(sourceFile?: SourceFile): Node[]; + getSourceFile(): ts.SourceFile; + getChildCount(sourceFile?: ts.SourceFile): number; + getChildAt(index: number, sourceFile?: ts.SourceFile): ts.Node; + getChildren(sourceFile?: ts.SourceFile): ts.Node[]; /* @internal */ - getChildren(sourceFile?: SourceFileLike): Node[]; // eslint-disable-line @typescript-eslint/unified-signatures - getStart(sourceFile?: SourceFile, includeJsDocComment?: boolean): number; + getChildren(sourceFile?: ts.SourceFileLike): ts.Node[]; // eslint-disable-line @typescript-eslint/unified-signatures + getStart(sourceFile?: ts.SourceFile, includeJsDocComment?: boolean): number; /* @internal */ - getStart(sourceFile?: SourceFileLike, includeJsDocComment?: boolean): number; // eslint-disable-line @typescript-eslint/unified-signatures + getStart(sourceFile?: ts.SourceFileLike, includeJsDocComment?: boolean): number; // eslint-disable-line @typescript-eslint/unified-signatures getFullStart(): number; getEnd(): number; - getWidth(sourceFile?: SourceFileLike): number; + getWidth(sourceFile?: ts.SourceFileLike): number; getFullWidth(): number; - getLeadingTriviaWidth(sourceFile?: SourceFile): number; - getFullText(sourceFile?: SourceFile): string; - getText(sourceFile?: SourceFile): string; - getFirstToken(sourceFile?: SourceFile): Node | undefined; + getLeadingTriviaWidth(sourceFile?: ts.SourceFile): number; + getFullText(sourceFile?: ts.SourceFile): string; + getText(sourceFile?: ts.SourceFile): string; + getFirstToken(sourceFile?: ts.SourceFile): ts.Node | undefined; /* @internal */ - getFirstToken(sourceFile?: SourceFileLike): Node | undefined; // eslint-disable-line @typescript-eslint/unified-signatures - getLastToken(sourceFile?: SourceFile): Node | undefined; + getFirstToken(sourceFile?: ts.SourceFileLike): ts.Node | undefined; // eslint-disable-line @typescript-eslint/unified-signatures + getLastToken(sourceFile?: ts.SourceFile): ts.Node | undefined; /* @internal */ - getLastToken(sourceFile?: SourceFileLike): Node | undefined; // eslint-disable-line @typescript-eslint/unified-signatures + getLastToken(sourceFile?: ts.SourceFileLike): ts.Node | undefined; // eslint-disable-line @typescript-eslint/unified-signatures // See ts.forEachChild for documentation. - forEachChild(cbNode: (node: Node) => T | undefined, cbNodeArray?: (nodes: NodeArray) => T | undefined): T | undefined; + forEachChild(cbNode: (node: ts.Node) => T | undefined, cbNodeArray?: (nodes: ts.NodeArray) => T | undefined): T | undefined; } export interface Identifier { @@ -36,83 +36,79 @@ namespace ts { export interface Symbol { readonly name: string; - getFlags(): SymbolFlags; - getEscapedName(): __String; + getFlags(): ts.SymbolFlags; + getEscapedName(): ts.__String; getName(): string; - getDeclarations(): Declaration[] | undefined; - getDocumentationComment(typeChecker: TypeChecker | undefined): SymbolDisplayPart[]; + getDeclarations(): ts.Declaration[] | undefined; + getDocumentationComment(typeChecker: ts.TypeChecker | undefined): SymbolDisplayPart[]; /* @internal */ - getContextualDocumentationComment(context: Node | undefined, checker: TypeChecker | undefined): SymbolDisplayPart[] - getJsDocTags(checker?: TypeChecker): JSDocTagInfo[]; + getContextualDocumentationComment(context: ts.Node | undefined, checker: ts.TypeChecker | undefined): SymbolDisplayPart[]; + getJsDocTags(checker?: ts.TypeChecker): JSDocTagInfo[]; /* @internal */ - getContextualJsDocTags(context: Node | undefined, checker: TypeChecker | undefined): JSDocTagInfo[]; + getContextualJsDocTags(context: ts.Node | undefined, checker: ts.TypeChecker | undefined): JSDocTagInfo[]; } export interface Type { - getFlags(): TypeFlags; - getSymbol(): Symbol | undefined; - getProperties(): Symbol[]; - getProperty(propertyName: string): Symbol | undefined; - getApparentProperties(): Symbol[]; - getCallSignatures(): readonly Signature[]; - getConstructSignatures(): readonly Signature[]; - getStringIndexType(): Type | undefined; - getNumberIndexType(): Type | undefined; - getBaseTypes(): BaseType[] | undefined; - getNonNullableType(): Type; - /*@internal*/ getNonOptionalType(): Type; + getFlags(): ts.TypeFlags; + getSymbol(): ts.Symbol | undefined; + getProperties(): ts.Symbol[]; + getProperty(propertyName: string): ts.Symbol | undefined; + getApparentProperties(): ts.Symbol[]; + getCallSignatures(): readonly ts.Signature[]; + getConstructSignatures(): readonly ts.Signature[]; + getStringIndexType(): ts.Type | undefined; + getNumberIndexType(): ts.Type | undefined; + getBaseTypes(): ts.BaseType[] | undefined; + getNonNullableType(): ts.Type; + /*@internal*/ getNonOptionalType(): ts.Type; /*@internal*/ isNullableType(): boolean; - getConstraint(): Type | undefined; - getDefault(): Type | undefined; - - isUnion(): this is UnionType; - isIntersection(): this is IntersectionType; - isUnionOrIntersection(): this is UnionOrIntersectionType; - isLiteral(): this is LiteralType; - isStringLiteral(): this is StringLiteralType; - isNumberLiteral(): this is NumberLiteralType; - isTypeParameter(): this is TypeParameter; - isClassOrInterface(): this is InterfaceType; - isClass(): this is InterfaceType; - isIndexType(): this is IndexType; + getConstraint(): ts.Type | undefined; + getDefault(): ts.Type | undefined; + isUnion(): this is ts.UnionType; + isIntersection(): this is ts.IntersectionType; + isUnionOrIntersection(): this is ts.UnionOrIntersectionType; + isLiteral(): this is ts.LiteralType; + isStringLiteral(): this is ts.StringLiteralType; + isNumberLiteral(): this is ts.NumberLiteralType; + isTypeParameter(): this is ts.TypeParameter; + isClassOrInterface(): this is ts.InterfaceType; + isClass(): this is ts.InterfaceType; + isIndexType(): this is ts.IndexType; } export interface TypeReference { - typeArguments?: readonly Type[]; + typeArguments?: readonly ts.Type[]; } export interface Signature { - getDeclaration(): SignatureDeclaration; - getTypeParameters(): TypeParameter[] | undefined; - getParameters(): Symbol[]; - getTypeParameterAtPosition(pos: number): Type; - getReturnType(): Type; - getDocumentationComment(typeChecker: TypeChecker | undefined): SymbolDisplayPart[]; + getDeclaration(): ts.SignatureDeclaration; + getTypeParameters(): ts.TypeParameter[] | undefined; + getParameters(): ts.Symbol[]; + getTypeParameterAtPosition(pos: number): ts.Type; + getReturnType(): ts.Type; + getDocumentationComment(typeChecker: ts.TypeChecker | undefined): SymbolDisplayPart[]; getJsDocTags(): JSDocTagInfo[]; } export interface SourceFile { /* @internal */ version: string; /* @internal */ scriptSnapshot: IScriptSnapshot | undefined; - /* @internal */ nameTable: UnderscoreEscapedMap | undefined; - - /* @internal */ getNamedDeclarations(): ESMap; - - getLineAndCharacterOfPosition(pos: number): LineAndCharacter; + /* @internal */ nameTable: ts.UnderscoreEscapedMap | undefined; + /* @internal */ getNamedDeclarations(): ts.ESMap; + getLineAndCharacterOfPosition(pos: number): ts.LineAndCharacter; getLineEndOfPosition(pos: number): number; getLineStarts(): readonly number[]; getPositionOfLineAndCharacter(line: number, character: number): number; - update(newText: string, textChangeRange: TextChangeRange): SourceFile; - - /* @internal */ sourceMapper?: DocumentPositionMapper; + update(newText: string, textChangeRange: ts.TextChangeRange): ts.SourceFile; + /* @internal */ sourceMapper?: ts.DocumentPositionMapper; } export interface SourceFileLike { - getLineAndCharacterOfPosition(pos: number): LineAndCharacter; + getLineAndCharacterOfPosition(pos: number): ts.LineAndCharacter; } export interface SourceMapSource { - getLineAndCharacterOfPosition(pos: number): LineAndCharacter; + getLineAndCharacterOfPosition(pos: number): ts.LineAndCharacter; } /** @@ -135,7 +131,7 @@ namespace ts { * change range cannot be determined. However, in that case, incremental parsing will * not happen and the entire document will be re - parsed. */ - getChangeRange(oldSnapshot: IScriptSnapshot): TextChangeRange | undefined; + getChangeRange(oldSnapshot: IScriptSnapshot): ts.TextChangeRange | undefined; /** Releases all resources held by this script snapshot */ dispose?(): void; @@ -157,7 +153,7 @@ namespace ts { return this.text.length; } - public getChangeRange(): TextChangeRange | undefined { + public getChangeRange(): ts.TextChangeRange | undefined { // Text-based snapshots do not support incremental parsing. Return undefined // to signal that to the caller. return undefined; @@ -170,10 +166,10 @@ namespace ts { } export interface PreProcessedFileInfo { - referencedFiles: FileReference[]; - typeReferenceDirectives: FileReference[]; - libReferenceDirectives: FileReference[]; - importedFiles: FileReference[]; + referencedFiles: ts.FileReference[]; + typeReferenceDirectives: ts.FileReference[]; + libReferenceDirectives: ts.FileReference[]; + importedFiles: ts.FileReference[]; ambientExternalModules?: string[]; isLibFile: boolean; } @@ -183,7 +179,7 @@ namespace ts { } export interface InstallPackageOptions { - fileName: Path; + fileName: ts.Path; packageName: string; } @@ -193,17 +189,17 @@ namespace ts { DevDependencies = 1 << 1, PeerDependencies = 1 << 2, OptionalDependencies = 1 << 3, - All = Dependencies | DevDependencies | PeerDependencies | OptionalDependencies, + All = Dependencies | DevDependencies | PeerDependencies | OptionalDependencies } /* @internal */ export interface PackageJsonInfo { fileName: string; parseable: boolean; - dependencies?: ESMap; - devDependencies?: ESMap; - peerDependencies?: ESMap; - optionalDependencies?: ESMap; + dependencies?: ts.ESMap; + devDependencies?: ts.ESMap; + peerDependencies?: ts.ESMap; + optionalDependencies?: ts.ESMap; get(dependencyName: string, inGroups?: PackageJsonDependencyGroup): string | undefined; has(dependencyName: string, inGroups?: PackageJsonDependencyGroup): boolean; } @@ -217,7 +213,7 @@ namespace ts { export const enum PackageJsonAutoImportPreference { Off, On, - Auto, + Auto } export interface PerformanceEvent { @@ -228,7 +224,7 @@ namespace ts { export enum LanguageServiceMode { Semantic, PartialSemantic, - Syntactic, + Syntactic } export interface IncompleteCompletionsCache { @@ -240,19 +236,19 @@ namespace ts { // // Public interface of the host of a language service instance. // - export interface LanguageServiceHost extends GetEffectiveTypeRootsHost, MinimalResolutionCacheHost { - getCompilationSettings(): CompilerOptions; + export interface LanguageServiceHost extends ts.GetEffectiveTypeRootsHost, ts.MinimalResolutionCacheHost { + getCompilationSettings(): ts.CompilerOptions; getNewLine?(): string; getProjectVersion?(): string; getScriptFileNames(): string[]; - getScriptKind?(fileName: string): ScriptKind; + getScriptKind?(fileName: string): ts.ScriptKind; getScriptVersion(fileName: string): string; getScriptSnapshot(fileName: string): IScriptSnapshot | undefined; - getProjectReferences?(): readonly ProjectReference[] | undefined; + getProjectReferences?(): readonly ts.ProjectReference[] | undefined; getLocalizedDiagnosticMessages?(): any; getCancellationToken?(): HostCancellationToken; getCurrentDirectory(): string; - getDefaultLibFileName(options: CompilerOptions): string; + getDefaultLibFileName(options: ts.CompilerOptions): string; log?(s: string): void; trace?(s: string): void; error?(s: string): void; @@ -284,15 +280,15 @@ namespace ts { * * If this is implemented, `getResolvedModuleWithFailedLookupLocationsFromCache` should be too. */ - resolveModuleNames?(moduleNames: string[], containingFile: string, reusedNames: string[] | undefined, redirectedReference: ResolvedProjectReference | undefined, options: CompilerOptions, containingSourceFile?: SourceFile): (ResolvedModule | undefined)[]; - getResolvedModuleWithFailedLookupLocationsFromCache?(modulename: string, containingFile: string, resolutionMode?: ModuleKind.CommonJS | ModuleKind.ESNext): ResolvedModuleWithFailedLookupLocations | undefined; - resolveTypeReferenceDirectives?(typeDirectiveNames: string[] | FileReference[], containingFile: string, redirectedReference: ResolvedProjectReference | undefined, options: CompilerOptions, containingFileMode?: SourceFile["impliedNodeFormat"] | undefined): (ResolvedTypeReferenceDirective | undefined)[]; - /* @internal */ hasInvalidatedResolution?: HasInvalidatedResolution; - /* @internal */ hasChangedAutomaticTypeDirectiveNames?: HasChangedAutomaticTypeDirectiveNames; + resolveModuleNames?(moduleNames: string[], containingFile: string, reusedNames: string[] | undefined, redirectedReference: ts.ResolvedProjectReference | undefined, options: ts.CompilerOptions, containingSourceFile?: ts.SourceFile): (ts.ResolvedModule | undefined)[]; + getResolvedModuleWithFailedLookupLocationsFromCache?(modulename: string, containingFile: string, resolutionMode?: ts.ModuleKind.CommonJS | ts.ModuleKind.ESNext): ts.ResolvedModuleWithFailedLookupLocations | undefined; + resolveTypeReferenceDirectives?(typeDirectiveNames: string[] | ts.FileReference[], containingFile: string, redirectedReference: ts.ResolvedProjectReference | undefined, options: ts.CompilerOptions, containingFileMode?: ts.SourceFile["impliedNodeFormat"] | undefined): (ts.ResolvedTypeReferenceDirective | undefined)[]; + /* @internal */ hasInvalidatedResolution?: ts.HasInvalidatedResolution; + /* @internal */ hasChangedAutomaticTypeDirectiveNames?: ts.HasChangedAutomaticTypeDirectiveNames; /* @internal */ getGlobalTypingsCacheLocation?(): string | undefined; - /* @internal */ getSymlinkCache?(files?: readonly SourceFile[]): SymlinkCache; + /* @internal */ getSymlinkCache?(files?: readonly ts.SourceFile[]): ts.SymlinkCache; /* Lets the Program from a AutoImportProviderProject use its host project's ModuleResolutionCache */ - /* @internal */ getModuleResolutionCache?(): ModuleResolutionCache | undefined; + /* @internal */ getModuleResolutionCache?(): ts.ModuleResolutionCache | undefined; /* * Required for full import and type reference completions. @@ -303,32 +299,34 @@ namespace ts { /** * Gets a set of custom transformers to use during emit. */ - getCustomTransformers?(): CustomTransformers | undefined; + getCustomTransformers?(): ts.CustomTransformers | undefined; isKnownTypesPackageName?(name: string): boolean; installPackage?(options: InstallPackageOptions): Promise; writeFile?(fileName: string, content: string): void; - /* @internal */ getDocumentPositionMapper?(generatedFileName: string, sourceFileName?: string): DocumentPositionMapper | undefined; - /* @internal */ getSourceFileLike?(fileName: string): SourceFileLike | undefined; + /* @internal */ getDocumentPositionMapper?(generatedFileName: string, sourceFileName?: string): ts.DocumentPositionMapper | undefined; + /* @internal */ getSourceFileLike?(fileName: string): ts.SourceFileLike | undefined; /* @internal */ getPackageJsonsVisibleToFile?(fileName: string, rootDir?: string): readonly PackageJsonInfo[]; /* @internal */ getNearestAncestorDirectoryWithPackageJson?(fileName: string): string | undefined; /* @internal */ getPackageJsonsForAutoImport?(rootDir?: string): readonly PackageJsonInfo[]; - /* @internal */ getCachedExportInfoMap?(): ExportInfoMap; - /* @internal */ getModuleSpecifierCache?(): ModuleSpecifierCache; - /* @internal */ setCompilerHost?(host: CompilerHost): void; + /* @internal */ getCachedExportInfoMap?(): ts.ExportInfoMap; + /* @internal */ getModuleSpecifierCache?(): ts.ModuleSpecifierCache; + /* @internal */ setCompilerHost?(host: ts.CompilerHost): void; /* @internal */ useSourceOfProjectReferenceRedirect?(): boolean; - /* @internal */ getPackageJsonAutoImportProvider?(): Program | undefined; + /* @internal */ getPackageJsonAutoImportProvider?(): ts.Program | undefined; /* @internal */ sendPerformanceEvent?(kind: PerformanceEvent["kind"], durationMs: number): void; - getParsedCommandLine?(fileName: string): ParsedCommandLine | undefined; - /* @internal */ onReleaseParsedCommandLine?(configFileName: string, oldResolvedRef: ResolvedProjectReference | undefined, optionOptions: CompilerOptions): void; + getParsedCommandLine?(fileName: string): ts.ParsedCommandLine | undefined; + /* @internal */ onReleaseParsedCommandLine?(configFileName: string, oldResolvedRef: ts.ResolvedProjectReference | undefined, optionOptions: ts.CompilerOptions): void; /* @internal */ getIncompleteCompletionsCache?(): IncompleteCompletionsCache; } /* @internal */ export const emptyOptions = {}; - export type WithMetadata = T & { metadata?: unknown; }; + export type WithMetadata = T & { + metadata?: unknown; + }; export const enum SemanticClassificationFormat { Original = "original", @@ -360,7 +358,7 @@ namespace ts { * * @param fileName A path to the file you want syntactic diagnostics for */ - getSyntacticDiagnostics(fileName: string): DiagnosticWithLocation[]; + getSyntacticDiagnostics(fileName: string): ts.DiagnosticWithLocation[]; /** * Gets warnings or errors indicating type system issues in a given file. @@ -377,7 +375,7 @@ namespace ts { * * @param fileName A path to the file you want semantic diagnostics for */ - getSemanticDiagnostics(fileName: string): Diagnostic[]; + getSemanticDiagnostics(fileName: string): ts.Diagnostic[]; /** * Gets suggestion diagnostics for a specific file. These diagnostics tend to @@ -386,7 +384,7 @@ namespace ts { * * @param fileName A path to the file you want semantic diagnostics for */ - getSuggestionDiagnostics(fileName: string): DiagnosticWithLocation[]; + getSuggestionDiagnostics(fileName: string): ts.DiagnosticWithLocation[]; // TODO: Rename this to getProgramDiagnostics to better indicate that these are any // diagnostics present for the program level, and not just 'options' diagnostics. @@ -394,18 +392,18 @@ namespace ts { /** * Gets global diagnostics related to the program configuration and compiler options. */ - getCompilerOptionsDiagnostics(): Diagnostic[]; + getCompilerOptionsDiagnostics(): ts.Diagnostic[]; /** @deprecated Use getEncodedSyntacticClassifications instead. */ - getSyntacticClassifications(fileName: string, span: TextSpan): ClassifiedSpan[]; - getSyntacticClassifications(fileName: string, span: TextSpan, format: SemanticClassificationFormat): ClassifiedSpan[] | ClassifiedSpan2020[]; + getSyntacticClassifications(fileName: string, span: ts.TextSpan): ClassifiedSpan[]; + getSyntacticClassifications(fileName: string, span: ts.TextSpan, format: SemanticClassificationFormat): ClassifiedSpan[] | ClassifiedSpan2020[]; /** @deprecated Use getEncodedSemanticClassifications instead. */ - getSemanticClassifications(fileName: string, span: TextSpan): ClassifiedSpan[]; - getSemanticClassifications(fileName: string, span: TextSpan, format: SemanticClassificationFormat): ClassifiedSpan[] | ClassifiedSpan2020[]; + getSemanticClassifications(fileName: string, span: ts.TextSpan): ClassifiedSpan[]; + getSemanticClassifications(fileName: string, span: ts.TextSpan, format: SemanticClassificationFormat): ClassifiedSpan[] | ClassifiedSpan2020[]; /** Encoded as triples of [start, length, ClassificationType]. */ - getEncodedSyntacticClassifications(fileName: string, span: TextSpan): Classifications; + getEncodedSyntacticClassifications(fileName: string, span: ts.TextSpan): Classifications; /** * Gets semantic highlights information for a particular file. Has two formats, an older @@ -416,7 +414,7 @@ namespace ts { * @param format Which format to use, defaults to "original" * @returns a number array encoded as triples of [start, length, ClassificationType, ...]. */ - getEncodedSemanticClassifications(fileName: string, span: TextSpan, format?: SemanticClassificationFormat): Classifications; + getEncodedSemanticClassifications(fileName: string, span: ts.TextSpan, format?: SemanticClassificationFormat): Classifications; /** * Gets completion entries at a particular position in a file. @@ -440,17 +438,8 @@ namespace ts { * @param preferences User settings, can be undefined for backwards compatibility * @param data `data` property from the completion entry */ - getCompletionEntryDetails( - fileName: string, - position: number, - entryName: string, - formatOptions: FormatCodeOptions | FormatCodeSettings | undefined, - source: string | undefined, - preferences: UserPreferences | undefined, - data: CompletionEntryData | undefined, - ): CompletionEntryDetails | undefined; - - getCompletionEntrySymbol(fileName: string, position: number, name: string, source: string | undefined): Symbol | undefined; + getCompletionEntryDetails(fileName: string, position: number, entryName: string, formatOptions: FormatCodeOptions | FormatCodeSettings | undefined, source: string | undefined, preferences: ts.UserPreferences | undefined, data: CompletionEntryData | undefined): CompletionEntryDetails | undefined; + getCompletionEntrySymbol(fileName: string, position: number, name: string, source: string | undefined): ts.Symbol | undefined; /** * Gets semantic information about the identifier at a particular position in a @@ -461,9 +450,8 @@ namespace ts { */ getQuickInfoAtPosition(fileName: string, position: number): QuickInfo | undefined; - getNameOrDottedNameSpan(fileName: string, startPos: number, endPos: number): TextSpan | undefined; - - getBreakpointStatementAtPosition(fileName: string, position: number): TextSpan | undefined; + getNameOrDottedNameSpan(fileName: string, startPos: number, endPos: number): ts.TextSpan | undefined; + getBreakpointStatementAtPosition(fileName: string, position: number): ts.TextSpan | undefined; getSignatureHelpItems(fileName: string, position: number, options: SignatureHelpItemsOptions | undefined): SignatureHelpItems | undefined; @@ -485,7 +473,7 @@ namespace ts { getReferencesAtPosition(fileName: string, position: number): ReferenceEntry[] | undefined; findReferences(fileName: string, position: number): ReferencedSymbol[] | undefined; - getDocumentHighlights(fileName: string, position: number, filesToSearch: string[]): DocumentHighlights[] | undefined; + getDocumentHighlights(fileName: string, position: number, filesToSearch: string[]): ts.DocumentHighlights[] | undefined; getFileReferences(fileName: string): ReferenceEntry[]; /** @deprecated */ @@ -499,11 +487,11 @@ namespace ts { provideCallHierarchyIncomingCalls(fileName: string, position: number): CallHierarchyIncomingCall[]; provideCallHierarchyOutgoingCalls(fileName: string, position: number): CallHierarchyOutgoingCall[]; - provideInlayHints(fileName: string, span: TextSpan, preferences: UserPreferences | undefined): InlayHint[] + provideInlayHints(fileName: string, span: ts.TextSpan, preferences: ts.UserPreferences | undefined): InlayHint[]; getOutliningSpans(fileName: string): OutliningSpan[]; getTodoComments(fileName: string, descriptors: TodoCommentDescriptor[]): TodoComment[]; - getBraceMatchingAtPosition(fileName: string, position: number): TextSpan[]; + getBraceMatchingAtPosition(fileName: string, position: number): ts.TextSpan[]; getIndentationAtPosition(fileName: string, position: number, options: EditorOptions | EditorSettings): number; getFormattingEditsForRange(fileName: string, start: number, end: number, options: FormatCodeOptions | FormatCodeSettings): TextChange[]; @@ -519,16 +507,15 @@ namespace ts { */ getJsxClosingTagAtPosition(fileName: string, position: number): JsxClosingTagInfo | undefined; - getSpanOfEnclosingComment(fileName: string, position: number, onlyMultiLine: boolean): TextSpan | undefined; - - toLineColumnOffset?(fileName: string, position: number): LineAndCharacter; + getSpanOfEnclosingComment(fileName: string, position: number, onlyMultiLine: boolean): ts.TextSpan | undefined; + toLineColumnOffset?(fileName: string, position: number): ts.LineAndCharacter; /** @internal */ - getSourceMapper(): SourceMapper; + getSourceMapper(): ts.SourceMapper; /** @internal */ clearSourceMapperCache(): void; - getCodeFixesAtPosition(fileName: string, start: number, end: number, errorCodes: readonly number[], formatOptions: FormatCodeSettings, preferences: UserPreferences): readonly CodeFixAction[]; - getCombinedCodeFix(scope: CombinedCodeFixScope, fixId: {}, formatOptions: FormatCodeSettings, preferences: UserPreferences): CombinedCodeActions; + getCodeFixesAtPosition(fileName: string, start: number, end: number, errorCodes: readonly number[], formatOptions: FormatCodeSettings, preferences: ts.UserPreferences): readonly CodeFixAction[]; + getCombinedCodeFix(scope: CombinedCodeFixScope, fixId: {}, formatOptions: FormatCodeSettings, preferences: ts.UserPreferences): CombinedCodeActions; applyCodeActionCommand(action: CodeActionCommand, formatSettings?: FormatCodeSettings): Promise; applyCodeActionCommand(action: CodeActionCommand[], formatSettings?: FormatCodeSettings): Promise; @@ -540,22 +527,18 @@ namespace ts { /** @deprecated `fileName` will be ignored */ applyCodeActionCommand(fileName: string, action: CodeActionCommand | CodeActionCommand[]): Promise; - getApplicableRefactors(fileName: string, positionOrRange: number | TextRange, preferences: UserPreferences | undefined, triggerReason?: RefactorTriggerReason, kind?: string): ApplicableRefactorInfo[]; - getEditsForRefactor(fileName: string, formatOptions: FormatCodeSettings, positionOrRange: number | TextRange, refactorName: string, actionName: string, preferences: UserPreferences | undefined): RefactorEditInfo | undefined; - organizeImports(args: OrganizeImportsArgs, formatOptions: FormatCodeSettings, preferences: UserPreferences | undefined): readonly FileTextChanges[]; - getEditsForFileRename(oldFilePath: string, newFilePath: string, formatOptions: FormatCodeSettings, preferences: UserPreferences | undefined): readonly FileTextChanges[]; - - getEmitOutput(fileName: string, emitOnlyDtsFiles?: boolean, forceDtsEmit?: boolean): EmitOutput; - - getProgram(): Program | undefined; - - /* @internal */ getNonBoundSourceFile(fileName: string): SourceFile; - /* @internal */ getAutoImportProvider(): Program | undefined; - - toggleLineComment(fileName: string, textRange: TextRange): TextChange[]; - toggleMultilineComment(fileName: string, textRange: TextRange): TextChange[]; - commentSelection(fileName: string, textRange: TextRange): TextChange[]; - uncommentSelection(fileName: string, textRange: TextRange): TextChange[]; + getApplicableRefactors(fileName: string, positionOrRange: number | ts.TextRange, preferences: ts.UserPreferences | undefined, triggerReason?: RefactorTriggerReason, kind?: string): ApplicableRefactorInfo[]; + getEditsForRefactor(fileName: string, formatOptions: FormatCodeSettings, positionOrRange: number | ts.TextRange, refactorName: string, actionName: string, preferences: ts.UserPreferences | undefined): RefactorEditInfo | undefined; + organizeImports(args: OrganizeImportsArgs, formatOptions: FormatCodeSettings, preferences: ts.UserPreferences | undefined): readonly FileTextChanges[]; + getEditsForFileRename(oldFilePath: string, newFilePath: string, formatOptions: FormatCodeSettings, preferences: ts.UserPreferences | undefined): readonly FileTextChanges[]; + getEmitOutput(fileName: string, emitOnlyDtsFiles?: boolean, forceDtsEmit?: boolean): ts.EmitOutput; + getProgram(): ts.Program | undefined; + /* @internal */ getNonBoundSourceFile(fileName: string): ts.SourceFile; + /* @internal */ getAutoImportProvider(): ts.Program | undefined; + toggleLineComment(fileName: string, textRange: ts.TextRange): TextChange[]; + toggleMultilineComment(fileName: string, textRange: ts.TextRange): TextChange[]; + commentSelection(fileName: string, textRange: ts.TextRange): TextChange[]; + uncommentSelection(fileName: string, textRange: ts.TextRange): TextChange[]; dispose(): void; } @@ -564,7 +547,10 @@ namespace ts { readonly newText: string; } - export interface CombinedCodeFixScope { type: "file"; fileName: string; } + export interface CombinedCodeFixScope { + type: "file"; + fileName: string; + } export interface OrganizeImportsArgs extends CombinedCodeFixScope { skipDestructiveCodeActions?: boolean; @@ -580,10 +566,10 @@ namespace ts { TriggerCharacter = 2, /** Completion was re-triggered as the current completion list is incomplete. */ - TriggerForIncompleteCompletions = 3, + TriggerForIncompleteCompletions = 3 } - export interface GetCompletionsAtPositionOptions extends UserPreferences { + export interface GetCompletionsAtPositionOptions extends ts.UserPreferences { /** * If the editor is asking for completions because a certain character was typed * (as opposed to when the user explicitly requested them) this should be set. @@ -603,10 +589,7 @@ namespace ts { triggerReason?: SignatureHelpTriggerReason; } - export type SignatureHelpTriggerReason = - | SignatureHelpInvokedReason - | SignatureHelpCharacterTypedReason - | SignatureHelpRetriggeredReason; + export type SignatureHelpTriggerReason = SignatureHelpInvokedReason | SignatureHelpCharacterTypedReason | SignatureHelpRetriggeredReason; /** * Signals that the user manually requested signature help. @@ -653,12 +636,12 @@ namespace ts { } export interface ClassifiedSpan { - textSpan: TextSpan; + textSpan: ts.TextSpan; classificationType: ClassificationTypeNames; } export interface ClassifiedSpan2020 { - textSpan: TextSpan; + textSpan: ts.TextSpan; classificationType: number; } @@ -672,7 +655,7 @@ namespace ts { text: string; kind: ScriptElementKind; kindModifiers: string; - spans: TextSpan[]; + spans: ts.TextSpan[]; childItems: NavigationBarItem[]; indent: number; bolded: boolean; @@ -693,8 +676,8 @@ namespace ts { * Spans of the nodes that generated this declaration. * There will be more than one if this is the result of merging. */ - spans: TextSpan[]; - nameSpan: TextSpan | undefined; + spans: ts.TextSpan[]; + nameSpan: ts.TextSpan | undefined; /** Present if non-empty */ childItems?: NavigationTree[]; } @@ -704,25 +687,25 @@ namespace ts { kind: ScriptElementKind; kindModifiers?: string; file: string; - span: TextSpan; - selectionSpan: TextSpan; + span: ts.TextSpan; + selectionSpan: ts.TextSpan; containerName?: string; } export interface CallHierarchyIncomingCall { from: CallHierarchyItem; - fromSpans: TextSpan[]; + fromSpans: ts.TextSpan[]; } export interface CallHierarchyOutgoingCall { to: CallHierarchyItem; - fromSpans: TextSpan[]; + fromSpans: ts.TextSpan[]; } export const enum InlayHintKind { Type = "Type", Parameter = "Parameter", - Enum = "Enum", + Enum = "Enum" } export interface InlayHint { @@ -745,7 +728,7 @@ namespace ts { } export interface TextChange { - span: TextSpan; + span: ts.TextSpan; newText: string; } @@ -867,22 +850,22 @@ namespace ts { } export interface DocumentSpan { - textSpan: TextSpan; + textSpan: ts.TextSpan; fileName: string; /** * If the span represents a location that was remapped (e.g. via a .d.ts.map file), * then the original filename and span will be specified here */ - originalTextSpan?: TextSpan; + originalTextSpan?: ts.TextSpan; originalFileName?: string; /** * If DocumentSpan.textSpan is the span for name of the declaration, * then this is the span for relevant declaration */ - contextSpan?: TextSpan; - originalContextSpan?: TextSpan; + contextSpan?: ts.TextSpan; + originalContextSpan?: ts.TextSpan; } export interface RenameLocation extends DocumentSpan { @@ -904,14 +887,14 @@ namespace ts { none = "none", definition = "definition", reference = "reference", - writtenReference = "writtenReference", + writtenReference = "writtenReference" } export interface HighlightSpan { fileName?: string; isInString?: true; - textSpan: TextSpan; - contextSpan?: TextSpan; + textSpan: ts.TextSpan; + contextSpan?: ts.TextSpan; kind: HighlightSpanKind; } @@ -922,7 +905,7 @@ namespace ts { matchKind: "exact" | "prefix" | "substring" | "camelCase"; isCaseSensitive: boolean; fileName: string; - textSpan: TextSpan; + textSpan: ts.TextSpan; containerName: string; containerKind: ScriptElementKind; } @@ -930,13 +913,13 @@ namespace ts { export enum IndentStyle { None = 0, Block = 1, - Smart = 2, + Smart = 2 } export enum SemicolonPreference { Ignore = "ignore", Insert = "insert", - Remove = "remove", + Remove = "remove" } /* @deprecated - consider using EditorSettings instead */ @@ -1044,7 +1027,7 @@ namespace ts { export interface DefinitionInfoAndBoundSpan { definitions?: readonly DefinitionInfo[]; - textSpan: TextSpan; + textSpan: ts.TextSpan; } export interface ReferencedSymbolDefinitionInfo extends DefinitionInfo { @@ -1085,7 +1068,7 @@ namespace ts { regularExpressionLiteral, link, linkName, - linkText, + linkText } export interface SymbolDisplayPart { @@ -1105,7 +1088,7 @@ namespace ts { export interface QuickInfo { kind: ScriptElementKind; kindModifiers: string; - textSpan: TextSpan; + textSpan: ts.TextSpan; displayParts?: SymbolDisplayPart[]; documentation?: SymbolDisplayPart[]; tags?: JSDocTagInfo[]; @@ -1123,7 +1106,7 @@ namespace ts { fullDisplayName: string; kind: ScriptElementKind; kindModifiers: string; - triggerSpan: TextSpan; + triggerSpan: ts.TextSpan; } export interface RenameInfoFailure { canRename: false; @@ -1147,7 +1130,7 @@ namespace ts { } export interface SelectionRange { - textSpan: TextSpan; + textSpan: ts.TextSpan; parent?: SelectionRange; } @@ -1173,7 +1156,7 @@ namespace ts { */ export interface SignatureHelpItems { items: SignatureHelpItem[]; - applicableSpan: TextSpan; + applicableSpan: ts.TextSpan; selectedItemIndex: number; argumentIndex: number; argumentCount: number; @@ -1187,7 +1170,7 @@ namespace ts { IsContinuation = 1 << 2, ResolvedModuleSpecifiers = 1 << 3, ResolvedModuleSpecifiersBeyondLimit = 1 << 4, - MayIncludeMethodSnippets = 1 << 5, + MayIncludeMethodSnippets = 1 << 5 } export interface CompletionInfo { @@ -1201,7 +1184,7 @@ namespace ts { * this span or its default one. If `CompletionEntry["replacementSpan"]` is defined, that span * must be used to commit that completion entry. */ - optionalReplacementSpan?: TextSpan; + optionalReplacementSpan?: ts.TextSpan; /** * true when the current location also allows for a new identifier */ @@ -1252,7 +1235,7 @@ namespace ts { * If present, this span should be used instead of the default one. * It will be set if the required span differs from the one generated by the default replacement behavior. */ - replacementSpan?: TextSpan; + replacementSpan?: ts.TextSpan; hasAction?: true; source?: string; sourceDisplay?: SymbolDisplayPart[]; @@ -1292,10 +1275,10 @@ namespace ts { export interface OutliningSpan { /** The span of the document to actually collapse. */ - textSpan: TextSpan; + textSpan: ts.TextSpan; /** The span of the document to display when the user hovers over the collapsed span. */ - hintSpan: TextSpan; + hintSpan: ts.TextSpan; /** The text to display in the editor for the collapsed region. */ bannerText: string; @@ -1339,7 +1322,7 @@ namespace ts { InDoubleQuoteStringLiteral, InTemplateHeadOrNoSubstitutionTemplate, InTemplateMiddleOrTail, - InTemplateSubstitutionPosition, + InTemplateSubstitutionPosition } export enum TokenClass { @@ -1352,7 +1335,7 @@ namespace ts { NumberLiteral, BigIntLiteral, StringLiteral, - RegExpLiteral, + RegExpLiteral } export interface ClassificationResult { @@ -1500,7 +1483,7 @@ namespace ts { linkName = "link name", /** Jsdoc @link: in `{@link C link text}`, the link text "link text" */ - linkText = "link text", + linkText = "link text" } export const enum ScriptElementKindModifier { @@ -1527,7 +1510,7 @@ namespace ts { mjsModifier = ".mjs", dctsModifier = ".d.cts", ctsModifier = ".cts", - cjsModifier = ".cjs", + cjsModifier = ".cjs" } export const enum ClassificationTypeNames { @@ -1556,7 +1539,7 @@ namespace ts { jsxSelfClosingTagName = "jsx self closing tag name", jsxAttribute = "jsx attribute", jsxText = "jsx text", - jsxAttributeStringLiteralValue = "jsx attribute string literal value", + jsxAttributeStringLiteralValue = "jsx attribute string literal value" } export const enum ClassificationType { @@ -1584,7 +1567,7 @@ namespace ts { jsxAttribute = 22, jsxText = 23, jsxAttributeStringLiteralValue = 24, - bigintLiteral = 25, + bigintLiteral = 25 } /** @internal */ @@ -1596,11 +1579,11 @@ namespace ts { } /** @internal */ - export interface CodeFixContextBase extends textChanges.TextChangesContext { - sourceFile: SourceFile; - program: Program; - cancellationToken: CancellationToken; - preferences: UserPreferences; + export interface CodeFixContextBase extends ts.textChanges.TextChangesContext { + sourceFile: ts.SourceFile; + program: ts.Program; + cancellationToken: ts.CancellationToken; + preferences: ts.UserPreferences; } /** @internal */ @@ -1611,7 +1594,7 @@ namespace ts { /** @internal */ export interface CodeFixContext extends CodeFixContextBase { errorCode: number; - span: TextSpan; + span: ts.TextSpan; } /** @internal */ @@ -1628,23 +1611,23 @@ namespace ts { } /** @internal */ - export interface RefactorContext extends textChanges.TextChangesContext { - file: SourceFile; + export interface RefactorContext extends ts.textChanges.TextChangesContext { + file: ts.SourceFile; startPosition: number; endPosition?: number; - program: Program; - cancellationToken?: CancellationToken; - preferences: UserPreferences; + program: ts.Program; + cancellationToken?: ts.CancellationToken; + preferences: ts.UserPreferences; triggerReason?: RefactorTriggerReason; kind?: string; } export interface InlayHintsContext { - file: SourceFile; - program: Program; - cancellationToken: CancellationToken; + file: ts.SourceFile; + program: ts.Program; + cancellationToken: ts.CancellationToken; host: LanguageServiceHost; - span: TextSpan; - preferences: UserPreferences; + span: ts.TextSpan; + preferences: ts.UserPreferences; } } diff --git a/src/services/utilities.ts b/src/services/utilities.ts index 60aa2c7d1945e..688d643de8dc5 100644 --- a/src/services/utilities.ts +++ b/src/services/utilities.ts @@ -12,7 +12,7 @@ declare var Promise: PromiseConstructor; // eslint-disable-line no-var namespace ts { // These utilities are common to multiple language service features. //#region - export const scanner: Scanner = createScanner(ScriptTarget.Latest, /*skipTrivia*/ true); + export const scanner: ts.Scanner = ts.createScanner(ts.ScriptTarget.Latest, /*skipTrivia*/ true); export const enum SemanticMeaning { None = 0x0, @@ -22,92 +22,90 @@ namespace ts { All = Value | Type | Namespace } - export function getMeaningFromDeclaration(node: Node): SemanticMeaning { + export function getMeaningFromDeclaration(node: ts.Node): SemanticMeaning { switch (node.kind) { - case SyntaxKind.VariableDeclaration: - return isInJSFile(node) && getJSDocEnumTag(node) ? SemanticMeaning.All : SemanticMeaning.Value; - - case SyntaxKind.Parameter: - case SyntaxKind.BindingElement: - case SyntaxKind.PropertyDeclaration: - case SyntaxKind.PropertySignature: - case SyntaxKind.PropertyAssignment: - case SyntaxKind.ShorthandPropertyAssignment: - case SyntaxKind.MethodDeclaration: - case SyntaxKind.MethodSignature: - case SyntaxKind.Constructor: - case SyntaxKind.GetAccessor: - case SyntaxKind.SetAccessor: - case SyntaxKind.FunctionDeclaration: - case SyntaxKind.FunctionExpression: - case SyntaxKind.ArrowFunction: - case SyntaxKind.CatchClause: - case SyntaxKind.JsxAttribute: + case ts.SyntaxKind.VariableDeclaration: + return ts.isInJSFile(node) && ts.getJSDocEnumTag(node) ? SemanticMeaning.All : SemanticMeaning.Value; + case ts.SyntaxKind.Parameter: + case ts.SyntaxKind.BindingElement: + case ts.SyntaxKind.PropertyDeclaration: + case ts.SyntaxKind.PropertySignature: + case ts.SyntaxKind.PropertyAssignment: + case ts.SyntaxKind.ShorthandPropertyAssignment: + case ts.SyntaxKind.MethodDeclaration: + case ts.SyntaxKind.MethodSignature: + case ts.SyntaxKind.Constructor: + case ts.SyntaxKind.GetAccessor: + case ts.SyntaxKind.SetAccessor: + case ts.SyntaxKind.FunctionDeclaration: + case ts.SyntaxKind.FunctionExpression: + case ts.SyntaxKind.ArrowFunction: + case ts.SyntaxKind.CatchClause: + case ts.SyntaxKind.JsxAttribute: return SemanticMeaning.Value; - case SyntaxKind.TypeParameter: - case SyntaxKind.InterfaceDeclaration: - case SyntaxKind.TypeAliasDeclaration: - case SyntaxKind.TypeLiteral: + case ts.SyntaxKind.TypeParameter: + case ts.SyntaxKind.InterfaceDeclaration: + case ts.SyntaxKind.TypeAliasDeclaration: + case ts.SyntaxKind.TypeLiteral: return SemanticMeaning.Type; - case SyntaxKind.JSDocTypedefTag: + case ts.SyntaxKind.JSDocTypedefTag: // If it has no name node, it shares the name with the value declaration below it. - return (node as JSDocTypedefTag).name === undefined ? SemanticMeaning.Value | SemanticMeaning.Type : SemanticMeaning.Type; - - case SyntaxKind.EnumMember: - case SyntaxKind.ClassDeclaration: + return (node as ts.JSDocTypedefTag).name === undefined ? SemanticMeaning.Value | SemanticMeaning.Type : SemanticMeaning.Type; + case ts.SyntaxKind.EnumMember: + case ts.SyntaxKind.ClassDeclaration: return SemanticMeaning.Value | SemanticMeaning.Type; - case SyntaxKind.ModuleDeclaration: - if (isAmbientModule(node as ModuleDeclaration)) { + case ts.SyntaxKind.ModuleDeclaration: + if (ts.isAmbientModule(node as ts.ModuleDeclaration)) { return SemanticMeaning.Namespace | SemanticMeaning.Value; } - else if (getModuleInstanceState(node as ModuleDeclaration) === ModuleInstanceState.Instantiated) { + else if (ts.getModuleInstanceState(node as ts.ModuleDeclaration) === ts.ModuleInstanceState.Instantiated) { return SemanticMeaning.Namespace | SemanticMeaning.Value; } else { return SemanticMeaning.Namespace; } - case SyntaxKind.EnumDeclaration: - case SyntaxKind.NamedImports: - case SyntaxKind.ImportSpecifier: - case SyntaxKind.ImportEqualsDeclaration: - case SyntaxKind.ImportDeclaration: - case SyntaxKind.ExportAssignment: - case SyntaxKind.ExportDeclaration: + case ts.SyntaxKind.EnumDeclaration: + case ts.SyntaxKind.NamedImports: + case ts.SyntaxKind.ImportSpecifier: + case ts.SyntaxKind.ImportEqualsDeclaration: + case ts.SyntaxKind.ImportDeclaration: + case ts.SyntaxKind.ExportAssignment: + case ts.SyntaxKind.ExportDeclaration: return SemanticMeaning.All; // An external module can be a Value - case SyntaxKind.SourceFile: + case ts.SyntaxKind.SourceFile: return SemanticMeaning.Namespace | SemanticMeaning.Value; } return SemanticMeaning.All; } - export function getMeaningFromLocation(node: Node): SemanticMeaning { + export function getMeaningFromLocation(node: ts.Node): SemanticMeaning { node = getAdjustedReferenceLocation(node); const parent = node.parent; - if (node.kind === SyntaxKind.SourceFile) { + if (node.kind === ts.SyntaxKind.SourceFile) { return SemanticMeaning.Value; } - else if (isExportAssignment(parent) - || isExportSpecifier(parent) - || isExternalModuleReference(parent) - || isImportSpecifier(parent) - || isImportClause(parent) - || isImportEqualsDeclaration(parent) && node === parent.name) { + else if (ts.isExportAssignment(parent) + || ts.isExportSpecifier(parent) + || ts.isExternalModuleReference(parent) + || ts.isImportSpecifier(parent) + || ts.isImportClause(parent) + || ts.isImportEqualsDeclaration(parent) && node === parent.name) { return SemanticMeaning.All; } else if (isInRightSideOfInternalImportEqualsDeclaration(node)) { - return getMeaningFromRightHandSideOfImportEquals(node as Identifier); + return getMeaningFromRightHandSideOfImportEquals(node as ts.Identifier); } - else if (isDeclarationName(node)) { + else if (ts.isDeclarationName(node)) { return getMeaningFromDeclaration(parent); } - else if (isEntityName(node) && findAncestor(node, or(isJSDocNameReference, isJSDocLinkLike, isJSDocMemberName))) { + else if (ts.isEntityName(node) && ts.findAncestor(node, ts.or(ts.isJSDocNameReference, ts.isJSDocLinkLike, ts.isJSDocMemberName))) { return SemanticMeaning.All; } else if (isTypeReference(node)) { @@ -116,11 +114,11 @@ namespace ts { else if (isNamespaceReference(node)) { return SemanticMeaning.Namespace; } - else if (isTypeParameterDeclaration(parent)) { - Debug.assert(isJSDocTemplateTag(parent.parent)); // Else would be handled by isDeclarationName + else if (ts.isTypeParameterDeclaration(parent)) { + ts.Debug.assert(ts.isJSDocTemplateTag(parent.parent)); // Else would be handled by isDeclarationName return SemanticMeaning.Type; } - else if (isLiteralTypeNode(parent)) { + else if (ts.isLiteralTypeNode(parent)) { // This might be T["name"], which is actually referencing a property and not a type. So allow both meanings. return SemanticMeaning.Type | SemanticMeaning.Value; } @@ -129,219 +127,221 @@ namespace ts { } } - function getMeaningFromRightHandSideOfImportEquals(node: Node): SemanticMeaning { + function getMeaningFromRightHandSideOfImportEquals(node: ts.Node): SemanticMeaning { // import a = |b|; // Namespace // import a = |b.c|; // Value, type, namespace // import a = |b.c|.d; // Namespace - const name = node.kind === SyntaxKind.QualifiedName ? node : isQualifiedName(node.parent) && node.parent.right === node ? node.parent : undefined; - return name && name.parent.kind === SyntaxKind.ImportEqualsDeclaration ? SemanticMeaning.All : SemanticMeaning.Namespace; + const name = node.kind === ts.SyntaxKind.QualifiedName ? node : ts.isQualifiedName(node.parent) && node.parent.right === node ? node.parent : undefined; + return name && name.parent.kind === ts.SyntaxKind.ImportEqualsDeclaration ? SemanticMeaning.All : SemanticMeaning.Namespace; } - export function isInRightSideOfInternalImportEqualsDeclaration(node: Node) { - while (node.parent.kind === SyntaxKind.QualifiedName) { + export function isInRightSideOfInternalImportEqualsDeclaration(node: ts.Node) { + while (node.parent.kind === ts.SyntaxKind.QualifiedName) { node = node.parent; } - return isInternalModuleImportEqualsDeclaration(node.parent) && node.parent.moduleReference === node; + return ts.isInternalModuleImportEqualsDeclaration(node.parent) && node.parent.moduleReference === node; } - function isNamespaceReference(node: Node): boolean { + function isNamespaceReference(node: ts.Node): boolean { return isQualifiedNameNamespaceReference(node) || isPropertyAccessNamespaceReference(node); } - function isQualifiedNameNamespaceReference(node: Node): boolean { + function isQualifiedNameNamespaceReference(node: ts.Node): boolean { let root = node; let isLastClause = true; - if (root.parent.kind === SyntaxKind.QualifiedName) { - while (root.parent && root.parent.kind === SyntaxKind.QualifiedName) { + if (root.parent.kind === ts.SyntaxKind.QualifiedName) { + while (root.parent && root.parent.kind === ts.SyntaxKind.QualifiedName) { root = root.parent; } - isLastClause = (root as QualifiedName).right === node; + isLastClause = (root as ts.QualifiedName).right === node; } - return root.parent.kind === SyntaxKind.TypeReference && !isLastClause; + return root.parent.kind === ts.SyntaxKind.TypeReference && !isLastClause; } - function isPropertyAccessNamespaceReference(node: Node): boolean { + function isPropertyAccessNamespaceReference(node: ts.Node): boolean { let root = node; let isLastClause = true; - if (root.parent.kind === SyntaxKind.PropertyAccessExpression) { - while (root.parent && root.parent.kind === SyntaxKind.PropertyAccessExpression) { + if (root.parent.kind === ts.SyntaxKind.PropertyAccessExpression) { + while (root.parent && root.parent.kind === ts.SyntaxKind.PropertyAccessExpression) { root = root.parent; } - isLastClause = (root as PropertyAccessExpression).name === node; + isLastClause = (root as ts.PropertyAccessExpression).name === node; } - if (!isLastClause && root.parent.kind === SyntaxKind.ExpressionWithTypeArguments && root.parent.parent.kind === SyntaxKind.HeritageClause) { + if (!isLastClause && root.parent.kind === ts.SyntaxKind.ExpressionWithTypeArguments && root.parent.parent.kind === ts.SyntaxKind.HeritageClause) { const decl = root.parent.parent.parent; - return (decl.kind === SyntaxKind.ClassDeclaration && (root.parent.parent as HeritageClause).token === SyntaxKind.ImplementsKeyword) || - (decl.kind === SyntaxKind.InterfaceDeclaration && (root.parent.parent as HeritageClause).token === SyntaxKind.ExtendsKeyword); + return (decl.kind === ts.SyntaxKind.ClassDeclaration && (root.parent.parent as ts.HeritageClause).token === ts.SyntaxKind.ImplementsKeyword) || + (decl.kind === ts.SyntaxKind.InterfaceDeclaration && (root.parent.parent as ts.HeritageClause).token === ts.SyntaxKind.ExtendsKeyword); } return false; } - function isTypeReference(node: Node): boolean { - if (isRightSideOfQualifiedNameOrPropertyAccess(node)) { + function isTypeReference(node: ts.Node): boolean { + if (ts.isRightSideOfQualifiedNameOrPropertyAccess(node)) { node = node.parent; } switch (node.kind) { - case SyntaxKind.ThisKeyword: - return !isExpressionNode(node); - case SyntaxKind.ThisType: + case ts.SyntaxKind.ThisKeyword: + return !ts.isExpressionNode(node); + case ts.SyntaxKind.ThisType: return true; } switch (node.parent.kind) { - case SyntaxKind.TypeReference: + case ts.SyntaxKind.TypeReference: return true; - case SyntaxKind.ImportType: - return !(node.parent as ImportTypeNode).isTypeOf; - case SyntaxKind.ExpressionWithTypeArguments: - return isPartOfTypeNode(node.parent); + case ts.SyntaxKind.ImportType: + return !(node.parent as ts.ImportTypeNode).isTypeOf; + case ts.SyntaxKind.ExpressionWithTypeArguments: + return ts.isPartOfTypeNode(node.parent); } return false; } - export function isCallExpressionTarget(node: Node, includeElementAccess = false, skipPastOuterExpressions = false): boolean { - return isCalleeWorker(node, isCallExpression, selectExpressionOfCallOrNewExpressionOrDecorator, includeElementAccess, skipPastOuterExpressions); + export function isCallExpressionTarget(node: ts.Node, includeElementAccess = false, skipPastOuterExpressions = false): boolean { + return isCalleeWorker(node, ts.isCallExpression, selectExpressionOfCallOrNewExpressionOrDecorator, includeElementAccess, skipPastOuterExpressions); } - export function isNewExpressionTarget(node: Node, includeElementAccess = false, skipPastOuterExpressions = false): boolean { - return isCalleeWorker(node, isNewExpression, selectExpressionOfCallOrNewExpressionOrDecorator, includeElementAccess, skipPastOuterExpressions); + export function isNewExpressionTarget(node: ts.Node, includeElementAccess = false, skipPastOuterExpressions = false): boolean { + return isCalleeWorker(node, ts.isNewExpression, selectExpressionOfCallOrNewExpressionOrDecorator, includeElementAccess, skipPastOuterExpressions); } - export function isCallOrNewExpressionTarget(node: Node, includeElementAccess = false, skipPastOuterExpressions = false): boolean { - return isCalleeWorker(node, isCallOrNewExpression, selectExpressionOfCallOrNewExpressionOrDecorator, includeElementAccess, skipPastOuterExpressions); + export function isCallOrNewExpressionTarget(node: ts.Node, includeElementAccess = false, skipPastOuterExpressions = false): boolean { + return isCalleeWorker(node, ts.isCallOrNewExpression, selectExpressionOfCallOrNewExpressionOrDecorator, includeElementAccess, skipPastOuterExpressions); } - export function isTaggedTemplateTag(node: Node, includeElementAccess = false, skipPastOuterExpressions = false): boolean { - return isCalleeWorker(node, isTaggedTemplateExpression, selectTagOfTaggedTemplateExpression, includeElementAccess, skipPastOuterExpressions); + export function isTaggedTemplateTag(node: ts.Node, includeElementAccess = false, skipPastOuterExpressions = false): boolean { + return isCalleeWorker(node, ts.isTaggedTemplateExpression, selectTagOfTaggedTemplateExpression, includeElementAccess, skipPastOuterExpressions); } - export function isDecoratorTarget(node: Node, includeElementAccess = false, skipPastOuterExpressions = false): boolean { - return isCalleeWorker(node, isDecorator, selectExpressionOfCallOrNewExpressionOrDecorator, includeElementAccess, skipPastOuterExpressions); + export function isDecoratorTarget(node: ts.Node, includeElementAccess = false, skipPastOuterExpressions = false): boolean { + return isCalleeWorker(node, ts.isDecorator, selectExpressionOfCallOrNewExpressionOrDecorator, includeElementAccess, skipPastOuterExpressions); } - export function isJsxOpeningLikeElementTagName(node: Node, includeElementAccess = false, skipPastOuterExpressions = false): boolean { - return isCalleeWorker(node, isJsxOpeningLikeElement, selectTagNameOfJsxOpeningLikeElement, includeElementAccess, skipPastOuterExpressions); + export function isJsxOpeningLikeElementTagName(node: ts.Node, includeElementAccess = false, skipPastOuterExpressions = false): boolean { + return isCalleeWorker(node, ts.isJsxOpeningLikeElement, selectTagNameOfJsxOpeningLikeElement, includeElementAccess, skipPastOuterExpressions); } - function selectExpressionOfCallOrNewExpressionOrDecorator(node: CallExpression | NewExpression | Decorator) { + function selectExpressionOfCallOrNewExpressionOrDecorator(node: ts.CallExpression | ts.NewExpression | ts.Decorator) { return node.expression; } - function selectTagOfTaggedTemplateExpression(node: TaggedTemplateExpression) { + function selectTagOfTaggedTemplateExpression(node: ts.TaggedTemplateExpression) { return node.tag; } - function selectTagNameOfJsxOpeningLikeElement(node: JsxOpeningLikeElement) { + function selectTagNameOfJsxOpeningLikeElement(node: ts.JsxOpeningLikeElement) { return node.tagName; } - function isCalleeWorker(node: Node, pred: (node: Node) => node is T, calleeSelector: (node: T) => Expression, includeElementAccess: boolean, skipPastOuterExpressions: boolean) { + function isCalleeWorker(node: ts.Node, pred: (node: ts.Node) => node is T, calleeSelector: (node: T) => ts.Expression, includeElementAccess: boolean, skipPastOuterExpressions: boolean) { let target = includeElementAccess ? climbPastPropertyOrElementAccess(node) : climbPastPropertyAccess(node); if (skipPastOuterExpressions) { - target = skipOuterExpressions(target); + target = ts.skipOuterExpressions(target); } return !!target && !!target.parent && pred(target.parent) && calleeSelector(target.parent) === target; } - export function climbPastPropertyAccess(node: Node) { + export function climbPastPropertyAccess(node: ts.Node) { return isRightSideOfPropertyAccess(node) ? node.parent : node; } - export function climbPastPropertyOrElementAccess(node: Node) { + export function climbPastPropertyOrElementAccess(node: ts.Node) { return isRightSideOfPropertyAccess(node) || isArgumentExpressionOfElementAccess(node) ? node.parent : node; } - export function getTargetLabel(referenceNode: Node, labelName: string): Identifier | undefined { + export function getTargetLabel(referenceNode: ts.Node, labelName: string): ts.Identifier | undefined { while (referenceNode) { - if (referenceNode.kind === SyntaxKind.LabeledStatement && (referenceNode as LabeledStatement).label.escapedText === labelName) { - return (referenceNode as LabeledStatement).label; + if (referenceNode.kind === ts.SyntaxKind.LabeledStatement && (referenceNode as ts.LabeledStatement).label.escapedText === labelName) { + return (referenceNode as ts.LabeledStatement).label; } referenceNode = referenceNode.parent; } return undefined; } - export function hasPropertyAccessExpressionWithName(node: CallExpression, funcName: string): boolean { - if (!isPropertyAccessExpression(node.expression)) { + export function hasPropertyAccessExpressionWithName(node: ts.CallExpression, funcName: string): boolean { + if (!ts.isPropertyAccessExpression(node.expression)) { return false; } return node.expression.name.text === funcName; } - export function isJumpStatementTarget(node: Node): node is Identifier & { parent: BreakOrContinueStatement } { - return isIdentifier(node) && tryCast(node.parent, isBreakOrContinueStatement)?.label === node; + export function isJumpStatementTarget(node: ts.Node): node is ts.Identifier & { + parent: ts.BreakOrContinueStatement; + } { + return ts.isIdentifier(node) && ts.tryCast(node.parent, ts.isBreakOrContinueStatement)?.label === node; } - export function isLabelOfLabeledStatement(node: Node): node is Identifier { - return isIdentifier(node) && tryCast(node.parent, isLabeledStatement)?.label === node; + export function isLabelOfLabeledStatement(node: ts.Node): node is ts.Identifier { + return ts.isIdentifier(node) && ts.tryCast(node.parent, ts.isLabeledStatement)?.label === node; } - export function isLabelName(node: Node): boolean { + export function isLabelName(node: ts.Node): boolean { return isLabelOfLabeledStatement(node) || isJumpStatementTarget(node); } - export function isTagName(node: Node): boolean { - return tryCast(node.parent, isJSDocTag)?.tagName === node; + export function isTagName(node: ts.Node): boolean { + return ts.tryCast(node.parent, ts.isJSDocTag)?.tagName === node; } - export function isRightSideOfQualifiedName(node: Node) { - return tryCast(node.parent, isQualifiedName)?.right === node; + export function isRightSideOfQualifiedName(node: ts.Node) { + return ts.tryCast(node.parent, ts.isQualifiedName)?.right === node; } - export function isRightSideOfPropertyAccess(node: Node) { - return tryCast(node.parent, isPropertyAccessExpression)?.name === node; + export function isRightSideOfPropertyAccess(node: ts.Node) { + return ts.tryCast(node.parent, ts.isPropertyAccessExpression)?.name === node; } - export function isArgumentExpressionOfElementAccess(node: Node) { - return tryCast(node.parent, isElementAccessExpression)?.argumentExpression === node; + export function isArgumentExpressionOfElementAccess(node: ts.Node) { + return ts.tryCast(node.parent, ts.isElementAccessExpression)?.argumentExpression === node; } - export function isNameOfModuleDeclaration(node: Node) { - return tryCast(node.parent, isModuleDeclaration)?.name === node; + export function isNameOfModuleDeclaration(node: ts.Node) { + return ts.tryCast(node.parent, ts.isModuleDeclaration)?.name === node; } - export function isNameOfFunctionDeclaration(node: Node): boolean { - return isIdentifier(node) && tryCast(node.parent, isFunctionLike)?.name === node; + export function isNameOfFunctionDeclaration(node: ts.Node): boolean { + return ts.isIdentifier(node) && ts.tryCast(node.parent, ts.isFunctionLike)?.name === node; } - export function isLiteralNameOfPropertyDeclarationOrIndexAccess(node: StringLiteral | NumericLiteral | NoSubstitutionTemplateLiteral): boolean { + export function isLiteralNameOfPropertyDeclarationOrIndexAccess(node: ts.StringLiteral | ts.NumericLiteral | ts.NoSubstitutionTemplateLiteral): boolean { switch (node.parent.kind) { - case SyntaxKind.PropertyDeclaration: - case SyntaxKind.PropertySignature: - case SyntaxKind.PropertyAssignment: - case SyntaxKind.EnumMember: - case SyntaxKind.MethodDeclaration: - case SyntaxKind.MethodSignature: - case SyntaxKind.GetAccessor: - case SyntaxKind.SetAccessor: - case SyntaxKind.ModuleDeclaration: - return getNameOfDeclaration(node.parent as Declaration) === node; - case SyntaxKind.ElementAccessExpression: - return (node.parent as ElementAccessExpression).argumentExpression === node; - case SyntaxKind.ComputedPropertyName: + case ts.SyntaxKind.PropertyDeclaration: + case ts.SyntaxKind.PropertySignature: + case ts.SyntaxKind.PropertyAssignment: + case ts.SyntaxKind.EnumMember: + case ts.SyntaxKind.MethodDeclaration: + case ts.SyntaxKind.MethodSignature: + case ts.SyntaxKind.GetAccessor: + case ts.SyntaxKind.SetAccessor: + case ts.SyntaxKind.ModuleDeclaration: + return ts.getNameOfDeclaration(node.parent as ts.Declaration) === node; + case ts.SyntaxKind.ElementAccessExpression: + return (node.parent as ts.ElementAccessExpression).argumentExpression === node; + case ts.SyntaxKind.ComputedPropertyName: return true; - case SyntaxKind.LiteralType: - return node.parent.parent.kind === SyntaxKind.IndexedAccessType; + case ts.SyntaxKind.LiteralType: + return node.parent.parent.kind === ts.SyntaxKind.IndexedAccessType; default: return false; } } - export function isExpressionOfExternalModuleImportEqualsDeclaration(node: Node) { - return isExternalModuleImportEqualsDeclaration(node.parent.parent) && - getExternalModuleImportEqualsDeclarationExpression(node.parent.parent) === node; + export function isExpressionOfExternalModuleImportEqualsDeclaration(node: ts.Node) { + return ts.isExternalModuleImportEqualsDeclaration(node.parent.parent) && + ts.getExternalModuleImportEqualsDeclarationExpression(node.parent.parent) === node; } - export function getContainerNode(node: Node): Declaration | undefined { - if (isJSDocTypeAlias(node)) { + export function getContainerNode(node: ts.Node): ts.Declaration | undefined { + if (ts.isJSDocTypeAlias(node)) { // This doesn't just apply to the node immediately under the comment, but to everything in its parent's scope. // node.parent = the JSDoc comment, node.parent.parent = the node having the comment. // Then we get parent again in the loop. @@ -354,127 +354,126 @@ namespace ts { return undefined; } switch (node.kind) { - case SyntaxKind.SourceFile: - case SyntaxKind.MethodDeclaration: - case SyntaxKind.MethodSignature: - case SyntaxKind.FunctionDeclaration: - case SyntaxKind.FunctionExpression: - case SyntaxKind.GetAccessor: - case SyntaxKind.SetAccessor: - case SyntaxKind.ClassDeclaration: - case SyntaxKind.InterfaceDeclaration: - case SyntaxKind.EnumDeclaration: - case SyntaxKind.ModuleDeclaration: - return node as Declaration; - } - } - } - - export function getNodeKind(node: Node): ScriptElementKind { + case ts.SyntaxKind.SourceFile: + case ts.SyntaxKind.MethodDeclaration: + case ts.SyntaxKind.MethodSignature: + case ts.SyntaxKind.FunctionDeclaration: + case ts.SyntaxKind.FunctionExpression: + case ts.SyntaxKind.GetAccessor: + case ts.SyntaxKind.SetAccessor: + case ts.SyntaxKind.ClassDeclaration: + case ts.SyntaxKind.InterfaceDeclaration: + case ts.SyntaxKind.EnumDeclaration: + case ts.SyntaxKind.ModuleDeclaration: + return node as ts.Declaration; + } + } + } + export function getNodeKind(node: ts.Node): ts.ScriptElementKind { switch (node.kind) { - case SyntaxKind.SourceFile: - return isExternalModule(node as SourceFile) ? ScriptElementKind.moduleElement : ScriptElementKind.scriptElement; - case SyntaxKind.ModuleDeclaration: - return ScriptElementKind.moduleElement; - case SyntaxKind.ClassDeclaration: - case SyntaxKind.ClassExpression: - return ScriptElementKind.classElement; - case SyntaxKind.InterfaceDeclaration: return ScriptElementKind.interfaceElement; - case SyntaxKind.TypeAliasDeclaration: - case SyntaxKind.JSDocCallbackTag: - case SyntaxKind.JSDocTypedefTag: - return ScriptElementKind.typeElement; - case SyntaxKind.EnumDeclaration: return ScriptElementKind.enumElement; - case SyntaxKind.VariableDeclaration: - return getKindOfVariableDeclaration(node as VariableDeclaration); - case SyntaxKind.BindingElement: - return getKindOfVariableDeclaration(getRootDeclaration(node) as VariableDeclaration); - case SyntaxKind.ArrowFunction: - case SyntaxKind.FunctionDeclaration: - case SyntaxKind.FunctionExpression: - return ScriptElementKind.functionElement; - case SyntaxKind.GetAccessor: return ScriptElementKind.memberGetAccessorElement; - case SyntaxKind.SetAccessor: return ScriptElementKind.memberSetAccessorElement; - case SyntaxKind.MethodDeclaration: - case SyntaxKind.MethodSignature: - return ScriptElementKind.memberFunctionElement; - case SyntaxKind.PropertyAssignment: - const { initializer } = node as PropertyAssignment; - return isFunctionLike(initializer) ? ScriptElementKind.memberFunctionElement : ScriptElementKind.memberVariableElement; - case SyntaxKind.PropertyDeclaration: - case SyntaxKind.PropertySignature: - case SyntaxKind.ShorthandPropertyAssignment: - case SyntaxKind.SpreadAssignment: - return ScriptElementKind.memberVariableElement; - case SyntaxKind.IndexSignature: return ScriptElementKind.indexSignatureElement; - case SyntaxKind.ConstructSignature: return ScriptElementKind.constructSignatureElement; - case SyntaxKind.CallSignature: return ScriptElementKind.callSignatureElement; - case SyntaxKind.Constructor: - case SyntaxKind.ClassStaticBlockDeclaration: - return ScriptElementKind.constructorImplementationElement; - case SyntaxKind.TypeParameter: return ScriptElementKind.typeParameterElement; - case SyntaxKind.EnumMember: return ScriptElementKind.enumMemberElement; - case SyntaxKind.Parameter: return hasSyntacticModifier(node, ModifierFlags.ParameterPropertyModifier) ? ScriptElementKind.memberVariableElement : ScriptElementKind.parameterElement; - case SyntaxKind.ImportEqualsDeclaration: - case SyntaxKind.ImportSpecifier: - case SyntaxKind.ExportSpecifier: - case SyntaxKind.NamespaceImport: - case SyntaxKind.NamespaceExport: - return ScriptElementKind.alias; - case SyntaxKind.BinaryExpression: - const kind = getAssignmentDeclarationKind(node as BinaryExpression); - const { right } = node as BinaryExpression; + case ts.SyntaxKind.SourceFile: + return ts.isExternalModule(node as ts.SourceFile) ? ts.ScriptElementKind.moduleElement : ts.ScriptElementKind.scriptElement; + case ts.SyntaxKind.ModuleDeclaration: + return ts.ScriptElementKind.moduleElement; + case ts.SyntaxKind.ClassDeclaration: + case ts.SyntaxKind.ClassExpression: + return ts.ScriptElementKind.classElement; + case ts.SyntaxKind.InterfaceDeclaration: return ts.ScriptElementKind.interfaceElement; + case ts.SyntaxKind.TypeAliasDeclaration: + case ts.SyntaxKind.JSDocCallbackTag: + case ts.SyntaxKind.JSDocTypedefTag: + return ts.ScriptElementKind.typeElement; + case ts.SyntaxKind.EnumDeclaration: return ts.ScriptElementKind.enumElement; + case ts.SyntaxKind.VariableDeclaration: + return getKindOfVariableDeclaration(node as ts.VariableDeclaration); + case ts.SyntaxKind.BindingElement: + return getKindOfVariableDeclaration(ts.getRootDeclaration(node) as ts.VariableDeclaration); + case ts.SyntaxKind.ArrowFunction: + case ts.SyntaxKind.FunctionDeclaration: + case ts.SyntaxKind.FunctionExpression: + return ts.ScriptElementKind.functionElement; + case ts.SyntaxKind.GetAccessor: return ts.ScriptElementKind.memberGetAccessorElement; + case ts.SyntaxKind.SetAccessor: return ts.ScriptElementKind.memberSetAccessorElement; + case ts.SyntaxKind.MethodDeclaration: + case ts.SyntaxKind.MethodSignature: + return ts.ScriptElementKind.memberFunctionElement; + case ts.SyntaxKind.PropertyAssignment: + const { initializer } = node as ts.PropertyAssignment; + return ts.isFunctionLike(initializer) ? ts.ScriptElementKind.memberFunctionElement : ts.ScriptElementKind.memberVariableElement; + case ts.SyntaxKind.PropertyDeclaration: + case ts.SyntaxKind.PropertySignature: + case ts.SyntaxKind.ShorthandPropertyAssignment: + case ts.SyntaxKind.SpreadAssignment: + return ts.ScriptElementKind.memberVariableElement; + case ts.SyntaxKind.IndexSignature: return ts.ScriptElementKind.indexSignatureElement; + case ts.SyntaxKind.ConstructSignature: return ts.ScriptElementKind.constructSignatureElement; + case ts.SyntaxKind.CallSignature: return ts.ScriptElementKind.callSignatureElement; + case ts.SyntaxKind.Constructor: + case ts.SyntaxKind.ClassStaticBlockDeclaration: + return ts.ScriptElementKind.constructorImplementationElement; + case ts.SyntaxKind.TypeParameter: return ts.ScriptElementKind.typeParameterElement; + case ts.SyntaxKind.EnumMember: return ts.ScriptElementKind.enumMemberElement; + case ts.SyntaxKind.Parameter: return ts.hasSyntacticModifier(node, ts.ModifierFlags.ParameterPropertyModifier) ? ts.ScriptElementKind.memberVariableElement : ts.ScriptElementKind.parameterElement; + case ts.SyntaxKind.ImportEqualsDeclaration: + case ts.SyntaxKind.ImportSpecifier: + case ts.SyntaxKind.ExportSpecifier: + case ts.SyntaxKind.NamespaceImport: + case ts.SyntaxKind.NamespaceExport: + return ts.ScriptElementKind.alias; + case ts.SyntaxKind.BinaryExpression: + const kind = ts.getAssignmentDeclarationKind(node as ts.BinaryExpression); + const { right } = node as ts.BinaryExpression; switch (kind) { - case AssignmentDeclarationKind.ObjectDefinePropertyValue: - case AssignmentDeclarationKind.ObjectDefinePropertyExports: - case AssignmentDeclarationKind.ObjectDefinePrototypeProperty: - case AssignmentDeclarationKind.None: - return ScriptElementKind.unknown; - case AssignmentDeclarationKind.ExportsProperty: - case AssignmentDeclarationKind.ModuleExports: + case ts.AssignmentDeclarationKind.ObjectDefinePropertyValue: + case ts.AssignmentDeclarationKind.ObjectDefinePropertyExports: + case ts.AssignmentDeclarationKind.ObjectDefinePrototypeProperty: + case ts.AssignmentDeclarationKind.None: + return ts.ScriptElementKind.unknown; + case ts.AssignmentDeclarationKind.ExportsProperty: + case ts.AssignmentDeclarationKind.ModuleExports: const rightKind = getNodeKind(right); - return rightKind === ScriptElementKind.unknown ? ScriptElementKind.constElement : rightKind; - case AssignmentDeclarationKind.PrototypeProperty: - return isFunctionExpression(right) ? ScriptElementKind.memberFunctionElement : ScriptElementKind.memberVariableElement; - case AssignmentDeclarationKind.ThisProperty: - return ScriptElementKind.memberVariableElement; // property - case AssignmentDeclarationKind.Property: + return rightKind === ts.ScriptElementKind.unknown ? ts.ScriptElementKind.constElement : rightKind; + case ts.AssignmentDeclarationKind.PrototypeProperty: + return ts.isFunctionExpression(right) ? ts.ScriptElementKind.memberFunctionElement : ts.ScriptElementKind.memberVariableElement; + case ts.AssignmentDeclarationKind.ThisProperty: + return ts.ScriptElementKind.memberVariableElement; // property + case ts.AssignmentDeclarationKind.Property: // static method / property - return isFunctionExpression(right) ? ScriptElementKind.memberFunctionElement : ScriptElementKind.memberVariableElement; - case AssignmentDeclarationKind.Prototype: - return ScriptElementKind.localClassElement; + return ts.isFunctionExpression(right) ? ts.ScriptElementKind.memberFunctionElement : ts.ScriptElementKind.memberVariableElement; + case ts.AssignmentDeclarationKind.Prototype: + return ts.ScriptElementKind.localClassElement; default: { - assertType(kind); - return ScriptElementKind.unknown; + ts.assertType(kind); + return ts.ScriptElementKind.unknown; } } - case SyntaxKind.Identifier: - return isImportClause(node.parent) ? ScriptElementKind.alias : ScriptElementKind.unknown; - case SyntaxKind.ExportAssignment: - const scriptKind = getNodeKind((node as ExportAssignment).expression); + case ts.SyntaxKind.Identifier: + return ts.isImportClause(node.parent) ? ts.ScriptElementKind.alias : ts.ScriptElementKind.unknown; + case ts.SyntaxKind.ExportAssignment: + const scriptKind = getNodeKind((node as ts.ExportAssignment).expression); // If the expression didn't come back with something (like it does for an identifiers) - return scriptKind === ScriptElementKind.unknown ? ScriptElementKind.constElement : scriptKind; + return scriptKind === ts.ScriptElementKind.unknown ? ts.ScriptElementKind.constElement : scriptKind; default: - return ScriptElementKind.unknown; + return ts.ScriptElementKind.unknown; } - function getKindOfVariableDeclaration(v: VariableDeclaration): ScriptElementKind { - return isVarConst(v) - ? ScriptElementKind.constElement - : isLet(v) - ? ScriptElementKind.letElement - : ScriptElementKind.variableElement; + function getKindOfVariableDeclaration(v: ts.VariableDeclaration): ts.ScriptElementKind { + return ts.isVarConst(v) + ? ts.ScriptElementKind.constElement + : ts.isLet(v) + ? ts.ScriptElementKind.letElement + : ts.ScriptElementKind.variableElement; } } - export function isThis(node: Node): boolean { + export function isThis(node: ts.Node): boolean { switch (node.kind) { - case SyntaxKind.ThisKeyword: + case ts.SyntaxKind.ThisKeyword: // case SyntaxKind.ThisType: TODO: GH#9267 return true; - case SyntaxKind.Identifier: + case ts.SyntaxKind.Identifier: // 'this' as a parameter - return identifierIsThisKeyword(node as Identifier) && node.parent.kind === SyntaxKind.Parameter; + return ts.identifierIsThisKeyword(node as ts.Identifier) && node.parent.kind === ts.SyntaxKind.Parameter; default: return false; } @@ -485,44 +484,44 @@ namespace ts { export interface ListItemInfo { listItemIndex: number; - list: Node; + list: ts.Node; } - export function getLineStartPositionForPosition(position: number, sourceFile: SourceFileLike): number { - const lineStarts = getLineStarts(sourceFile); + export function getLineStartPositionForPosition(position: number, sourceFile: ts.SourceFileLike): number { + const lineStarts = ts.getLineStarts(sourceFile); const line = sourceFile.getLineAndCharacterOfPosition(position).line; return lineStarts[line]; } - export function rangeContainsRange(r1: TextRange, r2: TextRange): boolean { + export function rangeContainsRange(r1: ts.TextRange, r2: ts.TextRange): boolean { return startEndContainsRange(r1.pos, r1.end, r2); } - export function rangeContainsRangeExclusive(r1: TextRange, r2: TextRange): boolean { + export function rangeContainsRangeExclusive(r1: ts.TextRange, r2: ts.TextRange): boolean { return rangeContainsPositionExclusive(r1, r2.pos) && rangeContainsPositionExclusive(r1, r2.end); } - export function rangeContainsPosition(r: TextRange, pos: number): boolean { + export function rangeContainsPosition(r: ts.TextRange, pos: number): boolean { return r.pos <= pos && pos <= r.end; } - export function rangeContainsPositionExclusive(r: TextRange, pos: number) { + export function rangeContainsPositionExclusive(r: ts.TextRange, pos: number) { return r.pos < pos && pos < r.end; } - export function startEndContainsRange(start: number, end: number, range: TextRange): boolean { + export function startEndContainsRange(start: number, end: number, range: ts.TextRange): boolean { return start <= range.pos && end >= range.end; } - export function rangeContainsStartEnd(range: TextRange, start: number, end: number): boolean { + export function rangeContainsStartEnd(range: ts.TextRange, start: number, end: number): boolean { return range.pos <= start && range.end >= end; } - export function rangeOverlapsWithStartEnd(r1: TextRange, start: number, end: number) { + export function rangeOverlapsWithStartEnd(r1: ts.TextRange, start: number, end: number) { return startEndOverlapsWithStartEnd(r1.pos, r1.end, start, end); } - export function nodeOverlapsWithStartEnd(node: Node, sourceFile: SourceFile, start: number, end: number) { + export function nodeOverlapsWithStartEnd(node: ts.Node, sourceFile: ts.SourceFile, start: number, end: number) { return startEndOverlapsWithStartEnd(node.getStart(sourceFile), node.end, start, end); } @@ -535,140 +534,126 @@ namespace ts { /** * Assumes `candidate.start <= position` holds. */ - export function positionBelongsToNode(candidate: Node, position: number, sourceFile: SourceFile): boolean { - Debug.assert(candidate.pos <= position); + export function positionBelongsToNode(candidate: ts.Node, position: number, sourceFile: ts.SourceFile): boolean { + ts.Debug.assert(candidate.pos <= position); return position < candidate.end || !isCompletedNode(candidate, sourceFile); } - function isCompletedNode(n: Node | undefined, sourceFile: SourceFile): boolean { - if (n === undefined || nodeIsMissing(n)) { + function isCompletedNode(n: ts.Node | undefined, sourceFile: ts.SourceFile): boolean { + if (n === undefined || ts.nodeIsMissing(n)) { return false; } switch (n.kind) { - case SyntaxKind.ClassDeclaration: - case SyntaxKind.InterfaceDeclaration: - case SyntaxKind.EnumDeclaration: - case SyntaxKind.ObjectLiteralExpression: - case SyntaxKind.ObjectBindingPattern: - case SyntaxKind.TypeLiteral: - case SyntaxKind.Block: - case SyntaxKind.ModuleBlock: - case SyntaxKind.CaseBlock: - case SyntaxKind.NamedImports: - case SyntaxKind.NamedExports: - return nodeEndsWith(n, SyntaxKind.CloseBraceToken, sourceFile); - case SyntaxKind.CatchClause: - return isCompletedNode((n as CatchClause).block, sourceFile); - case SyntaxKind.NewExpression: - if (!(n as NewExpression).arguments) { + case ts.SyntaxKind.ClassDeclaration: + case ts.SyntaxKind.InterfaceDeclaration: + case ts.SyntaxKind.EnumDeclaration: + case ts.SyntaxKind.ObjectLiteralExpression: + case ts.SyntaxKind.ObjectBindingPattern: + case ts.SyntaxKind.TypeLiteral: + case ts.SyntaxKind.Block: + case ts.SyntaxKind.ModuleBlock: + case ts.SyntaxKind.CaseBlock: + case ts.SyntaxKind.NamedImports: + case ts.SyntaxKind.NamedExports: + return nodeEndsWith(n, ts.SyntaxKind.CloseBraceToken, sourceFile); + case ts.SyntaxKind.CatchClause: + return isCompletedNode((n as ts.CatchClause).block, sourceFile); + case ts.SyntaxKind.NewExpression: + if (!(n as ts.NewExpression).arguments) { return true; } // falls through - case SyntaxKind.CallExpression: - case SyntaxKind.ParenthesizedExpression: - case SyntaxKind.ParenthesizedType: - return nodeEndsWith(n, SyntaxKind.CloseParenToken, sourceFile); - - case SyntaxKind.FunctionType: - case SyntaxKind.ConstructorType: - return isCompletedNode((n as SignatureDeclaration).type, sourceFile); - - case SyntaxKind.Constructor: - case SyntaxKind.GetAccessor: - case SyntaxKind.SetAccessor: - case SyntaxKind.FunctionDeclaration: - case SyntaxKind.FunctionExpression: - case SyntaxKind.MethodDeclaration: - case SyntaxKind.MethodSignature: - case SyntaxKind.ConstructSignature: - case SyntaxKind.CallSignature: - case SyntaxKind.ArrowFunction: - if ((n as FunctionLikeDeclaration).body) { - return isCompletedNode((n as FunctionLikeDeclaration).body, sourceFile); + case ts.SyntaxKind.CallExpression: + case ts.SyntaxKind.ParenthesizedExpression: + case ts.SyntaxKind.ParenthesizedType: + return nodeEndsWith(n, ts.SyntaxKind.CloseParenToken, sourceFile); + case ts.SyntaxKind.FunctionType: + case ts.SyntaxKind.ConstructorType: + return isCompletedNode((n as ts.SignatureDeclaration).type, sourceFile); + case ts.SyntaxKind.Constructor: + case ts.SyntaxKind.GetAccessor: + case ts.SyntaxKind.SetAccessor: + case ts.SyntaxKind.FunctionDeclaration: + case ts.SyntaxKind.FunctionExpression: + case ts.SyntaxKind.MethodDeclaration: + case ts.SyntaxKind.MethodSignature: + case ts.SyntaxKind.ConstructSignature: + case ts.SyntaxKind.CallSignature: + case ts.SyntaxKind.ArrowFunction: + if ((n as ts.FunctionLikeDeclaration).body) { + return isCompletedNode((n as ts.FunctionLikeDeclaration).body, sourceFile); } - - if ((n as FunctionLikeDeclaration).type) { - return isCompletedNode((n as FunctionLikeDeclaration).type, sourceFile); + if ((n as ts.FunctionLikeDeclaration).type) { + return isCompletedNode((n as ts.FunctionLikeDeclaration).type, sourceFile); } // Even though type parameters can be unclosed, we can get away with // having at least a closing paren. - return hasChildOfKind(n, SyntaxKind.CloseParenToken, sourceFile); - - case SyntaxKind.ModuleDeclaration: - return !!(n as ModuleDeclaration).body && isCompletedNode((n as ModuleDeclaration).body, sourceFile); - - case SyntaxKind.IfStatement: - if ((n as IfStatement).elseStatement) { - return isCompletedNode((n as IfStatement).elseStatement, sourceFile); + return hasChildOfKind(n, ts.SyntaxKind.CloseParenToken, sourceFile); + case ts.SyntaxKind.ModuleDeclaration: + return !!(n as ts.ModuleDeclaration).body && isCompletedNode((n as ts.ModuleDeclaration).body, sourceFile); + case ts.SyntaxKind.IfStatement: + if ((n as ts.IfStatement).elseStatement) { + return isCompletedNode((n as ts.IfStatement).elseStatement, sourceFile); } - return isCompletedNode((n as IfStatement).thenStatement, sourceFile); - - case SyntaxKind.ExpressionStatement: - return isCompletedNode((n as ExpressionStatement).expression, sourceFile) || - hasChildOfKind(n, SyntaxKind.SemicolonToken, sourceFile); - - case SyntaxKind.ArrayLiteralExpression: - case SyntaxKind.ArrayBindingPattern: - case SyntaxKind.ElementAccessExpression: - case SyntaxKind.ComputedPropertyName: - case SyntaxKind.TupleType: - return nodeEndsWith(n, SyntaxKind.CloseBracketToken, sourceFile); - - case SyntaxKind.IndexSignature: - if ((n as IndexSignatureDeclaration).type) { - return isCompletedNode((n as IndexSignatureDeclaration).type, sourceFile); + return isCompletedNode((n as ts.IfStatement).thenStatement, sourceFile); + case ts.SyntaxKind.ExpressionStatement: + return isCompletedNode((n as ts.ExpressionStatement).expression, sourceFile) || + hasChildOfKind(n, ts.SyntaxKind.SemicolonToken, sourceFile); + case ts.SyntaxKind.ArrayLiteralExpression: + case ts.SyntaxKind.ArrayBindingPattern: + case ts.SyntaxKind.ElementAccessExpression: + case ts.SyntaxKind.ComputedPropertyName: + case ts.SyntaxKind.TupleType: + return nodeEndsWith(n, ts.SyntaxKind.CloseBracketToken, sourceFile); + case ts.SyntaxKind.IndexSignature: + if ((n as ts.IndexSignatureDeclaration).type) { + return isCompletedNode((n as ts.IndexSignatureDeclaration).type, sourceFile); } - - return hasChildOfKind(n, SyntaxKind.CloseBracketToken, sourceFile); - - case SyntaxKind.CaseClause: - case SyntaxKind.DefaultClause: + return hasChildOfKind(n, ts.SyntaxKind.CloseBracketToken, sourceFile); + case ts.SyntaxKind.CaseClause: + case ts.SyntaxKind.DefaultClause: // there is no such thing as terminator token for CaseClause/DefaultClause so for simplicity always consider them non-completed return false; - case SyntaxKind.ForStatement: - case SyntaxKind.ForInStatement: - case SyntaxKind.ForOfStatement: - case SyntaxKind.WhileStatement: - return isCompletedNode((n as IterationStatement).statement, sourceFile); - case SyntaxKind.DoStatement: + case ts.SyntaxKind.ForStatement: + case ts.SyntaxKind.ForInStatement: + case ts.SyntaxKind.ForOfStatement: + case ts.SyntaxKind.WhileStatement: + return isCompletedNode((n as ts.IterationStatement).statement, sourceFile); + case ts.SyntaxKind.DoStatement: // rough approximation: if DoStatement has While keyword - then if node is completed is checking the presence of ')'; - return hasChildOfKind(n, SyntaxKind.WhileKeyword, sourceFile) - ? nodeEndsWith(n, SyntaxKind.CloseParenToken, sourceFile) - : isCompletedNode((n as DoStatement).statement, sourceFile); - - case SyntaxKind.TypeQuery: - return isCompletedNode((n as TypeQueryNode).exprName, sourceFile); - - case SyntaxKind.TypeOfExpression: - case SyntaxKind.DeleteExpression: - case SyntaxKind.VoidExpression: - case SyntaxKind.YieldExpression: - case SyntaxKind.SpreadElement: - const unaryWordExpression = n as (TypeOfExpression | DeleteExpression | VoidExpression | YieldExpression | SpreadElement); + return hasChildOfKind(n, ts.SyntaxKind.WhileKeyword, sourceFile) + ? nodeEndsWith(n, ts.SyntaxKind.CloseParenToken, sourceFile) + : isCompletedNode((n as ts.DoStatement).statement, sourceFile); + case ts.SyntaxKind.TypeQuery: + return isCompletedNode((n as ts.TypeQueryNode).exprName, sourceFile); + case ts.SyntaxKind.TypeOfExpression: + case ts.SyntaxKind.DeleteExpression: + case ts.SyntaxKind.VoidExpression: + case ts.SyntaxKind.YieldExpression: + case ts.SyntaxKind.SpreadElement: + const unaryWordExpression = n as (ts.TypeOfExpression | ts.DeleteExpression | ts.VoidExpression | ts.YieldExpression | ts.SpreadElement); return isCompletedNode(unaryWordExpression.expression, sourceFile); - case SyntaxKind.TaggedTemplateExpression: - return isCompletedNode((n as TaggedTemplateExpression).template, sourceFile); - case SyntaxKind.TemplateExpression: - const lastSpan = lastOrUndefined((n as TemplateExpression).templateSpans); + case ts.SyntaxKind.TaggedTemplateExpression: + return isCompletedNode((n as ts.TaggedTemplateExpression).template, sourceFile); + case ts.SyntaxKind.TemplateExpression: + const lastSpan = ts.lastOrUndefined((n as ts.TemplateExpression).templateSpans); return isCompletedNode(lastSpan, sourceFile); - case SyntaxKind.TemplateSpan: - return nodeIsPresent((n as TemplateSpan).literal); - - case SyntaxKind.ExportDeclaration: - case SyntaxKind.ImportDeclaration: - return nodeIsPresent((n as ExportDeclaration | ImportDeclaration).moduleSpecifier); - - case SyntaxKind.PrefixUnaryExpression: - return isCompletedNode((n as PrefixUnaryExpression).operand, sourceFile); - case SyntaxKind.BinaryExpression: - return isCompletedNode((n as BinaryExpression).right, sourceFile); - case SyntaxKind.ConditionalExpression: - return isCompletedNode((n as ConditionalExpression).whenFalse, sourceFile); + case ts.SyntaxKind.TemplateSpan: + return ts.nodeIsPresent((n as ts.TemplateSpan).literal); + case ts.SyntaxKind.ExportDeclaration: + case ts.SyntaxKind.ImportDeclaration: + return ts.nodeIsPresent((n as ts.ExportDeclaration | ts.ImportDeclaration).moduleSpecifier); + case ts.SyntaxKind.PrefixUnaryExpression: + return isCompletedNode((n as ts.PrefixUnaryExpression).operand, sourceFile); + case ts.SyntaxKind.BinaryExpression: + return isCompletedNode((n as ts.BinaryExpression).right, sourceFile); + case ts.SyntaxKind.ConditionalExpression: + return isCompletedNode((n as ts.ConditionalExpression).whenFalse, sourceFile); default: return true; @@ -679,21 +664,21 @@ namespace ts { * Checks if node ends with 'expectedLastToken'. * If child at position 'length - 1' is 'SemicolonToken' it is skipped and 'expectedLastToken' is compared with child at position 'length - 2'. */ - function nodeEndsWith(n: Node, expectedLastToken: SyntaxKind, sourceFile: SourceFile): boolean { + function nodeEndsWith(n: ts.Node, expectedLastToken: ts.SyntaxKind, sourceFile: ts.SourceFile): boolean { const children = n.getChildren(sourceFile); if (children.length) { - const lastChild = last(children); + const lastChild = ts.last(children); if (lastChild.kind === expectedLastToken) { return true; } - else if (lastChild.kind === SyntaxKind.SemicolonToken && children.length !== 1) { + else if (lastChild.kind === ts.SyntaxKind.SemicolonToken && children.length !== 1) { return children[children.length - 2].kind === expectedLastToken; } } return false; } - export function findListItemInfo(node: Node): ListItemInfo | undefined { + export function findListItemInfo(node: ts.Node): ListItemInfo | undefined { const list = findContainingList(node); // It is possible at this point for syntaxList to be undefined, either if @@ -705,7 +690,7 @@ namespace ts { } const children = list.getChildren(); - const listItemIndex = indexOfNode(children, node); + const listItemIndex = ts.indexOfNode(children, node); return { listItemIndex, @@ -713,109 +698,114 @@ namespace ts { }; } - export function hasChildOfKind(n: Node, kind: SyntaxKind, sourceFile: SourceFile): boolean { + export function hasChildOfKind(n: ts.Node, kind: ts.SyntaxKind, sourceFile: ts.SourceFile): boolean { return !!findChildOfKind(n, kind, sourceFile); } - export function findChildOfKind(n: Node, kind: T["kind"], sourceFile: SourceFileLike): T | undefined { - return find(n.getChildren(sourceFile), (c): c is T => c.kind === kind); + export function findChildOfKind(n: ts.Node, kind: T["kind"], sourceFile: ts.SourceFileLike): T | undefined { + return ts.find(n.getChildren(sourceFile), (c): c is T => c.kind === kind); } - export function findContainingList(node: Node): SyntaxList | undefined { + export function findContainingList(node: ts.Node): ts.SyntaxList | undefined { // The node might be a list element (nonsynthetic) or a comma (synthetic). Either way, it will // be parented by the container of the SyntaxList, not the SyntaxList itself. // In order to find the list item index, we first need to locate SyntaxList itself and then search // for the position of the relevant node (or comma). - const syntaxList = find(node.parent.getChildren(), (c): c is SyntaxList => isSyntaxList(c) && rangeContainsRange(c, node)); + const syntaxList = ts.find(node.parent.getChildren(), (c): c is ts.SyntaxList => ts.isSyntaxList(c) && rangeContainsRange(c, node)); // Either we didn't find an appropriate list, or the list must contain us. - Debug.assert(!syntaxList || contains(syntaxList.getChildren(), node)); + ts.Debug.assert(!syntaxList || ts.contains(syntaxList.getChildren(), node)); return syntaxList; } - function isDefaultModifier(node: Node) { - return node.kind === SyntaxKind.DefaultKeyword; + function isDefaultModifier(node: ts.Node) { + return node.kind === ts.SyntaxKind.DefaultKeyword; } - function isClassKeyword(node: Node) { - return node.kind === SyntaxKind.ClassKeyword; + function isClassKeyword(node: ts.Node) { + return node.kind === ts.SyntaxKind.ClassKeyword; } - function isFunctionKeyword(node: Node) { - return node.kind === SyntaxKind.FunctionKeyword; + function isFunctionKeyword(node: ts.Node) { + return node.kind === ts.SyntaxKind.FunctionKeyword; } - function getAdjustedLocationForClass(node: ClassDeclaration | ClassExpression) { - if (isNamedDeclaration(node)) { + function getAdjustedLocationForClass(node: ts.ClassDeclaration | ts.ClassExpression) { + if (ts.isNamedDeclaration(node)) { return node.name; } - if (isClassDeclaration(node)) { + if (ts.isClassDeclaration(node)) { // for class and function declarations, use the `default` modifier // when the declaration is unnamed. - const defaultModifier = node.modifiers && find(node.modifiers, isDefaultModifier); - if (defaultModifier) return defaultModifier; + const defaultModifier = node.modifiers && ts.find(node.modifiers, isDefaultModifier); + if (defaultModifier) + return defaultModifier; } - if (isClassExpression(node)) { + if (ts.isClassExpression(node)) { // for class expressions, use the `class` keyword when the class is unnamed - const classKeyword = find(node.getChildren(), isClassKeyword); - if (classKeyword) return classKeyword; + const classKeyword = ts.find(node.getChildren(), isClassKeyword); + if (classKeyword) + return classKeyword; } } - function getAdjustedLocationForFunction(node: FunctionDeclaration | FunctionExpression) { - if (isNamedDeclaration(node)) { + function getAdjustedLocationForFunction(node: ts.FunctionDeclaration | ts.FunctionExpression) { + if (ts.isNamedDeclaration(node)) { return node.name; } - if (isFunctionDeclaration(node)) { + if (ts.isFunctionDeclaration(node)) { // for class and function declarations, use the `default` modifier // when the declaration is unnamed. - const defaultModifier = find(node.modifiers!, isDefaultModifier); - if (defaultModifier) return defaultModifier; + const defaultModifier = ts.find(node.modifiers!, isDefaultModifier); + if (defaultModifier) + return defaultModifier; } - if (isFunctionExpression(node)) { + if (ts.isFunctionExpression(node)) { // for function expressions, use the `function` keyword when the function is unnamed - const functionKeyword = find(node.getChildren(), isFunctionKeyword); - if (functionKeyword) return functionKeyword; + const functionKeyword = ts.find(node.getChildren(), isFunctionKeyword); + if (functionKeyword) + return functionKeyword; } } - function getAncestorTypeNode(node: Node) { - let lastTypeNode: TypeNode | undefined; - findAncestor(node, a => { - if (isTypeNode(a)) { + function getAncestorTypeNode(node: ts.Node) { + let lastTypeNode: ts.TypeNode | undefined; + ts.findAncestor(node, a => { + if (ts.isTypeNode(a)) { lastTypeNode = a; } - return !isQualifiedName(a.parent) && !isTypeNode(a.parent) && !isTypeElement(a.parent); + return !ts.isQualifiedName(a.parent) && !ts.isTypeNode(a.parent) && !ts.isTypeElement(a.parent); }); return lastTypeNode; } - export function getContextualTypeFromParentOrAncestorTypeNode(node: Expression, checker: TypeChecker): Type | undefined { + export function getContextualTypeFromParentOrAncestorTypeNode(node: ts.Expression, checker: ts.TypeChecker): ts.Type | undefined { const contextualType = getContextualTypeFromParent(node, checker); - if (contextualType) return contextualType; + if (contextualType) + return contextualType; const ancestorTypeNode = getAncestorTypeNode(node); return ancestorTypeNode && checker.getTypeAtLocation(ancestorTypeNode); } - function getAdjustedLocationForDeclaration(node: Node, forRename: boolean) { + function getAdjustedLocationForDeclaration(node: ts.Node, forRename: boolean) { if (!forRename) { switch (node.kind) { - case SyntaxKind.ClassDeclaration: - case SyntaxKind.ClassExpression: - return getAdjustedLocationForClass(node as ClassDeclaration | ClassExpression); - case SyntaxKind.FunctionDeclaration: - case SyntaxKind.FunctionExpression: - return getAdjustedLocationForFunction(node as FunctionDeclaration | FunctionExpression); - case SyntaxKind.Constructor: + case ts.SyntaxKind.ClassDeclaration: + case ts.SyntaxKind.ClassExpression: + return getAdjustedLocationForClass(node as ts.ClassDeclaration | ts.ClassExpression); + case ts.SyntaxKind.FunctionDeclaration: + case ts.SyntaxKind.FunctionExpression: + return getAdjustedLocationForFunction(node as ts.FunctionDeclaration | ts.FunctionExpression); + case ts.SyntaxKind.Constructor: return node; } } - if (isNamedDeclaration(node)) { + if (ts.isNamedDeclaration(node)) { return node.name; } } - function getAdjustedLocationForImportDeclaration(node: ImportDeclaration, forRename: boolean) { + function getAdjustedLocationForImportDeclaration(node: ts.ImportDeclaration, forRename: boolean) { if (node.importClause) { if (node.importClause.name && node.importClause.namedBindings) { // do not adjust if we have both a name and named bindings @@ -835,15 +825,15 @@ namespace ts { // import /**/type { propertyName as [|name|] } from ...; // import /**/type * as [|name|] from ...; if (node.importClause.namedBindings) { - if (isNamedImports(node.importClause.namedBindings)) { + if (ts.isNamedImports(node.importClause.namedBindings)) { // do nothing if there is more than one binding - const onlyBinding = singleOrUndefined(node.importClause.namedBindings.elements); + const onlyBinding = ts.singleOrUndefined(node.importClause.namedBindings.elements); if (!onlyBinding) { return; } return onlyBinding.name; } - else if (isNamespaceImport(node.importClause.namedBindings)) { + else if (ts.isNamespaceImport(node.importClause.namedBindings)) { return node.importClause.namedBindings.name; } } @@ -856,7 +846,7 @@ namespace ts { } } - function getAdjustedLocationForExportDeclaration(node: ExportDeclaration, forRename: boolean) { + function getAdjustedLocationForExportDeclaration(node: ts.ExportDeclaration, forRename: boolean) { if (node.exportClause) { // /**/export { [|name|] } ... // /**/export { propertyName as [|name|] } ... @@ -864,15 +854,15 @@ namespace ts { // export /**/type { [|name|] } from ... // export /**/type { propertyName as [|name|] } from ... // export /**/type * as [|name|] ... - if (isNamedExports(node.exportClause)) { + if (ts.isNamedExports(node.exportClause)) { // do nothing if there is more than one binding - const onlyBinding = singleOrUndefined(node.exportClause.elements); + const onlyBinding = ts.singleOrUndefined(node.exportClause.elements); if (!onlyBinding) { return; } return node.exportClause.elements[0].name; } - else if (isNamespaceExport(node.exportClause)) { + else if (ts.isNamespaceExport(node.exportClause)) { return node.exportClause.name; } } @@ -883,7 +873,7 @@ namespace ts { } } - function getAdjustedLocationForHeritageClause(node: HeritageClause) { + function getAdjustedLocationForHeritageClause(node: ts.HeritageClause) { // /**/extends [|name|] // /**/implements [|name|] if (node.types.length === 1) { @@ -894,7 +884,7 @@ namespace ts { // /**/implements name1, name2 ... } - function getAdjustedLocation(node: Node, forRename: boolean): Node { + function getAdjustedLocation(node: ts.Node, forRename: boolean): ts.Node { const { parent } = node; // /**/ [|name|] ... // /**/ [|name|] ... @@ -903,35 +893,35 @@ namespace ts { // // NOTE: If the node is a modifier, we don't adjust its location if it is the `default` modifier as that is handled // specially by `getSymbolAtLocation`. - if (isModifier(node) && (forRename || node.kind !== SyntaxKind.DefaultKeyword) ? contains(parent.modifiers, node) : - node.kind === SyntaxKind.ClassKeyword ? isClassDeclaration(parent) || isClassExpression(node) : - node.kind === SyntaxKind.FunctionKeyword ? isFunctionDeclaration(parent) || isFunctionExpression(node) : - node.kind === SyntaxKind.InterfaceKeyword ? isInterfaceDeclaration(parent) : - node.kind === SyntaxKind.EnumKeyword ? isEnumDeclaration(parent) : - node.kind === SyntaxKind.TypeKeyword ? isTypeAliasDeclaration(parent) : - node.kind === SyntaxKind.NamespaceKeyword || node.kind === SyntaxKind.ModuleKeyword ? isModuleDeclaration(parent) : - node.kind === SyntaxKind.ImportKeyword ? isImportEqualsDeclaration(parent) : - node.kind === SyntaxKind.GetKeyword ? isGetAccessorDeclaration(parent) : - node.kind === SyntaxKind.SetKeyword && isSetAccessorDeclaration(parent)) { + if (ts.isModifier(node) && (forRename || node.kind !== ts.SyntaxKind.DefaultKeyword) ? ts.contains(parent.modifiers, node) : + node.kind === ts.SyntaxKind.ClassKeyword ? ts.isClassDeclaration(parent) || ts.isClassExpression(node) : + node.kind === ts.SyntaxKind.FunctionKeyword ? ts.isFunctionDeclaration(parent) || ts.isFunctionExpression(node) : + node.kind === ts.SyntaxKind.InterfaceKeyword ? ts.isInterfaceDeclaration(parent) : + node.kind === ts.SyntaxKind.EnumKeyword ? ts.isEnumDeclaration(parent) : + node.kind === ts.SyntaxKind.TypeKeyword ? ts.isTypeAliasDeclaration(parent) : + node.kind === ts.SyntaxKind.NamespaceKeyword || node.kind === ts.SyntaxKind.ModuleKeyword ? ts.isModuleDeclaration(parent) : + node.kind === ts.SyntaxKind.ImportKeyword ? ts.isImportEqualsDeclaration(parent) : + node.kind === ts.SyntaxKind.GetKeyword ? ts.isGetAccessorDeclaration(parent) : + node.kind === ts.SyntaxKind.SetKeyword && ts.isSetAccessorDeclaration(parent)) { const location = getAdjustedLocationForDeclaration(parent, forRename); if (location) { return location; } } // /**/ [|name|] ... - if ((node.kind === SyntaxKind.VarKeyword || node.kind === SyntaxKind.ConstKeyword || node.kind === SyntaxKind.LetKeyword) && - isVariableDeclarationList(parent) && parent.declarations.length === 1) { + if ((node.kind === ts.SyntaxKind.VarKeyword || node.kind === ts.SyntaxKind.ConstKeyword || node.kind === ts.SyntaxKind.LetKeyword) && + ts.isVariableDeclarationList(parent) && parent.declarations.length === 1) { const decl = parent.declarations[0]; - if (isIdentifier(decl.name)) { + if (ts.isIdentifier(decl.name)) { return decl.name; } } - if (node.kind === SyntaxKind.TypeKeyword) { + if (node.kind === ts.SyntaxKind.TypeKeyword) { // import /**/type [|name|] from ...; // import /**/type { [|name|] } from ...; // import /**/type { propertyName as [|name|] } from ...; // import /**/type ... from "[|module|]"; - if (isImportClause(parent) && parent.isTypeOnly) { + if (ts.isImportClause(parent) && parent.isTypeOnly) { const location = getAdjustedLocationForImportDeclaration(parent.parent, forRename); if (location) { return location; @@ -941,7 +931,7 @@ namespace ts { // export /**/type { propertyName as [|name|] } from ...; // export /**/type * from "[|module|]"; // export /**/type * as ... from "[|module|]"; - if (isExportDeclaration(parent) && parent.isTypeOnly) { + if (ts.isExportDeclaration(parent) && parent.isTypeOnly) { const location = getAdjustedLocationForExportDeclaration(parent, forRename); if (location) { return location; @@ -952,14 +942,14 @@ namespace ts { // import * /**/as [|name|] ... // export { propertyName /**/as [|name|] } ... // export * /**/as [|name|] ... - if (node.kind === SyntaxKind.AsKeyword) { - if (isImportSpecifier(parent) && parent.propertyName || - isExportSpecifier(parent) && parent.propertyName || - isNamespaceImport(parent) || - isNamespaceExport(parent)) { + if (node.kind === ts.SyntaxKind.AsKeyword) { + if (ts.isImportSpecifier(parent) && parent.propertyName || + ts.isExportSpecifier(parent) && parent.propertyName || + ts.isNamespaceImport(parent) || + ts.isNamespaceExport(parent)) { return parent.name; } - if (isExportDeclaration(parent) && parent.exportClause && isNamespaceExport(parent.exportClause)) { + if (ts.isExportDeclaration(parent) && parent.exportClause && ts.isNamespaceExport(parent.exportClause)) { return parent.exportClause.name; } } @@ -968,18 +958,18 @@ namespace ts { // /**/import { propertyName as [|name|] } from ...; // /**/import ... from "[|module|]"; // /**/import "[|module|]"; - if (node.kind === SyntaxKind.ImportKeyword && isImportDeclaration(parent)) { + if (node.kind === ts.SyntaxKind.ImportKeyword && ts.isImportDeclaration(parent)) { const location = getAdjustedLocationForImportDeclaration(parent, forRename); if (location) { return location; } } - if (node.kind === SyntaxKind.ExportKeyword) { + if (node.kind === ts.SyntaxKind.ExportKeyword) { // /**/export { [|name|] } ...; // /**/export { propertyName as [|name|] } ...; // /**/export * from "[|module|]"; // /**/export * as ... from "[|module|]"; - if (isExportDeclaration(parent)) { + if (ts.isExportDeclaration(parent)) { const location = getAdjustedLocationForExportDeclaration(parent, forRename); if (location) { return location; @@ -988,17 +978,17 @@ namespace ts { // NOTE: We don't adjust the location of the `default` keyword as that is handled specially by `getSymbolAtLocation`. // /**/export default [|name|]; // /**/export = [|name|]; - if (isExportAssignment(parent)) { - return skipOuterExpressions(parent.expression); + if (ts.isExportAssignment(parent)) { + return ts.skipOuterExpressions(parent.expression); } } // import name = /**/require("[|module|]"); - if (node.kind === SyntaxKind.RequireKeyword && isExternalModuleReference(parent)) { + if (node.kind === ts.SyntaxKind.RequireKeyword && ts.isExternalModuleReference(parent)) { return parent.expression; } // import ... /**/from "[|module|]"; // export ... /**/from "[|module|]"; - if (node.kind === SyntaxKind.FromKeyword && (isImportDeclaration(parent) || isExportDeclaration(parent)) && parent.moduleSpecifier) { + if (node.kind === ts.SyntaxKind.FromKeyword && (ts.isImportDeclaration(parent) || ts.isExportDeclaration(parent)) && parent.moduleSpecifier) { return parent.moduleSpecifier; } // class ... /**/extends [|name|] ... @@ -1006,38 +996,38 @@ namespace ts { // class ... /**/implements name1, name2 ... // interface ... /**/extends [|name|] ... // interface ... /**/extends name1, name2 ... - if ((node.kind === SyntaxKind.ExtendsKeyword || node.kind === SyntaxKind.ImplementsKeyword) && isHeritageClause(parent) && parent.token === node.kind) { + if ((node.kind === ts.SyntaxKind.ExtendsKeyword || node.kind === ts.SyntaxKind.ImplementsKeyword) && ts.isHeritageClause(parent) && parent.token === node.kind) { const location = getAdjustedLocationForHeritageClause(parent); if (location) { return location; } } - if (node.kind === SyntaxKind.ExtendsKeyword) { + if (node.kind === ts.SyntaxKind.ExtendsKeyword) { // ... ... - if (isTypeParameterDeclaration(parent) && parent.constraint && isTypeReferenceNode(parent.constraint)) { + if (ts.isTypeParameterDeclaration(parent) && parent.constraint && ts.isTypeReferenceNode(parent.constraint)) { return parent.constraint.typeName; } // ... T /**/extends [|U|] ? ... - if (isConditionalTypeNode(parent) && isTypeReferenceNode(parent.extendsType)) { + if (ts.isConditionalTypeNode(parent) && ts.isTypeReferenceNode(parent.extendsType)) { return parent.extendsType.typeName; } } // ... T extends /**/infer [|U|] ? ... - if (node.kind === SyntaxKind.InferKeyword && isInferTypeNode(parent)) { + if (node.kind === ts.SyntaxKind.InferKeyword && ts.isInferTypeNode(parent)) { return parent.typeParameter.name; } // { [ [|K|] /**/in keyof T]: ... } - if (node.kind === SyntaxKind.InKeyword && isTypeParameterDeclaration(parent) && isMappedTypeNode(parent.parent)) { + if (node.kind === ts.SyntaxKind.InKeyword && ts.isTypeParameterDeclaration(parent) && ts.isMappedTypeNode(parent.parent)) { return parent.name; } // /**/keyof [|T|] - if (node.kind === SyntaxKind.KeyOfKeyword && isTypeOperatorNode(parent) && parent.operator === SyntaxKind.KeyOfKeyword && - isTypeReferenceNode(parent.type)) { + if (node.kind === ts.SyntaxKind.KeyOfKeyword && ts.isTypeOperatorNode(parent) && parent.operator === ts.SyntaxKind.KeyOfKeyword && + ts.isTypeReferenceNode(parent.type)) { return parent.type.typeName; } // /**/readonly [|name|][] - if (node.kind === SyntaxKind.ReadonlyKeyword && isTypeOperatorNode(parent) && parent.operator === SyntaxKind.ReadonlyKeyword && - isArrayTypeNode(parent.type) && isTypeReferenceNode(parent.type.elementType)) { + if (node.kind === ts.SyntaxKind.ReadonlyKeyword && ts.isTypeOperatorNode(parent) && parent.operator === ts.SyntaxKind.ReadonlyKeyword && + ts.isArrayTypeNode(parent.type) && ts.isTypeReferenceNode(parent.type.elementType)) { return parent.type.elementType.typeName; } if (!forRename) { @@ -1051,30 +1041,30 @@ namespace ts { // /**/yield [|name|] // /**/yield obj.[|name|] // /**/delete obj.[|name|] - if (node.kind === SyntaxKind.NewKeyword && isNewExpression(parent) || - node.kind === SyntaxKind.VoidKeyword && isVoidExpression(parent) || - node.kind === SyntaxKind.TypeOfKeyword && isTypeOfExpression(parent) || - node.kind === SyntaxKind.AwaitKeyword && isAwaitExpression(parent) || - node.kind === SyntaxKind.YieldKeyword && isYieldExpression(parent) || - node.kind === SyntaxKind.DeleteKeyword && isDeleteExpression(parent)) { + if (node.kind === ts.SyntaxKind.NewKeyword && ts.isNewExpression(parent) || + node.kind === ts.SyntaxKind.VoidKeyword && ts.isVoidExpression(parent) || + node.kind === ts.SyntaxKind.TypeOfKeyword && ts.isTypeOfExpression(parent) || + node.kind === ts.SyntaxKind.AwaitKeyword && ts.isAwaitExpression(parent) || + node.kind === ts.SyntaxKind.YieldKeyword && ts.isYieldExpression(parent) || + node.kind === ts.SyntaxKind.DeleteKeyword && ts.isDeleteExpression(parent)) { if (parent.expression) { - return skipOuterExpressions(parent.expression); + return ts.skipOuterExpressions(parent.expression); } } // left /**/in [|name|] // left /**/instanceof [|name|] - if ((node.kind === SyntaxKind.InKeyword || node.kind === SyntaxKind.InstanceOfKeyword) && isBinaryExpression(parent) && parent.operatorToken === node) { - return skipOuterExpressions(parent.right); + if ((node.kind === ts.SyntaxKind.InKeyword || node.kind === ts.SyntaxKind.InstanceOfKeyword) && ts.isBinaryExpression(parent) && parent.operatorToken === node) { + return ts.skipOuterExpressions(parent.right); } // left /**/as [|name|] - if (node.kind === SyntaxKind.AsKeyword && isAsExpression(parent) && isTypeReferenceNode(parent.type)) { + if (node.kind === ts.SyntaxKind.AsKeyword && ts.isAsExpression(parent) && ts.isTypeReferenceNode(parent.type)) { return parent.type.typeName; } // for (... /**/in [|name|]) // for (... /**/of [|name|]) - if (node.kind === SyntaxKind.InKeyword && isForInStatement(parent) || - node.kind === SyntaxKind.OfKeyword && isForOfStatement(parent)) { - return skipOuterExpressions(parent.expression); + if (node.kind === ts.SyntaxKind.InKeyword && ts.isForInStatement(parent) || + node.kind === ts.SyntaxKind.OfKeyword && ts.isForOfStatement(parent)) { + return ts.skipOuterExpressions(parent.expression); } } return node; @@ -1084,14 +1074,14 @@ namespace ts { * Adjusts the location used for "find references" and "go to definition" when the cursor was not * on a property name. */ - export function getAdjustedReferenceLocation(node: Node): Node { + export function getAdjustedReferenceLocation(node: ts.Node): ts.Node { return getAdjustedLocation(node, /*forRename*/ false); } /** * Adjusts the location used for "rename" when the cursor was not on a property name. */ - export function getAdjustedRenameLocation(node: Node): Node { + export function getAdjustedRenameLocation(node: ts.Node): ts.Node { return getAdjustedLocation(node, /*forRename*/ true); } @@ -1099,32 +1089,32 @@ namespace ts { * Gets the token whose text has range [start, end) and * position >= start and (position < end or (position === end && token is literal or keyword or identifier)) */ - export function getTouchingPropertyName(sourceFile: SourceFile, position: number): Node { - return getTouchingToken(sourceFile, position, n => isPropertyNameLiteral(n) || isKeyword(n.kind) || isPrivateIdentifier(n)); + export function getTouchingPropertyName(sourceFile: ts.SourceFile, position: number): ts.Node { + return getTouchingToken(sourceFile, position, n => ts.isPropertyNameLiteral(n) || ts.isKeyword(n.kind) || ts.isPrivateIdentifier(n)); } /** * Returns the token if position is in [start, end). * If position === end, returns the preceding token if includeItemAtEndPosition(previousToken) === true */ - export function getTouchingToken(sourceFile: SourceFile, position: number, includePrecedingTokenAtEndPosition?: (n: Node) => boolean): Node { + export function getTouchingToken(sourceFile: ts.SourceFile, position: number, includePrecedingTokenAtEndPosition?: (n: ts.Node) => boolean): ts.Node { return getTokenAtPositionWorker(sourceFile, position, /*allowPositionInLeadingTrivia*/ false, includePrecedingTokenAtEndPosition, /*includeEndPosition*/ false); } /** Returns a token if position is in [start-of-leading-trivia, end) */ - export function getTokenAtPosition(sourceFile: SourceFile, position: number): Node { + export function getTokenAtPosition(sourceFile: ts.SourceFile, position: number): ts.Node { return getTokenAtPositionWorker(sourceFile, position, /*allowPositionInLeadingTrivia*/ true, /*includePrecedingTokenAtEndPosition*/ undefined, /*includeEndPosition*/ false); } /** Get the token whose text contains the position */ - function getTokenAtPositionWorker(sourceFile: SourceFile, position: number, allowPositionInLeadingTrivia: boolean, includePrecedingTokenAtEndPosition: ((n: Node) => boolean) | undefined, includeEndPosition: boolean): Node { - let current: Node = sourceFile; - let foundToken: Node | undefined; + function getTokenAtPositionWorker(sourceFile: ts.SourceFile, position: number, allowPositionInLeadingTrivia: boolean, includePrecedingTokenAtEndPosition: ((n: ts.Node) => boolean) | undefined, includeEndPosition: boolean): ts.Node { + let current: ts.Node = sourceFile; + let foundToken: ts.Node | undefined; outer: while (true) { // find the child that contains 'position' const children = current.getChildren(sourceFile); - const i = binarySearchKey(children, position, (_, i) => i, (middle, _) => { + const i = ts.binarySearchKey(children, position, (_, i) => i, (middle, _) => { // This last callback is more of a selector than a comparator - // `EqualTo` causes the `middle` result to be returned // `GreaterThan` causes recursion on the left of the middle @@ -1149,7 +1139,7 @@ namespace ts { const start = allowPositionInLeadingTrivia ? children[middle].getFullStart() : children[middle].getStart(sourceFile, /*includeJsDoc*/ true); if (start > position) { - return Comparison.GreaterThan; + return ts.Comparison.GreaterThan; } // first element whose start position is before the input and whose end position is after or equal to the input @@ -1157,17 +1147,17 @@ namespace ts { if (children[middle - 1]) { // we want the _first_ element that contains the position, so left-recur if the prior node also contains the position if (nodeContainsPosition(children[middle - 1])) { - return Comparison.GreaterThan; + return ts.Comparison.GreaterThan; } } - return Comparison.EqualTo; + return ts.Comparison.EqualTo; } // this complex condition makes us left-recur around a zero-length node when includePrecedingTokenAtEndPosition is set, rather than right-recur on it if (includePrecedingTokenAtEndPosition && start === position && children[middle - 1] && children[middle - 1].getEnd() === position && nodeContainsPosition(children[middle - 1])) { - return Comparison.GreaterThan; + return ts.Comparison.GreaterThan; } - return Comparison.LessThan; + return ts.Comparison.LessThan; }); if (foundToken) { @@ -1181,14 +1171,14 @@ namespace ts { return current; } - function nodeContainsPosition(node: Node) { + function nodeContainsPosition(node: ts.Node) { const start = allowPositionInLeadingTrivia ? node.getFullStart() : node.getStart(sourceFile, /*includeJsDoc*/ true); if (start > position) { // If this child begins after position, then all subsequent children will as well. return false; } const end = node.getEnd(); - if (position < end || (position === end && (node.kind === SyntaxKind.EndOfFileToken || includeEndPosition))) { + if (position < end || (position === end && (node.kind === ts.SyntaxKind.EndOfFileToken || includeEndPosition))) { return true; } else if (includePrecedingTokenAtEndPosition && end === position) { @@ -1206,11 +1196,12 @@ namespace ts { * Returns the first token where position is in [start, end), * excluding `JsxText` tokens containing only whitespace. */ - export function findFirstNonJsxWhitespaceToken(sourceFile: SourceFile, position: number): Node | undefined { + export function findFirstNonJsxWhitespaceToken(sourceFile: ts.SourceFile, position: number): ts.Node | undefined { let tokenAtPosition = getTokenAtPosition(sourceFile, position); while (isWhiteSpaceOnlyJsxText(tokenAtPosition)) { const nextToken = findNextToken(tokenAtPosition, tokenAtPosition.parent, sourceFile); - if (!nextToken) return; + if (!nextToken) + return; tokenAtPosition = nextToken; } return tokenAtPosition; @@ -1224,26 +1215,26 @@ namespace ts { * foo |bar -> will return foo * */ - export function findTokenOnLeftOfPosition(file: SourceFile, position: number): Node | undefined { + export function findTokenOnLeftOfPosition(file: ts.SourceFile, position: number): ts.Node | undefined { // Ideally, getTokenAtPosition should return a token. However, it is currently // broken, so we do a check to make sure the result was indeed a token. const tokenAtPosition = getTokenAtPosition(file, position); - if (isToken(tokenAtPosition) && position > tokenAtPosition.getStart(file) && position < tokenAtPosition.getEnd()) { + if (ts.isToken(tokenAtPosition) && position > tokenAtPosition.getStart(file) && position < tokenAtPosition.getEnd()) { return tokenAtPosition; } return findPrecedingToken(position, file); } - export function findNextToken(previousToken: Node, parent: Node, sourceFile: SourceFileLike): Node | undefined { + export function findNextToken(previousToken: ts.Node, parent: ts.Node, sourceFile: ts.SourceFileLike): ts.Node | undefined { return find(parent); - function find(n: Node): Node | undefined { - if (isToken(n) && n.pos === previousToken.end) { + function find(n: ts.Node): ts.Node | undefined { + if (ts.isToken(n) && n.pos === previousToken.end) { // this is token that starts at the end of previous token - return it return n; } - return firstDefined(n.getChildren(sourceFile), child => { + return ts.firstDefined(n.getChildren(sourceFile), child => { const shouldDiveInChildNode = // previous token is enclosed somewhere in the child (child.pos <= previousToken.pos && child.end > previousToken.end) || @@ -1258,20 +1249,20 @@ namespace ts { * Finds the rightmost token satisfying `token.end <= position`, * excluding `JsxText` tokens containing only whitespace. */ - export function findPrecedingToken(position: number, sourceFile: SourceFileLike, startNode: Node, excludeJsdoc?: boolean): Node | undefined; - export function findPrecedingToken(position: number, sourceFile: SourceFile, startNode?: Node, excludeJsdoc?: boolean): Node | undefined; - export function findPrecedingToken(position: number, sourceFile: SourceFileLike, startNode?: Node, excludeJsdoc?: boolean): Node | undefined { - const result = find((startNode || sourceFile) as Node); - Debug.assert(!(result && isWhiteSpaceOnlyJsxText(result))); + export function findPrecedingToken(position: number, sourceFile: ts.SourceFileLike, startNode: ts.Node, excludeJsdoc?: boolean): ts.Node | undefined; + export function findPrecedingToken(position: number, sourceFile: ts.SourceFile, startNode?: ts.Node, excludeJsdoc?: boolean): ts.Node | undefined; + export function findPrecedingToken(position: number, sourceFile: ts.SourceFileLike, startNode?: ts.Node, excludeJsdoc?: boolean): ts.Node | undefined { + const result = find((startNode || sourceFile) as ts.Node); + ts.Debug.assert(!(result && isWhiteSpaceOnlyJsxText(result))); return result; - function find(n: Node): Node | undefined { - if (isNonWhitespaceToken(n) && n.kind !== SyntaxKind.EndOfFileToken) { + function find(n: ts.Node): ts.Node | undefined { + if (isNonWhitespaceToken(n) && n.kind !== ts.SyntaxKind.EndOfFileToken) { return n; } const children = n.getChildren(sourceFile); - const i = binarySearchKey(children, position, (_, i) => i, (middle, _) => { + const i = ts.binarySearchKey(children, position, (_, i) => i, (middle, _) => { // This last callback is more of a selector than a comparator - // `EqualTo` causes the `middle` result to be returned // `GreaterThan` causes recursion on the left of the middle @@ -1279,11 +1270,11 @@ namespace ts { if (position < children[middle].end) { // first element whose end position is greater than the input position if (!children[middle - 1] || position >= children[middle - 1].end) { - return Comparison.EqualTo; + return ts.Comparison.EqualTo; } - return Comparison.GreaterThan; + return ts.Comparison.GreaterThan; } - return Comparison.LessThan; + return ts.Comparison.LessThan; }); if (i >= 0 && children[i]) { const child = children[i]; @@ -1294,8 +1285,7 @@ namespace ts { // 2) `position` is within the same span: we recurse on `child`. if (position < child.end) { const start = child.getStart(sourceFile, /*includeJsDoc*/ !excludeJsdoc); - const lookInPreviousChild = - (start >= position) || // cursor in the leading trivia + const lookInPreviousChild = (start >= position) || // cursor in the leading trivia !nodeHasTokens(child, sourceFile) || isWhiteSpaceOnlyJsxText(child); @@ -1311,7 +1301,7 @@ namespace ts { } } - Debug.assert(startNode !== undefined || n.kind === SyntaxKind.SourceFile || n.kind === SyntaxKind.EndOfFileToken || isJSDocCommentContainingNode(n)); + ts.Debug.assert(startNode !== undefined || n.kind === ts.SyntaxKind.SourceFile || n.kind === ts.SyntaxKind.EndOfFileToken || ts.isJSDocCommentContainingNode(n)); // Here we know that none of child token nodes embrace the position, // the only known case is when position is at the end of the file. @@ -1322,11 +1312,11 @@ namespace ts { } } - function isNonWhitespaceToken(n: Node): boolean { - return isToken(n) && !isWhiteSpaceOnlyJsxText(n); + function isNonWhitespaceToken(n: ts.Node): boolean { + return ts.isToken(n) && !isWhiteSpaceOnlyJsxText(n); } - function findRightmostToken(n: Node, sourceFile: SourceFileLike): Node | undefined { + function findRightmostToken(n: ts.Node, sourceFile: ts.SourceFileLike): ts.Node | undefined { if (isNonWhitespaceToken(n)) { return n; } @@ -1343,13 +1333,13 @@ namespace ts { /** * Finds the rightmost child to the left of `children[exclusiveStartPosition]` which is a non-all-whitespace token or has constituent tokens. */ - function findRightmostChildNodeWithTokens(children: Node[], exclusiveStartPosition: number, sourceFile: SourceFileLike, parentKind: SyntaxKind): Node | undefined { + function findRightmostChildNodeWithTokens(children: ts.Node[], exclusiveStartPosition: number, sourceFile: ts.SourceFileLike, parentKind: ts.SyntaxKind): ts.Node | undefined { for (let i = exclusiveStartPosition - 1; i >= 0; i--) { const child = children[i]; if (isWhiteSpaceOnlyJsxText(child)) { - if (i === 0 && (parentKind === SyntaxKind.JsxText || parentKind === SyntaxKind.JsxSelfClosingElement)) { - Debug.fail("`JsxText` tokens should not be the first child of `JsxElement | JsxSelfClosingElement`"); + if (i === 0 && (parentKind === ts.SyntaxKind.JsxText || parentKind === ts.SyntaxKind.JsxSelfClosingElement)) { + ts.Debug.fail("`JsxText` tokens should not be the first child of `JsxElement | JsxSelfClosingElement`"); } } else if (nodeHasTokens(children[i], sourceFile)) { @@ -1358,8 +1348,8 @@ namespace ts { } } - export function isInString(sourceFile: SourceFile, position: number, previousToken = findPrecedingToken(position, sourceFile)): boolean { - if (previousToken && isStringTextContainingNode(previousToken)) { + export function isInString(sourceFile: ts.SourceFile, position: number, previousToken = findPrecedingToken(position, sourceFile)): boolean { + if (previousToken && ts.isStringTextContainingNode(previousToken)) { const start = previousToken.getStart(sourceFile); const end = previousToken.getEnd(); @@ -1372,7 +1362,7 @@ namespace ts { } if (position === end) { - return !!(previousToken as LiteralExpression).isUnterminated; + return !!(previousToken as ts.LiteralExpression).isUnterminated; } } @@ -1382,80 +1372,81 @@ namespace ts { /** * returns true if the position is in between the open and close elements of an JSX expression. */ - export function isInsideJsxElementOrAttribute(sourceFile: SourceFile, position: number) { + export function isInsideJsxElementOrAttribute(sourceFile: ts.SourceFile, position: number) { const token = getTokenAtPosition(sourceFile, position); if (!token) { return false; } - if (token.kind === SyntaxKind.JsxText) { + if (token.kind === ts.SyntaxKind.JsxText) { return true; } //
Hello |
- if (token.kind === SyntaxKind.LessThanToken && token.parent.kind === SyntaxKind.JsxText) { + if (token.kind === ts.SyntaxKind.LessThanToken && token.parent.kind === ts.SyntaxKind.JsxText) { return true; } //
{ |
or
- if (token.kind === SyntaxKind.LessThanToken && token.parent.kind === SyntaxKind.JsxExpression) { + if (token.kind === ts.SyntaxKind.LessThanToken && token.parent.kind === ts.SyntaxKind.JsxExpression) { return true; } //
{ // | // } < /div> - if (token && token.kind === SyntaxKind.CloseBraceToken && token.parent.kind === SyntaxKind.JsxExpression) { + if (token && token.kind === ts.SyntaxKind.CloseBraceToken && token.parent.kind === ts.SyntaxKind.JsxExpression) { return true; } //
|
- if (token.kind === SyntaxKind.LessThanToken && token.parent.kind === SyntaxKind.JsxClosingElement) { + if (token.kind === ts.SyntaxKind.LessThanToken && token.parent.kind === ts.SyntaxKind.JsxClosingElement) { return true; } return false; } - function isWhiteSpaceOnlyJsxText(node: Node): boolean { - return isJsxText(node) && node.containsOnlyTriviaWhiteSpaces; + function isWhiteSpaceOnlyJsxText(node: ts.Node): boolean { + return ts.isJsxText(node) && node.containsOnlyTriviaWhiteSpaces; } - export function isInTemplateString(sourceFile: SourceFile, position: number) { + export function isInTemplateString(sourceFile: ts.SourceFile, position: number) { const token = getTokenAtPosition(sourceFile, position); - return isTemplateLiteralKind(token.kind) && position > token.getStart(sourceFile); + return ts.isTemplateLiteralKind(token.kind) && position > token.getStart(sourceFile); } - export function isInJSXText(sourceFile: SourceFile, position: number) { + export function isInJSXText(sourceFile: ts.SourceFile, position: number) { const token = getTokenAtPosition(sourceFile, position); - if (isJsxText(token)) { + if (ts.isJsxText(token)) { return true; } - if (token.kind === SyntaxKind.OpenBraceToken && isJsxExpression(token.parent) && isJsxElement(token.parent.parent)) { + if (token.kind === ts.SyntaxKind.OpenBraceToken && ts.isJsxExpression(token.parent) && ts.isJsxElement(token.parent.parent)) { return true; } - if (token.kind === SyntaxKind.LessThanToken && isJsxOpeningLikeElement(token.parent) && isJsxElement(token.parent.parent)) { + if (token.kind === ts.SyntaxKind.LessThanToken && ts.isJsxOpeningLikeElement(token.parent) && ts.isJsxElement(token.parent.parent)) { return true; } return false; } - export function isInsideJsxElement(sourceFile: SourceFile, position: number): boolean { - function isInsideJsxElementTraversal(node: Node): boolean { + export function isInsideJsxElement(sourceFile: ts.SourceFile, position: number): boolean { + function isInsideJsxElementTraversal(node: ts.Node): boolean { while (node) { - if (node.kind >= SyntaxKind.JsxSelfClosingElement && node.kind <= SyntaxKind.JsxExpression - || node.kind === SyntaxKind.JsxText - || node.kind === SyntaxKind.LessThanToken - || node.kind === SyntaxKind.GreaterThanToken - || node.kind === SyntaxKind.Identifier - || node.kind === SyntaxKind.CloseBraceToken - || node.kind === SyntaxKind.OpenBraceToken - || node.kind === SyntaxKind.SlashToken) { + if (node.kind >= ts.SyntaxKind.JsxSelfClosingElement && node.kind <= ts.SyntaxKind.JsxExpression + || node.kind === ts.SyntaxKind.JsxText + || node.kind === ts.SyntaxKind.LessThanToken + || node.kind === ts.SyntaxKind.GreaterThanToken + || node.kind === ts.SyntaxKind.Identifier + || node.kind === ts.SyntaxKind.CloseBraceToken + || node.kind === ts.SyntaxKind.OpenBraceToken + || node.kind === ts.SyntaxKind.SlashToken) { node = node.parent; } - else if (node.kind === SyntaxKind.JsxElement) { - if (position > node.getStart(sourceFile)) return true; + else if (node.kind === ts.SyntaxKind.JsxElement) { + if (position > node.getStart(sourceFile)) + return true; node = node.parent; } @@ -1470,9 +1461,9 @@ namespace ts { return isInsideJsxElementTraversal(getTokenAtPosition(sourceFile, position)); } - export function findPrecedingMatchingToken(token: Node, matchingTokenKind: SyntaxKind.OpenBraceToken | SyntaxKind.OpenParenToken | SyntaxKind.OpenBracketToken, sourceFile: SourceFile) { - const closeTokenText = tokenToString(token.kind)!; - const matchingTokenText = tokenToString(matchingTokenKind)!; + export function findPrecedingMatchingToken(token: ts.Node, matchingTokenKind: ts.SyntaxKind.OpenBraceToken | ts.SyntaxKind.OpenParenToken | ts.SyntaxKind.OpenBracketToken, sourceFile: ts.SourceFile) { + const closeTokenText = ts.tokenToString(token.kind)!; + const matchingTokenText = ts.tokenToString(matchingTokenKind)!; const tokenFullStart = token.getFullStart(); // Text-scan based fast path - can be bamboozled by comments and other trivia, but often provides // a good, fast approximation without too much extra work in the cases where it fails. @@ -1509,31 +1500,31 @@ namespace ts { } } - export function removeOptionality(type: Type, isOptionalExpression: boolean, isOptionalChain: boolean) { + export function removeOptionality(type: ts.Type, isOptionalExpression: boolean, isOptionalChain: boolean) { return isOptionalExpression ? type.getNonNullableType() : isOptionalChain ? type.getNonOptionalType() : type; } - export function isPossiblyTypeArgumentPosition(token: Node, sourceFile: SourceFile, checker: TypeChecker): boolean { + export function isPossiblyTypeArgumentPosition(token: ts.Node, sourceFile: ts.SourceFile, checker: ts.TypeChecker): boolean { const info = getPossibleTypeArgumentsInfo(token, sourceFile); - return info !== undefined && (isPartOfTypeNode(info.called) || + return info !== undefined && (ts.isPartOfTypeNode(info.called) || getPossibleGenericSignatures(info.called, info.nTypeArguments, checker).length !== 0 || isPossiblyTypeArgumentPosition(info.called, sourceFile, checker)); } - export function getPossibleGenericSignatures(called: Expression, typeArgumentCount: number, checker: TypeChecker): readonly Signature[] { + export function getPossibleGenericSignatures(called: ts.Expression, typeArgumentCount: number, checker: ts.TypeChecker): readonly ts.Signature[] { let type = checker.getTypeAtLocation(called); - if (isOptionalChain(called.parent)) { - type = removeOptionality(type, isOptionalChainRoot(called.parent), /*isOptionalChain*/ true); + if (ts.isOptionalChain(called.parent)) { + type = removeOptionality(type, ts.isOptionalChainRoot(called.parent), /*isOptionalChain*/ true); } - const signatures = isNewExpression(called.parent) ? type.getConstructSignatures() : type.getCallSignatures(); + const signatures = ts.isNewExpression(called.parent) ? type.getConstructSignatures() : type.getCallSignatures(); return signatures.filter(candidate => !!candidate.typeParameters && candidate.typeParameters.length >= typeArgumentCount); } export interface PossibleTypeArgumentInfo { - readonly called: Identifier; + readonly called: ts.Identifier; readonly nTypeArguments: number; } @@ -1542,7 +1533,7 @@ namespace ts { } // Get info for an expression like `f <` that may be the start of type arguments. - export function getPossibleTypeArgumentsInfo(tokenIn: Node | undefined, sourceFile: SourceFile): PossibleTypeArgumentInfo | undefined { + export function getPossibleTypeArgumentsInfo(tokenIn: ts.Node | undefined, sourceFile: ts.SourceFile): PossibleTypeArgumentInfo | undefined { // This is a rare case, but one that saves on a _lot_ of work if true - if the source file has _no_ `<` character, // then there obviously can't be any type arguments - no expensive brace-matching backwards scanning required @@ -1550,7 +1541,7 @@ namespace ts { return undefined; } - let token: Node | undefined = tokenIn; + let token: ts.Node | undefined = tokenIn; // This function determines if the node could be type argument position // Since during editing, when type argument list is not complete, // the tree could be of any shape depending on the tokens parsed before current node, @@ -1560,79 +1551,83 @@ namespace ts { let nTypeArguments = 0; while (token) { switch (token.kind) { - case SyntaxKind.LessThanToken: + case ts.SyntaxKind.LessThanToken: // Found the beginning of the generic argument expression token = findPrecedingToken(token.getFullStart(), sourceFile); - if (token && token.kind === SyntaxKind.QuestionDotToken) { + if (token && token.kind === ts.SyntaxKind.QuestionDotToken) { token = findPrecedingToken(token.getFullStart(), sourceFile); } - if (!token || !isIdentifier(token)) return undefined; + if (!token || !ts.isIdentifier(token)) + return undefined; if (!remainingLessThanTokens) { - return isDeclarationName(token) ? undefined : { called: token, nTypeArguments }; + return ts.isDeclarationName(token) ? undefined : { called: token, nTypeArguments }; } remainingLessThanTokens--; break; - case SyntaxKind.GreaterThanGreaterThanGreaterThanToken: + case ts.SyntaxKind.GreaterThanGreaterThanGreaterThanToken: remainingLessThanTokens = + 3; break; - case SyntaxKind.GreaterThanGreaterThanToken: + case ts.SyntaxKind.GreaterThanGreaterThanToken: remainingLessThanTokens = + 2; break; - case SyntaxKind.GreaterThanToken: + case ts.SyntaxKind.GreaterThanToken: remainingLessThanTokens++; break; - case SyntaxKind.CloseBraceToken: + case ts.SyntaxKind.CloseBraceToken: // This can be object type, skip until we find the matching open brace token // Skip until the matching open brace token - token = findPrecedingMatchingToken(token, SyntaxKind.OpenBraceToken, sourceFile); - if (!token) return undefined; + token = findPrecedingMatchingToken(token, ts.SyntaxKind.OpenBraceToken, sourceFile); + if (!token) + return undefined; break; - case SyntaxKind.CloseParenToken: + case ts.SyntaxKind.CloseParenToken: // This can be object type, skip until we find the matching open brace token // Skip until the matching open brace token - token = findPrecedingMatchingToken(token, SyntaxKind.OpenParenToken, sourceFile); - if (!token) return undefined; + token = findPrecedingMatchingToken(token, ts.SyntaxKind.OpenParenToken, sourceFile); + if (!token) + return undefined; break; - case SyntaxKind.CloseBracketToken: + case ts.SyntaxKind.CloseBracketToken: // This can be object type, skip until we find the matching open brace token // Skip until the matching open brace token - token = findPrecedingMatchingToken(token, SyntaxKind.OpenBracketToken, sourceFile); - if (!token) return undefined; + token = findPrecedingMatchingToken(token, ts.SyntaxKind.OpenBracketToken, sourceFile); + if (!token) + return undefined; break; // Valid tokens in a type name. Skip. - case SyntaxKind.CommaToken: + case ts.SyntaxKind.CommaToken: nTypeArguments++; break; - case SyntaxKind.EqualsGreaterThanToken: + case ts.SyntaxKind.EqualsGreaterThanToken: // falls through - case SyntaxKind.Identifier: - case SyntaxKind.StringLiteral: - case SyntaxKind.NumericLiteral: - case SyntaxKind.BigIntLiteral: - case SyntaxKind.TrueKeyword: - case SyntaxKind.FalseKeyword: + case ts.SyntaxKind.Identifier: + case ts.SyntaxKind.StringLiteral: + case ts.SyntaxKind.NumericLiteral: + case ts.SyntaxKind.BigIntLiteral: + case ts.SyntaxKind.TrueKeyword: + case ts.SyntaxKind.FalseKeyword: // falls through - case SyntaxKind.TypeOfKeyword: - case SyntaxKind.ExtendsKeyword: - case SyntaxKind.KeyOfKeyword: - case SyntaxKind.DotToken: - case SyntaxKind.BarToken: - case SyntaxKind.QuestionToken: - case SyntaxKind.ColonToken: + case ts.SyntaxKind.TypeOfKeyword: + case ts.SyntaxKind.ExtendsKeyword: + case ts.SyntaxKind.KeyOfKeyword: + case ts.SyntaxKind.DotToken: + case ts.SyntaxKind.BarToken: + case ts.SyntaxKind.QuestionToken: + case ts.SyntaxKind.ColonToken: break; default: - if (isTypeNode(token)) { + if (ts.isTypeNode(token)) { break; } @@ -1652,106 +1647,111 @@ namespace ts { * @param tokenAtPosition Must equal `getTokenAtPosition(sourceFile, position) * @param predicate Additional predicate to test on the comment range. */ - export function isInComment(sourceFile: SourceFile, position: number, tokenAtPosition?: Node): CommentRange | undefined { - return formatting.getRangeOfEnclosingComment(sourceFile, position, /*precedingToken*/ undefined, tokenAtPosition); + export function isInComment(sourceFile: ts.SourceFile, position: number, tokenAtPosition?: ts.Node): ts.CommentRange | undefined { + return ts.formatting.getRangeOfEnclosingComment(sourceFile, position, /*precedingToken*/ undefined, tokenAtPosition); } - export function hasDocComment(sourceFile: SourceFile, position: number): boolean { + export function hasDocComment(sourceFile: ts.SourceFile, position: number): boolean { const token = getTokenAtPosition(sourceFile, position); - return !!findAncestor(token, isJSDoc); + return !!ts.findAncestor(token, ts.isJSDoc); } - function nodeHasTokens(n: Node, sourceFile: SourceFileLike): boolean { + function nodeHasTokens(n: ts.Node, sourceFile: ts.SourceFileLike): boolean { // If we have a token or node that has a non-zero width, it must have tokens. // Note: getWidth() does not take trivia into account. - return n.kind === SyntaxKind.EndOfFileToken ? !!(n as EndOfFileToken).jsDoc : n.getWidth(sourceFile) !== 0; + return n.kind === ts.SyntaxKind.EndOfFileToken ? !!(n as ts.EndOfFileToken).jsDoc : n.getWidth(sourceFile) !== 0; } - export function getNodeModifiers(node: Node, excludeFlags = ModifierFlags.None): string { + export function getNodeModifiers(node: ts.Node, excludeFlags = ts.ModifierFlags.None): string { const result: string[] = []; - const flags = isDeclaration(node) - ? getCombinedNodeFlagsAlwaysIncludeJSDoc(node) & ~excludeFlags - : ModifierFlags.None; - - if (flags & ModifierFlags.Private) result.push(ScriptElementKindModifier.privateMemberModifier); - if (flags & ModifierFlags.Protected) result.push(ScriptElementKindModifier.protectedMemberModifier); - if (flags & ModifierFlags.Public) result.push(ScriptElementKindModifier.publicMemberModifier); - if (flags & ModifierFlags.Static || isClassStaticBlockDeclaration(node)) result.push(ScriptElementKindModifier.staticModifier); - if (flags & ModifierFlags.Abstract) result.push(ScriptElementKindModifier.abstractModifier); - if (flags & ModifierFlags.Export) result.push(ScriptElementKindModifier.exportedModifier); - if (flags & ModifierFlags.Deprecated) result.push(ScriptElementKindModifier.deprecatedModifier); - if (node.flags & NodeFlags.Ambient) result.push(ScriptElementKindModifier.ambientModifier); - if (node.kind === SyntaxKind.ExportAssignment) result.push(ScriptElementKindModifier.exportedModifier); - - return result.length > 0 ? result.join(",") : ScriptElementKindModifier.none; - } - - export function getTypeArgumentOrTypeParameterList(node: Node): NodeArray | undefined { - if (node.kind === SyntaxKind.TypeReference || node.kind === SyntaxKind.CallExpression) { - return (node as CallExpression).typeArguments; - } - - if (isFunctionLike(node) || node.kind === SyntaxKind.ClassDeclaration || node.kind === SyntaxKind.InterfaceDeclaration) { - return (node as FunctionLikeDeclaration).typeParameters; + const flags = ts.isDeclaration(node) + ? ts.getCombinedNodeFlagsAlwaysIncludeJSDoc(node) & ~excludeFlags + : ts.ModifierFlags.None; + if (flags & ts.ModifierFlags.Private) + result.push(ts.ScriptElementKindModifier.privateMemberModifier); + if (flags & ts.ModifierFlags.Protected) + result.push(ts.ScriptElementKindModifier.protectedMemberModifier); + if (flags & ts.ModifierFlags.Public) + result.push(ts.ScriptElementKindModifier.publicMemberModifier); + if (flags & ts.ModifierFlags.Static || ts.isClassStaticBlockDeclaration(node)) + result.push(ts.ScriptElementKindModifier.staticModifier); + if (flags & ts.ModifierFlags.Abstract) + result.push(ts.ScriptElementKindModifier.abstractModifier); + if (flags & ts.ModifierFlags.Export) + result.push(ts.ScriptElementKindModifier.exportedModifier); + if (flags & ts.ModifierFlags.Deprecated) + result.push(ts.ScriptElementKindModifier.deprecatedModifier); + if (node.flags & ts.NodeFlags.Ambient) + result.push(ts.ScriptElementKindModifier.ambientModifier); + if (node.kind === ts.SyntaxKind.ExportAssignment) + result.push(ts.ScriptElementKindModifier.exportedModifier); + return result.length > 0 ? result.join(",") : ts.ScriptElementKindModifier.none; + } + export function getTypeArgumentOrTypeParameterList(node: ts.Node): ts.NodeArray | undefined { + if (node.kind === ts.SyntaxKind.TypeReference || node.kind === ts.SyntaxKind.CallExpression) { + return (node as ts.CallExpression).typeArguments; + } + if (ts.isFunctionLike(node) || node.kind === ts.SyntaxKind.ClassDeclaration || node.kind === ts.SyntaxKind.InterfaceDeclaration) { + return (node as ts.FunctionLikeDeclaration).typeParameters; } return undefined; } - export function isComment(kind: SyntaxKind): boolean { - return kind === SyntaxKind.SingleLineCommentTrivia || kind === SyntaxKind.MultiLineCommentTrivia; + export function isComment(kind: ts.SyntaxKind): boolean { + return kind === ts.SyntaxKind.SingleLineCommentTrivia || kind === ts.SyntaxKind.MultiLineCommentTrivia; } - export function isStringOrRegularExpressionOrTemplateLiteral(kind: SyntaxKind): boolean { - if (kind === SyntaxKind.StringLiteral - || kind === SyntaxKind.RegularExpressionLiteral - || isTemplateLiteralKind(kind)) { + export function isStringOrRegularExpressionOrTemplateLiteral(kind: ts.SyntaxKind): boolean { + if (kind === ts.SyntaxKind.StringLiteral + || kind === ts.SyntaxKind.RegularExpressionLiteral + || ts.isTemplateLiteralKind(kind)) { return true; } return false; } - export function isPunctuation(kind: SyntaxKind): boolean { - return SyntaxKind.FirstPunctuation <= kind && kind <= SyntaxKind.LastPunctuation; + export function isPunctuation(kind: ts.SyntaxKind): boolean { + return ts.SyntaxKind.FirstPunctuation <= kind && kind <= ts.SyntaxKind.LastPunctuation; } - export function isInsideTemplateLiteral(node: TemplateLiteralToken, position: number, sourceFile: SourceFile): boolean { - return isTemplateLiteralKind(node.kind) + export function isInsideTemplateLiteral(node: ts.TemplateLiteralToken, position: number, sourceFile: ts.SourceFile): boolean { + return ts.isTemplateLiteralKind(node.kind) && (node.getStart(sourceFile) < position && position < node.end) || (!!node.isUnterminated && position === node.end); } - export function isAccessibilityModifier(kind: SyntaxKind) { + export function isAccessibilityModifier(kind: ts.SyntaxKind) { switch (kind) { - case SyntaxKind.PublicKeyword: - case SyntaxKind.PrivateKeyword: - case SyntaxKind.ProtectedKeyword: + case ts.SyntaxKind.PublicKeyword: + case ts.SyntaxKind.PrivateKeyword: + case ts.SyntaxKind.ProtectedKeyword: return true; } return false; } - export function cloneCompilerOptions(options: CompilerOptions): CompilerOptions { - const result = clone(options); - setConfigFileInOptions(result, options && options.configFile); + export function cloneCompilerOptions(options: ts.CompilerOptions): ts.CompilerOptions { + const result = ts.clone(options); + ts.setConfigFileInOptions(result, options && options.configFile); return result; } - export function isArrayLiteralOrObjectLiteralDestructuringPattern(node: Node) { - if (node.kind === SyntaxKind.ArrayLiteralExpression || - node.kind === SyntaxKind.ObjectLiteralExpression) { + export function isArrayLiteralOrObjectLiteralDestructuringPattern(node: ts.Node) { + if (node.kind === ts.SyntaxKind.ArrayLiteralExpression || + node.kind === ts.SyntaxKind.ObjectLiteralExpression) { // [a,b,c] from: // [a, b, c] = someExpression; - if (node.parent.kind === SyntaxKind.BinaryExpression && - (node.parent as BinaryExpression).left === node && - (node.parent as BinaryExpression).operatorToken.kind === SyntaxKind.EqualsToken) { + if (node.parent.kind === ts.SyntaxKind.BinaryExpression && + (node.parent as ts.BinaryExpression).left === node && + (node.parent as ts.BinaryExpression).operatorToken.kind === ts.SyntaxKind.EqualsToken) { return true; } // [a, b, c] from: // for([a, b, c] of expression) - if (node.parent.kind === SyntaxKind.ForOfStatement && - (node.parent as ForOfStatement).initializer === node) { + if (node.parent.kind === ts.SyntaxKind.ForOfStatement && + (node.parent as ts.ForOfStatement).initializer === node) { return true; } @@ -1759,7 +1759,7 @@ namespace ts { // [x, [a, b, c] ] = someExpression // or // {x, a: {a, b, c} } = someExpression - if (isArrayLiteralOrObjectLiteralDestructuringPattern(node.parent.kind === SyntaxKind.PropertyAssignment ? node.parent.parent : node.parent)) { + if (isArrayLiteralOrObjectLiteralDestructuringPattern(node.parent.kind === ts.SyntaxKind.PropertyAssignment ? node.parent.parent : node.parent)) { return true; } } @@ -1767,110 +1767,112 @@ namespace ts { return false; } - export function isInReferenceComment(sourceFile: SourceFile, position: number): boolean { + export function isInReferenceComment(sourceFile: ts.SourceFile, position: number): boolean { return isInReferenceCommentWorker(sourceFile, position, /*shouldBeReference*/ true); } - export function isInNonReferenceComment(sourceFile: SourceFile, position: number): boolean { + export function isInNonReferenceComment(sourceFile: ts.SourceFile, position: number): boolean { return isInReferenceCommentWorker(sourceFile, position, /*shouldBeReference*/ false); } - function isInReferenceCommentWorker(sourceFile: SourceFile, position: number, shouldBeReference: boolean): boolean { + function isInReferenceCommentWorker(sourceFile: ts.SourceFile, position: number, shouldBeReference: boolean): boolean { const range = isInComment(sourceFile, position, /*tokenAtPosition*/ undefined); return !!range && shouldBeReference === tripleSlashDirectivePrefixRegex.test(sourceFile.text.substring(range.pos, range.end)); } - export function getReplacementSpanForContextToken(contextToken: Node | undefined) { - if (!contextToken) return undefined; + export function getReplacementSpanForContextToken(contextToken: ts.Node | undefined) { + if (!contextToken) + return undefined; switch (contextToken.kind) { - case SyntaxKind.StringLiteral: - case SyntaxKind.NoSubstitutionTemplateLiteral: - return createTextSpanFromStringLiteralLikeContent(contextToken as StringLiteralLike); + case ts.SyntaxKind.StringLiteral: + case ts.SyntaxKind.NoSubstitutionTemplateLiteral: + return createTextSpanFromStringLiteralLikeContent(contextToken as ts.StringLiteralLike); default: return createTextSpanFromNode(contextToken); } } - export function createTextSpanFromNode(node: Node, sourceFile?: SourceFile, endNode?: Node): TextSpan { - return createTextSpanFromBounds(node.getStart(sourceFile), (endNode || node).getEnd()); + export function createTextSpanFromNode(node: ts.Node, sourceFile?: ts.SourceFile, endNode?: ts.Node): ts.TextSpan { + return ts.createTextSpanFromBounds(node.getStart(sourceFile), (endNode || node).getEnd()); } - export function createTextSpanFromStringLiteralLikeContent(node: StringLiteralLike) { - if (node.isUnterminated) return undefined; - return createTextSpanFromBounds(node.getStart() + 1, node.getEnd() - 1); + export function createTextSpanFromStringLiteralLikeContent(node: ts.StringLiteralLike) { + if (node.isUnterminated) + return undefined; + return ts.createTextSpanFromBounds(node.getStart() + 1, node.getEnd() - 1); } - export function createTextRangeFromNode(node: Node, sourceFile: SourceFile): TextRange { - return createRange(node.getStart(sourceFile), node.end); + export function createTextRangeFromNode(node: ts.Node, sourceFile: ts.SourceFile): ts.TextRange { + return ts.createRange(node.getStart(sourceFile), node.end); } - export function createTextSpanFromRange(range: TextRange): TextSpan { - return createTextSpanFromBounds(range.pos, range.end); + export function createTextSpanFromRange(range: ts.TextRange): ts.TextSpan { + return ts.createTextSpanFromBounds(range.pos, range.end); } - export function createTextRangeFromSpan(span: TextSpan): TextRange { - return createRange(span.start, span.start + span.length); + export function createTextRangeFromSpan(span: ts.TextSpan): ts.TextRange { + return ts.createRange(span.start, span.start + span.length); } - export function createTextChangeFromStartLength(start: number, length: number, newText: string): TextChange { - return createTextChange(createTextSpan(start, length), newText); + export function createTextChangeFromStartLength(start: number, length: number, newText: string): ts.TextChange { + return createTextChange(ts.createTextSpan(start, length), newText); } - export function createTextChange(span: TextSpan, newText: string): TextChange { + export function createTextChange(span: ts.TextSpan, newText: string): ts.TextChange { return { span, newText }; } - export const typeKeywords: readonly SyntaxKind[] = [ - SyntaxKind.AnyKeyword, - SyntaxKind.AssertsKeyword, - SyntaxKind.BigIntKeyword, - SyntaxKind.BooleanKeyword, - SyntaxKind.FalseKeyword, - SyntaxKind.InferKeyword, - SyntaxKind.KeyOfKeyword, - SyntaxKind.NeverKeyword, - SyntaxKind.NullKeyword, - SyntaxKind.NumberKeyword, - SyntaxKind.ObjectKeyword, - SyntaxKind.ReadonlyKeyword, - SyntaxKind.StringKeyword, - SyntaxKind.SymbolKeyword, - SyntaxKind.TrueKeyword, - SyntaxKind.VoidKeyword, - SyntaxKind.UndefinedKeyword, - SyntaxKind.UniqueKeyword, - SyntaxKind.UnknownKeyword, + export const typeKeywords: readonly ts.SyntaxKind[] = [ + ts.SyntaxKind.AnyKeyword, + ts.SyntaxKind.AssertsKeyword, + ts.SyntaxKind.BigIntKeyword, + ts.SyntaxKind.BooleanKeyword, + ts.SyntaxKind.FalseKeyword, + ts.SyntaxKind.InferKeyword, + ts.SyntaxKind.KeyOfKeyword, + ts.SyntaxKind.NeverKeyword, + ts.SyntaxKind.NullKeyword, + ts.SyntaxKind.NumberKeyword, + ts.SyntaxKind.ObjectKeyword, + ts.SyntaxKind.ReadonlyKeyword, + ts.SyntaxKind.StringKeyword, + ts.SyntaxKind.SymbolKeyword, + ts.SyntaxKind.TrueKeyword, + ts.SyntaxKind.VoidKeyword, + ts.SyntaxKind.UndefinedKeyword, + ts.SyntaxKind.UniqueKeyword, + ts.SyntaxKind.UnknownKeyword, ]; - export function isTypeKeyword(kind: SyntaxKind): boolean { - return contains(typeKeywords, kind); + export function isTypeKeyword(kind: ts.SyntaxKind): boolean { + return ts.contains(typeKeywords, kind); } - export function isTypeKeywordToken(node: Node): node is Token { - return node.kind === SyntaxKind.TypeKeyword; + export function isTypeKeywordToken(node: ts.Node): node is ts.Token { + return node.kind === ts.SyntaxKind.TypeKeyword; } - export function isTypeKeywordTokenOrIdentifier(node: Node) { - return isTypeKeywordToken(node) || isIdentifier(node) && node.text === "type"; + export function isTypeKeywordTokenOrIdentifier(node: ts.Node) { + return isTypeKeywordToken(node) || ts.isIdentifier(node) && node.text === "type"; } /** True if the symbol is for an external module, as opposed to a namespace. */ - export function isExternalModuleSymbol(moduleSymbol: Symbol): boolean { - return !!(moduleSymbol.flags & SymbolFlags.Module) && moduleSymbol.name.charCodeAt(0) === CharacterCodes.doubleQuote; + export function isExternalModuleSymbol(moduleSymbol: ts.Symbol): boolean { + return !!(moduleSymbol.flags & ts.SymbolFlags.Module) && moduleSymbol.name.charCodeAt(0) === ts.CharacterCodes.doubleQuote; } /** Returns `true` the first time it encounters a node and `false` afterwards. */ - export type NodeSeenTracker = (node: T) => boolean; - export function nodeSeenTracker(): NodeSeenTracker { + export type NodeSeenTracker = (node: T) => boolean; + export function nodeSeenTracker(): NodeSeenTracker { const seen: true[] = []; return node => { - const id = getNodeId(node); + const id = ts.getNodeId(node); return !seen[id] && (seen[id] = true); }; } - export function getSnapshotText(snap: IScriptSnapshot): string { + export function getSnapshotText(snap: ts.IScriptSnapshot): string { return snap.getText(0, snap.getLength()); } @@ -1882,95 +1884,95 @@ namespace ts { return result; } - export function skipConstraint(type: Type): Type { + export function skipConstraint(type: ts.Type): ts.Type { return type.isTypeParameter() ? type.getConstraint() || type : type; } - export function getNameFromPropertyName(name: PropertyName): string | undefined { - return name.kind === SyntaxKind.ComputedPropertyName + export function getNameFromPropertyName(name: ts.PropertyName): string | undefined { + return name.kind === ts.SyntaxKind.ComputedPropertyName // treat computed property names where expression is string/numeric literal as just string/numeric literal - ? isStringOrNumericLiteralLike(name.expression) ? name.expression.text : undefined - : isPrivateIdentifier(name) ? idText(name) : getTextOfIdentifierOrLiteral(name); + ? ts.isStringOrNumericLiteralLike(name.expression) ? name.expression.text : undefined + : ts.isPrivateIdentifier(name) ? ts.idText(name) : ts.getTextOfIdentifierOrLiteral(name); } - export function programContainsModules(program: Program): boolean { + export function programContainsModules(program: ts.Program): boolean { return program.getSourceFiles().some(s => !s.isDeclarationFile && !program.isSourceFileFromExternalLibrary(s) && !!(s.externalModuleIndicator || s.commonJsModuleIndicator)); } - export function programContainsEsModules(program: Program): boolean { + export function programContainsEsModules(program: ts.Program): boolean { return program.getSourceFiles().some(s => !s.isDeclarationFile && !program.isSourceFileFromExternalLibrary(s) && !!s.externalModuleIndicator); } - export function compilerOptionsIndicateEsModules(compilerOptions: CompilerOptions): boolean { - return !!compilerOptions.module || getEmitScriptTarget(compilerOptions) >= ScriptTarget.ES2015 || !!compilerOptions.noEmit; + export function compilerOptionsIndicateEsModules(compilerOptions: ts.CompilerOptions): boolean { + return !!compilerOptions.module || ts.getEmitScriptTarget(compilerOptions) >= ts.ScriptTarget.ES2015 || !!compilerOptions.noEmit; } - export function createModuleSpecifierResolutionHost(program: Program, host: LanguageServiceHost): ModuleSpecifierResolutionHost { + export function createModuleSpecifierResolutionHost(program: ts.Program, host: ts.LanguageServiceHost): ts.ModuleSpecifierResolutionHost { // Mix in `getSymlinkCache` from Program when host doesn't have it // in order for non-Project hosts to have a symlinks cache. return { fileExists: fileName => program.fileExists(fileName), getCurrentDirectory: () => host.getCurrentDirectory(), - readFile: maybeBind(host, host.readFile), - useCaseSensitiveFileNames: maybeBind(host, host.useCaseSensitiveFileNames), - getSymlinkCache: maybeBind(host, host.getSymlinkCache) || program.getSymlinkCache, - getModuleSpecifierCache: maybeBind(host, host.getModuleSpecifierCache), + readFile: ts.maybeBind(host, host.readFile), + useCaseSensitiveFileNames: ts.maybeBind(host, host.useCaseSensitiveFileNames), + getSymlinkCache: ts.maybeBind(host, host.getSymlinkCache) || program.getSymlinkCache, + getModuleSpecifierCache: ts.maybeBind(host, host.getModuleSpecifierCache), getPackageJsonInfoCache: () => program.getModuleResolutionCache()?.getPackageJsonInfoCache(), - getGlobalTypingsCacheLocation: maybeBind(host, host.getGlobalTypingsCacheLocation), + getGlobalTypingsCacheLocation: ts.maybeBind(host, host.getGlobalTypingsCacheLocation), redirectTargetsMap: program.redirectTargetsMap, getProjectReferenceRedirect: fileName => program.getProjectReferenceRedirect(fileName), isSourceOfProjectReferenceRedirect: fileName => program.isSourceOfProjectReferenceRedirect(fileName), - getNearestAncestorDirectoryWithPackageJson: maybeBind(host, host.getNearestAncestorDirectoryWithPackageJson), + getNearestAncestorDirectoryWithPackageJson: ts.maybeBind(host, host.getNearestAncestorDirectoryWithPackageJson), getFileIncludeReasons: () => program.getFileIncludeReasons(), }; } - export function getModuleSpecifierResolverHost(program: Program, host: LanguageServiceHost): SymbolTracker["moduleResolverHost"] { + export function getModuleSpecifierResolverHost(program: ts.Program, host: ts.LanguageServiceHost): ts.SymbolTracker["moduleResolverHost"] { return { ...createModuleSpecifierResolutionHost(program, host), getCommonSourceDirectory: () => program.getCommonSourceDirectory(), }; } - export function moduleResolutionRespectsExports(moduleResolution: ModuleResolutionKind): boolean { - return moduleResolution >= ModuleResolutionKind.Node16 && moduleResolution <= ModuleResolutionKind.NodeNext; + export function moduleResolutionRespectsExports(moduleResolution: ts.ModuleResolutionKind): boolean { + return moduleResolution >= ts.ModuleResolutionKind.Node16 && moduleResolution <= ts.ModuleResolutionKind.NodeNext; } - export function moduleResolutionUsesNodeModules(moduleResolution: ModuleResolutionKind): boolean { - return moduleResolution === ModuleResolutionKind.NodeJs || moduleResolution >= ModuleResolutionKind.Node16 && moduleResolution <= ModuleResolutionKind.NodeNext; + export function moduleResolutionUsesNodeModules(moduleResolution: ts.ModuleResolutionKind): boolean { + return moduleResolution === ts.ModuleResolutionKind.NodeJs || moduleResolution >= ts.ModuleResolutionKind.Node16 && moduleResolution <= ts.ModuleResolutionKind.NodeNext; } - export function makeImportIfNecessary(defaultImport: Identifier | undefined, namedImports: readonly ImportSpecifier[] | undefined, moduleSpecifier: string, quotePreference: QuotePreference): ImportDeclaration | undefined { + export function makeImportIfNecessary(defaultImport: ts.Identifier | undefined, namedImports: readonly ts.ImportSpecifier[] | undefined, moduleSpecifier: string, quotePreference: QuotePreference): ts.ImportDeclaration | undefined { return defaultImport || namedImports && namedImports.length ? makeImport(defaultImport, namedImports, moduleSpecifier, quotePreference) : undefined; } - export function makeImport(defaultImport: Identifier | undefined, namedImports: readonly ImportSpecifier[] | undefined, moduleSpecifier: string | Expression, quotePreference: QuotePreference, isTypeOnly?: boolean): ImportDeclaration { - return factory.createImportDeclaration( + export function makeImport(defaultImport: ts.Identifier | undefined, namedImports: readonly ts.ImportSpecifier[] | undefined, moduleSpecifier: string | ts.Expression, quotePreference: QuotePreference, isTypeOnly?: boolean): ts.ImportDeclaration { + return ts.factory.createImportDeclaration( /*decorators*/ undefined, - /*modifiers*/ undefined, - defaultImport || namedImports - ? factory.createImportClause(!!isTypeOnly, defaultImport, namedImports && namedImports.length ? factory.createNamedImports(namedImports) : undefined) - : undefined, - typeof moduleSpecifier === "string" ? makeStringLiteral(moduleSpecifier, quotePreference) : moduleSpecifier, + /*modifiers*/ undefined, defaultImport || namedImports + ? ts.factory.createImportClause(!!isTypeOnly, defaultImport, namedImports && namedImports.length ? ts.factory.createNamedImports(namedImports) : undefined) + : undefined, typeof moduleSpecifier === "string" ? makeStringLiteral(moduleSpecifier, quotePreference) : moduleSpecifier, /*assertClause*/ undefined); } - export function makeStringLiteral(text: string, quotePreference: QuotePreference): StringLiteral { - return factory.createStringLiteral(text, quotePreference === QuotePreference.Single); + export function makeStringLiteral(text: string, quotePreference: QuotePreference): ts.StringLiteral { + return ts.factory.createStringLiteral(text, quotePreference === QuotePreference.Single); + } + export const enum QuotePreference { + Single, + Double } - export const enum QuotePreference { Single, Double } - - export function quotePreferenceFromString(str: StringLiteral, sourceFile: SourceFile): QuotePreference { - return isStringDoubleQuoted(str, sourceFile) ? QuotePreference.Double : QuotePreference.Single; + export function quotePreferenceFromString(str: ts.StringLiteral, sourceFile: ts.SourceFile): QuotePreference { + return ts.isStringDoubleQuoted(str, sourceFile) ? QuotePreference.Double : QuotePreference.Single; } - export function getQuotePreference(sourceFile: SourceFile, preferences: UserPreferences): QuotePreference { + export function getQuotePreference(sourceFile: ts.SourceFile, preferences: ts.UserPreferences): QuotePreference { if (preferences.quotePreference && preferences.quotePreference !== "auto") { return preferences.quotePreference === "single" ? QuotePreference.Single : QuotePreference.Double; } else { // ignore synthetic import added when importHelpers: true const firstModuleSpecifier = sourceFile.imports && - find(sourceFile.imports, n => isStringLiteral(n) && !nodeIsSynthesized(n.parent)) as StringLiteral; + ts.find(sourceFile.imports, n => ts.isStringLiteral(n) && !ts.nodeIsSynthesized(n.parent)) as ts.StringLiteral; return firstModuleSpecifier ? quotePreferenceFromString(firstModuleSpecifier, sourceFile) : QuotePreference.Double; } } @@ -1979,53 +1981,53 @@ namespace ts { switch (qp) { case QuotePreference.Single: return "'"; case QuotePreference.Double: return '"'; - default: return Debug.assertNever(qp); + default: return ts.Debug.assertNever(qp); } } - export function symbolNameNoDefault(symbol: Symbol): string | undefined { + export function symbolNameNoDefault(symbol: ts.Symbol): string | undefined { const escaped = symbolEscapedNameNoDefault(symbol); - return escaped === undefined ? undefined : unescapeLeadingUnderscores(escaped); + return escaped === undefined ? undefined : ts.unescapeLeadingUnderscores(escaped); } - export function symbolEscapedNameNoDefault(symbol: Symbol): __String | undefined { - if (symbol.escapedName !== InternalSymbolName.Default) { + export function symbolEscapedNameNoDefault(symbol: ts.Symbol): ts.__String | undefined { + if (symbol.escapedName !== ts.InternalSymbolName.Default) { return symbol.escapedName; } - return firstDefined(symbol.declarations, decl => { - const name = getNameOfDeclaration(decl); - return name && name.kind === SyntaxKind.Identifier ? name.escapedText : undefined; + return ts.firstDefined(symbol.declarations, decl => { + const name = ts.getNameOfDeclaration(decl); + return name && name.kind === ts.SyntaxKind.Identifier ? name.escapedText : undefined; }); } - export function isModuleSpecifierLike(node: Node): node is StringLiteralLike { - return isStringLiteralLike(node) && ( - isExternalModuleReference(node.parent) || - isImportDeclaration(node.parent) || - isRequireCall(node.parent, /*requireStringLiteralLikeArgument*/ false) && node.parent.arguments[0] === node || - isImportCall(node.parent) && node.parent.arguments[0] === node); + export function isModuleSpecifierLike(node: ts.Node): node is ts.StringLiteralLike { + return ts.isStringLiteralLike(node) && (ts.isExternalModuleReference(node.parent) || + ts.isImportDeclaration(node.parent) || + ts.isRequireCall(node.parent, /*requireStringLiteralLikeArgument*/ false) && node.parent.arguments[0] === node || + ts.isImportCall(node.parent) && node.parent.arguments[0] === node); } - - export type ObjectBindingElementWithoutPropertyName = BindingElement & { name: Identifier }; - - export function isObjectBindingElementWithoutPropertyName(bindingElement: Node): bindingElement is ObjectBindingElementWithoutPropertyName { - return isBindingElement(bindingElement) && - isObjectBindingPattern(bindingElement.parent) && - isIdentifier(bindingElement.name) && + export type ObjectBindingElementWithoutPropertyName = ts.BindingElement & { + name: ts.Identifier; + }; + export function isObjectBindingElementWithoutPropertyName(bindingElement: ts.Node): bindingElement is ObjectBindingElementWithoutPropertyName { + return ts.isBindingElement(bindingElement) && + ts.isObjectBindingPattern(bindingElement.parent) && + ts.isIdentifier(bindingElement.name) && !bindingElement.propertyName; } - export function getPropertySymbolFromBindingElement(checker: TypeChecker, bindingElement: ObjectBindingElementWithoutPropertyName): Symbol | undefined { + export function getPropertySymbolFromBindingElement(checker: ts.TypeChecker, bindingElement: ObjectBindingElementWithoutPropertyName): ts.Symbol | undefined { const typeOfPattern = checker.getTypeAtLocation(bindingElement.parent); return typeOfPattern && checker.getPropertyOfType(typeOfPattern, bindingElement.name.text); } - export function getParentNodeInSpan(node: Node | undefined, file: SourceFile, span: TextSpan): Node | undefined { - if (!node) return undefined; + export function getParentNodeInSpan(node: ts.Node | undefined, file: ts.SourceFile, span: ts.TextSpan): ts.Node | undefined { + if (!node) + return undefined; while (node.parent) { - if (isSourceFile(node.parent) || !spanContainsNode(span, node.parent, file)) { + if (ts.isSourceFile(node.parent) || !spanContainsNode(span, node.parent, file)) { return node; } @@ -2033,30 +2035,30 @@ namespace ts { } } - function spanContainsNode(span: TextSpan, node: Node, file: SourceFile): boolean { - return textSpanContainsPosition(span, node.getStart(file)) && - node.getEnd() <= textSpanEnd(span); + function spanContainsNode(span: ts.TextSpan, node: ts.Node, file: ts.SourceFile): boolean { + return ts.textSpanContainsPosition(span, node.getStart(file)) && + node.getEnd() <= ts.textSpanEnd(span); } - export function findModifier(node: Node, kind: Modifier["kind"]): Modifier | undefined { - return node.modifiers && find(node.modifiers, m => m.kind === kind); + export function findModifier(node: ts.Node, kind: ts.Modifier["kind"]): ts.Modifier | undefined { + return node.modifiers && ts.find(node.modifiers, m => m.kind === kind); } - export function insertImports(changes: textChanges.ChangeTracker, sourceFile: SourceFile, imports: AnyImportOrRequireStatement | readonly AnyImportOrRequireStatement[], blankLineBetween: boolean): void { - const decl = isArray(imports) ? imports[0] : imports; - const importKindPredicate: (node: Node) => node is AnyImportOrRequireStatement = decl.kind === SyntaxKind.VariableStatement ? isRequireVariableStatement : isAnyImportSyntax; - const existingImportStatements = filter(sourceFile.statements, importKindPredicate); - const sortedNewImports = isArray(imports) ? stableSort(imports, OrganizeImports.compareImportsOrRequireStatements) : [imports]; + export function insertImports(changes: ts.textChanges.ChangeTracker, sourceFile: ts.SourceFile, imports: ts.AnyImportOrRequireStatement | readonly ts.AnyImportOrRequireStatement[], blankLineBetween: boolean): void { + const decl = ts.isArray(imports) ? imports[0] : imports; + const importKindPredicate: (node: ts.Node) => node is ts.AnyImportOrRequireStatement = decl.kind === ts.SyntaxKind.VariableStatement ? ts.isRequireVariableStatement : ts.isAnyImportSyntax; + const existingImportStatements = ts.filter(sourceFile.statements, importKindPredicate); + const sortedNewImports = ts.isArray(imports) ? ts.stableSort(imports, ts.OrganizeImports.compareImportsOrRequireStatements) : [imports]; if (!existingImportStatements.length) { changes.insertNodesAtTopOfFile(sourceFile, sortedNewImports, blankLineBetween); } - else if (existingImportStatements && OrganizeImports.importsAreSorted(existingImportStatements)) { + else if (existingImportStatements && ts.OrganizeImports.importsAreSorted(existingImportStatements)) { for (const newImport of sortedNewImports) { - const insertionIndex = OrganizeImports.getImportDeclarationInsertionIndex(existingImportStatements, newImport); + const insertionIndex = ts.OrganizeImports.getImportDeclarationInsertionIndex(existingImportStatements, newImport); if (insertionIndex === 0) { // If the first import is top-of-file, insert after the leading comment which is likely the header. const options = existingImportStatements[0] === sourceFile.statements[0] ? - { leadingTriviaOption: textChanges.LeadingTriviaOption.Exclude } : {}; + { leadingTriviaOption: ts.textChanges.LeadingTriviaOption.Exclude } : {}; changes.insertNodeBefore(sourceFile, existingImportStatements[0], newImport, /*blankLineBetween*/ false, options); } else { @@ -2066,7 +2068,7 @@ namespace ts { } } else { - const lastExistingImport = lastOrUndefined(existingImportStatements); + const lastExistingImport = ts.lastOrUndefined(existingImportStatements); if (lastExistingImport) { changes.insertNodesAfter(sourceFile, lastExistingImport, sortedNewImports); } @@ -2076,15 +2078,15 @@ namespace ts { } } - export function getTypeKeywordOfTypeOnlyImport(importClause: ImportClause, sourceFile: SourceFile): Token { - Debug.assert(importClause.isTypeOnly); - return cast(importClause.getChildAt(0, sourceFile), isTypeKeywordToken); + export function getTypeKeywordOfTypeOnlyImport(importClause: ts.ImportClause, sourceFile: ts.SourceFile): ts.Token { + ts.Debug.assert(importClause.isTypeOnly); + return ts.cast(importClause.getChildAt(0, sourceFile), isTypeKeywordToken); } - export function textSpansEqual(a: TextSpan | undefined, b: TextSpan | undefined): boolean { + export function textSpansEqual(a: ts.TextSpan | undefined, b: ts.TextSpan | undefined): boolean { return !!a && !!b && a.start === b.start && a.length === b.length; } - export function documentSpansEqual(a: DocumentSpan, b: DocumentSpan): boolean { + export function documentSpansEqual(a: ts.DocumentSpan, b: ts.DocumentSpan): boolean { return a.fileName === b.fileName && textSpansEqual(a.textSpan, b.textSpan); } @@ -2109,7 +2111,7 @@ namespace ts { export function isTextWhiteSpaceLike(text: string, startPos: number, endPos: number): boolean { for (let i = startPos; i < endPos; i++) { - if (!isWhiteSpaceLike(text.charCodeAt(i))) { + if (!ts.isWhiteSpaceLike(text.charCodeAt(i))) { return false; } } @@ -2121,42 +2123,41 @@ namespace ts { // Display-part writer helpers // #region - export function isFirstDeclarationOfSymbolParameter(symbol: Symbol) { - const declaration = symbol.declarations ? firstOrUndefined(symbol.declarations) : undefined; - return !!findAncestor(declaration, n => - isParameter(n) ? true : isBindingElement(n) || isObjectBindingPattern(n) || isArrayBindingPattern(n) ? false : "quit"); + export function isFirstDeclarationOfSymbolParameter(symbol: ts.Symbol) { + const declaration = symbol.declarations ? ts.firstOrUndefined(symbol.declarations) : undefined; + return !!ts.findAncestor(declaration, n => ts.isParameter(n) ? true : ts.isBindingElement(n) || ts.isObjectBindingPattern(n) || ts.isArrayBindingPattern(n) ? false : "quit"); } const displayPartWriter = getDisplayPartWriter(); - function getDisplayPartWriter(): DisplayPartsSymbolWriter { - const absoluteMaximumLength = defaultMaximumTruncationLength * 10; // A hard cutoff to avoid overloading the messaging channel in worst-case scenarios - let displayParts: SymbolDisplayPart[]; + function getDisplayPartWriter(): ts.DisplayPartsSymbolWriter { + const absoluteMaximumLength = ts.defaultMaximumTruncationLength * 10; // A hard cutoff to avoid overloading the messaging channel in worst-case scenarios + let displayParts: ts.SymbolDisplayPart[]; let lineStart: boolean; let indent: number; let length: number; resetWriter(); - const unknownWrite = (text: string) => writeKind(text, SymbolDisplayPartKind.text); + const unknownWrite = (text: string) => writeKind(text, ts.SymbolDisplayPartKind.text); return { displayParts: () => { const finalText = displayParts.length && displayParts[displayParts.length - 1].text; if (length > absoluteMaximumLength && finalText && finalText !== "...") { - if (!isWhiteSpaceLike(finalText.charCodeAt(finalText.length - 1))) { - displayParts.push(displayPart(" ", SymbolDisplayPartKind.space)); + if (!ts.isWhiteSpaceLike(finalText.charCodeAt(finalText.length - 1))) { + displayParts.push(displayPart(" ", ts.SymbolDisplayPartKind.space)); } - displayParts.push(displayPart("...", SymbolDisplayPartKind.punctuation)); + displayParts.push(displayPart("...", ts.SymbolDisplayPartKind.punctuation)); } return displayParts; }, - writeKeyword: text => writeKind(text, SymbolDisplayPartKind.keyword), - writeOperator: text => writeKind(text, SymbolDisplayPartKind.operator), - writePunctuation: text => writeKind(text, SymbolDisplayPartKind.punctuation), - writeTrailingSemicolon: text => writeKind(text, SymbolDisplayPartKind.punctuation), - writeSpace: text => writeKind(text, SymbolDisplayPartKind.space), - writeStringLiteral: text => writeKind(text, SymbolDisplayPartKind.stringLiteral), - writeParameter: text => writeKind(text, SymbolDisplayPartKind.parameterName), - writeProperty: text => writeKind(text, SymbolDisplayPartKind.propertyName), - writeLiteral: text => writeKind(text, SymbolDisplayPartKind.stringLiteral), + writeKeyword: text => writeKind(text, ts.SymbolDisplayPartKind.keyword), + writeOperator: text => writeKind(text, ts.SymbolDisplayPartKind.operator), + writePunctuation: text => writeKind(text, ts.SymbolDisplayPartKind.punctuation), + writeTrailingSemicolon: text => writeKind(text, ts.SymbolDisplayPartKind.punctuation), + writeSpace: text => writeKind(text, ts.SymbolDisplayPartKind.space), + writeStringLiteral: text => writeKind(text, ts.SymbolDisplayPartKind.stringLiteral), + writeParameter: text => writeKind(text, ts.SymbolDisplayPartKind.parameterName), + writeProperty: text => writeKind(text, ts.SymbolDisplayPartKind.propertyName), + writeLiteral: text => writeKind(text, ts.SymbolDisplayPartKind.stringLiteral), writeSymbol, writeLine, write: unknownWrite, @@ -2168,45 +2169,49 @@ namespace ts { isAtStartOfLine: () => false, hasTrailingWhitespace: () => false, hasTrailingComment: () => false, - rawWrite: notImplemented, + rawWrite: ts.notImplemented, getIndent: () => indent, increaseIndent: () => { indent++; }, decreaseIndent: () => { indent--; }, clear: resetWriter, trackSymbol: () => false, - reportInaccessibleThisError: noop, - reportInaccessibleUniqueSymbolError: noop, - reportPrivateInBaseOfClassExpression: noop, + reportInaccessibleThisError: ts.noop, + reportInaccessibleUniqueSymbolError: ts.noop, + reportPrivateInBaseOfClassExpression: ts.noop, }; function writeIndent() { - if (length > absoluteMaximumLength) return; + if (length > absoluteMaximumLength) + return; if (lineStart) { - const indentString = getIndentString(indent); + const indentString = ts.getIndentString(indent); if (indentString) { length += indentString.length; - displayParts.push(displayPart(indentString, SymbolDisplayPartKind.space)); + displayParts.push(displayPart(indentString, ts.SymbolDisplayPartKind.space)); } lineStart = false; } } - function writeKind(text: string, kind: SymbolDisplayPartKind) { - if (length > absoluteMaximumLength) return; + function writeKind(text: string, kind: ts.SymbolDisplayPartKind) { + if (length > absoluteMaximumLength) + return; writeIndent(); length += text.length; displayParts.push(displayPart(text, kind)); } - function writeSymbol(text: string, symbol: Symbol) { - if (length > absoluteMaximumLength) return; + function writeSymbol(text: string, symbol: ts.Symbol) { + if (length > absoluteMaximumLength) + return; writeIndent(); length += text.length; displayParts.push(symbolPart(text, symbol)); } function writeLine() { - if (length > absoluteMaximumLength) return; + if (length > absoluteMaximumLength) + return; length += 1; displayParts.push(lineBreakPart()); lineStart = true; @@ -2220,102 +2225,113 @@ namespace ts { } } - export function symbolPart(text: string, symbol: Symbol) { + export function symbolPart(text: string, symbol: ts.Symbol) { return displayPart(text, displayPartKind(symbol)); - function displayPartKind(symbol: Symbol): SymbolDisplayPartKind { + function displayPartKind(symbol: ts.Symbol): ts.SymbolDisplayPartKind { const flags = symbol.flags; - if (flags & SymbolFlags.Variable) { - return isFirstDeclarationOfSymbolParameter(symbol) ? SymbolDisplayPartKind.parameterName : SymbolDisplayPartKind.localName; - } - if (flags & SymbolFlags.Property) return SymbolDisplayPartKind.propertyName; - if (flags & SymbolFlags.GetAccessor) return SymbolDisplayPartKind.propertyName; - if (flags & SymbolFlags.SetAccessor) return SymbolDisplayPartKind.propertyName; - if (flags & SymbolFlags.EnumMember) return SymbolDisplayPartKind.enumMemberName; - if (flags & SymbolFlags.Function) return SymbolDisplayPartKind.functionName; - if (flags & SymbolFlags.Class) return SymbolDisplayPartKind.className; - if (flags & SymbolFlags.Interface) return SymbolDisplayPartKind.interfaceName; - if (flags & SymbolFlags.Enum) return SymbolDisplayPartKind.enumName; - if (flags & SymbolFlags.Module) return SymbolDisplayPartKind.moduleName; - if (flags & SymbolFlags.Method) return SymbolDisplayPartKind.methodName; - if (flags & SymbolFlags.TypeParameter) return SymbolDisplayPartKind.typeParameterName; - if (flags & SymbolFlags.TypeAlias) return SymbolDisplayPartKind.aliasName; - if (flags & SymbolFlags.Alias) return SymbolDisplayPartKind.aliasName; - - return SymbolDisplayPartKind.text; - } - } - - export function displayPart(text: string, kind: SymbolDisplayPartKind): SymbolDisplayPart { - return { text, kind: SymbolDisplayPartKind[kind] }; + if (flags & ts.SymbolFlags.Variable) { + return isFirstDeclarationOfSymbolParameter(symbol) ? ts.SymbolDisplayPartKind.parameterName : ts.SymbolDisplayPartKind.localName; + } + if (flags & ts.SymbolFlags.Property) + return ts.SymbolDisplayPartKind.propertyName; + if (flags & ts.SymbolFlags.GetAccessor) + return ts.SymbolDisplayPartKind.propertyName; + if (flags & ts.SymbolFlags.SetAccessor) + return ts.SymbolDisplayPartKind.propertyName; + if (flags & ts.SymbolFlags.EnumMember) + return ts.SymbolDisplayPartKind.enumMemberName; + if (flags & ts.SymbolFlags.Function) + return ts.SymbolDisplayPartKind.functionName; + if (flags & ts.SymbolFlags.Class) + return ts.SymbolDisplayPartKind.className; + if (flags & ts.SymbolFlags.Interface) + return ts.SymbolDisplayPartKind.interfaceName; + if (flags & ts.SymbolFlags.Enum) + return ts.SymbolDisplayPartKind.enumName; + if (flags & ts.SymbolFlags.Module) + return ts.SymbolDisplayPartKind.moduleName; + if (flags & ts.SymbolFlags.Method) + return ts.SymbolDisplayPartKind.methodName; + if (flags & ts.SymbolFlags.TypeParameter) + return ts.SymbolDisplayPartKind.typeParameterName; + if (flags & ts.SymbolFlags.TypeAlias) + return ts.SymbolDisplayPartKind.aliasName; + if (flags & ts.SymbolFlags.Alias) + return ts.SymbolDisplayPartKind.aliasName; + return ts.SymbolDisplayPartKind.text; + } + } + export function displayPart(text: string, kind: ts.SymbolDisplayPartKind): ts.SymbolDisplayPart { + return { text, kind: ts.SymbolDisplayPartKind[kind] }; } export function spacePart() { - return displayPart(" ", SymbolDisplayPartKind.space); + return displayPart(" ", ts.SymbolDisplayPartKind.space); } - export function keywordPart(kind: SyntaxKind) { - return displayPart(tokenToString(kind)!, SymbolDisplayPartKind.keyword); + export function keywordPart(kind: ts.SyntaxKind) { + return displayPart(ts.tokenToString(kind)!, ts.SymbolDisplayPartKind.keyword); } - export function punctuationPart(kind: SyntaxKind) { - return displayPart(tokenToString(kind)!, SymbolDisplayPartKind.punctuation); + export function punctuationPart(kind: ts.SyntaxKind) { + return displayPart(ts.tokenToString(kind)!, ts.SymbolDisplayPartKind.punctuation); } - export function operatorPart(kind: SyntaxKind) { - return displayPart(tokenToString(kind)!, SymbolDisplayPartKind.operator); + export function operatorPart(kind: ts.SyntaxKind) { + return displayPart(ts.tokenToString(kind)!, ts.SymbolDisplayPartKind.operator); } export function parameterNamePart(text: string) { - return displayPart(text, SymbolDisplayPartKind.parameterName); + return displayPart(text, ts.SymbolDisplayPartKind.parameterName); } export function propertyNamePart(text: string) { - return displayPart(text, SymbolDisplayPartKind.propertyName); + return displayPart(text, ts.SymbolDisplayPartKind.propertyName); } export function textOrKeywordPart(text: string) { - const kind = stringToToken(text); + const kind = ts.stringToToken(text); return kind === undefined ? textPart(text) : keywordPart(kind); } export function textPart(text: string) { - return displayPart(text, SymbolDisplayPartKind.text); + return displayPart(text, ts.SymbolDisplayPartKind.text); } export function typeAliasNamePart(text: string) { - return displayPart(text, SymbolDisplayPartKind.aliasName); + return displayPart(text, ts.SymbolDisplayPartKind.aliasName); } export function typeParameterNamePart(text: string) { - return displayPart(text, SymbolDisplayPartKind.typeParameterName); + return displayPart(text, ts.SymbolDisplayPartKind.typeParameterName); } export function linkTextPart(text: string) { - return displayPart(text, SymbolDisplayPartKind.linkText); + return displayPart(text, ts.SymbolDisplayPartKind.linkText); } - export function linkNamePart(text: string, target: Declaration): JSDocLinkDisplayPart { + export function linkNamePart(text: string, target: ts.Declaration): ts.JSDocLinkDisplayPart { return { text, - kind: SymbolDisplayPartKind[SymbolDisplayPartKind.linkName], + kind: ts.SymbolDisplayPartKind[ts.SymbolDisplayPartKind.linkName], target: { - fileName: getSourceFileOfNode(target).fileName, + fileName: ts.getSourceFileOfNode(target).fileName, textSpan: createTextSpanFromNode(target), }, }; } export function linkPart(text: string) { - return displayPart(text, SymbolDisplayPartKind.link); + return displayPart(text, ts.SymbolDisplayPartKind.link); } - export function buildLinkParts(link: JSDocLink | JSDocLinkCode | JSDocLinkPlain, checker?: TypeChecker): SymbolDisplayPart[] { - const prefix = isJSDocLink(link) ? "link" - : isJSDocLinkCode(link) ? "linkcode" + export function buildLinkParts(link: ts.JSDocLink | ts.JSDocLinkCode | ts.JSDocLinkPlain, checker?: ts.TypeChecker): ts.SymbolDisplayPart[] { + const prefix = ts.isJSDocLink(link) ? "link" + : ts.isJSDocLinkCode(link) ? "linkcode" : "linkplain"; const parts = [linkPart(`{@${prefix} `)]; if (!link.name) { @@ -2326,12 +2342,13 @@ namespace ts { else { const symbol = checker?.getSymbolAtLocation(link.name); const suffix = findLinkNameEnd(link.text); - const name = getTextOfNode(link.name) + link.text.slice(0, suffix); + const name = ts.getTextOfNode(link.name) + link.text.slice(0, suffix); const text = skipSeparatorFromLinkText(link.text.slice(suffix)); const decl = symbol?.valueDeclaration || symbol?.declarations?.[0]; if (decl) { parts.push(linkNamePart(name, decl)); - if (text) parts.push(linkTextPart(text)); + if (text) + parts.push(linkTextPart(text)); } else { parts.push(linkTextPart(name + (suffix || text.indexOf("://") === 0 ? "" : " ") + text)); @@ -2343,23 +2360,29 @@ namespace ts { function skipSeparatorFromLinkText(text: string) { let pos = 0; - if (text.charCodeAt(pos++) === CharacterCodes.bar) { - while (pos < text.length && text.charCodeAt(pos) === CharacterCodes.space) pos++; + if (text.charCodeAt(pos++) === ts.CharacterCodes.bar) { + while (pos < text.length && text.charCodeAt(pos) === ts.CharacterCodes.space) + pos++; return text.slice(pos); } return text; } function findLinkNameEnd(text: string) { - if (text.indexOf("()") === 0) return 2; - if (text[0] !== "<") return 0; + if (text.indexOf("()") === 0) + return 2; + if (text[0] !== "<") + return 0; let brackets = 0; let i = 0; while (i < text.length) { - if (text[i] === "<") brackets++; - if (text[i] === ">") brackets--; + if (text[i] === "<") + brackets++; + if (text[i] === ">") + brackets--; i++; - if (!brackets) return i; + if (!brackets) + return i; } return 0; } @@ -2368,17 +2391,17 @@ namespace ts { /** * The default is CRLF. */ - export function getNewLineOrDefaultFromHost(host: FormattingHost, formatSettings?: FormatCodeSettings) { + export function getNewLineOrDefaultFromHost(host: ts.FormattingHost, formatSettings?: ts.FormatCodeSettings) { return formatSettings?.newLineCharacter || host.getNewLine?.() || carriageReturnLineFeed; } export function lineBreakPart() { - return displayPart("\n", SymbolDisplayPartKind.lineBreak); + return displayPart("\n", ts.SymbolDisplayPartKind.lineBreak); } - export function mapToDisplayParts(writeDisplayParts: (writer: DisplayPartsSymbolWriter) => void): SymbolDisplayPart[] { + export function mapToDisplayParts(writeDisplayParts: (writer: ts.DisplayPartsSymbolWriter) => void): ts.SymbolDisplayPart[] { try { writeDisplayParts(displayPartWriter); return displayPartWriter.displayParts(); @@ -2388,77 +2411,77 @@ namespace ts { } } - export function typeToDisplayParts(typechecker: TypeChecker, type: Type, enclosingDeclaration?: Node, flags: TypeFormatFlags = TypeFormatFlags.None): SymbolDisplayPart[] { + export function typeToDisplayParts(typechecker: ts.TypeChecker, type: ts.Type, enclosingDeclaration?: ts.Node, flags: ts.TypeFormatFlags = ts.TypeFormatFlags.None): ts.SymbolDisplayPart[] { return mapToDisplayParts(writer => { - typechecker.writeType(type, enclosingDeclaration, flags | TypeFormatFlags.MultilineObjectLiterals | TypeFormatFlags.UseAliasDefinedOutsideCurrentScope, writer); + typechecker.writeType(type, enclosingDeclaration, flags | ts.TypeFormatFlags.MultilineObjectLiterals | ts.TypeFormatFlags.UseAliasDefinedOutsideCurrentScope, writer); }); } - export function symbolToDisplayParts(typeChecker: TypeChecker, symbol: Symbol, enclosingDeclaration?: Node, meaning?: SymbolFlags, flags: SymbolFormatFlags = SymbolFormatFlags.None): SymbolDisplayPart[] { + export function symbolToDisplayParts(typeChecker: ts.TypeChecker, symbol: ts.Symbol, enclosingDeclaration?: ts.Node, meaning?: ts.SymbolFlags, flags: ts.SymbolFormatFlags = ts.SymbolFormatFlags.None): ts.SymbolDisplayPart[] { return mapToDisplayParts(writer => { - typeChecker.writeSymbol(symbol, enclosingDeclaration, meaning, flags | SymbolFormatFlags.UseAliasDefinedOutsideCurrentScope, writer); + typeChecker.writeSymbol(symbol, enclosingDeclaration, meaning, flags | ts.SymbolFormatFlags.UseAliasDefinedOutsideCurrentScope, writer); }); } - export function signatureToDisplayParts(typechecker: TypeChecker, signature: Signature, enclosingDeclaration?: Node, flags: TypeFormatFlags = TypeFormatFlags.None): SymbolDisplayPart[] { - flags |= TypeFormatFlags.UseAliasDefinedOutsideCurrentScope | TypeFormatFlags.MultilineObjectLiterals | TypeFormatFlags.WriteTypeArgumentsOfSignature | TypeFormatFlags.OmitParameterModifiers; + export function signatureToDisplayParts(typechecker: ts.TypeChecker, signature: ts.Signature, enclosingDeclaration?: ts.Node, flags: ts.TypeFormatFlags = ts.TypeFormatFlags.None): ts.SymbolDisplayPart[] { + flags |= ts.TypeFormatFlags.UseAliasDefinedOutsideCurrentScope | ts.TypeFormatFlags.MultilineObjectLiterals | ts.TypeFormatFlags.WriteTypeArgumentsOfSignature | ts.TypeFormatFlags.OmitParameterModifiers; return mapToDisplayParts(writer => { typechecker.writeSignature(signature, enclosingDeclaration, flags, /*signatureKind*/ undefined, writer); }); } - export function nodeToDisplayParts(node: Node, enclosingDeclaration: Node): SymbolDisplayPart[] { + export function nodeToDisplayParts(node: ts.Node, enclosingDeclaration: ts.Node): ts.SymbolDisplayPart[] { const file = enclosingDeclaration.getSourceFile(); return mapToDisplayParts(writer => { - const printer = createPrinter({ removeComments: true, omitTrailingSemicolon: true }); - printer.writeNode(EmitHint.Unspecified, node, file, writer); + const printer = ts.createPrinter({ removeComments: true, omitTrailingSemicolon: true }); + printer.writeNode(ts.EmitHint.Unspecified, node, file, writer); }); } - export function isImportOrExportSpecifierName(location: Node): location is Identifier { - return !!location.parent && isImportOrExportSpecifier(location.parent) && location.parent.propertyName === location; + export function isImportOrExportSpecifierName(location: ts.Node): location is ts.Identifier { + return !!location.parent && ts.isImportOrExportSpecifier(location.parent) && location.parent.propertyName === location; } - export function getScriptKind(fileName: string, host: LanguageServiceHost): ScriptKind { + export function getScriptKind(fileName: string, host: ts.LanguageServiceHost): ts.ScriptKind { // First check to see if the script kind was specified by the host. Chances are the host // may override the default script kind for the file extension. - return ensureScriptKind(fileName, host.getScriptKind && host.getScriptKind(fileName)); + return ts.ensureScriptKind(fileName, host.getScriptKind && host.getScriptKind(fileName)); } - export function getSymbolTarget(symbol: Symbol, checker: TypeChecker): Symbol { - let next: Symbol = symbol; + export function getSymbolTarget(symbol: ts.Symbol, checker: ts.TypeChecker): ts.Symbol { + let next: ts.Symbol = symbol; while (isAliasSymbol(next) || (isTransientSymbol(next) && next.target)) { if (isTransientSymbol(next) && next.target) { next = next.target; } else { - next = skipAlias(next, checker); + next = ts.skipAlias(next, checker); } } return next; } - function isTransientSymbol(symbol: Symbol): symbol is TransientSymbol { - return (symbol.flags & SymbolFlags.Transient) !== 0; + function isTransientSymbol(symbol: ts.Symbol): symbol is ts.TransientSymbol { + return (symbol.flags & ts.SymbolFlags.Transient) !== 0; } - function isAliasSymbol(symbol: Symbol): boolean { - return (symbol.flags & SymbolFlags.Alias) !== 0; + function isAliasSymbol(symbol: ts.Symbol): boolean { + return (symbol.flags & ts.SymbolFlags.Alias) !== 0; } - export function getUniqueSymbolId(symbol: Symbol, checker: TypeChecker) { - return getSymbolId(skipAlias(symbol, checker)); + export function getUniqueSymbolId(symbol: ts.Symbol, checker: ts.TypeChecker) { + return ts.getSymbolId(ts.skipAlias(symbol, checker)); } export function getFirstNonSpaceCharacterPosition(text: string, position: number) { - while (isWhiteSpaceLike(text.charCodeAt(position))) { + while (ts.isWhiteSpaceLike(text.charCodeAt(position))) { position += 1; } return position; } export function getPrecedingNonSpaceCharacterPosition(text: string, position: number) { - while (position > -1 && isWhiteSpaceSingleLine(text.charCodeAt(position))) { + while (position > -1 && ts.isWhiteSpaceSingleLine(text.charCodeAt(position))) { position -= 1; } return position + 1; @@ -2470,73 +2493,64 @@ namespace ts { * WARNING: This is an expensive operation and is only intended to be used in refactorings * and code fixes (because those are triggered by explicit user actions). */ - export function getSynthesizedDeepClone(node: T, includeTrivia = true): T { + export function getSynthesizedDeepClone(node: T, includeTrivia = true): T { const clone = node && getSynthesizedDeepCloneWorker(node as NonNullable); - if (clone && !includeTrivia) suppressLeadingAndTrailingTrivia(clone); + if (clone && !includeTrivia) + suppressLeadingAndTrailingTrivia(clone); return clone; } - export function getSynthesizedDeepCloneWithReplacements( - node: T, - includeTrivia: boolean, - replaceNode: (node: Node) => Node | undefined - ): T { + export function getSynthesizedDeepCloneWithReplacements(node: T, includeTrivia: boolean, replaceNode: (node: ts.Node) => ts.Node | undefined): T { let clone = replaceNode(node); if (clone) { - setOriginalNode(clone, node); + ts.setOriginalNode(clone, node); } else { clone = getSynthesizedDeepCloneWorker(node as NonNullable, replaceNode); } - if (clone && !includeTrivia) suppressLeadingAndTrailingTrivia(clone); + if (clone && !includeTrivia) + suppressLeadingAndTrailingTrivia(clone); return clone as T; } - function getSynthesizedDeepCloneWorker(node: T, replaceNode?: (node: Node) => Node | undefined): T { + function getSynthesizedDeepCloneWorker(node: T, replaceNode?: (node: ts.Node) => ts.Node | undefined): T { const nodeClone: (n: T) => T = replaceNode ? n => getSynthesizedDeepCloneWithReplacements(n, /*includeTrivia*/ true, replaceNode) : getSynthesizedDeepClone; - const nodesClone: (ns: NodeArray) => NodeArray = replaceNode + const nodesClone: (ns: ts.NodeArray) => ts.NodeArray = replaceNode ? ns => ns && getSynthesizedDeepClonesWithReplacements(ns, /*includeTrivia*/ true, replaceNode) : ns => ns && getSynthesizedDeepClones(ns); - const visited = - visitEachChild(node, nodeClone, nullTransformationContext, nodesClone, nodeClone); + const visited = ts.visitEachChild(node, nodeClone, ts.nullTransformationContext, nodesClone, nodeClone); if (visited === node) { // This only happens for leaf nodes - internal nodes always see their children change. - const clone = - isStringLiteral(node) ? setOriginalNode(factory.createStringLiteralFromNode(node), node) as Node as T : - isNumericLiteral(node) ? setOriginalNode(factory.createNumericLiteral(node.text, node.numericLiteralFlags), node) as Node as T : - factory.cloneNode(node); - return setTextRange(clone, node); + const clone = ts.isStringLiteral(node) ? ts.setOriginalNode(ts.factory.createStringLiteralFromNode(node), node) as ts.Node as T : + ts.isNumericLiteral(node) ? ts.setOriginalNode(ts.factory.createNumericLiteral(node.text, node.numericLiteralFlags), node) as ts.Node as T : + ts.factory.cloneNode(node); + return ts.setTextRange(clone, node); } // PERF: As an optimization, rather than calling factory.cloneNode, we'll update // the new node created by visitEachChild with the extra changes factory.cloneNode // would have made. - (visited as Mutable).parent = undefined!; + (visited as ts.Mutable).parent = undefined!; return visited; } - export function getSynthesizedDeepClones(nodes: NodeArray, includeTrivia?: boolean): NodeArray; - export function getSynthesizedDeepClones(nodes: NodeArray | undefined, includeTrivia?: boolean): NodeArray | undefined; - export function getSynthesizedDeepClones(nodes: NodeArray | undefined, includeTrivia = true): NodeArray | undefined { - return nodes && factory.createNodeArray(nodes.map(n => getSynthesizedDeepClone(n, includeTrivia)), nodes.hasTrailingComma); + export function getSynthesizedDeepClones(nodes: ts.NodeArray, includeTrivia?: boolean): ts.NodeArray; + export function getSynthesizedDeepClones(nodes: ts.NodeArray | undefined, includeTrivia?: boolean): ts.NodeArray | undefined; + export function getSynthesizedDeepClones(nodes: ts.NodeArray | undefined, includeTrivia = true): ts.NodeArray | undefined { + return nodes && ts.factory.createNodeArray(nodes.map(n => getSynthesizedDeepClone(n, includeTrivia)), nodes.hasTrailingComma); } - - export function getSynthesizedDeepClonesWithReplacements( - nodes: NodeArray, - includeTrivia: boolean, - replaceNode: (node: Node) => Node | undefined - ): NodeArray { - return factory.createNodeArray(nodes.map(n => getSynthesizedDeepCloneWithReplacements(n, includeTrivia, replaceNode)), nodes.hasTrailingComma); + export function getSynthesizedDeepClonesWithReplacements(nodes: ts.NodeArray, includeTrivia: boolean, replaceNode: (node: ts.Node) => ts.Node | undefined): ts.NodeArray { + return ts.factory.createNodeArray(nodes.map(n => getSynthesizedDeepCloneWithReplacements(n, includeTrivia, replaceNode)), nodes.hasTrailingComma); } /** * Sets EmitFlags to suppress leading and trailing trivia on the node. */ - export function suppressLeadingAndTrailingTrivia(node: Node) { + export function suppressLeadingAndTrailingTrivia(node: ts.Node) { suppressLeadingTrivia(node); suppressTrailingTrivia(node); } @@ -2544,18 +2558,18 @@ namespace ts { /** * Sets EmitFlags to suppress leading trivia on the node. */ - export function suppressLeadingTrivia(node: Node) { - addEmitFlagsRecursively(node, EmitFlags.NoLeadingComments, getFirstChild); + export function suppressLeadingTrivia(node: ts.Node) { + addEmitFlagsRecursively(node, ts.EmitFlags.NoLeadingComments, getFirstChild); } /** * Sets EmitFlags to suppress trailing trivia on the node. */ - export function suppressTrailingTrivia(node: Node) { - addEmitFlagsRecursively(node, EmitFlags.NoTrailingComments, getLastChild); + export function suppressTrailingTrivia(node: ts.Node) { + addEmitFlagsRecursively(node, ts.EmitFlags.NoTrailingComments, ts.getLastChild); } - export function copyComments(sourceNode: Node, targetNode: Node) { + export function copyComments(sourceNode: ts.Node, targetNode: ts.Node) { const sourceFile = sourceNode.getSourceFile(); const text = sourceFile.text; if (hasLeadingLineBreak(sourceNode, text)) { @@ -2567,28 +2581,30 @@ namespace ts { copyTrailingComments(sourceNode, targetNode, sourceFile); } - function hasLeadingLineBreak(node: Node, text: string) { + function hasLeadingLineBreak(node: ts.Node, text: string) { const start = node.getFullStart(); const end = node.getStart(); for (let i = start; i < end; i++) { - if (text.charCodeAt(i) === CharacterCodes.lineFeed) return true; + if (text.charCodeAt(i) === ts.CharacterCodes.lineFeed) + return true; } return false; } - function addEmitFlagsRecursively(node: Node, flag: EmitFlags, getChild: (n: Node) => Node | undefined) { - addEmitFlags(node, flag); + function addEmitFlagsRecursively(node: ts.Node, flag: ts.EmitFlags, getChild: (n: ts.Node) => ts.Node | undefined) { + ts.addEmitFlags(node, flag); const child = getChild(node); - if (child) addEmitFlagsRecursively(child, flag, getChild); + if (child) + addEmitFlagsRecursively(child, flag, getChild); } - function getFirstChild(node: Node): Node | undefined { + function getFirstChild(node: ts.Node): ts.Node | undefined { return node.forEachChild(child => child); } - export function getUniqueName(baseName: string, sourceFile: SourceFile): string { + export function getUniqueName(baseName: string, sourceFile: ts.SourceFile): string { let nameText = baseName; - for (let i = 1; !isFileLevelUniqueName(sourceFile, nameText); i++) { + for (let i = 1; !ts.isFileLevelUniqueName(sourceFile, nameText); i++) { nameText = `${baseName}_${i}`; } return nameText; @@ -2599,11 +2615,11 @@ namespace ts { * to be on the reference, rather than the declaration, because it's closer to where the * user was before extracting it. */ - export function getRenameLocation(edits: readonly FileTextChanges[], renameFilename: string, name: string, preferLastLocation: boolean): number { + export function getRenameLocation(edits: readonly ts.FileTextChanges[], renameFilename: string, name: string, preferLastLocation: boolean): number { let delta = 0; let lastPos = -1; for (const { fileName, textChanges } of edits) { - Debug.assert(fileName === renameFilename); + ts.Debug.assert(fileName === renameFilename); for (const change of textChanges) { const { span, newText } = change; const index = indexInTextChange(newText, name); @@ -2620,18 +2636,18 @@ namespace ts { } // If the declaration comes first, return the position of the last occurrence. - Debug.assert(preferLastLocation); - Debug.assert(lastPos >= 0); + ts.Debug.assert(preferLastLocation); + ts.Debug.assert(lastPos >= 0); return lastPos; } - export function copyLeadingComments(sourceNode: Node, targetNode: Node, sourceFile: SourceFile, commentKind?: CommentKind, hasTrailingNewLine?: boolean) { - forEachLeadingCommentRange(sourceFile.text, sourceNode.pos, getAddCommentsFunction(targetNode, sourceFile, commentKind, hasTrailingNewLine, addSyntheticLeadingComment)); + export function copyLeadingComments(sourceNode: ts.Node, targetNode: ts.Node, sourceFile: ts.SourceFile, commentKind?: ts.CommentKind, hasTrailingNewLine?: boolean) { + ts.forEachLeadingCommentRange(sourceFile.text, sourceNode.pos, getAddCommentsFunction(targetNode, sourceFile, commentKind, hasTrailingNewLine, ts.addSyntheticLeadingComment)); } - export function copyTrailingComments(sourceNode: Node, targetNode: Node, sourceFile: SourceFile, commentKind?: CommentKind, hasTrailingNewLine?: boolean) { - forEachTrailingCommentRange(sourceFile.text, sourceNode.end, getAddCommentsFunction(targetNode, sourceFile, commentKind, hasTrailingNewLine, addSyntheticTrailingComment)); + export function copyTrailingComments(sourceNode: ts.Node, targetNode: ts.Node, sourceFile: ts.SourceFile, commentKind?: ts.CommentKind, hasTrailingNewLine?: boolean) { + ts.forEachTrailingCommentRange(sourceFile.text, sourceNode.end, getAddCommentsFunction(targetNode, sourceFile, commentKind, hasTrailingNewLine, ts.addSyntheticTrailingComment)); } /** @@ -2641,13 +2657,13 @@ namespace ts { * `function foo(\* not leading comment for a *\ a: string) {}` * The comment refers to `a` but belongs to the `(` token, but we might want to copy it. */ - export function copyTrailingAsLeadingComments(sourceNode: Node, targetNode: Node, sourceFile: SourceFile, commentKind?: CommentKind, hasTrailingNewLine?: boolean) { - forEachTrailingCommentRange(sourceFile.text, sourceNode.pos, getAddCommentsFunction(targetNode, sourceFile, commentKind, hasTrailingNewLine, addSyntheticLeadingComment)); + export function copyTrailingAsLeadingComments(sourceNode: ts.Node, targetNode: ts.Node, sourceFile: ts.SourceFile, commentKind?: ts.CommentKind, hasTrailingNewLine?: boolean) { + ts.forEachTrailingCommentRange(sourceFile.text, sourceNode.pos, getAddCommentsFunction(targetNode, sourceFile, commentKind, hasTrailingNewLine, ts.addSyntheticLeadingComment)); } - function getAddCommentsFunction(targetNode: Node, sourceFile: SourceFile, commentKind: CommentKind | undefined, hasTrailingNewLine: boolean | undefined, cb: (node: Node, kind: CommentKind, text: string, hasTrailingNewLine?: boolean) => void) { - return (pos: number, end: number, kind: CommentKind, htnl: boolean) => { - if (kind === SyntaxKind.MultiLineCommentTrivia) { + function getAddCommentsFunction(targetNode: ts.Node, sourceFile: ts.SourceFile, commentKind: ts.CommentKind | undefined, hasTrailingNewLine: boolean | undefined, cb: (node: ts.Node, kind: ts.CommentKind, text: string, hasTrailingNewLine?: boolean) => void) { + return (pos: number, end: number, kind: ts.CommentKind, htnl: boolean) => { + if (kind === ts.SyntaxKind.MultiLineCommentTrivia) { // Remove leading /* pos += 2; // Remove trailing */ @@ -2662,87 +2678,90 @@ namespace ts { } function indexInTextChange(change: string, name: string): number { - if (startsWith(change, name)) return 0; + if (ts.startsWith(change, name)) + return 0; // Add a " " to avoid references inside words let idx = change.indexOf(" " + name); - if (idx === -1) idx = change.indexOf("." + name); - if (idx === -1) idx = change.indexOf('"' + name); + if (idx === -1) + idx = change.indexOf("." + name); + if (idx === -1) + idx = change.indexOf('"' + name); return idx === -1 ? -1 : idx + 1; } /* @internal */ - export function needsParentheses(expression: Expression): boolean { - return isBinaryExpression(expression) && expression.operatorToken.kind === SyntaxKind.CommaToken - || isObjectLiteralExpression(expression) - || isAsExpression(expression) && isObjectLiteralExpression(expression.expression); + export function needsParentheses(expression: ts.Expression): boolean { + return ts.isBinaryExpression(expression) && expression.operatorToken.kind === ts.SyntaxKind.CommaToken + || ts.isObjectLiteralExpression(expression) + || ts.isAsExpression(expression) && ts.isObjectLiteralExpression(expression.expression); } - export function getContextualTypeFromParent(node: Expression, checker: TypeChecker): Type | undefined { + export function getContextualTypeFromParent(node: ts.Expression, checker: ts.TypeChecker): ts.Type | undefined { const { parent } = node; switch (parent.kind) { - case SyntaxKind.NewExpression: - return checker.getContextualType(parent as NewExpression); - case SyntaxKind.BinaryExpression: { - const { left, operatorToken, right } = parent as BinaryExpression; + case ts.SyntaxKind.NewExpression: + return checker.getContextualType(parent as ts.NewExpression); + case ts.SyntaxKind.BinaryExpression: { + const { left, operatorToken, right } = parent as ts.BinaryExpression; return isEqualityOperatorKind(operatorToken.kind) ? checker.getTypeAtLocation(node === right ? left : right) : checker.getContextualType(node); } - case SyntaxKind.CaseClause: - return (parent as CaseClause).expression === node ? getSwitchedType(parent as CaseClause, checker) : undefined; + case ts.SyntaxKind.CaseClause: + return (parent as ts.CaseClause).expression === node ? getSwitchedType(parent as ts.CaseClause, checker) : undefined; default: return checker.getContextualType(node); } } - export function quote(sourceFile: SourceFile, preferences: UserPreferences, text: string): string { + export function quote(sourceFile: ts.SourceFile, preferences: ts.UserPreferences, text: string): string { // Editors can pass in undefined or empty string - we want to infer the preference in those cases. const quotePreference = getQuotePreference(sourceFile, preferences); const quoted = JSON.stringify(text); - return quotePreference === QuotePreference.Single ? `'${stripQuotes(quoted).replace(/'/g, "\\'").replace(/\\"/g, '"')}'` : quoted; + return quotePreference === QuotePreference.Single ? `'${ts.stripQuotes(quoted).replace(/'/g, "\\'").replace(/\\"/g, '"')}'` : quoted; } - export function isEqualityOperatorKind(kind: SyntaxKind): kind is EqualityOperator { + export function isEqualityOperatorKind(kind: ts.SyntaxKind): kind is ts.EqualityOperator { switch (kind) { - case SyntaxKind.EqualsEqualsEqualsToken: - case SyntaxKind.EqualsEqualsToken: - case SyntaxKind.ExclamationEqualsEqualsToken: - case SyntaxKind.ExclamationEqualsToken: + case ts.SyntaxKind.EqualsEqualsEqualsToken: + case ts.SyntaxKind.EqualsEqualsToken: + case ts.SyntaxKind.ExclamationEqualsEqualsToken: + case ts.SyntaxKind.ExclamationEqualsToken: return true; default: return false; } } - export function isStringLiteralOrTemplate(node: Node): node is StringLiteralLike | TemplateExpression | TaggedTemplateExpression { + export function isStringLiteralOrTemplate(node: ts.Node): node is ts.StringLiteralLike | ts.TemplateExpression | ts.TaggedTemplateExpression { switch (node.kind) { - case SyntaxKind.StringLiteral: - case SyntaxKind.NoSubstitutionTemplateLiteral: - case SyntaxKind.TemplateExpression: - case SyntaxKind.TaggedTemplateExpression: + case ts.SyntaxKind.StringLiteral: + case ts.SyntaxKind.NoSubstitutionTemplateLiteral: + case ts.SyntaxKind.TemplateExpression: + case ts.SyntaxKind.TaggedTemplateExpression: return true; default: return false; } } - export function hasIndexSignature(type: Type): boolean { + export function hasIndexSignature(type: ts.Type): boolean { return !!type.getStringIndexType() || !!type.getNumberIndexType(); } - export function getSwitchedType(caseClause: CaseClause, checker: TypeChecker): Type | undefined { + export function getSwitchedType(caseClause: ts.CaseClause, checker: ts.TypeChecker): ts.Type | undefined { return checker.getTypeAtLocation(caseClause.parent.parent.expression); } export const ANONYMOUS = "anonymous function"; - export function getTypeNodeIfAccessible(type: Type, enclosingScope: Node, program: Program, host: LanguageServiceHost): TypeNode | undefined { + export function getTypeNodeIfAccessible(type: ts.Type, enclosingScope: ts.Node, program: ts.Program, host: ts.LanguageServiceHost): ts.TypeNode | undefined { const checker = program.getTypeChecker(); let typeIsAccessible = true; const notAccessible = () => typeIsAccessible = false; - const res = checker.typeToTypeNode(type, enclosingScope, NodeBuilderFlags.NoTruncation, { + const res = checker.typeToTypeNode(type, enclosingScope, ts.NodeBuilderFlags.NoTruncation, { trackSymbol: (symbol, declaration, meaning) => { - typeIsAccessible = typeIsAccessible && checker.isSymbolAccessible(symbol, declaration, meaning, /*shouldComputeAliasToMarkVisible*/ false).accessibility === SymbolAccessibility.Accessible; + typeIsAccessible = typeIsAccessible && checker.isSymbolAccessible(symbol, declaration, meaning, /*shouldComputeAliasToMarkVisible*/ false).accessibility === ts.SymbolAccessibility.Accessible; return !typeIsAccessible; }, reportInaccessibleThisError: notAccessible, @@ -2753,70 +2772,61 @@ namespace ts { return typeIsAccessible ? res : undefined; } - function syntaxRequiresTrailingCommaOrSemicolonOrASI(kind: SyntaxKind) { - return kind === SyntaxKind.CallSignature - || kind === SyntaxKind.ConstructSignature - || kind === SyntaxKind.IndexSignature - || kind === SyntaxKind.PropertySignature - || kind === SyntaxKind.MethodSignature; - } - - function syntaxRequiresTrailingFunctionBlockOrSemicolonOrASI(kind: SyntaxKind) { - return kind === SyntaxKind.FunctionDeclaration - || kind === SyntaxKind.Constructor - || kind === SyntaxKind.MethodDeclaration - || kind === SyntaxKind.GetAccessor - || kind === SyntaxKind.SetAccessor; - } - - function syntaxRequiresTrailingModuleBlockOrSemicolonOrASI(kind: SyntaxKind) { - return kind === SyntaxKind.ModuleDeclaration; - } - - export function syntaxRequiresTrailingSemicolonOrASI(kind: SyntaxKind) { - return kind === SyntaxKind.VariableStatement - || kind === SyntaxKind.ExpressionStatement - || kind === SyntaxKind.DoStatement - || kind === SyntaxKind.ContinueStatement - || kind === SyntaxKind.BreakStatement - || kind === SyntaxKind.ReturnStatement - || kind === SyntaxKind.ThrowStatement - || kind === SyntaxKind.DebuggerStatement - || kind === SyntaxKind.PropertyDeclaration - || kind === SyntaxKind.TypeAliasDeclaration - || kind === SyntaxKind.ImportDeclaration - || kind === SyntaxKind.ImportEqualsDeclaration - || kind === SyntaxKind.ExportDeclaration - || kind === SyntaxKind.NamespaceExportDeclaration - || kind === SyntaxKind.ExportAssignment; - } - - export const syntaxMayBeASICandidate = or( - syntaxRequiresTrailingCommaOrSemicolonOrASI, - syntaxRequiresTrailingFunctionBlockOrSemicolonOrASI, - syntaxRequiresTrailingModuleBlockOrSemicolonOrASI, - syntaxRequiresTrailingSemicolonOrASI); - - function nodeIsASICandidate(node: Node, sourceFile: SourceFileLike): boolean { + function syntaxRequiresTrailingCommaOrSemicolonOrASI(kind: ts.SyntaxKind) { + return kind === ts.SyntaxKind.CallSignature + || kind === ts.SyntaxKind.ConstructSignature + || kind === ts.SyntaxKind.IndexSignature + || kind === ts.SyntaxKind.PropertySignature + || kind === ts.SyntaxKind.MethodSignature; + } + function syntaxRequiresTrailingFunctionBlockOrSemicolonOrASI(kind: ts.SyntaxKind) { + return kind === ts.SyntaxKind.FunctionDeclaration + || kind === ts.SyntaxKind.Constructor + || kind === ts.SyntaxKind.MethodDeclaration + || kind === ts.SyntaxKind.GetAccessor + || kind === ts.SyntaxKind.SetAccessor; + } + function syntaxRequiresTrailingModuleBlockOrSemicolonOrASI(kind: ts.SyntaxKind) { + return kind === ts.SyntaxKind.ModuleDeclaration; + } + export function syntaxRequiresTrailingSemicolonOrASI(kind: ts.SyntaxKind) { + return kind === ts.SyntaxKind.VariableStatement + || kind === ts.SyntaxKind.ExpressionStatement + || kind === ts.SyntaxKind.DoStatement + || kind === ts.SyntaxKind.ContinueStatement + || kind === ts.SyntaxKind.BreakStatement + || kind === ts.SyntaxKind.ReturnStatement + || kind === ts.SyntaxKind.ThrowStatement + || kind === ts.SyntaxKind.DebuggerStatement + || kind === ts.SyntaxKind.PropertyDeclaration + || kind === ts.SyntaxKind.TypeAliasDeclaration + || kind === ts.SyntaxKind.ImportDeclaration + || kind === ts.SyntaxKind.ImportEqualsDeclaration + || kind === ts.SyntaxKind.ExportDeclaration + || kind === ts.SyntaxKind.NamespaceExportDeclaration + || kind === ts.SyntaxKind.ExportAssignment; + } + export const syntaxMayBeASICandidate = ts.or(syntaxRequiresTrailingCommaOrSemicolonOrASI, syntaxRequiresTrailingFunctionBlockOrSemicolonOrASI, syntaxRequiresTrailingModuleBlockOrSemicolonOrASI, syntaxRequiresTrailingSemicolonOrASI); + function nodeIsASICandidate(node: ts.Node, sourceFile: ts.SourceFileLike): boolean { const lastToken = node.getLastToken(sourceFile); - if (lastToken && lastToken.kind === SyntaxKind.SemicolonToken) { + if (lastToken && lastToken.kind === ts.SyntaxKind.SemicolonToken) { return false; } if (syntaxRequiresTrailingCommaOrSemicolonOrASI(node.kind)) { - if (lastToken && lastToken.kind === SyntaxKind.CommaToken) { + if (lastToken && lastToken.kind === ts.SyntaxKind.CommaToken) { return false; } } else if (syntaxRequiresTrailingModuleBlockOrSemicolonOrASI(node.kind)) { - const lastChild = last(node.getChildren(sourceFile)); - if (lastChild && isModuleBlock(lastChild)) { + const lastChild = ts.last(node.getChildren(sourceFile)); + if (lastChild && ts.isModuleBlock(lastChild)) { return false; } } else if (syntaxRequiresTrailingFunctionBlockOrSemicolonOrASI(node.kind)) { - const lastChild = last(node.getChildren(sourceFile)); - if (lastChild && isFunctionBlock(lastChild)) { + const lastChild = ts.last(node.getChildren(sourceFile)); + if (lastChild && ts.isFunctionBlock(lastChild)) { return false; } } @@ -2825,13 +2835,13 @@ namespace ts { } // See comment in parser’s `parseDoStatement` - if (node.kind === SyntaxKind.DoStatement) { + if (node.kind === ts.SyntaxKind.DoStatement) { return true; } - const topNode = findAncestor(node, ancestor => !ancestor.parent)!; + const topNode = ts.findAncestor(node, ancestor => !ancestor.parent)!; const nextToken = findNextToken(node, topNode, sourceFile); - if (!nextToken || nextToken.kind === SyntaxKind.CloseBraceToken) { + if (!nextToken || nextToken.kind === ts.SyntaxKind.CloseBraceToken) { return true; } @@ -2840,8 +2850,8 @@ namespace ts { return startLine !== endLine; } - export function positionIsASICandidate(pos: number, context: Node, sourceFile: SourceFileLike): boolean { - const contextAncestor = findAncestor(context, ancestor => { + export function positionIsASICandidate(pos: number, context: ts.Node, sourceFile: ts.SourceFileLike): boolean { + const contextAncestor = ts.findAncestor(context, ancestor => { if (ancestor.end !== pos) { return "quit"; } @@ -2851,14 +2861,14 @@ namespace ts { return !!contextAncestor && nodeIsASICandidate(contextAncestor, sourceFile); } - export function probablyUsesSemicolons(sourceFile: SourceFile): boolean { + export function probablyUsesSemicolons(sourceFile: ts.SourceFile): boolean { let withSemicolon = 0; let withoutSemicolon = 0; const nStatementsToObserve = 5; - forEachChild(sourceFile, function visit(node): boolean | undefined { + ts.forEachChild(sourceFile, function visit(node): boolean | undefined { if (syntaxRequiresTrailingSemicolonOrASI(node.kind)) { const lastToken = node.getLastToken(sourceFile); - if (lastToken?.kind === SyntaxKind.SemicolonToken) { + if (lastToken?.kind === ts.SyntaxKind.SemicolonToken) { withSemicolon++; } else { @@ -2867,12 +2877,12 @@ namespace ts { } else if (syntaxRequiresTrailingCommaOrSemicolonOrASI(node.kind)) { const lastToken = node.getLastToken(sourceFile); - if (lastToken?.kind === SyntaxKind.SemicolonToken) { + if (lastToken?.kind === ts.SyntaxKind.SemicolonToken) { withSemicolon++; } - else if (lastToken && lastToken.kind !== SyntaxKind.CommaToken) { - const lastTokenLine = getLineAndCharacterOfPosition(sourceFile, lastToken.getStart(sourceFile)).line; - const nextTokenLine = getLineAndCharacterOfPosition(sourceFile, getSpanOfTokenAtPosition(sourceFile, lastToken.end).start).line; + else if (lastToken && lastToken.kind !== ts.SyntaxKind.CommaToken) { + const lastTokenLine = ts.getLineAndCharacterOfPosition(sourceFile, lastToken.getStart(sourceFile)).line; + const nextTokenLine = ts.getLineAndCharacterOfPosition(sourceFile, ts.getSpanOfTokenAtPosition(sourceFile, lastToken.end).start).line; // Avoid counting missing semicolon in single-line objects: // `function f(p: { x: string /*no semicolon here is insignificant*/ }) {` if (lastTokenLine !== nextTokenLine) { @@ -2885,7 +2895,7 @@ namespace ts { return true; } - return forEachChild(node, visit); + return ts.forEachChild(node, visit); }); // One statement missing a semicolon isn't sufficient evidence to say the user @@ -2898,20 +2908,20 @@ namespace ts { return withSemicolon / withoutSemicolon > 1 / nStatementsToObserve; } - export function tryGetDirectories(host: Pick, directoryName: string): string[] { + export function tryGetDirectories(host: Pick, directoryName: string): string[] { return tryIOAndConsumeErrors(host, host.getDirectories, directoryName) || []; } - export function tryReadDirectory(host: Pick, path: string, extensions?: readonly string[], exclude?: readonly string[], include?: readonly string[]): readonly string[] { - return tryIOAndConsumeErrors(host, host.readDirectory, path, extensions, exclude, include) || emptyArray; + export function tryReadDirectory(host: Pick, path: string, extensions?: readonly string[], exclude?: readonly string[], include?: readonly string[]): readonly string[] { + return tryIOAndConsumeErrors(host, host.readDirectory, path, extensions, exclude, include) || ts.emptyArray; } - export function tryFileExists(host: Pick, path: string): boolean { + export function tryFileExists(host: Pick, path: string): boolean { return tryIOAndConsumeErrors(host, host.fileExists, path); } - export function tryDirectoryExists(host: LanguageServiceHost, path: string): boolean { - return tryAndIgnoreErrors(() => directoryProbablyExists(path, host)) || false; + export function tryDirectoryExists(host: ts.LanguageServiceHost, path: string): boolean { + return tryAndIgnoreErrors(() => ts.directoryProbablyExists(path, host)) || false; } export function tryAndIgnoreErrors(cb: () => T): T | undefined { @@ -2927,13 +2937,13 @@ namespace ts { return tryAndIgnoreErrors(() => toApply && toApply.apply(host, args)); } - export function findPackageJsons(startDirectory: string, host: Pick, stopDirectory?: string): string[] { + export function findPackageJsons(startDirectory: string, host: Pick, stopDirectory?: string): string[] { const paths: string[] = []; - forEachAncestorDirectory(startDirectory, ancestor => { + ts.forEachAncestorDirectory(startDirectory, ancestor => { if (ancestor === stopDirectory) { return true; } - const currentConfigPath = combinePaths(ancestor, "package.json"); + const currentConfigPath = ts.combinePaths(ancestor, "package.json"); if (tryFileExists(host, currentConfigPath)) { paths.push(currentConfigPath); } @@ -2941,11 +2951,12 @@ namespace ts { return paths; } - export function findPackageJson(directory: string, host: LanguageServiceHost): string | undefined { + export function findPackageJson(directory: string, host: ts.LanguageServiceHost): string | undefined { let packageJson: string | undefined; - forEachAncestorDirectory(directory, ancestor => { - if (ancestor === "node_modules") return true; - packageJson = findConfigFile(ancestor, (f) => tryFileExists(host, f), "package.json"); + ts.forEachAncestorDirectory(directory, ancestor => { + if (ancestor === "node_modules") + return true; + packageJson = ts.findConfigFile(ancestor, (f) => tryFileExists(host, f), "package.json"); if (packageJson) { return true; // break out } @@ -2953,14 +2964,14 @@ namespace ts { return packageJson; } - export function getPackageJsonsVisibleToFile(fileName: string, host: LanguageServiceHost): readonly PackageJsonInfo[] { + export function getPackageJsonsVisibleToFile(fileName: string, host: ts.LanguageServiceHost): readonly ts.PackageJsonInfo[] { if (!host.fileExists) { return []; } - const packageJsons: PackageJsonInfo[] = []; - forEachAncestorDirectory(getDirectoryPath(fileName), ancestor => { - const packageJsonFileName = combinePaths(ancestor, "package.json"); + const packageJsons: ts.PackageJsonInfo[] = []; + ts.forEachAncestorDirectory(ts.getDirectoryPath(fileName), ancestor => { + const packageJsonFileName = ts.combinePaths(ancestor, "package.json"); if (host.fileExists(packageJsonFileName)) { const info = createPackageJsonInfo(packageJsonFileName, host); if (info) { @@ -2972,7 +2983,9 @@ namespace ts { return packageJsons; } - export function createPackageJsonInfo(fileName: string, host: { readFile?(fileName: string): string | undefined }): PackageJsonInfo | undefined { + export function createPackageJsonInfo(fileName: string, host: { + readFile?(fileName: string): string | undefined; + }): ts.PackageJsonInfo | undefined { if (!host.readFile) { return undefined; } @@ -2981,14 +2994,14 @@ namespace ts { const dependencyKeys = ["dependencies", "devDependencies", "optionalDependencies", "peerDependencies"] as const; const stringContent = host.readFile(fileName) || ""; const content = tryParseJson(stringContent) as PackageJsonRaw | undefined; - const info: Pick = {}; + const info: Pick = {}; if (content) { for (const key of dependencyKeys) { const dependencies = content[key]; if (!dependencies) { continue; } - const dependencyMap = new Map(); + const dependencyMap = new ts.Map(); for (const packageName in dependencies) { dependencyMap.set(packageName, dependencies[packageName]); } @@ -2997,10 +3010,10 @@ namespace ts { } const dependencyGroups = [ - [PackageJsonDependencyGroup.Dependencies, info.dependencies], - [PackageJsonDependencyGroup.DevDependencies, info.devDependencies], - [PackageJsonDependencyGroup.OptionalDependencies, info.optionalDependencies], - [PackageJsonDependencyGroup.PeerDependencies, info.peerDependencies], + [ts.PackageJsonDependencyGroup.Dependencies, info.dependencies], + [ts.PackageJsonDependencyGroup.DevDependencies, info.devDependencies], + [ts.PackageJsonDependencyGroup.OptionalDependencies, info.optionalDependencies], + [ts.PackageJsonDependencyGroup.PeerDependencies, info.peerDependencies], ] as const; return { @@ -3013,7 +3026,7 @@ namespace ts { }, }; - function get(dependencyName: string, inGroups = PackageJsonDependencyGroup.All) { + function get(dependencyName: string, inGroups = ts.PackageJsonDependencyGroup.All) { for (const [group, deps] of dependencyGroups) { if (deps && (inGroups & group)) { const dep = deps.get(dependencyName); @@ -3026,8 +3039,8 @@ namespace ts { } export interface PackageJsonImportFilter { - allowsImportingAmbientModule: (moduleSymbol: Symbol, moduleSpecifierResolutionHost: ModuleSpecifierResolutionHost) => boolean; - allowsImportingSourceFile: (sourceFile: SourceFile, moduleSpecifierResolutionHost: ModuleSpecifierResolutionHost) => boolean; + allowsImportingAmbientModule: (moduleSymbol: ts.Symbol, moduleSpecifierResolutionHost: ts.ModuleSpecifierResolutionHost) => boolean; + allowsImportingSourceFile: (sourceFile: ts.SourceFile, moduleSpecifierResolutionHost: ts.ModuleSpecifierResolutionHost) => boolean; /** * Use for a specific module specifier that has already been resolved. * Use `allowsImportingAmbientModule` or `allowsImportingSourceFile` to resolve @@ -3036,10 +3049,8 @@ namespace ts { allowsImportingSpecifier: (moduleSpecifier: string) => boolean; } - export function createPackageJsonImportFilter(fromFile: SourceFile, preferences: UserPreferences, host: LanguageServiceHost): PackageJsonImportFilter { - const packageJsons = ( - (host.getPackageJsonsVisibleToFile && host.getPackageJsonsVisibleToFile(fromFile.fileName)) || getPackageJsonsVisibleToFile(fromFile.fileName, host) - ).filter(p => p.parseable); + export function createPackageJsonImportFilter(fromFile: ts.SourceFile, preferences: ts.UserPreferences, host: ts.LanguageServiceHost): PackageJsonImportFilter { + const packageJsons = ((host.getPackageJsonsVisibleToFile && host.getPackageJsonsVisibleToFile(fromFile.fileName)) || getPackageJsonsVisibleToFile(fromFile.fileName, host)).filter(p => p.parseable); let usesNodeCoreModules: boolean | undefined; return { allowsImportingAmbientModule, allowsImportingSourceFile, allowsImportingSpecifier }; @@ -3047,14 +3058,14 @@ namespace ts { function moduleSpecifierIsCoveredByPackageJson(specifier: string) { const packageName = getNodeModuleRootSpecifier(specifier); for (const packageJson of packageJsons) { - if (packageJson.has(packageName) || packageJson.has(getTypesPackageName(packageName))) { + if (packageJson.has(packageName) || packageJson.has(ts.getTypesPackageName(packageName))) { return true; } } return false; } - function allowsImportingAmbientModule(moduleSymbol: Symbol, moduleSpecifierResolutionHost: ModuleSpecifierResolutionHost): boolean { + function allowsImportingAmbientModule(moduleSymbol: ts.Symbol, moduleSpecifierResolutionHost: ts.ModuleSpecifierResolutionHost): boolean { if (!packageJsons.length || !moduleSymbol.valueDeclaration) { return true; } @@ -3065,7 +3076,7 @@ namespace ts { return true; } - const declaredModuleSpecifier = stripQuotes(moduleSymbol.getName()); + const declaredModuleSpecifier = ts.stripQuotes(moduleSymbol.getName()); if (isAllowedCoreNodeModulesImport(declaredModuleSpecifier)) { return true; } @@ -3074,7 +3085,7 @@ namespace ts { || moduleSpecifierIsCoveredByPackageJson(declaredModuleSpecifier); } - function allowsImportingSourceFile(sourceFile: SourceFile, moduleSpecifierResolutionHost: ModuleSpecifierResolutionHost): boolean { + function allowsImportingSourceFile(sourceFile: ts.SourceFile, moduleSpecifierResolutionHost: ts.ModuleSpecifierResolutionHost): boolean { if (!packageJsons.length) { return true; } @@ -3091,7 +3102,7 @@ namespace ts { if (!packageJsons.length || isAllowedCoreNodeModulesImport(moduleSpecifier)) { return true; } - if (pathIsRelative(moduleSpecifier) || isRootedDiskPath(moduleSpecifier)) { + if (ts.pathIsRelative(moduleSpecifier) || ts.isRootedDiskPath(moduleSpecifier)) { return true; } return moduleSpecifierIsCoveredByPackageJson(moduleSpecifier); @@ -3102,7 +3113,7 @@ namespace ts { // from Node core modules or not. We can start by seeing if the user is actually using // any node core modules, as opposed to simply having @types/node accidentally as a // dependency of a dependency. - if (isSourceFileJS(fromFile) && JsTyping.nodeCoreModules.has(moduleSpecifier)) { + if (ts.isSourceFileJS(fromFile) && ts.JsTyping.nodeCoreModules.has(moduleSpecifier)) { if (usesNodeCoreModules === undefined) { usesNodeCoreModules = consumesNodeCoreModules(fromFile); } @@ -3113,32 +3124,26 @@ namespace ts { return false; } - function getNodeModulesPackageNameFromFileName(importedFileName: string, moduleSpecifierResolutionHost: ModuleSpecifierResolutionHost): string | undefined { - if (!stringContains(importedFileName, "node_modules")) { + function getNodeModulesPackageNameFromFileName(importedFileName: string, moduleSpecifierResolutionHost: ts.ModuleSpecifierResolutionHost): string | undefined { + if (!ts.stringContains(importedFileName, "node_modules")) { return undefined; } - const specifier = moduleSpecifiers.getNodeModulesPackageName( - host.getCompilationSettings(), - fromFile, - importedFileName, - moduleSpecifierResolutionHost, - preferences, - ); + const specifier = ts.moduleSpecifiers.getNodeModulesPackageName(host.getCompilationSettings(), fromFile, importedFileName, moduleSpecifierResolutionHost, preferences); if (!specifier) { return undefined; } // Paths here are not node_modules, so we don’t care about them; // returning anything will trigger a lookup in package.json. - if (!pathIsRelative(specifier) && !isRootedDiskPath(specifier)) { + if (!ts.pathIsRelative(specifier) && !ts.isRootedDiskPath(specifier)) { return getNodeModuleRootSpecifier(specifier); } } function getNodeModuleRootSpecifier(fullSpecifier: string): string { - const components = getPathComponents(getPackageNameFromTypesPackageName(fullSpecifier)).slice(1); + const components = ts.getPathComponents(ts.getPackageNameFromTypesPackageName(fullSpecifier)).slice(1); // Scoped packages - if (startsWith(components[0], "@")) { + if (ts.startsWith(components[0], "@")) { return `${components[0]}/${components[1]}`; } return components[0]; @@ -3154,30 +3159,30 @@ namespace ts { } } - export function consumesNodeCoreModules(sourceFile: SourceFile): boolean { - return some(sourceFile.imports, ({ text }) => JsTyping.nodeCoreModules.has(text)); + export function consumesNodeCoreModules(sourceFile: ts.SourceFile): boolean { + return ts.some(sourceFile.imports, ({ text }) => ts.JsTyping.nodeCoreModules.has(text)); } export function isInsideNodeModules(fileOrDirectory: string): boolean { - return contains(getPathComponents(fileOrDirectory), "node_modules"); + return ts.contains(ts.getPathComponents(fileOrDirectory), "node_modules"); } - export function isDiagnosticWithLocation(diagnostic: Diagnostic): diagnostic is DiagnosticWithLocation { + export function isDiagnosticWithLocation(diagnostic: ts.Diagnostic): diagnostic is ts.DiagnosticWithLocation { return diagnostic.file !== undefined && diagnostic.start !== undefined && diagnostic.length !== undefined; } - export function findDiagnosticForNode(node: Node, sortedFileDiagnostics: readonly Diagnostic[]): DiagnosticWithLocation | undefined { - const span: Partial = createTextSpanFromNode(node); - const index = binarySearchKey(sortedFileDiagnostics, span, identity, compareTextSpans); + export function findDiagnosticForNode(node: ts.Node, sortedFileDiagnostics: readonly ts.Diagnostic[]): ts.DiagnosticWithLocation | undefined { + const span: Partial = createTextSpanFromNode(node); + const index = ts.binarySearchKey(sortedFileDiagnostics, span, ts.identity, ts.compareTextSpans); if (index >= 0) { const diagnostic = sortedFileDiagnostics[index]; - Debug.assertEqual(diagnostic.file, node.getSourceFile(), "Diagnostics proided to 'findDiagnosticForNode' must be from a single SourceFile"); - return cast(diagnostic, isDiagnosticWithLocation); + ts.Debug.assertEqual(diagnostic.file, node.getSourceFile(), "Diagnostics proided to 'findDiagnosticForNode' must be from a single SourceFile"); + return ts.cast(diagnostic, isDiagnosticWithLocation); } } - export function getDiagnosticsWithinSpan(span: TextSpan, sortedFileDiagnostics: readonly Diagnostic[]): readonly DiagnosticWithLocation[] { - let index = binarySearchKey(sortedFileDiagnostics, span.start, diag => diag.start, compareValues); + export function getDiagnosticsWithinSpan(span: ts.TextSpan, sortedFileDiagnostics: readonly ts.Diagnostic[]): readonly ts.DiagnosticWithLocation[] { + let index = ts.binarySearchKey(sortedFileDiagnostics, span.start, diag => diag.start, ts.compareValues); if (index < 0) { index = ~index; } @@ -3185,14 +3190,14 @@ namespace ts { index--; } - const result: DiagnosticWithLocation[] = []; - const end = textSpanEnd(span); + const result: ts.DiagnosticWithLocation[] = []; + const end = ts.textSpanEnd(span); while (true) { - const diagnostic = tryCast(sortedFileDiagnostics[index], isDiagnosticWithLocation); + const diagnostic = ts.tryCast(sortedFileDiagnostics[index], isDiagnosticWithLocation); if (!diagnostic || diagnostic.start > end) { break; } - if (textSpanContainsTextSpan(span, diagnostic)) { + if (ts.textSpanContainsTextSpan(span, diagnostic)) { result.push(diagnostic); } index++; @@ -3202,22 +3207,22 @@ namespace ts { } /* @internal */ - export function getRefactorContextSpan({ startPosition, endPosition }: RefactorContext): TextSpan { - return createTextSpanFromBounds(startPosition, endPosition === undefined ? startPosition : endPosition); + export function getRefactorContextSpan({ startPosition, endPosition }: ts.RefactorContext): ts.TextSpan { + return ts.createTextSpanFromBounds(startPosition, endPosition === undefined ? startPosition : endPosition); } /* @internal */ - export function getFixableErrorSpanExpression(sourceFile: SourceFile, span: TextSpan): Expression | undefined { + export function getFixableErrorSpanExpression(sourceFile: ts.SourceFile, span: ts.TextSpan): ts.Expression | undefined { const token = getTokenAtPosition(sourceFile, span.start); // Checker has already done work to determine that await might be possible, and has attached // related info to the node, so start by finding the expression that exactly matches up // with the diagnostic range. - const expression = findAncestor(token, node => { - if (node.getStart(sourceFile) < span.start || node.getEnd() > textSpanEnd(span)) { + const expression = ts.findAncestor(token, node => { + if (node.getStart(sourceFile) < span.start || node.getEnd() > ts.textSpanEnd(span)) { return "quit"; } - return isExpression(node) && textSpansEqual(span, createTextSpanFromNode(node, sourceFile)); - }) as Expression | undefined; + return ts.isExpression(node) && textSpansEqual(span, createTextSpanFromNode(node, sourceFile)); + }) as ts.Expression | undefined; return expression; } @@ -3230,56 +3235,59 @@ namespace ts { export function mapOneOrMany(valueOrArray: T | readonly T[] | undefined, f: (x: T, i: number) => U): U | U[] | undefined; export function mapOneOrMany(valueOrArray: T | readonly T[], f: (x: T, i: number) => U, resultSelector: (x: U[]) => U): U; export function mapOneOrMany(valueOrArray: T | readonly T[] | undefined, f: (x: T, i: number) => U, resultSelector: (x: U[]) => U): U | undefined; - export function mapOneOrMany(valueOrArray: T | readonly T[] | undefined, f: (x: T, i: number) => U, resultSelector: (x: U[]) => U | U[] = identity): U | U[] | undefined { - return valueOrArray ? isArray(valueOrArray) ? resultSelector(map(valueOrArray, f)) : f(valueOrArray, 0) : undefined; + export function mapOneOrMany(valueOrArray: T | readonly T[] | undefined, f: (x: T, i: number) => U, resultSelector: (x: U[]) => U | U[] = ts.identity): U | U[] | undefined { + return valueOrArray ? ts.isArray(valueOrArray) ? resultSelector(ts.map(valueOrArray, f)) : f(valueOrArray, 0) : undefined; } /** * If the provided value is an array, the first element of the array is returned; otherwise, the provided value is returned instead. */ export function firstOrOnly(valueOrArray: T | readonly T[]): T { - return isArray(valueOrArray) ? first(valueOrArray) : valueOrArray; + return ts.isArray(valueOrArray) ? ts.first(valueOrArray) : valueOrArray; } - export function getNamesForExportedSymbol(symbol: Symbol, scriptTarget: ScriptTarget | undefined): string | [lowercase: string, capitalized: string] { + export function getNamesForExportedSymbol(symbol: ts.Symbol, scriptTarget: ts.ScriptTarget | undefined): string | [ + lowercase: string, + capitalized: string + ] { if (needsNameFromDeclaration(symbol)) { const fromDeclaration = getDefaultLikeExportNameFromDeclaration(symbol); - if (fromDeclaration) return fromDeclaration; - const fileNameCase = codefix.moduleSymbolToValidIdentifier(getSymbolParentOrFail(symbol), scriptTarget, /*preferCapitalized*/ false); - const capitalized = codefix.moduleSymbolToValidIdentifier(getSymbolParentOrFail(symbol), scriptTarget, /*preferCapitalized*/ true); - if (fileNameCase === capitalized) return fileNameCase; + if (fromDeclaration) + return fromDeclaration; + const fileNameCase = ts.codefix.moduleSymbolToValidIdentifier(getSymbolParentOrFail(symbol), scriptTarget, /*preferCapitalized*/ false); + const capitalized = ts.codefix.moduleSymbolToValidIdentifier(getSymbolParentOrFail(symbol), scriptTarget, /*preferCapitalized*/ true); + if (fileNameCase === capitalized) + return fileNameCase; return [fileNameCase, capitalized]; } return symbol.name; } - export function getNameForExportedSymbol(symbol: Symbol, scriptTarget: ScriptTarget | undefined, preferCapitalized?: boolean) { + export function getNameForExportedSymbol(symbol: ts.Symbol, scriptTarget: ts.ScriptTarget | undefined, preferCapitalized?: boolean) { if (needsNameFromDeclaration(symbol)) { // Name of "export default foo;" is "foo". Name of "export default 0" is the filename converted to camelCase. return getDefaultLikeExportNameFromDeclaration(symbol) - || codefix.moduleSymbolToValidIdentifier(getSymbolParentOrFail(symbol), scriptTarget, !!preferCapitalized); + || ts.codefix.moduleSymbolToValidIdentifier(getSymbolParentOrFail(symbol), scriptTarget, !!preferCapitalized); } return symbol.name; } - function needsNameFromDeclaration(symbol: Symbol) { - return !(symbol.flags & SymbolFlags.Transient) && (symbol.escapedName === InternalSymbolName.ExportEquals || symbol.escapedName === InternalSymbolName.Default); + function needsNameFromDeclaration(symbol: ts.Symbol) { + return !(symbol.flags & ts.SymbolFlags.Transient) && (symbol.escapedName === ts.InternalSymbolName.ExportEquals || symbol.escapedName === ts.InternalSymbolName.Default); } - function getDefaultLikeExportNameFromDeclaration(symbol: Symbol) { - return firstDefined(symbol.declarations, d => isExportAssignment(d) ? tryCast(skipOuterExpressions(d.expression), isIdentifier)?.text : undefined); + function getDefaultLikeExportNameFromDeclaration(symbol: ts.Symbol) { + return ts.firstDefined(symbol.declarations, d => ts.isExportAssignment(d) ? ts.tryCast(ts.skipOuterExpressions(d.expression), ts.isIdentifier)?.text : undefined); } - function getSymbolParentOrFail(symbol: Symbol) { - return Debug.checkDefined( - symbol.parent, - `Symbol parent was undefined. Flags: ${Debug.formatSymbolFlags(symbol.flags)}. ` + + function getSymbolParentOrFail(symbol: ts.Symbol) { + return ts.Debug.checkDefined(symbol.parent, `Symbol parent was undefined. Flags: ${ts.Debug.formatSymbolFlags(symbol.flags)}. ` + `Declarations: ${symbol.declarations?.map(d => { - const kind = Debug.formatSyntaxKind(d.kind); - const inJS = isInJSFile(d); + const kind = ts.Debug.formatSyntaxKind(d.kind); + const inJS = ts.isInJSFile(d); const { expression } = d as any; - return (inJS ? "[JS]" : "") + kind + (expression ? ` (expression: ${Debug.formatSyntaxKind(expression.kind)})` : ""); + return (inJS ? "[JS]" : "") + kind + (expression ? ` (expression: ${ts.Debug.formatSyntaxKind(expression.kind)})` : ""); }).join(", ")}.`); } @@ -3307,67 +3315,75 @@ namespace ts { return false; } for (let i = 0; i < needleLength; i++) { - if (needle.charCodeAt(i) !== haystack.charCodeAt(i + startIndex)) return false; + if (needle.charCodeAt(i) !== haystack.charCodeAt(i + startIndex)) + return false; } return true; } export function startsWithUnderscore(name: string): boolean { - return name.charCodeAt(0) === CharacterCodes._; + return name.charCodeAt(0) === ts.CharacterCodes._; } - export function isGlobalDeclaration(declaration: Declaration) { + export function isGlobalDeclaration(declaration: ts.Declaration) { return !isNonGlobalDeclaration(declaration); } - export function isNonGlobalDeclaration(declaration: Declaration) { + export function isNonGlobalDeclaration(declaration: ts.Declaration) { const sourceFile = declaration.getSourceFile(); // If the file is not a module, the declaration is global if (!sourceFile.externalModuleIndicator && !sourceFile.commonJsModuleIndicator) { return false; } // If the file is a module written in TypeScript, it still might be in a `declare global` augmentation - return isInJSFile(declaration) || !findAncestor(declaration, isGlobalScopeAugmentation); + return ts.isInJSFile(declaration) || !ts.findAncestor(declaration, ts.isGlobalScopeAugmentation); } - export function isDeprecatedDeclaration(decl: Declaration) { - return !!(getCombinedNodeFlagsAlwaysIncludeJSDoc(decl) & ModifierFlags.Deprecated); + export function isDeprecatedDeclaration(decl: ts.Declaration) { + return !!(ts.getCombinedNodeFlagsAlwaysIncludeJSDoc(decl) & ts.ModifierFlags.Deprecated); } - export function shouldUseUriStyleNodeCoreModules(file: SourceFile, program: Program): boolean { - const decisionFromFile = firstDefined(file.imports, node => { - if (JsTyping.nodeCoreModules.has(node.text)) { - return startsWith(node.text, "node:"); + export function shouldUseUriStyleNodeCoreModules(file: ts.SourceFile, program: ts.Program): boolean { + const decisionFromFile = ts.firstDefined(file.imports, node => { + if (ts.JsTyping.nodeCoreModules.has(node.text)) { + return ts.startsWith(node.text, "node:"); } }); return decisionFromFile ?? program.usesUriStyleNodeCoreModules; } - export function getNewLineKind(newLineCharacter: string): NewLineKind { - return newLineCharacter === "\n" ? NewLineKind.LineFeed : NewLineKind.CarriageReturnLineFeed; + export function getNewLineKind(newLineCharacter: string): ts.NewLineKind { + return newLineCharacter === "\n" ? ts.NewLineKind.LineFeed : ts.NewLineKind.CarriageReturnLineFeed; } - export type DiagnosticAndArguments = DiagnosticMessage | [DiagnosticMessage, string] | [DiagnosticMessage, string, string]; + export type DiagnosticAndArguments = ts.DiagnosticMessage | [ + ts.DiagnosticMessage, + string + ] | [ + ts.DiagnosticMessage, + string, + string + ]; export function diagnosticToString(diag: DiagnosticAndArguments): string { - return isArray(diag) - ? formatStringFromArgs(getLocaleSpecificMessage(diag[0]), diag.slice(1) as readonly string[]) - : getLocaleSpecificMessage(diag); + return ts.isArray(diag) + ? ts.formatStringFromArgs(ts.getLocaleSpecificMessage(diag[0]), diag.slice(1) as readonly string[]) + : ts.getLocaleSpecificMessage(diag); } /** * Get format code settings for a code writing context (e.g. when formatting text changes or completions code). */ - export function getFormatCodeSettingsForWriting({ options }: formatting.FormatContext, sourceFile: SourceFile): FormatCodeSettings { - const shouldAutoDetectSemicolonPreference = !options.semicolons || options.semicolons === SemicolonPreference.Ignore; - const shouldRemoveSemicolons = options.semicolons === SemicolonPreference.Remove || shouldAutoDetectSemicolonPreference && !probablyUsesSemicolons(sourceFile); + export function getFormatCodeSettingsForWriting({ options }: ts.formatting.FormatContext, sourceFile: ts.SourceFile): ts.FormatCodeSettings { + const shouldAutoDetectSemicolonPreference = !options.semicolons || options.semicolons === ts.SemicolonPreference.Ignore; + const shouldRemoveSemicolons = options.semicolons === ts.SemicolonPreference.Remove || shouldAutoDetectSemicolonPreference && !probablyUsesSemicolons(sourceFile); return { ...options, - semicolons: shouldRemoveSemicolons ? SemicolonPreference.Remove : SemicolonPreference.Ignore, + semicolons: shouldRemoveSemicolons ? ts.SemicolonPreference.Remove : ts.SemicolonPreference.Ignore, }; } - export function jsxModeNeedsExplicitImport(jsx: JsxEmit | undefined) { - return jsx === JsxEmit.React || jsx === JsxEmit.ReactNative; + export function jsxModeNeedsExplicitImport(jsx: ts.JsxEmit | undefined) { + return jsx === ts.JsxEmit.React || jsx === ts.JsxEmit.ReactNative; } // #endregion diff --git a/src/shims/collectionShims.ts b/src/shims/collectionShims.ts index 6b868e8714e08..05f80f6479ed6 100644 --- a/src/shims/collectionShims.ts +++ b/src/shims/collectionShims.ts @@ -1,15 +1,16 @@ /* @internal */ namespace ts { - type GetIteratorCallback = | ReadonlyMapShim | undefined>(iterable: I) => IteratorShim< - I extends ReadonlyMapShim ? [K, V] : - I extends ReadonlySetShim ? T : - I extends readonly (infer T)[] ? T : - I extends undefined ? undefined : - never>; - - type IteratorResultShim = - | { value: T, done?: false } - | { value: void, done: true }; + type GetIteratorCallback = | ReadonlyMapShim | undefined>(iterable: I) => IteratorShim ? [ + K, + V + ] : I extends ReadonlySetShim ? T : I extends readonly (infer T)[] ? T : I extends undefined ? undefined : never>; + type IteratorResultShim = { + value: T; + done?: false; + } | { + value: void; + done: true; + }; interface IteratorShim { next(): IteratorResultShim; @@ -21,7 +22,10 @@ namespace ts { has(key: K): boolean; keys(): IteratorShim; values(): IteratorShim; - entries(): IteratorShim<[K, V]>; + entries(): IteratorShim<[ + K, + V + ]>; forEach(action: (value: V, key: K) => void): void; } @@ -31,14 +35,20 @@ namespace ts { clear(): void; } - type MapShimConstructor = new (iterable?: readonly (readonly [K, V])[] | ReadonlyMapShim) => MapShim; + type MapShimConstructor = new (iterable?: readonly (readonly [ + K, + V + ])[] | ReadonlyMapShim) => MapShim; interface ReadonlySetShim { readonly size: number; has(value: T): boolean; keys(): IteratorShim; values(): IteratorShim; - entries(): IteratorShim<[T, T]>; + entries(): IteratorShim<[ + T, + T + ]>; forEach(action: (value: T, key: T) => void): void; } @@ -73,7 +83,10 @@ namespace ts { prev?: MapEntry; } - interface IteratorData { + interface IteratorData { current?: MapEntry; selector: (key: K, value: V) => U; } @@ -97,7 +110,8 @@ namespace ts { const prev = entry.prev; // Entries without a 'prev' have been removed from the map. // An entry whose 'prev' points to itself is the head of the list and is invalid here. - if (!prev || prev === entry) throw new Error("Illegal state"); + if (!prev || prev === entry) + throw new Error("Illegal state"); return prev; } @@ -145,14 +159,16 @@ namespace ts { // We skip 'head' because it is an empty entry used to track iteration start. for (let entry = data.tail; entry !== data.head; entry = getPrev(entry)) { // all entries in the map should have a 'prev' pointer. - if (entry.prev === undefined) throw new Error("Illegal state"); + if (entry.prev === undefined) + throw new Error("Illegal state"); if (sameValueZero(entry.key, key)) { if (entry.next) { entry.next.prev = entry.prev; } else { // an entry in the map without a 'next' pointer must be the 'tail'. - if (data.tail !== entry) throw new Error("Illegal state"); + if (data.tail !== entry) + throw new Error("Illegal state"); data.tail = entry.prev; } @@ -196,11 +212,17 @@ namespace ts { } } - function createIteratorData(data: MapData, selector: (key: K, value: V) => U): IteratorData { + function createIteratorData(data: MapData, selector: (key: K, value: V) => U): IteratorData { return { current: data.head, selector }; } - function iteratorNext(data: IteratorData): IteratorResultShim { + function iteratorNext(data: IteratorData): IteratorResultShim { // Navigate to the next entry. data.current = getNext(data.current); if (data.current) { @@ -214,7 +236,10 @@ namespace ts { /* @internal */ export namespace ShimCollections { export function createMapShim(getIterator: GetIteratorCallback): MapShimConstructor { - class MapIterator { + class MapIterator { private _data: IteratorData; constructor(data: MapData, selector: (key: K, value: V) => U) { this._data = createIteratorData(data, selector); @@ -223,7 +248,10 @@ namespace ts { } return class Map implements MapShim { private _mapData = createMapData(); - constructor(iterable?: readonly (readonly [K, V])[] | ReadonlyMapShim) { + constructor(iterable?: readonly (readonly [ + K, + V + ])[] | ReadonlyMapShim) { forEachIteration(getIterator(iterable), ([key, value]) => this.set(key, value)); } get size() { return this._mapData.size; } @@ -234,13 +262,19 @@ namespace ts { clear(): void { clearEntries(this._mapData); } keys(): IteratorShim { return new MapIterator(this._mapData, (key, _value) => key); } values(): IteratorShim { return new MapIterator(this._mapData, (_key, value) => value); } - entries(): IteratorShim<[K, V]> { return new MapIterator(this._mapData, (key, value) => [key, value]); } + entries(): IteratorShim<[ + K, + V + ]> { return new MapIterator(this._mapData, (key, value) => [key, value]); } forEach(action: (value: V, key: K) => void): void { forEachEntry(this._mapData, action); } }; } export function createSetShim(getIterator: GetIteratorCallback): SetShimConstructor { - class SetIterator { + class SetIterator { private _data: IteratorData; constructor(data: MapData, selector: (key: K, value: V) => U) { this._data = createIteratorData(data, selector); @@ -259,7 +293,10 @@ namespace ts { clear(): void { clearEntries(this._mapData); } keys(): IteratorShim { return new SetIterator(this._mapData, (key, _value) => key); } values(): IteratorShim { return new SetIterator(this._mapData, (_key, value) => value); } - entries(): IteratorShim<[T, T]> { return new SetIterator(this._mapData, (key, value) => [key, value]); } + entries(): IteratorShim<[ + T, + T + ]> { return new SetIterator(this._mapData, (key, value) => [key, value]); } forEach(action: (value: T, key: T) => void): void { forEachEntry(this._mapData, action); } }; } diff --git a/src/testRunner/compilerRunner.ts b/src/testRunner/compilerRunner.ts index 1d320d667cf5f..3f2c0c964130d 100644 --- a/src/testRunner/compilerRunner.ts +++ b/src/testRunner/compilerRunner.ts @@ -5,13 +5,13 @@ namespace Harness { Test262 } - interface CompilerFileBasedTest extends FileBasedTest { + interface CompilerFileBasedTest extends Harness.FileBasedTest { readonly content?: string; } - export class CompilerBaselineRunner extends RunnerBase { + export class CompilerBaselineRunner extends Harness.RunnerBase { private basePath = "tests/cases"; - private testSuiteName: TestRunnerKind; + private testSuiteName: Harness.TestRunnerKind; private emit: boolean; public options: string | undefined; @@ -50,7 +50,7 @@ namespace Harness { }); // this will set up a series of describe/it blocks to run between the setup and cleanup phases - const files = this.tests.length > 0 ? this.tests : IO.enumerateTestFiles(this); + const files = this.tests.length > 0 ? this.tests : Harness.IO.enumerateTestFiles(this); files.forEach(test => { const file = typeof test === "string" ? test : test.file; this.checkTestCodeOutput(vpath.normalizeSeparators(file), typeof test === "string" ? CompilerTest.getConfigurations(test) : test); @@ -61,7 +61,7 @@ namespace Harness { public checkTestCodeOutput(fileName: string, test?: CompilerFileBasedTest) { if (test && ts.some(test.configurations)) { test.configurations.forEach(configuration => { - describe(`${this.testSuiteName} tests for ${fileName}${configuration ? ` (${getFileBasedTestConfigurationDescription(configuration)})` : ``}`, () => { + describe(`${this.testSuiteName} tests for ${fileName}${configuration ? ` (${Harness.getFileBasedTestConfigurationDescription(configuration)})` : ``}`, () => { this.runSuite(fileName, test, configuration); }); }); @@ -73,7 +73,7 @@ namespace Harness { } } - private runSuite(fileName: string, test?: CompilerFileBasedTest, configuration?: FileBasedTestConfiguration) { + private runSuite(fileName: string, test?: CompilerFileBasedTest, configuration?: Harness.FileBasedTestConfiguration) { // Mocha holds onto the closure environment of the describe callback even after the test is done. // Everything declared here should be cleared out in the "after" callback. let compilerTest!: CompilerTest; @@ -81,7 +81,7 @@ namespace Harness { let payload; if (test && test.content) { const rootDir = test.file.indexOf("conformance") === -1 ? "tests/cases/compiler/" : ts.getDirectoryPath(test.file) + "/"; - payload = TestCaseParser.makeUnitsFromTest(test.content, test.file, rootDir); + payload = Harness.TestCaseParser.makeUnitsFromTest(test.content, test.file, rootDir); } compilerTest = new CompilerTest(fileName, payload, configuration); }); @@ -146,18 +146,17 @@ namespace Harness { private fileName: string; private justName: string; private configuredName: string; - private lastUnit: TestCaseParser.TestUnitData; - private harnessSettings: TestCaseParser.CompilerSettings; + private lastUnit: Harness.TestCaseParser.TestUnitData; + private harnessSettings: Harness.TestCaseParser.CompilerSettings; private hasNonDtsFiles: boolean; private result: compiler.CompilationResult; private options: ts.CompilerOptions; - private tsConfigFiles: Compiler.TestFile[]; + private tsConfigFiles: Harness.Compiler.TestFile[]; // equivalent to the files that will be passed on the command line - private toBeCompiled: Compiler.TestFile[]; + private toBeCompiled: Harness.Compiler.TestFile[]; // equivalent to other files on the file system not directly passed to the compiler (ie things that are referenced by other files) - private otherFiles: Compiler.TestFile[]; - - constructor(fileName: string, testCaseContent?: TestCaseParser.TestCaseContent, configurationOverrides?: TestCaseParser.CompilerSettings) { + private otherFiles: Harness.Compiler.TestFile[]; + constructor(fileName: string, testCaseContent?: Harness.TestCaseParser.TestCaseContent, configurationOverrides?: Harness.TestCaseParser.CompilerSettings) { this.fileName = fileName; this.justName = vpath.basename(fileName); this.configuredName = this.justName; @@ -182,7 +181,7 @@ namespace Harness { const rootDir = fileName.indexOf("conformance") === -1 ? "tests/cases/compiler/" : ts.getDirectoryPath(fileName) + "/"; if (testCaseContent === undefined) { - testCaseContent = TestCaseParser.makeUnitsFromTest(IO.readFile(fileName)!, fileName, rootDir); + testCaseContent = Harness.TestCaseParser.makeUnitsFromTest(Harness.IO.readFile(fileName)!, fileName, rootDir); } if (configurationOverrides) { @@ -234,39 +233,29 @@ namespace Harness { tsConfigOptions.configFile!.fileName = tsConfigOptions.configFilePath; } - this.result = Compiler.compileFiles( - this.toBeCompiled, - this.otherFiles, - this.harnessSettings, + this.result = Harness.Compiler.compileFiles(this.toBeCompiled, this.otherFiles, this.harnessSettings, /*options*/ tsConfigOptions, - /*currentDirectory*/ this.harnessSettings.currentDirectory, - testCaseContent.symlinks - ); + /*currentDirectory*/ this.harnessSettings.currentDirectory, testCaseContent.symlinks); this.options = this.result.options; } public static getConfigurations(file: string): CompilerFileBasedTest { // also see `parseCompilerTestConfigurations` in tests/webTestServer.ts - const content = IO.readFile(file)!; - const settings = TestCaseParser.extractCompilerSettings(content); - const configurations = getFileBasedTestConfigurations(settings, CompilerTest.varyBy); + const content = Harness.IO.readFile(file)!; + const settings = Harness.TestCaseParser.extractCompilerSettings(content); + const configurations = Harness.getFileBasedTestConfigurations(settings, CompilerTest.varyBy); return { file, configurations, content }; } public verifyDiagnostics() { // check errors - Compiler.doErrorBaseline( - this.configuredName, - this.tsConfigFiles.concat(this.toBeCompiled, this.otherFiles), - this.result.diagnostics, - !!this.options.pretty); + Harness.Compiler.doErrorBaseline(this.configuredName, this.tsConfigFiles.concat(this.toBeCompiled, this.otherFiles), this.result.diagnostics, !!this.options.pretty); } public verifyModuleResolution() { if (this.options.traceResolution) { - Baseline.runBaseline(this.configuredName.replace(/\.tsx?$/, ".trace.json"), - JSON.stringify(this.result.traces.map(Utils.sanitizeTraceResolutionLogEntry), undefined, 4)); + Harness.Baseline.runBaseline(this.configuredName.replace(/\.tsx?$/, ".trace.json"), JSON.stringify(this.result.traces.map(Utils.sanitizeTraceResolutionLogEntry), undefined, 4)); } } @@ -277,30 +266,18 @@ namespace Harness { // Because of the noEmitOnError option no files are created. We need to return null because baselining isn't required. ? null // eslint-disable-line no-null/no-null : record; - Baseline.runBaseline(this.configuredName.replace(/\.tsx?$/, ".sourcemap.txt"), baseline); + Harness.Baseline.runBaseline(this.configuredName.replace(/\.tsx?$/, ".sourcemap.txt"), baseline); } } public verifyJavaScriptOutput() { if (this.hasNonDtsFiles) { - Compiler.doJsEmitBaseline( - this.configuredName, - this.fileName, - this.options, - this.result, - this.tsConfigFiles, - this.toBeCompiled, - this.otherFiles, - this.harnessSettings); + Harness.Compiler.doJsEmitBaseline(this.configuredName, this.fileName, this.options, this.result, this.tsConfigFiles, this.toBeCompiled, this.otherFiles, this.harnessSettings); } } public verifySourceMapOutput() { - Compiler.doSourcemapBaseline( - this.configuredName, - this.options, - this.result, - this.harnessSettings); + Harness.Compiler.doSourcemapBaseline(this.configuredName, this.options, this.result, this.harnessSettings); } public verifyTypesAndSymbols() { @@ -308,32 +285,26 @@ namespace Harness { return; } - const noTypesAndSymbols = - this.harnessSettings.noTypesAndSymbols && + const noTypesAndSymbols = this.harnessSettings.noTypesAndSymbols && this.harnessSettings.noTypesAndSymbols.toLowerCase() === "true"; if (noTypesAndSymbols) { return; } - Compiler.doTypeAndSymbolBaseline( - this.configuredName, - this.result.program!, - this.toBeCompiled.concat(this.otherFiles).filter(file => !!this.result.program!.getSourceFile(file.unitName)), + Harness.Compiler.doTypeAndSymbolBaseline(this.configuredName, this.result.program!, this.toBeCompiled.concat(this.otherFiles).filter(file => !!this.result.program!.getSourceFile(file.unitName)), /*opts*/ undefined, /*multifile*/ undefined, /*skipTypeBaselines*/ undefined, - /*skipSymbolBaselines*/ undefined, - !!ts.length(this.result.diagnostics) - ); + /*skipSymbolBaselines*/ undefined, !!ts.length(this.result.diagnostics)); } private makeUnitName(name: string, root: string) { const path = ts.toPath(name, root, ts.identity); - const pathStart = ts.toPath(IO.getCurrentDirectory(), "", ts.identity); + const pathStart = ts.toPath(Harness.IO.getCurrentDirectory(), "", ts.identity); return pathStart ? path.replace(pathStart, "/") : path; } - private createHarnessTestFile(lastUnit: TestCaseParser.TestUnitData, rootDir: string, unitName?: string): Compiler.TestFile { + private createHarnessTestFile(lastUnit: Harness.TestCaseParser.TestUnitData, rootDir: string, unitName?: string): Harness.Compiler.TestFile { return { unitName: unitName || this.makeUnitName(lastUnit.name, rootDir), content: lastUnit.content, fileOptions: lastUnit.fileOptions }; } } diff --git a/src/testRunner/externalCompileRunner.ts b/src/testRunner/externalCompileRunner.ts index 737377d89d7a8..8c7dc16e69140 100644 --- a/src/testRunner/externalCompileRunner.ts +++ b/src/testRunner/externalCompileRunner.ts @@ -16,11 +16,11 @@ namespace Harness { path?: string; } - abstract class ExternalCompileRunnerBase extends RunnerBase { + abstract class ExternalCompileRunnerBase extends Harness.RunnerBase { abstract testDir: string; abstract report(result: ExecResult, cwd: string): string | null; enumerateTestFiles() { - return IO.getDirectories(this.testDir); + return Harness.IO.getDirectories(this.testDir); } /** Setup the runner's tests so that they are ready to be executed by the harness * The first test should be a describe/it block that sets up the harness's compiler instance appropriately @@ -32,7 +32,7 @@ namespace Harness { // eslint-disable-next-line @typescript-eslint/no-this-alias const cls = this; describe(`${this.kind()} code samples`, function (this: Mocha.Suite) { - this.timeout(600_000); // 10 minutes + this.timeout(600000); // 10 minutes for (const test of testList) { cls.runTest(typeof test === "string" ? test : test.file); } @@ -41,15 +41,15 @@ namespace Harness { private runTest(directoryName: string) { // eslint-disable-next-line @typescript-eslint/no-this-alias const cls = this; - const timeout = 600_000; // 10 minutes + const timeout = 600000; // 10 minutes describe(directoryName, function (this: Mocha.Suite) { this.timeout(timeout); const cp: typeof import("child_process") = require("child_process"); it("should build successfully", () => { - let cwd = path.join(IO.getWorkspaceRoot(), cls.testDir, directoryName); + let cwd = path.join(Harness.IO.getWorkspaceRoot(), cls.testDir, directoryName); const originalCwd = cwd; - const stdio = isWorker ? "pipe" : "inherit"; + const stdio = Harness.isWorker ? "pipe" : "inherit"; let types: string[] | undefined; if (fs.existsSync(path.join(cwd, "test.json"))) { const config = JSON.parse(fs.readFileSync(path.join(cwd, "test.json"), { encoding: "utf8" })) as UserConfig; @@ -82,7 +82,7 @@ namespace Harness { } exec("npm", ["i", "--ignore-scripts", ...(isV7OrLater ? ["--legacy-peer-deps"] : [])], { cwd, timeout: timeout / 2 }); // NPM shouldn't take the entire timeout - if it takes a long time, it should be terminated and we should log the failure } - const args = [path.join(IO.getWorkspaceRoot(), "built/local/tsc.js")]; + const args = [path.join(Harness.IO.getWorkspaceRoot(), "built/local/tsc.js")]; if (types) { args.push("--types", types.join(",")); // Also actually install those types (for, eg, the js projects which need node) @@ -91,10 +91,13 @@ namespace Harness { } } args.push("--noEmit"); - Baseline.runBaseline(`${cls.kind()}/${directoryName}.log`, cls.report(cp.spawnSync(`node`, args, { cwd, timeout, shell: true }), cwd)); - - function exec(command: string, args: string[], options: { cwd: string, timeout?: number, stdio?: import("child_process").StdioOptions }): string | undefined { - const res = cp.spawnSync(isWorker ? `${command} 2>&1` : command, args, { shell: true, stdio, ...options }); + Harness.Baseline.runBaseline(`${cls.kind()}/${directoryName}.log`, cls.report(cp.spawnSync(`node`, args, { cwd, timeout, shell: true }), cwd)); + function exec(command: string, args: string[], options: { + cwd: string; + timeout?: number; + stdio?: import("child_process").StdioOptions; + }): string | undefined { + const res = cp.spawnSync(Harness.isWorker ? `${command} 2>&1` : command, args, { shell: true, stdio, ...options }); if (res.status !== 0) { throw new Error(`${command} ${args.join(" ")} for ${directoryName} failed: ${res.stdout && res.stdout.toString()}`); } @@ -107,7 +110,7 @@ namespace Harness { export class UserCodeRunner extends ExternalCompileRunnerBase { readonly testDir = "tests/cases/user/"; - kind(): TestRunnerKind { + kind(): Harness.TestRunnerKind { return "user"; } report(result: ExecResult) { @@ -124,7 +127,7 @@ ${stripAbsoluteImportPaths(result.stderr.toString().replace(/\r\n/g, "\n"))}`; export class DockerfileRunner extends ExternalCompileRunnerBase { readonly testDir = "tests/cases/docker/"; - kind(): TestRunnerKind { + kind(): Harness.TestRunnerKind { return "docker"; } initializeTests(): void { @@ -136,26 +139,28 @@ ${stripAbsoluteImportPaths(result.stderr.toString().replace(/\r\n/g, "\n"))}`; describe(`${this.kind()} code samples`, function (this: Mocha.Suite) { this.timeout(cls.timeout); // 20 minutes before(() => { - cls.exec("docker", ["build", ".", "-t", "typescript/typescript"], { cwd: IO.getWorkspaceRoot() }); // cached because workspace is hashed to determine cacheability + cls.exec("docker", ["build", ".", "-t", "typescript/typescript"], { cwd: Harness.IO.getWorkspaceRoot() }); // cached because workspace is hashed to determine cacheability }); for (const test of testList) { const directory = typeof test === "string" ? test : test.file; - const cwd = path.join(IO.getWorkspaceRoot(), cls.testDir, directory); + const cwd = path.join(Harness.IO.getWorkspaceRoot(), cls.testDir, directory); it(`should build ${directory} successfully`, () => { const imageName = `tstest/${directory}`; cls.exec("docker", ["build", "--no-cache", ".", "-t", imageName], { cwd }); // --no-cache so the latest version of the repos referenced is always fetched const cp: typeof import("child_process") = require("child_process"); - Baseline.runBaseline(`${cls.kind()}/${directory}.log`, cls.report(cp.spawnSync(`docker`, ["run", imageName], { cwd, timeout: cls.timeout, shell: true }))); + Harness.Baseline.runBaseline(`${cls.kind()}/${directory}.log`, cls.report(cp.spawnSync(`docker`, ["run", imageName], { cwd, timeout: cls.timeout, shell: true }))); }); } }); } - private timeout = 1_200_000; // 20 minutes; - private exec(command: string, args: string[], options: { cwd: string }): void { + private timeout = 1200000; // 20 minutes; + private exec(command: string, args: string[], options: { + cwd: string; + }): void { const cp: typeof import("child_process") = require("child_process"); - const stdio = isWorker ? "pipe" : "inherit"; - const res = cp.spawnSync(isWorker ? `${command} 2>&1` : command, args, { timeout: this.timeout, shell: true, stdio, ...options }); + const stdio = Harness.isWorker ? "pipe" : "inherit"; + const res = cp.spawnSync(Harness.isWorker ? `${command} 2>&1` : command, args, { timeout: this.timeout, shell: true, stdio, ...options }); if (res.status !== 0) { throw new Error(`${command} ${args.join(" ")} for ${options.cwd} failed: ${res.stdout && res.stdout.toString()}`); } @@ -243,7 +248,7 @@ ${sanitizeDockerfileOutput(result.stderr.toString())}`; * This is problematic for error baselines, so we grep for them and strip them out. */ function stripAbsoluteImportPaths(result: string) { - const workspaceRegexp = new RegExp(IO.getWorkspaceRoot().replace(/\\/g, "\\\\"), "g"); + const workspaceRegexp = new RegExp(Harness.IO.getWorkspaceRoot().replace(/\\/g, "\\\\"), "g"); return result .replace(/import\(".*?\/tests\/cases\/user\//g, `import("/`) .replace(/Module '".*?\/tests\/cases\/user\//g, `Module '"/`) @@ -278,7 +283,7 @@ ${sanitizeDockerfileOutput(result.stderr.toString())}`; export class DefinitelyTypedRunner extends ExternalCompileRunnerBase { readonly testDir = "../DefinitelyTyped/types/"; workingDirectory = this.testDir; - kind(): TestRunnerKind { + kind(): Harness.TestRunnerKind { return "dt"; } report(result: ExecResult, cwd: string) { diff --git a/src/testRunner/fourslashRunner.ts b/src/testRunner/fourslashRunner.ts index b996542a0a55e..20432f5c42dee 100644 --- a/src/testRunner/fourslashRunner.ts +++ b/src/testRunner/fourslashRunner.ts @@ -1,7 +1,7 @@ namespace Harness { - export class FourSlashRunner extends RunnerBase { + export class FourSlashRunner extends Harness.RunnerBase { protected basePath: string; - protected testSuiteName: TestRunnerKind; + protected testSuiteName: Harness.TestRunnerKind; constructor(private testType: FourSlash.FourSlashTestType) { super(); @@ -38,7 +38,7 @@ namespace Harness { public initializeTests() { if (this.tests.length === 0) { - this.tests = IO.enumerateTestFiles(this); + this.tests = Harness.IO.enumerateTestFiles(this); } describe(this.testSuiteName + " tests", () => { @@ -50,7 +50,8 @@ namespace Harness { // Convert to relative path const testIndex = fn.indexOf("tests/"); - if (testIndex >= 0) fn = fn.substr(testIndex); + if (testIndex >= 0) + fn = fn.substr(testIndex); if (justName !== "fourslash.ts") { it(this.testSuiteName + " test " + justName + " runs correctly", () => { diff --git a/src/testRunner/parallel/host.ts b/src/testRunner/parallel/host.ts index 819325bc85cf3..66b815d9b90ac 100644 --- a/src/testRunner/parallel/host.ts +++ b/src/testRunner/parallel/host.ts @@ -17,9 +17,9 @@ namespace Harness.Parallel.Host { const FailedTestReporter = require(Utils.findUpFile("scripts/failed-tests.js")) as typeof import("../../../scripts/failed-tests"); const perfdataFileNameFragment = ".parallelperf"; - const perfData = readSavedPerfData(configOption); - const newTasks: Task[] = []; - let tasks: Task[] = []; + const perfData = readSavedPerfData(Harness.configOption); + const newTasks: Harness.Parallel.Task[] = []; + let tasks: Harness.Parallel.Task[] = []; let unknownValue: string | undefined; let totalCost = 0; @@ -41,8 +41,8 @@ namespace Harness.Parallel.Host { } class RemoteTest extends Mocha.Test { - info: ErrorInfo | TestInfo; - constructor(info: ErrorInfo | TestInfo) { + info: Harness.Parallel.ErrorInfo | Harness.Parallel.TestInfo; + constructor(info: Harness.Parallel.ErrorInfo | Harness.Parallel.TestInfo) { super(info.name[info.name.length - 1]); this.info = info; this.state = "error" in info ? "failed" : "passed"; // eslint-disable-line no-in-operator @@ -53,7 +53,9 @@ namespace Harness.Parallel.Host { interface Worker { process: import("child_process").ChildProcess; accumulatedOutput: string; - currentTasks?: { file: string }[]; + currentTasks?: { + file: string; + }[]; timer?: any; } @@ -79,7 +81,8 @@ namespace Harness.Parallel.Host { private _lineCount: number; private _progressBars: ProgressBar[]; constructor(options?: Partial) { - if (!options) options = {}; + if (!options) + options = {}; const open = options.open || "["; const close = options.close || "]"; const complete = options.complete || "▬"; @@ -174,23 +177,27 @@ namespace Harness.Parallel.Host { return `${perfdataFileNameFragment}${target ? `.${target}` : ""}.json`; } - function readSavedPerfData(target?: string): { [testHash: string]: number } | undefined { - const perfDataContents = IO.readFile(perfdataFileName(target)); + function readSavedPerfData(target?: string): { + [testHash: string]: number; + } | undefined { + const perfDataContents = Harness.IO.readFile(perfdataFileName(target)); if (perfDataContents) { return JSON.parse(perfDataContents); } return undefined; } - function hashName(runner: TestRunnerKind | "unittest", test: string) { + function hashName(runner: Harness.TestRunnerKind | "unittest", test: string) { return `tsrunner-${runner}://${test}`; } - function startDelayed(perfData: { [testHash: string]: number } | undefined, totalCost: number) { + function startDelayed(perfData: { + [testHash: string]: number; + } | undefined, totalCost: number) { console.log(`Discovered ${tasks.length} unittest suites` + (newTasks.length ? ` and ${newTasks.length} new suites.` : ".")); console.log("Discovering runner-based tests..."); const discoverStart = +(new Date()); - for (const runner of runners) { + for (const runner of Harness.runners) { for (const test of runner.getTestFiles()) { const file = typeof test === "string" ? test : test.file; let size: number; @@ -201,7 +208,7 @@ namespace Harness.Parallel.Host { catch { // May be a directory try { - size = IO.listFiles(path.join(runner.workingDirectory, file), /.*/g, { recursive: true }).reduce((acc, elem) => acc + statSync(elem).size, 0); + size = Harness.IO.listFiles(path.join(runner.workingDirectory, file), /.*/g, { recursive: true }).reduce((acc, elem) => acc + statSync(elem).size, 0); } catch { // Unknown test kind, just return 0 and let the historical analysis take over after one run @@ -225,18 +232,20 @@ namespace Harness.Parallel.Host { } tasks.sort((a, b) => a.size - b.size); tasks = tasks.concat(newTasks); - const batchCount = workerCount; + const batchCount = Harness.workerCount; const packfraction = 0.9; const chunkSize = 1000; // ~1KB or 1s for sending batches near the end of a test - const batchSize = (totalCost / workerCount) * packfraction; // Keep spare tests for unittest thread in reserve + const batchSize = (totalCost / Harness.workerCount) * packfraction; // Keep spare tests for unittest thread in reserve console.log(`Discovered ${tasks.length} test files in ${+(new Date()) - discoverStart}ms.`); - console.log(`Starting to run tests using ${workerCount} threads...`); + console.log(`Starting to run tests using ${Harness.workerCount} threads...`); const totalFiles = tasks.length; let passingFiles = 0; let failingFiles = 0; - let errorResults: ErrorInfo[] = []; - let passingResults: { name: string[] }[] = []; + let errorResults: Harness.Parallel.ErrorInfo[] = []; + let passingResults: { + name: string[]; + }[] = []; let totalPassing = 0; const startDate = new Date(); @@ -244,15 +253,17 @@ namespace Harness.Parallel.Host { const progressUpdateInterval = 1 / progressBars._options.width; let nextProgress = progressUpdateInterval; - const newPerfData: { [testHash: string]: number } = {}; + const newPerfData: { + [testHash: string]: number; + } = {}; const workers: Worker[] = []; let closedWorkers = 0; - for (let i = 0; i < workerCount; i++) { + for (let i = 0; i < Harness.workerCount; i++) { // TODO: Just send the config over the IPC channel or in the command line arguments - const config: TestConfig = { light: lightMode, listenForWork: true, runUnitTests: Harness.runUnitTests, stackTraceLimit: Harness.stackTraceLimit, timeout: globalTimeout }; // eslint-disable-line @typescript-eslint/no-unnecessary-qualifier - const configPath = ts.combinePaths(taskConfigsFolder, `task-config${i}.json`); - IO.writeFile(configPath, JSON.stringify(config)); + const config: Harness.TestConfig = { light: Harness.lightMode, listenForWork: true, runUnitTests: Harness.runUnitTests, stackTraceLimit: Harness.stackTraceLimit, timeout: Harness.globalTimeout }; // eslint-disable-line @typescript-eslint/no-unnecessary-qualifier + const configPath = ts.combinePaths(Harness.taskConfigsFolder, `task-config${i}.json`); + Harness.IO.writeFile(configPath, JSON.stringify(config)); const worker: Worker = { process: fork(__filename, [`--config="${configPath}"`], { stdio: ["pipe", "pipe", "pipe", "ipc"] }), accumulatedOutput: "", @@ -265,7 +276,7 @@ namespace Harness.Parallel.Host { }; worker.process.stderr!.on("data", appendOutput); worker.process.stdout!.on("data", appendOutput); - const killChild = (timeout: TaskTimeout) => { + const killChild = (timeout: Harness.Parallel.TaskTimeout) => { worker.process.kill(); console.error(`Worker exceeded ${timeout.duration}ms timeout ${worker.currentTasks && worker.currentTasks.length ? `while running test '${worker.currentTasks[0].file}'.` : `during test setup.`}`); return process.exit(2); @@ -282,7 +293,7 @@ namespace Harness.Parallel.Host { return process.exit(2); } }); - worker.process.on("message", (data: ParallelClientMessage) => { + worker.process.on("message", (data: Harness.Parallel.ParallelClientMessage) => { switch (data.type) { case "error": { console.error(`Test worker encountered unexpected error${data.payload.name ? ` during the execution of test ${data.payload.name}` : ""} and was forced to close: @@ -334,7 +345,7 @@ namespace Harness.Parallel.Host { // No more tasks to distribute worker.process.send({ type: "close" }); closedWorkers++; - if (closedWorkers === workerCount) { + if (closedWorkers === Harness.workerCount) { outputFinalResult(); } return; @@ -346,10 +357,10 @@ namespace Harness.Parallel.Host { } worker.currentTasks = taskList; if (taskList.length === 1) { - worker.process.send({ type: "test", payload: taskList[0] } as ParallelHostMessage); // TODO: GH#18217 + worker.process.send({ type: "test", payload: taskList[0] } as Harness.Parallel.ParallelHostMessage); // TODO: GH#18217 } else { - worker.process.send({ type: "batch", payload: taskList } as ParallelHostMessage); // TODO: GH#18217 + worker.process.send({ type: "batch", payload: taskList } as Harness.Parallel.ParallelHostMessage); // TODO: GH#18217 } } } @@ -361,12 +372,16 @@ namespace Harness.Parallel.Host { // It's only really worth doing an initial batching if there are a ton of files to go through (and they have estimates) if (totalFiles > 1000 && batchSize > 0) { console.log("Batching initial test lists..."); - const batches: { runner: TestRunnerKind | "unittest", file: string, size: number }[][] = new Array(batchCount); + const batches: { + runner: Harness.TestRunnerKind | "unittest"; + file: string; + size: number; + }[][] = new Array(batchCount); const doneBatching = new Array(batchCount); let scheduledTotal = 0; batcher: while (true) { for (let i = 0; i < batchCount; i++) { - if (tasks.length <= workerCount) { // Keep a small reserve even in the suboptimally packed case + if (tasks.length <= Harness.workerCount) { // Keep a small reserve even in the suboptimally packed case console.log(`Suboptimal packing detected: no tests remain to be stolen. Reduce packing fraction from ${packfraction} to fix.`); break batcher; } @@ -414,7 +429,7 @@ namespace Harness.Parallel.Host { } } else { - for (let i = 0; i < workerCount; i++) { + for (let i = 0; i < Harness.workerCount; i++) { const task = tasks.pop()!; workers[i].currentTasks = [task]; workers[i].process.send({ type: "test", payload: task }); @@ -434,7 +449,7 @@ namespace Harness.Parallel.Host { const summaryTests = (isPartitionFail ? totalPassing + "/" + (errorResults.length + totalPassing) : totalPassing) + " passing"; const summaryDuration = "(" + ms(duration) + ")"; const savedUseColors = Base.useColors; - Base.useColors = !noColors; + Base.useColors = !Harness.noColors; const summary = color(summaryColor, summarySymbol + " " + summaryTests) + " " + color("light", summaryDuration); Base.useColors = savedUseColors; @@ -448,13 +463,7 @@ namespace Harness.Parallel.Host { progressColor = "fail"; } - progressBars.update( - 0, - percentComplete, - progressColor, - title, - titleColor - ); + progressBars.update(0, percentComplete, progressColor, title, titleColor); } function outputFinalResult() { @@ -463,36 +472,37 @@ namespace Harness.Parallel.Host { start: { configurable: true, enumerable: true, get() { return startDate; }, - set(_: Date) { /*do nothing*/ } + set(_: Date) { } }, end: { configurable: true, enumerable: true, get() { return endDate; }, - set(_: Date) { /*do nothing*/ } + set(_: Date) { } }, duration: { configurable: true, enumerable: true, get() { return duration; }, - set(_: number) { /*do nothing*/ } + set(_: number) { } } }); } - function rebuildSuite(failures: ErrorInfo[], passes: TestInfo[]) { + function rebuildSuite(failures: Harness.Parallel.ErrorInfo[], passes: Harness.Parallel.TestInfo[]) { const root = new RemoteSuite(""); - for (const result of [...failures, ...passes] as (ErrorInfo | TestInfo)[]) { + for (const result of [...failures, ...passes] as (Harness.Parallel.ErrorInfo | Harness.Parallel.TestInfo)[]) { getSuite(root, result.name.slice(0, -1)).addTest(new RemoteTest(result)); } return root; function getSuite(parent: RemoteSuite, titlePath: string[]): Mocha.Suite { const title = titlePath[0]; let suite = parent.suiteMap.get(title); - if (!suite) parent.addSuite(suite = new RemoteSuite(title)); + if (!suite) + parent.addSuite(suite = new RemoteSuite(title)); return titlePath.length === 1 ? suite : getSuite(suite, titlePath.slice(1)); } } - function rebuildError(result: ErrorInfo) { + function rebuildError(result: Harness.Parallel.ErrorInfo) { const error = new Error(result.error); error.stack = result.stack; return error; @@ -555,16 +565,18 @@ namespace Harness.Parallel.Host { } const savedUseColors = Base.useColors; - if (noColors) Base.useColors = false; + if (Harness.noColors) + Base.useColors = false; replayRunner.started = true; replayRunner.emit("start"); replaySuite(replayRunner, rebuildSuite(errorResults, passingResults)); replayRunner.emit("end"); consoleReporter.epilogue(); - if (noColors) Base.useColors = savedUseColors; + if (Harness.noColors) + Base.useColors = savedUseColors; // eslint-disable-next-line no-null/no-null - IO.writeFile(perfdataFileName(configOption), JSON.stringify(newPerfData, null, 4)); + Harness.IO.writeFile(perfdataFileName(Harness.configOption), JSON.stringify(newPerfData, null, 4)); if (xunitReporter) { xunitReporter.done(errorResults.length, failures => process.exit(failures)); @@ -588,15 +600,16 @@ namespace Harness.Parallel.Host { } function minMax(value: number, min: number, max: number) { - if (value < min) return min; - if (value > max) return max; + if (value < min) + return min; + if (value > max) + return max; return value; } function shimDiscoveryInterface(context: Mocha.MochaGlobals) { - shimNoopTestInterface(context); - - const perfData = readSavedPerfData(configOption); + Harness.Parallel.shimNoopTestInterface(context); + const perfData = readSavedPerfData(Harness.configOption); context.describe = addSuite as Mocha.SuiteFunction; context.it = addSuite as Mocha.TestFunction; @@ -616,11 +629,11 @@ namespace Harness.Parallel.Host { } } - if (runUnitTests) { + if (Harness.runUnitTests) { shimDiscoveryInterface(global); } else { - shimNoopTestInterface(global); + Harness.Parallel.shimNoopTestInterface(global); } // eslint-disable-next-line no-restricted-globals diff --git a/src/testRunner/parallel/shared.ts b/src/testRunner/parallel/shared.ts index bfcef09b4de3f..e9c669324d662 100644 --- a/src/testRunner/parallel/shared.ts +++ b/src/testRunner/parallel/shared.ts @@ -1,6 +1,6 @@ namespace Harness.Parallel { export interface RunnerTask { - runner: TestRunnerKind; + runner: Harness.TestRunnerKind; file: string; size: number; } @@ -53,7 +53,11 @@ namespace Harness.Parallel { export interface ParallelErrorMessage { type: "error"; - payload: { error: string, stack: string, name?: string[] }; + payload: { + error: string; + stack: string; + name?: string[]; + }; } export interface ParallelResultMessage { @@ -78,10 +82,10 @@ namespace Harness.Parallel { global.after = ts.noop; global.beforeEach = ts.noop; global.afterEach = ts.noop; - global.describe = global.context = ((_: any, __: any) => { /*empty*/ }) as Mocha.SuiteFunction; + global.describe = global.context = ((_: any, __: any) => { }) as Mocha.SuiteFunction; global.describe.skip = global.xdescribe = global.xcontext = ts.noop as Mocha.PendingSuiteFunction; global.describe.only = ts.noop as Mocha.ExclusiveSuiteFunction; - global.it = global.specify = ((_: any, __: any) => { /*empty*/ }) as Mocha.TestFunction; + global.it = global.specify = ((_: any, __: any) => { }) as Mocha.TestFunction; global.it.skip = global.xit = global.xspecify = ts.noop as Mocha.PendingTestFunction; global.it.only = ts.noop as Mocha.ExclusiveTestFunction; } diff --git a/src/testRunner/parallel/worker.ts b/src/testRunner/parallel/worker.ts index ed91b3c285fd6..217236eb4f480 100644 --- a/src/testRunner/parallel/worker.ts +++ b/src/testRunner/parallel/worker.ts @@ -59,7 +59,9 @@ namespace Harness.Parallel.Worker { * Mixes in an override for `clone` to support parallel test execution in a worker. */ function Clone(base: T) { - return class extends (base as new (...args: any[]) => { clone(): any; }) { + return class extends (base as new (...args: any[]) => { + clone(): any; + }) { clone() { const cloned = super.clone(); Object.setPrototypeOf(cloned, this.constructor.prototype); @@ -135,7 +137,7 @@ namespace Harness.Parallel.Worker { /** * Run the tests in the requested task. */ - function runTests(task: Task, fn: (payload: TaskResult) => void) { + function runTests(task: Harness.Parallel.Task, fn: (payload: Harness.Parallel.TaskResult) => void) { if (task.runner === "unittest") { return executeUnitTests(task, fn); } @@ -144,7 +146,7 @@ namespace Harness.Parallel.Worker { } } - function executeUnitTests(task: UnitTestTask, fn: (payload: TaskResult) => void) { + function executeUnitTests(task: Harness.Parallel.UnitTestTask, fn: (payload: Harness.Parallel.TaskResult) => void) { if (!unitTestSuiteMap && unitTestSuite.suites.length) { unitTestSuiteMap = new ts.Map(); for (const suite of unitTestSuite.suites) { @@ -169,7 +171,7 @@ namespace Harness.Parallel.Worker { } const root = new Suite("", new Mocha.Context()); - root.timeout(globalTimeout || 40_000); + root.timeout(Harness.globalTimeout || 40000); if (suite) { root.addSuite(suite); Object.setPrototypeOf(suite.ctx, root.ctx); @@ -191,13 +193,14 @@ namespace Harness.Parallel.Worker { }); } - function runFileTests(task: RunnerTask, fn: (result: TaskResult) => void) { + function runFileTests(task: Harness.Parallel.RunnerTask, fn: (result: Harness.Parallel.TaskResult) => void) { let instance = runners.get(task.runner); - if (!instance) runners.set(task.runner, instance = createRunner(task.runner)); + if (!instance) + runners.set(task.runner, instance = Harness.createRunner(task.runner)); instance.tests = [task.file]; const suite = new Suite("", new Mocha.Context()); - suite.timeout(globalTimeout || 40_000); + suite.timeout(Harness.globalTimeout || 40000); shimTestInterface(suite, global); instance.initializeTests(); @@ -205,9 +208,9 @@ namespace Harness.Parallel.Worker { runSuite(task, suite, fn); } - function runSuite(task: Task, suite: Mocha.Suite, fn: (result: TaskResult) => void) { - const errors: ErrorInfo[] = []; - const passes: TestInfo[] = []; + function runSuite(task: Harness.Parallel.Task, suite: Mocha.Suite, fn: (result: Harness.Parallel.TaskResult) => void) { + const errors: Harness.Parallel.ErrorInfo[] = []; + const passes: Harness.Parallel.TestInfo[] = []; const start = +new Date(); const runner = new Mocha.Runner(suite, { delay: false }); @@ -233,7 +236,7 @@ namespace Harness.Parallel.Worker { /** * Validates a message received from the host is well-formed. */ - function validateHostMessage(message: ParallelHostMessage) { + function validateHostMessage(message: Harness.Parallel.ParallelHostMessage) { switch (message.type) { case "test": return validateTest(message.payload); case "batch": return validateBatch(message.payload); @@ -245,18 +248,18 @@ namespace Harness.Parallel.Worker { /** * Validates a test task is well formed. */ - function validateTest(task: Task) { + function validateTest(task: Harness.Parallel.Task) { return !!task && !!task.runner && !!task.file; } /** * Validates a batch of test tasks are well formed. */ - function validateBatch(tasks: Task[]) { + function validateBatch(tasks: Harness.Parallel.Task[]) { return !!tasks && Array.isArray(tasks) && tasks.length > 0 && tasks.every(validateTest); } - function processHostMessage(message: ParallelHostMessage) { + function processHostMessage(message: Harness.Parallel.ParallelHostMessage) { if (!validateHostMessage(message)) { console.log("Invalid message:", message); return; @@ -269,18 +272,21 @@ namespace Harness.Parallel.Worker { } } - function processTest(task: Task, last: boolean, fn?: () => void) { + function processTest(task: Harness.Parallel.Task, last: boolean, fn?: () => void) { runTests(task, payload => { sendMessage(last ? { type: "result", payload } : { type: "progress", payload }); - if (fn) fn(); + if (fn) + fn(); }); } - function processBatch(tasks: Task[], fn?: () => void) { + function processBatch(tasks: Harness.Parallel.Task[], fn?: () => void) { const next = () => { const task = tasks.shift(); - if (task) return processTest(task, tasks.length === 0, next); - if (fn) fn(); + if (task) + return processTest(task, tasks.length === 0, next); + if (fn) + fn(); }; next(); } @@ -290,12 +296,12 @@ namespace Harness.Parallel.Worker { sendMessage({ type: "error", payload: { error: error.message, stack: error.stack! } }); } - function sendMessage(message: ParallelClientMessage) { + function sendMessage(message: Harness.Parallel.ParallelClientMessage) { process.send!(message); } // A cache of test harness Runner instances. - const runners = new ts.Map(); + const runners = new ts.Map(); // The root suite for all unit tests. let unitTestSuite: Suite; @@ -303,14 +309,14 @@ namespace Harness.Parallel.Worker { // (Unit) Tests directly within the root suite let unitTestTestMap: ts.ESMap; - if (runUnitTests) { + if (Harness.runUnitTests) { unitTestSuite = new Suite("", new Mocha.Context()); - unitTestSuite.timeout(globalTimeout || 40_000); + unitTestSuite.timeout(Harness.globalTimeout || 40000); shimTestInterface(unitTestSuite, global); } else { // ensure unit tests do not get run - shimNoopTestInterface(global); + Harness.Parallel.shimNoopTestInterface(global); } process.on("message", processHostMessage); diff --git a/src/testRunner/projectsRunner.ts b/src/testRunner/projectsRunner.ts index 580fca81c222f..2893e0cb54c82 100644 --- a/src/testRunner/projectsRunner.ts +++ b/src/testRunner/projectsRunner.ts @@ -102,11 +102,7 @@ namespace project { public readDirectory(path: string, extensions: string[], excludes: string[], includes: string[], depth: number): string[] { const result = super.readDirectory(path, extensions, excludes, includes, depth); const projectRoot = vpath.resolve(vfs.srcFolder, this._testCase.projectRoot); - return result.map(item => vpath.relative( - projectRoot, - vpath.resolve(projectRoot, item), - this.vfs.ignoreCase - )); + return result.map(item => vpath.relative(projectRoot, vpath.resolve(projectRoot, item), this.vfs.ignoreCase)); } } @@ -210,8 +206,7 @@ namespace project { const ignoreCase = this.vfs.ignoreCase; const resolutionInfo: ProjectRunnerTestCaseResolutionInfo & ts.CompilerOptions = JSON.parse(JSON.stringify(this.testCase)); resolutionInfo.resolvedInputFiles = this.compilerResult.program!.getSourceFiles() - .map(({ fileName: input }) => - vpath.beneath(vfs.builtFolder, input, this.vfs.ignoreCase) || vpath.beneath(vfs.testLibFolder, input, this.vfs.ignoreCase) ? Utils.removeTestPathPrefixes(input) : + .map(({ fileName: input }) => vpath.beneath(vfs.builtFolder, input, this.vfs.ignoreCase) || vpath.beneath(vfs.testLibFolder, input, this.vfs.ignoreCase) ? Utils.removeTestPathPrefixes(input) : vpath.isAbsolute(input) ? vpath.relative(cwd, input, ignoreCase) : input); @@ -311,10 +306,7 @@ namespace project { return url; } - private compileProjectFiles(moduleKind: ts.ModuleKind, configFileSourceFiles: readonly ts.SourceFile[], - getInputFiles: () => readonly string[], - compilerHost: ts.CompilerHost, - compilerOptions: ts.CompilerOptions): CompileProjectFilesResult { + private compileProjectFiles(moduleKind: ts.ModuleKind, configFileSourceFiles: readonly ts.SourceFile[], getInputFiles: () => readonly string[], compilerHost: ts.CompilerHost, compilerOptions: ts.CompilerOptions): CompileProjectFilesResult { const program = ts.createProgram(getInputFiles(), compilerOptions, compilerHost); const errors = ts.getPreEmitDiagnostics(program); diff --git a/src/testRunner/runner.ts b/src/testRunner/runner.ts index 4427390d7f398..d2a9888b09b28 100644 --- a/src/testRunner/runner.ts +++ b/src/testRunner/runner.ts @@ -1,15 +1,18 @@ namespace Harness { /* eslint-disable prefer-const */ - export let runners: RunnerBase[] = []; + export let runners: Harness.RunnerBase[] = []; export let iterations = 1; /* eslint-enable prefer-const */ - function runTests(runners: RunnerBase[]) { + function runTests(runners: Harness.RunnerBase[]) { for (let i = iterations; i > 0; i--) { const seen = new Map(); - const dupes: [string, string][] = []; + const dupes: [ + string, + string + ][] = []; for (const runner of runners) { - if (runner instanceof CompilerBaselineRunner || runner instanceof FourSlashRunner) { + if (runner instanceof Harness.CompilerBaselineRunner || runner instanceof Harness.FourSlashRunner) { for (const sf of runner.enumerateTestFiles()) { const full = typeof sf === "string" ? sf : sf.file; const base = vpath.basename(full).toLowerCase(); @@ -38,32 +41,32 @@ ${JSON.stringify(dupes, undefined, 2)}`); return configPath && configPath.replace(/(^[\"'])|([\"']$)/g, ""); } - export function createRunner(kind: TestRunnerKind): RunnerBase { + export function createRunner(kind: Harness.TestRunnerKind): Harness.RunnerBase { switch (kind) { case "conformance": - return new CompilerBaselineRunner(CompilerTestType.Conformance); + return new Harness.CompilerBaselineRunner(Harness.CompilerTestType.Conformance); case "compiler": - return new CompilerBaselineRunner(CompilerTestType.Regressions); + return new Harness.CompilerBaselineRunner(Harness.CompilerTestType.Regressions); case "fourslash": - return new FourSlashRunner(FourSlash.FourSlashTestType.Native); + return new Harness.FourSlashRunner(FourSlash.FourSlashTestType.Native); case "fourslash-shims": - return new FourSlashRunner(FourSlash.FourSlashTestType.Shims); + return new Harness.FourSlashRunner(FourSlash.FourSlashTestType.Shims); case "fourslash-shims-pp": - return new FourSlashRunner(FourSlash.FourSlashTestType.ShimsWithPreprocess); + return new Harness.FourSlashRunner(FourSlash.FourSlashTestType.ShimsWithPreprocess); case "fourslash-server": - return new FourSlashRunner(FourSlash.FourSlashTestType.Server); + return new Harness.FourSlashRunner(FourSlash.FourSlashTestType.Server); case "project": return new project.ProjectRunner(); case "rwc": return new RWC.RWCRunner(); case "test262": - return new Test262BaselineRunner(); + return new Harness.Test262BaselineRunner(); case "user": - return new UserCodeRunner(); + return new Harness.UserCodeRunner(); case "dt": - return new DefinitelyTypedRunner(); + return new Harness.DefinitelyTypedRunner(); case "docker": - return new DockerfileRunner(); + return new Harness.DockerfileRunner(); } return ts.Debug.fail(`Unknown runner kind ${kind}`); } @@ -73,13 +76,12 @@ ${JSON.stringify(dupes, undefined, 2)}`); const mytestconfigFileName = "mytest.config"; const testconfigFileName = "test.config"; - const customConfig = tryGetConfig(IO.args()); - const testConfigContent = - customConfig && IO.fileExists(customConfig) - ? IO.readFile(customConfig)! - : IO.fileExists(mytestconfigFileName) - ? IO.readFile(mytestconfigFileName)! - : IO.fileExists(testconfigFileName) ? IO.readFile(testconfigFileName)! : ""; + const customConfig = tryGetConfig(Harness.IO.args()); + const testConfigContent = customConfig && Harness.IO.fileExists(customConfig) + ? Harness.IO.readFile(customConfig)! + : Harness.IO.fileExists(mytestconfigFileName) + ? Harness.IO.readFile(mytestconfigFileName)! + : Harness.IO.fileExists(testconfigFileName) ? Harness.IO.readFile(testconfigFileName)! : ""; export let taskConfigsFolder: string; export let workerCount: number; @@ -105,7 +107,7 @@ ${JSON.stringify(dupes, undefined, 2)}`); } export interface TaskSet { - runner: TestRunnerKind; + runner: Harness.TestRunnerKind; files: string[]; } @@ -115,7 +117,7 @@ ${JSON.stringify(dupes, undefined, 2)}`); if (testConfigContent !== "") { const testConfig = JSON.parse(testConfigContent) as TestConfig; if (testConfig.light) { - setLightMode(true); + Harness.setLightMode(true); } if (testConfig.timeout) { globalTimeout = testConfig.timeout; @@ -134,10 +136,10 @@ ${JSON.stringify(dupes, undefined, 2)}`); keepFailed = true; } if (testConfig.shardId) { - setShardId(testConfig.shardId); + Harness.setShardId(testConfig.shardId); } if (testConfig.shards) { - setShards(testConfig.shards); + Harness.setShards(testConfig.shards); } if (testConfig.stackTraceLimit === "full") { @@ -171,44 +173,44 @@ ${JSON.stringify(dupes, undefined, 2)}`); switch (option) { case "compiler": - runners.push(new CompilerBaselineRunner(CompilerTestType.Conformance)); - runners.push(new CompilerBaselineRunner(CompilerTestType.Regressions)); + runners.push(new Harness.CompilerBaselineRunner(Harness.CompilerTestType.Conformance)); + runners.push(new Harness.CompilerBaselineRunner(Harness.CompilerTestType.Regressions)); break; case "conformance": - runners.push(new CompilerBaselineRunner(CompilerTestType.Conformance)); + runners.push(new Harness.CompilerBaselineRunner(Harness.CompilerTestType.Conformance)); break; case "project": runners.push(new project.ProjectRunner()); break; case "fourslash": - runners.push(new FourSlashRunner(FourSlash.FourSlashTestType.Native)); + runners.push(new Harness.FourSlashRunner(FourSlash.FourSlashTestType.Native)); break; case "fourslash-shims": - runners.push(new FourSlashRunner(FourSlash.FourSlashTestType.Shims)); + runners.push(new Harness.FourSlashRunner(FourSlash.FourSlashTestType.Shims)); break; case "fourslash-shims-pp": - runners.push(new FourSlashRunner(FourSlash.FourSlashTestType.ShimsWithPreprocess)); + runners.push(new Harness.FourSlashRunner(FourSlash.FourSlashTestType.ShimsWithPreprocess)); break; case "fourslash-server": - runners.push(new FourSlashRunner(FourSlash.FourSlashTestType.Server)); + runners.push(new Harness.FourSlashRunner(FourSlash.FourSlashTestType.Server)); break; case "fourslash-generated": - runners.push(new GeneratedFourslashRunner(FourSlash.FourSlashTestType.Native)); + runners.push(new Harness.GeneratedFourslashRunner(FourSlash.FourSlashTestType.Native)); break; case "rwc": runners.push(new RWC.RWCRunner()); break; case "test262": - runners.push(new Test262BaselineRunner()); + runners.push(new Harness.Test262BaselineRunner()); break; case "user": - runners.push(new UserCodeRunner()); + runners.push(new Harness.UserCodeRunner()); break; case "dt": - runners.push(new DefinitelyTypedRunner()); + runners.push(new Harness.DefinitelyTypedRunner()); break; case "docker": - runners.push(new DockerfileRunner()); + runners.push(new Harness.DockerfileRunner()); break; } } @@ -217,22 +219,22 @@ ${JSON.stringify(dupes, undefined, 2)}`); if (runners.length === 0) { // compiler - runners.push(new CompilerBaselineRunner(CompilerTestType.Conformance)); - runners.push(new CompilerBaselineRunner(CompilerTestType.Regressions)); + runners.push(new Harness.CompilerBaselineRunner(Harness.CompilerTestType.Conformance)); + runners.push(new Harness.CompilerBaselineRunner(Harness.CompilerTestType.Regressions)); runners.push(new project.ProjectRunner()); // language services - runners.push(new FourSlashRunner(FourSlash.FourSlashTestType.Native)); - runners.push(new FourSlashRunner(FourSlash.FourSlashTestType.Shims)); - runners.push(new FourSlashRunner(FourSlash.FourSlashTestType.ShimsWithPreprocess)); - runners.push(new FourSlashRunner(FourSlash.FourSlashTestType.Server)); + runners.push(new Harness.FourSlashRunner(FourSlash.FourSlashTestType.Native)); + runners.push(new Harness.FourSlashRunner(FourSlash.FourSlashTestType.Shims)); + runners.push(new Harness.FourSlashRunner(FourSlash.FourSlashTestType.ShimsWithPreprocess)); + runners.push(new Harness.FourSlashRunner(FourSlash.FourSlashTestType.Server)); // runners.push(new GeneratedFourslashRunner()); // CRON-only tests if (process.env.TRAVIS_EVENT_TYPE === "cron") { - runners.push(new UserCodeRunner()); - runners.push(new DockerfileRunner()); + runners.push(new Harness.UserCodeRunner()); + runners.push(new Harness.DockerfileRunner()); } } if (runUnitTests === undefined) { @@ -272,10 +274,10 @@ ${JSON.stringify(dupes, undefined, 2)}`); function startTestEnvironment() { isWorker = handleTestConfig(); if (isWorker) { - return Parallel.Worker.start(); + return Harness.Parallel.Worker.start(); } else if (taskConfigsFolder && workerCount && workerCount > 1) { - return Parallel.Host.start(); + return Harness.Parallel.Host.start(); } beginTests(); } diff --git a/src/testRunner/rwcRunner.ts b/src/testRunner/rwcRunner.ts index 29e86382aff34..bebde6c03bad3 100644 --- a/src/testRunner/rwcRunner.ts +++ b/src/testRunner/rwcRunner.ts @@ -48,7 +48,7 @@ namespace RWC { }); it("can compile", function (this: Mocha.Context) { - this.timeout(800_000); // Allow long timeouts for RWC compilations + this.timeout(800000); // Allow long timeouts for RWC compilations let opts!: ts.ParsedCommandLine; const ioLog: Playback.IoLog = Playback.newStyleLogIntoOldStyleLog(JSON.parse(Harness.IO.readFile(`internal/cases/rwc/${jsonPath}/test.json`)!), Harness.IO, `internal/cases/rwc/${baseName}`); @@ -121,11 +121,7 @@ namespace RWC { caseSensitive = ioLog.useCaseSensitiveFileNames || false; // Emit the results - compilerResult = Harness.Compiler.compileFiles( - inputFiles, - otherFiles, - { useCaseSensitiveFileNames: "" + caseSensitive }, - opts.options, + compilerResult = Harness.Compiler.compileFiles(inputFiles, otherFiles, { useCaseSensitiveFileNames: "" + caseSensitive }, opts.options, // Since each RWC json file specifies its current directory in its json file, we need // to pass this information in explicitly instead of acquiring it from the process. currentDirectory); @@ -146,7 +142,7 @@ namespace RWC { it("has the expected emitted code", function (this: Mocha.Context) { - this.timeout(100_000); // Allow longer timeouts for RWC js verification + this.timeout(100000); // Allow longer timeouts for RWC js verification Harness.Baseline.runMultifileBaseline(baseName, "", () => { return Harness.Compiler.iterateOutputs(compilerResult.js.values()); }, baselineOpts, [".js", ".jsx"]); @@ -193,8 +189,7 @@ namespace RWC { return null; // eslint-disable-line no-null/no-null } - const declContext = Harness.Compiler.prepareDeclarationCompilationContext( - inputFiles, otherFiles, compilerResult, /*harnessSettings*/ undefined!, compilerOptions, currentDirectory // TODO: GH#18217 + const declContext = Harness.Compiler.prepareDeclarationCompilationContext(inputFiles, otherFiles, compilerResult, /*harnessSettings*/ undefined!, compilerOptions, currentDirectory // TODO: GH#18217 ); // Reset compilerResult before calling into `compileDeclarationFiles` so the memory from the original compilation can be freed const links = compilerResult.symlinks; diff --git a/src/testRunner/test262Runner.ts b/src/testRunner/test262Runner.ts index 728d3fb322790..9e3da396df9eb 100644 --- a/src/testRunner/test262Runner.ts +++ b/src/testRunner/test262Runner.ts @@ -1,11 +1,11 @@ namespace Harness { // In harness baselines, null is different than undefined. See `generateActual` in `harness.ts`. - export class Test262BaselineRunner extends RunnerBase { + export class Test262BaselineRunner extends Harness.RunnerBase { private static readonly basePath = "internal/cases/test262"; private static readonly helpersFilePath = "tests/cases/test262-harness/helpers.d.ts"; - private static readonly helperFile: Compiler.TestFile = { + private static readonly helperFile: Harness.Compiler.TestFile = { unitName: Test262BaselineRunner.helpersFilePath, - content: IO.readFile(Test262BaselineRunner.helpersFilePath)!, + content: Harness.IO.readFile(Test262BaselineRunner.helpersFilePath)!, }; private static readonly testFileExtensionRegex = /\.js$/; private static readonly options: ts.CompilerOptions = { @@ -13,7 +13,7 @@ namespace Harness { target: ts.ScriptTarget.Latest, module: ts.ModuleKind.CommonJS }; - private static readonly baselineOptions: Baseline.BaselineOptions = { + private static readonly baselineOptions: Harness.Baseline.BaselineOptions = { Subfolder: "test262", Baselinefolder: "internal/baselines" }; @@ -29,15 +29,14 @@ namespace Harness { let testState: { filename: string; compilerResult: compiler.CompilationResult; - inputFiles: Compiler.TestFile[]; + inputFiles: Harness.Compiler.TestFile[]; }; before(() => { - const content = IO.readFile(filePath)!; + const content = Harness.IO.readFile(filePath)!; const testFilename = ts.removeFileExtension(filePath).replace(/\//g, "_") + ".test"; - const testCaseContent = TestCaseParser.makeUnitsFromTest(content, testFilename); - - const inputFiles: Compiler.TestFile[] = testCaseContent.testUnitData.map(unit => { + const testCaseContent = Harness.TestCaseParser.makeUnitsFromTest(content, testFilename); + const inputFiles: Harness.Compiler.TestFile[] = testCaseContent.testUnitData.map(unit => { const unitName = Test262BaselineRunner.getTestFilePath(unit.name); return { unitName, content: unit.content }; }); @@ -49,11 +48,9 @@ namespace Harness { compilerResult: undefined!, // TODO: GH#18217 }; - testState.compilerResult = Compiler.compileFiles( - [Test262BaselineRunner.helperFile].concat(inputFiles), + testState.compilerResult = Harness.Compiler.compileFiles([Test262BaselineRunner.helperFile].concat(inputFiles), /*otherFiles*/ [], - /* harnessOptions */ undefined, - Test262BaselineRunner.options, + /* harnessOptions */ undefined, Test262BaselineRunner.options, /* currentDirectory */ undefined); }); @@ -63,14 +60,14 @@ namespace Harness { it("has the expected emitted code", () => { const files = Array.from(testState.compilerResult.js.values()).filter(f => f.file !== Test262BaselineRunner.helpersFilePath); - Baseline.runBaseline(testState.filename + ".output.js", Compiler.collateOutputs(files), Test262BaselineRunner.baselineOptions); + Harness.Baseline.runBaseline(testState.filename + ".output.js", Harness.Compiler.collateOutputs(files), Test262BaselineRunner.baselineOptions); }); it("has the expected errors", () => { const errors = testState.compilerResult.diagnostics; // eslint-disable-next-line no-null/no-null - const baseline = errors.length === 0 ? null : Compiler.getErrorBaseline(testState.inputFiles, errors); - Baseline.runBaseline(testState.filename + ".errors.txt", baseline, Test262BaselineRunner.baselineOptions); + const baseline = errors.length === 0 ? null : Harness.Compiler.getErrorBaseline(testState.inputFiles, errors); + Harness.Baseline.runBaseline(testState.filename + ".errors.txt", baseline, Test262BaselineRunner.baselineOptions); }); it("satisfies invariants", () => { @@ -80,12 +77,12 @@ namespace Harness { it("has the expected AST", () => { const sourceFile = testState.compilerResult.program!.getSourceFile(Test262BaselineRunner.getTestFilePath(testState.filename))!; - Baseline.runBaseline(testState.filename + ".AST.txt", Utils.sourceFileToJSON(sourceFile), Test262BaselineRunner.baselineOptions); + Harness.Baseline.runBaseline(testState.filename + ".AST.txt", Utils.sourceFileToJSON(sourceFile), Test262BaselineRunner.baselineOptions); }); }); } - public kind(): TestRunnerKind { + public kind(): Harness.TestRunnerKind { return "test262"; } diff --git a/src/testRunner/unittests/asserts.ts b/src/testRunner/unittests/asserts.ts index a0cde51a0f841..3efb51485465e 100644 --- a/src/testRunner/unittests/asserts.ts +++ b/src/testRunner/unittests/asserts.ts @@ -1,12 +1,12 @@ namespace ts { describe("unittests:: assert", () => { it("deepEqual", () => { - assert.throws(() => assert.deepEqual(factory.createNodeArray([factory.createIdentifier("A")]), factory.createNodeArray([factory.createIdentifier("B")]))); - assert.throws(() => assert.deepEqual(factory.createNodeArray([], /*hasTrailingComma*/ true), factory.createNodeArray([], /*hasTrailingComma*/ false))); - assert.deepEqual(factory.createNodeArray([factory.createIdentifier("A")], /*hasTrailingComma*/ true), factory.createNodeArray([factory.createIdentifier("A")], /*hasTrailingComma*/ true)); + assert.throws(() => assert.deepEqual(ts.factory.createNodeArray([ts.factory.createIdentifier("A")]), ts.factory.createNodeArray([ts.factory.createIdentifier("B")]))); + assert.throws(() => assert.deepEqual(ts.factory.createNodeArray([], /*hasTrailingComma*/ true), ts.factory.createNodeArray([], /*hasTrailingComma*/ false))); + assert.deepEqual(ts.factory.createNodeArray([ts.factory.createIdentifier("A")], /*hasTrailingComma*/ true), ts.factory.createNodeArray([ts.factory.createIdentifier("A")], /*hasTrailingComma*/ true)); }); it("assertNever on string has correct error", () => { - assert.throws(() => Debug.assertNever("hi" as never), "Debug Failure. Illegal value: \"hi\""); + assert.throws(() => ts.Debug.assertNever("hi" as never), "Debug Failure. Illegal value: \"hi\""); }); }); } diff --git a/src/testRunner/unittests/base64.ts b/src/testRunner/unittests/base64.ts index 1dc51a8fbf5ae..19ce31cc98912 100644 --- a/src/testRunner/unittests/base64.ts +++ b/src/testRunner/unittests/base64.ts @@ -14,7 +14,7 @@ namespace ts { "", ]; for (const test of tests) { - assert.equal(base64decode({}, convertToBase64(test)), test); + assert.equal(ts.base64decode({}, ts.convertToBase64(test)), test); } }); }); diff --git a/src/testRunner/unittests/builder.ts b/src/testRunner/unittests/builder.ts index bf0415f13598c..db5f0bba4168c 100644 --- a/src/testRunner/unittests/builder.ts +++ b/src/testRunner/unittests/builder.ts @@ -1,13 +1,13 @@ namespace ts { describe("unittests:: builder", () => { it("emits dependent files", () => { - const files: NamedSourceText[] = [ - { name: "/a.ts", text: SourceText.New("", 'import { b } from "./b";', "") }, - { name: "/b.ts", text: SourceText.New("", ' import { c } from "./c";', "export const b = c;") }, - { name: "/c.ts", text: SourceText.New("", "", "export const c = 0;") }, + const files: ts.NamedSourceText[] = [ + { name: "/a.ts", text: ts.SourceText.New("", 'import { b } from "./b";', "") }, + { name: "/b.ts", text: ts.SourceText.New("", ' import { c } from "./c";', "export const b = c;") }, + { name: "/c.ts", text: ts.SourceText.New("", "", "export const c = 0;") }, ]; - let program = newProgram(files, ["/a.ts"], {}); + let program = ts.newProgram(files, ["/a.ts"], {}); const assertChanges = makeAssertChanges(() => program); assertChanges(["/c.js", "/b.js", "/a.js"]); @@ -23,12 +23,12 @@ namespace ts { }); it("if emitting all files, emits the changed file first", () => { - const files: NamedSourceText[] = [ - { name: "/a.ts", text: SourceText.New("", "", "namespace A { export const x = 0; }") }, - { name: "/b.ts", text: SourceText.New("", "", "namespace B { export const x = 0; }") }, + const files: ts.NamedSourceText[] = [ + { name: "/a.ts", text: ts.SourceText.New("", "", "namespace A { export const x = 0; }") }, + { name: "/b.ts", text: ts.SourceText.New("", "", "namespace B { export const x = 0; }") }, ]; - let program = newProgram(files, ["/a.ts", "/b.ts"], {}); + let program = ts.newProgram(files, ["/a.ts", "/b.ts"], {}); const assertChanges = makeAssertChanges(() => program); assertChanges(["/a.js", "/b.js"]); @@ -41,15 +41,15 @@ namespace ts { }); it("keeps the file in affected files if cancellation token throws during the operation", () => { - const files: NamedSourceText[] = [ - { name: "/a.ts", text: SourceText.New("", 'import { b } from "./b";', "") }, - { name: "/b.ts", text: SourceText.New("", ' import { c } from "./c";', "export const b = c;") }, - { name: "/c.ts", text: SourceText.New("", "", "export const c = 0;") }, - { name: "/d.ts", text: SourceText.New("", "", "export const dd = 0;") }, - { name: "/e.ts", text: SourceText.New("", "", "export const ee = 0;") }, + const files: ts.NamedSourceText[] = [ + { name: "/a.ts", text: ts.SourceText.New("", 'import { b } from "./b";', "") }, + { name: "/b.ts", text: ts.SourceText.New("", ' import { c } from "./c";', "export const b = c;") }, + { name: "/c.ts", text: ts.SourceText.New("", "", "export const c = 0;") }, + { name: "/d.ts", text: ts.SourceText.New("", "", "export const dd = 0;") }, + { name: "/e.ts", text: ts.SourceText.New("", "", "export const ee = 0;") }, ]; - let program = newProgram(files, ["/d.ts", "/e.ts", "/a.ts"], {}); + let program = ts.newProgram(files, ["/d.ts", "/e.ts", "/a.ts"], {}); const assertChanges = makeAssertChangesWithCancellationToken(() => program); // No cancellation assertChanges(["/d.js", "/e.js", "/c.js", "/b.js", "/a.js"]); @@ -71,12 +71,12 @@ namespace ts { }); }); - function makeAssertChanges(getProgram: () => Program): (fileNames: readonly string[]) => void { - const host: BuilderProgramHost = { useCaseSensitiveFileNames: returnTrue }; - let builderProgram: EmitAndSemanticDiagnosticsBuilderProgram | undefined; + function makeAssertChanges(getProgram: () => ts.Program): (fileNames: readonly string[]) => void { + const host: ts.BuilderProgramHost = { useCaseSensitiveFileNames: ts.returnTrue }; + let builderProgram: ts.EmitAndSemanticDiagnosticsBuilderProgram | undefined; return fileNames => { const program = getProgram(); - builderProgram = createEmitAndSemanticDiagnosticsBuilderProgram(program, host, builderProgram); + builderProgram = ts.createEmitAndSemanticDiagnosticsBuilderProgram(program, host, builderProgram); const outputFileNames: string[] = []; // eslint-disable-next-line no-empty while (builderProgram.emitNextAffectedFile(fileName => outputFileNames.push(fileName))) { @@ -85,15 +85,15 @@ namespace ts { }; } - function makeAssertChangesWithCancellationToken(getProgram: () => Program): (fileNames: readonly string[], cancelAfterEmitLength?: number) => void { - const host: BuilderProgramHost = { useCaseSensitiveFileNames: returnTrue }; - let builderProgram: EmitAndSemanticDiagnosticsBuilderProgram | undefined; + function makeAssertChangesWithCancellationToken(getProgram: () => ts.Program): (fileNames: readonly string[], cancelAfterEmitLength?: number) => void { + const host: ts.BuilderProgramHost = { useCaseSensitiveFileNames: ts.returnTrue }; + let builderProgram: ts.EmitAndSemanticDiagnosticsBuilderProgram | undefined; let cancel = false; - const cancellationToken: CancellationToken = { + const cancellationToken: ts.CancellationToken = { isCancellationRequested: () => cancel, throwIfCancellationRequested: () => { if (cancel) { - throw new OperationCanceledException(); + throw new ts.OperationCanceledException(); } }, }; @@ -101,7 +101,7 @@ namespace ts { cancel = false; let operationWasCancelled = false; const program = getProgram(); - builderProgram = createEmitAndSemanticDiagnosticsBuilderProgram(program, host, builderProgram); + builderProgram = ts.createEmitAndSemanticDiagnosticsBuilderProgram(program, host, builderProgram); const outputFileNames: string[] = []; try { do { @@ -113,7 +113,7 @@ namespace ts { } catch (e) { assert.isFalse(operationWasCancelled); - assert(e instanceof OperationCanceledException, e.toString()); + assert(e instanceof ts.OperationCanceledException, e.toString()); operationWasCancelled = true; } assert.equal(cancel, operationWasCancelled); @@ -122,9 +122,9 @@ namespace ts { }; } - function updateProgramFile(program: ProgramWithSourceTexts, fileName: string, fileContent: string): ProgramWithSourceTexts { - return updateProgram(program, program.getRootFileNames(), program.getCompilerOptions(), files => { - updateProgramText(files, fileName, fileContent); + function updateProgramFile(program: ts.ProgramWithSourceTexts, fileName: string, fileContent: string): ts.ProgramWithSourceTexts { + return ts.updateProgram(program, program.getRootFileNames(), program.getCompilerOptions(), files => { + ts.updateProgramText(files, fileName, fileContent); }); } } diff --git a/src/testRunner/unittests/comments.ts b/src/testRunner/unittests/comments.ts index 59f3020c112bc..783845487ff06 100644 --- a/src/testRunner/unittests/comments.ts +++ b/src/testRunner/unittests/comments.ts @@ -11,22 +11,22 @@ namespace ts { // another one `; it("skips shebang", () => { - const result = getLeadingCommentRanges(withShebang, 0); + const result = ts.getLeadingCommentRanges(withShebang, 0); assert.isDefined(result); assert.strictEqual(result!.length, 2); }); it("treats all comments at start of file as leading comments", () => { - const result = getLeadingCommentRanges(noShebang, 0); + const result = ts.getLeadingCommentRanges(noShebang, 0); assert.isDefined(result); assert.strictEqual(result!.length, 2); }); it("returns leading comments if position is not 0", () => { - const result = getLeadingCommentRanges(withTrailing, 1); + const result = ts.getLeadingCommentRanges(withTrailing, 1); assert.isDefined(result); assert.strictEqual(result!.length, 1); - assert.strictEqual(result![0].kind, SyntaxKind.SingleLineCommentTrivia); + assert.strictEqual(result![0].kind, ts.SyntaxKind.SingleLineCommentTrivia); }); }); } diff --git a/src/testRunner/unittests/compilerCore.ts b/src/testRunner/unittests/compilerCore.ts index 49c9601a39241..8c3fe30258a71 100644 --- a/src/testRunner/unittests/compilerCore.ts +++ b/src/testRunner/unittests/compilerCore.ts @@ -2,36 +2,36 @@ namespace ts { describe("unittests:: compilerCore", () => { describe("equalOwnProperties", () => { it("correctly equates objects", () => { - assert.isTrue(equalOwnProperties({}, {})); - assert.isTrue(equalOwnProperties({ a: 1 }, { a: 1 })); - assert.isTrue(equalOwnProperties({ a: 1, b: 2 }, { b: 2, a: 1 })); + assert.isTrue(ts.equalOwnProperties({}, {})); + assert.isTrue(ts.equalOwnProperties({ a: 1 }, { a: 1 })); + assert.isTrue(ts.equalOwnProperties({ a: 1, b: 2 }, { b: 2, a: 1 })); }); it("correctly identifies unmatched objects", () => { - assert.isFalse(equalOwnProperties({}, { a: 1 }), "missing left property"); - assert.isFalse(equalOwnProperties({ a: 1 }, {}), "missing right property"); - assert.isFalse(equalOwnProperties({ a: 1 }, { a: 2 }), "differing property"); + assert.isFalse(ts.equalOwnProperties({}, { a: 1 }), "missing left property"); + assert.isFalse(ts.equalOwnProperties({ a: 1 }, {}), "missing right property"); + assert.isFalse(ts.equalOwnProperties({ a: 1 }, { a: 2 }), "differing property"); }); it("correctly identifies undefined vs hasOwnProperty", () => { - assert.isFalse(equalOwnProperties({}, { a: undefined }), "missing left property"); - assert.isFalse(equalOwnProperties({ a: undefined }, {}), "missing right property"); + assert.isFalse(ts.equalOwnProperties({}, { a: undefined }), "missing left property"); + assert.isFalse(ts.equalOwnProperties({ a: undefined }, {}), "missing right property"); }); it("truthiness", () => { const trythyTest = (l: any, r: any) => !!l === !!r; - assert.isFalse(equalOwnProperties({}, { a: 1 }, trythyTest), "missing left truthy property"); - assert.isFalse(equalOwnProperties({}, { a: 0 }, trythyTest), "missing left falsey property"); - assert.isFalse(equalOwnProperties({ a: 1 }, {}, trythyTest), "missing right truthy property"); - assert.isFalse(equalOwnProperties({ a: 0 }, {}, trythyTest), "missing right falsey property"); - assert.isTrue(equalOwnProperties({ a: 1 }, { a: "foo" }, trythyTest), "valid equality"); + assert.isFalse(ts.equalOwnProperties({}, { a: 1 }, trythyTest), "missing left truthy property"); + assert.isFalse(ts.equalOwnProperties({}, { a: 0 }, trythyTest), "missing left falsey property"); + assert.isFalse(ts.equalOwnProperties({ a: 1 }, {}, trythyTest), "missing right truthy property"); + assert.isFalse(ts.equalOwnProperties({ a: 0 }, {}, trythyTest), "missing right falsey property"); + assert.isTrue(ts.equalOwnProperties({ a: 1 }, { a: "foo" }, trythyTest), "valid equality"); }); it("all equal", () => { - assert.isFalse(equalOwnProperties({}, { a: 1 }, () => true), "missing left property"); - assert.isFalse(equalOwnProperties({ a: 1 }, {}, () => true), "missing right property"); - assert.isTrue(equalOwnProperties({ a: 1 }, { a: 2 }, () => true), "valid equality"); + assert.isFalse(ts.equalOwnProperties({}, { a: 1 }, () => true), "missing left property"); + assert.isFalse(ts.equalOwnProperties({ a: 1 }, {}, () => true), "missing right property"); + assert.isTrue(ts.equalOwnProperties({ a: 1 }, { a: 2 }, () => true), "valid equality"); }); }); describe("customSet", () => { it("mutation", () => { - const set = createSet(x => x % 2, (x, y) => (x % 4) === (y % 4)); + const set = ts.createSet(x => x % 2, (x, y) => (x % 4) === (y % 4)); assert.equal(set.size, 0); const newSet = set.add(0); @@ -71,7 +71,7 @@ namespace ts { assert.equal(set.size, 0); }); it("resizing", () => { - const set = createSet(x => x % 2, (x, y) => x === y); + const set = ts.createSet(x => x % 2, (x, y) => x === y); const elementCount = 100; for (let i = 0; i < elementCount; i++) { @@ -89,7 +89,7 @@ namespace ts { } }); it("clear", () => { - const set = createSet(x => x % 2, (x, y) => (x % 4) === (y % 4)); + const set = ts.createSet(x => x % 2, (x, y) => (x % 4) === (y % 4)); for (let j = 0; j < 2; j++) { for (let i = 0; i < 100; i++) { set.add(i); @@ -102,7 +102,7 @@ namespace ts { } }); it("forEach", () => { - const set = createSet(x => x % 2, (x, y) => (x % 4) === (y % 4)); + const set = ts.createSet(x => x % 2, (x, y) => (x % 4) === (y % 4)); for (let i = 0; i < 100; i++) { set.add(i); } @@ -125,7 +125,7 @@ namespace ts { assert.deepEqual(keys, expected); }); it("iteration", () => { - const set = createSet(x => x % 2, (x, y) => (x % 4) === (y % 4)); + const set = ts.createSet(x => x % 2, (x, y) => (x % 4) === (y % 4)); for (let i = 0; i < 4; i++) { set.add(i); } @@ -133,15 +133,15 @@ namespace ts { const expected = [0, 1, 2, 3]; let actual: number[]; - actual = arrayFrom(set.keys()); + actual = ts.arrayFrom(set.keys()); actual.sort(); assert.deepEqual(actual, expected); - actual = arrayFrom(set.values()); + actual = ts.arrayFrom(set.values()); actual.sort(); assert.deepEqual(actual, expected); - const actualTuple = arrayFrom(set.entries()); + const actualTuple = ts.arrayFrom(set.entries()); assert.isFalse(actualTuple.some(([v, k]) => v !== k)); actual = actualTuple.map(([v, _]) => v); actual.sort(); @@ -153,7 +153,7 @@ namespace ts { y: string; } - const set = createSet(t => t.y, (t, u) => t.x === u.x && t.y === u.y); + const set = ts.createSet(t => t.y, (t, u) => t.x === u.x && t.y === u.y); const thing1: Thing = { x: 1, diff --git a/src/testRunner/unittests/config/commandLineParsing.ts b/src/testRunner/unittests/config/commandLineParsing.ts index e2b48977106b6..29ddc070c815d 100644 --- a/src/testRunner/unittests/config/commandLineParsing.ts +++ b/src/testRunner/unittests/config/commandLineParsing.ts @@ -1,8 +1,8 @@ namespace ts { describe("unittests:: config:: commandLineParsing:: parseCommandLine", () => { - function assertParseResult(commandLine: string[], expectedParsedCommandLine: ParsedCommandLine, workerDiagnostic?: () => ParseCommandLineWorkerDiagnostics) { - const parsed = parseCommandLineWorker(workerDiagnostic?.() || compilerOptionsDidYouMeanDiagnostics, commandLine); + function assertParseResult(commandLine: string[], expectedParsedCommandLine: ts.ParsedCommandLine, workerDiagnostic?: () => ts.ParseCommandLineWorkerDiagnostics) { + const parsed = ts.parseCommandLineWorker(workerDiagnostic?.() || ts.compilerOptionsDidYouMeanDiagnostics, commandLine); assert.deepEqual(parsed.options, expectedParsedCommandLine.options); assert.deepEqual(parsed.watchOptions, expectedParsedCommandLine.watchOptions); @@ -36,8 +36,7 @@ namespace ts { it("Parse single option of library flag ", () => { // --lib es6 0.ts - assertParseResult(["--lib", "es6", "0.ts"], - { + assertParseResult(["--lib", "es6", "0.ts"], { errors: [], fileNames: ["0.ts"], options: { @@ -52,8 +51,8 @@ namespace ts { assertParseResult(buildFlags, { errors: buildFlags.map(buildFlag => ({ messageText: `Compiler option '${buildFlag}' may only be used with '--build'.`, - category: Diagnostics.Compiler_option_0_may_only_be_used_with_build.category, - code: Diagnostics.Compiler_option_0_may_only_be_used_with_build.code, + category: ts.Diagnostics.Compiler_option_0_may_only_be_used_with_build.category, + code: ts.Diagnostics.Compiler_option_0_may_only_be_used_with_build.code, file: undefined, start: undefined, length: undefined @@ -69,16 +68,16 @@ namespace ts { errors: [ { messageText: "Unknown compiler option '--declarations'. Did you mean 'declaration'?", - category: Diagnostics.Unknown_compiler_option_0_Did_you_mean_1.category, - code: Diagnostics.Unknown_compiler_option_0_Did_you_mean_1.code, + category: ts.Diagnostics.Unknown_compiler_option_0_Did_you_mean_1.category, + code: ts.Diagnostics.Unknown_compiler_option_0_Did_you_mean_1.code, file: undefined, start: undefined, length: undefined }, { messageText: "Unknown compiler option '--allowTS'. Did you mean 'allowJs'?", - category: Diagnostics.Unknown_compiler_option_0_Did_you_mean_1.category, - code: Diagnostics.Unknown_compiler_option_0_Did_you_mean_1.code, + category: ts.Diagnostics.Unknown_compiler_option_0_Did_you_mean_1.category, + code: ts.Diagnostics.Unknown_compiler_option_0_Did_you_mean_1.code, file: undefined, start: undefined, length: undefined @@ -92,8 +91,7 @@ namespace ts { it("Parse multiple options of library flags ", () => { // --lib es5,es2015.symbol.wellknown 0.ts - assertParseResult(["--lib", "es5,es2015.symbol.wellknown", "0.ts"], - { + assertParseResult(["--lib", "es5,es2015.symbol.wellknown", "0.ts"], { errors: [], fileNames: ["0.ts"], options: { @@ -104,12 +102,11 @@ namespace ts { it("Parse invalid option of library flags ", () => { // --lib es5,invalidOption 0.ts - assertParseResult(["--lib", "es5,invalidOption", "0.ts"], - { + assertParseResult(["--lib", "es5,invalidOption", "0.ts"], { errors: [{ messageText: "Argument for '--lib' option must be: 'es5', 'es6' [...]", - category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category, - code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code, + category: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.category, + code: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.code, file: undefined, start: undefined, length: undefined, @@ -122,20 +119,19 @@ namespace ts { }); it("Parse empty options of --jsx ", () => { // 0.ts --jsx - assertParseResult(["0.ts", "--jsx"], - { + assertParseResult(["0.ts", "--jsx"], { errors: [{ messageText: "Compiler option 'jsx' expects an argument.", - category: Diagnostics.Compiler_option_0_expects_an_argument.category, - code: Diagnostics.Compiler_option_0_expects_an_argument.code, + category: ts.Diagnostics.Compiler_option_0_expects_an_argument.category, + code: ts.Diagnostics.Compiler_option_0_expects_an_argument.code, file: undefined, start: undefined, length: undefined, }, { messageText: "Argument for '--jsx' option must be: 'preserve', 'react-native', 'react', 'react-jsx', 'react-jsxdev'.", - category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category, - code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code, + category: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.category, + code: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.code, file: undefined, start: undefined, @@ -148,20 +144,19 @@ namespace ts { it("Parse empty options of --module ", () => { // 0.ts -- - assertParseResult(["0.ts", "--module"], - { + assertParseResult(["0.ts", "--module"], { errors: [{ messageText: "Compiler option 'module' expects an argument.", - category: Diagnostics.Compiler_option_0_expects_an_argument.category, - code: Diagnostics.Compiler_option_0_expects_an_argument.code, + category: ts.Diagnostics.Compiler_option_0_expects_an_argument.category, + code: ts.Diagnostics.Compiler_option_0_expects_an_argument.code, file: undefined, start: undefined, length: undefined, }, { messageText: "Argument for '--module' option must be: 'none', 'commonjs', 'amd', 'system', 'umd', 'es6', 'es2015', 'es2020', 'es2022', 'esnext', 'node16', 'nodenext'.", - category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category, - code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code, + category: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.category, + code: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.code, file: undefined, start: undefined, @@ -174,20 +169,19 @@ namespace ts { it("Parse empty options of --newLine ", () => { // 0.ts --newLine - assertParseResult(["0.ts", "--newLine"], - { + assertParseResult(["0.ts", "--newLine"], { errors: [{ messageText: "Compiler option 'newLine' expects an argument.", - category: Diagnostics.Compiler_option_0_expects_an_argument.category, - code: Diagnostics.Compiler_option_0_expects_an_argument.code, + category: ts.Diagnostics.Compiler_option_0_expects_an_argument.category, + code: ts.Diagnostics.Compiler_option_0_expects_an_argument.code, file: undefined, start: undefined, length: undefined, }, { messageText: "Argument for '--newLine' option must be: 'crlf', 'lf'.", - category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category, - code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code, + category: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.category, + code: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.code, file: undefined, start: undefined, @@ -200,20 +194,19 @@ namespace ts { it("Parse empty options of --target ", () => { // 0.ts --target - assertParseResult(["0.ts", "--target"], - { + assertParseResult(["0.ts", "--target"], { errors: [{ messageText: "Compiler option 'target' expects an argument.", - category: Diagnostics.Compiler_option_0_expects_an_argument.category, - code: Diagnostics.Compiler_option_0_expects_an_argument.code, + category: ts.Diagnostics.Compiler_option_0_expects_an_argument.category, + code: ts.Diagnostics.Compiler_option_0_expects_an_argument.code, file: undefined, start: undefined, length: undefined, }, { messageText: "Argument for '--target' option must be: 'es3', 'es5', 'es6', 'es2015', 'es2016', 'es2017', 'es2018', 'es2019', 'es2020', 'es2021', 'es2022', 'esnext'.", - category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category, - code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code, + category: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.category, + code: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.code, file: undefined, start: undefined, @@ -226,20 +219,19 @@ namespace ts { it("Parse empty options of --moduleResolution ", () => { // 0.ts --moduleResolution - assertParseResult(["0.ts", "--moduleResolution"], - { + assertParseResult(["0.ts", "--moduleResolution"], { errors: [{ messageText: "Compiler option 'moduleResolution' expects an argument.", - category: Diagnostics.Compiler_option_0_expects_an_argument.category, - code: Diagnostics.Compiler_option_0_expects_an_argument.code, + category: ts.Diagnostics.Compiler_option_0_expects_an_argument.category, + code: ts.Diagnostics.Compiler_option_0_expects_an_argument.code, file: undefined, start: undefined, length: undefined, }, { messageText: "Argument for '--moduleResolution' option must be: 'node', 'classic', 'node16', 'nodenext'.", - category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category, - code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code, + category: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.category, + code: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.code, file: undefined, start: undefined, @@ -252,12 +244,11 @@ namespace ts { it("Parse empty options of --lib ", () => { // 0.ts --lib - assertParseResult(["0.ts", "--lib"], - { + assertParseResult(["0.ts", "--lib"], { errors: [{ messageText: "Compiler option 'lib' expects an argument.", - category: Diagnostics.Compiler_option_0_expects_an_argument.category, - code: Diagnostics.Compiler_option_0_expects_an_argument.code, + category: ts.Diagnostics.Compiler_option_0_expects_an_argument.category, + code: ts.Diagnostics.Compiler_option_0_expects_an_argument.code, file: undefined, start: undefined, @@ -273,12 +264,11 @@ namespace ts { it("Parse empty string of --lib ", () => { // 0.ts --lib // This test is an error because the empty string is falsey - assertParseResult(["0.ts", "--lib", ""], - { + assertParseResult(["0.ts", "--lib", ""], { errors: [{ messageText: "Compiler option 'lib' expects an argument.", - category: Diagnostics.Compiler_option_0_expects_an_argument.category, - code: Diagnostics.Compiler_option_0_expects_an_argument.code, + category: ts.Diagnostics.Compiler_option_0_expects_an_argument.category, + code: ts.Diagnostics.Compiler_option_0_expects_an_argument.code, file: undefined, start: undefined, @@ -293,8 +283,7 @@ namespace ts { it("Parse immediately following command line argument of --lib ", () => { // 0.ts --lib - assertParseResult(["0.ts", "--lib", "--sourcemap"], - { + assertParseResult(["0.ts", "--lib", "--sourcemap"], { errors: [], fileNames: ["0.ts"], options: { @@ -306,12 +295,11 @@ namespace ts { it("Parse --lib option with extra comma ", () => { // --lib es5, es7 0.ts - assertParseResult(["--lib", "es5,", "es7", "0.ts"], - { + assertParseResult(["--lib", "es5,", "es7", "0.ts"], { errors: [{ messageText: "Argument for '--lib' option must be: 'es5', 'es6' [...].", - category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category, - code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code, + category: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.category, + code: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.code, file: undefined, start: undefined, length: undefined, @@ -325,12 +313,11 @@ namespace ts { it("Parse --lib option with trailing white-space ", () => { // --lib es5, es7 0.ts - assertParseResult(["--lib", "es5, ", "es7", "0.ts"], - { + assertParseResult(["--lib", "es5, ", "es7", "0.ts"], { errors: [{ messageText: "Argument for '--lib' option must be: 'es5', 'es6', [...]", - category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category, - code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code, + category: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.category, + code: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.code, file: undefined, start: undefined, length: undefined, @@ -344,26 +331,24 @@ namespace ts { it("Parse multiple compiler flags with input files at the end", () => { // --lib es5,es2015.symbol.wellknown --target es5 0.ts - assertParseResult(["--lib", "es5,es2015.symbol.wellknown", "--target", "es5", "0.ts"], - { + assertParseResult(["--lib", "es5,es2015.symbol.wellknown", "--target", "es5", "0.ts"], { errors: [], fileNames: ["0.ts"], options: { lib: ["lib.es5.d.ts", "lib.es2015.symbol.wellknown.d.ts"], - target: ScriptTarget.ES5, + target: ts.ScriptTarget.ES5, } }); }); it("Parse multiple compiler flags with input files in the middle", () => { // --module commonjs --target es5 0.ts --lib es5,es2015.symbol.wellknown - assertParseResult(["--module", "commonjs", "--target", "es5", "0.ts", "--lib", "es5,es2015.symbol.wellknown"], - { + assertParseResult(["--module", "commonjs", "--target", "es5", "0.ts", "--lib", "es5,es2015.symbol.wellknown"], { errors: [], fileNames: ["0.ts"], options: { - module: ModuleKind.CommonJS, - target: ScriptTarget.ES5, + module: ts.ModuleKind.CommonJS, + target: ts.ScriptTarget.ES5, lib: ["lib.es5.d.ts", "lib.es2015.symbol.wellknown.d.ts"], } }); @@ -371,21 +356,19 @@ namespace ts { it("Parse multiple library compiler flags ", () => { // --module commonjs --target es5 --lib es5 0.ts --library es2015.array,es2015.symbol.wellknown - assertParseResult(["--module", "commonjs", "--target", "es5", "--lib", "es5", "0.ts", "--lib", "es2015.core, es2015.symbol.wellknown "], - { + assertParseResult(["--module", "commonjs", "--target", "es5", "--lib", "es5", "0.ts", "--lib", "es2015.core, es2015.symbol.wellknown "], { errors: [], fileNames: ["0.ts"], options: { - module: ModuleKind.CommonJS, - target: ScriptTarget.ES5, + module: ts.ModuleKind.CommonJS, + target: ts.ScriptTarget.ES5, lib: ["lib.es2015.core.d.ts", "lib.es2015.symbol.wellknown.d.ts"], } }); }); it("Parse explicit boolean flag value", () => { - assertParseResult(["--strictNullChecks", "false", "0.ts"], - { + assertParseResult(["--strictNullChecks", "false", "0.ts"], { errors: [], fileNames: ["0.ts"], options: { @@ -395,8 +378,7 @@ namespace ts { }); it("Parse non boolean argument after boolean flag", () => { - assertParseResult(["--noImplicitAny", "t", "0.ts"], - { + assertParseResult(["--noImplicitAny", "t", "0.ts"], { errors: [], fileNames: ["t", "0.ts"], options: { @@ -406,8 +388,7 @@ namespace ts { }); it("Parse implicit boolean flag value", () => { - assertParseResult(["--strictNullChecks"], - { + assertParseResult(["--strictNullChecks"], { errors: [], fileNames: [], options: { @@ -418,8 +399,7 @@ namespace ts { it("parse --incremental", () => { // --lib es6 0.ts - assertParseResult(["--incremental", "0.ts"], - { + assertParseResult(["--incremental", "0.ts"], { errors: [], fileNames: ["0.ts"], options: { incremental: true } @@ -428,8 +408,7 @@ namespace ts { it("parse --tsBuildInfoFile", () => { // --lib es6 0.ts - assertParseResult(["--tsBuildInfoFile", "build.tsbuildinfo", "0.ts"], - { + assertParseResult(["--tsBuildInfoFile", "build.tsbuildinfo", "0.ts"], { errors: [], fileNames: ["0.ts"], options: { tsBuildInfoFile: "build.tsbuildinfo" } @@ -440,29 +419,23 @@ namespace ts { interface VerifyNull { optionName: string; nonNullValue?: string; - workerDiagnostic?: () => ParseCommandLineWorkerDiagnostics; - diagnosticMessage: DiagnosticMessage; + workerDiagnostic?: () => ts.ParseCommandLineWorkerDiagnostics; + diagnosticMessage: ts.DiagnosticMessage; } function verifyNull({ optionName, nonNullValue, workerDiagnostic, diagnosticMessage }: VerifyNull) { it("allows setting it to null", () => { - assertParseResult( - [`--${optionName}`, "null", "0.ts"], - { + assertParseResult([`--${optionName}`, "null", "0.ts"], { errors: [], fileNames: ["0.ts"], options: { [optionName]: undefined } - }, - workerDiagnostic - ); + }, workerDiagnostic); }); if (nonNullValue) { it("errors if non null value is passed", () => { - assertParseResult( - [`--${optionName}`, nonNullValue, "0.ts"], - { + assertParseResult([`--${optionName}`, nonNullValue, "0.ts"], { errors: [{ - messageText: formatStringFromArgs(diagnosticMessage.message, [optionName]), + messageText: ts.formatStringFromArgs(diagnosticMessage.message, [optionName]), category: diagnosticMessage.category, code: diagnosticMessage.code, file: undefined, @@ -471,18 +444,14 @@ namespace ts { }], fileNames: ["0.ts"], options: {} - }, - workerDiagnostic - ); + }, workerDiagnostic); }); } it("errors if its followed by another option", () => { - assertParseResult( - ["0.ts", "--strictNullChecks", `--${optionName}`], - { + assertParseResult(["0.ts", "--strictNullChecks", `--${optionName}`], { errors: [{ - messageText: formatStringFromArgs(diagnosticMessage.message, [optionName]), + messageText: ts.formatStringFromArgs(diagnosticMessage.message, [optionName]), category: diagnosticMessage.category, code: diagnosticMessage.code, file: undefined, @@ -491,17 +460,13 @@ namespace ts { }], fileNames: ["0.ts"], options: { strictNullChecks: true } - }, - workerDiagnostic - ); + }, workerDiagnostic); }); it("errors if its last option", () => { - assertParseResult( - ["0.ts", `--${optionName}`], - { + assertParseResult(["0.ts", `--${optionName}`], { errors: [{ - messageText: formatStringFromArgs(diagnosticMessage.message, [optionName]), + messageText: ts.formatStringFromArgs(diagnosticMessage.message, [optionName]), category: diagnosticMessage.category, code: diagnosticMessage.code, file: undefined, @@ -510,37 +475,35 @@ namespace ts { }], fileNames: ["0.ts"], options: {} - }, - workerDiagnostic - ); + }, workerDiagnostic); }); } interface VerifyNullNonIncludedOption { - type: () => "string" | "number" | ESMap; + type: () => "string" | "number" | ts.ESMap; nonNullValue?: string; } function verifyNullNonIncludedOption({ type, nonNullValue }: VerifyNullNonIncludedOption) { verifyNull({ optionName: "optionName", nonNullValue, - diagnosticMessage: Diagnostics.Option_0_can_only_be_specified_in_tsconfig_json_file_or_set_to_null_on_command_line, + diagnosticMessage: ts.Diagnostics.Option_0_can_only_be_specified_in_tsconfig_json_file_or_set_to_null_on_command_line, workerDiagnostic: () => { - const optionDeclarations: CommandLineOption[] = [ - ...compilerOptionsDidYouMeanDiagnostics.optionDeclarations, + const optionDeclarations: ts.CommandLineOption[] = [ + ...ts.compilerOptionsDidYouMeanDiagnostics.optionDeclarations, { name: "optionName", type: type(), isTSConfigOnly: true, - category: Diagnostics.Backwards_Compatibility, - description: Diagnostics.Enable_project_compilation, + category: ts.Diagnostics.Backwards_Compatibility, + description: ts.Diagnostics.Enable_project_compilation, defaultValueDescription: undefined, } ]; return { - ...compilerOptionsDidYouMeanDiagnostics, + ...ts.compilerOptionsDidYouMeanDiagnostics, optionDeclarations, - getOptionsNameMap: () => createOptionNameMap(optionDeclarations) + getOptionsNameMap: () => ts.createOptionNameMap(optionDeclarations) }; } }); @@ -548,27 +511,24 @@ namespace ts { describe("option of type boolean", () => { it("allows setting it to false", () => { - assertParseResult( - ["--composite", "false", "0.ts"], - { + assertParseResult(["--composite", "false", "0.ts"], { errors: [], fileNames: ["0.ts"], options: { composite: false } - } - ); }); + }); verifyNull({ optionName: "composite", nonNullValue: "true", - diagnosticMessage: Diagnostics.Option_0_can_only_be_specified_in_tsconfig_json_file_or_set_to_false_or_null_on_command_line + diagnosticMessage: ts.Diagnostics.Option_0_can_only_be_specified_in_tsconfig_json_file_or_set_to_false_or_null_on_command_line }); }); describe("option of type object", () => { verifyNull({ optionName: "paths", - diagnosticMessage: Diagnostics.Option_0_can_only_be_specified_in_tsconfig_json_file_or_set_to_null_on_command_line + diagnosticMessage: ts.Diagnostics.Option_0_can_only_be_specified_in_tsconfig_json_file_or_set_to_null_on_command_line }); }); @@ -576,7 +536,7 @@ namespace ts { verifyNull({ optionName: "rootDirs", nonNullValue: "abc,xyz", - diagnosticMessage: Diagnostics.Option_0_can_only_be_specified_in_tsconfig_json_file_or_set_to_null_on_command_line + diagnosticMessage: ts.Diagnostics.Option_0_can_only_be_specified_in_tsconfig_json_file_or_set_to_null_on_command_line }); }); @@ -596,9 +556,9 @@ namespace ts { describe("option of type Map", () => { verifyNullNonIncludedOption({ - type: () => new Map(getEntries({ - node: ModuleResolutionKind.NodeJs, - classic: ModuleResolutionKind.Classic, + type: () => new ts.Map(ts.getEntries({ + node: ts.ModuleResolutionKind.NodeJs, + classic: ts.ModuleResolutionKind.Classic, })), nonNullValue: "node" }); @@ -606,8 +566,7 @@ namespace ts { }); it("allows tsconfig only option to be set to null", () => { - assertParseResult(["--composite", "null", "-tsBuildInfoFile", "null", "0.ts"], - { + assertParseResult(["--composite", "null", "-tsBuildInfoFile", "null", "0.ts"], { errors: [], fileNames: ["0.ts"], options: { composite: undefined, tsBuildInfoFile: undefined } @@ -616,38 +575,34 @@ namespace ts { describe("Watch options", () => { it("parse --watchFile", () => { - assertParseResult(["--watchFile", "UseFsEvents", "0.ts"], - { + assertParseResult(["--watchFile", "UseFsEvents", "0.ts"], { errors: [], fileNames: ["0.ts"], options: {}, - watchOptions: { watchFile: WatchFileKind.UseFsEvents } + watchOptions: { watchFile: ts.WatchFileKind.UseFsEvents } }); }); it("parse --watchDirectory", () => { - assertParseResult(["--watchDirectory", "FixedPollingInterval", "0.ts"], - { + assertParseResult(["--watchDirectory", "FixedPollingInterval", "0.ts"], { errors: [], fileNames: ["0.ts"], options: {}, - watchOptions: { watchDirectory: WatchDirectoryKind.FixedPollingInterval } + watchOptions: { watchDirectory: ts.WatchDirectoryKind.FixedPollingInterval } }); }); it("parse --fallbackPolling", () => { - assertParseResult(["--fallbackPolling", "PriorityInterval", "0.ts"], - { + assertParseResult(["--fallbackPolling", "PriorityInterval", "0.ts"], { errors: [], fileNames: ["0.ts"], options: {}, - watchOptions: { fallbackPolling: PollingWatchKind.PriorityInterval } + watchOptions: { fallbackPolling: ts.PollingWatchKind.PriorityInterval } }); }); it("parse --synchronousWatchDirectory", () => { - assertParseResult(["--synchronousWatchDirectory", "0.ts"], - { + assertParseResult(["--synchronousWatchDirectory", "0.ts"], { errors: [], fileNames: ["0.ts"], options: {}, @@ -656,21 +611,20 @@ namespace ts { }); it("errors on missing argument to --fallbackPolling", () => { - assertParseResult(["0.ts", "--fallbackPolling"], - { + assertParseResult(["0.ts", "--fallbackPolling"], { errors: [ { messageText: "Watch option 'fallbackPolling' requires a value of type string.", - category: Diagnostics.Watch_option_0_requires_a_value_of_type_1.category, - code: Diagnostics.Watch_option_0_requires_a_value_of_type_1.code, + category: ts.Diagnostics.Watch_option_0_requires_a_value_of_type_1.category, + code: ts.Diagnostics.Watch_option_0_requires_a_value_of_type_1.code, file: undefined, start: undefined, length: undefined }, { messageText: "Argument for '--fallbackPolling' option must be: 'fixedinterval', 'priorityinterval', 'dynamicpriority', 'fixedchunksize'.", - category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category, - code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code, + category: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.category, + code: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.code, file: undefined, start: undefined, length: undefined @@ -683,8 +637,7 @@ namespace ts { }); it("parse --excludeDirectories", () => { - assertParseResult(["--excludeDirectories", "**/temp", "0.ts"], - { + assertParseResult(["--excludeDirectories", "**/temp", "0.ts"], { errors: [], fileNames: ["0.ts"], options: {}, @@ -693,13 +646,12 @@ namespace ts { }); it("errors on invalid excludeDirectories", () => { - assertParseResult(["--excludeDirectories", "**/../*", "0.ts"], - { + assertParseResult(["--excludeDirectories", "**/../*", "0.ts"], { errors: [ { messageText: `File specification cannot contain a parent directory ('..') that appears after a recursive directory wildcard ('**'): '**/../*'.`, - category: Diagnostics.File_specification_cannot_contain_a_parent_directory_that_appears_after_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0.category, - code: Diagnostics.File_specification_cannot_contain_a_parent_directory_that_appears_after_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0.code, + category: ts.Diagnostics.File_specification_cannot_contain_a_parent_directory_that_appears_after_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0.category, + code: ts.Diagnostics.File_specification_cannot_contain_a_parent_directory_that_appears_after_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0.code, file: undefined, start: undefined, length: undefined @@ -712,8 +664,7 @@ namespace ts { }); it("parse --excludeFiles", () => { - assertParseResult(["--excludeFiles", "**/temp/*.ts", "0.ts"], - { + assertParseResult(["--excludeFiles", "**/temp/*.ts", "0.ts"], { errors: [], fileNames: ["0.ts"], options: {}, @@ -722,13 +673,12 @@ namespace ts { }); it("errors on invalid excludeFiles", () => { - assertParseResult(["--excludeFiles", "**/../*", "0.ts"], - { + assertParseResult(["--excludeFiles", "**/../*", "0.ts"], { errors: [ { messageText: `File specification cannot contain a parent directory ('..') that appears after a recursive directory wildcard ('**'): '**/../*'.`, - category: Diagnostics.File_specification_cannot_contain_a_parent_directory_that_appears_after_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0.category, - code: Diagnostics.File_specification_cannot_contain_a_parent_directory_that_appears_after_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0.code, + category: ts.Diagnostics.File_specification_cannot_contain_a_parent_directory_that_appears_after_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0.category, + code: ts.Diagnostics.File_specification_cannot_contain_a_parent_directory_that_appears_after_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0.code, file: undefined, start: undefined, length: undefined @@ -743,8 +693,8 @@ namespace ts { }); describe("unittests:: config:: commandLineParsing:: parseBuildOptions", () => { - function assertParseResult(commandLine: string[], expectedParsedBuildCommand: ParsedBuildCommand) { - const parsed = parseBuildCommand(commandLine); + function assertParseResult(commandLine: string[], expectedParsedBuildCommand: ts.ParsedBuildCommand) { + const parsed = ts.parseBuildCommand(commandLine); assert.deepEqual(parsed.buildOptions, expectedParsedBuildCommand.buildOptions); assert.deepEqual(parsed.watchOptions, expectedParsedBuildCommand.watchOptions); @@ -765,8 +715,7 @@ namespace ts { } it("parse build without any options ", () => { // --lib es6 0.ts - assertParseResult([], - { + assertParseResult([], { errors: [], projects: ["."], buildOptions: {}, @@ -776,8 +725,7 @@ namespace ts { it("Parse multiple options", () => { // --lib es5,es2015.symbol.wellknown 0.ts - assertParseResult(["--verbose", "--force", "tests"], - { + assertParseResult(["--verbose", "--force", "tests"], { errors: [], projects: ["tests"], buildOptions: { verbose: true, force: true }, @@ -787,12 +735,11 @@ namespace ts { it("Parse option with invalid option ", () => { // --lib es5,invalidOption 0.ts - assertParseResult(["--verbose", "--invalidOption"], - { + assertParseResult(["--verbose", "--invalidOption"], { errors: [{ messageText: "Unknown build option '--invalidOption'.", - category: Diagnostics.Unknown_build_option_0.category, - code: Diagnostics.Unknown_build_option_0.code, + category: ts.Diagnostics.Unknown_build_option_0.category, + code: ts.Diagnostics.Unknown_build_option_0.code, file: undefined, start: undefined, length: undefined, @@ -805,12 +752,11 @@ namespace ts { it("parse build with listFilesOnly ", () => { // --lib es6 0.ts - assertParseResult(["--listFilesOnly"], - { + assertParseResult(["--listFilesOnly"], { errors: [{ messageText: "Compiler option '--listFilesOnly' may not be used with '--build'.", - category: Diagnostics.Compiler_option_0_may_not_be_used_with_build.category, - code: Diagnostics.Compiler_option_0_may_not_be_used_with_build.code, + category: ts.Diagnostics.Compiler_option_0_may_not_be_used_with_build.category, + code: ts.Diagnostics.Compiler_option_0_may_not_be_used_with_build.code, file: undefined, start: undefined, length: undefined, @@ -823,8 +769,7 @@ namespace ts { it("Parse multiple flags with input projects at the end", () => { // --lib es5,es2015.symbol.wellknown --target es5 0.ts - assertParseResult(["--force", "--verbose", "src", "tests"], - { + assertParseResult(["--force", "--verbose", "src", "tests"], { errors: [], projects: ["src", "tests"], buildOptions: { force: true, verbose: true }, @@ -834,8 +779,7 @@ namespace ts { it("Parse multiple flags with input projects in the middle", () => { // --module commonjs --target es5 0.ts --lib es5,es2015.symbol.wellknown - assertParseResult(["--force", "src", "tests", "--verbose"], - { + assertParseResult(["--force", "src", "tests", "--verbose"], { errors: [], projects: ["src", "tests"], buildOptions: { force: true, verbose: true }, @@ -845,8 +789,7 @@ namespace ts { it("Parse multiple flags with input projects in the beginning", () => { // --module commonjs --target es5 0.ts --lib es5,es2015.symbol.wellknown - assertParseResult(["src", "tests", "--force", "--verbose"], - { + assertParseResult(["src", "tests", "--force", "--verbose"], { errors: [], projects: ["src", "tests"], buildOptions: { force: true, verbose: true }, @@ -856,8 +799,7 @@ namespace ts { it("parse build with --incremental", () => { // --lib es6 0.ts - assertParseResult(["--incremental", "tests"], - { + assertParseResult(["--incremental", "tests"], { errors: [], projects: ["tests"], buildOptions: { incremental: true }, @@ -867,8 +809,7 @@ namespace ts { it("parse build with --locale en-us", () => { // --lib es6 0.ts - assertParseResult(["--locale", "en-us", "src"], - { + assertParseResult(["--locale", "en-us", "src"], { errors: [], projects: ["src"], buildOptions: { locale: "en-us" }, @@ -878,12 +819,11 @@ namespace ts { it("parse build with --tsBuildInfoFile", () => { // --lib es6 0.ts - assertParseResult(["--tsBuildInfoFile", "build.tsbuildinfo", "tests"], - { + assertParseResult(["--tsBuildInfoFile", "build.tsbuildinfo", "tests"], { errors: [{ messageText: "Compiler option '--tsBuildInfoFile' may not be used with '--build'.", - category: Diagnostics.Compiler_option_0_may_not_be_used_with_build.category, - code: Diagnostics.Compiler_option_0_may_not_be_used_with_build.code, + category: ts.Diagnostics.Compiler_option_0_may_not_be_used_with_build.category, + code: ts.Diagnostics.Compiler_option_0_may_not_be_used_with_build.code, file: undefined, start: undefined, length: undefined @@ -900,8 +840,8 @@ namespace ts { assertParseResult(buildFlags, { errors: buildFlags.map(buildFlag => ({ messageText: `Compiler option '${buildFlag}' may not be used with '--build'.`, - category: Diagnostics.Compiler_option_0_may_not_be_used_with_build.category, - code: Diagnostics.Compiler_option_0_may_not_be_used_with_build.code, + category: ts.Diagnostics.Compiler_option_0_may_not_be_used_with_build.category, + code: ts.Diagnostics.Compiler_option_0_may_not_be_used_with_build.code, file: undefined, start: undefined, length: undefined @@ -913,15 +853,14 @@ namespace ts { }); describe("Combining options that make no sense together", () => { - function verifyInvalidCombination(flag1: keyof BuildOptions, flag2: keyof BuildOptions) { + function verifyInvalidCombination(flag1: keyof ts.BuildOptions, flag2: keyof ts.BuildOptions) { it(`--${flag1} and --${flag2} together is invalid`, () => { // --module commonjs --target es5 0.ts --lib es5,es2015.symbol.wellknown - assertParseResult([`--${flag1}`, `--${flag2}`], - { + assertParseResult([`--${flag1}`, `--${flag2}`], { errors: [{ messageText: `Options '${flag1}' and '${flag2}' cannot be combined.`, - category: Diagnostics.Options_0_and_1_cannot_be_combined.category, - code: Diagnostics.Options_0_and_1_cannot_be_combined.code, + category: ts.Diagnostics.Options_0_and_1_cannot_be_combined.category, + code: ts.Diagnostics.Options_0_and_1_cannot_be_combined.code, file: undefined, start: undefined, length: undefined, @@ -941,38 +880,34 @@ namespace ts { describe("Watch options", () => { it("parse --watchFile", () => { - assertParseResult(["--watchFile", "UseFsEvents", "--verbose"], - { + assertParseResult(["--watchFile", "UseFsEvents", "--verbose"], { errors: [], projects: ["."], buildOptions: { verbose: true }, - watchOptions: { watchFile: WatchFileKind.UseFsEvents } + watchOptions: { watchFile: ts.WatchFileKind.UseFsEvents } }); }); it("parse --watchDirectory", () => { - assertParseResult(["--watchDirectory", "FixedPollingInterval", "--verbose"], - { + assertParseResult(["--watchDirectory", "FixedPollingInterval", "--verbose"], { errors: [], projects: ["."], buildOptions: { verbose: true }, - watchOptions: { watchDirectory: WatchDirectoryKind.FixedPollingInterval } + watchOptions: { watchDirectory: ts.WatchDirectoryKind.FixedPollingInterval } }); }); it("parse --fallbackPolling", () => { - assertParseResult(["--fallbackPolling", "PriorityInterval", "--verbose"], - { + assertParseResult(["--fallbackPolling", "PriorityInterval", "--verbose"], { errors: [], projects: ["."], buildOptions: { verbose: true }, - watchOptions: { fallbackPolling: PollingWatchKind.PriorityInterval } + watchOptions: { fallbackPolling: ts.PollingWatchKind.PriorityInterval } }); }); it("parse --synchronousWatchDirectory", () => { - assertParseResult(["--synchronousWatchDirectory", "--verbose"], - { + assertParseResult(["--synchronousWatchDirectory", "--verbose"], { errors: [], projects: ["."], buildOptions: { verbose: true }, @@ -981,21 +916,20 @@ namespace ts { }); it("errors on missing argument", () => { - assertParseResult(["--verbose", "--fallbackPolling"], - { + assertParseResult(["--verbose", "--fallbackPolling"], { errors: [ { messageText: "Watch option 'fallbackPolling' requires a value of type string.", - category: Diagnostics.Watch_option_0_requires_a_value_of_type_1.category, - code: Diagnostics.Watch_option_0_requires_a_value_of_type_1.code, + category: ts.Diagnostics.Watch_option_0_requires_a_value_of_type_1.category, + code: ts.Diagnostics.Watch_option_0_requires_a_value_of_type_1.code, file: undefined, start: undefined, length: undefined }, { messageText: "Argument for '--fallbackPolling' option must be: 'fixedinterval', 'priorityinterval', 'dynamicpriority', 'fixedchunksize'.", - category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category, - code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code, + category: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.category, + code: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.code, file: undefined, start: undefined, length: undefined @@ -1008,13 +942,12 @@ namespace ts { }); it("errors on invalid excludeDirectories", () => { - assertParseResult(["--excludeDirectories", "**/../*"], - { + assertParseResult(["--excludeDirectories", "**/../*"], { errors: [ { messageText: `File specification cannot contain a parent directory ('..') that appears after a recursive directory wildcard ('**'): '**/../*'.`, - category: Diagnostics.File_specification_cannot_contain_a_parent_directory_that_appears_after_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0.category, - code: Diagnostics.File_specification_cannot_contain_a_parent_directory_that_appears_after_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0.code, + category: ts.Diagnostics.File_specification_cannot_contain_a_parent_directory_that_appears_after_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0.category, + code: ts.Diagnostics.File_specification_cannot_contain_a_parent_directory_that_appears_after_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0.code, file: undefined, start: undefined, length: undefined @@ -1027,8 +960,7 @@ namespace ts { }); it("parse --excludeFiles", () => { - assertParseResult(["--excludeFiles", "**/temp/*.ts"], - { + assertParseResult(["--excludeFiles", "**/temp/*.ts"], { errors: [], projects: ["."], buildOptions: {}, @@ -1037,13 +969,12 @@ namespace ts { }); it("errors on invalid excludeFiles", () => { - assertParseResult(["--excludeFiles", "**/../*"], - { + assertParseResult(["--excludeFiles", "**/../*"], { errors: [ { messageText: `File specification cannot contain a parent directory ('..') that appears after a recursive directory wildcard ('**'): '**/../*'.`, - category: Diagnostics.File_specification_cannot_contain_a_parent_directory_that_appears_after_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0.category, - code: Diagnostics.File_specification_cannot_contain_a_parent_directory_that_appears_after_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0.code, + category: ts.Diagnostics.File_specification_cannot_contain_a_parent_directory_that_appears_after_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0.category, + code: ts.Diagnostics.File_specification_cannot_contain_a_parent_directory_that_appears_after_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0.code, file: undefined, start: undefined, length: undefined diff --git a/src/testRunner/unittests/config/configurationExtension.ts b/src/testRunner/unittests/config/configurationExtension.ts index ad906411ffbca..d42f839a0ebe5 100644 --- a/src/testRunner/unittests/config/configurationExtension.ts +++ b/src/testRunner/unittests/config/configurationExtension.ts @@ -168,7 +168,7 @@ namespace ts { compilerOptions: { module: "system" }, - include: null, // eslint-disable-line no-null/no-null + include: null, files: ["../main.ts"] }), "dev/configs/fifth.json": JSON.stringify({ @@ -195,56 +195,66 @@ namespace ts { const caseSensitiveBasePath = "/dev/"; const caseSensitiveHost = new fakes.ParseConfigHost(createFileSystem(/*ignoreCase*/ false, caseSensitiveBasePath, "/")); - function verifyDiagnostics(actual: Diagnostic[], expected: { code: number; messageText: string; }[]) { + function verifyDiagnostics(actual: ts.Diagnostic[], expected: { + code: number; + messageText: string; + }[]) { assert.isTrue(expected.length === actual.length, `Expected error: ${JSON.stringify(expected)}. Actual error: ${JSON.stringify(actual)}.`); for (let i = 0; i < actual.length; i++) { const actualError = actual[i]; const expectedError = expected[i]; assert.equal(actualError.code, expectedError.code, "Error code mismatch"); - assert.equal(actualError.category, DiagnosticCategory.Error, "Category mismatch"); // Should always be error - assert.equal(flattenDiagnosticMessageText(actualError.messageText, "\n"), expectedError.messageText); + assert.equal(actualError.category, ts.DiagnosticCategory.Error, "Category mismatch"); // Should always be error + assert.equal(ts.flattenDiagnosticMessageText(actualError.messageText, "\n"), expectedError.messageText); } } describe("unittests:: config:: configurationExtension", () => { - forEach<[string, string, fakes.ParseConfigHost], void>([ + ts.forEach<[ + string, + string, + fakes.ParseConfigHost + ], void>([ ["under a case insensitive host", caseInsensitiveBasePath, caseInsensitiveHost], ["under a case sensitive host", caseSensitiveBasePath, caseSensitiveHost] ], ([testName, basePath, host]) => { function getParseCommandLine(entry: string) { - const {config, error} = readConfigFile(entry, name => host.readFile(name)); - assert(config && !error, flattenDiagnosticMessageText(error && error.messageText, "\n")); - return parseJsonConfigFileContent(config, host, basePath, {}, entry); + const { config, error } = ts.readConfigFile(entry, name => host.readFile(name)); + assert(config && !error, ts.flattenDiagnosticMessageText(error && error.messageText, "\n")); + return ts.parseJsonConfigFileContent(config, host, basePath, {}, entry); } function getParseCommandLineJsonSourceFile(entry: string) { - const jsonSourceFile = readJsonConfigFile(entry, name => host.readFile(name)); - assert(jsonSourceFile.endOfFileToken && !jsonSourceFile.parseDiagnostics.length, flattenDiagnosticMessageText(jsonSourceFile.parseDiagnostics[0] && jsonSourceFile.parseDiagnostics[0].messageText, "\n")); + const jsonSourceFile = ts.readJsonConfigFile(entry, name => host.readFile(name)); + assert(jsonSourceFile.endOfFileToken && !jsonSourceFile.parseDiagnostics.length, ts.flattenDiagnosticMessageText(jsonSourceFile.parseDiagnostics[0] && jsonSourceFile.parseDiagnostics[0].messageText, "\n")); return { jsonSourceFile, - parsed: parseJsonSourceFileConfigFileContent(jsonSourceFile, host, basePath, {}, entry) + parsed: ts.parseJsonSourceFileConfigFileContent(jsonSourceFile, host, basePath, {}, entry) }; } - function testSuccess(name: string, entry: string, expected: CompilerOptions, expectedFiles: string[]) { + function testSuccess(name: string, entry: string, expected: ts.CompilerOptions, expectedFiles: string[]) { expected.configFilePath = entry; it(name, () => { const parsed = getParseCommandLine(entry); - assert(!parsed.errors.length, flattenDiagnosticMessageText(parsed.errors[0] && parsed.errors[0].messageText, "\n")); + assert(!parsed.errors.length, ts.flattenDiagnosticMessageText(parsed.errors[0] && parsed.errors[0].messageText, "\n")); assert.deepEqual(parsed.options, expected); assert.deepEqual(parsed.fileNames, expectedFiles); }); it(name + " with jsonSourceFile", () => { const { parsed, jsonSourceFile } = getParseCommandLineJsonSourceFile(entry); - assert(!parsed.errors.length, flattenDiagnosticMessageText(parsed.errors[0] && parsed.errors[0].messageText, "\n")); + assert(!parsed.errors.length, ts.flattenDiagnosticMessageText(parsed.errors[0] && parsed.errors[0].messageText, "\n")); assert.deepEqual(parsed.options, expected); assert.equal(parsed.options.configFile, jsonSourceFile); assert.deepEqual(parsed.fileNames, expectedFiles); }); } - function testFailure(name: string, entry: string, expectedDiagnostics: { code: number; messageText: string; }[]) { + function testFailure(name: string, entry: string, expectedDiagnostics: { + code: number; + messageText: string; + }[]) { it(name, () => { const parsed = getParseCommandLine(entry); verifyDiagnostics(parsed.errors, expectedDiagnostics); @@ -262,8 +272,8 @@ namespace ts { noImplicitAny: true, strictNullChecks: true, }, [ - combinePaths(basePath, "main.ts"), - combinePaths(basePath, "supplemental.ts"), + ts.combinePaths(basePath, "main.ts"), + ts.combinePaths(basePath, "supplemental.ts"), ]); testSuccess("can resolve an extension with a base extension that overrides options", "tsconfig.nostrictnull.json", { @@ -271,14 +281,14 @@ namespace ts { noImplicitAny: true, strictNullChecks: false, }, [ - combinePaths(basePath, "main.ts"), - combinePaths(basePath, "supplemental.ts"), + ts.combinePaths(basePath, "main.ts"), + ts.combinePaths(basePath, "supplemental.ts"), ]); testFailure("can report errors on circular imports", "circular.json", [ { code: 18000, - messageText: `Circularity detected while resolving configuration: ${[combinePaths(basePath, "circular.json"), combinePaths(basePath, "circular2.json"), combinePaths(basePath, "circular.json")].join(" -> ")}` + messageText: `Circularity detected while resolving configuration: ${[ts.combinePaths(basePath, "circular.json"), ts.combinePaths(basePath, "circular2.json"), ts.combinePaths(basePath, "circular.json")].join(" -> ")}` } ]); @@ -303,49 +313,49 @@ namespace ts { strictNullChecks: true, module: undefined // Technically, this is distinct from the key never being set; but within the compiler we don't make the distinction }, [ - combinePaths(basePath, "supplemental.ts") + ts.combinePaths(basePath, "supplemental.ts") ]); testSuccess("can overwrite top-level options using extended 'null'", "configs/fourth.json", { allowJs: true, noImplicitAny: true, strictNullChecks: true, - module: ModuleKind.System + module: ts.ModuleKind.System }, [ - combinePaths(basePath, "main.ts") + ts.combinePaths(basePath, "main.ts") ]); testSuccess("can overwrite top-level files using extended []", "configs/fifth.json", { allowJs: true, noImplicitAny: true, strictNullChecks: true, - module: ModuleKind.System + module: ts.ModuleKind.System }, [ - combinePaths(basePath, "tests/utils.ts") + ts.combinePaths(basePath, "tests/utils.ts") ]); describe("finding extended configs from node_modules", () => { - testSuccess("can lookup via tsconfig field", "tsconfig.extendsBox.json", { strict: true }, [combinePaths(basePath, "main.ts")]); - testSuccess("can lookup via package-relative path", "tsconfig.extendsStrict.json", { strict: true }, [combinePaths(basePath, "main.ts")]); - testSuccess("can lookup via non-redirected-to package-relative path", "tsconfig.extendsUnStrict.json", { strict: false }, [combinePaths(basePath, "main.ts")]); - testSuccess("can lookup via package-relative path with extension", "tsconfig.extendsStrictExtension.json", { strict: true }, [combinePaths(basePath, "main.ts")]); - testSuccess("can lookup via an implicit tsconfig", "tsconfig.extendsBoxImplied.json", { strict: true }, [combinePaths(basePath, "main.ts")]); - testSuccess("can lookup via an implicit tsconfig in a package-relative directory", "tsconfig.extendsBoxImpliedUnstrict.json", { strict: false }, [combinePaths(basePath, "main.ts")]); - testSuccess("can lookup via an implicit tsconfig in a package-relative directory with name", "tsconfig.extendsBoxImpliedUnstrictExtension.json", { strict: false }, [combinePaths(basePath, "main.ts")]); - testSuccess("can lookup via an implicit tsconfig in a package-relative directory with extension", "tsconfig.extendsBoxImpliedPath.json", { strict: true }, [combinePaths(basePath, "main.ts")]); + testSuccess("can lookup via tsconfig field", "tsconfig.extendsBox.json", { strict: true }, [ts.combinePaths(basePath, "main.ts")]); + testSuccess("can lookup via package-relative path", "tsconfig.extendsStrict.json", { strict: true }, [ts.combinePaths(basePath, "main.ts")]); + testSuccess("can lookup via non-redirected-to package-relative path", "tsconfig.extendsUnStrict.json", { strict: false }, [ts.combinePaths(basePath, "main.ts")]); + testSuccess("can lookup via package-relative path with extension", "tsconfig.extendsStrictExtension.json", { strict: true }, [ts.combinePaths(basePath, "main.ts")]); + testSuccess("can lookup via an implicit tsconfig", "tsconfig.extendsBoxImplied.json", { strict: true }, [ts.combinePaths(basePath, "main.ts")]); + testSuccess("can lookup via an implicit tsconfig in a package-relative directory", "tsconfig.extendsBoxImpliedUnstrict.json", { strict: false }, [ts.combinePaths(basePath, "main.ts")]); + testSuccess("can lookup via an implicit tsconfig in a package-relative directory with name", "tsconfig.extendsBoxImpliedUnstrictExtension.json", { strict: false }, [ts.combinePaths(basePath, "main.ts")]); + testSuccess("can lookup via an implicit tsconfig in a package-relative directory with extension", "tsconfig.extendsBoxImpliedPath.json", { strict: true }, [ts.combinePaths(basePath, "main.ts")]); }); it("adds extendedSourceFiles only once", () => { - const sourceFile = readJsonConfigFile("configs/fourth.json", (path) => host.readFile(path)); - const dir = combinePaths(basePath, "configs"); + const sourceFile = ts.readJsonConfigFile("configs/fourth.json", (path) => host.readFile(path)); + const dir = ts.combinePaths(basePath, "configs"); const expected = [ - combinePaths(dir, "third.json"), - combinePaths(dir, "second.json"), - combinePaths(dir, "base.json"), + ts.combinePaths(dir, "third.json"), + ts.combinePaths(dir, "second.json"), + ts.combinePaths(dir, "base.json"), ]; - parseJsonSourceFileConfigFileContent(sourceFile, host, dir, {}, "fourth.json"); + ts.parseJsonSourceFileConfigFileContent(sourceFile, host, dir, {}, "fourth.json"); assert.deepEqual(sourceFile.extendedSourceFiles, expected); - parseJsonSourceFileConfigFileContent(sourceFile, host, dir, {}, "fourth.json"); + ts.parseJsonSourceFileConfigFileContent(sourceFile, host, dir, {}, "fourth.json"); assert.deepEqual(sourceFile.extendedSourceFiles, expected); }); }); diff --git a/src/testRunner/unittests/config/convertCompilerOptionsFromJson.ts b/src/testRunner/unittests/config/convertCompilerOptionsFromJson.ts index 97ae30d24083e..8befec359ddc5 100644 --- a/src/testRunner/unittests/config/convertCompilerOptionsFromJson.ts +++ b/src/testRunner/unittests/config/convertCompilerOptionsFromJson.ts @@ -1,18 +1,18 @@ namespace ts { describe("unittests:: config:: convertCompilerOptionsFromJson", () => { - const formatDiagnosticHost: FormatDiagnosticsHost = { + const formatDiagnosticHost: ts.FormatDiagnosticsHost = { getCurrentDirectory: () => "/apath/", - getCanonicalFileName: createGetCanonicalFileName(/*useCaseSensitiveFileNames*/ true), + getCanonicalFileName: ts.createGetCanonicalFileName(/*useCaseSensitiveFileNames*/ true), getNewLine: () => "\n" }; interface ExpectedResultWithParsingSuccess { - compilerOptions: CompilerOptions; - errors: readonly Diagnostic[]; + compilerOptions: ts.CompilerOptions; + errors: readonly ts.Diagnostic[]; } interface ExpectedResultWithParsingFailure { - compilerOptions: CompilerOptions; + compilerOptions: ts.CompilerOptions; hasParseErrors: true; } @@ -28,7 +28,7 @@ namespace ts { } function assertCompilerOptionsWithJson(json: any, configFileName: string, expectedResult: ExpectedResultWithParsingSuccess) { - const { options: actualCompilerOptions, errors: actualErrors } = convertCompilerOptionsFromJson(json.compilerOptions, "/apath/", configFileName); + const { options: actualCompilerOptions, errors: actualErrors } = ts.convertCompilerOptionsFromJson(json.compilerOptions, "/apath/", configFileName); const parsedCompilerOptions = JSON.stringify(actualCompilerOptions); const expectedCompilerOptions = JSON.stringify({ ...expectedResult.compilerOptions, configFilePath: configFileName }); @@ -42,11 +42,11 @@ namespace ts { } function assertCompilerOptionsWithJsonText(fileText: string, configFileName: string, expectedResult: ExpectedResult) { - const result = parseJsonText(configFileName, fileText); + const result = ts.parseJsonText(configFileName, fileText); assert(!!result.endOfFileToken); assert.equal(!!result.parseDiagnostics.length, isExpectedResultWithParsingFailure(expectedResult)); - const host: ParseConfigHost = new fakes.ParseConfigHost(new vfs.FileSystem(/*ignoreCase*/ false, { cwd: "/apath/" })); - const { options: actualCompilerOptions, errors: actualParseErrors } = parseJsonSourceFileConfigFileContent(result, host, "/apath/", /*existingOptions*/ undefined, configFileName); + const host: ts.ParseConfigHost = new fakes.ParseConfigHost(new vfs.FileSystem(/*ignoreCase*/ false, { cwd: "/apath/" })); + const { options: actualCompilerOptions, errors: actualParseErrors } = ts.parseJsonSourceFileConfigFileContent(result, host, "/apath/", /*existingOptions*/ undefined, configFileName); expectedResult.compilerOptions.configFilePath = configFileName; const parsedCompilerOptions = JSON.stringify(actualCompilerOptions); @@ -55,11 +55,11 @@ namespace ts { assert.equal(actualCompilerOptions.configFile, result); if (!isExpectedResultWithParsingFailure(expectedResult)) { - verifyErrors(actualParseErrors.filter(error => error.code !== Diagnostics.No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2.code), expectedResult.errors); + verifyErrors(actualParseErrors.filter(error => error.code !== ts.Diagnostics.No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2.code), expectedResult.errors); } } - function verifyErrors(actualErrors: Diagnostic[], expectedErrors: readonly Diagnostic[], ignoreLocation?: boolean) { + function verifyErrors(actualErrors: ts.Diagnostic[], expectedErrors: readonly ts.Diagnostic[], ignoreLocation?: boolean) { assert.isTrue(expectedErrors.length === actualErrors.length, `Expected error: ${JSON.stringify(expectedErrors.map(getDiagnosticString), undefined, " ")}. Actual error: ${JSON.stringify(actualErrors.map(getDiagnosticString), undefined, " ")}.`); for (let i = 0; i < actualErrors.length; i++) { const actualError = actualErrors[i]; @@ -74,19 +74,18 @@ namespace ts { } } - function getDiagnosticString(diagnostic: Diagnostic) { + function getDiagnosticString(diagnostic: ts.Diagnostic) { if (ignoreLocation) { const { file, ...rest } = diagnostic; diagnostic = { file: undefined, ...rest }; } - return formatDiagnostic(diagnostic, formatDiagnosticHost); + return ts.formatDiagnostic(diagnostic, formatDiagnosticHost); } } // tsconfig.json tests it("Convert correctly format tsconfig.json to compiler-options ", () => { - assertCompilerOptions( - { + assertCompilerOptions({ compilerOptions: { module: "commonjs", target: "es5", @@ -94,23 +93,20 @@ namespace ts { sourceMap: false, lib: ["es5", "es2015.core", "es2015.symbol"] } - }, "tsconfig.json", - { + }, "tsconfig.json", { compilerOptions: { - module: ModuleKind.CommonJS, - target: ScriptTarget.ES5, + module: ts.ModuleKind.CommonJS, + target: ts.ScriptTarget.ES5, noImplicitAny: false, sourceMap: false, lib: ["lib.es5.d.ts", "lib.es2015.core.d.ts", "lib.es2015.symbol.d.ts"] }, errors: [] - } - ); }); + }); it("Convert correctly format tsconfig.json with allowJs is false to compiler-options ", () => { - assertCompilerOptions( - { + assertCompilerOptions({ compilerOptions: { module: "commonjs", target: "es5", @@ -119,24 +115,21 @@ namespace ts { allowJs: false, lib: ["es5", "es2015.core", "es2015.symbol"] } - }, "tsconfig.json", - { + }, "tsconfig.json", { compilerOptions: { - module: ModuleKind.CommonJS, - target: ScriptTarget.ES5, + module: ts.ModuleKind.CommonJS, + target: ts.ScriptTarget.ES5, noImplicitAny: false, sourceMap: false, allowJs: false, lib: ["lib.es5.d.ts", "lib.es2015.core.d.ts", "lib.es2015.symbol.d.ts"] }, errors: [] - } - ); }); + }); it("Convert incorrect option of jsx to compiler-options ", () => { - assertCompilerOptions( - { + assertCompilerOptions({ compilerOptions: { module: "commonjs", target: "es5", @@ -144,11 +137,10 @@ namespace ts { sourceMap: false, jsx: "" } - }, "tsconfig.json", - { + }, "tsconfig.json", { compilerOptions: { - module: ModuleKind.CommonJS, - target: ScriptTarget.ES5, + module: ts.ModuleKind.CommonJS, + target: ts.ScriptTarget.ES5, noImplicitAny: false, sourceMap: false, }, @@ -157,26 +149,23 @@ namespace ts { start: 0, length: 0, messageText: "Argument for '--jsx' option must be: 'preserve', 'react-native', 'react'.", - code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code, - category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category + code: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.code, + category: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.category }] - } - ); }); + }); it("Convert incorrect option of module to compiler-options ", () => { - assertCompilerOptions( - { + assertCompilerOptions({ compilerOptions: { module: "", target: "es5", noImplicitAny: false, sourceMap: false, } - }, "tsconfig.json", - { + }, "tsconfig.json", { compilerOptions: { - target: ScriptTarget.ES5, + target: ts.ScriptTarget.ES5, noImplicitAny: false, sourceMap: false, }, @@ -185,26 +174,23 @@ namespace ts { start: 0, length: 0, messageText: "Argument for '--module' option must be: 'none', 'commonjs', 'amd', 'system', 'umd', 'es6', 'es2015', 'es2020', 'es2022', 'esnext'.", - code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code, - category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category + code: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.code, + category: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.category }] - } - ); }); + }); it("Convert incorrect option of newLine to compiler-options ", () => { - assertCompilerOptions( - { + assertCompilerOptions({ compilerOptions: { newLine: "", target: "es5", noImplicitAny: false, sourceMap: false, } - }, "tsconfig.json", - { + }, "tsconfig.json", { compilerOptions: { - target: ScriptTarget.ES5, + target: ts.ScriptTarget.ES5, noImplicitAny: false, sourceMap: false, }, @@ -213,23 +199,20 @@ namespace ts { start: 0, length: 0, messageText: "Argument for '--newLine' option must be: 'crlf', 'lf'.", - code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code, - category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category + code: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.code, + category: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.category }] - } - ); }); + }); it("Convert incorrect option of target to compiler-options ", () => { - assertCompilerOptions( - { + assertCompilerOptions({ compilerOptions: { target: "", noImplicitAny: false, sourceMap: false, } - }, "tsconfig.json", - { + }, "tsconfig.json", { compilerOptions: { noImplicitAny: false, sourceMap: false, @@ -239,23 +222,20 @@ namespace ts { start: 0, length: 0, messageText: "Argument for '--target' option must be: 'es3', 'es5', 'es6', 'es2015', 'es2016', 'es2017', 'es2018', 'es2019', 'esnext'.", - code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code, - category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category + code: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.code, + category: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.category }] - } - ); }); + }); it("Convert incorrect option of module-resolution to compiler-options ", () => { - assertCompilerOptions( - { + assertCompilerOptions({ compilerOptions: { moduleResolution: "", noImplicitAny: false, sourceMap: false, } - }, "tsconfig.json", - { + }, "tsconfig.json", { compilerOptions: { noImplicitAny: false, sourceMap: false, @@ -265,16 +245,14 @@ namespace ts { start: 0, length: 0, messageText: "Argument for '--moduleResolution' option must be: 'node', 'classic'.", - code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code, - category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category + code: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.code, + category: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.category }] - } - ); }); + }); it("Convert incorrect option of libs to compiler-options ", () => { - assertCompilerOptions( - { + assertCompilerOptions({ compilerOptions: { module: "commonjs", target: "es5", @@ -282,11 +260,10 @@ namespace ts { sourceMap: false, lib: ["es5", "es2015.core", "incorrectLib"] } - }, "tsconfig.json", - { + }, "tsconfig.json", { compilerOptions: { - module: ModuleKind.CommonJS, - target: ScriptTarget.ES5, + module: ts.ModuleKind.CommonJS, + target: ts.ScriptTarget.ES5, noImplicitAny: false, sourceMap: false, lib: ["lib.es5.d.ts", "lib.es2015.core.d.ts"] @@ -296,16 +273,14 @@ namespace ts { start: 0, length: 0, messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'es2018', 'esnext', 'dom', 'dom.iterable', 'webworker', 'webworker.importscripts', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string', 'es2017.intl', 'es2017.typedarrays', 'es2018.asynciterable', 'es2018.intl', 'es2018.promise', 'es2018.regexp', 'esnext.array', 'esnext.symbol', 'esnext.intl', 'esnext.bigint', 'esnext.bigint', 'esnext.string', 'esnext.promise'.", - code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code, - category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category + code: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.code, + category: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.category }] - } - ); }); + }); it("Convert empty string option of libs to compiler-options ", () => { - assertCompilerOptions( - { + assertCompilerOptions({ compilerOptions: { module: "commonjs", target: "es5", @@ -313,11 +288,10 @@ namespace ts { sourceMap: false, lib: ["es5", ""] } - }, "tsconfig.json", - { + }, "tsconfig.json", { compilerOptions: { - module: ModuleKind.CommonJS, - target: ScriptTarget.ES5, + module: ts.ModuleKind.CommonJS, + target: ts.ScriptTarget.ES5, noImplicitAny: false, sourceMap: false, lib: ["lib.es5.d.ts"] @@ -327,16 +301,14 @@ namespace ts { start: 0, length: 0, messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'es2018', 'esnext', 'dom', 'dom.iterable', 'webworker', 'webworker.importscripts', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string', 'es2017.intl', 'es2017.typedarrays', 'es2018.asynciterable', 'es2018.intl', 'es2018.promise', 'es2018.regexp', 'esnext.array', 'esnext.symbol', 'esnext.intl', 'esnext.bigint', 'esnext.string', 'esnext.promise'.", - code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code, - category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category + code: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.code, + category: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.category }] - } - ); }); + }); it("Convert empty string option of libs to compiler-options ", () => { - assertCompilerOptions( - { + assertCompilerOptions({ compilerOptions: { module: "commonjs", target: "es5", @@ -344,11 +316,10 @@ namespace ts { sourceMap: false, lib: [""] } - }, "tsconfig.json", - { + }, "tsconfig.json", { compilerOptions: { - module: ModuleKind.CommonJS, - target: ScriptTarget.ES5, + module: ts.ModuleKind.CommonJS, + target: ts.ScriptTarget.ES5, noImplicitAny: false, sourceMap: false, lib: [] @@ -358,16 +329,14 @@ namespace ts { start: 0, length: 0, messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'es2018', 'esnext', 'dom', 'dom.iterable', 'webworker', 'webworker.importscripts', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string', 'es2017.intl', 'es2017.typedarrays', 'es2018.asynciterable', 'es2018.intl', 'es2018.promise', 'es2018.regexp', 'esnext.array', 'esnext.symbol', 'esnext.intl', 'esnext.bigint', 'esnext.string', 'esnext.promise'.", - code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code, - category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category + code: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.code, + category: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.category }] - } - ); }); + }); it("Convert trailing-whitespace string option of libs to compiler-options ", () => { - assertCompilerOptions( - { + assertCompilerOptions({ compilerOptions: { module: "commonjs", target: "es5", @@ -375,11 +344,10 @@ namespace ts { sourceMap: false, lib: [" "] } - }, "tsconfig.json", - { + }, "tsconfig.json", { compilerOptions: { - module: ModuleKind.CommonJS, - target: ScriptTarget.ES5, + module: ts.ModuleKind.CommonJS, + target: ts.ScriptTarget.ES5, noImplicitAny: false, sourceMap: false, lib: [] @@ -389,16 +357,14 @@ namespace ts { start: 0, length: 0, messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'es2018', 'esnext', 'dom', 'dom.iterable', 'webworker', 'webworker.importscripts', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string', 'es2017.intl', 'es2017.typedarrays', 'es2018.asynciterable', 'es2018.intl', 'es2018.promise', 'es2018.regexp', 'esnext.array', 'esnext.symbol', 'esnext.intl', 'esnext.bigint', 'esnext.string', 'esnext.promise'.", - code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code, - category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category + code: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.code, + category: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.category }] - } - ); }); + }); it("Convert empty option of libs to compiler-options ", () => { - assertCompilerOptions( - { + assertCompilerOptions({ compilerOptions: { module: "commonjs", target: "es5", @@ -406,136 +372,113 @@ namespace ts { sourceMap: false, lib: [] } - }, "tsconfig.json", - { + }, "tsconfig.json", { compilerOptions: { - module: ModuleKind.CommonJS, - target: ScriptTarget.ES5, + module: ts.ModuleKind.CommonJS, + target: ts.ScriptTarget.ES5, noImplicitAny: false, sourceMap: false, lib: [] }, errors: [] - } - ); }); + }); it("Convert empty string option of moduleSuffixes to compiler-options ", () => { - assertCompilerOptions( - { + assertCompilerOptions({ compilerOptions: { moduleSuffixes: [".ios", ""] } - }, "tsconfig.json", - { + }, "tsconfig.json", { compilerOptions: { moduleSuffixes: [".ios", ""] }, errors: [] - } - ); }); + }); it("Convert empty string option of moduleSuffixes to compiler-options ", () => { - assertCompilerOptions( - { + assertCompilerOptions({ compilerOptions: { moduleSuffixes: [""] } - }, "tsconfig.json", - { + }, "tsconfig.json", { compilerOptions: { moduleSuffixes: [""] }, errors: [] - } - ); }); + }); it("Convert trailing-whitespace string option of moduleSuffixes to compiler-options ", () => { - assertCompilerOptions( - { + assertCompilerOptions({ compilerOptions: { moduleSuffixes: [" "] } - }, "tsconfig.json", - { + }, "tsconfig.json", { compilerOptions: { moduleSuffixes: [" "] }, errors: [] - } - ); }); + }); it("Convert empty option of moduleSuffixes to compiler-options ", () => { - assertCompilerOptions( - { + assertCompilerOptions({ compilerOptions: { moduleSuffixes: [] } - }, "tsconfig.json", - { + }, "tsconfig.json", { compilerOptions: { moduleSuffixes: [] }, errors: [] - } - ); }); + }); it("Convert incorrectly format tsconfig.json to compiler-options ", () => { - assertCompilerOptions( - { + assertCompilerOptions({ compilerOptions: { modu: "commonjs", } - }, "tsconfig.json", - { + }, "tsconfig.json", { compilerOptions: {}, errors: [{ file: undefined, start: 0, length: 0, messageText: "Unknown compiler option 'modu'.", - code: Diagnostics.Unknown_compiler_option_0.code, - category: Diagnostics.Unknown_compiler_option_0.category + code: ts.Diagnostics.Unknown_compiler_option_0.code, + category: ts.Diagnostics.Unknown_compiler_option_0.category }] - } - ); }); + }); it("Convert default tsconfig.json to compiler-options ", () => { - assertCompilerOptions({}, "tsconfig.json", - { + assertCompilerOptions({}, "tsconfig.json", { compilerOptions: {}, errors: [] - } - ); }); + }); it("Convert negative numbers in tsconfig.json ", () => { - assertCompilerOptions( - { + assertCompilerOptions({ compilerOptions: { allowJs: true, maxNodeModuleJsDepth: -1 } - }, "tsconfig.json", - { + }, "tsconfig.json", { compilerOptions: { allowJs: true, maxNodeModuleJsDepth: -1 }, errors: [] - } - ); }); + }); // jsconfig.json it("Convert correctly format jsconfig.json to compiler-options ", () => { - assertCompilerOptions( - { + assertCompilerOptions({ compilerOptions: { module: "commonjs", target: "es5", @@ -543,28 +486,25 @@ namespace ts { sourceMap: false, lib: ["es5", "es2015.core", "es2015.symbol"] } - }, "jsconfig.json", - { + }, "jsconfig.json", { compilerOptions: { allowJs: true, maxNodeModuleJsDepth: 2, allowSyntheticDefaultImports: true, skipLibCheck: true, noEmit: true, - module: ModuleKind.CommonJS, - target: ScriptTarget.ES5, + module: ts.ModuleKind.CommonJS, + target: ts.ScriptTarget.ES5, noImplicitAny: false, sourceMap: false, lib: ["lib.es5.d.ts", "lib.es2015.core.d.ts", "lib.es2015.symbol.d.ts"] }, errors: [] - } - ); }); + }); it("Convert correctly format jsconfig.json with allowJs is false to compiler-options ", () => { - assertCompilerOptions( - { + assertCompilerOptions({ compilerOptions: { module: "commonjs", target: "es5", @@ -573,35 +513,30 @@ namespace ts { allowJs: false, lib: ["es5", "es2015.core", "es2015.symbol"] } - }, "jsconfig.json", - { + }, "jsconfig.json", { compilerOptions: { allowJs: false, maxNodeModuleJsDepth: 2, allowSyntheticDefaultImports: true, skipLibCheck: true, noEmit: true, - module: ModuleKind.CommonJS, - target: ScriptTarget.ES5, + module: ts.ModuleKind.CommonJS, + target: ts.ScriptTarget.ES5, noImplicitAny: false, sourceMap: false, lib: ["lib.es5.d.ts", "lib.es2015.core.d.ts", "lib.es2015.symbol.d.ts"] }, errors: [] - } - ); }); + }); it("Convert incorrectly format jsconfig.json to compiler-options ", () => { - assertCompilerOptions( - { + assertCompilerOptions({ compilerOptions: { modu: "commonjs", } - }, "jsconfig.json", - { - compilerOptions: - { + }, "jsconfig.json", { + compilerOptions: { allowJs: true, maxNodeModuleJsDepth: 2, allowSyntheticDefaultImports: true, @@ -613,18 +548,15 @@ namespace ts { start: 0, length: 0, messageText: "Unknown compiler option 'modu'.", - code: Diagnostics.Unknown_compiler_option_0.code, - category: Diagnostics.Unknown_compiler_option_0.category + code: ts.Diagnostics.Unknown_compiler_option_0.code, + category: ts.Diagnostics.Unknown_compiler_option_0.category }] - } - ); }); + }); it("Convert default jsconfig.json to compiler-options ", () => { - assertCompilerOptions({}, "jsconfig.json", - { - compilerOptions: - { + assertCompilerOptions({}, "jsconfig.json", { + compilerOptions: { allowJs: true, maxNodeModuleJsDepth: 2, allowSyntheticDefaultImports: true, @@ -632,10 +564,9 @@ namespace ts { noEmit: true }, errors: [] - } - ); }); + }); it("Convert tsconfig options when there are multiple invalid strings", () => { assertCompilerOptionsWithJsonText(`{ "compilerOptions": { @@ -656,12 +587,10 @@ namespace ts { ] } } -`, - "tsconfig.json", - { +`, "tsconfig.json", { compilerOptions: { target: undefined, - module: ModuleKind.ESNext, + module: ts.ModuleKind.ESNext, experimentalDecorators: true, }, hasParseErrors: true @@ -675,11 +604,11 @@ namespace ts { } } blah`, "tsconfig.json", { compilerOptions: { - target: ScriptTarget.ESNext + target: ts.ScriptTarget.ESNext }, hasParseErrors: true, errors: [{ - ...Diagnostics.The_root_value_of_a_0_file_must_be_an_object, + ...ts.Diagnostics.The_root_value_of_a_0_file_must_be_an_object, messageText: "The root value of a 'tsconfig.json' file must be an object.", file: undefined, start: 0, @@ -695,11 +624,11 @@ namespace ts { } }`, "tsconfig.json", { compilerOptions: { - target: ScriptTarget.ESNext + target: ts.ScriptTarget.ESNext }, hasParseErrors: true, errors: [{ - ...Diagnostics.The_root_value_of_a_0_file_must_be_an_object, + ...ts.Diagnostics.The_root_value_of_a_0_file_must_be_an_object, messageText: "The root value of a 'tsconfig.json' file must be an object.", file: undefined, start: 0, @@ -715,10 +644,10 @@ namespace ts { } }]`, "tsconfig.json", { compilerOptions: { - target: ScriptTarget.ESNext + target: ts.ScriptTarget.ESNext }, errors: [{ - ...Diagnostics.The_root_value_of_a_0_file_must_be_an_object, + ...ts.Diagnostics.The_root_value_of_a_0_file_must_be_an_object, messageText: "The root value of a 'tsconfig.json' file must be an object.", file: undefined, start: 0, @@ -733,7 +662,7 @@ namespace ts { }`, "tsconfig.json", { compilerOptions: {}, errors: [{ - ...Diagnostics._0_should_be_set_inside_the_compilerOptions_object_of_the_config_json_file, + ...ts.Diagnostics._0_should_be_set_inside_the_compilerOptions_object_of_the_config_json_file, messageText: "'module' should be set inside the 'compilerOptions' object of the config json file.", file: undefined, start: 0, @@ -750,7 +679,7 @@ namespace ts { } }`, "tsconfig.json", { compilerOptions: { - module: ModuleKind.ESNext + module: ts.ModuleKind.ESNext }, errors: [] }); @@ -760,7 +689,7 @@ namespace ts { assertCompilerOptionsWithJsonText(`42`, "tsconfig.json", { compilerOptions: {}, errors: [{ - ...Diagnostics.The_root_value_of_a_0_file_must_be_an_object, + ...ts.Diagnostics.The_root_value_of_a_0_file_must_be_an_object, messageText: "The root value of a 'tsconfig.json' file must be an object.", file: undefined, start: 0, diff --git a/src/testRunner/unittests/config/convertTypeAcquisitionFromJson.ts b/src/testRunner/unittests/config/convertTypeAcquisitionFromJson.ts index a985c4838dd24..e12fa1e69201c 100644 --- a/src/testRunner/unittests/config/convertTypeAcquisitionFromJson.ts +++ b/src/testRunner/unittests/config/convertTypeAcquisitionFromJson.ts @@ -1,18 +1,21 @@ namespace ts { - interface ExpectedResult { typeAcquisition: TypeAcquisition; errors: Diagnostic[]; } + interface ExpectedResult { + typeAcquisition: ts.TypeAcquisition; + errors: ts.Diagnostic[]; + } describe("unittests:: config:: convertTypeAcquisitionFromJson", () => { function assertTypeAcquisition(json: any, configFileName: string, expectedResult: ExpectedResult) { assertTypeAcquisitionWithJson(json, configFileName, expectedResult); assertTypeAcquisitionWithJsonNode(json, configFileName, expectedResult); } - function verifyAcquisition(actualTypeAcquisition: TypeAcquisition | undefined, expectedResult: ExpectedResult) { + function verifyAcquisition(actualTypeAcquisition: ts.TypeAcquisition | undefined, expectedResult: ExpectedResult) { const parsedTypeAcquisition = JSON.stringify(actualTypeAcquisition); const expectedTypeAcquisition = JSON.stringify(expectedResult.typeAcquisition); assert.equal(parsedTypeAcquisition, expectedTypeAcquisition); } - function verifyErrors(actualErrors: Diagnostic[], expectedResult: ExpectedResult, hasLocation?: boolean) { + function verifyErrors(actualErrors: ts.Diagnostic[], expectedResult: ExpectedResult, hasLocation?: boolean) { const expectedErrors = expectedResult.errors; assert.isTrue(expectedResult.errors.length === actualErrors.length, `Expected error: ${JSON.stringify(expectedResult.errors)}. Actual error: ${JSON.stringify(actualErrors)}.`); for (let i = 0; i < actualErrors.length; i++) { @@ -30,89 +33,74 @@ namespace ts { function assertTypeAcquisitionWithJson(json: any, configFileName: string, expectedResult: ExpectedResult) { const jsonOptions = json.typeAcquisition || json.typingOptions; - const { options: actualTypeAcquisition, errors: actualErrors } = convertTypeAcquisitionFromJson(jsonOptions, "/apath/", configFileName); + const { options: actualTypeAcquisition, errors: actualErrors } = ts.convertTypeAcquisitionFromJson(jsonOptions, "/apath/", configFileName); verifyAcquisition(actualTypeAcquisition, expectedResult); verifyErrors(actualErrors, expectedResult); } function assertTypeAcquisitionWithJsonNode(json: any, configFileName: string, expectedResult: ExpectedResult) { const fileText = JSON.stringify(json); - const result = parseJsonText(configFileName, fileText); + const result = ts.parseJsonText(configFileName, fileText); assert(!result.parseDiagnostics.length); assert(!!result.endOfFileToken); - const host: ParseConfigHost = new fakes.ParseConfigHost(new vfs.FileSystem(/*ignoreCase*/ false, { cwd: "/apath/" })); - const { typeAcquisition: actualTypeAcquisition, errors: actualParseErrors } = parseJsonSourceFileConfigFileContent(result, host, "/apath/", /*existingOptions*/ undefined, configFileName); + const host: ts.ParseConfigHost = new fakes.ParseConfigHost(new vfs.FileSystem(/*ignoreCase*/ false, { cwd: "/apath/" })); + const { typeAcquisition: actualTypeAcquisition, errors: actualParseErrors } = ts.parseJsonSourceFileConfigFileContent(result, host, "/apath/", /*existingOptions*/ undefined, configFileName); verifyAcquisition(actualTypeAcquisition, expectedResult); - const actualErrors = filter(actualParseErrors, error => error.code !== Diagnostics.No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2.code); + const actualErrors = ts.filter(actualParseErrors, error => error.code !== ts.Diagnostics.No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2.code); verifyErrors(actualErrors, expectedResult, /*hasLocation*/ true); } // tsconfig.json it("Convert deprecated typingOptions.enableAutoDiscovery format tsconfig.json to typeAcquisition ", () => { - assertTypeAcquisition( - { - typingOptions: - { + assertTypeAcquisition({ + typingOptions: { enableAutoDiscovery: true, include: ["0.d.ts", "1.d.ts"], exclude: ["0.js", "1.js"] } - }, - "tsconfig.json", - { - typeAcquisition: - { + }, "tsconfig.json", { + typeAcquisition: { enable: true, include: ["0.d.ts", "1.d.ts"], exclude: ["0.js", "1.js"] }, - errors: [] as Diagnostic[] - } - ); + errors: [] as ts.Diagnostic[] + }); }); it("Convert correctly format tsconfig.json to typeAcquisition ", () => { - assertTypeAcquisition( - { - typeAcquisition: - { + assertTypeAcquisition({ + typeAcquisition: { enable: true, include: ["0.d.ts", "1.d.ts"], exclude: ["0.js", "1.js"] } - }, - "tsconfig.json", - { - typeAcquisition: - { + }, "tsconfig.json", { + typeAcquisition: { enable: true, include: ["0.d.ts", "1.d.ts"], exclude: ["0.js", "1.js"] }, - errors: [] as Diagnostic[] + errors: [] as ts.Diagnostic[] }); }); it("Convert incorrect format tsconfig.json to typeAcquisition ", () => { - assertTypeAcquisition( - { - typeAcquisition: - { + assertTypeAcquisition({ + typeAcquisition: { enableAutoDiscovy: true, } - }, "tsconfig.json", - { - typeAcquisition: - { + }, "tsconfig.json", { + typeAcquisition: { enable: false, include: [], exclude: [] }, errors: [ { - category: Diagnostics.Unknown_type_acquisition_option_0_Did_you_mean_1.category, - code: Diagnostics.Unknown_type_acquisition_option_0_Did_you_mean_1.code, + category: ts.Diagnostics.Unknown_type_acquisition_option_0_Did_you_mean_1.category, + code: ts.Diagnostics.Unknown_type_acquisition_option_0_Did_you_mean_1.code, file: undefined, start: 0, length: 0, @@ -123,91 +111,75 @@ namespace ts { }); it("Convert default tsconfig.json to typeAcquisition ", () => { - assertTypeAcquisition({}, "tsconfig.json", - { - typeAcquisition: - { + assertTypeAcquisition({}, "tsconfig.json", { + typeAcquisition: { enable: false, include: [], exclude: [] }, - errors: [] as Diagnostic[] + errors: [] as ts.Diagnostic[] }); }); it("Convert tsconfig.json with only enable property to typeAcquisition ", () => { - assertTypeAcquisition( - { - typeAcquisition: - { + assertTypeAcquisition({ + typeAcquisition: { enable: true } - }, "tsconfig.json", - { - typeAcquisition: - { + }, "tsconfig.json", { + typeAcquisition: { enable: true, include: [], exclude: [] }, - errors: [] as Diagnostic[] + errors: [] as ts.Diagnostic[] }); }); // jsconfig.json it("Convert jsconfig.json to typeAcquisition ", () => { - assertTypeAcquisition( - { - typeAcquisition: - { + assertTypeAcquisition({ + typeAcquisition: { enable: false, include: ["0.d.ts"], exclude: ["0.js"] } - }, "jsconfig.json", - { - typeAcquisition: - { + }, "jsconfig.json", { + typeAcquisition: { enable: false, include: ["0.d.ts"], exclude: ["0.js"] }, - errors: [] as Diagnostic[] + errors: [] as ts.Diagnostic[] }); }); it("Convert default jsconfig.json to typeAcquisition ", () => { - assertTypeAcquisition({ }, "jsconfig.json", - { - typeAcquisition: - { + assertTypeAcquisition({}, "jsconfig.json", { + typeAcquisition: { enable: true, include: [], exclude: [] }, - errors: [] as Diagnostic[] + errors: [] as ts.Diagnostic[] }); }); it("Convert incorrect format jsconfig.json to typeAcquisition ", () => { - assertTypeAcquisition( - { - typeAcquisition: - { + assertTypeAcquisition({ + typeAcquisition: { enableAutoDiscovy: true, } - }, "jsconfig.json", - { - typeAcquisition: - { + }, "jsconfig.json", { + typeAcquisition: { enable: true, include: [], exclude: [] }, errors: [ { - category: Diagnostics.Unknown_type_acquisition_option_0_Did_you_mean_1.category, - code: Diagnostics.Unknown_type_acquisition_option_0_Did_you_mean_1.code, + category: ts.Diagnostics.Unknown_type_acquisition_option_0_Did_you_mean_1.category, + code: ts.Diagnostics.Unknown_type_acquisition_option_0_Did_you_mean_1.code, file: undefined, start: 0, length: 0, @@ -218,21 +190,17 @@ namespace ts { }); it("Convert jsconfig.json with only enable property to typeAcquisition ", () => { - assertTypeAcquisition( - { - typeAcquisition: - { + assertTypeAcquisition({ + typeAcquisition: { enable: false } - }, "jsconfig.json", - { - typeAcquisition: - { + }, "jsconfig.json", { + typeAcquisition: { enable: false, include: [], exclude: [] }, - errors: [] as Diagnostic[] + errors: [] as ts.Diagnostic[] }); }); }); diff --git a/src/testRunner/unittests/config/initializeTSConfig.ts b/src/testRunner/unittests/config/initializeTSConfig.ts index f7fb7d2a4398b..21427969ffcc1 100644 --- a/src/testRunner/unittests/config/initializeTSConfig.ts +++ b/src/testRunner/unittests/config/initializeTSConfig.ts @@ -2,8 +2,8 @@ namespace ts { describe("unittests:: config:: initTSConfig", () => { function initTSConfigCorrectly(name: string, commandLinesArgs: string[]) { describe(name, () => { - const commandLine = parseCommandLine(commandLinesArgs); - const initResult = generateTSConfig(commandLine.options, commandLine.fileNames, "\n"); + const commandLine = ts.parseCommandLine(commandLinesArgs); + const initResult = ts.generateTSConfig(commandLine.options, commandLine.fileNames, "\n"); const outputFileName = `tsConfig/${name.replace(/[^a-z0-9\-. ]/ig, "")}/tsconfig.json`; it(`Correct output for ${outputFileName}`, () => { diff --git a/src/testRunner/unittests/config/matchFiles.ts b/src/testRunner/unittests/config/matchFiles.ts index 951d87be80f24..296a9f2ac7944 100644 --- a/src/testRunner/unittests/config/matchFiles.ts +++ b/src/testRunner/unittests/config/matchFiles.ts @@ -100,17 +100,17 @@ namespace ts { "/dev/zebra.ts": "", }})); - function assertParsed(actual: ParsedCommandLine, expected: ParsedCommandLine): void { + function assertParsed(actual: ts.ParsedCommandLine, expected: ts.ParsedCommandLine): void { assert.deepEqual(actual.fileNames, expected.fileNames); assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories); assert.deepEqual(actual.errors, expected.errors); } - function validateMatches(expected: ParsedCommandLine, json: any, host: ParseConfigHost, basePath: string, existingOptions?: CompilerOptions, configFileName?: string, resolutionStack?: Path[]) { + function validateMatches(expected: ts.ParsedCommandLine, json: any, host: ts.ParseConfigHost, basePath: string, existingOptions?: ts.CompilerOptions, configFileName?: string, resolutionStack?: ts.Path[]) { { const jsonText = JSON.stringify(json); - const result = parseJsonText(caseInsensitiveTsconfigPath, jsonText); - const actual = parseJsonSourceFileConfigFileContent(result, host, basePath, existingOptions, configFileName, resolutionStack); + const result = ts.parseJsonText(caseInsensitiveTsconfigPath, jsonText); + const actual = ts.parseJsonSourceFileConfigFileContent(result, host, basePath, existingOptions, configFileName, resolutionStack); for (const error of expected.errors) { if (error.file) { error.file = result; @@ -119,8 +119,8 @@ namespace ts { assertParsed(actual, expected); } { - const actual = parseJsonConfigFileContent(json, host, basePath, existingOptions, configFileName, resolutionStack); - expected.errors = expected.errors.map((error): Diagnostic => ({ + const actual = ts.parseJsonConfigFileContent(json, host, basePath, existingOptions, configFileName, resolutionStack); + expected.errors = expected.errors.map((error): ts.Diagnostic => ({ category: error.category, code: error.code, file: undefined, @@ -134,20 +134,20 @@ namespace ts { } } - function createDiagnosticForConfigFile(json: any, start: number, length: number, diagnosticMessage: DiagnosticMessage, arg0: string) { + function createDiagnosticForConfigFile(json: any, start: number, length: number, diagnosticMessage: ts.DiagnosticMessage, arg0: string) { const text = JSON.stringify(json); const file = { fileName: caseInsensitiveTsconfigPath, - kind: SyntaxKind.SourceFile, + kind: ts.SyntaxKind.SourceFile, text - } as SourceFile; - return createFileDiagnostic(file, start, length, diagnosticMessage, arg0); + } as ts.SourceFile; + return ts.createFileDiagnostic(file, start, length, diagnosticMessage, arg0); } describe("unittests:: config:: matchFiles", () => { it("with defaults", () => { const json = {}; - const expected: ParsedCommandLine = { + const expected: ts.ParsedCommandLine = { options: {}, errors: [], fileNames: [ @@ -156,7 +156,7 @@ namespace ts { "c:/dev/x/a.ts" ], wildcardDirectories: { - "c:/dev": WatchDirectoryFlags.Recursive + "c:/dev": ts.WatchDirectoryFlags.Recursive }, }; validateMatches(expected, json, caseInsensitiveCommonFoldersHost, caseInsensitiveBasePath); @@ -170,7 +170,7 @@ namespace ts { "b.ts" ] }; - const expected: ParsedCommandLine = { + const expected: ts.ParsedCommandLine = { options: {}, errors: [], fileNames: [ @@ -188,7 +188,7 @@ namespace ts { "x.ts" ] }; - const expected: ParsedCommandLine = { + const expected: ts.ParsedCommandLine = { options: {}, errors: [], fileNames: [ @@ -209,7 +209,7 @@ namespace ts { "b.ts" ] }; - const expected: ParsedCommandLine = { + const expected: ts.ParsedCommandLine = { options: {}, errors: [], fileNames: [ @@ -230,7 +230,7 @@ namespace ts { "b.ts" ] }; - const expected: ParsedCommandLine = { + const expected: ts.ParsedCommandLine = { options: {}, errors: [], fileNames: [ @@ -248,11 +248,10 @@ namespace ts { "b.js" ] }; - const expected: ParsedCommandLine = { + const expected: ts.ParsedCommandLine = { options: {}, errors: [ - createCompilerDiagnostic(Diagnostics.No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2, - caseInsensitiveTsconfigPath, JSON.stringify(json.include), "[]") + ts.createCompilerDiagnostic(ts.Diagnostics.No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2, caseInsensitiveTsconfigPath, JSON.stringify(json.include), "[]") ], fileNames: [], wildcardDirectories: {}, @@ -266,11 +265,10 @@ namespace ts { "x.ts" ] }; - const expected: ParsedCommandLine = { + const expected: ts.ParsedCommandLine = { options: {}, errors: [ - createCompilerDiagnostic(Diagnostics.No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2, - caseInsensitiveTsconfigPath, JSON.stringify(json.include), "[]") + ts.createCompilerDiagnostic(ts.Diagnostics.No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2, caseInsensitiveTsconfigPath, JSON.stringify(json.include), "[]") ], fileNames: [], wildcardDirectories: {}, @@ -287,7 +285,7 @@ namespace ts { "b.ts" ] }; - const expected: ParsedCommandLine = { + const expected: ts.ParsedCommandLine = { options: {}, errors: [], fileNames: [ @@ -313,7 +311,7 @@ namespace ts { "*/b.ts" ] }; - const expected: ParsedCommandLine = { + const expected: ts.ParsedCommandLine = { options: {}, errors: [], fileNames: [ @@ -338,7 +336,7 @@ namespace ts { "**/b.ts" ] }; - const expected: ParsedCommandLine = { + const expected: ts.ParsedCommandLine = { options: {}, errors: [], fileNames: [ @@ -359,7 +357,7 @@ namespace ts { "**/b.ts" ] }; - const expected: ParsedCommandLine = { + const expected: ts.ParsedCommandLine = { options: {}, errors: [], fileNames: [ @@ -379,7 +377,7 @@ namespace ts { "jspm_packages/a.ts" ] }; - const expected: ParsedCommandLine = { + const expected: ts.ParsedCommandLine = { options: {}, errors: [], fileNames: [ @@ -407,7 +405,7 @@ namespace ts { "b.ts" ] }; - const expected: ParsedCommandLine = { + const expected: ts.ParsedCommandLine = { options: {}, errors: [], fileNames: [ @@ -429,7 +427,7 @@ namespace ts { "jspm_packages/a.ts" ] }; - const expected: ParsedCommandLine = { + const expected: ts.ParsedCommandLine = { options: {}, errors: [], fileNames: [ @@ -453,7 +451,7 @@ namespace ts { "x/*.ts" ] }; - const expected: ParsedCommandLine = { + const expected: ts.ParsedCommandLine = { options: {}, errors: [], fileNames: [ @@ -468,8 +466,8 @@ namespace ts { "c:/dev/x/b.ts" ], wildcardDirectories: { - "c:/dev/z": WatchDirectoryFlags.None, - "c:/dev/x": WatchDirectoryFlags.None + "c:/dev/z": ts.WatchDirectoryFlags.None, + "c:/dev/x": ts.WatchDirectoryFlags.None }, }; validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath); @@ -480,7 +478,7 @@ namespace ts { "*.ts" ] }; - const expected: ParsedCommandLine = { + const expected: ts.ParsedCommandLine = { options: {}, errors: [], fileNames: [ @@ -489,7 +487,7 @@ namespace ts { "c:/dev/c.d.ts" ], wildcardDirectories: { - "c:/dev": WatchDirectoryFlags.None + "c:/dev": ts.WatchDirectoryFlags.None }, }; validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath); @@ -500,7 +498,7 @@ namespace ts { "*" ] }; - const expected: ParsedCommandLine = { + const expected: ts.ParsedCommandLine = { options: {}, errors: [], fileNames: [ @@ -509,7 +507,7 @@ namespace ts { "c:/dev/c.d.ts" ], wildcardDirectories: { - "c:/dev": WatchDirectoryFlags.None + "c:/dev": ts.WatchDirectoryFlags.None }, }; validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath); @@ -520,7 +518,7 @@ namespace ts { "x/?.ts" ] }; - const expected: ParsedCommandLine = { + const expected: ts.ParsedCommandLine = { options: {}, errors: [], fileNames: [ @@ -528,7 +526,7 @@ namespace ts { "c:/dev/x/b.ts" ], wildcardDirectories: { - "c:/dev/x": WatchDirectoryFlags.None + "c:/dev/x": ts.WatchDirectoryFlags.None }, }; validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath); @@ -539,7 +537,7 @@ namespace ts { "**/a.ts" ] }; - const expected: ParsedCommandLine = { + const expected: ts.ParsedCommandLine = { options: {}, errors: [], fileNames: [ @@ -549,7 +547,7 @@ namespace ts { "c:/dev/z/a.ts" ], wildcardDirectories: { - "c:/dev": WatchDirectoryFlags.Recursive + "c:/dev": ts.WatchDirectoryFlags.Recursive }, }; validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath); @@ -562,7 +560,7 @@ namespace ts { "z/**/a.ts" ] }; - const expected: ParsedCommandLine = { + const expected: ts.ParsedCommandLine = { options: {}, errors: [], fileNames: [ @@ -571,8 +569,8 @@ namespace ts { "c:/dev/z/a.ts" ], wildcardDirectories: { - "c:/dev/x": WatchDirectoryFlags.Recursive, - "c:/dev/z": WatchDirectoryFlags.Recursive + "c:/dev/x": ts.WatchDirectoryFlags.Recursive, + "c:/dev/z": ts.WatchDirectoryFlags.Recursive }, }; validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath); @@ -583,14 +581,14 @@ namespace ts { "**/A.ts" ] }; - const expected: ParsedCommandLine = { + const expected: ts.ParsedCommandLine = { options: {}, errors: [], fileNames: [ "/dev/A.ts" ], wildcardDirectories: { - "/dev": WatchDirectoryFlags.Recursive + "/dev": ts.WatchDirectoryFlags.Recursive }, }; validateMatches(expected, json, caseSensitiveHost, caseSensitiveBasePath); @@ -601,15 +599,14 @@ namespace ts { "*/z.ts" ] }; - const expected: ParsedCommandLine = { + const expected: ts.ParsedCommandLine = { options: {}, errors: [ - createCompilerDiagnostic(Diagnostics.No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2, - caseInsensitiveTsconfigPath, JSON.stringify(json.include), "[]") + ts.createCompilerDiagnostic(ts.Diagnostics.No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2, caseInsensitiveTsconfigPath, JSON.stringify(json.include), "[]") ], fileNames: [], wildcardDirectories: { - "c:/dev": WatchDirectoryFlags.Recursive + "c:/dev": ts.WatchDirectoryFlags.Recursive }, }; validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath, /*existingOptions*/ undefined, caseInsensitiveTsconfigPath); @@ -626,14 +623,14 @@ namespace ts { "**/a.ts" ] }; - const expected: ParsedCommandLine = { + const expected: ts.ParsedCommandLine = { options: {}, errors: [], fileNames: [ "c:/dev/a.ts" ], wildcardDirectories: { - "c:/dev": WatchDirectoryFlags.Recursive + "c:/dev": ts.WatchDirectoryFlags.Recursive }, }; validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath); @@ -648,7 +645,7 @@ namespace ts { "x" ] }; - const expected: ParsedCommandLine = { + const expected: ts.ParsedCommandLine = { options: {}, errors: [], fileNames: [ @@ -657,7 +654,7 @@ namespace ts { "c:/dev/c.d.ts" ], wildcardDirectories: { - "c:/dev": WatchDirectoryFlags.Recursive + "c:/dev": ts.WatchDirectoryFlags.Recursive } }; validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath); @@ -669,7 +666,7 @@ namespace ts { "**/a.ts" ] }; - const expected: ParsedCommandLine = { + const expected: ts.ParsedCommandLine = { options: {}, errors: [], fileNames: [ @@ -677,7 +674,7 @@ namespace ts { "c:/dev/x/a.ts" ], wildcardDirectories: { - "c:/dev": WatchDirectoryFlags.Recursive + "c:/dev": ts.WatchDirectoryFlags.Recursive }, }; validateMatches(expected, json, caseInsensitiveCommonFoldersHost, caseInsensitiveBasePath); @@ -691,7 +688,7 @@ namespace ts { "a.ts" ] }; - const expected: ParsedCommandLine = { + const expected: ts.ParsedCommandLine = { options: {}, errors: [], fileNames: [ @@ -699,7 +696,7 @@ namespace ts { "c:/dev/x/a.ts" ], wildcardDirectories: { - "c:/dev": WatchDirectoryFlags.Recursive + "c:/dev": ts.WatchDirectoryFlags.Recursive }, }; validateMatches(expected, json, caseInsensitiveCommonFoldersHost, caseInsensitiveBasePath); @@ -711,7 +708,7 @@ namespace ts { ], exclude: [] as string[] }; - const expected: ParsedCommandLine = { + const expected: ts.ParsedCommandLine = { options: {}, errors: [], fileNames: [ @@ -719,7 +716,7 @@ namespace ts { "c:/dev/x/a.ts" ], wildcardDirectories: { - "c:/dev": WatchDirectoryFlags.Recursive + "c:/dev": ts.WatchDirectoryFlags.Recursive }, }; validateMatches(expected, json, caseInsensitiveCommonFoldersHost, caseInsensitiveBasePath); @@ -731,7 +728,7 @@ namespace ts { "**/node_modules/a.ts" ] }; - const expected: ParsedCommandLine = { + const expected: ts.ParsedCommandLine = { options: {}, errors: [], fileNames: [ @@ -740,7 +737,7 @@ namespace ts { "c:/dev/node_modules/a.ts" ], wildcardDirectories: { - "c:/dev": WatchDirectoryFlags.Recursive + "c:/dev": ts.WatchDirectoryFlags.Recursive }, }; validateMatches(expected, json, caseInsensitiveCommonFoldersHost, caseInsensitiveBasePath); @@ -751,14 +748,14 @@ namespace ts { "*/a.ts" ] }; - const expected: ParsedCommandLine = { + const expected: ts.ParsedCommandLine = { options: {}, errors: [], fileNames: [ "c:/dev/x/a.ts" ], wildcardDirectories: { - "c:/dev": WatchDirectoryFlags.Recursive + "c:/dev": ts.WatchDirectoryFlags.Recursive }, }; validateMatches(expected, json, caseInsensitiveCommonFoldersHost, caseInsensitiveBasePath); @@ -770,7 +767,7 @@ namespace ts { "node_modules/a.ts" ] }; - const expected: ParsedCommandLine = { + const expected: ts.ParsedCommandLine = { options: {}, errors: [], fileNames: [ @@ -778,7 +775,7 @@ namespace ts { "c:/dev/node_modules/a.ts" ], wildcardDirectories: { - "c:/dev": WatchDirectoryFlags.Recursive + "c:/dev": ts.WatchDirectoryFlags.Recursive }, }; validateMatches(expected, json, caseInsensitiveCommonFoldersHost, caseInsensitiveBasePath); @@ -793,17 +790,16 @@ namespace ts { "js/*" ] }; - const expected: ParsedCommandLine = { + const expected: ts.ParsedCommandLine = { options: { allowJs: false }, errors: [ - createCompilerDiagnostic(Diagnostics.No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2, - caseInsensitiveTsconfigPath, JSON.stringify(json.include), "[]") + ts.createCompilerDiagnostic(ts.Diagnostics.No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2, caseInsensitiveTsconfigPath, JSON.stringify(json.include), "[]") ], fileNames: [], wildcardDirectories: { - "c:/dev/js": WatchDirectoryFlags.None + "c:/dev/js": ts.WatchDirectoryFlags.None } }; validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath, /*existingOptions*/ undefined, caseInsensitiveTsconfigPath); @@ -817,7 +813,7 @@ namespace ts { "js/*" ] }; - const expected: ParsedCommandLine = { + const expected: ts.ParsedCommandLine = { options: { allowJs: true }, @@ -827,7 +823,7 @@ namespace ts { "c:/dev/js/b.js" ], wildcardDirectories: { - "c:/dev/js": WatchDirectoryFlags.None + "c:/dev/js": ts.WatchDirectoryFlags.None } }; validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath); @@ -841,7 +837,7 @@ namespace ts { "js/*.min.js" ] }; - const expected: ParsedCommandLine = { + const expected: ts.ParsedCommandLine = { options: { allowJs: true }, @@ -851,7 +847,7 @@ namespace ts { "c:/dev/js/d.min.js" ], wildcardDirectories: { - "c:/dev/js": WatchDirectoryFlags.None + "c:/dev/js": ts.WatchDirectoryFlags.None } }; validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath); @@ -863,7 +859,7 @@ namespace ts { "c:/ext/*" ] }; - const expected: ParsedCommandLine = { + const expected: ts.ParsedCommandLine = { options: {}, errors: [], fileNames: [ @@ -873,8 +869,8 @@ namespace ts { "c:/ext/ext.ts" ], wildcardDirectories: { - "c:/dev": WatchDirectoryFlags.None, - "c:/ext": WatchDirectoryFlags.None + "c:/dev": ts.WatchDirectoryFlags.None, + "c:/ext": ts.WatchDirectoryFlags.None } }; validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath); @@ -889,14 +885,14 @@ namespace ts { "**" ] }; - const expected: ParsedCommandLine = { + const expected: ts.ParsedCommandLine = { options: {}, errors: [], fileNames: [ "c:/ext/ext.ts" ], wildcardDirectories: { - "c:/ext": WatchDirectoryFlags.None + "c:/ext": ts.WatchDirectoryFlags.None } }; validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath); @@ -910,12 +906,11 @@ namespace ts { "../**" ] }; - const expected: ParsedCommandLine = { + const expected: ts.ParsedCommandLine = { options: {}, errors: [ - createCompilerDiagnostic(Diagnostics.No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2, - caseInsensitiveTsconfigPath, JSON.stringify(json.include), JSON.stringify(json.exclude))] - , + ts.createCompilerDiagnostic(ts.Diagnostics.No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2, caseInsensitiveTsconfigPath, JSON.stringify(json.include), JSON.stringify(json.exclude)) + ], fileNames: [], wildcardDirectories: {} }; @@ -930,7 +925,7 @@ namespace ts { "**" ] }; - const expected: ParsedCommandLine = { + const expected: ts.ParsedCommandLine = { options: {}, errors: [], fileNames: [ @@ -949,14 +944,14 @@ namespace ts { "c:/ext/b/a..b.ts" ] }; - const expected: ParsedCommandLine = { + const expected: ts.ParsedCommandLine = { options: {}, errors: [], fileNames: [ "c:/ext/ext.ts", ], wildcardDirectories: { - "c:/ext": WatchDirectoryFlags.Recursive + "c:/ext": ts.WatchDirectoryFlags.Recursive } }; validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath); @@ -967,7 +962,7 @@ namespace ts { allowJs: false } }; - const expected: ParsedCommandLine = { + const expected: ts.ParsedCommandLine = { options: { allowJs: false }, @@ -978,7 +973,7 @@ namespace ts { "c:/dev/c.tsx", ], wildcardDirectories: { - "c:/dev": WatchDirectoryFlags.Recursive + "c:/dev": ts.WatchDirectoryFlags.Recursive } }; validateMatches(expected, json, caseInsensitiveMixedExtensionHost, caseInsensitiveBasePath); @@ -990,9 +985,9 @@ namespace ts { allowJs: false } }; - const expected: ParsedCommandLine = { + const expected: ts.ParsedCommandLine = { options: { - jsx: JsxEmit.Preserve, + jsx: ts.JsxEmit.Preserve, allowJs: false }, errors: [], @@ -1002,7 +997,7 @@ namespace ts { "c:/dev/c.tsx", ], wildcardDirectories: { - "c:/dev": WatchDirectoryFlags.Recursive + "c:/dev": ts.WatchDirectoryFlags.Recursive } }; validateMatches(expected, json, caseInsensitiveMixedExtensionHost, caseInsensitiveBasePath); @@ -1014,9 +1009,9 @@ namespace ts { allowJs: false } }; - const expected: ParsedCommandLine = { + const expected: ts.ParsedCommandLine = { options: { - jsx: JsxEmit.ReactNative, + jsx: ts.JsxEmit.ReactNative, allowJs: false }, errors: [], @@ -1026,7 +1021,7 @@ namespace ts { "c:/dev/c.tsx", ], wildcardDirectories: { - "c:/dev": WatchDirectoryFlags.Recursive + "c:/dev": ts.WatchDirectoryFlags.Recursive } }; validateMatches(expected, json, caseInsensitiveMixedExtensionHost, caseInsensitiveBasePath); @@ -1037,7 +1032,7 @@ namespace ts { allowJs: true } }; - const expected: ParsedCommandLine = { + const expected: ts.ParsedCommandLine = { options: { allowJs: true }, @@ -1050,7 +1045,7 @@ namespace ts { "c:/dev/e.jsx", ], wildcardDirectories: { - "c:/dev": WatchDirectoryFlags.Recursive + "c:/dev": ts.WatchDirectoryFlags.Recursive } }; validateMatches(expected, json, caseInsensitiveMixedExtensionHost, caseInsensitiveBasePath); @@ -1062,9 +1057,9 @@ namespace ts { allowJs: true } }; - const expected: ParsedCommandLine = { + const expected: ts.ParsedCommandLine = { options: { - jsx: JsxEmit.Preserve, + jsx: ts.JsxEmit.Preserve, allowJs: true }, errors: [], @@ -1076,7 +1071,7 @@ namespace ts { "c:/dev/e.jsx", ], wildcardDirectories: { - "c:/dev": WatchDirectoryFlags.Recursive + "c:/dev": ts.WatchDirectoryFlags.Recursive } }; validateMatches(expected, json, caseInsensitiveMixedExtensionHost, caseInsensitiveBasePath); @@ -1088,9 +1083,9 @@ namespace ts { allowJs: true } }; - const expected: ParsedCommandLine = { + const expected: ts.ParsedCommandLine = { options: { - jsx: JsxEmit.ReactNative, + jsx: ts.JsxEmit.ReactNative, allowJs: true }, errors: [], @@ -1102,7 +1097,7 @@ namespace ts { "c:/dev/e.jsx", ], wildcardDirectories: { - "c:/dev": WatchDirectoryFlags.Recursive + "c:/dev": ts.WatchDirectoryFlags.Recursive } }; validateMatches(expected, json, caseInsensitiveMixedExtensionHost, caseInsensitiveBasePath); @@ -1119,7 +1114,7 @@ namespace ts { "js/a*" ] }; - const expected: ParsedCommandLine = { + const expected: ts.ParsedCommandLine = { options: { allowJs: true }, @@ -1128,7 +1123,7 @@ namespace ts { "c:/dev/js/d.min.js" ], wildcardDirectories: { - "c:/dev/js": WatchDirectoryFlags.None + "c:/dev/js": ts.WatchDirectoryFlags.None } }; validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath); @@ -1141,12 +1136,11 @@ namespace ts { "**" ] }; - const expected: ParsedCommandLine = { + const expected: ts.ParsedCommandLine = { options: {}, errors: [ - createDiagnosticForConfigFile(json, 12, 4, Diagnostics.File_specification_cannot_end_in_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0, "**"), - createCompilerDiagnostic(Diagnostics.No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2, - caseInsensitiveTsconfigPath, JSON.stringify(json.include), "[]") + createDiagnosticForConfigFile(json, 12, 4, ts.Diagnostics.File_specification_cannot_end_in_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0, "**"), + ts.createCompilerDiagnostic(ts.Diagnostics.No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2, caseInsensitiveTsconfigPath, JSON.stringify(json.include), "[]") ], fileNames: [], wildcardDirectories: {} @@ -1162,11 +1156,10 @@ namespace ts { "**" ] }; - const expected: ParsedCommandLine = { + const expected: ts.ParsedCommandLine = { options: {}, errors: [ - createCompilerDiagnostic(Diagnostics.No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2, - caseInsensitiveTsconfigPath, JSON.stringify(json.include), JSON.stringify(json.exclude)) + ts.createCompilerDiagnostic(ts.Diagnostics.No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2, caseInsensitiveTsconfigPath, JSON.stringify(json.include), JSON.stringify(json.exclude)) ], fileNames: [], wildcardDirectories: {} @@ -1181,7 +1174,7 @@ namespace ts { "**/x/**/*" ] }; - const expected: ParsedCommandLine = { + const expected: ts.ParsedCommandLine = { options: {}, errors: [], fileNames: [ @@ -1192,7 +1185,7 @@ namespace ts { "c:/dev/x/y/b.ts", ], wildcardDirectories: { - "c:/dev": WatchDirectoryFlags.Recursive + "c:/dev": ts.WatchDirectoryFlags.Recursive } }; validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath, /*existingOptions*/ undefined, caseInsensitiveTsconfigPath); @@ -1206,7 +1199,7 @@ namespace ts { "**/x/**" ] }; - const expected: ParsedCommandLine = { + const expected: ts.ParsedCommandLine = { options: {}, errors: [], fileNames: [ @@ -1214,7 +1207,7 @@ namespace ts { "c:/dev/z/a.ts" ], wildcardDirectories: { - "c:/dev": WatchDirectoryFlags.Recursive + "c:/dev": ts.WatchDirectoryFlags.Recursive } }; validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath); @@ -1228,12 +1221,11 @@ namespace ts { "**/../*" ] }; - const expected: ParsedCommandLine = { + const expected: ts.ParsedCommandLine = { options: {}, errors: [ - createDiagnosticForConfigFile(json, 12, 9, Diagnostics.File_specification_cannot_contain_a_parent_directory_that_appears_after_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0, "**/../*"), - createCompilerDiagnostic(Diagnostics.No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2, - caseInsensitiveTsconfigPath, JSON.stringify(json.include), "[]") + createDiagnosticForConfigFile(json, 12, 9, ts.Diagnostics.File_specification_cannot_contain_a_parent_directory_that_appears_after_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0, "**/../*"), + ts.createCompilerDiagnostic(ts.Diagnostics.No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2, caseInsensitiveTsconfigPath, JSON.stringify(json.include), "[]") ], fileNames: [], wildcardDirectories: {} @@ -1247,12 +1239,11 @@ namespace ts { "**/y/../*" ] }; - const expected: ParsedCommandLine = { + const expected: ts.ParsedCommandLine = { options: {}, errors: [ - createDiagnosticForConfigFile(json, 12, 11, Diagnostics.File_specification_cannot_contain_a_parent_directory_that_appears_after_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0, "**/y/../*"), - createCompilerDiagnostic(Diagnostics.No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2, - caseInsensitiveTsconfigPath, JSON.stringify(json.include), "[]") + createDiagnosticForConfigFile(json, 12, 11, ts.Diagnostics.File_specification_cannot_contain_a_parent_directory_that_appears_after_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0, "**/y/../*"), + ts.createCompilerDiagnostic(ts.Diagnostics.No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2, caseInsensitiveTsconfigPath, JSON.stringify(json.include), "[]") ], fileNames: [], wildcardDirectories: {} @@ -1269,10 +1260,10 @@ namespace ts { "**/.." ] }; - const expected: ParsedCommandLine = { + const expected: ts.ParsedCommandLine = { options: {}, errors: [ - createDiagnosticForConfigFile(json, 34, 7, Diagnostics.File_specification_cannot_contain_a_parent_directory_that_appears_after_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0, "**/..") + createDiagnosticForConfigFile(json, 34, 7, ts.Diagnostics.File_specification_cannot_contain_a_parent_directory_that_appears_after_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0, "**/..") ], fileNames: [ "c:/dev/a.ts", @@ -1281,7 +1272,7 @@ namespace ts { "c:/dev/z/a.ts" ], wildcardDirectories: { - "c:/dev": WatchDirectoryFlags.Recursive + "c:/dev": ts.WatchDirectoryFlags.Recursive } }; validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath); @@ -1296,10 +1287,10 @@ namespace ts { "**/y/.." ] }; - const expected: ParsedCommandLine = { + const expected: ts.ParsedCommandLine = { options: {}, errors: [ - createDiagnosticForConfigFile(json, 34, 9, Diagnostics.File_specification_cannot_contain_a_parent_directory_that_appears_after_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0, "**/y/..") + createDiagnosticForConfigFile(json, 34, 9, ts.Diagnostics.File_specification_cannot_contain_a_parent_directory_that_appears_after_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0, "**/y/..") ], fileNames: [ "c:/dev/a.ts", @@ -1308,7 +1299,7 @@ namespace ts { "c:/dev/z/a.ts" ], wildcardDirectories: { - "c:/dev": WatchDirectoryFlags.Recursive + "c:/dev": ts.WatchDirectoryFlags.Recursive } }; validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath); @@ -1320,12 +1311,12 @@ namespace ts { const json = { include: ["z"] }; - const expected: ParsedCommandLine = { + const expected: ts.ParsedCommandLine = { options: {}, errors: [], fileNames: [ "a.ts", "aba.ts", "abz.ts", "b.ts", "bba.ts", "bbz.ts" ].map(x => `c:/dev/z/${x}`), wildcardDirectories: { - "c:/dev/z": WatchDirectoryFlags.Recursive + "c:/dev/z": ts.WatchDirectoryFlags.Recursive } }; validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath); @@ -1341,7 +1332,7 @@ namespace ts { "w/*/*" ] }; - const expected: ParsedCommandLine = { + const expected: ts.ParsedCommandLine = { options: {}, errors: [], fileNames: [ @@ -1349,8 +1340,8 @@ namespace ts { "c:/dev/x/y/d.ts", ], wildcardDirectories: { - "c:/dev/x": WatchDirectoryFlags.Recursive, - "c:/dev/w": WatchDirectoryFlags.Recursive + "c:/dev/x": ts.WatchDirectoryFlags.Recursive, + "c:/dev/w": ts.WatchDirectoryFlags.Recursive } }; validateMatches(expected, json, caseInsensitiveDottedFoldersHost, caseInsensitiveBasePath); @@ -1363,7 +1354,7 @@ namespace ts { "c:/dev/.z/.b.ts" ] }; - const expected: ParsedCommandLine = { + const expected: ts.ParsedCommandLine = { options: {}, errors: [], fileNames: [ @@ -1380,7 +1371,7 @@ namespace ts { "**/.*/*" ] }; - const expected: ParsedCommandLine = { + const expected: ts.ParsedCommandLine = { options: {}, errors: [], fileNames: [ @@ -1390,7 +1381,7 @@ namespace ts { "c:/dev/x/.y/a.ts" ], wildcardDirectories: { - "c:/dev": WatchDirectoryFlags.Recursive + "c:/dev": ts.WatchDirectoryFlags.Recursive } }; validateMatches(expected, json, caseInsensitiveDottedFoldersHost, caseInsensitiveBasePath); @@ -1402,7 +1393,7 @@ namespace ts { ".z/**/.*" ] }; - const expected: ParsedCommandLine = { + const expected: ts.ParsedCommandLine = { options: {}, errors: [], fileNames: [ @@ -1410,8 +1401,8 @@ namespace ts { "c:/dev/.z/.b.ts" ], wildcardDirectories: { - "c:/dev/.z": WatchDirectoryFlags.Recursive, - "c:/dev/x": WatchDirectoryFlags.Recursive + "c:/dev/.z": ts.WatchDirectoryFlags.Recursive, + "c:/dev/x": ts.WatchDirectoryFlags.Recursive } }; validateMatches(expected, json, caseInsensitiveDottedFoldersHost, caseInsensitiveBasePath); @@ -1425,11 +1416,10 @@ namespace ts { "**/*" ] }; - const expected: ParsedCommandLine = { + const expected: ts.ParsedCommandLine = { options: {}, errors: [ - createCompilerDiagnostic(Diagnostics.No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2, - caseInsensitiveTsconfigPath, JSON.stringify(json.include), JSON.stringify(json.exclude)) + ts.createCompilerDiagnostic(ts.Diagnostics.No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2, caseInsensitiveTsconfigPath, JSON.stringify(json.include), JSON.stringify(json.exclude)) ], fileNames: [], wildcardDirectories: {} @@ -1446,7 +1436,7 @@ namespace ts { "**/x" ] }; - const expected: ParsedCommandLine = { + const expected: ts.ParsedCommandLine = { options: {}, errors: [], fileNames: [ @@ -1464,7 +1454,7 @@ namespace ts { "/dev/z/bbz.ts", ], wildcardDirectories: { - "/dev": WatchDirectoryFlags.Recursive + "/dev": ts.WatchDirectoryFlags.Recursive } }; validateMatches(expected, json, caseSensitiveHost, caseSensitiveBasePath); @@ -1476,7 +1466,7 @@ namespace ts { "**/a/**/b" ] }; - const expected: ParsedCommandLine = { + const expected: ts.ParsedCommandLine = { options: {}, errors: [], fileNames: [ @@ -1487,7 +1477,7 @@ namespace ts { "/dev/q/a/c/b/d.ts", ], wildcardDirectories: { - "/dev": WatchDirectoryFlags.Recursive + "/dev": ts.WatchDirectoryFlags.Recursive } }; validateMatches(expected, json, caseSensitiveHost, caseSensitiveBasePath); @@ -1495,17 +1485,17 @@ namespace ts { }); it("can include files in the same order on multiple platforms", () => { - function getExpected(basePath: string): ParsedCommandLine { + function getExpected(basePath: string): ts.ParsedCommandLine { return { options: {}, errors: [], fileNames: [ - `${basePath}Yosemite.ts`, // capital always comes before lowercase letters + `${basePath}Yosemite.ts`, `${basePath}xylophone.ts`, `${basePath}zebra.ts` ], wildcardDirectories: { - [basePath.slice(0, basePath.length - 1)]: WatchDirectoryFlags.Recursive + [basePath.slice(0, basePath.length - 1)]: ts.WatchDirectoryFlags.Recursive }, }; } @@ -1526,14 +1516,14 @@ namespace ts { fs.symlinkSync("c:/dev/a", "c:/dev/a/b/c/grandparent"); const host = new fakes.ParseConfigHost(fs); const json = {}; - const expected: ParsedCommandLine = { + const expected: ts.ParsedCommandLine = { options: {}, errors: [], fileNames: [ "c:/dev/index.ts" ], wildcardDirectories: { - "c:/dev": WatchDirectoryFlags.Recursive + "c:/dev": ts.WatchDirectoryFlags.Recursive }, }; validateMatches(expected, json, host, caseInsensitiveBasePath); diff --git a/src/testRunner/unittests/config/projectReferences.ts b/src/testRunner/unittests/config/projectReferences.ts index a70329a8db8a2..41389fb5d8c0a 100644 --- a/src/testRunner/unittests/config/projectReferences.ts +++ b/src/testRunner/unittests/config/projectReferences.ts @@ -1,24 +1,28 @@ namespace ts { interface TestProjectSpecification { configFileName?: string; - references?: readonly (string | ProjectReference)[]; - files: { [fileName: string]: string }; - outputFiles?: { [fileName: string]: string }; + references?: readonly (string | ts.ProjectReference)[]; + files: { + [fileName: string]: string; + }; + outputFiles?: { + [fileName: string]: string; + }; config?: object; - options?: Partial; + options?: Partial; } interface TestSpecification { [path: string]: TestProjectSpecification; } - function assertHasError(message: string, errors: readonly Diagnostic[], diag: DiagnosticMessage) { + function assertHasError(message: string, errors: readonly ts.Diagnostic[], diag: ts.DiagnosticMessage) { if (!errors.some(e => e.code === diag.code)) { const errorString = errors.map(e => ` ${e.file ? e.file.fileName : "[global]"}: ${e.messageText}`).join("\r\n"); assert(false, `${message}: Did not find any diagnostic for ${diag.message} in:\r\n${errorString}`); } } - function assertNoErrors(message: string, errors: readonly Diagnostic[]) { + function assertNoErrors(message: string, errors: readonly ts.Diagnostic[]) { if (errors && errors.length > 0) { assert(false, `${message}: Expected no errors, but found:\r\n${errors.map(e => ` ${e.messageText}`).join("\r\n")}`); } @@ -27,7 +31,7 @@ namespace ts { function combineAllPaths(...paths: string[]) { let result = paths[0]; for (let i = 1; i < paths.length; i++) { - result = combinePaths(result, paths[i]); + result = ts.combinePaths(result, paths[i]); } return result; } @@ -42,8 +46,8 @@ namespace ts { return names.map((n, i) => `import * as mod_${i} from ${n}`).join("\r\n"); } - function testProjectReferences(spec: TestSpecification, entryPointConfigFileName: string, checkResult: (prog: Program, host: fakes.CompilerHost) => void) { - const files = new Map(); + function testProjectReferences(spec: TestSpecification, entryPointConfigFileName: string, checkResult: (prog: ts.Program, host: fakes.CompilerHost) => void) { + const files = new ts.Map(); for (const key in spec) { const sp = spec[key]; const configFileName = combineAllPaths("/", key, sp.configFileName || "tsconfig.json"); @@ -74,20 +78,20 @@ namespace ts { } } - const vfsys = new vfs.FileSystem(false, { files: { "/lib.d.ts": TestFSWithWatch.libFile.content } }); + const vfsys = new vfs.FileSystem(false, { files: { "/lib.d.ts": ts.TestFSWithWatch.libFile.content } }); files.forEach((v, k) => { - vfsys.mkdirpSync(getDirectoryPath(k)); + vfsys.mkdirpSync(ts.getDirectoryPath(k)); vfsys.writeFileSync(k, v); }); const host = new fakes.CompilerHost(new fakes.System(vfsys)); - const { config, error } = readConfigFile(entryPointConfigFileName, name => host.readFile(name)); + const { config, error } = ts.readConfigFile(entryPointConfigFileName, name => host.readFile(name)); // We shouldn't have any errors about invalid tsconfig files in these tests - assert(config && !error, flattenDiagnosticMessageText(error && error.messageText, "\n")); - const file = parseJsonConfigFileContent(config, parseConfigHostFromCompilerHostLike(host), getDirectoryPath(entryPointConfigFileName), {}, entryPointConfigFileName); + assert(config && !error, ts.flattenDiagnosticMessageText(error && error.messageText, "\n")); + const file = ts.parseJsonConfigFileContent(config, ts.parseConfigHostFromCompilerHostLike(host), ts.getDirectoryPath(entryPointConfigFileName), {}, entryPointConfigFileName); file.options.configFilePath = entryPointConfigFileName; - const prog = createProgram({ + const prog = ts.createProgram({ rootNames: file.fileNames, options: file.options, host, @@ -132,7 +136,7 @@ namespace ts { testProjectReferences(spec, "/primary/tsconfig.json", program => { const errs = program.getOptionsDiagnostics(); - assertHasError("Reports an error about the wrong decl setting", errs, Diagnostics.Composite_projects_may_not_disable_declaration_emit); + assertHasError("Reports an error about the wrong decl setting", errs, ts.Diagnostics.Composite_projects_may_not_disable_declaration_emit); }); }); @@ -155,7 +159,7 @@ namespace ts { }; testProjectReferences(spec, "/reference/tsconfig.json", program => { const errs = program.getOptionsDiagnostics(); - assertHasError("Reports an error about 'composite' not being set", errs, Diagnostics.Referenced_project_0_must_have_setting_composite_Colon_true); + assertHasError("Reports an error about 'composite' not being set", errs, ts.Diagnostics.Referenced_project_0_must_have_setting_composite_Colon_true); }); }); @@ -194,7 +198,7 @@ namespace ts { testProjectReferences(spec, "/primary/tsconfig.json", program => { const errs = program.getSemanticDiagnostics(program.getSourceFile("/primary/a.ts")); - assertHasError("Reports an error about b.ts not being in the list", errs, Diagnostics.File_0_is_not_listed_within_the_file_list_of_project_1_Projects_must_list_all_files_or_use_an_include_pattern); + assertHasError("Reports an error about b.ts not being in the list", errs, ts.Diagnostics.File_0_is_not_listed_within_the_file_list_of_project_1_Projects_must_list_all_files_or_use_an_include_pattern); }); }); @@ -207,7 +211,7 @@ namespace ts { }; testProjectReferences(spec, "/primary/tsconfig.json", program => { const errs = program.getOptionsDiagnostics(); - assertHasError("Reports an error about a missing file", errs, Diagnostics.File_0_not_found); + assertHasError("Reports an error about a missing file", errs, ts.Diagnostics.File_0_not_found); }); }); @@ -223,7 +227,7 @@ namespace ts { }; testProjectReferences(spec, "/primary/tsconfig.json", program => { const errs = program.getOptionsDiagnostics(); - assertHasError("Reports an error about outFile not being set", errs, Diagnostics.Cannot_prepend_project_0_because_it_does_not_have_outFile_set); + assertHasError("Reports an error about outFile not being set", errs, ts.Diagnostics.Cannot_prepend_project_0_because_it_does_not_have_outFile_set); }); }); @@ -240,7 +244,7 @@ namespace ts { }; testProjectReferences(spec, "/primary/tsconfig.json", program => { const errs = program.getOptionsDiagnostics(); - assertHasError("Reports an error about outFile being missing", errs, Diagnostics.Output_file_0_from_project_1_does_not_exist); + assertHasError("Reports an error about outFile being missing", errs, ts.Diagnostics.Output_file_0_from_project_1_does_not_exist); }); }); }); @@ -263,7 +267,7 @@ namespace ts { }; testProjectReferences(spec, "/beta/tsconfig.json", program => { assertNoErrors("File setup should be correct", program.getOptionsDiagnostics()); - assertHasError("Found a type error", program.getSemanticDiagnostics(), Diagnostics.Module_0_has_no_exported_member_1); + assertHasError("Found a type error", program.getSemanticDiagnostics(), ts.Diagnostics.Module_0_has_no_exported_member_1); }); }); }); @@ -281,7 +285,7 @@ namespace ts { } }; testProjectReferences(spec, "/beta/tsconfig.json", program => { - assertHasError("Issues a useful error", program.getSemanticDiagnostics(), Diagnostics.Output_file_0_has_not_been_built_from_source_file_1); + assertHasError("Issues a useful error", program.getSemanticDiagnostics(), ts.Diagnostics.Output_file_0_has_not_been_built_from_source_file_1); }); }); @@ -303,7 +307,7 @@ namespace ts { } }; testProjectReferences(spec, "/beta/tsconfig.json", program => { - assertHasError("Issues a useful error", program.getSemanticDiagnostics(), Diagnostics.Output_file_0_has_not_been_built_from_source_file_1); + assertHasError("Issues a useful error", program.getSemanticDiagnostics(), ts.Diagnostics.Output_file_0_has_not_been_built_from_source_file_1); }); }); }); @@ -344,8 +348,8 @@ namespace ts { }; testProjectReferences(spec, "/alpha/tsconfig.json", (program) => { const semanticDiagnostics = program.getSemanticDiagnostics(program.getSourceFile("/alpha/src/a.ts")); - assertHasError("Issues an error about the rootDir", semanticDiagnostics, Diagnostics.File_0_is_not_under_rootDir_1_rootDir_is_expected_to_contain_all_source_files); - assertHasError("Issues an error about the fileList", semanticDiagnostics, Diagnostics.File_0_is_not_listed_within_the_file_list_of_project_1_Projects_must_list_all_files_or_use_an_include_pattern); + assertHasError("Issues an error about the rootDir", semanticDiagnostics, ts.Diagnostics.File_0_is_not_under_rootDir_1_rootDir_is_expected_to_contain_all_source_files); + assertHasError("Issues an error about the fileList", semanticDiagnostics, ts.Diagnostics.File_0_is_not_listed_within_the_file_list_of_project_1_Projects_must_list_all_files_or_use_an_include_pattern); }); }); }); diff --git a/src/testRunner/unittests/config/showConfig.ts b/src/testRunner/unittests/config/showConfig.ts index f8905e3412677..ac831468fd88b 100644 --- a/src/testRunner/unittests/config/showConfig.ts +++ b/src/testRunner/unittests/config/showConfig.ts @@ -6,28 +6,26 @@ namespace ts { it(`Correct output for ${outputFileName}`, () => { const cwd = `/${name}`; - const configPath = combinePaths(cwd, "tsconfig.json"); + const configPath = ts.combinePaths(cwd, "tsconfig.json"); const configContents = configJson ? JSON.stringify(configJson) : undefined; - const configParseHost: ParseConfigFileHost = { - fileExists: path => - comparePaths(getNormalizedAbsolutePath(path, cwd), configPath) === Comparison.EqualTo ? true : false, + const configParseHost: ts.ParseConfigFileHost = { + fileExists: path => ts.comparePaths(ts.getNormalizedAbsolutePath(path, cwd), configPath) === ts.Comparison.EqualTo ? true : false, getCurrentDirectory() { return cwd; }, useCaseSensitiveFileNames: true, onUnRecoverableConfigFileDiagnostic: d => { - throw new Error(flattenDiagnosticMessageText(d.messageText, "\n")); + throw new Error(ts.flattenDiagnosticMessageText(d.messageText, "\n")); }, readDirectory() { return []; }, - readFile: path => - comparePaths(getNormalizedAbsolutePath(path, cwd), configPath) === Comparison.EqualTo ? configContents : undefined, + readFile: path => ts.comparePaths(ts.getNormalizedAbsolutePath(path, cwd), configPath) === ts.Comparison.EqualTo ? configContents : undefined, }; - let commandLine = parseCommandLine(commandLinesArgs); + let commandLine = ts.parseCommandLine(commandLinesArgs); if (commandLine.options.project) { - const result = getParsedCommandLineOfConfigFile(commandLine.options.project, commandLine.options, configParseHost); + const result = ts.getParsedCommandLineOfConfigFile(commandLine.options.project, commandLine.options, configParseHost); if (result) { commandLine = result; } } - const initResult = convertToTSConfig(commandLine, configPath, configParseHost); + const initResult = ts.convertToTSConfig(commandLine, configPath, configParseHost); // eslint-disable-next-line no-null/no-null Harness.Baseline.runBaseline(outputFileName, JSON.stringify(initResult, null, 4) + "\n"); @@ -112,16 +110,17 @@ namespace ts { }); // Bulk validation of all option declarations - for (const option of optionDeclarations) { + for (const option of ts.optionDeclarations) { baselineOption(option, /*isCompilerOptions*/ true); } - for (const option of optionsForWatch) { + for (const option of ts.optionsForWatch) { baselineOption(option, /*isCompilerOptions*/ false); } - function baselineOption(option: CommandLineOption, isCompilerOptions: boolean) { - if (option.name === "project") return; + function baselineOption(option: ts.CommandLineOption, isCompilerOptions: boolean) { + if (option.name === "project") + return; let args: string[]; let optionValue: object | undefined; switch (option.type) { @@ -172,7 +171,8 @@ namespace ts { } default: { const iterResult = option.type.keys().next(); - if (iterResult.done) return Debug.fail("Expected 'option.type' to have entries"); + if (iterResult.done) + return ts.Debug.fail("Expected 'option.type' to have entries"); const val = iterResult.value; if (option.isTSConfigOnly) { args = ["-p", "tsconfig.json"]; diff --git a/src/testRunner/unittests/config/tsconfigParsing.ts b/src/testRunner/unittests/config/tsconfigParsing.ts index de793bffa4e05..1e8e3d33b4c61 100644 --- a/src/testRunner/unittests/config/tsconfigParsing.ts +++ b/src/testRunner/unittests/config/tsconfigParsing.ts @@ -1,47 +1,50 @@ namespace ts { describe("unittests:: config:: tsconfigParsing:: parseConfigFileTextToJson", () => { - function assertParseResult(jsonText: string, expectedConfigObject: { config?: any; error?: Diagnostic[] }) { - const parsed = parseConfigFileTextToJson("/apath/tsconfig.json", jsonText); + function assertParseResult(jsonText: string, expectedConfigObject: { + config?: any; + error?: ts.Diagnostic[]; + }) { + const parsed = ts.parseConfigFileTextToJson("/apath/tsconfig.json", jsonText); assert.equal(JSON.stringify(parsed), JSON.stringify(expectedConfigObject)); } function assertParseErrorWithExcludesKeyword(jsonText: string) { { - const parsed = parseConfigFileTextToJson("/apath/tsconfig.json", jsonText); - const parsedCommand = parseJsonConfigFileContent(parsed.config, sys, "tests/cases/unittests"); + const parsed = ts.parseConfigFileTextToJson("/apath/tsconfig.json", jsonText); + const parsedCommand = ts.parseJsonConfigFileContent(parsed.config, ts.sys, "tests/cases/unittests"); assert.isTrue(parsedCommand.errors && parsedCommand.errors.length === 1 && - parsedCommand.errors[0].code === Diagnostics.Unknown_option_excludes_Did_you_mean_exclude.code); + parsedCommand.errors[0].code === ts.Diagnostics.Unknown_option_excludes_Did_you_mean_exclude.code); } { - const parsed = parseJsonText("/apath/tsconfig.json", jsonText); - const parsedCommand = parseJsonSourceFileConfigFileContent(parsed, sys, "tests/cases/unittests"); + const parsed = ts.parseJsonText("/apath/tsconfig.json", jsonText); + const parsedCommand = ts.parseJsonSourceFileConfigFileContent(parsed, ts.sys, "tests/cases/unittests"); assert.isTrue(parsedCommand.errors && parsedCommand.errors.length === 1 && - parsedCommand.errors[0].code === Diagnostics.Unknown_option_excludes_Did_you_mean_exclude.code); + parsedCommand.errors[0].code === ts.Diagnostics.Unknown_option_excludes_Did_you_mean_exclude.code); } } function getParsedCommandJson(jsonText: string, configFileName: string, basePath: string, allFileList: string[]) { - const parsed = parseConfigFileTextToJson(configFileName, jsonText); + const parsed = ts.parseConfigFileTextToJson(configFileName, jsonText); const files = allFileList.reduce((files, value) => (files[value] = "", files), {} as vfs.FileSet); - const host: ParseConfigHost = new fakes.ParseConfigHost(new vfs.FileSystem(/*ignoreCase*/ false, { cwd: basePath, files: { "/": {}, ...files } })); - return parseJsonConfigFileContent(parsed.config, host, basePath, /*existingOptions*/ undefined, configFileName); + const host: ts.ParseConfigHost = new fakes.ParseConfigHost(new vfs.FileSystem(/*ignoreCase*/ false, { cwd: basePath, files: { "/": {}, ...files } })); + return ts.parseJsonConfigFileContent(parsed.config, host, basePath, /*existingOptions*/ undefined, configFileName); } function getParsedCommandJsonNode(jsonText: string, configFileName: string, basePath: string, allFileList: string[]) { - const parsed = parseJsonText(configFileName, jsonText); + const parsed = ts.parseJsonText(configFileName, jsonText); const files = allFileList.reduce((files, value) => (files[value] = "", files), {} as vfs.FileSet); - const host: ParseConfigHost = new fakes.ParseConfigHost(new vfs.FileSystem(/*ignoreCase*/ false, { cwd: basePath, files: { "/": {}, ...files } })); - return parseJsonSourceFileConfigFileContent(parsed, host, basePath, /*existingOptions*/ undefined, configFileName); + const host: ts.ParseConfigHost = new fakes.ParseConfigHost(new vfs.FileSystem(/*ignoreCase*/ false, { cwd: basePath, files: { "/": {}, ...files } })); + return ts.parseJsonSourceFileConfigFileContent(parsed, host, basePath, /*existingOptions*/ undefined, configFileName); } function assertParseFileList(jsonText: string, configFileName: string, basePath: string, allFileList: string[], expectedFileList: string[]) { { const parsed = getParsedCommandJson(jsonText, configFileName, basePath, allFileList); - assert.isTrue(arrayIsEqualTo(parsed.fileNames.sort(), expectedFileList.sort())); + assert.isTrue(ts.arrayIsEqualTo(parsed.fileNames.sort(), expectedFileList.sort())); } { const parsed = getParsedCommandJsonNode(jsonText, configFileName, basePath, allFileList); - assert.isTrue(arrayIsEqualTo(parsed.fileNames.sort(), expectedFileList.sort())); + assert.isTrue(ts.arrayIsEqualTo(parsed.fileNames.sort(), expectedFileList.sort())); } } @@ -89,16 +92,14 @@ namespace ts { }); it("returns config object without comments", () => { - assertParseResult( - `{ // Excluded files + assertParseResult(`{ // Excluded files "exclude": [ // Exclude d.ts "file.d.ts" ] }`, { config: { exclude: ["file.d.ts"] } }); - assertParseResult( - `{ + assertParseResult(`{ /* Excluded Files */ @@ -109,14 +110,12 @@ namespace ts { }); it("keeps string content untouched", () => { - assertParseResult( - `{ + assertParseResult(`{ "exclude": [ "xx//file.d.ts" ] }`, { config: { exclude: ["xx//file.d.ts"] } }); - assertParseResult( - `{ + assertParseResult(`{ "exclude": [ "xx/*file.d.ts*/" ] @@ -124,15 +123,13 @@ namespace ts { }); it("handles escaped characters in strings correctly", () => { - assertParseResult( - `{ + assertParseResult(`{ "exclude": [ "xx\\"//files" ] }`, { config: { exclude: ["xx\"//files"] } }); - assertParseResult( - `{ + assertParseResult(`{ "exclude": [ "xx\\\\" // end of line comment ] @@ -140,9 +137,9 @@ namespace ts { }); it("returns object with error when json is invalid", () => { - const parsed = parseConfigFileTextToJson("/apath/tsconfig.json", "invalid"); + const parsed = ts.parseConfigFileTextToJson("/apath/tsconfig.json", "invalid"); assert.deepEqual(parsed.config, {}); - const expected = createCompilerDiagnostic(Diagnostics._0_expected, "{"); + const expected = ts.createCompilerDiagnostic(ts.Diagnostics._0_expected, "{"); const error = parsed.error!; assert.equal(error.messageText, expected.messageText); assert.equal(error.category, expected.category); @@ -152,8 +149,7 @@ namespace ts { }); it("returns object when users correctly specify library", () => { - assertParseResult( - `{ + assertParseResult(`{ "compilerOptions": { "lib": ["es5"] } @@ -161,8 +157,7 @@ namespace ts { config: { compilerOptions: { lib: ["es5"] } } }); - assertParseResult( - `{ + assertParseResult(`{ "compilerOptions": { "lib": ["es5", "es6"] } @@ -172,8 +167,7 @@ namespace ts { }); it("returns error when tsconfig have excludes", () => { - assertParseErrorWithExcludesKeyword( - `{ + assertParseErrorWithExcludesKeyword(`{ "compilerOptions": { "lib": ["es5"] }, @@ -184,36 +178,22 @@ namespace ts { }); it("ignore dotted files and folders", () => { - assertParseFileList( - `{}`, - "tsconfig.json", - "/apath", - ["/apath/test.ts", "/apath/.git/a.ts", "/apath/.b.ts", "/apath/..c.ts"], - ["/apath/test.ts"] - ); + assertParseFileList(`{}`, "tsconfig.json", "/apath", ["/apath/test.ts", "/apath/.git/a.ts", "/apath/.b.ts", "/apath/..c.ts"], ["/apath/test.ts"]); }); it("allow dotted files and folders when explicitly requested", () => { - assertParseFileList( - `{ + assertParseFileList(`{ "files": ["/apath/.git/a.ts", "/apath/.b.ts", "/apath/..c.ts"] - }`, - "tsconfig.json", - "/apath", - ["/apath/test.ts", "/apath/.git/a.ts", "/apath/.b.ts", "/apath/..c.ts"], - ["/apath/.git/a.ts", "/apath/.b.ts", "/apath/..c.ts"] - ); + }`, "tsconfig.json", "/apath", ["/apath/test.ts", "/apath/.git/a.ts", "/apath/.b.ts", "/apath/..c.ts"], ["/apath/.git/a.ts", "/apath/.b.ts", "/apath/..c.ts"]); }); it("exclude outDir unless overridden", () => { - const tsconfigWithoutExclude = - `{ + const tsconfigWithoutExclude = `{ "compilerOptions": { "outDir": "bin" } }`; - const tsconfigWithExclude = - `{ + const tsconfigWithExclude = `{ "compilerOptions": { "outDir": "bin" }, @@ -227,14 +207,12 @@ namespace ts { }); it("exclude declarationDir unless overridden", () => { - const tsconfigWithoutExclude = - `{ + const tsconfigWithoutExclude = `{ "compilerOptions": { "declarationDir": "declarations" } }`; - const tsconfigWithExclude = - `{ + const tsconfigWithExclude = `{ "compilerOptions": { "declarationDir": "declarations" }, @@ -250,13 +228,7 @@ namespace ts { }); it("implicitly exclude common package folders", () => { - assertParseFileList( - `{}`, - "tsconfig.json", - "/", - ["/node_modules/a.ts", "/bower_components/b.ts", "/jspm_packages/c.ts", "/d.ts", "/folder/e.ts"], - ["/d.ts", "/folder/e.ts"] - ); + assertParseFileList(`{}`, "tsconfig.json", "/", ["/node_modules/a.ts", "/bower_components/b.ts", "/jspm_packages/c.ts", "/d.ts", "/folder/e.ts"], ["/d.ts", "/folder/e.ts"]); }); it("parse and re-emit tsconfig.json file with diagnostics", () => { @@ -268,9 +240,9 @@ namespace ts { } "files": ["file1.ts"] }`; - const result = parseJsonText("config.json", content); + const result = ts.parseJsonText("config.json", content); const diagnostics = result.parseDiagnostics; - const configJsonObject = convertToObject(result, diagnostics); + const configJsonObject = ts.convertToObject(result, diagnostics); const expectedResult = { compilerOptions: { allowJs: true, @@ -286,11 +258,7 @@ namespace ts { const content = `{ "files": [] }`; - assertParseFileDiagnostics(content, - "/apath/tsconfig.json", - "tests/cases/unittests", - ["/apath/a.ts"], - Diagnostics.The_files_list_in_config_file_0_is_empty.code); + assertParseFileDiagnostics(content, "/apath/tsconfig.json", "tests/cases/unittests", ["/apath/a.ts"], ts.Diagnostics.The_files_list_in_config_file_0_is_empty.code); }); it("generates errors for empty files list when no references are provided", () => { @@ -298,11 +266,7 @@ namespace ts { "files": [], "references": [] }`; - assertParseFileDiagnostics(content, - "/apath/tsconfig.json", - "tests/cases/unittests", - ["/apath/a.ts"], - Diagnostics.The_files_list_in_config_file_0_is_empty.code); + assertParseFileDiagnostics(content, "/apath/tsconfig.json", "tests/cases/unittests", ["/apath/a.ts"], ts.Diagnostics.The_files_list_in_config_file_0_is_empty.code); }); it("does not generate errors for empty files list when one or more references are provided", () => { @@ -310,21 +274,13 @@ namespace ts { "files": [], "references": [{ "path": "/apath" }] }`; - assertParseFileDiagnosticsExclusion(content, - "/apath/tsconfig.json", - "tests/cases/unittests", - ["/apath/a.ts"], - Diagnostics.The_files_list_in_config_file_0_is_empty.code); + assertParseFileDiagnosticsExclusion(content, "/apath/tsconfig.json", "tests/cases/unittests", ["/apath/a.ts"], ts.Diagnostics.The_files_list_in_config_file_0_is_empty.code); }); it("generates errors for directory with no .ts files", () => { const content = `{ }`; - assertParseFileDiagnostics(content, - "/apath/tsconfig.json", - "tests/cases/unittests", - ["/apath/a.js"], - Diagnostics.No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2.code, + assertParseFileDiagnostics(content, "/apath/tsconfig.json", "tests/cases/unittests", ["/apath/a.js"], ts.Diagnostics.No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2.code, /*noLocation*/ true); }); @@ -334,11 +290,7 @@ namespace ts { "allowJs": true } }`; - assertParseFileDiagnostics(content, - "/apath/tsconfig.json", - "tests/cases/unittests", - [], - Diagnostics.No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2.code, + assertParseFileDiagnostics(content, "/apath/tsconfig.json", "tests/cases/unittests", [], ts.Diagnostics.No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2.code, /*noLocation*/ true); }); @@ -346,11 +298,7 @@ namespace ts { const content = `{ "include": [] }`; - assertParseFileDiagnostics(content, - "/apath/tsconfig.json", - "tests/cases/unittests", - ["/apath/a.ts"], - Diagnostics.No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2.code, + assertParseFileDiagnostics(content, "/apath/tsconfig.json", "tests/cases/unittests", ["/apath/a.ts"], ts.Diagnostics.No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2.code, /*noLocation*/ true); }); @@ -361,11 +309,7 @@ namespace ts { }, "include": ["**/*"] }`; - assertParseFileDiagnostics(content, - "/apath/tsconfig.json", - "tests/cases/unittests", - ["/apath/a.ts"], - Diagnostics.No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2.code, + assertParseFileDiagnostics(content, "/apath/tsconfig.json", "tests/cases/unittests", ["/apath/a.ts"], ts.Diagnostics.No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2.code, /*noLocation*/ true); }); @@ -383,43 +327,33 @@ namespace ts { }); it("generates errors when files is not string", () => { - assertParseFileDiagnostics( - JSON.stringify({ + assertParseFileDiagnostics(JSON.stringify({ files: [{ compilerOptions: { experimentalDecorators: true, allowJs: true } }] - }), - "/apath/tsconfig.json", - "tests/cases/unittests", - ["/apath/a.ts"], - Diagnostics.Compiler_option_0_requires_a_value_of_type_1.code, + }), "/apath/tsconfig.json", "tests/cases/unittests", ["/apath/a.ts"], ts.Diagnostics.Compiler_option_0_requires_a_value_of_type_1.code, /*noLocation*/ true); }); it("generates errors when include is not string", () => { - assertParseFileDiagnostics( - JSON.stringify({ + assertParseFileDiagnostics(JSON.stringify({ include: [ ["./**/*.ts"] ] - }), - "/apath/tsconfig.json", - "tests/cases/unittests", - ["/apath/a.ts"], - Diagnostics.Compiler_option_0_requires_a_value_of_type_1.code, + }), "/apath/tsconfig.json", "tests/cases/unittests", ["/apath/a.ts"], ts.Diagnostics.Compiler_option_0_requires_a_value_of_type_1.code, /*noLocation*/ true); }); it("parses wildcard directories even when parent directories have dots", () => { - const parsed = parseConfigFileTextToJson("/foo.bar/tsconfig.json", JSON.stringify({ + const parsed = ts.parseConfigFileTextToJson("/foo.bar/tsconfig.json", JSON.stringify({ include: ["src"] })); - const parsedCommand = parseJsonConfigFileContent(parsed.config, sys, "/foo.bar"); - assert.deepEqual(parsedCommand.wildcardDirectories, { "/foo.bar/src": WatchDirectoryFlags.Recursive }); + const parsedCommand = ts.parseJsonConfigFileContent(parsed.config, ts.sys, "/foo.bar"); + assert.deepEqual(parsedCommand.wildcardDirectories, { "/foo.bar/src": ts.WatchDirectoryFlags.Recursive }); }); }); } diff --git a/src/testRunner/unittests/config/tsconfigParsingWatchOptions.ts b/src/testRunner/unittests/config/tsconfigParsingWatchOptions.ts index 120dd42d2c542..3fa639b6fca10 100644 --- a/src/testRunner/unittests/config/tsconfigParsingWatchOptions.ts +++ b/src/testRunner/unittests/config/tsconfigParsingWatchOptions.ts @@ -1,51 +1,34 @@ namespace ts { describe("unittests:: config:: tsconfigParsingWatchOptions:: parseConfigFileTextToJson", () => { function createParseConfigHost(additionalFiles?: vfs.FileSet) { - return new fakes.ParseConfigHost( - new vfs.FileSystem( - /*ignoreCase*/ false, - { + return new fakes.ParseConfigHost(new vfs.FileSystem( + /*ignoreCase*/ false, { cwd: "/", files: { "/": {}, "/a.ts": "", ...additionalFiles } + })); } - ) - ); - } - function getParsedCommandJson(json: object, additionalFiles?: vfs.FileSet, existingWatchOptions?: WatchOptions) { - return parseJsonConfigFileContent( - json, - createParseConfigHost(additionalFiles), - "/", - /*existingOptions*/ undefined, - "tsconfig.json", + function getParsedCommandJson(json: object, additionalFiles?: vfs.FileSet, existingWatchOptions?: ts.WatchOptions) { + return ts.parseJsonConfigFileContent(json, createParseConfigHost(additionalFiles), "/", + /*existingOptions*/ undefined, "tsconfig.json", /*resolutionStack*/ undefined, /*extraFileExtensions*/ undefined, - /*extendedConfigCache*/ undefined, - existingWatchOptions, - ); + /*extendedConfigCache*/ undefined, existingWatchOptions); } - - function getParsedCommandJsonNode(json: object, additionalFiles?: vfs.FileSet, existingWatchOptions?: WatchOptions) { - const parsed = parseJsonText("tsconfig.json", JSON.stringify(json)); - return parseJsonSourceFileConfigFileContent( - parsed, - createParseConfigHost(additionalFiles), - "/", - /*existingOptions*/ undefined, - "tsconfig.json", + function getParsedCommandJsonNode(json: object, additionalFiles?: vfs.FileSet, existingWatchOptions?: ts.WatchOptions) { + const parsed = ts.parseJsonText("tsconfig.json", JSON.stringify(json)); + return ts.parseJsonSourceFileConfigFileContent(parsed, createParseConfigHost(additionalFiles), "/", + /*existingOptions*/ undefined, "tsconfig.json", /*resolutionStack*/ undefined, /*extraFileExtensions*/ undefined, - /*extendedConfigCache*/ undefined, - existingWatchOptions, - ); + /*extendedConfigCache*/ undefined, existingWatchOptions); } interface VerifyWatchOptions { json: object; - expectedOptions: WatchOptions | undefined; + expectedOptions: ts.WatchOptions | undefined; additionalFiles?: vfs.FileSet; - existingWatchOptions?: WatchOptions | undefined; - expectedErrors?: (sourceFile?: SourceFile) => Diagnostic[]; + existingWatchOptions?: ts.WatchOptions | undefined; + expectedErrors?: (sourceFile?: ts.SourceFile) => ts.Diagnostic[]; } function verifyWatchOptions(scenario: () => VerifyWatchOptions[]) { @@ -53,11 +36,11 @@ namespace ts { for (const { json, expectedOptions, additionalFiles, existingWatchOptions, expectedErrors } of scenario()) { const parsed = getParsedCommandJson(json, additionalFiles, existingWatchOptions); assert.deepEqual(parsed.watchOptions, expectedOptions, `With ${JSON.stringify(json)}`); - if (length(parsed.errors)) { + if (ts.length(parsed.errors)) { assert.deepEqual(parsed.errors, expectedErrors?.()); } else { - assert.equal(0, length(expectedErrors?.()), `Expected no errors`); + assert.equal(0, ts.length(expectedErrors?.()), `Expected no errors`); } } }); @@ -66,11 +49,11 @@ namespace ts { for (const { json, expectedOptions, additionalFiles, existingWatchOptions, expectedErrors } of scenario()) { const parsed = getParsedCommandJsonNode(json, additionalFiles, existingWatchOptions); assert.deepEqual(parsed.watchOptions, expectedOptions); - if (length(parsed.errors)) { + if (ts.length(parsed.errors)) { assert.deepEqual(parsed.errors, expectedErrors?.(parsed.options.configFile)); } else { - assert.equal(0, length(expectedErrors?.(parsed.options.configFile)), `Expected no errors`); + assert.equal(0, ts.length(expectedErrors?.(parsed.options.configFile)), `Expected no errors`); } } }); @@ -98,7 +81,7 @@ namespace ts { extends: "./base.json", watchOptions: { watchFile: "UseFsEvents" } }, - expectedOptions: { watchFile: WatchFileKind.UseFsEvents }, + expectedOptions: { watchFile: ts.WatchFileKind.UseFsEvents }, additionalFiles: { "/base.json": "{}" } }, { @@ -119,8 +102,8 @@ namespace ts { } }, expectedOptions: { - watchFile: WatchFileKind.UseFsEvents, - watchDirectory: WatchDirectoryKind.FixedPollingInterval + watchFile: ts.WatchFileKind.UseFsEvents, + watchDirectory: ts.WatchDirectoryKind.FixedPollingInterval }, additionalFiles: { "/base.json": JSON.stringify({ @@ -136,8 +119,8 @@ namespace ts { extends: "./base.json", }, expectedOptions: { - watchFile: WatchFileKind.UseFsEventsOnParentDirectory, - watchDirectory: WatchDirectoryKind.FixedPollingInterval + watchFile: ts.WatchFileKind.UseFsEventsOnParentDirectory, + watchDirectory: ts.WatchDirectoryKind.FixedPollingInterval }, additionalFiles: { "/base.json": JSON.stringify({ @@ -156,15 +139,15 @@ namespace ts { verifyWatchOptions(() => [ { json: { watchOptions: { watchFile: "UseFsEvents" } }, - expectedOptions: { watchFile: WatchFileKind.UseFsEvents } + expectedOptions: { watchFile: ts.WatchFileKind.UseFsEvents } }, { json: { watchOptions: { watchDirectory: "UseFsEvents" } }, - expectedOptions: { watchDirectory: WatchDirectoryKind.UseFsEvents } + expectedOptions: { watchDirectory: ts.WatchDirectoryKind.UseFsEvents } }, { json: { watchOptions: { fallbackPolling: "DynamicPriority" } }, - expectedOptions: { fallbackPolling: PollingWatchKind.DynamicPriority } + expectedOptions: { fallbackPolling: ts.PollingWatchKind.DynamicPriority } }, { json: { watchOptions: { synchronousWatchDirectory: true } }, @@ -184,8 +167,8 @@ namespace ts { expectedErrors: sourceFile => [ { messageText: `File specification cannot contain a parent directory ('..') that appears after a recursive directory wildcard ('**'): '**/../*'.`, - category: Diagnostics.File_specification_cannot_contain_a_parent_directory_that_appears_after_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0.category, - code: Diagnostics.File_specification_cannot_contain_a_parent_directory_that_appears_after_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0.code, + category: ts.Diagnostics.File_specification_cannot_contain_a_parent_directory_that_appears_after_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0.category, + code: ts.Diagnostics.File_specification_cannot_contain_a_parent_directory_that_appears_after_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0.code, file: sourceFile, start: sourceFile && sourceFile.text.indexOf(`"**/../*"`), length: sourceFile && `"**/../*"`.length, @@ -200,8 +183,8 @@ namespace ts { expectedErrors: sourceFile => [ { messageText: `File specification cannot contain a parent directory ('..') that appears after a recursive directory wildcard ('**'): '**/../*'.`, - category: Diagnostics.File_specification_cannot_contain_a_parent_directory_that_appears_after_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0.category, - code: Diagnostics.File_specification_cannot_contain_a_parent_directory_that_appears_after_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0.code, + category: ts.Diagnostics.File_specification_cannot_contain_a_parent_directory_that_appears_after_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0.category, + code: ts.Diagnostics.File_specification_cannot_contain_a_parent_directory_that_appears_after_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0.code, file: sourceFile, start: sourceFile && sourceFile.text.indexOf(`"**/../*"`), length: sourceFile && `"**/../*"`.length, @@ -217,13 +200,13 @@ namespace ts { verifyWatchOptions(() => [ { json: { watchOptions: { watchFile: "UseFsEvents" } }, - expectedOptions: { watchFile: WatchFileKind.UseFsEvents, watchDirectory: WatchDirectoryKind.FixedPollingInterval }, - existingWatchOptions: { watchDirectory: WatchDirectoryKind.FixedPollingInterval } + expectedOptions: { watchFile: ts.WatchFileKind.UseFsEvents, watchDirectory: ts.WatchDirectoryKind.FixedPollingInterval }, + existingWatchOptions: { watchDirectory: ts.WatchDirectoryKind.FixedPollingInterval } }, { json: {}, - expectedOptions: { watchDirectory: WatchDirectoryKind.FixedPollingInterval }, - existingWatchOptions: { watchDirectory: WatchDirectoryKind.FixedPollingInterval } + expectedOptions: { watchDirectory: ts.WatchDirectoryKind.FixedPollingInterval }, + existingWatchOptions: { watchDirectory: ts.WatchDirectoryKind.FixedPollingInterval } }, ]); }); diff --git a/src/testRunner/unittests/convertToBase64.ts b/src/testRunner/unittests/convertToBase64.ts index 37e38da8da7dc..dcc4c056df855 100644 --- a/src/testRunner/unittests/convertToBase64.ts +++ b/src/testRunner/unittests/convertToBase64.ts @@ -1,8 +1,8 @@ namespace ts { describe("unittests:: convertToBase64", () => { function runTest(input: string): void { - const actual = convertToBase64(input); - const expected = sys.base64encode!(input); + const actual = ts.convertToBase64(input); + const expected = ts.sys.base64encode!(input); assert.equal(actual, expected, "Encoded string using convertToBase64 does not match buffer.toString('base64')"); } diff --git a/src/testRunner/unittests/createMapShim.ts b/src/testRunner/unittests/createMapShim.ts index e76718e1f244b..b4bed7270bc19 100644 --- a/src/testRunner/unittests/createMapShim.ts +++ b/src/testRunner/unittests/createMapShim.ts @@ -24,7 +24,7 @@ namespace ts { { toString() { return "2"; } }, "4", false, - null, // eslint-disable-line no-null/no-null + null, undefined, "B", { toString() { return "C"; } }, @@ -35,7 +35,7 @@ namespace ts { "Y" ]; - function testMapIterationAddedValues(keys: K[], map: ESMap, useForEach: boolean): string { + function testMapIterationAddedValues(keys: K[], map: ts.ESMap, useForEach: boolean): string { let resultString = ""; map.set(keys[0], "1"); @@ -115,21 +115,20 @@ namespace ts { return resultString; } - let MapShim!: MapConstructor; + let MapShim!: ts.MapConstructor; beforeEach(() => { - function getIterator | ReadonlyESMap | undefined>(iterable: I): Iterator< - I extends ReadonlyESMap ? [K, V] : - I extends ReadonlySet ? T : - I extends readonly (infer T)[] ? T : - I extends undefined ? undefined : - never>; - function getIterator(iterable: readonly any[] | ReadonlySet | ReadonlyESMap | undefined): Iterator | undefined { + function getIterator | ts.ReadonlyESMap | undefined>(iterable: I): ts.Iterator ? [ + K, + V + ] : I extends ts.ReadonlySet ? T : I extends readonly (infer T)[] ? T : I extends undefined ? undefined : never>; + function getIterator(iterable: readonly any[] | ts.ReadonlySet | ts.ReadonlyESMap | undefined): ts.Iterator | undefined { // override `ts.getIterator` with a version that allows us to iterate over a `MapShim` in an environment with a native `Map`. - if (iterable instanceof MapShim) return iterable.entries(); + if (iterable instanceof MapShim) + return iterable.entries(); return ts.getIterator(iterable); } - MapShim = ShimCollections.createMapShim(getIterator); + MapShim = ts.ShimCollections.createMapShim(getIterator); }); afterEach(() => { MapShim = undefined!; @@ -139,11 +138,11 @@ namespace ts { const expectedResult = "1:1;3:3;2:Y2;4:X4;0:X0;3:Y3;999:999;A:A;Z:Z;X:X;Y:Y;"; // First, ensure the test actually has the same behavior as a native Map. - let nativeMap = new Map(); + let nativeMap = new ts.Map(); const nativeMapForEachResult = testMapIterationAddedValues(stringKeys, nativeMap, /* useForEach */ true); assert.equal(nativeMapForEachResult, expectedResult, "nativeMap-forEach"); - nativeMap = new Map(); + nativeMap = new ts.Map(); const nativeMapIteratorResult = testMapIterationAddedValues(stringKeys, nativeMap, /* useForEach */ false); assert.equal(nativeMapIteratorResult, expectedResult, "nativeMap-iterator"); @@ -161,11 +160,11 @@ namespace ts { const expectedResult = "true:1;3:3;2:Y2;4:X4;false:X0;3:Y3;null:999;undefined:A;Z:Z;X:X;Y:Y;"; // First, ensure the test actually has the same behavior as a native Map. - let nativeMap = new Map(); + let nativeMap = new ts.Map(); const nativeMapForEachResult = testMapIterationAddedValues(mixedKeys, nativeMap, /* useForEach */ true); assert.equal(nativeMapForEachResult, expectedResult, "nativeMap-forEach"); - nativeMap = new Map(); + nativeMap = new ts.Map(); const nativeMapIteratorResult = testMapIterationAddedValues(mixedKeys, nativeMap, /* useForEach */ false); assert.equal(nativeMapIteratorResult, expectedResult, "nativeMap-iterator"); @@ -258,7 +257,7 @@ namespace ts { const map = new MapShim(); map.set("a", "b"); map.delete("a"); - const actual = arrayFrom(map.keys()); + const actual = ts.arrayFrom(map.keys()); assert.deepEqual(actual, []); }); @@ -267,9 +266,9 @@ namespace ts { map.set("a", "b"); map.set("c", "d"); map.delete("a"); - assert.deepEqual(arrayFrom(map.keys()), ["c"]); - assert.deepEqual(arrayFrom(map.values()), ["d"]); - assert.deepEqual(arrayFrom(map.entries()), [["c", "d"]]); + assert.deepEqual(ts.arrayFrom(map.keys()), ["c"]); + assert.deepEqual(ts.arrayFrom(map.values()), ["d"]); + assert.deepEqual(ts.arrayFrom(map.entries()), [["c", "d"]]); }); it("remove last item and iterate", () => { @@ -277,9 +276,9 @@ namespace ts { map.set("a", "b"); map.set("c", "d"); map.delete("c"); - assert.deepEqual(arrayFrom(map.keys()), ["a"]); - assert.deepEqual(arrayFrom(map.values()), ["b"]); - assert.deepEqual(arrayFrom(map.entries()), [["a", "b"]]); + assert.deepEqual(ts.arrayFrom(map.keys()), ["a"]); + assert.deepEqual(ts.arrayFrom(map.values()), ["b"]); + assert.deepEqual(ts.arrayFrom(map.entries()), [["a", "b"]]); }); it("remove middle item and iterate", () => { @@ -288,37 +287,40 @@ namespace ts { map.set("c", "d"); map.set("e", "f"); map.delete("c"); - assert.deepEqual(arrayFrom(map.keys()), ["a", "e"]); - assert.deepEqual(arrayFrom(map.values()), ["b", "f"]); - assert.deepEqual(arrayFrom(map.entries()), [["a", "b"], ["e", "f"]]); + assert.deepEqual(ts.arrayFrom(map.keys()), ["a", "e"]); + assert.deepEqual(ts.arrayFrom(map.values()), ["b", "f"]); + assert.deepEqual(ts.arrayFrom(map.entries()), [["a", "b"], ["e", "f"]]); }); it("keys", () => { const map = new MapShim(); map.set("c", "d"); map.set("a", "b"); - assert.deepEqual(arrayFrom(map.keys()), ["c", "a"]); + assert.deepEqual(ts.arrayFrom(map.keys()), ["c", "a"]); }); it("values", () => { const map = new MapShim(); map.set("c", "d"); map.set("a", "b"); - assert.deepEqual(arrayFrom(map.values()), ["d", "b"]); + assert.deepEqual(ts.arrayFrom(map.values()), ["d", "b"]); }); it("entries", () => { const map = new MapShim(); map.set("c", "d"); map.set("a", "b"); - assert.deepEqual(arrayFrom(map.entries()), [["c", "d"], ["a", "b"]]); + assert.deepEqual(ts.arrayFrom(map.entries()), [["c", "d"], ["a", "b"]]); }); it("forEach", () => { const map = new MapShim(); map.set("c", "d"); map.set("a", "b"); - const actual: [string, string][] = []; + const actual: [ + string, + string + ][] = []; map.forEach((value, key) => actual.push([key, value])); assert.deepEqual(actual, [["c", "d"], ["a", "b"]]); }); diff --git a/src/testRunner/unittests/createSetShim.ts b/src/testRunner/unittests/createSetShim.ts index bef82d78e2b61..6b6b6f79ca524 100644 --- a/src/testRunner/unittests/createSetShim.ts +++ b/src/testRunner/unittests/createSetShim.ts @@ -23,7 +23,7 @@ namespace ts { { toString() { return "2"; } }, "4", false, - null, // eslint-disable-line no-null/no-null + null, undefined, "B", { toString() { return "C"; } }, @@ -34,7 +34,7 @@ namespace ts { "Y" ]; - function testSetIterationAddedValues(keys: K[], set: Set, useForEach: boolean): string { + function testSetIterationAddedValues(keys: K[], set: ts.Set, useForEach: boolean): string { let resultString = ""; set.add(keys[0]); @@ -113,21 +113,20 @@ namespace ts { return resultString; } - let SetShim!: SetConstructor; + let SetShim!: ts.SetConstructor; beforeEach(() => { - function getIterator | ReadonlyESMap | undefined>(iterable: I): Iterator< - I extends ReadonlyESMap ? [K, V] : - I extends ReadonlySet ? T : - I extends readonly (infer T)[] ? T : - I extends undefined ? undefined : - never>; - function getIterator(iterable: readonly any[] | ReadonlySet | ReadonlyESMap | undefined): Iterator | undefined { + function getIterator | ts.ReadonlyESMap | undefined>(iterable: I): ts.Iterator ? [ + K, + V + ] : I extends ts.ReadonlySet ? T : I extends readonly (infer T)[] ? T : I extends undefined ? undefined : never>; + function getIterator(iterable: readonly any[] | ts.ReadonlySet | ts.ReadonlyESMap | undefined): ts.Iterator | undefined { // override `ts.getIterator` with a version that allows us to iterate over a `SetShim` in an environment with a native `Set`. - if (iterable instanceof SetShim) return iterable.values(); + if (iterable instanceof SetShim) + return iterable.values(); return ts.getIterator(iterable); } - SetShim = ShimCollections.createSetShim(getIterator); + SetShim = ts.ShimCollections.createSetShim(getIterator); }); afterEach(() => { SetShim = undefined!; @@ -137,11 +136,11 @@ namespace ts { const expectedResult = "1;3;2;4;0;3;999;A;Z;X;Y;"; // First, ensure the test actually has the same behavior as a native Set. - let nativeSet = new Set(); + let nativeSet = new ts.Set(); const nativeSetForEachResult = testSetIterationAddedValues(stringKeys, nativeSet, /* useForEach */ true); assert.equal(nativeSetForEachResult, expectedResult, "nativeSet-forEach"); - nativeSet = new Set(); + nativeSet = new ts.Set(); const nativeSetIteratorResult = testSetIterationAddedValues(stringKeys, nativeSet, /* useForEach */ false); assert.equal(nativeSetIteratorResult, expectedResult, "nativeSet-iterator"); @@ -159,11 +158,11 @@ namespace ts { const expectedResult = "true;3;2;4;false;3;null;undefined;Z;X;Y;"; // First, ensure the test actually has the same behavior as a native Set. - let nativeSet = new Set(); + let nativeSet = new ts.Set(); const nativeSetForEachResult = testSetIterationAddedValues(mixedKeys, nativeSet, /* useForEach */ true); assert.equal(nativeSetForEachResult, expectedResult, "nativeSet-forEach"); - nativeSet = new Set(); + nativeSet = new ts.Set(); const nativeSetIteratorResult = testSetIterationAddedValues(mixedKeys, nativeSet, /* useForEach */ false); assert.equal(nativeSetIteratorResult, expectedResult, "nativeSet-iterator"); @@ -241,7 +240,7 @@ namespace ts { const set = new SetShim(); set.add("a"); set.delete("a"); - const actual = arrayFrom(set.keys()); + const actual = ts.arrayFrom(set.keys()); assert.deepEqual(actual, []); }); @@ -250,9 +249,9 @@ namespace ts { set.add("a"); set.add("c"); set.delete("a"); - assert.deepEqual(arrayFrom(set.keys()), ["c"]); - assert.deepEqual(arrayFrom(set.values()), ["c"]); - assert.deepEqual(arrayFrom(set.entries()), [["c", "c"]]); + assert.deepEqual(ts.arrayFrom(set.keys()), ["c"]); + assert.deepEqual(ts.arrayFrom(set.values()), ["c"]); + assert.deepEqual(ts.arrayFrom(set.entries()), [["c", "c"]]); }); it("remove last item and iterate", () => { @@ -260,9 +259,9 @@ namespace ts { set.add("a"); set.add("c"); set.delete("c"); - assert.deepEqual(arrayFrom(set.keys()), ["a"]); - assert.deepEqual(arrayFrom(set.values()), ["a"]); - assert.deepEqual(arrayFrom(set.entries()), [["a", "a"]]); + assert.deepEqual(ts.arrayFrom(set.keys()), ["a"]); + assert.deepEqual(ts.arrayFrom(set.values()), ["a"]); + assert.deepEqual(ts.arrayFrom(set.entries()), [["a", "a"]]); }); it("remove middle item and iterate", () => { @@ -271,37 +270,40 @@ namespace ts { set.add("c"); set.add("e"); set.delete("c"); - assert.deepEqual(arrayFrom(set.keys()), ["a", "e"]); - assert.deepEqual(arrayFrom(set.values()), ["a", "e"]); - assert.deepEqual(arrayFrom(set.entries()), [["a", "a"], ["e", "e"]]); + assert.deepEqual(ts.arrayFrom(set.keys()), ["a", "e"]); + assert.deepEqual(ts.arrayFrom(set.values()), ["a", "e"]); + assert.deepEqual(ts.arrayFrom(set.entries()), [["a", "a"], ["e", "e"]]); }); it("keys", () => { const set = new SetShim(); set.add("c"); set.add("a"); - assert.deepEqual(arrayFrom(set.keys()), ["c", "a"]); + assert.deepEqual(ts.arrayFrom(set.keys()), ["c", "a"]); }); it("values", () => { const set = new SetShim(); set.add("c"); set.add("a"); - assert.deepEqual(arrayFrom(set.values()), ["c", "a"]); + assert.deepEqual(ts.arrayFrom(set.values()), ["c", "a"]); }); it("entries", () => { const set = new SetShim(); set.add("c"); set.add("a"); - assert.deepEqual(arrayFrom(set.entries()), [["c", "c"], ["a", "a"]]); + assert.deepEqual(ts.arrayFrom(set.entries()), [["c", "c"], ["a", "a"]]); }); it("forEach", () => { const set = new SetShim(); set.add("c"); set.add("a"); - const actual: [string, string][] = []; + const actual: [ + string, + string + ][] = []; set.forEach((value, key) => actual.push([key, value])); assert.deepEqual(actual, [["c", "c"], ["a", "a"]]); }); diff --git a/src/testRunner/unittests/customTransforms.ts b/src/testRunner/unittests/customTransforms.ts index 0f65aba6e3408..88701ef078855 100644 --- a/src/testRunner/unittests/customTransforms.ts +++ b/src/testRunner/unittests/customTransforms.ts @@ -1,11 +1,14 @@ namespace ts { describe("unittests:: customTransforms", () => { - function emitsCorrectly(name: string, sources: { file: string, text: string }[], customTransformers: CustomTransformers, options: CompilerOptions = {}) { + function emitsCorrectly(name: string, sources: { + file: string; + text: string; + }[], customTransformers: ts.CustomTransformers, options: ts.CompilerOptions = {}) { it(name, () => { - const roots = sources.map(source => createSourceFile(source.file, source.text, ScriptTarget.ES2015)); - const fileMap = arrayToMap(roots, file => file.fileName); - const outputs = new Map(); - const host: CompilerHost = { + const roots = sources.map(source => ts.createSourceFile(source.file, source.text, ts.ScriptTarget.ES2015)); + const fileMap = ts.arrayToMap(roots, file => file.fileName); + const outputs = new ts.Map(); + const host: ts.CompilerHost = { getSourceFile: (fileName) => fileMap.get(fileName), getDefaultLibFileName: () => "lib.d.ts", getCurrentDirectory: () => "", @@ -18,11 +21,12 @@ namespace ts { writeFile: (fileName, text) => outputs.set(fileName, text), }; - const program = createProgram(arrayFrom(fileMap.keys()), { newLine: NewLineKind.LineFeed, ...options }, host); + const program = ts.createProgram(ts.arrayFrom(fileMap.keys()), { newLine: ts.NewLineKind.LineFeed, ...options }, host); program.emit(/*targetSourceFile*/ undefined, host.writeFile, /*cancellationToken*/ undefined, /*emitOnlyDtsFiles*/ false, customTransformers); let content = ""; - for (const [file, text] of arrayFrom(outputs.entries())) { - if (content) content += "\n\n"; + for (const [file, text] of ts.arrayFrom(outputs.entries())) { + if (content) + content += "\n\n"; content += `// [${file}]\n`; content += text; } @@ -41,34 +45,34 @@ namespace ts { ` }]; - const before: TransformerFactory = context => { - return file => visitEachChild(file, visit, context); - function visit(node: Node): VisitResult { + const before: ts.TransformerFactory = context => { + return file => ts.visitEachChild(file, visit, context); + function visit(node: ts.Node): ts.VisitResult { switch (node.kind) { - case SyntaxKind.FunctionDeclaration: - return visitFunction(node as FunctionDeclaration); + case ts.SyntaxKind.FunctionDeclaration: + return visitFunction(node as ts.FunctionDeclaration); default: - return visitEachChild(node, visit, context); + return ts.visitEachChild(node, visit, context); } } - function visitFunction(node: FunctionDeclaration) { - addSyntheticLeadingComment(node, SyntaxKind.MultiLineCommentTrivia, "@before", /*hasTrailingNewLine*/ true); + function visitFunction(node: ts.FunctionDeclaration) { + ts.addSyntheticLeadingComment(node, ts.SyntaxKind.MultiLineCommentTrivia, "@before", /*hasTrailingNewLine*/ true); return node; } }; - const after: TransformerFactory = context => { - return file => visitEachChild(file, visit, context); - function visit(node: Node): VisitResult { + const after: ts.TransformerFactory = context => { + return file => ts.visitEachChild(file, visit, context); + function visit(node: ts.Node): ts.VisitResult { switch (node.kind) { - case SyntaxKind.VariableStatement: - return visitVariableStatement(node as VariableStatement); + case ts.SyntaxKind.VariableStatement: + return visitVariableStatement(node as ts.VariableStatement); default: - return visitEachChild(node, visit, context); + return ts.visitEachChild(node, visit, context); } } - function visitVariableStatement(node: VariableStatement) { - addSyntheticLeadingComment(node, SyntaxKind.SingleLineCommentTrivia, "@after"); + function visitVariableStatement(node: ts.VariableStatement) { + ts.addSyntheticLeadingComment(node, ts.SyntaxKind.SingleLineCommentTrivia, "@after"); return node; } }; @@ -86,19 +90,19 @@ namespace ts { 'change' ` }], {before: [ - context => node => visitNode(node, function visitor(node: Node): Node { - if (isStringLiteral(node) && node.text === "change") return factory.createStringLiteral("changed"); - return visitEachChild(node, visitor, context); + context => node => ts.visitNode(node, function visitor(node: ts.Node): ts.Node { + if (ts.isStringLiteral(node) && node.text === "change") + return ts.factory.createStringLiteral("changed"); + return ts.visitEachChild(node, visitor, context); }) ]}, { - target: ScriptTarget.ES5, - module: ModuleKind.ES2015, + target: ts.ScriptTarget.ES5, + module: ts.ModuleKind.ES2015, emitDecoratorMetadata: true, experimentalDecorators: true }); - emitsCorrectly("sourceMapExternalSourceFiles", - [ + emitsCorrectly("sourceMapExternalSourceFiles", [ { file: "source.ts", // The text of length 'changed' is made to be on two lines so we know the line map change @@ -106,63 +110,55 @@ namespace ts { line\` 'change'` }, - ], - { + ], { before: [ - context => node => visitNode(node, function visitor(node: Node): Node { - if (isStringLiteral(node) && node.text === "change") { + context => node => ts.visitNode(node, function visitor(node: ts.Node): ts.Node { + if (ts.isStringLiteral(node) && node.text === "change") { const text = "'changed'"; - const lineMap = computeLineStarts(text); - setSourceMapRange(node, { + const lineMap = ts.computeLineStarts(text); + ts.setSourceMapRange(node, { pos: 0, end: text.length, source: { text, fileName: "another.html", lineMap, - getLineAndCharacterOfPosition: pos => computeLineAndCharacterOfPosition(lineMap, pos) + getLineAndCharacterOfPosition: pos => ts.computeLineAndCharacterOfPosition(lineMap, pos) } }); return node; } - return visitEachChild(node, visitor, context); + return ts.visitEachChild(node, visitor, context); }) ] - }, - { sourceMap: true } - ); - - emitsCorrectly("skipTriviaExternalSourceFiles", - [ + }, { sourceMap: true }); + emitsCorrectly("skipTriviaExternalSourceFiles", [ { file: "source.ts", // The source file contains preceding trivia (e.g. whitespace) to try to confuse the `skipSourceTrivia` function. text: " original;" }, - ], - { + ], { before: [ context => { - const transformSourceFile: Transformer = node => visitNode(node, function visitor(node: Node): Node { - if (isIdentifier(node) && node.text === "original") { - const newNode = factory.createIdentifier("changed"); - setSourceMapRange(newNode, { + const transformSourceFile: ts.Transformer = node => ts.visitNode(node, function visitor(node: ts.Node): ts.Node { + if (ts.isIdentifier(node) && node.text === "original") { + const newNode = ts.factory.createIdentifier("changed"); + ts.setSourceMapRange(newNode, { pos: 0, end: 7, // Do not provide a custom skipTrivia function for `source`. - source: createSourceMapSource("another.html", "changed;") + source: ts.createSourceMapSource("another.html", "changed;") }); return newNode; } - return visitEachChild(node, visitor, context); + return ts.visitEachChild(node, visitor, context); }); return { transformSourceFile, - transformBundle: node => factory.createBundle(map(node.sourceFiles, transformSourceFile), node.prepends), + transformBundle: node => ts.factory.createBundle(ts.map(node.sourceFiles, transformSourceFile), node.prepends), }; } ] - }, - { sourceMap: true, outFile: "source.js" } - ); + }, { sourceMap: true, outFile: "source.js" }); }); } diff --git a/src/testRunner/unittests/debugDeprecation.ts b/src/testRunner/unittests/debugDeprecation.ts index 1687f24d40644..80b0b732b5423 100644 --- a/src/testRunner/unittests/debugDeprecation.ts +++ b/src/testRunner/unittests/debugDeprecation.ts @@ -1,21 +1,21 @@ namespace ts { describe("unittests:: debugDeprecation", () => { - let loggingHost: LoggingHost | undefined; + let loggingHost: ts.LoggingHost | undefined; beforeEach(() => { - loggingHost = Debug.loggingHost; + loggingHost = ts.Debug.loggingHost; }); afterEach(() => { - Debug.loggingHost = loggingHost; + ts.Debug.loggingHost = loggingHost; loggingHost = undefined; }); describe("deprecateFunction", () => { it("silent deprecation", () => { - const deprecation = Debug.deprecate(noop, { + const deprecation = ts.Debug.deprecate(ts.noop, { warnAfter: "3.9", typeScriptVersion: "3.8" }); let logWritten = false; - Debug.loggingHost = { + ts.Debug.loggingHost = { log() { logWritten = true; } @@ -24,12 +24,12 @@ namespace ts { assert.isFalse(logWritten); }); it("warning deprecation with warnAfter", () => { - const deprecation = Debug.deprecate(noop, { + const deprecation = ts.Debug.deprecate(ts.noop, { warnAfter: "3.9", typeScriptVersion: "3.9" }); let logWritten = false; - Debug.loggingHost = { + ts.Debug.loggingHost = { log() { logWritten = true; } @@ -38,11 +38,11 @@ namespace ts { assert.isTrue(logWritten); }); it("warning deprecation without warnAfter", () => { - const deprecation = Debug.deprecate(noop, { + const deprecation = ts.Debug.deprecate(ts.noop, { typeScriptVersion: "3.9" }); let logWritten = false; - Debug.loggingHost = { + ts.Debug.loggingHost = { log() { logWritten = true; } @@ -51,11 +51,11 @@ namespace ts { assert.isTrue(logWritten); }); it("warning deprecation writes once", () => { - const deprecation = Debug.deprecate(noop, { + const deprecation = ts.Debug.deprecate(ts.noop, { typeScriptVersion: "3.9" }); let logWrites = 0; - Debug.loggingHost = { + ts.Debug.loggingHost = { log() { logWrites++; } @@ -65,13 +65,13 @@ namespace ts { assert.equal(logWrites, 1); }); it("error deprecation with errorAfter", () => { - const deprecation = Debug.deprecate(noop, { + const deprecation = ts.Debug.deprecate(ts.noop, { warnAfter: "3.8", errorAfter: "3.9", typeScriptVersion: "3.9" }); let logWritten = false; - Debug.loggingHost = { + ts.Debug.loggingHost = { log() { logWritten = true; } @@ -80,11 +80,11 @@ namespace ts { assert.isFalse(logWritten); }); it("error deprecation with error", () => { - const deprecation = Debug.deprecate(noop, { + const deprecation = ts.Debug.deprecate(ts.noop, { error: true, }); let logWritten = false; - Debug.loggingHost = { + ts.Debug.loggingHost = { log() { logWritten = true; } diff --git a/src/testRunner/unittests/factory.ts b/src/testRunner/unittests/factory.ts index a413881c07d3e..f942c09e231e5 100644 --- a/src/testRunner/unittests/factory.ts +++ b/src/testRunner/unittests/factory.ts @@ -1,85 +1,75 @@ namespace ts { describe("unittests:: FactoryAPI", () => { - function assertSyntaxKind(node: Node, expected: SyntaxKind) { - assert.strictEqual(node.kind, expected, `Actual: ${Debug.formatSyntaxKind(node.kind)} Expected: ${Debug.formatSyntaxKind(expected)}`); + function assertSyntaxKind(node: ts.Node, expected: ts.SyntaxKind) { + assert.strictEqual(node.kind, expected, `Actual: ${ts.Debug.formatSyntaxKind(node.kind)} Expected: ${ts.Debug.formatSyntaxKind(expected)}`); } describe("factory.createExportAssignment", () => { it("parenthesizes default export if necessary", () => { - function checkExpression(expression: Expression) { - const node = factory.createExportAssignment( + function checkExpression(expression: ts.Expression) { + const node = ts.factory.createExportAssignment( /*decorators*/ undefined, /*modifiers*/ undefined, - /*isExportEquals*/ false, - expression, - ); - assertSyntaxKind(node.expression, SyntaxKind.ParenthesizedExpression); + /*isExportEquals*/ false, expression); + assertSyntaxKind(node.expression, ts.SyntaxKind.ParenthesizedExpression); } - const clazz = factory.createClassExpression(/*decorators*/ undefined, /*modifiers*/ undefined, "C", /*typeParameters*/ undefined, /*heritageClauses*/ undefined, [ - factory.createPropertyDeclaration(/*decorators*/ undefined, [factory.createToken(SyntaxKind.StaticKeyword)], "prop", /*questionOrExclamationToken*/ undefined, /*type*/ undefined, factory.createStringLiteral("1")), + const clazz = ts.factory.createClassExpression(/*decorators*/ undefined, /*modifiers*/ undefined, "C", /*typeParameters*/ undefined, /*heritageClauses*/ undefined, [ + ts.factory.createPropertyDeclaration(/*decorators*/ undefined, [ts.factory.createToken(ts.SyntaxKind.StaticKeyword)], "prop", /*questionOrExclamationToken*/ undefined, /*type*/ undefined, ts.factory.createStringLiteral("1")), ]); checkExpression(clazz); - checkExpression(factory.createPropertyAccessExpression(clazz, "prop")); - - const func = factory.createFunctionExpression(/*modifiers*/ undefined, /*asteriskToken*/ undefined, "fn", /*typeParameters*/ undefined, /*parameters*/ undefined, /*type*/ undefined, factory.createBlock([])); + checkExpression(ts.factory.createPropertyAccessExpression(clazz, "prop")); + const func = ts.factory.createFunctionExpression(/*modifiers*/ undefined, /*asteriskToken*/ undefined, "fn", /*typeParameters*/ undefined, /*parameters*/ undefined, /*type*/ undefined, ts.factory.createBlock([])); checkExpression(func); - checkExpression(factory.createCallExpression(func, /*typeArguments*/ undefined, /*argumentsArray*/ undefined)); - checkExpression(factory.createTaggedTemplateExpression(func, /*typeArguments*/ undefined, factory.createNoSubstitutionTemplateLiteral(""))); - - checkExpression(factory.createBinaryExpression(factory.createStringLiteral("a"), SyntaxKind.CommaToken, factory.createStringLiteral("b"))); - checkExpression(factory.createCommaListExpression([factory.createStringLiteral("a"), factory.createStringLiteral("b")])); + checkExpression(ts.factory.createCallExpression(func, /*typeArguments*/ undefined, /*argumentsArray*/ undefined)); + checkExpression(ts.factory.createTaggedTemplateExpression(func, /*typeArguments*/ undefined, ts.factory.createNoSubstitutionTemplateLiteral(""))); + checkExpression(ts.factory.createBinaryExpression(ts.factory.createStringLiteral("a"), ts.SyntaxKind.CommaToken, ts.factory.createStringLiteral("b"))); + checkExpression(ts.factory.createCommaListExpression([ts.factory.createStringLiteral("a"), ts.factory.createStringLiteral("b")])); }); }); describe("factory.createArrowFunction", () => { it("parenthesizes concise body if necessary", () => { - function checkBody(body: ConciseBody) { - const node = factory.createArrowFunction( + function checkBody(body: ts.ConciseBody) { + const node = ts.factory.createArrowFunction( /*modifiers*/ undefined, - /*typeParameters*/ undefined, - [], + /*typeParameters*/ undefined, [], /*type*/ undefined, - /*equalsGreaterThanToken*/ undefined, - body, - ); - assertSyntaxKind(node.body, SyntaxKind.ParenthesizedExpression); + /*equalsGreaterThanToken*/ undefined, body); + assertSyntaxKind(node.body, ts.SyntaxKind.ParenthesizedExpression); } - checkBody(factory.createObjectLiteralExpression()); - checkBody(factory.createPropertyAccessExpression(factory.createObjectLiteralExpression(), "prop")); - checkBody(factory.createAsExpression(factory.createPropertyAccessExpression(factory.createObjectLiteralExpression(), "prop"), factory.createTypeReferenceNode("T", /*typeArguments*/ undefined))); - checkBody(factory.createNonNullExpression(factory.createPropertyAccessExpression(factory.createObjectLiteralExpression(), "prop"))); - checkBody(factory.createCommaListExpression([factory.createStringLiteral("a"), factory.createStringLiteral("b")])); - checkBody(factory.createBinaryExpression(factory.createStringLiteral("a"), SyntaxKind.CommaToken, factory.createStringLiteral("b"))); + checkBody(ts.factory.createObjectLiteralExpression()); + checkBody(ts.factory.createPropertyAccessExpression(ts.factory.createObjectLiteralExpression(), "prop")); + checkBody(ts.factory.createAsExpression(ts.factory.createPropertyAccessExpression(ts.factory.createObjectLiteralExpression(), "prop"), ts.factory.createTypeReferenceNode("T", /*typeArguments*/ undefined))); + checkBody(ts.factory.createNonNullExpression(ts.factory.createPropertyAccessExpression(ts.factory.createObjectLiteralExpression(), "prop"))); + checkBody(ts.factory.createCommaListExpression([ts.factory.createStringLiteral("a"), ts.factory.createStringLiteral("b")])); + checkBody(ts.factory.createBinaryExpression(ts.factory.createStringLiteral("a"), ts.SyntaxKind.CommaToken, ts.factory.createStringLiteral("b"))); }); }); describe("createBinaryExpression", () => { it("parenthesizes arrow function in RHS if necessary", () => { - const lhs = factory.createIdentifier("foo"); - const rhs = factory.createArrowFunction( + const lhs = ts.factory.createIdentifier("foo"); + const rhs = ts.factory.createArrowFunction( /*modifiers*/ undefined, - /*typeParameters*/ undefined, - [], + /*typeParameters*/ undefined, [], /*type*/ undefined, - /*equalsGreaterThanToken*/ undefined, - factory.createBlock([]), - ); - function checkRhs(operator: BinaryOperator, expectParens: boolean) { - const node = factory.createBinaryExpression(lhs, operator, rhs); - assertSyntaxKind(node.right, expectParens ? SyntaxKind.ParenthesizedExpression : SyntaxKind.ArrowFunction); + /*equalsGreaterThanToken*/ undefined, ts.factory.createBlock([])); + function checkRhs(operator: ts.BinaryOperator, expectParens: boolean) { + const node = ts.factory.createBinaryExpression(lhs, operator, rhs); + assertSyntaxKind(node.right, expectParens ? ts.SyntaxKind.ParenthesizedExpression : ts.SyntaxKind.ArrowFunction); } - checkRhs(SyntaxKind.CommaToken, /*expectParens*/ false); - checkRhs(SyntaxKind.EqualsToken, /*expectParens*/ false); - checkRhs(SyntaxKind.PlusEqualsToken, /*expectParens*/ false); - checkRhs(SyntaxKind.BarBarToken, /*expectParens*/ true); - checkRhs(SyntaxKind.AmpersandAmpersandToken, /*expectParens*/ true); - checkRhs(SyntaxKind.QuestionQuestionToken, /*expectParens*/ true); - checkRhs(SyntaxKind.EqualsEqualsToken, /*expectParens*/ true); - checkRhs(SyntaxKind.BarBarEqualsToken, /*expectParens*/ false); - checkRhs(SyntaxKind.AmpersandAmpersandEqualsToken, /*expectParens*/ false); - checkRhs(SyntaxKind.QuestionQuestionEqualsToken, /*expectParens*/ false); + checkRhs(ts.SyntaxKind.CommaToken, /*expectParens*/ false); + checkRhs(ts.SyntaxKind.EqualsToken, /*expectParens*/ false); + checkRhs(ts.SyntaxKind.PlusEqualsToken, /*expectParens*/ false); + checkRhs(ts.SyntaxKind.BarBarToken, /*expectParens*/ true); + checkRhs(ts.SyntaxKind.AmpersandAmpersandToken, /*expectParens*/ true); + checkRhs(ts.SyntaxKind.QuestionQuestionToken, /*expectParens*/ true); + checkRhs(ts.SyntaxKind.EqualsEqualsToken, /*expectParens*/ true); + checkRhs(ts.SyntaxKind.BarBarEqualsToken, /*expectParens*/ false); + checkRhs(ts.SyntaxKind.AmpersandAmpersandEqualsToken, /*expectParens*/ false); + checkRhs(ts.SyntaxKind.QuestionQuestionEqualsToken, /*expectParens*/ false); }); }); }); diff --git a/src/testRunner/unittests/incrementalParser.ts b/src/testRunner/unittests/incrementalParser.ts index 07be24b4b5b4a..e4b907580160e 100644 --- a/src/testRunner/unittests/incrementalParser.ts +++ b/src/testRunner/unittests/incrementalParser.ts @@ -1,24 +1,33 @@ namespace ts { - function withChange(text: IScriptSnapshot, start: number, length: number, newText: string): { text: IScriptSnapshot; textChangeRange: TextChangeRange; } { - const contents = getSnapshotText(text); + function withChange(text: ts.IScriptSnapshot, start: number, length: number, newText: string): { + text: ts.IScriptSnapshot; + textChangeRange: ts.TextChangeRange; + } { + const contents = ts.getSnapshotText(text); const newContents = contents.substr(0, start) + newText + contents.substring(start + length); - return { text: ScriptSnapshot.fromString(newContents), textChangeRange: createTextChangeRange(createTextSpan(start, length), newText.length) }; + return { text: ts.ScriptSnapshot.fromString(newContents), textChangeRange: ts.createTextChangeRange(ts.createTextSpan(start, length), newText.length) }; } - function withInsert(text: IScriptSnapshot, start: number, newText: string): { text: IScriptSnapshot; textChangeRange: TextChangeRange; } { + function withInsert(text: ts.IScriptSnapshot, start: number, newText: string): { + text: ts.IScriptSnapshot; + textChangeRange: ts.TextChangeRange; + } { return withChange(text, start, 0, newText); } - function withDelete(text: IScriptSnapshot, start: number, length: number): { text: IScriptSnapshot; textChangeRange: TextChangeRange; } { + function withDelete(text: ts.IScriptSnapshot, start: number, length: number): { + text: ts.IScriptSnapshot; + textChangeRange: ts.TextChangeRange; + } { return withChange(text, start, length, ""); } - function createTree(text: IScriptSnapshot, version: string) { - return createLanguageServiceSourceFile(/*fileName:*/ "", text, ScriptTarget.Latest, version, /*setNodeParents:*/ true); + function createTree(text: ts.IScriptSnapshot, version: string) { + return ts.createLanguageServiceSourceFile(/*fileName:*/ "", text, ts.ScriptTarget.Latest, version, /*setNodeParents:*/ true); } - function assertSameDiagnostics(file1: SourceFile, file2: SourceFile) { + function assertSameDiagnostics(file1: ts.SourceFile, file2: ts.SourceFile) { const diagnostics1 = file1.parseDiagnostics; const diagnostics2 = file2.parseDiagnostics; @@ -42,7 +51,7 @@ namespace ts { // be a good thing. If it decreases, that's not great (less reusability), but that may be // unavoidable. If it does decrease an investigation should be done to make sure that things // are still ok and we're still appropriately reusing most of the tree. - function compareTrees(oldText: IScriptSnapshot, newText: IScriptSnapshot, textChangeRange: TextChangeRange, expectedReusedElements: number, oldTree?: SourceFile) { + function compareTrees(oldText: ts.IScriptSnapshot, newText: ts.IScriptSnapshot, textChangeRange: ts.TextChangeRange, expectedReusedElements: number, oldTree?: ts.SourceFile) { oldTree = oldTree || createTree(oldText, /*version:*/ "."); Utils.assertInvariants(oldTree, /*parent:*/ undefined); @@ -51,7 +60,7 @@ namespace ts { Utils.assertInvariants(newTree, /*parent:*/ undefined); // Create a tree for the new text, in an incremental fashion. - const incrementalNewTree = updateLanguageServiceSourceFile(oldTree, newText, oldTree.version + ".", textChangeRange); + const incrementalNewTree = ts.updateLanguageServiceSourceFile(oldTree, newText, oldTree.version + ".", textChangeRange); Utils.assertInvariants(incrementalNewTree, /*parent:*/ undefined); // We should get the same tree when doign a full or incremental parse. @@ -74,46 +83,46 @@ namespace ts { return { oldTree, newTree, incrementalNewTree }; } - function reusedElements(oldNode: SourceFile, newNode: SourceFile): number { + function reusedElements(oldNode: ts.SourceFile, newNode: ts.SourceFile): number { const allOldElements = collectElements(oldNode); const allNewElements = collectElements(newNode); - return filter(allOldElements, v => contains(allNewElements, v)).length; + return ts.filter(allOldElements, v => ts.contains(allNewElements, v)).length; } - function collectElements(node: Node) { - const result: Node[] = []; + function collectElements(node: ts.Node) { + const result: ts.Node[] = []; visit(node); return result; - function visit(node: Node) { + function visit(node: ts.Node) { result.push(node); - forEachChild(node, visit); + ts.forEachChild(node, visit); } } function deleteCode(source: string, index: number, toDelete: string) { const repeat = toDelete.length; - let oldTree = createTree(ScriptSnapshot.fromString(source), /*version:*/ "."); + let oldTree = createTree(ts.ScriptSnapshot.fromString(source), /*version:*/ "."); for (let i = 0; i < repeat; i++) { - const oldText = ScriptSnapshot.fromString(source); + const oldText = ts.ScriptSnapshot.fromString(source); const newTextAndChange = withDelete(oldText, index, 1); const newTree = compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, -1, oldTree).incrementalNewTree; - source = getSnapshotText(newTextAndChange.text); + source = ts.getSnapshotText(newTextAndChange.text); oldTree = newTree; } } function insertCode(source: string, index: number, toInsert: string) { const repeat = toInsert.length; - let oldTree = createTree(ScriptSnapshot.fromString(source), /*version:*/ "."); + let oldTree = createTree(ts.ScriptSnapshot.fromString(source), /*version:*/ "."); for (let i = 0; i < repeat; i++) { - const oldText = ScriptSnapshot.fromString(source); + const oldText = ts.ScriptSnapshot.fromString(source); const newTextAndChange = withInsert(oldText, index + i, toInsert.charAt(i)); const newTree = compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, -1, oldTree).incrementalNewTree; - source = getSnapshotText(newTextAndChange.text); + source = ts.getSnapshotText(newTextAndChange.text); oldTree = newTree; } } @@ -128,7 +137,7 @@ namespace ts { " public foo3() { }\r\n" + "}"; - const oldText = ScriptSnapshot.fromString(source); + const oldText = ts.ScriptSnapshot.fromString(source); const semicolonIndex = source.indexOf(";"); const newTextAndChange = withInsert(oldText, semicolonIndex, " + 1"); @@ -145,7 +154,7 @@ namespace ts { "}"; const index = source.indexOf("+ 1"); - const oldText = ScriptSnapshot.fromString(source); + const oldText = ts.ScriptSnapshot.fromString(source); const newTextAndChange = withDelete(oldText, index, "+ 1".length); compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 8); @@ -155,7 +164,7 @@ namespace ts { const source = "class C { public foo1() { /; } public foo2() { return 1;} public foo3() { } }"; const semicolonIndex = source.indexOf(";}"); - const oldText = ScriptSnapshot.fromString(source); + const oldText = ts.ScriptSnapshot.fromString(source); const newTextAndChange = withInsert(oldText, semicolonIndex, "/"); compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 0); @@ -165,7 +174,7 @@ namespace ts { const source = "class C { public foo1() { ; } public foo2() { return 1/;} public foo3() { } }"; const semicolonIndex = source.indexOf(";"); - const oldText = ScriptSnapshot.fromString(source); + const oldText = ts.ScriptSnapshot.fromString(source); const newTextAndChange = withInsert(oldText, semicolonIndex, "/"); compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 4); @@ -175,7 +184,7 @@ namespace ts { const source = "class C { public foo1() { /; } public foo2() { return 1; } public foo3() { } }"; const semicolonIndex = source.indexOf(";"); - const oldText = ScriptSnapshot.fromString(source); + const oldText = ts.ScriptSnapshot.fromString(source); const newTextAndChange = withInsert(oldText, semicolonIndex, "/"); compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 0); @@ -184,7 +193,7 @@ namespace ts { it("Comment 2", () => { const source = "class C { public foo1() { /; } public foo2() { return 1; } public foo3() { } }"; - const oldText = ScriptSnapshot.fromString(source); + const oldText = ts.ScriptSnapshot.fromString(source); const newTextAndChange = withInsert(oldText, 0, "//"); compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 0); @@ -193,7 +202,7 @@ namespace ts { it("Comment 3", () => { const source = "//class C { public foo1() { /; } public foo2() { return 1; } public foo3() { } }"; - const oldText = ScriptSnapshot.fromString(source); + const oldText = ts.ScriptSnapshot.fromString(source); const newTextAndChange = withDelete(oldText, 0, 2); compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 0); @@ -203,7 +212,7 @@ namespace ts { const source = "class C { public foo1() { /; } public foo2() { */ return 1; } public foo3() { } }"; const index = source.indexOf(";"); - const oldText = ScriptSnapshot.fromString(source); + const oldText = ts.ScriptSnapshot.fromString(source); const newTextAndChange = withInsert(oldText, index, "*"); compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 4); @@ -218,7 +227,7 @@ namespace ts { "}"; const semicolonIndex = source.indexOf(";"); - const oldText = ScriptSnapshot.fromString(source); + const oldText = ts.ScriptSnapshot.fromString(source); const newTextAndChange = withInsert(oldText, semicolonIndex, " + 1"); compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 8); @@ -229,7 +238,7 @@ namespace ts { const source = "interface I { a: number; b: string; (c): d; new (e): f; g(): h }"; const index = source.indexOf(": string"); - const oldText = ScriptSnapshot.fromString(source); + const oldText = ts.ScriptSnapshot.fromString(source); const newTextAndChange = withInsert(oldText, index, "?"); compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 14); @@ -240,7 +249,7 @@ namespace ts { const source = "enum E { a = 1, b = 1 << 1, c = 3, e = 4, f = 5, g = 7, h = 8, i = 9, j = 10 }"; const index = source.indexOf("<<"); - const oldText = ScriptSnapshot.fromString(source); + const oldText = ts.ScriptSnapshot.fromString(source); const newTextAndChange = withChange(oldText, index, 2, "+"); compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 24); @@ -249,7 +258,7 @@ namespace ts { it("Strict mode 1", () => { const source = "foo1();\r\nfoo1();\r\nfoo1();\r\package();"; - const oldText = ScriptSnapshot.fromString(source); + const oldText = ts.ScriptSnapshot.fromString(source); const newTextAndChange = withInsert(oldText, 0, "'strict';\r\n"); compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 9); @@ -258,7 +267,7 @@ namespace ts { it("Strict mode 2", () => { const source = "foo1();\r\nfoo1();\r\nfoo1();\r\package();"; - const oldText = ScriptSnapshot.fromString(source); + const oldText = ts.ScriptSnapshot.fromString(source); const newTextAndChange = withInsert(oldText, 0, "'use strict';\r\n"); compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 9); @@ -268,7 +277,7 @@ namespace ts { const source = "'strict';\r\nfoo1();\r\nfoo1();\r\nfoo1();\r\npackage();"; const index = source.indexOf("f"); - const oldText = ScriptSnapshot.fromString(source); + const oldText = ts.ScriptSnapshot.fromString(source); const newTextAndChange = withDelete(oldText, 0, index); compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 9); @@ -278,7 +287,7 @@ namespace ts { const source = "'use strict';\r\nfoo1();\r\nfoo1();\r\nfoo1();\r\npackage();"; const index = source.indexOf("f"); - const oldText = ScriptSnapshot.fromString(source); + const oldText = ts.ScriptSnapshot.fromString(source); const newTextAndChange = withDelete(oldText, 0, index); compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 9); @@ -288,7 +297,7 @@ namespace ts { const source = "'use blahhh';\r\nfoo1();\r\nfoo2();\r\nfoo3();\r\nfoo4();\r\nfoo4();\r\nfoo6();\r\nfoo7();\r\nfoo8();\r\nfoo9();\r\n"; const index = source.indexOf("b"); - const oldText = ScriptSnapshot.fromString(source); + const oldText = ts.ScriptSnapshot.fromString(source); const newTextAndChange = withChange(oldText, index, 6, "strict"); compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 27); @@ -298,7 +307,7 @@ namespace ts { const source = "'use strict';\r\nfoo1();\r\nfoo2();\r\nfoo3();\r\nfoo4();\r\nfoo4();\r\nfoo6();\r\nfoo7();\r\nfoo8();\r\nfoo9();\r\n"; const index = source.indexOf("s"); - const oldText = ScriptSnapshot.fromString(source); + const oldText = ts.ScriptSnapshot.fromString(source); const newTextAndChange = withChange(oldText, index, 6, "blahhh"); compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 27); @@ -308,7 +317,7 @@ namespace ts { const source = "'use blahhh';\r\nfoo1();\r\nfoo2();\r\nfoo3();\r\nfoo4();\r\nfoo4();\r\nfoo6();\r\nfoo7();\r\nfoo8();\r\nfoo9();\r\n"; const index = source.indexOf("f"); - const oldText = ScriptSnapshot.fromString(source); + const oldText = ts.ScriptSnapshot.fromString(source); const newTextAndChange = withDelete(oldText, 0, index); compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 24); @@ -318,7 +327,7 @@ namespace ts { const source = "var v = (a, b, c, d, e)"; const index = source.indexOf("a"); - const oldText = ScriptSnapshot.fromString(source); + const oldText = ts.ScriptSnapshot.fromString(source); const newTextAndChange = withInsert(oldText, index + 1, ":"); compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 0); @@ -328,7 +337,7 @@ namespace ts { const source = "var v = (a, b) = c"; const index = source.indexOf("= c") + 1; - const oldText = ScriptSnapshot.fromString(source); + const oldText = ts.ScriptSnapshot.fromString(source); const newTextAndChange = withInsert(oldText, index, ">"); compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 0); @@ -338,7 +347,7 @@ namespace ts { const source = "var v = (a:, b, c, d, e)"; const index = source.indexOf(":"); - const oldText = ScriptSnapshot.fromString(source); + const oldText = ts.ScriptSnapshot.fromString(source); const newTextAndChange = withDelete(oldText, index, 1); compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 0); @@ -348,7 +357,7 @@ namespace ts { const source = "var v = (a, b) => c"; const index = source.indexOf(">"); - const oldText = ScriptSnapshot.fromString(source); + const oldText = ts.ScriptSnapshot.fromString(source); const newTextAndChange = withDelete(oldText, index, 1); compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 0); @@ -358,7 +367,7 @@ namespace ts { const source = "var v = Fe"; const index = source.indexOf("b"); - const oldText = ScriptSnapshot.fromString(source); + const oldText = ts.ScriptSnapshot.fromString(source); const newTextAndChange = withInsert(oldText, index + 1, ",x"); compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, -1); @@ -368,7 +377,7 @@ namespace ts { const source = "var v = Fe"; const index = source.indexOf("b"); - const oldText = ScriptSnapshot.fromString(source); + const oldText = ts.ScriptSnapshot.fromString(source); const newTextAndChange = withInsert(oldText, index + 1, ",x"); compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, -1); @@ -378,7 +387,7 @@ namespace ts { const source = "var v = Fe"; const index = source.indexOf("b"); - const oldText = ScriptSnapshot.fromString(source); + const oldText = ts.ScriptSnapshot.fromString(source); const newTextAndChange = withInsert(oldText, index + 1, ",x"); compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, -1); @@ -388,7 +397,7 @@ namespace ts { const source = "var v = Fe"; const index = source.indexOf("b"); - const oldText = ScriptSnapshot.fromString(source); + const oldText = ts.ScriptSnapshot.fromString(source); const newTextAndChange = withInsert(oldText, index + 1, ",x"); compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, -1); @@ -398,7 +407,7 @@ namespace ts { const source = "var v = (a);"; const index = source.indexOf(";"); - const oldText = ScriptSnapshot.fromString(source); + const oldText = ts.ScriptSnapshot.fromString(source); const newTextAndChange = withInsert(oldText, index, " => 1"); compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 0); @@ -408,7 +417,7 @@ namespace ts { const source = "var v = (a) => 1;"; const index = source.indexOf(" =>"); - const oldText = ScriptSnapshot.fromString(source); + const oldText = ts.ScriptSnapshot.fromString(source); const newTextAndChange = withDelete(oldText, index, " => 1".length); compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 0); @@ -418,7 +427,7 @@ namespace ts { const source = "var v = 1 >> = 2"; const index = source.indexOf(">> ="); - const oldText = ScriptSnapshot.fromString(source); + const oldText = ts.ScriptSnapshot.fromString(source); const newTextAndChange = withDelete(oldText, index + 2, 1); compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 0); @@ -428,7 +437,7 @@ namespace ts { const source = "var v = 1 >>= 2"; const index = source.indexOf(">>="); - const oldText = ScriptSnapshot.fromString(source); + const oldText = ts.ScriptSnapshot.fromString(source); const newTextAndChange = withInsert(oldText, index + 2, " "); compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 0); @@ -438,7 +447,7 @@ namespace ts { const source = "var v = T>>(2)"; const index = source.indexOf("T"); - const oldText = ScriptSnapshot.fromString(source); + const oldText = ts.ScriptSnapshot.fromString(source); const newTextAndChange = withInsert(oldText, index, "Foo0"; const index = source.indexOf("0"); - const oldText = ScriptSnapshot.fromString(source); + const oldText = ts.ScriptSnapshot.fromString(source); const newTextAndChange = withChange(oldText, index, 1, "()"); compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 0); @@ -488,7 +497,7 @@ namespace ts { const source = "var v = new Dictionary()"; const index = source.indexOf("()"); - const oldText = ScriptSnapshot.fromString(source); + const oldText = ts.ScriptSnapshot.fromString(source); const newTextAndChange = withDelete(oldText, index, 2); compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 0); @@ -498,7 +507,7 @@ namespace ts { // We're changing from a non-generator to a genarator. We can't reuse statement nodes. const source = "function foo() {\r\nyield(foo1);\r\n}"; - const oldText = ScriptSnapshot.fromString(source); + const oldText = ts.ScriptSnapshot.fromString(source); const index = source.indexOf("foo"); const newTextAndChange = withInsert(oldText, index, "*"); @@ -509,7 +518,7 @@ namespace ts { // We're changing from a generator to a non-genarator. We can't reuse statement nodes. const source = "function *foo() {\r\nyield(foo1);\r\n}"; - const oldText = ScriptSnapshot.fromString(source); + const oldText = ts.ScriptSnapshot.fromString(source); const index = source.indexOf("*"); const newTextAndChange = withDelete(oldText, index, "*".length); @@ -519,7 +528,7 @@ namespace ts { it("Delete semicolon", () => { const source = "export class Foo {\r\n}\r\n\r\nexport var foo = new Foo();\r\n\r\n export function test(foo: Foo) {\r\n return true;\r\n }\r\n"; - const oldText = ScriptSnapshot.fromString(source); + const oldText = ts.ScriptSnapshot.fromString(source); const index = source.lastIndexOf(";"); const newTextAndChange = withDelete(oldText, index, 1); @@ -529,7 +538,7 @@ namespace ts { it("Edit after empty type parameter list", () => { const source = "class Dictionary<> { }\r\nvar y;\r\n"; - const oldText = ScriptSnapshot.fromString(source); + const oldText = ts.ScriptSnapshot.fromString(source); const index = source.length; const newTextAndChange = withInsert(oldText, index, "var x;"); @@ -539,7 +548,7 @@ namespace ts { it("Delete parameter after comment", () => { const source = "function fn(/* comment! */ a: number, c) { }"; - const oldText = ScriptSnapshot.fromString(source); + const oldText = ts.ScriptSnapshot.fromString(source); const index = source.indexOf("a:"); const newTextAndChange = withDelete(oldText, index, "a: number,".length); @@ -547,13 +556,12 @@ namespace ts { }); it("Modifier added to accessor", () => { - const source = - "class C {\ + const source = "class C {\ set Bar(bar:string) {}\ }\ var o2 = { set Foo(val:number) { } };"; - const oldText = ScriptSnapshot.fromString(source); + const oldText = ts.ScriptSnapshot.fromString(source); const index = source.indexOf("set"); const newTextAndChange = withInsert(oldText, index, "public "); @@ -561,15 +569,14 @@ var o2 = { set Foo(val:number) { } };"; }); it("Insert parameter ahead of parameter", () => { - const source = - "alert(100);\ + const source = "alert(100);\ \ class OverloadedMonster {\ constructor();\ constructor(name) { }\ }"; - const oldText = ScriptSnapshot.fromString(source); + const oldText = ts.ScriptSnapshot.fromString(source); const index = source.indexOf("100"); const newTextAndChange = withInsert(oldText, index, "'1', "); @@ -577,12 +584,11 @@ constructor(name) { }\ }); it("Insert declare modifier before module", () => { - const source = - "module mAmbient {\ + const source = "module mAmbient {\ module m3 { }\ }"; - const oldText = ScriptSnapshot.fromString(source); + const oldText = ts.ScriptSnapshot.fromString(source); const index = 0; const newTextAndChange = withInsert(oldText, index, "declare "); @@ -590,13 +596,12 @@ module m3 { }\ }); it("Insert function above arrow function with comment", () => { - const source = - "\ + const source = "\ () =>\ // do something\ 0;"; - const oldText = ScriptSnapshot.fromString(source); + const oldText = ts.ScriptSnapshot.fromString(source); const index = 0; const newTextAndChange = withInsert(oldText, index, "function Foo() { }"); @@ -606,7 +611,7 @@ module m3 { }\ it("Finish incomplete regular expression", () => { const source = "while (true) /3; return;"; - const oldText = ScriptSnapshot.fromString(source); + const oldText = ts.ScriptSnapshot.fromString(source); const index = source.length - 1; const newTextAndChange = withInsert(oldText, index, "/"); @@ -616,7 +621,7 @@ module m3 { }\ it("Regular expression to divide operation", () => { const source = "return;\r\nwhile (true) /3/g;"; - const oldText = ScriptSnapshot.fromString(source); + const oldText = ts.ScriptSnapshot.fromString(source); const index = source.indexOf("while"); const newTextAndChange = withDelete(oldText, index, "while ".length); @@ -626,7 +631,7 @@ module m3 { }\ it("Divide operation to regular expression", () => { const source = "return;\r\n(true) /3/g;"; - const oldText = ScriptSnapshot.fromString(source); + const oldText = ts.ScriptSnapshot.fromString(source); const index = source.indexOf("("); const newTextAndChange = withInsert(oldText, index, "while "); @@ -639,7 +644,7 @@ module m3 { }\ // change anything, and we should still get the same errors. const source = "return; a.public /*"; - const oldText = ScriptSnapshot.fromString(source); + const oldText = ts.ScriptSnapshot.fromString(source); const newTextAndChange = withInsert(oldText, 0, ""); compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 7); @@ -648,7 +653,7 @@ module m3 { }\ it("Class to interface", () => { const source = "class A { public M1() { } public M2() { } public M3() { } p1 = 0; p2 = 0; p3 = 0 }"; - const oldText = ScriptSnapshot.fromString(source); + const oldText = ts.ScriptSnapshot.fromString(source); const newTextAndChange = withChange(oldText, 0, "class".length, "interface"); compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 0); @@ -657,7 +662,7 @@ module m3 { }\ it("Interface to class", () => { const source = "interface A { M1?(); M2?(); M3?(); p1?; p2?; p3? }"; - const oldText = ScriptSnapshot.fromString(source); + const oldText = ts.ScriptSnapshot.fromString(source); const newTextAndChange = withChange(oldText, 0, "interface".length, "class"); compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 0); @@ -666,7 +671,7 @@ module m3 { }\ it("Surrounding function declarations with block", () => { const source = "declare function F1() { } export function F2() { } declare export function F3() { }"; - const oldText = ScriptSnapshot.fromString(source); + const oldText = ts.ScriptSnapshot.fromString(source); const newTextAndChange = withInsert(oldText, 0, "{"); compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 9); @@ -675,7 +680,7 @@ module m3 { }\ it("Removing block around function declarations", () => { const source = "{ declare function F1() { } export function F2() { } declare export function F3() { }"; - const oldText = ScriptSnapshot.fromString(source); + const oldText = ts.ScriptSnapshot.fromString(source); const newTextAndChange = withDelete(oldText, 0, "{".length); compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 9); @@ -684,7 +689,7 @@ module m3 { }\ it("Moving methods from class to object literal", () => { const source = "class C { public A() { } public B() { } public C() { } }"; - const oldText = ScriptSnapshot.fromString(source); + const oldText = ts.ScriptSnapshot.fromString(source); const newTextAndChange = withChange(oldText, 0, "class C".length, "var v ="); compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 0); @@ -693,7 +698,7 @@ module m3 { }\ it("Moving methods from object literal to class", () => { const source = "var v = { public A() { } public B() { } public C() { } }"; - const oldText = ScriptSnapshot.fromString(source); + const oldText = ts.ScriptSnapshot.fromString(source); const newTextAndChange = withChange(oldText, 0, "var v =".length, "class C"); compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 4); @@ -702,7 +707,7 @@ module m3 { }\ it("Moving methods from object literal to class in strict mode", () => { const source = "\"use strict\"; var v = { public A() { } public B() { } public C() { } }"; - const oldText = ScriptSnapshot.fromString(source); + const oldText = ts.ScriptSnapshot.fromString(source); const newTextAndChange = withChange(oldText, 14, "var v =".length, "class C"); compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 4); @@ -711,7 +716,7 @@ module m3 { }\ it("Do not move constructors from class to object-literal.", () => { const source = "class C { public constructor() { } public constructor() { } public constructor() { } }"; - const oldText = ScriptSnapshot.fromString(source); + const oldText = ts.ScriptSnapshot.fromString(source); const newTextAndChange = withChange(oldText, 0, "class C".length, "var v ="); compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 0); @@ -720,7 +725,7 @@ module m3 { }\ it("Do not move methods called \"constructor\" from object literal to class", () => { const source = "var v = { public constructor() { } public constructor() { } public constructor() { } }"; - const oldText = ScriptSnapshot.fromString(source); + const oldText = ts.ScriptSnapshot.fromString(source); const newTextAndChange = withChange(oldText, 0, "var v =".length, "class C"); compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 0); @@ -729,7 +734,7 @@ module m3 { }\ it("Moving index signatures from class to interface", () => { const source = "class C { public [a: number]: string; public [a: number]: string; public [a: number]: string }"; - const oldText = ScriptSnapshot.fromString(source); + const oldText = ts.ScriptSnapshot.fromString(source); const newTextAndChange = withChange(oldText, 0, "class".length, "interface"); compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 18); @@ -738,7 +743,7 @@ module m3 { }\ it("Moving index signatures from class to interface in strict mode", () => { const source = "\"use strict\"; class C { public [a: number]: string; public [a: number]: string; public [a: number]: string }"; - const oldText = ScriptSnapshot.fromString(source); + const oldText = ts.ScriptSnapshot.fromString(source); const newTextAndChange = withChange(oldText, 14, "class".length, "interface"); compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 18); @@ -747,7 +752,7 @@ module m3 { }\ it("Moving index signatures from interface to class", () => { const source = "interface C { public [a: number]: string; public [a: number]: string; public [a: number]: string }"; - const oldText = ScriptSnapshot.fromString(source); + const oldText = ts.ScriptSnapshot.fromString(source); const newTextAndChange = withChange(oldText, 0, "interface".length, "class"); compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 18); @@ -757,7 +762,7 @@ module m3 { }\ it("Moving index signatures from interface to class in strict mode", () => { const source = "\"use strict\"; interface C { public [a: number]: string; public [a: number]: string; public [a: number]: string }"; - const oldText = ScriptSnapshot.fromString(source); + const oldText = ts.ScriptSnapshot.fromString(source); const newTextAndChange = withChange(oldText, 14, "interface".length, "class"); compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 18); @@ -766,7 +771,7 @@ module m3 { }\ it("Moving accessors from class to object literal", () => { const source = "class C { public get A() { } public get B() { } public get C() { } }"; - const oldText = ScriptSnapshot.fromString(source); + const oldText = ts.ScriptSnapshot.fromString(source); const newTextAndChange = withChange(oldText, 0, "class C".length, "var v ="); compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 0); @@ -775,7 +780,7 @@ module m3 { }\ it("Moving accessors from object literal to class", () => { const source = "var v = { public get A() { } public get B() { } public get C() { } }"; - const oldText = ScriptSnapshot.fromString(source); + const oldText = ts.ScriptSnapshot.fromString(source); const newTextAndChange = withChange(oldText, 0, "var v =".length, "class C"); compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 4); @@ -785,7 +790,7 @@ module m3 { }\ it("Moving accessors from object literal to class in strict mode", () => { const source = "\"use strict\"; var v = { public get A() { } public get B() { } public get C() { } }"; - const oldText = ScriptSnapshot.fromString(source); + const oldText = ts.ScriptSnapshot.fromString(source); const newTextAndChange = withChange(oldText, 14, "var v =".length, "class C"); compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 4); @@ -793,11 +798,11 @@ module m3 { }\ it("Reuse transformFlags of subtree during bind", () => { const source = `class Greeter { constructor(element: HTMLElement) { } }`; - const oldText = ScriptSnapshot.fromString(source); + const oldText = ts.ScriptSnapshot.fromString(source); const newTextAndChange = withChange(oldText, 15, 0, "\n"); const { oldTree, incrementalNewTree } = compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, -1); - bindSourceFile(oldTree, {}); - bindSourceFile(incrementalNewTree, {}); + ts.bindSourceFile(oldTree, {}); + ts.bindSourceFile(incrementalNewTree, {}); assert.equal(oldTree.transformFlags, incrementalNewTree.transformFlags); }); @@ -865,7 +870,10 @@ module m3 { }\ verifyScenario("when changing text that adds another comment", verifyChangeDirectiveType); verifyScenario("when changing text that keeps the comment but adds more nodes", verifyReuseChange); - function verifyCommentDirectives(oldText: IScriptSnapshot, newTextAndChange: { text: IScriptSnapshot; textChangeRange: TextChangeRange; }) { + function verifyCommentDirectives(oldText: ts.IScriptSnapshot, newTextAndChange: { + text: ts.IScriptSnapshot; + textChangeRange: ts.TextChangeRange; + }) { const { incrementalNewTree, newTree } = compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, -1); assert.deepEqual(incrementalNewTree.commentDirectives, newTree.commentDirectives); } @@ -894,7 +902,8 @@ module m3 { }\ } function textWithIgnoreCommentFrom(text: string, singleIgnore: true | undefined) { - if (!singleIgnore) return text; + if (!singleIgnore) + return text; const splits = text.split(tsIgnoreComment); if (splits.length > 2) { const tail = splits[splits.length - 2] + splits[splits.length - 1]; @@ -908,7 +917,7 @@ module m3 { }\ function verifyDelete(atIndex: number, singleIgnore?: true) { const index = getIndexOfTsIgnoreComment(atIndex); - const oldText = ScriptSnapshot.fromString(textWithIgnoreCommentFrom(textWithIgnoreComment, singleIgnore)); + const oldText = ts.ScriptSnapshot.fromString(textWithIgnoreCommentFrom(textWithIgnoreComment, singleIgnore)); const newTextAndChange = withDelete(oldText, index, tsIgnoreComment.length); verifyCommentDirectives(oldText, newTextAndChange); } @@ -916,14 +925,14 @@ module m3 { }\ function verifyInsert(atIndex: number, singleIgnore?: true) { const index = getIndexOfTsIgnoreComment(atIndex); const source = textWithIgnoreCommentFrom(textWithIgnoreComment.slice(0, index) + textWithIgnoreComment.slice(index + tsIgnoreComment.length), singleIgnore); - const oldText = ScriptSnapshot.fromString(source); + const oldText = ts.ScriptSnapshot.fromString(source); const newTextAndChange = withInsert(oldText, index, tsIgnoreComment); verifyCommentDirectives(oldText, newTextAndChange); } function verifyChangeToBlah(atIndex: number, singleIgnore?: true) { const index = getIndexOfTsIgnoreComment(atIndex) + tsIgnoreComment.indexOf("@"); - const oldText = ScriptSnapshot.fromString(textWithIgnoreCommentFrom(textWithIgnoreComment, singleIgnore)); + const oldText = ts.ScriptSnapshot.fromString(textWithIgnoreCommentFrom(textWithIgnoreComment, singleIgnore)); const newTextAndChange = withChange(oldText, index, 1, "blah "); verifyCommentDirectives(oldText, newTextAndChange); } @@ -931,7 +940,7 @@ module m3 { }\ function verifyChangeBackToDirective(atIndex: number, singleIgnore?: true) { const index = getIndexOfTsIgnoreComment(atIndex) + tsIgnoreComment.indexOf("@"); const source = textWithIgnoreCommentFrom(textWithIgnoreComment.slice(0, index) + "blah " + textWithIgnoreComment.slice(index + 1), singleIgnore); - const oldText = ScriptSnapshot.fromString(source); + const oldText = ts.ScriptSnapshot.fromString(source); const newTextAndChange = withChange(oldText, index, "blah ".length, "@"); verifyCommentDirectives(oldText, newTextAndChange); } @@ -940,14 +949,14 @@ module m3 { }\ const tsIgnoreIndex = getIndexOfTsIgnoreComment(atIndex); const index = tsIgnoreIndex + tsIgnoreComment.indexOf("@"); const source = textWithIgnoreCommentFrom(textWithIgnoreComment.slice(0, index) + "blah " + textWithIgnoreComment.slice(index + 1), singleIgnore); - const oldText = ScriptSnapshot.fromString(source); + const oldText = ts.ScriptSnapshot.fromString(source); const newTextAndChange = withDelete(oldText, tsIgnoreIndex, tsIgnoreComment.length + "blah".length); verifyCommentDirectives(oldText, newTextAndChange); } function verifyChangeDirectiveType(atIndex: number, singleIgnore?: true) { const index = getIndexOfTsIgnoreComment(atIndex) + tsIgnoreComment.indexOf("ignore"); - const oldText = ScriptSnapshot.fromString(textWithIgnoreCommentFrom(textWithIgnoreComment, singleIgnore)); + const oldText = ts.ScriptSnapshot.fromString(textWithIgnoreCommentFrom(textWithIgnoreComment, singleIgnore)); const newTextAndChange = withChange(oldText, index, "ignore".length, "expect-error"); verifyCommentDirectives(oldText, newTextAndChange); } @@ -978,7 +987,7 @@ module m3 { }\ foo1(); foo2(); foo3();`; - const oldText = ScriptSnapshot.fromString(textWithIgnoreCommentFrom(source, singleIgnore)); + const oldText = ts.ScriptSnapshot.fromString(textWithIgnoreCommentFrom(source, singleIgnore)); const start = source.indexOf(`const x${atIndex + 1}`); const letStr = `let y${atIndex + 1}: string = x;`; const end = source.indexOf(letStr) + letStr.length; diff --git a/src/testRunner/unittests/jsDocParsing.ts b/src/testRunner/unittests/jsDocParsing.ts index 0e544e7f77c95..18f91443e6d42 100644 --- a/src/testRunner/unittests/jsDocParsing.ts +++ b/src/testRunner/unittests/jsDocParsing.ts @@ -3,17 +3,16 @@ namespace ts { describe("TypeExpressions", () => { function parsesCorrectly(name: string, content: string) { it(name, () => { - const typeAndDiagnostics = parseJSDocTypeExpressionForTests(content); + const typeAndDiagnostics = ts.parseJSDocTypeExpressionForTests(content); assert.isTrue(typeAndDiagnostics && typeAndDiagnostics.diagnostics.length === 0, "no errors issued"); - Harness.Baseline.runBaseline("JSDocParsing/TypeExpressions.parsesCorrectly." + name + ".json", - Utils.sourceFileToJSON(typeAndDiagnostics!.jsDocTypeExpression.type)); + Harness.Baseline.runBaseline("JSDocParsing/TypeExpressions.parsesCorrectly." + name + ".json", Utils.sourceFileToJSON(typeAndDiagnostics!.jsDocTypeExpression.type)); }); } function parsesIncorrectly(name: string, content: string) { it(name, () => { - const type = parseJSDocTypeExpressionForTests(content); + const type = ts.parseJSDocTypeExpressionForTests(content); assert.isTrue(!type || type.diagnostics.length > 0); }); } @@ -88,62 +87,52 @@ namespace ts { describe("DocComments", () => { function parsesCorrectly(name: string, content: string) { it(name, () => { - const comment = parseIsolatedJSDocComment(content)!; + const comment = ts.parseIsolatedJSDocComment(content)!; if (!comment) { - Debug.fail("Comment failed to parse entirely"); + ts.Debug.fail("Comment failed to parse entirely"); } if (comment.diagnostics.length > 0) { - Debug.fail("Comment has at least one diagnostic: " + comment.diagnostics[0].messageText); + ts.Debug.fail("Comment has at least one diagnostic: " + comment.diagnostics[0].messageText); } - Harness.Baseline.runBaseline("JSDocParsing/DocComments.parsesCorrectly." + name + ".json", - JSON.stringify(comment.jsDoc, - (_, v) => v && v.pos !== undefined ? JSON.parse(Utils.sourceFileToJSON(v)) : v, 4)); + Harness.Baseline.runBaseline("JSDocParsing/DocComments.parsesCorrectly." + name + ".json", JSON.stringify(comment.jsDoc, (_, v) => v && v.pos !== undefined ? JSON.parse(Utils.sourceFileToJSON(v)) : v, 4)); }); } function parsesIncorrectly(name: string, content: string) { it(name, () => { - const type = parseIsolatedJSDocComment(content); + const type = ts.parseIsolatedJSDocComment(content); assert.isTrue(!type || type.diagnostics.length > 0); }); } describe("parsesIncorrectly", () => { - parsesIncorrectly("multipleTypes", - `/** + parsesIncorrectly("multipleTypes", `/** * @type {number} * @type {string} */`); - parsesIncorrectly("multipleReturnTypes", - `/** + parsesIncorrectly("multipleReturnTypes", `/** * @return {number} * @return {string} */`); - parsesIncorrectly("noTypeParameters", - `/** + parsesIncorrectly("noTypeParameters", `/** * @template */`); - parsesIncorrectly("trailingTypeParameterComma", - `/** + parsesIncorrectly("trailingTypeParameterComma", `/** * @template T, */`); - parsesIncorrectly("paramWithoutName", - `/** + parsesIncorrectly("paramWithoutName", `/** * @param {number} */`); - parsesIncorrectly("paramWithoutTypeOrName", - `/** + parsesIncorrectly("paramWithoutTypeOrName", `/** * @param */`); - parsesIncorrectly("noType", - `/** + parsesIncorrectly("noType", `/** * @type */`); - parsesIncorrectly("@augments with no type", - `/** + parsesIncorrectly("@augments with no type", `/** * @augments */`); }); @@ -151,167 +140,139 @@ namespace ts { describe("parsesCorrectly", () => { parsesCorrectly("threeAsterisks", "/*** */"); parsesCorrectly("emptyComment", "/***/"); - parsesCorrectly("noLeadingAsterisk", - `/** + parsesCorrectly("noLeadingAsterisk", `/** @type {number} */`); - parsesCorrectly("noReturnType", - `/** + parsesCorrectly("noReturnType", `/** * @return */`); - parsesCorrectly("leadingAsterisk", - `/** + parsesCorrectly("leadingAsterisk", `/** * @type {number} */`); parsesCorrectly("asteriskAfterPreamble", "/** * @type {number} */"); - parsesCorrectly("typeTag", - `/** + parsesCorrectly("typeTag", `/** * @type {number} */`); - parsesCorrectly("returnTag1", - `/** + parsesCorrectly("returnTag1", `/** * @return {number} */`); - parsesCorrectly("returnTag2", - `/** + parsesCorrectly("returnTag2", `/** * @return {number} Description text follows */`); - parsesCorrectly("returnsTag1", - `/** + parsesCorrectly("returnsTag1", `/** * @returns {number} */`); - parsesCorrectly("oneParamTag", - `/** + parsesCorrectly("oneParamTag", `/** * @param {number} name1 */`); - parsesCorrectly("twoParamTag2", - `/** + parsesCorrectly("twoParamTag2", `/** * @param {number} name1 * @param {number} name2 */`); - parsesCorrectly("paramTag1", - `/** + parsesCorrectly("paramTag1", `/** * @param {number} name1 Description text follows */`); - parsesCorrectly("paramTagBracketedName1", - `/** + parsesCorrectly("paramTagBracketedName1", `/** * @param {number} [name1] Description text follows */`); - parsesCorrectly("paramTagBracketedName2", - `/** + parsesCorrectly("paramTagBracketedName2", `/** * @param {number} [ name1 = 1] Description text follows */`); - parsesCorrectly("twoParamTagOnSameLine", - `/** + parsesCorrectly("twoParamTagOnSameLine", `/** * @param {number} name1 @param {number} name2 */`); - parsesCorrectly("paramTagNameThenType1", - `/** + parsesCorrectly("paramTagNameThenType1", `/** * @param name1 {number} */`); - parsesCorrectly("paramTagNameThenType2", - `/** + parsesCorrectly("paramTagNameThenType2", `/** * @param name1 {number} Description */`); - parsesCorrectly("argSynonymForParamTag", - `/** + parsesCorrectly("argSynonymForParamTag", `/** * @arg {number} name1 Description */`); - parsesCorrectly("argumentSynonymForParamTag", - `/** + parsesCorrectly("argumentSynonymForParamTag", `/** * @argument {number} name1 Description */`); - parsesCorrectly("templateTag", - `/** + parsesCorrectly("templateTag", `/** * @template T */`); - parsesCorrectly("templateTag2", - `/** + parsesCorrectly("templateTag2", `/** * @template K,V */`); - parsesCorrectly("templateTag3", - `/** + parsesCorrectly("templateTag3", `/** * @template K ,V */`); - parsesCorrectly("templateTag4", - `/** + parsesCorrectly("templateTag4", `/** * @template K, V */`); - parsesCorrectly("templateTag5", - `/** + parsesCorrectly("templateTag5", `/** * @template K , V */`); - parsesCorrectly("templateTag6", - `/** + parsesCorrectly("templateTag6", `/** * @template K , V Description of type parameters. */`); - parsesCorrectly("paramWithoutType", - `/** + parsesCorrectly("paramWithoutType", `/** * @param foo */`); - parsesCorrectly("typedefTagWithChildrenTags", - `/** + parsesCorrectly("typedefTagWithChildrenTags", `/** * @typedef People * @type {Object} * @property {number} age * @property {string} name */`); - parsesCorrectly("less-than and greater-than characters", - `/** + parsesCorrectly("less-than and greater-than characters", `/** * @param x hi < > still part of the previous comment */`); - parsesCorrectly("Nested @param tags", - `/** + parsesCorrectly("Nested @param tags", `/** * @param {object} o Doc doc * @param {string} o.f Doc for f */`); - parsesCorrectly("@link tags", - `/** + parsesCorrectly("@link tags", `/** * {@link first } * Inside {@link link text} thing * @param foo See also {@link A.Reference} @@ -330,8 +291,7 @@ oh.no * }, because of the intermediate asterisks. * @author Alfa Romero See my home page: {@link https://example.com} */`); - parsesCorrectly("authorTag", - `/** + parsesCorrectly("authorTag", `/** * @author John Doe * @author John Doe unexpected comment * @author 108 <108@actionbutton.net> Video Games Forever @@ -351,8 +311,7 @@ oh.no * want to keep commenting down here, I dunno. */`); - parsesCorrectly("consecutive newline tokens", - `/** + parsesCorrectly("consecutive newline tokens", `/** * @example * Some\n\n * text\r\n * with newlines. */`); @@ -360,49 +319,47 @@ oh.no parsesCorrectly("Initial star is not a tag", `/***@a*/`); parsesCorrectly("Initial star space is not a tag", `/*** @a*/`); parsesCorrectly("Initial email address is not a tag", `/**bill@example.com*/`); - parsesCorrectly("no space before @ is not a new tag", - `/** + parsesCorrectly("no space before @ is not a new tag", `/** * @param this (@is@) * @param fine its@fine @zerowidth *@singlestar **@doublestar */`); - parsesCorrectly("@@ does not start a new tag", - `/** + parsesCorrectly("@@ does not start a new tag", `/** * @param this is (@@fine@@and) is one comment */`); }); }); describe("getFirstToken", () => { it("gets jsdoc", () => { - const root = createSourceFile("foo.ts", "/** comment */var a = true;", ScriptTarget.ES5, /*setParentNodes*/ true); + const root = ts.createSourceFile("foo.ts", "/** comment */var a = true;", ts.ScriptTarget.ES5, /*setParentNodes*/ true); assert.isDefined(root); - assert.equal(root.kind, SyntaxKind.SourceFile); + assert.equal(root.kind, ts.SyntaxKind.SourceFile); const first = root.getFirstToken(); assert.isDefined(first); - assert.equal(first!.kind, SyntaxKind.VarKeyword); + assert.equal(first!.kind, ts.SyntaxKind.VarKeyword); }); }); describe("getLastToken", () => { it("gets jsdoc", () => { - const root = createSourceFile("foo.ts", "var a = true;/** comment */", ScriptTarget.ES5, /*setParentNodes*/ true); + const root = ts.createSourceFile("foo.ts", "var a = true;/** comment */", ts.ScriptTarget.ES5, /*setParentNodes*/ true); assert.isDefined(root); const last = root.getLastToken(); assert.isDefined(last); - assert.equal(last!.kind, SyntaxKind.EndOfFileToken); + assert.equal(last!.kind, ts.SyntaxKind.EndOfFileToken); }); }); describe("getStart", () => { it("runs when node with JSDoc but no parent pointers", () => { - const root = createSourceFile("foo.ts", "/** */var a = true;", ScriptTarget.ES5, /*setParentNodes*/ false); + const root = ts.createSourceFile("foo.ts", "/** */var a = true;", ts.ScriptTarget.ES5, /*setParentNodes*/ false); root.statements[0].getStart(root, /*includeJsdocComment*/ true); }); }); describe("parseIsolatedJSDocComment", () => { it("doesn't create a 1-element array with missing type parameter in jsDoc", () => { - const doc = parseIsolatedJSDocComment("/**\n @template\n*/"); - assert.equal((doc?.jsDoc.tags?.[0] as JSDocTemplateTag).typeParameters.length, 0); + const doc = ts.parseIsolatedJSDocComment("/**\n @template\n*/"); + assert.equal((doc?.jsDoc.tags?.[0] as ts.JSDocTemplateTag).typeParameters.length, 0); }); }); }); diff --git a/src/testRunner/unittests/jsonParserRecovery.ts b/src/testRunner/unittests/jsonParserRecovery.ts index 43007a687d349..ba3c8e2ea41d5 100644 --- a/src/testRunner/unittests/jsonParserRecovery.ts +++ b/src/testRunner/unittests/jsonParserRecovery.ts @@ -2,11 +2,9 @@ namespace ts { describe("unittests:: jsonParserRecovery", () => { function parsesToValidSourceFileWithErrors(name: string, text: string) { it(name, () => { - const file = parseJsonText(name, text); + const file = ts.parseJsonText(name, text); assert(file.parseDiagnostics.length, "Should have parse errors"); - Harness.Baseline.runBaseline( - `jsonParserRecovery/${name.replace(/[^a-z0-9_-]/ig, "_")}.errors.txt`, - Harness.Compiler.getErrorBaseline([{ + Harness.Baseline.runBaseline(`jsonParserRecovery/${name.replace(/[^a-z0-9_-]/ig, "_")}.errors.txt`, Harness.Compiler.getErrorBaseline([{ content: text, unitName: name }], file.parseDiagnostics)); diff --git a/src/testRunner/unittests/moduleResolution.ts b/src/testRunner/unittests/moduleResolution.ts index 872e9e8b17f71..aad8ffdfd870a 100644 --- a/src/testRunner/unittests/moduleResolution.ts +++ b/src/testRunner/unittests/moduleResolution.ts @@ -1,5 +1,5 @@ namespace ts { - export function checkResolvedModule(actual: ResolvedModuleFull | undefined, expected: ResolvedModuleFull | undefined): boolean { + export function checkResolvedModule(actual: ts.ResolvedModuleFull | undefined, expected: ts.ResolvedModuleFull | undefined): boolean { if (!expected) { if (actual) { assert.fail(actual, expected, "expected resolved module to be undefined"); @@ -18,14 +18,14 @@ namespace ts { return true; } - export function checkResolvedModuleWithFailedLookupLocations(actual: ResolvedModuleWithFailedLookupLocations, expectedResolvedModule: ResolvedModuleFull, expectedFailedLookupLocations: string[]): void { + export function checkResolvedModuleWithFailedLookupLocations(actual: ts.ResolvedModuleWithFailedLookupLocations, expectedResolvedModule: ts.ResolvedModuleFull, expectedFailedLookupLocations: string[]): void { assert.isTrue(actual.resolvedModule !== undefined, "module should be resolved"); checkResolvedModule(actual.resolvedModule, expectedResolvedModule); assert.deepEqual(actual.failedLookupLocations, expectedFailedLookupLocations, `Failed lookup locations should match - expected has ${expectedFailedLookupLocations.length}, actual has ${actual.failedLookupLocations.length}`); } - export function createResolvedModule(resolvedFileName: string, isExternalLibraryImport = false): ResolvedModuleFull { - return { resolvedFileName, extension: extensionFromPath(resolvedFileName), isExternalLibraryImport }; + export function createResolvedModule(resolvedFileName: string, isExternalLibraryImport = false): ts.ResolvedModuleFull { + return { resolvedFileName, extension: ts.extensionFromPath(resolvedFileName), isExternalLibraryImport }; } interface File { @@ -34,8 +34,8 @@ namespace ts { symlinks?: string[]; } - function createModuleResolutionHost(hasDirectoryExists: boolean, ...files: File[]): ModuleResolutionHost { - const map = new Map(); + function createModuleResolutionHost(hasDirectoryExists: boolean, ...files: File[]): ts.ModuleResolutionHost { + const map = new ts.Map(); for (const file of files) { map.set(file.name, file); if (file.symlinks) { @@ -46,12 +46,12 @@ namespace ts { } if (hasDirectoryExists) { - const directories = new Map(); + const directories = new ts.Map(); for (const f of files) { - let name = getDirectoryPath(f.name); + let name = ts.getDirectoryPath(f.name); while (true) { directories.set(name, name); - const baseName = getDirectoryPath(name); + const baseName = ts.getDirectoryPath(name); if (baseName === name) { break; } @@ -63,7 +63,7 @@ namespace ts { realpath, directoryExists: path => directories.has(path), fileExists: path => { - assert.isTrue(directories.has(getDirectoryPath(path)), `'fileExists' '${path}' request in non-existing directory`); + assert.isTrue(directories.has(ts.getDirectoryPath(path)), `'fileExists' '${path}' request in non-existing directory`); return map.has(path); }, useCaseSensitiveFileNames: true @@ -83,8 +83,8 @@ namespace ts { describe("unittests:: moduleResolution:: Node module resolution - relative paths", () => { // node module resolution does _not_ implicitly append these extensions to an extensionless path (though will still attempt to load them if explicitly) - const nonImplicitExtensions = [Extension.Mts, Extension.Dmts, Extension.Mjs, Extension.Cts, Extension.Dcts, Extension.Cjs]; - const autoExtensions = filter(supportedTSExtensionsFlat, e => nonImplicitExtensions.indexOf(e) === -1); + const nonImplicitExtensions = [ts.Extension.Mts, ts.Extension.Dmts, ts.Extension.Mjs, ts.Extension.Cts, ts.Extension.Dcts, ts.Extension.Cjs]; + const autoExtensions = ts.filter(ts.supportedTSExtensionsFlat, e => nonImplicitExtensions.indexOf(e) === -1); function testLoadAsFile(containingFileName: string, moduleFileNameNoExt: string, moduleName: string): void { for (const ext of autoExtensions) { test(ext, /*hasDirectoryExists*/ false); @@ -94,17 +94,17 @@ namespace ts { function test(ext: string, hasDirectoryExists: boolean) { const containingFile = { name: containingFileName }; const moduleFile = { name: moduleFileNameNoExt + ext }; - const resolution = nodeModuleNameResolver(moduleName, containingFile.name, {}, createModuleResolutionHost(hasDirectoryExists, containingFile, moduleFile)); + const resolution = ts.nodeModuleNameResolver(moduleName, containingFile.name, {}, createModuleResolutionHost(hasDirectoryExists, containingFile, moduleFile)); checkResolvedModule(resolution.resolvedModule, createResolvedModule(moduleFile.name)); const failedLookupLocations: string[] = []; - const dir = getDirectoryPath(containingFileName); + const dir = ts.getDirectoryPath(containingFileName); for (const e of autoExtensions) { if (e === ext) { break; } else { - failedLookupLocations.push(normalizePath(getRootLength(moduleName) === 0 ? combinePaths(dir, moduleName) : moduleName) + e); + failedLookupLocations.push(ts.normalizePath(ts.getRootLength(moduleName) === 0 ? ts.combinePaths(dir, moduleName) : moduleName) + e); } } @@ -137,10 +137,10 @@ namespace ts { const containingFile = { name: containingFileName }; const packageJson = { name: packageJsonFileName, content: JSON.stringify({ typings: fieldRef }) }; const moduleFile = { name: moduleFileName }; - const resolution = nodeModuleNameResolver(moduleName, containingFile.name, {}, createModuleResolutionHost(hasDirectoryExists, containingFile, packageJson, moduleFile)); + const resolution = ts.nodeModuleNameResolver(moduleName, containingFile.name, {}, createModuleResolutionHost(hasDirectoryExists, containingFile, packageJson, moduleFile)); checkResolvedModule(resolution.resolvedModule, createResolvedModule(moduleFile.name)); // expect three failed lookup location - attempt to load module as file with all supported extensions - assert.equal(resolution.failedLookupLocations.length, supportedTSExtensions[0].length); + assert.equal(resolution.failedLookupLocations.length, ts.supportedTSExtensions[0].length); } } @@ -163,7 +163,7 @@ namespace ts { const indexPath = "/node_modules/b/index.d.ts"; const indexFile = { name: indexPath }; - const resolution = nodeModuleNameResolver("b", containingFile.name, {}, createModuleResolutionHost(hasDirectoryExists, containingFile, packageJson, moduleFile, indexFile)); + const resolution = ts.nodeModuleNameResolver("b", containingFile.name, {}, createModuleResolutionHost(hasDirectoryExists, containingFile, packageJson, moduleFile, indexFile)); checkResolvedModule(resolution.resolvedModule, createResolvedModule(indexPath, /*isExternalLibraryImport*/ true)); } @@ -184,7 +184,7 @@ namespace ts { const containingFile = { name: "/a/b/c.ts" }; const packageJson = { name: "/a/b/foo/package.json", content: JSON.stringify({ main: "/c/d" }) }; const indexFile = { name: "/a/b/foo/index.d.ts" }; - const resolution = nodeModuleNameResolver("./foo", containingFile.name, {}, createModuleResolutionHost(hasDirectoryExists, containingFile, packageJson, indexFile)); + const resolution = ts.nodeModuleNameResolver("./foo", containingFile.name, {}, createModuleResolutionHost(hasDirectoryExists, containingFile, packageJson, indexFile)); checkResolvedModuleWithFailedLookupLocations(resolution, createResolvedModule(indexFile.name), [ "/a/b/foo.ts", "/a/b/foo.tsx", @@ -205,14 +205,14 @@ namespace ts { describe("unittests:: moduleResolution:: Node module resolution - non-relative paths", () => { it("computes correct commonPrefix for moduleName cache", () => { - const resolutionCache = createModuleResolutionCache("/", (f) => f); + const resolutionCache = ts.createModuleResolutionCache("/", (f) => f); let cache = resolutionCache.getOrCreateCacheForModuleName("a", /*mode*/ undefined); cache.set("/sub", { resolvedModule: { originalPath: undefined, resolvedFileName: "/sub/node_modules/a/index.ts", isExternalLibraryImport: true, - extension: Extension.Ts, + extension: ts.Extension.Ts, }, failedLookupLocations: [], resolutionDiagnostics: [], @@ -226,7 +226,7 @@ namespace ts { originalPath: undefined, resolvedFileName: "/sub/directory/node_modules/b/index.ts", isExternalLibraryImport: true, - extension: Extension.Ts, + extension: ts.Extension.Ts, }, failedLookupLocations: [], resolutionDiagnostics: [], @@ -242,7 +242,7 @@ namespace ts { originalPath: undefined, resolvedFileName: "/bar/node_modules/c/index.ts", isExternalLibraryImport: true, - extension: Extension.Ts, + extension: ts.Extension.Ts, }, failedLookupLocations: [], resolutionDiagnostics: [], @@ -257,7 +257,7 @@ namespace ts { originalPath: undefined, resolvedFileName: "/foo/index.ts", isExternalLibraryImport: true, - extension: Extension.Ts, + extension: ts.Extension.Ts, }, failedLookupLocations: [], resolutionDiagnostics: [], @@ -271,7 +271,7 @@ namespace ts { originalPath: undefined, resolvedFileName: "d:/bar/node_modules/e/index.ts", isExternalLibraryImport: true, - extension: Extension.Ts, + extension: ts.Extension.Ts, }, failedLookupLocations: [], resolutionDiagnostics: [], @@ -299,7 +299,7 @@ namespace ts { function test(hasDirectoryExists: boolean) { const containingFile = { name: "/a/b/c/d/e.ts" }; const moduleFile = { name: "/a/b/node_modules/foo.ts" }; - const resolution = nodeModuleNameResolver("foo", containingFile.name, {}, createModuleResolutionHost(hasDirectoryExists, containingFile, moduleFile)); + const resolution = ts.nodeModuleNameResolver("foo", containingFile.name, {}, createModuleResolutionHost(hasDirectoryExists, containingFile, moduleFile)); checkResolvedModuleWithFailedLookupLocations(resolution, createResolvedModule(moduleFile.name, /*isExternalLibraryImport*/ true), [ "/a/b/c/d/node_modules/foo/package.json", "/a/b/c/d/node_modules/foo.ts", @@ -340,7 +340,7 @@ namespace ts { function test(hasDirectoryExists: boolean) { const containingFile = { name: "/a/b/c/d/e.ts" }; const moduleFile = { name: "/a/b/node_modules/foo.d.ts" }; - const resolution = nodeModuleNameResolver("foo", containingFile.name, {}, createModuleResolutionHost(hasDirectoryExists, containingFile, moduleFile)); + const resolution = ts.nodeModuleNameResolver("foo", containingFile.name, {}, createModuleResolutionHost(hasDirectoryExists, containingFile, moduleFile)); checkResolvedModule(resolution.resolvedModule, createResolvedModule(moduleFile.name, /*isExternalLibraryImport*/ true)); } }); @@ -352,7 +352,7 @@ namespace ts { function test(hasDirectoryExists: boolean) { const containingFile: File = { name: "/a/node_modules/b/c/node_modules/d/e.ts" }; const moduleFile: File = { name: "/a/node_modules/foo/index.d.ts" }; - const resolution = nodeModuleNameResolver("foo", containingFile.name, {}, createModuleResolutionHost(hasDirectoryExists, containingFile, moduleFile)); + const resolution = ts.nodeModuleNameResolver("foo", containingFile.name, {}, createModuleResolutionHost(hasDirectoryExists, containingFile, moduleFile)); checkResolvedModuleWithFailedLookupLocations(resolution, createResolvedModule(moduleFile.name, /*isExternalLibraryImport*/ true), [ "/a/node_modules/b/c/node_modules/d/node_modules/foo/package.json", "/a/node_modules/b/c/node_modules/d/node_modules/foo.ts", @@ -414,11 +414,8 @@ namespace ts { const realFileName = "/linked/index.d.ts"; const symlinkFileName = "/app/node_modules/linked/index.d.ts"; const host = createModuleResolutionHost( - /*hasDirectoryExists*/ true, - { name: realFileName, symlinks: [symlinkFileName] }, - { name: "/app/node_modules/linked/package.json", content: '{"version": "0.0.0", "main": "./index"}' }, - ); - const resolution = nodeModuleNameResolver("linked", "/app/app.ts", { preserveSymlinks }, host); + /*hasDirectoryExists*/ true, { name: realFileName, symlinks: [symlinkFileName] }, { name: "/app/node_modules/linked/package.json", content: '{"version": "0.0.0", "main": "./index"}' }); + const resolution = ts.nodeModuleNameResolver("linked", "/app/app.ts", { preserveSymlinks }, host); const resolvedFileName = preserveSymlinks ? symlinkFileName : realFileName; checkResolvedModule(resolution.resolvedModule, createResolvedModule(resolvedFileName, /*isExternalLibraryImport*/ true)); }); @@ -426,40 +423,33 @@ namespace ts { it("uses originalPath for caching", () => { const host = createModuleResolutionHost( - /*hasDirectoryExists*/ true, - { + /*hasDirectoryExists*/ true, { name: "/modules/a.ts", symlinks: ["/sub/node_modules/a/index.ts"], - }, - { + }, { name: "/sub/node_modules/a/package.json", content: '{"version": "0.0.0", "main": "./index"}' - } - ); - const compilerOptions: CompilerOptions = { moduleResolution: ModuleResolutionKind.NodeJs }; - const cache = createModuleResolutionCache("/", (f) => f); - let resolution = resolveModuleName("a", "/sub/dir/foo.ts", compilerOptions, host, cache); + }); + const compilerOptions: ts.CompilerOptions = { moduleResolution: ts.ModuleResolutionKind.NodeJs }; + const cache = ts.createModuleResolutionCache("/", (f) => f); + let resolution = ts.resolveModuleName("a", "/sub/dir/foo.ts", compilerOptions, host, cache); checkResolvedModule(resolution.resolvedModule, createResolvedModule("/modules/a.ts", /*isExternalLibraryImport*/ true)); - resolution = resolveModuleName("a", "/sub/foo.ts", compilerOptions, host, cache); + resolution = ts.resolveModuleName("a", "/sub/foo.ts", compilerOptions, host, cache); checkResolvedModule(resolution.resolvedModule, createResolvedModule("/modules/a.ts", /*isExternalLibraryImport*/ true)); - resolution = resolveModuleName("a", "/foo.ts", compilerOptions, host, cache); + resolution = ts.resolveModuleName("a", "/foo.ts", compilerOptions, host, cache); assert.isUndefined(resolution.resolvedModule, "lookup in parent directory doesn't hit the cache"); }); it("preserves originalPath on cache hit", () => { const host = createModuleResolutionHost( - /*hasDirectoryExists*/ true, - { name: "/linked/index.d.ts", symlinks: ["/app/node_modules/linked/index.d.ts"] }, - { name: "/app/node_modules/linked/package.json", content: '{"version": "0.0.0", "main": "./index"}' }, - ); - const cache = createModuleResolutionCache("/", (f) => f); - const compilerOptions: CompilerOptions = { moduleResolution: ModuleResolutionKind.NodeJs }; - checkResolution(resolveModuleName("linked", "/app/src/app.ts", compilerOptions, host, cache)); - checkResolution(resolveModuleName("linked", "/app/lib/main.ts", compilerOptions, host, cache)); - - function checkResolution(resolution: ResolvedModuleWithFailedLookupLocations) { + /*hasDirectoryExists*/ true, { name: "/linked/index.d.ts", symlinks: ["/app/node_modules/linked/index.d.ts"] }, { name: "/app/node_modules/linked/package.json", content: '{"version": "0.0.0", "main": "./index"}' }); + const cache = ts.createModuleResolutionCache("/", (f) => f); + const compilerOptions: ts.CompilerOptions = { moduleResolution: ts.ModuleResolutionKind.NodeJs }; + checkResolution(ts.resolveModuleName("linked", "/app/src/app.ts", compilerOptions, host, cache)); + checkResolution(ts.resolveModuleName("linked", "/app/lib/main.ts", compilerOptions, host, cache)); + function checkResolution(resolution: ts.ResolvedModuleWithFailedLookupLocations) { checkResolvedModule(resolution.resolvedModule, createResolvedModule("/linked/index.d.ts", /*isExternalLibraryImport*/ true)); assert.strictEqual(resolution.resolvedModule!.originalPath, "/app/node_modules/linked/index.d.ts"); } @@ -467,29 +457,29 @@ namespace ts { }); describe("unittests:: moduleResolution:: Relative imports", () => { - function test(files: ESMap, currentDirectory: string, rootFiles: string[], expectedFilesCount: number, relativeNamesToCheck: string[]) { - const options: CompilerOptions = { module: ModuleKind.CommonJS }; - const host: CompilerHost = { - getSourceFile: (fileName: string, languageVersion: ScriptTarget) => { - const path = normalizePath(combinePaths(currentDirectory, fileName)); + function test(files: ts.ESMap, currentDirectory: string, rootFiles: string[], expectedFilesCount: number, relativeNamesToCheck: string[]) { + const options: ts.CompilerOptions = { module: ts.ModuleKind.CommonJS }; + const host: ts.CompilerHost = { + getSourceFile: (fileName: string, languageVersion: ts.ScriptTarget) => { + const path = ts.normalizePath(ts.combinePaths(currentDirectory, fileName)); const file = files.get(path); - return file ? createSourceFile(fileName, file, languageVersion) : undefined; + return file ? ts.createSourceFile(fileName, file, languageVersion) : undefined; }, getDefaultLibFileName: () => "lib.d.ts", - writeFile: notImplemented, + writeFile: ts.notImplemented, getCurrentDirectory: () => currentDirectory, getDirectories: () => [], getCanonicalFileName: fileName => fileName.toLowerCase(), getNewLine: () => "\r\n", useCaseSensitiveFileNames: () => false, fileExists: fileName => { - const path = normalizePath(combinePaths(currentDirectory, fileName)); + const path = ts.normalizePath(ts.combinePaths(currentDirectory, fileName)); return files.has(path); }, - readFile: notImplemented, + readFile: ts.notImplemented, }; - const program = createProgram(rootFiles, options, host); + const program = ts.createProgram(rootFiles, options, host); assert.equal(program.getSourceFiles().length, expectedFilesCount); const syntacticDiagnostics = program.getSyntacticDiagnostics(); @@ -504,7 +494,7 @@ namespace ts { } it("should find all modules", () => { - const files = new Map(getEntries({ + const files = new ts.Map(ts.getEntries({ "/a/b/c/first/shared.ts": ` class A {} export = A`, @@ -523,7 +513,7 @@ export = C; }); it("should find modules in node_modules", () => { - const files = new Map(getEntries({ + const files = new ts.Map(ts.getEntries({ "/parent/node_modules/mod/index.d.ts": "export var x", "/parent/app/myapp.ts": `import {x} from "mod"` })); @@ -531,7 +521,7 @@ export = C; }); it("should find file referenced via absolute and relative names", () => { - const files = new Map(getEntries({ + const files = new ts.Map(ts.getEntries({ "/a/b/c.ts": `/// `, "/a/b/b.ts": "var x" })); @@ -540,294 +530,161 @@ export = C; }); describe("unittests:: moduleResolution:: Files with different casing with forceConsistentCasingInFileNames", () => { - let library: SourceFile; - function test( - files: ESMap, - options: CompilerOptions, - currentDirectory: string, - useCaseSensitiveFileNames: boolean, - rootFiles: string[], - expectedDiagnostics: (program: Program) => readonly Diagnostic[] - ): void { - const getCanonicalFileName = createGetCanonicalFileName(useCaseSensitiveFileNames); + let library: ts.SourceFile; + function test(files: ts.ESMap, options: ts.CompilerOptions, currentDirectory: string, useCaseSensitiveFileNames: boolean, rootFiles: string[], expectedDiagnostics: (program: ts.Program) => readonly ts.Diagnostic[]): void { + const getCanonicalFileName = ts.createGetCanonicalFileName(useCaseSensitiveFileNames); if (!useCaseSensitiveFileNames) { const oldFiles = files; - files = new Map(); + files = new ts.Map(); oldFiles.forEach((file, fileName) => { files.set(getCanonicalFileName(fileName), file); }); } - const host: CompilerHost = { - getSourceFile: (fileName: string, languageVersion: ScriptTarget) => { + const host: ts.CompilerHost = { + getSourceFile: (fileName: string, languageVersion: ts.ScriptTarget) => { if (fileName === "lib.d.ts") { if (!library) { - library = createSourceFile("lib.d.ts", "", ScriptTarget.ES5); + library = ts.createSourceFile("lib.d.ts", "", ts.ScriptTarget.ES5); } return library; } - const path = getCanonicalFileName(normalizePath(combinePaths(currentDirectory, fileName))); + const path = getCanonicalFileName(ts.normalizePath(ts.combinePaths(currentDirectory, fileName))); const file = files.get(path); - return file ? createSourceFile(fileName, file, languageVersion) : undefined; + return file ? ts.createSourceFile(fileName, file, languageVersion) : undefined; }, getDefaultLibFileName: () => "lib.d.ts", - writeFile: notImplemented, + writeFile: ts.notImplemented, getCurrentDirectory: () => currentDirectory, getDirectories: () => [], getCanonicalFileName, getNewLine: () => "\r\n", useCaseSensitiveFileNames: () => useCaseSensitiveFileNames, fileExists: fileName => { - const path = getCanonicalFileName(normalizePath(combinePaths(currentDirectory, fileName))); + const path = getCanonicalFileName(ts.normalizePath(ts.combinePaths(currentDirectory, fileName))); return files.has(path); }, - readFile: notImplemented, + readFile: ts.notImplemented, }; - const program = createProgram(rootFiles, options, host); - const diagnostics = sortAndDeduplicateDiagnostics([...program.getSemanticDiagnostics(), ...program.getOptionsDiagnostics()]); - assert.deepEqual(diagnostics, sortAndDeduplicateDiagnostics(expectedDiagnostics(program))); + const program = ts.createProgram(rootFiles, options, host); + const diagnostics = ts.sortAndDeduplicateDiagnostics([...program.getSemanticDiagnostics(), ...program.getOptionsDiagnostics()]); + assert.deepEqual(diagnostics, ts.sortAndDeduplicateDiagnostics(expectedDiagnostics(program))); } it("should succeed when the same file is referenced using absolute and relative names", () => { - const files = new Map(getEntries({ + const files = new ts.Map(ts.getEntries({ "/a/b/c.ts": `/// `, "/a/b/d.ts": "var x" })); - test( - files, - { module: ModuleKind.AMD }, - "/a/b", - /*useCaseSensitiveFileNames*/ false, - ["c.ts", "/a/b/d.ts"], - () => emptyArray - ); + test(files, { module: ts.ModuleKind.AMD }, "/a/b", + /*useCaseSensitiveFileNames*/ false, ["c.ts", "/a/b/d.ts"], () => ts.emptyArray); }); it("should fail when two files used in program differ only in casing (tripleslash references)", () => { - const files = new Map(getEntries({ + const files = new ts.Map(ts.getEntries({ "/a/b/c.ts": `/// `, "/a/b/d.ts": "var x" })); - test( - files, - { module: ModuleKind.AMD, forceConsistentCasingInFileNames: true }, - "/a/b", - /*useCaseSensitiveFileNames*/ false, - ["c.ts", "d.ts"], - program => [{ - ...tscWatch.getDiagnosticOfFileFromProgram( - program, - "c.ts", - `/// `.indexOf(`D.ts`), - "D.ts".length, - tscWatch.getDiagnosticMessageChain( - Diagnostics.Already_included_file_name_0_differs_from_file_name_1_only_in_casing, - ["D.ts", "d.ts"], - [ - tscWatch.getDiagnosticMessageChain( - Diagnostics.The_file_is_in_the_program_because_Colon, - emptyArray, - [ - tscWatch.getDiagnosticMessageChain(Diagnostics.Referenced_via_0_from_file_1, ["D.ts", "c.ts"]), - tscWatch.getDiagnosticMessageChain(Diagnostics.Root_file_specified_for_compilation) - ] - ) - ], - ) - ), + test(files, { module: ts.ModuleKind.AMD, forceConsistentCasingInFileNames: true }, "/a/b", + /*useCaseSensitiveFileNames*/ false, ["c.ts", "d.ts"], program => [{ + ...ts.tscWatch.getDiagnosticOfFileFromProgram(program, "c.ts", `/// `.indexOf(`D.ts`), "D.ts".length, ts.tscWatch.getDiagnosticMessageChain(ts.Diagnostics.Already_included_file_name_0_differs_from_file_name_1_only_in_casing, ["D.ts", "d.ts"], [ + ts.tscWatch.getDiagnosticMessageChain(ts.Diagnostics.The_file_is_in_the_program_because_Colon, ts.emptyArray, [ + ts.tscWatch.getDiagnosticMessageChain(ts.Diagnostics.Referenced_via_0_from_file_1, ["D.ts", "c.ts"]), + ts.tscWatch.getDiagnosticMessageChain(ts.Diagnostics.Root_file_specified_for_compilation) + ]) + ])), relatedInformation: undefined, - }] - ); + }]); }); it("should fail when two files used in program differ only in casing (imports)", () => { - const files = new Map(getEntries({ + const files = new ts.Map(ts.getEntries({ "/a/b/c.ts": `import {x} from "D"`, "/a/b/d.ts": "export var x" })); - test( - files, - { module: ModuleKind.AMD, forceConsistentCasingInFileNames: true }, - "/a/b", - /*useCaseSensitiveFileNames*/ false, - ["c.ts", "d.ts"], - program => [{ - ...tscWatch.getDiagnosticOfFileFromProgram( - program, - "c.ts", - `import {x} from "D"`.indexOf(`"D"`), - `"D"`.length, - tscWatch.getDiagnosticMessageChain( - Diagnostics.Already_included_file_name_0_differs_from_file_name_1_only_in_casing, - ["/a/b/D.ts", "d.ts"], - [ - tscWatch.getDiagnosticMessageChain( - Diagnostics.The_file_is_in_the_program_because_Colon, - emptyArray, - [ - tscWatch.getDiagnosticMessageChain(Diagnostics.Imported_via_0_from_file_1, [`"D"`, "c.ts"]), - tscWatch.getDiagnosticMessageChain(Diagnostics.Root_file_specified_for_compilation) - ] - ) - ], - ) - ), + test(files, { module: ts.ModuleKind.AMD, forceConsistentCasingInFileNames: true }, "/a/b", + /*useCaseSensitiveFileNames*/ false, ["c.ts", "d.ts"], program => [{ + ...ts.tscWatch.getDiagnosticOfFileFromProgram(program, "c.ts", `import {x} from "D"`.indexOf(`"D"`), `"D"`.length, ts.tscWatch.getDiagnosticMessageChain(ts.Diagnostics.Already_included_file_name_0_differs_from_file_name_1_only_in_casing, ["/a/b/D.ts", "d.ts"], [ + ts.tscWatch.getDiagnosticMessageChain(ts.Diagnostics.The_file_is_in_the_program_because_Colon, ts.emptyArray, [ + ts.tscWatch.getDiagnosticMessageChain(ts.Diagnostics.Imported_via_0_from_file_1, [`"D"`, "c.ts"]), + ts.tscWatch.getDiagnosticMessageChain(ts.Diagnostics.Root_file_specified_for_compilation) + ]) + ])), relatedInformation: undefined, - }] - ); + }]); }); it("should fail when two files used in program differ only in casing (imports, relative module names)", () => { - const files = new Map(getEntries({ + const files = new ts.Map(ts.getEntries({ "moduleA.ts": `import {x} from "./ModuleB"`, "moduleB.ts": "export var x" })); - test( - files, - { module: ModuleKind.CommonJS, forceConsistentCasingInFileNames: true }, - "", - /*useCaseSensitiveFileNames*/ false, - ["moduleA.ts", "moduleB.ts"], - program => [{ - ...tscWatch.getDiagnosticOfFileFromProgram( - program, - "moduleA.ts", - `import {x} from "./ModuleB"`.indexOf(`"./ModuleB"`), - `"./ModuleB"`.length, - tscWatch.getDiagnosticMessageChain( - Diagnostics.Already_included_file_name_0_differs_from_file_name_1_only_in_casing, - ["ModuleB.ts", "moduleB.ts"], - [ - tscWatch.getDiagnosticMessageChain( - Diagnostics.The_file_is_in_the_program_because_Colon, - emptyArray, - [ - tscWatch.getDiagnosticMessageChain(Diagnostics.Imported_via_0_from_file_1, [`"./ModuleB"`, "moduleA.ts"]), - tscWatch.getDiagnosticMessageChain(Diagnostics.Root_file_specified_for_compilation) - ] - ) - ], - ) - ), + test(files, { module: ts.ModuleKind.CommonJS, forceConsistentCasingInFileNames: true }, "", + /*useCaseSensitiveFileNames*/ false, ["moduleA.ts", "moduleB.ts"], program => [{ + ...ts.tscWatch.getDiagnosticOfFileFromProgram(program, "moduleA.ts", `import {x} from "./ModuleB"`.indexOf(`"./ModuleB"`), `"./ModuleB"`.length, ts.tscWatch.getDiagnosticMessageChain(ts.Diagnostics.Already_included_file_name_0_differs_from_file_name_1_only_in_casing, ["ModuleB.ts", "moduleB.ts"], [ + ts.tscWatch.getDiagnosticMessageChain(ts.Diagnostics.The_file_is_in_the_program_because_Colon, ts.emptyArray, [ + ts.tscWatch.getDiagnosticMessageChain(ts.Diagnostics.Imported_via_0_from_file_1, [`"./ModuleB"`, "moduleA.ts"]), + ts.tscWatch.getDiagnosticMessageChain(ts.Diagnostics.Root_file_specified_for_compilation) + ]) + ])), relatedInformation: undefined - }] - ); + }]); }); it("should fail when two files exist on disk that differs only in casing", () => { - const files = new Map(getEntries({ + const files = new ts.Map(ts.getEntries({ "/a/b/c.ts": `import {x} from "D"`, "/a/b/D.ts": "export var x", "/a/b/d.ts": "export var y" })); - test( - files, - { module: ModuleKind.AMD }, - "/a/b", - /*useCaseSensitiveFileNames*/ true, - ["c.ts", "d.ts"], - program => [{ - ...tscWatch.getDiagnosticOfFileFromProgram( - program, - "c.ts", - `import {x} from "D"`.indexOf(`"D"`), - `"D"`.length, - tscWatch.getDiagnosticMessageChain( - Diagnostics.Already_included_file_name_0_differs_from_file_name_1_only_in_casing, - ["/a/b/D.ts", "d.ts"], - [ - tscWatch.getDiagnosticMessageChain( - Diagnostics.The_file_is_in_the_program_because_Colon, - emptyArray, - [ - tscWatch.getDiagnosticMessageChain(Diagnostics.Imported_via_0_from_file_1, [`"D"`, "c.ts"]), - tscWatch.getDiagnosticMessageChain(Diagnostics.Root_file_specified_for_compilation) - ] - ) - ], - ) - ), + test(files, { module: ts.ModuleKind.AMD }, "/a/b", + /*useCaseSensitiveFileNames*/ true, ["c.ts", "d.ts"], program => [{ + ...ts.tscWatch.getDiagnosticOfFileFromProgram(program, "c.ts", `import {x} from "D"`.indexOf(`"D"`), `"D"`.length, ts.tscWatch.getDiagnosticMessageChain(ts.Diagnostics.Already_included_file_name_0_differs_from_file_name_1_only_in_casing, ["/a/b/D.ts", "d.ts"], [ + ts.tscWatch.getDiagnosticMessageChain(ts.Diagnostics.The_file_is_in_the_program_because_Colon, ts.emptyArray, [ + ts.tscWatch.getDiagnosticMessageChain(ts.Diagnostics.Imported_via_0_from_file_1, [`"D"`, "c.ts"]), + ts.tscWatch.getDiagnosticMessageChain(ts.Diagnostics.Root_file_specified_for_compilation) + ]) + ])), relatedInformation: undefined - }] - ); + }]); }); it("should fail when module name in 'require' calls has inconsistent casing", () => { - const files = new Map(getEntries({ + const files = new ts.Map(ts.getEntries({ "moduleA.ts": `import a = require("./ModuleC")`, "moduleB.ts": `import a = require("./moduleC")`, "moduleC.ts": "export var x" })); - test( - files, - { module: ModuleKind.CommonJS, forceConsistentCasingInFileNames: true }, - "", - /*useCaseSensitiveFileNames*/ false, - ["moduleA.ts", "moduleB.ts", "moduleC.ts"], - program => { + test(files, { module: ts.ModuleKind.CommonJS, forceConsistentCasingInFileNames: true }, "", + /*useCaseSensitiveFileNames*/ false, ["moduleA.ts", "moduleB.ts", "moduleC.ts"], program => { const importInA = { - ...tscWatch.getDiagnosticOfFileFromProgram( - program, - "moduleA.ts", - `import a = require("./ModuleC")`.indexOf(`"./ModuleC"`), - `"./ModuleC"`.length, - Diagnostics.File_is_included_via_import_here, - ), + ...ts.tscWatch.getDiagnosticOfFileFromProgram(program, "moduleA.ts", `import a = require("./ModuleC")`.indexOf(`"./ModuleC"`), `"./ModuleC"`.length, ts.Diagnostics.File_is_included_via_import_here), reportsUnnecessary: undefined, reportsDeprecated: undefined }; const importInB = { - ...tscWatch.getDiagnosticOfFileFromProgram( - program, - "moduleB.ts", - `import a = require("./moduleC")`.indexOf(`"./moduleC"`), - `"./moduleC"`.length, - Diagnostics.File_is_included_via_import_here, - ), + ...ts.tscWatch.getDiagnosticOfFileFromProgram(program, "moduleB.ts", `import a = require("./moduleC")`.indexOf(`"./moduleC"`), `"./moduleC"`.length, ts.Diagnostics.File_is_included_via_import_here), reportsUnnecessary: undefined, reportsDeprecated: undefined }; - const importHereInA = tscWatch.getDiagnosticMessageChain(Diagnostics.Imported_via_0_from_file_1, [`"./ModuleC"`, "moduleA.ts"]); - const importHereInB = tscWatch.getDiagnosticMessageChain(Diagnostics.Imported_via_0_from_file_1, [`"./moduleC"`, "moduleB.ts"]); - const details = [tscWatch.getDiagnosticMessageChain( - Diagnostics.The_file_is_in_the_program_because_Colon, - emptyArray, - [importHereInA, importHereInB, tscWatch.getDiagnosticMessageChain(Diagnostics.Root_file_specified_for_compilation)] - )]; + const importHereInA = ts.tscWatch.getDiagnosticMessageChain(ts.Diagnostics.Imported_via_0_from_file_1, [`"./ModuleC"`, "moduleA.ts"]); + const importHereInB = ts.tscWatch.getDiagnosticMessageChain(ts.Diagnostics.Imported_via_0_from_file_1, [`"./moduleC"`, "moduleB.ts"]); + const details = [ts.tscWatch.getDiagnosticMessageChain(ts.Diagnostics.The_file_is_in_the_program_because_Colon, ts.emptyArray, [importHereInA, importHereInB, ts.tscWatch.getDiagnosticMessageChain(ts.Diagnostics.Root_file_specified_for_compilation)])]; return [ { - ...tscWatch.getDiagnosticOfFileFrom( - importInA.file, - importInA.start, - importInA.length, - tscWatch.getDiagnosticMessageChain( - Diagnostics.Already_included_file_name_0_differs_from_file_name_1_only_in_casing, - ["ModuleC.ts", "moduleC.ts" ], - details, - ) - ), + ...ts.tscWatch.getDiagnosticOfFileFrom(importInA.file, importInA.start, importInA.length, ts.tscWatch.getDiagnosticMessageChain(ts.Diagnostics.Already_included_file_name_0_differs_from_file_name_1_only_in_casing, ["ModuleC.ts", "moduleC.ts"], details)), relatedInformation: [importInB] }, { - ...tscWatch.getDiagnosticOfFileFrom( - importInB.file, - importInB.start, - importInB.length, - tscWatch.getDiagnosticMessageChain( - Diagnostics.File_name_0_differs_from_already_included_file_name_1_only_in_casing, - ["moduleC.ts", "ModuleC.ts"], - details, - ) - ), + ...ts.tscWatch.getDiagnosticOfFileFrom(importInB.file, importInB.start, importInB.length, ts.tscWatch.getDiagnosticMessageChain(ts.Diagnostics.File_name_0_differs_from_already_included_file_name_1_only_in_casing, ["moduleC.ts", "ModuleC.ts"], details)), relatedInformation: [importInA] } ]; - } - ); }); + }); it("should fail when module names in 'require' calls has inconsistent casing and current directory has uppercase chars", () => { - const files = new Map(getEntries({ + const files = new ts.Map(ts.getEntries({ "/a/B/c/moduleA.ts": `import a = require("./ModuleC")`, "/a/B/c/moduleB.ts": `import a = require("./moduleC")`, "/a/B/c/moduleC.ts": "export var x", @@ -836,51 +693,25 @@ import a = require("./moduleA"); import b = require("./moduleB"); ` })); - test( - files, - { module: ModuleKind.CommonJS, forceConsistentCasingInFileNames: true }, - "/a/B/c", - /*useCaseSensitiveFileNames*/ false, - ["moduleD.ts"], - program => [{ - ...tscWatch.getDiagnosticOfFileFromProgram( - program, - "moduleB.ts", - `import a = require("./moduleC")`.indexOf(`"./moduleC"`), - `"./moduleC"`.length, - tscWatch.getDiagnosticMessageChain( - Diagnostics.File_name_0_differs_from_already_included_file_name_1_only_in_casing, - ["/a/B/c/moduleC.ts", "/a/B/c/ModuleC.ts"], - [ - tscWatch.getDiagnosticMessageChain( - Diagnostics.The_file_is_in_the_program_because_Colon, - emptyArray, - [ - tscWatch.getDiagnosticMessageChain(Diagnostics.Imported_via_0_from_file_1, [`"./ModuleC"`, "/a/B/c/moduleA.ts"]), - tscWatch.getDiagnosticMessageChain(Diagnostics.Imported_via_0_from_file_1, [`"./moduleC"`, "/a/B/c/moduleB.ts"]) - ] - ) - ], - ) - ), + test(files, { module: ts.ModuleKind.CommonJS, forceConsistentCasingInFileNames: true }, "/a/B/c", + /*useCaseSensitiveFileNames*/ false, ["moduleD.ts"], program => [{ + ...ts.tscWatch.getDiagnosticOfFileFromProgram(program, "moduleB.ts", `import a = require("./moduleC")`.indexOf(`"./moduleC"`), `"./moduleC"`.length, ts.tscWatch.getDiagnosticMessageChain(ts.Diagnostics.File_name_0_differs_from_already_included_file_name_1_only_in_casing, ["/a/B/c/moduleC.ts", "/a/B/c/ModuleC.ts"], [ + ts.tscWatch.getDiagnosticMessageChain(ts.Diagnostics.The_file_is_in_the_program_because_Colon, ts.emptyArray, [ + ts.tscWatch.getDiagnosticMessageChain(ts.Diagnostics.Imported_via_0_from_file_1, [`"./ModuleC"`, "/a/B/c/moduleA.ts"]), + ts.tscWatch.getDiagnosticMessageChain(ts.Diagnostics.Imported_via_0_from_file_1, [`"./moduleC"`, "/a/B/c/moduleB.ts"]) + ]) + ])), relatedInformation: [ { - ...tscWatch.getDiagnosticOfFileFromProgram( - program, - "moduleA.ts", - `import a = require("./ModuleC")`.indexOf(`"./ModuleC"`), - `"./ModuleC"`.length, - Diagnostics.File_is_included_via_import_here, - ), + ...ts.tscWatch.getDiagnosticOfFileFromProgram(program, "moduleA.ts", `import a = require("./ModuleC")`.indexOf(`"./ModuleC"`), `"./ModuleC"`.length, ts.Diagnostics.File_is_included_via_import_here), reportsUnnecessary: undefined, reportsDeprecated: undefined } ] - }] - ); + }]); }); it("should not fail when module names in 'require' calls has consistent casing and current directory has uppercase chars", () => { - const files = new Map(getEntries({ + const files = new ts.Map(ts.getEntries({ "/a/B/c/moduleA.ts": `import a = require("./moduleC")`, "/a/B/c/moduleB.ts": `import a = require("./moduleC")`, "/a/B/c/moduleC.ts": "export var x", @@ -889,30 +720,18 @@ import a = require("./moduleA"); import b = require("./moduleB"); ` })); - test( - files, - { module: ModuleKind.CommonJS, forceConsistentCasingInFileNames: true }, - "/a/B/c", - /*useCaseSensitiveFileNames*/ false, - ["moduleD.ts"], - () => emptyArray - ); + test(files, { module: ts.ModuleKind.CommonJS, forceConsistentCasingInFileNames: true }, "/a/B/c", + /*useCaseSensitiveFileNames*/ false, ["moduleD.ts"], () => ts.emptyArray); }); it("should succeed when the two files in program differ only in drive letter in their names", () => { - const files = new Map(getEntries({ + const files = new ts.Map(ts.getEntries({ "d:/someFolder/moduleA.ts": `import a = require("D:/someFolder/moduleC")`, "d:/someFolder/moduleB.ts": `import a = require("./moduleC")`, "D:/someFolder/moduleC.ts": "export const x = 10", })); - test( - files, - { module: ModuleKind.CommonJS, forceConsistentCasingInFileNames: true }, - "d:/someFolder", - /*useCaseSensitiveFileNames*/ false, - ["d:/someFolder/moduleA.ts", "d:/someFolder/moduleB.ts"], - () => emptyArray - ); + test(files, { module: ts.ModuleKind.CommonJS, forceConsistentCasingInFileNames: true }, "d:/someFolder", + /*useCaseSensitiveFileNames*/ false, ["d:/someFolder/moduleA.ts", "d:/someFolder/moduleB.ts"], () => ts.emptyArray); }); }); @@ -927,18 +746,18 @@ import b = require("./moduleB"); const file2: File = { name: "/root/folder2/file2.ts" }; const file3: File = { name: "/root/folder2/file3.ts" }; const host = createModuleResolutionHost(hasDirectoryExists, file1, file2, file3); - for (const moduleResolution of [ ModuleResolutionKind.NodeJs, ModuleResolutionKind.Classic ]) { - const options: CompilerOptions = { moduleResolution, baseUrl: "/root" }; + for (const moduleResolution of [ts.ModuleResolutionKind.NodeJs, ts.ModuleResolutionKind.Classic]) { + const options: ts.CompilerOptions = { moduleResolution, baseUrl: "/root" }; { - const result = resolveModuleName("folder2/file2", file1.name, options, host); + const result = ts.resolveModuleName("folder2/file2", file1.name, options, host); checkResolvedModuleWithFailedLookupLocations(result, createResolvedModule(file2.name), []); } { - const result = resolveModuleName("./file3", file2.name, options, host); + const result = ts.resolveModuleName("./file3", file2.name, options, host); checkResolvedModuleWithFailedLookupLocations(result, createResolvedModule(file3.name), []); } { - const result = resolveModuleName("/root/folder1/file1", file2.name, options, host); + const result = ts.resolveModuleName("/root/folder1/file1", file2.name, options, host); checkResolvedModuleWithFailedLookupLocations(result, createResolvedModule(file1.name), []); } } @@ -958,7 +777,7 @@ import b = require("./moduleB"); const m3Typings: File = { name: "/root/m3/dist/typings.d.ts" }; const m4: File = { name: "/root/node_modules/m4.ts" }; // fallback to node - const options: CompilerOptions = { moduleResolution: ModuleResolutionKind.NodeJs, baseUrl: "/root" }; + const options: ts.CompilerOptions = { moduleResolution: ts.ModuleResolutionKind.NodeJs, baseUrl: "/root" }; const host = createModuleResolutionHost(hasDirectoryExists, main, m1, m2, m3, m3Typings, m4); check("m1", main, m1); @@ -967,7 +786,7 @@ import b = require("./moduleB"); check("m4", main, m4, /*isExternalLibraryImport*/ true); function check(name: string, caller: File, expected: File, isExternalLibraryImport = false) { - const result = resolveModuleName(name, caller.name, options, host); + const result = ts.resolveModuleName(name, caller.name, options, host); checkResolvedModule(result.resolvedModule, createResolvedModule(expected.name, isExternalLibraryImport)); } } @@ -982,14 +801,14 @@ import b = require("./moduleB"); const m1: File = { name: "/root/x/m1.ts" }; // load from base url const m2: File = { name: "/m2.ts" }; // fallback to classic - const options: CompilerOptions = { moduleResolution: ModuleResolutionKind.Classic, baseUrl: "/root/x", jsx: JsxEmit.React }; + const options: ts.CompilerOptions = { moduleResolution: ts.ModuleResolutionKind.Classic, baseUrl: "/root/x", jsx: ts.JsxEmit.React }; const host = createModuleResolutionHost(hasDirectoryExists, main, m1, m2); check("m1", main, m1); check("m2", main, m2); function check(name: string, caller: File, expected: File) { - const result = resolveModuleName(name, caller.name, options, host); + const result = ts.resolveModuleName(name, caller.name, options, host); checkResolvedModule(result.resolvedModule, createResolvedModule(expected.name)); } } @@ -1011,10 +830,10 @@ import b = require("./moduleB"); const file6: File = { name: "/root/node_modules/file6.ts" }; // fallback to node const host = createModuleResolutionHost(hasDirectoryExists, file1, file2, file3, file4, file4Typings, file5, file6); - const options: CompilerOptions = { - moduleResolution: ModuleResolutionKind.NodeJs, + const options: ts.CompilerOptions = { + moduleResolution: ts.ModuleResolutionKind.NodeJs, baseUrl: "/root", - jsx: JsxEmit.React, + jsx: ts.JsxEmit.React, paths: { "*": [ "*", @@ -1140,7 +959,7 @@ import b = require("./moduleB"); ], /*isExternalLibraryImport*/ true); function check(name: string, expected: File, expectedFailedLookups: string[], isExternalLibraryImport = false) { - const result = resolveModuleName(name, main.name, options, host); + const result = ts.resolveModuleName(name, main.name, options, host); checkResolvedModuleWithFailedLookupLocations(result, createResolvedModule(expected.name, isExternalLibraryImport), expectedFailedLookups); } } @@ -1158,10 +977,10 @@ import b = require("./moduleB"); const file3: File = { name: "/folder1/file3.ts" }; // fallback to classic const host = createModuleResolutionHost(hasDirectoryExists, file1, file2, file3); - const options: CompilerOptions = { - moduleResolution: ModuleResolutionKind.Classic, + const options: ts.CompilerOptions = { + moduleResolution: ts.ModuleResolutionKind.Classic, baseUrl: "/root", - jsx: JsxEmit.React, + jsx: ts.JsxEmit.React, paths: { "*": [ "*", @@ -1203,7 +1022,7 @@ import b = require("./moduleB"); ]); function check(name: string, expected: File, expectedFailedLookups: string[]) { - const result = resolveModuleName(name, main.name, options, host); + const result = ts.resolveModuleName(name, main.name, options, host); checkResolvedModuleWithFailedLookupLocations(result, createResolvedModule(expected.name), expectedFailedLookups); } } @@ -1219,8 +1038,8 @@ import b = require("./moduleB"); const file2: File = { name: "/root/generated/folder1/file2.ts" }; const file3: File = { name: "/root/generated/folder2/file3.ts" }; const host = createModuleResolutionHost(hasDirectoryExists, file1, file1_1, file2, file3); - const options: CompilerOptions = { - moduleResolution: ModuleResolutionKind.NodeJs, + const options: ts.CompilerOptions = { + moduleResolution: ts.ModuleResolutionKind.NodeJs, rootDirs: [ "/root", "/root/generated/" @@ -1276,7 +1095,7 @@ import b = require("./moduleB"); ]); function check(name: string, container: File, expected: File, expectedFailedLookups: string[]) { - const result = resolveModuleName(name, container.name, options, host); + const result = ts.resolveModuleName(name, container.name, options, host); checkResolvedModuleWithFailedLookupLocations(result, createResolvedModule(expected.name), expectedFailedLookups); } } @@ -1291,9 +1110,9 @@ import b = require("./moduleB"); const file3: File = { name: "/root/generated/folder2/file3.ts" }; const file4: File = { name: "/folder1/file1_1.ts" }; const host = createModuleResolutionHost(hasDirectoryExists, file1, file2, file3, file4); - const options: CompilerOptions = { - moduleResolution: ModuleResolutionKind.Classic, - jsx: JsxEmit.React, + const options: ts.CompilerOptions = { + moduleResolution: ts.ModuleResolutionKind.Classic, + jsx: ts.JsxEmit.React, rootDirs: [ "/root", "/root/generated/" @@ -1330,7 +1149,7 @@ import b = require("./moduleB"); ]); function check(name: string, container: File, expected: File, expectedFailedLookups: string[]) { - const result = resolveModuleName(name, container.name, options, host); + const result = ts.resolveModuleName(name, container.name, options, host); checkResolvedModuleWithFailedLookupLocations(result, createResolvedModule(expected.name), expectedFailedLookups); } } @@ -1345,14 +1164,14 @@ import b = require("./moduleB"); const libsPackage: File = { name: "/root/src/libs/guid/package.json", content: JSON.stringify({ typings: "dist/guid.d.ts" }) }; const libsTypings: File = { name: "/root/src/libs/guid/dist/guid.d.ts" }; const host = createModuleResolutionHost(hasDirectoryExists, app, libsPackage, libsTypings); - const options: CompilerOptions = { - moduleResolution: ModuleResolutionKind.NodeJs, + const options: ts.CompilerOptions = { + moduleResolution: ts.ModuleResolutionKind.NodeJs, baseUrl: "/root", paths: { "libs/guid": [ "src/libs/guid" ] } }; - const result = resolveModuleName("libs/guid", app.name, options, host); + const result = ts.resolveModuleName("libs/guid", app.name, options, host); checkResolvedModuleWithFailedLookupLocations(result, createResolvedModule(libsTypings.name), [ // first try to load module as file "/root/src/libs/guid.ts", @@ -1365,13 +1184,13 @@ import b = require("./moduleB"); describe("unittests:: moduleResolution:: ModuleResolutionHost.directoryExists", () => { it("No 'fileExists' calls if containing directory is missing", () => { - const host: ModuleResolutionHost = { - readFile: notImplemented, - fileExists: notImplemented, + const host: ts.ModuleResolutionHost = { + readFile: ts.notImplemented, + fileExists: ts.notImplemented, directoryExists: _ => false }; - const result = resolveModuleName("someName", "/a/b/c/d", { moduleResolution: ModuleResolutionKind.NodeJs }, host); + const result = ts.resolveModuleName("someName", "/a/b/c/d", { moduleResolution: ts.ModuleResolutionKind.NodeJs }, host); assert(!result.resolvedModule); }); }); @@ -1379,7 +1198,7 @@ import b = require("./moduleB"); describe("unittests:: moduleResolution:: Type reference directive resolution: ", () => { function testWorker(hasDirectoryExists: boolean, typesRoot: string | undefined, typeDirective: string, primary: boolean, initialFile: File, targetFile: File, ...otherFiles: File[]) { const host = createModuleResolutionHost(hasDirectoryExists, ...[initialFile, targetFile].concat(...otherFiles)); - const result = resolveTypeReferenceDirective(typeDirective, initialFile.name, typesRoot ? { typeRoots: [typesRoot] } : {}, host); + const result = ts.resolveTypeReferenceDirective(typeDirective, initialFile.name, typesRoot ? { typeRoots: [typesRoot] } : {}, host); assert(result.resolvedTypeReferenceDirective!.resolvedFileName !== undefined, "expected type directive to be resolved"); assert.equal(result.resolvedTypeReferenceDirective!.resolvedFileName, targetFile.name, "unexpected result of type reference resolution"); assert.equal(result.resolvedTypeReferenceDirective!.primary, primary, "unexpected 'primary' value"); @@ -1468,13 +1287,13 @@ import b = require("./moduleB"); const f4 = { name: "/root/src/a/b/c/d/f/node_modules/lib/index.d.ts", content: `declare var x: number;` }; const files = [f1, f2, f3, f4]; - const names = map(files, f => f.name); - const sourceFiles = arrayToMap(map(files, f => createSourceFile(f.name, f.content, ScriptTarget.ES2015)), f => f.fileName); - const compilerHost: CompilerHost = { + const names = ts.map(files, f => f.name); + const sourceFiles = ts.arrayToMap(ts.map(files, f => ts.createSourceFile(f.name, f.content, ts.ScriptTarget.ES2015)), f => f.fileName); + const compilerHost: ts.CompilerHost = { fileExists: fileName => sourceFiles.has(fileName), getSourceFile: fileName => sourceFiles.get(fileName), getDefaultLibFileName: () => "lib.d.ts", - writeFile: notImplemented, + writeFile: ts.notImplemented, getCurrentDirectory: () => "/", getDirectories: () => [], getCanonicalFileName: f => f.toLowerCase(), @@ -1485,12 +1304,12 @@ import b = require("./moduleB"); return file && file.text; }, }; - const program1 = createProgram(names, {}, compilerHost); + const program1 = ts.createProgram(names, {}, compilerHost); const diagnostics1 = program1.getOptionsDiagnostics(); assert.equal(diagnostics1.length, 1, "expected one diagnostic"); - const program2 = createProgram(names, {}, compilerHost, program1); - assert.isTrue(program2.structureIsReused === StructureIsReused.Completely); + const program2 = ts.createProgram(names, {}, compilerHost, program1); + assert.isTrue(program2.structureIsReused === ts.StructureIsReused.Completely); const diagnostics2 = program2.getOptionsDiagnostics(); assert.equal(diagnostics2.length, 1, "expected one diagnostic"); assert.deepEqual(diagnostics1[0].messageText, diagnostics2[0].messageText, "expected one diagnostic"); @@ -1508,21 +1327,21 @@ import b = require("./moduleB"); export function foo(): Stat; }` }; - const file = createSourceFile(f.name, f.content, ScriptTarget.ES2015); - const compilerHost: CompilerHost = { + const file = ts.createSourceFile(f.name, f.content, ts.ScriptTarget.ES2015); + const compilerHost: ts.CompilerHost = { fileExists: fileName => fileName === file.fileName, getSourceFile: fileName => fileName === file.fileName ? file : undefined, getDefaultLibFileName: () => "lib.d.ts", - writeFile: notImplemented, + writeFile: ts.notImplemented, getCurrentDirectory: () => "/", getDirectories: () => [], getCanonicalFileName: f => f.toLowerCase(), getNewLine: () => "\r\n", useCaseSensitiveFileNames: () => false, readFile: fileName => fileName === file.fileName ? file.text : undefined, - resolveModuleNames: notImplemented, + resolveModuleNames: ts.notImplemented, }; - createProgram([f.name], {}, compilerHost); + ts.createProgram([f.name], {}, compilerHost); }); it("Modules in .ts file are not checked in the same file", () => { @@ -1537,12 +1356,12 @@ import b = require("./moduleB"); export function foo(): Stat; }` }; - const file = createSourceFile(f.name, f.content, ScriptTarget.ES2015); - const compilerHost: CompilerHost = { + const file = ts.createSourceFile(f.name, f.content, ts.ScriptTarget.ES2015); + const compilerHost: ts.CompilerHost = { fileExists: fileName => fileName === file.fileName, getSourceFile: fileName => fileName === file.fileName ? file : undefined, getDefaultLibFileName: () => "lib.d.ts", - writeFile: notImplemented, + writeFile: ts.notImplemented, getCurrentDirectory: () => "/", getDirectories: () => [], getCanonicalFileName: f => f.toLowerCase(), @@ -1554,7 +1373,7 @@ import b = require("./moduleB"); return [undefined!]; // TODO: GH#18217 } }; - createProgram([f.name], {}, compilerHost); + ts.createProgram([f.name], {}, compilerHost); }); describe("can be resolved when typeReferenceDirective is relative and in a sibling folder", () => { const initialFile = { name: "/root/src/background/app.ts" }; diff --git a/src/testRunner/unittests/parsePseudoBigInt.ts b/src/testRunner/unittests/parsePseudoBigInt.ts index db1a841dc2b74..6f17c2cf73b9b 100644 --- a/src/testRunner/unittests/parsePseudoBigInt.ts +++ b/src/testRunner/unittests/parsePseudoBigInt.ts @@ -2,17 +2,15 @@ namespace ts { describe("unittests:: BigInt literal base conversions", () => { describe("parsePseudoBigInt", () => { const testNumbers: number[] = []; - for (let i = 0; i < 1e3; i++) testNumbers.push(i); + for (let i = 0; i < 1e3; i++) + testNumbers.push(i); for (let bits = 0; bits <= 52; bits++) { testNumbers.push(2 ** bits, 2 ** bits - 1); } it("can strip base-10 strings", () => { for (const testNumber of testNumbers) { for (let leadingZeros = 0; leadingZeros < 10; leadingZeros++) { - assert.equal( - parsePseudoBigInt("0".repeat(leadingZeros) + testNumber + "n"), - String(testNumber) - ); + assert.equal(ts.parsePseudoBigInt("0".repeat(leadingZeros) + testNumber + "n"), String(testNumber)); } } }); @@ -21,7 +19,7 @@ namespace ts { for (let leadingZeros = 0; leadingZeros < 10; leadingZeros++) { const binary = "0".repeat(leadingZeros) + testNumber.toString(2) + "n"; for (const prefix of ["0b", "0B"]) { - assert.equal(parsePseudoBigInt(prefix + binary), String(testNumber)); + assert.equal(ts.parsePseudoBigInt(prefix + binary), String(testNumber)); } } } @@ -31,7 +29,7 @@ namespace ts { for (let leadingZeros = 0; leadingZeros < 10; leadingZeros++) { const octal = "0".repeat(leadingZeros) + testNumber.toString(8) + "n"; for (const prefix of ["0o", "0O"]) { - assert.equal(parsePseudoBigInt(prefix + octal), String(testNumber)); + assert.equal(ts.parsePseudoBigInt(prefix + octal), String(testNumber)); } } } @@ -42,29 +40,17 @@ namespace ts { const hex = "0".repeat(leadingZeros) + testNumber.toString(16) + "n"; for (const prefix of ["0x", "0X"]) { for (const hexCase of [hex.toLowerCase(), hex.toUpperCase()]) { - assert.equal(parsePseudoBigInt(prefix + hexCase), String(testNumber)); + assert.equal(ts.parsePseudoBigInt(prefix + hexCase), String(testNumber)); } } } } }); it("can parse large literals", () => { - assert.equal( - parsePseudoBigInt("123456789012345678901234567890n"), - "123456789012345678901234567890" - ); - assert.equal( - parsePseudoBigInt("0b1100011101110100100001111111101101100001101110011111000001110111001001110001111110000101011010010n"), - "123456789012345678901234567890" - ); - assert.equal( - parsePseudoBigInt("0o143564417755415637016711617605322n"), - "123456789012345678901234567890" - ); - assert.equal( - parsePseudoBigInt("0x18ee90ff6c373e0ee4e3f0ad2n"), - "123456789012345678901234567890" - ); + assert.equal(ts.parsePseudoBigInt("123456789012345678901234567890n"), "123456789012345678901234567890"); + assert.equal(ts.parsePseudoBigInt("0b1100011101110100100001111111101101100001101110011111000001110111001001110001111110000101011010010n"), "123456789012345678901234567890"); + assert.equal(ts.parsePseudoBigInt("0o143564417755415637016711617605322n"), "123456789012345678901234567890"); + assert.equal(ts.parsePseudoBigInt("0x18ee90ff6c373e0ee4e3f0ad2n"), "123456789012345678901234567890"); }); }); }); diff --git a/src/testRunner/unittests/paths.ts b/src/testRunner/unittests/paths.ts index cf2bde3acbee2..7ba18cba21768 100644 --- a/src/testRunner/unittests/paths.ts +++ b/src/testRunner/unittests/paths.ts @@ -290,21 +290,9 @@ describe("unittests:: core paths", () => { assert.strictEqual(ts.getRelativePathFromDirectory("file:///c:", "file:///d:", /*ignoreCase*/ false), "file:///d:/"); }); it("toFileNameLowerCase", () => { - assert.strictEqual( - ts.toFileNameLowerCase("/user/UserName/projects/Project/file.ts"), - "/user/username/projects/project/file.ts" - ); - assert.strictEqual( - ts.toFileNameLowerCase("/user/UserName/projects/projectß/file.ts"), - "/user/username/projects/projectß/file.ts" - ); - assert.strictEqual( - ts.toFileNameLowerCase("/user/UserName/projects/İproject/file.ts"), - "/user/username/projects/İproject/file.ts" - ); - assert.strictEqual( - ts.toFileNameLowerCase("/user/UserName/projects/ı/file.ts"), - "/user/username/projects/ı/file.ts" - ); + assert.strictEqual(ts.toFileNameLowerCase("/user/UserName/projects/Project/file.ts"), "/user/username/projects/project/file.ts"); + assert.strictEqual(ts.toFileNameLowerCase("/user/UserName/projects/projectß/file.ts"), "/user/username/projects/projectß/file.ts"); + assert.strictEqual(ts.toFileNameLowerCase("/user/UserName/projects/İproject/file.ts"), "/user/username/projects/İproject/file.ts"); + assert.strictEqual(ts.toFileNameLowerCase("/user/UserName/projects/ı/file.ts"), "/user/username/projects/ı/file.ts"); }); }); diff --git a/src/testRunner/unittests/printer.ts b/src/testRunner/unittests/printer.ts index 51e1727e7ef82..ddf62ce0467de 100644 --- a/src/testRunner/unittests/printer.ts +++ b/src/testRunner/unittests/printer.ts @@ -1,10 +1,9 @@ namespace ts { describe("unittests:: PrinterAPI", () => { function makePrintsCorrectly(prefix: string) { - return function printsCorrectly(name: string, options: PrinterOptions, printCallback: (printer: Printer) => string) { + return function printsCorrectly(name: string, options: ts.PrinterOptions, printCallback: (printer: ts.Printer) => string) { it(name, () => { - Harness.Baseline.runBaseline(`printerApi/${prefix}.${name}.js`, - printCallback(createPrinter({ newLine: NewLineKind.CarriageReturnLineFeed, ...options }))); + Harness.Baseline.runBaseline(`printerApi/${prefix}.${name}.js`, printCallback(ts.createPrinter({ newLine: ts.NewLineKind.CarriageReturnLineFeed, ...options }))); }); }; } @@ -13,9 +12,9 @@ namespace ts { const printsCorrectly = makePrintsCorrectly("printsFileCorrectly"); describe("comment handling", () => { // Avoid eagerly creating the sourceFile so that `createSourceFile` doesn't run unless one of these tests is run. - let sourceFile: SourceFile; + let sourceFile: ts.SourceFile; before(() => { - sourceFile = createSourceFile("source.ts", ` + sourceFile = ts.createSourceFile("source.ts", ` interface A { // comment1 readonly prop?: T; @@ -49,7 +48,7 @@ namespace ts { // comment10 function functionWithDefaultArgValue(argument: string = "defaultValue"): void { } - `, ScriptTarget.ES2015); + `, ts.ScriptTarget.ES2015); }); printsCorrectly("default", {}, printer => printer.printFile(sourceFile)); printsCorrectly("removeComments", { removeComments: true }, printer => printer.printFile(sourceFile)); @@ -57,39 +56,26 @@ namespace ts { // https://github.com/microsoft/TypeScript/issues/14948 // eslint-disable-next-line no-template-curly-in-string - printsCorrectly("templateLiteral", {}, printer => printer.printFile(createSourceFile("source.ts", "let greeting = `Hi ${name}, how are you?`;", ScriptTarget.ES2017))); + printsCorrectly("templateLiteral", {}, printer => printer.printFile(ts.createSourceFile("source.ts", "let greeting = `Hi ${name}, how are you?`;", ts.ScriptTarget.ES2017))); // https://github.com/microsoft/TypeScript/issues/18071 - printsCorrectly("regularExpressionLiteral", {}, printer => printer.printFile(createSourceFile("source.ts", "let regex = /abc/;", ScriptTarget.ES2017))); + printsCorrectly("regularExpressionLiteral", {}, printer => printer.printFile(ts.createSourceFile("source.ts", "let regex = /abc/;", ts.ScriptTarget.ES2017))); // https://github.com/microsoft/TypeScript/issues/22239 - printsCorrectly("importStatementRemoveComments", { removeComments: true }, printer => printer.printFile(createSourceFile("source.ts", "import {foo} from 'foo';", ScriptTarget.ESNext))); - printsCorrectly("classHeritageClauses", {}, printer => printer.printFile(createSourceFile( - "source.ts", - `class A extends B implements C implements D {}`, - ScriptTarget.ES2017 - ))); + printsCorrectly("importStatementRemoveComments", { removeComments: true }, printer => printer.printFile(ts.createSourceFile("source.ts", "import {foo} from 'foo';", ts.ScriptTarget.ESNext))); + printsCorrectly("classHeritageClauses", {}, printer => printer.printFile(ts.createSourceFile("source.ts", `class A extends B implements C implements D {}`, ts.ScriptTarget.ES2017))); // https://github.com/microsoft/TypeScript/issues/35093 - printsCorrectly("definiteAssignmentAssertions", {}, printer => printer.printFile(createSourceFile( - "source.ts", - `class A { + printsCorrectly("definiteAssignmentAssertions", {}, printer => printer.printFile(ts.createSourceFile("source.ts", `class A { prop!: string; } - let x!: string;`, - ScriptTarget.ES2017 - ))); + let x!: string;`, ts.ScriptTarget.ES2017))); // https://github.com/microsoft/TypeScript/issues/35054 printsCorrectly("jsx attribute escaping", {}, printer => { - return printer.printFile(createSourceFile( - "source.ts", - String.raw`
`, - ScriptTarget.ESNext, - /*setParentNodes*/ undefined, - ScriptKind.TSX - )); + return printer.printFile(ts.createSourceFile("source.ts", String.raw ``, ts.ScriptTarget.ESNext, + /*setParentNodes*/ undefined, ts.ScriptKind.TSX)); }); }); @@ -100,9 +86,9 @@ namespace ts { "/test.d.ts": `/// \n/// \n/// { const printsCorrectly = makePrintsCorrectly("printsBundleCorrectly"); - let bundle: Bundle; + let bundle: ts.Bundle; before(() => { - bundle = factory.createBundle([ - createSourceFile("a.ts", ` + bundle = ts.factory.createBundle([ + ts.createSourceFile("a.ts", ` /*! [a.ts] */ // comment0 const a = 1; - `, ScriptTarget.ES2015), - createSourceFile("b.ts", ` + `, ts.ScriptTarget.ES2015), + ts.createSourceFile("b.ts", ` /*! [b.ts] */ // comment1 const b = 2; - `, ScriptTarget.ES2015) + `, ts.ScriptTarget.ES2015) ]); }); printsCorrectly("default", {}, printer => printer.printBundle(bundle)); @@ -145,183 +131,87 @@ namespace ts { describe("printNode", () => { const printsCorrectly = makePrintsCorrectly("printsNodeCorrectly"); - printsCorrectly("class", {}, printer => printer.printNode( - EmitHint.Unspecified, - factory.createClassDeclaration( + printsCorrectly("class", {}, printer => printer.printNode(ts.EmitHint.Unspecified, ts.factory.createClassDeclaration( /*decorators*/ undefined, /*modifiers*/ undefined, - /*name*/ factory.createIdentifier("C"), + /*name*/ ts.factory.createIdentifier("C"), /*typeParameters*/ undefined, - /*heritageClauses*/ undefined, - [factory.createPropertyDeclaration( - /*decorators*/ undefined, - factory.createNodeArray([factory.createToken(SyntaxKind.PublicKeyword)]), - factory.createIdentifier("prop"), + /*heritageClauses*/ undefined, [ts.factory.createPropertyDeclaration( + /*decorators*/ undefined, ts.factory.createNodeArray([ts.factory.createToken(ts.SyntaxKind.PublicKeyword)]), ts.factory.createIdentifier("prop"), /*questionToken*/ undefined, /*type*/ undefined, - /*initializer*/ undefined - )] - ), - createSourceFile("source.ts", "", ScriptTarget.ES2015) - )); - - printsCorrectly("namespaceExportDeclaration", {}, printer => printer.printNode( - EmitHint.Unspecified, - factory.createNamespaceExportDeclaration("B"), - createSourceFile("source.ts", "", ScriptTarget.ES2015) - )); - - printsCorrectly("newExpressionWithPropertyAccessOnCallExpression", {}, printer => printer.printNode( - EmitHint.Unspecified, - factory.createNewExpression( - factory.createPropertyAccessExpression( - factory.createCallExpression(factory.createIdentifier("f"), /*typeArguments*/ undefined, /*argumentsArray*/ undefined), - "x"), + /*initializer*/ undefined)]), ts.createSourceFile("source.ts", "", ts.ScriptTarget.ES2015))); + printsCorrectly("namespaceExportDeclaration", {}, printer => printer.printNode(ts.EmitHint.Unspecified, ts.factory.createNamespaceExportDeclaration("B"), ts.createSourceFile("source.ts", "", ts.ScriptTarget.ES2015))); + printsCorrectly("newExpressionWithPropertyAccessOnCallExpression", {}, printer => printer.printNode(ts.EmitHint.Unspecified, ts.factory.createNewExpression(ts.factory.createPropertyAccessExpression(ts.factory.createCallExpression(ts.factory.createIdentifier("f"), /*typeArguments*/ undefined, /*argumentsArray*/ undefined), "x"), /*typeArguments*/ undefined, - /*argumentsArray*/ undefined - ), - createSourceFile("source.ts", "", ScriptTarget.ESNext)) - ); - - printsCorrectly("newExpressionOnConditionalExpression", {}, printer => printer.printNode( - EmitHint.Unspecified, - factory.createNewExpression( - factory.createConditionalExpression( - factory.createIdentifier("x"), factory.createToken(SyntaxKind.QuestionToken), - factory.createIdentifier("y"), factory.createToken(SyntaxKind.ColonToken), - factory.createIdentifier("z")), + /*argumentsArray*/ undefined), ts.createSourceFile("source.ts", "", ts.ScriptTarget.ESNext))); + printsCorrectly("newExpressionOnConditionalExpression", {}, printer => printer.printNode(ts.EmitHint.Unspecified, ts.factory.createNewExpression(ts.factory.createConditionalExpression(ts.factory.createIdentifier("x"), ts.factory.createToken(ts.SyntaxKind.QuestionToken), ts.factory.createIdentifier("y"), ts.factory.createToken(ts.SyntaxKind.ColonToken), ts.factory.createIdentifier("z")), /*typeArguments*/ undefined, - /*argumentsArray*/ undefined - ), - createSourceFile("source.ts", "", ScriptTarget.ESNext)) - ); - - printsCorrectly("emptyGlobalAugmentation", {}, printer => printer.printNode( - EmitHint.Unspecified, - factory.createModuleDeclaration( + /*argumentsArray*/ undefined), ts.createSourceFile("source.ts", "", ts.ScriptTarget.ESNext))); + printsCorrectly("emptyGlobalAugmentation", {}, printer => printer.printNode(ts.EmitHint.Unspecified, ts.factory.createModuleDeclaration( /*decorators*/ undefined, - /*modifiers*/ [factory.createToken(SyntaxKind.DeclareKeyword)], - factory.createIdentifier("global"), - factory.createModuleBlock(emptyArray), - NodeFlags.GlobalAugmentation), - createSourceFile("source.ts", "", ScriptTarget.ES2015) - )); - - printsCorrectly("emptyGlobalAugmentationWithNoDeclareKeyword", {}, printer => printer.printNode( - EmitHint.Unspecified, - factory.createModuleDeclaration( + /*modifiers*/ [ts.factory.createToken(ts.SyntaxKind.DeclareKeyword)], ts.factory.createIdentifier("global"), ts.factory.createModuleBlock(ts.emptyArray), ts.NodeFlags.GlobalAugmentation), ts.createSourceFile("source.ts", "", ts.ScriptTarget.ES2015))); + printsCorrectly("emptyGlobalAugmentationWithNoDeclareKeyword", {}, printer => printer.printNode(ts.EmitHint.Unspecified, ts.factory.createModuleDeclaration( /*decorators*/ undefined, - /*modifiers*/ undefined, - factory.createIdentifier("global"), - factory.createModuleBlock(emptyArray), - NodeFlags.GlobalAugmentation), - createSourceFile("source.ts", "", ScriptTarget.ES2015) - )); + /*modifiers*/ undefined, ts.factory.createIdentifier("global"), ts.factory.createModuleBlock(ts.emptyArray), ts.NodeFlags.GlobalAugmentation), ts.createSourceFile("source.ts", "", ts.ScriptTarget.ES2015))); // https://github.com/Microsoft/TypeScript/issues/15971 - printsCorrectly("classWithOptionalMethodAndProperty", {}, printer => printer.printNode( - EmitHint.Unspecified, - factory.createClassDeclaration( + printsCorrectly("classWithOptionalMethodAndProperty", {}, printer => printer.printNode(ts.EmitHint.Unspecified, ts.factory.createClassDeclaration( /*decorators*/ undefined, - /*modifiers*/ [factory.createToken(SyntaxKind.DeclareKeyword)], - /*name*/ factory.createIdentifier("X"), + /*modifiers*/ [ts.factory.createToken(ts.SyntaxKind.DeclareKeyword)], + /*name*/ ts.factory.createIdentifier("X"), /*typeParameters*/ undefined, - /*heritageClauses*/ undefined, - [ - factory.createMethodDeclaration( + /*heritageClauses*/ undefined, [ + ts.factory.createMethodDeclaration( /*decorators*/ undefined, /*modifiers*/ undefined, /*asteriskToken*/ undefined, - /*name*/ factory.createIdentifier("method"), - /*questionToken*/ factory.createToken(SyntaxKind.QuestionToken), - /*typeParameters*/ undefined, - [], - /*type*/ factory.createKeywordTypeNode(SyntaxKind.VoidKeyword), - /*body*/ undefined - ), - factory.createPropertyDeclaration( + /*name*/ ts.factory.createIdentifier("method"), + /*questionToken*/ ts.factory.createToken(ts.SyntaxKind.QuestionToken), + /*typeParameters*/ undefined, [], + /*type*/ ts.factory.createKeywordTypeNode(ts.SyntaxKind.VoidKeyword), + /*body*/ undefined), + ts.factory.createPropertyDeclaration( /*decorators*/ undefined, /*modifiers*/ undefined, - /*name*/ factory.createIdentifier("property"), - /*questionToken*/ factory.createToken(SyntaxKind.QuestionToken), - /*type*/ factory.createKeywordTypeNode(SyntaxKind.StringKeyword), - /*initializer*/ undefined - ), - ] - ), - createSourceFile("source.ts", "", ScriptTarget.ES2015) - )); + /*name*/ ts.factory.createIdentifier("property"), + /*questionToken*/ ts.factory.createToken(ts.SyntaxKind.QuestionToken), + /*type*/ ts.factory.createKeywordTypeNode(ts.SyntaxKind.StringKeyword), + /*initializer*/ undefined), + ]), ts.createSourceFile("source.ts", "", ts.ScriptTarget.ES2015))); // https://github.com/Microsoft/TypeScript/issues/15651 - printsCorrectly("functionTypes", {}, printer => printer.printNode( - EmitHint.Unspecified, - setEmitFlags(factory.createTupleTypeNode([ - factory.createFunctionTypeNode( - /*typeArguments*/ undefined, - [factory.createParameterDeclaration( + printsCorrectly("functionTypes", {}, printer => printer.printNode(ts.EmitHint.Unspecified, ts.setEmitFlags(ts.factory.createTupleTypeNode([ + ts.factory.createFunctionTypeNode( + /*typeArguments*/ undefined, [ts.factory.createParameterDeclaration( /*decorators*/ undefined, /*modifiers*/ undefined, - /*dotDotDotToken*/ undefined, - factory.createIdentifier("args") - )], - factory.createKeywordTypeNode(SyntaxKind.AnyKeyword) - ), - factory.createFunctionTypeNode( - [factory.createTypeParameterDeclaration(/*modifiers*/ undefined, "T")], - [factory.createParameterDeclaration( + /*dotDotDotToken*/ undefined, ts.factory.createIdentifier("args"))], ts.factory.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword)), + ts.factory.createFunctionTypeNode([ts.factory.createTypeParameterDeclaration(/*modifiers*/ undefined, "T")], [ts.factory.createParameterDeclaration( /*decorators*/ undefined, /*modifiers*/ undefined, - /*dotDotDotToken*/ undefined, - factory.createIdentifier("args") - )], - factory.createKeywordTypeNode(SyntaxKind.AnyKeyword) - ), - factory.createFunctionTypeNode( - /*typeArguments*/ undefined, - [factory.createParameterDeclaration( + /*dotDotDotToken*/ undefined, ts.factory.createIdentifier("args"))], ts.factory.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword)), + ts.factory.createFunctionTypeNode( + /*typeArguments*/ undefined, [ts.factory.createParameterDeclaration( /*decorators*/ undefined, - /*modifiers*/ undefined, - factory.createToken(SyntaxKind.DotDotDotToken), - factory.createIdentifier("args") - )], - factory.createKeywordTypeNode(SyntaxKind.AnyKeyword) - ), - factory.createFunctionTypeNode( - /*typeArguments*/ undefined, - [factory.createParameterDeclaration( + /*modifiers*/ undefined, ts.factory.createToken(ts.SyntaxKind.DotDotDotToken), ts.factory.createIdentifier("args"))], ts.factory.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword)), + ts.factory.createFunctionTypeNode( + /*typeArguments*/ undefined, [ts.factory.createParameterDeclaration( /*decorators*/ undefined, /*modifiers*/ undefined, - /*dotDotDotToken*/ undefined, - factory.createIdentifier("args"), - factory.createToken(SyntaxKind.QuestionToken) - )], - factory.createKeywordTypeNode(SyntaxKind.AnyKeyword) - ), - factory.createFunctionTypeNode( - /*typeArguments*/ undefined, - [factory.createParameterDeclaration( + /*dotDotDotToken*/ undefined, ts.factory.createIdentifier("args"), ts.factory.createToken(ts.SyntaxKind.QuestionToken))], ts.factory.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword)), + ts.factory.createFunctionTypeNode( + /*typeArguments*/ undefined, [ts.factory.createParameterDeclaration( /*decorators*/ undefined, /*modifiers*/ undefined, - /*dotDotDotToken*/ undefined, - factory.createIdentifier("args"), - /*questionToken*/ undefined, - factory.createKeywordTypeNode(SyntaxKind.AnyKeyword) - )], - factory.createKeywordTypeNode(SyntaxKind.AnyKeyword) - ), - factory.createFunctionTypeNode( - /*typeArguments*/ undefined, - [factory.createParameterDeclaration( + /*dotDotDotToken*/ undefined, ts.factory.createIdentifier("args"), + /*questionToken*/ undefined, ts.factory.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword))], ts.factory.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword)), + ts.factory.createFunctionTypeNode( + /*typeArguments*/ undefined, [ts.factory.createParameterDeclaration( /*decorators*/ undefined, /*modifiers*/ undefined, - /*dotDotDotToken*/ undefined, - factory.createObjectBindingPattern([]) - )], - factory.createKeywordTypeNode(SyntaxKind.AnyKeyword) - ), - ]), EmitFlags.SingleLine), - createSourceFile("source.ts", "", ScriptTarget.ES2015) - )); + /*dotDotDotToken*/ undefined, ts.factory.createObjectBindingPattern([]))], ts.factory.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword)), + ]), ts.EmitFlags.SingleLine), ts.createSourceFile("source.ts", "", ts.ScriptTarget.ES2015))); }); }); } diff --git a/src/testRunner/unittests/programApi.ts b/src/testRunner/unittests/programApi.ts index e15ec0bf434d0..3a851070a9035 100644 --- a/src/testRunner/unittests/programApi.ts +++ b/src/testRunner/unittests/programApi.ts @@ -1,19 +1,19 @@ namespace ts { - function verifyMissingFilePaths(missingPaths: readonly Path[], expected: readonly string[]) { + function verifyMissingFilePaths(missingPaths: readonly ts.Path[], expected: readonly string[]) { assert.isDefined(missingPaths); - const map = new Set(expected); + const map = new ts.Set(expected); for (const missing of missingPaths) { const value = map.has(missing); assert.isTrue(value, `${missing} to be ${value === undefined ? "not present" : "present only once"}, in actual: ${missingPaths} expected: ${expected}`); map.delete(missing); } - const notFound = arrayFrom(mapDefinedIterator(map.keys(), k => map.has(k) ? k : undefined)); + const notFound = ts.arrayFrom(ts.mapDefinedIterator(map.keys(), k => map.has(k) ? k : undefined)); assert.equal(notFound.length, 0, `Not found ${notFound} in actual: ${missingPaths} expected: ${expected}`); } describe("unittests:: programApi:: Program.getMissingFilePaths", () => { - const options: CompilerOptions = { + const options: ts.CompilerOptions = { noLib: true, }; @@ -25,53 +25,48 @@ namespace ts { const referenceFileName = "reference.ts"; const referenceFileRelativePath = "./" + referenceFileName; - const referenceFile = new documents.TextDocument(referenceFileName, - "/// \n" + // Absolute + const referenceFile = new documents.TextDocument(referenceFileName, "/// \n" + // Absolute "/// \n" + // Relative "/// \n" + // Unqualified "/// \n" // No extension ); - const testCompilerHost = new fakes.CompilerHost( - vfs.createFromFileSystem( - Harness.IO, - /*ignoreCase*/ true, - { documents: [emptyFile, referenceFile], cwd: "d:\\pretend\\" }), - { newLine: NewLineKind.LineFeed }); + const testCompilerHost = new fakes.CompilerHost(vfs.createFromFileSystem(Harness.IO, + /*ignoreCase*/ true, { documents: [emptyFile, referenceFile], cwd: "d:\\pretend\\" }), { newLine: ts.NewLineKind.LineFeed }); it("handles no missing root files", () => { - const program = createProgram([emptyFileRelativePath], options, testCompilerHost); + const program = ts.createProgram([emptyFileRelativePath], options, testCompilerHost); const missing = program.getMissingFilePaths(); verifyMissingFilePaths(missing, []); }); it("handles missing root file", () => { - const program = createProgram(["./nonexistent.ts"], options, testCompilerHost); + const program = ts.createProgram(["./nonexistent.ts"], options, testCompilerHost); const missing = program.getMissingFilePaths(); verifyMissingFilePaths(missing, ["d:/pretend/nonexistent.ts"]); // Absolute path }); it("handles multiple missing root files", () => { - const program = createProgram(["./nonexistent0.ts", "./nonexistent1.ts"], options, testCompilerHost); + const program = ts.createProgram(["./nonexistent0.ts", "./nonexistent1.ts"], options, testCompilerHost); const missing = program.getMissingFilePaths(); verifyMissingFilePaths(missing, ["d:/pretend/nonexistent0.ts", "d:/pretend/nonexistent1.ts"]); }); it("handles a mix of present and missing root files", () => { - const program = createProgram(["./nonexistent0.ts", emptyFileRelativePath, "./nonexistent1.ts"], options, testCompilerHost); + const program = ts.createProgram(["./nonexistent0.ts", emptyFileRelativePath, "./nonexistent1.ts"], options, testCompilerHost); const missing = program.getMissingFilePaths(); verifyMissingFilePaths(missing, ["d:/pretend/nonexistent0.ts", "d:/pretend/nonexistent1.ts"]); }); it("handles repeatedly specified root files", () => { - const program = createProgram(["./nonexistent.ts", "./nonexistent.ts"], options, testCompilerHost); + const program = ts.createProgram(["./nonexistent.ts", "./nonexistent.ts"], options, testCompilerHost); const missing = program.getMissingFilePaths(); verifyMissingFilePaths(missing, ["d:/pretend/nonexistent.ts"]); }); it("normalizes file paths", () => { - const program0 = createProgram(["./nonexistent.ts", "./NONEXISTENT.ts"], options, testCompilerHost); - const program1 = createProgram(["./NONEXISTENT.ts", "./nonexistent.ts"], options, testCompilerHost); + const program0 = ts.createProgram(["./nonexistent.ts", "./NONEXISTENT.ts"], options, testCompilerHost); + const program1 = ts.createProgram(["./NONEXISTENT.ts", "./nonexistent.ts"], options, testCompilerHost); const missing0 = program0.getMissingFilePaths(); const missing1 = program1.getMissingFilePaths(); assert.equal(missing0.length, 1); @@ -79,7 +74,7 @@ namespace ts { }); it("handles missing triple slash references", () => { - const program = createProgram([referenceFileRelativePath], options, testCompilerHost); + const program = ts.createProgram([referenceFileRelativePath], options, testCompilerHost); const missing = program.getMissingFilePaths(); verifyMissingFilePaths(missing, [ // From absolute reference @@ -104,23 +99,23 @@ namespace ts { bar: string = 'baz'; }`; - const host: CompilerHost = { - getSourceFile: (fileName: string, languageVersion: ScriptTarget, _onError?: (message: string) => void) => { - return fileName === "test.ts" ? createSourceFile(fileName, testSource, languageVersion) : undefined; + const host: ts.CompilerHost = { + getSourceFile: (fileName: string, languageVersion: ts.ScriptTarget, _onError?: (message: string) => void) => { + return fileName === "test.ts" ? ts.createSourceFile(fileName, testSource, languageVersion) : undefined; }, getDefaultLibFileName: () => "", writeFile: (_fileName, _content) => { throw new Error("unsupported"); }, - getCurrentDirectory: () => sys.getCurrentDirectory(), - getCanonicalFileName: fileName => sys.useCaseSensitiveFileNames ? fileName : fileName.toLowerCase(), - getNewLine: () => sys.newLine, - useCaseSensitiveFileNames: () => sys.useCaseSensitiveFileNames, + getCurrentDirectory: () => ts.sys.getCurrentDirectory(), + getCanonicalFileName: fileName => ts.sys.useCaseSensitiveFileNames ? fileName : fileName.toLowerCase(), + getNewLine: () => ts.sys.newLine, + useCaseSensitiveFileNames: () => ts.sys.useCaseSensitiveFileNames, fileExists: fileName => fileName === "test.ts", readFile: fileName => fileName === "test.ts" ? testSource : undefined, resolveModuleNames: (_moduleNames: string[], _containingFile: string) => { throw new Error("unsupported"); }, getDirectories: _path => { throw new Error("unsupported"); }, }; - const program = createProgram(["test.ts"], { module: ModuleKind.ES2015 }, host); + const program = ts.createProgram(["test.ts"], { module: ts.ModuleKind.ES2015 }, host); assert(program.getSourceFiles().length === 1, "expected 'getSourceFiles' length to be 1"); assert(program.getMissingFilePaths().length === 0, "expected 'getMissingFilePaths' length to be 0"); assert((program.getFileProcessingDiagnostics()?.length || 0) === 0, "expected 'getFileProcessingDiagnostics' length to be 0"); @@ -140,7 +135,7 @@ namespace ts { const fooIndex = new documents.TextDocument("/node_modules/foo/index.d.ts", fooIndexText); const fs = vfs.createFromFileSystem(Harness.IO, /*ignoreCase*/ false, { documents: [a, bar, barFooPackage, barFooIndex, fooPackage, fooIndex], cwd: "/" }); - const program = createProgram(["/a.ts"], emptyOptions, new fakes.CompilerHost(fs, { newLine: NewLineKind.LineFeed })); + const program = ts.createProgram(["/a.ts"], ts.emptyOptions, new fakes.CompilerHost(fs, { newLine: ts.NewLineKind.LineFeed })); assertIsExternal(program, [a, bar, barFooIndex, fooIndex], f => f !== a); }); @@ -148,11 +143,11 @@ namespace ts { const a = new documents.TextDocument("/a.ts", '/// '); const fooIndex = new documents.TextDocument("/node_modules/foo/index.d.ts", "declare const foo: number;"); const fs = vfs.createFromFileSystem(Harness.IO, /*ignoreCase*/ false, { documents: [a, fooIndex], cwd: "/" }); - const program = createProgram(["/a.ts"], emptyOptions, new fakes.CompilerHost(fs, { newLine: NewLineKind.LineFeed })); + const program = ts.createProgram(["/a.ts"], ts.emptyOptions, new fakes.CompilerHost(fs, { newLine: ts.NewLineKind.LineFeed })); assertIsExternal(program, [a, fooIndex], f => f !== a); }); - function assertIsExternal(program: Program, files: readonly documents.TextDocument[], isExternalExpected: (file: documents.TextDocument) => boolean): void { + function assertIsExternal(program: ts.Program, files: readonly documents.TextDocument[], isExternalExpected: (file: documents.TextDocument) => boolean): void { for (const file of files) { const actual = program.isSourceFileFromExternalLibrary(program.getSourceFile(file.file)!); const expected = isExternalExpected(file); @@ -167,10 +162,10 @@ namespace ts { const pkg = new documents.TextDocument("/package.json", '{"version": "1.0.0"}'); const fs = vfs.createFromFileSystem(Harness.IO, /*ignoreCase*/ false, { documents: [main, pkg], cwd: "/" }); - const program = createProgram(["/main.ts"], { resolveJsonModule: true }, new fakes.CompilerHost(fs, { newLine: NewLineKind.LineFeed })); + const program = ts.createProgram(["/main.ts"], { resolveJsonModule: true }, new fakes.CompilerHost(fs, { newLine: ts.NewLineKind.LineFeed })); const json = program.getSourceFile("/package.json")!; - assert.equal(json.scriptKind, ScriptKind.JSON); + assert.equal(json.scriptKind, ts.ScriptKind.JSON); assert.isNumber(json.nodeCount); assert.isNumber(json.identifierCount); @@ -184,10 +179,10 @@ namespace ts { const main = new documents.TextDocument("/main.ts", "0 as const"); const fs = vfs.createFromFileSystem(Harness.IO, /*ignoreCase*/ false, { documents: [main], cwd: "/" }); - const program = createProgram(["/main.ts"], {}, new fakes.CompilerHost(fs, { newLine: NewLineKind.LineFeed })); + const program = ts.createProgram(["/main.ts"], {}, new fakes.CompilerHost(fs, { newLine: ts.NewLineKind.LineFeed })); const typeChecker = program.getTypeChecker(); const sourceFile = program.getSourceFile("main.ts")!; - typeChecker.getTypeAtLocation(((sourceFile.statements[0] as ExpressionStatement).expression as AsExpression).type); + typeChecker.getTypeAtLocation(((sourceFile.statements[0] as ts.ExpressionStatement).expression as ts.AsExpression).type); const diag = program.getSemanticDiagnostics(); assert.isEmpty(diag); }); @@ -196,11 +191,11 @@ namespace ts { const mod = new documents.TextDocument("/module.d.ts", "declare const foo: any;"); const fs = vfs.createFromFileSystem(Harness.IO, /*ignoreCase*/ false, { documents: [main, mod], cwd: "/" }); - const program = createProgram(["/main.ts"], {}, new fakes.CompilerHost(fs, { newLine: NewLineKind.LineFeed })); + const program = ts.createProgram(["/main.ts"], {}, new fakes.CompilerHost(fs, { newLine: ts.NewLineKind.LineFeed })); const sourceFile = program.getSourceFile("main.ts")!; const typeChecker = program.getTypeChecker(); - typeChecker.getSymbolAtLocation((sourceFile.statements[0] as ImportDeclaration).moduleSpecifier); + typeChecker.getSymbolAtLocation((sourceFile.statements[0] as ts.ImportDeclaration).moduleSpecifier); assert.isEmpty(program.getSemanticDiagnostics()); }); }); @@ -211,9 +206,9 @@ namespace ts { const mod = new documents.TextDocument("/lib/module.ts", "declare const foo: any;"); const fs = vfs.createFromFileSystem(Harness.IO, /*ignoreCase*/ false, { documents: [main, mod], cwd: "/" }); - const program = createProgram(["./main.ts"], { + const program = ts.createProgram(["./main.ts"], { paths: { "*": ["./lib/*"] } - }, new fakes.CompilerHost(fs, { newLine: NewLineKind.LineFeed })); + }, new fakes.CompilerHost(fs, { newLine: ts.NewLineKind.LineFeed })); assert.isEmpty(program.getConfigFileParsingDiagnostics()); assert.isEmpty(program.getGlobalDiagnostics()); diff --git a/src/testRunner/unittests/publicApi.ts b/src/testRunner/unittests/publicApi.ts index 4bfce8288f500..26aa9ca422ce6 100644 --- a/src/testRunner/unittests/publicApi.ts +++ b/src/testRunner/unittests/publicApi.ts @@ -5,7 +5,8 @@ describe("unittests:: Public APIs", () => { let fileContent: string; before(() => { fileContent = Harness.IO.readFile(builtFile)!; - if (!fileContent) throw new Error(`File ${fileName} was not present in built/local`); + if (!fileContent) + throw new Error(`File ${fileName} was not present in built/local`); fileContent = fileContent.replace(/\r\n/g, "\n"); }); @@ -92,10 +93,8 @@ describe("unittests:: Public APIs:: getTypeAtLocation", () => { } class Foo implements Test.Test {}`; - const host = new fakes.CompilerHost(vfs.createFromFileSystem( - Harness.IO, - /*ignoreCase*/ true, - { documents: [new documents.TextDocument("/file.ts", content)], cwd: "/" })); + const host = new fakes.CompilerHost(vfs.createFromFileSystem(Harness.IO, + /*ignoreCase*/ true, { documents: [new documents.TextDocument("/file.ts", content)], cwd: "/" })); const program = ts.createProgram({ host, @@ -114,10 +113,8 @@ describe("unittests:: Public APIs:: getTypeAtLocation", () => { it("works on SourceFile", () => { const content = `const foo = 1;`; - const host = new fakes.CompilerHost(vfs.createFromFileSystem( - Harness.IO, - /*ignoreCase*/ true, - { documents: [new documents.TextDocument("/file.ts", content)], cwd: "/" })); + const host = new fakes.CompilerHost(vfs.createFromFileSystem(Harness.IO, + /*ignoreCase*/ true, { documents: [new documents.TextDocument("/file.ts", content)], cwd: "/" })); const program = ts.createProgram({ host, @@ -134,10 +131,8 @@ describe("unittests:: Public APIs:: getTypeAtLocation", () => { it("returns an errorType for VariableDeclaration with BindingPattern name", () => { const content = "const foo = [1];\n" + "const [a] = foo;"; - const host = new fakes.CompilerHost(vfs.createFromFileSystem( - Harness.IO, - /*ignoreCase*/ true, - { documents: [new documents.TextDocument("/file.ts", content)], cwd: "/" })); + const host = new fakes.CompilerHost(vfs.createFromFileSystem(Harness.IO, + /*ignoreCase*/ true, { documents: [new documents.TextDocument("/file.ts", content)], cwd: "/" })); const program = ts.createProgram({ host, diff --git a/src/testRunner/unittests/reuseProgramStructure.ts b/src/testRunner/unittests/reuseProgramStructure.ts index 3e9e5f2313441..54b8b25134c8f 100644 --- a/src/testRunner/unittests/reuseProgramStructure.ts +++ b/src/testRunner/unittests/reuseProgramStructure.ts @@ -8,7 +8,7 @@ namespace ts { const newLine = "\r\n"; - interface SourceFileWithText extends SourceFile { + interface SourceFileWithText extends ts.SourceFile { sourceText?: SourceText; } @@ -17,29 +17,25 @@ namespace ts { text: SourceText; } - export interface ProgramWithSourceTexts extends Program { + export interface ProgramWithSourceTexts extends ts.Program { sourceTexts?: readonly NamedSourceText[]; host: TestCompilerHost; } - interface TestCompilerHost extends CompilerHost { + interface TestCompilerHost extends ts.CompilerHost { getTrace(): string[]; } - export class SourceText implements IScriptSnapshot { + export class SourceText implements ts.IScriptSnapshot { private fullText: string | undefined; - constructor(private references: string, - private importsAndExports: string, - private program: string, - private changedPart: ChangedPart = 0, - private version = 0) { + constructor(private references: string, private importsAndExports: string, private program: string, private changedPart: ChangedPart = 0, private version = 0) { } static New(references: string, importsAndExports: string, program: string): SourceText { - Debug.assert(references !== undefined); - Debug.assert(importsAndExports !== undefined); - Debug.assert(program !== undefined); + ts.Debug.assert(references !== undefined); + ts.Debug.assert(importsAndExports !== undefined); + ts.Debug.assert(program !== undefined); return new SourceText(references + newLine, importsAndExports + newLine, program || ""); } @@ -48,15 +44,15 @@ namespace ts { } public updateReferences(newReferences: string): SourceText { - Debug.assert(newReferences !== undefined); + ts.Debug.assert(newReferences !== undefined); return new SourceText(newReferences + newLine, this.importsAndExports, this.program, this.changedPart | ChangedPart.references, this.version + 1); } public updateImportsAndExports(newImportsAndExports: string): SourceText { - Debug.assert(newImportsAndExports !== undefined); + ts.Debug.assert(newImportsAndExports !== undefined); return new SourceText(this.references, newImportsAndExports + newLine, this.program, this.changedPart | ChangedPart.importsAndExports, this.version + 1); } public updateProgram(newProgram: string): SourceText { - Debug.assert(newProgram !== undefined); + ts.Debug.assert(newProgram !== undefined); return new SourceText(this.references, this.importsAndExports, newProgram, this.changedPart | ChangedPart.program, this.version + 1); } @@ -72,40 +68,40 @@ namespace ts { return this.getFullText().length; } - getChangeRange(oldSnapshot: IScriptSnapshot): TextChangeRange { + getChangeRange(oldSnapshot: ts.IScriptSnapshot): ts.TextChangeRange { const oldText = oldSnapshot as SourceText; - let oldSpan: TextSpan; + let oldSpan: ts.TextSpan; let newLength: number; switch (oldText.changedPart ^ this.changedPart) { case ChangedPart.references: - oldSpan = createTextSpan(0, oldText.references.length); + oldSpan = ts.createTextSpan(0, oldText.references.length); newLength = this.references.length; break; case ChangedPart.importsAndExports: - oldSpan = createTextSpan(oldText.references.length, oldText.importsAndExports.length); + oldSpan = ts.createTextSpan(oldText.references.length, oldText.importsAndExports.length); newLength = this.importsAndExports.length; break; case ChangedPart.program: - oldSpan = createTextSpan(oldText.references.length + oldText.importsAndExports.length, oldText.program.length); + oldSpan = ts.createTextSpan(oldText.references.length + oldText.importsAndExports.length, oldText.program.length); newLength = this.program.length; break; default: - return Debug.fail("Unexpected change"); + return ts.Debug.fail("Unexpected change"); } - return createTextChangeRange(oldSpan, newLength); + return ts.createTextChangeRange(oldSpan, newLength); } } - function createSourceFileWithText(fileName: string, sourceText: SourceText, target: ScriptTarget) { - const file = createSourceFile(fileName, sourceText.getFullText(), target) as SourceFileWithText; + function createSourceFileWithText(fileName: string, sourceText: SourceText, target: ts.ScriptTarget) { + const file = ts.createSourceFile(fileName, sourceText.getFullText(), target) as SourceFileWithText; file.sourceText = sourceText; file.version = "" + sourceText.getVersion(); return file; } - export function createTestCompilerHost(texts: readonly NamedSourceText[], target: ScriptTarget, oldProgram?: ProgramWithSourceTexts, useGetSourceFileByPath?: boolean) { - const files = arrayToMap(texts, t => t.name, t => { + export function createTestCompilerHost(texts: readonly NamedSourceText[], target: ts.ScriptTarget, oldProgram?: ProgramWithSourceTexts, useGetSourceFileByPath?: boolean) { + const files = ts.arrayToMap(texts, t => t.name, t => { if (oldProgram) { let oldFile = oldProgram.getSourceFile(t.name) as SourceFileWithText; if (oldFile && oldFile.redirectInfo) { @@ -117,20 +113,20 @@ namespace ts { } return createSourceFileWithText(t.name, t.text, target); }); - const useCaseSensitiveFileNames = sys && sys.useCaseSensitiveFileNames; - const getCanonicalFileName = createGetCanonicalFileName(useCaseSensitiveFileNames); + const useCaseSensitiveFileNames = ts.sys && ts.sys.useCaseSensitiveFileNames; + const getCanonicalFileName = ts.createGetCanonicalFileName(useCaseSensitiveFileNames); const trace: string[] = []; const result: TestCompilerHost = { trace: s => trace.push(s), getTrace: () => trace, getSourceFile: fileName => files.get(fileName), getDefaultLibFileName: () => "lib.d.ts", - writeFile: notImplemented, + writeFile: ts.notImplemented, getCurrentDirectory: () => "", getDirectories: () => [], getCanonicalFileName, useCaseSensitiveFileNames: () => useCaseSensitiveFileNames, - getNewLine: () => sys ? sys.newLine : newLine, + getNewLine: () => ts.sys ? ts.sys.newLine : newLine, fileExists: fileName => files.has(fileName), readFile: fileName => { const file = files.get(fileName); @@ -138,44 +134,44 @@ namespace ts { }, }; if (useGetSourceFileByPath) { - const filesByPath = mapEntries(files, (fileName, file) => [toPath(fileName, "", getCanonicalFileName), file]); + const filesByPath = ts.mapEntries(files, (fileName, file) => [ts.toPath(fileName, "", getCanonicalFileName), file]); result.getSourceFileByPath = (_fileName, path) => filesByPath.get(path); } return result; } - export function newProgram(texts: NamedSourceText[], rootNames: string[], options: CompilerOptions, useGetSourceFileByPath?: boolean): ProgramWithSourceTexts { + export function newProgram(texts: NamedSourceText[], rootNames: string[], options: ts.CompilerOptions, useGetSourceFileByPath?: boolean): ProgramWithSourceTexts { const host = createTestCompilerHost(texts, options.target!, /*oldProgram*/ undefined, useGetSourceFileByPath); - const program = createProgram(rootNames, options, host) as ProgramWithSourceTexts; + const program = ts.createProgram(rootNames, options, host) as ProgramWithSourceTexts; program.sourceTexts = texts; program.host = host; return program; } - export function updateProgram(oldProgram: ProgramWithSourceTexts, rootNames: readonly string[], options: CompilerOptions, updater: (files: NamedSourceText[]) => void, newTexts?: NamedSourceText[], useGetSourceFileByPath?: boolean) { + export function updateProgram(oldProgram: ProgramWithSourceTexts, rootNames: readonly string[], options: ts.CompilerOptions, updater: (files: NamedSourceText[]) => void, newTexts?: NamedSourceText[], useGetSourceFileByPath?: boolean) { if (!newTexts) { newTexts = oldProgram.sourceTexts!.slice(0); } updater(newTexts); const host = createTestCompilerHost(newTexts, options.target!, oldProgram, useGetSourceFileByPath); - const program = createProgram(rootNames, options, host, oldProgram) as ProgramWithSourceTexts; + const program = ts.createProgram(rootNames, options, host, oldProgram) as ProgramWithSourceTexts; program.sourceTexts = newTexts; program.host = host; return program; } export function updateProgramText(files: readonly NamedSourceText[], fileName: string, newProgramText: string) { - const file = find(files, f => f.name === fileName)!; + const file = ts.find(files, f => f.name === fileName)!; file.text = file.text.updateProgram(newProgramText); } - function checkResolvedTypeDirective(actual: ResolvedTypeReferenceDirective, expected: ResolvedTypeReferenceDirective) { + function checkResolvedTypeDirective(actual: ts.ResolvedTypeReferenceDirective, expected: ts.ResolvedTypeReferenceDirective) { assert.equal(actual.resolvedFileName, expected.resolvedFileName, `'resolvedFileName': expected '${actual.resolvedFileName}' to be equal to '${expected.resolvedFileName}'`); assert.equal(actual.primary, expected.primary, `'primary': expected '${actual.primary}' to be equal to '${expected.primary}'`); return true; } - function checkCache(caption: string, program: Program, fileName: string, expectedContent: ESMap | undefined, getCache: (f: SourceFile) => ModeAwareCache | undefined, entryChecker: (expected: T, original: T) => boolean): void { + function checkCache(caption: string, program: ts.Program, fileName: string, expectedContent: ts.ESMap | undefined, getCache: (f: ts.SourceFile) => ts.ModeAwareCache | undefined, entryChecker: (expected: T, original: T) => boolean): void { const file = program.getSourceFile(fileName); assert.isTrue(file !== undefined, `cannot find file ${fileName}`); const cache = getCache(file!); @@ -189,34 +185,37 @@ namespace ts { } /** True if the maps have the same keys and values. */ - function mapEqualToCache(left: ESMap, right: ModeAwareCache, valuesAreEqual?: (left: T, right: T) => boolean): boolean { - if (left as any === right) return true; // given the type mismatch (the tests never pass a cache), this'll never be true - if (!left || !right) return false; - const someInLeftHasNoMatch = forEachEntry(left, (leftValue, leftKey) => { - if (!right.has(leftKey, /*mode*/ undefined)) return true; + function mapEqualToCache(left: ts.ESMap, right: ts.ModeAwareCache, valuesAreEqual?: (left: T, right: T) => boolean): boolean { + if (left as any === right) + return true; // given the type mismatch (the tests never pass a cache), this'll never be true + if (!left || !right) + return false; + const someInLeftHasNoMatch = ts.forEachEntry(left, (leftValue, leftKey) => { + if (!right.has(leftKey, /*mode*/ undefined)) + return true; const rightValue = right.get(leftKey, /*mode*/ undefined)!; return !(valuesAreEqual ? valuesAreEqual(leftValue, rightValue) : leftValue === rightValue); }); - if (someInLeftHasNoMatch) return false; + if (someInLeftHasNoMatch) + return false; let someInRightHasNoMatch = false; right.forEach((_, rightKey) => someInRightHasNoMatch = someInRightHasNoMatch || !left.has(rightKey)); return !someInRightHasNoMatch; } - function checkResolvedModulesCache(program: Program, fileName: string, expectedContent: ESMap | undefined): void { - checkCache("resolved modules", program, fileName, expectedContent, f => f.resolvedModules, checkResolvedModule); + function checkResolvedModulesCache(program: ts.Program, fileName: string, expectedContent: ts.ESMap | undefined): void { + checkCache("resolved modules", program, fileName, expectedContent, f => f.resolvedModules, ts.checkResolvedModule); } - function checkResolvedTypeDirectivesCache(program: Program, fileName: string, expectedContent: ESMap | undefined): void { + function checkResolvedTypeDirectivesCache(program: ts.Program, fileName: string, expectedContent: ts.ESMap | undefined): void { checkCache("resolved type directives", program, fileName, expectedContent, f => f.resolvedTypeReferenceDirectiveNames, checkResolvedTypeDirective); } describe("unittests:: Reuse program structure:: General", () => { - const target = ScriptTarget.Latest; + const target = ts.ScriptTarget.Latest; const files: NamedSourceText[] = [ { - name: "a.ts", text: SourceText.New( - ` + name: "a.ts", text: SourceText.New(` /// /// /// @@ -232,7 +231,7 @@ namespace ts { const program2 = updateProgram(program1, ["a.ts"], { target }, files => { files[0].text = files[0].text.updateProgram("var x = 100"); }); - assert.equal(program2.structureIsReused, StructureIsReused.Completely); + assert.equal(program2.structureIsReused, ts.StructureIsReused.Completely); const program1Diagnostics = program1.getSemanticDiagnostics(program1.getSourceFile("a.ts")); const program2Diagnostics = program2.getSemanticDiagnostics(program2.getSourceFile("a.ts")); assert.equal(program1Diagnostics.length, program2Diagnostics.length); @@ -243,7 +242,7 @@ namespace ts { const program2 = updateProgram(program1, ["a.ts"], { target }, files => { files[0].text = files[0].text.updateProgram("var x = 100"); }); - assert.equal(program2.structureIsReused, StructureIsReused.Completely); + assert.equal(program2.structureIsReused, ts.StructureIsReused.Completely); const program1Diagnostics = program1.getSemanticDiagnostics(program1.getSourceFile("a.ts")); const program2Diagnostics = program2.getSemanticDiagnostics(program2.getSourceFile("a.ts")); assert.equal(program1Diagnostics.length, program2Diagnostics.length); @@ -257,12 +256,12 @@ namespace ts { { name: "/node_modules/b/package.json", text: SourceText.New("", "", JSON.stringify({ name: "b", version: "1.2.3" })) }, ]; - const options: CompilerOptions = { target, moduleResolution: ModuleResolutionKind.NodeJs }; + const options: ts.CompilerOptions = { target, moduleResolution: ts.ModuleResolutionKind.NodeJs }; const program1 = newProgram(files, ["/a.ts"], options); const program2 = updateProgram(program1, ["/a.ts"], options, files => { files[2].text = files[2].text.updateProgram("export const b = 2;"); }); - assert.equal(program2.structureIsReused, StructureIsReused.Completely); + assert.equal(program2.structureIsReused, ts.StructureIsReused.Completely); const program1Diagnostics = program1.getSemanticDiagnostics(program1.getSourceFile("a.ts")); const program2Diagnostics = program2.getSemanticDiagnostics(program2.getSourceFile("a.ts")); assert.equal(program1Diagnostics.length, program2Diagnostics.length); @@ -276,19 +275,19 @@ namespace ts { `; files[0].text = files[0].text.updateReferences(newReferences); }); - assert.equal(program2.structureIsReused, StructureIsReused.SafeModules); + assert.equal(program2.structureIsReused, ts.StructureIsReused.SafeModules); }); it("fails if change affects type references", () => { const program1 = newProgram(files, ["a.ts"], { types: ["a"] }); - const program2 = updateProgram(program1, ["a.ts"], { types: ["b"] }, noop); - assert.equal(program2.structureIsReused, StructureIsReused.SafeModules); + const program2 = updateProgram(program1, ["a.ts"], { types: ["b"] }, ts.noop); + assert.equal(program2.structureIsReused, ts.StructureIsReused.SafeModules); }); it("succeeds if change doesn't affect type references", () => { const program1 = newProgram(files, ["a.ts"], { types: ["a"] }); - const program2 = updateProgram(program1, ["a.ts"], { types: ["a"] }, noop); - assert.equal(program2.structureIsReused, StructureIsReused.Completely); + const program2 = updateProgram(program1, ["a.ts"], { types: ["a"] }, ts.noop); + assert.equal(program2.structureIsReused, ts.StructureIsReused.Completely); }); it("fails if change affects imports", () => { @@ -296,7 +295,7 @@ namespace ts { const program2 = updateProgram(program1, ["a.ts"], { target }, files => { files[2].text = files[2].text.updateImportsAndExports("import x from 'b'"); }); - assert.equal(program2.structureIsReused, StructureIsReused.SafeModules); + assert.equal(program2.structureIsReused, ts.StructureIsReused.SafeModules); }); it("fails if change affects type directives", () => { @@ -308,50 +307,49 @@ namespace ts { /// `; files[0].text = files[0].text.updateReferences(newReferences); }); - assert.equal(program2.structureIsReused, StructureIsReused.SafeModules); + assert.equal(program2.structureIsReused, ts.StructureIsReused.SafeModules); }); it("fails if module kind changes", () => { - const program1 = newProgram(files, ["a.ts"], { target, module: ModuleKind.CommonJS }); - const program2 = updateProgram(program1, ["a.ts"], { target, module: ModuleKind.AMD }, noop); - assert.equal(program2.structureIsReused, StructureIsReused.Not); + const program1 = newProgram(files, ["a.ts"], { target, module: ts.ModuleKind.CommonJS }); + const program2 = updateProgram(program1, ["a.ts"], { target, module: ts.ModuleKind.AMD }, ts.noop); + assert.equal(program2.structureIsReused, ts.StructureIsReused.Not); }); it("succeeds if rootdir changes", () => { - const program1 = newProgram(files, ["a.ts"], { target, module: ModuleKind.CommonJS, rootDir: "/a/b" }); - const program2 = updateProgram(program1, ["a.ts"], { target, module: ModuleKind.CommonJS, rootDir: "/a/c" }, noop); - assert.equal(program2.structureIsReused, StructureIsReused.Completely); + const program1 = newProgram(files, ["a.ts"], { target, module: ts.ModuleKind.CommonJS, rootDir: "/a/b" }); + const program2 = updateProgram(program1, ["a.ts"], { target, module: ts.ModuleKind.CommonJS, rootDir: "/a/c" }, ts.noop); + assert.equal(program2.structureIsReused, ts.StructureIsReused.Completely); }); it("fails if config path changes", () => { - const program1 = newProgram(files, ["a.ts"], { target, module: ModuleKind.CommonJS, configFilePath: "/a/b/tsconfig.json" }); - const program2 = updateProgram(program1, ["a.ts"], { target, module: ModuleKind.CommonJS, configFilePath: "/a/c/tsconfig.json" }, noop); - assert.equal(program2.structureIsReused, StructureIsReused.Not); + const program1 = newProgram(files, ["a.ts"], { target, module: ts.ModuleKind.CommonJS, configFilePath: "/a/b/tsconfig.json" }); + const program2 = updateProgram(program1, ["a.ts"], { target, module: ts.ModuleKind.CommonJS, configFilePath: "/a/c/tsconfig.json" }, ts.noop); + assert.equal(program2.structureIsReused, ts.StructureIsReused.Not); }); it("succeeds if missing files remain missing", () => { - const options: CompilerOptions = { target, noLib: true }; + const options: ts.CompilerOptions = { target, noLib: true }; const program1 = newProgram(files, ["a.ts"], options); - assert.notDeepEqual(emptyArray, program1.getMissingFilePaths()); - - const program2 = updateProgram(program1, ["a.ts"], options, noop); + assert.notDeepEqual(ts.emptyArray, program1.getMissingFilePaths()); + const program2 = updateProgram(program1, ["a.ts"], options, ts.noop); assert.deepEqual(program1.getMissingFilePaths(), program2.getMissingFilePaths()); - assert.equal(program2.structureIsReused, StructureIsReused.Completely,); + assert.equal(program2.structureIsReused, ts.StructureIsReused.Completely); }); it("fails if missing file is created", () => { - const options: CompilerOptions = { target, noLib: true }; + const options: ts.CompilerOptions = { target, noLib: true }; const program1 = newProgram(files, ["a.ts"], options); - assert.notDeepEqual(emptyArray, program1.getMissingFilePaths()); + assert.notDeepEqual(ts.emptyArray, program1.getMissingFilePaths()); const newTexts: NamedSourceText[] = files.concat([{ name: "non-existing-file.ts", text: SourceText.New("", "", `var x = 1`) }]); - const program2 = updateProgram(program1, ["a.ts"], options, noop, newTexts); + const program2 = updateProgram(program1, ["a.ts"], options, ts.noop, newTexts); assert.lengthOf(program2.getMissingFilePaths(), 0); - assert.equal(program2.structureIsReused, StructureIsReused.Not); + assert.equal(program2.structureIsReused, ts.StructureIsReused.Not); }); it("resolution cache follows imports", () => { @@ -361,26 +359,26 @@ namespace ts { { name: "a.ts", text: SourceText.New("", "import {_} from 'b'", "var x = 1") }, { name: "b.ts", text: SourceText.New("", "", "var y = 2") }, ]; - const options: CompilerOptions = { target }; + const options: ts.CompilerOptions = { target }; const program1 = newProgram(files, ["a.ts"], options); - checkResolvedModulesCache(program1, "a.ts", new Map(getEntries({ b: createResolvedModule("b.ts") }))); + checkResolvedModulesCache(program1, "a.ts", new ts.Map(ts.getEntries({ b: ts.createResolvedModule("b.ts") }))); checkResolvedModulesCache(program1, "b.ts", /*expectedContent*/ undefined); const program2 = updateProgram(program1, ["a.ts"], options, files => { files[0].text = files[0].text.updateProgram("var x = 2"); }); - assert.equal(program2.structureIsReused, StructureIsReused.Completely); + assert.equal(program2.structureIsReused, ts.StructureIsReused.Completely); // content of resolution cache should not change - checkResolvedModulesCache(program1, "a.ts", new Map(getEntries({ b: createResolvedModule("b.ts") }))); + checkResolvedModulesCache(program1, "a.ts", new ts.Map(ts.getEntries({ b: ts.createResolvedModule("b.ts") }))); checkResolvedModulesCache(program1, "b.ts", /*expectedContent*/ undefined); // imports has changed - program is not reused const program3 = updateProgram(program2, ["a.ts"], options, files => { files[0].text = files[0].text.updateImportsAndExports(""); }); - assert.equal(program3.structureIsReused, StructureIsReused.SafeModules); + assert.equal(program3.structureIsReused, ts.StructureIsReused.SafeModules); checkResolvedModulesCache(program3, "a.ts", /*expectedContent*/ undefined); const program4 = updateProgram(program3, ["a.ts"], options, files => { @@ -389,8 +387,8 @@ namespace ts { `; files[0].text = files[0].text.updateImportsAndExports(newImports); }); - assert.equal(program4.structureIsReused, StructureIsReused.SafeModules); - checkResolvedModulesCache(program4, "a.ts", new Map(getEntries({ b: createResolvedModule("b.ts"), c: undefined }))); + assert.equal(program4.structureIsReused, ts.StructureIsReused.SafeModules); + checkResolvedModulesCache(program4, "a.ts", new ts.Map(ts.getEntries({ b: ts.createResolvedModule("b.ts"), c: undefined }))); }); it("set the resolvedImports after re-using an ambient external module declaration", () => { @@ -398,7 +396,7 @@ namespace ts { { name: "/a.ts", text: SourceText.New("", "", 'import * as a from "a";') }, { name: "/types/zzz/index.d.ts", text: SourceText.New("", "", 'declare module "a" { }') }, ]; - const options: CompilerOptions = { target, typeRoots: ["/types"] }; + const options: ts.CompilerOptions = { target, typeRoots: ["/types"] }; const program1 = newProgram(files, ["/a.ts"], options); const program2 = updateProgram(program1, ["/a.ts"], options, files => { files[0].text = files[0].text.updateProgram('import * as aa from "a";'); @@ -413,11 +411,11 @@ namespace ts { { name: "/types/zzz/index.d.ts", text: SourceText.New("", "", 'declare module "a" { }') }, ]; const host = createTestCompilerHost(files, target); - const options: CompilerOptions = { target, typeRoots: ["/types"] }; - const program1 = createProgram(["/a.ts"], options, host); + const options: ts.CompilerOptions = { target, typeRoots: ["/types"] }; + const program1 = ts.createProgram(["/a.ts"], options, host); let sourceFile = program1.getSourceFile("/a.ts")!; assert.isDefined(sourceFile, "'/a.ts' is included in the program"); - sourceFile = updateSourceFile(sourceFile, "'use strict';" + sourceFile.text, { newLength: "'use strict';".length, span: { start: 0, length: 0 } }); + sourceFile = ts.updateSourceFile(sourceFile, "'use strict';" + sourceFile.text, { newLength: "'use strict';".length, span: { start: 0, length: 0 } }); assert.strictEqual(sourceFile.statements[2].getSourceFile(), sourceFile, "parent pointers are updated"); const updateHost: TestCompilerHost = { ...host, @@ -425,7 +423,7 @@ namespace ts { return fileName === sourceFile.fileName ? sourceFile : program1.getSourceFile(fileName); } }; - const program2 = createProgram(["/a.ts"], options, updateHost, program1); + const program2 = ts.createProgram(["/a.ts"], options, updateHost, program1); assert.isDefined(program2.getSourceFile("/a.ts")!.resolvedModules!.get("a", /*mode*/ undefined), "'a' is not an unresolved module after re-use"); assert.strictEqual(sourceFile.statements[2].getSourceFile(), sourceFile, "parent pointers are not altered"); }); @@ -435,19 +433,19 @@ namespace ts { { name: "/a.ts", text: SourceText.New("/// ", "", "var x = $") }, { name: "/types/typedefs/index.d.ts", text: SourceText.New("", "", "declare var $: number") }, ]; - const options: CompilerOptions = { target, typeRoots: ["/types"] }; + const options: ts.CompilerOptions = { target, typeRoots: ["/types"] }; const program1 = newProgram(files, ["/a.ts"], options); - checkResolvedTypeDirectivesCache(program1, "/a.ts", new Map(getEntries({ typedefs: { resolvedFileName: "/types/typedefs/index.d.ts", primary: true } }))); + checkResolvedTypeDirectivesCache(program1, "/a.ts", new ts.Map(ts.getEntries({ typedefs: { resolvedFileName: "/types/typedefs/index.d.ts", primary: true } }))); checkResolvedTypeDirectivesCache(program1, "/types/typedefs/index.d.ts", /*expectedContent*/ undefined); const program2 = updateProgram(program1, ["/a.ts"], options, files => { files[0].text = files[0].text.updateProgram("var x = 2"); }); - assert.equal(program2.structureIsReused, StructureIsReused.Completely); + assert.equal(program2.structureIsReused, ts.StructureIsReused.Completely); // content of resolution cache should not change - checkResolvedTypeDirectivesCache(program1, "/a.ts", new Map(getEntries({ typedefs: { resolvedFileName: "/types/typedefs/index.d.ts", primary: true } }))); + checkResolvedTypeDirectivesCache(program1, "/a.ts", new ts.Map(ts.getEntries({ typedefs: { resolvedFileName: "/types/typedefs/index.d.ts", primary: true } }))); checkResolvedTypeDirectivesCache(program1, "/types/typedefs/index.d.ts", /*expectedContent*/ undefined); // type reference directives has changed - program is not reused @@ -455,7 +453,7 @@ namespace ts { files[0].text = files[0].text.updateReferences(""); }); - assert.equal(program3.structureIsReused, StructureIsReused.SafeModules); + assert.equal(program3.structureIsReused, ts.StructureIsReused.SafeModules); checkResolvedTypeDirectivesCache(program3, "/a.ts", /*expectedContent*/ undefined); const program4 = updateProgram(program3, ["/a.ts"], options, files => { @@ -464,22 +462,21 @@ namespace ts { `; files[0].text = files[0].text.updateReferences(newReferences); }); - assert.equal(program4.structureIsReused, StructureIsReused.SafeModules); - checkResolvedTypeDirectivesCache(program1, "/a.ts", new Map(getEntries({ typedefs: { resolvedFileName: "/types/typedefs/index.d.ts", primary: true } }))); + assert.equal(program4.structureIsReused, ts.StructureIsReused.SafeModules); + checkResolvedTypeDirectivesCache(program1, "/a.ts", new ts.Map(ts.getEntries({ typedefs: { resolvedFileName: "/types/typedefs/index.d.ts", primary: true } }))); }); it("fetches imports after npm install", () => { const file1Ts = { name: "file1.ts", text: SourceText.New("", `import * as a from "a";`, "const myX: number = a.x;") }; const file2Ts = { name: "file2.ts", text: SourceText.New("", "", "") }; const indexDTS = { name: "node_modules/a/index.d.ts", text: SourceText.New("", "export declare let x: number;", "") }; - const options: CompilerOptions = { target: ScriptTarget.ES2015, traceResolution: true, moduleResolution: ModuleResolutionKind.NodeJs }; + const options: ts.CompilerOptions = { target: ts.ScriptTarget.ES2015, traceResolution: true, moduleResolution: ts.ModuleResolutionKind.NodeJs }; const rootFiles = [file1Ts, file2Ts]; const filesAfterNpmInstall = [file1Ts, file2Ts, indexDTS]; const initialProgram = newProgram(rootFiles, rootFiles.map(f => f.name), options); { - assert.deepEqual(initialProgram.host.getTrace(), - [ + assert.deepEqual(initialProgram.host.getTrace(), [ "======== Resolving module 'a' from 'file1.ts'. ========", "Explicitly specified module resolution kind: 'NodeJs'.", "Loading module 'a' from 'node_modules' folder, target file type 'TypeScript'.", @@ -500,8 +497,7 @@ namespace ts { "File 'node_modules/a/index.js' does not exist.", "File 'node_modules/a/index.jsx' does not exist.", "======== Module name 'a' was not resolved. ========" - ], - "initialProgram: execute module resolution normally."); + ], "initialProgram: execute module resolution normally."); const initialProgramDiagnostics = initialProgram.getSemanticDiagnostics(initialProgram.getSourceFile("file1.ts")); assert.lengthOf(initialProgramDiagnostics, 1, `initialProgram: import should fail.`); @@ -511,8 +507,7 @@ namespace ts { f[1].text = f[1].text.updateReferences(`/// `); }, filesAfterNpmInstall); { - assert.deepEqual(afterNpmInstallProgram.host.getTrace(), - [ + assert.deepEqual(afterNpmInstallProgram.host.getTrace(), [ "======== Resolving module 'a' from 'file1.ts'. ========", "Explicitly specified module resolution kind: 'NodeJs'.", "Loading module 'a' from 'node_modules' folder, target file type 'TypeScript'.", @@ -524,8 +519,7 @@ namespace ts { "File 'node_modules/a/index.tsx' does not exist.", "File 'node_modules/a/index.d.ts' exist - use it as a name resolution result.", "======== Module name 'a' was successfully resolved to 'node_modules/a/index.d.ts'. ========" - ], - "afterNpmInstallProgram: execute module resolution normally."); + ], "afterNpmInstallProgram: execute module resolution normally."); const afterNpmInstallProgramDiagnostics = afterNpmInstallProgram.getSemanticDiagnostics(afterNpmInstallProgram.getSourceFile("file1.ts")); assert.lengthOf(afterNpmInstallProgramDiagnostics, 0, `afterNpmInstallProgram: program is well-formed with import.`); @@ -537,10 +531,9 @@ namespace ts { { name: "/a/b/app.ts", text: SourceText.New("", "import * as fs from 'fs'", "") }, { name: "/a/b/node.d.ts", text: SourceText.New("", "", "declare module 'fs' {}") } ]; - const options = { target: ScriptTarget.ES2015, traceResolution: true }; + const options = { target: ts.ScriptTarget.ES2015, traceResolution: true }; const program = newProgram(files, files.map(f => f.name), options); - assert.deepEqual(program.host.getTrace(), - [ + assert.deepEqual(program.host.getTrace(), [ "======== Resolving module 'fs' from '/a/b/app.ts'. ========", "Module resolution kind is not specified, using 'Classic'.", "File '/a/b/fs.ts' does not exist.", @@ -581,8 +574,7 @@ namespace ts { f[0].text = f[0].text.updateProgram("var y = 1;"); f[1].text = f[1].text.updateProgram("declare var process: any"); }); - assert.deepEqual(program3.host.getTrace(), - [ + assert.deepEqual(program3.host.getTrace(), [ "======== Resolving module 'fs' from '/a/b/app.ts'. ========", "Module resolution kind is not specified, using 'Classic'.", "File '/a/b/fs.ts' does not exist.", @@ -623,27 +615,19 @@ namespace ts { { name: "node_modules/@types/typerefs2/index.d.ts", text: SourceText.New("", "", "declare let z: string;") }, { name: "f1.ts", - text: - SourceText.New( - `/// ${newLine}/// ${newLine}/// `, - `import { B } from './b1';${newLine}export let BB = B;`, - "declare module './b1' { interface B { y: string; } }") + text: SourceText.New(`/// ${newLine}/// ${newLine}/// `, `import { B } from './b1';${newLine}export let BB = B;`, "declare module './b1' { interface B { y: string; } }") }, { name: "f2.ts", - text: SourceText.New( - `/// ${newLine}/// `, - `import { B } from './b2';${newLine}import { BB } from './f1';`, - "(new BB).x; (new BB).y;") + text: SourceText.New(`/// ${newLine}/// `, `import { B } from './b2';${newLine}import { BB } from './f1';`, "(new BB).x; (new BB).y;") }, ]; - const options: CompilerOptions = { target: ScriptTarget.ES2015, traceResolution: true, moduleResolution: ModuleResolutionKind.Classic }; + const options: ts.CompilerOptions = { target: ts.ScriptTarget.ES2015, traceResolution: true, moduleResolution: ts.ModuleResolutionKind.Classic }; const program1 = newProgram(files, files.map(f => f.name), options); let expectedErrors = 0; { - assert.deepEqual(program1.host.getTrace(), - [ + assert.deepEqual(program1.host.getTrace(), [ "======== Resolving type reference directive 'typerefs1', containing file 'f1.ts', root directory 'node_modules/@types'. ========", "Resolving with primary search path 'node_modules/@types'.", "File 'node_modules/@types/typerefs1/package.json' does not exist.", @@ -666,8 +650,7 @@ namespace ts { "Explicitly specified module resolution kind: 'Classic'.", "File 'f1.ts' exist - use it as a name resolution result.", "======== Module name './f1' was successfully resolved to 'f1.ts'. ========" - ], - "program1: execute module resolution normally."); + ], "program1: execute module resolution normally."); const program1Diagnostics = program1.getSemanticDiagnostics(program1.getSourceFile("f2.ts")); assert.lengthOf(program1Diagnostics, expectedErrors, `initial program should be well-formed`); @@ -819,9 +802,11 @@ namespace ts { const bxIndex = "/node_modules/b/node_modules/x/index.d.ts"; const bxPackage = "/node_modules/b/node_modules/x/package.json"; const root = "/a.ts"; - const compilerOptions = { target, moduleResolution: ModuleResolutionKind.NodeJs }; - - function createRedirectProgram(useGetSourceFileByPath: boolean, options?: { bText: string, bVersion: string }): ProgramWithSourceTexts { + const compilerOptions = { target, moduleResolution: ts.ModuleResolutionKind.NodeJs }; + function createRedirectProgram(useGetSourceFileByPath: boolean, options?: { + bText: string; + bVersion: string; + }): ProgramWithSourceTexts { const files: NamedSourceText[] = [ { name: "/node_modules/a/index.d.ts", @@ -867,7 +852,7 @@ namespace ts { const program2 = updateRedirectProgram(program1, files => { updateProgramText(files, root, "const x = 1;"); }, useGetSourceFileByPath); - assert.equal(program2.structureIsReused, StructureIsReused.Completely); + assert.equal(program2.structureIsReused, ts.StructureIsReused.Completely); assert.lengthOf(program2.getSemanticDiagnostics(), 0); }); @@ -879,7 +864,7 @@ namespace ts { updateProgramText(files, axIndex, "export default class X { private x: number; private y: number; }"); updateProgramText(files, axPackage, JSON.stringify('{ name: "x", version: "1.2.4" }')); }, useGetSourceFileByPath); - assert.equal(program2.structureIsReused, StructureIsReused.Not); + assert.equal(program2.structureIsReused, ts.StructureIsReused.Not); assert.lengthOf(program2.getSemanticDiagnostics(), 1); }); @@ -890,7 +875,7 @@ namespace ts { updateProgramText(files, bxIndex, "export default class X { private x: number; private y: number; }"); updateProgramText(files, bxPackage, JSON.stringify({ name: "x", version: "1.2.4" })); }, useGetSourceFileByPath); - assert.equal(program2.structureIsReused, StructureIsReused.Not); + assert.equal(program2.structureIsReused, ts.StructureIsReused.Not); assert.lengthOf(program2.getSemanticDiagnostics(), 1); }); @@ -901,7 +886,7 @@ namespace ts { updateProgramText(files, bxIndex, "export default class X { private x: number; }"); updateProgramText(files, bxPackage, JSON.stringify({ name: "x", version: "1.2.3" })); }, useGetSourceFileByPath); - assert.equal(program2.structureIsReused, StructureIsReused.Not); + assert.equal(program2.structureIsReused, ts.StructureIsReused.Not); assert.deepEqual(program2.getSemanticDiagnostics(), []); }); } @@ -917,48 +902,35 @@ namespace ts { describe("unittests:: Reuse program structure:: host is optional", () => { it("should work if host is not provided", () => { - createProgram([], {}); + ts.createProgram([], {}); }); }); - type File = TestFSWithWatch.File; - import createTestSystem = TestFSWithWatch.createWatchedSystem; - import libFile = TestFSWithWatch.libFile; + type File = ts.TestFSWithWatch.File; + import createTestSystem = ts.TestFSWithWatch.createWatchedSystem; + import libFile = ts.TestFSWithWatch.libFile; describe("unittests:: Reuse program structure:: isProgramUptoDate", () => { - function getWhetherProgramIsUptoDate( - program: Program, - newRootFileNames: string[], - newOptions: CompilerOptions - ) { - return isProgramUptoDate( - program, newRootFileNames, newOptions, - path => program.getSourceFileByPath(path)!.version, /*fileExists*/ returnFalse, - /*hasInvalidatedResolution*/ returnFalse, - /*hasChangedAutomaticTypeDirectiveNames*/ undefined, - /*getParsedCommandLine*/ returnUndefined, - /*projectReferences*/ undefined - ); + function getWhetherProgramIsUptoDate(program: ts.Program, newRootFileNames: string[], newOptions: ts.CompilerOptions) { + return ts.isProgramUptoDate(program, newRootFileNames, newOptions, path => program.getSourceFileByPath(path)!.version, ts.returnFalse, ts.returnFalse, + /*hasChangedAutomaticTypeDirectiveNames*/ undefined, ts.returnUndefined, + /*projectReferences*/ undefined); } - function duplicate(options: CompilerOptions): CompilerOptions; + function duplicate(options: ts.CompilerOptions): ts.CompilerOptions; function duplicate(fileNames: string[]): string[]; - function duplicate(filesOrOptions: CompilerOptions | string[]) { + function duplicate(filesOrOptions: ts.CompilerOptions | string[]) { return JSON.parse(JSON.stringify(filesOrOptions)); } describe("should return true when there is no change in compiler options and", () => { - function verifyProgramIsUptoDate( - program: Program, - newRootFileNames: string[], - newOptions: CompilerOptions - ) { + function verifyProgramIsUptoDate(program: ts.Program, newRootFileNames: string[], newOptions: ts.CompilerOptions) { const actual = getWhetherProgramIsUptoDate(program, newRootFileNames, newOptions); assert.isTrue(actual); } - function verifyProgramWithoutConfigFile(system: System, rootFiles: string[], options: CompilerOptions) { - const program = createWatchProgram(createWatchCompilerHostOfFilesAndCompilerOptions({ + function verifyProgramWithoutConfigFile(system: ts.System, rootFiles: string[], options: ts.CompilerOptions) { + const program = ts.createWatchProgram(ts.createWatchCompilerHostOfFilesAndCompilerOptions({ rootFiles, options, watchOptions: undefined, @@ -967,16 +939,16 @@ namespace ts { verifyProgramIsUptoDate(program, duplicate(rootFiles), duplicate(options)); } - function verifyProgramWithConfigFile(system: System, configFileName: string) { - const program = createWatchProgram(createWatchCompilerHostOfConfigFile({ + function verifyProgramWithConfigFile(system: ts.System, configFileName: string) { + const program = ts.createWatchProgram(ts.createWatchCompilerHostOfConfigFile({ configFileName, system })).getCurrentProgram().getProgram(); - const { fileNames, options } = parseConfigFileWithSystem(configFileName, {}, /*extendedConfigCache*/ undefined, /*watchOptionsToExtend*/ undefined, system, notImplemented)!; // TODO: GH#18217 + const { fileNames, options } = ts.parseConfigFileWithSystem(configFileName, {}, /*extendedConfigCache*/ undefined, /*watchOptionsToExtend*/ undefined, system, ts.notImplemented)!; // TODO: GH#18217 verifyProgramIsUptoDate(program, fileNames, options); } - function verifyProgram(files: File[], rootFiles: string[], options: CompilerOptions, configFile: string) { + function verifyProgram(files: File[], rootFiles: string[], options: ts.CompilerOptions, configFile: string) { const system = createTestSystem(files); verifyProgramWithoutConfigFile(system, rootFiles, options); verifyProgramWithConfigFile(system, configFile); @@ -999,7 +971,7 @@ namespace ts { }); it("has lib specified in the options", () => { - const compilerOptions: CompilerOptions = { lib: ["es5", "es2015.promise"] }; + const compilerOptions: ts.CompilerOptions = { lib: ["es5", "es2015.promise"] }; const app: File = { path: "/src/app.ts", content: "var x: Promise;" @@ -1021,7 +993,7 @@ namespace ts { }); it("has paths specified in the options", () => { - const compilerOptions: CompilerOptions = { + const compilerOptions: ts.CompilerOptions = { baseUrl: ".", paths: { "*": [ @@ -1059,7 +1031,7 @@ namespace ts { }); it("has include paths specified in tsconfig file", () => { - const compilerOptions: CompilerOptions = { + const compilerOptions: ts.CompilerOptions = { baseUrl: ".", paths: { "*": [ @@ -1110,7 +1082,7 @@ namespace ts { const rootFiles = [module1.path, module2.path, module3.path]; const system = createTestSystem([module1, module2, module3]); const options = {}; - const program = createWatchProgram(createWatchCompilerHostOfFilesAndCompilerOptions({ + const program = ts.createWatchProgram(ts.createWatchCompilerHostOfFilesAndCompilerOptions({ rootFiles, options, watchOptions: undefined, @@ -1121,11 +1093,7 @@ namespace ts { }); describe("should return false when there is no change in compiler options but", () => { - function verifyProgramIsNotUptoDate( - program: Program, - newRootFileNames: string[], - newOptions: CompilerOptions - ) { + function verifyProgramIsNotUptoDate(program: ts.Program, newRootFileNames: string[], newOptions: ts.CompilerOptions) { const actual = getWhetherProgramIsUptoDate(program, newRootFileNames, newOptions); assert.isFalse(actual); } @@ -1146,7 +1114,7 @@ namespace ts { const newRootFiles = [module1.path, module2.path, module3.path]; const system = createTestSystem([module1, module2, module3]); const options = {}; - const program = createWatchProgram(createWatchCompilerHostOfFilesAndCompilerOptions({ + const program = ts.createWatchProgram(ts.createWatchCompilerHostOfFilesAndCompilerOptions({ rootFiles, options, watchOptions: undefined, @@ -1171,7 +1139,7 @@ namespace ts { const newRootFiles = [module2.path, module3.path]; const system = createTestSystem([module1, module2, module3]); const options = {}; - const program = createWatchProgram(createWatchCompilerHostOfFilesAndCompilerOptions({ + const program = ts.createWatchProgram(ts.createWatchCompilerHostOfFilesAndCompilerOptions({ rootFiles, options, watchOptions: undefined, diff --git a/src/testRunner/unittests/semver.ts b/src/testRunner/unittests/semver.ts index 2e6a61fbad87d..d974ff0d2a77a 100644 --- a/src/testRunner/unittests/semver.ts +++ b/src/testRunner/unittests/semver.ts @@ -4,7 +4,7 @@ namespace ts { describe("VersionRange", () => { function assertVersionRange(version: string, good: string[], bad: string[]): () => void { return () => { - const range = VersionRange.tryParse(version)!; + const range = ts.VersionRange.tryParse(version)!; assert(range); for (const g of good) { assert.isTrue(range.test(g), g); @@ -25,104 +25,110 @@ namespace ts { it(">= works with prerelease", assertVersionRange(">=3.8.0-0", ["3.8", "3.9", "4.0"], ["3.6", "3.7"])); }); describe("Version", () => { - function assertVersion(version: Version, [major, minor, patch, prerelease, build]: [number, number, number, string[]?, string[]?]) { + function assertVersion(version: ts.Version, [major, minor, patch, prerelease, build]: [ + number, + number, + number, + string[]?, + string[]? + ]) { assert.strictEqual(version.major, major); assert.strictEqual(version.minor, minor); assert.strictEqual(version.patch, patch); - assert.deepEqual(version.prerelease, prerelease || emptyArray); - assert.deepEqual(version.build, build || emptyArray); + assert.deepEqual(version.prerelease, prerelease || ts.emptyArray); + assert.deepEqual(version.build, build || ts.emptyArray); } describe("new", () => { it("text", () => { - assertVersion(new Version("1.2.3-pre.4+build.5"), [1, 2, 3, ["pre", "4"], ["build", "5"]]); + assertVersion(new ts.Version("1.2.3-pre.4+build.5"), [1, 2, 3, ["pre", "4"], ["build", "5"]]); }); it("parts", () => { - assertVersion(new Version(1, 2, 3, "pre.4", "build.5"), [1, 2, 3, ["pre", "4"], ["build", "5"]]); - assertVersion(new Version(1, 2, 3), [1, 2, 3]); - assertVersion(new Version(1, 2), [1, 2, 0]); - assertVersion(new Version(1), [1, 0, 0]); + assertVersion(new ts.Version(1, 2, 3, "pre.4", "build.5"), [1, 2, 3, ["pre", "4"], ["build", "5"]]); + assertVersion(new ts.Version(1, 2, 3), [1, 2, 3]); + assertVersion(new ts.Version(1, 2), [1, 2, 0]); + assertVersion(new ts.Version(1), [1, 0, 0]); }); }); it("toString", () => { - assert.strictEqual(new Version(1, 2, 3, "pre.4", "build.5").toString(), "1.2.3-pre.4+build.5"); - assert.strictEqual(new Version(1, 2, 3, "pre.4").toString(), "1.2.3-pre.4"); - assert.strictEqual(new Version(1, 2, 3, /*prerelease*/ undefined, "build.5").toString(), "1.2.3+build.5"); - assert.strictEqual(new Version(1, 2, 3).toString(), "1.2.3"); - assert.strictEqual(new Version(1, 2).toString(), "1.2.0"); - assert.strictEqual(new Version(1).toString(), "1.0.0"); + assert.strictEqual(new ts.Version(1, 2, 3, "pre.4", "build.5").toString(), "1.2.3-pre.4+build.5"); + assert.strictEqual(new ts.Version(1, 2, 3, "pre.4").toString(), "1.2.3-pre.4"); + assert.strictEqual(new ts.Version(1, 2, 3, /*prerelease*/ undefined, "build.5").toString(), "1.2.3+build.5"); + assert.strictEqual(new ts.Version(1, 2, 3).toString(), "1.2.3"); + assert.strictEqual(new ts.Version(1, 2).toString(), "1.2.0"); + assert.strictEqual(new ts.Version(1).toString(), "1.0.0"); }); it("compareTo", () => { // https://semver.org/#spec-item-11 // > Precedence is determined by the first difference when comparing each of these // > identifiers from left to right as follows: Major, minor, and patch versions are // > always compared numerically. - assert.strictEqual(new Version("1.0.0").compareTo(new Version("2.0.0")), Comparison.LessThan); - assert.strictEqual(new Version("1.0.0").compareTo(new Version("1.1.0")), Comparison.LessThan); - assert.strictEqual(new Version("1.0.0").compareTo(new Version("1.0.1")), Comparison.LessThan); - assert.strictEqual(new Version("2.0.0").compareTo(new Version("1.0.0")), Comparison.GreaterThan); - assert.strictEqual(new Version("1.1.0").compareTo(new Version("1.0.0")), Comparison.GreaterThan); - assert.strictEqual(new Version("1.0.1").compareTo(new Version("1.0.0")), Comparison.GreaterThan); - assert.strictEqual(new Version("1.0.0").compareTo(new Version("1.0.0")), Comparison.EqualTo); + assert.strictEqual(new ts.Version("1.0.0").compareTo(new ts.Version("2.0.0")), ts.Comparison.LessThan); + assert.strictEqual(new ts.Version("1.0.0").compareTo(new ts.Version("1.1.0")), ts.Comparison.LessThan); + assert.strictEqual(new ts.Version("1.0.0").compareTo(new ts.Version("1.0.1")), ts.Comparison.LessThan); + assert.strictEqual(new ts.Version("2.0.0").compareTo(new ts.Version("1.0.0")), ts.Comparison.GreaterThan); + assert.strictEqual(new ts.Version("1.1.0").compareTo(new ts.Version("1.0.0")), ts.Comparison.GreaterThan); + assert.strictEqual(new ts.Version("1.0.1").compareTo(new ts.Version("1.0.0")), ts.Comparison.GreaterThan); + assert.strictEqual(new ts.Version("1.0.0").compareTo(new ts.Version("1.0.0")), ts.Comparison.EqualTo); // https://semver.org/#spec-item-11 // > When major, minor, and patch are equal, a pre-release version has lower // > precedence than a normal version. - assert.strictEqual(new Version("1.0.0").compareTo(new Version("1.0.0-pre")), Comparison.GreaterThan); - assert.strictEqual(new Version("1.0.1-pre").compareTo(new Version("1.0.0")), Comparison.GreaterThan); - assert.strictEqual(new Version("1.0.0-pre").compareTo(new Version("1.0.0")), Comparison.LessThan); + assert.strictEqual(new ts.Version("1.0.0").compareTo(new ts.Version("1.0.0-pre")), ts.Comparison.GreaterThan); + assert.strictEqual(new ts.Version("1.0.1-pre").compareTo(new ts.Version("1.0.0")), ts.Comparison.GreaterThan); + assert.strictEqual(new ts.Version("1.0.0-pre").compareTo(new ts.Version("1.0.0")), ts.Comparison.LessThan); // https://semver.org/#spec-item-11 // > identifiers consisting of only digits are compared numerically - assert.strictEqual(new Version("1.0.0-0").compareTo(new Version("1.0.0-1")), Comparison.LessThan); - assert.strictEqual(new Version("1.0.0-1").compareTo(new Version("1.0.0-0")), Comparison.GreaterThan); - assert.strictEqual(new Version("1.0.0-2").compareTo(new Version("1.0.0-10")), Comparison.LessThan); - assert.strictEqual(new Version("1.0.0-10").compareTo(new Version("1.0.0-2")), Comparison.GreaterThan); - assert.strictEqual(new Version("1.0.0-0").compareTo(new Version("1.0.0-0")), Comparison.EqualTo); + assert.strictEqual(new ts.Version("1.0.0-0").compareTo(new ts.Version("1.0.0-1")), ts.Comparison.LessThan); + assert.strictEqual(new ts.Version("1.0.0-1").compareTo(new ts.Version("1.0.0-0")), ts.Comparison.GreaterThan); + assert.strictEqual(new ts.Version("1.0.0-2").compareTo(new ts.Version("1.0.0-10")), ts.Comparison.LessThan); + assert.strictEqual(new ts.Version("1.0.0-10").compareTo(new ts.Version("1.0.0-2")), ts.Comparison.GreaterThan); + assert.strictEqual(new ts.Version("1.0.0-0").compareTo(new ts.Version("1.0.0-0")), ts.Comparison.EqualTo); // https://semver.org/#spec-item-11 // > identifiers with letters or hyphens are compared lexically in ASCII sort order. - assert.strictEqual(new Version("1.0.0-a").compareTo(new Version("1.0.0-b")), Comparison.LessThan); - assert.strictEqual(new Version("1.0.0-a-2").compareTo(new Version("1.0.0-a-10")), Comparison.GreaterThan); - assert.strictEqual(new Version("1.0.0-b").compareTo(new Version("1.0.0-a")), Comparison.GreaterThan); - assert.strictEqual(new Version("1.0.0-a").compareTo(new Version("1.0.0-a")), Comparison.EqualTo); - assert.strictEqual(new Version("1.0.0-A").compareTo(new Version("1.0.0-a")), Comparison.LessThan); + assert.strictEqual(new ts.Version("1.0.0-a").compareTo(new ts.Version("1.0.0-b")), ts.Comparison.LessThan); + assert.strictEqual(new ts.Version("1.0.0-a-2").compareTo(new ts.Version("1.0.0-a-10")), ts.Comparison.GreaterThan); + assert.strictEqual(new ts.Version("1.0.0-b").compareTo(new ts.Version("1.0.0-a")), ts.Comparison.GreaterThan); + assert.strictEqual(new ts.Version("1.0.0-a").compareTo(new ts.Version("1.0.0-a")), ts.Comparison.EqualTo); + assert.strictEqual(new ts.Version("1.0.0-A").compareTo(new ts.Version("1.0.0-a")), ts.Comparison.LessThan); // https://semver.org/#spec-item-11 // > Numeric identifiers always have lower precedence than non-numeric identifiers. - assert.strictEqual(new Version("1.0.0-0").compareTo(new Version("1.0.0-alpha")), Comparison.LessThan); - assert.strictEqual(new Version("1.0.0-alpha").compareTo(new Version("1.0.0-0")), Comparison.GreaterThan); - assert.strictEqual(new Version("1.0.0-0").compareTo(new Version("1.0.0-0")), Comparison.EqualTo); - assert.strictEqual(new Version("1.0.0-alpha").compareTo(new Version("1.0.0-alpha")), Comparison.EqualTo); + assert.strictEqual(new ts.Version("1.0.0-0").compareTo(new ts.Version("1.0.0-alpha")), ts.Comparison.LessThan); + assert.strictEqual(new ts.Version("1.0.0-alpha").compareTo(new ts.Version("1.0.0-0")), ts.Comparison.GreaterThan); + assert.strictEqual(new ts.Version("1.0.0-0").compareTo(new ts.Version("1.0.0-0")), ts.Comparison.EqualTo); + assert.strictEqual(new ts.Version("1.0.0-alpha").compareTo(new ts.Version("1.0.0-alpha")), ts.Comparison.EqualTo); // https://semver.org/#spec-item-11 // > A larger set of pre-release fields has a higher precedence than a smaller set, if all // > of the preceding identifiers are equal. - assert.strictEqual(new Version("1.0.0-alpha").compareTo(new Version("1.0.0-alpha.0")), Comparison.LessThan); - assert.strictEqual(new Version("1.0.0-alpha.0").compareTo(new Version("1.0.0-alpha")), Comparison.GreaterThan); + assert.strictEqual(new ts.Version("1.0.0-alpha").compareTo(new ts.Version("1.0.0-alpha.0")), ts.Comparison.LessThan); + assert.strictEqual(new ts.Version("1.0.0-alpha.0").compareTo(new ts.Version("1.0.0-alpha")), ts.Comparison.GreaterThan); // https://semver.org/#spec-item-11 // > Precedence for two pre-release versions with the same major, minor, and patch version // > MUST be determined by comparing each dot separated identifier from left to right until // > a difference is found [...] - assert.strictEqual(new Version("1.0.0-a.0.b.1").compareTo(new Version("1.0.0-a.0.b.2")), Comparison.LessThan); - assert.strictEqual(new Version("1.0.0-a.0.b.1").compareTo(new Version("1.0.0-b.0.a.1")), Comparison.LessThan); - assert.strictEqual(new Version("1.0.0-a.0.b.2").compareTo(new Version("1.0.0-a.0.b.1")), Comparison.GreaterThan); - assert.strictEqual(new Version("1.0.0-b.0.a.1").compareTo(new Version("1.0.0-a.0.b.1")), Comparison.GreaterThan); + assert.strictEqual(new ts.Version("1.0.0-a.0.b.1").compareTo(new ts.Version("1.0.0-a.0.b.2")), ts.Comparison.LessThan); + assert.strictEqual(new ts.Version("1.0.0-a.0.b.1").compareTo(new ts.Version("1.0.0-b.0.a.1")), ts.Comparison.LessThan); + assert.strictEqual(new ts.Version("1.0.0-a.0.b.2").compareTo(new ts.Version("1.0.0-a.0.b.1")), ts.Comparison.GreaterThan); + assert.strictEqual(new ts.Version("1.0.0-b.0.a.1").compareTo(new ts.Version("1.0.0-a.0.b.1")), ts.Comparison.GreaterThan); // https://semver.org/#spec-item-11 // > Build metadata does not figure into precedence - assert.strictEqual(new Version("1.0.0+build").compareTo(new Version("1.0.0")), Comparison.EqualTo); + assert.strictEqual(new ts.Version("1.0.0+build").compareTo(new ts.Version("1.0.0")), ts.Comparison.EqualTo); }); it("increment", () => { - assertVersion(new Version(1, 2, 3, "pre.4", "build.5").increment("major"), [2, 0, 0]); - assertVersion(new Version(1, 2, 3, "pre.4", "build.5").increment("minor"), [1, 3, 0]); - assertVersion(new Version(1, 2, 3, "pre.4", "build.5").increment("patch"), [1, 2, 4]); + assertVersion(new ts.Version(1, 2, 3, "pre.4", "build.5").increment("major"), [2, 0, 0]); + assertVersion(new ts.Version(1, 2, 3, "pre.4", "build.5").increment("minor"), [1, 3, 0]); + assertVersion(new ts.Version(1, 2, 3, "pre.4", "build.5").increment("patch"), [1, 2, 4]); }); }); describe("VersionRange", () => { function assertRange(rangeText: string, versionText: string, inRange = true) { - const range = new VersionRange(rangeText); - const version = new Version(versionText); + const range = new ts.VersionRange(rangeText); + const version = new ts.Version(versionText); assert.strictEqual(range.test(version), inRange, `Expected version '${version}' ${inRange ? `to be` : `to not be`} in range '${rangeText}' (${range})`); } theory("comparators", assertRange, [ diff --git a/src/testRunner/unittests/services/cancellableLanguageServiceOperations.ts b/src/testRunner/unittests/services/cancellableLanguageServiceOperations.ts index 26ad16d8ebcef..d01b5cd3e155d 100644 --- a/src/testRunner/unittests/services/cancellableLanguageServiceOperations.ts +++ b/src/testRunner/unittests/services/cancellableLanguageServiceOperations.ts @@ -8,29 +8,26 @@ namespace ts { `; it("can cancel signature help mid-request", () => { verifyOperationCancelledAfter(file, 4, service => // Two calls are top-level in services, one is the root type, and the second should be for the parameter type - service.getSignatureHelpItems("file.ts", file.lastIndexOf("f"), emptyOptions)!, r => assert.exists(r.items[0]) - ); + service.getSignatureHelpItems("file.ts", file.lastIndexOf("f"), ts.emptyOptions)!, r => assert.exists(r.items[0])); }); it("can cancel find all references mid-request", () => { verifyOperationCancelledAfter(file, 3, service => // Two calls are top-level in services, one is the root type - service.findReferences("file.ts", file.lastIndexOf("o"))!, r => assert.exists(r[0].definition) - ); + service.findReferences("file.ts", file.lastIndexOf("o"))!, r => assert.exists(r[0].definition)); }); it("can cancel quick info mid-request", () => { verifyOperationCancelledAfter(file, 1, service => // The LS doesn't do any top-level checks on the token for quickinfo, so the first check is within the checker - service.getQuickInfoAtPosition("file.ts", file.lastIndexOf("o"))!, r => assert.exists(r.displayParts) - ); + service.getQuickInfoAtPosition("file.ts", file.lastIndexOf("o"))!, r => assert.exists(r.displayParts)); }); it("can cancel completion entry details mid-request", () => { - const options: FormatCodeSettings = { + const options: ts.FormatCodeSettings = { indentSize: 4, tabSize: 4, newLineCharacter: "\n", convertTabsToSpaces: true, - indentStyle: IndentStyle.Smart, + indentStyle: ts.IndentStyle.Smart, insertSpaceAfterConstructor: false, insertSpaceAfterCommaDelimiter: true, insertSpaceAfterSemicolonInForStatements: true, @@ -47,20 +44,18 @@ namespace ts { placeOpenBraceOnNewLineForControlBlocks: false, }; verifyOperationCancelledAfter(file, 1, service => // The LS doesn't do any top-level checks on the token for completion entry details, so the first check is within the checker - service.getCompletionEntryDetails("file.ts", file.lastIndexOf("f"), "foo", options, /*source*/ undefined, {}, /*data*/ undefined)!, r => assert.exists(r.displayParts) - ); + service.getCompletionEntryDetails("file.ts", file.lastIndexOf("f"), "foo", options, /*source*/ undefined, {}, /*data*/ undefined)!, r => assert.exists(r.displayParts)); }); it("can cancel suggestion diagnostics mid-request", () => { verifyOperationCancelledAfter(file, 1, service => // The LS doesn't do any top-level checks on the token for suggestion diagnostics, so the first check is within the checker - service.getSuggestionDiagnostics("file.js"), r => assert.notEqual(r.length, 0), "file.js", "function foo() { let a = 10; }", { allowJs: true } - ); + service.getSuggestionDiagnostics("file.js"), r => assert.notEqual(r.length, 0), "file.js", "function foo() { let a = 10; }", { allowJs: true }); }); }); - function verifyOperationCancelledAfter(content: string, cancelAfter: number, operation: (service: LanguageService) => T, validator: (arg: T) => void, fileName?: string, fileContent?: string, options?: CompilerOptions) { + function verifyOperationCancelledAfter(content: string, cancelAfter: number, operation: (service: ts.LanguageService) => T, validator: (arg: T) => void, fileName?: string, fileContent?: string, options?: ts.CompilerOptions) { let checks = 0; - const token: HostCancellationToken = { + const token: ts.HostCancellationToken = { isCancellationRequested() { checks++; const result = checks >= cancelAfter; @@ -90,6 +85,6 @@ namespace ts { caught = e; } assert.exists(caught, "Expected operation to be cancelled, but was not"); - assert.instanceOf(caught, OperationCanceledException); + assert.instanceOf(caught, ts.OperationCanceledException); } } diff --git a/src/testRunner/unittests/services/colorization.ts b/src/testRunner/unittests/services/colorization.ts index 4a89ccad56e92..01619e1e13396 100644 --- a/src/testRunner/unittests/services/colorization.ts +++ b/src/testRunner/unittests/services/colorization.ts @@ -77,293 +77,138 @@ describe("unittests:: services:: Colorization", () => { describe("test getClassifications", () => { it("returns correct token classes", () => { - testLexicalClassification("var x: string = \"foo\" ?? \"bar\"; //Hello", - ts.EndOfLineState.None, - keyword("var"), - whitespace(" "), - identifier("x"), - punctuation(":"), - keyword("string"), - operator("="), - stringLiteral("\"foo\""), - whitespace(" "), - operator("??"), - stringLiteral("\"foo\""), - comment("//Hello"), - punctuation(";")); + testLexicalClassification("var x: string = \"foo\" ?? \"bar\"; //Hello", ts.EndOfLineState.None, keyword("var"), whitespace(" "), identifier("x"), punctuation(":"), keyword("string"), operator("="), stringLiteral("\"foo\""), whitespace(" "), operator("??"), stringLiteral("\"foo\""), comment("//Hello"), punctuation(";")); }); it("correctly classifies a comment after a divide operator", () => { - testLexicalClassification("1 / 2 // comment", - ts.EndOfLineState.None, - numberLiteral("1"), - whitespace(" "), - operator("/"), - numberLiteral("2"), - comment("// comment")); + testLexicalClassification("1 / 2 // comment", ts.EndOfLineState.None, numberLiteral("1"), whitespace(" "), operator("/"), numberLiteral("2"), comment("// comment")); }); it("correctly classifies a literal after a divide operator", () => { - testLexicalClassification("1 / 2, 3 / 4", - ts.EndOfLineState.None, - numberLiteral("1"), - whitespace(" "), - operator("/"), - numberLiteral("2"), - numberLiteral("3"), - numberLiteral("4"), - operator(",")); + testLexicalClassification("1 / 2, 3 / 4", ts.EndOfLineState.None, numberLiteral("1"), whitespace(" "), operator("/"), numberLiteral("2"), numberLiteral("3"), numberLiteral("4"), operator(",")); }); it("correctly classifies a multiline string with one backslash", () => { - testLexicalClassification("'line1\\", - ts.EndOfLineState.None, - stringLiteral("'line1\\"), - finalEndOfLineState(ts.EndOfLineState.InSingleQuoteStringLiteral)); + testLexicalClassification("'line1\\", ts.EndOfLineState.None, stringLiteral("'line1\\"), finalEndOfLineState(ts.EndOfLineState.InSingleQuoteStringLiteral)); }); it("correctly classifies a multiline string with three backslashes", () => { - testLexicalClassification("'line1\\\\\\", - ts.EndOfLineState.None, - stringLiteral("'line1\\\\\\"), - finalEndOfLineState(ts.EndOfLineState.InSingleQuoteStringLiteral)); + testLexicalClassification("'line1\\\\\\", ts.EndOfLineState.None, stringLiteral("'line1\\\\\\"), finalEndOfLineState(ts.EndOfLineState.InSingleQuoteStringLiteral)); }); it("correctly classifies an unterminated single-line string with no backslashes", () => { - testLexicalClassification("'line1", - ts.EndOfLineState.None, - stringLiteral("'line1"), - finalEndOfLineState(ts.EndOfLineState.None)); + testLexicalClassification("'line1", ts.EndOfLineState.None, stringLiteral("'line1"), finalEndOfLineState(ts.EndOfLineState.None)); }); it("correctly classifies an unterminated single-line string with two backslashes", () => { - testLexicalClassification("'line1\\\\", - ts.EndOfLineState.None, - stringLiteral("'line1\\\\"), - finalEndOfLineState(ts.EndOfLineState.None)); + testLexicalClassification("'line1\\\\", ts.EndOfLineState.None, stringLiteral("'line1\\\\"), finalEndOfLineState(ts.EndOfLineState.None)); }); it("correctly classifies an unterminated single-line string with four backslashes", () => { - testLexicalClassification("'line1\\\\\\\\", - ts.EndOfLineState.None, - stringLiteral("'line1\\\\\\\\"), - finalEndOfLineState(ts.EndOfLineState.None)); + testLexicalClassification("'line1\\\\\\\\", ts.EndOfLineState.None, stringLiteral("'line1\\\\\\\\"), finalEndOfLineState(ts.EndOfLineState.None)); }); it("correctly classifies the continuing line of a multiline string ending in one backslash", () => { - testLexicalClassification("\\", - ts.EndOfLineState.InDoubleQuoteStringLiteral, - stringLiteral("\\"), - finalEndOfLineState(ts.EndOfLineState.InDoubleQuoteStringLiteral)); + testLexicalClassification("\\", ts.EndOfLineState.InDoubleQuoteStringLiteral, stringLiteral("\\"), finalEndOfLineState(ts.EndOfLineState.InDoubleQuoteStringLiteral)); }); it("correctly classifies the continuing line of a multiline string ending in three backslashes", () => { - testLexicalClassification("\\", - ts.EndOfLineState.InDoubleQuoteStringLiteral, - stringLiteral("\\"), - finalEndOfLineState(ts.EndOfLineState.InDoubleQuoteStringLiteral)); + testLexicalClassification("\\", ts.EndOfLineState.InDoubleQuoteStringLiteral, stringLiteral("\\"), finalEndOfLineState(ts.EndOfLineState.InDoubleQuoteStringLiteral)); }); it("correctly classifies the last line of an unterminated multiline string ending in no backslashes", () => { - testLexicalClassification(" ", - ts.EndOfLineState.InDoubleQuoteStringLiteral, - stringLiteral(" "), - finalEndOfLineState(ts.EndOfLineState.None)); + testLexicalClassification(" ", ts.EndOfLineState.InDoubleQuoteStringLiteral, stringLiteral(" "), finalEndOfLineState(ts.EndOfLineState.None)); }); it("correctly classifies the last line of an unterminated multiline string ending in two backslashes", () => { - testLexicalClassification("\\\\", - ts.EndOfLineState.InDoubleQuoteStringLiteral, - stringLiteral("\\\\"), - finalEndOfLineState(ts.EndOfLineState.None)); + testLexicalClassification("\\\\", ts.EndOfLineState.InDoubleQuoteStringLiteral, stringLiteral("\\\\"), finalEndOfLineState(ts.EndOfLineState.None)); }); it("correctly classifies the last line of an unterminated multiline string ending in four backslashes", () => { - testLexicalClassification("\\\\\\\\", - ts.EndOfLineState.InDoubleQuoteStringLiteral, - stringLiteral("\\\\\\\\"), - finalEndOfLineState(ts.EndOfLineState.None)); + testLexicalClassification("\\\\\\\\", ts.EndOfLineState.InDoubleQuoteStringLiteral, stringLiteral("\\\\\\\\"), finalEndOfLineState(ts.EndOfLineState.None)); }); it("correctly classifies the last line of a multiline string", () => { - testLexicalClassification("'", - ts.EndOfLineState.InSingleQuoteStringLiteral, - stringLiteral("'"), - finalEndOfLineState(ts.EndOfLineState.None)); + testLexicalClassification("'", ts.EndOfLineState.InSingleQuoteStringLiteral, stringLiteral("'"), finalEndOfLineState(ts.EndOfLineState.None)); }); it("correctly classifies an unterminated multiline comment", () => { - testLexicalClassification("/*", - ts.EndOfLineState.None, - comment("/*"), - finalEndOfLineState(ts.EndOfLineState.InMultiLineCommentTrivia)); + testLexicalClassification("/*", ts.EndOfLineState.None, comment("/*"), finalEndOfLineState(ts.EndOfLineState.InMultiLineCommentTrivia)); }); it("correctly classifies the termination of a multiline comment", () => { - testLexicalClassification(" */ ", - ts.EndOfLineState.InMultiLineCommentTrivia, - comment(" */"), - finalEndOfLineState(ts.EndOfLineState.None)); + testLexicalClassification(" */ ", ts.EndOfLineState.InMultiLineCommentTrivia, comment(" */"), finalEndOfLineState(ts.EndOfLineState.None)); }); it("correctly classifies the continuation of a multiline comment", () => { - testLexicalClassification("LOREM IPSUM DOLOR ", - ts.EndOfLineState.InMultiLineCommentTrivia, - comment("LOREM IPSUM DOLOR "), - finalEndOfLineState(ts.EndOfLineState.InMultiLineCommentTrivia)); + testLexicalClassification("LOREM IPSUM DOLOR ", ts.EndOfLineState.InMultiLineCommentTrivia, comment("LOREM IPSUM DOLOR "), finalEndOfLineState(ts.EndOfLineState.InMultiLineCommentTrivia)); }); it("correctly classifies an unterminated multiline comment on a line ending in '/*/'", () => { - testLexicalClassification(" /*/", - ts.EndOfLineState.None, - comment("/*/"), - finalEndOfLineState(ts.EndOfLineState.InMultiLineCommentTrivia)); + testLexicalClassification(" /*/", ts.EndOfLineState.None, comment("/*/"), finalEndOfLineState(ts.EndOfLineState.InMultiLineCommentTrivia)); }); it("correctly classifies an unterminated multiline comment with trailing space", () => { - testLexicalClassification("/* ", - ts.EndOfLineState.None, - comment("/* "), - finalEndOfLineState(ts.EndOfLineState.InMultiLineCommentTrivia)); + testLexicalClassification("/* ", ts.EndOfLineState.None, comment("/* "), finalEndOfLineState(ts.EndOfLineState.InMultiLineCommentTrivia)); }); it("correctly classifies a keyword after a dot", () => { - testLexicalClassification("a.var", - ts.EndOfLineState.None, - identifier("var")); + testLexicalClassification("a.var", ts.EndOfLineState.None, identifier("var")); }); it("correctly classifies a string literal after a dot", () => { - testLexicalClassification("a.\"var\"", - ts.EndOfLineState.None, - stringLiteral("\"var\"")); + testLexicalClassification("a.\"var\"", ts.EndOfLineState.None, stringLiteral("\"var\"")); }); it("correctly classifies a keyword after a dot separated by comment trivia", () => { - testLexicalClassification("a./*hello world*/ var", - ts.EndOfLineState.None, - identifier("a"), - punctuation("."), - comment("/*hello world*/"), - identifier("var")); + testLexicalClassification("a./*hello world*/ var", ts.EndOfLineState.None, identifier("a"), punctuation("."), comment("/*hello world*/"), identifier("var")); }); it("classifies a property access with whitespace around the dot", () => { - testLexicalClassification(" x .\tfoo ()", - ts.EndOfLineState.None, - identifier("x"), - identifier("foo")); + testLexicalClassification(" x .\tfoo ()", ts.EndOfLineState.None, identifier("x"), identifier("foo")); }); it("classifies a keyword after a dot on previous line", () => { - testLexicalClassification("var", - ts.EndOfLineState.None, - keyword("var"), - finalEndOfLineState(ts.EndOfLineState.None)); + testLexicalClassification("var", ts.EndOfLineState.None, keyword("var"), finalEndOfLineState(ts.EndOfLineState.None)); }); it("classifies multiple keywords properly", () => { - testLexicalClassification("public static", - ts.EndOfLineState.None, - keyword("public"), - keyword("static"), - finalEndOfLineState(ts.EndOfLineState.None)); - - testLexicalClassification("public var", - ts.EndOfLineState.None, - keyword("public"), - identifier("var"), - finalEndOfLineState(ts.EndOfLineState.None)); + testLexicalClassification("public static", ts.EndOfLineState.None, keyword("public"), keyword("static"), finalEndOfLineState(ts.EndOfLineState.None)); + testLexicalClassification("public var", ts.EndOfLineState.None, keyword("public"), identifier("var"), finalEndOfLineState(ts.EndOfLineState.None)); }); it("classifies a single line no substitution template string correctly", () => { - testLexicalClassification("`number number public string`", - ts.EndOfLineState.None, - stringLiteral("`number number public string`"), - finalEndOfLineState(ts.EndOfLineState.None)); + testLexicalClassification("`number number public string`", ts.EndOfLineState.None, stringLiteral("`number number public string`"), finalEndOfLineState(ts.EndOfLineState.None)); }); it("classifies substitution parts of a template string correctly", () => { - testLexicalClassification("`number '${ 1 + 1 }' string '${ 'hello' }'`", - ts.EndOfLineState.None, - stringLiteral("`number '${"), - numberLiteral("1"), - operator("+"), - numberLiteral("1"), - stringLiteral("}' string '${"), - stringLiteral("'hello'"), - stringLiteral("}'`"), - finalEndOfLineState(ts.EndOfLineState.None)); + testLexicalClassification("`number '${ 1 + 1 }' string '${ 'hello' }'`", ts.EndOfLineState.None, stringLiteral("`number '${"), numberLiteral("1"), operator("+"), numberLiteral("1"), stringLiteral("}' string '${"), stringLiteral("'hello'"), stringLiteral("}'`"), finalEndOfLineState(ts.EndOfLineState.None)); }); it("classifies an unterminated no substitution template string correctly", () => { - testLexicalClassification("`hello world", - ts.EndOfLineState.None, - stringLiteral("`hello world"), - finalEndOfLineState(ts.EndOfLineState.InTemplateHeadOrNoSubstitutionTemplate)); + testLexicalClassification("`hello world", ts.EndOfLineState.None, stringLiteral("`hello world"), finalEndOfLineState(ts.EndOfLineState.InTemplateHeadOrNoSubstitutionTemplate)); }); it("classifies the entire line of an unterminated multiline no-substitution/head template", () => { - testLexicalClassification("...", - ts.EndOfLineState.InTemplateHeadOrNoSubstitutionTemplate, - stringLiteral("..."), - finalEndOfLineState(ts.EndOfLineState.InTemplateHeadOrNoSubstitutionTemplate)); + testLexicalClassification("...", ts.EndOfLineState.InTemplateHeadOrNoSubstitutionTemplate, stringLiteral("..."), finalEndOfLineState(ts.EndOfLineState.InTemplateHeadOrNoSubstitutionTemplate)); }); it("classifies the entire line of an unterminated multiline template middle/end", () => { - testLexicalClassification("...", - ts.EndOfLineState.InTemplateMiddleOrTail, - stringLiteral("..."), - finalEndOfLineState(ts.EndOfLineState.InTemplateMiddleOrTail)); + testLexicalClassification("...", ts.EndOfLineState.InTemplateMiddleOrTail, stringLiteral("..."), finalEndOfLineState(ts.EndOfLineState.InTemplateMiddleOrTail)); }); it("classifies a termination of a multiline template head", () => { - testLexicalClassification("...${", - ts.EndOfLineState.InTemplateHeadOrNoSubstitutionTemplate, - stringLiteral("...${"), - finalEndOfLineState(ts.EndOfLineState.InTemplateSubstitutionPosition)); + testLexicalClassification("...${", ts.EndOfLineState.InTemplateHeadOrNoSubstitutionTemplate, stringLiteral("...${"), finalEndOfLineState(ts.EndOfLineState.InTemplateSubstitutionPosition)); }); it("classifies the termination of a multiline no substitution template", () => { - testLexicalClassification("...`", - ts.EndOfLineState.InTemplateHeadOrNoSubstitutionTemplate, - stringLiteral("...`"), - finalEndOfLineState(ts.EndOfLineState.None)); + testLexicalClassification("...`", ts.EndOfLineState.InTemplateHeadOrNoSubstitutionTemplate, stringLiteral("...`"), finalEndOfLineState(ts.EndOfLineState.None)); }); it("classifies the substitution parts and middle/tail of a multiline template string", () => { - testLexicalClassification("${ 1 + 1 }...`", - ts.EndOfLineState.InTemplateHeadOrNoSubstitutionTemplate, - stringLiteral("${"), - numberLiteral("1"), - operator("+"), - numberLiteral("1"), - stringLiteral("}...`"), - finalEndOfLineState(ts.EndOfLineState.None)); + testLexicalClassification("${ 1 + 1 }...`", ts.EndOfLineState.InTemplateHeadOrNoSubstitutionTemplate, stringLiteral("${"), numberLiteral("1"), operator("+"), numberLiteral("1"), stringLiteral("}...`"), finalEndOfLineState(ts.EndOfLineState.None)); }); it("classifies a template middle and propagates the end of line state", () => { - testLexicalClassification("${ 1 + 1 }...`", - ts.EndOfLineState.InTemplateHeadOrNoSubstitutionTemplate, - stringLiteral("${"), - numberLiteral("1"), - operator("+"), - numberLiteral("1"), - stringLiteral("}...`"), - finalEndOfLineState(ts.EndOfLineState.None)); + testLexicalClassification("${ 1 + 1 }...`", ts.EndOfLineState.InTemplateHeadOrNoSubstitutionTemplate, stringLiteral("${"), numberLiteral("1"), operator("+"), numberLiteral("1"), stringLiteral("}...`"), finalEndOfLineState(ts.EndOfLineState.None)); }); it("classifies substitution expressions with curly braces appropriately", () => { let pos = 0; let lastLength = 0; - testLexicalClassification("...${ () => { } } ${ { x: `1` } }...`", - ts.EndOfLineState.InTemplateHeadOrNoSubstitutionTemplate, - stringLiteral(track("...${"), pos), - punctuation(track(" ", "("), pos), - punctuation(track(")"), pos), - punctuation(track(" ", "=>"), pos), - punctuation(track(" ", "{"), pos), - punctuation(track(" ", "}"), pos), - stringLiteral(track(" ", "} ${"), pos), - punctuation(track(" ", "{"), pos), - identifier(track(" ", "x"), pos), - punctuation(track(":"), pos), - stringLiteral(track(" ", "`1`"), pos), - punctuation(track(" ", "}"), pos), - stringLiteral(track(" ", "}...`"), pos), - finalEndOfLineState(ts.EndOfLineState.None)); + testLexicalClassification("...${ () => { } } ${ { x: `1` } }...`", ts.EndOfLineState.InTemplateHeadOrNoSubstitutionTemplate, stringLiteral(track("...${"), pos), punctuation(track(" ", "("), pos), punctuation(track(")"), pos), punctuation(track(" ", "=>"), pos), punctuation(track(" ", "{"), pos), punctuation(track(" ", "}"), pos), stringLiteral(track(" ", "} ${"), pos), punctuation(track(" ", "{"), pos), identifier(track(" ", "x"), pos), punctuation(track(":"), pos), stringLiteral(track(" ", "`1`"), pos), punctuation(track(" ", "}"), pos), stringLiteral(track(" ", "}...`"), pos), finalEndOfLineState(ts.EndOfLineState.None)); // Adjusts 'pos' by accounting for the length of each portion of the string, // but only return the last given string @@ -377,75 +222,30 @@ describe("unittests:: services:: Colorization", () => { }); it("classifies partially written generics correctly.", () => { - testLexicalClassification("Foo { // Test conflict markers. - testLexicalClassification( - "class C {\r\n\ + testLexicalClassification("class C {\r\n\ <<<<<<< HEAD\r\n\ v = 1;\r\n\ =======\r\n\ v = 2;\r\n\ >>>>>>> Branch - a\r\n\ -}", - ts.EndOfLineState.None, - keyword("class"), - identifier("C"), - punctuation("{"), - comment("<<<<<<< HEAD"), - identifier("v"), - operator("="), - numberLiteral("1"), - punctuation(";"), - comment("=======\r\n v = 2;\r\n"), - comment(">>>>>>> Branch - a"), - punctuation("}"), - finalEndOfLineState(ts.EndOfLineState.None)); - - testLexicalClassification( - "<<<<<<< HEAD\r\n\ +}", ts.EndOfLineState.None, keyword("class"), identifier("C"), punctuation("{"), comment("<<<<<<< HEAD"), identifier("v"), operator("="), numberLiteral("1"), punctuation(";"), comment("=======\r\n v = 2;\r\n"), comment(">>>>>>> Branch - a"), punctuation("}"), finalEndOfLineState(ts.EndOfLineState.None)); + testLexicalClassification("<<<<<<< HEAD\r\n\ class C { }\r\n\ =======\r\n\ class D { }\r\n\ ->>>>>>> Branch - a\r\n", - ts.EndOfLineState.None, - comment("<<<<<<< HEAD"), - keyword("class"), - identifier("C"), - punctuation("{"), - punctuation("}"), - comment("=======\r\nclass D { }\r\n"), - comment(">>>>>>> Branch - a"), - finalEndOfLineState(ts.EndOfLineState.None)); - - testLexicalClassification( - "class C {\r\n\ +>>>>>>> Branch - a\r\n", ts.EndOfLineState.None, comment("<<<<<<< HEAD"), keyword("class"), identifier("C"), punctuation("{"), punctuation("}"), comment("=======\r\nclass D { }\r\n"), comment(">>>>>>> Branch - a"), finalEndOfLineState(ts.EndOfLineState.None)); + testLexicalClassification("class C {\r\n\ <<<<<<< HEAD\r\n\ v = 1;\r\n\ ||||||| merged common ancestors\r\n\ @@ -453,55 +253,18 @@ class D { }\r\n\ =======\r\n\ v = 2;\r\n\ >>>>>>> Branch - a\r\n\ -}", - ts.EndOfLineState.None, - keyword("class"), - identifier("C"), - punctuation("{"), - comment("<<<<<<< HEAD"), - identifier("v"), - operator("="), - numberLiteral("1"), - punctuation(";"), - comment("||||||| merged common ancestors\r\n v = 3;\r\n"), - comment("=======\r\n v = 2;\r\n"), - comment(">>>>>>> Branch - a"), - punctuation("}"), - finalEndOfLineState(ts.EndOfLineState.None)); - - testLexicalClassification( - "<<<<<<< HEAD\r\n\ +}", ts.EndOfLineState.None, keyword("class"), identifier("C"), punctuation("{"), comment("<<<<<<< HEAD"), identifier("v"), operator("="), numberLiteral("1"), punctuation(";"), comment("||||||| merged common ancestors\r\n v = 3;\r\n"), comment("=======\r\n v = 2;\r\n"), comment(">>>>>>> Branch - a"), punctuation("}"), finalEndOfLineState(ts.EndOfLineState.None)); + testLexicalClassification("<<<<<<< HEAD\r\n\ class C { }\r\n\ ||||||| merged common ancestors\r\n\ class E { }\r\n\ =======\r\n\ class D { }\r\n\ ->>>>>>> Branch - a\r\n", - ts.EndOfLineState.None, - comment("<<<<<<< HEAD"), - keyword("class"), - identifier("C"), - punctuation("{"), - punctuation("}"), - comment("||||||| merged common ancestors\r\nclass E { }\r\n"), - comment("=======\r\nclass D { }\r\n"), - comment(">>>>>>> Branch - a"), - finalEndOfLineState(ts.EndOfLineState.None)); +>>>>>>> Branch - a\r\n", ts.EndOfLineState.None, comment("<<<<<<< HEAD"), keyword("class"), identifier("C"), punctuation("{"), punctuation("}"), comment("||||||| merged common ancestors\r\nclass E { }\r\n"), comment("=======\r\nclass D { }\r\n"), comment(">>>>>>> Branch - a"), finalEndOfLineState(ts.EndOfLineState.None)); }); it("'of' keyword", () => { - testLexicalClassification("for (var of of of) { }", - ts.EndOfLineState.None, - keyword("for"), - punctuation("("), - keyword("var"), - keyword("of"), - keyword("of"), - keyword("of"), - punctuation(")"), - punctuation("{"), - punctuation("}"), - finalEndOfLineState(ts.EndOfLineState.None)); + testLexicalClassification("for (var of of of) { }", ts.EndOfLineState.None, keyword("for"), punctuation("("), keyword("var"), keyword("of"), keyword("of"), keyword("of"), punctuation(")"), punctuation("{"), punctuation("}"), finalEndOfLineState(ts.EndOfLineState.None)); }); }); }); diff --git a/src/testRunner/unittests/services/convertToAsyncFunction.ts b/src/testRunner/unittests/services/convertToAsyncFunction.ts index a8bd6e6d520c0..2e545a7094df4 100644 --- a/src/testRunner/unittests/services/convertToAsyncFunction.ts +++ b/src/testRunner/unittests/services/convertToAsyncFunction.ts @@ -1,5 +1,5 @@ namespace ts { - const libFile: TestFSWithWatch.File = { + const libFile: ts.TestFSWithWatch.File = { path: "/a/lib/lib.d.ts", content: `/// interface Boolean {} @@ -262,10 +262,9 @@ interface String { charAt: any; } interface Array {}` }; - const moduleFile: TestFSWithWatch.File = { + const moduleFile: ts.TestFSWithWatch.File = { path: "/module.ts", - content: -`export function fn(res: any): any { + content: `export function fn(res: any): any { return res; }` }; @@ -294,7 +293,7 @@ interface Array {}` ExpectNoAction = 1 << 5, ExpectSuccess = ExpectSuggestionDiagnostic | ExpectAction, - ExpectFailed = ExpectNoSuggestionDiagnostic | ExpectNoAction, + ExpectFailed = ExpectNoSuggestionDiagnostic | ExpectNoAction } function testConvertToAsyncFunction(it: Mocha.PendingTestFunction, caption: string, text: string, baselineFolder: string, flags: ConvertToAsyncTestFlags) { @@ -305,28 +304,24 @@ interface Array {}` const expectAction = !!(flags & ConvertToAsyncTestFlags.ExpectAction); const expectNoAction = !!(flags & ConvertToAsyncTestFlags.ExpectNoAction); const expectFailure = expectNoSuggestionDiagnostic || expectNoAction; - Debug.assert(!(expectSuggestionDiagnostic && expectNoSuggestionDiagnostic), "Cannot combine both 'ExpectSuggestionDiagnostic' and 'ExpectNoSuggestionDiagnostic'"); - Debug.assert(!(expectAction && expectNoAction), "Cannot combine both 'ExpectAction' and 'ExpectNoAction'"); - - const t = extractTest(text); + ts.Debug.assert(!(expectSuggestionDiagnostic && expectNoSuggestionDiagnostic), "Cannot combine both 'ExpectSuggestionDiagnostic' and 'ExpectNoSuggestionDiagnostic'"); + ts.Debug.assert(!(expectAction && expectNoAction), "Cannot combine both 'ExpectAction' and 'ExpectNoAction'"); + const t = ts.extractTest(text); const selectionRange = t.ranges.get("selection")!; if (!selectionRange) { throw new Error(`Test ${caption} does not specify selection range`); } - const extensions = expectFailure ? [Extension.Ts] : [Extension.Ts, Extension.Js]; - - extensions.forEach(extension => - it(`${caption} [${extension}]`, () => runBaseline(extension))); - - function runBaseline(extension: Extension) { + const extensions = expectFailure ? [ts.Extension.Ts] : [ts.Extension.Ts, ts.Extension.Js]; + extensions.forEach(extension => it(`${caption} [${extension}]`, () => runBaseline(extension))); + function runBaseline(extension: ts.Extension) { const path = "/a" + extension; const languageService = makeLanguageService({ path, content: t.source }, includeLib, includeModule); const program = languageService.getProgram()!; if (hasSyntacticDiagnostics(program)) { // Don't bother generating JS baselines for inputs that aren't valid JS. - assert.equal(Extension.Js, extension, "Syntactic diagnostics found in non-JS file"); + assert.equal(ts.Extension.Js, extension, "Syntactic diagnostics found in non-JS file"); return; } @@ -336,22 +331,22 @@ interface Array {}` }; const sourceFile = program.getSourceFile(path)!; - const context: CodeFixContext = { + const context: ts.CodeFixContext = { errorCode: 80006, span: { start: selectionRange.pos, length: selectionRange.end - selectionRange.pos }, sourceFile, program, - cancellationToken: { throwIfCancellationRequested: noop, isCancellationRequested: returnFalse }, - preferences: emptyOptions, - host: notImplementedHost, - formatContext: formatting.getFormatContext(testFormatSettings, notImplementedHost) + cancellationToken: { throwIfCancellationRequested: ts.noop, isCancellationRequested: ts.returnFalse }, + preferences: ts.emptyOptions, + host: ts.notImplementedHost, + formatContext: ts.formatting.getFormatContext(ts.testFormatSettings, ts.notImplementedHost) }; const diagnostics = languageService.getSuggestionDiagnostics(f.path); - const diagnostic = find(diagnostics, diagnostic => diagnostic.messageText === Diagnostics.This_may_be_converted_to_an_async_function.message && + const diagnostic = ts.find(diagnostics, diagnostic => diagnostic.messageText === ts.Diagnostics.This_may_be_converted_to_an_async_function.message && diagnostic.start === context.span.start && diagnostic.length === context.span.length); - const actions = codefix.getFixes(context); - const action = find(actions, action => action.description === Diagnostics.Convert_to_async_function.message); + const actions = ts.codefix.getFixes(context); + const action = ts.find(actions, action => action.description === ts.Diagnostics.Convert_to_async_function.message); let outputText: string | null; if (action?.changes.length) { @@ -362,12 +357,12 @@ interface Array {}` assert.lengthOf(changes, 1); data.push(`// ==ASYNC FUNCTION::${action.description}==`); - const newText = textChanges.applyChanges(sourceFile.text, changes[0].textChanges); + const newText = ts.textChanges.applyChanges(sourceFile.text, changes[0].textChanges); data.push(newText); const diagProgram = makeLanguageService({ path, content: newText }, includeLib, includeModule).getProgram()!; assert.isFalse(hasSyntacticDiagnostics(diagProgram)); - outputText = data.join(newLineCharacter); + outputText = data.join(ts.newLineCharacter); } else { // eslint-disable-next-line no-null/no-null @@ -393,7 +388,7 @@ interface Array {}` } } - function makeLanguageService(file: TestFSWithWatch.File, includeLib?: boolean, includeModule?: boolean) { + function makeLanguageService(file: ts.TestFSWithWatch.File, includeLib?: boolean, includeModule?: boolean) { const files = [file]; if (includeLib) { files.push(libFile); // libFile is expensive to parse repeatedly - only test when required @@ -401,15 +396,15 @@ interface Array {}` if (includeModule) { files.push(moduleFile); } - const host = projectSystem.createServerHost(files); - const projectService = projectSystem.createProjectService(host); + const host = ts.projectSystem.createServerHost(files); + const projectService = ts.projectSystem.createProjectService(host); projectService.openClientFile(file.path); - return first(projectService.inferredProjects).getLanguageService(); + return ts.first(projectService.inferredProjects).getLanguageService(); } - function hasSyntacticDiagnostics(program: Program) { + function hasSyntacticDiagnostics(program: ts.Program) { const diags = program.getSyntacticDiagnostics(); - return length(diags) > 0; + return ts.length(diags) > 0; } } @@ -512,44 +507,37 @@ function catch_err(err){ _testConvertToAsyncFunction("convertToAsyncFunction_CatchNoBrackets", ` function [#|f|]():Promise { return fetch('https://typescriptlang.org').then(result => console.log(result)).catch(err => console.log(err)); -}` - ); +}`); _testConvertToAsyncFunction("convertToAsyncFunction_IgnoreArgs1", ` function [#|f|](): Promise { return fetch('https://typescriptlang.org').then( _ => { console.log("done"); }); -}` - ); +}`); _testConvertToAsyncFunction("convertToAsyncFunction_IgnoreArgs2", ` function [#|f|](): Promise { return fetch('https://typescriptlang.org').then( () => console.log("done") ); -}` - ); +}`); _testConvertToAsyncFunction("convertToAsyncFunction_IgnoreArgs3", ` function [#|f|](): Promise { return fetch('https://typescriptlang.org').then( () => console.log("almost done") ).then( () => console.log("done") ); -}` - ); +}`); _testConvertToAsyncFunction("convertToAsyncFunction_IgnoreArgs4", ` function [#|f|]() { return fetch('https://typescriptlang.org').then(res); } function res(){ console.log("done"); -}` - ); +}`); _testConvertToAsyncFunction("convertToAsyncFunction_Method", ` class Parser { [#|f|]():Promise { return fetch('https://typescriptlang.org').then(result => console.log(result)); } -}` - ); +}`); _testConvertToAsyncFunction("convertToAsyncFunction_MultipleCatches", ` function [#|f|](): Promise { return fetch('https://typescriptlang.org').then(res => console.log(res)).catch(err => console.log("err", err)).catch(err2 => console.log("err2", err2)); -}` - ); +}`); _testConvertToAsyncFunction("convertToAsyncFunction_MultipleThens", ` function [#|f|]():Promise { return fetch('https://typescriptlang.org').then(res).then(res2); @@ -559,8 +547,7 @@ function res(result){ } function res2(result2){ console.log(result2); -}` - ); +}`); _testConvertToAsyncFunction("convertToAsyncFunction_MultipleThensSameVarName", ` function [#|f|]():Promise { return fetch('https://typescriptlang.org').then(res).then(res2); @@ -571,64 +558,54 @@ function res(result){ function res2(result){ return result.bodyUsed; } -` - ); +`); _testConvertToAsyncFunction("convertToAsyncFunction_NoRes", ` function [#|f|]():Promise { return fetch('https://typescriptlang.org').then(null, rejection => console.log("rejected:", rejection)); } -` - ); +`); _testConvertToAsyncFunction("convertToAsyncFunction_NoRes2", ` function [#|f|]():Promise { return fetch('https://typescriptlang.org').then(undefined).catch(rej => console.log(rej)); } -` - ); +`); _testConvertToAsyncFunction("convertToAsyncFunction_NoRes3", ` function [#|f|]():Promise { return fetch('https://typescriptlang.org').catch(rej => console.log(rej)); } -` - ); +`); _testConvertToAsyncFunction("convertToAsyncFunction_NoRes4", ` function [#|f|]() { return fetch('https://typescriptlang.org').then(undefined, rejection => console.log("rejected:", rejection)); } -` - ); +`); _testConvertToAsyncFunction("convertToAsyncFunction_NoCatchHandler", ` function [#|f|]() { return fetch('https://typescriptlang.org').then(x => x.statusText).catch(undefined); } -` - ); +`); _testConvertToAsyncFunctionFailed("convertToAsyncFunction_NoSuggestion", ` function [#|f|]():Promise { return fetch('https://typescriptlang.org'); } -` - ); +`); _testConvertToAsyncFunction("convertToAsyncFunction_PromiseDotAll", ` function [#|f|]():Promise{ return Promise.all([fetch('https://typescriptlang.org'), fetch('https://microsoft.com'), fetch('https://youtube.com')]).then(function(vals){ vals.forEach(console.log); }); } -` - ); +`); _testConvertToAsyncFunctionFailed("convertToAsyncFunction_NoSuggestionNoPromise", ` function [#|f|]():void{ } -` - ); +`); _testConvertToAsyncFunctionFailed("convertToAsyncFunction_Rej", ` function [#|f|]():Promise { return fetch('https://typescriptlang.org').then(result => { console.log(result); }, rejection => { console.log("rejected:", rejection); }); } -` - ); +`); _testConvertToAsyncFunctionFailed("convertToAsyncFunction_RejRef", ` function [#|f|]():Promise { return fetch('https://typescriptlang.org').then(res, rej); @@ -639,14 +616,12 @@ function res(result){ function rej(err){ console.log(err); } -` - ); +`); _testConvertToAsyncFunctionFailed("convertToAsyncFunction_RejNoBrackets", ` function [#|f|]():Promise { return fetch('https://typescriptlang.org').then(result => console.log(result), rejection => console.log("rejected:", rejection)); } -` - ); +`); _testConvertToAsyncFunction("convertToAsyncFunction_ResRef", ` function [#|f|]():Promise { @@ -655,8 +630,7 @@ function [#|f|]():Promise { function res(result){ return result.ok; } -` - ); +`); _testConvertToAsyncFunction("convertToAsyncFunction_ResRef1", ` class Foo { @@ -687,16 +661,14 @@ const res = (result) => { function [#|f|](): Promise { return fetch('https://typescriptlang.org').then(res); } - ` - ); + `); _testConvertToAsyncFunctionFailed("convertToAsyncFunction_NoSuggestionResRef1", ` const res = 1; function [#|f|]() { return fetch('https://typescriptlang.org').then(res); } -` - ); +`); _testConvertToAsyncFunctionFailed("convertToAsyncFunction_NoSuggestionResRef2", ` class Foo { @@ -705,16 +677,14 @@ class Foo { return fetch('a').then(this.foo); } } -` - ); +`); _testConvertToAsyncFunctionFailed("convertToAsyncFunction_NoSuggestionResRef3", ` const res = undefined; function [#|f|]() { return fetch('https://typescriptlang.org').then(res); } -` - ); +`); _testConvertToAsyncFunctionFailed("convertToAsyncFunction_NoSuggestionResRef4", ` class Foo { @@ -723,8 +693,7 @@ class Foo { return fetch('a').then(this.foo); } } -` - ); +`); _testConvertToAsyncFunction("convertToAsyncFunction_ResRefNoReturnVal", ` function [#|f|]():Promise { @@ -733,8 +702,7 @@ function [#|f|]():Promise { function res(result){ console.log(result); } -` - ); +`); _testConvertToAsyncFunction("convertToAsyncFunction_ResRefNoReturnVal1", ` class Foo { @@ -752,28 +720,24 @@ class Foo { function [#|f|]():Promise { return fetch('https://typescriptlang.org').then(result => console.log(result)); } -` - ); +`); _testConvertToAsyncFunctionFailed("convertToAsyncFunction_Finally1", ` function [#|finallyTest|](): Promise { return fetch("https://typescriptlang.org").then(res => console.log(res)).catch(rej => console.log("error", rej)).finally(console.log("finally!")); } -` - ); +`); _testConvertToAsyncFunctionFailed("convertToAsyncFunction_Finally2", ` function [#|finallyTest|](): Promise { return fetch("https://typescriptlang.org").then(res => console.log(res)).finally(console.log("finally!")); } -` - ); +`); _testConvertToAsyncFunctionFailed("convertToAsyncFunction_Finally3", ` function [#|finallyTest|](): Promise { return fetch("https://typescriptlang.org").finally(console.log("finally!")); } -` - ); +`); _testConvertToAsyncFunction("convertToAsyncFunction_InnerPromise", ` function [#|innerPromise|](): Promise { return fetch("https://typescriptlang.org").then(resp => { @@ -783,8 +747,7 @@ function [#|innerPromise|](): Promise { return blob.toString(); }); } -` - ); +`); _testConvertToAsyncFunction("convertToAsyncFunction_InnerPromiseRet", ` function [#|innerPromise|](): Promise { return fetch("https://typescriptlang.org").then(resp => { @@ -793,8 +756,7 @@ function [#|innerPromise|](): Promise { return blob.toString(); }); } -` - ); +`); _testConvertToAsyncFunction("convertToAsyncFunction_InnerPromiseRetBinding1", ` function [#|innerPromise|](): Promise { @@ -804,8 +766,7 @@ function [#|innerPromise|](): Promise { return blob.toString(); }); } -` - ); +`); _testConvertToAsyncFunction("convertToAsyncFunction_InnerPromiseRetBinding2", ` function [#|innerPromise|](): Promise { @@ -815,8 +776,7 @@ function [#|innerPromise|](): Promise { return x.toString(); }); } -` - ); +`); _testConvertToAsyncFunction("convertToAsyncFunction_InnerPromiseRetBinding3", ` function [#|innerPromise|](): Promise { @@ -826,8 +786,7 @@ function [#|innerPromise|](): Promise { return (x || y).toString(); }); } -` - ); +`); _testConvertToAsyncFunction("convertToAsyncFunction_InnerPromiseRetBinding4", ` function [#|innerPromise|](): Promise { @@ -837,24 +796,21 @@ function [#|innerPromise|](): Promise { return (x || y).toString(); }); } -` - ); +`); _testConvertToAsyncFunctionFailed("convertToAsyncFunction_VarReturn01", ` function [#|f|]() { let blob = fetch("https://typescriptlang.org").then(resp => console.log(resp)); return blob; } -` - ); +`); _testConvertToAsyncFunctionFailed("convertToAsyncFunction_VarReturn02", ` function [#|f|]() { let blob = fetch("https://typescriptlang.org"); blob.then(resp => console.log(resp)); return blob; } -` - ); +`); _testConvertToAsyncFunctionFailed("convertToAsyncFunction_VarReturn03", ` function [#|f|]() { let blob = fetch("https://typescriptlang.org") @@ -866,8 +822,7 @@ function [#|f|]() { function err (rej) { console.log(rej) } -` - ); +`); _testConvertToAsyncFunctionFailed("convertToAsyncFunction_VarReturn04", ` function [#|f|]() { var blob = fetch("https://typescriptlang.org").then(res => console.log(res)), blob2 = fetch("https://microsoft.com").then(res => res.ok).catch(err); @@ -876,8 +831,7 @@ function [#|f|]() { function err (rej) { console.log(rej) } -` - ); +`); _testConvertToAsyncFunctionFailed("convertToAsyncFunction_VarReturn05", ` function [#|f|]() { @@ -885,16 +839,14 @@ function [#|f|]() { blob.then(x => x); return blob; } -` - ); +`); _testConvertToAsyncFunctionFailed("convertToAsyncFunction_VarReturn06", ` function [#|f|]() { var blob = fetch("https://typescriptlang.org"); return blob; } -` - ); +`); _testConvertToAsyncFunctionFailed("convertToAsyncFunction_VarReturn07", ` function [#|f|]() { @@ -904,8 +856,7 @@ function [#|f|]() { blob.then(resp => console.log(resp)); return blob; } -` - ); +`); _testConvertToAsyncFunctionFailed("convertToAsyncFunction_VarReturn08", ` function [#|f|]() { @@ -916,8 +867,7 @@ function [#|f|]() { blob.then(resp => console.log(resp)); return blob; } -` - ); +`); _testConvertToAsyncFunctionFailed("convertToAsyncFunction_VarReturn09", ` function [#|f|]() { @@ -929,8 +879,7 @@ function [#|f|]() { blob3 = blob2.catch(rej => rej.ok); return blob; } -` - ); +`); _testConvertToAsyncFunctionFailed("convertToAsyncFunction_VarReturn10", ` @@ -944,16 +893,14 @@ function [#|f|]() { blob3 = blob2; return blob; } -` - ); +`); _testConvertToAsyncFunctionFailed("convertToAsyncFunction_VarReturn11", ` function [#|f|]() { let blob; return blob; } -` - ); +`); @@ -968,8 +915,7 @@ function my_print (resp) { return resp; } -` - ); +`); _testConvertToAsyncFunction("convertToAsyncFunction_Param2", ` function [#|f|]() { @@ -983,8 +929,7 @@ function my_print (resp): Promise { } -` - ); +`); _testConvertToAsyncFunction("convertToAsyncFunction_MultipleReturns1", ` function [#|f|](): Promise { @@ -996,8 +941,7 @@ function [#|f|](): Promise { var blob = resp.blob().then(blob => blob.byteOffset).catch(err => 'Error'); }); } -` - ); +`); _testConvertToAsyncFunction("convertToAsyncFunction_MultipleReturns2", ` function [#|f|](): Promise { @@ -1010,8 +954,7 @@ function [#|f|](): Promise { return fetch("https://microsoft.com").then(res => console.log("Another one!")); }); } -` - ); +`); _testConvertToAsyncFunctionFailed("convertToAsyncFunction_SeperateLines", ` @@ -1026,8 +969,7 @@ function [#|f|](): Promise { return blob; } -` - ); +`); _testConvertToAsyncFunction("convertToAsyncFunction_InnerVarNameConflict", ` @@ -1038,8 +980,7 @@ function [#|f|](): Promise { return blob.toString(); }); } -` - ); +`); _testConvertToAsyncFunction("convertToAsyncFunction_InnerPromiseSimple", ` function [#|f|](): Promise { return fetch("https://typescriptlang.org").then(resp => { @@ -1048,8 +989,7 @@ function [#|f|](): Promise { return blob.toString(); }); } -` - ); +`); _testConvertToAsyncFunction("convertToAsyncFunction_PromiseAllAndThen1", ` function [#|f|]() { return Promise.resolve().then(function () { @@ -1058,8 +998,7 @@ function [#|f|]() { }).then(res => res.toString())]); }); } -` - ); +`); _testConvertToAsyncFunction("convertToAsyncFunction_PromiseAllAndThen2", ` function [#|f|]() { @@ -1069,8 +1008,7 @@ function [#|f|]() { })]).then(res => res.toString()); }); } -` - ); +`); _testConvertToAsyncFunction("convertToAsyncFunction_PromiseAllAndThen3", ` function [#|f|]() { @@ -1079,8 +1017,7 @@ function [#|f|]() { return fetch("https://github.com"); }).then(res => res.toString())])); } -` - ); +`); _testConvertToAsyncFunction("convertToAsyncFunction_PromiseAllAndThen4", ` function [#|f|]() { @@ -1089,8 +1026,7 @@ function [#|f|]() { return fetch("https://github.com"); })]).then(res => res.toString())); } -` - ); +`); _testConvertToAsyncFunction("convertToAsyncFunction_Scope1", ` function [#|f|]() { var var1: Response, var2; @@ -1124,8 +1060,7 @@ function [#|f|](){ } }); } -` - ); +`); _testConvertToAsyncFunction("convertToAsyncFunction_CatchFollowedByThen", ` function [#|f|](){ @@ -1139,8 +1074,7 @@ function res(result){ function rej(reject){ return reject; } -` - ); +`); _testConvertToAsyncFunction("convertToAsyncFunction_CatchFollowedByThenMatchingTypes01", ` function [#|f|](){ @@ -1154,8 +1088,7 @@ function res(result): number { function rej(reject): number { return 3; } -` - ); +`); _testConvertToAsyncFunction("convertToAsyncFunction_CatchFollowedByThenMatchingTypes01NoAnnotations", ` function [#|f|](){ @@ -1169,8 +1102,7 @@ function res(result){ function rej(reject){ return 3; } -` - ); +`); _testConvertToAsyncFunction("convertToAsyncFunction_CatchFollowedByThenMatchingTypes02", ` @@ -1181,8 +1113,7 @@ function [#|f|](){ function res(result): number { return 5; } -` - ); +`); _testConvertToAsyncFunction("convertToAsyncFunction_CatchFollowedByThenMatchingTypes02NoAnnotations", ` function [#|f|](){ @@ -1192,8 +1123,7 @@ function [#|f|](){ function res(result){ return 5; } -` - ); +`); _testConvertToAsyncFunction("convertToAsyncFunction_CatchFollowedByThenMismatchTypes01", ` function [#|f|](){ @@ -1207,8 +1137,7 @@ function res(result){ function rej(reject){ return "Error"; } -` - ); +`); _testConvertToAsyncFunction("convertToAsyncFunction_CatchFollowedByThenMismatchTypes02", ` function [#|f|](){ @@ -1222,8 +1151,7 @@ function res(result){ function rej(reject): Response{ return reject; } -` - ); +`); _testConvertToAsyncFunction("convertToAsyncFunction_CatchFollowedByThenMismatchTypes02NoAnnotations", ` function [#|f|](){ @@ -1237,8 +1165,7 @@ function res(result){ function rej(reject){ return reject; } -` - ); +`); _testConvertToAsyncFunction("convertToAsyncFunction_CatchFollowedByThenMismatchTypes03", ` @@ -1253,8 +1180,7 @@ function res(result){ function rej(reject){ return Promise.resolve(1); } -` - ); +`); _testConvertToAsyncFunction("convertToAsyncFunction_CatchFollowedByThenMismatchTypes04", ` interface a { @@ -1278,8 +1204,7 @@ function res(result): b{ function rej(reject): a{ return {name: "myName", age: 27}; } -` - ); +`); _testConvertToAsyncFunction("convertToAsyncFunction_ParameterNameCollision", ` async function foo(x: T): Promise { @@ -1289,30 +1214,26 @@ async function foo(x: T): Promise { function [#|bar|](x: T): Promise { return foo(x).then(foo) } -` - ); +`); _testConvertToAsyncFunction("convertToAsyncFunction_Return1", ` function [#|f|](p: Promise) { return p.catch((error: Error) => { return Promise.reject(error); }); -}` - ); +}`); _testConvertToAsyncFunction("convertToAsyncFunction_Return2", ` function [#|f|](p: Promise) { return p.catch((error: Error) => Promise.reject(error)); -}` - ); +}`); _testConvertToAsyncFunction("convertToAsyncFunction_Return3", ` function [#|f|](p: Promise) { return p.catch(function (error: Error) { return Promise.reject(error); }); -}` - ); +}`); _testConvertToAsyncFunction("convertToAsyncFunction_LocalReturn", ` function [#|f|]() { @@ -1339,16 +1260,14 @@ function res(result){ function rej(reject){ return reject; } -` - ); +`); _testConvertToAsyncFunction("convertToAsyncFunction_Scope2", ` function [#|f|](){ var i:number; return fetch("https://typescriptlang.org").then(i => i.ok).then(res => i+1).catch(err => i-1) } -` - ); +`); _testConvertToAsyncFunction("convertToAsyncFunction_Loop", ` function [#|f|](){ @@ -1356,8 +1275,7 @@ function [#|f|](){ console.log(res); }}) } -` - ); +`); _testConvertToAsyncFunction("convertToAsyncFunction_Conditional2", ` function [#|f|](){ @@ -1373,8 +1291,7 @@ function [#|f|](){ function res_func(result){ console.log(result); } -` - ); +`); _testConvertToAsyncFunction("convertToAsyncFunction_Scope3", ` function [#|f|]() { @@ -1387,8 +1304,7 @@ function [#|f|]() { }; }); } -` - ); +`); _testConvertToAsyncFunctionFailed("convertToAsyncFunction_NestedFunctionWrongLocation", ` function [#|f|]() { diff --git a/src/testRunner/unittests/services/extract/constants.ts b/src/testRunner/unittests/services/extract/constants.ts index 05c3aa5ac52bb..fe32437e00a23 100644 --- a/src/testRunner/unittests/services/extract/constants.ts +++ b/src/testRunner/unittests/services/extract/constants.ts @@ -1,35 +1,26 @@ namespace ts { describe("unittests:: services:: extract:: extractConstants", () => { - testExtractConstant("extractConstant_TopLevel", - `let x = [#|1|];`); - - testExtractConstant("extractConstant_Namespace", - `namespace N { + testExtractConstant("extractConstant_TopLevel", `let x = [#|1|];`); + testExtractConstant("extractConstant_Namespace", `namespace N { let x = [#|1|]; }`); - testExtractConstant("extractConstant_Class", - `class C { + testExtractConstant("extractConstant_Class", `class C { x = [#|1|]; }`); - testExtractConstant("extractConstant_Method", - `class C { + testExtractConstant("extractConstant_Method", `class C { M() { let x = [#|1|]; } }`); - testExtractConstant("extractConstant_Function", - `function F() { + testExtractConstant("extractConstant_Function", `function F() { let x = [#|1|]; }`); - testExtractConstant("extractConstant_ExpressionStatement", - `[#|"hello";|]`); - - testExtractConstant("extractConstant_ExpressionStatementExpression", - `[#|"hello"|];`); + testExtractConstant("extractConstant_ExpressionStatement", `[#|"hello";|]`); + testExtractConstant("extractConstant_ExpressionStatementExpression", `[#|"hello"|];`); testExtractConstant("extractConstant_ExpressionStatementInNestedScope", ` let i = 0; @@ -45,15 +36,13 @@ function F() { } `); - testExtractConstant("extractConstant_BlockScopes_NoDependencies", - `for (let i = 0; i < 10; i++) { + testExtractConstant("extractConstant_BlockScopes_NoDependencies", `for (let i = 0; i < 10; i++) { for (let j = 0; j < 10; j++) { let x = [#|1|]; } }`); - testExtractConstant("extractConstant_ClassInsertionPosition1", - `class C { + testExtractConstant("extractConstant_ClassInsertionPosition1", `class C { a = 1; b = 2; M1() { } @@ -63,8 +52,7 @@ function F() { } }`); - testExtractConstant("extractConstant_ClassInsertionPosition2", - `class C { + testExtractConstant("extractConstant_ClassInsertionPosition2", `class C { a = 1; M1() { } b = 2; @@ -74,8 +62,7 @@ function F() { } }`); - testExtractConstant("extractConstant_ClassInsertionPosition3", - `class C { + testExtractConstant("extractConstant_ClassInsertionPosition3", `class C { M1() { } a = 1; b = 2; @@ -85,33 +72,27 @@ function F() { } }`); - testExtractConstant("extractConstant_Parameters", - `function F() { + testExtractConstant("extractConstant_Parameters", `function F() { let w = 1; let x = [#|w + 1|]; }`); - testExtractConstant("extractConstant_TypeParameters", - `function F(t: T) { + testExtractConstant("extractConstant_TypeParameters", `function F(t: T) { let x = [#|t + 1|]; }`); - testExtractConstant("extractConstant_RepeatedSubstitution", - `namespace X { + testExtractConstant("extractConstant_RepeatedSubstitution", `namespace X { export const j = 10; export const y = [#|j * j|]; }`); - testExtractConstant("extractConstant_VariableList_const", - `const a = 1, b = [#|a + 1|];`); + testExtractConstant("extractConstant_VariableList_const", `const a = 1, b = [#|a + 1|];`); // NOTE: this test isn't normative - it just documents our sub-optimal behavior. - testExtractConstant("extractConstant_VariableList_let", - `let a = 1, b = [#|a + 1|];`); + testExtractConstant("extractConstant_VariableList_let", `let a = 1, b = [#|a + 1|];`); // NOTE: this test isn't normative - it just documents our sub-optimal behavior. - testExtractConstant("extractConstant_VariableList_MultipleLines", - `const /*About A*/a = 1, + testExtractConstant("extractConstant_VariableList_MultipleLines", `const /*About A*/a = 1, /*About B*/b = [#|a + 1|];`); testExtractConstant("extractConstant_BlockScopeMismatch", ` @@ -218,8 +199,7 @@ const f = () => { return [#|2 + 1|]; };`); - testExtractConstant("extractConstant_ArrowFunction_Expression", - `const f = () => [#|2 + 1|];`); + testExtractConstant("extractConstant_ArrowFunction_Expression", `const f = () => [#|2 + 1|];`); testExtractConstant("extractConstant_PreserveTrivia", ` // a @@ -280,25 +260,19 @@ switch (1) { } `); - testExtractConstant("extractConstant_PropertyName", - `[#|x.y|].z();`); - - testExtractConstant("extractConstant_PropertyName_ExistingName", - `let y; + testExtractConstant("extractConstant_PropertyName", `[#|x.y|].z();`); + testExtractConstant("extractConstant_PropertyName_ExistingName", `let y; [#|x.y|].z();`); - testExtractConstant("extractConstant_PropertyName_Keyword", - `[#|x.if|].z();`); - - testExtractConstant("extractConstant_PropertyName_PrivateIdentifierKeyword", - `[#|this.#if|].z();`); + testExtractConstant("extractConstant_PropertyName_Keyword", `[#|x.if|].z();`); + testExtractConstant("extractConstant_PropertyName_PrivateIdentifierKeyword", `[#|this.#if|].z();`); }); function testExtractConstant(caption: string, text: string) { - testExtractSymbol(caption, text, "extractConstant", Diagnostics.Extract_constant); + ts.testExtractSymbol(caption, text, "extractConstant", ts.Diagnostics.Extract_constant); } function testExtractConstantFailed(caption: string, text: string) { - testExtractSymbolFailed(caption, text, Diagnostics.Extract_constant); + ts.testExtractSymbolFailed(caption, text, ts.Diagnostics.Extract_constant); } } diff --git a/src/testRunner/unittests/services/extract/functions.ts b/src/testRunner/unittests/services/extract/functions.ts index c0e0a4b21f5ec..6ec3ca43158e7 100644 --- a/src/testRunner/unittests/services/extract/functions.ts +++ b/src/testRunner/unittests/services/extract/functions.ts @@ -1,7 +1,6 @@ namespace ts { describe("unittests:: services:: extract:: extractFunctions", () => { - testExtractFunction("extractFunction1", - `namespace A { + testExtractFunction("extractFunction1", `namespace A { let x = 1; function foo() { } @@ -16,8 +15,7 @@ namespace ts { } } }`); - testExtractFunction("extractFunction2", - `namespace A { + testExtractFunction("extractFunction2", `namespace A { let x = 1; function foo() { } @@ -30,8 +28,7 @@ namespace ts { } } }`); - testExtractFunction("extractFunction3", - `namespace A { + testExtractFunction("extractFunction3", `namespace A { function foo() { } namespace B { @@ -43,8 +40,7 @@ namespace ts { } } }`); - testExtractFunction("extractFunction4", - `namespace A { + testExtractFunction("extractFunction4", `namespace A { function foo() { } namespace B { @@ -58,8 +54,7 @@ namespace ts { } } }`); - testExtractFunction("extractFunction5", - `namespace A { + testExtractFunction("extractFunction5", `namespace A { let x = 1; export function foo() { } @@ -74,8 +69,7 @@ namespace ts { } } }`); - testExtractFunction("extractFunction6", - `namespace A { + testExtractFunction("extractFunction6", `namespace A { let x = 1; export function foo() { } @@ -90,8 +84,7 @@ namespace ts { } } }`); - testExtractFunction("extractFunction7", - `namespace A { + testExtractFunction("extractFunction7", `namespace A { let x = 1; export namespace C { export function foo() { @@ -108,8 +101,7 @@ namespace ts { } } }`); - testExtractFunction("extractFunction9", - `namespace A { + testExtractFunction("extractFunction9", `namespace A { export interface I { x: number }; namespace B { function a() { @@ -118,8 +110,7 @@ namespace ts { } } }`); - testExtractFunction("extractFunction10", - `namespace A { + testExtractFunction("extractFunction10", `namespace A { export interface I { x: number }; class C { a() { @@ -129,8 +120,7 @@ namespace ts { } } }`); - testExtractFunction("extractFunction11", - `namespace A { + testExtractFunction("extractFunction11", `namespace A { let y = 1; class C { a() { @@ -142,8 +132,7 @@ namespace ts { } } }`); - testExtractFunction("extractFunction12", - `namespace A { + testExtractFunction("extractFunction12", `namespace A { let y = 1; class C { b() {} @@ -162,8 +151,7 @@ namespace ts { // In all cases, we could use type inference, rather than passing explicit type arguments. // Note the inclusion of arrow functions to ensure that some type parameters are not from // targetable scopes. - testExtractFunction("extractFunction13", - `(u1a: U1a, u1b: U1b) => { + testExtractFunction("extractFunction13", `(u1a: U1a, u1b: U1b) => { function F1(t1a: T1a, t1b: T1b) { (u2a: U2a, u2b: U2b) => { function F2(t2a: T2a, t2b: T2b) { @@ -180,62 +168,53 @@ namespace ts { }`); // This test is descriptive, rather than normative. The current implementation // doesn't handle type parameter shadowing. - testExtractFunction("extractFunction14", - `function F(t1: T) { + testExtractFunction("extractFunction14", `function F(t1: T) { function G(t2: T) { [#|t1.toString(); t2.toString();|] } }`); // Confirm that the constraint is preserved. - testExtractFunction("extractFunction15", - `function F(t1: T) { + testExtractFunction("extractFunction15", `function F(t1: T) { function G(t2: U) { [#|t2.toString();|] } }`, /*includeLib*/ true); // Confirm that the contextual type of an extracted expression counts as a use. - testExtractFunction("extractFunction16", - `function F() { + testExtractFunction("extractFunction16", `function F() { const array: T[] = [#|[]|]; }`, /*includeLib*/ true); // Class type parameter - testExtractFunction("extractFunction17", - `class C { + testExtractFunction("extractFunction17", `class C { M(t1: T1, t2: T2) { [#|t1.toString()|]; } }`); // Function type parameter - testExtractFunction("extractFunction18", - `class C { + testExtractFunction("extractFunction18", `class C { M(t1: T1, t2: T2) { [#|t1.toString()|]; } }`); // Coupled constraints - testExtractFunction("extractFunction19", - `function F(v: V) { + testExtractFunction("extractFunction19", `function F(v: V) { [#|v.toString()|]; }`, /*includeLib*/ true); - testExtractFunction("extractFunction20", - `const _ = class { + testExtractFunction("extractFunction20", `const _ = class { a() { [#|let a1 = { x: 1 }; return a1.x + 10;|] } }`); // Write + void return - testExtractFunction("extractFunction21", - `function foo() { + testExtractFunction("extractFunction21", `function foo() { let x = 10; [#|x++; return;|] }`); // Return in finally block - testExtractFunction("extractFunction22", - `function test() { + testExtractFunction("extractFunction22", `function test() { try { } finally { @@ -243,8 +222,7 @@ namespace ts { } }`); // Extraction position - namespace - testExtractFunction("extractFunction23", - `namespace NS { + testExtractFunction("extractFunction23", `namespace NS { function M1() { } function M2() { [#|return 1;|] @@ -252,8 +230,7 @@ namespace ts { function M3() { } }`); // Extraction position - function - testExtractFunction("extractFunction24", - `function Outer() { + testExtractFunction("extractFunction24", `function Outer() { function M1() { } function M2() { [#|return 1;|] @@ -261,15 +238,13 @@ namespace ts { function M3() { } }`); // Extraction position - file - testExtractFunction("extractFunction25", - `function M1() { } + testExtractFunction("extractFunction25", `function M1() { } function M2() { [#|return 1;|] } function M3() { }`); // Extraction position - class without ctor - testExtractFunction("extractFunction26", - `class C { + testExtractFunction("extractFunction26", `class C { M1() { } M2() { [#|return 1;|] @@ -277,8 +252,7 @@ function M3() { }`); M3() { } }`); // Extraction position - class with ctor in middle - testExtractFunction("extractFunction27", - `class C { + testExtractFunction("extractFunction27", `class C { M1() { } M2() { [#|return 1;|] @@ -287,8 +261,7 @@ function M3() { }`); M3() { } }`); // Extraction position - class with ctor at end - testExtractFunction("extractFunction28", - `class C { + testExtractFunction("extractFunction28", `class C { M1() { } M2() { [#|return 1;|] @@ -297,8 +270,7 @@ function M3() { }`); constructor() { } }`); // Shorthand property names - testExtractFunction("extractFunction29", - `interface UnaryExpression { + testExtractFunction("extractFunction29", `interface UnaryExpression { kind: "Unary"; operator: string; operand: any; @@ -316,13 +288,11 @@ function parsePrimaryExpression(): any { throw "Not implemented"; }`); // Type parameter as declared type - testExtractFunction("extractFunction30", - `function F() { + testExtractFunction("extractFunction30", `function F() { [#|let t: T;|] }`); // Return in nested function - testExtractFunction("extractFunction31", - `namespace N { + testExtractFunction("extractFunction31", `namespace N { export const value = 1; @@ -334,8 +304,7 @@ function parsePrimaryExpression(): any { } }`); // Return in nested class - testExtractFunction("extractFunction32", - `namespace N { + testExtractFunction("extractFunction32", `namespace N { export const value = 1; @@ -348,18 +317,15 @@ function parsePrimaryExpression(): any { } }`); // Selection excludes leading trivia of declaration - testExtractFunction("extractFunction33", - `function F() { + testExtractFunction("extractFunction33", `function F() { [#|function G() { }|] }`); // Arrow function - testExtractFunction("extractFunction34", - `const F = () => { + testExtractFunction("extractFunction34", `const F = () => { [#|function G() { }|] };`); - testExtractFunction("extractFunction_RepeatedSubstitution", - `namespace X { + testExtractFunction("extractFunction_RepeatedSubstitution", `namespace X { export const j = 10; export const y = [#|j * j|]; }`); @@ -564,6 +530,6 @@ function F() { }); function testExtractFunction(caption: string, text: string, includeLib?: boolean) { - testExtractSymbol(caption, text, "extractFunction", Diagnostics.Extract_function, includeLib); + ts.testExtractSymbol(caption, text, "extractFunction", ts.Diagnostics.Extract_function, includeLib); } } diff --git a/src/testRunner/unittests/services/extract/helpers.ts b/src/testRunner/unittests/services/extract/helpers.ts index 660c903bd2bf3..e43145f1d68c7 100644 --- a/src/testRunner/unittests/services/extract/helpers.ts +++ b/src/testRunner/unittests/services/extract/helpers.ts @@ -7,7 +7,7 @@ namespace ts { interface Test { source: string; - ranges: ESMap; + ranges: ts.ESMap; } export function extractTest(source: string): Test { @@ -15,21 +15,21 @@ namespace ts { let text = ""; let lastPos = 0; let pos = 0; - const ranges = new Map(); + const ranges = new ts.Map(); while (pos < source.length) { - if (source.charCodeAt(pos) === CharacterCodes.openBracket && - (source.charCodeAt(pos + 1) === CharacterCodes.hash || source.charCodeAt(pos + 1) === CharacterCodes.$)) { + if (source.charCodeAt(pos) === ts.CharacterCodes.openBracket && + (source.charCodeAt(pos + 1) === ts.CharacterCodes.hash || source.charCodeAt(pos + 1) === ts.CharacterCodes.$)) { const saved = pos; pos += 2; const s = pos; consumeIdentifier(); const e = pos; - if (source.charCodeAt(pos) === CharacterCodes.bar) { + if (source.charCodeAt(pos) === ts.CharacterCodes.bar) { pos++; text += source.substring(lastPos, saved); const name = s === e - ? source.charCodeAt(saved + 1) === CharacterCodes.hash ? "selection" : "extracted" + ? source.charCodeAt(saved + 1) === ts.CharacterCodes.hash ? "selection" : "extracted" : source.substring(s, e); activeRanges.push({ name, pos: text.length, end: undefined! }); // TODO: GH#18217 lastPos = pos; @@ -39,11 +39,11 @@ namespace ts { pos = saved; } } - else if (source.charCodeAt(pos) === CharacterCodes.bar && source.charCodeAt(pos + 1) === CharacterCodes.closeBracket) { + else if (source.charCodeAt(pos) === ts.CharacterCodes.bar && source.charCodeAt(pos + 1) === ts.CharacterCodes.closeBracket) { text += source.substring(lastPos, pos); activeRanges[activeRanges.length - 1].end = text.length; const range = activeRanges.pop()!; - if (hasProperty(ranges, range.name)) { + if (ts.hasProperty(ranges, range.name)) { throw new Error(`Duplicate name of range ${range.name}`); } ranges.set(range.name, range); @@ -56,7 +56,7 @@ namespace ts { text += source.substring(lastPos, pos); function consumeIdentifier() { - while (isIdentifierPart(source.charCodeAt(pos), ScriptTarget.Latest)) { + while (ts.isIdentifierPart(source.charCodeAt(pos), ts.ScriptTarget.Latest)) { pos++; } } @@ -65,61 +65,59 @@ namespace ts { export const newLineCharacter = "\n"; - export const notImplementedHost: LanguageServiceHost = { - getCompilationSettings: notImplemented, - getScriptFileNames: notImplemented, - getScriptVersion: notImplemented, - getScriptSnapshot: notImplemented, - getDefaultLibFileName: notImplemented, - getCurrentDirectory: notImplemented, - readFile: notImplemented, - fileExists: notImplemented + export const notImplementedHost: ts.LanguageServiceHost = { + getCompilationSettings: ts.notImplemented, + getScriptFileNames: ts.notImplemented, + getScriptVersion: ts.notImplemented, + getScriptSnapshot: ts.notImplemented, + getDefaultLibFileName: ts.notImplemented, + getCurrentDirectory: ts.notImplemented, + readFile: ts.notImplemented, + fileExists: ts.notImplemented }; - export function testExtractSymbol(caption: string, text: string, baselineFolder: string, description: DiagnosticMessage, includeLib?: boolean) { + export function testExtractSymbol(caption: string, text: string, baselineFolder: string, description: ts.DiagnosticMessage, includeLib?: boolean) { const t = extractTest(text); const selectionRange = t.ranges.get("selection")!; if (!selectionRange) { throw new Error(`Test ${caption} does not specify selection range`); } - [Extension.Ts, Extension.Js].forEach(extension => - it(`${caption} [${extension}]`, () => runBaseline(extension))); - - function runBaseline(extension: Extension) { + [ts.Extension.Ts, ts.Extension.Js].forEach(extension => it(`${caption} [${extension}]`, () => runBaseline(extension))); + function runBaseline(extension: ts.Extension) { const path = "/a" + extension; const { program } = makeProgram({ path, content: t.source }, includeLib); if (hasSyntacticDiagnostics(program)) { // Don't bother generating JS baselines for inputs that aren't valid JS. - assert.equal(Extension.Js, extension, "Syntactic diagnostics found in non-JS file"); + assert.equal(ts.Extension.Js, extension, "Syntactic diagnostics found in non-JS file"); return; } const sourceFile = program.getSourceFile(path)!; - const context: RefactorContext = { - cancellationToken: { throwIfCancellationRequested: noop, isCancellationRequested: returnFalse }, + const context: ts.RefactorContext = { + cancellationToken: { throwIfCancellationRequested: ts.noop, isCancellationRequested: ts.returnFalse }, program, file: sourceFile, startPosition: selectionRange.pos, endPosition: selectionRange.end, host: notImplementedHost, - formatContext: formatting.getFormatContext(testFormatSettings, notImplementedHost), - preferences: emptyOptions, + formatContext: ts.formatting.getFormatContext(ts.testFormatSettings, notImplementedHost), + preferences: ts.emptyOptions, }; - const rangeToExtract = refactor.extractSymbol.getRangeToExtract(sourceFile, createTextSpanFromRange(selectionRange)); + const rangeToExtract = ts.refactor.extractSymbol.getRangeToExtract(sourceFile, ts.createTextSpanFromRange(selectionRange)); assert.equal(rangeToExtract.errors, undefined, rangeToExtract.errors && "Range error: " + rangeToExtract.errors[0].messageText); - const infos = refactor.extractSymbol.getRefactorActionsToExtractSymbol(context); - const actions = find(infos, info => info.description === description.message)!.actions; + const infos = ts.refactor.extractSymbol.getRefactorActionsToExtractSymbol(context); + const actions = ts.find(infos, info => info.description === description.message)!.actions; const data: string[] = []; data.push(`// ==ORIGINAL==`); data.push(text.replace("[#|", "/*[#|*/").replace("|]", "/*|]*/")); for (const action of actions) { - const { renameLocation, edits } = refactor.extractSymbol.getRefactorEditsToExtractSymbol(context, action.name)!; + const { renameLocation, edits } = ts.refactor.extractSymbol.getRefactorEditsToExtractSymbol(context, action.name)!; assert.lengthOf(edits, 1); data.push(`// ==SCOPE::${action.description}==`); - const newText = textChanges.applyChanges(sourceFile.text, edits[0].textChanges); + const newText = ts.textChanges.applyChanges(sourceFile.text, edits[0].textChanges); const newTextWithRename = newText.slice(0, renameLocation) + "/*RENAME*/" + newText.slice(renameLocation); data.push(newTextWithRename); @@ -129,22 +127,25 @@ namespace ts { Harness.Baseline.runBaseline(`${baselineFolder}/${caption}${extension}`, data.join(newLineCharacter)); } - function makeProgram(f: {path: string, content: string }, includeLib?: boolean) { - const host = projectSystem.createServerHost(includeLib ? [f, projectSystem.libFile] : [f]); // libFile is expensive to parse repeatedly - only test when required - const projectService = projectSystem.createProjectService(host); + function makeProgram(f: { + path: string; + content: string; + }, includeLib?: boolean) { + const host = ts.projectSystem.createServerHost(includeLib ? [f, ts.projectSystem.libFile] : [f]); // libFile is expensive to parse repeatedly - only test when required + const projectService = ts.projectSystem.createProjectService(host); projectService.openClientFile(f.path); const program = projectService.inferredProjects[0].getLanguageService().getProgram()!; const autoImportProvider = projectService.inferredProjects[0].getLanguageService().getAutoImportProvider(); return { program, autoImportProvider }; } - function hasSyntacticDiagnostics(program: Program) { + function hasSyntacticDiagnostics(program: ts.Program) { const diags = program.getSyntacticDiagnostics(); - return length(diags) > 0; + return ts.length(diags) > 0; } } - export function testExtractSymbolFailed(caption: string, text: string, description: DiagnosticMessage) { + export function testExtractSymbolFailed(caption: string, text: string, description: ts.DiagnosticMessage) { it(caption, () => { const t = extractTest(text); const selectionRange = t.ranges.get("selection"); @@ -155,25 +156,25 @@ namespace ts { path: "/a.ts", content: t.source }; - const host = projectSystem.createServerHost([f, projectSystem.libFile]); - const projectService = projectSystem.createProjectService(host); + const host = ts.projectSystem.createServerHost([f, ts.projectSystem.libFile]); + const projectService = ts.projectSystem.createProjectService(host); projectService.openClientFile(f.path); const program = projectService.inferredProjects[0].getLanguageService().getProgram()!; const sourceFile = program.getSourceFile(f.path)!; - const context: RefactorContext = { - cancellationToken: { throwIfCancellationRequested: noop, isCancellationRequested: returnFalse }, + const context: ts.RefactorContext = { + cancellationToken: { throwIfCancellationRequested: ts.noop, isCancellationRequested: ts.returnFalse }, program, file: sourceFile, startPosition: selectionRange.pos, endPosition: selectionRange.end, host: notImplementedHost, - formatContext: formatting.getFormatContext(testFormatSettings, notImplementedHost), - preferences: emptyOptions, + formatContext: ts.formatting.getFormatContext(ts.testFormatSettings, notImplementedHost), + preferences: ts.emptyOptions, }; - const rangeToExtract = refactor.extractSymbol.getRangeToExtract(sourceFile, createTextSpanFromRange(selectionRange)); + const rangeToExtract = ts.refactor.extractSymbol.getRangeToExtract(sourceFile, ts.createTextSpanFromRange(selectionRange)); assert.isUndefined(rangeToExtract.errors, rangeToExtract.errors && "Range error: " + rangeToExtract.errors[0].messageText); - const infos = refactor.extractSymbol.getRefactorActionsToExtractSymbol(context); - assert.isUndefined(find(infos, info => info.description === description.message)); + const infos = ts.refactor.extractSymbol.getRefactorActionsToExtractSymbol(context); + assert.isUndefined(ts.find(infos, info => info.description === description.message)); }); } } diff --git a/src/testRunner/unittests/services/extract/ranges.ts b/src/testRunner/unittests/services/extract/ranges.ts index 38d47f028402e..257e9e8b34b6c 100644 --- a/src/testRunner/unittests/services/extract/ranges.ts +++ b/src/testRunner/unittests/services/extract/ranges.ts @@ -1,13 +1,13 @@ namespace ts { function testExtractRangeFailed(caption: string, s: string, expectedErrors: string[]) { return it(caption, () => { - const t = extractTest(s); - const file = createSourceFile("a.ts", t.source, ScriptTarget.Latest, /*setParentNodes*/ true); + const t = ts.extractTest(s); + const file = ts.createSourceFile("a.ts", t.source, ts.ScriptTarget.Latest, /*setParentNodes*/ true); const selectionRange = t.ranges.get("selection"); if (!selectionRange) { throw new Error(`Test ${s} does not specify selection range`); } - const result = refactor.extractSymbol.getRangeToExtract(file, createTextSpanFromRange(selectionRange), /*userRequested*/ false); + const result = ts.refactor.extractSymbol.getRangeToExtract(file, ts.createTextSpanFromRange(selectionRange), /*userRequested*/ false); assert(result.targetRange === undefined, "failure expected"); const sortedErrors = result.errors.map(e => e.messageText as string).sort(); assert.deepEqual(sortedErrors, expectedErrors.sort(), "unexpected errors"); @@ -16,20 +16,20 @@ namespace ts { function testExtractRange(caption: string, s: string) { return it(caption, () => { - const t = extractTest(s); - const f = createSourceFile("a.ts", t.source, ScriptTarget.Latest, /*setParentNodes*/ true); + const t = ts.extractTest(s); + const f = ts.createSourceFile("a.ts", t.source, ts.ScriptTarget.Latest, /*setParentNodes*/ true); const selectionRange = t.ranges.get("selection"); if (!selectionRange) { throw new Error(`Test ${s} does not specify selection range`); } - const result = refactor.extractSymbol.getRangeToExtract(f, createTextSpanFromRange(selectionRange)); + const result = ts.refactor.extractSymbol.getRangeToExtract(f, ts.createTextSpanFromRange(selectionRange)); const expectedRange = t.ranges.get("extracted"); if (expectedRange) { let pos: number, end: number; const targetRange = result.targetRange!; - if (isArray(targetRange.range)) { + if (ts.isArray(targetRange.range)) { pos = targetRange.range[0].getStart(f); - end = last(targetRange.range).getEnd(); + end = ts.last(targetRange.range).getEnd(); } else { pos = targetRange.range.getStart(f); @@ -195,8 +195,7 @@ namespace ts { testExtractRange("extractRange30", `for (var i = [#|[$|1|]|]; i < 2; i++) {}`); }); - testExtractRangeFailed("extractRangeFailed1", - ` + testExtractRangeFailed("extractRangeFailed1", ` namespace A { function f() { [#| @@ -207,11 +206,8 @@ function f() { |] } } - `, - [refactor.extractSymbol.Messages.cannotExtractRangeContainingConditionalReturnStatement.message]); - - testExtractRangeFailed("extractRangeFailed2", - ` + `, [ts.refactor.extractSymbol.Messages.cannotExtractRangeContainingConditionalReturnStatement.message]); + testExtractRangeFailed("extractRangeFailed2", ` namespace A { function f() { while (true) { @@ -224,11 +220,8 @@ function f() { } } } - `, - [refactor.extractSymbol.Messages.cannotExtractRangeContainingConditionalBreakOrContinueStatements.message]); - - testExtractRangeFailed("extractRangeFailed3", - ` + `, [ts.refactor.extractSymbol.Messages.cannotExtractRangeContainingConditionalBreakOrContinueStatements.message]); + testExtractRangeFailed("extractRangeFailed3", ` namespace A { function f() { while (true) { @@ -241,11 +234,8 @@ function f() { } } } - `, - [refactor.extractSymbol.Messages.cannotExtractRangeContainingConditionalBreakOrContinueStatements.message]); - - testExtractRangeFailed("extractRangeFailed4", - ` + `, [ts.refactor.extractSymbol.Messages.cannotExtractRangeContainingConditionalBreakOrContinueStatements.message]); + testExtractRangeFailed("extractRangeFailed4", ` namespace A { function f() { l1: { @@ -258,11 +248,8 @@ function f() { } } } - `, - [refactor.extractSymbol.Messages.cannotExtractRangeContainingLabeledBreakOrContinueStatementWithTargetOutsideOfTheRange.message]); - - testExtractRangeFailed("extractRangeFailed5", - ` + `, [ts.refactor.extractSymbol.Messages.cannotExtractRangeContainingLabeledBreakOrContinueStatementWithTargetOutsideOfTheRange.message]); + testExtractRangeFailed("extractRangeFailed5", ` namespace A { function f() { [#| @@ -277,11 +264,8 @@ function f() { function f2() { } } - `, - [refactor.extractSymbol.Messages.cannotExtractRangeContainingConditionalReturnStatement.message]); - - testExtractRangeFailed("extractRangeFailed6", - ` + `, [ts.refactor.extractSymbol.Messages.cannotExtractRangeContainingConditionalReturnStatement.message]); + testExtractRangeFailed("extractRangeFailed6", ` namespace A { function f() { [#| @@ -296,46 +280,31 @@ function f() { function f2() { } } - `, - [refactor.extractSymbol.Messages.cannotExtractRangeContainingConditionalReturnStatement.message]); - - testExtractRangeFailed("extractRangeFailed7", - ` + `, [ts.refactor.extractSymbol.Messages.cannotExtractRangeContainingConditionalReturnStatement.message]); + testExtractRangeFailed("extractRangeFailed7", ` function test(x: number) { while (x) { x--; [#|break;|] } } - `, - [refactor.extractSymbol.Messages.cannotExtractRangeContainingConditionalBreakOrContinueStatements.message]); - - testExtractRangeFailed("extractRangeFailed8", - ` + `, [ts.refactor.extractSymbol.Messages.cannotExtractRangeContainingConditionalBreakOrContinueStatements.message]); + testExtractRangeFailed("extractRangeFailed8", ` function test(x: number) { switch (x) { case 1: [#|break;|] } } - `, - [refactor.extractSymbol.Messages.cannotExtractRangeContainingConditionalBreakOrContinueStatements.message]); - - testExtractRangeFailed("extractRangeFailed9", - `var x = ([#||]1 + 2);`, - [refactor.extractSymbol.Messages.cannotExtractEmpty.message]); - - testExtractRangeFailed("extractRangeFailed10", - ` + `, [ts.refactor.extractSymbol.Messages.cannotExtractRangeContainingConditionalBreakOrContinueStatements.message]); + testExtractRangeFailed("extractRangeFailed9", `var x = ([#||]1 + 2);`, [ts.refactor.extractSymbol.Messages.cannotExtractEmpty.message]); + testExtractRangeFailed("extractRangeFailed10", ` function f() { return 1 + [#|2 + 3|]; } } - `, - [refactor.extractSymbol.Messages.cannotExtractRange.message]); - - testExtractRangeFailed("extractRangeFailed11", - ` + `, [ts.refactor.extractSymbol.Messages.cannotExtractRange.message]); + testExtractRangeFailed("extractRangeFailed11", ` function f(x: number) { while (true) { [#|try { @@ -346,63 +315,39 @@ switch (x) { }|] } } - `, - [refactor.extractSymbol.Messages.cannotExtractRangeContainingConditionalBreakOrContinueStatements.message]); - - testExtractRangeFailed("extractRangeFailed12", - `let [#|x|];`, - [refactor.extractSymbol.Messages.statementOrExpressionExpected.message]); - - testExtractRangeFailed("extractRangeFailed13", - `[#|return;|]`, - [refactor.extractSymbol.Messages.cannotExtractRange.message]); - - testExtractRangeFailed("extractRangeFailed14", - ` + `, [ts.refactor.extractSymbol.Messages.cannotExtractRangeContainingConditionalBreakOrContinueStatements.message]); + testExtractRangeFailed("extractRangeFailed12", `let [#|x|];`, [ts.refactor.extractSymbol.Messages.statementOrExpressionExpected.message]); + testExtractRangeFailed("extractRangeFailed13", `[#|return;|]`, [ts.refactor.extractSymbol.Messages.cannotExtractRange.message]); + testExtractRangeFailed("extractRangeFailed14", ` switch(1) { case [#|1: break;|] } - `, - [refactor.extractSymbol.Messages.cannotExtractRange.message]); - - testExtractRangeFailed("extractRangeFailed15", - ` + `, [ts.refactor.extractSymbol.Messages.cannotExtractRange.message]); + testExtractRangeFailed("extractRangeFailed15", ` switch(1) { case [#|1: break|]; } - `, - [refactor.extractSymbol.Messages.cannotExtractRange.message]); + `, [ts.refactor.extractSymbol.Messages.cannotExtractRange.message]); // Documentation only - it would be nice if the result were [$|1|] - testExtractRangeFailed("extractRangeFailed16", - ` + testExtractRangeFailed("extractRangeFailed16", ` switch(1) { [#|case 1|]: break; } - `, - [refactor.extractSymbol.Messages.cannotExtractRange.message]); + `, [ts.refactor.extractSymbol.Messages.cannotExtractRange.message]); // Documentation only - it would be nice if the result were [$|1|] - testExtractRangeFailed("extractRangeFailed17", - ` + testExtractRangeFailed("extractRangeFailed17", ` switch(1) { [#|case 1:|] break; } - `, - [refactor.extractSymbol.Messages.cannotExtractRange.message]); - - testExtractRangeFailed("extractRangeFailed18", - `[#|{ 1;|] }`, - [refactor.extractSymbol.Messages.cannotExtractRange.message]); - - testExtractRangeFailed("extractRangeFailed19", - `[#|/** @type {number} */|] const foo = 1;`, - [refactor.extractSymbol.Messages.cannotExtractJSDoc.message]); - - testExtractRangeFailed("extract-method-not-for-token-expression-statement", `[#|a|]`, [refactor.extractSymbol.Messages.cannotExtractIdentifier.message]); + `, [ts.refactor.extractSymbol.Messages.cannotExtractRange.message]); + testExtractRangeFailed("extractRangeFailed18", `[#|{ 1;|] }`, [ts.refactor.extractSymbol.Messages.cannotExtractRange.message]); + testExtractRangeFailed("extractRangeFailed19", `[#|/** @type {number} */|] const foo = 1;`, [ts.refactor.extractSymbol.Messages.cannotExtractJSDoc.message]); + testExtractRangeFailed("extract-method-not-for-token-expression-statement", `[#|a|]`, [ts.refactor.extractSymbol.Messages.cannotExtractIdentifier.message]); }); } diff --git a/src/testRunner/unittests/services/extract/symbolWalker.ts b/src/testRunner/unittests/services/extract/symbolWalker.ts index 58d9dcb577f39..c17fc44c63d7c 100644 --- a/src/testRunner/unittests/services/extract/symbolWalker.ts +++ b/src/testRunner/unittests/services/extract/symbolWalker.ts @@ -1,6 +1,6 @@ namespace ts { describe("unittests:: services:: extract:: Symbol Walker", () => { - function test(description: string, source: string, verifier: (file: SourceFile, checker: TypeChecker) => void) { + function test(description: string, source: string, verifier: (file: ts.SourceFile, checker: ts.TypeChecker) => void) { it(description, () => { const result = Harness.Compiler.compileFiles([{ unitName: "main.ts", @@ -23,8 +23,8 @@ export default function foo(a: number, b: Bar): void {}`, (file, checker) => { let stdLibRefSymbols = 0; const expectedSymbols = ["default", "a", "b", "Bar", "x", "y", "history"]; const walker = checker.getSymbolWalker(symbol => { - const isStdLibSymbol = forEach(symbol.declarations, d => { - return getSourceFileOfNode(d).hasNoDefaultLib; + const isStdLibSymbol = ts.forEach(symbol.declarations, d => { + return ts.getSourceFileOfNode(d).hasNoDefaultLib; }); if (isStdLibSymbol) { stdLibRefSymbols++; diff --git a/src/testRunner/unittests/services/hostNewLineSupport.ts b/src/testRunner/unittests/services/hostNewLineSupport.ts index 762b8e3ddc159..762d5292dc842 100644 --- a/src/testRunner/unittests/services/hostNewLineSupport.ts +++ b/src/testRunner/unittests/services/hostNewLineSupport.ts @@ -1,31 +1,32 @@ namespace ts { describe("unittests:: services:: hostNewLineSupport", () => { - function testLSWithFiles(settings: CompilerOptions, files: Harness.Compiler.TestFile[]) { - function snapFor(path: string): IScriptSnapshot | undefined { + function testLSWithFiles(settings: ts.CompilerOptions, files: Harness.Compiler.TestFile[]) { + function snapFor(path: string): ts.IScriptSnapshot | undefined { if (path === "lib.d.ts") { - return ScriptSnapshot.fromString(""); + return ts.ScriptSnapshot.fromString(""); } - const result = find(files, f => f.unitName === path); - return result && ScriptSnapshot.fromString(result.content); + const result = ts.find(files, f => f.unitName === path); + return result && ts.ScriptSnapshot.fromString(result.content); } - const lshost: LanguageServiceHost = { + const lshost: ts.LanguageServiceHost = { getCompilationSettings: () => settings, - getScriptFileNames: () => map(files, f => f.unitName), + getScriptFileNames: () => ts.map(files, f => f.unitName), getScriptVersion: () => "1", getScriptSnapshot: name => snapFor(name), getDefaultLibFileName: () => "lib.d.ts", getCurrentDirectory: () => "", readFile: name => { const snap = snapFor(name); - if (!snap) return undefined; + if (!snap) + return undefined; return snap.getText(0, snap.getLength()); }, fileExists: name => !!snapFor(name), }; - return createLanguageService(lshost); + return ts.createLanguageService(lshost); } - function verifyNewLines(content: string, options: CompilerOptions) { + function verifyNewLines(content: string, options: ts.CompilerOptions) { const ls = testLSWithFiles(options, [{ content, fileOptions: {}, @@ -35,16 +36,16 @@ namespace ts { assert(!result.emitSkipped, "emit was skipped"); assert(result.outputFiles.length === 1, "a number of files other than 1 was output"); assert(result.outputFiles[0].name === "input.js", `Expected output file name input.js, but got ${result.outputFiles[0].name}`); - assert(result.outputFiles[0].text.match(options.newLine === NewLineKind.CarriageReturnLineFeed ? /\r\n/ : /[^\r]\n/), "expected to find appropriate newlines"); - assert(!result.outputFiles[0].text.match(options.newLine === NewLineKind.CarriageReturnLineFeed ? /[^\r]\n/ : /\r\n/), "expected not to find inappropriate newlines"); + assert(result.outputFiles[0].text.match(options.newLine === ts.NewLineKind.CarriageReturnLineFeed ? /\r\n/ : /[^\r]\n/), "expected to find appropriate newlines"); + assert(!result.outputFiles[0].text.match(options.newLine === ts.NewLineKind.CarriageReturnLineFeed ? /[^\r]\n/ : /\r\n/), "expected not to find inappropriate newlines"); } function verifyBothNewLines(content: string) { - verifyNewLines(content, { newLine: NewLineKind.CarriageReturnLineFeed }); - verifyNewLines(content, { newLine: NewLineKind.LineFeed }); + verifyNewLines(content, { newLine: ts.NewLineKind.CarriageReturnLineFeed }); + verifyNewLines(content, { newLine: ts.NewLineKind.LineFeed }); } - function verifyOutliningSpanNewLines(content: string, options: CompilerOptions) { + function verifyOutliningSpanNewLines(content: string, options: ts.CompilerOptions) { const ls = testLSWithFiles(options, [{ content, fileOptions: {}, @@ -52,8 +53,8 @@ namespace ts { }]); const span = ls.getOutliningSpans("input.ts")[0]; const textAfterSpanCollapse = content.substring(span.textSpan.start + span.textSpan.length); - assert(textAfterSpanCollapse.match(options.newLine === NewLineKind.CarriageReturnLineFeed ? /\r\n/ : /[^\r]\n/), "expected to find appropriate newlines"); - assert(!textAfterSpanCollapse.match(options.newLine === NewLineKind.CarriageReturnLineFeed ? /[^\r]\n/ : /\r\n/), "expected not to find inappropriate newlines"); + assert(textAfterSpanCollapse.match(options.newLine === ts.NewLineKind.CarriageReturnLineFeed ? /\r\n/ : /[^\r]\n/), "expected to find appropriate newlines"); + assert(!textAfterSpanCollapse.match(options.newLine === ts.NewLineKind.CarriageReturnLineFeed ? /[^\r]\n/ : /\r\n/), "expected not to find inappropriate newlines"); } it("should exist and respect provided compiler options", () => { @@ -65,13 +66,11 @@ namespace ts { }); it("should respect CRLF line endings around outlining spans", () => { - verifyOutliningSpanNewLines("// comment not included\r\n// #region name\r\nlet x: string = \"x\";\r\n// #endregion name\r\n", - { newLine: NewLineKind.CarriageReturnLineFeed }); + verifyOutliningSpanNewLines("// comment not included\r\n// #region name\r\nlet x: string = \"x\";\r\n// #endregion name\r\n", { newLine: ts.NewLineKind.CarriageReturnLineFeed }); }); it("should respect LF line endings around outlining spans", () => { - verifyOutliningSpanNewLines("// comment not included\n// #region name\nlet x: string = \"x\";\n// #endregion name\n\n", - { newLine: NewLineKind.LineFeed }); + verifyOutliningSpanNewLines("// comment not included\n// #region name\nlet x: string = \"x\";\n// #endregion name\n\n", { newLine: ts.NewLineKind.LineFeed }); }); }); } diff --git a/src/testRunner/unittests/services/languageService.ts b/src/testRunner/unittests/services/languageService.ts index c3f5f019541af..7f5d7b79d5747 100644 --- a/src/testRunner/unittests/services/languageService.ts +++ b/src/testRunner/unittests/services/languageService.ts @@ -2,7 +2,9 @@ namespace ts { const _chai: typeof import("chai") = require("chai"); const expect: typeof _chai.expect = _chai.expect; describe("unittests:: services:: languageService", () => { - const files: {[index: string]: string} = { + const files: { + [index: string]: string; + } = { "foo.ts": `import Vue from "./vue"; import Component from "./vue-class-component"; import { vueTemplateHtml } from "./variables"; @@ -31,13 +33,13 @@ export function Component(x: Config): any;` }, getScriptSnapshot(fileName) { if (fileName === ".ts") { - return ScriptSnapshot.fromString(""); + return ts.ScriptSnapshot.fromString(""); } - return ScriptSnapshot.fromString(files[fileName] || ""); + return ts.ScriptSnapshot.fromString(files[fileName] || ""); }, getCurrentDirectory: () => ".", getDefaultLibFileName(options) { - return getDefaultLibFilePath(options); + return ts.getDefaultLibFilePath(options); }, fileExists: name => !!files[name], readFile: name => files[name] @@ -53,48 +55,40 @@ export function Component(x: Config): any;` it("getEmitOutput on language service has way to force dts emit", () => { const languageService = createLanguageService(); - assert.deepEqual( - languageService.getEmitOutput( - "foo.ts", - /*emitOnlyDtsFiles*/ true - ), - { + assert.deepEqual(languageService.getEmitOutput("foo.ts", + /*emitOnlyDtsFiles*/ true), { emitSkipped: true, - diagnostics: emptyArray, - outputFiles: emptyArray, + diagnostics: ts.emptyArray, + outputFiles: ts.emptyArray, exportedModulesFromDeclarationEmit: undefined - } - ); - - assert.deepEqual( - languageService.getEmitOutput( - "foo.ts", + }); + assert.deepEqual(languageService.getEmitOutput("foo.ts", /*emitOnlyDtsFiles*/ true, - /*forceDtsEmit*/ true - ), - { + /*forceDtsEmit*/ true), { emitSkipped: false, - diagnostics: emptyArray, + diagnostics: ts.emptyArray, outputFiles: [{ name: "foo.d.ts", text: "export {};\r\n", writeByteOrderMark: false }], exportedModulesFromDeclarationEmit: undefined - } - ); }); + }); describe("detects program upto date correctly", () => { function verifyProgramUptoDate(useProjectVersion: boolean) { let projectVersion = "1"; - const files = new Map(); + const files = new ts.Map(); files.set("/project/root.ts", { version: "1", text: `import { foo } from "./other"` }); files.set("/project/other.ts", { version: "1", text: `export function foo() { }` }); - files.set("/lib/lib.d.ts", { version: "1", text: projectSystem.libFile.content }); - const host: LanguageServiceHost = { - useCaseSensitiveFileNames: returnTrue, - getCompilationSettings: getDefaultCompilerOptions, + files.set("/lib/lib.d.ts", { version: "1", text: ts.projectSystem.libFile.content }); + const host: ts.LanguageServiceHost = { + useCaseSensitiveFileNames: ts.returnTrue, + getCompilationSettings: ts.getDefaultCompilerOptions, fileExists: path => files.has(path), readFile: path => files.get(path)?.text, getProjectVersion: !useProjectVersion ? undefined : () => projectVersion, @@ -102,7 +96,7 @@ export function Component(x: Config): any;` getScriptVersion: path => files.get(path)?.version || "", getScriptSnapshot: path => { const text = files.get(path)?.text; - return text ? ScriptSnapshot.fromString(text) : undefined; + return text ? ts.ScriptSnapshot.fromString(text) : undefined; }, getCurrentDirectory: () => "/project", getDefaultLibFileName: () => "/lib/lib.d.ts" @@ -127,11 +121,8 @@ export function Component(x: Config): any;` assert.notStrictEqual(program3, program4); verifyProgramFiles(program4); - function verifyProgramFiles(program: Program) { - assert.deepEqual( - program.getSourceFiles().map(f => f.fileName), - ["/lib/lib.d.ts", "/project/other.ts", "/project/root.ts"] - ); + function verifyProgramFiles(program: ts.Program) { + assert.deepEqual(program.getSourceFiles().map(f => f.fileName), ["/lib/lib.d.ts", "/project/other.ts", "/project/root.ts"]); } } it("when host implements getProjectVersion", () => { @@ -144,8 +135,8 @@ export function Component(x: Config): any;` describe("detects program upto date when new file is added to the referenced project", () => { function setup(useSourceOfProjectReferenceRedirect: (() => boolean) | undefined) { - const config1: TestFSWithWatch.File = { - path: `${tscWatch.projectRoot}/projects/project1/tsconfig.json`, + const config1: ts.TestFSWithWatch.File = { + path: `${ts.tscWatch.projectRoot}/projects/project1/tsconfig.json`, content: JSON.stringify({ compilerOptions: { module: "none", @@ -154,16 +145,16 @@ export function Component(x: Config): any;` exclude: ["temp"] }) }; - const class1: TestFSWithWatch.File = { - path: `${tscWatch.projectRoot}/projects/project1/class1.ts`, + const class1: ts.TestFSWithWatch.File = { + path: `${ts.tscWatch.projectRoot}/projects/project1/class1.ts`, content: `class class1 {}` }; - const class1Dts: TestFSWithWatch.File = { - path: `${tscWatch.projectRoot}/projects/project1/class1.d.ts`, + const class1Dts: ts.TestFSWithWatch.File = { + path: `${ts.tscWatch.projectRoot}/projects/project1/class1.d.ts`, content: `declare class class1 {}` }; - const config2: TestFSWithWatch.File = { - path: `${tscWatch.projectRoot}/projects/project2/tsconfig.json`, + const config2: ts.TestFSWithWatch.File = { + path: `${ts.tscWatch.projectRoot}/projects/project2/tsconfig.json`, content: JSON.stringify({ compilerOptions: { module: "none", @@ -174,21 +165,21 @@ export function Component(x: Config): any;` ] }) }; - const class2: TestFSWithWatch.File = { - path: `${tscWatch.projectRoot}/projects/project2/class2.ts`, + const class2: ts.TestFSWithWatch.File = { + path: `${ts.tscWatch.projectRoot}/projects/project2/class2.ts`, content: `class class2 {}` }; - const system = projectSystem.createServerHost([config1, class1, class1Dts, config2, class2, projectSystem.libFile]); - const result = getParsedCommandLineOfConfigFile(`${tscWatch.projectRoot}/projects/project2/tsconfig.json`, /*optionsToExtend*/ undefined, { + const system = ts.projectSystem.createServerHost([config1, class1, class1Dts, config2, class2, ts.projectSystem.libFile]); + const result = ts.getParsedCommandLineOfConfigFile(`${ts.tscWatch.projectRoot}/projects/project2/tsconfig.json`, /*optionsToExtend*/ undefined, { useCaseSensitiveFileNames: true, fileExists: path => system.fileExists(path), readFile: path => system.readFile(path), getCurrentDirectory: () => system.getCurrentDirectory(), readDirectory: (path, extensions, excludes, includes, depth) => system.readDirectory(path, extensions, excludes, includes, depth), - onUnRecoverableConfigFileDiagnostic: noop, + onUnRecoverableConfigFileDiagnostic: ts.noop, })!; - const host: LanguageServiceHost = { - useCaseSensitiveFileNames: returnTrue, + const host: ts.LanguageServiceHost = { + useCaseSensitiveFileNames: ts.returnTrue, useSourceOfProjectReferenceRedirect, getCompilationSettings: () => result.options, fileExists: path => system.fileExists(path), @@ -200,76 +191,55 @@ export function Component(x: Config): any;` }, getScriptSnapshot: path => { const text = system.readFile(path); - return text ? ScriptSnapshot.fromString(text) : undefined; + return text ? ts.ScriptSnapshot.fromString(text) : undefined; }, readDirectory: (path, extensions, excludes, includes, depth) => system.readDirectory(path, extensions, excludes, includes, depth), getCurrentDirectory: () => system.getCurrentDirectory(), - getDefaultLibFileName: () => projectSystem.libFile.path, + getDefaultLibFileName: () => ts.projectSystem.libFile.path, getProjectReferences: () => result.projectReferences, }; const ls = ts.createLanguageService(host); return { system, ls, class1, class1Dts, class2 }; } it("detects program upto date when new file is added to the referenced project", () => { - const { ls, system, class1, class2 } = setup(returnTrue); - assert.deepEqual( - ls.getProgram()!.getSourceFiles().map(f => f.fileName), - [projectSystem.libFile.path, class1.path, class2.path] - ); + const { ls, system, class1, class2 } = setup(ts.returnTrue); + assert.deepEqual(ls.getProgram()!.getSourceFiles().map(f => f.fileName), [ts.projectSystem.libFile.path, class1.path, class2.path]); // Add new file to referenced project - const class3 = `${tscWatch.projectRoot}/projects/project1/class3.ts`; + const class3 = `${ts.tscWatch.projectRoot}/projects/project1/class3.ts`; system.writeFile(class3, `class class3 {}`); const program = ls.getProgram()!; - assert.deepEqual( - program.getSourceFiles().map(f => f.fileName), - [projectSystem.libFile.path, class1.path, class3, class2.path] - ); + assert.deepEqual(program.getSourceFiles().map(f => f.fileName), [ts.projectSystem.libFile.path, class1.path, class3, class2.path]); // Add excluded file to referenced project - system.ensureFileOrFolder({ path: `${tscWatch.projectRoot}/projects/project1/temp/file.d.ts`, content: `declare class file {}` }); + system.ensureFileOrFolder({ path: `${ts.tscWatch.projectRoot}/projects/project1/temp/file.d.ts`, content: `declare class file {}` }); assert.strictEqual(ls.getProgram(), program); // Add output from new class to referenced project - system.writeFile(`${tscWatch.projectRoot}/projects/project1/class3.d.ts`, `declare class class3 {}`); + system.writeFile(`${ts.tscWatch.projectRoot}/projects/project1/class3.d.ts`, `declare class class3 {}`); assert.strictEqual(ls.getProgram(), program); }); it("detects program upto date when new file is added to the referenced project without useSourceOfProjectReferenceRedirect", () => { const { ls, system, class1Dts, class2 } = setup(/*useSourceOfProjectReferenceRedirect*/ undefined); const program1 = ls.getProgram()!; - assert.deepEqual( - program1.getSourceFiles().map(f => f.fileName), - [projectSystem.libFile.path, class1Dts.path, class2.path] - ); + assert.deepEqual(program1.getSourceFiles().map(f => f.fileName), [ts.projectSystem.libFile.path, class1Dts.path, class2.path]); // Add new file to referenced project - const class3 = `${tscWatch.projectRoot}/projects/project1/class3.ts`; + const class3 = `${ts.tscWatch.projectRoot}/projects/project1/class3.ts`; system.writeFile(class3, `class class3 {}`); assert.notStrictEqual(ls.getProgram(), program1); - assert.deepEqual( - ls.getProgram()!.getSourceFiles().map(f => f.fileName), - [projectSystem.libFile.path, class1Dts.path, class2.path] - ); + assert.deepEqual(ls.getProgram()!.getSourceFiles().map(f => f.fileName), [ts.projectSystem.libFile.path, class1Dts.path, class2.path]); // Add class3 output - const class3Dts = `${tscWatch.projectRoot}/projects/project1/class3.d.ts`; + const class3Dts = `${ts.tscWatch.projectRoot}/projects/project1/class3.d.ts`; system.writeFile(class3Dts, `declare class class3 {}`); const program2 = ls.getProgram()!; - assert.deepEqual( - program2.getSourceFiles().map(f => f.fileName), - [projectSystem.libFile.path, class1Dts.path, class3Dts, class2.path] - ); + assert.deepEqual(program2.getSourceFiles().map(f => f.fileName), [ts.projectSystem.libFile.path, class1Dts.path, class3Dts, class2.path]); // Add excluded file to referenced project - system.ensureFileOrFolder({ path: `${tscWatch.projectRoot}/projects/project1/temp/file.d.ts`, content: `declare class file {}` }); + system.ensureFileOrFolder({ path: `${ts.tscWatch.projectRoot}/projects/project1/temp/file.d.ts`, content: `declare class file {}` }); assert.strictEqual(ls.getProgram(), program2); // Delete output from new class to referenced project system.deleteFile(class3Dts); - assert.deepEqual( - ls.getProgram()!.getSourceFiles().map(f => f.fileName), - [projectSystem.libFile.path, class1Dts.path, class2.path] - ); + assert.deepEqual(ls.getProgram()!.getSourceFiles().map(f => f.fileName), [ts.projectSystem.libFile.path, class1Dts.path, class2.path]); // Write output again system.writeFile(class3Dts, `declare class class3 {}`); - assert.deepEqual( - ls.getProgram()!.getSourceFiles().map(f => f.fileName), - [projectSystem.libFile.path, class1Dts.path, class3Dts, class2.path] - ); + assert.deepEqual(ls.getProgram()!.getSourceFiles().map(f => f.fileName), [ts.projectSystem.libFile.path, class1Dts.path, class3Dts, class2.path]); }); }); }); diff --git a/src/testRunner/unittests/services/organizeImports.ts b/src/testRunner/unittests/services/organizeImports.ts index 4ddd1b608d003..172f07e9c7771 100644 --- a/src/testRunner/unittests/services/organizeImports.ts +++ b/src/testRunner/unittests/services/organizeImports.ts @@ -2,193 +2,138 @@ namespace ts { describe("unittests:: services:: organizeImports", () => { describe("Sort imports", () => { it("Sort - non-relative vs non-relative", () => { - assertSortsBefore( - `import y from "lib1";`, - `import x from "lib2";`); + assertSortsBefore(`import y from "lib1";`, `import x from "lib2";`); }); it("Sort - relative vs relative", () => { - assertSortsBefore( - `import y from "./lib1";`, - `import x from "./lib2";`); + assertSortsBefore(`import y from "./lib1";`, `import x from "./lib2";`); }); it("Sort - relative vs non-relative", () => { - assertSortsBefore( - `import y from "lib";`, - `import x from "./lib";`); + assertSortsBefore(`import y from "lib";`, `import x from "./lib";`); }); it("Sort - case-insensitive", () => { - assertSortsBefore( - `import y from "a";`, - `import x from "Z";`); - assertSortsBefore( - `import y from "A";`, - `import x from "z";`); + assertSortsBefore(`import y from "a";`, `import x from "Z";`); + assertSortsBefore(`import y from "A";`, `import x from "z";`); }); function assertSortsBefore(importString1: string, importString2: string) { const [{moduleSpecifier: moduleSpecifier1}, {moduleSpecifier: moduleSpecifier2}] = parseImports(importString1, importString2); - assert.equal(OrganizeImports.compareModuleSpecifiers(moduleSpecifier1, moduleSpecifier2), Comparison.LessThan); - assert.equal(OrganizeImports.compareModuleSpecifiers(moduleSpecifier2, moduleSpecifier1), Comparison.GreaterThan); + assert.equal(ts.OrganizeImports.compareModuleSpecifiers(moduleSpecifier1, moduleSpecifier2), ts.Comparison.LessThan); + assert.equal(ts.OrganizeImports.compareModuleSpecifiers(moduleSpecifier2, moduleSpecifier1), ts.Comparison.GreaterThan); } }); describe("Coalesce imports", () => { it("No imports", () => { - assert.isEmpty(OrganizeImports.coalesceImports([])); + assert.isEmpty(ts.OrganizeImports.coalesceImports([])); }); it("Sort specifiers - case-insensitive", () => { const sortedImports = parseImports(`import { default as M, a as n, B, y, Z as O } from "lib";`); - const actualCoalescedImports = OrganizeImports.coalesceImports(sortedImports); + const actualCoalescedImports = ts.OrganizeImports.coalesceImports(sortedImports); const expectedCoalescedImports = parseImports(`import { a as n, B, default as M, y, Z as O } from "lib";`); assertListEqual(actualCoalescedImports, expectedCoalescedImports); }); it("Combine side-effect-only imports", () => { - const sortedImports = parseImports( - `import "lib";`, - `import "lib";`); - const actualCoalescedImports = OrganizeImports.coalesceImports(sortedImports); + const sortedImports = parseImports(`import "lib";`, `import "lib";`); + const actualCoalescedImports = ts.OrganizeImports.coalesceImports(sortedImports); const expectedCoalescedImports = parseImports(`import "lib";`); assertListEqual(actualCoalescedImports, expectedCoalescedImports); }); it("Combine namespace imports", () => { - const sortedImports = parseImports( - `import * as x from "lib";`, - `import * as y from "lib";`); - const actualCoalescedImports = OrganizeImports.coalesceImports(sortedImports); + const sortedImports = parseImports(`import * as x from "lib";`, `import * as y from "lib";`); + const actualCoalescedImports = ts.OrganizeImports.coalesceImports(sortedImports); const expectedCoalescedImports = sortedImports; assertListEqual(actualCoalescedImports, expectedCoalescedImports); }); it("Combine default imports", () => { - const sortedImports = parseImports( - `import x from "lib";`, - `import y from "lib";`); - const actualCoalescedImports = OrganizeImports.coalesceImports(sortedImports); + const sortedImports = parseImports(`import x from "lib";`, `import y from "lib";`); + const actualCoalescedImports = ts.OrganizeImports.coalesceImports(sortedImports); const expectedCoalescedImports = parseImports(`import { default as x, default as y } from "lib";`); assertListEqual(actualCoalescedImports, expectedCoalescedImports); }); it("Combine property imports", () => { - const sortedImports = parseImports( - `import { x } from "lib";`, - `import { y as z } from "lib";`); - const actualCoalescedImports = OrganizeImports.coalesceImports(sortedImports); + const sortedImports = parseImports(`import { x } from "lib";`, `import { y as z } from "lib";`); + const actualCoalescedImports = ts.OrganizeImports.coalesceImports(sortedImports); const expectedCoalescedImports = parseImports(`import { x, y as z } from "lib";`); assertListEqual(actualCoalescedImports, expectedCoalescedImports); }); it("Combine side-effect-only import with namespace import", () => { - const sortedImports = parseImports( - `import "lib";`, - `import * as x from "lib";`); - const actualCoalescedImports = OrganizeImports.coalesceImports(sortedImports); + const sortedImports = parseImports(`import "lib";`, `import * as x from "lib";`); + const actualCoalescedImports = ts.OrganizeImports.coalesceImports(sortedImports); const expectedCoalescedImports = sortedImports; assertListEqual(actualCoalescedImports, expectedCoalescedImports); }); it("Combine side-effect-only import with default import", () => { - const sortedImports = parseImports( - `import "lib";`, - `import x from "lib";`); - const actualCoalescedImports = OrganizeImports.coalesceImports(sortedImports); + const sortedImports = parseImports(`import "lib";`, `import x from "lib";`); + const actualCoalescedImports = ts.OrganizeImports.coalesceImports(sortedImports); const expectedCoalescedImports = sortedImports; assertListEqual(actualCoalescedImports, expectedCoalescedImports); }); it("Combine side-effect-only import with property import", () => { - const sortedImports = parseImports( - `import "lib";`, - `import { x } from "lib";`); - const actualCoalescedImports = OrganizeImports.coalesceImports(sortedImports); + const sortedImports = parseImports(`import "lib";`, `import { x } from "lib";`); + const actualCoalescedImports = ts.OrganizeImports.coalesceImports(sortedImports); const expectedCoalescedImports = sortedImports; assertListEqual(actualCoalescedImports, expectedCoalescedImports); }); it("Combine namespace import with default import", () => { - const sortedImports = parseImports( - `import * as x from "lib";`, - `import y from "lib";`); - const actualCoalescedImports = OrganizeImports.coalesceImports(sortedImports); - const expectedCoalescedImports = parseImports( - `import y, * as x from "lib";`); + const sortedImports = parseImports(`import * as x from "lib";`, `import y from "lib";`); + const actualCoalescedImports = ts.OrganizeImports.coalesceImports(sortedImports); + const expectedCoalescedImports = parseImports(`import y, * as x from "lib";`); assertListEqual(actualCoalescedImports, expectedCoalescedImports); }); it("Combine namespace import with property import", () => { - const sortedImports = parseImports( - `import * as x from "lib";`, - `import { y } from "lib";`); - const actualCoalescedImports = OrganizeImports.coalesceImports(sortedImports); + const sortedImports = parseImports(`import * as x from "lib";`, `import { y } from "lib";`); + const actualCoalescedImports = ts.OrganizeImports.coalesceImports(sortedImports); const expectedCoalescedImports = sortedImports; assertListEqual(actualCoalescedImports, expectedCoalescedImports); }); it("Combine default import with property import", () => { - const sortedImports = parseImports( - `import x from "lib";`, - `import { y } from "lib";`); - const actualCoalescedImports = OrganizeImports.coalesceImports(sortedImports); - const expectedCoalescedImports = parseImports( - `import x, { y } from "lib";`); + const sortedImports = parseImports(`import x from "lib";`, `import { y } from "lib";`); + const actualCoalescedImports = ts.OrganizeImports.coalesceImports(sortedImports); + const expectedCoalescedImports = parseImports(`import x, { y } from "lib";`); assertListEqual(actualCoalescedImports, expectedCoalescedImports); }); it("Combine many imports", () => { - const sortedImports = parseImports( - `import "lib";`, - `import * as y from "lib";`, - `import w from "lib";`, - `import { b } from "lib";`, - `import "lib";`, - `import * as x from "lib";`, - `import z from "lib";`, - `import { a } from "lib";`); - const actualCoalescedImports = OrganizeImports.coalesceImports(sortedImports); - const expectedCoalescedImports = parseImports( - `import "lib";`, - `import * as x from "lib";`, - `import * as y from "lib";`, - `import { a, b, default as w, default as z } from "lib";`); + const sortedImports = parseImports(`import "lib";`, `import * as y from "lib";`, `import w from "lib";`, `import { b } from "lib";`, `import "lib";`, `import * as x from "lib";`, `import z from "lib";`, `import { a } from "lib";`); + const actualCoalescedImports = ts.OrganizeImports.coalesceImports(sortedImports); + const expectedCoalescedImports = parseImports(`import "lib";`, `import * as x from "lib";`, `import * as y from "lib";`, `import { a, b, default as w, default as z } from "lib";`); assertListEqual(actualCoalescedImports, expectedCoalescedImports); }); // This is descriptive, rather than normative it("Combine two namespace imports with one default import", () => { - const sortedImports = parseImports( - `import * as x from "lib";`, - `import * as y from "lib";`, - `import z from "lib";`); - const actualCoalescedImports = OrganizeImports.coalesceImports(sortedImports); + const sortedImports = parseImports(`import * as x from "lib";`, `import * as y from "lib";`, `import z from "lib";`); + const actualCoalescedImports = ts.OrganizeImports.coalesceImports(sortedImports); const expectedCoalescedImports = sortedImports; assertListEqual(actualCoalescedImports, expectedCoalescedImports); }); it("Combine type-only imports separately from other imports", () => { - const sortedImports = parseImports( - `import type { x } from "lib";`, - `import type { y } from "lib";`, - `import { z } from "lib";`); - const actualCoalescedImports = OrganizeImports.coalesceImports(sortedImports); - const expectedCoalescedImports = parseImports( - `import { z } from "lib";`, - `import type { x, y } from "lib";`); + const sortedImports = parseImports(`import type { x } from "lib";`, `import type { y } from "lib";`, `import { z } from "lib";`); + const actualCoalescedImports = ts.OrganizeImports.coalesceImports(sortedImports); + const expectedCoalescedImports = parseImports(`import { z } from "lib";`, `import type { x, y } from "lib";`); assertListEqual(actualCoalescedImports, expectedCoalescedImports); }); it("Do not combine type-only default, namespace, or named imports with each other", () => { - const sortedImports = parseImports( - `import type { x } from "lib";`, - `import type * as y from "lib";`, - `import type z from "lib";`); + const sortedImports = parseImports(`import type { x } from "lib";`, `import type * as y from "lib";`, `import type z from "lib";`); // Default import could be rewritten as a named import to combine with `x`, // but seems of debatable merit. - const actualCoalescedImports = OrganizeImports.coalesceImports(sortedImports); + const actualCoalescedImports = ts.OrganizeImports.coalesceImports(sortedImports); const expectedCoalescedImports = actualCoalescedImports; assertListEqual(actualCoalescedImports, expectedCoalescedImports); }); @@ -196,98 +141,76 @@ namespace ts { describe("Coalesce exports", () => { it("No exports", () => { - assert.isEmpty(OrganizeImports.coalesceExports([])); + assert.isEmpty(ts.OrganizeImports.coalesceExports([])); }); it("Sort specifiers - case-insensitive", () => { const sortedExports = parseExports(`export { default as M, a as n, B, y, Z as O } from "lib";`); - const actualCoalescedExports = OrganizeImports.coalesceExports(sortedExports); + const actualCoalescedExports = ts.OrganizeImports.coalesceExports(sortedExports); const expectedCoalescedExports = parseExports(`export { a as n, B, default as M, y, Z as O } from "lib";`); assertListEqual(actualCoalescedExports, expectedCoalescedExports); }); it("Sort specifiers - type-only", () => { const sortedImports = parseImports(`import { type z, y, type x, c, type b, a } from "lib";`); - const actualCoalescedImports = OrganizeImports.coalesceImports(sortedImports); + const actualCoalescedImports = ts.OrganizeImports.coalesceImports(sortedImports); const expectedCoalescedImports = parseImports(`import { a, c, y, type b, type x, type z } from "lib";`); assertListEqual(actualCoalescedImports, expectedCoalescedImports); }); it("Combine namespace re-exports", () => { - const sortedExports = parseExports( - `export * from "lib";`, - `export * from "lib";`); - const actualCoalescedExports = OrganizeImports.coalesceExports(sortedExports); + const sortedExports = parseExports(`export * from "lib";`, `export * from "lib";`); + const actualCoalescedExports = ts.OrganizeImports.coalesceExports(sortedExports); const expectedCoalescedExports = parseExports(`export * from "lib";`); assertListEqual(actualCoalescedExports, expectedCoalescedExports); }); it("Combine property exports", () => { - const sortedExports = parseExports( - `export { x };`, - `export { y as z };`); - const actualCoalescedExports = OrganizeImports.coalesceExports(sortedExports); + const sortedExports = parseExports(`export { x };`, `export { y as z };`); + const actualCoalescedExports = ts.OrganizeImports.coalesceExports(sortedExports); const expectedCoalescedExports = parseExports(`export { x, y as z };`); assertListEqual(actualCoalescedExports, expectedCoalescedExports); }); it("Combine property re-exports", () => { - const sortedExports = parseExports( - `export { x } from "lib";`, - `export { y as z } from "lib";`); - const actualCoalescedExports = OrganizeImports.coalesceExports(sortedExports); + const sortedExports = parseExports(`export { x } from "lib";`, `export { y as z } from "lib";`); + const actualCoalescedExports = ts.OrganizeImports.coalesceExports(sortedExports); const expectedCoalescedExports = parseExports(`export { x, y as z } from "lib";`); assertListEqual(actualCoalescedExports, expectedCoalescedExports); }); it("Combine namespace re-export with property re-export", () => { - const sortedExports = parseExports( - `export * from "lib";`, - `export { y } from "lib";`); - const actualCoalescedExports = OrganizeImports.coalesceExports(sortedExports); + const sortedExports = parseExports(`export * from "lib";`, `export { y } from "lib";`); + const actualCoalescedExports = ts.OrganizeImports.coalesceExports(sortedExports); const expectedCoalescedExports = sortedExports; assertListEqual(actualCoalescedExports, expectedCoalescedExports); }); it("Combine many exports", () => { - const sortedExports = parseExports( - `export { x };`, - `export { y as w, z as default };`, - `export { w as q };`); - const actualCoalescedExports = OrganizeImports.coalesceExports(sortedExports); - const expectedCoalescedExports = parseExports( - `export { w as q, x, y as w, z as default };`); + const sortedExports = parseExports(`export { x };`, `export { y as w, z as default };`, `export { w as q };`); + const actualCoalescedExports = ts.OrganizeImports.coalesceExports(sortedExports); + const expectedCoalescedExports = parseExports(`export { w as q, x, y as w, z as default };`); assertListEqual(actualCoalescedExports, expectedCoalescedExports); }); it("Combine many re-exports", () => { - const sortedExports = parseExports( - `export { x as a, y } from "lib";`, - `export * from "lib";`, - `export { z as b } from "lib";`); - const actualCoalescedExports = OrganizeImports.coalesceExports(sortedExports); - const expectedCoalescedExports = parseExports( - `export * from "lib";`, - `export { x as a, y, z as b } from "lib";`); + const sortedExports = parseExports(`export { x as a, y } from "lib";`, `export * from "lib";`, `export { z as b } from "lib";`); + const actualCoalescedExports = ts.OrganizeImports.coalesceExports(sortedExports); + const expectedCoalescedExports = parseExports(`export * from "lib";`, `export { x as a, y, z as b } from "lib";`); assertListEqual(actualCoalescedExports, expectedCoalescedExports); }); it("Keep type-only exports separate", () => { - const sortedExports = parseExports( - `export { x };`, - `export type { y };`); - const actualCoalescedExports = OrganizeImports.coalesceExports(sortedExports); + const sortedExports = parseExports(`export { x };`, `export type { y };`); + const actualCoalescedExports = ts.OrganizeImports.coalesceExports(sortedExports); const expectedCoalescedExports = sortedExports; assertListEqual(actualCoalescedExports, expectedCoalescedExports); }); it("Combine type-only exports", () => { - const sortedExports = parseExports( - `export type { x };`, - `export type { y };`); - const actualCoalescedExports = OrganizeImports.coalesceExports(sortedExports); - const expectedCoalescedExports = parseExports( - `export type { x, y };`); + const sortedExports = parseExports(`export type { x };`, `export type { y };`); + const actualCoalescedExports = ts.OrganizeImports.coalesceExports(sortedExports); + const expectedCoalescedExports = parseExports(`export type { x, y };`); assertListEqual(actualCoalescedExports, expectedCoalescedExports); }); }); @@ -321,7 +244,7 @@ export const Other = 1; content: "function F() { }", }; const languageService = makeLanguageService(testFile); - const changes = languageService.organizeImports({ type: "file", fileName: testFile.path }, testFormatSettings, emptyOptions); + const changes = languageService.organizeImports({ type: "file", fileName: testFile.path }, ts.testFormatSettings, ts.emptyOptions); assert.isEmpty(changes); }); @@ -331,7 +254,7 @@ export const Other = 1; content: "declare module '*';", }; const languageService = makeLanguageService(testFile); - const changes = languageService.organizeImports({ type: "file", fileName: testFile.path }, testFormatSettings, emptyOptions); + const changes = languageService.organizeImports({ type: "file", fileName: testFile.path }, ts.testFormatSettings, ts.emptyOptions); assert.isEmpty(changes); }); @@ -341,24 +264,21 @@ export const Other = 1; content: `import { f } from 'foo';\nf();` }; const languageService = makeLanguageService(testFile); - const changes = languageService.organizeImports({ type: "file", fileName: testFile.path }, testFormatSettings, emptyOptions); + const changes = languageService.organizeImports({ type: "file", fileName: testFile.path }, ts.testFormatSettings, ts.emptyOptions); assert.isEmpty(changes); }); testOrganizeImports("Renamed_used", - /*skipDestructiveCodeActions*/ false, - { + /*skipDestructiveCodeActions*/ false, { path: "/test.ts", content: ` import { F1 as EffOne, F2 as EffTwo } from "lib"; EffOne(); `, - }, - libFile); + }, libFile); testOrganizeImports("Simple", - /*skipDestructiveCodeActions*/ false, - { + /*skipDestructiveCodeActions*/ false, { path: "/test.ts", content: ` import { F1, F2 } from "lib"; @@ -370,12 +290,10 @@ D(); F1(); F2(); `, - }, - libFile); + }, libFile); testOrganizeImports("Unused_Some", - /*skipDestructiveCodeActions*/ false, - { + /*skipDestructiveCodeActions*/ false, { path: "/test.ts", content: ` import { F1, F2 } from "lib"; @@ -384,13 +302,11 @@ import D from "lib"; D(); `, - }, - libFile); + }, libFile); describe("skipDestructiveCodeActions=true", () => { testOrganizeImports("Syntax_Error_Body_skipDestructiveCodeActions", - /*skipDestructiveCodeActions*/ true, - { + /*skipDestructiveCodeActions*/ true, { path: "/test.ts", content: ` import { F1, F2 } from "lib"; @@ -400,13 +316,11 @@ import D from "lib"; class class class; D; `, - }, - libFile); + }, libFile); }); testOrganizeImports("Syntax_Error_Imports_skipDestructiveCodeActions", - /*skipDestructiveCodeActions*/ true, - { + /*skipDestructiveCodeActions*/ true, { path: "/test.ts", content: ` import { F1, F2 class class class; } from "lib"; @@ -416,13 +330,11 @@ import D from "lib"; D; `, - }, - libFile); + }, libFile); describe("skipDestructiveCodeActions=false", () => { testOrganizeImports("Syntax_Error_Body", - /*skipDestructiveCodeActions*/ false, - { + /*skipDestructiveCodeActions*/ false, { path: "/test.ts", content: ` import { F1, F2 } from "lib"; @@ -432,12 +344,10 @@ import D from "lib"; class class class; D; `, - }, - libFile); + }, libFile); testOrganizeImports("Syntax_Error_Imports", - /*skipDestructiveCodeActions*/ false, - { + /*skipDestructiveCodeActions*/ false, { path: "/test.ts", content: ` import { F1, F2 class class class; } from "lib"; @@ -447,8 +357,7 @@ import D from "lib"; D; `, - }, - libFile); + }, libFile); }); it("doesn't return any changes when the text would be identical", () => { @@ -457,21 +366,19 @@ D; content: `import { f } from 'foo';\nf();` }; const languageService = makeLanguageService(testFile); - const changes = languageService.organizeImports({ type: "file", fileName: testFile.path }, testFormatSettings, emptyOptions); + const changes = languageService.organizeImports({ type: "file", fileName: testFile.path }, ts.testFormatSettings, ts.emptyOptions); assert.isEmpty(changes); }); testOrganizeImports("Unused_All", - /*skipDestructiveCodeActions*/ false, - { + /*skipDestructiveCodeActions*/ false, { path: "/test.ts", content: ` import { F1, F2 } from "lib"; import * as NS from "lib"; import D from "lib"; `, - }, - libFile); + }, libFile); it("Unused_Empty", () => { const testFile = { @@ -481,13 +388,12 @@ import { } from "lib"; `, }; const languageService = makeLanguageService(testFile); - const changes = languageService.organizeImports({ type: "file", fileName: testFile.path }, testFormatSettings, emptyOptions); + const changes = languageService.organizeImports({ type: "file", fileName: testFile.path }, ts.testFormatSettings, ts.emptyOptions); assert.isEmpty(changes); }); testOrganizeImports("Unused_false_positive_module_augmentation", - /*skipDestructiveCodeActions*/ false, - { + /*skipDestructiveCodeActions*/ false, { path: "/test.d.ts", content: ` import foo from 'foo'; @@ -502,8 +408,7 @@ declare module 'caseless' { }); testOrganizeImports("Unused_preserve_imports_for_module_augmentation_in_non_declaration_file", - /*skipDestructiveCodeActions*/ false, - { + /*skipDestructiveCodeActions*/ false, { path: "/test.ts", content: ` import foo from 'foo'; @@ -526,7 +431,7 @@ const o = { x }; ` }; const languageService = makeLanguageService(testFile); - const changes = languageService.organizeImports({ type: "file", fileName: testFile.path }, testFormatSettings, emptyOptions); + const changes = languageService.organizeImports({ type: "file", fileName: testFile.path }, ts.testFormatSettings, ts.emptyOptions); assert.isEmpty(changes); }); @@ -539,13 +444,12 @@ export { x }; ` }; const languageService = makeLanguageService(testFile); - const changes = languageService.organizeImports({ type: "file", fileName: testFile.path }, testFormatSettings, emptyOptions); + const changes = languageService.organizeImports({ type: "file", fileName: testFile.path }, ts.testFormatSettings, ts.emptyOptions); assert.isEmpty(changes); }); testOrganizeImports("MoveToTop", - /*skipDestructiveCodeActions*/ false, - { + /*skipDestructiveCodeActions*/ false, { path: "/test.ts", content: ` import { F1, F2 } from "lib"; @@ -556,13 +460,11 @@ NS.F1(); import D from "lib"; D(); `, - }, - libFile); + }, libFile); /* eslint-disable no-template-curly-in-string */ testOrganizeImports("MoveToTop_Invalid", - /*skipDestructiveCodeActions*/ false, - { + /*skipDestructiveCodeActions*/ false, { path: "/test.ts", content: ` import { F1, F2 } from "lib"; @@ -575,13 +477,11 @@ import a from ${"`${'lib'}`"}; import D from "lib"; D(); `, - }, - libFile); + }, libFile); /* eslint-enable no-template-curly-in-string */ testOrganizeImports("TypeOnly", - /*skipDestructiveCodeActions*/ false, - { + /*skipDestructiveCodeActions*/ false, { path: "/test.ts", content: ` import { X } from "lib"; @@ -593,8 +493,7 @@ export { A, B, X, Y, Z };` }); testOrganizeImports("CoalesceMultipleModules", - /*skipDestructiveCodeActions*/ false, - { + /*skipDestructiveCodeActions*/ false, { path: "/test.ts", content: ` import { d } from "lib1"; @@ -603,13 +502,10 @@ import { c } from "lib2"; import { a } from "lib2"; a + b + c + d; `, - }, - { path: "/lib1.ts", content: "export const b = 1, d = 2;" }, - { path: "/lib2.ts", content: "export const a = 3, c = 4;" }); + }, { path: "/lib1.ts", content: "export const b = 1, d = 2;" }, { path: "/lib2.ts", content: "export const a = 3, c = 4;" }); testOrganizeImports("CoalesceTrivia", - /*skipDestructiveCodeActions*/ false, - { + /*skipDestructiveCodeActions*/ false, { path: "/test.ts", content: ` /*A*/import /*B*/ { /*C*/ F2 /*D*/ } /*E*/ from /*F*/ "lib" /*G*/;/*H*/ //I @@ -618,70 +514,56 @@ a + b + c + d; F1(); F2(); `, - }, - libFile); + }, libFile); testOrganizeImports("SortTrivia", - /*skipDestructiveCodeActions*/ false, - { + /*skipDestructiveCodeActions*/ false, { path: "/test.ts", content: ` /*A*/import /*B*/ "lib2" /*C*/;/*D*/ //E /*F*/import /*G*/ "lib1" /*H*/;/*I*/ //J `, - }, - { path: "/lib1.ts", content: "" }, - { path: "/lib2.ts", content: "" }); + }, { path: "/lib1.ts", content: "" }, { path: "/lib2.ts", content: "" }); testOrganizeImports("UnusedTrivia1", - /*skipDestructiveCodeActions*/ false, - { + /*skipDestructiveCodeActions*/ false, { path: "/test.ts", content: ` /*A*/import /*B*/ { /*C*/ F1 /*D*/ } /*E*/ from /*F*/ "lib" /*G*/;/*H*/ //I `, - }, - libFile); + }, libFile); testOrganizeImports("UnusedTrivia2", - /*skipDestructiveCodeActions*/ false, - { + /*skipDestructiveCodeActions*/ false, { path: "/test.ts", content: ` /*A*/import /*B*/ { /*C*/ F1 /*D*/, /*E*/ F2 /*F*/ } /*G*/ from /*H*/ "lib" /*I*/;/*J*/ //K F1(); `, - }, - libFile); + }, libFile); testOrganizeImports("UnusedHeaderComment", - /*skipDestructiveCodeActions*/ false, - { + /*skipDestructiveCodeActions*/ false, { path: "/test.ts", content: ` // Header import { F1 } from "lib"; `, - }, - libFile); + }, libFile); testOrganizeImports("SortHeaderComment", - /*skipDestructiveCodeActions*/ false, - { + /*skipDestructiveCodeActions*/ false, { path: "/test.ts", content: ` // Header import "lib2"; import "lib1"; `, - }, - { path: "/lib1.ts", content: "" }, - { path: "/lib2.ts", content: "" }); + }, { path: "/lib1.ts", content: "" }, { path: "/lib2.ts", content: "" }); testOrganizeImports("AmbientModule", - /*skipDestructiveCodeActions*/ false, - { + /*skipDestructiveCodeActions*/ false, { path: "/test.ts", content: ` declare module "mod" { @@ -692,12 +574,10 @@ declare module "mod" { function F(f1: {} = F1, f2: {} = F2) {} } `, - }, - libFile); + }, libFile); testOrganizeImports("TopLevelAndAmbientModule", - /*skipDestructiveCodeActions*/ false, - { + /*skipDestructiveCodeActions*/ false, { path: "/test.ts", content: ` import D from "lib"; @@ -715,104 +595,86 @@ import "lib"; D(); `, - }, - libFile); + }, libFile); testOrganizeImports("JsxFactoryUsedJsx", - /*skipDestructiveCodeActions*/ false, - { + /*skipDestructiveCodeActions*/ false, { path: "/test.jsx", content: ` import { React, Other } from "react";
; `, - }, - reactLibFile); + }, reactLibFile); testOrganizeImports("JsxFactoryUsedJs", - /*skipDestructiveCodeActions*/ false, - { + /*skipDestructiveCodeActions*/ false, { path: "/test.js", content: ` import { React, Other } from "react";
; `, - }, - reactLibFile); + }, reactLibFile); testOrganizeImports("JsxFactoryUsedTsx", - /*skipDestructiveCodeActions*/ false, - { + /*skipDestructiveCodeActions*/ false, { path: "/test.tsx", content: ` import { React, Other } from "react";
; `, - }, - reactLibFile); + }, reactLibFile); // TS files are not JSX contexts, so the parser does not treat // `
` as a JSX element. testOrganizeImports("JsxFactoryUsedTs", - /*skipDestructiveCodeActions*/ false, - { + /*skipDestructiveCodeActions*/ false, { path: "/test.ts", content: ` import { React, Other } from "react";
; `, - }, - reactLibFile); + }, reactLibFile); testOrganizeImports("JsxFactoryUnusedJsx", - /*skipDestructiveCodeActions*/ false, - { + /*skipDestructiveCodeActions*/ false, { path: "/test.jsx", content: ` import { React, Other } from "react"; `, - }, - reactLibFile); + }, reactLibFile); // Note: Since the file extension does not end with "x", the jsx compiler option // will not be enabled. The import should be retained regardless. testOrganizeImports("JsxFactoryUnusedJs", - /*skipDestructiveCodeActions*/ false, - { + /*skipDestructiveCodeActions*/ false, { path: "/test.js", content: ` import { React, Other } from "react"; `, - }, - reactLibFile); + }, reactLibFile); testOrganizeImports("JsxFactoryUnusedTsx", - /*skipDestructiveCodeActions*/ false, - { + /*skipDestructiveCodeActions*/ false, { path: "/test.tsx", content: ` import { React, Other } from "react"; `, - }, - reactLibFile); + }, reactLibFile); testOrganizeImports("JsxFactoryUnusedTs", - /*skipDestructiveCodeActions*/ false, - { + /*skipDestructiveCodeActions*/ false, { path: "/test.ts", content: ` import { React, Other } from "react"; `, - }, - reactLibFile); + }, reactLibFile); testOrganizeImports("JsxPragmaTsx", - /*skipDestructiveCodeActions*/ false, - { + /*skipDestructiveCodeActions*/ false, { path: "/test.tsx", content: `/** @jsx jsx */ @@ -821,14 +683,12 @@ import * as React from 'react'; export const App: React.FunctionComponent = _ =>

Hello!

`, - }, - { + }, { path: "/@emotion/core/index.d.ts", content: `import { createElement } from 'react' export const jsx: typeof createElement; export function Global(props: any): ReactElement;` - }, - { + }, { path: reactLibFile.path, content: `${reactLibFile.content} export namespace React { @@ -836,12 +696,10 @@ export namespace React { } } ` - } - ); + }); testOrganizeImports("JsxFragmentPragmaTsx", - /*skipDestructiveCodeActions*/ false, - { + /*skipDestructiveCodeActions*/ false, { path: "/test.tsx", content: `/** @jsx h */ /** @jsxFrag frag */ @@ -849,19 +707,16 @@ import { h, frag } from "@foo/core"; const elem = <>
Foo
; `, - }, - { + }, { path: "/@foo/core/index.d.ts", content: `export function h(): void; export function frag(): void; ` - } - ); + }); describe("Exports", () => { - testOrganizeExports("MoveToTop", - { + testOrganizeExports("MoveToTop", { path: "/test.ts", content: ` export { F1, F2 } from "lib"; @@ -869,12 +724,10 @@ export { F1, F2 } from "lib"; export * from "lib"; 2; `, - }, - libFile); + }, libFile); /* eslint-disable no-template-curly-in-string */ - testOrganizeExports("MoveToTop_Invalid", - { + testOrganizeExports("MoveToTop_Invalid", { path: "/test.ts", content: ` export { F1, F2 } from "lib"; @@ -886,12 +739,10 @@ export { a } from ${"`${'lib'}`"}; export { D } from "lib"; 3; `, - }, - libFile); + }, libFile); /* eslint-enable no-template-curly-in-string */ - testOrganizeExports("MoveToTop_WithImportsFirst", - { + testOrganizeExports("MoveToTop_WithImportsFirst", { path: "/test.ts", content: ` import { F1, F2 } from "lib"; @@ -904,11 +755,8 @@ export * from "lib"; 4; F1(); F2(); NS.F1(); `, - }, - libFile); - - testOrganizeExports("MoveToTop_WithExportsFirst", - { + }, libFile); + testOrganizeExports("MoveToTop_WithExportsFirst", { path: "/test.ts", content: ` export { F1, F2 } from "lib"; @@ -921,11 +769,8 @@ import * as NS from "lib"; 4; F1(); F2(); NS.F1(); `, - }, - libFile); - - testOrganizeExports("CoalesceMultipleModules", - { + }, libFile); + testOrganizeExports("CoalesceMultipleModules", { path: "/test.ts", content: ` export { d } from "lib1"; @@ -933,45 +778,30 @@ export { b } from "lib1"; export { c } from "lib2"; export { a } from "lib2"; `, - }, - { path: "/lib1.ts", content: "export const b = 1, d = 2;" }, - { path: "/lib2.ts", content: "export const a = 3, c = 4;" }); - - testOrganizeExports("CoalesceTrivia", - { + }, { path: "/lib1.ts", content: "export const b = 1, d = 2;" }, { path: "/lib2.ts", content: "export const a = 3, c = 4;" }); + testOrganizeExports("CoalesceTrivia", { path: "/test.ts", content: ` /*A*/export /*B*/ { /*C*/ F2 /*D*/ } /*E*/ from /*F*/ "lib" /*G*/;/*H*/ //I /*J*/export /*K*/ { /*L*/ F1 /*M*/ } /*N*/ from /*O*/ "lib" /*P*/;/*Q*/ //R `, - }, - libFile); - - testOrganizeExports("SortTrivia", - { + }, libFile); + testOrganizeExports("SortTrivia", { path: "/test.ts", content: ` /*A*/export /*B*/ * /*C*/ from /*D*/ "lib2" /*E*/;/*F*/ //G /*H*/export /*I*/ * /*J*/ from /*K*/ "lib1" /*L*/;/*M*/ //N `, - }, - { path: "/lib1.ts", content: "" }, - { path: "/lib2.ts", content: "" }); - - testOrganizeExports("SortHeaderComment", - { + }, { path: "/lib1.ts", content: "" }, { path: "/lib2.ts", content: "" }); + testOrganizeExports("SortHeaderComment", { path: "/test.ts", content: ` // Header export * from "lib2"; export * from "lib1"; `, - }, - { path: "/lib1.ts", content: "" }, - { path: "/lib2.ts", content: "" }); - - testOrganizeExports("AmbientModule", - { + }, { path: "/lib1.ts", content: "" }, { path: "/lib2.ts", content: "" }); + testOrganizeExports("AmbientModule", { path: "/test.ts", content: ` declare module "mod" { @@ -980,11 +810,8 @@ declare module "mod" { export { F2 } from "lib"; } `, - }, - libFile); - - testOrganizeExports("TopLevelAndAmbientModule", - { + }, libFile); + testOrganizeExports("TopLevelAndAmbientModule", { path: "/test.ts", content: ` export { D } from "lib"; @@ -998,58 +825,57 @@ declare module "mod" { export { E } from "lib"; export * from "lib"; `, - }, - libFile); + }, libFile); }); - function testOrganizeExports(testName: string, testFile: TestFSWithWatch.File, ...otherFiles: TestFSWithWatch.File[]) { + function testOrganizeExports(testName: string, testFile: ts.TestFSWithWatch.File, ...otherFiles: ts.TestFSWithWatch.File[]) { testOrganizeImports(`${testName}.exports`, /*skipDestructiveCodeActions*/ true, testFile, ...otherFiles); } - function testOrganizeImports(testName: string, skipDestructiveCodeActions: boolean, testFile: TestFSWithWatch.File, ...otherFiles: TestFSWithWatch.File[]) { + function testOrganizeImports(testName: string, skipDestructiveCodeActions: boolean, testFile: ts.TestFSWithWatch.File, ...otherFiles: ts.TestFSWithWatch.File[]) { it(testName, () => runBaseline(`organizeImports/${testName}.ts`, skipDestructiveCodeActions, testFile, ...otherFiles)); } - function runBaseline(baselinePath: string, skipDestructiveCodeActions: boolean, testFile: TestFSWithWatch.File, ...otherFiles: TestFSWithWatch.File[]) { + function runBaseline(baselinePath: string, skipDestructiveCodeActions: boolean, testFile: ts.TestFSWithWatch.File, ...otherFiles: ts.TestFSWithWatch.File[]) { const { path: testPath, content: testContent } = testFile; const languageService = makeLanguageService(testFile, ...otherFiles); - const changes = languageService.organizeImports({ skipDestructiveCodeActions, type: "file", fileName: testPath }, testFormatSettings, emptyOptions); + const changes = languageService.organizeImports({ skipDestructiveCodeActions, type: "file", fileName: testPath }, ts.testFormatSettings, ts.emptyOptions); assert.equal(changes.length, 1); assert.equal(changes[0].fileName, testPath); - const newText = textChanges.applyChanges(testContent, changes[0].textChanges); + const newText = ts.textChanges.applyChanges(testContent, changes[0].textChanges); Harness.Baseline.runBaseline(baselinePath, [ "// ==ORIGINAL==", testContent, "// ==ORGANIZED==", newText, - ].join(newLineCharacter)); + ].join(ts.newLineCharacter)); } - function makeLanguageService(...files: TestFSWithWatch.File[]) { - const host = projectSystem.createServerHost(files); - const projectService = projectSystem.createProjectService(host, { useSingleInferredProject: true }); - projectService.setCompilerOptionsForInferredProjects({ jsx: files.some(f => f.path.endsWith("x")) ? JsxEmit.React : JsxEmit.None }); + function makeLanguageService(...files: ts.TestFSWithWatch.File[]) { + const host = ts.projectSystem.createServerHost(files); + const projectService = ts.projectSystem.createProjectService(host, { useSingleInferredProject: true }); + projectService.setCompilerOptionsForInferredProjects({ jsx: files.some(f => f.path.endsWith("x")) ? ts.JsxEmit.React : ts.JsxEmit.None }); files.forEach(f => projectService.openClientFile(f.path)); return projectService.inferredProjects[0].getLanguageService(); } }); - function parseImports(...importStrings: string[]): readonly ImportDeclaration[] { - const sourceFile = createSourceFile("a.ts", importStrings.join("\n"), ScriptTarget.ES2015, /*setParentNodes*/ true, ScriptKind.TS); - const imports = filter(sourceFile.statements, isImportDeclaration); + function parseImports(...importStrings: string[]): readonly ts.ImportDeclaration[] { + const sourceFile = ts.createSourceFile("a.ts", importStrings.join("\n"), ts.ScriptTarget.ES2015, /*setParentNodes*/ true, ts.ScriptKind.TS); + const imports = ts.filter(sourceFile.statements, ts.isImportDeclaration); assert.equal(imports.length, importStrings.length); return imports; } - function parseExports(...exportStrings: string[]): readonly ExportDeclaration[] { - const sourceFile = createSourceFile("a.ts", exportStrings.join("\n"), ScriptTarget.ES2015, /*setParentNodes*/ true, ScriptKind.TS); - const exports = filter(sourceFile.statements, isExportDeclaration); + function parseExports(...exportStrings: string[]): readonly ts.ExportDeclaration[] { + const sourceFile = ts.createSourceFile("a.ts", exportStrings.join("\n"), ts.ScriptTarget.ES2015, /*setParentNodes*/ true, ts.ScriptKind.TS); + const exports = ts.filter(sourceFile.statements, ts.isExportDeclaration); assert.equal(exports.length, exportStrings.length); return exports; } - function assertEqual(node1?: Node, node2?: Node) { + function assertEqual(node1?: ts.Node, node2?: ts.Node) { if (node1 === undefined) { assert.isUndefined(node2); return; @@ -1062,60 +888,60 @@ export * from "lib"; assert.equal(node1.kind, node2.kind); switch (node1.kind) { - case SyntaxKind.ImportDeclaration: - const decl1 = node1 as ImportDeclaration; - const decl2 = node2 as ImportDeclaration; + case ts.SyntaxKind.ImportDeclaration: + const decl1 = node1 as ts.ImportDeclaration; + const decl2 = node2 as ts.ImportDeclaration; assertEqual(decl1.importClause, decl2.importClause); assertEqual(decl1.moduleSpecifier, decl2.moduleSpecifier); break; - case SyntaxKind.ImportClause: - const clause1 = node1 as ImportClause; - const clause2 = node2 as ImportClause; + case ts.SyntaxKind.ImportClause: + const clause1 = node1 as ts.ImportClause; + const clause2 = node2 as ts.ImportClause; assertEqual(clause1.name, clause2.name); assertEqual(clause1.namedBindings, clause2.namedBindings); break; - case SyntaxKind.NamespaceImport: - const nsi1 = node1 as NamespaceImport; - const nsi2 = node2 as NamespaceImport; + case ts.SyntaxKind.NamespaceImport: + const nsi1 = node1 as ts.NamespaceImport; + const nsi2 = node2 as ts.NamespaceImport; assertEqual(nsi1.name, nsi2.name); break; - case SyntaxKind.NamedImports: - const ni1 = node1 as NamedImports; - const ni2 = node2 as NamedImports; + case ts.SyntaxKind.NamedImports: + const ni1 = node1 as ts.NamedImports; + const ni2 = node2 as ts.NamedImports; assertListEqual(ni1.elements, ni2.elements); break; - case SyntaxKind.ImportSpecifier: - const is1 = node1 as ImportSpecifier; - const is2 = node2 as ImportSpecifier; + case ts.SyntaxKind.ImportSpecifier: + const is1 = node1 as ts.ImportSpecifier; + const is2 = node2 as ts.ImportSpecifier; assertEqual(is1.name, is2.name); assertEqual(is1.propertyName, is2.propertyName); break; - case SyntaxKind.ExportDeclaration: - const ed1 = node1 as ExportDeclaration; - const ed2 = node2 as ExportDeclaration; + case ts.SyntaxKind.ExportDeclaration: + const ed1 = node1 as ts.ExportDeclaration; + const ed2 = node2 as ts.ExportDeclaration; assertEqual(ed1.exportClause, ed2.exportClause); assertEqual(ed1.moduleSpecifier, ed2.moduleSpecifier); break; - case SyntaxKind.NamedExports: - const ne1 = node1 as NamedExports; - const ne2 = node2 as NamedExports; + case ts.SyntaxKind.NamedExports: + const ne1 = node1 as ts.NamedExports; + const ne2 = node2 as ts.NamedExports; assertListEqual(ne1.elements, ne2.elements); break; - case SyntaxKind.ExportSpecifier: - const es1 = node1 as ExportSpecifier; - const es2 = node2 as ExportSpecifier; + case ts.SyntaxKind.ExportSpecifier: + const es1 = node1 as ts.ExportSpecifier; + const es2 = node2 as ts.ExportSpecifier; assertEqual(es1.name, es2.name); assertEqual(es1.propertyName, es2.propertyName); break; - case SyntaxKind.Identifier: - const id1 = node1 as Identifier; - const id2 = node2 as Identifier; + case ts.SyntaxKind.Identifier: + const id1 = node1 as ts.Identifier; + const id2 = node2 as ts.Identifier; assert.equal(id1.text, id2.text); break; - case SyntaxKind.StringLiteral: - case SyntaxKind.NoSubstitutionTemplateLiteral: - const sl1 = node1 as LiteralLikeNode; - const sl2 = node2 as LiteralLikeNode; + case ts.SyntaxKind.StringLiteral: + case ts.SyntaxKind.NoSubstitutionTemplateLiteral: + const sl1 = node1 as ts.LiteralLikeNode; + const sl2 = node2 as ts.LiteralLikeNode; assert.equal(sl1.text, sl2.text); break; default: @@ -1124,7 +950,7 @@ export * from "lib"; } } - function assertListEqual(list1: readonly Node[], list2: readonly Node[]) { + function assertListEqual(list1: readonly ts.Node[], list2: readonly ts.Node[]) { if (list1 === undefined || list2 === undefined) { assert.isUndefined(list1); assert.isUndefined(list2); diff --git a/src/testRunner/unittests/services/preProcessFile.ts b/src/testRunner/unittests/services/preProcessFile.ts index a6369d6e4d4cf..83bb364937e71 100644 --- a/src/testRunner/unittests/services/preProcessFile.ts +++ b/src/testRunner/unittests/services/preProcessFile.ts @@ -23,8 +23,7 @@ describe("unittests:: services:: PreProcessFile:", () => { it("Correctly return referenced files from triple slash", () => { test("///" + "\n" + "///" + "\n" + "///" + "\n" + "///", /*readImportFile*/ true, - /*detectJavaScriptImports*/ false, - { + /*detectJavaScriptImports*/ false, { referencedFiles: [{ fileName: "refFile1.ts", pos: 22, end: 33 }, { fileName: "refFile2.ts", pos: 59, end: 70 }, { fileName: "refFile3.ts", pos: 94, end: 105 }, { fileName: "..\\refFile4d.ts", pos: 131, end: 146 }], importedFiles: [] as ts.FileReference[], @@ -38,8 +37,7 @@ describe("unittests:: services:: PreProcessFile:", () => { it("Do not return reference path because of invalid triple-slash syntax", () => { test("///" + "\n" + "///" + "\n" + "///" + "\n" + "///", /*readImportFile*/ true, - /*detectJavaScriptImports*/ false, - { + /*detectJavaScriptImports*/ false, { referencedFiles: [] as ts.FileReference[], importedFiles: [] as ts.FileReference[], typeReferenceDirectives: [], @@ -52,8 +50,7 @@ describe("unittests:: services:: PreProcessFile:", () => { it("Do not return reference path of non-imports", () => { test("Quill.import('delta');", /*readImportFile*/ true, - /*detectJavaScriptImports*/ false, - { + /*detectJavaScriptImports*/ false, { referencedFiles: [] as ts.FileReference[], importedFiles: [] as ts.FileReference[], typeReferenceDirectives: [], @@ -66,8 +63,7 @@ describe("unittests:: services:: PreProcessFile:", () => { it("Do not return reference path of nested non-imports", () => { test("a.b.import('c');", /*readImportFile*/ true, - /*detectJavaScriptImports*/ false, - { + /*detectJavaScriptImports*/ false, { referencedFiles: [] as ts.FileReference[], importedFiles: [] as ts.FileReference[], typeReferenceDirectives: [], @@ -80,8 +76,7 @@ describe("unittests:: services:: PreProcessFile:", () => { it("Correctly return imported files", () => { test("import i1 = require(\"r1.ts\"); import i2 =require(\"r2.ts\"); import i3= require(\"r3.ts\"); import i4=require(\"r4.ts\"); import i5 = require (\"r5.ts\");", /*readImportFile*/ true, - /*detectJavaScriptImports*/ false, - { + /*detectJavaScriptImports*/ false, { referencedFiles: [] as ts.FileReference[], typeReferenceDirectives: [], libReferenceDirectives: [], @@ -95,8 +90,7 @@ describe("unittests:: services:: PreProcessFile:", () => { it("Do not return imported files if readImportFiles argument is false", () => { test("import i1 = require(\"r1.ts\"); import i2 =require(\"r2.ts\"); import i3= require(\"r3.ts\"); import i4=require(\"r4.ts\"); import i5 = require (\"r5.ts\");", /*readImportFile*/ false, - /*detectJavaScriptImports*/ false, - { + /*detectJavaScriptImports*/ false, { referencedFiles: [] as ts.FileReference[], typeReferenceDirectives: [], libReferenceDirectives: [], @@ -109,8 +103,7 @@ describe("unittests:: services:: PreProcessFile:", () => { it("Do not return import path because of invalid import syntax", () => { test("import i1 require(\"r1.ts\"); import = require(\"r2.ts\") import i3= require(\"r3.ts\"); import i5", /*readImportFile*/ true, - /*detectJavaScriptImports*/ false, - { + /*detectJavaScriptImports*/ false, { referencedFiles: [] as ts.FileReference[], typeReferenceDirectives: [], libReferenceDirectives: [], @@ -123,8 +116,7 @@ describe("unittests:: services:: PreProcessFile:", () => { it("Correctly return referenced files and import files", () => { test("///" + "\n" + "///" + "\n" + "import i1 = require(\"r1.ts\"); import i2 =require(\"r2.ts\");", /*readImportFile*/ true, - /*detectJavaScriptImports*/ false, - { + /*detectJavaScriptImports*/ false, { referencedFiles: [{ fileName: "refFile1.ts", pos: 20, end: 31 }, { fileName: "refFile2.ts", pos: 57, end: 68 }], typeReferenceDirectives: [], libReferenceDirectives: [], @@ -137,8 +129,7 @@ describe("unittests:: services:: PreProcessFile:", () => { it("Correctly return referenced files and import files even with some invalid syntax", () => { test("///" + "\n" + "///" + "\n" + "import i1 = require(\"r1.ts\"); import = require(\"r2.ts\"); import i2 = require(\"r3.ts\");", /*readImportFile*/ true, - /*detectJavaScriptImports*/ false, - { + /*detectJavaScriptImports*/ false, { referencedFiles: [{ fileName: "refFile1.ts", pos: 20, end: 31 }], typeReferenceDirectives: [], libReferenceDirectives: [], @@ -157,8 +148,7 @@ describe("unittests:: services:: PreProcessFile:", () => { "import {a as A, b, c as C} from \"m6\";" + "\n" + "import def , {a, b, c as C} from \"m7\";" + "\n", /*readImportFile*/ true, - /*detectJavaScriptImports*/ false, - { + /*detectJavaScriptImports*/ false, { referencedFiles: [], typeReferenceDirectives: [], libReferenceDirectives: [], @@ -193,8 +183,7 @@ describe("unittests:: services:: PreProcessFile:", () => { " * ```" + "\n" + " */", /*readImportFile*/ true, - /*detectJavaScriptImports*/ true, - { + /*detectJavaScriptImports*/ true, { referencedFiles: [], typeReferenceDirectives: [], libReferenceDirectives: [], @@ -209,8 +198,7 @@ describe("unittests:: services:: PreProcessFile:", () => { /* eslint-disable no-template-curly-in-string */ test("`${foo}`; import \"./foo\";", /*readImportFile*/ true, - /*detectJavaScriptImports*/ true, - { + /*detectJavaScriptImports*/ true, { referencedFiles: [], typeReferenceDirectives: [], libReferenceDirectives: [], @@ -229,8 +217,7 @@ describe("unittests:: services:: PreProcessFile:", () => { "${import(\"a\")} {import(\"b\")} " + "\n" + "${/* A comment */} ${/* import(\"ignored\") */}
)}`", /*readImportFile*/ true, - /*detectJavaScriptImports*/ true, - { + /*detectJavaScriptImports*/ true, { referencedFiles: [], typeReferenceDirectives: [], libReferenceDirectives: [], @@ -248,8 +235,7 @@ describe("unittests:: services:: PreProcessFile:", () => { /* eslint-disable no-template-curly-in-string */ test("`${foo(`${bar(`${import(\"a\")} ${import(\"b\")}`, `${baz(`${import(\"c\") ${import(\"d\")}`)}`)}`)}`", /*readImportFile*/ true, - /*detectJavaScriptImports*/ true, - { + /*detectJavaScriptImports*/ true, { referencedFiles: [], typeReferenceDirectives: [], libReferenceDirectives: [], @@ -269,8 +255,7 @@ describe("unittests:: services:: PreProcessFile:", () => { /* eslint-disable no-template-curly-in-string */ test("foo`${ fn({ a: 100 }, import(\"a\"), `${import(\"b\")}`, import(\"c\"), `${import(\"d\")} foo`, import(\"e\")) }`", /*readImportFile*/ true, - /*detectJavaScriptImports*/ true, - { + /*detectJavaScriptImports*/ true, { referencedFiles: [], typeReferenceDirectives: [], libReferenceDirectives: [], @@ -292,8 +277,7 @@ describe("unittests:: services:: PreProcessFile:", () => { test("const x = `hello ${await import(\"a\").default}`;" + "\n\n" + "import { y } from \"b\";", /*readImportFile*/ true, - /*detectJavaScriptImports*/ true, - { + /*detectJavaScriptImports*/ true, { referencedFiles: [], typeReferenceDirectives: [], libReferenceDirectives: [], @@ -314,8 +298,7 @@ describe("unittests:: services:: PreProcessFile:", () => { "const y = `y ${import(\"c\")}`;" + "\n\n" + "import { d } from \"d\";", /*readImportFile*/ true, - /*detectJavaScriptImports*/ true, - { + /*detectJavaScriptImports*/ true, { referencedFiles: [], typeReferenceDirectives: [], libReferenceDirectives: [], @@ -335,8 +318,7 @@ describe("unittests:: services:: PreProcessFile:", () => { /* eslint-disable no-template-curly-in-string */ test("const foo = `${", /*readImportFile*/ true, - /*detectJavaScriptImports*/ true, - { + /*detectJavaScriptImports*/ true, { referencedFiles: [], typeReferenceDirectives: [], libReferenceDirectives: [], @@ -353,8 +335,7 @@ describe("unittests:: services:: PreProcessFile:", () => { "export {a as A} from \"m3\";" + "\n" + "export {a as A, b, c as C} from \"m4\";" + "\n", /*readImportFile*/ true, - /*detectJavaScriptImports*/ false, - { + /*detectJavaScriptImports*/ false, { referencedFiles: [], typeReferenceDirectives: [], libReferenceDirectives: [], @@ -383,8 +364,7 @@ describe("unittests:: services:: PreProcessFile:", () => { "export import type T = require(\"m11\");" + "\n" + "export import type = require(\"m12\");" + "\n", /*readImportFile*/ true, - /*detectJavaScriptImports*/ false, - { + /*detectJavaScriptImports*/ false, { referencedFiles: [] as ts.FileReference[], typeReferenceDirectives: [], libReferenceDirectives: [], @@ -413,8 +393,7 @@ describe("unittests:: services:: PreProcessFile:", () => { "export type {a as A} from \"m3\";" + "\n" + "export type {a as A, b, c as C} from \"m4\";" + "\n", /*readImportFile*/ true, - /*detectJavaScriptImports*/ false, - { + /*detectJavaScriptImports*/ false, { referencedFiles: [] as ts.FileReference[], typeReferenceDirectives: [], libReferenceDirectives: [], @@ -434,8 +413,7 @@ describe("unittests:: services:: PreProcessFile:", () => { "let y: import(\"m2\").Bar.I = { a: \"\", b: 0 };" + "\n" + "let shim: typeof import(\"m3\") = { Bar: Bar2 };" + "\n", /*readImportFile*/ true, - /*detectJavaScriptImports*/ false, - { + /*detectJavaScriptImports*/ false, { referencedFiles: [], typeReferenceDirectives: [], libReferenceDirectives: [], @@ -457,8 +435,7 @@ describe("unittests:: services:: PreProcessFile:", () => { } `, /*readImportFile*/ true, - /*detectJavaScriptImports*/ false, - { + /*detectJavaScriptImports*/ false, { referencedFiles: [], typeReferenceDirectives: [], libReferenceDirectives: [], @@ -471,8 +448,7 @@ describe("unittests:: services:: PreProcessFile:", () => { it("Correctly handles export import declarations", () => { test("export import a = require(\"m1\");", /*readImportFile*/ true, - /*detectJavaScriptImports*/ false, - { + /*detectJavaScriptImports*/ false, { referencedFiles: [], typeReferenceDirectives: [], libReferenceDirectives: [], @@ -491,8 +467,7 @@ describe("unittests:: services:: PreProcessFile:", () => { var z = { f: require('m4') } `, /*readImportFile*/ true, - /*detectJavaScriptImports*/ true, - { + /*detectJavaScriptImports*/ true, { referencedFiles: [], typeReferenceDirectives: [], libReferenceDirectives: [], @@ -512,8 +487,7 @@ describe("unittests:: services:: PreProcessFile:", () => { }); `, /*readImportFile*/ true, - /*detectJavaScriptImports*/ true, - { + /*detectJavaScriptImports*/ true, { referencedFiles: [], typeReferenceDirectives: [], libReferenceDirectives: [], @@ -532,8 +506,7 @@ describe("unittests:: services:: PreProcessFile:", () => { }); `, /*readImportFile*/ true, - /*detectJavaScriptImports*/ true, - { + /*detectJavaScriptImports*/ true, { referencedFiles: [], typeReferenceDirectives: [], libReferenceDirectives: [], @@ -555,8 +528,7 @@ describe("unittests:: services:: PreProcessFile:", () => { export {} `, /*readImportFile*/ true, - /*detectJavaScriptImports*/ false, - { + /*detectJavaScriptImports*/ false, { referencedFiles: [], typeReferenceDirectives: [], libReferenceDirectives: [], @@ -576,8 +548,7 @@ describe("unittests:: services:: PreProcessFile:", () => { import * as x from "m"; `, /*readImportFile*/ true, - /*detectJavaScriptImports*/ false, - { + /*detectJavaScriptImports*/ false, { referencedFiles: [], typeReferenceDirectives: [], libReferenceDirectives: [], @@ -598,8 +569,7 @@ describe("unittests:: services:: PreProcessFile:", () => { import m = require("m"); `, /*readImportFile*/ true, - /*detectJavaScriptImports*/ false, - { + /*detectJavaScriptImports*/ false, { referencedFiles: [], typeReferenceDirectives: [], libReferenceDirectives: [], @@ -620,8 +590,7 @@ describe("unittests:: services:: PreProcessFile:", () => { export = N; `, /*readImportFile*/ true, - /*detectJavaScriptImports*/ false, - { + /*detectJavaScriptImports*/ false, { referencedFiles: [], typeReferenceDirectives: [], libReferenceDirectives: [], @@ -641,8 +610,7 @@ describe("unittests:: services:: PreProcessFile:", () => { export import IN = N; `, /*readImportFile*/ true, - /*detectJavaScriptImports*/ false, - { + /*detectJavaScriptImports*/ false, { referencedFiles: [], typeReferenceDirectives: [], libReferenceDirectives: [], @@ -661,8 +629,7 @@ describe("unittests:: services:: PreProcessFile:", () => { export let x = 1; `, /*readImportFile*/ true, - /*detectJavaScriptImports*/ false, - { + /*detectJavaScriptImports*/ false, { referencedFiles: [], typeReferenceDirectives: [], libReferenceDirectives: [], @@ -683,8 +650,7 @@ describe("unittests:: services:: PreProcessFile:", () => { } `, /*readImportFile*/ true, - /*detectJavaScriptImports*/ false, - { + /*detectJavaScriptImports*/ false, { referencedFiles: [], typeReferenceDirectives: [], libReferenceDirectives: [], @@ -708,8 +674,7 @@ describe("unittests:: services:: PreProcessFile:", () => { } `, /*readImportFile*/ true, - /*detectJavaScriptImports*/ false, - { + /*detectJavaScriptImports*/ false, { referencedFiles: [], typeReferenceDirectives: [], libReferenceDirectives: [], @@ -729,8 +694,7 @@ describe("unittests:: services:: PreProcessFile:", () => { /// `, /*readImportFile*/ true, - /*detectJavaScriptImports*/ false, - { + /*detectJavaScriptImports*/ false, { referencedFiles: [ { pos: 34, end: 35, fileName: "a" }, { pos: 112, end: 114, fileName: "a2" } @@ -753,14 +717,12 @@ describe("unittests:: services:: PreProcessFile:", () => { /// `, /*readImportFile*/ true, - /*detectJavaScriptImports*/ false, - { + /*detectJavaScriptImports*/ false, { referencedFiles: [ { pos: 34, end: 35, fileName: "a" }, { pos: 110, end: 112, fileName: "a2" } ], - typeReferenceDirectives: [ - ], + typeReferenceDirectives: [], libReferenceDirectives: [ { pos: 71, end: 73, fileName: "a1" }, { pos: 148, end: 150, fileName: "a3" } @@ -777,8 +739,7 @@ describe("unittests:: services:: PreProcessFile:", () => { "Promise.all([import('mod3'), import(`mod4`)]);" + "\n" + "import(/* webpackChunkName: 'module5' */ `mod5`);" + "\n", /*readImportFile*/ true, - /*detectJavaScriptImports*/ false, - { + /*detectJavaScriptImports*/ false, { referencedFiles: [], typeReferenceDirectives: [], libReferenceDirectives: [], @@ -799,8 +760,7 @@ describe("unittests:: services:: PreProcessFile:", () => { "f(require(`mod2`));" + "\n" + "const a = { x: require(`mod3`) };" + "\n", /*readImportFile*/ true, - /*detectJavaScriptImports*/ true, - { + /*detectJavaScriptImports*/ true, { referencedFiles: [], typeReferenceDirectives: [], libReferenceDirectives: [], @@ -817,8 +777,7 @@ describe("unittests:: services:: PreProcessFile:", () => { it("Correctly handles dependency lists in define(modName, [deplist]) calls with template literals in JS files", () => { test("define(`mod`, [`mod1`, `mod2`], (m1, m2) => {});", /*readImportFile*/ true, - /*detectJavaScriptImports*/ true, - { + /*detectJavaScriptImports*/ true, { referencedFiles: [], typeReferenceDirectives: [], libReferenceDirectives: [], diff --git a/src/testRunner/unittests/services/textChanges.ts b/src/testRunner/unittests/services/textChanges.ts index 534d57ebf8f08..a369cf9d69c96 100644 --- a/src/testRunner/unittests/services/textChanges.ts +++ b/src/testRunner/unittests/services/textChanges.ts @@ -2,58 +2,57 @@ namespace ts { describe("unittests:: services:: textChanges", () => { - function findChild(name: string, n: Node) { + function findChild(name: string, n: ts.Node) { return find(n)!; - function find(node: Node): Node | undefined { - if (isDeclaration(node) && node.name && isIdentifier(node.name) && node.name.escapedText === name) { + function find(node: ts.Node): ts.Node | undefined { + if (ts.isDeclaration(node) && node.name && ts.isIdentifier(node.name) && node.name.escapedText === name) { return node; } else { - return forEachChild(node, find); + return ts.forEachChild(node, find); } } } - const printerOptions = { newLine: NewLineKind.LineFeed }; - const newLineCharacter = getNewLineCharacter(printerOptions); - - function getRuleProvider(placeOpenBraceOnNewLineForFunctions: boolean): formatting.FormatContext { - return formatting.getFormatContext(placeOpenBraceOnNewLineForFunctions ? { ...testFormatSettings, placeOpenBraceOnNewLineForFunctions: true } : testFormatSettings, notImplementedHost); + const printerOptions = { newLine: ts.NewLineKind.LineFeed }; + const newLineCharacter = ts.getNewLineCharacter(printerOptions); + function getRuleProvider(placeOpenBraceOnNewLineForFunctions: boolean): ts.formatting.FormatContext { + return ts.formatting.getFormatContext(placeOpenBraceOnNewLineForFunctions ? { ...ts.testFormatSettings, placeOpenBraceOnNewLineForFunctions: true } : ts.testFormatSettings, ts.notImplementedHost); } // validate that positions that were recovered from the printed text actually match positions that will be created if the same text is parsed. - function verifyPositions(node: Node, text: string): void { + function verifyPositions(node: ts.Node, text: string): void { const nodeList = flattenNodes(node); - const sourceFile = createSourceFile("f.ts", text, ScriptTarget.ES2015); + const sourceFile = ts.createSourceFile("f.ts", text, ts.ScriptTarget.ES2015); const parsedNodeList = flattenNodes(sourceFile.statements[0]); - zipWith(nodeList, parsedNodeList, (left, right) => { - Debug.assert(left.pos === right.pos); - Debug.assert(left.end === right.end); + ts.zipWith(nodeList, parsedNodeList, (left, right) => { + ts.Debug.assert(left.pos === right.pos); + ts.Debug.assert(left.end === right.end); }); - function flattenNodes(n: Node) { - const data: (Node | NodeArray)[] = []; + function flattenNodes(n: ts.Node) { + const data: (ts.Node | ts.NodeArray)[] = []; walk(n); return data; - function walk(n: Node | NodeArray): void { + function walk(n: ts.Node | ts.NodeArray): void { data.push(n); - return isArray(n) ? forEach(n, walk) : forEachChild(n, walk, walk); + return ts.isArray(n) ? ts.forEach(n, walk) : ts.forEachChild(n, walk, walk); } } } - function runSingleFileTest(caption: string, placeOpenBraceOnNewLineForFunctions: boolean, text: string, validateNodes: boolean, testBlock: (sourceFile: SourceFile, changeTracker: textChanges.ChangeTracker) => void) { + function runSingleFileTest(caption: string, placeOpenBraceOnNewLineForFunctions: boolean, text: string, validateNodes: boolean, testBlock: (sourceFile: ts.SourceFile, changeTracker: ts.textChanges.ChangeTracker) => void) { it(caption, () => { - const sourceFile = createSourceFile("source.ts", text, ScriptTarget.ES2015, /*setParentNodes*/ true); + const sourceFile = ts.createSourceFile("source.ts", text, ts.ScriptTarget.ES2015, /*setParentNodes*/ true); const rulesProvider = getRuleProvider(placeOpenBraceOnNewLineForFunctions); - const changeTracker = new textChanges.ChangeTracker(newLineCharacter, rulesProvider); + const changeTracker = new ts.textChanges.ChangeTracker(newLineCharacter, rulesProvider); testBlock(sourceFile, changeTracker); const changes = changeTracker.getChanges(validateNodes ? verifyPositions : undefined); assert.equal(changes.length, 1); assert.equal(changes[0].fileName, sourceFile.fileName); - const modified = textChanges.applyChanges(sourceFile.text, changes[0].textChanges); + const modified = ts.textChanges.applyChanges(sourceFile.text, changes[0].textChanges); Harness.Baseline.runBaseline(`textChanges/${caption}.js`, `===ORIGINAL===${newLineCharacter}${text}${newLineCharacter}===MODIFIED===${newLineCharacter}${modified}`); }); } @@ -81,28 +80,23 @@ namespace M } }`; runSingleFileTest("extractMethodLike", /*placeOpenBraceOnNewLineForFunctions*/ true, text, /*validateNodes*/ true, (sourceFile, changeTracker) => { - const statements = (findChild("foo", sourceFile) as FunctionDeclaration).body!.statements.slice(1); - const newFunction = factory.createFunctionDeclaration( + const statements = (findChild("foo", sourceFile) as ts.FunctionDeclaration).body!.statements.slice(1); + const newFunction = ts.factory.createFunctionDeclaration( /*decorators*/ undefined, /*modifiers*/ undefined, /*asteriskToken*/ undefined, /*name*/ "bar", - /*typeParameters*/ undefined, - /*parameters*/ emptyArray, - /*type*/ factory.createKeywordTypeNode(SyntaxKind.AnyKeyword), - /*body */ factory.createBlock(statements) - ); + /*typeParameters*/ undefined, ts.emptyArray, + /*type*/ ts.factory.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword), + /*body */ ts.factory.createBlock(statements)); changeTracker.insertNodeBefore(sourceFile, /*before*/findChild("M2", sourceFile), newFunction); // replace statements with return statement - const newStatement = factory.createReturnStatement( - factory.createCallExpression( + const newStatement = ts.factory.createReturnStatement(ts.factory.createCallExpression( /*expression*/ newFunction.name!, - /*typeArguments*/ undefined, - /*argumentsArray*/ emptyArray - )); - changeTracker.replaceNodeRange(sourceFile, statements[0], last(statements), newStatement, { suffix: newLineCharacter }); + /*typeArguments*/ undefined, ts.emptyArray)); + changeTracker.replaceNodeRange(sourceFile, statements[0], ts.last(statements), newStatement, { suffix: newLineCharacter }); }); } { @@ -119,13 +113,13 @@ function bar() { changeTracker.deleteRange(sourceFile, { pos: text.indexOf("function foo"), end: text.indexOf("function bar") }); }); } - function findVariableStatementContaining(name: string, sourceFile: SourceFile): VariableStatement { - return cast(findVariableDeclarationContaining(name, sourceFile).parent.parent, isVariableStatement); + function findVariableStatementContaining(name: string, sourceFile: ts.SourceFile): ts.VariableStatement { + return ts.cast(findVariableDeclarationContaining(name, sourceFile).parent.parent, ts.isVariableStatement); } - function findVariableDeclarationContaining(name: string, sourceFile: SourceFile): VariableDeclaration { - return cast(findChild(name, sourceFile), isVariableDeclaration); + function findVariableDeclarationContaining(name: string, sourceFile: ts.SourceFile): ts.VariableDeclaration { + return ts.cast(findChild(name, sourceFile), ts.isVariableDeclaration); } - const { deleteNode } = textChanges; + const { deleteNode } = ts.textChanges; { const text = ` var x = 1; // some comment - 1 @@ -139,13 +133,13 @@ var z = 3; // comment 4 deleteNode(changeTracker, sourceFile, findVariableStatementContaining("y", sourceFile)); }); runSingleFileTest("deleteNode2", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => { - deleteNode(changeTracker, sourceFile, findVariableStatementContaining("y", sourceFile), { leadingTriviaOption: textChanges.LeadingTriviaOption.Exclude }); + deleteNode(changeTracker, sourceFile, findVariableStatementContaining("y", sourceFile), { leadingTriviaOption: ts.textChanges.LeadingTriviaOption.Exclude }); }); runSingleFileTest("deleteNode3", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => { - deleteNode(changeTracker, sourceFile, findVariableStatementContaining("y", sourceFile), { trailingTriviaOption: textChanges.TrailingTriviaOption.Exclude }); + deleteNode(changeTracker, sourceFile, findVariableStatementContaining("y", sourceFile), { trailingTriviaOption: ts.textChanges.TrailingTriviaOption.Exclude }); }); runSingleFileTest("deleteNode4", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => { - deleteNode(changeTracker, sourceFile, findVariableStatementContaining("y", sourceFile), { leadingTriviaOption: textChanges.LeadingTriviaOption.Exclude, trailingTriviaOption: textChanges.TrailingTriviaOption.Exclude }); + deleteNode(changeTracker, sourceFile, findVariableStatementContaining("y", sourceFile), { leadingTriviaOption: ts.textChanges.LeadingTriviaOption.Exclude, trailingTriviaOption: ts.textChanges.TrailingTriviaOption.Exclude }); }); runSingleFileTest("deleteNode5", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => { deleteNode(changeTracker, sourceFile, findVariableStatementContaining("x", sourceFile)); @@ -165,48 +159,34 @@ var a = 4; // comment 7 changeTracker.deleteNodeRange(sourceFile, findVariableStatementContaining("y", sourceFile), findVariableStatementContaining("z", sourceFile)); }); runSingleFileTest("deleteNodeRange2", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => { - changeTracker.deleteNodeRange(sourceFile, findVariableStatementContaining("y", sourceFile), findVariableStatementContaining("z", sourceFile), - { leadingTriviaOption: textChanges.LeadingTriviaOption.Exclude }); + changeTracker.deleteNodeRange(sourceFile, findVariableStatementContaining("y", sourceFile), findVariableStatementContaining("z", sourceFile), { leadingTriviaOption: ts.textChanges.LeadingTriviaOption.Exclude }); }); runSingleFileTest("deleteNodeRange3", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => { - changeTracker.deleteNodeRange(sourceFile, findVariableStatementContaining("y", sourceFile), findVariableStatementContaining("z", sourceFile), - { trailingTriviaOption: textChanges.TrailingTriviaOption.Exclude }); + changeTracker.deleteNodeRange(sourceFile, findVariableStatementContaining("y", sourceFile), findVariableStatementContaining("z", sourceFile), { trailingTriviaOption: ts.textChanges.TrailingTriviaOption.Exclude }); }); runSingleFileTest("deleteNodeRange4", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => { - changeTracker.deleteNodeRange(sourceFile, findVariableStatementContaining("y", sourceFile), findVariableStatementContaining("z", sourceFile), - { leadingTriviaOption: textChanges.LeadingTriviaOption.Exclude, trailingTriviaOption: textChanges.TrailingTriviaOption.Exclude }); + changeTracker.deleteNodeRange(sourceFile, findVariableStatementContaining("y", sourceFile), findVariableStatementContaining("z", sourceFile), { leadingTriviaOption: ts.textChanges.LeadingTriviaOption.Exclude, trailingTriviaOption: ts.textChanges.TrailingTriviaOption.Exclude }); }); } function createTestVariableDeclaration(name: string) { - return factory.createVariableDeclaration(name, /*exclamationToken*/ undefined, /*type*/ undefined, factory.createObjectLiteralExpression([factory.createPropertyAssignment("p1", factory.createNumericLiteral(1))], /*multiline*/ true)); + return ts.factory.createVariableDeclaration(name, /*exclamationToken*/ undefined, /*type*/ undefined, ts.factory.createObjectLiteralExpression([ts.factory.createPropertyAssignment("p1", ts.factory.createNumericLiteral(1))], /*multiline*/ true)); } function createTestClass() { - return factory.createClassDeclaration( + return ts.factory.createClassDeclaration( + /*decorators*/ undefined, [ + ts.factory.createToken(ts.SyntaxKind.PublicKeyword) + ], "class1", + /*typeParameters*/ undefined, [ + ts.factory.createHeritageClause(ts.SyntaxKind.ImplementsKeyword, [ + ts.factory.createExpressionWithTypeArguments(ts.factory.createIdentifier("interface1"), /*typeArguments*/ undefined) + ]) + ], [ + ts.factory.createPropertyDeclaration( /*decorators*/ undefined, - [ - factory.createToken(SyntaxKind.PublicKeyword) - ], - "class1", - /*typeParameters*/ undefined, - [ - factory.createHeritageClause( - SyntaxKind.ImplementsKeyword, - [ - factory.createExpressionWithTypeArguments(factory.createIdentifier("interface1"), /*typeArguments*/ undefined) - ] - ) - ], - [ - factory.createPropertyDeclaration( - /*decorators*/ undefined, - /*modifiers*/ undefined, - "property1", - /*questionToken*/ undefined, - factory.createKeywordTypeNode(SyntaxKind.BooleanKeyword), - /*initializer*/ undefined - ) - ] - ); + /*modifiers*/ undefined, "property1", + /*questionToken*/ undefined, ts.factory.createKeywordTypeNode(ts.SyntaxKind.BooleanKeyword), + /*initializer*/ undefined) + ]); } { const text = ` @@ -253,16 +233,16 @@ var a = 4; // comment 7`; changeTracker.replaceNode(sourceFile, findVariableStatementContaining("y", sourceFile), createTestClass(), { suffix: newLineCharacter }); }); runSingleFileTest("replaceNode2", /*placeOpenBraceOnNewLineForFunctions*/ true, text, /*validateNodes*/ true, (sourceFile, changeTracker) => { - changeTracker.replaceNode(sourceFile, findVariableStatementContaining("y", sourceFile), createTestClass(), { leadingTriviaOption: textChanges.LeadingTriviaOption.Exclude, suffix: newLineCharacter, prefix: newLineCharacter }); + changeTracker.replaceNode(sourceFile, findVariableStatementContaining("y", sourceFile), createTestClass(), { leadingTriviaOption: ts.textChanges.LeadingTriviaOption.Exclude, suffix: newLineCharacter, prefix: newLineCharacter }); }); runSingleFileTest("replaceNode3", /*placeOpenBraceOnNewLineForFunctions*/ true, text, /*validateNodes*/ true, (sourceFile, changeTracker) => { - changeTracker.replaceNode(sourceFile, findVariableStatementContaining("y", sourceFile), createTestClass(), { trailingTriviaOption: textChanges.TrailingTriviaOption.Exclude, suffix: newLineCharacter }); + changeTracker.replaceNode(sourceFile, findVariableStatementContaining("y", sourceFile), createTestClass(), { trailingTriviaOption: ts.textChanges.TrailingTriviaOption.Exclude, suffix: newLineCharacter }); }); runSingleFileTest("replaceNode4", /*placeOpenBraceOnNewLineForFunctions*/ true, text, /*validateNodes*/ true, (sourceFile, changeTracker) => { - changeTracker.replaceNode(sourceFile, findVariableStatementContaining("y", sourceFile), createTestClass(), { leadingTriviaOption: textChanges.LeadingTriviaOption.Exclude, trailingTriviaOption: textChanges.TrailingTriviaOption.Exclude }); + changeTracker.replaceNode(sourceFile, findVariableStatementContaining("y", sourceFile), createTestClass(), { leadingTriviaOption: ts.textChanges.LeadingTriviaOption.Exclude, trailingTriviaOption: ts.textChanges.TrailingTriviaOption.Exclude }); }); runSingleFileTest("replaceNode5", /*placeOpenBraceOnNewLineForFunctions*/ true, text, /*validateNodes*/ true, (sourceFile, changeTracker) => { - changeTracker.replaceNode(sourceFile, findVariableStatementContaining("x", sourceFile), createTestClass(), { leadingTriviaOption: textChanges.LeadingTriviaOption.Exclude, trailingTriviaOption: textChanges.TrailingTriviaOption.Exclude }); + changeTracker.replaceNode(sourceFile, findVariableStatementContaining("x", sourceFile), createTestClass(), { leadingTriviaOption: ts.textChanges.LeadingTriviaOption.Exclude, trailingTriviaOption: ts.textChanges.TrailingTriviaOption.Exclude }); }); } { @@ -278,13 +258,13 @@ var a = 4; // comment 7`; changeTracker.replaceNodeRange(sourceFile, findVariableStatementContaining("y", sourceFile), findVariableStatementContaining("z", sourceFile), createTestClass(), { suffix: newLineCharacter }); }); runSingleFileTest("replaceNodeRange2", /*placeOpenBraceOnNewLineForFunctions*/ true, text, /*validateNodes*/ true, (sourceFile, changeTracker) => { - changeTracker.replaceNodeRange(sourceFile, findVariableStatementContaining("y", sourceFile), findVariableStatementContaining("z", sourceFile), createTestClass(), { leadingTriviaOption: textChanges.LeadingTriviaOption.Exclude, suffix: newLineCharacter, prefix: newLineCharacter }); + changeTracker.replaceNodeRange(sourceFile, findVariableStatementContaining("y", sourceFile), findVariableStatementContaining("z", sourceFile), createTestClass(), { leadingTriviaOption: ts.textChanges.LeadingTriviaOption.Exclude, suffix: newLineCharacter, prefix: newLineCharacter }); }); runSingleFileTest("replaceNodeRange3", /*placeOpenBraceOnNewLineForFunctions*/ true, text, /*validateNodes*/ true, (sourceFile, changeTracker) => { - changeTracker.replaceNodeRange(sourceFile, findVariableStatementContaining("y", sourceFile), findVariableStatementContaining("z", sourceFile), createTestClass(), { trailingTriviaOption: textChanges.TrailingTriviaOption.Exclude, suffix: newLineCharacter }); + changeTracker.replaceNodeRange(sourceFile, findVariableStatementContaining("y", sourceFile), findVariableStatementContaining("z", sourceFile), createTestClass(), { trailingTriviaOption: ts.textChanges.TrailingTriviaOption.Exclude, suffix: newLineCharacter }); }); runSingleFileTest("replaceNodeRange4", /*placeOpenBraceOnNewLineForFunctions*/ true, text, /*validateNodes*/ true, (sourceFile, changeTracker) => { - changeTracker.replaceNodeRange(sourceFile, findVariableStatementContaining("y", sourceFile), findVariableStatementContaining("z", sourceFile), createTestClass(), { leadingTriviaOption: textChanges.LeadingTriviaOption.Exclude, trailingTriviaOption: textChanges.TrailingTriviaOption.Exclude }); + changeTracker.replaceNodeRange(sourceFile, findVariableStatementContaining("y", sourceFile), findVariableStatementContaining("z", sourceFile), createTestClass(), { leadingTriviaOption: ts.textChanges.LeadingTriviaOption.Exclude, trailingTriviaOption: ts.textChanges.TrailingTriviaOption.Exclude }); }); } { @@ -328,17 +308,14 @@ namespace M { }); } - function findConstructor(sourceFile: SourceFile): ConstructorDeclaration { - const classDecl = sourceFile.statements[0] as ClassDeclaration; - return find(classDecl.members, (m): m is ConstructorDeclaration => isConstructorDeclaration(m) && !!m.body)!; + function findConstructor(sourceFile: ts.SourceFile): ts.ConstructorDeclaration { + const classDecl = sourceFile.statements[0] as ts.ClassDeclaration; + return ts.find(classDecl.members, (m): m is ts.ConstructorDeclaration => ts.isConstructorDeclaration(m) && !!m.body)!; } function createTestSuperCall() { - const superCall = factory.createCallExpression( - factory.createSuper(), - /*typeArguments*/ undefined, - /*argumentsArray*/ emptyArray - ); - return factory.createExpressionStatement(superCall); + const superCall = ts.factory.createCallExpression(ts.factory.createSuper(), + /*typeArguments*/ undefined, ts.emptyArray); + return ts.factory.createExpressionStatement(superCall); } { @@ -484,27 +461,27 @@ function foo( const text = ` const x = 1, y = 2;`; runSingleFileTest("insertNodeInListAfter1", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => { - changeTracker.insertNodeInListAfter(sourceFile, findChild("x", sourceFile), factory.createVariableDeclaration("z", /*exclamationToken*/ undefined, /*type*/ undefined, factory.createNumericLiteral(1))); + changeTracker.insertNodeInListAfter(sourceFile, findChild("x", sourceFile), ts.factory.createVariableDeclaration("z", /*exclamationToken*/ undefined, /*type*/ undefined, ts.factory.createNumericLiteral(1))); }); runSingleFileTest("insertNodeInListAfter2", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => { - changeTracker.insertNodeInListAfter(sourceFile, findChild("y", sourceFile), factory.createVariableDeclaration("z", /*exclamationToken*/ undefined, /*type*/ undefined, factory.createNumericLiteral(1))); + changeTracker.insertNodeInListAfter(sourceFile, findChild("y", sourceFile), ts.factory.createVariableDeclaration("z", /*exclamationToken*/ undefined, /*type*/ undefined, ts.factory.createNumericLiteral(1))); }); } { const text = ` const /*x*/ x = 1, /*y*/ y = 2;`; runSingleFileTest("insertNodeInListAfter3", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => { - changeTracker.insertNodeInListAfter(sourceFile, findChild("x", sourceFile), factory.createVariableDeclaration("z", /*exclamationToken*/ undefined, /*type*/ undefined, factory.createNumericLiteral(1))); + changeTracker.insertNodeInListAfter(sourceFile, findChild("x", sourceFile), ts.factory.createVariableDeclaration("z", /*exclamationToken*/ undefined, /*type*/ undefined, ts.factory.createNumericLiteral(1))); }); runSingleFileTest("insertNodeInListAfter4", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => { - changeTracker.insertNodeInListAfter(sourceFile, findChild("y", sourceFile), factory.createVariableDeclaration("z", /*exclamationToken*/ undefined, /*type*/ undefined, factory.createNumericLiteral(1))); + changeTracker.insertNodeInListAfter(sourceFile, findChild("y", sourceFile), ts.factory.createVariableDeclaration("z", /*exclamationToken*/ undefined, /*type*/ undefined, ts.factory.createNumericLiteral(1))); }); } { const text = ` const x = 1;`; runSingleFileTest("insertNodeInListAfter5", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => { - changeTracker.insertNodeInListAfter(sourceFile, findChild("x", sourceFile), factory.createVariableDeclaration("z", /*exclamationToken*/ undefined, /*type*/ undefined, factory.createNumericLiteral(1))); + changeTracker.insertNodeInListAfter(sourceFile, findChild("x", sourceFile), ts.factory.createVariableDeclaration("z", /*exclamationToken*/ undefined, /*type*/ undefined, ts.factory.createNumericLiteral(1))); }); } { @@ -512,10 +489,10 @@ const x = 1;`; const x = 1, y = 2;`; runSingleFileTest("insertNodeInListAfter6", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => { - changeTracker.insertNodeInListAfter(sourceFile, findChild("x", sourceFile), factory.createVariableDeclaration("z", /*exclamationToken*/ undefined, /*type*/ undefined, factory.createNumericLiteral(1))); + changeTracker.insertNodeInListAfter(sourceFile, findChild("x", sourceFile), ts.factory.createVariableDeclaration("z", /*exclamationToken*/ undefined, /*type*/ undefined, ts.factory.createNumericLiteral(1))); }); runSingleFileTest("insertNodeInListAfter7", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => { - changeTracker.insertNodeInListAfter(sourceFile, findChild("y", sourceFile), factory.createVariableDeclaration("z", /*exclamationToken*/ undefined, /*type*/ undefined, factory.createNumericLiteral(1))); + changeTracker.insertNodeInListAfter(sourceFile, findChild("y", sourceFile), ts.factory.createVariableDeclaration("z", /*exclamationToken*/ undefined, /*type*/ undefined, ts.factory.createNumericLiteral(1))); }); } { @@ -523,10 +500,10 @@ const x = 1, const /*x*/ x = 1, /*y*/ y = 2;`; runSingleFileTest("insertNodeInListAfter8", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => { - changeTracker.insertNodeInListAfter(sourceFile, findChild("x", sourceFile), factory.createVariableDeclaration("z", /*exclamationToken*/ undefined, /*type*/ undefined, factory.createNumericLiteral(1))); + changeTracker.insertNodeInListAfter(sourceFile, findChild("x", sourceFile), ts.factory.createVariableDeclaration("z", /*exclamationToken*/ undefined, /*type*/ undefined, ts.factory.createNumericLiteral(1))); }); runSingleFileTest("insertNodeInListAfter9", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => { - changeTracker.insertNodeInListAfter(sourceFile, findChild("y", sourceFile), factory.createVariableDeclaration("z", /*exclamationToken*/ undefined, /*type*/ undefined, factory.createNumericLiteral(1))); + changeTracker.insertNodeInListAfter(sourceFile, findChild("y", sourceFile), ts.factory.createVariableDeclaration("z", /*exclamationToken*/ undefined, /*type*/ undefined, ts.factory.createNumericLiteral(1))); }); } { @@ -535,7 +512,7 @@ import { x } from "bar"`; runSingleFileTest("insertNodeInListAfter10", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => { - changeTracker.insertNodeInListAfter(sourceFile, findChild("x", sourceFile), factory.createImportSpecifier(/*isTypeOnly*/ false, factory.createIdentifier("b"), factory.createIdentifier("a"))); + changeTracker.insertNodeInListAfter(sourceFile, findChild("x", sourceFile), ts.factory.createImportSpecifier(/*isTypeOnly*/ false, ts.factory.createIdentifier("b"), ts.factory.createIdentifier("a"))); }); } { @@ -544,7 +521,7 @@ import { x // this is x } from "bar"`; runSingleFileTest("insertNodeInListAfter11", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => { - changeTracker.insertNodeInListAfter(sourceFile, findChild("x", sourceFile), factory.createImportSpecifier(/*isTypeOnly*/ false, factory.createIdentifier("b"), factory.createIdentifier("a"))); + changeTracker.insertNodeInListAfter(sourceFile, findChild("x", sourceFile), ts.factory.createImportSpecifier(/*isTypeOnly*/ false, ts.factory.createIdentifier("b"), ts.factory.createIdentifier("a"))); }); } { @@ -554,7 +531,7 @@ import { } from "bar"`; runSingleFileTest("insertNodeInListAfter12", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => { // eslint-disable-next-line boolean-trivia - changeTracker.insertNodeInListAfter(sourceFile, findChild("x", sourceFile), factory.createImportSpecifier(/*isTypeOnly*/ false, undefined, factory.createIdentifier("a"))); + changeTracker.insertNodeInListAfter(sourceFile, findChild("x", sourceFile), ts.factory.createImportSpecifier(/*isTypeOnly*/ false, undefined, ts.factory.createIdentifier("a"))); }); } { @@ -564,7 +541,7 @@ import { } from "bar"`; runSingleFileTest("insertNodeInListAfter13", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => { // eslint-disable-next-line boolean-trivia - changeTracker.insertNodeInListAfter(sourceFile, findChild("x", sourceFile), factory.createImportSpecifier(/*isTypeOnly*/ false, undefined, factory.createIdentifier("a"))); + changeTracker.insertNodeInListAfter(sourceFile, findChild("x", sourceFile), ts.factory.createImportSpecifier(/*isTypeOnly*/ false, undefined, ts.factory.createIdentifier("a"))); }); } { @@ -574,7 +551,7 @@ import { x } from "bar"`; runSingleFileTest("insertNodeInListAfter14", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => { - changeTracker.insertNodeInListAfter(sourceFile, findChild("x", sourceFile), factory.createImportSpecifier(/*isTypeOnly*/ false, factory.createIdentifier("b"), factory.createIdentifier("a"))); + changeTracker.insertNodeInListAfter(sourceFile, findChild("x", sourceFile), ts.factory.createImportSpecifier(/*isTypeOnly*/ false, ts.factory.createIdentifier("b"), ts.factory.createIdentifier("a"))); }); } { @@ -584,7 +561,7 @@ import { x // this is x } from "bar"`; runSingleFileTest("insertNodeInListAfter15", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => { - changeTracker.insertNodeInListAfter(sourceFile, findChild("x", sourceFile), factory.createImportSpecifier(/*isTypeOnly*/ false, factory.createIdentifier("b"), factory.createIdentifier("a"))); + changeTracker.insertNodeInListAfter(sourceFile, findChild("x", sourceFile), ts.factory.createImportSpecifier(/*isTypeOnly*/ false, ts.factory.createIdentifier("b"), ts.factory.createIdentifier("a"))); }); } { @@ -595,7 +572,7 @@ import { } from "bar"`; runSingleFileTest("insertNodeInListAfter16", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => { // eslint-disable-next-line boolean-trivia - changeTracker.insertNodeInListAfter(sourceFile, findChild("x", sourceFile), factory.createImportSpecifier(/*isTypeOnly*/ false, undefined, factory.createIdentifier("a"))); + changeTracker.insertNodeInListAfter(sourceFile, findChild("x", sourceFile), ts.factory.createImportSpecifier(/*isTypeOnly*/ false, undefined, ts.factory.createIdentifier("a"))); }); } { @@ -606,7 +583,7 @@ import { } from "bar"`; runSingleFileTest("insertNodeInListAfter17", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => { // eslint-disable-next-line boolean-trivia - changeTracker.insertNodeInListAfter(sourceFile, findChild("x", sourceFile), factory.createImportSpecifier(/*isTypeOnly*/ false, undefined, factory.createIdentifier("a"))); + changeTracker.insertNodeInListAfter(sourceFile, findChild("x", sourceFile), ts.factory.createImportSpecifier(/*isTypeOnly*/ false, undefined, ts.factory.createIdentifier("a"))); }); } { @@ -616,14 +593,14 @@ import { } from "bar"`; runSingleFileTest("insertNodeInListAfter18", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => { // eslint-disable-next-line boolean-trivia - changeTracker.insertNodeInListAfter(sourceFile, findChild("x", sourceFile), factory.createImportSpecifier(/*isTypeOnly*/ false, undefined, factory.createIdentifier("a"))); + changeTracker.insertNodeInListAfter(sourceFile, findChild("x", sourceFile), ts.factory.createImportSpecifier(/*isTypeOnly*/ false, undefined, ts.factory.createIdentifier("a"))); }); } { const runTest = (name: string, text: string) => runSingleFileTest(name, /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => { for (const specifier of ["x3", "x4", "x5"]) { // eslint-disable-next-line boolean-trivia - changeTracker.insertNodeInListAfter(sourceFile, findChild("x2", sourceFile), factory.createImportSpecifier(/*isTypeOnly*/ false, undefined, factory.createIdentifier(specifier))); + changeTracker.insertNodeInListAfter(sourceFile, findChild("x2", sourceFile), ts.factory.createImportSpecifier(/*isTypeOnly*/ false, undefined, ts.factory.createIdentifier(specifier))); } }); @@ -643,7 +620,7 @@ class A { for (let i = 0; i < 11 /*error doesn't occur with fewer nodes*/; ++i) { newNodes.push( // eslint-disable-next-line boolean-trivia - factory.createPropertyDeclaration(undefined, undefined, i + "", undefined, undefined, undefined)); + ts.factory.createPropertyDeclaration(undefined, undefined, i + "", undefined, undefined, undefined)); } const insertAfter = findChild("x", sourceFile); for (const newNode of newNodes) { @@ -659,7 +636,7 @@ class A { `; runSingleFileTest("insertNodeAfterInClass1", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => { // eslint-disable-next-line boolean-trivia - changeTracker.insertNodeAfter(sourceFile, findChild("x", sourceFile), factory.createPropertyDeclaration(undefined, undefined, "a", undefined, factory.createKeywordTypeNode(SyntaxKind.BooleanKeyword), undefined)); + changeTracker.insertNodeAfter(sourceFile, findChild("x", sourceFile), ts.factory.createPropertyDeclaration(undefined, undefined, "a", undefined, ts.factory.createKeywordTypeNode(ts.SyntaxKind.BooleanKeyword), undefined)); }); } { @@ -670,7 +647,7 @@ class A { `; runSingleFileTest("insertNodeAfterInClass2", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => { // eslint-disable-next-line boolean-trivia - changeTracker.insertNodeAfter(sourceFile, findChild("x", sourceFile), factory.createPropertyDeclaration(undefined, undefined, "a", undefined, factory.createKeywordTypeNode(SyntaxKind.BooleanKeyword), undefined)); + changeTracker.insertNodeAfter(sourceFile, findChild("x", sourceFile), ts.factory.createPropertyDeclaration(undefined, undefined, "a", undefined, ts.factory.createKeywordTypeNode(ts.SyntaxKind.BooleanKeyword), undefined)); }); } { @@ -702,12 +679,10 @@ class A { } `; runSingleFileTest("insertNodeInClassAfterNodeWithoutSeparator1", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => { - const newNode = factory.createPropertyDeclaration( + const newNode = ts.factory.createPropertyDeclaration( /*decorators*/ undefined, - /*modifiers*/ undefined, - factory.createComputedPropertyName(factory.createNumericLiteral(1)), - /*questionToken*/ undefined, - factory.createKeywordTypeNode(SyntaxKind.AnyKeyword), + /*modifiers*/ undefined, ts.factory.createComputedPropertyName(ts.factory.createNumericLiteral(1)), + /*questionToken*/ undefined, ts.factory.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword), /*initializer*/ undefined); changeTracker.insertNodeAfter(sourceFile, findChild("x", sourceFile), newNode); }); @@ -720,12 +695,10 @@ class A { } `; runSingleFileTest("insertNodeInClassAfterNodeWithoutSeparator2", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => { - const newNode = factory.createPropertyDeclaration( + const newNode = ts.factory.createPropertyDeclaration( /*decorators*/ undefined, - /*modifiers*/ undefined, - factory.createComputedPropertyName(factory.createNumericLiteral(1)), - /*questionToken*/ undefined, - factory.createKeywordTypeNode(SyntaxKind.AnyKeyword), + /*modifiers*/ undefined, ts.factory.createComputedPropertyName(ts.factory.createNumericLiteral(1)), + /*questionToken*/ undefined, ts.factory.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword), /*initializer*/ undefined); changeTracker.insertNodeAfter(sourceFile, findChild("x", sourceFile), newNode); }); @@ -737,12 +710,10 @@ interface A { } `; runSingleFileTest("insertNodeInInterfaceAfterNodeWithoutSeparator1", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => { - const newNode = factory.createPropertyDeclaration( + const newNode = ts.factory.createPropertyDeclaration( /*decorators*/ undefined, - /*modifiers*/ undefined, - factory.createComputedPropertyName(factory.createNumericLiteral(1)), - /*questionToken*/ undefined, - factory.createKeywordTypeNode(SyntaxKind.AnyKeyword), + /*modifiers*/ undefined, ts.factory.createComputedPropertyName(ts.factory.createNumericLiteral(1)), + /*questionToken*/ undefined, ts.factory.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword), /*initializer*/ undefined); changeTracker.insertNodeAfter(sourceFile, findChild("x", sourceFile), newNode); }); @@ -754,12 +725,10 @@ interface A { } `; runSingleFileTest("insertNodeInInterfaceAfterNodeWithoutSeparator2", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => { - const newNode = factory.createPropertyDeclaration( + const newNode = ts.factory.createPropertyDeclaration( /*decorators*/ undefined, - /*modifiers*/ undefined, - factory.createComputedPropertyName(factory.createNumericLiteral(1)), - /*questionToken*/ undefined, - factory.createKeywordTypeNode(SyntaxKind.AnyKeyword), + /*modifiers*/ undefined, ts.factory.createComputedPropertyName(ts.factory.createNumericLiteral(1)), + /*questionToken*/ undefined, ts.factory.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword), /*initializer*/ undefined); changeTracker.insertNodeAfter(sourceFile, findChild("x", sourceFile), newNode); }); @@ -769,7 +738,7 @@ interface A { let x = foo `; runSingleFileTest("insertNodeInStatementListAfterNodeWithoutSeparator1", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => { - const newNode = factory.createExpressionStatement(factory.createParenthesizedExpression(factory.createNumericLiteral(1))); + const newNode = ts.factory.createExpressionStatement(ts.factory.createParenthesizedExpression(ts.factory.createNumericLiteral(1))); changeTracker.insertNodeAfter(sourceFile, findVariableStatementContaining("x", sourceFile), newNode); }); } diff --git a/src/testRunner/unittests/services/transpile.ts b/src/testRunner/unittests/services/transpile.ts index 2e0c8ea24547a..df8c89edc4ba7 100644 --- a/src/testRunner/unittests/services/transpile.ts +++ b/src/testRunner/unittests/services/transpile.ts @@ -2,27 +2,26 @@ namespace ts { describe("unittests:: services:: Transpile", () => { interface TranspileTestSettings { - options?: TranspileOptions; + options?: ts.TranspileOptions; noSetFileName?: boolean; } function transpilesCorrectly(name: string, input: string, testSettings: TranspileTestSettings) { describe(name, () => { - let transpileResult: TranspileOutput; + let transpileResult: ts.TranspileOutput; let oldTranspileResult: string; - let oldTranspileDiagnostics: Diagnostic[]; - - const transpileOptions: TranspileOptions = testSettings.options || {}; + let oldTranspileDiagnostics: ts.Diagnostic[]; + const transpileOptions: ts.TranspileOptions = testSettings.options || {}; if (!transpileOptions.compilerOptions) { transpileOptions.compilerOptions = { }; } if (transpileOptions.compilerOptions.target === undefined) { - transpileOptions.compilerOptions.target = ScriptTarget.ES3; + transpileOptions.compilerOptions.target = ts.ScriptTarget.ES3; } if (transpileOptions.compilerOptions.newLine === undefined) { // use \r\n as default new line - transpileOptions.compilerOptions.newLine = NewLineKind.CarriageReturnLineFeed; + transpileOptions.compilerOptions.newLine = ts.NewLineKind.CarriageReturnLineFeed; } transpileOptions.compilerOptions.sourceMap = true; @@ -37,7 +36,7 @@ namespace ts { transpileOptions.reportDiagnostics = true; - const justName = "transpile/" + name.replace(/[^a-z0-9\-. ]/ig, "") + (transpileOptions.compilerOptions.jsx ? Extension.Tsx : Extension.Ts); + const justName = "transpile/" + name.replace(/[^a-z0-9\-. ]/ig, "") + (transpileOptions.compilerOptions.jsx ? ts.Extension.Tsx : ts.Extension.Ts); const toBeCompiled = [{ unitName, content: input @@ -45,11 +44,11 @@ namespace ts { const canUseOldTranspile = !transpileOptions.renamedDependencies; before(() => { - transpileResult = transpileModule(input, transpileOptions); + transpileResult = ts.transpileModule(input, transpileOptions); if (canUseOldTranspile) { oldTranspileDiagnostics = []; - oldTranspileResult = transpile(input, transpileOptions.compilerOptions, transpileOptions.fileName, oldTranspileDiagnostics, transpileOptions.moduleName); + oldTranspileResult = ts.transpile(input, transpileOptions.compilerOptions, transpileOptions.fileName, oldTranspileDiagnostics, transpileOptions.moduleName); } }); @@ -61,20 +60,18 @@ namespace ts { /* eslint-disable no-null/no-null */ it("Correct errors for " + justName, () => { - Harness.Baseline.runBaseline(justName.replace(/\.tsx?$/, ".errors.txt"), - transpileResult.diagnostics!.length === 0 ? null : Harness.Compiler.getErrorBaseline(toBeCompiled, transpileResult.diagnostics!)); + Harness.Baseline.runBaseline(justName.replace(/\.tsx?$/, ".errors.txt"), transpileResult.diagnostics!.length === 0 ? null : Harness.Compiler.getErrorBaseline(toBeCompiled, transpileResult.diagnostics!)); }); if (canUseOldTranspile) { it("Correct errors (old transpile) for " + justName, () => { - Harness.Baseline.runBaseline(justName.replace(/\.tsx?$/, ".oldTranspile.errors.txt"), - oldTranspileDiagnostics.length === 0 ? null : Harness.Compiler.getErrorBaseline(toBeCompiled, oldTranspileDiagnostics)); + Harness.Baseline.runBaseline(justName.replace(/\.tsx?$/, ".oldTranspile.errors.txt"), oldTranspileDiagnostics.length === 0 ? null : Harness.Compiler.getErrorBaseline(toBeCompiled, oldTranspileDiagnostics)); }); } /* eslint-enable no-null/no-null */ it("Correct output for " + justName, () => { - Harness.Baseline.runBaseline(justName.replace(/\.tsx?$/, Extension.Js), transpileResult.outputText); + Harness.Baseline.runBaseline(justName.replace(/\.tsx?$/, ts.Extension.Js), transpileResult.outputText); }); if (canUseOldTranspile) { @@ -86,65 +83,61 @@ namespace ts { } transpilesCorrectly("Generates no diagnostics with valid inputs", `var x = 0;`, { - options: { compilerOptions: { module: ModuleKind.CommonJS } } + options: { compilerOptions: { module: ts.ModuleKind.CommonJS } } }); transpilesCorrectly("Generates no diagnostics for missing file references", `/// var x = 0;`, { - options: { compilerOptions: { module: ModuleKind.CommonJS } } + options: { compilerOptions: { module: ts.ModuleKind.CommonJS } } }); transpilesCorrectly("Generates no diagnostics for missing module imports", `import {a} from "module2";`, { - options: { compilerOptions: { module: ModuleKind.CommonJS } } + options: { compilerOptions: { module: ts.ModuleKind.CommonJS } } }); transpilesCorrectly("Generates expected syntactic diagnostics", `a b`, { - options: { compilerOptions: { module: ModuleKind.CommonJS } } + options: { compilerOptions: { module: ts.ModuleKind.CommonJS } } }); transpilesCorrectly("Does not generate semantic diagnostics", `var x: string = 0;`, { - options: { compilerOptions: { module: ModuleKind.CommonJS } } + options: { compilerOptions: { module: ts.ModuleKind.CommonJS } } }); transpilesCorrectly("Generates module output", `var x = 0;`, { - options: { compilerOptions: { module: ModuleKind.AMD } } + options: { compilerOptions: { module: ts.ModuleKind.AMD } } }); transpilesCorrectly("Uses correct newLine character", `var x = 0;`, { - options: { compilerOptions: { module: ModuleKind.CommonJS, newLine: NewLineKind.LineFeed } } + options: { compilerOptions: { module: ts.ModuleKind.CommonJS, newLine: ts.NewLineKind.LineFeed } } }); transpilesCorrectly("Sets module name", "var x = 1;", { - options: { compilerOptions: { module: ModuleKind.System, newLine: NewLineKind.LineFeed }, moduleName: "NamedModule" } + options: { compilerOptions: { module: ts.ModuleKind.System, newLine: ts.NewLineKind.LineFeed }, moduleName: "NamedModule" } }); transpilesCorrectly("No extra errors for file without extension", `"use strict";\r\nvar x = 0;`, { - options: { compilerOptions: { module: ModuleKind.CommonJS }, fileName: "file" } + options: { compilerOptions: { module: ts.ModuleKind.CommonJS }, fileName: "file" } }); - transpilesCorrectly("Rename dependencies - System", - `import {foo} from "SomeName";\n` + + transpilesCorrectly("Rename dependencies - System", `import {foo} from "SomeName";\n` + `declare function use(a: any);\n` + `use(foo);`, { - options: { compilerOptions: { module: ModuleKind.System, newLine: NewLineKind.LineFeed }, renamedDependencies: { SomeName: "SomeOtherName" } } + options: { compilerOptions: { module: ts.ModuleKind.System, newLine: ts.NewLineKind.LineFeed }, renamedDependencies: { SomeName: "SomeOtherName" } } }); - transpilesCorrectly("Rename dependencies - AMD", - `import {foo} from "SomeName";\n` + + transpilesCorrectly("Rename dependencies - AMD", `import {foo} from "SomeName";\n` + `declare function use(a: any);\n` + `use(foo);`, { - options: { compilerOptions: { module: ModuleKind.AMD, newLine: NewLineKind.LineFeed }, renamedDependencies: { SomeName: "SomeOtherName" } } + options: { compilerOptions: { module: ts.ModuleKind.AMD, newLine: ts.NewLineKind.LineFeed }, renamedDependencies: { SomeName: "SomeOtherName" } } }); - transpilesCorrectly("Rename dependencies - UMD", - `import {foo} from "SomeName";\n` + + transpilesCorrectly("Rename dependencies - UMD", `import {foo} from "SomeName";\n` + `declare function use(a: any);\n` + `use(foo);`, { - options: { compilerOptions: { module: ModuleKind.UMD, newLine: NewLineKind.LineFeed }, renamedDependencies: { SomeName: "SomeOtherName" } } + options: { compilerOptions: { module: ts.ModuleKind.UMD, newLine: ts.NewLineKind.LineFeed }, renamedDependencies: { SomeName: "SomeOtherName" } } }); - transpilesCorrectly("Transpile with emit decorators and emit metadata", - `import {db} from './db';\n` + + transpilesCorrectly("Transpile with emit decorators and emit metadata", `import {db} from './db';\n` + `function someDecorator(target) {\n` + ` return target;\n` + `} \n` + @@ -159,12 +152,12 @@ var x = 0;`, { `export {MyClass}; \n`, { options: { compilerOptions: { - module: ModuleKind.CommonJS, - newLine: NewLineKind.LineFeed, + module: ts.ModuleKind.CommonJS, + newLine: ts.NewLineKind.LineFeed, noEmitHelpers: true, emitDecoratorMetadata: true, experimentalDecorators: true, - target: ScriptTarget.ES5, + target: ts.ScriptTarget.ES5, } } }); @@ -174,11 +167,11 @@ var x = 0;`, { }); transpilesCorrectly("transpile file as 'tsx' if 'jsx' is specified", `var x =
`, { - options: { compilerOptions: { jsx: JsxEmit.React, newLine: NewLineKind.LineFeed } } + options: { compilerOptions: { jsx: ts.JsxEmit.React, newLine: ts.NewLineKind.LineFeed } } }); transpilesCorrectly("transpile .js files", "const a = 10;", { - options: { compilerOptions: { newLine: NewLineKind.LineFeed, module: ModuleKind.CommonJS }, fileName: "input.js", reportDiagnostics: true } + options: { compilerOptions: { newLine: ts.NewLineKind.LineFeed, module: ts.ModuleKind.CommonJS }, fileName: "input.js", reportDiagnostics: true } }); transpilesCorrectly("Supports urls in file name", "var x", { @@ -188,27 +181,27 @@ var x = 0;`, { transpilesCorrectly("Accepts string as enum values for compile-options", "export const x = 0", { options: { compilerOptions: { - module: "es6" as any as ModuleKind, + module: "es6" as any as ts.ModuleKind, // Capitalization and spaces ignored - target: " Es6 " as any as ScriptTarget + target: " Es6 " as any as ts.ScriptTarget } } }); transpilesCorrectly("Report an error when compiler-options module-kind is out-of-range", "", { - options: { compilerOptions: { module: 123 as any as ModuleKind } } + options: { compilerOptions: { module: 123 as any as ts.ModuleKind } } }); transpilesCorrectly("Report an error when compiler-options target-script is out-of-range", "", { - options: { compilerOptions: { module: 123 as any as ModuleKind } } + options: { compilerOptions: { module: 123 as any as ts.ModuleKind } } }); transpilesCorrectly("Support options with lib values", "const a = 10;", { - options: { compilerOptions: { lib: ["es6", "dom"], module: ModuleKind.CommonJS }, fileName: "input.js", reportDiagnostics: true } + options: { compilerOptions: { lib: ["es6", "dom"], module: ts.ModuleKind.CommonJS }, fileName: "input.js", reportDiagnostics: true } }); transpilesCorrectly("Support options with types values", "const a = 10;", { - options: { compilerOptions: { types: ["jquery", "typescript"], module: ModuleKind.CommonJS }, fileName: "input.js", reportDiagnostics: true } + options: { compilerOptions: { types: ["jquery", "typescript"], module: ts.ModuleKind.CommonJS }, fileName: "input.js", reportDiagnostics: true } }); transpilesCorrectly("Supports setting 'allowJs'", "x;", { @@ -280,15 +273,15 @@ var x = 0;`, { }); transpilesCorrectly("Supports setting 'module'", "x;", { - options: { compilerOptions: { module: ModuleKind.CommonJS }, fileName: "input.js", reportDiagnostics: true } + options: { compilerOptions: { module: ts.ModuleKind.CommonJS }, fileName: "input.js", reportDiagnostics: true } }); transpilesCorrectly("Supports setting 'moduleResolution'", "x;", { - options: { compilerOptions: { moduleResolution: ModuleResolutionKind.NodeJs }, fileName: "input.js", reportDiagnostics: true } + options: { compilerOptions: { moduleResolution: ts.ModuleResolutionKind.NodeJs }, fileName: "input.js", reportDiagnostics: true } }); transpilesCorrectly("Supports setting 'newLine'", "x;", { - options: { compilerOptions: { newLine: NewLineKind.CarriageReturnLineFeed }, fileName: "input.js", reportDiagnostics: true } + options: { compilerOptions: { newLine: ts.NewLineKind.CarriageReturnLineFeed }, fileName: "input.js", reportDiagnostics: true } }); transpilesCorrectly("Supports setting 'noEmit'", "x;", { @@ -427,8 +420,7 @@ var x = 0;`, { options: { compilerOptions: { incremental: true, tsBuildInfoFile: "./folder/config.tsbuildinfo" }, fileName: "input.js", reportDiagnostics: true } }); - transpilesCorrectly("Correctly serialize metadata when transpile with CommonJS option", - `import * as ng from "angular2/core";` + + transpilesCorrectly("Correctly serialize metadata when transpile with CommonJS option", `import * as ng from "angular2/core";` + `declare function foo(...args: any[]);` + `@foo` + `export class MyClass1 {` + @@ -436,19 +428,16 @@ var x = 0;`, { `}`, { options: { compilerOptions: { - target: ScriptTarget.ES5, - module: ModuleKind.CommonJS, - moduleResolution: ModuleResolutionKind.NodeJs, + target: ts.ScriptTarget.ES5, + module: ts.ModuleKind.CommonJS, + moduleResolution: ts.ModuleResolutionKind.NodeJs, emitDecoratorMetadata: true, experimentalDecorators: true, isolatedModules: true, } } - } - ); - - transpilesCorrectly("Correctly serialize metadata when transpile with System option", - `import * as ng from "angular2/core";` + + }); + transpilesCorrectly("Correctly serialize metadata when transpile with System option", `import * as ng from "angular2/core";` + `declare function foo(...args: any[]);` + `@foo` + `export class MyClass1 {` + @@ -456,23 +445,22 @@ var x = 0;`, { `}`, { options: { compilerOptions: { - target: ScriptTarget.ES5, - module: ModuleKind.System, - moduleResolution: ModuleResolutionKind.NodeJs, + target: ts.ScriptTarget.ES5, + module: ts.ModuleKind.System, + moduleResolution: ts.ModuleResolutionKind.NodeJs, emitDecoratorMetadata: true, experimentalDecorators: true, isolatedModules: true, } } - } - ); + }); transpilesCorrectly("Supports readonly keyword for arrays", "let x: readonly string[];", { - options: { compilerOptions: { module: ModuleKind.CommonJS } } + options: { compilerOptions: { module: ts.ModuleKind.CommonJS } } }); transpilesCorrectly("Supports 'as const' arrays", `([] as const).forEach(k => console.log(k));`, { - options: { compilerOptions: { module: ModuleKind.CommonJS } } + options: { compilerOptions: { module: ts.ModuleKind.CommonJS } } }); transpilesCorrectly("Infer correct file extension", `const fn = (a: T) => a`, { diff --git a/src/testRunner/unittests/transform.ts b/src/testRunner/unittests/transform.ts index 256a1db2e303e..ecd6a2f3d8ed5 100644 --- a/src/testRunner/unittests/transform.ts +++ b/src/testRunner/unittests/transform.ts @@ -1,72 +1,63 @@ namespace ts { describe("unittests:: TransformAPI", () => { - function replaceUndefinedWithVoid0(context: TransformationContext) { + function replaceUndefinedWithVoid0(context: ts.TransformationContext) { const previousOnSubstituteNode = context.onSubstituteNode; - context.enableSubstitution(SyntaxKind.Identifier); + context.enableSubstitution(ts.SyntaxKind.Identifier); context.onSubstituteNode = (hint, node) => { node = previousOnSubstituteNode(hint, node); - if (hint === EmitHint.Expression && isIdentifier(node) && node.escapedText === "undefined") { - node = factory.createPartiallyEmittedExpression( - addSyntheticTrailingComment( - setTextRange( - factory.createVoidZero(), - node), - SyntaxKind.MultiLineCommentTrivia, "undefined")); + if (hint === ts.EmitHint.Expression && ts.isIdentifier(node) && node.escapedText === "undefined") { + node = ts.factory.createPartiallyEmittedExpression(ts.addSyntheticTrailingComment(ts.setTextRange(ts.factory.createVoidZero(), node), ts.SyntaxKind.MultiLineCommentTrivia, "undefined")); } return node; }; - return (file: SourceFile) => file; + return (file: ts.SourceFile) => file; } - function replaceNumberWith2(context: TransformationContext) { - function visitor(node: Node): Node { - if (isNumericLiteral(node)) { - return factory.createNumericLiteral("2"); + function replaceNumberWith2(context: ts.TransformationContext) { + function visitor(node: ts.Node): ts.Node { + if (ts.isNumericLiteral(node)) { + return ts.factory.createNumericLiteral("2"); } - return visitEachChild(node, visitor, context); + return ts.visitEachChild(node, visitor, context); } - return (file: SourceFile) => visitNode(file, visitor); + return (file: ts.SourceFile) => ts.visitNode(file, visitor); } - function replaceIdentifiersNamedOldNameWithNewName(context: TransformationContext) { + function replaceIdentifiersNamedOldNameWithNewName(context: ts.TransformationContext) { const previousOnSubstituteNode = context.onSubstituteNode; - context.enableSubstitution(SyntaxKind.Identifier); + context.enableSubstitution(ts.SyntaxKind.Identifier); context.onSubstituteNode = (hint, node) => { node = previousOnSubstituteNode(hint, node); - if (isIdentifier(node) && node.escapedText === "oldName") { - node = setTextRange(factory.createIdentifier("newName"), node); + if (ts.isIdentifier(node) && node.escapedText === "oldName") { + node = ts.setTextRange(ts.factory.createIdentifier("newName"), node); } return node; }; - return (file: SourceFile) => file; + return (file: ts.SourceFile) => file; } - function replaceIdentifiersNamedOldNameWithNewName2(context: TransformationContext) { - const visitor: Visitor = (node) => { - if (isIdentifier(node) && node.text === "oldName") { - return factory.createIdentifier("newName"); + function replaceIdentifiersNamedOldNameWithNewName2(context: ts.TransformationContext) { + const visitor: ts.Visitor = (node) => { + if (ts.isIdentifier(node) && node.text === "oldName") { + return ts.factory.createIdentifier("newName"); } - return visitEachChild(node, visitor, context); + return ts.visitEachChild(node, visitor, context); }; - return (node: SourceFile) => visitNode(node, visitor); + return (node: ts.SourceFile) => ts.visitNode(node, visitor); } - - function createTaggedTemplateLiteral(): Transformer { - return sourceFile => factory.updateSourceFile(sourceFile, [ - factory.createExpressionStatement( - factory.createTaggedTemplateExpression( - factory.createIdentifier("$tpl"), - /*typeArguments*/ undefined, - factory.createNoSubstitutionTemplateLiteral("foo", "foo"))) + function createTaggedTemplateLiteral(): ts.Transformer { + return sourceFile => ts.factory.updateSourceFile(sourceFile, [ + ts.factory.createExpressionStatement(ts.factory.createTaggedTemplateExpression(ts.factory.createIdentifier("$tpl"), + /*typeArguments*/ undefined, ts.factory.createNoSubstitutionTemplateLiteral("foo", "foo"))) ]); } - function transformSourceFile(sourceText: string, transformers: TransformerFactory[]) { - const transformed = transform(createSourceFile("source.ts", sourceText, ScriptTarget.ES2015), transformers); - const printer = createPrinter({ newLine: NewLineKind.CarriageReturnLineFeed }, { + function transformSourceFile(sourceText: string, transformers: ts.TransformerFactory[]) { + const transformed = ts.transform(ts.createSourceFile("source.ts", sourceText, ts.ScriptTarget.ES2015), transformers); + const printer = ts.createPrinter({ newLine: ts.NewLineKind.CarriageReturnLineFeed }, { onEmitNode: transformed.emitNodeWithNotification, substituteNode: transformed.substituteNode }); - const result = printer.printBundle(factory.createBundle(transformed.transformed)); + const result = printer.printBundle(ts.factory.createBundle(transformed.transformed)); transformed.dispose(); return result; } @@ -101,55 +92,55 @@ namespace ts { testBaseline("types", () => { return transformSourceFile(`let a: () => void`, [ - context => file => visitNode(file, function visitor(node: Node): VisitResult { - return visitEachChild(node, visitor, context); + context => file => ts.visitNode(file, function visitor(node: ts.Node): ts.VisitResult { + return ts.visitEachChild(node, visitor, context); }) ]); }); testBaseline("transformDefiniteAssignmentAssertions", () => { return transformSourceFile(`let a!: () => void`, [ - context => file => visitNode(file, function visitor(node: Node): VisitResult { - if (node.kind === SyntaxKind.VoidKeyword) { - return factory.createKeywordTypeNode(SyntaxKind.UndefinedKeyword); + context => file => ts.visitNode(file, function visitor(node: ts.Node): ts.VisitResult { + if (node.kind === ts.SyntaxKind.VoidKeyword) { + return ts.factory.createKeywordTypeNode(ts.SyntaxKind.UndefinedKeyword); } - return visitEachChild(node, visitor, context); + return ts.visitEachChild(node, visitor, context); }) ]); }); testBaseline("fromTranspileModule", () => { - return transpileModule(`var oldName = undefined;`, { + return ts.transpileModule(`var oldName = undefined;`, { transformers: { before: [replaceUndefinedWithVoid0], after: [replaceIdentifiersNamedOldNameWithNewName] }, compilerOptions: { - newLine: NewLineKind.CarriageReturnLineFeed + newLine: ts.NewLineKind.CarriageReturnLineFeed } }).outputText; }); testBaseline("transformTaggedTemplateLiteral", () => { - return transpileModule("", { + return ts.transpileModule("", { transformers: { before: [createTaggedTemplateLiteral], }, compilerOptions: { - target: ScriptTarget.ES5, - newLine: NewLineKind.CarriageReturnLineFeed + target: ts.ScriptTarget.ES5, + newLine: ts.NewLineKind.CarriageReturnLineFeed } }).outputText; }); testBaseline("issue27854", () => { - return transpileModule(`oldName<{ a: string; }>\` ... \`;`, { + return ts.transpileModule(`oldName<{ a: string; }>\` ... \`;`, { transformers: { before: [replaceIdentifiersNamedOldNameWithNewName2] }, compilerOptions: { - newLine: NewLineKind.CarriageReturnLineFeed, - target: ScriptTarget.Latest + newLine: ts.NewLineKind.CarriageReturnLineFeed, + target: ts.ScriptTarget.Latest } }).outputText; }); @@ -160,33 +151,31 @@ namespace ts { const SecondVar = null; `, [ context => file => { - const firstVarName = (file.statements[0] as VariableStatement) - .declarationList.declarations[0].name as Identifier; - const secondVarName = (file.statements[0] as VariableStatement) - .declarationList.declarations[0].name as Identifier; + const firstVarName = (file.statements[0] as ts.VariableStatement) + .declarationList.declarations[0].name as ts.Identifier; + const secondVarName = (file.statements[0] as ts.VariableStatement) + .declarationList.declarations[0].name as ts.Identifier; return context.factory.updateSourceFile(file, file.statements.concat([ - context.factory.createExpressionStatement( - context.factory.createArrayLiteralExpression([firstVarName, secondVarName]) - ), + context.factory.createExpressionStatement(context.factory.createArrayLiteralExpression([firstVarName, secondVarName])), ])); } ]); }); testBaseline("rewrittenNamespace", () => { - return transpileModule(`namespace Reflect { const x = 1; }`, { + return ts.transpileModule(`namespace Reflect { const x = 1; }`, { transformers: { before: [forceNamespaceRewrite], }, compilerOptions: { - newLine: NewLineKind.CarriageReturnLineFeed, + newLine: ts.NewLineKind.CarriageReturnLineFeed, } }).outputText; }); testBaseline("rewrittenNamespaceFollowingClass", () => { - return transpileModule(` + return ts.transpileModule(` class C { foo = 10; static bar = 20 } namespace C { export let x = 10; } `, { @@ -194,94 +183,90 @@ namespace ts { before: [forceNamespaceRewrite], }, compilerOptions: { - target: ScriptTarget.ESNext, - newLine: NewLineKind.CarriageReturnLineFeed, + target: ts.ScriptTarget.ESNext, + newLine: ts.NewLineKind.CarriageReturnLineFeed, useDefineForClassFields: false, } }).outputText; }); testBaseline("transformTypesInExportDefault", () => { - return transpileModule(` + return ts.transpileModule(` export default (foo: string) => { return 1; } `, { transformers: { before: [replaceNumberWith2], }, compilerOptions: { - target: ScriptTarget.ESNext, - newLine: NewLineKind.CarriageReturnLineFeed, + target: ts.ScriptTarget.ESNext, + newLine: ts.NewLineKind.CarriageReturnLineFeed, } }).outputText; }); testBaseline("synthesizedClassAndNamespaceCombination", () => { - return transpileModule("", { + return ts.transpileModule("", { transformers: { before: [replaceWithClassAndNamespace], }, compilerOptions: { - target: ScriptTarget.ESNext, - newLine: NewLineKind.CarriageReturnLineFeed, + target: ts.ScriptTarget.ESNext, + newLine: ts.NewLineKind.CarriageReturnLineFeed, } }).outputText; function replaceWithClassAndNamespace() { - return (sourceFile: SourceFile) => { + return (sourceFile: ts.SourceFile) => { // TODO(rbuckton): Does this need to be parented? - const result = factory.updateSourceFile( - sourceFile, - factory.createNodeArray([ - factory.createClassDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, "Foo", /*typeParameters*/ undefined, /*heritageClauses*/ undefined, /*members*/ undefined!), // TODO: GH#18217 - factory.createModuleDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, factory.createIdentifier("Foo"), factory.createModuleBlock([factory.createEmptyStatement()])) - ]) - ); + const result = ts.factory.updateSourceFile(sourceFile, ts.factory.createNodeArray([ + ts.factory.createClassDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, "Foo", /*typeParameters*/ undefined, /*heritageClauses*/ undefined, /*members*/ undefined!), + ts.factory.createModuleDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, ts.factory.createIdentifier("Foo"), ts.factory.createModuleBlock([ts.factory.createEmptyStatement()])) + ])); return result; }; } }); - function forceNamespaceRewrite(context: TransformationContext) { - return (sourceFile: SourceFile): SourceFile => { + function forceNamespaceRewrite(context: ts.TransformationContext) { + return (sourceFile: ts.SourceFile): ts.SourceFile => { return visitNode(sourceFile); - function visitNode(node: T): T { - if (node.kind === SyntaxKind.ModuleBlock) { - const block = node as T & ModuleBlock; - const statements = factory.createNodeArray([...block.statements]); - return factory.updateModuleBlock(block, statements) as typeof block; + function visitNode(node: T): T { + if (node.kind === ts.SyntaxKind.ModuleBlock) { + const block = node as T & ts.ModuleBlock; + const statements = ts.factory.createNodeArray([...block.statements]); + return ts.factory.updateModuleBlock(block, statements) as typeof block; } - return visitEachChild(node, visitNode, context); + return ts.visitEachChild(node, visitNode, context); } }; } testBaseline("transformAwayExportStar", () => { - return transpileModule("export * from './helper';", { + return ts.transpileModule("export * from './helper';", { transformers: { before: [expandExportStar], }, compilerOptions: { - target: ScriptTarget.ESNext, - newLine: NewLineKind.CarriageReturnLineFeed, + target: ts.ScriptTarget.ESNext, + newLine: ts.NewLineKind.CarriageReturnLineFeed, } }).outputText; - function expandExportStar(context: TransformationContext) { - return (sourceFile: SourceFile): SourceFile => { + function expandExportStar(context: ts.TransformationContext) { + return (sourceFile: ts.SourceFile): ts.SourceFile => { return visitNode(sourceFile); - function visitNode(node: T): T { - if (node.kind === SyntaxKind.ExportDeclaration) { - const ed = node as Node as ExportDeclaration; + function visitNode(node: T): T { + if (node.kind === ts.SyntaxKind.ExportDeclaration) { + const ed = node as ts.Node as ts.ExportDeclaration; const exports = [{ name: "x" }]; - const exportSpecifiers = exports.map(e => factory.createExportSpecifier(/*isTypeOnly*/ false, e.name, e.name)); - const exportClause = factory.createNamedExports(exportSpecifiers); - const newEd = factory.updateExportDeclaration(ed, ed.decorators, ed.modifiers, ed.isTypeOnly, exportClause, ed.moduleSpecifier, ed.assertClause); - - return newEd as Node as T; + const exportSpecifiers = exports.map(e => ts.factory.createExportSpecifier(/*isTypeOnly*/ false, e.name, e.name)); + const exportClause = ts.factory.createNamedExports(exportSpecifiers); + const newEd = ts.factory.updateExportDeclaration(ed, ed.decorators, ed.modifiers, ed.isTypeOnly, exportClause, ed.moduleSpecifier, ed.assertClause); + return newEd as ts.Node as T; } - return visitEachChild(node, visitNode, context); + return ts.visitEachChild(node, visitNode, context); } }; } @@ -289,60 +274,58 @@ namespace ts { // https://github.com/Microsoft/TypeScript/issues/19618 testBaseline("transformAddImportStar", () => { - return transpileModule("", { + return ts.transpileModule("", { transformers: { before: [transformAddImportStar], }, compilerOptions: { - target: ScriptTarget.ES5, - module: ModuleKind.System, - newLine: NewLineKind.CarriageReturnLineFeed, + target: ts.ScriptTarget.ES5, + module: ts.ModuleKind.System, + newLine: ts.NewLineKind.CarriageReturnLineFeed, } }).outputText; - function transformAddImportStar(_context: TransformationContext) { - return (sourceFile: SourceFile): SourceFile => { + function transformAddImportStar(_context: ts.TransformationContext) { + return (sourceFile: ts.SourceFile): ts.SourceFile => { return visitNode(sourceFile); }; - function visitNode(sf: SourceFile) { + function visitNode(sf: ts.SourceFile) { // produce `import * as i0 from './comp'; - const importStar = factory.createImportDeclaration( + const importStar = ts.factory.createImportDeclaration( /*decorators*/ undefined, /*modifiers*/ undefined, - /*importClause*/ factory.createImportClause( + /*importClause*/ ts.factory.createImportClause( /*isTypeOnly*/ false, - /*name*/ undefined, - factory.createNamespaceImport(factory.createIdentifier("i0")) - ), - /*moduleSpecifier*/ factory.createStringLiteral("./comp1"), + /*name*/ undefined, ts.factory.createNamespaceImport(ts.factory.createIdentifier("i0"))), + /*moduleSpecifier*/ ts.factory.createStringLiteral("./comp1"), /*assertClause*/ undefined); - return factory.updateSourceFile(sf, [importStar]); + return ts.factory.updateSourceFile(sf, [importStar]); } } }); // https://github.com/Microsoft/TypeScript/issues/17384 testBaseline("transformAddDecoratedNode", () => { - return transpileModule("", { + return ts.transpileModule("", { transformers: { before: [transformAddDecoratedNode], }, compilerOptions: { - target: ScriptTarget.ES5, - newLine: NewLineKind.CarriageReturnLineFeed, + target: ts.ScriptTarget.ES5, + newLine: ts.NewLineKind.CarriageReturnLineFeed, } }).outputText; - function transformAddDecoratedNode(_context: TransformationContext) { - return (sourceFile: SourceFile): SourceFile => { + function transformAddDecoratedNode(_context: ts.TransformationContext) { + return (sourceFile: ts.SourceFile): ts.SourceFile => { return visitNode(sourceFile); }; - function visitNode(sf: SourceFile) { + function visitNode(sf: ts.SourceFile) { // produce `class Foo { @Bar baz() {} }`; - const classDecl = factory.createClassDeclaration([], [], "Foo", /*typeParameters*/ undefined, /*heritageClauses*/ undefined, [ - factory.createMethodDeclaration([factory.createDecorator(factory.createIdentifier("Bar"))], [], /**/ undefined, "baz", /**/ undefined, /**/ undefined, [], /**/ undefined, factory.createBlock([])) + const classDecl = ts.factory.createClassDeclaration([], [], "Foo", /*typeParameters*/ undefined, /*heritageClauses*/ undefined, [ + ts.factory.createMethodDeclaration([ts.factory.createDecorator(ts.factory.createIdentifier("Bar"))], [], /**/ undefined, "baz", /**/ undefined, /**/ undefined, [], /**/ undefined, ts.factory.createBlock([])) ]); - return factory.updateSourceFile(sf, [classDecl]); + return ts.factory.updateSourceFile(sf, [classDecl]); } } }); @@ -353,7 +336,7 @@ namespace ts { afterDeclarations: [replaceIdentifiersNamedOldNameWithNewName] }, compilerOptions: { - newLine: NewLineKind.CarriageReturnLineFeed, + newLine: ts.NewLineKind.CarriageReturnLineFeed, declaration: true } }); @@ -361,89 +344,90 @@ namespace ts { // https://github.com/microsoft/TypeScript/issues/33295 testBaseline("transformParameterProperty", () => { - return transpileModule("", { + return ts.transpileModule("", { transformers: { before: [transformAddParameterProperty], }, compilerOptions: { - target: ScriptTarget.ES5, - newLine: NewLineKind.CarriageReturnLineFeed, + target: ts.ScriptTarget.ES5, + newLine: ts.NewLineKind.CarriageReturnLineFeed, } }).outputText; - function transformAddParameterProperty(_context: TransformationContext) { - return (sourceFile: SourceFile): SourceFile => { + function transformAddParameterProperty(_context: ts.TransformationContext) { + return (sourceFile: ts.SourceFile): ts.SourceFile => { return visitNode(sourceFile); }; - function visitNode(sf: SourceFile) { + function visitNode(sf: ts.SourceFile) { // produce `class Foo { constructor(@Dec private x) {} }`; // The decorator is required to trigger ts.ts transformations. - const classDecl = factory.createClassDeclaration([], [], "Foo", /*typeParameters*/ undefined, /*heritageClauses*/ undefined, [ - factory.createConstructorDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, [ - factory.createParameterDeclaration(/*decorators*/ [factory.createDecorator(factory.createIdentifier("Dec"))], /*modifiers*/ [factory.createModifier(SyntaxKind.PrivateKeyword)], /*dotDotDotToken*/ undefined, "x")], factory.createBlock([])) + const classDecl = ts.factory.createClassDeclaration([], [], "Foo", /*typeParameters*/ undefined, /*heritageClauses*/ undefined, [ + ts.factory.createConstructorDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, [ + ts.factory.createParameterDeclaration(/*decorators*/ [ts.factory.createDecorator(ts.factory.createIdentifier("Dec"))], /*modifiers*/ [ts.factory.createModifier(ts.SyntaxKind.PrivateKeyword)], /*dotDotDotToken*/ undefined, "x") + ], ts.factory.createBlock([])) ]); - return factory.updateSourceFile(sf, [classDecl]); + return ts.factory.updateSourceFile(sf, [classDecl]); } } }); - function baselineDeclarationTransform(text: string, opts: TranspileOptions) { + function baselineDeclarationTransform(text: string, opts: ts.TranspileOptions) { const fs = vfs.createFromFileSystem(Harness.IO, /*caseSensitive*/ true, { documents: [new documents.TextDocument("/.src/index.ts", text)] }); const host = new fakes.CompilerHost(fs, opts.compilerOptions); - const program = createProgram(["/.src/index.ts"], opts.compilerOptions!, host); + const program = ts.createProgram(["/.src/index.ts"], opts.compilerOptions!, host); program.emit(program.getSourceFile("/.src/index.ts"), (p, s, bom) => host.writeFile(p, s, bom), /*cancellationToken*/ undefined, /*onlyDts*/ true, opts.transformers); return fs.readFileSync("/.src/index.d.ts").toString(); } - function addSyntheticComment(nodeFilter: (node: Node) => boolean) { - return (context: TransformationContext) => { - return (sourceFile: SourceFile): SourceFile => { - return visitNode(sourceFile, rootTransform, isSourceFile); + function addSyntheticComment(nodeFilter: (node: ts.Node) => boolean) { + return (context: ts.TransformationContext) => { + return (sourceFile: ts.SourceFile): ts.SourceFile => { + return ts.visitNode(sourceFile, rootTransform, ts.isSourceFile); }; - function rootTransform(node: T): VisitResult { + function rootTransform(node: T): ts.VisitResult { if (nodeFilter(node)) { - setEmitFlags(node, EmitFlags.NoLeadingComments); - setSyntheticLeadingComments(node, [{ kind: SyntaxKind.MultiLineCommentTrivia, text: "comment", pos: -1, end: -1, hasTrailingNewLine: true }]); + ts.setEmitFlags(node, ts.EmitFlags.NoLeadingComments); + ts.setSyntheticLeadingComments(node, [{ kind: ts.SyntaxKind.MultiLineCommentTrivia, text: "comment", pos: -1, end: -1, hasTrailingNewLine: true }]); } - return visitEachChild(node, rootTransform, context); + return ts.visitEachChild(node, rootTransform, context); } }; } // https://github.com/Microsoft/TypeScript/issues/24096 testBaseline("transformAddCommentToArrowReturnValue", () => { - return transpileModule(`const foo = () => + return ts.transpileModule(`const foo = () => void 0 `, { transformers: { - before: [addSyntheticComment(isVoidExpression)], + before: [addSyntheticComment(ts.isVoidExpression)], }, compilerOptions: { - target: ScriptTarget.ES5, - newLine: NewLineKind.CarriageReturnLineFeed, + target: ts.ScriptTarget.ES5, + newLine: ts.NewLineKind.CarriageReturnLineFeed, } }).outputText; }); // https://github.com/Microsoft/TypeScript/issues/17594 testBaseline("transformAddCommentToExportedVar", () => { - return transpileModule(`export const exportedDirectly = 1; + return ts.transpileModule(`export const exportedDirectly = 1; const exportedSeparately = 2; export {exportedSeparately}; `, { transformers: { - before: [addSyntheticComment(isVariableStatement)], + before: [addSyntheticComment(ts.isVariableStatement)], }, compilerOptions: { - target: ScriptTarget.ES5, - newLine: NewLineKind.CarriageReturnLineFeed, + target: ts.ScriptTarget.ES5, + newLine: ts.NewLineKind.CarriageReturnLineFeed, } }).outputText; }); // https://github.com/Microsoft/TypeScript/issues/17594 testBaseline("transformAddCommentToImport", () => { - return transpileModule(` + return ts.transpileModule(` // Previous comment on import. import {Value} from 'somewhere'; import * as X from 'somewhere'; @@ -453,18 +437,18 @@ export * from 'somewhere'; export {Value}; `, { transformers: { - before: [addSyntheticComment(n => isImportDeclaration(n) || isExportDeclaration(n) || isImportSpecifier(n) || isExportSpecifier(n))], + before: [addSyntheticComment(n => ts.isImportDeclaration(n) || ts.isExportDeclaration(n) || ts.isImportSpecifier(n) || ts.isExportSpecifier(n))], }, compilerOptions: { - target: ScriptTarget.ES5, - newLine: NewLineKind.CarriageReturnLineFeed, + target: ts.ScriptTarget.ES5, + newLine: ts.NewLineKind.CarriageReturnLineFeed, } }).outputText; }); // https://github.com/Microsoft/TypeScript/issues/17594 testBaseline("transformAddCommentToProperties", () => { - return transpileModule(` + return ts.transpileModule(` // class comment. class Clazz { // original comment 1. @@ -476,17 +460,17 @@ class Clazz { } `, { transformers: { - before: [addSyntheticComment(n => isPropertyDeclaration(n) || isParameterPropertyDeclaration(n, n.parent) || isClassDeclaration(n) || isConstructorDeclaration(n))], + before: [addSyntheticComment(n => ts.isPropertyDeclaration(n) || ts.isParameterPropertyDeclaration(n, n.parent) || ts.isClassDeclaration(n) || ts.isConstructorDeclaration(n))], }, compilerOptions: { - target: ScriptTarget.ES2015, - newLine: NewLineKind.CarriageReturnLineFeed, + target: ts.ScriptTarget.ES2015, + newLine: ts.NewLineKind.CarriageReturnLineFeed, } }).outputText; }); testBaseline("transformAddCommentToNamespace", () => { - return transpileModule(` + return ts.transpileModule(` // namespace comment. namespace Foo { export const x = 1; @@ -497,17 +481,17 @@ namespace Foo { } `, { transformers: { - before: [addSyntheticComment(n => isModuleDeclaration(n))], + before: [addSyntheticComment(n => ts.isModuleDeclaration(n))], }, compilerOptions: { - target: ScriptTarget.ES2015, - newLine: NewLineKind.CarriageReturnLineFeed, + target: ts.ScriptTarget.ES2015, + newLine: ts.NewLineKind.CarriageReturnLineFeed, } }).outputText; }); testBaseline("transformUpdateModuleMember", () => { - return transpileModule(` + return ts.transpileModule(` module MyModule { const myVariable = 1; function foo(param: string) {} @@ -517,20 +501,20 @@ module MyModule { before: [renameVariable], }, compilerOptions: { - target: ScriptTarget.ES2015, - newLine: NewLineKind.CarriageReturnLineFeed, + target: ts.ScriptTarget.ES2015, + newLine: ts.NewLineKind.CarriageReturnLineFeed, } }).outputText; - function renameVariable(context: TransformationContext) { - return (sourceFile: SourceFile): SourceFile => { - return visitNode(sourceFile, rootTransform, isSourceFile); + function renameVariable(context: ts.TransformationContext) { + return (sourceFile: ts.SourceFile): ts.SourceFile => { + return ts.visitNode(sourceFile, rootTransform, ts.isSourceFile); }; - function rootTransform(node: T): Node { - if (isVariableDeclaration(node)) { - return factory.updateVariableDeclaration(node, factory.createIdentifier("newName"), /*exclamationToken*/ undefined, /*type*/ undefined, node.initializer); + function rootTransform(node: T): ts.Node { + if (ts.isVariableDeclaration(node)) { + return ts.factory.updateVariableDeclaration(node, ts.factory.createIdentifier("newName"), /*exclamationToken*/ undefined, /*type*/ undefined, node.initializer); } - return visitEachChild(node, rootTransform, context); + return ts.visitEachChild(node, rootTransform, context); } } }); @@ -538,94 +522,77 @@ module MyModule { // https://github.com/Microsoft/TypeScript/issues/24709 testBaseline("issue24709", () => { const fs = vfs.createFromFileSystem(Harness.IO, /*caseSensitive*/ true); - const transformed = transform(createSourceFile("source.ts", "class X { echo(x: string) { return x; } }", ScriptTarget.ES3), [transformSourceFile]); + const transformed = ts.transform(ts.createSourceFile("source.ts", "class X { echo(x: string) { return x; } }", ts.ScriptTarget.ES3), [transformSourceFile]); const transformedSourceFile = transformed.transformed[0]; transformed.dispose(); const host = new fakes.CompilerHost(fs); host.getSourceFile = () => transformedSourceFile; - const program = createProgram(["source.ts"], { - target: ScriptTarget.ES3, - module: ModuleKind.None, + const program = ts.createProgram(["source.ts"], { + target: ts.ScriptTarget.ES3, + module: ts.ModuleKind.None, noLib: true }, host); program.emit(transformedSourceFile, (_p, s, b) => host.writeFile("source.js", s, b)); return host.readFile("source.js")!.toString(); - function transformSourceFile(context: TransformationContext) { - const visitor: Visitor = (node) => { - if (isMethodDeclaration(node)) { - return factory.updateMethodDeclaration( - node, - node.decorators, - node.modifiers, - node.asteriskToken, - factory.createIdentifier("foobar"), - node.questionToken, - node.typeParameters, - node.parameters, - node.type, - node.body, - ); + function transformSourceFile(context: ts.TransformationContext) { + const visitor: ts.Visitor = (node) => { + if (ts.isMethodDeclaration(node)) { + return ts.factory.updateMethodDeclaration(node, node.decorators, node.modifiers, node.asteriskToken, ts.factory.createIdentifier("foobar"), node.questionToken, node.typeParameters, node.parameters, node.type, node.body); } - return visitEachChild(node, visitor, context); + return ts.visitEachChild(node, visitor, context); }; - return (node: SourceFile) => visitNode(node, visitor); + return (node: ts.SourceFile) => ts.visitNode(node, visitor); } }); testBaselineAndEvaluate("templateSpans", () => { - return transpileModule("const x = String.raw`\n\nhello`; exports.stringLength = x.trim().length;", { + return ts.transpileModule("const x = String.raw`\n\nhello`; exports.stringLength = x.trim().length;", { compilerOptions: { - target: ScriptTarget.ESNext, - newLine: NewLineKind.CarriageReturnLineFeed, + target: ts.ScriptTarget.ESNext, + newLine: ts.NewLineKind.CarriageReturnLineFeed, }, transformers: { before: [transformSourceFile] } }).outputText; - function transformSourceFile(context: TransformationContext): Transformer { - function visitor(node: Node): VisitResult { - if (isNoSubstitutionTemplateLiteral(node)) { - return factory.createNoSubstitutionTemplateLiteral(node.text, node.rawText); + function transformSourceFile(context: ts.TransformationContext): ts.Transformer { + function visitor(node: ts.Node): ts.VisitResult { + if (ts.isNoSubstitutionTemplateLiteral(node)) { + return ts.factory.createNoSubstitutionTemplateLiteral(node.text, node.rawText); } else { - return visitEachChild(node, visitor, context); + return ts.visitEachChild(node, visitor, context); } } - return sourceFile => visitNode(sourceFile, visitor, isSourceFile); + return sourceFile => ts.visitNode(sourceFile, visitor, ts.isSourceFile); } }, exports => { assert.equal(exports.stringLength, 5); }); - function addStaticFieldWithComment(context: TransformationContext) { - return (sourceFile: SourceFile): SourceFile => { - return visitNode(sourceFile, rootTransform, isSourceFile); + function addStaticFieldWithComment(context: ts.TransformationContext) { + return (sourceFile: ts.SourceFile): ts.SourceFile => { + return ts.visitNode(sourceFile, rootTransform, ts.isSourceFile); }; - function rootTransform(node: T): Node { - if (isClassLike(node)) { - const newMembers = [factory.createPropertyDeclaration(/* decorators */ undefined, [factory.createModifier(SyntaxKind.StaticKeyword)], "newField", /* questionOrExclamationToken */ undefined, /* type */ undefined, factory.createStringLiteral("x"))]; - setSyntheticLeadingComments(newMembers[0], [{ kind: SyntaxKind.MultiLineCommentTrivia, text: "comment", pos: -1, end: -1, hasTrailingNewLine: true }]); - return isClassDeclaration(node) ? - factory.updateClassDeclaration( - node, node.decorators, - /* modifierFlags */ undefined, node.name, - node.typeParameters, node.heritageClauses, - newMembers) : - factory.updateClassExpression( - node, node.decorators, - /* modifierFlags */ undefined, node.name, - node.typeParameters, node.heritageClauses, - newMembers); - } - return visitEachChild(node, rootTransform, context); + function rootTransform(node: T): ts.Node { + if (ts.isClassLike(node)) { + const newMembers = [ts.factory.createPropertyDeclaration(/* decorators */ undefined, [ts.factory.createModifier(ts.SyntaxKind.StaticKeyword)], "newField", /* questionOrExclamationToken */ undefined, /* type */ undefined, ts.factory.createStringLiteral("x"))]; + ts.setSyntheticLeadingComments(newMembers[0], [{ kind: ts.SyntaxKind.MultiLineCommentTrivia, text: "comment", pos: -1, end: -1, hasTrailingNewLine: true }]); + return ts.isClassDeclaration(node) ? + ts.factory.updateClassDeclaration(node, node.decorators, + /* modifierFlags */ undefined, node.name, node.typeParameters, node.heritageClauses, newMembers) : + ts.factory.updateClassExpression(node, node.decorators, + /* modifierFlags */ undefined, node.name, node.typeParameters, node.heritageClauses, newMembers); + } + return ts.visitEachChild(node, rootTransform, context); } } testBaseline("transformSyntheticCommentOnStaticFieldInClassDeclaration", () => { - return transpileModule(` + return ts.transpileModule(` declare const Decorator: any; @Decorator class MyClass { @@ -635,14 +602,14 @@ class MyClass { before: [addStaticFieldWithComment], }, compilerOptions: { - target: ScriptTarget.ES2015, - newLine: NewLineKind.CarriageReturnLineFeed, + target: ts.ScriptTarget.ES2015, + newLine: ts.NewLineKind.CarriageReturnLineFeed, } }).outputText; }); testBaseline("transformSyntheticCommentOnStaticFieldInClassExpression", () => { - return transpileModule(` + return ts.transpileModule(` const MyClass = class { }; `, { @@ -650,8 +617,8 @@ const MyClass = class { before: [addStaticFieldWithComment], }, compilerOptions: { - target: ScriptTarget.ES2015, - newLine: NewLineKind.CarriageReturnLineFeed, + target: ts.ScriptTarget.ES2015, + newLine: ts.NewLineKind.CarriageReturnLineFeed, } }).outputText; }); diff --git a/src/testRunner/unittests/tsbuild/amdModulesWithOut.ts b/src/testRunner/unittests/tsbuild/amdModulesWithOut.ts index 3e3a81491b127..51c88a274af10 100644 --- a/src/testRunner/unittests/tsbuild/amdModulesWithOut.ts +++ b/src/testRunner/unittests/tsbuild/amdModulesWithOut.ts @@ -2,7 +2,7 @@ namespace ts { describe("unittests:: tsbuild:: outFile:: on amd modules with --out", () => { let outFileFs: vfs.FileSystem; before(() => { - outFileFs = loadProjectFromDisk("tests/projects/amdModulesWithOut"); + outFileFs = ts.loadProjectFromDisk("tests/projects/amdModulesWithOut"); }); after(() => { outFileFs = undefined!; @@ -14,12 +14,8 @@ namespace ts { modifyAgainFs?: (fs: vfs.FileSystem) => void; } - function verifyOutFileScenario({ - subScenario, - modifyFs, - modifyAgainFs - }: VerifyOutFileScenarioInput) { - verifyTscWithEdits({ + function verifyOutFileScenario({ subScenario, modifyFs, modifyAgainFs }: VerifyOutFileScenarioInput) { + ts.verifyTscWithEdits({ scenario: "amdModulesWithOut", subScenario, fs: () => outFileFs, @@ -29,12 +25,12 @@ namespace ts { edits: [ { subScenario: "incremental-declaration-doesnt-change", - modifyFs: fs => appendText(fs, "/src/lib/file1.ts", "console.log(x);") + modifyFs: fs => ts.appendText(fs, "/src/lib/file1.ts", "console.log(x);") }, ...(modifyAgainFs ? [{ subScenario: "incremental-headers-change-without-dts-changes", modifyFs: modifyAgainFs - }] : emptyArray), + }] : ts.emptyArray), ] }); } @@ -49,15 +45,15 @@ namespace ts { verifyOutFileScenario({ subScenario: "multiple prologues in all projects", modifyFs: fs => { - enableStrict(fs, "/src/lib/tsconfig.json"); - addTestPrologue(fs, "/src/lib/file0.ts", `"myPrologue"`); - addTestPrologue(fs, "/src/lib/file2.ts", `"myPrologueFile"`); - addTestPrologue(fs, "/src/lib/global.ts", `"myPrologue3"`); - enableStrict(fs, "/src/app/tsconfig.json"); - addTestPrologue(fs, "/src/app/file3.ts", `"myPrologue"`); - addTestPrologue(fs, "/src/app/file4.ts", `"myPrologue2";`); + ts.enableStrict(fs, "/src/lib/tsconfig.json"); + ts.addTestPrologue(fs, "/src/lib/file0.ts", `"myPrologue"`); + ts.addTestPrologue(fs, "/src/lib/file2.ts", `"myPrologueFile"`); + ts.addTestPrologue(fs, "/src/lib/global.ts", `"myPrologue3"`); + ts.enableStrict(fs, "/src/app/tsconfig.json"); + ts.addTestPrologue(fs, "/src/app/file3.ts", `"myPrologue"`); + ts.addTestPrologue(fs, "/src/app/file4.ts", `"myPrologue2";`); }, - modifyAgainFs: fs => addTestPrologue(fs, "/src/lib/file1.ts", `"myPrologue5"`) + modifyAgainFs: fs => ts.addTestPrologue(fs, "/src/lib/file1.ts", `"myPrologue5"`) }); }); @@ -67,9 +63,9 @@ namespace ts { verifyOutFileScenario({ subScenario: "shebang in all projects", modifyFs: fs => { - addShebang(fs, "lib", "file0"); - addShebang(fs, "lib", "file1"); - addShebang(fs, "app", "file3"); + ts.addShebang(fs, "lib", "file0"); + ts.addShebang(fs, "lib", "file1"); + ts.addShebang(fs, "app", "file3"); }, }); }); @@ -79,12 +75,12 @@ namespace ts { verifyOutFileScenario({ subScenario: "multiple emitHelpers in all projects", modifyFs: fs => { - addSpread(fs, "lib", "file0"); - addRest(fs, "lib", "file1"); - addRest(fs, "app", "file3"); - addSpread(fs, "app", "file4"); + ts.addSpread(fs, "lib", "file0"); + ts.addRest(fs, "lib", "file1"); + ts.addRest(fs, "app", "file3"); + ts.addSpread(fs, "app", "file4"); }, - modifyAgainFs: fs => removeRest(fs, "lib", "file1") + modifyAgainFs: fs => ts.removeRest(fs, "lib", "file1") }); }); @@ -94,8 +90,8 @@ namespace ts { verifyOutFileScenario({ subScenario: "triple slash refs in all projects", modifyFs: fs => { - addTripleSlashRef(fs, "lib", "file0"); - addTripleSlashRef(fs, "app", "file4"); + ts.addTripleSlashRef(fs, "lib", "file0"); + ts.addTripleSlashRef(fs, "app", "file4"); } }); }); @@ -103,10 +99,10 @@ namespace ts { describe("stripInternal", () => { function stripInternalScenario(fs: vfs.FileSystem) { const internal = "/*@internal*/"; - replaceText(fs, "/src/app/tsconfig.json", `"composite": true,`, `"composite": true, + ts.replaceText(fs, "/src/app/tsconfig.json", `"composite": true,`, `"composite": true, "stripInternal": true,`); - replaceText(fs, "/src/lib/file0.ts", "const", `${internal} const`); - appendText(fs, "/src/lib/file1.ts", ` + ts.replaceText(fs, "/src/lib/file0.ts", "const", `${internal} const`); + ts.appendText(fs, "/src/lib/file1.ts", ` export class normalC { ${internal} constructor() { } ${internal} prop: string; @@ -138,19 +134,19 @@ ${internal} export enum internalEnum { a, b, c }`); verifyOutFileScenario({ subScenario: "stripInternal", modifyFs: stripInternalScenario, - modifyAgainFs: fs => replaceText(fs, "/src/lib/file1.ts", `export const`, `/*@internal*/ export const`), + modifyAgainFs: fs => ts.replaceText(fs, "/src/lib/file1.ts", `export const`, `/*@internal*/ export const`), }); }); describe("when the module resolution finds original source file", () => { function modifyFs(fs: vfs.FileSystem) { // Make lib to output to parent dir - replaceText(fs, "/src/lib/tsconfig.json", `"outFile": "module.js"`, `"outFile": "../module.js", "rootDir": "../"`); + ts.replaceText(fs, "/src/lib/tsconfig.json", `"outFile": "module.js"`, `"outFile": "../module.js", "rootDir": "../"`); // Change reference to file1 module to resolve to lib/file1 - replaceText(fs, "/src/app/file3.ts", "file1", "lib/file1"); + ts.replaceText(fs, "/src/app/file3.ts", "file1", "lib/file1"); } - verifyTsc({ + ts.verifyTsc({ scenario: "amdModulesWithOut", subScenario: "when the module resolution finds original source file", fs: () => outFileFs, diff --git a/src/testRunner/unittests/tsbuild/clean.ts b/src/testRunner/unittests/tsbuild/clean.ts index 90bb298529028..809cf34122345 100644 --- a/src/testRunner/unittests/tsbuild/clean.ts +++ b/src/testRunner/unittests/tsbuild/clean.ts @@ -1,10 +1,10 @@ namespace ts { describe("unittests:: tsbuild - clean", () => { - verifyTsc({ + ts.verifyTsc({ scenario: "clean", subScenario: `file name and output name clashing`, commandLineArgs: ["--b", "/src/tsconfig.json", "-clean"], - fs: () => loadProjectFromFiles({ + fs: () => ts.loadProjectFromFiles({ "/src/index.js": "", "/src/bar.ts": "", "/src/tsconfig.json": JSON.stringify({ diff --git a/src/testRunner/unittests/tsbuild/configFileErrors.ts b/src/testRunner/unittests/tsbuild/configFileErrors.ts index 594c8e07cadd8..60e1c1c5c815d 100644 --- a/src/testRunner/unittests/tsbuild/configFileErrors.ts +++ b/src/testRunner/unittests/tsbuild/configFileErrors.ts @@ -1,18 +1,18 @@ namespace ts { describe("unittests:: tsbuild:: configFileErrors:: when tsconfig extends the missing file", () => { - verifyTsc({ + ts.verifyTsc({ scenario: "configFileErrors", subScenario: "when tsconfig extends the missing file", - fs: () => loadProjectFromDisk("tests/projects/missingExtendedConfig"), + fs: () => ts.loadProjectFromDisk("tests/projects/missingExtendedConfig"), commandLineArgs: ["--b", "/src/tsconfig.json"], }); }); describe("unittests:: tsbuild:: configFileErrors:: reports syntax errors in config file", () => { - verifyTscWithEdits({ + ts.verifyTscWithEdits({ scenario: "configFileErrors", subScenario: "reports syntax errors in config file", - fs: () => loadProjectFromFiles({ + fs: () => ts.loadProjectFromFiles({ "/src/a.ts": "export function foo() { }", "/src/b.ts": "export function bar() { }", "/src/tsconfig.json": Utils.dedent` @@ -29,23 +29,20 @@ namespace ts { commandLineArgs: ["--b", "/src/tsconfig.json"], edits: [ { - modifyFs: fs => replaceText(fs, "/src/tsconfig.json", ",", `, + modifyFs: fs => ts.replaceText(fs, "/src/tsconfig.json", ",", `, "declaration": true,`), subScenario: "reports syntax errors after change to config file" }, { - modifyFs: fs => appendText(fs, "/src/a.ts", "export function fooBar() { }"), + modifyFs: fs => ts.appendText(fs, "/src/a.ts", "export function fooBar() { }"), subScenario: "reports syntax errors after change to ts file" }, - noChangeRun, + ts.noChangeRun, { - modifyFs: fs => fs.writeFileSync( - "/src/tsconfig.json", - JSON.stringify({ + modifyFs: fs => fs.writeFileSync("/src/tsconfig.json", JSON.stringify({ compilerOptions: { composite: true, declaration: true }, files: ["a.ts", "b.ts"] - }) - ), + })), subScenario: "builds after fixing config file errors" }, ] diff --git a/src/testRunner/unittests/tsbuild/configFileExtends.ts b/src/testRunner/unittests/tsbuild/configFileExtends.ts index b00a213b9d3fc..3a1431df6ddd4 100644 --- a/src/testRunner/unittests/tsbuild/configFileExtends.ts +++ b/src/testRunner/unittests/tsbuild/configFileExtends.ts @@ -1,7 +1,7 @@ namespace ts { describe("unittests:: tsbuild:: configFileExtends:: when tsconfig extends another config", () => { function getConfigExtendsWithIncludeFs() { - return loadProjectFromFiles({ + return ts.loadProjectFromFiles({ "/src/tsconfig.json": JSON.stringify({ references: [ { path: "./shared/tsconfig.json" }, @@ -36,13 +36,13 @@ namespace ts { "/src/webpack/index.ts": `export const b: Unrestricted = 1;`, }); } - verifyTsc({ + ts.verifyTsc({ scenario: "configFileExtends", subScenario: "when building solution with projects extends config with include", fs: getConfigExtendsWithIncludeFs, commandLineArgs: ["--b", "/src/tsconfig.json", "--v", "--listFiles"], }); - verifyTsc({ + ts.verifyTsc({ scenario: "configFileExtends", subScenario: "when building project uses reference and both extend config with include", fs: getConfigExtendsWithIncludeFs, diff --git a/src/testRunner/unittests/tsbuild/containerOnlyReferenced.ts b/src/testRunner/unittests/tsbuild/containerOnlyReferenced.ts index e9eacf1fa657c..762e87974ff77 100644 --- a/src/testRunner/unittests/tsbuild/containerOnlyReferenced.ts +++ b/src/testRunner/unittests/tsbuild/containerOnlyReferenced.ts @@ -1,11 +1,11 @@ namespace ts { describe("unittests:: tsbuild:: when containerOnly project is referenced", () => { - verifyTscWithEdits({ + ts.verifyTscWithEdits({ scenario: "containerOnlyReferenced", subScenario: "verify that subsequent builds after initial build doesnt build anything", - fs: () => loadProjectFromDisk("tests/projects/containerOnlyReferenced"), + fs: () => ts.loadProjectFromDisk("tests/projects/containerOnlyReferenced"), commandLineArgs: ["--b", "/src", "--verbose"], - edits: noChangeOnlyRuns + edits: ts.noChangeOnlyRuns }); }); } diff --git a/src/testRunner/unittests/tsbuild/declarationEmit.ts b/src/testRunner/unittests/tsbuild/declarationEmit.ts index 122912e026d8c..e6f4c2a4a5450 100644 --- a/src/testRunner/unittests/tsbuild/declarationEmit.ts +++ b/src/testRunner/unittests/tsbuild/declarationEmit.ts @@ -55,17 +55,17 @@ declare type MyNominal = T & { };`, }; } - verifyTsc({ + ts.verifyTsc({ scenario: "declarationEmit", subScenario: "when declaration file is referenced through triple slash", - fs: () => loadProjectFromFiles(getFiles()), + fs: () => ts.loadProjectFromFiles(getFiles()), commandLineArgs: ["--b", "/src/solution/tsconfig.json", "--verbose"] }); - verifyTsc({ + ts.verifyTsc({ scenario: "declarationEmit", subScenario: "when declaration file is referenced through triple slash but uses no references", - fs: () => loadProjectFromFiles({ + fs: () => ts.loadProjectFromFiles({ ...getFiles(), "/src/solution/tsconfig.json": JSON.stringify({ extends: "./tsconfig.base.json", @@ -76,10 +76,10 @@ declare type MyNominal = T & { commandLineArgs: ["--b", "/src/solution/tsconfig.json", "--verbose"] }); - verifyTsc({ + ts.verifyTsc({ scenario: "declarationEmit", subScenario: "when declaration file used inferred type from referenced project", - fs: () => loadProjectFromFiles({ + fs: () => ts.loadProjectFromFiles({ "/src/tsconfig.json": JSON.stringify({ compilerOptions: { composite: true, diff --git a/src/testRunner/unittests/tsbuild/demo.ts b/src/testRunner/unittests/tsbuild/demo.ts index 18bc1eea89a3b..63bdc8efae770 100644 --- a/src/testRunner/unittests/tsbuild/demo.ts +++ b/src/testRunner/unittests/tsbuild/demo.ts @@ -2,48 +2,39 @@ namespace ts { describe("unittests:: tsbuild:: on demo project", () => { let projFs: vfs.FileSystem; before(() => { - projFs = loadProjectFromDisk("tests/projects/demo"); + projFs = ts.loadProjectFromDisk("tests/projects/demo"); }); after(() => { projFs = undefined!; // Release the contents }); - verifyTsc({ + ts.verifyTsc({ scenario: "demo", subScenario: "in master branch with everything setup correctly and reports no error", fs: () => projFs, commandLineArgs: ["--b", "/src/tsconfig.json", "--verbose"] }); - verifyTsc({ + ts.verifyTsc({ scenario: "demo", subScenario: "in circular branch reports the error about it by stopping build", fs: () => projFs, commandLineArgs: ["--b", "/src/tsconfig.json", "--verbose"], - modifyFs: fs => replaceText( - fs, - "/src/core/tsconfig.json", - "}", - `}, + modifyFs: fs => ts.replaceText(fs, "/src/core/tsconfig.json", "}", `}, "references": [ { "path": "../zoo" } - ]` - ) + ]`) }); - verifyTsc({ + ts.verifyTsc({ scenario: "demo", subScenario: "in bad-ref branch reports the error about files not in rootDir at the import location", fs: () => projFs, commandLineArgs: ["--b", "/src/tsconfig.json", "--verbose"], - modifyFs: fs => prependText( - fs, - "/src/core/utilities.ts", - `import * as A from '../animals'; -` - ) + modifyFs: fs => ts.prependText(fs, "/src/core/utilities.ts", `import * as A from '../animals'; +`) }); }); } diff --git a/src/testRunner/unittests/tsbuild/emitDeclarationOnly.ts b/src/testRunner/unittests/tsbuild/emitDeclarationOnly.ts index 9994b24d32c2a..091c40719f7b2 100644 --- a/src/testRunner/unittests/tsbuild/emitDeclarationOnly.ts +++ b/src/testRunner/unittests/tsbuild/emitDeclarationOnly.ts @@ -2,49 +2,49 @@ namespace ts { describe("unittests:: tsbuild:: on project with emitDeclarationOnly set to true", () => { let projFs: vfs.FileSystem; before(() => { - projFs = loadProjectFromDisk("tests/projects/emitDeclarationOnly"); + projFs = ts.loadProjectFromDisk("tests/projects/emitDeclarationOnly"); }); after(() => { projFs = undefined!; }); function verifyEmitDeclarationOnly(disableMap?: true) { - verifyTscWithEdits({ + ts.verifyTscWithEdits({ subScenario: `only dts output in circular import project with emitDeclarationOnly${disableMap ? "" : " and declarationMap"}`, fs: () => projFs, scenario: "emitDeclarationOnly", commandLineArgs: ["--b", "/src", "--verbose"], modifyFs: disableMap ? - (fs => replaceText(fs, "/src/tsconfig.json", `"declarationMap": true,`, "")) : + (fs => ts.replaceText(fs, "/src/tsconfig.json", `"declarationMap": true,`, "")) : undefined, edits: [{ subScenario: "incremental-declaration-changes", - modifyFs: fs => replaceText(fs, "/src/src/a.ts", "b: B;", "b: B; foo: any;"), + modifyFs: fs => ts.replaceText(fs, "/src/src/a.ts", "b: B;", "b: B; foo: any;"), }], }); } verifyEmitDeclarationOnly(); verifyEmitDeclarationOnly(/*disableMap*/ true); - verifyTscWithEdits({ + ts.verifyTscWithEdits({ subScenario: `only dts output in non circular imports project with emitDeclarationOnly`, fs: () => projFs, scenario: "emitDeclarationOnly", commandLineArgs: ["--b", "/src", "--verbose"], modifyFs: fs => { fs.rimrafSync("/src/src/index.ts"); - replaceText(fs, "/src/src/a.ts", `import { B } from "./b";`, `export class B { prop = "hello"; }`); + ts.replaceText(fs, "/src/src/a.ts", `import { B } from "./b";`, `export class B { prop = "hello"; }`); }, edits: [ { subScenario: "incremental-declaration-doesnt-change", - modifyFs: fs => replaceText(fs, "/src/src/a.ts", "export interface A {", `class C { } + modifyFs: fs => ts.replaceText(fs, "/src/src/a.ts", "export interface A {", `class C { } export interface A {`), }, { subScenario: "incremental-declaration-changes", - modifyFs: fs => replaceText(fs, "/src/src/a.ts", "b: B;", "b: B; foo: any;"), + modifyFs: fs => ts.replaceText(fs, "/src/src/a.ts", "b: B;", "b: B; foo: any;"), }, ], }); diff --git a/src/testRunner/unittests/tsbuild/emptyFiles.ts b/src/testRunner/unittests/tsbuild/emptyFiles.ts index ffd9429a34411..fe829e0558945 100644 --- a/src/testRunner/unittests/tsbuild/emptyFiles.ts +++ b/src/testRunner/unittests/tsbuild/emptyFiles.ts @@ -2,20 +2,20 @@ namespace ts { describe("unittests:: tsbuild - empty files option in tsconfig", () => { let projFs: vfs.FileSystem; before(() => { - projFs = loadProjectFromDisk("tests/projects/empty-files"); + projFs = ts.loadProjectFromDisk("tests/projects/empty-files"); }); after(() => { projFs = undefined!; }); - verifyTsc({ + ts.verifyTsc({ scenario: "emptyFiles", subScenario: "has empty files diagnostic when files is empty and no references are provided", fs: () => projFs, commandLineArgs: ["--b", "/src/no-references"], }); - verifyTsc({ + ts.verifyTsc({ scenario: "emptyFiles", subScenario: "does not have empty files diagnostic when files is empty and references are provided", fs: () => projFs, diff --git a/src/testRunner/unittests/tsbuild/exitCodeOnBogusFile.ts b/src/testRunner/unittests/tsbuild/exitCodeOnBogusFile.ts index 487671dfae147..fd200a3ca5788 100644 --- a/src/testRunner/unittests/tsbuild/exitCodeOnBogusFile.ts +++ b/src/testRunner/unittests/tsbuild/exitCodeOnBogusFile.ts @@ -1,10 +1,10 @@ namespace ts { // https://github.com/microsoft/TypeScript/issues/33849 describe("unittests:: tsbuild:: exitCodeOnBogusFile:: test exit code", () => { - verifyTsc({ + ts.verifyTsc({ scenario: "exitCodeOnBogusFile", subScenario: `test exit code`, - fs: () => loadProjectFromFiles({}), + fs: () => ts.loadProjectFromFiles({}), commandLineArgs: ["-b", "bogus.json"] }); }); diff --git a/src/testRunner/unittests/tsbuild/graphOrdering.ts b/src/testRunner/unittests/tsbuild/graphOrdering.ts index 79ddd80d67bde..678947281b0d3 100644 --- a/src/testRunner/unittests/tsbuild/graphOrdering.ts +++ b/src/testRunner/unittests/tsbuild/graphOrdering.ts @@ -1,7 +1,10 @@ namespace ts { describe("unittests:: tsbuild - graph-ordering", () => { let host: fakes.SolutionBuilderHost | undefined; - const deps: [string, string][] = [ + const deps: [ + string, + string + ][] = [ ["A", "B"], ["B", "C"], ["A", "C"], @@ -47,16 +50,17 @@ namespace ts { }); function checkGraphOrdering(rootNames: string[], expectedBuildSet: string[], circular?: true) { - const builder = createSolutionBuilder(host!, rootNames.map(getProjectFileName), { dry: true, force: false, verbose: false }); + const builder = ts.createSolutionBuilder(host!, rootNames.map(getProjectFileName), { dry: true, force: false, verbose: false }); const buildOrder = builder.getBuildOrder(); - assert.equal(isCircularBuildOrder(buildOrder), !!circular); - const buildQueue = getBuildOrderFromAnyBuildOrder(buildOrder); + assert.equal(ts.isCircularBuildOrder(buildOrder), !!circular); + const buildQueue = ts.getBuildOrderFromAnyBuildOrder(buildOrder); assert.deepEqual(buildQueue, expectedBuildSet.map(getProjectFileName)); if (!circular) { for (const dep of deps) { const child = getProjectFileName(dep[0]); - if (buildQueue.indexOf(child) < 0) continue; + if (buildQueue.indexOf(child) < 0) + continue; const parent = getProjectFileName(dep[1]); assert.isAbove(buildQueue.indexOf(child), buildQueue.indexOf(parent), `Expecting child ${child} to be built after parent ${parent}`); } @@ -64,14 +68,19 @@ namespace ts { } function getProjectFileName(proj: string) { - return `/project/${proj}/tsconfig.json` as ResolvedConfigFileName; + return `/project/${proj}/tsconfig.json` as ts.ResolvedConfigFileName; } - function writeProjects(fileSystem: vfs.FileSystem, projectNames: string[], deps: [string, string][]): string[] { + function writeProjects(fileSystem: vfs.FileSystem, projectNames: string[], deps: [ + string, + string + ][]): string[] { const projFileNames: string[] = []; for (const dep of deps) { - if (projectNames.indexOf(dep[0]) < 0) throw new Error(`Invalid dependency - project ${dep[0]} does not exist`); - if (projectNames.indexOf(dep[1]) < 0) throw new Error(`Invalid dependency - project ${dep[1]} does not exist`); + if (projectNames.indexOf(dep[0]) < 0) + throw new Error(`Invalid dependency - project ${dep[0]} does not exist`); + if (projectNames.indexOf(dep[1]) < 0) + throw new Error(`Invalid dependency - project ${dep[1]} does not exist`); } for (const proj of projectNames) { fileSystem.mkdirpSync(`/project/${proj}`); diff --git a/src/testRunner/unittests/tsbuild/helpers.ts b/src/testRunner/unittests/tsbuild/helpers.ts index 803a37e014fc6..c270fbd1ae433 100644 --- a/src/testRunner/unittests/tsbuild/helpers.ts +++ b/src/testRunner/unittests/tsbuild/helpers.ts @@ -4,17 +4,18 @@ namespace ts { } export function getExpectedDiagnosticForProjectsInBuild(...projects: string[]): fakes.ExpectedDiagnostic { - return [Diagnostics.Projects_in_this_build_Colon_0, projects.map(p => "\r\n * " + p).join("")]; + return [ts.Diagnostics.Projects_in_this_build_Colon_0, projects.map(p => "\r\n * " + p).join("")]; } export function changeCompilerVersion(host: fakes.SolutionBuilderHost) { const originalReadFile = host.readFile; host.readFile = path => { const value = originalReadFile.call(host, path); - if (!value || !isBuildInfoFile(path)) return value; - const buildInfo = getBuildInfo(value); + if (!value || !ts.isBuildInfoFile(path)) + return value; + const buildInfo = ts.getBuildInfo(value); buildInfo.version = fakes.version; - return getBuildInfoText(buildInfo); + return ts.getBuildInfoText(buildInfo); }; } @@ -78,7 +79,7 @@ namespace ts { }; } - export const libContent = `${TestFSWithWatch.libFile.content} + export const libContent = `${ts.TestFSWithWatch.libFile.content} interface ReadonlyArray {} declare const console: { log(msg: any): void; };`; @@ -96,10 +97,7 @@ interface Symbol { /** * Load project from disk into /src folder */ - export function loadProjectFromDisk( - root: string, - libContentToAppend?: string - ): vfs.FileSystem { + export function loadProjectFromDisk(root: string, libContentToAppend?: string): vfs.FileSystem { const resolver = vfs.createResolver(Harness.IO); const fs = new vfs.FileSystem(/*ignoreCase*/ true, { files: { @@ -115,10 +113,7 @@ interface Symbol { /** * All the files must be in /src */ - export function loadProjectFromFiles( - files: vfs.FileSet, - libContentToAppend?: string - ): vfs.FileSystem { + export function loadProjectFromFiles(files: vfs.FileSet, libContentToAppend?: string): vfs.FileSystem { const fs = new vfs.FileSystem(/*ignoreCase*/ true, { files, cwd: "/", @@ -146,32 +141,36 @@ interface Symbol { } } - export function generateSourceMapBaselineFiles(sys: System & { writtenFiles: ReadonlyCollection; }) { - const mapFileNames = mapDefinedIterator(sys.writtenFiles.keys(), f => f.endsWith(".map") ? f : undefined); + export function generateSourceMapBaselineFiles(sys: ts.System & { + writtenFiles: ts.ReadonlyCollection; + }) { + const mapFileNames = ts.mapDefinedIterator(sys.writtenFiles.keys(), f => f.endsWith(".map") ? f : undefined); while (true) { const result = mapFileNames.next(); - if (result.done) break; + if (result.done) + break; const mapFile = result.value; const text = Harness.SourceMapRecorder.getSourceMapRecordWithSystem(sys, mapFile); sys.writeFile(`${mapFile}.baseline.txt`, text); } } - function generateBundleFileSectionInfo(sys: System, originalReadCall: System["readFile"], baselineRecorder: Harness.Compiler.WriterAggregator, bundleFileInfo: BundleFileInfo | undefined, outFile: string | undefined) { - if (!length(bundleFileInfo && bundleFileInfo.sections) && !outFile) return; // Nothing to baseline + function generateBundleFileSectionInfo(sys: ts.System, originalReadCall: ts.System["readFile"], baselineRecorder: Harness.Compiler.WriterAggregator, bundleFileInfo: ts.BundleFileInfo | undefined, outFile: string | undefined) { + if (!ts.length(bundleFileInfo && bundleFileInfo.sections) && !outFile) + return; // Nothing to baseline const content = outFile && sys.fileExists(outFile) ? originalReadCall.call(sys, outFile, "utf8")! : ""; baselineRecorder.WriteLine("======================================================================"); baselineRecorder.WriteLine(`File:: ${outFile}`); - for (const section of bundleFileInfo ? bundleFileInfo.sections : emptyArray) { + for (const section of bundleFileInfo ? bundleFileInfo.sections : ts.emptyArray) { baselineRecorder.WriteLine("----------------------------------------------------------------------"); writeSectionHeader(section); - if (section.kind !== BundleFileSectionKind.Prepend) { + if (section.kind !== ts.BundleFileSectionKind.Prepend) { writeTextOfSection(section.pos, section.end); } else if (section.texts.length > 0) { - Debug.assert(section.pos === first(section.texts).pos); - Debug.assert(section.end === last(section.texts).end); + ts.Debug.assert(section.pos === ts.first(section.texts).pos); + ts.Debug.assert(section.end === ts.last(section.texts).end); for (const text of section.texts) { baselineRecorder.WriteLine(">>--------------------------------------------------------------------"); writeSectionHeader(text); @@ -179,7 +178,7 @@ interface Symbol { } } else { - Debug.assert(section.pos === section.end); + ts.Debug.assert(section.pos === section.end); } } baselineRecorder.WriteLine("======================================================================"); @@ -191,27 +190,36 @@ interface Symbol { } } - function writeSectionHeader(section: BundleFileSection) { - baselineRecorder.WriteLine(`${section.kind}: (${section.pos}-${section.end})${section.data ? ":: " + section.data : ""}${section.kind === BundleFileSectionKind.Prepend ? " texts:: " + section.texts.length : ""}`); + function writeSectionHeader(section: ts.BundleFileSection) { + baselineRecorder.WriteLine(`${section.kind}: (${section.pos}-${section.end})${section.data ? ":: " + section.data : ""}${section.kind === ts.BundleFileSectionKind.Prepend ? " texts:: " + section.texts.length : ""}`); } } - type ReadableProgramBuildInfoDiagnostic = string | [string, readonly ReusableDiagnostic[]]; - type ReadableProgramBuilderInfoFilePendingEmit = [string, "DtsOnly" | "Full"]; + type ReadableProgramBuildInfoDiagnostic = string | [ + string, + readonly ts.ReusableDiagnostic[] + ]; + type ReadableProgramBuilderInfoFilePendingEmit = [ + string, + "DtsOnly" | "Full" + ]; interface ReadableProgramBuildInfo { fileNames: readonly string[]; fileNamesList: readonly (readonly string[])[] | undefined; - fileInfos: MapLike; - options: CompilerOptions | undefined; - referencedMap?: MapLike; - exportedModulesMap?: MapLike; + fileInfos: ts.MapLike; + options: ts.CompilerOptions | undefined; + referencedMap?: ts.MapLike; + exportedModulesMap?: ts.MapLike; semanticDiagnosticsPerFile?: readonly ReadableProgramBuildInfoDiagnostic[]; affectedFilesPendingEmit?: readonly ReadableProgramBuilderInfoFilePendingEmit[]; } - type ReadableBuildInfo = Omit & { program: ReadableProgramBuildInfo | undefined; size: number; }; - function generateBuildInfoProgramBaseline(sys: System, buildInfoPath: string, buildInfo: BuildInfo) { + type ReadableBuildInfo = Omit & { + program: ReadableProgramBuildInfo | undefined; + size: number; + }; + function generateBuildInfoProgramBaseline(sys: ts.System, buildInfoPath: string, buildInfo: ts.BuildInfo) { const fileInfos: ReadableProgramBuildInfo["fileInfos"] = {}; - buildInfo.program?.fileInfos.forEach((fileInfo, index) => fileInfos[toFileName(index + 1 as ProgramBuildInfoFileId)] = toBuilderStateFileInfo(fileInfo)); + buildInfo.program?.fileInfos.forEach((fileInfo, index) => fileInfos[toFileName(index + 1 as ts.ProgramBuildInfoFileId)] = ts.toBuilderStateFileInfo(fileInfo)); const fileNamesList = buildInfo.program?.fileIdsList?.map(fileIdsListId => fileIdsListId.map(toFileName)); const program: ReadableProgramBuildInfo | undefined = buildInfo.program && { fileNames: buildInfo.program.fileNames, @@ -220,16 +228,14 @@ interface Symbol { options: buildInfo.program.options, referencedMap: toMapOfReferencedSet(buildInfo.program.referencedMap), exportedModulesMap: toMapOfReferencedSet(buildInfo.program.exportedModulesMap), - semanticDiagnosticsPerFile: buildInfo.program.semanticDiagnosticsPerFile?.map(d => - isNumber(d) ? + semanticDiagnosticsPerFile: buildInfo.program.semanticDiagnosticsPerFile?.map(d => ts.isNumber(d) ? toFileName(d) : - [toFileName(d[0]), d[1]] - ), + [toFileName(d[0]), d[1]]), affectedFilesPendingEmit: buildInfo.program.affectedFilesPendingEmit?.map(([fileId, emitKind]) => [ toFileName(fileId), - emitKind === BuilderFileEmit.DtsOnly ? "DtsOnly" : - emitKind === BuilderFileEmit.Full ? "Full" : - Debug.assertNever(emitKind) + emitKind === ts.BuilderFileEmit.DtsOnly ? "DtsOnly" : + emitKind === ts.BuilderFileEmit.Full ? "Full" : + ts.Debug.assertNever(emitKind) ]), }; const version = buildInfo.version === ts.version ? fakes.version : buildInfo.version; @@ -237,22 +243,23 @@ interface Symbol { bundle: buildInfo.bundle, program, version, - size: getBuildInfoText({ ...buildInfo, version }).length, + size: ts.getBuildInfoText({ ...buildInfo, version }).length, }; // For now its just JSON.stringify sys.writeFile(`${buildInfoPath}.readable.baseline.txt`, JSON.stringify(result, /*replacer*/ undefined, 2)); - function toFileName(fileId: ProgramBuildInfoFileId) { + function toFileName(fileId: ts.ProgramBuildInfoFileId) { return buildInfo.program!.fileNames[fileId - 1]; } - function toFileNames(fileIdsListId: ProgramBuildInfoFileIdListId) { + function toFileNames(fileIdsListId: ts.ProgramBuildInfoFileIdListId) { return fileNamesList![fileIdsListId - 1]; } - function toMapOfReferencedSet(referenceMap: ProgramBuildInfoReferencedMap | undefined): MapLike | undefined { - if (!referenceMap) return undefined; - const result: MapLike = {}; + function toMapOfReferencedSet(referenceMap: ts.ProgramBuildInfoReferencedMap | undefined): ts.MapLike | undefined { + if (!referenceMap) + return undefined; + const result: ts.MapLike = {}; for (const [fileNamesKey, fileNamesListKey] of referenceMap) { result[toFileName(fileNamesKey)] = toFileNames(fileNamesListKey); } @@ -260,26 +267,24 @@ interface Symbol { } } - export function toPathWithSystem(sys: System, fileName: string): Path { - return toPath(fileName, sys.getCurrentDirectory(), createGetCanonicalFileName(sys.useCaseSensitiveFileNames)); + export function toPathWithSystem(sys: ts.System, fileName: string): ts.Path { + return ts.toPath(fileName, sys.getCurrentDirectory(), ts.createGetCanonicalFileName(sys.useCaseSensitiveFileNames)); } - - export function baselineBuildInfo( - options: CompilerOptions, - sys: TscCompileSystem | tscWatch.WatchedSystem, - originalReadCall?: System["readFile"], - ) { - const buildInfoPath = getTsBuildInfoEmitOutputFilePath(options); - if (!buildInfoPath || !sys.writtenFiles!.has(toPathWithSystem(sys, buildInfoPath))) return; - if (!sys.fileExists(buildInfoPath)) return; - - const buildInfo = getBuildInfo((originalReadCall || sys.readFile).call(sys, buildInfoPath, "utf8")!); + export function baselineBuildInfo(options: ts.CompilerOptions, sys: ts.TscCompileSystem | ts.tscWatch.WatchedSystem, originalReadCall?: ts.System["readFile"]) { + const buildInfoPath = ts.getTsBuildInfoEmitOutputFilePath(options); + if (!buildInfoPath || !sys.writtenFiles!.has(toPathWithSystem(sys, buildInfoPath))) + return; + if (!sys.fileExists(buildInfoPath)) + return; + const buildInfo = ts.getBuildInfo((originalReadCall || sys.readFile).call(sys, buildInfoPath, "utf8")!); generateBuildInfoProgramBaseline(sys, buildInfoPath, buildInfo); - if (!outFile(options)) return; - const { jsFilePath, declarationFilePath } = getOutputPathsForBundle(options, /*forceDts*/ false); + if (!ts.outFile(options)) + return; + const { jsFilePath, declarationFilePath } = ts.getOutputPathsForBundle(options, /*forceDts*/ false); const bundle = buildInfo.bundle; - if (!bundle || (!length(bundle.js && bundle.js.sections) && !length(bundle.dts && bundle.dts.sections))) return; + if (!bundle || (!ts.length(bundle.js && bundle.js.sections) && !ts.length(bundle.dts && bundle.dts.sections))) + return; // Write the baselines: const baselineRecorder = new Harness.Compiler.WriterAggregator(); @@ -291,43 +296,42 @@ interface Symbol { } interface VerifyTscEditDiscrepanciesInput { index: number; - scenario: TestTscCompile["scenario"]; - subScenario: TestTscCompile["subScenario"]; + scenario: ts.TestTscCompile["scenario"]; + subScenario: ts.TestTscCompile["subScenario"]; baselines: string[] | undefined; - commandLineArgs: TestTscCompile["commandLineArgs"]; - modifyFs: TestTscCompile["modifyFs"]; + commandLineArgs: ts.TestTscCompile["commandLineArgs"]; + modifyFs: ts.TestTscCompile["modifyFs"]; editFs: TestTscEdit["modifyFs"]; baseFs: vfs.FileSystem; - newSys: TscCompileSystem; + newSys: ts.TscCompileSystem; discrepancyExplanation: TestTscEdit["discrepancyExplanation"]; } - function verifyTscEditDiscrepancies({ - index, scenario, subScenario, commandLineArgs, - discrepancyExplanation, baselines, - modifyFs, editFs, baseFs, newSys - }: VerifyTscEditDiscrepanciesInput): string[] | undefined { - const sys = testTscCompile({ + function verifyTscEditDiscrepancies({ index, scenario, subScenario, commandLineArgs, discrepancyExplanation, baselines, modifyFs, editFs, baseFs, newSys }: VerifyTscEditDiscrepanciesInput): string[] | undefined { + const sys = ts.testTscCompile({ scenario, subScenario, fs: () => baseFs.makeReadonly(), commandLineArgs, modifyFs: fs => { - if (modifyFs) modifyFs(fs); + if (modifyFs) + modifyFs(fs); editFs(fs); }, disableUseFileVersionAsSignature: true, }); let headerAdded = false; - for (const outputFile of arrayFrom(sys.writtenFiles.keys())) { + for (const outputFile of ts.arrayFrom(sys.writtenFiles.keys())) { const cleanBuildText = sys.readFile(outputFile); const incrementalBuildText = newSys.readFile(outputFile); - if (isBuildInfoFile(outputFile)) { + if (ts.isBuildInfoFile(outputFile)) { // Check only presence and absence and not text as we will do that for readable baseline - if (!sys.fileExists(`${outputFile}.readable.baseline.txt`)) addBaseline(`Readable baseline not present in clean build:: File:: ${outputFile}`); - if (!newSys.fileExists(`${outputFile}.readable.baseline.txt`)) addBaseline(`Readable baseline not present in incremental build:: File:: ${outputFile}`); + if (!sys.fileExists(`${outputFile}.readable.baseline.txt`)) + addBaseline(`Readable baseline not present in clean build:: File:: ${outputFile}`); + if (!newSys.fileExists(`${outputFile}.readable.baseline.txt`)) + addBaseline(`Readable baseline not present in incremental build:: File:: ${outputFile}`); verifyPresenceAbsence(incrementalBuildText, cleanBuildText, `Incremental and clean tsbuildinfo file presence differs:: File:: ${outputFile}`); } - else if (!fileExtensionIs(outputFile, ".tsbuildinfo.readable.baseline.txt")) { + else if (!ts.fileExtensionIs(outputFile, ".tsbuildinfo.readable.baseline.txt")) { verifyTextEqual(incrementalBuildText, cleanBuildText, `File: ${outputFile}`); } else if (incrementalBuildText !== cleanBuildText) { @@ -336,10 +340,7 @@ interface Symbol { const { buildInfo: cleanBuildInfo, readableBuildInfo: cleanReadableBuildInfo } = getBuildInfoForIncrementalCorrectnessCheck(cleanBuildText); verifyTextEqual(incrementalBuildInfo, cleanBuildInfo, `TsBuild info text without affectedFilesPendingEmit:: ${outputFile}::`); // Verify file info sigantures - verifyMapLike( - incrementalReadableBuildInfo?.program?.fileInfos, - cleanReadableBuildInfo?.program?.fileInfos, - (key, incrementalFileInfo, cleanFileInfo) => { + verifyMapLike(incrementalReadableBuildInfo?.program?.fileInfos, cleanReadableBuildInfo?.program?.fileInfos, (key, incrementalFileInfo, cleanFileInfo) => { if (incrementalFileInfo.signature !== cleanFileInfo.signature && incrementalFileInfo.signature !== incrementalFileInfo.version) { return [ `Incremental signature is neither dts signature nor file version for File:: ${key}`, @@ -347,15 +348,10 @@ interface Symbol { `Clean:: ${JSON.stringify(cleanFileInfo, /*replacer*/ undefined, 2)}` ]; } - }, - `FileInfos:: File:: ${outputFile}` - ); + }, `FileInfos:: File:: ${outputFile}`); // Verify exportedModulesMap - verifyMapLike( - incrementalReadableBuildInfo?.program?.exportedModulesMap, - cleanReadableBuildInfo?.program?.exportedModulesMap, - (key, incrementalReferenceSet, cleanReferenceSet) => { - if (!arrayIsEqualTo(incrementalReferenceSet, cleanReferenceSet) && !arrayIsEqualTo(incrementalReferenceSet, incrementalReadableBuildInfo!.program!.referencedMap![key])) { + verifyMapLike(incrementalReadableBuildInfo?.program?.exportedModulesMap, cleanReadableBuildInfo?.program?.exportedModulesMap, (key, incrementalReferenceSet, cleanReferenceSet) => { + if (!ts.arrayIsEqualTo(incrementalReferenceSet, cleanReferenceSet) && !ts.arrayIsEqualTo(incrementalReferenceSet, incrementalReadableBuildInfo!.program!.referencedMap![key])) { return [ `Incremental Reference set is neither from dts nor files reference map for File:: ${key}::`, `Incremental:: ${JSON.stringify(incrementalReferenceSet, /*replacer*/ undefined, 2)}`, @@ -364,87 +360,69 @@ interface Symbol { `CleanReferenceMap:: ${JSON.stringify(cleanReadableBuildInfo!.program!.referencedMap![key], /*replacer*/ undefined, 2)}`, ]; } - }, - `exportedModulesMap:: File:: ${outputFile}` - ); + }, `exportedModulesMap:: File:: ${outputFile}`); // Verify that incrementally pending affected file emit are in clean build since clean build can contain more files compared to incremental depending of noEmitOnError option if (incrementalReadableBuildInfo?.program?.affectedFilesPendingEmit) { if (cleanReadableBuildInfo?.program?.affectedFilesPendingEmit === undefined) { - addBaseline( - `Incremental build contains affectedFilesPendingEmit, clean build does not have it: ${outputFile}::`, - `Incremental buildInfoText:: ${incrementalBuildText}`, - `Clean buildInfoText:: ${cleanBuildText}` - ); + addBaseline(`Incremental build contains affectedFilesPendingEmit, clean build does not have it: ${outputFile}::`, `Incremental buildInfoText:: ${incrementalBuildText}`, `Clean buildInfoText:: ${cleanBuildText}`); } let expectedIndex = 0; incrementalReadableBuildInfo.program.affectedFilesPendingEmit.forEach(([actualFile]) => { - expectedIndex = findIndex(cleanReadableBuildInfo!.program!.affectedFilesPendingEmit!, ([expectedFile]) => actualFile === expectedFile, expectedIndex); + expectedIndex = ts.findIndex(cleanReadableBuildInfo!.program!.affectedFilesPendingEmit!, ([expectedFile]) => actualFile === expectedFile, expectedIndex); if (expectedIndex === -1) { - addBaseline( - `Incremental build contains ${actualFile} file as pending emit, clean build does not have it: ${outputFile}::`, - `Incremental buildInfoText:: ${incrementalBuildText}`, - `Clean buildInfoText:: ${cleanBuildText}` - ); + addBaseline(`Incremental build contains ${actualFile} file as pending emit, clean build does not have it: ${outputFile}::`, `Incremental buildInfoText:: ${incrementalBuildText}`, `Clean buildInfoText:: ${cleanBuildText}`); } expectedIndex++; }); } } } - if (!headerAdded && discrepancyExplanation) addBaseline("*** Supplied discrepancy explanation but didnt file any difference"); + if (!headerAdded && discrepancyExplanation) + addBaseline("*** Supplied discrepancy explanation but didnt file any difference"); return baselines; function verifyTextEqual(incrementalText: string | undefined, cleanText: string | undefined, message: string) { - if (incrementalText !== cleanText) writeNotEqual(incrementalText, cleanText, message); + if (incrementalText !== cleanText) + writeNotEqual(incrementalText, cleanText, message); } - function verifyMapLike(incremental: MapLike | undefined, clean: MapLike | undefined, verifyValue: (key: string, incrementalValue: T, cleanValue: T) => string[] | undefined, message: string) { + function verifyMapLike(incremental: ts.MapLike | undefined, clean: ts.MapLike | undefined, verifyValue: (key: string, incrementalValue: T, cleanValue: T) => string[] | undefined, message: string) { verifyPresenceAbsence(incremental, clean, `Incremental and clean do not match:: ${message}`); - if (!incremental || !clean) return; - const incrementalMap = new Map(getEntries(incremental)); - const cleanMap = new Map(getEntries(clean)); + if (!incremental || !clean) + return; + const incrementalMap = new ts.Map(ts.getEntries(incremental)); + const cleanMap = new ts.Map(ts.getEntries(clean)); if (incrementalMap.size !== cleanMap.size) { - addBaseline( - `Incremental and clean size of maps do not match:: ${message}`, - `Incremental: ${JSON.stringify(incremental, /*replacer*/ undefined, 2)}`, - `Clean: ${JSON.stringify(clean, /*replacer*/ undefined, 2)}`, - ); + addBaseline(`Incremental and clean size of maps do not match:: ${message}`, `Incremental: ${JSON.stringify(incremental, /*replacer*/ undefined, 2)}`, `Clean: ${JSON.stringify(clean, /*replacer*/ undefined, 2)}`); return; } cleanMap.forEach((cleanValue, key) => { const incrementalValue = incrementalMap.get(key); if (!incrementalValue) { - addBaseline( - `Incremental does not contain ${key} which is present in clean:: ${message}`, - `Incremental: ${JSON.stringify(incremental, /*replacer*/ undefined, 2)}`, - `Clean: ${JSON.stringify(clean, /*replacer*/ undefined, 2)}`, - ); + addBaseline(`Incremental does not contain ${key} which is present in clean:: ${message}`, `Incremental: ${JSON.stringify(incremental, /*replacer*/ undefined, 2)}`, `Clean: ${JSON.stringify(clean, /*replacer*/ undefined, 2)}`); } else { const result = verifyValue(key, incrementalMap.get(key)!, cleanValue); - if (result) addBaseline(...result); + if (result) + addBaseline(...result); } }); } function verifyPresenceAbsence(actual: T | undefined, expected: T | undefined, message: string) { if (expected === undefined) { - if (actual === undefined) return; + if (actual === undefined) + return; } else { - if (actual !== undefined) return; + if (actual !== undefined) + return; } writeNotEqual(actual, expected, message); } function writeNotEqual(actual: T | undefined, expected: T | undefined, message: string) { - addBaseline( - message, - "CleanBuild:", - isString(expected) ? expected : JSON.stringify(expected), - "IncrementalBuild:", - isString(actual) ? actual : JSON.stringify(actual), - ); + addBaseline(message, "CleanBuild:", ts.isString(expected) ? expected : JSON.stringify(expected), "IncrementalBuild:", ts.isString(actual) ? actual : JSON.stringify(actual)); } function addBaseline(...text: string[]) { @@ -460,13 +438,14 @@ interface Symbol { buildInfo: string | undefined; readableBuildInfo?: ReadableBuildInfo; } { - if (!text) return { buildInfo: text }; + if (!text) + return { buildInfo: text }; const readableBuildInfo = JSON.parse(text) as ReadableBuildInfo; - let sanitizedFileInfos: MapLike | undefined; + let sanitizedFileInfos: ts.MapLike | undefined; if (readableBuildInfo.program?.fileInfos) { sanitizedFileInfos = {}; for (const id in readableBuildInfo.program.fileInfos) { - if (hasProperty(readableBuildInfo.program.fileInfos, id)) { + if (ts.hasProperty(readableBuildInfo.program.fileInfos, id)) { sanitizedFileInfos[id] = { ...readableBuildInfo.program.fileInfos[id], signature: undefined }; } } @@ -492,7 +471,7 @@ interface Symbol { export enum CleanBuildDescrepancy { CleanFileTextDifferent, - CleanFilePresent, + CleanFilePresent } export interface TestTscEdit { @@ -503,26 +482,22 @@ interface Symbol { discrepancyExplanation?: () => readonly string[]; } - export interface VerifyTscWithEditsInput extends TestTscCompile { + export interface VerifyTscWithEditsInput extends ts.TestTscCompile { edits: TestTscEdit[]; } /** * Verify non watch tsc invokcation after each edit */ - export function verifyTscWithEdits({ - subScenario, fs, scenario, commandLineArgs, - baselineSourceMap, modifyFs, baselineReadFileCalls, baselinePrograms, - edits - }: VerifyTscWithEditsInput) { + export function verifyTscWithEdits({ subScenario, fs, scenario, commandLineArgs, baselineSourceMap, modifyFs, baselineReadFileCalls, baselinePrograms, edits }: VerifyTscWithEditsInput) { describe(`tsc ${commandLineArgs.join(" ")} ${scenario}:: ${subScenario} serializedEdits`, () => { - let sys: TscCompileSystem; + let sys: ts.TscCompileSystem; let baseFs: vfs.FileSystem; - let editsSys: TscCompileSystem[]; + let editsSys: ts.TscCompileSystem[]; before(() => { - Debug.assert(!!edits.length, `${scenario}/${subScenario}:: No incremental scenarios, you probably want to use verifyTsc instead.`); + ts.Debug.assert(!!edits.length, `${scenario}/${subScenario}:: No incremental scenarios, you probably want to use verifyTsc instead.`); baseFs = fs().makeReadonly(); - sys = testTscCompile({ + sys = ts.testTscCompile({ scenario, subScenario, fs: () => baseFs, @@ -532,11 +507,8 @@ interface Symbol { baselineReadFileCalls, baselinePrograms }); - edits.forEach(( - { modifyFs, subScenario: editScenario, commandLineArgs: editCommandLineArgs }, - index - ) => { - (editsSys || (editsSys = [])).push(testTscCompile({ + edits.forEach(({ modifyFs, subScenario: editScenario, commandLineArgs: editCommandLineArgs }, index) => { + (editsSys || (editsSys = [])).push(ts.testTscCompile({ scenario, subScenario: editScenario || subScenario, diffWithInitial: true, @@ -554,7 +526,7 @@ interface Symbol { sys = undefined!; editsSys = undefined!; }); - verifyTscBaseline(() => ({ + ts.verifyTscBaseline(() => ({ baseLine: () => { const { file, text } = sys.baseLine(); const texts: string[] = [text]; @@ -587,9 +559,7 @@ interface Symbol { modifyFs }); } - Harness.Baseline.runBaseline( - `${isBuild(commandLineArgs) ? "tsbuild" : "tsc"}/${scenario}/${subScenario.split(" ").join("-")}-discrepancies.js`, - baselines ? baselines.join("\r\n") : null // eslint-disable-line no-null/no-null + Harness.Baseline.runBaseline(`${ts.isBuild(commandLineArgs) ? "tsbuild" : "tsc"}/${scenario}/${subScenario.split(" ").join("-")}-discrepancies.js`, baselines ? baselines.join("\r\n") : null // eslint-disable-line no-null/no-null ); }); }); diff --git a/src/testRunner/unittests/tsbuild/inferredTypeFromTransitiveModule.ts b/src/testRunner/unittests/tsbuild/inferredTypeFromTransitiveModule.ts index 2f8cc57d11175..bb897438dfe75 100644 --- a/src/testRunner/unittests/tsbuild/inferredTypeFromTransitiveModule.ts +++ b/src/testRunner/unittests/tsbuild/inferredTypeFromTransitiveModule.ts @@ -2,13 +2,13 @@ namespace ts { describe("unittests:: tsbuild:: inferredTypeFromTransitiveModule::", () => { let projFs: vfs.FileSystem; before(() => { - projFs = loadProjectFromDisk("tests/projects/inferredTypeFromTransitiveModule"); + projFs = ts.loadProjectFromDisk("tests/projects/inferredTypeFromTransitiveModule"); }); after(() => { projFs = undefined!; }); - verifyTscWithEdits({ + ts.verifyTscWithEdits({ scenario: "inferredTypeFromTransitiveModule", subScenario: "inferred type from transitive module", fs: () => projFs, @@ -25,7 +25,7 @@ namespace ts { ], }); - verifyTscWithEdits({ + ts.verifyTscWithEdits({ subScenario: "inferred type from transitive module with isolatedModules", fs: () => projFs, scenario: "inferredTypeFromTransitiveModule", @@ -43,14 +43,14 @@ namespace ts { ] }); - verifyTscWithEdits({ + ts.verifyTscWithEdits({ scenario: "inferredTypeFromTransitiveModule", subScenario: "reports errors in files affected by change in signature with isolatedModules", fs: () => projFs, commandLineArgs: ["--b", "/src", "--verbose"], modifyFs: fs => { changeToIsolatedModules(fs); - appendText(fs, "/src/lazyIndex.ts", ` + ts.appendText(fs, "/src/lazyIndex.ts", ` import { default as bar } from './bar'; bar("hello");`); }, @@ -69,21 +69,21 @@ bar("hello");`); }, { subScenario: "Fix Error", - modifyFs: fs => replaceText(fs, "/src/lazyIndex.ts", `bar("hello")`, "bar()") + modifyFs: fs => ts.replaceText(fs, "/src/lazyIndex.ts", `bar("hello")`, "bar()") }, ] }); }); function changeToIsolatedModules(fs: vfs.FileSystem) { - replaceText(fs, "/src/tsconfig.json", `"incremental": true`, `"incremental": true, "isolatedModules": true`); + ts.replaceText(fs, "/src/tsconfig.json", `"incremental": true`, `"incremental": true, "isolatedModules": true`); } function changeBarParam(fs: vfs.FileSystem) { - replaceText(fs, "/src/bar.ts", "param: string", ""); + ts.replaceText(fs, "/src/bar.ts", "param: string", ""); } function changeBarParamBack(fs: vfs.FileSystem) { - replaceText(fs, "/src/bar.ts", "foobar()", "foobar(param: string)"); + ts.replaceText(fs, "/src/bar.ts", "foobar()", "foobar(param: string)"); } } diff --git a/src/testRunner/unittests/tsbuild/javascriptProjectEmit.ts b/src/testRunner/unittests/tsbuild/javascriptProjectEmit.ts index 6a0f6d5bc156c..9b5c626ad8b07 100644 --- a/src/testRunner/unittests/tsbuild/javascriptProjectEmit.ts +++ b/src/testRunner/unittests/tsbuild/javascriptProjectEmit.ts @@ -1,9 +1,9 @@ namespace ts { describe("unittests:: tsbuild:: javascriptProjectEmit::", () => { - verifyTsc({ + ts.verifyTsc({ scenario: "javascriptProjectEmit", subScenario: `loads js-based projects and emits them correctly`, - fs: () => loadProjectFromFiles({ + fs: () => ts.loadProjectFromFiles({ "/src/common/nominal.js": Utils.dedent` /** * @template T, Name @@ -84,14 +84,14 @@ namespace ts { "declaration": true } }`, - }, symbolLibContent), + }, ts.symbolLibContent), commandLineArgs: ["-b", "/src"] }); - verifyTscWithEdits({ + ts.verifyTscWithEdits({ scenario: "javascriptProjectEmit", subScenario: `modifies outfile js projects and concatenates them correctly`, - fs: () => loadProjectFromFiles({ + fs: () => ts.loadProjectFromFiles({ "/src/common/nominal.js": Utils.dedent` /** * @template T, Name @@ -174,18 +174,18 @@ namespace ts { "declaration": true } }`, - }, symbolLibContent), + }, ts.symbolLibContent), commandLineArgs: ["-b", "/src"], edits: [{ subScenario: "incremental-declaration-doesnt-change", - modifyFs: fs => replaceText(fs, "/src/sub-project/index.js", "null", "undefined") + modifyFs: fs => ts.replaceText(fs, "/src/sub-project/index.js", "null", "undefined") }] }); - verifyTsc({ + ts.verifyTsc({ scenario: "javascriptProjectEmit", subScenario: `loads js-based projects with non-moved json files and emits them correctly`, - fs: () => loadProjectFromFiles({ + fs: () => ts.loadProjectFromFiles({ "/src/common/obj.json": Utils.dedent` { "val": 42 @@ -265,7 +265,7 @@ namespace ts { "declaration": true } }`, - }, symbolLibContent), + }, ts.symbolLibContent), commandLineArgs: ["-b", "/src"] }); }); diff --git a/src/testRunner/unittests/tsbuild/lateBoundSymbol.ts b/src/testRunner/unittests/tsbuild/lateBoundSymbol.ts index aeb075f5ab501..85a1b344c8831 100644 --- a/src/testRunner/unittests/tsbuild/lateBoundSymbol.ts +++ b/src/testRunner/unittests/tsbuild/lateBoundSymbol.ts @@ -1,18 +1,18 @@ namespace ts { describe("unittests:: tsbuild:: lateBoundSymbol:: interface is merged and contains late bound member", () => { - verifyTscWithEdits({ + ts.verifyTscWithEdits({ subScenario: "interface is merged and contains late bound member", - fs: () => loadProjectFromDisk("tests/projects/lateBoundSymbol"), + fs: () => ts.loadProjectFromDisk("tests/projects/lateBoundSymbol"), scenario: "lateBoundSymbol", commandLineArgs: ["--b", "/src/tsconfig.json", "--verbose"], edits: [ { subScenario: "incremental-declaration-doesnt-change", - modifyFs: fs => replaceText(fs, "/src/src/main.ts", "const x = 10;", ""), + modifyFs: fs => ts.replaceText(fs, "/src/src/main.ts", "const x = 10;", ""), }, { subScenario: "incremental-declaration-doesnt-change", - modifyFs: fs => appendText(fs, "/src/src/main.ts", "const x = 10;"), + modifyFs: fs => ts.appendText(fs, "/src/src/main.ts", "const x = 10;"), }, ] }); diff --git a/src/testRunner/unittests/tsbuild/moduleResolution.ts b/src/testRunner/unittests/tsbuild/moduleResolution.ts index 10508b92404fd..320e77163e1fd 100644 --- a/src/testRunner/unittests/tsbuild/moduleResolution.ts +++ b/src/testRunner/unittests/tsbuild/moduleResolution.ts @@ -1,30 +1,30 @@ namespace ts.tscWatch { describe("unittests:: tsbuild:: moduleResolution:: handles the modules and options from referenced project correctly", () => { - function sys(optionsToExtend?: CompilerOptions) { - return createWatchedSystem([ + function sys(optionsToExtend?: ts.CompilerOptions) { + return ts.tscWatch.createWatchedSystem([ { - path: `${projectRoot}/packages/pkg1/index.ts`, + path: `${ts.tscWatch.projectRoot}/packages/pkg1/index.ts`, content: Utils.dedent` import type { TheNum } from 'pkg2' export const theNum: TheNum = 42;` }, { - path: `${projectRoot}/packages/pkg1/tsconfig.json`, + path: `${ts.tscWatch.projectRoot}/packages/pkg1/tsconfig.json`, content: JSON.stringify({ compilerOptions: { outDir: "build", ...optionsToExtend }, references: [{ path: "../pkg2" }] }) }, { - path: `${projectRoot}/packages/pkg2/const.ts`, + path: `${ts.tscWatch.projectRoot}/packages/pkg2/const.ts`, content: `export type TheNum = 42;` }, { - path: `${projectRoot}/packages/pkg2/index.ts`, + path: `${ts.tscWatch.projectRoot}/packages/pkg2/index.ts`, content: `export type { TheNum } from 'const';` }, { - path: `${projectRoot}/packages/pkg2/tsconfig.json`, + path: `${ts.tscWatch.projectRoot}/packages/pkg2/tsconfig.json`, content: JSON.stringify({ compilerOptions: { composite: true, @@ -35,7 +35,7 @@ namespace ts.tscWatch { }) }, { - path: `${projectRoot}/packages/pkg2/package.json`, + path: `${ts.tscWatch.projectRoot}/packages/pkg2/package.json`, content: JSON.stringify({ name: "pkg2", version: "1.0.0", @@ -43,35 +43,35 @@ namespace ts.tscWatch { }) }, { - path: `${projectRoot}/node_modules/pkg2`, - symLink: `${projectRoot}/packages/pkg2`, + path: `${ts.tscWatch.projectRoot}/node_modules/pkg2`, + symLink: `${ts.tscWatch.projectRoot}/packages/pkg2`, }, - libFile - ], { currentDirectory: projectRoot }); + ts.tscWatch.libFile + ], { currentDirectory: ts.tscWatch.projectRoot }); } - verifyTscWatch({ + ts.tscWatch.verifyTscWatch({ scenario: "moduleResolution", subScenario: `resolves specifier in output declaration file from referenced project correctly`, sys, commandLineArgs: ["-b", "packages/pkg1", "--verbose", "--traceResolution"], - changes: emptyArray + changes: ts.emptyArray }); - verifyTscWatch({ + ts.tscWatch.verifyTscWatch({ scenario: "moduleResolution", subScenario: `resolves specifier in output declaration file from referenced project correctly with preserveSymlinks`, sys: () => sys({ preserveSymlinks: true }), commandLineArgs: ["-b", "packages/pkg1", "--verbose", "--traceResolution"], - changes: emptyArray + changes: ts.emptyArray }); - verifyTscWatch({ + ts.tscWatch.verifyTscWatch({ scenario: "moduleResolution", subScenario: `resolves specifier in output declaration file from referenced project correctly with cts and mts extensions`, - sys: () => createWatchedSystem([ + sys: () => ts.tscWatch.createWatchedSystem([ { - path: `${projectRoot}/packages/pkg1/package.json`, + path: `${ts.tscWatch.projectRoot}/packages/pkg1/package.json`, content: JSON.stringify({ name: "pkg1", version: "1.0.0", @@ -80,13 +80,13 @@ namespace ts.tscWatch { }) }, { - path: `${projectRoot}/packages/pkg1/index.ts`, + path: `${ts.tscWatch.projectRoot}/packages/pkg1/index.ts`, content: Utils.dedent` import type { TheNum } from 'pkg2' export const theNum: TheNum = 42;` }, { - path: `${projectRoot}/packages/pkg1/tsconfig.json`, + path: `${ts.tscWatch.projectRoot}/packages/pkg1/tsconfig.json`, content: JSON.stringify({ compilerOptions: { outDir: "build", @@ -96,15 +96,15 @@ namespace ts.tscWatch { }) }, { - path: `${projectRoot}/packages/pkg2/const.cts`, + path: `${ts.tscWatch.projectRoot}/packages/pkg2/const.cts`, content: `export type TheNum = 42;` }, { - path: `${projectRoot}/packages/pkg2/index.ts`, + path: `${ts.tscWatch.projectRoot}/packages/pkg2/index.ts`, content: `export type { TheNum } from './const.cjs';` }, { - path: `${projectRoot}/packages/pkg2/tsconfig.json`, + path: `${ts.tscWatch.projectRoot}/packages/pkg2/tsconfig.json`, content: JSON.stringify({ compilerOptions: { composite: true, @@ -114,7 +114,7 @@ namespace ts.tscWatch { }) }, { - path: `${projectRoot}/packages/pkg2/package.json`, + path: `${ts.tscWatch.projectRoot}/packages/pkg2/package.json`, content: JSON.stringify({ name: "pkg2", version: "1.0.0", @@ -123,43 +123,43 @@ namespace ts.tscWatch { }) }, { - path: `${projectRoot}/node_modules/pkg2`, - symLink: `${projectRoot}/packages/pkg2`, + path: `${ts.tscWatch.projectRoot}/node_modules/pkg2`, + symLink: `${ts.tscWatch.projectRoot}/packages/pkg2`, }, - { ...libFile, path: `/a/lib/lib.es2022.full.d.ts` } - ], { currentDirectory: projectRoot }), + { ...ts.tscWatch.libFile, path: `/a/lib/lib.es2022.full.d.ts` } + ], { currentDirectory: ts.tscWatch.projectRoot }), commandLineArgs: ["-b", "packages/pkg1", "-w", "--verbose", "--traceResolution"], changes: [ { caption: "reports import errors after change to package file", - change: sys => replaceFileText(sys, `${projectRoot}/packages/pkg1/package.json`, `"module"`, `"commonjs"`), - timeouts: runQueuedTimeoutCallbacks, + change: sys => ts.tscWatch.replaceFileText(sys, `${ts.tscWatch.projectRoot}/packages/pkg1/package.json`, `"module"`, `"commonjs"`), + timeouts: ts.tscWatch.runQueuedTimeoutCallbacks, }, { caption: "removes those errors when a package file is changed back", - change: sys => replaceFileText(sys, `${projectRoot}/packages/pkg1/package.json`, `"commonjs"`, `"module"`), - timeouts: runQueuedTimeoutCallbacks, + change: sys => ts.tscWatch.replaceFileText(sys, `${ts.tscWatch.projectRoot}/packages/pkg1/package.json`, `"commonjs"`, `"module"`), + timeouts: ts.tscWatch.runQueuedTimeoutCallbacks, }, { caption: "reports import errors after change to package file", - change: sys => replaceFileText(sys, `${projectRoot}/packages/pkg1/package.json`, `"module"`, `"commonjs"`), - timeouts: runQueuedTimeoutCallbacks, + change: sys => ts.tscWatch.replaceFileText(sys, `${ts.tscWatch.projectRoot}/packages/pkg1/package.json`, `"module"`, `"commonjs"`), + timeouts: ts.tscWatch.runQueuedTimeoutCallbacks, }, { caption: "removes those errors when a package file is changed to cjs extensions", change: sys => { - replaceFileText(sys, `${projectRoot}/packages/pkg2/package.json`, `"build/index.js"`, `"build/index.cjs"`); - sys.renameFile(`${projectRoot}/packages/pkg2/index.ts`, `${projectRoot}/packages/pkg2/index.cts`); + ts.tscWatch.replaceFileText(sys, `${ts.tscWatch.projectRoot}/packages/pkg2/package.json`, `"build/index.js"`, `"build/index.cjs"`); + sys.renameFile(`${ts.tscWatch.projectRoot}/packages/pkg2/index.ts`, `${ts.tscWatch.projectRoot}/packages/pkg2/index.cts`); }, - timeouts: runQueuedTimeoutCallbacks, + timeouts: ts.tscWatch.runQueuedTimeoutCallbacks, }, ] }); - verifyTsc({ + ts.verifyTsc({ scenario: "moduleResolution", subScenario: `type reference resolution uses correct options for different resolution options referenced project`, - fs: () => loadProjectFromFiles({ + fs: () => ts.loadProjectFromFiles({ "/src/packages/pkg1_index.ts": `export const theNum: TheNum = "type1";`, "/src/packages/pkg1.tsconfig.json": JSON.stringify({ compilerOptions: { composite: true, typeRoots: ["./typeroot1"] }, @@ -176,12 +176,12 @@ namespace ts.tscWatch { commandLineArgs: ["-b", "/src/packages/pkg1.tsconfig.json", "/src/packages/pkg2.tsconfig.json", "--verbose", "--traceResolution"], }); - verifyTscWatch({ + ts.tscWatch.verifyTscWatch({ scenario: "moduleResolution", subScenario: `watches for changes to package-json main fields`, - sys: () => createWatchedSystem([ + sys: () => ts.tscWatch.createWatchedSystem([ { - path: `${projectRoot}/packages/pkg1/package.json`, + path: `${ts.tscWatch.projectRoot}/packages/pkg1/package.json`, content: JSON.stringify({ name: "pkg1", version: "1.0.0", @@ -189,13 +189,13 @@ namespace ts.tscWatch { }) }, { - path: `${projectRoot}/packages/pkg1/index.ts`, + path: `${ts.tscWatch.projectRoot}/packages/pkg1/index.ts`, content: Utils.dedent` import type { TheNum } from 'pkg2' export const theNum: TheNum = 42;` }, { - path: `${projectRoot}/packages/pkg1/tsconfig.json`, + path: `${ts.tscWatch.projectRoot}/packages/pkg1/tsconfig.json`, content: JSON.stringify({ compilerOptions: { outDir: "build", @@ -203,19 +203,19 @@ namespace ts.tscWatch { }) }, { - path: `${projectRoot}/packages/pkg2/build/const.d.ts`, + path: `${ts.tscWatch.projectRoot}/packages/pkg2/build/const.d.ts`, content: `export type TheNum = 42;` }, { - path: `${projectRoot}/packages/pkg2/build/index.d.ts`, + path: `${ts.tscWatch.projectRoot}/packages/pkg2/build/index.d.ts`, content: `export type { TheNum } from './const.js';` }, { - path: `${projectRoot}/packages/pkg2/build/other.d.ts`, + path: `${ts.tscWatch.projectRoot}/packages/pkg2/build/other.d.ts`, content: `export type TheStr = string;` }, { - path: `${projectRoot}/packages/pkg2/package.json`, + path: `${ts.tscWatch.projectRoot}/packages/pkg2/package.json`, content: JSON.stringify({ name: "pkg2", version: "1.0.0", @@ -223,33 +223,33 @@ namespace ts.tscWatch { }) }, { - path: `${projectRoot}/node_modules/pkg2`, - symLink: `${projectRoot}/packages/pkg2`, + path: `${ts.tscWatch.projectRoot}/node_modules/pkg2`, + symLink: `${ts.tscWatch.projectRoot}/packages/pkg2`, }, - libFile - ], { currentDirectory: projectRoot }), + ts.tscWatch.libFile + ], { currentDirectory: ts.tscWatch.projectRoot }), commandLineArgs: ["--project", "./packages/pkg1/tsconfig.json", "-w", "--traceResolution"], changes: [ { caption: "reports import errors after change to package file", - change: sys => replaceFileText(sys, `${projectRoot}/packages/pkg2/package.json`, `index.js`, `other.js`), - timeouts: runQueuedTimeoutCallbacks, + change: sys => ts.tscWatch.replaceFileText(sys, `${ts.tscWatch.projectRoot}/packages/pkg2/package.json`, `index.js`, `other.js`), + timeouts: ts.tscWatch.runQueuedTimeoutCallbacks, }, { caption: "removes those errors when a package file is changed back", - change: sys => replaceFileText(sys, `${projectRoot}/packages/pkg2/package.json`, `other.js`, `index.js`), - timeouts: runQueuedTimeoutCallbacks, + change: sys => ts.tscWatch.replaceFileText(sys, `${ts.tscWatch.projectRoot}/packages/pkg2/package.json`, `other.js`, `index.js`), + timeouts: ts.tscWatch.runQueuedTimeoutCallbacks, }, ] }); - verifyTscWatch({ + ts.tscWatch.verifyTscWatch({ scenario: "moduleResolution", subScenario: `build mode watches for changes to package-json main fields`, - sys: () => createWatchedSystem([ + sys: () => ts.tscWatch.createWatchedSystem([ { - path: `${projectRoot}/packages/pkg1/package.json`, + path: `${ts.tscWatch.projectRoot}/packages/pkg1/package.json`, content: JSON.stringify({ name: "pkg1", version: "1.0.0", @@ -257,13 +257,13 @@ namespace ts.tscWatch { }) }, { - path: `${projectRoot}/packages/pkg1/index.ts`, + path: `${ts.tscWatch.projectRoot}/packages/pkg1/index.ts`, content: Utils.dedent` import type { TheNum } from 'pkg2' export const theNum: TheNum = 42;` }, { - path: `${projectRoot}/packages/pkg1/tsconfig.json`, + path: `${ts.tscWatch.projectRoot}/packages/pkg1/tsconfig.json`, content: JSON.stringify({ compilerOptions: { outDir: "build", @@ -272,7 +272,7 @@ namespace ts.tscWatch { }) }, { - path: `${projectRoot}/packages/pkg2/tsconfig.json`, + path: `${ts.tscWatch.projectRoot}/packages/pkg2/tsconfig.json`, content: JSON.stringify({ compilerOptions: { composite: true, @@ -282,19 +282,19 @@ namespace ts.tscWatch { }) }, { - path: `${projectRoot}/packages/pkg2/const.ts`, + path: `${ts.tscWatch.projectRoot}/packages/pkg2/const.ts`, content: `export type TheNum = 42;` }, { - path: `${projectRoot}/packages/pkg2/index.ts`, + path: `${ts.tscWatch.projectRoot}/packages/pkg2/index.ts`, content: `export type { TheNum } from './const.js';` }, { - path: `${projectRoot}/packages/pkg2/other.ts`, + path: `${ts.tscWatch.projectRoot}/packages/pkg2/other.ts`, content: `export type TheStr = string;` }, { - path: `${projectRoot}/packages/pkg2/package.json`, + path: `${ts.tscWatch.projectRoot}/packages/pkg2/package.json`, content: JSON.stringify({ name: "pkg2", version: "1.0.0", @@ -302,22 +302,22 @@ namespace ts.tscWatch { }) }, { - path: `${projectRoot}/node_modules/pkg2`, - symLink: `${projectRoot}/packages/pkg2`, + path: `${ts.tscWatch.projectRoot}/node_modules/pkg2`, + symLink: `${ts.tscWatch.projectRoot}/packages/pkg2`, }, - libFile - ], { currentDirectory: projectRoot }), + ts.tscWatch.libFile + ], { currentDirectory: ts.tscWatch.projectRoot }), commandLineArgs: ["-b", "packages/pkg1", "--verbose", "-w", "--traceResolution"], changes: [ { caption: "reports import errors after change to package file", - change: sys => replaceFileText(sys, `${projectRoot}/packages/pkg2/package.json`, `index.js`, `other.js`), - timeouts: runQueuedTimeoutCallbacks, + change: sys => ts.tscWatch.replaceFileText(sys, `${ts.tscWatch.projectRoot}/packages/pkg2/package.json`, `index.js`, `other.js`), + timeouts: ts.tscWatch.runQueuedTimeoutCallbacks, }, { caption: "removes those errors when a package file is changed back", - change: sys => replaceFileText(sys, `${projectRoot}/packages/pkg2/package.json`, `other.js`, `index.js`), - timeouts: runQueuedTimeoutCallbacks, + change: sys => ts.tscWatch.replaceFileText(sys, `${ts.tscWatch.projectRoot}/packages/pkg2/package.json`, `other.js`, `index.js`), + timeouts: ts.tscWatch.runQueuedTimeoutCallbacks, }, ] }); diff --git a/src/testRunner/unittests/tsbuild/moduleSpecifiers.ts b/src/testRunner/unittests/tsbuild/moduleSpecifiers.ts index d8caa8997e784..e11f48140032a 100644 --- a/src/testRunner/unittests/tsbuild/moduleSpecifiers.ts +++ b/src/testRunner/unittests/tsbuild/moduleSpecifiers.ts @@ -1,10 +1,10 @@ namespace ts { // https://github.com/microsoft/TypeScript/issues/31696 describe("unittests:: tsbuild:: moduleSpecifiers:: synthesized module specifiers to referenced projects resolve correctly", () => { - verifyTsc({ + ts.verifyTsc({ scenario: "moduleSpecifiers", subScenario: `synthesized module specifiers resolve correctly`, - fs: () => loadProjectFromFiles({ + fs: () => ts.loadProjectFromFiles({ "/src/solution/common/nominal.ts": Utils.dedent` export declare type Nominal = T & { [Symbol.species]: Name; @@ -84,17 +84,17 @@ namespace ts { ], "include": [] }` - }, symbolLibContent), + }, ts.symbolLibContent), commandLineArgs: ["-b", "/src", "--verbose"] }); }); // https://github.com/microsoft/TypeScript/issues/44434 but with `module: node16`, some `exports` maps blocking direct access, and no `baseUrl` describe("unittests:: tsbuild:: moduleSpecifiers:: synthesized module specifiers across referenced projects resolve correctly", () => { - verifyTsc({ + ts.verifyTsc({ scenario: "moduleSpecifiers", subScenario: `synthesized module specifiers across projects resolve correctly`, - fs: () => loadProjectFromFiles({ + fs: () => ts.loadProjectFromFiles({ "/src/src-types/index.ts": Utils.dedent` export * from './dogconfig.js';`, "/src/src-types/dogconfig.ts": Utils.dedent` @@ -178,7 +178,7 @@ namespace ts { }`, }, ""), modifyFs: fs => { - fs.writeFileSync("/lib/lib.es2022.full.d.ts", tscWatch.libFile.content); + fs.writeFileSync("/lib/lib.es2022.full.d.ts", ts.tscWatch.libFile.content); fs.symlinkSync("/src", "/src/src-types/node_modules"); fs.symlinkSync("/src", "/src/src-dogs/node_modules"); }, diff --git a/src/testRunner/unittests/tsbuild/noEmitOnError.ts b/src/testRunner/unittests/tsbuild/noEmitOnError.ts index f1aa1ac17c090..4943b2e6928ca 100644 --- a/src/testRunner/unittests/tsbuild/noEmitOnError.ts +++ b/src/testRunner/unittests/tsbuild/noEmitOnError.ts @@ -2,19 +2,19 @@ namespace ts { describe("unittests:: tsbuild - with noEmitOnError", () => { let projFs: vfs.FileSystem; before(() => { - projFs = loadProjectFromDisk("tests/projects/noEmitOnError"); + projFs = ts.loadProjectFromDisk("tests/projects/noEmitOnError"); }); after(() => { projFs = undefined!; }); - verifyTscWithEdits({ + ts.verifyTscWithEdits({ scenario: "noEmitOnError", subScenario: "syntax errors", fs: () => projFs, commandLineArgs: ["--b", "/src/tsconfig.json"], edits: [ - noChangeRun, + ts.noChangeRun, { subScenario: "Fix error", modifyFs: fs => fs.writeFileSync("/src/src/main.ts", `import { A } from "../shared/types/db"; @@ -22,32 +22,32 @@ const a = { lastName: 'sdsd' };`, "utf-8"), }, - noChangeRun, + ts.noChangeRun, ], baselinePrograms: true, }); - verifyTscWithEdits({ + ts.verifyTscWithEdits({ scenario: "noEmitOnError", subScenario: "syntax errors with incremental", fs: () => projFs, commandLineArgs: ["--b", "/src/tsconfig.json", "--incremental"], edits: [ - noChangeRun, + ts.noChangeRun, { subScenario: "Fix error", modifyFs: fs => fs.writeFileSync("/src/src/main.ts", `import { A } from "../shared/types/db"; const a = { lastName: 'sdsd' };`, "utf-8"), - discrepancyExplanation: noChangeWithExportsDiscrepancyRun.discrepancyExplanation, + discrepancyExplanation: ts.noChangeWithExportsDiscrepancyRun.discrepancyExplanation, }, - noChangeWithExportsDiscrepancyRun, + ts.noChangeWithExportsDiscrepancyRun, ], baselinePrograms: true, }); - verifyTscWithEdits({ + ts.verifyTscWithEdits({ scenario: "noEmitOnError", subScenario: "semantic errors", fs: () => projFs, @@ -55,18 +55,18 @@ const a = { const a: string = 10;`, "utf-8"), commandLineArgs: ["--b", "/src/tsconfig.json"], edits: [ - noChangeRun, + ts.noChangeRun, { subScenario: "Fix error", modifyFs: fs => fs.writeFileSync("/src/src/main.ts", `import { A } from "../shared/types/db"; const a: string = "hello";`, "utf-8"), }, - noChangeRun, + ts.noChangeRun, ], baselinePrograms: true, }); - verifyTscWithEdits({ + ts.verifyTscWithEdits({ scenario: "noEmitOnError", subScenario: "semantic errors with incremental", fs: () => projFs, @@ -74,13 +74,13 @@ const a: string = "hello";`, "utf-8"), const a: string = 10;`, "utf-8"), commandLineArgs: ["--b", "/src/tsconfig.json", "--incremental"], edits: [ - noChangeWithExportsDiscrepancyRun, + ts.noChangeWithExportsDiscrepancyRun, { subScenario: "Fix error", modifyFs: fs => fs.writeFileSync("/src/src/main.ts", `import { A } from "../shared/types/db"; const a: string = "hello";`, "utf-8"), }, - noChangeRun, + ts.noChangeRun, ], baselinePrograms: true, }); diff --git a/src/testRunner/unittests/tsbuild/outFile.ts b/src/testRunner/unittests/tsbuild/outFile.ts index 109ab200c69ef..23f3ce47149fd 100644 --- a/src/testRunner/unittests/tsbuild/outFile.ts +++ b/src/testRunner/unittests/tsbuild/outFile.ts @@ -3,7 +3,7 @@ namespace ts { let outFileFs: vfs.FileSystem; let outFileWithBuildFs: vfs.FileSystem; before(() => { - outFileFs = loadProjectFromDisk("tests/projects/outfile-concat"); + outFileFs = ts.loadProjectFromDisk("tests/projects/outfile-concat"); }); after(() => { outFileFs = undefined!; @@ -20,26 +20,18 @@ namespace ts { additionalCommandLineArgs?: string[]; } - function verifyOutFileScenario({ - subScenario, - modifyFs, - modifyAgainFs, - ignoreDtsChanged, - ignoreDtsUnchanged, - baselineOnly, - additionalCommandLineArgs, - }: VerifyOutFileScenarioInput) { - const edits: TestTscEdit[] = []; + function verifyOutFileScenario({ subScenario, modifyFs, modifyAgainFs, ignoreDtsChanged, ignoreDtsUnchanged, baselineOnly, additionalCommandLineArgs, }: VerifyOutFileScenarioInput) { + const edits: ts.TestTscEdit[] = []; if (!ignoreDtsChanged) { edits.push({ subScenario: "incremental-declaration-changes", - modifyFs: fs => replaceText(fs, "/src/first/first_PART1.ts", "Hello", "Hola"), + modifyFs: fs => ts.replaceText(fs, "/src/first/first_PART1.ts", "Hello", "Hola"), }); } if (!ignoreDtsUnchanged) { edits.push({ subScenario: "incremental-declaration-doesnt-change", - modifyFs: fs => appendText(fs, "/src/first/first_PART1.ts", "console.log(s);"), + modifyFs: fs => ts.appendText(fs, "/src/first/first_PART1.ts", "console.log(s);"), }); } if (modifyAgainFs) { @@ -48,7 +40,7 @@ namespace ts { modifyFs: modifyAgainFs }); } - const input: VerifyTscWithEditsInput = { + const input: ts.VerifyTscWithEditsInput = { subScenario, fs: () => outFileFs, scenario: "outfile-concat", @@ -59,8 +51,8 @@ namespace ts { edits, }; return edits.length ? - verifyTscWithEdits(input) : - verifyTsc(input); + ts.verifyTscWithEdits(input) : + ts.verifyTsc(input); } // Verify initial + incremental edits @@ -77,7 +69,7 @@ namespace ts { // Verify baseline with build info + dts unChanged verifyOutFileScenario({ subScenario: "when final project is not composite but uses project references", - modifyFs: fs => replaceText(fs, "/src/third/tsconfig.json", `"composite": true,`, ""), + modifyFs: fs => ts.replaceText(fs, "/src/third/tsconfig.json", `"composite": true,`, ""), ignoreDtsChanged: true, baselineOnly: true }); @@ -85,7 +77,7 @@ namespace ts { // Verify baseline with build info verifyOutFileScenario({ subScenario: "when final project is not composite but incremental", - modifyFs: fs => replaceText(fs, "/src/third/tsconfig.json", `"composite": true,`, `"incremental": true,`), + modifyFs: fs => ts.replaceText(fs, "/src/third/tsconfig.json", `"composite": true,`, `"incremental": true,`), ignoreDtsChanged: true, ignoreDtsUnchanged: true, baselineOnly: true @@ -94,7 +86,7 @@ namespace ts { // Verify baseline with build info verifyOutFileScenario({ subScenario: "when final project specifies tsBuildInfoFile", - modifyFs: fs => replaceText(fs, "/src/third/tsconfig.json", `"composite": true,`, `"composite": true, + modifyFs: fs => ts.replaceText(fs, "/src/third/tsconfig.json", `"composite": true,`, `"composite": true, "tsBuildInfoFile": "./thirdjs/output/third.tsbuildinfo",`), ignoreDtsChanged: true, ignoreDtsUnchanged: true, @@ -102,25 +94,26 @@ namespace ts { }); function getOutFileFsAfterBuild() { - if (outFileWithBuildFs) return outFileWithBuildFs; + if (outFileWithBuildFs) + return outFileWithBuildFs; const fs = outFileFs.shadow(); const sys = new fakes.System(fs, { executingFilePath: "/lib/tsc" }); - const host = createSolutionBuilderHostForBaseline(sys as TscCompileSystem); - const builder = createSolutionBuilder(host, ["/src/third"], { dry: false, force: false, verbose: true }); + const host = ts.createSolutionBuilderHostForBaseline(sys as ts.TscCompileSystem); + const builder = ts.createSolutionBuilder(host, ["/src/third"], { dry: false, force: false, verbose: true }); builder.build(); fs.makeReadonly(); return outFileWithBuildFs = fs; } - verifyTscWithEdits({ + ts.verifyTscWithEdits({ scenario: "outFile", subScenario: "clean projects", fs: getOutFileFsAfterBuild, commandLineArgs: ["--b", "/src/third", "--clean"], - edits: noChangeOnlyRuns + edits: ts.noChangeOnlyRuns }); - verifyTsc({ + ts.verifyTsc({ scenario: "outFile", subScenario: "verify buildInfo absence results in new build", fs: getOutFileFsAfterBuild, @@ -128,69 +121,69 @@ namespace ts { modifyFs: fs => fs.unlinkSync("/src/first/bin/first-output.tsbuildinfo"), }); - verifyTsc({ + ts.verifyTsc({ scenario: "outFile", subScenario: "tsbuildinfo is not generated when incremental is set to false", fs: () => outFileFs, commandLineArgs: ["--b", "/src/third", "--verbose"], - modifyFs: fs => replaceText(fs, "/src/third/tsconfig.json", `"composite": true,`, ""), + modifyFs: fs => ts.replaceText(fs, "/src/third/tsconfig.json", `"composite": true,`, ""), }); - verifyTscCompileLike(testTscCompileLike, { + ts.verifyTscCompileLike(ts.testTscCompileLike, { scenario: "outFile", subScenario: "rebuilds completely when version in tsbuildinfo doesnt match ts version", fs: getOutFileFsAfterBuild, commandLineArgs: ["--b", "/src/third", "--verbose"], compile: sys => { // Buildinfo will have version which does not match with current ts version - const buildHost = createSolutionBuilderHostForBaseline(sys, "FakeTSCurrentVersion"); - const builder = createSolutionBuilder(buildHost, ["/src/third"], { verbose: true }); + const buildHost = ts.createSolutionBuilderHostForBaseline(sys, "FakeTSCurrentVersion"); + const builder = ts.createSolutionBuilder(buildHost, ["/src/third"], { verbose: true }); sys.exit(builder.build()); } }); - verifyTscWithEdits({ + ts.verifyTscWithEdits({ scenario: "outFile", subScenario: "rebuilds completely when command line incremental flag changes between non dts changes", fs: () => outFileFs, // Make non composite third project - modifyFs: fs => replaceText(fs, "/src/third/tsconfig.json", `"composite": true,`, ""), + modifyFs: fs => ts.replaceText(fs, "/src/third/tsconfig.json", `"composite": true,`, ""), // Build with command line incremental commandLineArgs: ["--b", "/src/third", "--i", "--verbose"], edits: [ { subScenario: "Make non incremental build with change in file that doesnt affect dts", - modifyFs: fs => appendText(fs, "/src/first/first_PART1.ts", "console.log(s);"), + modifyFs: fs => ts.appendText(fs, "/src/first/first_PART1.ts", "console.log(s);"), commandLineArgs: ["--b", "/src/third", "--verbose"], }, { subScenario: "Make incremental build with change in file that doesnt affect dts", - modifyFs: fs => appendText(fs, "/src/first/first_PART1.ts", "console.log(s);"), + modifyFs: fs => ts.appendText(fs, "/src/first/first_PART1.ts", "console.log(s);"), commandLineArgs: ["--b", "/src/third", "--verbose", "--incremental"], } ] }); - verifyTscCompileLike(testTscCompileLike, { + ts.verifyTscCompileLike(ts.testTscCompileLike, { scenario: "outFile", subScenario: "builds till project specified", fs: () => outFileFs, commandLineArgs: ["--build", "/src/second/tsconfig.json"], compile: sys => { - const buildHost = createSolutionBuilderHostForBaseline(sys); - const builder = createSolutionBuilder(buildHost, ["/src/third/tsconfig.json"], {}); + const buildHost = ts.createSolutionBuilderHostForBaseline(sys); + const builder = ts.createSolutionBuilder(buildHost, ["/src/third/tsconfig.json"], {}); sys.exit(builder.build("/src/second/tsconfig.json")); } }); - verifyTscCompileLike(testTscCompileLike, { + ts.verifyTscCompileLike(ts.testTscCompileLike, { scenario: "outFile", subScenario: "cleans till project specified", fs: getOutFileFsAfterBuild, commandLineArgs: ["--build", "--clean", "/src/second/tsconfig.json"], compile: sys => { - const buildHost = createSolutionBuilderHostForBaseline(sys); - const builder = createSolutionBuilder(buildHost, ["/src/third/tsconfig.json"], { verbose: true }); + const buildHost = ts.createSolutionBuilderHostForBaseline(sys); + const builder = ts.createSolutionBuilder(buildHost, ["/src/third/tsconfig.json"], { verbose: true }); sys.exit(builder.clean("/src/second/tsconfig.json")); } }); @@ -202,18 +195,18 @@ namespace ts { verifyOutFileScenario({ subScenario: "strict in all projects", modifyFs: fs => { - enableStrict(fs, "/src/first/tsconfig.json"); - enableStrict(fs, "/src/second/tsconfig.json"); - enableStrict(fs, "/src/third/tsconfig.json"); + ts.enableStrict(fs, "/src/first/tsconfig.json"); + ts.enableStrict(fs, "/src/second/tsconfig.json"); + ts.enableStrict(fs, "/src/third/tsconfig.json"); }, - modifyAgainFs: fs => addTestPrologue(fs, "/src/first/first_PART1.ts", `"myPrologue"`) + modifyAgainFs: fs => ts.addTestPrologue(fs, "/src/first/first_PART1.ts", `"myPrologue"`) }); // Verify ignore dtsChanged verifyOutFileScenario({ subScenario: "strict in one dependency", - modifyFs: fs => enableStrict(fs, "/src/second/tsconfig.json"), - modifyAgainFs: fs => addTestPrologue(fs, "src/first/first_PART1.ts", `"myPrologue"`), + modifyFs: fs => ts.enableStrict(fs, "/src/second/tsconfig.json"), + modifyAgainFs: fs => ts.addTestPrologue(fs, "src/first/first_PART1.ts", `"myPrologue"`), ignoreDtsChanged: true, baselineOnly: true }); @@ -222,28 +215,28 @@ namespace ts { verifyOutFileScenario({ subScenario: "multiple prologues in all projects", modifyFs: fs => { - enableStrict(fs, "/src/first/tsconfig.json"); - addTestPrologue(fs, "/src/first/first_PART1.ts", `"myPrologue"`); - enableStrict(fs, "/src/second/tsconfig.json"); - addTestPrologue(fs, "/src/second/second_part1.ts", `"myPrologue"`); - addTestPrologue(fs, "/src/second/second_part2.ts", `"myPrologue2";`); - enableStrict(fs, "/src/third/tsconfig.json"); - addTestPrologue(fs, "/src/third/third_part1.ts", `"myPrologue";`); - addTestPrologue(fs, "/src/third/third_part1.ts", `"myPrologue3";`); + ts.enableStrict(fs, "/src/first/tsconfig.json"); + ts.addTestPrologue(fs, "/src/first/first_PART1.ts", `"myPrologue"`); + ts.enableStrict(fs, "/src/second/tsconfig.json"); + ts.addTestPrologue(fs, "/src/second/second_part1.ts", `"myPrologue"`); + ts.addTestPrologue(fs, "/src/second/second_part2.ts", `"myPrologue2";`); + ts.enableStrict(fs, "/src/third/tsconfig.json"); + ts.addTestPrologue(fs, "/src/third/third_part1.ts", `"myPrologue";`); + ts.addTestPrologue(fs, "/src/third/third_part1.ts", `"myPrologue3";`); }, - modifyAgainFs: fs => addTestPrologue(fs, "/src/first/first_PART1.ts", `"myPrologue5"`) + modifyAgainFs: fs => ts.addTestPrologue(fs, "/src/first/first_PART1.ts", `"myPrologue5"`) }); // Verify ignore dtsChanged verifyOutFileScenario({ subScenario: "multiple prologues in different projects", modifyFs: fs => { - enableStrict(fs, "/src/first/tsconfig.json"); - addTestPrologue(fs, "/src/second/second_part1.ts", `"myPrologue"`); - addTestPrologue(fs, "/src/second/second_part2.ts", `"myPrologue2";`); - enableStrict(fs, "/src/third/tsconfig.json"); + ts.enableStrict(fs, "/src/first/tsconfig.json"); + ts.addTestPrologue(fs, "/src/second/second_part1.ts", `"myPrologue"`); + ts.addTestPrologue(fs, "/src/second/second_part2.ts", `"myPrologue2";`); + ts.enableStrict(fs, "/src/third/tsconfig.json"); }, - modifyAgainFs: fs => addTestPrologue(fs, "/src/first/first_PART1.ts", `"myPrologue5"`), + modifyAgainFs: fs => ts.addTestPrologue(fs, "/src/first/first_PART1.ts", `"myPrologue5"`), ignoreDtsChanged: true, baselineOnly: true }); @@ -256,17 +249,17 @@ namespace ts { verifyOutFileScenario({ subScenario: "shebang in all projects", modifyFs: fs => { - addShebang(fs, "first", "first_PART1"); - addShebang(fs, "first", "first_part2"); - addShebang(fs, "second", "second_part1"); - addShebang(fs, "third", "third_part1"); + ts.addShebang(fs, "first", "first_PART1"); + ts.addShebang(fs, "first", "first_part2"); + ts.addShebang(fs, "second", "second_part1"); + ts.addShebang(fs, "third", "third_part1"); }, }); // Verify ignore dtsChanged verifyOutFileScenario({ subScenario: "shebang in only one dependency project", - modifyFs: fs => addShebang(fs, "second", "second_part1"), + modifyFs: fs => ts.addShebang(fs, "second", "second_part1"), ignoreDtsChanged: true, baselineOnly: true }); @@ -278,21 +271,21 @@ namespace ts { verifyOutFileScenario({ subScenario: "emitHelpers in all projects", modifyFs: fs => { - addRest(fs, "first", "first_PART1"); - addRest(fs, "second", "second_part1"); - addRest(fs, "third", "third_part1"); + ts.addRest(fs, "first", "first_PART1"); + ts.addRest(fs, "second", "second_part1"); + ts.addRest(fs, "third", "third_part1"); }, - modifyAgainFs: fs => removeRest(fs, "first", "first_PART1") + modifyAgainFs: fs => ts.removeRest(fs, "first", "first_PART1") }); // Verify ignore dtsChanged verifyOutFileScenario({ subScenario: "emitHelpers in only one dependency project", modifyFs: fs => { - addStubFoo(fs, "first", "first_PART1"); - addRest(fs, "second", "second_part1"); + ts.addStubFoo(fs, "first", "first_PART1"); + ts.addRest(fs, "second", "second_part1"); }, - modifyAgainFs: fs => changeStubToRest(fs, "first", "first_PART1"), + modifyAgainFs: fs => ts.changeStubToRest(fs, "first", "first_PART1"), ignoreDtsChanged: true, baselineOnly: true }); @@ -301,14 +294,14 @@ namespace ts { verifyOutFileScenario({ subScenario: "multiple emitHelpers in all projects", modifyFs: fs => { - addRest(fs, "first", "first_PART1"); - addSpread(fs, "first", "first_part3"); - addRest(fs, "second", "second_part1"); - addSpread(fs, "second", "second_part2"); - addRest(fs, "third", "third_part1"); - addSpread(fs, "third", "third_part1"); + ts.addRest(fs, "first", "first_PART1"); + ts.addSpread(fs, "first", "first_part3"); + ts.addRest(fs, "second", "second_part1"); + ts.addSpread(fs, "second", "second_part2"); + ts.addRest(fs, "third", "third_part1"); + ts.addSpread(fs, "third", "third_part1"); }, - modifyAgainFs: fs => removeRest(fs, "first", "first_PART1"), + modifyAgainFs: fs => ts.removeRest(fs, "first", "first_PART1"), ignoreDtsChanged: true, baselineOnly: true }); @@ -317,11 +310,11 @@ namespace ts { verifyOutFileScenario({ subScenario: "multiple emitHelpers in different projects", modifyFs: fs => { - addRest(fs, "first", "first_PART1"); - addSpread(fs, "second", "second_part1"); - addRest(fs, "third", "third_part1"); + ts.addRest(fs, "first", "first_PART1"); + ts.addSpread(fs, "second", "second_part1"); + ts.addRest(fs, "third", "third_part1"); }, - modifyAgainFs: fs => removeRest(fs, "first", "first_PART1"), + modifyAgainFs: fs => ts.removeRest(fs, "first", "first_PART1"), ignoreDtsChanged: true, baselineOnly: true }); @@ -334,16 +327,16 @@ namespace ts { verifyOutFileScenario({ subScenario: "triple slash refs in all projects", modifyFs: fs => { - addTripleSlashRef(fs, "first", "first_part2"); - addTripleSlashRef(fs, "second", "second_part1"); - addTripleSlashRef(fs, "third", "third_part1"); + ts.addTripleSlashRef(fs, "first", "first_part2"); + ts.addTripleSlashRef(fs, "second", "second_part1"); + ts.addTripleSlashRef(fs, "third", "third_part1"); } }); // Verify ignore dtsChanged verifyOutFileScenario({ subScenario: "triple slash refs in one project", - modifyFs: fs => addTripleSlashRef(fs, "second", "second_part1"), + modifyFs: fs => ts.addTripleSlashRef(fs, "second", "second_part1"), ignoreDtsChanged: true, baselineOnly: true }); @@ -351,7 +344,7 @@ namespace ts { describe("stripInternal", () => { function disableRemoveComments(fs: vfs.FileSystem, file: string) { - replaceText(fs, file, `"removeComments": true`, `"removeComments": false`); + ts.replaceText(fs, file, `"removeComments": true`, `"removeComments": false`); } function diableRemoveCommentsInAll(fs: vfs.FileSystem) { @@ -361,7 +354,7 @@ namespace ts { } function stripInternalOfThird(fs: vfs.FileSystem) { - replaceText(fs, "/src/third/tsconfig.json", `"declaration": true,`, `"declaration": true, + ts.replaceText(fs, "/src/third/tsconfig.json", `"declaration": true,`, `"declaration": true, "stripInternal": true,`); } @@ -371,8 +364,8 @@ namespace ts { diableRemoveCommentsInAll(fs); } stripInternalOfThird(fs); - replaceText(fs, "/src/first/first_PART1.ts", "interface", `${internal} interface`); - appendText(fs, "/src/second/second_part1.ts", ` + ts.replaceText(fs, "/src/first/first_PART1.ts", "interface", `${internal} interface`); + ts.appendText(fs, "/src/second/second_part1.ts", ` class normalC { ${internal} constructor() { } ${internal} prop: string; @@ -404,14 +397,14 @@ ${internal} enum internalEnum { a, b, c }`); verifyOutFileScenario({ subScenario: "stripInternal", modifyFs: stripInternalScenario, - modifyAgainFs: fs => replaceText(fs, "/src/first/first_PART1.ts", `/*@internal*/ interface`, "interface"), + modifyAgainFs: fs => ts.replaceText(fs, "/src/first/first_PART1.ts", `/*@internal*/ interface`, "interface"), }); // Verify ignore dtsChanged verifyOutFileScenario({ subScenario: "stripInternal with comments emit enabled", modifyFs: fs => stripInternalScenario(fs, /*removeCommentsDisabled*/ true), - modifyAgainFs: fs => replaceText(fs, "/src/first/first_PART1.ts", `/*@internal*/ interface`, "interface"), + modifyAgainFs: fs => ts.replaceText(fs, "/src/first/first_PART1.ts", `/*@internal*/ interface`, "interface"), ignoreDtsChanged: true, baselineOnly: true }); @@ -420,7 +413,7 @@ ${internal} enum internalEnum { a, b, c }`); verifyOutFileScenario({ subScenario: "stripInternal jsdoc style comment", modifyFs: fs => stripInternalScenario(fs, /*removeCommentsDisabled*/ false, /*jsDocStyle*/ true), - modifyAgainFs: fs => replaceText(fs, "/src/first/first_PART1.ts", `/**@internal*/ interface`, "interface"), + modifyAgainFs: fs => ts.replaceText(fs, "/src/first/first_PART1.ts", `/**@internal*/ interface`, "interface"), ignoreDtsChanged: true, baselineOnly: true }); @@ -435,9 +428,9 @@ ${internal} enum internalEnum { a, b, c }`); describe("with three levels of project dependency", () => { function makeOneTwoThreeDependOrder(fs: vfs.FileSystem) { - replaceText(fs, "/src/second/tsconfig.json", "[", `[ + ts.replaceText(fs, "/src/second/tsconfig.json", "[", `[ { "path": "../first", "prepend": true }`); - replaceText(fs, "/src/third/tsconfig.json", `{ "path": "../first", "prepend": true },`, ""); + ts.replaceText(fs, "/src/third/tsconfig.json", `{ "path": "../first", "prepend": true },`, ""); } function stripInternalWithDependentOrder(fs: vfs.FileSystem, removeCommentsDisabled?: boolean, jsDocStyle?: boolean) { @@ -449,14 +442,14 @@ ${internal} enum internalEnum { a, b, c }`); verifyOutFileScenario({ subScenario: "stripInternal when one-two-three are prepended in order", modifyFs: stripInternalWithDependentOrder, - modifyAgainFs: fs => replaceText(fs, "/src/first/first_PART1.ts", `/*@internal*/ interface`, "interface"), + modifyAgainFs: fs => ts.replaceText(fs, "/src/first/first_PART1.ts", `/*@internal*/ interface`, "interface"), }); // Verify ignore dtsChanged verifyOutFileScenario({ subScenario: "stripInternal with comments emit enabled when one-two-three are prepended in order", modifyFs: fs => stripInternalWithDependentOrder(fs, /*removeCommentsDisabled*/ true), - modifyAgainFs: fs => replaceText(fs, "/src/first/first_PART1.ts", `/*@internal*/ interface`, "interface"), + modifyAgainFs: fs => ts.replaceText(fs, "/src/first/first_PART1.ts", `/*@internal*/ interface`, "interface"), ignoreDtsChanged: true, baselineOnly: true }); @@ -465,7 +458,7 @@ ${internal} enum internalEnum { a, b, c }`); verifyOutFileScenario({ subScenario: "stripInternal jsdoc style comment when one-two-three are prepended in order", modifyFs: fs => stripInternalWithDependentOrder(fs, /*removeCommentsDisabled*/ false, /*jsDocStyle*/ true), - modifyAgainFs: fs => replaceText(fs, "/src/first/first_PART1.ts", `/**@internal*/ interface`, "interface"), + modifyAgainFs: fs => ts.replaceText(fs, "/src/first/first_PART1.ts", `/**@internal*/ interface`, "interface"), ignoreDtsChanged: true, baselineOnly: true }); @@ -484,7 +477,7 @@ ${internal} enum internalEnum { a, b, c }`); subScenario: "stripInternal baseline when internal is inside another internal", modifyFs: fs => { stripInternalOfThird(fs); - prependText(fs, "/src/first/first_PART1.ts", `namespace ts { + ts.prependText(fs, "/src/first/first_PART1.ts", `namespace ts { /* @internal */ /** * Subset of properties from SourceFile that are used in multiple utility functions @@ -523,7 +516,7 @@ ${internal} enum internalEnum { a, b, c }`); subScenario: "stripInternal when few members of enum are internal", modifyFs: fs => { stripInternalOfThird(fs); - prependText(fs, "/src/first/first_PART1.ts", `enum TokenFlags { + ts.prependText(fs, "/src/first/first_PART1.ts", `enum TokenFlags { None = 0, /* @internal */ PrecedingLineBreak = 1 << 0, @@ -605,9 +598,9 @@ ${internal} enum internalEnum { a, b, c }`); subScenario: "declarationMap and sourceMap disabled", modifyFs: fs => { makeThirdEmptySourceFile(fs); - replaceText(fs, "/src/third/tsconfig.json", `"composite": true,`, ""); - replaceText(fs, "/src/third/tsconfig.json", `"sourceMap": true,`, ""); - replaceText(fs, "/src/third/tsconfig.json", `"declarationMap": true,`, ""); + ts.replaceText(fs, "/src/third/tsconfig.json", `"composite": true,`, ""); + ts.replaceText(fs, "/src/third/tsconfig.json", `"sourceMap": true,`, ""); + ts.replaceText(fs, "/src/third/tsconfig.json", `"declarationMap": true,`, ""); }, ignoreDtsChanged: true, ignoreDtsUnchanged: true, @@ -616,25 +609,25 @@ ${internal} enum internalEnum { a, b, c }`); }); }); - verifyTsc({ + ts.verifyTsc({ scenario: "outFile", subScenario: "non module projects without prepend", fs: () => outFileFs, commandLineArgs: ["--b", "/src/third", "--verbose"], modifyFs: fs => { // No prepend - replaceText(fs, "/src/third/tsconfig.json", `{ "path": "../first", "prepend": true }`, `{ "path": "../first" }`); - replaceText(fs, "/src/third/tsconfig.json", `{ "path": "../second", "prepend": true }`, `{ "path": "../second" }`); + ts.replaceText(fs, "/src/third/tsconfig.json", `{ "path": "../first", "prepend": true }`, `{ "path": "../first" }`); + ts.replaceText(fs, "/src/third/tsconfig.json", `{ "path": "../second", "prepend": true }`, `{ "path": "../second" }`); // Non Modules - replaceText(fs, "/src/first/tsconfig.json", `"composite": true,`, `"composite": true, "module": "none",`); - replaceText(fs, "/src/second/tsconfig.json", `"composite": true,`, `"composite": true, "module": "none",`); - replaceText(fs, "/src/third/tsconfig.json", `"composite": true,`, `"composite": true, "module": "none",`); + ts.replaceText(fs, "/src/first/tsconfig.json", `"composite": true,`, `"composite": true, "module": "none",`); + ts.replaceText(fs, "/src/second/tsconfig.json", `"composite": true,`, `"composite": true, "module": "none",`); + ts.replaceText(fs, "/src/third/tsconfig.json", `"composite": true,`, `"composite": true, "module": "none",`); // Own file emit - replaceText(fs, "/src/first/tsconfig.json", `"outFile": "./bin/first-output.js",`, ""); - replaceText(fs, "/src/second/tsconfig.json", `"outFile": "../2/second-output.js",`, ""); - replaceText(fs, "/src/third/tsconfig.json", `"outFile": "./thirdjs/output/third-output.js",`, ""); + ts.replaceText(fs, "/src/first/tsconfig.json", `"outFile": "./bin/first-output.js",`, ""); + ts.replaceText(fs, "/src/second/tsconfig.json", `"outFile": "../2/second-output.js",`, ""); + ts.replaceText(fs, "/src/third/tsconfig.json", `"outFile": "./thirdjs/output/third-output.js",`, ""); }, }); }); diff --git a/src/testRunner/unittests/tsbuild/outputPaths.ts b/src/testRunner/unittests/tsbuild/outputPaths.ts index 72374f846115f..881179bb06262 100644 --- a/src/testRunner/unittests/tsbuild/outputPaths.ts +++ b/src/testRunner/unittests/tsbuild/outputPaths.ts @@ -1,39 +1,33 @@ namespace ts { describe("unittests:: tsbuild - output file paths", () => { - const noChangeProject: TestTscEdit = { - modifyFs: noop, + const noChangeProject: ts.TestTscEdit = { + modifyFs: ts.noop, subScenario: "Normal build without change, that does not block emit on error to show files that get emitted", commandLineArgs: ["-p", "/src/tsconfig.json"], }; - const edits: TestTscEdit[] = [ - noChangeRun, + const edits: ts.TestTscEdit[] = [ + ts.noChangeRun, noChangeProject, ]; - function verify(input: Pick, expectedOuptutNames: readonly string[]) { - verifyTscWithEdits({ + function verify(input: Pick, expectedOuptutNames: readonly string[]) { + ts.verifyTscWithEdits({ scenario: "outputPaths", commandLineArgs: ["--b", "/src/tsconfig.json", "-v"], ...input }); it("verify getOutputFileNames", () => { - const sys = new fakes.System(input.fs().makeReadonly(), { executingFilePath: "/lib/tsc" }) as TscCompileSystem; + const sys = new fakes.System(input.fs().makeReadonly(), { executingFilePath: "/lib/tsc" }) as ts.TscCompileSystem; ; - assert.deepEqual( - getOutputFileNames( - parseConfigFileWithSystem("/src/tsconfig.json", {}, /*extendedConfigCache*/ undefined, {}, sys, noop)!, - "/src/src/index.ts", - /*ignoreCase*/ false - ), - expectedOuptutNames - ); + assert.deepEqual(ts.getOutputFileNames(ts.parseConfigFileWithSystem("/src/tsconfig.json", {}, /*extendedConfigCache*/ undefined, {}, sys, ts.noop)!, "/src/src/index.ts", + /*ignoreCase*/ false), expectedOuptutNames); }); } verify({ subScenario: "when rootDir is not specified", - fs: () => loadProjectFromFiles({ + fs: () => ts.loadProjectFromFiles({ "/src/src/index.ts": "export const x = 10;", "/src/tsconfig.json": JSON.stringify({ compilerOptions: { @@ -46,7 +40,7 @@ namespace ts { verify({ subScenario: "when rootDir is not specified and is composite", - fs: () => loadProjectFromFiles({ + fs: () => ts.loadProjectFromFiles({ "/src/src/index.ts": "export const x = 10;", "/src/tsconfig.json": JSON.stringify({ compilerOptions: { @@ -60,7 +54,7 @@ namespace ts { verify({ subScenario: "when rootDir is specified", - fs: () => loadProjectFromFiles({ + fs: () => ts.loadProjectFromFiles({ "/src/src/index.ts": "export const x = 10;", "/src/tsconfig.json": JSON.stringify({ compilerOptions: { @@ -74,7 +68,7 @@ namespace ts { verify({ subScenario: "when rootDir is specified but not all files belong to rootDir", - fs: () => loadProjectFromFiles({ + fs: () => ts.loadProjectFromFiles({ "/src/src/index.ts": "export const x = 10;", "/src/types/type.ts": "export type t = string;", "/src/tsconfig.json": JSON.stringify({ @@ -89,7 +83,7 @@ namespace ts { verify({ subScenario: "when rootDir is specified but not all files belong to rootDir and is composite", - fs: () => loadProjectFromFiles({ + fs: () => ts.loadProjectFromFiles({ "/src/src/index.ts": "export const x = 10;", "/src/types/type.ts": "export type t = string;", "/src/tsconfig.json": JSON.stringify({ diff --git a/src/testRunner/unittests/tsbuild/publicApi.ts b/src/testRunner/unittests/tsbuild/publicApi.ts index cb2d35ca9670f..4feb5d0d6e219 100644 --- a/src/testRunner/unittests/tsbuild/publicApi.ts +++ b/src/testRunner/unittests/tsbuild/publicApi.ts @@ -1,8 +1,8 @@ namespace ts { describe("unittests:: tsbuild:: Public API with custom transformers when passed to build", () => { - let sys: TscCompileSystem; + let sys: ts.TscCompileSystem; before(() => { - const inputFs = loadProjectFromFiles({ + const inputFs = ts.loadProjectFromFiles({ "/src/tsconfig.json": JSON.stringify({ references: [ { path: "./shared/tsconfig.json" }, @@ -33,35 +33,30 @@ export function f22() { } // trailing`, const fs = inputFs.shadow(); // Create system - sys = new fakes.System(fs, { executingFilePath: "/lib/tsc" }) as TscCompileSystem; + sys = new fakes.System(fs, { executingFilePath: "/lib/tsc" }) as ts.TscCompileSystem; fakes.patchHostForBuildInfoReadWrite(sys); const commandLineArgs = ["--b", "/src/tsconfig.json"]; sys.write(`${sys.getExecutingFilePath()} ${commandLineArgs.join(" ")}\n`); sys.exit = exitCode => sys.exitCode = exitCode; - const writtenFiles = sys.writtenFiles = new Set(); + const writtenFiles = sys.writtenFiles = new ts.Set(); const originalWriteFile = sys.writeFile; sys.writeFile = (fileName, content, writeByteOrderMark) => { - const path = toPathWithSystem(sys, fileName); + const path = ts.toPathWithSystem(sys, fileName); assert.isFalse(writtenFiles.has(path)); writtenFiles.add(path); return originalWriteFile.call(sys, fileName, content, writeByteOrderMark); }; - const { cb, getPrograms } = commandLineCallbacks(sys, /*originalReadCall*/ undefined); - const buildHost = createSolutionBuilderHost( - sys, - /*createProgram*/ undefined, - createDiagnosticReporter(sys, /*pretty*/ true), - createBuilderStatusReporter(sys, /*pretty*/ true), - (errorCount, filesInError) => sys.write(getErrorSummaryText(errorCount, filesInError, sys.newLine, sys)) - ); + const { cb, getPrograms } = ts.commandLineCallbacks(sys, /*originalReadCall*/ undefined); + const buildHost = ts.createSolutionBuilderHost(sys, + /*createProgram*/ undefined, ts.createDiagnosticReporter(sys, /*pretty*/ true), ts.createBuilderStatusReporter(sys, /*pretty*/ true), (errorCount, filesInError) => sys.write(ts.getErrorSummaryText(errorCount, filesInError, sys.newLine, sys))); buildHost.afterProgramEmitAndDiagnostics = cb; buildHost.afterEmitBundle = cb; - const builder = createSolutionBuilder(buildHost, [commandLineArgs[1]], { verbose: true }); + const builder = ts.createSolutionBuilder(buildHost, [commandLineArgs[1]], { verbose: true }); const exitStatus = builder.build(/*project*/ undefined, /*cancellationToken*/ undefined, /*writeFile*/ undefined, getCustomTransformers); sys.exit(exitStatus); - sys.write(`exitCode:: ExitStatus.${ExitStatus[sys.exitCode as ExitStatus]}\n`); + sys.write(`exitCode:: ExitStatus.${ts.ExitStatus[sys.exitCode as ts.ExitStatus]}\n`); const baseline: string[] = []; - tscWatch.baselinePrograms(baseline, getPrograms, emptyArray, /*baselineDependencies*/ false); + ts.tscWatch.baselinePrograms(baseline, getPrograms, ts.emptyArray, /*baselineDependencies*/ false); sys.write(baseline.join("\n")); fs.makeReadonly(); sys.baseLine = () => { @@ -79,35 +74,35 @@ ${patch ? vfs.formatPatch(patch) : ""}` }; }; - function getCustomTransformers(project: string): CustomTransformers { - const before: TransformerFactory = context => { - return file => visitEachChild(file, visit, context); - function visit(node: Node): VisitResult { + function getCustomTransformers(project: string): ts.CustomTransformers { + const before: ts.TransformerFactory = context => { + return file => ts.visitEachChild(file, visit, context); + function visit(node: ts.Node): ts.VisitResult { switch (node.kind) { - case SyntaxKind.FunctionDeclaration: - return visitFunction(node as FunctionDeclaration); + case ts.SyntaxKind.FunctionDeclaration: + return visitFunction(node as ts.FunctionDeclaration); default: - return visitEachChild(node, visit, context); + return ts.visitEachChild(node, visit, context); } } - function visitFunction(node: FunctionDeclaration) { - addSyntheticLeadingComment(node, SyntaxKind.MultiLineCommentTrivia, `@before${project}`, /*hasTrailingNewLine*/ true); + function visitFunction(node: ts.FunctionDeclaration) { + ts.addSyntheticLeadingComment(node, ts.SyntaxKind.MultiLineCommentTrivia, `@before${project}`, /*hasTrailingNewLine*/ true); return node; } }; - const after: TransformerFactory = context => { - return file => visitEachChild(file, visit, context); - function visit(node: Node): VisitResult { + const after: ts.TransformerFactory = context => { + return file => ts.visitEachChild(file, visit, context); + function visit(node: ts.Node): ts.VisitResult { switch (node.kind) { - case SyntaxKind.VariableStatement: - return visitVariableStatement(node as VariableStatement); + case ts.SyntaxKind.VariableStatement: + return visitVariableStatement(node as ts.VariableStatement); default: - return visitEachChild(node, visit, context); + return ts.visitEachChild(node, visit, context); } } - function visitVariableStatement(node: VariableStatement) { - addSyntheticLeadingComment(node, SyntaxKind.SingleLineCommentTrivia, `@after${project}`); + function visitVariableStatement(node: ts.VariableStatement) { + ts.addSyntheticLeadingComment(node, ts.SyntaxKind.SingleLineCommentTrivia, `@after${project}`); return node; } }; @@ -117,6 +112,6 @@ ${patch ? vfs.formatPatch(patch) : ""}` after(() => { sys = undefined!; }); - verifyTscBaseline(() => sys); + ts.verifyTscBaseline(() => sys); }); } diff --git a/src/testRunner/unittests/tsbuild/referencesWithRootDirInParent.ts b/src/testRunner/unittests/tsbuild/referencesWithRootDirInParent.ts index bd78954780aab..6504a43073b68 100644 --- a/src/testRunner/unittests/tsbuild/referencesWithRootDirInParent.ts +++ b/src/testRunner/unittests/tsbuild/referencesWithRootDirInParent.ts @@ -2,29 +2,29 @@ namespace ts { describe("unittests:: tsbuild:: with rootDir of project reference in parentDirectory", () => { let projFs: vfs.FileSystem; before(() => { - projFs = loadProjectFromDisk("tests/projects/projectReferenceWithRootDirInParent"); + projFs = ts.loadProjectFromDisk("tests/projects/projectReferenceWithRootDirInParent"); }); after(() => { projFs = undefined!; // Release the contents }); - verifyTsc({ + ts.verifyTsc({ scenario: "projectReferenceWithRootDirInParent", subScenario: "builds correctly", fs: () => projFs, commandLineArgs: ["--b", "/src/src/main", "/src/src/other"], }); - verifyTsc({ + ts.verifyTsc({ scenario: "projectReferenceWithRootDirInParent", subScenario: "reports error for same tsbuildinfo file because no rootDir in the base", fs: () => projFs, commandLineArgs: ["--b", "/src/src/main", "--verbose"], - modifyFs: fs => replaceText(fs, "/src/tsconfig.base.json", `"rootDir": "./src/",`, ""), + modifyFs: fs => ts.replaceText(fs, "/src/tsconfig.base.json", `"rootDir": "./src/",`, ""), }); - verifyTsc({ + ts.verifyTsc({ scenario: "projectReferenceWithRootDirInParent", subScenario: "reports error for same tsbuildinfo file", fs: () => projFs, @@ -40,7 +40,7 @@ namespace ts { }, }); - verifyTsc({ + ts.verifyTsc({ scenario: "projectReferenceWithRootDirInParent", subScenario: "reports no error when tsbuildinfo differ", fs: () => projFs, diff --git a/src/testRunner/unittests/tsbuild/resolveJsonModule.ts b/src/testRunner/unittests/tsbuild/resolveJsonModule.ts index 834d5825377f2..edd6eba1e27e7 100644 --- a/src/testRunner/unittests/tsbuild/resolveJsonModule.ts +++ b/src/testRunner/unittests/tsbuild/resolveJsonModule.ts @@ -2,28 +2,28 @@ namespace ts { describe("unittests:: tsbuild:: with resolveJsonModule option on project resolveJsonModuleAndComposite", () => { let projFs: vfs.FileSystem; before(() => { - projFs = loadProjectFromDisk("tests/projects/resolveJsonModuleAndComposite"); + projFs = ts.loadProjectFromDisk("tests/projects/resolveJsonModuleAndComposite"); }); after(() => { projFs = undefined!; // Release the contents }); - verifyTsc({ + ts.verifyTsc({ scenario: "resolveJsonModule", subScenario: "include only", fs: () => projFs, commandLineArgs: ["--b", "/src/tsconfig_withInclude.json", "--v", "--explainFiles"], }); - verifyTsc({ + ts.verifyTsc({ scenario: "resolveJsonModule", subScenario: "include of json along with other include", fs: () => projFs, commandLineArgs: ["--b", "/src/tsconfig_withIncludeOfJson.json", "--v", "--explainFiles"], }); - verifyTsc({ + ts.verifyTsc({ scenario: "resolveJsonModule", subScenario: "include of json along with other include and file name matches ts file", fs: () => projFs, @@ -37,46 +37,46 @@ export default hello.hello`); }, }); - verifyTsc({ + ts.verifyTsc({ scenario: "resolveJsonModule", subScenario: "files containing json file", fs: () => projFs, commandLineArgs: ["--b", "/src/tsconfig_withFiles.json", "--v", "--explainFiles"], }); - verifyTsc({ + ts.verifyTsc({ scenario: "resolveJsonModule", subScenario: "include and files", fs: () => projFs, commandLineArgs: ["--b", "/src/tsconfig_withIncludeAndFiles.json", "--v", "--explainFiles"], }); - verifyTscWithEdits({ + ts.verifyTscWithEdits({ scenario: "resolveJsonModule", subScenario: "sourcemap", fs: () => projFs, commandLineArgs: ["--b", "src/tsconfig_withFiles.json", "--verbose", "--explainFiles"], - modifyFs: fs => replaceText(fs, "src/tsconfig_withFiles.json", `"composite": true,`, `"composite": true, "sourceMap": true,`), - edits: noChangeOnlyRuns + modifyFs: fs => ts.replaceText(fs, "src/tsconfig_withFiles.json", `"composite": true,`, `"composite": true, "sourceMap": true,`), + edits: ts.noChangeOnlyRuns }); - verifyTscWithEdits({ + ts.verifyTscWithEdits({ scenario: "resolveJsonModule", subScenario: "without outDir", fs: () => projFs, commandLineArgs: ["--b", "src/tsconfig_withFiles.json", "--verbose"], - modifyFs: fs => replaceText(fs, "src/tsconfig_withFiles.json", `"outDir": "dist",`, ""), - edits: noChangeOnlyRuns + modifyFs: fs => ts.replaceText(fs, "src/tsconfig_withFiles.json", `"outDir": "dist",`, ""), + edits: ts.noChangeOnlyRuns }); }); describe("unittests:: tsbuild:: with resolveJsonModule option on project importJsonFromProjectReference", () => { - verifyTscWithEdits({ + ts.verifyTscWithEdits({ scenario: "resolveJsonModule", subScenario: "importing json module from project reference", - fs: () => loadProjectFromDisk("tests/projects/importJsonFromProjectReference"), + fs: () => ts.loadProjectFromDisk("tests/projects/importJsonFromProjectReference"), commandLineArgs: ["--b", "src/tsconfig.json", "--verbose", "--explainFiles"], - edits: noChangeOnlyRuns + edits: ts.noChangeOnlyRuns }); }); } diff --git a/src/testRunner/unittests/tsbuild/sample.ts b/src/testRunner/unittests/tsbuild/sample.ts index 2178c422ab9ea..82951bc5237bd 100644 --- a/src/testRunner/unittests/tsbuild/sample.ts +++ b/src/testRunner/unittests/tsbuild/sample.ts @@ -3,7 +3,7 @@ namespace ts { let projFs: vfs.FileSystem; let projFsWithBuild: vfs.FileSystem; before(() => { - projFs = loadProjectFromDisk("tests/projects/sample1"); + projFs = ts.loadProjectFromDisk("tests/projects/sample1"); }); after(() => { @@ -11,26 +11,27 @@ namespace ts { projFsWithBuild = undefined!; }); - function getTsBuildProjectFile(project: string, file: string): tscWatch.File { + function getTsBuildProjectFile(project: string, file: string): ts.tscWatch.File { return { - path: TestFSWithWatch.getTsBuildProjectFilePath(project, file), + path: ts.TestFSWithWatch.getTsBuildProjectFilePath(project, file), content: projFs.readFileSync(`/src/${project}/${file}`, "utf8")! }; } function getSampleFsAfterBuild() { - if (projFsWithBuild) return projFsWithBuild; + if (projFsWithBuild) + return projFsWithBuild; const fs = projFs.shadow(); const sys = new fakes.System(fs, { executingFilePath: "/lib/tsc" }); - const host = createSolutionBuilderHostForBaseline(sys as TscCompileSystem); - const builder = createSolutionBuilder(host, ["/src/tests"], {}); + const host = ts.createSolutionBuilderHostForBaseline(sys as ts.TscCompileSystem); + const builder = ts.createSolutionBuilder(host, ["/src/tests"], {}); builder.build(); fs.makeReadonly(); return projFsWithBuild = fs; } describe("sanity check of clean build of 'sample1' project", () => { - verifyTsc({ + ts.verifyTsc({ scenario: "sample1", subScenario: "builds correctly when outDir is specified", fs: () => projFs, @@ -41,7 +42,7 @@ namespace ts { })), }); - verifyTsc({ + ts.verifyTsc({ scenario: "sample1", subScenario: "builds correctly when declarationDir is specified", fs: () => projFs, @@ -52,17 +53,17 @@ namespace ts { })), }); - verifyTsc({ + ts.verifyTsc({ scenario: "sample1", subScenario: "builds correctly when project is not composite or doesnt have any references", fs: () => projFs, commandLineArgs: ["--b", "/src/core", "--verbose"], - modifyFs: fs => replaceText(fs, "/src/core/tsconfig.json", `"composite": true,`, ""), + modifyFs: fs => ts.replaceText(fs, "/src/core/tsconfig.json", `"composite": true,`, ""), }); }); describe("dry builds", () => { - verifyTsc({ + ts.verifyTsc({ scenario: "sample1", subScenario: "does not write any files in a dry build", fs: () => projFs, @@ -71,51 +72,51 @@ namespace ts { }); describe("clean builds", () => { - verifyTscWithEdits({ + ts.verifyTscWithEdits({ scenario: "sample1", subScenario: "removes all files it built", fs: getSampleFsAfterBuild, commandLineArgs: ["--b", "/src/tests", "--clean"], - edits: noChangeOnlyRuns + edits: ts.noChangeOnlyRuns }); - verifyTscCompileLike(testTscCompileLike, { + ts.verifyTscCompileLike(ts.testTscCompileLike, { scenario: "sample1", subScenario: "cleans till project specified", fs: getSampleFsAfterBuild, commandLineArgs: ["--b", "/src/logic", "--clean"], compile: sys => { - const buildHost = createSolutionBuilderHostForBaseline(sys); - const builder = createSolutionBuilder(buildHost, ["/src/third/tsconfig.json"], {}); + const buildHost = ts.createSolutionBuilderHostForBaseline(sys); + const builder = ts.createSolutionBuilder(buildHost, ["/src/third/tsconfig.json"], {}); sys.exit(builder.clean("/src/logic")); } }); - verifyTscCompileLike(testTscCompileLike, { + ts.verifyTscCompileLike(ts.testTscCompileLike, { scenario: "sample1", subScenario: "cleaning project in not build order doesnt throw error", fs: getSampleFsAfterBuild, commandLineArgs: ["--b", "/src/logic2", "--clean"], compile: sys => { - const buildHost = createSolutionBuilderHostForBaseline(sys); - const builder = createSolutionBuilder(buildHost, ["/src/third/tsconfig.json"], {}); + const buildHost = ts.createSolutionBuilderHostForBaseline(sys); + const builder = ts.createSolutionBuilder(buildHost, ["/src/third/tsconfig.json"], {}); sys.exit(builder.clean("/src/logic2")); } }); }); describe("force builds", () => { - verifyTscWithEdits({ + ts.verifyTscWithEdits({ scenario: "sample1", subScenario: "always builds under with force option", fs: () => projFs, commandLineArgs: ["--b", "/src/tests", "--force"], - edits: noChangeOnlyRuns + edits: ts.noChangeOnlyRuns }); }); describe("can detect when and what to rebuild", () => { - verifyTscWithEdits({ + ts.verifyTscWithEdits({ scenario: "sample1", subScenario: "can detect when and what to rebuild", fs: getSampleFsAfterBuild, @@ -129,49 +130,49 @@ namespace ts { // Update a file in the parent (without affecting types), should get fast downstream builds { subScenario: "Detects type-only changes in upstream projects", - modifyFs: fs => replaceText(fs, "/src/core/index.ts", "HELLO WORLD", "WELCOME PLANET"), + modifyFs: fs => ts.replaceText(fs, "/src/core/index.ts", "HELLO WORLD", "WELCOME PLANET"), }, { subScenario: "rebuilds when tsconfig changes", - modifyFs: fs => replaceText(fs, "/src/tests/tsconfig.json", `"composite": true`, `"composite": true, "target": "es3"`), + modifyFs: fs => ts.replaceText(fs, "/src/tests/tsconfig.json", `"composite": true`, `"composite": true, "target": "es3"`), }, ] }); - verifyTsc({ + ts.verifyTsc({ scenario: "sample1", subScenario: "indicates that it would skip builds during a dry build", fs: getSampleFsAfterBuild, commandLineArgs: ["--b", "/src/tests", "--dry"], }); - verifyTsc({ + ts.verifyTsc({ scenario: "sample1", subScenario: "rebuilds from start if force option is set", fs: getSampleFsAfterBuild, commandLineArgs: ["--b", "/src/tests", "--verbose", "--force"], }); - verifyTscCompileLike(testTscCompileLike, { + ts.verifyTscCompileLike(ts.testTscCompileLike, { scenario: "sample1", subScenario: "rebuilds completely when version in tsbuildinfo doesnt match ts version", fs: getSampleFsAfterBuild, commandLineArgs: ["--b", "/src/tests", "--verbose"], compile: sys => { // Buildinfo will have version which does not match with current ts version - const buildHost = createSolutionBuilderHostForBaseline(sys, "FakeTSCurrentVersion"); - const builder = createSolutionBuilder(buildHost, ["/src/tests"], { verbose: true }); + const buildHost = ts.createSolutionBuilderHostForBaseline(sys, "FakeTSCurrentVersion"); + const builder = ts.createSolutionBuilder(buildHost, ["/src/tests"], { verbose: true }); sys.exit(builder.build()); } }); - verifyTscCompileLike(testTscCompileLike, { + ts.verifyTscCompileLike(ts.testTscCompileLike, { scenario: "sample1", subScenario: "does not rebuild if there is no program and bundle in the ts build info event if version doesnt match ts version", fs: () => { const fs = projFs.shadow(); - const host = fakes.SolutionBuilderHost.create(fs, /*options*/ undefined, /*setParentNodes*/ undefined, createAbstractBuilder); - const builder = createSolutionBuilder(host, ["/src/tests"], { verbose: true }); + const host = fakes.SolutionBuilderHost.create(fs, /*options*/ undefined, /*setParentNodes*/ undefined, ts.createAbstractBuilder); + const builder = ts.createSolutionBuilder(host, ["/src/tests"], { verbose: true }); builder.build(); fs.makeReadonly(); return fs; @@ -179,20 +180,20 @@ namespace ts { commandLineArgs: ["--b", "/src/tests", "--verbose"], compile: sys => { // Buildinfo will have version which does not match with current ts version - const buildHost = createSolutionBuilderHostForBaseline(sys, "FakeTSCurrentVersion"); - const builder = createSolutionBuilder(buildHost, ["/src/tests"], { verbose: true }); + const buildHost = ts.createSolutionBuilderHostForBaseline(sys, "FakeTSCurrentVersion"); + const builder = ts.createSolutionBuilder(buildHost, ["/src/tests"], { verbose: true }); sys.exit(builder.build()); }, }); - verifyTscWithEdits({ + ts.verifyTscWithEdits({ scenario: "sample1", subScenario: "rebuilds when extended config file changes", fs: () => projFs, commandLineArgs: ["--b", "/src/tests", "--verbose"], modifyFs: fs => { fs.writeFileSync("/src/tests/tsconfig.base.json", JSON.stringify({ compilerOptions: { target: "es3" } })); - replaceText(fs, "/src/tests/tsconfig.json", `"references": [`, `"extends": "./tsconfig.base.json", "references": [`); + ts.replaceText(fs, "/src/tests/tsconfig.json", `"references": [`, `"extends": "./tsconfig.base.json", "references": [`); }, edits: [{ subScenario: "incremental-declaration-changes", @@ -200,26 +201,26 @@ namespace ts { }] }); - verifyTscCompileLike(testTscCompileLike, { + ts.verifyTscCompileLike(ts.testTscCompileLike, { scenario: "sample1", subScenario: "builds till project specified", fs: () => projFs, commandLineArgs: ["--build", "/src/logic/tsconfig.json"], compile: sys => { - const buildHost = createSolutionBuilderHostForBaseline(sys); - const builder = createSolutionBuilder(buildHost, ["/src/tests"], {}); + const buildHost = ts.createSolutionBuilderHostForBaseline(sys); + const builder = ts.createSolutionBuilder(buildHost, ["/src/tests"], {}); sys.exit(builder.build("/src/logic/tsconfig.json")); } }); - verifyTscCompileLike(testTscCompileLike, { + ts.verifyTscCompileLike(ts.testTscCompileLike, { scenario: "sample1", subScenario: "building project in not build order doesnt throw error", fs: () => projFs, commandLineArgs: ["--build", "/src/logic2/tsconfig.json"], compile: sys => { - const buildHost = createSolutionBuilderHostForBaseline(sys); - const builder = createSolutionBuilder(buildHost, ["/src/tests"], {}); + const buildHost = ts.createSolutionBuilderHostForBaseline(sys); + const builder = ts.createSolutionBuilder(buildHost, ["/src/tests"], {}); sys.exit(builder.build("/src/logic2/tsconfig.json")); } }); @@ -234,20 +235,15 @@ namespace ts { const testsConfig = getTsBuildProjectFile("tests", "tsconfig.json"); const testsIndex = getTsBuildProjectFile("tests", "index.ts"); const baseline: string[] = []; - let oldSnap: ReturnType | undefined; - const system = TestFSWithWatch.changeToHostTrackingWrittenFiles( - fakes.patchHostForBuildInfoReadWrite( - tscWatch.createWatchedSystem([ + let oldSnap: ReturnType | undefined; + const system = ts.TestFSWithWatch.changeToHostTrackingWrittenFiles(fakes.patchHostForBuildInfoReadWrite(ts.tscWatch.createWatchedSystem([ coreConfig, coreIndex, coreDecl, coreAnotherModule, logicConfig, logicIndex, testsConfig, testsIndex, - tscWatch.libFile - ]) - ) - ); - - const host = createSolutionBuilderHostForBaseline(system); - const builder = createSolutionBuilder(host, [testsConfig.path], {}); + ts.tscWatch.libFile + ]))); + const host = ts.createSolutionBuilderHostForBaseline(system); + const builder = ts.createSolutionBuilder(host, [testsConfig.path], {}); baseline.push("Input::"); baselineState(); verifyBuildNextResult(); // core @@ -271,26 +267,26 @@ namespace ts { } }); - verifyTscCompileLike(testTscCompileLike, { + ts.verifyTscCompileLike(ts.testTscCompileLike, { scenario: "sample1", subScenario: "building using buildReferencedProject", fs: () => projFs, commandLineArgs: ["--build", "/src/logic2/tsconfig.json"], compile: sys => { - const buildHost = createSolutionBuilderHostForBaseline(sys); - const builder = createSolutionBuilder(buildHost, ["/src/tests"], { verbose: true }); + const buildHost = ts.createSolutionBuilderHostForBaseline(sys); + const builder = ts.createSolutionBuilder(buildHost, ["/src/tests"], { verbose: true }); sys.exit(builder.buildReferences("/src/tests")); } }); }); describe("downstream-blocked compilations", () => { - verifyTsc({ + ts.verifyTsc({ scenario: "sample1", subScenario: "does not build downstream projects if upstream projects have errors", fs: () => projFs, commandLineArgs: ["--b", "/src/tests", "--verbose"], - modifyFs: fs => replaceText(fs, "/src/logic/index.ts", "c.multiply(10, 15)", `c.muitply()`) + modifyFs: fs => ts.replaceText(fs, "/src/logic/index.ts", "c.multiply(10, 15)", `c.muitply()`) }); }); @@ -305,20 +301,15 @@ namespace ts { const testsConfig = getTsBuildProjectFile("tests", "tsconfig.json"); const testsIndex = getTsBuildProjectFile("tests", "index.ts"); const baseline: string[] = []; - let oldSnap: ReturnType | undefined; - const system = TestFSWithWatch.changeToHostTrackingWrittenFiles( - fakes.patchHostForBuildInfoReadWrite( - tscWatch.createWatchedSystem([ + let oldSnap: ReturnType | undefined; + const system = ts.TestFSWithWatch.changeToHostTrackingWrittenFiles(fakes.patchHostForBuildInfoReadWrite(ts.tscWatch.createWatchedSystem([ coreConfig, coreIndex, coreDecl, coreAnotherModule, logicConfig, logicIndex, testsConfig, testsIndex, - tscWatch.libFile - ]) - ) - ); - - const host = createSolutionBuilderHostForBaseline(system); - const builder = createSolutionBuilder(host, [testsConfig.path], { dry: false, force: false, verbose: false }); + ts.tscWatch.libFile + ]))); + const host = ts.createSolutionBuilderHostForBaseline(system); + const builder = ts.createSolutionBuilder(host, [testsConfig.path], { dry: false, force: false, verbose: false }); builder.build(); baselineState("Build of project"); @@ -327,7 +318,7 @@ namespace ts { // Because we haven't reset the build context, the builder should assume there's nothing to do right now const status = builder.getUpToDateStatusOfProject(logicConfig.path); - baseline.push(`Project should still be upto date: ${UpToDateStatusType[status.type]}`); + baseline.push(`Project should still be upto date: ${ts.UpToDateStatusType[status.type]}`); verifyInvalidation("non Dts change to logic"); // Rebuild this project @@ -337,7 +328,7 @@ namespace ts { function verifyInvalidation(heading: string) { // Rebuild this project - builder.invalidateProject(logicConfig.path as ResolvedConfigFilePath); + builder.invalidateProject(logicConfig.path as ts.ResolvedConfigFilePath); builder.buildNextInvalidatedProject(); baselineState(`${heading}:: After rebuilding logicConfig`); @@ -356,35 +347,35 @@ namespace ts { }); }); - const coreChanges: TestTscEdit[] = [ + const coreChanges: ts.TestTscEdit[] = [ { subScenario: "incremental-declaration-changes", - modifyFs: fs => appendText(fs, "/src/core/index.ts", ` + modifyFs: fs => ts.appendText(fs, "/src/core/index.ts", ` export class someClass { }`), }, { subScenario: "incremental-declaration-doesnt-change", - modifyFs: fs => appendText(fs, "/src/core/index.ts", ` + modifyFs: fs => ts.appendText(fs, "/src/core/index.ts", ` class someClass2 { }`), } ]; describe("lists files", () => { - verifyTscWithEdits({ + ts.verifyTscWithEdits({ scenario: "sample1", subScenario: "listFiles", fs: () => projFs, commandLineArgs: ["--b", "/src/tests", "--listFiles"], edits: coreChanges }); - verifyTscWithEdits({ + ts.verifyTscWithEdits({ scenario: "sample1", subScenario: "listEmittedFiles", fs: () => projFs, commandLineArgs: ["--b", "/src/tests", "--listEmittedFiles"], edits: coreChanges }); - verifyTscWithEdits({ + ts.verifyTscWithEdits({ scenario: "sample1", subScenario: "explainFiles", fs: () => projFs, @@ -394,7 +385,7 @@ class someClass2 { }`), }); describe("emit output", () => { - verifyTscWithEdits({ + ts.verifyTscWithEdits({ subScenario: "sample", fs: () => projFs, scenario: "sample1", @@ -405,25 +396,25 @@ class someClass2 { }`), ...coreChanges, { subScenario: "when logic config changes declaration dir", - modifyFs: fs => replaceText(fs, "/src/logic/tsconfig.json", `"declaration": true,`, `"declaration": true, + modifyFs: fs => ts.replaceText(fs, "/src/logic/tsconfig.json", `"declaration": true,`, `"declaration": true, "declarationDir": "decls",`), }, - noChangeRun, + ts.noChangeRun, ], }); - verifyTsc({ + ts.verifyTsc({ scenario: "sample1", subScenario: "when logic specifies tsBuildInfoFile", fs: () => projFs, - modifyFs: fs => replaceText(fs, "/src/logic/tsconfig.json", `"composite": true,`, `"composite": true, + modifyFs: fs => ts.replaceText(fs, "/src/logic/tsconfig.json", `"composite": true,`, `"composite": true, "tsBuildInfoFile": "ownFile.tsbuildinfo",`), commandLineArgs: ["--b", "/src/tests", "--verbose"], baselineSourceMap: true, baselineReadFileCalls: true }); - verifyTscWithEdits({ + ts.verifyTscWithEdits({ subScenario: "when declaration option changes", fs: () => projFs, scenario: "sample1", @@ -436,11 +427,11 @@ class someClass2 { }`), }`), edits: [{ subScenario: "incremental-declaration-changes", - modifyFs: fs => replaceText(fs, "/src/core/tsconfig.json", `"incremental": true,`, `"incremental": true, "declaration": true,`), + modifyFs: fs => ts.replaceText(fs, "/src/core/tsconfig.json", `"incremental": true,`, `"incremental": true, "declaration": true,`), }], }); - verifyTscWithEdits({ + ts.verifyTscWithEdits({ subScenario: "when target option changes", fs: () => projFs, scenario: "sample1", @@ -448,7 +439,7 @@ class someClass2 { }`), modifyFs: fs => { fs.writeFileSync("/lib/lib.esnext.full.d.ts", `/// /// `); - fs.writeFileSync("/lib/lib.esnext.d.ts", libContent); + fs.writeFileSync("/lib/lib.esnext.d.ts", ts.libContent); fs.writeFileSync("/lib/lib.d.ts", `/// /// `); fs.writeFileSync("/src/core/tsconfig.json", `{ @@ -462,11 +453,11 @@ class someClass2 { }`), }, edits: [{ subScenario: "incremental-declaration-changes", - modifyFs: fs => replaceText(fs, "/src/core/tsconfig.json", "esnext", "es5"), + modifyFs: fs => ts.replaceText(fs, "/src/core/tsconfig.json", "esnext", "es5"), }], }); - verifyTscWithEdits({ + ts.verifyTscWithEdits({ subScenario: "when module option changes", fs: () => projFs, scenario: "sample1", @@ -479,11 +470,11 @@ class someClass2 { }`), }`), edits: [{ subScenario: "incremental-declaration-changes", - modifyFs: fs => replaceText(fs, "/src/core/tsconfig.json", `"module": "commonjs"`, `"module": "amd"`), + modifyFs: fs => ts.replaceText(fs, "/src/core/tsconfig.json", `"module": "commonjs"`, `"module": "amd"`), }], }); - verifyTscWithEdits({ + ts.verifyTscWithEdits({ subScenario: "when esModuleInterop option changes", fs: () => projFs, scenario: "sample1", @@ -504,7 +495,7 @@ class someClass2 { }`), }`), edits: [{ subScenario: "incremental-declaration-changes", - modifyFs: fs => replaceText(fs, "/src/tests/tsconfig.json", `"esModuleInterop": false`, `"esModuleInterop": true`), + modifyFs: fs => ts.replaceText(fs, "/src/tests/tsconfig.json", `"esModuleInterop": false`, `"esModuleInterop": true`), }], }); }); diff --git a/src/testRunner/unittests/tsbuild/transitiveReferences.ts b/src/testRunner/unittests/tsbuild/transitiveReferences.ts index 735c13f5976fb..e428506d96df6 100644 --- a/src/testRunner/unittests/tsbuild/transitiveReferences.ts +++ b/src/testRunner/unittests/tsbuild/transitiveReferences.ts @@ -2,7 +2,7 @@ namespace ts { describe("unittests:: tsbuild:: when project reference is referenced transitively", () => { let projFs: vfs.FileSystem; before(() => { - projFs = loadProjectFromDisk("tests/projects/transitiveReferences"); + projFs = ts.loadProjectFromDisk("tests/projects/transitiveReferences"); }); after(() => { projFs = undefined!; // Release the contents @@ -21,14 +21,14 @@ export const b = new A();`); })); } - verifyTsc({ + ts.verifyTsc({ scenario: "transitiveReferences", subScenario: "builds correctly", fs: () => projFs, commandLineArgs: ["--b", "/src/tsconfig.c.json", "--listFiles"], }); - verifyTsc({ + ts.verifyTsc({ scenario: "transitiveReferences", subScenario: "builds correctly when the referenced project uses different module resolution", fs: () => projFs, @@ -36,7 +36,7 @@ export const b = new A();`); modifyFs: fs => modifyFsBTsToNonRelativeImport(fs, "classic"), }); - verifyTsc({ + ts.verifyTsc({ scenario: "transitiveReferences", subScenario: "reports error about module not found with node resolution with external module name", fs: () => projFs, diff --git a/src/testRunner/unittests/tsbuildWatch/configFileErrors.ts b/src/testRunner/unittests/tsbuildWatch/configFileErrors.ts index 2d0bb90c4cb12..57e76de142f92 100644 --- a/src/testRunner/unittests/tsbuildWatch/configFileErrors.ts +++ b/src/testRunner/unittests/tsbuildWatch/configFileErrors.ts @@ -1,18 +1,17 @@ namespace ts.tscWatch { describe("unittests:: tsbuildWatch:: watchMode:: configFileErrors:: reports syntax errors in config file", () => { - function build(sys: WatchedSystem) { + function build(sys: ts.tscWatch.WatchedSystem) { sys.checkTimeoutQueueLengthAndRun(1); // build the project sys.checkTimeoutQueueLength(0); } - verifyTscWatch({ + ts.tscWatch.verifyTscWatch({ scenario: "configFileErrors", subScenario: "reports syntax errors in config file", - sys: () => createWatchedSystem( - [ - { path: `${projectRoot}/a.ts`, content: "export function foo() { }" }, - { path: `${projectRoot}/b.ts`, content: "export function bar() { }" }, + sys: () => ts.tscWatch.createWatchedSystem([ + { path: `${ts.tscWatch.projectRoot}/a.ts`, content: "export function foo() { }" }, + { path: `${ts.tscWatch.projectRoot}/b.ts`, content: "export function bar() { }" }, { - path: `${projectRoot}/tsconfig.json`, + path: `${ts.tscWatch.projectRoot}/tsconfig.json`, content: Utils.dedent` { "compilerOptions": { @@ -24,31 +23,29 @@ namespace ts.tscWatch { ] }` }, - libFile - ], - { currentDirectory: projectRoot } - ), + ts.tscWatch.libFile + ], { currentDirectory: ts.tscWatch.projectRoot }), commandLineArgs: ["--b", "-w"], changes: [ { caption: "reports syntax errors after change to config file", - change: sys => replaceFileText(sys, `${projectRoot}/tsconfig.json`, ",", `, + change: sys => ts.tscWatch.replaceFileText(sys, `${ts.tscWatch.projectRoot}/tsconfig.json`, ",", `, "declaration": true,`), timeouts: build, }, { caption: "reports syntax errors after change to ts file", - change: sys => replaceFileText(sys, `${projectRoot}/a.ts`, "foo", "fooBar"), + change: sys => ts.tscWatch.replaceFileText(sys, `${ts.tscWatch.projectRoot}/a.ts`, "foo", "fooBar"), timeouts: build, }, { caption: "reports error when there is no change to tsconfig file", - change: sys => replaceFileText(sys, `${projectRoot}/tsconfig.json`, "", ""), + change: sys => ts.tscWatch.replaceFileText(sys, `${ts.tscWatch.projectRoot}/tsconfig.json`, "", ""), timeouts: build, }, { caption: "builds after fixing config file errors", - change: sys => sys.writeFile(`${projectRoot}/tsconfig.json`, JSON.stringify({ + change: sys => sys.writeFile(`${ts.tscWatch.projectRoot}/tsconfig.json`, JSON.stringify({ compilerOptions: { composite: true, declaration: true }, files: ["a.ts", "b.ts"] })), diff --git a/src/testRunner/unittests/tsbuildWatch/demo.ts b/src/testRunner/unittests/tsbuildWatch/demo.ts index a648f084cd07e..f358ae171d7ea 100644 --- a/src/testRunner/unittests/tsbuildWatch/demo.ts +++ b/src/testRunner/unittests/tsbuildWatch/demo.ts @@ -1,19 +1,19 @@ namespace ts.tscWatch { describe("unittests:: tsbuildWatch:: watchMode:: with demo project", () => { - const projectLocation = `${TestFSWithWatch.tsbuildProjectsLocation}/demo`; - let coreFiles: File[]; - let animalFiles: File[]; - let zooFiles: File[]; - let solutionFile: File; - let baseConfig: File; - let allFiles: File[]; + const projectLocation = `${ts.TestFSWithWatch.tsbuildProjectsLocation}/demo`; + let coreFiles: ts.tscWatch.File[]; + let animalFiles: ts.tscWatch.File[]; + let zooFiles: ts.tscWatch.File[]; + let solutionFile: ts.tscWatch.File; + let baseConfig: ts.tscWatch.File; + let allFiles: ts.tscWatch.File[]; before(() => { coreFiles = subProjectFiles("core", ["tsconfig.json", "utilities.ts"]); animalFiles = subProjectFiles("animals", ["tsconfig.json", "animal.ts", "dog.ts", "index.ts"]); zooFiles = subProjectFiles("zoo", ["tsconfig.json", "zoo.ts"]); solutionFile = projectFile("tsconfig.json"); baseConfig = projectFile("tsconfig-base.json"); - allFiles = [...coreFiles, ...animalFiles, ...zooFiles, solutionFile, baseConfig, { path: libFile.path, content: libContent }]; + allFiles = [...coreFiles, ...animalFiles, ...zooFiles, solutionFile, baseConfig, { path: ts.tscWatch.libFile.path, content: ts.libContent }]; }); after(() => { @@ -25,21 +25,18 @@ namespace ts.tscWatch { allFiles = undefined!; }); - verifyTscWatch({ + ts.tscWatch.verifyTscWatch({ scenario: "demo", subScenario: "updates with circular reference", commandLineArgs: ["-b", "-w", "-verbose"], sys: () => { - const sys = createWatchedSystem(allFiles, { currentDirectory: projectLocation }); - sys.writeFile(coreFiles[0].path, coreFiles[0].content.replace( - "}", - `}, + const sys = ts.tscWatch.createWatchedSystem(allFiles, { currentDirectory: projectLocation }); + sys.writeFile(coreFiles[0].path, coreFiles[0].content.replace("}", `}, "references": [ { "path": "../zoo" } - ]` - )); + ]`)); return sys; }, changes: [ @@ -57,12 +54,12 @@ namespace ts.tscWatch { ] }); - verifyTscWatch({ + ts.tscWatch.verifyTscWatch({ scenario: "demo", subScenario: "updates with bad reference", commandLineArgs: ["-b", "-w", "-verbose"], sys: () => { - const sys = createWatchedSystem(allFiles, { currentDirectory: projectLocation }); + const sys = ts.tscWatch.createWatchedSystem(allFiles, { currentDirectory: projectLocation }); sys.writeFile(coreFiles[1].path, `import * as A from '../animals'; ${coreFiles[1].content}`); return sys; @@ -74,17 +71,17 @@ ${coreFiles[1].content}`); import * as A from '../animals'; ${coreFiles[1].content}`), // build core - timeouts: checkSingleTimeoutQueueLengthAndRunAndVerifyNoTimeout, + timeouts: ts.tscWatch.checkSingleTimeoutQueueLengthAndRunAndVerifyNoTimeout, } ] }); - function subProjectFiles(subProject: string, fileNames: readonly string[]): File[] { + function subProjectFiles(subProject: string, fileNames: readonly string[]): ts.tscWatch.File[] { return fileNames.map(file => projectFile(`${subProject}/${file}`)); } - function projectFile(fileName: string): File { - return TestFSWithWatch.getTsBuildProjectFile("demo", fileName); + function projectFile(fileName: string): ts.tscWatch.File { + return ts.TestFSWithWatch.getTsBuildProjectFile("demo", fileName); } }); } \ No newline at end of file diff --git a/src/testRunner/unittests/tsbuildWatch/moduleResolution.ts b/src/testRunner/unittests/tsbuildWatch/moduleResolution.ts index d68e63a5c4e8b..69c317ba8fdca 100644 --- a/src/testRunner/unittests/tsbuildWatch/moduleResolution.ts +++ b/src/testRunner/unittests/tsbuildWatch/moduleResolution.ts @@ -1,32 +1,31 @@ namespace ts.tscWatch { describe("unittests:: tsbuildWatch:: watchMode:: module resolution different in referenced project", () => { - verifyTscWatch({ + ts.tscWatch.verifyTscWatch({ scenario: "moduleResolutionCache", subScenario: "handles the cache correctly when two projects use different module resolution settings", - sys: () => createWatchedSystem( - [ - { path: `${projectRoot}/project1/index.ts`, content: `import { foo } from "file";` }, - { path: `${projectRoot}/project1/node_modules/file/index.d.ts`, content: "export const foo = 10;" }, + sys: () => ts.tscWatch.createWatchedSystem([ + { path: `${ts.tscWatch.projectRoot}/project1/index.ts`, content: `import { foo } from "file";` }, + { path: `${ts.tscWatch.projectRoot}/project1/node_modules/file/index.d.ts`, content: "export const foo = 10;" }, { - path: `${projectRoot}/project1/tsconfig.json`, + path: `${ts.tscWatch.projectRoot}/project1/tsconfig.json`, content: JSON.stringify({ compilerOptions: { composite: true, types: ["foo", "bar"] }, files: ["index.ts"] }) }, - { path: `${projectRoot}/project2/index.ts`, content: `import { foo } from "file";` }, - { path: `${projectRoot}/project2/file.d.ts`, content: "export const foo = 10;" }, + { path: `${ts.tscWatch.projectRoot}/project2/index.ts`, content: `import { foo } from "file";` }, + { path: `${ts.tscWatch.projectRoot}/project2/file.d.ts`, content: "export const foo = 10;" }, { - path: `${projectRoot}/project2/tsconfig.json`, + path: `${ts.tscWatch.projectRoot}/project2/tsconfig.json`, content: JSON.stringify({ compilerOptions: { composite: true, types: ["foo"], moduleResolution: "classic" }, files: ["index.ts"] }) }, - { path: `${projectRoot}/node_modules/@types/foo/index.d.ts`, content: "export const foo = 10;" }, - { path: `${projectRoot}/node_modules/@types/bar/index.d.ts`, content: "export const bar = 10;" }, + { path: `${ts.tscWatch.projectRoot}/node_modules/@types/foo/index.d.ts`, content: "export const foo = 10;" }, + { path: `${ts.tscWatch.projectRoot}/node_modules/@types/bar/index.d.ts`, content: "export const bar = 10;" }, { - path: `${projectRoot}/tsconfig.json`, + path: `${ts.tscWatch.projectRoot}/tsconfig.json`, content: JSON.stringify({ files: [], references: [ @@ -35,15 +34,13 @@ namespace ts.tscWatch { ] }) }, - libFile - ], - { currentDirectory: projectRoot } - ), + ts.tscWatch.libFile + ], { currentDirectory: ts.tscWatch.projectRoot }), commandLineArgs: ["--b", "-w", "-v"], changes: [ { caption: "Append text", - change: sys => sys.appendFile(`${projectRoot}/project1/index.ts`, "const bar = 10;"), + change: sys => sys.appendFile(`${ts.tscWatch.projectRoot}/project1/index.ts`, "const bar = 10;"), timeouts: sys => { sys.checkTimeoutQueueLengthAndRun(1); // build project1 sys.checkTimeoutQueueLengthAndRun(1); // Solution diff --git a/src/testRunner/unittests/tsbuildWatch/noEmit.ts b/src/testRunner/unittests/tsbuildWatch/noEmit.ts index ddcf1dd0b2893..aed4b288db20a 100644 --- a/src/testRunner/unittests/tsbuildWatch/noEmit.ts +++ b/src/testRunner/unittests/tsbuildWatch/noEmit.ts @@ -1,31 +1,28 @@ namespace ts.tscWatch { describe("unittests:: tsbuildWatch:: watchMode:: with noEmit", () => { - verifyTscWatch({ + ts.tscWatch.verifyTscWatch({ scenario: "noEmit", subScenario: "does not go in loop when watching when no files are emitted", commandLineArgs: ["-b", "-w", "-verbose"], - sys: () => createWatchedSystem( - [ - libFile, - { path: `${projectRoot}/a.js`, content: "" }, - { path: `${projectRoot}/b.ts`, content: "" }, - { path: `${projectRoot}/tsconfig.json`, content: JSON.stringify({ compilerOptions: { allowJs: true, noEmit: true } }) }, - { path: libFile.path, content: libContent } - ], - { currentDirectory: projectRoot } - ), + sys: () => ts.tscWatch.createWatchedSystem([ + ts.tscWatch.libFile, + { path: `${ts.tscWatch.projectRoot}/a.js`, content: "" }, + { path: `${ts.tscWatch.projectRoot}/b.ts`, content: "" }, + { path: `${ts.tscWatch.projectRoot}/tsconfig.json`, content: JSON.stringify({ compilerOptions: { allowJs: true, noEmit: true } }) }, + { path: ts.tscWatch.libFile.path, content: ts.libContent } + ], { currentDirectory: ts.tscWatch.projectRoot }), changes: [ { caption: "No change", - change: sys => sys.writeFile(`${projectRoot}/a.js`, sys.readFile(`${projectRoot}/a.js`)!), + change: sys => sys.writeFile(`${ts.tscWatch.projectRoot}/a.js`, sys.readFile(`${ts.tscWatch.projectRoot}/a.js`)!), // build project - timeouts: checkSingleTimeoutQueueLengthAndRunAndVerifyNoTimeout, + timeouts: ts.tscWatch.checkSingleTimeoutQueueLengthAndRunAndVerifyNoTimeout, }, { caption: "change", - change: sys => sys.writeFile(`${projectRoot}/a.js`, "const x = 10;"), + change: sys => sys.writeFile(`${ts.tscWatch.projectRoot}/a.js`, "const x = 10;"), // build project - timeouts: checkSingleTimeoutQueueLengthAndRunAndVerifyNoTimeout, + timeouts: ts.tscWatch.checkSingleTimeoutQueueLengthAndRunAndVerifyNoTimeout, }, ], baselineIncremental: true diff --git a/src/testRunner/unittests/tsbuildWatch/noEmitOnError.ts b/src/testRunner/unittests/tsbuildWatch/noEmitOnError.ts index 34ae0e8bcdf0f..6330a1f89d53a 100644 --- a/src/testRunner/unittests/tsbuildWatch/noEmitOnError.ts +++ b/src/testRunner/unittests/tsbuildWatch/noEmitOnError.ts @@ -1,32 +1,29 @@ namespace ts.tscWatch { describe("unittests:: tsbuildWatch:: watchMode:: with noEmitOnError", () => { - function change(caption: string, content: string): TscWatchCompileChange { + function change(caption: string, content: string): ts.tscWatch.TscWatchCompileChange { return { caption, - change: sys => sys.writeFile(`${TestFSWithWatch.tsbuildProjectsLocation}/noEmitOnError/src/main.ts`, content), + change: sys => sys.writeFile(`${ts.TestFSWithWatch.tsbuildProjectsLocation}/noEmitOnError/src/main.ts`, content), // build project - timeouts: checkSingleTimeoutQueueLengthAndRunAndVerifyNoTimeout, + timeouts: ts.tscWatch.checkSingleTimeoutQueueLengthAndRunAndVerifyNoTimeout, }; } - const noChange: TscWatchCompileChange = { + const noChange: ts.tscWatch.TscWatchCompileChange = { caption: "No change", - change: sys => sys.writeFile(`${TestFSWithWatch.tsbuildProjectsLocation}/noEmitOnError/src/main.ts`, sys.readFile(`${TestFSWithWatch.tsbuildProjectsLocation}/noEmitOnError/src/main.ts`)!), + change: sys => sys.writeFile(`${ts.TestFSWithWatch.tsbuildProjectsLocation}/noEmitOnError/src/main.ts`, sys.readFile(`${ts.TestFSWithWatch.tsbuildProjectsLocation}/noEmitOnError/src/main.ts`)!), // build project - timeouts: checkSingleTimeoutQueueLengthAndRunAndVerifyNoTimeout, + timeouts: ts.tscWatch.checkSingleTimeoutQueueLengthAndRunAndVerifyNoTimeout, }; - verifyTscWatch({ + ts.tscWatch.verifyTscWatch({ scenario: "noEmitOnError", subScenario: "does not emit any files on error", commandLineArgs: ["-b", "-w", "-verbose"], - sys: () => createWatchedSystem( - [ + sys: () => ts.tscWatch.createWatchedSystem([ ...["tsconfig.json", "shared/types/db.ts", "src/main.ts", "src/other.ts"] - .map(f => TestFSWithWatch.getTsBuildProjectFile("noEmitOnError", f)), - { path: libFile.path, content: libContent } - ], - { currentDirectory: `${TestFSWithWatch.tsbuildProjectsLocation}/noEmitOnError` } - ), + .map(f => ts.TestFSWithWatch.getTsBuildProjectFile("noEmitOnError", f)), + { path: ts.tscWatch.libFile.path, content: ts.libContent } + ], { currentDirectory: `${ts.TestFSWithWatch.tsbuildProjectsLocation}/noEmitOnError` }), changes: [ noChange, change("Fix Syntax error", `import { A } from "../shared/types/db"; diff --git a/src/testRunner/unittests/tsbuildWatch/programUpdates.ts b/src/testRunner/unittests/tsbuildWatch/programUpdates.ts index e6ba2f0e93e52..7608ac8a29843 100644 --- a/src/testRunner/unittests/tsbuildWatch/programUpdates.ts +++ b/src/testRunner/unittests/tsbuildWatch/programUpdates.ts @@ -1,5 +1,5 @@ namespace ts.tscWatch { - import projectsLocation = TestFSWithWatch.tsbuildProjectsLocation; + import projectsLocation = ts.TestFSWithWatch.tsbuildProjectsLocation; describe("unittests:: tsbuildWatch:: watchMode:: program updates", () => { const enum SubProject { core = "core", @@ -7,15 +7,23 @@ namespace ts.tscWatch { tests = "tests", ui = "ui" } - type ReadonlyFile = Readonly; + type ReadonlyFile = Readonly; /** [tsconfig, index] | [tsconfig, index, anotherModule, someDecl] */ - type SubProjectFiles = [tsconfig: ReadonlyFile, index: ReadonlyFile] | [tsconfig: ReadonlyFile, index: ReadonlyFile, anotherModule: ReadonlyFile, someDecl: ReadonlyFile]; + type SubProjectFiles = [ + tsconfig: ReadonlyFile, + index: ReadonlyFile + ] | [ + tsconfig: ReadonlyFile, + index: ReadonlyFile, + anotherModule: ReadonlyFile, + someDecl: ReadonlyFile + ]; function projectFilePath(subProject: SubProject, baseFileName: string) { - return `${TestFSWithWatch.getTsBuildProjectFilePath("sample1", subProject)}/${baseFileName.toLowerCase()}`; + return `${ts.TestFSWithWatch.getTsBuildProjectFilePath("sample1", subProject)}/${baseFileName.toLowerCase()}`; } - function projectFile(subProject: SubProject, baseFileName: string): File { - return TestFSWithWatch.getTsBuildProjectFile("sample1", `${subProject}/${baseFileName}`); + function projectFile(subProject: SubProject, baseFileName: string): ts.tscWatch.File { + return ts.TestFSWithWatch.getTsBuildProjectFile("sample1", `${subProject}/${baseFileName}`); } function subProjectFiles(subProject: SubProject, anotherModuleAndSomeDecl?: true): SubProjectFiles { @@ -29,11 +37,11 @@ namespace ts.tscWatch { return [tsconfig, index, anotherModule, someDecl]; } - function changeFile(fileName: string | (() => string), content: string | (() => string), caption: string): TscWatchCompileChange { + function changeFile(fileName: string | (() => string), content: string | (() => string), caption: string): ts.tscWatch.TscWatchCompileChange { return { caption, - change: sys => sys.writeFile(isString(fileName) ? fileName : fileName(), isString(content) ? content : content()), - timeouts: checkSingleTimeoutQueueLengthAndRun, // Builds core + change: sys => sys.writeFile(ts.isString(fileName) ? fileName : fileName(), ts.isString(content) ? content : content()), + timeouts: ts.tscWatch.checkSingleTimeoutQueueLengthAndRun, // Builds core }; } @@ -45,14 +53,14 @@ namespace ts.tscWatch { let logic: SubProjectFiles; let tests: SubProjectFiles; let ui: SubProjectFiles; - let allFiles: readonly File[]; + let allFiles: readonly ts.tscWatch.File[]; before(() => { core = subProjectFiles(SubProject.core, /*anotherModuleAndSomeDecl*/ true); logic = subProjectFiles(SubProject.logic); tests = subProjectFiles(SubProject.tests); ui = subProjectFiles(SubProject.ui); - allFiles = [libFile, ...core, ...logic, ...tests, ...ui]; + allFiles = [ts.tscWatch.libFile, ...core, ...logic, ...tests, ...ui]; }); after(() => { @@ -63,20 +71,20 @@ namespace ts.tscWatch { allFiles = undefined!; }); - verifyTscWatch({ + ts.tscWatch.verifyTscWatch({ scenario: "programUpdates", subScenario: "creates solution in watch mode", commandLineArgs: ["-b", "-w", `sample1/${SubProject.tests}`], - sys: () => createWatchedSystem(allFiles, { currentDirectory: projectsLocation }), - changes: emptyArray + sys: () => ts.tscWatch.createWatchedSystem(allFiles, { currentDirectory: projectsLocation }), + changes: ts.emptyArray }); it("verify building references watches only those projects", () => { - const { sys, baseline, oldSnap, cb, getPrograms } = createBaseline(createWatchedSystem(allFiles, { currentDirectory: projectsLocation })); - const host = createSolutionBuilderWithWatchHostForBaseline(sys, cb); - const solutionBuilder = createSolutionBuilderWithWatch(host, [`sample1/${SubProject.tests}`], { watch: true }); + const { sys, baseline, oldSnap, cb, getPrograms } = ts.tscWatch.createBaseline(ts.tscWatch.createWatchedSystem(allFiles, { currentDirectory: projectsLocation })); + const host = ts.tscWatch.createSolutionBuilderWithWatchHostForBaseline(sys, cb); + const solutionBuilder = ts.createSolutionBuilderWithWatch(host, [`sample1/${SubProject.tests}`], { watch: true }); solutionBuilder.buildReferences(`sample1/${SubProject.tests}`); - runWatchBaseline({ + ts.tscWatch.runWatchBaseline({ scenario: "programUpdates", subScenario: "verify building references watches only those projects", commandLineArgs: ["--b", "--w"], @@ -84,40 +92,37 @@ namespace ts.tscWatch { baseline, oldSnap, getPrograms, - changes: emptyArray, + changes: ts.emptyArray, watchOrSolution: solutionBuilder }); }); - const buildTests: TscWatchCompileChange = { + const buildTests: ts.tscWatch.TscWatchCompileChange = { caption: "Build Tests", - change: noop, + change: ts.noop, // Build tests - timeouts: checkSingleTimeoutQueueLengthAndRunAndVerifyNoTimeout, + timeouts: ts.tscWatch.checkSingleTimeoutQueueLengthAndRunAndVerifyNoTimeout, }; describe("validates the changes and watched files", () => { const newFileWithoutExtension = "newFile"; - const newFile: File = { + const newFile: ts.tscWatch.File = { path: projectFilePath(SubProject.core, `${newFileWithoutExtension}.ts`), content: `export const newFileConst = 30;` }; - function verifyProjectChanges(subScenario: string, allFilesGetter: () => readonly File[]) { - const buildLogicOrUpdateTimeStamps: TscWatchCompileChange = { + function verifyProjectChanges(subScenario: string, allFilesGetter: () => readonly ts.tscWatch.File[]) { + const buildLogicOrUpdateTimeStamps: ts.tscWatch.TscWatchCompileChange = { caption: "Build logic or update time stamps", - change: noop, - timeouts: checkSingleTimeoutQueueLengthAndRun, // Builds logic or updates timestamps + change: ts.noop, + timeouts: ts.tscWatch.checkSingleTimeoutQueueLengthAndRun, // Builds logic or updates timestamps }; - verifyTscWatch({ + ts.tscWatch.verifyTscWatch({ scenario: "programUpdates", subScenario: `${subScenario}/change builds changes and reports found errors message`, commandLineArgs: ["-b", "-w", `sample1/${SubProject.tests}`], - sys: () => createWatchedSystem( - allFilesGetter(), - { currentDirectory: projectsLocation } - ), + sys: () => ts.tscWatch.createWatchedSystem(allFilesGetter(), { currentDirectory: projectsLocation }), changes: [ changeCore(() => `${core[1].content} export class someClass { }`, "Make change to core"), @@ -138,21 +143,18 @@ export class someClass { }`; sys.writeFile(core[1].path, `${change1} export class someClass2 { }`); }, - timeouts: checkSingleTimeoutQueueLengthAndRun, // Builds core + timeouts: ts.tscWatch.checkSingleTimeoutQueueLengthAndRun, // Builds core }, buildLogicOrUpdateTimeStamps, buildTests, ] }); - verifyTscWatch({ + ts.tscWatch.verifyTscWatch({ scenario: "programUpdates", subScenario: `${subScenario}/non local change does not start build of referencing projects`, commandLineArgs: ["-b", "-w", `sample1/${SubProject.tests}`], - sys: () => createWatchedSystem( - allFilesGetter(), - { currentDirectory: projectsLocation } - ), + sys: () => ts.tscWatch.createWatchedSystem(allFilesGetter(), { currentDirectory: projectsLocation }), changes: [ changeCore(() => `${core[1].content} function foo() { }`, "Make local change to core"), @@ -164,14 +166,11 @@ function foo() { }`, "Make local change to core"), function changeNewFile(newFileContent: string) { return changeFile(newFile.path, newFileContent, "Change to new File and build core"); } - verifyTscWatch({ + ts.tscWatch.verifyTscWatch({ scenario: "programUpdates", subScenario: `${subScenario}/builds when new file is added, and its subsequent updates`, commandLineArgs: ["-b", "-w", `sample1/${SubProject.tests}`], - sys: () => createWatchedSystem( - allFilesGetter(), - { currentDirectory: projectsLocation } - ), + sys: () => ts.tscWatch.createWatchedSystem(allFilesGetter(), { currentDirectory: projectsLocation }), changes: [ changeNewFile(newFile.content), buildLogicOrUpdateTimeStamps, @@ -185,50 +184,41 @@ export class someClass2 { }`), } describe("with simple project reference graph", () => { - verifyProjectChanges( - "with simple project reference graph", - () => allFiles - ); + verifyProjectChanges("with simple project reference graph", () => allFiles); }); describe("with circular project reference", () => { - verifyProjectChanges( - "with circular project reference", - () => { + verifyProjectChanges("with circular project reference", () => { const [coreTsconfig, ...otherCoreFiles] = core; - const circularCoreConfig: File = { + const circularCoreConfig: ts.tscWatch.File = { path: coreTsconfig.path, content: JSON.stringify({ compilerOptions: { composite: true, declaration: true }, references: [{ path: "../tests", circular: true }] }) }; - return [libFile, circularCoreConfig, ...otherCoreFiles, ...logic, ...tests]; - } - ); + return [ts.tscWatch.libFile, circularCoreConfig, ...otherCoreFiles, ...logic, ...tests]; }); }); - verifyTscWatch({ + }); + ts.tscWatch.verifyTscWatch({ scenario: "programUpdates", subScenario: "watches config files that are not present", commandLineArgs: ["-b", "-w", `sample1/${SubProject.tests}`], - sys: () => createWatchedSystem( - [libFile, ...core, logic[1], ...tests], - { currentDirectory: projectsLocation } - ), + sys: () => ts.tscWatch.createWatchedSystem([ts.tscWatch.libFile, ...core, logic[1], ...tests], { currentDirectory: projectsLocation }), changes: [ { caption: "Write logic tsconfig and build logic", change: sys => sys.writeFile(logic[0].path, logic[0].content), - timeouts: checkSingleTimeoutQueueLengthAndRun, // Builds logic + timeouts: ts.tscWatch.checkSingleTimeoutQueueLengthAndRun, // Builds logic }, buildTests ] }); describe("when referenced using prepend, builds referencing project even for non local change", () => { - let coreIndex: File; + let coreIndex: ts.tscWatch.File; before(() => { coreIndex = { path: core[1].path, @@ -238,35 +228,35 @@ export class someClass2 { }`), after(() => { coreIndex = undefined!; }); - const buildLogic: TscWatchCompileChange = { + const buildLogic: ts.tscWatch.TscWatchCompileChange = { caption: "Build logic", - change: noop, + change: ts.noop, // Builds logic - timeouts: checkSingleTimeoutQueueLengthAndRunAndVerifyNoTimeout, + timeouts: ts.tscWatch.checkSingleTimeoutQueueLengthAndRunAndVerifyNoTimeout, }; - verifyTscWatch({ + ts.tscWatch.verifyTscWatch({ scenario: "programUpdates", subScenario: "when referenced using prepend builds referencing project even for non local change", commandLineArgs: ["-b", "-w", `sample1/${SubProject.logic}`], sys: () => { - const coreTsConfig: File = { + const coreTsConfig: ts.tscWatch.File = { path: core[0].path, content: JSON.stringify({ compilerOptions: { composite: true, declaration: true, outFile: "index.js" } }) }; - const logicTsConfig: File = { + const logicTsConfig: ts.tscWatch.File = { path: logic[0].path, content: JSON.stringify({ compilerOptions: { composite: true, declaration: true, outFile: "index.js" }, references: [{ path: "../core", prepend: true }] }) }; - const logicIndex: File = { + const logicIndex: ts.tscWatch.File = { path: logic[1].path, content: `function bar() { return foo() + 1 };` }; - return createWatchedSystem([libFile, coreTsConfig, coreIndex, logicTsConfig, logicIndex], { currentDirectory: projectsLocation }); + return ts.tscWatch.createWatchedSystem([ts.tscWatch.libFile, coreTsConfig, coreIndex, logicTsConfig, logicIndex], { currentDirectory: projectsLocation }); }, changes: [ changeCore(() => `${coreIndex.content} @@ -281,7 +271,7 @@ function myFunc() { return 100; }`, "Make local change and build core"), describe("when referenced project change introduces error in the down stream project and then fixes it", () => { const subProjectLibrary = `${projectsLocation}/sample1/Library`; - const libraryTs: File = { + const libraryTs: ts.tscWatch.File = { path: `${subProjectLibrary}/library.ts`, content: ` interface SomeObject @@ -296,28 +286,28 @@ export function createSomeObject(): SomeObject }; }` }; - verifyTscWatch({ + ts.tscWatch.verifyTscWatch({ scenario: "programUpdates", subScenario: "when referenced project change introduces error in the down stream project and then fixes it", commandLineArgs: ["-b", "-w", "App"], sys: () => { - const libraryTsconfig: File = { + const libraryTsconfig: ts.tscWatch.File = { path: `${subProjectLibrary}/tsconfig.json`, content: JSON.stringify({ compilerOptions: { composite: true } }) }; const subProjectApp = `${projectsLocation}/sample1/App`; - const appTs: File = { + const appTs: ts.tscWatch.File = { path: `${subProjectApp}/app.ts`, content: `import { createSomeObject } from "../Library/library"; createSomeObject().message;` }; - const appTsconfig: File = { + const appTsconfig: ts.tscWatch.File = { path: `${subProjectApp}/tsconfig.json`, content: JSON.stringify({ references: [{ path: "../Library" }] }) }; - const files = [libFile, libraryTs, libraryTsconfig, appTs, appTsconfig]; - return createWatchedSystem(files, { currentDirectory: `${projectsLocation}/sample1` }); + const files = [ts.tscWatch.libFile, libraryTs, libraryTsconfig, appTs, appTsconfig]; + return ts.tscWatch.createWatchedSystem(files, { currentDirectory: `${projectsLocation}/sample1` }); }, changes: [ { @@ -345,129 +335,117 @@ createSomeObject().message;` describe("reports errors in all projects on incremental compile", () => { function verifyIncrementalErrors(subScenario: string, buildOptions: readonly string[]) { - verifyTscWatch({ + ts.tscWatch.verifyTscWatch({ scenario: "programUpdates", subScenario: `reportErrors/${subScenario}`, commandLineArgs: ["-b", "-w", `sample1/${SubProject.tests}`, ...buildOptions], - sys: () => createWatchedSystem(allFiles, { currentDirectory: projectsLocation }), + sys: () => ts.tscWatch.createWatchedSystem(allFiles, { currentDirectory: projectsLocation }), changes: [ { caption: "change logic", change: sys => sys.writeFile(logic[1].path, `${logic[1].content} let y: string = 10;`), // Builds logic - timeouts: checkSingleTimeoutQueueLengthAndRunAndVerifyNoTimeout, + timeouts: ts.tscWatch.checkSingleTimeoutQueueLengthAndRunAndVerifyNoTimeout, }, { caption: "change core", change: sys => sys.writeFile(core[1].path, `${core[1].content} let x: string = 10;`), // Builds core - timeouts: checkSingleTimeoutQueueLengthAndRunAndVerifyNoTimeout, + timeouts: ts.tscWatch.checkSingleTimeoutQueueLengthAndRunAndVerifyNoTimeout, } ] }); } - verifyIncrementalErrors("when preserveWatchOutput is not used", emptyArray); + verifyIncrementalErrors("when preserveWatchOutput is not used", ts.emptyArray); verifyIncrementalErrors("when preserveWatchOutput is passed on command line", ["--preserveWatchOutput"]); describe("when declaration emit errors are present", () => { const solution = "solution"; const subProject = "app"; const subProjectLocation = `${projectsLocation}/${solution}/${subProject}`; - const fileWithError: File = { + const fileWithError: ts.tscWatch.File = { path: `${subProjectLocation}/fileWithError.ts`, content: `export var myClassWithError = class { tags() { } private p = 12 };` }; - const fileWithFixedError: File = { + const fileWithFixedError: ts.tscWatch.File = { path: fileWithError.path, content: fileWithError.content.replace("private p = 12", "") }; - const fileWithoutError: File = { + const fileWithoutError: ts.tscWatch.File = { path: `${subProjectLocation}/fileWithoutError.ts`, content: `export class myClass { }` }; - const tsconfig: File = { + const tsconfig: ts.tscWatch.File = { path: `${subProjectLocation}/tsconfig.json`, content: JSON.stringify({ compilerOptions: { composite: true } }) }; - function incrementalBuild(sys: WatchedSystem) { + function incrementalBuild(sys: ts.tscWatch.WatchedSystem) { sys.checkTimeoutQueueLengthAndRun(1); // Build the app sys.checkTimeoutQueueLength(0); } - const fixError: TscWatchCompileChange = { + const fixError: ts.tscWatch.TscWatchCompileChange = { caption: "Fix error in fileWithError", // Fix error change: sys => sys.writeFile(fileWithError.path, fileWithFixedError.content), timeouts: incrementalBuild }; - const changeFileWithoutError: TscWatchCompileChange = { + const changeFileWithoutError: ts.tscWatch.TscWatchCompileChange = { caption: "Change fileWithoutError", change: sys => sys.writeFile(fileWithoutError.path, fileWithoutError.content.replace(/myClass/g, "myClass2")), timeouts: incrementalBuild }; - verifyTscWatch({ + ts.tscWatch.verifyTscWatch({ scenario: "programUpdates", subScenario: "reportErrors/declarationEmitErrors/when fixing error files all files are emitted", commandLineArgs: ["-b", "-w", subProject], - sys: () => createWatchedSystem( - [libFile, fileWithError, fileWithoutError, tsconfig], - { currentDirectory: `${projectsLocation}/${solution}` } - ), + sys: () => ts.tscWatch.createWatchedSystem([ts.tscWatch.libFile, fileWithError, fileWithoutError, tsconfig], { currentDirectory: `${projectsLocation}/${solution}` }), changes: [ fixError ] }); - verifyTscWatch({ + ts.tscWatch.verifyTscWatch({ scenario: "programUpdates", subScenario: "reportErrors/declarationEmitErrors/when file with no error changes", commandLineArgs: ["-b", "-w", subProject], - sys: () => createWatchedSystem( - [libFile, fileWithError, fileWithoutError, tsconfig], - { currentDirectory: `${projectsLocation}/${solution}` } - ), + sys: () => ts.tscWatch.createWatchedSystem([ts.tscWatch.libFile, fileWithError, fileWithoutError, tsconfig], { currentDirectory: `${projectsLocation}/${solution}` }), changes: [ changeFileWithoutError ] }); describe("when reporting errors on introducing error", () => { - const introduceError: TscWatchCompileChange = { + const introduceError: ts.tscWatch.TscWatchCompileChange = { caption: "Introduce error", change: sys => sys.writeFile(fileWithError.path, fileWithError.content), timeouts: incrementalBuild, }; - verifyTscWatch({ + ts.tscWatch.verifyTscWatch({ scenario: "programUpdates", subScenario: "reportErrors/declarationEmitErrors/introduceError/when fixing errors only changed file is emitted", commandLineArgs: ["-b", "-w", subProject], - sys: () => createWatchedSystem( - [libFile, fileWithFixedError, fileWithoutError, tsconfig], - { currentDirectory: `${projectsLocation}/${solution}` } - ), + sys: () => ts.tscWatch.createWatchedSystem([ts.tscWatch.libFile, fileWithFixedError, fileWithoutError, tsconfig], { currentDirectory: `${projectsLocation}/${solution}` }), changes: [ introduceError, fixError ] }); - verifyTscWatch({ + ts.tscWatch.verifyTscWatch({ scenario: "programUpdates", subScenario: "reportErrors/declarationEmitErrors/introduceError/when file with no error changes", commandLineArgs: ["-b", "-w", subProject], - sys: () => createWatchedSystem( - [libFile, fileWithFixedError, fileWithoutError, tsconfig], - { currentDirectory: `${projectsLocation}/${solution}` } - ), + sys: () => ts.tscWatch.createWatchedSystem([ts.tscWatch.libFile, fileWithFixedError, fileWithoutError, tsconfig], { currentDirectory: `${projectsLocation}/${solution}` }), changes: [ introduceError, changeFileWithoutError @@ -477,11 +455,11 @@ let x: string = 10;`), }); }); - verifyTscWatch({ + ts.tscWatch.verifyTscWatch({ scenario: "programUpdates", subScenario: "incremental updates in verbose mode", commandLineArgs: ["-b", "-w", `sample1/${SubProject.tests}`, "-verbose"], - sys: () => createWatchedSystem(allFiles, { currentDirectory: projectsLocation }), + sys: () => ts.tscWatch.createWatchedSystem(allFiles, { currentDirectory: projectsLocation }), changes: [ { caption: "Make non dts change", @@ -504,104 +482,104 @@ export function someFn() { }`), ], }); - verifyTscWatch({ + ts.tscWatch.verifyTscWatch({ scenario: "programUpdates", subScenario: "works when noUnusedParameters changes to false", commandLineArgs: ["-b", "-w"], sys: () => { - const index: File = { - path: `${projectRoot}/index.ts`, + const index: ts.tscWatch.File = { + path: `${ts.tscWatch.projectRoot}/index.ts`, content: `const fn = (a: string, b: string) => b;` }; - const configFile: File = { - path: `${projectRoot}/tsconfig.json`, + const configFile: ts.tscWatch.File = { + path: `${ts.tscWatch.projectRoot}/tsconfig.json`, content: JSON.stringify({ compilerOptions: { noUnusedParameters: true } }) }; - return createWatchedSystem([index, configFile, libFile], { currentDirectory: projectRoot }); + return ts.tscWatch.createWatchedSystem([index, configFile, ts.tscWatch.libFile], { currentDirectory: ts.tscWatch.projectRoot }); }, changes: [ { caption: "Change tsconfig to set noUnusedParameters to false", - change: sys => sys.writeFile(`${projectRoot}/tsconfig.json`, JSON.stringify({ + change: sys => sys.writeFile(`${ts.tscWatch.projectRoot}/tsconfig.json`, JSON.stringify({ compilerOptions: { noUnusedParameters: false } })), - timeouts: runQueuedTimeoutCallbacks, + timeouts: ts.tscWatch.runQueuedTimeoutCallbacks, }, ] }); - verifyTscWatch({ + ts.tscWatch.verifyTscWatch({ scenario: "programUpdates", subScenario: "should not trigger recompilation because of program emit", commandLineArgs: ["-b", "-w", `sample1/${SubProject.core}`, "-verbose"], - sys: () => createWatchedSystem([libFile, ...core], { currentDirectory: projectsLocation }), + sys: () => ts.tscWatch.createWatchedSystem([ts.tscWatch.libFile, ...core], { currentDirectory: projectsLocation }), changes: [ - noopChange, + ts.tscWatch.noopChange, { caption: "Add new file", change: sys => sys.writeFile(`sample1/${SubProject.core}/file3.ts`, `export const y = 10;`), - timeouts: checkSingleTimeoutQueueLengthAndRun + timeouts: ts.tscWatch.checkSingleTimeoutQueueLengthAndRun }, - noopChange, + ts.tscWatch.noopChange, ] }); - verifyTscWatch({ + ts.tscWatch.verifyTscWatch({ scenario: "programUpdates", subScenario: "should not trigger recompilation because of program emit with outDir specified", commandLineArgs: ["-b", "-w", `sample1/${SubProject.core}`, "-verbose"], sys: () => { const [coreConfig, ...rest] = core; - const newCoreConfig: File = { path: coreConfig.path, content: JSON.stringify({ compilerOptions: { composite: true, outDir: "outDir" } }) }; - return createWatchedSystem([libFile, newCoreConfig, ...rest], { currentDirectory: projectsLocation }); + const newCoreConfig: ts.tscWatch.File = { path: coreConfig.path, content: JSON.stringify({ compilerOptions: { composite: true, outDir: "outDir" } }) }; + return ts.tscWatch.createWatchedSystem([ts.tscWatch.libFile, newCoreConfig, ...rest], { currentDirectory: projectsLocation }); }, changes: [ - noopChange, + ts.tscWatch.noopChange, { caption: "Add new file", change: sys => sys.writeFile(`sample1/${SubProject.core}/file3.ts`, `export const y = 10;`), - timeouts: checkSingleTimeoutQueueLengthAndRun + timeouts: ts.tscWatch.checkSingleTimeoutQueueLengthAndRun }, - noopChange + ts.tscWatch.noopChange ] }); - verifyTscWatch({ + ts.tscWatch.verifyTscWatch({ scenario: "programUpdates", subScenario: "works with extended source files", commandLineArgs: ["-b", "-w", "-v", "project1.tsconfig.json", "project2.tsconfig.json"], sys: () => { - const alphaExtendedConfigFile: File = { + const alphaExtendedConfigFile: ts.tscWatch.File = { path: "/a/b/alpha.tsconfig.json", content: "{}" }; - const project1Config: File = { + const project1Config: ts.tscWatch.File = { path: "/a/b/project1.tsconfig.json", content: JSON.stringify({ extends: "./alpha.tsconfig.json", compilerOptions: { composite: true, }, - files: [commonFile1.path, commonFile2.path] + files: [ts.tscWatch.commonFile1.path, ts.tscWatch.commonFile2.path] }) }; - const bravoExtendedConfigFile: File = { + const bravoExtendedConfigFile: ts.tscWatch.File = { path: "/a/b/bravo.tsconfig.json", content: JSON.stringify({ extends: "./alpha.tsconfig.json" }) }; - const otherFile: File = { + const otherFile: ts.tscWatch.File = { path: "/a/b/other.ts", content: "let z = 0;", }; - const project2Config: File = { + const project2Config: ts.tscWatch.File = { path: "/a/b/project2.tsconfig.json", content: JSON.stringify({ extends: "./bravo.tsconfig.json", @@ -611,9 +589,11 @@ export function someFn() { }`), files: [otherFile.path] }) }; - return createWatchedSystem([ - libFile, - alphaExtendedConfigFile, project1Config, commonFile1, commonFile2, + return ts.tscWatch.createWatchedSystem([ + ts.tscWatch.libFile, + alphaExtendedConfigFile, project1Config, + ts.tscWatch.commonFile1, + ts.tscWatch.commonFile2, bravoExtendedConfigFile, project2Config, otherFile ], { currentDirectory: "/a/b" }); }, @@ -623,12 +603,12 @@ export function someFn() { }`), change: sys => sys.writeFile("/a/b/alpha.tsconfig.json", JSON.stringify({ compilerOptions: { strict: true } })), - timeouts: checkSingleTimeoutQueueLengthAndRun // Build project1 + timeouts: ts.tscWatch.checkSingleTimeoutQueueLengthAndRun // Build project1 }, { caption: "Build project 2", - change: noop, - timeouts: checkSingleTimeoutQueueLengthAndRunAndVerifyNoTimeout // Build project2 + change: ts.noop, + timeouts: ts.tscWatch.checkSingleTimeoutQueueLengthAndRunAndVerifyNoTimeout // Build project2 }, { caption: "change bravo config", @@ -636,34 +616,34 @@ export function someFn() { }`), extends: "./alpha.tsconfig.json", compilerOptions: { strict: false } })), - timeouts: checkSingleTimeoutQueueLengthAndRunAndVerifyNoTimeout // Build project2 + timeouts: ts.tscWatch.checkSingleTimeoutQueueLengthAndRunAndVerifyNoTimeout // Build project2 }, { caption: "project 2 extends alpha", change: sys => sys.writeFile("/a/b/project2.tsconfig.json", JSON.stringify({ extends: "./alpha.tsconfig.json", })), - timeouts: checkSingleTimeoutQueueLengthAndRunAndVerifyNoTimeout // Build project2 + timeouts: ts.tscWatch.checkSingleTimeoutQueueLengthAndRunAndVerifyNoTimeout // Build project2 }, { caption: "update aplha config", change: sys => sys.writeFile("/a/b/alpha.tsconfig.json", "{}"), - timeouts: checkSingleTimeoutQueueLengthAndRun, // build project1 + timeouts: ts.tscWatch.checkSingleTimeoutQueueLengthAndRun, // build project1 }, { caption: "Build project 2", - change: noop, - timeouts: checkSingleTimeoutQueueLengthAndRunAndVerifyNoTimeout // Build project2 + change: ts.noop, + timeouts: ts.tscWatch.checkSingleTimeoutQueueLengthAndRunAndVerifyNoTimeout // Build project2 }, ] }); - verifyTscWatch({ + ts.tscWatch.verifyTscWatch({ scenario: "programUpdates", subScenario: "works correctly when project with extended config is removed", commandLineArgs: ["-b", "-w", "-v"], sys: () => { - const alphaExtendedConfigFile: File = { + const alphaExtendedConfigFile: ts.tscWatch.File = { path: "/a/b/alpha.tsconfig.json", content: JSON.stringify({ compilerOptions: { @@ -671,17 +651,17 @@ export function someFn() { }`), } }) }; - const project1Config: File = { + const project1Config: ts.tscWatch.File = { path: "/a/b/project1.tsconfig.json", content: JSON.stringify({ extends: "./alpha.tsconfig.json", compilerOptions: { composite: true, }, - files: [commonFile1.path, commonFile2.path] + files: [ts.tscWatch.commonFile1.path, ts.tscWatch.commonFile2.path] }) }; - const bravoExtendedConfigFile: File = { + const bravoExtendedConfigFile: ts.tscWatch.File = { path: "/a/b/bravo.tsconfig.json", content: JSON.stringify({ compilerOptions: { @@ -689,11 +669,11 @@ export function someFn() { }`), } }) }; - const otherFile: File = { + const otherFile: ts.tscWatch.File = { path: "/a/b/other.ts", content: "let z = 0;", }; - const project2Config: File = { + const project2Config: ts.tscWatch.File = { path: "/a/b/project2.tsconfig.json", content: JSON.stringify({ extends: "./bravo.tsconfig.json", @@ -703,7 +683,7 @@ export function someFn() { }`), files: [otherFile.path] }) }; - const configFile: File = { + const configFile: ts.tscWatch.File = { path: "/a/b/tsconfig.json", content: JSON.stringify({ references: [ @@ -717,9 +697,12 @@ export function someFn() { }`), files: [], }) }; - return createWatchedSystem([ - libFile, configFile, - alphaExtendedConfigFile, project1Config, commonFile1, commonFile2, + return ts.tscWatch.createWatchedSystem([ + ts.tscWatch.libFile, + configFile, + alphaExtendedConfigFile, project1Config, + ts.tscWatch.commonFile1, + ts.tscWatch.commonFile2, bravoExtendedConfigFile, project2Config, otherFile ], { currentDirectory: "/a/b" }); }, @@ -734,7 +717,7 @@ export function someFn() { }`), ], files: [], })), - timeouts: checkSingleTimeoutQueueLengthAndRunAndVerifyNoTimeout, + timeouts: ts.tscWatch.checkSingleTimeoutQueueLengthAndRunAndVerifyNoTimeout, } ] }); diff --git a/src/testRunner/unittests/tsbuildWatch/publicApi.ts b/src/testRunner/unittests/tsbuildWatch/publicApi.ts index 21ccf2948c5b6..ef2f34fdfd478 100644 --- a/src/testRunner/unittests/tsbuildWatch/publicApi.ts +++ b/src/testRunner/unittests/tsbuildWatch/publicApi.ts @@ -1,7 +1,7 @@ namespace ts.tscWatch { it("unittests:: tsbuildWatch:: watchMode:: Public API with custom transformers", () => { - const solution: File = { - path: `${projectRoot}/tsconfig.json`, + const solution: ts.tscWatch.File = { + path: `${ts.tscWatch.projectRoot}/tsconfig.json`, content: JSON.stringify({ references: [ { path: "./shared/tsconfig.json" }, @@ -10,29 +10,29 @@ namespace ts.tscWatch { files: [] }) }; - const sharedConfig: File = { - path: `${projectRoot}/shared/tsconfig.json`, + const sharedConfig: ts.tscWatch.File = { + path: `${ts.tscWatch.projectRoot}/shared/tsconfig.json`, content: JSON.stringify({ compilerOptions: { composite: true }, }) }; - const sharedIndex: File = { - path: `${projectRoot}/shared/index.ts`, + const sharedIndex: ts.tscWatch.File = { + path: `${ts.tscWatch.projectRoot}/shared/index.ts`, content: `export function f1() { } export class c { } export enum e { } // leading export function f2() { } // trailing` }; - const webpackConfig: File = { - path: `${projectRoot}/webpack/tsconfig.json`, + const webpackConfig: ts.tscWatch.File = { + path: `${ts.tscWatch.projectRoot}/webpack/tsconfig.json`, content: JSON.stringify({ compilerOptions: { composite: true, }, references: [{ path: "../shared/tsconfig.json" }] }) }; - const webpackIndex: File = { - path: `${projectRoot}/webpack/index.ts`, + const webpackIndex: ts.tscWatch.File = { + path: `${ts.tscWatch.projectRoot}/webpack/index.ts`, content: `export function f2() { } export class c2 { } export enum e2 { } @@ -40,12 +40,12 @@ export enum e2 { } export function f22() { } // trailing` }; const commandLineArgs = ["--b", "--w"]; - const { sys, baseline, oldSnap, cb, getPrograms } = createBaseline(createWatchedSystem([libFile, solution, sharedConfig, sharedIndex, webpackConfig, webpackIndex], { currentDirectory: projectRoot })); - const buildHost = createSolutionBuilderWithWatchHostForBaseline(sys, cb); + const { sys, baseline, oldSnap, cb, getPrograms } = ts.tscWatch.createBaseline(ts.tscWatch.createWatchedSystem([ts.tscWatch.libFile, solution, sharedConfig, sharedIndex, webpackConfig, webpackIndex], { currentDirectory: ts.tscWatch.projectRoot })); + const buildHost = ts.tscWatch.createSolutionBuilderWithWatchHostForBaseline(sys, cb); buildHost.getCustomTransformers = getCustomTransformers; - const builder = createSolutionBuilderWithWatch(buildHost, [solution.path], { verbose: true }); + const builder = ts.createSolutionBuilderWithWatch(buildHost, [solution.path], { verbose: true }); builder.build(); - runWatchBaseline({ + ts.tscWatch.runWatchBaseline({ scenario: "publicApi", subScenario: "with custom transformers", commandLineArgs, @@ -68,35 +68,35 @@ export function f22() { } // trailing` watchOrSolution: builder }); - function getCustomTransformers(project: string): CustomTransformers { - const before: TransformerFactory = context => { - return file => visitEachChild(file, visit, context); - function visit(node: Node): VisitResult { + function getCustomTransformers(project: string): ts.CustomTransformers { + const before: ts.TransformerFactory = context => { + return file => ts.visitEachChild(file, visit, context); + function visit(node: ts.Node): ts.VisitResult { switch (node.kind) { - case SyntaxKind.FunctionDeclaration: - return visitFunction(node as FunctionDeclaration); + case ts.SyntaxKind.FunctionDeclaration: + return visitFunction(node as ts.FunctionDeclaration); default: - return visitEachChild(node, visit, context); + return ts.visitEachChild(node, visit, context); } } - function visitFunction(node: FunctionDeclaration) { - addSyntheticLeadingComment(node, SyntaxKind.MultiLineCommentTrivia, `@before${project}`, /*hasTrailingNewLine*/ true); + function visitFunction(node: ts.FunctionDeclaration) { + ts.addSyntheticLeadingComment(node, ts.SyntaxKind.MultiLineCommentTrivia, `@before${project}`, /*hasTrailingNewLine*/ true); return node; } }; - const after: TransformerFactory = context => { - return file => visitEachChild(file, visit, context); - function visit(node: Node): VisitResult { + const after: ts.TransformerFactory = context => { + return file => ts.visitEachChild(file, visit, context); + function visit(node: ts.Node): ts.VisitResult { switch (node.kind) { - case SyntaxKind.VariableStatement: - return visitVariableStatement(node as VariableStatement); + case ts.SyntaxKind.VariableStatement: + return visitVariableStatement(node as ts.VariableStatement); default: - return visitEachChild(node, visit, context); + return ts.visitEachChild(node, visit, context); } } - function visitVariableStatement(node: VariableStatement) { - addSyntheticLeadingComment(node, SyntaxKind.SingleLineCommentTrivia, `@after${project}`); + function visitVariableStatement(node: ts.VariableStatement) { + ts.addSyntheticLeadingComment(node, ts.SyntaxKind.SingleLineCommentTrivia, `@after${project}`); return node; } }; diff --git a/src/testRunner/unittests/tsbuildWatch/reexport.ts b/src/testRunner/unittests/tsbuildWatch/reexport.ts index d105bd0fcf0ba..89e80bc03ae3f 100644 --- a/src/testRunner/unittests/tsbuildWatch/reexport.ts +++ b/src/testRunner/unittests/tsbuildWatch/reexport.ts @@ -1,36 +1,33 @@ namespace ts.tscWatch { describe("unittests:: tsbuildWatch:: watchMode:: with reexport when referenced project reexports definitions from another file", () => { - function build(sys: WatchedSystem) { + function build(sys: ts.tscWatch.WatchedSystem) { sys.checkTimeoutQueueLengthAndRun(1); // build src/pure sys.checkTimeoutQueueLengthAndRun(1); // build src/main sys.checkTimeoutQueueLengthAndRun(1); // build src sys.checkTimeoutQueueLength(0); } - verifyTscWatch({ + ts.tscWatch.verifyTscWatch({ scenario: "reexport", subScenario: "Reports errors correctly", commandLineArgs: ["-b", "-w", "-verbose", "src"], - sys: () => createWatchedSystem( - [ + sys: () => ts.tscWatch.createWatchedSystem([ ...[ "src/tsconfig.json", "src/main/tsconfig.json", "src/main/index.ts", "src/pure/tsconfig.json", "src/pure/index.ts", "src/pure/session.ts" ] - .map(f => TestFSWithWatch.getTsBuildProjectFile("reexport", f)), - { path: libFile.path, content: libContent } - ], - { currentDirectory: `${TestFSWithWatch.tsbuildProjectsLocation}/reexport` } - ), + .map(f => ts.TestFSWithWatch.getTsBuildProjectFile("reexport", f)), + { path: ts.tscWatch.libFile.path, content: ts.libContent } + ], { currentDirectory: `${ts.TestFSWithWatch.tsbuildProjectsLocation}/reexport` }), changes: [ { caption: "Introduce error", - change: sys => replaceFileText(sys, `${TestFSWithWatch.tsbuildProjectsLocation}/reexport/src/pure/session.ts`, "// ", ""), + change: sys => ts.tscWatch.replaceFileText(sys, `${ts.TestFSWithWatch.tsbuildProjectsLocation}/reexport/src/pure/session.ts`, "// ", ""), timeouts: build, }, { caption: "Fix error", - change: sys => replaceFileText(sys, `${TestFSWithWatch.tsbuildProjectsLocation}/reexport/src/pure/session.ts`, "bar: ", "// bar: "), + change: sys => ts.tscWatch.replaceFileText(sys, `${ts.TestFSWithWatch.tsbuildProjectsLocation}/reexport/src/pure/session.ts`, "bar: ", "// bar: "), timeouts: build } ] diff --git a/src/testRunner/unittests/tsbuildWatch/watchEnvironment.ts b/src/testRunner/unittests/tsbuildWatch/watchEnvironment.ts index a01b35f5a98cc..3b051054740ab 100644 --- a/src/testRunner/unittests/tsbuildWatch/watchEnvironment.ts +++ b/src/testRunner/unittests/tsbuildWatch/watchEnvironment.ts @@ -6,29 +6,27 @@ namespace ts.tscWatch { describe("when watchFile is single watcher per file", () => { verifyWatchFileOnMultipleProjects( - /*singleWatchPerFile*/ true, - arrayToMap(["TSC_WATCHFILE"], identity, () => TestFSWithWatch.Tsc_WatchFile.SingleFileWatcherPerName) - ); + /*singleWatchPerFile*/ true, ts.arrayToMap(["TSC_WATCHFILE"], ts.identity, () => ts.TestFSWithWatch.Tsc_WatchFile.SingleFileWatcherPerName)); }); - function verifyWatchFileOnMultipleProjects(singleWatchPerFile: boolean, environmentVariables?: ESMap) { + function verifyWatchFileOnMultipleProjects(singleWatchPerFile: boolean, environmentVariables?: ts.ESMap) { it("watchFile on same file multiple times because file is part of multiple projects", () => { - const project = `${TestFSWithWatch.tsbuildProjectsLocation}/myproject`; + const project = `${ts.TestFSWithWatch.tsbuildProjectsLocation}/myproject`; let maxPkgs = 4; const configPath = `${project}/tsconfig.json`; - const typing: File = { + const typing: ts.tscWatch.File = { path: `${project}/typings/xterm.d.ts`, content: "export const typing = 10;" }; const allPkgFiles = pkgs(pkgFiles); - const system = createWatchedSystem([libFile, typing, ...flatArray(allPkgFiles)], { currentDirectory: project, environmentVariables }); + const system = ts.tscWatch.createWatchedSystem([ts.tscWatch.libFile, typing, ...flatArray(allPkgFiles)], { currentDirectory: project, environmentVariables }); writePkgReferences(system); - const { sys, baseline, oldSnap, cb, getPrograms } = createBaseline(system); - const host = createSolutionBuilderWithWatchHostForBaseline(sys, cb); - const solutionBuilder = createSolutionBuilderWithWatch(host, ["tsconfig.json"], { watch: true, verbose: true }); + const { sys, baseline, oldSnap, cb, getPrograms } = ts.tscWatch.createBaseline(system); + const host = ts.tscWatch.createSolutionBuilderWithWatchHostForBaseline(sys, cb); + const solutionBuilder = ts.createSolutionBuilderWithWatch(host, ["tsconfig.json"], { watch: true, verbose: true }); solutionBuilder.build(); - runWatchBaseline({ + ts.tscWatch.runWatchBaseline({ scenario: "watchEnvironment", subScenario: `same file in multiple projects${singleWatchPerFile ? " with single watcher per file" : ""}`, commandLineArgs: ["--b", "--w"], @@ -49,7 +47,7 @@ namespace ts.tscWatch { maxPkgs--; writePkgReferences(sys); }, - timeouts: checkSingleTimeoutQueueLengthAndRun, + timeouts: ts.tscWatch.checkSingleTimeoutQueueLengthAndRun, }, { caption: "modify typing file", @@ -63,7 +61,7 @@ namespace ts.tscWatch { maxPkgs = 0; writePkgReferences(sys); }, - timeouts: checkSingleTimeoutQueueLengthAndRun, + timeouts: ts.tscWatch.checkSingleTimeoutQueueLengthAndRun, }, { caption: "modify typing file", @@ -75,7 +73,7 @@ namespace ts.tscWatch { }); function flatArray(arr: T[][]): readonly T[] { - return flatMap(arr, identity); + return ts.flatMap(arr, ts.identity); } function pkgs(cb: (index: number) => T): T[] { const result: T[] = []; @@ -87,7 +85,7 @@ namespace ts.tscWatch { function createPkgReference(index: number) { return { path: `./pkg${index}` }; } - function pkgFiles(index: number): File[] { + function pkgFiles(index: number): ts.tscWatch.File[] { return [ { path: `${project}/pkg${index}/index.ts`, @@ -105,7 +103,7 @@ namespace ts.tscWatch { } ]; } - function writePkgReferences(system: TestFSWithWatch.TestServerHost) { + function writePkgReferences(system: ts.TestFSWithWatch.TestServerHost) { system.writeFile(configPath, JSON.stringify({ files: [], include: [], diff --git a/src/testRunner/unittests/tsc/composite.ts b/src/testRunner/unittests/tsc/composite.ts index 8eb0ea3bd8595..7b20b3764a67d 100644 --- a/src/testRunner/unittests/tsc/composite.ts +++ b/src/testRunner/unittests/tsc/composite.ts @@ -1,9 +1,9 @@ namespace ts { describe("unittests:: tsc:: composite::", () => { - verifyTsc({ + ts.verifyTsc({ scenario: "composite", subScenario: "when setting composite false on command line", - fs: () => loadProjectFromFiles({ + fs: () => ts.loadProjectFromFiles({ "/src/project/src/main.ts": "export const x = 10;", "/src/project/tsconfig.json": Utils.dedent` { @@ -20,10 +20,10 @@ namespace ts { commandLineArgs: ["--composite", "false", "--p", "src/project"], }); - verifyTsc({ + ts.verifyTsc({ scenario: "composite", subScenario: "when setting composite null on command line", - fs: () => loadProjectFromFiles({ + fs: () => ts.loadProjectFromFiles({ "/src/project/src/main.ts": "export const x = 10;", "/src/project/tsconfig.json": Utils.dedent` { @@ -40,10 +40,10 @@ namespace ts { commandLineArgs: ["--composite", "null", "--p", "src/project"], }); - verifyTsc({ + ts.verifyTsc({ scenario: "composite", subScenario: "when setting composite false on command line but has tsbuild info in config", - fs: () => loadProjectFromFiles({ + fs: () => ts.loadProjectFromFiles({ "/src/project/src/main.ts": "export const x = 10;", "/src/project/tsconfig.json": Utils.dedent` { @@ -61,10 +61,10 @@ namespace ts { commandLineArgs: ["--composite", "false", "--p", "src/project"], }); - verifyTsc({ + ts.verifyTsc({ scenario: "composite", subScenario: "when setting composite false and tsbuildinfo as null on command line but has tsbuild info in config", - fs: () => loadProjectFromFiles({ + fs: () => ts.loadProjectFromFiles({ "/src/project/src/main.ts": "export const x = 10;", "/src/project/tsconfig.json": Utils.dedent` { diff --git a/src/testRunner/unittests/tsc/declarationEmit.ts b/src/testRunner/unittests/tsc/declarationEmit.ts index f345d4a3c8f61..1b51326798146 100644 --- a/src/testRunner/unittests/tsc/declarationEmit.ts +++ b/src/testRunner/unittests/tsc/declarationEmit.ts @@ -2,39 +2,36 @@ namespace ts { describe("unittests:: tsc:: declarationEmit::", () => { interface VerifyDeclarationEmitInput { subScenario: string; - files: TestFSWithWatch.FileOrFolderOrSymLink[]; + files: ts.TestFSWithWatch.FileOrFolderOrSymLink[]; rootProject: string; changeCaseFileTestPath: (path: string) => boolean; } - function changeCaseFile(file: TestFSWithWatch.FileOrFolderOrSymLink, testPath: (path: string) => boolean, replacePath: (path: string) => string): TestFSWithWatch.FileOrFolderOrSymLink { - return !TestFSWithWatch.isSymLink(file) || !testPath(file.symLink) ? + function changeCaseFile(file: ts.TestFSWithWatch.FileOrFolderOrSymLink, testPath: (path: string) => boolean, replacePath: (path: string) => string): ts.TestFSWithWatch.FileOrFolderOrSymLink { + return !ts.TestFSWithWatch.isSymLink(file) || !testPath(file.symLink) ? testPath(file.path) ? { ...file, path: replacePath(file.path) } : file : { path: testPath(file.path) ? replacePath(file.path) : file.path, symLink: replacePath(file.symLink) }; } function verifyDeclarationEmit({ subScenario, files, rootProject, changeCaseFileTestPath }: VerifyDeclarationEmitInput) { describe(subScenario, () => { - tscWatch.verifyTscWatch({ + ts.tscWatch.verifyTscWatch({ scenario: "declarationEmit", subScenario, - sys: () => tscWatch.createWatchedSystem(files, { currentDirectory: tscWatch.projectRoot }), + sys: () => ts.tscWatch.createWatchedSystem(files, { currentDirectory: ts.tscWatch.projectRoot }), commandLineArgs: ["-p", rootProject, "--explainFiles"], - changes: emptyArray + changes: ts.emptyArray }); }); const caseChangeScenario = `${subScenario} moduleCaseChange`; describe(caseChangeScenario, () => { - tscWatch.verifyTscWatch({ + ts.tscWatch.verifyTscWatch({ scenario: "declarationEmit", subScenario: caseChangeScenario, - sys: () => tscWatch.createWatchedSystem( - files.map(f => changeCaseFile(f, changeCaseFileTestPath, str => str.replace("myproject", "myProject"))), - { currentDirectory: tscWatch.projectRoot } - ), + sys: () => ts.tscWatch.createWatchedSystem(files.map(f => changeCaseFile(f, changeCaseFileTestPath, str => str.replace("myproject", "myProject"))), { currentDirectory: ts.tscWatch.projectRoot }), commandLineArgs: ["-p", rootProject, "--explainFiles"], - changes: emptyArray + changes: ts.emptyArray }); }); } @@ -110,18 +107,18 @@ namespace ts { subScenario: "when same version is referenced through source and another symlinked package", rootProject: "plugin-one", files: [ - { path: `${tscWatch.projectRoot}/plugin-two/index.d.ts`, content: pluginTwoDts() }, - { path: `${tscWatch.projectRoot}/plugin-two/node_modules/typescript-fsa/package.json`, content: fsaPackageJson() }, - { path: `${tscWatch.projectRoot}/plugin-two/node_modules/typescript-fsa/index.d.ts`, content: fsaIndex() }, - { path: `${tscWatch.projectRoot}/plugin-one/tsconfig.json`, content: pluginOneConfig() }, - { path: `${tscWatch.projectRoot}/plugin-one/index.ts`, content: pluginOneIndex() }, - { path: `${tscWatch.projectRoot}/plugin-one/action.ts`, content: pluginOneAction() }, - { path: `${tscWatch.projectRoot}/plugin-one/node_modules/typescript-fsa/package.json`, content: fsaPackageJson() }, - { path: `${tscWatch.projectRoot}/plugin-one/node_modules/typescript-fsa/index.d.ts`, content: fsaIndex() }, - { path: `${tscWatch.projectRoot}/plugin-one/node_modules/plugin-two`, symLink: `${tscWatch.projectRoot}/plugin-two` }, - tscWatch.libFile + { path: `${ts.tscWatch.projectRoot}/plugin-two/index.d.ts`, content: pluginTwoDts() }, + { path: `${ts.tscWatch.projectRoot}/plugin-two/node_modules/typescript-fsa/package.json`, content: fsaPackageJson() }, + { path: `${ts.tscWatch.projectRoot}/plugin-two/node_modules/typescript-fsa/index.d.ts`, content: fsaIndex() }, + { path: `${ts.tscWatch.projectRoot}/plugin-one/tsconfig.json`, content: pluginOneConfig() }, + { path: `${ts.tscWatch.projectRoot}/plugin-one/index.ts`, content: pluginOneIndex() }, + { path: `${ts.tscWatch.projectRoot}/plugin-one/action.ts`, content: pluginOneAction() }, + { path: `${ts.tscWatch.projectRoot}/plugin-one/node_modules/typescript-fsa/package.json`, content: fsaPackageJson() }, + { path: `${ts.tscWatch.projectRoot}/plugin-one/node_modules/typescript-fsa/index.d.ts`, content: fsaIndex() }, + { path: `${ts.tscWatch.projectRoot}/plugin-one/node_modules/plugin-two`, symLink: `${ts.tscWatch.projectRoot}/plugin-two` }, + ts.tscWatch.libFile ], - changeCaseFileTestPath: str => stringContains(str, "/plugin-two"), + changeCaseFileTestPath: str => ts.stringContains(str, "/plugin-two"), }); verifyDeclarationEmit({ @@ -129,29 +126,29 @@ namespace ts { rootProject: "plugin-one", files: [ { - path: `${tscWatch.projectRoot}/plugin-two/package.json`, + path: `${ts.tscWatch.projectRoot}/plugin-two/package.json`, content: JSON.stringify({ name: "plugin-two", version: "0.1.3", main: "dist/commonjs/index.js" }) }, - { path: `${tscWatch.projectRoot}/plugin-two/dist/commonjs/index.d.ts`, content: pluginTwoDts() }, - { path: `${tscWatch.projectRoot}/plugin-two/node_modules/typescript-fsa/package.json`, content: fsaPackageJson() }, - { path: `${tscWatch.projectRoot}/plugin-two/node_modules/typescript-fsa/index.d.ts`, content: fsaIndex() }, - { path: `${tscWatch.projectRoot}/plugin-one/tsconfig.json`, content: pluginOneConfig() }, + { path: `${ts.tscWatch.projectRoot}/plugin-two/dist/commonjs/index.d.ts`, content: pluginTwoDts() }, + { path: `${ts.tscWatch.projectRoot}/plugin-two/node_modules/typescript-fsa/package.json`, content: fsaPackageJson() }, + { path: `${ts.tscWatch.projectRoot}/plugin-two/node_modules/typescript-fsa/index.d.ts`, content: fsaIndex() }, + { path: `${ts.tscWatch.projectRoot}/plugin-one/tsconfig.json`, content: pluginOneConfig() }, { - path: `${tscWatch.projectRoot}/plugin-one/index.ts`, + path: `${ts.tscWatch.projectRoot}/plugin-one/index.ts`, content: `${pluginOneIndex()} ${pluginOneAction()}` }, - { path: `${tscWatch.projectRoot}/plugin-one/node_modules/typescript-fsa/package.json`, content: fsaPackageJson() }, - { path: `${tscWatch.projectRoot}/plugin-one/node_modules/typescript-fsa/index.d.ts`, content: fsaIndex() }, - { path: `/temp/yarn/data/link/plugin-two`, symLink: `${tscWatch.projectRoot}/plugin-two` }, - { path: `${tscWatch.projectRoot}/plugin-one/node_modules/plugin-two`, symLink: `/temp/yarn/data/link/plugin-two` }, - tscWatch.libFile + { path: `${ts.tscWatch.projectRoot}/plugin-one/node_modules/typescript-fsa/package.json`, content: fsaPackageJson() }, + { path: `${ts.tscWatch.projectRoot}/plugin-one/node_modules/typescript-fsa/index.d.ts`, content: fsaIndex() }, + { path: `/temp/yarn/data/link/plugin-two`, symLink: `${ts.tscWatch.projectRoot}/plugin-two` }, + { path: `${ts.tscWatch.projectRoot}/plugin-one/node_modules/plugin-two`, symLink: `/temp/yarn/data/link/plugin-two` }, + ts.tscWatch.libFile ], - changeCaseFileTestPath: str => stringContains(str, "/plugin-two"), + changeCaseFileTestPath: str => ts.stringContains(str, "/plugin-two"), }); }); @@ -160,12 +157,12 @@ ${pluginOneAction()}` rootProject: "pkg3", files: [ { - path: `${tscWatch.projectRoot}/pkg1/dist/index.d.ts`, + path: `${ts.tscWatch.projectRoot}/pkg1/dist/index.d.ts`, content: Utils.dedent` export * from './types';` }, { - path: `${tscWatch.projectRoot}/pkg1/dist/types.d.ts`, + path: `${ts.tscWatch.projectRoot}/pkg1/dist/types.d.ts`, content: Utils.dedent` export declare type A = { id: string; @@ -182,7 +179,7 @@ ${pluginOneAction()}` }` }, { - path: `${tscWatch.projectRoot}/pkg1/package.json`, + path: `${ts.tscWatch.projectRoot}/pkg1/package.json`, content: JSON.stringify({ name: "@raymondfeng/pkg1", version: "1.0.0", @@ -191,17 +188,17 @@ ${pluginOneAction()}` }) }, { - path: `${tscWatch.projectRoot}/pkg2/dist/index.d.ts`, + path: `${ts.tscWatch.projectRoot}/pkg2/dist/index.d.ts`, content: Utils.dedent` export * from './types';` }, { - path: `${tscWatch.projectRoot}/pkg2/dist/types.d.ts`, + path: `${ts.tscWatch.projectRoot}/pkg2/dist/types.d.ts`, content: Utils.dedent` export {MetadataAccessor} from '@raymondfeng/pkg1';` }, { - path: `${tscWatch.projectRoot}/pkg2/package.json`, + path: `${ts.tscWatch.projectRoot}/pkg2/package.json`, content: JSON.stringify({ name: "@raymondfeng/pkg2", version: "1.0.0", @@ -210,18 +207,18 @@ ${pluginOneAction()}` }) }, { - path: `${tscWatch.projectRoot}/pkg3/src/index.ts`, + path: `${ts.tscWatch.projectRoot}/pkg3/src/index.ts`, content: Utils.dedent` export * from './keys';` }, { - path: `${tscWatch.projectRoot}/pkg3/src/keys.ts`, + path: `${ts.tscWatch.projectRoot}/pkg3/src/keys.ts`, content: Utils.dedent` import {MetadataAccessor} from "@raymondfeng/pkg2"; export const ADMIN = MetadataAccessor.create('1');` }, { - path: `${tscWatch.projectRoot}/pkg3/tsconfig.json`, + path: `${ts.tscWatch.projectRoot}/pkg3/tsconfig.json`, content: JSON.stringify({ compilerOptions: { outDir: "dist", @@ -235,16 +232,16 @@ ${pluginOneAction()}` }) }, { - path: `${tscWatch.projectRoot}/pkg2/node_modules/@raymondfeng/pkg1`, - symLink: `${tscWatch.projectRoot}/pkg1` + path: `${ts.tscWatch.projectRoot}/pkg2/node_modules/@raymondfeng/pkg1`, + symLink: `${ts.tscWatch.projectRoot}/pkg1` }, { - path: `${tscWatch.projectRoot}/pkg3/node_modules/@raymondfeng/pkg2`, - symLink: `${tscWatch.projectRoot}/pkg2` + path: `${ts.tscWatch.projectRoot}/pkg3/node_modules/@raymondfeng/pkg2`, + symLink: `${ts.tscWatch.projectRoot}/pkg2` }, - tscWatch.libFile + ts.tscWatch.libFile ], - changeCaseFileTestPath: str => stringContains(str, "/pkg1"), + changeCaseFileTestPath: str => ts.stringContains(str, "/pkg1"), }); }); } diff --git a/src/testRunner/unittests/tsc/helpers.ts b/src/testRunner/unittests/tsc/helpers.ts index 81d22823e0b01..972e232747ea6 100644 --- a/src/testRunner/unittests/tsc/helpers.ts +++ b/src/testRunner/unittests/tsc/helpers.ts @@ -1,16 +1,19 @@ namespace ts { export type TscCompileSystem = fakes.System & { - writtenFiles: Set; - baseLine(): { file: string; text: string; }; + writtenFiles: ts.Set; + baseLine(): { + file: string; + text: string; + }; disableUseFileVersionAsSignature?: boolean; storeFilesChangingSignatureDuringEmit?: boolean; }; - export const noChangeRun: TestTscEdit = { + export const noChangeRun: ts.TestTscEdit = { subScenario: "no-change-run", - modifyFs: noop + modifyFs: ts.noop }; - export const noChangeWithExportsDiscrepancyRun: TestTscEdit = { + export const noChangeWithExportsDiscrepancyRun: ts.TestTscEdit = { ...noChangeRun, discrepancyExplanation: () => [ "Incremental build did not emit and has .ts as signature so exports has all imported modules/referenced files", @@ -27,36 +30,35 @@ namespace ts { baselineDependencies?: boolean; } - export type CommandLineProgram = [Program, BuilderProgram?]; + export type CommandLineProgram = [ + ts.Program, + ts.BuilderProgram? + ]; export interface CommandLineCallbacks { - cb: ExecuteCommandLineCallbacks; + cb: ts.ExecuteCommandLineCallbacks; getPrograms: () => readonly CommandLineProgram[]; } - function isAnyProgram(program: Program | BuilderProgram | ParsedCommandLine): program is Program | BuilderProgram { - return !!(program as Program | BuilderProgram).getCompilerOptions; + function isAnyProgram(program: ts.Program | ts.BuilderProgram | ts.ParsedCommandLine): program is ts.Program | ts.BuilderProgram { + return !!(program as ts.Program | ts.BuilderProgram).getCompilerOptions; } - export function commandLineCallbacks( - sys: TscCompileSystem | tscWatch.WatchedSystem, - originalReadCall?: System["readFile"], - ): CommandLineCallbacks { + export function commandLineCallbacks(sys: TscCompileSystem | ts.tscWatch.WatchedSystem, originalReadCall?: ts.System["readFile"]): CommandLineCallbacks { let programs: CommandLineProgram[] | undefined; return { cb: program => { if (isAnyProgram(program)) { - baselineBuildInfo(program.getCompilerOptions(), sys, originalReadCall); - (programs || (programs = [])).push(isBuilderProgram(program) ? + ts.baselineBuildInfo(program.getCompilerOptions(), sys, originalReadCall); + (programs || (programs = [])).push(ts.isBuilderProgram(program) ? [program.getProgram(), program] : - [program] - ); + [program]); } else { - baselineBuildInfo(program.options, sys, originalReadCall); + ts.baselineBuildInfo(program.options, sys, originalReadCall); } }, getPrograms: () => { - const result = programs || emptyArray; + const result = programs || ts.emptyArray; programs = undefined; return result; } @@ -79,24 +81,21 @@ namespace ts { export function testTscCompileLike(input: TestTscCompileLike) { const initialFs = input.fs(); const inputFs = initialFs.shadow(); - const { - scenario, subScenario, diffWithInitial, - commandLineArgs, modifyFs, - environmentVariables, - compile: worker, additionalBaseline, - } = input; - if (modifyFs) modifyFs(inputFs); + const { scenario, subScenario, diffWithInitial, commandLineArgs, modifyFs, environmentVariables, compile: worker, additionalBaseline, } = input; + if (modifyFs) + modifyFs(inputFs); inputFs.makeReadonly(); const fs = inputFs.shadow(); // Create system const sys = new fakes.System(fs, { executingFilePath: "/lib/tsc", env: environmentVariables }) as TscCompileSystem; - if (input.disableUseFileVersionAsSignature) sys.disableUseFileVersionAsSignature = true; + if (input.disableUseFileVersionAsSignature) + sys.disableUseFileVersionAsSignature = true; sys.storeFilesChangingSignatureDuringEmit = true; sys.write(`${sys.getExecutingFilePath()} ${commandLineArgs.join(" ")}\n`); sys.exit = exitCode => sys.exitCode = exitCode; worker(sys); - sys.write(`exitCode:: ExitStatus.${ExitStatus[sys.exitCode as ExitStatus]}\n`); + sys.write(`exitCode:: ExitStatus.${ts.ExitStatus[sys.exitCode as ts.ExitStatus]}\n`); additionalBaseline?.(sys); fs.makeReadonly(); sys.baseLine = () => { @@ -105,7 +104,7 @@ namespace ts { inputFs.diff(/*base*/ undefined, { baseIsNotShadowRoot: true }); const patch = fs.diff(inputFs, { includeChangedFileWithSameContent: true }); return { - file: `${isBuild(commandLineArgs) ? "tsbuild" : "tsc"}/${scenario}/${subScenario.split(" ").join("-")}.js`, + file: `${ts.isBuild(commandLineArgs) ? "tsbuild" : "tsc"}/${scenario}/${subScenario.split(" ").join("-")}.js`, text: `Input:: ${baseFsPatch ? vfs.formatPatch(baseFsPatch) : ""} @@ -125,31 +124,25 @@ ${patch ? vfs.formatPatch(patch) : ""}` else { fakes.patchHostForBuildInfoReadWrite(sys); } - const writtenFiles = sys.writtenFiles = new Set(); + const writtenFiles = sys.writtenFiles = new ts.Set(); const originalWriteFile = sys.writeFile; sys.writeFile = (fileName, content, writeByteOrderMark) => { - const path = toPathWithSystem(sys, fileName); + const path = ts.toPathWithSystem(sys, fileName); // When buildinfo is same for two projects, // it gives error and doesnt write buildinfo but because buildInfo is written for one project, // readable baseline will be written two times for those two projects with same contents and is ok - Debug.assert(!writtenFiles.has(path) || endsWith(path, "baseline.txt")); + ts.Debug.assert(!writtenFiles.has(path) || ts.endsWith(path, "baseline.txt")); writtenFiles.add(path); return originalWriteFile.call(sys, fileName, content, writeByteOrderMark); }; } - export function createSolutionBuilderHostForBaseline( - sys: TscCompileSystem | tscWatch.WatchedSystem, - versionToWrite?: string, - originalRead?: (TscCompileSystem | tscWatch.WatchedSystem)["readFile"] - ) { - if (sys instanceof fakes.System) makeSystemReadyForBaseline(sys, versionToWrite); + export function createSolutionBuilderHostForBaseline(sys: TscCompileSystem | ts.tscWatch.WatchedSystem, versionToWrite?: string, originalRead?: (TscCompileSystem | ts.tscWatch.WatchedSystem)["readFile"]) { + if (sys instanceof fakes.System) + makeSystemReadyForBaseline(sys, versionToWrite); const { cb } = commandLineCallbacks(sys, originalRead); - const host = createSolutionBuilderHost(sys, - /*createProgram*/ undefined, - createDiagnosticReporter(sys, /*pretty*/ true), - createBuilderStatusReporter(sys, /*pretty*/ true), - ); + const host = ts.createSolutionBuilderHost(sys, + /*createProgram*/ undefined, ts.createDiagnosticReporter(sys, /*pretty*/ true), ts.createBuilderStatusReporter(sys, /*pretty*/ true)); host.afterProgramEmitAndDiagnostics = cb; host.afterEmitBundle = cb; return host; @@ -159,7 +152,7 @@ ${patch ? vfs.formatPatch(patch) : ""}` * Initialize Fs, execute command line and save baseline */ export function testTscCompile(input: TestTscCompile) { - let actualReadFileMap: MapLike | undefined; + let actualReadFileMap: ts.MapLike | undefined; let getPrograms: CommandLineCallbacks["getPrograms"] | undefined; return testTscCompileLike({ ...input, @@ -174,17 +167,13 @@ ${patch ? vfs.formatPatch(patch) : ""}` sys.readFile = path => { // Dont record libs if (path.startsWith("/src/")) { - actualReadFileMap![path] = (getProperty(actualReadFileMap!, path) || 0) + 1; + actualReadFileMap![path] = (ts.getProperty(actualReadFileMap!, path) || 0) + 1; } return originalReadFile.call(sys, path); }; const result = commandLineCallbacks(sys, originalReadFile); - executeCommandLine( - sys, - result.cb, - input.commandLineArgs, - ); + ts.executeCommandLine(sys, result.cb, input.commandLineArgs); sys.readFile = originalReadFile; getPrograms = result.getPrograms; } @@ -193,19 +182,22 @@ ${patch ? vfs.formatPatch(patch) : ""}` const { baselineSourceMap, baselineReadFileCalls, baselinePrograms, baselineDependencies } = input; if (baselinePrograms) { const baseline: string[] = []; - tscWatch.baselinePrograms(baseline, getPrograms!, emptyArray, baselineDependencies); + ts.tscWatch.baselinePrograms(baseline, getPrograms!, ts.emptyArray, baselineDependencies); sys.write(baseline.join("\n")); } if (baselineReadFileCalls) { sys.write(`readFiles:: ${JSON.stringify(actualReadFileMap, /*replacer*/ undefined, " ")} `); } - if (baselineSourceMap) generateSourceMapBaselineFiles(sys); + if (baselineSourceMap) + ts.generateSourceMapBaselineFiles(sys); actualReadFileMap = undefined; getPrograms = undefined; } } - export function verifyTscBaseline(sys: () => { baseLine: TscCompileSystem["baseLine"]; }) { + export function verifyTscBaseline(sys: () => { + baseLine: TscCompileSystem["baseLine"]; + }) { it(`Generates files matching the baseline`, () => { const { file, text } = sys().baseLine(); Harness.Baseline.runBaseline(file, text); @@ -221,7 +213,9 @@ ${patch ? vfs.formatPatch(patch) : ""}` /** * Verify by baselining after initializing FS and custom compile */ - export function verifyTscCompileLike(verifier: (input: T) => { baseLine: TscCompileSystem["baseLine"]; }, input: T) { + export function verifyTscCompileLike(verifier: (input: T) => { + baseLine: TscCompileSystem["baseLine"]; + }, input: T) { describe(`tsc ${input.commandLineArgs.join(" ")} ${input.scenario}:: ${input.subScenario}`, () => { describe(input.scenario, () => { describe(input.subScenario, () => { diff --git a/src/testRunner/unittests/tsc/incremental.ts b/src/testRunner/unittests/tsc/incremental.ts index b3bd30d91aef9..a9bd18f6cab66 100644 --- a/src/testRunner/unittests/tsc/incremental.ts +++ b/src/testRunner/unittests/tsc/incremental.ts @@ -1,9 +1,9 @@ namespace ts { describe("unittests:: tsc:: incremental::", () => { - verifyTscWithEdits({ + ts.verifyTscWithEdits({ scenario: "incremental", subScenario: "when passing filename for buildinfo on commandline", - fs: () => loadProjectFromFiles({ + fs: () => ts.loadProjectFromFiles({ "/src/project/src/main.ts": "export const x = 10;", "/src/project/tsconfig.json": Utils.dedent` { @@ -17,13 +17,13 @@ namespace ts { }`, }), commandLineArgs: ["--incremental", "--p", "src/project", "--tsBuildInfoFile", "src/project/.tsbuildinfo", "--explainFiles"], - edits: noChangeOnlyRuns + edits: ts.noChangeOnlyRuns }); - verifyTscWithEdits({ + ts.verifyTscWithEdits({ scenario: "incremental", subScenario: "when passing rootDir from commandline", - fs: () => loadProjectFromFiles({ + fs: () => ts.loadProjectFromFiles({ "/src/project/src/main.ts": "export const x = 10;", "/src/project/tsconfig.json": Utils.dedent` { @@ -34,31 +34,31 @@ namespace ts { }`, }), commandLineArgs: ["--p", "src/project", "--rootDir", "src/project/src"], - edits: noChangeOnlyRuns + edits: ts.noChangeOnlyRuns }); - verifyTscWithEdits({ + ts.verifyTscWithEdits({ scenario: "incremental", subScenario: "with only dts files", - fs: () => loadProjectFromFiles({ + fs: () => ts.loadProjectFromFiles({ "/src/project/src/main.d.ts": "export const x = 10;", "/src/project/src/another.d.ts": "export const y = 10;", "/src/project/tsconfig.json": "{}", }), commandLineArgs: ["--incremental", "--p", "src/project"], edits: [ - noChangeRun, + ts.noChangeRun, { subScenario: "incremental-declaration-doesnt-change", - modifyFs: fs => appendText(fs, "/src/project/src/main.d.ts", "export const xy = 100;") + modifyFs: fs => ts.appendText(fs, "/src/project/src/main.d.ts", "export const xy = 100;") } ] }); - verifyTscWithEdits({ + ts.verifyTscWithEdits({ scenario: "incremental", subScenario: "when passing rootDir is in the tsconfig", - fs: () => loadProjectFromFiles({ + fs: () => ts.loadProjectFromFiles({ "/src/project/src/main.ts": "export const x = 10;", "/src/project/tsconfig.json": Utils.dedent` { @@ -70,51 +70,43 @@ namespace ts { }`, }), commandLineArgs: ["--p", "src/project"], - edits: noChangeOnlyRuns + edits: ts.noChangeOnlyRuns }); describe("with noEmitOnError", () => { let projFs: vfs.FileSystem; before(() => { - projFs = loadProjectFromDisk("tests/projects/noEmitOnError"); + projFs = ts.loadProjectFromDisk("tests/projects/noEmitOnError"); }); after(() => { projFs = undefined!; }); - function verifyNoEmitOnError(subScenario: string, fixModifyFs: TestTscEdit["modifyFs"], modifyFs?: TestTscEdit["modifyFs"]) { - verifyTscWithEdits({ + function verifyNoEmitOnError(subScenario: string, fixModifyFs: ts.TestTscEdit["modifyFs"], modifyFs?: ts.TestTscEdit["modifyFs"]) { + ts.verifyTscWithEdits({ scenario: "incremental", subScenario, fs: () => projFs, commandLineArgs: ["--incremental", "-p", "src"], modifyFs, edits: [ - noChangeWithExportsDiscrepancyRun, + ts.noChangeWithExportsDiscrepancyRun, { subScenario: "incremental-declaration-doesnt-change", modifyFs: fixModifyFs }, - noChangeRun, + ts.noChangeRun, ], baselinePrograms: true }); } - verifyNoEmitOnError( - "with noEmitOnError syntax errors", - fs => fs.writeFileSync("/src/src/main.ts", `import { A } from "../shared/types/db"; + verifyNoEmitOnError("with noEmitOnError syntax errors", fs => fs.writeFileSync("/src/src/main.ts", `import { A } from "../shared/types/db"; const a = { lastName: 'sdsd' -};`, "utf-8") - ); - - verifyNoEmitOnError( - "with noEmitOnError semantic errors", - fs => fs.writeFileSync("/src/src/main.ts", `import { A } from "../shared/types/db"; -const a: string = "hello";`, "utf-8"), - fs => fs.writeFileSync("/src/src/main.ts", `import { A } from "../shared/types/db"; -const a: string = 10;`, "utf-8"), - ); +};`, "utf-8")); + verifyNoEmitOnError("with noEmitOnError semantic errors", fs => fs.writeFileSync("/src/src/main.ts", `import { A } from "../shared/types/db"; +const a: string = "hello";`, "utf-8"), fs => fs.writeFileSync("/src/src/main.ts", `import { A } from "../shared/types/db"; +const a: string = 10;`, "utf-8")); }); describe("when noEmit changes between compilation", () => { @@ -122,30 +114,30 @@ const a: string = 10;`, "utf-8"), verifyNoEmitChanges({ incremental: true, declaration: true }); verifyNoEmitChanges({ composite: true }); - function verifyNoEmitChanges(compilerOptions: CompilerOptions) { - const discrepancyIfNoDtsEmit = getEmitDeclarations(compilerOptions) ? + function verifyNoEmitChanges(compilerOptions: ts.CompilerOptions) { + const discrepancyIfNoDtsEmit = ts.getEmitDeclarations(compilerOptions) ? undefined : - noChangeWithExportsDiscrepancyRun.discrepancyExplanation; - const noChangeRunWithNoEmit: TestTscEdit = { - ...noChangeRun, + ts.noChangeWithExportsDiscrepancyRun.discrepancyExplanation; + const noChangeRunWithNoEmit: ts.TestTscEdit = { + ...ts.noChangeRun, subScenario: "No Change run with noEmit", commandLineArgs: ["--p", "src/project", "--noEmit"], discrepancyExplanation: discrepancyIfNoDtsEmit, }; - const noChangeRunWithEmit: TestTscEdit = { - ...noChangeRun, + const noChangeRunWithEmit: ts.TestTscEdit = { + ...ts.noChangeRun, subScenario: "No Change run with emit", commandLineArgs: ["--p", "src/project"], discrepancyExplanation: discrepancyIfNoDtsEmit, }; let optionsString = ""; for (const key in compilerOptions) { - if (hasProperty(compilerOptions, key)) { + if (ts.hasProperty(compilerOptions, key)) { optionsString += ` ${key}`; } } - verifyTscWithEdits({ + ts.verifyTscWithEdits({ scenario: "incremental", subScenario: `noEmit changes${optionsString}`, commandLineArgs: ["--p", "src/project"], @@ -156,12 +148,12 @@ const a: string = 10;`, "utf-8"), { subScenario: "Introduce error but still noEmit", commandLineArgs: ["--p", "src/project", "--noEmit"], - modifyFs: fs => replaceText(fs, "/src/project/src/class.ts", "prop", "prop1"), - discrepancyExplanation: getEmitDeclarations(compilerOptions) ? noChangeWithExportsDiscrepancyRun.discrepancyExplanation : undefined, + modifyFs: fs => ts.replaceText(fs, "/src/project/src/class.ts", "prop", "prop1"), + discrepancyExplanation: ts.getEmitDeclarations(compilerOptions) ? ts.noChangeWithExportsDiscrepancyRun.discrepancyExplanation : undefined, }, { subScenario: "Fix error and emit", - modifyFs: fs => replaceText(fs, "/src/project/src/class.ts", "prop1", "prop"), + modifyFs: fs => ts.replaceText(fs, "/src/project/src/class.ts", "prop1", "prop"), discrepancyExplanation: discrepancyIfNoDtsEmit }, noChangeRunWithEmit, @@ -170,7 +162,7 @@ const a: string = 10;`, "utf-8"), noChangeRunWithEmit, { subScenario: "Introduce error and emit", - modifyFs: fs => replaceText(fs, "/src/project/src/class.ts", "prop", "prop1"), + modifyFs: fs => ts.replaceText(fs, "/src/project/src/class.ts", "prop", "prop1"), discrepancyExplanation: discrepancyIfNoDtsEmit }, noChangeRunWithEmit, @@ -180,8 +172,8 @@ const a: string = 10;`, "utf-8"), { subScenario: "Fix error and no emit", commandLineArgs: ["--p", "src/project", "--noEmit"], - modifyFs: fs => replaceText(fs, "/src/project/src/class.ts", "prop1", "prop"), - discrepancyExplanation: noChangeWithExportsDiscrepancyRun.discrepancyExplanation, + modifyFs: fs => ts.replaceText(fs, "/src/project/src/class.ts", "prop1", "prop"), + discrepancyExplanation: ts.noChangeWithExportsDiscrepancyRun.discrepancyExplanation, }, noChangeRunWithEmit, noChangeRunWithNoEmit, @@ -190,7 +182,7 @@ const a: string = 10;`, "utf-8"), ], }); - verifyTscWithEdits({ + ts.verifyTscWithEdits({ scenario: "incremental", subScenario: `noEmit changes with initial noEmit${optionsString}`, commandLineArgs: ["--p", "src/project", "--noEmit"], @@ -200,19 +192,19 @@ const a: string = 10;`, "utf-8"), { subScenario: "Introduce error with emit", commandLineArgs: ["--p", "src/project"], - modifyFs: fs => replaceText(fs, "/src/project/src/class.ts", "prop", "prop1"), + modifyFs: fs => ts.replaceText(fs, "/src/project/src/class.ts", "prop", "prop1"), }, { subScenario: "Fix error and no emit", - modifyFs: fs => replaceText(fs, "/src/project/src/class.ts", "prop1", "prop"), - discrepancyExplanation: noChangeWithExportsDiscrepancyRun.discrepancyExplanation + modifyFs: fs => ts.replaceText(fs, "/src/project/src/class.ts", "prop1", "prop"), + discrepancyExplanation: ts.noChangeWithExportsDiscrepancyRun.discrepancyExplanation }, noChangeRunWithEmit, ], }); function fs() { - return loadProjectFromFiles({ + return ts.loadProjectFromFiles({ "/src/project/src/class.ts": Utils.dedent` export class classC { prop = 1; @@ -240,10 +232,10 @@ const a: string = 10;`, "utf-8"), } }); - verifyTscWithEdits({ + ts.verifyTscWithEdits({ scenario: "incremental", subScenario: `when global file is added, the signatures are updated`, - fs: () => loadProjectFromFiles({ + fs: () => ts.loadProjectFromFiles({ "/src/project/src/main.ts": Utils.dedent` /// /// @@ -262,22 +254,22 @@ const a: string = 10;`, "utf-8"), }), commandLineArgs: ["--p", "src/project"], edits: [ - noChangeRun, + ts.noChangeRun, { subScenario: "Modify main file", - modifyFs: fs => appendText(fs, `/src/project/src/main.ts`, `something();`), + modifyFs: fs => ts.appendText(fs, `/src/project/src/main.ts`, `something();`), }, { subScenario: "Modify main file again", - modifyFs: fs => appendText(fs, `/src/project/src/main.ts`, `something();`), + modifyFs: fs => ts.appendText(fs, `/src/project/src/main.ts`, `something();`), }, { subScenario: "Add new file and update main file", modifyFs: fs => { fs.writeFileSync(`/src/project/src/newFile.ts`, "function foo() { return 20; }"); - prependText(fs, `/src/project/src/main.ts`, `/// + ts.prependText(fs, `/src/project/src/main.ts`, `/// `); - appendText(fs, `/src/project/src/main.ts`, `foo();`); + ts.appendText(fs, `/src/project/src/main.ts`, `foo();`); }, }, { @@ -286,7 +278,7 @@ const a: string = 10;`, "utf-8"), }, { subScenario: "Modify main file", - modifyFs: fs => appendText(fs, `/src/project/src/main.ts`, `something();`), + modifyFs: fs => ts.appendText(fs, `/src/project/src/main.ts`, `something();`), }, ], baselinePrograms: true, @@ -308,24 +300,24 @@ declare global { }`; } - verifyTsc({ + ts.verifyTsc({ scenario: "react-jsx-emit-mode", subScenario: "with no backing types found doesn't crash", - fs: () => loadProjectFromFiles({ - "/src/project/node_modules/react/jsx-runtime.js": "export {}", // js needs to be present so there's a resolution result - "/src/project/node_modules/@types/react/index.d.ts": getJsxLibraryContent(), // doesn't contain a jsx-runtime definition + fs: () => ts.loadProjectFromFiles({ + "/src/project/node_modules/react/jsx-runtime.js": "export {}", + "/src/project/node_modules/@types/react/index.d.ts": getJsxLibraryContent(), "/src/project/src/index.tsx": `export const App = () =>
;`, "/src/project/tsconfig.json": JSON.stringify({ compilerOptions: { module: "commonjs", jsx: "react-jsx", incremental: true, jsxImportSource: "react" } }) }), commandLineArgs: ["--p", "src/project"] }); - verifyTsc({ + ts.verifyTsc({ scenario: "react-jsx-emit-mode", subScenario: "with no backing types found doesn't crash under --strict", - fs: () => loadProjectFromFiles({ - "/src/project/node_modules/react/jsx-runtime.js": "export {}", // js needs to be present so there's a resolution result - "/src/project/node_modules/@types/react/index.d.ts": getJsxLibraryContent(), // doesn't contain a jsx-runtime definition + fs: () => ts.loadProjectFromFiles({ + "/src/project/node_modules/react/jsx-runtime.js": "export {}", + "/src/project/node_modules/@types/react/index.d.ts": getJsxLibraryContent(), "/src/project/src/index.tsx": `export const App = () =>
;`, "/src/project/tsconfig.json": JSON.stringify({ compilerOptions: { module: "commonjs", jsx: "react-jsx", incremental: true, jsxImportSource: "react" } }) }), @@ -333,11 +325,11 @@ declare global { }); }); - verifyTscWithEdits({ + ts.verifyTscWithEdits({ scenario: "incremental", subScenario: "when new file is added to the referenced project", commandLineArgs: ["-i", "-p", `src/projects/project2`], - fs: () => loadProjectFromFiles({ + fs: () => ts.loadProjectFromFiles({ "/src/projects/project1/tsconfig.json": JSON.stringify({ compilerOptions: { module: "none", @@ -394,11 +386,11 @@ declare global { }); - verifyTscWithEdits({ + ts.verifyTscWithEdits({ scenario: "incremental", subScenario: "when project has strict true", commandLineArgs: ["-noEmit", "-p", `src/project`], - fs: () => loadProjectFromFiles({ + fs: () => ts.loadProjectFromFiles({ "/src/project/tsconfig.json": JSON.stringify({ compilerOptions: { incremental: true, @@ -407,15 +399,15 @@ declare global { }), "/src/project/class1.ts": `export class class1 {}`, }), - edits: noChangeOnlyRuns, + edits: ts.noChangeOnlyRuns, baselinePrograms: true }); - verifyTscWithEdits({ + ts.verifyTscWithEdits({ scenario: "incremental", subScenario: "serializing error chains", commandLineArgs: ["-p", `src/project`], - fs: () => loadProjectFromFiles({ + fs: () => ts.loadProjectFromFiles({ "/src/project/tsconfig.json": JSON.stringify({ compilerOptions: { incremental: true, @@ -439,13 +431,13 @@ declare global {
)` }, `\ninterface ReadonlyArray { readonly length: number }`), - edits: noChangeOnlyRuns, + edits: ts.noChangeOnlyRuns, }); - verifyTsc({ + ts.verifyTsc({ scenario: "incremental", subScenario: "ts file with no-default-lib that augments the global scope", - fs: () => loadProjectFromFiles({ + fs: () => ts.loadProjectFromFiles({ "/src/project/src/main.ts": Utils.dedent` /// /// @@ -469,15 +461,15 @@ declare global { }), commandLineArgs: ["--p", "src/project", "--rootDir", "src/project/src"], modifyFs: (fs) => { - fs.writeFileSync("/lib/lib.esnext.d.ts", libContent); + fs.writeFileSync("/lib/lib.esnext.d.ts", ts.libContent); } }); - verifyTscWithEdits({ + ts.verifyTscWithEdits({ scenario: "incremental", subScenario: "change to type that gets used as global through export in another file", commandLineArgs: ["-p", `src/project`], - fs: () => loadProjectFromFiles({ + fs: () => ts.loadProjectFromFiles({ "/src/project/tsconfig.json": JSON.stringify({ compilerOptions: { composite: true }, }), "/src/project/class1.ts": `const a: MagicNumber = 1; console.log(a);`, @@ -490,11 +482,11 @@ console.log(a);`, }], }); - verifyTscWithEdits({ + ts.verifyTscWithEdits({ scenario: "incremental", subScenario: "change to type that gets used as global through export in another file through indirect import", commandLineArgs: ["-p", `src/project`], - fs: () => loadProjectFromFiles({ + fs: () => ts.loadProjectFromFiles({ "/src/project/tsconfig.json": JSON.stringify({ compilerOptions: { composite: true }, }), "/src/project/class1.ts": `const a: MagicNumber = 1; console.log(a);`, diff --git a/src/testRunner/unittests/tsc/listFilesOnly.ts b/src/testRunner/unittests/tsc/listFilesOnly.ts index 97c9bd7d5e43c..90bb5907105b9 100644 --- a/src/testRunner/unittests/tsc/listFilesOnly.ts +++ b/src/testRunner/unittests/tsc/listFilesOnly.ts @@ -1,19 +1,19 @@ namespace ts { describe("unittests:: tsc:: listFilesOnly::", () => { - verifyTsc({ + ts.verifyTsc({ scenario: "listFilesOnly", subScenario: "combined with watch", - fs: () => loadProjectFromFiles({ + fs: () => ts.loadProjectFromFiles({ "/src/test.ts": Utils.dedent` export const x = 1;`, }), commandLineArgs: ["/src/test.ts", "--watch", "--listFilesOnly"] }); - verifyTsc({ + ts.verifyTsc({ scenario: "listFilesOnly", subScenario: "loose file", - fs: () => loadProjectFromFiles({ + fs: () => ts.loadProjectFromFiles({ "/src/test.ts": Utils.dedent` export const x = 1;`, }), diff --git a/src/testRunner/unittests/tsc/projectReferences.ts b/src/testRunner/unittests/tsc/projectReferences.ts index 765bdfdb53cf1..7c4cd855282d5 100644 --- a/src/testRunner/unittests/tsc/projectReferences.ts +++ b/src/testRunner/unittests/tsc/projectReferences.ts @@ -1,9 +1,9 @@ namespace ts { describe("unittests:: tsc:: projectReferences::", () => { - verifyTsc({ + ts.verifyTsc({ scenario: "projectReferences", subScenario: "when project contains invalid project reference", - fs: () => loadProjectFromFiles({ + fs: () => ts.loadProjectFromFiles({ "/src/project/src/main.ts": "export const x = 10;", "/src/project/tsconfig.json": JSON.stringify({ compilerOptions: { @@ -18,10 +18,10 @@ namespace ts { commandLineArgs: ["--p", "src/project"], }); - verifyTsc({ + ts.verifyTsc({ scenario: "projectReferences", subScenario: "when project references composite project with noEmit", - fs: () => loadProjectFromFiles({ + fs: () => ts.loadProjectFromFiles({ "/src/utils/index.ts": "export const x = 10;", "/src/utils/tsconfig.json": JSON.stringify({ compilerOptions: { diff --git a/src/testRunner/unittests/tsc/redirect.ts b/src/testRunner/unittests/tsc/redirect.ts index e131ba821af4f..67a549b8dd765 100644 --- a/src/testRunner/unittests/tsc/redirect.ts +++ b/src/testRunner/unittests/tsc/redirect.ts @@ -1,9 +1,9 @@ namespace ts { describe("unittests:: tsc:: redirect::", () => { - verifyTsc({ + ts.verifyTsc({ scenario: "redirect", subScenario: "when redirecting ts file", - fs: () => loadProjectFromFiles({ + fs: () => ts.loadProjectFromFiles({ "/src/project/tsconfig.json": JSON.stringify({ compilerOptions: { outDir: "out" diff --git a/src/testRunner/unittests/tsc/runWithoutArgs.ts b/src/testRunner/unittests/tsc/runWithoutArgs.ts index 1c4a3c9a0a4f4..baa5b30a76cc8 100644 --- a/src/testRunner/unittests/tsc/runWithoutArgs.ts +++ b/src/testRunner/unittests/tsc/runWithoutArgs.ts @@ -1,24 +1,24 @@ namespace ts { describe("unittests:: tsc:: runWithoutArgs::", () => { - verifyTsc({ + ts.verifyTsc({ scenario: "runWithoutArgs", subScenario: "show help with ExitStatus.DiagnosticsPresent_OutputsSkipped", - fs: () => loadProjectFromFiles({}), + fs: () => ts.loadProjectFromFiles({}), commandLineArgs: [], environmentVariables: { TS_TEST_TERMINAL_WIDTH: "120" } }); - verifyTsc({ + ts.verifyTsc({ scenario: "runWithoutArgs", subScenario: "show help with ExitStatus.DiagnosticsPresent_OutputsSkipped when host can't provide terminal width", - fs: () => loadProjectFromFiles({}), + fs: () => ts.loadProjectFromFiles({}), commandLineArgs: [], }); - verifyTsc({ + ts.verifyTsc({ scenario: "runWithoutArgs", subScenario: "does not add color when NO_COLOR is set", - fs: () => loadProjectFromFiles({}), + fs: () => ts.loadProjectFromFiles({}), commandLineArgs: [], environmentVariables: { NO_COLOR: "true" } }); diff --git a/src/testRunner/unittests/tscWatch/consoleClearing.ts b/src/testRunner/unittests/tscWatch/consoleClearing.ts index bde7b6c901863..26fbd7ec2ec3f 100644 --- a/src/testRunner/unittests/tscWatch/consoleClearing.ts +++ b/src/testRunner/unittests/tscWatch/consoleClearing.ts @@ -1,23 +1,23 @@ namespace ts.tscWatch { describe("unittests:: tsc-watch:: console clearing", () => { const scenario = "consoleClearing"; - const file: File = { + const file: ts.tscWatch.File = { path: "/f.ts", content: "" }; - const makeChangeToFile: TscWatchCompileChange[] = [{ + const makeChangeToFile: ts.tscWatch.TscWatchCompileChange[] = [{ caption: "Comment added to file f", change: sys => sys.modifyFile(file.path, "//"), - timeouts: runQueuedTimeoutCallbacks, + timeouts: ts.tscWatch.runQueuedTimeoutCallbacks, }]; function checkConsoleClearingUsingCommandLineOptions(subScenario: string, commandLineOptions?: string[]) { - verifyTscWatch({ + ts.tscWatch.verifyTscWatch({ scenario, subScenario, - commandLineArgs: ["--w", file.path, ...commandLineOptions || emptyArray], - sys: () => createWatchedSystem([file, libFile]), + commandLineArgs: ["--w", file.path, ...commandLineOptions || ts.emptyArray], + sys: () => ts.tscWatch.createWatchedSystem([file, ts.tscWatch.libFile]), changes: makeChangeToFile, }); } @@ -28,23 +28,23 @@ namespace ts.tscWatch { checkConsoleClearingUsingCommandLineOptions("with --preserveWatchOutput", ["--preserveWatchOutput"]); describe("when preserveWatchOutput is true in config file", () => { - const compilerOptions: CompilerOptions = { + const compilerOptions: ts.CompilerOptions = { preserveWatchOutput: true }; - const configFile: File = { + const configFile: ts.tscWatch.File = { path: "/tsconfig.json", content: JSON.stringify({ compilerOptions }) }; - const files = [file, configFile, libFile]; + const files = [file, configFile, ts.tscWatch.libFile]; it("using createWatchOfConfigFile ", () => { - const baseline = createBaseline(createWatchedSystem(files)); - const watch = createWatchProgram(createWatchCompilerHostOfConfigFileForBaseline({ + const baseline = ts.tscWatch.createBaseline(ts.tscWatch.createWatchedSystem(files)); + const watch = ts.createWatchProgram(ts.tscWatch.createWatchCompilerHostOfConfigFileForBaseline({ system: baseline.sys, cb: baseline.cb, configFileName: configFile.path, })); // Initially console is cleared if --preserveOutput is not provided since the config file is yet to be parsed - runWatchBaseline({ + ts.tscWatch.runWatchBaseline({ scenario, subScenario: "when preserveWatchOutput is true in config file/createWatchOfConfigFile", commandLineArgs: ["--w", "-p", configFile.path], @@ -54,11 +54,11 @@ namespace ts.tscWatch { watchOrSolution: watch }); }); - verifyTscWatch({ + ts.tscWatch.verifyTscWatch({ scenario, subScenario: "when preserveWatchOutput is true in config file/when createWatchProgram is invoked with configFileParseResult on WatchCompilerHostOfConfigFile", commandLineArgs: ["--w", "-p", configFile.path], - sys: () => createWatchedSystem(files), + sys: () => ts.tscWatch.createWatchedSystem(files), changes: makeChangeToFile, }); }); diff --git a/src/testRunner/unittests/tscWatch/emit.ts b/src/testRunner/unittests/tscWatch/emit.ts index 217d4c059a5ba..016fce2c6e1d5 100644 --- a/src/testRunner/unittests/tscWatch/emit.ts +++ b/src/testRunner/unittests/tscWatch/emit.ts @@ -2,35 +2,35 @@ namespace ts.tscWatch { const scenario = "emit"; describe("unittests:: tsc-watch:: emit with outFile or out setting", () => { function verifyOutAndOutFileSetting(subScenario: string, out?: string, outFile?: string) { - verifyTscWatch({ + ts.tscWatch.verifyTscWatch({ scenario, subScenario: `emit with outFile or out setting/${subScenario}`, commandLineArgs: ["--w", "-p", "/a/tsconfig.json"], sys: () => { - const config: File = { + const config: ts.tscWatch.File = { path: "/a/tsconfig.json", content: JSON.stringify({ compilerOptions: { out, outFile } }) }; - const f1: File = { + const f1: ts.tscWatch.File = { path: "/a/a.ts", content: "let x = 1" }; - const f2: File = { + const f2: ts.tscWatch.File = { path: "/a/b.ts", content: "let y = 1" }; - return createWatchedSystem([f1, f2, config, libFile]); + return ts.tscWatch.createWatchedSystem([f1, f2, config, ts.tscWatch.libFile]); }, changes: [ { caption: "Make change in the file", change: sys => sys.writeFile("/a/a.ts", "let x = 11"), - timeouts: runQueuedTimeoutCallbacks + timeouts: ts.tscWatch.runQueuedTimeoutCallbacks }, { caption: "Make change in the file again", change: sys => sys.writeFile("/a/a.ts", "let xy = 11"), - timeouts: runQueuedTimeoutCallbacks + timeouts: ts.tscWatch.runQueuedTimeoutCallbacks } ] }); @@ -40,28 +40,28 @@ namespace ts.tscWatch { verifyOutAndOutFileSetting("config has outFile", /*out*/ undefined, "/a/out.js"); function verifyFilesEmittedOnce(subScenario: string, useOutFile: boolean) { - verifyTscWatch({ + ts.tscWatch.verifyTscWatch({ scenario, subScenario: `emit with outFile or out setting/${subScenario}`, commandLineArgs: ["--w", "-p", "/a/b/project/tsconfig.json"], sys: () => { - const file1: File = { + const file1: ts.tscWatch.File = { path: "/a/b/output/AnotherDependency/file1.d.ts", content: "declare namespace Common.SomeComponent.DynamicMenu { enum Z { Full = 0, Min = 1, Average = 2, } }" }; - const file2: File = { + const file2: ts.tscWatch.File = { path: "/a/b/dependencies/file2.d.ts", content: "declare namespace Dependencies.SomeComponent { export class SomeClass { version: string; } }" }; - const file3: File = { + const file3: ts.tscWatch.File = { path: "/a/b/project/src/main.ts", content: "namespace Main { export function fooBar() {} }" }; - const file4: File = { + const file4: ts.tscWatch.File = { path: "/a/b/project/src/main2.ts", content: "namespace main.file4 { import DynamicMenu = Common.SomeComponent.DynamicMenu; export function foo(a: DynamicMenu.z) { } }" }; - const configFile: File = { + const configFile: ts.tscWatch.File = { path: "/a/b/project/tsconfig.json", content: JSON.stringify({ compilerOptions: useOutFile ? @@ -70,9 +70,9 @@ namespace ts.tscWatch { files: [file1.path, file2.path, file3.path, file4.path] }) }; - return createWatchedSystem([file1, file2, file3, file4, libFile, configFile]); + return ts.tscWatch.createWatchedSystem([file1, file2, file3, file4, ts.tscWatch.libFile, configFile]); }, - changes: emptyArray + changes: ts.emptyArray }); } verifyFilesEmittedOnce("with --outFile and multiple declaration files in the program", /*useOutFile*/ true); @@ -91,69 +91,62 @@ namespace ts.tscWatch { /** custom config file options */ configObj?: any; /** Additional files and folders to add */ - getAdditionalFileOrFolder?: () => File[]; + getAdditionalFileOrFolder?: () => ts.tscWatch.File[]; /** initial list of files to emit if not the default list */ firstReloadFileList?: string[]; - changes: TscWatchCompileChange[] + changes: ts.tscWatch.TscWatchCompileChange[]; } - function verifyTscWatchEmit({ - subScenario, - configObj, - getAdditionalFileOrFolder, - firstReloadFileList, - changes - }: VerifyTscWatchEmit) { - verifyTscWatch({ + function verifyTscWatchEmit({ subScenario, configObj, getAdditionalFileOrFolder, firstReloadFileList, changes }: VerifyTscWatchEmit) { + ts.tscWatch.verifyTscWatch({ scenario, subScenario: `emit for configured projects/${subScenario}`, commandLineArgs: ["--w", "-p", configFilePath], sys: () => { - const moduleFile1: File = { + const moduleFile1: ts.tscWatch.File = { path: moduleFile1Path, content: "export function Foo() { };", }; - const file1Consumer1: File = { + const file1Consumer1: ts.tscWatch.File = { path: file1Consumer1Path, content: `import {Foo} from "./moduleFile1"; export var y = 10;`, }; - const file1Consumer2: File = { + const file1Consumer2: ts.tscWatch.File = { path: file1Consumer2Path, content: `import {Foo} from "./moduleFile1"; let z = 10;`, }; - const moduleFile2: File = { + const moduleFile2: ts.tscWatch.File = { path: moduleFile2Path, content: `export var Foo4 = 10;`, }; - const globalFile3: File = { + const globalFile3: ts.tscWatch.File = { path: globalFilePath, content: `interface GlobalFoo { age: number }` }; - const configFile: File = { + const configFile: ts.tscWatch.File = { path: configFilePath, content: JSON.stringify(configObj || {}) }; - const additionalFiles = getAdditionalFileOrFolder?.() || emptyArray; - const files = [moduleFile1, file1Consumer1, file1Consumer2, globalFile3, moduleFile2, configFile, libFile, ...additionalFiles]; - return createWatchedSystem(firstReloadFileList ? - map(firstReloadFileList, fileName => find(files, file => file.path === fileName)!) : - files - ); + const additionalFiles = getAdditionalFileOrFolder?.() || ts.emptyArray; + const files = [moduleFile1, file1Consumer1, file1Consumer2, globalFile3, moduleFile2, configFile, ts.tscWatch.libFile, ...additionalFiles]; + return ts.tscWatch.createWatchedSystem(firstReloadFileList ? + ts.map(firstReloadFileList, fileName => ts.find(files, file => file.path === fileName)!) : + files); }, changes }); } - function modifyModuleFile1Shape(sys: WatchedSystem) { + function modifyModuleFile1Shape(sys: ts.tscWatch.WatchedSystem) { sys.writeFile(moduleFile1Path, `export var T: number;export function Foo() { };`); } - const changeModuleFile1Shape: TscWatchCompileChange = { + const changeModuleFile1Shape: ts.tscWatch.TscWatchCompileChange = { caption: "Change the content of moduleFile1 to `export var T: number;export function Foo() { };`", change: modifyModuleFile1Shape, - timeouts: checkSingleTimeoutQueueLengthAndRun, + timeouts: ts.tscWatch.checkSingleTimeoutQueueLengthAndRun, }; verifyTscWatchEmit({ @@ -163,7 +156,7 @@ namespace ts.tscWatch { { caption: "Change the content of moduleFile1 to `export var T: number;export function Foo() { console.log('hi'); };`", change: sys => sys.writeFile(moduleFile1Path, `export var T: number;export function Foo() { console.log('hi'); };`), - timeouts: checkSingleTimeoutQueueLengthAndRun, + timeouts: ts.tscWatch.checkSingleTimeoutQueueLengthAndRun, } ] }); @@ -174,18 +167,18 @@ namespace ts.tscWatch { { caption: "Change file1Consumer1 content to `export let y = Foo();`", change: sys => sys.writeFile(file1Consumer1Path, `export let y = Foo();`), - timeouts: checkSingleTimeoutQueueLengthAndRun, + timeouts: ts.tscWatch.checkSingleTimeoutQueueLengthAndRun, }, changeModuleFile1Shape, { caption: "Add the import statements back to file1Consumer1", change: sys => sys.writeFile(file1Consumer1Path, `import {Foo} from "./moduleFile1";let y = Foo();`), - timeouts: checkSingleTimeoutQueueLengthAndRun, + timeouts: ts.tscWatch.checkSingleTimeoutQueueLengthAndRun, }, { caption: "Change the content of moduleFile1 to `export var T: number;export var T2: string;export function Foo() { };`", change: sys => sys.writeFile(moduleFile1Path, `export let y = Foo();`), - timeouts: checkSingleTimeoutQueueLengthAndRun, + timeouts: ts.tscWatch.checkSingleTimeoutQueueLengthAndRun, }, { caption: "Multiple file edits in one go", @@ -195,7 +188,7 @@ namespace ts.tscWatch { sys.writeFile(file1Consumer1Path, `import {Foo} from "./moduleFile1";let y = Foo();`); modifyModuleFile1Shape(sys); }, - timeouts: checkSingleTimeoutQueueLengthAndRun, + timeouts: ts.tscWatch.checkSingleTimeoutQueueLengthAndRun, } ] }); @@ -209,7 +202,7 @@ namespace ts.tscWatch { modifyModuleFile1Shape(sys); sys.deleteFile(file1Consumer2Path); }, - timeouts: checkSingleTimeoutQueueLengthAndRun, + timeouts: ts.tscWatch.checkSingleTimeoutQueueLengthAndRun, } ] }); @@ -223,7 +216,7 @@ namespace ts.tscWatch { sys.writeFile("/a/b/file1Consumer3.ts", `import {Foo} from "./moduleFile1"; let y = Foo();`); modifyModuleFile1Shape(sys); }, - timeouts: checkSingleTimeoutQueueLengthAndRun, + timeouts: ts.tscWatch.checkSingleTimeoutQueueLengthAndRun, } ] }); @@ -236,7 +229,7 @@ namespace ts.tscWatch { { caption: "change file1 internal, and verify only file1 is affected", change: sys => sys.appendFile(moduleFile1Path, "var T1: number;"), - timeouts: checkSingleTimeoutQueueLengthAndRun, + timeouts: ts.tscWatch.checkSingleTimeoutQueueLengthAndRun, } ] }); @@ -247,7 +240,7 @@ namespace ts.tscWatch { { caption: "change shape of global file", change: sys => sys.appendFile(globalFilePath, "var T2: string;"), - timeouts: checkSingleTimeoutQueueLengthAndRun, + timeouts: ts.tscWatch.checkSingleTimeoutQueueLengthAndRun, } ] }); @@ -278,7 +271,7 @@ namespace ts.tscWatch { { caption: "change file1Consumer1", change: sys => sys.appendFile(file1Consumer1Path, "export var T: number;"), - timeouts: checkSingleTimeoutQueueLengthAndRun, + timeouts: ts.tscWatch.checkSingleTimeoutQueueLengthAndRun, }, changeModuleFile1Shape, { @@ -287,7 +280,7 @@ namespace ts.tscWatch { sys.appendFile(file1Consumer1Path, "export var T2: number;"); sys.writeFile(moduleFile1Path, `export var T2: number;export function Foo() { };`); }, - timeouts: checkSingleTimeoutQueueLengthAndRun, + timeouts: ts.tscWatch.checkSingleTimeoutQueueLengthAndRun, } ] }); @@ -306,12 +299,12 @@ export var t1 = 10;` export var t2 = 10;` } ], - firstReloadFileList: [libFile.path, "/a/b/file1.ts", "/a/b/file2.ts", configFilePath], + firstReloadFileList: [ts.tscWatch.libFile.path, "/a/b/file1.ts", "/a/b/file2.ts", configFilePath], changes: [ { caption: "change file1", change: sys => sys.appendFile("/a/b/file1.ts", "export var t3 = 10;"), - timeouts: checkSingleTimeoutQueueLengthAndRun, + timeouts: ts.tscWatch.checkSingleTimeoutQueueLengthAndRun, } ] }); @@ -323,12 +316,12 @@ export var t2 = 10;` content: `/// export var x = Foo();` }], - firstReloadFileList: [libFile.path, "/a/b/referenceFile1.ts", moduleFile1Path, configFilePath], + firstReloadFileList: [ts.tscWatch.libFile.path, "/a/b/referenceFile1.ts", moduleFile1Path, configFilePath], changes: [ { caption: "delete moduleFile1", change: sys => sys.deleteFile(moduleFile1Path), - timeouts: checkSingleTimeoutQueueLengthAndRun, + timeouts: ts.tscWatch.checkSingleTimeoutQueueLengthAndRun, } ] }); @@ -340,17 +333,17 @@ export var x = Foo();` content: `/// export var x = Foo();` }], - firstReloadFileList: [libFile.path, "/a/b/referenceFile1.ts", configFilePath], + firstReloadFileList: [ts.tscWatch.libFile.path, "/a/b/referenceFile1.ts", configFilePath], changes: [ { caption: "edit refereceFile1", change: sys => sys.appendFile("/a/b/referenceFile1.ts", "export var yy = Foo();"), - timeouts: checkSingleTimeoutQueueLengthAndRun, + timeouts: ts.tscWatch.checkSingleTimeoutQueueLengthAndRun, }, { caption: "create moduleFile2", change: sys => sys.writeFile(moduleFile2Path, "export var Foo4 = 10;"), - timeouts: checkSingleTimeoutQueueLengthAndRun, + timeouts: ts.tscWatch.checkSingleTimeoutQueueLengthAndRun, } ] }); @@ -358,25 +351,22 @@ export var x = Foo();` describe("unittests:: tsc-watch:: emit file content", () => { function verifyNewLine(subScenario: string, newLine: string) { - verifyTscWatch({ + ts.tscWatch.verifyTscWatch({ scenario, subScenario: `emit file content/${subScenario}`, commandLineArgs: ["--w", "/a/app.ts"], - sys: () => createWatchedSystem( - [ + sys: () => ts.tscWatch.createWatchedSystem([ { path: "/a/app.ts", content: ["var x = 1;", "var y = 2;"].join(newLine) }, - libFile - ], - { newLine } - ), + ts.tscWatch.libFile + ], { newLine }), changes: [ { caption: "Append a line", change: sys => sys.appendFile("/a/app.ts", newLine + "var z = 3;"), - timeouts: checkSingleTimeoutQueueLengthAndRun, + timeouts: ts.tscWatch.checkSingleTimeoutQueueLengthAndRun, } ], }); @@ -384,7 +374,7 @@ export var x = Foo();` verifyNewLine("handles new lines lineFeed", "\n"); verifyNewLine("handles new lines carriageReturn lineFeed", "\r\n"); - verifyTscWatch({ + ts.tscWatch.verifyTscWatch({ scenario, subScenario: "emit file content/should emit specified file", commandLineArgs: ["-w", "-p", "/a/b/tsconfig.json"], @@ -408,62 +398,62 @@ export var x = Foo();` path: "/a/b/tsconfig.json", content: "{}" }; - return createWatchedSystem([file1, file2, file3, configFile, libFile]); + return ts.tscWatch.createWatchedSystem([file1, file2, file3, configFile, ts.tscWatch.libFile]); }, changes: [ { caption: "Append content to f1", change: sys => sys.appendFile("/a/b/f1.ts", "export function foo2() { return 2; }"), - timeouts: checkSingleTimeoutQueueLengthAndRun, + timeouts: ts.tscWatch.checkSingleTimeoutQueueLengthAndRun, }, { caption: "Again Append content to f1", change: sys => sys.appendFile("/a/b/f1.ts", "export function fooN() { return 2; }"), - timeouts: checkSingleTimeoutQueueLengthAndRun, + timeouts: ts.tscWatch.checkSingleTimeoutQueueLengthAndRun, } ], }); - verifyTscWatch({ + ts.tscWatch.verifyTscWatch({ scenario, subScenario: "emit file content/elides const enums correctly in incremental compilation", commandLineArgs: ["-w", "/user/someone/projects/myproject/file3.ts"], sys: () => { const currentDirectory = "/user/someone/projects/myproject"; - const file1: File = { + const file1: ts.tscWatch.File = { path: `${currentDirectory}/file1.ts`, content: "export const enum E1 { V = 1 }" }; - const file2: File = { + const file2: ts.tscWatch.File = { path: `${currentDirectory}/file2.ts`, content: `import { E1 } from "./file1"; export const enum E2 { V = E1.V }` }; - const file3: File = { + const file3: ts.tscWatch.File = { path: `${currentDirectory}/file3.ts`, content: `import { E2 } from "./file2"; const v: E2 = E2.V;` }; - return createWatchedSystem([file1, file2, file3, libFile]); + return ts.tscWatch.createWatchedSystem([file1, file2, file3, ts.tscWatch.libFile]); }, changes: [ { caption: "Append content to file3", change: sys => sys.appendFile("/user/someone/projects/myproject/file3.ts", "function foo2() { return 2; }"), - timeouts: checkSingleTimeoutQueueLengthAndRun, + timeouts: ts.tscWatch.checkSingleTimeoutQueueLengthAndRun, } ], }); - verifyTscWatch({ + ts.tscWatch.verifyTscWatch({ scenario, subScenario: "emit file content/file is deleted and created as part of change", commandLineArgs: ["-w"], sys: () => { const projectLocation = "/home/username/project"; - const file: File = { + const file: ts.tscWatch.File = { path: `${projectLocation}/app/file.ts`, content: "var a = 10;" }; - const configFile: File = { + const configFile: ts.tscWatch.File = { path: `${projectLocation}/tsconfig.json`, content: JSON.stringify({ include: [ @@ -471,26 +461,26 @@ export var x = Foo();` ] }) }; - const files = [file, configFile, libFile]; - return createWatchedSystem(files, { currentDirectory: projectLocation, useCaseSensitiveFileNames: true }); + const files = [file, configFile, ts.tscWatch.libFile]; + return ts.tscWatch.createWatchedSystem(files, { currentDirectory: projectLocation, useCaseSensitiveFileNames: true }); }, changes: [ { caption: "file is deleted and then created to modify content", change: sys => sys.appendFile("/home/username/project/app/file.ts", "\nvar b = 10;", { invokeFileDeleteCreateAsPartInsteadOfChange: true }), - timeouts: checkSingleTimeoutQueueLengthAndRun, + timeouts: ts.tscWatch.checkSingleTimeoutQueueLengthAndRun, } ] }); }); describe("unittests:: tsc-watch:: emit with when module emit is specified as node", () => { - verifyTscWatch({ + ts.tscWatch.verifyTscWatch({ scenario, subScenario: "when module emit is specified as node/when instead of filechanged recursive directory watcher is invoked", commandLineArgs: ["--w", "--p", "/a/rootFolder/project/tsconfig.json"], sys: () => { - const configFile: File = { + const configFile: ts.tscWatch.File = { path: "/a/rootFolder/project/tsconfig.json", content: JSON.stringify({ compilerOptions: { @@ -503,25 +493,21 @@ export var x = Foo();` ], }) }; - const file1: File = { + const file1: ts.tscWatch.File = { path: "/a/rootFolder/project/Scripts/TypeScript.ts", content: "var z = 10;" }; - const file2: File = { + const file2: ts.tscWatch.File = { path: "/a/rootFolder/project/Scripts/Javascript.js", content: "var zz = 10;" }; - return createWatchedSystem([configFile, file1, file2, libFile]); + return ts.tscWatch.createWatchedSystem([configFile, file1, file2, ts.tscWatch.libFile]); }, changes: [ { caption: "Modify typescript file", - change: sys => sys.modifyFile( - "/a/rootFolder/project/Scripts/TypeScript.ts", - "var zz30 = 100;", - { invokeDirectoryWatcherInsteadOfFileChanged: true }, - ), - timeouts: runQueuedTimeoutCallbacks, + change: sys => sys.modifyFile("/a/rootFolder/project/Scripts/TypeScript.ts", "var zz30 = 100;", { invokeDirectoryWatcherInsteadOfFileChanged: true }), + timeouts: ts.tscWatch.runQueuedTimeoutCallbacks, } ], }); diff --git a/src/testRunner/unittests/tscWatch/emitAndErrorUpdates.ts b/src/testRunner/unittests/tscWatch/emitAndErrorUpdates.ts index 598b422d5bab7..52b6ab0524ca7 100644 --- a/src/testRunner/unittests/tscWatch/emitAndErrorUpdates.ts +++ b/src/testRunner/unittests/tscWatch/emitAndErrorUpdates.ts @@ -1,46 +1,32 @@ namespace ts.tscWatch { describe("unittests:: tsc-watch:: Emit times and Error updates in builder after program changes", () => { - const config: File = { - path: `${projectRoot}/tsconfig.json`, + const config: ts.tscWatch.File = { + path: `${ts.tscWatch.projectRoot}/tsconfig.json`, content: `{}` }; interface VerifyEmitAndErrorUpdatesWorker extends VerifyEmitAndErrorUpdates { - configFile: () => File; + configFile: () => ts.tscWatch.File; } - function verifyEmitAndErrorUpdatesWorker({ - subScenario, - files, - currentDirectory, - lib, - configFile, - changes, - baselineIncremental - }: VerifyEmitAndErrorUpdatesWorker) { - verifyTscWatch({ + function verifyEmitAndErrorUpdatesWorker({ subScenario, files, currentDirectory, lib, configFile, changes, baselineIncremental }: VerifyEmitAndErrorUpdatesWorker) { + ts.tscWatch.verifyTscWatch({ scenario: "emitAndErrorUpdates", subScenario, commandLineArgs: ["--w"], - sys: () => createWatchedSystem( - [...files(), configFile(), lib?.() || libFile], - { currentDirectory: currentDirectory || projectRoot } - ), + sys: () => ts.tscWatch.createWatchedSystem([...files(), configFile(), lib?.() || ts.tscWatch.libFile], { currentDirectory: currentDirectory || ts.tscWatch.projectRoot }), changes, baselineIncremental }); - verifyTscWatch({ + ts.tscWatch.verifyTscWatch({ scenario: "emitAndErrorUpdates", subScenario: `incremental/${subScenario}`, commandLineArgs: ["--w", "--i"], - sys: () => createWatchedSystem( - [...files(), configFile(), lib?.() || libFile], - { currentDirectory: currentDirectory || projectRoot } - ), + sys: () => ts.tscWatch.createWatchedSystem([...files(), configFile(), lib?.() || ts.tscWatch.libFile], { currentDirectory: currentDirectory || ts.tscWatch.projectRoot }), changes, baselineIncremental }); } - function changeCompilerOptions(input: VerifyEmitAndErrorUpdates, additionalOptions: CompilerOptions): File { + function changeCompilerOptions(input: VerifyEmitAndErrorUpdates, additionalOptions: ts.CompilerOptions): ts.tscWatch.File { const configFile = input.configFile?.() || config; const content = JSON.parse(configFile.content); content.compilerOptions = { ...content.compilerOptions, ...additionalOptions }; @@ -48,13 +34,13 @@ namespace ts.tscWatch { } interface VerifyEmitAndErrorUpdates { - subScenario: string - files: () => File[]; + subScenario: string; + files: () => ts.tscWatch.File[]; currentDirectory?: string; - lib?: () => File; - changes: TscWatchCompileChange[]; - configFile?: () => File; - baselineIncremental?: boolean + lib?: () => ts.tscWatch.File; + changes: ts.tscWatch.TscWatchCompileChange[]; + configFile?: () => ts.tscWatch.File; + baselineIncremental?: boolean; } function verifyEmitAndErrorUpdates(input: VerifyEmitAndErrorUpdates) { verifyEmitAndErrorUpdatesWorker({ @@ -95,15 +81,15 @@ namespace ts.tscWatch { } describe("deep import changes", () => { - const aFile: File = { - path: `${projectRoot}/a.ts`, + const aFile: ts.tscWatch.File = { + path: `${ts.tscWatch.projectRoot}/a.ts`, content: `import {B} from './b'; declare var console: any; let b = new B(); console.log(b.c.d);` }; - function verifyDeepImportChange(subScenario: string, bFile: File, cFile: File) { + function verifyDeepImportChange(subScenario: string, bFile: ts.tscWatch.File, cFile: ts.tscWatch.File) { verifyEmitAndErrorUpdates({ subScenario: `deepImportChanges/${subScenario}`, files: () => [aFile, bFile, cFile], @@ -111,70 +97,62 @@ console.log(b.c.d);` { caption: "Rename property d to d2 of class C to initialize signatures", change: sys => sys.writeFile(cFile.path, cFile.content.replace("d", "d2")), - timeouts: runQueuedTimeoutCallbacks, + timeouts: ts.tscWatch.runQueuedTimeoutCallbacks, }, { caption: "Rename property d2 to d of class C to revert back to original text", change: sys => sys.writeFile(cFile.path, cFile.content.replace("d2", "d")), - timeouts: runQueuedTimeoutCallbacks, + timeouts: ts.tscWatch.runQueuedTimeoutCallbacks, }, { caption: "Rename property d to d2 of class C", change: sys => sys.writeFile(cFile.path, cFile.content.replace("d", "d2")), - timeouts: runQueuedTimeoutCallbacks, + timeouts: ts.tscWatch.runQueuedTimeoutCallbacks, } ], }); } describe("updates errors when deep import file changes", () => { - const bFile: File = { - path: `${projectRoot}/b.ts`, + const bFile: ts.tscWatch.File = { + path: `${ts.tscWatch.projectRoot}/b.ts`, content: `import {C} from './c'; export class B { c = new C(); }` }; - const cFile: File = { - path: `${projectRoot}/c.ts`, + const cFile: ts.tscWatch.File = { + path: `${ts.tscWatch.projectRoot}/c.ts`, content: `export class C { d = 1; }` }; - verifyDeepImportChange( - "errors for .ts change", - bFile, - cFile - ); + verifyDeepImportChange("errors for .ts change", bFile, cFile); }); describe("updates errors when deep import through declaration file changes", () => { - const bFile: File = { - path: `${projectRoot}/b.d.ts`, + const bFile: ts.tscWatch.File = { + path: `${ts.tscWatch.projectRoot}/b.d.ts`, content: `import {C} from './c'; export class B { c: C; }` }; - const cFile: File = { - path: `${projectRoot}/c.d.ts`, + const cFile: ts.tscWatch.File = { + path: `${ts.tscWatch.projectRoot}/c.d.ts`, content: `export class C { d: number; }` }; - verifyDeepImportChange( - "errors for .d.ts change", - bFile, - cFile - ); + verifyDeepImportChange("errors for .d.ts change", bFile, cFile); }); }); describe("updates errors in file not exporting a deep multilevel import that changes", () => { - const aFile: File = { - path: `${projectRoot}/a.ts`, + const aFile: ts.tscWatch.File = { + path: `${ts.tscWatch.projectRoot}/a.ts`, content: `export interface Point { name: string; c: Coords; @@ -184,14 +162,14 @@ export interface Coords { y: number; }` }; - const bFile: File = { - path: `${projectRoot}/b.ts`, + const bFile: ts.tscWatch.File = { + path: `${ts.tscWatch.projectRoot}/b.ts`, content: `import { Point } from "./a"; export interface PointWrapper extends Point { }` }; - const cFile: File = { - path: `${projectRoot}/c.ts`, + const cFile: ts.tscWatch.File = { + path: `${ts.tscWatch.projectRoot}/c.ts`, content: `import { PointWrapper } from "./b"; export function getPoint(): PointWrapper { return { @@ -203,13 +181,13 @@ export function getPoint(): PointWrapper { } };` }; - const dFile: File = { - path: `${projectRoot}/d.ts`, + const dFile: ts.tscWatch.File = { + path: `${ts.tscWatch.projectRoot}/d.ts`, content: `import { getPoint } from "./c"; getPoint().c.x;` }; - const eFile: File = { - path: `${projectRoot}/e.ts`, + const eFile: ts.tscWatch.File = { + path: `${ts.tscWatch.projectRoot}/e.ts`, content: `import "./d";` }; verifyEmitAndErrorUpdates({ @@ -219,31 +197,31 @@ getPoint().c.x;` { caption: "Rename property x2 to x of interface Coords to initialize signatures", change: sys => sys.writeFile(aFile.path, aFile.content.replace("x2", "x")), - timeouts: runQueuedTimeoutCallbacks, + timeouts: ts.tscWatch.runQueuedTimeoutCallbacks, }, { caption: "Rename property x to x2 of interface Coords to revert back to original text", change: sys => sys.writeFile(aFile.path, aFile.content.replace("x: number", "x2: number")), - timeouts: runQueuedTimeoutCallbacks, + timeouts: ts.tscWatch.runQueuedTimeoutCallbacks, }, { caption: "Rename property x2 to x of interface Coords", change: sys => sys.writeFile(aFile.path, aFile.content.replace("x2", "x")), - timeouts: runQueuedTimeoutCallbacks, + timeouts: ts.tscWatch.runQueuedTimeoutCallbacks, }, ] }); }); describe("updates errors when file transitively exported file changes", () => { - const config: File = { - path: `${projectRoot}/tsconfig.json`, + const config: ts.tscWatch.File = { + path: `${ts.tscWatch.projectRoot}/tsconfig.json`, content: JSON.stringify({ files: ["app.ts"], compilerOptions: { baseUrl: "." } }) }; - const app: File = { - path: `${projectRoot}/app.ts`, + const app: ts.tscWatch.File = { + path: `${ts.tscWatch.projectRoot}/app.ts`, content: `import { Data } from "lib2/public"; export class App { public constructor() { @@ -251,12 +229,12 @@ export class App { } }` }; - const lib2Public: File = { - path: `${projectRoot}/lib2/public.ts`, + const lib2Public: ts.tscWatch.File = { + path: `${ts.tscWatch.projectRoot}/lib2/public.ts`, content: `export * from "./data";` }; - const lib2Data: File = { - path: `${projectRoot}/lib2/data.ts`, + const lib2Data: ts.tscWatch.File = { + path: `${ts.tscWatch.projectRoot}/lib2/data.ts`, content: `import { ITest } from "lib1/public"; export class Data { public test() { @@ -267,22 +245,22 @@ export class Data { } }` }; - const lib1Public: File = { - path: `${projectRoot}/lib1/public.ts`, + const lib1Public: ts.tscWatch.File = { + path: `${ts.tscWatch.projectRoot}/lib1/public.ts`, content: `export * from "./tools/public";` }; - const lib1ToolsPublic: File = { - path: `${projectRoot}/lib1/tools/public.ts`, + const lib1ToolsPublic: ts.tscWatch.File = { + path: `${ts.tscWatch.projectRoot}/lib1/tools/public.ts`, content: `export * from "./tools.interface";` }; - const lib1ToolsInterface: File = { - path: `${projectRoot}/lib1/tools/tools.interface.ts`, + const lib1ToolsInterface: ts.tscWatch.File = { + path: `${ts.tscWatch.projectRoot}/lib1/tools/tools.interface.ts`, content: `export interface ITest { title: string; }` }; - function verifyTransitiveExports(subScenario: string, files: readonly File[]) { + function verifyTransitiveExports(subScenario: string, files: readonly ts.tscWatch.File[]) { verifyEmitAndErrorUpdates({ subScenario: `transitive exports/${subScenario}`, files: () => [lib1ToolsInterface, lib1ToolsPublic, app, lib2Public, lib1Public, ...files], @@ -291,30 +269,27 @@ export class Data { { caption: "Rename property title to title2 of interface ITest to initialize signatures", change: sys => sys.writeFile(lib1ToolsInterface.path, lib1ToolsInterface.content.replace("title", "title2")), - timeouts: runQueuedTimeoutCallbacks, + timeouts: ts.tscWatch.runQueuedTimeoutCallbacks, }, { caption: "Rename property title2 to title of interface ITest to revert back to original text", change: sys => sys.writeFile(lib1ToolsInterface.path, lib1ToolsInterface.content.replace("title2", "title")), - timeouts: runQueuedTimeoutCallbacks, + timeouts: ts.tscWatch.runQueuedTimeoutCallbacks, }, { caption: "Rename property title to title2 of interface ITest", change: sys => sys.writeFile(lib1ToolsInterface.path, lib1ToolsInterface.content.replace("title", "title2")), - timeouts: runQueuedTimeoutCallbacks, + timeouts: ts.tscWatch.runQueuedTimeoutCallbacks, } ] }); } describe("when there are no circular import and exports", () => { - verifyTransitiveExports( - "no circular import/export", - [lib2Data] - ); + verifyTransitiveExports("no circular import/export", [lib2Data]); }); describe("when there are circular import and exports", () => { - const lib2Data: File = { - path: `${projectRoot}/lib2/data.ts`, + const lib2Data: ts.tscWatch.File = { + path: `${ts.tscWatch.projectRoot}/lib2/data.ts`, content: `import { ITest } from "lib1/public"; import { Data2 } from "./data2"; export class Data { public dat?: Data2; public test() { @@ -325,42 +300,39 @@ export class Data { } }` }; - const lib2Data2: File = { - path: `${projectRoot}/lib2/data2.ts`, + const lib2Data2: ts.tscWatch.File = { + path: `${ts.tscWatch.projectRoot}/lib2/data2.ts`, content: `import { Data } from "./data"; export class Data2 { public dat?: Data; }` }; - verifyTransitiveExports( - "yes circular import/exports", - [lib2Data, lib2Data2] - ); + verifyTransitiveExports("yes circular import/exports", [lib2Data, lib2Data2]); }); }); describe("with noEmitOnError", () => { - function change(caption: string, content: string): TscWatchCompileChange { + function change(caption: string, content: string): ts.tscWatch.TscWatchCompileChange { return { caption, - change: sys => sys.writeFile(`${TestFSWithWatch.tsbuildProjectsLocation}/noEmitOnError/src/main.ts`, content), + change: sys => sys.writeFile(`${ts.TestFSWithWatch.tsbuildProjectsLocation}/noEmitOnError/src/main.ts`, content), // build project - timeouts: checkSingleTimeoutQueueLengthAndRun + timeouts: ts.tscWatch.checkSingleTimeoutQueueLengthAndRun }; } - const noChange: TscWatchCompileChange = { + const noChange: ts.tscWatch.TscWatchCompileChange = { caption: "No change", - change: sys => sys.writeFile(`${TestFSWithWatch.tsbuildProjectsLocation}/noEmitOnError/src/main.ts`, sys.readFile(`${TestFSWithWatch.tsbuildProjectsLocation}/noEmitOnError/src/main.ts`)!), + change: sys => sys.writeFile(`${ts.TestFSWithWatch.tsbuildProjectsLocation}/noEmitOnError/src/main.ts`, sys.readFile(`${ts.TestFSWithWatch.tsbuildProjectsLocation}/noEmitOnError/src/main.ts`)!), // build project - timeouts: checkSingleTimeoutQueueLengthAndRun, + timeouts: ts.tscWatch.checkSingleTimeoutQueueLengthAndRun, }; verifyEmitAndErrorUpdates({ subScenario: "with noEmitOnError", - currentDirectory: `${TestFSWithWatch.tsbuildProjectsLocation}/noEmitOnError`, + currentDirectory: `${ts.TestFSWithWatch.tsbuildProjectsLocation}/noEmitOnError`, files: () => ["shared/types/db.ts", "src/main.ts", "src/other.ts"] - .map(f => TestFSWithWatch.getTsBuildProjectFile("noEmitOnError", f)), - lib: () => ({ path: libFile.path, content: libContent }), - configFile: () => TestFSWithWatch.getTsBuildProjectFile("noEmitOnError", "tsconfig.json"), + .map(f => ts.TestFSWithWatch.getTsBuildProjectFile("noEmitOnError", f)), + lib: () => ({ path: ts.tscWatch.libFile.path, content: ts.libContent }), + configFile: () => ts.TestFSWithWatch.getTsBuildProjectFile("noEmitOnError", "tsconfig.json"), changes: [ noChange, change("Fix Syntax error", `import { A } from "../shared/types/db"; diff --git a/src/testRunner/unittests/tscWatch/forceConsistentCasingInFileNames.ts b/src/testRunner/unittests/tscWatch/forceConsistentCasingInFileNames.ts index 5199b780b06e3..69ddd03e47db8 100644 --- a/src/testRunner/unittests/tscWatch/forceConsistentCasingInFileNames.ts +++ b/src/testRunner/unittests/tscWatch/forceConsistentCasingInFileNames.ts @@ -1,26 +1,29 @@ namespace ts.tscWatch { describe("unittests:: tsc-watch:: forceConsistentCasingInFileNames", () => { - const loggerFile: File = { - path: `${projectRoot}/logger.ts`, + const loggerFile: ts.tscWatch.File = { + path: `${ts.tscWatch.projectRoot}/logger.ts`, content: `export class logger { }` }; - const anotherFile: File = { - path: `${projectRoot}/another.ts`, + const anotherFile: ts.tscWatch.File = { + path: `${ts.tscWatch.projectRoot}/another.ts`, content: `import { logger } from "./logger"; new logger();` }; - const tsconfig: File = { - path: `${projectRoot}/tsconfig.json`, + const tsconfig: ts.tscWatch.File = { + path: `${ts.tscWatch.projectRoot}/tsconfig.json`, content: JSON.stringify({ compilerOptions: { forceConsistentCasingInFileNames: true } }) }; - function verifyConsistentFileNames({ subScenario, changes }: { subScenario: string; changes: TscWatchCompileChange[]; }) { - verifyTscWatch({ + function verifyConsistentFileNames({ subScenario, changes }: { + subScenario: string; + changes: ts.tscWatch.TscWatchCompileChange[]; + }) { + ts.tscWatch.verifyTscWatch({ scenario: "forceConsistentCasingInFileNames", subScenario, commandLineArgs: ["--w", "--p", tsconfig.path], - sys: () => createWatchedSystem([loggerFile, anotherFile, tsconfig, libFile, tsconfig]), + sys: () => ts.tscWatch.createWatchedSystem([loggerFile, anotherFile, tsconfig, ts.tscWatch.libFile, tsconfig]), changes }); } @@ -31,7 +34,7 @@ namespace ts.tscWatch { { caption: "Change module name from logger to Logger", change: sys => sys.writeFile(anotherFile.path, anotherFile.content.replace("./logger", "./Logger")), - timeouts: runQueuedTimeoutCallbacks, + timeouts: ts.tscWatch.runQueuedTimeoutCallbacks, } ] }); @@ -41,53 +44,53 @@ namespace ts.tscWatch { changes: [ { caption: "Change name of file from logger to Logger", - change: sys => sys.renameFile(loggerFile.path, `${projectRoot}/Logger.ts`), - timeouts: runQueuedTimeoutCallbacks, + change: sys => sys.renameFile(loggerFile.path, `${ts.tscWatch.projectRoot}/Logger.ts`), + timeouts: ts.tscWatch.runQueuedTimeoutCallbacks, } ] }); - verifyTscWatch({ + ts.tscWatch.verifyTscWatch({ scenario: "forceConsistentCasingInFileNames", subScenario: "when relative information file location changes", commandLineArgs: ["--w", "--p", ".", "--explainFiles"], sys: () => { - const moduleA: File = { - path: `${projectRoot}/moduleA.ts`, + const moduleA: ts.tscWatch.File = { + path: `${ts.tscWatch.projectRoot}/moduleA.ts`, content: `import a = require("./ModuleC")` }; - const moduleB: File = { - path: `${projectRoot}/moduleB.ts`, + const moduleB: ts.tscWatch.File = { + path: `${ts.tscWatch.projectRoot}/moduleB.ts`, content: `import a = require("./moduleC")` }; - const moduleC: File = { - path: `${projectRoot}/moduleC.ts`, + const moduleC: ts.tscWatch.File = { + path: `${ts.tscWatch.projectRoot}/moduleC.ts`, content: `export const x = 10;` }; - const tsconfig: File = { - path: `${projectRoot}/tsconfig.json`, + const tsconfig: ts.tscWatch.File = { + path: `${ts.tscWatch.projectRoot}/tsconfig.json`, content: JSON.stringify({ compilerOptions: { forceConsistentCasingInFileNames: true } }) }; - return createWatchedSystem([moduleA, moduleB, moduleC, libFile, tsconfig], { currentDirectory: projectRoot }); + return ts.tscWatch.createWatchedSystem([moduleA, moduleB, moduleC, ts.tscWatch.libFile, tsconfig], { currentDirectory: ts.tscWatch.projectRoot }); }, changes: [ { caption: "Prepend a line to moduleA", - change: sys => sys.prependFile(`${projectRoot}/moduleA.ts`, `// some comment + change: sys => sys.prependFile(`${ts.tscWatch.projectRoot}/moduleA.ts`, `// some comment `), - timeouts: runQueuedTimeoutCallbacks, + timeouts: ts.tscWatch.runQueuedTimeoutCallbacks, } ], }); - verifyTscWatch({ + ts.tscWatch.verifyTscWatch({ scenario: "forceConsistentCasingInFileNames", subScenario: "jsxImportSource option changed", commandLineArgs: ["--w", "--p", ".", "--explainFiles"], - sys: () => createWatchedSystem([ - libFile, + sys: () => ts.tscWatch.createWatchedSystem([ + ts.tscWatch.libFile, { - path: `${projectRoot}/node_modules/react/Jsx-runtime/index.d.ts`, + path: `${ts.tscWatch.projectRoot}/node_modules/react/Jsx-runtime/index.d.ts`, content: `export namespace JSX { interface Element {} interface IntrinsicElements { @@ -102,38 +105,38 @@ export const Fragment: unique symbol; `, }, { - path: `${projectRoot}/node_modules/react/package.json`, + path: `${ts.tscWatch.projectRoot}/node_modules/react/package.json`, content: JSON.stringify({ name: "react", version: "0.0.1" }) }, { - path: `${projectRoot}/index.tsx`, + path: `${ts.tscWatch.projectRoot}/index.tsx`, content: `export const App = () =>
;` }, { - path: `${projectRoot}/tsconfig.json`, + path: `${ts.tscWatch.projectRoot}/tsconfig.json`, content: JSON.stringify({ compilerOptions: { jsx: "react-jsx", jsxImportSource: "react", forceConsistentCasingInFileNames: true }, files: ["node_modules/react/jsx-Runtime/index.d.ts", "index.tsx"] // NB: casing does not match disk }) } - ], { currentDirectory: projectRoot }), - changes: emptyArray, + ], { currentDirectory: ts.tscWatch.projectRoot }), + changes: ts.emptyArray, }); function verifyWindowsStyleRoot(subScenario: string, windowsStyleRoot: string, projectRootRelative: string) { - verifyTscWatch({ + ts.tscWatch.verifyTscWatch({ scenario: "forceConsistentCasingInFileNames", subScenario, commandLineArgs: ["--w", "--p", `${windowsStyleRoot}/${projectRootRelative}`, "--explainFiles"], sys: () => { - const moduleA: File = { + const moduleA: ts.tscWatch.File = { path: `${windowsStyleRoot}/${projectRootRelative}/a.ts`, content: ` export const a = 1; export const b = 2; ` }; - const moduleB: File = { + const moduleB: ts.tscWatch.File = { path: `${windowsStyleRoot}/${projectRootRelative}/b.ts`, content: ` import { a } from "${windowsStyleRoot.toLocaleUpperCase()}/${projectRootRelative}/a" @@ -142,18 +145,18 @@ import { b } from "${windowsStyleRoot.toLocaleLowerCase()}/${projectRootRelative a;b; ` }; - const tsconfig: File = { + const tsconfig: ts.tscWatch.File = { path: `${windowsStyleRoot}/${projectRootRelative}/tsconfig.json`, content: JSON.stringify({ compilerOptions: { forceConsistentCasingInFileNames: true } }) }; - return createWatchedSystem([moduleA, moduleB, libFile, tsconfig], { windowsStyleRoot, useCaseSensitiveFileNames: false }); + return ts.tscWatch.createWatchedSystem([moduleA, moduleB, ts.tscWatch.libFile, tsconfig], { windowsStyleRoot, useCaseSensitiveFileNames: false }); }, changes: [ { caption: "Prepend a line to moduleA", change: sys => sys.prependFile(`${windowsStyleRoot}/${projectRootRelative}/a.ts`, `// some comment `), - timeouts: runQueuedTimeoutCallbacks, + timeouts: ts.tscWatch.runQueuedTimeoutCallbacks, } ], }); @@ -163,12 +166,12 @@ a;b; verifyWindowsStyleRoot("when Windows-style drive root is uppercase", "C:/", "project"); function verifyFileSymlink(subScenario: string, diskPath: string, targetPath: string, importedPath: string) { - verifyTscWatch({ + ts.tscWatch.verifyTscWatch({ scenario: "forceConsistentCasingInFileNames", subScenario, commandLineArgs: ["--w", "--p", ".", "--explainFiles"], sys: () => { - const moduleA: File = { + const moduleA: ts.tscWatch.File = { path: diskPath, content: ` @@ -176,12 +179,12 @@ export const a = 1; export const b = 2; ` }; - const symlinkA: SymLink = { - path: `${projectRoot}/link.ts`, + const symlinkA: ts.tscWatch.SymLink = { + path: `${ts.tscWatch.projectRoot}/link.ts`, symLink: targetPath, }; - const moduleB: File = { - path: `${projectRoot}/b.ts`, + const moduleB: ts.tscWatch.File = { + path: `${ts.tscWatch.projectRoot}/b.ts`, content: ` import { a } from "${importedPath}"; import { b } from "./link"; @@ -189,36 +192,36 @@ import { b } from "./link"; a;b; ` }; - const tsconfig: File = { - path: `${projectRoot}/tsconfig.json`, + const tsconfig: ts.tscWatch.File = { + path: `${ts.tscWatch.projectRoot}/tsconfig.json`, content: JSON.stringify({ compilerOptions: { forceConsistentCasingInFileNames: true } }) }; - return createWatchedSystem([moduleA, symlinkA, moduleB, libFile, tsconfig], { currentDirectory: projectRoot }); + return ts.tscWatch.createWatchedSystem([moduleA, symlinkA, moduleB, ts.tscWatch.libFile, tsconfig], { currentDirectory: ts.tscWatch.projectRoot }); }, changes: [ { caption: "Prepend a line to moduleA", change: sys => sys.prependFile(diskPath, `// some comment `), - timeouts: runQueuedTimeoutCallbacks, + timeouts: ts.tscWatch.runQueuedTimeoutCallbacks, } ], }); } - verifyFileSymlink("when both file symlink target and import match disk", `${projectRoot}/XY.ts`, `${projectRoot}/XY.ts`, `./XY`); - verifyFileSymlink("when file symlink target matches disk but import does not", `${projectRoot}/XY.ts`, `${projectRoot}/Xy.ts`, `./XY`); - verifyFileSymlink("when import matches disk but file symlink target does not", `${projectRoot}/XY.ts`, `${projectRoot}/XY.ts`, `./Xy`); - verifyFileSymlink("when import and file symlink target agree but do not match disk", `${projectRoot}/XY.ts`, `${projectRoot}/Xy.ts`, `./Xy`); - verifyFileSymlink("when import, file symlink target, and disk are all different", `${projectRoot}/XY.ts`, `${projectRoot}/Xy.ts`, `./yX`); + verifyFileSymlink("when both file symlink target and import match disk", `${ts.tscWatch.projectRoot}/XY.ts`, `${ts.tscWatch.projectRoot}/XY.ts`, `./XY`); + verifyFileSymlink("when file symlink target matches disk but import does not", `${ts.tscWatch.projectRoot}/XY.ts`, `${ts.tscWatch.projectRoot}/Xy.ts`, `./XY`); + verifyFileSymlink("when import matches disk but file symlink target does not", `${ts.tscWatch.projectRoot}/XY.ts`, `${ts.tscWatch.projectRoot}/XY.ts`, `./Xy`); + verifyFileSymlink("when import and file symlink target agree but do not match disk", `${ts.tscWatch.projectRoot}/XY.ts`, `${ts.tscWatch.projectRoot}/Xy.ts`, `./Xy`); + verifyFileSymlink("when import, file symlink target, and disk are all different", `${ts.tscWatch.projectRoot}/XY.ts`, `${ts.tscWatch.projectRoot}/Xy.ts`, `./yX`); function verifyDirSymlink(subScenario: string, diskPath: string, targetPath: string, importedPath: string) { - verifyTscWatch({ + ts.tscWatch.verifyTscWatch({ scenario: "forceConsistentCasingInFileNames", subScenario, commandLineArgs: ["--w", "--p", ".", "--explainFiles"], sys: () => { - const moduleA: File = { + const moduleA: ts.tscWatch.File = { path: `${diskPath}/a.ts`, content: ` @@ -226,12 +229,12 @@ export const a = 1; export const b = 2; ` }; - const symlinkA: SymLink = { - path: `${projectRoot}/link`, + const symlinkA: ts.tscWatch.SymLink = { + path: `${ts.tscWatch.projectRoot}/link`, symLink: targetPath, }; - const moduleB: File = { - path: `${projectRoot}/b.ts`, + const moduleB: ts.tscWatch.File = { + path: `${ts.tscWatch.projectRoot}/b.ts`, content: ` import { a } from "${importedPath}/a"; import { b } from "./link/a"; @@ -239,28 +242,28 @@ import { b } from "./link/a"; a;b; ` }; - const tsconfig: File = { - path: `${projectRoot}/tsconfig.json`, + const tsconfig: ts.tscWatch.File = { + path: `${ts.tscWatch.projectRoot}/tsconfig.json`, // Use outFile because otherwise the real and linked files will have the same output path content: JSON.stringify({ compilerOptions: { forceConsistentCasingInFileNames: true, outFile: "out.js", module: "system" } }) }; - return createWatchedSystem([moduleA, symlinkA, moduleB, libFile, tsconfig], { currentDirectory: projectRoot }); + return ts.tscWatch.createWatchedSystem([moduleA, symlinkA, moduleB, ts.tscWatch.libFile, tsconfig], { currentDirectory: ts.tscWatch.projectRoot }); }, changes: [ { caption: "Prepend a line to moduleA", change: sys => sys.prependFile(`${diskPath}/a.ts`, `// some comment `), - timeouts: runQueuedTimeoutCallbacks, + timeouts: ts.tscWatch.runQueuedTimeoutCallbacks, } ], }); } - verifyDirSymlink("when both directory symlink target and import match disk", `${projectRoot}/XY`, `${projectRoot}/XY`, `./XY`); - verifyDirSymlink("when directory symlink target matches disk but import does not", `${projectRoot}/XY`, `${projectRoot}/Xy`, `./XY`); - verifyDirSymlink("when import matches disk but directory symlink target does not", `${projectRoot}/XY`, `${projectRoot}/XY`, `./Xy`); - verifyDirSymlink("when import and directory symlink target agree but do not match disk", `${projectRoot}/XY`, `${projectRoot}/Xy`, `./Xy`); - verifyDirSymlink("when import, directory symlink target, and disk are all different", `${projectRoot}/XY`, `${projectRoot}/Xy`, `./yX`); + verifyDirSymlink("when both directory symlink target and import match disk", `${ts.tscWatch.projectRoot}/XY`, `${ts.tscWatch.projectRoot}/XY`, `./XY`); + verifyDirSymlink("when directory symlink target matches disk but import does not", `${ts.tscWatch.projectRoot}/XY`, `${ts.tscWatch.projectRoot}/Xy`, `./XY`); + verifyDirSymlink("when import matches disk but directory symlink target does not", `${ts.tscWatch.projectRoot}/XY`, `${ts.tscWatch.projectRoot}/XY`, `./Xy`); + verifyDirSymlink("when import and directory symlink target agree but do not match disk", `${ts.tscWatch.projectRoot}/XY`, `${ts.tscWatch.projectRoot}/Xy`, `./Xy`); + verifyDirSymlink("when import, directory symlink target, and disk are all different", `${ts.tscWatch.projectRoot}/XY`, `${ts.tscWatch.projectRoot}/Xy`, `./yX`); }); } diff --git a/src/testRunner/unittests/tscWatch/helpers.ts b/src/testRunner/unittests/tscWatch/helpers.ts index 501264b40ff32..d90f0dbf450ab 100644 --- a/src/testRunner/unittests/tscWatch/helpers.ts +++ b/src/testRunner/unittests/tscWatch/helpers.ts @@ -1,18 +1,18 @@ namespace ts.tscWatch { export const projects = `/user/username/projects`; export const projectRoot = `${projects}/myproject`; - export import WatchedSystem = TestFSWithWatch.TestServerHost; - export type File = TestFSWithWatch.File; - export type SymLink = TestFSWithWatch.SymLink; - export import libFile = TestFSWithWatch.libFile; - export import createWatchedSystem = TestFSWithWatch.createWatchedSystem; - export import checkArray = TestFSWithWatch.checkArray; - export import checkWatchedFiles = TestFSWithWatch.checkWatchedFiles; - export import checkWatchedFilesDetailed = TestFSWithWatch.checkWatchedFilesDetailed; - export import checkWatchedDirectories = TestFSWithWatch.checkWatchedDirectories; - export import checkWatchedDirectoriesDetailed = TestFSWithWatch.checkWatchedDirectoriesDetailed; - export import checkOutputContains = TestFSWithWatch.checkOutputContains; - export import checkOutputDoesNotContain = TestFSWithWatch.checkOutputDoesNotContain; + export import WatchedSystem = ts.TestFSWithWatch.TestServerHost; + export type File = ts.TestFSWithWatch.File; + export type SymLink = ts.TestFSWithWatch.SymLink; + export import libFile = ts.TestFSWithWatch.libFile; + export import createWatchedSystem = ts.TestFSWithWatch.createWatchedSystem; + export import checkArray = ts.TestFSWithWatch.checkArray; + export import checkWatchedFiles = ts.TestFSWithWatch.checkWatchedFiles; + export import checkWatchedFilesDetailed = ts.TestFSWithWatch.checkWatchedFilesDetailed; + export import checkWatchedDirectories = ts.TestFSWithWatch.checkWatchedDirectories; + export import checkWatchedDirectoriesDetailed = ts.TestFSWithWatch.checkWatchedDirectoriesDetailed; + export import checkOutputContains = ts.TestFSWithWatch.checkOutputContains; + export import checkOutputDoesNotContain = ts.TestFSWithWatch.checkOutputDoesNotContain; export const commonFile1: File = { path: "/a/b/commonFile1.ts", @@ -23,14 +23,14 @@ namespace ts.tscWatch { content: "let y = 1" }; - export function checkProgramActualFiles(program: Program, expectedFiles: readonly string[]) { + export function checkProgramActualFiles(program: ts.Program, expectedFiles: readonly string[]) { checkArray(`Program actual files`, program.getSourceFiles().map(file => file.fileName), expectedFiles); } - export function getDiagnosticMessageChain(message: DiagnosticMessage, args?: (string | number)[], next?: DiagnosticMessageChain[]): DiagnosticMessageChain { - let text = getLocaleSpecificMessage(message); + export function getDiagnosticMessageChain(message: ts.DiagnosticMessage, args?: (string | number)[], next?: ts.DiagnosticMessageChain[]): ts.DiagnosticMessageChain { + let text = ts.getLocaleSpecificMessage(message); if (args?.length) { - text = formatStringFromArgs(text, args); + text = ts.formatStringFromArgs(text, args); } return { messageText: text, @@ -40,11 +40,11 @@ namespace ts.tscWatch { }; } - function isDiagnosticMessageChain(message: DiagnosticMessage | DiagnosticMessageChain): message is DiagnosticMessageChain { - return !!(message as DiagnosticMessageChain).messageText; + function isDiagnosticMessageChain(message: ts.DiagnosticMessage | ts.DiagnosticMessageChain): message is ts.DiagnosticMessageChain { + return !!(message as ts.DiagnosticMessageChain).messageText; } - export function getDiagnosticOfFileFrom(file: SourceFile | undefined, start: number | undefined, length: number | undefined, message: DiagnosticMessage | DiagnosticMessageChain, ...args: (string | number)[]): Diagnostic { + export function getDiagnosticOfFileFrom(file: ts.SourceFile | undefined, start: number | undefined, length: number | undefined, message: ts.DiagnosticMessage | ts.DiagnosticMessageChain, ...args: (string | number)[]): ts.Diagnostic { return { file, start, @@ -58,32 +58,31 @@ namespace ts.tscWatch { }; } - export function getDiagnosticWithoutFile(message: DiagnosticMessage | DiagnosticMessageChain, ...args: (string | number)[]): Diagnostic { + export function getDiagnosticWithoutFile(message: ts.DiagnosticMessage | ts.DiagnosticMessageChain, ...args: (string | number)[]): ts.Diagnostic { return getDiagnosticOfFileFrom(/*file*/ undefined, /*start*/ undefined, /*length*/ undefined, message, ...args); } - export function getDiagnosticOfFile(file: SourceFile, start: number, length: number, message: DiagnosticMessage | DiagnosticMessageChain, ...args: (string | number)[]): Diagnostic { + export function getDiagnosticOfFile(file: ts.SourceFile, start: number, length: number, message: ts.DiagnosticMessage | ts.DiagnosticMessageChain, ...args: (string | number)[]): ts.Diagnostic { return getDiagnosticOfFileFrom(file, start, length, message, ...args); } - export function getDiagnosticOfFileFromProgram(program: Program, filePath: string, start: number, length: number, message: DiagnosticMessage | DiagnosticMessageChain, ...args: (string | number)[]): Diagnostic { - return getDiagnosticOfFileFrom(program.getSourceFileByPath(toPath(filePath, program.getCurrentDirectory(), s => s.toLowerCase())), - start, length, message, ...args); + export function getDiagnosticOfFileFromProgram(program: ts.Program, filePath: string, start: number, length: number, message: ts.DiagnosticMessage | ts.DiagnosticMessageChain, ...args: (string | number)[]): ts.Diagnostic { + return getDiagnosticOfFileFrom(program.getSourceFileByPath(ts.toPath(filePath, program.getCurrentDirectory(), s => s.toLowerCase())), start, length, message, ...args); } - export function getUnknownCompilerOption(program: Program, configFile: File, option: string) { + export function getUnknownCompilerOption(program: ts.Program, configFile: File, option: string) { const quotedOption = `"${option}"`; - return getDiagnosticOfFile(program.getCompilerOptions().configFile!, configFile.content.indexOf(quotedOption), quotedOption.length, Diagnostics.Unknown_compiler_option_0, option); + return getDiagnosticOfFile(program.getCompilerOptions().configFile!, configFile.content.indexOf(quotedOption), quotedOption.length, ts.Diagnostics.Unknown_compiler_option_0, option); } - export function getUnknownDidYouMeanCompilerOption(program: Program, configFile: File, option: string, didYouMean: string) { + export function getUnknownDidYouMeanCompilerOption(program: ts.Program, configFile: File, option: string, didYouMean: string) { const quotedOption = `"${option}"`; - return getDiagnosticOfFile(program.getCompilerOptions().configFile!, configFile.content.indexOf(quotedOption), quotedOption.length, Diagnostics.Unknown_compiler_option_0_Did_you_mean_1, option, didYouMean); + return getDiagnosticOfFile(program.getCompilerOptions().configFile!, configFile.content.indexOf(quotedOption), quotedOption.length, ts.Diagnostics.Unknown_compiler_option_0_Did_you_mean_1, option, didYouMean); } - export function getDiagnosticModuleNotFoundOfFile(program: Program, file: File, moduleName: string) { + export function getDiagnosticModuleNotFoundOfFile(program: ts.Program, file: File, moduleName: string) { const quotedModuleName = `"${moduleName}"`; - return getDiagnosticOfFileFromProgram(program, file.path, file.content.indexOf(quotedModuleName), quotedModuleName.length, Diagnostics.Cannot_find_module_0_Did_you_mean_to_set_the_moduleResolution_option_to_node_or_to_add_aliases_to_the_paths_option, moduleName); + return getDiagnosticOfFileFromProgram(program, file.path, file.content.indexOf(quotedModuleName), quotedModuleName.length, ts.Diagnostics.Cannot_find_module_0_Did_you_mean_to_set_the_moduleResolution_option_to_node_or_to_add_aliases_to_the_paths_option, moduleName); } export function runQueuedTimeoutCallbacks(sys: WatchedSystem) { @@ -99,21 +98,17 @@ namespace ts.tscWatch { sys.checkTimeoutQueueLength(0); } - export type WatchOrSolution = void | SolutionBuilder | WatchOfConfigFile | WatchOfFilesAndCompilerOptions; - export interface TscWatchCompileChange { + export type WatchOrSolution = void | ts.SolutionBuilder | ts.WatchOfConfigFile | ts.WatchOfFilesAndCompilerOptions; + export interface TscWatchCompileChange { caption: string; - change: (sys: TestFSWithWatch.TestServerHostTrackingWrittenFiles) => void; - timeouts: ( - sys: TestFSWithWatch.TestServerHostTrackingWrittenFiles, - programs: readonly CommandLineProgram[], - watchOrSolution: WatchOrSolution - ) => void; + change: (sys: ts.TestFSWithWatch.TestServerHostTrackingWrittenFiles) => void; + timeouts: (sys: ts.TestFSWithWatch.TestServerHostTrackingWrittenFiles, programs: readonly ts.CommandLineProgram[], watchOrSolution: WatchOrSolution) => void; } export interface TscWatchCheckOptions { baselineSourceMap?: boolean; baselineDependencies?: boolean; } - export interface TscWatchCompileBase extends TscWatchCheckOptions { + export interface TscWatchCompileBase extends TscWatchCheckOptions { scenario: string; subScenario: string; commandLineArgs: readonly string[]; @@ -125,7 +120,7 @@ namespace ts.tscWatch { export const noopChange: TscWatchCompileChange = { caption: "No change", - change: noop, + change: ts.noop, timeouts: sys => sys.checkTimeoutQueueLength(0), }; @@ -133,19 +128,11 @@ namespace ts.tscWatch { function tscWatchCompile(input: TscWatchCompile) { it("tsc-watch:: Generates files matching the baseline", () => { const { sys, baseline, oldSnap } = createBaseline(input.sys()); - const { - scenario, subScenario, - commandLineArgs, changes, - baselineSourceMap, baselineDependencies - } = input; - - if (!isWatch(commandLineArgs)) sys.exit = exitCode => sys.exitCode = exitCode; - const { cb, getPrograms } = commandLineCallbacks(sys); - const watchOrSolution = executeCommandLine( - sys, - cb, - commandLineArgs, - ); + const { scenario, subScenario, commandLineArgs, changes, baselineSourceMap, baselineDependencies } = input; + if (!isWatch(commandLineArgs)) + sys.exit = exitCode => sys.exitCode = exitCode; + const { cb, getPrograms } = ts.commandLineCallbacks(sys); + const watchOrSolution = ts.executeCommandLine(sys, cb, commandLineArgs); runWatchBaseline({ scenario, subScenario, @@ -164,71 +151,63 @@ namespace ts.tscWatch { export interface BaselineBase { baseline: string[]; - sys: TestFSWithWatch.TestServerHostTrackingWrittenFiles; + sys: ts.TestFSWithWatch.TestServerHostTrackingWrittenFiles; oldSnap: SystemSnap; } - export interface Baseline extends BaselineBase, CommandLineCallbacks { + export interface Baseline extends BaselineBase, ts.CommandLineCallbacks { } export function createBaseline(system: WatchedSystem, modifySystem?: (sys: WatchedSystem, originalRead: WatchedSystem["readFile"]) => void): Baseline { const originalRead = system.readFile; const initialSys = fakes.patchHostForBuildInfoReadWrite(system); modifySystem?.(initialSys, originalRead); - const sys = TestFSWithWatch.changeToHostTrackingWrittenFiles(initialSys); + const sys = ts.TestFSWithWatch.changeToHostTrackingWrittenFiles(initialSys); const baseline: string[] = []; baseline.push("Input::"); sys.diff(baseline); - const { cb, getPrograms } = commandLineCallbacks(sys); + const { cb, getPrograms } = ts.commandLineCallbacks(sys); return { sys, baseline, oldSnap: sys.snap(), cb, getPrograms }; } - export function createSolutionBuilderWithWatchHostForBaseline(sys: WatchedSystem, cb: ExecuteCommandLineCallbacks) { - const host = createSolutionBuilderWithWatchHost(sys, - /*createProgram*/ undefined, - createDiagnosticReporter(sys, /*pretty*/ true), - createBuilderStatusReporter(sys, /*pretty*/ true), - createWatchStatusReporter(sys, /*pretty*/ true) - ); + export function createSolutionBuilderWithWatchHostForBaseline(sys: WatchedSystem, cb: ts.ExecuteCommandLineCallbacks) { + const host = ts.createSolutionBuilderWithWatchHost(sys, + /*createProgram*/ undefined, ts.createDiagnosticReporter(sys, /*pretty*/ true), ts.createBuilderStatusReporter(sys, /*pretty*/ true), ts.createWatchStatusReporter(sys, /*pretty*/ true)); host.afterProgramEmitAndDiagnostics = cb; host.afterEmitBundle = cb; return host; } - interface CreateWatchCompilerHostOfConfigFileForBaseline extends CreateWatchCompilerHostOfConfigFileInput { - system: WatchedSystem, - cb: ExecuteCommandLineCallbacks; + interface CreateWatchCompilerHostOfConfigFileForBaseline extends ts.CreateWatchCompilerHostOfConfigFileInput { + system: WatchedSystem; + cb: ts.ExecuteCommandLineCallbacks; } - export function createWatchCompilerHostOfConfigFileForBaseline( - input: CreateWatchCompilerHostOfConfigFileForBaseline - ) { - const host = createWatchCompilerHostOfConfigFile({ + export function createWatchCompilerHostOfConfigFileForBaseline(input: CreateWatchCompilerHostOfConfigFileForBaseline) { + const host = ts.createWatchCompilerHostOfConfigFile({ ...input, - reportDiagnostic: createDiagnosticReporter(input.system, /*pretty*/ true), - reportWatchStatus: createWatchStatusReporter(input.system, /*pretty*/ true), + reportDiagnostic: ts.createDiagnosticReporter(input.system, /*pretty*/ true), + reportWatchStatus: ts.createWatchStatusReporter(input.system, /*pretty*/ true), }); updateWatchHostForBaseline(host, input.cb); return host; } - interface CreateWatchCompilerHostOfFilesAndCompilerOptionsForBaseline extends CreateWatchCompilerHostOfFilesAndCompilerOptionsInput { - system: WatchedSystem, - cb: ExecuteCommandLineCallbacks; + interface CreateWatchCompilerHostOfFilesAndCompilerOptionsForBaseline extends ts.CreateWatchCompilerHostOfFilesAndCompilerOptionsInput { + system: WatchedSystem; + cb: ts.ExecuteCommandLineCallbacks; } - export function createWatchCompilerHostOfFilesAndCompilerOptionsForBaseline( - input: CreateWatchCompilerHostOfFilesAndCompilerOptionsForBaseline - ) { - const host = createWatchCompilerHostOfFilesAndCompilerOptions({ + export function createWatchCompilerHostOfFilesAndCompilerOptionsForBaseline(input: CreateWatchCompilerHostOfFilesAndCompilerOptionsForBaseline) { + const host = ts.createWatchCompilerHostOfFilesAndCompilerOptions({ ...input, - reportDiagnostic: createDiagnosticReporter(input.system, /*pretty*/ true), - reportWatchStatus: createWatchStatusReporter(input.system, /*pretty*/ true), + reportDiagnostic: ts.createDiagnosticReporter(input.system, /*pretty*/ true), + reportWatchStatus: ts.createWatchStatusReporter(input.system, /*pretty*/ true), }); updateWatchHostForBaseline(host, input.cb); return host; } - function updateWatchHostForBaseline(host: WatchCompilerHost, cb: ExecuteCommandLineCallbacks) { + function updateWatchHostForBaseline(host: ts.WatchCompilerHost, cb: ts.ExecuteCommandLineCallbacks) { const emitFilesAndReportErrors = host.afterProgramCreate!; host.afterProgramCreate = builderProgram => { emitFilesAndReportErrors.call(host, builderProgram); @@ -246,22 +225,17 @@ namespace ts.tscWatch { return sys.snap(); } - export interface RunWatchBaseline extends BaselineBase, TscWatchCompileBase { - sys: TestFSWithWatch.TestServerHostTrackingWrittenFiles; - getPrograms: () => readonly CommandLineProgram[]; + export interface RunWatchBaseline extends BaselineBase, TscWatchCompileBase { + sys: ts.TestFSWithWatch.TestServerHostTrackingWrittenFiles; + getPrograms: () => readonly ts.CommandLineProgram[]; watchOrSolution: WatchOrSolution; } - export function runWatchBaseline({ - scenario, subScenario, commandLineArgs, - getPrograms, sys, baseline, oldSnap, - baselineSourceMap, baselineDependencies, - changes, watchOrSolution - }: RunWatchBaseline) { + export function runWatchBaseline({ scenario, subScenario, commandLineArgs, getPrograms, sys, baseline, oldSnap, baselineSourceMap, baselineDependencies, changes, watchOrSolution }: RunWatchBaseline) { baseline.push(`${sys.getExecutingFilePath()} ${commandLineArgs.join(" ")}`); let programs = watchBaseline({ baseline, getPrograms, - oldPrograms: emptyArray, + oldPrograms: ts.emptyArray, sys, oldSnap, baselineSourceMap, @@ -281,27 +255,29 @@ namespace ts.tscWatch { baselineDependencies, }); } - Harness.Baseline.runBaseline(`${isBuild(commandLineArgs) ? "tsbuild" : "tsc"}${isWatch(commandLineArgs) ? "Watch" : ""}/${scenario}/${subScenario.split(" ").join("-")}.js`, baseline.join("\r\n")); + Harness.Baseline.runBaseline(`${ts.isBuild(commandLineArgs) ? "tsbuild" : "tsc"}${isWatch(commandLineArgs) ? "Watch" : ""}/${scenario}/${subScenario.split(" ").join("-")}.js`, baseline.join("\r\n")); } function isWatch(commandLineArgs: readonly string[]) { - return forEach(commandLineArgs, arg => { - if (arg.charCodeAt(0) !== CharacterCodes.minus) return false; - const option = arg.slice(arg.charCodeAt(1) === CharacterCodes.minus ? 2 : 1).toLowerCase(); + return ts.forEach(commandLineArgs, arg => { + if (arg.charCodeAt(0) !== ts.CharacterCodes.minus) + return false; + const option = arg.slice(arg.charCodeAt(1) === ts.CharacterCodes.minus ? 2 : 1).toLowerCase(); return option === "watch" || option === "w"; }); } export interface WatchBaseline extends BaselineBase, TscWatchCheckOptions { - oldPrograms: readonly (CommandLineProgram | undefined)[]; - getPrograms: () => readonly CommandLineProgram[]; + oldPrograms: readonly (ts.CommandLineProgram | undefined)[]; + getPrograms: () => readonly ts.CommandLineProgram[]; } export function watchBaseline({ baseline, getPrograms, oldPrograms, sys, oldSnap, baselineSourceMap, baselineDependencies }: WatchBaseline) { - if (baselineSourceMap) generateSourceMapBaselineFiles(sys); + if (baselineSourceMap) + ts.generateSourceMapBaselineFiles(sys); sys.serializeOutput(baseline); const programs = baselinePrograms(baseline, getPrograms, oldPrograms, baselineDependencies); sys.serializeWatches(baseline); - baseline.push(`exitCode:: ExitStatus.${ExitStatus[sys.exitCode as ExitStatus]}`, ""); + baseline.push(`exitCode:: ExitStatus.${ts.ExitStatus[sys.exitCode as ts.ExitStatus]}`, ""); sys.diff(baseline, oldSnap); sys.writtenFiles.forEach((value, key) => { assert.equal(value, 1, `Expected to write file ${key} only once`); @@ -310,7 +286,7 @@ namespace ts.tscWatch { return programs; } - export function baselinePrograms(baseline: string[], getPrograms: () => readonly CommandLineProgram[], oldPrograms: readonly (CommandLineProgram | undefined)[], baselineDependencies: boolean | undefined) { + export function baselinePrograms(baseline: string[], getPrograms: () => readonly ts.CommandLineProgram[], oldPrograms: readonly (ts.CommandLineProgram | undefined)[], baselineDependencies: boolean | undefined) { const programs = getPrograms(); for (let i = 0; i < programs.length; i++) { baselineProgram(baseline, programs[i], oldPrograms[i], baselineDependencies); @@ -318,7 +294,7 @@ namespace ts.tscWatch { return programs; } - function baselineProgram(baseline: string[], [program, builderProgram]: CommandLineProgram, oldProgram: CommandLineProgram | undefined, baselineDependencies: boolean | undefined) { + function baselineProgram(baseline: string[], [program, builderProgram]: ts.CommandLineProgram, oldProgram: ts.CommandLineProgram | undefined, baselineDependencies: boolean | undefined) { if (program !== oldProgram?.[0]) { const options = program.getCompilerOptions(); baseline.push(`Program root files: ${JSON.stringify(program.getRootFileNames())}`); @@ -334,10 +310,11 @@ namespace ts.tscWatch { } baseline.push(""); - if (!builderProgram) return; + if (!builderProgram) + return; if (builderProgram !== oldProgram?.[1]) { const state = builderProgram.getState(); - const internalState = state as unknown as BuilderProgramState; + const internalState = state as unknown as ts.BuilderProgramState; if (state.semanticDiagnosticsPerFile?.size) { baseline.push("Semantic diagnostics in builder refreshed for::"); for (const file of program.getSourceFiles()) { @@ -353,7 +330,7 @@ namespace ts.tscWatch { baseline.push(""); if (internalState.hasCalledUpdateShapeSignature?.size) { baseline.push("Shape signatures in builder refreshed for::"); - internalState.hasCalledUpdateShapeSignature.forEach((path: Path) => { + internalState.hasCalledUpdateShapeSignature.forEach((path: ts.Path) => { const info = state.fileInfos.get(path); if (info?.version === info?.signature || !info?.signature) { baseline.push(path + " (used version)"); @@ -371,7 +348,8 @@ namespace ts.tscWatch { } } baseline.push(""); - if (!baselineDependencies) return; + if (!baselineDependencies) + return; baseline.push("Dependencies for::"); for (const file of builderProgram.getSourceFiles()) { baseline.push(`${file.fileName}:`); @@ -407,12 +385,12 @@ namespace ts.tscWatch { } export function replaceFileText(sys: WatchedSystem, file: string, searchValue: string | RegExp, replaceValue: string) { - const content = Debug.checkDefined(sys.readFile(file)); + const content = ts.Debug.checkDefined(sys.readFile(file)); sys.writeFile(file, content.replace(searchValue, replaceValue)); } export function createSolutionBuilder(system: WatchedSystem, rootNames: readonly string[], originalRead?: WatchedSystem["readFile"]) { - const host = createSolutionBuilderHostForBaseline(system, /*versionToWrite*/ undefined, originalRead); + const host = ts.createSolutionBuilderHostForBaseline(system, /*versionToWrite*/ undefined, originalRead); return ts.createSolutionBuilder(host, rootNames, {}); } @@ -426,9 +404,7 @@ namespace ts.tscWatch { const originalReadFile = sys.readFile; const originalWrite = sys.write; const originalWriteFile = sys.writeFile; - const solutionBuilder = createSolutionBuilder(TestFSWithWatch.changeToHostTrackingWrittenFiles( - fakes.patchHostForBuildInfoReadWrite(sys) - ), solutionRoots, originalRead); + const solutionBuilder = createSolutionBuilder(ts.TestFSWithWatch.changeToHostTrackingWrittenFiles(fakes.patchHostForBuildInfoReadWrite(sys)), solutionRoots, originalRead); solutionBuilder.build(); sys.readFile = originalReadFile; sys.write = originalWrite; @@ -436,7 +412,7 @@ namespace ts.tscWatch { return sys; } - export function createSystemWithSolutionBuild(solutionRoots: readonly string[], files: readonly TestFSWithWatch.FileOrFolderOrSymLink[], params?: TestFSWithWatch.TestServerHostCreationParameters) { + export function createSystemWithSolutionBuild(solutionRoots: readonly string[], files: readonly ts.TestFSWithWatch.FileOrFolderOrSymLink[], params?: ts.TestFSWithWatch.TestServerHostCreationParameters) { return solutionBuildWithBaseline(createWatchedSystem(files, params), solutionRoots); } } diff --git a/src/testRunner/unittests/tscWatch/incremental.ts b/src/testRunner/unittests/tscWatch/incremental.ts index 1af240764fea7..2caad5ec8737e 100644 --- a/src/testRunner/unittests/tscWatch/incremental.ts +++ b/src/testRunner/unittests/tscWatch/incremental.ts @@ -2,16 +2,16 @@ namespace ts.tscWatch { describe("unittests:: tsc-watch:: emit file --incremental", () => { const project = "/users/username/projects/project"; - const configFile: File = { + const configFile: ts.tscWatch.File = { path: `${project}/tsconfig.json`, content: JSON.stringify({ compilerOptions: { incremental: true } }) }; interface VerifyIncrementalWatchEmitInput { subScenario: string; - files: () => readonly File[]; + files: () => readonly ts.tscWatch.File[]; optionsToExtend?: readonly string[]; - modifyFs?: (host: WatchedSystem) => void; + modifyFs?: (host: ts.tscWatch.WatchedSystem) => void; } function verifyIncrementalWatchEmit(input: VerifyIncrementalWatchEmitInput) { describe(input.subScenario, () => { @@ -24,47 +24,41 @@ namespace ts.tscWatch { }); } - function verifyIncrementalWatchEmitWorker( - { subScenario, files, optionsToExtend, modifyFs }: VerifyIncrementalWatchEmitInput, - incremental: boolean - ) { - const { sys, baseline, oldSnap, cb, getPrograms } = createBaseline(createWatchedSystem(files(), { currentDirectory: project })); - if (incremental) sys.exit = exitCode => sys.exitCode = exitCode; - const argsToPass = [incremental ? "-i" : "-w", ...(optionsToExtend || emptyArray)]; + function verifyIncrementalWatchEmitWorker({ subScenario, files, optionsToExtend, modifyFs }: VerifyIncrementalWatchEmitInput, incremental: boolean) { + const { sys, baseline, oldSnap, cb, getPrograms } = ts.tscWatch.createBaseline(ts.tscWatch.createWatchedSystem(files(), { currentDirectory: project })); + if (incremental) + sys.exit = exitCode => sys.exitCode = exitCode; + const argsToPass = [incremental ? "-i" : "-w", ...(optionsToExtend || ts.emptyArray)]; baseline.push(`${sys.getExecutingFilePath()} ${argsToPass.join(" ")}`); - let oldPrograms: readonly CommandLineProgram[] = emptyArray; + let oldPrograms: readonly ts.CommandLineProgram[] = ts.emptyArray; build(oldSnap); if (modifyFs) { - const oldSnap = applyChange(sys, baseline, modifyFs); + const oldSnap = ts.tscWatch.applyChange(sys, baseline, modifyFs); build(oldSnap); } - Harness.Baseline.runBaseline(`${isBuild(argsToPass) ? "tsbuild/watchMode" : "tscWatch"}/incremental/${subScenario.split(" ").join("-")}-${incremental ? "incremental" : "watch"}.js`, baseline.join("\r\n")); - - function build(oldSnap: SystemSnap) { - const closer = executeCommandLine( - sys, - cb, - argsToPass, - ); - oldPrograms = watchBaseline({ + Harness.Baseline.runBaseline(`${ts.isBuild(argsToPass) ? "tsbuild/watchMode" : "tscWatch"}/incremental/${subScenario.split(" ").join("-")}-${incremental ? "incremental" : "watch"}.js`, baseline.join("\r\n")); + function build(oldSnap: ts.tscWatch.SystemSnap) { + const closer = ts.executeCommandLine(sys, cb, argsToPass); + oldPrograms = ts.tscWatch.watchBaseline({ baseline, getPrograms, oldPrograms, sys, oldSnap }); - if (closer) closer.close(); + if (closer) + closer.close(); } } describe("non module compilation", () => { - const file1: File = { + const file1: ts.tscWatch.File = { path: `${project}/file1.ts`, content: "const x = 10;" }; - const file2: File = { + const file2: ts.tscWatch.File = { path: `${project}/file2.ts`, content: "const y = 20;" }; @@ -72,7 +66,7 @@ namespace ts.tscWatch { function verify(subScenario: string, optionsToExtend?: readonly string[]) { const modifiedFile2Content = file2.content.replace("y", "z").replace("20", "10"); verifyIncrementalWatchEmit({ - files: () => [libFile, file1, file2, configFile], + files: () => [ts.tscWatch.libFile, file1, file2, configFile], optionsToExtend, subScenario: `own file emit without errors/${subScenario}`, modifyFs: host => host.writeFile(file2.path, modifiedFile2Content), @@ -83,7 +77,7 @@ namespace ts.tscWatch { }); verifyIncrementalWatchEmit({ - files: () => [libFile, file1, configFile, { + files: () => [ts.tscWatch.libFile, file1, configFile, { path: file2.path, content: `const y: string = 20;` }], @@ -92,7 +86,7 @@ namespace ts.tscWatch { }); verifyIncrementalWatchEmit({ - files: () => [libFile, file1, file2, { + files: () => [ts.tscWatch.libFile, file1, file2, { path: configFile.path, content: JSON.stringify({ compilerOptions: { incremental: true, outFile: "out.js" } }) }], @@ -101,76 +95,76 @@ namespace ts.tscWatch { }); describe("module compilation", () => { - const file1: File = { + const file1: ts.tscWatch.File = { path: `${project}/file1.ts`, content: "export const x = 10;" }; - const file2: File = { + const file2: ts.tscWatch.File = { path: `${project}/file2.ts`, content: "export const y = 20;" }; - const config: File = { + const config: ts.tscWatch.File = { path: configFile.path, content: JSON.stringify({ compilerOptions: { incremental: true, module: "amd" } }) }; verifyIncrementalWatchEmit({ - files: () => [libFile, file1, file2, config], + files: () => [ts.tscWatch.libFile, file1, file2, config], subScenario: "module compilation/own file emit without errors", modifyFs: host => host.writeFile(file2.path, file2.content.replace("y", "z").replace("20", "10")), }); describe("own file emit with errors", () => { - const fileModified: File = { + const fileModified: ts.tscWatch.File = { path: file2.path, content: `export const y: string = 20;` }; verifyIncrementalWatchEmit({ - files: () => [libFile, file1, fileModified, config], + files: () => [ts.tscWatch.libFile, file1, fileModified, config], subScenario: "module compilation/own file emit with errors", modifyFs: host => host.writeFile(file1.path, file1.content.replace("x = 10", "z = 10")), }); it("verify that state is read correctly", () => { - const system = createWatchedSystem([libFile, file1, fileModified, config], { currentDirectory: project }); - const reportDiagnostic = createDiagnosticReporter(system); - const parsedConfig = parseConfigFileWithSystem("tsconfig.json", {}, /*extendedConfigCache*/ undefined, /*watchOptionsToExtend*/ undefined, system, reportDiagnostic)!; - performIncrementalCompilation({ + const system = ts.tscWatch.createWatchedSystem([ts.tscWatch.libFile, file1, fileModified, config], { currentDirectory: project }); + const reportDiagnostic = ts.createDiagnosticReporter(system); + const parsedConfig = ts.parseConfigFileWithSystem("tsconfig.json", {}, /*extendedConfigCache*/ undefined, /*watchOptionsToExtend*/ undefined, system, reportDiagnostic)!; + ts.performIncrementalCompilation({ rootNames: parsedConfig.fileNames, options: parsedConfig.options, projectReferences: parsedConfig.projectReferences, - configFileParsingDiagnostics: getConfigFileParsingDiagnostics(parsedConfig), + configFileParsingDiagnostics: ts.getConfigFileParsingDiagnostics(parsedConfig), reportDiagnostic, system }); - const command = parseConfigFileWithSystem("tsconfig.json", {}, /*extendedConfigCache*/ undefined, /*watchOptionsToExtend*/ undefined, system, noop)!; - const builderProgram = createIncrementalProgram({ + const command = ts.parseConfigFileWithSystem("tsconfig.json", {}, /*extendedConfigCache*/ undefined, /*watchOptionsToExtend*/ undefined, system, ts.noop)!; + const builderProgram = ts.createIncrementalProgram({ rootNames: command.fileNames, options: command.options, projectReferences: command.projectReferences, - configFileParsingDiagnostics: getConfigFileParsingDiagnostics(command), - host: createIncrementalCompilerHost(command.options, system) + configFileParsingDiagnostics: ts.getConfigFileParsingDiagnostics(command), + host: ts.createIncrementalCompilerHost(command.options, system) }); const state = builderProgram.getState(); assert.equal(state.changedFilesSet!.size, 0, "changes"); assert.equal(state.fileInfos.size, 3, "FileInfo size"); - assert.deepEqual(state.fileInfos.get(libFile.path as Path), { - version: system.createHash(libFile.content), - signature: system.createHash(libFile.content), + assert.deepEqual(state.fileInfos.get(ts.tscWatch.libFile.path as ts.Path), { + version: system.createHash(ts.tscWatch.libFile.content), + signature: system.createHash(ts.tscWatch.libFile.content), affectsGlobalScope: true, impliedFormat: undefined, }); - assert.deepEqual(state.fileInfos.get(file1.path as Path), { + assert.deepEqual(state.fileInfos.get(file1.path as ts.Path), { version: system.createHash(file1.content), signature: system.createHash(file1.content), affectsGlobalScope: undefined, impliedFormat: undefined, }); - assert.deepEqual(state.fileInfos.get(file2.path as Path), { + assert.deepEqual(state.fileInfos.get(file2.path as ts.Path), { version: system.createHash(fileModified.content), signature: system.createHash(fileModified.content), affectsGlobalScope: undefined, @@ -179,22 +173,22 @@ namespace ts.tscWatch { assert.deepEqual(state.compilerOptions, { incremental: true, - module: ModuleKind.AMD, + module: ts.ModuleKind.AMD, configFilePath: config.path }); - assert.equal(arrayFrom(state.referencedMap!.keys()).length, 0); - assert.equal(arrayFrom(state.exportedModulesMap!.keys()).length, 0); + assert.equal(ts.arrayFrom(state.referencedMap!.keys()).length, 0); + assert.equal(ts.arrayFrom(state.exportedModulesMap!.keys()).length, 0); assert.equal(state.semanticDiagnosticsPerFile!.size, 3); - assert.deepEqual(state.semanticDiagnosticsPerFile!.get(libFile.path as Path), emptyArray); - assert.deepEqual(state.semanticDiagnosticsPerFile!.get(file1.path as Path), emptyArray); - assert.deepEqual(state.semanticDiagnosticsPerFile!.get(file2.path as Path), [{ - file: state.program!.getSourceFileByPath(file2.path as Path)!, + assert.deepEqual(state.semanticDiagnosticsPerFile!.get(ts.tscWatch.libFile.path as ts.Path), ts.emptyArray); + assert.deepEqual(state.semanticDiagnosticsPerFile!.get(file1.path as ts.Path), ts.emptyArray); + assert.deepEqual(state.semanticDiagnosticsPerFile!.get(file2.path as ts.Path), [{ + file: state.program!.getSourceFileByPath(file2.path as ts.Path)!, start: 13, length: 1, - code: Diagnostics.Type_0_is_not_assignable_to_type_1.code, - category: Diagnostics.Type_0_is_not_assignable_to_type_1.category, + code: ts.Diagnostics.Type_0_is_not_assignable_to_type_1.code, + category: ts.Diagnostics.Type_0_is_not_assignable_to_type_1.category, messageText: "Type 'number' is not assignable to type 'string'.", relatedInformation: undefined, reportsUnnecessary: undefined, @@ -206,7 +200,7 @@ namespace ts.tscWatch { }); verifyIncrementalWatchEmit({ - files: () => [libFile, file1, file2, { + files: () => [ts.tscWatch.libFile, file1, file2, { path: configFile.path, content: JSON.stringify({ compilerOptions: { incremental: true, module: "amd", outFile: "out.js" } }) }], @@ -216,7 +210,7 @@ namespace ts.tscWatch { verifyIncrementalWatchEmit({ files: () => { - const config: File = { + const config: ts.tscWatch.File = { path: configFile.path, content: JSON.stringify({ compilerOptions: { @@ -228,7 +222,7 @@ namespace ts.tscWatch { } }) }; - const aTs: File = { + const aTs: ts.tscWatch.File = { path: `${project}/a.ts`, content: `import { B } from "./b"; export interface A { @@ -236,7 +230,7 @@ export interface A { } ` }; - const bTs: File = { + const bTs: ts.tscWatch.File = { path: `${project}/b.ts`, content: `import { C } from "./c"; export interface B { @@ -244,7 +238,7 @@ export interface B { } ` }; - const cTs: File = { + const cTs: ts.tscWatch.File = { path: `${project}/c.ts`, content: `import { A } from "./a"; export interface C { @@ -252,14 +246,14 @@ export interface C { } ` }; - const indexTs: File = { + const indexTs: ts.tscWatch.File = { path: `${project}/index.ts`, content: `export { A } from "./a"; export { B } from "./b"; export { C } from "./c"; ` }; - return [libFile, aTs, bTs, cTs, indexTs, config]; + return [ts.tscWatch.libFile, aTs, bTs, cTs, indexTs, config]; }, subScenario: "incremental with circular references", modifyFs: host => host.writeFile(`${project}/a.ts`, `import { B } from "./b"; @@ -273,7 +267,7 @@ export interface A { verifyIncrementalWatchEmit({ subScenario: "when file with ambient global declaration file is deleted", files: () => [ - { path: libFile.path, content: libContent }, + { path: ts.tscWatch.libFile.path, content: ts.libContent }, { path: `${project}/globals.d.ts`, content: `declare namespace Config { const value: string;} ` }, { path: `${project}/index.ts`, content: `console.log(Config.value);` }, { path: configFile.path, content: JSON.stringify({ compilerOptions: { incremental: true, } }) } @@ -299,7 +293,7 @@ export const Fragment: unique symbol; verifyIncrementalWatchEmit({ subScenario: "jsxImportSource option changed", files: () => [ - { path: libFile.path, content: libContent }, + { path: ts.tscWatch.libFile.path, content: ts.libContent }, { path: `${project}/node_modules/react/jsx-runtime/index.d.ts`, content: jsxLibraryContent }, { path: `${project}/node_modules/react/package.json`, content: JSON.stringify({ name: "react", version: "0.0.1" }) }, { path: `${project}/node_modules/preact/jsx-runtime/index.d.ts`, content: jsxLibraryContent.replace("propA", "propB") }, @@ -314,7 +308,7 @@ export const Fragment: unique symbol; verifyIncrementalWatchEmit({ subScenario: "jsxImportSource backing types added", files: () => [ - { path: libFile.path, content: libContent }, + { path: ts.tscWatch.libFile.path, content: ts.libContent }, { path: `${project}/index.tsx`, content: `export const App = () =>
;` }, { path: configFile.path, content: JSON.stringify({ compilerOptions: jsxImportSourceOptions }) } ], @@ -330,7 +324,7 @@ export const Fragment: unique symbol; verifyIncrementalWatchEmit({ subScenario: "jsxImportSource backing types removed", files: () => [ - { path: libFile.path, content: libContent }, + { path: ts.tscWatch.libFile.path, content: ts.libContent }, { path: `${project}/node_modules/react/jsx-runtime/index.d.ts`, content: jsxLibraryContent }, { path: `${project}/node_modules/react/package.json`, content: JSON.stringify({ name: "react", version: "0.0.1" }) }, { path: `${project}/index.tsx`, content: `export const App = () =>
;` }, @@ -345,7 +339,7 @@ export const Fragment: unique symbol; verifyIncrementalWatchEmit({ subScenario: "importHelpers backing types removed", files: () => [ - { path: libFile.path, content: libContent }, + { path: ts.tscWatch.libFile.path, content: ts.libContent }, { path: `${project}/node_modules/tslib/index.d.ts`, content: "export function __assign(...args: any[]): any;" }, { path: `${project}/node_modules/tslib/package.json`, content: JSON.stringify({ name: "tslib", version: "0.0.1" }) }, { path: `${project}/index.tsx`, content: `export const x = {...{}};` }, @@ -362,7 +356,7 @@ export const Fragment: unique symbol; verifyIncrementalWatchEmit({ subScenario: "editing module augmentation", files: () => [ - { path: libFile.path, content: libContent }, + { path: ts.tscWatch.libFile.path, content: ts.libContent }, { path: `${project}/node_modules/classnames/index.d.ts`, content: `export interface Result {} export default function classNames(): Result;` }, { path: `${project}/src/types/classnames.d.ts`, content: `export {}; declare module "classnames" { interface Result { foo } }` }, { path: `${project}/src/index.ts`, content: `import classNames from "classnames"; classNames().foo;` }, diff --git a/src/testRunner/unittests/tscWatch/nodeNextWatch.ts b/src/testRunner/unittests/tscWatch/nodeNextWatch.ts index a7cb1d4ed949a..9a119d483f739 100644 --- a/src/testRunner/unittests/tscWatch/nodeNextWatch.ts +++ b/src/testRunner/unittests/tscWatch/nodeNextWatch.ts @@ -1,11 +1,11 @@ namespace ts.tscWatch { describe("unittests:: tsc-watch:: nodeNextWatch:: emit when module emit is specified as nodenext", () => { - verifyTscWatch({ + ts.tscWatch.verifyTscWatch({ scenario: "nodenext watch emit", subScenario: "esm-mode file is edited", commandLineArgs: ["--w", "--p", "/project/tsconfig.json"], sys: () => { - const configFile: File = { + const configFile: ts.tscWatch.File = { path: "/project/tsconfig.json", content: JSON.stringify({ compilerOptions: { @@ -17,7 +17,7 @@ namespace ts.tscWatch { } }) }; - const packageFile: File = { + const packageFile: ts.tscWatch.File = { path: "/project/package.json", content: JSON.stringify({ name: "some-proj", @@ -27,30 +27,26 @@ namespace ts.tscWatch { main: "index.js", }) }; - const file1: File = { + const file1: ts.tscWatch.File = { path: "/project/src/index.ts", content: Utils.dedent` import * as Thing from "thing"; Thing.fn();` }; - const declFile: File = { + const declFile: ts.tscWatch.File = { path: "/project/src/deps.d.ts", content: `declare module "thing";` }; - return createWatchedSystem([configFile, file1, declFile, packageFile, { ...libFile, path: "/a/lib/lib.es2020.full.d.ts" }]); + return ts.tscWatch.createWatchedSystem([configFile, file1, declFile, packageFile, { ...ts.tscWatch.libFile, path: "/a/lib/lib.es2020.full.d.ts" }]); }, changes: [ { caption: "Modify typescript file", - change: sys => sys.modifyFile( - "/project/src/index.ts", - Utils.dedent` + change: sys => sys.modifyFile("/project/src/index.ts", Utils.dedent ` import * as Thing from "thing"; - Thing.fn();`, - {}, - ), - timeouts: runQueuedTimeoutCallbacks, + Thing.fn();`, {}), + timeouts: ts.tscWatch.runQueuedTimeoutCallbacks, } ], }); diff --git a/src/testRunner/unittests/tscWatch/programUpdates.ts b/src/testRunner/unittests/tscWatch/programUpdates.ts index 68f03f0d20cc4..a8e9d65317169 100644 --- a/src/testRunner/unittests/tscWatch/programUpdates.ts +++ b/src/testRunner/unittests/tscWatch/programUpdates.ts @@ -2,16 +2,16 @@ namespace ts.tscWatch { describe("unittests:: tsc-watch:: program updates", () => { const scenario = "programUpdates"; const configFilePath = "/a/b/tsconfig.json"; - const configFile: File = { + const configFile: ts.tscWatch.File = { path: configFilePath, content: `{}` }; - verifyTscWatch({ + ts.tscWatch.verifyTscWatch({ scenario, subScenario: "create watch without config file", commandLineArgs: ["-w", "/a/b/c/app.ts"], sys: () => { - const appFile: File = { + const appFile: ts.tscWatch.File = { path: "/a/b/c/app.ts", content: ` import {f} from "./module" @@ -19,16 +19,16 @@ namespace ts.tscWatch { ` }; - const moduleFile: File = { + const moduleFile: ts.tscWatch.File = { path: "/a/b/c/module.d.ts", content: `export let x: number` }; - return createWatchedSystem([appFile, moduleFile, libFile]); + return ts.tscWatch.createWatchedSystem([appFile, moduleFile, ts.tscWatch.libFile]); }, - changes: emptyArray + changes: ts.emptyArray }); - verifyTscWatch({ + ts.tscWatch.verifyTscWatch({ scenario, subScenario: "can handle tsconfig file name with difference casing", commandLineArgs: ["-w", "-p", "/A/B/tsconfig.json"], @@ -43,17 +43,17 @@ namespace ts.tscWatch { include: ["app.ts"] }) }; - return createWatchedSystem([f1, libFile, config], { useCaseSensitiveFileNames: false }); + return ts.tscWatch.createWatchedSystem([f1, ts.tscWatch.libFile, config], { useCaseSensitiveFileNames: false }); }, - changes: emptyArray + changes: ts.emptyArray }); - verifyTscWatch({ + ts.tscWatch.verifyTscWatch({ scenario, subScenario: "create configured project without file list", commandLineArgs: ["-w", "-p", configFilePath], sys: () => { - const configFile: File = { + const configFile: ts.tscWatch.File = { path: configFilePath, content: ` { @@ -63,43 +63,43 @@ namespace ts.tscWatch { ] }` }; - const file1: File = { + const file1: ts.tscWatch.File = { path: "/a/b/c/f1.ts", content: "let x = 1" }; - const file2: File = { + const file2: ts.tscWatch.File = { path: "/a/b/d/f2.ts", content: "let y = 1" }; - const file3: File = { + const file3: ts.tscWatch.File = { path: "/a/b/e/f3.ts", content: "let z = 1" }; - return createWatchedSystem([configFile, libFile, file1, file2, file3]); + return ts.tscWatch.createWatchedSystem([configFile, ts.tscWatch.libFile, file1, file2, file3]); }, - changes: emptyArray + changes: ts.emptyArray }); - verifyTscWatch({ + ts.tscWatch.verifyTscWatch({ scenario, subScenario: "add new files to a configured program without file list", commandLineArgs: ["-w", "-p", configFilePath], - sys: () => createWatchedSystem([commonFile1, libFile, configFile]), + sys: () => ts.tscWatch.createWatchedSystem([ts.tscWatch.commonFile1, ts.tscWatch.libFile, configFile]), changes: [ { caption: "Create commonFile2", - change: sys => sys.writeFile(commonFile2.path, commonFile2.content), - timeouts: checkSingleTimeoutQueueLengthAndRun, + change: sys => sys.writeFile(ts.tscWatch.commonFile2.path, ts.tscWatch.commonFile2.content), + timeouts: ts.tscWatch.checkSingleTimeoutQueueLengthAndRun, } ] }); - verifyTscWatch({ + ts.tscWatch.verifyTscWatch({ scenario, subScenario: "should ignore non-existing files specified in the config file", commandLineArgs: ["-w", "-p", configFilePath], sys: () => { - const configFile: File = { + const configFile: ts.tscWatch.File = { path: configFilePath, content: `{ "compilerOptions": {}, @@ -109,131 +109,131 @@ namespace ts.tscWatch { ] }` }; - return createWatchedSystem([commonFile1, commonFile2, libFile, configFile]); + return ts.tscWatch.createWatchedSystem([ts.tscWatch.commonFile1, ts.tscWatch.commonFile2, ts.tscWatch.libFile, configFile]); }, - changes: emptyArray + changes: ts.emptyArray }); - verifyTscWatch({ + ts.tscWatch.verifyTscWatch({ scenario, subScenario: "handle recreated files correctly", commandLineArgs: ["-w", "-p", configFilePath, "--explainFiles"], sys: () => { - return createWatchedSystem([libFile, commonFile1, commonFile2, configFile]); + return ts.tscWatch.createWatchedSystem([ts.tscWatch.libFile, ts.tscWatch.commonFile1, ts.tscWatch.commonFile2, configFile]); }, changes: [ { caption: "change file to ensure signatures are updated", - change: sys => sys.appendFile(commonFile2.path, ";let xy = 10;"), - timeouts: checkSingleTimeoutQueueLengthAndRun, + change: sys => sys.appendFile(ts.tscWatch.commonFile2.path, ";let xy = 10;"), + timeouts: ts.tscWatch.checkSingleTimeoutQueueLengthAndRun, }, { caption: "delete file2", - change: sys => sys.deleteFile(commonFile2.path), - timeouts: checkSingleTimeoutQueueLengthAndRun, + change: sys => sys.deleteFile(ts.tscWatch.commonFile2.path), + timeouts: ts.tscWatch.checkSingleTimeoutQueueLengthAndRun, }, { caption: "recreate file2", - change: sys => sys.writeFile(commonFile2.path, commonFile2.content), - timeouts: checkSingleTimeoutQueueLengthAndRun, + change: sys => sys.writeFile(ts.tscWatch.commonFile2.path, ts.tscWatch.commonFile2.content), + timeouts: ts.tscWatch.checkSingleTimeoutQueueLengthAndRun, } ] }); - verifyTscWatch({ + ts.tscWatch.verifyTscWatch({ scenario, subScenario: "handles the missing files - that were added to program because they were added with tripleSlashRefs", commandLineArgs: ["-w", "/a/b/commonFile1.ts"], sys: () => { - const file1: File = { - path: commonFile1.path, + const file1: ts.tscWatch.File = { + path: ts.tscWatch.commonFile1.path, content: `/// let x = y` }; - return createWatchedSystem([file1, libFile]); + return ts.tscWatch.createWatchedSystem([file1, ts.tscWatch.libFile]); }, changes: [ { caption: "create file2", - change: sys => sys.writeFile(commonFile2.path, commonFile2.content), - timeouts: checkSingleTimeoutQueueLengthAndRun, + change: sys => sys.writeFile(ts.tscWatch.commonFile2.path, ts.tscWatch.commonFile2.content), + timeouts: ts.tscWatch.checkSingleTimeoutQueueLengthAndRun, } ] }); - verifyTscWatch({ + ts.tscWatch.verifyTscWatch({ scenario, subScenario: "should reflect change in config file", commandLineArgs: ["-w", "-p", configFilePath, "--explainFiles"], sys: () => { - const configFile: File = { + const configFile: ts.tscWatch.File = { path: configFilePath, content: `{ "compilerOptions": {}, - "files": ["${commonFile1.path}", "${commonFile2.path}"] + "files": ["${ts.tscWatch.commonFile1.path}", "${ts.tscWatch.commonFile2.path}"] }` }; - return createWatchedSystem([libFile, commonFile1, commonFile2, configFile]); + return ts.tscWatch.createWatchedSystem([ts.tscWatch.libFile, ts.tscWatch.commonFile1, ts.tscWatch.commonFile2, configFile]); }, changes: [ { caption: "change file to ensure signatures are updated", - change: sys => sys.appendFile(commonFile2.path, ";let xy = 10;"), - timeouts: checkSingleTimeoutQueueLengthAndRun, + change: sys => sys.appendFile(ts.tscWatch.commonFile2.path, ";let xy = 10;"), + timeouts: ts.tscWatch.checkSingleTimeoutQueueLengthAndRun, }, { caption: "Change config", change: sys => sys.writeFile(configFilePath, `{ "compilerOptions": {}, - "files": ["${commonFile1.path}"] + "files": ["${ts.tscWatch.commonFile1.path}"] }`), - timeouts: checkSingleTimeoutQueueLengthAndRun, + timeouts: ts.tscWatch.checkSingleTimeoutQueueLengthAndRun, } ] }); - verifyTscWatch({ + ts.tscWatch.verifyTscWatch({ scenario, subScenario: "works correctly when config file is changed but its content havent", commandLineArgs: ["-w", "-p", configFilePath], sys: () => { - const configFile: File = { + const configFile: ts.tscWatch.File = { path: configFilePath, content: `{ "compilerOptions": {}, - "files": ["${commonFile1.path}", "${commonFile2.path}"] + "files": ["${ts.tscWatch.commonFile1.path}", "${ts.tscWatch.commonFile2.path}"] }` }; - return createWatchedSystem([libFile, commonFile1, commonFile2, configFile]); + return ts.tscWatch.createWatchedSystem([ts.tscWatch.libFile, ts.tscWatch.commonFile1, ts.tscWatch.commonFile2, configFile]); }, changes: [ { caption: "Modify config without changing content", change: sys => sys.modifyFile(configFilePath, `{ "compilerOptions": {}, - "files": ["${commonFile1.path}", "${commonFile2.path}"] + "files": ["${ts.tscWatch.commonFile1.path}", "${ts.tscWatch.commonFile2.path}"] }`), - timeouts: checkSingleTimeoutQueueLengthAndRun, + timeouts: ts.tscWatch.checkSingleTimeoutQueueLengthAndRun, } ] }); - verifyTscWatch({ + ts.tscWatch.verifyTscWatch({ scenario, subScenario: "Updates diagnostics when '--noUnusedLabels' changes", commandLineArgs: ["-w", "-p", "/tsconfig.json"], sys: () => { - const aTs: File = { + const aTs: ts.tscWatch.File = { path: "/a.ts", content: "label: while (1) {}" }; - const tsconfig: File = { + const tsconfig: ts.tscWatch.File = { path: "/tsconfig.json", content: JSON.stringify({ compilerOptions: { allowUnusedLabels: true } }) }; - return createWatchedSystem([libFile, aTs, tsconfig]); + return ts.tscWatch.createWatchedSystem([ts.tscWatch.libFile, aTs, tsconfig]); }, changes: [ { @@ -241,24 +241,24 @@ namespace ts.tscWatch { change: sys => sys.modifyFile("/tsconfig.json", JSON.stringify({ compilerOptions: { allowUnusedLabels: false } })), - timeouts: checkSingleTimeoutQueueLengthAndRun + timeouts: ts.tscWatch.checkSingleTimeoutQueueLengthAndRun }, { caption: "Enable allowUnsusedLabels", change: sys => sys.modifyFile("/tsconfig.json", JSON.stringify({ compilerOptions: { allowUnusedLabels: true } })), - timeouts: checkSingleTimeoutQueueLengthAndRun, + timeouts: ts.tscWatch.checkSingleTimeoutQueueLengthAndRun, } ] }); - verifyTscWatch({ + ts.tscWatch.verifyTscWatch({ scenario, subScenario: "updates diagnostics and emit for decorators", commandLineArgs: ["-w"], sys: () => { - const aTs: File = { + const aTs: ts.tscWatch.File = { path: "/a.ts", content: `import {B} from './b' @((_) => {}) @@ -266,17 +266,17 @@ export class A { constructor(p: B) {} }`, }; - const bTs: File = { + const bTs: ts.tscWatch.File = { path: "/b.ts", content: `export class B {}`, }; - const tsconfig: File = { + const tsconfig: ts.tscWatch.File = { path: "/tsconfig.json", content: JSON.stringify({ compilerOptions: { target: "es6", importsNotUsedAsValues: "error" } }) }; - return createWatchedSystem([libFile, aTs, bTs, tsconfig]); + return ts.tscWatch.createWatchedSystem([ts.tscWatch.libFile, aTs, bTs, tsconfig]); }, changes: [ { @@ -284,7 +284,7 @@ export class A { change: sys => sys.modifyFile("/tsconfig.json", JSON.stringify({ compilerOptions: { target: "es6", importsNotUsedAsValues: "error", experimentalDecorators: true } })), - timeouts: checkSingleTimeoutQueueLengthAndRun, + timeouts: ts.tscWatch.checkSingleTimeoutQueueLengthAndRun, }, { @@ -292,50 +292,50 @@ export class A { change: sys => sys.modifyFile("/tsconfig.json", JSON.stringify({ compilerOptions: { target: "es6", importsNotUsedAsValues: "error", experimentalDecorators: true, emitDecoratorMetadata: true } })), - timeouts: checkSingleTimeoutQueueLengthAndRun, + timeouts: ts.tscWatch.checkSingleTimeoutQueueLengthAndRun, } ] }); - verifyTscWatch({ + ts.tscWatch.verifyTscWatch({ scenario, subScenario: "files explicitly excluded in config file", commandLineArgs: ["-w", "-p", configFilePath], sys: () => { - const configFile: File = { + const configFile: ts.tscWatch.File = { path: configFilePath, content: `{ "compilerOptions": {}, "exclude": ["/a/c"] }` }; - const excludedFile1: File = { + const excludedFile1: ts.tscWatch.File = { path: "/a/c/excluedFile1.ts", content: `let t = 1;` }; - return createWatchedSystem([libFile, commonFile1, commonFile2, excludedFile1, configFile]); + return ts.tscWatch.createWatchedSystem([ts.tscWatch.libFile, ts.tscWatch.commonFile1, ts.tscWatch.commonFile2, excludedFile1, configFile]); }, - changes: emptyArray + changes: ts.emptyArray }); - verifyTscWatch({ + ts.tscWatch.verifyTscWatch({ scenario, subScenario: "should properly handle module resolution changes in config file", commandLineArgs: ["-w", "-p", configFilePath], sys: () => { - const file1: File = { + const file1: ts.tscWatch.File = { path: "/a/b/file1.ts", content: `import { T } from "module1";` }; - const nodeModuleFile: File = { + const nodeModuleFile: ts.tscWatch.File = { path: "/a/b/node_modules/module1.ts", content: `export interface T {}` }; - const classicModuleFile: File = { + const classicModuleFile: ts.tscWatch.File = { path: "/a/module1.ts", content: `export interface T {}` }; - const configFile: File = { + const configFile: ts.tscWatch.File = { path: configFilePath, content: `{ "compilerOptions": { @@ -344,7 +344,7 @@ export class A { "files": ["${file1.path}"] }` }; - return createWatchedSystem([libFile, file1, nodeModuleFile, classicModuleFile, configFile]); + return ts.tscWatch.createWatchedSystem([ts.tscWatch.libFile, file1, nodeModuleFile, classicModuleFile, configFile]); }, changes: [ { @@ -355,17 +355,17 @@ export class A { }, "files": ["/a/b/file1.ts"] }`), - timeouts: checkSingleTimeoutQueueLengthAndRun, + timeouts: ts.tscWatch.checkSingleTimeoutQueueLengthAndRun, } ] }); - verifyTscWatch({ + ts.tscWatch.verifyTscWatch({ scenario, subScenario: "should tolerate config file errors and still try to build a project", commandLineArgs: ["-w", "-p", configFilePath], sys: () => { - const configFile: File = { + const configFile: ts.tscWatch.File = { path: configFilePath, content: `{ "compilerOptions": { @@ -375,12 +375,12 @@ export class A { "someOtherProperty": {} }` }; - return createWatchedSystem([commonFile1, commonFile2, libFile, configFile]); + return ts.tscWatch.createWatchedSystem([ts.tscWatch.commonFile1, ts.tscWatch.commonFile2, ts.tscWatch.libFile, configFile]); }, - changes: emptyArray + changes: ts.emptyArray }); - verifyTscWatch({ + ts.tscWatch.verifyTscWatch({ scenario, subScenario: "changes in files are reflected in project structure", commandLineArgs: ["-w", "/a/b/f1.ts", "--explainFiles"], @@ -397,19 +397,19 @@ export class A { path: "/a/c/f3.ts", content: `export let y = 1;` }; - return createWatchedSystem([file1, file2, file3, libFile]); + return ts.tscWatch.createWatchedSystem([file1, file2, file3, ts.tscWatch.libFile]); }, changes: [ { caption: "Modify f2 to include f3", // now inferred project should inclule file3 change: sys => sys.modifyFile("/a/b/f2.ts", `export * from "../c/f3"`), - timeouts: checkSingleTimeoutQueueLengthAndRun, + timeouts: ts.tscWatch.checkSingleTimeoutQueueLengthAndRun, } ] }); - verifyTscWatch({ + ts.tscWatch.verifyTscWatch({ scenario, subScenario: "deleted files affect project structure", commandLineArgs: ["-w", "/a/b/f1.ts", "--noImplicitAny"], @@ -426,18 +426,18 @@ export class A { path: "/a/c/f3.ts", content: `export let y = 1;` }; - return createWatchedSystem([file1, file2, file3, libFile]); + return ts.tscWatch.createWatchedSystem([file1, file2, file3, ts.tscWatch.libFile]); }, changes: [ { caption: "Delete f2", change: sys => sys.deleteFile("/a/b/f2.ts"), - timeouts: checkSingleTimeoutQueueLengthAndRun, + timeouts: ts.tscWatch.checkSingleTimeoutQueueLengthAndRun, } ] }); - verifyTscWatch({ + ts.tscWatch.verifyTscWatch({ scenario, subScenario: "deleted files affect project structure-2", commandLineArgs: ["-w", "/a/b/f1.ts", "/a/c/f3.ts", "--noImplicitAny"], @@ -454,18 +454,18 @@ export class A { path: "/a/c/f3.ts", content: `export let y = 1;` }; - return createWatchedSystem([file1, file2, file3, libFile]); + return ts.tscWatch.createWatchedSystem([file1, file2, file3, ts.tscWatch.libFile]); }, changes: [ { caption: "Delete f2", change: sys => sys.deleteFile("/a/b/f2.ts"), - timeouts: checkSingleTimeoutQueueLengthAndRun, + timeouts: ts.tscWatch.checkSingleTimeoutQueueLengthAndRun, } ] }); - verifyTscWatch({ + ts.tscWatch.verifyTscWatch({ scenario, subScenario: "config file includes the file", commandLineArgs: ["-w", "-p", "/a/c/tsconfig.json"], @@ -486,12 +486,12 @@ export class A { path: "/a/c/tsconfig.json", content: JSON.stringify({ compilerOptions: {}, files: ["f2.ts", "f3.ts"] }) }; - return createWatchedSystem([file1, file2, file3, libFile, configFile]); + return ts.tscWatch.createWatchedSystem([file1, file2, file3, ts.tscWatch.libFile, configFile]); }, - changes: emptyArray + changes: ts.emptyArray }); - verifyTscWatch({ + ts.tscWatch.verifyTscWatch({ scenario, subScenario: "change module to none", commandLineArgs: ["-w", "-p", configFilePath], @@ -500,11 +500,11 @@ export class A { path: "/a/b/f1.ts", content: "export {}\ndeclare global {}" }; - return createWatchedSystem([file1, libFile, configFile]); + return ts.tscWatch.createWatchedSystem([file1, ts.tscWatch.libFile, configFile]); }, changes: [{ caption: "change `module` to 'none'", - timeouts: checkSingleTimeoutQueueLengthAndRun, + timeouts: ts.tscWatch.checkSingleTimeoutQueueLengthAndRun, change: sys => { sys.writeFile(configFilePath, JSON.stringify({ compilerOptions: { module: "none" } })); } @@ -526,49 +526,49 @@ export class A { path: "/a/d/f3.ts", content: "export let y = 1;" }; - const { sys, baseline, oldSnap, cb, getPrograms } = createBaseline(createWatchedSystem([libFile, file1, file2, file3])); - const host = createWatchCompilerHostOfFilesAndCompilerOptionsForBaseline({ + const { sys, baseline, oldSnap, cb, getPrograms } = ts.tscWatch.createBaseline(ts.tscWatch.createWatchedSystem([ts.tscWatch.libFile, file1, file2, file3])); + const host = ts.tscWatch.createWatchCompilerHostOfFilesAndCompilerOptionsForBaseline({ rootFiles: [file2.path, file3.path], system: sys, options: { allowNonTsExtensions: true }, cb, watchOptions: undefined }); - createWatchProgram(host); + ts.createWatchProgram(host); baseline.push(`${sys.getExecutingFilePath()} --w ${file2.path} ${file3.path}`); - watchBaseline({ + ts.tscWatch.watchBaseline({ baseline, getPrograms, - oldPrograms: emptyArray, + oldPrograms: ts.emptyArray, sys, oldSnap, }); - const {cb: cb2, getPrograms: getPrograms2 } = commandLineCallbacks(sys); + const { cb: cb2, getPrograms: getPrograms2 } = ts.commandLineCallbacks(sys); const oldSnap2 = sys.snap(); baseline.push("createing separate watcher"); - createWatchProgram(createWatchCompilerHostOfFilesAndCompilerOptionsForBaseline({ + ts.createWatchProgram(ts.tscWatch.createWatchCompilerHostOfFilesAndCompilerOptionsForBaseline({ rootFiles:[file1.path], system: sys, options: { allowNonTsExtensions: true }, cb: cb2, watchOptions: undefined })); - watchBaseline({ + ts.tscWatch.watchBaseline({ baseline, getPrograms: getPrograms2, - oldPrograms: emptyArray, + oldPrograms: ts.emptyArray, sys, oldSnap: oldSnap2, }); sys.checkTimeoutQueueLength(0); - baseline.push(`First program is not updated:: ${getPrograms() === emptyArray}`); - baseline.push(`Second program is not updated:: ${getPrograms2() === emptyArray}`); + baseline.push(`First program is not updated:: ${getPrograms() === ts.emptyArray}`); + baseline.push(`Second program is not updated:: ${getPrograms2() === ts.emptyArray}`); Harness.Baseline.runBaseline(`tscWatch/${scenario}/two-watch-programs-are-not-affected-by-each-other.js`, baseline.join("\r\n")); }); - verifyTscWatch({ + ts.tscWatch.verifyTscWatch({ scenario, subScenario: "can correctly update configured project when set of root files has changed (new file on disk)", commandLineArgs: ["-w", "-p", configFilePath], @@ -577,18 +577,18 @@ export class A { path: "/a/b/f1.ts", content: "let x = 1" }; - return createWatchedSystem([file1, libFile, configFile]); + return ts.tscWatch.createWatchedSystem([file1, ts.tscWatch.libFile, configFile]); }, changes: [ { caption: "Write f2", change: sys => sys.writeFile("/a/b/f2.ts", "let y = 1"), - timeouts: checkSingleTimeoutQueueLengthAndRun, + timeouts: ts.tscWatch.checkSingleTimeoutQueueLengthAndRun, } ] }); - verifyTscWatch({ + ts.tscWatch.verifyTscWatch({ scenario, subScenario: "can correctly update configured project when set of root files has changed (new file in list of files)", commandLineArgs: ["-w", "-p", configFilePath], @@ -605,42 +605,42 @@ export class A { path: configFilePath, content: JSON.stringify({ compilerOptions: {}, files: ["f1.ts"] }) }; - return createWatchedSystem([file1, file2, libFile, configFile]); + return ts.tscWatch.createWatchedSystem([file1, file2, ts.tscWatch.libFile, configFile]); }, changes: [ { caption: "Modify config to make f2 as root too", change: sys => sys.writeFile(configFilePath, JSON.stringify({ compilerOptions: {}, files: ["f1.ts", "f2.ts"] })), - timeouts: checkSingleTimeoutQueueLengthAndRun, + timeouts: ts.tscWatch.checkSingleTimeoutQueueLengthAndRun, } ] }); - verifyTscWatch({ + ts.tscWatch.verifyTscWatch({ scenario, subScenario: "can correctly update configured project when set of root files has changed through include", commandLineArgs: ["-w", "-p", "."], sys: () => { const file1 = { - path: `${projectRoot}/Project/file1.ts`, + path: `${ts.tscWatch.projectRoot}/Project/file1.ts`, content: "export const x = 10;" }; const configFile = { - path: `${projectRoot}/Project/tsconfig.json`, + path: `${ts.tscWatch.projectRoot}/Project/tsconfig.json`, content: JSON.stringify({ include: [".", "./**/*.json"] }) }; - return createWatchedSystem([file1, libFile, configFile], { currentDirectory: `${projectRoot}/Project` }); + return ts.tscWatch.createWatchedSystem([file1, ts.tscWatch.libFile, configFile], { currentDirectory: `${ts.tscWatch.projectRoot}/Project` }); }, changes: [ { caption: "Write file2", - change: sys => sys.writeFile(`${projectRoot}/Project/file2.ts`, "export const y = 10;"), - timeouts: checkSingleTimeoutQueueLengthAndRun + change: sys => sys.writeFile(`${ts.tscWatch.projectRoot}/Project/file2.ts`, "export const y = 10;"), + timeouts: ts.tscWatch.checkSingleTimeoutQueueLengthAndRun } ] }); - verifyTscWatch({ + ts.tscWatch.verifyTscWatch({ scenario, subScenario: "can update configured project when set of root files was not changed", commandLineArgs: ["-w", "-p", configFilePath], @@ -657,18 +657,18 @@ export class A { path: configFilePath, content: JSON.stringify({ compilerOptions: {}, files: ["f1.ts", "f2.ts"] }) }; - return createWatchedSystem([file1, file2, libFile, configFile]); + return ts.tscWatch.createWatchedSystem([file1, file2, ts.tscWatch.libFile, configFile]); }, changes: [ { caption: "Modify config to set outFile option", change: sys => sys.writeFile(configFilePath, JSON.stringify({ compilerOptions: { outFile: "out.js" }, files: ["f1.ts", "f2.ts"] })), - timeouts: checkSingleTimeoutQueueLengthAndRun, + timeouts: ts.tscWatch.checkSingleTimeoutQueueLengthAndRun, } ] }); - verifyTscWatch({ + ts.tscWatch.verifyTscWatch({ scenario, subScenario: "file in files is deleted", commandLineArgs: ["-w", "-p", configFilePath], @@ -685,18 +685,18 @@ export class A { path: configFilePath, content: JSON.stringify({ compilerOptions: {}, files: ["f1.ts", "f2.ts"] }) }; - return createWatchedSystem([file1, file2, libFile, configFile]); + return ts.tscWatch.createWatchedSystem([file1, file2, ts.tscWatch.libFile, configFile]); }, changes: [ { caption: "Delete f2", change: sys => sys.deleteFile("/a/b/f2.ts"), - timeouts: checkSingleTimeoutQueueLengthAndRun, + timeouts: ts.tscWatch.checkSingleTimeoutQueueLengthAndRun, } ] }); - verifyTscWatch({ + ts.tscWatch.verifyTscWatch({ scenario, subScenario: "config file is deleted", commandLineArgs: ["-w", "-p", configFilePath], @@ -709,18 +709,18 @@ export class A { path: "/a/b/f2.ts", content: "let y = 2;" }; - return createWatchedSystem([file1, file2, libFile, configFile]); + return ts.tscWatch.createWatchedSystem([file1, file2, ts.tscWatch.libFile, configFile]); }, changes: [ { caption: "Delete config file", change: sys => sys.deleteFile(configFilePath), - timeouts: checkSingleTimeoutQueueLengthAndRun, + timeouts: ts.tscWatch.checkSingleTimeoutQueueLengthAndRun, } ] }); - verifyTscWatch({ + ts.tscWatch.verifyTscWatch({ scenario, subScenario: "Proper errors document is not contained in project", commandLineArgs: ["-w", "-p", configFilePath], @@ -733,19 +733,19 @@ export class A { path: configFilePath, content: "{" }; - return createWatchedSystem([file1, libFile, corruptedConfig]); + return ts.tscWatch.createWatchedSystem([file1, ts.tscWatch.libFile, corruptedConfig]); }, - changes: emptyArray + changes: ts.emptyArray }); - verifyTscWatch({ + ts.tscWatch.verifyTscWatch({ scenario, subScenario: "correctly handles changes in lib section of config file", commandLineArgs: ["-w", "-p", "/src/tsconfig.json"], sys: () => { const libES5 = { path: "/compiler/lib.es5.d.ts", - content: `${libFile.content} + content: `${ts.tscWatch.libFile.content} declare const eval: any` }; const libES2015Promise = { @@ -758,8 +758,7 @@ declare const eval: any` }; const config1 = { path: "/src/tsconfig.json", - content: JSON.stringify( - { + content: JSON.stringify({ compilerOptions: { module: "commonjs", target: "es5", @@ -771,13 +770,12 @@ declare const eval: any` } }) }; - return createWatchedSystem([libES5, libES2015Promise, app, config1], { executingFilePath: "/compiler/tsc.js" }); + return ts.tscWatch.createWatchedSystem([libES5, libES2015Promise, app, config1], { executingFilePath: "/compiler/tsc.js" }); }, changes: [ { caption: "Change the lib in config", - change: sys => sys.writeFile("/src/tsconfig.json", JSON.stringify( - { + change: sys => sys.writeFile("/src/tsconfig.json", JSON.stringify({ compilerOptions: { module: "commonjs", target: "es5", @@ -788,14 +786,13 @@ declare const eval: any` "es2015.promise" ] } - }) - ), - timeouts: checkSingleTimeoutQueueLengthAndRun, + })), + timeouts: ts.tscWatch.checkSingleTimeoutQueueLengthAndRun, } ] }); - verifyTscWatch({ + ts.tscWatch.verifyTscWatch({ scenario, subScenario: "should handle non-existing directories in config file", commandLineArgs: ["-w", "-p", "/a/tsconfig.json"], @@ -814,17 +811,17 @@ declare const eval: any` ] }) }; - return createWatchedSystem([f, config, libFile]); + return ts.tscWatch.createWatchedSystem([f, config, ts.tscWatch.libFile]); }, - changes: emptyArray + changes: ts.emptyArray }); - function runQueuedTimeoutCallbacksTwice(sys: WatchedSystem) { + function runQueuedTimeoutCallbacksTwice(sys: ts.tscWatch.WatchedSystem) { sys.runQueuedTimeoutCallbacks(); // Scheduled invalidation of resolutions sys.runQueuedTimeoutCallbacks(); // Actual update } - const changeModuleFileToModuleFile1: TscWatchCompileChange = { + const changeModuleFileToModuleFile1: ts.tscWatch.TscWatchCompileChange = { caption: "Rename moduleFile to moduleFile1", change: sys => { sys.renameFile("/a/b/moduleFile.ts", "/a/b/moduleFile1.ts"); @@ -832,13 +829,13 @@ declare const eval: any` }, timeouts: runQueuedTimeoutCallbacksTwice }; - const changeModuleFile1ToModuleFile: TscWatchCompileChange = { + const changeModuleFile1ToModuleFile: ts.tscWatch.TscWatchCompileChange = { caption: "Rename moduleFile1 back to moduleFile", change: sys => sys.renameFile("/a/b/moduleFile1.ts", "/a/b/moduleFile.ts"), timeouts: runQueuedTimeoutCallbacksTwice, }; - verifyTscWatch({ + ts.tscWatch.verifyTscWatch({ scenario, subScenario: "rename a module file and rename back should restore the states for inferred projects", commandLineArgs: ["-w", "/a/b/file1.ts"], @@ -851,7 +848,7 @@ declare const eval: any` path: "/a/b/file1.ts", content: 'import * as T from "./moduleFile"; T.bar();' }; - return createWatchedSystem([moduleFile, file1, libFile]); + return ts.tscWatch.createWatchedSystem([moduleFile, file1, ts.tscWatch.libFile]); }, changes: [ changeModuleFileToModuleFile1, @@ -859,7 +856,7 @@ declare const eval: any` ] }); - verifyTscWatch({ + ts.tscWatch.verifyTscWatch({ scenario, subScenario: "rename a module file and rename back should restore the states for configured projects", commandLineArgs: ["-w", "-p", configFilePath], @@ -872,7 +869,7 @@ declare const eval: any` path: "/a/b/file1.ts", content: 'import * as T from "./moduleFile"; T.bar();' }; - return createWatchedSystem([moduleFile, file1, configFile, libFile]); + return ts.tscWatch.createWatchedSystem([moduleFile, file1, configFile, ts.tscWatch.libFile]); }, changes: [ changeModuleFileToModuleFile1, @@ -880,7 +877,7 @@ declare const eval: any` ] }); - verifyTscWatch({ + ts.tscWatch.verifyTscWatch({ scenario, subScenario: "types should load from config file path if config exists", commandLineArgs: ["-w", "-p", configFilePath], @@ -900,12 +897,12 @@ declare const eval: any` const cwd = { path: "/a/c" }; - return createWatchedSystem([f1, config, node, cwd, libFile], { currentDirectory: cwd.path }); + return ts.tscWatch.createWatchedSystem([f1, config, node, cwd, ts.tscWatch.libFile], { currentDirectory: cwd.path }); }, - changes: emptyArray + changes: ts.emptyArray }); - verifyTscWatch({ + ts.tscWatch.verifyTscWatch({ scenario, subScenario: "add the missing module file for inferred project-should remove the module not found error", commandLineArgs: ["-w", "/a/b/file1.ts"], @@ -914,7 +911,7 @@ declare const eval: any` path: "/a/b/file1.ts", content: 'import * as T from "./moduleFile"; T.bar();' }; - return createWatchedSystem([file1, libFile]); + return ts.tscWatch.createWatchedSystem([file1, ts.tscWatch.libFile]); }, changes: [ { @@ -925,7 +922,7 @@ declare const eval: any` ] }); - verifyTscWatch({ + ts.tscWatch.verifyTscWatch({ scenario, subScenario: "Configure file diagnostics events are generated when the config file has errors", commandLineArgs: ["-w", "-p", configFilePath], @@ -943,12 +940,12 @@ declare const eval: any` } }` }; - return createWatchedSystem([file, configFile, libFile]); + return ts.tscWatch.createWatchedSystem([file, configFile, ts.tscWatch.libFile]); }, - changes: emptyArray + changes: ts.emptyArray }); - verifyTscWatch({ + ts.tscWatch.verifyTscWatch({ scenario, subScenario: "if config file doesnt have errors, they are not reported", commandLineArgs: ["-w", "-p", configFilePath], @@ -963,12 +960,12 @@ declare const eval: any` "compilerOptions": {} }` }; - return createWatchedSystem([file, configFile, libFile]); + return ts.tscWatch.createWatchedSystem([file, configFile, ts.tscWatch.libFile]); }, - changes: emptyArray + changes: ts.emptyArray }); - verifyTscWatch({ + ts.tscWatch.verifyTscWatch({ scenario, subScenario: "Reports errors when the config file changes", commandLineArgs: ["-w", "-p", configFilePath], @@ -977,7 +974,7 @@ declare const eval: any` path: "/a/b/app.ts", content: "let x = 10" }; - return createWatchedSystem([file, configFile, libFile]); + return ts.tscWatch.createWatchedSystem([file, configFile, ts.tscWatch.libFile]); }, changes: [ { @@ -987,7 +984,7 @@ declare const eval: any` "haha": 123 } }`), - timeouts: runQueuedTimeoutCallbacks, + timeouts: ts.tscWatch.runQueuedTimeoutCallbacks, }, { caption: "change config file to remove error", @@ -995,12 +992,12 @@ declare const eval: any` "compilerOptions": { } }`), - timeouts: runQueuedTimeoutCallbacks, + timeouts: ts.tscWatch.runQueuedTimeoutCallbacks, } ] }); - verifyTscWatch({ + ts.tscWatch.verifyTscWatch({ scenario, subScenario: "non-existing directories listed in config file input array should be tolerated without crashing the server", commandLineArgs: ["-w", "-p", configFilePath], @@ -1016,12 +1013,12 @@ declare const eval: any` path: "/a/b/file1.ts", content: "let t = 10;" }; - return createWatchedSystem([file1, configFile, libFile]); + return ts.tscWatch.createWatchedSystem([file1, configFile, ts.tscWatch.libFile]); }, - changes: emptyArray + changes: ts.emptyArray }); - verifyTscWatch({ + ts.tscWatch.verifyTscWatch({ scenario, subScenario: "non-existing directories listed in config file input array should be able to handle @types if input file list is empty", commandLineArgs: ["-w", "-p", "/a/tsconfig.json"], @@ -1045,9 +1042,9 @@ declare const eval: any` path: "/a/node_modules/@types/typings/lib.d.ts", content: `export const x: number` }; - return createWatchedSystem([f, config, t1, t2, libFile], { currentDirectory: getDirectoryPath(f.path) }); + return ts.tscWatch.createWatchedSystem([f, config, t1, t2, ts.tscWatch.libFile], { currentDirectory: ts.getDirectoryPath(f.path) }); }, - changes: emptyArray + changes: ts.emptyArray }); it("should support files without extensions", () => { @@ -1055,15 +1052,15 @@ declare const eval: any` path: "/a/compile", content: "let x = 1" }; - const { sys, baseline, oldSnap, cb, getPrograms } = createBaseline(createWatchedSystem([f, libFile])); - const watch = createWatchProgram(createWatchCompilerHostOfFilesAndCompilerOptionsForBaseline({ + const { sys, baseline, oldSnap, cb, getPrograms } = ts.tscWatch.createBaseline(ts.tscWatch.createWatchedSystem([f, ts.tscWatch.libFile])); + const watch = ts.createWatchProgram(ts.tscWatch.createWatchCompilerHostOfFilesAndCompilerOptionsForBaseline({ rootFiles: [f.path], system: sys, options: { allowNonTsExtensions: true }, cb, watchOptions: undefined })); - runWatchBaseline({ + ts.tscWatch.runWatchBaseline({ scenario, subScenario: "should support files without extensions", commandLineArgs: ["--w", f.path], @@ -1071,12 +1068,12 @@ declare const eval: any` baseline, oldSnap, getPrograms, - changes: emptyArray, + changes: ts.emptyArray, watchOrSolution: watch }); }); - verifyTscWatch({ + ts.tscWatch.verifyTscWatch({ scenario, subScenario: "Options Diagnostic locations reported correctly with changes in configFile contents when options change", commandLineArgs: ["-w", "-p", configFilePath], @@ -1097,7 +1094,7 @@ declare const eval: any` } }` }; - return createWatchedSystem([file, libFile, configFile]); + return ts.tscWatch.createWatchedSystem([file, ts.tscWatch.libFile, configFile]); }, changes: [ { @@ -1109,81 +1106,57 @@ declare const eval: any` "mapRoot": "./" } }`), - timeouts: runQueuedTimeoutCallbacks, + timeouts: ts.tscWatch.runQueuedTimeoutCallbacks, } ] }); describe("should not trigger recompilation because of program emit", () => { - function verifyWithOptions(subScenario: string, options: CompilerOptions) { - verifyTscWatch({ + function verifyWithOptions(subScenario: string, options: ts.CompilerOptions) { + ts.tscWatch.verifyTscWatch({ scenario, subScenario: `should not trigger recompilation because of program emit/${subScenario}`, - commandLineArgs: ["-w", "-p", `${projectRoot}/tsconfig.json`], + commandLineArgs: ["-w", "-p", `${ts.tscWatch.projectRoot}/tsconfig.json`], sys: () => { - const file1: File = { - path: `${projectRoot}/file1.ts`, + const file1: ts.tscWatch.File = { + path: `${ts.tscWatch.projectRoot}/file1.ts`, content: "export const c = 30;" }; - const file2: File = { - path: `${projectRoot}/src/file2.ts`, + const file2: ts.tscWatch.File = { + path: `${ts.tscWatch.projectRoot}/src/file2.ts`, content: `import {c} from "file1"; export const d = 30;` }; - const tsconfig: File = { - path: `${projectRoot}/tsconfig.json`, - content: generateTSConfig(options, emptyArray, "\n") + const tsconfig: ts.tscWatch.File = { + path: `${ts.tscWatch.projectRoot}/tsconfig.json`, + content: ts.generateTSConfig(options, ts.emptyArray, "\n") }; - return createWatchedSystem([file1, file2, libFile, tsconfig], { currentDirectory: projectRoot }); + return ts.tscWatch.createWatchedSystem([file1, file2, ts.tscWatch.libFile, tsconfig], { currentDirectory: ts.tscWatch.projectRoot }); }, changes: [ - noopChange, + ts.tscWatch.noopChange, { caption: "Add new file", - change: sys => sys.writeFile(`${projectRoot}/src/file3.ts`, `export const y = 10;`), + change: sys => sys.writeFile(`${ts.tscWatch.projectRoot}/src/file3.ts`, `export const y = 10;`), timeouts: sys => sys.checkTimeoutQueueLengthAndRun(2), // To update program and failed lookups }, - noopChange, + ts.tscWatch.noopChange, ] }); } - verifyWithOptions( - "without outDir or outFile is specified", - { module: ModuleKind.AMD } - ); - - verifyWithOptions( - "with outFile", - { module: ModuleKind.AMD, outFile: "build/outFile.js" } - ); - - verifyWithOptions( - "when outDir is specified", - { module: ModuleKind.AMD, outDir: "build" } - ); - - verifyWithOptions( - "without outDir or outFile is specified with declaration enabled", - { module: ModuleKind.AMD, declaration: true } - ); - - verifyWithOptions( - "when outDir and declarationDir is specified", - { module: ModuleKind.AMD, outDir: "build", declaration: true, declarationDir: "decls" } - ); - - verifyWithOptions( - "declarationDir is specified", - { module: ModuleKind.AMD, declaration: true, declarationDir: "decls" } - ); + verifyWithOptions("without outDir or outFile is specified", { module: ts.ModuleKind.AMD }); + verifyWithOptions("with outFile", { module: ts.ModuleKind.AMD, outFile: "build/outFile.js" }); + verifyWithOptions("when outDir is specified", { module: ts.ModuleKind.AMD, outDir: "build" }); + verifyWithOptions("without outDir or outFile is specified with declaration enabled", { module: ts.ModuleKind.AMD, declaration: true }); + verifyWithOptions("when outDir and declarationDir is specified", { module: ts.ModuleKind.AMD, outDir: "build", declaration: true, declarationDir: "decls" }); + verifyWithOptions("declarationDir is specified", { module: ts.ModuleKind.AMD, declaration: true, declarationDir: "decls" }); }); - - verifyTscWatch({ + ts.tscWatch.verifyTscWatch({ scenario, subScenario: "shouldnt report error about unused function incorrectly when file changes from global to module", commandLineArgs: ["-w", "/a/b/file.ts", "--noUnusedLocals"], sys: () => { - const file: File = { + const file: ts.tscWatch.File = { path: "/a/b/file.ts", content: `function one() {} function two() { @@ -1192,7 +1165,7 @@ function two() { } }` }; - return createWatchedSystem([file, libFile]); + return ts.tscWatch.createWatchedSystem([file, ts.tscWatch.libFile]); }, changes: [ { @@ -1203,64 +1176,64 @@ export function two() { one(); } }`), - timeouts: runQueuedTimeoutCallbacks, + timeouts: ts.tscWatch.runQueuedTimeoutCallbacks, } ] }); - verifyTscWatch({ + ts.tscWatch.verifyTscWatch({ scenario, subScenario: "watched files when file is deleted and new file is added as part of change", commandLineArgs: ["-w", "-p", "/home/username/project/tsconfig.json"], sys: () => { const projectLocation = "/home/username/project"; - const file: File = { + const file: ts.tscWatch.File = { path: `${projectLocation}/src/file1.ts`, content: "var a = 10;" }; - const configFile: File = { + const configFile: ts.tscWatch.File = { path: `${projectLocation}/tsconfig.json`, content: "{}" }; - return createWatchedSystem([file, libFile, configFile]); + return ts.tscWatch.createWatchedSystem([file, ts.tscWatch.libFile, configFile]); }, changes: [ { caption: "Rename file1 to file2", change: sys => sys.renameFile("/home/username/project/src/file1.ts", "/home/username/project/src/file2.ts"), - timeouts: runQueuedTimeoutCallbacks, + timeouts: ts.tscWatch.runQueuedTimeoutCallbacks, } ] }); - function changeParameterTypeOfBFile(parameterName: string, toType: string): TscWatchCompileChange { + function changeParameterTypeOfBFile(parameterName: string, toType: string): ts.tscWatch.TscWatchCompileChange { return { caption: `Changed ${parameterName} type to ${toType}`, - change: sys => replaceFileText(sys, `${projectRoot}/b.ts`, new RegExp(`${parameterName}\: [a-z]*`), `${parameterName}: ${toType}`), - timeouts: runQueuedTimeoutCallbacks, + change: sys => ts.tscWatch.replaceFileText(sys, `${ts.tscWatch.projectRoot}/b.ts`, new RegExp(`${parameterName}\: [a-z]*`), `${parameterName}: ${toType}`), + timeouts: ts.tscWatch.runQueuedTimeoutCallbacks, }; } - verifyTscWatch({ + ts.tscWatch.verifyTscWatch({ scenario, subScenario: "updates errors correctly when declaration emit is disabled in compiler options", commandLineArgs: ["-w"], sys: () => { - const aFile: File = { - path: `${projectRoot}/a.ts`, + const aFile: ts.tscWatch.File = { + path: `${ts.tscWatch.projectRoot}/a.ts`, content: `import test from './b'; test(4, 5);` }; - const bFile: File = { - path: `${projectRoot}/b.ts`, + const bFile: ts.tscWatch.File = { + path: `${ts.tscWatch.projectRoot}/b.ts`, content: `function test(x: number, y: number) { return x + y / 5; } export default test;` }; - const tsconfigFile: File = { - path: `${projectRoot}/tsconfig.json`, + const tsconfigFile: ts.tscWatch.File = { + path: `${ts.tscWatch.projectRoot}/tsconfig.json`, content: JSON.stringify({ compilerOptions: { module: "commonjs", @@ -1269,7 +1242,7 @@ export default test;` } }) }; - return createWatchedSystem([aFile, bFile, libFile, tsconfigFile], { currentDirectory: projectRoot }); + return ts.tscWatch.createWatchedSystem([aFile, bFile, ts.tscWatch.libFile, tsconfigFile], { currentDirectory: ts.tscWatch.projectRoot }); }, changes: [ changeParameterTypeOfBFile("x", "string"), @@ -1279,48 +1252,48 @@ export default test;` ] }); - verifyTscWatch({ + ts.tscWatch.verifyTscWatch({ scenario, subScenario: "updates errors when strictNullChecks changes", commandLineArgs: ["-w"], sys: () => { - const aFile: File = { - path: `${projectRoot}/a.ts`, + const aFile: ts.tscWatch.File = { + path: `${ts.tscWatch.projectRoot}/a.ts`, content: `declare function foo(): null | { hello: any }; foo().hello` }; - const config: File = { - path: `${projectRoot}/tsconfig.json`, + const config: ts.tscWatch.File = { + path: `${ts.tscWatch.projectRoot}/tsconfig.json`, content: JSON.stringify({ compilerOptions: {} }) }; - return createWatchedSystem([aFile, config, libFile], { currentDirectory: projectRoot }); + return ts.tscWatch.createWatchedSystem([aFile, config, ts.tscWatch.libFile], { currentDirectory: ts.tscWatch.projectRoot }); }, changes: [ { caption: "Enable strict null checks", - change: sys => sys.writeFile(`${projectRoot}/tsconfig.json`, JSON.stringify({ compilerOptions: { strictNullChecks: true } })), - timeouts: runQueuedTimeoutCallbacks, + change: sys => sys.writeFile(`${ts.tscWatch.projectRoot}/tsconfig.json`, JSON.stringify({ compilerOptions: { strictNullChecks: true } })), + timeouts: ts.tscWatch.runQueuedTimeoutCallbacks, }, { caption: "Set always strict false", - change: sys => sys.writeFile(`${projectRoot}/tsconfig.json`, JSON.stringify({ compilerOptions: { strict: true, alwaysStrict: false } })), // Avoid changing 'alwaysStrict' or must re-bind - timeouts: runQueuedTimeoutCallbacks, + change: sys => sys.writeFile(`${ts.tscWatch.projectRoot}/tsconfig.json`, JSON.stringify({ compilerOptions: { strict: true, alwaysStrict: false } })), + timeouts: ts.tscWatch.runQueuedTimeoutCallbacks, }, { caption: "Disable strict", - change: sys => sys.writeFile(`${projectRoot}/tsconfig.json`, JSON.stringify({ compilerOptions: {} })), - timeouts: runQueuedTimeoutCallbacks, + change: sys => sys.writeFile(`${ts.tscWatch.projectRoot}/tsconfig.json`, JSON.stringify({ compilerOptions: {} })), + timeouts: ts.tscWatch.runQueuedTimeoutCallbacks, }, ] }); - verifyTscWatch({ + ts.tscWatch.verifyTscWatch({ scenario, subScenario: "updates errors when noErrorTruncation changes", commandLineArgs: ["-w"], sys: () => { - const aFile: File = { - path: `${projectRoot}/a.ts`, + const aFile: ts.tscWatch.File = { + path: `${ts.tscWatch.projectRoot}/a.ts`, content: `declare var v: { reallyLongPropertyName1: string | number | boolean | object | symbol | bigint; reallyLongPropertyName2: string | number | boolean | object | symbol | bigint; @@ -1332,172 +1305,172 @@ foo().hello` }; v === 'foo';` }; - const config: File = { - path: `${projectRoot}/tsconfig.json`, + const config: ts.tscWatch.File = { + path: `${ts.tscWatch.projectRoot}/tsconfig.json`, content: JSON.stringify({ compilerOptions: {} }) }; - return createWatchedSystem([aFile, config, libFile], { currentDirectory: projectRoot }); + return ts.tscWatch.createWatchedSystem([aFile, config, ts.tscWatch.libFile], { currentDirectory: ts.tscWatch.projectRoot }); }, changes: [ { caption: "Enable noErrorTruncation", - change: sys => sys.writeFile(`${projectRoot}/tsconfig.json`, JSON.stringify({ compilerOptions: { noErrorTruncation: true } })), - timeouts: runQueuedTimeoutCallbacks, + change: sys => sys.writeFile(`${ts.tscWatch.projectRoot}/tsconfig.json`, JSON.stringify({ compilerOptions: { noErrorTruncation: true } })), + timeouts: ts.tscWatch.runQueuedTimeoutCallbacks, }, ] }); - verifyTscWatch({ + ts.tscWatch.verifyTscWatch({ scenario, subScenario: "updates diagnostics and emit when useDefineForClassFields changes", commandLineArgs: ["-w"], sys: () => { - const aFile: File = { + const aFile: ts.tscWatch.File = { path: `/a.ts`, content: `class C { get prop() { return 1; } } class D extends C { prop = 1; }` }; - const config: File = { + const config: ts.tscWatch.File = { path: `/tsconfig.json`, content: JSON.stringify({ compilerOptions: { target: "es6" } }) }; - return createWatchedSystem([aFile, config, libFile]); + return ts.tscWatch.createWatchedSystem([aFile, config, ts.tscWatch.libFile]); }, changes: [ { caption: "Enable useDefineForClassFields", change: sys => sys.writeFile(`/tsconfig.json`, JSON.stringify({ compilerOptions: { target: "es6", useDefineForClassFields: true } })), - timeouts: runQueuedTimeoutCallbacks, + timeouts: ts.tscWatch.runQueuedTimeoutCallbacks, }, ] }); - verifyTscWatch({ + ts.tscWatch.verifyTscWatch({ scenario, subScenario: "updates errors and emit when importsNotUsedAsValues changes", commandLineArgs: ["-w"], sys: () => { - const aFile: File = { - path: `${projectRoot}/a.ts`, + const aFile: ts.tscWatch.File = { + path: `${ts.tscWatch.projectRoot}/a.ts`, content: `export class C {}` }; - const bFile: File = { - path: `${projectRoot}/b.ts`, + const bFile: ts.tscWatch.File = { + path: `${ts.tscWatch.projectRoot}/b.ts`, content: `import {C} from './a'; export function f(p: C) { return p; }` }; - const config: File = { - path: `${projectRoot}/tsconfig.json`, + const config: ts.tscWatch.File = { + path: `${ts.tscWatch.projectRoot}/tsconfig.json`, content: JSON.stringify({ compilerOptions: {} }) }; - return createWatchedSystem([aFile, bFile, config, libFile], { currentDirectory: projectRoot }); + return ts.tscWatch.createWatchedSystem([aFile, bFile, config, ts.tscWatch.libFile], { currentDirectory: ts.tscWatch.projectRoot }); }, changes: [ { caption: 'Set to "remove"', - change: sys => sys.writeFile(`${projectRoot}/tsconfig.json`, JSON.stringify({ compilerOptions: { importsNotUsedAsValues: "remove" } })), - timeouts: runQueuedTimeoutCallbacks, + change: sys => sys.writeFile(`${ts.tscWatch.projectRoot}/tsconfig.json`, JSON.stringify({ compilerOptions: { importsNotUsedAsValues: "remove" } })), + timeouts: ts.tscWatch.runQueuedTimeoutCallbacks, }, { caption: 'Set to "error"', - change: sys => sys.writeFile(`${projectRoot}/tsconfig.json`, JSON.stringify({ compilerOptions: { importsNotUsedAsValues: "error" } })), - timeouts: runQueuedTimeoutCallbacks, + change: sys => sys.writeFile(`${ts.tscWatch.projectRoot}/tsconfig.json`, JSON.stringify({ compilerOptions: { importsNotUsedAsValues: "error" } })), + timeouts: ts.tscWatch.runQueuedTimeoutCallbacks, }, { caption: 'Set to "preserve"', - change: sys => sys.writeFile(`${projectRoot}/tsconfig.json`, JSON.stringify({ compilerOptions: { importsNotUsedAsValues: "preserve" } })), - timeouts: runQueuedTimeoutCallbacks, + change: sys => sys.writeFile(`${ts.tscWatch.projectRoot}/tsconfig.json`, JSON.stringify({ compilerOptions: { importsNotUsedAsValues: "preserve" } })), + timeouts: ts.tscWatch.runQueuedTimeoutCallbacks, }, ] }); - verifyTscWatch({ + ts.tscWatch.verifyTscWatch({ scenario, subScenario: "updates errors when forceConsistentCasingInFileNames changes", commandLineArgs: ["-w"], sys: () => { - const aFile: File = { + const aFile: ts.tscWatch.File = { path: `/a.ts`, content: `export class C {}` }; - const bFile: File = { + const bFile: ts.tscWatch.File = { path: `/b.ts`, content: `import {C} from './a'; import * as A from './A';` }; - const config: File = { + const config: ts.tscWatch.File = { path: `/tsconfig.json`, content: JSON.stringify({ compilerOptions: {} }) }; - return createWatchedSystem([aFile, bFile, config, libFile], { useCaseSensitiveFileNames: false }); + return ts.tscWatch.createWatchedSystem([aFile, bFile, config, ts.tscWatch.libFile], { useCaseSensitiveFileNames: false }); }, changes: [ { caption: "Enable forceConsistentCasingInFileNames", change: sys => sys.writeFile(`/tsconfig.json`, JSON.stringify({ compilerOptions: { forceConsistentCasingInFileNames: true } })), - timeouts: runQueuedTimeoutCallbacks, + timeouts: ts.tscWatch.runQueuedTimeoutCallbacks, }, ] }); - verifyTscWatch({ + ts.tscWatch.verifyTscWatch({ scenario, subScenario: "updates moduleResolution when resolveJsonModule changes", commandLineArgs: ["-w"], sys: () => { - const aFile: File = { - path: `${projectRoot}/a.ts`, + const aFile: ts.tscWatch.File = { + path: `${ts.tscWatch.projectRoot}/a.ts`, content: `import * as data from './data.json'` }; - const jsonFile: File = { - path: `${projectRoot}/data.json`, + const jsonFile: ts.tscWatch.File = { + path: `${ts.tscWatch.projectRoot}/data.json`, content: `{ "foo": 1 }` }; - const config: File = { - path: `${projectRoot}/tsconfig.json`, + const config: ts.tscWatch.File = { + path: `${ts.tscWatch.projectRoot}/tsconfig.json`, content: JSON.stringify({ compilerOptions: { moduleResolution: "node" } }) }; - return createWatchedSystem([aFile, jsonFile, config, libFile], { currentDirectory: projectRoot }); + return ts.tscWatch.createWatchedSystem([aFile, jsonFile, config, ts.tscWatch.libFile], { currentDirectory: ts.tscWatch.projectRoot }); }, changes: [ { caption: "Enable resolveJsonModule", - change: sys => sys.writeFile(`${projectRoot}/tsconfig.json`, JSON.stringify({ compilerOptions: { moduleResolution: "node", resolveJsonModule: true } })), - timeouts: runQueuedTimeoutCallbacks, + change: sys => sys.writeFile(`${ts.tscWatch.projectRoot}/tsconfig.json`, JSON.stringify({ compilerOptions: { moduleResolution: "node", resolveJsonModule: true } })), + timeouts: ts.tscWatch.runQueuedTimeoutCallbacks, }, ] }); - verifyTscWatch({ + ts.tscWatch.verifyTscWatch({ scenario, subScenario: "updates errors when ambient modules of program changes", commandLineArgs: ["-w"], sys: () => { - const aFile: File = { - path: `${projectRoot}/a.ts`, + const aFile: ts.tscWatch.File = { + path: `${ts.tscWatch.projectRoot}/a.ts`, content: `declare module 'a' { type foo = number; }` }; - const config: File = { - path: `${projectRoot}/tsconfig.json`, + const config: ts.tscWatch.File = { + path: `${ts.tscWatch.projectRoot}/tsconfig.json`, content: "{}" }; - return createWatchedSystem([aFile, config, libFile], { currentDirectory: projectRoot }); + return ts.tscWatch.createWatchedSystem([aFile, config, ts.tscWatch.libFile], { currentDirectory: ts.tscWatch.projectRoot }); }, changes: [ { caption: "Create b.ts with same content", // Create bts with same file contents - change: sys => sys.writeFile(`${projectRoot}/b.ts`, `declare module 'a' { + change: sys => sys.writeFile(`${ts.tscWatch.projectRoot}/b.ts`, `declare module 'a' { type foo = number; }`), - timeouts: runQueuedTimeoutCallbacks, + timeouts: ts.tscWatch.runQueuedTimeoutCallbacks, }, { caption: "Delete b.ts", - change: sys => sys.deleteFile(`${projectRoot}/b.ts`), - timeouts: runQueuedTimeoutCallbacks, + change: sys => sys.deleteFile(`${ts.tscWatch.projectRoot}/b.ts`), + timeouts: ts.tscWatch.runQueuedTimeoutCallbacks, }, ] }); @@ -1508,44 +1481,44 @@ export function f(p: C) { return p; }` ${field}: boolean; }`; - const libFileWithDocument: File = { - path: libFile.path, - content: `${libFile.content} + const libFileWithDocument: ts.tscWatch.File = { + path: ts.tscWatch.libFile.path, + content: `${ts.tscWatch.libFile.content} interface Document { readonly ${field}: boolean; }` }; - function verifyLibFileErrorsWith(subScenario: string, aFile: File) { + function verifyLibFileErrorsWith(subScenario: string, aFile: ts.tscWatch.File) { function verifyLibErrors(subScenario: string, commandLineOptions: readonly string[]) { - verifyTscWatch({ + ts.tscWatch.verifyTscWatch({ scenario, subScenario: `updates errors in lib file/${subScenario}`, commandLineArgs: ["-w", aFile.path, ...commandLineOptions], - sys: () => createWatchedSystem([aFile, libFileWithDocument], { currentDirectory: projectRoot }), + sys: () => ts.tscWatch.createWatchedSystem([aFile, libFileWithDocument], { currentDirectory: ts.tscWatch.projectRoot }), changes: [ { caption: "Remove document declaration from file", change: sys => sys.writeFile(aFile.path, aFile.content.replace(fieldWithoutReadonly, "var x: string;")), - timeouts: runQueuedTimeoutCallbacks, + timeouts: ts.tscWatch.runQueuedTimeoutCallbacks, }, { caption: "Rever the file to contain document declaration", change: sys => sys.writeFile(aFile.path, aFile.content), - timeouts: runQueuedTimeoutCallbacks, + timeouts: ts.tscWatch.runQueuedTimeoutCallbacks, }, ] }); } - verifyLibErrors(`${subScenario}/with default options`, emptyArray); + verifyLibErrors(`${subScenario}/with default options`, ts.emptyArray); verifyLibErrors(`${subScenario}/with skipLibCheck`, ["--skipLibCheck"]); verifyLibErrors(`${subScenario}/with skipDefaultLibCheck`, ["--skipDefaultLibCheck"]); } describe("when non module file changes", () => { - const aFile: File = { - path: `${projectRoot}/a.ts`, + const aFile: ts.tscWatch.File = { + path: `${ts.tscWatch.projectRoot}/a.ts`, content: `${fieldWithoutReadonly} var y: number;` }; @@ -1553,8 +1526,8 @@ var y: number;` }); describe("when module file with global definitions changes", () => { - const aFile: File = { - path: `${projectRoot}/a.ts`, + const aFile: ts.tscWatch.File = { + path: `${ts.tscWatch.projectRoot}/a.ts`, content: `export {} declare global { ${fieldWithoutReadonly} @@ -1565,45 +1538,45 @@ var y: number; }); }); - function changeWhenLibCheckChanges(compilerOptions: CompilerOptions): TscWatchCompileChange { + function changeWhenLibCheckChanges(compilerOptions: ts.CompilerOptions): ts.tscWatch.TscWatchCompileChange { const configFileContent = JSON.stringify({ compilerOptions }); return { caption: `Changing config to ${configFileContent}`, - change: sys => sys.writeFile(`${projectRoot}/tsconfig.json`, configFileContent), - timeouts: runQueuedTimeoutCallbacks, + change: sys => sys.writeFile(`${ts.tscWatch.projectRoot}/tsconfig.json`, configFileContent), + timeouts: ts.tscWatch.runQueuedTimeoutCallbacks, }; } - verifyTscWatch({ + ts.tscWatch.verifyTscWatch({ scenario, subScenario: "when skipLibCheck and skipDefaultLibCheck changes", commandLineArgs: ["-w"], sys: () => { const field = "fullscreen"; - const aFile: File = { - path: `${projectRoot}/a.ts`, + const aFile: ts.tscWatch.File = { + path: `${ts.tscWatch.projectRoot}/a.ts`, content: `interface Document { ${field}: boolean; }` }; - const bFile: File = { - path: `${projectRoot}/b.d.ts`, + const bFile: ts.tscWatch.File = { + path: `${ts.tscWatch.projectRoot}/b.d.ts`, content: `interface Document { ${field}: boolean; }` }; - const libFileWithDocument: File = { - path: libFile.path, - content: `${libFile.content} + const libFileWithDocument: ts.tscWatch.File = { + path: ts.tscWatch.libFile.path, + content: `${ts.tscWatch.libFile.content} interface Document { readonly ${field}: boolean; }` }; - const configFile: File = { - path: `${projectRoot}/tsconfig.json`, + const configFile: ts.tscWatch.File = { + path: `${ts.tscWatch.projectRoot}/tsconfig.json`, content: "{}" }; - return createWatchedSystem([aFile, bFile, configFile, libFileWithDocument], { currentDirectory: projectRoot }); + return ts.tscWatch.createWatchedSystem([aFile, bFile, configFile, libFileWithDocument], { currentDirectory: ts.tscWatch.projectRoot }); }, changes: [ changeWhenLibCheckChanges({ skipLibCheck: true }), @@ -1615,54 +1588,54 @@ interface Document { ] }); - verifyTscWatch({ + ts.tscWatch.verifyTscWatch({ scenario, subScenario: "reports errors correctly with isolatedModules", commandLineArgs: ["-w"], sys: () => { - const aFile: File = { - path: `${projectRoot}/a.ts`, + const aFile: ts.tscWatch.File = { + path: `${ts.tscWatch.projectRoot}/a.ts`, content: `export const a: string = "";` }; - const bFile: File = { - path: `${projectRoot}/b.ts`, + const bFile: ts.tscWatch.File = { + path: `${ts.tscWatch.projectRoot}/b.ts`, content: `import { a } from "./a"; const b: string = a;` }; - const configFile: File = { - path: `${projectRoot}/tsconfig.json`, + const configFile: ts.tscWatch.File = { + path: `${ts.tscWatch.projectRoot}/tsconfig.json`, content: JSON.stringify({ compilerOptions: { isolatedModules: true } }) }; - return createWatchedSystem([aFile, bFile, configFile, libFile], { currentDirectory: projectRoot }); + return ts.tscWatch.createWatchedSystem([aFile, bFile, configFile, ts.tscWatch.libFile], { currentDirectory: ts.tscWatch.projectRoot }); }, changes: [ { caption: "Change shape of a", - change: sys => sys.writeFile(`${projectRoot}/a.ts`, `export const a: number = 1`), - timeouts: runQueuedTimeoutCallbacks, + change: sys => sys.writeFile(`${ts.tscWatch.projectRoot}/a.ts`, `export const a: number = 1`), + timeouts: ts.tscWatch.runQueuedTimeoutCallbacks, }, ] }); - verifyTscWatch({ + ts.tscWatch.verifyTscWatch({ scenario, subScenario: "reports errors correctly with file not in rootDir", commandLineArgs: ["-w"], sys: () => { - const aFile: File = { - path: `${projectRoot}/a.ts`, + const aFile: ts.tscWatch.File = { + path: `${ts.tscWatch.projectRoot}/a.ts`, content: `import { x } from "../b";` }; - const bFile: File = { + const bFile: ts.tscWatch.File = { path: `/user/username/projects/b.ts`, content: `export const x = 10;` }; - const configFile: File = { - path: `${projectRoot}/tsconfig.json`, + const configFile: ts.tscWatch.File = { + path: `${ts.tscWatch.projectRoot}/tsconfig.json`, content: JSON.stringify({ compilerOptions: { rootDir: ".", @@ -1670,53 +1643,53 @@ const b: string = a;` } }) }; - return createWatchedSystem([aFile, bFile, configFile, libFile], { currentDirectory: projectRoot }); + return ts.tscWatch.createWatchedSystem([aFile, bFile, configFile, ts.tscWatch.libFile], { currentDirectory: ts.tscWatch.projectRoot }); }, changes: [ { caption: "Make changes to file a", - change: sys => sys.writeFile(`${projectRoot}/a.ts`, ` + change: sys => sys.writeFile(`${ts.tscWatch.projectRoot}/a.ts`, ` import { x } from "../b";`), - timeouts: runQueuedTimeoutCallbacks, + timeouts: ts.tscWatch.runQueuedTimeoutCallbacks, }, ] }); - verifyTscWatch({ + ts.tscWatch.verifyTscWatch({ scenario, subScenario: "updates emit on jsx option change", commandLineArgs: ["-w"], sys: () => { - const index: File = { - path: `${projectRoot}/index.tsx`, + const index: ts.tscWatch.File = { + path: `${ts.tscWatch.projectRoot}/index.tsx`, content: `declare var React: any;\nconst d =
;` }; - const configFile: File = { - path: `${projectRoot}/tsconfig.json`, + const configFile: ts.tscWatch.File = { + path: `${ts.tscWatch.projectRoot}/tsconfig.json`, content: JSON.stringify({ compilerOptions: { jsx: "preserve" } }) }; - return createWatchedSystem([index, configFile, libFile], { currentDirectory: projectRoot }); + return ts.tscWatch.createWatchedSystem([index, configFile, ts.tscWatch.libFile], { currentDirectory: ts.tscWatch.projectRoot }); }, changes: [ { caption: "Update 'jsx' to 'react'", - change: sys => sys.writeFile(`${projectRoot}/tsconfig.json`, '{ "compilerOptions": { "jsx": "react" } }'), - timeouts: runQueuedTimeoutCallbacks, + change: sys => sys.writeFile(`${ts.tscWatch.projectRoot}/tsconfig.json`, '{ "compilerOptions": { "jsx": "react" } }'), + timeouts: ts.tscWatch.runQueuedTimeoutCallbacks, }, ] }); - verifyTscWatch({ + ts.tscWatch.verifyTscWatch({ scenario, subScenario: "extended source files are watched", commandLineArgs: ["-w", "-p", configFilePath], sys: () => { - const firstExtendedConfigFile: File = { + const firstExtendedConfigFile: ts.tscWatch.File = { path: "/a/b/first.tsconfig.json", content: JSON.stringify({ compilerOptions: { @@ -1724,21 +1697,24 @@ import { x } from "../b";`), } }) }; - const secondExtendedConfigFile: File = { + const secondExtendedConfigFile: ts.tscWatch.File = { path: "/a/b/second.tsconfig.json", content: JSON.stringify({ extends: "./first.tsconfig.json" }) }; - const configFile: File = { + const configFile: ts.tscWatch.File = { path: configFilePath, content: JSON.stringify({ compilerOptions: {}, - files: [commonFile1.path, commonFile2.path] + files: [ts.tscWatch.commonFile1.path, ts.tscWatch.commonFile2.path] }) }; - return createWatchedSystem([ - libFile, commonFile1, commonFile2, configFile, firstExtendedConfigFile, secondExtendedConfigFile + return ts.tscWatch.createWatchedSystem([ + ts.tscWatch.libFile, + ts.tscWatch.commonFile1, + ts.tscWatch.commonFile2, + configFile, firstExtendedConfigFile, secondExtendedConfigFile ]); }, changes: [ @@ -1747,9 +1723,9 @@ import { x } from "../b";`), change: sys => sys.modifyFile(configFilePath, JSON.stringify({ extends: "./second.tsconfig.json", compilerOptions: {}, - files: [commonFile1.path, commonFile2.path] + files: [ts.tscWatch.commonFile1.path, ts.tscWatch.commonFile2.path] })), - timeouts: checkSingleTimeoutQueueLengthAndRun, + timeouts: ts.tscWatch.checkSingleTimeoutQueueLengthAndRun, }, { caption: "Change first extended config", @@ -1758,7 +1734,7 @@ import { x } from "../b";`), strict: false, } })), - timeouts: checkSingleTimeoutQueueLengthAndRun, + timeouts: ts.tscWatch.checkSingleTimeoutQueueLengthAndRun, }, { caption: "Change second extended config", @@ -1768,38 +1744,38 @@ import { x } from "../b";`), strictNullChecks: true, } })), - timeouts: checkSingleTimeoutQueueLengthAndRun, + timeouts: ts.tscWatch.checkSingleTimeoutQueueLengthAndRun, }, { caption: "Change config to stop extending another config", change: sys => sys.modifyFile(configFilePath, JSON.stringify({ compilerOptions: {}, - files: [commonFile1.path, commonFile2.path] + files: [ts.tscWatch.commonFile1.path, ts.tscWatch.commonFile2.path] })), - timeouts: checkSingleTimeoutQueueLengthAndRun, + timeouts: ts.tscWatch.checkSingleTimeoutQueueLengthAndRun, }, ] }); - verifyTscWatch({ + ts.tscWatch.verifyTscWatch({ scenario, subScenario: "when creating new file in symlinked folder", commandLineArgs: ["-w", "-p", ".", "--extendedDiagnostics"], sys: () => { - const module1: File = { - path: `${projectRoot}/client/folder1/module1.ts`, + const module1: ts.tscWatch.File = { + path: `${ts.tscWatch.projectRoot}/client/folder1/module1.ts`, content: `export class Module1Class { }` }; - const module2: File = { - path: `${projectRoot}/folder2/module2.ts`, + const module2: ts.tscWatch.File = { + path: `${ts.tscWatch.projectRoot}/folder2/module2.ts`, content: `import * as M from "folder1/module1";` }; - const symlink: SymLink = { - path: `${projectRoot}/client/linktofolder2`, - symLink: `${projectRoot}/folder2`, + const symlink: ts.tscWatch.SymLink = { + path: `${ts.tscWatch.projectRoot}/client/linktofolder2`, + symLink: `${ts.tscWatch.projectRoot}/folder2`, }; - const config: File = { - path: `${projectRoot}/tsconfig.json`, + const config: ts.tscWatch.File = { + path: `${ts.tscWatch.projectRoot}/tsconfig.json`, content: JSON.stringify({ compilerOptions: { baseUrl: "client", @@ -1808,24 +1784,24 @@ import { x } from "../b";`), include: ["client/**/*", "folder2"] }) }; - return createWatchedSystem([module1, module2, symlink, config, libFile], { currentDirectory: projectRoot }); + return ts.tscWatch.createWatchedSystem([module1, module2, symlink, config, ts.tscWatch.libFile], { currentDirectory: ts.tscWatch.projectRoot }); }, changes: [ { caption: "Add module3 to folder2", - change: sys => sys.writeFile(`${projectRoot}/client/linktofolder2/module3.ts`, `import * as M from "folder1/module1";`), - timeouts: checkSingleTimeoutQueueLengthAndRun, + change: sys => sys.writeFile(`${ts.tscWatch.projectRoot}/client/linktofolder2/module3.ts`, `import * as M from "folder1/module1";`), + timeouts: ts.tscWatch.checkSingleTimeoutQueueLengthAndRun, }, ] }); - verifyTscWatch({ + ts.tscWatch.verifyTscWatch({ scenario, subScenario: "when new file is added to the referenced project", - commandLineArgs: ["-w", "-p", `${projectRoot}/projects/project2/tsconfig.json`, "--extendedDiagnostics"], + commandLineArgs: ["-w", "-p", `${ts.tscWatch.projectRoot}/projects/project2/tsconfig.json`, "--extendedDiagnostics"], sys: () => { - const config1: File = { - path: `${projectRoot}/projects/project1/tsconfig.json`, + const config1: ts.tscWatch.File = { + path: `${ts.tscWatch.projectRoot}/projects/project1/tsconfig.json`, content: JSON.stringify({ compilerOptions: { module: "none", @@ -1834,17 +1810,17 @@ import { x } from "../b";`), exclude: ["temp"] }) }; - const class1: File = { - path: `${projectRoot}/projects/project1/class1.ts`, + const class1: ts.tscWatch.File = { + path: `${ts.tscWatch.projectRoot}/projects/project1/class1.ts`, content: `class class1 {}` }; // Built file - const class1Dt: File = { - path: `${projectRoot}/projects/project1/class1.d.ts`, + const class1Dt: ts.tscWatch.File = { + path: `${ts.tscWatch.projectRoot}/projects/project1/class1.d.ts`, content: `declare class class1 {}` }; - const config2: File = { - path: `${projectRoot}/projects/project2/tsconfig.json`, + const config2: ts.tscWatch.File = { + path: `${ts.tscWatch.projectRoot}/projects/project2/tsconfig.json`, content: JSON.stringify({ compilerOptions: { module: "none", @@ -1855,61 +1831,61 @@ import { x } from "../b";`), ] }) }; - const class2: File = { - path: `${projectRoot}/projects/project2/class2.ts`, + const class2: ts.tscWatch.File = { + path: `${ts.tscWatch.projectRoot}/projects/project2/class2.ts`, content: `class class2 {}` }; - return createWatchedSystem([config1, class1, config2, class2, libFile, class1Dt]); + return ts.tscWatch.createWatchedSystem([config1, class1, config2, class2, ts.tscWatch.libFile, class1Dt]); }, changes: [ { caption: "Add class3 to project1", - change: sys => sys.writeFile(`${projectRoot}/projects/project1/class3.ts`, `class class3 {}`), - timeouts: checkSingleTimeoutQueueLengthAndRun, + change: sys => sys.writeFile(`${ts.tscWatch.projectRoot}/projects/project1/class3.ts`, `class class3 {}`), + timeouts: ts.tscWatch.checkSingleTimeoutQueueLengthAndRun, }, { caption: "Add output of class3", - change: sys => sys.writeFile(`${projectRoot}/projects/project1/class3.d.ts`, `declare class class3 {}`), - timeouts: checkSingleTimeoutQueueLengthAndRun, + change: sys => sys.writeFile(`${ts.tscWatch.projectRoot}/projects/project1/class3.d.ts`, `declare class class3 {}`), + timeouts: ts.tscWatch.checkSingleTimeoutQueueLengthAndRun, }, { caption: "Add excluded file to project1", - change: sys => sys.ensureFileOrFolder({ path: `${projectRoot}/projects/project1/temp/file.d.ts`, content: `declare class file {}` }), + change: sys => sys.ensureFileOrFolder({ path: `${ts.tscWatch.projectRoot}/projects/project1/temp/file.d.ts`, content: `declare class file {}` }), timeouts: sys => sys.checkTimeoutQueueLength(0), }, { caption: "Delete output of class3", - change: sys => sys.deleteFile(`${projectRoot}/projects/project1/class3.d.ts`), - timeouts: checkSingleTimeoutQueueLengthAndRun, + change: sys => sys.deleteFile(`${ts.tscWatch.projectRoot}/projects/project1/class3.d.ts`), + timeouts: ts.tscWatch.checkSingleTimeoutQueueLengthAndRun, }, { caption: "Add output of class3", - change: sys => sys.writeFile(`${projectRoot}/projects/project1/class3.d.ts`, `declare class class3 {}`), - timeouts: checkSingleTimeoutQueueLengthAndRun, + change: sys => sys.writeFile(`${ts.tscWatch.projectRoot}/projects/project1/class3.d.ts`, `declare class class3 {}`), + timeouts: ts.tscWatch.checkSingleTimeoutQueueLengthAndRun, }, ] }); - verifyTscWatch({ + ts.tscWatch.verifyTscWatch({ scenario, subScenario: "when creating extensionless file", commandLineArgs: ["-w", "-p", ".", "--extendedDiagnostics"], sys: () => { - const module1: File = { - path: `${projectRoot}/index.ts`, + const module1: ts.tscWatch.File = { + path: `${ts.tscWatch.projectRoot}/index.ts`, content: `` }; - const config: File = { - path: `${projectRoot}/tsconfig.json`, + const config: ts.tscWatch.File = { + path: `${ts.tscWatch.projectRoot}/tsconfig.json`, content: `{}` }; - return createWatchedSystem([module1, config, libFile], { currentDirectory: projectRoot }); + return ts.tscWatch.createWatchedSystem([module1, config, ts.tscWatch.libFile], { currentDirectory: ts.tscWatch.projectRoot }); }, changes: [ { caption: "Create foo in project root", - change: sys => sys.writeFile(`${projectRoot}/foo`, ``), - timeouts: checkSingleTimeoutQueueLengthAndRun, + change: sys => sys.writeFile(`${ts.tscWatch.projectRoot}/foo`, ``), + timeouts: ts.tscWatch.checkSingleTimeoutQueueLengthAndRun, }, ] }); diff --git a/src/testRunner/unittests/tscWatch/projectsWithReferences.ts b/src/testRunner/unittests/tscWatch/projectsWithReferences.ts index 83b65de1bda2d..6dd44cd87af83 100644 --- a/src/testRunner/unittests/tscWatch/projectsWithReferences.ts +++ b/src/testRunner/unittests/tscWatch/projectsWithReferences.ts @@ -1,193 +1,179 @@ namespace ts.tscWatch { describe("unittests:: tsc-watch:: projects with references: invoking when references are already built", () => { - verifyTscWatch({ + ts.tscWatch.verifyTscWatch({ scenario: "projectsWithReferences", subScenario: "on sample project", - sys: () => createSystemWithSolutionBuild( - ["tests"], - [ - libFile, - TestFSWithWatch.getTsBuildProjectFile("sample1", "core/tsconfig.json"), - TestFSWithWatch.getTsBuildProjectFile("sample1", "core/index.ts"), - TestFSWithWatch.getTsBuildProjectFile("sample1", "core/anotherModule.ts"), - TestFSWithWatch.getTsBuildProjectFile("sample1", "core/some_decl.d.ts"), - TestFSWithWatch.getTsBuildProjectFile("sample1", "logic/tsconfig.json"), - TestFSWithWatch.getTsBuildProjectFile("sample1", "logic/index.ts"), - TestFSWithWatch.getTsBuildProjectFile("sample1", "tests/tsconfig.json"), - TestFSWithWatch.getTsBuildProjectFile("sample1", "tests/index.ts"), - ], - { currentDirectory: `${TestFSWithWatch.tsbuildProjectsLocation}/sample1` } - ), + sys: () => ts.tscWatch.createSystemWithSolutionBuild(["tests"], [ + ts.tscWatch.libFile, + ts.TestFSWithWatch.getTsBuildProjectFile("sample1", "core/tsconfig.json"), + ts.TestFSWithWatch.getTsBuildProjectFile("sample1", "core/index.ts"), + ts.TestFSWithWatch.getTsBuildProjectFile("sample1", "core/anotherModule.ts"), + ts.TestFSWithWatch.getTsBuildProjectFile("sample1", "core/some_decl.d.ts"), + ts.TestFSWithWatch.getTsBuildProjectFile("sample1", "logic/tsconfig.json"), + ts.TestFSWithWatch.getTsBuildProjectFile("sample1", "logic/index.ts"), + ts.TestFSWithWatch.getTsBuildProjectFile("sample1", "tests/tsconfig.json"), + ts.TestFSWithWatch.getTsBuildProjectFile("sample1", "tests/index.ts"), + ], { currentDirectory: `${ts.TestFSWithWatch.tsbuildProjectsLocation}/sample1` }), commandLineArgs: ["-w", "-p", "tests"], changes: [ { caption: "local edit in logic ts, and build logic", change: sys => { - sys.appendFile(TestFSWithWatch.getTsBuildProjectFilePath("sample1", "logic/index.ts"), `function foo() { }`); - const solutionBuilder = createSolutionBuilder(sys, ["logic"]); + sys.appendFile(ts.TestFSWithWatch.getTsBuildProjectFilePath("sample1", "logic/index.ts"), `function foo() { }`); + const solutionBuilder = ts.tscWatch.createSolutionBuilder(sys, ["logic"]); solutionBuilder.build(); }, // not ideal, but currently because of d.ts but no new file is written // There will be timeout queued even though file contents are same - timeouts: checkSingleTimeoutQueueLengthAndRun + timeouts: ts.tscWatch.checkSingleTimeoutQueueLengthAndRun }, { caption: "non local edit in logic ts, and build logic", change: sys => { - sys.appendFile(TestFSWithWatch.getTsBuildProjectFilePath("sample1", "logic/index.ts"), `export function gfoo() { }`); - const solutionBuilder = createSolutionBuilder(sys, ["logic"]); + sys.appendFile(ts.TestFSWithWatch.getTsBuildProjectFilePath("sample1", "logic/index.ts"), `export function gfoo() { }`); + const solutionBuilder = ts.tscWatch.createSolutionBuilder(sys, ["logic"]); solutionBuilder.build(); }, - timeouts: checkSingleTimeoutQueueLengthAndRun + timeouts: ts.tscWatch.checkSingleTimeoutQueueLengthAndRun }, { caption: "change in project reference config file builds correctly", change: sys => { - sys.writeFile(TestFSWithWatch.getTsBuildProjectFilePath("sample1", "logic/tsconfig.json"), JSON.stringify({ + sys.writeFile(ts.TestFSWithWatch.getTsBuildProjectFilePath("sample1", "logic/tsconfig.json"), JSON.stringify({ compilerOptions: { composite: true, declaration: true, declarationDir: "decls" }, references: [{ path: "../core" }] })); - const solutionBuilder = createSolutionBuilder(sys, ["logic"]); + const solutionBuilder = ts.tscWatch.createSolutionBuilder(sys, ["logic"]); solutionBuilder.build(); }, - timeouts: checkSingleTimeoutQueueLengthAndRun + timeouts: ts.tscWatch.checkSingleTimeoutQueueLengthAndRun }, ], baselineDependencies: true }); - function changeCompilerOpitonsPaths(sys: WatchedSystem, config: string, newPaths: object) { + function changeCompilerOpitonsPaths(sys: ts.tscWatch.WatchedSystem, config: string, newPaths: object) { const configJson = JSON.parse(sys.readFile(config)!); configJson.compilerOptions.paths = newPaths; sys.writeFile(config, JSON.stringify(configJson)); } - verifyTscWatch({ + ts.tscWatch.verifyTscWatch({ scenario: "projectsWithReferences", subScenario: "on transitive references", - sys: () => createSystemWithSolutionBuild( - ["tsconfig.c.json"], - [ - libFile, - TestFSWithWatch.getTsBuildProjectFile("transitiveReferences", "tsconfig.a.json"), - TestFSWithWatch.getTsBuildProjectFile("transitiveReferences", "tsconfig.b.json"), - TestFSWithWatch.getTsBuildProjectFile("transitiveReferences", "tsconfig.c.json"), - TestFSWithWatch.getTsBuildProjectFile("transitiveReferences", "a.ts"), - TestFSWithWatch.getTsBuildProjectFile("transitiveReferences", "b.ts"), - TestFSWithWatch.getTsBuildProjectFile("transitiveReferences", "c.ts"), - TestFSWithWatch.getTsBuildProjectFile("transitiveReferences", "refs/a.d.ts"), - ], - { currentDirectory: `${TestFSWithWatch.tsbuildProjectsLocation}/transitiveReferences` } - ), + sys: () => ts.tscWatch.createSystemWithSolutionBuild(["tsconfig.c.json"], [ + ts.tscWatch.libFile, + ts.TestFSWithWatch.getTsBuildProjectFile("transitiveReferences", "tsconfig.a.json"), + ts.TestFSWithWatch.getTsBuildProjectFile("transitiveReferences", "tsconfig.b.json"), + ts.TestFSWithWatch.getTsBuildProjectFile("transitiveReferences", "tsconfig.c.json"), + ts.TestFSWithWatch.getTsBuildProjectFile("transitiveReferences", "a.ts"), + ts.TestFSWithWatch.getTsBuildProjectFile("transitiveReferences", "b.ts"), + ts.TestFSWithWatch.getTsBuildProjectFile("transitiveReferences", "c.ts"), + ts.TestFSWithWatch.getTsBuildProjectFile("transitiveReferences", "refs/a.d.ts"), + ], { currentDirectory: `${ts.TestFSWithWatch.tsbuildProjectsLocation}/transitiveReferences` }), commandLineArgs: ["-w", "-p", "tsconfig.c.json"], changes: [ { caption: "non local edit b ts, and build b", change: sys => { - sys.appendFile(TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "b.ts"), `export function gfoo() { }`); - const solutionBuilder = createSolutionBuilder(sys, ["tsconfig.b.json"]); + sys.appendFile(ts.TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "b.ts"), `export function gfoo() { }`); + const solutionBuilder = ts.tscWatch.createSolutionBuilder(sys, ["tsconfig.b.json"]); solutionBuilder.build(); }, - timeouts: checkSingleTimeoutQueueLengthAndRun + timeouts: ts.tscWatch.checkSingleTimeoutQueueLengthAndRun }, { caption: "edit on config file", change: sys => { sys.ensureFileOrFolder({ - path: TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "nrefs/a.d.ts"), - content: sys.readFile(TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "refs/a.d.ts"))! + path: ts.TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "nrefs/a.d.ts"), + content: sys.readFile(ts.TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "refs/a.d.ts"))! }); - changeCompilerOpitonsPaths(sys, TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "tsconfig.c.json"), { "@ref/*": ["./nrefs/*"] }); + changeCompilerOpitonsPaths(sys, ts.TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "tsconfig.c.json"), { "@ref/*": ["./nrefs/*"] }); }, - timeouts: checkSingleTimeoutQueueLengthAndRun + timeouts: ts.tscWatch.checkSingleTimeoutQueueLengthAndRun }, { caption: "Revert config file edit", - change: sys => changeCompilerOpitonsPaths(sys, TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "tsconfig.c.json"), { "@ref/*": ["./refs/*"] }), - timeouts: checkSingleTimeoutQueueLengthAndRun + change: sys => changeCompilerOpitonsPaths(sys, ts.TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "tsconfig.c.json"), { "@ref/*": ["./refs/*"] }), + timeouts: ts.tscWatch.checkSingleTimeoutQueueLengthAndRun }, { caption: "edit in referenced config file", - change: sys => changeCompilerOpitonsPaths(sys, TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "tsconfig.b.json"), { "@ref/*": ["./nrefs/*"] }), - timeouts: checkSingleTimeoutQueueLengthAndRun + change: sys => changeCompilerOpitonsPaths(sys, ts.TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "tsconfig.b.json"), { "@ref/*": ["./nrefs/*"] }), + timeouts: ts.tscWatch.checkSingleTimeoutQueueLengthAndRun }, { caption: "Revert referenced config file edit", - change: sys => changeCompilerOpitonsPaths(sys, TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "tsconfig.b.json"), { "@ref/*": ["./refs/*"] }), - timeouts: checkSingleTimeoutQueueLengthAndRun + change: sys => changeCompilerOpitonsPaths(sys, ts.TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "tsconfig.b.json"), { "@ref/*": ["./refs/*"] }), + timeouts: ts.tscWatch.checkSingleTimeoutQueueLengthAndRun }, { caption: "deleting referenced config file", - change: sys => sys.deleteFile(TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "tsconfig.b.json")), - timeouts: checkSingleTimeoutQueueLengthAndRun + change: sys => sys.deleteFile(ts.TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "tsconfig.b.json")), + timeouts: ts.tscWatch.checkSingleTimeoutQueueLengthAndRun }, { caption: "Revert deleting referenced config file", - change: sys => sys.ensureFileOrFolder(TestFSWithWatch.getTsBuildProjectFile("transitiveReferences", "tsconfig.b.json")), - timeouts: checkSingleTimeoutQueueLengthAndRun + change: sys => sys.ensureFileOrFolder(ts.TestFSWithWatch.getTsBuildProjectFile("transitiveReferences", "tsconfig.b.json")), + timeouts: ts.tscWatch.checkSingleTimeoutQueueLengthAndRun }, { caption: "deleting transitively referenced config file", - change: sys => sys.deleteFile(TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "tsconfig.a.json")), - timeouts: checkSingleTimeoutQueueLengthAndRun + change: sys => sys.deleteFile(ts.TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "tsconfig.a.json")), + timeouts: ts.tscWatch.checkSingleTimeoutQueueLengthAndRun }, { caption: "Revert deleting transitively referenced config file", - change: sys => sys.ensureFileOrFolder(TestFSWithWatch.getTsBuildProjectFile("transitiveReferences", "tsconfig.a.json")), - timeouts: checkSingleTimeoutQueueLengthAndRun + change: sys => sys.ensureFileOrFolder(ts.TestFSWithWatch.getTsBuildProjectFile("transitiveReferences", "tsconfig.a.json")), + timeouts: ts.tscWatch.checkSingleTimeoutQueueLengthAndRun }, ], baselineDependencies: true, }); - verifyTscWatch({ + ts.tscWatch.verifyTscWatch({ scenario: "projectsWithReferences", subScenario: "when referenced project uses different module resolution", - sys: () => createSystemWithSolutionBuild( - ["tsconfig.c.json"], - [ - libFile, - TestFSWithWatch.getTsBuildProjectFile("transitiveReferences", "tsconfig.a.json"), + sys: () => ts.tscWatch.createSystemWithSolutionBuild(["tsconfig.c.json"], [ + ts.tscWatch.libFile, + ts.TestFSWithWatch.getTsBuildProjectFile("transitiveReferences", "tsconfig.a.json"), { - path: TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "tsconfig.b.json"), + path: ts.TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "tsconfig.b.json"), content: JSON.stringify({ compilerOptions: { composite: true, moduleResolution: "classic" }, files: ["b.ts"], references: [{ path: "tsconfig.a.json" }] }) }, - TestFSWithWatch.getTsBuildProjectFile("transitiveReferences", "tsconfig.c.json"), - TestFSWithWatch.getTsBuildProjectFile("transitiveReferences", "a.ts"), + ts.TestFSWithWatch.getTsBuildProjectFile("transitiveReferences", "tsconfig.c.json"), + ts.TestFSWithWatch.getTsBuildProjectFile("transitiveReferences", "a.ts"), { - path: TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "b.ts"), + path: ts.TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "b.ts"), content: `import {A} from "a";export const b = new A();` }, - TestFSWithWatch.getTsBuildProjectFile("transitiveReferences", "c.ts"), - TestFSWithWatch.getTsBuildProjectFile("transitiveReferences", "refs/a.d.ts"), - ], - { currentDirectory: `${TestFSWithWatch.tsbuildProjectsLocation}/transitiveReferences` } - ), + ts.TestFSWithWatch.getTsBuildProjectFile("transitiveReferences", "c.ts"), + ts.TestFSWithWatch.getTsBuildProjectFile("transitiveReferences", "refs/a.d.ts"), + ], { currentDirectory: `${ts.TestFSWithWatch.tsbuildProjectsLocation}/transitiveReferences` }), commandLineArgs: ["-w", "-p", "tsconfig.c.json"], - changes: emptyArray, + changes: ts.emptyArray, baselineDependencies: true, }); - verifyTscWatch({ + ts.tscWatch.verifyTscWatch({ scenario: "projectsWithReferences", subScenario: "on transitive references in different folders", - sys: () => createSystemWithSolutionBuild( - ["c"], - [ - libFile, + sys: () => ts.tscWatch.createSystemWithSolutionBuild(["c"], [ + ts.tscWatch.libFile, { - path: TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "a/tsconfig.json"), + path: ts.TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "a/tsconfig.json"), content: JSON.stringify({ compilerOptions: { composite: true }, files: ["index.ts"] }), }, { - path: TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "b/tsconfig.json"), + path: ts.TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "b/tsconfig.json"), content: JSON.stringify({ compilerOptions: { composite: true, baseUrl: "./", paths: { "@ref/*": ["../*"] } }, files: ["index.ts"], @@ -195,7 +181,7 @@ namespace ts.tscWatch { }), }, { - path: TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "c/tsconfig.json"), + path: ts.TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "c/tsconfig.json"), content: JSON.stringify({ compilerOptions: { baseUrl: "./", paths: { "@ref/*": ["../refs/*"] } }, files: ["index.ts"], @@ -203,208 +189,190 @@ namespace ts.tscWatch { }), }, { - path: TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "a/index.ts"), + path: ts.TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "a/index.ts"), content: `export class A {}`, }, { - path: TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "b/index.ts"), + path: ts.TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "b/index.ts"), content: `import {A} from '@ref/a'; export const b = new A();`, }, { - path: TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "c/index.ts"), + path: ts.TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "c/index.ts"), content: `import {b} from '../b'; import {X} from "@ref/a"; b; X;`, }, - TestFSWithWatch.getTsBuildProjectFile("transitiveReferences", "refs/a.d.ts"), - ], - { currentDirectory: `${TestFSWithWatch.tsbuildProjectsLocation}/transitiveReferences` } - ), + ts.TestFSWithWatch.getTsBuildProjectFile("transitiveReferences", "refs/a.d.ts"), + ], { currentDirectory: `${ts.TestFSWithWatch.tsbuildProjectsLocation}/transitiveReferences` }), commandLineArgs: ["-w", "-p", "c"], changes: [ { caption: "non local edit b ts, and build b", change: sys => { - sys.appendFile(TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "b/index.ts"), `export function gfoo() { }`); - const solutionBuilder = createSolutionBuilder(sys, ["b"]); + sys.appendFile(ts.TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "b/index.ts"), `export function gfoo() { }`); + const solutionBuilder = ts.tscWatch.createSolutionBuilder(sys, ["b"]); solutionBuilder.build(); }, - timeouts: checkSingleTimeoutQueueLengthAndRun + timeouts: ts.tscWatch.checkSingleTimeoutQueueLengthAndRun }, { caption: "edit on config file", change: sys => { sys.ensureFileOrFolder({ - path: TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "nrefs/a.d.ts"), - content: sys.readFile(TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "refs/a.d.ts"))! + path: ts.TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "nrefs/a.d.ts"), + content: sys.readFile(ts.TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "refs/a.d.ts"))! }); - changeCompilerOpitonsPaths(sys, TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "c/tsconfig.json"), { "@ref/*": ["../nrefs/*"] }); + changeCompilerOpitonsPaths(sys, ts.TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "c/tsconfig.json"), { "@ref/*": ["../nrefs/*"] }); }, - timeouts: checkSingleTimeoutQueueLengthAndRun + timeouts: ts.tscWatch.checkSingleTimeoutQueueLengthAndRun }, { caption: "Revert config file edit", - change: sys => changeCompilerOpitonsPaths(sys, TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "c/tsconfig.json"), { "@ref/*": ["../refs/*"] }), - timeouts: checkSingleTimeoutQueueLengthAndRun + change: sys => changeCompilerOpitonsPaths(sys, ts.TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "c/tsconfig.json"), { "@ref/*": ["../refs/*"] }), + timeouts: ts.tscWatch.checkSingleTimeoutQueueLengthAndRun }, { caption: "edit in referenced config file", - change: sys => changeCompilerOpitonsPaths(sys, TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "b/tsconfig.json"), { "@ref/*": ["../nrefs/*"] }), - timeouts: checkSingleTimeoutQueueLengthAndRun + change: sys => changeCompilerOpitonsPaths(sys, ts.TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "b/tsconfig.json"), { "@ref/*": ["../nrefs/*"] }), + timeouts: ts.tscWatch.checkSingleTimeoutQueueLengthAndRun }, { caption: "Revert referenced config file edit", - change: sys => changeCompilerOpitonsPaths(sys, TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "b/tsconfig.json"), { "@ref/*": ["../refs/*"] }), - timeouts: checkSingleTimeoutQueueLengthAndRun + change: sys => changeCompilerOpitonsPaths(sys, ts.TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "b/tsconfig.json"), { "@ref/*": ["../refs/*"] }), + timeouts: ts.tscWatch.checkSingleTimeoutQueueLengthAndRun }, { caption: "deleting referenced config file", - change: sys => sys.deleteFile(TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "b/tsconfig.json")), + change: sys => sys.deleteFile(ts.TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "b/tsconfig.json")), timeouts: sys => sys.checkTimeoutQueueLengthAndRun(2) }, { caption: "Revert deleting referenced config file", - change: sys => sys.writeFile( - TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "b/tsconfig.json"), - JSON.stringify({ + change: sys => sys.writeFile(ts.TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "b/tsconfig.json"), JSON.stringify({ compilerOptions: { composite: true, baseUrl: "./", paths: { "@ref/*": ["../*"] } }, files: ["index.ts"], references: [{ path: `../a` }] - }) - ), + })), timeouts: sys => sys.checkTimeoutQueueLengthAndRun(2) }, { caption: "deleting transitively referenced config file", - change: sys => sys.deleteFile(TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "a/tsconfig.json")), + change: sys => sys.deleteFile(ts.TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "a/tsconfig.json")), timeouts: sys => sys.checkTimeoutQueueLengthAndRun(2) }, { caption: "Revert deleting transitively referenced config file", - change: sys => sys.writeFile( - TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "a/tsconfig.json"), - JSON.stringify({ + change: sys => sys.writeFile(ts.TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "a/tsconfig.json"), JSON.stringify({ compilerOptions: { composite: true }, files: ["index.ts"] - }), - ), + })), timeouts: sys => sys.checkTimeoutQueueLengthAndRun(2) }, ], baselineDependencies: true, }); - verifyTscWatch({ + ts.tscWatch.verifyTscWatch({ scenario: "projectsWithReferences", subScenario: "on transitive references in different folders with no files clause", - sys: () => createSystemWithSolutionBuild( - ["c"], - [ - libFile, + sys: () => ts.tscWatch.createSystemWithSolutionBuild(["c"], [ + ts.tscWatch.libFile, { - path: TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "a/tsconfig.json"), + path: ts.TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "a/tsconfig.json"), content: JSON.stringify({ compilerOptions: { composite: true } }), }, { - path: TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "b/tsconfig.json"), + path: ts.TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "b/tsconfig.json"), content: JSON.stringify({ compilerOptions: { composite: true, baseUrl: "./", paths: { "@ref/*": ["../*"] } }, references: [{ path: `../a` }] }), }, { - path: TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "c/tsconfig.json"), + path: ts.TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "c/tsconfig.json"), content: JSON.stringify({ compilerOptions: { baseUrl: "./", paths: { "@ref/*": ["../refs/*"] } }, references: [{ path: `../b` }] }), }, { - path: TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "a/index.ts"), + path: ts.TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "a/index.ts"), content: `export class A {}`, }, { - path: TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "b/index.ts"), + path: ts.TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "b/index.ts"), content: `import {A} from '@ref/a'; export const b = new A();`, }, { - path: TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "c/index.ts"), + path: ts.TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "c/index.ts"), content: `import {b} from '../b'; import {X} from "@ref/a"; b; X;`, }, - TestFSWithWatch.getTsBuildProjectFile("transitiveReferences", "refs/a.d.ts"), - ], - { currentDirectory: `${TestFSWithWatch.tsbuildProjectsLocation}/transitiveReferences` } - ), + ts.TestFSWithWatch.getTsBuildProjectFile("transitiveReferences", "refs/a.d.ts"), + ], { currentDirectory: `${ts.TestFSWithWatch.tsbuildProjectsLocation}/transitiveReferences` }), commandLineArgs: ["-w", "-p", "c"], changes: [ { caption: "non local edit b ts, and build b", change: sys => { - sys.appendFile(TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "b/index.ts"), `export function gfoo() { }`); - const solutionBuilder = createSolutionBuilder(sys, ["b"]); + sys.appendFile(ts.TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "b/index.ts"), `export function gfoo() { }`); + const solutionBuilder = ts.tscWatch.createSolutionBuilder(sys, ["b"]); solutionBuilder.build(); }, - timeouts: checkSingleTimeoutQueueLengthAndRun + timeouts: ts.tscWatch.checkSingleTimeoutQueueLengthAndRun }, { caption: "edit on config file", change: sys => { sys.ensureFileOrFolder({ - path: TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "nrefs/a.d.ts"), - content: sys.readFile(TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "refs/a.d.ts"))! + path: ts.TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "nrefs/a.d.ts"), + content: sys.readFile(ts.TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "refs/a.d.ts"))! }); - changeCompilerOpitonsPaths(sys, TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "c/tsconfig.json"), { "@ref/*": ["../nrefs/*"] }); + changeCompilerOpitonsPaths(sys, ts.TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "c/tsconfig.json"), { "@ref/*": ["../nrefs/*"] }); }, - timeouts: checkSingleTimeoutQueueLengthAndRun + timeouts: ts.tscWatch.checkSingleTimeoutQueueLengthAndRun }, { caption: "Revert config file edit", - change: sys => changeCompilerOpitonsPaths(sys, TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "c/tsconfig.json"), { "@ref/*": ["../refs/*"] }), - timeouts: checkSingleTimeoutQueueLengthAndRun + change: sys => changeCompilerOpitonsPaths(sys, ts.TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "c/tsconfig.json"), { "@ref/*": ["../refs/*"] }), + timeouts: ts.tscWatch.checkSingleTimeoutQueueLengthAndRun }, { caption: "edit in referenced config file", - change: sys => changeCompilerOpitonsPaths(sys, TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "b/tsconfig.json"), { "@ref/*": ["../nrefs/*"] }), - timeouts: checkSingleTimeoutQueueLengthAndRun + change: sys => changeCompilerOpitonsPaths(sys, ts.TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "b/tsconfig.json"), { "@ref/*": ["../nrefs/*"] }), + timeouts: ts.tscWatch.checkSingleTimeoutQueueLengthAndRun }, { caption: "Revert referenced config file edit", - change: sys => changeCompilerOpitonsPaths(sys, TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "b/tsconfig.json"), { "@ref/*": ["../refs/*"] }), - timeouts: checkSingleTimeoutQueueLengthAndRun + change: sys => changeCompilerOpitonsPaths(sys, ts.TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "b/tsconfig.json"), { "@ref/*": ["../refs/*"] }), + timeouts: ts.tscWatch.checkSingleTimeoutQueueLengthAndRun }, { caption: "deleting referenced config file", - change: sys => sys.deleteFile(TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "b/tsconfig.json")), + change: sys => sys.deleteFile(ts.TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "b/tsconfig.json")), timeouts: sys => sys.checkTimeoutQueueLengthAndRun(2) }, { caption: "Revert deleting referenced config file", - change: sys => sys.writeFile( - TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "b/tsconfig.json"), - JSON.stringify({ + change: sys => sys.writeFile(ts.TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "b/tsconfig.json"), JSON.stringify({ compilerOptions: { composite: true, baseUrl: "./", paths: { "@ref/*": ["../*"] } }, references: [{ path: `../a` }] - }) - ), + })), timeouts: sys => sys.checkTimeoutQueueLengthAndRun(2) }, { caption: "deleting transitively referenced config file", - change: sys => sys.deleteFile(TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "a/tsconfig.json")), + change: sys => sys.deleteFile(ts.TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "a/tsconfig.json")), timeouts: sys => sys.checkTimeoutQueueLengthAndRun(2) }, { caption: "Revert deleting transitively referenced config file", - change: sys => sys.writeFile( - TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "a/tsconfig.json"), - JSON.stringify({ compilerOptions: { composite: true } }), - ), + change: sys => sys.writeFile(ts.TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "a/tsconfig.json"), JSON.stringify({ compilerOptions: { composite: true } })), timeouts: sys => sys.checkTimeoutQueueLengthAndRun(2) }, ], diff --git a/src/testRunner/unittests/tscWatch/resolutionCache.ts b/src/testRunner/unittests/tscWatch/resolutionCache.ts index ef923e28d3cae..613e11a835e26 100644 --- a/src/testRunner/unittests/tscWatch/resolutionCache.ts +++ b/src/testRunner/unittests/tscWatch/resolutionCache.ts @@ -11,18 +11,18 @@ namespace ts.tscWatch { content: `foo()` }; - const { sys, baseline, oldSnap, cb, getPrograms } = createBaseline(createWatchedSystem([root, imported, libFile])); - const host = createWatchCompilerHostOfFilesAndCompilerOptionsForBaseline({ + const { sys, baseline, oldSnap, cb, getPrograms } = ts.tscWatch.createBaseline(ts.tscWatch.createWatchedSystem([root, imported, ts.tscWatch.libFile])); + const host = ts.tscWatch.createWatchCompilerHostOfFilesAndCompilerOptionsForBaseline({ rootFiles: [root.path], system: sys, - options: { module: ModuleKind.AMD }, + options: { module: ts.ModuleKind.AMD }, cb, watchOptions: undefined }); const originalFileExists = host.fileExists; - const watch = createWatchProgram(host); + const watch = ts.createWatchProgram(host); let fileExistsIsCalled = false; - runWatchBaseline({ + ts.tscWatch.runWatchBaseline({ scenario: "resolutionCache", subScenario: "caching works", commandLineArgs: ["--w", root.path], @@ -35,11 +35,11 @@ namespace ts.tscWatch { caption: "Adding text doesnt re-resole the imports", change: sys => { // patch fileExists to make sure that disk is not touched - host.fileExists = notImplemented; + host.fileExists = ts.notImplemented; sys.writeFile(root.path, `import {x} from "f1" var x: string = 1;`); }, - timeouts: runQueuedTimeoutCallbacks + timeouts: ts.tscWatch.runQueuedTimeoutCallbacks }, { caption: "Resolves f2", @@ -94,11 +94,11 @@ namespace ts.tscWatch { content: `export const y = 1;` }; - const { sys, baseline, oldSnap, cb, getPrograms } = createBaseline(createWatchedSystem([root, libFile])); - const host = createWatchCompilerHostOfFilesAndCompilerOptionsForBaseline({ + const { sys, baseline, oldSnap, cb, getPrograms } = ts.tscWatch.createBaseline(ts.tscWatch.createWatchedSystem([root, ts.tscWatch.libFile])); + const host = ts.tscWatch.createWatchCompilerHostOfFilesAndCompilerOptionsForBaseline({ rootFiles: [root.path], system: sys, - options: { module: ModuleKind.AMD }, + options: { module: ts.ModuleKind.AMD }, cb, watchOptions: undefined }); @@ -115,9 +115,9 @@ namespace ts.tscWatch { return originalFileExists.call(host, fileName); }; - const watch = createWatchProgram(host); + const watch = ts.createWatchProgram(host); assert.isTrue(fileExistsCalledForBar, "'fileExists' should be called"); - runWatchBaseline({ + ts.tscWatch.runWatchBaseline({ scenario: "resolutionCache", subScenario: "loads missing files from disk", commandLineArgs: ["--w", root.path], @@ -152,11 +152,11 @@ namespace ts.tscWatch { content: `export const y = 1;export const x = 10;` }; - const { sys, baseline, oldSnap, cb, getPrograms } = createBaseline(createWatchedSystem([root, imported, libFile])); - const host = createWatchCompilerHostOfFilesAndCompilerOptionsForBaseline({ + const { sys, baseline, oldSnap, cb, getPrograms } = ts.tscWatch.createBaseline(ts.tscWatch.createWatchedSystem([root, imported, ts.tscWatch.libFile])); + const host = ts.tscWatch.createWatchCompilerHostOfFilesAndCompilerOptionsForBaseline({ rootFiles: [root.path], system: sys, - options: { module: ModuleKind.AMD }, + options: { module: ts.ModuleKind.AMD }, cb, watchOptions: undefined }); @@ -171,9 +171,9 @@ namespace ts.tscWatch { } return originalFileExists.call(host, fileName); }; - const watch = createWatchProgram(host); + const watch = ts.createWatchProgram(host); assert.isTrue(fileExistsCalledForBar, "'fileExists' should be called"); - runWatchBaseline({ + ts.tscWatch.runWatchBaseline({ scenario: "resolutionCache", subScenario: "should compile correctly when resolved module goes missing and then comes back", commandLineArgs: ["--w", root.path], @@ -210,14 +210,14 @@ namespace ts.tscWatch { }); }); - verifyTscWatch({ + ts.tscWatch.verifyTscWatch({ scenario, subScenario: "works when module resolution changes to ambient module", commandLineArgs: ["-w", "/a/b/foo.ts"], - sys: () => createWatchedSystem([{ + sys: () => ts.tscWatch.createWatchedSystem([{ path: "/a/b/foo.ts", content: `import * as fs from "fs";` - }, libFile], { currentDirectory: "/a/b" }), + }, ts.tscWatch.libFile], { currentDirectory: "/a/b" }), changes: [ { caption: "npm install node types", @@ -240,12 +240,12 @@ declare module "fs" { }` }); }, - timeouts: runQueuedTimeoutCallbacks, + timeouts: ts.tscWatch.runQueuedTimeoutCallbacks, } ] }); - verifyTscWatch({ + ts.tscWatch.verifyTscWatch({ scenario, subScenario: "works when included file with ambient module changes", commandLineArgs: ["--w", "/a/b/foo.ts", "/a/b/bar.d.ts"], @@ -268,7 +268,7 @@ declare module "url" { } ` }; - return createWatchedSystem([root, file, libFile], { currentDirectory: "/a/b" }); + return ts.tscWatch.createWatchedSystem([root, file, ts.tscWatch.libFile], { currentDirectory: "/a/b" }); }, changes: [ { @@ -280,30 +280,30 @@ declare module "fs" { } } `), - timeouts: runQueuedTimeoutCallbacks, + timeouts: ts.tscWatch.runQueuedTimeoutCallbacks, } ] }); - verifyTscWatch({ + ts.tscWatch.verifyTscWatch({ scenario, subScenario: "works when reusing program with files from external library", commandLineArgs: ["--w", "-p", "/a/b/projects/myProject/src"], sys: () => { const configDir = "/a/b/projects/myProject/src/"; - const file1: File = { + const file1: ts.tscWatch.File = { path: configDir + "file1.ts", content: 'import module1 = require("module1");\nmodule1("hello");' }; - const file2: File = { + const file2: ts.tscWatch.File = { path: configDir + "file2.ts", content: 'import module11 = require("module1");\nmodule11("hello");' }; - const module1: File = { + const module1: ts.tscWatch.File = { path: "/a/b/projects/myProject/node_modules/module1/index.js", content: "module.exports = options => { return options.toString(); }" }; - const configFile: File = { + const configFile: ts.tscWatch.File = { path: configDir + "tsconfig.json", content: JSON.stringify({ compilerOptions: { @@ -315,67 +315,67 @@ declare module "fs" { } }) }; - return createWatchedSystem([file1, file2, module1, libFile, configFile], { currentDirectory: "/a/b/projects/myProject/" }); + return ts.tscWatch.createWatchedSystem([file1, file2, module1, ts.tscWatch.libFile, configFile], { currentDirectory: "/a/b/projects/myProject/" }); }, changes: [ { caption: "Add new line to file1", change: sys => sys.appendFile("/a/b/projects/myProject/src/file1.ts", "\n;"), - timeouts: runQueuedTimeoutCallbacks, + timeouts: ts.tscWatch.runQueuedTimeoutCallbacks, } ] }); - verifyTscWatch({ + ts.tscWatch.verifyTscWatch({ scenario, subScenario: "works when renaming node_modules folder that already contains @types folder", - commandLineArgs: ["--w", `${projectRoot}/a.ts`], + commandLineArgs: ["--w", `${ts.tscWatch.projectRoot}/a.ts`], sys: () => { - const file: File = { - path: `${projectRoot}/a.ts`, + const file: ts.tscWatch.File = { + path: `${ts.tscWatch.projectRoot}/a.ts`, content: `import * as q from "qqq";` }; - const module: File = { - path: `${projectRoot}/node_modules2/@types/qqq/index.d.ts`, + const module: ts.tscWatch.File = { + path: `${ts.tscWatch.projectRoot}/node_modules2/@types/qqq/index.d.ts`, content: "export {}" }; - return createWatchedSystem([file, libFile, module], { currentDirectory: projectRoot }); + return ts.tscWatch.createWatchedSystem([file, ts.tscWatch.libFile, module], { currentDirectory: ts.tscWatch.projectRoot }); }, changes: [ { caption: "npm install", - change: sys => sys.renameFolder(`${projectRoot}/node_modules2`, `${projectRoot}/node_modules`), - timeouts: runQueuedTimeoutCallbacks, + change: sys => sys.renameFolder(`${ts.tscWatch.projectRoot}/node_modules2`, `${ts.tscWatch.projectRoot}/node_modules`), + timeouts: ts.tscWatch.runQueuedTimeoutCallbacks, } ] }); describe("ignores files/folder changes in node_modules that start with '.'", () => { function verifyIgnore(subScenario: string, commandLineArgs: readonly string[]) { - verifyTscWatch({ + ts.tscWatch.verifyTscWatch({ scenario, subScenario: `ignores changes in node_modules that start with dot/${subScenario}`, commandLineArgs, sys: () => { - const file1: File = { - path: `${projectRoot}/test.ts`, + const file1: ts.tscWatch.File = { + path: `${ts.tscWatch.projectRoot}/test.ts`, content: `import { x } from "somemodule";` }; - const file2: File = { - path: `${projectRoot}/node_modules/somemodule/index.d.ts`, + const file2: ts.tscWatch.File = { + path: `${ts.tscWatch.projectRoot}/node_modules/somemodule/index.d.ts`, content: `export const x = 10;` }; - const config: File = { - path: `${projectRoot}/tsconfig.json`, + const config: ts.tscWatch.File = { + path: `${ts.tscWatch.projectRoot}/tsconfig.json`, content: "{}" }; - return createWatchedSystem([libFile, file1, file2, config]); + return ts.tscWatch.createWatchedSystem([ts.tscWatch.libFile, file1, file2, config]); }, changes: [ { caption: "npm install file and folder that start with '.'", change: sys => sys.ensureFileOrFolder({ - path: `${projectRoot}/node_modules/.cache/babel-loader/89c02171edab901b9926470ba6d5677e.ts`, + path: `${ts.tscWatch.projectRoot}/node_modules/.cache/babel-loader/89c02171edab901b9926470ba6d5677e.ts`, content: JSON.stringify({ something: 10 }) }), timeouts: sys => sys.checkTimeoutQueueLength(0), @@ -383,21 +383,21 @@ declare module "fs" { ] }); } - verifyIgnore("watch without configFile", ["--w", `${projectRoot}/test.ts`]); - verifyIgnore("watch with configFile", ["--w", "-p", `${projectRoot}/tsconfig.json`]); + verifyIgnore("watch without configFile", ["--w", `${ts.tscWatch.projectRoot}/test.ts`]); + verifyIgnore("watch with configFile", ["--w", "-p", `${ts.tscWatch.projectRoot}/tsconfig.json`]); }); - verifyTscWatch({ + ts.tscWatch.verifyTscWatch({ scenario, subScenario: "when types in compiler option are global and installed at later point", - commandLineArgs: ["--w", "-p", `${projectRoot}/tsconfig.json`], + commandLineArgs: ["--w", "-p", `${ts.tscWatch.projectRoot}/tsconfig.json`], sys: () => { - const app: File = { - path: `${projectRoot}/lib/app.ts`, + const app: ts.tscWatch.File = { + path: `${ts.tscWatch.projectRoot}/lib/app.ts`, content: `myapp.component("hello");` }; - const tsconfig: File = { - path: `${projectRoot}/tsconfig.json`, + const tsconfig: ts.tscWatch.File = { + path: `${ts.tscWatch.projectRoot}/tsconfig.json`, content: JSON.stringify({ compilerOptions: { module: "none", @@ -405,21 +405,21 @@ declare module "fs" { } }) }; - return createWatchedSystem([app, tsconfig, libFile]); + return ts.tscWatch.createWatchedSystem([app, tsconfig, ts.tscWatch.libFile]); }, changes: [ { caption: "npm install ts-types", change: sys => { sys.ensureFileOrFolder({ - path: `${projectRoot}/node_modules/@myapp/ts-types/package.json`, + path: `${ts.tscWatch.projectRoot}/node_modules/@myapp/ts-types/package.json`, content: JSON.stringify({ version: "1.65.1", types: "types/somefile.define.d.ts" }) }); sys.ensureFileOrFolder({ - path: `${projectRoot}/node_modules/@myapp/ts-types/types/somefile.define.d.ts`, + path: `${ts.tscWatch.projectRoot}/node_modules/@myapp/ts-types/types/somefile.define.d.ts`, content: ` declare namespace myapp { function component(str: string): number; @@ -433,10 +433,10 @@ declare namespace myapp { }, { caption: "No change, just check program", - change: noop, + change: ts.noop, timeouts: (sys, [[oldProgram, oldBuilderProgram]], watchorSolution) => { sys.checkTimeoutQueueLength(0); - const newProgram = (watchorSolution as WatchOfConfigFile).getProgram(); + const newProgram = (watchorSolution as ts.WatchOfConfigFile).getProgram(); assert.strictEqual(newProgram, oldBuilderProgram, "No change so builder program should be same"); assert.strictEqual(newProgram.getProgram(), oldProgram, "No change so program should be same"); } @@ -444,63 +444,63 @@ declare namespace myapp { ] }); - verifyTscWatch({ + ts.tscWatch.verifyTscWatch({ scenario, subScenario: "with modules linked to sibling folder", commandLineArgs: ["-w"], sys: () => { - const mainPackageRoot = `${projectRoot}/main`; - const linkedPackageRoot = `${projectRoot}/linked-package`; - const mainFile: File = { + const mainPackageRoot = `${ts.tscWatch.projectRoot}/main`; + const linkedPackageRoot = `${ts.tscWatch.projectRoot}/linked-package`; + const mainFile: ts.tscWatch.File = { path: `${mainPackageRoot}/index.ts`, content: "import { Foo } from '@scoped/linked-package'" }; - const config: File = { + const config: ts.tscWatch.File = { path: `${mainPackageRoot}/tsconfig.json`, content: JSON.stringify({ compilerOptions: { module: "commonjs", moduleResolution: "node", baseUrl: ".", rootDir: "." }, files: ["index.ts"] }) }; - const linkedPackageInMain: SymLink = { + const linkedPackageInMain: ts.tscWatch.SymLink = { path: `${mainPackageRoot}/node_modules/@scoped/linked-package`, symLink: `${linkedPackageRoot}` }; - const linkedPackageJson: File = { + const linkedPackageJson: ts.tscWatch.File = { path: `${linkedPackageRoot}/package.json`, content: JSON.stringify({ name: "@scoped/linked-package", version: "0.0.1", types: "dist/index.d.ts", main: "dist/index.js" }) }; - const linkedPackageIndex: File = { + const linkedPackageIndex: ts.tscWatch.File = { path: `${linkedPackageRoot}/dist/index.d.ts`, content: "export * from './other';" }; - const linkedPackageOther: File = { + const linkedPackageOther: ts.tscWatch.File = { path: `${linkedPackageRoot}/dist/other.d.ts`, content: 'export declare const Foo = "BAR";' }; - const files = [libFile, mainFile, config, linkedPackageInMain, linkedPackageJson, linkedPackageIndex, linkedPackageOther]; - return createWatchedSystem(files, { currentDirectory: mainPackageRoot }); + const files = [ts.tscWatch.libFile, mainFile, config, linkedPackageInMain, linkedPackageJson, linkedPackageIndex, linkedPackageOther]; + return ts.tscWatch.createWatchedSystem(files, { currentDirectory: mainPackageRoot }); }, - changes: emptyArray + changes: ts.emptyArray }); describe("works when installing something in node_modules or @types when there is no notification from fs for index file", () => { function getNodeAtTypes() { - const nodeAtTypesIndex: File = { - path: `${projectRoot}/node_modules/@types/node/index.d.ts`, + const nodeAtTypesIndex: ts.tscWatch.File = { + path: `${ts.tscWatch.projectRoot}/node_modules/@types/node/index.d.ts`, content: `/// ` }; - const nodeAtTypesBase: File = { - path: `${projectRoot}/node_modules/@types/node/base.d.ts`, + const nodeAtTypesBase: ts.tscWatch.File = { + path: `${ts.tscWatch.projectRoot}/node_modules/@types/node/base.d.ts`, content: `// Base definitions for all NodeJS modules that are not specific to any version of TypeScript: /// ` }; - const nodeAtTypes36Base: File = { - path: `${projectRoot}/node_modules/@types/node/ts3.6/base.d.ts`, + const nodeAtTypes36Base: ts.tscWatch.File = { + path: `${ts.tscWatch.projectRoot}/node_modules/@types/node/ts3.6/base.d.ts`, content: `/// ` }; - const nodeAtTypesGlobals: File = { - path: `${projectRoot}/node_modules/@types/node/globals.d.ts`, + const nodeAtTypesGlobals: ts.tscWatch.File = { + path: `${ts.tscWatch.projectRoot}/node_modules/@types/node/globals.d.ts`, content: `declare var process: NodeJS.Process; declare namespace NodeJS { interface Process { @@ -510,40 +510,40 @@ declare namespace NodeJS { }; return { nodeAtTypesIndex, nodeAtTypesBase, nodeAtTypes36Base, nodeAtTypesGlobals }; } - verifyTscWatch({ + ts.tscWatch.verifyTscWatch({ scenario, subScenario: "works when installing something in node_modules or @types when there is no notification from fs for index file", commandLineArgs: ["--w", `--extendedDiagnostics`], sys: () => { - const file: File = { - path: `${projectRoot}/worker.ts`, + const file: ts.tscWatch.File = { + path: `${ts.tscWatch.projectRoot}/worker.ts`, content: `process.on("uncaughtException");` }; - const tsconfig: File = { - path: `${projectRoot}/tsconfig.json`, + const tsconfig: ts.tscWatch.File = { + path: `${ts.tscWatch.projectRoot}/tsconfig.json`, content: "{}" }; const { nodeAtTypesIndex, nodeAtTypesBase, nodeAtTypes36Base, nodeAtTypesGlobals } = getNodeAtTypes(); - return createWatchedSystem([file, libFile, tsconfig, nodeAtTypesIndex, nodeAtTypesBase, nodeAtTypes36Base, nodeAtTypesGlobals], { currentDirectory: projectRoot }); + return ts.tscWatch.createWatchedSystem([file, ts.tscWatch.libFile, tsconfig, nodeAtTypesIndex, nodeAtTypesBase, nodeAtTypes36Base, nodeAtTypesGlobals], { currentDirectory: ts.tscWatch.projectRoot }); }, changes: [ { caption: "npm ci step one: remove all node_modules files", - change: sys => sys.deleteFolder(`${projectRoot}/node_modules/@types`, /*recursive*/ true), - timeouts: runQueuedTimeoutCallbacks, + change: sys => sys.deleteFolder(`${ts.tscWatch.projectRoot}/node_modules/@types`, /*recursive*/ true), + timeouts: ts.tscWatch.runQueuedTimeoutCallbacks, }, { caption: `npm ci step two: create atTypes but something else in the @types folder`, change: sys => sys.ensureFileOrFolder({ - path: `${projectRoot}/node_modules/@types/mocha/index.d.ts`, + path: `${ts.tscWatch.projectRoot}/node_modules/@types/mocha/index.d.ts`, content: `export const foo = 10;` }), - timeouts: runQueuedTimeoutCallbacks + timeouts: ts.tscWatch.runQueuedTimeoutCallbacks }, { caption: `npm ci step three: create atTypes node folder`, - change: sys => sys.ensureFileOrFolder({ path: `${projectRoot}/node_modules/@types/node` }), - timeouts: runQueuedTimeoutCallbacks + change: sys => sys.ensureFileOrFolder({ path: `${ts.tscWatch.projectRoot}/node_modules/@types/node` }), + timeouts: ts.tscWatch.runQueuedTimeoutCallbacks }, { caption: `npm ci step four: create atTypes write all the files but dont invoke watcher for index.d.ts`, diff --git a/src/testRunner/unittests/tscWatch/sourceOfProjectReferenceRedirect.ts b/src/testRunner/unittests/tscWatch/sourceOfProjectReferenceRedirect.ts index 4110dbfe3331b..9315991089a4c 100644 --- a/src/testRunner/unittests/tscWatch/sourceOfProjectReferenceRedirect.ts +++ b/src/testRunner/unittests/tscWatch/sourceOfProjectReferenceRedirect.ts @@ -1,28 +1,25 @@ namespace ts.tscWatch { - import getFileFromProject = TestFSWithWatch.getTsBuildProjectFile; + import getFileFromProject = ts.TestFSWithWatch.getTsBuildProjectFile; describe("unittests:: tsc-watch:: watchAPI:: with sourceOfProjectReferenceRedirect", () => { interface VerifyWatchInput { - files: readonly TestFSWithWatch.FileOrFolderOrSymLink[]; + files: readonly ts.TestFSWithWatch.FileOrFolderOrSymLink[]; config: string; subScenario: string; } function verifyWatch({ files, config, subScenario }: VerifyWatchInput, alreadyBuilt: boolean) { - const { sys, baseline, oldSnap, cb, getPrograms } = createBaseline( - createWatchedSystem(files), - alreadyBuilt ? (sys, originalRead) => { - solutionBuildWithBaseline(sys, [config], originalRead); + const { sys, baseline, oldSnap, cb, getPrograms } = ts.tscWatch.createBaseline(ts.tscWatch.createWatchedSystem(files), alreadyBuilt ? (sys, originalRead) => { + ts.tscWatch.solutionBuildWithBaseline(sys, [config], originalRead); sys.clearOutput(); - } : undefined - ); - const host = createWatchCompilerHostOfConfigFileForBaseline({ + } : undefined); + const host = ts.tscWatch.createWatchCompilerHostOfConfigFileForBaseline({ configFileName: config, system: sys, cb, }); - host.useSourceOfProjectReferenceRedirect = returnTrue; - const watch = createWatchProgram(host); - runWatchBaseline({ + host.useSourceOfProjectReferenceRedirect = ts.returnTrue; + const watch = ts.createWatchProgram(host); + ts.tscWatch.runWatchBaseline({ scenario: "sourceOfProjectReferenceRedirect", subScenario: `${subScenario}${alreadyBuilt ? " when solution is already built" : ""}`, commandLineArgs: ["--w", "--p", config], @@ -30,7 +27,7 @@ namespace ts.tscWatch { baseline, oldSnap, getPrograms, - changes: emptyArray, + changes: ts.emptyArray, watchOrSolution: watch }); } @@ -55,7 +52,7 @@ namespace ts.tscWatch { const indexTs = getFileFromProject("demo", "animals/index.ts"); const animalsConfig = getFileFromProject("demo", "animals/tsconfig.json"); return { - files: [{ path: libFile.path, content: libContent }, baseConfig, coreTs, coreConfig, animalTs, dogTs, indexTs, animalsConfig], + files: [{ path: ts.tscWatch.libFile.path, content: ts.libContent }, baseConfig, coreTs, coreConfig, animalTs, dogTs, indexTs, animalsConfig], config: animalsConfig.path, subScenario: "with simple project" }; @@ -64,11 +61,11 @@ namespace ts.tscWatch { describe("when references are monorepo like with symlinks", () => { interface Packages { - bPackageJson: File; - aTest: File; - bFoo: File; - bBar: File; - bSymlink: SymLink; + bPackageJson: ts.tscWatch.File; + aTest: ts.tscWatch.File; + bFoo: ts.tscWatch.File; + bBar: ts.tscWatch.File; + bSymlink: ts.tscWatch.SymLink; subScenario: string; } function verifySymlinkScenario(packages: () => Packages) { @@ -80,22 +77,22 @@ namespace ts.tscWatch { }); } - function verifySymlinkScenarioWorker(packages: () => Packages, extraOptions: CompilerOptions) { + function verifySymlinkScenarioWorker(packages: () => Packages, extraOptions: ts.CompilerOptions) { verifyScenario(() => { const { bPackageJson, aTest, bFoo, bBar, bSymlink, subScenario } = packages(); const aConfig = config("A", extraOptions, ["../B"]); const bConfig = config("B", extraOptions); return { - files: [libFile, bPackageJson, aConfig, bConfig, aTest, bFoo, bBar, bSymlink], + files: [ts.tscWatch.libFile, bPackageJson, aConfig, bConfig, aTest, bFoo, bBar, bSymlink], config: aConfig.path, subScenario: `${subScenario}${extraOptions.preserveSymlinks ? " with preserveSymlinks" : ""}` }; }); } - function config(packageName: string, extraOptions: CompilerOptions, references?: string[]): File { + function config(packageName: string, extraOptions: ts.CompilerOptions, references?: string[]): ts.tscWatch.File { return { - path: `${projectRoot}/packages/${packageName}/tsconfig.json`, + path: `${ts.tscWatch.projectRoot}/packages/${packageName}/tsconfig.json`, content: JSON.stringify({ compilerOptions: { outDir: "lib", @@ -109,9 +106,9 @@ namespace ts.tscWatch { }; } - function file(packageName: string, fileName: string, content: string): File { + function file(packageName: string, fileName: string, content: string): ts.tscWatch.File { return { - path: `${projectRoot}/packages/${packageName}/src/${fileName}`, + path: `${ts.tscWatch.projectRoot}/packages/${packageName}/src/${fileName}`, content }; } @@ -120,7 +117,7 @@ namespace ts.tscWatch { describe("when packageJson has types field", () => { verifySymlinkScenario(() => ({ bPackageJson: { - path: `${projectRoot}/packages/B/package.json`, + path: `${ts.tscWatch.projectRoot}/packages/B/package.json`, content: JSON.stringify({ main: "lib/index.js", types: "lib/index.d.ts" @@ -134,8 +131,8 @@ bar(); bFoo: file("B", "index.ts", `export function foo() { }`), bBar: file("B", "bar.ts", `export function bar() { }`), bSymlink: { - path: `${projectRoot}/node_modules/${scope}b`, - symLink: `${projectRoot}/packages/B` + path: `${ts.tscWatch.projectRoot}/node_modules/${scope}b`, + symLink: `${ts.tscWatch.projectRoot}/packages/B` }, subScenario: `when packageJson has types field${scope ? " with scoped package" : ""}` })); @@ -144,7 +141,7 @@ bar(); describe("when referencing file from subFolder", () => { verifySymlinkScenario(() => ({ bPackageJson: { - path: `${projectRoot}/packages/B/package.json`, + path: `${ts.tscWatch.projectRoot}/packages/B/package.json`, content: "{}" }, aTest: file("A", "test.ts", `import { foo } from '${scope}b/lib/foo'; @@ -155,8 +152,8 @@ bar(); bFoo: file("B", "foo.ts", `export function foo() { }`), bBar: file("B", "bar/foo.ts", `export function bar() { }`), bSymlink: { - path: `${projectRoot}/node_modules/${scope}b`, - symLink: `${projectRoot}/packages/B` + path: `${ts.tscWatch.projectRoot}/node_modules/${scope}b`, + symLink: `${ts.tscWatch.projectRoot}/packages/B` }, subScenario: `when referencing file from subFolder${scope ? " with scoped package" : ""}` })); diff --git a/src/testRunner/unittests/tscWatch/watchApi.ts b/src/testRunner/unittests/tscWatch/watchApi.ts index 477a982eafde2..b5be24b77b784 100644 --- a/src/testRunner/unittests/tscWatch/watchApi.ts +++ b/src/testRunner/unittests/tscWatch/watchApi.ts @@ -4,32 +4,29 @@ namespace ts.tscWatch { compilerOptions: { module: "commonjs", resolveJsonModule: true }, files: ["index.ts"] }; - const mainFile: File = { - path: `${projectRoot}/index.ts`, + const mainFile: ts.tscWatch.File = { + path: `${ts.tscWatch.projectRoot}/index.ts`, content: "import settings from './settings.json';" }; - const config: File = { - path: `${projectRoot}/tsconfig.json`, + const config: ts.tscWatch.File = { + path: `${ts.tscWatch.projectRoot}/tsconfig.json`, content: JSON.stringify(configFileJson) }; - const settingsJson: File = { - path: `${projectRoot}/settings.json`, + const settingsJson: ts.tscWatch.File = { + path: `${ts.tscWatch.projectRoot}/settings.json`, content: JSON.stringify({ content: "Print this" }) }; it("verify that module resolution with json extension works when returned without extension", () => { - const { sys, baseline, oldSnap, cb, getPrograms } = createBaseline(createWatchedSystem( - [libFile, mainFile, config, settingsJson], - { currentDirectory: projectRoot }), - ); - const host = createWatchCompilerHostOfConfigFileForBaseline({ + const { sys, baseline, oldSnap, cb, getPrograms } = ts.tscWatch.createBaseline(ts.tscWatch.createWatchedSystem([ts.tscWatch.libFile, mainFile, config, settingsJson], { currentDirectory: ts.tscWatch.projectRoot })); + const host = ts.tscWatch.createWatchCompilerHostOfConfigFileForBaseline({ configFileName: config.path, system: sys, cb, }); - const parsedCommandResult = parseJsonConfigFileContent(configFileJson, sys, config.path); + const parsedCommandResult = ts.parseJsonConfigFileContent(configFileJson, sys, config.path); host.resolveModuleNames = (moduleNames, containingFile) => moduleNames.map(m => { - const result = resolveModuleName(m, containingFile, parsedCommandResult.options, host); + const result = ts.resolveModuleName(m, containingFile, parsedCommandResult.options, host); const resolvedModule = result.resolvedModule!; return { resolvedFileName: resolvedModule.resolvedFileName, @@ -37,8 +34,8 @@ namespace ts.tscWatch { originalFileName: resolvedModule.originalPath, }; }); - const watch = createWatchProgram(host); - runWatchBaseline({ + const watch = ts.createWatchProgram(host); + ts.tscWatch.runWatchBaseline({ scenario: "watchApi", subScenario: "verify that module resolution with json extension works when returned without extension", commandLineArgs: ["--w", "--p", config.path], @@ -46,7 +43,7 @@ namespace ts.tscWatch { baseline, oldSnap, getPrograms, - changes: emptyArray, + changes: ts.emptyArray, watchOrSolution: watch }); }); @@ -54,22 +51,19 @@ namespace ts.tscWatch { describe("unittests:: tsc-watch:: watchAPI:: tsc-watch expose error count to watch status reporter", () => { it("verify that the error count is correctly passed down to the watch status reporter", () => { - const config: File = { - path: `${projectRoot}/tsconfig.json`, + const config: ts.tscWatch.File = { + path: `${ts.tscWatch.projectRoot}/tsconfig.json`, content: JSON.stringify({ compilerOptions: { module: "commonjs" }, files: ["index.ts"] }) }; - const mainFile: File = { - path: `${projectRoot}/index.ts`, + const mainFile: ts.tscWatch.File = { + path: `${ts.tscWatch.projectRoot}/index.ts`, content: "let compiler = new Compiler(); for (let i = 0; j < 5; i++) {}" }; - const { sys, baseline, oldSnap, cb, getPrograms } = createBaseline(createWatchedSystem( - [libFile, mainFile, config], - { currentDirectory: projectRoot }), - ); - const host = createWatchCompilerHostOfConfigFileForBaseline({ + const { sys, baseline, oldSnap, cb, getPrograms } = ts.tscWatch.createBaseline(ts.tscWatch.createWatchedSystem([ts.tscWatch.libFile, mainFile, config], { currentDirectory: ts.tscWatch.projectRoot })); + const host = ts.tscWatch.createWatchCompilerHostOfConfigFileForBaseline({ configFileName: config.path, system: sys, cb, @@ -80,9 +74,9 @@ namespace ts.tscWatch { existing.call(host, diagnostic, newLine, options, errorCount); watchedErrorCount = errorCount; }; - const watch = createWatchProgram(host); + const watch = ts.createWatchProgram(host); assert.equal(watchedErrorCount, 2, "The error count was expected to be 2 for the file change"); - runWatchBaseline({ + ts.tscWatch.runWatchBaseline({ scenario: "watchApi", subScenario: "verify that the error count is correctly passed down to the watch status reporter", commandLineArgs: ["--w", "--p", config.path], @@ -90,7 +84,7 @@ namespace ts.tscWatch { baseline, oldSnap, getPrograms, - changes: emptyArray, + changes: ts.emptyArray, watchOrSolution: watch }); }); @@ -98,24 +92,24 @@ namespace ts.tscWatch { describe("unittests:: tsc-watch:: watchAPI:: when watchHost does not implement setTimeout or clearTimeout", () => { it("verifies that getProgram gets updated program if new file is added to the program", () => { - const config: File = { - path: `${projectRoot}/tsconfig.json`, + const config: ts.tscWatch.File = { + path: `${ts.tscWatch.projectRoot}/tsconfig.json`, content: "{}" }; - const mainFile: File = { - path: `${projectRoot}/main.ts`, + const mainFile: ts.tscWatch.File = { + path: `${ts.tscWatch.projectRoot}/main.ts`, content: "const x = 10;" }; - const { sys, baseline, oldSnap, cb, getPrograms } = createBaseline(createWatchedSystem([config, mainFile, libFile])); - const host = createWatchCompilerHostOfConfigFileForBaseline({ + const { sys, baseline, oldSnap, cb, getPrograms } = ts.tscWatch.createBaseline(ts.tscWatch.createWatchedSystem([config, mainFile, ts.tscWatch.libFile])); + const host = ts.tscWatch.createWatchCompilerHostOfConfigFileForBaseline({ configFileName: config.path, system: sys, cb, }); host.setTimeout = undefined; host.clearTimeout = undefined; - const watch = createWatchProgram(host); - runWatchBaseline({ + const watch = ts.createWatchProgram(host); + ts.tscWatch.runWatchBaseline({ scenario: "watchApi", subScenario: "without timesouts on host program gets updated", commandLineArgs: ["--w", "--p", config.path], @@ -125,7 +119,7 @@ namespace ts.tscWatch { getPrograms, changes: [{ caption: "Write a file", - change: sys => sys.writeFile(`${projectRoot}/bar.ts`, "const y =10;"), + change: sys => sys.writeFile(`${ts.tscWatch.projectRoot}/bar.ts`, "const y =10;"), timeouts: sys => { sys.checkTimeoutQueueLength(0); watch.getProgram(); @@ -138,30 +132,28 @@ namespace ts.tscWatch { describe("unittests:: tsc-watch:: watchAPI:: when watchHost can add extraFileExtensions to process", () => { it("verifies that extraFileExtensions are supported to get the program with other extensions", () => { - const config: File = { - path: `${projectRoot}/tsconfig.json`, + const config: ts.tscWatch.File = { + path: `${ts.tscWatch.projectRoot}/tsconfig.json`, content: "{}" }; - const mainFile: File = { - path: `${projectRoot}/main.ts`, + const mainFile: ts.tscWatch.File = { + path: `${ts.tscWatch.projectRoot}/main.ts`, content: "const x = 10;" }; - const otherFile: File = { - path: `${projectRoot}/other.vue`, + const otherFile: ts.tscWatch.File = { + path: `${ts.tscWatch.projectRoot}/other.vue`, content: "" }; - const { sys, baseline, oldSnap, cb, getPrograms } = createBaseline( - createWatchedSystem([config, mainFile, otherFile, libFile]) - ); - const host = createWatchCompilerHostOfConfigFileForBaseline({ + const { sys, baseline, oldSnap, cb, getPrograms } = ts.tscWatch.createBaseline(ts.tscWatch.createWatchedSystem([config, mainFile, otherFile, ts.tscWatch.libFile])); + const host = ts.tscWatch.createWatchCompilerHostOfConfigFileForBaseline({ configFileName: config.path, optionsToExtend: { allowNonTsExtensions: true }, - extraFileExtensions: [{ extension: ".vue", isMixedContent: true, scriptKind: ScriptKind.Deferred }], + extraFileExtensions: [{ extension: ".vue", isMixedContent: true, scriptKind: ts.ScriptKind.Deferred }], system: sys, cb, }); - const watch = createWatchProgram(host); - runWatchBaseline({ + const watch = ts.createWatchProgram(host); + ts.tscWatch.runWatchBaseline({ scenario: "watchApi", subScenario: "extraFileExtensions are supported", commandLineArgs: ["--w", "--p", config.path], @@ -171,8 +163,8 @@ namespace ts.tscWatch { getPrograms, changes: [{ caption: "Write a file", - change: sys => sys.writeFile(`${projectRoot}/other2.vue`, otherFile.content), - timeouts: checkSingleTimeoutQueueLengthAndRun, + change: sys => sys.writeFile(`${ts.tscWatch.projectRoot}/other2.vue`, otherFile.content), + timeouts: ts.tscWatch.checkSingleTimeoutQueueLengthAndRun, }], watchOrSolution: watch }); @@ -181,57 +173,51 @@ namespace ts.tscWatch { describe("unittests:: tsc-watch:: watchAPI:: when watchHost uses createSemanticDiagnosticsBuilderProgram", () => { function createSystem(configText: string, mainText: string) { - const config: File = { - path: `${projectRoot}/tsconfig.json`, + const config: ts.tscWatch.File = { + path: `${ts.tscWatch.projectRoot}/tsconfig.json`, content: configText }; - const mainFile: File = { - path: `${projectRoot}/main.ts`, + const mainFile: ts.tscWatch.File = { + path: `${ts.tscWatch.projectRoot}/main.ts`, content: mainText }; - const otherFile: File = { - path: `${projectRoot}/other.ts`, + const otherFile: ts.tscWatch.File = { + path: `${ts.tscWatch.projectRoot}/other.ts`, content: "export const y = 10;" }; return { - ...createBaseline(createWatchedSystem([config, mainFile, otherFile, libFile])), + ...ts.tscWatch.createBaseline(ts.tscWatch.createWatchedSystem([config, mainFile, otherFile, ts.tscWatch.libFile])), config, mainFile, otherFile, }; } - function createWatch( - baseline: string[], - config: File, - sys: TestFSWithWatch.TestServerHostTrackingWrittenFiles, - createProgram: CreateProgram, - optionsToExtend?: CompilerOptions, - ) { - const { cb, getPrograms } = commandLineCallbacks(sys); + function createWatch(baseline: string[], config: ts.tscWatch.File, sys: ts.TestFSWithWatch.TestServerHostTrackingWrittenFiles, createProgram: ts.CreateProgram, optionsToExtend?: ts.CompilerOptions) { + const { cb, getPrograms } = ts.commandLineCallbacks(sys); baseline.push(`tsc --w${optionsToExtend?.noEmit ? " --noEmit" : ""}`); const oldSnap = sys.snap(); - const host = createWatchCompilerHostOfConfigFileForBaseline({ + const host = ts.tscWatch.createWatchCompilerHostOfConfigFileForBaseline({ configFileName: config.path, optionsToExtend, createProgram, system: sys, cb, }); - const watch = createWatchProgram(host); - watchBaseline({ + const watch = ts.createWatchProgram(host); + ts.tscWatch.watchBaseline({ baseline, getPrograms, - oldPrograms: emptyArray, + oldPrograms: ts.emptyArray, sys, oldSnap, }); watch.close(); } - function verifyOutputs(baseline: string[], sys: System, emitSys: System) { + function verifyOutputs(baseline: string[], sys: ts.System, emitSys: ts.System) { baseline.push("Checking if output is same as EmitAndSemanticDiagnosticsBuilderProgram::"); - for (const output of [`${projectRoot}/main.js`, `${projectRoot}/main.d.ts`, `${projectRoot}/other.js`, `${projectRoot}/other.d.ts`, `${projectRoot}/tsconfig.tsbuildinfo`]) { + for (const output of [`${ts.tscWatch.projectRoot}/main.js`, `${ts.tscWatch.projectRoot}/main.d.ts`, `${ts.tscWatch.projectRoot}/other.js`, `${ts.tscWatch.projectRoot}/other.d.ts`, `${ts.tscWatch.projectRoot}/tsconfig.tsbuildinfo`]) { baseline.push(`Output file text for ${output} is same:: ${sys.readFile(output) === emitSys.readFile(output)}`); } baseline.push(""); @@ -243,43 +229,29 @@ namespace ts.tscWatch { return { ...result, emitSys, emitBaseline }; } - function applyChangeForBuilderTest( - baseline: string[], - emitBaseline: string[], - sys: TestFSWithWatch.TestServerHostTrackingWrittenFiles, - emitSys: TestFSWithWatch.TestServerHostTrackingWrittenFiles, - change: (sys: TestFSWithWatch.TestServerHostTrackingWrittenFiles) => void, - caption: string - ) { + function applyChangeForBuilderTest(baseline: string[], emitBaseline: string[], sys: ts.TestFSWithWatch.TestServerHostTrackingWrittenFiles, emitSys: ts.TestFSWithWatch.TestServerHostTrackingWrittenFiles, change: (sys: ts.TestFSWithWatch.TestServerHostTrackingWrittenFiles) => void, caption: string) { // Change file - applyChange(sys, baseline, change, caption); - applyChange(emitSys, emitBaseline, change, caption); + ts.tscWatch.applyChange(sys, baseline, change, caption); + ts.tscWatch.applyChange(emitSys, emitBaseline, change, caption); } - function verifyBuilder( - baseline: string[], - emitBaseline: string[], - config: File, - sys: TestFSWithWatch.TestServerHostTrackingWrittenFiles, - emitSys: TestFSWithWatch.TestServerHostTrackingWrittenFiles, - createProgram: CreateProgram, - optionsToExtend?: CompilerOptions) { + function verifyBuilder(baseline: string[], emitBaseline: string[], config: ts.tscWatch.File, sys: ts.TestFSWithWatch.TestServerHostTrackingWrittenFiles, emitSys: ts.TestFSWithWatch.TestServerHostTrackingWrittenFiles, createProgram: ts.CreateProgram, optionsToExtend?: ts.CompilerOptions) { createWatch(baseline, config, sys, createProgram, optionsToExtend); - createWatch(emitBaseline, config, emitSys, createEmitAndSemanticDiagnosticsBuilderProgram, optionsToExtend); + createWatch(emitBaseline, config, emitSys, ts.createEmitAndSemanticDiagnosticsBuilderProgram, optionsToExtend); verifyOutputs(baseline, sys, emitSys); } it("verifies that noEmit is handled on createSemanticDiagnosticsBuilderProgram and typechecking happens only on affected files", () => { const { sys, baseline, oldSnap, cb, getPrograms, config, mainFile } = createSystem("{}", "export const x = 10;"); - const host = createWatchCompilerHostOfConfigFileForBaseline({ + const host = ts.tscWatch.createWatchCompilerHostOfConfigFileForBaseline({ configFileName: config.path, optionsToExtend: { noEmit: true }, - createProgram: createSemanticDiagnosticsBuilderProgram, + createProgram: ts.createSemanticDiagnosticsBuilderProgram, system: sys, cb, }); - const watch = createWatchProgram(host); - runWatchBaseline({ + const watch = ts.createWatchProgram(host); + ts.tscWatch.runWatchBaseline({ scenario: "watchApi", subScenario: "verifies that noEmit is handled on createSemanticDiagnosticsBuilderProgram", commandLineArgs: ["--w", "--p", config.path], @@ -290,7 +262,7 @@ namespace ts.tscWatch { changes: [{ caption: "Modify a file", change: sys => sys.appendFile(mainFile.path, "\n// SomeComment"), - timeouts: runQueuedTimeoutCallbacks, + timeouts: ts.tscWatch.runQueuedTimeoutCallbacks, }], watchOrSolution: watch }); @@ -308,25 +280,25 @@ namespace ts.tscWatch { const { sys, config, mainFile, emitSys } = result; // No Emit - verifyBuilder(baseline, emitBaseline, config, sys, emitSys, createEmitAndSemanticDiagnosticsBuilderProgram, { noEmit: true }); + verifyBuilder(baseline, emitBaseline, config, sys, emitSys, ts.createEmitAndSemanticDiagnosticsBuilderProgram, { noEmit: true }); // Emit on both sys should result in same output - verifyBuilder(baseline, emitBaseline, config, sys, emitSys, createEmitAndSemanticDiagnosticsBuilderProgram); + verifyBuilder(baseline, emitBaseline, config, sys, emitSys, ts.createEmitAndSemanticDiagnosticsBuilderProgram); // Change file applyChangeForBuilderTest(baseline, emitBaseline, sys, emitSys, sys => sys.appendFile(mainFile.path, "\n// SomeComment"), "Add comment"); // Verify noEmit results in same output - verifyBuilder(baseline, emitBaseline, config, sys, emitSys, createSemanticDiagnosticsBuilderProgram, { noEmit: true }); + verifyBuilder(baseline, emitBaseline, config, sys, emitSys, ts.createSemanticDiagnosticsBuilderProgram, { noEmit: true }); // Emit on both sys should result in same output - verifyBuilder(baseline, emitBaseline, config, sys, emitSys, createEmitAndSemanticDiagnosticsBuilderProgram); + verifyBuilder(baseline, emitBaseline, config, sys, emitSys, ts.createEmitAndSemanticDiagnosticsBuilderProgram); // Change file applyChangeForBuilderTest(baseline, emitBaseline, sys, emitSys, sys => sys.appendFile(mainFile.path, "\n// SomeComment"), "Add comment"); // Emit on both the builders should result in same files - verifyBuilder(baseline, emitBaseline, config, sys, emitSys, createSemanticDiagnosticsBuilderProgram); + verifyBuilder(baseline, emitBaseline, config, sys, emitSys, ts.createSemanticDiagnosticsBuilderProgram); }); after(() => { baseline = undefined!; @@ -352,20 +324,20 @@ namespace ts.tscWatch { const { sys, config, mainFile, emitSys } = result; // Verify noEmit results in same output - verifyBuilder(baseline, emitBaseline, config, sys, emitSys, createSemanticDiagnosticsBuilderProgram); + verifyBuilder(baseline, emitBaseline, config, sys, emitSys, ts.createSemanticDiagnosticsBuilderProgram); // Change file applyChangeForBuilderTest(baseline, emitBaseline, sys, emitSys, sys => sys.appendFile(mainFile.path, "\n// SomeComment"), "Add comment"); // Verify noEmit results in same output - verifyBuilder(baseline, emitBaseline, config, sys, emitSys, createSemanticDiagnosticsBuilderProgram); + verifyBuilder(baseline, emitBaseline, config, sys, emitSys, ts.createSemanticDiagnosticsBuilderProgram); // Fix error const fixed = "export const x = 10;"; applyChangeForBuilderTest(baseline, emitBaseline, sys, emitSys, sys => sys.writeFile(mainFile.path, fixed), "Fix error"); // Emit on both the builders should result in same files - verifyBuilder(baseline, emitBaseline, config, sys, emitSys, createSemanticDiagnosticsBuilderProgram); + verifyBuilder(baseline, emitBaseline, config, sys, emitSys, ts.createSemanticDiagnosticsBuilderProgram); }); it("noEmitOnError with composite writes the tsbuildinfo with pending affected files correctly", () => { @@ -379,40 +351,34 @@ namespace ts.tscWatch { it("SemanticDiagnosticsBuilderProgram emitDtsOnly does not update affected files pending emit", () => { // Initial const { sys, baseline, config, mainFile } = createSystem(JSON.stringify({ compilerOptions: { composite: true, noEmitOnError: true } }), "export const x: string = 10;"); - createWatch(baseline, config, sys, createSemanticDiagnosticsBuilderProgram); + createWatch(baseline, config, sys, ts.createSemanticDiagnosticsBuilderProgram); // Fix error and emit - applyChange(sys, baseline, sys => sys.writeFile(mainFile.path, "export const x = 10;"), "Fix error"); - - const { cb, getPrograms } = commandLineCallbacks(sys); + ts.tscWatch.applyChange(sys, baseline, sys => sys.writeFile(mainFile.path, "export const x = 10;"), "Fix error"); + const { cb, getPrograms } = ts.commandLineCallbacks(sys); const oldSnap = sys.snap(); - const reportDiagnostic = createDiagnosticReporter(sys, /*pretty*/ true); - const reportWatchStatus = createWatchStatusReporter(sys, /*pretty*/ true); - const host = createWatchCompilerHostOfConfigFile({ + const reportDiagnostic = ts.createDiagnosticReporter(sys, /*pretty*/ true); + const reportWatchStatus = ts.createWatchStatusReporter(sys, /*pretty*/ true); + const host = ts.createWatchCompilerHostOfConfigFile({ configFileName: config.path, - createProgram: createSemanticDiagnosticsBuilderProgram, + createProgram: ts.createSemanticDiagnosticsBuilderProgram, system: sys, reportDiagnostic, reportWatchStatus, }); host.afterProgramCreate = program => { - const diagnostics = sortAndDeduplicateDiagnostics(program.getSemanticDiagnostics()); + const diagnostics = ts.sortAndDeduplicateDiagnostics(program.getSemanticDiagnostics()); diagnostics.forEach(reportDiagnostic); // Buildinfo should still have affectedFilesPendingEmit since we are only emitting dts files program.emit(/*targetSourceFile*/ undefined, /*writeFile*/ undefined, /*cancellationToken*/ undefined, /*emitOnlyDts*/ true); - reportWatchStatus( - createCompilerDiagnostic(getWatchErrorSummaryDiagnosticMessage(diagnostics.length), diagnostics.length), - sys.newLine, - program.getCompilerOptions(), - diagnostics.length - ); + reportWatchStatus(ts.createCompilerDiagnostic(ts.getWatchErrorSummaryDiagnosticMessage(diagnostics.length), diagnostics.length), sys.newLine, program.getCompilerOptions(), diagnostics.length); cb(program); }; - createWatchProgram(host); - watchBaseline({ + ts.createWatchProgram(host); + ts.tscWatch.watchBaseline({ baseline, getPrograms, - oldPrograms: emptyArray, + oldPrograms: ts.emptyArray, sys, oldSnap, }); @@ -422,8 +388,8 @@ namespace ts.tscWatch { describe("unittests:: tsc-watch:: watchAPI:: when getParsedCommandLine is implemented", () => { function setup(useSourceOfProjectReferenceRedirect?: () => boolean) { - const config1: File = { - path: `${projectRoot}/projects/project1/tsconfig.json`, + const config1: ts.tscWatch.File = { + path: `${ts.tscWatch.projectRoot}/projects/project1/tsconfig.json`, content: JSON.stringify({ compilerOptions: { module: "none", @@ -432,16 +398,16 @@ namespace ts.tscWatch { exclude: ["temp"] }) }; - const class1: File = { - path: `${projectRoot}/projects/project1/class1.ts`, + const class1: ts.tscWatch.File = { + path: `${ts.tscWatch.projectRoot}/projects/project1/class1.ts`, content: `class class1 {}` }; - const class1Dts: File = { - path: `${projectRoot}/projects/project1/class1.d.ts`, + const class1Dts: ts.tscWatch.File = { + path: `${ts.tscWatch.projectRoot}/projects/project1/class1.d.ts`, content: `declare class class1 {}` }; - const config2: File = { - path: `${projectRoot}/projects/project2/tsconfig.json`, + const config2: ts.tscWatch.File = { + path: `${ts.tscWatch.projectRoot}/projects/project2/tsconfig.json`, content: JSON.stringify({ compilerOptions: { module: "none", @@ -452,39 +418,39 @@ namespace ts.tscWatch { ] }) }; - const class2: File = { - path: `${projectRoot}/projects/project2/class2.ts`, + const class2: ts.tscWatch.File = { + path: `${ts.tscWatch.projectRoot}/projects/project2/class2.ts`, content: `class class2 {}` }; - const system = createWatchedSystem([config1, class1, class1Dts, config2, class2, libFile]); - const baseline = createBaseline(system); - const compilerHost = createWatchCompilerHostOfConfigFileForBaseline({ + const system = ts.tscWatch.createWatchedSystem([config1, class1, class1Dts, config2, class2, ts.tscWatch.libFile]); + const baseline = ts.tscWatch.createBaseline(system); + const compilerHost = ts.tscWatch.createWatchCompilerHostOfConfigFileForBaseline({ cb: baseline.cb, system, configFileName: config2.path, optionsToExtend: { extendedDiagnostics: true } }); compilerHost.useSourceOfProjectReferenceRedirect = useSourceOfProjectReferenceRedirect; - const calledGetParsedCommandLine = new Set(); + const calledGetParsedCommandLine = new ts.Set(); compilerHost.getParsedCommandLine = fileName => { assert.isFalse(calledGetParsedCommandLine.has(fileName), `Already called on ${fileName}`); calledGetParsedCommandLine.add(fileName); - return getParsedCommandLineOfConfigFile(fileName, /*optionsToExtend*/ undefined, { + return ts.getParsedCommandLineOfConfigFile(fileName, /*optionsToExtend*/ undefined, { useCaseSensitiveFileNames: true, fileExists: path => system.fileExists(path), readFile: path => system.readFile(path), getCurrentDirectory: () => system.getCurrentDirectory(), readDirectory: (path, extensions, excludes, includes, depth) => system.readDirectory(path, extensions, excludes, includes, depth), - onUnRecoverableConfigFileDiagnostic: noop, + onUnRecoverableConfigFileDiagnostic: ts.noop, }); }; - const watch = createWatchProgram(compilerHost); + const watch = ts.createWatchProgram(compilerHost); return { watch, baseline, config2, calledGetParsedCommandLine }; } it("when new file is added to the referenced project with host implementing getParsedCommandLine", () => { - const { watch, baseline, config2, calledGetParsedCommandLine } = setup(returnTrue); - runWatchBaseline({ + const { watch, baseline, config2, calledGetParsedCommandLine } = setup(ts.returnTrue); + ts.tscWatch.runWatchBaseline({ scenario: "watchApi", subScenario: "when new file is added to the referenced project with host implementing getParsedCommandLine", commandLineArgs: ["--w", "-p", config2.path, "--extendedDiagnostics"], @@ -494,18 +460,18 @@ namespace ts.tscWatch { caption: "Add class3 to project1", change: sys => { calledGetParsedCommandLine.clear(); - sys.writeFile(`${projectRoot}/projects/project1/class3.ts`, `class class3 {}`); + sys.writeFile(`${ts.tscWatch.projectRoot}/projects/project1/class3.ts`, `class class3 {}`); }, - timeouts: checkSingleTimeoutQueueLengthAndRun, + timeouts: ts.tscWatch.checkSingleTimeoutQueueLengthAndRun, }, { caption: "Add excluded file to project1", - change: sys => sys.ensureFileOrFolder({ path: `${projectRoot}/projects/project1/temp/file.d.ts`, content: `declare class file {}` }), + change: sys => sys.ensureFileOrFolder({ path: `${ts.tscWatch.projectRoot}/projects/project1/temp/file.d.ts`, content: `declare class file {}` }), timeouts: sys => sys.checkTimeoutQueueLength(0), }, { caption: "Add output of class3", - change: sys => sys.writeFile(`${projectRoot}/projects/project1/class3.d.ts`, `declare class class3 {}`), + change: sys => sys.writeFile(`${ts.tscWatch.projectRoot}/projects/project1/class3.d.ts`, `declare class class3 {}`), timeouts: sys => sys.checkTimeoutQueueLength(0), }, ], @@ -515,7 +481,7 @@ namespace ts.tscWatch { it("when new file is added to the referenced project with host implementing getParsedCommandLine without implementing useSourceOfProjectReferenceRedirect", () => { const { watch, baseline, config2, calledGetParsedCommandLine } = setup(); - runWatchBaseline({ + ts.tscWatch.runWatchBaseline({ scenario: "watchApi", subScenario: "when new file is added to the referenced project with host implementing getParsedCommandLine without implementing useSourceOfProjectReferenceRedirect", commandLineArgs: ["--w", "-p", config2.path, "--extendedDiagnostics"], @@ -525,29 +491,29 @@ namespace ts.tscWatch { caption: "Add class3 to project1", change: sys => { calledGetParsedCommandLine.clear(); - sys.writeFile(`${projectRoot}/projects/project1/class3.ts`, `class class3 {}`); + sys.writeFile(`${ts.tscWatch.projectRoot}/projects/project1/class3.ts`, `class class3 {}`); }, - timeouts: checkSingleTimeoutQueueLengthAndRun, + timeouts: ts.tscWatch.checkSingleTimeoutQueueLengthAndRun, }, { caption: "Add class3 output to project1", - change: sys => sys.writeFile(`${projectRoot}/projects/project1/class3.d.ts`, `declare class class3 {}`), - timeouts: checkSingleTimeoutQueueLengthAndRun, + change: sys => sys.writeFile(`${ts.tscWatch.projectRoot}/projects/project1/class3.d.ts`, `declare class class3 {}`), + timeouts: ts.tscWatch.checkSingleTimeoutQueueLengthAndRun, }, { caption: "Add excluded file to project1", - change: sys => sys.ensureFileOrFolder({ path: `${projectRoot}/projects/project1/temp/file.d.ts`, content: `declare class file {}` }), + change: sys => sys.ensureFileOrFolder({ path: `${ts.tscWatch.projectRoot}/projects/project1/temp/file.d.ts`, content: `declare class file {}` }), timeouts: sys => sys.checkTimeoutQueueLength(0), }, { caption: "Delete output of class3", - change: sys => sys.deleteFile(`${projectRoot}/projects/project1/class3.d.ts`), - timeouts: checkSingleTimeoutQueueLengthAndRun, + change: sys => sys.deleteFile(`${ts.tscWatch.projectRoot}/projects/project1/class3.d.ts`), + timeouts: ts.tscWatch.checkSingleTimeoutQueueLengthAndRun, }, { caption: "Add output of class3", - change: sys => sys.writeFile(`${projectRoot}/projects/project1/class3.d.ts`, `declare class class3 {}`), - timeouts: checkSingleTimeoutQueueLengthAndRun, + change: sys => sys.writeFile(`${ts.tscWatch.projectRoot}/projects/project1/class3.d.ts`, `declare class class3 {}`), + timeouts: ts.tscWatch.checkSingleTimeoutQueueLengthAndRun, }, ], watchOrSolution: watch diff --git a/src/testRunner/unittests/tscWatch/watchEnvironment.ts b/src/testRunner/unittests/tscWatch/watchEnvironment.ts index d02afa3137714..4d4efb9b47fa2 100644 --- a/src/testRunner/unittests/tscWatch/watchEnvironment.ts +++ b/src/testRunner/unittests/tscWatch/watchEnvironment.ts @@ -1,28 +1,28 @@ namespace ts.tscWatch { - import Tsc_WatchDirectory = TestFSWithWatch.Tsc_WatchDirectory; + import Tsc_WatchDirectory = ts.TestFSWithWatch.Tsc_WatchDirectory; describe("unittests:: tsc-watch:: watchEnvironment:: tsc-watch with different polling/non polling options", () => { const scenario = "watchEnvironment"; - verifyTscWatch({ + ts.tscWatch.verifyTscWatch({ scenario, subScenario: "watchFile/using dynamic priority polling", commandLineArgs: ["--w", `/a/username/project/typescript.ts`], sys: () => { const projectFolder = "/a/username/project"; - const file1: File = { + const file1: ts.tscWatch.File = { path: `${projectFolder}/typescript.ts`, content: "var z = 10;" }; - const environmentVariables = new Map(); - environmentVariables.set("TSC_WATCHFILE", TestFSWithWatch.Tsc_WatchFile.DynamicPolling); - return createWatchedSystem([file1, libFile], { environmentVariables }); + const environmentVariables = new ts.Map(); + environmentVariables.set("TSC_WATCHFILE", ts.TestFSWithWatch.Tsc_WatchFile.DynamicPolling); + return ts.tscWatch.createWatchedSystem([file1, ts.tscWatch.libFile], { environmentVariables }); }, changes: [ { caption: "Time spent to Transition libFile and file1 to low priority queue", - change: noop, + change: ts.noop, timeouts: (sys, programs) => { const initialProgram = programs[0][0]; - const mediumPollingIntervalThreshold = unchangedPollThresholds[PollingInterval.Medium]; + const mediumPollingIntervalThreshold = ts.unchangedPollThresholds[ts.PollingInterval.Medium]; for (let index = 0; index < mediumPollingIntervalThreshold; index++) { // Transition libFile and file1 to low priority queue sys.checkTimeoutQueueLengthAndRun(1); @@ -36,22 +36,22 @@ namespace ts.tscWatch { // Make a change to file change: sys => sys.writeFile("/a/username/project/typescript.ts", "var zz30 = 100;"), // During this timeout the file would be detected as unchanged - timeouts: checkSingleTimeoutQueueLengthAndRun, + timeouts: ts.tscWatch.checkSingleTimeoutQueueLengthAndRun, }, { caption: "Callbacks: medium priority + high priority queue and scheduled program update", - change: noop, + change: ts.noop, // Callbacks: medium priority + high priority queue and scheduled program update // This should detect change in the file timeouts: sys => sys.checkTimeoutQueueLengthAndRun(3), }, { caption: "Polling queues polled and everything is in the high polling queue", - change: noop, + change: ts.noop, timeouts: (sys, programs) => { const initialProgram = programs[0][0]; - const mediumPollingIntervalThreshold = unchangedPollThresholds[PollingInterval.Medium]; - const newThreshold = unchangedPollThresholds[PollingInterval.Low] + mediumPollingIntervalThreshold; + const mediumPollingIntervalThreshold = ts.unchangedPollThresholds[ts.PollingInterval.Medium]; + const newThreshold = ts.unchangedPollThresholds[ts.PollingInterval.Low] + mediumPollingIntervalThreshold; for (let fileUnchangeDetected = 1; fileUnchangeDetected < newThreshold; fileUnchangeDetected++) { // For high + Medium/low polling interval sys.checkTimeoutQueueLengthAndRun(2); @@ -66,12 +66,12 @@ namespace ts.tscWatch { ] }); - verifyTscWatch({ + ts.tscWatch.verifyTscWatch({ scenario, subScenario: "watchFile/using fixed chunk size polling", commandLineArgs: ["-w", "-p", "/a/b/tsconfig.json"], sys: () => { - const configFile: File = { + const configFile: ts.tscWatch.File = { path: "/a/b/tsconfig.json", content: JSON.stringify({ watchOptions: { @@ -79,13 +79,13 @@ namespace ts.tscWatch { } }) }; - const files = [libFile, commonFile1, commonFile2, configFile]; - return createWatchedSystem(files); + const files = [ts.tscWatch.libFile, ts.tscWatch.commonFile1, ts.tscWatch.commonFile2, configFile]; + return ts.tscWatch.createWatchedSystem(files); }, changes: [ { caption: "The timeout is to check the status of all files", - change: noop, + change: ts.noop, timeouts: (sys, programs) => { // On each timeout file does not change const initialProgram = programs[0][0]; @@ -98,18 +98,18 @@ namespace ts.tscWatch { { caption: "Make change to file but should detect as changed and schedule program update", // Make a change to file - change: sys => sys.writeFile(commonFile1.path, "var zz30 = 100;"), - timeouts: checkSingleTimeoutQueueLengthAndRun, + change: sys => sys.writeFile(ts.tscWatch.commonFile1.path, "var zz30 = 100;"), + timeouts: ts.tscWatch.checkSingleTimeoutQueueLengthAndRun, }, { caption: "Callbacks: queue and scheduled program update", - change: noop, + change: ts.noop, // Callbacks: scheduled program update and queue for the polling timeouts: sys => sys.checkTimeoutQueueLengthAndRun(2), }, { caption: "The timeout is to check the status of all files", - change: noop, + change: ts.noop, timeouts: (sys, programs) => { // On each timeout file does not change const initialProgram = programs[0][0]; @@ -120,30 +120,30 @@ namespace ts.tscWatch { ] }); - verifyTscWatch({ + ts.tscWatch.verifyTscWatch({ scenario, subScenario: "watchFile/setting default as fixed chunk size watch file works", commandLineArgs: ["-w", "-p", "/a/b/tsconfig.json"], sys: () => { - const configFile: File = { + const configFile: ts.tscWatch.File = { path: "/a/b/tsconfig.json", content: "{}" }; - const files = [libFile, commonFile1, commonFile2, configFile]; - const sys = createWatchedSystem(files); - sys.defaultWatchFileKind = () => WatchFileKind.FixedChunkSizePolling; + const files = [ts.tscWatch.libFile, ts.tscWatch.commonFile1, ts.tscWatch.commonFile2, configFile]; + const sys = ts.tscWatch.createWatchedSystem(files); + sys.defaultWatchFileKind = () => ts.WatchFileKind.FixedChunkSizePolling; return sys; }, changes: [ { caption: "Make change to file but should detect as changed and schedule program update", // Make a change to file - change: sys => sys.writeFile(commonFile1.path, "var zz30 = 100;"), - timeouts: checkSingleTimeoutQueueLengthAndRun, + change: sys => sys.writeFile(ts.tscWatch.commonFile1.path, "var zz30 = 100;"), + timeouts: ts.tscWatch.checkSingleTimeoutQueueLengthAndRun, }, { caption: "Callbacks: queue and scheduled program update", - change: noop, + change: ts.noop, // Callbacks: scheduled program update and queue for the polling timeouts: sys => sys.checkTimeoutQueueLengthAndRun(2), }, @@ -154,7 +154,7 @@ namespace ts.tscWatch { function verifyRenamingFileInSubFolder(subScenario: string, tscWatchDirectory: Tsc_WatchDirectory) { const projectFolder = "/a/username/project"; const projectSrcFolder = `${projectFolder}/src`; - const configFile: File = { + const configFile: ts.tscWatch.File = { path: `${projectFolder}/tsconfig.json`, content: JSON.stringify({ watchOptions: { @@ -162,19 +162,19 @@ namespace ts.tscWatch { } }) }; - const file: File = { + const file: ts.tscWatch.File = { path: `${projectSrcFolder}/file1.ts`, content: "" }; - verifyTscWatch({ + ts.tscWatch.verifyTscWatch({ scenario, subScenario: `watchDirectories/${subScenario}`, commandLineArgs: ["--w", "-p", configFile.path], sys: () => { - const files = [file, configFile, libFile]; - const environmentVariables = new Map(); + const files = [file, configFile, ts.tscWatch.libFile]; + const environmentVariables = new ts.Map(); environmentVariables.set("TSC_WATCHDIRECTORY", tscWatchDirectory); - return createWatchedSystem(files, { environmentVariables }); + return ts.tscWatch.createWatchedSystem(files, { environmentVariables }); }, changes: [ { @@ -201,76 +201,76 @@ namespace ts.tscWatch { verifyRenamingFileInSubFolder("uses non recursive dynamic polling when renaming file in subfolder", Tsc_WatchDirectory.DynamicPolling); - verifyTscWatch({ + ts.tscWatch.verifyTscWatch({ scenario, subScenario: "watchDirectories/when there are symlinks to folders in recursive folders", commandLineArgs: ["--w"], sys: () => { const cwd = "/home/user/projects/myproject"; - const file1: File = { + const file1: ts.tscWatch.File = { path: `${cwd}/src/file.ts`, content: `import * as a from "a"` }; - const tsconfig: File = { + const tsconfig: ts.tscWatch.File = { path: `${cwd}/tsconfig.json`, content: `{ "compilerOptions": { "extendedDiagnostics": true, "traceResolution": true }}` }; - const realA: File = { + const realA: ts.tscWatch.File = { path: `${cwd}/node_modules/reala/index.d.ts`, content: `export {}` }; - const realB: File = { + const realB: ts.tscWatch.File = { path: `${cwd}/node_modules/realb/index.d.ts`, content: `export {}` }; - const symLinkA: SymLink = { + const symLinkA: ts.tscWatch.SymLink = { path: `${cwd}/node_modules/a`, symLink: `${cwd}/node_modules/reala` }; - const symLinkB: SymLink = { + const symLinkB: ts.tscWatch.SymLink = { path: `${cwd}/node_modules/b`, symLink: `${cwd}/node_modules/realb` }; - const symLinkBInA: SymLink = { + const symLinkBInA: ts.tscWatch.SymLink = { path: `${cwd}/node_modules/reala/node_modules/b`, symLink: `${cwd}/node_modules/b` }; - const symLinkAInB: SymLink = { + const symLinkAInB: ts.tscWatch.SymLink = { path: `${cwd}/node_modules/realb/node_modules/a`, symLink: `${cwd}/node_modules/a` }; - const files = [libFile, file1, tsconfig, realA, realB, symLinkA, symLinkB, symLinkBInA, symLinkAInB]; - const environmentVariables = new Map(); + const files = [ts.tscWatch.libFile, file1, tsconfig, realA, realB, symLinkA, symLinkB, symLinkBInA, symLinkAInB]; + const environmentVariables = new ts.Map(); environmentVariables.set("TSC_WATCHDIRECTORY", Tsc_WatchDirectory.NonRecursiveWatchDirectory); - return createWatchedSystem(files, { environmentVariables, currentDirectory: cwd }); + return ts.tscWatch.createWatchedSystem(files, { environmentVariables, currentDirectory: cwd }); }, - changes: emptyArray + changes: ts.emptyArray }); - verifyTscWatch({ + ts.tscWatch.verifyTscWatch({ scenario, subScenario: "watchDirectories/with non synchronous watch directory", - commandLineArgs: ["--w", "-p", `${projectRoot}/tsconfig.json`], + commandLineArgs: ["--w", "-p", `${ts.tscWatch.projectRoot}/tsconfig.json`], sys: () => { - const configFile: File = { - path: `${projectRoot}/tsconfig.json`, + const configFile: ts.tscWatch.File = { + path: `${ts.tscWatch.projectRoot}/tsconfig.json`, content: "{}" }; - const file1: File = { - path: `${projectRoot}/src/file1.ts`, + const file1: ts.tscWatch.File = { + path: `${ts.tscWatch.projectRoot}/src/file1.ts`, content: `import { x } from "file2";` }; - const file2: File = { - path: `${projectRoot}/node_modules/file2/index.d.ts`, + const file2: ts.tscWatch.File = { + path: `${ts.tscWatch.projectRoot}/node_modules/file2/index.d.ts`, content: `export const x = 10;` }; - const files = [libFile, file1, file2, configFile]; - return createWatchedSystem(files, { runWithoutRecursiveWatches: true }); + const files = [ts.tscWatch.libFile, file1, file2, configFile]; + return ts.tscWatch.createWatchedSystem(files, { runWithoutRecursiveWatches: true }); }, changes: [ { caption: "Directory watch updates because of file1.js creation", - change: noop, + change: ts.noop, timeouts: sys => { sys.checkTimeoutQueueLengthAndRun(1); // To update directory callbacks for file1.js output sys.checkTimeoutQueueLength(0); @@ -279,7 +279,7 @@ namespace ts.tscWatch { { caption: "Remove directory node_modules", // Remove directory node_modules - change: sys => sys.deleteFolder(`${projectRoot}/node_modules`, /*recursive*/ true), + change: sys => sys.deleteFolder(`${ts.tscWatch.projectRoot}/node_modules`, /*recursive*/ true), timeouts: sys => { sys.checkTimeoutQueueLength(3); // 1. Failed lookup invalidation 2. For updating program and 3. for updating child watches sys.runQueuedTimeoutCallbacks(sys.getNextTimeoutId() - 2); // Update program @@ -287,7 +287,7 @@ namespace ts.tscWatch { }, { caption: "Pending directory watchers and program update", - change: noop, + change: ts.noop, timeouts: sys => { sys.checkTimeoutQueueLengthAndRun(1); // To update directory watchers sys.checkTimeoutQueueLengthAndRun(2); // To Update program and failed lookup update @@ -298,22 +298,22 @@ namespace ts.tscWatch { { caption: "Start npm install", // npm install - change: sys => sys.createDirectory(`${projectRoot}/node_modules`), + change: sys => sys.createDirectory(`${ts.tscWatch.projectRoot}/node_modules`), timeouts: sys => sys.checkTimeoutQueueLength(1), // To update folder structure }, { caption: "npm install folder creation of file2", - change: sys => sys.createDirectory(`${projectRoot}/node_modules/file2`), + change: sys => sys.createDirectory(`${ts.tscWatch.projectRoot}/node_modules/file2`), timeouts: sys => sys.checkTimeoutQueueLength(1), // To update folder structure }, { caption: "npm install index file in file2", - change: sys => sys.writeFile(`${projectRoot}/node_modules/file2/index.d.ts`, `export const x = 10;`), + change: sys => sys.writeFile(`${ts.tscWatch.projectRoot}/node_modules/file2/index.d.ts`, `export const x = 10;`), timeouts: sys => sys.checkTimeoutQueueLength(1), // To update folder structure }, { caption: "Updates the program", - change: noop, + change: ts.noop, timeouts: sys => { sys.runQueuedTimeoutCallbacks(); sys.checkTimeoutQueueLength(2); // To Update program and failed lookup update @@ -321,7 +321,7 @@ namespace ts.tscWatch { }, { caption: "Invalidates module resolution cache", - change: noop, + change: ts.noop, timeouts: sys => { sys.runQueuedTimeoutCallbacks(); sys.checkTimeoutQueueLength(1); // To Update program @@ -329,7 +329,7 @@ namespace ts.tscWatch { }, { caption: "Pending updates", - change: noop, + change: ts.noop, timeouts: sys => { sys.runQueuedTimeoutCallbacks(); sys.checkTimeoutQueueLength(0); @@ -338,72 +338,72 @@ namespace ts.tscWatch { ], }); - verifyTscWatch({ + ts.tscWatch.verifyTscWatch({ scenario, subScenario: "watchDirectories/with non synchronous watch directory with outDir and declaration enabled", - commandLineArgs: ["--w", "-p", `${projectRoot}/tsconfig.json`], + commandLineArgs: ["--w", "-p", `${ts.tscWatch.projectRoot}/tsconfig.json`], sys: () => { - const configFile: File = { - path: `${projectRoot}/tsconfig.json`, + const configFile: ts.tscWatch.File = { + path: `${ts.tscWatch.projectRoot}/tsconfig.json`, content: JSON.stringify({ compilerOptions: { outDir: "dist", declaration: true } }) }; - const file1: File = { - path: `${projectRoot}/src/file1.ts`, + const file1: ts.tscWatch.File = { + path: `${ts.tscWatch.projectRoot}/src/file1.ts`, content: `import { x } from "file2";` }; - const file2: File = { - path: `${projectRoot}/node_modules/file2/index.d.ts`, + const file2: ts.tscWatch.File = { + path: `${ts.tscWatch.projectRoot}/node_modules/file2/index.d.ts`, content: `export const x = 10;` }; - const files = [libFile, file1, file2, configFile]; - return createWatchedSystem(files, { runWithoutRecursiveWatches: true }); + const files = [ts.tscWatch.libFile, file1, file2, configFile]; + return ts.tscWatch.createWatchedSystem(files, { runWithoutRecursiveWatches: true }); }, changes: [ - noopChange, + ts.tscWatch.noopChange, { caption: "Add new file, should schedule and run timeout to update directory watcher", - change: sys => sys.writeFile(`${projectRoot}/src/file3.ts`, `export const y = 10;`), - timeouts: checkSingleTimeoutQueueLengthAndRun, // Update the child watch + change: sys => sys.writeFile(`${ts.tscWatch.projectRoot}/src/file3.ts`, `export const y = 10;`), + timeouts: ts.tscWatch.checkSingleTimeoutQueueLengthAndRun, // Update the child watch }, { caption: "Actual program update to include new file", - change: noop, + change: ts.noop, timeouts: sys => sys.checkTimeoutQueueLengthAndRun(2), // Scheduling failed lookup update and program update }, { caption: "After program emit with new file, should schedule and run timeout to update directory watcher", - change: noop, - timeouts: checkSingleTimeoutQueueLengthAndRun, // Update the child watch + change: ts.noop, + timeouts: ts.tscWatch.checkSingleTimeoutQueueLengthAndRun, // Update the child watch }, - noopChange, + ts.tscWatch.noopChange, ], }); - verifyTscWatch({ + ts.tscWatch.verifyTscWatch({ scenario, subScenario: "watchDirectories/with non synchronous watch directory renaming a file", - commandLineArgs: ["--w", "-p", `${projectRoot}/tsconfig.json`], + commandLineArgs: ["--w", "-p", `${ts.tscWatch.projectRoot}/tsconfig.json`], sys: () => { - const configFile: File = { - path: `${projectRoot}/tsconfig.json`, + const configFile: ts.tscWatch.File = { + path: `${ts.tscWatch.projectRoot}/tsconfig.json`, content: JSON.stringify({ compilerOptions: { outDir: "dist" } }) }; - const file1: File = { - path: `${projectRoot}/src/file1.ts`, + const file1: ts.tscWatch.File = { + path: `${ts.tscWatch.projectRoot}/src/file1.ts`, content: `import { x } from "./file2";` }; - const file2: File = { - path: `${projectRoot}/src/file2.ts`, + const file2: ts.tscWatch.File = { + path: `${ts.tscWatch.projectRoot}/src/file2.ts`, content: `export const x = 10;` }; - const files = [libFile, file1, file2, configFile]; - return createWatchedSystem(files, { runWithoutRecursiveWatches: true }); + const files = [ts.tscWatch.libFile, file1, file2, configFile]; + return ts.tscWatch.createWatchedSystem(files, { runWithoutRecursiveWatches: true }); }, changes: [ - noopChange, + ts.tscWatch.noopChange, { caption: "rename the file", - change: sys => sys.renameFile(`${projectRoot}/src/file2.ts`, `${projectRoot}/src/renamed.ts`), + change: sys => sys.renameFile(`${ts.tscWatch.projectRoot}/src/file2.ts`, `${ts.tscWatch.projectRoot}/src/renamed.ts`), timeouts: sys => { sys.checkTimeoutQueueLength(2); // 1. For updating program and 2. for updating child watches sys.runQueuedTimeoutCallbacks(1); // Update program @@ -411,7 +411,7 @@ namespace ts.tscWatch { }, { caption: "Pending directory watchers and program update", - change: noop, + change: ts.noop, timeouts: sys => { sys.checkTimeoutQueueLengthAndRun(1); // To update directory watchers sys.checkTimeoutQueueLengthAndRun(2); // To Update program and failed lookup update @@ -424,12 +424,12 @@ namespace ts.tscWatch { }); describe("handles watch compiler options", () => { - verifyTscWatch({ + ts.tscWatch.verifyTscWatch({ scenario, subScenario: "watchOptions/with watchFile option", commandLineArgs: ["-w", "-p", "/a/b/tsconfig.json"], sys: () => { - const configFile: File = { + const configFile: ts.tscWatch.File = { path: "/a/b/tsconfig.json", content: JSON.stringify({ watchOptions: { @@ -437,18 +437,18 @@ namespace ts.tscWatch { } }) }; - const files = [libFile, commonFile1, commonFile2, configFile]; - return createWatchedSystem(files); + const files = [ts.tscWatch.libFile, ts.tscWatch.commonFile1, ts.tscWatch.commonFile2, configFile]; + return ts.tscWatch.createWatchedSystem(files); }, - changes: emptyArray + changes: ts.emptyArray }); - verifyTscWatch({ + ts.tscWatch.verifyTscWatch({ scenario, subScenario: "watchOptions/with watchDirectory option", commandLineArgs: ["-w", "-p", "/a/b/tsconfig.json"], sys: () => { - const configFile: File = { + const configFile: ts.tscWatch.File = { path: "/a/b/tsconfig.json", content: JSON.stringify({ watchOptions: { @@ -456,18 +456,18 @@ namespace ts.tscWatch { } }) }; - const files = [libFile, commonFile1, commonFile2, configFile]; - return createWatchedSystem(files, { runWithoutRecursiveWatches: true }); + const files = [ts.tscWatch.libFile, ts.tscWatch.commonFile1, ts.tscWatch.commonFile2, configFile]; + return ts.tscWatch.createWatchedSystem(files, { runWithoutRecursiveWatches: true }); }, - changes: emptyArray + changes: ts.emptyArray }); - verifyTscWatch({ + ts.tscWatch.verifyTscWatch({ scenario, subScenario: "watchOptions/with fallbackPolling option", commandLineArgs: ["-w", "-p", "/a/b/tsconfig.json"], sys: () => { - const configFile: File = { + const configFile: ts.tscWatch.File = { path: "/a/b/tsconfig.json", content: JSON.stringify({ watchOptions: { @@ -475,59 +475,59 @@ namespace ts.tscWatch { } }) }; - const files = [libFile, commonFile1, commonFile2, configFile]; - return createWatchedSystem(files, { runWithoutRecursiveWatches: true, runWithFallbackPolling: true }); + const files = [ts.tscWatch.libFile, ts.tscWatch.commonFile1, ts.tscWatch.commonFile2, configFile]; + return ts.tscWatch.createWatchedSystem(files, { runWithoutRecursiveWatches: true, runWithFallbackPolling: true }); }, - changes: emptyArray + changes: ts.emptyArray }); - verifyTscWatch({ + ts.tscWatch.verifyTscWatch({ scenario, subScenario: "watchOptions/with watchFile as watch options to extend", commandLineArgs: ["-w", "-p", "/a/b/tsconfig.json", "--watchFile", "UseFsEvents"], sys: () => { - const configFile: File = { + const configFile: ts.tscWatch.File = { path: "/a/b/tsconfig.json", content: "{}" }; - const files = [libFile, commonFile1, commonFile2, configFile]; - return createWatchedSystem(files); + const files = [ts.tscWatch.libFile, ts.tscWatch.commonFile1, ts.tscWatch.commonFile2, configFile]; + return ts.tscWatch.createWatchedSystem(files); }, - changes: emptyArray + changes: ts.emptyArray }); describe("exclude options", () => { - function sys(watchOptions: WatchOptions, runWithoutRecursiveWatches?: boolean): WatchedSystem { - const configFile: File = { - path: `${projectRoot}/tsconfig.json`, + function sys(watchOptions: ts.WatchOptions, runWithoutRecursiveWatches?: boolean): ts.tscWatch.WatchedSystem { + const configFile: ts.tscWatch.File = { + path: `${ts.tscWatch.projectRoot}/tsconfig.json`, content: JSON.stringify({ exclude: ["node_modules"], watchOptions }) }; - const main: File = { - path: `${projectRoot}/src/main.ts`, + const main: ts.tscWatch.File = { + path: `${ts.tscWatch.projectRoot}/src/main.ts`, content: `import { foo } from "bar"; foo();` }; - const bar: File = { - path: `${projectRoot}/node_modules/bar/index.d.ts`, + const bar: ts.tscWatch.File = { + path: `${ts.tscWatch.projectRoot}/node_modules/bar/index.d.ts`, content: `export { foo } from "./foo";` }; - const foo: File = { - path: `${projectRoot}/node_modules/bar/foo.d.ts`, + const foo: ts.tscWatch.File = { + path: `${ts.tscWatch.projectRoot}/node_modules/bar/foo.d.ts`, content: `export function foo(): string;` }; - const fooBar: File = { - path: `${projectRoot}/node_modules/bar/fooBar.d.ts`, + const fooBar: ts.tscWatch.File = { + path: `${ts.tscWatch.projectRoot}/node_modules/bar/fooBar.d.ts`, content: `export function fooBar(): string;` }; - const temp: File = { - path: `${projectRoot}/node_modules/bar/temp/index.d.ts`, + const temp: ts.tscWatch.File = { + path: `${ts.tscWatch.projectRoot}/node_modules/bar/temp/index.d.ts`, content: "export function temp(): string;" }; - const files = [libFile, main, bar, foo, fooBar, temp, configFile]; - return createWatchedSystem(files, { currentDirectory: projectRoot, runWithoutRecursiveWatches }); + const files = [ts.tscWatch.libFile, main, bar, foo, fooBar, temp, configFile]; + return ts.tscWatch.createWatchedSystem(files, { currentDirectory: ts.tscWatch.projectRoot, runWithoutRecursiveWatches }); } function verifyWorker(...additionalFlags: string[]) { - verifyTscWatch({ + ts.tscWatch.verifyTscWatch({ scenario, subScenario: `watchOptions/with excludeFiles option${additionalFlags.join("")}`, commandLineArgs: ["-w", ...additionalFlags], @@ -535,13 +535,13 @@ namespace ts.tscWatch { changes: [ { caption: "Change foo", - change: sys => replaceFileText(sys, `${projectRoot}/node_modules/bar/foo.d.ts`, "foo", "fooBar"), + change: sys => ts.tscWatch.replaceFileText(sys, `${ts.tscWatch.projectRoot}/node_modules/bar/foo.d.ts`, "foo", "fooBar"), timeouts: sys => sys.checkTimeoutQueueLength(0), } ] }); - verifyTscWatch({ + ts.tscWatch.verifyTscWatch({ scenario, subScenario: `watchOptions/with excludeDirectories option${additionalFlags.join("")}`, commandLineArgs: ["-w", ...additionalFlags], @@ -549,12 +549,13 @@ namespace ts.tscWatch { changes: [ { caption: "delete fooBar", - change: sys => sys.deleteFile(`${projectRoot}/node_modules/bar/fooBar.d.ts`), - timeouts: sys => sys.checkTimeoutQueueLength(0), } + change: sys => sys.deleteFile(`${ts.tscWatch.projectRoot}/node_modules/bar/fooBar.d.ts`), + timeouts: sys => sys.checkTimeoutQueueLength(0), + } ] }); - verifyTscWatch({ + ts.tscWatch.verifyTscWatch({ scenario, subScenario: `watchOptions/with excludeDirectories option with recursive directory watching${additionalFlags.join("")}`, commandLineArgs: ["-w", ...additionalFlags], @@ -562,7 +563,7 @@ namespace ts.tscWatch { changes: [ { caption: "Directory watch updates because of main.js creation", - change: noop, + change: ts.noop, timeouts: sys => { sys.checkTimeoutQueueLengthAndRun(1); // To update directory callbacks for main.js output sys.checkTimeoutQueueLength(0); @@ -570,7 +571,7 @@ namespace ts.tscWatch { }, { caption: "add new folder to temp", - change: sys => sys.ensureFileOrFolder({ path: `${projectRoot}/node_modules/bar/temp/fooBar/index.d.ts`, content: "export function temp(): string;" }), + change: sys => sys.ensureFileOrFolder({ path: `${ts.tscWatch.projectRoot}/node_modules/bar/temp/fooBar/index.d.ts`, content: "export function temp(): string;" }), timeouts: sys => sys.checkTimeoutQueueLength(0), } ] diff --git a/src/testRunner/unittests/tsserver/applyChangesToOpenFiles.ts b/src/testRunner/unittests/tsserver/applyChangesToOpenFiles.ts index 6d5ee91d68d67..8eb242e6c8ee1 100644 --- a/src/testRunner/unittests/tsserver/applyChangesToOpenFiles.ts +++ b/src/testRunner/unittests/tsserver/applyChangesToOpenFiles.ts @@ -1,51 +1,51 @@ namespace ts.projectSystem { describe("unittests:: tsserver:: applyChangesToOpenFiles", () => { - const configFile: File = { + const configFile: ts.projectSystem.File = { path: "/a/b/tsconfig.json", content: "{}" }; - const file3: File = { + const file3: ts.projectSystem.File = { path: "/a/b/file3.ts", content: "let xyz = 1;" }; - const app: File = { + const app: ts.projectSystem.File = { path: "/a/b/app.ts", content: "let z = 1;" }; - function fileContentWithComment(file: File) { + function fileContentWithComment(file: ts.projectSystem.File) { return `// some copy right notice ${file.content}`; } - function verifyText(service: server.ProjectService, file: string, expected: string) { + function verifyText(service: ts.server.ProjectService, file: string, expected: string) { const info = service.getScriptInfo(file)!; const snap = info.getSnapshot(); // Verified applied in reverse order assert.equal(snap.getText(0, snap.getLength()), expected, `Text of changed file: ${file}`); } - function verifyProjectVersion(project: server.Project, expected: number) { + function verifyProjectVersion(project: ts.server.Project, expected: number) { assert.equal(Number(project.getProjectVersion()), expected); } interface Verify { - applyChangesToOpen: (session: TestSession) => void; - openFile1Again: (session: TestSession) => void; + applyChangesToOpen: (session: ts.projectSystem.TestSession) => void; + openFile1Again: (session: ts.projectSystem.TestSession) => void; } function verify({ applyChangesToOpen, openFile1Again }: Verify) { - const host = createServerHost([app, file3, commonFile1, commonFile2, libFile, configFile]); - const session = createSession(host); - session.executeCommandSeq({ - command: protocol.CommandTypes.Open, + const host = ts.projectSystem.createServerHost([app, file3, ts.projectSystem.commonFile1, ts.projectSystem.commonFile2, ts.projectSystem.libFile, configFile]); + const session = ts.projectSystem.createSession(host); + session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.Open, arguments: { file: app.path } }); const service = session.getProjectService(); const project = service.configuredProjects.get(configFile.path)!; assert.isDefined(project); verifyProjectVersion(project, 1); - session.executeCommandSeq({ - command: protocol.CommandTypes.Open, + session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.Open, arguments: { file: file3.path, fileContent: fileContentWithComment(file3) @@ -54,8 +54,8 @@ ${file.content}`; verifyProjectVersion(project, 2); // Verify Texts - verifyText(service, commonFile1.path, commonFile1.content); - verifyText(service, commonFile2.path, commonFile2.content); + verifyText(service, ts.projectSystem.commonFile1.path, ts.projectSystem.commonFile1.content); + verifyText(service, ts.projectSystem.commonFile2.path, ts.projectSystem.commonFile2.content); verifyText(service, app.path, app.content); verifyText(service, file3.path, fileContentWithComment(file3)); @@ -65,36 +65,36 @@ ${file.content}`; // Verify again verifyProjectVersion(project, 3); // Open file contents - verifyText(service, commonFile1.path, fileContentWithComment(commonFile1)); - verifyText(service, commonFile2.path, fileContentWithComment(commonFile2)); + verifyText(service, ts.projectSystem.commonFile1.path, fileContentWithComment(ts.projectSystem.commonFile1)); + verifyText(service, ts.projectSystem.commonFile2.path, fileContentWithComment(ts.projectSystem.commonFile2)); verifyText(service, app.path, "let zzz = 10;let zz = 10;let z = 1;"); verifyText(service, file3.path, file3.content); // Open file1 again openFile1Again(session); - assert.isTrue(service.getScriptInfo(commonFile1.path)!.isScriptOpen()); + assert.isTrue(service.getScriptInfo(ts.projectSystem.commonFile1.path)!.isScriptOpen()); // Verify that file1 contents are changed verifyProjectVersion(project, 4); - verifyText(service, commonFile1.path, commonFile1.content); - verifyText(service, commonFile2.path, fileContentWithComment(commonFile2)); + verifyText(service, ts.projectSystem.commonFile1.path, ts.projectSystem.commonFile1.content); + verifyText(service, ts.projectSystem.commonFile2.path, fileContentWithComment(ts.projectSystem.commonFile2)); verifyText(service, app.path, "let zzz = 10;let zz = 10;let z = 1;"); verifyText(service, file3.path, file3.content); } it("with applyChangedToOpenFiles request", () => { verify({ - applyChangesToOpen: session => session.executeCommandSeq({ - command: protocol.CommandTypes.ApplyChangedToOpenFiles, + applyChangesToOpen: session => session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.ApplyChangedToOpenFiles, arguments: { openFiles: [ { - fileName: commonFile1.path, - content: fileContentWithComment(commonFile1) + fileName: ts.projectSystem.commonFile1.path, + content: fileContentWithComment(ts.projectSystem.commonFile1) }, { - fileName: commonFile2.path, - content: fileContentWithComment(commonFile2) + fileName: ts.projectSystem.commonFile2.path, + content: fileContentWithComment(ts.projectSystem.commonFile2) } ], changedFiles: [ @@ -117,12 +117,12 @@ ${file.content}`; ] } }), - openFile1Again: session => session.executeCommandSeq({ - command: protocol.CommandTypes.ApplyChangedToOpenFiles, + openFile1Again: session => session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.ApplyChangedToOpenFiles, arguments: { openFiles: [{ - fileName: commonFile1.path, - content: commonFile1.content + fileName: ts.projectSystem.commonFile1.path, + content: ts.projectSystem.commonFile1.content }] } }), @@ -131,17 +131,17 @@ ${file.content}`; it("with updateOpen request", () => { verify({ - applyChangesToOpen: session => session.executeCommandSeq({ - command: protocol.CommandTypes.UpdateOpen, + applyChangesToOpen: session => session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.UpdateOpen, arguments: { openFiles: [ { - file: commonFile1.path, - fileContent: fileContentWithComment(commonFile1) + file: ts.projectSystem.commonFile1.path, + fileContent: fileContentWithComment(ts.projectSystem.commonFile1) }, { - file: commonFile2.path, - fileContent: fileContentWithComment(commonFile2) + file: ts.projectSystem.commonFile2.path, + fileContent: fileContentWithComment(ts.projectSystem.commonFile2) } ], changedFiles: [ @@ -166,12 +166,12 @@ ${file.content}`; ] } }), - openFile1Again: session => session.executeCommandSeq({ - command: protocol.CommandTypes.UpdateOpen, + openFile1Again: session => session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.UpdateOpen, arguments: { openFiles: [{ - file: commonFile1.path, - fileContent: commonFile1.content + file: ts.projectSystem.commonFile1.path, + fileContent: ts.projectSystem.commonFile1.content }] } }), diff --git a/src/testRunner/unittests/tsserver/autoImportProvider.ts b/src/testRunner/unittests/tsserver/autoImportProvider.ts index f05d06f484237..b7edce1e0a602 100644 --- a/src/testRunner/unittests/tsserver/autoImportProvider.ts +++ b/src/testRunner/unittests/tsserver/autoImportProvider.ts @@ -1,29 +1,29 @@ namespace ts.projectSystem { - const angularFormsDts: File = { + const angularFormsDts: ts.projectSystem.File = { path: "/node_modules/@angular/forms/forms.d.ts", content: "export declare class PatternValidator {}", }; - const angularFormsPackageJson: File = { + const angularFormsPackageJson: ts.projectSystem.File = { path: "/node_modules/@angular/forms/package.json", content: `{ "name": "@angular/forms", "typings": "./forms.d.ts" }`, }; - const angularCoreDts: File = { + const angularCoreDts: ts.projectSystem.File = { path: "/node_modules/@angular/core/core.d.ts", content: "", }; - const angularCorePackageJson: File = { + const angularCorePackageJson: ts.projectSystem.File = { path: "/node_modules/@angular/core/package.json", content: `{ "name": "@angular/core", "typings": "./core.d.ts" }`, }; - const tsconfig: File = { + const tsconfig: ts.projectSystem.File = { path: "/tsconfig.json", content: `{ "compilerOptions": { "module": "commonjs" } }`, }; - const packageJson: File = { + const packageJson: ts.projectSystem.File = { path: "/package.json", content: `{ "dependencies": { "@angular/forms": "*", "@angular/core": "*" } }` }; - const indexTs: File = { + const indexTs: ts.projectSystem.File = { path: "/index.ts", content: "" }; @@ -37,7 +37,7 @@ namespace ts.projectSystem { { path: packageJson.path, content: `{ "dependencies": {} }` }, indexTs ]); - openFilesForSession([indexTs], session); + ts.projectSystem.openFilesForSession([indexTs], session); assert.isUndefined(projectService.configuredProjects.get(tsconfig.path)!.getLanguageService().getAutoImportProvider()); }); @@ -49,7 +49,7 @@ namespace ts.projectSystem { packageJson, { path: indexTs.path, content: "import '@angular/forms';" } ]); - openFilesForSession([indexTs], session); + ts.projectSystem.openFilesForSession([indexTs], session); assert.isUndefined(projectService.configuredProjects.get(tsconfig.path)!.getLanguageService().getAutoImportProvider()); }); @@ -63,28 +63,24 @@ namespace ts.projectSystem { { path: "/node_modules/@angular/core/core.d.ts", content: `export namespace angular {};` }, ]); - openFilesForSession([angularFormsDts], session); - checkNumberOfInferredProjects(projectService, 1); - checkNumberOfConfiguredProjects(projectService, 0); + ts.projectSystem.openFilesForSession([angularFormsDts], session); + ts.projectSystem.checkNumberOfInferredProjects(projectService, 1); + ts.projectSystem.checkNumberOfConfiguredProjects(projectService, 0); assert.isUndefined(projectService - .getDefaultProjectForFile(angularFormsDts.path as server.NormalizedPath, /*ensureProject*/ true)! + .getDefaultProjectForFile(angularFormsDts.path as ts.server.NormalizedPath, /*ensureProject*/ true)! .getLanguageService() .getAutoImportProvider()); }); it("Auto-importable file is in inferred project until imported", () => { const { projectService, session, updateFile } = setup([angularFormsDts, angularFormsPackageJson, tsconfig, packageJson, indexTs]); - checkNumberOfInferredProjects(projectService, 0); - openFilesForSession([angularFormsDts], session); - checkNumberOfInferredProjects(projectService, 1); - assert.equal( - projectService.getDefaultProjectForFile(angularFormsDts.path as server.NormalizedPath, /*ensureProject*/ true)?.projectKind, - server.ProjectKind.Inferred); + ts.projectSystem.checkNumberOfInferredProjects(projectService, 0); + ts.projectSystem.openFilesForSession([angularFormsDts], session); + ts.projectSystem.checkNumberOfInferredProjects(projectService, 1); + assert.equal(projectService.getDefaultProjectForFile(angularFormsDts.path as ts.server.NormalizedPath, /*ensureProject*/ true)?.projectKind, ts.server.ProjectKind.Inferred); updateFile(indexTs.path, "import '@angular/forms'"); - assert.equal( - projectService.getDefaultProjectForFile(angularFormsDts.path as server.NormalizedPath, /*ensureProject*/ true)?.projectKind, - server.ProjectKind.Configured); + assert.equal(projectService.getDefaultProjectForFile(angularFormsDts.path as ts.server.NormalizedPath, /*ensureProject*/ true)?.projectKind, ts.server.ProjectKind.Configured); assert.isUndefined(projectService.configuredProjects.get(tsconfig.path)!.getLanguageService().getAutoImportProvider()); }); @@ -98,7 +94,7 @@ namespace ts.projectSystem { indexTs ]); - openFilesForSession([indexTs], session); + ts.projectSystem.openFilesForSession([indexTs], session); assert.isUndefined(projectService.configuredProjects.get(tsconfig.path)!.getLanguageService().getAutoImportProvider()); host.writeFile(packageJson.path, packageJson.content); @@ -114,14 +110,12 @@ namespace ts.projectSystem { indexTs ]); - openFilesForSession([indexTs], session); + ts.projectSystem.openFilesForSession([indexTs], session); const autoImportProvider = projectService.configuredProjects.get(tsconfig.path)!.getLanguageService().getAutoImportProvider(); assert.ok(autoImportProvider); updateFile(indexTs.path, "console.log(0)"); - assert.strictEqual( - projectService.configuredProjects.get(tsconfig.path)!.getLanguageService().getAutoImportProvider(), - autoImportProvider); + assert.strictEqual(projectService.configuredProjects.get(tsconfig.path)!.getLanguageService().getAutoImportProvider(), autoImportProvider); }); it("Closes AutoImportProviderProject when host project closes", () => { @@ -133,7 +127,7 @@ namespace ts.projectSystem { indexTs ]); - openFilesForSession([indexTs], session); + ts.projectSystem.openFilesForSession([indexTs], session); const hostProject = projectService.configuredProjects.get(tsconfig.path)!; hostProject.getPackageJsonAutoImportProvider(); const autoImportProviderProject = hostProject.autoImportProviderHost; @@ -153,7 +147,7 @@ namespace ts.projectSystem { ]); // Create configured project only, ensure !projectService.pendingEnsureProjectForOpenFiles - openFilesForSession([indexTs], session); + ts.projectSystem.openFilesForSession([indexTs], session); const hostProject = projectService.configuredProjects.get(tsconfig.path)!; projectService.delayEnsureProjectForOpenFiles(); host.runQueuedTimeoutCallbacks(); @@ -176,7 +170,7 @@ namespace ts.projectSystem { indexTs ]); - openFilesForSession([indexTs], session); + ts.projectSystem.openFilesForSession([indexTs], session); const project = projectService.configuredProjects.get(tsconfig.path)!; const completionsBefore = project.getLanguageService().getCompletionsAtPosition(indexTs.path, 0, { includeCompletionsForModuleExports: true }); assert.isTrue(completionsBefore?.entries.some(c => c.name === "PatternValidator")); @@ -203,7 +197,7 @@ namespace ts.projectSystem { indexTs ]); - openFilesForSession([indexTs, angularFormsDts], session); + ts.projectSystem.openFilesForSession([indexTs, angularFormsDts], session); const project = projectService.configuredProjects.get(tsconfig.path)!; const completionsBefore = project.getLanguageService().getCompletionsAtPosition(indexTs.path, 0, { includeCompletionsForModuleExports: true }); assert.isTrue(completionsBefore?.entries.some(c => c.name === "PatternValidator")); @@ -223,7 +217,7 @@ namespace ts.projectSystem { indexTs ]); - openFilesForSession([indexTs], session); + ts.projectSystem.openFilesForSession([indexTs], session); assert.isUndefined(projectService.configuredProjects.get(tsconfig.path)!.getLanguageService().getAutoImportProvider()); host.writeFile(packageJson.path, packageJson.content); @@ -231,7 +225,7 @@ namespace ts.projectSystem { }); it("Does not create an auto import provider if there are too many dependencies", () => { - const createPackage = (i: number): File[] => ([ + const createPackage = (i: number): ts.projectSystem.File[] => ([ { path: `/node_modules/package${i}/package.json`, content: `{ "name": "package${i}" }` }, { path: `/node_modules/package${i}/index.d.ts`, content: `` } ]); @@ -242,10 +236,9 @@ namespace ts.projectSystem { } const dependencies = packages.reduce((hash, p) => ({ ...hash, [JSON.parse(p[0].content).name]: "*" }), {}); - const packageJson: File = { path: "/package.json", content: JSON.stringify(dependencies) }; - const { projectService, session } = setup([ ...flatten(packages), indexTs, tsconfig, packageJson ]); - - openFilesForSession([indexTs], session); + const packageJson: ts.projectSystem.File = { path: "/package.json", content: JSON.stringify(dependencies) }; + const { projectService, session } = setup([...ts.flatten(packages), indexTs, tsconfig, packageJson]); + ts.projectSystem.openFilesForSession([indexTs], session); const project = projectService.configuredProjects.get(tsconfig.path)!; assert.isUndefined(project.getPackageJsonAutoImportProvider()); }); @@ -275,10 +268,10 @@ namespace ts.projectSystem { const { projectService, session, findAllReferences } = setup(files); - openFilesForSession([files.find(f => f.path === "/packages/b/index.ts")!], session); - checkNumberOfConfiguredProjects(projectService, 2); // Solution (no files), B + ts.projectSystem.openFilesForSession([files.find(f => f.path === "/packages/b/index.ts")!], session); + ts.projectSystem.checkNumberOfConfiguredProjects(projectService, 2); // Solution (no files), B findAllReferences("/packages/b/index.ts", 1, "export class B".length - 1); - checkNumberOfConfiguredProjects(projectService, 3); // Solution (no files), A, B + ts.projectSystem.checkNumberOfConfiguredProjects(projectService, 3); // Solution (no files), A, B // Project for A is created - ensure it doesn't have an autoImportProvider assert.isUndefined(projectService.configuredProjects.get("/packages/a/tsconfig.json")!.getLanguageService().getAutoImportProvider()); @@ -298,24 +291,21 @@ namespace ts.projectSystem { ]; const { projectService, session } = setup(files); - openFilesForSession([files[2]], session); + ts.projectSystem.openFilesForSession([files[2]], session); assert.isDefined(projectService.configuredProjects.get("/packages/a/tsconfig.json")!.getPackageJsonAutoImportProvider()); assert.isDefined(projectService.configuredProjects.get("/packages/a/tsconfig.json")!.getPackageJsonAutoImportProvider()); }); it("Can use the same document registry bucket key as main program", () => { - for (const option of sourceFileAffectingCompilerOptions) { - assert( - !hasProperty(server.AutoImportProviderProject.compilerOptionsOverrides, option.name), - `'${option.name}' may cause AutoImportProviderProject not to share source files with main program` - ); + for (const option of ts.sourceFileAffectingCompilerOptions) { + assert(!ts.hasProperty(ts.server.AutoImportProviderProject.compilerOptionsOverrides, option.name), `'${option.name}' may cause AutoImportProviderProject not to share source files with main program`); } }); }); - function setup(files: File[]) { - const host = createServerHost(files); - const session = createSession(host); + function setup(files: ts.projectSystem.File[]) { + const host = ts.projectSystem.createServerHost(files); + const session = ts.projectSystem.createSession(host); const projectService = session.getProjectService(); return { host, @@ -326,9 +316,9 @@ namespace ts.projectSystem { }; function updateFile(path: string, newText: string) { - Debug.assertIsDefined(files.find(f => f.path === path)); - session.executeCommandSeq({ - command: protocol.CommandTypes.ApplyChangedToOpenFiles, + ts.Debug.assertIsDefined(files.find(f => f.path === path)); + session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.ApplyChangedToOpenFiles, arguments: { openFiles: [{ fileName: path, @@ -339,9 +329,9 @@ namespace ts.projectSystem { } function findAllReferences(file: string, line: number, offset: number) { - Debug.assertIsDefined(files.find(f => f.path === file)); - session.executeCommandSeq({ - command: protocol.CommandTypes.References, + ts.Debug.assertIsDefined(files.find(f => f.path === file)); + session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.References, arguments: { file, line, diff --git a/src/testRunner/unittests/tsserver/auxiliaryProject.ts b/src/testRunner/unittests/tsserver/auxiliaryProject.ts index 4b5f865c19aeb..1dc1d3c9a5320 100644 --- a/src/testRunner/unittests/tsserver/auxiliaryProject.ts +++ b/src/testRunner/unittests/tsserver/auxiliaryProject.ts @@ -1,25 +1,25 @@ namespace ts.projectSystem { - const aTs: File = { + const aTs: ts.projectSystem.File = { path: "/a.ts", content: `import { B } from "./b";` }; - const bDts: File = { + const bDts: ts.projectSystem.File = { path: "/b.d.ts", content: `export declare class B {}` }; - const bJs: File = { + const bJs: ts.projectSystem.File = { path: "/b.js", content: `export class B {}` }; describe("unittests:: tsserver:: auxiliaryProject", () => { it("AuxiliaryProject does not remove scrips from InferredProject", () => { - const host = createServerHost([aTs, bDts, bJs]); - const session = createSession(host); + const host = ts.projectSystem.createServerHost([aTs, bDts, bJs]); + const session = ts.projectSystem.createSession(host); const projectService = session.getProjectService(); - openFilesForSession([aTs], session); + ts.projectSystem.openFilesForSession([aTs], session); // Open file is in inferred project - checkNumberOfInferredProjects(projectService, 1); + ts.projectSystem.checkNumberOfInferredProjects(projectService, 1); const inferredProject = projectService.inferredProjects[0]; // getNoDtsResolutionProject will create an AuxiliaryProject with a.ts and b.js @@ -30,7 +30,7 @@ namespace ts.projectSystem { // The AuxiliaryProject should never be the default project for anything, so // the ScriptInfo should still report being an orphan, and getting its default // project should throw. - const bJsScriptInfo = Debug.checkDefined(projectService.getScriptInfo(bJs.path)); + const bJsScriptInfo = ts.Debug.checkDefined(projectService.getScriptInfo(bJs.path)); assert(bJsScriptInfo.isOrphan()); assert(bJsScriptInfo.isContainedByBackgroundProject()); assert.deepEqual(bJsScriptInfo.containingProjects, [auxProject]); @@ -38,10 +38,10 @@ namespace ts.projectSystem { // When b.js is opened in the editor, it should be put into an InferredProject // even though it's still contained by the AuxiliaryProject. - openFilesForSession([bJs], session); + ts.projectSystem.openFilesForSession([bJs], session); assert(!bJsScriptInfo.isOrphan()); assert(bJsScriptInfo.isContainedByBackgroundProject()); - assert.equal(bJsScriptInfo.getDefaultProject().projectKind, server.ProjectKind.Inferred); + assert.equal(bJsScriptInfo.getDefaultProject().projectKind, ts.server.ProjectKind.Inferred); }); }); } diff --git a/src/testRunner/unittests/tsserver/cachingFileSystemInformation.ts b/src/testRunner/unittests/tsserver/cachingFileSystemInformation.ts index 34863897e8abb..03526a6d4eb07 100644 --- a/src/testRunner/unittests/tsserver/cachingFileSystemInformation.ts +++ b/src/testRunner/unittests/tsserver/cachingFileSystemInformation.ts @@ -1,6 +1,6 @@ namespace ts.projectSystem { function getNumberOfWatchesInvokedForRecursiveWatches(recursiveWatchedDirs: string[], file: string) { - return countWhere(recursiveWatchedDirs, dir => file.length > dir.length && startsWith(file, dir) && file[dir.length] === directorySeparator); + return ts.countWhere(recursiveWatchedDirs, dir => file.length > dir.length && ts.startsWith(file, dir) && file[dir.length] === ts.directorySeparator); } describe("unittests:: tsserver:: CachingFileSystemInformation:: tsserverProjectSystem CachingFileSystemInformation", () => { @@ -14,9 +14,14 @@ namespace ts.projectSystem { readDirectory = "readDirectory" } type CalledMaps = CalledMapsWithSingleArg | CalledMapsWithFiveArgs; - type CalledWithFiveArgs = [readonly string[], readonly string[], readonly string[], number]; - function createCallsTrackingHost(host: TestServerHost) { - const calledMaps: Record> & Record> = { + type CalledWithFiveArgs = [ + readonly string[], + readonly string[], + readonly string[], + number + ]; + function createCallsTrackingHost(host: ts.projectSystem.TestServerHost) { + const calledMaps: Record> & Record> = { fileExists: setCallsTrackingWithSingleArgFn(CalledMapsWithSingleArg.fileExists), directoryExists: setCallsTrackingWithSingleArgFn(CalledMapsWithSingleArg.directoryExists), getDirectories: setCallsTrackingWithSingleArgFn(CalledMapsWithSingleArg.getDirectories), @@ -35,7 +40,7 @@ namespace ts.projectSystem { }; function setCallsTrackingWithSingleArgFn(prop: CalledMapsWithSingleArg) { - const calledMap = createMultiMap(); + const calledMap = ts.createMultiMap(); const cb = (host as any)[prop].bind(host); (host as any)[prop] = (f: string) => { calledMap.add(f, /*value*/ true); @@ -45,7 +50,12 @@ namespace ts.projectSystem { } function setCallsTrackingWithFiveArgFn(prop: CalledMapsWithFiveArgs) { - const calledMap = createMultiMap<[U, V, W, X]>(); + const calledMap = ts.createMultiMap<[ + U, + V, + W, + X + ]>(); const cb = (host as any)[prop].bind(host); (host as any)[prop] = (f: string, arg1?: U, arg2?: V, arg3?: W, arg4?: X) => { calledMap.add(f, [arg1!, arg2!, arg3!, arg4!]); // TODO: GH#18217 @@ -57,20 +67,20 @@ namespace ts.projectSystem { function verifyCalledOn(callback: CalledMaps, name: string) { const calledMap = calledMaps[callback]; const result = calledMap.get(name); - assert.isTrue(result && !!result.length, `${callback} should be called with name: ${name}: ${arrayFrom(calledMap.keys())}`); + assert.isTrue(result && !!result.length, `${callback} should be called with name: ${name}: ${ts.arrayFrom(calledMap.keys())}`); } function verifyNoCall(callback: CalledMaps) { const calledMap = calledMaps[callback]; - assert.equal(calledMap.size, 0, `${callback} shouldn't be called: ${arrayFrom(calledMap.keys())}`); + assert.equal(calledMap.size, 0, `${callback} shouldn't be called: ${ts.arrayFrom(calledMap.keys())}`); } - function verifyCalledOnEachEntry(callback: CalledMaps, expectedKeys: ESMap) { - TestFSWithWatch.checkMap(callback, calledMaps[callback], expectedKeys); + function verifyCalledOnEachEntry(callback: CalledMaps, expectedKeys: ts.ESMap) { + ts.TestFSWithWatch.checkMap(callback, calledMaps[callback], expectedKeys); } function verifyCalledOnEachEntryNTimes(callback: CalledMaps, expectedKeys: readonly string[], nTimes: number) { - TestFSWithWatch.checkMap(callback, calledMaps[callback], expectedKeys, nTimes); + ts.TestFSWithWatch.checkMap(callback, calledMaps[callback], expectedKeys, nTimes); } function verifyNoHostCalls() { @@ -101,21 +111,21 @@ namespace ts.projectSystem { it("works using legacy resolution logic", () => { let rootContent = `import {x} from "f1"`; - const root: File = { + const root: ts.projectSystem.File = { path: "/c/d/f0.ts", content: rootContent }; - const imported: File = { + const imported: ts.projectSystem.File = { path: "/c/f1.ts", content: `foo()` }; - const host = createServerHost([root, imported]); - const projectService = createProjectService(host); - projectService.setCompilerOptionsForInferredProjects({ module: ModuleKind.AMD, noLib: true }); + const host = ts.projectSystem.createServerHost([root, imported]); + const projectService = ts.projectSystem.createProjectService(host); + projectService.setCompilerOptionsForInferredProjects({ module: ts.ModuleKind.AMD, noLib: true }); projectService.openClientFile(root.path); - checkNumberOfProjects(projectService, { inferredProjects: 1 }); + ts.projectSystem.checkNumberOfProjects(projectService, { inferredProjects: 1 }); const project = projectService.inferredProjects[0]; const rootScriptInfo = project.getRootScriptInfos()[0]; assert.equal(rootScriptInfo.fileName, root.path); @@ -154,12 +164,12 @@ namespace ts.projectSystem { verifyImportedDiagnostics(); const f1Lookups = f2Lookups.map(s => s.replace("f2", "f1")); f1Lookups.length = f1Lookups.indexOf(imported.path) + 1; - const f1DirLookups = ["/c/d", "/c", ...mapCombinedPathsInAncestor(getDirectoryPath(root.path), nodeModulesAtTypes, returnTrue)]; + const f1DirLookups = ["/c/d", "/c", ...ts.projectSystem.mapCombinedPathsInAncestor(ts.getDirectoryPath(root.path), ts.projectSystem.nodeModulesAtTypes, ts.returnTrue)]; vertifyF1Lookups(); // setting compiler options discards module resolution cache callsTrackingHost.clear(); - projectService.setCompilerOptionsForInferredProjects({ module: ModuleKind.AMD, noLib: true, target: ScriptTarget.ES5 }); + projectService.setCompilerOptionsForInferredProjects({ module: ts.ModuleKind.AMD, noLib: true, target: ts.ScriptTarget.ES5 }); verifyImportedDiagnostics(); vertifyF1Lookups(); @@ -181,58 +191,51 @@ namespace ts.projectSystem { const diags = project.getLanguageService().getSemanticDiagnostics(imported.path); assert.equal(diags.length, 1); const diag = diags[0]; - assert.equal(diag.code, Diagnostics.Cannot_find_name_0.code); - assert.equal(flattenDiagnosticMessageText(diag.messageText, "\n"), "Cannot find name 'foo'."); + assert.equal(diag.code, ts.Diagnostics.Cannot_find_name_0.code); + assert.equal(ts.flattenDiagnosticMessageText(diag.messageText, "\n"), "Cannot find name 'foo'."); } function getLocationsForModuleLookup(module: string) { const locations: string[] = []; - forEachAncestorDirectory(getDirectoryPath(root.path), ancestor => { - locations.push( - combinePaths(ancestor, `${module}.ts`), - combinePaths(ancestor, `${module}.tsx`), - combinePaths(ancestor, `${module}.d.ts`) - ); + ts.forEachAncestorDirectory(ts.getDirectoryPath(root.path), ancestor => { + locations.push(ts.combinePaths(ancestor, `${module}.ts`), ts.combinePaths(ancestor, `${module}.tsx`), ts.combinePaths(ancestor, `${module}.d.ts`)); }); - forEachAncestorDirectory(getDirectoryPath(root.path), ancestor => { - locations.push( - combinePaths(ancestor, `${module}.js`), - combinePaths(ancestor, `${module}.jsx`) - ); + ts.forEachAncestorDirectory(ts.getDirectoryPath(root.path), ancestor => { + locations.push(ts.combinePaths(ancestor, `${module}.js`), ts.combinePaths(ancestor, `${module}.jsx`)); }); return locations; } function getLocationsForDirectoryLookup() { - const result = new Map(); - forEachAncestorDirectory(getDirectoryPath(root.path), ancestor => { + const result = new ts.Map(); + ts.forEachAncestorDirectory(ts.getDirectoryPath(root.path), ancestor => { // To resolve modules result.set(ancestor, 2); // for type roots - result.set(combinePaths(ancestor, nodeModules), 1); - result.set(combinePaths(ancestor, nodeModulesAtTypes), 1); + result.set(ts.combinePaths(ancestor, ts.projectSystem.nodeModules), 1); + result.set(ts.combinePaths(ancestor, ts.projectSystem.nodeModulesAtTypes), 1); }); return result; } }); it("loads missing files from disk", () => { - const root: File = { + const root: ts.projectSystem.File = { path: "/c/foo.ts", content: `import {y} from "bar"` }; - const imported: File = { + const imported: ts.projectSystem.File = { path: "/c/bar.d.ts", content: `export var y = 1` }; - const host = createServerHost([root]); - const projectService = createProjectService(host); - projectService.setCompilerOptionsForInferredProjects({ module: ModuleKind.AMD, noLib: true }); + const host = ts.projectSystem.createServerHost([root]); + const projectService = ts.projectSystem.createProjectService(host); + projectService.setCompilerOptionsForInferredProjects({ module: ts.ModuleKind.AMD, noLib: true }); const callsTrackingHost = createCallsTrackingHost(host); projectService.openClientFile(root.path); - checkNumberOfProjects(projectService, { inferredProjects: 1 }); + ts.projectSystem.checkNumberOfProjects(projectService, { inferredProjects: 1 }); const project = projectService.inferredProjects[0]; const rootScriptInfo = project.getRootScriptInfos()[0]; assert.equal(rootScriptInfo.fileName, root.path); @@ -240,8 +243,8 @@ namespace ts.projectSystem { let diags = project.getLanguageService().getSemanticDiagnostics(root.path); assert.equal(diags.length, 1); const diag = diags[0]; - assert.equal(diag.code, Diagnostics.Cannot_find_module_0_Did_you_mean_to_set_the_moduleResolution_option_to_node_or_to_add_aliases_to_the_paths_option.code); - assert.equal(flattenDiagnosticMessageText(diag.messageText, "\n"), "Cannot find module 'bar'. Did you mean to set the 'moduleResolution' option to 'node', or to add aliases to the 'paths' option?"); + assert.equal(diag.code, ts.Diagnostics.Cannot_find_module_0_Did_you_mean_to_set_the_moduleResolution_option_to_node_or_to_add_aliases_to_the_paths_option.code); + assert.equal(ts.flattenDiagnosticMessageText(diag.messageText, "\n"), "Cannot find module 'bar'. Did you mean to set the 'moduleResolution' option to 'node', or to add aliases to the 'paths' option?"); callsTrackingHost.verifyCalledOn(CalledMapsWithSingleArg.fileExists, imported.path); @@ -254,31 +257,31 @@ namespace ts.projectSystem { }); it("when calling goto definition of module", () => { - const clientFile: File = { + const clientFile: ts.projectSystem.File = { path: "/a/b/controllers/vessels/client.ts", content: ` import { Vessel } from '~/models/vessel'; const v = new Vessel(); ` }; - const anotherModuleFile: File = { + const anotherModuleFile: ts.projectSystem.File = { path: "/a/b/utils/db.ts", content: "export class Bookshelf { }" }; - const moduleFile: File = { + const moduleFile: ts.projectSystem.File = { path: "/a/b/models/vessel.ts", content: ` import { Bookshelf } from '~/utils/db'; export class Vessel extends Bookshelf {} ` }; - const tsconfigFile: File = { + const tsconfigFile: ts.projectSystem.File = { path: "/a/b/tsconfig.json", content: JSON.stringify({ compilerOptions: { target: "es6", module: "es6", - baseUrl: "./", // all paths are relative to the baseUrl + baseUrl: "./", paths: { "~/*": ["*"] // resolve any `~/foo/bar` to `/foo/bar` } @@ -295,27 +298,27 @@ namespace ts.projectSystem { }) }; const projectFiles = [clientFile, anotherModuleFile, moduleFile, tsconfigFile]; - const host = createServerHost(projectFiles); - const session = createSession(host); + const host = ts.projectSystem.createServerHost(projectFiles); + const session = ts.projectSystem.createSession(host); const projectService = session.getProjectService(); const { configFileName } = projectService.openClientFile(clientFile.path); assert.isDefined(configFileName, `should find config`); - checkNumberOfConfiguredProjects(projectService, 1); + ts.projectSystem.checkNumberOfConfiguredProjects(projectService, 1); const project = projectService.configuredProjects.get(tsconfigFile.path)!; - checkProjectActualFiles(project, map(projectFiles, f => f.path)); + ts.projectSystem.checkProjectActualFiles(project, ts.map(projectFiles, f => f.path)); const callsTrackingHost = createCallsTrackingHost(host); // Get definitions shouldnt make host requests - const getDefinitionRequest = makeSessionRequest(protocol.CommandTypes.Definition, { + const getDefinitionRequest = ts.projectSystem.makeSessionRequest(ts.projectSystem.protocol.CommandTypes.Definition, { file: clientFile.path, position: clientFile.content.indexOf("/vessel") + 1, - line: undefined!, // TODO: GH#18217 + line: undefined!, offset: undefined! // TODO: GH#18217 }); - const response = session.executeCommand(getDefinitionRequest).response as server.protocol.FileSpan[]; + const response = session.executeCommand(getDefinitionRequest).response as ts.server.protocol.FileSpan[]; assert.equal(response[0].file, moduleFile.path, "Should go to definition of vessel: response: " + JSON.stringify(response)); callsTrackingHost.verifyNoHostCalls(); @@ -324,34 +327,34 @@ namespace ts.projectSystem { assert.equal(config2, configFileName); callsTrackingHost.verifyNoHostCallsExceptFileExistsOnce(["/a/b/models/tsconfig.json", "/a/b/models/jsconfig.json"]); - checkNumberOfConfiguredProjects(projectService, 1); + ts.projectSystem.checkNumberOfConfiguredProjects(projectService, 1); assert.strictEqual(projectService.configuredProjects.get(tsconfigFile.path), project); }); describe("WatchDirectories for config file with", () => { function verifyWatchDirectoriesCaseSensitivity(useCaseSensitiveFileNames: boolean) { const frontendDir = "/Users/someuser/work/applications/frontend"; - const toCanonical: (s: string) => Path = useCaseSensitiveFileNames ? s => s as Path : s => s.toLowerCase() as Path; + const toCanonical: (s: string) => ts.Path = useCaseSensitiveFileNames ? s => s as ts.Path : s => s.toLowerCase() as ts.Path; const canonicalFrontendDir = toCanonical(frontendDir); - const file1: File = { + const file1: ts.projectSystem.File = { path: `${frontendDir}/src/app/utils/Analytic.ts`, content: "export class SomeClass { };" }; - const file2: File = { + const file2: ts.projectSystem.File = { path: `${frontendDir}/src/app/redux/configureStore.ts`, content: "export class configureStore { }" }; - const file3: File = { + const file3: ts.projectSystem.File = { path: `${frontendDir}/src/app/utils/Cookie.ts`, content: "export class Cookie { }" }; - const es2016LibFile: File = { + const es2016LibFile: ts.projectSystem.File = { path: "/a/lib/lib.es2016.full.d.ts", - content: libFile.content + content: ts.projectSystem.libFile.content }; const typeRoots = ["types", "node_modules/@types"]; const types = ["node", "jest"]; - const tsconfigFile: File = { + const tsconfigFile: ts.projectSystem.File = { path: `${frontendDir}/tsconfig.json`, content: JSON.stringify({ compilerOptions: { @@ -385,13 +388,13 @@ namespace ts.projectSystem { }) }; const projectFiles = [file1, file2, es2016LibFile, tsconfigFile]; - const host = createServerHost(projectFiles, { useCaseSensitiveFileNames }); - const projectService = createProjectService(host); + const host = ts.projectSystem.createServerHost(projectFiles, { useCaseSensitiveFileNames }); + const projectService = ts.projectSystem.createProjectService(host); const canonicalConfigPath = toCanonical(tsconfigFile.path); const { configFileName } = projectService.openClientFile(file1.path); - assert.equal(configFileName, tsconfigFile.path as server.NormalizedPath, `should find config`); - checkNumberOfConfiguredProjects(projectService, 1); - const watchingRecursiveDirectories = [`${canonicalFrontendDir}/src`, `${canonicalFrontendDir}/types`, `${canonicalFrontendDir}/node_modules`].concat(getNodeModuleDirectories(getDirectoryPath(canonicalFrontendDir))); + assert.equal(configFileName, tsconfigFile.path as ts.server.NormalizedPath, `should find config`); + ts.projectSystem.checkNumberOfConfiguredProjects(projectService, 1); + const watchingRecursiveDirectories = [`${canonicalFrontendDir}/src`, `${canonicalFrontendDir}/types`, `${canonicalFrontendDir}/node_modules`].concat(ts.projectSystem.getNodeModuleDirectories(ts.getDirectoryPath(canonicalFrontendDir))); const project = projectService.configuredProjects.get(canonicalConfigPath)!; verifyProjectAndWatchedDirectories(); @@ -411,7 +414,7 @@ namespace ts.projectSystem { callsTrackingHost.verifyCalledOnEachEntryNTimes(CalledMapsWithSingleArg.readFile, [file3.path], 1); callsTrackingHost.verifyNoCall(CalledMapsWithFiveArgs.readDirectory); - checkNumberOfConfiguredProjects(projectService, 1); + ts.projectSystem.checkNumberOfConfiguredProjects(projectService, 1); assert.strictEqual(projectService.configuredProjects.get(canonicalConfigPath), project); verifyProjectAndWatchedDirectories(); @@ -420,22 +423,22 @@ namespace ts.projectSystem { const { configFileName: configFile2 } = projectService.openClientFile(file3.path); assert.equal(configFile2, configFileName); - checkNumberOfConfiguredProjects(projectService, 1); + ts.projectSystem.checkNumberOfConfiguredProjects(projectService, 1); assert.strictEqual(projectService.configuredProjects.get(canonicalConfigPath), project); verifyProjectAndWatchedDirectories(); callsTrackingHost.verifyNoHostCalls(); - function getFilePathIfNotOpen(f: File) { + function getFilePathIfNotOpen(f: ts.projectSystem.File) { const path = toCanonical(f.path); const info = projectService.getScriptInfoForPath(toCanonical(f.path)); return info && info.isScriptOpen() ? undefined : path; } function verifyProjectAndWatchedDirectories() { - checkProjectActualFiles(project, map(projectFiles, f => f.path)); - checkWatchedFiles(host, mapDefined(projectFiles, getFilePathIfNotOpen)); - checkWatchedDirectories(host, watchingRecursiveDirectories, /*recursive*/ true); - checkWatchedDirectories(host, [], /*recursive*/ false); + ts.projectSystem.checkProjectActualFiles(project, ts.map(projectFiles, f => f.path)); + ts.projectSystem.checkWatchedFiles(host, ts.mapDefined(projectFiles, getFilePathIfNotOpen)); + ts.projectSystem.checkWatchedDirectories(host, watchingRecursiveDirectories, /*recursive*/ true); + ts.projectSystem.checkWatchedDirectories(host, [], /*recursive*/ false); } } @@ -451,15 +454,15 @@ namespace ts.projectSystem { describe("Subfolder invalidations correctly include parent folder failed lookup locations", () => { function runFailedLookupTest(resolution: "Node" | "Classic") { const projectLocation = "/proj"; - const file1: File = { + const file1: ts.projectSystem.File = { path: `${projectLocation}/foo/boo/app.ts`, content: `import * as debug from "debug"` }; - const file2: File = { + const file2: ts.projectSystem.File = { path: `${projectLocation}/foo/boo/moo/app.ts`, content: `import * as debug from "debug"` }; - const tsconfig: File = { + const tsconfig: ts.projectSystem.File = { path: `${projectLocation}/tsconfig.json`, content: JSON.stringify({ files: ["foo/boo/app.ts", "foo/boo/moo/app.ts"], @@ -467,17 +470,17 @@ namespace ts.projectSystem { }) }; - const files = [file1, file2, tsconfig, libFile]; - const host = createServerHost(files); - const service = createProjectService(host); + const files = [file1, file2, tsconfig, ts.projectSystem.libFile]; + const host = ts.projectSystem.createServerHost(files); + const service = ts.projectSystem.createProjectService(host); service.openClientFile(file1.path); const project = service.configuredProjects.get(tsconfig.path)!; - checkProjectActualFiles(project, files.map(f => f.path)); + ts.projectSystem.checkProjectActualFiles(project, files.map(f => f.path)); assert.deepEqual(project.getLanguageService().getSemanticDiagnostics(file1.path).map(diag => diag.messageText), ["Cannot find module 'debug' or its corresponding type declarations."]); assert.deepEqual(project.getLanguageService().getSemanticDiagnostics(file2.path).map(diag => diag.messageText), ["Cannot find module 'debug' or its corresponding type declarations."]); - const debugTypesFile: File = { + const debugTypesFile: ts.projectSystem.File = { path: `${projectLocation}/node_modules/debug/index.d.ts`, content: "export {}" }; @@ -485,7 +488,7 @@ namespace ts.projectSystem { host.writeFile(debugTypesFile.path, debugTypesFile.content); host.runQueuedTimeoutCallbacks(); // Scheduled invalidation of resolutions host.runQueuedTimeoutCallbacks(); // Actual update - checkProjectActualFiles(project, files.map(f => f.path)); + ts.projectSystem.checkProjectActualFiles(project, files.map(f => f.path)); assert.deepEqual(project.getLanguageService().getSemanticDiagnostics(file1.path).map(diag => diag.messageText), []); assert.deepEqual(project.getLanguageService().getSemanticDiagnostics(file2.path).map(diag => diag.messageText), []); } @@ -501,19 +504,19 @@ namespace ts.projectSystem { describe("Verify npm install in directory with tsconfig file works when", () => { function verifyNpmInstall(timeoutDuringPartialInstallation: boolean) { const root = "/user/username/rootfolder/otherfolder"; - const getRootedFileOrFolder = (fileOrFolder: File) => { + const getRootedFileOrFolder = (fileOrFolder: ts.projectSystem.File) => { fileOrFolder.path = root + fileOrFolder.path; return fileOrFolder; }; - const app: File = getRootedFileOrFolder({ + const app: ts.projectSystem.File = getRootedFileOrFolder({ path: "/a/b/app.ts", content: "import _ from 'lodash';" }); - const tsconfigJson: File = getRootedFileOrFolder({ + const tsconfigJson: ts.projectSystem.File = getRootedFileOrFolder({ path: "/a/b/tsconfig.json", content: '{ "compilerOptions": { } }' }); - const packageJson: File = getRootedFileOrFolder({ + const packageJson: ts.projectSystem.File = getRootedFileOrFolder({ path: "/a/b/package.json", content: ` { @@ -538,22 +541,22 @@ namespace ts.projectSystem { } ` }); - const appFolder = getDirectoryPath(app.path); - const projectFiles = [app, libFile, tsconfigJson]; - const typeRootDirectories = getTypeRootsFromLocation(getDirectoryPath(tsconfigJson.path)); + const appFolder = ts.getDirectoryPath(app.path); + const projectFiles = [app, ts.projectSystem.libFile, tsconfigJson]; + const typeRootDirectories = ts.projectSystem.getTypeRootsFromLocation(ts.getDirectoryPath(tsconfigJson.path)); const otherFiles = [packageJson]; - const host = createServerHost(projectFiles.concat(otherFiles)); - const projectService = createProjectService(host); + const host = ts.projectSystem.createServerHost(projectFiles.concat(otherFiles)); + const projectService = ts.projectSystem.createProjectService(host); projectService.setHostConfiguration({ preferences: { includePackageJsonAutoImports: "off" } }); const { configFileName } = projectService.openClientFile(app.path); - assert.equal(configFileName, tsconfigJson.path as server.NormalizedPath, `should find config`); // TODO: GH#18217 - const recursiveWatchedDirectories: string[] = [`${appFolder}`, `${appFolder}/node_modules`].concat(getNodeModuleDirectories(getDirectoryPath(appFolder))); + assert.equal(configFileName, tsconfigJson.path as ts.server.NormalizedPath, `should find config`); // TODO: GH#18217 + const recursiveWatchedDirectories: string[] = [`${appFolder}`, `${appFolder}/node_modules`].concat(ts.projectSystem.getNodeModuleDirectories(ts.getDirectoryPath(appFolder))); verifyProject(); let npmInstallComplete = false; // Simulate npm install - const filesAndFoldersToAdd: File[] = [ + const filesAndFoldersToAdd: ts.projectSystem.File[] = [ { path: "/a/b/node_modules" }, { path: "/a/b/node_modules/.staging/@types" }, { path: "/a/b/node_modules/.staging/lodash-b0733faa" }, @@ -583,7 +586,7 @@ namespace ts.projectSystem { verifyAfterPartialOrCompleteNpmInstall(0); // Remove file "/a/b/node_modules/.staging/typescript-8493ea5d/package.json.3017591594" - host.deleteFile(last(filesAndFoldersToAdd).path); + host.deleteFile(ts.last(filesAndFoldersToAdd).path); filesAndFoldersToAdd.length--; verifyAfterPartialOrCompleteNpmInstall(0); @@ -605,7 +608,7 @@ namespace ts.projectSystem { verifyAfterPartialOrCompleteNpmInstall(0); // remove /a/b/node_modules/.staging/rxjs-22375c61/package.json.2252192041 - host.deleteFile(last(filesAndFoldersToAdd).path); + host.deleteFile(ts.last(filesAndFoldersToAdd).path); filesAndFoldersToAdd.length--; // and add few more folders/files filesAndFoldersToAdd.push(...[ @@ -620,7 +623,7 @@ namespace ts.projectSystem { // From the type root update verifyAfterPartialOrCompleteNpmInstall(2); - forEach(filesAndFoldersToAdd, f => { + ts.forEach(filesAndFoldersToAdd, f => { f.path = f.path .replace("/a/b/node_modules/.staging", "/a/b/node_modules") .replace(/[\-\.][\d\w][\d\w][\d\w][\d\w][\d\w][\d\w][\d\w][\d\w]/g, ""); @@ -628,7 +631,7 @@ namespace ts.projectSystem { host.deleteFolder(root + "/a/b/node_modules/.staging", /*recursive*/ true); const lodashIndexPath = root + "/a/b/node_modules/@types/lodash/index.d.ts"; - projectFiles.push(find(filesAndFoldersToAdd, f => f.path === lodashIndexPath)!); + projectFiles.push(ts.find(filesAndFoldersToAdd, f => f.path === lodashIndexPath)!); // we would now not have failed lookup in the parent of appFolder since lodash is available recursiveWatchedDirectories.length = 2; // npm installation complete, timeout after reload fs @@ -654,16 +657,15 @@ namespace ts.projectSystem { } function verifyProject() { - checkNumberOfConfiguredProjects(projectService, 1); + ts.projectSystem.checkNumberOfConfiguredProjects(projectService, 1); const project = projectService.configuredProjects.get(tsconfigJson.path)!; - const projectFilePaths = map(projectFiles, f => f.path); - checkProjectActualFiles(project, projectFilePaths); - - const filesWatched = filter(projectFilePaths, p => p !== app.path && p.indexOf("/a/b/node_modules") === -1); - checkWatchedFiles(host, filesWatched); - checkWatchedDirectories(host, typeRootDirectories.concat(recursiveWatchedDirectories), /*recursive*/ true); - checkWatchedDirectories(host, [], /*recursive*/ false); + const projectFilePaths = ts.map(projectFiles, f => f.path); + ts.projectSystem.checkProjectActualFiles(project, projectFilePaths); + const filesWatched = ts.filter(projectFilePaths, p => p !== app.path && p.indexOf("/a/b/node_modules") === -1); + ts.projectSystem.checkWatchedFiles(host, filesWatched); + ts.projectSystem.checkWatchedDirectories(host, typeRootDirectories.concat(recursiveWatchedDirectories), /*recursive*/ true); + ts.projectSystem.checkWatchedDirectories(host, [], /*recursive*/ false); } } @@ -678,25 +680,25 @@ namespace ts.projectSystem { it("when node_modules dont receive event for the @types file addition", () => { const projectLocation = "/user/username/folder/myproject"; - const app: File = { + const app: ts.projectSystem.File = { path: `${projectLocation}/app.ts`, content: `import * as debug from "debug"` }; - const tsconfig: File = { + const tsconfig: ts.projectSystem.File = { path: `${projectLocation}/tsconfig.json`, content: "" }; - const files = [app, tsconfig, libFile]; - const host = createServerHost(files); - const service = createProjectService(host); + const files = [app, tsconfig, ts.projectSystem.libFile]; + const host = ts.projectSystem.createServerHost(files); + const service = ts.projectSystem.createProjectService(host); service.openClientFile(app.path); const project = service.configuredProjects.get(tsconfig.path)!; - checkProjectActualFiles(project, files.map(f => f.path)); + ts.projectSystem.checkProjectActualFiles(project, files.map(f => f.path)); assert.deepEqual(project.getLanguageService().getSemanticDiagnostics(app.path).map(diag => diag.messageText), ["Cannot find module 'debug' or its corresponding type declarations."]); - const debugTypesFile: File = { + const debugTypesFile: ts.projectSystem.File = { path: `${projectLocation}/node_modules/@types/debug/index.d.ts`, content: "export {}" }; @@ -710,25 +712,25 @@ namespace ts.projectSystem { }; host.writeFile(debugTypesFile.path, debugTypesFile.content); host.runQueuedTimeoutCallbacks(); - checkProjectActualFiles(project, files.map(f => f.path)); + ts.projectSystem.checkProjectActualFiles(project, files.map(f => f.path)); assert.deepEqual(project.getLanguageService().getSemanticDiagnostics(app.path).map(diag => diag.messageText), []); }); it("when creating new file in symlinked folder", () => { - const module1: File = { - path: `${tscWatch.projectRoot}/client/folder1/module1.ts`, + const module1: ts.projectSystem.File = { + path: `${ts.tscWatch.projectRoot}/client/folder1/module1.ts`, content: `export class Module1Class { }` }; - const module2: File = { - path: `${tscWatch.projectRoot}/folder2/module2.ts`, + const module2: ts.projectSystem.File = { + path: `${ts.tscWatch.projectRoot}/folder2/module2.ts`, content: `import * as M from "folder1/module1";` }; - const symlink: SymLink = { - path: `${tscWatch.projectRoot}/client/linktofolder2`, - symLink: `${tscWatch.projectRoot}/folder2`, + const symlink: ts.projectSystem.SymLink = { + path: `${ts.tscWatch.projectRoot}/client/linktofolder2`, + symLink: `${ts.tscWatch.projectRoot}/folder2`, }; - const config: File = { - path: `${tscWatch.projectRoot}/tsconfig.json`, + const config: ts.projectSystem.File = { + path: `${ts.tscWatch.projectRoot}/tsconfig.json`, content: JSON.stringify({ compilerOptions: { baseUrl: "client", @@ -737,16 +739,16 @@ namespace ts.projectSystem { include: ["client/**/*", "folder2"] }) }; - const host = createServerHost([module1, module2, symlink, config, libFile]); - const service = createProjectService(host); + const host = ts.projectSystem.createServerHost([module1, module2, symlink, config, ts.projectSystem.libFile]); + const service = ts.projectSystem.createProjectService(host); service.openClientFile(`${symlink.path}/module2.ts`); - checkNumberOfProjects(service, { configuredProjects: 1 }); - const project = Debug.checkDefined(service.configuredProjects.get(config.path)); - checkProjectActualFiles(project, [module1.path, `${symlink.path}/module2.ts`, config.path, libFile.path]); + ts.projectSystem.checkNumberOfProjects(service, { configuredProjects: 1 }); + const project = ts.Debug.checkDefined(service.configuredProjects.get(config.path)); + ts.projectSystem.checkProjectActualFiles(project, [module1.path, `${symlink.path}/module2.ts`, config.path, ts.projectSystem.libFile.path]); host.writeFile(`${symlink.path}/module3.ts`, `import * as M from "folder1/module1";`); host.runQueuedTimeoutCallbacks(); - checkNumberOfProjects(service, { configuredProjects: 1 }); - checkProjectActualFiles(project, [module1.path, `${symlink.path}/module2.ts`, config.path, libFile.path, `${symlink.path}/module3.ts`]); + ts.projectSystem.checkNumberOfProjects(service, { configuredProjects: 1 }); + ts.projectSystem.checkProjectActualFiles(project, [module1.path, `${symlink.path}/module2.ts`, config.path, ts.projectSystem.libFile.path, `${symlink.path}/module3.ts`]); }); }); } diff --git a/src/testRunner/unittests/tsserver/cancellationToken.ts b/src/testRunner/unittests/tsserver/cancellationToken.ts index f727263357ec0..528e40dcd27b0 100644 --- a/src/testRunner/unittests/tsserver/cancellationToken.ts +++ b/src/testRunner/unittests/tsserver/cancellationToken.ts @@ -1,7 +1,7 @@ namespace ts.projectSystem { describe("unittests:: tsserver:: cancellationToken", () => { // Disable sourcemap support for the duration of the test, as sourcemapping the errors generated during this test is slow and not something we care to test - let oldPrepare: AnyFunction; + let oldPrepare: ts.AnyFunction; before(() => { oldPrepare = (Error as any).prepareStackTrace; delete (Error as any).prepareStackTrace; @@ -16,9 +16,9 @@ namespace ts.projectSystem { path: "/a/b/app.ts", content: "let xyz = 1;" }; - const host = createServerHost([f1]); + const host = ts.projectSystem.createServerHost([f1]); let expectedRequestId: number; - const cancellationToken: server.ServerCancellationToken = { + const cancellationToken: ts.server.ServerCancellationToken = { isCancellationRequested: () => false, setRequest: requestId => { if (expectedRequestId === undefined) { @@ -26,28 +26,28 @@ namespace ts.projectSystem { } assert.equal(requestId, expectedRequestId); }, - resetRequest: noop + resetRequest: ts.noop }; - const session = createSession(host, { cancellationToken }); + const session = ts.projectSystem.createSession(host, { cancellationToken }); expectedRequestId = session.getNextSeq(); session.executeCommandSeq({ command: "open", arguments: { file: f1.path } - } as server.protocol.OpenRequest); + } as ts.server.protocol.OpenRequest); expectedRequestId = session.getNextSeq(); session.executeCommandSeq({ command: "geterr", arguments: { files: [f1.path] } - } as server.protocol.GeterrRequest); + } as ts.server.protocol.GeterrRequest); expectedRequestId = session.getNextSeq(); session.executeCommandSeq({ command: "occurrences", arguments: { file: f1.path, line: 1, offset: 6 } - } as server.protocol.OccurrencesRequest); + } as ts.server.protocol.OccurrencesRequest); expectedRequestId = 2; host.runQueuedImmediateCallbacks(); @@ -67,23 +67,23 @@ namespace ts.projectSystem { }) }; - const cancellationToken = new TestServerCancellationToken(); - const host = createServerHost([f1, config]); - const session = createSession(host, { + const cancellationToken = new ts.projectSystem.TestServerCancellationToken(); + const host = ts.projectSystem.createServerHost([f1, config]); + const session = ts.projectSystem.createSession(host, { canUseEvents: true, - eventHandler: noop, + eventHandler: ts.noop, cancellationToken }); { session.executeCommandSeq({ command: "open", arguments: { file: f1.path } - } as protocol.OpenRequest); + } as ts.projectSystem.protocol.OpenRequest); // send geterr for missing file session.executeCommandSeq({ command: "geterr", arguments: { files: ["/a/missing"] } - } as protocol.GeterrRequest); + } as ts.projectSystem.protocol.GeterrRequest); // Queued files assert.equal(host.getOutput().length, 0, "expected 0 message"); host.checkTimeoutQueueLengthAndRun(1); @@ -97,7 +97,7 @@ namespace ts.projectSystem { session.executeCommandSeq({ command: "geterr", arguments: { files: [f1.path] } - } as protocol.GeterrRequest); + } as ts.projectSystem.protocol.GeterrRequest); assert.equal(host.getOutput().length, 0, "expect 0 messages"); @@ -105,7 +105,7 @@ namespace ts.projectSystem { session.executeCommandSeq({ command: "projectInfo", arguments: { file: f1.path } - } as protocol.ProjectInfoRequest); + } as ts.projectSystem.protocol.ProjectInfoRequest); session.clearMessages(); // cancel previously issued Geterr @@ -122,13 +122,13 @@ namespace ts.projectSystem { session.executeCommandSeq({ command: "geterr", arguments: { files: [f1.path] } - } as protocol.GeterrRequest); + } as ts.projectSystem.protocol.GeterrRequest); assert.equal(host.getOutput().length, 0, "expect 0 messages"); // run first step host.runQueuedTimeoutCallbacks(); assert.equal(host.getOutput().length, 1, "expect 1 message"); - const e1 = getMessage(0) as protocol.Event; + const e1 = getMessage(0) as ts.projectSystem.protocol.Event; assert.equal(e1.event, "syntaxDiag"); session.clearMessages(); @@ -144,26 +144,26 @@ namespace ts.projectSystem { session.executeCommandSeq({ command: "geterr", arguments: { files: [f1.path] } - } as protocol.GeterrRequest); + } as ts.projectSystem.protocol.GeterrRequest); assert.equal(host.getOutput().length, 0, "expect 0 messages"); // run first step host.runQueuedTimeoutCallbacks(); assert.equal(host.getOutput().length, 1, "expect 1 message"); - const e1 = getMessage(0) as protocol.Event; + const e1 = getMessage(0) as ts.projectSystem.protocol.Event; assert.equal(e1.event, "syntaxDiag"); session.clearMessages(); // the semanticDiag message host.runQueuedImmediateCallbacks(); assert.equal(host.getOutput().length, 1); - const e2 = getMessage(0) as protocol.Event; + const e2 = getMessage(0) as ts.projectSystem.protocol.Event; assert.equal(e2.event, "semanticDiag"); session.clearMessages(); host.runQueuedImmediateCallbacks(1); assert.equal(host.getOutput().length, 2); - const e3 = getMessage(0) as protocol.Event; + const e3 = getMessage(0) as ts.projectSystem.protocol.Event; assert.equal(e3.event, "suggestionDiag"); verifyRequestCompleted(getErrId, 1); @@ -174,32 +174,32 @@ namespace ts.projectSystem { session.executeCommandSeq({ command: "geterr", arguments: { files: [f1.path] } - } as protocol.GeterrRequest); + } as ts.projectSystem.protocol.GeterrRequest); assert.equal(host.getOutput().length, 0, "expect 0 messages"); // run first step host.runQueuedTimeoutCallbacks(); assert.equal(host.getOutput().length, 1, "expect 1 message"); - const e1 = getMessage(0) as protocol.Event; + const e1 = getMessage(0) as ts.projectSystem.protocol.Event; assert.equal(e1.event, "syntaxDiag"); session.clearMessages(); session.executeCommandSeq({ command: "geterr", arguments: { files: [f1.path] } - } as protocol.GeterrRequest); + } as ts.projectSystem.protocol.GeterrRequest); // make sure that getErr1 is completed verifyRequestCompleted(getErr1, 0); } function verifyRequestCompleted(expectedSeq: number, n: number) { - const event = getMessage(n) as protocol.RequestCompletedEvent; + const event = getMessage(n) as ts.projectSystem.protocol.RequestCompletedEvent; assert.equal(event.event, "requestCompleted"); assert.equal(event.body.request_seq, expectedSeq, "expectedSeq"); session.clearMessages(); } function getMessage(n: number) { - return JSON.parse(server.extractMessage(host.getOutput()[n])); + return JSON.parse(ts.server.extractMessage(host.getOutput()[n])); } }); @@ -214,11 +214,11 @@ namespace ts.projectSystem { compilerOptions: {} }) }; - const cancellationToken = new TestServerCancellationToken(/*cancelAfterRequest*/ 3); - const host = createServerHost([f1, config]); - const session = createSession(host, { + const cancellationToken = new ts.projectSystem.TestServerCancellationToken(/*cancelAfterRequest*/ 3); + const host = ts.projectSystem.createServerHost([f1, config]); + const session = ts.projectSystem.createSession(host, { canUseEvents: true, - eventHandler: noop, + eventHandler: ts.noop, cancellationToken, throttleWaitMilliseconds: 0 }); @@ -226,34 +226,34 @@ namespace ts.projectSystem { session.executeCommandSeq({ command: "open", arguments: { file: f1.path } - } as protocol.OpenRequest); + } as ts.projectSystem.protocol.OpenRequest); // send navbar request (normal priority) session.executeCommandSeq({ command: "navbar", arguments: { file: f1.path } - } as protocol.NavBarRequest); + } as ts.projectSystem.protocol.NavBarRequest); // ensure the nav bar request can be canceled verifyExecuteCommandSeqIsCancellable({ command: "navbar", arguments: { file: f1.path } - } as protocol.NavBarRequest); + } as ts.projectSystem.protocol.NavBarRequest); // send outlining spans request (normal priority) session.executeCommandSeq({ command: "outliningSpans", arguments: { file: f1.path } - } as protocol.OutliningSpansRequestFull); + } as ts.projectSystem.protocol.OutliningSpansRequestFull); // ensure the outlining spans request can be canceled verifyExecuteCommandSeqIsCancellable({ command: "outliningSpans", arguments: { file: f1.path } - } as protocol.OutliningSpansRequestFull); + } as ts.projectSystem.protocol.OutliningSpansRequestFull); } - function verifyExecuteCommandSeqIsCancellable(request: Partial) { + function verifyExecuteCommandSeqIsCancellable(request: Partial) { // Set the next request to be cancellable // The cancellation token will cancel the request the third time // isCancellationRequested() is called. @@ -264,7 +264,7 @@ namespace ts.projectSystem { session.executeCommandSeq(request); } catch (e) { - assert(e instanceof OperationCanceledException); + assert(e instanceof ts.OperationCanceledException); operationCanceledExceptionThrown = true; } assert(operationCanceledExceptionThrown, "Operation Canceled Exception not thrown for request: " + JSON.stringify(request)); diff --git a/src/testRunner/unittests/tsserver/compileOnSave.ts b/src/testRunner/unittests/tsserver/compileOnSave.ts index d8ea2df4008d9..b51407005ec63 100644 --- a/src/testRunner/unittests/tsserver/compileOnSave.ts +++ b/src/testRunner/unittests/tsserver/compileOnSave.ts @@ -1,14 +1,17 @@ namespace ts.projectSystem { - import CommandNames = server.CommandNames; - function createTestTypingsInstaller(host: server.ServerHost) { - return new TestTypingsInstaller("/a/data/", /*throttleLimit*/5, host); + import CommandNames = ts.server.CommandNames; + function createTestTypingsInstaller(host: ts.server.ServerHost) { + return new ts.projectSystem.TestTypingsInstaller("/a/data/", /*throttleLimit*/ 5, host); } describe("unittests:: tsserver:: compileOnSave:: affected list", () => { - function sendAffectedFileRequestAndCheckResult(session: server.Session, request: server.protocol.Request, expectedFileList: { projectFileName: string, files: File[] }[]) { - const response = session.executeCommand(request).response as server.protocol.CompileOnSaveAffectedFileListSingleProject[]; - const actualResult = response.sort((list1, list2) => compareStringsCaseSensitive(list1.projectFileName, list2.projectFileName)); - expectedFileList = expectedFileList.sort((list1, list2) => compareStringsCaseSensitive(list1.projectFileName, list2.projectFileName)); + function sendAffectedFileRequestAndCheckResult(session: ts.server.Session, request: ts.server.protocol.Request, expectedFileList: { + projectFileName: string; + files: ts.projectSystem.File[]; + }[]) { + const response = session.executeCommand(request).response as ts.server.protocol.CompileOnSaveAffectedFileListSingleProject[]; + const actualResult = response.sort((list1, list2) => ts.compareStringsCaseSensitive(list1.projectFileName, list2.projectFileName)); + expectedFileList = expectedFileList.sort((list1, list2) => ts.compareStringsCaseSensitive(list1.projectFileName, list2.projectFileName)); assert.equal(actualResult.length, expectedFileList.length, `Actual result project number is different from the expected project number`); @@ -18,24 +21,22 @@ namespace ts.projectSystem { assert.equal(actualResultSingleProject.projectFileName, expectedResultSingleProject.projectFileName, `Actual result contains different projects than the expected result`); const actualResultSingleProjectFileNameList = actualResultSingleProject.fileNames.sort(); - const expectedResultSingleProjectFileNameList = map(expectedResultSingleProject.files, f => f.path).sort(); - assert.isTrue( - arrayIsEqualTo(actualResultSingleProjectFileNameList, expectedResultSingleProjectFileNameList), - `For project ${actualResultSingleProject.projectFileName}, the actual result is ${actualResultSingleProjectFileNameList}, while expected ${expectedResultSingleProjectFileNameList}`); + const expectedResultSingleProjectFileNameList = ts.map(expectedResultSingleProject.files, f => f.path).sort(); + assert.isTrue(ts.arrayIsEqualTo(actualResultSingleProjectFileNameList, expectedResultSingleProjectFileNameList), `For project ${actualResultSingleProject.projectFileName}, the actual result is ${actualResultSingleProjectFileNameList}, while expected ${expectedResultSingleProjectFileNameList}`); } } describe("for configured projects", () => { - let moduleFile1: File; - let file1Consumer1: File; - let file1Consumer2: File; - let moduleFile2: File; - let globalFile3: File; - let configFile: File; - let changeModuleFile1ShapeRequest1: server.protocol.Request; - let changeModuleFile1InternalRequest1: server.protocol.Request; + let moduleFile1: ts.projectSystem.File; + let file1Consumer1: ts.projectSystem.File; + let file1Consumer2: ts.projectSystem.File; + let moduleFile2: ts.projectSystem.File; + let globalFile3: ts.projectSystem.File; + let configFile: ts.projectSystem.File; + let changeModuleFile1ShapeRequest1: ts.server.protocol.Request; + let changeModuleFile1InternalRequest1: ts.server.protocol.Request; // A compile on save affected file request using file1 - let moduleFile1FileListRequest: server.protocol.Request; + let moduleFile1FileListRequest: ts.server.protocol.Request; beforeEach(() => { moduleFile1 = { @@ -71,7 +72,7 @@ namespace ts.projectSystem { }; // Change the content of file1 to `export var T: number;export function Foo() { };` - changeModuleFile1ShapeRequest1 = makeSessionRequest(CommandNames.Change, { + changeModuleFile1ShapeRequest1 = ts.projectSystem.makeSessionRequest(CommandNames.Change, { file: moduleFile1.path, line: 1, offset: 1, @@ -81,7 +82,7 @@ namespace ts.projectSystem { }); // Change the content of file1 to `export var T: number;export function Foo() { };` - changeModuleFile1InternalRequest1 = makeSessionRequest(CommandNames.Change, { + changeModuleFile1InternalRequest1 = ts.projectSystem.makeSessionRequest(CommandNames.Change, { file: moduleFile1.path, line: 1, offset: 1, @@ -90,15 +91,14 @@ namespace ts.projectSystem { insertString: `var T1: number;` }); - moduleFile1FileListRequest = makeSessionRequest(CommandNames.CompileOnSaveAffectedFileList, { file: moduleFile1.path, projectFileName: configFile.path }); + moduleFile1FileListRequest = ts.projectSystem.makeSessionRequest(CommandNames.CompileOnSaveAffectedFileList, { file: moduleFile1.path, projectFileName: configFile.path }); }); it("should contains only itself if a module file's shape didn't change, and all files referencing it if its shape changed", () => { - const host = createServerHost([moduleFile1, file1Consumer1, file1Consumer2, globalFile3, moduleFile2, configFile, libFile]); + const host = ts.projectSystem.createServerHost([moduleFile1, file1Consumer1, file1Consumer2, globalFile3, moduleFile2, configFile, ts.projectSystem.libFile]); const typingsInstaller = createTestTypingsInstaller(host); - const session = createSession(host, { typingsInstaller }); - - openFilesForSession([moduleFile1, file1Consumer1], session); + const session = ts.projectSystem.createSession(host, { typingsInstaller }); + ts.projectSystem.openFilesForSession([moduleFile1, file1Consumer1], session); // Send an initial compileOnSave request sendAffectedFileRequestAndCheckResult(session, moduleFile1FileListRequest, [{ projectFileName: configFile.path, files: [moduleFile1, file1Consumer1, file1Consumer2] }]); @@ -106,7 +106,7 @@ namespace ts.projectSystem { sendAffectedFileRequestAndCheckResult(session, moduleFile1FileListRequest, [{ projectFileName: configFile.path, files: [moduleFile1, file1Consumer1, file1Consumer2] }]); // Change the content of file1 to `export var T: number;export function Foo() { console.log('hi'); };` - const changeFile1InternalRequest = makeSessionRequest(CommandNames.Change, { + const changeFile1InternalRequest = ts.projectSystem.makeSessionRequest(CommandNames.Change, { file: moduleFile1.path, line: 1, offset: 46, @@ -119,17 +119,16 @@ namespace ts.projectSystem { }); it("should be up-to-date with the reference map changes", () => { - const host = createServerHost([moduleFile1, file1Consumer1, file1Consumer2, globalFile3, moduleFile2, configFile, libFile]); + const host = ts.projectSystem.createServerHost([moduleFile1, file1Consumer1, file1Consumer2, globalFile3, moduleFile2, configFile, ts.projectSystem.libFile]); const typingsInstaller = createTestTypingsInstaller(host); - const session = createSession(host, { typingsInstaller }); - - openFilesForSession([moduleFile1, file1Consumer1], session); + const session = ts.projectSystem.createSession(host, { typingsInstaller }); + ts.projectSystem.openFilesForSession([moduleFile1, file1Consumer1], session); // Send an initial compileOnSave request sendAffectedFileRequestAndCheckResult(session, moduleFile1FileListRequest, [{ projectFileName: configFile.path, files: [moduleFile1, file1Consumer1, file1Consumer2] }]); // Change file2 content to `let y = Foo();` - const removeFile1Consumer1ImportRequest = makeSessionRequest(CommandNames.Change, { + const removeFile1Consumer1ImportRequest = ts.projectSystem.makeSessionRequest(CommandNames.Change, { file: file1Consumer1.path, line: 1, offset: 1, @@ -142,7 +141,7 @@ namespace ts.projectSystem { sendAffectedFileRequestAndCheckResult(session, moduleFile1FileListRequest, [{ projectFileName: configFile.path, files: [moduleFile1, file1Consumer2] }]); // Add the import statements back to file2 - const addFile2ImportRequest = makeSessionRequest(CommandNames.Change, { + const addFile2ImportRequest = ts.projectSystem.makeSessionRequest(CommandNames.Change, { file: file1Consumer1.path, line: 1, offset: 1, @@ -153,7 +152,7 @@ namespace ts.projectSystem { session.executeCommand(addFile2ImportRequest); // Change the content of file1 to `export var T2: string;export var T: number;export function Foo() { };` - const changeModuleFile1ShapeRequest2 = makeSessionRequest(CommandNames.Change, { + const changeModuleFile1ShapeRequest2 = ts.projectSystem.makeSessionRequest(CommandNames.Change, { file: moduleFile1.path, line: 1, offset: 1, @@ -166,11 +165,10 @@ namespace ts.projectSystem { }); it("should be up-to-date with changes made in non-open files", () => { - const host = createServerHost([moduleFile1, file1Consumer1, file1Consumer2, globalFile3, moduleFile2, configFile, libFile]); + const host = ts.projectSystem.createServerHost([moduleFile1, file1Consumer1, file1Consumer2, globalFile3, moduleFile2, configFile, ts.projectSystem.libFile]); const typingsInstaller = createTestTypingsInstaller(host); - const session = createSession(host, { typingsInstaller }); - - openFilesForSession([moduleFile1], session); + const session = ts.projectSystem.createSession(host, { typingsInstaller }); + ts.projectSystem.openFilesForSession([moduleFile1], session); // Send an initial compileOnSave request sendAffectedFileRequestAndCheckResult(session, moduleFile1FileListRequest, [{ projectFileName: configFile.path, files: [moduleFile1, file1Consumer1, file1Consumer2] }]); @@ -182,11 +180,10 @@ namespace ts.projectSystem { }); it("should be up-to-date with deleted files", () => { - const host = createServerHost([moduleFile1, file1Consumer1, file1Consumer2, globalFile3, moduleFile2, configFile, libFile]); + const host = ts.projectSystem.createServerHost([moduleFile1, file1Consumer1, file1Consumer2, globalFile3, moduleFile2, configFile, ts.projectSystem.libFile]); const typingsInstaller = createTestTypingsInstaller(host); - const session = createSession(host, { typingsInstaller }); - - openFilesForSession([moduleFile1], session); + const session = ts.projectSystem.createSession(host, { typingsInstaller }); + ts.projectSystem.openFilesForSession([moduleFile1], session); sendAffectedFileRequestAndCheckResult(session, moduleFile1FileListRequest, [{ projectFileName: configFile.path, files: [moduleFile1, file1Consumer1, file1Consumer2] }]); session.executeCommand(changeModuleFile1ShapeRequest1); @@ -196,14 +193,13 @@ namespace ts.projectSystem { }); it("should be up-to-date with newly created files", () => { - const host = createServerHost([moduleFile1, file1Consumer1, file1Consumer2, globalFile3, moduleFile2, configFile, libFile]); + const host = ts.projectSystem.createServerHost([moduleFile1, file1Consumer1, file1Consumer2, globalFile3, moduleFile2, configFile, ts.projectSystem.libFile]); const typingsInstaller = createTestTypingsInstaller(host); - const session = createSession(host, { typingsInstaller }); - - openFilesForSession([moduleFile1], session); + const session = ts.projectSystem.createSession(host, { typingsInstaller }); + ts.projectSystem.openFilesForSession([moduleFile1], session); sendAffectedFileRequestAndCheckResult(session, moduleFile1FileListRequest, [{ projectFileName: configFile.path, files: [moduleFile1, file1Consumer1, file1Consumer2] }]); - const file1Consumer3: File = { + const file1Consumer3: ts.projectSystem.File = { path: "/a/b/file1Consumer3.ts", content: `import {Foo} from "./moduleFile1"; let y = Foo();` }; @@ -232,11 +228,10 @@ namespace ts.projectSystem { }` }; - const host = createServerHost([moduleFile1, file1Consumer1, configFile, libFile]); + const host = ts.projectSystem.createServerHost([moduleFile1, file1Consumer1, configFile, ts.projectSystem.libFile]); const typingsInstaller = createTestTypingsInstaller(host); - const session = createSession(host, { typingsInstaller }); - - openFilesForSession([moduleFile1, file1Consumer1], session); + const session = ts.projectSystem.createSession(host, { typingsInstaller }); + ts.projectSystem.openFilesForSession([moduleFile1, file1Consumer1], session); sendAffectedFileRequestAndCheckResult(session, moduleFile1FileListRequest, [{ projectFileName: configFile.path, files: [moduleFile1, file1Consumer1] }]); // change file1 shape now, and verify both files are affected @@ -249,12 +244,11 @@ namespace ts.projectSystem { }); it("should return all files if a global file changed shape", () => { - const host = createServerHost([moduleFile1, file1Consumer1, file1Consumer2, globalFile3, moduleFile2, configFile, libFile]); + const host = ts.projectSystem.createServerHost([moduleFile1, file1Consumer1, file1Consumer2, globalFile3, moduleFile2, configFile, ts.projectSystem.libFile]); const typingsInstaller = createTestTypingsInstaller(host); - const session = createSession(host, { typingsInstaller }); - - openFilesForSession([globalFile3], session); - const changeGlobalFile3ShapeRequest = makeSessionRequest(CommandNames.Change, { + const session = ts.projectSystem.createSession(host, { typingsInstaller }); + ts.projectSystem.openFilesForSession([globalFile3], session); + const changeGlobalFile3ShapeRequest = ts.projectSystem.makeSessionRequest(CommandNames.Change, { file: globalFile3.path, line: 1, offset: 1, @@ -265,7 +259,7 @@ namespace ts.projectSystem { // check after file1 shape changes session.executeCommand(changeGlobalFile3ShapeRequest); - const globalFile3FileListRequest = makeSessionRequest(CommandNames.CompileOnSaveAffectedFileList, { file: globalFile3.path }); + const globalFile3FileListRequest = ts.projectSystem.makeSessionRequest(CommandNames.CompileOnSaveAffectedFileList, { file: globalFile3.path }); sendAffectedFileRequestAndCheckResult(session, globalFile3FileListRequest, [{ projectFileName: configFile.path, files: [moduleFile1, file1Consumer1, file1Consumer2, globalFile3, moduleFile2] }]); }); @@ -275,10 +269,10 @@ namespace ts.projectSystem { content: `{}` }; - const host = createServerHost([moduleFile1, file1Consumer1, file1Consumer2, configFile, libFile]); + const host = ts.projectSystem.createServerHost([moduleFile1, file1Consumer1, file1Consumer2, configFile, ts.projectSystem.libFile]); const typingsInstaller = createTestTypingsInstaller(host); - const session = createSession(host, { typingsInstaller }); - openFilesForSession([moduleFile1], session); + const session = ts.projectSystem.createSession(host, { typingsInstaller }); + ts.projectSystem.openFilesForSession([moduleFile1], session); sendAffectedFileRequestAndCheckResult(session, moduleFile1FileListRequest, []); }); @@ -293,10 +287,10 @@ namespace ts.projectSystem { }` }; - const host = createServerHost([moduleFile1, file1Consumer1, file1Consumer2, configFile, libFile]); + const host = ts.projectSystem.createServerHost([moduleFile1, file1Consumer1, file1Consumer2, configFile, ts.projectSystem.libFile]); const typingsInstaller = createTestTypingsInstaller(host); - const session = createSession(host, { typingsInstaller }); - openFilesForSession([moduleFile1], session); + const session = ts.projectSystem.createSession(host, { typingsInstaller }); + ts.projectSystem.openFilesForSession([moduleFile1], session); sendAffectedFileRequestAndCheckResult(session, moduleFile1FileListRequest, []); }); @@ -308,18 +302,17 @@ namespace ts.projectSystem { }` }; - const configFile2: File = { + const configFile2: ts.projectSystem.File = { path: "/a/tsconfig.json", content: `{ "compileOnSave": true }` }; - const host = createServerHost([moduleFile1, file1Consumer1, file1Consumer2, configFile2, configFile, libFile]); + const host = ts.projectSystem.createServerHost([moduleFile1, file1Consumer1, file1Consumer2, configFile2, configFile, ts.projectSystem.libFile]); const typingsInstaller = createTestTypingsInstaller(host); - const session = createSession(host, { typingsInstaller }); - - openFilesForSession([moduleFile1, file1Consumer1], session); + const session = ts.projectSystem.createSession(host, { typingsInstaller }); + ts.projectSystem.openFilesForSession([moduleFile1, file1Consumer1], session); sendAffectedFileRequestAndCheckResult(session, moduleFile1FileListRequest, [{ projectFileName: configFile.path, files: [moduleFile1, file1Consumer1, file1Consumer2] }]); }); @@ -334,12 +327,11 @@ namespace ts.projectSystem { }` }; - const host = createServerHost([moduleFile1, file1Consumer1, configFile, libFile]); + const host = ts.projectSystem.createServerHost([moduleFile1, file1Consumer1, configFile, ts.projectSystem.libFile]); const typingsInstaller = createTestTypingsInstaller(host); - const session = createSession(host, { typingsInstaller }); - openFilesForSession([moduleFile1], session); - - const file1ChangeShapeRequest = makeSessionRequest(CommandNames.Change, { + const session = ts.projectSystem.createSession(host, { typingsInstaller }); + ts.projectSystem.openFilesForSession([moduleFile1], session); + const file1ChangeShapeRequest = ts.projectSystem.makeSessionRequest(CommandNames.Change, { file: moduleFile1.path, line: 1, offset: 27, @@ -363,12 +355,11 @@ namespace ts.projectSystem { }` }; - const host = createServerHost([moduleFile1, file1Consumer1, configFile, libFile]); + const host = ts.projectSystem.createServerHost([moduleFile1, file1Consumer1, configFile, ts.projectSystem.libFile]); const typingsInstaller = createTestTypingsInstaller(host); - const session = createSession(host, { typingsInstaller }); - openFilesForSession([moduleFile1], session); - - const file1ChangeShapeRequest = makeSessionRequest(CommandNames.Change, { + const session = ts.projectSystem.createSession(host, { typingsInstaller }); + ts.projectSystem.openFilesForSession([moduleFile1], session); + const file1ChangeShapeRequest = ts.projectSystem.makeSessionRequest(CommandNames.Change, { file: moduleFile1.path, line: 1, offset: 27, @@ -381,18 +372,17 @@ namespace ts.projectSystem { }); it("should return cascaded affected file list", () => { - const file1Consumer1Consumer1: File = { + const file1Consumer1Consumer1: ts.projectSystem.File = { path: "/a/b/file1Consumer1Consumer1.ts", content: `import {y} from "./file1Consumer1";` }; - const host = createServerHost([moduleFile1, file1Consumer1, file1Consumer1Consumer1, globalFile3, configFile, libFile]); + const host = ts.projectSystem.createServerHost([moduleFile1, file1Consumer1, file1Consumer1Consumer1, globalFile3, configFile, ts.projectSystem.libFile]); const typingsInstaller = createTestTypingsInstaller(host); - const session = createSession(host, { typingsInstaller }); - - openFilesForSession([moduleFile1, file1Consumer1], session); + const session = ts.projectSystem.createSession(host, { typingsInstaller }); + ts.projectSystem.openFilesForSession([moduleFile1, file1Consumer1], session); sendAffectedFileRequestAndCheckResult(session, moduleFile1FileListRequest, [{ projectFileName: configFile.path, files: [moduleFile1, file1Consumer1, file1Consumer1Consumer1] }]); - const changeFile1Consumer1ShapeRequest = makeSessionRequest(CommandNames.Change, { + const changeFile1Consumer1ShapeRequest = ts.projectSystem.makeSessionRequest(CommandNames.Change, { file: file1Consumer1.path, line: 2, offset: 1, @@ -406,39 +396,36 @@ namespace ts.projectSystem { }); it("should work fine for files with circular references", () => { - const file1: File = { + const file1: ts.projectSystem.File = { path: "/a/b/file1.ts", content: ` /// export var t1 = 10;` }; - const file2: File = { + const file2: ts.projectSystem.File = { path: "/a/b/file2.ts", content: ` /// export var t2 = 10;` }; - const host = createServerHost([file1, file2, configFile]); + const host = ts.projectSystem.createServerHost([file1, file2, configFile]); const typingsInstaller = createTestTypingsInstaller(host); - const session = createSession(host, { typingsInstaller }); - - openFilesForSession([file1, file2], session); - const file1AffectedListRequest = makeSessionRequest(CommandNames.CompileOnSaveAffectedFileList, { file: file1.path }); + const session = ts.projectSystem.createSession(host, { typingsInstaller }); + ts.projectSystem.openFilesForSession([file1, file2], session); + const file1AffectedListRequest = ts.projectSystem.makeSessionRequest(CommandNames.CompileOnSaveAffectedFileList, { file: file1.path }); sendAffectedFileRequestAndCheckResult(session, file1AffectedListRequest, [{ projectFileName: configFile.path, files: [file1, file2] }]); }); it("should return results for all projects if not specifying projectFileName", () => { - const file1: File = { path: "/a/b/file1.ts", content: "export var t = 10;" }; - const file2: File = { path: "/a/b/file2.ts", content: `import {t} from "./file1"; var t2 = 11;` }; - const file3: File = { path: "/a/c/file2.ts", content: `import {t} from "../b/file1"; var t3 = 11;` }; - const configFile1: File = { path: "/a/b/tsconfig.json", content: `{ "compileOnSave": true }` }; - const configFile2: File = { path: "/a/c/tsconfig.json", content: `{ "compileOnSave": true }` }; - - const host = createServerHost([file1, file2, file3, configFile1, configFile2]); - const session = createSession(host); - - openFilesForSession([file1, file2, file3], session); - const file1AffectedListRequest = makeSessionRequest(CommandNames.CompileOnSaveAffectedFileList, { file: file1.path }); + const file1: ts.projectSystem.File = { path: "/a/b/file1.ts", content: "export var t = 10;" }; + const file2: ts.projectSystem.File = { path: "/a/b/file2.ts", content: `import {t} from "./file1"; var t2 = 11;` }; + const file3: ts.projectSystem.File = { path: "/a/c/file2.ts", content: `import {t} from "../b/file1"; var t3 = 11;` }; + const configFile1: ts.projectSystem.File = { path: "/a/b/tsconfig.json", content: `{ "compileOnSave": true }` }; + const configFile2: ts.projectSystem.File = { path: "/a/c/tsconfig.json", content: `{ "compileOnSave": true }` }; + const host = ts.projectSystem.createServerHost([file1, file2, file3, configFile1, configFile2]); + const session = ts.projectSystem.createSession(host); + ts.projectSystem.openFilesForSession([file1, file2, file3], session); + const file1AffectedListRequest = ts.projectSystem.makeSessionRequest(CommandNames.CompileOnSaveAffectedFileList, { file: file1.path }); sendAffectedFileRequestAndCheckResult(session, file1AffectedListRequest, [ { projectFileName: configFile1.path, files: [file1, file2] }, @@ -447,38 +434,36 @@ namespace ts.projectSystem { }); it("should detect removed code file", () => { - const referenceFile1: File = { + const referenceFile1: ts.projectSystem.File = { path: "/a/b/referenceFile1.ts", content: ` /// export var x = Foo();` }; - const host = createServerHost([moduleFile1, referenceFile1, configFile]); - const session = createSession(host); - - openFilesForSession([referenceFile1], session); + const host = ts.projectSystem.createServerHost([moduleFile1, referenceFile1, configFile]); + const session = ts.projectSystem.createSession(host); + ts.projectSystem.openFilesForSession([referenceFile1], session); host.deleteFile(moduleFile1.path); - const request = makeSessionRequest(CommandNames.CompileOnSaveAffectedFileList, { file: referenceFile1.path }); + const request = ts.projectSystem.makeSessionRequest(CommandNames.CompileOnSaveAffectedFileList, { file: referenceFile1.path }); sendAffectedFileRequestAndCheckResult(session, request, [ { projectFileName: configFile.path, files: [referenceFile1] } ]); - const requestForMissingFile = makeSessionRequest(CommandNames.CompileOnSaveAffectedFileList, { file: moduleFile1.path }); + const requestForMissingFile = ts.projectSystem.makeSessionRequest(CommandNames.CompileOnSaveAffectedFileList, { file: moduleFile1.path }); sendAffectedFileRequestAndCheckResult(session, requestForMissingFile, []); }); it("should detect non-existing code file", () => { - const referenceFile1: File = { + const referenceFile1: ts.projectSystem.File = { path: "/a/b/referenceFile1.ts", content: ` /// export var x = Foo();` }; - const host = createServerHost([referenceFile1, configFile]); - const session = createSession(host); - - openFilesForSession([referenceFile1], session); - const request = makeSessionRequest(CommandNames.CompileOnSaveAffectedFileList, { file: referenceFile1.path }); + const host = ts.projectSystem.createServerHost([referenceFile1, configFile]); + const session = ts.projectSystem.createSession(host); + ts.projectSystem.openFilesForSession([referenceFile1], session); + const request = ts.projectSystem.makeSessionRequest(CommandNames.CompileOnSaveAffectedFileList, { file: referenceFile1.path }); sendAffectedFileRequestAndCheckResult(session, request, [ { projectFileName: configFile.path, files: [referenceFile1] } ]); @@ -486,7 +471,7 @@ namespace ts.projectSystem { }); describe("for changes in declaration files", () => { - function testDTS(dtsFileContents: string, tsFileContents: string, opts: CompilerOptions, expectDTSEmit: boolean) { + function testDTS(dtsFileContents: string, tsFileContents: string, opts: ts.CompilerOptions, expectDTSEmit: boolean) { const dtsFile = { path: "/a/runtime/a.d.ts", content: dtsFileContents @@ -502,37 +487,37 @@ namespace ts.projectSystem { compileOnSave: true }) }; - const host = createServerHost([dtsFile, f2, config]); - const session = createSession(host); + const host = ts.projectSystem.createServerHost([dtsFile, f2, config]); + const session = ts.projectSystem.createSession(host); session.executeCommand({ seq: 1, type: "request", command: "open", arguments: { file: dtsFile.path } - } as protocol.OpenRequest); + } as ts.projectSystem.protocol.OpenRequest); const projectService = session.getProjectService(); - checkNumberOfProjects(projectService, { configuredProjects: 1 }); + ts.projectSystem.checkNumberOfProjects(projectService, { configuredProjects: 1 }); const project = projectService.configuredProjects.get(config.path)!; - checkProjectRootFiles(project, [dtsFile.path, f2.path]); + ts.projectSystem.checkProjectRootFiles(project, [dtsFile.path, f2.path]); session.executeCommand({ seq: 2, type: "request", command: "open", arguments: { file: f2.path } - } as protocol.OpenRequest); - checkNumberOfProjects(session.getProjectService(), { configuredProjects: 1 }); + } as ts.projectSystem.protocol.OpenRequest); + ts.projectSystem.checkNumberOfProjects(session.getProjectService(), { configuredProjects: 1 }); const { response } = session.executeCommand({ seq: 3, type: "request", command: "compileOnSaveAffectedFileList", arguments: { file: dtsFile.path } - } as protocol.CompileOnSaveAffectedFileListRequest); + } as ts.projectSystem.protocol.CompileOnSaveAffectedFileListRequest); if (expectDTSEmit) { - assert.equal((response as protocol.CompileOnSaveAffectedFileListSingleProject[]).length, 1, "expected output from 1 project"); - assert.equal((response as protocol.CompileOnSaveAffectedFileListSingleProject[])[0].fileNames.length, 2, "expected to affect 2 files"); + assert.equal((response as ts.projectSystem.protocol.CompileOnSaveAffectedFileListSingleProject[]).length, 1, "expected output from 1 project"); + assert.equal((response as ts.projectSystem.protocol.CompileOnSaveAffectedFileListSingleProject[])[0].fileNames.length, 2, "expected to affect 2 files"); } else { - assert.equal((response as protocol.CompileOnSaveAffectedFileListSingleProject[]).length, 0, "expected no output"); + assert.equal((response as ts.projectSystem.protocol.CompileOnSaveAffectedFileListSingleProject[]).length, 0, "expected no output"); } @@ -541,8 +526,8 @@ namespace ts.projectSystem { type: "request", command: "compileOnSaveAffectedFileList", arguments: { file: f2.path } - } as protocol.CompileOnSaveAffectedFileListRequest); - assert.equal((response2 as protocol.CompileOnSaveAffectedFileListSingleProject[]).length, 1, "expected output from 1 project"); + } as ts.projectSystem.protocol.CompileOnSaveAffectedFileListRequest); + assert.equal((response2 as ts.projectSystem.protocol.CompileOnSaveAffectedFileListSingleProject[]).length, 1, "expected output from 1 project"); } it("should return empty array if change is made in a global declaration file", () => { @@ -550,8 +535,7 @@ namespace ts.projectSystem { /*dtsFileContents*/ "declare const x: string;", /*tsFileContents*/ "var y = 1;", /*opts*/ {}, - /*expectDTSEmit*/ false - ); + /*expectDTSEmit*/ false); }); it("should return empty array if change is made in a module declaration file", () => { @@ -559,8 +543,7 @@ namespace ts.projectSystem { /*dtsFileContents*/ "export const x: string;", /*tsFileContents*/ "import { x } from './runtime/a;", /*opts*/ {}, - /*expectDTSEmit*/ false - ); + /*expectDTSEmit*/ false); }); it("should return results if change is made in a global declaration file with declaration emit", () => { @@ -568,8 +551,7 @@ namespace ts.projectSystem { /*dtsFileContents*/ "declare const x: string;", /*tsFileContents*/ "var y = 1;", /*opts*/ { declaration: true }, - /*expectDTSEmit*/ true - ); + /*expectDTSEmit*/ true); }); it("should return results if change is made in a global declaration file with composite enabled", () => { @@ -577,8 +559,7 @@ namespace ts.projectSystem { /*dtsFileContents*/ "declare const x: string;", /*tsFileContents*/ "var y = 1;", /*opts*/ { composite: true }, - /*expectDTSEmit*/ true - ); + /*expectDTSEmit*/ true); }); it("should return results if change is made in a global declaration file with decorator emit enabled", () => { @@ -586,13 +567,12 @@ namespace ts.projectSystem { /*dtsFileContents*/ "declare const x: string;", /*tsFileContents*/ "var y = 1;", /*opts*/ { experimentalDecorators: true, emitDecoratorMetadata: true }, - /*expectDTSEmit*/ true - ); + /*expectDTSEmit*/ true); }); }); describe("tsserverProjectSystem emit with outFile or out setting", () => { - function test(opts: CompilerOptions, expectedUsesOutFile: boolean) { + function test(opts: ts.CompilerOptions, expectedUsesOutFile: boolean) { const f1 = { path: "/a/a.ts", content: "let x = 1" @@ -608,24 +588,24 @@ namespace ts.projectSystem { compileOnSave: true }) }; - const host = createServerHost([f1, f2, config]); - const session = createSession(host); + const host = ts.projectSystem.createServerHost([f1, f2, config]); + const session = ts.projectSystem.createSession(host); session.executeCommand({ seq: 1, type: "request", command: "open", arguments: { file: f1.path } - } as protocol.OpenRequest); - checkNumberOfProjects(session.getProjectService(), { configuredProjects: 1 }); + } as ts.projectSystem.protocol.OpenRequest); + ts.projectSystem.checkNumberOfProjects(session.getProjectService(), { configuredProjects: 1 }); const { response } = session.executeCommand({ seq: 2, type: "request", command: "compileOnSaveAffectedFileList", arguments: { file: f1.path } - } as protocol.CompileOnSaveAffectedFileListRequest); - assert.equal((response as protocol.CompileOnSaveAffectedFileListSingleProject[]).length, 1, "expected output for 1 project"); - assert.equal((response as protocol.CompileOnSaveAffectedFileListSingleProject[])[0].fileNames.length, 2, "expected output for 1 project"); - assert.equal((response as protocol.CompileOnSaveAffectedFileListSingleProject[])[0].projectUsesOutFile, expectedUsesOutFile, "usesOutFile"); + } as ts.projectSystem.protocol.CompileOnSaveAffectedFileListRequest); + assert.equal((response as ts.projectSystem.protocol.CompileOnSaveAffectedFileListSingleProject[]).length, 1, "expected output for 1 project"); + assert.equal((response as ts.projectSystem.protocol.CompileOnSaveAffectedFileListSingleProject[])[0].fileNames.length, 2, "expected output for 1 project"); + assert.equal((response as ts.projectSystem.protocol.CompileOnSaveAffectedFileListSingleProject[])[0].projectUsesOutFile, expectedUsesOutFile, "usesOutFile"); } it("projectUsesOutFile should not be returned if not set", () => { @@ -649,26 +629,26 @@ namespace ts.projectSystem { const lines = ["var x = 1;", "var y = 2;"]; const path = "/a/app"; const f = { - path: path + Extension.Ts, + path: path + ts.Extension.Ts, content: lines.join(newLine) }; - const host = createServerHost([f], { newLine }); - const session = createSession(host); - const openRequest: server.protocol.OpenRequest = { + const host = ts.projectSystem.createServerHost([f], { newLine }); + const session = ts.projectSystem.createSession(host); + const openRequest: ts.server.protocol.OpenRequest = { seq: 1, type: "request", - command: server.protocol.CommandTypes.Open, + command: ts.server.protocol.CommandTypes.Open, arguments: { file: f.path } }; session.executeCommand(openRequest); - const emitFileRequest: server.protocol.CompileOnSaveEmitFileRequest = { + const emitFileRequest: ts.server.protocol.CompileOnSaveEmitFileRequest = { seq: 2, type: "request", - command: server.protocol.CommandTypes.CompileOnSaveEmitFile, + command: ts.server.protocol.CommandTypes.CompileOnSaveEmitFile, arguments: { file: f.path } }; session.executeCommand(emitFileRequest); - const emitOutput = host.readFile(path + Extension.Js); + const emitOutput = host.readFile(path + ts.Extension.Js); assert.equal(emitOutput, f.content + newLine, "content of emit output should be identical with the input + newline"); } }); @@ -686,12 +666,11 @@ namespace ts.projectSystem { path: "/a/b/tsconfig.json", content: `{}` }; - const host = createServerHost([file1, file2, configFile, libFile], { newLine: "\r\n" }); + const host = ts.projectSystem.createServerHost([file1, file2, configFile, ts.projectSystem.libFile], { newLine: "\r\n" }); const typingsInstaller = createTestTypingsInstaller(host); - const session = createSession(host, { typingsInstaller }); - - openFilesForSession([file1, file2], session); - const compileFileRequest = makeSessionRequest(CommandNames.CompileOnSaveEmitFile, { file: file1.path, projectFileName: configFile.path }); + const session = ts.projectSystem.createSession(host, { typingsInstaller }); + ts.projectSystem.openFilesForSession([file1, file2], session); + const compileFileRequest = ts.projectSystem.makeSessionRequest(CommandNames.CompileOnSaveEmitFile, { file: file1.path, projectFileName: configFile.path }); session.executeCommand(compileFileRequest); const expectedEmittedFileName = "/a/b/f1.js"; @@ -714,12 +693,12 @@ namespace ts.projectSystem { content: "console.log('file3');" }; const externalProjectName = "/a/b/externalproject"; - const host = createServerHost([file1, file2, file3, libFile]); - const session = createSession(host); + const host = ts.projectSystem.createServerHost([file1, file2, file3, ts.projectSystem.libFile]); + const session = ts.projectSystem.createSession(host); const projectService = session.getProjectService(); projectService.openExternalProject({ - rootFiles: toExternalFiles([file1.path, file2.path]), + rootFiles: ts.projectSystem.toExternalFiles([file1.path, file2.path]), options: { allowJs: true, outFile: "dist.js", @@ -728,7 +707,7 @@ namespace ts.projectSystem { projectFileName: externalProjectName }); - const emitRequest = makeSessionRequest(CommandNames.CompileOnSaveEmitFile, { file: file1.path }); + const emitRequest = ts.projectSystem.makeSessionRequest(CommandNames.CompileOnSaveEmitFile, { file: file1.path }); session.executeCommand(emitRequest); const expectedOutFileName = "/a/b/dist.js"; @@ -746,13 +725,13 @@ namespace ts.projectSystem { content: "consonle.log('file1');" }; const externalProjectName = "/root/TypeScriptProject3/TypeScriptProject3/TypeScriptProject3.csproj"; - const host = createServerHost([file1, libFile]); - const session = createSession(host); + const host = ts.projectSystem.createServerHost([file1, ts.projectSystem.libFile]); + const session = ts.projectSystem.createSession(host); const projectService = session.getProjectService(); const outFileName = "bar.js"; projectService.openExternalProject({ - rootFiles: toExternalFiles([file1.path]), + rootFiles: ts.projectSystem.toExternalFiles([file1.path]), options: { outFile: outFileName, sourceMap: true, @@ -761,7 +740,7 @@ namespace ts.projectSystem { projectFileName: externalProjectName }); - const emitRequest = makeSessionRequest(CommandNames.CompileOnSaveEmitFile, { file: file1.path }); + const emitRequest = ts.projectSystem.makeSessionRequest(CommandNames.CompileOnSaveEmitFile, { file: file1.path }); session.executeCommand(emitRequest); // Verify js file @@ -778,7 +757,7 @@ namespace ts.projectSystem { verifyContentHasString(mapFileContent, `"sources":["${inputFileName}"]`); function verifyContentHasString(content: string, str: string) { - assert.isTrue(stringContains(content, str), `Expected "${content}" to have "${str}"`); + assert.isTrue(ts.stringContains(content, str), `Expected "${content}" to have "${str}"`); } }); @@ -794,8 +773,8 @@ namespace ts.projectSystem { }); function verify(richResponse: boolean | undefined) { - const config: File = { - path: `${tscWatch.projectRoot}/tsconfig.json`, + const config: ts.projectSystem.File = { + path: `${ts.tscWatch.projectRoot}/tsconfig.json`, content: JSON.stringify({ compileOnSave: true, compilerOptions: { @@ -806,38 +785,37 @@ namespace ts.projectSystem { exclude: ["node_modules"] }) }; - const file1: File = { - path: `${tscWatch.projectRoot}/file1.ts`, + const file1: ts.projectSystem.File = { + path: `${ts.tscWatch.projectRoot}/file1.ts`, content: "const x = 1;" }; - const file2: File = { - path: `${tscWatch.projectRoot}/file2.ts`, + const file2: ts.projectSystem.File = { + path: `${ts.tscWatch.projectRoot}/file2.ts`, content: "const y = 2;" }; - const host = createServerHost([file1, file2, config, libFile]); - const session = createSession(host); - openFilesForSession([file1], session); - - const affectedFileResponse = session.executeCommandSeq({ - command: protocol.CommandTypes.CompileOnSaveAffectedFileList, + const host = ts.projectSystem.createServerHost([file1, file2, config, ts.projectSystem.libFile]); + const session = ts.projectSystem.createSession(host); + ts.projectSystem.openFilesForSession([file1], session); + const affectedFileResponse = session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.CompileOnSaveAffectedFileList, arguments: { file: file1.path } - }).response as protocol.CompileOnSaveAffectedFileListSingleProject[]; + }).response as ts.projectSystem.protocol.CompileOnSaveAffectedFileListSingleProject[]; assert.deepEqual(affectedFileResponse, [ { fileNames: [file1.path, file2.path], projectFileName: config.path, projectUsesOutFile: false } ]); - const file1SaveResponse = session.executeCommandSeq({ - command: protocol.CommandTypes.CompileOnSaveEmitFile, + const file1SaveResponse = session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.CompileOnSaveEmitFile, arguments: { file: file1.path, richResponse } }).response; if (richResponse) { - assert.deepEqual(file1SaveResponse, { emitSkipped: false, diagnostics: emptyArray }); + assert.deepEqual(file1SaveResponse, { emitSkipped: false, diagnostics: ts.emptyArray }); } else { assert.isTrue(file1SaveResponse); } - assert.strictEqual(host.readFile(`${tscWatch.projectRoot}/test/file1.d.ts`), "declare const x = 1;\n"); - const file2SaveResponse = session.executeCommandSeq({ - command: protocol.CommandTypes.CompileOnSaveEmitFile, + assert.strictEqual(host.readFile(`${ts.tscWatch.projectRoot}/test/file1.d.ts`), "declare const x = 1;\n"); + const file2SaveResponse = session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.CompileOnSaveEmitFile, arguments: { file: file2.path, richResponse } }).response; if (richResponse) { @@ -847,9 +825,9 @@ namespace ts.projectSystem { start: undefined, end: undefined, fileName: undefined, - text: formatStringFromArgs(Diagnostics.Cannot_write_file_0_because_it_would_overwrite_input_file.message, [`${tscWatch.projectRoot}/test/file1.d.ts`]), - code: Diagnostics.Cannot_write_file_0_because_it_would_overwrite_input_file.code, - category: diagnosticCategoryName(Diagnostics.Cannot_write_file_0_because_it_would_overwrite_input_file), + text: ts.formatStringFromArgs(ts.Diagnostics.Cannot_write_file_0_because_it_would_overwrite_input_file.message, [`${ts.tscWatch.projectRoot}/test/file1.d.ts`]), + code: ts.Diagnostics.Cannot_write_file_0_because_it_would_overwrite_input_file.code, + category: ts.diagnosticCategoryName(ts.Diagnostics.Cannot_write_file_0_because_it_would_overwrite_input_file), reportsUnnecessary: undefined, reportsDeprecated: undefined, relatedInformation: undefined, @@ -860,7 +838,7 @@ namespace ts.projectSystem { else { assert.isFalse(file2SaveResponse); } - assert.isFalse(host.fileExists(`${tscWatch.projectRoot}/test/file2.d.ts`)); + assert.isFalse(host.fileExists(`${ts.tscWatch.projectRoot}/test/file2.d.ts`)); } }); @@ -882,8 +860,8 @@ namespace ts.projectSystem { }); }); function verifyGlobalSave(declaration: boolean,hasModule: boolean) { - const config: File = { - path: `${tscWatch.projectRoot}/tsconfig.json`, + const config: ts.projectSystem.File = { + path: `${ts.tscWatch.projectRoot}/tsconfig.json`, content: JSON.stringify({ compileOnSave: true, compilerOptions: { @@ -892,37 +870,36 @@ namespace ts.projectSystem { }, }) }; - const file1: File = { - path: `${tscWatch.projectRoot}/file1.ts`, + const file1: ts.projectSystem.File = { + path: `${ts.tscWatch.projectRoot}/file1.ts`, content: `const x = 1; function foo() { return "hello"; }` }; - const file2: File = { - path: `${tscWatch.projectRoot}/file2.ts`, + const file2: ts.projectSystem.File = { + path: `${ts.tscWatch.projectRoot}/file2.ts`, content: `const y = 2; function bar() { return "world"; }` }; - const file3: File = { - path: `${tscWatch.projectRoot}/file3.ts`, + const file3: ts.projectSystem.File = { + path: `${ts.tscWatch.projectRoot}/file3.ts`, content: "const xy = 3;" }; - const module: File = { - path: `${tscWatch.projectRoot}/module.ts`, + const module: ts.projectSystem.File = { + path: `${ts.tscWatch.projectRoot}/module.ts`, content: "export const xyz = 4;" }; - const files = [file1, file2, file3, ...(hasModule ? [module] : emptyArray)]; - const host = createServerHost([...files, config, libFile]); - const session = createSession(host); - openFilesForSession([file1, file2], session); - - const affectedFileResponse = session.executeCommandSeq({ - command: protocol.CommandTypes.CompileOnSaveAffectedFileList, + const files = [file1, file2, file3, ...(hasModule ? [module] : ts.emptyArray)]; + const host = ts.projectSystem.createServerHost([...files, config, ts.projectSystem.libFile]); + const session = ts.projectSystem.createSession(host); + ts.projectSystem.openFilesForSession([file1, file2], session); + const affectedFileResponse = session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.CompileOnSaveAffectedFileList, arguments: { file: file1.path } - }).response as protocol.CompileOnSaveAffectedFileListSingleProject[]; + }).response as ts.projectSystem.protocol.CompileOnSaveAffectedFileListSingleProject[]; assert.deepEqual(affectedFileResponse, [ { fileNames: files.map(f => f.path), projectFileName: config.path, projectUsesOutFile: false } ]); @@ -939,49 +916,43 @@ function bar() { // Change file2 get affected file list = will return only file2 if --declaration otherwise all files verifyLocalEdit(file2, "world", "hello", /*returnsAllFilesAsAffected*/ !declaration); - function verifyFileSave(file: File) { - const response = session.executeCommandSeq({ - command: protocol.CommandTypes.CompileOnSaveEmitFile, + function verifyFileSave(file: ts.projectSystem.File) { + const response = session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.CompileOnSaveEmitFile, arguments: { file: file.path } }).response; assert.isTrue(response); - assert.strictEqual( - host.readFile(changeExtension(file.path, ".js")), - file === module ? + assert.strictEqual(host.readFile(ts.changeExtension(file.path, ".js")), file === module ? `"use strict";\nexports.__esModule = true;\nexports.xyz = void 0;\nexports.xyz = 4;\n` : - `${file.content.replace("const", "var")}\n` - ); + `${file.content.replace("const", "var")}\n`); if (declaration) { - assert.strictEqual( - host.readFile(changeExtension(file.path, ".d.ts")), - (file.content.substr(0, file.content.indexOf(" {") === -1 ? file.content.length : file.content.indexOf(" {")) + assert.strictEqual(host.readFile(ts.changeExtension(file.path, ".d.ts")), (file.content.substr(0, file.content.indexOf(" {") === -1 ? file.content.length : file.content.indexOf(" {")) .replace("const ", "declare const ") .replace("function ", "declare function ") - .replace(")", "): string;")) + "\n" - ); + .replace(")", "): string;")) + "\n"); } } - function verifyLocalEdit(file: File, oldText: string, newText: string, returnsAllFilesAsAffected?: boolean) { + function verifyLocalEdit(file: ts.projectSystem.File, oldText: string, newText: string, returnsAllFilesAsAffected?: boolean) { // Change file1 get affected file list - session.executeCommandSeq({ - command: protocol.CommandTypes.UpdateOpen, + session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.UpdateOpen, arguments: { changedFiles: [{ fileName: file.path, textChanges: [{ newText, - ...protocolTextSpanFromSubstring(file.content, oldText) + ...ts.projectSystem.protocolTextSpanFromSubstring(file.content, oldText) }] }] } }); - const affectedFileResponse = session.executeCommandSeq({ - command: protocol.CommandTypes.CompileOnSaveAffectedFileList, + const affectedFileResponse = session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.CompileOnSaveAffectedFileList, arguments: { file: file.path } - }).response as protocol.CompileOnSaveAffectedFileListSingleProject[]; + }).response as ts.projectSystem.protocol.CompileOnSaveAffectedFileListSingleProject[]; assert.deepEqual(affectedFileResponse, [ - { fileNames: [file.path, ...(returnsAllFilesAsAffected ? files.filter(f => f !== file).map(f => f.path) : emptyArray)], projectFileName: config.path, projectUsesOutFile: false } + { fileNames: [file.path, ...(returnsAllFilesAsAffected ? files.filter(f => f !== file).map(f => f.path) : ts.emptyArray)], projectFileName: config.path, projectUsesOutFile: false } ]); file.content = file.content.replace(oldText, newText); verifyFileSave(file); @@ -991,39 +962,38 @@ function bar() { }); describe("unittests:: tsserver:: compileOnSave:: CompileOnSaveAffectedFileListRequest with and without projectFileName in request", () => { - const core: File = { - path: `${tscWatch.projectRoot}/core/core.ts`, + const core: ts.projectSystem.File = { + path: `${ts.tscWatch.projectRoot}/core/core.ts`, content: "let z = 10;" }; - const app1: File = { - path: `${tscWatch.projectRoot}/app1/app.ts`, + const app1: ts.projectSystem.File = { + path: `${ts.tscWatch.projectRoot}/app1/app.ts`, content: "let x = 10;" }; - const app2: File = { - path: `${tscWatch.projectRoot}/app2/app.ts`, + const app2: ts.projectSystem.File = { + path: `${ts.tscWatch.projectRoot}/app2/app.ts`, content: "let y = 10;" }; - const app1Config: File = { - path: `${tscWatch.projectRoot}/app1/tsconfig.json`, + const app1Config: ts.projectSystem.File = { + path: `${ts.tscWatch.projectRoot}/app1/tsconfig.json`, content: JSON.stringify({ files: ["app.ts", "../core/core.ts"], compilerOptions: { outFile: "build/output.js" }, compileOnSave: true }) }; - const app2Config: File = { - path: `${tscWatch.projectRoot}/app2/tsconfig.json`, + const app2Config: ts.projectSystem.File = { + path: `${ts.tscWatch.projectRoot}/app2/tsconfig.json`, content: JSON.stringify({ files: ["app.ts", "../core/core.ts"], compilerOptions: { outFile: "build/output.js" }, compileOnSave: true }) }; - const files = [libFile, core, app1, app2, app1Config, app2Config]; - - function insertString(session: TestSession, file: File) { - session.executeCommandSeq({ - command: protocol.CommandTypes.Change, + const files = [ts.projectSystem.libFile, core, app1, app2, app1Config, app2Config]; + function insertString(session: ts.projectSystem.TestSession, file: ts.projectSystem.File) { + session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.Change, arguments: { file: file.path, line: 1, @@ -1036,15 +1006,15 @@ function bar() { } function getSession() { - const host = createServerHost(files); - const session = createSession(host); - openFilesForSession([app1, app2, core], session); + const host = ts.projectSystem.createServerHost(files); + const session = ts.projectSystem.createSession(host); + ts.projectSystem.openFilesForSession([app1, app2, core], session); const service = session.getProjectService(); - checkNumberOfProjects(session.getProjectService(), { configuredProjects: 2 }); + ts.projectSystem.checkNumberOfProjects(session.getProjectService(), { configuredProjects: 2 }); const project1 = service.configuredProjects.get(app1Config.path)!; const project2 = service.configuredProjects.get(app2Config.path)!; - checkProjectActualFiles(project1, [libFile.path, app1.path, core.path, app1Config.path]); - checkProjectActualFiles(project2, [libFile.path, app2.path, core.path, app2Config.path]); + ts.projectSystem.checkProjectActualFiles(project1, [ts.projectSystem.libFile.path, app1.path, core.path, app1Config.path]); + ts.projectSystem.checkProjectActualFiles(project2, [ts.projectSystem.libFile.path, app2.path, core.path, app2Config.path]); insertString(session, app1); insertString(session, app2); assert.equal(project1.dirty, true); @@ -1054,8 +1024,8 @@ function bar() { it("when projectFile is specified", () => { const session = getSession(); - const response = session.executeCommandSeq({ - command: protocol.CommandTypes.CompileOnSaveAffectedFileList, + const response = session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.CompileOnSaveAffectedFileList, arguments: { file: core.path, projectFileName: app1Config.path @@ -1070,8 +1040,8 @@ function bar() { it("when projectFile is not specified", () => { const session = getSession(); - const response = session.executeCommandSeq({ - command: protocol.CommandTypes.CompileOnSaveAffectedFileList, + const response = session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.CompileOnSaveAffectedFileList, arguments: { file: core.path } diff --git a/src/testRunner/unittests/tsserver/completions.ts b/src/testRunner/unittests/tsserver/completions.ts index 3da4c8fe8ca28..c3ddb55416fd4 100644 --- a/src/testRunner/unittests/tsserver/completions.ts +++ b/src/testRunner/unittests/tsserver/completions.ts @@ -1,44 +1,43 @@ namespace ts.projectSystem { describe("unittests:: tsserver:: completions", () => { it("works", () => { - const aTs: File = { + const aTs: ts.projectSystem.File = { path: "/a.ts", content: "export const foo = 0;", }; - const bTs: File = { + const bTs: ts.projectSystem.File = { path: "/b.ts", content: "foo", }; - const tsconfig: File = { + const tsconfig: ts.projectSystem.File = { path: "/tsconfig.json", content: "{}", }; - const session = createSession(createServerHost([aTs, bTs, tsconfig])); - openFilesForSession([aTs, bTs], session); - - const requestLocation: protocol.FileLocationRequestArgs = { + const session = ts.projectSystem.createSession(ts.projectSystem.createServerHost([aTs, bTs, tsconfig])); + ts.projectSystem.openFilesForSession([aTs, bTs], session); + const requestLocation: ts.projectSystem.protocol.FileLocationRequestArgs = { file: bTs.path, line: 1, offset: 3, }; - const response = executeSessionRequest(session, protocol.CommandTypes.CompletionInfo, { + const response = ts.projectSystem.executeSessionRequest(session, ts.projectSystem.protocol.CommandTypes.CompletionInfo, { ...requestLocation, includeExternalModuleExports: true, prefix: "foo", }); - const entry: protocol.CompletionEntry = { + const entry: ts.projectSystem.protocol.CompletionEntry = { hasAction: true, insertText: undefined, isRecommended: undefined, - kind: ScriptElementKind.constElement, - kindModifiers: ScriptElementKindModifier.exportedModifier, + kind: ts.ScriptElementKind.constElement, + kindModifiers: ts.ScriptElementKindModifier.exportedModifier, name: "foo", replacementSpan: undefined, isPackageJsonImport: undefined, isImportStatementCompletion: undefined, - sortText: Completions.SortText.AutoImportSuggestions, + sortText: ts.Completions.SortText.AutoImportSuggestions, source: "/a", sourceDisplay: undefined, isSnippet: undefined, @@ -51,8 +50,8 @@ namespace ts.projectSystem { const exportMapKey = (response?.entries[0].data as any)?.exportMapKey; assert.isString(exportMapKey); delete (response?.entries[0].data as any).exportMapKey; - assert.deepEqual(response, { - flags: CompletionInfoFlags.MayIncludeAutoImports, + assert.deepEqual(response, { + flags: ts.CompletionInfoFlags.MayIncludeAutoImports, isGlobalCompletion: true, isIncomplete: undefined, isMemberCompletion: false, @@ -61,29 +60,29 @@ namespace ts.projectSystem { entries: [entry], }); - const detailsRequestArgs: protocol.CompletionDetailsRequestArgs = { + const detailsRequestArgs: ts.projectSystem.protocol.CompletionDetailsRequestArgs = { ...requestLocation, entryNames: [{ name: "foo", source: "/a", data: { exportName: "foo", fileName: "/a.ts", exportMapKey } }], }; - const detailsResponse = executeSessionRequest(session, protocol.CommandTypes.CompletionDetails, detailsRequestArgs); - const detailsCommon: protocol.CompletionEntryDetails & CompletionEntryDetails = { + const detailsResponse = ts.projectSystem.executeSessionRequest(session, ts.projectSystem.protocol.CommandTypes.CompletionDetails, detailsRequestArgs); + const detailsCommon: ts.projectSystem.protocol.CompletionEntryDetails & ts.CompletionEntryDetails = { displayParts: [ - keywordPart(SyntaxKind.ConstKeyword), - spacePart(), - displayPart("foo", SymbolDisplayPartKind.localName), - punctuationPart(SyntaxKind.ColonToken), - spacePart(), - displayPart("0", SymbolDisplayPartKind.stringLiteral), + ts.keywordPart(ts.SyntaxKind.ConstKeyword), + ts.spacePart(), + ts.displayPart("foo", ts.SymbolDisplayPartKind.localName), + ts.punctuationPart(ts.SyntaxKind.ColonToken), + ts.spacePart(), + ts.displayPart("0", ts.SymbolDisplayPartKind.stringLiteral), ], - documentation: emptyArray, - kind: ScriptElementKind.constElement, - kindModifiers: ScriptElementKindModifier.exportedModifier, + documentation: ts.emptyArray, + kind: ts.ScriptElementKind.constElement, + kindModifiers: ts.ScriptElementKindModifier.exportedModifier, name: "foo", source: [{ text: "./a", kind: "text" }], sourceDisplay: [{ text: "./a", kind: "text" }], }; - assert.deepEqual(detailsResponse, [ + assert.deepEqual(detailsResponse, [ { codeActions: [ { @@ -108,15 +107,15 @@ namespace ts.projectSystem { }, ]); - interface CompletionDetailsFullRequest extends protocol.FileLocationRequest { - readonly command: protocol.CommandTypes.CompletionDetailsFull; - readonly arguments: protocol.CompletionDetailsRequestArgs; + interface CompletionDetailsFullRequest extends ts.projectSystem.protocol.FileLocationRequest { + readonly command: ts.projectSystem.protocol.CommandTypes.CompletionDetailsFull; + readonly arguments: ts.projectSystem.protocol.CompletionDetailsRequestArgs; } - interface CompletionDetailsFullResponse extends protocol.Response { - readonly body?: readonly CompletionEntryDetails[]; + interface CompletionDetailsFullResponse extends ts.projectSystem.protocol.Response { + readonly body?: readonly ts.CompletionEntryDetails[]; } - const detailsFullResponse = executeSessionRequest(session, protocol.CommandTypes.CompletionDetailsFull, detailsRequestArgs); - assert.deepEqual(detailsFullResponse, [ + const detailsFullResponse = ts.projectSystem.executeSessionRequest(session, ts.projectSystem.protocol.CommandTypes.CompletionDetailsFull, detailsRequestArgs); + assert.deepEqual(detailsFullResponse, [ { codeActions: [ { @@ -124,7 +123,7 @@ namespace ts.projectSystem { changes: [ { fileName: "/b.ts", - textChanges: [createTextChange(createTextSpan(0, 0), 'import { foo } from "./a";\n\n')], + textChanges: [ts.createTextChange(ts.createTextSpan(0, 0), 'import { foo } from "./a";\n\n')], }, ], commands: undefined, @@ -138,7 +137,7 @@ namespace ts.projectSystem { it("works when files are included from two different drives of windows", () => { const projectRoot = "e:/myproject"; - const appPackage: File = { + const appPackage: ts.projectSystem.File = { path: `${projectRoot}/package.json`, content: JSON.stringify({ name: "test", @@ -149,7 +148,7 @@ namespace ts.projectSystem { } }) }; - const appFile: File = { + const appFile: ts.projectSystem.File = { path: `${projectRoot}/src/app.js`, content: `import React from 'react'; import { @@ -159,37 +158,37 @@ import { }; const localNodeModules = `${projectRoot}/node_modules`; const localAtTypes = `${localNodeModules}/@types`; - const localReactPackage: File = { + const localReactPackage: ts.projectSystem.File = { path: `${localAtTypes}/react/package.json`, content: JSON.stringify({ name: "@types/react", version: "16.9.14", }) }; - const localReact: File = { + const localReact: ts.projectSystem.File = { path: `${localAtTypes}/react/index.d.ts`, content: `import * as PropTypes from 'prop-types'; ` }; - const localReactRouterDomPackage: File = { + const localReactRouterDomPackage: ts.projectSystem.File = { path: `${localNodeModules}/react-router-dom/package.json`, content: JSON.stringify({ name: "react-router-dom", version: "5.1.2", }) }; - const localReactRouterDom: File = { + const localReactRouterDom: ts.projectSystem.File = { path: `${localNodeModules}/react-router-dom/index.js`, content: `export function foo() {}` }; - const localPropTypesPackage: File = { + const localPropTypesPackage: ts.projectSystem.File = { path: `${localAtTypes}/prop-types/package.json`, content: JSON.stringify({ name: "@types/prop-types", version: "15.7.3", }) }; - const localPropTypes: File = { + const localPropTypes: ts.projectSystem.File = { path: `${localAtTypes}/prop-types/index.d.ts`, content: `export type ReactComponentLike = | string @@ -200,14 +199,14 @@ import { const globalCacheLocation = `c:/typescript`; const globalAtTypes = `${globalCacheLocation}/node_modules/@types`; - const globalReactRouterDomPackage: File = { + const globalReactRouterDomPackage: ts.projectSystem.File = { path: `${globalAtTypes}/react-router-dom/package.json`, content: JSON.stringify({ name: "@types/react-router-dom", version: "5.1.2", }) }; - const globalReactRouterDom: File = { + const globalReactRouterDom: ts.projectSystem.File = { path: `${globalAtTypes}/react-router-dom/index.d.ts`, content: `import * as React from 'react'; export interface BrowserRouterProps { @@ -217,11 +216,11 @@ export interface BrowserRouterProps { keyLength?: number; }` }; - const globalReactPackage: File = { + const globalReactPackage: ts.projectSystem.File = { path: `${globalAtTypes}/react/package.json`, content: localReactPackage.content }; - const globalReact: File = { + const globalReact: ts.projectSystem.File = { path: `${globalAtTypes}/react/index.d.ts`, content: localReact.content }; @@ -235,7 +234,8 @@ export interface BrowserRouterProps { ]; const files = [ ...filesInProject, - appPackage, libFile, + appPackage, + ts.projectSystem.libFile, localReactPackage, localReactRouterDomPackage, localReactRouterDom, localPropTypesPackage, @@ -243,17 +243,17 @@ export interface BrowserRouterProps { globalReactPackage, ]; - const host = createServerHost(files, { windowsStyleRoot: "c:/" }); - const session = createSession(host, { - typingsInstaller: new TestTypingsInstaller(globalCacheLocation, /*throttleLimit*/ 5, host), + const host = ts.projectSystem.createServerHost(files, { windowsStyleRoot: "c:/" }); + const session = ts.projectSystem.createSession(host, { + typingsInstaller: new ts.projectSystem.TestTypingsInstaller(globalCacheLocation, /*throttleLimit*/ 5, host), }); const service = session.getProjectService(); - openFilesForSession([appFile], session); - checkNumberOfProjects(service, { inferredProjects: 1 }); - const windowsStyleLibFilePath = "c:/" + libFile.path.substring(1); - checkProjectActualFiles(service.inferredProjects[0], filesInProject.map(f => f.path).concat(windowsStyleLibFilePath)); - session.executeCommandSeq({ - command: protocol.CommandTypes.CompletionInfo, + ts.projectSystem.openFilesForSession([appFile], session); + ts.projectSystem.checkNumberOfProjects(service, { inferredProjects: 1 }); + const windowsStyleLibFilePath = "c:/" + ts.projectSystem.libFile.path.substring(1); + ts.projectSystem.checkProjectActualFiles(service.inferredProjects[0], filesInProject.map(f => f.path).concat(windowsStyleLibFilePath)); + session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.CompletionInfo, arguments: { file: appFile.path, line: 5, diff --git a/src/testRunner/unittests/tsserver/completionsIncomplete.ts b/src/testRunner/unittests/tsserver/completionsIncomplete.ts index 0bdef496d1de1..3d8fc0c476ecb 100644 --- a/src/testRunner/unittests/tsserver/completionsIncomplete.ts +++ b/src/testRunner/unittests/tsserver/completionsIncomplete.ts @@ -1,19 +1,16 @@ namespace ts.projectSystem { - function createExportingModuleFile(path: string, exportPrefix: string, exportCount: number): File { + function createExportingModuleFile(path: string, exportPrefix: string, exportCount: number): ts.projectSystem.File { return { path, - content: fill(exportCount, i => `export const ${exportPrefix}_${i} = ${i};`).join("\n"), + content: ts.fill(exportCount, i => `export const ${exportPrefix}_${i} = ${i};`).join("\n"), }; } - function createExportingModuleFiles(pathPrefix: string, fileCount: number, exportCount: number, getExportPrefix: (fileIndex: number) => string): File[] { - return fill(fileCount, fileIndex => createExportingModuleFile( - `${pathPrefix}_${fileIndex}.ts`, - getExportPrefix(fileIndex), - exportCount)); + function createExportingModuleFiles(pathPrefix: string, fileCount: number, exportCount: number, getExportPrefix: (fileIndex: number) => string): ts.projectSystem.File[] { + return ts.fill(fileCount, fileIndex => createExportingModuleFile(`${pathPrefix}_${fileIndex}.ts`, getExportPrefix(fileIndex), exportCount)); } - function createNodeModulesPackage(packageName: string, fileCount: number, exportCount: number, getExportPrefix: (fileIndex: number) => string): File[] { + function createNodeModulesPackage(packageName: string, fileCount: number, exportCount: number, getExportPrefix: (fileIndex: number) => string): ts.projectSystem.File[] { const exportingFiles = createExportingModuleFiles(`/node_modules/${packageName}/file`, fileCount, exportCount, getExportPrefix); return [ { @@ -23,43 +20,43 @@ namespace ts.projectSystem { { path: `/node_modules/${packageName}/index.d.ts`, content: exportingFiles - .map(f => `export * from "./${removeFileExtension(convertToRelativePath(f.path, `/node_modules/${packageName}/`, identity))}";`) + .map(f => `export * from "./${ts.removeFileExtension(ts.convertToRelativePath(f.path, `/node_modules/${packageName}/`, ts.identity))}";`) .join("\n") + `\nexport default function main(): void;`, }, ...exportingFiles, ]; } - const indexFile: File = { + const indexFile: ts.projectSystem.File = { path: "/index.ts", content: "" }; - const tsconfigFile: File = { + const tsconfigFile: ts.projectSystem.File = { path: "/tsconfig.json", content: `{ "compilerOptions": { "module": "commonjs" } }` }; - const packageJsonFile: File = { + const packageJsonFile: ts.projectSystem.File = { path: "/package.json", content: `{ "dependencies": { "dep-a": "*" } }`, }; describe("unittests:: tsserver:: completionsIncomplete", () => { it("works", () => { - const excessFileCount = Completions.moduleSpecifierResolutionLimit + 50; - const exportingFiles = createExportingModuleFiles(`/lib/a`, Completions.moduleSpecifierResolutionLimit + excessFileCount, 1, i => `aa_${i}_`); + const excessFileCount = ts.Completions.moduleSpecifierResolutionLimit + 50; + const exportingFiles = createExportingModuleFiles(`/lib/a`, ts.Completions.moduleSpecifierResolutionLimit + excessFileCount, 1, i => `aa_${i}_`); const { typeToTriggerCompletions, session } = setup([tsconfigFile, indexFile, ...exportingFiles]); - openFilesForSession([indexFile], session); + ts.projectSystem.openFilesForSession([indexFile], session); typeToTriggerCompletions(indexFile.path, "a", completions => { assert(completions.isIncomplete); - assert.lengthOf(completions.entries.filter(entry => (entry.data as any)?.moduleSpecifier), Completions.moduleSpecifierResolutionLimit); + assert.lengthOf(completions.entries.filter(entry => (entry.data as any)?.moduleSpecifier), ts.Completions.moduleSpecifierResolutionLimit); assert.lengthOf(completions.entries.filter(entry => entry.source && !(entry.data as any)?.moduleSpecifier), excessFileCount); }) .continueTyping("a", completions => { assert(completions.isIncomplete); - assert.lengthOf(completions.entries.filter(entry => (entry.data as any)?.moduleSpecifier), Completions.moduleSpecifierResolutionLimit * 2); + assert.lengthOf(completions.entries.filter(entry => (entry.data as any)?.moduleSpecifier), ts.Completions.moduleSpecifierResolutionLimit * 2); }) .continueTyping("_", completions => { assert(!completions.isIncomplete); @@ -70,7 +67,7 @@ namespace ts.projectSystem { it("resolves more when available from module specifier cache (1)", () => { const exportingFiles = createExportingModuleFiles(`/lib/a`, 50, 50, i => `aa_${i}_`); const { typeToTriggerCompletions, session } = setup([tsconfigFile, indexFile, ...exportingFiles]); - openFilesForSession([indexFile], session); + ts.projectSystem.openFilesForSession([indexFile], session); typeToTriggerCompletions(indexFile.path, "a", completions => { assert(!completions.isIncomplete); @@ -79,9 +76,9 @@ namespace ts.projectSystem { it("resolves more when available from module specifier cache (2)", () => { const excessFileCount = 50; - const exportingFiles = createExportingModuleFiles(`/lib/a`, Completions.moduleSpecifierResolutionLimit + excessFileCount, 1, i => `aa_${i}_`); + const exportingFiles = createExportingModuleFiles(`/lib/a`, ts.Completions.moduleSpecifierResolutionLimit + excessFileCount, 1, i => `aa_${i}_`); const { typeToTriggerCompletions, session } = setup([tsconfigFile, indexFile, ...exportingFiles]); - openFilesForSession([indexFile], session); + ts.projectSystem.openFilesForSession([indexFile], session); typeToTriggerCompletions(indexFile.path, "a", completions => assert(completions.isIncomplete)) .backspace() @@ -89,14 +86,14 @@ namespace ts.projectSystem { }); it("ambient module specifier resolutions do not count against the resolution limit", () => { - const ambientFiles = fill(100, (i): File => ({ + const ambientFiles = ts.fill(100, (i): ts.projectSystem.File => ({ path: `/lib/ambient_${i}.ts`, content: `declare module "ambient_${i}" { export const aa_${i} = ${i}; }`, })); - const exportingFiles = createExportingModuleFiles(`/lib/a`, Completions.moduleSpecifierResolutionLimit, 5, i => `aa_${i}_`); + const exportingFiles = createExportingModuleFiles(`/lib/a`, ts.Completions.moduleSpecifierResolutionLimit, 5, i => `aa_${i}_`); const { typeToTriggerCompletions, session } = setup([tsconfigFile, indexFile, ...ambientFiles, ...exportingFiles]); - openFilesForSession([indexFile], session); + ts.projectSystem.openFilesForSession([indexFile], session); typeToTriggerCompletions(indexFile.path, "a", completions => { assert(!completions.isIncomplete); @@ -105,32 +102,30 @@ namespace ts.projectSystem { }); it("works with PackageJsonAutoImportProvider", () => { - const exportingFiles = createExportingModuleFiles(`/lib/a`, Completions.moduleSpecifierResolutionLimit, 1, i => `aa_${i}_`); + const exportingFiles = createExportingModuleFiles(`/lib/a`, ts.Completions.moduleSpecifierResolutionLimit, 1, i => `aa_${i}_`); const nodeModulesPackage = createNodeModulesPackage("dep-a", 50, 1, i => `depA_${i}_`); const { typeToTriggerCompletions, assertCompletionDetailsOk, session } = setup([tsconfigFile, packageJsonFile, indexFile, ...exportingFiles, ...nodeModulesPackage]); - openFilesForSession([indexFile], session); + ts.projectSystem.openFilesForSession([indexFile], session); typeToTriggerCompletions(indexFile.path, "a", completions => assert(completions.isIncomplete)) .continueTyping("_", completions => { assert(!completions.isIncomplete); assert.lengthOf(completions.entries.filter(entry => (entry.data as any)?.moduleSpecifier?.startsWith("dep-a")), 50); - assertCompletionDetailsOk( - indexFile.path, - completions.entries.find(entry => (entry.data as any)?.moduleSpecifier?.startsWith("dep-a"))!); + assertCompletionDetailsOk(indexFile.path, completions.entries.find(entry => (entry.data as any)?.moduleSpecifier?.startsWith("dep-a"))!); }); }); it("works for transient symbols between requests", () => { - const constantsDts: File = { + const constantsDts: ts.projectSystem.File = { path: "/lib/foo/constants.d.ts", content: ` type Signals = "SIGINT" | "SIGABRT"; declare const exp: {} & { [K in Signals]: K }; export = exp;`, }; - const exportingFiles = createExportingModuleFiles("/lib/a", Completions.moduleSpecifierResolutionLimit, 1, i => `S${i}`); + const exportingFiles = createExportingModuleFiles("/lib/a", ts.Completions.moduleSpecifierResolutionLimit, 1, i => `S${i}`); const { typeToTriggerCompletions, session } = setup([tsconfigFile, indexFile, ...exportingFiles, constantsDts]); - openFilesForSession([indexFile], session); + ts.projectSystem.openFilesForSession([indexFile], session); typeToTriggerCompletions(indexFile.path, "s", completions => { const sigint = completions.entries.find(e => e.name === "SIGINT"); @@ -144,12 +139,12 @@ namespace ts.projectSystem { }); }); - function setup(files: File[]) { - const host = createServerHost(files); - const session = createSession(host); + function setup(files: ts.projectSystem.File[]) { + const host = ts.projectSystem.createServerHost(files); + const session = ts.projectSystem.createSession(host); const projectService = session.getProjectService(); - session.executeCommandSeq({ - command: protocol.CommandTypes.Configure, + session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.Configure, arguments: { preferences: { allowIncompleteCompletions: true, @@ -163,16 +158,16 @@ namespace ts.projectSystem { return { host, session, projectService, typeToTriggerCompletions, assertCompletionDetailsOk }; - function typeToTriggerCompletions(fileName: string, typedCharacters: string, cb?: (completions: protocol.CompletionInfo) => void) { - const project = projectService.getDefaultProjectForFile(server.toNormalizedPath(fileName), /*ensureProject*/ true)!; + function typeToTriggerCompletions(fileName: string, typedCharacters: string, cb?: (completions: ts.projectSystem.protocol.CompletionInfo) => void) { + const project = projectService.getDefaultProjectForFile(ts.server.toNormalizedPath(fileName), /*ensureProject*/ true)!; return type(typedCharacters, cb, /*isIncompleteContinuation*/ false); - function type(typedCharacters: string, cb: ((completions: protocol.CompletionInfo) => void) | undefined, isIncompleteContinuation: boolean) { - const file = Debug.checkDefined(project.getLanguageService(/*ensureSynchronized*/ true).getProgram()?.getSourceFile(fileName)); - const { line, character } = getLineAndCharacterOfPosition(file, file.text.length); + function type(typedCharacters: string, cb: ((completions: ts.projectSystem.protocol.CompletionInfo) => void) | undefined, isIncompleteContinuation: boolean) { + const file = ts.Debug.checkDefined(project.getLanguageService(/*ensureSynchronized*/ true).getProgram()?.getSourceFile(fileName)); + const { line, character } = ts.getLineAndCharacterOfPosition(file, file.text.length); const oneBasedEditPosition = { line: line + 1, offset: character + 1 }; - session.executeCommandSeq({ - command: protocol.CommandTypes.UpdateOpen, + session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.UpdateOpen, arguments: { changedFiles: [{ fileName, @@ -185,35 +180,34 @@ namespace ts.projectSystem { }, }); - const response = session.executeCommandSeq({ - command: protocol.CommandTypes.CompletionInfo, + const response = session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.CompletionInfo, arguments: { file: fileName, line: oneBasedEditPosition.line, offset: oneBasedEditPosition.offset, triggerKind: isIncompleteContinuation - ? protocol.CompletionTriggerKind.TriggerForIncompleteCompletions + ? ts.projectSystem.protocol.CompletionTriggerKind.TriggerForIncompleteCompletions : undefined, } - }).response as protocol.CompletionInfo; - - cb?.(Debug.checkDefined(response)); + }).response as ts.projectSystem.protocol.CompletionInfo; + cb?.(ts.Debug.checkDefined(response)); return { backspace, - continueTyping: (typedCharacters: string, cb: (completions: protocol.CompletionInfo) => void) => { + continueTyping: (typedCharacters: string, cb: (completions: ts.projectSystem.protocol.CompletionInfo) => void) => { return type(typedCharacters, cb, !!response.isIncomplete); }, }; } function backspace(n = 1) { - const file = Debug.checkDefined(project.getLanguageService(/*ensureSynchronized*/ true).getProgram()?.getSourceFile(fileName)); - const startLineCharacter = getLineAndCharacterOfPosition(file, file.text.length - n); - const endLineCharacter = getLineAndCharacterOfPosition(file, file.text.length); + const file = ts.Debug.checkDefined(project.getLanguageService(/*ensureSynchronized*/ true).getProgram()?.getSourceFile(fileName)); + const startLineCharacter = ts.getLineAndCharacterOfPosition(file, file.text.length - n); + const endLineCharacter = ts.getLineAndCharacterOfPosition(file, file.text.length); const oneBasedStartPosition = { line: startLineCharacter.line + 1, offset: startLineCharacter.character + 1 }; const oneBasedEndPosition = { line: endLineCharacter.line + 1, offset: endLineCharacter.character + 1 }; - session.executeCommandSeq({ - command: protocol.CommandTypes.UpdateOpen, + session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.UpdateOpen, arguments: { changedFiles: [{ fileName, @@ -228,19 +222,19 @@ namespace ts.projectSystem { return { backspace, - type: (typedCharacters: string, cb: (completions: protocol.CompletionInfo) => void) => { + type: (typedCharacters: string, cb: (completions: ts.projectSystem.protocol.CompletionInfo) => void) => { return type(typedCharacters, cb, /*isIncompleteContinuation*/ false); }, }; } } - function assertCompletionDetailsOk(fileName: string, entry: protocol.CompletionEntry) { - const project = projectService.getDefaultProjectForFile(server.toNormalizedPath(fileName), /*ensureProject*/ true)!; - const file = Debug.checkDefined(project.getLanguageService(/*ensureSynchronized*/ true).getProgram()?.getSourceFile(fileName)); - const { line, character } = getLineAndCharacterOfPosition(file, file.text.length - 1); - const details = session.executeCommandSeq({ - command: protocol.CommandTypes.CompletionDetails, + function assertCompletionDetailsOk(fileName: string, entry: ts.projectSystem.protocol.CompletionEntry) { + const project = projectService.getDefaultProjectForFile(ts.server.toNormalizedPath(fileName), /*ensureProject*/ true)!; + const file = ts.Debug.checkDefined(project.getLanguageService(/*ensureSynchronized*/ true).getProgram()?.getSourceFile(fileName)); + const { line, character } = ts.getLineAndCharacterOfPosition(file, file.text.length - 1); + const details = session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.CompletionDetails, arguments: { file: fileName, line: line + 1, @@ -251,7 +245,7 @@ namespace ts.projectSystem { data: entry.data, }] } - }).response as protocol.CompletionEntryDetails[]; + }).response as ts.projectSystem.protocol.CompletionEntryDetails[]; assert(details[0]); assert(details[0].codeActions); diff --git a/src/testRunner/unittests/tsserver/configFileSearch.ts b/src/testRunner/unittests/tsserver/configFileSearch.ts index 152184e9ae5d3..f03159f333fff 100644 --- a/src/testRunner/unittests/tsserver/configFileSearch.ts +++ b/src/testRunner/unittests/tsserver/configFileSearch.ts @@ -9,17 +9,17 @@ namespace ts.projectSystem { path: "/tsconfig.json", content: "{}" }; - const host = createServerHost([f1, configFile]); - const service = createProjectService(host); + const host = ts.projectSystem.createServerHost([f1, configFile]); + const service = ts.projectSystem.createProjectService(host); service.openClientFile(f1.path, /*fileContent*/ undefined, /*scriptKind*/ undefined, "/a"); - checkNumberOfConfiguredProjects(service, 0); - checkNumberOfInferredProjects(service, 1); + ts.projectSystem.checkNumberOfConfiguredProjects(service, 0); + ts.projectSystem.checkNumberOfInferredProjects(service, 1); service.closeClientFile(f1.path); service.openClientFile(f1.path); - checkNumberOfConfiguredProjects(service, 1); - checkNumberOfInferredProjects(service, 0); + ts.projectSystem.checkNumberOfConfiguredProjects(service, 1); + ts.projectSystem.checkNumberOfInferredProjects(service, 0); }); it("should use projectRootPath when searching for inferred project again", () => { @@ -37,23 +37,23 @@ namespace ts.projectSystem { path: "/a/b/projects/tsconfig.json", content: "{}" }; - const host = createServerHost([f1, libFile, configFile, configFile2]); - const service = createProjectService(host); + const host = ts.projectSystem.createServerHost([f1, ts.projectSystem.libFile, configFile, configFile2]); + const service = ts.projectSystem.createProjectService(host); service.openClientFile(f1.path, /*fileContent*/ undefined, /*scriptKind*/ undefined, projectDir); - checkNumberOfProjects(service, { configuredProjects: 1 }); + ts.projectSystem.checkNumberOfProjects(service, { configuredProjects: 1 }); assert.isDefined(service.configuredProjects.get(configFile.path)); - checkWatchedFiles(host, [libFile.path, configFile.path]); - checkWatchedDirectories(host, [], /*recursive*/ false); - const typeRootLocations = getTypeRootsFromLocation(configFileLocation); - checkWatchedDirectories(host, typeRootLocations.concat(configFileLocation), /*recursive*/ true); + ts.projectSystem.checkWatchedFiles(host, [ts.projectSystem.libFile.path, configFile.path]); + ts.projectSystem.checkWatchedDirectories(host, [], /*recursive*/ false); + const typeRootLocations = ts.projectSystem.getTypeRootsFromLocation(configFileLocation); + ts.projectSystem.checkWatchedDirectories(host, typeRootLocations.concat(configFileLocation), /*recursive*/ true); // Delete config file - should create inferred project and not configured project host.deleteFile(configFile.path); host.runQueuedTimeoutCallbacks(); - checkNumberOfProjects(service, { inferredProjects: 1 }); - checkWatchedFiles(host, [libFile.path, configFile.path, `${configFileLocation}/jsconfig.json`, `${projectDir}/tsconfig.json`, `${projectDir}/jsconfig.json`]); - checkWatchedDirectories(host, [], /*recursive*/ false); - checkWatchedDirectories(host, typeRootLocations, /*recursive*/ true); + ts.projectSystem.checkNumberOfProjects(service, { inferredProjects: 1 }); + ts.projectSystem.checkWatchedFiles(host, [ts.projectSystem.libFile.path, configFile.path, `${configFileLocation}/jsconfig.json`, `${projectDir}/tsconfig.json`, `${projectDir}/jsconfig.json`]); + ts.projectSystem.checkWatchedDirectories(host, [], /*recursive*/ false); + ts.projectSystem.checkWatchedDirectories(host, typeRootLocations, /*recursive*/ true); }); it("should use projectRootPath when searching for inferred project again 2", () => { @@ -71,75 +71,73 @@ namespace ts.projectSystem { path: "/a/b/projects/tsconfig.json", content: "{}" }; - const host = createServerHost([f1, libFile, configFile, configFile2]); - const service = createProjectService(host, { useSingleInferredProject: true, useInferredProjectPerProjectRoot: true }); + const host = ts.projectSystem.createServerHost([f1, ts.projectSystem.libFile, configFile, configFile2]); + const service = ts.projectSystem.createProjectService(host, { useSingleInferredProject: true, useInferredProjectPerProjectRoot: true }); service.openClientFile(f1.path, /*fileContent*/ undefined, /*scriptKind*/ undefined, projectDir); - checkNumberOfProjects(service, { configuredProjects: 1 }); + ts.projectSystem.checkNumberOfProjects(service, { configuredProjects: 1 }); assert.isDefined(service.configuredProjects.get(configFile.path)); - checkWatchedFiles(host, [libFile.path, configFile.path]); - checkWatchedDirectories(host, [], /*recursive*/ false); - checkWatchedDirectories(host, getTypeRootsFromLocation(configFileLocation).concat(configFileLocation), /*recursive*/ true); + ts.projectSystem.checkWatchedFiles(host, [ts.projectSystem.libFile.path, configFile.path]); + ts.projectSystem.checkWatchedDirectories(host, [], /*recursive*/ false); + ts.projectSystem.checkWatchedDirectories(host, ts.projectSystem.getTypeRootsFromLocation(configFileLocation).concat(configFileLocation), /*recursive*/ true); // Delete config file - should create inferred project with project root path set host.deleteFile(configFile.path); host.runQueuedTimeoutCallbacks(); - checkNumberOfProjects(service, { inferredProjects: 1 }); + ts.projectSystem.checkNumberOfProjects(service, { inferredProjects: 1 }); assert.equal(service.inferredProjects[0].projectRootPath, projectDir); - checkWatchedFiles(host, [libFile.path, configFile.path, `${configFileLocation}/jsconfig.json`, `${projectDir}/tsconfig.json`, `${projectDir}/jsconfig.json`]); - checkWatchedDirectories(host, [], /*recursive*/ false); - checkWatchedDirectories(host, getTypeRootsFromLocation(projectDir), /*recursive*/ true); + ts.projectSystem.checkWatchedFiles(host, [ts.projectSystem.libFile.path, configFile.path, `${configFileLocation}/jsconfig.json`, `${projectDir}/tsconfig.json`, `${projectDir}/jsconfig.json`]); + ts.projectSystem.checkWatchedDirectories(host, [], /*recursive*/ false); + ts.projectSystem.checkWatchedDirectories(host, ts.projectSystem.getTypeRootsFromLocation(projectDir), /*recursive*/ true); }); describe("when the opened file is not from project root", () => { const projectRoot = "/a/b/projects/project"; - const file: File = { + const file: ts.projectSystem.File = { path: `${projectRoot}/src/index.ts`, content: "let y = 10" }; - const tsconfig: File = { + const tsconfig: ts.projectSystem.File = { path: `${projectRoot}/tsconfig.json`, content: "{}" }; - const dirOfFile = getDirectoryPath(file.path); - - function openClientFile(files: File[]) { - const host = createServerHost(files); - const projectService = createProjectService(host); + const dirOfFile = ts.getDirectoryPath(file.path); + function openClientFile(files: ts.projectSystem.File[]) { + const host = ts.projectSystem.createServerHost(files); + const projectService = ts.projectSystem.createProjectService(host); projectService.openClientFile(file.path, /*fileContent*/ undefined, /*scriptKind*/ undefined, "/a/b/projects/proj"); return { host, projectService }; } - function verifyConfiguredProject(host: TestServerHost, projectService: TestProjectService, orphanInferredProject?: boolean) { + function verifyConfiguredProject(host: ts.projectSystem.TestServerHost, projectService: ts.projectSystem.TestProjectService, orphanInferredProject?: boolean) { projectService.checkNumberOfProjects({ configuredProjects: 1, inferredProjects: orphanInferredProject ? 1 : 0 }); - const project = Debug.checkDefined(projectService.configuredProjects.get(tsconfig.path)); + const project = ts.Debug.checkDefined(projectService.configuredProjects.get(tsconfig.path)); if (orphanInferredProject) { const inferredProject = projectService.inferredProjects[0]; assert.isTrue(inferredProject.isOrphan()); } - checkProjectActualFiles(project, [file.path, libFile.path, tsconfig.path]); - checkWatchedFiles(host, [libFile.path, tsconfig.path]); - checkWatchedDirectories(host, emptyArray, /*recursive*/ false); - checkWatchedDirectories(host, (orphanInferredProject ? [projectRoot, `${dirOfFile}/node_modules/@types`] : [projectRoot]).concat(getTypeRootsFromLocation(projectRoot)), /*recursive*/ true); + ts.projectSystem.checkProjectActualFiles(project, [file.path, ts.projectSystem.libFile.path, tsconfig.path]); + ts.projectSystem.checkWatchedFiles(host, [ts.projectSystem.libFile.path, tsconfig.path]); + ts.projectSystem.checkWatchedDirectories(host, ts.emptyArray, /*recursive*/ false); + ts.projectSystem.checkWatchedDirectories(host, (orphanInferredProject ? [projectRoot, `${dirOfFile}/node_modules/@types`] : [projectRoot]).concat(ts.projectSystem.getTypeRootsFromLocation(projectRoot)), /*recursive*/ true); } - function verifyInferredProject(host: TestServerHost, projectService: TestProjectService) { + function verifyInferredProject(host: ts.projectSystem.TestServerHost, projectService: ts.projectSystem.TestProjectService) { projectService.checkNumberOfProjects({ inferredProjects: 1 }); const project = projectService.inferredProjects[0]; assert.isDefined(project); - const filesToWatch = [libFile.path, ...getConfigFilesToWatch(dirOfFile)]; - - checkProjectActualFiles(project, [file.path, libFile.path]); - checkWatchedFiles(host, filesToWatch); - checkWatchedDirectories(host, emptyArray, /*recursive*/ false); - checkWatchedDirectories(host, getTypeRootsFromLocation(dirOfFile), /*recursive*/ true); + const filesToWatch = [ts.projectSystem.libFile.path, ...ts.projectSystem.getConfigFilesToWatch(dirOfFile)]; + ts.projectSystem.checkProjectActualFiles(project, [file.path, ts.projectSystem.libFile.path]); + ts.projectSystem.checkWatchedFiles(host, filesToWatch); + ts.projectSystem.checkWatchedDirectories(host, ts.emptyArray, /*recursive*/ false); + ts.projectSystem.checkWatchedDirectories(host, ts.projectSystem.getTypeRootsFromLocation(dirOfFile), /*recursive*/ true); } it("tsconfig for the file exists", () => { - const { host, projectService } = openClientFile([file, libFile, tsconfig]); + const { host, projectService } = openClientFile([file, ts.projectSystem.libFile, tsconfig]); verifyConfiguredProject(host, projectService); host.deleteFile(tsconfig.path); @@ -152,7 +150,7 @@ namespace ts.projectSystem { }); it("tsconfig for the file does not exist", () => { - const { host, projectService } = openClientFile([file, libFile]); + const { host, projectService } = openClientFile([file, ts.projectSystem.libFile]); verifyInferredProject(host, projectService); host.writeFile(tsconfig.path, tsconfig.content); @@ -169,12 +167,12 @@ namespace ts.projectSystem { const root = "/root/teams/VSCode68/Shared Documents/General/jt-ts-test-workspace"; function verifyConfigFileWatch(projectRootPath: string | undefined) { const path = `${root}/x.js`; - const host = createServerHost([libFile, { path, content: "const x = 10" }], { useCaseSensitiveFileNames: true }); - const service = createProjectService(host); + const host = ts.projectSystem.createServerHost([ts.projectSystem.libFile, { path, content: "const x = 10" }], { useCaseSensitiveFileNames: true }); + const service = ts.projectSystem.createProjectService(host); service.openClientFile(path, /*fileContent*/ undefined, /*scriptKind*/ undefined, projectRootPath); - checkNumberOfProjects(service, { inferredProjects: 1 }); - checkProjectActualFiles(service.inferredProjects[0], [path, libFile.path]); - checkWatchedFilesDetailed(host, [libFile.path, ...getConfigFilesToWatch(root)], 1); + ts.projectSystem.checkNumberOfProjects(service, { inferredProjects: 1 }); + ts.projectSystem.checkProjectActualFiles(service.inferredProjects[0], [path, ts.projectSystem.libFile.path]); + ts.projectSystem.checkWatchedFilesDetailed(host, [ts.projectSystem.libFile.path, ...ts.projectSystem.getConfigFilesToWatch(root)], 1); } it("when projectRootPath is not present", () => { diff --git a/src/testRunner/unittests/tsserver/configuredProjects.ts b/src/testRunner/unittests/tsserver/configuredProjects.ts index cd5bd4d81f306..51e8e877abc61 100644 --- a/src/testRunner/unittests/tsserver/configuredProjects.ts +++ b/src/testRunner/unittests/tsserver/configuredProjects.ts @@ -1,7 +1,7 @@ namespace ts.projectSystem { describe("unittests:: tsserver:: ConfiguredProjects", () => { it("create configured project without file list", () => { - const configFile: File = { + const configFile: ts.projectSystem.File = { path: "/a/b/tsconfig.json", content: ` { @@ -11,39 +11,38 @@ namespace ts.projectSystem { ] }` }; - const file1: File = { + const file1: ts.projectSystem.File = { path: "/a/b/c/f1.ts", content: "let x = 1" }; - const file2: File = { + const file2: ts.projectSystem.File = { path: "/a/b/d/f2.ts", content: "let y = 1" }; - const file3: File = { + const file3: ts.projectSystem.File = { path: "/a/b/e/f3.ts", content: "let z = 1" }; - const host = createServerHost([configFile, libFile, file1, file2, file3]); - const projectService = createProjectService(host); + const host = ts.projectSystem.createServerHost([configFile, ts.projectSystem.libFile, file1, file2, file3]); + const projectService = ts.projectSystem.createProjectService(host); const { configFileName, configFileErrors } = projectService.openClientFile(file1.path); assert(configFileName, "should find config file"); assert.isTrue(!configFileErrors || configFileErrors.length === 0, `expect no errors in config file, got ${JSON.stringify(configFileErrors)}`); - checkNumberOfInferredProjects(projectService, 0); - checkNumberOfConfiguredProjects(projectService, 1); - - const project = configuredProjectAt(projectService, 0); - checkProjectActualFiles(project, [file1.path, libFile.path, file2.path, configFile.path]); - checkProjectRootFiles(project, [file1.path, file2.path]); + ts.projectSystem.checkNumberOfInferredProjects(projectService, 0); + ts.projectSystem.checkNumberOfConfiguredProjects(projectService, 1); + const project = ts.projectSystem.configuredProjectAt(projectService, 0); + ts.projectSystem.checkProjectActualFiles(project, [file1.path, ts.projectSystem.libFile.path, file2.path, configFile.path]); + ts.projectSystem.checkProjectRootFiles(project, [file1.path, file2.path]); // watching all files except one that was open - checkWatchedFiles(host, [configFile.path, file2.path, libFile.path]); - const configFileDirectory = getDirectoryPath(configFile.path); - checkWatchedDirectories(host, [configFileDirectory, combinePaths(configFileDirectory, nodeModulesAtTypes)], /*recursive*/ true); + ts.projectSystem.checkWatchedFiles(host, [configFile.path, file2.path, ts.projectSystem.libFile.path]); + const configFileDirectory = ts.getDirectoryPath(configFile.path); + ts.projectSystem.checkWatchedDirectories(host, [configFileDirectory, ts.combinePaths(configFileDirectory, ts.projectSystem.nodeModulesAtTypes)], /*recursive*/ true); }); it("create configured project with the file list", () => { - const configFile: File = { + const configFile: ts.projectSystem.File = { path: "/a/b/tsconfig.json", content: ` { @@ -51,64 +50,61 @@ namespace ts.projectSystem { "include": ["*.ts"] }` }; - const file1: File = { + const file1: ts.projectSystem.File = { path: "/a/b/f1.ts", content: "let x = 1" }; - const file2: File = { + const file2: ts.projectSystem.File = { path: "/a/b/f2.ts", content: "let y = 1" }; - const file3: File = { + const file3: ts.projectSystem.File = { path: "/a/b/c/f3.ts", content: "let z = 1" }; - const host = createServerHost([configFile, libFile, file1, file2, file3]); - const projectService = createProjectService(host); + const host = ts.projectSystem.createServerHost([configFile, ts.projectSystem.libFile, file1, file2, file3]); + const projectService = ts.projectSystem.createProjectService(host); const { configFileName, configFileErrors } = projectService.openClientFile(file1.path); assert(configFileName, "should find config file"); assert.isTrue(!configFileErrors || configFileErrors.length === 0, `expect no errors in config file, got ${JSON.stringify(configFileErrors)}`); - checkNumberOfInferredProjects(projectService, 0); - checkNumberOfConfiguredProjects(projectService, 1); - - const project = configuredProjectAt(projectService, 0); - checkProjectActualFiles(project, [file1.path, libFile.path, file2.path, configFile.path]); - checkProjectRootFiles(project, [file1.path, file2.path]); + ts.projectSystem.checkNumberOfInferredProjects(projectService, 0); + ts.projectSystem.checkNumberOfConfiguredProjects(projectService, 1); + const project = ts.projectSystem.configuredProjectAt(projectService, 0); + ts.projectSystem.checkProjectActualFiles(project, [file1.path, ts.projectSystem.libFile.path, file2.path, configFile.path]); + ts.projectSystem.checkProjectRootFiles(project, [file1.path, file2.path]); // watching all files except one that was open - checkWatchedFiles(host, [configFile.path, file2.path, libFile.path]); - checkWatchedDirectories(host, [getDirectoryPath(configFile.path)], /*recursive*/ false); + ts.projectSystem.checkWatchedFiles(host, [configFile.path, file2.path, ts.projectSystem.libFile.path]); + ts.projectSystem.checkWatchedDirectories(host, [ts.getDirectoryPath(configFile.path)], /*recursive*/ false); }); it("add and then remove a config file in a folder with loose files", () => { - const configFile: File = { - path: `${tscWatch.projectRoot}/tsconfig.json`, + const configFile: ts.projectSystem.File = { + path: `${ts.tscWatch.projectRoot}/tsconfig.json`, content: `{ "files": ["commonFile1.ts"] }` }; - const commonFile1: File = { - path: `${tscWatch.projectRoot}/commonFile1.ts`, + const commonFile1: ts.projectSystem.File = { + path: `${ts.tscWatch.projectRoot}/commonFile1.ts`, content: "let x = 1" }; - const commonFile2: File = { - path: `${tscWatch.projectRoot}/commonFile2.ts`, + const commonFile2: ts.projectSystem.File = { + path: `${ts.tscWatch.projectRoot}/commonFile2.ts`, content: "let y = 1" }; - const host = createServerHost([libFile, commonFile1, commonFile2]); - - const projectService = createProjectService(host); + const host = ts.projectSystem.createServerHost([ts.projectSystem.libFile, commonFile1, commonFile2]); + const projectService = ts.projectSystem.createProjectService(host); projectService.openClientFile(commonFile1.path); projectService.openClientFile(commonFile2.path); projectService.checkNumberOfProjects({ inferredProjects: 2 }); - checkProjectActualFiles(projectService.inferredProjects[0], [commonFile1.path, libFile.path]); - checkProjectActualFiles(projectService.inferredProjects[1], [commonFile2.path, libFile.path]); - - const watchedFiles = getConfigFilesToWatch(tscWatch.projectRoot).concat(libFile.path); - checkWatchedFiles(host, watchedFiles); + ts.projectSystem.checkProjectActualFiles(projectService.inferredProjects[0], [commonFile1.path, ts.projectSystem.libFile.path]); + ts.projectSystem.checkProjectActualFiles(projectService.inferredProjects[1], [commonFile2.path, ts.projectSystem.libFile.path]); + const watchedFiles = ts.projectSystem.getConfigFilesToWatch(ts.tscWatch.projectRoot).concat(ts.projectSystem.libFile.path); + ts.projectSystem.checkWatchedFiles(host, watchedFiles); // Add a tsconfig file host.writeFile(configFile.path, configFile.content); @@ -116,50 +112,48 @@ namespace ts.projectSystem { projectService.checkNumberOfProjects({ inferredProjects: 2, configuredProjects: 1 }); assert.isTrue(projectService.inferredProjects[0].isOrphan()); - checkProjectActualFiles(projectService.inferredProjects[1], [commonFile2.path, libFile.path]); - checkProjectActualFiles(projectService.configuredProjects.get(configFile.path)!, [libFile.path, commonFile1.path, configFile.path]); - - checkWatchedFiles(host, watchedFiles); + ts.projectSystem.checkProjectActualFiles(projectService.inferredProjects[1], [commonFile2.path, ts.projectSystem.libFile.path]); + ts.projectSystem.checkProjectActualFiles(projectService.configuredProjects.get(configFile.path)!, [ts.projectSystem.libFile.path, commonFile1.path, configFile.path]); + ts.projectSystem.checkWatchedFiles(host, watchedFiles); // remove the tsconfig file host.deleteFile(configFile.path); projectService.checkNumberOfProjects({ inferredProjects: 2 }); assert.isTrue(projectService.inferredProjects[0].isOrphan()); - checkProjectActualFiles(projectService.inferredProjects[1], [commonFile2.path, libFile.path]); + ts.projectSystem.checkProjectActualFiles(projectService.inferredProjects[1], [commonFile2.path, ts.projectSystem.libFile.path]); host.checkTimeoutQueueLengthAndRun(1); // Refresh inferred projects projectService.checkNumberOfProjects({ inferredProjects: 2 }); - checkProjectActualFiles(projectService.inferredProjects[0], [commonFile1.path, libFile.path]); - checkProjectActualFiles(projectService.inferredProjects[1], [commonFile2.path, libFile.path]); - checkWatchedFiles(host, watchedFiles); + ts.projectSystem.checkProjectActualFiles(projectService.inferredProjects[0], [commonFile1.path, ts.projectSystem.libFile.path]); + ts.projectSystem.checkProjectActualFiles(projectService.inferredProjects[1], [commonFile2.path, ts.projectSystem.libFile.path]); + ts.projectSystem.checkWatchedFiles(host, watchedFiles); }); it("add new files to a configured project without file list", () => { - const configFile: File = { + const configFile: ts.projectSystem.File = { path: "/a/b/tsconfig.json", content: `{}` }; - const host = createServerHost([commonFile1, libFile, configFile]); - const projectService = createProjectService(host); - projectService.openClientFile(commonFile1.path); - const configFileDir = getDirectoryPath(configFile.path); - checkWatchedDirectories(host, [configFileDir, combinePaths(configFileDir, nodeModulesAtTypes)], /*recursive*/ true); - checkNumberOfConfiguredProjects(projectService, 1); - - const project = configuredProjectAt(projectService, 0); - checkProjectRootFiles(project, [commonFile1.path]); + const host = ts.projectSystem.createServerHost([ts.projectSystem.commonFile1, ts.projectSystem.libFile, configFile]); + const projectService = ts.projectSystem.createProjectService(host); + projectService.openClientFile(ts.projectSystem.commonFile1.path); + const configFileDir = ts.getDirectoryPath(configFile.path); + ts.projectSystem.checkWatchedDirectories(host, [configFileDir, ts.combinePaths(configFileDir, ts.projectSystem.nodeModulesAtTypes)], /*recursive*/ true); + ts.projectSystem.checkNumberOfConfiguredProjects(projectService, 1); + const project = ts.projectSystem.configuredProjectAt(projectService, 0); + ts.projectSystem.checkProjectRootFiles(project, [ts.projectSystem.commonFile1.path]); // add a new ts file - host.writeFile(commonFile2.path, commonFile2.content); + host.writeFile(ts.projectSystem.commonFile2.path, ts.projectSystem.commonFile2.content); host.checkTimeoutQueueLengthAndRun(2); // project service waits for 250ms to update the project structure, therefore the assertion needs to wait longer. - checkProjectRootFiles(project, [commonFile1.path, commonFile2.path]); + ts.projectSystem.checkProjectRootFiles(project, [ts.projectSystem.commonFile1.path, ts.projectSystem.commonFile2.path]); }); it("should ignore non-existing files specified in the config file", () => { - const configFile: File = { + const configFile: ts.projectSystem.File = { path: "/a/b/tsconfig.json", content: `{ "compilerOptions": {}, @@ -169,83 +163,80 @@ namespace ts.projectSystem { ] }` }; - const host = createServerHost([commonFile1, commonFile2, configFile]); - const projectService = createProjectService(host); - projectService.openClientFile(commonFile1.path); - projectService.openClientFile(commonFile2.path); - - checkNumberOfConfiguredProjects(projectService, 1); - const project = configuredProjectAt(projectService, 0); - checkProjectRootFiles(project, [commonFile1.path]); - checkNumberOfInferredProjects(projectService, 1); + const host = ts.projectSystem.createServerHost([ts.projectSystem.commonFile1, ts.projectSystem.commonFile2, configFile]); + const projectService = ts.projectSystem.createProjectService(host); + projectService.openClientFile(ts.projectSystem.commonFile1.path); + projectService.openClientFile(ts.projectSystem.commonFile2.path); + ts.projectSystem.checkNumberOfConfiguredProjects(projectService, 1); + const project = ts.projectSystem.configuredProjectAt(projectService, 0); + ts.projectSystem.checkProjectRootFiles(project, [ts.projectSystem.commonFile1.path]); + ts.projectSystem.checkNumberOfInferredProjects(projectService, 1); }); it("handle recreated files correctly", () => { - const configFile: File = { + const configFile: ts.projectSystem.File = { path: "/a/b/tsconfig.json", content: `{}` }; - const host = createServerHost([commonFile1, commonFile2, configFile]); - const projectService = createProjectService(host); - projectService.openClientFile(commonFile1.path); - - checkNumberOfConfiguredProjects(projectService, 1); - const project = configuredProjectAt(projectService, 0); - checkProjectRootFiles(project, [commonFile1.path, commonFile2.path]); + const host = ts.projectSystem.createServerHost([ts.projectSystem.commonFile1, ts.projectSystem.commonFile2, configFile]); + const projectService = ts.projectSystem.createProjectService(host); + projectService.openClientFile(ts.projectSystem.commonFile1.path); + ts.projectSystem.checkNumberOfConfiguredProjects(projectService, 1); + const project = ts.projectSystem.configuredProjectAt(projectService, 0); + ts.projectSystem.checkProjectRootFiles(project, [ts.projectSystem.commonFile1.path, ts.projectSystem.commonFile2.path]); // delete commonFile2 - host.deleteFile(commonFile2.path); + host.deleteFile(ts.projectSystem.commonFile2.path); host.checkTimeoutQueueLengthAndRun(2); - checkProjectRootFiles(project, [commonFile1.path]); + ts.projectSystem.checkProjectRootFiles(project, [ts.projectSystem.commonFile1.path]); // re-add commonFile2 - host.writeFile(commonFile2.path, commonFile2.content); + host.writeFile(ts.projectSystem.commonFile2.path, ts.projectSystem.commonFile2.content); host.checkTimeoutQueueLengthAndRun(2); - checkProjectRootFiles(project, [commonFile1.path, commonFile2.path]); + ts.projectSystem.checkProjectRootFiles(project, [ts.projectSystem.commonFile1.path, ts.projectSystem.commonFile2.path]); }); it("files explicitly excluded in config file", () => { - const configFile: File = { + const configFile: ts.projectSystem.File = { path: "/a/b/tsconfig.json", content: `{ "compilerOptions": {}, "exclude": ["/a/c"] }` }; - const excludedFile1: File = { + const excludedFile1: ts.projectSystem.File = { path: "/a/c/excluedFile1.ts", content: `let t = 1;` }; - const host = createServerHost([commonFile1, commonFile2, excludedFile1, configFile]); - const projectService = createProjectService(host); - - projectService.openClientFile(commonFile1.path); - checkNumberOfConfiguredProjects(projectService, 1); - const project = configuredProjectAt(projectService, 0); - checkProjectRootFiles(project, [commonFile1.path, commonFile2.path]); + const host = ts.projectSystem.createServerHost([ts.projectSystem.commonFile1, ts.projectSystem.commonFile2, excludedFile1, configFile]); + const projectService = ts.projectSystem.createProjectService(host); + projectService.openClientFile(ts.projectSystem.commonFile1.path); + ts.projectSystem.checkNumberOfConfiguredProjects(projectService, 1); + const project = ts.projectSystem.configuredProjectAt(projectService, 0); + ts.projectSystem.checkProjectRootFiles(project, [ts.projectSystem.commonFile1.path, ts.projectSystem.commonFile2.path]); projectService.openClientFile(excludedFile1.path); - checkNumberOfInferredProjects(projectService, 1); + ts.projectSystem.checkNumberOfInferredProjects(projectService, 1); }); it("should properly handle module resolution changes in config file", () => { - const file1: File = { + const file1: ts.projectSystem.File = { path: "/a/b/file1.ts", content: `import { T } from "module1";` }; - const nodeModuleFile: File = { + const nodeModuleFile: ts.projectSystem.File = { path: "/a/b/node_modules/module1.ts", content: `export interface T {}` }; - const classicModuleFile: File = { + const classicModuleFile: ts.projectSystem.File = { path: "/a/module1.ts", content: `export interface T {}` }; - const randomFile: File = { + const randomFile: ts.projectSystem.File = { path: "/a/file1.ts", content: `export interface T {}` }; - const configFile: File = { + const configFile: ts.projectSystem.File = { path: "/a/b/tsconfig.json", content: `{ "compilerOptions": { @@ -255,17 +246,17 @@ namespace ts.projectSystem { }` }; const files = [file1, nodeModuleFile, classicModuleFile, configFile, randomFile]; - const host = createServerHost(files); - const projectService = createProjectService(host); + const host = ts.projectSystem.createServerHost(files); + const projectService = ts.projectSystem.createProjectService(host); projectService.openClientFile(file1.path); projectService.openClientFile(nodeModuleFile.path); projectService.openClientFile(classicModuleFile.path); - checkNumberOfProjects(projectService, { configuredProjects: 1, inferredProjects: 1 }); - const project = configuredProjectAt(projectService, 0); + ts.projectSystem.checkNumberOfProjects(projectService, { configuredProjects: 1, inferredProjects: 1 }); + const project = ts.projectSystem.configuredProjectAt(projectService, 0); const inferredProject0 = projectService.inferredProjects[0]; - checkProjectActualFiles(project, [file1.path, nodeModuleFile.path, configFile.path]); - checkProjectActualFiles(projectService.inferredProjects[0], [classicModuleFile.path]); + ts.projectSystem.checkProjectActualFiles(project, [file1.path, nodeModuleFile.path, configFile.path]); + ts.projectSystem.checkProjectActualFiles(projectService.inferredProjects[0], [classicModuleFile.path]); host.writeFile(configFile.path, `{ "compilerOptions": { @@ -275,33 +266,33 @@ namespace ts.projectSystem { }`); host.checkTimeoutQueueLengthAndRun(2); - checkNumberOfProjects(projectService, { configuredProjects: 1, inferredProjects: 2 }); // will not remove project 1 - checkProjectActualFiles(project, [file1.path, classicModuleFile.path, configFile.path]); + ts.projectSystem.checkNumberOfProjects(projectService, { configuredProjects: 1, inferredProjects: 2 }); // will not remove project 1 + ts.projectSystem.checkProjectActualFiles(project, [file1.path, classicModuleFile.path, configFile.path]); assert.strictEqual(projectService.inferredProjects[0], inferredProject0); assert.isTrue(projectService.inferredProjects[0].isOrphan()); const inferredProject1 = projectService.inferredProjects[1]; - checkProjectActualFiles(projectService.inferredProjects[1], [nodeModuleFile.path]); + ts.projectSystem.checkProjectActualFiles(projectService.inferredProjects[1], [nodeModuleFile.path]); // Open random file and it will reuse first inferred project projectService.openClientFile(randomFile.path); - checkNumberOfProjects(projectService, { configuredProjects: 1, inferredProjects: 2 }); - checkProjectActualFiles(project, [file1.path, classicModuleFile.path, configFile.path]); + ts.projectSystem.checkNumberOfProjects(projectService, { configuredProjects: 1, inferredProjects: 2 }); + ts.projectSystem.checkProjectActualFiles(project, [file1.path, classicModuleFile.path, configFile.path]); assert.strictEqual(projectService.inferredProjects[0], inferredProject0); - checkProjectActualFiles(projectService.inferredProjects[0], [randomFile.path]); // Reuses first inferred project + ts.projectSystem.checkProjectActualFiles(projectService.inferredProjects[0], [randomFile.path]); // Reuses first inferred project assert.strictEqual(projectService.inferredProjects[1], inferredProject1); - checkProjectActualFiles(projectService.inferredProjects[1], [nodeModuleFile.path]); + ts.projectSystem.checkProjectActualFiles(projectService.inferredProjects[1], [nodeModuleFile.path]); }); it("should keep the configured project when the opened file is referenced by the project but not its root", () => { - const file1: File = { + const file1: ts.projectSystem.File = { path: "/a/b/main.ts", content: "import { objA } from './obj-a';" }; - const file2: File = { + const file2: ts.projectSystem.File = { path: "/a/b/obj-a.ts", content: `export const objA = Object.assign({foo: "bar"}, {bar: "baz"});` }; - const configFile: File = { + const configFile: ts.projectSystem.File = { path: "/a/b/tsconfig.json", content: `{ "compilerOptions": { @@ -310,25 +301,25 @@ namespace ts.projectSystem { "files": [ "main.ts" ] }` }; - const host = createServerHost([file1, file2, configFile]); - const projectService = createProjectService(host); + const host = ts.projectSystem.createServerHost([file1, file2, configFile]); + const projectService = ts.projectSystem.createProjectService(host); projectService.openClientFile(file1.path); projectService.closeClientFile(file1.path); projectService.openClientFile(file2.path); - checkNumberOfConfiguredProjects(projectService, 1); - checkNumberOfInferredProjects(projectService, 0); + ts.projectSystem.checkNumberOfConfiguredProjects(projectService, 1); + ts.projectSystem.checkNumberOfInferredProjects(projectService, 0); }); it("should keep the configured project when the opened file is referenced by the project but not its root", () => { - const file1: File = { + const file1: ts.projectSystem.File = { path: "/a/b/main.ts", content: "import { objA } from './obj-a';" }; - const file2: File = { + const file2: ts.projectSystem.File = { path: "/a/b/obj-a.ts", content: `export const objA = Object.assign({foo: "bar"}, {bar: "baz"});` }; - const configFile: File = { + const configFile: ts.projectSystem.File = { path: "/a/b/tsconfig.json", content: `{ "compilerOptions": { @@ -337,17 +328,17 @@ namespace ts.projectSystem { "files": [ "main.ts" ] }` }; - const host = createServerHost([file1, file2, configFile]); - const projectService = createProjectService(host); + const host = ts.projectSystem.createServerHost([file1, file2, configFile]); + const projectService = ts.projectSystem.createProjectService(host); projectService.openClientFile(file1.path); projectService.closeClientFile(file1.path); projectService.openClientFile(file2.path); - checkNumberOfConfiguredProjects(projectService, 1); - checkNumberOfInferredProjects(projectService, 0); + ts.projectSystem.checkNumberOfConfiguredProjects(projectService, 1); + ts.projectSystem.checkNumberOfInferredProjects(projectService, 0); }); it("should tolerate config file errors and still try to build a project", () => { - const configFile: File = { + const configFile: ts.projectSystem.File = { path: "/a/b/tsconfig.json", content: `{ "compilerOptions": { @@ -357,11 +348,11 @@ namespace ts.projectSystem { "someOtherProperty": {} }` }; - const host = createServerHost([commonFile1, commonFile2, libFile, configFile]); - const projectService = createProjectService(host); - projectService.openClientFile(commonFile1.path); - checkNumberOfConfiguredProjects(projectService, 1); - checkProjectRootFiles(configuredProjectAt(projectService, 0), [commonFile1.path, commonFile2.path]); + const host = ts.projectSystem.createServerHost([ts.projectSystem.commonFile1, ts.projectSystem.commonFile2, ts.projectSystem.libFile, configFile]); + const projectService = ts.projectSystem.createProjectService(host); + projectService.openClientFile(ts.projectSystem.commonFile1.path); + ts.projectSystem.checkNumberOfConfiguredProjects(projectService, 1); + ts.projectSystem.checkProjectRootFiles(ts.projectSystem.configuredProjectAt(projectService, 0), [ts.projectSystem.commonFile1.path, ts.projectSystem.commonFile2.path]); }); it("should reuse same project if file is opened from the configured project that has no open files", () => { @@ -373,7 +364,7 @@ namespace ts.projectSystem { path: "/a/b/main2.ts", content: "let y =1;" }; - const configFile: File = { + const configFile: ts.projectSystem.File = { path: "/a/b/tsconfig.json", content: `{ "compilerOptions": { @@ -382,21 +373,21 @@ namespace ts.projectSystem { "files": [ "main.ts", "main2.ts" ] }` }; - const host = createServerHost([file1, file2, configFile, libFile]); - const projectService = createProjectService(host, { useSingleInferredProject: true }); + const host = ts.projectSystem.createServerHost([file1, file2, configFile, ts.projectSystem.libFile]); + const projectService = ts.projectSystem.createProjectService(host, { useSingleInferredProject: true }); projectService.openClientFile(file1.path); - checkNumberOfConfiguredProjects(projectService, 1); + ts.projectSystem.checkNumberOfConfiguredProjects(projectService, 1); const project = projectService.configuredProjects.get(configFile.path)!; assert.isTrue(project.hasOpenRef()); // file1 projectService.closeClientFile(file1.path); - checkNumberOfConfiguredProjects(projectService, 1); + ts.projectSystem.checkNumberOfConfiguredProjects(projectService, 1); assert.strictEqual(projectService.configuredProjects.get(configFile.path), project); assert.isFalse(project.hasOpenRef()); // No open files assert.isFalse(project.isClosed()); projectService.openClientFile(file2.path); - checkNumberOfConfiguredProjects(projectService, 1); + ts.projectSystem.checkNumberOfConfiguredProjects(projectService, 1); assert.strictEqual(projectService.configuredProjects.get(configFile.path), project); assert.isTrue(project.hasOpenRef()); // file2 assert.isFalse(project.isClosed()); @@ -407,7 +398,7 @@ namespace ts.projectSystem { path: "/a/b/main.ts", content: "let x =1;" }; - const configFile: File = { + const configFile: ts.projectSystem.File = { path: "/a/b/tsconfig.json", content: `{ "compilerOptions": { @@ -416,59 +407,59 @@ namespace ts.projectSystem { "files": [ "main.ts" ] }` }; - const host = createServerHost([file1, configFile, libFile]); - const projectService = createProjectService(host, { useSingleInferredProject: true }); + const host = ts.projectSystem.createServerHost([file1, configFile, ts.projectSystem.libFile]); + const projectService = ts.projectSystem.createProjectService(host, { useSingleInferredProject: true }); projectService.openClientFile(file1.path); - checkNumberOfConfiguredProjects(projectService, 1); + ts.projectSystem.checkNumberOfConfiguredProjects(projectService, 1); const project = projectService.configuredProjects.get(configFile.path)!; assert.isTrue(project.hasOpenRef()); // file1 projectService.closeClientFile(file1.path); - checkNumberOfConfiguredProjects(projectService, 1); + ts.projectSystem.checkNumberOfConfiguredProjects(projectService, 1); assert.strictEqual(projectService.configuredProjects.get(configFile.path), project); assert.isFalse(project.hasOpenRef()); // No files assert.isFalse(project.isClosed()); - projectService.openClientFile(libFile.path); - checkNumberOfConfiguredProjects(projectService, 0); + projectService.openClientFile(ts.projectSystem.libFile.path); + ts.projectSystem.checkNumberOfConfiguredProjects(projectService, 0); assert.isFalse(project.hasOpenRef()); // No files + project closed assert.isTrue(project.isClosed()); }); it("open file become a part of configured project if it is referenced from root file", () => { const file1 = { - path: `${tscWatch.projectRoot}/a/b/f1.ts`, + path: `${ts.tscWatch.projectRoot}/a/b/f1.ts`, content: "export let x = 5" }; const file2 = { - path: `${tscWatch.projectRoot}/a/c/f2.ts`, + path: `${ts.tscWatch.projectRoot}/a/c/f2.ts`, content: `import {x} from "../b/f1"` }; const file3 = { - path: `${tscWatch.projectRoot}/a/c/f3.ts`, + path: `${ts.tscWatch.projectRoot}/a/c/f3.ts`, content: "export let y = 1" }; const configFile = { - path: `${tscWatch.projectRoot}/a/c/tsconfig.json`, + path: `${ts.tscWatch.projectRoot}/a/c/tsconfig.json`, content: JSON.stringify({ compilerOptions: {}, files: ["f2.ts", "f3.ts"] }) }; - const host = createServerHost([file1, file2, file3]); - const projectService = createProjectService(host); + const host = ts.projectSystem.createServerHost([file1, file2, file3]); + const projectService = ts.projectSystem.createProjectService(host); projectService.openClientFile(file1.path); - checkNumberOfProjects(projectService, { inferredProjects: 1 }); - checkProjectActualFiles(projectService.inferredProjects[0], [file1.path]); + ts.projectSystem.checkNumberOfProjects(projectService, { inferredProjects: 1 }); + ts.projectSystem.checkProjectActualFiles(projectService.inferredProjects[0], [file1.path]); projectService.openClientFile(file3.path); - checkNumberOfProjects(projectService, { inferredProjects: 2 }); - checkProjectActualFiles(projectService.inferredProjects[0], [file1.path]); - checkProjectActualFiles(projectService.inferredProjects[1], [file3.path]); + ts.projectSystem.checkNumberOfProjects(projectService, { inferredProjects: 2 }); + ts.projectSystem.checkProjectActualFiles(projectService.inferredProjects[0], [file1.path]); + ts.projectSystem.checkProjectActualFiles(projectService.inferredProjects[1], [file3.path]); host.writeFile(configFile.path, configFile.content); host.checkTimeoutQueueLengthAndRun(2); // load configured project from disk + ensureProjectsForOpenFiles - checkNumberOfProjects(projectService, { configuredProjects: 1, inferredProjects: 2 }); - checkProjectActualFiles(configuredProjectAt(projectService, 0), [file1.path, file2.path, file3.path, configFile.path]); + ts.projectSystem.checkNumberOfProjects(projectService, { configuredProjects: 1, inferredProjects: 2 }); + ts.projectSystem.checkProjectActualFiles(ts.projectSystem.configuredProjectAt(projectService, 0), [file1.path, file2.path, file3.path, configFile.path]); assert.isTrue(projectService.inferredProjects[0].isOrphan()); assert.isTrue(projectService.inferredProjects[1].isOrphan()); }); @@ -487,19 +478,19 @@ namespace ts.projectSystem { content: JSON.stringify({ compilerOptions: {} }) }; - const host = createServerHost([file1, configFile]); - const projectService = createProjectService(host); + const host = ts.projectSystem.createServerHost([file1, configFile]); + const projectService = ts.projectSystem.createProjectService(host); projectService.openClientFile(file1.path); - checkNumberOfProjects(projectService, { configuredProjects: 1 }); - checkProjectActualFiles(configuredProjectAt(projectService, 0), [file1.path, configFile.path]); + ts.projectSystem.checkNumberOfProjects(projectService, { configuredProjects: 1 }); + ts.projectSystem.checkProjectActualFiles(ts.projectSystem.configuredProjectAt(projectService, 0), [file1.path, configFile.path]); host.writeFile(file2.path, file2.content); host.checkTimeoutQueueLengthAndRun(2); - checkNumberOfProjects(projectService, { configuredProjects: 1 }); - checkProjectRootFiles(configuredProjectAt(projectService, 0), [file1.path, file2.path]); + ts.projectSystem.checkNumberOfProjects(projectService, { configuredProjects: 1 }); + ts.projectSystem.checkProjectRootFiles(ts.projectSystem.configuredProjectAt(projectService, 0), [file1.path, file2.path]); }); it("can correctly update configured project when set of root files has changed (new file in list of files)", () => { @@ -516,18 +507,18 @@ namespace ts.projectSystem { content: JSON.stringify({ compilerOptions: {}, files: ["f1.ts"] }) }; - const host = createServerHost([file1, file2, configFile]); - const projectService = createProjectService(host); + const host = ts.projectSystem.createServerHost([file1, file2, configFile]); + const projectService = ts.projectSystem.createProjectService(host); projectService.openClientFile(file1.path); - checkNumberOfProjects(projectService, { configuredProjects: 1 }); - checkProjectActualFiles(configuredProjectAt(projectService, 0), [file1.path, configFile.path]); + ts.projectSystem.checkNumberOfProjects(projectService, { configuredProjects: 1 }); + ts.projectSystem.checkProjectActualFiles(ts.projectSystem.configuredProjectAt(projectService, 0), [file1.path, configFile.path]); host.writeFile(configFile.path, JSON.stringify({ compilerOptions: {}, files: ["f1.ts", "f2.ts"] })); - checkNumberOfProjects(projectService, { configuredProjects: 1 }); + ts.projectSystem.checkNumberOfProjects(projectService, { configuredProjects: 1 }); host.checkTimeoutQueueLengthAndRun(2); - checkProjectRootFiles(configuredProjectAt(projectService, 0), [file1.path, file2.path]); + ts.projectSystem.checkProjectRootFiles(ts.projectSystem.configuredProjectAt(projectService, 0), [file1.path, file2.path]); }); it("can update configured project when set of root files was not changed", () => { @@ -544,33 +535,33 @@ namespace ts.projectSystem { content: JSON.stringify({ compilerOptions: {}, files: ["f1.ts", "f2.ts"] }) }; - const host = createServerHost([file1, file2, configFile]); - const projectService = createProjectService(host); + const host = ts.projectSystem.createServerHost([file1, file2, configFile]); + const projectService = ts.projectSystem.createProjectService(host); projectService.openClientFile(file1.path); - checkNumberOfProjects(projectService, { configuredProjects: 1 }); - checkProjectActualFiles(configuredProjectAt(projectService, 0), [file1.path, file2.path, configFile.path]); + ts.projectSystem.checkNumberOfProjects(projectService, { configuredProjects: 1 }); + ts.projectSystem.checkProjectActualFiles(ts.projectSystem.configuredProjectAt(projectService, 0), [file1.path, file2.path, configFile.path]); host.writeFile(configFile.path, JSON.stringify({ compilerOptions: { outFile: "out.js" }, files: ["f1.ts", "f2.ts"] })); - checkNumberOfProjects(projectService, { configuredProjects: 1 }); - checkProjectRootFiles(configuredProjectAt(projectService, 0), [file1.path, file2.path]); + ts.projectSystem.checkNumberOfProjects(projectService, { configuredProjects: 1 }); + ts.projectSystem.checkProjectRootFiles(ts.projectSystem.configuredProjectAt(projectService, 0), [file1.path, file2.path]); }); it("Open ref of configured project when open file gets added to the project as part of configured file update", () => { - const file1: File = { + const file1: ts.projectSystem.File = { path: "/a/b/src/file1.ts", content: "let x = 1;" }; - const file2: File = { + const file2: ts.projectSystem.File = { path: "/a/b/src/file2.ts", content: "let y = 1;" }; - const file3: File = { + const file3: ts.projectSystem.File = { path: "/a/b/file3.ts", content: "let z = 1;" }; - const file4: File = { + const file4: ts.projectSystem.File = { path: "/a/file4.ts", content: "let z = 1;" }; @@ -580,34 +571,34 @@ namespace ts.projectSystem { }; const files = [file1, file2, file3, file4]; - const host = createServerHost(files.concat(configFile)); - const projectService = createProjectService(host); + const host = ts.projectSystem.createServerHost(files.concat(configFile)); + const projectService = ts.projectSystem.createProjectService(host); projectService.openClientFile(file1.path); projectService.openClientFile(file2.path); projectService.openClientFile(file3.path); projectService.openClientFile(file4.path); - const infos = files.map(file => projectService.getScriptInfoForPath(file.path as Path)!); - checkOpenFiles(projectService, files); - checkNumberOfProjects(projectService, { configuredProjects: 1, inferredProjects: 2 }); + const infos = files.map(file => projectService.getScriptInfoForPath(file.path as ts.Path)!); + ts.projectSystem.checkOpenFiles(projectService, files); + ts.projectSystem.checkNumberOfProjects(projectService, { configuredProjects: 1, inferredProjects: 2 }); const configProject1 = projectService.configuredProjects.get(configFile.path)!; assert.isTrue(configProject1.hasOpenRef()); // file1 and file3 - checkProjectActualFiles(configProject1, [file1.path, file3.path, configFile.path]); + ts.projectSystem.checkProjectActualFiles(configProject1, [file1.path, file3.path, configFile.path]); const inferredProject1 = projectService.inferredProjects[0]; - checkProjectActualFiles(inferredProject1, [file2.path]); + ts.projectSystem.checkProjectActualFiles(inferredProject1, [file2.path]); const inferredProject2 = projectService.inferredProjects[1]; - checkProjectActualFiles(inferredProject2, [file4.path]); + ts.projectSystem.checkProjectActualFiles(inferredProject2, [file4.path]); host.writeFile(configFile.path, "{}"); host.runQueuedTimeoutCallbacks(); verifyScriptInfos(); - checkOpenFiles(projectService, files); + ts.projectSystem.checkOpenFiles(projectService, files); verifyConfiguredProjectStateAfterUpdate(/*hasOpenRef*/ true, 2); // file1, file2, file3 assert.isTrue(projectService.inferredProjects[0].isOrphan()); const inferredProject3 = projectService.inferredProjects[1]; - checkProjectActualFiles(inferredProject3, [file4.path]); + ts.projectSystem.checkProjectActualFiles(inferredProject3, [file4.path]); assert.strictEqual(inferredProject3, inferredProject2); projectService.closeClientFile(file1.path); @@ -615,73 +606,73 @@ namespace ts.projectSystem { projectService.closeClientFile(file4.path); verifyScriptInfos(); - checkOpenFiles(projectService, [file3]); + ts.projectSystem.checkOpenFiles(projectService, [file3]); verifyConfiguredProjectStateAfterUpdate(/*hasOpenRef*/ true, 2); // file3 assert.isTrue(projectService.inferredProjects[0].isOrphan()); assert.isTrue(projectService.inferredProjects[1].isOrphan()); projectService.openClientFile(file4.path); verifyScriptInfos(); - checkOpenFiles(projectService, [file3, file4]); + ts.projectSystem.checkOpenFiles(projectService, [file3, file4]); verifyConfiguredProjectStateAfterUpdate(/*hasOpenRef*/ true, 1); // file3 const inferredProject4 = projectService.inferredProjects[0]; - checkProjectActualFiles(inferredProject4, [file4.path]); + ts.projectSystem.checkProjectActualFiles(inferredProject4, [file4.path]); projectService.closeClientFile(file3.path); verifyScriptInfos(); - checkOpenFiles(projectService, [file4]); + ts.projectSystem.checkOpenFiles(projectService, [file4]); verifyConfiguredProjectStateAfterUpdate(/*hasOpenRef*/ false, 1); // No open files const inferredProject5 = projectService.inferredProjects[0]; - checkProjectActualFiles(inferredProject4, [file4.path]); + ts.projectSystem.checkProjectActualFiles(inferredProject4, [file4.path]); assert.strictEqual(inferredProject5, inferredProject4); - const file5: File = { + const file5: ts.projectSystem.File = { path: "/file5.ts", content: "let zz = 1;" }; host.writeFile(file5.path, file5.content); projectService.openClientFile(file5.path); verifyScriptInfosAreUndefined([file1, file2, file3]); - assert.strictEqual(projectService.getScriptInfoForPath(file4.path as Path), find(infos, info => info.path === file4.path)); - assert.isDefined(projectService.getScriptInfoForPath(file5.path as Path)); - checkOpenFiles(projectService, [file4, file5]); - checkNumberOfProjects(projectService, { inferredProjects: 2 }); - checkProjectActualFiles(projectService.inferredProjects[0], [file4.path]); - checkProjectActualFiles(projectService.inferredProjects[1], [file5.path]); + assert.strictEqual(projectService.getScriptInfoForPath(file4.path as ts.Path), ts.find(infos, info => info.path === file4.path)); + assert.isDefined(projectService.getScriptInfoForPath(file5.path as ts.Path)); + ts.projectSystem.checkOpenFiles(projectService, [file4, file5]); + ts.projectSystem.checkNumberOfProjects(projectService, { inferredProjects: 2 }); + ts.projectSystem.checkProjectActualFiles(projectService.inferredProjects[0], [file4.path]); + ts.projectSystem.checkProjectActualFiles(projectService.inferredProjects[1], [file5.path]); function verifyScriptInfos() { infos.forEach(info => assert.strictEqual(projectService.getScriptInfoForPath(info.path), info)); } - function verifyScriptInfosAreUndefined(files: File[]) { + function verifyScriptInfosAreUndefined(files: ts.projectSystem.File[]) { for (const file of files) { - assert.isUndefined(projectService.getScriptInfoForPath(file.path as Path)); + assert.isUndefined(projectService.getScriptInfoForPath(file.path as ts.Path)); } } function verifyConfiguredProjectStateAfterUpdate(hasOpenRef: boolean, inferredProjects: number) { - checkNumberOfProjects(projectService, { configuredProjects: 1, inferredProjects }); + ts.projectSystem.checkNumberOfProjects(projectService, { configuredProjects: 1, inferredProjects }); const configProject2 = projectService.configuredProjects.get(configFile.path)!; assert.strictEqual(configProject2, configProject1); - checkProjectActualFiles(configProject2, [file1.path, file2.path, file3.path, configFile.path]); + ts.projectSystem.checkProjectActualFiles(configProject2, [file1.path, file2.path, file3.path, configFile.path]); assert.equal(configProject2.hasOpenRef(), hasOpenRef); } }); it("Open ref of configured project when open file gets added to the project as part of configured file update buts its open file references are all closed when the update happens", () => { - const file1: File = { + const file1: ts.projectSystem.File = { path: "/a/b/src/file1.ts", content: "let x = 1;" }; - const file2: File = { + const file2: ts.projectSystem.File = { path: "/a/b/src/file2.ts", content: "let y = 1;" }; - const file3: File = { + const file3: ts.projectSystem.File = { path: "/a/b/file3.ts", content: "let z = 1;" }; - const file4: File = { + const file4: ts.projectSystem.File = { path: "/a/file4.ts", content: "let z = 1;" }; @@ -692,19 +683,19 @@ namespace ts.projectSystem { const files = [file1, file2, file3]; const hostFiles = files.concat(file4, configFile); - const host = createServerHost(hostFiles); - const projectService = createProjectService(host); + const host = ts.projectSystem.createServerHost(hostFiles); + const projectService = ts.projectSystem.createProjectService(host); projectService.openClientFile(file1.path); projectService.openClientFile(file2.path); projectService.openClientFile(file3.path); - checkNumberOfProjects(projectService, { configuredProjects: 1, inferredProjects: 1 }); + ts.projectSystem.checkNumberOfProjects(projectService, { configuredProjects: 1, inferredProjects: 1 }); const configuredProject = projectService.configuredProjects.get(configFile.path)!; assert.isTrue(configuredProject.hasOpenRef()); // file1 and file3 - checkProjectActualFiles(configuredProject, [file1.path, file3.path, configFile.path]); + ts.projectSystem.checkProjectActualFiles(configuredProject, [file1.path, file3.path, configFile.path]); const inferredProject1 = projectService.inferredProjects[0]; - checkProjectActualFiles(inferredProject1, [file2.path]); + ts.projectSystem.checkProjectActualFiles(inferredProject1, [file2.path]); projectService.closeClientFile(file1.path); projectService.closeClientFile(file3.path); @@ -716,22 +707,22 @@ namespace ts.projectSystem { projectService.openClientFile(file4.path); - checkNumberOfProjects(projectService, { configuredProjects: 1, inferredProjects: 2 }); + ts.projectSystem.checkNumberOfProjects(projectService, { configuredProjects: 1, inferredProjects: 2 }); assert.strictEqual(projectService.configuredProjects.get(configFile.path), configuredProject); assert.isTrue(configuredProject.hasOpenRef()); // Pending update and F2 might get into the project assert.strictEqual(projectService.inferredProjects[0], inferredProject1); const inferredProject2 = projectService.inferredProjects[1]; - checkProjectActualFiles(inferredProject2, [file4.path]); + ts.projectSystem.checkProjectActualFiles(inferredProject2, [file4.path]); host.runQueuedTimeoutCallbacks(); - checkNumberOfProjects(projectService, { configuredProjects: 1, inferredProjects: 2 }); + ts.projectSystem.checkNumberOfProjects(projectService, { configuredProjects: 1, inferredProjects: 2 }); assert.strictEqual(projectService.configuredProjects.get(configFile.path), configuredProject); assert.isTrue(configuredProject.hasOpenRef()); // file2 - checkProjectActualFiles(configuredProject, [file1.path, file2.path, file3.path, configFile.path]); + ts.projectSystem.checkProjectActualFiles(configuredProject, [file1.path, file2.path, file3.path, configFile.path]); assert.strictEqual(projectService.inferredProjects[0], inferredProject1); assert.isTrue(inferredProject1.isOrphan()); assert.strictEqual(projectService.inferredProjects[1], inferredProject2); - checkProjectActualFiles(inferredProject2, [file4.path]); + ts.projectSystem.checkProjectActualFiles(inferredProject2, [file4.path]); }); it("files are properly detached when language service is disabled", () => { @@ -751,12 +742,10 @@ namespace ts.projectSystem { path: "/a/tsconfig.json", content: JSON.stringify({ compilerOptions: { allowJs: true } }) }; - const host = createServerHost([f1, f2, f3, config]); + const host = ts.projectSystem.createServerHost([f1, f2, f3, config]); const originalGetFileSize = host.getFileSize; - host.getFileSize = (filePath: string) => - filePath === f2.path ? server.maxProgramSizeForNonTsFiles + 1 : originalGetFileSize.call(host, filePath); - - const projectService = createProjectService(host); + host.getFileSize = (filePath: string) => filePath === f2.path ? ts.server.maxProgramSizeForNonTsFiles + 1 : originalGetFileSize.call(host, filePath); + const projectService = ts.projectSystem.createProjectService(host); projectService.openClientFile(f1.path); projectService.checkNumberOfProjects({ configuredProjects: 1 }); const project = projectService.configuredProjects.get(config.path)!; @@ -771,7 +760,7 @@ namespace ts.projectSystem { for (const f of [f1, f2, f3]) { // All the script infos should be present and contain the project since it is still alive. - const scriptInfo = projectService.getScriptInfoForNormalizedPath(server.toNormalizedPath(f.path))!; + const scriptInfo = projectService.getScriptInfoForNormalizedPath(ts.server.toNormalizedPath(f.path))!; assert.equal(scriptInfo.containingProjects.length, 1, `expect 1 containing projects for '${f.path}'`); assert.equal(scriptInfo.containingProjects[0], project, `expect configured project to be the only containing project for '${f.path}'`); } @@ -788,7 +777,7 @@ namespace ts.projectSystem { for (const f of [f1, f2, f3]) { // All the script infos should not be present since the project is closed and orphan script infos are collected - assert.isUndefined(projectService.getScriptInfoForNormalizedPath(server.toNormalizedPath(f.path))); + assert.isUndefined(projectService.getScriptInfoForNormalizedPath(ts.server.toNormalizedPath(f.path))); } }); @@ -805,34 +794,33 @@ namespace ts.projectSystem { path: "/a/jsconfig.json", content: "{}" }; - const host = createServerHost([f1, f2, config]); + const host = ts.projectSystem.createServerHost([f1, f2, config]); const originalGetFileSize = host.getFileSize; - host.getFileSize = (filePath: string) => - filePath === f2.path ? server.maxProgramSizeForNonTsFiles + 1 : originalGetFileSize.call(host, filePath); - const { session, events } = createSessionWithEventTracking(host, server.ProjectLanguageServiceStateEvent); + host.getFileSize = (filePath: string) => filePath === f2.path ? ts.server.maxProgramSizeForNonTsFiles + 1 : originalGetFileSize.call(host, filePath); + const { session, events } = ts.projectSystem.createSessionWithEventTracking(host, ts.server.ProjectLanguageServiceStateEvent); session.executeCommand({ seq: 0, type: "request", command: "open", arguments: { file: f1.path } - } as protocol.OpenRequest); + } as ts.projectSystem.protocol.OpenRequest); const projectService = session.getProjectService(); - checkNumberOfProjects(projectService, { configuredProjects: 1 }); - const project = configuredProjectAt(projectService, 0); + ts.projectSystem.checkNumberOfProjects(projectService, { configuredProjects: 1 }); + const project = ts.projectSystem.configuredProjectAt(projectService, 0); assert.isFalse(project.languageServiceEnabled, "Language service enabled"); assert.equal(events.length, 1, "should receive event"); assert.equal(events[0].data.project, project, "project name"); assert.isFalse(events[0].data.languageServiceEnabled, "Language service state"); - const options = projectService.getFormatCodeOptions(f1.path as server.NormalizedPath); + const options = projectService.getFormatCodeOptions(f1.path as ts.server.NormalizedPath); const edits = project.getLanguageService().getFormattingEditsForDocument(f1.path, options); - assert.deepEqual(edits, [{ span: createTextSpan(/*start*/ 7, /*length*/ 3), newText: " " }]); + assert.deepEqual(edits, [{ span: ts.createTextSpan(/*start*/ 7, /*length*/ 3), newText: " " }]); }); it("when multiple projects are open, detects correct default project", () => { - const barConfig: File = { - path: `${tscWatch.projectRoot}/bar/tsconfig.json`, + const barConfig: ts.projectSystem.File = { + path: `${ts.tscWatch.projectRoot}/bar/tsconfig.json`, content: JSON.stringify({ include: ["index.ts"], compilerOptions: { @@ -840,15 +828,15 @@ namespace ts.projectSystem { } }) }; - const barIndex: File = { - path: `${tscWatch.projectRoot}/bar/index.ts`, + const barIndex: ts.projectSystem.File = { + path: `${ts.tscWatch.projectRoot}/bar/index.ts`, content: ` export function bar() { console.log("hello world"); }` }; - const fooConfig: File = { - path: `${tscWatch.projectRoot}/foo/tsconfig.json`, + const fooConfig: ts.projectSystem.File = { + path: `${ts.tscWatch.projectRoot}/foo/tsconfig.json`, content: JSON.stringify({ include: ["index.ts"], compilerOptions: { @@ -856,75 +844,77 @@ export function bar() { } }) }; - const fooIndex: File = { - path: `${tscWatch.projectRoot}/foo/index.ts`, + const fooIndex: ts.projectSystem.File = { + path: `${ts.tscWatch.projectRoot}/foo/index.ts`, content: ` import { bar } from "bar"; bar();` }; - const barSymLink: SymLink = { - path: `${tscWatch.projectRoot}/foo/node_modules/bar`, - symLink: `${tscWatch.projectRoot}/bar` + const barSymLink: ts.projectSystem.SymLink = { + path: `${ts.tscWatch.projectRoot}/foo/node_modules/bar`, + symLink: `${ts.tscWatch.projectRoot}/bar` }; - const lib2017: File = { - path: `${getDirectoryPath(libFile.path)}/lib.es2017.d.ts`, - content: libFile.content + const lib2017: ts.projectSystem.File = { + path: `${ts.getDirectoryPath(ts.projectSystem.libFile.path)}/lib.es2017.d.ts`, + content: ts.projectSystem.libFile.content }; - const libDom: File = { - path: `${getDirectoryPath(libFile.path)}/lib.dom.d.ts`, + const libDom: ts.projectSystem.File = { + path: `${ts.getDirectoryPath(ts.projectSystem.libFile.path)}/lib.dom.d.ts`, content: ` declare var console: { log(...args: any[]): void; };` }; - const host = createServerHost([barConfig, barIndex, fooConfig, fooIndex, barSymLink, lib2017, libDom]); - const session = createSession(host, { canUseEvents: true, logger: createLoggerWithInMemoryLogs() }); - openFilesForSession([fooIndex, barIndex], session); - verifyGetErrRequest({ session, host, files: [barIndex, fooIndex] }); - baselineTsserverLogs("configuredProjects", "when multiple projects are open detects correct default project", session); + const host = ts.projectSystem.createServerHost([barConfig, barIndex, fooConfig, fooIndex, barSymLink, lib2017, libDom]); + const session = ts.projectSystem.createSession(host, { canUseEvents: true, logger: ts.projectSystem.createLoggerWithInMemoryLogs() }); + ts.projectSystem.openFilesForSession([fooIndex, barIndex], session); + ts.projectSystem.verifyGetErrRequest({ session, host, files: [barIndex, fooIndex] }); + ts.projectSystem.baselineTsserverLogs("configuredProjects", "when multiple projects are open detects correct default project", session); }); it("when file name starts with ^", () => { - const file: File = { - path: `${tscWatch.projectRoot}/file.ts`, + const file: ts.projectSystem.File = { + path: `${ts.tscWatch.projectRoot}/file.ts`, content: "const x = 10;" }; - const app: File = { - path: `${tscWatch.projectRoot}/^app.ts`, + const app: ts.projectSystem.File = { + path: `${ts.tscWatch.projectRoot}/^app.ts`, content: "const y = 10;" }; - const tsconfig: File = { - path: `${tscWatch.projectRoot}/tsconfig.json`, + const tsconfig: ts.projectSystem.File = { + path: `${ts.tscWatch.projectRoot}/tsconfig.json`, content: "{}" }; - const host = createServerHost([file, app, tsconfig, libFile]); - const service = createProjectService(host); + const host = ts.projectSystem.createServerHost([file, app, tsconfig, ts.projectSystem.libFile]); + const service = ts.projectSystem.createProjectService(host); service.openClientFile(file.path); }); describe("when creating new file", () => { - const foo: File = { - path: `${tscWatch.projectRoot}/src/foo.ts`, + const foo: ts.projectSystem.File = { + path: `${ts.tscWatch.projectRoot}/src/foo.ts`, content: "export function foo() { }" }; - const bar: File = { - path: `${tscWatch.projectRoot}/src/bar.ts`, + const bar: ts.projectSystem.File = { + path: `${ts.tscWatch.projectRoot}/src/bar.ts`, content: "export function bar() { }" }; - const config: File = { - path: `${tscWatch.projectRoot}/tsconfig.json`, + const config: ts.projectSystem.File = { + path: `${ts.tscWatch.projectRoot}/tsconfig.json`, content: JSON.stringify({ include: ["./src"] }) }; - const fooBar: File = { - path: `${tscWatch.projectRoot}/src/sub/fooBar.ts`, + const fooBar: ts.projectSystem.File = { + path: `${ts.tscWatch.projectRoot}/src/sub/fooBar.ts`, content: "export function fooBar() { }" }; function verifySessionWorker({ withExclude, openFileBeforeCreating }: VerifySession, errorOnNewFileBeforeOldFile: boolean) { - const host = createServerHost([ - foo, bar, libFile, { path: `${tscWatch.projectRoot}/src/sub` }, + const host = ts.projectSystem.createServerHost([ + foo, bar, + ts.projectSystem.libFile, + { path: `${ts.tscWatch.projectRoot}/src/sub` }, withExclude ? { path: config.path, @@ -935,33 +925,33 @@ declare var console: { } : config ]); - const session = createSession(host, { + const session = ts.projectSystem.createSession(host, { canUseEvents: true, - logger: createLoggerWithInMemoryLogs(), + logger: ts.projectSystem.createLoggerWithInMemoryLogs(), }); - session.executeCommandSeq({ - command: protocol.CommandTypes.Open, + session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.Open, arguments: { file: foo.path, fileContent: foo.content, - projectRootPath: tscWatch.projectRoot + projectRootPath: ts.tscWatch.projectRoot } }); if (!openFileBeforeCreating) { host.writeFile(fooBar.path, fooBar.content); } - session.executeCommandSeq({ - command: protocol.CommandTypes.Open, + session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.Open, arguments: { file: fooBar.path, fileContent: fooBar.content, - projectRootPath: tscWatch.projectRoot + projectRootPath: ts.tscWatch.projectRoot } }); if (openFileBeforeCreating) { host.writeFile(fooBar.path, fooBar.content); } - verifyGetErrRequest({ + ts.projectSystem.verifyGetErrRequest({ session, host, files: errorOnNewFileBeforeOldFile ? @@ -969,7 +959,7 @@ declare var console: { [foo, fooBar], existingTimeouts: withExclude ? 0 : 2 }); - baselineTsserverLogs("configuredProjects", `creating new file and then open it ${openFileBeforeCreating ? "before" : "after"} watcher is invoked, ask errors on it ${errorOnNewFileBeforeOldFile ? "before" : "after"} old one${withExclude ? " without file being in config" : ""}`, session); + ts.projectSystem.baselineTsserverLogs("configuredProjects", `creating new file and then open it ${openFileBeforeCreating ? "before" : "after"} watcher is invoked, ask errors on it ${errorOnNewFileBeforeOldFile ? "before" : "after"} old one${withExclude ? " without file being in config" : ""}`, session); } interface VerifySession { withExclude?: boolean; @@ -1010,25 +1000,25 @@ declare var console: { }); it("when default configured project does not contain the file", () => { - const barConfig: File = { - path: `${tscWatch.projectRoot}/bar/tsconfig.json`, + const barConfig: ts.projectSystem.File = { + path: `${ts.tscWatch.projectRoot}/bar/tsconfig.json`, content: "{}" }; - const barIndex: File = { - path: `${tscWatch.projectRoot}/bar/index.ts`, + const barIndex: ts.projectSystem.File = { + path: `${ts.tscWatch.projectRoot}/bar/index.ts`, content: `import {foo} from "../foo/lib"; foo();` }; - const fooBarConfig: File = { - path: `${tscWatch.projectRoot}/foobar/tsconfig.json`, + const fooBarConfig: ts.projectSystem.File = { + path: `${ts.tscWatch.projectRoot}/foobar/tsconfig.json`, content: barConfig.path }; - const fooBarIndex: File = { - path: `${tscWatch.projectRoot}/foobar/index.ts`, + const fooBarIndex: ts.projectSystem.File = { + path: `${ts.tscWatch.projectRoot}/foobar/index.ts`, content: barIndex.content }; - const fooConfig: File = { - path: `${tscWatch.projectRoot}/foo/tsconfig.json`, + const fooConfig: ts.projectSystem.File = { + path: `${ts.tscWatch.projectRoot}/foo/tsconfig.json`, content: JSON.stringify({ include: ["index.ts"], compilerOptions: { @@ -1037,25 +1027,25 @@ foo();` } }) }; - const fooIndex: File = { - path: `${tscWatch.projectRoot}/foo/index.ts`, + const fooIndex: ts.projectSystem.File = { + path: `${ts.tscWatch.projectRoot}/foo/index.ts`, content: `export function foo() {}` }; - const host = createServerHost([barConfig, barIndex, fooBarConfig, fooBarIndex, fooConfig, fooIndex, libFile]); - tscWatch.ensureErrorFreeBuild(host, [fooConfig.path]); - const fooDts = `${tscWatch.projectRoot}/foo/lib/index.d.ts`; + const host = ts.projectSystem.createServerHost([barConfig, barIndex, fooBarConfig, fooBarIndex, fooConfig, fooIndex, ts.projectSystem.libFile]); + ts.tscWatch.ensureErrorFreeBuild(host, [fooConfig.path]); + const fooDts = `${ts.tscWatch.projectRoot}/foo/lib/index.d.ts`; assert.isTrue(host.fileExists(fooDts)); - const session = createSession(host); + const session = ts.projectSystem.createSession(host); const service = session.getProjectService(); service.openClientFile(barIndex.path); - checkProjectActualFiles(service.configuredProjects.get(barConfig.path)!, [barIndex.path, fooDts, libFile.path, barConfig.path]); + ts.projectSystem.checkProjectActualFiles(service.configuredProjects.get(barConfig.path)!, [barIndex.path, fooDts, ts.projectSystem.libFile.path, barConfig.path]); service.openClientFile(fooBarIndex.path); - checkProjectActualFiles(service.configuredProjects.get(fooBarConfig.path)!, [fooBarIndex.path, fooDts, libFile.path, fooBarConfig.path]); + ts.projectSystem.checkProjectActualFiles(service.configuredProjects.get(fooBarConfig.path)!, [fooBarIndex.path, fooDts, ts.projectSystem.libFile.path, fooBarConfig.path]); service.openClientFile(fooIndex.path); - checkProjectActualFiles(service.configuredProjects.get(fooConfig.path)!, [fooIndex.path, libFile.path, fooConfig.path]); + ts.projectSystem.checkProjectActualFiles(service.configuredProjects.get(fooConfig.path)!, [fooIndex.path, ts.projectSystem.libFile.path, fooConfig.path]); service.openClientFile(fooDts); - session.executeCommandSeq({ - command: protocol.CommandTypes.GetApplicableRefactors, + session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.GetApplicableRefactors, arguments: { file: fooDts, startLine: 1, @@ -1064,46 +1054,46 @@ foo();` endOffset: 1 } }); - assert.equal(service.tryGetDefaultProjectForFile(server.toNormalizedPath(fooDts)), service.configuredProjects.get(barConfig.path)); + assert.equal(service.tryGetDefaultProjectForFile(ts.server.toNormalizedPath(fooDts)), service.configuredProjects.get(barConfig.path)); }); describe("watches extended config files", () => { - function getService(additionalFiles?: File[]) { - const alphaExtendedConfig: File = { - path: `${tscWatch.projectRoot}/extended/alpha.tsconfig.json`, + function getService(additionalFiles?: ts.projectSystem.File[]) { + const alphaExtendedConfig: ts.projectSystem.File = { + path: `${ts.tscWatch.projectRoot}/extended/alpha.tsconfig.json`, content: "{}" }; - const bravoExtendedConfig: File = { - path: `${tscWatch.projectRoot}/extended/bravo.tsconfig.json`, + const bravoExtendedConfig: ts.projectSystem.File = { + path: `${ts.tscWatch.projectRoot}/extended/bravo.tsconfig.json`, content: JSON.stringify({ extends: "./alpha.tsconfig.json" }) }; - const aConfig: File = { - path: `${tscWatch.projectRoot}/a/tsconfig.json`, + const aConfig: ts.projectSystem.File = { + path: `${ts.tscWatch.projectRoot}/a/tsconfig.json`, content: JSON.stringify({ extends: "../extended/alpha.tsconfig.json", files: ["a.ts"] }) }; - const aFile: File = { - path: `${tscWatch.projectRoot}/a/a.ts`, + const aFile: ts.projectSystem.File = { + path: `${ts.tscWatch.projectRoot}/a/a.ts`, content: `let a = 1;` }; - const bConfig: File = { - path: `${tscWatch.projectRoot}/b/tsconfig.json`, + const bConfig: ts.projectSystem.File = { + path: `${ts.tscWatch.projectRoot}/b/tsconfig.json`, content: JSON.stringify({ extends: "../extended/bravo.tsconfig.json", files: ["b.ts"] }) }; - const bFile: File = { - path: `${tscWatch.projectRoot}/b/b.ts`, + const bFile: ts.projectSystem.File = { + path: `${ts.tscWatch.projectRoot}/b/b.ts`, content: `let b = 1;` }; - const host = createServerHost([alphaExtendedConfig, aConfig, aFile, bravoExtendedConfig, bConfig, bFile, ...(additionalFiles || emptyArray)]); - const projectService = createProjectService(host); + const host = ts.projectSystem.createServerHost([alphaExtendedConfig, aConfig, aFile, bravoExtendedConfig, bConfig, bFile, ...(additionalFiles || ts.emptyArray)]); + const projectService = ts.projectSystem.createProjectService(host); return { host, projectService, aFile, bFile, aConfig, bConfig, alphaExtendedConfig, bravoExtendedConfig }; } @@ -1112,14 +1102,14 @@ foo();` projectService.openClientFile(aFile.path); projectService.openClientFile(bFile.path); - checkNumberOfConfiguredProjects(projectService, 2); + ts.projectSystem.checkNumberOfConfiguredProjects(projectService, 2); const aProject = projectService.configuredProjects.get(aConfig.path)!; const bProject = projectService.configuredProjects.get(bConfig.path)!; - checkProjectActualFiles(aProject, [aFile.path, aConfig.path, alphaExtendedConfig.path]); - checkProjectActualFiles(bProject, [bFile.path, bConfig.path, bravoExtendedConfig.path, alphaExtendedConfig.path]); + ts.projectSystem.checkProjectActualFiles(aProject, [aFile.path, aConfig.path, alphaExtendedConfig.path]); + ts.projectSystem.checkProjectActualFiles(bProject, [bFile.path, bConfig.path, bravoExtendedConfig.path, alphaExtendedConfig.path]); assert.isUndefined(aProject.getCompilerOptions().strict); assert.isUndefined(bProject.getCompilerOptions().strict); - checkWatchedFiles(host, [aConfig.path, bConfig.path, libFile.path, bravoExtendedConfig.path, alphaExtendedConfig.path]); + ts.projectSystem.checkWatchedFiles(host, [aConfig.path, bConfig.path, ts.projectSystem.libFile.path, bravoExtendedConfig.path, alphaExtendedConfig.path]); host.writeFile(alphaExtendedConfig.path, JSON.stringify({ compilerOptions: { @@ -1131,7 +1121,7 @@ foo();` host.checkTimeoutQueueLengthAndRun(3); assert.isTrue(aProject.getCompilerOptions().strict); assert.isTrue(bProject.getCompilerOptions().strict); - checkWatchedFiles(host, [aConfig.path, bConfig.path, libFile.path, bravoExtendedConfig.path, alphaExtendedConfig.path]); + ts.projectSystem.checkWatchedFiles(host, [aConfig.path, bConfig.path, ts.projectSystem.libFile.path, bravoExtendedConfig.path, alphaExtendedConfig.path]); host.writeFile(bravoExtendedConfig.path, JSON.stringify({ extends: "./alpha.tsconfig.json", @@ -1144,7 +1134,7 @@ foo();` host.checkTimeoutQueueLengthAndRun(2); assert.isTrue(aProject.getCompilerOptions().strict); assert.isFalse(bProject.getCompilerOptions().strict); - checkWatchedFiles(host, [aConfig.path, bConfig.path, libFile.path, bravoExtendedConfig.path, alphaExtendedConfig.path]); + ts.projectSystem.checkWatchedFiles(host, [aConfig.path, bConfig.path, ts.projectSystem.libFile.path, bravoExtendedConfig.path, alphaExtendedConfig.path]); host.writeFile(bConfig.path, JSON.stringify({ extends: "../extended/alpha.tsconfig.json", @@ -1154,7 +1144,7 @@ foo();` host.checkTimeoutQueueLengthAndRun(2); assert.isTrue(aProject.getCompilerOptions().strict); assert.isTrue(bProject.getCompilerOptions().strict); - checkWatchedFiles(host, [aConfig.path, bConfig.path, libFile.path, alphaExtendedConfig.path]); + ts.projectSystem.checkWatchedFiles(host, [aConfig.path, bConfig.path, ts.projectSystem.libFile.path, alphaExtendedConfig.path]); host.writeFile(alphaExtendedConfig.path, "{}"); assert.isTrue(projectService.hasPendingProjectUpdate(aProject)); @@ -1162,16 +1152,16 @@ foo();` host.checkTimeoutQueueLengthAndRun(3); assert.isUndefined(aProject.getCompilerOptions().strict); assert.isUndefined(bProject.getCompilerOptions().strict); - checkWatchedFiles(host, [aConfig.path, bConfig.path, libFile.path, alphaExtendedConfig.path]); + ts.projectSystem.checkWatchedFiles(host, [aConfig.path, bConfig.path, ts.projectSystem.libFile.path, alphaExtendedConfig.path]); }); it("should stop watching the extended configs of closed projects", () => { - const dummy: File = { - path: `${tscWatch.projectRoot}/dummy/dummy.ts`, + const dummy: ts.projectSystem.File = { + path: `${ts.tscWatch.projectRoot}/dummy/dummy.ts`, content: `let dummy = 1;` }; - const dummyConfig: File = { - path: `${tscWatch.projectRoot}/dummy/tsconfig.json`, + const dummyConfig: ts.projectSystem.File = { + path: `${ts.tscWatch.projectRoot}/dummy/tsconfig.json`, content: "{}" }; const { host, projectService, aFile, bFile, aConfig, bConfig, alphaExtendedConfig, bravoExtendedConfig } = getService([dummy, dummyConfig]); @@ -1179,22 +1169,22 @@ foo();` projectService.openClientFile(aFile.path); projectService.openClientFile(bFile.path); projectService.openClientFile(dummy.path); - checkNumberOfConfiguredProjects(projectService, 3); - checkWatchedFiles(host, [aConfig.path, bConfig.path, libFile.path, bravoExtendedConfig.path, alphaExtendedConfig.path, dummyConfig.path]); + ts.projectSystem.checkNumberOfConfiguredProjects(projectService, 3); + ts.projectSystem.checkWatchedFiles(host, [aConfig.path, bConfig.path, ts.projectSystem.libFile.path, bravoExtendedConfig.path, alphaExtendedConfig.path, dummyConfig.path]); projectService.closeClientFile(bFile.path); projectService.closeClientFile(dummy.path); projectService.openClientFile(dummy.path); - checkNumberOfConfiguredProjects(projectService, 2); - checkWatchedFiles(host, [aConfig.path, libFile.path, alphaExtendedConfig.path, dummyConfig.path]); + ts.projectSystem.checkNumberOfConfiguredProjects(projectService, 2); + ts.projectSystem.checkWatchedFiles(host, [aConfig.path, ts.projectSystem.libFile.path, alphaExtendedConfig.path, dummyConfig.path]); projectService.closeClientFile(aFile.path); projectService.closeClientFile(dummy.path); projectService.openClientFile(dummy.path); - checkNumberOfConfiguredProjects(projectService, 1); - checkWatchedFiles(host, [libFile.path, dummyConfig.path]); + ts.projectSystem.checkNumberOfConfiguredProjects(projectService, 1); + ts.projectSystem.checkWatchedFiles(host, [ts.projectSystem.libFile.path, dummyConfig.path]); }); }); }); @@ -1213,16 +1203,16 @@ foo();` content: "let t = 10;" }; - const host = createServerHost([file1, configFile]); - const projectService = createProjectService(host); + const host = ts.projectSystem.createServerHost([file1, configFile]); + const projectService = ts.projectSystem.createProjectService(host); projectService.openClientFile(file1.path); host.runQueuedTimeoutCallbacks(); // Since file1 refers to config file as the default project, it needs to be kept alive - checkNumberOfProjects(projectService, { inferredProjects: 1, configuredProjects: 1 }); + ts.projectSystem.checkNumberOfProjects(projectService, { inferredProjects: 1, configuredProjects: 1 }); const inferredProject = projectService.inferredProjects[0]; - assert.isTrue(inferredProject.containsFile(file1.path as server.NormalizedPath)); - assert.isFalse(projectService.configuredProjects.get(configFile.path)!.containsFile(file1.path as server.NormalizedPath)); + assert.isTrue(inferredProject.containsFile(file1.path as ts.server.NormalizedPath)); + assert.isFalse(projectService.configuredProjects.get(configFile.path)!.containsFile(file1.path as ts.server.NormalizedPath)); }); it("should be able to handle @types if input file list is empty", () => { @@ -1245,8 +1235,8 @@ foo();` path: "/a/node_modules/@types/typings/lib.d.ts", content: `export const x: number` }; - const host = createServerHost([f, config, t1, t2], { currentDirectory: getDirectoryPath(f.path) }); - const projectService = createProjectService(host); + const host = ts.projectSystem.createServerHost([f, config, t1, t2], { currentDirectory: ts.getDirectoryPath(f.path) }); + const projectService = ts.projectSystem.createProjectService(host); projectService.openClientFile(f.path); // Since f refers to config file as the default project, it needs to be kept alive @@ -1255,11 +1245,11 @@ foo();` it("should tolerate invalid include files that start in subDirectory", () => { const f = { - path: `${tscWatch.projectRoot}/src/server/index.ts`, + path: `${ts.tscWatch.projectRoot}/src/server/index.ts`, content: "let x = 1" }; const config = { - path: `${tscWatch.projectRoot}/src/server/tsconfig.json`, + path: `${ts.tscWatch.projectRoot}/src/server/tsconfig.json`, content: JSON.stringify({ compiler: { module: "commonjs", @@ -1270,8 +1260,8 @@ foo();` ] }) }; - const host = createServerHost([f, config, libFile], { useCaseSensitiveFileNames: true }); - const projectService = createProjectService(host); + const host = ts.projectSystem.createServerHost([f, config, ts.projectSystem.libFile], { useCaseSensitiveFileNames: true }); + const projectService = ts.projectSystem.createProjectService(host); projectService.openClientFile(f.path); // Since f refers to config file as the default project, it needs to be kept alive @@ -1279,124 +1269,124 @@ foo();` }); it("Changed module resolution reflected when specifying files list", () => { - const file1: File = { + const file1: ts.projectSystem.File = { path: "/a/b/file1.ts", content: 'import classc from "file2"' }; - const file2a: File = { + const file2a: ts.projectSystem.File = { path: "/a/file2.ts", content: "export classc { method2a() { return 10; } }" }; - const file2: File = { + const file2: ts.projectSystem.File = { path: "/a/b/file2.ts", content: "export classc { method2() { return 10; } }" }; - const configFile: File = { + const configFile: ts.projectSystem.File = { path: "/a/b/tsconfig.json", content: JSON.stringify({ files: [file1.path], compilerOptions: { module: "amd" } }) }; - const files = [file1, file2a, configFile, libFile]; - const host = createServerHost(files); - const projectService = createProjectService(host); + const files = [file1, file2a, configFile, ts.projectSystem.libFile]; + const host = ts.projectSystem.createServerHost(files); + const projectService = ts.projectSystem.createProjectService(host); projectService.openClientFile(file1.path); - checkNumberOfProjects(projectService, { configuredProjects: 1 }); + ts.projectSystem.checkNumberOfProjects(projectService, { configuredProjects: 1 }); const project = projectService.configuredProjects.get(configFile.path)!; assert.isDefined(project); - checkProjectActualFiles(project, map(files, file => file.path)); - checkWatchedFiles(host, mapDefined(files, file => file === file1 ? undefined : file.path)); - checkWatchedDirectoriesDetailed(host, ["/a/b"], 1, /*recursive*/ false); - checkWatchedDirectoriesDetailed(host, ["/a/b/node_modules/@types"], 1, /*recursive*/ true); + ts.projectSystem.checkProjectActualFiles(project, ts.map(files, file => file.path)); + ts.projectSystem.checkWatchedFiles(host, ts.mapDefined(files, file => file === file1 ? undefined : file.path)); + ts.projectSystem.checkWatchedDirectoriesDetailed(host, ["/a/b"], 1, /*recursive*/ false); + ts.projectSystem.checkWatchedDirectoriesDetailed(host, ["/a/b/node_modules/@types"], 1, /*recursive*/ true); files.push(file2); host.writeFile(file2.path, file2.content); host.runQueuedTimeoutCallbacks(); // Scheduled invalidation of resolutions host.runQueuedTimeoutCallbacks(); // Actual update - checkNumberOfProjects(projectService, { configuredProjects: 1 }); + ts.projectSystem.checkNumberOfProjects(projectService, { configuredProjects: 1 }); assert.strictEqual(projectService.configuredProjects.get(configFile.path), project); - checkProjectActualFiles(project, mapDefined(files, file => file === file2a ? undefined : file.path)); - checkWatchedFiles(host, mapDefined(files, file => file === file1 ? undefined : file.path)); - checkWatchedDirectories(host, emptyArray, /*recursive*/ false); - checkWatchedDirectoriesDetailed(host, ["/a/b/node_modules/@types"], 1, /*recursive*/ true); + ts.projectSystem.checkProjectActualFiles(project, ts.mapDefined(files, file => file === file2a ? undefined : file.path)); + ts.projectSystem.checkWatchedFiles(host, ts.mapDefined(files, file => file === file1 ? undefined : file.path)); + ts.projectSystem.checkWatchedDirectories(host, ts.emptyArray, /*recursive*/ false); + ts.projectSystem.checkWatchedDirectoriesDetailed(host, ["/a/b/node_modules/@types"], 1, /*recursive*/ true); // On next file open the files file2a should be closed and not watched any more projectService.openClientFile(file2.path); - checkNumberOfProjects(projectService, { configuredProjects: 1 }); + ts.projectSystem.checkNumberOfProjects(projectService, { configuredProjects: 1 }); assert.strictEqual(projectService.configuredProjects.get(configFile.path), project); - checkProjectActualFiles(project, mapDefined(files, file => file === file2a ? undefined : file.path)); - checkWatchedFiles(host, [libFile.path, configFile.path]); - checkWatchedDirectories(host, emptyArray, /*recursive*/ false); - checkWatchedDirectoriesDetailed(host, ["/a/b/node_modules/@types"], 1, /*recursive*/ true); + ts.projectSystem.checkProjectActualFiles(project, ts.mapDefined(files, file => file === file2a ? undefined : file.path)); + ts.projectSystem.checkWatchedFiles(host, [ts.projectSystem.libFile.path, configFile.path]); + ts.projectSystem.checkWatchedDirectories(host, ts.emptyArray, /*recursive*/ false); + ts.projectSystem.checkWatchedDirectoriesDetailed(host, ["/a/b/node_modules/@types"], 1, /*recursive*/ true); }); it("Failed lookup locations uses parent most node_modules directory", () => { const root = "/user/username/rootfolder"; - const file1: File = { + const file1: ts.projectSystem.File = { path: "/a/b/src/file1.ts", content: 'import { classc } from "module1"' }; - const module1: File = { + const module1: ts.projectSystem.File = { path: "/a/b/node_modules/module1/index.d.ts", content: `import { class2 } from "module2"; export classc { method2a(): class2; }` }; - const module2: File = { + const module2: ts.projectSystem.File = { path: "/a/b/node_modules/module2/index.d.ts", content: "export class2 { method2() { return 10; } }" }; - const module3: File = { + const module3: ts.projectSystem.File = { path: "/a/b/node_modules/module/node_modules/module3/index.d.ts", content: "export class3 { method2() { return 10; } }" }; - const configFile: File = { + const configFile: ts.projectSystem.File = { path: "/a/b/src/tsconfig.json", content: JSON.stringify({ files: ["file1.ts"] }) }; const nonLibFiles = [file1, module1, module2, module3, configFile]; nonLibFiles.forEach(f => f.path = root + f.path); - const files = nonLibFiles.concat(libFile); - const host = createServerHost(files); - const projectService = createProjectService(host); + const files = nonLibFiles.concat(ts.projectSystem.libFile); + const host = ts.projectSystem.createServerHost(files); + const projectService = ts.projectSystem.createProjectService(host); projectService.openClientFile(file1.path); - checkNumberOfProjects(projectService, { configuredProjects: 1 }); + ts.projectSystem.checkNumberOfProjects(projectService, { configuredProjects: 1 }); const project = projectService.configuredProjects.get(configFile.path)!; assert.isDefined(project); - checkProjectActualFiles(project, [file1.path, libFile.path, module1.path, module2.path, configFile.path]); - checkWatchedFiles(host, [libFile.path, configFile.path]); - checkWatchedDirectories(host, [], /*recursive*/ false); - const watchedRecursiveDirectories = getTypeRootsFromLocation(root + "/a/b/src"); + ts.projectSystem.checkProjectActualFiles(project, [file1.path, ts.projectSystem.libFile.path, module1.path, module2.path, configFile.path]); + ts.projectSystem.checkWatchedFiles(host, [ts.projectSystem.libFile.path, configFile.path]); + ts.projectSystem.checkWatchedDirectories(host, [], /*recursive*/ false); + const watchedRecursiveDirectories = ts.projectSystem.getTypeRootsFromLocation(root + "/a/b/src"); watchedRecursiveDirectories.push(`${root}/a/b/src/node_modules`, `${root}/a/b/node_modules`); - checkWatchedDirectories(host, watchedRecursiveDirectories, /*recursive*/ true); + ts.projectSystem.checkWatchedDirectories(host, watchedRecursiveDirectories, /*recursive*/ true); }); }); describe("unittests:: tsserver:: ConfiguredProjects:: when reading tsconfig file fails", () => { it("should be tolerated without crashing the server", () => { const configFile = { - path: `${tscWatch.projectRoot}/tsconfig.json`, + path: `${ts.tscWatch.projectRoot}/tsconfig.json`, content: "" }; const file1 = { - path: `${tscWatch.projectRoot}/file1.ts`, + path: `${ts.tscWatch.projectRoot}/file1.ts`, content: "let t = 10;" }; - const host = createServerHost([file1, libFile, configFile]); - const { session, events } = createSessionWithEventTracking(host, server.ConfigFileDiagEvent); + const host = ts.projectSystem.createServerHost([file1, ts.projectSystem.libFile, configFile]); + const { session, events } = ts.projectSystem.createSessionWithEventTracking(host, ts.server.ConfigFileDiagEvent); const originalReadFile = host.readFile; host.readFile = f => { return f === configFile.path ? undefined : originalReadFile.call(host, f); }; - openFilesForSession([file1], session); + ts.projectSystem.openFilesForSession([file1], session); assert.deepEqual(events, [{ - eventName: server.ConfigFileDiagEvent, + eventName: ts.server.ConfigFileDiagEvent, data: { triggerFile: file1.path, configFileName: configFile.path, diagnostics: [ - createCompilerDiagnostic(Diagnostics.Cannot_read_file_0, configFile.path) + ts.createCompilerDiagnostic(ts.Diagnostics.Cannot_read_file_0, configFile.path) ] } }]); diff --git a/src/testRunner/unittests/tsserver/declarationFileMaps.ts b/src/testRunner/unittests/tsserver/declarationFileMaps.ts index 2ceb75d6b6015..773c561e7c124 100644 --- a/src/testRunner/unittests/tsserver/declarationFileMaps.ts +++ b/src/testRunner/unittests/tsserver/declarationFileMaps.ts @@ -1,22 +1,22 @@ namespace ts.projectSystem { - function documentSpanFromSubstring({ file, text, contextText, options, contextOptions }: DocumentSpanFromSubstring): DocumentSpan { + function documentSpanFromSubstring({ file, text, contextText, options, contextOptions }: ts.projectSystem.DocumentSpanFromSubstring): ts.DocumentSpan { const contextSpan = contextText !== undefined ? documentSpanFromSubstring({ file, text: contextText, options: contextOptions }) : undefined; return { fileName: file.path, - textSpan: textSpanFromSubstring(file.content, text, options), + textSpan: ts.projectSystem.textSpanFromSubstring(file.content, text, options), ...contextSpan && { contextSpan: contextSpan.textSpan } }; } - function renameLocation(input: DocumentSpanFromSubstring): RenameLocation { + function renameLocation(input: ts.projectSystem.DocumentSpanFromSubstring): ts.RenameLocation { return documentSpanFromSubstring(input); } - interface MakeReferenceEntry extends DocumentSpanFromSubstring { + interface MakeReferenceEntry extends ts.projectSystem.DocumentSpanFromSubstring { isDefinition?: boolean; isWriteAccess?: boolean; } - function makeReferencedSymbolEntry({ isDefinition, isWriteAccess, ...rest }: MakeReferenceEntry): ReferencedSymbolEntry { + function makeReferencedSymbolEntry({ isDefinition, isWriteAccess, ...rest }: MakeReferenceEntry): ts.ReferencedSymbolEntry { const result = { ...documentSpanFromSubstring(rest), isDefinition, @@ -29,32 +29,30 @@ namespace ts.projectSystem { return result; } - function checkDeclarationFiles(file: File, session: TestSession, expectedFiles: readonly File[]): void { - openFilesForSession([file], session); - const project = Debug.checkDefined(session.getProjectService().getDefaultProjectForFile(file.path as server.NormalizedPath, /*ensureProject*/ false)); + function checkDeclarationFiles(file: ts.projectSystem.File, session: ts.projectSystem.TestSession, expectedFiles: readonly ts.projectSystem.File[]): void { + ts.projectSystem.openFilesForSession([file], session); + const project = ts.Debug.checkDefined(session.getProjectService().getDefaultProjectForFile(file.path as ts.server.NormalizedPath, /*ensureProject*/ false)); const program = project.getCurrentProgram()!; - const output = getFileEmitOutput(program, Debug.checkDefined(program.getSourceFile(file.path)), /*emitOnlyDtsFiles*/ true); - closeFilesForSession([file], session); - - Debug.assert(!output.emitSkipped); - assert.deepEqual(output.outputFiles, expectedFiles.map((e): OutputFile => ({ name: e.path, text: e.content, writeByteOrderMark: false }))); + const output = ts.getFileEmitOutput(program, ts.Debug.checkDefined(program.getSourceFile(file.path)), /*emitOnlyDtsFiles*/ true); + ts.projectSystem.closeFilesForSession([file], session); + ts.Debug.assert(!output.emitSkipped); + assert.deepEqual(output.outputFiles, expectedFiles.map((e): ts.OutputFile => ({ name: e.path, text: e.content, writeByteOrderMark: false }))); } describe("unittests:: tsserver:: with declaration file maps:: project references", () => { - const aTs: File = { + const aTs: ts.projectSystem.File = { path: "/a/a.ts", content: "export function fnA() {}\nexport interface IfaceA {}\nexport const instanceA: IfaceA = {};", }; - const compilerOptions: CompilerOptions = { + const compilerOptions: ts.CompilerOptions = { outDir: "bin", declaration: true, declarationMap: true, composite: true, }; const configContent = JSON.stringify({ compilerOptions }); - const aTsconfig: File = { path: "/a/tsconfig.json", content: configContent }; - - const aDtsMapContent: RawSourceMap = { + const aTsconfig: ts.projectSystem.File = { path: "/a/tsconfig.json", content: configContent }; + const aDtsMapContent: ts.RawSourceMap = { version: 3, file: "a.d.ts", sourceRoot: "", @@ -62,23 +60,22 @@ namespace ts.projectSystem { names: [], mappings: "AAAA,wBAAgB,GAAG,SAAK;AACxB,MAAM,WAAW,MAAM;CAAG;AAC1B,eAAO,MAAM,SAAS,EAAE,MAAW,CAAC" }; - const aDtsMap: File = { + const aDtsMap: ts.projectSystem.File = { path: "/a/bin/a.d.ts.map", content: JSON.stringify(aDtsMapContent), }; - const aDts: File = { + const aDts: ts.projectSystem.File = { path: "/a/bin/a.d.ts", // ${""} is needed to mangle the sourceMappingURL part or it breaks the build content: `export declare function fnA(): void;\nexport interface IfaceA {\n}\nexport declare const instanceA: IfaceA;\n//# source${""}MappingURL=a.d.ts.map`, }; - const bTs: File = { + const bTs: ts.projectSystem.File = { path: "/b/b.ts", content: "export function fnB() {}", }; - const bTsconfig: File = { path: "/b/tsconfig.json", content: configContent }; - - const bDtsMapContent: RawSourceMap = { + const bTsconfig: ts.projectSystem.File = { path: "/b/tsconfig.json", content: configContent }; + const bDtsMapContent: ts.RawSourceMap = { version: 3, file: "b.d.ts", sourceRoot: "", @@ -86,32 +83,32 @@ namespace ts.projectSystem { names: [], mappings: "AAAA,wBAAgB,GAAG,SAAK", }; - const bDtsMap: File = { + const bDtsMap: ts.projectSystem.File = { path: "/b/bin/b.d.ts.map", content: JSON.stringify(bDtsMapContent), }; - const bDts: File = { + const bDts: ts.projectSystem.File = { // ${""} is need to mangle the sourceMappingURL part so it doesn't break the build path: "/b/bin/b.d.ts", content: `export declare function fnB(): void;\n//# source${""}MappingURL=b.d.ts.map`, }; - const dummyFile: File = { + const dummyFile: ts.projectSystem.File = { path: "/dummy/dummy.ts", content: "let a = 10;" }; - const userTs: File = { + const userTs: ts.projectSystem.File = { path: "/user/user.ts", content: 'import * as a from "../a/bin/a";\nimport * as b from "../b/bin/b";\nexport function fnUser() { a.fnA(); b.fnB(); a.instanceA; }', }; - const userTsForConfigProject: File = { + const userTsForConfigProject: ts.projectSystem.File = { path: "/user/user.ts", content: 'import * as a from "../a/a";\nimport * as b from "../b/b";\nexport function fnUser() { a.fnA(); b.fnB(); a.instanceA; }', }; - const userTsconfig: File = { + const userTsconfig: ts.projectSystem.File = { path: "/user/tsconfig.json", content: JSON.stringify({ file: ["user.ts"], @@ -120,8 +117,8 @@ namespace ts.projectSystem { }; function makeSampleProjects(addUserTsConfig?: boolean, keepAllFiles?: boolean) { - const host = createServerHost([aTs, aTsconfig, aDtsMap, aDts, bTsconfig, bTs, bDtsMap, bDts, ...(addUserTsConfig ? [userTsForConfigProject, userTsconfig] : [userTs]), dummyFile]); - const session = createSession(host); + const host = ts.projectSystem.createServerHost([aTs, aTsconfig, aDtsMap, aDts, bTsconfig, bTs, bDtsMap, bDts, ...(addUserTsConfig ? [userTsForConfigProject, userTsconfig] : [userTs]), dummyFile]); + const session = ts.projectSystem.createSession(host); checkDeclarationFiles(aTs, session, [aDtsMap, aDts]); checkDeclarationFiles(bTs, session, [bDtsMap, bDts]); @@ -131,70 +128,70 @@ namespace ts.projectSystem { host.deleteFile(bTs.path); } - openFilesForSession([userTs], session); + ts.projectSystem.openFilesForSession([userTs], session); const service = session.getProjectService(); // If config file then userConfig project and bConfig project since it is referenced - checkNumberOfProjects(service, addUserTsConfig ? { configuredProjects: 2 } : { inferredProjects: 1 }); + ts.projectSystem.checkNumberOfProjects(service, addUserTsConfig ? { configuredProjects: 2 } : { inferredProjects: 1 }); return session; } - function verifyInferredProjectUnchanged(session: TestSession) { - checkProjectActualFiles(session.getProjectService().inferredProjects[0], [userTs.path, aDts.path, bDts.path]); + function verifyInferredProjectUnchanged(session: ts.projectSystem.TestSession) { + ts.projectSystem.checkProjectActualFiles(session.getProjectService().inferredProjects[0], [userTs.path, aDts.path, bDts.path]); } - function verifyDummyProject(session: TestSession) { - checkProjectActualFiles(session.getProjectService().inferredProjects[0], [dummyFile.path]); + function verifyDummyProject(session: ts.projectSystem.TestSession) { + ts.projectSystem.checkProjectActualFiles(session.getProjectService().inferredProjects[0], [dummyFile.path]); } - function verifyOnlyOrphanInferredProject(session: TestSession) { - openFilesForSession([dummyFile], session); - checkNumberOfProjects(session.getProjectService(), { inferredProjects: 1 }); + function verifyOnlyOrphanInferredProject(session: ts.projectSystem.TestSession) { + ts.projectSystem.openFilesForSession([dummyFile], session); + ts.projectSystem.checkNumberOfProjects(session.getProjectService(), { inferredProjects: 1 }); verifyDummyProject(session); } - function verifySingleInferredProject(session: TestSession) { - checkNumberOfProjects(session.getProjectService(), { inferredProjects: 1 }); + function verifySingleInferredProject(session: ts.projectSystem.TestSession) { + ts.projectSystem.checkNumberOfProjects(session.getProjectService(), { inferredProjects: 1 }); verifyInferredProjectUnchanged(session); // Close user file should close all the projects after opening dummy file - closeFilesForSession([userTs], session); + ts.projectSystem.closeFilesForSession([userTs], session); verifyOnlyOrphanInferredProject(session); } - function verifyATsConfigProject(session: TestSession) { - checkProjectActualFiles(session.getProjectService().configuredProjects.get(aTsconfig.path)!, [aTs.path, aTsconfig.path]); + function verifyATsConfigProject(session: ts.projectSystem.TestSession) { + ts.projectSystem.checkProjectActualFiles(session.getProjectService().configuredProjects.get(aTsconfig.path)!, [aTs.path, aTsconfig.path]); } - function verifyATsConfigOriginalProject(session: TestSession) { - checkNumberOfProjects(session.getProjectService(), { inferredProjects: 1, configuredProjects: 1 }); + function verifyATsConfigOriginalProject(session: ts.projectSystem.TestSession) { + ts.projectSystem.checkNumberOfProjects(session.getProjectService(), { inferredProjects: 1, configuredProjects: 1 }); verifyInferredProjectUnchanged(session); verifyATsConfigProject(session); // Close user file should close all the projects - closeFilesForSession([userTs], session); + ts.projectSystem.closeFilesForSession([userTs], session); verifyOnlyOrphanInferredProject(session); } - function verifyATsConfigWhenOpened(session: TestSession) { - checkNumberOfProjects(session.getProjectService(), { inferredProjects: 1, configuredProjects: 1 }); + function verifyATsConfigWhenOpened(session: ts.projectSystem.TestSession) { + ts.projectSystem.checkNumberOfProjects(session.getProjectService(), { inferredProjects: 1, configuredProjects: 1 }); verifyInferredProjectUnchanged(session); verifyATsConfigProject(session); - closeFilesForSession([userTs], session); - openFilesForSession([dummyFile], session); - checkNumberOfProjects(session.getProjectService(), { inferredProjects: 1, configuredProjects: 1 }); + ts.projectSystem.closeFilesForSession([userTs], session); + ts.projectSystem.openFilesForSession([dummyFile], session); + ts.projectSystem.checkNumberOfProjects(session.getProjectService(), { inferredProjects: 1, configuredProjects: 1 }); verifyDummyProject(session); verifyATsConfigProject(session); // ATsConfig should still be alive } - function verifyUserTsConfigProject(session: TestSession) { - checkProjectActualFiles(session.getProjectService().configuredProjects.get(userTsconfig.path)!, [userTs.path, aTs.path, userTsconfig.path]); + function verifyUserTsConfigProject(session: ts.projectSystem.TestSession) { + ts.projectSystem.checkProjectActualFiles(session.getProjectService().configuredProjects.get(userTsconfig.path)!, [userTs.path, aTs.path, userTsconfig.path]); } it("goToDefinition", () => { const session = makeSampleProjects(); - const response = executeSessionRequest(session, protocol.CommandTypes.Definition, protocolFileLocationFromSubstring(userTs, "fnA()")); + const response = ts.projectSystem.executeSessionRequest(session, ts.projectSystem.protocol.CommandTypes.Definition, ts.projectSystem.protocolFileLocationFromSubstring(userTs, "fnA()")); assert.deepEqual(response, [ - protocolFileSpanWithContextFromSubstring({ + ts.projectSystem.protocolFileSpanWithContextFromSubstring({ file: aTs, text: "fnA", contextText: "export function fnA() {}" @@ -205,11 +202,11 @@ namespace ts.projectSystem { it("getDefinitionAndBoundSpan", () => { const session = makeSampleProjects(); - const response = executeSessionRequest(session, protocol.CommandTypes.DefinitionAndBoundSpan, protocolFileLocationFromSubstring(userTs, "fnA()")); + const response = ts.projectSystem.executeSessionRequest(session, ts.projectSystem.protocol.CommandTypes.DefinitionAndBoundSpan, ts.projectSystem.protocolFileLocationFromSubstring(userTs, "fnA()")); assert.deepEqual(response, { - textSpan: protocolTextSpanFromSubstring(userTs.content, "fnA"), + textSpan: ts.projectSystem.protocolTextSpanFromSubstring(userTs.content, "fnA"), definitions: [ - protocolFileSpanWithContextFromSubstring({ + ts.projectSystem.protocolFileSpanWithContextFromSubstring({ file: aTs, text: "fnA", contextText: "export function fnA() {}" @@ -221,38 +218,38 @@ namespace ts.projectSystem { it("getDefinitionAndBoundSpan with file navigation", () => { const session = makeSampleProjects(/*addUserTsConfig*/ true); - const response = executeSessionRequest(session, protocol.CommandTypes.DefinitionAndBoundSpan, protocolFileLocationFromSubstring(userTs, "fnA()")); + const response = ts.projectSystem.executeSessionRequest(session, ts.projectSystem.protocol.CommandTypes.DefinitionAndBoundSpan, ts.projectSystem.protocolFileLocationFromSubstring(userTs, "fnA()")); assert.deepEqual(response, { - textSpan: protocolTextSpanFromSubstring(userTs.content, "fnA"), + textSpan: ts.projectSystem.protocolTextSpanFromSubstring(userTs.content, "fnA"), definitions: [ - protocolFileSpanWithContextFromSubstring({ + ts.projectSystem.protocolFileSpanWithContextFromSubstring({ file: aTs, text: "fnA", contextText: "export function fnA() {}" }) ], }); - checkNumberOfProjects(session.getProjectService(), { configuredProjects: 2 }); + ts.projectSystem.checkNumberOfProjects(session.getProjectService(), { configuredProjects: 2 }); verifyUserTsConfigProject(session); // Navigate to the definition - closeFilesForSession([userTs], session); - openFilesForSession([aTs], session); + ts.projectSystem.closeFilesForSession([userTs], session); + ts.projectSystem.openFilesForSession([aTs], session); // UserTs configured project should be alive - checkNumberOfProjects(session.getProjectService(), { configuredProjects: 3 }); + ts.projectSystem.checkNumberOfProjects(session.getProjectService(), { configuredProjects: 3 }); verifyUserTsConfigProject(session); verifyATsConfigProject(session); - closeFilesForSession([aTs], session); + ts.projectSystem.closeFilesForSession([aTs], session); verifyOnlyOrphanInferredProject(session); }); it("goToType", () => { const session = makeSampleProjects(); - const response = executeSessionRequest(session, protocol.CommandTypes.TypeDefinition, protocolFileLocationFromSubstring(userTs, "instanceA")); + const response = ts.projectSystem.executeSessionRequest(session, ts.projectSystem.protocol.CommandTypes.TypeDefinition, ts.projectSystem.protocolFileLocationFromSubstring(userTs, "instanceA")); assert.deepEqual(response, [ - protocolFileSpanWithContextFromSubstring({ + ts.projectSystem.protocolFileSpanWithContextFromSubstring({ file: aTs, text: "IfaceA", contextText: "export interface IfaceA {}" @@ -263,22 +260,23 @@ namespace ts.projectSystem { it("goToImplementation", () => { const session = makeSampleProjects(); - const response = executeSessionRequest(session, protocol.CommandTypes.Implementation, protocolFileLocationFromSubstring(userTs, "fnA()")); + const response = ts.projectSystem.executeSessionRequest(session, ts.projectSystem.protocol.CommandTypes.Implementation, ts.projectSystem.protocolFileLocationFromSubstring(userTs, "fnA()")); assert.deepEqual(response, [ - protocolFileSpanWithContextFromSubstring({ + ts.projectSystem.protocolFileSpanWithContextFromSubstring({ file: aTs, text: "fnA", contextText: "export function fnA() {}" - })]); + }) + ]); verifySingleInferredProject(session); }); it("goToDefinition -- target does not exist", () => { const session = makeSampleProjects(); - const response = executeSessionRequest(session, CommandNames.Definition, protocolFileLocationFromSubstring(userTs, "fnB()")); + const response = ts.projectSystem.executeSessionRequest(session, ts.projectSystem.CommandNames.Definition, ts.projectSystem.protocolFileLocationFromSubstring(userTs, "fnB()")); // bTs does not exist, so stick with bDts assert.deepEqual(response, [ - protocolFileSpanWithContextFromSubstring({ + ts.projectSystem.protocolFileSpanWithContextFromSubstring({ file: bDts, text: "fnB", contextText: "export declare function fnB(): void;" @@ -289,30 +287,30 @@ namespace ts.projectSystem { it("navigateTo", () => { const session = makeSampleProjects(); - const response = executeSessionRequest(session, CommandNames.Navto, { file: userTs.path, searchValue: "fn" }); - assert.deepEqual(response, [ + const response = ts.projectSystem.executeSessionRequest(session, ts.projectSystem.CommandNames.Navto, { file: userTs.path, searchValue: "fn" }); + assert.deepEqual(response, [ // Keep the .d.ts file since the .ts file no longer exists // (otherwise it would be treated as not in the project) { - ...protocolFileSpanFromSubstring({ + ...ts.projectSystem.protocolFileSpanFromSubstring({ file: bDts, text: "export declare function fnB(): void;" }), name: "fnB", matchKind: "prefix", isCaseSensitive: true, - kind: ScriptElementKind.functionElement, + kind: ts.ScriptElementKind.functionElement, kindModifiers: "export,declare", }, { - ...protocolFileSpanFromSubstring({ + ...ts.projectSystem.protocolFileSpanFromSubstring({ file: userTs, text: "export function fnUser() { a.fnA(); b.fnB(); a.instanceA; }" }), name: "fnUser", matchKind: "prefix", isCaseSensitive: true, - kind: ScriptElementKind.functionElement, + kind: ts.ScriptElementKind.functionElement, kindModifiers: "export", }, ]); @@ -322,39 +320,39 @@ namespace ts.projectSystem { it("navigateToAll -- when neither file nor project is specified", () => { const session = makeSampleProjects(/*addUserTsConfig*/ true, /*keepAllFiles*/ true); - const response = executeSessionRequest(session, CommandNames.Navto, { file: undefined, searchValue: "fn" }); - assert.deepEqual(response, [ + const response = ts.projectSystem.executeSessionRequest(session, ts.projectSystem.CommandNames.Navto, { file: undefined, searchValue: "fn" }); + assert.deepEqual(response, [ { - ...protocolFileSpanFromSubstring({ + ...ts.projectSystem.protocolFileSpanFromSubstring({ file: bTs, text: "export function fnB() {}" }), name: "fnB", matchKind: "prefix", isCaseSensitive: true, - kind: ScriptElementKind.functionElement, + kind: ts.ScriptElementKind.functionElement, kindModifiers: "export", }, { - ...protocolFileSpanFromSubstring({ + ...ts.projectSystem.protocolFileSpanFromSubstring({ file: aTs, text: "export function fnA() {}" }), name: "fnA", matchKind: "prefix", isCaseSensitive: true, - kind: ScriptElementKind.functionElement, + kind: ts.ScriptElementKind.functionElement, kindModifiers: "export", }, { - ...protocolFileSpanFromSubstring({ + ...ts.projectSystem.protocolFileSpanFromSubstring({ file: userTs, text: "export function fnUser() { a.fnA(); b.fnB(); a.instanceA; }" }), name: "fnUser", matchKind: "prefix", isCaseSensitive: true, - kind: ScriptElementKind.functionElement, + kind: ts.ScriptElementKind.functionElement, kindModifiers: "export", } ]); @@ -362,23 +360,23 @@ namespace ts.projectSystem { it("navigateToAll -- when file is not specified but project is", () => { const session = makeSampleProjects(/*addUserTsConfig*/ true, /*keepAllFiles*/ true); - const response = executeSessionRequest(session, CommandNames.Navto, { projectFileName: bTsconfig.path, file: undefined, searchValue: "fn" }); - assert.deepEqual(response, [ + const response = ts.projectSystem.executeSessionRequest(session, ts.projectSystem.CommandNames.Navto, { projectFileName: bTsconfig.path, file: undefined, searchValue: "fn" }); + assert.deepEqual(response, [ { - ...protocolFileSpanFromSubstring({ + ...ts.projectSystem.protocolFileSpanFromSubstring({ file: bTs, text: "export function fnB() {}" }), name: "fnB", matchKind: "prefix", isCaseSensitive: true, - kind: ScriptElementKind.functionElement, + kind: ts.ScriptElementKind.functionElement, kindModifiers: "export", } ]); }); - const referenceATs = (aTs: File, isDefinition: true | undefined): protocol.ReferencesResponseItem => makeReferenceItem({ + const referenceATs = (aTs: ts.projectSystem.File, isDefinition: true | undefined): ts.projectSystem.protocol.ReferencesResponseItem => ts.projectSystem.makeReferenceItem({ file: aTs, isDefinition, isWriteAccess: true, @@ -386,8 +384,8 @@ namespace ts.projectSystem { contextText: "export function fnA() {}", lineText: "export function fnA() {}" }); - const referencesUserTs = (userTs: File, isDefinition: false | undefined): readonly protocol.ReferencesResponseItem[] => [ - makeReferenceItem({ + const referencesUserTs = (userTs: ts.projectSystem.File, isDefinition: false | undefined): readonly ts.projectSystem.protocol.ReferencesResponseItem[] => [ + ts.projectSystem.makeReferenceItem({ file: userTs, isDefinition, text: "fnA", @@ -398,11 +396,11 @@ namespace ts.projectSystem { it("findAllReferences", () => { const session = makeSampleProjects(); - const response = executeSessionRequest(session, protocol.CommandTypes.References, protocolFileLocationFromSubstring(userTs, "fnA()")); - assert.deepEqual(response, { - refs: [...referencesUserTs(userTs, /*isDefinition*/ undefined), referenceATs(aTs, /*isDefinition*/ true)], // Presently inconsistent across projects + const response = ts.projectSystem.executeSessionRequest(session, ts.projectSystem.protocol.CommandTypes.References, ts.projectSystem.protocolFileLocationFromSubstring(userTs, "fnA()")); + assert.deepEqual(response, { + refs: [...referencesUserTs(userTs, /*isDefinition*/ undefined), referenceATs(aTs, /*isDefinition*/ true)], symbolName: "fnA", - symbolStartOffset: protocolLocationFromSubstring(userTs.content, "fnA()").offset, + symbolStartOffset: ts.projectSystem.protocolLocationFromSubstring(userTs.content, "fnA()").offset, symbolDisplayString: "function fnA(): void", }); @@ -411,26 +409,29 @@ namespace ts.projectSystem { it("findAllReferences -- starting at definition", () => { const session = makeSampleProjects(); - openFilesForSession([aTs], session); // If it's not opened, the reference isn't found. - const response = executeSessionRequest(session, protocol.CommandTypes.References, protocolFileLocationFromSubstring(aTs, "fnA")); - assert.deepEqual(response, { + ts.projectSystem.openFilesForSession([aTs], session); // If it's not opened, the reference isn't found. + const response = ts.projectSystem.executeSessionRequest(session, ts.projectSystem.protocol.CommandTypes.References, ts.projectSystem.protocolFileLocationFromSubstring(aTs, "fnA")); + assert.deepEqual(response, { refs: [referenceATs(aTs, /*isDefinition*/ true), ...referencesUserTs(userTs, /*isDefinition*/ false)], symbolName: "fnA", - symbolStartOffset: protocolLocationFromSubstring(aTs.content, "fnA").offset, + symbolStartOffset: ts.projectSystem.protocolLocationFromSubstring(aTs.content, "fnA").offset, symbolDisplayString: "function fnA(): void", }); verifyATsConfigWhenOpened(session); }); - interface ReferencesFullRequest extends protocol.FileLocationRequest { readonly command: protocol.CommandTypes.ReferencesFull; } - interface ReferencesFullResponse extends protocol.Response { readonly body: readonly ReferencedSymbol[]; } + interface ReferencesFullRequest extends ts.projectSystem.protocol.FileLocationRequest { + readonly command: ts.projectSystem.protocol.CommandTypes.ReferencesFull; + } + interface ReferencesFullResponse extends ts.projectSystem.protocol.Response { + readonly body: readonly ts.ReferencedSymbol[]; + } it("findAllReferencesFull", () => { const session = makeSampleProjects(); - const responseFull = executeSessionRequest(session, protocol.CommandTypes.ReferencesFull, protocolFileLocationFromSubstring(userTs, "fnA()")); - - assert.deepEqual(responseFull, [ + const responseFull = ts.projectSystem.executeSessionRequest(session, ts.projectSystem.protocol.CommandTypes.ReferencesFull, ts.projectSystem.protocolFileLocationFromSubstring(userTs, "fnA()")); + assert.deepEqual(responseFull, [ { definition: { ...documentSpanFromSubstring({ @@ -438,19 +439,19 @@ namespace ts.projectSystem { text: "fnA", contextText: "export function fnA() {}" }), - kind: ScriptElementKind.functionElement, + kind: ts.ScriptElementKind.functionElement, name: "function fnA(): void", - containerKind: ScriptElementKind.unknown, + containerKind: ts.ScriptElementKind.unknown, containerName: "", displayParts: [ - keywordPart(SyntaxKind.FunctionKeyword), - spacePart(), - displayPart("fnA", SymbolDisplayPartKind.functionName), - punctuationPart(SyntaxKind.OpenParenToken), - punctuationPart(SyntaxKind.CloseParenToken), - punctuationPart(SyntaxKind.ColonToken), - spacePart(), - keywordPart(SyntaxKind.VoidKeyword), + ts.keywordPart(ts.SyntaxKind.FunctionKeyword), + ts.spacePart(), + ts.displayPart("fnA", ts.SymbolDisplayPartKind.functionName), + ts.punctuationPart(ts.SyntaxKind.OpenParenToken), + ts.punctuationPart(ts.SyntaxKind.CloseParenToken), + ts.punctuationPart(ts.SyntaxKind.ColonToken), + ts.spacePart(), + ts.keywordPart(ts.SyntaxKind.VoidKeyword), ], }, references: [ @@ -463,27 +464,25 @@ namespace ts.projectSystem { }); it("findAllReferencesFull definition is in mapped file", () => { - const aTs: File = { path: "/a/a.ts", content: `function f() {}` }; - const aTsconfig: File = { + const aTs: ts.projectSystem.File = { path: "/a/a.ts", content: `function f() {}` }; + const aTsconfig: ts.projectSystem.File = { path: "/a/tsconfig.json", content: JSON.stringify({ compilerOptions: { declaration: true, declarationMap: true, outFile: "../bin/a.js" } }), }; - const bTs: File = { path: "/b/b.ts", content: `f();` }; - const bTsconfig: File = { path: "/b/tsconfig.json", content: JSON.stringify({ references: [{ path: "../a" }] }) }; - const aDts: File = { path: "/bin/a.d.ts", content: `declare function f(): void;\n//# sourceMappingURL=a.d.ts.map` }; - const aDtsMap: File = { + const bTs: ts.projectSystem.File = { path: "/b/b.ts", content: `f();` }; + const bTsconfig: ts.projectSystem.File = { path: "/b/tsconfig.json", content: JSON.stringify({ references: [{ path: "../a" }] }) }; + const aDts: ts.projectSystem.File = { path: "/bin/a.d.ts", content: `declare function f(): void;\n//# sourceMappingURL=a.d.ts.map` }; + const aDtsMap: ts.projectSystem.File = { path: "/bin/a.d.ts.map", content: JSON.stringify({ version: 3, file: "a.d.ts", sourceRoot: "", sources: ["../a/a.ts"], names: [], mappings: "AAAA,iBAAS,CAAC,SAAK" }), }; - const session = createSession(createServerHost([aTs, aTsconfig, bTs, bTsconfig, aDts, aDtsMap])); + const session = ts.projectSystem.createSession(ts.projectSystem.createServerHost([aTs, aTsconfig, bTs, bTsconfig, aDts, aDtsMap])); checkDeclarationFiles(aTs, session, [aDtsMap, aDts]); - openFilesForSession([bTs], session); - checkNumberOfProjects(session.getProjectService(), { configuredProjects: 2 }); // configured project of b is alive since a references b - - const responseFull = executeSessionRequest(session, protocol.CommandTypes.ReferencesFull, protocolFileLocationFromSubstring(bTs, "f()")); - - assert.deepEqual(responseFull, [ + ts.projectSystem.openFilesForSession([bTs], session); + ts.projectSystem.checkNumberOfProjects(session.getProjectService(), { configuredProjects: 2 }); // configured project of b is alive since a references b + const responseFull = ts.projectSystem.executeSessionRequest(session, ts.projectSystem.protocol.CommandTypes.ReferencesFull, ts.projectSystem.protocolFileLocationFromSubstring(bTs, "f()")); + assert.deepEqual(responseFull, [ { definition: { ...documentSpanFromSubstring({ @@ -492,19 +491,19 @@ namespace ts.projectSystem { options: { index: 1 }, contextText: "function f() {}" }), - containerKind: ScriptElementKind.unknown, + containerKind: ts.ScriptElementKind.unknown, containerName: "", displayParts: [ - keywordPart(SyntaxKind.FunctionKeyword), - spacePart(), - displayPart("f", SymbolDisplayPartKind.functionName), - punctuationPart(SyntaxKind.OpenParenToken), - punctuationPart(SyntaxKind.CloseParenToken), - punctuationPart(SyntaxKind.ColonToken), - spacePart(), - keywordPart(SyntaxKind.VoidKeyword), + ts.keywordPart(ts.SyntaxKind.FunctionKeyword), + ts.spacePart(), + ts.displayPart("f", ts.SymbolDisplayPartKind.functionName), + ts.punctuationPart(ts.SyntaxKind.OpenParenToken), + ts.punctuationPart(ts.SyntaxKind.CloseParenToken), + ts.punctuationPart(ts.SyntaxKind.ColonToken), + ts.spacePart(), + ts.keywordPart(ts.SyntaxKind.VoidKeyword), ], - kind: ScriptElementKind.functionElement, + kind: ts.ScriptElementKind.functionElement, name: "function f(): void", }, references: [ @@ -529,43 +528,43 @@ namespace ts.projectSystem { it("findAllReferences -- target does not exist", () => { const session = makeSampleProjects(); - const response = executeSessionRequest(session, protocol.CommandTypes.References, protocolFileLocationFromSubstring(userTs, "fnB()")); - assert.deepEqual(response, { + const response = ts.projectSystem.executeSessionRequest(session, ts.projectSystem.protocol.CommandTypes.References, ts.projectSystem.protocolFileLocationFromSubstring(userTs, "fnB()")); + assert.deepEqual(response, { refs: [ - makeReferenceItem({ + ts.projectSystem.makeReferenceItem({ file: bDts, isWriteAccess: true, text: "fnB", contextText: "export declare function fnB(): void;", lineText: "export declare function fnB(): void;" }), - makeReferenceItem({ + ts.projectSystem.makeReferenceItem({ file: userTs, text: "fnB", lineText: "export function fnUser() { a.fnA(); b.fnB(); a.instanceA; }" }), ], symbolName: "fnB", - symbolStartOffset: protocolLocationFromSubstring(userTs.content, "fnB()").offset, + symbolStartOffset: ts.projectSystem.protocolLocationFromSubstring(userTs.content, "fnB()").offset, symbolDisplayString: "function fnB(): void", }); verifySingleInferredProject(session); }); - const renameATs = (aTs: File): protocol.SpanGroup => ({ + const renameATs = (aTs: ts.projectSystem.File): ts.projectSystem.protocol.SpanGroup => ({ file: aTs.path, locs: [ - protocolRenameSpanFromSubstring({ + ts.projectSystem.protocolRenameSpanFromSubstring({ fileText: aTs.content, text: "fnA", contextText: "export function fnA() {}" }) ], }); - const renameUserTs = (userTs: File): protocol.SpanGroup => ({ + const renameUserTs = (userTs: ts.projectSystem.File): ts.projectSystem.protocol.SpanGroup => ({ file: userTs.path, locs: [ - protocolRenameSpanFromSubstring({ + ts.projectSystem.protocolRenameSpanFromSubstring({ fileText: userTs.content, text: "fnA" }) @@ -574,16 +573,16 @@ namespace ts.projectSystem { it("renameLocations", () => { const session = makeSampleProjects(); - const response = executeSessionRequest(session, protocol.CommandTypes.Rename, protocolFileLocationFromSubstring(userTs, "fnA()")); - assert.deepEqual(response, { + const response = ts.projectSystem.executeSessionRequest(session, ts.projectSystem.protocol.CommandTypes.Rename, ts.projectSystem.protocolFileLocationFromSubstring(userTs, "fnA()")); + assert.deepEqual(response, { info: { canRename: true, displayName: "fnA", fileToRename: undefined, - fullDisplayName: '"/a/bin/a".fnA', // Ideally this would use the original source's path instead of the declaration file's path. - kind: ScriptElementKind.functionElement, - kindModifiers: [ScriptElementKindModifier.exportedModifier, ScriptElementKindModifier.ambientModifier].join(","), - triggerSpan: protocolTextSpanFromSubstring(userTs.content, "fnA"), + fullDisplayName: '"/a/bin/a".fnA', + kind: ts.ScriptElementKind.functionElement, + kindModifiers: [ts.ScriptElementKindModifier.exportedModifier, ts.ScriptElementKindModifier.ambientModifier].join(","), + triggerSpan: ts.projectSystem.protocolTextSpanFromSubstring(userTs.content, "fnA"), }, locs: [renameUserTs(userTs), renameATs(aTs)], }); @@ -592,17 +591,17 @@ namespace ts.projectSystem { it("renameLocations -- starting at definition", () => { const session = makeSampleProjects(); - openFilesForSession([aTs], session); // If it's not opened, the reference isn't found. - const response = executeSessionRequest(session, protocol.CommandTypes.Rename, protocolFileLocationFromSubstring(aTs, "fnA")); - assert.deepEqual(response, { + ts.projectSystem.openFilesForSession([aTs], session); // If it's not opened, the reference isn't found. + const response = ts.projectSystem.executeSessionRequest(session, ts.projectSystem.protocol.CommandTypes.Rename, ts.projectSystem.protocolFileLocationFromSubstring(aTs, "fnA")); + assert.deepEqual(response, { info: { canRename: true, displayName: "fnA", fileToRename: undefined, fullDisplayName: '"/a/a".fnA', - kind: ScriptElementKind.functionElement, - kindModifiers: ScriptElementKindModifier.exportedModifier, - triggerSpan: protocolTextSpanFromSubstring(aTs.content, "fnA"), + kind: ts.ScriptElementKind.functionElement, + kindModifiers: ts.ScriptElementKindModifier.exportedModifier, + triggerSpan: ts.projectSystem.protocolTextSpanFromSubstring(aTs.content, "fnA"), }, locs: [renameATs(aTs), renameUserTs(userTs)], }); @@ -611,8 +610,8 @@ namespace ts.projectSystem { it("renameLocationsFull", () => { const session = makeSampleProjects(); - const response = executeSessionRequest(session, protocol.CommandTypes.RenameLocationsFull, protocolFileLocationFromSubstring(userTs, "fnA()")); - assert.deepEqual(response, [ + const response = ts.projectSystem.executeSessionRequest(session, ts.projectSystem.protocol.CommandTypes.RenameLocationsFull, ts.projectSystem.protocolFileLocationFromSubstring(userTs, "fnA()")); + assert.deepEqual(response, [ renameLocation({ file: userTs, text: "fnA" }), renameLocation({ file: aTs, text: "fnA", contextText: "export function fnA() {}" }), ]); @@ -621,22 +620,22 @@ namespace ts.projectSystem { it("renameLocations -- target does not exist", () => { const session = makeSampleProjects(); - const response = executeSessionRequest(session, protocol.CommandTypes.Rename, protocolFileLocationFromSubstring(userTs, "fnB()")); - assert.deepEqual(response, { + const response = ts.projectSystem.executeSessionRequest(session, ts.projectSystem.protocol.CommandTypes.Rename, ts.projectSystem.protocolFileLocationFromSubstring(userTs, "fnB()")); + assert.deepEqual(response, { info: { canRename: true, displayName: "fnB", fileToRename: undefined, fullDisplayName: '"/b/bin/b".fnB', - kind: ScriptElementKind.functionElement, - kindModifiers: [ScriptElementKindModifier.exportedModifier, ScriptElementKindModifier.ambientModifier].join(","), - triggerSpan: protocolTextSpanFromSubstring(userTs.content, "fnB"), + kind: ts.ScriptElementKind.functionElement, + kindModifiers: [ts.ScriptElementKindModifier.exportedModifier, ts.ScriptElementKindModifier.ambientModifier].join(","), + triggerSpan: ts.projectSystem.protocolTextSpanFromSubstring(userTs.content, "fnB"), }, locs: [ { file: bDts.path, locs: [ - protocolRenameSpanFromSubstring({ + ts.projectSystem.protocolRenameSpanFromSubstring({ fileText: bDts.content, text: "fnB", contextText: "export declare function fnB(): void;" @@ -646,7 +645,7 @@ namespace ts.projectSystem { { file: userTs.path, locs: [ - protocolRenameSpanFromSubstring({ + ts.projectSystem.protocolRenameSpanFromSubstring({ fileText: userTs.content, text: "fnB" }) @@ -659,15 +658,15 @@ namespace ts.projectSystem { it("getEditsForFileRename", () => { const session = makeSampleProjects(); - const response = executeSessionRequest(session, protocol.CommandTypes.GetEditsForFileRename, { + const response = ts.projectSystem.executeSessionRequest(session, ts.projectSystem.protocol.CommandTypes.GetEditsForFileRename, { oldFilePath: aTs.path, newFilePath: "/a/aNew.ts", }); - assert.deepEqual(response, [ + assert.deepEqual(response, [ { fileName: userTs.path, textChanges: [ - { ...protocolTextSpanFromSubstring(userTs.content, "../a/bin/a"), newText: "../a/bin/aNew" }, + { ...ts.projectSystem.protocolTextSpanFromSubstring(userTs.content, "../a/bin/a"), newText: "../a/bin/aNew" }, ], }, ]); @@ -675,8 +674,8 @@ namespace ts.projectSystem { }); it("getEditsForFileRename when referencing project doesnt include file and its renamed", () => { - const aTs: File = { path: "/a/src/a.ts", content: "" }; - const aTsconfig: File = { + const aTs: ts.projectSystem.File = { path: "/a/src/a.ts", content: "" }; + const aTsconfig: ts.projectSystem.File = { path: "/a/tsconfig.json", content: JSON.stringify({ compilerOptions: { @@ -687,8 +686,8 @@ namespace ts.projectSystem { } }), }; - const bTs: File = { path: "/b/src/b.ts", content: "" }; - const bTsconfig: File = { + const bTs: ts.projectSystem.File = { path: "/b/src/b.ts", content: "" }; + const bTsconfig: ts.projectSystem.File = { path: "/b/tsconfig.json", content: JSON.stringify({ compilerOptions: { @@ -700,70 +699,55 @@ namespace ts.projectSystem { }), }; - const host = createServerHost([aTs, aTsconfig, bTs, bTsconfig]); - const session = createSession(host); - openFilesForSession([aTs, bTs], session); - const response = executeSessionRequest(session, CommandNames.GetEditsForFileRename, { + const host = ts.projectSystem.createServerHost([aTs, aTsconfig, bTs, bTsconfig]); + const session = ts.projectSystem.createSession(host); + ts.projectSystem.openFilesForSession([aTs, bTs], session); + const response = ts.projectSystem.executeSessionRequest(session, ts.projectSystem.CommandNames.GetEditsForFileRename, { oldFilePath: aTs.path, newFilePath: "/a/src/a1.ts", }); - assert.deepEqual(response, []); // Should not change anything + assert.deepEqual(response, []); // Should not change anything }); it("does not jump to source if inlined sources", () => { - const aDtsInlinedSources: RawSourceMap = { + const aDtsInlinedSources: ts.RawSourceMap = { ...aDtsMapContent, sourcesContent: [aTs.content] }; - const aDtsMapInlinedSources: File = { + const aDtsMapInlinedSources: ts.projectSystem.File = { path: aDtsMap.path, content: JSON.stringify(aDtsInlinedSources) }; - const host = createServerHost([aTs, aDtsMapInlinedSources, aDts, bTs, bDtsMap, bDts, userTs, dummyFile]); - const session = createSession(host); - - openFilesForSession([userTs], session); + const host = ts.projectSystem.createServerHost([aTs, aDtsMapInlinedSources, aDts, bTs, bDtsMap, bDts, userTs, dummyFile]); + const session = ts.projectSystem.createSession(host); + ts.projectSystem.openFilesForSession([userTs], session); const service = session.getProjectService(); // If config file then userConfig project and bConfig project since it is referenced - checkNumberOfProjects(service, { inferredProjects: 1 }); + ts.projectSystem.checkNumberOfProjects(service, { inferredProjects: 1 }); // Inlined so does not jump to aTs - assert.deepEqual( - executeSessionRequest( - session, - protocol.CommandTypes.DefinitionAndBoundSpan, - protocolFileLocationFromSubstring(userTs, "fnA()") - ), - { - textSpan: protocolTextSpanFromSubstring(userTs.content, "fnA"), + assert.deepEqual(ts.projectSystem.executeSessionRequest(session, ts.projectSystem.protocol.CommandTypes.DefinitionAndBoundSpan, ts.projectSystem.protocolFileLocationFromSubstring(userTs, "fnA()")), { + textSpan: ts.projectSystem.protocolTextSpanFromSubstring(userTs.content, "fnA"), definitions: [ - protocolFileSpanWithContextFromSubstring({ + ts.projectSystem.protocolFileSpanWithContextFromSubstring({ file: aDts, text: "fnA", contextText: "export declare function fnA(): void;" }) ], - } - ); + }); // Not inlined, jumps to bTs - assert.deepEqual( - executeSessionRequest( - session, - protocol.CommandTypes.DefinitionAndBoundSpan, - protocolFileLocationFromSubstring(userTs, "fnB()") - ), - { - textSpan: protocolTextSpanFromSubstring(userTs.content, "fnB"), + assert.deepEqual(ts.projectSystem.executeSessionRequest(session, ts.projectSystem.protocol.CommandTypes.DefinitionAndBoundSpan, ts.projectSystem.protocolFileLocationFromSubstring(userTs, "fnB()")), { + textSpan: ts.projectSystem.protocolTextSpanFromSubstring(userTs.content, "fnB"), definitions: [ - protocolFileSpanWithContextFromSubstring({ + ts.projectSystem.protocolFileSpanWithContextFromSubstring({ file: bTs, text: "fnB", contextText: "export function fnB() {}" }) ], - } - ); + }); verifySingleInferredProject(session); }); diff --git a/src/testRunner/unittests/tsserver/documentRegistry.ts b/src/testRunner/unittests/tsserver/documentRegistry.ts index 8c29af51a27a0..e364f75af674b 100644 --- a/src/testRunner/unittests/tsserver/documentRegistry.ts +++ b/src/testRunner/unittests/tsserver/documentRegistry.ts @@ -1,28 +1,28 @@ namespace ts.projectSystem { describe("unittests:: tsserver:: document registry in project service", () => { const importModuleContent = `import {a} from "./module1"`; - const file: File = { - path: `${tscWatch.projectRoot}/index.ts`, + const file: ts.projectSystem.File = { + path: `${ts.tscWatch.projectRoot}/index.ts`, content: importModuleContent }; - const moduleFile: File = { - path: `${tscWatch.projectRoot}/module1.d.ts`, + const moduleFile: ts.projectSystem.File = { + path: `${ts.tscWatch.projectRoot}/module1.d.ts`, content: "export const a: number;" }; - const configFile: File = { - path: `${tscWatch.projectRoot}/tsconfig.json`, + const configFile: ts.projectSystem.File = { + path: `${ts.tscWatch.projectRoot}/tsconfig.json`, content: JSON.stringify({ files: ["index.ts"] }) }; - function getProject(service: TestProjectService) { + function getProject(service: ts.projectSystem.TestProjectService) { return service.configuredProjects.get(configFile.path)!; } - function checkProject(service: TestProjectService, moduleIsOrphan: boolean) { + function checkProject(service: ts.projectSystem.TestProjectService, moduleIsOrphan: boolean) { // Update the project const project = getProject(service); project.getLanguageService(); - checkProjectActualFiles(project, [file.path, libFile.path, configFile.path, ...(moduleIsOrphan ? [] : [moduleFile.path])]); + ts.projectSystem.checkProjectActualFiles(project, [file.path, ts.projectSystem.libFile.path, configFile.path, ...(moduleIsOrphan ? [] : [moduleFile.path])]); const moduleInfo = service.getScriptInfo(moduleFile.path)!; assert.isDefined(moduleInfo); assert.equal(moduleInfo.isOrphan(), moduleIsOrphan); @@ -31,22 +31,22 @@ namespace ts.projectSystem { } function createServiceAndHost() { - const host = createServerHost([file, moduleFile, libFile, configFile]); - const service = createProjectService(host); + const host = ts.projectSystem.createServerHost([file, moduleFile, ts.projectSystem.libFile, configFile]); + const service = ts.projectSystem.createProjectService(host); service.openClientFile(file.path); checkProject(service, /*moduleIsOrphan*/ false); return { host, service }; } - function changeFileToNotImportModule(service: TestProjectService) { + function changeFileToNotImportModule(service: ts.projectSystem.TestProjectService) { const info = service.getScriptInfo(file.path)!; - service.applyChangesToFile(info, singleIterator({ span: { start: 0, length: importModuleContent.length }, newText: "" })); + service.applyChangesToFile(info, ts.singleIterator({ span: { start: 0, length: importModuleContent.length }, newText: "" })); checkProject(service, /*moduleIsOrphan*/ true); } - function changeFileToImportModule(service: TestProjectService) { + function changeFileToImportModule(service: ts.projectSystem.TestProjectService) { const info = service.getScriptInfo(file.path)!; - service.applyChangesToFile(info, singleIterator({ span: { start: 0, length: 0 }, newText: importModuleContent })); + service.applyChangesToFile(info, ts.singleIterator({ span: { start: 0, length: 0 }, newText: importModuleContent })); checkProject(service, /*moduleIsOrphan*/ false); } diff --git a/src/testRunner/unittests/tsserver/duplicatePackages.ts b/src/testRunner/unittests/tsserver/duplicatePackages.ts index 366ca5ea379c4..d46689c13a385 100644 --- a/src/testRunner/unittests/tsserver/duplicatePackages.ts +++ b/src/testRunner/unittests/tsserver/duplicatePackages.ts @@ -4,34 +4,33 @@ namespace ts.projectSystem { it("works with import fixes", () => { const packageContent = "export const foo: number;"; const packageJsonContent = JSON.stringify({ name: "foo", version: "1.2.3" }); - const aFooIndex: File = { path: "/a/node_modules/foo/index.d.ts", content: packageContent }; - const aFooPackage: File = { path: "/a/node_modules/foo/package.json", content: packageJsonContent }; - const bFooIndex: File = { path: "/b/node_modules/foo/index.d.ts", content: packageContent }; - const bFooPackage: File = { path: "/b/node_modules/foo/package.json", content: packageJsonContent }; + const aFooIndex: ts.projectSystem.File = { path: "/a/node_modules/foo/index.d.ts", content: packageContent }; + const aFooPackage: ts.projectSystem.File = { path: "/a/node_modules/foo/package.json", content: packageJsonContent }; + const bFooIndex: ts.projectSystem.File = { path: "/b/node_modules/foo/index.d.ts", content: packageContent }; + const bFooPackage: ts.projectSystem.File = { path: "/b/node_modules/foo/package.json", content: packageJsonContent }; const userContent = 'import("foo");\nfoo'; - const aUser: File = { path: "/a/user.ts", content: userContent }; - const bUser: File = { path: "/b/user.ts", content: userContent }; - const tsconfig: File = { + const aUser: ts.projectSystem.File = { path: "/a/user.ts", content: userContent }; + const bUser: ts.projectSystem.File = { path: "/b/user.ts", content: userContent }; + const tsconfig: ts.projectSystem.File = { path: "/tsconfig.json", content: "{}", }; - const host = createServerHost([aFooIndex, aFooPackage, bFooIndex, bFooPackage, aUser, bUser, tsconfig]); - const session = createSession(host); - - openFilesForSession([aUser, bUser], session); + const host = ts.projectSystem.createServerHost([aFooIndex, aFooPackage, bFooIndex, bFooPackage, aUser, bUser, tsconfig]); + const session = ts.projectSystem.createSession(host); + ts.projectSystem.openFilesForSession([aUser, bUser], session); for (const user of [aUser, bUser]) { - const response = executeSessionRequest(session, protocol.CommandTypes.GetCodeFixes, { + const response = ts.projectSystem.executeSessionRequest(session, ts.projectSystem.protocol.CommandTypes.GetCodeFixes, { file: user.path, startLine: 2, startOffset: 1, endLine: 2, endOffset: 4, - errorCodes: [Diagnostics.Cannot_find_name_0.code], + errorCodes: [ts.Diagnostics.Cannot_find_name_0.code], }); - assert.deepEqual(response, [ + assert.deepEqual(response, [ { description: `Add import from "foo"`, fixName: "import", diff --git a/src/testRunner/unittests/tsserver/dynamicFiles.ts b/src/testRunner/unittests/tsserver/dynamicFiles.ts index 554c4c8c67477..9ebed4b2683eb 100644 --- a/src/testRunner/unittests/tsserver/dynamicFiles.ts +++ b/src/testRunner/unittests/tsserver/dynamicFiles.ts @@ -1,52 +1,50 @@ namespace ts.projectSystem { - export function verifyDynamic(service: server.ProjectService, path: string) { - const info = Debug.checkDefined(service.filenameToScriptInfo.get(path), `Expected ${path} in :: ${JSON.stringify(arrayFrom(service.filenameToScriptInfo.entries(), ([key, f]) => ({ key, fileName: f.fileName, path: f.path })))}`); + export function verifyDynamic(service: ts.server.ProjectService, path: string) { + const info = ts.Debug.checkDefined(service.filenameToScriptInfo.get(path), `Expected ${path} in :: ${JSON.stringify(ts.arrayFrom(service.filenameToScriptInfo.entries(), ([key, f]) => ({ key, fileName: f.fileName, path: f.path })))}`); assert.isTrue(info.isDynamic); } function verifyPathRecognizedAsDynamic(path: string) { - const file: File = { + const file: ts.projectSystem.File = { path, content: `/// /// var x = 10;` }; - const host = createServerHost([libFile]); - const projectService = createProjectService(host); + const host = ts.projectSystem.createServerHost([ts.projectSystem.libFile]); + const projectService = ts.projectSystem.createProjectService(host); projectService.openClientFile(file.path, file.content); verifyDynamic(projectService, projectService.toPath(file.path)); projectService.checkNumberOfProjects({ inferredProjects: 1 }); const project = projectService.inferredProjects[0]; - checkProjectRootFiles(project, [file.path]); - checkProjectActualFiles(project, [file.path, libFile.path]); + ts.projectSystem.checkProjectRootFiles(project, [file.path]); + ts.projectSystem.checkProjectActualFiles(project, [file.path, ts.projectSystem.libFile.path]); } describe("unittests:: tsserver:: dynamicFiles:: Untitled files", () => { const untitledFile = "untitled:^Untitled-1"; it("Can convert positions to locations", () => { - const aTs: File = { path: "/proj/a.ts", content: "" }; - const tsconfig: File = { path: "/proj/tsconfig.json", content: "{}" }; - const session = createSession(createServerHost([aTs, tsconfig]), { useInferredProjectPerProjectRoot: true }); - - openFilesForSession([aTs], session); - - executeSessionRequestNoResponse(session, protocol.CommandTypes.Open, { + const aTs: ts.projectSystem.File = { path: "/proj/a.ts", content: "" }; + const tsconfig: ts.projectSystem.File = { path: "/proj/tsconfig.json", content: "{}" }; + const session = ts.projectSystem.createSession(ts.projectSystem.createServerHost([aTs, tsconfig]), { useInferredProjectPerProjectRoot: true }); + ts.projectSystem.openFilesForSession([aTs], session); + ts.projectSystem.executeSessionRequestNoResponse(session, ts.projectSystem.protocol.CommandTypes.Open, { file: untitledFile, fileContent: `/// \nlet foo = 1;\nfooo/**/`, scriptKindName: "TS", projectRootPath: "/proj", }); verifyDynamic(session.getProjectService(), `/proj/untitled:^untitled-1`); - const response = executeSessionRequest(session, protocol.CommandTypes.GetCodeFixes, { + const response = ts.projectSystem.executeSessionRequest(session, ts.projectSystem.protocol.CommandTypes.GetCodeFixes, { file: untitledFile, startLine: 3, startOffset: 1, endLine: 3, endOffset: 5, - errorCodes: [Diagnostics.Cannot_find_name_0_Did_you_mean_1.code], + errorCodes: [ts.Diagnostics.Cannot_find_name_0_Did_you_mean_1.code], }); - assert.deepEqual(response, [ + assert.deepEqual(response, [ { description: "Change spelling to 'foo'", fixName: "spelling", @@ -66,68 +64,66 @@ var x = 10;` }); it("opening untitled files", () => { - const config: File = { - path: `${tscWatch.projectRoot}/tsconfig.json`, + const config: ts.projectSystem.File = { + path: `${ts.tscWatch.projectRoot}/tsconfig.json`, content: "{}" }; - const host = createServerHost([config, libFile], { useCaseSensitiveFileNames: true, currentDirectory: tscWatch.projectRoot }); - const service = createProjectService(host); - service.openClientFile(untitledFile, "const x = 10;", /*scriptKind*/ undefined, tscWatch.projectRoot); - checkNumberOfProjects(service, { inferredProjects: 1 }); - checkProjectActualFiles(service.inferredProjects[0], [untitledFile, libFile.path]); - verifyDynamic(service, `${tscWatch.projectRoot}/${untitledFile}`); - - const untitled: File = { - path: `${tscWatch.projectRoot}/Untitled-1.ts`, + const host = ts.projectSystem.createServerHost([config, ts.projectSystem.libFile], { useCaseSensitiveFileNames: true, currentDirectory: ts.tscWatch.projectRoot }); + const service = ts.projectSystem.createProjectService(host); + service.openClientFile(untitledFile, "const x = 10;", /*scriptKind*/ undefined, ts.tscWatch.projectRoot); + ts.projectSystem.checkNumberOfProjects(service, { inferredProjects: 1 }); + ts.projectSystem.checkProjectActualFiles(service.inferredProjects[0], [untitledFile, ts.projectSystem.libFile.path]); + verifyDynamic(service, `${ts.tscWatch.projectRoot}/${untitledFile}`); + const untitled: ts.projectSystem.File = { + path: `${ts.tscWatch.projectRoot}/Untitled-1.ts`, content: "const x = 10;" }; host.writeFile(untitled.path, untitled.content); host.checkTimeoutQueueLength(0); - service.openClientFile(untitled.path, untitled.content, /*scriptKind*/ undefined, tscWatch.projectRoot); - checkNumberOfProjects(service, { configuredProjects: 1, inferredProjects: 1 }); - checkProjectActualFiles(service.configuredProjects.get(config.path)!, [untitled.path, libFile.path, config.path]); - checkProjectActualFiles(service.inferredProjects[0], [untitledFile, libFile.path]); + service.openClientFile(untitled.path, untitled.content, /*scriptKind*/ undefined, ts.tscWatch.projectRoot); + ts.projectSystem.checkNumberOfProjects(service, { configuredProjects: 1, inferredProjects: 1 }); + ts.projectSystem.checkProjectActualFiles(service.configuredProjects.get(config.path)!, [untitled.path, ts.projectSystem.libFile.path, config.path]); + ts.projectSystem.checkProjectActualFiles(service.inferredProjects[0], [untitledFile, ts.projectSystem.libFile.path]); service.closeClientFile(untitledFile); - checkProjectActualFiles(service.configuredProjects.get(config.path)!, [untitled.path, libFile.path, config.path]); - checkProjectActualFiles(service.inferredProjects[0], [untitledFile, libFile.path]); - - service.openClientFile(untitledFile, "const x = 10;", /*scriptKind*/ undefined, tscWatch.projectRoot); - verifyDynamic(service, `${tscWatch.projectRoot}/${untitledFile}`); - checkProjectActualFiles(service.configuredProjects.get(config.path)!, [untitled.path, libFile.path, config.path]); - checkProjectActualFiles(service.inferredProjects[0], [untitledFile, libFile.path]); + ts.projectSystem.checkProjectActualFiles(service.configuredProjects.get(config.path)!, [untitled.path, ts.projectSystem.libFile.path, config.path]); + ts.projectSystem.checkProjectActualFiles(service.inferredProjects[0], [untitledFile, ts.projectSystem.libFile.path]); + service.openClientFile(untitledFile, "const x = 10;", /*scriptKind*/ undefined, ts.tscWatch.projectRoot); + verifyDynamic(service, `${ts.tscWatch.projectRoot}/${untitledFile}`); + ts.projectSystem.checkProjectActualFiles(service.configuredProjects.get(config.path)!, [untitled.path, ts.projectSystem.libFile.path, config.path]); + ts.projectSystem.checkProjectActualFiles(service.inferredProjects[0], [untitledFile, ts.projectSystem.libFile.path]); }); it("opening and closing untitled files when projectRootPath is different from currentDirectory", () => { - const config: File = { - path: `${tscWatch.projectRoot}/tsconfig.json`, + const config: ts.projectSystem.File = { + path: `${ts.tscWatch.projectRoot}/tsconfig.json`, content: "{}" }; - const file: File = { - path: `${tscWatch.projectRoot}/file.ts`, + const file: ts.projectSystem.File = { + path: `${ts.tscWatch.projectRoot}/file.ts`, content: "const y = 10" }; - const host = createServerHost([config, file, libFile], { useCaseSensitiveFileNames: true }); - const service = createProjectService(host, { useInferredProjectPerProjectRoot: true }); - service.openClientFile(untitledFile, "const x = 10;", /*scriptKind*/ undefined, tscWatch.projectRoot); - checkNumberOfProjects(service, { inferredProjects: 1 }); - checkProjectActualFiles(service.inferredProjects[0], [untitledFile, libFile.path]); - verifyDynamic(service, `${tscWatch.projectRoot}/${untitledFile}`); + const host = ts.projectSystem.createServerHost([config, file, ts.projectSystem.libFile], { useCaseSensitiveFileNames: true }); + const service = ts.projectSystem.createProjectService(host, { useInferredProjectPerProjectRoot: true }); + service.openClientFile(untitledFile, "const x = 10;", /*scriptKind*/ undefined, ts.tscWatch.projectRoot); + ts.projectSystem.checkNumberOfProjects(service, { inferredProjects: 1 }); + ts.projectSystem.checkProjectActualFiles(service.inferredProjects[0], [untitledFile, ts.projectSystem.libFile.path]); + verifyDynamic(service, `${ts.tscWatch.projectRoot}/${untitledFile}`); // Close untitled file service.closeClientFile(untitledFile); // Open file from configured project which should collect inferredProject service.openClientFile(file.path); - checkNumberOfProjects(service, { configuredProjects: 1 }); + ts.projectSystem.checkNumberOfProjects(service, { configuredProjects: 1 }); }); it("when changing scriptKind of the untitled files", () => { - const host = createServerHost([libFile], { useCaseSensitiveFileNames: true }); - const service = createProjectService(host, { useInferredProjectPerProjectRoot: true }); - service.openClientFile(untitledFile, "const x = 10;", ScriptKind.TS, tscWatch.projectRoot); - checkNumberOfProjects(service, { inferredProjects: 1 }); - checkProjectActualFiles(service.inferredProjects[0], [untitledFile, libFile.path]); + const host = ts.projectSystem.createServerHost([ts.projectSystem.libFile], { useCaseSensitiveFileNames: true }); + const service = ts.projectSystem.createProjectService(host, { useInferredProjectPerProjectRoot: true }); + service.openClientFile(untitledFile, "const x = 10;", ts.ScriptKind.TS, ts.tscWatch.projectRoot); + ts.projectSystem.checkNumberOfProjects(service, { inferredProjects: 1 }); + ts.projectSystem.checkProjectActualFiles(service.inferredProjects[0], [untitledFile, ts.projectSystem.libFile.path]); const program = service.inferredProjects[0].getCurrentProgram()!; const sourceFile = program.getSourceFile(untitledFile)!; @@ -135,9 +131,9 @@ var x = 10;` service.closeClientFile(untitledFile); // Open untitled file with different mode - service.openClientFile(untitledFile, "const x = 10;", ScriptKind.TSX, tscWatch.projectRoot); - checkNumberOfProjects(service, { inferredProjects: 1 }); - checkProjectActualFiles(service.inferredProjects[0], [untitledFile, libFile.path]); + service.openClientFile(untitledFile, "const x = 10;", ts.ScriptKind.TSX, ts.tscWatch.projectRoot); + ts.projectSystem.checkNumberOfProjects(service, { inferredProjects: 1 }); + ts.projectSystem.checkProjectActualFiles(service.inferredProjects[0], [untitledFile, ts.projectSystem.libFile.path]); const newProgram = service.inferredProjects[0].getCurrentProgram()!; const newSourceFile = newProgram.getSourceFile(untitledFile)!; assert.notStrictEqual(newProgram, program); @@ -147,14 +143,14 @@ var x = 10;` describe("unittests:: tsserver:: dynamicFiles:: ", () => { it("dynamic file without external project", () => { - const file: File = { + const file: ts.projectSystem.File = { path: "^walkThroughSnippet:/Users/UserName/projects/someProject/out/someFile#1.js", content: "var x = 10;" }; - const host = createServerHost([libFile], { useCaseSensitiveFileNames: true }); - const projectService = createProjectService(host); + const host = ts.projectSystem.createServerHost([ts.projectSystem.libFile], { useCaseSensitiveFileNames: true }); + const projectService = ts.projectSystem.createProjectService(host); projectService.setCompilerOptionsForInferredProjects({ - module: ModuleKind.CommonJS, + module: ts.ModuleKind.CommonJS, allowJs: true, allowSyntheticDefaultImports: true, allowNonTsExtensions: true @@ -163,14 +159,14 @@ var x = 10;` projectService.checkNumberOfProjects({ inferredProjects: 1 }); const project = projectService.inferredProjects[0]; - checkProjectRootFiles(project, [file.path]); - checkProjectActualFiles(project, [file.path, libFile.path]); + ts.projectSystem.checkProjectRootFiles(project, [file.path]); + ts.projectSystem.checkProjectActualFiles(project, [file.path, ts.projectSystem.libFile.path]); verifyDynamic(projectService, `/${file.path}`); - assert.strictEqual(projectService.ensureDefaultProjectForFile(server.toNormalizedPath(file.path)), project); + assert.strictEqual(projectService.ensureDefaultProjectForFile(ts.server.toNormalizedPath(file.path)), project); const indexOfX = file.content.indexOf("x"); assert.deepEqual(project.getLanguageService(/*ensureSynchronized*/ true).getQuickInfoAtPosition(file.path, indexOfX), { - kind: ScriptElementKind.variableElement, + kind: ts.ScriptElementKind.variableElement, kindModifiers: "", textSpan: { start: indexOfX, length: 1 }, displayParts: [ @@ -191,30 +187,29 @@ var x = 10;` }); describe("dynamic file with projectRootPath", () => { - const file: File = { + const file: ts.projectSystem.File = { path: "^walkThroughSnippet:/Users/UserName/projects/someProject/out/someFile#1.js", content: "var x = 10;" }; - const configFile: File = { - path: `${tscWatch.projectRoot}/tsconfig.json`, + const configFile: ts.projectSystem.File = { + path: `${ts.tscWatch.projectRoot}/tsconfig.json`, content: "{}" }; - const configProjectFile: File = { - path: `${tscWatch.projectRoot}/a.ts`, + const configProjectFile: ts.projectSystem.File = { + path: `${ts.tscWatch.projectRoot}/a.ts`, content: "let y = 10;" }; it("with useInferredProjectPerProjectRoot", () => { - const host = createServerHost([libFile, configFile, configProjectFile], { useCaseSensitiveFileNames: true }); - const session = createSession(host, { useInferredProjectPerProjectRoot: true }); - openFilesForSession([{ file: file.path, projectRootPath: tscWatch.projectRoot }], session); + const host = ts.projectSystem.createServerHost([ts.projectSystem.libFile, configFile, configProjectFile], { useCaseSensitiveFileNames: true }); + const session = ts.projectSystem.createSession(host, { useInferredProjectPerProjectRoot: true }); + ts.projectSystem.openFilesForSession([{ file: file.path, projectRootPath: ts.tscWatch.projectRoot }], session); const projectService = session.getProjectService(); - checkNumberOfProjects(projectService, { inferredProjects: 1 }); - checkProjectActualFiles(projectService.inferredProjects[0], [file.path, libFile.path]); - verifyDynamic(projectService, `${tscWatch.projectRoot}/${file.path}`); - - session.executeCommandSeq({ - command: protocol.CommandTypes.GetOutliningSpans, + ts.projectSystem.checkNumberOfProjects(projectService, { inferredProjects: 1 }); + ts.projectSystem.checkProjectActualFiles(projectService.inferredProjects[0], [file.path, ts.projectSystem.libFile.path]); + verifyDynamic(projectService, `${ts.tscWatch.projectRoot}/${file.path}`); + session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.GetOutliningSpans, arguments: { file: file.path } @@ -223,27 +218,24 @@ var x = 10;` // Without project root const file2Path = file.path.replace("#1", "#2"); projectService.openClientFile(file2Path, file.content); - checkNumberOfProjects(projectService, { inferredProjects: 2 }); - checkProjectActualFiles(projectService.inferredProjects[0], [file.path, libFile.path]); - checkProjectActualFiles(projectService.inferredProjects[1], [file2Path, libFile.path]); + ts.projectSystem.checkNumberOfProjects(projectService, { inferredProjects: 2 }); + ts.projectSystem.checkProjectActualFiles(projectService.inferredProjects[0], [file.path, ts.projectSystem.libFile.path]); + ts.projectSystem.checkProjectActualFiles(projectService.inferredProjects[1], [file2Path, ts.projectSystem.libFile.path]); }); it("fails when useInferredProjectPerProjectRoot is false", () => { - const host = createServerHost([libFile, configFile, configProjectFile], { useCaseSensitiveFileNames: true }); - const projectService = createProjectService(host); + const host = ts.projectSystem.createServerHost([ts.projectSystem.libFile, configFile, configProjectFile], { useCaseSensitiveFileNames: true }); + const projectService = ts.projectSystem.createProjectService(host); try { - projectService.openClientFile(file.path, file.content, /*scriptKind*/ undefined, tscWatch.projectRoot); + projectService.openClientFile(file.path, file.content, /*scriptKind*/ undefined, ts.tscWatch.projectRoot); } catch (e) { - assert.strictEqual( - e.message.replace(/\r?\n/, "\n"), - `Debug Failure. False expression.\nVerbose Debug Information: {"fileName":"^walkThroughSnippet:/Users/UserName/projects/someProject/out/someFile#1.js","currentDirectory":"/user/username/projects/myproject","hostCurrentDirectory":"/","openKeys":[]}\nDynamic files must always be opened with service's current directory or service should support inferred project per projectRootPath.` - ); + assert.strictEqual(e.message.replace(/\r?\n/, "\n"), `Debug Failure. False expression.\nVerbose Debug Information: {"fileName":"^walkThroughSnippet:/Users/UserName/projects/someProject/out/someFile#1.js","currentDirectory":"/user/username/projects/myproject","hostCurrentDirectory":"/","openKeys":[]}\nDynamic files must always be opened with service's current directory or service should support inferred project per projectRootPath.`); } const file2Path = file.path.replace("#1", "#2"); projectService.openClientFile(file2Path, file.content); projectService.checkNumberOfProjects({ inferredProjects: 1 }); - checkProjectActualFiles(projectService.inferredProjects[0], [file2Path, libFile.path]); + ts.projectSystem.checkProjectActualFiles(projectService.inferredProjects[0], [file2Path, ts.projectSystem.libFile.path]); }); }); diff --git a/src/testRunner/unittests/tsserver/events/largeFileReferenced.ts b/src/testRunner/unittests/tsserver/events/largeFileReferenced.ts index 1807f104ee2d6..22b4abdb98442 100644 --- a/src/testRunner/unittests/tsserver/events/largeFileReferenced.ts +++ b/src/testRunner/unittests/tsserver/events/largeFileReferenced.ts @@ -5,61 +5,61 @@ namespace ts.projectSystem { return `src/large.${useLargeTsFile ? "ts" : "js"}`; } - function createSessionWithEventHandler(files: File[], useLargeTsFile: boolean) { - const largeFile: File = { - path: `${tscWatch.projectRoot}/${getLargeFile(useLargeTsFile)}`, + function createSessionWithEventHandler(files: ts.projectSystem.File[], useLargeTsFile: boolean) { + const largeFile: ts.projectSystem.File = { + path: `${ts.tscWatch.projectRoot}/${getLargeFile(useLargeTsFile)}`, content: "export var x = 10;", - fileSize: server.maxFileSize + 1 + fileSize: ts.server.maxFileSize + 1 }; files.push(largeFile); - const host = createServerHost(files); - const { session, events: largeFileReferencedEvents } = createSessionWithEventTracking(host, server.LargeFileReferencedEvent); + const host = ts.projectSystem.createServerHost(files); + const { session, events: largeFileReferencedEvents } = ts.projectSystem.createSessionWithEventTracking(host, ts.server.LargeFileReferencedEvent); return { session, verifyLargeFile }; - function verifyLargeFile(project: server.Project) { - checkProjectActualFiles(project, files.map(f => f.path)); + function verifyLargeFile(project: ts.server.Project) { + ts.projectSystem.checkProjectActualFiles(project, files.map(f => f.path)); // large file for non ts file should be empty and for ts file should have content const service = session.getProjectService(); const info = service.getScriptInfo(largeFile.path)!; assert.equal(info.cacheSourceFile!.sourceFile.text, useLargeTsFile ? largeFile.content : ""); - assert.deepEqual(largeFileReferencedEvents, useLargeTsFile ? emptyArray : [{ - eventName: server.LargeFileReferencedEvent, - data: { file: largeFile.path, fileSize: largeFile.fileSize, maxFileSize: server.maxFileSize } + assert.deepEqual(largeFileReferencedEvents, useLargeTsFile ? ts.emptyArray : [{ + eventName: ts.server.LargeFileReferencedEvent, + data: { file: largeFile.path, fileSize: largeFile.fileSize, maxFileSize: ts.server.maxFileSize } }]); } } function verifyLargeFile(useLargeTsFile: boolean) { it("when large file is included by tsconfig", () => { - const file: File = { - path: `${tscWatch.projectRoot}/src/file.ts`, + const file: ts.projectSystem.File = { + path: `${ts.tscWatch.projectRoot}/src/file.ts`, content: "export var y = 10;" }; - const tsconfig: File = { - path: `${tscWatch.projectRoot}/tsconfig.json`, + const tsconfig: ts.projectSystem.File = { + path: `${ts.tscWatch.projectRoot}/tsconfig.json`, content: JSON.stringify({ files: ["src/file.ts", getLargeFile(useLargeTsFile)], compilerOptions: { target: 1, allowJs: true } }) }; - const files = [file, libFile, tsconfig]; + const files = [file, ts.projectSystem.libFile, tsconfig]; const { session, verifyLargeFile } = createSessionWithEventHandler(files, useLargeTsFile); const service = session.getProjectService(); - openFilesForSession([file], session); - checkNumberOfProjects(service, { configuredProjects: 1 }); + ts.projectSystem.openFilesForSession([file], session); + ts.projectSystem.checkNumberOfProjects(service, { configuredProjects: 1 }); verifyLargeFile(service.configuredProjects.get(tsconfig.path)!); }); it("when large file is included by module resolution", () => { - const file: File = { - path: `${tscWatch.projectRoot}/src/file.ts`, + const file: ts.projectSystem.File = { + path: `${ts.tscWatch.projectRoot}/src/file.ts`, content: `export var y = 10;import {x} from "./large"` }; - const files = [file, libFile]; + const files = [file, ts.projectSystem.libFile]; const { session, verifyLargeFile } = createSessionWithEventHandler(files, useLargeTsFile); const service = session.getProjectService(); - openFilesForSession([file], session); - checkNumberOfProjects(service, { inferredProjects: 1 }); + ts.projectSystem.openFilesForSession([file], session); + ts.projectSystem.checkNumberOfProjects(service, { inferredProjects: 1 }); verifyLargeFile(service.inferredProjects[0]); }); } diff --git a/src/testRunner/unittests/tsserver/events/projectLanguageServiceState.ts b/src/testRunner/unittests/tsserver/events/projectLanguageServiceState.ts index 08d66db76a16c..7dbbd35d67f39 100644 --- a/src/testRunner/unittests/tsserver/events/projectLanguageServiceState.ts +++ b/src/testRunner/unittests/tsserver/events/projectLanguageServiceState.ts @@ -17,21 +17,19 @@ namespace ts.projectSystem { path: config.path, content: JSON.stringify({ exclude: ["largefile.js"] }) }; - const host = createServerHost([f1, f2, config]); + const host = ts.projectSystem.createServerHost([f1, f2, config]); const originalGetFileSize = host.getFileSize; - host.getFileSize = (filePath: string) => - filePath === f2.path ? server.maxProgramSizeForNonTsFiles + 1 : originalGetFileSize.call(host, filePath); - - const { session, events } = createSessionWithEventTracking(host, server.ProjectLanguageServiceStateEvent); + host.getFileSize = (filePath: string) => filePath === f2.path ? ts.server.maxProgramSizeForNonTsFiles + 1 : originalGetFileSize.call(host, filePath); + const { session, events } = ts.projectSystem.createSessionWithEventTracking(host, ts.server.ProjectLanguageServiceStateEvent); session.executeCommand({ seq: 0, type: "request", command: "open", arguments: { file: f1.path } - } as protocol.OpenRequest); + } as ts.projectSystem.protocol.OpenRequest); const projectService = session.getProjectService(); - checkNumberOfProjects(projectService, { configuredProjects: 1 }); - const project = configuredProjectAt(projectService, 0); + ts.projectSystem.checkNumberOfProjects(projectService, { configuredProjects: 1 }); + const project = ts.projectSystem.configuredProjectAt(projectService, 0); assert.isFalse(project.languageServiceEnabled, "Language service enabled"); assert.equal(events.length, 1, "should receive event"); assert.equal(events[0].data.project, project, "project name"); @@ -40,7 +38,7 @@ namespace ts.projectSystem { host.writeFile(configWithExclude.path, configWithExclude.content); host.checkTimeoutQueueLengthAndRun(2); - checkNumberOfProjects(projectService, { configuredProjects: 1 }); + ts.projectSystem.checkNumberOfProjects(projectService, { configuredProjects: 1 }); assert.isTrue(project.languageServiceEnabled, "Language service enabled"); assert.equal(events.length, 2, "should receive event"); assert.equal(events[1].data.project, project, "project"); @@ -49,31 +47,31 @@ namespace ts.projectSystem { }); it("Large file size is determined correctly", () => { - const f1: File = { + const f1: ts.projectSystem.File = { path: "/a/app.js", content: "let x = 1;" }; - const f2: File = { + const f2: ts.projectSystem.File = { path: "/a/largefile.js", content: "", - fileSize: server.maxProgramSizeForNonTsFiles + 1 + fileSize: ts.server.maxProgramSizeForNonTsFiles + 1 }; - const f3: File = { + const f3: ts.projectSystem.File = { path: "/a/extremlylarge.d.ts", content: "", - fileSize: server.maxProgramSizeForNonTsFiles + 100 + fileSize: ts.server.maxProgramSizeForNonTsFiles + 100 }; const config = { path: "/a/jsconfig.json", content: "{}" }; - const host = createServerHost([f1, f2, f3, libFile, config]); - const service = createProjectService(host, { logger: createLoggerWithInMemoryLogs() }); + const host = ts.projectSystem.createServerHost([f1, f2, f3, ts.projectSystem.libFile, config]); + const service = ts.projectSystem.createProjectService(host, { logger: ts.projectSystem.createLoggerWithInMemoryLogs() }); service.openClientFile(f1.path); const project = service.configuredProjects.get(config.path)!; service.logger.logs.push(`languageServiceEnabled: ${project.languageServiceEnabled}`); service.logger.logs.push(`lastFileExceededProgramSize: ${project.lastFileExceededProgramSize}`); - baselineTsserverLogs("projectLanguageServiceStateEvent", "large file size is determined correctly", service); + ts.projectSystem.baselineTsserverLogs("projectLanguageServiceStateEvent", "large file size is determined correctly", service); }); }); } diff --git a/src/testRunner/unittests/tsserver/events/projectLoading.ts b/src/testRunner/unittests/tsserver/events/projectLoading.ts index 150f7c1c724e3..8eb6cb815d3ad 100644 --- a/src/testRunner/unittests/tsserver/events/projectLoading.ts +++ b/src/testRunner/unittests/tsserver/events/projectLoading.ts @@ -1,25 +1,27 @@ namespace ts.projectSystem { describe("unittests:: tsserver:: events:: ProjectLoadingStart and ProjectLoadingFinish events", () => { - const aTs: File = { - path: `${tscWatch.projects}/a/a.ts`, + const aTs: ts.projectSystem.File = { + path: `${ts.tscWatch.projects}/a/a.ts`, content: "export class A { }" }; - const configA: File = { - path: `${tscWatch.projects}/a/tsconfig.json`, + const configA: ts.projectSystem.File = { + path: `${ts.tscWatch.projects}/a/tsconfig.json`, content: "{}" }; - const bTsPath = `${tscWatch.projects}/b/b.ts`; - const configBPath = `${tscWatch.projects}/b/tsconfig.json`; - const files = [libFile, aTs, configA]; - - function verifyProjectLoadingStartAndFinish(createSession: (host: TestServerHost) => { - session: TestSession; + const bTsPath = `${ts.tscWatch.projects}/b/b.ts`; + const configBPath = `${ts.tscWatch.projects}/b/tsconfig.json`; + const files = [ts.projectSystem.libFile, aTs, configA]; + function verifyProjectLoadingStartAndFinish(createSession: (host: ts.projectSystem.TestServerHost) => { + session: ts.projectSystem.TestSession; getNumberOfEvents: () => number; clearEvents: () => void; - verifyProjectLoadEvents: (expected: [server.ProjectLoadingStartEvent, server.ProjectLoadingFinishEvent]) => void; + verifyProjectLoadEvents: (expected: [ + ts.server.ProjectLoadingStartEvent, + ts.server.ProjectLoadingFinishEvent + ]) => void; }) { - function createSessionToVerifyEvent(files: readonly File[]) { - const host = createServerHost(files); + function createSessionToVerifyEvent(files: readonly ts.projectSystem.File[]) { + const host = ts.projectSystem.createServerHost(files); const originalReadFile = host.readFile; const { session, getNumberOfEvents, clearEvents, verifyProjectLoadEvents } = createSession(host); host.readFile = file => { @@ -31,17 +33,17 @@ namespace ts.projectSystem { const service = session.getProjectService(); return { host, session, verifyEvent, verifyEventWithOpenTs, service, getNumberOfEvents }; - function verifyEvent(project: server.Project, reason: string) { + function verifyEvent(project: ts.server.Project, reason: string) { verifyProjectLoadEvents([ - { eventName: server.ProjectLoadingStartEvent, data: { project, reason } }, - { eventName: server.ProjectLoadingFinishEvent, data: { project } } + { eventName: ts.server.ProjectLoadingStartEvent, data: { project, reason } }, + { eventName: ts.server.ProjectLoadingFinishEvent, data: { project } } ]); clearEvents(); } - function verifyEventWithOpenTs(file: File, configPath: string, configuredProjects: number) { - openFilesForSession([file], session); - checkNumberOfProjects(service, { configuredProjects }); + function verifyEventWithOpenTs(file: ts.projectSystem.File, configPath: string, configuredProjects: number) { + ts.projectSystem.openFilesForSession([file], session); + ts.projectSystem.checkNumberOfProjects(service, { configuredProjects }); const project = service.configuredProjects.get(configPath)!; assert.isDefined(project); verifyEvent(project, `Creating possible configured project for ${file.path} to open`); @@ -49,11 +51,11 @@ namespace ts.projectSystem { } it("when project is created by open file", () => { - const bTs: File = { + const bTs: ts.projectSystem.File = { path: bTsPath, content: "export class B {}" }; - const configB: File = { + const configB: ts.projectSystem.File = { path: configBPath, content: "{}" }; @@ -73,11 +75,11 @@ namespace ts.projectSystem { }); it("when change is detected in an extended config file", () => { - const bTs: File = { + const bTs: ts.projectSystem.File = { path: bTsPath, content: "export class B {}" }; - const configB: File = { + const configB: ts.projectSystem.File = { path: configBPath, content: JSON.stringify({ extends: "../a/tsconfig.json", @@ -102,22 +104,22 @@ namespace ts.projectSystem { }); function verify(disableSourceOfProjectReferenceRedirect?: true) { - const aDTs: File = { - path: `${tscWatch.projects}/a/a.d.ts`, + const aDTs: ts.projectSystem.File = { + path: `${ts.tscWatch.projects}/a/a.d.ts`, content: `export declare class A { } //# sourceMappingURL=a.d.ts.map ` }; - const aDTsMap: File = { - path: `${tscWatch.projects}/a/a.d.ts.map`, + const aDTsMap: ts.projectSystem.File = { + path: `${ts.tscWatch.projects}/a/a.d.ts.map`, content: `{"version":3,"file":"a.d.ts","sourceRoot":"","sources":["./a.ts"],"names":[],"mappings":"AAAA,qBAAa,CAAC;CAAI"}` }; - const bTs: File = { + const bTs: ts.projectSystem.File = { path: bTsPath, content: `import {A} from "../a/a"; new A();` }; - const configB: File = { + const configB: ts.projectSystem.File = { path: configBPath, content: JSON.stringify({ ...(disableSourceOfProjectReferenceRedirect && { @@ -132,38 +134,35 @@ namespace ts.projectSystem { const { service, session, verifyEventWithOpenTs, verifyEvent } = createSessionToVerifyEvent(files.concat(aDTs, aDTsMap, bTs, configB)); verifyEventWithOpenTs(bTs, configB.path, 1); - session.executeCommandSeq({ - command: protocol.CommandTypes.References, + session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.References, arguments: { file: bTs.path, - ...protocolLocationFromSubstring(bTs.content, "A()") + ...ts.projectSystem.protocolLocationFromSubstring(bTs.content, "A()") } }); - checkNumberOfProjects(service, { configuredProjects: 2 }); + ts.projectSystem.checkNumberOfProjects(service, { configuredProjects: 2 }); const project = service.configuredProjects.get(configA.path)!; assert.isDefined(project); - verifyEvent( - project, - disableSourceOfProjectReferenceRedirect ? + verifyEvent(project, disableSourceOfProjectReferenceRedirect ? `Creating project for original file: ${aTs.path} for location: ${aDTs.path}` : - `Creating project for original file: ${aTs.path}` - ); + `Creating project for original file: ${aTs.path}`); } }); describe("with external projects and config files ", () => { - const projectFileName = `${tscWatch.projects}/a/project.csproj`; + const projectFileName = `${ts.tscWatch.projects}/a/project.csproj`; function createSession(lazyConfiguredProjectsFromExternalProject: boolean) { const { session, service, verifyEvent: verifyEventWorker, getNumberOfEvents } = createSessionToVerifyEvent(files); service.setHostConfiguration({ preferences: { lazyConfiguredProjectsFromExternalProject } }); service.openExternalProject({ projectFileName, - rootFiles: toExternalFiles([aTs.path, configA.path]), + rootFiles: ts.projectSystem.toExternalFiles([aTs.path, configA.path]), options: {} - } as protocol.ExternalProject); - checkNumberOfProjects(service, { configuredProjects: 1 }); + } as ts.projectSystem.protocol.ExternalProject); + ts.projectSystem.checkNumberOfProjects(service, { configuredProjects: 1 }); return { session, service, verifyEvent, getNumberOfEvents }; function verifyEvent() { @@ -182,7 +181,7 @@ namespace ts.projectSystem { const { verifyEvent, getNumberOfEvents, session } = createSession(/*lazyConfiguredProjectsFromExternalProject*/ true); assert.equal(getNumberOfEvents(), 0); - openFilesForSession([aTs], session); + ts.projectSystem.openFilesForSession([aTs], session); verifyEvent(); }); @@ -198,7 +197,7 @@ namespace ts.projectSystem { describe("when using event handler", () => { verifyProjectLoadingStartAndFinish(host => { - const { session, events } = createSessionWithEventTracking(host, server.ProjectLoadingStartEvent, server.ProjectLoadingFinishEvent); + const { session, events } = ts.projectSystem.createSessionWithEventTracking(host, ts.server.ProjectLoadingStartEvent, ts.server.ProjectLoadingFinishEvent); return { session, getNumberOfEvents: () => events.length, @@ -210,7 +209,7 @@ namespace ts.projectSystem { describe("when using default event handler", () => { verifyProjectLoadingStartAndFinish(host => { - const { session, getEvents, clearEvents } = createSessionWithDefaultEventHandler(host, [server.ProjectLoadingStartEvent, server.ProjectLoadingFinishEvent]); + const { session, getEvents, clearEvents } = ts.projectSystem.createSessionWithDefaultEventHandler(host, [ts.server.ProjectLoadingStartEvent, ts.server.ProjectLoadingFinishEvent]); return { session, getNumberOfEvents: () => getEvents().length, @@ -218,7 +217,10 @@ namespace ts.projectSystem { verifyProjectLoadEvents }; - function verifyProjectLoadEvents(expected: [server.ProjectLoadingStartEvent, server.ProjectLoadingFinishEvent]) { + function verifyProjectLoadEvents(expected: [ + ts.server.ProjectLoadingStartEvent, + ts.server.ProjectLoadingFinishEvent + ]) { const actual = getEvents().map(e => ({ eventName: e.event, data: e.body })); const mappedExpected = expected.map(e => { const { project, ...rest } = e.data; diff --git a/src/testRunner/unittests/tsserver/events/projectUpdatedInBackground.ts b/src/testRunner/unittests/tsserver/events/projectUpdatedInBackground.ts index 34e8f7d8e0ad8..29922ea15f7f0 100644 --- a/src/testRunner/unittests/tsserver/events/projectUpdatedInBackground.ts +++ b/src/testRunner/unittests/tsserver/events/projectUpdatedInBackground.ts @@ -2,59 +2,59 @@ namespace ts.projectSystem { describe("unittests:: tsserver:: events:: ProjectsUpdatedInBackground", () => { function verifyFiles(caption: string, actual: readonly string[], expected: readonly string[]) { assert.equal(actual.length, expected.length, `Incorrect number of ${caption}. Actual: ${actual} Expected: ${expected}`); - const seen = new Map(); - forEach(actual, f => { + const seen = new ts.Map(); + ts.forEach(actual, f => { assert.isFalse(seen.has(f), `${caption}: Found duplicate ${f}. Actual: ${actual} Expected: ${expected}`); seen.set(f, true); - assert.isTrue(contains(expected, f), `${caption}: Expected not to contain ${f}. Actual: ${actual} Expected: ${expected}`); + assert.isTrue(ts.contains(expected, f), `${caption}: Expected not to contain ${f}. Actual: ${actual} Expected: ${expected}`); }); } - function createVerifyInitialOpen(session: TestSession, verifyProjectsUpdatedInBackgroundEventHandler: (events: server.ProjectsUpdatedInBackgroundEvent[]) => void) { - return (file: File) => { + function createVerifyInitialOpen(session: ts.projectSystem.TestSession, verifyProjectsUpdatedInBackgroundEventHandler: (events: ts.server.ProjectsUpdatedInBackgroundEvent[]) => void) { + return (file: ts.projectSystem.File) => { session.executeCommandSeq({ - command: server.CommandNames.Open, + command: ts.server.CommandNames.Open, arguments: { file: file.path } - } as protocol.OpenRequest); + } as ts.projectSystem.protocol.OpenRequest); verifyProjectsUpdatedInBackgroundEventHandler([]); }; } interface ProjectsUpdatedInBackgroundEventVerifier { - session: TestSession; - verifyProjectsUpdatedInBackgroundEventHandler(events: server.ProjectsUpdatedInBackgroundEvent[]): void; - verifyInitialOpen(file: File): void; + session: ts.projectSystem.TestSession; + verifyProjectsUpdatedInBackgroundEventHandler(events: ts.server.ProjectsUpdatedInBackgroundEvent[]): void; + verifyInitialOpen(file: ts.projectSystem.File): void; } - function verifyProjectsUpdatedInBackgroundEvent(createSession: (host: TestServerHost) => ProjectsUpdatedInBackgroundEventVerifier) { + function verifyProjectsUpdatedInBackgroundEvent(createSession: (host: ts.projectSystem.TestServerHost) => ProjectsUpdatedInBackgroundEventVerifier) { it("when adding new file", () => { - const commonFile1: File = { + const commonFile1: ts.projectSystem.File = { path: "/a/b/file1.ts", content: "export var x = 10;" }; - const commonFile2: File = { + const commonFile2: ts.projectSystem.File = { path: "/a/b/file2.ts", content: "export var y = 10;" }; - const commonFile3: File = { + const commonFile3: ts.projectSystem.File = { path: "/a/b/file3.ts", content: "export var z = 10;" }; - const configFile: File = { + const configFile: ts.projectSystem.File = { path: "/a/b/tsconfig.json", content: `{}` }; const openFiles = [commonFile1.path]; - const host = createServerHost([commonFile1, libFile, configFile]); + const host = ts.projectSystem.createServerHost([commonFile1, ts.projectSystem.libFile, configFile]); const { verifyProjectsUpdatedInBackgroundEventHandler, verifyInitialOpen } = createSession(host); verifyInitialOpen(commonFile1); host.writeFile(commonFile2.path, commonFile2.content); host.runQueuedTimeoutCallbacks(); verifyProjectsUpdatedInBackgroundEventHandler([{ - eventName: server.ProjectsUpdatedInBackgroundEvent, + eventName: ts.server.ProjectsUpdatedInBackgroundEvent, data: { openFiles } @@ -63,7 +63,7 @@ namespace ts.projectSystem { host.writeFile(commonFile3.path, commonFile3.content); host.runQueuedTimeoutCallbacks(); verifyProjectsUpdatedInBackgroundEventHandler([{ - eventName: server.ProjectsUpdatedInBackgroundEvent, + eventName: ts.server.ProjectsUpdatedInBackgroundEvent, data: { openFiles } @@ -71,26 +71,26 @@ namespace ts.projectSystem { }); describe("with --out or --outFile setting", () => { - function verifyEventWithOutSettings(compilerOptions: CompilerOptions = {}) { - const config: File = { + function verifyEventWithOutSettings(compilerOptions: ts.CompilerOptions = {}) { + const config: ts.projectSystem.File = { path: "/a/tsconfig.json", content: JSON.stringify({ compilerOptions }) }; - const f1: File = { + const f1: ts.projectSystem.File = { path: "/a/a.ts", content: "export let x = 1" }; - const f2: File = { + const f2: ts.projectSystem.File = { path: "/a/b.ts", content: "export let y = 1" }; const openFiles = [f1.path]; - const files = [f1, config, libFile]; - const host = createServerHost(files); + const files = [f1, config, ts.projectSystem.libFile]; + const host = ts.projectSystem.createServerHost(files); const { verifyInitialOpen, verifyProjectsUpdatedInBackgroundEventHandler } = createSession(host); verifyInitialOpen(f1); @@ -98,7 +98,7 @@ namespace ts.projectSystem { host.runQueuedTimeoutCallbacks(); verifyProjectsUpdatedInBackgroundEventHandler([{ - eventName: server.ProjectsUpdatedInBackgroundEvent, + eventName: ts.server.ProjectsUpdatedInBackgroundEvent, data: { openFiles } @@ -107,7 +107,7 @@ namespace ts.projectSystem { host.writeFile(f2.path, "export let x = 11"); host.runQueuedTimeoutCallbacks(); verifyProjectsUpdatedInBackgroundEventHandler([{ - eventName: server.ProjectsUpdatedInBackgroundEvent, + eventName: ts.server.ProjectsUpdatedInBackgroundEvent, data: { openFiles } @@ -137,32 +137,32 @@ namespace ts.projectSystem { /** custom config file options */ configObj?: any; /** Additional files and folders to add */ - getAdditionalFileOrFolder?(): File[]; + getAdditionalFileOrFolder?(): ts.projectSystem.File[]; /** initial list of files to reload in fs and first file in this list being the file to open */ firstReloadFileList?: string[]; } function getInitialState({ configObj = {}, getAdditionalFileOrFolder, firstReloadFileList }: InitialStateParams = {}) { - const moduleFile1: File = { + const moduleFile1: ts.projectSystem.File = { path: moduleFile1Path, content: "export function Foo() { };", }; - const file1Consumer1: File = { + const file1Consumer1: ts.projectSystem.File = { path: file1Consumer1Path, content: `import {Foo} from "./moduleFile1"; export var y = 10;`, }; - const file1Consumer2: File = { + const file1Consumer2: ts.projectSystem.File = { path: "/a/b/file1Consumer2.ts", content: `import {Foo} from "./moduleFile1"; let z = 10;`, }; - const moduleFile2: File = { + const moduleFile2: ts.projectSystem.File = { path: "/a/b/moduleFile2.ts", content: `export var Foo4 = 10;`, }; - const globalFile3: File = { + const globalFile3: ts.projectSystem.File = { path: "/a/b/globalFile3.ts", content: `interface GlobalFoo { age: number }` }; @@ -173,10 +173,10 @@ namespace ts.projectSystem { content: JSON.stringify(configObj || { compilerOptions: {} }) }; - const files: File[] = [file1Consumer1, moduleFile1, file1Consumer2, moduleFile2, ...additionalFiles, globalFile3, libFile, configFile]; + const files: ts.projectSystem.File[] = [file1Consumer1, moduleFile1, file1Consumer2, moduleFile2, ...additionalFiles, globalFile3, ts.projectSystem.libFile, configFile]; const filesToReload = firstReloadFileList && getFiles(firstReloadFileList) || files; - const host = createServerHost([filesToReload[0], configFile]); + const host = ts.projectSystem.createServerHost([filesToReload[0], configFile]); // Initial project creation const { session, verifyProjectsUpdatedInBackgroundEventHandler, verifyInitialOpen } = createSession(host); @@ -185,7 +185,8 @@ namespace ts.projectSystem { // Since this is first event, it will have all the files filesToReload.forEach(f => host.ensureFileOrFolder(f)); - if (!firstReloadFileList) host.runQueuedTimeoutCallbacks(); // Invalidated module resolutions to schedule project update + if (!firstReloadFileList) + host.runQueuedTimeoutCallbacks(); // Invalidated module resolutions to schedule project update verifyProjectsUpdatedInBackgroundEvent(); return { @@ -197,11 +198,11 @@ namespace ts.projectSystem { }; function getFiles(filelist: string[]) { - return map(filelist, getFile); + return ts.map(filelist, getFile); } function getFile(fileName: string) { - return find(files, file => file.path === fileName)!; + return ts.find(files, file => file.path === fileName)!; } function verifyNoProjectsUpdatedInBackgroundEvent() { @@ -212,16 +213,16 @@ namespace ts.projectSystem { function verifyProjectsUpdatedInBackgroundEvent() { host.runQueuedTimeoutCallbacks(); verifyProjectsUpdatedInBackgroundEventHandler([{ - eventName: server.ProjectsUpdatedInBackgroundEvent, + eventName: ts.server.ProjectsUpdatedInBackgroundEvent, data: { openFiles } }]); } - function updateContentOfOpenFile(file: File, newContent: string) { - session.executeCommandSeq({ - command: server.CommandNames.Change, + function updateContentOfOpenFile(file: ts.projectSystem.File, newContent: string) { + session.executeCommandSeq({ + command: ts.server.CommandNames.Change, arguments: { file: file.path, insertString: newContent, @@ -334,7 +335,7 @@ namespace ts.projectSystem { }); it("should return cascaded affected file list", () => { - const file1Consumer1Consumer1: File = { + const file1Consumer1Consumer1: ts.projectSystem.File = { path: "/a/b/file1Consumer1Consumer1.ts", content: `import {y} from "./file1Consumer1";` }; @@ -356,13 +357,13 @@ namespace ts.projectSystem { }); it("should work fine for files with circular references", () => { - const file1: File = { + const file1: ts.projectSystem.File = { path: "/a/b/file1.ts", content: ` /// export var t1 = 10;` }; - const file2: File = { + const file2: ts.projectSystem.File = { path: "/a/b/file2.ts", content: ` /// @@ -370,7 +371,7 @@ namespace ts.projectSystem { }; const { host, verifyProjectsUpdatedInBackgroundEvent } = getInitialState({ getAdditionalFileOrFolder: () => [file1, file2], - firstReloadFileList: [file1.path, libFile.path, file2.path, configFilePath] + firstReloadFileList: [file1.path, ts.projectSystem.libFile.path, file2.path, configFilePath] }); host.writeFile(file2.path, file2.content + "export var t3 = 10;"); @@ -378,7 +379,7 @@ namespace ts.projectSystem { }); it("should detect removed code file", () => { - const referenceFile1: File = { + const referenceFile1: ts.projectSystem.File = { path: "/a/b/referenceFile1.ts", content: ` /// @@ -386,7 +387,7 @@ namespace ts.projectSystem { }; const { host, verifyProjectsUpdatedInBackgroundEvent } = getInitialState({ getAdditionalFileOrFolder: () => [referenceFile1], - firstReloadFileList: [referenceFile1.path, libFile.path, moduleFile1Path, configFilePath] + firstReloadFileList: [referenceFile1.path, ts.projectSystem.libFile.path, moduleFile1Path, configFilePath] }); host.deleteFile(moduleFile1Path); @@ -394,7 +395,7 @@ namespace ts.projectSystem { }); it("should detect non-existing code file", () => { - const referenceFile1: File = { + const referenceFile1: ts.projectSystem.File = { path: "/a/b/referenceFile1.ts", content: ` /// @@ -402,7 +403,7 @@ namespace ts.projectSystem { }; const { host, moduleFile2, updateContentOfOpenFile, verifyNoProjectsUpdatedInBackgroundEvent, verifyProjectsUpdatedInBackgroundEvent } = getInitialState({ getAdditionalFileOrFolder: () => [referenceFile1], - firstReloadFileList: [referenceFile1.path, libFile.path, configFilePath] + firstReloadFileList: [referenceFile1.path, ts.projectSystem.libFile.path, configFilePath] }); updateContentOfOpenFile(referenceFile1, referenceFile1.content + "export var yy = Foo();"); @@ -417,35 +418,35 @@ namespace ts.projectSystem { describe("resolution when resolution cache size", () => { function verifyWithMaxCacheLimit(useSlashRootAsSomeNotRootFolderInUserDirectory: boolean) { const rootFolder = useSlashRootAsSomeNotRootFolderInUserDirectory ? "/user/username/rootfolder/otherfolder/" : "/"; - const file1: File = { + const file1: ts.projectSystem.File = { path: rootFolder + "a/b/project/file1.ts", content: 'import a from "file2"' }; - const file2: File = { + const file2: ts.projectSystem.File = { path: rootFolder + "a/b/node_modules/file2.d.ts", content: "export class a { }" }; - const file3: File = { + const file3: ts.projectSystem.File = { path: rootFolder + "a/b/project/file3.ts", content: "export class c { }" }; - const configFile: File = { + const configFile: ts.projectSystem.File = { path: rootFolder + "a/b/project/tsconfig.json", content: JSON.stringify({ compilerOptions: { typeRoots: [] } }) }; - const projectFiles = [file1, file3, libFile, configFile]; + const projectFiles = [file1, file3, ts.projectSystem.libFile, configFile]; const openFiles = [file1.path]; const watchedRecursiveDirectories = useSlashRootAsSomeNotRootFolderInUserDirectory ? // Folders of node_modules lookup not in changedRoot ["a/b/project", "a/b/project/node_modules", "a/b/node_modules", "a/node_modules", "node_modules"].map(v => rootFolder + v) : // Folder of tsconfig ["/a/b/project", "/a/b/project/node_modules"]; - const host = createServerHost(projectFiles); + const host = ts.projectSystem.createServerHost(projectFiles); const { session, verifyInitialOpen, verifyProjectsUpdatedInBackgroundEventHandler } = createSession(host); const projectService = session.getProjectService(); verifyInitialOpen(file1); - checkNumberOfProjects(projectService, { configuredProjects: 1 }); + ts.projectSystem.checkNumberOfProjects(projectService, { configuredProjects: 1 }); const project = projectService.configuredProjects.get(configFile.path)!; verifyProject(); @@ -456,7 +457,7 @@ namespace ts.projectSystem { // Since this is first event verifyProject(); verifyProjectsUpdatedInBackgroundEventHandler([{ - eventName: server.ProjectsUpdatedInBackgroundEvent, + eventName: ts.server.ProjectsUpdatedInBackgroundEvent, data: { openFiles } @@ -477,16 +478,16 @@ namespace ts.projectSystem { verifyProject(); verifyProjectsUpdatedInBackgroundEventHandler(useSlashRootAsSomeNotRootFolderInUserDirectory ? [{ - eventName: server.ProjectsUpdatedInBackgroundEvent, + eventName: ts.server.ProjectsUpdatedInBackgroundEvent, data: { openFiles } }] : []); function verifyProject() { - checkProjectActualFiles(project, map(projectFiles, file => file.path)); - checkWatchedDirectories(host, [], /*recursive*/ false); - checkWatchedDirectories(host, watchedRecursiveDirectories, /*recursive*/ true); + ts.projectSystem.checkProjectActualFiles(project, ts.map(projectFiles, file => file.path)); + ts.projectSystem.checkWatchedDirectories(host, [], /*recursive*/ false); + ts.projectSystem.checkWatchedDirectories(host, watchedRecursiveDirectories, /*recursive*/ true); } } @@ -503,25 +504,25 @@ namespace ts.projectSystem { describe("when event handler is set in the session", () => { verifyProjectsUpdatedInBackgroundEvent(createSessionWithProjectChangedEventHandler); - function createSessionWithProjectChangedEventHandler(host: TestServerHost): ProjectsUpdatedInBackgroundEventVerifier { - const { session, events: projectChangedEvents } = createSessionWithEventTracking(host, server.ProjectsUpdatedInBackgroundEvent); + function createSessionWithProjectChangedEventHandler(host: ts.projectSystem.TestServerHost): ProjectsUpdatedInBackgroundEventVerifier { + const { session, events: projectChangedEvents } = ts.projectSystem.createSessionWithEventTracking(host, ts.server.ProjectsUpdatedInBackgroundEvent); return { session, verifyProjectsUpdatedInBackgroundEventHandler, verifyInitialOpen: createVerifyInitialOpen(session, verifyProjectsUpdatedInBackgroundEventHandler) }; - function eventToString(event: server.ProjectsUpdatedInBackgroundEvent) { + function eventToString(event: ts.server.ProjectsUpdatedInBackgroundEvent) { return JSON.stringify(event && { eventName: event.eventName, data: event.data }); } - function eventsToString(events: readonly server.ProjectsUpdatedInBackgroundEvent[]) { - return "[" + map(events, eventToString).join(",") + "]"; + function eventsToString(events: readonly ts.server.ProjectsUpdatedInBackgroundEvent[]) { + return "[" + ts.map(events, eventToString).join(",") + "]"; } - function verifyProjectsUpdatedInBackgroundEventHandler(expectedEvents: readonly server.ProjectsUpdatedInBackgroundEvent[]) { + function verifyProjectsUpdatedInBackgroundEventHandler(expectedEvents: readonly ts.server.ProjectsUpdatedInBackgroundEvent[]) { assert.equal(projectChangedEvents.length, expectedEvents.length, `Incorrect number of events Actual: ${eventsToString(projectChangedEvents)} Expected: ${eventsToString(expectedEvents)}`); - forEach(projectChangedEvents, (actualEvent, i) => { + ts.forEach(projectChangedEvents, (actualEvent, i) => { const expectedEvent = expectedEvents[i]; assert.strictEqual(actualEvent.eventName, expectedEvent.eventName); verifyFiles("openFiles", actualEvent.data.openFiles, expectedEvent.data.openFiles); @@ -543,8 +544,8 @@ namespace ts.projectSystem { }); - function createSessionThatUsesEvents(host: TestServerHost, noGetErrOnBackgroundUpdate?: boolean): ProjectsUpdatedInBackgroundEventVerifier { - const { session, getEvents, clearEvents } = createSessionWithDefaultEventHandler(host, server.ProjectsUpdatedInBackgroundEvent, { noGetErrOnBackgroundUpdate }); + function createSessionThatUsesEvents(host: ts.projectSystem.TestServerHost, noGetErrOnBackgroundUpdate?: boolean): ProjectsUpdatedInBackgroundEventVerifier { + const { session, getEvents, clearEvents } = ts.projectSystem.createSessionWithDefaultEventHandler(host, ts.server.ProjectsUpdatedInBackgroundEvent, { noGetErrOnBackgroundUpdate }); return { session, @@ -552,15 +553,15 @@ namespace ts.projectSystem { verifyInitialOpen: createVerifyInitialOpen(session, verifyProjectsUpdatedInBackgroundEventHandler) }; - function verifyProjectsUpdatedInBackgroundEventHandler(expected: readonly server.ProjectsUpdatedInBackgroundEvent[]) { - const expectedEvents: protocol.ProjectsUpdatedInBackgroundEventBody[] = map(expected, e => { + function verifyProjectsUpdatedInBackgroundEventHandler(expected: readonly ts.server.ProjectsUpdatedInBackgroundEvent[]) { + const expectedEvents: ts.projectSystem.protocol.ProjectsUpdatedInBackgroundEventBody[] = ts.map(expected, e => { return { openFiles: e.data.openFiles }; }); const events = getEvents(); - assert.equal(events.length, expectedEvents.length, `Incorrect number of events Actual: ${map(events, e => e.body)} Expected: ${expectedEvents}`); - forEach(events, (actualEvent, i) => { + assert.equal(events.length, expectedEvents.length, `Incorrect number of events Actual: ${ts.map(events, e => e.body)} Expected: ${expectedEvents}`); + ts.forEach(events, (actualEvent, i) => { const expectedEvent = expectedEvents[i]; verifyFiles("openFiles", actualEvent.body.openFiles, expectedEvent.openFiles); }); diff --git a/src/testRunner/unittests/tsserver/exportMapCache.ts b/src/testRunner/unittests/tsserver/exportMapCache.ts index 184200c07cbe4..4a8e9c744f3bc 100644 --- a/src/testRunner/unittests/tsserver/exportMapCache.ts +++ b/src/testRunner/unittests/tsserver/exportMapCache.ts @@ -1,33 +1,33 @@ namespace ts.projectSystem { - const packageJson: File = { + const packageJson: ts.projectSystem.File = { path: "/package.json", content: `{ "dependencies": { "mobx": "*" } }` }; - const aTs: File = { + const aTs: ts.projectSystem.File = { path: "/a.ts", content: "export const foo = 0;", }; - const bTs: File = { + const bTs: ts.projectSystem.File = { path: "/b.ts", content: "foo", }; - const tsconfig: File = { + const tsconfig: ts.projectSystem.File = { path: "/tsconfig.json", content: "{}", }; - const ambientDeclaration: File = { + const ambientDeclaration: ts.projectSystem.File = { path: "/ambient.d.ts", content: "declare module 'ambient' {}" }; - const mobxPackageJson: File = { + const mobxPackageJson: ts.projectSystem.File = { path: "/node_modules/mobx/package.json", content: `{ "name": "mobx", "version": "1.0.0" }` }; - const mobxDts: File = { + const mobxDts: ts.projectSystem.File = { path: "/node_modules/mobx/index.d.ts", content: "export declare function observable(): unknown;" }; - const exportEqualsMappedType: File = { + const exportEqualsMappedType: ts.projectSystem.File = { path: "/lib/foo/constants.d.ts", content: ` type Signals = "SIGINT" | "SIGABRT"; @@ -38,7 +38,7 @@ namespace ts.projectSystem { describe("unittests:: tsserver:: exportMapCache", () => { it("caches auto-imports in the same file", () => { const { exportMapCache } = setup(); - assert.ok(exportMapCache.isUsableByFile(bTs.path as Path)); + assert.ok(exportMapCache.isUsableByFile(bTs.path as ts.Path)); assert.ok(!exportMapCache.isEmpty()); }); @@ -46,7 +46,7 @@ namespace ts.projectSystem { const { host, exportMapCache } = setup(); host.writeFile("/src/a2.ts", aTs.content); host.runQueuedTimeoutCallbacks(); - assert.ok(!exportMapCache.isUsableByFile(bTs.path as Path)); + assert.ok(!exportMapCache.isUsableByFile(bTs.path as ts.Path)); assert.ok(exportMapCache.isEmpty()); }); @@ -55,7 +55,7 @@ namespace ts.projectSystem { projectService.closeClientFile(aTs.path); host.deleteFile(aTs.path); host.runQueuedTimeoutCallbacks(); - assert.ok(!exportMapCache.isUsableByFile(bTs.path as Path)); + assert.ok(!exportMapCache.isUsableByFile(bTs.path as ts.Path)); assert.ok(exportMapCache.isEmpty()); }); @@ -64,7 +64,7 @@ namespace ts.projectSystem { host.writeFile("/package.json", `{ "name": "blah", "dependencies": { "mobx": "*" } }`); host.runQueuedTimeoutCallbacks(); project.getPackageJsonAutoImportProvider(); - assert.ok(exportMapCache.isUsableByFile(bTs.path as Path)); + assert.ok(exportMapCache.isUsableByFile(bTs.path as ts.Path)); assert.ok(!exportMapCache.isEmpty()); }); @@ -73,7 +73,7 @@ namespace ts.projectSystem { host.writeFile("/package.json", `{}`); host.runQueuedTimeoutCallbacks(); project.getPackageJsonAutoImportProvider(); - assert.ok(!exportMapCache.isUsableByFile(bTs.path as Path)); + assert.ok(!exportMapCache.isUsableByFile(bTs.path as ts.Path)); assert.ok(exportMapCache.isEmpty()); }); @@ -86,17 +86,18 @@ namespace ts.projectSystem { // accessing a transient symbol with two different checkers results in different symbol identities, since // transient symbols are recreated with every new checker. const programBefore = project.getCurrentProgram()!; - let sigintPropBefore: readonly SymbolExportInfo[] | undefined; - exportMapCache.search(bTs.path as Path, /*preferCapitalized*/ false, returnTrue, (info, symbolName) => { - if (symbolName === "SIGINT") sigintPropBefore = info; + let sigintPropBefore: readonly ts.SymbolExportInfo[] | undefined; + exportMapCache.search(bTs.path as ts.Path, /*preferCapitalized*/ false, ts.returnTrue, (info, symbolName) => { + if (symbolName === "SIGINT") + sigintPropBefore = info; }); assert.ok(sigintPropBefore); - assert.ok(sigintPropBefore![0].symbol.flags & SymbolFlags.Transient); - const symbolIdBefore = getSymbolId(sigintPropBefore![0].symbol); + assert.ok(sigintPropBefore![0].symbol.flags & ts.SymbolFlags.Transient); + const symbolIdBefore = ts.getSymbolId(sigintPropBefore![0].symbol); // Update program without clearing cache - session.executeCommandSeq({ - command: protocol.CommandTypes.UpdateOpen, + session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.UpdateOpen, arguments: { changedFiles: [{ fileName: bTs.path, @@ -112,32 +113,33 @@ namespace ts.projectSystem { assert.notEqual(programBefore, project.getCurrentProgram()!); // Get same info from cache again - let sigintPropAfter: readonly SymbolExportInfo[] | undefined; - exportMapCache.search(bTs.path as Path, /*preferCapitalized*/ false, returnTrue, (info, symbolName) => { - if (symbolName === "SIGINT") sigintPropAfter = info; + let sigintPropAfter: readonly ts.SymbolExportInfo[] | undefined; + exportMapCache.search(bTs.path as ts.Path, /*preferCapitalized*/ false, ts.returnTrue, (info, symbolName) => { + if (symbolName === "SIGINT") + sigintPropAfter = info; }); assert.ok(sigintPropAfter); - assert.notEqual(symbolIdBefore, getSymbolId(sigintPropAfter![0].symbol)); + assert.notEqual(symbolIdBefore, ts.getSymbolId(sigintPropAfter![0].symbol)); }); }); function setup() { - const host = createServerHost([aTs, bTs, ambientDeclaration, tsconfig, packageJson, mobxPackageJson, mobxDts, exportEqualsMappedType]); - const session = createSession(host); - openFilesForSession([aTs, bTs], session); + const host = ts.projectSystem.createServerHost([aTs, bTs, ambientDeclaration, tsconfig, packageJson, mobxPackageJson, mobxDts, exportEqualsMappedType]); + const session = ts.projectSystem.createSession(host); + ts.projectSystem.openFilesForSession([aTs, bTs], session); const projectService = session.getProjectService(); - const project = configuredProjectAt(projectService, 0); + const project = ts.projectSystem.configuredProjectAt(projectService, 0); triggerCompletions(); const checker = project.getLanguageService().getProgram()!.getTypeChecker(); return { host, project, projectService, session, exportMapCache: project.getCachedExportInfoMap(), checker, triggerCompletions }; function triggerCompletions() { - const requestLocation: protocol.FileLocationRequestArgs = { + const requestLocation: ts.projectSystem.protocol.FileLocationRequestArgs = { file: bTs.path, line: 1, offset: 3, }; - executeSessionRequest(session, protocol.CommandTypes.CompletionInfo, { + ts.projectSystem.executeSessionRequest(session, ts.projectSystem.protocol.CommandTypes.CompletionInfo, { ...requestLocation, includeExternalModuleExports: true, prefix: "foo", diff --git a/src/testRunner/unittests/tsserver/externalProjects.ts b/src/testRunner/unittests/tsserver/externalProjects.ts index 3bcb5789daaea..320444cf270f2 100644 --- a/src/testRunner/unittests/tsserver/externalProjects.ts +++ b/src/testRunner/unittests/tsserver/externalProjects.ts @@ -13,32 +13,32 @@ namespace ts.projectSystem { }) }; - const host = createServerHost([f1, config], { useCaseSensitiveFileNames: false }); - const service = createProjectService(host); + const host = ts.projectSystem.createServerHost([f1, config], { useCaseSensitiveFileNames: false }); + const service = ts.projectSystem.createProjectService(host); service.setHostConfiguration({ preferences: { lazyConfiguredProjectsFromExternalProject } }); - const upperCaseConfigFilePath = combinePaths(getDirectoryPath(config.path).toUpperCase(), getBaseFileName(config.path)); + const upperCaseConfigFilePath = ts.combinePaths(ts.getDirectoryPath(config.path).toUpperCase(), ts.getBaseFileName(config.path)); service.openExternalProject({ projectFileName: "/a/b/project.csproj", - rootFiles: toExternalFiles([f1.path, upperCaseConfigFilePath]), + rootFiles: ts.projectSystem.toExternalFiles([f1.path, upperCaseConfigFilePath]), options: {} - } as protocol.ExternalProject); + } as ts.projectSystem.protocol.ExternalProject); service.checkNumberOfProjects({ configuredProjects: 1 }); const project = service.configuredProjects.get(config.path)!; if (lazyConfiguredProjectsFromExternalProject) { - assert.equal(project.pendingReload, ConfigFileProgramReloadLevel.Full); // External project referenced configured project pending to be reloaded - checkProjectActualFiles(project, emptyArray); + assert.equal(project.pendingReload, ts.ConfigFileProgramReloadLevel.Full); // External project referenced configured project pending to be reloaded + ts.projectSystem.checkProjectActualFiles(project, ts.emptyArray); } else { - assert.equal(project.pendingReload, ConfigFileProgramReloadLevel.None); // External project referenced configured project loaded - checkProjectActualFiles(project, [upperCaseConfigFilePath]); + assert.equal(project.pendingReload, ts.ConfigFileProgramReloadLevel.None); // External project referenced configured project loaded + ts.projectSystem.checkProjectActualFiles(project, [upperCaseConfigFilePath]); } service.openClientFile(f1.path); service.checkNumberOfProjects({ configuredProjects: 1, inferredProjects: 1 }); - assert.equal(project.pendingReload, ConfigFileProgramReloadLevel.None); // External project referenced configured project is updated - checkProjectActualFiles(project, [upperCaseConfigFilePath]); - checkProjectActualFiles(service.inferredProjects[0], [f1.path]); + assert.equal(project.pendingReload, ts.ConfigFileProgramReloadLevel.None); // External project referenced configured project is updated + ts.projectSystem.checkProjectActualFiles(project, [upperCaseConfigFilePath]); + ts.projectSystem.checkProjectActualFiles(service.inferredProjects[0], [f1.path]); } it("when lazyConfiguredProjectsFromExternalProject not set", () => { @@ -55,20 +55,19 @@ namespace ts.projectSystem { path: "/a/file1.ts", content: "let x = [1, 2];" }; - const p1 = { projectFileName: "/a/proj1.csproj", rootFiles: [toExternalFile(f1.path)], options: {} }; - - const host = createServerHost([f1]); + const p1 = { projectFileName: "/a/proj1.csproj", rootFiles: [ts.projectSystem.toExternalFile(f1.path)], options: {} }; + const host = ts.projectSystem.createServerHost([f1]); host.require = (_initialPath, moduleName) => { assert.equal(moduleName, "myplugin"); return { module: () => ({ - create(info: server.PluginCreateInfo) { + create(info: ts.server.PluginCreateInfo) { const proxy = Harness.LanguageService.makeDefaultProxy(info); proxy.getSemanticDiagnostics = filename => { const prev = info.languageService.getSemanticDiagnostics(filename); - const sourceFile: SourceFile = info.project.getSourceFile(toPath(filename, /*basePath*/ undefined, createGetCanonicalFileName(info.serverHost.useCaseSensitiveFileNames)))!; + const sourceFile: ts.SourceFile = info.project.getSourceFile(ts.toPath(filename, /*basePath*/ undefined, ts.createGetCanonicalFileName(info.serverHost.useCaseSensitiveFileNames)))!; prev.push({ - category: DiagnosticCategory.Warning, + category: ts.DiagnosticCategory.Warning, file: sourceFile, code: 9999, length: 3, @@ -83,17 +82,17 @@ namespace ts.projectSystem { error: undefined }; }; - const session = createSession(host, { globalPlugins: ["myplugin"] }); + const session = ts.projectSystem.createSession(host, { globalPlugins: ["myplugin"] }); session.executeCommand({ seq: 1, type: "request", command: "openExternalProjects", arguments: { projects: [p1] } - } as protocol.OpenExternalProjectsRequest); + } as ts.projectSystem.protocol.OpenExternalProjectsRequest); const projectService = session.getProjectService(); - checkNumberOfProjects(projectService, { externalProjects: 1 }); + ts.projectSystem.checkNumberOfProjects(projectService, { externalProjects: 1 }); assert.equal(projectService.externalProjects[0].getProjectName(), p1.projectFileName); const handlerResponse = session.executeCommand({ @@ -104,10 +103,10 @@ namespace ts.projectSystem { file: f1.path, projectFileName: p1.projectFileName } - } as protocol.SemanticDiagnosticsSyncRequest); + } as ts.projectSystem.protocol.SemanticDiagnosticsSyncRequest); assert.isDefined(handlerResponse.response); - const response = handlerResponse.response as protocol.Diagnostic[]; + const response = handlerResponse.response as ts.projectSystem.protocol.Diagnostic[]; assert.equal(response.length, 1); assert.equal(response[0].text, "Plugin diagnostic"); }); @@ -125,23 +124,23 @@ namespace ts.projectSystem { path: "/c/app.ts", content: "let x = 1" }; - const makeProject = (f: File) => ({ projectFileName: f.path + ".csproj", rootFiles: [toExternalFile(f.path)], options: {} }); + const makeProject = (f: ts.projectSystem.File) => ({ projectFileName: f.path + ".csproj", rootFiles: [ts.projectSystem.toExternalFile(f.path)], options: {} }); const p1 = makeProject(f1); const p2 = makeProject(f2); const p3 = makeProject(f3); - const host = createServerHost([f1, f2, f3]); - const session = createSession(host); + const host = ts.projectSystem.createServerHost([f1, f2, f3]); + const session = ts.projectSystem.createSession(host); session.executeCommand({ seq: 1, type: "request", command: "openExternalProjects", arguments: { projects: [p1, p2] } - } as protocol.OpenExternalProjectsRequest); + } as ts.projectSystem.protocol.OpenExternalProjectsRequest); const projectService = session.getProjectService(); - checkNumberOfProjects(projectService, { externalProjects: 2 }); + ts.projectSystem.checkNumberOfProjects(projectService, { externalProjects: 2 }); assert.equal(projectService.externalProjects[0].getProjectName(), p1.projectFileName); assert.equal(projectService.externalProjects[1].getProjectName(), p2.projectFileName); @@ -150,8 +149,8 @@ namespace ts.projectSystem { type: "request", command: "openExternalProjects", arguments: { projects: [p1, p3] } - } as protocol.OpenExternalProjectsRequest); - checkNumberOfProjects(projectService, { externalProjects: 2 }); + } as ts.projectSystem.protocol.OpenExternalProjectsRequest); + ts.projectSystem.checkNumberOfProjects(projectService, { externalProjects: 2 }); assert.equal(projectService.externalProjects[0].getProjectName(), p1.projectFileName); assert.equal(projectService.externalProjects[1].getProjectName(), p3.projectFileName); @@ -160,15 +159,15 @@ namespace ts.projectSystem { type: "request", command: "openExternalProjects", arguments: { projects: [] } - } as protocol.OpenExternalProjectsRequest); - checkNumberOfProjects(projectService, { externalProjects: 0 }); + } as ts.projectSystem.protocol.OpenExternalProjectsRequest); + ts.projectSystem.checkNumberOfProjects(projectService, { externalProjects: 0 }); session.executeCommand({ seq: 3, type: "request", command: "openExternalProjects", arguments: { projects: [p2] } - } as protocol.OpenExternalProjectsRequest); + } as ts.projectSystem.protocol.OpenExternalProjectsRequest); assert.equal(projectService.externalProjects[0].getProjectName(), p2.projectFileName); }); @@ -182,67 +181,67 @@ namespace ts.projectSystem { content: "let y =1;" }; const externalProjectName = "externalproject"; - const host = createServerHost([file1, file2]); - const projectService = createProjectService(host); + const host = ts.projectSystem.createServerHost([file1, file2]); + const projectService = ts.projectSystem.createProjectService(host); projectService.openExternalProject({ - rootFiles: toExternalFiles([file1.path, file2.path]), + rootFiles: ts.projectSystem.toExternalFiles([file1.path, file2.path]), options: {}, projectFileName: externalProjectName }); - checkNumberOfExternalProjects(projectService, 1); - checkNumberOfInferredProjects(projectService, 0); + ts.projectSystem.checkNumberOfExternalProjects(projectService, 1); + ts.projectSystem.checkNumberOfInferredProjects(projectService, 0); // open client file - should not lead to creation of inferred project projectService.openClientFile(file1.path, file1.content); - checkNumberOfExternalProjects(projectService, 1); - checkNumberOfInferredProjects(projectService, 0); + ts.projectSystem.checkNumberOfExternalProjects(projectService, 1); + ts.projectSystem.checkNumberOfInferredProjects(projectService, 0); // close client file - external project should still exists projectService.closeClientFile(file1.path); - checkNumberOfExternalProjects(projectService, 1); - checkNumberOfInferredProjects(projectService, 0); + ts.projectSystem.checkNumberOfExternalProjects(projectService, 1); + ts.projectSystem.checkNumberOfInferredProjects(projectService, 0); projectService.closeExternalProject(externalProjectName); - checkNumberOfExternalProjects(projectService, 0); - checkNumberOfInferredProjects(projectService, 0); + ts.projectSystem.checkNumberOfExternalProjects(projectService, 0); + ts.projectSystem.checkNumberOfInferredProjects(projectService, 0); }); it("external project for dynamic file", () => { const externalProjectName = "^ScriptDocument1 file1.ts"; - const externalFiles = toExternalFiles(["^ScriptDocument1 file1.ts"]); - const host = createServerHost([]); - const projectService = createProjectService(host); + const externalFiles = ts.projectSystem.toExternalFiles(["^ScriptDocument1 file1.ts"]); + const host = ts.projectSystem.createServerHost([]); + const projectService = ts.projectSystem.createProjectService(host); projectService.openExternalProject({ rootFiles: externalFiles, options: {}, projectFileName: externalProjectName }); - checkNumberOfExternalProjects(projectService, 1); - checkNumberOfInferredProjects(projectService, 0); - verifyDynamic(projectService, "/^scriptdocument1 file1.ts"); + ts.projectSystem.checkNumberOfExternalProjects(projectService, 1); + ts.projectSystem.checkNumberOfInferredProjects(projectService, 0); + ts.projectSystem.verifyDynamic(projectService, "/^scriptdocument1 file1.ts"); externalFiles[0].content = "let x =1;"; - projectService.applyChangesInOpenFiles(arrayIterator(externalFiles)); + projectService.applyChangesInOpenFiles(ts.arrayIterator(externalFiles)); }); it("when file name starts with ^", () => { - const file: File = { - path: `${tscWatch.projectRoot}/file.ts`, + const file: ts.projectSystem.File = { + path: `${ts.tscWatch.projectRoot}/file.ts`, content: "const x = 10;" }; - const app: File = { - path: `${tscWatch.projectRoot}/^app.ts`, + const app: ts.projectSystem.File = { + path: `${ts.tscWatch.projectRoot}/^app.ts`, content: "const y = 10;" }; - const host = createServerHost([file, app, libFile]); - const service = createProjectService(host); + const host = ts.projectSystem.createServerHost([file, app, ts.projectSystem.libFile]); + const service = ts.projectSystem.createProjectService(host); service.openExternalProjects([{ - projectFileName: `${tscWatch.projectRoot}/myproject.njsproj`, + projectFileName: `${ts.tscWatch.projectRoot}/myproject.njsproj`, rootFiles: [ - toExternalFile(file.path), - toExternalFile(app.path) + ts.projectSystem.toExternalFile(file.path), + ts.projectSystem.toExternalFile(app.path) ], options: { }, }]); @@ -255,12 +254,10 @@ namespace ts.projectSystem { }; const config1 = { path: "/a/b/tsconfig.json", - content: JSON.stringify( - { + content: JSON.stringify({ compilerOptions: {}, files: ["f1.ts"] - } - ) + }) }; const file2 = { path: "/a/c/f2.ts", @@ -268,27 +265,25 @@ namespace ts.projectSystem { }; const config2 = { path: "/a/c/tsconfig.json", - content: JSON.stringify( - { + content: JSON.stringify({ compilerOptions: {}, files: ["f2.ts"] - } - ) + }) }; const file3 = { path: "/a/d/f3.ts", content: "let z =1;" }; const externalProjectName = "externalproject"; - const host = createServerHost([file1, file2, file3, config1, config2]); - const projectService = createProjectService(host); + const host = ts.projectSystem.createServerHost([file1, file2, file3, config1, config2]); + const projectService = ts.projectSystem.createProjectService(host); projectService.openExternalProject({ - rootFiles: toExternalFiles([config1.path, config2.path, file3.path]), + rootFiles: ts.projectSystem.toExternalFiles([config1.path, config2.path, file3.path]), options: {}, projectFileName: externalProjectName }); - checkNumberOfProjects(projectService, { configuredProjects: 2 }); + ts.projectSystem.checkNumberOfProjects(projectService, { configuredProjects: 2 }); const proj1 = projectService.configuredProjects.get(config1.path); const proj2 = projectService.configuredProjects.get(config2.path); assert.isDefined(proj1); @@ -296,35 +291,35 @@ namespace ts.projectSystem { // open client file - should not lead to creation of inferred project projectService.openClientFile(file1.path, file1.content); - checkNumberOfProjects(projectService, { configuredProjects: 2 }); + ts.projectSystem.checkNumberOfProjects(projectService, { configuredProjects: 2 }); assert.strictEqual(projectService.configuredProjects.get(config1.path), proj1); assert.strictEqual(projectService.configuredProjects.get(config2.path), proj2); projectService.openClientFile(file3.path, file3.content); - checkNumberOfProjects(projectService, { configuredProjects: 2, inferredProjects: 1 }); + ts.projectSystem.checkNumberOfProjects(projectService, { configuredProjects: 2, inferredProjects: 1 }); assert.strictEqual(projectService.configuredProjects.get(config1.path), proj1); assert.strictEqual(projectService.configuredProjects.get(config2.path), proj2); projectService.closeExternalProject(externalProjectName); // open file 'file1' from configured project keeps project alive - checkNumberOfProjects(projectService, { configuredProjects: 1, inferredProjects: 1 }); + ts.projectSystem.checkNumberOfProjects(projectService, { configuredProjects: 1, inferredProjects: 1 }); assert.strictEqual(projectService.configuredProjects.get(config1.path), proj1); assert.isUndefined(projectService.configuredProjects.get(config2.path)); projectService.closeClientFile(file3.path); - checkNumberOfProjects(projectService, { configuredProjects: 1, inferredProjects: 1 }); + ts.projectSystem.checkNumberOfProjects(projectService, { configuredProjects: 1, inferredProjects: 1 }); assert.strictEqual(projectService.configuredProjects.get(config1.path), proj1); assert.isUndefined(projectService.configuredProjects.get(config2.path)); assert.isTrue(projectService.inferredProjects[0].isOrphan()); projectService.closeClientFile(file1.path); - checkNumberOfProjects(projectService, { configuredProjects: 1, inferredProjects: 1 }); + ts.projectSystem.checkNumberOfProjects(projectService, { configuredProjects: 1, inferredProjects: 1 }); assert.strictEqual(projectService.configuredProjects.get(config1.path), proj1); assert.isUndefined(projectService.configuredProjects.get(config2.path)); assert.isTrue(projectService.inferredProjects[0].isOrphan()); projectService.openClientFile(file2.path, file2.content); - checkNumberOfProjects(projectService, { configuredProjects: 1 }); + ts.projectSystem.checkNumberOfProjects(projectService, { configuredProjects: 1 }); assert.isUndefined(projectService.configuredProjects.get(config1.path)); assert.isDefined(projectService.configuredProjects.get(config2.path)); }); @@ -339,26 +334,26 @@ namespace ts.projectSystem { content: JSON.stringify({ compilerOptions: {} }) }; const externalProjectName = "externalproject"; - const host = createServerHost([file1, configFile]); - const projectService = createProjectService(host); + const host = ts.projectSystem.createServerHost([file1, configFile]); + const projectService = ts.projectSystem.createProjectService(host); projectService.openClientFile(file1.path); - checkNumberOfProjects(projectService, { configuredProjects: 1 }); + ts.projectSystem.checkNumberOfProjects(projectService, { configuredProjects: 1 }); projectService.openExternalProject({ - rootFiles: toExternalFiles([configFile.path]), + rootFiles: ts.projectSystem.toExternalFiles([configFile.path]), options: {}, projectFileName: externalProjectName }); - checkNumberOfProjects(projectService, { configuredProjects: 1 }); + ts.projectSystem.checkNumberOfProjects(projectService, { configuredProjects: 1 }); projectService.closeClientFile(file1.path); // configured project is alive since it is opened as part of external project - checkNumberOfProjects(projectService, { configuredProjects: 1 }); + ts.projectSystem.checkNumberOfProjects(projectService, { configuredProjects: 1 }); projectService.closeExternalProject(externalProjectName); - checkNumberOfProjects(projectService, { configuredProjects: 0 }); + ts.projectSystem.checkNumberOfProjects(projectService, { configuredProjects: 0 }); }); it("external project with included config file opened after configured project and then closed", () => { @@ -375,33 +370,33 @@ namespace ts.projectSystem { content: JSON.stringify({ compilerOptions: {} }) }; const externalProjectName = "externalproject"; - const host = createServerHost([file1, file2, libFile, configFile]); - const projectService = createProjectService(host); + const host = ts.projectSystem.createServerHost([file1, file2, ts.projectSystem.libFile, configFile]); + const projectService = ts.projectSystem.createProjectService(host); projectService.openClientFile(file1.path); - checkNumberOfProjects(projectService, { configuredProjects: 1 }); + ts.projectSystem.checkNumberOfProjects(projectService, { configuredProjects: 1 }); const project = projectService.configuredProjects.get(configFile.path); projectService.openExternalProject({ - rootFiles: toExternalFiles([configFile.path]), + rootFiles: ts.projectSystem.toExternalFiles([configFile.path]), options: {}, projectFileName: externalProjectName }); - checkNumberOfProjects(projectService, { configuredProjects: 1 }); + ts.projectSystem.checkNumberOfProjects(projectService, { configuredProjects: 1 }); assert.strictEqual(projectService.configuredProjects.get(configFile.path), project); projectService.closeExternalProject(externalProjectName); // configured project is alive since file is still open - checkNumberOfProjects(projectService, { configuredProjects: 1 }); + ts.projectSystem.checkNumberOfProjects(projectService, { configuredProjects: 1 }); assert.strictEqual(projectService.configuredProjects.get(configFile.path), project); projectService.closeClientFile(file1.path); - checkNumberOfProjects(projectService, { configuredProjects: 1 }); + ts.projectSystem.checkNumberOfProjects(projectService, { configuredProjects: 1 }); assert.strictEqual(projectService.configuredProjects.get(configFile.path), project); projectService.openClientFile(file2.path); - checkNumberOfProjects(projectService, { inferredProjects: 1 }); + ts.projectSystem.checkNumberOfProjects(projectService, { inferredProjects: 1 }); assert.isUndefined(projectService.configuredProjects.get(configFile.path)); }); @@ -414,16 +409,14 @@ namespace ts.projectSystem { path: "/a/b/f2.ts", content: "let y = 1" }; - const host = createServerHost([file1, file2]); - const projectService = createProjectService(host); - - projectService.openExternalProject({ projectFileName: "project", options: {}, rootFiles: toExternalFiles([file1.path]) }); - checkNumberOfProjects(projectService, { externalProjects: 1 }); - checkProjectActualFiles(projectService.externalProjects[0], [file1.path]); - - projectService.openExternalProject({ projectFileName: "project", options: {}, rootFiles: toExternalFiles([file1.path, file2.path]) }); - checkNumberOfProjects(projectService, { externalProjects: 1 }); - checkProjectRootFiles(projectService.externalProjects[0], [file1.path, file2.path]); + const host = ts.projectSystem.createServerHost([file1, file2]); + const projectService = ts.projectSystem.createProjectService(host); + projectService.openExternalProject({ projectFileName: "project", options: {}, rootFiles: ts.projectSystem.toExternalFiles([file1.path]) }); + ts.projectSystem.checkNumberOfProjects(projectService, { externalProjects: 1 }); + ts.projectSystem.checkProjectActualFiles(projectService.externalProjects[0], [file1.path]); + projectService.openExternalProject({ projectFileName: "project", options: {}, rootFiles: ts.projectSystem.toExternalFiles([file1.path, file2.path]) }); + ts.projectSystem.checkNumberOfProjects(projectService, { externalProjects: 1 }); + ts.projectSystem.checkProjectRootFiles(projectService.externalProjects[0], [file1.path, file2.path]); }); it("can update external project when set of root files was not changed", () => { @@ -440,18 +433,16 @@ namespace ts.projectSystem { content: "export let y = 1" }; - const host = createServerHost([file1, file2, file3]); - const projectService = createProjectService(host); - - projectService.openExternalProject({ projectFileName: "project", options: { moduleResolution: ModuleResolutionKind.NodeJs }, rootFiles: toExternalFiles([file1.path, file2.path]) }); - checkNumberOfProjects(projectService, { externalProjects: 1 }); - checkProjectRootFiles(projectService.externalProjects[0], [file1.path, file2.path]); - checkProjectActualFiles(projectService.externalProjects[0], [file1.path, file2.path]); - - projectService.openExternalProject({ projectFileName: "project", options: { moduleResolution: ModuleResolutionKind.Classic }, rootFiles: toExternalFiles([file1.path, file2.path]) }); - checkNumberOfProjects(projectService, { externalProjects: 1 }); - checkProjectRootFiles(projectService.externalProjects[0], [file1.path, file2.path]); - checkProjectActualFiles(projectService.externalProjects[0], [file1.path, file2.path, file3.path]); + const host = ts.projectSystem.createServerHost([file1, file2, file3]); + const projectService = ts.projectSystem.createProjectService(host); + projectService.openExternalProject({ projectFileName: "project", options: { moduleResolution: ts.ModuleResolutionKind.NodeJs }, rootFiles: ts.projectSystem.toExternalFiles([file1.path, file2.path]) }); + ts.projectSystem.checkNumberOfProjects(projectService, { externalProjects: 1 }); + ts.projectSystem.checkProjectRootFiles(projectService.externalProjects[0], [file1.path, file2.path]); + ts.projectSystem.checkProjectActualFiles(projectService.externalProjects[0], [file1.path, file2.path]); + projectService.openExternalProject({ projectFileName: "project", options: { moduleResolution: ts.ModuleResolutionKind.Classic }, rootFiles: ts.projectSystem.toExternalFiles([file1.path, file2.path]) }); + ts.projectSystem.checkNumberOfProjects(projectService, { externalProjects: 1 }); + ts.projectSystem.checkProjectRootFiles(projectService.externalProjects[0], [file1.path, file2.path]); + ts.projectSystem.checkProjectActualFiles(projectService.externalProjects[0], [file1.path, file2.path, file3.path]); }); it("language service disabled state is updated in external projects", () => { @@ -463,17 +454,15 @@ namespace ts.projectSystem { path: "/a/largefile.js", content: "" }; - const host = createServerHost([f1, f2]); + const host = ts.projectSystem.createServerHost([f1, f2]); const originalGetFileSize = host.getFileSize; - host.getFileSize = (filePath: string) => - filePath === f2.path ? server.maxProgramSizeForNonTsFiles + 1 : originalGetFileSize.call(host, filePath); - - const service = createProjectService(host); + host.getFileSize = (filePath: string) => filePath === f2.path ? ts.server.maxProgramSizeForNonTsFiles + 1 : originalGetFileSize.call(host, filePath); + const service = ts.projectSystem.createProjectService(host); const projectFileName = "/a/proj.csproj"; service.openExternalProject({ projectFileName, - rootFiles: toExternalFiles([f1.path, f2.path]), + rootFiles: ts.projectSystem.toExternalFiles([f1.path, f2.path]), options: {} }); service.checkNumberOfProjects({ externalProjects: 1 }); @@ -481,7 +470,7 @@ namespace ts.projectSystem { service.openExternalProject({ projectFileName, - rootFiles: toExternalFiles([f1.path]), + rootFiles: ts.projectSystem.toExternalFiles([f1.path]), options: {} }); service.checkNumberOfProjects({ externalProjects: 1 }); @@ -489,7 +478,7 @@ namespace ts.projectSystem { service.openExternalProject({ projectFileName, - rootFiles: toExternalFiles([f1.path, f2.path]), + rootFiles: ts.projectSystem.toExternalFiles([f1.path, f2.path]), options: {} }); service.checkNumberOfProjects({ externalProjects: 1 }); @@ -507,13 +496,13 @@ namespace ts.projectSystem { content: "{}" }; const projectFileName = "/user/someuser/project/WebApplication6.csproj"; - const host = createServerHost([libFile, site, configFile]); - const projectService = createProjectService(host); + const host = ts.projectSystem.createServerHost([ts.projectSystem.libFile, site, configFile]); + const projectService = ts.projectSystem.createProjectService(host); projectService.setHostConfiguration({ preferences: { lazyConfiguredProjectsFromExternalProject } }); - const externalProject: protocol.ExternalProject = { + const externalProject: ts.projectSystem.protocol.ExternalProject = { projectFileName, - rootFiles: [toExternalFile(site.path), toExternalFile(configFile.path)], + rootFiles: [ts.projectSystem.toExternalFile(site.path), ts.projectSystem.toExternalFile(configFile.path)], options: { allowJs: false }, typeAcquisition: { include: [] } }; @@ -521,23 +510,21 @@ namespace ts.projectSystem { projectService.openExternalProjects([externalProject]); let knownProjects = projectService.synchronizeProjectList([]); - checkNumberOfProjects(projectService, { configuredProjects: 1, externalProjects: 0, inferredProjects: 0 }); - - const configProject = configuredProjectAt(projectService, 0); - checkProjectActualFiles(configProject, lazyConfiguredProjectsFromExternalProject ? - emptyArray : // Since no files opened from this project, its not loaded + ts.projectSystem.checkNumberOfProjects(projectService, { configuredProjects: 1, externalProjects: 0, inferredProjects: 0 }); + const configProject = ts.projectSystem.configuredProjectAt(projectService, 0); + ts.projectSystem.checkProjectActualFiles(configProject, lazyConfiguredProjectsFromExternalProject ? ts.emptyArray : // Since no files opened from this project, its not loaded [configFile.path]); host.deleteFile(configFile.path); - knownProjects = projectService.synchronizeProjectList(map(knownProjects, proj => proj.info!)); // TODO: GH#18217 GH#20039 - checkNumberOfProjects(projectService, { configuredProjects: 0, externalProjects: 0, inferredProjects: 0 }); + knownProjects = projectService.synchronizeProjectList(ts.map(knownProjects, proj => proj.info!)); // TODO: GH#18217 GH#20039 + ts.projectSystem.checkNumberOfProjects(projectService, { configuredProjects: 0, externalProjects: 0, inferredProjects: 0 }); externalProject.rootFiles.length = 1; projectService.openExternalProjects([externalProject]); - checkNumberOfProjects(projectService, { configuredProjects: 0, externalProjects: 1, inferredProjects: 0 }); - checkProjectActualFiles(projectService.externalProjects[0], [site.path, libFile.path]); + ts.projectSystem.checkNumberOfProjects(projectService, { configuredProjects: 0, externalProjects: 1, inferredProjects: 0 }); + ts.projectSystem.checkProjectActualFiles(projectService.externalProjects[0], [site.path, ts.projectSystem.libFile.path]); } it("when lazyConfiguredProjectsFromExternalProject not set", () => { verifyDeletingConfigFile(/*lazyConfiguredProjectsFromExternalProject*/ false); @@ -561,45 +548,45 @@ namespace ts.projectSystem { path: "/a/b/tsconfig.json", content: "" }; - const host = createServerHost([f1, f2]); - const projectService = createProjectService(host); + const host = ts.projectSystem.createServerHost([f1, f2]); + const projectService = ts.projectSystem.createProjectService(host); projectService.setHostConfiguration({ preferences: { lazyConfiguredProjectsFromExternalProject } }); // open external project const projectName = "/a/b/proj1"; projectService.openExternalProject({ projectFileName: projectName, - rootFiles: toExternalFiles([f1.path, f2.path]), + rootFiles: ts.projectSystem.toExternalFiles([f1.path, f2.path]), options: {} }); projectService.openClientFile(f1.path); projectService.checkNumberOfProjects({ externalProjects: 1 }); - checkProjectActualFiles(projectService.externalProjects[0], [f1.path, f2.path]); + ts.projectSystem.checkProjectActualFiles(projectService.externalProjects[0], [f1.path, f2.path]); // rename lib.ts to tsconfig.json host.renameFile(f2.path, tsconfig.path); projectService.openExternalProject({ projectFileName: projectName, - rootFiles: toExternalFiles([f1.path, tsconfig.path]), + rootFiles: ts.projectSystem.toExternalFiles([f1.path, tsconfig.path]), options: {} }); projectService.checkNumberOfProjects({ configuredProjects: 1 }); if (lazyConfiguredProjectsFromExternalProject) { - checkProjectActualFiles(configuredProjectAt(projectService, 0), emptyArray); // Configured project created but not loaded till actually needed + ts.projectSystem.checkProjectActualFiles(ts.projectSystem.configuredProjectAt(projectService, 0), ts.emptyArray); // Configured project created but not loaded till actually needed projectService.ensureInferredProjectsUpToDate_TestOnly(); } - checkProjectActualFiles(configuredProjectAt(projectService, 0), [f1.path, tsconfig.path]); + ts.projectSystem.checkProjectActualFiles(ts.projectSystem.configuredProjectAt(projectService, 0), [f1.path, tsconfig.path]); // rename tsconfig.json back to lib.ts host.renameFile(tsconfig.path, f2.path); projectService.openExternalProject({ projectFileName: projectName, - rootFiles: toExternalFiles([f1.path, f2.path]), + rootFiles: ts.projectSystem.toExternalFiles([f1.path, f2.path]), options: {} }); projectService.checkNumberOfProjects({ externalProjects: 1 }); - checkProjectActualFiles(projectService.externalProjects[0], [f1.path, f2.path]); + ts.projectSystem.checkProjectActualFiles(projectService.externalProjects[0], [f1.path, f2.path]); } it("when lazyConfiguredProjectsFromExternalProject not set", () => { verifyAddRemoveConfig(/*lazyConfiguredProjectsFromExternalProject*/ false); @@ -631,71 +618,71 @@ namespace ts.projectSystem { path: "/a/b/d/tsconfig.json", content: "{}" }; - const host = createServerHost([f1, cLib, cTsconfig, dLib, dTsconfig]); - const projectService = createProjectService(host); + const host = ts.projectSystem.createServerHost([f1, cLib, cTsconfig, dLib, dTsconfig]); + const projectService = ts.projectSystem.createProjectService(host); projectService.setHostConfiguration({ preferences: { lazyConfiguredProjectsFromExternalProject } }); // open external project const projectName = "/a/b/proj1"; projectService.openExternalProject({ projectFileName: projectName, - rootFiles: toExternalFiles([f1.path]), + rootFiles: ts.projectSystem.toExternalFiles([f1.path]), options: {} }); projectService.checkNumberOfProjects({ externalProjects: 1 }); - checkProjectActualFiles(projectService.externalProjects[0], [f1.path]); + ts.projectSystem.checkProjectActualFiles(projectService.externalProjects[0], [f1.path]); // add two config file as root files projectService.openExternalProject({ projectFileName: projectName, - rootFiles: toExternalFiles([f1.path, cTsconfig.path, dTsconfig.path]), + rootFiles: ts.projectSystem.toExternalFiles([f1.path, cTsconfig.path, dTsconfig.path]), options: {} }); projectService.checkNumberOfProjects({ configuredProjects: 2 }); if (lazyConfiguredProjectsFromExternalProject) { - checkProjectActualFiles(configuredProjectAt(projectService, 0), emptyArray); // Configured project created but not loaded till actually needed - checkProjectActualFiles(configuredProjectAt(projectService, 1), emptyArray); // Configured project created but not loaded till actually needed + ts.projectSystem.checkProjectActualFiles(ts.projectSystem.configuredProjectAt(projectService, 0), ts.emptyArray); // Configured project created but not loaded till actually needed + ts.projectSystem.checkProjectActualFiles(ts.projectSystem.configuredProjectAt(projectService, 1), ts.emptyArray); // Configured project created but not loaded till actually needed projectService.ensureInferredProjectsUpToDate_TestOnly(); } - checkProjectActualFiles(configuredProjectAt(projectService, 0), [cLib.path, cTsconfig.path]); - checkProjectActualFiles(configuredProjectAt(projectService, 1), [dLib.path, dTsconfig.path]); + ts.projectSystem.checkProjectActualFiles(ts.projectSystem.configuredProjectAt(projectService, 0), [cLib.path, cTsconfig.path]); + ts.projectSystem.checkProjectActualFiles(ts.projectSystem.configuredProjectAt(projectService, 1), [dLib.path, dTsconfig.path]); // remove one config file projectService.openExternalProject({ projectFileName: projectName, - rootFiles: toExternalFiles([f1.path, dTsconfig.path]), + rootFiles: ts.projectSystem.toExternalFiles([f1.path, dTsconfig.path]), options: {} }); projectService.checkNumberOfProjects({ configuredProjects: 1 }); - checkProjectActualFiles(configuredProjectAt(projectService, 0), [dLib.path, dTsconfig.path]); + ts.projectSystem.checkProjectActualFiles(ts.projectSystem.configuredProjectAt(projectService, 0), [dLib.path, dTsconfig.path]); // remove second config file projectService.openExternalProject({ projectFileName: projectName, - rootFiles: toExternalFiles([f1.path]), + rootFiles: ts.projectSystem.toExternalFiles([f1.path]), options: {} }); projectService.checkNumberOfProjects({ externalProjects: 1 }); - checkProjectActualFiles(projectService.externalProjects[0], [f1.path]); + ts.projectSystem.checkProjectActualFiles(projectService.externalProjects[0], [f1.path]); // open two config files // add two config file as root files projectService.openExternalProject({ projectFileName: projectName, - rootFiles: toExternalFiles([f1.path, cTsconfig.path, dTsconfig.path]), + rootFiles: ts.projectSystem.toExternalFiles([f1.path, cTsconfig.path, dTsconfig.path]), options: {} }); projectService.checkNumberOfProjects({ configuredProjects: 2 }); if (lazyConfiguredProjectsFromExternalProject) { - checkProjectActualFiles(configuredProjectAt(projectService, 0), emptyArray); // Configured project created but not loaded till actually needed - checkProjectActualFiles(configuredProjectAt(projectService, 1), emptyArray); // Configured project created but not loaded till actually needed + ts.projectSystem.checkProjectActualFiles(ts.projectSystem.configuredProjectAt(projectService, 0), ts.emptyArray); // Configured project created but not loaded till actually needed + ts.projectSystem.checkProjectActualFiles(ts.projectSystem.configuredProjectAt(projectService, 1), ts.emptyArray); // Configured project created but not loaded till actually needed projectService.ensureInferredProjectsUpToDate_TestOnly(); } - checkProjectActualFiles(configuredProjectAt(projectService, 0), [cLib.path, cTsconfig.path]); - checkProjectActualFiles(configuredProjectAt(projectService, 1), [dLib.path, dTsconfig.path]); + ts.projectSystem.checkProjectActualFiles(ts.projectSystem.configuredProjectAt(projectService, 0), [cLib.path, cTsconfig.path]); + ts.projectSystem.checkProjectActualFiles(ts.projectSystem.configuredProjectAt(projectService, 1), [dLib.path, dTsconfig.path]); // close all projects - no projects should be opened projectService.closeExternalProject(projectName); @@ -725,8 +712,7 @@ namespace ts.projectSystem { }; const config1 = { path: "/src/tsconfig.json", - content: JSON.stringify( - { + content: JSON.stringify({ compilerOptions: { module: "commonjs", target: "es5", @@ -740,8 +726,7 @@ namespace ts.projectSystem { }; const config2 = { path: config1.path, - content: JSON.stringify( - { + content: JSON.stringify({ compilerOptions: { module: "commonjs", target: "es5", @@ -754,18 +739,18 @@ namespace ts.projectSystem { } }) }; - const host = createServerHost([libES5, libES2015Promise, app, config1], { executingFilePath: "/compiler/tsc.js" }); - const projectService = createProjectService(host); + const host = ts.projectSystem.createServerHost([libES5, libES2015Promise, app, config1], { executingFilePath: "/compiler/tsc.js" }); + const projectService = ts.projectSystem.createProjectService(host); projectService.openClientFile(app.path); projectService.checkNumberOfProjects({ configuredProjects: 1 }); - checkProjectActualFiles(configuredProjectAt(projectService, 0), [libES5.path, app.path, config1.path]); + ts.projectSystem.checkProjectActualFiles(ts.projectSystem.configuredProjectAt(projectService, 0), [libES5.path, app.path, config1.path]); host.writeFile(config2.path, config2.content); host.checkTimeoutQueueLengthAndRun(2); projectService.checkNumberOfProjects({ configuredProjects: 1 }); - checkProjectActualFiles(configuredProjectAt(projectService, 0), [libES5.path, libES2015Promise.path, app.path, config2.path]); + ts.projectSystem.checkProjectActualFiles(ts.projectSystem.configuredProjectAt(projectService, 0), [libES5.path, libES2015Promise.path, app.path, config2.path]); }); it("should handle non-existing directories in config file", () => { @@ -783,8 +768,8 @@ namespace ts.projectSystem { ] }) }; - const host = createServerHost([f, config]); - const projectService = createProjectService(host); + const host = ts.projectSystem.createServerHost([f, config]); + const projectService = ts.projectSystem.createProjectService(host); projectService.openClientFile(f.path); projectService.checkNumberOfProjects({ configuredProjects: 1 }); const project = projectService.configuredProjects.get(config.path)!; @@ -813,46 +798,46 @@ namespace ts.projectSystem { content: JSON.stringify({}) }; const projectFileName = "/a/b/project.csproj"; - const host = createServerHost([f1, config]); - const service = createProjectService(host); + const host = ts.projectSystem.createServerHost([f1, config]); + const service = ts.projectSystem.createProjectService(host); service.setHostConfiguration({ preferences: { lazyConfiguredProjectsFromExternalProject: true } }); service.openExternalProject({ projectFileName, - rootFiles: toExternalFiles([f1.path, config.path]), + rootFiles: ts.projectSystem.toExternalFiles([f1.path, config.path]), options: {} - } as protocol.ExternalProject); + } as ts.projectSystem.protocol.ExternalProject); service.checkNumberOfProjects({ configuredProjects: 1 }); const project = service.configuredProjects.get(config.path)!; - assert.equal(project.pendingReload, ConfigFileProgramReloadLevel.Full); // External project referenced configured project pending to be reloaded - checkProjectActualFiles(project, emptyArray); + assert.equal(project.pendingReload, ts.ConfigFileProgramReloadLevel.Full); // External project referenced configured project pending to be reloaded + ts.projectSystem.checkProjectActualFiles(project, ts.emptyArray); service.setHostConfiguration({ preferences: { lazyConfiguredProjectsFromExternalProject: false } }); - assert.equal(project.pendingReload, ConfigFileProgramReloadLevel.None); // External project referenced configured project loaded - checkProjectActualFiles(project, [config.path, f1.path]); + assert.equal(project.pendingReload, ts.ConfigFileProgramReloadLevel.None); // External project referenced configured project loaded + ts.projectSystem.checkProjectActualFiles(project, [config.path, f1.path]); service.closeExternalProject(projectFileName); service.checkNumberOfProjects({}); service.openExternalProject({ projectFileName, - rootFiles: toExternalFiles([f1.path, config.path]), + rootFiles: ts.projectSystem.toExternalFiles([f1.path, config.path]), options: {} - } as protocol.ExternalProject); + } as ts.projectSystem.protocol.ExternalProject); service.checkNumberOfProjects({ configuredProjects: 1 }); const project2 = service.configuredProjects.get(config.path)!; - assert.equal(project2.pendingReload, ConfigFileProgramReloadLevel.None); // External project referenced configured project loaded - checkProjectActualFiles(project2, [config.path, f1.path]); + assert.equal(project2.pendingReload, ts.ConfigFileProgramReloadLevel.None); // External project referenced configured project loaded + ts.projectSystem.checkProjectActualFiles(project2, [config.path, f1.path]); }); it("handles creation of external project with jsconfig before jsconfig creation watcher is invoked", () => { - const projectFileName = `${tscWatch.projectRoot}/WebApplication36.csproj`; - const tsconfig: File = { - path: `${tscWatch.projectRoot}/tsconfig.json`, + const projectFileName = `${ts.tscWatch.projectRoot}/WebApplication36.csproj`; + const tsconfig: ts.projectSystem.File = { + path: `${ts.tscWatch.projectRoot}/tsconfig.json`, content: "{}" }; - const files = [libFile, tsconfig]; - const host = createServerHost(files); - const service = createProjectService(host); + const files = [ts.projectSystem.libFile, tsconfig]; + const host = ts.projectSystem.createServerHost(files); + const service = ts.projectSystem.createProjectService(host); // Create external project service.openExternalProjects([{ @@ -860,27 +845,27 @@ namespace ts.projectSystem { rootFiles: [{ fileName: tsconfig.path }], options: { allowJs: false } }]); - checkNumberOfProjects(service, { configuredProjects: 1 }); + ts.projectSystem.checkNumberOfProjects(service, { configuredProjects: 1 }); const configProject = service.configuredProjects.get(tsconfig.path.toLowerCase())!; - checkProjectActualFiles(configProject, [tsconfig.path]); + ts.projectSystem.checkProjectActualFiles(configProject, [tsconfig.path]); // write js file, open external project and open it for edit - const jsFilePath = `${tscWatch.projectRoot}/javascript.js`; + const jsFilePath = `${ts.tscWatch.projectRoot}/javascript.js`; host.writeFile(jsFilePath, ""); service.openExternalProjects([{ projectFileName, rootFiles: [{ fileName: tsconfig.path }, { fileName: jsFilePath }], options: { allowJs: false } }]); - service.applyChangesInOpenFiles(singleIterator({ fileName: jsFilePath, scriptKind: ScriptKind.JS, content: "" })); - checkNumberOfProjects(service, { configuredProjects: 1, inferredProjects: 1 }); - checkProjectActualFiles(configProject, [tsconfig.path]); + service.applyChangesInOpenFiles(ts.singleIterator({ fileName: jsFilePath, scriptKind: ts.ScriptKind.JS, content: "" })); + ts.projectSystem.checkNumberOfProjects(service, { configuredProjects: 1, inferredProjects: 1 }); + ts.projectSystem.checkProjectActualFiles(configProject, [tsconfig.path]); const inferredProject = service.inferredProjects[0]; - checkProjectActualFiles(inferredProject, [libFile.path, jsFilePath]); + ts.projectSystem.checkProjectActualFiles(inferredProject, [ts.projectSystem.libFile.path, jsFilePath]); // write jsconfig file - const jsConfig: File = { - path: `${tscWatch.projectRoot}/jsconfig.json`, + const jsConfig: ts.projectSystem.File = { + path: `${ts.tscWatch.projectRoot}/jsconfig.json`, content: "{}" }; // Dont invoke file creation watchers as the repro suggests @@ -892,11 +877,11 @@ namespace ts.projectSystem { rootFiles: [{ fileName: jsConfig.path }, { fileName: tsconfig.path }, { fileName: jsFilePath }], options: { allowJs: false } }]); - checkNumberOfProjects(service, { configuredProjects: 2, inferredProjects: 1 }); - checkProjectActualFiles(configProject, [tsconfig.path]); + ts.projectSystem.checkNumberOfProjects(service, { configuredProjects: 2, inferredProjects: 1 }); + ts.projectSystem.checkProjectActualFiles(configProject, [tsconfig.path]); assert.isTrue(inferredProject.isOrphan()); const jsConfigProject = service.configuredProjects.get(jsConfig.path.toLowerCase())!; - checkProjectActualFiles(jsConfigProject, [jsConfig.path, jsFilePath, libFile.path]); + ts.projectSystem.checkProjectActualFiles(jsConfigProject, [jsConfig.path, jsFilePath, ts.projectSystem.libFile.path]); }); it("does not crash if external file does not exist", () => { @@ -906,16 +891,16 @@ namespace ts.projectSystem { }; const p1 = { projectFileName: "/a/proj1.csproj", - rootFiles: [toExternalFile(f1.path)], + rootFiles: [ts.projectSystem.toExternalFile(f1.path)], options: {}, }; - const host = createServerHost([f1]); + const host = ts.projectSystem.createServerHost([f1]); host.require = (_initialPath, moduleName) => { assert.equal(moduleName, "myplugin"); return { module: () => ({ - create(info: server.PluginCreateInfo) { + create(info: ts.server.PluginCreateInfo) { return Harness.LanguageService.makeDefaultProxy(info); }, getExternalFiles() { @@ -925,7 +910,7 @@ namespace ts.projectSystem { error: undefined, }; }; - const session = createSession(host, { + const session = ts.projectSystem.createSession(host, { globalPlugins: ["myplugin"], }); const projectService = session.getProjectService(); @@ -935,7 +920,7 @@ namespace ts.projectSystem { // info for it. If tsserver does not handle this case, the following // method call will crash. projectService.openExternalProject(p1); - checkNumberOfProjects(projectService, { externalProjects: 1 }); + ts.projectSystem.checkNumberOfProjects(projectService, { externalProjects: 1 }); }); }); } diff --git a/src/testRunner/unittests/tsserver/forceConsistentCasingInFileNames.ts b/src/testRunner/unittests/tsserver/forceConsistentCasingInFileNames.ts index 674556e8cf135..30851edb76421 100644 --- a/src/testRunner/unittests/tsserver/forceConsistentCasingInFileNames.ts +++ b/src/testRunner/unittests/tsserver/forceConsistentCasingInFileNames.ts @@ -2,19 +2,19 @@ namespace ts.projectSystem { describe("unittests:: tsserver:: forceConsistentCasingInFileNames", () => { it("works when extends is specified with a case insensitive file system", () => { const rootPath = "/Users/username/dev/project"; - const file1: File = { + const file1: ts.projectSystem.File = { path: `${rootPath}/index.ts`, content: 'import {x} from "file2";', }; - const file2: File = { + const file2: ts.projectSystem.File = { path: `${rootPath}/file2.js`, content: "", }; - const file2Dts: File = { + const file2Dts: ts.projectSystem.File = { path: `${rootPath}/types/file2/index.d.ts`, content: "export declare const x: string;", }; - const tsconfigAll: File = { + const tsconfigAll: ts.projectSystem.File = { path: `${rootPath}/tsconfig.all.json`, content: JSON.stringify({ compilerOptions: { @@ -25,112 +25,103 @@ namespace ts.projectSystem { }, }), }; - const tsconfig: File = { + const tsconfig: ts.projectSystem.File = { path: `${rootPath}/tsconfig.json`, content: JSON.stringify({ extends: "./tsconfig.all.json" }), }; - const host = createServerHost([file1, file2, file2Dts, libFile, tsconfig, tsconfigAll], { useCaseSensitiveFileNames: false }); - const session = createSession(host); - - openFilesForSession([file1], session); + const host = ts.projectSystem.createServerHost([file1, file2, file2Dts, ts.projectSystem.libFile, tsconfig, tsconfigAll], { useCaseSensitiveFileNames: false }); + const session = ts.projectSystem.createSession(host); + ts.projectSystem.openFilesForSession([file1], session); const projectService = session.getProjectService(); - checkNumberOfProjects(projectService, { configuredProjects: 1 }); - - const diagnostics = configuredProjectAt(projectService, 0).getLanguageService().getCompilerOptionsDiagnostics(); + ts.projectSystem.checkNumberOfProjects(projectService, { configuredProjects: 1 }); + const diagnostics = ts.projectSystem.configuredProjectAt(projectService, 0).getLanguageService().getCompilerOptionsDiagnostics(); assert.deepEqual(diagnostics, []); }); it("works when renaming file with different casing", () => { - const loggerFile: File = { - path: `${tscWatch.projectRoot}/Logger.ts`, + const loggerFile: ts.projectSystem.File = { + path: `${ts.tscWatch.projectRoot}/Logger.ts`, content: `export class logger { }` }; - const anotherFile: File = { - path: `${tscWatch.projectRoot}/another.ts`, + const anotherFile: ts.projectSystem.File = { + path: `${ts.tscWatch.projectRoot}/another.ts`, content: `import { logger } from "./Logger"; new logger();` }; - const tsconfig: File = { - path: `${tscWatch.projectRoot}/tsconfig.json`, + const tsconfig: ts.projectSystem.File = { + path: `${ts.tscWatch.projectRoot}/tsconfig.json`, content: JSON.stringify({ compilerOptions: { forceConsistentCasingInFileNames: true } }) }; - const host = createServerHost([loggerFile, anotherFile, tsconfig, libFile, tsconfig]); - const session = createSession(host, { canUseEvents: true, logger: createLoggerWithInMemoryLogs() }); - openFilesForSession([{ file: loggerFile, projectRootPath: tscWatch.projectRoot }], session); - verifyGetErrRequest({ session, host, files: [loggerFile] }); + const host = ts.projectSystem.createServerHost([loggerFile, anotherFile, tsconfig, ts.projectSystem.libFile, tsconfig]); + const session = ts.projectSystem.createSession(host, { canUseEvents: true, logger: ts.projectSystem.createLoggerWithInMemoryLogs() }); + ts.projectSystem.openFilesForSession([{ file: loggerFile, projectRootPath: ts.tscWatch.projectRoot }], session); + ts.projectSystem.verifyGetErrRequest({ session, host, files: [loggerFile] }); const newLoggerPath = loggerFile.path.toLowerCase(); host.renameFile(loggerFile.path, newLoggerPath); - closeFilesForSession([loggerFile], session); - openFilesForSession([{ file: newLoggerPath, content: loggerFile.content, projectRootPath: tscWatch.projectRoot }], session); + ts.projectSystem.closeFilesForSession([loggerFile], session); + ts.projectSystem.openFilesForSession([{ file: newLoggerPath, content: loggerFile.content, projectRootPath: ts.tscWatch.projectRoot }], session); // Apply edits for rename - openFilesForSession([{ file: anotherFile, projectRootPath: tscWatch.projectRoot }], session); - session.executeCommandSeq({ - command: protocol.CommandTypes.UpdateOpen, + ts.projectSystem.openFilesForSession([{ file: anotherFile, projectRootPath: ts.tscWatch.projectRoot }], session); + session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.UpdateOpen, arguments: { changedFiles: [{ fileName: anotherFile.path, textChanges: [{ newText: "./logger", - ...protocolTextSpanFromSubstring( - anotherFile.content, - "./Logger" - ) + ...ts.projectSystem.protocolTextSpanFromSubstring(anotherFile.content, "./Logger") }] }] } }); // Check errors in both files - verifyGetErrRequest({ session, host, files: [newLoggerPath, anotherFile] }); - baselineTsserverLogs("forceConsistentCasingInFileNames", "works when renaming file with different casing", session); + ts.projectSystem.verifyGetErrRequest({ session, host, files: [newLoggerPath, anotherFile] }); + ts.projectSystem.baselineTsserverLogs("forceConsistentCasingInFileNames", "works when renaming file with different casing", session); }); it("when changing module name with different casing", () => { - const loggerFile: File = { - path: `${tscWatch.projectRoot}/Logger.ts`, + const loggerFile: ts.projectSystem.File = { + path: `${ts.tscWatch.projectRoot}/Logger.ts`, content: `export class logger { }` }; - const anotherFile: File = { - path: `${tscWatch.projectRoot}/another.ts`, + const anotherFile: ts.projectSystem.File = { + path: `${ts.tscWatch.projectRoot}/another.ts`, content: `import { logger } from "./Logger"; new logger();` }; - const tsconfig: File = { - path: `${tscWatch.projectRoot}/tsconfig.json`, + const tsconfig: ts.projectSystem.File = { + path: `${ts.tscWatch.projectRoot}/tsconfig.json`, content: JSON.stringify({ compilerOptions: { forceConsistentCasingInFileNames: true } }) }; - const host = createServerHost([loggerFile, anotherFile, tsconfig, libFile, tsconfig]); - const session = createSession(host, { canUseEvents: true, logger: createLoggerWithInMemoryLogs() }); - openFilesForSession([{ file: anotherFile, projectRootPath: tscWatch.projectRoot }], session); - verifyGetErrRequest({ session, host, files: [anotherFile] }); - - session.executeCommandSeq({ - command: protocol.CommandTypes.UpdateOpen, + const host = ts.projectSystem.createServerHost([loggerFile, anotherFile, tsconfig, ts.projectSystem.libFile, tsconfig]); + const session = ts.projectSystem.createSession(host, { canUseEvents: true, logger: ts.projectSystem.createLoggerWithInMemoryLogs() }); + ts.projectSystem.openFilesForSession([{ file: anotherFile, projectRootPath: ts.tscWatch.projectRoot }], session); + ts.projectSystem.verifyGetErrRequest({ session, host, files: [anotherFile] }); + session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.UpdateOpen, arguments: { changedFiles: [{ fileName: anotherFile.path, textChanges: [{ newText: "./logger", - ...protocolTextSpanFromSubstring( - anotherFile.content, - "./Logger" - ) + ...ts.projectSystem.protocolTextSpanFromSubstring(anotherFile.content, "./Logger") }] }] } }); // Check errors in both files - verifyGetErrRequest({ host, session, files: [anotherFile] }); - baselineTsserverLogs("forceConsistentCasingInFileNames", "when changing module name with different casing", session); + ts.projectSystem.verifyGetErrRequest({ host, session, files: [anotherFile] }); + ts.projectSystem.baselineTsserverLogs("forceConsistentCasingInFileNames", "when changing module name with different casing", session); }); }); } diff --git a/src/testRunner/unittests/tsserver/formatSettings.ts b/src/testRunner/unittests/tsserver/formatSettings.ts index 2d09ed8a8a0eb..cb49a1da6b1a6 100644 --- a/src/testRunner/unittests/tsserver/formatSettings.ts +++ b/src/testRunner/unittests/tsserver/formatSettings.ts @@ -5,18 +5,18 @@ namespace ts.projectSystem { path: "/a/b/app.ts", content: "let x;" }; - const host = createServerHost([f1]); - const projectService = createProjectService(host); + const host = ts.projectSystem.createServerHost([f1]); + const projectService = ts.projectSystem.createProjectService(host); projectService.openClientFile(f1.path); - const defaultSettings = projectService.getFormatCodeOptions(f1.path as server.NormalizedPath); + const defaultSettings = projectService.getFormatCodeOptions(f1.path as ts.server.NormalizedPath); // set global settings const newGlobalSettings1 = { ...defaultSettings, placeOpenBraceOnNewLineForControlBlocks: !defaultSettings.placeOpenBraceOnNewLineForControlBlocks }; projectService.setHostConfiguration({ formatOptions: newGlobalSettings1 }); // get format options for file - should be equal to new global settings - const s1 = projectService.getFormatCodeOptions(server.toNormalizedPath(f1.path)); + const s1 = projectService.getFormatCodeOptions(ts.server.toNormalizedPath(f1.path)); assert.deepEqual(s1, newGlobalSettings1, "file settings should be the same with global settings"); // set per file format options @@ -24,7 +24,7 @@ namespace ts.projectSystem { projectService.setHostConfiguration({ formatOptions: newPerFileSettings, file: f1.path }); // get format options for file - should be equal to new per-file settings - const s2 = projectService.getFormatCodeOptions(server.toNormalizedPath(f1.path)); + const s2 = projectService.getFormatCodeOptions(ts.server.toNormalizedPath(f1.path)); assert.deepEqual(s2, newPerFileSettings, "file settings should be the same with per-file settings"); // set new global settings - they should not affect ones that were set per-file @@ -32,7 +32,7 @@ namespace ts.projectSystem { projectService.setHostConfiguration({ formatOptions: newGlobalSettings2 }); // get format options for file - should be equal to new per-file settings - const s3 = projectService.getFormatCodeOptions(server.toNormalizedPath(f1.path)); + const s3 = projectService.getFormatCodeOptions(ts.server.toNormalizedPath(f1.path)); assert.deepEqual(s3, newPerFileSettings, "file settings should still be the same with per-file settings"); }); }); diff --git a/src/testRunner/unittests/tsserver/getApplicableRefactors.ts b/src/testRunner/unittests/tsserver/getApplicableRefactors.ts index bec4a65456051..d356bef769d07 100644 --- a/src/testRunner/unittests/tsserver/getApplicableRefactors.ts +++ b/src/testRunner/unittests/tsserver/getApplicableRefactors.ts @@ -1,12 +1,11 @@ namespace ts.projectSystem { describe("unittests:: tsserver:: getApplicableRefactors", () => { it("works when taking position", () => { - const aTs: File = { path: "/a.ts", content: "" }; - const session = createSession(createServerHost([aTs])); - openFilesForSession([aTs], session); - const response = executeSessionRequest( - session, protocol.CommandTypes.GetApplicableRefactors, { file: aTs.path, line: 1, offset: 1 }); - assert.deepEqual(response, []); + const aTs: ts.projectSystem.File = { path: "/a.ts", content: "" }; + const session = ts.projectSystem.createSession(ts.projectSystem.createServerHost([aTs])); + ts.projectSystem.openFilesForSession([aTs], session); + const response = ts.projectSystem.executeSessionRequest(session, ts.projectSystem.protocol.CommandTypes.GetApplicableRefactors, { file: aTs.path, line: 1, offset: 1 }); + assert.deepEqual(response, []); }); }); } diff --git a/src/testRunner/unittests/tsserver/getEditsForFileRename.ts b/src/testRunner/unittests/tsserver/getEditsForFileRename.ts index 5dcd3e96fdb1d..ed15c7339c252 100644 --- a/src/testRunner/unittests/tsserver/getEditsForFileRename.ts +++ b/src/testRunner/unittests/tsserver/getEditsForFileRename.ts @@ -1,103 +1,99 @@ namespace ts.projectSystem { describe("unittests:: tsserver:: getEditsForFileRename", () => { it("works for host implementing 'resolveModuleNames' and 'getResolvedModuleWithFailedLookupLocationsFromCache'", () => { - const userTs: File = { + const userTs: ts.projectSystem.File = { path: "/user.ts", content: 'import { x } from "./old";', }; - const newTs: File = { + const newTs: ts.projectSystem.File = { path: "/new.ts", content: "export const x = 0;", }; - const tsconfig: File = { + const tsconfig: ts.projectSystem.File = { path: "/tsconfig.json", content: "{}", }; - const host = createServerHost([userTs, newTs, tsconfig]); - const projectService = createProjectService(host); + const host = ts.projectSystem.createServerHost([userTs, newTs, tsconfig]); + const projectService = ts.projectSystem.createProjectService(host); projectService.openClientFile(userTs.path); const project = projectService.configuredProjects.get(tsconfig.path)!; - Debug.assert(!!project.resolveModuleNames); - - const edits = project.getLanguageService().getEditsForFileRename("/old.ts", "/new.ts", testFormatSettings, emptyOptions); - assert.deepEqual(edits, [{ + ts.Debug.assert(!!project.resolveModuleNames); + const edits = project.getLanguageService().getEditsForFileRename("/old.ts", "/new.ts", ts.testFormatSettings, ts.emptyOptions); + assert.deepEqual(edits, [{ fileName: "/user.ts", textChanges: [{ - span: textSpanFromSubstring(userTs.content, "./old"), + span: ts.projectSystem.textSpanFromSubstring(userTs.content, "./old"), newText: "./new", }], }]); }); it("works with multiple projects", () => { - const aUserTs: File = { + const aUserTs: ts.projectSystem.File = { path: "/a/user.ts", content: 'import { x } from "./old";', }; - const aOldTs: File = { + const aOldTs: ts.projectSystem.File = { path: "/a/old.ts", content: "export const x = 0;", }; - const aTsconfig: File = { + const aTsconfig: ts.projectSystem.File = { path: "/a/tsconfig.json", content: JSON.stringify({ files: ["./old.ts", "./user.ts"] }), }; - const bUserTs: File = { + const bUserTs: ts.projectSystem.File = { path: "/b/user.ts", content: 'import { x } from "../a/old";', }; - const bTsconfig: File = { + const bTsconfig: ts.projectSystem.File = { path: "/b/tsconfig.json", content: "{}", }; - const host = createServerHost([aUserTs, aOldTs, aTsconfig, bUserTs, bTsconfig]); - const session = createSession(host); - openFilesForSession([aUserTs, bUserTs], session); - - const response = executeSessionRequest(session, CommandNames.GetEditsForFileRename, { + const host = ts.projectSystem.createServerHost([aUserTs, aOldTs, aTsconfig, bUserTs, bTsconfig]); + const session = ts.projectSystem.createSession(host); + ts.projectSystem.openFilesForSession([aUserTs, bUserTs], session); + const response = ts.projectSystem.executeSessionRequest(session, ts.projectSystem.CommandNames.GetEditsForFileRename, { oldFilePath: aOldTs.path, newFilePath: "/a/new.ts", }); - assert.deepEqual(response, [ + assert.deepEqual(response, [ { fileName: aTsconfig.path, - textChanges: [{ ...protocolTextSpanFromSubstring(aTsconfig.content, "./old.ts"), newText: "new.ts" }], + textChanges: [{ ...ts.projectSystem.protocolTextSpanFromSubstring(aTsconfig.content, "./old.ts"), newText: "new.ts" }], }, { fileName: aUserTs.path, - textChanges: [{ ...protocolTextSpanFromSubstring(aUserTs.content, "./old"), newText: "./new" }], + textChanges: [{ ...ts.projectSystem.protocolTextSpanFromSubstring(aUserTs.content, "./old"), newText: "./new" }], }, { fileName: bUserTs.path, - textChanges: [{ ...protocolTextSpanFromSubstring(bUserTs.content, "../a/old"), newText: "../a/new" }], + textChanges: [{ ...ts.projectSystem.protocolTextSpanFromSubstring(bUserTs.content, "../a/old"), newText: "../a/new" }], }, ]); }); it("works with file moved to inferred project", () => { - const aTs: File = { path: "/a.ts", content: 'import {} from "./b";' }; - const cTs: File = { path: "/c.ts", content: "export {};" }; - const tsconfig: File = { path: "/tsconfig.json", content: JSON.stringify({ files: ["./a.ts", "./b.ts"] }) }; - - const host = createServerHost([aTs, cTs, tsconfig]); - const session = createSession(host); - openFilesForSession([aTs, cTs], session); - - const response = executeSessionRequest(session, CommandNames.GetEditsForFileRename, { + const aTs: ts.projectSystem.File = { path: "/a.ts", content: 'import {} from "./b";' }; + const cTs: ts.projectSystem.File = { path: "/c.ts", content: "export {};" }; + const tsconfig: ts.projectSystem.File = { path: "/tsconfig.json", content: JSON.stringify({ files: ["./a.ts", "./b.ts"] }) }; + const host = ts.projectSystem.createServerHost([aTs, cTs, tsconfig]); + const session = ts.projectSystem.createSession(host); + ts.projectSystem.openFilesForSession([aTs, cTs], session); + const response = ts.projectSystem.executeSessionRequest(session, ts.projectSystem.CommandNames.GetEditsForFileRename, { oldFilePath: "/b.ts", newFilePath: cTs.path, }); - assert.deepEqual(response, [ + assert.deepEqual(response, [ { fileName: "/tsconfig.json", - textChanges: [{ ...protocolTextSpanFromSubstring(tsconfig.content, "./b.ts"), newText: "c.ts" }], + textChanges: [{ ...ts.projectSystem.protocolTextSpanFromSubstring(tsconfig.content, "./b.ts"), newText: "c.ts" }], }, { fileName: "/a.ts", - textChanges: [{ ...protocolTextSpanFromSubstring(aTs.content, "./b"), newText: "./c" }], + textChanges: [{ ...ts.projectSystem.protocolTextSpanFromSubstring(aTs.content, "./b"), newText: "./c" }], }, ]); }); diff --git a/src/testRunner/unittests/tsserver/getExportReferences.ts b/src/testRunner/unittests/tsserver/getExportReferences.ts index 2312c7b823d07..264fceb9d1462 100644 --- a/src/testRunner/unittests/tsserver/getExportReferences.ts +++ b/src/testRunner/unittests/tsserver/getExportReferences.ts @@ -5,11 +5,11 @@ namespace ts.projectSystem { const exportObjectDestructured = "export const { valueC, valueD: renamedD } = { valueC: 0, valueD: 1 };"; const exportNestedObject = "export const { nest: [valueE, { valueF }] } = { nest: [0, { valueF: 1 }] };"; - const mainTs: File = { + const mainTs: ts.projectSystem.File = { path: "/main.ts", content: 'import { value, valueA, valueB, valueC, renamedD, valueE, valueF } from "./mod";', }; - const modTs: File = { + const modTs: ts.projectSystem.File = { path: "/mod.ts", content: `${exportVariable} ${exportArrayDestructured} @@ -17,20 +17,19 @@ ${exportObjectDestructured} ${exportNestedObject} `, }; - const tsconfig: File = { + const tsconfig: ts.projectSystem.File = { path: "/tsconfig.json", content: "{}", }; function makeSampleSession() { - const host = createServerHost([mainTs, modTs, tsconfig]); - const session = createSession(host); - openFilesForSession([mainTs, modTs], session); + const host = ts.projectSystem.createServerHost([mainTs, modTs, tsconfig]); + const session = ts.projectSystem.createSession(host); + ts.projectSystem.openFilesForSession([mainTs, modTs], session); return session; } - const referenceMainTs = (mainTs: File, text: string): protocol.ReferencesResponseItem => - makeReferenceItem({ + const referenceMainTs = (mainTs: ts.projectSystem.File, text: string): ts.projectSystem.protocol.ReferencesResponseItem => ts.projectSystem.makeReferenceItem({ file: mainTs, isDefinition: false, isWriteAccess: true, @@ -39,11 +38,11 @@ ${exportNestedObject} text, }); - const referenceModTs = ( - texts: { text: string; lineText: string; contextText?: string }, - override: Partial = {}, - ): protocol.ReferencesResponseItem => - makeReferenceItem({ + const referenceModTs = (texts: { + text: string; + lineText: string; + contextText?: string; + }, override: Partial = {}): ts.projectSystem.protocol.ReferencesResponseItem => ts.projectSystem.makeReferenceItem({ file: modTs, isDefinition: true, ...texts, @@ -53,11 +52,7 @@ ${exportNestedObject} it("should get const variable declaration references", () => { const session = makeSampleSession(); - const response = executeSessionRequest( - session, - protocol.CommandTypes.References, - protocolFileLocationFromSubstring(modTs, "value"), - ); + const response = ts.projectSystem.executeSessionRequest(session, ts.projectSystem.protocol.CommandTypes.References, ts.projectSystem.protocolFileLocationFromSubstring(modTs, "value")); const expectResponse = { refs: [ @@ -66,7 +61,7 @@ ${exportNestedObject} ], symbolDisplayString: "const value: 0", symbolName: "value", - symbolStartOffset: protocolLocationFromSubstring(modTs.content, "value").offset, + symbolStartOffset: ts.projectSystem.protocolLocationFromSubstring(modTs.content, "value").offset, }; assert.deepEqual(response, expectResponse); @@ -74,11 +69,7 @@ ${exportNestedObject} it("should get array destructuring declaration references", () => { const session = makeSampleSession(); - const response = executeSessionRequest( - session, - protocol.CommandTypes.References, - protocolFileLocationFromSubstring(modTs, "valueA"), - ); + const response = ts.projectSystem.executeSessionRequest(session, ts.projectSystem.protocol.CommandTypes.References, ts.projectSystem.protocolFileLocationFromSubstring(modTs, "valueA")); const expectResponse = { refs: [ @@ -91,7 +82,7 @@ ${exportNestedObject} ], symbolDisplayString: "const valueA: number", symbolName: "valueA", - symbolStartOffset: protocolLocationFromSubstring(modTs.content, "valueA").offset, + symbolStartOffset: ts.projectSystem.protocolLocationFromSubstring(modTs.content, "valueA").offset, }; assert.deepEqual(response, expectResponse); @@ -99,11 +90,7 @@ ${exportNestedObject} it("should get object destructuring declaration references", () => { const session = makeSampleSession(); - const response = executeSessionRequest( - session, - protocol.CommandTypes.References, - protocolFileLocationFromSubstring(modTs, "valueC"), - ); + const response = ts.projectSystem.executeSessionRequest(session, ts.projectSystem.protocol.CommandTypes.References, ts.projectSystem.protocolFileLocationFromSubstring(modTs, "valueC")); const expectResponse = { refs: [ referenceModTs({ @@ -112,9 +99,7 @@ ${exportNestedObject} contextText: exportObjectDestructured, }), referenceMainTs(mainTs, "valueC"), - referenceModTs( - { text: "valueC", lineText: exportObjectDestructured, contextText: "valueC: 0" }, - { + referenceModTs({ text: "valueC", lineText: exportObjectDestructured, contextText: "valueC: 0" }, { options: { index: 1 }, isDefinition: false, isWriteAccess: true, @@ -122,7 +107,7 @@ ${exportNestedObject} ], symbolDisplayString: "const valueC: number", symbolName: "valueC", - symbolStartOffset: protocolLocationFromSubstring(modTs.content, "valueC").offset, + symbolStartOffset: ts.projectSystem.protocolLocationFromSubstring(modTs.content, "valueC").offset, }; assert.deepEqual(response, expectResponse); @@ -130,11 +115,7 @@ ${exportNestedObject} it("should get object declaration references that renames destructured property", () => { const session = makeSampleSession(); - const response = executeSessionRequest( - session, - protocol.CommandTypes.References, - protocolFileLocationFromSubstring(modTs, "renamedD"), - ); + const response = ts.projectSystem.executeSessionRequest(session, ts.projectSystem.protocol.CommandTypes.References, ts.projectSystem.protocolFileLocationFromSubstring(modTs, "renamedD")); const expectResponse = { refs: [ @@ -147,7 +128,7 @@ ${exportNestedObject} ], symbolDisplayString: "const renamedD: number", symbolName: "renamedD", - symbolStartOffset: protocolLocationFromSubstring(modTs.content, "renamedD").offset, + symbolStartOffset: ts.projectSystem.protocolLocationFromSubstring(modTs.content, "renamedD").offset, }; assert.deepEqual(response, expectResponse); @@ -155,11 +136,7 @@ ${exportNestedObject} it("should get nested object declaration references", () => { const session = makeSampleSession(); - const response = executeSessionRequest( - session, - protocol.CommandTypes.References, - protocolFileLocationFromSubstring(modTs, "valueF"), - ); + const response = ts.projectSystem.executeSessionRequest(session, ts.projectSystem.protocol.CommandTypes.References, ts.projectSystem.protocolFileLocationFromSubstring(modTs, "valueF")); const expectResponse = { refs: [ @@ -169,22 +146,19 @@ ${exportNestedObject} contextText: exportNestedObject, }), referenceMainTs(mainTs, "valueF"), - referenceModTs( - { + referenceModTs({ text: "valueF", lineText: exportNestedObject, contextText: "valueF: 1", - }, - { + }, { options: { index: 1 }, isDefinition: false, isWriteAccess: true, - }, - ), + }), ], symbolDisplayString: "const valueF: number", symbolName: "valueF", - symbolStartOffset: protocolLocationFromSubstring(modTs.content, "valueF").offset, + symbolStartOffset: ts.projectSystem.protocolLocationFromSubstring(modTs.content, "valueF").offset, }; assert.deepEqual(response, expectResponse); diff --git a/src/testRunner/unittests/tsserver/getFileReferences.ts b/src/testRunner/unittests/tsserver/getFileReferences.ts index 4244671e756c4..a833f0ac979a3 100644 --- a/src/testRunner/unittests/tsserver/getFileReferences.ts +++ b/src/testRunner/unittests/tsserver/getFileReferences.ts @@ -5,49 +5,44 @@ namespace ts.projectSystem { const importAFromA = `import { a } from "/project/a";`; const typeofImportA = `type T = typeof import("./a").a;`; - const aTs: File = { + const aTs: ts.projectSystem.File = { path: "/project/a.ts", content: "export const a = {};", }; - const bTs: File = { + const bTs: ts.projectSystem.File = { path: "/project/b.ts", content: importA, }; - const cTs: File = { + const cTs: ts.projectSystem.File = { path: "/project/c.ts", content: importCurlyFromA }; - const dTs: File = { + const dTs: ts.projectSystem.File = { path: "/project/d.ts", content: [importAFromA, typeofImportA].join("\n") }; - const tsconfig: File = { + const tsconfig: ts.projectSystem.File = { path: "/project/tsconfig.json", content: "{}", }; function makeSampleSession() { - const host = createServerHost([aTs, bTs, cTs, dTs, tsconfig]); - const session = createSession(host); - openFilesForSession([aTs, bTs, cTs, dTs], session); + const host = ts.projectSystem.createServerHost([aTs, bTs, cTs, dTs, tsconfig]); + const session = ts.projectSystem.createSession(host); + ts.projectSystem.openFilesForSession([aTs, bTs, cTs, dTs], session); return session; } it("should get file references", () => { const session = makeSampleSession(); - const response = executeSessionRequest( - session, - protocol.CommandTypes.FileReferences, - { file: aTs.path }, - ); - - const expectResponse: protocol.FileReferencesResponseBody = { + const response = ts.projectSystem.executeSessionRequest(session, ts.projectSystem.protocol.CommandTypes.FileReferences, { file: aTs.path }); + const expectResponse: ts.projectSystem.protocol.FileReferencesResponseBody = { refs: [ - makeReferenceItem({ file: bTs, text: "./a", lineText: importA, contextText: importA, isWriteAccess: false }), - makeReferenceItem({ file: cTs, text: "./a", lineText: importCurlyFromA, contextText: importCurlyFromA, isWriteAccess: false }), - makeReferenceItem({ file: dTs, text: "/project/a", lineText: importAFromA, contextText: importAFromA, isWriteAccess: false }), - makeReferenceItem({ file: dTs, text: "./a", lineText: typeofImportA, contextText: typeofImportA, isWriteAccess: false }), + ts.projectSystem.makeReferenceItem({ file: bTs, text: "./a", lineText: importA, contextText: importA, isWriteAccess: false }), + ts.projectSystem.makeReferenceItem({ file: cTs, text: "./a", lineText: importCurlyFromA, contextText: importCurlyFromA, isWriteAccess: false }), + ts.projectSystem.makeReferenceItem({ file: dTs, text: "/project/a", lineText: importAFromA, contextText: importAFromA, isWriteAccess: false }), + ts.projectSystem.makeReferenceItem({ file: dTs, text: "./a", lineText: typeofImportA, contextText: typeofImportA, isWriteAccess: false }), ], symbolName: `"${aTs.path}"`, }; diff --git a/src/testRunner/unittests/tsserver/helpers.ts b/src/testRunner/unittests/tsserver/helpers.ts index eb7c74653436a..95db397d5d6b1 100644 --- a/src/testRunner/unittests/tsserver/helpers.ts +++ b/src/testRunner/unittests/tsserver/helpers.ts @@ -1,33 +1,28 @@ namespace ts.projectSystem { - export import TI = server.typingsInstaller; - export import protocol = server.protocol; - export import CommandNames = server.CommandNames; - - export import TestServerHost = TestFSWithWatch.TestServerHost; - export type File = TestFSWithWatch.File; - export type SymLink = TestFSWithWatch.SymLink; - export type Folder = TestFSWithWatch.Folder; - export import createServerHost = TestFSWithWatch.createServerHost; - export import checkArray = TestFSWithWatch.checkArray; - export import libFile = TestFSWithWatch.libFile; - export import checkWatchedFiles = TestFSWithWatch.checkWatchedFiles; - export import checkWatchedFilesDetailed = TestFSWithWatch.checkWatchedFilesDetailed; - export import checkWatchedDirectories = TestFSWithWatch.checkWatchedDirectories; - export import checkWatchedDirectoriesDetailed = TestFSWithWatch.checkWatchedDirectoriesDetailed; - - export import commonFile1 = tscWatch.commonFile1; - export import commonFile2 = tscWatch.commonFile2; + export import TI = ts.server.typingsInstaller; + export import protocol = ts.server.protocol; + export import CommandNames = ts.server.CommandNames; + export import TestServerHost = ts.TestFSWithWatch.TestServerHost; + export type File = ts.TestFSWithWatch.File; + export type SymLink = ts.TestFSWithWatch.SymLink; + export type Folder = ts.TestFSWithWatch.Folder; + export import createServerHost = ts.TestFSWithWatch.createServerHost; + export import checkArray = ts.TestFSWithWatch.checkArray; + export import libFile = ts.TestFSWithWatch.libFile; + export import checkWatchedFiles = ts.TestFSWithWatch.checkWatchedFiles; + export import checkWatchedFilesDetailed = ts.TestFSWithWatch.checkWatchedFilesDetailed; + export import checkWatchedDirectories = ts.TestFSWithWatch.checkWatchedDirectories; + export import checkWatchedDirectoriesDetailed = ts.TestFSWithWatch.checkWatchedDirectoriesDetailed; + export import commonFile1 = ts.tscWatch.commonFile1; + export import commonFile2 = ts.tscWatch.commonFile2; const outputEventRegex = /Content\-Length: [\d]+\r\n\r\n/; export function mapOutputToJson(s: string) { - return convertToObject( - parseJsonText("json.json", s.replace(outputEventRegex, "")), - [] - ); + return ts.convertToObject(ts.parseJsonText("json.json", s.replace(outputEventRegex, "")), []); } export const customTypesMap = { - path: "/typesMap.json" as Path, + path: "/typesMap.json" as ts.Path, content: `{ "typesMap": { "jquery": { @@ -55,21 +50,21 @@ namespace ts.projectSystem { readonly callback: TI.RequestCompletedAction; } - export interface Logger extends server.Logger { + export interface Logger extends ts.server.Logger { logs: string[]; } export function nullLogger(): Logger { return { - close: noop, - hasLevel: returnFalse, - loggingEnabled: returnFalse, - perftrc: noop, - info: noop, - msg: noop, - startGroup: noop, - endGroup: noop, - getLogFileName: returnUndefined, + close: ts.noop, + hasLevel: ts.returnFalse, + loggingEnabled: ts.returnFalse, + perftrc: ts.noop, + info: ts.noop, + msg: ts.noop, + startGroup: ts.noop, + endGroup: ts.noop, + getLogFileName: ts.returnUndefined, logs: [], }; } @@ -77,15 +72,15 @@ namespace ts.projectSystem { export function createHasErrorMessageLogger(): Logger { return { ...nullLogger(), - msg: (s, type) => Debug.fail(`Error: ${s}, type: ${type}`), + msg: (s, type) => ts.Debug.fail(`Error: ${s}, type: ${type}`), }; } export function createLoggerWritingToConsole(): Logger { return { ...nullLogger(), - hasLevel: returnTrue, - loggingEnabled: returnTrue, + hasLevel: ts.returnTrue, + loggingEnabled: ts.returnTrue, perftrc: s => console.log(s), info: s => console.log(s), msg: (s, type) => console.log(`${type}:: ${s}`), @@ -96,30 +91,28 @@ namespace ts.projectSystem { const logger = createHasErrorMessageLogger(); return { ...logger, - hasLevel: returnTrue, - loggingEnabled: returnTrue, - info: s => logger.logs.push( - s.replace(/Elapsed::?\s*\d+(?:\.\d+)?ms/g, "Elapsed:: *ms") + hasLevel: ts.returnTrue, + loggingEnabled: ts.returnTrue, + info: s => logger.logs.push(s.replace(/Elapsed::?\s*\d+(?:\.\d+)?ms/g, "Elapsed:: *ms") .replace(/\"updateGraphDurationMs\"\:\d+(?:\.\d+)?/g, `"updateGraphDurationMs":*`) .replace(/\"createAutoImportProviderProgramDurationMs\"\:\d+(?:\.\d+)?/g, `"createAutoImportProviderProgramDurationMs":*`) - .replace(`"version":"${version}"`, `"version":"FakeVersion"`) - ) + .replace(`"version":"${ts.version}"`, `"version":"FakeVersion"`)) }; } export function baselineTsserverLogs(scenario: string, subScenario: string, sessionOrService: TestSession | TestProjectService) { - Debug.assert(sessionOrService.logger.logs.length); // Ensure caller used in memory logger + ts.Debug.assert(sessionOrService.logger.logs.length); // Ensure caller used in memory logger Harness.Baseline.runBaseline(`tsserver/${scenario}/${subScenario.split(" ").join("-")}.js`, sessionOrService.logger.logs.join("\r\n")); } - export function appendAllScriptInfos(service: server.ProjectService, logs: string[]) { + export function appendAllScriptInfos(service: ts.server.ProjectService, logs: string[]) { logs.push(""); logs.push(`ScriptInfos:`); service.filenameToScriptInfo.forEach(info => logs.push(`path: ${info.path} fileName: ${info.fileName}`)); logs.push(""); } - export function appendProjectFileText(project: server.Project, logs: string[]) { + export function appendProjectFileText(project: ts.server.Project, logs: string[]) { logs.push(""); logs.push(`Project: ${project.getProjectName()}`); project.getCurrentProgram()?.getSourceFiles().forEach(f => { @@ -130,22 +123,17 @@ namespace ts.projectSystem { logs.push(""); } - export class TestTypingsInstaller extends TI.TypingsInstaller implements server.ITypingsInstaller { - protected projectService!: server.ProjectService; - constructor( - readonly globalTypingsCacheLocation: string, - throttleLimit: number, - installTypingHost: server.ServerHost, - readonly typesRegistry = new Map>(), - log?: TI.Log) { - super(installTypingHost, globalTypingsCacheLocation, TestFSWithWatch.safeList.path, customTypesMap.path, throttleLimit, log); + export class TestTypingsInstaller extends TI.TypingsInstaller implements ts.server.ITypingsInstaller { + protected projectService!: ts.server.ProjectService; + constructor(readonly globalTypingsCacheLocation: string, throttleLimit: number, installTypingHost: ts.server.ServerHost, readonly typesRegistry = new ts.Map>(), log?: TI.Log) { + super(installTypingHost, globalTypingsCacheLocation, ts.TestFSWithWatch.safeList.path, customTypesMap.path, throttleLimit, log); } protected postExecActions: PostExecAction[] = []; - isKnownTypesPackageName = notImplemented; - installPackage = notImplemented; - inspectValue = notImplemented; + isKnownTypesPackageName = ts.notImplemented; + installPackage = ts.notImplemented; + inspectValue = ts.notImplemented; executePendingCommands() { const actionsToRun = this.postExecActions; @@ -159,9 +147,8 @@ namespace ts.projectSystem { assert.equal(this.postExecActions.length, expectedCount, `Expected ${expectedCount} post install actions`); } - onProjectClosed = noop; - - attach(projectService: server.ProjectService) { + onProjectClosed = ts.noop; + attach(projectService: ts.server.ProjectService) { this.projectService = projectService; } @@ -173,17 +160,17 @@ namespace ts.projectSystem { this.addPostExecAction("success", cb); } - sendResponse(response: server.SetTypings | server.InvalidateCachedTypings) { + sendResponse(response: ts.server.SetTypings | ts.server.InvalidateCachedTypings) { this.projectService.updateTypingsForProject(response); } - enqueueInstallTypingsRequest(project: server.Project, typeAcquisition: TypeAcquisition, unresolvedImports: SortedReadonlyArray) { - const request = server.createInstallTypingsRequest(project, typeAcquisition, unresolvedImports, this.globalTypingsCacheLocation); + enqueueInstallTypingsRequest(project: ts.server.Project, typeAcquisition: ts.TypeAcquisition, unresolvedImports: ts.SortedReadonlyArray) { + const request = ts.server.createInstallTypingsRequest(project, typeAcquisition, unresolvedImports, this.globalTypingsCacheLocation); this.install(request); } addPostExecAction(stdout: string | string[], cb: TI.RequestCompletedAction) { - const out = isString(stdout) ? stdout : createNpmPackageJsonString(stdout); + const out = ts.isString(stdout) ? stdout : createNpmPackageJsonString(stdout); const action: PostExecAction = { success: !!out, callback: cb @@ -193,14 +180,14 @@ namespace ts.projectSystem { } function createNpmPackageJsonString(installedTypings: string[]): string { - const dependencies: MapLike = {}; + const dependencies: ts.MapLike = {}; for (const typing of installedTypings) { dependencies[typing] = "1.0.0"; } return JSON.stringify({ dependencies }); } - export function createTypesRegistry(...list: string[]): ESMap> { + export function createTypesRegistry(...list: string[]): ts.ESMap> { const versionMap = { "latest": "1.3.0", "ts2.0": "1.0.0", @@ -212,7 +199,7 @@ namespace ts.projectSystem { "ts2.6": "1.3.0", "ts2.7": "1.3.0" }; - const map = new Map>(); + const map = new ts.Map>(); for (const l of list) { map.set(l, versionMap); } @@ -224,17 +211,17 @@ namespace ts.projectSystem { } export function toExternalFiles(fileNames: string[]) { - return map(fileNames, toExternalFile); + return ts.map(fileNames, toExternalFile); } - export function fileStats(nonZeroStats: Partial): server.FileStats { + export function fileStats(nonZeroStats: Partial): ts.server.FileStats { return { ts: 0, tsSize: 0, tsx: 0, tsxSize: 0, dts: 0, dtsSize: 0, js: 0, jsSize: 0, jsx: 0, jsxSize: 0, deferred: 0, deferredSize: 0, ...nonZeroStats }; } export class TestServerEventManager { - private events: server.ProjectServiceEvent[] = []; + private events: ts.server.ProjectServiceEvent[] = []; readonly session: TestSession; - readonly service: server.ProjectService; + readonly service: ts.server.ProjectService; readonly host: TestServerHost; constructor(files: File[], suppressDiagnosticEvents?: boolean) { this.host = createServerHost(files); @@ -246,15 +233,15 @@ namespace ts.projectSystem { this.service = this.session.getProjectService(); } - getEvents(): readonly server.ProjectServiceEvent[] { + getEvents(): readonly ts.server.ProjectServiceEvent[] { const events = this.events; this.events = []; return events; } - getEvent(eventName: T["eventName"]): T["data"] { + getEvent(eventName: T["eventName"]): T["data"] { let eventData: T["data"] | undefined; - filterMutate(this.events, e => { + ts.filterMutate(this.events, e => { if (e.eventName === eventName) { if (eventData !== undefined) { assert(false, "more than one event found"); @@ -264,16 +251,16 @@ namespace ts.projectSystem { } return true; }); - return Debug.checkDefined(eventData); + return ts.Debug.checkDefined(eventData); } - hasZeroEvent(eventName: T["eventName"]) { + hasZeroEvent(eventName: T["eventName"]) { this.events.forEach(event => assert.notEqual(event.eventName, eventName)); } - assertProjectInfoTelemetryEvent(partial: Partial, configFile = "/tsconfig.json"): void { - assert.deepEqual(this.getEvent(server.ProjectInfoTelemetryEvent), { - projectId: sys.createSHA256Hash!(configFile), + assertProjectInfoTelemetryEvent(partial: Partial, configFile = "/tsconfig.json"): void { + assert.deepEqual(this.getEvent(ts.server.ProjectInfoTelemetryEvent), { + projectId: ts.sys.createSHA256Hash!(configFile), fileStats: fileStats({ ts: 1 }), compilerOptions: {}, extends: false, @@ -289,24 +276,24 @@ namespace ts.projectSystem { configFileName: "tsconfig.json", projectType: "configured", languageServiceEnabled: true, - version: ts.version, // eslint-disable-line @typescript-eslint/no-unnecessary-qualifier + version: ts.version, ...partial, }); } - assertOpenFileTelemetryEvent(info: server.OpenFileInfo): void { - assert.deepEqual(this.getEvent(server.OpenFileInfoTelemetryEvent), { info }); + assertOpenFileTelemetryEvent(info: ts.server.OpenFileInfo): void { + assert.deepEqual(this.getEvent(ts.server.OpenFileInfoTelemetryEvent), { info }); } assertNoOpenFilesTelemetryEvent(): void { - this.hasZeroEvent(server.OpenFileInfoTelemetryEvent); + this.hasZeroEvent(ts.server.OpenFileInfoTelemetryEvent); } } - export interface TestSessionOptions extends server.SessionOptions { + export interface TestSessionOptions extends ts.server.SessionOptions { logger: Logger; } - export class TestSession extends server.Session { + export class TestSession extends ts.server.Session { private seq = 0; public events: protocol.Event[] = []; public testhost: TestServerHost = this.host as TestServerHost; @@ -330,14 +317,16 @@ namespace ts.projectSystem { } public executeCommand(request: protocol.Request) { - const verboseLogging = this.logger.hasLevel(server.LogLevel.verbose); - if (verboseLogging) this.logger.info(`request:${JSON.stringify(request)}`); + const verboseLogging = this.logger.hasLevel(ts.server.LogLevel.verbose); + if (verboseLogging) + this.logger.info(`request:${JSON.stringify(request)}`); const result = super.executeCommand(request); - if (verboseLogging) this.logger.info(`response:${JSON.stringify(result)}`); + if (verboseLogging) + this.logger.info(`response:${JSON.stringify(result)}`); return result; } - public executeCommandSeq(request: Partial) { + public executeCommandSeq(request: Partial) { this.seq++; request.seq = this.seq; request.type = "request"; @@ -345,17 +334,17 @@ namespace ts.projectSystem { } public event(body: T, eventName: string) { - this.events.push(server.toEvent(eventName, body)); + this.events.push(ts.server.toEvent(eventName, body)); super.event(body, eventName); } public clearMessages() { - clear(this.events); + ts.clear(this.events); this.testhost.clearOutput(); } } - export function createSession(host: server.ServerHost, opts: Partial = {}) { + export function createSession(host: ts.server.ServerHost, opts: Partial = {}) { if (opts.typingsInstaller === undefined) { opts.typingsInstaller = new TestTypingsInstaller("/a/data/", /*throttleLimit*/ 5, host); } @@ -366,10 +355,10 @@ namespace ts.projectSystem { const sessionOptions: TestSessionOptions = { host, - cancellationToken: server.nullCancellationToken, + cancellationToken: ts.server.nullCancellationToken, useSingleInferredProject: false, useInferredProjectPerProjectRoot: false, - typingsInstaller: undefined!, // TODO: GH#18217 + typingsInstaller: undefined!, byteLength: Utils.byteLength, hrtime: process.hrtime, logger: opts.logger || createHasErrorMessageLogger(), @@ -379,7 +368,7 @@ namespace ts.projectSystem { return new TestSession({ ...sessionOptions, ...opts }); } - export function createSessionWithEventTracking(host: server.ServerHost, eventName: T["eventName"], ...eventNames: T["eventName"][]) { + export function createSessionWithEventTracking(host: ts.server.ServerHost, eventName: T["eventName"], ...eventNames: T["eventName"][]) { const events: T[] = []; const session = createSession(host, { eventHandler: e => { @@ -402,9 +391,9 @@ namespace ts.projectSystem { }; function getEvents() { - return mapDefined(host.getOutput(), s => { + return ts.mapDefined(host.getOutput(), s => { const e = mapOutputToJson(s); - return (isArray(eventNames) ? eventNames.some(eventName => e.event === eventName) : e.event === eventNames) ? e as T : undefined; + return (ts.isArray(eventNames) ? eventNames.some(eventName => e.event === eventName) : e.event === eventNames) ? e as T : undefined; }); } @@ -413,13 +402,12 @@ namespace ts.projectSystem { } } - export interface TestProjectServiceOptions extends server.ProjectServiceOptions { + export interface TestProjectServiceOptions extends ts.server.ProjectServiceOptions { logger: Logger; } - export class TestProjectService extends server.ProjectService { - constructor(host: server.ServerHost, public logger: Logger, cancellationToken: HostCancellationToken, useSingleInferredProject: boolean, - typingsInstaller: server.ITypingsInstaller, opts: Partial = {}) { + export class TestProjectService extends ts.server.ProjectService { + constructor(host: ts.server.ServerHost, public logger: Logger, cancellationToken: ts.HostCancellationToken, useSingleInferredProject: boolean, typingsInstaller: ts.server.ITypingsInstaller, opts: Partial = {}) { super({ host, logger, @@ -433,76 +421,83 @@ namespace ts.projectSystem { }); } - checkNumberOfProjects(count: { inferredProjects?: number, configuredProjects?: number, externalProjects?: number }) { + checkNumberOfProjects(count: { + inferredProjects?: number; + configuredProjects?: number; + externalProjects?: number; + }) { checkNumberOfProjects(this, count); } } - export function createProjectService(host: server.ServerHost, options?: Partial) { - const cancellationToken = options?.cancellationToken || server.nullCancellationToken; + export function createProjectService(host: ts.server.ServerHost, options?: Partial) { + const cancellationToken = options?.cancellationToken || ts.server.nullCancellationToken; const logger = options?.logger || createHasErrorMessageLogger(); const useSingleInferredProject = options?.useSingleInferredProject !== undefined ? options.useSingleInferredProject : false; - return new TestProjectService(host, logger, cancellationToken, useSingleInferredProject, options?.typingsInstaller || server.nullTypingsInstaller, options); + return new TestProjectService(host, logger, cancellationToken, useSingleInferredProject, options?.typingsInstaller || ts.server.nullTypingsInstaller, options); } - export function checkNumberOfConfiguredProjects(projectService: server.ProjectService, expected: number) { + export function checkNumberOfConfiguredProjects(projectService: ts.server.ProjectService, expected: number) { assert.equal(projectService.configuredProjects.size, expected, `expected ${expected} configured project(s)`); } - export function checkNumberOfExternalProjects(projectService: server.ProjectService, expected: number) { + export function checkNumberOfExternalProjects(projectService: ts.server.ProjectService, expected: number) { assert.equal(projectService.externalProjects.length, expected, `expected ${expected} external project(s)`); } - export function checkNumberOfInferredProjects(projectService: server.ProjectService, expected: number) { + export function checkNumberOfInferredProjects(projectService: ts.server.ProjectService, expected: number) { assert.equal(projectService.inferredProjects.length, expected, `expected ${expected} inferred project(s)`); } - export function checkNumberOfProjects(projectService: server.ProjectService, count: { inferredProjects?: number, configuredProjects?: number, externalProjects?: number }) { + export function checkNumberOfProjects(projectService: ts.server.ProjectService, count: { + inferredProjects?: number; + configuredProjects?: number; + externalProjects?: number; + }) { checkNumberOfConfiguredProjects(projectService, count.configuredProjects || 0); checkNumberOfExternalProjects(projectService, count.externalProjects || 0); checkNumberOfInferredProjects(projectService, count.inferredProjects || 0); } - export function configuredProjectAt(projectService: server.ProjectService, index: number) { + export function configuredProjectAt(projectService: ts.server.ProjectService, index: number) { const values = projectService.configuredProjects.values(); while (index > 0) { const iterResult = values.next(); - if (iterResult.done) return Debug.fail("Expected a result."); + if (iterResult.done) + return ts.Debug.fail("Expected a result."); index--; } const iterResult = values.next(); - if (iterResult.done) return Debug.fail("Expected a result."); + if (iterResult.done) + return ts.Debug.fail("Expected a result."); return iterResult.value; } - export function checkOrphanScriptInfos(service: server.ProjectService, expectedFiles: readonly string[]) { - checkArray("Orphan ScriptInfos:", arrayFrom(mapDefinedIterator( - service.filenameToScriptInfo.values(), - v => v.containingProjects.length === 0 ? v.fileName : undefined - )), expectedFiles); + export function checkOrphanScriptInfos(service: ts.server.ProjectService, expectedFiles: readonly string[]) { + checkArray("Orphan ScriptInfos:", ts.arrayFrom(ts.mapDefinedIterator(service.filenameToScriptInfo.values(), v => v.containingProjects.length === 0 ? v.fileName : undefined)), expectedFiles); } - export function checkProjectActualFiles(project: server.Project, expectedFiles: readonly string[]) { - checkArray(`${server.ProjectKind[project.projectKind]} project: ${project.getProjectName()}:: actual files`, project.getFileNames(), expectedFiles); + export function checkProjectActualFiles(project: ts.server.Project, expectedFiles: readonly string[]) { + checkArray(`${ts.server.ProjectKind[project.projectKind]} project: ${project.getProjectName()}:: actual files`, project.getFileNames(), expectedFiles); } - export function checkProjectRootFiles(project: server.Project, expectedFiles: readonly string[]) { - checkArray(`${server.ProjectKind[project.projectKind]} project: ${project.getProjectName()}::, rootFileNames`, project.getRootFiles(), expectedFiles); + export function checkProjectRootFiles(project: ts.server.Project, expectedFiles: readonly string[]) { + checkArray(`${ts.server.ProjectKind[project.projectKind]} project: ${project.getProjectName()}::, rootFileNames`, project.getRootFiles(), expectedFiles); } export function mapCombinedPathsInAncestor(dir: string, path2: string, mapAncestor: (ancestor: string) => boolean) { - dir = normalizePath(dir); + dir = ts.normalizePath(dir); const result: string[] = []; - forEachAncestorDirectory(dir, ancestor => { + ts.forEachAncestorDirectory(dir, ancestor => { if (mapAncestor(ancestor)) { - result.push(combinePaths(ancestor, path2)); + result.push(ts.combinePaths(ancestor, path2)); } }); return result; } export function getRootsToWatchWithAncestorDirectory(dir: string, path2: string) { - return mapCombinedPathsInAncestor(dir, path2, ancestor => ancestor.split(directorySeparator).length > 4); + return mapCombinedPathsInAncestor(dir, path2, ancestor => ancestor.split(ts.directorySeparator).length > 4); } export const nodeModules = "node_modules"; @@ -522,24 +517,24 @@ namespace ts.projectSystem { ]; } - export function checkOpenFiles(projectService: server.ProjectService, expectedFiles: File[]) { - checkArray("Open files", arrayFrom(projectService.openFiles.keys(), path => projectService.getScriptInfoForPath(path as Path)!.fileName), expectedFiles.map(file => file.path)); + export function checkOpenFiles(projectService: ts.server.ProjectService, expectedFiles: File[]) { + checkArray("Open files", ts.arrayFrom(projectService.openFiles.keys(), path => projectService.getScriptInfoForPath(path as ts.Path)!.fileName), expectedFiles.map(file => file.path)); } - export function checkScriptInfos(projectService: server.ProjectService, expectedFiles: readonly string[], additionInfo?: string) { - checkArray(`ScriptInfos files: ${additionInfo || ""}`, arrayFrom(projectService.filenameToScriptInfo.values(), info => info.fileName), expectedFiles); + export function checkScriptInfos(projectService: ts.server.ProjectService, expectedFiles: readonly string[], additionInfo?: string) { + checkArray(`ScriptInfos files: ${additionInfo || ""}`, ts.arrayFrom(projectService.filenameToScriptInfo.values(), info => info.fileName), expectedFiles); } export function protocolLocationFromSubstring(str: string, substring: string, options?: SpanFromSubstringOptions): protocol.Location { const start = nthIndexOf(str, substring, options ? options.index : 0); - Debug.assert(start !== -1); + ts.Debug.assert(start !== -1); return protocolToLocation(str)(start); } export function protocolToLocation(text: string): (pos: number) => protocol.Location { - const lineStarts = computeLineStarts(text); + const lineStarts = ts.computeLineStarts(text); return pos => { - const x = computeLineAndCharacterOfPosition(lineStarts, pos); + const x = ts.computeLineAndCharacterOfPosition(lineStarts, pos); return { line: x.line + 1, offset: x.character + 1 }; }; } @@ -547,7 +542,7 @@ namespace ts.projectSystem { export function protocolTextSpanFromSubstring(str: string, substring: string, options?: SpanFromSubstringOptions): protocol.TextSpan { const span = textSpanFromSubstring(str, substring, options); const toLocation = protocolToLocation(str); - return { start: toLocation(span.start), end: toLocation(textSpanEnd(span)) }; + return { start: toLocation(span.start), end: toLocation(ts.textSpanEnd(span)) }; } export interface DocumentSpanFromSubstring { @@ -595,10 +590,10 @@ namespace ts.projectSystem { const contextSpan = contextText !== undefined ? textSpanFromSubstring(fileText, contextText, contextOptions) : undefined; return { start: toLocation(span.start), - end: toLocation(textSpanEnd(span)), + end: toLocation(ts.textSpanEnd(span)), ...contextSpan && { contextStart: toLocation(contextSpan.start), - contextEnd: toLocation(textSpanEnd(contextSpan)) + contextEnd: toLocation(ts.textSpanEnd(contextSpan)) } }; } @@ -616,10 +611,10 @@ namespace ts.projectSystem { }; } - export function textSpanFromSubstring(str: string, substring: string, options?: SpanFromSubstringOptions): TextSpan { + export function textSpanFromSubstring(str: string, substring: string, options?: SpanFromSubstringOptions): ts.TextSpan { const start = nthIndexOf(str, substring, options ? options.index : 0); - Debug.assert(start !== -1); - return createTextSpan(start, substring.length); + ts.Debug.assert(start !== -1); + return ts.createTextSpan(start, substring.length); } export function protocolFileLocationFromSubstring(file: File, substring: string, options?: SpanFromSubstringOptions): protocol.FileLocationRequestArgs { @@ -634,7 +629,8 @@ namespace ts.projectSystem { let index = -1; for (; n >= 0; n--) { index = str.indexOf(substr, index + 1); - if (index === -1) return -1; + if (index === -1) + return -1; } return index; } @@ -645,7 +641,7 @@ namespace ts.projectSystem { * should be made before canceling the token. The id of the request to cancel should be set with * setRequestToCancel(); */ - export class TestServerCancellationToken implements server.ServerCancellationToken { + export class TestServerCancellationToken implements ts.server.ServerCancellationToken { private currentId: number | undefined = -1; private requestToCancel = -1; private isCancellationRequestedCount = 0; @@ -691,22 +687,25 @@ namespace ts.projectSystem { }; } - export function executeSessionRequest(session: server.Session, command: TRequest["command"], args: TRequest["arguments"]): TResponse["body"] { + export function executeSessionRequest(session: ts.server.Session, command: TRequest["command"], args: TRequest["arguments"]): TResponse["body"] { return session.executeCommand(makeSessionRequest(command, args)).response as TResponse["body"]; } - export function executeSessionRequestNoResponse(session: server.Session, command: TRequest["command"], args: TRequest["arguments"]): void { + export function executeSessionRequestNoResponse(session: ts.server.Session, command: TRequest["command"], args: TRequest["arguments"]): void { session.executeCommand(makeSessionRequest(command, args)); } - export function openFilesForSession(files: readonly (File | { readonly file: File | string, readonly projectRootPath: string, content?: string })[], session: server.Session): void { + export function openFilesForSession(files: readonly (File | { + readonly file: File | string; + readonly projectRootPath: string; + content?: string; + })[], session: ts.server.Session): void { for (const file of files) { - session.executeCommand(makeSessionRequest(CommandNames.Open, - "projectRootPath" in file ? { file: typeof file.file === "string" ? file.file : file.file.path, projectRootPath: file.projectRootPath } : { file: file.path })); // eslint-disable-line no-in-operator + session.executeCommand(makeSessionRequest(CommandNames.Open, "projectRootPath" in file ? { file: typeof file.file === "string" ? file.file : file.file.path, projectRootPath: file.projectRootPath } : { file: file.path })); // eslint-disable-line no-in-operator } } - export function closeFilesForSession(files: readonly File[], session: server.Session): void { + export function closeFilesForSession(files: readonly File[], session: ts.server.Session): void { for (const file of files) { session.executeCommand(makeSessionRequest(CommandNames.Close, { file: file.path })); } @@ -745,13 +744,17 @@ namespace ts.projectSystem { checkAllErrors(request); } - interface SkipErrors { semantic?: true; suggestion?: true }; + interface SkipErrors { + semantic?: true; + suggestion?: true; + } + ; export interface CheckAllErrors extends VerifyGetErrRequestBase { files: readonly any[]; skip?: readonly (SkipErrors | undefined)[]; } function checkAllErrors({ session, host, existingTimeouts, files, skip }: CheckAllErrors) { - Debug.assert(session.logger.logs.length); + ts.Debug.assert(session.logger.logs.length); for (let i = 0; i < files.length; i++) { if (existingTimeouts !== undefined) { host.checkTimeoutQueueLength(existingTimeouts + 1); @@ -760,13 +763,15 @@ namespace ts.projectSystem { else { host.checkTimeoutQueueLengthAndRun(1); } - if (!skip?.[i]?.semantic) host.runQueuedImmediateCallbacks(1); - if (!skip?.[i]?.suggestion) host.runQueuedImmediateCallbacks(1); + if (!skip?.[i]?.semantic) + host.runQueuedImmediateCallbacks(1); + if (!skip?.[i]?.suggestion) + host.runQueuedImmediateCallbacks(1); } } function filePath(file: string | File) { - return isString(file) ? file : file.path; + return ts.isString(file) ? file : file.path; } function verifyErrorsUsingGeterr({scenario, subScenario, allFiles, openFiles, getErrRequest }: VerifyGetErrScenario) { diff --git a/src/testRunner/unittests/tsserver/importHelpers.ts b/src/testRunner/unittests/tsserver/importHelpers.ts index b1ec5955eaae4..de2311274185f 100644 --- a/src/testRunner/unittests/tsserver/importHelpers.ts +++ b/src/testRunner/unittests/tsserver/importHelpers.ts @@ -9,9 +9,9 @@ namespace ts.projectSystem { path: "/a/node_modules/tslib/index.d.ts", content: "" }; - const host = createServerHost([f1, tslib]); - const service = createProjectService(host); - service.openExternalProject({ projectFileName: "p", rootFiles: [toExternalFile(f1.path)], options: { importHelpers: true } }); + const host = ts.projectSystem.createServerHost([f1, tslib]); + const service = ts.projectSystem.createProjectService(host); + service.openExternalProject({ projectFileName: "p", rootFiles: [ts.projectSystem.toExternalFile(f1.path)], options: { importHelpers: true } }); service.checkNumberOfProjects({ externalProjects: 1 }); }); }); diff --git a/src/testRunner/unittests/tsserver/inferredProjects.ts b/src/testRunner/unittests/tsserver/inferredProjects.ts index be7238323fe58..e36adae6b13e0 100644 --- a/src/testRunner/unittests/tsserver/inferredProjects.ts +++ b/src/testRunner/unittests/tsserver/inferredProjects.ts @@ -1,41 +1,41 @@ namespace ts.projectSystem { describe("unittests:: tsserver:: Inferred projects", () => { it("create inferred project", () => { - const appFile: File = { - path: `${tscWatch.projectRoot}/app.ts`, + const appFile: ts.projectSystem.File = { + path: `${ts.tscWatch.projectRoot}/app.ts`, content: ` import {f} from "./module" console.log(f) ` }; - const moduleFile: File = { - path: `${tscWatch.projectRoot}/module.d.ts`, + const moduleFile: ts.projectSystem.File = { + path: `${ts.tscWatch.projectRoot}/module.d.ts`, content: `export let x: number` }; - const host = createServerHost([appFile, moduleFile, libFile]); - const projectService = createProjectService(host); + const host = ts.projectSystem.createServerHost([appFile, moduleFile, ts.projectSystem.libFile]); + const projectService = ts.projectSystem.createProjectService(host); const { configFileName } = projectService.openClientFile(appFile.path); assert(!configFileName, `should not find config, got: '${configFileName}`); - checkNumberOfConfiguredProjects(projectService, 0); - checkNumberOfInferredProjects(projectService, 1); + ts.projectSystem.checkNumberOfConfiguredProjects(projectService, 0); + ts.projectSystem.checkNumberOfInferredProjects(projectService, 1); const project = projectService.inferredProjects[0]; - checkArray("inferred project", project.getFileNames(), [appFile.path, libFile.path, moduleFile.path]); - checkWatchedFiles(host, getConfigFilesToWatch(tscWatch.projectRoot).concat(libFile.path, moduleFile.path)); - checkWatchedDirectories(host, [tscWatch.projectRoot], /*recursive*/ false); - checkWatchedDirectories(host, [combinePaths(tscWatch.projectRoot, nodeModulesAtTypes)], /*recursive*/ true); + ts.projectSystem.checkArray("inferred project", project.getFileNames(), [appFile.path, ts.projectSystem.libFile.path, moduleFile.path]); + ts.projectSystem.checkWatchedFiles(host, ts.projectSystem.getConfigFilesToWatch(ts.tscWatch.projectRoot).concat(ts.projectSystem.libFile.path, moduleFile.path)); + ts.projectSystem.checkWatchedDirectories(host, [ts.tscWatch.projectRoot], /*recursive*/ false); + ts.projectSystem.checkWatchedDirectories(host, [ts.combinePaths(ts.tscWatch.projectRoot, ts.projectSystem.nodeModulesAtTypes)], /*recursive*/ true); }); it("should use only one inferred project if 'useOneInferredProject' is set", () => { const file1 = { - path: `${tscWatch.projectRoot}/a/b/main.ts`, + path: `${ts.tscWatch.projectRoot}/a/b/main.ts`, content: "let x =1;" }; - const configFile: File = { - path: `${tscWatch.projectRoot}/a/b/tsconfig.json`, + const configFile: ts.projectSystem.File = { + path: `${ts.tscWatch.projectRoot}/a/b/tsconfig.json`, content: `{ "compilerOptions": { "target": "es6" @@ -44,31 +44,31 @@ namespace ts.projectSystem { }` }; const file2 = { - path: `${tscWatch.projectRoot}/a/c/main.ts`, + path: `${ts.tscWatch.projectRoot}/a/c/main.ts`, content: "let x =1;" }; const file3 = { - path: `${tscWatch.projectRoot}/a/d/main.ts`, + path: `${ts.tscWatch.projectRoot}/a/d/main.ts`, content: "let x =1;" }; - const host = createServerHost([file1, file2, file3, libFile]); - const projectService = createProjectService(host, { useSingleInferredProject: true }); + const host = ts.projectSystem.createServerHost([file1, file2, file3, ts.projectSystem.libFile]); + const projectService = ts.projectSystem.createProjectService(host, { useSingleInferredProject: true }); projectService.openClientFile(file1.path); projectService.openClientFile(file2.path); projectService.openClientFile(file3.path); - checkNumberOfConfiguredProjects(projectService, 0); - checkNumberOfInferredProjects(projectService, 1); - checkProjectActualFiles(projectService.inferredProjects[0], [file1.path, file2.path, file3.path, libFile.path]); + ts.projectSystem.checkNumberOfConfiguredProjects(projectService, 0); + ts.projectSystem.checkNumberOfInferredProjects(projectService, 1); + ts.projectSystem.checkProjectActualFiles(projectService.inferredProjects[0], [file1.path, file2.path, file3.path, ts.projectSystem.libFile.path]); host.writeFile(configFile.path, configFile.content); host.checkTimeoutQueueLengthAndRun(2); // load configured project from disk + ensureProjectsForOpenFiles - checkNumberOfConfiguredProjects(projectService, 1); - checkNumberOfInferredProjects(projectService, 1); - checkProjectActualFiles(projectService.inferredProjects[0], [file2.path, file3.path, libFile.path]); + ts.projectSystem.checkNumberOfConfiguredProjects(projectService, 1); + ts.projectSystem.checkNumberOfInferredProjects(projectService, 1); + ts.projectSystem.checkProjectActualFiles(projectService.inferredProjects[0], [file2.path, file3.path, ts.projectSystem.libFile.path]); }); it("disable inferred project", () => { @@ -77,12 +77,12 @@ namespace ts.projectSystem { content: "let x =1;" }; - const host = createServerHost([file1]); - const projectService = createProjectService(host, { useSingleInferredProject: true, syntaxOnly: true }); + const host = ts.projectSystem.createServerHost([file1]); + const projectService = ts.projectSystem.createProjectService(host, { useSingleInferredProject: true, syntaxOnly: true }); projectService.openClientFile(file1.path, file1.content); - checkNumberOfProjects(projectService, { inferredProjects: 1 }); + ts.projectSystem.checkNumberOfProjects(projectService, { inferredProjects: 1 }); const proj = projectService.inferredProjects[0]; assert.isDefined(proj); @@ -98,23 +98,22 @@ namespace ts.projectSystem { path: "/a/mod.ts", content: "export let x: number" }; - const host = createServerHost([file1, modFile]); - const projectService = createProjectService(host); + const host = ts.projectSystem.createServerHost([file1, modFile]); + const projectService = ts.projectSystem.createProjectService(host); projectService.openClientFile(file1.path); projectService.openClientFile(modFile.path); - checkNumberOfProjects(projectService, { inferredProjects: 2 }); + ts.projectSystem.checkNumberOfProjects(projectService, { inferredProjects: 2 }); const inferredProjects = projectService.inferredProjects.slice(); - checkProjectActualFiles(inferredProjects[0], [file1.path]); - checkProjectActualFiles(inferredProjects[1], [modFile.path]); - - projectService.setCompilerOptionsForInferredProjects({ moduleResolution: ModuleResolutionKind.Classic }); + ts.projectSystem.checkProjectActualFiles(inferredProjects[0], [file1.path]); + ts.projectSystem.checkProjectActualFiles(inferredProjects[1], [modFile.path]); + projectService.setCompilerOptionsForInferredProjects({ moduleResolution: ts.ModuleResolutionKind.Classic }); host.checkTimeoutQueueLengthAndRun(3); - checkNumberOfProjects(projectService, { inferredProjects: 2 }); + ts.projectSystem.checkNumberOfProjects(projectService, { inferredProjects: 2 }); assert.strictEqual(projectService.inferredProjects[0], inferredProjects[0]); assert.strictEqual(projectService.inferredProjects[1], inferredProjects[1]); - checkProjectActualFiles(inferredProjects[0], [file1.path, modFile.path]); + ts.projectSystem.checkProjectActualFiles(inferredProjects[0], [file1.path, modFile.path]); assert.isTrue(inferredProjects[1].isOrphan()); }); @@ -123,8 +122,8 @@ namespace ts.projectSystem { path: "/a/compile", content: "let x = 1" }; - const host = createServerHost([f]); - const session = createSession(host); + const host = ts.projectSystem.createServerHost([f]); + const session = ts.projectSystem.createSession(host); session.executeCommand({ seq: 1, type: "request", @@ -134,7 +133,7 @@ namespace ts.projectSystem { allowJs: true } } - } as server.protocol.SetCompilerOptionsForInferredProjectsRequest); + } as ts.server.protocol.SetCompilerOptionsForInferredProjectsRequest); session.executeCommand({ seq: 2, type: "request", @@ -144,10 +143,10 @@ namespace ts.projectSystem { fileContent: f.content, scriptKindName: "JS" } - } as server.protocol.OpenRequest); + } as ts.server.protocol.OpenRequest); const projectService = session.getProjectService(); - checkNumberOfProjects(projectService, { inferredProjects: 1 }); - checkProjectActualFiles(projectService.inferredProjects[0], [f.path]); + ts.projectSystem.checkNumberOfProjects(projectService, { inferredProjects: 1 }); + ts.projectSystem.checkProjectActualFiles(projectService.inferredProjects[0], [f.path]); }); it("inferred projects per project root", () => { @@ -155,171 +154,181 @@ namespace ts.projectSystem { const file2 = { path: "/a/file2.ts", content: "let y = 2;", projectRootPath: "/a" }; const file3 = { path: "/b/file2.ts", content: "let x = 3;", projectRootPath: "/b" }; const file4 = { path: "/c/file3.ts", content: "let z = 4;" }; - const host = createServerHost([file1, file2, file3, file4]); - const session = createSession(host, { + const host = ts.projectSystem.createServerHost([file1, file2, file3, file4]); + const session = ts.projectSystem.createSession(host, { useSingleInferredProject: true, useInferredProjectPerProjectRoot: true }); session.executeCommand({ seq: 1, type: "request", - command: CommandNames.CompilerOptionsForInferredProjects, + command: ts.projectSystem.CommandNames.CompilerOptionsForInferredProjects, arguments: { options: { allowJs: true, - target: ScriptTarget.ESNext + target: ts.ScriptTarget.ESNext } } - } as server.protocol.SetCompilerOptionsForInferredProjectsRequest); + } as ts.server.protocol.SetCompilerOptionsForInferredProjectsRequest); session.executeCommand({ seq: 2, type: "request", - command: CommandNames.CompilerOptionsForInferredProjects, + command: ts.projectSystem.CommandNames.CompilerOptionsForInferredProjects, arguments: { options: { allowJs: true, - target: ScriptTarget.ES2015 + target: ts.ScriptTarget.ES2015 }, projectRootPath: "/b" } - } as server.protocol.SetCompilerOptionsForInferredProjectsRequest); + } as ts.server.protocol.SetCompilerOptionsForInferredProjectsRequest); session.executeCommand({ seq: 3, type: "request", - command: CommandNames.Open, + command: ts.projectSystem.CommandNames.Open, arguments: { file: file1.path, fileContent: file1.content, scriptKindName: "JS", projectRootPath: file1.projectRootPath } - } as server.protocol.OpenRequest); + } as ts.server.protocol.OpenRequest); session.executeCommand({ seq: 4, type: "request", - command: CommandNames.Open, + command: ts.projectSystem.CommandNames.Open, arguments: { file: file2.path, fileContent: file2.content, scriptKindName: "JS", projectRootPath: file2.projectRootPath } - } as server.protocol.OpenRequest); + } as ts.server.protocol.OpenRequest); session.executeCommand({ seq: 5, type: "request", - command: CommandNames.Open, + command: ts.projectSystem.CommandNames.Open, arguments: { file: file3.path, fileContent: file3.content, scriptKindName: "JS", projectRootPath: file3.projectRootPath } - } as server.protocol.OpenRequest); + } as ts.server.protocol.OpenRequest); session.executeCommand({ seq: 6, type: "request", - command: CommandNames.Open, + command: ts.projectSystem.CommandNames.Open, arguments: { file: file4.path, fileContent: file4.content, scriptKindName: "JS" } - } as server.protocol.OpenRequest); + } as ts.server.protocol.OpenRequest); const projectService = session.getProjectService(); - checkNumberOfProjects(projectService, { inferredProjects: 3 }); - checkProjectActualFiles(projectService.inferredProjects[0], [file4.path]); - checkProjectActualFiles(projectService.inferredProjects[1], [file1.path, file2.path]); - checkProjectActualFiles(projectService.inferredProjects[2], [file3.path]); - assert.equal(projectService.inferredProjects[0].getCompilationSettings().target, ScriptTarget.ESNext); - assert.equal(projectService.inferredProjects[1].getCompilationSettings().target, ScriptTarget.ESNext); - assert.equal(projectService.inferredProjects[2].getCompilationSettings().target, ScriptTarget.ES2015); + ts.projectSystem.checkNumberOfProjects(projectService, { inferredProjects: 3 }); + ts.projectSystem.checkProjectActualFiles(projectService.inferredProjects[0], [file4.path]); + ts.projectSystem.checkProjectActualFiles(projectService.inferredProjects[1], [file1.path, file2.path]); + ts.projectSystem.checkProjectActualFiles(projectService.inferredProjects[2], [file3.path]); + assert.equal(projectService.inferredProjects[0].getCompilationSettings().target, ts.ScriptTarget.ESNext); + assert.equal(projectService.inferredProjects[1].getCompilationSettings().target, ts.ScriptTarget.ESNext); + assert.equal(projectService.inferredProjects[2].getCompilationSettings().target, ts.ScriptTarget.ES2015); }); - function checkInferredProject(inferredProject: server.InferredProject, actualFiles: File[], target: ScriptTarget) { - checkProjectActualFiles(inferredProject, actualFiles.map(f => f.path)); + function checkInferredProject(inferredProject: ts.server.InferredProject, actualFiles: ts.projectSystem.File[], target: ts.ScriptTarget) { + ts.projectSystem.checkProjectActualFiles(inferredProject, actualFiles.map(f => f.path)); assert.equal(inferredProject.getCompilationSettings().target, target); } function verifyProjectRootWithCaseSensitivity(useCaseSensitiveFileNames: boolean) { - const files: [File, File, File, File] = [ + const files: [ + ts.projectSystem.File, + ts.projectSystem.File, + ts.projectSystem.File, + ts.projectSystem.File + ] = [ { path: "/a/file1.ts", content: "let x = 1;" }, { path: "/A/file2.ts", content: "let y = 2;" }, { path: "/b/file2.ts", content: "let x = 3;" }, { path: "/c/file3.ts", content: "let z = 4;" } ]; - const host = createServerHost(files, { useCaseSensitiveFileNames }); - const projectService = createProjectService(host, { useSingleInferredProject: true, useInferredProjectPerProjectRoot: true }); + const host = ts.projectSystem.createServerHost(files, { useCaseSensitiveFileNames }); + const projectService = ts.projectSystem.createProjectService(host, { useSingleInferredProject: true, useInferredProjectPerProjectRoot: true }); projectService.setCompilerOptionsForInferredProjects({ allowJs: true, - target: ScriptTarget.ESNext + target: ts.ScriptTarget.ESNext }); projectService.setCompilerOptionsForInferredProjects({ allowJs: true, - target: ScriptTarget.ES2015 + target: ts.ScriptTarget.ES2015 }, "/a"); openClientFiles(["/a", "/a", "/b", undefined]); verifyInferredProjectsState([ - [[files[3]], ScriptTarget.ESNext], - [[files[0], files[1]], ScriptTarget.ES2015], - [[files[2]], ScriptTarget.ESNext] + [[files[3]], ts.ScriptTarget.ESNext], + [[files[0], files[1]], ts.ScriptTarget.ES2015], + [[files[2]], ts.ScriptTarget.ESNext] ]); closeClientFiles(); openClientFiles(["/a", "/A", "/b", undefined]); if (useCaseSensitiveFileNames) { verifyInferredProjectsState([ - [[files[3]], ScriptTarget.ESNext], - [[files[0]], ScriptTarget.ES2015], - [[files[1]], ScriptTarget.ESNext], - [[files[2]], ScriptTarget.ESNext] + [[files[3]], ts.ScriptTarget.ESNext], + [[files[0]], ts.ScriptTarget.ES2015], + [[files[1]], ts.ScriptTarget.ESNext], + [[files[2]], ts.ScriptTarget.ESNext] ]); } else { verifyInferredProjectsState([ - [[files[3]], ScriptTarget.ESNext], - [[files[0], files[1]], ScriptTarget.ES2015], - [[files[2]], ScriptTarget.ESNext] + [[files[3]], ts.ScriptTarget.ESNext], + [[files[0], files[1]], ts.ScriptTarget.ES2015], + [[files[2]], ts.ScriptTarget.ESNext] ]); } closeClientFiles(); projectService.setCompilerOptionsForInferredProjects({ allowJs: true, - target: ScriptTarget.ES2017 + target: ts.ScriptTarget.ES2017 }, "/A"); openClientFiles(["/a", "/a", "/b", undefined]); verifyInferredProjectsState([ - [[files[3]], ScriptTarget.ESNext], - [[files[0], files[1]], useCaseSensitiveFileNames ? ScriptTarget.ES2015 : ScriptTarget.ES2017], - [[files[2]], ScriptTarget.ESNext] + [[files[3]], ts.ScriptTarget.ESNext], + [[files[0], files[1]], useCaseSensitiveFileNames ? ts.ScriptTarget.ES2015 : ts.ScriptTarget.ES2017], + [[files[2]], ts.ScriptTarget.ESNext] ]); closeClientFiles(); openClientFiles(["/a", "/A", "/b", undefined]); if (useCaseSensitiveFileNames) { verifyInferredProjectsState([ - [[files[3]], ScriptTarget.ESNext], - [[files[0]], ScriptTarget.ES2015], - [[files[1]], ScriptTarget.ES2017], - [[files[2]], ScriptTarget.ESNext] + [[files[3]], ts.ScriptTarget.ESNext], + [[files[0]], ts.ScriptTarget.ES2015], + [[files[1]], ts.ScriptTarget.ES2017], + [[files[2]], ts.ScriptTarget.ESNext] ]); } else { verifyInferredProjectsState([ - [[files[3]], ScriptTarget.ESNext], - [[files[0], files[1]], ScriptTarget.ES2017], - [[files[2]], ScriptTarget.ESNext] + [[files[3]], ts.ScriptTarget.ESNext], + [[files[0], files[1]], ts.ScriptTarget.ES2017], + [[files[2]], ts.ScriptTarget.ESNext] ]); } closeClientFiles(); - function openClientFiles(projectRoots: [string | undefined, string | undefined, string | undefined, string | undefined]) { + function openClientFiles(projectRoots: [ + string | undefined, + string | undefined, + string | undefined, + string | undefined + ]) { files.forEach((file, index) => { - projectService.openClientFile(file.path, file.content, ScriptKind.JS, projectRoots[index]); + projectService.openClientFile(file.path, file.content, ts.ScriptKind.JS, projectRoots[index]); }); } @@ -327,8 +336,11 @@ namespace ts.projectSystem { files.forEach(file => projectService.closeClientFile(file.path)); } - function verifyInferredProjectsState(expected: [File[], ScriptTarget][]) { - checkNumberOfProjects(projectService, { inferredProjects: expected.length }); + function verifyInferredProjectsState(expected: [ + ts.projectSystem.File[], + ts.ScriptTarget + ][]) { + ts.projectSystem.checkNumberOfProjects(projectService, { inferredProjects: expected.length }); projectService.inferredProjects.forEach((p, index) => { const [actualFiles, target] = expected[index]; checkInferredProject(p, actualFiles, target); @@ -345,28 +357,28 @@ namespace ts.projectSystem { }); it("should still retain configured project created while opening the file", () => { - const appFile: File = { - path: `${tscWatch.projectRoot}/app.ts`, + const appFile: ts.projectSystem.File = { + path: `${ts.tscWatch.projectRoot}/app.ts`, content: `const app = 20;` }; - const config: File = { - path: `${tscWatch.projectRoot}/tsconfig.json`, + const config: ts.projectSystem.File = { + path: `${ts.tscWatch.projectRoot}/tsconfig.json`, content: "{}" }; - const jsFile1: File = { - path: `${tscWatch.projectRoot}/jsFile1.js`, + const jsFile1: ts.projectSystem.File = { + path: `${ts.tscWatch.projectRoot}/jsFile1.js`, content: `const jsFile1 = 10;` }; - const jsFile2: File = { - path: `${tscWatch.projectRoot}/jsFile2.js`, + const jsFile2: ts.projectSystem.File = { + path: `${ts.tscWatch.projectRoot}/jsFile2.js`, content: `const jsFile2 = 10;` }; - const host = createServerHost([appFile, libFile, config, jsFile1, jsFile2]); - const projectService = createProjectService(host); + const host = ts.projectSystem.createServerHost([appFile, ts.projectSystem.libFile, config, jsFile1, jsFile2]); + const projectService = ts.projectSystem.createProjectService(host); const originalSet = projectService.configuredProjects.set; const originalDelete = projectService.configuredProjects.delete; - const configuredCreated = new Map(); - const configuredRemoved = new Map(); + const configuredCreated = new ts.Map(); + const configuredRemoved = new ts.Map(); projectService.configuredProjects.set = (key, value) => { assert.isFalse(configuredCreated.has(key)); configuredCreated.set(key, true); @@ -380,34 +392,34 @@ namespace ts.projectSystem { // Do not remove config project when opening jsFile that is not present as part of config project projectService.openClientFile(jsFile1.path); - checkNumberOfProjects(projectService, { inferredProjects: 1, configuredProjects: 1 }); - checkProjectActualFiles(projectService.inferredProjects[0], [jsFile1.path, libFile.path]); + ts.projectSystem.checkNumberOfProjects(projectService, { inferredProjects: 1, configuredProjects: 1 }); + ts.projectSystem.checkProjectActualFiles(projectService.inferredProjects[0], [jsFile1.path, ts.projectSystem.libFile.path]); const project = projectService.configuredProjects.get(config.path)!; - checkProjectActualFiles(project, [appFile.path, config.path, libFile.path]); + ts.projectSystem.checkProjectActualFiles(project, [appFile.path, config.path, ts.projectSystem.libFile.path]); checkConfiguredProjectCreatedAndNotDeleted(); // Do not remove config project when opening jsFile that is not present as part of config project projectService.closeClientFile(jsFile1.path); - checkNumberOfProjects(projectService, { inferredProjects: 1, configuredProjects: 1 }); + ts.projectSystem.checkNumberOfProjects(projectService, { inferredProjects: 1, configuredProjects: 1 }); projectService.openClientFile(jsFile2.path); - checkNumberOfProjects(projectService, { inferredProjects: 1, configuredProjects: 1 }); - checkProjectActualFiles(projectService.inferredProjects[0], [jsFile2.path, libFile.path]); - checkProjectActualFiles(project, [appFile.path, config.path, libFile.path]); + ts.projectSystem.checkNumberOfProjects(projectService, { inferredProjects: 1, configuredProjects: 1 }); + ts.projectSystem.checkProjectActualFiles(projectService.inferredProjects[0], [jsFile2.path, ts.projectSystem.libFile.path]); + ts.projectSystem.checkProjectActualFiles(project, [appFile.path, config.path, ts.projectSystem.libFile.path]); checkConfiguredProjectNotCreatedAndNotDeleted(); // Do not remove config project when opening jsFile that is not present as part of config project projectService.openClientFile(jsFile1.path); - checkNumberOfProjects(projectService, { inferredProjects: 2, configuredProjects: 1 }); - checkProjectActualFiles(projectService.inferredProjects[0], [jsFile2.path, libFile.path]); - checkProjectActualFiles(projectService.inferredProjects[1], [jsFile1.path, libFile.path]); - checkProjectActualFiles(project, [appFile.path, config.path, libFile.path]); + ts.projectSystem.checkNumberOfProjects(projectService, { inferredProjects: 2, configuredProjects: 1 }); + ts.projectSystem.checkProjectActualFiles(projectService.inferredProjects[0], [jsFile2.path, ts.projectSystem.libFile.path]); + ts.projectSystem.checkProjectActualFiles(projectService.inferredProjects[1], [jsFile1.path, ts.projectSystem.libFile.path]); + ts.projectSystem.checkProjectActualFiles(project, [appFile.path, config.path, ts.projectSystem.libFile.path]); checkConfiguredProjectNotCreatedAndNotDeleted(); // When opening file that doesnt fall back to the config file, we remove the config project - projectService.openClientFile(libFile.path); - checkNumberOfProjects(projectService, { inferredProjects: 2 }); - checkProjectActualFiles(projectService.inferredProjects[0], [jsFile2.path, libFile.path]); - checkProjectActualFiles(projectService.inferredProjects[1], [jsFile1.path, libFile.path]); + projectService.openClientFile(ts.projectSystem.libFile.path); + ts.projectSystem.checkNumberOfProjects(projectService, { inferredProjects: 2 }); + ts.projectSystem.checkProjectActualFiles(projectService.inferredProjects[0], [jsFile2.path, ts.projectSystem.libFile.path]); + ts.projectSystem.checkProjectActualFiles(projectService.inferredProjects[1], [jsFile1.path, ts.projectSystem.libFile.path]); checkConfiguredProjectNotCreatedButDeleted(); function checkConfiguredProjectCreatedAndNotDeleted() { @@ -432,15 +444,14 @@ namespace ts.projectSystem { it("regression test - should infer typeAcquisition for inferred projects when set undefined", () => { const file1 = { path: "/a/file1.js", content: "" }; - const host = createServerHost([file1]); - - const projectService = createProjectService(host); + const host = ts.projectSystem.createServerHost([file1]); + const projectService = ts.projectSystem.createProjectService(host); projectService.openClientFile(file1.path); - checkNumberOfProjects(projectService, { inferredProjects: 1 }); + ts.projectSystem.checkNumberOfProjects(projectService, { inferredProjects: 1 }); const inferredProject = projectService.inferredProjects[0]; - checkProjectActualFiles(inferredProject, [file1.path]); + ts.projectSystem.checkProjectActualFiles(inferredProject, [file1.path]); inferredProject.setTypeAcquisition(undefined); const expected = { @@ -452,11 +463,11 @@ namespace ts.projectSystem { }); it("Setting compiler options for inferred projects when there are no open files should not schedule any refresh", () => { - const host = createServerHost([commonFile1, libFile]); - const projectService = createProjectService(host); + const host = ts.projectSystem.createServerHost([ts.projectSystem.commonFile1, ts.projectSystem.libFile]); + const projectService = ts.projectSystem.createProjectService(host); projectService.setCompilerOptionsForInferredProjects({ allowJs: true, - target: ScriptTarget.ES2015 + target: ts.ScriptTarget.ES2015 }); host.checkTimeoutQueueLength(0); }); diff --git a/src/testRunner/unittests/tsserver/inlayHints.ts b/src/testRunner/unittests/tsserver/inlayHints.ts index 837bc9c452e6a..94e738c8c762a 100644 --- a/src/testRunner/unittests/tsserver/inlayHints.ts +++ b/src/testRunner/unittests/tsserver/inlayHints.ts @@ -1,62 +1,62 @@ namespace ts.projectSystem { describe("unittests:: tsserver:: inlayHints", () => { - const configFile: File = { + const configFile: ts.projectSystem.File = { path: "/a/b/tsconfig.json", content: "{}" }; - const app: File = { + const app: ts.projectSystem.File = { path: "/a/b/app.ts", content: "declare function foo(param: any): void;\nfoo(12);" }; it("with updateOpen request does not corrupt documents", () => { - const host = createServerHost([app, commonFile1, commonFile2, libFile, configFile]); - const session = createSession(host); - session.executeCommandSeq({ - command: protocol.CommandTypes.Open, + const host = ts.projectSystem.createServerHost([app, ts.projectSystem.commonFile1, ts.projectSystem.commonFile2, ts.projectSystem.libFile, configFile]); + const session = ts.projectSystem.createSession(host); + session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.Open, arguments: { file: app.path } }); - session.executeCommandSeq({ - command: protocol.CommandTypes.Configure, + session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.Configure, arguments: { preferences: { includeInlayParameterNameHints: "all" - } as UserPreferences + } as ts.UserPreferences } }); verifyInlayHintResponse(session); - session.executeCommandSeq({ - command: protocol.CommandTypes.UpdateOpen, + session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.UpdateOpen, arguments: { changedFiles: [{ fileName: app.path, textChanges: [{ start: { line: 1, offset: 39 }, end: { line: 1, offset: 39 }, newText: "//" }] }] } }); verifyInlayHintResponse(session); - session.executeCommandSeq({ - command: protocol.CommandTypes.UpdateOpen, + session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.UpdateOpen, arguments: { changedFiles: [{ fileName: app.path, textChanges: [{ start: { line: 1, offset: 41 }, end: { line: 1, offset: 41 }, newText: "c" }] }] } }); verifyInlayHintResponse(session); - function verifyInlayHintResponse(session: TestSession) { - verifyParamInlayHint(session.executeCommandSeq({ - command: protocol.CommandTypes.ProvideInlayHints, + function verifyInlayHintResponse(session: ts.projectSystem.TestSession) { + verifyParamInlayHint(session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.ProvideInlayHints, arguments: { file: app.path, start: 0, length: app.content.length, } - }).response as protocol.InlayHintItem[] | undefined); + }).response as ts.projectSystem.protocol.InlayHintItem[] | undefined); } - function verifyParamInlayHint(response: protocol.InlayHintItem[] | undefined) { - Debug.assert(response); - Debug.assert(response[0]); - Debug.assertEqual(response[0].text, "param:"); - Debug.assertEqual(response[0].position.line, 2); - Debug.assertEqual(response[0].position.offset, 5); + function verifyParamInlayHint(response: ts.projectSystem.protocol.InlayHintItem[] | undefined) { + ts.Debug.assert(response); + ts.Debug.assert(response[0]); + ts.Debug.assertEqual(response[0].text, "param:"); + ts.Debug.assertEqual(response[0].position.line, 2); + ts.Debug.assertEqual(response[0].position.offset, 5); } }); }); diff --git a/src/testRunner/unittests/tsserver/jsdocTag.ts b/src/testRunner/unittests/tsserver/jsdocTag.ts index 7699c107586e2..a90fc1771d694 100644 --- a/src/testRunner/unittests/tsserver/jsdocTag.ts +++ b/src/testRunner/unittests/tsserver/jsdocTag.ts @@ -1,6 +1,6 @@ namespace ts.projectSystem { describe("unittests:: tsserver:: jsdoc @link ", () => { - const config: File = { + const config: ts.projectSystem.File = { path: "/a/tsconfig.json", content: `{ "compilerOptions": { @@ -11,26 +11,26 @@ namespace ts.projectSystem { } ` }; - function assertQuickInfoJSDoc(file: File, options: { - displayPartsForJSDoc: boolean, - command: protocol.CommandTypes, - tags: string | unknown[] | undefined, - documentation: string | unknown[] + function assertQuickInfoJSDoc(file: ts.projectSystem.File, options: { + displayPartsForJSDoc: boolean; + command: ts.projectSystem.protocol.CommandTypes; + tags: string | unknown[] | undefined; + documentation: string | unknown[]; }) { const { command, displayPartsForJSDoc, tags, documentation } = options; - const session = createSession(createServerHost([file, config])); + const session = ts.projectSystem.createSession(ts.projectSystem.createServerHost([file, config])); session.getProjectService().setHostConfiguration({ preferences: { displayPartsForJSDoc } }); - openFilesForSession([file], session); + ts.projectSystem.openFilesForSession([file], session); const indexOfX = file.content.indexOf("x"); - const quickInfo = session.executeCommandSeq({ - command: command as protocol.CommandTypes.Quickinfo, + const quickInfo = session.executeCommandSeq({ + command: command as ts.projectSystem.protocol.CommandTypes.Quickinfo, arguments: { file: file.path, position: indexOfX, - } as protocol.FileLocationRequestArgs + } as ts.projectSystem.protocol.FileLocationRequestArgs }).response; - const summaryAndLocation = command === protocol.CommandTypes.Quickinfo ? { + const summaryAndLocation = command === ts.projectSystem.protocol.CommandTypes.Quickinfo ? { displayString: "var x: number", start: { line: 3, @@ -74,13 +74,13 @@ namespace ts.projectSystem { }); } - const linkInTag: File = { + const linkInTag: ts.projectSystem.File = { path: "/a/someFile1.js", content: `class C { } /** @wat {@link C} */ var x = 1` }; - const linkInComment: File = { + const linkInComment: ts.projectSystem.File = { path: "/a/someFile1.js", content: `class C { } /** {@link C} */ @@ -90,7 +90,7 @@ var x = 1 it("for quickinfo, should provide display parts plus a span for a working link in a tag", () => { assertQuickInfoJSDoc(linkInTag, { - command: protocol.CommandTypes.Quickinfo, + command: ts.projectSystem.protocol.CommandTypes.Quickinfo, displayPartsForJSDoc: true, documentation: [], tags: [{ @@ -124,7 +124,7 @@ var x = 1 }); it("for quickinfo, should provide a string for a working link in a tag", () => { assertQuickInfoJSDoc(linkInTag, { - command: protocol.CommandTypes.Quickinfo, + command: ts.projectSystem.protocol.CommandTypes.Quickinfo, displayPartsForJSDoc: false, documentation: "", tags: [{ @@ -135,7 +135,7 @@ var x = 1 }); it("for quickinfo, should provide display parts for a working link in a comment", () => { assertQuickInfoJSDoc(linkInComment, { - command: protocol.CommandTypes.Quickinfo, + command: ts.projectSystem.protocol.CommandTypes.Quickinfo, displayPartsForJSDoc: true, documentation: [{ kind: "text", @@ -166,7 +166,7 @@ var x = 1 }); it("for quickinfo, should provide a string for a working link in a comment", () => { assertQuickInfoJSDoc(linkInComment, { - command: protocol.CommandTypes.Quickinfo, + command: ts.projectSystem.protocol.CommandTypes.Quickinfo, displayPartsForJSDoc: false, documentation: "{@link C}", tags: [], @@ -175,7 +175,7 @@ var x = 1 it("for quickinfo-full, should provide display parts plus a span for a working link in a tag", () => { assertQuickInfoJSDoc(linkInTag, { - command: protocol.CommandTypes.QuickinfoFull, + command: ts.projectSystem.protocol.CommandTypes.QuickinfoFull, displayPartsForJSDoc: true, documentation: [], tags: [{ @@ -205,7 +205,7 @@ var x = 1 }); it("for quickinfo-full, should provide a string for a working link in a tag", () => { assertQuickInfoJSDoc(linkInTag, { - command: protocol.CommandTypes.QuickinfoFull, + command: ts.projectSystem.protocol.CommandTypes.QuickinfoFull, displayPartsForJSDoc: false, documentation: [], tags: [{ @@ -216,7 +216,7 @@ var x = 1 }); it("for quickinfo-full, should provide display parts plus a span for a working link in a comment", () => { assertQuickInfoJSDoc(linkInComment, { - command: protocol.CommandTypes.QuickinfoFull, + command: ts.projectSystem.protocol.CommandTypes.QuickinfoFull, displayPartsForJSDoc: true, documentation: [{ kind: "text", @@ -243,7 +243,7 @@ var x = 1 }); it("for quickinfo-full, should provide a string for a working link in a comment", () => { assertQuickInfoJSDoc(linkInComment, { - command: protocol.CommandTypes.QuickinfoFull, + command: ts.projectSystem.protocol.CommandTypes.QuickinfoFull, displayPartsForJSDoc: false, documentation: [{ kind: "text", @@ -270,12 +270,12 @@ var x = 1 }); function assertSignatureHelpJSDoc(options: { - displayPartsForJSDoc: boolean, - command: protocol.CommandTypes, - documentation: string | unknown[], - tags: unknown[] + displayPartsForJSDoc: boolean; + command: ts.projectSystem.protocol.CommandTypes; + documentation: string | unknown[]; + tags: unknown[]; }) { - const linkInParamTag: File = { + const linkInParamTag: ts.projectSystem.File = { path: "/a/someFile1.js", content: `class C { } /** @param y - {@link C} */ @@ -284,21 +284,21 @@ x(1)` }; const { command, displayPartsForJSDoc, documentation, tags } = options; - const session = createSession(createServerHost([linkInParamTag, config])); + const session = ts.projectSystem.createSession(ts.projectSystem.createServerHost([linkInParamTag, config])); session.getProjectService().setHostConfiguration({ preferences: { displayPartsForJSDoc } }); - openFilesForSession([linkInParamTag], session); + ts.projectSystem.openFilesForSession([linkInParamTag], session); const indexOfX = linkInParamTag.content.lastIndexOf("1"); - const signatureHelp = session.executeCommandSeq({ - command: command as protocol.CommandTypes.SignatureHelp, + const signatureHelp = session.executeCommandSeq({ + command: command as ts.projectSystem.protocol.CommandTypes.SignatureHelp, arguments: { triggerReason: { kind: "invoked" }, file: linkInParamTag.path, position: indexOfX, - } as protocol.SignatureHelpRequestArgs + } as ts.projectSystem.protocol.SignatureHelpRequestArgs }).response; - const applicableSpan = command === protocol.CommandTypes.SignatureHelp ? { + const applicableSpan = command === ts.projectSystem.protocol.CommandTypes.SignatureHelp ? { end: { line: 4, offset: 4 @@ -382,7 +382,7 @@ x(1)` } it("for signature help, should provide a string for a working link in a comment", () => { assertSignatureHelpJSDoc({ - command: protocol.CommandTypes.SignatureHelp, + command: ts.projectSystem.protocol.CommandTypes.SignatureHelp, displayPartsForJSDoc: false, tags: [{ name: "param", @@ -449,7 +449,7 @@ x(1)` }] }]; assertSignatureHelpJSDoc({ - command: protocol.CommandTypes.SignatureHelp, + command: ts.projectSystem.protocol.CommandTypes.SignatureHelp, displayPartsForJSDoc: true, tags, documentation: tags[0].text.slice(2) @@ -457,7 +457,7 @@ x(1)` }); it("for signature help-full, should provide a string for a working link in a comment", () => { assertSignatureHelpJSDoc({ - command: protocol.CommandTypes.SignatureHelpFull, + command: ts.projectSystem.protocol.CommandTypes.SignatureHelpFull, displayPartsForJSDoc: false, tags: [{ name: "param", @@ -516,7 +516,7 @@ x(1)` }] }]; assertSignatureHelpJSDoc({ - command: protocol.CommandTypes.SignatureHelpFull, + command: ts.projectSystem.protocol.CommandTypes.SignatureHelpFull, displayPartsForJSDoc: true, tags, documentation: tags[0].text.slice(2), @@ -524,11 +524,11 @@ x(1)` }); function assertCompletionsJSDoc(options: { - displayPartsForJSDoc: boolean, - command: protocol.CommandTypes, - tags: unknown[] + displayPartsForJSDoc: boolean; + command: ts.projectSystem.protocol.CommandTypes; + tags: unknown[]; }) { - const linkInParamJSDoc: File = { + const linkInParamJSDoc: ts.projectSystem.File = { path: "/a/someFile1.js", content: `class C { } /** @param x - see {@link C} */ @@ -536,17 +536,17 @@ function foo (x) { } foo` }; const { command, displayPartsForJSDoc, tags } = options; - const session = createSession(createServerHost([linkInParamJSDoc, config])); + const session = ts.projectSystem.createSession(ts.projectSystem.createServerHost([linkInParamJSDoc, config])); session.getProjectService().setHostConfiguration({ preferences: { displayPartsForJSDoc } }); - openFilesForSession([linkInParamJSDoc], session); + ts.projectSystem.openFilesForSession([linkInParamJSDoc], session); const indexOfFoo = linkInParamJSDoc.content.lastIndexOf("fo"); - const completions = session.executeCommandSeq({ - command: command as protocol.CommandTypes.CompletionDetails, + const completions = session.executeCommandSeq({ + command: command as ts.projectSystem.protocol.CommandTypes.CompletionDetails, arguments: { entryNames: ["foo"], file: linkInParamJSDoc.path, position: indexOfFoo, - } as protocol.CompletionDetailsRequestArgs + } as ts.projectSystem.protocol.CompletionDetailsRequestArgs }).response; assert.deepEqual(completions, [{ codeActions: undefined, @@ -598,7 +598,7 @@ foo` } it("for completions, should provide display parts for a working link in a comment", () => { assertCompletionsJSDoc({ - command: protocol.CommandTypes.CompletionDetails, + command: ts.projectSystem.protocol.CommandTypes.CompletionDetails, displayPartsForJSDoc: true, tags: [{ name: "param", @@ -637,7 +637,7 @@ foo` }); it("for completions, should provide a string for a working link in a comment", () => { assertCompletionsJSDoc({ - command: protocol.CommandTypes.CompletionDetails, + command: ts.projectSystem.protocol.CommandTypes.CompletionDetails, displayPartsForJSDoc: false, tags: [{ name: "param", @@ -647,7 +647,7 @@ foo` }); it("for completions-full, should provide display parts for a working link in a comment", () => { assertCompletionsJSDoc({ - command: protocol.CommandTypes.CompletionDetailsFull, + command: ts.projectSystem.protocol.CommandTypes.CompletionDetailsFull, displayPartsForJSDoc: true, tags: [{ name: "param", @@ -682,7 +682,7 @@ foo` }); it("for completions-full, should provide a string for a working link in a comment", () => { assertCompletionsJSDoc({ - command: protocol.CommandTypes.CompletionDetailsFull, + command: ts.projectSystem.protocol.CommandTypes.CompletionDetailsFull, displayPartsForJSDoc: false, tags: [{ name: "param", diff --git a/src/testRunner/unittests/tsserver/languageService.ts b/src/testRunner/unittests/tsserver/languageService.ts index 8e7bf0eedcdaa..898a542826b3a 100644 --- a/src/testRunner/unittests/tsserver/languageService.ts +++ b/src/testRunner/unittests/tsserver/languageService.ts @@ -9,8 +9,8 @@ namespace ts.projectSystem { path: "/a/b/app.ts", content: "let x = 1;" }; - const host = createServerHost([lib, f], { executingFilePath: "/a/Lib/tsc.js", useCaseSensitiveFileNames: true }); - const projectService = createProjectService(host); + const host = ts.projectSystem.createServerHost([lib, f], { executingFilePath: "/a/Lib/tsc.js", useCaseSensitiveFileNames: true }); + const projectService = ts.projectSystem.createProjectService(host); projectService.openClientFile(f.path); projectService.checkNumberOfProjects({ inferredProjects: 1 }); projectService.inferredProjects[0].getLanguageService().getProgram(); @@ -54,15 +54,15 @@ namespace ts.projectSystem { } ]; - const host = createServerHost(files, { executingFilePath: "/project/tsc.js", useCaseSensitiveFileNames: true }); - const projectService = createProjectService(host); + const host = ts.projectSystem.createServerHost(files, { executingFilePath: "/project/tsc.js", useCaseSensitiveFileNames: true }); + const projectService = ts.projectSystem.createProjectService(host); projectService.openClientFile(files[3].path); projectService.openClientFile(files[6].path); projectService.checkNumberOfProjects({ configuredProjects: 2 }); const proj1Diags = projectService.configuredProjects.get(files[1].path)!.getLanguageService().getProgram()!.getSemanticDiagnostics(); - Debug.assertEqual(proj1Diags.length, 0); + ts.Debug.assertEqual(proj1Diags.length, 0); const proj2Diags = projectService.configuredProjects.get(files[4].path)!.getLanguageService().getProgram()!.getSemanticDiagnostics(); - Debug.assertEqual(proj2Diags.length, 1); + ts.Debug.assertEqual(proj2Diags.length, 1); }); }); } diff --git a/src/testRunner/unittests/tsserver/maxNodeModuleJsDepth.ts b/src/testRunner/unittests/tsserver/maxNodeModuleJsDepth.ts index eb254789d671e..47ea8f170aa66 100644 --- a/src/testRunner/unittests/tsserver/maxNodeModuleJsDepth.ts +++ b/src/testRunner/unittests/tsserver/maxNodeModuleJsDepth.ts @@ -1,17 +1,17 @@ namespace ts.projectSystem { describe("unittests:: tsserver:: maxNodeModuleJsDepth for inferred projects", () => { it("should be set to 2 if the project has js root files", () => { - const file1: File = { + const file1: ts.projectSystem.File = { path: "/a/b/file1.js", content: `var t = require("test"); t.` }; - const moduleFile: File = { + const moduleFile: ts.projectSystem.File = { path: "/a/b/node_modules/test/index.js", content: `var v = 10; module.exports = v;` }; - const host = createServerHost([file1, moduleFile]); - const projectService = createProjectService(host); + const host = ts.projectSystem.createServerHost([file1, moduleFile]); + const projectService = ts.projectSystem.createProjectService(host); projectService.openClientFile(file1.path); let project = projectService.inferredProjects[0]; @@ -19,7 +19,7 @@ namespace ts.projectSystem { assert.isTrue(options.maxNodeModuleJsDepth === 2); // Assert the option sticks - projectService.setCompilerOptionsForInferredProjects({ target: ScriptTarget.ES2016 }); + projectService.setCompilerOptionsForInferredProjects({ target: ts.ScriptTarget.ES2016 }); project = projectService.inferredProjects[0]; options = project.getCompilationSettings(); assert.isTrue(options.maxNodeModuleJsDepth === 2); @@ -35,11 +35,11 @@ namespace ts.projectSystem { content: "let x =1;" }; - const host = createServerHost([file1, file2, libFile]); - const projectService = createProjectService(host, { useSingleInferredProject: true }); + const host = ts.projectSystem.createServerHost([file1, file2, ts.projectSystem.libFile]); + const projectService = ts.projectSystem.createProjectService(host, { useSingleInferredProject: true }); projectService.openClientFile(file1.path); - checkNumberOfInferredProjects(projectService, 1); + ts.projectSystem.checkNumberOfInferredProjects(projectService, 1); let project = projectService.inferredProjects[0]; assert.isUndefined(project.getCompilationSettings().maxNodeModuleJsDepth); diff --git a/src/testRunner/unittests/tsserver/metadataInResponse.ts b/src/testRunner/unittests/tsserver/metadataInResponse.ts index 8ea9d5ff7f742..081264ac9bb11 100644 --- a/src/testRunner/unittests/tsserver/metadataInResponse.ts +++ b/src/testRunner/unittests/tsserver/metadataInResponse.ts @@ -1,36 +1,35 @@ namespace ts.projectSystem { describe("unittests:: tsserver:: with metadata in response", () => { const metadata = "Extra Info"; - function verifyOutput(host: TestServerHost, expectedResponse: protocol.Response) { - const output = host.getOutput().map(mapOutputToJson); + function verifyOutput(host: ts.projectSystem.TestServerHost, expectedResponse: ts.projectSystem.protocol.Response) { + const output = host.getOutput().map(ts.projectSystem.mapOutputToJson); assert.deepEqual(output, [expectedResponse]); host.clearOutput(); } - function verifyCommandWithMetadata(session: TestSession, host: TestServerHost, command: Partial, expectedResponseBody: U) { + function verifyCommandWithMetadata(session: ts.projectSystem.TestSession, host: ts.projectSystem.TestServerHost, command: Partial, expectedResponseBody: U) { command.seq = session.getSeq(); command.type = "request"; session.onMessage(JSON.stringify(command)); verifyOutput(host, expectedResponseBody ? { seq: 0, type: "response", command: command.command!, request_seq: command.seq, success: true, body: expectedResponseBody, metadata } : - { seq: 0, type: "response", command: command.command!, request_seq: command.seq, success: false, message: "No content available." } - ); + { seq: 0, type: "response", command: command.command!, request_seq: command.seq, success: false, message: "No content available." }); } - const aTs: File = { path: "/a.ts", content: `class c { prop = "hello"; foo() { return this.prop; } }` }; - const tsconfig: File = { + const aTs: ts.projectSystem.File = { path: "/a.ts", content: `class c { prop = "hello"; foo() { return this.prop; } }` }; + const tsconfig: ts.projectSystem.File = { path: "/tsconfig.json", content: JSON.stringify({ compilerOptions: { plugins: [{ name: "myplugin" }] } }) }; - function createHostWithPlugin(files: readonly File[]) { - const host = createServerHost(files); + function createHostWithPlugin(files: readonly ts.projectSystem.File[]) { + const host = ts.projectSystem.createServerHost(files); host.require = (_initialPath, moduleName) => { assert.equal(moduleName, "myplugin"); return { module: () => ({ - create(info: server.PluginCreateInfo) { + create(info: ts.server.PluginCreateInfo) { const proxy = Harness.LanguageService.makeDefaultProxy(info); proxy.getCompletionsAtPosition = (filename, position, options) => { const result = info.languageService.getCompletionsAtPosition(filename, position, options); @@ -49,32 +48,32 @@ namespace ts.projectSystem { } describe("With completion requests", () => { - const completionRequestArgs: protocol.CompletionsRequestArgs = { + const completionRequestArgs: ts.projectSystem.protocol.CompletionsRequestArgs = { file: aTs.path, line: 1, offset: aTs.content.indexOf("this.") + 1 + "this.".length }; - const expectedCompletionEntries: readonly protocol.CompletionEntry[] = [ - { name: "foo", kind: ScriptElementKind.memberFunctionElement, kindModifiers: "", sortText: Completions.SortText.LocationPriority }, - { name: "prop", kind: ScriptElementKind.memberVariableElement, kindModifiers: "", sortText: Completions.SortText.LocationPriority } + const expectedCompletionEntries: readonly ts.projectSystem.protocol.CompletionEntry[] = [ + { name: "foo", kind: ts.ScriptElementKind.memberFunctionElement, kindModifiers: "", sortText: ts.Completions.SortText.LocationPriority }, + { name: "prop", kind: ts.ScriptElementKind.memberVariableElement, kindModifiers: "", sortText: ts.Completions.SortText.LocationPriority } ]; it("can pass through metadata when the command returns array", () => { const host = createHostWithPlugin([aTs, tsconfig]); - const session = createSession(host); - openFilesForSession([aTs], session); - verifyCommandWithMetadata(session, host, { - command: protocol.CommandTypes.Completions, + const session = ts.projectSystem.createSession(host); + ts.projectSystem.openFilesForSession([aTs], session); + verifyCommandWithMetadata(session, host, { + command: ts.projectSystem.protocol.CommandTypes.Completions, arguments: completionRequestArgs }, expectedCompletionEntries); }); it("can pass through metadata when the command returns object", () => { const host = createHostWithPlugin([aTs, tsconfig]); - const session = createSession(host); - openFilesForSession([aTs], session); - verifyCommandWithMetadata(session, host, { - command: protocol.CommandTypes.CompletionInfo, + const session = ts.projectSystem.createSession(host); + ts.projectSystem.openFilesForSession([aTs], session); + verifyCommandWithMetadata(session, host, { + command: ts.projectSystem.protocol.CommandTypes.CompletionInfo, arguments: completionRequestArgs }, { flags: 0, @@ -90,12 +89,12 @@ namespace ts.projectSystem { }); it("returns undefined correctly", () => { - const aTs: File = { path: "/a.ts", content: `class c { prop = "hello"; foo() { const x = 0; } }` }; + const aTs: ts.projectSystem.File = { path: "/a.ts", content: `class c { prop = "hello"; foo() { const x = 0; } }` }; const host = createHostWithPlugin([aTs, tsconfig]); - const session = createSession(host); - openFilesForSession([aTs], session); - verifyCommandWithMetadata(session, host, { - command: protocol.CommandTypes.Completions, + const session = ts.projectSystem.createSession(host); + ts.projectSystem.openFilesForSession([aTs], session); + verifyCommandWithMetadata(session, host, { + command: ts.projectSystem.protocol.CommandTypes.Completions, arguments: { file: aTs.path, line: 1, offset: aTs.content.indexOf("x") + 1 } }, /*expectedResponseBody*/ undefined); }); diff --git a/src/testRunner/unittests/tsserver/moduleSpecifierCache.ts b/src/testRunner/unittests/tsserver/moduleSpecifierCache.ts index e86cd6a694e1b..aaaf72f1a4ef9 100644 --- a/src/testRunner/unittests/tsserver/moduleSpecifierCache.ts +++ b/src/testRunner/unittests/tsserver/moduleSpecifierCache.ts @@ -1,37 +1,37 @@ namespace ts.projectSystem { - const packageJson: File = { + const packageJson: ts.projectSystem.File = { path: "/package.json", content: `{ "dependencies": { "mobx": "*" } }` }; - const aTs: File = { + const aTs: ts.projectSystem.File = { path: "/src/a.ts", content: "export const foo = 0;", }; - const bTs: File = { + const bTs: ts.projectSystem.File = { path: "/src/b.ts", content: "foo", }; - const cTs: File = { + const cTs: ts.projectSystem.File = { path: "/src/c.ts", content: "import ", }; - const bSymlink: SymLink = { + const bSymlink: ts.projectSystem.SymLink = { path: "/src/b-link.ts", symLink: "./b.ts", }; - const tsconfig: File = { + const tsconfig: ts.projectSystem.File = { path: "/tsconfig.json", content: `{ "include": ["src"] }`, }; - const ambientDeclaration: File = { + const ambientDeclaration: ts.projectSystem.File = { path: "/src/ambient.d.ts", content: "declare module 'ambient' {}" }; - const mobxPackageJson: File = { + const mobxPackageJson: ts.projectSystem.File = { path: "/node_modules/mobx/package.json", content: `{ "name": "mobx", "version": "1.0.0" }` }; - const mobxDts: File = { + const mobxDts: ts.projectSystem.File = { path: "/node_modules/mobx/index.d.ts", content: "export declare function observable(): unknown;" }; @@ -39,14 +39,14 @@ namespace ts.projectSystem { describe("unittests:: tsserver:: moduleSpecifierCache", () => { it("caches importability within a file", () => { const { moduleSpecifierCache } = setup(); - assert.isFalse(moduleSpecifierCache.get(bTs.path as Path, aTs.path as Path, {}, {})?.isBlockedByPackageJsonDependencies); + assert.isFalse(moduleSpecifierCache.get(bTs.path as ts.Path, aTs.path as ts.Path, {}, {})?.isBlockedByPackageJsonDependencies); }); it("caches module specifiers within a file", () => { const { moduleSpecifierCache, triggerCompletions } = setup(); // Completion at an import statement will calculate and cache module specifiers triggerCompletions({ file: cTs.path, line: 1, offset: cTs.content.length + 1 }); - const mobxCache = moduleSpecifierCache.get(cTs.path as Path, mobxDts.path as Path, {}, {}); + const mobxCache = moduleSpecifierCache.get(cTs.path as ts.Path, mobxDts.path as ts.Path, {}, {}); assert.deepEqual(mobxCache, { modulePaths: [{ path: mobxDts.path, @@ -62,7 +62,7 @@ namespace ts.projectSystem { const { host, moduleSpecifierCache, triggerCompletions } = setup(); // Completion at an import statement will calculate and cache module specifiers triggerCompletions({ file: cTs.path, line: 1, offset: cTs.content.length + 1 }); - checkWatchedDirectories(host, ["/src", "/node_modules"], /*recursive*/ true); + ts.projectSystem.checkWatchedDirectories(host, ["/src", "/node_modules"], /*recursive*/ true); host.writeFile("/node_modules/.staging/mobx-12345678/package.json", "{}"); host.runQueuedTimeoutCallbacks(); assert.equal(moduleSpecifierCache.count(), 0); @@ -72,7 +72,7 @@ namespace ts.projectSystem { const { host, moduleSpecifierCache } = setup(); host.writeFile("/src/a2.ts", aTs.content); host.runQueuedTimeoutCallbacks(); - assert.isFalse(moduleSpecifierCache.get(bTs.path as Path, aTs.path as Path, {}, {})?.isBlockedByPackageJsonDependencies); + assert.isFalse(moduleSpecifierCache.get(bTs.path as ts.Path, aTs.path as ts.Path, {}, {})?.isBlockedByPackageJsonDependencies); }); it("invalidates the cache when symlinks are added or removed", () => { @@ -98,10 +98,10 @@ namespace ts.projectSystem { it("invalidates the cache when user preferences change", () => { const { moduleSpecifierCache, session, triggerCompletions } = setup(); - const preferences: UserPreferences = { importModuleSpecifierPreference: "project-relative" }; + const preferences: ts.UserPreferences = { importModuleSpecifierPreference: "project-relative" }; assert.ok(getWithPreferences({})); - executeSessionRequest(session, protocol.CommandTypes.Configure, { preferences }); + ts.projectSystem.executeSessionRequest(session, ts.projectSystem.protocol.CommandTypes.Configure, { preferences }); // Nothing changes yet assert.ok(getWithPreferences({})); assert.isUndefined(getWithPreferences(preferences)); @@ -111,25 +111,25 @@ namespace ts.projectSystem { assert.ok(getWithPreferences(preferences)); // Test other affecting preference - executeSessionRequest(session, protocol.CommandTypes.Configure, { + ts.projectSystem.executeSessionRequest(session, ts.projectSystem.protocol.CommandTypes.Configure, { preferences: { importModuleSpecifierEnding: "js" }, }); triggerCompletions({ file: bTs.path, line: 1, offset: 3 }); assert.isUndefined(getWithPreferences(preferences)); - function getWithPreferences(preferences: UserPreferences) { - return moduleSpecifierCache.get(bTs.path as Path, aTs.path as Path, preferences, {}); + function getWithPreferences(preferences: ts.UserPreferences) { + return moduleSpecifierCache.get(bTs.path as ts.Path, aTs.path as ts.Path, preferences, {}); } }); }); function setup() { - const host = createServerHost([aTs, bTs, cTs, bSymlink, ambientDeclaration, tsconfig, packageJson, mobxPackageJson, mobxDts]); - const session = createSession(host); - openFilesForSession([aTs, bTs, cTs], session); + const host = ts.projectSystem.createServerHost([aTs, bTs, cTs, bSymlink, ambientDeclaration, tsconfig, packageJson, mobxPackageJson, mobxDts]); + const session = ts.projectSystem.createSession(host); + ts.projectSystem.openFilesForSession([aTs, bTs, cTs], session); const projectService = session.getProjectService(); - const project = configuredProjectAt(projectService, 0); - executeSessionRequest(session, protocol.CommandTypes.Configure, { + const project = ts.projectSystem.configuredProjectAt(projectService, 0); + ts.projectSystem.executeSessionRequest(session, ts.projectSystem.protocol.CommandTypes.Configure, { preferences: { includeCompletionsForImportStatements: true, includeCompletionsForModuleExports: true, @@ -141,8 +141,8 @@ namespace ts.projectSystem { return { host, project, projectService, session, moduleSpecifierCache: project.getModuleSpecifierCache(), triggerCompletions }; - function triggerCompletions(requestLocation: protocol.FileLocationRequestArgs) { - executeSessionRequest(session, protocol.CommandTypes.CompletionInfo, { + function triggerCompletions(requestLocation: ts.projectSystem.protocol.FileLocationRequestArgs) { + ts.projectSystem.executeSessionRequest(session, ts.projectSystem.protocol.CommandTypes.CompletionInfo, { ...requestLocation, }); } diff --git a/src/testRunner/unittests/tsserver/navTo.ts b/src/testRunner/unittests/tsserver/navTo.ts index eeebca75263fd..01be0002cfe7a 100644 --- a/src/testRunner/unittests/tsserver/navTo.ts +++ b/src/testRunner/unittests/tsserver/navTo.ts @@ -1,38 +1,38 @@ namespace ts.projectSystem { describe("unittests:: tsserver:: navigate-to for javascript project", () => { - function findNavToItem(items: protocol.NavtoItem[], itemName: string, itemKind: string) { - return find(items, item => item.name === itemName && item.kind === itemKind); + function findNavToItem(items: ts.projectSystem.protocol.NavtoItem[], itemName: string, itemKind: string) { + return ts.find(items, item => item.name === itemName && item.kind === itemKind); } - function containsNavToItem(items: protocol.NavtoItem[], itemName: string, itemKind: string) { + function containsNavToItem(items: ts.projectSystem.protocol.NavtoItem[], itemName: string, itemKind: string) { return findNavToItem(items, itemName, itemKind) !== undefined; } it("should not include type symbols", () => { - const file1: File = { + const file1: ts.projectSystem.File = { path: "/a/b/file1.js", content: "function foo() {}" }; - const configFile: File = { + const configFile: ts.projectSystem.File = { path: "/a/b/jsconfig.json", content: "{}" }; - const host = createServerHost([file1, configFile, libFile]); - const session = createSession(host); - openFilesForSession([file1], session); + const host = ts.projectSystem.createServerHost([file1, configFile, ts.projectSystem.libFile]); + const session = ts.projectSystem.createSession(host); + ts.projectSystem.openFilesForSession([file1], session); // Try to find some interface type defined in lib.d.ts - const libTypeNavToRequest = makeSessionRequest(CommandNames.Navto, { searchValue: "Document", file: file1.path, projectFileName: configFile.path }); - const items = session.executeCommand(libTypeNavToRequest).response as protocol.NavtoItem[]; + const libTypeNavToRequest = ts.projectSystem.makeSessionRequest(ts.projectSystem.CommandNames.Navto, { searchValue: "Document", file: file1.path, projectFileName: configFile.path }); + const items = session.executeCommand(libTypeNavToRequest).response as ts.projectSystem.protocol.NavtoItem[]; assert.isFalse(containsNavToItem(items, "Document", "interface"), `Found lib.d.ts symbol in JavaScript project nav to request result.`); - const localFunctionNavToRequst = makeSessionRequest(CommandNames.Navto, { searchValue: "foo", file: file1.path, projectFileName: configFile.path }); - const items2 = session.executeCommand(localFunctionNavToRequst).response as protocol.NavtoItem[]; + const localFunctionNavToRequst = ts.projectSystem.makeSessionRequest(ts.projectSystem.CommandNames.Navto, { searchValue: "foo", file: file1.path, projectFileName: configFile.path }); + const items2 = session.executeCommand(localFunctionNavToRequst).response as ts.projectSystem.protocol.NavtoItem[]; assert.isTrue(containsNavToItem(items2, "foo", "function"), `Cannot find function symbol "foo".`); }); it("should de-duplicate symbols", () => { - const configFile1: File = { + const configFile1: ts.projectSystem.File = { path: "/a/tsconfig.json", content: `{ "compilerOptions": { @@ -40,11 +40,11 @@ namespace ts.projectSystem { } }` }; - const file1: File = { + const file1: ts.projectSystem.File = { path: "/a/index.ts", content: "export const abcdef = 1;" }; - const configFile2: File = { + const configFile2: ts.projectSystem.File = { path: "/b/tsconfig.json", content: `{ "compilerOptions": { @@ -55,30 +55,28 @@ namespace ts.projectSystem { ] }` }; - const file2: File = { + const file2: ts.projectSystem.File = { path: "/b/index.ts", content: `import a = require("../a"); export const ghijkl = a.abcdef;` }; - const host = createServerHost([configFile1, file1, configFile2, file2]); - const session = createSession(host, { logger: createLoggerWithInMemoryLogs() }); - openFilesForSession([file1, file2], session); - - const request = makeSessionRequest(CommandNames.Navto, { searchValue: "abcdef", file: file1.path }); - session.executeCommand(request).response as protocol.NavtoItem[]; - - baselineTsserverLogs("navTo", "should de-duplicate symbols", session); + const host = ts.projectSystem.createServerHost([configFile1, file1, configFile2, file2]); + const session = ts.projectSystem.createSession(host, { logger: ts.projectSystem.createLoggerWithInMemoryLogs() }); + ts.projectSystem.openFilesForSession([file1, file2], session); + const request = ts.projectSystem.makeSessionRequest(ts.projectSystem.CommandNames.Navto, { searchValue: "abcdef", file: file1.path }); + session.executeCommand(request).response as ts.projectSystem.protocol.NavtoItem[]; + ts.projectSystem.baselineTsserverLogs("navTo", "should de-duplicate symbols", session); }); it("should de-duplicate symbols when searching all projects", () => { - const solutionConfig: File = { + const solutionConfig: ts.projectSystem.File = { path: "/tsconfig.json", content: JSON.stringify({ references: [{ path: "./a" }, { path: "./b" }], files: [], }) }; - const configFile1: File = { + const configFile1: ts.projectSystem.File = { path: "/a/tsconfig.json", content: `{ "compilerOptions": { @@ -86,11 +84,11 @@ export const ghijkl = a.abcdef;` } }` }; - const file1: File = { + const file1: ts.projectSystem.File = { path: "/a/index.ts", content: "export const abcdef = 1;" }; - const configFile2: File = { + const configFile2: ts.projectSystem.File = { path: "/b/tsconfig.json", content: `{ "compilerOptions": { @@ -101,36 +99,35 @@ export const ghijkl = a.abcdef;` ] }` }; - const file2: File = { + const file2: ts.projectSystem.File = { path: "/b/index.ts", content: `import a = require("../a"); export const ghijkl = a.abcdef;` }; - const host = createServerHost([configFile1, file1, configFile2, file2, solutionConfig]); - const session = createSession(host, { logger: createLoggerWithInMemoryLogs() }); - openFilesForSession([file1], session); - - const request = makeSessionRequest(CommandNames.Navto, { searchValue: "abcdef" }); - session.executeCommand(request).response as protocol.NavtoItem[]; - baselineTsserverLogs("navTo", "should de-duplicate symbols when searching all projects", session); + const host = ts.projectSystem.createServerHost([configFile1, file1, configFile2, file2, solutionConfig]); + const session = ts.projectSystem.createSession(host, { logger: ts.projectSystem.createLoggerWithInMemoryLogs() }); + ts.projectSystem.openFilesForSession([file1], session); + const request = ts.projectSystem.makeSessionRequest(ts.projectSystem.CommandNames.Navto, { searchValue: "abcdef" }); + session.executeCommand(request).response as ts.projectSystem.protocol.NavtoItem[]; + ts.projectSystem.baselineTsserverLogs("navTo", "should de-duplicate symbols when searching all projects", session); }); it("should work with Deprecated", () => { - const file1: File = { + const file1: ts.projectSystem.File = { path: "/a/b/file1.js", content: "/** @deprecated */\nfunction foo () {}" }; - const configFile: File = { + const configFile: ts.projectSystem.File = { path: "/a/b/jsconfig.json", content: "{}" }; - const host = createServerHost([file1, configFile, libFile]); - const session = createSession(host); - openFilesForSession([file1], session); + const host = ts.projectSystem.createServerHost([file1, configFile, ts.projectSystem.libFile]); + const session = ts.projectSystem.createSession(host); + ts.projectSystem.openFilesForSession([file1], session); // Try to find some interface type defined in lib.d.ts - const libTypeNavToRequest = makeSessionRequest(CommandNames.Navto, { searchValue: "foo", file: file1.path, projectFileName: configFile.path }); - const items = session.executeCommand(libTypeNavToRequest).response as protocol.NavtoItem[]; + const libTypeNavToRequest = ts.projectSystem.makeSessionRequest(ts.projectSystem.CommandNames.Navto, { searchValue: "foo", file: file1.path, projectFileName: configFile.path }); + const items = session.executeCommand(libTypeNavToRequest).response as ts.projectSystem.protocol.NavtoItem[]; const fooItem = findNavToItem(items, "foo", "function"); assert.isNotNull(fooItem, `Cannot find function symbol "foo".`); assert.isTrue(fooItem?.kindModifiers?.includes("deprecated")); diff --git a/src/testRunner/unittests/tsserver/occurences.ts b/src/testRunner/unittests/tsserver/occurences.ts index 25dfb3c9e90f2..2e6d66614b66b 100644 --- a/src/testRunner/unittests/tsserver/occurences.ts +++ b/src/testRunner/unittests/tsserver/occurences.ts @@ -1,43 +1,34 @@ namespace ts.projectSystem { describe("unittests:: tsserver:: occurrence highlight on string", () => { it("should be marked if only on string values", () => { - const file1: File = { + const file1: ts.projectSystem.File = { path: "/a/b/file1.ts", content: `let t1 = "div";\nlet t2 = "div";\nlet t3 = { "div": 123 };\nlet t4 = t3["div"];` }; - const host = createServerHost([file1]); - const session = createSession(host); + const host = ts.projectSystem.createServerHost([file1]); + const session = ts.projectSystem.createSession(host); const projectService = session.getProjectService(); projectService.openClientFile(file1.path); { - const highlightRequest = makeSessionRequest( - CommandNames.Occurrences, - { file: file1.path, line: 1, offset: 11 } - ); - const highlightResponse = session.executeCommand(highlightRequest).response as protocol.OccurrencesResponseItem[]; + const highlightRequest = ts.projectSystem.makeSessionRequest(ts.projectSystem.CommandNames.Occurrences, { file: file1.path, line: 1, offset: 11 }); + const highlightResponse = session.executeCommand(highlightRequest).response as ts.projectSystem.protocol.OccurrencesResponseItem[]; const firstOccurence = highlightResponse[0]; assert.isTrue(firstOccurence.isInString, "Highlights should be marked with isInString"); } { - const highlightRequest = makeSessionRequest( - CommandNames.Occurrences, - { file: file1.path, line: 3, offset: 13 } - ); - const highlightResponse = session.executeCommand(highlightRequest).response as protocol.OccurrencesResponseItem[]; + const highlightRequest = ts.projectSystem.makeSessionRequest(ts.projectSystem.CommandNames.Occurrences, { file: file1.path, line: 3, offset: 13 }); + const highlightResponse = session.executeCommand(highlightRequest).response as ts.projectSystem.protocol.OccurrencesResponseItem[]; assert.isTrue(highlightResponse.length === 2); const firstOccurence = highlightResponse[0]; assert.isUndefined(firstOccurence.isInString, "Highlights should not be marked with isInString if on property name"); } { - const highlightRequest = makeSessionRequest( - CommandNames.Occurrences, - { file: file1.path, line: 4, offset: 14 } - ); - const highlightResponse = session.executeCommand(highlightRequest).response as protocol.OccurrencesResponseItem[]; + const highlightRequest = ts.projectSystem.makeSessionRequest(ts.projectSystem.CommandNames.Occurrences, { file: file1.path, line: 4, offset: 14 }); + const highlightResponse = session.executeCommand(highlightRequest).response as ts.projectSystem.protocol.OccurrencesResponseItem[]; assert.isTrue(highlightResponse.length === 2); const firstOccurence = highlightResponse[0]; assert.isUndefined(firstOccurence.isInString, "Highlights should not be marked with isInString if on indexer"); diff --git a/src/testRunner/unittests/tsserver/openFile.ts b/src/testRunner/unittests/tsserver/openFile.ts index 362c6ae16f005..36f93cb54a379 100644 --- a/src/testRunner/unittests/tsserver/openFile.ts +++ b/src/testRunner/unittests/tsserver/openFile.ts @@ -6,10 +6,10 @@ namespace ts.projectSystem { content: "let x = 1" }; const projectFileName = "externalProject"; - const host = createServerHost([f]); - const projectService = createProjectService(host); + const host = ts.projectSystem.createServerHost([f]); + const projectService = ts.projectSystem.createProjectService(host); // create a project - projectService.openExternalProject({ projectFileName, rootFiles: [toExternalFile(f.path)], options: {} }); + projectService.openExternalProject({ projectFileName, rootFiles: [ts.projectSystem.toExternalFile(f.path)], options: {} }); projectService.checkNumberOfProjects({ externalProjects: 1 }); const p = projectService.externalProjects[0]; @@ -23,31 +23,31 @@ namespace ts.projectSystem { projectService.openClientFile(f.path, ""); checkSnapLength(scriptInfo.getSnapshot(), 0); }); - function checkSnapLength(snap: IScriptSnapshot, expectedLength: number) { + function checkSnapLength(snap: ts.IScriptSnapshot, expectedLength: number) { assert.equal(snap.getLength(), expectedLength, "Incorrect snapshot size"); } function verifyOpenFileWorks(useCaseSensitiveFileNames: boolean) { - const file1: File = { + const file1: ts.projectSystem.File = { path: "/a/b/src/app.ts", content: "let x = 10;" }; - const file2: File = { + const file2: ts.projectSystem.File = { path: "/a/B/lib/module2.ts", content: "let z = 10;" }; - const configFile: File = { + const configFile: ts.projectSystem.File = { path: "/a/b/tsconfig.json", content: "" }; - const configFile2: File = { + const configFile2: ts.projectSystem.File = { path: "/a/tsconfig.json", content: "" }; - const host = createServerHost([file1, file2, configFile, configFile2], { + const host = ts.projectSystem.createServerHost([file1, file2, configFile, configFile2], { useCaseSensitiveFileNames }); - const service = createProjectService(host); + const service = ts.projectSystem.createProjectService(host); // Open file1 -> configFile verifyConfigFileName(file1, "/a", configFile); @@ -59,7 +59,7 @@ namespace ts.projectSystem { verifyConfigFileName(file2, "/a/b", useCaseSensitiveFileNames ? configFile2 : configFile); verifyConfigFileName(file2, "/a/B", useCaseSensitiveFileNames ? undefined : configFile); - function verifyConfigFileName(file: File, projectRoot: string, expectedConfigFile: File | undefined) { + function verifyConfigFileName(file: ts.projectSystem.File, projectRoot: string, expectedConfigFile: ts.projectSystem.File | undefined) { const { configFileName } = service.openClientFile(file.path, /*fileContent*/ undefined, /*scriptKind*/ undefined, projectRoot); assert.equal(configFileName, expectedConfigFile && expectedConfigFile.path); service.closeClientFile(file.path); @@ -75,63 +75,63 @@ namespace ts.projectSystem { it("uses existing project even if project refresh is pending", () => { const projectFolder = "/user/someuser/projects/myproject"; - const aFile: File = { + const aFile: ts.projectSystem.File = { path: `${projectFolder}/src/a.ts`, content: "export const x = 0;" }; - const configFile: File = { + const configFile: ts.projectSystem.File = { path: `${projectFolder}/tsconfig.json`, content: "{}" }; - const files = [aFile, configFile, libFile]; - const host = createServerHost(files); - const service = createProjectService(host); - service.openClientFile(aFile.path, /*fileContent*/ undefined, ScriptKind.TS, projectFolder); + const files = [aFile, configFile, ts.projectSystem.libFile]; + const host = ts.projectSystem.createServerHost(files); + const service = ts.projectSystem.createProjectService(host); + service.openClientFile(aFile.path, /*fileContent*/ undefined, ts.ScriptKind.TS, projectFolder); verifyProject(); - const bFile: File = { + const bFile: ts.projectSystem.File = { path: `${projectFolder}/src/b.ts`, content: `export {}; declare module "./a" { export const y: number; }` }; files.push(bFile); host.writeFile(bFile.path, bFile.content); - service.openClientFile(bFile.path, /*fileContent*/ undefined, ScriptKind.TS, projectFolder); + service.openClientFile(bFile.path, /*fileContent*/ undefined, ts.ScriptKind.TS, projectFolder); verifyProject(); function verifyProject() { assert.isDefined(service.configuredProjects.get(configFile.path)); const project = service.configuredProjects.get(configFile.path)!; - checkProjectActualFiles(project, files.map(f => f.path)); + ts.projectSystem.checkProjectActualFiles(project, files.map(f => f.path)); } }); it("can open same file again", () => { const projectFolder = "/user/someuser/projects/myproject"; - const aFile: File = { + const aFile: ts.projectSystem.File = { path: `${projectFolder}/src/a.ts`, content: "export const x = 0;" }; - const configFile: File = { + const configFile: ts.projectSystem.File = { path: `${projectFolder}/tsconfig.json`, content: "{}" }; - const files = [aFile, configFile, libFile]; - const host = createServerHost(files); - const service = createProjectService(host); + const files = [aFile, configFile, ts.projectSystem.libFile]; + const host = ts.projectSystem.createServerHost(files); + const service = ts.projectSystem.createProjectService(host); verifyProject(aFile.content); verifyProject(`${aFile.content}export const y = 10;`); function verifyProject(aFileContent: string) { - service.openClientFile(aFile.path, aFileContent, ScriptKind.TS, projectFolder); + service.openClientFile(aFile.path, aFileContent, ts.ScriptKind.TS, projectFolder); const project = service.configuredProjects.get(configFile.path)!; - checkProjectActualFiles(project, files.map(f => f.path)); + ts.projectSystem.checkProjectActualFiles(project, files.map(f => f.path)); assert.equal(project.getCurrentProgram()?.getSourceFile(aFile.path)!.text, aFileContent); } }); it("when file makes edits to add/remove comment directives, they are handled correcrly", () => { - const file: File = { - path: `${tscWatch.projectRoot}/file.ts`, + const file: ts.projectSystem.File = { + path: `${ts.tscWatch.projectRoot}/file.ts`, content: `const x = 10; function foo() { // @ts-ignore @@ -146,16 +146,16 @@ function bar() { foo(); bar();` }; - const host = createServerHost([file, libFile]); - const session = createSession(host, { canUseEvents: true, logger: createLoggerWithInMemoryLogs() }); - openFilesForSession([file], session); - verifyGetErrRequest({ session, host, files: [file] }); + const host = ts.projectSystem.createServerHost([file, ts.projectSystem.libFile]); + const session = ts.projectSystem.createSession(host, { canUseEvents: true, logger: ts.projectSystem.createLoggerWithInMemoryLogs() }); + ts.projectSystem.openFilesForSession([file], session); + ts.projectSystem.verifyGetErrRequest({ session, host, files: [file] }); // Remove first ts-ignore and check only first error is reported const tsIgnoreComment = `// @ts-ignore`; - const locationOfTsIgnore = protocolTextSpanFromSubstring(file.content, tsIgnoreComment); - session.executeCommandSeq({ - command: protocol.CommandTypes.UpdateOpen, + const locationOfTsIgnore = ts.projectSystem.protocolTextSpanFromSubstring(file.content, tsIgnoreComment); + session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.UpdateOpen, arguments: { changedFiles: [{ fileName: file.path, @@ -166,10 +166,10 @@ bar();` }] } }); - verifyGetErrRequest({ session, host, files: [file] }); + ts.projectSystem.verifyGetErrRequest({ session, host, files: [file] }); // Revert the change and no errors should be reported - session.executeCommandSeq({ - command: protocol.CommandTypes.UpdateOpen, + session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.UpdateOpen, arguments: { changedFiles: [{ fileName: file.path, @@ -180,8 +180,8 @@ bar();` }] } }); - verifyGetErrRequest({ session, host, files: [file] }); - baselineTsserverLogs("openfile", "when file makes edits to add/remove comment directives, they are handled correcrly", session); + ts.projectSystem.verifyGetErrRequest({ session, host, files: [file] }); + ts.projectSystem.baselineTsserverLogs("openfile", "when file makes edits to add/remove comment directives, they are handled correcrly", session); }); }); } diff --git a/src/testRunner/unittests/tsserver/packageJsonInfo.ts b/src/testRunner/unittests/tsserver/packageJsonInfo.ts index b931d984c1275..7a4229a38ce97 100644 --- a/src/testRunner/unittests/tsserver/packageJsonInfo.ts +++ b/src/testRunner/unittests/tsserver/packageJsonInfo.ts @@ -1,5 +1,5 @@ namespace ts.projectSystem { - const tsConfig: File = { + const tsConfig: ts.projectSystem.File = { path: "/tsconfig.json", content: "{}" }; @@ -17,7 +17,7 @@ namespace ts.projectSystem { webpack: "*" } }; - const packageJson: File = { + const packageJson: ts.projectSystem.File = { path: "/package.json", content: JSON.stringify(packageJsonContent, undefined, 2) }; @@ -26,11 +26,11 @@ namespace ts.projectSystem { it("detects new package.json files that are added, caches them, and watches them", () => { // Initialize project without package.json const { projectService, host } = setup([tsConfig]); - assert.isUndefined(projectService.packageJsonCache.getInDirectory("/" as Path)); + assert.isUndefined(projectService.packageJsonCache.getInDirectory("/" as ts.Path)); // Add package.json host.writeFile(packageJson.path, packageJson.content); - let packageJsonInfo = projectService.packageJsonCache.getInDirectory("/" as Path)!; + let packageJsonInfo = projectService.packageJsonCache.getInDirectory("/" as ts.Path)!; assert.ok(packageJsonInfo); assert.ok(packageJsonInfo.dependencies); assert.ok(packageJsonInfo.devDependencies); @@ -42,19 +42,19 @@ namespace ts.projectSystem { ...packageJsonContent, dependencies: undefined })); - packageJsonInfo = projectService.packageJsonCache.getInDirectory("/" as Path)!; + packageJsonInfo = projectService.packageJsonCache.getInDirectory("/" as ts.Path)!; assert.isUndefined(packageJsonInfo.dependencies); }); it("finds package.json on demand, watches for deletion, and removes them from cache", () => { // Initialize project with package.json const { projectService, host } = setup(); - projectService.getPackageJsonsVisibleToFile("/src/whatever/blah.ts" as Path); - assert.ok(projectService.packageJsonCache.getInDirectory("/" as Path)); + projectService.getPackageJsonsVisibleToFile("/src/whatever/blah.ts" as ts.Path); + assert.ok(projectService.packageJsonCache.getInDirectory("/" as ts.Path)); // Delete package.json host.deleteFile(packageJson.path); - assert.isUndefined(projectService.packageJsonCache.getInDirectory("/" as Path)); + assert.isUndefined(projectService.packageJsonCache.getInDirectory("/" as ts.Path)); }); it("finds multiple package.json files when present", () => { @@ -62,20 +62,20 @@ namespace ts.projectSystem { const { projectService, host } = setup(); // Add package.json in /src host.writeFile("/src/package.json", packageJson.content); - assert.lengthOf(projectService.getPackageJsonsVisibleToFile("/a.ts" as Path), 1); - assert.lengthOf(projectService.getPackageJsonsVisibleToFile("/src/b.ts" as Path), 2); + assert.lengthOf(projectService.getPackageJsonsVisibleToFile("/a.ts" as ts.Path), 1); + assert.lengthOf(projectService.getPackageJsonsVisibleToFile("/src/b.ts" as ts.Path), 2); }); it("handles errors in json parsing of package.json", () => { const packageJsonContent = `{ "mod" }`; const { projectService, host } = setup([tsConfig, { path: packageJson.path, content: packageJsonContent }]); - projectService.getPackageJsonsVisibleToFile("/src/whatever/blah.ts" as Path); - const packageJsonInfo = projectService.packageJsonCache.getInDirectory("/" as Path)!; + projectService.getPackageJsonsVisibleToFile("/src/whatever/blah.ts" as ts.Path); + const packageJsonInfo = projectService.packageJsonCache.getInDirectory("/" as ts.Path)!; assert.isFalse(packageJsonInfo.parseable); host.writeFile(packageJson.path, packageJson.content); - projectService.getPackageJsonsVisibleToFile("/src/whatever/blah.ts" as Path); - const packageJsonInfo2 = projectService.packageJsonCache.getInDirectory("/" as Path)!; + projectService.getPackageJsonsVisibleToFile("/src/whatever/blah.ts" as ts.Path); + const packageJsonInfo2 = projectService.packageJsonCache.getInDirectory("/" as ts.Path)!; assert.ok(packageJsonInfo2); assert.ok(packageJsonInfo2.dependencies); assert.ok(packageJsonInfo2.devDependencies); @@ -86,13 +86,13 @@ namespace ts.projectSystem { it("handles empty package.json", () => { const packageJsonContent = ""; const { projectService, host } = setup([tsConfig, { path: packageJson.path, content: packageJsonContent }]); - projectService.getPackageJsonsVisibleToFile("/src/whatever/blah.ts" as Path); - const packageJsonInfo = projectService.packageJsonCache.getInDirectory("/" as Path)!; + projectService.getPackageJsonsVisibleToFile("/src/whatever/blah.ts" as ts.Path); + const packageJsonInfo = projectService.packageJsonCache.getInDirectory("/" as ts.Path)!; assert.isFalse(packageJsonInfo.parseable); host.writeFile(packageJson.path, packageJson.content); - projectService.getPackageJsonsVisibleToFile("/src/whatever/blah.ts" as Path); - const packageJsonInfo2 = projectService.packageJsonCache.getInDirectory("/" as Path)!; + projectService.getPackageJsonsVisibleToFile("/src/whatever/blah.ts" as ts.Path); + const packageJsonInfo2 = projectService.packageJsonCache.getInDirectory("/" as ts.Path)!; assert.ok(packageJsonInfo2); assert.ok(packageJsonInfo2.dependencies); assert.ok(packageJsonInfo2.devDependencies); @@ -101,12 +101,12 @@ namespace ts.projectSystem { }); }); - function setup(files: readonly File[] = [tsConfig, packageJson]) { - const host = createServerHost(files); - const session = createSession(host); + function setup(files: readonly ts.projectSystem.File[] = [tsConfig, packageJson]) { + const host = ts.projectSystem.createServerHost(files); + const session = ts.projectSystem.createSession(host); const projectService = session.getProjectService(); projectService.openClientFile(files[0].path); - const project = configuredProjectAt(projectService, 0); + const project = ts.projectSystem.configuredProjectAt(projectService, 0); return { host, session, project, projectService }; } } diff --git a/src/testRunner/unittests/tsserver/partialSemanticServer.ts b/src/testRunner/unittests/tsserver/partialSemanticServer.ts index 2aee331883dcf..5428a93c35bd2 100644 --- a/src/testRunner/unittests/tsserver/partialSemanticServer.ts +++ b/src/testRunner/unittests/tsserver/partialSemanticServer.ts @@ -1,70 +1,70 @@ namespace ts.projectSystem { describe("unittests:: tsserver:: Semantic operations on partialSemanticServer", () => { function setup() { - const file1: File = { - path: `${tscWatch.projectRoot}/a.ts`, + const file1: ts.projectSystem.File = { + path: `${ts.tscWatch.projectRoot}/a.ts`, content: `import { y, cc } from "./b"; import { something } from "something"; class c { prop = "hello"; foo() { return this.prop; } }` }; - const file2: File = { - path: `${tscWatch.projectRoot}/b.ts`, + const file2: ts.projectSystem.File = { + path: `${ts.tscWatch.projectRoot}/b.ts`, content: `export { cc } from "./c"; import { something } from "something"; export const y = 10;` }; - const file3: File = { - path: `${tscWatch.projectRoot}/c.ts`, + const file3: ts.projectSystem.File = { + path: `${ts.tscWatch.projectRoot}/c.ts`, content: `export const cc = 10;` }; - const something: File = { - path: `${tscWatch.projectRoot}/node_modules/something/index.d.ts`, + const something: ts.projectSystem.File = { + path: `${ts.tscWatch.projectRoot}/node_modules/something/index.d.ts`, content: "export const something = 10;" }; - const configFile: File = { - path: `${tscWatch.projectRoot}/tsconfig.json`, + const configFile: ts.projectSystem.File = { + path: `${ts.tscWatch.projectRoot}/tsconfig.json`, content: "{}" }; - const host = createServerHost([file1, file2, file3, something, libFile, configFile]); - const session = createSession(host, { serverMode: LanguageServiceMode.PartialSemantic, useSingleInferredProject: true }); + const host = ts.projectSystem.createServerHost([file1, file2, file3, something, ts.projectSystem.libFile, configFile]); + const session = ts.projectSystem.createSession(host, { serverMode: ts.LanguageServiceMode.PartialSemantic, useSingleInferredProject: true }); return { host, session, file1, file2, file3, something, configFile }; } it("open files are added to inferred project even if config file is present and semantic operations succeed", () => { const { host, session, file1, file2 } = setup(); const service = session.getProjectService(); - openFilesForSession([file1], session); - checkNumberOfProjects(service, { inferredProjects: 1 }); + ts.projectSystem.openFilesForSession([file1], session); + ts.projectSystem.checkNumberOfProjects(service, { inferredProjects: 1 }); const project = service.inferredProjects[0]; - checkProjectActualFiles(project, [libFile.path, file1.path]); // no imports are resolved + ts.projectSystem.checkProjectActualFiles(project, [ts.projectSystem.libFile.path, file1.path]); // no imports are resolved verifyCompletions(); - openFilesForSession([file2], session); - checkNumberOfProjects(service, { inferredProjects: 1 }); - checkProjectActualFiles(project, [libFile.path, file1.path, file2.path]); + ts.projectSystem.openFilesForSession([file2], session); + ts.projectSystem.checkNumberOfProjects(service, { inferredProjects: 1 }); + ts.projectSystem.checkProjectActualFiles(project, [ts.projectSystem.libFile.path, file1.path, file2.path]); verifyCompletions(); function verifyCompletions() { assert.isTrue(project.languageServiceEnabled); - checkWatchedFiles(host, emptyArray); - checkWatchedDirectories(host, emptyArray, /*recursive*/ true); - checkWatchedDirectories(host, emptyArray, /*recursive*/ false); - const response = session.executeCommandSeq({ - command: protocol.CommandTypes.Completions, - arguments: protocolFileLocationFromSubstring(file1, "prop", { index: 1 }) - }).response as protocol.CompletionEntry[]; + ts.projectSystem.checkWatchedFiles(host, ts.emptyArray); + ts.projectSystem.checkWatchedDirectories(host, ts.emptyArray, /*recursive*/ true); + ts.projectSystem.checkWatchedDirectories(host, ts.emptyArray, /*recursive*/ false); + const response = session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.Completions, + arguments: ts.projectSystem.protocolFileLocationFromSubstring(file1, "prop", { index: 1 }) + }).response as ts.projectSystem.protocol.CompletionEntry[]; assert.deepEqual(response, [ - completionEntry("foo", ScriptElementKind.memberFunctionElement), - completionEntry("prop", ScriptElementKind.memberVariableElement), + completionEntry("foo", ts.ScriptElementKind.memberFunctionElement), + completionEntry("prop", ts.ScriptElementKind.memberVariableElement), ]); } - function completionEntry(name: string, kind: ScriptElementKind): protocol.CompletionEntry { + function completionEntry(name: string, kind: ts.ScriptElementKind): ts.projectSystem.protocol.CompletionEntry { return { name, kind, kindModifiers: "", - sortText: Completions.SortText.LocationPriority, + sortText: ts.Completions.SortText.LocationPriority, hasAction: undefined, insertText: undefined, isPackageJsonImport: undefined, @@ -83,12 +83,12 @@ import { something } from "something"; it("throws on unsupported commands", () => { const { session, file1 } = setup(); const service = session.getProjectService(); - openFilesForSession([file1], session); + ts.projectSystem.openFilesForSession([file1], session); let hasException = false; - const request: protocol.SemanticDiagnosticsSyncRequest = { + const request: ts.projectSystem.protocol.SemanticDiagnosticsSyncRequest = { type: "request", seq: 1, - command: protocol.CommandTypes.SemanticDiagnosticsSync, + command: ts.projectSystem.protocol.CommandTypes.SemanticDiagnosticsSync, arguments: { file: file1.path } }; try { @@ -113,149 +113,149 @@ import { something } from "something"; }); it("allows syntactic diagnostic commands", () => { - const file1: File = { - path: `${tscWatch.projectRoot}/a.ts`, + const file1: ts.projectSystem.File = { + path: `${ts.tscWatch.projectRoot}/a.ts`, content: `if (a < (b + c) { }` }; - const configFile: File = { - path: `${tscWatch.projectRoot}/tsconfig.json`, + const configFile: ts.projectSystem.File = { + path: `${ts.tscWatch.projectRoot}/tsconfig.json`, content: `{}` }; const expectedErrorMessage = "')' expected."; - const host = createServerHost([file1, libFile, configFile]); - const session = createSession(host, { - serverMode: LanguageServiceMode.PartialSemantic, + const host = ts.projectSystem.createServerHost([file1, ts.projectSystem.libFile, configFile]); + const session = ts.projectSystem.createSession(host, { + serverMode: ts.LanguageServiceMode.PartialSemantic, useSingleInferredProject: true, - logger: createLoggerWithInMemoryLogs() + logger: ts.projectSystem.createLoggerWithInMemoryLogs() }); const service = session.getProjectService(); - openFilesForSession([file1], session); - const request: protocol.SyntacticDiagnosticsSyncRequest = { + ts.projectSystem.openFilesForSession([file1], session); + const request: ts.projectSystem.protocol.SyntacticDiagnosticsSyncRequest = { type: "request", seq: 1, - command: protocol.CommandTypes.SyntacticDiagnosticsSync, + command: ts.projectSystem.protocol.CommandTypes.SyntacticDiagnosticsSync, arguments: { file: file1.path } }; - const response = session.executeCommandSeq(request).response as protocol.SyntacticDiagnosticsSyncResponse["body"]; + const response = session.executeCommandSeq(request).response as ts.projectSystem.protocol.SyntacticDiagnosticsSyncResponse["body"]; assert.isDefined(response); assert.equal(response!.length, 1); - assert.equal((response![0] as protocol.Diagnostic).text, expectedErrorMessage); + assert.equal((response![0] as ts.projectSystem.protocol.Diagnostic).text, expectedErrorMessage); const project = service.inferredProjects[0]; const diagnostics = project.getLanguageService().getSyntacticDiagnostics(file1.path); assert.isTrue(diagnostics.length === 1); assert.equal(diagnostics[0].messageText, expectedErrorMessage); - verifyGetErrRequest({ session, host, files: [file1], skip: [{ semantic: true, suggestion: true }] }); - baselineTsserverLogs("partialSemanticServer", "syntactic diagnostics are returned with no error", session); + ts.projectSystem.verifyGetErrRequest({ session, host, files: [file1], skip: [{ semantic: true, suggestion: true }] }); + ts.projectSystem.baselineTsserverLogs("partialSemanticServer", "syntactic diagnostics are returned with no error", session); }); it("should not include auto type reference directives", () => { const { host, session, file1 } = setup(); - const atTypes: File = { + const atTypes: ts.projectSystem.File = { path: `/node_modules/@types/somemodule/index.d.ts`, content: "export const something = 10;" }; host.ensureFileOrFolder(atTypes); const service = session.getProjectService(); - openFilesForSession([file1], session); - checkNumberOfProjects(service, { inferredProjects: 1 }); + ts.projectSystem.openFilesForSession([file1], session); + ts.projectSystem.checkNumberOfProjects(service, { inferredProjects: 1 }); const project = service.inferredProjects[0]; - checkProjectActualFiles(project, [libFile.path, file1.path]); // Should not contain atTypes + ts.projectSystem.checkProjectActualFiles(project, [ts.projectSystem.libFile.path, file1.path]); // Should not contain atTypes }); it("should not include referenced files from unopened files", () => { - const file1: File = { - path: `${tscWatch.projectRoot}/a.ts`, + const file1: ts.projectSystem.File = { + path: `${ts.tscWatch.projectRoot}/a.ts`, content: `/// -/// +/// function fooA() { }` }; - const file2: File = { - path: `${tscWatch.projectRoot}/b.ts`, + const file2: ts.projectSystem.File = { + path: `${ts.tscWatch.projectRoot}/b.ts`, content: `/// -/// +/// function fooB() { }` }; - const file3: File = { - path: `${tscWatch.projectRoot}/c.ts`, + const file3: ts.projectSystem.File = { + path: `${ts.tscWatch.projectRoot}/c.ts`, content: `function fooC() { }` }; - const something: File = { - path: `${tscWatch.projectRoot}/node_modules/something/index.d.ts`, + const something: ts.projectSystem.File = { + path: `${ts.tscWatch.projectRoot}/node_modules/something/index.d.ts`, content: "function something() {}" }; - const configFile: File = { - path: `${tscWatch.projectRoot}/tsconfig.json`, + const configFile: ts.projectSystem.File = { + path: `${ts.tscWatch.projectRoot}/tsconfig.json`, content: "{}" }; - const host = createServerHost([file1, file2, file3, something, libFile, configFile]); - const session = createSession(host, { serverMode: LanguageServiceMode.PartialSemantic, useSingleInferredProject: true }); + const host = ts.projectSystem.createServerHost([file1, file2, file3, something, ts.projectSystem.libFile, configFile]); + const session = ts.projectSystem.createSession(host, { serverMode: ts.LanguageServiceMode.PartialSemantic, useSingleInferredProject: true }); const service = session.getProjectService(); - openFilesForSession([file1], session); - checkNumberOfProjects(service, { inferredProjects: 1 }); + ts.projectSystem.openFilesForSession([file1], session); + ts.projectSystem.checkNumberOfProjects(service, { inferredProjects: 1 }); const project = service.inferredProjects[0]; - checkProjectActualFiles(project, [libFile.path, file1.path]); // no resolve + ts.projectSystem.checkProjectActualFiles(project, [ts.projectSystem.libFile.path, file1.path]); // no resolve }); it("should not crash when external module name resolution is reused", () => { const { session, file1, file2, file3 } = setup(); const service = session.getProjectService(); - openFilesForSession([file1], session); - checkNumberOfProjects(service, { inferredProjects: 1 }); + ts.projectSystem.openFilesForSession([file1], session); + ts.projectSystem.checkNumberOfProjects(service, { inferredProjects: 1 }); const project = service.inferredProjects[0]; - checkProjectActualFiles(project, [libFile.path, file1.path]); + ts.projectSystem.checkProjectActualFiles(project, [ts.projectSystem.libFile.path, file1.path]); // Close the file that contains non relative external module name and open some file that doesnt have non relative external module import - closeFilesForSession([file1], session); - openFilesForSession([file3], session); - checkProjectActualFiles(project, [libFile.path, file3.path]); + ts.projectSystem.closeFilesForSession([file1], session); + ts.projectSystem.openFilesForSession([file3], session); + ts.projectSystem.checkProjectActualFiles(project, [ts.projectSystem.libFile.path, file3.path]); // Open file with non relative external module name - openFilesForSession([file2], session); - checkProjectActualFiles(project, [libFile.path, file2.path, file3.path]); + ts.projectSystem.openFilesForSession([file2], session); + ts.projectSystem.checkProjectActualFiles(project, [ts.projectSystem.libFile.path, file2.path, file3.path]); }); it("should not create autoImportProvider or handle package jsons", () => { - const angularFormsDts: File = { + const angularFormsDts: ts.projectSystem.File = { path: "/node_modules/@angular/forms/forms.d.ts", content: "export declare class PatternValidator {}", }; - const angularFormsPackageJson: File = { + const angularFormsPackageJson: ts.projectSystem.File = { path: "/node_modules/@angular/forms/package.json", content: `{ "name": "@angular/forms", "typings": "./forms.d.ts" }`, }; - const tsconfig: File = { + const tsconfig: ts.projectSystem.File = { path: "/tsconfig.json", content: `{ "compilerOptions": { "module": "commonjs" } }`, }; - const packageJson: File = { + const packageJson: ts.projectSystem.File = { path: "/package.json", content: `{ "dependencies": { "@angular/forms": "*", "@angular/core": "*" } }` }; - const indexTs: File = { + const indexTs: ts.projectSystem.File = { path: "/index.ts", content: "" }; - const host = createServerHost([angularFormsDts, angularFormsPackageJson, tsconfig, packageJson, indexTs, libFile]); - const session = createSession(host, { serverMode: LanguageServiceMode.PartialSemantic, useSingleInferredProject: true }); + const host = ts.projectSystem.createServerHost([angularFormsDts, angularFormsPackageJson, tsconfig, packageJson, indexTs, ts.projectSystem.libFile]); + const session = ts.projectSystem.createSession(host, { serverMode: ts.LanguageServiceMode.PartialSemantic, useSingleInferredProject: true }); const service = session.getProjectService(); - openFilesForSession([indexTs], session); + ts.projectSystem.openFilesForSession([indexTs], session); const project = service.inferredProjects[0]; assert.isFalse(project.autoImportProviderHost); assert.isUndefined(project.getPackageJsonAutoImportProvider()); - assert.deepEqual(project.getPackageJsonsForAutoImport(), emptyArray); + assert.deepEqual(project.getPackageJsonsForAutoImport(), ts.emptyArray); }); it("should support go-to-definition on module specifiers", () => { const { session, file1, file2 } = setup(); - openFilesForSession([file1], session); - const response = session.executeCommandSeq({ - command: protocol.CommandTypes.DefinitionAndBoundSpan, - arguments: protocolFileLocationFromSubstring(file1, `"./b"`) - }).response as protocol.DefinitionInfoAndBoundSpan; + ts.projectSystem.openFilesForSession([file1], session); + const response = session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.DefinitionAndBoundSpan, + arguments: ts.projectSystem.protocolFileLocationFromSubstring(file1, `"./b"`) + }).response as ts.projectSystem.protocol.DefinitionInfoAndBoundSpan; assert.isDefined(response); assert.deepEqual(response.definitions, [{ file: file2.path, diff --git a/src/testRunner/unittests/tsserver/plugins.ts b/src/testRunner/unittests/tsserver/plugins.ts index 5d46dd203f9db..9e7d249880a1f 100644 --- a/src/testRunner/unittests/tsserver/plugins.ts +++ b/src/testRunner/unittests/tsserver/plugins.ts @@ -4,15 +4,18 @@ namespace ts.projectSystem { const testProtocolCommandRequest = "testProtocolCommandRequest"; const testProtocolCommandResponse = "testProtocolCommandResponse"; - function createHostWithPlugin(files: readonly File[]) { - const host = createServerHost(files); + function createHostWithPlugin(files: readonly ts.projectSystem.File[]) { + const host = ts.projectSystem.createServerHost(files); const pluginsLoaded: string[] = []; - const protocolHandlerRequests: [string, string][] = []; + const protocolHandlerRequests: [ + string, + string + ][] = []; host.require = (_initialPath, moduleName) => { pluginsLoaded.push(moduleName); return { module: () => ({ - create(info: server.PluginCreateInfo) { + create(info: ts.server.PluginCreateInfo) { info.session?.addProtocolHandler(testProtocolCommand, request => { protocolHandlerRequests.push([request.command, request.arguments]); return { @@ -31,8 +34,8 @@ namespace ts.projectSystem { it("With local plugins", () => { const expectedToLoad = ["@myscoped/plugin", "unscopedPlugin"]; const notToLoad = ["../myPlugin", "myPlugin/../malicious"]; - const aTs: File = { path: "/a.ts", content: `class c { prop = "hello"; foo() { return this.prop; } }` }; - const tsconfig: File = { + const aTs: ts.projectSystem.File = { path: "/a.ts", content: `class c { prop = "hello"; foo() { return this.prop; } }` }; + const tsconfig: ts.projectSystem.File = { path: "/tsconfig.json", content: JSON.stringify({ compilerOptions: { @@ -43,8 +46,8 @@ namespace ts.projectSystem { } }) }; - const { host, pluginsLoaded } = createHostWithPlugin([aTs, tsconfig, libFile]); - const service = createProjectService(host); + const { host, pluginsLoaded } = createHostWithPlugin([aTs, tsconfig, ts.projectSystem.libFile]); + const service = ts.projectSystem.createProjectService(host); service.openClientFile(aTs.path); assert.deepEqual(pluginsLoaded, expectedToLoad); }); @@ -52,13 +55,13 @@ namespace ts.projectSystem { it("With global plugins", () => { const expectedToLoad = ["@myscoped/plugin", "unscopedPlugin"]; const notToLoad = ["../myPlugin", "myPlugin/../malicious"]; - const aTs: File = { path: "/a.ts", content: `class c { prop = "hello"; foo() { return this.prop; } }` }; - const tsconfig: File = { + const aTs: ts.projectSystem.File = { path: "/a.ts", content: `class c { prop = "hello"; foo() { return this.prop; } }` }; + const tsconfig: ts.projectSystem.File = { path: "/tsconfig.json", content: "{}" }; - const { host, pluginsLoaded } = createHostWithPlugin([aTs, tsconfig, libFile]); - const service = createProjectService(host, { globalPlugins: [...expectedToLoad, ...notToLoad] }); + const { host, pluginsLoaded } = createHostWithPlugin([aTs, tsconfig, ts.projectSystem.libFile]); + const service = ts.projectSystem.createProjectService(host, { globalPlugins: [...expectedToLoad, ...notToLoad] }); service.openClientFile(aTs.path); assert.deepEqual(pluginsLoaded, expectedToLoad); }); @@ -66,8 +69,8 @@ namespace ts.projectSystem { it("With session and custom protocol message", () => { const pluginName = "some-plugin"; const expectedToLoad = [pluginName]; - const aTs: File = { path: "/a.ts", content: `class c { prop = "hello"; foo() { return this.prop; } }` }; - const tsconfig: File = { + const aTs: ts.projectSystem.File = { path: "/a.ts", content: `class c { prop = "hello"; foo() { return this.prop; } }` }; + const tsconfig: ts.projectSystem.File = { path: "/tsconfig.json", content: JSON.stringify({ compilerOptions: { @@ -78,10 +81,9 @@ namespace ts.projectSystem { }) }; - const { host, pluginsLoaded, protocolHandlerRequests } = createHostWithPlugin([aTs, tsconfig, libFile]); - const session = createSession(host); - - const service = createProjectService(host, { session }); + const { host, pluginsLoaded, protocolHandlerRequests } = createHostWithPlugin([aTs, tsconfig, ts.projectSystem.libFile]); + const session = ts.projectSystem.createSession(host); + const service = ts.projectSystem.createProjectService(host, { session }); service.openClientFile(aTs.path); assert.deepEqual(pluginsLoaded, expectedToLoad); @@ -95,7 +97,7 @@ namespace ts.projectSystem { assert.strictEqual(command, testProtocolCommand); assert.strictEqual(args, testProtocolCommandRequest); - const expectedResp: server.HandlerResponse = { + const expectedResp: ts.server.HandlerResponse = { response: testProtocolCommandResponse }; assert.deepEqual(resp, expectedResp); diff --git a/src/testRunner/unittests/tsserver/projectErrors.ts b/src/testRunner/unittests/tsserver/projectErrors.ts index f721a27cf316f..a1dbe92beed16 100644 --- a/src/testRunner/unittests/tsserver/projectErrors.ts +++ b/src/testRunner/unittests/tsserver/projectErrors.ts @@ -1,26 +1,26 @@ namespace ts.projectSystem { describe("unittests:: tsserver:: Project Errors", () => { - function checkProjectErrors(projectFiles: server.ProjectFilesWithTSDiagnostics, expectedErrors: readonly string[]): void { + function checkProjectErrors(projectFiles: ts.server.ProjectFilesWithTSDiagnostics, expectedErrors: readonly string[]): void { assert.isTrue(projectFiles !== undefined, "missing project files"); checkProjectErrorsWorker(projectFiles.projectErrors, expectedErrors); } - function checkProjectErrorsWorker(errors: readonly Diagnostic[], expectedErrors: readonly string[]): void { + function checkProjectErrorsWorker(errors: readonly ts.Diagnostic[], expectedErrors: readonly string[]): void { assert.equal(errors ? errors.length : 0, expectedErrors.length, `expected ${expectedErrors.length} error in the list`); if (expectedErrors.length) { for (let i = 0; i < errors.length; i++) { - const actualMessage = flattenDiagnosticMessageText(errors[i].messageText, "\n"); + const actualMessage = ts.flattenDiagnosticMessageText(errors[i].messageText, "\n"); const expectedMessage = expectedErrors[i]; assert.isTrue(actualMessage.indexOf(expectedMessage) === 0, `error message does not match, expected ${actualMessage} to start with ${expectedMessage}`); } } } - function checkDiagnosticsWithLinePos(errors: server.protocol.DiagnosticWithLinePosition[], expectedErrors: string[]) { + function checkDiagnosticsWithLinePos(errors: ts.server.protocol.DiagnosticWithLinePosition[], expectedErrors: string[]) { assert.equal(errors ? errors.length : 0, expectedErrors.length, `expected ${expectedErrors.length} error in the list`); if (expectedErrors.length) { - zipWith(errors, expectedErrors, ({ message: actualMessage }, expectedMessage) => { - assert.isTrue(startsWith(actualMessage, actualMessage), `error message does not match, expected ${actualMessage} to start with ${expectedMessage}`); + ts.zipWith(errors, expectedErrors, ({ message: actualMessage }, expectedMessage) => { + assert.isTrue(ts.startsWith(actualMessage, actualMessage), `error message does not match, expected ${actualMessage} to start with ${expectedMessage}`); }); } } @@ -34,13 +34,13 @@ namespace ts.projectSystem { path: "/a/b/applib.ts", content: "" }; - const host = createServerHost([file1, libFile]); - const session = createSession(host); + const host = ts.projectSystem.createServerHost([file1, ts.projectSystem.libFile]); + const session = ts.projectSystem.createSession(host); const projectService = session.getProjectService(); const projectFileName = "/a/b/test.csproj"; - const compilerOptionsRequest: server.protocol.CompilerOptionsDiagnosticsRequest = { + const compilerOptionsRequest: ts.server.protocol.CompilerOptionsDiagnosticsRequest = { type: "request", - command: server.CommandNames.CompilerOptionsDiagnosticsFull, + command: ts.server.CommandNames.CompilerOptionsDiagnosticsFull, seq: 2, arguments: { projectFileName } }; @@ -49,27 +49,27 @@ namespace ts.projectSystem { projectService.openExternalProject({ projectFileName, options: {}, - rootFiles: toExternalFiles([file1.path, file2.path]) + rootFiles: ts.projectSystem.toExternalFiles([file1.path, file2.path]) }); - checkNumberOfProjects(projectService, { externalProjects: 1 }); - const diags = session.executeCommand(compilerOptionsRequest).response as server.protocol.DiagnosticWithLinePosition[]; + ts.projectSystem.checkNumberOfProjects(projectService, { externalProjects: 1 }); + const diags = session.executeCommand(compilerOptionsRequest).response as ts.server.protocol.DiagnosticWithLinePosition[]; // only file1 exists - expect error checkDiagnosticsWithLinePos(diags, ["File '/a/b/applib.ts' not found."]); } host.renameFile(file1.path, file2.path); { // only file2 exists - expect error - checkNumberOfProjects(projectService, { externalProjects: 1 }); - const diags = session.executeCommand(compilerOptionsRequest).response as server.protocol.DiagnosticWithLinePosition[]; + ts.projectSystem.checkNumberOfProjects(projectService, { externalProjects: 1 }); + const diags = session.executeCommand(compilerOptionsRequest).response as ts.server.protocol.DiagnosticWithLinePosition[]; checkDiagnosticsWithLinePos(diags, ["File '/a/b/app.ts' not found."]); } host.writeFile(file1.path, file1.content); { // both files exist - expect no errors - checkNumberOfProjects(projectService, { externalProjects: 1 }); - const diags = session.executeCommand(compilerOptionsRequest).response as server.protocol.DiagnosticWithLinePosition[]; + ts.projectSystem.checkNumberOfProjects(projectService, { externalProjects: 1 }); + const diags = session.executeCommand(compilerOptionsRequest).response as ts.server.protocol.DiagnosticWithLinePosition[]; checkDiagnosticsWithLinePos(diags, []); } }); @@ -85,27 +85,27 @@ namespace ts.projectSystem { }; const config = { path: "/a/b/tsconfig.json", - content: JSON.stringify({ files: [file1, file2].map(f => getBaseFileName(f.path)) }) + content: JSON.stringify({ files: [file1, file2].map(f => ts.getBaseFileName(f.path)) }) }; - const host = createServerHost([file1, config, libFile]); - const session = createSession(host); + const host = ts.projectSystem.createServerHost([file1, config, ts.projectSystem.libFile]); + const session = ts.projectSystem.createSession(host); const projectService = session.getProjectService(); - openFilesForSession([file1], session); - checkNumberOfProjects(projectService, { configuredProjects: 1 }); - const project = configuredProjectAt(projectService, 0); - const compilerOptionsRequest: server.protocol.CompilerOptionsDiagnosticsRequest = { + ts.projectSystem.openFilesForSession([file1], session); + ts.projectSystem.checkNumberOfProjects(projectService, { configuredProjects: 1 }); + const project = ts.projectSystem.configuredProjectAt(projectService, 0); + const compilerOptionsRequest: ts.server.protocol.CompilerOptionsDiagnosticsRequest = { type: "request", - command: server.CommandNames.CompilerOptionsDiagnosticsFull, + command: ts.server.CommandNames.CompilerOptionsDiagnosticsFull, seq: 2, arguments: { projectFileName: project.getProjectName() } }; - let diags = session.executeCommand(compilerOptionsRequest).response as server.protocol.DiagnosticWithLinePosition[]; + let diags = session.executeCommand(compilerOptionsRequest).response as ts.server.protocol.DiagnosticWithLinePosition[]; checkDiagnosticsWithLinePos(diags, ["File '/a/b/applib.ts' not found."]); host.writeFile(file2.path, file2.content); - checkNumberOfProjects(projectService, { configuredProjects: 1 }); - diags = session.executeCommand(compilerOptionsRequest).response as server.protocol.DiagnosticWithLinePosition[]; + ts.projectSystem.checkNumberOfProjects(projectService, { configuredProjects: 1 }); + diags = session.executeCommand(compilerOptionsRequest).response as ts.server.protocol.DiagnosticWithLinePosition[]; checkDiagnosticsWithLinePos(diags, []); }); @@ -120,22 +120,22 @@ namespace ts.projectSystem { }; const correctConfig = { path: "/a/b/tsconfig.json", - content: JSON.stringify({ files: [file1, file2].map(f => getBaseFileName(f.path)) }) + content: JSON.stringify({ files: [file1, file2].map(f => ts.getBaseFileName(f.path)) }) }; const corruptedConfig = { path: correctConfig.path, content: correctConfig.content.substr(1) }; - const host = createServerHost([file1, file2, corruptedConfig]); - const projectService = createProjectService(host); + const host = ts.projectSystem.createServerHost([file1, file2, corruptedConfig]); + const projectService = ts.projectSystem.createProjectService(host); projectService.openClientFile(file1.path); { projectService.checkNumberOfProjects({ configuredProjects: 1 }); - const configuredProject = find(projectService.synchronizeProjectList([]), f => f.info!.projectName === corruptedConfig.path)!; + const configuredProject = ts.find(projectService.synchronizeProjectList([]), f => f.info!.projectName === corruptedConfig.path)!; assert.isTrue(configuredProject !== undefined, "should find configured project"); checkProjectErrors(configuredProject, []); - const projectErrors = configuredProjectAt(projectService, 0).getAllProjectErrors(); + const projectErrors = ts.projectSystem.configuredProjectAt(projectService, 0).getAllProjectErrors(); checkProjectErrorsWorker(projectErrors, [ "'{' expected." ]); @@ -146,10 +146,10 @@ namespace ts.projectSystem { host.writeFile(correctConfig.path, correctConfig.content); { projectService.checkNumberOfProjects({ configuredProjects: 1 }); - const configuredProject = find(projectService.synchronizeProjectList([]), f => f.info!.projectName === corruptedConfig.path)!; + const configuredProject = ts.find(projectService.synchronizeProjectList([]), f => f.info!.projectName === corruptedConfig.path)!; assert.isTrue(configuredProject !== undefined, "should find configured project"); checkProjectErrors(configuredProject, []); - const projectErrors = configuredProjectAt(projectService, 0).getAllProjectErrors(); + const projectErrors = ts.projectSystem.configuredProjectAt(projectService, 0).getAllProjectErrors(); checkProjectErrorsWorker(projectErrors, []); } }); @@ -165,32 +165,32 @@ namespace ts.projectSystem { }; const correctConfig = { path: "/a/b/tsconfig.json", - content: JSON.stringify({ files: [file1, file2].map(f => getBaseFileName(f.path)) }) + content: JSON.stringify({ files: [file1, file2].map(f => ts.getBaseFileName(f.path)) }) }; const corruptedConfig = { path: correctConfig.path, content: correctConfig.content.substr(1) }; - const host = createServerHost([file1, file2, correctConfig]); - const projectService = createProjectService(host); + const host = ts.projectSystem.createServerHost([file1, file2, correctConfig]); + const projectService = ts.projectSystem.createProjectService(host); projectService.openClientFile(file1.path); { projectService.checkNumberOfProjects({ configuredProjects: 1 }); - const configuredProject = find(projectService.synchronizeProjectList([]), f => f.info!.projectName === corruptedConfig.path)!; + const configuredProject = ts.find(projectService.synchronizeProjectList([]), f => f.info!.projectName === corruptedConfig.path)!; assert.isTrue(configuredProject !== undefined, "should find configured project"); checkProjectErrors(configuredProject, []); - const projectErrors = configuredProjectAt(projectService, 0).getAllProjectErrors(); + const projectErrors = ts.projectSystem.configuredProjectAt(projectService, 0).getAllProjectErrors(); checkProjectErrorsWorker(projectErrors, []); } // break config and trigger watcher host.writeFile(corruptedConfig.path, corruptedConfig.content); { projectService.checkNumberOfProjects({ configuredProjects: 1 }); - const configuredProject = find(projectService.synchronizeProjectList([]), f => f.info!.projectName === corruptedConfig.path)!; + const configuredProject = ts.find(projectService.synchronizeProjectList([]), f => f.info!.projectName === corruptedConfig.path)!; assert.isTrue(configuredProject !== undefined, "should find configured project"); checkProjectErrors(configuredProject, []); - const projectErrors = configuredProjectAt(projectService, 0).getAllProjectErrors(); + const projectErrors = ts.projectSystem.configuredProjectAt(projectService, 0).getAllProjectErrors(); checkProjectErrorsWorker(projectErrors, [ "'{' expected." ]); @@ -210,37 +210,37 @@ namespace ts.projectSystem { path: "/a/b/tsconfig.json", content: "{" }; - const host = createServerHost([file1, corruptedConfig]); - const projectService = createProjectService(host); + const host = ts.projectSystem.createServerHost([file1, corruptedConfig]); + const projectService = ts.projectSystem.createProjectService(host); projectService.openClientFile(file1.path); projectService.checkNumberOfProjects({ configuredProjects: 1 }); const project = projectService.findProject(corruptedConfig.path)!; - checkProjectRootFiles(project, [file1.path]); + ts.projectSystem.checkProjectRootFiles(project, [file1.path]); }); describe("when opening new file that doesnt exist on disk yet", () => { function verifyNonExistentFile(useProjectRoot: boolean) { const folderPath = "/user/someuser/projects/someFolder"; - const fileInRoot: File = { + const fileInRoot: ts.projectSystem.File = { path: `/src/somefile.d.ts`, content: "class c { }" }; - const fileInProjectRoot: File = { + const fileInProjectRoot: ts.projectSystem.File = { path: `${folderPath}/src/somefile.d.ts`, content: "class c { }" }; - const host = createServerHost([libFile, fileInRoot, fileInProjectRoot]); - const session = createSession(host, { canUseEvents: true, logger: createLoggerWithInMemoryLogs(), useInferredProjectPerProjectRoot: true }); + const host = ts.projectSystem.createServerHost([ts.projectSystem.libFile, fileInRoot, fileInProjectRoot]); + const session = ts.projectSystem.createSession(host, { canUseEvents: true, logger: ts.projectSystem.createLoggerWithInMemoryLogs(), useInferredProjectPerProjectRoot: true }); const untitledFile = "untitled:Untitled-1"; const refPathNotFound1 = "../../../../../../typings/@epic/Core.d.ts"; const refPathNotFound2 = "./src/somefile.d.ts"; const fileContent = `/// /// `; - session.executeCommandSeq({ - command: server.CommandNames.Open, + session.executeCommandSeq({ + command: ts.server.CommandNames.Open, arguments: { file: untitledFile, fileContent, @@ -248,12 +248,12 @@ namespace ts.projectSystem { projectRootPath: useProjectRoot ? folderPath : undefined } }); - appendAllScriptInfos(session.getProjectService(), session.logger.logs); + ts.projectSystem.appendAllScriptInfos(session.getProjectService(), session.logger.logs); // Since this is not js project so no typings are queued host.checkTimeoutQueueLength(0); - verifyGetErrRequest({ session, host, files: [untitledFile] }); - baselineTsserverLogs("projectErrors", `when opening new file that doesnt exist on disk yet ${useProjectRoot ? "with projectRoot" : "without projectRoot"}`, session); + ts.projectSystem.verifyGetErrRequest({ session, host, files: [untitledFile] }); + ts.projectSystem.baselineTsserverLogs("projectErrors", `when opening new file that doesnt exist on disk yet ${useProjectRoot ? "with projectRoot" : "without projectRoot"}`, session); } it("has projectRoot", () => { @@ -267,43 +267,42 @@ namespace ts.projectSystem { it("folder rename updates project structure and reports no errors", () => { const projectDir = "/a/b/projects/myproject"; - const app: File = { + const app: ts.projectSystem.File = { path: `${projectDir}/bar/app.ts`, content: "class Bar implements foo.Foo { getFoo() { return ''; } get2() { return 1; } }" }; - const foo: File = { + const foo: ts.projectSystem.File = { path: `${projectDir}/foo/foo.ts`, content: "declare namespace foo { interface Foo { get2(): number; getFoo(): string; } }" }; - const configFile: File = { + const configFile: ts.projectSystem.File = { path: `${projectDir}/tsconfig.json`, content: JSON.stringify({ compilerOptions: { module: "none", targer: "es5" }, exclude: ["node_modules"] }) }; - const host = createServerHost([app, foo, configFile]); - const session = createSession(host, { canUseEvents: true, logger: createLoggerWithInMemoryLogs() }); - - session.executeCommandSeq({ - command: server.CommandNames.Open, + const host = ts.projectSystem.createServerHost([app, foo, configFile]); + const session = ts.projectSystem.createSession(host, { canUseEvents: true, logger: ts.projectSystem.createLoggerWithInMemoryLogs() }); + session.executeCommandSeq({ + command: ts.server.CommandNames.Open, arguments: { file: app.path, } }); - verifyGetErrRequest({ session, host, files: [app] }); + ts.projectSystem.verifyGetErrRequest({ session, host, files: [app] }); host.renameFolder(`${projectDir}/foo`, `${projectDir}/foo2`); host.runQueuedTimeoutCallbacks(); host.runQueuedTimeoutCallbacks(); - verifyGetErrRequest({ session, host, files: [app] }); - baselineTsserverLogs("projectErrors", `folder rename updates project structure and reports no errors`, session); + ts.projectSystem.verifyGetErrRequest({ session, host, files: [app] }); + ts.projectSystem.baselineTsserverLogs("projectErrors", `folder rename updates project structure and reports no errors`, session); }); it("Getting errors before opening file", () => { - const file: File = { + const file: ts.projectSystem.File = { path: "/a/b/project/file.ts", content: "let x: number = false;" }; - const host = createServerHost([file, libFile]); - const session = createSession(host, { canUseEvents: true, logger: createLoggerWithInMemoryLogs() }); - session.executeCommandSeq({ - command: server.CommandNames.Geterr, + const host = ts.projectSystem.createServerHost([file, ts.projectSystem.libFile]); + const session = ts.projectSystem.createSession(host, { canUseEvents: true, logger: ts.projectSystem.createLoggerWithInMemoryLogs() }); + session.executeCommandSeq({ + command: ts.server.CommandNames.Geterr, arguments: { delay: 0, files: [file.path] @@ -311,69 +310,69 @@ namespace ts.projectSystem { }); host.checkTimeoutQueueLengthAndRun(1); - baselineTsserverLogs("projectErrors", "getting errors before opening file", session); + ts.projectSystem.baselineTsserverLogs("projectErrors", "getting errors before opening file", session); }); it("Reports errors correctly when file referenced by inferred project root, is opened right after closing the root file", () => { - const app: File = { - path: `${tscWatch.projectRoot}/src/client/app.js`, + const app: ts.projectSystem.File = { + path: `${ts.tscWatch.projectRoot}/src/client/app.js`, content: "" }; - const serverUtilities: File = { - path: `${tscWatch.projectRoot}/src/server/utilities.js`, + const serverUtilities: ts.projectSystem.File = { + path: `${ts.tscWatch.projectRoot}/src/server/utilities.js`, content: `function getHostName() { return "hello"; } export { getHostName };` }; - const backendTest: File = { - path: `${tscWatch.projectRoot}/test/backend/index.js`, + const backendTest: ts.projectSystem.File = { + path: `${ts.tscWatch.projectRoot}/test/backend/index.js`, content: `import { getHostName } from '../../src/server/utilities';export default getHostName;` }; - const files = [libFile, app, serverUtilities, backendTest]; - const host = createServerHost(files); - const session = createSession(host, { useInferredProjectPerProjectRoot: true, canUseEvents: true, logger: createLoggerWithInMemoryLogs() }); - openFilesForSession([{ file: app, projectRootPath: tscWatch.projectRoot }], session); - openFilesForSession([{ file: backendTest, projectRootPath: tscWatch.projectRoot }], session); - verifyGetErrRequest({ session, host, files: [backendTest.path, app.path] }); - closeFilesForSession([backendTest], session); - openFilesForSession([{ file: serverUtilities.path, projectRootPath: tscWatch.projectRoot }], session); - verifyGetErrRequest({ session, host, files: [serverUtilities.path, app.path] }); - baselineTsserverLogs("projectErrors", `reports errors correctly when file referenced by inferred project root, is opened right after closing the root file`, session); + const files = [ts.projectSystem.libFile, app, serverUtilities, backendTest]; + const host = ts.projectSystem.createServerHost(files); + const session = ts.projectSystem.createSession(host, { useInferredProjectPerProjectRoot: true, canUseEvents: true, logger: ts.projectSystem.createLoggerWithInMemoryLogs() }); + ts.projectSystem.openFilesForSession([{ file: app, projectRootPath: ts.tscWatch.projectRoot }], session); + ts.projectSystem.openFilesForSession([{ file: backendTest, projectRootPath: ts.tscWatch.projectRoot }], session); + ts.projectSystem.verifyGetErrRequest({ session, host, files: [backendTest.path, app.path] }); + ts.projectSystem.closeFilesForSession([backendTest], session); + ts.projectSystem.openFilesForSession([{ file: serverUtilities.path, projectRootPath: ts.tscWatch.projectRoot }], session); + ts.projectSystem.verifyGetErrRequest({ session, host, files: [serverUtilities.path, app.path] }); + ts.projectSystem.baselineTsserverLogs("projectErrors", `reports errors correctly when file referenced by inferred project root, is opened right after closing the root file`, session); }); it("Correct errors when resolution resolves to file that has same ambient module and is also module", () => { const projectRootPath = "/users/username/projects/myproject"; - const aFile: File = { + const aFile: ts.projectSystem.File = { path: `${projectRootPath}/src/a.ts`, content: `import * as myModule from "@custom/plugin"; function foo() { // hello }` }; - const config: File = { + const config: ts.projectSystem.File = { path: `${projectRootPath}/tsconfig.json`, content: JSON.stringify({ include: ["src"] }) }; - const plugin: File = { + const plugin: ts.projectSystem.File = { path: `${projectRootPath}/node_modules/@custom/plugin/index.d.ts`, content: `import './proposed'; declare module '@custom/plugin' { export const version: string; }` }; - const pluginProposed: File = { + const pluginProposed: ts.projectSystem.File = { path: `${projectRootPath}/node_modules/@custom/plugin/proposed.d.ts`, content: `declare module '@custom/plugin' { export const bar = 10; }` }; - const files = [libFile, aFile, config, plugin, pluginProposed]; - const host = createServerHost(files); - const session = createSession(host, { canUseEvents: true, logger: createLoggerWithInMemoryLogs() }); - openFilesForSession([aFile], session); + const files = [ts.projectSystem.libFile, aFile, config, plugin, pluginProposed]; + const host = ts.projectSystem.createServerHost(files); + const session = ts.projectSystem.createSession(host, { canUseEvents: true, logger: ts.projectSystem.createLoggerWithInMemoryLogs() }); + ts.projectSystem.openFilesForSession([aFile], session); checkErrors(); - session.executeCommandSeq({ - command: protocol.CommandTypes.Change, + session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.Change, arguments: { file: aFile.path, line: 3, @@ -384,28 +383,28 @@ declare module '@custom/plugin' { } }); checkErrors(); - baselineTsserverLogs("projectErrors", `correct errors when resolution resolves to file that has same ambient module and is also module`, session); + ts.projectSystem.baselineTsserverLogs("projectErrors", `correct errors when resolution resolves to file that has same ambient module and is also module`, session); function checkErrors() { host.checkTimeoutQueueLength(0); - verifyGetErrRequest({ session, host, files: [aFile] }); + ts.projectSystem.verifyGetErrRequest({ session, host, files: [aFile] }); } }); describe("when semantic error returns includes global error", () => { - const file: File = { - path: `${tscWatch.projectRoot}/ui.ts`, + const file: ts.projectSystem.File = { + path: `${ts.tscWatch.projectRoot}/ui.ts`, content: `const x = async (_action: string) => { };` }; - const config: File = { - path: `${tscWatch.projectRoot}/tsconfig.json`, + const config: ts.projectSystem.File = { + path: `${ts.tscWatch.projectRoot}/tsconfig.json`, content: "{}" }; - verifyGetErrScenario({ + ts.projectSystem.verifyGetErrScenario({ scenario: "projectErrors", subScenario: "when semantic error returns includes global error", - allFiles: () => [libFile, file, config], + allFiles: () => [ts.projectSystem.libFile, file, config], openFiles: () => [file], getErrRequest: () => [file], getErrForProjectRequest: () => [{ project: file, files: [file] }], @@ -416,11 +415,11 @@ declare module '@custom/plugin' { describe("unittests:: tsserver:: Project Errors for Configure file diagnostics events", () => { it("are generated when the config file has errors", () => { - const file: File = { + const file: ts.projectSystem.File = { path: "/a/b/app.ts", content: "let x = 10" }; - const configFile: File = { + const configFile: ts.projectSystem.File = { path: "/a/b/tsconfig.json", content: `{ "compilerOptions": { @@ -429,31 +428,31 @@ declare module '@custom/plugin' { } }` }; - const host = createServerHost([file, libFile, configFile]); - const session = createSession(host, { canUseEvents: true, logger: createLoggerWithInMemoryLogs() }); - openFilesForSession([file], session); - baselineTsserverLogs("projectErrors", "configFileDiagnostic events are generated when the config file has errors", session); + const host = ts.projectSystem.createServerHost([file, ts.projectSystem.libFile, configFile]); + const session = ts.projectSystem.createSession(host, { canUseEvents: true, logger: ts.projectSystem.createLoggerWithInMemoryLogs() }); + ts.projectSystem.openFilesForSession([file], session); + ts.projectSystem.baselineTsserverLogs("projectErrors", "configFileDiagnostic events are generated when the config file has errors", session); }); it("are generated when the config file doesn't have errors", () => { - const file: File = { + const file: ts.projectSystem.File = { path: "/a/b/app.ts", content: "let x = 10" }; - const configFile: File = { + const configFile: ts.projectSystem.File = { path: "/a/b/tsconfig.json", content: `{ "compilerOptions": {} }` }; - const host = createServerHost([file, libFile, configFile]); - const session = createSession(host, { canUseEvents: true, logger: createLoggerWithInMemoryLogs() }); - openFilesForSession([file], session); - baselineTsserverLogs("projectErrors", "configFileDiagnostic events are generated when the config file doesnt have errors", session); + const host = ts.projectSystem.createServerHost([file, ts.projectSystem.libFile, configFile]); + const session = ts.projectSystem.createSession(host, { canUseEvents: true, logger: ts.projectSystem.createLoggerWithInMemoryLogs() }); + ts.projectSystem.openFilesForSession([file], session); + ts.projectSystem.baselineTsserverLogs("projectErrors", "configFileDiagnostic events are generated when the config file doesnt have errors", session); }); it("are generated when the config file changes", () => { - const file: File = { + const file: ts.projectSystem.File = { path: "/a/b/app.ts", content: "let x = 10" }; @@ -464,9 +463,9 @@ declare module '@custom/plugin' { }` }; - const host = createServerHost([file, libFile, configFile]); - const session = createSession(host, { canUseEvents: true, logger: createLoggerWithInMemoryLogs() }); - openFilesForSession([file], session); + const host = ts.projectSystem.createServerHost([file, ts.projectSystem.libFile, configFile]); + const session = ts.projectSystem.createSession(host, { canUseEvents: true, logger: ts.projectSystem.createLoggerWithInMemoryLogs() }); + ts.projectSystem.openFilesForSession([file], session); configFile.content = `{ "compilerOptions": { @@ -481,23 +480,23 @@ declare module '@custom/plugin' { }`; host.writeFile(configFile.path, configFile.content); host.runQueuedTimeoutCallbacks(); - baselineTsserverLogs("projectErrors", "configFileDiagnostic events are generated when the config file changes", session); + ts.projectSystem.baselineTsserverLogs("projectErrors", "configFileDiagnostic events are generated when the config file changes", session); }); it("are not generated when the config file does not include file opened and config file has errors", () => { - const file: File = { + const file: ts.projectSystem.File = { path: "/a/b/app.ts", content: "let x = 10" }; - const file2: File = { + const file2: ts.projectSystem.File = { path: "/a/b/test.ts", content: "let x = 10" }; - const file3: File = { + const file3: ts.projectSystem.File = { path: "/a/b/test2.ts", content: "let xy = 10" }; - const configFile: File = { + const configFile: ts.projectSystem.File = { path: "/a/b/tsconfig.json", content: `{ "compilerOptions": { @@ -507,21 +506,21 @@ declare module '@custom/plugin' { "files": ["app.ts"] }` }; - const host = createServerHost([file, libFile, configFile]); - const session = createSession(host, { canUseEvents: true, logger: createLoggerWithInMemoryLogs() }); - openFilesForSession([file2], session); - openFilesForSession([file], session); + const host = ts.projectSystem.createServerHost([file, ts.projectSystem.libFile, configFile]); + const session = ts.projectSystem.createSession(host, { canUseEvents: true, logger: ts.projectSystem.createLoggerWithInMemoryLogs() }); + ts.projectSystem.openFilesForSession([file2], session); + ts.projectSystem.openFilesForSession([file], session); // We generate only if project is created when opening file from the project - openFilesForSession([file3], session); - baselineTsserverLogs("projectErrors", "configFileDiagnostic events are not generated when the config file does not include file opened and config file has errors", session); + ts.projectSystem.openFilesForSession([file3], session); + ts.projectSystem.baselineTsserverLogs("projectErrors", "configFileDiagnostic events are not generated when the config file does not include file opened and config file has errors", session); }); it("are not generated when the config file has errors but suppressDiagnosticEvents is true", () => { - const file: File = { + const file: ts.projectSystem.File = { path: "/a/b/app.ts", content: "let x = 10" }; - const configFile: File = { + const configFile: ts.projectSystem.File = { path: "/a/b/tsconfig.json", content: `{ "compilerOptions": { @@ -530,48 +529,48 @@ declare module '@custom/plugin' { } }` }; - const host = createServerHost([file, libFile, configFile]); - const session = createSession(host, { canUseEvents: true, suppressDiagnosticEvents: true, logger: createLoggerWithInMemoryLogs() }); - openFilesForSession([file], session); - baselineTsserverLogs("projectErrors", "configFileDiagnostic events are not generated when the config file has errors but suppressDiagnosticEvents is true", session); + const host = ts.projectSystem.createServerHost([file, ts.projectSystem.libFile, configFile]); + const session = ts.projectSystem.createSession(host, { canUseEvents: true, suppressDiagnosticEvents: true, logger: ts.projectSystem.createLoggerWithInMemoryLogs() }); + ts.projectSystem.openFilesForSession([file], session); + ts.projectSystem.baselineTsserverLogs("projectErrors", "configFileDiagnostic events are not generated when the config file has errors but suppressDiagnosticEvents is true", session); }); it("are not generated when the config file does not include file opened and doesnt contain any errors", () => { - const file: File = { + const file: ts.projectSystem.File = { path: "/a/b/app.ts", content: "let x = 10" }; - const file2: File = { + const file2: ts.projectSystem.File = { path: "/a/b/test.ts", content: "let x = 10" }; - const file3: File = { + const file3: ts.projectSystem.File = { path: "/a/b/test2.ts", content: "let xy = 10" }; - const configFile: File = { + const configFile: ts.projectSystem.File = { path: "/a/b/tsconfig.json", content: `{ "files": ["app.ts"] }` }; - const host = createServerHost([file, file2, file3, libFile, configFile]); - const session = createSession(host, { canUseEvents: true, logger: createLoggerWithInMemoryLogs() }); - openFilesForSession([file2], session); - openFilesForSession([file], session); + const host = ts.projectSystem.createServerHost([file, file2, file3, ts.projectSystem.libFile, configFile]); + const session = ts.projectSystem.createSession(host, { canUseEvents: true, logger: ts.projectSystem.createLoggerWithInMemoryLogs() }); + ts.projectSystem.openFilesForSession([file2], session); + ts.projectSystem.openFilesForSession([file], session); // We generate only if project is created when opening file from the project - openFilesForSession([file3], session); - baselineTsserverLogs("projectErrors", "configFileDiagnostic events are not generated when the config file does not include file opened and doesnt contain any errors", session); + ts.projectSystem.openFilesForSession([file3], session); + ts.projectSystem.baselineTsserverLogs("projectErrors", "configFileDiagnostic events are not generated when the config file does not include file opened and doesnt contain any errors", session); }); it("contains the project reference errors", () => { - const file: File = { + const file: ts.projectSystem.File = { path: "/a/b/app.ts", content: "let x = 10" }; const noSuchTsconfig = "no-such-tsconfig.json"; - const configFile: File = { + const configFile: ts.projectSystem.File = { path: "/a/b/tsconfig.json", content: `{ "files": ["app.ts"], @@ -579,10 +578,10 @@ declare module '@custom/plugin' { }` }; - const host = createServerHost([file, libFile, configFile]); - const session = createSession(host, { canUseEvents: true, logger: createLoggerWithInMemoryLogs() }); - openFilesForSession([file], session); - baselineTsserverLogs("projectErrors", "configFileDiagnostic events contains the project reference errors", session); + const host = ts.projectSystem.createServerHost([file, ts.projectSystem.libFile, configFile]); + const session = ts.projectSystem.createSession(host, { canUseEvents: true, logger: ts.projectSystem.createLoggerWithInMemoryLogs() }); + ts.projectSystem.openFilesForSession([file], session); + ts.projectSystem.baselineTsserverLogs("projectErrors", "configFileDiagnostic events contains the project reference errors", session); }); }); @@ -592,34 +591,34 @@ declare module '@custom/plugin' { path: "/a/b/f1.js", content: "function test1() { }" }; - const host = createServerHost([f1, libFile]); - const session = createSession(host); - openFilesForSession([f1], session); + const host = ts.projectSystem.createServerHost([f1, ts.projectSystem.libFile]); + const session = ts.projectSystem.createSession(host); + ts.projectSystem.openFilesForSession([f1], session); const projectService = session.getProjectService(); - checkNumberOfProjects(projectService, { inferredProjects: 1 }); + ts.projectSystem.checkNumberOfProjects(projectService, { inferredProjects: 1 }); const projectName = projectService.inferredProjects[0].getProjectName(); const diags = session.executeCommand({ type: "request", - command: server.CommandNames.CompilerOptionsDiagnosticsFull, + command: ts.server.CommandNames.CompilerOptionsDiagnosticsFull, seq: 2, arguments: { projectFileName: projectName } - } as server.protocol.CompilerOptionsDiagnosticsRequest).response as readonly protocol.DiagnosticWithLinePosition[]; + } as ts.server.protocol.CompilerOptionsDiagnosticsRequest).response as readonly ts.projectSystem.protocol.DiagnosticWithLinePosition[]; assert.isTrue(diags.length === 0); session.executeCommand({ type: "request", - command: server.CommandNames.CompilerOptionsForInferredProjects, + command: ts.server.CommandNames.CompilerOptionsForInferredProjects, seq: 3, - arguments: { options: { module: ModuleKind.CommonJS } } - } as server.protocol.SetCompilerOptionsForInferredProjectsRequest); + arguments: { options: { module: ts.ModuleKind.CommonJS } } + } as ts.server.protocol.SetCompilerOptionsForInferredProjectsRequest); const diagsAfterUpdate = session.executeCommand({ type: "request", - command: server.CommandNames.CompilerOptionsDiagnosticsFull, + command: ts.server.CommandNames.CompilerOptionsDiagnosticsFull, seq: 4, arguments: { projectFileName: projectName } - } as server.protocol.CompilerOptionsDiagnosticsRequest).response as readonly protocol.DiagnosticWithLinePosition[]; + } as ts.server.protocol.CompilerOptionsDiagnosticsRequest).response as readonly ts.projectSystem.protocol.DiagnosticWithLinePosition[]; assert.isTrue(diagsAfterUpdate.length === 0); }); @@ -628,43 +627,42 @@ declare module '@custom/plugin' { path: "/a/b/f1.js", content: "function test1() { }" }; - const host = createServerHost([f1, libFile]); - const session = createSession(host); + const host = ts.projectSystem.createServerHost([f1, ts.projectSystem.libFile]); + const session = ts.projectSystem.createSession(host); const projectService = session.getProjectService(); const projectFileName = "/a/b/project.csproj"; - const externalFiles = toExternalFiles([f1.path]); + const externalFiles = ts.projectSystem.toExternalFiles([f1.path]); projectService.openExternalProject({ projectFileName, rootFiles: externalFiles, options: {} - } as protocol.ExternalProject); - - checkNumberOfProjects(projectService, { externalProjects: 1 }); + } as ts.projectSystem.protocol.ExternalProject); + ts.projectSystem.checkNumberOfProjects(projectService, { externalProjects: 1 }); const diags = session.executeCommand({ type: "request", - command: server.CommandNames.CompilerOptionsDiagnosticsFull, + command: ts.server.CommandNames.CompilerOptionsDiagnosticsFull, seq: 2, arguments: { projectFileName } - } as server.protocol.CompilerOptionsDiagnosticsRequest).response as readonly server.protocol.DiagnosticWithLinePosition[]; + } as ts.server.protocol.CompilerOptionsDiagnosticsRequest).response as readonly ts.server.protocol.DiagnosticWithLinePosition[]; assert.isTrue(diags.length === 0); session.executeCommand({ type: "request", - command: server.CommandNames.OpenExternalProject, + command: ts.server.CommandNames.OpenExternalProject, seq: 3, arguments: { projectFileName, rootFiles: externalFiles, - options: { module: ModuleKind.CommonJS } + options: { module: ts.ModuleKind.CommonJS } } - } as server.protocol.OpenExternalProjectRequest); + } as ts.server.protocol.OpenExternalProjectRequest); const diagsAfterUpdate = session.executeCommand({ type: "request", - command: server.CommandNames.CompilerOptionsDiagnosticsFull, + command: ts.server.CommandNames.CompilerOptionsDiagnosticsFull, seq: 4, arguments: { projectFileName } - } as server.protocol.CompilerOptionsDiagnosticsRequest).response as readonly server.protocol.DiagnosticWithLinePosition[]; + } as ts.server.protocol.CompilerOptionsDiagnosticsRequest).response as readonly ts.server.protocol.DiagnosticWithLinePosition[]; assert.isTrue(diagsAfterUpdate.length === 0); }); }); @@ -691,20 +689,20 @@ declare module '@custom/plugin' { path: "/a/b/tsconfig.json", content: configFileContentWithComment }; - const host = createServerHost([file, libFile, configFile]); - const session = createSession(host); - openFilesForSession([file], session); + const host = ts.projectSystem.createServerHost([file, ts.projectSystem.libFile, configFile]); + const session = ts.projectSystem.createSession(host); + ts.projectSystem.openFilesForSession([file], session); const projectService = session.getProjectService(); - checkNumberOfProjects(projectService, { configuredProjects: 1 }); - const projectName = configuredProjectAt(projectService, 0).getProjectName(); + ts.projectSystem.checkNumberOfProjects(projectService, { configuredProjects: 1 }); + const projectName = ts.projectSystem.configuredProjectAt(projectService, 0).getProjectName(); const diags = session.executeCommand({ type: "request", - command: server.CommandNames.SemanticDiagnosticsSync, + command: ts.server.CommandNames.SemanticDiagnosticsSync, seq: 2, arguments: { file: configFile.path, projectFileName: projectName, includeLinePosition: true } - } as server.protocol.SemanticDiagnosticsSyncRequest).response as readonly server.protocol.DiagnosticWithLinePosition[]; + } as ts.server.protocol.SemanticDiagnosticsSyncRequest).response as readonly ts.server.protocol.DiagnosticWithLinePosition[]; assert.isTrue(diags.length === 3); configFile.content = configFileContentWithoutCommentLine; @@ -712,17 +710,17 @@ declare module '@custom/plugin' { const diagsAfterEdit = session.executeCommand({ type: "request", - command: server.CommandNames.SemanticDiagnosticsSync, + command: ts.server.CommandNames.SemanticDiagnosticsSync, seq: 2, arguments: { file: configFile.path, projectFileName: projectName, includeLinePosition: true } - } as server.protocol.SemanticDiagnosticsSyncRequest).response as readonly server.protocol.DiagnosticWithLinePosition[]; + } as ts.server.protocol.SemanticDiagnosticsSyncRequest).response as readonly ts.server.protocol.DiagnosticWithLinePosition[]; assert.isTrue(diagsAfterEdit.length === 3); verifyDiagnostic(diags[0], diagsAfterEdit[0]); verifyDiagnostic(diags[1], diagsAfterEdit[1]); verifyDiagnostic(diags[2], diagsAfterEdit[2]); - function verifyDiagnostic(beforeEditDiag: server.protocol.DiagnosticWithLinePosition, afterEditDiag: server.protocol.DiagnosticWithLinePosition) { + function verifyDiagnostic(beforeEditDiag: ts.server.protocol.DiagnosticWithLinePosition, afterEditDiag: ts.server.protocol.DiagnosticWithLinePosition) { assert.equal(beforeEditDiag.message, afterEditDiag.message); assert.equal(beforeEditDiag.code, afterEditDiag.code); assert.equal(beforeEditDiag.category, afterEditDiag.category); @@ -736,25 +734,24 @@ declare module '@custom/plugin' { describe("unittests:: tsserver:: Project Errors with config file change", () => { it("Updates diagnostics when '--noUnusedLabels' changes", () => { - const aTs: File = { path: "/a.ts", content: "label: while (1) {}" }; + const aTs: ts.projectSystem.File = { path: "/a.ts", content: "label: while (1) {}" }; const options = (allowUnusedLabels: boolean) => `{ "compilerOptions": { "allowUnusedLabels": ${allowUnusedLabels} } }`; - const tsconfig: File = { path: "/tsconfig.json", content: options(/*allowUnusedLabels*/ true) }; - - const host = createServerHost([aTs, tsconfig]); - const session = createSession(host); - openFilesForSession([aTs], session); + const tsconfig: ts.projectSystem.File = { path: "/tsconfig.json", content: options(/*allowUnusedLabels*/ true) }; + const host = ts.projectSystem.createServerHost([aTs, tsconfig]); + const session = ts.projectSystem.createSession(host); + ts.projectSystem.openFilesForSession([aTs], session); host.modifyFile(tsconfig.path, options(/*allowUnusedLabels*/ false)); host.runQueuedTimeoutCallbacks(); - const response = executeSessionRequest(session, protocol.CommandTypes.SemanticDiagnosticsSync, { file: aTs.path }) as protocol.Diagnostic[] | undefined; - assert.deepEqual(response, [ + const response = ts.projectSystem.executeSessionRequest(session, ts.projectSystem.protocol.CommandTypes.SemanticDiagnosticsSync, { file: aTs.path }) as ts.projectSystem.protocol.Diagnostic[] | undefined; + assert.deepEqual(response, [ { start: { line: 1, offset: 1 }, end: { line: 1, offset: 1 + "label".length }, text: "Unused label.", category: "error", - code: Diagnostics.Unused_label.code, + code: ts.Diagnostics.Unused_label.code, relatedInformation: undefined, reportsUnnecessary: true, reportsDeprecated: undefined, @@ -765,19 +762,21 @@ declare module '@custom/plugin' { }); describe("unittests:: tsserver:: Project Errors with resolveJsonModule", () => { - function createSessionForTest({ include }: { include: readonly string[]; }) { - const test: File = { - path: `${tscWatch.projectRoot}/src/test.ts`, + function createSessionForTest({ include }: { + include: readonly string[]; + }) { + const test: ts.projectSystem.File = { + path: `${ts.tscWatch.projectRoot}/src/test.ts`, content: `import * as blabla from "./blabla.json"; declare var console: any; console.log(blabla);` }; - const blabla: File = { - path: `${tscWatch.projectRoot}/src/blabla.json`, + const blabla: ts.projectSystem.File = { + path: `${ts.tscWatch.projectRoot}/src/blabla.json`, content: "{}" }; - const tsconfig: File = { - path: `${tscWatch.projectRoot}/tsconfig.json`, + const tsconfig: ts.projectSystem.File = { + path: `${ts.tscWatch.projectRoot}/tsconfig.json`, content: JSON.stringify({ compilerOptions: { resolveJsonModule: true, @@ -787,9 +786,9 @@ console.log(blabla);` }) }; - const host = createServerHost([test, blabla, libFile, tsconfig]); - const session = createSession(host, { canUseEvents: true, logger: createLoggerWithInMemoryLogs() }); - openFilesForSession([test], session); + const host = ts.projectSystem.createServerHost([test, blabla, ts.projectSystem.libFile, tsconfig]); + const session = ts.projectSystem.createSession(host, { canUseEvents: true, logger: ts.projectSystem.createLoggerWithInMemoryLogs() }); + ts.projectSystem.openFilesForSession([test], session); return { host, session, test, blabla, tsconfig }; } @@ -797,56 +796,56 @@ console.log(blabla);` const { host, session, test } = createSessionForTest({ include: ["./src/*.ts", "./src/*.json"] }); - verifyGetErrRequest({ session, host, files: [test] }); - baselineTsserverLogs("projectErrors", `should not report incorrect error when json is root file found by tsconfig`, session); + ts.projectSystem.verifyGetErrRequest({ session, host, files: [test] }); + ts.projectSystem.baselineTsserverLogs("projectErrors", `should not report incorrect error when json is root file found by tsconfig`, session); }); it("should report error when json is not root file found by tsconfig", () => { const { host, session, test } = createSessionForTest({ include: ["./src/*.ts"] }); - verifyGetErrRequest({ session, host, files: [test] }); - baselineTsserverLogs("projectErrors", `should report error when json is not root file found by tsconfig`, session); + ts.projectSystem.verifyGetErrRequest({ session, host, files: [test] }); + ts.projectSystem.baselineTsserverLogs("projectErrors", `should report error when json is not root file found by tsconfig`, session); }); }); describe("unittests:: tsserver:: Project Errors with npm install when", () => { function verifyNpmInstall(timeoutDuringPartialInstallation: boolean) { - const main: File = { - path: `${tscWatch.projectRoot}/src/main.ts`, + const main: ts.projectSystem.File = { + path: `${ts.tscWatch.projectRoot}/src/main.ts`, content: "import * as _a from '@angular/core';" }; - const config: File = { - path: `${tscWatch.projectRoot}/tsconfig.json`, + const config: ts.projectSystem.File = { + path: `${ts.tscWatch.projectRoot}/tsconfig.json`, content: "{}" }; // Move things from staging to node_modules without triggering watch - const moduleFile: File = { - path: `${tscWatch.projectRoot}/node_modules/@angular/core/index.d.ts`, + const moduleFile: ts.projectSystem.File = { + path: `${ts.tscWatch.projectRoot}/node_modules/@angular/core/index.d.ts`, content: `export const y = 10;` }; - const projectFiles = [main, libFile, config]; - const host = createServerHost(projectFiles); - const session = createSession(host, { canUseEvents: true, logger: createLoggerWithInMemoryLogs() }); - openFilesForSession([{ file: main, projectRootPath: tscWatch.projectRoot }], session); - verifyGetErrRequest({ session, host, files: [main] }); + const projectFiles = [main, ts.projectSystem.libFile, config]; + const host = ts.projectSystem.createServerHost(projectFiles); + const session = ts.projectSystem.createSession(host, { canUseEvents: true, logger: ts.projectSystem.createLoggerWithInMemoryLogs() }); + ts.projectSystem.openFilesForSession([{ file: main, projectRootPath: ts.tscWatch.projectRoot }], session); + ts.projectSystem.verifyGetErrRequest({ session, host, files: [main] }); let npmInstallComplete = false; // Simulate npm install - let filesAndFoldersToAdd: (File | Folder)[] = [ - { path: `${tscWatch.projectRoot}/node_modules` }, // This should queue update - { path: `${tscWatch.projectRoot}/node_modules/.staging` }, - { path: `${tscWatch.projectRoot}/node_modules/.staging/@babel` }, - { path: `${tscWatch.projectRoot}/node_modules/.staging/@babel/helper-plugin-utils-a06c629f` }, - { path: `${tscWatch.projectRoot}/node_modules/.staging/core-js-db53158d` }, + let filesAndFoldersToAdd: (ts.projectSystem.File | ts.projectSystem.Folder)[] = [ + { path: `${ts.tscWatch.projectRoot}/node_modules` }, + { path: `${ts.tscWatch.projectRoot}/node_modules/.staging` }, + { path: `${ts.tscWatch.projectRoot}/node_modules/.staging/@babel` }, + { path: `${ts.tscWatch.projectRoot}/node_modules/.staging/@babel/helper-plugin-utils-a06c629f` }, + { path: `${ts.tscWatch.projectRoot}/node_modules/.staging/core-js-db53158d` }, ]; verifyWhileNpmInstall(3); filesAndFoldersToAdd = [ - { path: `${tscWatch.projectRoot}/node_modules/.staging/@angular/platform-browser-dynamic-5efaaa1a` }, - { path: `${tscWatch.projectRoot}/node_modules/.staging/@angular/cli-c1e44b05/models/analytics.d.ts`, content: `export const x = 10;` }, - { path: `${tscWatch.projectRoot}/node_modules/.staging/@angular/core-0963aebf/index.d.ts`, content: `export const y = 10;` }, + { path: `${ts.tscWatch.projectRoot}/node_modules/.staging/@angular/platform-browser-dynamic-5efaaa1a` }, + { path: `${ts.tscWatch.projectRoot}/node_modules/.staging/@angular/cli-c1e44b05/models/analytics.d.ts`, content: `export const x = 10;` }, + { path: `${ts.tscWatch.projectRoot}/node_modules/.staging/@angular/core-0963aebf/index.d.ts`, content: `export const y = 10;` }, ]; // Since we added/removed in .staging no timeout verifyWhileNpmInstall(0); @@ -857,13 +856,13 @@ console.log(blabla);` verifyWhileNpmInstall(0); // Remove staging folder to remove errors - host.deleteFolder(`${tscWatch.projectRoot}/node_modules/.staging`, /*recursive*/ true); + host.deleteFolder(`${ts.tscWatch.projectRoot}/node_modules/.staging`, /*recursive*/ true); npmInstallComplete = true; projectFiles.push(moduleFile); // Additional watch for watching script infos from node_modules verifyWhileNpmInstall(3); - baselineTsserverLogs("projectErrors", `npm install when timeout occurs ${timeoutDuringPartialInstallation ? "inbetween" : "after"} installation`, session); + ts.projectSystem.baselineTsserverLogs("projectErrors", `npm install when timeout occurs ${timeoutDuringPartialInstallation ? "inbetween" : "after"} installation`, session); function verifyWhileNpmInstall(timeouts: number) { filesAndFoldersToAdd.forEach(f => host.ensureFileOrFolder(f)); @@ -876,7 +875,7 @@ console.log(blabla);` else { host.checkTimeoutQueueLength(timeouts ? 3 : 2); } - verifyGetErrRequest({ session, host, files: [main], existingTimeouts: !npmInstallComplete && !timeoutDuringPartialInstallation ? timeouts ? 3 : 2 : undefined }); + ts.projectSystem.verifyGetErrRequest({ session, host, files: [main], existingTimeouts: !npmInstallComplete && !timeoutDuringPartialInstallation ? timeouts ? 3 : 2 : undefined }); } } diff --git a/src/testRunner/unittests/tsserver/projectReferenceCompileOnSave.ts b/src/testRunner/unittests/tsserver/projectReferenceCompileOnSave.ts index 97132be83b75d..29001c8852c81 100644 --- a/src/testRunner/unittests/tsserver/projectReferenceCompileOnSave.ts +++ b/src/testRunner/unittests/tsserver/projectReferenceCompileOnSave.ts @@ -1,21 +1,21 @@ namespace ts.projectSystem { describe("unittests:: tsserver:: with project references and compile on save", () => { - const dependecyLocation = `${tscWatch.projectRoot}/dependency`; - const usageLocation = `${tscWatch.projectRoot}/usage`; - const dependencyTs: File = { + const dependecyLocation = `${ts.tscWatch.projectRoot}/dependency`; + const usageLocation = `${ts.tscWatch.projectRoot}/usage`; + const dependencyTs: ts.projectSystem.File = { path: `${dependecyLocation}/fns.ts`, content: `export function fn1() { } export function fn2() { } ` }; - const dependencyConfig: File = { + const dependencyConfig: ts.projectSystem.File = { path: `${dependecyLocation}/tsconfig.json`, content: JSON.stringify({ compilerOptions: { composite: true, declarationDir: "../decls" }, compileOnSave: true }) }; - const usageTs: File = { + const usageTs: ts.projectSystem.File = { path: `${usageLocation}/usage.ts`, content: `import { fn1, @@ -25,7 +25,7 @@ fn1(); fn2(); ` }; - const usageConfig: File = { + const usageConfig: ts.projectSystem.File = { path: `${usageLocation}/tsconfig.json`, content: JSON.stringify({ compileOnSave: true, @@ -39,7 +39,7 @@ fn2(); exports.fn3 = fn3;`; const changeDts = "export declare function fn3(): void;"; - function expectedAffectedFiles(config: File, fileNames: readonly File[]): protocol.CompileOnSaveAffectedFileListSingleProject { + function expectedAffectedFiles(config: ts.projectSystem.File, fileNames: readonly ts.projectSystem.File[]): ts.projectSystem.protocol.CompileOnSaveAffectedFileListSingleProject { return { projectFileName: config.path, fileNames: fileNames.map(f => f.path), @@ -47,7 +47,7 @@ exports.fn3 = fn3;`; }; } - function expectedUsageEmitFiles(appendJsText?: string): readonly File[] { + function expectedUsageEmitFiles(appendJsText?: string): readonly ts.projectSystem.File[] { const appendJs = appendJsText ? `${appendJsText} ` : ""; return [{ @@ -61,7 +61,7 @@ ${appendJs}` }]; } - function expectedEmitOutput(expectedFiles: readonly File[]): EmitOutput { + function expectedEmitOutput(expectedFiles: readonly ts.projectSystem.File[]): ts.EmitOutput { return { outputFiles: expectedFiles.map(({ path, content }) => ({ name: path, @@ -69,19 +69,19 @@ ${appendJs}` writeByteOrderMark: false })), emitSkipped: false, - diagnostics: emptyArray + diagnostics: ts.emptyArray }; } - function noEmitOutput(): EmitOutput { + function noEmitOutput(): ts.EmitOutput { return { emitSkipped: true, outputFiles: [], - diagnostics: emptyArray + diagnostics: ts.emptyArray }; } - function expectedDependencyEmitFiles(appendJsText?: string, appendDtsText?: string): readonly File[] { + function expectedDependencyEmitFiles(appendJsText?: string, appendDtsText?: string): readonly ts.projectSystem.File[] { const appendJs = appendJsText ? `${appendJsText} ` : ""; const appendDts = appendDtsText ? `${appendDtsText} @@ -99,7 +99,7 @@ exports.fn2 = fn2; ${appendJs}` }, { - path: `${tscWatch.projectRoot}/decls/fns.d.ts`, + path: `${ts.tscWatch.projectRoot}/decls/fns.d.ts`, content: `export declare function fn1(): void; export declare function fn2(): void; ${appendDts}` @@ -110,24 +110,22 @@ ${appendDts}` describe("when dependency project is not open", () => { describe("Of usageTs", () => { it("with initial file open, without specifying project file", () => { - const host = TestFSWithWatch.changeToHostTrackingWrittenFiles( - createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]) - ); - const session = createSession(host); - openFilesForSession([usageTs], session); + const host = ts.TestFSWithWatch.changeToHostTrackingWrittenFiles(ts.projectSystem.createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, ts.projectSystem.libFile])); + const session = ts.projectSystem.createSession(host); + ts.projectSystem.openFilesForSession([usageTs], session); // Verify CompileOnSaveAffectedFileList - const actualAffectedFiles = session.executeCommandSeq({ - command: protocol.CommandTypes.CompileOnSaveAffectedFileList, + const actualAffectedFiles = session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.CompileOnSaveAffectedFileList, arguments: { file: usageTs.path } - }).response as protocol.CompileOnSaveAffectedFileListSingleProject[]; + }).response as ts.projectSystem.protocol.CompileOnSaveAffectedFileListSingleProject[]; assert.deepEqual(actualAffectedFiles, [ expectedAffectedFiles(usageConfig, [usageTs]) ], "Affected files"); // Verify CompileOnSaveEmit - const actualEmit = session.executeCommandSeq({ - command: protocol.CommandTypes.CompileOnSaveEmitFile, + const actualEmit = session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.CompileOnSaveEmitFile, arguments: { file: usageTs.path } }).response; assert.isTrue(actualEmit, "Emit files"); @@ -135,35 +133,33 @@ ${appendDts}` assert.equal(host.writtenFiles.size, expectedFiles.length); for (const file of expectedFiles) { assert.equal(host.readFile(file.path), file.content, `Expected to write ${file.path}`); - assert.isTrue(host.writtenFiles.has(file.path as Path), `${file.path} is newly written`); + assert.isTrue(host.writtenFiles.has(file.path as ts.Path), `${file.path} is newly written`); } // Verify EmitOutput - const { exportedModulesFromDeclarationEmit: _1, ...actualEmitOutput } = session.executeCommandSeq({ - command: protocol.CommandTypes.EmitOutput, + const { exportedModulesFromDeclarationEmit: _1, ...actualEmitOutput } = session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.EmitOutput, arguments: { file: usageTs.path } - }).response as EmitOutput; + }).response as ts.EmitOutput; assert.deepEqual(actualEmitOutput, expectedEmitOutput(expectedFiles), "Emit output"); }); it("with initial file open, with specifying project file", () => { - const host = TestFSWithWatch.changeToHostTrackingWrittenFiles( - createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]) - ); - const session = createSession(host); - openFilesForSession([usageTs], session); + const host = ts.TestFSWithWatch.changeToHostTrackingWrittenFiles(ts.projectSystem.createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, ts.projectSystem.libFile])); + const session = ts.projectSystem.createSession(host); + ts.projectSystem.openFilesForSession([usageTs], session); // Verify CompileOnSaveAffectedFileList - const actualAffectedFiles = session.executeCommandSeq({ - command: protocol.CommandTypes.CompileOnSaveAffectedFileList, + const actualAffectedFiles = session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.CompileOnSaveAffectedFileList, arguments: { file: usageTs.path, projectFileName: usageConfig.path } - }).response as protocol.CompileOnSaveAffectedFileListSingleProject[]; + }).response as ts.projectSystem.protocol.CompileOnSaveAffectedFileListSingleProject[]; assert.deepEqual(actualAffectedFiles, [ expectedAffectedFiles(usageConfig, [usageTs]) ], "Affected files"); // Verify CompileOnSaveEmit - const actualEmit = session.executeCommandSeq({ - command: protocol.CommandTypes.CompileOnSaveEmitFile, + const actualEmit = session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.CompileOnSaveEmitFile, arguments: { file: usageTs.path, projectFileName: usageConfig.path } }).response; assert.isTrue(actualEmit, "Emit files"); @@ -171,42 +167,39 @@ ${appendDts}` assert.equal(host.writtenFiles.size, expectedFiles.length); for (const file of expectedFiles) { assert.equal(host.readFile(file.path), file.content, `Expected to write ${file.path}`); - assert.isTrue(host.writtenFiles.has(file.path as Path), `${file.path} is newly written`); + assert.isTrue(host.writtenFiles.has(file.path as ts.Path), `${file.path} is newly written`); } // Verify EmitOutput - const { exportedModulesFromDeclarationEmit: _1, ...actualEmitOutput } = session.executeCommandSeq({ - command: protocol.CommandTypes.EmitOutput, + const { exportedModulesFromDeclarationEmit: _1, ...actualEmitOutput } = session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.EmitOutput, arguments: { file: usageTs.path, projectFileName: usageConfig.path } - }).response as EmitOutput; + }).response as ts.EmitOutput; assert.deepEqual(actualEmitOutput, expectedEmitOutput(expectedFiles), "Emit output"); }); it("with local change to dependency, without specifying project file", () => { - const host = TestFSWithWatch.changeToHostTrackingWrittenFiles( - createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]) - ); - const session = createSession(host); - openFilesForSession([usageTs], session); - - session.executeCommandSeq({ - command: protocol.CommandTypes.CompileOnSaveAffectedFileList, + const host = ts.TestFSWithWatch.changeToHostTrackingWrittenFiles(ts.projectSystem.createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, ts.projectSystem.libFile])); + const session = ts.projectSystem.createSession(host); + ts.projectSystem.openFilesForSession([usageTs], session); + session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.CompileOnSaveAffectedFileList, arguments: { file: dependencyTs.path } }); host.writeFile(dependencyTs.path, `${dependencyTs.content}${localChange}`); host.writtenFiles.clear(); // Verify CompileOnSaveAffectedFileList - const actualAffectedFiles = session.executeCommandSeq({ - command: protocol.CommandTypes.CompileOnSaveAffectedFileList, + const actualAffectedFiles = session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.CompileOnSaveAffectedFileList, arguments: { file: usageTs.path } - }).response as protocol.CompileOnSaveAffectedFileListSingleProject[]; + }).response as ts.projectSystem.protocol.CompileOnSaveAffectedFileListSingleProject[]; assert.deepEqual(actualAffectedFiles, [ expectedAffectedFiles(usageConfig, [usageTs]) ], "Affected files"); // Verify CompileOnSaveEmit - const actualEmit = session.executeCommandSeq({ - command: protocol.CommandTypes.CompileOnSaveEmitFile, + const actualEmit = session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.CompileOnSaveEmitFile, arguments: { file: usageTs.path } }).response; assert.isTrue(actualEmit, "Emit files"); @@ -214,42 +207,39 @@ ${appendDts}` assert.equal(host.writtenFiles.size, expectedFiles.length); for (const file of expectedFiles) { assert.equal(host.readFile(file.path), file.content, `Expected to write ${file.path}`); - assert.isTrue(host.writtenFiles.has(file.path as Path), `${file.path} is newly written`); + assert.isTrue(host.writtenFiles.has(file.path as ts.Path), `${file.path} is newly written`); } // Verify EmitOutput - const { exportedModulesFromDeclarationEmit: _1, ...actualEmitOutput } = session.executeCommandSeq({ - command: protocol.CommandTypes.EmitOutput, + const { exportedModulesFromDeclarationEmit: _1, ...actualEmitOutput } = session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.EmitOutput, arguments: { file: usageTs.path } - }).response as EmitOutput; + }).response as ts.EmitOutput; assert.deepEqual(actualEmitOutput, expectedEmitOutput(expectedFiles), "Emit output"); }); it("with local change to dependency, with specifying project file", () => { - const host = TestFSWithWatch.changeToHostTrackingWrittenFiles( - createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]) - ); - const session = createSession(host); - openFilesForSession([usageTs], session); - - session.executeCommandSeq({ - command: protocol.CommandTypes.CompileOnSaveAffectedFileList, + const host = ts.TestFSWithWatch.changeToHostTrackingWrittenFiles(ts.projectSystem.createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, ts.projectSystem.libFile])); + const session = ts.projectSystem.createSession(host); + ts.projectSystem.openFilesForSession([usageTs], session); + session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.CompileOnSaveAffectedFileList, arguments: { file: dependencyTs.path } }); host.writeFile(dependencyTs.path, `${dependencyTs.content}${localChange}`); host.writtenFiles.clear(); // Verify CompileOnSaveAffectedFileList - const actualAffectedFiles = session.executeCommandSeq({ - command: protocol.CommandTypes.CompileOnSaveAffectedFileList, + const actualAffectedFiles = session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.CompileOnSaveAffectedFileList, arguments: { file: usageTs.path, projectFileName: usageConfig.path } - }).response as protocol.CompileOnSaveAffectedFileListSingleProject[]; + }).response as ts.projectSystem.protocol.CompileOnSaveAffectedFileListSingleProject[]; assert.deepEqual(actualAffectedFiles, [ expectedAffectedFiles(usageConfig, [usageTs]) ], "Affected files"); // Verify CompileOnSaveEmit - const actualEmit = session.executeCommandSeq({ - command: protocol.CommandTypes.CompileOnSaveEmitFile, + const actualEmit = session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.CompileOnSaveEmitFile, arguments: { file: usageTs.path, projectFileName: usageConfig.path } }).response; assert.isTrue(actualEmit, "Emit files"); @@ -257,31 +247,28 @@ ${appendDts}` assert.equal(host.writtenFiles.size, expectedFiles.length); for (const file of expectedFiles) { assert.equal(host.readFile(file.path), file.content, `Expected to write ${file.path}`); - assert.isTrue(host.writtenFiles.has(file.path as Path), `${file.path} is newly written`); + assert.isTrue(host.writtenFiles.has(file.path as ts.Path), `${file.path} is newly written`); } // Verify EmitOutput - const { exportedModulesFromDeclarationEmit: _1, ...actualEmitOutput } = session.executeCommandSeq({ - command: protocol.CommandTypes.EmitOutput, + const { exportedModulesFromDeclarationEmit: _1, ...actualEmitOutput } = session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.EmitOutput, arguments: { file: usageTs.path, projectFileName: usageConfig.path } - }).response as EmitOutput; + }).response as ts.EmitOutput; assert.deepEqual(actualEmitOutput, expectedEmitOutput(expectedFiles), "Emit output"); }); it("with local change to usage, without specifying project file", () => { - const host = TestFSWithWatch.changeToHostTrackingWrittenFiles( - createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]) - ); - const session = createSession(host); - openFilesForSession([usageTs], session); - - session.executeCommandSeq({ - command: protocol.CommandTypes.CompileOnSaveAffectedFileList, + const host = ts.TestFSWithWatch.changeToHostTrackingWrittenFiles(ts.projectSystem.createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, ts.projectSystem.libFile])); + const session = ts.projectSystem.createSession(host); + ts.projectSystem.openFilesForSession([usageTs], session); + session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.CompileOnSaveAffectedFileList, arguments: { file: dependencyTs.path } }); - const toLocation = protocolToLocation(usageTs.content); + const toLocation = ts.projectSystem.protocolToLocation(usageTs.content); const location = toLocation(usageTs.content.length); - session.executeCommandSeq({ - command: protocol.CommandTypes.Change, + session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.Change, arguments: { file: usageTs.path, ...location, @@ -293,17 +280,17 @@ ${appendDts}` host.writtenFiles.clear(); // Verify CompileOnSaveAffectedFileList - const actualAffectedFiles = session.executeCommandSeq({ - command: protocol.CommandTypes.CompileOnSaveAffectedFileList, + const actualAffectedFiles = session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.CompileOnSaveAffectedFileList, arguments: { file: usageTs.path } - }).response as protocol.CompileOnSaveAffectedFileListSingleProject[]; + }).response as ts.projectSystem.protocol.CompileOnSaveAffectedFileListSingleProject[]; assert.deepEqual(actualAffectedFiles, [ expectedAffectedFiles(usageConfig, [usageTs]) ], "Affected files"); // Verify CompileOnSaveEmit - const actualEmit = session.executeCommandSeq({ - command: protocol.CommandTypes.CompileOnSaveEmitFile, + const actualEmit = session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.CompileOnSaveEmitFile, arguments: { file: usageTs.path } }).response; assert.isTrue(actualEmit, "Emit files"); @@ -311,31 +298,28 @@ ${appendDts}` assert.equal(host.writtenFiles.size, expectedFiles.length); for (const file of expectedFiles) { assert.equal(host.readFile(file.path), file.content, `Expected to write ${file.path}`); - assert.isTrue(host.writtenFiles.has(file.path as Path), `${file.path} is newly written`); + assert.isTrue(host.writtenFiles.has(file.path as ts.Path), `${file.path} is newly written`); } // Verify EmitOutput - const { exportedModulesFromDeclarationEmit: _1, ...actualEmitOutput } = session.executeCommandSeq({ - command: protocol.CommandTypes.EmitOutput, + const { exportedModulesFromDeclarationEmit: _1, ...actualEmitOutput } = session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.EmitOutput, arguments: { file: usageTs.path } - }).response as EmitOutput; + }).response as ts.EmitOutput; assert.deepEqual(actualEmitOutput, expectedEmitOutput(expectedFiles), "Emit output"); }); it("with local change to usage, with specifying project file", () => { - const host = TestFSWithWatch.changeToHostTrackingWrittenFiles( - createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]) - ); - const session = createSession(host); - openFilesForSession([usageTs], session); - - session.executeCommandSeq({ - command: protocol.CommandTypes.CompileOnSaveAffectedFileList, + const host = ts.TestFSWithWatch.changeToHostTrackingWrittenFiles(ts.projectSystem.createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, ts.projectSystem.libFile])); + const session = ts.projectSystem.createSession(host); + ts.projectSystem.openFilesForSession([usageTs], session); + session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.CompileOnSaveAffectedFileList, arguments: { file: dependencyTs.path } }); - const toLocation = protocolToLocation(usageTs.content); + const toLocation = ts.projectSystem.protocolToLocation(usageTs.content); const location = toLocation(usageTs.content.length); - session.executeCommandSeq({ - command: protocol.CommandTypes.Change, + session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.Change, arguments: { file: usageTs.path, ...location, @@ -347,17 +331,17 @@ ${appendDts}` host.writtenFiles.clear(); // Verify CompileOnSaveAffectedFileList - const actualAffectedFiles = session.executeCommandSeq({ - command: protocol.CommandTypes.CompileOnSaveAffectedFileList, + const actualAffectedFiles = session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.CompileOnSaveAffectedFileList, arguments: { file: usageTs.path, projectFileName: usageConfig.path } - }).response as protocol.CompileOnSaveAffectedFileListSingleProject[]; + }).response as ts.projectSystem.protocol.CompileOnSaveAffectedFileListSingleProject[]; assert.deepEqual(actualAffectedFiles, [ expectedAffectedFiles(usageConfig, [usageTs]) ], "Affected files"); // Verify CompileOnSaveEmit - const actualEmit = session.executeCommandSeq({ - command: protocol.CommandTypes.CompileOnSaveEmitFile, + const actualEmit = session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.CompileOnSaveEmitFile, arguments: { file: usageTs.path, projectFileName: usageConfig.path } }).response; assert.isTrue(actualEmit, "Emit files"); @@ -365,42 +349,39 @@ ${appendDts}` assert.equal(host.writtenFiles.size, expectedFiles.length); for (const file of expectedFiles) { assert.equal(host.readFile(file.path), file.content, `Expected to write ${file.path}`); - assert.isTrue(host.writtenFiles.has(file.path as Path), `${file.path} is newly written`); + assert.isTrue(host.writtenFiles.has(file.path as ts.Path), `${file.path} is newly written`); } // Verify EmitOutput - const { exportedModulesFromDeclarationEmit: _1, ...actualEmitOutput } = session.executeCommandSeq({ - command: protocol.CommandTypes.EmitOutput, + const { exportedModulesFromDeclarationEmit: _1, ...actualEmitOutput } = session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.EmitOutput, arguments: { file: usageTs.path, projectFileName: usageConfig.path } - }).response as EmitOutput; + }).response as ts.EmitOutput; assert.deepEqual(actualEmitOutput, expectedEmitOutput(expectedFiles), "Emit output"); }); it("with change to dependency, without specifying project file", () => { - const host = TestFSWithWatch.changeToHostTrackingWrittenFiles( - createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]) - ); - const session = createSession(host); - openFilesForSession([usageTs], session); - - session.executeCommandSeq({ - command: protocol.CommandTypes.CompileOnSaveAffectedFileList, + const host = ts.TestFSWithWatch.changeToHostTrackingWrittenFiles(ts.projectSystem.createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, ts.projectSystem.libFile])); + const session = ts.projectSystem.createSession(host); + ts.projectSystem.openFilesForSession([usageTs], session); + session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.CompileOnSaveAffectedFileList, arguments: { file: dependencyTs.path } }); host.writeFile(dependencyTs.path, `${dependencyTs.content}${change}`); host.writtenFiles.clear(); // Verify CompileOnSaveAffectedFileList - const actualAffectedFiles = session.executeCommandSeq({ - command: protocol.CommandTypes.CompileOnSaveAffectedFileList, + const actualAffectedFiles = session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.CompileOnSaveAffectedFileList, arguments: { file: usageTs.path } - }).response as protocol.CompileOnSaveAffectedFileListSingleProject[]; + }).response as ts.projectSystem.protocol.CompileOnSaveAffectedFileListSingleProject[]; assert.deepEqual(actualAffectedFiles, [ expectedAffectedFiles(usageConfig, [usageTs]) ], "Affected files"); // Verify CompileOnSaveEmit - const actualEmit = session.executeCommandSeq({ - command: protocol.CommandTypes.CompileOnSaveEmitFile, + const actualEmit = session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.CompileOnSaveEmitFile, arguments: { file: usageTs.path } }).response; assert.isTrue(actualEmit, "Emit files"); @@ -408,42 +389,39 @@ ${appendDts}` assert.equal(host.writtenFiles.size, expectedFiles.length); for (const file of expectedFiles) { assert.equal(host.readFile(file.path), file.content, `Expected to write ${file.path}`); - assert.isTrue(host.writtenFiles.has(file.path as Path), `${file.path} is newly written`); + assert.isTrue(host.writtenFiles.has(file.path as ts.Path), `${file.path} is newly written`); } // Verify EmitOutput - const { exportedModulesFromDeclarationEmit: _1, ...actualEmitOutput } = session.executeCommandSeq({ - command: protocol.CommandTypes.EmitOutput, + const { exportedModulesFromDeclarationEmit: _1, ...actualEmitOutput } = session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.EmitOutput, arguments: { file: usageTs.path } - }).response as EmitOutput; + }).response as ts.EmitOutput; assert.deepEqual(actualEmitOutput, expectedEmitOutput(expectedFiles), "Emit output"); }); it("with change to dependency, with specifying project file", () => { - const host = TestFSWithWatch.changeToHostTrackingWrittenFiles( - createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]) - ); - const session = createSession(host); - openFilesForSession([usageTs], session); - - session.executeCommandSeq({ - command: protocol.CommandTypes.CompileOnSaveAffectedFileList, + const host = ts.TestFSWithWatch.changeToHostTrackingWrittenFiles(ts.projectSystem.createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, ts.projectSystem.libFile])); + const session = ts.projectSystem.createSession(host); + ts.projectSystem.openFilesForSession([usageTs], session); + session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.CompileOnSaveAffectedFileList, arguments: { file: dependencyTs.path } }); host.writeFile(dependencyTs.path, `${dependencyTs.content}${change}`); host.writtenFiles.clear(); // Verify CompileOnSaveAffectedFileList - const actualAffectedFiles = session.executeCommandSeq({ - command: protocol.CommandTypes.CompileOnSaveAffectedFileList, + const actualAffectedFiles = session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.CompileOnSaveAffectedFileList, arguments: { file: usageTs.path, projectFileName: usageConfig.path } - }).response as protocol.CompileOnSaveAffectedFileListSingleProject[]; + }).response as ts.projectSystem.protocol.CompileOnSaveAffectedFileListSingleProject[]; assert.deepEqual(actualAffectedFiles, [ expectedAffectedFiles(usageConfig, [usageTs]) ], "Affected files"); // Verify CompileOnSaveEmit - const actualEmit = session.executeCommandSeq({ - command: protocol.CommandTypes.CompileOnSaveEmitFile, + const actualEmit = session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.CompileOnSaveEmitFile, arguments: { file: usageTs.path, projectFileName: usageConfig.path } }).response; assert.isTrue(actualEmit, "Emit files"); @@ -451,31 +429,28 @@ ${appendDts}` assert.equal(host.writtenFiles.size, expectedFiles.length); for (const file of expectedFiles) { assert.equal(host.readFile(file.path), file.content, `Expected to write ${file.path}`); - assert.isTrue(host.writtenFiles.has(file.path as Path), `${file.path} is newly written`); + assert.isTrue(host.writtenFiles.has(file.path as ts.Path), `${file.path} is newly written`); } // Verify EmitOutput - const { exportedModulesFromDeclarationEmit: _1, ...actualEmitOutput } = session.executeCommandSeq({ - command: protocol.CommandTypes.EmitOutput, + const { exportedModulesFromDeclarationEmit: _1, ...actualEmitOutput } = session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.EmitOutput, arguments: { file: usageTs.path, projectFileName: usageConfig.path } - }).response as EmitOutput; + }).response as ts.EmitOutput; assert.deepEqual(actualEmitOutput, expectedEmitOutput(expectedFiles), "Emit output"); }); it("with change to usage, without specifying project file", () => { - const host = TestFSWithWatch.changeToHostTrackingWrittenFiles( - createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]) - ); - const session = createSession(host); - openFilesForSession([usageTs], session); - - session.executeCommandSeq({ - command: protocol.CommandTypes.CompileOnSaveAffectedFileList, + const host = ts.TestFSWithWatch.changeToHostTrackingWrittenFiles(ts.projectSystem.createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, ts.projectSystem.libFile])); + const session = ts.projectSystem.createSession(host); + ts.projectSystem.openFilesForSession([usageTs], session); + session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.CompileOnSaveAffectedFileList, arguments: { file: dependencyTs.path } }); - const toLocation = protocolToLocation(usageTs.content); + const toLocation = ts.projectSystem.protocolToLocation(usageTs.content); const location = toLocation(usageTs.content.length); - session.executeCommandSeq({ - command: protocol.CommandTypes.Change, + session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.Change, arguments: { file: usageTs.path, ...location, @@ -487,17 +462,17 @@ ${appendDts}` host.writtenFiles.clear(); // Verify CompileOnSaveAffectedFileList - const actualAffectedFiles = session.executeCommandSeq({ - command: protocol.CommandTypes.CompileOnSaveAffectedFileList, + const actualAffectedFiles = session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.CompileOnSaveAffectedFileList, arguments: { file: usageTs.path } - }).response as protocol.CompileOnSaveAffectedFileListSingleProject[]; + }).response as ts.projectSystem.protocol.CompileOnSaveAffectedFileListSingleProject[]; assert.deepEqual(actualAffectedFiles, [ expectedAffectedFiles(usageConfig, [usageTs]) ], "Affected files"); // Verify CompileOnSaveEmit - const actualEmit = session.executeCommandSeq({ - command: protocol.CommandTypes.CompileOnSaveEmitFile, + const actualEmit = session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.CompileOnSaveEmitFile, arguments: { file: usageTs.path } }).response; assert.isTrue(actualEmit, "Emit files"); @@ -505,31 +480,28 @@ ${appendDts}` assert.equal(host.writtenFiles.size, expectedFiles.length); for (const file of expectedFiles) { assert.equal(host.readFile(file.path), file.content, `Expected to write ${file.path}`); - assert.isTrue(host.writtenFiles.has(file.path as Path), `${file.path} is newly written`); + assert.isTrue(host.writtenFiles.has(file.path as ts.Path), `${file.path} is newly written`); } // Verify EmitOutput - const { exportedModulesFromDeclarationEmit: _1, ...actualEmitOutput } = session.executeCommandSeq({ - command: protocol.CommandTypes.EmitOutput, + const { exportedModulesFromDeclarationEmit: _1, ...actualEmitOutput } = session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.EmitOutput, arguments: { file: usageTs.path } - }).response as EmitOutput; + }).response as ts.EmitOutput; assert.deepEqual(actualEmitOutput, expectedEmitOutput(expectedFiles), "Emit output"); }); it("with change to usage, with specifying project file", () => { - const host = TestFSWithWatch.changeToHostTrackingWrittenFiles( - createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]) - ); - const session = createSession(host); - openFilesForSession([usageTs], session); - - session.executeCommandSeq({ - command: protocol.CommandTypes.CompileOnSaveAffectedFileList, + const host = ts.TestFSWithWatch.changeToHostTrackingWrittenFiles(ts.projectSystem.createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, ts.projectSystem.libFile])); + const session = ts.projectSystem.createSession(host); + ts.projectSystem.openFilesForSession([usageTs], session); + session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.CompileOnSaveAffectedFileList, arguments: { file: dependencyTs.path } }); - const toLocation = protocolToLocation(usageTs.content); + const toLocation = ts.projectSystem.protocolToLocation(usageTs.content); const location = toLocation(usageTs.content.length); - session.executeCommandSeq({ - command: protocol.CommandTypes.Change, + session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.Change, arguments: { file: usageTs.path, ...location, @@ -541,17 +513,17 @@ ${appendDts}` host.writtenFiles.clear(); // Verify CompileOnSaveAffectedFileList - const actualAffectedFiles = session.executeCommandSeq({ - command: protocol.CommandTypes.CompileOnSaveAffectedFileList, + const actualAffectedFiles = session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.CompileOnSaveAffectedFileList, arguments: { file: usageTs.path, projectFileName: usageConfig.path } - }).response as protocol.CompileOnSaveAffectedFileListSingleProject[]; + }).response as ts.projectSystem.protocol.CompileOnSaveAffectedFileListSingleProject[]; assert.deepEqual(actualAffectedFiles, [ expectedAffectedFiles(usageConfig, [usageTs]) ], "Affected files"); // Verify CompileOnSaveEmit - const actualEmit = session.executeCommandSeq({ - command: protocol.CommandTypes.CompileOnSaveEmitFile, + const actualEmit = session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.CompileOnSaveEmitFile, arguments: { file: usageTs.path, projectFileName: usageConfig.path } }).response; assert.isTrue(actualEmit, "Emit files"); @@ -559,172 +531,159 @@ ${appendDts}` assert.equal(host.writtenFiles.size, expectedFiles.length); for (const file of expectedFiles) { assert.equal(host.readFile(file.path), file.content, `Expected to write ${file.path}`); - assert.isTrue(host.writtenFiles.has(file.path as Path), `${file.path} is newly written`); + assert.isTrue(host.writtenFiles.has(file.path as ts.Path), `${file.path} is newly written`); } // Verify EmitOutput - const { exportedModulesFromDeclarationEmit: _1, ...actualEmitOutput } = session.executeCommandSeq({ - command: protocol.CommandTypes.EmitOutput, + const { exportedModulesFromDeclarationEmit: _1, ...actualEmitOutput } = session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.EmitOutput, arguments: { file: usageTs.path, projectFileName: usageConfig.path } - }).response as EmitOutput; + }).response as ts.EmitOutput; assert.deepEqual(actualEmitOutput, expectedEmitOutput(expectedFiles), "Emit output"); }); }); describe("Of dependencyTs in usage project", () => { it("with initial file open, without specifying project file", () => { - const host = TestFSWithWatch.changeToHostTrackingWrittenFiles( - createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]) - ); - const session = createSession(host); - openFilesForSession([usageTs], session); + const host = ts.TestFSWithWatch.changeToHostTrackingWrittenFiles(ts.projectSystem.createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, ts.projectSystem.libFile])); + const session = ts.projectSystem.createSession(host); + ts.projectSystem.openFilesForSession([usageTs], session); // Verify CompileOnSaveAffectedFileList - const actualAffectedFiles = session.executeCommandSeq({ - command: protocol.CommandTypes.CompileOnSaveAffectedFileList, + const actualAffectedFiles = session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.CompileOnSaveAffectedFileList, arguments: { file: dependencyTs.path } - }).response as protocol.CompileOnSaveAffectedFileListSingleProject[]; + }).response as ts.projectSystem.protocol.CompileOnSaveAffectedFileListSingleProject[]; assert.deepEqual(actualAffectedFiles, [ expectedAffectedFiles(usageConfig, [usageTs]) ], "Affected files"); // Verify CompileOnSaveEmit - const actualEmit = session.executeCommandSeq({ - command: protocol.CommandTypes.CompileOnSaveEmitFile, + const actualEmit = session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.CompileOnSaveEmitFile, arguments: { file: dependencyTs.path } }).response; assert.isFalse(actualEmit, "Emit files"); assert.equal(host.writtenFiles.size, 0); // Verify EmitOutput - const { exportedModulesFromDeclarationEmit: _1, ...actualEmitOutput } = session.executeCommandSeq({ - command: protocol.CommandTypes.EmitOutput, + const { exportedModulesFromDeclarationEmit: _1, ...actualEmitOutput } = session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.EmitOutput, arguments: { file: dependencyTs.path } - }).response as EmitOutput; + }).response as ts.EmitOutput; assert.deepEqual(actualEmitOutput, noEmitOutput(), "Emit output"); }); it("with initial file open, with specifying project file", () => { - const host = TestFSWithWatch.changeToHostTrackingWrittenFiles( - createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]) - ); - const session = createSession(host); - openFilesForSession([usageTs], session); + const host = ts.TestFSWithWatch.changeToHostTrackingWrittenFiles(ts.projectSystem.createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, ts.projectSystem.libFile])); + const session = ts.projectSystem.createSession(host); + ts.projectSystem.openFilesForSession([usageTs], session); // Verify CompileOnSaveAffectedFileList - const actualAffectedFiles = session.executeCommandSeq({ - command: protocol.CommandTypes.CompileOnSaveAffectedFileList, + const actualAffectedFiles = session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.CompileOnSaveAffectedFileList, arguments: { file: dependencyTs.path, projectFileName: usageConfig.path } - }).response as protocol.CompileOnSaveAffectedFileListSingleProject[]; + }).response as ts.projectSystem.protocol.CompileOnSaveAffectedFileListSingleProject[]; assert.deepEqual(actualAffectedFiles, [ expectedAffectedFiles(usageConfig, [usageTs]) ], "Affected files"); // Verify CompileOnSaveEmit - const actualEmit = session.executeCommandSeq({ - command: protocol.CommandTypes.CompileOnSaveEmitFile, + const actualEmit = session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.CompileOnSaveEmitFile, arguments: { file: dependencyTs.path, projectFileName: usageConfig.path } }).response; assert.isFalse(actualEmit, "Emit files"); assert.equal(host.writtenFiles.size, 0); // Verify EmitOutput - const { exportedModulesFromDeclarationEmit: _1, ...actualEmitOutput } = session.executeCommandSeq({ - command: protocol.CommandTypes.EmitOutput, + const { exportedModulesFromDeclarationEmit: _1, ...actualEmitOutput } = session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.EmitOutput, arguments: { file: dependencyTs.path, projectFileName: usageConfig.path } - }).response as EmitOutput; + }).response as ts.EmitOutput; assert.deepEqual(actualEmitOutput, noEmitOutput(), "Emit output"); }); it("with local change to dependency, without specifying project file", () => { - const host = TestFSWithWatch.changeToHostTrackingWrittenFiles( - createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]) - ); - const session = createSession(host); - openFilesForSession([usageTs], session); - - session.executeCommandSeq({ - command: protocol.CommandTypes.CompileOnSaveAffectedFileList, + const host = ts.TestFSWithWatch.changeToHostTrackingWrittenFiles(ts.projectSystem.createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, ts.projectSystem.libFile])); + const session = ts.projectSystem.createSession(host); + ts.projectSystem.openFilesForSession([usageTs], session); + session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.CompileOnSaveAffectedFileList, arguments: { file: dependencyTs.path } }); host.writeFile(dependencyTs.path, `${dependencyTs.content}${localChange}`); host.writtenFiles.clear(); // Verify CompileOnSaveAffectedFileList - const actualAffectedFiles = session.executeCommandSeq({ - command: protocol.CommandTypes.CompileOnSaveAffectedFileList, + const actualAffectedFiles = session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.CompileOnSaveAffectedFileList, arguments: { file: dependencyTs.path } - }).response as protocol.CompileOnSaveAffectedFileListSingleProject[]; + }).response as ts.projectSystem.protocol.CompileOnSaveAffectedFileListSingleProject[]; assert.deepEqual(actualAffectedFiles, [ - expectedAffectedFiles(usageConfig, emptyArray) + expectedAffectedFiles(usageConfig, ts.emptyArray) ], "Affected files"); // Verify CompileOnSaveEmit - const actualEmit = session.executeCommandSeq({ - command: protocol.CommandTypes.CompileOnSaveEmitFile, + const actualEmit = session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.CompileOnSaveEmitFile, arguments: { file: dependencyTs.path } }).response; assert.isFalse(actualEmit, "Emit files"); assert.equal(host.writtenFiles.size, 0); // Verify EmitOutput - const { exportedModulesFromDeclarationEmit: _1, ...actualEmitOutput } = session.executeCommandSeq({ - command: protocol.CommandTypes.EmitOutput, + const { exportedModulesFromDeclarationEmit: _1, ...actualEmitOutput } = session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.EmitOutput, arguments: { file: dependencyTs.path } - }).response as EmitOutput; + }).response as ts.EmitOutput; assert.deepEqual(actualEmitOutput, noEmitOutput(), "Emit output"); }); it("with local change to dependency, with specifying project file", () => { - const host = TestFSWithWatch.changeToHostTrackingWrittenFiles( - createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]) - ); - const session = createSession(host); - openFilesForSession([usageTs], session); - - session.executeCommandSeq({ - command: protocol.CommandTypes.CompileOnSaveAffectedFileList, + const host = ts.TestFSWithWatch.changeToHostTrackingWrittenFiles(ts.projectSystem.createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, ts.projectSystem.libFile])); + const session = ts.projectSystem.createSession(host); + ts.projectSystem.openFilesForSession([usageTs], session); + session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.CompileOnSaveAffectedFileList, arguments: { file: dependencyTs.path } }); host.writeFile(dependencyTs.path, `${dependencyTs.content}${localChange}`); host.writtenFiles.clear(); // Verify CompileOnSaveAffectedFileList - const actualAffectedFiles = session.executeCommandSeq({ - command: protocol.CommandTypes.CompileOnSaveAffectedFileList, + const actualAffectedFiles = session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.CompileOnSaveAffectedFileList, arguments: { file: dependencyTs.path, projectFileName: usageConfig.path } - }).response as protocol.CompileOnSaveAffectedFileListSingleProject[]; + }).response as ts.projectSystem.protocol.CompileOnSaveAffectedFileListSingleProject[]; assert.deepEqual(actualAffectedFiles, [ - expectedAffectedFiles(usageConfig, emptyArray) + expectedAffectedFiles(usageConfig, ts.emptyArray) ], "Affected files"); // Verify CompileOnSaveEmit - const actualEmit = session.executeCommandSeq({ - command: protocol.CommandTypes.CompileOnSaveEmitFile, + const actualEmit = session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.CompileOnSaveEmitFile, arguments: { file: dependencyTs.path, projectFileName: usageConfig.path } }).response; assert.isFalse(actualEmit, "Emit files"); assert.equal(host.writtenFiles.size, 0); // Verify EmitOutput - const { exportedModulesFromDeclarationEmit: _1, ...actualEmitOutput } = session.executeCommandSeq({ - command: protocol.CommandTypes.EmitOutput, + const { exportedModulesFromDeclarationEmit: _1, ...actualEmitOutput } = session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.EmitOutput, arguments: { file: dependencyTs.path, projectFileName: usageConfig.path } - }).response as EmitOutput; + }).response as ts.EmitOutput; assert.deepEqual(actualEmitOutput, noEmitOutput(), "Emit output"); }); it("with local change to usage, without specifying project file", () => { - const host = TestFSWithWatch.changeToHostTrackingWrittenFiles( - createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]) - ); - const session = createSession(host); - openFilesForSession([usageTs], session); - - session.executeCommandSeq({ - command: protocol.CommandTypes.CompileOnSaveAffectedFileList, + const host = ts.TestFSWithWatch.changeToHostTrackingWrittenFiles(ts.projectSystem.createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, ts.projectSystem.libFile])); + const session = ts.projectSystem.createSession(host); + ts.projectSystem.openFilesForSession([usageTs], session); + session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.CompileOnSaveAffectedFileList, arguments: { file: dependencyTs.path } }); - const toLocation = protocolToLocation(usageTs.content); + const toLocation = ts.projectSystem.protocolToLocation(usageTs.content); const location = toLocation(usageTs.content.length); - session.executeCommandSeq({ - command: protocol.CommandTypes.Change, + session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.Change, arguments: { file: usageTs.path, ...location, @@ -736,44 +695,41 @@ ${appendDts}` host.writtenFiles.clear(); // Verify CompileOnSaveAffectedFileList - const actualAffectedFiles = session.executeCommandSeq({ - command: protocol.CommandTypes.CompileOnSaveAffectedFileList, + const actualAffectedFiles = session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.CompileOnSaveAffectedFileList, arguments: { file: dependencyTs.path } - }).response as protocol.CompileOnSaveAffectedFileListSingleProject[]; + }).response as ts.projectSystem.protocol.CompileOnSaveAffectedFileListSingleProject[]; assert.deepEqual(actualAffectedFiles, [ - expectedAffectedFiles(usageConfig, emptyArray) + expectedAffectedFiles(usageConfig, ts.emptyArray) ], "Affected files"); // Verify CompileOnSaveEmit - const actualEmit = session.executeCommandSeq({ - command: protocol.CommandTypes.CompileOnSaveEmitFile, + const actualEmit = session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.CompileOnSaveEmitFile, arguments: { file: dependencyTs.path } }).response; assert.isFalse(actualEmit, "Emit files"); assert.equal(host.writtenFiles.size, 0); // Verify EmitOutput - const { exportedModulesFromDeclarationEmit: _1, ...actualEmitOutput } = session.executeCommandSeq({ - command: protocol.CommandTypes.EmitOutput, + const { exportedModulesFromDeclarationEmit: _1, ...actualEmitOutput } = session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.EmitOutput, arguments: { file: dependencyTs.path } - }).response as EmitOutput; + }).response as ts.EmitOutput; assert.deepEqual(actualEmitOutput, noEmitOutput(), "Emit output"); }); it("with local change to usage, with specifying project file", () => { - const host = TestFSWithWatch.changeToHostTrackingWrittenFiles( - createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]) - ); - const session = createSession(host); - openFilesForSession([usageTs], session); - - session.executeCommandSeq({ - command: protocol.CommandTypes.CompileOnSaveAffectedFileList, + const host = ts.TestFSWithWatch.changeToHostTrackingWrittenFiles(ts.projectSystem.createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, ts.projectSystem.libFile])); + const session = ts.projectSystem.createSession(host); + ts.projectSystem.openFilesForSession([usageTs], session); + session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.CompileOnSaveAffectedFileList, arguments: { file: dependencyTs.path } }); - const toLocation = protocolToLocation(usageTs.content); + const toLocation = ts.projectSystem.protocolToLocation(usageTs.content); const location = toLocation(usageTs.content.length); - session.executeCommandSeq({ - command: protocol.CommandTypes.Change, + session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.Change, arguments: { file: usageTs.path, ...location, @@ -785,120 +741,111 @@ ${appendDts}` host.writtenFiles.clear(); // Verify CompileOnSaveAffectedFileList - const actualAffectedFiles = session.executeCommandSeq({ - command: protocol.CommandTypes.CompileOnSaveAffectedFileList, + const actualAffectedFiles = session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.CompileOnSaveAffectedFileList, arguments: { file: dependencyTs.path, projectFileName: usageConfig.path } - }).response as protocol.CompileOnSaveAffectedFileListSingleProject[]; + }).response as ts.projectSystem.protocol.CompileOnSaveAffectedFileListSingleProject[]; assert.deepEqual(actualAffectedFiles, [ - expectedAffectedFiles(usageConfig, emptyArray) + expectedAffectedFiles(usageConfig, ts.emptyArray) ], "Affected files"); // Verify CompileOnSaveEmit - const actualEmit = session.executeCommandSeq({ - command: protocol.CommandTypes.CompileOnSaveEmitFile, + const actualEmit = session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.CompileOnSaveEmitFile, arguments: { file: dependencyTs.path, projectFileName: usageConfig.path } }).response; assert.isFalse(actualEmit, "Emit files"); assert.equal(host.writtenFiles.size, 0); // Verify EmitOutput - const { exportedModulesFromDeclarationEmit: _1, ...actualEmitOutput } = session.executeCommandSeq({ - command: protocol.CommandTypes.EmitOutput, + const { exportedModulesFromDeclarationEmit: _1, ...actualEmitOutput } = session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.EmitOutput, arguments: { file: dependencyTs.path, projectFileName: usageConfig.path } - }).response as EmitOutput; + }).response as ts.EmitOutput; assert.deepEqual(actualEmitOutput, noEmitOutput(), "Emit output"); }); it("with change to dependency, without specifying project file", () => { - const host = TestFSWithWatch.changeToHostTrackingWrittenFiles( - createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]) - ); - const session = createSession(host); - openFilesForSession([usageTs], session); - - session.executeCommandSeq({ - command: protocol.CommandTypes.CompileOnSaveAffectedFileList, + const host = ts.TestFSWithWatch.changeToHostTrackingWrittenFiles(ts.projectSystem.createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, ts.projectSystem.libFile])); + const session = ts.projectSystem.createSession(host); + ts.projectSystem.openFilesForSession([usageTs], session); + session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.CompileOnSaveAffectedFileList, arguments: { file: dependencyTs.path } }); host.writeFile(dependencyTs.path, `${dependencyTs.content}${change}`); host.writtenFiles.clear(); // Verify CompileOnSaveAffectedFileList - const actualAffectedFiles = session.executeCommandSeq({ - command: protocol.CommandTypes.CompileOnSaveAffectedFileList, + const actualAffectedFiles = session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.CompileOnSaveAffectedFileList, arguments: { file: dependencyTs.path } - }).response as protocol.CompileOnSaveAffectedFileListSingleProject[]; + }).response as ts.projectSystem.protocol.CompileOnSaveAffectedFileListSingleProject[]; assert.deepEqual(actualAffectedFiles, [ expectedAffectedFiles(usageConfig, [usageTs]) ], "Affected files"); // Verify CompileOnSaveEmit - const actualEmit = session.executeCommandSeq({ - command: protocol.CommandTypes.CompileOnSaveEmitFile, + const actualEmit = session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.CompileOnSaveEmitFile, arguments: { file: dependencyTs.path } }).response; assert.isFalse(actualEmit, "Emit files"); assert.equal(host.writtenFiles.size, 0); // Verify EmitOutput - const { exportedModulesFromDeclarationEmit: _1, ...actualEmitOutput } = session.executeCommandSeq({ - command: protocol.CommandTypes.EmitOutput, + const { exportedModulesFromDeclarationEmit: _1, ...actualEmitOutput } = session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.EmitOutput, arguments: { file: dependencyTs.path } - }).response as EmitOutput; + }).response as ts.EmitOutput; assert.deepEqual(actualEmitOutput, noEmitOutput(), "Emit output"); }); it("with change to dependency, with specifying project file", () => { - const host = TestFSWithWatch.changeToHostTrackingWrittenFiles( - createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]) - ); - const session = createSession(host); - openFilesForSession([usageTs], session); - - session.executeCommandSeq({ - command: protocol.CommandTypes.CompileOnSaveAffectedFileList, + const host = ts.TestFSWithWatch.changeToHostTrackingWrittenFiles(ts.projectSystem.createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, ts.projectSystem.libFile])); + const session = ts.projectSystem.createSession(host); + ts.projectSystem.openFilesForSession([usageTs], session); + session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.CompileOnSaveAffectedFileList, arguments: { file: dependencyTs.path } }); host.writeFile(dependencyTs.path, `${dependencyTs.content}${change}`); host.writtenFiles.clear(); // Verify CompileOnSaveAffectedFileList - const actualAffectedFiles = session.executeCommandSeq({ - command: protocol.CommandTypes.CompileOnSaveAffectedFileList, + const actualAffectedFiles = session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.CompileOnSaveAffectedFileList, arguments: { file: dependencyTs.path, projectFileName: usageConfig.path } - }).response as protocol.CompileOnSaveAffectedFileListSingleProject[]; + }).response as ts.projectSystem.protocol.CompileOnSaveAffectedFileListSingleProject[]; assert.deepEqual(actualAffectedFiles, [ expectedAffectedFiles(usageConfig, [usageTs]) ], "Affected files"); // Verify CompileOnSaveEmit - const actualEmit = session.executeCommandSeq({ - command: protocol.CommandTypes.CompileOnSaveEmitFile, + const actualEmit = session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.CompileOnSaveEmitFile, arguments: { file: dependencyTs.path, projectFileName: usageConfig.path } }).response; assert.isFalse(actualEmit, "Emit files"); assert.equal(host.writtenFiles.size, 0); // Verify EmitOutput - const { exportedModulesFromDeclarationEmit: _1, ...actualEmitOutput } = session.executeCommandSeq({ - command: protocol.CommandTypes.EmitOutput, + const { exportedModulesFromDeclarationEmit: _1, ...actualEmitOutput } = session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.EmitOutput, arguments: { file: dependencyTs.path, projectFileName: usageConfig.path } - }).response as EmitOutput; + }).response as ts.EmitOutput; assert.deepEqual(actualEmitOutput, noEmitOutput(), "Emit output"); }); it("with change to usage, without specifying project file", () => { - const host = TestFSWithWatch.changeToHostTrackingWrittenFiles( - createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]) - ); - const session = createSession(host); - openFilesForSession([usageTs], session); - - session.executeCommandSeq({ - command: protocol.CommandTypes.CompileOnSaveAffectedFileList, + const host = ts.TestFSWithWatch.changeToHostTrackingWrittenFiles(ts.projectSystem.createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, ts.projectSystem.libFile])); + const session = ts.projectSystem.createSession(host); + ts.projectSystem.openFilesForSession([usageTs], session); + session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.CompileOnSaveAffectedFileList, arguments: { file: dependencyTs.path } }); - const toLocation = protocolToLocation(usageTs.content); + const toLocation = ts.projectSystem.protocolToLocation(usageTs.content); const location = toLocation(usageTs.content.length); - session.executeCommandSeq({ - command: protocol.CommandTypes.Change, + session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.Change, arguments: { file: usageTs.path, ...location, @@ -910,44 +857,41 @@ ${appendDts}` host.writtenFiles.clear(); // Verify CompileOnSaveAffectedFileList - const actualAffectedFiles = session.executeCommandSeq({ - command: protocol.CommandTypes.CompileOnSaveAffectedFileList, + const actualAffectedFiles = session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.CompileOnSaveAffectedFileList, arguments: { file: dependencyTs.path } - }).response as protocol.CompileOnSaveAffectedFileListSingleProject[]; + }).response as ts.projectSystem.protocol.CompileOnSaveAffectedFileListSingleProject[]; assert.deepEqual(actualAffectedFiles, [ - expectedAffectedFiles(usageConfig, emptyArray) + expectedAffectedFiles(usageConfig, ts.emptyArray) ], "Affected files"); // Verify CompileOnSaveEmit - const actualEmit = session.executeCommandSeq({ - command: protocol.CommandTypes.CompileOnSaveEmitFile, + const actualEmit = session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.CompileOnSaveEmitFile, arguments: { file: dependencyTs.path } }).response; assert.isFalse(actualEmit, "Emit files"); assert.equal(host.writtenFiles.size, 0); // Verify EmitOutput - const { exportedModulesFromDeclarationEmit: _1, ...actualEmitOutput } = session.executeCommandSeq({ - command: protocol.CommandTypes.EmitOutput, + const { exportedModulesFromDeclarationEmit: _1, ...actualEmitOutput } = session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.EmitOutput, arguments: { file: dependencyTs.path } - }).response as EmitOutput; + }).response as ts.EmitOutput; assert.deepEqual(actualEmitOutput, noEmitOutput(), "Emit output"); }); it("with change to usage, with specifying project file", () => { - const host = TestFSWithWatch.changeToHostTrackingWrittenFiles( - createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]) - ); - const session = createSession(host); - openFilesForSession([usageTs], session); - - session.executeCommandSeq({ - command: protocol.CommandTypes.CompileOnSaveAffectedFileList, + const host = ts.TestFSWithWatch.changeToHostTrackingWrittenFiles(ts.projectSystem.createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, ts.projectSystem.libFile])); + const session = ts.projectSystem.createSession(host); + ts.projectSystem.openFilesForSession([usageTs], session); + session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.CompileOnSaveAffectedFileList, arguments: { file: dependencyTs.path } }); - const toLocation = protocolToLocation(usageTs.content); + const toLocation = ts.projectSystem.protocolToLocation(usageTs.content); const location = toLocation(usageTs.content.length); - session.executeCommandSeq({ - command: protocol.CommandTypes.Change, + session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.Change, arguments: { file: usageTs.path, ...location, @@ -959,27 +903,27 @@ ${appendDts}` host.writtenFiles.clear(); // Verify CompileOnSaveAffectedFileList - const actualAffectedFiles = session.executeCommandSeq({ - command: protocol.CommandTypes.CompileOnSaveAffectedFileList, + const actualAffectedFiles = session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.CompileOnSaveAffectedFileList, arguments: { file: dependencyTs.path, projectFileName: usageConfig.path } - }).response as protocol.CompileOnSaveAffectedFileListSingleProject[]; + }).response as ts.projectSystem.protocol.CompileOnSaveAffectedFileListSingleProject[]; assert.deepEqual(actualAffectedFiles, [ - expectedAffectedFiles(usageConfig, emptyArray) + expectedAffectedFiles(usageConfig, ts.emptyArray) ], "Affected files"); // Verify CompileOnSaveEmit - const actualEmit = session.executeCommandSeq({ - command: protocol.CommandTypes.CompileOnSaveEmitFile, + const actualEmit = session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.CompileOnSaveEmitFile, arguments: { file: dependencyTs.path, projectFileName: usageConfig.path } }).response; assert.isFalse(actualEmit, "Emit files"); assert.equal(host.writtenFiles.size, 0); // Verify EmitOutput - const { exportedModulesFromDeclarationEmit: _1, ...actualEmitOutput } = session.executeCommandSeq({ - command: protocol.CommandTypes.EmitOutput, + const { exportedModulesFromDeclarationEmit: _1, ...actualEmitOutput } = session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.EmitOutput, arguments: { file: dependencyTs.path, projectFileName: usageConfig.path } - }).response as EmitOutput; + }).response as ts.EmitOutput; assert.deepEqual(actualEmitOutput, noEmitOutput(), "Emit output"); }); }); @@ -988,24 +932,22 @@ ${appendDts}` describe("when the depedency file is open", () => { describe("Of usageTs", () => { it("with initial file open, without specifying project file", () => { - const host = TestFSWithWatch.changeToHostTrackingWrittenFiles( - createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]) - ); - const session = createSession(host); - openFilesForSession([usageTs, dependencyTs], session); + const host = ts.TestFSWithWatch.changeToHostTrackingWrittenFiles(ts.projectSystem.createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, ts.projectSystem.libFile])); + const session = ts.projectSystem.createSession(host); + ts.projectSystem.openFilesForSession([usageTs, dependencyTs], session); // Verify CompileOnSaveAffectedFileList - const actualAffectedFiles = session.executeCommandSeq({ - command: protocol.CommandTypes.CompileOnSaveAffectedFileList, + const actualAffectedFiles = session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.CompileOnSaveAffectedFileList, arguments: { file: usageTs.path } - }).response as protocol.CompileOnSaveAffectedFileListSingleProject[]; + }).response as ts.projectSystem.protocol.CompileOnSaveAffectedFileListSingleProject[]; assert.deepEqual(actualAffectedFiles, [ expectedAffectedFiles(usageConfig, [usageTs]) ], "Affected files"); // Verify CompileOnSaveEmit - const actualEmit = session.executeCommandSeq({ - command: protocol.CommandTypes.CompileOnSaveEmitFile, + const actualEmit = session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.CompileOnSaveEmitFile, arguments: { file: usageTs.path } }).response; assert.isTrue(actualEmit, "Emit files"); @@ -1013,35 +955,33 @@ ${appendDts}` assert.equal(host.writtenFiles.size, expectedFiles.length); for (const file of expectedFiles) { assert.equal(host.readFile(file.path), file.content, `Expected to write ${file.path}`); - assert.isTrue(host.writtenFiles.has(file.path as Path), `${file.path} is newly written`); + assert.isTrue(host.writtenFiles.has(file.path as ts.Path), `${file.path} is newly written`); } // Verify EmitOutput - const { exportedModulesFromDeclarationEmit: _1, ...actualEmitOutput } = session.executeCommandSeq({ - command: protocol.CommandTypes.EmitOutput, + const { exportedModulesFromDeclarationEmit: _1, ...actualEmitOutput } = session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.EmitOutput, arguments: { file: usageTs.path } - }).response as EmitOutput; + }).response as ts.EmitOutput; assert.deepEqual(actualEmitOutput, expectedEmitOutput(expectedFiles), "Emit output"); }); it("with initial file open, with specifying project file", () => { - const host = TestFSWithWatch.changeToHostTrackingWrittenFiles( - createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]) - ); - const session = createSession(host); - openFilesForSession([usageTs, dependencyTs], session); + const host = ts.TestFSWithWatch.changeToHostTrackingWrittenFiles(ts.projectSystem.createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, ts.projectSystem.libFile])); + const session = ts.projectSystem.createSession(host); + ts.projectSystem.openFilesForSession([usageTs, dependencyTs], session); // Verify CompileOnSaveAffectedFileList - const actualAffectedFiles = session.executeCommandSeq({ - command: protocol.CommandTypes.CompileOnSaveAffectedFileList, + const actualAffectedFiles = session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.CompileOnSaveAffectedFileList, arguments: { file: usageTs.path, projectFileName: usageConfig.path } - }).response as protocol.CompileOnSaveAffectedFileListSingleProject[]; + }).response as ts.projectSystem.protocol.CompileOnSaveAffectedFileListSingleProject[]; assert.deepEqual(actualAffectedFiles, [ expectedAffectedFiles(usageConfig, [usageTs]) ], "Affected files"); // Verify CompileOnSaveEmit - const actualEmit = session.executeCommandSeq({ - command: protocol.CommandTypes.CompileOnSaveEmitFile, + const actualEmit = session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.CompileOnSaveEmitFile, arguments: { file: usageTs.path, projectFileName: usageConfig.path } }).response; assert.isTrue(actualEmit, "Emit files"); @@ -1049,31 +989,28 @@ ${appendDts}` assert.equal(host.writtenFiles.size, expectedFiles.length); for (const file of expectedFiles) { assert.equal(host.readFile(file.path), file.content, `Expected to write ${file.path}`); - assert.isTrue(host.writtenFiles.has(file.path as Path), `${file.path} is newly written`); + assert.isTrue(host.writtenFiles.has(file.path as ts.Path), `${file.path} is newly written`); } // Verify EmitOutput - const { exportedModulesFromDeclarationEmit: _1, ...actualEmitOutput } = session.executeCommandSeq({ - command: protocol.CommandTypes.EmitOutput, + const { exportedModulesFromDeclarationEmit: _1, ...actualEmitOutput } = session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.EmitOutput, arguments: { file: usageTs.path, projectFileName: usageConfig.path } - }).response as EmitOutput; + }).response as ts.EmitOutput; assert.deepEqual(actualEmitOutput, expectedEmitOutput(expectedFiles), "Emit output"); }); it("with local change to dependency, without specifying project file", () => { - const host = TestFSWithWatch.changeToHostTrackingWrittenFiles( - createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]) - ); - const session = createSession(host); - openFilesForSession([usageTs, dependencyTs], session); - - session.executeCommandSeq({ - command: protocol.CommandTypes.CompileOnSaveAffectedFileList, + const host = ts.TestFSWithWatch.changeToHostTrackingWrittenFiles(ts.projectSystem.createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, ts.projectSystem.libFile])); + const session = ts.projectSystem.createSession(host); + ts.projectSystem.openFilesForSession([usageTs, dependencyTs], session); + session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.CompileOnSaveAffectedFileList, arguments: { file: dependencyTs.path } }); - const toLocation = protocolToLocation(dependencyTs.content); + const toLocation = ts.projectSystem.protocolToLocation(dependencyTs.content); const location = toLocation(dependencyTs.content.length); - session.executeCommandSeq({ - command: protocol.CommandTypes.Change, + session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.Change, arguments: { file: dependencyTs.path, ...location, @@ -1085,17 +1022,17 @@ ${appendDts}` host.writtenFiles.clear(); // Verify CompileOnSaveAffectedFileList - const actualAffectedFiles = session.executeCommandSeq({ - command: protocol.CommandTypes.CompileOnSaveAffectedFileList, + const actualAffectedFiles = session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.CompileOnSaveAffectedFileList, arguments: { file: usageTs.path } - }).response as protocol.CompileOnSaveAffectedFileListSingleProject[]; + }).response as ts.projectSystem.protocol.CompileOnSaveAffectedFileListSingleProject[]; assert.deepEqual(actualAffectedFiles, [ expectedAffectedFiles(usageConfig, [usageTs]) ], "Affected files"); // Verify CompileOnSaveEmit - const actualEmit = session.executeCommandSeq({ - command: protocol.CommandTypes.CompileOnSaveEmitFile, + const actualEmit = session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.CompileOnSaveEmitFile, arguments: { file: usageTs.path } }).response; assert.isTrue(actualEmit, "Emit files"); @@ -1103,31 +1040,28 @@ ${appendDts}` assert.equal(host.writtenFiles.size, expectedFiles.length); for (const file of expectedFiles) { assert.equal(host.readFile(file.path), file.content, `Expected to write ${file.path}`); - assert.isTrue(host.writtenFiles.has(file.path as Path), `${file.path} is newly written`); + assert.isTrue(host.writtenFiles.has(file.path as ts.Path), `${file.path} is newly written`); } // Verify EmitOutput - const { exportedModulesFromDeclarationEmit: _1, ...actualEmitOutput } = session.executeCommandSeq({ - command: protocol.CommandTypes.EmitOutput, + const { exportedModulesFromDeclarationEmit: _1, ...actualEmitOutput } = session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.EmitOutput, arguments: { file: usageTs.path } - }).response as EmitOutput; + }).response as ts.EmitOutput; assert.deepEqual(actualEmitOutput, expectedEmitOutput(expectedFiles), "Emit output"); }); it("with local change to dependency, with specifying project file", () => { - const host = TestFSWithWatch.changeToHostTrackingWrittenFiles( - createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]) - ); - const session = createSession(host); - openFilesForSession([usageTs, dependencyTs], session); - - session.executeCommandSeq({ - command: protocol.CommandTypes.CompileOnSaveAffectedFileList, + const host = ts.TestFSWithWatch.changeToHostTrackingWrittenFiles(ts.projectSystem.createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, ts.projectSystem.libFile])); + const session = ts.projectSystem.createSession(host); + ts.projectSystem.openFilesForSession([usageTs, dependencyTs], session); + session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.CompileOnSaveAffectedFileList, arguments: { file: dependencyTs.path } }); - const toLocation = protocolToLocation(dependencyTs.content); + const toLocation = ts.projectSystem.protocolToLocation(dependencyTs.content); const location = toLocation(dependencyTs.content.length); - session.executeCommandSeq({ - command: protocol.CommandTypes.Change, + session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.Change, arguments: { file: dependencyTs.path, ...location, @@ -1139,17 +1073,17 @@ ${appendDts}` host.writtenFiles.clear(); // Verify CompileOnSaveAffectedFileList - const actualAffectedFiles = session.executeCommandSeq({ - command: protocol.CommandTypes.CompileOnSaveAffectedFileList, + const actualAffectedFiles = session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.CompileOnSaveAffectedFileList, arguments: { file: usageTs.path, projectFileName: usageConfig.path } - }).response as protocol.CompileOnSaveAffectedFileListSingleProject[]; + }).response as ts.projectSystem.protocol.CompileOnSaveAffectedFileListSingleProject[]; assert.deepEqual(actualAffectedFiles, [ expectedAffectedFiles(usageConfig, [usageTs]) ], "Affected files"); // Verify CompileOnSaveEmit - const actualEmit = session.executeCommandSeq({ - command: protocol.CommandTypes.CompileOnSaveEmitFile, + const actualEmit = session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.CompileOnSaveEmitFile, arguments: { file: usageTs.path, projectFileName: usageConfig.path } }).response; assert.isTrue(actualEmit, "Emit files"); @@ -1157,31 +1091,28 @@ ${appendDts}` assert.equal(host.writtenFiles.size, expectedFiles.length); for (const file of expectedFiles) { assert.equal(host.readFile(file.path), file.content, `Expected to write ${file.path}`); - assert.isTrue(host.writtenFiles.has(file.path as Path), `${file.path} is newly written`); + assert.isTrue(host.writtenFiles.has(file.path as ts.Path), `${file.path} is newly written`); } // Verify EmitOutput - const { exportedModulesFromDeclarationEmit: _1, ...actualEmitOutput } = session.executeCommandSeq({ - command: protocol.CommandTypes.EmitOutput, + const { exportedModulesFromDeclarationEmit: _1, ...actualEmitOutput } = session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.EmitOutput, arguments: { file: usageTs.path, projectFileName: usageConfig.path } - }).response as EmitOutput; + }).response as ts.EmitOutput; assert.deepEqual(actualEmitOutput, expectedEmitOutput(expectedFiles), "Emit output"); }); it("with local change to usage, without specifying project file", () => { - const host = TestFSWithWatch.changeToHostTrackingWrittenFiles( - createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]) - ); - const session = createSession(host); - openFilesForSession([usageTs, dependencyTs], session); - - session.executeCommandSeq({ - command: protocol.CommandTypes.CompileOnSaveAffectedFileList, + const host = ts.TestFSWithWatch.changeToHostTrackingWrittenFiles(ts.projectSystem.createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, ts.projectSystem.libFile])); + const session = ts.projectSystem.createSession(host); + ts.projectSystem.openFilesForSession([usageTs, dependencyTs], session); + session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.CompileOnSaveAffectedFileList, arguments: { file: dependencyTs.path } }); - const toLocation = protocolToLocation(usageTs.content); + const toLocation = ts.projectSystem.protocolToLocation(usageTs.content); const location = toLocation(usageTs.content.length); - session.executeCommandSeq({ - command: protocol.CommandTypes.Change, + session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.Change, arguments: { file: usageTs.path, ...location, @@ -1193,17 +1124,17 @@ ${appendDts}` host.writtenFiles.clear(); // Verify CompileOnSaveAffectedFileList - const actualAffectedFiles = session.executeCommandSeq({ - command: protocol.CommandTypes.CompileOnSaveAffectedFileList, + const actualAffectedFiles = session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.CompileOnSaveAffectedFileList, arguments: { file: usageTs.path } - }).response as protocol.CompileOnSaveAffectedFileListSingleProject[]; + }).response as ts.projectSystem.protocol.CompileOnSaveAffectedFileListSingleProject[]; assert.deepEqual(actualAffectedFiles, [ expectedAffectedFiles(usageConfig, [usageTs]) ], "Affected files"); // Verify CompileOnSaveEmit - const actualEmit = session.executeCommandSeq({ - command: protocol.CommandTypes.CompileOnSaveEmitFile, + const actualEmit = session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.CompileOnSaveEmitFile, arguments: { file: usageTs.path } }).response; assert.isTrue(actualEmit, "Emit files"); @@ -1211,31 +1142,28 @@ ${appendDts}` assert.equal(host.writtenFiles.size, expectedFiles.length); for (const file of expectedFiles) { assert.equal(host.readFile(file.path), file.content, `Expected to write ${file.path}`); - assert.isTrue(host.writtenFiles.has(file.path as Path), `${file.path} is newly written`); + assert.isTrue(host.writtenFiles.has(file.path as ts.Path), `${file.path} is newly written`); } // Verify EmitOutput - const { exportedModulesFromDeclarationEmit: _1, ...actualEmitOutput } = session.executeCommandSeq({ - command: protocol.CommandTypes.EmitOutput, + const { exportedModulesFromDeclarationEmit: _1, ...actualEmitOutput } = session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.EmitOutput, arguments: { file: usageTs.path } - }).response as EmitOutput; + }).response as ts.EmitOutput; assert.deepEqual(actualEmitOutput, expectedEmitOutput(expectedFiles), "Emit output"); }); it("with local change to usage, with specifying project file", () => { - const host = TestFSWithWatch.changeToHostTrackingWrittenFiles( - createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]) - ); - const session = createSession(host); - openFilesForSession([usageTs, dependencyTs], session); - - session.executeCommandSeq({ - command: protocol.CommandTypes.CompileOnSaveAffectedFileList, + const host = ts.TestFSWithWatch.changeToHostTrackingWrittenFiles(ts.projectSystem.createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, ts.projectSystem.libFile])); + const session = ts.projectSystem.createSession(host); + ts.projectSystem.openFilesForSession([usageTs, dependencyTs], session); + session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.CompileOnSaveAffectedFileList, arguments: { file: dependencyTs.path } }); - const toLocation = protocolToLocation(usageTs.content); + const toLocation = ts.projectSystem.protocolToLocation(usageTs.content); const location = toLocation(usageTs.content.length); - session.executeCommandSeq({ - command: protocol.CommandTypes.Change, + session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.Change, arguments: { file: usageTs.path, ...location, @@ -1247,17 +1175,17 @@ ${appendDts}` host.writtenFiles.clear(); // Verify CompileOnSaveAffectedFileList - const actualAffectedFiles = session.executeCommandSeq({ - command: protocol.CommandTypes.CompileOnSaveAffectedFileList, + const actualAffectedFiles = session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.CompileOnSaveAffectedFileList, arguments: { file: usageTs.path, projectFileName: usageConfig.path } - }).response as protocol.CompileOnSaveAffectedFileListSingleProject[]; + }).response as ts.projectSystem.protocol.CompileOnSaveAffectedFileListSingleProject[]; assert.deepEqual(actualAffectedFiles, [ expectedAffectedFiles(usageConfig, [usageTs]) ], "Affected files"); // Verify CompileOnSaveEmit - const actualEmit = session.executeCommandSeq({ - command: protocol.CommandTypes.CompileOnSaveEmitFile, + const actualEmit = session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.CompileOnSaveEmitFile, arguments: { file: usageTs.path, projectFileName: usageConfig.path } }).response; assert.isTrue(actualEmit, "Emit files"); @@ -1265,31 +1193,28 @@ ${appendDts}` assert.equal(host.writtenFiles.size, expectedFiles.length); for (const file of expectedFiles) { assert.equal(host.readFile(file.path), file.content, `Expected to write ${file.path}`); - assert.isTrue(host.writtenFiles.has(file.path as Path), `${file.path} is newly written`); + assert.isTrue(host.writtenFiles.has(file.path as ts.Path), `${file.path} is newly written`); } // Verify EmitOutput - const { exportedModulesFromDeclarationEmit: _1, ...actualEmitOutput } = session.executeCommandSeq({ - command: protocol.CommandTypes.EmitOutput, + const { exportedModulesFromDeclarationEmit: _1, ...actualEmitOutput } = session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.EmitOutput, arguments: { file: usageTs.path, projectFileName: usageConfig.path } - }).response as EmitOutput; + }).response as ts.EmitOutput; assert.deepEqual(actualEmitOutput, expectedEmitOutput(expectedFiles), "Emit output"); }); it("with change to dependency, without specifying project file", () => { - const host = TestFSWithWatch.changeToHostTrackingWrittenFiles( - createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]) - ); - const session = createSession(host); - openFilesForSession([usageTs, dependencyTs], session); - - session.executeCommandSeq({ - command: protocol.CommandTypes.CompileOnSaveAffectedFileList, + const host = ts.TestFSWithWatch.changeToHostTrackingWrittenFiles(ts.projectSystem.createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, ts.projectSystem.libFile])); + const session = ts.projectSystem.createSession(host); + ts.projectSystem.openFilesForSession([usageTs, dependencyTs], session); + session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.CompileOnSaveAffectedFileList, arguments: { file: dependencyTs.path } }); - const toLocation = protocolToLocation(dependencyTs.content); + const toLocation = ts.projectSystem.protocolToLocation(dependencyTs.content); const location = toLocation(dependencyTs.content.length); - session.executeCommandSeq({ - command: protocol.CommandTypes.Change, + session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.Change, arguments: { file: dependencyTs.path, ...location, @@ -1301,17 +1226,17 @@ ${appendDts}` host.writtenFiles.clear(); // Verify CompileOnSaveAffectedFileList - const actualAffectedFiles = session.executeCommandSeq({ - command: protocol.CommandTypes.CompileOnSaveAffectedFileList, + const actualAffectedFiles = session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.CompileOnSaveAffectedFileList, arguments: { file: usageTs.path } - }).response as protocol.CompileOnSaveAffectedFileListSingleProject[]; + }).response as ts.projectSystem.protocol.CompileOnSaveAffectedFileListSingleProject[]; assert.deepEqual(actualAffectedFiles, [ expectedAffectedFiles(usageConfig, [usageTs]) ], "Affected files"); // Verify CompileOnSaveEmit - const actualEmit = session.executeCommandSeq({ - command: protocol.CommandTypes.CompileOnSaveEmitFile, + const actualEmit = session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.CompileOnSaveEmitFile, arguments: { file: usageTs.path } }).response; assert.isTrue(actualEmit, "Emit files"); @@ -1319,31 +1244,28 @@ ${appendDts}` assert.equal(host.writtenFiles.size, expectedFiles.length); for (const file of expectedFiles) { assert.equal(host.readFile(file.path), file.content, `Expected to write ${file.path}`); - assert.isTrue(host.writtenFiles.has(file.path as Path), `${file.path} is newly written`); + assert.isTrue(host.writtenFiles.has(file.path as ts.Path), `${file.path} is newly written`); } // Verify EmitOutput - const { exportedModulesFromDeclarationEmit: _1, ...actualEmitOutput } = session.executeCommandSeq({ - command: protocol.CommandTypes.EmitOutput, + const { exportedModulesFromDeclarationEmit: _1, ...actualEmitOutput } = session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.EmitOutput, arguments: { file: usageTs.path } - }).response as EmitOutput; + }).response as ts.EmitOutput; assert.deepEqual(actualEmitOutput, expectedEmitOutput(expectedFiles), "Emit output"); }); it("with change to dependency, with specifying project file", () => { - const host = TestFSWithWatch.changeToHostTrackingWrittenFiles( - createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]) - ); - const session = createSession(host); - openFilesForSession([usageTs, dependencyTs], session); - - session.executeCommandSeq({ - command: protocol.CommandTypes.CompileOnSaveAffectedFileList, + const host = ts.TestFSWithWatch.changeToHostTrackingWrittenFiles(ts.projectSystem.createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, ts.projectSystem.libFile])); + const session = ts.projectSystem.createSession(host); + ts.projectSystem.openFilesForSession([usageTs, dependencyTs], session); + session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.CompileOnSaveAffectedFileList, arguments: { file: dependencyTs.path } }); - const toLocation = protocolToLocation(dependencyTs.content); + const toLocation = ts.projectSystem.protocolToLocation(dependencyTs.content); const location = toLocation(dependencyTs.content.length); - session.executeCommandSeq({ - command: protocol.CommandTypes.Change, + session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.Change, arguments: { file: dependencyTs.path, ...location, @@ -1355,17 +1277,17 @@ ${appendDts}` host.writtenFiles.clear(); // Verify CompileOnSaveAffectedFileList - const actualAffectedFiles = session.executeCommandSeq({ - command: protocol.CommandTypes.CompileOnSaveAffectedFileList, + const actualAffectedFiles = session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.CompileOnSaveAffectedFileList, arguments: { file: usageTs.path, projectFileName: usageConfig.path } - }).response as protocol.CompileOnSaveAffectedFileListSingleProject[]; + }).response as ts.projectSystem.protocol.CompileOnSaveAffectedFileListSingleProject[]; assert.deepEqual(actualAffectedFiles, [ expectedAffectedFiles(usageConfig, [usageTs]) ], "Affected files"); // Verify CompileOnSaveEmit - const actualEmit = session.executeCommandSeq({ - command: protocol.CommandTypes.CompileOnSaveEmitFile, + const actualEmit = session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.CompileOnSaveEmitFile, arguments: { file: usageTs.path, projectFileName: usageConfig.path } }).response; assert.isTrue(actualEmit, "Emit files"); @@ -1373,31 +1295,28 @@ ${appendDts}` assert.equal(host.writtenFiles.size, expectedFiles.length); for (const file of expectedFiles) { assert.equal(host.readFile(file.path), file.content, `Expected to write ${file.path}`); - assert.isTrue(host.writtenFiles.has(file.path as Path), `${file.path} is newly written`); + assert.isTrue(host.writtenFiles.has(file.path as ts.Path), `${file.path} is newly written`); } // Verify EmitOutput - const { exportedModulesFromDeclarationEmit: _1, ...actualEmitOutput } = session.executeCommandSeq({ - command: protocol.CommandTypes.EmitOutput, + const { exportedModulesFromDeclarationEmit: _1, ...actualEmitOutput } = session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.EmitOutput, arguments: { file: usageTs.path, projectFileName: usageConfig.path } - }).response as EmitOutput; + }).response as ts.EmitOutput; assert.deepEqual(actualEmitOutput, expectedEmitOutput(expectedFiles), "Emit output"); }); it("with change to usage, without specifying project file", () => { - const host = TestFSWithWatch.changeToHostTrackingWrittenFiles( - createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]) - ); - const session = createSession(host); - openFilesForSession([usageTs, dependencyTs], session); - - session.executeCommandSeq({ - command: protocol.CommandTypes.CompileOnSaveAffectedFileList, + const host = ts.TestFSWithWatch.changeToHostTrackingWrittenFiles(ts.projectSystem.createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, ts.projectSystem.libFile])); + const session = ts.projectSystem.createSession(host); + ts.projectSystem.openFilesForSession([usageTs, dependencyTs], session); + session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.CompileOnSaveAffectedFileList, arguments: { file: dependencyTs.path } }); - const toLocation = protocolToLocation(usageTs.content); + const toLocation = ts.projectSystem.protocolToLocation(usageTs.content); const location = toLocation(usageTs.content.length); - session.executeCommandSeq({ - command: protocol.CommandTypes.Change, + session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.Change, arguments: { file: usageTs.path, ...location, @@ -1409,17 +1328,17 @@ ${appendDts}` host.writtenFiles.clear(); // Verify CompileOnSaveAffectedFileList - const actualAffectedFiles = session.executeCommandSeq({ - command: protocol.CommandTypes.CompileOnSaveAffectedFileList, + const actualAffectedFiles = session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.CompileOnSaveAffectedFileList, arguments: { file: usageTs.path } - }).response as protocol.CompileOnSaveAffectedFileListSingleProject[]; + }).response as ts.projectSystem.protocol.CompileOnSaveAffectedFileListSingleProject[]; assert.deepEqual(actualAffectedFiles, [ expectedAffectedFiles(usageConfig, [usageTs]) ], "Affected files"); // Verify CompileOnSaveEmit - const actualEmit = session.executeCommandSeq({ - command: protocol.CommandTypes.CompileOnSaveEmitFile, + const actualEmit = session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.CompileOnSaveEmitFile, arguments: { file: usageTs.path } }).response; assert.isTrue(actualEmit, "Emit files"); @@ -1427,31 +1346,28 @@ ${appendDts}` assert.equal(host.writtenFiles.size, expectedFiles.length); for (const file of expectedFiles) { assert.equal(host.readFile(file.path), file.content, `Expected to write ${file.path}`); - assert.isTrue(host.writtenFiles.has(file.path as Path), `${file.path} is newly written`); + assert.isTrue(host.writtenFiles.has(file.path as ts.Path), `${file.path} is newly written`); } // Verify EmitOutput - const { exportedModulesFromDeclarationEmit: _1, ...actualEmitOutput } = session.executeCommandSeq({ - command: protocol.CommandTypes.EmitOutput, + const { exportedModulesFromDeclarationEmit: _1, ...actualEmitOutput } = session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.EmitOutput, arguments: { file: usageTs.path } - }).response as EmitOutput; + }).response as ts.EmitOutput; assert.deepEqual(actualEmitOutput, expectedEmitOutput(expectedFiles), "Emit output"); }); it("with change to usage, with specifying project file", () => { - const host = TestFSWithWatch.changeToHostTrackingWrittenFiles( - createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]) - ); - const session = createSession(host); - openFilesForSession([usageTs, dependencyTs], session); - - session.executeCommandSeq({ - command: protocol.CommandTypes.CompileOnSaveAffectedFileList, + const host = ts.TestFSWithWatch.changeToHostTrackingWrittenFiles(ts.projectSystem.createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, ts.projectSystem.libFile])); + const session = ts.projectSystem.createSession(host); + ts.projectSystem.openFilesForSession([usageTs, dependencyTs], session); + session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.CompileOnSaveAffectedFileList, arguments: { file: dependencyTs.path } }); - const toLocation = protocolToLocation(usageTs.content); + const toLocation = ts.projectSystem.protocolToLocation(usageTs.content); const location = toLocation(usageTs.content.length); - session.executeCommandSeq({ - command: protocol.CommandTypes.Change, + session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.Change, arguments: { file: usageTs.path, ...location, @@ -1463,17 +1379,17 @@ ${appendDts}` host.writtenFiles.clear(); // Verify CompileOnSaveAffectedFileList - const actualAffectedFiles = session.executeCommandSeq({ - command: protocol.CommandTypes.CompileOnSaveAffectedFileList, + const actualAffectedFiles = session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.CompileOnSaveAffectedFileList, arguments: { file: usageTs.path, projectFileName: usageConfig.path } - }).response as protocol.CompileOnSaveAffectedFileListSingleProject[]; + }).response as ts.projectSystem.protocol.CompileOnSaveAffectedFileListSingleProject[]; assert.deepEqual(actualAffectedFiles, [ expectedAffectedFiles(usageConfig, [usageTs]) ], "Affected files"); // Verify CompileOnSaveEmit - const actualEmit = session.executeCommandSeq({ - command: protocol.CommandTypes.CompileOnSaveEmitFile, + const actualEmit = session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.CompileOnSaveEmitFile, arguments: { file: usageTs.path, projectFileName: usageConfig.path } }).response; assert.isTrue(actualEmit, "Emit files"); @@ -1481,65 +1397,60 @@ ${appendDts}` assert.equal(host.writtenFiles.size, expectedFiles.length); for (const file of expectedFiles) { assert.equal(host.readFile(file.path), file.content, `Expected to write ${file.path}`); - assert.isTrue(host.writtenFiles.has(file.path as Path), `${file.path} is newly written`); + assert.isTrue(host.writtenFiles.has(file.path as ts.Path), `${file.path} is newly written`); } // Verify EmitOutput - const { exportedModulesFromDeclarationEmit: _1, ...actualEmitOutput } = session.executeCommandSeq({ - command: protocol.CommandTypes.EmitOutput, + const { exportedModulesFromDeclarationEmit: _1, ...actualEmitOutput } = session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.EmitOutput, arguments: { file: usageTs.path, projectFileName: usageConfig.path } - }).response as EmitOutput; + }).response as ts.EmitOutput; assert.deepEqual(actualEmitOutput, expectedEmitOutput(expectedFiles), "Emit output"); }); }); describe("Of dependencyTs in usage project", () => { it("with initial file open, with specifying project file", () => { - const host = TestFSWithWatch.changeToHostTrackingWrittenFiles( - createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]) - ); - const session = createSession(host); - openFilesForSession([usageTs, dependencyTs], session); + const host = ts.TestFSWithWatch.changeToHostTrackingWrittenFiles(ts.projectSystem.createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, ts.projectSystem.libFile])); + const session = ts.projectSystem.createSession(host); + ts.projectSystem.openFilesForSession([usageTs, dependencyTs], session); // Verify CompileOnSaveAffectedFileList - const actualAffectedFiles = session.executeCommandSeq({ - command: protocol.CommandTypes.CompileOnSaveAffectedFileList, + const actualAffectedFiles = session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.CompileOnSaveAffectedFileList, arguments: { file: dependencyTs.path, projectFileName: usageConfig.path } - }).response as protocol.CompileOnSaveAffectedFileListSingleProject[]; + }).response as ts.projectSystem.protocol.CompileOnSaveAffectedFileListSingleProject[]; assert.deepEqual(actualAffectedFiles, [ expectedAffectedFiles(usageConfig, [usageTs]) ], "Affected files"); // Verify CompileOnSaveEmit - const actualEmit = session.executeCommandSeq({ - command: protocol.CommandTypes.CompileOnSaveEmitFile, + const actualEmit = session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.CompileOnSaveEmitFile, arguments: { file: dependencyTs.path, projectFileName: usageConfig.path } }).response; assert.isFalse(actualEmit, "Emit files"); assert.equal(host.writtenFiles.size, 0); // Verify EmitOutput - const { exportedModulesFromDeclarationEmit: _1, ...actualEmitOutput } = session.executeCommandSeq({ - command: protocol.CommandTypes.EmitOutput, + const { exportedModulesFromDeclarationEmit: _1, ...actualEmitOutput } = session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.EmitOutput, arguments: { file: dependencyTs.path, projectFileName: usageConfig.path } - }).response as EmitOutput; + }).response as ts.EmitOutput; assert.deepEqual(actualEmitOutput, noEmitOutput(), "Emit output"); }); it("with local change to dependency, with specifying project file", () => { - const host = TestFSWithWatch.changeToHostTrackingWrittenFiles( - createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]) - ); - const session = createSession(host); - openFilesForSession([usageTs, dependencyTs], session); - - session.executeCommandSeq({ - command: protocol.CommandTypes.CompileOnSaveAffectedFileList, + const host = ts.TestFSWithWatch.changeToHostTrackingWrittenFiles(ts.projectSystem.createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, ts.projectSystem.libFile])); + const session = ts.projectSystem.createSession(host); + ts.projectSystem.openFilesForSession([usageTs, dependencyTs], session); + session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.CompileOnSaveAffectedFileList, arguments: { file: dependencyTs.path } }); - const toLocation = protocolToLocation(dependencyTs.content); + const toLocation = ts.projectSystem.protocolToLocation(dependencyTs.content); const location = toLocation(dependencyTs.content.length); - session.executeCommandSeq({ - command: protocol.CommandTypes.Change, + session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.Change, arguments: { file: dependencyTs.path, ...location, @@ -1551,44 +1462,41 @@ ${appendDts}` host.writtenFiles.clear(); // Verify CompileOnSaveAffectedFileList - const actualAffectedFiles = session.executeCommandSeq({ - command: protocol.CommandTypes.CompileOnSaveAffectedFileList, + const actualAffectedFiles = session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.CompileOnSaveAffectedFileList, arguments: { file: dependencyTs.path, projectFileName: usageConfig.path } - }).response as protocol.CompileOnSaveAffectedFileListSingleProject[]; + }).response as ts.projectSystem.protocol.CompileOnSaveAffectedFileListSingleProject[]; assert.deepEqual(actualAffectedFiles, [ - expectedAffectedFiles(usageConfig, emptyArray) + expectedAffectedFiles(usageConfig, ts.emptyArray) ], "Affected files"); // Verify CompileOnSaveEmit - const actualEmit = session.executeCommandSeq({ - command: protocol.CommandTypes.CompileOnSaveEmitFile, + const actualEmit = session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.CompileOnSaveEmitFile, arguments: { file: dependencyTs.path, projectFileName: usageConfig.path } }).response; assert.isFalse(actualEmit, "Emit files"); assert.equal(host.writtenFiles.size, 0); // Verify EmitOutput - const { exportedModulesFromDeclarationEmit: _1, ...actualEmitOutput } = session.executeCommandSeq({ - command: protocol.CommandTypes.EmitOutput, + const { exportedModulesFromDeclarationEmit: _1, ...actualEmitOutput } = session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.EmitOutput, arguments: { file: dependencyTs.path, projectFileName: usageConfig.path } - }).response as EmitOutput; + }).response as ts.EmitOutput; assert.deepEqual(actualEmitOutput, noEmitOutput(), "Emit output"); }); it("with local change to usage, with specifying project file", () => { - const host = TestFSWithWatch.changeToHostTrackingWrittenFiles( - createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]) - ); - const session = createSession(host); - openFilesForSession([usageTs, dependencyTs], session); - - session.executeCommandSeq({ - command: protocol.CommandTypes.CompileOnSaveAffectedFileList, + const host = ts.TestFSWithWatch.changeToHostTrackingWrittenFiles(ts.projectSystem.createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, ts.projectSystem.libFile])); + const session = ts.projectSystem.createSession(host); + ts.projectSystem.openFilesForSession([usageTs, dependencyTs], session); + session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.CompileOnSaveAffectedFileList, arguments: { file: dependencyTs.path } }); - const toLocation = protocolToLocation(usageTs.content); + const toLocation = ts.projectSystem.protocolToLocation(usageTs.content); const location = toLocation(usageTs.content.length); - session.executeCommandSeq({ - command: protocol.CommandTypes.Change, + session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.Change, arguments: { file: usageTs.path, ...location, @@ -1600,44 +1508,41 @@ ${appendDts}` host.writtenFiles.clear(); // Verify CompileOnSaveAffectedFileList - const actualAffectedFiles = session.executeCommandSeq({ - command: protocol.CommandTypes.CompileOnSaveAffectedFileList, + const actualAffectedFiles = session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.CompileOnSaveAffectedFileList, arguments: { file: dependencyTs.path, projectFileName: usageConfig.path } - }).response as protocol.CompileOnSaveAffectedFileListSingleProject[]; + }).response as ts.projectSystem.protocol.CompileOnSaveAffectedFileListSingleProject[]; assert.deepEqual(actualAffectedFiles, [ - expectedAffectedFiles(usageConfig, emptyArray) + expectedAffectedFiles(usageConfig, ts.emptyArray) ], "Affected files"); // Verify CompileOnSaveEmit - const actualEmit = session.executeCommandSeq({ - command: protocol.CommandTypes.CompileOnSaveEmitFile, + const actualEmit = session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.CompileOnSaveEmitFile, arguments: { file: dependencyTs.path, projectFileName: usageConfig.path } }).response; assert.isFalse(actualEmit, "Emit files"); assert.equal(host.writtenFiles.size, 0); // Verify EmitOutput - const { exportedModulesFromDeclarationEmit: _1, ...actualEmitOutput } = session.executeCommandSeq({ - command: protocol.CommandTypes.EmitOutput, + const { exportedModulesFromDeclarationEmit: _1, ...actualEmitOutput } = session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.EmitOutput, arguments: { file: dependencyTs.path, projectFileName: usageConfig.path } - }).response as EmitOutput; + }).response as ts.EmitOutput; assert.deepEqual(actualEmitOutput, noEmitOutput(), "Emit output"); }); it("with change to dependency, with specifying project file", () => { - const host = TestFSWithWatch.changeToHostTrackingWrittenFiles( - createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]) - ); - const session = createSession(host); - openFilesForSession([usageTs, dependencyTs], session); - - session.executeCommandSeq({ - command: protocol.CommandTypes.CompileOnSaveAffectedFileList, + const host = ts.TestFSWithWatch.changeToHostTrackingWrittenFiles(ts.projectSystem.createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, ts.projectSystem.libFile])); + const session = ts.projectSystem.createSession(host); + ts.projectSystem.openFilesForSession([usageTs, dependencyTs], session); + session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.CompileOnSaveAffectedFileList, arguments: { file: dependencyTs.path } }); - const toLocation = protocolToLocation(dependencyTs.content); + const toLocation = ts.projectSystem.protocolToLocation(dependencyTs.content); const location = toLocation(dependencyTs.content.length); - session.executeCommandSeq({ - command: protocol.CommandTypes.Change, + session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.Change, arguments: { file: dependencyTs.path, ...location, @@ -1649,44 +1554,41 @@ ${appendDts}` host.writtenFiles.clear(); // Verify CompileOnSaveAffectedFileList - const actualAffectedFiles = session.executeCommandSeq({ - command: protocol.CommandTypes.CompileOnSaveAffectedFileList, + const actualAffectedFiles = session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.CompileOnSaveAffectedFileList, arguments: { file: dependencyTs.path, projectFileName: usageConfig.path } - }).response as protocol.CompileOnSaveAffectedFileListSingleProject[]; + }).response as ts.projectSystem.protocol.CompileOnSaveAffectedFileListSingleProject[]; assert.deepEqual(actualAffectedFiles, [ expectedAffectedFiles(usageConfig, [usageTs]) ], "Affected files"); // Verify CompileOnSaveEmit - const actualEmit = session.executeCommandSeq({ - command: protocol.CommandTypes.CompileOnSaveEmitFile, + const actualEmit = session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.CompileOnSaveEmitFile, arguments: { file: dependencyTs.path, projectFileName: usageConfig.path } }).response; assert.isFalse(actualEmit, "Emit files"); assert.equal(host.writtenFiles.size, 0); // Verify EmitOutput - const { exportedModulesFromDeclarationEmit: _1, ...actualEmitOutput } = session.executeCommandSeq({ - command: protocol.CommandTypes.EmitOutput, + const { exportedModulesFromDeclarationEmit: _1, ...actualEmitOutput } = session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.EmitOutput, arguments: { file: dependencyTs.path, projectFileName: usageConfig.path } - }).response as EmitOutput; + }).response as ts.EmitOutput; assert.deepEqual(actualEmitOutput, noEmitOutput(), "Emit output"); }); it("with change to usage, with specifying project file", () => { - const host = TestFSWithWatch.changeToHostTrackingWrittenFiles( - createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]) - ); - const session = createSession(host); - openFilesForSession([usageTs, dependencyTs], session); - - session.executeCommandSeq({ - command: protocol.CommandTypes.CompileOnSaveAffectedFileList, + const host = ts.TestFSWithWatch.changeToHostTrackingWrittenFiles(ts.projectSystem.createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, ts.projectSystem.libFile])); + const session = ts.projectSystem.createSession(host); + ts.projectSystem.openFilesForSession([usageTs, dependencyTs], session); + session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.CompileOnSaveAffectedFileList, arguments: { file: dependencyTs.path } }); - const toLocation = protocolToLocation(usageTs.content); + const toLocation = ts.projectSystem.protocolToLocation(usageTs.content); const location = toLocation(usageTs.content.length); - session.executeCommandSeq({ - command: protocol.CommandTypes.Change, + session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.Change, arguments: { file: usageTs.path, ...location, @@ -1698,52 +1600,50 @@ ${appendDts}` host.writtenFiles.clear(); // Verify CompileOnSaveAffectedFileList - const actualAffectedFiles = session.executeCommandSeq({ - command: protocol.CommandTypes.CompileOnSaveAffectedFileList, + const actualAffectedFiles = session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.CompileOnSaveAffectedFileList, arguments: { file: dependencyTs.path, projectFileName: usageConfig.path } - }).response as protocol.CompileOnSaveAffectedFileListSingleProject[]; + }).response as ts.projectSystem.protocol.CompileOnSaveAffectedFileListSingleProject[]; assert.deepEqual(actualAffectedFiles, [ - expectedAffectedFiles(usageConfig, emptyArray) + expectedAffectedFiles(usageConfig, ts.emptyArray) ], "Affected files"); // Verify CompileOnSaveEmit - const actualEmit = session.executeCommandSeq({ - command: protocol.CommandTypes.CompileOnSaveEmitFile, + const actualEmit = session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.CompileOnSaveEmitFile, arguments: { file: dependencyTs.path, projectFileName: usageConfig.path } }).response; assert.isFalse(actualEmit, "Emit files"); assert.equal(host.writtenFiles.size, 0); // Verify EmitOutput - const { exportedModulesFromDeclarationEmit: _1, ...actualEmitOutput } = session.executeCommandSeq({ - command: protocol.CommandTypes.EmitOutput, + const { exportedModulesFromDeclarationEmit: _1, ...actualEmitOutput } = session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.EmitOutput, arguments: { file: dependencyTs.path, projectFileName: usageConfig.path } - }).response as EmitOutput; + }).response as ts.EmitOutput; assert.deepEqual(actualEmitOutput, noEmitOutput(), "Emit output"); }); }); describe("Of dependencyTs", () => { it("with initial file open, without specifying project file", () => { - const host = TestFSWithWatch.changeToHostTrackingWrittenFiles( - createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]) - ); - const session = createSession(host); - openFilesForSession([usageTs, dependencyTs], session); + const host = ts.TestFSWithWatch.changeToHostTrackingWrittenFiles(ts.projectSystem.createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, ts.projectSystem.libFile])); + const session = ts.projectSystem.createSession(host); + ts.projectSystem.openFilesForSession([usageTs, dependencyTs], session); // Verify CompileOnSaveAffectedFileList - const actualAffectedFiles = session.executeCommandSeq({ - command: protocol.CommandTypes.CompileOnSaveAffectedFileList, + const actualAffectedFiles = session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.CompileOnSaveAffectedFileList, arguments: { file: dependencyTs.path } - }).response as protocol.CompileOnSaveAffectedFileListSingleProject[]; + }).response as ts.projectSystem.protocol.CompileOnSaveAffectedFileListSingleProject[]; assert.deepEqual(actualAffectedFiles, [ expectedAffectedFiles(usageConfig, [usageTs]), expectedAffectedFiles(dependencyConfig, [dependencyTs]) ], "Affected files"); // Verify CompileOnSaveEmit - const actualEmit = session.executeCommandSeq({ - command: protocol.CommandTypes.CompileOnSaveEmitFile, + const actualEmit = session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.CompileOnSaveEmitFile, arguments: { file: dependencyTs.path } }).response; assert.isTrue(actualEmit, "Emit files"); @@ -1751,35 +1651,33 @@ ${appendDts}` assert.equal(host.writtenFiles.size, expectedFiles.length); for (const file of expectedFiles) { assert.equal(host.readFile(file.path), file.content, `Expected to write ${file.path}`); - assert.isTrue(host.writtenFiles.has(file.path as Path), `${file.path} is newly written`); + assert.isTrue(host.writtenFiles.has(file.path as ts.Path), `${file.path} is newly written`); } // Verify EmitOutput - const { exportedModulesFromDeclarationEmit: _1, ...actualEmitOutput } = session.executeCommandSeq({ - command: protocol.CommandTypes.EmitOutput, + const { exportedModulesFromDeclarationEmit: _1, ...actualEmitOutput } = session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.EmitOutput, arguments: { file: dependencyTs.path } - }).response as EmitOutput; + }).response as ts.EmitOutput; assert.deepEqual(actualEmitOutput, expectedEmitOutput(expectedFiles), "Emit output"); }); it("with initial file open, with specifying project file", () => { - const host = TestFSWithWatch.changeToHostTrackingWrittenFiles( - createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]) - ); - const session = createSession(host); - openFilesForSession([usageTs, dependencyTs], session); + const host = ts.TestFSWithWatch.changeToHostTrackingWrittenFiles(ts.projectSystem.createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, ts.projectSystem.libFile])); + const session = ts.projectSystem.createSession(host); + ts.projectSystem.openFilesForSession([usageTs, dependencyTs], session); // Verify CompileOnSaveAffectedFileList - const actualAffectedFiles = session.executeCommandSeq({ - command: protocol.CommandTypes.CompileOnSaveAffectedFileList, + const actualAffectedFiles = session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.CompileOnSaveAffectedFileList, arguments: { file: dependencyTs.path, projectFileName: dependencyConfig.path } - }).response as protocol.CompileOnSaveAffectedFileListSingleProject[]; + }).response as ts.projectSystem.protocol.CompileOnSaveAffectedFileListSingleProject[]; assert.deepEqual(actualAffectedFiles, [ expectedAffectedFiles(dependencyConfig, [dependencyTs]) ], "Affected files"); // Verify CompileOnSaveEmit - const actualEmit = session.executeCommandSeq({ - command: protocol.CommandTypes.CompileOnSaveEmitFile, + const actualEmit = session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.CompileOnSaveEmitFile, arguments: { file: dependencyTs.path, projectFileName: dependencyConfig.path } }).response; assert.isTrue(actualEmit, "Emit files"); @@ -1787,31 +1685,28 @@ ${appendDts}` assert.equal(host.writtenFiles.size, expectedFiles.length); for (const file of expectedFiles) { assert.equal(host.readFile(file.path), file.content, `Expected to write ${file.path}`); - assert.isTrue(host.writtenFiles.has(file.path as Path), `${file.path} is newly written`); + assert.isTrue(host.writtenFiles.has(file.path as ts.Path), `${file.path} is newly written`); } // Verify EmitOutput - const { exportedModulesFromDeclarationEmit: _1, ...actualEmitOutput } = session.executeCommandSeq({ - command: protocol.CommandTypes.EmitOutput, + const { exportedModulesFromDeclarationEmit: _1, ...actualEmitOutput } = session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.EmitOutput, arguments: { file: dependencyTs.path, projectFileName: dependencyConfig.path } - }).response as EmitOutput; + }).response as ts.EmitOutput; assert.deepEqual(actualEmitOutput, expectedEmitOutput(expectedFiles), "Emit output"); }); it("with local change to dependency, without specifying project file", () => { - const host = TestFSWithWatch.changeToHostTrackingWrittenFiles( - createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]) - ); - const session = createSession(host); - openFilesForSession([usageTs, dependencyTs], session); - - session.executeCommandSeq({ - command: protocol.CommandTypes.CompileOnSaveAffectedFileList, + const host = ts.TestFSWithWatch.changeToHostTrackingWrittenFiles(ts.projectSystem.createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, ts.projectSystem.libFile])); + const session = ts.projectSystem.createSession(host); + ts.projectSystem.openFilesForSession([usageTs, dependencyTs], session); + session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.CompileOnSaveAffectedFileList, arguments: { file: dependencyTs.path } }); - const toLocation = protocolToLocation(dependencyTs.content); + const toLocation = ts.projectSystem.protocolToLocation(dependencyTs.content); const location = toLocation(dependencyTs.content.length); - session.executeCommandSeq({ - command: protocol.CommandTypes.Change, + session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.Change, arguments: { file: dependencyTs.path, ...location, @@ -1823,18 +1718,18 @@ ${appendDts}` host.writtenFiles.clear(); // Verify CompileOnSaveAffectedFileList - const actualAffectedFiles = session.executeCommandSeq({ - command: protocol.CommandTypes.CompileOnSaveAffectedFileList, + const actualAffectedFiles = session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.CompileOnSaveAffectedFileList, arguments: { file: dependencyTs.path } - }).response as protocol.CompileOnSaveAffectedFileListSingleProject[]; + }).response as ts.projectSystem.protocol.CompileOnSaveAffectedFileListSingleProject[]; assert.deepEqual(actualAffectedFiles, [ - expectedAffectedFiles(usageConfig, emptyArray), + expectedAffectedFiles(usageConfig, ts.emptyArray), expectedAffectedFiles(dependencyConfig, [dependencyTs]) ], "Affected files"); // Verify CompileOnSaveEmit - const actualEmit = session.executeCommandSeq({ - command: protocol.CommandTypes.CompileOnSaveEmitFile, + const actualEmit = session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.CompileOnSaveEmitFile, arguments: { file: dependencyTs.path } }).response; assert.isTrue(actualEmit, "Emit files"); @@ -1842,31 +1737,28 @@ ${appendDts}` assert.equal(host.writtenFiles.size, expectedFiles.length); for (const file of expectedFiles) { assert.equal(host.readFile(file.path), file.content, `Expected to write ${file.path}`); - assert.isTrue(host.writtenFiles.has(file.path as Path), `${file.path} is newly written`); + assert.isTrue(host.writtenFiles.has(file.path as ts.Path), `${file.path} is newly written`); } // Verify EmitOutput - const { exportedModulesFromDeclarationEmit: _1, ...actualEmitOutput } = session.executeCommandSeq({ - command: protocol.CommandTypes.EmitOutput, + const { exportedModulesFromDeclarationEmit: _1, ...actualEmitOutput } = session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.EmitOutput, arguments: { file: dependencyTs.path } - }).response as EmitOutput; + }).response as ts.EmitOutput; assert.deepEqual(actualEmitOutput, expectedEmitOutput(expectedFiles), "Emit output"); }); it("with local change to dependency, with specifying project file", () => { - const host = TestFSWithWatch.changeToHostTrackingWrittenFiles( - createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]) - ); - const session = createSession(host); - openFilesForSession([usageTs, dependencyTs], session); - - session.executeCommandSeq({ - command: protocol.CommandTypes.CompileOnSaveAffectedFileList, + const host = ts.TestFSWithWatch.changeToHostTrackingWrittenFiles(ts.projectSystem.createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, ts.projectSystem.libFile])); + const session = ts.projectSystem.createSession(host); + ts.projectSystem.openFilesForSession([usageTs, dependencyTs], session); + session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.CompileOnSaveAffectedFileList, arguments: { file: dependencyTs.path } }); - const toLocation = protocolToLocation(dependencyTs.content); + const toLocation = ts.projectSystem.protocolToLocation(dependencyTs.content); const location = toLocation(dependencyTs.content.length); - session.executeCommandSeq({ - command: protocol.CommandTypes.Change, + session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.Change, arguments: { file: dependencyTs.path, ...location, @@ -1878,17 +1770,17 @@ ${appendDts}` host.writtenFiles.clear(); // Verify CompileOnSaveAffectedFileList - const actualAffectedFiles = session.executeCommandSeq({ - command: protocol.CommandTypes.CompileOnSaveAffectedFileList, + const actualAffectedFiles = session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.CompileOnSaveAffectedFileList, arguments: { file: dependencyTs.path, projectFileName: dependencyConfig.path } - }).response as protocol.CompileOnSaveAffectedFileListSingleProject[]; + }).response as ts.projectSystem.protocol.CompileOnSaveAffectedFileListSingleProject[]; assert.deepEqual(actualAffectedFiles, [ expectedAffectedFiles(dependencyConfig, [dependencyTs]) ], "Affected files"); // Verify CompileOnSaveEmit - const actualEmit = session.executeCommandSeq({ - command: protocol.CommandTypes.CompileOnSaveEmitFile, + const actualEmit = session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.CompileOnSaveEmitFile, arguments: { file: dependencyTs.path, projectFileName: dependencyConfig.path } }).response; assert.isTrue(actualEmit, "Emit files"); @@ -1896,31 +1788,28 @@ ${appendDts}` assert.equal(host.writtenFiles.size, expectedFiles.length); for (const file of expectedFiles) { assert.equal(host.readFile(file.path), file.content, `Expected to write ${file.path}`); - assert.isTrue(host.writtenFiles.has(file.path as Path), `${file.path} is newly written`); + assert.isTrue(host.writtenFiles.has(file.path as ts.Path), `${file.path} is newly written`); } // Verify EmitOutput - const { exportedModulesFromDeclarationEmit: _1, ...actualEmitOutput } = session.executeCommandSeq({ - command: protocol.CommandTypes.EmitOutput, + const { exportedModulesFromDeclarationEmit: _1, ...actualEmitOutput } = session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.EmitOutput, arguments: { file: dependencyTs.path, projectFileName: dependencyConfig.path } - }).response as EmitOutput; + }).response as ts.EmitOutput; assert.deepEqual(actualEmitOutput, expectedEmitOutput(expectedFiles), "Emit output"); }); it("with local change to usage, without specifying project file", () => { - const host = TestFSWithWatch.changeToHostTrackingWrittenFiles( - createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]) - ); - const session = createSession(host); - openFilesForSession([usageTs, dependencyTs], session); - - session.executeCommandSeq({ - command: protocol.CommandTypes.CompileOnSaveAffectedFileList, + const host = ts.TestFSWithWatch.changeToHostTrackingWrittenFiles(ts.projectSystem.createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, ts.projectSystem.libFile])); + const session = ts.projectSystem.createSession(host); + ts.projectSystem.openFilesForSession([usageTs, dependencyTs], session); + session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.CompileOnSaveAffectedFileList, arguments: { file: dependencyTs.path } }); - const toLocation = protocolToLocation(usageTs.content); + const toLocation = ts.projectSystem.protocolToLocation(usageTs.content); const location = toLocation(usageTs.content.length); - session.executeCommandSeq({ - command: protocol.CommandTypes.Change, + session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.Change, arguments: { file: usageTs.path, ...location, @@ -1932,18 +1821,18 @@ ${appendDts}` host.writtenFiles.clear(); // Verify CompileOnSaveAffectedFileList - const actualAffectedFiles = session.executeCommandSeq({ - command: protocol.CommandTypes.CompileOnSaveAffectedFileList, + const actualAffectedFiles = session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.CompileOnSaveAffectedFileList, arguments: { file: dependencyTs.path } - }).response as protocol.CompileOnSaveAffectedFileListSingleProject[]; + }).response as ts.projectSystem.protocol.CompileOnSaveAffectedFileListSingleProject[]; assert.deepEqual(actualAffectedFiles, [ - expectedAffectedFiles(usageConfig, emptyArray), + expectedAffectedFiles(usageConfig, ts.emptyArray), expectedAffectedFiles(dependencyConfig, [dependencyTs]) ], "Affected files"); // Verify CompileOnSaveEmit - const actualEmit = session.executeCommandSeq({ - command: protocol.CommandTypes.CompileOnSaveEmitFile, + const actualEmit = session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.CompileOnSaveEmitFile, arguments: { file: dependencyTs.path } }).response; assert.isTrue(actualEmit, "Emit files"); @@ -1951,31 +1840,28 @@ ${appendDts}` assert.equal(host.writtenFiles.size, expectedFiles.length); for (const file of expectedFiles) { assert.equal(host.readFile(file.path), file.content, `Expected to write ${file.path}`); - assert.isTrue(host.writtenFiles.has(file.path as Path), `${file.path} is newly written`); + assert.isTrue(host.writtenFiles.has(file.path as ts.Path), `${file.path} is newly written`); } // Verify EmitOutput - const { exportedModulesFromDeclarationEmit: _1, ...actualEmitOutput } = session.executeCommandSeq({ - command: protocol.CommandTypes.EmitOutput, + const { exportedModulesFromDeclarationEmit: _1, ...actualEmitOutput } = session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.EmitOutput, arguments: { file: dependencyTs.path } - }).response as EmitOutput; + }).response as ts.EmitOutput; assert.deepEqual(actualEmitOutput, expectedEmitOutput(expectedFiles), "Emit output"); }); it("with local change to usage, with specifying project file", () => { - const host = TestFSWithWatch.changeToHostTrackingWrittenFiles( - createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]) - ); - const session = createSession(host); - openFilesForSession([usageTs, dependencyTs], session); - - session.executeCommandSeq({ - command: protocol.CommandTypes.CompileOnSaveAffectedFileList, + const host = ts.TestFSWithWatch.changeToHostTrackingWrittenFiles(ts.projectSystem.createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, ts.projectSystem.libFile])); + const session = ts.projectSystem.createSession(host); + ts.projectSystem.openFilesForSession([usageTs, dependencyTs], session); + session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.CompileOnSaveAffectedFileList, arguments: { file: dependencyTs.path } }); - const toLocation = protocolToLocation(usageTs.content); + const toLocation = ts.projectSystem.protocolToLocation(usageTs.content); const location = toLocation(usageTs.content.length); - session.executeCommandSeq({ - command: protocol.CommandTypes.Change, + session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.Change, arguments: { file: usageTs.path, ...location, @@ -1987,17 +1873,17 @@ ${appendDts}` host.writtenFiles.clear(); // Verify CompileOnSaveAffectedFileList - const actualAffectedFiles = session.executeCommandSeq({ - command: protocol.CommandTypes.CompileOnSaveAffectedFileList, + const actualAffectedFiles = session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.CompileOnSaveAffectedFileList, arguments: { file: dependencyTs.path, projectFileName: dependencyConfig.path } - }).response as protocol.CompileOnSaveAffectedFileListSingleProject[]; + }).response as ts.projectSystem.protocol.CompileOnSaveAffectedFileListSingleProject[]; assert.deepEqual(actualAffectedFiles, [ expectedAffectedFiles(dependencyConfig, [dependencyTs]) ], "Affected files"); // Verify CompileOnSaveEmit - const actualEmit = session.executeCommandSeq({ - command: protocol.CommandTypes.CompileOnSaveEmitFile, + const actualEmit = session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.CompileOnSaveEmitFile, arguments: { file: dependencyTs.path, projectFileName: dependencyConfig.path } }).response; assert.isTrue(actualEmit, "Emit files"); @@ -2005,31 +1891,28 @@ ${appendDts}` assert.equal(host.writtenFiles.size, expectedFiles.length); for (const file of expectedFiles) { assert.equal(host.readFile(file.path), file.content, `Expected to write ${file.path}`); - assert.isTrue(host.writtenFiles.has(file.path as Path), `${file.path} is newly written`); + assert.isTrue(host.writtenFiles.has(file.path as ts.Path), `${file.path} is newly written`); } // Verify EmitOutput - const { exportedModulesFromDeclarationEmit: _1, ...actualEmitOutput } = session.executeCommandSeq({ - command: protocol.CommandTypes.EmitOutput, + const { exportedModulesFromDeclarationEmit: _1, ...actualEmitOutput } = session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.EmitOutput, arguments: { file: dependencyTs.path, projectFileName: dependencyConfig.path } - }).response as EmitOutput; + }).response as ts.EmitOutput; assert.deepEqual(actualEmitOutput, expectedEmitOutput(expectedFiles), "Emit output"); }); it("with change to dependency, without specifying project file", () => { - const host = TestFSWithWatch.changeToHostTrackingWrittenFiles( - createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]) - ); - const session = createSession(host); - openFilesForSession([usageTs, dependencyTs], session); - - session.executeCommandSeq({ - command: protocol.CommandTypes.CompileOnSaveAffectedFileList, + const host = ts.TestFSWithWatch.changeToHostTrackingWrittenFiles(ts.projectSystem.createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, ts.projectSystem.libFile])); + const session = ts.projectSystem.createSession(host); + ts.projectSystem.openFilesForSession([usageTs, dependencyTs], session); + session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.CompileOnSaveAffectedFileList, arguments: { file: dependencyTs.path } }); - const toLocation = protocolToLocation(dependencyTs.content); + const toLocation = ts.projectSystem.protocolToLocation(dependencyTs.content); const location = toLocation(dependencyTs.content.length); - session.executeCommandSeq({ - command: protocol.CommandTypes.Change, + session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.Change, arguments: { file: dependencyTs.path, ...location, @@ -2041,18 +1924,18 @@ ${appendDts}` host.writtenFiles.clear(); // Verify CompileOnSaveAffectedFileList - const actualAffectedFiles = session.executeCommandSeq({ - command: protocol.CommandTypes.CompileOnSaveAffectedFileList, + const actualAffectedFiles = session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.CompileOnSaveAffectedFileList, arguments: { file: dependencyTs.path } - }).response as protocol.CompileOnSaveAffectedFileListSingleProject[]; + }).response as ts.projectSystem.protocol.CompileOnSaveAffectedFileListSingleProject[]; assert.deepEqual(actualAffectedFiles, [ expectedAffectedFiles(usageConfig, [usageTs]), expectedAffectedFiles(dependencyConfig, [dependencyTs]) ], "Affected files"); // Verify CompileOnSaveEmit - const actualEmit = session.executeCommandSeq({ - command: protocol.CommandTypes.CompileOnSaveEmitFile, + const actualEmit = session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.CompileOnSaveEmitFile, arguments: { file: dependencyTs.path } }).response; assert.isTrue(actualEmit, "Emit files"); @@ -2060,31 +1943,28 @@ ${appendDts}` assert.equal(host.writtenFiles.size, expectedFiles.length); for (const file of expectedFiles) { assert.equal(host.readFile(file.path), file.content, `Expected to write ${file.path}`); - assert.isTrue(host.writtenFiles.has(file.path as Path), `${file.path} is newly written`); + assert.isTrue(host.writtenFiles.has(file.path as ts.Path), `${file.path} is newly written`); } // Verify EmitOutput - const { exportedModulesFromDeclarationEmit: _1, ...actualEmitOutput } = session.executeCommandSeq({ - command: protocol.CommandTypes.EmitOutput, + const { exportedModulesFromDeclarationEmit: _1, ...actualEmitOutput } = session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.EmitOutput, arguments: { file: dependencyTs.path } - }).response as EmitOutput; + }).response as ts.EmitOutput; assert.deepEqual(actualEmitOutput, expectedEmitOutput(expectedFiles), "Emit output"); }); it("with change to dependency, with specifying project file", () => { - const host = TestFSWithWatch.changeToHostTrackingWrittenFiles( - createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]) - ); - const session = createSession(host); - openFilesForSession([usageTs, dependencyTs], session); - - session.executeCommandSeq({ - command: protocol.CommandTypes.CompileOnSaveAffectedFileList, + const host = ts.TestFSWithWatch.changeToHostTrackingWrittenFiles(ts.projectSystem.createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, ts.projectSystem.libFile])); + const session = ts.projectSystem.createSession(host); + ts.projectSystem.openFilesForSession([usageTs, dependencyTs], session); + session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.CompileOnSaveAffectedFileList, arguments: { file: dependencyTs.path } }); - const toLocation = protocolToLocation(dependencyTs.content); + const toLocation = ts.projectSystem.protocolToLocation(dependencyTs.content); const location = toLocation(dependencyTs.content.length); - session.executeCommandSeq({ - command: protocol.CommandTypes.Change, + session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.Change, arguments: { file: dependencyTs.path, ...location, @@ -2096,17 +1976,17 @@ ${appendDts}` host.writtenFiles.clear(); // Verify CompileOnSaveAffectedFileList - const actualAffectedFiles = session.executeCommandSeq({ - command: protocol.CommandTypes.CompileOnSaveAffectedFileList, + const actualAffectedFiles = session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.CompileOnSaveAffectedFileList, arguments: { file: dependencyTs.path, projectFileName: dependencyConfig.path } - }).response as protocol.CompileOnSaveAffectedFileListSingleProject[]; + }).response as ts.projectSystem.protocol.CompileOnSaveAffectedFileListSingleProject[]; assert.deepEqual(actualAffectedFiles, [ expectedAffectedFiles(dependencyConfig, [dependencyTs]) ], "Affected files"); // Verify CompileOnSaveEmit - const actualEmit = session.executeCommandSeq({ - command: protocol.CommandTypes.CompileOnSaveEmitFile, + const actualEmit = session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.CompileOnSaveEmitFile, arguments: { file: dependencyTs.path, projectFileName: dependencyConfig.path } }).response; assert.isTrue(actualEmit, "Emit files"); @@ -2114,31 +1994,28 @@ ${appendDts}` assert.equal(host.writtenFiles.size, expectedFiles.length); for (const file of expectedFiles) { assert.equal(host.readFile(file.path), file.content, `Expected to write ${file.path}`); - assert.isTrue(host.writtenFiles.has(file.path as Path), `${file.path} is newly written`); + assert.isTrue(host.writtenFiles.has(file.path as ts.Path), `${file.path} is newly written`); } // Verify EmitOutput - const { exportedModulesFromDeclarationEmit: _1, ...actualEmitOutput } = session.executeCommandSeq({ - command: protocol.CommandTypes.EmitOutput, + const { exportedModulesFromDeclarationEmit: _1, ...actualEmitOutput } = session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.EmitOutput, arguments: { file: dependencyTs.path, projectFileName: dependencyConfig.path } - }).response as EmitOutput; + }).response as ts.EmitOutput; assert.deepEqual(actualEmitOutput, expectedEmitOutput(expectedFiles), "Emit output"); }); it("with change to usage, without specifying project file", () => { - const host = TestFSWithWatch.changeToHostTrackingWrittenFiles( - createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]) - ); - const session = createSession(host); - openFilesForSession([usageTs, dependencyTs], session); - - session.executeCommandSeq({ - command: protocol.CommandTypes.CompileOnSaveAffectedFileList, + const host = ts.TestFSWithWatch.changeToHostTrackingWrittenFiles(ts.projectSystem.createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, ts.projectSystem.libFile])); + const session = ts.projectSystem.createSession(host); + ts.projectSystem.openFilesForSession([usageTs, dependencyTs], session); + session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.CompileOnSaveAffectedFileList, arguments: { file: dependencyTs.path } }); - const toLocation = protocolToLocation(usageTs.content); + const toLocation = ts.projectSystem.protocolToLocation(usageTs.content); const location = toLocation(usageTs.content.length); - session.executeCommandSeq({ - command: protocol.CommandTypes.Change, + session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.Change, arguments: { file: usageTs.path, ...location, @@ -2150,18 +2027,18 @@ ${appendDts}` host.writtenFiles.clear(); // Verify CompileOnSaveAffectedFileList - const actualAffectedFiles = session.executeCommandSeq({ - command: protocol.CommandTypes.CompileOnSaveAffectedFileList, + const actualAffectedFiles = session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.CompileOnSaveAffectedFileList, arguments: { file: dependencyTs.path } - }).response as protocol.CompileOnSaveAffectedFileListSingleProject[]; + }).response as ts.projectSystem.protocol.CompileOnSaveAffectedFileListSingleProject[]; assert.deepEqual(actualAffectedFiles, [ - expectedAffectedFiles(usageConfig, emptyArray), + expectedAffectedFiles(usageConfig, ts.emptyArray), expectedAffectedFiles(dependencyConfig, [dependencyTs]) ], "Affected files"); // Verify CompileOnSaveEmit - const actualEmit = session.executeCommandSeq({ - command: protocol.CommandTypes.CompileOnSaveEmitFile, + const actualEmit = session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.CompileOnSaveEmitFile, arguments: { file: dependencyTs.path } }).response; assert.isTrue(actualEmit, "Emit files"); @@ -2169,31 +2046,28 @@ ${appendDts}` assert.equal(host.writtenFiles.size, expectedFiles.length); for (const file of expectedFiles) { assert.equal(host.readFile(file.path), file.content, `Expected to write ${file.path}`); - assert.isTrue(host.writtenFiles.has(file.path as Path), `${file.path} is newly written`); + assert.isTrue(host.writtenFiles.has(file.path as ts.Path), `${file.path} is newly written`); } // Verify EmitOutput - const { exportedModulesFromDeclarationEmit: _1, ...actualEmitOutput } = session.executeCommandSeq({ - command: protocol.CommandTypes.EmitOutput, + const { exportedModulesFromDeclarationEmit: _1, ...actualEmitOutput } = session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.EmitOutput, arguments: { file: dependencyTs.path } - }).response as EmitOutput; + }).response as ts.EmitOutput; assert.deepEqual(actualEmitOutput, expectedEmitOutput(expectedFiles), "Emit output"); }); it("with change to usage, with specifying project file", () => { - const host = TestFSWithWatch.changeToHostTrackingWrittenFiles( - createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]) - ); - const session = createSession(host); - openFilesForSession([usageTs, dependencyTs], session); - - session.executeCommandSeq({ - command: protocol.CommandTypes.CompileOnSaveAffectedFileList, + const host = ts.TestFSWithWatch.changeToHostTrackingWrittenFiles(ts.projectSystem.createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, ts.projectSystem.libFile])); + const session = ts.projectSystem.createSession(host); + ts.projectSystem.openFilesForSession([usageTs, dependencyTs], session); + session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.CompileOnSaveAffectedFileList, arguments: { file: dependencyTs.path } }); - const toLocation = protocolToLocation(usageTs.content); + const toLocation = ts.projectSystem.protocolToLocation(usageTs.content); const location = toLocation(usageTs.content.length); - session.executeCommandSeq({ - command: protocol.CommandTypes.Change, + session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.Change, arguments: { file: usageTs.path, ...location, @@ -2205,17 +2079,17 @@ ${appendDts}` host.writtenFiles.clear(); // Verify CompileOnSaveAffectedFileList - const actualAffectedFiles = session.executeCommandSeq({ - command: protocol.CommandTypes.CompileOnSaveAffectedFileList, + const actualAffectedFiles = session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.CompileOnSaveAffectedFileList, arguments: { file: dependencyTs.path, projectFileName: dependencyConfig.path } - }).response as protocol.CompileOnSaveAffectedFileListSingleProject[]; + }).response as ts.projectSystem.protocol.CompileOnSaveAffectedFileListSingleProject[]; assert.deepEqual(actualAffectedFiles, [ expectedAffectedFiles(dependencyConfig, [dependencyTs]) ], "Affected files"); // Verify CompileOnSaveEmit - const actualEmit = session.executeCommandSeq({ - command: protocol.CommandTypes.CompileOnSaveEmitFile, + const actualEmit = session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.CompileOnSaveEmitFile, arguments: { file: dependencyTs.path, projectFileName: dependencyConfig.path } }).response; assert.isTrue(actualEmit, "Emit files"); @@ -2223,14 +2097,14 @@ ${appendDts}` assert.equal(host.writtenFiles.size, expectedFiles.length); for (const file of expectedFiles) { assert.equal(host.readFile(file.path), file.content, `Expected to write ${file.path}`); - assert.isTrue(host.writtenFiles.has(file.path as Path), `${file.path} is newly written`); + assert.isTrue(host.writtenFiles.has(file.path as ts.Path), `${file.path} is newly written`); } // Verify EmitOutput - const { exportedModulesFromDeclarationEmit: _1, ...actualEmitOutput } = session.executeCommandSeq({ - command: protocol.CommandTypes.EmitOutput, + const { exportedModulesFromDeclarationEmit: _1, ...actualEmitOutput } = session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.EmitOutput, arguments: { file: dependencyTs.path, projectFileName: dependencyConfig.path } - }).response as EmitOutput; + }).response as ts.EmitOutput; assert.deepEqual(actualEmitOutput, expectedEmitOutput(expectedFiles), "Emit output"); }); }); @@ -2239,8 +2113,8 @@ ${appendDts}` describe("unittests:: tsserver:: with project references and compile on save with external projects", () => { it("compile on save emits same output as project build", () => { - const tsbaseJson: File = { - path: `${tscWatch.projectRoot}/tsbase.json`, + const tsbaseJson: ts.projectSystem.File = { + path: `${ts.tscWatch.projectRoot}/tsbase.json`, content: JSON.stringify({ compileOnSave: true, compilerOptions: { @@ -2249,8 +2123,8 @@ ${appendDts}` } }) }; - const buttonClass = `${tscWatch.projectRoot}/buttonClass`; - const buttonConfig: File = { + const buttonClass = `${ts.tscWatch.projectRoot}/buttonClass`; + const buttonConfig: ts.projectSystem.File = { path: `${buttonClass}/tsconfig.json`, content: JSON.stringify({ extends: "../tsbase.json", @@ -2260,7 +2134,7 @@ ${appendDts}` files: ["Source.ts"] }) }; - const buttonSource: File = { + const buttonSource: ts.projectSystem.File = { path: `${buttonClass}/Source.ts`, content: `module Hmi { export class Button { @@ -2270,8 +2144,8 @@ ${appendDts}` }` }; - const siblingClass = `${tscWatch.projectRoot}/SiblingClass`; - const siblingConfig: File = { + const siblingClass = `${ts.tscWatch.projectRoot}/SiblingClass`; + const siblingConfig: ts.projectSystem.File = { path: `${siblingClass}/tsconfig.json`, content: JSON.stringify({ extends: "../tsbase.json", @@ -2284,7 +2158,7 @@ ${appendDts}` files: ["Source.ts"] }) }; - const siblingSource: File = { + const siblingSource: ts.projectSystem.File = { path: `${siblingClass}/Source.ts`, content: `module Hmi { export class Sibling { @@ -2293,18 +2167,17 @@ ${appendDts}` } }` }; - const host = createServerHost([libFile, tsbaseJson, buttonConfig, buttonSource, siblingConfig, siblingSource], { useCaseSensitiveFileNames: true }); + const host = ts.projectSystem.createServerHost([ts.projectSystem.libFile, tsbaseJson, buttonConfig, buttonSource, siblingConfig, siblingSource], { useCaseSensitiveFileNames: true }); // ts build should succeed - tscWatch.ensureErrorFreeBuild(host, [siblingConfig.path]); - const sourceJs = changeExtension(siblingSource.path, ".js"); + ts.tscWatch.ensureErrorFreeBuild(host, [siblingConfig.path]); + const sourceJs = ts.changeExtension(siblingSource.path, ".js"); const expectedSiblingJs = host.readFile(sourceJs); - const session = createSession(host); - openFilesForSession([siblingSource], session); - - session.executeCommandSeq({ - command: protocol.CommandTypes.CompileOnSaveEmitFile, + const session = ts.projectSystem.createSession(host); + ts.projectSystem.openFilesForSession([siblingSource], session); + session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.CompileOnSaveEmitFile, arguments: { file: siblingSource.path, projectFileName: siblingConfig.path diff --git a/src/testRunner/unittests/tsserver/projectReferenceErrors.ts b/src/testRunner/unittests/tsserver/projectReferenceErrors.ts index 7368f54b9f2ad..bb29587fcdfaf 100644 --- a/src/testRunner/unittests/tsserver/projectReferenceErrors.ts +++ b/src/testRunner/unittests/tsserver/projectReferenceErrors.ts @@ -1,19 +1,18 @@ namespace ts.projectSystem { describe("unittests:: tsserver:: with project references and error reporting", () => { - const dependecyLocation = `${tscWatch.projectRoot}/dependency`; - const usageLocation = `${tscWatch.projectRoot}/usage`; - - function verifyUsageAndDependency(scenario: string, dependencyTs: File, dependencyConfig: File, usageTs: File, usageConfig: File) { - function usageProjectDiagnostics(): GetErrForProjectDiagnostics { + const dependecyLocation = `${ts.tscWatch.projectRoot}/dependency`; + const usageLocation = `${ts.tscWatch.projectRoot}/usage`; + function verifyUsageAndDependency(scenario: string, dependencyTs: ts.projectSystem.File, dependencyConfig: ts.projectSystem.File, usageTs: ts.projectSystem.File, usageConfig: ts.projectSystem.File) { + function usageProjectDiagnostics(): ts.projectSystem.GetErrForProjectDiagnostics { return { project: usageTs, files: [usageTs, dependencyTs] }; } - function dependencyProjectDiagnostics(): GetErrForProjectDiagnostics { + function dependencyProjectDiagnostics(): ts.projectSystem.GetErrForProjectDiagnostics { return { project: dependencyTs, files: [dependencyTs] }; } describe("when dependency project is not open", () => { - verifyGetErrScenario({ + ts.projectSystem.verifyGetErrScenario({ scenario: "projectReferenceErrors", subScenario: `${scenario} when dependency project is not open`, allFiles: () => [dependencyTs, dependencyConfig, usageTs, usageConfig], @@ -38,7 +37,7 @@ namespace ts.projectSystem { }); describe("when the depedency file is open", () => { - verifyGetErrScenario({ + ts.projectSystem.verifyGetErrScenario({ scenario: "projectReferenceErrors", subScenario: `${scenario} when the depedency file is open`, allFiles: () => [dependencyTs, dependencyConfig, usageTs, usageConfig], @@ -62,7 +61,7 @@ namespace ts.projectSystem { } describe("with module scenario", () => { - const dependencyTs: File = { + const dependencyTs: ts.projectSystem.File = { path: `${dependecyLocation}/fns.ts`, content: `export function fn1() { } export function fn2() { } @@ -71,11 +70,11 @@ export function fn2() { } // Error in dependency ts file export let x: string = 10;` }; - const dependencyConfig: File = { + const dependencyConfig: ts.projectSystem.File = { path: `${dependecyLocation}/tsconfig.json`, content: JSON.stringify({ compilerOptions: { composite: true, declarationDir: "../decls" } }) }; - const usageTs: File = { + const usageTs: ts.projectSystem.File = { path: `${usageLocation}/usage.ts`, content: `import { fn1, @@ -87,7 +86,7 @@ fn2(); fnErr(); ` }; - const usageConfig: File = { + const usageConfig: ts.projectSystem.File = { path: `${usageLocation}/tsconfig.json`, content: JSON.stringify({ compilerOptions: { composite: true }, @@ -98,7 +97,7 @@ fnErr(); }); describe("with non module --out", () => { - const dependencyTs: File = { + const dependencyTs: ts.projectSystem.File = { path: `${dependecyLocation}/fns.ts`, content: `function fn1() { } function fn2() { } @@ -107,18 +106,18 @@ function fn2() { } // Error in dependency ts file let x: string = 10;` }; - const dependencyConfig: File = { + const dependencyConfig: ts.projectSystem.File = { path: `${dependecyLocation}/tsconfig.json`, content: JSON.stringify({ compilerOptions: { composite: true, outFile: "../dependency.js" } }) }; - const usageTs: File = { + const usageTs: ts.projectSystem.File = { path: `${usageLocation}/usage.ts`, content: `fn1(); fn2(); fnErr(); ` }; - const usageConfig: File = { + const usageConfig: ts.projectSystem.File = { path: `${usageLocation}/tsconfig.json`, content: JSON.stringify({ compilerOptions: { composite: true, outFile: "../usage.js" }, diff --git a/src/testRunner/unittests/tsserver/projectReferences.ts b/src/testRunner/unittests/tsserver/projectReferences.ts index ba4604be5aabf..2d511112bf3ef 100644 --- a/src/testRunner/unittests/tsserver/projectReferences.ts +++ b/src/testRunner/unittests/tsserver/projectReferences.ts @@ -1,17 +1,20 @@ namespace ts.projectSystem { - export function createHostWithSolutionBuild(files: readonly TestFSWithWatch.FileOrFolderOrSymLink[], rootNames: readonly string[]) { - const host = createServerHost(files); + export function createHostWithSolutionBuild(files: readonly ts.TestFSWithWatch.FileOrFolderOrSymLink[], rootNames: readonly string[]) { + const host = ts.projectSystem.createServerHost(files); // ts build should succeed - tscWatch.ensureErrorFreeBuild(host, rootNames); + ts.tscWatch.ensureErrorFreeBuild(host, rootNames); return host; } describe("unittests:: tsserver:: with project references and tsbuild", () => { describe("with container project", () => { - function getProjectFiles(project: string): [File, File] { + function getProjectFiles(project: string): [ + ts.projectSystem.File, + ts.projectSystem.File + ] { return [ - TestFSWithWatch.getTsBuildProjectFile(project, "tsconfig.json"), - TestFSWithWatch.getTsBuildProjectFile(project, "index.ts"), + ts.TestFSWithWatch.getTsBuildProjectFile(project, "tsconfig.json"), + ts.TestFSWithWatch.getTsBuildProjectFile(project, "index.ts"), ]; } @@ -19,72 +22,72 @@ namespace ts.projectSystem { const containerLib = getProjectFiles("container/lib"); const containerExec = getProjectFiles("container/exec"); const containerCompositeExec = getProjectFiles("container/compositeExec"); - const containerConfig = TestFSWithWatch.getTsBuildProjectFile(project, "tsconfig.json"); - const files = [libFile, ...containerLib, ...containerExec, ...containerCompositeExec, containerConfig]; + const containerConfig = ts.TestFSWithWatch.getTsBuildProjectFile(project, "tsconfig.json"); + const files = [ts.projectSystem.libFile, ...containerLib, ...containerExec, ...containerCompositeExec, containerConfig]; it("does not error on container only project", () => { const host = createHostWithSolutionBuild(files, [containerConfig.path]); // Open external project for the folder - const session = createSession(host, { logger: createLoggerWithInMemoryLogs() }); + const session = ts.projectSystem.createSession(host, { logger: ts.projectSystem.createLoggerWithInMemoryLogs() }); const service = session.getProjectService(); service.openExternalProjects([{ - projectFileName: TestFSWithWatch.getTsBuildProjectFilePath(project, project), + projectFileName: ts.TestFSWithWatch.getTsBuildProjectFilePath(project, project), rootFiles: files.map(f => ({ fileName: f.path })), options: {} }]); files.forEach(f => { - const args: protocol.FileRequestArgs = { + const args: ts.projectSystem.protocol.FileRequestArgs = { file: f.path, - projectFileName: endsWith(f.path, "tsconfig.json") ? f.path : undefined + projectFileName: ts.endsWith(f.path, "tsconfig.json") ? f.path : undefined }; - session.executeCommandSeq({ - command: protocol.CommandTypes.SyntacticDiagnosticsSync, + session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.SyntacticDiagnosticsSync, arguments: args }); - session.executeCommandSeq({ - command: protocol.CommandTypes.SemanticDiagnosticsSync, + session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.SemanticDiagnosticsSync, arguments: args }); }); const containerProject = service.configuredProjects.get(containerConfig.path)!; - session.executeCommandSeq({ - command: protocol.CommandTypes.CompilerOptionsDiagnosticsFull, + session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.CompilerOptionsDiagnosticsFull, arguments: { projectFileName: containerProject.projectName } }); - baselineTsserverLogs("projectReferences", `does not error on container only project`, session); + ts.projectSystem.baselineTsserverLogs("projectReferences", `does not error on container only project`, session); }); it("can successfully find references with --out options", () => { const host = createHostWithSolutionBuild(files, [containerConfig.path]); - const session = createSession(host, { logger: createLoggerWithInMemoryLogs() }); - openFilesForSession([containerCompositeExec[1]], session); - const myConstStart = protocolLocationFromSubstring(containerCompositeExec[1].content, "myConst"); - session.executeCommandSeq({ - command: protocol.CommandTypes.Rename, + const session = ts.projectSystem.createSession(host, { logger: ts.projectSystem.createLoggerWithInMemoryLogs() }); + ts.projectSystem.openFilesForSession([containerCompositeExec[1]], session); + const myConstStart = ts.projectSystem.protocolLocationFromSubstring(containerCompositeExec[1].content, "myConst"); + session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.Rename, arguments: { file: containerCompositeExec[1].path, ...myConstStart } }); - baselineTsserverLogs("projectReferences", `can successfully find references with out option`, session); + ts.projectSystem.baselineTsserverLogs("projectReferences", `can successfully find references with out option`, session); }); it("ancestor and project ref management", () => { - const tempFile: File = { + const tempFile: ts.projectSystem.File = { path: `/user/username/projects/temp/temp.ts`, content: "let x = 10" }; const host = createHostWithSolutionBuild(files.concat([tempFile]), [containerConfig.path]); - const session = createSession(host, { logger: createLoggerWithInMemoryLogs() }); - openFilesForSession([containerCompositeExec[1]], session); + const session = ts.projectSystem.createSession(host, { logger: ts.projectSystem.createLoggerWithInMemoryLogs() }); + ts.projectSystem.openFilesForSession([containerCompositeExec[1]], session); const service = session.getProjectService(); // Open temp file and verify all projects alive - openFilesForSession([tempFile], session); + ts.projectSystem.openFilesForSession([tempFile], session); // Ref projects are loaded after as part of this command - const locationOfMyConst = protocolLocationFromSubstring(containerCompositeExec[1].content, "myConst"); - session.executeCommandSeq({ - command: protocol.CommandTypes.Rename, + const locationOfMyConst = ts.projectSystem.protocolLocationFromSubstring(containerCompositeExec[1].content, "myConst"); + session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.Rename, arguments: { file: containerCompositeExec[1].path, ...locationOfMyConst @@ -93,20 +96,20 @@ namespace ts.projectSystem { // Open temp file and verify all projects alive service.closeClientFile(tempFile.path); - openFilesForSession([tempFile], session); + ts.projectSystem.openFilesForSession([tempFile], session); // Close all files and open temp file, only inferred project should be alive service.closeClientFile(containerCompositeExec[1].path); service.closeClientFile(tempFile.path); - openFilesForSession([tempFile], session); - baselineTsserverLogs("projectReferences", `ancestor and project ref management`, session); + ts.projectSystem.openFilesForSession([tempFile], session); + ts.projectSystem.baselineTsserverLogs("projectReferences", `ancestor and project ref management`, session); }); }); describe("when root file is file from referenced project", () => { function verify(disableSourceOfProjectReferenceRedirect: boolean) { const projectLocation = `/user/username/projects/project`; - const commonConfig: File = { + const commonConfig: ts.projectSystem.File = { path: `${projectLocation}/src/common/tsconfig.json`, content: JSON.stringify({ compilerOptions: { @@ -119,12 +122,12 @@ namespace ts.projectSystem { include: ["./**/*"] }) }; - const keyboardTs: File = { + const keyboardTs: ts.projectSystem.File = { path: `${projectLocation}/src/common/input/keyboard.ts`, content: `function bar() { return "just a random function so .d.ts location doesnt match"; } export function evaluateKeyboardEvent() { }` }; - const keyboardTestTs: File = { + const keyboardTestTs: ts.projectSystem.File = { path: `${projectLocation}/src/common/input/keyboard.test.ts`, content: `import { evaluateKeyboardEvent } from 'common/input/keyboard'; function testEvaluateKeyboardEvent() { @@ -132,7 +135,7 @@ function testEvaluateKeyboardEvent() { } ` }; - const srcConfig: File = { + const srcConfig: ts.projectSystem.File = { path: `${projectLocation}/src/tsconfig.json`, content: JSON.stringify({ compilerOptions: { @@ -152,7 +155,7 @@ function testEvaluateKeyboardEvent() { ] }) }; - const terminalTs: File = { + const terminalTs: ts.projectSystem.File = { path: `${projectLocation}/src/terminal.ts`, content: `import { evaluateKeyboardEvent } from 'common/input/keyboard'; function foo() { @@ -160,29 +163,26 @@ function foo() { } ` }; - const host = createHostWithSolutionBuild( - [commonConfig, keyboardTs, keyboardTestTs, srcConfig, terminalTs, libFile], - [srcConfig.path] - ); - const session = createSession(host, { logger: createLoggerWithInMemoryLogs() }); - openFilesForSession([keyboardTs, terminalTs], session); + const host = createHostWithSolutionBuild([commonConfig, keyboardTs, keyboardTestTs, srcConfig, terminalTs, ts.projectSystem.libFile], [srcConfig.path]); + const session = ts.projectSystem.createSession(host, { logger: ts.projectSystem.createLoggerWithInMemoryLogs() }); + ts.projectSystem.openFilesForSession([keyboardTs, terminalTs], session); const searchStr = "evaluateKeyboardEvent"; const importStr = `import { evaluateKeyboardEvent } from 'common/input/keyboard';`; - const result = session.executeCommandSeq({ - command: protocol.CommandTypes.References, - arguments: protocolFileLocationFromSubstring(keyboardTs, searchStr) - }).response as protocol.ReferencesResponseBody; + const result = session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.References, + arguments: ts.projectSystem.protocolFileLocationFromSubstring(keyboardTs, searchStr) + }).response as ts.projectSystem.protocol.ReferencesResponseBody; assert.deepEqual(result, { refs: [ - makeReferenceItem({ + ts.projectSystem.makeReferenceItem({ file: keyboardTs, text: searchStr, contextText: `export function evaluateKeyboardEvent() { }`, isDefinition: true, lineText: `export function evaluateKeyboardEvent() { }` }), - makeReferenceItem({ + ts.projectSystem.makeReferenceItem({ file: keyboardTestTs, text: searchStr, contextText: importStr, @@ -190,14 +190,14 @@ function foo() { isWriteAccess: true, lineText: importStr }), - makeReferenceItem({ + ts.projectSystem.makeReferenceItem({ file: keyboardTestTs, text: searchStr, options: { index: 1 }, isDefinition: false, lineText: ` return evaluateKeyboardEvent();` }), - makeReferenceItem({ + ts.projectSystem.makeReferenceItem({ file: terminalTs, text: searchStr, contextText: importStr, @@ -205,7 +205,7 @@ function foo() { isWriteAccess: true, lineText: importStr }), - makeReferenceItem({ + ts.projectSystem.makeReferenceItem({ file: terminalTs, text: searchStr, options: { index: 1 }, @@ -214,10 +214,10 @@ function foo() { }), ], symbolName: searchStr, - symbolStartOffset: protocolLocationFromSubstring(keyboardTs.content, searchStr).offset, + symbolStartOffset: ts.projectSystem.protocolLocationFromSubstring(keyboardTs.content, searchStr).offset, symbolDisplayString: "function evaluateKeyboardEvent(): void" }); - baselineTsserverLogs("projectReferences", `root file is file from referenced project${disableSourceOfProjectReferenceRedirect ? " and using declaration maps" : ""}`, session); + ts.projectSystem.baselineTsserverLogs("projectReferences", `root file is file from referenced project${disableSourceOfProjectReferenceRedirect ? " and using declaration maps" : ""}`, session); } it(`when using declaration file maps to navigate between projects`, () => { @@ -229,8 +229,8 @@ function foo() { }); it("reusing d.ts files from composite and non composite projects", () => { - const configA: File = { - path: `${tscWatch.projectRoot}/compositea/tsconfig.json`, + const configA: ts.projectSystem.File = { + path: `${ts.tscWatch.projectRoot}/compositea/tsconfig.json`, content: JSON.stringify({ compilerOptions: { composite: true, @@ -241,28 +241,28 @@ function foo() { } }) }; - const aTs: File = { - path: `${tscWatch.projectRoot}/compositea/a.ts`, + const aTs: ts.projectSystem.File = { + path: `${ts.tscWatch.projectRoot}/compositea/a.ts`, content: `import { b } from "@ref/compositeb/b";` }; - const a2Ts: File = { - path: `${tscWatch.projectRoot}/compositea/a2.ts`, + const a2Ts: ts.projectSystem.File = { + path: `${ts.tscWatch.projectRoot}/compositea/a2.ts`, content: `export const x = 10;` }; - const configB: File = { - path: `${tscWatch.projectRoot}/compositeb/tsconfig.json`, + const configB: ts.projectSystem.File = { + path: `${ts.tscWatch.projectRoot}/compositeb/tsconfig.json`, content: configA.content }; - const bTs: File = { - path: `${tscWatch.projectRoot}/compositeb/b.ts`, + const bTs: ts.projectSystem.File = { + path: `${ts.tscWatch.projectRoot}/compositeb/b.ts`, content: "export function b() {}" }; - const bDts: File = { - path: `${tscWatch.projectRoot}/dist/compositeb/b.d.ts`, + const bDts: ts.projectSystem.File = { + path: `${ts.tscWatch.projectRoot}/dist/compositeb/b.d.ts`, content: "export declare function b(): void;" }; - const configC: File = { - path: `${tscWatch.projectRoot}/compositec/tsconfig.json`, + const configC: ts.projectSystem.File = { + path: `${ts.tscWatch.projectRoot}/compositec/tsconfig.json`, content: JSON.stringify({ compilerOptions: { composite: true, @@ -274,27 +274,27 @@ function foo() { references: [{ path: "../compositeb" }] }) }; - const cTs: File = { - path: `${tscWatch.projectRoot}/compositec/c.ts`, + const cTs: ts.projectSystem.File = { + path: `${ts.tscWatch.projectRoot}/compositec/c.ts`, content: aTs.content }; - const files = [libFile, aTs, a2Ts, configA, bDts, bTs, configB, cTs, configC]; - const host = createServerHost(files); - const service = createProjectService(host); + const files = [ts.projectSystem.libFile, aTs, a2Ts, configA, bDts, bTs, configB, cTs, configC]; + const host = ts.projectSystem.createServerHost(files); + const service = ts.projectSystem.createProjectService(host); service.openClientFile(aTs.path); service.checkNumberOfProjects({ configuredProjects: 1 }); // project A referencing b.d.ts without project reference const projectA = service.configuredProjects.get(configA.path)!; assert.isDefined(projectA); - checkProjectActualFiles(projectA, [aTs.path, a2Ts.path, bDts.path, libFile.path, configA.path]); + ts.projectSystem.checkProjectActualFiles(projectA, [aTs.path, a2Ts.path, bDts.path, ts.projectSystem.libFile.path, configA.path]); // reuses b.d.ts but sets the path and resolved path since projectC has project references // as the real resolution was to b.ts service.openClientFile(cTs.path); service.checkNumberOfProjects({ configuredProjects: 2 }); const projectC = service.configuredProjects.get(configC.path)!; - checkProjectActualFiles(projectC, [cTs.path, bTs.path, libFile.path, configC.path]); + ts.projectSystem.checkProjectActualFiles(projectC, [cTs.path, bTs.path, ts.projectSystem.libFile.path, configC.path]); // Now new project for project A tries to reuse b but there is no filesByName mapping for b's source location host.writeFile(a2Ts.path, `${a2Ts.content}export const y = 30;`); @@ -304,11 +304,11 @@ function foo() { describe("when references are monorepo like with symlinks", () => { interface Packages { - bPackageJson: File; - aTest: File; - bFoo: File; - bBar: File; - bSymlink: SymLink; + bPackageJson: ts.projectSystem.File; + aTest: ts.projectSystem.File; + bFoo: ts.projectSystem.File; + bBar: ts.projectSystem.File; + bSymlink: ts.projectSystem.SymLink; } function verifySymlinkScenario(scenario: string, packages: () => Packages) { describe(`${scenario}: when solution is not built`, () => { @@ -332,20 +332,20 @@ function foo() { }); } - function verifySession(scenario: string, { bPackageJson, aTest, bFoo, bBar, bSymlink }: Packages, alreadyBuilt: boolean, extraOptions: CompilerOptions) { + function verifySession(scenario: string, { bPackageJson, aTest, bFoo, bBar, bSymlink }: Packages, alreadyBuilt: boolean, extraOptions: ts.CompilerOptions) { const aConfig = config("A", extraOptions, ["../B"]); const bConfig = config("B", extraOptions); - const files = [libFile, bPackageJson, aConfig, bConfig, aTest, bFoo, bBar, bSymlink]; + const files = [ts.projectSystem.libFile, bPackageJson, aConfig, bConfig, aTest, bFoo, bBar, bSymlink]; const host = alreadyBuilt ? createHostWithSolutionBuild(files, [aConfig.path]) : - createServerHost(files); + ts.projectSystem.createServerHost(files); // Create symlink in node module - const session = createSession(host, { canUseEvents: true, logger: createLoggerWithInMemoryLogs() }); - openFilesForSession([aTest], session); - verifyGetErrRequest({ session, host, files: [aTest] }); - session.executeCommandSeq({ - command: protocol.CommandTypes.UpdateOpen, + const session = ts.projectSystem.createSession(host, { canUseEvents: true, logger: ts.projectSystem.createLoggerWithInMemoryLogs() }); + ts.projectSystem.openFilesForSession([aTest], session); + ts.projectSystem.verifyGetErrRequest({ session, host, files: [aTest] }); + session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.UpdateOpen, arguments: { changedFiles: [{ fileName: aTest.path, @@ -357,13 +357,13 @@ function foo() { }] } }); - verifyGetErrRequest({ session, host, files: [aTest] }); - baselineTsserverLogs("projectReferences", `monorepo like with symlinks ${scenario} and solution is ${alreadyBuilt ? "built" : "not built"}${extraOptions.preserveSymlinks ? " with preserveSymlinks" : ""}`, session); + ts.projectSystem.verifyGetErrRequest({ session, host, files: [aTest] }); + ts.projectSystem.baselineTsserverLogs("projectReferences", `monorepo like with symlinks ${scenario} and solution is ${alreadyBuilt ? "built" : "not built"}${extraOptions.preserveSymlinks ? " with preserveSymlinks" : ""}`, session); } - function config(packageName: string, extraOptions: CompilerOptions, references?: string[]): File { + function config(packageName: string, extraOptions: ts.CompilerOptions, references?: string[]): ts.projectSystem.File { return { - path: `${tscWatch.projectRoot}/packages/${packageName}/tsconfig.json`, + path: `${ts.tscWatch.projectRoot}/packages/${packageName}/tsconfig.json`, content: JSON.stringify({ compilerOptions: { outDir: "lib", @@ -377,9 +377,9 @@ function foo() { }; } - function file(packageName: string, fileName: string, content: string): File { + function file(packageName: string, fileName: string, content: string): ts.projectSystem.File { return { - path: `${tscWatch.projectRoot}/packages/${packageName}/src/${fileName}`, + path: `${ts.tscWatch.projectRoot}/packages/${packageName}/src/${fileName}`, content }; } @@ -387,7 +387,7 @@ function foo() { function verifyMonoRepoLike(scope = "") { verifySymlinkScenario(`when packageJson has types field and has index.ts${scope ? " with scoped package" : ""}`, () => ({ bPackageJson: { - path: `${tscWatch.projectRoot}/packages/B/package.json`, + path: `${ts.tscWatch.projectRoot}/packages/B/package.json`, content: JSON.stringify({ main: "lib/index.js", types: "lib/index.d.ts" @@ -401,14 +401,14 @@ bar(); bFoo: file("B", "index.ts", `export function foo() { }`), bBar: file("B", "bar.ts", `export function bar() { }`), bSymlink: { - path: `${tscWatch.projectRoot}/node_modules/${scope}b`, - symLink: `${tscWatch.projectRoot}/packages/B` + path: `${ts.tscWatch.projectRoot}/node_modules/${scope}b`, + symLink: `${ts.tscWatch.projectRoot}/packages/B` } })); verifySymlinkScenario(`when referencing file from subFolder${scope ? " with scoped package" : ""}`, () => ({ bPackageJson: { - path: `${tscWatch.projectRoot}/packages/B/package.json`, + path: `${ts.tscWatch.projectRoot}/packages/B/package.json`, content: "{}" }, aTest: file("A", "test.ts", `import { foo } from '${scope}b/lib/foo'; @@ -419,8 +419,8 @@ bar(); bFoo: file("B", "foo.ts", `export function foo() { }`), bBar: file("B", "bar/foo.ts", `export function bar() { }`), bSymlink: { - path: `${tscWatch.projectRoot}/node_modules/${scope}b`, - symLink: `${tscWatch.projectRoot}/packages/B` + path: `${ts.tscWatch.projectRoot}/node_modules/${scope}b`, + symLink: `${ts.tscWatch.projectRoot}/packages/B` } })); } @@ -434,8 +434,8 @@ bar(); }); it("when the referenced projects have allowJs and emitDeclarationOnly", () => { - const compositeConfig: File = { - path: `${tscWatch.projectRoot}/packages/emit-composite/tsconfig.json`, + const compositeConfig: ts.projectSystem.File = { + path: `${ts.tscWatch.projectRoot}/packages/emit-composite/tsconfig.json`, content: JSON.stringify({ compilerOptions: { composite: true, @@ -447,8 +447,8 @@ bar(); include: ["src"] }) }; - const compositePackageJson: File = { - path: `${tscWatch.projectRoot}/packages/emit-composite/package.json`, + const compositePackageJson: ts.projectSystem.File = { + path: `${ts.tscWatch.projectRoot}/packages/emit-composite/package.json`, content: JSON.stringify({ name: "emit-composite", version: "1.0.0", @@ -456,15 +456,15 @@ bar(); typings: "lib/index.d.ts" }) }; - const compositeIndex: File = { - path: `${tscWatch.projectRoot}/packages/emit-composite/src/index.js`, + const compositeIndex: ts.projectSystem.File = { + path: `${ts.tscWatch.projectRoot}/packages/emit-composite/src/index.js`, content: `const testModule = require('./testModule'); module.exports = { ...testModule }` }; - const compositeTestModule: File = { - path: `${tscWatch.projectRoot}/packages/emit-composite/src/testModule.js`, + const compositeTestModule: ts.projectSystem.File = { + path: `${ts.tscWatch.projectRoot}/packages/emit-composite/src/testModule.js`, content: `/** * @param {string} arg */ @@ -474,33 +474,33 @@ module.exports = { testCompositeFunction }` }; - const consumerConfig: File = { - path: `${tscWatch.projectRoot}/packages/consumer/tsconfig.json`, + const consumerConfig: ts.projectSystem.File = { + path: `${ts.tscWatch.projectRoot}/packages/consumer/tsconfig.json`, content: JSON.stringify({ include: ["src"], references: [{ path: "../emit-composite" }] }) }; - const consumerIndex: File = { - path: `${tscWatch.projectRoot}/packages/consumer/src/index.ts`, + const consumerIndex: ts.projectSystem.File = { + path: `${ts.tscWatch.projectRoot}/packages/consumer/src/index.ts`, content: `import { testCompositeFunction } from 'emit-composite'; testCompositeFunction('why hello there'); testCompositeFunction('why hello there', 42);` }; - const symlink: SymLink = { - path: `${tscWatch.projectRoot}/node_modules/emit-composite`, - symLink: `${tscWatch.projectRoot}/packages/emit-composite` + const symlink: ts.projectSystem.SymLink = { + path: `${ts.tscWatch.projectRoot}/node_modules/emit-composite`, + symLink: `${ts.tscWatch.projectRoot}/packages/emit-composite` }; - const host = createServerHost([libFile, compositeConfig, compositePackageJson, compositeIndex, compositeTestModule, consumerConfig, consumerIndex, symlink], { useCaseSensitiveFileNames: true }); - const session = createSession(host, { canUseEvents: true, logger: createLoggerWithInMemoryLogs() }); - openFilesForSession([consumerIndex], session); - verifyGetErrRequest({ host, session, files: [consumerIndex] }); - baselineTsserverLogs("projectReferences", `when the referenced projects have allowJs and emitDeclarationOnly`, session); + const host = ts.projectSystem.createServerHost([ts.projectSystem.libFile, compositeConfig, compositePackageJson, compositeIndex, compositeTestModule, consumerConfig, consumerIndex, symlink], { useCaseSensitiveFileNames: true }); + const session = ts.projectSystem.createSession(host, { canUseEvents: true, logger: ts.projectSystem.createLoggerWithInMemoryLogs() }); + ts.projectSystem.openFilesForSession([consumerIndex], session); + ts.projectSystem.verifyGetErrRequest({ host, session, files: [consumerIndex] }); + ts.projectSystem.baselineTsserverLogs("projectReferences", `when the referenced projects have allowJs and emitDeclarationOnly`, session); }); it("when finding local reference doesnt load ancestor/sibling projects", () => { const solutionLocation = "/user/username/projects/solution"; - const solution: File = { + const solution: ts.projectSystem.File = { path: `${solutionLocation}/tsconfig.json`, content: JSON.stringify({ files: [], @@ -511,7 +511,7 @@ testCompositeFunction('why hello there', 42);` ] }) }; - const compilerConfig: File = { + const compilerConfig: ts.projectSystem.File = { path: `${solutionLocation}/compiler/tsconfig.json`, content: JSON.stringify({ compilerOptions: { @@ -521,7 +521,7 @@ testCompositeFunction('why hello there', 42);` files: ["./types.ts", "./program.ts"] }) }; - const typesFile: File = { + const typesFile: ts.projectSystem.File = { path: `${solutionLocation}/compiler/types.ts`, content: ` namespace ts { @@ -530,7 +530,7 @@ testCompositeFunction('why hello there', 42);` } }` }; - const programFile: File = { + const programFile: ts.projectSystem.File = { path: `${solutionLocation}/compiler/program.ts`, content: ` namespace ts { @@ -540,7 +540,7 @@ testCompositeFunction('why hello there', 42);` function getSourceFile() { return "something"; } }` }; - const servicesConfig: File = { + const servicesConfig: ts.projectSystem.File = { path: `${solutionLocation}/services/tsconfig.json`, content: JSON.stringify({ compilerOptions: { @@ -552,7 +552,7 @@ testCompositeFunction('why hello there', 42);` ] }) }; - const servicesFile: File = { + const servicesFile: ts.projectSystem.File = { path: `${solutionLocation}/services/services.ts`, content: ` namespace ts { @@ -560,32 +560,32 @@ testCompositeFunction('why hello there', 42);` }` }; - const files = [libFile, solution, compilerConfig, typesFile, programFile, servicesConfig, servicesFile, libFile]; - const host = createServerHost(files); - const session = createSession(host, { logger: createLoggerWithInMemoryLogs() }); - openFilesForSession([programFile], session); + const files = [ts.projectSystem.libFile, solution, compilerConfig, typesFile, programFile, servicesConfig, servicesFile, ts.projectSystem.libFile]; + const host = ts.projectSystem.createServerHost(files); + const session = ts.projectSystem.createSession(host, { logger: ts.projectSystem.createLoggerWithInMemoryLogs() }); + ts.projectSystem.openFilesForSession([programFile], session); // Find all references for getSourceFile // Shouldnt load more projects - session.executeCommandSeq({ - command: protocol.CommandTypes.References, - arguments: protocolFileLocationFromSubstring(programFile, "getSourceFile", { index: 1 }) + session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.References, + arguments: ts.projectSystem.protocolFileLocationFromSubstring(programFile, "getSourceFile", { index: 1 }) }); // Find all references for getSourceFiles // Should load more projects - session.executeCommandSeq({ - command: protocol.CommandTypes.References, - arguments: protocolFileLocationFromSubstring(programFile, "getSourceFiles") + session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.References, + arguments: ts.projectSystem.protocolFileLocationFromSubstring(programFile, "getSourceFiles") }); - baselineTsserverLogs("projectReferences", `finding local reference doesnt load ancestor/sibling projects`, session); + ts.projectSystem.baselineTsserverLogs("projectReferences", `finding local reference doesnt load ancestor/sibling projects`, session); }); describe("special handling of localness of the definitions for findAllRefs", () => { function verify(scenario: string, definition: string, usage: string, referenceTerm: string) { it(scenario, () => { const solutionLocation = "/user/username/projects/solution"; - const solution: File = { + const solution: ts.projectSystem.File = { path: `${solutionLocation}/tsconfig.json`, content: JSON.stringify({ files: [], @@ -595,7 +595,7 @@ testCompositeFunction('why hello there', 42);` ] }) }; - const apiConfig: File = { + const apiConfig: ts.projectSystem.File = { path: `${solutionLocation}/api/tsconfig.json`, content: JSON.stringify({ compilerOptions: { @@ -607,20 +607,20 @@ testCompositeFunction('why hello there', 42);` references: [{ path: "../shared" }] }) }; - const apiFile: File = { + const apiFile: ts.projectSystem.File = { path: `${solutionLocation}/api/src/server.ts`, content: `import * as shared from "../../shared/dist"; ${usage}` }; - const appConfig: File = { + const appConfig: ts.projectSystem.File = { path: `${solutionLocation}/app/tsconfig.json`, content: apiConfig.content }; - const appFile: File = { + const appFile: ts.projectSystem.File = { path: `${solutionLocation}/app/src/app.ts`, content: apiFile.content }; - const sharedConfig: File = { + const sharedConfig: ts.projectSystem.File = { path: `${solutionLocation}/shared/tsconfig.json`, content: JSON.stringify({ compilerOptions: { @@ -631,67 +631,40 @@ ${usage}` include: ["src"] }) }; - const sharedFile: File = { + const sharedFile: ts.projectSystem.File = { path: `${solutionLocation}/shared/src/index.ts`, content: definition }; - const host = createServerHost([libFile, solution, libFile, apiConfig, apiFile, appConfig, appFile, sharedConfig, sharedFile]); - const session = createSession(host, { logger: createLoggerWithInMemoryLogs() }); - openFilesForSession([apiFile], session); + const host = ts.projectSystem.createServerHost([ts.projectSystem.libFile, solution, ts.projectSystem.libFile, apiConfig, apiFile, appConfig, appFile, sharedConfig, sharedFile]); + const session = ts.projectSystem.createSession(host, { logger: ts.projectSystem.createLoggerWithInMemoryLogs() }); + ts.projectSystem.openFilesForSession([apiFile], session); // Find all references - session.executeCommandSeq({ - command: protocol.CommandTypes.References, - arguments: protocolFileLocationFromSubstring(apiFile, referenceTerm) + session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.References, + arguments: ts.projectSystem.protocolFileLocationFromSubstring(apiFile, referenceTerm) }); - baselineTsserverLogs("projectReferences", `special handling of localness ${scenario}`, session); + ts.projectSystem.baselineTsserverLogs("projectReferences", `special handling of localness ${scenario}`, session); }); } - verify( - "when using arrow function assignment", - `export const dog = () => { };`, - `shared.dog();`, - "dog" - ); - - verify( - "when using arrow function as object literal property types", - `export const foo = { bar: () => { } };`, - `shared.foo.bar();`, - "bar" - ); - - verify( - "when using object literal property", - `export const foo = { baz: "BAZ" };`, - `shared.foo.baz;`, - "baz" - ); - - verify( - "when using method of class expression", - `export const foo = class { fly() {} };`, - `const instance = new shared.foo(); -instance.fly();`, - "fly" - ); + verify("when using arrow function assignment", `export const dog = () => { };`, `shared.dog();`, "dog"); + verify("when using arrow function as object literal property types", `export const foo = { bar: () => { } };`, `shared.foo.bar();`, "bar"); + verify("when using object literal property", `export const foo = { baz: "BAZ" };`, `shared.foo.baz;`, "baz"); + verify("when using method of class expression", `export const foo = class { fly() {} };`, `const instance = new shared.foo(); +instance.fly();`, "fly"); verify( // when using arrow function as object literal property is loaded through indirect assignment with original declaration local to project is treated as local - "when using arrow function as object literal property", - `const local = { bar: () => { } }; -export const foo = local;`, - `shared.foo.bar();`, - "bar" - ); + "when using arrow function as object literal property", `const local = { bar: () => { } }; +export const foo = local;`, `shared.foo.bar();`, "bar"); }); it("when disableSolutionSearching is true, solution and siblings are not loaded", () => { const solutionLocation = "/user/username/projects/solution"; - const solution: File = { + const solution: ts.projectSystem.File = { path: `${solutionLocation}/tsconfig.json`, content: JSON.stringify({ files: [], @@ -702,7 +675,7 @@ export const foo = local;`, ] }) }; - const compilerConfig: File = { + const compilerConfig: ts.projectSystem.File = { path: `${solutionLocation}/compiler/tsconfig.json`, content: JSON.stringify({ compilerOptions: { @@ -713,7 +686,7 @@ export const foo = local;`, files: ["./types.ts", "./program.ts"] }) }; - const typesFile: File = { + const typesFile: ts.projectSystem.File = { path: `${solutionLocation}/compiler/types.ts`, content: ` namespace ts { @@ -722,7 +695,7 @@ export const foo = local;`, } }` }; - const programFile: File = { + const programFile: ts.projectSystem.File = { path: `${solutionLocation}/compiler/program.ts`, content: ` namespace ts { @@ -732,7 +705,7 @@ export const foo = local;`, function getSourceFile() { return "something"; } }` }; - const servicesConfig: File = { + const servicesConfig: ts.projectSystem.File = { path: `${solutionLocation}/services/tsconfig.json`, content: JSON.stringify({ compilerOptions: { @@ -744,7 +717,7 @@ export const foo = local;`, ] }) }; - const servicesFile: File = { + const servicesFile: ts.projectSystem.File = { path: `${solutionLocation}/services/services.ts`, content: ` namespace ts { @@ -752,75 +725,75 @@ export const foo = local;`, }` }; - const files = [libFile, solution, compilerConfig, typesFile, programFile, servicesConfig, servicesFile, libFile]; - const host = createServerHost(files); - const session = createSession(host, { logger: createLoggerWithInMemoryLogs() }); - openFilesForSession([programFile], session); + const files = [ts.projectSystem.libFile, solution, compilerConfig, typesFile, programFile, servicesConfig, servicesFile, ts.projectSystem.libFile]; + const host = ts.projectSystem.createServerHost(files); + const session = ts.projectSystem.createSession(host, { logger: ts.projectSystem.createLoggerWithInMemoryLogs() }); + ts.projectSystem.openFilesForSession([programFile], session); // Find all references // No new solutions/projects loaded - session.executeCommandSeq({ - command: protocol.CommandTypes.References, - arguments: protocolFileLocationFromSubstring(programFile, "getSourceFiles") + session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.References, + arguments: ts.projectSystem.protocolFileLocationFromSubstring(programFile, "getSourceFiles") }); - baselineTsserverLogs("projectReferences", `with disableSolutionSearching solution and siblings are not loaded`, session); + ts.projectSystem.baselineTsserverLogs("projectReferences", `with disableSolutionSearching solution and siblings are not loaded`, session); }); describe("when default project is solution project", () => { interface Setup { scenario: string; - solutionOptions?: CompilerOptions; + solutionOptions?: ts.CompilerOptions; solutionFiles?: string[]; configRefs: string[]; - additionalFiles: readonly File[]; + additionalFiles: readonly ts.projectSystem.File[]; } - const main: File = { - path: `${tscWatch.projectRoot}/src/main.ts`, + const main: ts.projectSystem.File = { + path: `${ts.tscWatch.projectRoot}/src/main.ts`, content: `import { foo } from 'helpers/functions'; export { foo };` }; - const helper: File = { - path: `${tscWatch.projectRoot}/src/helpers/functions.ts`, + const helper: ts.projectSystem.File = { + path: `${ts.tscWatch.projectRoot}/src/helpers/functions.ts`, content: `export const foo = 1;` }; - const mainDts: File = { - path: `${tscWatch.projectRoot}/target/src/main.d.ts`, + const mainDts: ts.projectSystem.File = { + path: `${ts.tscWatch.projectRoot}/target/src/main.d.ts`, content: `import { foo } from 'helpers/functions'; export { foo }; //# sourceMappingURL=main.d.ts.map` }; - const mainDtsMap: File = { - path: `${tscWatch.projectRoot}/target/src/main.d.ts.map`, + const mainDtsMap: ts.projectSystem.File = { + path: `${ts.tscWatch.projectRoot}/target/src/main.d.ts.map`, content: `{"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../../src/main.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,mBAAmB,CAAC;AAExC,OAAO,EAAC,GAAG,EAAC,CAAC"}` }; - const helperDts: File = { - path: `${tscWatch.projectRoot}/target/src/helpers/functions.d.ts`, + const helperDts: ts.projectSystem.File = { + path: `${ts.tscWatch.projectRoot}/target/src/helpers/functions.d.ts`, content: `export declare const foo = 1; //# sourceMappingURL=functions.d.ts.map` }; - const helperDtsMap: File = { - path: `${tscWatch.projectRoot}/target/src/helpers/functions.d.ts.map`, + const helperDtsMap: ts.projectSystem.File = { + path: `${ts.tscWatch.projectRoot}/target/src/helpers/functions.d.ts.map`, content: `{"version":3,"file":"functions.d.ts","sourceRoot":"","sources":["../../../src/helpers/functions.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,GAAG,IAAI,CAAC"}` }; - const tsconfigIndirect3: File = { - path: `${tscWatch.projectRoot}/indirect3/tsconfig.json`, + const tsconfigIndirect3: ts.projectSystem.File = { + path: `${ts.tscWatch.projectRoot}/indirect3/tsconfig.json`, content: JSON.stringify({ compilerOptions: { baseUrl: "../target/src/" }, }) }; - const fileResolvingToMainDts: File = { - path: `${tscWatch.projectRoot}/indirect3/main.ts`, + const fileResolvingToMainDts: ts.projectSystem.File = { + path: `${ts.tscWatch.projectRoot}/indirect3/main.ts`, content: `import { foo } from 'main'; foo; export function bar() {}` }; - const tsconfigSrcPath = `${tscWatch.projectRoot}/tsconfig-src.json`; - const tsconfigPath = `${tscWatch.projectRoot}/tsconfig.json`; + const tsconfigSrcPath = `${ts.tscWatch.projectRoot}/tsconfig-src.json`; + const tsconfigPath = `${ts.tscWatch.projectRoot}/tsconfig.json`; const dummyFilePath = "/dummy/dummy.ts"; function setup({ solutionFiles, solutionOptions, configRefs, additionalFiles }: Setup) { - const tsconfigSrc: File = { + const tsconfigSrc: ts.projectSystem.File = { path: tsconfigSrcPath, content: JSON.stringify({ compilerOptions: { @@ -831,7 +804,7 @@ export function bar() {}` include: ["./src/**/*"] }) }; - const tsconfig: File = { + const tsconfig: ts.projectSystem.File = { path: tsconfigPath, content: JSON.stringify({ ... (solutionOptions ? { compilerOptions: solutionOptions } : {}), @@ -839,17 +812,19 @@ export function bar() {}` files: solutionFiles || [] }) }; - const dummyFile: File = { + const dummyFile: ts.projectSystem.File = { path: dummyFilePath, content: "let a = 10;" }; - const host = createServerHost([ + const host = ts.projectSystem.createServerHost([ tsconfigSrc, tsconfig, main, helper, - libFile, dummyFile, + ts.projectSystem.libFile, + dummyFile, mainDts, mainDtsMap, helperDts, helperDtsMap, tsconfigIndirect3, fileResolvingToMainDts, - ...additionalFiles]); - const session = createSession(host, { canUseEvents: true, logger: createLoggerWithInMemoryLogs() }); + ...additionalFiles + ]); + const session = ts.projectSystem.createSession(host, { canUseEvents: true, logger: ts.projectSystem.createLoggerWithInMemoryLogs() }); const service = session.getProjectService(); service.openClientFile(main.path); return { session, service, host }; @@ -858,14 +833,14 @@ export function bar() {}` function verifySolutionScenario(input: Setup) { const { session, service, host } = setup(input); - const info = service.getScriptInfoForPath(main.path as Path)!; + const info = service.getScriptInfoForPath(main.path as ts.Path)!; session.logger.logs.push(""); session.logger.logs.push(`getDefaultProject for ${main.path}: ${info.getDefaultProject().projectName}`); session.logger.logs.push(`findDefaultConfiguredProject for ${main.path}: ${service.findDefaultConfiguredProject(info)!.projectName}`); session.logger.logs.push(""); // Verify errors - verifyGetErrRequest({ session, host, files: [main] }); + ts.projectSystem.verifyGetErrRequest({ session, host, files: [main] }); // Verify collection of script infos service.openClientFile(dummyFilePath); @@ -882,10 +857,10 @@ export function bar() {}` service.reloadProjects(); // Find all refs - session.executeCommandSeq({ - command: protocol.CommandTypes.References, - arguments: protocolFileLocationFromSubstring(main, "foo", { index: 1 }) - }).response as protocol.ReferencesResponseBody; + session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.References, + arguments: ts.projectSystem.protocolFileLocationFromSubstring(main, "foo", { index: 1 }) + }).response as ts.projectSystem.protocol.ReferencesResponseBody; service.closeClientFile(main.path); service.closeClientFile(dummyFilePath); @@ -894,16 +869,16 @@ export function bar() {}` service.openClientFile(fileResolvingToMainDts.path); // Find all refs from dts include - session.executeCommandSeq({ - command: protocol.CommandTypes.References, - arguments: protocolFileLocationFromSubstring(fileResolvingToMainDts, "foo") - }).response as protocol.ReferencesResponseBody; - baselineTsserverLogs("projectReferences", input.scenario, session); + session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.References, + arguments: ts.projectSystem.protocolFileLocationFromSubstring(fileResolvingToMainDts, "foo") + }).response as ts.projectSystem.protocol.ReferencesResponseBody; + ts.projectSystem.baselineTsserverLogs("projectReferences", input.scenario, session); } - function getIndirectProject(postfix: string, optionsToExtend?: CompilerOptions) { - const tsconfigIndirect: File = { - path: `${tscWatch.projectRoot}/tsconfig-indirect${postfix}.json`, + function getIndirectProject(postfix: string, optionsToExtend?: ts.CompilerOptions) { + const tsconfigIndirect: ts.projectSystem.File = { + path: `${ts.tscWatch.projectRoot}/tsconfig-indirect${postfix}.json`, content: JSON.stringify({ compilerOptions: { composite: true, @@ -915,8 +890,8 @@ export function bar() {}` references: [{ path: "./tsconfig-src.json" }] }) }; - const indirect: File = { - path: `${tscWatch.projectRoot}/indirect${postfix}/main.ts`, + const indirect: ts.projectSystem.File = { + path: `${ts.tscWatch.projectRoot}/indirect${postfix}/main.ts`, content: fileResolvingToMainDts.content }; return { tsconfigIndirect, indirect }; @@ -925,7 +900,7 @@ export function bar() {}` function verifyDisableReferencedProjectLoad(input: Setup) { const { session, service } = setup(input); - const info = service.getScriptInfoForPath(main.path as Path)!; + const info = service.getScriptInfoForPath(main.path as ts.Path)!; session.logger.logs.push(""); session.logger.logs.push(`getDefaultProject for ${main.path}: ${info.getDefaultProject().projectName}`); session.logger.logs.push(`findDefaultConfiguredProject for ${main.path}: ${service.findDefaultConfiguredProject(info)?.projectName}`); @@ -942,14 +917,14 @@ export function bar() {}` // Verify Reload projects service.reloadProjects(); - baselineTsserverLogs("projectReferences", input.scenario, session); + ts.projectSystem.baselineTsserverLogs("projectReferences", input.scenario, session); } it("when project is directly referenced by solution", () => { verifySolutionScenario({ scenario: "project is directly referenced by solution", configRefs: ["./tsconfig-src.json"], - additionalFiles: emptyArray, + additionalFiles: ts.emptyArray, }); }); @@ -968,7 +943,7 @@ export function bar() {}` scenario: "disables looking into the child project if disableReferencedProjectLoad is set", solutionOptions: { disableReferencedProjectLoad: true }, configRefs: ["./tsconfig-src.json"], - additionalFiles: emptyArray, + additionalFiles: ts.emptyArray, }); }); @@ -993,8 +968,8 @@ export function bar() {}` describe("when solution is project that contains its own files", () => { it("when the project found is not solution but references open file through project reference", () => { - const ownMain: File = { - path: `${tscWatch.projectRoot}/own/main.ts`, + const ownMain: ts.projectSystem.File = { + path: `${ts.tscWatch.projectRoot}/own/main.ts`, content: fileResolvingToMainDts.content }; verifySolutionScenario({ @@ -1010,8 +985,8 @@ export function bar() {}` }); it("when project is indirectly referenced by solution", () => { - const ownMain: File = { - path: `${tscWatch.projectRoot}/own/main.ts`, + const ownMain: ts.projectSystem.File = { + path: `${ts.tscWatch.projectRoot}/own/main.ts`, content: `import { bar } from 'main'; bar;` }; @@ -1030,8 +1005,8 @@ bar;` }); it("disables looking into the child project if disableReferencedProjectLoad is set", () => { - const ownMain: File = { - path: `${tscWatch.projectRoot}/own/main.ts`, + const ownMain: ts.projectSystem.File = { + path: `${ts.tscWatch.projectRoot}/own/main.ts`, content: fileResolvingToMainDts.content }; verifyDisableReferencedProjectLoad({ @@ -1048,8 +1023,8 @@ bar;` }); it("disables looking into the child project if disableReferencedProjectLoad is set in indirect project", () => { - const ownMain: File = { - path: `${tscWatch.projectRoot}/own/main.ts`, + const ownMain: ts.projectSystem.File = { + path: `${ts.tscWatch.projectRoot}/own/main.ts`, content: `import { bar } from 'main'; bar;` }; @@ -1067,8 +1042,8 @@ bar;` }); it("disables looking into the child project if disableReferencedProjectLoad is set in first indirect project but not in another one", () => { - const ownMain: File = { - path: `${tscWatch.projectRoot}/own/main.ts`, + const ownMain: ts.projectSystem.File = { + path: `${ts.tscWatch.projectRoot}/own/main.ts`, content: `import { bar } from 'main'; bar;` }; @@ -1089,9 +1064,9 @@ bar;` }); describe("when new file is added to the referenced project", () => { - function setup(extendOptionsProject2?: CompilerOptions) { - const config1: File = { - path: `${tscWatch.projectRoot}/projects/project1/tsconfig.json`, + function setup(extendOptionsProject2?: ts.CompilerOptions) { + const config1: ts.projectSystem.File = { + path: `${ts.tscWatch.projectRoot}/projects/project1/tsconfig.json`, content: JSON.stringify({ compilerOptions: { module: "none", @@ -1100,16 +1075,16 @@ bar;` exclude: ["temp"] }) }; - const class1: File = { - path: `${tscWatch.projectRoot}/projects/project1/class1.ts`, + const class1: ts.projectSystem.File = { + path: `${ts.tscWatch.projectRoot}/projects/project1/class1.ts`, content: `class class1 {}` }; - const class1Dts: File = { - path: `${tscWatch.projectRoot}/projects/project1/class1.d.ts`, + const class1Dts: ts.projectSystem.File = { + path: `${ts.tscWatch.projectRoot}/projects/project1/class1.d.ts`, content: `declare class class1 {}` }; - const config2: File = { - path: `${tscWatch.projectRoot}/projects/project2/tsconfig.json`, + const config2: ts.projectSystem.File = { + path: `${ts.tscWatch.projectRoot}/projects/project2/tsconfig.json`, content: JSON.stringify({ compilerOptions: { module: "none", @@ -1121,13 +1096,13 @@ bar;` ] }) }; - const class2: File = { - path: `${tscWatch.projectRoot}/projects/project2/class2.ts`, + const class2: ts.projectSystem.File = { + path: `${ts.tscWatch.projectRoot}/projects/project2/class2.ts`, content: `class class2 {}` }; - const host = createServerHost([config1, class1, class1Dts, config2, class2, libFile]); - const session = createSession(host, { logger: createLoggerWithInMemoryLogs() }); - openFilesForSession([class2], session); + const host = ts.projectSystem.createServerHost([config1, class1, class1Dts, config2, class2, ts.projectSystem.libFile]); + const session = ts.projectSystem.createSession(host, { logger: ts.projectSystem.createLoggerWithInMemoryLogs() }); + ts.projectSystem.openFilesForSession([class2], session); return { host, session, class1 }; } @@ -1135,52 +1110,52 @@ bar;` const { host, session } = setup(); // Add new class to referenced project - const class3 = `${tscWatch.projectRoot}/projects/project1/class3.ts`; + const class3 = `${ts.tscWatch.projectRoot}/projects/project1/class3.ts`; host.writeFile(class3, `class class3 {}`); host.checkTimeoutQueueLengthAndRun(2); // Add excluded file to referenced project - host.ensureFileOrFolder({ path: `${tscWatch.projectRoot}/projects/project1/temp/file.d.ts`, content: `declare class file {}` }); + host.ensureFileOrFolder({ path: `${ts.tscWatch.projectRoot}/projects/project1/temp/file.d.ts`, content: `declare class file {}` }); host.checkTimeoutQueueLengthAndRun(0); // Add output from new class to referenced project - const class3Dts = `${tscWatch.projectRoot}/projects/project1/class3.d.ts`; + const class3Dts = `${ts.tscWatch.projectRoot}/projects/project1/class3.d.ts`; host.writeFile(class3Dts, `declare class class3 {}`); host.checkTimeoutQueueLengthAndRun(0); - baselineTsserverLogs("projectReferences", `new file is added to the referenced project when referenced project is not open`, session); + ts.projectSystem.baselineTsserverLogs("projectReferences", `new file is added to the referenced project when referenced project is not open`, session); }); it("when referenced project is open", () => { const { host, session, class1 } = setup(); - openFilesForSession([class1], session); + ts.projectSystem.openFilesForSession([class1], session); // Add new class to referenced project - const class3 = `${tscWatch.projectRoot}/projects/project1/class3.ts`; + const class3 = `${ts.tscWatch.projectRoot}/projects/project1/class3.ts`; host.writeFile(class3, `class class3 {}`); host.checkTimeoutQueueLengthAndRun(3); // Add excluded file to referenced project - host.ensureFileOrFolder({ path: `${tscWatch.projectRoot}/projects/project1/temp/file.d.ts`, content: `declare class file {}` }); + host.ensureFileOrFolder({ path: `${ts.tscWatch.projectRoot}/projects/project1/temp/file.d.ts`, content: `declare class file {}` }); host.checkTimeoutQueueLengthAndRun(0); // Add output from new class to referenced project - const class3Dts = `${tscWatch.projectRoot}/projects/project1/class3.d.ts`; + const class3Dts = `${ts.tscWatch.projectRoot}/projects/project1/class3.d.ts`; host.writeFile(class3Dts, `declare class class3 {}`); host.checkTimeoutQueueLengthAndRun(0); - baselineTsserverLogs("projectReferences", `new file is added to the referenced project when referenced project is open`, session); + ts.projectSystem.baselineTsserverLogs("projectReferences", `new file is added to the referenced project when referenced project is open`, session); }); it("when referenced project is not open with disableSourceOfProjectReferenceRedirect", () => { const { host, session } = setup({ disableSourceOfProjectReferenceRedirect: true }); // Add new class to referenced project - const class3 = `${tscWatch.projectRoot}/projects/project1/class3.ts`; + const class3 = `${ts.tscWatch.projectRoot}/projects/project1/class3.ts`; host.writeFile(class3, `class class3 {}`); host.checkTimeoutQueueLengthAndRun(2); // Add output of new class to referenced project - const class3Dts = `${tscWatch.projectRoot}/projects/project1/class3.d.ts`; + const class3Dts = `${ts.tscWatch.projectRoot}/projects/project1/class3.d.ts`; host.writeFile(class3Dts, `declare class class3 {}`); host.checkTimeoutQueueLengthAndRun(2); // Add excluded file to referenced project - host.ensureFileOrFolder({ path: `${tscWatch.projectRoot}/projects/project1/temp/file.d.ts`, content: `declare class file {}` }); + host.ensureFileOrFolder({ path: `${ts.tscWatch.projectRoot}/projects/project1/temp/file.d.ts`, content: `declare class file {}` }); host.checkTimeoutQueueLengthAndRun(0); // Delete output from new class to referenced project host.deleteFile(class3Dts); @@ -1188,23 +1163,23 @@ bar;` // Write back output of new class to referenced project host.writeFile(class3Dts, `declare class class3 {}`); host.checkTimeoutQueueLengthAndRun(2); - baselineTsserverLogs("projectReferences", `new file is added to the referenced project when referenced project is not open with disableSourceOfProjectReferenceRedirect`, session); + ts.projectSystem.baselineTsserverLogs("projectReferences", `new file is added to the referenced project when referenced project is not open with disableSourceOfProjectReferenceRedirect`, session); }); it("when referenced project is open with disableSourceOfProjectReferenceRedirect", () => { const { host, session, class1 } = setup({ disableSourceOfProjectReferenceRedirect: true }); - openFilesForSession([class1], session); + ts.projectSystem.openFilesForSession([class1], session); // Add new class to referenced project - const class3 = `${tscWatch.projectRoot}/projects/project1/class3.ts`; + const class3 = `${ts.tscWatch.projectRoot}/projects/project1/class3.ts`; host.writeFile(class3, `class class3 {}`); host.checkTimeoutQueueLengthAndRun(3); // Add output of new class to referenced project - const class3Dts = `${tscWatch.projectRoot}/projects/project1/class3.d.ts`; + const class3Dts = `${ts.tscWatch.projectRoot}/projects/project1/class3.d.ts`; host.writeFile(class3Dts, `declare class class3 {}`); host.checkTimeoutQueueLengthAndRun(2); // Add excluded file to referenced project - host.ensureFileOrFolder({ path: `${tscWatch.projectRoot}/projects/project1/temp/file.d.ts`, content: `declare class file {}` }); + host.ensureFileOrFolder({ path: `${ts.tscWatch.projectRoot}/projects/project1/temp/file.d.ts`, content: `declare class file {}` }); host.checkTimeoutQueueLengthAndRun(0); // Delete output from new class to referenced project host.deleteFile(class3Dts); @@ -1212,14 +1187,14 @@ bar;` // Write back output of new class to referenced project host.writeFile(class3Dts, `declare class class3 {}`); host.checkTimeoutQueueLengthAndRun(2); - baselineTsserverLogs("projectReferences", `new file is added to the referenced project when referenced project is open with disableSourceOfProjectReferenceRedirect`, session); + ts.projectSystem.baselineTsserverLogs("projectReferences", `new file is added to the referenced project when referenced project is open with disableSourceOfProjectReferenceRedirect`, session); }); }); describe("auto import with referenced project", () => { function verifyAutoImport(built: boolean, disableSourceOfProjectReferenceRedirect?: boolean) { - const solnConfig: File = { - path: `${tscWatch.projectRoot}/tsconfig.json`, + const solnConfig: ts.projectSystem.File = { + path: `${ts.tscWatch.projectRoot}/tsconfig.json`, content: JSON.stringify({ files: [], references: [ @@ -1228,8 +1203,8 @@ bar;` ] }) }; - const sharedConfig: File = { - path: `${tscWatch.projectRoot}/shared/src/library/tsconfig.json`, + const sharedConfig: ts.projectSystem.File = { + path: `${ts.tscWatch.projectRoot}/shared/src/library/tsconfig.json`, content: JSON.stringify({ compilerOptions: { composite: true, @@ -1237,12 +1212,12 @@ bar;` } }) }; - const sharedIndex: File = { - path: `${tscWatch.projectRoot}/shared/src/library/index.ts`, + const sharedIndex: ts.projectSystem.File = { + path: `${ts.tscWatch.projectRoot}/shared/src/library/index.ts`, content: `export function foo() {}` }; - const sharedPackage: File = { - path: `${tscWatch.projectRoot}/shared/package.json`, + const sharedPackage: ts.projectSystem.File = { + path: `${ts.tscWatch.projectRoot}/shared/package.json`, content: JSON.stringify({ name: "shared", version: "1.0.0", @@ -1250,8 +1225,8 @@ bar;` types: "bld/library/index.d.ts" }) }; - const appConfig: File = { - path: `${tscWatch.projectRoot}/app/src/program/tsconfig.json`, + const appConfig: ts.projectSystem.File = { + path: `${ts.tscWatch.projectRoot}/app/src/program/tsconfig.json`, content: JSON.stringify({ compilerOptions: { composite: true, @@ -1263,38 +1238,38 @@ bar;` ] }) }; - const appBar: File = { - path: `${tscWatch.projectRoot}/app/src/program/bar.ts`, + const appBar: ts.projectSystem.File = { + path: `${ts.tscWatch.projectRoot}/app/src/program/bar.ts`, content: `import {foo} from "shared";` }; - const appIndex: File = { - path: `${tscWatch.projectRoot}/app/src/program/index.ts`, + const appIndex: ts.projectSystem.File = { + path: `${ts.tscWatch.projectRoot}/app/src/program/index.ts`, content: `foo` }; - const sharedSymlink: SymLink = { - path: `${tscWatch.projectRoot}/node_modules/shared`, - symLink: `${tscWatch.projectRoot}/shared` + const sharedSymlink: ts.projectSystem.SymLink = { + path: `${ts.tscWatch.projectRoot}/node_modules/shared`, + symLink: `${ts.tscWatch.projectRoot}/shared` }; - const files = [solnConfig, sharedConfig, sharedIndex, sharedPackage, appConfig, appBar, appIndex, sharedSymlink, libFile]; - const host = createServerHost(files); + const files = [solnConfig, sharedConfig, sharedIndex, sharedPackage, appConfig, appBar, appIndex, sharedSymlink, ts.projectSystem.libFile]; + const host = ts.projectSystem.createServerHost(files); if (built) { - tscWatch.solutionBuildWithBaseline(host, [solnConfig.path]); + ts.tscWatch.solutionBuildWithBaseline(host, [solnConfig.path]); host.clearOutput(); } - const session = createSession(host, { logger: createLoggerWithInMemoryLogs() }); - openFilesForSession([appIndex], session); - session.executeCommandSeq({ - command: protocol.CommandTypes.GetCodeFixes, + const session = ts.projectSystem.createSession(host, { logger: ts.projectSystem.createLoggerWithInMemoryLogs() }); + ts.projectSystem.openFilesForSession([appIndex], session); + session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.GetCodeFixes, arguments: { file: appIndex.path, startLine: 1, startOffset: 1, endLine: 1, endOffset: 4, - errorCodes: [Diagnostics.Cannot_find_name_0.code], + errorCodes: [ts.Diagnostics.Cannot_find_name_0.code], } }); - baselineTsserverLogs("projectReferences", `auto import with referenced project${built ? " when built" : ""}${disableSourceOfProjectReferenceRedirect ? " with disableSourceOfProjectReferenceRedirect": ""}`, session); + ts.projectSystem.baselineTsserverLogs("projectReferences", `auto import with referenced project${built ? " when built" : ""}${disableSourceOfProjectReferenceRedirect ? " with disableSourceOfProjectReferenceRedirect" : ""}`, session); } it("when project is built", () => { @@ -1309,13 +1284,16 @@ bar;` }); it("when files from two projects are open and one project references", () => { - function getPackageAndFile(packageName: string, references?: string[], optionsToExtend?: CompilerOptions): [file: File, config: File] { - const file: File = { - path: `${tscWatch.projectRoot}/${packageName}/src/file1.ts`, + function getPackageAndFile(packageName: string, references?: string[], optionsToExtend?: ts.CompilerOptions): [ + file: ts.projectSystem.File, + config: ts.projectSystem.File + ] { + const file: ts.projectSystem.File = { + path: `${ts.tscWatch.projectRoot}/${packageName}/src/file1.ts`, content: `export const ${packageName}Const = 10;` }; - const config: File = { - path: `${tscWatch.projectRoot}/${packageName}/tsconfig.json`, + const config: ts.projectSystem.File = { + path: `${ts.tscWatch.projectRoot}/${packageName}/tsconfig.json`, content: JSON.stringify({ compilerOptions: { composite: true, ...optionsToExtend || {} }, references: references?.map(path => ({ path: `../${path}` })) @@ -1336,35 +1314,36 @@ bar;` const [indirectNoCoreRefFile, indirectNoCoreRefConfig] = getPackageAndFile("indirectNoCoreRef", ["noCoreRef2"]); const [noCoreRef2File, noCoreRef2Config] = getPackageAndFile("noCoreRef2"); - const host = createServerHost([ - libFile, mainFile, mainConfig, coreFile, coreConfig, noCoreRef1File, noCoreRef1Config, + const host = ts.projectSystem.createServerHost([ + ts.projectSystem.libFile, + mainFile, mainConfig, coreFile, coreConfig, noCoreRef1File, noCoreRef1Config, indirectFile, indirectConfig, coreRef1File, coreRef1Config, indirectDisabledChildLoad1File, indirectDisabledChildLoad1Config, coreRef2File, coreRef2Config, indirectDisabledChildLoad2File, indirectDisabledChildLoad2Config, coreRef3File, coreRef3Config, refToCoreRef3File, refToCoreRef3Config, indirectNoCoreRefFile, indirectNoCoreRefConfig, noCoreRef2File, noCoreRef2Config ], { useCaseSensitiveFileNames: true }); - const session = createSession(host, { logger: createLoggerWithInMemoryLogs() }); - openFilesForSession([mainFile, coreFile], session); + const session = ts.projectSystem.createSession(host, { logger: ts.projectSystem.createLoggerWithInMemoryLogs() }); + ts.projectSystem.openFilesForSession([mainFile, coreFile], session); // Find all refs in coreFile - session.executeCommandSeq({ - command: protocol.CommandTypes.References, - arguments: protocolFileLocationFromSubstring(coreFile, `coreConst`) + session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.References, + arguments: ts.projectSystem.protocolFileLocationFromSubstring(coreFile, `coreConst`) }); - baselineTsserverLogs("projectReferences", `when files from two projects are open and one project references`, session); + ts.projectSystem.baselineTsserverLogs("projectReferences", `when files from two projects are open and one project references`, session); }); describe("find refs to decl in other proj", () => { - const indexA: File = { - path: `${tscWatch.projectRoot}/a/index.ts`, + const indexA: ts.projectSystem.File = { + path: `${ts.tscWatch.projectRoot}/a/index.ts`, content: `import { B } from "../b/lib"; const b: B = new B();` }; - const configB: File = { - path: `${tscWatch.projectRoot}/b/tsconfig.json`, + const configB: ts.projectSystem.File = { + path: `${ts.tscWatch.projectRoot}/b/tsconfig.json`, content: `{ "compilerOptions": { "declarationMap": true, @@ -1374,69 +1353,63 @@ const b: B = new B();` }` }; - const indexB: File = { - path: `${tscWatch.projectRoot}/b/index.ts`, + const indexB: ts.projectSystem.File = { + path: `${ts.tscWatch.projectRoot}/b/index.ts`, content: `export class B { M() {} }` }; - const helperB: File = { - path: `${tscWatch.projectRoot}/b/helper.ts`, + const helperB: ts.projectSystem.File = { + path: `${ts.tscWatch.projectRoot}/b/helper.ts`, content: `import { B } from "."; const b: B = new B();` }; - const dtsB: File = { - path: `${tscWatch.projectRoot}/b/lib/index.d.ts`, + const dtsB: ts.projectSystem.File = { + path: `${ts.tscWatch.projectRoot}/b/lib/index.d.ts`, content: `export declare class B { M(): void; } //# sourceMappingURL=index.d.ts.map` }; - const dtsMapB: File = { - path: `${tscWatch.projectRoot}/b/lib/index.d.ts.map`, + const dtsMapB: ts.projectSystem.File = { + path: `${ts.tscWatch.projectRoot}/b/lib/index.d.ts.map`, content: `{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA,qBAAa,CAAC;IACV,CAAC;CACJ"}` }; - function baselineDisableReferencedProjectLoad( - projectAlreadyLoaded: boolean, - disableReferencedProjectLoad: boolean, - disableSourceOfProjectReferenceRedirect: boolean, - dtsMapPresent: boolean) { + function baselineDisableReferencedProjectLoad(projectAlreadyLoaded: boolean, disableReferencedProjectLoad: boolean, disableSourceOfProjectReferenceRedirect: boolean, dtsMapPresent: boolean) { // Mangled to stay under windows path length limit - const subScenario = - `when proj ${projectAlreadyLoaded ? "is" : "is not"} loaded` + + const subScenario = `when proj ${projectAlreadyLoaded ? "is" : "is not"} loaded` + ` and refd proj loading is ${disableReferencedProjectLoad ? "disabled" : "enabled"}` + ` and proj ref redirects are ${disableSourceOfProjectReferenceRedirect ? "disabled" : "enabled"}` + ` and a decl map is ${dtsMapPresent ? "present" : "missing"}`; - const compilerOptions: CompilerOptions = { + const compilerOptions: ts.CompilerOptions = { disableReferencedProjectLoad, disableSourceOfProjectReferenceRedirect, composite: true }; it(subScenario, () => { - const configA: File = { - path: `${tscWatch.projectRoot}/a/tsconfig.json`, + const configA: ts.projectSystem.File = { + path: `${ts.tscWatch.projectRoot}/a/tsconfig.json`, content: `{ "compilerOptions": ${JSON.stringify(compilerOptions)}, "references": [{ "path": "../b" }] }` }; - const host = createServerHost([configA, indexA, configB, indexB, helperB, dtsB, ...(dtsMapPresent ? [dtsMapB] : [])]); - const session = createSession(host, { logger: createLoggerWithInMemoryLogs() }); - openFilesForSession([indexA, ...(projectAlreadyLoaded ? [helperB] : [])], session); - - session.executeCommandSeq({ - command: protocol.CommandTypes.References, - arguments: protocolFileLocationFromSubstring(indexA, `B`, { index: 1 }) + const host = ts.projectSystem.createServerHost([configA, indexA, configB, indexB, helperB, dtsB, ...(dtsMapPresent ? [dtsMapB] : [])]); + const session = ts.projectSystem.createSession(host, { logger: ts.projectSystem.createLoggerWithInMemoryLogs() }); + ts.projectSystem.openFilesForSession([indexA, ...(projectAlreadyLoaded ? [helperB] : [])], session); + session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.References, + arguments: ts.projectSystem.protocolFileLocationFromSubstring(indexA, `B`, { index: 1 }) }); - baselineTsserverLogs("projectReferences", `find refs to decl in other proj ${subScenario}`, session); + ts.projectSystem.baselineTsserverLogs("projectReferences", `find refs to decl in other proj ${subScenario}`, session); }); } diff --git a/src/testRunner/unittests/tsserver/projectReferencesSourcemap.ts b/src/testRunner/unittests/tsserver/projectReferencesSourcemap.ts index e49522f7dc96b..9cbf4915fc13b 100644 --- a/src/testRunner/unittests/tsserver/projectReferencesSourcemap.ts +++ b/src/testRunner/unittests/tsserver/projectReferencesSourcemap.ts @@ -1,9 +1,9 @@ namespace ts.projectSystem { describe("unittests:: tsserver:: with project references and tsbuild source map", () => { - const dependecyLocation = `${tscWatch.projectRoot}/dependency`; - const dependecyDeclsLocation = `${tscWatch.projectRoot}/decls`; - const mainLocation = `${tscWatch.projectRoot}/main`; - const dependencyTs: File = { + const dependecyLocation = `${ts.tscWatch.projectRoot}/dependency`; + const dependecyDeclsLocation = `${ts.tscWatch.projectRoot}/decls`; + const mainLocation = `${ts.tscWatch.projectRoot}/main`; + const dependencyTs: ts.projectSystem.File = { path: `${dependecyLocation}/FnS.ts`, content: `export function fn1() { } export function fn2() { } @@ -13,12 +13,12 @@ export function fn5() { } ` }; const dependencyTsPath = dependencyTs.path.toLowerCase(); - const dependencyConfig: File = { + const dependencyConfig: ts.projectSystem.File = { path: `${dependecyLocation}/tsconfig.json`, content: JSON.stringify({ compilerOptions: { composite: true, declarationMap: true, declarationDir: "../decls" } }) }; - const mainTs: File = { + const mainTs: ts.projectSystem.File = { path: `${mainLocation}/main.ts`, content: `import { fn1, @@ -35,7 +35,7 @@ fn4(); fn5(); ` }; - const mainConfig: File = { + const mainConfig: ts.projectSystem.File = { path: `${mainLocation}/tsconfig.json`, content: JSON.stringify({ compilerOptions: { composite: true, declarationMap: true }, @@ -43,49 +43,38 @@ fn5(); }) }; - const randomFile: File = { - path: `${tscWatch.projectRoot}/random/random.ts`, + const randomFile: ts.projectSystem.File = { + path: `${ts.tscWatch.projectRoot}/random/random.ts`, content: "let a = 10;" }; - const randomConfig: File = { - path: `${tscWatch.projectRoot}/random/tsconfig.json`, + const randomConfig: ts.projectSystem.File = { + path: `${ts.tscWatch.projectRoot}/random/tsconfig.json`, content: "{}" }; const dtsLocation = `${dependecyDeclsLocation}/FnS.d.ts`; - const dtsPath = dtsLocation.toLowerCase() as Path; + const dtsPath = dtsLocation.toLowerCase() as ts.Path; const dtsMapLocation = `${dependecyDeclsLocation}/FnS.d.ts.map`; - const dtsMapPath = dtsMapLocation.toLowerCase() as Path; - - const files = [dependencyTs, dependencyConfig, mainTs, mainConfig, libFile, randomFile, randomConfig]; - - function changeDtsFile(host: TestServerHost) { - host.writeFile( - dtsLocation, - host.readFile(dtsLocation)!.replace( - "//# sourceMappingURL=FnS.d.ts.map", - `export declare function fn6(): void; -//# sourceMappingURL=FnS.d.ts.map` - ) - ); + const dtsMapPath = dtsMapLocation.toLowerCase() as ts.Path; + const files = [dependencyTs, dependencyConfig, mainTs, mainConfig, ts.projectSystem.libFile, randomFile, randomConfig]; + function changeDtsFile(host: ts.projectSystem.TestServerHost) { + host.writeFile(dtsLocation, host.readFile(dtsLocation)!.replace("//# sourceMappingURL=FnS.d.ts.map", `export declare function fn6(): void; +//# sourceMappingURL=FnS.d.ts.map`)); } - function changeDtsMapFile(host: TestServerHost) { - host.writeFile( - dtsMapLocation, - `{"version":3,"file":"FnS.d.ts","sourceRoot":"","sources":["../dependency/FnS.ts"],"names":[],"mappings":"AAAA,wBAAgB,GAAG,SAAM;AACzB,wBAAgB,GAAG,SAAM;AACzB,wBAAgB,GAAG,SAAM;AACzB,wBAAgB,GAAG,SAAM;AACzB,wBAAgB,GAAG,SAAM;AACzB,eAAO,MAAM,CAAC,KAAK,CAAC"}` - ); + function changeDtsMapFile(host: ts.projectSystem.TestServerHost) { + host.writeFile(dtsMapLocation, `{"version":3,"file":"FnS.d.ts","sourceRoot":"","sources":["../dependency/FnS.ts"],"names":[],"mappings":"AAAA,wBAAgB,GAAG,SAAM;AACzB,wBAAgB,GAAG,SAAM;AACzB,wBAAgB,GAAG,SAAM;AACzB,wBAAgB,GAAG,SAAM;AACzB,wBAAgB,GAAG,SAAM;AACzB,eAAO,MAAM,CAAC,KAAK,CAAC"}`); } - function verifyScriptInfos(session: TestSession, host: TestServerHost, openInfos: readonly string[], closedInfos: readonly string[], otherWatchedFiles: readonly string[], additionalInfo?: string) { - checkScriptInfos(session.getProjectService(), openInfos.concat(closedInfos), additionalInfo); - checkWatchedFiles(host, closedInfos.concat(otherWatchedFiles).map(f => f.toLowerCase()), additionalInfo); + function verifyScriptInfos(session: ts.projectSystem.TestSession, host: ts.projectSystem.TestServerHost, openInfos: readonly string[], closedInfos: readonly string[], otherWatchedFiles: readonly string[], additionalInfo?: string) { + ts.projectSystem.checkScriptInfos(session.getProjectService(), openInfos.concat(closedInfos), additionalInfo); + ts.projectSystem.checkWatchedFiles(host, closedInfos.concat(otherWatchedFiles).map(f => f.toLowerCase()), additionalInfo); } - function verifyOnlyRandomInfos(session: TestSession, host: TestServerHost) { - verifyScriptInfos(session, host, [randomFile.path], [libFile.path], [randomConfig.path], "Random"); + function verifyOnlyRandomInfos(session: ts.projectSystem.TestSession, host: ts.projectSystem.TestServerHost) { + verifyScriptInfos(session, host, [randomFile.path], [ts.projectSystem.libFile.path], [randomConfig.path], "Random"); } - function declarationSpan(fn: number): protocol.TextSpanWithContext { + function declarationSpan(fn: number): ts.projectSystem.protocol.TextSpanWithContext { return { start: { line: fn, offset: 17 }, end: { line: fn, offset: 20 }, @@ -93,7 +82,7 @@ fn5(); contextEnd: { line: fn, offset: 26 } }; } - function importSpan(fn: number): protocol.TextSpanWithContext { + function importSpan(fn: number): ts.projectSystem.protocol.TextSpanWithContext { return { start: { line: fn + 1, offset: 5 }, end: { line: fn + 1, offset: 8 }, @@ -101,17 +90,17 @@ fn5(); contextEnd: { line: 7, offset: 22 } }; } - function usageSpan(fn: number): protocol.TextSpan { + function usageSpan(fn: number): ts.projectSystem.protocol.TextSpan { return { start: { line: fn + 8, offset: 1 }, end: { line: fn + 8, offset: 4 } }; } - function goToDefFromMainTs(fn: number): Action { + function goToDefFromMainTs(fn: number): Action { const textSpan = usageSpan(fn); - const definition: protocol.FileSpan = { file: dependencyTs.path, ...declarationSpan(fn) }; + const definition: ts.projectSystem.protocol.FileSpan = { file: dependencyTs.path, ...declarationSpan(fn) }; return { reqName: "goToDef", request: { - command: protocol.CommandTypes.DefinitionAndBoundSpan, + command: ts.projectSystem.protocol.CommandTypes.DefinitionAndBoundSpan, arguments: { file: mainTs.path, ...textSpan.start } }, expectedResponse: { @@ -122,14 +111,14 @@ fn5(); }; } - function goToDefFromMainTsWithNoMap(fn: number): Action { + function goToDefFromMainTsWithNoMap(fn: number): Action { const textSpan = usageSpan(fn); const definition = declarationSpan(fn); const declareSpaceLength = "declare ".length; return { reqName: "goToDef", request: { - command: protocol.CommandTypes.DefinitionAndBoundSpan, + command: ts.projectSystem.protocol.CommandTypes.DefinitionAndBoundSpan, arguments: { file: mainTs.path, ...textSpan.start } }, expectedResponse: { @@ -146,12 +135,12 @@ fn5(); }; } - function goToDefFromMainTsWithNoDts(fn: number): Action { + function goToDefFromMainTsWithNoDts(fn: number): Action { const textSpan = usageSpan(fn); return { reqName: "goToDef", request: { - command: protocol.CommandTypes.DefinitionAndBoundSpan, + command: ts.projectSystem.protocol.CommandTypes.DefinitionAndBoundSpan, arguments: { file: mainTs.path, ...textSpan.start } }, expectedResponse: { @@ -162,12 +151,12 @@ fn5(); }; } - function goToDefFromMainTsWithDependencyChange(fn: number): Action { + function goToDefFromMainTsWithDependencyChange(fn: number): Action { const textSpan = usageSpan(fn); return { reqName: "goToDef", request: { - command: protocol.CommandTypes.DefinitionAndBoundSpan, + command: ts.projectSystem.protocol.CommandTypes.DefinitionAndBoundSpan, arguments: { file: mainTs.path, ...textSpan.start } }, expectedResponse: { @@ -178,13 +167,13 @@ fn5(); }; } - function renameFromDependencyTs(fn: number): Action { + function renameFromDependencyTs(fn: number): Action { const defSpan = declarationSpan(fn); const { contextStart: _, contextEnd: _1, ...triggerSpan } = defSpan; return { reqName: "rename", request: { - command: protocol.CommandTypes.Rename, + command: ts.projectSystem.protocol.CommandTypes.Rename, arguments: { file: dependencyTs.path, ...triggerSpan.start } }, expectedResponse: { @@ -193,7 +182,7 @@ fn5(); fileToRename: undefined, displayName: `fn${fn}`, fullDisplayName: `"${dependecyLocation}/FnS".fn${fn}`, - kind: ScriptElementKind.functionElement, + kind: ts.ScriptElementKind.functionElement, kindModifiers: "export", triggerSpan }, @@ -204,14 +193,14 @@ fn5(); }; } - function renameFromDependencyTsWithDependencyChange(fn: number): Action { + function renameFromDependencyTsWithDependencyChange(fn: number): Action { const { expectedResponse: { info, locs }, ...rest } = renameFromDependencyTs(fn + 1); return { ...rest, expectedResponse: { info: { - ...info as protocol.RenameInfoSuccess, + ...info as ts.projectSystem.protocol.RenameInfoSuccess, displayName: `fn${fn}`, fullDisplayName: `"${dependecyLocation}/FnS".fn${fn}`, }, @@ -220,7 +209,7 @@ fn5(); }; } - function renameFromDependencyTsWithBothProjectsOpen(fn: number): Action { + function renameFromDependencyTsWithBothProjectsOpen(fn: number): Action { const { reqName, request, expectedResponse } = renameFromDependencyTs(fn); const { info, locs } = expectedResponse; return { @@ -242,7 +231,7 @@ fn5(); }; } - function renameFromDependencyTsWithBothProjectsOpenWithDependencyChange(fn: number): Action { + function renameFromDependencyTsWithBothProjectsOpenWithDependencyChange(fn: number): Action { const { reqName, request, expectedResponse, } = renameFromDependencyTsWithDependencyChange(fn); const { info, locs } = expectedResponse; return { @@ -271,36 +260,25 @@ fn5(); }); } - interface Action { + interface Action { reqName: string; request: Partial; expectedResponse: Response; } - function verifyAction(session: TestSession, { reqName, request, expectedResponse }: Action) { + function verifyAction(session: ts.projectSystem.TestSession, { reqName, request, expectedResponse }: Action) { const { response } = session.executeCommandSeq(request); assert.deepEqual(response, expectedResponse, `Failed Request: ${reqName}`); } - function verifyDocumentPositionMapper( - session: TestSession, - dependencyMap: server.ScriptInfo | undefined, - documentPositionMapper: server.ScriptInfo["documentPositionMapper"], - equal: boolean, - debugInfo?: string, - ) { + function verifyDocumentPositionMapper(session: ts.projectSystem.TestSession, dependencyMap: ts.server.ScriptInfo | undefined, documentPositionMapper: ts.server.ScriptInfo["documentPositionMapper"], equal: boolean, debugInfo?: string) { assert.strictEqual(session.getProjectService().filenameToScriptInfo.get(dtsMapPath), dependencyMap, `${debugInfo} dependencyMap`); if (dependencyMap) { verifyEquality(dependencyMap.documentPositionMapper, documentPositionMapper, equal, `${debugInfo} DocumentPositionMapper`); } } - function verifyDocumentPositionMapperEqual( - session: TestSession, - dependencyMap: server.ScriptInfo | undefined, - documentPositionMapper: server.ScriptInfo["documentPositionMapper"], - debugInfo?: string, - ) { + function verifyDocumentPositionMapperEqual(session: ts.projectSystem.TestSession, dependencyMap: ts.server.ScriptInfo | undefined, documentPositionMapper: ts.server.ScriptInfo["documentPositionMapper"], debugInfo?: string) { verifyDocumentPositionMapper(session, dependencyMap, documentPositionMapper, /*equal*/ true, debugInfo); } @@ -313,27 +291,16 @@ fn5(); } } - function verifyAllFnAction( - session: TestSession, - host: TestServerHost, - action: (fn: number) => Action, - expectedInfos: readonly string[], - expectedWatchedFiles: readonly string[], - existingDependencyMap: server.ScriptInfo | undefined, - existingDocumentPositionMapper: server.ScriptInfo["documentPositionMapper"], - existingMapEqual: boolean, - existingDocumentPositionMapperEqual: boolean, - skipMapPathInDtsInfo?: boolean - ) { - let sourceMapPath: server.ScriptInfo["sourceMapFilePath"] | undefined; - let dependencyMap: server.ScriptInfo | undefined; - let documentPositionMapper: server.ScriptInfo["documentPositionMapper"]; + function verifyAllFnAction(session: ts.projectSystem.TestSession, host: ts.projectSystem.TestServerHost, action: (fn: number) => Action, expectedInfos: readonly string[], expectedWatchedFiles: readonly string[], existingDependencyMap: ts.server.ScriptInfo | undefined, existingDocumentPositionMapper: ts.server.ScriptInfo["documentPositionMapper"], existingMapEqual: boolean, existingDocumentPositionMapperEqual: boolean, skipMapPathInDtsInfo?: boolean) { + let sourceMapPath: ts.server.ScriptInfo["sourceMapFilePath"] | undefined; + let dependencyMap: ts.server.ScriptInfo | undefined; + let documentPositionMapper: ts.server.ScriptInfo["documentPositionMapper"]; for (let fn = 1; fn <= 5; fn++) { const fnAction = action(fn); verifyAction(session, fnAction); const debugInfo = `${fnAction.reqName}:: ${fn}`; - checkScriptInfos(session.getProjectService(), expectedInfos, debugInfo); - checkWatchedFiles(host, expectedWatchedFiles, debugInfo); + ts.projectSystem.checkScriptInfos(session.getProjectService(), expectedInfos, debugInfo); + ts.projectSystem.checkWatchedFiles(host, expectedWatchedFiles, debugInfo); const dtsInfo = session.getProjectService().getScriptInfoForPath(dtsPath); const dtsMapInfo = session.getProjectService().getScriptInfoForPath(dtsMapPath); @@ -363,37 +330,33 @@ fn5(); } } - function verifyScriptInfoCollectionWith( - session: TestSession, - host: TestServerHost, - openFiles: readonly File[], - expectedInfos: readonly string[], - expectedWatchedFiles: readonly string[], - ) { + function verifyScriptInfoCollectionWith(session: ts.projectSystem.TestSession, host: ts.projectSystem.TestServerHost, openFiles: readonly ts.projectSystem.File[], expectedInfos: readonly string[], expectedWatchedFiles: readonly string[]) { const { dependencyMap, documentPositionMapper } = getDocumentPositionMapper(session); // Collecting at this point retains dependency.d.ts and map - closeFilesForSession([randomFile], session); - openFilesForSession([randomFile], session); - - checkScriptInfos(session.getProjectService(), expectedInfos); - checkWatchedFiles(host, expectedWatchedFiles); + ts.projectSystem.closeFilesForSession([randomFile], session); + ts.projectSystem.openFilesForSession([randomFile], session); + ts.projectSystem.checkScriptInfos(session.getProjectService(), expectedInfos); + ts.projectSystem.checkWatchedFiles(host, expectedWatchedFiles); // If map is not collected, document position mapper shouldnt change if (session.getProjectService().filenameToScriptInfo.has(dtsMapPath)) { verifyDocumentPositionMapperEqual(session, dependencyMap, documentPositionMapper); } // Closing open file, removes dependencies too - closeFilesForSession([...openFiles, randomFile], session); - openFilesForSession([randomFile], session); + ts.projectSystem.closeFilesForSession([...openFiles, randomFile], session); + ts.projectSystem.openFilesForSession([randomFile], session); verifyOnlyRandomInfos(session, host); } - type OnHostCreate = (host: TestServerHost) => void; - type CreateSessionFn = (onHostCreate?: OnHostCreate) => { host: TestServerHost; session: TestSession; }; - function setupWith(createSession: CreateSessionFn, openFiles: readonly File[], onHostCreate: OnHostCreate | undefined) { + type OnHostCreate = (host: ts.projectSystem.TestServerHost) => void; + type CreateSessionFn = (onHostCreate?: OnHostCreate) => { + host: ts.projectSystem.TestServerHost; + session: ts.projectSystem.TestSession; + }; + function setupWith(createSession: CreateSessionFn, openFiles: readonly ts.projectSystem.File[], onHostCreate: OnHostCreate | undefined) { const result = createSession(onHostCreate); - openFilesForSession(openFiles, result.session); + ts.projectSystem.openFilesForSession(openFiles, result.session); return result; } @@ -410,25 +373,25 @@ fn5(); } function createSessionWithoutProjectReferences(onHostCreate?: OnHostCreate) { - const host = createHostWithSolutionBuild(files, [mainConfig.path]); + const host = ts.projectSystem.createHostWithSolutionBuild(files, [mainConfig.path]); // Erase project reference host.writeFile(mainConfig.path, JSON.stringify({ compilerOptions: { composite: true, declarationMap: true } })); onHostCreate?.(host); - const session = createSession(host); + const session = ts.projectSystem.createSession(host); return { host, session }; } function createSessionWithProjectReferences(onHostCreate?: OnHostCreate) { - const host = createHostWithSolutionBuild(files, [mainConfig.path]); + const host = ts.projectSystem.createHostWithSolutionBuild(files, [mainConfig.path]); onHostCreate?.(host); - const session = createSession(host); + const session = ts.projectSystem.createSession(host); return { host, session }; } function createSessionWithDisabledProjectReferences(onHostCreate?: OnHostCreate) { - const host = createHostWithSolutionBuild(files, [mainConfig.path]); + const host = ts.projectSystem.createHostWithSolutionBuild(files, [mainConfig.path]); // Erase project reference host.writeFile(mainConfig.path, JSON.stringify({ compilerOptions: { @@ -439,43 +402,43 @@ fn5(); references: [{ path: "../dependency" }] })); onHostCreate?.(host); - const session = createSession(host); + const session = ts.projectSystem.createSession(host); return { host, session }; } - function getDocumentPositionMapper(session: TestSession) { + function getDocumentPositionMapper(session: ts.projectSystem.TestSession) { const dependencyMap = session.getProjectService().filenameToScriptInfo.get(dtsMapPath); const documentPositionMapper = dependencyMap?.documentPositionMapper; return { dependencyMap, documentPositionMapper }; } - function checkMainProjectWithoutProjectReferences(session: TestSession) { - checkProjectActualFiles(session.getProjectService().configuredProjects.get(mainConfig.path)!, [mainTs.path, libFile.path, mainConfig.path, dtsPath]); + function checkMainProjectWithoutProjectReferences(session: ts.projectSystem.TestSession) { + ts.projectSystem.checkProjectActualFiles(session.getProjectService().configuredProjects.get(mainConfig.path)!, [mainTs.path, ts.projectSystem.libFile.path, mainConfig.path, dtsPath]); } - function checkMainProjectWithoutProjectReferencesWithoutDts(session: TestSession) { - checkProjectActualFiles(session.getProjectService().configuredProjects.get(mainConfig.path)!, [mainTs.path, libFile.path, mainConfig.path]); + function checkMainProjectWithoutProjectReferencesWithoutDts(session: ts.projectSystem.TestSession) { + ts.projectSystem.checkProjectActualFiles(session.getProjectService().configuredProjects.get(mainConfig.path)!, [mainTs.path, ts.projectSystem.libFile.path, mainConfig.path]); } - function checkMainProjectWithProjectReferences(session: TestSession) { - checkProjectActualFiles(session.getProjectService().configuredProjects.get(mainConfig.path)!, [mainTs.path, libFile.path, mainConfig.path, dependencyTs.path]); + function checkMainProjectWithProjectReferences(session: ts.projectSystem.TestSession) { + ts.projectSystem.checkProjectActualFiles(session.getProjectService().configuredProjects.get(mainConfig.path)!, [mainTs.path, ts.projectSystem.libFile.path, mainConfig.path, dependencyTs.path]); } - function checkMainProjectWithDisabledProjectReferences(session: TestSession) { - checkProjectActualFiles(session.getProjectService().configuredProjects.get(mainConfig.path)!, [mainTs.path, libFile.path, mainConfig.path, dtsPath]); + function checkMainProjectWithDisabledProjectReferences(session: ts.projectSystem.TestSession) { + ts.projectSystem.checkProjectActualFiles(session.getProjectService().configuredProjects.get(mainConfig.path)!, [mainTs.path, ts.projectSystem.libFile.path, mainConfig.path, dtsPath]); } - function checkMainProjectWithDisabledProjectReferencesWithoutDts(session: TestSession) { - checkProjectActualFiles(session.getProjectService().configuredProjects.get(mainConfig.path)!, [mainTs.path, libFile.path, mainConfig.path]); + function checkMainProjectWithDisabledProjectReferencesWithoutDts(session: ts.projectSystem.TestSession) { + ts.projectSystem.checkProjectActualFiles(session.getProjectService().configuredProjects.get(mainConfig.path)!, [mainTs.path, ts.projectSystem.libFile.path, mainConfig.path]); } - function checkDependencyProjectWith(session: TestSession) { - checkProjectActualFiles(session.getProjectService().configuredProjects.get(dependencyConfig.path)!, [dependencyTs.path, libFile.path, dependencyConfig.path]); + function checkDependencyProjectWith(session: ts.projectSystem.TestSession) { + ts.projectSystem.checkProjectActualFiles(session.getProjectService().configuredProjects.get(dependencyConfig.path)!, [dependencyTs.path, ts.projectSystem.libFile.path, dependencyConfig.path]); } - function makeChangeToMainTs(session: TestSession) { - session.executeCommandSeq({ - command: protocol.CommandTypes.Change, + function makeChangeToMainTs(session: ts.projectSystem.TestSession) { + session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.Change, arguments: { file: mainTs.path, line: 14, @@ -487,9 +450,9 @@ fn5(); }); } - function makeChangeToDependencyTs(session: TestSession) { - session.executeCommandSeq({ - command: protocol.CommandTypes.Change, + function makeChangeToDependencyTs(session: ts.projectSystem.TestSession) { + session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.Change, arguments: { file: dependencyTs.path, line: 6, @@ -508,12 +471,7 @@ fn5(); return { ...result, ...getDocumentPositionMapper(result.session) }; } - function verifyScriptInfoCollection( - session: TestSession, - host: TestServerHost, - expectedInfos: readonly string[], - expectedWatchedFiles: readonly string[], - ) { + function verifyScriptInfoCollection(session: ts.projectSystem.TestSession, host: ts.projectSystem.TestServerHost, expectedInfos: readonly string[], expectedWatchedFiles: readonly string[]) { return verifyScriptInfoCollectionWith(session, host, [mainTs], expectedInfos, expectedWatchedFiles); } @@ -526,22 +484,22 @@ fn5(); return setupWithActionWith(setup, onHostCreate); } - function checkProjects(session: TestSession) { - checkNumberOfProjects(session.getProjectService(), { configuredProjects: 2 }); + function checkProjects(session: ts.projectSystem.TestSession) { + ts.projectSystem.checkNumberOfProjects(session.getProjectService(), { configuredProjects: 2 }); checkMainProjectWithoutProjectReferences(session); } - function checkProjectsWithoutDts(session: TestSession) { - checkNumberOfProjects(session.getProjectService(), { configuredProjects: 2 }); + function checkProjectsWithoutDts(session: ts.projectSystem.TestSession) { + ts.projectSystem.checkNumberOfProjects(session.getProjectService(), { configuredProjects: 2 }); checkMainProjectWithoutProjectReferencesWithoutDts(session); } function expectedScriptInfosWhenMapped() { - return [mainTs.path, randomFile.path, dependencyTs.path, libFile.path, dtsPath, dtsMapLocation]; + return [mainTs.path, randomFile.path, dependencyTs.path, ts.projectSystem.libFile.path, dtsPath, dtsMapLocation]; } function expectedWatchedFilesWhenMapped() { - return [dependencyTsPath, libFile.path, dtsPath, dtsMapPath, mainConfig.path, randomConfig.path]; + return [dependencyTsPath, ts.projectSystem.libFile.path, dtsPath, dtsMapPath, mainConfig.path, randomConfig.path]; } function expectedScriptInfosWhenNoMap() { @@ -566,24 +524,13 @@ fn5(); it("can go to definition correctly", () => { const { host, session } = setup(); checkProjects(session); - verifyAllFnAction( - session, - host, - goToDefFromMainTs, - expectedScriptInfosWhenMapped(), - expectedWatchedFilesWhenMapped(), + verifyAllFnAction(session, host, goToDefFromMainTs, expectedScriptInfosWhenMapped(), expectedWatchedFilesWhenMapped(), /*existingDependencyMap*/ undefined, /*existingDocumentPositionMapper*/ undefined, /*existingMapEqual*/ false, - /*existingDocumentPositionMapperEqual*/ false - ); + /*existingDocumentPositionMapperEqual*/ false); checkProjects(session); - verifyScriptInfoCollection( - session, - host, - expectedScriptInfosWhenMapped(), - expectedWatchedFilesWhenMapped(), - ); + verifyScriptInfoCollection(session, host, expectedScriptInfosWhenMapped(), expectedWatchedFilesWhenMapped()); }); // Edit @@ -598,17 +545,9 @@ fn5(); verifyDocumentPositionMapperEqual(session, dependencyMap, documentPositionMapper); // action - verifyAllFnAction( - session, - host, - goToDefFromMainTs, - expectedScriptInfosWhenMapped(), - expectedWatchedFilesWhenMapped(), - dependencyMap, - documentPositionMapper, - /*existingMapEqual*/ true, - /*existingDocumentPositionMapperEqual*/ true - ); + verifyAllFnAction(session, host, goToDefFromMainTs, expectedScriptInfosWhenMapped(), expectedWatchedFilesWhenMapped(), dependencyMap, documentPositionMapper, + /*existingMapEqual*/ true, + /*existingDocumentPositionMapperEqual*/ true); }); it(`when usage file changes, document position mapper doesnt change, when timeout does not occur before request`, () => { // Create DocumentPositionMapper @@ -618,17 +557,9 @@ fn5(); makeChangeToMainTs(session); // action - verifyAllFnAction( - session, - host, - goToDefFromMainTs, - expectedScriptInfosWhenMapped(), - expectedWatchedFilesWhenMapped(), - dependencyMap, - documentPositionMapper, - /*existingMapEqual*/ true, - /*existingDocumentPositionMapperEqual*/ true - ); + verifyAllFnAction(session, host, goToDefFromMainTs, expectedScriptInfosWhenMapped(), expectedWatchedFilesWhenMapped(), dependencyMap, documentPositionMapper, + /*existingMapEqual*/ true, + /*existingDocumentPositionMapperEqual*/ true); }); // Edit dts to add new fn @@ -643,17 +574,9 @@ fn5(); verifyDocumentPositionMapperEqual(session, dependencyMap, documentPositionMapper); // action - verifyAllFnAction( - session, - host, - goToDefFromMainTs, - expectedScriptInfosWhenMapped(), - expectedWatchedFilesWhenMapped(), - dependencyMap, - documentPositionMapper, - /*existingMapEqual*/ true, - /*existingDocumentPositionMapperEqual*/ true - ); + verifyAllFnAction(session, host, goToDefFromMainTs, expectedScriptInfosWhenMapped(), expectedWatchedFilesWhenMapped(), dependencyMap, documentPositionMapper, + /*existingMapEqual*/ true, + /*existingDocumentPositionMapperEqual*/ true); }); it(`when dependency .d.ts changes, document position mapper doesnt change, when timeout does not occur before request`, () => { // Create DocumentPositionMapper @@ -663,17 +586,9 @@ fn5(); changeDtsFile(host); // action - verifyAllFnAction( - session, - host, - goToDefFromMainTs, - expectedScriptInfosWhenMapped(), - expectedWatchedFilesWhenMapped(), - dependencyMap, - documentPositionMapper, - /*existingMapEqual*/ true, - /*existingDocumentPositionMapperEqual*/ true - ); + verifyAllFnAction(session, host, goToDefFromMainTs, expectedScriptInfosWhenMapped(), expectedWatchedFilesWhenMapped(), dependencyMap, documentPositionMapper, + /*existingMapEqual*/ true, + /*existingDocumentPositionMapperEqual*/ true); }); // Edit map file to represent added new line @@ -688,17 +603,9 @@ fn5(); verifyDocumentPositionMapperEqual(session, dependencyMap, documentPositionMapper); // action - verifyAllFnAction( - session, - host, - goToDefFromMainTs, - expectedScriptInfosWhenMapped(), - expectedWatchedFilesWhenMapped(), - dependencyMap, - documentPositionMapper, - /*existingMapEqual*/ true, - /*existingDocumentPositionMapperEqual*/ false - ); + verifyAllFnAction(session, host, goToDefFromMainTs, expectedScriptInfosWhenMapped(), expectedWatchedFilesWhenMapped(), dependencyMap, documentPositionMapper, + /*existingMapEqual*/ true, + /*existingDocumentPositionMapperEqual*/ false); }); it(`when dependency file's map changes, when timeout does not occur before request`, () => { // Create DocumentPositionMapper @@ -708,41 +615,22 @@ fn5(); changeDtsMapFile(host); // action - verifyAllFnAction( - session, - host, - goToDefFromMainTs, - expectedScriptInfosWhenMapped(), - expectedWatchedFilesWhenMapped(), - dependencyMap, - documentPositionMapper, - /*existingMapEqual*/ true, - /*existingDocumentPositionMapperEqual*/ false - ); + verifyAllFnAction(session, host, goToDefFromMainTs, expectedScriptInfosWhenMapped(), expectedWatchedFilesWhenMapped(), dependencyMap, documentPositionMapper, + /*existingMapEqual*/ true, + /*existingDocumentPositionMapperEqual*/ false); }); it(`with depedency files map file, when file is not present`, () => { const { host, session } = setup(host => host.deleteFile(dtsMapLocation)); checkProjects(session); - verifyAllFnAction( - session, - host, - goToDefFromMainTsWithNoMap, - expectedScriptInfosWhenNoMap(), - expectedWatchedFilesWhenNoMap(), + verifyAllFnAction(session, host, goToDefFromMainTsWithNoMap, expectedScriptInfosWhenNoMap(), expectedWatchedFilesWhenNoMap(), /*existingDependencyMap*/ undefined, /*existingDocumentPositionMapper*/ undefined, /*existingMapEqual*/ true, - /*existingDocumentPositionMapperEqual*/ true - ); + /*existingDocumentPositionMapperEqual*/ true); checkProjects(session); - verifyScriptInfoCollection( - session, - host, - expectedScriptInfosWhenNoMap(), - expectedWatchedFilesWhenNoMap(), - ); + verifyScriptInfoCollection(session, host, expectedScriptInfosWhenNoMap(), expectedWatchedFilesWhenNoMap()); }); it(`with depedency files map file, when file is created after actions on projects`, () => { let fileContents: string; @@ -752,75 +640,39 @@ fn5(); }); host.writeFile(dtsMapLocation, fileContents!); - verifyAllFnAction( - session, - host, - goToDefFromMainTs, - expectedScriptInfosWhenMapped(), - expectedWatchedFilesWhenMapped(), - dependencyMap, - documentPositionMapper, + verifyAllFnAction(session, host, goToDefFromMainTs, expectedScriptInfosWhenMapped(), expectedWatchedFilesWhenMapped(), dependencyMap, documentPositionMapper, /*existingMapEqual*/ false, - /*existingDocumentPositionMapperEqual*/ false - ); + /*existingDocumentPositionMapperEqual*/ false); checkProjects(session); - verifyScriptInfoCollection( - session, - host, - expectedScriptInfosWhenMapped(), - expectedWatchedFilesWhenMapped() - ); + verifyScriptInfoCollection(session, host, expectedScriptInfosWhenMapped(), expectedWatchedFilesWhenMapped()); }); it(`with depedency files map file, when file is deleted after actions on the projects`, () => { const { host, session, dependencyMap, documentPositionMapper } = setupWithAction(); // The dependency file is deleted when orphan files are collected host.deleteFile(dtsMapLocation); - verifyAllFnAction( - session, - host, - goToDefFromMainTsWithNoMap, + verifyAllFnAction(session, host, goToDefFromMainTsWithNoMap, // The script info for map is collected only after file open - expectedScriptInfosWhenNoMap().concat(dependencyTs.path), - expectedWatchedFilesWhenNoMap().concat(dependencyTsPath), - dependencyMap, - documentPositionMapper, + expectedScriptInfosWhenNoMap().concat(dependencyTs.path), expectedWatchedFilesWhenNoMap().concat(dependencyTsPath), dependencyMap, documentPositionMapper, /*existingMapEqual*/ false, - /*existingDocumentPositionMapperEqual*/ false - ); + /*existingDocumentPositionMapperEqual*/ false); checkProjects(session); // Script info collection should behave as fileNotPresentKey - verifyScriptInfoCollection( - session, - host, - expectedScriptInfosWhenNoMap(), - expectedWatchedFilesWhenNoMap(), - ); + verifyScriptInfoCollection(session, host, expectedScriptInfosWhenNoMap(), expectedWatchedFilesWhenNoMap()); }); it(`with depedency .d.ts file, when file is not present`, () => { const { host, session } = setup(host => host.deleteFile(dtsLocation)); checkProjectsWithoutDts(session); - verifyAllFnAction( - session, - host, - goToDefFromMainTsWithNoDts, - expectedScriptInfosWhenNoDts(), - expectedWatchedFilesWhenNoDts(), + verifyAllFnAction(session, host, goToDefFromMainTsWithNoDts, expectedScriptInfosWhenNoDts(), expectedWatchedFilesWhenNoDts(), /*existingDependencyMap*/ undefined, /*existingDocumentPositionMapper*/ undefined, /*existingMapEqual*/ true, - /*existingDocumentPositionMapperEqual*/ true - ); + /*existingDocumentPositionMapperEqual*/ true); checkProjectsWithoutDts(session); - verifyScriptInfoCollection( - session, - host, - expectedScriptInfosWhenNoDts(), - expectedWatchedFilesWhenNoDts(), - ); + verifyScriptInfoCollection(session, host, expectedScriptInfosWhenNoDts(), expectedWatchedFilesWhenNoDts()); }); it(`with depedency .d.ts file, when file is created after actions on projects`, () => { let fileContents: string; @@ -830,51 +682,26 @@ fn5(); }); host.writeFile(dtsLocation, fileContents!); - verifyAllFnAction( - session, - host, - goToDefFromMainTs, - expectedScriptInfosWhenMapped(), - expectedWatchedFilesWhenMapped(), - dependencyMap, - documentPositionMapper, + verifyAllFnAction(session, host, goToDefFromMainTs, expectedScriptInfosWhenMapped(), expectedWatchedFilesWhenMapped(), dependencyMap, documentPositionMapper, /*existingMapEqual*/ false, - /*existingDocumentPositionMapperEqual*/ false - ); + /*existingDocumentPositionMapperEqual*/ false); checkProjects(session); - verifyScriptInfoCollection( - session, - host, - expectedScriptInfosWhenMapped(), - expectedWatchedFilesWhenMapped() - ); + verifyScriptInfoCollection(session, host, expectedScriptInfosWhenMapped(), expectedWatchedFilesWhenMapped()); }); it(`with depedency .d.ts file, when file is deleted after actions on the projects`, () => { const { host, session, dependencyMap, documentPositionMapper } = setupWithAction(); // The dependency file is deleted when orphan files are collected host.deleteFile(dtsLocation); - verifyAllFnAction( - session, - host, - goToDefFromMainTsWithNoDts, + verifyAllFnAction(session, host, goToDefFromMainTsWithNoDts, // The script info for map is collected only after file open - expectedScriptInfosWhenNoDts().concat(dependencyTs.path, dtsMapLocation), - expectedWatchedFilesWhenNoDts().concat(dependencyTsPath, dtsMapPath), - dependencyMap, - documentPositionMapper, + expectedScriptInfosWhenNoDts().concat(dependencyTs.path, dtsMapLocation), expectedWatchedFilesWhenNoDts().concat(dependencyTsPath, dtsMapPath), dependencyMap, documentPositionMapper, /*existingMapEqual*/ true, - /*existingDocumentPositionMapperEqual*/ true - ); + /*existingDocumentPositionMapperEqual*/ true); checkProjectsWithoutDts(session); // Script info collection should behave as "noDts" - verifyScriptInfoCollection( - session, - host, - expectedScriptInfosWhenNoDts(), - expectedWatchedFilesWhenNoDts(), - ); + verifyScriptInfoCollection(session, host, expectedScriptInfosWhenNoDts(), expectedWatchedFilesWhenNoDts()); }); }); describe("when main tsconfig has project reference", () => { @@ -886,40 +713,29 @@ fn5(); return setupWithActionWith(setup, onHostCreate); } - function checkProjects(session: TestSession) { - checkNumberOfProjects(session.getProjectService(), { configuredProjects: 2 }); + function checkProjects(session: ts.projectSystem.TestSession) { + ts.projectSystem.checkNumberOfProjects(session.getProjectService(), { configuredProjects: 2 }); checkMainProjectWithProjectReferences(session); } function expectedScriptInfos() { - return [dependencyTs.path, libFile.path, mainTs.path, randomFile.path]; + return [dependencyTs.path, ts.projectSystem.libFile.path, mainTs.path, randomFile.path]; } function expectedWatchedFiles() { - return [dependencyTsPath, dependencyConfig.path, libFile.path, mainConfig.path, randomConfig.path]; + return [dependencyTsPath, dependencyConfig.path, ts.projectSystem.libFile.path, mainConfig.path, randomConfig.path]; } it("can go to definition correctly", () => { const { host, session } = setup(); checkProjects(session); - verifyAllFnAction( - session, - host, - goToDefFromMainTs, - expectedScriptInfos(), - expectedWatchedFiles(), + verifyAllFnAction(session, host, goToDefFromMainTs, expectedScriptInfos(), expectedWatchedFiles(), /*existingDependencyMap*/ undefined, /*existingDocumentPositionMapper*/ undefined, /*existingMapEqual*/ true, - /*existingDocumentPositionMapperEqual*/ true - ); + /*existingDocumentPositionMapperEqual*/ true); checkProjects(session); - verifyScriptInfoCollection( - session, - host, - expectedScriptInfos(), - expectedWatchedFiles(), - ); + verifyScriptInfoCollection(session, host, expectedScriptInfos(), expectedWatchedFiles()); }); // Edit @@ -934,17 +750,9 @@ fn5(); verifyDocumentPositionMapperEqual(session, dependencyMap, documentPositionMapper); // action - verifyAllFnAction( - session, - host, - goToDefFromMainTs, - expectedScriptInfos(), - expectedWatchedFiles(), - dependencyMap, - documentPositionMapper, - /*existingMapEqual*/ true, - /*existingDocumentPositionMapperEqual*/ true - ); + verifyAllFnAction(session, host, goToDefFromMainTs, expectedScriptInfos(), expectedWatchedFiles(), dependencyMap, documentPositionMapper, + /*existingMapEqual*/ true, + /*existingDocumentPositionMapperEqual*/ true); }); it(`when usage file changes, document position mapper doesnt change, when timeout does not occur before request`, () => { // Create DocumentPositionMapper @@ -954,17 +762,9 @@ fn5(); makeChangeToMainTs(session); // action - verifyAllFnAction( - session, - host, - goToDefFromMainTs, - expectedScriptInfos(), - expectedWatchedFiles(), - dependencyMap, - documentPositionMapper, - /*existingMapEqual*/ true, - /*existingDocumentPositionMapperEqual*/ true - ); + verifyAllFnAction(session, host, goToDefFromMainTs, expectedScriptInfos(), expectedWatchedFiles(), dependencyMap, documentPositionMapper, + /*existingMapEqual*/ true, + /*existingDocumentPositionMapperEqual*/ true); }); // Edit dts to add new fn @@ -979,17 +779,9 @@ fn5(); verifyDocumentPositionMapperEqual(session, dependencyMap, documentPositionMapper); // action - verifyAllFnAction( - session, - host, - goToDefFromMainTs, - expectedScriptInfos(), - expectedWatchedFiles(), - dependencyMap, - documentPositionMapper, - /*existingMapEqual*/ true, - /*existingDocumentPositionMapperEqual*/ true - ); + verifyAllFnAction(session, host, goToDefFromMainTs, expectedScriptInfos(), expectedWatchedFiles(), dependencyMap, documentPositionMapper, + /*existingMapEqual*/ true, + /*existingDocumentPositionMapperEqual*/ true); }); it(`when dependency .d.ts changes, document position mapper doesnt change, when timeout does not occur before request`, () => { // Create DocumentPositionMapper @@ -999,17 +791,9 @@ fn5(); changeDtsFile(host); // action - verifyAllFnAction( - session, - host, - goToDefFromMainTs, - expectedScriptInfos(), - expectedWatchedFiles(), - dependencyMap, - documentPositionMapper, - /*existingMapEqual*/ true, - /*existingDocumentPositionMapperEqual*/ true - ); + verifyAllFnAction(session, host, goToDefFromMainTs, expectedScriptInfos(), expectedWatchedFiles(), dependencyMap, documentPositionMapper, + /*existingMapEqual*/ true, + /*existingDocumentPositionMapperEqual*/ true); }); // Edit map file to represent added new line @@ -1024,17 +808,9 @@ fn5(); verifyDocumentPositionMapperEqual(session, dependencyMap, documentPositionMapper); // action - verifyAllFnAction( - session, - host, - goToDefFromMainTs, - expectedScriptInfos(), - expectedWatchedFiles(), - dependencyMap, - documentPositionMapper, - /*existingMapEqual*/ true, - /*existingDocumentPositionMapperEqual*/ true - ); + verifyAllFnAction(session, host, goToDefFromMainTs, expectedScriptInfos(), expectedWatchedFiles(), dependencyMap, documentPositionMapper, + /*existingMapEqual*/ true, + /*existingDocumentPositionMapperEqual*/ true); }); it(`when dependency file's map changes, when timeout does not occur before request`, () => { // Create DocumentPositionMapper @@ -1044,41 +820,22 @@ fn5(); changeDtsMapFile(host); // action - verifyAllFnAction( - session, - host, - goToDefFromMainTs, - expectedScriptInfos(), - expectedWatchedFiles(), - dependencyMap, - documentPositionMapper, - /*existingMapEqual*/ true, - /*existingDocumentPositionMapperEqual*/ true - ); + verifyAllFnAction(session, host, goToDefFromMainTs, expectedScriptInfos(), expectedWatchedFiles(), dependencyMap, documentPositionMapper, + /*existingMapEqual*/ true, + /*existingDocumentPositionMapperEqual*/ true); }); it(`with depedency files map file, when file is not present`, () => { const { host, session } = setup(host => host.deleteFile(dtsMapLocation)); checkProjects(session); - verifyAllFnAction( - session, - host, - goToDefFromMainTs, - expectedScriptInfos(), - expectedWatchedFiles(), + verifyAllFnAction(session, host, goToDefFromMainTs, expectedScriptInfos(), expectedWatchedFiles(), /*existingDependencyMap*/ undefined, /*existingDocumentPositionMapper*/ undefined, /*existingMapEqual*/ true, - /*existingDocumentPositionMapperEqual*/ true - ); + /*existingDocumentPositionMapperEqual*/ true); checkProjects(session); - verifyScriptInfoCollection( - session, - host, - expectedScriptInfos(), - expectedWatchedFiles(), - ); + verifyScriptInfoCollection(session, host, expectedScriptInfos(), expectedWatchedFiles()); }); it(`with depedency files map file, when file is created after actions on projects`, () => { let fileContents: string; @@ -1088,74 +845,37 @@ fn5(); }); host.writeFile(dtsMapLocation, fileContents!); - verifyAllFnAction( - session, - host, - goToDefFromMainTs, - expectedScriptInfos(), - expectedWatchedFiles(), - dependencyMap, - documentPositionMapper, - /*existingMapEqual*/ true, - /*existingDocumentPositionMapperEqual*/ true - ); + verifyAllFnAction(session, host, goToDefFromMainTs, expectedScriptInfos(), expectedWatchedFiles(), dependencyMap, documentPositionMapper, + /*existingMapEqual*/ true, + /*existingDocumentPositionMapperEqual*/ true); checkProjects(session); - verifyScriptInfoCollection( - session, - host, - expectedScriptInfos(), - expectedWatchedFiles() - ); + verifyScriptInfoCollection(session, host, expectedScriptInfos(), expectedWatchedFiles()); }); it(`with depedency files map file, when file is deleted after actions on the projects`, () => { const { host, session, dependencyMap, documentPositionMapper } = setupWithAction(); // The dependency file is deleted when orphan files are collected host.deleteFile(dtsMapLocation); - verifyAllFnAction( - session, - host, - goToDefFromMainTs, - expectedScriptInfos(), - expectedWatchedFiles(), - dependencyMap, - documentPositionMapper, - /*existingMapEqual*/ true, - /*existingDocumentPositionMapperEqual*/ true - ); + verifyAllFnAction(session, host, goToDefFromMainTs, expectedScriptInfos(), expectedWatchedFiles(), dependencyMap, documentPositionMapper, + /*existingMapEqual*/ true, + /*existingDocumentPositionMapperEqual*/ true); checkProjects(session); // Script info collection should behave as fileNotPresentKey - verifyScriptInfoCollection( - session, - host, - expectedScriptInfos(), - expectedWatchedFiles(), - ); + verifyScriptInfoCollection(session, host, expectedScriptInfos(), expectedWatchedFiles()); }); it(`with depedency .d.ts file, when file is not present`, () => { const { host, session } = setup(host => host.deleteFile(dtsLocation)); checkProjects(session); - verifyAllFnAction( - session, - host, - goToDefFromMainTs, - expectedScriptInfos(), - expectedWatchedFiles(), + verifyAllFnAction(session, host, goToDefFromMainTs, expectedScriptInfos(), expectedWatchedFiles(), /*existingDependencyMap*/ undefined, /*existingDocumentPositionMapper*/ undefined, /*existingMapEqual*/ true, - /*existingDocumentPositionMapperEqual*/ true - ); + /*existingDocumentPositionMapperEqual*/ true); checkProjects(session); - verifyScriptInfoCollection( - session, - host, - expectedScriptInfos(), - expectedWatchedFiles(), - ); + verifyScriptInfoCollection(session, host, expectedScriptInfos(), expectedWatchedFiles()); }); it(`with depedency .d.ts file, when file is created after actions on projects`, () => { let fileContents: string; @@ -1165,50 +885,24 @@ fn5(); }); host.writeFile(dtsLocation, fileContents!); - verifyAllFnAction( - session, - host, - goToDefFromMainTs, - expectedScriptInfos(), - expectedWatchedFiles(), - dependencyMap, - documentPositionMapper, - /*existingMapEqual*/ true, - /*existingDocumentPositionMapperEqual*/ true - ); + verifyAllFnAction(session, host, goToDefFromMainTs, expectedScriptInfos(), expectedWatchedFiles(), dependencyMap, documentPositionMapper, + /*existingMapEqual*/ true, + /*existingDocumentPositionMapperEqual*/ true); checkProjects(session); - verifyScriptInfoCollection( - session, - host, - expectedScriptInfos(), - expectedWatchedFiles() - ); + verifyScriptInfoCollection(session, host, expectedScriptInfos(), expectedWatchedFiles()); }); it(`with depedency .d.ts file, when file is deleted after actions on the projects`, () => { const { host, session, dependencyMap, documentPositionMapper } = setupWithAction(); // The dependency file is deleted when orphan files are collected host.deleteFile(dtsLocation); - verifyAllFnAction( - session, - host, - goToDefFromMainTs, - expectedScriptInfos(), - expectedWatchedFiles(), - dependencyMap, - documentPositionMapper, - /*existingMapEqual*/ true, - /*existingDocumentPositionMapperEqual*/ true - ); + verifyAllFnAction(session, host, goToDefFromMainTs, expectedScriptInfos(), expectedWatchedFiles(), dependencyMap, documentPositionMapper, + /*existingMapEqual*/ true, + /*existingDocumentPositionMapperEqual*/ true); checkProjects(session); // Script info collection should behave as "noDts" - verifyScriptInfoCollection( - session, - host, - expectedScriptInfos(), - expectedWatchedFiles(), - ); + verifyScriptInfoCollection(session, host, expectedScriptInfos(), expectedWatchedFiles()); }); it(`when defining project source changes, when timeout occurs before request`, () => { @@ -1224,17 +918,11 @@ ${dependencyTs.content}`); verifyDocumentPositionMapperEqual(session, dependencyMap, documentPositionMapper); // action - verifyAllFnAction( - session, - host, - goToDefFromMainTsWithDependencyChange, - expectedScriptInfos(), - expectedWatchedFiles(), + verifyAllFnAction(session, host, goToDefFromMainTsWithDependencyChange, expectedScriptInfos(), expectedWatchedFiles(), /*existingDependencyMap*/ undefined, /*existingDocumentPositionMapper*/ undefined, /*existingMapEqual*/ true, - /*existingDocumentPositionMapperEqual*/ true - ); + /*existingDocumentPositionMapperEqual*/ true); }); it(`when defining project source changes, when timeout does not occur before request`, () => { // Create DocumentPositionMapper @@ -1246,41 +934,24 @@ ${dependencyTs.content}`); ${dependencyTs.content}`); // action - verifyAllFnAction( - session, - host, - goToDefFromMainTsWithDependencyChange, - expectedScriptInfos(), - expectedWatchedFiles(), + verifyAllFnAction(session, host, goToDefFromMainTsWithDependencyChange, expectedScriptInfos(), expectedWatchedFiles(), /*existingDependencyMap*/ undefined, /*existingDocumentPositionMapper*/ undefined, /*existingMapEqual*/ true, - /*existingDocumentPositionMapperEqual*/ true - ); + /*existingDocumentPositionMapperEqual*/ true); }); it("when projects are not built", () => { - const host = createServerHost(files); - const session = createSession(host); - openFilesForSession([mainTs, randomFile], session); - verifyAllFnAction( - session, - host, - goToDefFromMainTs, - expectedScriptInfos(), - expectedWatchedFiles(), + const host = ts.projectSystem.createServerHost(files); + const session = ts.projectSystem.createSession(host); + ts.projectSystem.openFilesForSession([mainTs, randomFile], session); + verifyAllFnAction(session, host, goToDefFromMainTs, expectedScriptInfos(), expectedWatchedFiles(), /*existingDependencyMap*/ undefined, /*existingDocumentPositionMapper*/ undefined, /*existingMapEqual*/ true, - /*existingDocumentPositionMapperEqual*/ true - ); + /*existingDocumentPositionMapperEqual*/ true); checkProjects(session); - verifyScriptInfoCollection( - session, - host, - expectedScriptInfos(), - expectedWatchedFiles(), - ); + verifyScriptInfoCollection(session, host, expectedScriptInfos(), expectedWatchedFiles()); }); }); describe("when main tsconfig has disableSourceOfProjectReferenceRedirect along with project reference", () => { @@ -1292,22 +963,22 @@ ${dependencyTs.content}`); return setupWithActionWith(setup, onHostCreate); } - function checkProjects(session: TestSession) { - checkNumberOfProjects(session.getProjectService(), { configuredProjects: 2 }); + function checkProjects(session: ts.projectSystem.TestSession) { + ts.projectSystem.checkNumberOfProjects(session.getProjectService(), { configuredProjects: 2 }); checkMainProjectWithDisabledProjectReferences(session); } - function checkProjectsWithoutDts(session: TestSession) { - checkNumberOfProjects(session.getProjectService(), { configuredProjects: 2 }); + function checkProjectsWithoutDts(session: ts.projectSystem.TestSession) { + ts.projectSystem.checkNumberOfProjects(session.getProjectService(), { configuredProjects: 2 }); checkMainProjectWithDisabledProjectReferencesWithoutDts(session); } function expectedScriptInfosWhenMapped() { - return [mainTs.path, randomFile.path, dependencyTs.path, libFile.path, dtsPath, dtsMapLocation]; + return [mainTs.path, randomFile.path, dependencyTs.path, ts.projectSystem.libFile.path, dtsPath, dtsMapLocation]; } function expectedWatchedFilesWhenMapped() { - return [dependencyTsPath, libFile.path, dtsPath, dtsMapPath, mainConfig.path, randomConfig.path, dependencyConfig.path]; + return [dependencyTsPath, ts.projectSystem.libFile.path, dtsPath, dtsMapPath, mainConfig.path, randomConfig.path, dependencyConfig.path]; } function expectedScriptInfosWhenNoMap() { @@ -1332,24 +1003,13 @@ ${dependencyTs.content}`); it("can go to definition correctly", () => { const { host, session } = setup(); checkProjects(session); - verifyAllFnAction( - session, - host, - goToDefFromMainTs, - expectedScriptInfosWhenMapped(), - expectedWatchedFilesWhenMapped(), + verifyAllFnAction(session, host, goToDefFromMainTs, expectedScriptInfosWhenMapped(), expectedWatchedFilesWhenMapped(), /*existingDependencyMap*/ undefined, /*existingDocumentPositionMapper*/ undefined, /*existingMapEqual*/ false, - /*existingDocumentPositionMapperEqual*/ false - ); + /*existingDocumentPositionMapperEqual*/ false); checkProjects(session); - verifyScriptInfoCollection( - session, - host, - expectedScriptInfosWhenMapped(), - expectedWatchedFilesWhenMapped(), - ); + verifyScriptInfoCollection(session, host, expectedScriptInfosWhenMapped(), expectedWatchedFilesWhenMapped()); }); // Edit @@ -1364,17 +1024,9 @@ ${dependencyTs.content}`); verifyDocumentPositionMapperEqual(session, dependencyMap, documentPositionMapper); // action - verifyAllFnAction( - session, - host, - goToDefFromMainTs, - expectedScriptInfosWhenMapped(), - expectedWatchedFilesWhenMapped(), - dependencyMap, - documentPositionMapper, - /*existingMapEqual*/ true, - /*existingDocumentPositionMapperEqual*/ true - ); + verifyAllFnAction(session, host, goToDefFromMainTs, expectedScriptInfosWhenMapped(), expectedWatchedFilesWhenMapped(), dependencyMap, documentPositionMapper, + /*existingMapEqual*/ true, + /*existingDocumentPositionMapperEqual*/ true); }); it(`when usage file changes, document position mapper doesnt change, when timeout does not occur before request`, () => { // Create DocumentPositionMapper @@ -1384,17 +1036,9 @@ ${dependencyTs.content}`); makeChangeToMainTs(session); // action - verifyAllFnAction( - session, - host, - goToDefFromMainTs, - expectedScriptInfosWhenMapped(), - expectedWatchedFilesWhenMapped(), - dependencyMap, - documentPositionMapper, - /*existingMapEqual*/ true, - /*existingDocumentPositionMapperEqual*/ true - ); + verifyAllFnAction(session, host, goToDefFromMainTs, expectedScriptInfosWhenMapped(), expectedWatchedFilesWhenMapped(), dependencyMap, documentPositionMapper, + /*existingMapEqual*/ true, + /*existingDocumentPositionMapperEqual*/ true); }); // Edit dts to add new fn @@ -1409,17 +1053,9 @@ ${dependencyTs.content}`); verifyDocumentPositionMapperEqual(session, dependencyMap, documentPositionMapper); // action - verifyAllFnAction( - session, - host, - goToDefFromMainTs, - expectedScriptInfosWhenMapped(), - expectedWatchedFilesWhenMapped(), - dependencyMap, - documentPositionMapper, - /*existingMapEqual*/ true, - /*existingDocumentPositionMapperEqual*/ true - ); + verifyAllFnAction(session, host, goToDefFromMainTs, expectedScriptInfosWhenMapped(), expectedWatchedFilesWhenMapped(), dependencyMap, documentPositionMapper, + /*existingMapEqual*/ true, + /*existingDocumentPositionMapperEqual*/ true); }); it(`when dependency .d.ts changes, document position mapper doesnt change, when timeout does not occur before request`, () => { // Create DocumentPositionMapper @@ -1429,17 +1065,9 @@ ${dependencyTs.content}`); changeDtsFile(host); // action - verifyAllFnAction( - session, - host, - goToDefFromMainTs, - expectedScriptInfosWhenMapped(), - expectedWatchedFilesWhenMapped(), - dependencyMap, - documentPositionMapper, - /*existingMapEqual*/ true, - /*existingDocumentPositionMapperEqual*/ true - ); + verifyAllFnAction(session, host, goToDefFromMainTs, expectedScriptInfosWhenMapped(), expectedWatchedFilesWhenMapped(), dependencyMap, documentPositionMapper, + /*existingMapEqual*/ true, + /*existingDocumentPositionMapperEqual*/ true); }); // Edit map file to represent added new line @@ -1454,17 +1082,9 @@ ${dependencyTs.content}`); verifyDocumentPositionMapperEqual(session, dependencyMap, documentPositionMapper); // action - verifyAllFnAction( - session, - host, - goToDefFromMainTs, - expectedScriptInfosWhenMapped(), - expectedWatchedFilesWhenMapped(), - dependencyMap, - documentPositionMapper, - /*existingMapEqual*/ true, - /*existingDocumentPositionMapperEqual*/ false - ); + verifyAllFnAction(session, host, goToDefFromMainTs, expectedScriptInfosWhenMapped(), expectedWatchedFilesWhenMapped(), dependencyMap, documentPositionMapper, + /*existingMapEqual*/ true, + /*existingDocumentPositionMapperEqual*/ false); }); it(`when dependency file's map changes, when timeout does not occur before request`, () => { // Create DocumentPositionMapper @@ -1474,41 +1094,22 @@ ${dependencyTs.content}`); changeDtsMapFile(host); // action - verifyAllFnAction( - session, - host, - goToDefFromMainTs, - expectedScriptInfosWhenMapped(), - expectedWatchedFilesWhenMapped(), - dependencyMap, - documentPositionMapper, - /*existingMapEqual*/ true, - /*existingDocumentPositionMapperEqual*/ false - ); + verifyAllFnAction(session, host, goToDefFromMainTs, expectedScriptInfosWhenMapped(), expectedWatchedFilesWhenMapped(), dependencyMap, documentPositionMapper, + /*existingMapEqual*/ true, + /*existingDocumentPositionMapperEqual*/ false); }); it(`with depedency files map file, when file is not present`, () => { const { host, session } = setup(host => host.deleteFile(dtsMapLocation)); checkProjects(session); - verifyAllFnAction( - session, - host, - goToDefFromMainTsWithNoMap, - expectedScriptInfosWhenNoMap(), - expectedWatchedFilesWhenNoMap(), + verifyAllFnAction(session, host, goToDefFromMainTsWithNoMap, expectedScriptInfosWhenNoMap(), expectedWatchedFilesWhenNoMap(), /*existingDependencyMap*/ undefined, /*existingDocumentPositionMapper*/ undefined, /*existingMapEqual*/ true, - /*existingDocumentPositionMapperEqual*/ true - ); + /*existingDocumentPositionMapperEqual*/ true); checkProjects(session); - verifyScriptInfoCollection( - session, - host, - expectedScriptInfosWhenNoMap(), - expectedWatchedFilesWhenNoMap(), - ); + verifyScriptInfoCollection(session, host, expectedScriptInfosWhenNoMap(), expectedWatchedFilesWhenNoMap()); }); it(`with depedency files map file, when file is created after actions on projects`, () => { let fileContents: string; @@ -1518,75 +1119,39 @@ ${dependencyTs.content}`); }); host.writeFile(dtsMapLocation, fileContents!); - verifyAllFnAction( - session, - host, - goToDefFromMainTs, - expectedScriptInfosWhenMapped(), - expectedWatchedFilesWhenMapped(), - dependencyMap, - documentPositionMapper, + verifyAllFnAction(session, host, goToDefFromMainTs, expectedScriptInfosWhenMapped(), expectedWatchedFilesWhenMapped(), dependencyMap, documentPositionMapper, /*existingMapEqual*/ false, - /*existingDocumentPositionMapperEqual*/ false - ); + /*existingDocumentPositionMapperEqual*/ false); checkProjects(session); - verifyScriptInfoCollection( - session, - host, - expectedScriptInfosWhenMapped(), - expectedWatchedFilesWhenMapped() - ); + verifyScriptInfoCollection(session, host, expectedScriptInfosWhenMapped(), expectedWatchedFilesWhenMapped()); }); it(`with depedency files map file, when file is deleted after actions on the projects`, () => { const { host, session, dependencyMap, documentPositionMapper } = setupWithAction(); // The dependency file is deleted when orphan files are collected host.deleteFile(dtsMapLocation); - verifyAllFnAction( - session, - host, - goToDefFromMainTsWithNoMap, + verifyAllFnAction(session, host, goToDefFromMainTsWithNoMap, // The script info for map is collected only after file open - expectedScriptInfosWhenNoMap().concat(dependencyTs.path), - expectedWatchedFilesWhenNoMap().concat(dependencyTsPath), - dependencyMap, - documentPositionMapper, + expectedScriptInfosWhenNoMap().concat(dependencyTs.path), expectedWatchedFilesWhenNoMap().concat(dependencyTsPath), dependencyMap, documentPositionMapper, /*existingMapEqual*/ false, - /*existingDocumentPositionMapperEqual*/ false - ); + /*existingDocumentPositionMapperEqual*/ false); checkProjects(session); // Script info collection should behave as fileNotPresentKey - verifyScriptInfoCollection( - session, - host, - expectedScriptInfosWhenNoMap(), - expectedWatchedFilesWhenNoMap(), - ); + verifyScriptInfoCollection(session, host, expectedScriptInfosWhenNoMap(), expectedWatchedFilesWhenNoMap()); }); it(`with depedency .d.ts file, when file is not present`, () => { const { host, session } = setup(host => host.deleteFile(dtsLocation)); checkProjectsWithoutDts(session); - verifyAllFnAction( - session, - host, - goToDefFromMainTsWithNoDts, - expectedScriptInfosWhenNoDts(), - expectedWatchedFilesWhenNoDts(), + verifyAllFnAction(session, host, goToDefFromMainTsWithNoDts, expectedScriptInfosWhenNoDts(), expectedWatchedFilesWhenNoDts(), /*existingDependencyMap*/ undefined, /*existingDocumentPositionMapper*/ undefined, /*existingMapEqual*/ true, - /*existingDocumentPositionMapperEqual*/ true - ); + /*existingDocumentPositionMapperEqual*/ true); checkProjectsWithoutDts(session); - verifyScriptInfoCollection( - session, - host, - expectedScriptInfosWhenNoDts(), - expectedWatchedFilesWhenNoDts(), - ); + verifyScriptInfoCollection(session, host, expectedScriptInfosWhenNoDts(), expectedWatchedFilesWhenNoDts()); }); it(`with depedency .d.ts file, when file is created after actions on projects`, () => { let fileContents: string; @@ -1596,51 +1161,26 @@ ${dependencyTs.content}`); }); host.writeFile(dtsLocation, fileContents!); - verifyAllFnAction( - session, - host, - goToDefFromMainTs, - expectedScriptInfosWhenMapped(), - expectedWatchedFilesWhenMapped(), - dependencyMap, - documentPositionMapper, + verifyAllFnAction(session, host, goToDefFromMainTs, expectedScriptInfosWhenMapped(), expectedWatchedFilesWhenMapped(), dependencyMap, documentPositionMapper, /*existingMapEqual*/ false, - /*existingDocumentPositionMapperEqual*/ false - ); + /*existingDocumentPositionMapperEqual*/ false); checkProjects(session); - verifyScriptInfoCollection( - session, - host, - expectedScriptInfosWhenMapped(), - expectedWatchedFilesWhenMapped() - ); + verifyScriptInfoCollection(session, host, expectedScriptInfosWhenMapped(), expectedWatchedFilesWhenMapped()); }); it(`with depedency .d.ts file, when file is deleted after actions on the projects`, () => { const { host, session, dependencyMap, documentPositionMapper } = setupWithAction(); // The dependency file is deleted when orphan files are collected host.deleteFile(dtsLocation); - verifyAllFnAction( - session, - host, - goToDefFromMainTsWithNoDts, + verifyAllFnAction(session, host, goToDefFromMainTsWithNoDts, // The script info for map is collected only after file open - expectedScriptInfosWhenNoDts().concat(dependencyTs.path, dtsMapLocation), - expectedWatchedFilesWhenNoDts().concat(dependencyTsPath, dtsMapPath), - dependencyMap, - documentPositionMapper, + expectedScriptInfosWhenNoDts().concat(dependencyTs.path, dtsMapLocation), expectedWatchedFilesWhenNoDts().concat(dependencyTsPath, dtsMapPath), dependencyMap, documentPositionMapper, /*existingMapEqual*/ true, - /*existingDocumentPositionMapperEqual*/ true - ); + /*existingDocumentPositionMapperEqual*/ true); checkProjectsWithoutDts(session); // Script info collection should behave as "noDts" - verifyScriptInfoCollection( - session, - host, - expectedScriptInfosWhenNoDts(), - expectedWatchedFilesWhenNoDts(), - ); + verifyScriptInfoCollection(session, host, expectedScriptInfosWhenNoDts(), expectedWatchedFilesWhenNoDts()); }); }); }); @@ -1652,26 +1192,21 @@ ${dependencyTs.content}`); return { ...result, ...getDocumentPositionMapper(result.session) }; } - function verifyScriptInfoCollection( - session: TestSession, - host: TestServerHost, - expectedInfos: readonly string[], - expectedWatchedFiles: readonly string[], - ) { + function verifyScriptInfoCollection(session: ts.projectSystem.TestSession, host: ts.projectSystem.TestServerHost, expectedInfos: readonly string[], expectedWatchedFiles: readonly string[]) { return verifyScriptInfoCollectionWith(session, host, [dependencyTs], expectedInfos, expectedWatchedFiles); } - function checkProjects(session: TestSession) { - checkNumberOfProjects(session.getProjectService(), { configuredProjects: 2 }); + function checkProjects(session: ts.projectSystem.TestSession) { + ts.projectSystem.checkNumberOfProjects(session.getProjectService(), { configuredProjects: 2 }); checkDependencyProjectWith(session); } function expectedScriptInfos() { - return [libFile.path, dtsLocation, dtsMapLocation, dependencyTs.path, randomFile.path]; + return [ts.projectSystem.libFile.path, dtsLocation, dtsMapLocation, dependencyTs.path, randomFile.path]; } function expectedWatchedFiles() { - return [libFile.path, dtsPath, dtsMapPath, dependencyConfig.path, randomConfig.path]; + return [ts.projectSystem.libFile.path, dtsPath, dtsMapPath, dependencyConfig.path, randomConfig.path]; } function expectedScriptInfosWhenNoMap() { @@ -1706,24 +1241,13 @@ ${dependencyTs.content}`); it("rename locations from dependency", () => { const { host, session } = setup(); checkProjects(session); - verifyAllFnAction( - session, - host, - renameFromDependencyTs, - expectedScriptInfos(), - expectedWatchedFiles(), + verifyAllFnAction(session, host, renameFromDependencyTs, expectedScriptInfos(), expectedWatchedFiles(), /*existingDependencyMap*/ undefined, /*existingDocumentPositionMapper*/ undefined, /*existingMapEqual*/ false, - /*existingDocumentPositionMapperEqual*/ false - ); + /*existingDocumentPositionMapperEqual*/ false); checkProjects(session); - verifyScriptInfoCollection( - session, - host, - expectedScriptInfos(), - expectedWatchedFiles(), - ); + verifyScriptInfoCollection(session, host, expectedScriptInfos(), expectedWatchedFiles()); }); // Edit @@ -1738,17 +1262,9 @@ ${dependencyTs.content}`); verifyDocumentPositionMapperEqual(session, dependencyMap, documentPositionMapper); // action - verifyAllFnAction( - session, - host, - renameFromDependencyTs, - expectedScriptInfos(), - expectedWatchedFiles(), - dependencyMap, - documentPositionMapper, - /*existingMapEqual*/ true, - /*existingDocumentPositionMapperEqual*/ true - ); + verifyAllFnAction(session, host, renameFromDependencyTs, expectedScriptInfos(), expectedWatchedFiles(), dependencyMap, documentPositionMapper, + /*existingMapEqual*/ true, + /*existingDocumentPositionMapperEqual*/ true); }); it(`when usage file changes, document position mapper doesnt change, when timeout does not occur before request`, () => { // Create DocumentPositionMapper @@ -1758,17 +1274,9 @@ ${dependencyTs.content}`); makeChangeToDependencyTs(session); // action - verifyAllFnAction( - session, - host, - renameFromDependencyTs, - expectedScriptInfos(), - expectedWatchedFiles(), - dependencyMap, - documentPositionMapper, - /*existingMapEqual*/ true, - /*existingDocumentPositionMapperEqual*/ true - ); + verifyAllFnAction(session, host, renameFromDependencyTs, expectedScriptInfos(), expectedWatchedFiles(), dependencyMap, documentPositionMapper, + /*existingMapEqual*/ true, + /*existingDocumentPositionMapperEqual*/ true); }); // Edit dts to add new fn @@ -1783,17 +1291,9 @@ ${dependencyTs.content}`); verifyDocumentPositionMapperEqual(session, dependencyMap, documentPositionMapper); // action - verifyAllFnAction( - session, - host, - renameFromDependencyTs, - expectedScriptInfos(), - expectedWatchedFiles(), - dependencyMap, - documentPositionMapper, - /*existingMapEqual*/ true, - /*existingDocumentPositionMapperEqual*/ true - ); + verifyAllFnAction(session, host, renameFromDependencyTs, expectedScriptInfos(), expectedWatchedFiles(), dependencyMap, documentPositionMapper, + /*existingMapEqual*/ true, + /*existingDocumentPositionMapperEqual*/ true); }); it(`when dependency .d.ts changes, document position mapper doesnt change, when timeout does not occur before request`, () => { // Create DocumentPositionMapper @@ -1803,17 +1303,9 @@ ${dependencyTs.content}`); changeDtsFile(host); // action - verifyAllFnAction( - session, - host, - renameFromDependencyTs, - expectedScriptInfos(), - expectedWatchedFiles(), - dependencyMap, - documentPositionMapper, - /*existingMapEqual*/ true, - /*existingDocumentPositionMapperEqual*/ true - ); + verifyAllFnAction(session, host, renameFromDependencyTs, expectedScriptInfos(), expectedWatchedFiles(), dependencyMap, documentPositionMapper, + /*existingMapEqual*/ true, + /*existingDocumentPositionMapperEqual*/ true); }); // Edit map file to represent added new line @@ -1828,17 +1320,9 @@ ${dependencyTs.content}`); verifyDocumentPositionMapperEqual(session, dependencyMap, documentPositionMapper); // action - verifyAllFnAction( - session, - host, - renameFromDependencyTs, - expectedScriptInfos(), - expectedWatchedFiles(), - dependencyMap, - documentPositionMapper, - /*existingMapEqual*/ true, - /*existingDocumentPositionMapperEqual*/ false - ); + verifyAllFnAction(session, host, renameFromDependencyTs, expectedScriptInfos(), expectedWatchedFiles(), dependencyMap, documentPositionMapper, + /*existingMapEqual*/ true, + /*existingDocumentPositionMapperEqual*/ false); }); it(`when dependency file's map changes, when timeout does not occur before request`, () => { // Create DocumentPositionMapper @@ -1848,41 +1332,22 @@ ${dependencyTs.content}`); changeDtsMapFile(host); // action - verifyAllFnAction( - session, - host, - renameFromDependencyTs, - expectedScriptInfos(), - expectedWatchedFiles(), - dependencyMap, - documentPositionMapper, - /*existingMapEqual*/ true, - /*existingDocumentPositionMapperEqual*/ false - ); + verifyAllFnAction(session, host, renameFromDependencyTs, expectedScriptInfos(), expectedWatchedFiles(), dependencyMap, documentPositionMapper, + /*existingMapEqual*/ true, + /*existingDocumentPositionMapperEqual*/ false); }); it(`with depedency files map file, when file is not present`, () => { const { host, session } = setup(host => host.deleteFile(dtsMapLocation)); checkProjects(session); - verifyAllFnAction( - session, - host, - renameFromDependencyTs, - expectedScriptInfosWhenNoMap(), - expectedWatchedFilesWhenNoMap(), + verifyAllFnAction(session, host, renameFromDependencyTs, expectedScriptInfosWhenNoMap(), expectedWatchedFilesWhenNoMap(), /*existingDependencyMap*/ undefined, /*existingDocumentPositionMapper*/ undefined, /*existingMapEqual*/ true, - /*existingDocumentPositionMapperEqual*/ true - ); + /*existingDocumentPositionMapperEqual*/ true); checkProjects(session); - verifyScriptInfoCollection( - session, - host, - expectedScriptInfosWhenNoMap(), - expectedWatchedFilesWhenNoMap(), - ); + verifyScriptInfoCollection(session, host, expectedScriptInfosWhenNoMap(), expectedWatchedFilesWhenNoMap()); }); it(`with depedency files map file, when file is created after actions on projects`, () => { let fileContents: string; @@ -1892,74 +1357,37 @@ ${dependencyTs.content}`); }); host.writeFile(dtsMapLocation, fileContents!); - verifyAllFnAction( - session, - host, - renameFromDependencyTs, - expectedScriptInfos(), - expectedWatchedFiles(), - dependencyMap, - documentPositionMapper, + verifyAllFnAction(session, host, renameFromDependencyTs, expectedScriptInfos(), expectedWatchedFiles(), dependencyMap, documentPositionMapper, /*existingMapEqual*/ false, - /*existingDocumentPositionMapperEqual*/ false - ); + /*existingDocumentPositionMapperEqual*/ false); checkProjects(session); - verifyScriptInfoCollection( - session, - host, - expectedScriptInfos(), - expectedWatchedFiles() - ); + verifyScriptInfoCollection(session, host, expectedScriptInfos(), expectedWatchedFiles()); }); it(`with depedency files map file, when file is deleted after actions on the projects`, () => { const { host, session, dependencyMap, documentPositionMapper } = setupWithAction(); // The dependency file is deleted when orphan files are collected host.deleteFile(dtsMapLocation); - verifyAllFnAction( - session, - host, - renameFromDependencyTs, - expectedScriptInfosWhenNoMap(), - expectedWatchedFilesWhenNoMap(), - dependencyMap, - documentPositionMapper, + verifyAllFnAction(session, host, renameFromDependencyTs, expectedScriptInfosWhenNoMap(), expectedWatchedFilesWhenNoMap(), dependencyMap, documentPositionMapper, /*existingMapEqual*/ false, - /*existingDocumentPositionMapperEqual*/ false - ); + /*existingDocumentPositionMapperEqual*/ false); checkProjects(session); // Script info collection should behave as fileNotPresentKey - verifyScriptInfoCollection( - session, - host, - expectedScriptInfosWhenNoMap(), - expectedWatchedFilesWhenNoMap(), - ); + verifyScriptInfoCollection(session, host, expectedScriptInfosWhenNoMap(), expectedWatchedFilesWhenNoMap()); }); it(`with depedency .d.ts file, when file is not present`, () => { const { host, session } = setup(host => host.deleteFile(dtsLocation)); checkProjects(session); - verifyAllFnAction( - session, - host, - renameFromDependencyTs, - expectedScriptInfosWhenNoDts(), - expectedWatchedFilesWhenNoDts(), + verifyAllFnAction(session, host, renameFromDependencyTs, expectedScriptInfosWhenNoDts(), expectedWatchedFilesWhenNoDts(), /*existingDependencyMap*/ undefined, /*existingDocumentPositionMapper*/ undefined, /*existingMapEqual*/ true, - /*existingDocumentPositionMapperEqual*/ true - ); + /*existingDocumentPositionMapperEqual*/ true); checkProjects(session); - verifyScriptInfoCollection( - session, - host, - expectedScriptInfosWhenNoDts(), - expectedWatchedFilesWhenNoDts(), - ); + verifyScriptInfoCollection(session, host, expectedScriptInfosWhenNoDts(), expectedWatchedFilesWhenNoDts()); }); it(`with depedency .d.ts file, when file is created after actions on projects`, () => { let fileContents: string; @@ -1969,51 +1397,26 @@ ${dependencyTs.content}`); }); host.writeFile(dtsLocation, fileContents!); - verifyAllFnAction( - session, - host, - renameFromDependencyTs, - expectedScriptInfos(), - expectedWatchedFiles(), - dependencyMap, - documentPositionMapper, + verifyAllFnAction(session, host, renameFromDependencyTs, expectedScriptInfos(), expectedWatchedFiles(), dependencyMap, documentPositionMapper, /*existingMapEqual*/ false, - /*existingDocumentPositionMapperEqual*/ false - ); + /*existingDocumentPositionMapperEqual*/ false); checkProjects(session); - verifyScriptInfoCollection( - session, - host, - expectedScriptInfos(), - expectedWatchedFiles() - ); + verifyScriptInfoCollection(session, host, expectedScriptInfos(), expectedWatchedFiles()); }); it(`with depedency .d.ts file, when file is deleted after actions on the projects`, () => { const { host, session, dependencyMap, documentPositionMapper } = setupWithAction(); // The dependency file is deleted when orphan files are collected host.deleteFile(dtsLocation); - verifyAllFnAction( - session, - host, - renameFromDependencyTs, + verifyAllFnAction(session, host, renameFromDependencyTs, // Map is collected after file open - expectedScriptInfosWhenNoDts().concat(dtsMapLocation), - expectedWatchedFilesWhenNoDts().concat(dtsPath), - dependencyMap, - documentPositionMapper, + expectedScriptInfosWhenNoDts().concat(dtsMapLocation), expectedWatchedFilesWhenNoDts().concat(dtsPath), dependencyMap, documentPositionMapper, /*existingMapEqual*/ true, - /*existingDocumentPositionMapperEqual*/ true - ); + /*existingDocumentPositionMapperEqual*/ true); checkProjects(session); // Script info collection should behave as "noDts" - verifyScriptInfoCollection( - session, - host, - expectedScriptInfosWhenNoDts(), - expectedWatchedFilesWhenNoDts(), - ); + verifyScriptInfoCollection(session, host, expectedScriptInfosWhenNoDts(), expectedWatchedFilesWhenNoDts()); }); }); describe("when main tsconfig has project reference", () => { @@ -2028,24 +1431,13 @@ ${dependencyTs.content}`); it("rename locations from dependency", () => { const { host, session } = setup(); checkProjects(session); - verifyAllFnAction( - session, - host, - renameFromDependencyTs, - expectedScriptInfos(), - expectedWatchedFiles(), + verifyAllFnAction(session, host, renameFromDependencyTs, expectedScriptInfos(), expectedWatchedFiles(), /*existingDependencyMap*/ undefined, /*existingDocumentPositionMapper*/ undefined, /*existingMapEqual*/ false, - /*existingDocumentPositionMapperEqual*/ false - ); + /*existingDocumentPositionMapperEqual*/ false); checkProjects(session); - verifyScriptInfoCollection( - session, - host, - expectedScriptInfos(), - expectedWatchedFiles(), - ); + verifyScriptInfoCollection(session, host, expectedScriptInfos(), expectedWatchedFiles()); }); // Edit @@ -2060,17 +1452,9 @@ ${dependencyTs.content}`); verifyDocumentPositionMapperEqual(session, dependencyMap, documentPositionMapper); // action - verifyAllFnAction( - session, - host, - renameFromDependencyTs, - expectedScriptInfos(), - expectedWatchedFiles(), - dependencyMap, - documentPositionMapper, - /*existingMapEqual*/ true, - /*existingDocumentPositionMapperEqual*/ true - ); + verifyAllFnAction(session, host, renameFromDependencyTs, expectedScriptInfos(), expectedWatchedFiles(), dependencyMap, documentPositionMapper, + /*existingMapEqual*/ true, + /*existingDocumentPositionMapperEqual*/ true); }); it(`when usage file changes, document position mapper doesnt change, when timeout does not occur before request`, () => { // Create DocumentPositionMapper @@ -2080,17 +1464,9 @@ ${dependencyTs.content}`); makeChangeToDependencyTs(session); // action - verifyAllFnAction( - session, - host, - renameFromDependencyTs, - expectedScriptInfos(), - expectedWatchedFiles(), - dependencyMap, - documentPositionMapper, - /*existingMapEqual*/ true, - /*existingDocumentPositionMapperEqual*/ true - ); + verifyAllFnAction(session, host, renameFromDependencyTs, expectedScriptInfos(), expectedWatchedFiles(), dependencyMap, documentPositionMapper, + /*existingMapEqual*/ true, + /*existingDocumentPositionMapperEqual*/ true); }); // Edit dts to add new fn @@ -2105,17 +1481,9 @@ ${dependencyTs.content}`); verifyDocumentPositionMapperEqual(session, dependencyMap, documentPositionMapper); // action - verifyAllFnAction( - session, - host, - renameFromDependencyTs, - expectedScriptInfos(), - expectedWatchedFiles(), - dependencyMap, - documentPositionMapper, - /*existingMapEqual*/ true, - /*existingDocumentPositionMapperEqual*/ true - ); + verifyAllFnAction(session, host, renameFromDependencyTs, expectedScriptInfos(), expectedWatchedFiles(), dependencyMap, documentPositionMapper, + /*existingMapEqual*/ true, + /*existingDocumentPositionMapperEqual*/ true); }); it(`when dependency .d.ts changes, document position mapper doesnt change, when timeout does not occur before request`, () => { // Create DocumentPositionMapper @@ -2125,17 +1493,9 @@ ${dependencyTs.content}`); changeDtsFile(host); // action - verifyAllFnAction( - session, - host, - renameFromDependencyTs, - expectedScriptInfos(), - expectedWatchedFiles(), - dependencyMap, - documentPositionMapper, - /*existingMapEqual*/ true, - /*existingDocumentPositionMapperEqual*/ true - ); + verifyAllFnAction(session, host, renameFromDependencyTs, expectedScriptInfos(), expectedWatchedFiles(), dependencyMap, documentPositionMapper, + /*existingMapEqual*/ true, + /*existingDocumentPositionMapperEqual*/ true); }); // Edit map file to represent added new line @@ -2150,17 +1510,9 @@ ${dependencyTs.content}`); verifyDocumentPositionMapperEqual(session, dependencyMap, documentPositionMapper); // action - verifyAllFnAction( - session, - host, - renameFromDependencyTs, - expectedScriptInfos(), - expectedWatchedFiles(), - dependencyMap, - documentPositionMapper, - /*existingMapEqual*/ true, - /*existingDocumentPositionMapperEqual*/ false - ); + verifyAllFnAction(session, host, renameFromDependencyTs, expectedScriptInfos(), expectedWatchedFiles(), dependencyMap, documentPositionMapper, + /*existingMapEqual*/ true, + /*existingDocumentPositionMapperEqual*/ false); }); it(`when dependency file's map changes, when timeout does not occur before request`, () => { // Create DocumentPositionMapper @@ -2170,41 +1522,22 @@ ${dependencyTs.content}`); changeDtsMapFile(host); // action - verifyAllFnAction( - session, - host, - renameFromDependencyTs, - expectedScriptInfos(), - expectedWatchedFiles(), - dependencyMap, - documentPositionMapper, - /*existingMapEqual*/ true, - /*existingDocumentPositionMapperEqual*/ false - ); + verifyAllFnAction(session, host, renameFromDependencyTs, expectedScriptInfos(), expectedWatchedFiles(), dependencyMap, documentPositionMapper, + /*existingMapEqual*/ true, + /*existingDocumentPositionMapperEqual*/ false); }); it(`with depedency files map file, when file is not present`, () => { const { host, session } = setup(host => host.deleteFile(dtsMapLocation)); checkProjects(session); - verifyAllFnAction( - session, - host, - renameFromDependencyTs, - expectedScriptInfosWhenNoMap(), - expectedWatchedFilesWhenNoMap(), + verifyAllFnAction(session, host, renameFromDependencyTs, expectedScriptInfosWhenNoMap(), expectedWatchedFilesWhenNoMap(), /*existingDependencyMap*/ undefined, /*existingDocumentPositionMapper*/ undefined, /*existingMapEqual*/ true, - /*existingDocumentPositionMapperEqual*/ true - ); + /*existingDocumentPositionMapperEqual*/ true); checkProjects(session); - verifyScriptInfoCollection( - session, - host, - expectedScriptInfosWhenNoMap(), - expectedWatchedFilesWhenNoMap(), - ); + verifyScriptInfoCollection(session, host, expectedScriptInfosWhenNoMap(), expectedWatchedFilesWhenNoMap()); }); it(`with depedency files map file, when file is created after actions on projects`, () => { let fileContents: string; @@ -2214,74 +1547,37 @@ ${dependencyTs.content}`); }); host.writeFile(dtsMapLocation, fileContents!); - verifyAllFnAction( - session, - host, - renameFromDependencyTs, - expectedScriptInfos(), - expectedWatchedFiles(), - dependencyMap, - documentPositionMapper, + verifyAllFnAction(session, host, renameFromDependencyTs, expectedScriptInfos(), expectedWatchedFiles(), dependencyMap, documentPositionMapper, /*existingMapEqual*/ false, - /*existingDocumentPositionMapperEqual*/ false - ); + /*existingDocumentPositionMapperEqual*/ false); checkProjects(session); - verifyScriptInfoCollection( - session, - host, - expectedScriptInfos(), - expectedWatchedFiles() - ); + verifyScriptInfoCollection(session, host, expectedScriptInfos(), expectedWatchedFiles()); }); it(`with depedency files map file, when file is deleted after actions on the projects`, () => { const { host, session, dependencyMap, documentPositionMapper } = setupWithAction(); // The dependency file is deleted when orphan files are collected host.deleteFile(dtsMapLocation); - verifyAllFnAction( - session, - host, - renameFromDependencyTs, - expectedScriptInfosWhenNoMap(), - expectedWatchedFilesWhenNoMap(), - dependencyMap, - documentPositionMapper, + verifyAllFnAction(session, host, renameFromDependencyTs, expectedScriptInfosWhenNoMap(), expectedWatchedFilesWhenNoMap(), dependencyMap, documentPositionMapper, /*existingMapEqual*/ false, - /*existingDocumentPositionMapperEqual*/ false - ); + /*existingDocumentPositionMapperEqual*/ false); checkProjects(session); // Script info collection should behave as fileNotPresentKey - verifyScriptInfoCollection( - session, - host, - expectedScriptInfosWhenNoMap(), - expectedWatchedFilesWhenNoMap(), - ); + verifyScriptInfoCollection(session, host, expectedScriptInfosWhenNoMap(), expectedWatchedFilesWhenNoMap()); }); it(`with depedency .d.ts file, when file is not present`, () => { const { host, session } = setup(host => host.deleteFile(dtsLocation)); checkProjects(session); - verifyAllFnAction( - session, - host, - renameFromDependencyTs, - expectedScriptInfosWhenNoDts(), - expectedWatchedFilesWhenNoDts(), + verifyAllFnAction(session, host, renameFromDependencyTs, expectedScriptInfosWhenNoDts(), expectedWatchedFilesWhenNoDts(), /*existingDependencyMap*/ undefined, /*existingDocumentPositionMapper*/ undefined, /*existingMapEqual*/ true, - /*existingDocumentPositionMapperEqual*/ true - ); + /*existingDocumentPositionMapperEqual*/ true); checkProjects(session); - verifyScriptInfoCollection( - session, - host, - expectedScriptInfosWhenNoDts(), - expectedWatchedFilesWhenNoDts(), - ); + verifyScriptInfoCollection(session, host, expectedScriptInfosWhenNoDts(), expectedWatchedFilesWhenNoDts()); }); it(`with depedency .d.ts file, when file is created after actions on projects`, () => { let fileContents: string; @@ -2291,51 +1587,26 @@ ${dependencyTs.content}`); }); host.writeFile(dtsLocation, fileContents!); - verifyAllFnAction( - session, - host, - renameFromDependencyTs, - expectedScriptInfos(), - expectedWatchedFiles(), - dependencyMap, - documentPositionMapper, + verifyAllFnAction(session, host, renameFromDependencyTs, expectedScriptInfos(), expectedWatchedFiles(), dependencyMap, documentPositionMapper, /*existingMapEqual*/ false, - /*existingDocumentPositionMapperEqual*/ false - ); + /*existingDocumentPositionMapperEqual*/ false); checkProjects(session); - verifyScriptInfoCollection( - session, - host, - expectedScriptInfos(), - expectedWatchedFiles() - ); + verifyScriptInfoCollection(session, host, expectedScriptInfos(), expectedWatchedFiles()); }); it(`with depedency .d.ts file, when file is deleted after actions on the projects`, () => { const { host, session, dependencyMap, documentPositionMapper } = setupWithAction(); // The dependency file is deleted when orphan files are collected host.deleteFile(dtsLocation); - verifyAllFnAction( - session, - host, - renameFromDependencyTs, + verifyAllFnAction(session, host, renameFromDependencyTs, // Map is collected after file open - expectedScriptInfosWhenNoDts().concat(dtsMapLocation), - expectedWatchedFilesWhenNoDts().concat(dtsPath), - dependencyMap, - documentPositionMapper, + expectedScriptInfosWhenNoDts().concat(dtsMapLocation), expectedWatchedFilesWhenNoDts().concat(dtsPath), dependencyMap, documentPositionMapper, /*existingMapEqual*/ true, - /*existingDocumentPositionMapperEqual*/ true - ); + /*existingDocumentPositionMapperEqual*/ true); checkProjects(session); // Script info collection should behave as "noDts" - verifyScriptInfoCollection( - session, - host, - expectedScriptInfosWhenNoDts(), - expectedWatchedFilesWhenNoDts(), - ); + verifyScriptInfoCollection(session, host, expectedScriptInfosWhenNoDts(), expectedWatchedFilesWhenNoDts()); }); it(`when defining project source changes, when timeout occurs before request`, () => { @@ -2344,28 +1615,23 @@ ${dependencyTs.content}`); // change // Make change, without rebuild of solution - session.executeCommandSeq({ - command: protocol.CommandTypes.Change, + session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.Change, arguments: { file: dependencyTs.path, line: 1, offset: 1, endLine: 1, endOffset: 1, insertString: `function fooBar() { } -`} +` + } }); host.runQueuedTimeoutCallbacks(); checkProjects(session); verifyDocumentPositionMapperEqual(session, dependencyMap, documentPositionMapper); // action - verifyAllFnAction( - session, - host, - renameFromDependencyTsWithDependencyChange, - expectedScriptInfos(), - expectedWatchedFiles(), + verifyAllFnAction(session, host, renameFromDependencyTsWithDependencyChange, expectedScriptInfos(), expectedWatchedFiles(), /*existingDependencyMap*/ undefined, /*existingDocumentPositionMapper*/ undefined, /*existingMapEqual*/ false, - /*existingDocumentPositionMapperEqual*/ false - ); + /*existingDocumentPositionMapperEqual*/ false); }); it(`when defining project source changes, when timeout does not occur before request`, () => { // Create DocumentPositionMapper @@ -2373,49 +1639,33 @@ ${dependencyTs.content}`); // change // Make change, without rebuild of solution - session.executeCommandSeq({ - command: protocol.CommandTypes.Change, + session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.Change, arguments: { file: dependencyTs.path, line: 1, offset: 1, endLine: 1, endOffset: 1, insertString: `function fooBar() { } -`} +` + } }); // action - verifyAllFnAction( - session, - host, - renameFromDependencyTsWithDependencyChange, - expectedScriptInfos(), - expectedWatchedFiles(), + verifyAllFnAction(session, host, renameFromDependencyTsWithDependencyChange, expectedScriptInfos(), expectedWatchedFiles(), /*existingDependencyMap*/ undefined, /*existingDocumentPositionMapper*/ undefined, /*existingMapEqual*/ false, - /*existingDocumentPositionMapperEqual*/ false - ); + /*existingDocumentPositionMapperEqual*/ false); }); it("when projects are not built", () => { - const host = createServerHost(files); - const session = createSession(host); - openFilesForSession([dependencyTs, randomFile], session); - verifyAllFnAction( - session, - host, - renameFromDependencyTs, - expectedScriptInfosWhenNoDts(), - expectedWatchedFilesWhenNoDts(), + const host = ts.projectSystem.createServerHost(files); + const session = ts.projectSystem.createSession(host); + ts.projectSystem.openFilesForSession([dependencyTs, randomFile], session); + verifyAllFnAction(session, host, renameFromDependencyTs, expectedScriptInfosWhenNoDts(), expectedWatchedFilesWhenNoDts(), /*existingDependencyMap*/ undefined, /*existingDocumentPositionMapper*/ undefined, /*existingMapEqual*/ true, - /*existingDocumentPositionMapperEqual*/ true - ); + /*existingDocumentPositionMapperEqual*/ true); checkProjects(session); - verifyScriptInfoCollection( - session, - host, - expectedScriptInfosWhenNoDts(), - expectedWatchedFilesWhenNoDts(), - ); + verifyScriptInfoCollection(session, host, expectedScriptInfosWhenNoDts(), expectedWatchedFilesWhenNoDts()); }); }); describe("when main tsconfig has disableSourceOfProjectReferenceRedirect along with project reference", () => { @@ -2430,24 +1680,13 @@ ${dependencyTs.content}`); it("rename locations from dependency", () => { const { host, session } = setup(); checkProjects(session); - verifyAllFnAction( - session, - host, - renameFromDependencyTs, - expectedScriptInfos(), - expectedWatchedFiles(), + verifyAllFnAction(session, host, renameFromDependencyTs, expectedScriptInfos(), expectedWatchedFiles(), /*existingDependencyMap*/ undefined, /*existingDocumentPositionMapper*/ undefined, /*existingMapEqual*/ false, - /*existingDocumentPositionMapperEqual*/ false - ); + /*existingDocumentPositionMapperEqual*/ false); checkProjects(session); - verifyScriptInfoCollection( - session, - host, - expectedScriptInfos(), - expectedWatchedFiles(), - ); + verifyScriptInfoCollection(session, host, expectedScriptInfos(), expectedWatchedFiles()); }); // Edit @@ -2462,17 +1701,9 @@ ${dependencyTs.content}`); verifyDocumentPositionMapperEqual(session, dependencyMap, documentPositionMapper); // action - verifyAllFnAction( - session, - host, - renameFromDependencyTs, - expectedScriptInfos(), - expectedWatchedFiles(), - dependencyMap, - documentPositionMapper, - /*existingMapEqual*/ true, - /*existingDocumentPositionMapperEqual*/ true - ); + verifyAllFnAction(session, host, renameFromDependencyTs, expectedScriptInfos(), expectedWatchedFiles(), dependencyMap, documentPositionMapper, + /*existingMapEqual*/ true, + /*existingDocumentPositionMapperEqual*/ true); }); it(`when usage file changes, document position mapper doesnt change, when timeout does not occur before request`, () => { // Create DocumentPositionMapper @@ -2482,17 +1713,9 @@ ${dependencyTs.content}`); makeChangeToDependencyTs(session); // action - verifyAllFnAction( - session, - host, - renameFromDependencyTs, - expectedScriptInfos(), - expectedWatchedFiles(), - dependencyMap, - documentPositionMapper, - /*existingMapEqual*/ true, - /*existingDocumentPositionMapperEqual*/ true - ); + verifyAllFnAction(session, host, renameFromDependencyTs, expectedScriptInfos(), expectedWatchedFiles(), dependencyMap, documentPositionMapper, + /*existingMapEqual*/ true, + /*existingDocumentPositionMapperEqual*/ true); }); // Edit dts to add new fn @@ -2507,17 +1730,9 @@ ${dependencyTs.content}`); verifyDocumentPositionMapperEqual(session, dependencyMap, documentPositionMapper); // action - verifyAllFnAction( - session, - host, - renameFromDependencyTs, - expectedScriptInfos(), - expectedWatchedFiles(), - dependencyMap, - documentPositionMapper, - /*existingMapEqual*/ true, - /*existingDocumentPositionMapperEqual*/ true - ); + verifyAllFnAction(session, host, renameFromDependencyTs, expectedScriptInfos(), expectedWatchedFiles(), dependencyMap, documentPositionMapper, + /*existingMapEqual*/ true, + /*existingDocumentPositionMapperEqual*/ true); }); it(`when dependency .d.ts changes, document position mapper doesnt change, when timeout does not occur before request`, () => { // Create DocumentPositionMapper @@ -2527,17 +1742,9 @@ ${dependencyTs.content}`); changeDtsFile(host); // action - verifyAllFnAction( - session, - host, - renameFromDependencyTs, - expectedScriptInfos(), - expectedWatchedFiles(), - dependencyMap, - documentPositionMapper, - /*existingMapEqual*/ true, - /*existingDocumentPositionMapperEqual*/ true - ); + verifyAllFnAction(session, host, renameFromDependencyTs, expectedScriptInfos(), expectedWatchedFiles(), dependencyMap, documentPositionMapper, + /*existingMapEqual*/ true, + /*existingDocumentPositionMapperEqual*/ true); }); // Edit map file to represent added new line @@ -2552,17 +1759,9 @@ ${dependencyTs.content}`); verifyDocumentPositionMapperEqual(session, dependencyMap, documentPositionMapper); // action - verifyAllFnAction( - session, - host, - renameFromDependencyTs, - expectedScriptInfos(), - expectedWatchedFiles(), - dependencyMap, - documentPositionMapper, - /*existingMapEqual*/ true, - /*existingDocumentPositionMapperEqual*/ false - ); + verifyAllFnAction(session, host, renameFromDependencyTs, expectedScriptInfos(), expectedWatchedFiles(), dependencyMap, documentPositionMapper, + /*existingMapEqual*/ true, + /*existingDocumentPositionMapperEqual*/ false); }); it(`when dependency file's map changes, when timeout does not occur before request`, () => { // Create DocumentPositionMapper @@ -2572,41 +1771,22 @@ ${dependencyTs.content}`); changeDtsMapFile(host); // action - verifyAllFnAction( - session, - host, - renameFromDependencyTs, - expectedScriptInfos(), - expectedWatchedFiles(), - dependencyMap, - documentPositionMapper, - /*existingMapEqual*/ true, - /*existingDocumentPositionMapperEqual*/ false - ); + verifyAllFnAction(session, host, renameFromDependencyTs, expectedScriptInfos(), expectedWatchedFiles(), dependencyMap, documentPositionMapper, + /*existingMapEqual*/ true, + /*existingDocumentPositionMapperEqual*/ false); }); it(`with depedency files map file, when file is not present`, () => { const { host, session } = setup(host => host.deleteFile(dtsMapLocation)); checkProjects(session); - verifyAllFnAction( - session, - host, - renameFromDependencyTs, - expectedScriptInfosWhenNoMap(), - expectedWatchedFilesWhenNoMap(), + verifyAllFnAction(session, host, renameFromDependencyTs, expectedScriptInfosWhenNoMap(), expectedWatchedFilesWhenNoMap(), /*existingDependencyMap*/ undefined, /*existingDocumentPositionMapper*/ undefined, /*existingMapEqual*/ true, - /*existingDocumentPositionMapperEqual*/ true - ); + /*existingDocumentPositionMapperEqual*/ true); checkProjects(session); - verifyScriptInfoCollection( - session, - host, - expectedScriptInfosWhenNoMap(), - expectedWatchedFilesWhenNoMap(), - ); + verifyScriptInfoCollection(session, host, expectedScriptInfosWhenNoMap(), expectedWatchedFilesWhenNoMap()); }); it(`with depedency files map file, when file is created after actions on projects`, () => { let fileContents: string; @@ -2616,74 +1796,37 @@ ${dependencyTs.content}`); }); host.writeFile(dtsMapLocation, fileContents!); - verifyAllFnAction( - session, - host, - renameFromDependencyTs, - expectedScriptInfos(), - expectedWatchedFiles(), - dependencyMap, - documentPositionMapper, + verifyAllFnAction(session, host, renameFromDependencyTs, expectedScriptInfos(), expectedWatchedFiles(), dependencyMap, documentPositionMapper, /*existingMapEqual*/ false, - /*existingDocumentPositionMapperEqual*/ false - ); + /*existingDocumentPositionMapperEqual*/ false); checkProjects(session); - verifyScriptInfoCollection( - session, - host, - expectedScriptInfos(), - expectedWatchedFiles() - ); + verifyScriptInfoCollection(session, host, expectedScriptInfos(), expectedWatchedFiles()); }); it(`with depedency files map file, when file is deleted after actions on the projects`, () => { const { host, session, dependencyMap, documentPositionMapper } = setupWithAction(); // The dependency file is deleted when orphan files are collected host.deleteFile(dtsMapLocation); - verifyAllFnAction( - session, - host, - renameFromDependencyTs, - expectedScriptInfosWhenNoMap(), - expectedWatchedFilesWhenNoMap(), - dependencyMap, - documentPositionMapper, + verifyAllFnAction(session, host, renameFromDependencyTs, expectedScriptInfosWhenNoMap(), expectedWatchedFilesWhenNoMap(), dependencyMap, documentPositionMapper, /*existingMapEqual*/ false, - /*existingDocumentPositionMapperEqual*/ false - ); + /*existingDocumentPositionMapperEqual*/ false); checkProjects(session); // Script info collection should behave as fileNotPresentKey - verifyScriptInfoCollection( - session, - host, - expectedScriptInfosWhenNoMap(), - expectedWatchedFilesWhenNoMap(), - ); + verifyScriptInfoCollection(session, host, expectedScriptInfosWhenNoMap(), expectedWatchedFilesWhenNoMap()); }); it(`with depedency .d.ts file, when file is not present`, () => { const { host, session } = setup(host => host.deleteFile(dtsLocation)); checkProjects(session); - verifyAllFnAction( - session, - host, - renameFromDependencyTs, - expectedScriptInfosWhenNoDts(), - expectedWatchedFilesWhenNoDts(), + verifyAllFnAction(session, host, renameFromDependencyTs, expectedScriptInfosWhenNoDts(), expectedWatchedFilesWhenNoDts(), /*existingDependencyMap*/ undefined, /*existingDocumentPositionMapper*/ undefined, /*existingMapEqual*/ true, - /*existingDocumentPositionMapperEqual*/ true - ); + /*existingDocumentPositionMapperEqual*/ true); checkProjects(session); - verifyScriptInfoCollection( - session, - host, - expectedScriptInfosWhenNoDts(), - expectedWatchedFilesWhenNoDts(), - ); + verifyScriptInfoCollection(session, host, expectedScriptInfosWhenNoDts(), expectedWatchedFilesWhenNoDts()); }); it(`with depedency .d.ts file, when file is created after actions on projects`, () => { let fileContents: string; @@ -2693,51 +1836,26 @@ ${dependencyTs.content}`); }); host.writeFile(dtsLocation, fileContents!); - verifyAllFnAction( - session, - host, - renameFromDependencyTs, - expectedScriptInfos(), - expectedWatchedFiles(), - dependencyMap, - documentPositionMapper, + verifyAllFnAction(session, host, renameFromDependencyTs, expectedScriptInfos(), expectedWatchedFiles(), dependencyMap, documentPositionMapper, /*existingMapEqual*/ false, - /*existingDocumentPositionMapperEqual*/ false - ); + /*existingDocumentPositionMapperEqual*/ false); checkProjects(session); - verifyScriptInfoCollection( - session, - host, - expectedScriptInfos(), - expectedWatchedFiles() - ); + verifyScriptInfoCollection(session, host, expectedScriptInfos(), expectedWatchedFiles()); }); it(`with depedency .d.ts file, when file is deleted after actions on the projects`, () => { const { host, session, dependencyMap, documentPositionMapper } = setupWithAction(); // The dependency file is deleted when orphan files are collected host.deleteFile(dtsLocation); - verifyAllFnAction( - session, - host, - renameFromDependencyTs, + verifyAllFnAction(session, host, renameFromDependencyTs, // Map is collected after file open - expectedScriptInfosWhenNoDts().concat(dtsMapLocation), - expectedWatchedFilesWhenNoDts().concat(dtsPath), - dependencyMap, - documentPositionMapper, + expectedScriptInfosWhenNoDts().concat(dtsMapLocation), expectedWatchedFilesWhenNoDts().concat(dtsPath), dependencyMap, documentPositionMapper, /*existingMapEqual*/ true, - /*existingDocumentPositionMapperEqual*/ true - ); + /*existingDocumentPositionMapperEqual*/ true); checkProjects(session); // Script info collection should behave as "noDts" - verifyScriptInfoCollection( - session, - host, - expectedScriptInfosWhenNoDts(), - expectedWatchedFilesWhenNoDts(), - ); + verifyScriptInfoCollection(session, host, expectedScriptInfosWhenNoDts(), expectedWatchedFilesWhenNoDts()); }); }); }); @@ -2750,12 +1868,7 @@ ${dependencyTs.content}`); return { ...result, ...getDocumentPositionMapper(result.session) }; } - function verifyScriptInfoCollection( - session: TestSession, - host: TestServerHost, - expectedInfos: readonly string[], - expectedWatchedFiles: readonly string[], - ) { + function verifyScriptInfoCollection(session: ts.projectSystem.TestSession, host: ts.projectSystem.TestServerHost, expectedInfos: readonly string[], expectedWatchedFiles: readonly string[]) { return verifyScriptInfoCollectionWith(session, host, [mainTs, dependencyTs], expectedInfos, expectedWatchedFiles); } @@ -2768,24 +1881,24 @@ ${dependencyTs.content}`); return setupWithActionWith(setup, onHostCreate); } - function checkProjects(session: TestSession) { - checkNumberOfProjects(session.getProjectService(), { configuredProjects: 3 }); + function checkProjects(session: ts.projectSystem.TestSession) { + ts.projectSystem.checkNumberOfProjects(session.getProjectService(), { configuredProjects: 3 }); checkMainProjectWithoutProjectReferences(session); checkDependencyProjectWith(session); } - function checkProjectsWithoutDts(session: TestSession) { - checkNumberOfProjects(session.getProjectService(), { configuredProjects: 3 }); + function checkProjectsWithoutDts(session: ts.projectSystem.TestSession) { + ts.projectSystem.checkNumberOfProjects(session.getProjectService(), { configuredProjects: 3 }); checkMainProjectWithoutProjectReferencesWithoutDts(session); checkDependencyProjectWith(session); } function expectedScriptInfosWhenMapped() { - return [mainTs.path, randomFile.path, dependencyTs.path, libFile.path, dtsPath, dtsMapLocation]; + return [mainTs.path, randomFile.path, dependencyTs.path, ts.projectSystem.libFile.path, dtsPath, dtsMapLocation]; } function expectedWatchedFilesWhenMapped() { - return [libFile.path, dtsPath, dtsMapPath, mainConfig.path, randomConfig.path, dependencyConfig.path]; + return [ts.projectSystem.libFile.path, dtsPath, dtsMapPath, mainConfig.path, randomConfig.path, dependencyConfig.path]; } function expectedScriptInfosWhenNoMap() { @@ -2820,36 +1933,17 @@ ${dependencyTs.content}`); it("goto Definition in usage and rename locations from defining project", () => { const { host, session } = setup(); checkProjects(session); - verifyAllFnAction( - session, - host, - goToDefFromMainTs, - expectedScriptInfosWhenMapped(), - expectedWatchedFilesWhenMapped(), + verifyAllFnAction(session, host, goToDefFromMainTs, expectedScriptInfosWhenMapped(), expectedWatchedFilesWhenMapped(), /*existingDependencyMap*/ undefined, /*existingDocumentPositionMapper*/ undefined, /*existingMapEqual*/ false, - /*existingDocumentPositionMapperEqual*/ false - ); + /*existingDocumentPositionMapperEqual*/ false); const { dependencyMap, documentPositionMapper } = getDocumentPositionMapper(session); - verifyAllFnAction( - session, - host, - renameFromDependencyTsWithBothProjectsOpen, - expectedScriptInfosWhenMapped(), - expectedWatchedFilesWhenMapped(), - dependencyMap, - documentPositionMapper, - /*existingMapEqual*/ true, - /*existingDocumentPositionMapperEqual*/ true - ); + verifyAllFnAction(session, host, renameFromDependencyTsWithBothProjectsOpen, expectedScriptInfosWhenMapped(), expectedWatchedFilesWhenMapped(), dependencyMap, documentPositionMapper, + /*existingMapEqual*/ true, + /*existingDocumentPositionMapperEqual*/ true); checkProjects(session); - verifyScriptInfoCollection( - session, - host, - expectedScriptInfosWhenMapped(), - expectedWatchedFilesWhenMapped(), - ); + verifyScriptInfoCollection(session, host, expectedScriptInfosWhenMapped(), expectedWatchedFilesWhenMapped()); }); // Edit @@ -2865,28 +1959,12 @@ ${dependencyTs.content}`); verifyDocumentPositionMapperEqual(session, dependencyMap, documentPositionMapper); // action - verifyAllFnAction( - session, - host, - goToDefFromMainTs, - expectedScriptInfosWhenMapped(), - expectedWatchedFilesWhenMapped(), - dependencyMap, - documentPositionMapper, - /*existingMapEqual*/ true, - /*existingDocumentPositionMapperEqual*/ true - ); - verifyAllFnAction( - session, - host, - renameFromDependencyTsWithBothProjectsOpen, - expectedScriptInfosWhenMapped(), - expectedWatchedFilesWhenMapped(), - dependencyMap, - documentPositionMapper, - /*existingMapEqual*/ true, - /*existingDocumentPositionMapperEqual*/ true - ); + verifyAllFnAction(session, host, goToDefFromMainTs, expectedScriptInfosWhenMapped(), expectedWatchedFilesWhenMapped(), dependencyMap, documentPositionMapper, + /*existingMapEqual*/ true, + /*existingDocumentPositionMapperEqual*/ true); + verifyAllFnAction(session, host, renameFromDependencyTsWithBothProjectsOpen, expectedScriptInfosWhenMapped(), expectedWatchedFilesWhenMapped(), dependencyMap, documentPositionMapper, + /*existingMapEqual*/ true, + /*existingDocumentPositionMapperEqual*/ true); }); it(`when usage file changes, document position mapper doesnt change, when timeout does not occur before request`, () => { // Create DocumentPositionMapper @@ -2897,28 +1975,12 @@ ${dependencyTs.content}`); makeChangeToDependencyTs(session); // action - verifyAllFnAction( - session, - host, - goToDefFromMainTs, - expectedScriptInfosWhenMapped(), - expectedWatchedFilesWhenMapped(), - dependencyMap, - documentPositionMapper, - /*existingMapEqual*/ true, - /*existingDocumentPositionMapperEqual*/ true - ); - verifyAllFnAction( - session, - host, - renameFromDependencyTsWithBothProjectsOpen, - expectedScriptInfosWhenMapped(), - expectedWatchedFilesWhenMapped(), - dependencyMap, - documentPositionMapper, - /*existingMapEqual*/ true, - /*existingDocumentPositionMapperEqual*/ true - ); + verifyAllFnAction(session, host, goToDefFromMainTs, expectedScriptInfosWhenMapped(), expectedWatchedFilesWhenMapped(), dependencyMap, documentPositionMapper, + /*existingMapEqual*/ true, + /*existingDocumentPositionMapperEqual*/ true); + verifyAllFnAction(session, host, renameFromDependencyTsWithBothProjectsOpen, expectedScriptInfosWhenMapped(), expectedWatchedFilesWhenMapped(), dependencyMap, documentPositionMapper, + /*existingMapEqual*/ true, + /*existingDocumentPositionMapperEqual*/ true); }); // Edit dts to add new fn @@ -2933,28 +1995,12 @@ ${dependencyTs.content}`); verifyDocumentPositionMapperEqual(session, dependencyMap, documentPositionMapper); // action - verifyAllFnAction( - session, - host, - goToDefFromMainTs, - expectedScriptInfosWhenMapped(), - expectedWatchedFilesWhenMapped(), - dependencyMap, - documentPositionMapper, - /*existingMapEqual*/ true, - /*existingDocumentPositionMapperEqual*/ true - ); - verifyAllFnAction( - session, - host, - renameFromDependencyTsWithBothProjectsOpen, - expectedScriptInfosWhenMapped(), - expectedWatchedFilesWhenMapped(), - dependencyMap, - documentPositionMapper, - /*existingMapEqual*/ true, - /*existingDocumentPositionMapperEqual*/ true - ); + verifyAllFnAction(session, host, goToDefFromMainTs, expectedScriptInfosWhenMapped(), expectedWatchedFilesWhenMapped(), dependencyMap, documentPositionMapper, + /*existingMapEqual*/ true, + /*existingDocumentPositionMapperEqual*/ true); + verifyAllFnAction(session, host, renameFromDependencyTsWithBothProjectsOpen, expectedScriptInfosWhenMapped(), expectedWatchedFilesWhenMapped(), dependencyMap, documentPositionMapper, + /*existingMapEqual*/ true, + /*existingDocumentPositionMapperEqual*/ true); }); it(`when dependency .d.ts changes, document position mapper doesnt change, when timeout does not occur before request`, () => { // Create DocumentPositionMapper @@ -2964,28 +2010,12 @@ ${dependencyTs.content}`); changeDtsFile(host); // action - verifyAllFnAction( - session, - host, - goToDefFromMainTs, - expectedScriptInfosWhenMapped(), - expectedWatchedFilesWhenMapped(), - dependencyMap, - documentPositionMapper, - /*existingMapEqual*/ true, - /*existingDocumentPositionMapperEqual*/ true - ); - verifyAllFnAction( - session, - host, - renameFromDependencyTsWithBothProjectsOpen, - expectedScriptInfosWhenMapped(), - expectedWatchedFilesWhenMapped(), - dependencyMap, - documentPositionMapper, - /*existingMapEqual*/ true, - /*existingDocumentPositionMapperEqual*/ true - ); + verifyAllFnAction(session, host, goToDefFromMainTs, expectedScriptInfosWhenMapped(), expectedWatchedFilesWhenMapped(), dependencyMap, documentPositionMapper, + /*existingMapEqual*/ true, + /*existingDocumentPositionMapperEqual*/ true); + verifyAllFnAction(session, host, renameFromDependencyTsWithBothProjectsOpen, expectedScriptInfosWhenMapped(), expectedWatchedFilesWhenMapped(), dependencyMap, documentPositionMapper, + /*existingMapEqual*/ true, + /*existingDocumentPositionMapperEqual*/ true); }); // Edit map file to represent added new line @@ -3000,29 +2030,13 @@ ${dependencyTs.content}`); verifyDocumentPositionMapperEqual(session, dependencyMap, documentPositionMapper); // action - verifyAllFnAction( - session, - host, - goToDefFromMainTs, - expectedScriptInfosWhenMapped(), - expectedWatchedFilesWhenMapped(), - dependencyMap, - documentPositionMapper, - /*existingMapEqual*/ true, - /*existingDocumentPositionMapperEqual*/ false - ); + verifyAllFnAction(session, host, goToDefFromMainTs, expectedScriptInfosWhenMapped(), expectedWatchedFilesWhenMapped(), dependencyMap, documentPositionMapper, + /*existingMapEqual*/ true, + /*existingDocumentPositionMapperEqual*/ false); const { documentPositionMapper: newDocumentPositionMapper } = getDocumentPositionMapper(session); - verifyAllFnAction( - session, - host, - renameFromDependencyTsWithBothProjectsOpen, - expectedScriptInfosWhenMapped(), - expectedWatchedFilesWhenMapped(), - dependencyMap, - newDocumentPositionMapper, - /*existingMapEqual*/ true, - /*existingDocumentPositionMapperEqual*/ true - ); + verifyAllFnAction(session, host, renameFromDependencyTsWithBothProjectsOpen, expectedScriptInfosWhenMapped(), expectedWatchedFilesWhenMapped(), dependencyMap, newDocumentPositionMapper, + /*existingMapEqual*/ true, + /*existingDocumentPositionMapperEqual*/ true); }); it(`when dependency file's map changes, when timeout does not occur before request`, () => { // Create DocumentPositionMapper @@ -3032,64 +2046,31 @@ ${dependencyTs.content}`); changeDtsMapFile(host); // action - verifyAllFnAction( - session, - host, - goToDefFromMainTs, - expectedScriptInfosWhenMapped(), - expectedWatchedFilesWhenMapped(), - dependencyMap, - documentPositionMapper, - /*existingMapEqual*/ true, - /*existingDocumentPositionMapperEqual*/ false - ); + verifyAllFnAction(session, host, goToDefFromMainTs, expectedScriptInfosWhenMapped(), expectedWatchedFilesWhenMapped(), dependencyMap, documentPositionMapper, + /*existingMapEqual*/ true, + /*existingDocumentPositionMapperEqual*/ false); const { documentPositionMapper: newDocumentPositionMapper } = getDocumentPositionMapper(session); - verifyAllFnAction( - session, - host, - renameFromDependencyTsWithBothProjectsOpen, - expectedScriptInfosWhenMapped(), - expectedWatchedFilesWhenMapped(), - dependencyMap, - newDocumentPositionMapper, - /*existingMapEqual*/ true, - /*existingDocumentPositionMapperEqual*/ true - ); + verifyAllFnAction(session, host, renameFromDependencyTsWithBothProjectsOpen, expectedScriptInfosWhenMapped(), expectedWatchedFilesWhenMapped(), dependencyMap, newDocumentPositionMapper, + /*existingMapEqual*/ true, + /*existingDocumentPositionMapperEqual*/ true); }); it(`with depedency files map file, when file is not present`, () => { const { host, session } = setup(host => host.deleteFile(dtsMapLocation)); checkProjects(session); - verifyAllFnAction( - session, - host, - goToDefFromMainTsWithNoMap, - expectedScriptInfosWhenNoMap(), - expectedWatchedFilesWhenNoMap(), + verifyAllFnAction(session, host, goToDefFromMainTsWithNoMap, expectedScriptInfosWhenNoMap(), expectedWatchedFilesWhenNoMap(), /*existingDependencyMap*/ undefined, /*existingDocumentPositionMapper*/ undefined, /*existingMapEqual*/ true, - /*existingDocumentPositionMapperEqual*/ true - ); - verifyAllFnAction( - session, - host, - renameFromDependencyTs, - expectedScriptInfosWhenNoMap(), - expectedWatchedFilesWhenNoMap(), + /*existingDocumentPositionMapperEqual*/ true); + verifyAllFnAction(session, host, renameFromDependencyTs, expectedScriptInfosWhenNoMap(), expectedWatchedFilesWhenNoMap(), /*existingDependencyMap*/ undefined, /*existingDocumentPositionMapper*/ undefined, /*existingMapEqual*/ true, - /*existingDocumentPositionMapperEqual*/ true - ); + /*existingDocumentPositionMapperEqual*/ true); checkProjects(session); - verifyScriptInfoCollection( - session, - host, - expectedScriptInfosWhenNoMap(), - expectedWatchedFilesWhenNoMap(), - ); + verifyScriptInfoCollection(session, host, expectedScriptInfosWhenNoMap(), expectedWatchedFilesWhenNoMap()); }); it(`with depedency files map file, when file is created after actions on projects`, () => { let fileContents: string; @@ -3099,109 +2080,50 @@ ${dependencyTs.content}`); }); host.writeFile(dtsMapLocation, fileContents!); - verifyAllFnAction( - session, - host, - goToDefFromMainTs, - expectedScriptInfosWhenMapped(), - expectedWatchedFilesWhenMapped(), - dependencyMap, - documentPositionMapper, + verifyAllFnAction(session, host, goToDefFromMainTs, expectedScriptInfosWhenMapped(), expectedWatchedFilesWhenMapped(), dependencyMap, documentPositionMapper, /*existingMapEqual*/ false, - /*existingDocumentPositionMapperEqual*/ false - ); + /*existingDocumentPositionMapperEqual*/ false); const { dependencyMap: newDependencyMap, documentPositionMapper: newDocumentPositionMapper } = getDocumentPositionMapper(session); - verifyAllFnAction( - session, - host, - renameFromDependencyTsWithBothProjectsOpen, - expectedScriptInfosWhenMapped(), - expectedWatchedFilesWhenMapped(), - newDependencyMap, - newDocumentPositionMapper, - /*existingMapEqual*/ true, - /*existingDocumentPositionMapperEqual*/ true - ); + verifyAllFnAction(session, host, renameFromDependencyTsWithBothProjectsOpen, expectedScriptInfosWhenMapped(), expectedWatchedFilesWhenMapped(), newDependencyMap, newDocumentPositionMapper, + /*existingMapEqual*/ true, + /*existingDocumentPositionMapperEqual*/ true); checkProjects(session); - verifyScriptInfoCollection( - session, - host, - expectedScriptInfosWhenMapped(), - expectedWatchedFilesWhenMapped() - ); + verifyScriptInfoCollection(session, host, expectedScriptInfosWhenMapped(), expectedWatchedFilesWhenMapped()); }); it(`with depedency files map file, when file is deleted after actions on the projects`, () => { const { host, session, dependencyMap, documentPositionMapper } = setupWithAction(); // The dependency file is deleted when orphan files are collected host.deleteFile(dtsMapLocation); - verifyAllFnAction( - session, - host, - goToDefFromMainTsWithNoMap, - expectedScriptInfosWhenNoMap(), - expectedWatchedFilesWhenNoMap(), - dependencyMap, - documentPositionMapper, + verifyAllFnAction(session, host, goToDefFromMainTsWithNoMap, expectedScriptInfosWhenNoMap(), expectedWatchedFilesWhenNoMap(), dependencyMap, documentPositionMapper, /*existingMapEqual*/ false, - /*existingDocumentPositionMapperEqual*/ false - ); + /*existingDocumentPositionMapperEqual*/ false); const { dependencyMap: newDependencyMap, documentPositionMapper: newDocumentPositionMapper } = getDocumentPositionMapper(session); - verifyAllFnAction( - session, - host, - renameFromDependencyTs, - expectedScriptInfosWhenNoMap(), - expectedWatchedFilesWhenNoMap(), - newDependencyMap, - newDocumentPositionMapper, - /*existingMapEqual*/ true, - /*existingDocumentPositionMapperEqual*/ true - ); + verifyAllFnAction(session, host, renameFromDependencyTs, expectedScriptInfosWhenNoMap(), expectedWatchedFilesWhenNoMap(), newDependencyMap, newDocumentPositionMapper, + /*existingMapEqual*/ true, + /*existingDocumentPositionMapperEqual*/ true); checkProjects(session); // Script info collection should behave as fileNotPresentKey - verifyScriptInfoCollection( - session, - host, - expectedScriptInfosWhenNoMap(), - expectedWatchedFilesWhenNoMap(), - ); + verifyScriptInfoCollection(session, host, expectedScriptInfosWhenNoMap(), expectedWatchedFilesWhenNoMap()); }); it(`with depedency .d.ts file, when file is not present`, () => { const { host, session } = setup(host => host.deleteFile(dtsLocation)); checkProjectsWithoutDts(session); - verifyAllFnAction( - session, - host, - goToDefFromMainTsWithNoDts, - expectedScriptInfosAfterGotoDefWhenNoDts(), - expectedWatchedFilesAfterGotoDefWhenNoDts(), + verifyAllFnAction(session, host, goToDefFromMainTsWithNoDts, expectedScriptInfosAfterGotoDefWhenNoDts(), expectedWatchedFilesAfterGotoDefWhenNoDts(), /*existingDependencyMap*/ undefined, /*existingDocumentPositionMapper*/ undefined, /*existingMapEqual*/ true, - /*existingDocumentPositionMapperEqual*/ true - ); - verifyAllFnAction( - session, - host, - renameFromDependencyTs, - expectedScriptInfosAfterRenameWhenNoDts(), - expectedWatchedFilesAfterRenameWhenNoDts(), + /*existingDocumentPositionMapperEqual*/ true); + verifyAllFnAction(session, host, renameFromDependencyTs, expectedScriptInfosAfterRenameWhenNoDts(), expectedWatchedFilesAfterRenameWhenNoDts(), /*existingDependencyMap*/ undefined, /*existingDocumentPositionMapper*/ undefined, /*existingMapEqual*/ true, - /*existingDocumentPositionMapperEqual*/ true - ); + /*existingDocumentPositionMapperEqual*/ true); checkProjectsWithoutDts(session); - verifyScriptInfoCollection( - session, - host, - expectedScriptInfosAfterRenameWhenNoDts(), - expectedWatchedFilesAfterRenameWhenNoDts(), - ); + verifyScriptInfoCollection(session, host, expectedScriptInfosAfterRenameWhenNoDts(), expectedWatchedFilesAfterRenameWhenNoDts()); }); it(`with depedency .d.ts file, when file is created after actions on projects`, () => { let fileContents: string; @@ -3211,75 +2133,35 @@ ${dependencyTs.content}`); }); host.writeFile(dtsLocation, fileContents!); - verifyAllFnAction( - session, - host, - goToDefFromMainTs, - expectedScriptInfosWhenMapped(), - expectedWatchedFilesWhenMapped(), - dependencyMap, - documentPositionMapper, + verifyAllFnAction(session, host, goToDefFromMainTs, expectedScriptInfosWhenMapped(), expectedWatchedFilesWhenMapped(), dependencyMap, documentPositionMapper, /*existingMapEqual*/ false, - /*existingDocumentPositionMapperEqual*/ false - ); + /*existingDocumentPositionMapperEqual*/ false); const { dependencyMap: newDependencyMap, documentPositionMapper: newDocumentPositionMapper } = getDocumentPositionMapper(session); - verifyAllFnAction( - session, - host, - renameFromDependencyTsWithBothProjectsOpen, - expectedScriptInfosWhenMapped(), - expectedWatchedFilesWhenMapped(), - newDependencyMap, - newDocumentPositionMapper, - /*existingMapEqual*/ true, - /*existingDocumentPositionMapperEqual*/ true - ); + verifyAllFnAction(session, host, renameFromDependencyTsWithBothProjectsOpen, expectedScriptInfosWhenMapped(), expectedWatchedFilesWhenMapped(), newDependencyMap, newDocumentPositionMapper, + /*existingMapEqual*/ true, + /*existingDocumentPositionMapperEqual*/ true); checkProjects(session); - verifyScriptInfoCollection( - session, - host, - expectedScriptInfosWhenMapped(), - expectedWatchedFilesWhenMapped() - ); + verifyScriptInfoCollection(session, host, expectedScriptInfosWhenMapped(), expectedWatchedFilesWhenMapped()); }); it(`with depedency .d.ts file, when file is deleted after actions on the projects`, () => { const { host, session, dependencyMap, documentPositionMapper } = setupWithAction(); // The dependency file is deleted when orphan files are collected host.deleteFile(dtsLocation); - verifyAllFnAction( - session, - host, - goToDefFromMainTsWithNoDts, + verifyAllFnAction(session, host, goToDefFromMainTsWithNoDts, // The script info for map is collected only after file open - expectedScriptInfosAfterGotoDefWhenNoDts().concat(dtsMapLocation), - expectedWatchedFilesAfterGotoDefWhenNoDts().concat(dtsMapPath), - dependencyMap, - documentPositionMapper, - /*existingMapEqual*/ true, - /*existingDocumentPositionMapperEqual*/ true - ); - verifyAllFnAction( - session, - host, - renameFromDependencyTs, + expectedScriptInfosAfterGotoDefWhenNoDts().concat(dtsMapLocation), expectedWatchedFilesAfterGotoDefWhenNoDts().concat(dtsMapPath), dependencyMap, documentPositionMapper, + /*existingMapEqual*/ true, + /*existingDocumentPositionMapperEqual*/ true); + verifyAllFnAction(session, host, renameFromDependencyTs, // The script info for map is collected only after file open - expectedScriptInfosAfterRenameWhenNoDts().concat(dtsMapLocation), - expectedWatchedFilesAfterRenameWhenNoDts().concat(dtsMapPath), - dependencyMap, - documentPositionMapper, + expectedScriptInfosAfterRenameWhenNoDts().concat(dtsMapLocation), expectedWatchedFilesAfterRenameWhenNoDts().concat(dtsMapPath), dependencyMap, documentPositionMapper, /*existingMapEqual*/ true, - /*existingDocumentPositionMapperEqual*/ true - ); + /*existingDocumentPositionMapperEqual*/ true); checkProjectsWithoutDts(session); // Script info collection should behave as "noDts" - verifyScriptInfoCollection( - session, - host, - expectedScriptInfosAfterRenameWhenNoDts(), - expectedWatchedFilesAfterRenameWhenNoDts(), - ); + verifyScriptInfoCollection(session, host, expectedScriptInfosAfterRenameWhenNoDts(), expectedWatchedFilesAfterRenameWhenNoDts()); }); }); describe("when main tsconfig has project reference", () => { @@ -3291,18 +2173,18 @@ ${dependencyTs.content}`); return setupWithActionWith(setup, onHostCreate); } - function checkProjects(session: TestSession) { - checkNumberOfProjects(session.getProjectService(), { configuredProjects: 3 }); + function checkProjects(session: ts.projectSystem.TestSession) { + ts.projectSystem.checkNumberOfProjects(session.getProjectService(), { configuredProjects: 3 }); checkMainProjectWithProjectReferences(session); checkDependencyProjectWith(session); } function expectedScriptInfosAfterGotoDef() { - return [dependencyTs.path, libFile.path, mainTs.path, randomFile.path]; + return [dependencyTs.path, ts.projectSystem.libFile.path, mainTs.path, randomFile.path]; } function expectedWatchedFilesAfterGotoDef() { - return [dependencyConfig.path, libFile.path, mainConfig.path, randomConfig.path]; + return [dependencyConfig.path, ts.projectSystem.libFile.path, mainConfig.path, randomConfig.path]; } function expectedScriptInfosAfterRenameWhenMapped() { @@ -3336,35 +2218,18 @@ ${dependencyTs.content}`); it("goto Definition in usage and rename locations from defining project", () => { const { host, session } = setup(); checkProjects(session); - verifyAllFnAction( - session, - host, - goToDefFromMainTs, - expectedScriptInfosAfterGotoDef(), - expectedWatchedFilesAfterGotoDef(), + verifyAllFnAction(session, host, goToDefFromMainTs, expectedScriptInfosAfterGotoDef(), expectedWatchedFilesAfterGotoDef(), /*existingDependencyMap*/ undefined, /*existingDocumentPositionMapper*/ undefined, /*existingMapEqual*/ true, - /*existingDocumentPositionMapperEqual*/ true - ); - verifyAllFnAction( - session, - host, - renameFromDependencyTsWithBothProjectsOpen, - expectedScriptInfosAfterRenameWhenMapped(), - expectedWatchedFilesAfterRenameWhenMapped(), + /*existingDocumentPositionMapperEqual*/ true); + verifyAllFnAction(session, host, renameFromDependencyTsWithBothProjectsOpen, expectedScriptInfosAfterRenameWhenMapped(), expectedWatchedFilesAfterRenameWhenMapped(), /*existingDependencyMap*/ undefined, /*existingDocumentPositionMapper*/ undefined, /*existingMapEqual*/ false, - /*existingDocumentPositionMapperEqual*/ false - ); + /*existingDocumentPositionMapperEqual*/ false); checkProjects(session); - verifyScriptInfoCollection( - session, - host, - expectedScriptInfosAfterRenameWhenMapped(), - expectedWatchedFilesAfterRenameWhenMapped(), - ); + verifyScriptInfoCollection(session, host, expectedScriptInfosAfterRenameWhenMapped(), expectedWatchedFilesAfterRenameWhenMapped()); }); // Edit @@ -3380,28 +2245,12 @@ ${dependencyTs.content}`); verifyDocumentPositionMapperEqual(session, dependencyMap, documentPositionMapper); // action - verifyAllFnAction( - session, - host, - goToDefFromMainTs, - expectedScriptInfosAfterRenameWhenMapped(), - expectedWatchedFilesAfterRenameWhenMapped(), - dependencyMap, - documentPositionMapper, - /*existingMapEqual*/ true, - /*existingDocumentPositionMapperEqual*/ true - ); - verifyAllFnAction( - session, - host, - renameFromDependencyTsWithBothProjectsOpen, - expectedScriptInfosAfterRenameWhenMapped(), - expectedWatchedFilesAfterRenameWhenMapped(), - dependencyMap, - documentPositionMapper, - /*existingMapEqual*/ true, - /*existingDocumentPositionMapperEqual*/ true - ); + verifyAllFnAction(session, host, goToDefFromMainTs, expectedScriptInfosAfterRenameWhenMapped(), expectedWatchedFilesAfterRenameWhenMapped(), dependencyMap, documentPositionMapper, + /*existingMapEqual*/ true, + /*existingDocumentPositionMapperEqual*/ true); + verifyAllFnAction(session, host, renameFromDependencyTsWithBothProjectsOpen, expectedScriptInfosAfterRenameWhenMapped(), expectedWatchedFilesAfterRenameWhenMapped(), dependencyMap, documentPositionMapper, + /*existingMapEqual*/ true, + /*existingDocumentPositionMapperEqual*/ true); }); it(`when usage file changes, document position mapper doesnt change, when timeout does not occur before request`, () => { // Create DocumentPositionMapper @@ -3412,28 +2261,12 @@ ${dependencyTs.content}`); makeChangeToDependencyTs(session); // action - verifyAllFnAction( - session, - host, - goToDefFromMainTs, - expectedScriptInfosAfterRenameWhenMapped(), - expectedWatchedFilesAfterRenameWhenMapped(), - dependencyMap, - documentPositionMapper, - /*existingMapEqual*/ true, - /*existingDocumentPositionMapperEqual*/ true - ); - verifyAllFnAction( - session, - host, - renameFromDependencyTsWithBothProjectsOpen, - expectedScriptInfosAfterRenameWhenMapped(), - expectedWatchedFilesAfterRenameWhenMapped(), - dependencyMap, - documentPositionMapper, - /*existingMapEqual*/ true, - /*existingDocumentPositionMapperEqual*/ true - ); + verifyAllFnAction(session, host, goToDefFromMainTs, expectedScriptInfosAfterRenameWhenMapped(), expectedWatchedFilesAfterRenameWhenMapped(), dependencyMap, documentPositionMapper, + /*existingMapEqual*/ true, + /*existingDocumentPositionMapperEqual*/ true); + verifyAllFnAction(session, host, renameFromDependencyTsWithBothProjectsOpen, expectedScriptInfosAfterRenameWhenMapped(), expectedWatchedFilesAfterRenameWhenMapped(), dependencyMap, documentPositionMapper, + /*existingMapEqual*/ true, + /*existingDocumentPositionMapperEqual*/ true); }); // Edit dts to add new fn @@ -3448,28 +2281,12 @@ ${dependencyTs.content}`); verifyDocumentPositionMapperEqual(session, dependencyMap, documentPositionMapper); // action - verifyAllFnAction( - session, - host, - goToDefFromMainTs, - expectedScriptInfosAfterRenameWhenMapped(), - expectedWatchedFilesAfterRenameWhenMapped(), - dependencyMap, - documentPositionMapper, - /*existingMapEqual*/ true, - /*existingDocumentPositionMapperEqual*/ true - ); - verifyAllFnAction( - session, - host, - renameFromDependencyTsWithBothProjectsOpen, - expectedScriptInfosAfterRenameWhenMapped(), - expectedWatchedFilesAfterRenameWhenMapped(), - dependencyMap, - documentPositionMapper, - /*existingMapEqual*/ true, - /*existingDocumentPositionMapperEqual*/ true - ); + verifyAllFnAction(session, host, goToDefFromMainTs, expectedScriptInfosAfterRenameWhenMapped(), expectedWatchedFilesAfterRenameWhenMapped(), dependencyMap, documentPositionMapper, + /*existingMapEqual*/ true, + /*existingDocumentPositionMapperEqual*/ true); + verifyAllFnAction(session, host, renameFromDependencyTsWithBothProjectsOpen, expectedScriptInfosAfterRenameWhenMapped(), expectedWatchedFilesAfterRenameWhenMapped(), dependencyMap, documentPositionMapper, + /*existingMapEqual*/ true, + /*existingDocumentPositionMapperEqual*/ true); }); it(`when dependency .d.ts changes, document position mapper doesnt change, when timeout does not occur before request`, () => { // Create DocumentPositionMapper @@ -3479,28 +2296,12 @@ ${dependencyTs.content}`); changeDtsFile(host); // action - verifyAllFnAction( - session, - host, - goToDefFromMainTs, - expectedScriptInfosAfterRenameWhenMapped(), - expectedWatchedFilesAfterRenameWhenMapped(), - dependencyMap, - documentPositionMapper, - /*existingMapEqual*/ true, - /*existingDocumentPositionMapperEqual*/ true - ); - verifyAllFnAction( - session, - host, - renameFromDependencyTsWithBothProjectsOpen, - expectedScriptInfosAfterRenameWhenMapped(), - expectedWatchedFilesAfterRenameWhenMapped(), - dependencyMap, - documentPositionMapper, - /*existingMapEqual*/ true, - /*existingDocumentPositionMapperEqual*/ true - ); + verifyAllFnAction(session, host, goToDefFromMainTs, expectedScriptInfosAfterRenameWhenMapped(), expectedWatchedFilesAfterRenameWhenMapped(), dependencyMap, documentPositionMapper, + /*existingMapEqual*/ true, + /*existingDocumentPositionMapperEqual*/ true); + verifyAllFnAction(session, host, renameFromDependencyTsWithBothProjectsOpen, expectedScriptInfosAfterRenameWhenMapped(), expectedWatchedFilesAfterRenameWhenMapped(), dependencyMap, documentPositionMapper, + /*existingMapEqual*/ true, + /*existingDocumentPositionMapperEqual*/ true); }); // Edit map file to represent added new line @@ -3515,28 +2316,12 @@ ${dependencyTs.content}`); verifyDocumentPositionMapperEqual(session, dependencyMap, documentPositionMapper); // action - verifyAllFnAction( - session, - host, - goToDefFromMainTs, - expectedScriptInfosAfterRenameWhenMapped(), - expectedWatchedFilesAfterRenameWhenMapped(), - dependencyMap, - documentPositionMapper, - /*existingMapEqual*/ true, - /*existingDocumentPositionMapperEqual*/ true - ); - verifyAllFnAction( - session, - host, - renameFromDependencyTsWithBothProjectsOpen, - expectedScriptInfosAfterRenameWhenMapped(), - expectedWatchedFilesAfterRenameWhenMapped(), - dependencyMap, - documentPositionMapper, - /*existingMapEqual*/ true, - /*existingDocumentPositionMapperEqual*/ false - ); + verifyAllFnAction(session, host, goToDefFromMainTs, expectedScriptInfosAfterRenameWhenMapped(), expectedWatchedFilesAfterRenameWhenMapped(), dependencyMap, documentPositionMapper, + /*existingMapEqual*/ true, + /*existingDocumentPositionMapperEqual*/ true); + verifyAllFnAction(session, host, renameFromDependencyTsWithBothProjectsOpen, expectedScriptInfosAfterRenameWhenMapped(), expectedWatchedFilesAfterRenameWhenMapped(), dependencyMap, documentPositionMapper, + /*existingMapEqual*/ true, + /*existingDocumentPositionMapperEqual*/ false); }); it(`when dependency file's map changes, when timeout does not occur before request`, () => { // Create DocumentPositionMapper @@ -3546,63 +2331,30 @@ ${dependencyTs.content}`); changeDtsMapFile(host); // action - verifyAllFnAction( - session, - host, - goToDefFromMainTs, - expectedScriptInfosAfterRenameWhenMapped(), - expectedWatchedFilesAfterRenameWhenMapped(), - dependencyMap, - documentPositionMapper, - /*existingMapEqual*/ true, - /*existingDocumentPositionMapperEqual*/ true - ); - verifyAllFnAction( - session, - host, - renameFromDependencyTsWithBothProjectsOpen, - expectedScriptInfosAfterRenameWhenMapped(), - expectedWatchedFilesAfterRenameWhenMapped(), - dependencyMap, - documentPositionMapper, - /*existingMapEqual*/ true, - /*existingDocumentPositionMapperEqual*/ false - ); + verifyAllFnAction(session, host, goToDefFromMainTs, expectedScriptInfosAfterRenameWhenMapped(), expectedWatchedFilesAfterRenameWhenMapped(), dependencyMap, documentPositionMapper, + /*existingMapEqual*/ true, + /*existingDocumentPositionMapperEqual*/ true); + verifyAllFnAction(session, host, renameFromDependencyTsWithBothProjectsOpen, expectedScriptInfosAfterRenameWhenMapped(), expectedWatchedFilesAfterRenameWhenMapped(), dependencyMap, documentPositionMapper, + /*existingMapEqual*/ true, + /*existingDocumentPositionMapperEqual*/ false); }); it(`with depedency files map file, when file is not present`, () => { const { host, session } = setup(host => host.deleteFile(dtsMapLocation)); checkProjects(session); - verifyAllFnAction( - session, - host, - goToDefFromMainTs, - expectedScriptInfosAfterGotoDef(), - expectedWatchedFilesAfterGotoDef(), + verifyAllFnAction(session, host, goToDefFromMainTs, expectedScriptInfosAfterGotoDef(), expectedWatchedFilesAfterGotoDef(), /*existingDependencyMap*/ undefined, /*existingDocumentPositionMapper*/ undefined, /*existingMapEqual*/ true, - /*existingDocumentPositionMapperEqual*/ true - ); - verifyAllFnAction( - session, - host, - renameFromDependencyTsWithBothProjectsOpen, - expectedScriptInfosAfterRenameWhenNoMap(), - expectedWatchedFilesAfterRenameWhenNoMap(), + /*existingDocumentPositionMapperEqual*/ true); + verifyAllFnAction(session, host, renameFromDependencyTsWithBothProjectsOpen, expectedScriptInfosAfterRenameWhenNoMap(), expectedWatchedFilesAfterRenameWhenNoMap(), /*existingDependencyMap*/ undefined, /*existingDocumentPositionMapper*/ undefined, /*existingMapEqual*/ true, - /*existingDocumentPositionMapperEqual*/ true - ); + /*existingDocumentPositionMapperEqual*/ true); checkProjects(session); - verifyScriptInfoCollection( - session, - host, - expectedScriptInfosAfterRenameWhenNoMap(), - expectedWatchedFilesAfterRenameWhenNoMap(), - ); + verifyScriptInfoCollection(session, host, expectedScriptInfosAfterRenameWhenNoMap(), expectedWatchedFilesAfterRenameWhenNoMap()); }); it(`with depedency files map file, when file is created after actions on projects`, () => { let fileContents: string; @@ -3612,111 +2364,54 @@ ${dependencyTs.content}`); }); host.writeFile(dtsMapLocation, fileContents!); - verifyAllFnAction( - session, - host, - goToDefFromMainTs, - expectedScriptInfosAfterRenameWhenNoMap(), + verifyAllFnAction(session, host, goToDefFromMainTs, expectedScriptInfosAfterRenameWhenNoMap(), // Map file is reset so its not watched any more, as this action doesnt need map - removePath(expectedWatchedFilesAfterRenameWhenNoMap(), dtsMapPath), - dependencyMap, - documentPositionMapper, + removePath(expectedWatchedFilesAfterRenameWhenNoMap(), dtsMapPath), dependencyMap, documentPositionMapper, /*existingMapEqual*/ true, /*existingDocumentPositionMapperEqual*/ true, - /*skipMapPathInDtsInfo*/ true - ); - verifyAllFnAction( - session, - host, - renameFromDependencyTsWithBothProjectsOpen, - expectedScriptInfosAfterRenameWhenMapped(), - expectedWatchedFilesAfterRenameWhenMapped(), - dependencyMap, - documentPositionMapper, + /*skipMapPathInDtsInfo*/ true); + verifyAllFnAction(session, host, renameFromDependencyTsWithBothProjectsOpen, expectedScriptInfosAfterRenameWhenMapped(), expectedWatchedFilesAfterRenameWhenMapped(), dependencyMap, documentPositionMapper, /*existingMapEqual*/ false, - /*existingDocumentPositionMapperEqual*/ false - ); + /*existingDocumentPositionMapperEqual*/ false); checkProjects(session); - verifyScriptInfoCollection( - session, - host, - expectedScriptInfosAfterRenameWhenMapped(), - expectedWatchedFilesAfterRenameWhenMapped(), - ); + verifyScriptInfoCollection(session, host, expectedScriptInfosAfterRenameWhenMapped(), expectedWatchedFilesAfterRenameWhenMapped()); }); it(`with depedency files map file, when file is deleted after actions on the projects`, () => { const { host, session, dependencyMap, documentPositionMapper } = setupWithAction(); // The dependency file is deleted when orphan files are collected host.deleteFile(dtsMapLocation); - verifyAllFnAction( - session, - host, - goToDefFromMainTs, - expectedScriptInfosAfterRenameWhenNoMap(), + verifyAllFnAction(session, host, goToDefFromMainTs, expectedScriptInfosAfterRenameWhenNoMap(), // Map file is reset so its not watched any more, as this action doesnt need map - removePath(expectedWatchedFilesAfterRenameWhenNoMap(), dtsMapPath), - dependencyMap, - documentPositionMapper, + removePath(expectedWatchedFilesAfterRenameWhenNoMap(), dtsMapPath), dependencyMap, documentPositionMapper, /*existingMapEqual*/ false, /*existingDocumentPositionMapperEqual*/ false, - /*skipMapPathInDtsInfo*/ true - ); - verifyAllFnAction( - session, - host, - renameFromDependencyTsWithBothProjectsOpen, - expectedScriptInfosAfterRenameWhenNoMap(), - expectedWatchedFilesAfterRenameWhenNoMap(), - dependencyMap, - documentPositionMapper, + /*skipMapPathInDtsInfo*/ true); + verifyAllFnAction(session, host, renameFromDependencyTsWithBothProjectsOpen, expectedScriptInfosAfterRenameWhenNoMap(), expectedWatchedFilesAfterRenameWhenNoMap(), dependencyMap, documentPositionMapper, /*existingMapEqual*/ false, - /*existingDocumentPositionMapperEqual*/ false - ); + /*existingDocumentPositionMapperEqual*/ false); checkProjects(session); // Script info collection should behave as fileNotPresentKey - verifyScriptInfoCollection( - session, - host, - expectedScriptInfosAfterRenameWhenNoMap(), - expectedWatchedFilesAfterRenameWhenNoMap(), - ); + verifyScriptInfoCollection(session, host, expectedScriptInfosAfterRenameWhenNoMap(), expectedWatchedFilesAfterRenameWhenNoMap()); }); it(`with depedency .d.ts file, when file is not present`, () => { const { host, session } = setup(host => host.deleteFile(dtsLocation)); checkProjects(session); - verifyAllFnAction( - session, - host, - goToDefFromMainTs, - expectedScriptInfosAfterGotoDef(), - expectedWatchedFilesAfterGotoDef(), + verifyAllFnAction(session, host, goToDefFromMainTs, expectedScriptInfosAfterGotoDef(), expectedWatchedFilesAfterGotoDef(), /*existingDependencyMap*/ undefined, /*existingDocumentPositionMapper*/ undefined, /*existingMapEqual*/ true, - /*existingDocumentPositionMapperEqual*/ true - ); - verifyAllFnAction( - session, - host, - renameFromDependencyTsWithBothProjectsOpen, - expectedScriptInfosAfterRenameWhenNoDts(), - expectedWatchedFilesAfterRenameWhenNoDts(), + /*existingDocumentPositionMapperEqual*/ true); + verifyAllFnAction(session, host, renameFromDependencyTsWithBothProjectsOpen, expectedScriptInfosAfterRenameWhenNoDts(), expectedWatchedFilesAfterRenameWhenNoDts(), /*existingDependencyMap*/ undefined, /*existingDocumentPositionMapper*/ undefined, /*existingMapEqual*/ true, - /*existingDocumentPositionMapperEqual*/ true - ); + /*existingDocumentPositionMapperEqual*/ true); checkProjects(session); - verifyScriptInfoCollection( - session, - host, - expectedScriptInfosAfterRenameWhenNoDts(), - expectedWatchedFilesAfterRenameWhenNoDts(), - ); + verifyScriptInfoCollection(session, host, expectedScriptInfosAfterRenameWhenNoDts(), expectedWatchedFilesAfterRenameWhenNoDts()); }); it(`with depedency .d.ts file, when file is created after actions on projects`, () => { let fileContents: string; @@ -3726,76 +2421,38 @@ ${dependencyTs.content}`); }); host.writeFile(dtsLocation, fileContents!); - verifyAllFnAction( - session, - host, - goToDefFromMainTs, - expectedScriptInfosAfterGotoDef(), + verifyAllFnAction(session, host, goToDefFromMainTs, expectedScriptInfosAfterGotoDef(), // Since the project for dependency is not updated, the watcher from rename for dts still there - expectedWatchedFilesAfterGotoDef().concat(dtsPath), - dependencyMap, - documentPositionMapper, - /*existingMapEqual*/ true, - /*existingDocumentPositionMapperEqual*/ true - ); - verifyAllFnAction( - session, - host, - renameFromDependencyTsWithBothProjectsOpen, - expectedScriptInfosAfterRenameWhenMapped(), - expectedWatchedFilesAfterRenameWhenMapped(), - dependencyMap, - documentPositionMapper, + expectedWatchedFilesAfterGotoDef().concat(dtsPath), dependencyMap, documentPositionMapper, + /*existingMapEqual*/ true, + /*existingDocumentPositionMapperEqual*/ true); + verifyAllFnAction(session, host, renameFromDependencyTsWithBothProjectsOpen, expectedScriptInfosAfterRenameWhenMapped(), expectedWatchedFilesAfterRenameWhenMapped(), dependencyMap, documentPositionMapper, /*existingMapEqual*/ false, - /*existingDocumentPositionMapperEqual*/ false - ); + /*existingDocumentPositionMapperEqual*/ false); checkProjects(session); - verifyScriptInfoCollection( - session, - host, - expectedScriptInfosAfterRenameWhenMapped(), - expectedWatchedFilesAfterRenameWhenMapped(), - ); + verifyScriptInfoCollection(session, host, expectedScriptInfosAfterRenameWhenMapped(), expectedWatchedFilesAfterRenameWhenMapped()); }); it(`with depedency .d.ts file, when file is deleted after actions on the projects`, () => { const { host, session, dependencyMap, documentPositionMapper } = setupWithAction(); // The dependency file is deleted when orphan files are collected host.deleteFile(dtsLocation); - verifyAllFnAction( - session, - host, - goToDefFromMainTs, + verifyAllFnAction(session, host, goToDefFromMainTs, // Map collection after file open expectedScriptInfosAfterRenameWhenNoDts().concat(dtsMapLocation), // not watching dts since this operation doesnt need it - removePath(expectedWatchedFilesAfterRenameWhenNoDts(), dtsPath).concat(dtsMapPath), - dependencyMap, - documentPositionMapper, - /*existingMapEqual*/ true, - /*existingDocumentPositionMapperEqual*/ true - ); - verifyAllFnAction( - session, - host, - renameFromDependencyTsWithBothProjectsOpen, + removePath(expectedWatchedFilesAfterRenameWhenNoDts(), dtsPath).concat(dtsMapPath), dependencyMap, documentPositionMapper, + /*existingMapEqual*/ true, + /*existingDocumentPositionMapperEqual*/ true); + verifyAllFnAction(session, host, renameFromDependencyTsWithBothProjectsOpen, // Map collection after file open - expectedScriptInfosAfterRenameWhenNoDts().concat(dtsMapLocation), - expectedWatchedFilesAfterRenameWhenNoDts().concat(dtsMapPath), - dependencyMap, - documentPositionMapper, + expectedScriptInfosAfterRenameWhenNoDts().concat(dtsMapLocation), expectedWatchedFilesAfterRenameWhenNoDts().concat(dtsMapPath), dependencyMap, documentPositionMapper, /*existingMapEqual*/ true, - /*existingDocumentPositionMapperEqual*/ true - ); + /*existingDocumentPositionMapperEqual*/ true); checkProjects(session); // Script info collection should behave as "noDts" - verifyScriptInfoCollection( - session, - host, - expectedScriptInfosAfterRenameWhenNoDts(), - expectedWatchedFilesAfterRenameWhenNoDts(), - ); + verifyScriptInfoCollection(session, host, expectedScriptInfosAfterRenameWhenNoDts(), expectedWatchedFilesAfterRenameWhenNoDts()); }); it(`when defining project source changes, when timeout occurs before request`, () => { @@ -3804,39 +2461,24 @@ ${dependencyTs.content}`); // change // Make change, without rebuild of solution - session.executeCommandSeq({ - command: protocol.CommandTypes.Change, + session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.Change, arguments: { file: dependencyTs.path, line: 1, offset: 1, endLine: 1, endOffset: 1, insertString: `function fooBar() { } -`} +` + } }); host.runQueuedTimeoutCallbacks(); checkProjects(session); verifyDocumentPositionMapperEqual(session, dependencyMap, documentPositionMapper); // action - verifyAllFnAction( - session, - host, - goToDefFromMainTsWithDependencyChange, - expectedScriptInfosAfterRenameWhenMapped(), - expectedWatchedFilesAfterRenameWhenMapped(), - dependencyMap, - documentPositionMapper, - /*existingMapEqual*/ true, - /*existingDocumentPositionMapperEqual*/ true - ); - verifyAllFnAction( - session, - host, - renameFromDependencyTsWithBothProjectsOpenWithDependencyChange, - expectedScriptInfosAfterRenameWhenMapped(), - expectedWatchedFilesAfterRenameWhenMapped(), - dependencyMap, - documentPositionMapper, - /*existingMapEqual*/ true, - /*existingDocumentPositionMapperEqual*/ true - ); + verifyAllFnAction(session, host, goToDefFromMainTsWithDependencyChange, expectedScriptInfosAfterRenameWhenMapped(), expectedWatchedFilesAfterRenameWhenMapped(), dependencyMap, documentPositionMapper, + /*existingMapEqual*/ true, + /*existingDocumentPositionMapperEqual*/ true); + verifyAllFnAction(session, host, renameFromDependencyTsWithBothProjectsOpenWithDependencyChange, expectedScriptInfosAfterRenameWhenMapped(), expectedWatchedFilesAfterRenameWhenMapped(), dependencyMap, documentPositionMapper, + /*existingMapEqual*/ true, + /*existingDocumentPositionMapperEqual*/ true); }); it(`when defining project source changes, when timeout does not occur before request`, () => { // Create DocumentPositionMapper @@ -3844,71 +2486,39 @@ ${dependencyTs.content}`); // change // Make change, without rebuild of solution - session.executeCommandSeq({ - command: protocol.CommandTypes.Change, + session.executeCommandSeq({ + command: ts.projectSystem.protocol.CommandTypes.Change, arguments: { file: dependencyTs.path, line: 1, offset: 1, endLine: 1, endOffset: 1, insertString: `function fooBar() { } -`} +` + } }); // action - verifyAllFnAction( - session, - host, - goToDefFromMainTsWithDependencyChange, - expectedScriptInfosAfterRenameWhenMapped(), - expectedWatchedFilesAfterRenameWhenMapped(), - dependencyMap, - documentPositionMapper, - /*existingMapEqual*/ true, - /*existingDocumentPositionMapperEqual*/ true - ); - verifyAllFnAction( - session, - host, - renameFromDependencyTsWithBothProjectsOpenWithDependencyChange, - expectedScriptInfosAfterRenameWhenMapped(), - expectedWatchedFilesAfterRenameWhenMapped(), - dependencyMap, - documentPositionMapper, - /*existingMapEqual*/ true, - /*existingDocumentPositionMapperEqual*/ true - ); + verifyAllFnAction(session, host, goToDefFromMainTsWithDependencyChange, expectedScriptInfosAfterRenameWhenMapped(), expectedWatchedFilesAfterRenameWhenMapped(), dependencyMap, documentPositionMapper, + /*existingMapEqual*/ true, + /*existingDocumentPositionMapperEqual*/ true); + verifyAllFnAction(session, host, renameFromDependencyTsWithBothProjectsOpenWithDependencyChange, expectedScriptInfosAfterRenameWhenMapped(), expectedWatchedFilesAfterRenameWhenMapped(), dependencyMap, documentPositionMapper, + /*existingMapEqual*/ true, + /*existingDocumentPositionMapperEqual*/ true); }); it("when projects are not built", () => { - const host = createServerHost(files); - const session = createSession(host); - openFilesForSession([mainTs, dependencyTs, randomFile], session); - verifyAllFnAction( - session, - host, - goToDefFromMainTs, - expectedScriptInfosAfterGotoDef(), - expectedWatchedFilesAfterGotoDef(), + const host = ts.projectSystem.createServerHost(files); + const session = ts.projectSystem.createSession(host); + ts.projectSystem.openFilesForSession([mainTs, dependencyTs, randomFile], session); + verifyAllFnAction(session, host, goToDefFromMainTs, expectedScriptInfosAfterGotoDef(), expectedWatchedFilesAfterGotoDef(), /*existingDependencyMap*/ undefined, /*existingDocumentPositionMapper*/ undefined, /*existingMapEqual*/ true, - /*existingDocumentPositionMapperEqual*/ true - ); - verifyAllFnAction( - session, - host, - renameFromDependencyTsWithBothProjectsOpen, - expectedScriptInfosAfterRenameWhenNoDts(), - expectedWatchedFilesAfterRenameWhenNoDts(), + /*existingDocumentPositionMapperEqual*/ true); + verifyAllFnAction(session, host, renameFromDependencyTsWithBothProjectsOpen, expectedScriptInfosAfterRenameWhenNoDts(), expectedWatchedFilesAfterRenameWhenNoDts(), /*existingDependencyMap*/ undefined, /*existingDocumentPositionMapper*/ undefined, /*existingMapEqual*/ true, - /*existingDocumentPositionMapperEqual*/ true - ); + /*existingDocumentPositionMapperEqual*/ true); checkProjects(session); - verifyScriptInfoCollection( - session, - host, - expectedScriptInfosAfterRenameWhenNoDts(), - expectedWatchedFilesAfterRenameWhenNoDts(), - ); + verifyScriptInfoCollection(session, host, expectedScriptInfosAfterRenameWhenNoDts(), expectedWatchedFilesAfterRenameWhenNoDts()); }); }); describe("when main tsconfig has disableSourceOfProjectReferenceRedirect along with project reference", () => { @@ -3920,24 +2530,24 @@ ${dependencyTs.content}`); return setupWithActionWith(setup, onHostCreate); } - function checkProjects(session: TestSession) { - checkNumberOfProjects(session.getProjectService(), { configuredProjects: 3 }); + function checkProjects(session: ts.projectSystem.TestSession) { + ts.projectSystem.checkNumberOfProjects(session.getProjectService(), { configuredProjects: 3 }); checkMainProjectWithDisabledProjectReferences(session); checkDependencyProjectWith(session); } - function checkProjectsWithoutDts(session: TestSession) { - checkNumberOfProjects(session.getProjectService(), { configuredProjects: 3 }); + function checkProjectsWithoutDts(session: ts.projectSystem.TestSession) { + ts.projectSystem.checkNumberOfProjects(session.getProjectService(), { configuredProjects: 3 }); checkMainProjectWithDisabledProjectReferencesWithoutDts(session); checkDependencyProjectWith(session); } function expectedScriptInfosWhenMapped() { - return [mainTs.path, randomFile.path, dependencyTs.path, libFile.path, dtsPath, dtsMapLocation]; + return [mainTs.path, randomFile.path, dependencyTs.path, ts.projectSystem.libFile.path, dtsPath, dtsMapLocation]; } function expectedWatchedFilesWhenMapped() { - return [libFile.path, dtsPath, dtsMapPath, mainConfig.path, randomConfig.path, dependencyConfig.path]; + return [ts.projectSystem.libFile.path, dtsPath, dtsMapPath, mainConfig.path, randomConfig.path, dependencyConfig.path]; } function expectedScriptInfosWhenNoMap() { @@ -3972,36 +2582,17 @@ ${dependencyTs.content}`); it("goto Definition in usage and rename locations from defining project", () => { const { host, session } = setup(); checkProjects(session); - verifyAllFnAction( - session, - host, - goToDefFromMainTs, - expectedScriptInfosWhenMapped(), - expectedWatchedFilesWhenMapped(), + verifyAllFnAction(session, host, goToDefFromMainTs, expectedScriptInfosWhenMapped(), expectedWatchedFilesWhenMapped(), /*existingDependencyMap*/ undefined, /*existingDocumentPositionMapper*/ undefined, /*existingMapEqual*/ false, - /*existingDocumentPositionMapperEqual*/ false - ); + /*existingDocumentPositionMapperEqual*/ false); const { dependencyMap, documentPositionMapper } = getDocumentPositionMapper(session); - verifyAllFnAction( - session, - host, - renameFromDependencyTsWithBothProjectsOpen, - expectedScriptInfosWhenMapped(), - expectedWatchedFilesWhenMapped(), - dependencyMap, - documentPositionMapper, - /*existingMapEqual*/ true, - /*existingDocumentPositionMapperEqual*/ true - ); + verifyAllFnAction(session, host, renameFromDependencyTsWithBothProjectsOpen, expectedScriptInfosWhenMapped(), expectedWatchedFilesWhenMapped(), dependencyMap, documentPositionMapper, + /*existingMapEqual*/ true, + /*existingDocumentPositionMapperEqual*/ true); checkProjects(session); - verifyScriptInfoCollection( - session, - host, - expectedScriptInfosWhenMapped(), - expectedWatchedFilesWhenMapped(), - ); + verifyScriptInfoCollection(session, host, expectedScriptInfosWhenMapped(), expectedWatchedFilesWhenMapped()); }); // Edit @@ -4017,28 +2608,12 @@ ${dependencyTs.content}`); verifyDocumentPositionMapperEqual(session, dependencyMap, documentPositionMapper); // action - verifyAllFnAction( - session, - host, - goToDefFromMainTs, - expectedScriptInfosWhenMapped(), - expectedWatchedFilesWhenMapped(), - dependencyMap, - documentPositionMapper, - /*existingMapEqual*/ true, - /*existingDocumentPositionMapperEqual*/ true - ); - verifyAllFnAction( - session, - host, - renameFromDependencyTsWithBothProjectsOpen, - expectedScriptInfosWhenMapped(), - expectedWatchedFilesWhenMapped(), - dependencyMap, - documentPositionMapper, - /*existingMapEqual*/ true, - /*existingDocumentPositionMapperEqual*/ true - ); + verifyAllFnAction(session, host, goToDefFromMainTs, expectedScriptInfosWhenMapped(), expectedWatchedFilesWhenMapped(), dependencyMap, documentPositionMapper, + /*existingMapEqual*/ true, + /*existingDocumentPositionMapperEqual*/ true); + verifyAllFnAction(session, host, renameFromDependencyTsWithBothProjectsOpen, expectedScriptInfosWhenMapped(), expectedWatchedFilesWhenMapped(), dependencyMap, documentPositionMapper, + /*existingMapEqual*/ true, + /*existingDocumentPositionMapperEqual*/ true); }); it(`when usage file changes, document position mapper doesnt change, when timeout does not occur before request`, () => { // Create DocumentPositionMapper @@ -4049,28 +2624,12 @@ ${dependencyTs.content}`); makeChangeToDependencyTs(session); // action - verifyAllFnAction( - session, - host, - goToDefFromMainTs, - expectedScriptInfosWhenMapped(), - expectedWatchedFilesWhenMapped(), - dependencyMap, - documentPositionMapper, - /*existingMapEqual*/ true, - /*existingDocumentPositionMapperEqual*/ true - ); - verifyAllFnAction( - session, - host, - renameFromDependencyTsWithBothProjectsOpen, - expectedScriptInfosWhenMapped(), - expectedWatchedFilesWhenMapped(), - dependencyMap, - documentPositionMapper, - /*existingMapEqual*/ true, - /*existingDocumentPositionMapperEqual*/ true - ); + verifyAllFnAction(session, host, goToDefFromMainTs, expectedScriptInfosWhenMapped(), expectedWatchedFilesWhenMapped(), dependencyMap, documentPositionMapper, + /*existingMapEqual*/ true, + /*existingDocumentPositionMapperEqual*/ true); + verifyAllFnAction(session, host, renameFromDependencyTsWithBothProjectsOpen, expectedScriptInfosWhenMapped(), expectedWatchedFilesWhenMapped(), dependencyMap, documentPositionMapper, + /*existingMapEqual*/ true, + /*existingDocumentPositionMapperEqual*/ true); }); // Edit dts to add new fn @@ -4085,28 +2644,12 @@ ${dependencyTs.content}`); verifyDocumentPositionMapperEqual(session, dependencyMap, documentPositionMapper); // action - verifyAllFnAction( - session, - host, - goToDefFromMainTs, - expectedScriptInfosWhenMapped(), - expectedWatchedFilesWhenMapped(), - dependencyMap, - documentPositionMapper, - /*existingMapEqual*/ true, - /*existingDocumentPositionMapperEqual*/ true - ); - verifyAllFnAction( - session, - host, - renameFromDependencyTsWithBothProjectsOpen, - expectedScriptInfosWhenMapped(), - expectedWatchedFilesWhenMapped(), - dependencyMap, - documentPositionMapper, - /*existingMapEqual*/ true, - /*existingDocumentPositionMapperEqual*/ true - ); + verifyAllFnAction(session, host, goToDefFromMainTs, expectedScriptInfosWhenMapped(), expectedWatchedFilesWhenMapped(), dependencyMap, documentPositionMapper, + /*existingMapEqual*/ true, + /*existingDocumentPositionMapperEqual*/ true); + verifyAllFnAction(session, host, renameFromDependencyTsWithBothProjectsOpen, expectedScriptInfosWhenMapped(), expectedWatchedFilesWhenMapped(), dependencyMap, documentPositionMapper, + /*existingMapEqual*/ true, + /*existingDocumentPositionMapperEqual*/ true); }); it(`when dependency .d.ts changes, document position mapper doesnt change, when timeout does not occur before request`, () => { // Create DocumentPositionMapper @@ -4116,28 +2659,12 @@ ${dependencyTs.content}`); changeDtsFile(host); // action - verifyAllFnAction( - session, - host, - goToDefFromMainTs, - expectedScriptInfosWhenMapped(), - expectedWatchedFilesWhenMapped(), - dependencyMap, - documentPositionMapper, - /*existingMapEqual*/ true, - /*existingDocumentPositionMapperEqual*/ true - ); - verifyAllFnAction( - session, - host, - renameFromDependencyTsWithBothProjectsOpen, - expectedScriptInfosWhenMapped(), - expectedWatchedFilesWhenMapped(), - dependencyMap, - documentPositionMapper, - /*existingMapEqual*/ true, - /*existingDocumentPositionMapperEqual*/ true - ); + verifyAllFnAction(session, host, goToDefFromMainTs, expectedScriptInfosWhenMapped(), expectedWatchedFilesWhenMapped(), dependencyMap, documentPositionMapper, + /*existingMapEqual*/ true, + /*existingDocumentPositionMapperEqual*/ true); + verifyAllFnAction(session, host, renameFromDependencyTsWithBothProjectsOpen, expectedScriptInfosWhenMapped(), expectedWatchedFilesWhenMapped(), dependencyMap, documentPositionMapper, + /*existingMapEqual*/ true, + /*existingDocumentPositionMapperEqual*/ true); }); // Edit map file to represent added new line @@ -4152,29 +2679,13 @@ ${dependencyTs.content}`); verifyDocumentPositionMapperEqual(session, dependencyMap, documentPositionMapper); // action - verifyAllFnAction( - session, - host, - goToDefFromMainTs, - expectedScriptInfosWhenMapped(), - expectedWatchedFilesWhenMapped(), - dependencyMap, - documentPositionMapper, - /*existingMapEqual*/ true, - /*existingDocumentPositionMapperEqual*/ false - ); + verifyAllFnAction(session, host, goToDefFromMainTs, expectedScriptInfosWhenMapped(), expectedWatchedFilesWhenMapped(), dependencyMap, documentPositionMapper, + /*existingMapEqual*/ true, + /*existingDocumentPositionMapperEqual*/ false); const { documentPositionMapper: newDocumentPositionMapper } = getDocumentPositionMapper(session); - verifyAllFnAction( - session, - host, - renameFromDependencyTsWithBothProjectsOpen, - expectedScriptInfosWhenMapped(), - expectedWatchedFilesWhenMapped(), - dependencyMap, - newDocumentPositionMapper, - /*existingMapEqual*/ true, - /*existingDocumentPositionMapperEqual*/ true - ); + verifyAllFnAction(session, host, renameFromDependencyTsWithBothProjectsOpen, expectedScriptInfosWhenMapped(), expectedWatchedFilesWhenMapped(), dependencyMap, newDocumentPositionMapper, + /*existingMapEqual*/ true, + /*existingDocumentPositionMapperEqual*/ true); }); it(`when dependency file's map changes, when timeout does not occur before request`, () => { // Create DocumentPositionMapper @@ -4184,64 +2695,31 @@ ${dependencyTs.content}`); changeDtsMapFile(host); // action - verifyAllFnAction( - session, - host, - goToDefFromMainTs, - expectedScriptInfosWhenMapped(), - expectedWatchedFilesWhenMapped(), - dependencyMap, - documentPositionMapper, - /*existingMapEqual*/ true, - /*existingDocumentPositionMapperEqual*/ false - ); + verifyAllFnAction(session, host, goToDefFromMainTs, expectedScriptInfosWhenMapped(), expectedWatchedFilesWhenMapped(), dependencyMap, documentPositionMapper, + /*existingMapEqual*/ true, + /*existingDocumentPositionMapperEqual*/ false); const { documentPositionMapper: newDocumentPositionMapper } = getDocumentPositionMapper(session); - verifyAllFnAction( - session, - host, - renameFromDependencyTsWithBothProjectsOpen, - expectedScriptInfosWhenMapped(), - expectedWatchedFilesWhenMapped(), - dependencyMap, - newDocumentPositionMapper, - /*existingMapEqual*/ true, - /*existingDocumentPositionMapperEqual*/ true - ); + verifyAllFnAction(session, host, renameFromDependencyTsWithBothProjectsOpen, expectedScriptInfosWhenMapped(), expectedWatchedFilesWhenMapped(), dependencyMap, newDocumentPositionMapper, + /*existingMapEqual*/ true, + /*existingDocumentPositionMapperEqual*/ true); }); it(`with depedency files map file, when file is not present`, () => { const { host, session } = setup(host => host.deleteFile(dtsMapLocation)); checkProjects(session); - verifyAllFnAction( - session, - host, - goToDefFromMainTsWithNoMap, - expectedScriptInfosWhenNoMap(), - expectedWatchedFilesWhenNoMap(), + verifyAllFnAction(session, host, goToDefFromMainTsWithNoMap, expectedScriptInfosWhenNoMap(), expectedWatchedFilesWhenNoMap(), /*existingDependencyMap*/ undefined, /*existingDocumentPositionMapper*/ undefined, /*existingMapEqual*/ true, - /*existingDocumentPositionMapperEqual*/ true - ); - verifyAllFnAction( - session, - host, - renameFromDependencyTs, - expectedScriptInfosWhenNoMap(), - expectedWatchedFilesWhenNoMap(), + /*existingDocumentPositionMapperEqual*/ true); + verifyAllFnAction(session, host, renameFromDependencyTs, expectedScriptInfosWhenNoMap(), expectedWatchedFilesWhenNoMap(), /*existingDependencyMap*/ undefined, /*existingDocumentPositionMapper*/ undefined, /*existingMapEqual*/ true, - /*existingDocumentPositionMapperEqual*/ true - ); + /*existingDocumentPositionMapperEqual*/ true); checkProjects(session); - verifyScriptInfoCollection( - session, - host, - expectedScriptInfosWhenNoMap(), - expectedWatchedFilesWhenNoMap(), - ); + verifyScriptInfoCollection(session, host, expectedScriptInfosWhenNoMap(), expectedWatchedFilesWhenNoMap()); }); it(`with depedency files map file, when file is created after actions on projects`, () => { let fileContents: string; @@ -4251,109 +2729,50 @@ ${dependencyTs.content}`); }); host.writeFile(dtsMapLocation, fileContents!); - verifyAllFnAction( - session, - host, - goToDefFromMainTs, - expectedScriptInfosWhenMapped(), - expectedWatchedFilesWhenMapped(), - dependencyMap, - documentPositionMapper, + verifyAllFnAction(session, host, goToDefFromMainTs, expectedScriptInfosWhenMapped(), expectedWatchedFilesWhenMapped(), dependencyMap, documentPositionMapper, /*existingMapEqual*/ false, - /*existingDocumentPositionMapperEqual*/ false - ); + /*existingDocumentPositionMapperEqual*/ false); const { dependencyMap: newDependencyMap, documentPositionMapper: newDocumentPositionMapper } = getDocumentPositionMapper(session); - verifyAllFnAction( - session, - host, - renameFromDependencyTsWithBothProjectsOpen, - expectedScriptInfosWhenMapped(), - expectedWatchedFilesWhenMapped(), - newDependencyMap, - newDocumentPositionMapper, - /*existingMapEqual*/ true, - /*existingDocumentPositionMapperEqual*/ true - ); + verifyAllFnAction(session, host, renameFromDependencyTsWithBothProjectsOpen, expectedScriptInfosWhenMapped(), expectedWatchedFilesWhenMapped(), newDependencyMap, newDocumentPositionMapper, + /*existingMapEqual*/ true, + /*existingDocumentPositionMapperEqual*/ true); checkProjects(session); - verifyScriptInfoCollection( - session, - host, - expectedScriptInfosWhenMapped(), - expectedWatchedFilesWhenMapped() - ); + verifyScriptInfoCollection(session, host, expectedScriptInfosWhenMapped(), expectedWatchedFilesWhenMapped()); }); it(`with depedency files map file, when file is deleted after actions on the projects`, () => { const { host, session, dependencyMap, documentPositionMapper } = setupWithAction(); // The dependency file is deleted when orphan files are collected host.deleteFile(dtsMapLocation); - verifyAllFnAction( - session, - host, - goToDefFromMainTsWithNoMap, - expectedScriptInfosWhenNoMap(), - expectedWatchedFilesWhenNoMap(), - dependencyMap, - documentPositionMapper, + verifyAllFnAction(session, host, goToDefFromMainTsWithNoMap, expectedScriptInfosWhenNoMap(), expectedWatchedFilesWhenNoMap(), dependencyMap, documentPositionMapper, /*existingMapEqual*/ false, - /*existingDocumentPositionMapperEqual*/ false - ); + /*existingDocumentPositionMapperEqual*/ false); const { dependencyMap: newDependencyMap, documentPositionMapper: newDocumentPositionMapper } = getDocumentPositionMapper(session); - verifyAllFnAction( - session, - host, - renameFromDependencyTs, - expectedScriptInfosWhenNoMap(), - expectedWatchedFilesWhenNoMap(), - newDependencyMap, - newDocumentPositionMapper, - /*existingMapEqual*/ true, - /*existingDocumentPositionMapperEqual*/ true - ); + verifyAllFnAction(session, host, renameFromDependencyTs, expectedScriptInfosWhenNoMap(), expectedWatchedFilesWhenNoMap(), newDependencyMap, newDocumentPositionMapper, + /*existingMapEqual*/ true, + /*existingDocumentPositionMapperEqual*/ true); checkProjects(session); // Script info collection should behave as fileNotPresentKey - verifyScriptInfoCollection( - session, - host, - expectedScriptInfosWhenNoMap(), - expectedWatchedFilesWhenNoMap(), - ); + verifyScriptInfoCollection(session, host, expectedScriptInfosWhenNoMap(), expectedWatchedFilesWhenNoMap()); }); it(`with depedency .d.ts file, when file is not present`, () => { const { host, session } = setup(host => host.deleteFile(dtsLocation)); checkProjectsWithoutDts(session); - verifyAllFnAction( - session, - host, - goToDefFromMainTsWithNoDts, - expectedScriptInfosAfterGotoDefWhenNoDts(), - expectedWatchedFilesAfterGotoDefWhenNoDts(), + verifyAllFnAction(session, host, goToDefFromMainTsWithNoDts, expectedScriptInfosAfterGotoDefWhenNoDts(), expectedWatchedFilesAfterGotoDefWhenNoDts(), /*existingDependencyMap*/ undefined, /*existingDocumentPositionMapper*/ undefined, /*existingMapEqual*/ true, - /*existingDocumentPositionMapperEqual*/ true - ); - verifyAllFnAction( - session, - host, - renameFromDependencyTs, - expectedScriptInfosAfterRenameWhenNoDts(), - expectedWatchedFilesAfterRenameWhenNoDts(), + /*existingDocumentPositionMapperEqual*/ true); + verifyAllFnAction(session, host, renameFromDependencyTs, expectedScriptInfosAfterRenameWhenNoDts(), expectedWatchedFilesAfterRenameWhenNoDts(), /*existingDependencyMap*/ undefined, /*existingDocumentPositionMapper*/ undefined, /*existingMapEqual*/ true, - /*existingDocumentPositionMapperEqual*/ true - ); + /*existingDocumentPositionMapperEqual*/ true); checkProjectsWithoutDts(session); - verifyScriptInfoCollection( - session, - host, - expectedScriptInfosAfterRenameWhenNoDts(), - expectedWatchedFilesAfterRenameWhenNoDts(), - ); + verifyScriptInfoCollection(session, host, expectedScriptInfosAfterRenameWhenNoDts(), expectedWatchedFilesAfterRenameWhenNoDts()); }); it(`with depedency .d.ts file, when file is created after actions on projects`, () => { let fileContents: string; @@ -4363,75 +2782,35 @@ ${dependencyTs.content}`); }); host.writeFile(dtsLocation, fileContents!); - verifyAllFnAction( - session, - host, - goToDefFromMainTs, - expectedScriptInfosWhenMapped(), - expectedWatchedFilesWhenMapped(), - dependencyMap, - documentPositionMapper, + verifyAllFnAction(session, host, goToDefFromMainTs, expectedScriptInfosWhenMapped(), expectedWatchedFilesWhenMapped(), dependencyMap, documentPositionMapper, /*existingMapEqual*/ false, - /*existingDocumentPositionMapperEqual*/ false - ); + /*existingDocumentPositionMapperEqual*/ false); const { dependencyMap: newDependencyMap, documentPositionMapper: newDocumentPositionMapper } = getDocumentPositionMapper(session); - verifyAllFnAction( - session, - host, - renameFromDependencyTsWithBothProjectsOpen, - expectedScriptInfosWhenMapped(), - expectedWatchedFilesWhenMapped(), - newDependencyMap, - newDocumentPositionMapper, - /*existingMapEqual*/ true, - /*existingDocumentPositionMapperEqual*/ true - ); + verifyAllFnAction(session, host, renameFromDependencyTsWithBothProjectsOpen, expectedScriptInfosWhenMapped(), expectedWatchedFilesWhenMapped(), newDependencyMap, newDocumentPositionMapper, + /*existingMapEqual*/ true, + /*existingDocumentPositionMapperEqual*/ true); checkProjects(session); - verifyScriptInfoCollection( - session, - host, - expectedScriptInfosWhenMapped(), - expectedWatchedFilesWhenMapped() - ); + verifyScriptInfoCollection(session, host, expectedScriptInfosWhenMapped(), expectedWatchedFilesWhenMapped()); }); it(`with depedency .d.ts file, when file is deleted after actions on the projects`, () => { const { host, session, dependencyMap, documentPositionMapper } = setupWithAction(); // The dependency file is deleted when orphan files are collected host.deleteFile(dtsLocation); - verifyAllFnAction( - session, - host, - goToDefFromMainTsWithNoDts, + verifyAllFnAction(session, host, goToDefFromMainTsWithNoDts, // The script info for map is collected only after file open - expectedScriptInfosAfterGotoDefWhenNoDts().concat(dtsMapLocation), - expectedWatchedFilesAfterGotoDefWhenNoDts().concat(dtsMapPath), - dependencyMap, - documentPositionMapper, - /*existingMapEqual*/ true, - /*existingDocumentPositionMapperEqual*/ true - ); - verifyAllFnAction( - session, - host, - renameFromDependencyTs, + expectedScriptInfosAfterGotoDefWhenNoDts().concat(dtsMapLocation), expectedWatchedFilesAfterGotoDefWhenNoDts().concat(dtsMapPath), dependencyMap, documentPositionMapper, + /*existingMapEqual*/ true, + /*existingDocumentPositionMapperEqual*/ true); + verifyAllFnAction(session, host, renameFromDependencyTs, // The script info for map is collected only after file open - expectedScriptInfosAfterRenameWhenNoDts().concat(dtsMapLocation), - expectedWatchedFilesAfterRenameWhenNoDts().concat(dtsMapPath), - dependencyMap, - documentPositionMapper, + expectedScriptInfosAfterRenameWhenNoDts().concat(dtsMapLocation), expectedWatchedFilesAfterRenameWhenNoDts().concat(dtsMapPath), dependencyMap, documentPositionMapper, /*existingMapEqual*/ true, - /*existingDocumentPositionMapperEqual*/ true - ); + /*existingDocumentPositionMapperEqual*/ true); checkProjectsWithoutDts(session); // Script info collection should behave as "noDts" - verifyScriptInfoCollection( - session, - host, - expectedScriptInfosAfterRenameWhenNoDts(), - expectedWatchedFilesAfterRenameWhenNoDts(), - ); + verifyScriptInfoCollection(session, host, expectedScriptInfosAfterRenameWhenNoDts(), expectedWatchedFilesAfterRenameWhenNoDts()); }); }); }); diff --git a/src/testRunner/unittests/tsserver/projects.ts b/src/testRunner/unittests/tsserver/projects.ts index a9df947bf2b73..3894e832e3334 100644 --- a/src/testRunner/unittests/tsserver/projects.ts +++ b/src/testRunner/unittests/tsserver/projects.ts @@ -1,58 +1,52 @@ namespace ts.projectSystem { describe("unittests:: tsserver:: Projects", () => { it("handles the missing files - that were added to program because they were added with /// { - const file1: File = { + const file1: ts.projectSystem.File = { path: "/a/b/commonFile1.ts", content: `/// let x = y` }; - const host = createServerHost([file1, libFile]); - const session = createSession(host, { logger: createLoggerWithInMemoryLogs() }); - openFilesForSession([file1], session); - - const getErrRequest = makeSessionRequest( - server.CommandNames.SemanticDiagnosticsSync, - { file: file1.path } - ); + const host = ts.projectSystem.createServerHost([file1, ts.projectSystem.libFile]); + const session = ts.projectSystem.createSession(host, { logger: ts.projectSystem.createLoggerWithInMemoryLogs() }); + ts.projectSystem.openFilesForSession([file1], session); + const getErrRequest = ts.projectSystem.makeSessionRequest(ts.server.CommandNames.SemanticDiagnosticsSync, { file: file1.path }); // Two errors: CommonFile2 not found and cannot find name y session.executeCommand(getErrRequest); - host.writeFile(commonFile2.path, commonFile2.content); + host.writeFile(ts.projectSystem.commonFile2.path, ts.projectSystem.commonFile2.content); host.runQueuedTimeoutCallbacks(); session.executeCommand(getErrRequest); - baselineTsserverLogs("projects", "handles the missing files added with tripleslash ref", session); + ts.projectSystem.baselineTsserverLogs("projects", "handles the missing files added with tripleslash ref", session); }); it("should create new inferred projects for files excluded from a configured project", () => { - const configFile: File = { + const configFile: ts.projectSystem.File = { path: "/a/b/tsconfig.json", content: `{ "compilerOptions": {}, - "files": ["${commonFile1.path}", "${commonFile2.path}"] + "files": ["${ts.projectSystem.commonFile1.path}", "${ts.projectSystem.commonFile2.path}"] }` }; - const files = [commonFile1, commonFile2, configFile]; - const host = createServerHost(files); - const projectService = createProjectService(host); - projectService.openClientFile(commonFile1.path); - - const project = configuredProjectAt(projectService, 0); - checkProjectRootFiles(project, [commonFile1.path, commonFile2.path]); + const files = [ts.projectSystem.commonFile1, ts.projectSystem.commonFile2, configFile]; + const host = ts.projectSystem.createServerHost(files); + const projectService = ts.projectSystem.createProjectService(host); + projectService.openClientFile(ts.projectSystem.commonFile1.path); + const project = ts.projectSystem.configuredProjectAt(projectService, 0); + ts.projectSystem.checkProjectRootFiles(project, [ts.projectSystem.commonFile1.path, ts.projectSystem.commonFile2.path]); configFile.content = `{ "compilerOptions": {}, - "files": ["${commonFile1.path}"] + "files": ["${ts.projectSystem.commonFile1.path}"] }`; host.writeFile(configFile.path, configFile.content); - checkNumberOfConfiguredProjects(projectService, 1); - checkProjectRootFiles(project, [commonFile1.path, commonFile2.path]); + ts.projectSystem.checkNumberOfConfiguredProjects(projectService, 1); + ts.projectSystem.checkProjectRootFiles(project, [ts.projectSystem.commonFile1.path, ts.projectSystem.commonFile2.path]); host.checkTimeoutQueueLengthAndRun(2); // Update the configured project + refresh inferred projects - checkNumberOfConfiguredProjects(projectService, 1); - checkProjectRootFiles(project, [commonFile1.path]); - - projectService.openClientFile(commonFile2.path); - checkNumberOfInferredProjects(projectService, 1); + ts.projectSystem.checkNumberOfConfiguredProjects(projectService, 1); + ts.projectSystem.checkProjectRootFiles(project, [ts.projectSystem.commonFile1.path]); + projectService.openClientFile(ts.projectSystem.commonFile2.path); + ts.projectSystem.checkNumberOfInferredProjects(projectService, 1); }); it("should disable features when the files are too large", () => { @@ -74,18 +68,17 @@ namespace ts.projectSystem { const proj1name = "proj1", proj2name = "proj2", proj3name = "proj3"; - const host = createServerHost([file1, file2, file3]); - const projectService = createProjectService(host); - - projectService.openExternalProject({ rootFiles: toExternalFiles([file1.path]), options: {}, projectFileName: proj1name }); + const host = ts.projectSystem.createServerHost([file1, file2, file3]); + const projectService = ts.projectSystem.createProjectService(host); + projectService.openExternalProject({ rootFiles: ts.projectSystem.toExternalFiles([file1.path]), options: {}, projectFileName: proj1name }); const proj1 = projectService.findProject(proj1name)!; assert.isTrue(proj1.languageServiceEnabled); - projectService.openExternalProject({ rootFiles: toExternalFiles([file2.path]), options: {}, projectFileName: proj2name }); + projectService.openExternalProject({ rootFiles: ts.projectSystem.toExternalFiles([file2.path]), options: {}, projectFileName: proj2name }); const proj2 = projectService.findProject(proj2name)!; assert.isTrue(proj2.languageServiceEnabled); - projectService.openExternalProject({ rootFiles: toExternalFiles([file3.path]), options: {}, projectFileName: proj3name }); + projectService.openExternalProject({ rootFiles: ts.projectSystem.toExternalFiles([file3.path]), options: {}, projectFileName: proj3name }); const proj3 = projectService.findProject(proj3name)!; assert.isFalse(proj3.languageServiceEnabled); }); @@ -104,10 +97,9 @@ namespace ts.projectSystem { const projName = "proj1"; - const host = createServerHost([file1, file2]); - const projectService = createProjectService(host, { useSingleInferredProject: true, eventHandler: noop }); - - projectService.openExternalProject({ rootFiles: toExternalFiles([file1.path, file2.path]), options: {}, projectFileName: projName }); + const host = ts.projectSystem.createServerHost([file1, file2]); + const projectService = ts.projectSystem.createProjectService(host, { useSingleInferredProject: true, eventHandler: ts.noop }); + projectService.openExternalProject({ rootFiles: ts.projectSystem.toExternalFiles([file1.path, file2.path]), options: {}, projectFileName: projName }); const proj1 = projectService.findProject(projName)!; assert.isFalse(proj1.languageServiceEnabled); @@ -122,24 +114,22 @@ namespace ts.projectSystem { }; const config1 = { path: "/a/b/tsconfig.json", - content: JSON.stringify( - { + content: JSON.stringify({ compilerOptions: {}, files: ["f1.ts"] - } - ) + }) }; const externalProjectName = "externalproject"; - const host = createServerHost([file1, config1]); - const projectService = createProjectService(host, { useSingleInferredProject: true, syntaxOnly: true }); + const host = ts.projectSystem.createServerHost([file1, config1]); + const projectService = ts.projectSystem.createProjectService(host, { useSingleInferredProject: true, syntaxOnly: true }); projectService.openExternalProject({ - rootFiles: toExternalFiles([file1.path, config1.path]), + rootFiles: ts.projectSystem.toExternalFiles([file1.path, config1.path]), options: {}, projectFileName: externalProjectName }); - checkNumberOfProjects(projectService, { externalProjects: 1 }); + ts.projectSystem.checkNumberOfProjects(projectService, { externalProjects: 1 }); const proj = projectService.externalProjects[0]; assert.isDefined(proj); @@ -153,19 +143,17 @@ namespace ts.projectSystem { }; const config1 = { path: "/a/b/tsconfig.json", - content: JSON.stringify( - { + content: JSON.stringify({ compilerOptions: {}, files: ["f1.ts"] - } - ) + }) }; - const host = createServerHost([file1, config1]); - const projectService = createProjectService(host, { useSingleInferredProject: true, syntaxOnly: true }); + const host = ts.projectSystem.createServerHost([file1, config1]); + const projectService = ts.projectSystem.createProjectService(host, { useSingleInferredProject: true, syntaxOnly: true }); projectService.openClientFile(file1.path, file1.content); - checkNumberOfProjects(projectService, { inferredProjects: 1 }); + ts.projectSystem.checkNumberOfProjects(projectService, { inferredProjects: 1 }); const proj = projectService.inferredProjects[0]; assert.isDefined(proj); @@ -179,19 +167,15 @@ namespace ts.projectSystem { }; const config1 = { path: "/a/b/tsconfig.json", - content: JSON.stringify( - { + content: JSON.stringify({ compilerOptions: {}, files: ["f1.ts"] - } - ) + }) }; - - const host = createServerHost([file1, config1]); - const projectService = createProjectService(host, { useSingleInferredProject: true, syntaxOnly: true }); - projectService.applyChangesInOpenFiles(singleIterator({ fileName: file1.path, content: file1.content })); - - checkNumberOfProjects(projectService, { inferredProjects: 1 }); + const host = ts.projectSystem.createServerHost([file1, config1]); + const projectService = ts.projectSystem.createProjectService(host, { useSingleInferredProject: true, syntaxOnly: true }); + projectService.applyChangesInOpenFiles(ts.singleIterator({ fileName: file1.path, content: file1.content })); + ts.projectSystem.checkNumberOfProjects(projectService, { inferredProjects: 1 }); const proj = projectService.inferredProjects[0]; assert.isDefined(proj); @@ -209,23 +193,22 @@ namespace ts.projectSystem { content: "let x: number;" }; - const host = createServerHost([f1, f2, libFile]); - const service = createProjectService(host); - service.openExternalProject({ projectFileName: "/a/b/project", rootFiles: toExternalFiles([f1.path, f2.path]), options: {} }); + const host = ts.projectSystem.createServerHost([f1, f2, ts.projectSystem.libFile]); + const service = ts.projectSystem.createProjectService(host); + service.openExternalProject({ projectFileName: "/a/b/project", rootFiles: ts.projectSystem.toExternalFiles([f1.path, f2.path]), options: {} }); service.openClientFile(f1.path); service.openClientFile(f2.path, "let x: string"); service.checkNumberOfProjects({ externalProjects: 1 }); - checkProjectActualFiles(service.externalProjects[0], [f1.path, f2.path, libFile.path]); - - const completions1 = service.externalProjects[0].getLanguageService().getCompletionsAtPosition(f1.path, 2, emptyOptions)!; + ts.projectSystem.checkProjectActualFiles(service.externalProjects[0], [f1.path, f2.path, ts.projectSystem.libFile.path]); + const completions1 = service.externalProjects[0].getLanguageService().getCompletionsAtPosition(f1.path, 2, ts.emptyOptions)!; // should contain completions for string assert.isTrue(completions1.entries.some(e => e.name === "charAt"), "should contain 'charAt'"); assert.isFalse(completions1.entries.some(e => e.name === "toExponential"), "should not contain 'toExponential'"); service.closeClientFile(f2.path); - const completions2 = service.externalProjects[0].getLanguageService().getCompletionsAtPosition(f1.path, 2, emptyOptions)!; + const completions2 = service.externalProjects[0].getLanguageService().getCompletionsAtPosition(f1.path, 2, ts.emptyOptions)!; // should contain completions for string assert.isFalse(completions2.entries.some(e => e.name === "charAt"), "should not contain 'charAt'"); assert.isTrue(completions2.entries.some(e => e.name === "toExponential"), "should contain 'toExponential'"); @@ -241,21 +224,20 @@ namespace ts.projectSystem { content: "" }; - const host = createServerHost([f1, f2, libFile]); - const service = createProjectService(host); + const host = ts.projectSystem.createServerHost([f1, f2, ts.projectSystem.libFile]); + const service = ts.projectSystem.createProjectService(host); service.openExternalProject({ projectFileName: "/a/b/project", rootFiles: [{ fileName: f1.path }, { fileName: f2.path, hasMixedContent: true }], options: {} }); service.openClientFile(f1.path); service.openClientFile(f2.path, "let somelongname: string"); service.checkNumberOfProjects({ externalProjects: 1 }); - checkProjectActualFiles(service.externalProjects[0], [f1.path, f2.path, libFile.path]); - - const completions1 = service.externalProjects[0].getLanguageService().getCompletionsAtPosition(f1.path, 0, emptyOptions)!; + ts.projectSystem.checkProjectActualFiles(service.externalProjects[0], [f1.path, f2.path, ts.projectSystem.libFile.path]); + const completions1 = service.externalProjects[0].getLanguageService().getCompletionsAtPosition(f1.path, 0, ts.emptyOptions)!; assert.isTrue(completions1.entries.some(e => e.name === "somelongname"), "should contain 'somelongname'"); service.closeClientFile(f2.path); - const completions2 = service.externalProjects[0].getLanguageService().getCompletionsAtPosition(f1.path, 0, emptyOptions)!; + const completions2 = service.externalProjects[0].getLanguageService().getCompletionsAtPosition(f1.path, 0, ts.emptyOptions)!; assert.isFalse(completions2.entries.some(e => e.name === "somelongname"), "should not contain 'somelongname'"); const sf2 = service.externalProjects[0].getLanguageService().getProgram()!.getSourceFile(f2.path)!; assert.equal(sf2.text, ""); @@ -274,26 +256,26 @@ namespace ts.projectSystem { path: "/a/c/f3.ts", content: `export let y = 1;` }; - const host = createServerHost([file1, file2, file3]); - const projectService = createProjectService(host); + const host = ts.projectSystem.createServerHost([file1, file2, file3]); + const projectService = ts.projectSystem.createProjectService(host); projectService.openClientFile(file1.path); - checkNumberOfProjects(projectService, { inferredProjects: 1 }); + ts.projectSystem.checkNumberOfProjects(projectService, { inferredProjects: 1 }); const inferredProject0 = projectService.inferredProjects[0]; - checkProjectActualFiles(projectService.inferredProjects[0], [file1.path, file2.path]); + ts.projectSystem.checkProjectActualFiles(projectService.inferredProjects[0], [file1.path, file2.path]); projectService.openClientFile(file3.path); - checkNumberOfProjects(projectService, { inferredProjects: 2 }); + ts.projectSystem.checkNumberOfProjects(projectService, { inferredProjects: 2 }); assert.strictEqual(projectService.inferredProjects[0], inferredProject0); - checkProjectActualFiles(projectService.inferredProjects[0], [file1.path, file2.path]); + ts.projectSystem.checkProjectActualFiles(projectService.inferredProjects[0], [file1.path, file2.path]); const inferredProject1 = projectService.inferredProjects[1]; - checkProjectActualFiles(projectService.inferredProjects[1], [file3.path]); + ts.projectSystem.checkProjectActualFiles(projectService.inferredProjects[1], [file3.path]); host.writeFile(file2.path, `export * from "../c/f3"`); // now inferred project should inclule file3 host.checkTimeoutQueueLengthAndRun(2); - checkNumberOfProjects(projectService, { inferredProjects: 2 }); + ts.projectSystem.checkNumberOfProjects(projectService, { inferredProjects: 2 }); assert.strictEqual(projectService.inferredProjects[0], inferredProject0); - checkProjectActualFiles(projectService.inferredProjects[0], [file1.path, file2.path, file3.path]); + ts.projectSystem.checkProjectActualFiles(projectService.inferredProjects[0], [file1.path, file2.path, file3.path]); assert.strictEqual(projectService.inferredProjects[1], inferredProject1); assert.isTrue(inferredProject1.isOrphan()); }); @@ -311,25 +293,23 @@ namespace ts.projectSystem { path: "/a/c/f3.ts", content: `export let y = 1;` }; - const host = createServerHost([file1, file2, file3]); - const projectService = createProjectService(host); + const host = ts.projectSystem.createServerHost([file1, file2, file3]); + const projectService = ts.projectSystem.createProjectService(host); projectService.openClientFile(file1.path); - checkNumberOfProjects(projectService, { inferredProjects: 1 }); - - checkProjectActualFiles(projectService.inferredProjects[0], [file1.path, file2.path, file3.path]); + ts.projectSystem.checkNumberOfProjects(projectService, { inferredProjects: 1 }); + ts.projectSystem.checkProjectActualFiles(projectService.inferredProjects[0], [file1.path, file2.path, file3.path]); projectService.openClientFile(file3.path); - checkNumberOfProjects(projectService, { inferredProjects: 1 }); + ts.projectSystem.checkNumberOfProjects(projectService, { inferredProjects: 1 }); host.deleteFile(file2.path); host.checkTimeoutQueueLengthAndRun(2); - checkNumberOfProjects(projectService, { inferredProjects: 2 }); - - checkProjectActualFiles(projectService.inferredProjects[0], [file1.path]); - checkProjectActualFiles(projectService.inferredProjects[1], [file3.path]); + ts.projectSystem.checkNumberOfProjects(projectService, { inferredProjects: 2 }); + ts.projectSystem.checkProjectActualFiles(projectService.inferredProjects[0], [file1.path]); + ts.projectSystem.checkProjectActualFiles(projectService.inferredProjects[1], [file3.path]); }); it("ignores files excluded by a custom safe type list", () => { @@ -341,10 +321,10 @@ namespace ts.projectSystem { path: "/lib/duckquack-3.min.js", content: "whoa do @@ not parse me ok thanks!!!" }; - const host = createServerHost([file1, office, customTypesMap]); - const projectService = createProjectService(host); + const host = ts.projectSystem.createServerHost([file1, office, ts.projectSystem.customTypesMap]); + const projectService = ts.projectSystem.createProjectService(host); try { - projectService.openExternalProject({ projectFileName: "project", options: {}, rootFiles: toExternalFiles([file1.path, office.path]) }); + projectService.openExternalProject({ projectFileName: "project", options: {}, rootFiles: ts.projectSystem.toExternalFiles([file1.path, office.path]) }); const proj = projectService.externalProjects[0]; assert.deepEqual(proj.getFileNames(/*excludeFilesFromExternalLibraries*/ true), [file1.path]); assert.deepEqual(proj.getTypeAcquisition().include, ["duck-types"]); @@ -367,27 +347,27 @@ namespace ts.projectSystem { path: "/a/b/bliss.js", content: "export function is() { return true; }" }; - const host = createServerHost([file1, libFile, constructorFile, bliss, customTypesMap]); + const host = ts.projectSystem.createServerHost([file1, ts.projectSystem.libFile, constructorFile, bliss, ts.projectSystem.customTypesMap]); let request: string | undefined; const cachePath = "/a/data"; - const typingsInstaller: server.ITypingsInstaller = { - isKnownTypesPackageName: returnFalse, - installPackage: notImplemented, + const typingsInstaller: ts.server.ITypingsInstaller = { + isKnownTypesPackageName: ts.returnFalse, + installPackage: ts.notImplemented, enqueueInstallTypingsRequest: (proj, typeAcquisition, unresolvedImports) => { assert.isUndefined(request); - request = JSON.stringify(server.createInstallTypingsRequest(proj, typeAcquisition, unresolvedImports || server.emptyArray, cachePath)); + request = JSON.stringify(ts.server.createInstallTypingsRequest(proj, typeAcquisition, unresolvedImports || ts.server.emptyArray, cachePath)); }, - attach: noop, - onProjectClosed: noop, + attach: ts.noop, + onProjectClosed: ts.noop, globalTypingsCacheLocation: cachePath }; const projectName = "project"; - const projectService = createProjectService(host, { typingsInstaller }); - projectService.openExternalProject({ projectFileName: projectName, options: {}, rootFiles: toExternalFiles([file1.path, constructorFile.path, bliss.path]) }); + const projectService = ts.projectSystem.createProjectService(host, { typingsInstaller }); + projectService.openExternalProject({ projectFileName: projectName, options: {}, rootFiles: ts.projectSystem.toExternalFiles([file1.path, constructorFile.path, bliss.path]) }); assert.equal(request, JSON.stringify({ projectName, - fileNames: [libFile.path, file1.path, constructorFile.path, bliss.path], + fileNames: [ts.projectSystem.libFile.path, file1.path, constructorFile.path, bliss.path], compilerOptions: { allowNonTsExtensions: true, noEmitForJsFiles: true }, typeAcquisition: { include: ["blissfuljs"], exclude: [], enable: true }, unresolvedImports: ["s"], @@ -402,7 +382,7 @@ namespace ts.projectSystem { projectName: response.projectName, typeAcquisition: response.typeAcquisition, compilerOptions: response.compilerOptions, - typings: emptyArray, + typings: ts.emptyArray, unresolvedImports: response.unresolvedImports, }); @@ -440,10 +420,10 @@ namespace ts.projectSystem { content: "unspecified" }; const files = [file1, minFile, kendoFile1, kendoFile2, kendoFile3, officeFile1, officeFile2]; - const host = createServerHost(files); - const projectService = createProjectService(host); + const host = ts.projectSystem.createServerHost(files); + const projectService = ts.projectSystem.createProjectService(host); try { - projectService.openExternalProject({ projectFileName: "project", options: {}, rootFiles: toExternalFiles(files.map(f => f.path)) }); + projectService.openExternalProject({ projectFileName: "project", options: {}, rootFiles: ts.projectSystem.toExternalFiles(files.map(f => f.path)) }); const proj = projectService.externalProjects[0]; assert.deepEqual(proj.getFileNames(/*excludeFilesFromExternalLibraries*/ true), [file1.path]); assert.deepEqual(proj.getTypeAcquisition().include, ["kendo-ui", "office"]); @@ -454,7 +434,10 @@ namespace ts.projectSystem { }); it("removes version numbers correctly", () => { - const testData: [string, string][] = [ + const testData: [ + string, + string + ][] = [ ["jquery-max", "jquery-max"], ["jquery.min", "jquery"], ["jquery-min.4.2.3", "jquery"], @@ -465,7 +448,7 @@ namespace ts.projectSystem { ["jquery", "jquery"] ]; for (const t of testData) { - assert.equal(removeMinAndVersionNumbers(t[0]), t[1], t[0]); + assert.equal(ts.removeMinAndVersionNumbers(t[0]), t[1], t[0]); } }); @@ -482,10 +465,10 @@ namespace ts.projectSystem { path: "/a/b/Bacon.js", content: "let y = 5" }; - const host = createServerHost([file1, file2, file3, customTypesMap]); - const projectService = createProjectService(host); + const host = ts.projectSystem.createServerHost([file1, file2, file3, ts.projectSystem.customTypesMap]); + const projectService = ts.projectSystem.createProjectService(host); try { - projectService.openExternalProject({ projectFileName: "project", options: {}, rootFiles: toExternalFiles([file1.path, file2.path]), typeAcquisition: { enable: true } }); + projectService.openExternalProject({ projectFileName: "project", options: {}, rootFiles: ts.projectSystem.toExternalFiles([file1.path, file2.path]), typeAcquisition: { enable: true } }); const proj = projectService.externalProjects[0]; assert.deepEqual(proj.getFileNames(), [file2.path]); } @@ -509,52 +492,52 @@ namespace ts.projectSystem { path: "/a/d/f3.ts", content: "export let y = 1;" }; - const host = createServerHost([file1, file2, file3]); - const projectService = createProjectService(host); + const host = ts.projectSystem.createServerHost([file1, file2, file3]); + const projectService = ts.projectSystem.createProjectService(host); projectService.openClientFile(file2.path); - checkNumberOfProjects(projectService, { inferredProjects: 1 }); - checkProjectActualFiles(projectService.inferredProjects[0], [file2.path]); + ts.projectSystem.checkNumberOfProjects(projectService, { inferredProjects: 1 }); + ts.projectSystem.checkProjectActualFiles(projectService.inferredProjects[0], [file2.path]); let inferredProjects = projectService.inferredProjects.slice(); projectService.openClientFile(file3.path); - checkNumberOfProjects(projectService, { inferredProjects: 2 }); + ts.projectSystem.checkNumberOfProjects(projectService, { inferredProjects: 2 }); assert.strictEqual(projectService.inferredProjects[0], inferredProjects[0]); - checkProjectActualFiles(projectService.inferredProjects[0], [file2.path]); - checkProjectActualFiles(projectService.inferredProjects[1], [file3.path]); + ts.projectSystem.checkProjectActualFiles(projectService.inferredProjects[0], [file2.path]); + ts.projectSystem.checkProjectActualFiles(projectService.inferredProjects[1], [file3.path]); inferredProjects = projectService.inferredProjects.slice(); projectService.openClientFile(file1.path); - checkNumberOfProjects(projectService, { inferredProjects: 1 }); + ts.projectSystem.checkNumberOfProjects(projectService, { inferredProjects: 1 }); assert.notStrictEqual(projectService.inferredProjects[0], inferredProjects[0]); assert.notStrictEqual(projectService.inferredProjects[0], inferredProjects[1]); - checkProjectRootFiles(projectService.inferredProjects[0], [file1.path]); - checkProjectActualFiles(projectService.inferredProjects[0], [file1.path, file2.path, file3.path]); + ts.projectSystem.checkProjectRootFiles(projectService.inferredProjects[0], [file1.path]); + ts.projectSystem.checkProjectActualFiles(projectService.inferredProjects[0], [file1.path, file2.path, file3.path]); inferredProjects = projectService.inferredProjects.slice(); projectService.closeClientFile(file1.path); - checkNumberOfProjects(projectService, { inferredProjects: 3 }); + ts.projectSystem.checkNumberOfProjects(projectService, { inferredProjects: 3 }); assert.strictEqual(projectService.inferredProjects[0], inferredProjects[0]); assert.isTrue(projectService.inferredProjects[0].isOrphan()); - checkProjectActualFiles(projectService.inferredProjects[1], [file2.path]); - checkProjectActualFiles(projectService.inferredProjects[2], [file3.path]); + ts.projectSystem.checkProjectActualFiles(projectService.inferredProjects[1], [file2.path]); + ts.projectSystem.checkProjectActualFiles(projectService.inferredProjects[2], [file3.path]); inferredProjects = projectService.inferredProjects.slice(); projectService.closeClientFile(file3.path); - checkNumberOfProjects(projectService, { inferredProjects: 3 }); + ts.projectSystem.checkNumberOfProjects(projectService, { inferredProjects: 3 }); assert.strictEqual(projectService.inferredProjects[0], inferredProjects[0]); assert.strictEqual(projectService.inferredProjects[1], inferredProjects[1]); assert.strictEqual(projectService.inferredProjects[2], inferredProjects[2]); assert.isTrue(projectService.inferredProjects[0].isOrphan()); - checkProjectActualFiles(projectService.inferredProjects[1], [file2.path]); + ts.projectSystem.checkProjectActualFiles(projectService.inferredProjects[1], [file2.path]); assert.isTrue(projectService.inferredProjects[2].isOrphan()); projectService.openClientFile(file3.path); - checkNumberOfProjects(projectService, { inferredProjects: 2 }); + ts.projectSystem.checkNumberOfProjects(projectService, { inferredProjects: 2 }); assert.strictEqual(projectService.inferredProjects[0], inferredProjects[2]); assert.strictEqual(projectService.inferredProjects[1], inferredProjects[1]); - checkProjectActualFiles(projectService.inferredProjects[0], [file3.path]); - checkProjectActualFiles(projectService.inferredProjects[1], [file2.path]); + ts.projectSystem.checkProjectActualFiles(projectService.inferredProjects[0], [file3.path]); + ts.projectSystem.checkProjectActualFiles(projectService.inferredProjects[1], [file2.path]); }); it("regression test for crash in acquireOrUpdateDocument", () => { @@ -570,13 +553,13 @@ namespace ts.projectSystem { scriptKind: "JS" as "JS" }; - const host = createServerHost([]); - const projectService = createProjectService(host); - projectService.applyChangesInOpenFiles(singleIterator(tsFile)); + const host = ts.projectSystem.createServerHost([]); + const projectService = ts.projectSystem.createProjectService(host); + projectService.applyChangesInOpenFiles(ts.singleIterator(tsFile)); const projs = projectService.synchronizeProjectList([]); projectService.findProject(projs[0].info!.projectName)!.getLanguageService().getNavigationBarItems(tsFile.fileName); projectService.synchronizeProjectList([projs[0].info!]); - projectService.applyChangesInOpenFiles(singleIterator(jsFile)); + projectService.applyChangesInOpenFiles(ts.singleIterator(jsFile)); }); it("config file is deleted", () => { @@ -592,22 +575,22 @@ namespace ts.projectSystem { path: "/a/b/tsconfig.json", content: JSON.stringify({ compilerOptions: {} }) }; - const host = createServerHost([file1, file2, config]); - const projectService = createProjectService(host); + const host = ts.projectSystem.createServerHost([file1, file2, config]); + const projectService = ts.projectSystem.createProjectService(host); projectService.openClientFile(file1.path); - checkNumberOfProjects(projectService, { configuredProjects: 1 }); - checkProjectActualFiles(configuredProjectAt(projectService, 0), [file1.path, file2.path, config.path]); + ts.projectSystem.checkNumberOfProjects(projectService, { configuredProjects: 1 }); + ts.projectSystem.checkProjectActualFiles(ts.projectSystem.configuredProjectAt(projectService, 0), [file1.path, file2.path, config.path]); projectService.openClientFile(file2.path); - checkNumberOfProjects(projectService, { configuredProjects: 1 }); - checkProjectActualFiles(configuredProjectAt(projectService, 0), [file1.path, file2.path, config.path]); + ts.projectSystem.checkNumberOfProjects(projectService, { configuredProjects: 1 }); + ts.projectSystem.checkProjectActualFiles(ts.projectSystem.configuredProjectAt(projectService, 0), [file1.path, file2.path, config.path]); host.deleteFile(config.path); host.checkTimeoutQueueLengthAndRun(1); - checkNumberOfProjects(projectService, { inferredProjects: 2 }); - checkProjectActualFiles(projectService.inferredProjects[0], [file1.path]); - checkProjectActualFiles(projectService.inferredProjects[1], [file2.path]); + ts.projectSystem.checkNumberOfProjects(projectService, { inferredProjects: 2 }); + ts.projectSystem.checkProjectActualFiles(projectService.inferredProjects[0], [file1.path]); + ts.projectSystem.checkProjectActualFiles(projectService.inferredProjects[1], [file2.path]); }); it("loading files with correct priority", () => { @@ -629,8 +612,8 @@ namespace ts.projectSystem { compilerOptions: { allowJs: true } }) }; - const host = createServerHost([f1, f2, f3, config]); - const projectService = createProjectService(host); + const host = ts.projectSystem.createServerHost([f1, f2, f3, config]); + const projectService = ts.projectSystem.createProjectService(host); projectService.setHostConfiguration({ extraFileExtensions: [ { extension: ".js", isMixedContent: false }, @@ -639,21 +622,21 @@ namespace ts.projectSystem { }); projectService.openClientFile(f1.path); projectService.checkNumberOfProjects({ configuredProjects: 1 }); - checkProjectActualFiles(configuredProjectAt(projectService, 0), [f1.path, config.path]); + ts.projectSystem.checkProjectActualFiles(ts.projectSystem.configuredProjectAt(projectService, 0), [f1.path, config.path]); // Since f2 refers to config file as the default project, it needs to be kept alive projectService.closeClientFile(f1.path); projectService.openClientFile(f2.path); projectService.checkNumberOfProjects({ inferredProjects: 1, configuredProjects: 1 }); assert.isDefined(projectService.configuredProjects.get(config.path)); - checkProjectActualFiles(projectService.inferredProjects[0], [f2.path]); + ts.projectSystem.checkProjectActualFiles(projectService.inferredProjects[0], [f2.path]); // Should close configured project with next file open projectService.closeClientFile(f2.path); projectService.openClientFile(f3.path); projectService.checkNumberOfProjects({ inferredProjects: 1 }); assert.isUndefined(projectService.configuredProjects.get(config.path)); - checkProjectActualFiles(projectService.inferredProjects[0], [f3.path]); + ts.projectSystem.checkProjectActualFiles(projectService.inferredProjects[0], [f3.path]); }); it("tsconfig script block support", () => { @@ -669,41 +652,41 @@ namespace ts.projectSystem { path: "/a/b/tsconfig.json", content: JSON.stringify({ compilerOptions: { allowJs: true } }) }; - const host = createServerHost([file1, file2, config]); - const session = createSession(host); - openFilesForSession([file1], session); + const host = ts.projectSystem.createServerHost([file1, file2, config]); + const session = ts.projectSystem.createSession(host); + ts.projectSystem.openFilesForSession([file1], session); const projectService = session.getProjectService(); // HTML file will not be included in any projects yet - checkNumberOfProjects(projectService, { configuredProjects: 1 }); - const configuredProj = configuredProjectAt(projectService, 0); - checkProjectActualFiles(configuredProj, [file1.path, config.path]); + ts.projectSystem.checkNumberOfProjects(projectService, { configuredProjects: 1 }); + const configuredProj = ts.projectSystem.configuredProjectAt(projectService, 0); + ts.projectSystem.checkProjectActualFiles(configuredProj, [file1.path, config.path]); // Specify .html extension as mixed content - const extraFileExtensions = [{ extension: ".html", scriptKind: ScriptKind.JS, isMixedContent: true }]; - const configureHostRequest = makeSessionRequest(CommandNames.Configure, { extraFileExtensions }); + const extraFileExtensions = [{ extension: ".html", scriptKind: ts.ScriptKind.JS, isMixedContent: true }]; + const configureHostRequest = ts.projectSystem.makeSessionRequest(ts.projectSystem.CommandNames.Configure, { extraFileExtensions }); session.executeCommand(configureHostRequest); // The configured project should now be updated to include html file - checkNumberOfProjects(projectService, { configuredProjects: 1 }); - assert.strictEqual(configuredProjectAt(projectService, 0), configuredProj, "Same configured project should be updated"); - checkProjectActualFiles(configuredProjectAt(projectService, 0), [file1.path, file2.path, config.path]); + ts.projectSystem.checkNumberOfProjects(projectService, { configuredProjects: 1 }); + assert.strictEqual(ts.projectSystem.configuredProjectAt(projectService, 0), configuredProj, "Same configured project should be updated"); + ts.projectSystem.checkProjectActualFiles(ts.projectSystem.configuredProjectAt(projectService, 0), [file1.path, file2.path, config.path]); // Open HTML file - projectService.applyChangesInOpenFiles(singleIterator({ + projectService.applyChangesInOpenFiles(ts.singleIterator({ fileName: file2.path, hasMixedContent: true, - scriptKind: ScriptKind.JS, + scriptKind: ts.ScriptKind.JS, content: `var hello = "hello";` })); // Now HTML file is included in the project - checkNumberOfProjects(projectService, { configuredProjects: 1 }); - checkProjectActualFiles(configuredProjectAt(projectService, 0), [file1.path, file2.path, config.path]); + ts.projectSystem.checkNumberOfProjects(projectService, { configuredProjects: 1 }); + ts.projectSystem.checkProjectActualFiles(ts.projectSystem.configuredProjectAt(projectService, 0), [file1.path, file2.path, config.path]); // Check identifiers defined in HTML content are available in .ts file - const project = configuredProjectAt(projectService, 0); - let completions = project.getLanguageService().getCompletionsAtPosition(file1.path, 1, emptyOptions); - assert(completions && some(completions.entries, e => e.name === "hello"), `expected entry hello to be in completion list`); + const project = ts.projectSystem.configuredProjectAt(projectService, 0); + let completions = project.getLanguageService().getCompletionsAtPosition(file1.path, 1, ts.emptyOptions); + assert(completions && ts.some(completions.entries, e => e.name === "hello"), `expected entry hello to be in completion list`); // Close HTML file projectService.applyChangesInOpenFiles( @@ -712,11 +695,11 @@ namespace ts.projectSystem { /*closedFiles*/[file2.path]); // HTML file is still included in project - checkNumberOfProjects(projectService, { configuredProjects: 1 }); - checkProjectActualFiles(configuredProjectAt(projectService, 0), [file1.path, file2.path, config.path]); + ts.projectSystem.checkNumberOfProjects(projectService, { configuredProjects: 1 }); + ts.projectSystem.checkProjectActualFiles(ts.projectSystem.configuredProjectAt(projectService, 0), [file1.path, file2.path, config.path]); // Check identifiers defined in HTML content are not available in .ts file - completions = project.getLanguageService().getCompletionsAtPosition(file1.path, 5, emptyOptions); + completions = project.getLanguageService().getCompletionsAtPosition(file1.path, 5, ts.emptyOptions); assert(completions && completions.entries[0].name !== "hello", `unexpected hello entry in completion list`); }); @@ -736,20 +719,19 @@ namespace ts.projectSystem { content: JSON.stringify({ compilerOptions: { allowJs: true } }) }; - let host = createServerHost([file1, file2, config1, libFile], { executingFilePath: combinePaths(getDirectoryPath(libFile.path), "tsc.js") }); - let session = createSession(host); + let host = ts.projectSystem.createServerHost([file1, file2, config1, ts.projectSystem.libFile], { executingFilePath: ts.combinePaths(ts.getDirectoryPath(ts.projectSystem.libFile.path), "tsc.js") }); + let session = ts.projectSystem.createSession(host); // Specify .html extension as mixed content in a configure host request - const extraFileExtensions = [{ extension: ".html", scriptKind: ScriptKind.JS, isMixedContent: true }]; - const configureHostRequest = makeSessionRequest(CommandNames.Configure, { extraFileExtensions }); + const extraFileExtensions = [{ extension: ".html", scriptKind: ts.ScriptKind.JS, isMixedContent: true }]; + const configureHostRequest = ts.projectSystem.makeSessionRequest(ts.projectSystem.CommandNames.Configure, { extraFileExtensions }); session.executeCommand(configureHostRequest); - openFilesForSession([file1], session); + ts.projectSystem.openFilesForSession([file1], session); let projectService = session.getProjectService(); - checkNumberOfProjects(projectService, { configuredProjects: 1 }); - - let diagnostics = configuredProjectAt(projectService, 0).getLanguageService().getCompilerOptionsDiagnostics(); + ts.projectSystem.checkNumberOfProjects(projectService, { configuredProjects: 1 }); + let diagnostics = ts.projectSystem.configuredProjectAt(projectService, 0).getLanguageService().getCompilerOptionsDiagnostics(); assert.deepEqual(diagnostics, []); // #2. Ensure no errors when allowJs is false @@ -758,17 +740,16 @@ namespace ts.projectSystem { content: JSON.stringify({ compilerOptions: { allowJs: false } }) }; - host = createServerHost([file1, file2, config2, libFile], { executingFilePath: combinePaths(getDirectoryPath(libFile.path), "tsc.js") }); - session = createSession(host); + host = ts.projectSystem.createServerHost([file1, file2, config2, ts.projectSystem.libFile], { executingFilePath: ts.combinePaths(ts.getDirectoryPath(ts.projectSystem.libFile.path), "tsc.js") }); + session = ts.projectSystem.createSession(host); session.executeCommand(configureHostRequest); - openFilesForSession([file1], session); + ts.projectSystem.openFilesForSession([file1], session); projectService = session.getProjectService(); - checkNumberOfProjects(projectService, { configuredProjects: 1 }); - - diagnostics = configuredProjectAt(projectService, 0).getLanguageService().getCompilerOptionsDiagnostics(); + ts.projectSystem.checkNumberOfProjects(projectService, { configuredProjects: 1 }); + diagnostics = ts.projectSystem.configuredProjectAt(projectService, 0).getLanguageService().getCompilerOptionsDiagnostics(); assert.deepEqual(diagnostics, []); // #3. Ensure no errors when compiler options aren't specified @@ -777,17 +758,16 @@ namespace ts.projectSystem { content: JSON.stringify({}) }; - host = createServerHost([file1, file2, config3, libFile], { executingFilePath: combinePaths(getDirectoryPath(libFile.path), "tsc.js") }); - session = createSession(host); + host = ts.projectSystem.createServerHost([file1, file2, config3, ts.projectSystem.libFile], { executingFilePath: ts.combinePaths(ts.getDirectoryPath(ts.projectSystem.libFile.path), "tsc.js") }); + session = ts.projectSystem.createSession(host); session.executeCommand(configureHostRequest); - openFilesForSession([file1], session); + ts.projectSystem.openFilesForSession([file1], session); projectService = session.getProjectService(); - checkNumberOfProjects(projectService, { configuredProjects: 1 }); - - diagnostics = configuredProjectAt(projectService, 0).getLanguageService().getCompilerOptionsDiagnostics(); + ts.projectSystem.checkNumberOfProjects(projectService, { configuredProjects: 1 }); + diagnostics = ts.projectSystem.configuredProjectAt(projectService, 0).getLanguageService().getCompilerOptionsDiagnostics(); assert.deepEqual(diagnostics, []); // #4. Ensure no errors when files are explicitly specified in tsconfig @@ -796,17 +776,16 @@ namespace ts.projectSystem { content: JSON.stringify({ compilerOptions: { allowJs: true }, files: [file1.path, file2.path] }) }; - host = createServerHost([file1, file2, config4, libFile], { executingFilePath: combinePaths(getDirectoryPath(libFile.path), "tsc.js") }); - session = createSession(host); + host = ts.projectSystem.createServerHost([file1, file2, config4, ts.projectSystem.libFile], { executingFilePath: ts.combinePaths(ts.getDirectoryPath(ts.projectSystem.libFile.path), "tsc.js") }); + session = ts.projectSystem.createSession(host); session.executeCommand(configureHostRequest); - openFilesForSession([file1], session); + ts.projectSystem.openFilesForSession([file1], session); projectService = session.getProjectService(); - checkNumberOfProjects(projectService, { configuredProjects: 1 }); - - diagnostics = configuredProjectAt(projectService, 0).getLanguageService().getCompilerOptionsDiagnostics(); + ts.projectSystem.checkNumberOfProjects(projectService, { configuredProjects: 1 }); + diagnostics = ts.projectSystem.configuredProjectAt(projectService, 0).getLanguageService().getCompilerOptionsDiagnostics(); assert.deepEqual(diagnostics, []); // #4. Ensure no errors when files are explicitly excluded in tsconfig @@ -815,17 +794,16 @@ namespace ts.projectSystem { content: JSON.stringify({ compilerOptions: { allowJs: true }, exclude: [file2.path] }) }; - host = createServerHost([file1, file2, config5, libFile], { executingFilePath: combinePaths(getDirectoryPath(libFile.path), "tsc.js") }); - session = createSession(host); + host = ts.projectSystem.createServerHost([file1, file2, config5, ts.projectSystem.libFile], { executingFilePath: ts.combinePaths(ts.getDirectoryPath(ts.projectSystem.libFile.path), "tsc.js") }); + session = ts.projectSystem.createSession(host); session.executeCommand(configureHostRequest); - openFilesForSession([file1], session); + ts.projectSystem.openFilesForSession([file1], session); projectService = session.getProjectService(); - checkNumberOfProjects(projectService, { configuredProjects: 1 }); - - diagnostics = configuredProjectAt(projectService, 0).getLanguageService().getCompilerOptionsDiagnostics(); + ts.projectSystem.checkNumberOfProjects(projectService, { configuredProjects: 1 }); + diagnostics = ts.projectSystem.configuredProjectAt(projectService, 0).getLanguageService().getCompilerOptionsDiagnostics(); assert.deepEqual(diagnostics, []); }); @@ -838,21 +816,21 @@ namespace ts.projectSystem { path: "/a/b/f2.ts", content: "export let x = 1" }; - const host = createServerHost([file1, file2]); - const projectService = createProjectService(host); + const host = ts.projectSystem.createServerHost([file1, file2]); + const projectService = ts.projectSystem.createProjectService(host); projectService.openClientFile(file1.path); projectService.openClientFile(file2.path); - checkNumberOfProjects(projectService, { inferredProjects: 1 }); + ts.projectSystem.checkNumberOfProjects(projectService, { inferredProjects: 1 }); projectService.applyChangesInOpenFiles( /*openFiles*/ undefined, - /*changedFiles*/singleIterator({ fileName: file1.path, changes: singleIterator({ span: createTextSpan(0, file1.path.length), newText: "let y = 1" }) }), + /*changedFiles*/ ts.singleIterator({ fileName: file1.path, changes: ts.singleIterator({ span: ts.createTextSpan(0, file1.path.length), newText: "let y = 1" }) }), /*closedFiles*/ undefined); - checkNumberOfProjects(projectService, { inferredProjects: 1 }); + ts.projectSystem.checkNumberOfProjects(projectService, { inferredProjects: 1 }); projectService.ensureInferredProjectsUpToDate_TestOnly(); - checkNumberOfProjects(projectService, { inferredProjects: 2 }); + ts.projectSystem.checkNumberOfProjects(projectService, { inferredProjects: 2 }); }); it("files with mixed content are handled correctly", () => { @@ -860,31 +838,30 @@ namespace ts.projectSystem { path: "/a/b/f1.html", content: `